Skip to content

[Feature]: extract provider validation from config persistence #2379

Description

@Ingwannu

Area

Multiple areas

What are you trying to accomplish?

Make provider configuration validation a small, reusable boundary shared by persisted config loading, provider CLI writes, and management API payload validation, without changing any accepted configuration or runtime behavior.

What prevents this today?

The pure provider validation helpers currently live inside the broad src/config.ts persistence module. Callers that need only one validation rule therefore import config storage, schema, migration, and filesystem dependencies as well. That obscures the single validation owner and makes isolated characterization difficult.

What should OpenCodex do?

  • Move the pure provider payload helpers into src/config/provider-validation.ts.
  • Keep src/config.ts as a compatibility facade that re-exports the existing public symbols.
  • Let direct CLI and management callers import the leaf module when they need only validation.
  • Preserve validation order, exact error strings, accepted and rejected shapes, Zod issue paths, canonical ChatGPT forward-provider restrictions, and wire-pinned model restrictions.
  • Record the ownership boundary and rationale in structure/02_config-and-codex-home.md.

Example usage or interface

import { providerBaseUrlConfigError } from "./config/provider-validation";

The refactor must remain behavior-preserving: existing imports from src/config.ts continue to work, and management requests and hand-edited config.json continue to accept and reject the same values with the same messages.

Acceptance criteria:

  • Characterization tests cover every extracted helper, including inherited-property objects, sensitive headers, line breaks, contradictory reasoning-summary flags, canonical-forward overrides, and wire-pinned models.
  • Focused config/management tests, strict typecheck, and the full Bun suite are evaluated on the exact PR head.
  • No persisted schema, defaults, provider behavior, GUI text, or management response shape changes.
  • There is one validation implementation; the compatibility facade does not duplicate it.

Alternatives or workarounds

  • Keep the helpers in src/config.ts: lowest churn, but preserves the broad dependency and unclear ownership.
  • Duplicate validation in each caller: rejected because disk config and management writes could drift.
  • Extract one shared leaf with compatibility re-exports: preferred because callers can migrate incrementally while preserving the public API.

Additional context

[Decision Log]

  • Purpose: separate reusable provider validation from config persistence without changing behavior.
  • Existing constraints: persisted config and management DTOs must reject the same payloads with the same messages.
  • Chosen approach: one pure leaf module plus src/config.ts facade re-exports and focused characterization tests.
  • Tradeoff: the facade remains temporarily, but it avoids a flag-day import rewrite and keeps downstream compatibility.

This is a Bun-native TypeScript ownership change on the current dev runtime line. The retired dev2-go line has no integration obligation.

Checks

  • I searched existing issues and documentation.
  • This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
  • I removed secrets and personal data.

Activity

  1. changed the title [-][Architecture]: extract shared provider validation from the config persistence module[/-] [+][Feature]: extract provider validation from config persistence[/+] on Aug 22, 2026
  2. added
    proxyHTTP proxy, routing, reverse-proxy / management auth
    on Aug 22, 2026
  3. lidge-jun commented on Aug 22, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 45 / 80

    설명: 이 이슈는 제공자 값이 맞는지 보는 일을 src/config.ts 에서 꺼내 순수 검사 모듈로 만들자고 한다. 지금 CURRENT dev HEAD 는 378d889c5 이다. 이번 시간에 origin/dev 가 af5dd16 에서 여기로 옮겼다. 착지한 코드는 #2359 호출 불가 모델 제외(Closes #2330), #2376 번 1.4 메모리 문서+하니스, #2377 WP7 기록이다. package.json 은 2.27.0 이다. 이슈는 config.ts 가 1780줄이라고 적었다. 지금 HEAD 는 3975줄이다. 줄 수는 이미 틀렸다. 검사 함수는 759줄 근처에 있다. providerBaseUrlConfigError, providerHeadersConfigError, apiKeyTransportConfigError, positiveIntegerRecordConfigError, reasoningSummaryDeliveryRecordConfigError, modelPreferHostedToolsConfigError, modelAdapterRecordConfigError 다. 이미 src/config/provider-name.ts 잎이 있고 config.ts 라인 757 이 그 이름을 다시 보낸다. 이슈가 말한 패턴은 이미 하나 있다. src/server/auth-cors.ts 와 management 라우트와 src/cli/provider.ts 가 설정 모듈 전체를 가져와 이 검사만 쓴다. 그래서 설정 저장을 고치면 검사만 필요한 코드도 같이 흔들린다. 다만 modelPreferHostedToolsConfigError 는 getProviderRegistryEntry 와 providerMatchesRegistryTransport 와 pinnedWireAdapter 를 본다. 순수 함수가 아니다. 레지스트리와 와이어 핀을 빼면 에러 문자열이 달라질 수 있다. 이슈는 에러 문자열, 검사 순서, 거절 모양, 조드 경로를 그대로 두라고 했다. 캐논 챗지피티 포워드와 와이어 핀 모델 제한도 그대로다. 동작 변경 없이 옮기려면 레지스트리를 보는 함수도 같이 가거나, 순수라고 거짓말하지 말고 의존을 적어야 한다. 사용자 길이 버그가 아니라 모듈 경계 일이라서 45.

    src/config.ts 라인 759 - providerBaseUrlConfigError. 자격 증명과 쿼리와 조각을 거절한다. auth-cors 와 management 가 같이 쓴다
    src/config.ts 라인 866 - apiKeyTransportConfigError. 앤트로픽 키 인증에서만 x-api-key 또는 bearer 를 받는다
    src/config.ts 라인 980 - modelPreferHostedToolsConfigError. 레지스트리를 본다. 순수 잎이라고 우기면 안 된다
    src/config.ts 라인 1081 - modelAdapterRecordConfigError. 와이어 핀 모델은 덮어쓰기를 거절한다
    src/config/provider-name.ts - 이미 있는 잎. 이 이슈의 본보기다. 검사 잎도 여기 옆에 두는 편이 맞다

    메인테이너의 판단이 필요한 지점

    너의 추천
    새 PR 을 연다. 경로는 src/config/provider-validation.ts 가 기존 잎과 같다. 순수 헬퍼를 먼저 옮기고, 레지스트리를 보는 함수는 같은 파일에 두되 순수라고 쓰지 않는다. #2378 과 같은 PR 에 넣지 않는다. 이슈 본문의 1780줄은 지금 HEAD 와 다르니 PR 에서 고친다. 지금 닫지 말 것. types.ts 스플릿과 겹치면 닫고 리베이스하지 않는다. 라벨은 그대로 둔다. 프리뷰 배포가 아니다.

    이 댓글은 grok-bot이 작성했습니다

  4. Ingwannu commented on Aug 22, 2026

    @Ingwannu
    OwnerAuthor

    Implemented in draft PR #2380 against dev. The patch keeps src/config.ts compatibility exports, moves the pure provider validators into src/config/provider-validation.ts, migrates direct CLI/management consumers, adds characterization tests, and documents the ownership boundary.

    After rebasing onto current dev (5e5059044), exact-head focused validation is 174/174, strict typecheck passes, and git diff --check passes. I left the PR draft because repository policy requires another maintainer to review the import-only auth-cors.ts boundary change; exact-head CI is running after the rebase. I will not self-approve or self-merge it.

  5. lidge-jun commented on Aug 23, 2026

    @lidge-jun
    Owner

    Closed by #2380, squash-merged to dev as aa37c8b.

    Eleven pure provider-validation helpers and three supporting constants now live in a focused leaf module. src/config.ts retains every compatibility re-export, while direct consumers take the narrower dependency. Independent review traced this as a security-adjacent change because provider validation sits next to the auth surface, and found no behavior delta: auth and CORS handling, logging, persistence, response shapes, and the core/Lab boundary are all unchanged, and every moved function body matches its original.

    Evidence: 187 pass / 0 fail across provider-config-validation, management-provider-validation, management-origin-tls, server-auth, and core-lab-boundary; config.test.ts 153 / 0; bun run typecheck pass; CI 23 pass.

    Closing by hand because PRs here target dev.

  6. lidge-jun commented on Aug 23, 2026

    @lidge-jun
    Owner

    Landed via #2380 at aa37c8b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestlanded-via-maintainerOriginal PR closed after landing via a maintainer merge trainproxyHTTP proxy, routing, reverse-proxy / management auth

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions