Skip to content

Commit ed1de8c

Browse files
build(spec): the migration registry is generated at build and leaves git (#22706)
Fixes #22554 Clause-②: no Executes ruling B on #22554 (comment 6092692730, maintainer 「同意」), which completes #22449 B′ (comment 6078203801): `packages/spec/src/migrations/registry.ts` is generated at build and leaves git, at its unchanged path. The 3 source imports, the script import and the test imports are untouched. The published package is unchanged apart from `package.json` scripts and the input-hash stamps (measured below). **Landing:** +4,054 / −31,059 across 25 files, about 35,100 changed lines (GitHub's reading at head `81ae60b20a`). That is over the 3,000-line line, so this PR takes the maintainer's APPROVED review, as the ruling notes. It stays draft. The two PM-tool fixes it needs co-land here (see "Two PM tools, co-landed here"). ## A premise the ruling stated, measured false: the registry was a MIXED file The ruling says "the entry files stay the only source". At `cb3bb9333f`, `registry.ts` had 30,718 lines (the ruling's 30,124 is an earlier count). Of these, 27,268 sit inside the six os-generated regions, concatenated from 899 entry files (419 semantic, 258 retired-key, 222 retired-def). The other **3,451 lines are hand-written**: the module header, the two value imports, `MIGRATION_SUPPORT_FLOOR`, step 17's rationale, `STEP18_RATIONALE` (about 1,937 lines of keyed fragments), `step18`, `MIGRATIONS_BY_MAJOR`, `MIGRATION_MAJORS` and the two tables' doc comments. The generator used the file as its own template. So the hand-written part needs a committed home. In the ruling's intent, it becomes **`packages/spec/src/migrations/registry.ts.template`**: the old file with every region emptied, produced mechanically. The generator now writes `registry.ts` whole from that template plus `entries/`. Regenerating from an absent file reproduced the committed blob byte for byte (`feb4843913`) before the header rewording below. The template is deliberately **not** a `.ts` file, for two reasons. With empty regions, its `TranslationDataSchema` import is unused, and the root tsconfig's `noUnusedLocals` would red `tsc`. More important, a `.ts` template would be importable, and an import of it would silently receive empty tables. **Measured cost of this to the ruling's "no shared file for a D3 PR":** of the last 60 commits that touched `registry.ts`, 33 also changed hand-written lines, mostly one `STEP18_RATIONALE` fragment. Those edits now land in the template. It is keyed and sorted, so two retirements insert at different lines (#20535, pinned by `step18-rationale-merge.test.ts`, which now merges the template). Region-only PRs (the other 27 of 60) touch no shared file at all. ## The ruling's measure-first readings (condition 2) 1. **Generation wall time.** Measured at BASE with `tsx scripts/build-migration-registry.ts --self-test --check` and a TMPDIR-isolated tsx cache, load about 3.3 on 4 cores. Cold runs: 1,808 / 1,583 / 1,685 ms. Warm runs: 1,611 / 1,426 / 1,563 ms. `pnpm run gen:migration-registry` took 1,465 ms. A fresh `pnpm install --frozen-lockfile` including the generation took 11 s. 2. **`prepare` on a workspace package runs on `pnpm install`.** I measured this on a fresh worktree with an uncommitted probe `prepare` on `@objectstack/spec`. pnpm 10.31.0 printed `packages/spec prepare$ …` and wrote the marker with cwd `packages/spec`. The probe was then restored byte-identical (blob `de5c9fa2dd`, `git diff HEAD` empty). The real `prepare` (`pnpm gen:migration-registry`) was then measured on a second fresh worktree at `765ae6bde4`. Install printed `✓ wrote src/migrations/registry.ts (419 semantic, 258 retired-key, 222 retired-def)` and `git status` stayed clean. The editor is therefore not red before the first build. `prepare` is strict: a malformed entry fails the install with the generator's located message. A lenient one would leave the previous run's file on disk to be read stale. Also measured: `pnpm pack` runs `prepare` and leaves it out of the packed manifest. 3. **`typecheck` order.** The script is now `pnpm gen:migration-registry && tsc --noEmit && pnpm check:scripts-typecheck && pnpm check:test-typecheck`, so all three run after generation. turbo's `@objectstack/spec#typecheck` also depends on the generation task. In the fresh worktree the typecheck went green with no `dist/` present. ## What changed - **`registry.ts`**: removed from git and ignored (root `.gitignore`, beside `packages/spec/json-schema/`), together with the staging file of the generator's atomic write. - **The generator** (`build-migration-registry.ts`): - reads the template, writes `registry.ts` only when its bytes differ, and writes it by rename, so a parallel `tsc`, vitest worker or importer never reads half a file; - runs its self-test on every generation (`--self-test` alone stops after it). The self-test gains an ordering case (code-unit order; a locale compare fails it) and a determinism and fixed-point case; - header (condition 3): quotes the rule B completes and cites #22449 B′ (6078203801) and #22554 B (6092692730) as superseding the Option-B clause of #6957's 2026-08-10 ruling. - **`packages/spec/package.json`**: `build` starts with `gen:migration-registry` (before `gen:schema`); `typecheck`, `test` and `test:repo` start with it; `prepare` runs it; `check:migration-registry` is removed. - **`turbo.json`**: `@objectstack/spec#gen:migration-registry` has `outputs: ["src/migrations/registry.ts"]`, with inputs the template, the entries, the generator and the manifest. `#typecheck` (new), `#test` and `#test:repo` depend on it, and `#build` lists the file among its outputs so a cache-hit build restores it. - **Template header**: reworded in place to say the file is generated whole and git-ignored, and where each kind of edit goes. The line count is unchanged, so the shipped source maps cannot move. - **Retired**: the `lint.yml` step "Migration registry matches its entry files" and the `migration_registry` gate family in `scripts/ci/select-gate-families.sh`. Its self-test pins go too: 12 cases, with the floor moved from 71 cases / 369 checks to the measured 59 / 304. No other family's verdicts changed. ## Readers of the committed copy, adapted A census of `git grep migrations/registry` (112 files) plus a run of every derived gate found these path-dependent readers. Each is changed only as far as the retirement requires. - **`scripts/check-adr-0087-registration.mjs`** read the ledger with `git show REV:…/registry.ts` and laid out its witness with `git archive`, so it went red ("ledger source not found at HEAD"). - `ledgerAt` now reads a rev's migration ledger from the template plus the entry files when that rev tracks the template, and from the committed registry otherwise, because a merge base can predate this PR. Measured on HEAD against `cb3bb9333f`: 532 / 591 ids on both sides, with 0 differences either way. - The witness runs the rev's own registry generator before projecting. - The `--audit-stock` ledger-touch test counts entry and template commits. - A new battery, GR1–GR7 (13 cases), covers the generated era, including the committed-to-generated transition merge. The roster floor is 50 → 51. - **`scripts/check-future-spec-major.mjs`**: its exemption row for `registry.ts` matched nothing once the file left the tracked corpus. The row is dropped; the entry file that carries the sentence keeps its own row, and the R2 self-test fixture is re-pointed at it. - **`packages/spec/scripts/check-generated.ts`**: `gen:migration-registry` moves to `UNGATED_GENERATORS`, with the build-output rationale `gen:openapi` already has. - **`scripts/regen-artifacts.mjs`**: the registry's `NOT_DRIVER_MANAGED` row becomes `untracked: true` (git never merges it). - **`.gitattributes`, `entries/README.md`, the `build-schemas.ts` remedies and test comments**: stop naming the retired check or a committed lap. - **Disk readers stay green.** The generated file exists after every install, so `check:dispatcher-error-vocabulary`'s row and the ESLint stack-headroom canary still see it. `check:cli-command-ids`, `check:issue-citations` and `check:cross-package-test-inputs` were also measured green. ## The published package `pnpm pack` of `@objectstack/spec` built at BASE `cb3bb9333f` was compared with the build at HEAD (merge `625c4d202e`; the later commit only adds the changeset). Both tarballs hold **2,070 files, and 4 differ**: - `package/package.json`, in `scripts` only: `build`, `typecheck`, `test` and `test:repo` start with the generation, and `check:migration-registry` is gone. `prepare` is not in the packed manifest. - `dist/.build-input-hash`, `dist/.build-input-hash-dts` and `json-schema/.build-input-hash-schema` (`53a504fa…` to `ac4356b2…`). They hash the build inputs, which this PR changes by construction. Every `dist` JS file, declaration, source map and JSON Schema, and every shipped `src/**/*.zod.ts`, is byte-identical. Tarball sha256: BASE `d3d59ac0…`, HEAD `362a845e…`. `pnpm check:published-files` passed at HEAD `765ae6bde4`. ## A fresh checkout builds, typechecks and tests with no committed registry This ran on a new detached worktree at `765ae6bde4`, where `registry.ts` was absent: - `pnpm install --frozen-lockfile`: `prepare` generated the file. - `pnpm --filter @objectstack/spec typecheck`: `VERDICT command-exit 0`, before any build. - `pnpm --filter @objectstack/spec build`: `VERDICT command-exit 0`, with input hash `ac4356b2…`, identical to the primary worktree's build. - `registry.ts` deleted, then `pnpm --filter @objectstack/spec test`: the script wrote it again (`✓ wrote src/migrations/registry.ts`). Result: `Test Files 642 passed (642)`, `Tests 19164 passed | 1 todo (19165)`, `VERDICT command-exit 0`. ## Two PM tools, co-landed here (`scripts/pm`, declared to the `domain:skills` seat on #7623) - **`scripts/pm/os-regen-merge.sh`**: self-test case 9c pinned the registry as a TRACKED `NOT_DRIVER_MANAGED` row, which is untracked now. It pins `skills/README.md` / `gen:skill-docs` / `skills/README.md: merge: unspecified` instead, the same shape (tracked, MIXED, marked regions, a generator); all cases pass. The header's class-3 roster (about `:359`–`:366`) now names two MIXED rows, with the registry noted as the former third. Comment text only. ### A touch on the frozen `scripts/pm/dispatch-gates.mjs`, under ruling 208's exception Ruling 208 R6, as `.claude/skills/pm-dispatch/references/instrument-discipline.md` carries it: 「工具位只有一个,先花在删除上;`dispatch-gates.mjs` 冻结,只在它喂的 workflow 坏了时碰」. This PR makes `packages/spec/src/migrations/registry.ts` generated and git-ignored, so the hint a gate's import of the registry yields names a file no card can touch. Two things broke as a result: `check:pm-dispatch-gates`, a `Lint & Repo Gates` leg, went red on its extension-narrowing agreement case; and a card editing only an entry file or the template stopped deriving five families that import the registry (`check:spec-changes`, `check:upgrade-guide`, `check:authorable-surface`, `check:query-options-erasure`, `check:role-word`). That is the workflow the file feeds breaking, so the file is touched under the ruling's exception, in the W3 split's shape: - **Data**: `scripts/pm/dispatch-gates.data.mjs`, +43/-2. The declared row `GENERATED_MODULE_SOURCES` (the registry module, and its committed sources `registry.ts.template` and `entries/`) with its rationale. - **Engine**: `scripts/pm/dispatch-gates.mjs`, +11/-1 against `765ae6bde4`. The data import and re-export, a five-line `generatedModuleSources` lookup and one `||` clause in `hintCovers`. - **Self-test**: `scripts/pm/dispatch-gates.self-test.mjs`. It pins the mapping with a control, proves the row against the tree on every run (module untracked and ignored by a tracked ignore file, sources tracked), and keeps mapped hints out of the extension-narrowing agreement case. One census line pin moved 734 -> 736 with the import. Removing the clause turns exactly the mapping case red (1 of 1828). Declared to the `domain:skills` seat on #7623; that seat's answer is comment 6100894139 on #22554. ## Governed text this makes false (reported, not edited) `.claude/skills/spec-property-retirement/SKILL.md:213` says the D3 step lives in `packages/spec/src/migrations/registry.ts`, and that a step-18 retirement adds its `STEP18_RATIONALE` fragment and an earlier step's `conversionIds` and `rationale` there. After this PR those hand edits belong in `registry.ts.template`: an edit to `registry.ts` is never committed. The proposed wording is in the os-dev report. ## Concurrency - **Open PR #22691** (`claude/issue-22658-skills-package`) edits `turbo.json`. Whichever lands second resolves the textual overlap. - **#19939 pass 4 S1 has landed** as PR #22715 (`f66fdc7973`) and is merged here (`84612b393b`, through `scripts/pm/os-regen-merge.sh`). Its modify/delete on `registry.ts` was resolved by `git rm` after proving its 4 hunks lie inside the os-generated regions on both sides (0 hand-written lines). The registry generated on the merged tree then equals `origin/main`'s committed blob `9aaae83bde` byte for byte, apart from the declared header lines 19, 21–26 and 38–42; the ledger reads 591 ids (532 migration) on both sides, 0 differences. The branch `claude/issue-15204-s1-position-permission-sets` (epic #15194) is unchanged: it changes only generated regions, so the same `git rm` resolves it losslessly. - **General rule for any branch forked before this lands:** a branch whose `registry.ts` diff touches lines outside the os-generated markers must port those lines into `registry.ts.template` before `git rm`. Otherwise the edit is silently dropped. ## Verification at HEAD `84612b393b` (patch round) and `765ae6bde4` (round 1) - **Patch round, at `84612b393b`** (`81ae60b20a` adds only the `os-regen-merge.sh` header comment; its self-test reads "all cases pass" there): `pnpm --filter @objectstack/spec typecheck` VERDICT 0; `pnpm --filter @objectstack/spec test` VERDICT 0, `Test Files 642 passed (642)`, `Tests 19197 passed | 1 todo (19198)`; `pnpm check:pm-dispatch-gates` "1828 cases pass" and `check-dispatch-gates.mjs --slow` "2088 cases pass"; `os-regen-merge.sh --self-test` "all cases pass"; the gate union re-derived on the 25 paths, 146 commands, "146 derived, 146 run, 0 NOT-MEASURED, 0 UNRUN", all exit 0 (including `check:dual-build-cjs-loads`, measured this time). CI on `84612b393b`: 34 success, 2 skipped. The bullets below are round 1's. - **`@objectstack/spec`**: typecheck, build and test, all green (`VERDICT command-exit 0` each). These ran on the fresh worktree above, at this commit, under `scripts/pm/os-verify-lock.sh`. - **Gates**: the union `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derives from the 21 changed paths is 146 commands, all run at this commit with exit codes captured before any pipe: - **144 green.** One of them, `check:dts-closure`, first exited 1, naming the half-built `dist/` of two plugins that my own earlier gate runner had left when its timeout killed `check:type-check-debt` mid-build. I removed those git-ignored partial trees and reran it: exit 0, 171/171 declaration files across 71 packages. - **1 red**: `check:pm-dispatch-gates` (above). - **1 NOT MEASURED**: `check:dual-build-cjs-loads`, which exited 3 because it needs every workspace package built. This PR changes no package's `dist`, and the spec tarball diff above shows its own `dist` is byte-identical. - **`dispatch-gates --ran`** over the exit-coded record: "146 derived, 145 run, 1 NOT-MEASURED, 0 UNRUN". - **Self-tests run directly**: - `node scripts/check-adr-0087-registration.mjs --self-test`: 463 assertions. - `bash scripts/ci/select-gate-families.selftest.sh`: 59 cases, 304 checks. - `node scripts/regen-artifacts.mjs --self-test` and `node scripts/git-merge-regen.mjs --self-test`: exit 0. - `tsx packages/spec/scripts/build-migration-registry.ts --self-test`: ok. - **ESLint, narrowed to the changed lintable files plus the generated `registry.ts`**: 11 files, 0 errors, 0 warnings, 0 fatal, run with the `lint` script's own `--stack-size=4000 --no-inline-config`. - Population: read from `eslint.config.mjs`, whose objects glob `**/*.{ts,…}`. `--print-config` on `registry.ts.template` answers `undefined`, so the template is outside it. - Invariance: no `parserOptions.project` (no type-aware rules), so this diff cannot move a verdict on an untouched file. The repo-wide run is CI's. ## Ablations (one-time proofs, each restored to the HEAD blob under the tool's own trap) All were run through `node scripts/ablation-replace.mjs` on the committed tree. 1. `migrationLedgerTextAt` forced to the committed era: the ADR-0087 self-test goes red on GR1, GR3 and both GR7 cases. 2. The witness's registry-generation step disabled: the real gate against `origin/main` goes red, with "Cannot find module '../src/migrations/registry'" in the witness. 3. The entry comparator swapped for `localeCompare`: the generator's self-test goes red on the new ordering case. ## Acceptance notes - `scripts/regen-artifacts.mjs` cites `.gitignore:61`, `:73` and `:108` for three other untracked rows. These were already off by 2 before this PR, and the six lines added here move two of them further. They are not gated. Noted, not changed. - The `packages/spec/src/migrations/registry.ts` path keeps its name and exports, so `export-origins/migrations.json`, `SYNC_ARCHITECTURE.md` and the source comments that name it stay true. --- _Generated by [Claude Code](https://claude.ai/code/session_01S3aAf11JjbW1mSGL1EhfFj)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f59a73c commit ed1de8c

25 files changed

Lines changed: 4054 additions & 31061 deletions
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
The migration registry `src/migrations/registry.ts` is generated at build and no longer committed
6+
7+
Clause-②: no
8+
9+
`src/migrations/registry.ts` keeps its path and its exports, and the built package carries the same
10+
`./migrations` entry as before. What changes is where the file comes from in this repository: it is
11+
git-ignored and written whole by `gen:migration-registry` from two committed sources,
12+
`src/migrations/registry.ts.template` (the hand-written step rationale, doc comments and table
13+
skeleton) and `src/migrations/entries/` (one file per entry). The generator runs on `pnpm install`
14+
(the package's new `prepare` script), as the first step of `build`, and before `typecheck`, `test`
15+
and `test:repo`; its self-test runs inside every generation. `check:migration-registry` is removed,
16+
since there is no committed copy left to compare.
17+
18+
For a contributor: add a migration entry as a file under `src/migrations/entries/` and edit any other
19+
registry prose in `registry.ts.template`. An edit to `registry.ts` itself is never committed, and the
20+
next install or build overwrites it.
21+
22+
Measured with `pnpm pack` against the previous build: 2,070 files each, and 4 differ. Those are
23+
`package.json`'s `scripts` (`build`, `typecheck`, `test` and `test:repo` now start with the generation,
24+
and `check:migration-registry` is gone; `pnpm pack` leaves `prepare` out of the packed manifest) and the
25+
three `.build-input-hash` stamps that record the build's inputs. Every `dist` file, declaration, source
26+
map and JSON Schema is byte-identical. No schema, type, export or runtime behaviour changes.

‎.gitattributes‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,10 @@
6464
# The migrations registry is the interesting one since #7297: its three append
6565
# tables now come from `packages/spec/src/migrations/entries/` (one file per
6666
# entry, the `.changeset/*.md` shape), so the conflict two retirement cards used
67-
# to have is gone at the SOURCE — different entries are different files. The
68-
# file stays out of this list anyway, because it is now MIXED: a driver that
69-
# deferred it whole would resolve its still-hand-written prose by regenerating,
70-
# which loses an edit rather than a merge. `check:migration-registry` is what
71-
# guards the generated half instead.
67+
# to have is gone at the SOURCE — different entries are different files. Since
68+
# #22554 the registry itself is git-ignored and generated whole at install and
69+
# build, so git never merges it; its hand-written prose lives in
70+
# `registry.ts.template`, which is plain source and text-merges like any other.
7271
#
7372
# The strictness ledger's COUNTS file joined at #5107 — the ledger's numbers were
7473
# the repo's hottest conflict surface and merged in the one way that hides: two

‎.github/workflows/lint.yml‎

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -283,11 +283,11 @@ jobs:
283283
# over the ten merge-group runs measured for #16496; the PM dispatch-gates
284284
# self-test alone 597 s), and none of its expensive steps read a
285285
# merge group's file surface: a docs-only group paid the full battery.
286-
# So on `merge_group` and `pull_request` the TEN scoped families below
286+
# So on `merge_group` and `pull_request` the NINE scoped families below
287287
# -- each step carrying `if: steps.gate-families.outputs.<id> != 'skip'`
288288
# -- run only when the changed paths touch the files that family reads.
289-
# One of the ten, `migration_registry` (#19753), is a gate this job did
290-
# not run before at all; the other nine were scoped away from it.
289+
# (A tenth, `migration_registry` (#19753), retired with its gate in
290+
# #22554: the registry it compared is no longer committed.)
291291
# `push` on main and the scheduled full run keep the whole battery: the
292292
# script runs everything for any event it does not scope.
293293
#
@@ -399,24 +399,12 @@ jobs:
399399
- name: ADR anchors + number uniqueness (governed code names its decision)
400400
run: pnpm check:adr-anchors
401401

402-
# Migration registry matches its entry files (#19753). `registry.ts` is
403-
# the generated concatenation of `packages/spec/src/migrations/entries/`,
404-
# it ships in the spec package's `dist`, and this check is the only
405-
# proof the two agree -- `check:generated --reconcile-only` (in the
406-
# `Type Check · source gates` job) proves the script is classified,
407-
# never that the artifact is current. It ran
408-
# in no CI step, so an entry edited without `gen:migration-registry`
409-
# shipped the old text with every required check green.
410-
#
411-
# Scoped, on the maintainer's ruling for that card: a step in THIS
412-
# required job, run when the change touches what the check reads
413-
# (`migration_registry` in the selector above). ⛔ Not a separate
414-
# `paths:`-filtered job: one that never reports on an unrelated PR
415-
# leaves a required context pending forever. Cheap -- tsx over one
416-
# directory, no build (~1.4 s measured locally) -- so it sits early.
417-
- name: Migration registry matches its entry files
418-
if: steps.gate-families.outputs.migration_registry != 'skip'
419-
run: pnpm --filter @objectstack/spec check:migration-registry
402+
# No "migration registry matches its entry files" step since #22554:
403+
# `packages/spec/src/migrations/registry.ts` is git-ignored and generated
404+
# whole from `registry.ts.template` + `entries/` by `gen:migration-registry`,
405+
# which `pnpm install` above already ran (spec's `prepare`, self-test
406+
# included). There is no committed copy left to compare, and an entry the
407+
# generator refuses fails that install step, loudly, in every job.
420408

421409
# Enforces the no-restricted-imports guard against @objectstack/spec root
422410
# namespace imports (the dormant rule was never run in CI). Syntactic

‎.gitignore‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ packages/*/*.tsbuildinfo
6262
# Generated JSON Schema (rebuilt by `pnpm gen:schema` during build)
6363
packages/spec/json-schema/
6464

65+
# Generated migration registry (rebuilt by `pnpm gen:migration-registry` on
66+
# install and as the first step of build, from registry.ts.template + entries/),
67+
# and the staging file its atomic write renames into place.
68+
packages/spec/src/migrations/registry.ts
69+
packages/spec/src/migrations/registry.ts.*.tmp
70+
6571
# Generated bundle size reports
6672
packages/spec/bundle-size-report.json
6773

‎packages/spec/package.json‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@
264264
"protocol-upgrade-guide.md"
265265
],
266266
"scripts": {
267-
"build": "pnpm gen:schema && pnpm gen:openapi && tsup && if [ -z \"$OS_SKIP_DTS\" ]; then NODE_OPTIONS=\"--max-old-space-size=6144\" BUILD_DTS=true tsup; fi && node ../../scripts/check-dts-emitted.mjs && node ../../scripts/check-dts-references.mjs && node ../../scripts/check-dev-prereqs.mjs --stamp",
267+
"build": "pnpm gen:migration-registry && pnpm gen:schema && pnpm gen:openapi && tsup && if [ -z \"$OS_SKIP_DTS\" ]; then NODE_OPTIONS=\"--max-old-space-size=6144\" BUILD_DTS=true tsup; fi && node ../../scripts/check-dts-emitted.mjs && node ../../scripts/check-dts-references.mjs && node ../../scripts/check-dev-prereqs.mjs --stamp",
268+
"prepare": "pnpm gen:migration-registry",
268269
"dev": "tsc --watch",
269270
"clean": "rm -rf dist",
270271
"gen:schema": "OS_EAGER_SCHEMAS=1 tsx scripts/build-schemas.ts",
@@ -295,13 +296,12 @@
295296
"check:llms-txt": "tsx scripts/check-llms-txt.ts --self-test && tsx scripts/check-llms-txt.ts",
296297
"check:authorable-surface": "OS_EAGER_SCHEMAS=1 tsx scripts/build-schemas.ts --check",
297298
"gen:migration-registry": "tsx scripts/build-migration-registry.ts",
298-
"check:migration-registry": "tsx scripts/build-migration-registry.ts --self-test --check",
299299
"gen:spec-changes": "tsx scripts/build-spec-changes.ts",
300300
"check:spec-changes": "tsx scripts/build-spec-changes.ts --check",
301301
"gen:upgrade-guide": "tsx scripts/build-upgrade-guide.ts",
302302
"check:upgrade-guide": "tsx scripts/build-upgrade-guide.ts --check",
303-
"test": "vitest run --project local",
304-
"test:repo": "vitest run --project repo",
303+
"test": "pnpm gen:migration-registry && vitest run --project local",
304+
"test:repo": "pnpm gen:migration-registry && vitest run --project repo",
305305
"test:watch": "vitest",
306306
"test:coverage": "vitest run --coverage",
307307
"check:liveness": "tsx scripts/liveness/check-liveness.mts",
@@ -320,7 +320,7 @@
320320
"check:test-typecheck": "tsx ../../scripts/check-test-typecheck.mts --self-test && tsx ../../scripts/check-test-typecheck.mts --package packages/spec --project tsconfig.test.json",
321321
"gen:test-typecheck-debt": "tsx ../../scripts/check-test-typecheck.mts --update --package packages/spec --project tsconfig.test.json",
322322
"check:scripts-typecheck": "tsc --noEmit -p tsconfig.scripts.json",
323-
"typecheck": "tsc --noEmit && pnpm check:scripts-typecheck && pnpm check:test-typecheck"
323+
"typecheck": "pnpm gen:migration-registry && tsc --noEmit && pnpm check:scripts-typecheck && pnpm check:test-typecheck"
324324
},
325325
"keywords": [
326326
"objectstack",

‎packages/spec/scripts/build-migration-registry-entry.test.ts‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
// `build-migration-registry.ts` has TWO kinds of caller now, and its entry guard
44
// is the only thing telling them apart:
55
//
6-
// - pnpm RUNS it (`gen:migration-registry`, `check:migration-registry`), and
7-
// write mode rewrites `src/migrations/registry.ts`;
6+
// - pnpm RUNS it (`gen:migration-registry`, on install, in `build`, before
7+
// `typecheck` and `test`), and every run rewrites `src/migrations/registry.ts`
8+
// from the template and the entries;
89
// - `build-schemas.ts` IMPORTS it, for `shardNameFor` — so the entry file each
910
// registration remedy names is the one name the generator accepts, read from
1011
// the rule `entries/README.md` documents instead of restated beside it.
@@ -66,8 +67,9 @@ describe('build-migration-registry.ts — run, it speaks; import, it runs nothin
6667
);
6768
const r = tsx([probe]);
6869
expect(r.status, r.stderr).toBe(0);
69-
// Write mode would have printed `✓ wrote src/migrations/registry.ts (…)`, and
70-
// check mode `✓ … is current` — any line beyond the probe's own is the defect.
70+
// A run would have printed its self-test line and then `✓ wrote
71+
// src/migrations/registry.ts (…)` or `✓ … is current` — any line beyond the
72+
// probe's own is the defect.
7173
expect(r.stdout).toBe('17.data__AggregationNode__distinct.ts\n');
7274
expect(r.stderr).toBe('');
7375
});

0 commit comments

Comments
 (0)