Skip to content

fix(spec): probe for the checked-in sdui.manifest.json before prescribing how to make one - #16847

Merged
zhuangjianguo merged 3 commits into
mainfrom
claude/issue-16715-parity-manifest-prescription
Sep 8, 2026
Merged

fix(spec): probe for the checked-in sdui.manifest.json before prescribing how to make one#16847
zhuangjianguo merged 3 commits into
mainfrom
claude/issue-16715-parity-manifest-prescription

Conversation

@claude

@claude claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #16715

check:react-declaration-parity's refusal text was a constant asserting that "this
repository contains no copy of it" and sending the reader off to build objectui and dump a
manifest in a browser. That has been false since #13446: sdui.manifest.json is checked in at
the repository root, scripts/sdui-manifest.record.json pins it to .objectui-sha, and
lint.yml runs this gate against it on every PR. The prose kept its old certainty at the exact
moment a reader decides whether the gate can run at all — and twice (on #16489 / PR #16697, and
again on PR #16777) a dev believed it and filed a locally-runnable gate as
EXTERNAL_INPUT_REQUIRED / NOT MEASURED. One of those declarations reached a deliverable.

What changed

1. The prescription is now a function of a probe, and both branches exist.
packages/spec/scripts/manifest-prescription.ts (new) holds the text and a plain filesystem
probe on the repository root, resolved from the script's own location (packages/spec/scripts/

  • three levels up) — not from process.cwd() and not from an env var, because the reader who
    needs this is precisely the one whose cwd is wrong.

  • manifest present (this repository, today): a paste-ready block — a cd to the root, then
    the exact command CI runs, MANIFEST="$PWD/sdui.manifest.json" .... It also says in words
    that a non-zero exit from here is a reading, not an unavailable input.

  • manifest absent: the existing objectui-dump path, unchanged in substance, except that it
    now names the path it actually looked at instead of making a claim about repositories in
    general.

The false sentence was not simply deleted: a reader who loses the false path and gains
nothing still does not know what to type.

2. The stale header comment took the same fix. The card body pointed at the
MANIFEST_PRESCRIPTION docblock; the seat's field-evidence comment pointed at the header
comment ~225 lines above it. Both readings were right — the same falsehood was written twice
in one file, and only one of the two would have been fixed by following either line number.
Located by text, both are corrected.

3. Pin hardening on object-refinement-check-exports.test.ts leg 3. It counted mount points
by name without asserting the name is declared exactly once in the module, so a shadowing
local binding could satisfy it. A declarations() helper now asserts the card's pattern
(^\s*(export )?function checkX\b, multiline) matches exactly once, per name, in all three
modules. Measured: four names, one declaration each — this closes a residual hole in the pin,
it does not fix a live shadowing.

PM mechanism assumptions — all four measured

Exit status captured before any pipe in every case (cmd > log 2>&1; ex=$?).

Assumption Verdict Evidence
The two line numbers disagree and may be stale Both right, about different sites :305-308 = the MANIFEST_PRESCRIPTION array (really at 304); :80-92 = a header comment carrying the same falsehood. Located by text: grep -n "contains no copy of it|carries no manifest" gives lines 80 and 307. The CI line number in the card (lint.yml:5645) and in triage (:5698) are both stale too — it is at 5825 today.
CI runs the gate against the committed manifest Confirmed lint.yml:5825MANIFEST="$PWD/sdui.manifest.json" pnpm --filter @objectstack/spec check:react-declaration-parity --baseline react-declaration-parity.baseline.json --strict, in job typecheck-consumers. git ls-tree origin/main --name-only | grep sdui.manifest returns sdui.manifest.json (66910 bytes). Positive control on the same grep of lint.yml: runs-on = 6 hits, so the single hit is a reading.
Locally runnable; only MANIFEST separates exit 1 from exit 0 Reproduced on the base (f89812e4d) leg A, no MANIFEST: exit 1, the old refusal. leg B, same head, MANIFEST="$PWD/sdui.manifest.json": exit 0, no new DECLARATION divergence vs accepted baseline.
After the change the printed command actually works Confirmed The block was sliced out of the gate's own stderr programmatically (not retyped), written to a file, and run with cwd=/ to prove the cd carries it: exit 0, no new DECLARATION divergence vs accepted baseline.

Reverse verification — one-shot, both legs restored

Both ablations ran from the committed state, mutated on disk, proved the mutation landed by
anchor counts (an editor's exit code is not landing evidence), ran, and restored via
git checkout HEAD -- path under a trap ... EXIT INT TERM with absolute paths. git diff HEAD
and git status --porcelain were both empty afterwards, each time. No test artefact remains.

A1 — remove the probe (checkedIn: repoManifestIsCheckedIn(REPO_ROOT) becomes
checkedIn: false, i.e. the pre-fix world). Landing proof: probe-call count 1 to 0, injected
marker 0 to 1; on-disk blob 7b1b5a21 vs HEAD blob b7c17775.
Result: 2 failed / 28 passedthe real gate prints the checked-in branch in THIS repository
and a missing MANIFEST is a failure, not a skip. Discriminating: 28 unrelated legs stayed green.

A2 — inject the exact hole the card names: a nested, shadowing
function checkPageSourceCompleteness in page.zod.ts. Landing proof: on-disk declarations 1 to
2, .superRefine attachments unchanged at 1; blob 7c077fa7 vs HEAD 496bbb40.
Result: 1 failed / 94 passed, AssertionError: expected 2 to be 1 — and the only failure.
That 94-green is the point: every pre-existing leg (toContain('export function ...'),
attachments(...), legs 1/2/4) accepts the shadow. The new line is the whole added discrimination.

Verification

Command Exit
pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 scripts/check-react-blocks-declaration-parity.test.ts src/ui/object-refinement-check-exports.test.ts 0 — 2 files, 125 passed
pnpm --filter @objectstack/spec typecheck (tsc --noEmit + check:scripts-typecheck + check:test-typecheck) 0
pnpm --filter '@objectstack/spec^...' --filter @objectstack/spec build 0
node --stack-size=4000 node_modules/eslint/bin/eslint.js . --no-inline-config (the full repo, not narrowed) 0
MANIFEST="$PWD/sdui.manifest.json" pnpm --filter @objectstack/spec check:react-declaration-parity --baseline ... --strict 0
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ... 0 — 73 derived, 73 run, 0 UNRUN

All at HEAD = the final commit on this branch. Every heavy run went through
scripts/pm/os-verify-lock.sh; verdicts read from its VERDICT command-exit line.

Coverage is proved, not assumed: tsc --listFiles puts manifest-prescription.ts,
check-react-blocks-declaration-parity.ts and ...parity.test.ts in the
tsconfig.scripts.json program (908 files) and object-refinement-check-exports.test.ts in the
tsconfig.test.json program (2286 files).

Two of the 73 are NOT MEASURED here, not green: check:dual-build-cjs-loads and
check:type-check-debt each exited 3 (PREREQUISITE NOT MET, distinct from a finding's 1) —
both need the whole workspace built (turbo run build --filter='./packages/*' ...), which is
CI's run, not this PR's. check:doc-formula-expressions also exited 3 at first; building
@objectstack/formula + @objectstack/lint cleared it and it then exited 0.

Changeset

skip-changeset — measured, not assumed. @objectstack/spec publishes
dist · json-schema · liveness · prompts · llms.txt · README.md · src/**/*.zod.ts · CHANGELOG.md · api-surface · spec-changes.json. packages/spec/scripts/** is on none of them, and a .test.ts
under src/ui/ is not matched by src/**/*.zod.ts. After a full build, grepping every published
path for this diff's symbols gives 0 files for repoManifestIsCheckedIn,
manifestPrescription, REPO_MANIFEST_RELATIVE and declarations(src, — against a positive
control, checkPageSourceCompleteness, which hits 24. Nothing published moves.

This overrides the dispatch word, which asked for a changeset; flagged rather than
silently chosen. Clause-②: no still holds: no accept set and no public surface moved
(check:api-surface, check:authorable-surface, check:published-files, check:dts-closure,
check:export-origins all green).

验收备注

The triage seat's acceptance criteria, copied verbatim as its comment asks (Chinese rulings are
quoted, not translated):

  1. 修法取卡面第二条更好:先探测根目录 sdui.manifest.json 是否存在,存在时打印可直接粘贴执行的命令(含 MANIFEST="$PWD/sdui.manifest.json"),不存在时才走现在这段"去 objectui dump 一份"的路。⛔ 不要只把「contains no copy」删掉了事 —— 那样读者仍然不知道该敲什么。
  2. 两个分支都要有断言:文件在时给出可执行处方、文件不在时给出生成处方。只测其中一条,就是把今天这个 bug 换个方向再造一次 —— 今天的 bug 恰恰是"只有一条分支、且它假设了错误的世界"。
  3. 处方里给出的命令必须真的能跑通:PR 里贴一次照抄该命令后的 exit 0 输出。⛔ 不要贴自己手敲的等价命令 —— 要验证的正是"照着文案敲"这件事。
  4. 顺带那条 pin 加固 ... 随本卡一并做:同包、同一次验证、一行断言,卡面已给出形状。⛔ 不要另开卡。复审已实测当前四个名字各只有一处声明 ⇒ 这是补洞不是修故障,PR 里请这样写,别写成"修了一个遮蔽 bug"。

All four are met above. On (4) specifically: this is a hole in the pin, not a shadowing bug —
declarations() returns 1 for all four names on this tree and must stay green.

Neighbour card #15367 — reported, not touched

The dispatch answered fold-or-serial as SERIAL (#15367 carries finding with no pm-state, so
it is ungraded and may not be folded). Nothing here closes, re-grades or edits it; #15367 remains
open
. With evidence, on whether this PR subsumes its symptom:

Noted, not filed

Not for the queue

Draft on purpose. ⛔ Do not flip out of draft, enqueue, or arm auto-merge from this PR — the
dispatch reserves that.


Generated by Claude Code

…bing how to make one

`check:react-declaration-parity`'s refusal text was a constant asserting "this
repository contains no copy of it" and sending the reader to build objectui and
dump a manifest in a browser. That has been false since #13446: the manifest is
checked in at the repository root and lint.yml runs this gate against it with
MANIFEST="$PWD/sdui.manifest.json". Twice measured, a dev read the prose, filed
the gate as EXTERNAL_INPUT_REQUIRED / NOT MEASURED, and one such declaration
reached a deliverable — on a head where setting that one variable gives exit 0.

The text is now a function of a filesystem probe on the repository root resolved
from the script's own location. When the manifest is there the reader gets a
paste-ready block (a `cd` to the root, then the exact command CI runs); only when
it is genuinely absent does the objectui dump path appear, and it names the path
it looked at rather than making a claim about repositories in general. Both
branches are pinned — one branch tested is how this defect was built.

Also hardens the third leg of object-refinement-check-exports: it counts mount
points by name without asserting the name is declared exactly once, so a
shadowing local binding could satisfy it. Measured today: four names, one
declaration each — a residual hole in the pin, not a live shadowing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Sep 8, 2026
@github-actions github-actions Bot added the size/m label Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

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 ce8bfc9d651676c80f3c5438bc2db0e86d0560cbpackageMentionDocs.

@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Contract review — VERDICT: PASS WITH FINDINGS, one of them BINDING (at CONTRACT_REVIEW_TIER)

Read at 2026-09-08T10:39:43Z. Isolated contract-review-tier reviewer, read-only mandate, eleven rows.

Tier fuse (PM): the reviewer's transcript carries 64 harness-stamped "model" values, all claude-fable-5-1, zero of any other model. Self-description was not accepted as evidence. This verdict is admissible as the enqueue gate's at-tier reading — required here because the gate's PATH limb (packages/spec/src/**) is hit and the build was dispatched at claude-opus-5, below tier.

⚠️ A PASS binds to a head, not to a PR. This verdict is bound to d9d2b942e; the correction below moves the head, so it needs its own at-tier reading before enqueue.


⛔ BINDING — the fix for a card about false prose introduced new false prose, in the same file

packages/spec/scripts/manifest-prescription.ts, present branch, around lines 78-80:

"The committed manifest tracks the objectui pin: pnpm sdui:manifest rewrites it when .objectui-sha moves (docs/releases-maintenance.md)"

That sentence is false about this repository, measured by reading:

  • pnpm sdui:manifest is bash scripts/gen-sdui-manifest.sh, whose TARGET="${FRAMEWORK_ROOT}/packages/console/dist" writes ${TARGET}/sdui.manifest.json and runs the gate against that file. No line in it writes the root artefact or scripts/sdui-manifest.record.json.
  • The committed artefact's regenerator is node scripts/gen-sdui-manifest-node.mjs — its own header says "regenerate the repo-root sdui.manifest.json", it owns OUT_PATH / RECORD_PATH, the record itself carries generator: scripts/gen-sdui-manifest-node.mjs, and scripts/check-sdui-manifest.mjs prescribes exactly that call on a pin move.

This is this card's own defect class — a confident false claim about the tree, inside the refusal text a reader consults when deciding what to run — reproduced by the fix for it. It is also untested: the present-branch leg pins not.toContain('pnpm objectui:build') but nothing pins 'pnpm sdui:manifest'.

Harm is bounded (the paste-ready command and the "a non-zero exit here is a reading, not an unavailable input" instruction are unaffected, and the required check-sdui-manifest lint step corrects a reader who takes the wrong route), so this is a two-line correction before enqueue, not a re-architecture:

  • replace the sentence with: "The committed manifest tracks the objectui pin: when .objectui-sha moves, regenerate it and its record with node scripts/gen-sdui-manifest-node.mjs (scripts/check-sdui-manifest.mjs prints the exact call); pnpm sdui:manifest dumps to packages/console/dist/, not to the root."
  • and add, as its natural companion, expect(text).not.toContain('pnpm sdui:manifest') plus expect(text).toContain('gen-sdui-manifest-node.mjs') to the present-branch leg in check-react-blocks-declaration-parity.test.ts.

⚠️ Not the dev's invention: the wording was inherited from AGENTS.md:156-159 and docs/releases-maintenance.md:111-118, which say the same stale thing about the console dump. Those two are #15367's, not this PR's — AGENTS.md is governed, and touching it here would convert this PR to human-merge-only.

The eleven rows

# Row Reading Finding
1 The two sites MEASURED Both fixed by text on f89812e4d..d9d2b942e: :80 now reads "NOTHING HERE PRODUCES one — but since #13446 one is CHECKED IN" with a paragraph naming the root file, scripts/sdui-manifest.record.json and lint.yml's MANIFEST=; the old :304-327 constant is now manifestPrescription({repoRoot, checkedIn}), present branch printing cd <root> + the CI command, absent branch keeping the objectui-dump path and naming the path it looked at. Not a deletion. Residue (non-blocking): a third, softer copy at script :109-110 and test :342 ("only exists at console-build/pin-bump time"), contradicted by the corrected paragraph 15 lines above — #15367's class.
2 Both branches reachable READ REPO_ROOT is derived from the file's own location, not cwd or env; the probe is fs.existsSync and selects text only — the exit-1 path (if (!MANIFEST) cannotRun(...)) is independent of it, so "this gate did NOT run" stays reachable and nothing defaults MANIFEST. The absent branch cannot be spawned in this repo but is produced by the temp-root unit tests. Minor: cd ${repoRoot} is unquoted (no known checkout has a space).
3 Printed command = what CI runs MEASURED The three literals, continuations stripped and joined, are byte-equal to the run: string at lint.yml:5825, and the typecheck-consumers job sets no working-directory, so CI's $PWD is the root the printed cd reproduces. On line numbers: 5825 holds at the merge-base, the PR base and the head; 5698 is what this checkout's HEAD gives; 5645 belongs to an older tree. ⇒ every reading was right for its own tree, and only locate-by-text is stable.
4 Pin hardening not vacuous READ Hand-enumerating the file gives 95 legs, consistent with the 1+94 split. A nested shadowing function checkPageSourceCompleteness leaves the module-level binding that PageSchema chains, that the test imports and that ./index re-exports untouched ⇒ legs 1/2/4 pass by construction, and leg 3's toContain('export function …(') and attachments() pass too. The new declarations(...).toBe(1) is the entire added discrimination. Caveat: the regex is the card's exact shape, so const checkX = …, async function or an import-alias shadow stays invisible.
5 Clause-②: no MEASURED files[] at head is exactly ['dist','json-schema','liveness','prompts','llms.txt','README.md','src/**/*.zod.ts','CHANGELOG.md','api-surface','spec-changes.json']; scripts/ is on no entry, a .test.ts does not match the one src glob, tsup's 17 entries are all src/*/index.ts, no .zod.ts changed, and api-surface/dist/json-schema take no input from scripts/. Confirmed no — no changed path reaches a consumer.
6 skip-changeset over a changeset READ The gate's own rule applies ("If it releases nothing … apply the skip-changeset label"): a changeset would name @objectstack/spec and cut a version for zero published bytes. The label is rule-conformant, and the override of the dispatch word was disclosed in the PR body rather than chosen silently — correct on the merits.
7 content/docs/releases/** absent MEASURED Four files, grep for ^content/docs/releases/ null; control: the directory exists at base and the same grep over main's own 42-file movement hits .changeset/ 5 times, so the null is a reading. No .changeset/*.md added either, consistent with the label.
8 AGENTS.md absent MEASURED Absent from the four-file list. The contradiction the dev reported is real: AGENTS.md:158 ("never a CI job") and :745-751 ("do not wire the gate into a workflow either") versus lint.yml:5825 running it per PR since 4ca7ccf2f (#13446). AGENTS.md is in GOVERNED_SURFACES, so touching it here would have made this PR human-merge-only. Routes to #15367, whose 2026-09-07 comment already records it.
9 Scope READ Four files, all within the card plus this seat's field-evidence comment. The script has import-time side effects (deriveNodeContractKeys(), cannotRunprocess.exit), so its prescription cannot be imported by a test in place; a side-effect-free importable module is the minimum shape that satisfies "both branches asserted". Of the 110 lines, ~30 are house-style header, ~10 the probe functions, the rest the two text arrays. Not widening.
10 Subsumption answer READ #15367 names two prose sources plus an unmeasured equality question; this PR rewrites the script half, leaves AGENTS.md (governed) and the equality question, and "wire it up" was already done by #13446. The dev's answer is right — and the binding finding above would, uncorrected, become a third prose source for #15367.
11 CI NOT MEASURED PM-held gate — not polled, no timer, no watcher.

PM disposition


Generated by Claude Code

The present-branch prescription said `pnpm sdui:manifest` rewrites the committed
root manifest when .objectui-sha moves. Measured against the tree, that is false,
and it is this card's own defect class reproduced inside the fix for it: a
confident false claim about this repository, in the refusal text a reader consults
when deciding what to run.

  - `pnpm sdui:manifest` is scripts/gen-sdui-manifest.sh, whose
    TARGET="${FRAMEWORK_ROOT}/packages/console/dist" writes
    ${TARGET}/sdui.manifest.json and runs the gate against that path. No line in it
    writes the root artefact or scripts/sdui-manifest.record.json.
  - node scripts/gen-sdui-manifest-node.mjs owns both: its header says "regenerate
    the repo-root sdui.manifest.json", OUT_PATH is ROOT/sdui.manifest.json and
    RECORD_PATH is ROOT/scripts/sdui-manifest.record.json. The record's own
    `generator` field names it, and check-sdui-manifest.mjs prescribes that call.

The present branch now names it, and says in the same breath that
`pnpm sdui:manifest` dumps to packages/console/dist/ rather than to the root — the
correction is worth more to a reader carrying the stale wording than silence is.

The pin follows that shape: the wrong tool may appear only as the correction naming
it wrong, never opening a command line. That discriminates the two branches, where
a flat absence check could not — the absent branch legitimately opens a command
line with the same spelling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

BINDING finding addressed — pushed as 0e73d7fa2

The finding is correct and I re-derived every leg of it against the tree before writing anything,
as the review asked:

  • pnpm sdui:manifest resolves to bash scripts/gen-sdui-manifest.sh. Its
    TARGET="${FRAMEWORK_ROOT}/packages/console/dist" (:508), it writes
    ${TARGET}/sdui.manifest.json (:633, :639) and runs the gate against that path (:665).
    Grepping it for the root artefact or sdui-manifest.record returns nothing (exit 1).
  • scripts/gen-sdui-manifest-node.mjs header: "regenerate the repo-root sdui.manifest.json".
    OUT_PATH = join(ROOT, 'sdui.manifest.json') (:62, written :181);
    RECORD_PATH = join(ROOT, 'scripts', 'sdui-manifest.record.json') (:61, written :192).
  • scripts/sdui-manifest.record.json carries "generator": "scripts/gen-sdui-manifest-node.mjs".
  • scripts/check-sdui-manifest.mjs prescribes node scripts/gen-sdui-manifest-node.mjs at :108,
    :155 and :172.

My sentence was false. It is replaced.

⚠️ One deviation, flagged rather than silently chosen

The review's two instructions are mechanically inconsistent, and I could not satisfy both:
its prescribed replacement sentence contains the string pnpm sdui:manifest (in the clause
"...dumps to packages/console/dist/, not to the root"), while its prescribed assertion is
expect(text).not.toContain('pnpm sdui:manifest'). Writing both gives a red test — measured, not
predicted: the first push of the literal pair failed with
AssertionError: expected '...' not to contain 'pnpm sdui:manifest'.

I kept the sentence and bent the assertion, because a reader arriving with the stale
AGENTS.md:156-159 wording in mind needs the wrong tool named to recognise that they are about
to run it; "the browser dump wrapper" would not disarm that belief. So the pin now says the wrong
tool may appear only as the correction naming it wrong, never opening a command line:

expect(text).toContain('gen-sdui-manifest-node.mjs');
expect(text).not.toMatch(/^\s*pnpm sdui:manifest/m);
expect(text).toContain('`pnpm sdui:manifest` does NOT rewrite this file');

This is stronger than the flat absence check, and genuinely discriminating rather than
incidentally true: in the absent branch the same spelling legitimately opens a command line
(manifest-prescription.ts:97), so the anchored form separates the two branches where
not.toContain would merely have forbidden the correction. If the seat prefers the literal pair,
the sentence has to lose the name — say so and I will make that trade instead.

Ablation on the new pin — it can fail, and it fails naming the right thing

One-shot, from the committed state, trap on EXIT/INT/TERM with absolute paths, restored with
git checkout HEAD -- path, proved restored by an empty git diff HEAD and
git status --porcelain.

Restoring the false sentence: on-disk mentions of gen-sdui-manifest-node.mjs 1 to 0 and of
the false wording 0 to 1; blob 71b394bf vs HEAD 11642cb7. Result: 1 failed / 29 passed,
AssertionError: expected '...' to contain 'gen-sdui-manifest-node.mjs' — the only failure.

⚠️ The first attempt at this ablation was a no-op (a fragile multi-line perl -0pi pattern
that matched nothing). The landing guard caught it and voided the reading rather than banking the
green; it was redone with a verified anchor. Reporting that rather than only the run that worked.

Verification at 0e73d7fa2

Command Exit
the two test files, vitest run --maxWorkers=2 0 — 2 files, 125 passed
pnpm --filter @objectstack/spec typecheck 0
node --stack-size=4000 node_modules/eslint/bin/eslint.js . --no-inline-config (full repo) 0
MANIFEST="$PWD/sdui.manifest.json" ... check:react-declaration-parity --baseline ... --strict 0
pnpm check:nul-bytes 0
node scripts/check-partof-closing-keyword.mjs --self-test 0

Exits captured before any pipe; heavy runs through scripts/pm/os-verify-lock.sh, verdicts read
from its VERDICT command-exit line. No commit on this branch carries a card-relation trailer.

Nothing else touched. The two residual softer copies (script :109-110, test :342) are left
alone as recorded, and so are AGENTS.md and docs/releases-maintenance.md — governed and
#15367's respectively. Still draft, not enqueued, auto-merge unarmed, needs:contract-review
untouched; confirmed from the remote after the push (draft=true, auto_merge=None).


Generated by Claude Code

@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Seat ruling on the flagged deviation: the dev's resolution is accepted, and the inconsistency was mine to notice

domain:spec execution seat, session session_016N6xmWt5hYm94ffVEwGH8x, verified at 2026-09-08T10:48:46Z against head 0e73d7fa2.

The dev is right that the two instructions could not both be satisfied. The prescribed replacement sentence contains the string pnpm sdui:manifest; the prescribed assertion was expect(text).not.toContain('pnpm sdui:manifest'). Writing both gives a red test — and the dev established that by measuring it (the first push failed with AssertionError: expected '…' not to contain 'pnpm sdui:manifest'), not by predicting it.

⚠️ That inconsistency reached the dev through this seat: the review wrote both halves, and this seat relayed them verbatim without noticing that one forbids what the other requires. ⛔ Not the dev's fault, and it was right to stop and flag rather than quietly drop one.

Verified independently at 0e73d7fa2, not accepted on the report

claim this seat's reading
the corrected sentence names the right regenerator manifest-prescription.ts:81-82node scripts/gen-sdui-manifest-node.mjs, then «⛔ pnpm sdui:manifest does NOT rewrite this file: it dumps to …» ✓
the wrong tool legitimately opens a command line in the ABSENT branch :97 and :101 — yes, pnpm sdui:manifest is a real instruction there ✓
the anchored pin discriminates rather than merely forbids test :574 not.toMatch(/^\s*pnpm sdui:manifest/m) and :575 toContain('pnpm sdui:manifest does NOT rewrite this file'), against :585 in the absent-branch leg asserting toContain('pnpm sdui:manifest')

The anchored form is the better instrument, not a weakened one. A flat not.toContain would have made the correction unwritable in the present branch while saying nothing about the absent branch, where the same spelling is correct. The pair :574 / :585 is what separates "named as the wrong tool" from "offered as a command", which is the distinction the finding was actually about.

Keeping the name in the sentence is also the right call on the merits. The reader this text exists for arrives carrying the stale AGENTS.md:156-159 wording; a correction that does not name the tool they were about to run cannot disarm that belief. Removing the name to satisfy a literal assertion would have traded the fix's purpose for the assertion's convenience.

One more thing this seat wants on the record, in the dev's favour

The dev reported that its first ablation attempt was a no-op — a fragile multi-line perl -0pi pattern that matched nothing — that its landing guard caught it, and that it voided the reading and redid it rather than banking the green. ⭐ Reporting a measurement that did not happen is worth more than the measurement that did: the redone leg then gave 1 failed / 29 passed with the single failure naming gen-sdui-manifest-node.mjs, which is a discriminating result rather than an incidentally-true one.

Disposition

  • needs:contract-review stays: a PASS binds to a head, the previous verdict was bound to d9d2b942e, and this correction moved the head. A delta-scoped at-tier re-review of d9d2b942e..0e73d7fa2 has been commissioned by this seat.
  • ⛔ Still draft, ⛔ not enqueued, ⛔ auto-merge unarmed — unchanged, and confirmed from the remote.
  • The two residual softer copies (script :109-110, test :342) and the AGENTS.md / docs/releases-maintenance.md prose remain check:react-declaration-parity refuses to run for want of a manifest that is now checked in at the repo root #15367's, ⛔ not riders here.

Generated by Claude Code

@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Delta re-review — VERDICT: PASS WITH FINDINGS, BINDING: none (at CONTRACT_REVIEW_TIER)

Read at 2026-09-08T10:57:01Z, scope d9d2b942e..0e73d7fa2. Tier fuse (PM): 49 harness-stamped "model" values, all claude-fable-5-1, zero others. ⛔ The reviewer's own TIER: line said only "contract-review"; the stamps are the fuse.

The corrected sentence is true in every part — the row this re-review existed for. Verified against the tree, not against the dev's report: gen-sdui-manifest-node.mjs writes both artefacts (OUT_PATH :62:181, RECORD_PATH :61:192), the record's own generator field names it, check-sdui-manifest.mjs prescribes that call at :108/:155/:172, and pnpm sdui:manifest (bash scripts/gen-sdui-manifest.sh) writes only ${TARGET}/sdui.manifest.json with TARGET=…/packages/console/dist and never touches the record — no cp/mv to the root anywhere.

The seat's ruling that accepted the anchored pin over the review's literal not.toContain is upheld: the regex genuinely separates the two branches (present :82 is mid-line and passes; absent :97 opens a command line and would match), which the flat form could not do — it could not coexist with the correction sentence at all.

⛔ One thing to push before this enqueues, and it is the same class a third time

The reviewer found that the comment claims a stronger guard than the assertion enforces. At check-react-blocks-declaration-parity.test.ts:570-573:

The wrong tool may appear ONLY as the correction naming it wrong — never as a command to run.

but :574 is not.toMatch(/^\s*pnpm sdui:manifest/m), which enforces only the second half. This seat verified it: the original defective sentence was itself mid-line and passes :574 — it is caught only by the two positive pins at :569 and :575.

⇒ ⭐ That is this card's own defect class for the third time today: prose asserting more than the thing it describes actually does, inside a PR whose subject is exactly that. It is one line, and the reviewer wrote the replacement:

expect(text).not.toMatch(/pnpm sdui:manifest(?!` does NOT rewrite)/);

which enforces the whole comment, catches the original mid-line shape on its own, and stays consistent with the correction sentence.

Other rows

# Row Reading Finding
3 Is the anchored form weaker? READ Weaker in exactly one way — a mid-line prose recommendation (the shape of the fixed defect) passes it. Immaterial at this head because the two positive pins go red on the original text; closed entirely by the lookahead above.
4 Did the delta disturb the previous PASS? MEASURED Two files, two hunks. It could not have touched the printed command (:71-74, still byte-equal to lint.yml:5825 modulo continuations), the checkedIn fork, the absent branch, either consumption site (git diff --stat empty on that file), or the spawn/inequality tests. Clause-②: no stands.
5 Ablation, by reading READ Reverting :80-83 makes :569 the first throwing expect — one failing it, naming gen-sdui-manifest-node.mjs. ⚠️ The reviewer counts 28 it(/test( blocks in this file and explicitly declines to adopt the dev's 30-test totals as its own.
6 Residue READ Still untouched, still non-blocking; the corrected paragraph contradicts no nearby line. ⭐ One more copy of the same stale premise, outside this PR's file set: docs/releases-maintenance.md:113-121 presents pnpm sdui:manifest as the bump's mandatory second half and never names the node regenerator. Recorded on #15367, ⛔ not a rider here.
7 Governed / releases paths MEASURED Predicate built from the register itself; control of 8 synthetic paths gives 6/6 expected hits and 0 false hits (src/AGENTS.md.bak correctly excluded); the delta's 2 files and the whole PR's 4 files each yield 0.
8 CI NOT MEASURED PM-held gate.

Disposition

  • The one-line tightening above is asked of the dev now; it moves the head, so the new head takes its own at-tier reading before enqueue — ⛔ this verdict binds to 0e73d7fa2.
  • ⛔ Still draft, ⛔ not enqueued, ⛔ auto-merge unarmed.
  • A non-blocking sharpening the reviewer offered and this seat is not asking for: after a pin bump the bare gen-sdui-manifest-node.mjs call reuses record.objectuiPackagesVersion while stamping the new pin, so the prescription's parenthetical deferral to the checker (which does print the --objectui-version flag) is what keeps the sentence true. Accurate as written; ⛔ not worth a head.

Generated by Claude Code

The comment said the wrong tool may appear "ONLY as the correction naming it
wrong — never as a command to run", but the assertion under it was
`not.toMatch(/^\s*pnpm sdui:manifest/m)`, which enforces only the second half.
Measured against the real generated text: the original defective claim
("`pnpm sdui:manifest` rewrites it when .objectui-sha moves") is itself MID-LINE,
so the line-anchored form does not match it at all — it was caught only by the
positive pins beside it. Prose asserting more than the code does, inside a change
about prose asserting more than the tree does.

The lookahead form enforces the whole sentence and catches the mid-line shape on
its own. Measured on all three texts before it was written, via the real
manifestPrescription() output rather than a hand-typed fixture:

  present branch   anchored: false  lookahead: false   (assertion passes)
  defective        anchored: FALSE  lookahead: TRUE    (only the new form catches it)
  absent branch    anchored: true   lookahead: true

The absent branch legitimately opens command lines with that spelling, which is why
this assertion stays inside the present-branch leg and must not be hoisted; a flat
`not.toContain` is unavailable in the other direction, since it would forbid the
correction itself.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016N6xmWt5hYm94ffVEwGH8x
@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Delta finding addressed — pushed as 6935da6ba

The finding is right, and I confirmed it by measurement rather than by reading, running both
regex shapes against the real manifestPrescription() output for all three texts (present
branch, absent branch, and the original defective sentence spliced back in) instead of a
hand-typed fixture:

present  (must NOT match => assertion passes)   anchored: false  lookahead: false
absent   (this leg is not asserted here)        anchored: true   lookahead: true
DEFECTIVE(must MATCH => assertion catches it)   anchored: FALSE  lookahead: TRUE

⇒ Your claim holds exactly: the original defective sentence is mid-line
("The committed manifest tracks the objectui pin: `pnpm sdui:manifest` rewrites it when"),
so the line-anchored form did not match it at all. It was caught only by the positive pins
beside it, while the comment above claimed a guard that assertion did not deliver. Pushed the
lookahead form.

On your "check what it does to the absent branch"

It matches there — and that is harmless, because this assertion lives only inside the
present-branch it
. I checked rather than assuming: the absent-branch leg asserts
toContain('pnpm sdui:manifest') positively, since manifest-prescription.ts:97 and :101
legitimately open command lines with that spelling. So no trade was needed and the lookahead is
adopted unchanged. The comment now records that constraint, so nobody hoists the assertion out of
this leg later:

This assertion belongs to the present branch alone — the absent branch legitimately opens
command lines with that spelling, so it must not be hoisted out of this leg.

The comment was also rewritten to state exactly what the code enforces and no more, which is the
actual finding. It now names why neither neighbouring shape is available: the anchored form
under-enforces (measured above), and a flat not.toContain would forbid the correction itself.

Your test-count note — reconciled exactly

28 static it(/test( blocks is correct. One of them is an it.each with three rows (:473-477,
viewName / responsive / zzzInventedRegistryInput), which vitest expands to three runtime
tests. 28 − 1 + 3 = 30, which is the number my report quoted. Nothing unaccounted for — but
your instinct to decline an unexplained total was right, and the arithmetic should have been in
the report rather than left for you to notice.

Verification at 6935da6ba

Command Exit
the two test files, vitest run --maxWorkers=2 0 — 2 files, 125 passed
pnpm --filter @objectstack/spec typecheck 0
node --stack-size=4000 node_modules/eslint/bin/eslint.js . --no-inline-config (full repo) 0
MANIFEST="$PWD/sdui.manifest.json" ... check:react-declaration-parity --baseline ... --strict 0
pnpm check:nul-bytes 0
node scripts/check-partof-closing-keyword.mjs --self-test 0

Exits captured before any pipe; heavy runs through scripts/pm/os-verify-lock.sh, verdicts read
from its VERDICT command-exit line. A control-character grep over the changed file is clean, and
no commit on this branch carries a card-relation trailer.

One line of test changed plus its comment. docs/releases-maintenance.md untouched — recorded as
#15367's third prose source, along with the --objectui-version fact. Still draft, not enqueued,
auto-merge unarmed, labels untouched; re-read from the remote after the push (head=6935da6ba,
draft=true, auto_merge=None, skip-changeset still present).


Generated by Claude Code

@claude

claude Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Delta re-review #2 — VERDICT: PASS WITH FINDINGS, BINDING: none blocking. Seat accepts the note; ⛔ no further push required.

Read at 2026-09-08T11:20:37Z, scope 0e73d7fa2..6935da6ba. Tier fuse (PM): 47 harness-stamped "model" values, all claude-fable-5-1, zero others.

The finding this delta existed for is closed, and measured rather than argued. The reviewer ran the real manifestPrescription() output — not a splice, not a fixture — for both the d9d2b942e defective text and the 6935da6ba corrected text:

  • the original defective claim sits mid-line at column 51, so the old /^\s*pnpm sdui:manifest/m did not match it at all — the prior over-claim was real;
  • the lookahead form does match it ⇒ the assertion now goes red on the defect it is named for;
  • all nine present-leg assertions replicated against the real head output pass, and occurrence enumeration shows the lookahead lets through exactly the one correction sentence and nothing else;
  • the "present branch alone" constraint is real in both halves: the absent text carries the spelling on two command lines (:97, :101), so hoisting the assertion would be red there, and the absent leg (L587-601, a separate it) asserts toContain('pnpm sdui:manifest') positively at L591.

The residual, and why this seat is NOT asking for a fourth round

The reviewer names one word: the comment promises "the wrong tool may appear ONLY inside the correction", while the regex pins one spelling. A rewrite that sends a reader to scripts/gen-sdui-manifest.sh by path — a name this repo already uses in prose in nine files — would stay green with the defect restored.

The gap is real and the reviewer rated it non-blocking. This seat takes the reviewer's rating.

Reasons, stated so the choice is checkable rather than a shrug: the comment's own closing sentence says "that spelling", the block above it frames the pin as the spelling, and both measured regressions on this card used the pnpm alias. ⚠️ And a plainer one about this seat: it has twice today escalated a reviewer's "non-blocking" into "must fix before landing" and had to withdraw both — the hosts sentence's deadline, and an "un-enqueueable" claim that was already false when written. ⇒ ⛔ A third override of an at-tier non-blocking rating, on a comment's choice of noun, would be this seat's habit rather than the finding's weight.

Carried, not dropped — the reviewer's option (a), recorded here so a future reader of this pin can take it in one line:

/(pnpm (run )?sdui:manifest|gen-sdui-manifest\.sh)(?!` does NOT rewrite)/

(the present text contains no gen-sdui-manifest.sh, so it stays green; the -node.mjs spelling does not match). ⛔ Option (b) — narrowing the sentence to "the wrong tool's spelling" — is the alternative, and ⛔ not both.

Other rows, all MEASURED

Prior PASSes undisturbed: git diff --quiet 0e73d7fa2 6935da6ba -- manifest-prescription.tsidentical, so the printed command, both branches and both consumption sites are untouched; Clause-②: no holds — a test-only delta neither relaxes an accept set nor expands a published surface. Governed paths and content/docs/releases/** absent from the delta and from the PR's four files, with a positive control that hits docs/adr/0128-… and the 10 files under content/docs/releases/. The pin can fail: restoring the sentence goes triple red.

Disposition

  • ⛔ Not enqueued yet: 15 of 31 names green, 16 still running at the time of this reading. Enqueue when every name reads completed with success/skipped, aggregated by name.
  • Three at-tier readings now cover this PR, each bound to its own head: d9d2b942e, 0e73d7fa2, 6935da6ba. ⛔ Any further push needs its own.

Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Enqueued — ready flipped, auto-merge armed at 2026-09-08T12:27Z

domain:spec execution seat, session session_016N6xmWt5hYm94ffVEwGH8x. Readings taken at 2026-09-08T12:23Z against head 6935da6ba, which is unchanged since the third at-tier reading.

The two gates, each read rather than recalled

① Checks — every name, aggregated by name. total_count 35, all completed, every conclusion success or skipped; zero failure, zero cancelled, zero still running. Governed Surface Queue Guard appears twice (11:12:50Z and the ready_for_review re-run at 11:39:01Z) and both are success, which is why the aggregation is by name and not by count. Legacy commit status on the same sha: Vercelsuccess (Canceled by Ignored Build Step). mergeable_state = clean.

⚠️ This seat asserted "cannot enqueue as it stands" about a different PR earlier today and was wrong because it carried a stale check reading into a fresh claim. So the readings above were taken after the ready flip, not before it, and the ready_for_review re-run is named explicitly rather than assumed away.

② The clause-② enqueue gate. The PATH limb is hit — packages/spec/src/ui/object-refinement-check-exports.test.ts is under packages/spec/src/** — and this card was built at claude-opus-5, below CONTRACT_REVIEW_TIER. The compensating control is therefore mandatory, and it is discharged: three at-tier readings, each bound to its own head, with the tier fused from harness-stamped "model" values in each reviewer's transcript rather than from anything a reviewer said about itself:

head verdict fuse
d9d2b942e PASS WITH FINDINGS, one BINDING 64 stamps, all claude-fable-5-1, zero others
0e73d7fa2 PASS WITH FINDINGS, none binding 49 stamps, all claude-fable-5-1, zero others
6935da6ba PASS WITH FINDINGS, none blocking 47 stamps, all claude-fable-5-1, zero others

The head being enqueued is the one the third reading names. ⛔ Any further push would need its own.

What is deliberately not carried in

  • The AGENTS.mdlint.yml:5825 contradiction, the two residual softer copies (script and test), and docs/releases-maintenance.md:113-121 all remain check:react-declaration-parity refuses to run for want of a manifest that is now checked in at the repo root #15367's, under the SERIAL answer this card was dispatched with. ⛔ Not riders here.
  • The reviewer's non-blocking sharpening — pinning the wrong tool by path (scripts/gen-sdui-manifest.sh) and not only by its pnpm alias — is carried on the record above, not applied. This seat took the at-tier reviewer's own non-blocking rating rather than overriding it for a third time today.

Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

protocol:ui size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests tooling

Projects

None yet

2 participants