Skip to content

test(provider): gate user-facing strings against the legacy provider names - #2020

Merged
code-yeongyu merged 1 commit into
mainfrom
test/1989-name-gate
Sep 22, 2026
Merged

code-yeongyu merged 1 commit into
mainfrom
test/1989-name-gate

Conversation

@code-yeongyu

@code-yeongyu code-yeongyu commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

Turns "no leaked old name" into an enforced gate. Part of #1989 (todo 11). Rebased onto main now that #2018 (todo 10) has merged; the gate is verified 3/3 against the post-rename tree.

(Reopened from #2019, whose base branch was deleted on #2018's merge — that froze its head at the pre-rebase sha and GitHub will not retarget a PR with a deleted base ref.)

How it works

Scans every shipped .ts under packages/coding-agent/src and packages/ai/src, extracts string and template literals only (comments and identifiers are not user-facing), and fails on any literal carrying openai-codex, OpenAI Codex, claude-sdk-oauth or Claude SDK OAuth outside the allowlist.

The allowlist is (file, literal) PAIRS

Not whole files — a new legacy string in an already-listed file still fails. Each entry states why it is frozen:

File Literal Why
anthropic-subscription/api-id.ts claude-sdk-oauth frozen wire api id (its own comment: "Frozen permanently — must NOT follow a provider-id rename")
goal/terminal-provider-error.ts, utils/prompt-cache-ttl.ts claude-sdk-oauth compare/switch on model.api, the frozen wire id
anthropic-subscription/affinity.ts claude-sdk-oauth-default persisted HRW affinity key
anthropic-subscription/session-binding.ts claude-sdk-oauth-binding persisted binding entry type
anthropic-subscription/config-dir-credentials.ts claude-sdk-oauth-accounts legacy accounts dir the one-shot move reads from
extensions/builtin/index.ts claude-sdk-oauth builtin extension module id
packages/ai/src/types.ts openai-codex retained KnownProvider legacy member

Allowed anywhere because the string is the contract: the seven frozen tokens, CLAUDE_CODE_OAUTH_TOKEN/SENPI_CLAUDE_SDK_OAUTH/claude_sdk_oauth_, and "was renamed to" — the todo-9 rejection message must name the old id back to the user.

Allowed wholesale because knowing the legacy ids is their entire job: legacy-provider-ids.ts, legacy-api-aliases.ts, auth-provider-key-migration.ts, settings-manager.ts.

Scope decisions worth reviewing

  • Both casings, both providers. An earlier symbol inventory covered SCREAMING_SNAKE only on the Anthropic side and missed OPENAI_CODEX_*; a one-sided gate would be blind to half its surface.
  • Excludes changes.md/AGENTS.md. 166 of 201 legacy hits in the tree are dated design-history entries; a gate demanding those be rewritten would attack the fork's own record.
  • A third case pins the load-bearing direction: both LEGACY_PROVIDER_IDS map keys must stay reachable, since every normalization and every typed rejection reads them.

Verification

bunx vitest run test/suite/anthropic-subscription-naming.test.ts — 3 passed, run on the rebased head whose base contains the full rename.

Proven live, as the plan requires: re-introducing "OpenAI Codex" as a display name in provider-display-names.ts turns the guard RED naming the offending file and literal:

+   "packages/coding-agent/src/core/provider-display-names.ts: OpenAI Codex",

Restored afterwards; 3 passed again. Biome 0 errors; changelog gate PASS (test-only diff).

Observation for a follow-up, not fixed here

extensions/builtin/index.ts still registers { id: "claude-sdk-oauth" } while todo 10 moved its directory to anthropic-subscription/, so the builtin id no longer mirrors its directory. Keeping it is correct for a behaviour-free commit (it is a stable module identifier), but whether it should be renamed with a migration deserves its own issue.

Part of #1989


Summary by cubic

Adds a test that makes "no leaked old provider name" an enforced gate across packages/coding-agent/src and packages/ai/src.

  • Scans only string and template literals (comments and identifiers are not user-facing) and fails on any carrying openai-codex, OpenAI Codex, claude-sdk-oauth, or Claude SDK OAuth.
  • Allowlists are per literal (file + literal pairs), not whole files, so a new legacy string in an already-listed file still fails; each entry documents why it is frozen (wire API ids, persisted tokens, stable module ids, retained union member).
  • Allows frozen contract substrings anywhere (persisted tokens and env vars) and allows four files wholesale whose job is to know the legacy ids.
  • Adds a separate assertion that both LEGACY_PROVIDER_IDS map keys stay reachable since every normalization and rejection reads them.

Part of #1989.

Written for commit c947b4a. Summary will update on new commits.

Review in cubic

…names

Extends the naming-boundary test into an enforced guard: it scans every
shipped .ts under packages/coding-agent/src and packages/ai/src, extracts
STRING AND TEMPLATE LITERALS ONLY (comments and identifiers are not
user-facing), and fails on any literal carrying `openai-codex`, `OpenAI Codex`,
`claude-sdk-oauth` or `Claude SDK OAuth` outside an explicit allowlist.

The allowlist is (file, literal) PAIRS, not whole files, so a NEW legacy string
in an already-listed file still fails. Every entry states why it is frozen:
the wire api id `claude-sdk-oauth` and its two comparison sites, the persisted
affinity key / binding entry type / legacy accounts dir, the builtin extension
module id, and the retained KnownProvider legacy member. Substrings that ARE
the contract (the seven frozen tokens, the env families, and the todo-9
rejection message, which must name the old id back to the user) are allowed
anywhere. Four files whose entire job is knowing the legacy ids are allowed
wholesale: legacy-provider-ids.ts, legacy-api-aliases.ts,
auth-provider-key-migration.ts and settings-manager.ts.

A third case pins the load-bearing direction: both LEGACY_PROVIDER_IDS map keys
must stay reachable, since every normalization and every typed rejection reads
them.

Proven live: re-introducing `"OpenAI Codex"` as a display name in
provider-display-names.ts turns the guard RED and names that file and literal.

Part of #1989
@code-yeongyu
code-yeongyu merged commit 429fb0f into main Sep 22, 2026
26 checks passed
@code-yeongyu
code-yeongyu deleted the test/1989-name-gate branch September 22, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant