Skip to content

Commit 106717c

Browse files
os-billclaude
andauthored
docs(sdui): three passages name the PIN as the generator version default, not the record (#18956)
Fixes #18879 Clause-②: no PR #18875 retired the generator's record-derived version default. `scripts/gen-sdui-manifest-node.mjs` now resolves the version in one order — `--objectui-version` when passed, otherwise what the PINNED objectui commit declares in `packages/core/package.json` (through `check-sdui-manifest.mjs`'s own exported `readPinnedDeclaredVersion`) — and REFUSES when neither answers. Three passages still described the retired default as current. This repairs those three, and leaves four others alone because they are conditional, not broken. ## The card's six sites are not one class, and there is a seventh I enumerated every site on this tree and classified each. The census phrase the card used (`gen-sdui-manifest-node`, 30 hits tree-wide) plus two wording sweeps (`REUSE`, `already in the record` / `already recorded` / `already sitting`) is what the enumeration is taken from. Class (a) — literally false today, repaired here: 1. `scripts/check-sdui-manifest.mjs` check 4's problem text (was :318-319) 2. `packages/spec/scripts/check-react-blocks-declaration-parity.ts` (was :87-88) 3. `scripts/check-sdui-manifest.mjs` header, check 4's own rationale (was :43-47) — NOT on the card's six; see "The seventh site" below Class (b) — conditional, not broken, deliberately untouched: 4. `scripts/check-sdui-manifest.mjs:228` (artefact missing) — flagless `Regenerate:` prescription 5. `scripts/check-sdui-manifest.mjs:275` (sha256 mismatch) — flagless `Regenerate:` prescription 6. `scripts/sdui-manifest.record.json:10` — flagless prescription; also held by open PR #18723 7. `packages/spec/scripts/manifest-prescription.ts:81` — flagless prescription, and its own text already points the reader at where the exact call is printed ## (a) verbatim, before and after ### 1. check 4's problem text Before (the false sentence is the REASON CLAUSE for the prescription on the line below it): ``` describes a registry this pin does not name. The generator REUSES the version already recorded when --objectui-version is not passed, which is how a regeneration re-records a new pin under an old version. Regenerate against the pin: node scripts/gen-sdui-manifest-node.mjs --objectui-version 9.9.9-what-the-pin-declares ``` After: ``` describes a registry this pin does not name. The generator reads this version from the PIN, never from this record, so a disagreement came from outside that default: a version named explicitly on some other run, a hand edit, or a record written before the default was fixed to read the pin. Regenerate against the pin: node scripts/gen-sdui-manifest-node.mjs --objectui-version 9.9.9-what-the-pin-declares ``` Both blocks are real output, captured by driving `checkTree` against the fixture shape the script's own self-test uses (a green tree plus a throwaway objectui whose declared version disagrees with the record). The prescription line is unchanged. Why the new sentence is true of today's generator: `gen-sdui-manifest-node.mjs:149-168` takes `--objectui-version` when passed, otherwise calls `readPinnedDeclaredVersion(pin)` and `fail`s on any status but `resolved`; it never reads `record.objectuiPackagesVersion`. Check 4 only runs when `pin === record.objectuiSha` (check 3 returns early otherwise), so at this point the record names the LIVE pin and its version field disagrees with what that pin declares. The three routes the new sentence lists are the ones that survive: an explicit `--objectui-version` naming another version, a hand edit, and a record written before that default was fixed. ### 2. the node producer's description in the parity gate header Before: ``` // node `scripts/gen-sdui-manifest-node.mjs` writes the TRACKED repo-root // artefact under plain Node — no browser, no objectui build. It // enumerates the PUBLISHED `@object-ui/*` packages at the version named // in `scripts/sdui-manifest.record.json`. ``` After: ``` // node `scripts/gen-sdui-manifest-node.mjs` writes the TRACKED repo-root // artefact under plain Node — no browser, no objectui build. It // enumerates the PUBLISHED `@object-ui/*` packages at the version // `--objectui-version` names, else the one the PINNED commit's // `packages/core/package.json` declares — and REFUSES when neither // answers. `scripts/sdui-manifest.record.json` is what that run // WRITES, never where it reads the version from. ``` Why the new sentence is true of today's generator: the record is the run's OUTPUT (`gen-sdui-manifest-node.mjs:229-240` writes `nextRecord` with `objectuiPackagesVersion: version`), never its input. The paragraph forty lines below this one in the same header already says the version is "read off the pinned commit's `packages/core/package.json`", so the file now agrees with itself. ### 3. the seventh site — the same defect, one grep-phrase away The card's census missed it because the wording differs: the problem text says "the version already recorded", the header says "the version already in the record", so the card's own firing control never sounded on it. Before: ``` * with nothing asking whether V is C's version at all (#18611). The live * way to write that record is the generator's own default — * `--objectui-version` unset makes it REUSE the version already in the * record, so a regeneration after a pin bump keeps the OLD version string * while re-recording the NEW pin, and checks 1-3 stay green throughout. ``` After: ``` * with nothing asking whether V is C's version at all (#18611). The * generator's own default does not write such a record — `--objectui-version` * unset reads the version off the PIN and REFUSES when the pin cannot be * read — but an explicit wrong version, a hand edit, or a record written * before that default was fixed still produce one, and checks 1-3 stay * green throughout. ``` Repaired in place rather than filed: same file, same defect class, same gate family, mechanical, and the correct shape was already pinned by the sibling passage above. A full scan of all 25 open non-release PRs (file lists read one by one) found no other claim on this file. ## Firing control `git grep -n 'version already recorded' -- '*.mjs' '*.ts' '*.md'` - before: 1 hit (`scripts/check-sdui-manifest.mjs:318`) - after: 0 hits, exit 1 The instrument is not dead. Two positive controls of the same command shape, run on the same tree after the edit: `'version already sitting in the record'` answers 1 hit in `scripts/gen-sdui-manifest-node.mjs`, and `'Regenerate against the pin'` answers 1 hit in `scripts/check-sdui-manifest.mjs` — the very file the zero is claimed about, so the grep demonstrably still reaches it. ## (b) decided, with live readings, and the decision differs from triage Triage framed `:228` / `:275` as "a gate handing you a command it will itself refuse", and half of its `p2` audience argument rests on that reading. I agree with the PM's narrowing, and I did not take the reading off the source: I ran the generator both ways in a scratch root, so nothing in this tree was written. The scratch root was made discriminating on purpose — its record was seeded with `objectuiPackagesVersion: "0.0.0-BOGUS-SCRATCH"`, a version that exists on no registry. Had the retired default still been live, the run would have tried to install it. Leg 1 — no resolvable pin (`OBJECTUI_ROOT` pointed at a path with no checkout): exit 1, nothing written, and the refusal carries its own two remedies: ``` ✗ gen-sdui-manifest-node: no --objectui-version, and the pinned commit's declared version could not be read: no objectui checkout at /nonexistent-objectui (no .git there). Set OBJECTUI_ROOT to one that carries the pin. ⛔ This script does NOT fall back to the version in scripts/sdui-manifest.record.json: after a pin bump that re-records the NEW pin under the OLD version string, and check-sdui-manifest.mjs check 4 reds exactly that record. Either: - point OBJECTUI_ROOT at an objectui checkout carrying 53ded82bf7a4…, or - pass --objectui-version {the @object-ui version that pin ships} explicitly. ``` Leg 2 — resolvable pin, full run including the network install: exit 0. ``` → installing @object-ui/* 17.6.0 into /tmp/sdui-manifest-gen-OcPzor (npm, network)... → enumerating the registry (16 modules)... ✓ wrote sdui.manifest.json (57 components, 66910 bytes, sha256 49211fee7792…) ✓ re-recorded scripts/sdui-manifest.record.json at pin 53ded82bf7a4 / @object-ui 17.6.0 (version from packages/core/package.json at objectui 53ded82bf7a4… (read from /home/user/objectui)) ``` It resolved `17.6.0` — the version objectui declares at the pin — over the bogus `0.0.0-BOGUS-SCRATCH` sitting in the record, and overwrote the record with it. The manifest it produced carries sha256 `49211fee7792…`, byte-matching the artefact tracked here. So `:228` and `:275` are not broken. The flagless call they print writes the correct artefact whenever the pin's declared version is readable, and when it is not, it refuses loudly with the remedy in its own failure text rather than writing a drifted record. That is the behaviour #18875 was for. They are conditional, and a conditional prescription that fails loudly and names its own fix is not the shape this repo files cards about. Sites 6 and 7 in the list above are the same conditional shape; site 7 (`manifest-prescription.ts:81`) even printed itself during this round's gate sweep, intact and actionable, when `check:react-declaration-parity` ran without `MANIFEST` set. One consequence worth writing down rather than acting on: because the flagless default now reads the pin, the flagless call would ALSO repair the check-4 record. The flagged prescription is kept unchanged anyway — it names the value in the command, which is the self-evidencing form, and this round is prose only. ## DARK — the gate's verdicts do not move `scripts/check-sdui-manifest.mjs` run before and after the edit, three arms, both streams captured to files and compared with `cmp`: | arm | exit before | exit after | stdout | stderr | |---|---|---|---|---| | plain (resolves the `../objectui` sibling) | 0 | 0 | identical, 290 bytes | identical, 0 bytes | | `OBJECTUI_ROOT` unresolvable | 0 | 0 | identical, 496 bytes | identical, 0 bytes | | `OBJECTUI_ROOT` unresolvable + `--require-objectui` | 1 | 1 | identical, 0 bytes | identical, 295 bytes | `--self-test` is green and its output is byte-identical before and after: 11 cases, battery floor 11. The strings this PR edits live on failure paths, so a green tree never prints them — which is exactly why the verdict bytes do not move. ## Gates Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`, run one by one with each exit code landed to disk before anything read it, then reconciled with `--ran` carrying those codes. ``` ✓ dispatch-gates --ran: 72 derived famil(ies) accounted for — 70 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3). ``` The two NOT MEASURED are `check:dual-build-cjs-loads` and `check:lean-entry-closure`. Both exit 3 — their own `PREREQUISITE NOT MET` code — because they load built output and this worktree has no full `pnpm build`. Both self-tests passed (93 and 22 cases). Neither can be moved by a comment-only diff; they are declared to CI. One gate exits 1 under the derived spelling and 0 under CI's: `check:react-declaration-parity` refuses when `MANIFEST` is unset, which is a prerequisite, not a red. Run as `lint.yml` runs it — `MANIFEST="$PWD/sdui.manifest.json" ... --baseline react-declaration-parity.baseline.json --strict` — it exits 0 with "no new DECLARATION divergence vs accepted baseline". Derivation stability: the 72-family list came out byte-identical at all three tree states this branch passed through (`625db0e853`, `0ea26d37e8`, `92eee4dcc5`), so the tool's STALE TREE notice — raised because a sibling agent's fetch keeps advancing the shared `origin/main` ref — changed nothing about what is owed here. ## Tests and lint - `pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 scripts/check-react-blocks-declaration-parity.test.ts scripts/build-schemas-check-mode.test.ts` — 2 files, 115 tests, all passed. These are the suites that name the two edited scripts. `scripts/check-sdui-manifest.mjs` has no sibling test file in `scripts/`; its `--self-test` is its suite, and it is above. - `pnpm --filter @objectstack/spec typecheck` — exit 0. - `pnpm --filter @objectstack/spec check:scripts-typecheck` — exit 0; this is the program that compiles the edited `packages/spec/scripts/**` file. - `pnpm --filter @objectstack/spec build && pnpm --filter @objectstack/spec check:generated` after merging `main` — all 15 generated artifacts up to date. - Dependency-closure build `pnpm --filter '@objectstack/spec^...' build` is an empty run here: "No projects matched the filters" — `packages/spec` has no workspace dependencies. - Lint, the whole union, as CI runs it, at `92eee4dcc5`: `eslint . --no-inline-config --format json` over a population of **6855 files** read from eslint's own JSON output — 0 errors, 0 warnings. Narrowed to the two edited files: 2 files, 0 errors, 0 warnings. `eslint.config.mjs:326-328` records that this repo "never enables type-aware linting (no `parserOptions.project`, no typed `@typescript-eslint` rules) for ANY file", so nothing in this diff can move an untouched file's verdict either way. ## Changeset `skip-changeset`, measured rather than assumed: - No package manifest in the repo declares a `files[]` entry reaching `scripts/` — 76 manifests scanned, 0 hits. - `packages/spec`'s `files[]` is `dist`, `json-schema`, `liveness`, `prompts`, `llms.txt`, `README.md`, `src/**/*.zod.ts`, `CHANGELOG.md`, `api-surface`, `spec-changes.json`. `scripts/` is not among them. - Grepping every one of those published paths (plus all 202 `src/**/*.zod.ts`) for two distinctive strings from this diff returns zero hits, exit 1. Positive control, same command shape: `PageComponentSchema` answers from `dist/identity/index.js` and three siblings. - `scripts/check-sdui-manifest.mjs` is a repo-root script belonging to no package. Nothing published moves, so the tarballs do not move. ## Read-only fences, re-taken at start of work - `scripts/sdui-manifest.record.json` is held by open PR #18723 (state open, draft, 11 files) — confirmed by reading that PR's file list directly, not inherited. Untouched here. Its own stale-ish prescription is class (b) anyway, so the fence costs this round nothing. - The same scan confirmed #18723 does NOT hold `check-sdui-manifest.mjs`, `check-react-blocks-declaration-parity.ts` or `gen-sdui-manifest-node.mjs`, and no other open PR holds any of them. - `scripts/gen-sdui-manifest-node.mjs` is this round's source of truth and is untouched. - No self-test making every printed prescription runnable was added. That is a new gate and it is not on this card. - No product code under `packages/spec/src/`. ## Acceptance notes Observed, deliberately not filed: - The card counts "six" sites; a full sweep finds a seventh, in the same file, repaired here under the bounded in-place rule. Noted so the census phrase is on record: a wording sweep keyed on one spelling ("already recorded") will not find its sibling spelling ("already in the record"). Who would hit it: the next reader of check 4's rationale — the same audience as the problem text, which is why it is repaired rather than noted. - `docs/releases-maintenance.md:116` / `:279`, `scripts/bump-objectui.sh:11` / `:705` / `:739` and `scripts/build-console.sh:282` / `:297` all print the FLAGGED form and are correct today; `scripts/sdui-manifest.record.json:5` and `check-sdui-manifest.mjs:19-21` describe the version as "the version `.objectui-sha` ships", which is more true after #18875 than before. None of them is a site. Carrier: none — nothing here needs changing. --- _Generated by [Claude Code](https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 89c6ec5 commit 106717c

2 files changed

Lines changed: 14 additions & 9 deletions

File tree

‎packages/spec/scripts/check-react-blocks-declaration-parity.ts‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,11 @@
8484
// gate on the result — so what it reads is the pinned SOURCE.
8585
// node `scripts/gen-sdui-manifest-node.mjs` writes the TRACKED repo-root
8686
// artefact under plain Node — no browser, no objectui build. It
87-
// enumerates the PUBLISHED `@object-ui/*` packages at the version named
88-
// in `scripts/sdui-manifest.record.json`.
87+
// enumerates the PUBLISHED `@object-ui/*` packages at the version
88+
// `--objectui-version` names, else the one the PINNED commit's
89+
// `packages/core/package.json` declares — and REFUSES when neither
90+
// answers. `scripts/sdui-manifest.record.json` is what that run
91+
// WRITES, never where it reads the version from.
8992
//
9093
// ⚠️ "The registry is a browser app so nothing enumerates it from Node" was true
9194
// when this header was written and is now FALSE — measured 2026-08-29,

‎scripts/check-sdui-manifest.mjs‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@
4040
* the version `packages/core/package.json` DECLARES at the pinned commit.
4141
* Checks 1-3 reach both fields and relate neither: the version was read
4242
* as a presence check only, so the record could name pin C and version V
43-
* with nothing asking whether V is C's version at all (#18611). The live
44-
* way to write that record is the generator's own default —
45-
* `--objectui-version` unset makes it REUSE the version already in the
46-
* record, so a regeneration after a pin bump keeps the OLD version string
47-
* while re-recording the NEW pin, and checks 1-3 stay green throughout.
43+
* with nothing asking whether V is C's version at all (#18611). The
44+
* generator's own default does not write such a record — `--objectui-version`
45+
* unset reads the version off the PIN and REFUSES when the pin cannot be
46+
* read — but an explicit wrong version, a hand edit, or a record written
47+
* before that default was fixed still produce one, and checks 1-3 stay
48+
* green throughout.
4849
* This is the only check here that needs an input from outside this tree,
4950
* so it is the only one that can report NOT CHECKED — see below.
5051
*
@@ -315,8 +316,9 @@ export function checkTree(root, { objectuiRoot, requireObjectui = false, onVersi
315316
`the record's two objectui fields describe different commits: objectuiPackagesVersion is ${JSON.stringify(record.objectuiPackagesVersion)},\n` +
316317
` but objectui ${pin.slice(0, 12)}… — the pin the record itself names — declares ${JSON.stringify(versionLeg.version)} in ${OBJECTUI_VERSION_FILE}\n` +
317318
` (read from ${versionLeg.where}). The manifest was generated from the published ${record.objectuiPackagesVersion} packages, so it\n` +
318-
' describes a registry this pin does not name. The generator REUSES the version already recorded when\n' +
319-
' --objectui-version is not passed, which is how a regeneration re-records a new pin under an old version.\n' +
319+
' describes a registry this pin does not name. The generator reads this version from the PIN, never\n' +
320+
' from this record, so a disagreement came from outside that default: a version named explicitly on\n' +
321+
' some other run, a hand edit, or a record written before the default was fixed to read the pin.\n' +
320322
` Regenerate against the pin: node scripts/gen-sdui-manifest-node.mjs --objectui-version ${versionLeg.version}`,
321323
);
322324
} else if (versionLeg.status === 'unsupported') {

0 commit comments

Comments
 (0)