Skip to content

docs(sdui): three passages name the PIN as the generator version default, not the record - #18956

Merged
os-bill merged 2 commits into
mainfrom
claude/issue-18879-retired-version-default-prose
Sep 18, 2026
Merged

os-bill merged 2 commits into
mainfrom
claude/issue-18879-retired-version-default-prose

Conversation

@os-bill

@os-bill os-bill commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

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:

  1. scripts/check-sdui-manifest.mjs:228 (artefact missing) — flagless Regenerate: prescription
  2. scripts/check-sdui-manifest.mjs:275 (sha256 mismatch) — flagless Regenerate: prescription
  3. scripts/sdui-manifest.record.json:10 — flagless prescription; also held by open PR sdui-parser: port inert-quick-add and member-type-mismatch from objectui, re-record the lockstep and bump the pin #18723
  4. 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 fails 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

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 fix(scripts): the manifest generator defaults its @object-ui version from the PIN, not the record #18875 than before. None of them is a site. Carrier: none — nothing here needs changing.

Generated by Claude Code

…n default

The record-derived `--objectui-version` default is gone from
`scripts/gen-sdui-manifest-node.mjs`: with no flag it reads the version the
PINNED commit declares, through check 4's own `readPinnedDeclaredVersion`
oracle, and REFUSES when that cannot be read. Three passages still described
the retired default as current.

- `scripts/check-sdui-manifest.mjs` check 4's problem text: the reason clause
  for the prescription on its next line asserted "The generator REUSES the
  version already recorded when --objectui-version is not passed". It now
  names the pin as the source and lists how a disagreeing record still
  arises, so the flagged prescription below it keeps a true reason.
- The same file's header, check 4's own rationale: "`--objectui-version`
  unset makes it REUSE the version already in the record" — the same retired
  default, one grep-phrase away from the one above, which is why the card's
  census missed it. Repaired in place: same file, same defect class, same
  gate family.
- `packages/spec/scripts/check-react-blocks-declaration-parity.ts`: the node
  producer "enumerates the PUBLISHED @object-ui/* packages at the version
  named in scripts/sdui-manifest.record.json". That record is the run's
  OUTPUT today, never where it reads the version from.

Prose only. The gate's verdicts do not move: its three non-self-test arms are
byte-identical before and after, on both streams, and `--self-test` is
byte-identical and green.

Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3
Co-authored-by: Claude <noreply@anthropic.com>
@os-bill os-bill added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 18, 2026 — with Claude
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 16cb493d5640f4e9bf762a41ac016d0c6113c92f → packageMentionDocs.

@os-bill
os-bill marked this pull request as ready for review September 18, 2026 07:47
@os-bill
os-bill added this pull request to the merge queue Sep 18, 2026
Merged via the queue into main with commit 106717c Sep 18, 2026
43 of 44 checks passed
@os-bill
os-bill deleted the claude/issue-18879-retired-version-default-prose branch September 18, 2026 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate tooling

Projects

None yet

2 participants