Skip to content

refactor: factor the seeded-provider-tier migration skeleton into _lib.js (#4161) - #4261

Merged
atomantic merged 1 commit into
mainfrom
claim/issue-4161
Aug 15, 2026
Merged

refactor: factor the seeded-provider-tier migration skeleton into _lib.js (#4161)#4261
atomantic merged 1 commit into
mainfrom
claim/issue-4161

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

scripts/migrations/206-claude-default-opus-5.js was the fourth hand-copy of the same "bump one seeded Claude provider tier" shell (032 → 058 → 153 → 206). All four exact-match the prior seeded models list, rewrite it, swap every retired model id wherever it appears (the list plus any of the four tier pointers), repair an orphan pointer left at a now-absent id, and skip anything the user curated. Only the data differs.

  • makeSeededProviderTierMigration({ targets, tierLabel }) in scripts/migrations/_lib.js is that shell. A future bump becomes a small data table — per provider, the exact prior seeded models array plus a retired-id → replacement map — instead of another ~200-line clone. Bedrock entries list the plain and [1m] ids separately so a long-context pin maps like-for-like rather than silently dropping a context tier. Resolves to { ok, reason, touched, alreadyCurrent, customized }.
  • runSeededProviderTierMigrationTests({ migration, targets, prefix }) in scripts/migrations/_testHelpers.js is its companion runner, mirroring runPromptMigrationTests. Every fixture is derived from the migration's own targets table, so a bump's test file collapses to a describe + one call and still asserts the whole conservative contract (exact-match-only rewrites, like-for-like mapping of each retired id, still-current pointers preserved, orphan pointers repaired, byte-for-byte no-op on customized/current/absent/unparseable input).

Migrations 032/058/153/206 are deliberately NOT rewritten to consume the factory. A migration is the historical record of what it did to an install, and an applied one must keep behaving exactly as documented. Instead, 153 and 206 are re-expressed as targets tables inside a differential suite that runs each shipped migration head-to-head against its factory-built equivalent over the same fixtures and requires a byte-identical data/providers.json. That is what proves the factory reproduces their behavior without touching them. The factoring pays off starting with the migration after 206.

Also folded in while there: the data/providers.json read → parse → shape-guard preamble was duplicated between the existing provider-seed family and the new one, so it is now a shared private readProvidersDoc. Each family keeps its own log copy and result shape, so the six provider-seed migrations (149/152/185/195/201/231) are behaviorally unchanged — their existing suite asserts every reason path.

Test plan

  • cd server && NODE_ENV=test npx vitest run ../scripts/ — 247 files / 1802 tests pass.
  • cd server && NODE_ENV=test npm test — full server suite green (1395 files, 29225 tests; the 26 DB-backed suites skip against the non-test database as designed).
  • Anti-vacuity check on the new suites: two deliberate bypass probes were injected into _lib.js and reverted. Breaking the like-for-like pointer map failed 10 tests (including both Bedrock [1m] differential fixtures); making the factory silently decline to write failed 30. The differential test additionally asserts that the mutating fixtures really did change on disk and that the three no-op fixtures really did not, so "both migrations wrote nothing" can never pass as a match.

Closes #4161

…b.js (#4161)

Migrations 032 -> 058 -> 153 -> 206 are four hand-copies of the same
"bump one seeded Claude provider tier" shell: exact-match the prior seeded
models list, rewrite it, swap every retired id wherever it appears, repair an
orphan tier pointer, skip anything customized. Only the data differs.

`makeSeededProviderTierMigration({ targets, tierLabel })` is that shell, so the
next bump is a small data table (prior models list + retired-id -> replacement
map per provider) rather than another ~200-line clone.
`runSeededProviderTierMigrationTests` in _testHelpers.js is its companion
runner, deriving every fixture from the migration's own targets table the way
`runPromptMigrationTests` does for the prompt-replace family.

The four shipped migrations are NOT rewritten to consume the factory - a
migration is the historical record of what it did to an install, and an applied
one must keep behaving exactly as documented. Instead 153 and 206 are re-expressed
as targets tables in a differential suite that runs each shipped migration
head-to-head against its factory-built equivalent over the same fixtures and
requires a byte-identical data/providers.json. The factory pays off starting
with the migration after 206.

Also extracts the data/providers.json read -> parse -> shape-guard preamble
that the provider-seed family already repeated into a shared `readProvidersDoc`,
with each family keeping its own log copy and result shape.
@atomantic

Copy link
Copy Markdown
Owner Author

Review gate — antigravity (agy 1.1.13)

Round 1 (diff-only prompt) returned one finding: _testHelpers.js calls existsSync without importing it. False positiveexistsSync is already in the fs import on line 16 (it predates this branch, so it never appeared as diff context). The suites also execute it, so a genuine missing import would have thrown.

Round 2 (re-run with repo file access and an instruction to open the full files before judging): NO FINDINGS. No code changes were needed; the worktree is unchanged from round 1.

Self-review

One finding from my own pass was fixed in the same diff: the data/providers.json read → parse → shape-guard preamble was about to exist twice in _lib.js (the existing provider-seed family plus the new tier family), so it is now a shared private readProvidersDoc. Each family keeps its own log copy and result shape, so migrations 149/152/185/195/201/231 are behaviorally unchanged.

Anti-vacuity check on the new suites

Two deliberate bypass probes were injected into _lib.js and reverted:

  • breaking the like-for-like retired-id map (so …[1m] collapses to the plain id) → 10 tests failed, including both Bedrock [1m] differential fixtures;
  • making the factory silently decline to write → 30 tests failed.

The differential test also asserts that the mutating fixtures actually changed on disk and that the three no-op fixtures actually did not, so "both migrations wrote nothing" cannot pass as a match.

Tests

cd server && NODE_ENV=test npx vitest run ../scripts/ → 247 files / 1802 tests pass.
cd server && NODE_ENV=test npm test → 1395 files / 29225 tests pass (26 DB-backed suites skip against the non-test database, as designed).

@atomantic
atomantic merged commit 9b16971 into main Aug 15, 2026
7 checks passed
@atomantic
atomantic deleted the claim/issue-4161 branch August 15, 2026 04:33
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.

Factor the repeated 'bump seeded Claude provider tier' migration into _lib.js

1 participant