Skip to content

fix(scripts): the manifest generator defaults its @object-ui version from the PIN, not the record - #18875

Merged
os-bill merged 1 commit into
mainfrom
claude/issue-18819-generator-version-default-oracle
Sep 18, 2026
Merged

os-bill merged 1 commit into
mainfrom
claude/issue-18819-generator-version-default-oracle

Conversation

@os-bill

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

Copy link
Copy Markdown
Collaborator

Fixes #18819

Clause-②: no

The defect, re-measured on this branch's base

origin/main 36583e989b. The generator read its two provenance fields at two different
moments:

:129   const version = arg('--objectui-version') ?? record.objectuiPackagesVersion;
:199   objectuiSha: pin,
:200   objectuiPackagesVersion: version,

objectuiSha is re-read from the LIVE .objectui-sha; objectuiPackagesVersion fell back to
the value already sitting in scripts/sdui-manifest.record.json. A regeneration after a pin bump
therefore wrote the NEW pin under the OLD version string — a record whose two objectui fields
describe two different commits, which is exactly the record scripts/check-sdui-manifest.mjs
check 4 rejects. The person that reds is the one who followed the documented bump procedure, so
the producer is where it gets fixed.

Step one, before writing any fix: is that path reachable today?

The counterfactual on :129 is that the defect is unreachable if arg('--objectui-version') is
never empty. It is reachable. Paths, not counts.

No automated caller exists at all. No package.json script, no workflow step and no shell
line executes this generator. scripts/bump-objectui.sh and scripts/build-console.sh only
echo the command. Every invocation is therefore a person or an agent typing one of the
spellings the tree documents.

Of those spellings, six omit --objectui-version:

path spelling
scripts/check-sdui-manifest.mjs:228 Regenerate: node scripts/gen-sdui-manifest-node.mjs — printed when the artefact is missing
scripts/check-sdui-manifest.mjs:275 Regenerate: node scripts/gen-sdui-manifest-node.mjs — printed on a sha256 mismatch
scripts/sdui-manifest.record.json:10 Regenerate + re-record: node scripts/gen-sdui-manifest-node.mjs
packages/spec/scripts/manifest-prescription.ts:81 regenerate it and its record with `node scripts/gen-sdui-manifest-node.mjs`
scripts/gen-sdui-manifest-node.mjs:8 the bare usage line
scripts/gen-sdui-manifest-node.mjs:9 the --modules-root DIR offline usage line

Two of those six are printed by the gate itself. The remaining spellings do carry the flag:
AGENTS.md:156, docs/releases-maintenance.md:116 and :279, scripts/bump-objectui.sh:11 and
:739, scripts/build-console.sh:297, scripts/check-sdui-manifest.mjs:301 :303 :320.

The other paths that name the generator carry no command at all and are listed here for
completeness: .github/workflows/lint.yml:799 (a comment),
packages/spec/scripts/check-generated.ts:391,
packages/spec/scripts/check-react-blocks-declaration-parity.ts:85, and
packages/spec/scripts/check-react-blocks-declaration-parity.test.ts:565 :569 (a pin test on
the prescription text).

A or B — decided by that reading, not by preference

Zero automated call sites means option B's stated cost ("every call site has to change") is
nearly zero in code. But B is not free: it would turn all six documented no-flag spellings into
refusals, including the --modules-root offline mode, and it would refuse even when the answer is
sitting in the objectui checkout the bump already required.

So: A for the default, B for the residue.

  • --objectui-version still wins when passed.
  • Otherwise the version is what packages/core/package.json DECLARES at the pinned commit, read
    through check-sdui-manifest.mjs's exported readPinnedDeclaredVersion — the same function
    check 4 judges the written record with, imported rather than re-typed. Producer and gate now
    read one oracle; two readers of two oracles is where this drift came from.
  • When that oracle cannot answer (no objectui checkout, or one that does not carry the pin) the
    generator REFUSES and names both remedies. An unread version is never converted into a version
    string — Route and surface ownership §3, prefer failing to falling back, and Prime Directive
    Add comprehensive test suite for Zod schema validation #12's ban on a lenient ?? fallback in place of fixing the producer.

Importing the gate's exported oracle changes no gate: scripts/check-sdui-manifest.mjs is
untouched in this diff, and its CLI body is behind isEntrypoint(import.meta.url), so importing
it runs nothing.

Verification

Every leg below ran against a fixture tree in a scratchpad, or against the real repo with a trap
and a proved restore. .objectui-sha and scripts/sdui-manifest.record.json are read-only this
round; neither is in this diff.

LIT — pin bumped, --objectui-version not passed. Both legs read.

A synthetic objectui checkout with two commits (a183cfbf… declaring 17.6.0, 51ecffcc…
declaring 18.0.0-fixture), a stub @object-ui install behind --modules-root, and a fixture
record naming the OLD sha at 17.6.0. The fixture pin is the NEW sha.

leg generator record written check-sdui-manifest.mjs
before 36583e989b 51ecffccfb32 / 17.6.0 — new pin, old version exit 1, check 4 red
after this branch 51ecffccfb32 / 18.0.0-fixture exit 0, green

The before leg's gate output is check 4 naming the defect verbatim:

the record's two objectui fields describe different commits: objectuiPackagesVersion is "17.6.0",
  but objectui 51ecffccfb32… — the pin the record itself names — declares "18.0.0-fixture" in packages/core/package.json

DARK — pin not bumped. Reads zero, on the REAL artefact.

Not a fixture: the real scripts/gen-sdui-manifest-node.mjs, the real pin
53ded82bf7a494f54e344e19099dbf00854b8694, and the real published @object-ui/* 17.6.0 set
installed once and reused by both legs so the install cannot be the variable. The base generator
was swapped in on disk, its arrival proved by anchor counts before the leg ran
(?? record.objectuiPackagesVersion = 1, readPinnedDeclaredVersion = 0, and a git hash-object
differing from the HEAD blob), then restored.

leg after  (fixed) : 57 components, 66910 bytes, sha256 49211fee7792cf51174930dc2c1be2169d5175f77a83491f68f90b3f0c19e69d
leg before (base)  : 57 components, 66910 bytes, sha256 49211fee7792cf51174930dc2c1be2169d5175f77a83491f68f90b3f0c19e69d
cmp: BYTE-IDENTICAL

That sha256 is also the one the tracked record already carries, and the tracked
sdui.manifest.json HEAD blob is still 78f870e42fe9 — unmoved. Restore proved by state, not by
an exit code: git diff HEAD empty and git status --porcelain empty afterwards.

Two further legs

  • Refusal residue. Pin bumped, no flag, oracle unreachable (OBJECTUI_ROOT at a directory
    with no .git): base generator exits 0 and silently writes the drifted record; this branch
    exits 1, writes no manifest, and leaves the record untouched.
  • Explicit precedence. --objectui-version 99.1.2-explicit is honoured unchanged on both
    legs; the success line now also names where the version came from.

Gates

  • node scripts/check-sdui-manifest.mjs — exit 0 on the clean tree, and its check 4 leg
    resolved for real: "@object-ui 17.6.0 is the version objectui 53ded82bf7a4… declares in
    packages/core/package.json (read from /home/user/objectui)".
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 26
    commands; all 26 run, all exit 0, and --ran with exit codes recorded reconciles:
    "26 derived famil(ies) accounted for — 26 run, 0 NOT-MEASURED (a DERIVED zero)".
  • The seven roster families the tool flags as "roster under scripts, which one of your paths is
    in — silence is not evidence in EITHER direction" were run too. Six exit 0.
    pnpm check:published-readme-exports exits 3 — PREREQUISITE NOT MET (46 packages unbuilt);
    that is NOT MEASURED, not a finding, and this diff moves no package source and no README.
  • pnpm lint (eslint . --no-inline-config), the whole repo, exit 0 at 1c3a721ac1.
  • pnpm check:nul-bytes exit 0; an independent control-byte scan of the changed file is clean.

No changeset: nothing published moves. scripts/** appears in no package's files[] and the
root package is private, so no released package's contents change.

Acceptance notes

Noted, not filed — none is a reproducible defect, a declared-contract violation, or a
metadata-authoring trap, so none earns a card under Prime Directive #10:

  • scripts/check-sdui-manifest.mjs check 4's header paragraph, and its check-4 failure text at
    :318-319, both explain the producer default this PR removes ("The generator REUSES the version
    already recorded when --objectui-version is not passed"). After this lands those sentences
    describe history rather than current behaviour. The gate is fenced read-only for this card, so
    they are left exactly as they are. The check itself stays load-bearing — it still catches a
    hand-edited record, an explicitly-wrong --objectui-version, and any other producer.
  • packages/spec/scripts/check-react-blocks-declaration-parity.ts:88-89 says the node producer
    "enumerates the PUBLISHED @object-ui/* packages at the version named in
    scripts/sdui-manifest.record.json". That sentence is wrong-by-default after this change. Not
    fixed in place: editing it pulls packages/spec into the diff and with it a whole gate family
    this card does not otherwise owe, against the bounded-in-place-fix condition of adding no new
    verification surface.
  • The residual hole this PR deliberately does not close: an operator who passes
    --objectui-version explicitly and wrongly still writes a drifted record. The generator
    could warn when an explicit value disagrees with the resolvable pin oracle. Check 4 already reds
    the resulting record, so this is a loudness improvement, not a correctness gap.
  • [finding] the tracked root sdui.manifest.json and the browser dump differ on the fields the parity gate consumes (18 of 57 components; dataSource missing on 15 in the root artefact) — the gate's verdict set is identical under both today, which is the configuration in which the drift is least visible #17735 is not addressed here — whether the published tarballs at a version were built from the
    pinned commit is that card's producer question, and it carries needs-user-decision. This
    change moves the version's SOURCE and nothing about that relation. fix(scripts): relate the recorded @object-ui version to the objectui pin #18814's check 4 is not
    modified here either.

Fenced files honoured: scripts/sdui-manifest.record.json and .objectui-sha are held by open PR
#18723 and are read-only in this round. The real DARK leg did rewrite the record as a side effect
of running the generator, exactly as warned; both were restored from HEAD and the restore is
proved by an empty git diff HEAD, never by an exit code.


Generated by Claude Code

…from the PIN, not the record

`gen-sdui-manifest-node.mjs` re-read `objectuiSha` from the live `.objectui-sha`
while `objectuiPackagesVersion` fell back to the value already in
`scripts/sdui-manifest.record.json`. The two record fields were therefore read
at two different moments: a regeneration after a pin bump wrote the NEW pin
under the OLD version string, producing a record whose two objectui fields
describe two different commits — the exact record `check-sdui-manifest.mjs`
check 4 rejects. The person that reds is the one who followed the documented
bump procedure, so the producer is where it is fixed.

The default now comes from the same oracle the gate judges with: the version
`packages/core/package.json` declares at the pinned commit, read through
`check-sdui-manifest.mjs`'s exported `readPinnedDeclaredVersion` — the same
function, imported, not a second copy. Producer and gate consulting two
separate oracles is where this drift came from.

`--objectui-version` still wins when passed. When the oracle cannot answer (no
objectui checkout, or one that does not carry the pin) the script now REFUSES
and names both remedies, rather than falling back to a version string nobody
read: an absent reading is never converted into an answer.

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
@os-bill
os-bill marked this pull request as ready for review September 18, 2026 03:50
@os-bill
os-bill added this pull request to the merge queue Sep 18, 2026
Merged via the queue into main with commit 36f13bb Sep 18, 2026
37 checks passed
@os-bill
os-bill deleted the claude/issue-18819-generator-version-default-oracle branch September 18, 2026 04:27
akarma-synetal pushed a commit to akarma-synetal/framework that referenced this pull request Sep 28, 2026
…ult, not the record (objectstack-ai#18956)

Fixes objectstack-ai#18879

Clause-②: no

PR objectstack-ai#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 objectstack-ai#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 (objectstack-ai#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 (objectstack-ai#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 objectstack-ai#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 objectstack-ai#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 objectstack-ai#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 objectstack-ai#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>
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

Projects

None yet

2 participants