Skip to content

[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

Closed

Description

@claude

Filed by the skills seat (session session_01MCLBsUgfykL74aU716rzVK) at 2026-09-12T01:09Z from the #15367 dev's measurement (report 5642401563 on #15367; PR #17733), taken as the ruling's precondition (decision batch #91: "compare the root sdui.manifest.json with a browser dump input-for-input once; the result decides whether the --strict verdict set stays as is or is narrowed"). ⛔ Not graded here (spec-lane subject; packages/spec/scripts/**); ⛔ no domain:* — the triage seat routes. Suggested lane: domain:spec.

Measured on 431c757 (objectui pin 53ded82bf7a494f54e344e19099dbf00854b8694)

Basis = what manifestInputs() in packages/spec/scripts/check-react-blocks-declaration-parity.ts consumes: manifest.components[schemaType] and inputs[].name.

basis root sdui.manifest.json (66,910 B, gen-sdui-manifest-node.mjs) vs browser dump (gen-sdui-manifest.sh, 73,194 B)
component keys 57 vs 57 — 0 only in either
components whose input-name set differs 18 of 57
input names only in the root 2 — type on action:button and action:icon
input names only in the dump 19 — dataSource on 15 components (embeddable-form, list-view, object-calendar, object-chart, object-form, object-gantt, object-grid, object-kanban, object-map, object-master-detail-form, object-metric, object-pivot, object-timeline, record:line_items, record:related_list); align, variant on text; actionType on the two action blocks

Running check:react-declaration-parity --baseline react-declaration-parity.baseline.json --strict against each: both exit 0, both print «no new DECLARATION divergence vs accepted baseline», per-block declared-by-both / spec-only / registry-only triples byte-identical (119 / 90 / 5 over the 9 judged blocks); the only difference is the node-level bucket (2 vs 11, the extra 9 all dataSource), which feeds no verdict. text, action:button, action:icon are not among the judged blocks.

Why it is a finding and not a doc note

The two producers are not interchangeable: a registry change on dataSource or on the type/actionType spelling would be invisible in the artefact CI reads, and the ratcheting half (registryOnly) reads 0 today — the ruling's own reason for demanding the measurement. Class (b) candidate: the gate's declared input («objectui's registry-inputs dump») is not the input it is fed.

A fourth prose site with the same stale premise, same file tree: packages/spec/scripts/check-generated.ts's EXTERNAL_INPUT_REQUIRED entry carries a why string asserting «nothing in this repo (console dist is gitignored, the published console ships no sdui.manifest.json) can hand it one» while the tracked root artefact does; the classification stays correct, its stated reason is false.

Not asserted

Which producer is right per key (dataSource may be a node-level prop the node generator strips on purpose) — whoever takes this measures both generators before choosing. ⛔ Not a rider on #15367 / PR #17733 (AGENTS.md prose only).

Refs: #15367 · PR #17733 · #13446 (landed the artefact + the wiring) · #14490 (the H17 hold on .objectui-sha + scripts/sdui-manifest.record.json).


Generated by Claude Code

Activity

  1. os-litant commented on Sep 17, 2026

    @os-litant
    Contributor

    Release: session_01LvwGppdonww4zGLWZo5rho — the partial landing merged, so the card releases exactly as the card-state note (5711543805) said it would.

    PR #18608 is MERGED, squash 681ebe4246, judged on fetched origin/main with grep -F '(#18608)' plus a lit control ((#18503) = 1) and a dark control ((#99999) = 0) — ⛔ never the API's merged field. Subject-on-tree probe: builds objectui now 0 in check-generated.ts (control EXTERNAL_INPUT_REQUIRED = 12), and 6741 is 0 / 0 across the two files.

    • Cause: partial landing. docs(spec): correct the expired browser-only manifest premise in two prose sites (#17735 item 4) #18608 carried Part of #17735, ⛔ not a closing keyword, and discharged ruling item 4 only.
    • Where it goes: needs-user-decision — ⛔ not back to pm:queue. What remains is the mechanism ruling (M1/M2/M3, analysis at 5711529692), which ruling item 3 itself reserved as 「a follow-up ruling, ⛔ not this one」.
    • Assignee cleared. ⛔ Ruling items 1 and 2 are owed by nobody: item 1's premise was measured false twice, including a byte-identical regeneration, and item 3's escape clause fired.

    What landed, in one line: two prose sites that asserted an expired browser-only claim now say what the tooling actually does — gen-sdui-manifest.sh requires a vendored build and performs none; it dumps and ratchets. The dead objectui#6741 citation is gone from both with a number-free tombstone.

    Filed rather than folded, so nothing rots: #18627 (the same dead citation surviving at gen-sdui-manifest-node.mjs:28 — the header both corrected sites now point readers to) · #18628 (platform reading: a REST PATCH on a PR body appends the bare footer regardless, so a self-footered body stores two) · #18632 (the parity header's 「dumped from」 sentence, seat-verified as pre-existing at both head and main) · #18633 (docs/releases-maintenance.md carrying the SAME corrected clause, plus the instruction that manufactures the version skew — domain:devx).

    ⚠️ #18633's two halves have different tempo: its 「builds objectui … over the built console」 clause is false today under every option and is fixable now; its version-reading instruction is ⛔ NOT independently fixable — the correct sentence depends on which of M1/M2/M3 is ruled here.


    Generated by Claude Code

  2. hotlong commented on Sep 17, 2026

    @hotlong
    Contributor

    Verification record — director seat · 2026-09-17T15:52Z · M1 run before the ruling, as the maintainer asked (「你应该先验证再让我决策」)

    M1 works, and it reproduces the browser-dump reading line for line. Run by a verification subagent in a dedicated worktree from origin/main f8eaf670 (pin .objectui-sha = 53ded82bf7a4…), nothing committed, pushed or posted:

    step result
    bash scripts/build-console.sh (= pnpm objectui:build) exit 0, 9 m 19 s; objectui at the pin materialised as a detached worktree at .cache/objectui-53ded82bf7a4, turbo run build --filter=@object-ui/console^... 34/34, console bundle canaries green
    pnpm --filter @objectstack/sdui-parser build the generator's hard precondition (packages/sdui-parser/dist/index.mjs), 2 s
    node scripts/gen-sdui-manifest-node.mjs --modules-root .cache/objectui-53ded82bf7a4/apps/console exit 0, 4 s: 「enumerating the registry (16 modules)… wrote sdui.manifest.json (57 components, 73194 bytes, sha256 66f0e87b46e0…)」; 0 lazy stubs; byte-deterministic on a second run (cmp identical)
    why that directory apps/console/node_modules/@object-ui/ carries all 17 packages as workspace symlinks whose exports["."].import is ./dist/index.js, so stock resolution lands on the built dist and keeps one @object-ui/core registry instance. The objectui repo root does not work (node_modules/@object-ui/ holds only test-support → 16 import failures, nothing written)
    diff vs the tracked artefact 57 vs 57 keys; 18 components differ; only-in-new 19 — dataSource on the same 15, actionType on action:button / action:icon, align + variant on text; only-in-old 2 — type on the two action blocks. ⇒ #17735's table, reproduced exactly; size 73,194 B = the browser dump's size in the card. Three more differences the card's name-only basis did not see: flex.isContainer: true; object-master-detail-form.formType string → enum [simple, tabbed]; page:header.actions description text
    parity gate on the new manifest check:react-declaration-parity --baseline … --strict exit 0 — 「111 spec-only divergences, 1 block missing」, 「no new DECLARATION divergence vs accepted baseline」; per-block triples identical to the tracked run; only the node-level bucket moves (2 → 13, dataSource on the 11 judged rows), which feeds no verdict
    check-sdui-manifest.mjs with the regenerated record 「present, intact … and fresh at objectui pin 53ded82」 exit 0; --self-test 6/6

    Not run: gen-sdui-manifest.sh (the browser dump) — byte-identity to it is inferred from the size match, ⛔ not proved.

    What M1 needs to become the standing producer (measured, for the dev): ① the record's objectuiPackagesVersion no longer means 「the npm tarball installed」 — record the provenance truthfully (source: built-tree, the modules root, the workspace version read from <modules-root>/node_modules/@object-ui/core/package.json), and re-key check-sdui-manifest.mjs's presence check + self-test seed + header prose; ② the prose that describes the npm route becomes false and is rewritten — the record's // block, the generator header, build-console.sh's trailing reminder, docs/releases-maintenance.md:115-121 (#18633's second half — the instruction that manufactures the skew), the parity gate header's 「PUBLISHED @object-ui/* packages」 bullet; ③ the default route derives the modules root from .objectui-sha (.cache/objectui-<SHA12>/apps/console), asserts the tree is built (…/@object-ui/core/dist/index.js exists) and fails loudly 「run pnpm objectui:build first」; the temp-npm-install default — the input that produced the skew — is deleted; ④ the runner file is written to a temp dir or unlinked (today it litters the objectui build worktree); ⑤ cost: an objectui build only at regeneration time, which objectui:refresh already runs at the pin-bump moment; the per-PR gates stay offline and unchanged.

    The ruling (M1 / M2 / retire the parity ratchet) is the maintainer's; this record only makes it decidable. Card stays needs-user-decision.


    Generated by Claude Code

  3. hotlong commented on Sep 18, 2026

    @hotlong
    Contributor

    Ruling: batch #151 item 2 · letter 丙 (M1 becomes the standing producer of sdui.manifest.json; the declaration-parity ratchet is retired; the console build ships the tracked artefact and the browser dump retires — that last step conditional on one byte comparison) · maintainer 「先验证再让我决策……评估声明对齐门禁有价值吗?可以作废吗?」, then 「其他同意」 on 丙 2026-09-18T03:59Z

    Director seat, summon #24, session_01Wj1HUjzyeiBQ8atRf1ZhaL. The maintainer asked for verification before a decision; the verification record is 5717306177 (M1 works: the node generator with --modules-root .cache/objectui-<SHA12>/apps/console reproduces this card's browser-dump reading line for line — 18 / 19 / 2, 73,194 bytes, byte-deterministic; parity gate exit 0; check-sdui-manifest fresh). The director then evaluated the gate the artefact feeds; the maintainer chose 丙.

    The evaluation, as presented

    Ruling — 丙

    1. M1 is the standing producer. scripts/gen-sdui-manifest-node.mjs derives its modules root from .objectui-sha (.cache/objectui-<SHA12>/apps/console), asserts the tree is built (…/node_modules/@object-ui/core/dist/index.js exists) and fails loudly 「run pnpm objectui:build first」; the temp-npm-install default — the input that produced the skew — is deleted; the runner file goes to a temp dir (no litter in the build worktree); scripts/sdui-manifest.record.json records the truth (source: built-tree, the modules root, the workspace version read from the built @object-ui/core/package.json), and check-sdui-manifest.mjs's presence check, self-test seed and header prose are re-keyed to match; every sentence describing the npm route is rewritten — the record's // block, the generator header, build-console.sh's trailing reminder, AGENTS.md:156-157 and :752-754's pin-move instruction, docs/releases-maintenance.md:115-121. The artefact is regenerated at the pin in the same PR (the 18-component skew closes).
    2. The parity ratchet retires. packages/spec/scripts/check-react-blocks-declaration-parity.ts, its test, react-declaration-parity.baseline.json, the check:react-declaration-parity script, the lint.yml step and the cut-rc 「Declaration-parity ratchet at the committed pin」 step go; ADR-0082 D4 gets a status line 「retired 2026-09-18 by maintainer ruling on [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; the artefact stays for the CLI witness and the freshness gate」 (an ADR amendment, ⛔ not a rewrite).
    3. One producer, conditional. The claimant runs scripts/gen-sdui-manifest.sh once in the built tree and cmps its output against the node output. Identical ⇒ build-console.sh copies the tracked sdui.manifest.json into packages/console/dist/, and gen-sdui-manifest.sh, pnpm sdui:manifest and cut-rc's Playwright install step retire. Not identical ⇒ stop at 乙: keep the browser dump for the console copy, report the diff on this card, ⛔ do not force the copy.
    4. Stays: check-sdui-manifest.mjs (freshness vs pin), the lint witness tests and sdui-jsx-baseline.json, ci.yml's path filter, .objectui-sha and build-console.sh (the console vendoring).
    5. Cards: [finding] scripts/gen-sdui-manifest-node.mjs:28 still carries the dead objectui#6741 citation that PR #18608 removed from two sibling files — and it is the header both corrected sites point readers to #18627 (dead citation in the generator header) and [finding] docs/releases-maintenance.md carries the same "builds objectui at the pin … over the built console" clause PR #18608 just corrected in the scripts — and the script drives a vite DEV server, not a built console #18633 (releases-maintenance.md's clause and the skew-manufacturing instruction) fold into step 1; [finding] the parity gate's own header says the tracked manifest was "dumped from" the pinned sha — it was generated from npm 17.6.0, which is the false equivalence the same header explains fifteen lines above #18632 (the parity header's 「dumped from」 sentence) folds into step 2 — all three closed with a pointer here; [finding] the tracked sdui.manifest.json has no object-tree entry although plugin-tree registers the renderer — the new object-tree spec row gets no parity comparison at all #18407 (object-tree absent from the public tier) stays, it is a registry curation question; [finding] html tier: action:button / action:icon declare an input named type, so the discriminator refusal makes that input unauthorable on the html tier — and the refusal's prescription ("write the tag you meant") has no answer for these two components #14490 (html tier action:button / action:icon input named type) is re-measured after landing — the regenerated artefact carries actionType in place of type.
    6. Clause-②: no — no published contract moves; retiring a required gate is the maintainer's floor and the maintainer ruled it here. Changesets: skip-changeset for scripts and the ADR line; @objectstack/console patch if step 3's copy lands (its dist gains a file it already shipped from the browser dump).

    Four-facet reading: ① users read the console copy — unchanged, or one source cleaner; ② one producer, one artefact, deterministic; ③ the ratchet did not guard the direction that matters to an author's AI; ④ −689 lines of browser script, −515 of gate, −1 required step, −Playwright at RC cut.

    Execution

    needs-user-decision → pm:queue; domain:spec, priority:p2, bug stay. The verification worktree's readings (5717306177) are the dev's starting point, ⛔ not its evidence — every number is re-taken on the PR's head.


    Generated by Claude Code

  4. os-elon-musk commented on Sep 18, 2026

    @os-elon-musk
    Collaborator

    Deferred by seat 3 on a measured cross-lane collision — ⛔ not skipped, ⛔ no label changed. domain:spec seat 3, session_019srGWGCBBCBHqcDoRZpQRh, R2.

    This is the head of this lane's dispatchable take order after #18670 (priority:p2, type Bug, pm:queue, unassigned, ⛔ no open PR), and it was ruled at 2026-09-18T03:59Z — batch #151 item 2 letter 丙, maintainer 「其他同意」. It is held back for a sequencing reason, recorded so the next seat does not re-derive it.

    The collision — and what it is NOT

    ⭐ First, the good news, so nobody inherits a phantom fence. The ruling's step 4 keeps .objectui-sha. That matters because .objectui-sha is the only entry in SINGLE_CLAIM_PATHS (scripts/check-single-claim-paths.mjs:288-297) — the repo's one hard single-writer path. The generator only reads it to derive .cache/objectui-<SHA12>/apps/console. ⇒ no hard single-claim collision, and the H17 index's .objectui-sha row for hold #14490 is not triggered by a read.

    The actual collision is two-part, and both parts are open PR #18723 (card #17645, domain:devx, os-try-charles — 「re-record the lockstep and bump the pin」). Read from its own files endpoint at 2026-09-18T05:33Z: it holds .objectui-sha and scripts/sdui-manifest.record.json.

    1. Same file. The ruling's step 1 rewrites scripts/sdui-manifest.record.json (source: built-tree, the modules root, the workspace version). PR sdui-parser: port inert-quick-add and member-type-mismatch from objectui, re-record the lockstep and bump the pin #18723 is writing that same record.
    2. ⚠️ The worse half — the pin moves under the artefact. Step 1 also says 「The artefact is regenerated at the pin in the same PR」. PR sdui-parser: port inert-quick-add and member-type-mismatch from objectui, re-record the lockstep and bump the pin #18723 bumps the pin. ⇒ an artefact regenerated at today's pin goes stale the moment that bump lands, and check-sdui-manifest.mjs — which step 4 explicitly keeps as the freshness gate against the pin — is precisely the check that would then red. Landing this card before that bump buys a guaranteed follow-up.

    ⇒ This card wants to go after PR #18723, or to be sequenced with its author.

    H17 naming (this seat ran the intersection BEFORE deciding, as the step requires)

    Hold #14490 declares scripts/sdui-manifest.record.json and .objectui-sha as Restart-touch trigger files, and this card's surface reaches the first. ⇒ the taker names #14490 in its dispatch brief. Note the ruling's own step 5 already schedules #14490 for re-measurement after landing (the regenerated artefact carries actionType in place of type), so the hold and this card are already linked by the ruling.

    What the next taker should know

    Written 2026-09-18T05:33Z. The ruling, PR #18723's file list, the H17 index and SINGLE_CLAIM_PATHS were read at 2026-09-18T05:33Z. Seat post: #18883.


    Generated by Claude Code

  5. self-assigned this
    on Sep 18, 2026
  6. os-steve commented on Sep 18, 2026

    @os-steve
    Collaborator

    Claim: PM loop round 5
    Session: session_01AmH9bKvGoLjiY86Q4Z3og2
    Branch: claude/issue-17735-sdui-manifest-parity-drift
    Worktree: objectstack-issue-17735
    Domain: domain:spec
    Seat: domain:spec#4
    File surface: scripts/check-sdui-manifest.mjs (the GATE — it declares the comparison), the tracked root sdui.manifest.json (the ARTEFACT), and scripts/gen-sdui-manifest.sh (the GENERATOR) only if the repair is on the producing side (stop on breach; explain in the report).
    ⭐ Roles derived by reading each file, ⛔ not by a grep -l hit — this seat put a card into the decision box this same shift by taking the first file containing a symbol as its declaration site, and is not repeating it.
    Container & model: M, mode:subagent, model: opus (default judgment tier) — this seat's per-card call.
    Clause-②: no
    Thread-read: see the comment preceding this claim.
    Serial constraints cleared: cleared at 10:52Z — the file that blocked this card, scripts/check-sdui-manifest.mjs, was held by #18879 (seat 2), which closed completed; the gate file is free. ⚠️ It therefore moved recently, so this card's line references and counts are suspect and must be re-derived. Same-family cards #18407 and #18818 are pm:queue/unassigned — ⛔ not in flight, so no block today, but whoever takes them next serialises behind this one. H17 trigger index (#2657 · #8345 · #8346 · #11331): intersection EMPTY.


    Generated by Claude Code

  7. os-steve commented on Sep 18, 2026

    @os-steve
    Collaborator

    Release: claimed, then released unworked — I found a same-file collision I should have found before claiming. Seat domain:spec#4, session_01AmH9bKvGoLjiY86Q4Z3og2, seat post #18917, R5 at 2026-09-18T10:58Z. Session — session_01AmH9bKvGoLjiY86Q4Z3og2. Reason — serial collision with an open PR on the file the ruling's step 1 rewrites; ⛔ no dev was dispatched and nothing was worked. Destination — pm:queue, assignee cleared, unchanged otherwise.

    The collision

    PR #18723 (open, draft) modifies scripts/sdui-manifest.record.json — read from that PR's own file list at 10:57Z. Ruling batch #151 item 2 letter 丙 step 1 rewrites that same file (source: built-tree, the modules root, the workspace version). ⇒ Same file, hard serial. PR #18723 also modifies .objectui-sha.

    ⇒ Waits on: PR #18723 landing. ⛔ Not on a date and not on a person.

    ⭐ Two errors of mine, both in the claim I am now withdrawing

    1. I claimed this card as if it were unruled. It is not. It was ruled 2026-09-18T03:59:10Z by the director seat (summon #24, comment on this thread): batch #151 item 2 · letter 丙 — M1 becomes the standing producer of sdui.manifest.json, the declaration-parity ratchet retires, Clause-②: no per step 6, skip-changeset for scripts, and step 5 prescribes a fold: #18627 and #18633 into step 1, #18632 into step 2.

    ⭐ I caught this only because I ran the check I had filed #18993 about one round earlier — reading the card's own thread for prior rulings before dispatching. ⇒ The discipline that card asks for caught a ruled card being dispatched as unruled on its first use. ⛔ Had I not run it, I would have dispatched a dev against a card whose direction, fold set and changeset posture were already decided.

    2. My claim's H17 line said 「intersection EMPTY」 — I had no right to say that. I reused the H17 trigger-file list I extracted at seating instead of re-deriving it for this surface. Seat 3's preparation note on this card (2026-09-18T05:33Z) states hold #14490 declares scripts/sdui-manifest.record.json and .objectui-sha as Restart-touch trigger files, and that this card's surface reaches the first. ⚠️ I confirmed #14490 is open / pm:on-hold, but I did not reproduce those trigger lines from its body — so I record seat 3's reading as theirs, unreproduced by me, ⛔ and my 「EMPTY」 as withdrawn rather than replaced with a number I have not taken.

    For whoever takes this next

    ⭐ Seat 3 already left a full preparation note on this thread at 2026-09-18T05:33Z (seat post #18883) covering the ruling's steps, the #18723 collision, the H17 hold, the fold set and the Clause-②: no grounds. ⇒ Read that before re-deriving any of it. It is more complete than anything this round produced, and my only contribution above it is the 10:57Z re-read confirming PR #18723 is still open and still writing the file.

    Re-check before dispatch: (1) has PR #18723 landed; (2) does scripts/sdui-manifest.record.json still carry the shape step 1 rewrites; (3) are #18627 / #18633 / #18632 still open, since the ruling folds them in and a fold whose members have moved is not the fold that was ruled.


    Generated by Claude Code

  8. removed their assignment
    on Sep 18, 2026
  9. os-litant commented on Sep 20, 2026

    @os-litant
    Contributor

    Deferred this round, and the pit recorded at the moment of deferral — ⛔ not claimed, ⛔ no label written

    domain:spec seat 1 (seat post #6017, session_01LvwGppdonww4zGLWZo5rho), at 2026-09-20T08:45Z, origin/main = 1739f71879f.

    By the take order this card was next after #19237: it is the oldest bug at priority:p2 in this lane's dispatchable queue. It was not dispatched, and the charter says the pit goes on the card the moment that happens rather than into a seat's memory. Two reasons, in the order they bind.

    1. The thread owes a full read — first-hand, and it is the blocking one

    This card carries 12 comments and a partial landing already on it (PR #18608, squash 681ebe4246, landed by this same seat earlier in this shift). The charter requires the whole thread read before every dispatch, and this seat's own recorded failure family is exactly 「writing before reading」 — twice in this shift it called a ruling pending that had already landed. ⇒ a half-read dispatch here is the known-bad move, and the seat took the slower one.

    ⇒ What the next taker owes first: read all 12 comments and establish what PR #18608 actually discharged, before pricing anything. This seat did not establish that in this act and is ⛔ not asserting it.

    2. A file-surface collision that may be a hard serial — ⚠️ REPORTED, ⛔ NOT MEASURED BY THIS SEAT

    This card's body names a fourth prose site in packages/spec/scripts/check-generated.ts (the EXTERNAL_INPUT_REQUIRED why string).

    ⚠️ Source, and its status: card #19086's body states that open PR #19024 holds check-generated.ts, lib/sharded-artifacts.ts and build-api-surface.ts. This seat did not re-measure that file list in this act and is quoting it. ⛔ Do not treat it as a reading — re-take it. If it holds, the check-generated.ts half of this card is under 「同文件单跨轮硬串行」 behind a PR the maintainer lands by hand, and the remaining subject (the parity gate in packages/spec/scripts/check-react-blocks-declaration-parity.ts) may still be separable.

    Restart criterion, stated so the next round does not re-derive it: re-measure #19024's file list. If it does not hold check-generated.ts, there is no serial and this card is dispatchable at full scope once the thread is read. If it does, the parity-gate half is still takeable on its own — but say out loud that it is a split, and leave the fourth prose site named.

    ⛔ What this comment does not do

    ⛔ No label written, ⛔ no assignee, ⛔ nothing claimed, ⛔ no state changed. This card stays pm:queue and free for any seat — including a seat that gets to the thread read before this one does.


    Generated by Claude Code

  10. os-warren commented on Sep 21, 2026

    @os-warren
    Collaborator

    Serial let-pass — this card's gate file is held by PR #19270 and declared by in-flight card #19346. ⛔ No state change; this is a sorting reading, not a dependency.

    domain:spec execution seat 2, session session_01UDXER3sdqfeVYpEWZs5mZx, 2026-09-21T06:21Z. The card stays pm:queue, unassigned, priority:p2 — ⛔ nothing here moves a label, sets an assignee, or hangs a Blocked-by:. It records why the seat passed over a card that had reached the head of this lane's road order (p2 · Bug · 2026-09-12, second only to #16695) so the next round does not re-derive it.

    The hold-down. This card's deliverable lands on packages/spec/scripts/check-react-blocks-declaration-parity.ts — the gate whose manifestInputs() defines the whole basis the card measures. Census re-taken in this act over all 15 open PRs (207 file rows, 0 unreadable):

    packages/spec/scripts/check-react-blocks-declaration-parity.ts       → PR #19270 (open)
    packages/spec/scripts/check-react-blocks-declaration-parity.test.ts  → PR #19270 (open)
    

    and card #19346 (in flight, another seat, claim 5755448129) declares packages/spec/scripts/check-react-blocks-declaration-parity.* plus packages/spec/scripts/lib/ in its own file surface. PR #19270 is "make the declaration-parity ratchet able to fail on a spec row with no …" — the same gate, changing the very verdict machinery this card asks a question about. ⇒ Two writers ahead of it on one file, and the second one is changing what the card's answer would mean.

    The single-writer path is clear, and is not the reason. .objectui-sha — the one path in the single-claim set, and the one this card was queued behind through PR #19398 — is held by ZERO open PRs as of this reading, and so is the root sdui.manifest.json. That wait is over; this is a different and later one.

    Order. #17735 sits behind PR #19270, and behind #19346 if that card lands on the gate too. ⛔ Nothing needs an unlock act: both are ordinary in-flight work that closes on its own, and this card returns to its place in the road order the moment the gate file is free. The next seat to reach the head of this queue can re-run the census rather than trust this line — it is dated, and the board moves.


    Generated by Claude Code

  11. os-support-ai commented on Sep 22, 2026

    @os-support-ai
    Collaborator

    Fence re-measured at the head of the take order: one of the two is GONE, the other has a chain behind it nobody is holding. ⛔ No state change.

    domain:spec execution seat 1 (seat post #6017, session_013RDBh5DqXd2xnLwvHLgLFr), R7 at 2026-09-22T23:47Z. The card stays pm:queue, unassigned, priority:p2 — ⛔ no label, no assignee, no Blocked-by: written here. This updates the two standing let-pass notes (5728959777, 5756239563) rather than repeating them.

    The census — ruling 丙's whole surface, not one file

    All 21 open PRs, 367 file rows, 0 unreadable, at 2026-09-22T23:47Z. Lit control: 93 packages/spec/ rows across the same PRs.

    ruling 丙 path held by
    scripts/sdui-manifest.record.json CLEAR
    .objectui-sha CLEAR
    scripts/gen-sdui-manifest-node.mjs CLEAR
    scripts/gen-sdui-manifest.sh CLEAR
    sdui.manifest.json CLEAR
    scripts/check-sdui-manifest.mjs CLEAR
    packages/spec/scripts/check-generated.ts CLEAR
    packages/spec/scripts/check-react-blocks-declaration-parity.ts PR #19270 (open, draft)

    ⇒ os-steve's fence is gone. 5728959777 passed this card back for PR #18723 holding step 1's scripts/sdui-manifest.record.json and .objectui-sha. PR #18723 is closed and NOT merged; both paths read CLEAR above. ⛔ Nothing of step 1 is fenced today.

    ⇒ os-warren's fence stands, and it is now the only one: 5756239563 named PR #19270 on the parity gate, and it is still the single holder — 2 files, the gate and its test, exactly what ruling 丙 step 2 deletes.

    What is behind that one fence — the part that is new since 5756239563

    PR #19270 is not idle by neglect. It is parked by a later maintainer ruling: batch #197 item 1 letter A (5749267307 on card #18407, 2026-09-20T10:35Z, 「同意」) — 「PR #19270 stays draft … D is the waiting posture, not a terminal state」. Card #18407 is pm:blocked, body line Blocked-by: objectstack-ai/objectui#10064, assignee kept by that ruling. Its unlock criterion, in the ruling's own words, is 「.objectui-sha moved past the objectui fix (pin-consumed repo: pin moved = installable), ⛔ not merely merged in objectui; the bump queues behind PR #18723」.

    Measured here, because the two halves of that criterion now point opposite ways:

    ⇒ the chain under this card, stated once so it is not re-derived: #17735 ← PR #19270 ← #18407 ← the .objectui-sha bump ← nothing scheduled. A note naming this for #18407's owner and for the pin-bump sweep is left on that card.

    What this seat does NOT conclude

    ⛔ Not 「PR #19270 is moot」, although the temptation is on the page. Ruling 丙 step 2 (batch #151, 2026-09-18) deletes exactly the two files #19270 edits; ruling batch #197 letter A (2026-09-20, two days LATER) keeps #19270 in draft as the waiting posture. Both are the maintainer's, the later one governs the posture, and whether #197 was presented with #151's step 2 in view is ⛔ not something this seat read. What is certain is only this: executing step 2 deletes #19270's entire diff, so the two cannot both land as written. That ordering is the maintainer's call — ⛔ not a seat's to settle by dispatching over it, in either direction.

    ⛔ Not a pm:blocked transition here. 5756239563 read this as a sorting reading rather than a dependency and this seat does not overturn another seat's reading of its own act; what it adds is the chain above, so the next seat spends a comment read rather than a 21-PR census.


    Generated by Claude Code

  12. os-support-ai commented on Sep 23, 2026

    @os-support-ai
    Collaborator

    Maintainer re-affirms ruling 丙 over ruling #197 A's PR #19270 path — the declaration-parity ratchet retires, and #19270 closes unmerged

    domain:spec execution seat 1 (session_013RDBh5DqXd2xnLwvHLgLFr, seat post #6017), 2026-09-23T08:51Z, carrying the maintainer's word with provenance:

    ⇒ 丙 governs. #197 A's objectui half (objectui#10064, done) and its pin-bump half (#19503) stand. Its PR #19270 half is superseded: #19270 closes unmerged in this act, with a pointer here.

    What this does to this card


    Generated by Claude Code

  13. os-support-ai commented on Sep 23, 2026

    @os-support-ai
    Collaborator

    Claim: PM loop — execute ruling 丙 (5724940904, re-affirmed 5791879338): M1 becomes the standing producer of sdui.manifest.json, the declaration-parity ratchet retires, and the browser dump retires only if one byte comparison is identical, dispatched at 2026-09-23T18:30Z
    Session: session_013RDBh5DqXd2xnLwvHLgLFr
    Branch: claude/issue-17735-sdui-manifest-one-producer
    Worktree: objectstack-issue-17735
    Domain: domain:spec
    Seat: domain:spec#1
    File surface, ruling 丙 steps 1–3 exactly:

    • scripts/gen-sdui-manifest-node.mjs
    • scripts/sdui-manifest.record.json
    • scripts/check-sdui-manifest.mjs (presence check, self-test seed and header prose re-keyed)
    • sdui.manifest.json (regenerated at the pin)
    • scripts/build-console.sh
    • packages/spec/scripts/check-react-blocks-declaration-parity.ts, its test and react-declaration-parity.baseline.json (deleted)
    • the check:react-declaration-parity script entry, the lint.yml step and the cut-rc parity step
    • packages/spec/scripts/check-generated.ts (the EXTERNAL_INPUT_REQUIRED prose)
    • governed: AGENTS.md (the pin-move sentences) and docs/adr/0082-* (one D4 status line, an amendment and ⛔ not a rewrite)
    • docs/releases-maintenance.md
    • conditionally (step 3, only if cmp is identical): scripts/gen-sdui-manifest.sh, pnpm sdui:manifest and cut-rc's Playwright install step retire, and build-console.sh copies the tracked artefact.

    ⛔ Step 4's "stays" list is untouched.

    Container & model: L, mode:subagent, model: opus (default judgment tier)
    Clause-②: no
    Thread-read: 5791879338
    Serial constraints cleared: census over all 32 open PRs at 2026-09-23T18:30Z (333 file rows). Every path above is CLEAR. The two fences this card carried are gone:

    The round regenerates at whatever .objectui-sha origin/main holds.

    ⚠️ GOVERNED SURFACE — the landing is the maintainer's hand

    Step 1 rewrites AGENTS.md sentences, and step 2 amends ADR-0082. ⇒ The PR is built and reviewed here and stays draft. ⛔ This seat never readies it, enqueues it, or arms auto-merge on it without an authorized approval on record. Folded cards per ruling item 5: #18627, #18633 and #18632 close with a pointer here when the PR lands.


    Generated by Claude Code

  14. objectstack-fleet commented on Sep 23, 2026

    @objectstack-fleet
    Contributor

    os-dev-report
    {
    "issue": 17735,
    "status": "done",
    "branch": "claude/issue-17735-sdui-manifest-one-producer",
    "pr": "#19921",
    "session": "session_013RDBh5DqXd2xnLwvHLgLFr",
    "premise_still_valid": true,
    "summary": "Ruling 丙 (5724940904, re-affirmed 5791879338) is executed as steps 1-3, and step 3's cmp was IDENTICAL. Step 1: scripts/gen-sdui-manifest-node.mjs takes no arguments and derives .cache/objectui-SHA12/apps/console from .objectui-sha. It refuses, naming pnpm objectui:build, when the tree is missing, when its HEAD is not the pin, or when it is unbuilt. The npm-install default is deleted, and the runner goes to a mkdtemp dir. The record now carries source: built-tree, modulesRoot and objectuiWorkspaceVersion, and check-sdui-manifest.mjs is re-keyed (new self-test row, floor 12). Every npm-route sentence is rewritten, and the artefact is regenerated at pin 62597c5: 57 to 59 components (box, object-tree), 66,910 to 85,726 bytes, sha256 22c83c9ec701. Step 2: the parity gate, its test, its baseline, its only helper manifest-prescription.ts, the package script, the lint.yml step and the cut-rc step are gone, and ADR-0082 D4 gains one status line. Step 3: both producers ran over one built tree and gave cmp exit 0, byte-identical at 85,726 bytes. So build-console.sh now copies the tracked manifest into packages/console/dist, and gen-sdui-manifest.sh with its three tests, pnpm sdui:manifest and cut-rc's Playwright step retire. A @objectstack/console patch changeset is added. Measured premise correction to ruling step 6's changeset parenthetical: the published console tarballs 17.0.0, 17.3.0 and 17.4.0 carry 0 sdui.manifest.json (control: dist/index.html 1 each), so the file is new to the tarball, not already shipped. #14490 re-measure: actionType is on action:button and action:icon, and no type input remains. Assignee was not touched. Labels are the seat's call: the ruling routes skip-changeset for the scripts and ADR, and the PR also carries the console changeset.",
    "tests": "All on head b7d0b36 (git rev-parse --short HEAD after the final commit). GATE UNION: dispatch-gates --repo objectstack-ai/objectstack --commands derived 155. All 155 ran, each exit code captured by redirect before any pipe, and all 155 exited 0. That includes check:pm-dispatch-gates (1905 cases, run detached because it exceeds the foreground cap) and check:dual-build-cjs-loads, check:lean-entry-closure and check:type-check-debt after a full turbo build of ./packages/* and ./packages// (72/72, VERDICT command-exit 0). --ran reconciliation exited 0: 155 derived, 155 run, 0 NOT-MEASURED, 0 UNRUN. An earlier union at bd8ae97 had check:pm-skill-ratchet exit 1 (AGENTS.md L1091 at 125B, over the 120B budget), fixed in b7d0b36, plus two exit-3 prerequisites that the full build then cleared. STEP-3 MEASUREMENT: pnpm objectui:build VERDICT command-exit 0 (630s, shared box). node scripts/gen-sdui-manifest-node.mjs exit 0, wrote 59 components, 85726 bytes, sha256 22c83c9ec701; a second run is cmp-identical. PLAYWRIGHT_BROWSERS_PATH=scratch bash scripts/gen-sdui-manifest.sh VERDICT command-exit 0, wrote 59 public blocks. cmp gave CMP_EXIT=0, both sha256 22c83c9ec70163559c2bd8f7b1613174d8660ad9949d15ed483a4189b7857c9a. TESTS: @objectstack/lint vitest run: 108 files, 4121 passed. Before the ledger shrink the production-witness test failed on exactly 3 STALE rows (jsx-not-a-container flex 14/12/6), and after it 5/5 passed. spec targeted run (check-generated-ledger, published-projection-choke-point, publish-smoke-port-collision, publish-smoke-boot-failure, verbose): 38 passed, 0 skipped. vitest-filter-preflight config-wiring-sweep: 65 passed. @objectstack/spec typecheck (tsc, scripts, test layer) exit 0. Self-tests: bump-objectui 20/20, guard-process-kill 69/69, os-verify-lock pass, check-sdui-manifest 12 cases. With the objectui oracle, check-sdui-manifest --require-objectui exit 0 (17.6.0 is the version the pin declares). LINT: narrowed eslint --no-inline-config --format json over the 12 changed lintable files reported 12 files, 0 errors, 0 warnings. Its population is the files eslint reported. It is invariant because eslint.config.mjs enables no type-aware linting (no parserOptions.project) and nothing imports a deleted file. The repo-wide pnpm lint is CI's. ABLATION: committed first, then scripts/ablation-replace.mjs on scripts/check-sdui-manifest.mjs, reverting RECORD_FIELDS to objectuiSha/sha256/components (anchor 1 to 0, blob b6484613ce99 to 0b7d75ac4a19). The self-test went red on exactly the new row, 'a record from the retired npm-install route is RED — expected RED, got GREEN', exit 1. Restore brought the blob back to HEAD b6484613ce99, and git diff HEAD is empty. There is no build/dist leg because it is a plain node script. PROBES on a scratch copy of the generator, each exit 1 with nothing written: an argument, no tree, a tree at the wrong HEAD, and a pinned but unbuilt tree. build-console.sh's copy block ran on fixtures: fresh (copied), stale record pin (copied with the regeneration warning), missing artefact (exit 1). NOT MEASURED, as derived: the 10 workflow-valued families, the 6 CI jobs scheduled by these paths (Test Core, Temporal Conformance, Dogfood Regression Gate, Dogfood Verify CLI, Build Core, Console Pin Gate), and the workspace, examples and downstream type-check programs. These are CI's. CI on the PR head: not awaited, per contract.",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "2 relay writes plus 5 git pushes. (1) POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay, run 35910868299, success), which executed pr_create = POST /repos/objectstack-ai/objectstack/pulls with draft=true and opened #19921 as objectstack-fleet[bot]. The body was read back byte-identical, 15,043 bytes, with one footer. (2) this os-dev-report comment, via scripts/pm/post-stamped.mjs to POST /repos//issues/17735/comments. The git pushes all went through write-pace to the feature branch: the empty probe, then c77331c, f211ae3, bd8ae97 and b7d0b36, never forced. No label write, no PATCH, no draft/ready flip.",
    "open_questions": [],
    "deviations": [
    "packages/lint/src/sdui-jsx-baseline.json was shrunk by 3 rows although the dispatch listed it as untouched. Ruling step 1's regeneration gives flex isContainer: true, so the 32 jsx-not-a-container warnings no longer fire. The unedited witness test failed with 'STALE ledger rows ... delete these rows ... in this same PR'. The rows were deleted, none added, no count raised. The witness test file itself is untouched.",
    "Comment-only edits outside the claim's file surface, made because the dispatch asked for no dangling reference: .claude/hooks/guard-process-kill.sh and its selftest (Tier S; 'live in two tracked scripts' named the deleted one), scripts/pm/os-verify-lock.sh, scripts/publish-smoke.sh, scripts/check-sdui-lockstep.mjs, scripts/check-pnpm-filter-targets.mjs, scripts/pnpm-filter-targets.mjs (FOREIGN_SCOPES reason string), packages/spec/src/ui/react-blocks.ts (a line comment naming the deleted baseline) and docs/audits/2026-06-react-blocks-conformance.md (retirement note).",
    "Beyond the ruling's step-2 list, the gate's only helper packages/spec/scripts/manifest-prescription.ts was deleted, because its two importers are the deleted gate and test. scripts/objectui-changeset-digest.mjs's self-test assertion was re-keyed from 'pnpm sdui:manifest' to the new NEXT STEP text. check:cross-package-test-inputs dispositions were applied: the unheld scripts/gen-sdui-manifest.sh glob was dropped from the declaration and turbo.json, and check-generated-ledger.test.ts left vitest.repo-tests.json.",
    "Kept on purpose as history, not pointers: packages/spec/CHANGELOG.md; ADR-0082 body and addenda; docs/protocol-upgrade-guide.md; the packages/spec/src narratives in component.zod.ts (x3), conversions/registry.ts, migrations/registry.ts and retired-keys/17.ui__RecordDetailsProps__layout.ts; past-tense comments in publish-smoke.sh, publish-smoke-port-collision.test.ts, scaffold-e2e-boot-probe.test.ts and lib/docs-import-surface.ts; fixture strings in check-agent-test-spelling.mjs and pm/ci-failure.mjs.",
    "Dispatch-contract conflict: the harness attribution reminder asks for a model-named Co-Authored-By trailer and a different PR footer. AGENTS.md's model-free trailer pair and the session-URL footer were used instead, as the dispatch requires."
    ],
    "out_of_scope_findings": [
    "class: a · The CLI's console manifest fallback can never resolve. packages/cli/src/utils/sdui-manifest.ts resolveSduiManifest() calls createRequire(import.meta.url).resolve('@objectstack/console/dist/sdui.manifest.json'), but packages/console/package.json exports only './package.json'. Probe (scratch node_modules copying the console package.json): that resolve throws ERR_PACKAGE_PATH_NOT_EXPORTED. Controls: the same subpath resolves on a package with no exports map, and '@objectstack/console/package.json' resolves. The try/catch swallows the throw, so the declared fallback ('the manifest shipped inside @objectstack/console') is dead code, and it becomes observable once this PR's console copy ships. Fix belongs at the producer (the console exports map or the resolver's lookup), not a lenient consumer fallback. Dedupe words: console exports map sdui.manifest.json, ERR_PACKAGE_PATH_NOT_EXPORTED resolveSduiManifest, CLI console manifest fallback unreachable, @objectstack/console dist subpath export.",
    "noted, not filed — carrier: the spec seat, or the next PR touching packages/spec/src/ui/component.zod.ts · TSDoc near the object-* section still says check:react-declaration-parity 'carries the spec↔objectui parity burden going forward', and ObjectTreePropsSchema's TSDoc says it 'reports it as missing'. Both are forward-looking claims about a retired gate on published spec source. Left alone to avoid a spec docs regeneration inside this PR.",
    "noted, not filed — carrier: none · The unedited production-witness test's title still says '57-component public tier' (it asserts a length above 0; the artefact now has 59). Also, packages/sdui-parser/src/tests/dashboard-widget-options.test.ts's comment says there is no sdui.manifest.json in the tree, which has been false since the artefact was tracked.",
    "noted, not filed — carrier: PM · AGENTS.md is now 1104 lines against a pm-skill-ratchet ceiling of 1116 (headroom 12, freed by deleted content). The ceiling can be lowered."
    ]
    }


    Generated by Claude Code

  15. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    Landed — PR #19921 → 28ce61260b on origin/main, verified by content

    domain:spec execution seat 1 (session_013RDBh5DqXd2xnLwvHLgLFr), 2026-09-24T15:56Z.

    Path.

    • The PR touches governed surfaces (AGENTS.md and docs/adr/**, Tier H), so it landed by the maintainer's hand.
    • os-zhuang submitted an APPROVED review (5306301677) on head b7d0b3693a at 2026-09-24T15:08Z, flipped the PR to ready, and enabled auto-merge.
    • It joined the merge queue at 2026-09-24T15:10Z and merged at 2026-09-24T15:54Z as squash 28ce61260b0ac03be468f5caf83b8d59a8af2265, with parent ccccdcc35e.
    • The squash tree d61d8131ec equals the merge-group tree that CI measured.

    Re-measured on origin/main (tip 276d96dd23, which has the squash as an ancestor), parent against squash:

    reading parent squash
    scripts/gen-sdui-manifest.sh exists (the browser dump) 1 0
    packages/spec/scripts/check-react-blocks-declaration-parity.ts exists (the ratchet) 1 0
    packages/spec/react-declaration-parity.baseline.json exists 1 0
    "sdui:manifest" in root package.json 1 0
    playwright mentions in .github/workflows/cut-rc.yml (case-insensitive) 5 1
    sdui.manifest.json mentions in scripts/build-console.sh 3 7
    scripts/gen-sdui-manifest-node.mjs exists (M1, the standing producer) — dark control 1 1
    sdui.manifest.json exists — dark control 1 1
    • The single playwright mention left in cut-rc.yml is the retirement comment at line 412, "the Playwright browser it needed, are retired". No step invokes Playwright.
    • The tracked sdui.manifest.json on origin/main hashes to sha256 22c83c9ec70163559c2bd8f7b1613174d8660ad9949d15ed483a4189b7857c9a. That is the digest the PR body's step-3 byte comparison recorded for both producers.

    Card state. pm:dispatched is removed and the assignee is cleared (fleet-write relay run 36023712992; read back as 3 labels, 0 assignees). GitHub closed the card as completed through Fixes #17735.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions