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

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-tesla commented on Sep 13, 2026

    @os-tesla
    Collaborator

    Ruling recorded — the tracked sdui.manifest.json must equal what objectui's registry declares (the browser dump), pinned by a producer-parity test; the --strict verdict set is ⛔ not narrowed; the false why string is fixed in the same PR (director seat class-one adjudication, 2026-09-13)

    Class-one self-adjudication by the summoned director seat (SKILL.md:400-403), recorded for the maintainer's 追认表; an overturned row executes the new ruling.

    ① Authority. A gate reads the input it declares: check-react-blocks-declaration-parity.ts declares its input as 「objectui's registry-inputs dump」, and decision batch #91's own precondition made this measurement the deciding one. The measurement says the tracked root artefact (node generator) is NOT that dump: 18 of 57 components differ, dataSource is missing on 15, type vs actionType is one concept spelled two ways. The declared contract is the dump; the artefact CI reads is pulled back to it. Narrowing the verdict set would weaken a gate — a floor — so it is not touched.
    ② Failure direction. A parity pin that reddens when the two producers diverge; a producer fix is one revert away.
    ③ Floors. None moved: gate strength unchanged (verdict set as is), no contract semantics, no security.

    What is ruled

    1. Read both generators first (scripts/gen-sdui-manifest-node.mjs vs gen-sdui-manifest.sh) and establish, key by key, why they differ — the card's own precondition. Where the node generator omits what the runtime registry declares (dataSource on 15 components, align / variant on text, actionType on the two action blocks), the node generator is fixed to emit it; where the node artefact carries a spelling the registry does not (type on the action blocks), the node artefact drops it. One concept, one spelling — ⛔ no union.
    2. A producer-parity test pins the two outputs equal on the fields the parity gate consumes (components[schemaType], inputs[].name); it runs where the browser dump can be produced (Playwright is available in CI).
    3. If parity is unreachable by construction (a registry input that only exists after runtime registration), that is reported on this card before anything is retired — the likely consequence is that CI consumes a browser-produced dump and the node producer retires, and that is a follow-up ruling, ⛔ not this one.
    4. packages/spec/scripts/check-generated.ts's EXTERNAL_INPUT_REQUIRED why string for this artefact is corrected in the same PR (classification unchanged, reason made true).
    5. The --strict verdict set stays exactly as ruled in batch Auto-organize documentation by zod source files #91; [finding] docs/releases-maintenance.md :113–:121, scripts/bump-objectui.sh and scripts/build-console.sh present pnpm sdui:manifest as the pin bump's mandatory second half — the committed artefact the freshness gate reds on is written by node scripts/gen-sdui-manifest-node.mjs, which none of them names #17736 keeps its command/filename scope and inherits this card's answer for the sentence at docs/releases-maintenance.md:118.

    State

    needs-user-decision → pm:queue; bug / domain:spec / priority:p2 kept; cross-domain: the root scripts/gen-sdui-manifest* face is declared in the claim comment.


    Generated by Claude Code

  2. self-assigned this
    on Sep 17, 2026
  3. os-litant commented on Sep 17, 2026

    @os-litant
    Collaborator

    Claim: PM loop round 2
    Session: session_01LvwGppdonww4zGLWZo5rho
    Branch: claude/issue-17735-sdui-manifest-producer-parity
    Worktree: objectstack-issue-17735
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: scripts/gen-sdui-manifest-node.mjs, scripts/gen-sdui-manifest.sh, packages/spec/scripts/check-react-blocks-declaration-parity.ts, packages/spec/scripts/check-generated.ts, root sdui.manifest.json, plus the new producer-parity test and its CI wiring (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: default judgment tier (opus) — dispatch-gates --tier on this surface this run: "no path-derived mandate … floor sonnet · default opus · ceiling fable"; the card carries design judgment (read both generators and decide, key by key, which producer is right), so the default tier applies rather than the floor
    Clause-②: no
    Thread-read: 5651830083
    Serial constraints cleared: none — the three sibling PRs in flight at claim time (#18492, #18525, #18528) touch packages/spec/src/ui/view.zod.ts, packages/spec/src/automation/** and packages/spec/src/ai/** with their generated artefacts; ⛔ none touches scripts/gen-sdui-manifest*, check-react-blocks-declaration-parity.ts, check-generated.ts or the root sdui.manifest.json

    Clause-② reasoning, so a wrong no is auditable

    Neither limb fires. Path limb: the surface is scripts/** and packages/spec/scripts/**, ⛔ not packages/spec/src/**; no *.zod.ts, no error-code ledger. Content limb: no new exported symbol and no new key on a published payload — the root sdui.manifest.json is a tracked repo artefact, not a file in any package's files[]. The ruling states in its own words that gate strength is unchanged (「verdict set as is」) and that no contract semantics move. ⚠️ The accept-set change that does happen is a tightening (a parity pin is added; the artefact drops a spelling the registry does not declare), which is the direction that does not trigger clause ②.

    ⛔ This declaration is the conservative-direction call at claim time, not a finding. The seat routes every delivery in this lane to an isolated review at CONTRACT_REVIEW_TIER regardless, and that review tests this no against the real diff.

    Premise check at claim time — three faces, measured

    Action surface. ⚠️ A plain git log -- PATH on this clone is VOID: all five files report their last touch as 7c8d6d989, which is the shallow graft boundary — git cannot see its parent, so it diffs against the empty tree and every path in that tree reads as touched. Re-taken with scripts/pm/git-history.mjs touch, which proves each answer:

    file last touch when
    scripts/gen-sdui-manifest-node.mjs 4ca7ccf2f 2026-08-30
    root sdui.manifest.json 4ca7ccf2f 2026-08-30 (same commit — generator and artefact move together)
    packages/spec/scripts/check-generated.ts e9fcd6bbd 2026-09-06
    packages/spec/scripts/check-react-blocks-declaration-parity.ts b37f0b176 2026-09-08

    All four predate the 2026-09-13 ruling ⇒ no drift since it was written.

    Work-item surface, measured on origin/main with controls: "dataSource" in the tracked artefact = 0 (control "name" = 339) ⇒ the omission is still there; the false why string 「console dist is gitignored」 in check-generated.ts = 1 (control EXTERNAL_INPUT_REQUIRED = 12) ⇒ ruled item 4 is still owed.

    Card-reference surface, read current rather than as the ruling described them: #15367 closed/completed · #17733 closed · #17736 closed/completed · #18407 open. The last two are live inputs, not background — they are in the dispatch order as premises to falsify.


    Generated by Claude Code

  4. os-litant commented on Sep 17, 2026

    @os-litant
    Collaborator

    os-dev-report
    {
    "issue": 17735,
    "status": "needs_decision",
    "branch": "claude/issue-17735-sdui-manifest-producer-parity",
    "pr": "#18608",
    "session": "session_01LvwGppdonww4zGLWZo5rho",
    "premise_still_valid": false,
    "summary": "Ruling item 4 is implemented (the EXTERNAL_INPUT_REQUIRED why string, plus the identical stale premise in the parity gate own header, both on the declared file surface). Items 1 and 2 are NOT implemented because item 1 premise measured false: the node generator omits nothing. Read in full it calls getPublicConfigs() and hands the result to manifestFromConfigs, which copies config.inputs field-for-field; no filter exists in either. Regenerating reproduces the tracked artefact BYTE-IDENTICALLY (blob 78f870e42fe9 before and after, sha256 49211fee7792 == the record), so the artefact is exactly the registry its producer reads and there is no omission to remove. The divergence is an INPUT skew: the node producer installs npm-published @object-ui 17.6.0 (published 2026-08-24) while the browser dump builds the source at pin 53ded82b (authored 2026-09-05), and all three diverging key families landed in objectui source inside that 12-day window. Root cause is one false equivalence in this repo prose and procedure: .objectui-sha ships a COMMIT, but the @object-ui version read off that commit package.json names a tarball built from an EARLIER commit, because objectui bumps version only at release. check-sdui-manifest.mjs cannot see it: it verifies shape, sha256 and objectuiSha, and reads objectuiPackagesVersion only as a presence check. Item 3 escape therefore fires and nothing is retired.",
    "tests": "Gates: 54 families derived on this head (dispatch-gates --repo objectstack-ai/objectstack --commands), all 54 run, --ran reconciliation exit 0 (51 run, 3 NOT MEASURED). check:generated exit 0 (All 15 generated artifacts are up to date). Parity gate CI-shaped MANIFEST=PWD/sdui.manifest.json ... --strict exit 0 (no new DECLARATION divergence vs accepted baseline); the bare derived command without MANIFEST exits 1 by design and is a prerequisite artifact, not a red. Tests: vitest --project repo check-generated-ledger.test.ts exit 0 (8 passed); vitest --project local check-react-blocks-declaration-parity.test.ts exit 0 (30 passed). Control leg for the one pre-existing red: with both edited files reverted to main content, check:cross-package-test-inputs fails identically (same rooted file packages/cli/test/init-created-files-summary.e2e.test.ts descending packages/spec/dist/), so it is not caused by this diff; restoration proved byte-exact (blobs back to f3a33c06 / 3f850968, git diff HEAD empty). Zero-hit greps all carry same-subject controls: dataSource in tracked artefact = 0 with control name = 339; false why string = 1 with control EXTERNAL_INPUT_REQUIRED = 12; object-tree in PUBLIC_BLOCKS = 0 with control object-grid = 1; published core 17.6.0 has no ELEMENT_DATA_SOURCE_INPUT with control getPublicConfigs hitting.",
    "gates": [
    "node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0",
    "node scripts/check-adr-0087-registration.mjs --self-test :: exit 0",
    "node scripts/check-ci-filter-parity.mjs :: exit 0",
    "node scripts/check-closing-keyword-parity.mjs :: exit 0",
    "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0",
    "node scripts/check-comment-mask-adoption.mjs :: exit 0",
    "node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0",
    "node scripts/check-comment-mask-corpus.mjs :: exit 0",
    "node scripts/check-dev-prereqs.mjs --self-test :: exit 0",
    "node scripts/check-keyed-text-bounds.mjs :: exit 0",
    "node scripts/check-keyed-text-bounds.mjs --self-test :: exit 0",
    "node scripts/check-platform-object-tenancy-census.mjs :: exit 0",
    "node scripts/check-platform-object-tenancy-census.mjs --self-test :: exit 0",
    "node scripts/check-plugin-teardown-shape.mjs :: exit 0",
    "node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0",
    "node scripts/check-registry-log-declared.mjs :: exit 0",
    "node scripts/check-registry-log-declared.mjs --self-test :: exit 0",
    "node scripts/check-rest-log-spy-declared.mjs :: exit 0",
    "node scripts/check-rest-log-spy-declared.mjs --self-test :: exit 0",
    "node scripts/check-system-context-census.mjs :: exit 0",
    "node scripts/check-system-context-census.mjs --self-test :: exit 0",
    "node scripts/check-undeclared-dep-imports.mjs :: exit 0",
    "node scripts/check-undeclared-dep-imports.mjs --self-test :: exit 0",
    "node scripts/docs-audit/check-affected-docs.mjs :: exit 0",
    "node scripts/docs-audit/check-drift-comment.mjs :: exit 0",
    "node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0",
    "pnpm --filter @objectstack/spec run check:empty-state :: exit 0",
    "pnpm --filter @objectstack/spec run check:generated :: exit 0",
    "pnpm --filter @objectstack/spec run check:liveness :: exit 0",
    "pnpm --filter @objectstack/spec run check:react-declaration-parity :: exit 1",
    "pnpm --filter @objectstack/spec run check:strictness-ledger :: exit 0",
    "pnpm --filter @objectstack/spec run check:variant-docs :: exit 0",
    "pnpm check:changeset-gate-self-tests :: exit 0",
    "pnpm check:cross-package-test-inputs :: exit 1",
    "pnpm check:doc-authoring :: exit 0",
    "pnpm check:driver-memory-census :: exit 0",
    "pnpm check:dts-closure :: exit 0",
    "pnpm check:dual-build-cjs-loads :: exit 3",
    "pnpm check:lean-entry-closure :: exit 3",
    "pnpm check:logger-receiver-detach :: exit 0",
    "pnpm check:merge-driver :: exit 0",
    "pnpm check:nul-bytes :: exit 0",
    "pnpm check:org-identifier :: exit 0",
    "pnpm check:page-declaration-shape :: exit 0",
    "NOT-MEASURED pnpm check:pm-dispatch-gates :: exceeded a 560s local foreground budget (exit 124 from the timeout wrapper); no verdict reached. CI runs it uncapped.",
    "pnpm check:pm-governed-merges :: exit 0",
    "pnpm check:published-files :: exit 0",
    "pnpm check:refd-timer-probe :: exit 0",
    "pnpm check:slot-lookup :: exit 0",
    "pnpm check:sourcemap-no-sources-content :: exit 0",
    "pnpm check:test-source-alias :: exit 0",
    "pnpm check:tier-file-adoption :: exit 0",
    "pnpm check:type-source-resolution :: exit 0",
    "pnpm check:watch-hint-literal :: exit 0"
    ],
    "line_budget": "n/a — no skills/** path in the diff. Diff is 2 files, +36/-11 on the first commit, comments and one string literal only.",
    "deviations": [
    "Ruling items 1 and 2 deliberately not implemented — item 1 premise measured false and item 3 escape clause fires. Reported here rather than worked around, as item 3 directs.",
    "Ruling item 4 extended by one file: the identical stale premise in check-react-blocks-declaration-parity.ts own header. It is on the claim declared file surface, is the same defect class, and is named explicitly in the PR body.",
    "check:pm-dispatch-gates killed at a 560s local foreground budget (exit 124) — declared NOT-MEASURED to the reconciler with its reason; CI runs it uncapped.",
    "check:dual-build-cjs-loads and check:lean-entry-closure exit 3 = PREREQUISITE NOT MET (both need a full pnpm build); recorded NOT MEASURED, not as passes."
    ],
    "files_changed": [
    "packages/spec/scripts/check-generated.ts",
    "packages/spec/scripts/check-react-blocks-declaration-parity.ts"
    ],
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "3 — POST /repos/objectstack-ai/objectstack/pulls (draft PR 18608); POST /repos//issues/18608/labels (skip-changeset); POST /repos//issues/17735/comments (this report). Plus 3 git pushes to the feature branch.",
    "open_questions": [
    {
    "question": "Parity is unreachable through the node producer current input (npm), because 17.6.0 is the newest published @object-ui/core and the pin is 12 days ahead of it. Which mechanism reaches the ruled direction of convergence?",
    "options": [
    "M1 — keep a node producer, point it at the pin BUILT TREE via its existing --modules-root flag (build-console.sh already materialises .cache/objectui-SHA, and objectui:refresh already builds it at exactly the moment the manifest needs regenerating). Changes the record to pin a commit rather than a version string. UNVERIFIED: no built objectui tree exists in this container and building one exceeded this round budget.",
    "M2 — CI consumes a browser-produced dump and the node producer retires. Ruling item 3 reserves this as a FOLLOW-UP ruling, explicitly not this card.",
    "M3 — accept the skew as the artefact declared meaning and add a gate that makes it visible (assert the installed version corresponds to the pinned commit, or record both and fail when they disagree)."
    ],
    "recommendation": "M1, because it reaches the ruled direction (the artefact describes the pin registry) without retiring anything, and it reuses a flag the generator already has. But it must be MEASURED before it is chosen — I could not verify that the node generator enumerates an objectui workspace via --modules-root, and shipping an unverified change to a generator is the failure mode this card exists to document. If M1 fails on measurement, M2 is the answer and it needs its own ruling."
    },
    {
    "question": "docs/releases-maintenance.md lines 120-121 tell the operator to read the @object-ui version from the pinned checkout packages/core/package.json. That instruction is what manufactures the skew. The file is domain:devx and #17736 is closed as completed, so it landed without this card answer.",
    "options": [
    "Seat routes a domain:devx card to correct the sentence",
    "Fold it into whichever producer ruling lands from the question above"
    ],
    "recommendation": "Fold it in — the correct sentence depends on which mechanism is chosen, so correcting it now would just need rewriting."
    }
    ],
    "out_of_scope_findings": [
    "to file (3 classes, dedupe words: sdui manifest, objectui version pin, published tarball, registry skew, check-sdui-manifest) — class (b): scripts/check-sdui-manifest.mjs declares it holds the artefact fresh at the objectui pin and its success line says so, but it never verifies that objectuiPackagesVersion corresponds to the pinned commit, so a pin ahead of the last release passes green while the artefact describes an older registry. Same-subject control: it does verify objectuiSha and sha256.",
    "to file (3 classes, dedupe words: object-tree, plugin-tree, PUBLIC_BLOCKS, public tier, getPublicConfigs) — #18407 is NOT subsumed by regenerating. object-tree is registered by plugin-tree in published 17.6.0 AND at the pin, but absent from PUBLIC_BLOCKS in both (control: object-grid present) and plugin-tree declares no tier public opt-in, so getPublicConfigs() excludes it in BOTH producers. The defect lives in objectui public-tier curation, not in either producer. The parity gate reports it live: object-tree: NO component in the manifest.",
    "noted, not filed: check:cross-package-test-inputs is red on this branch AND on main content (control leg above). Rooted in packages/cli/test/init-created-files-summary.e2e.test.ts descending packages/spec/dist/ with no declared glob reaching inside. Successor: the packages/cli seat, or whoever next touches that e2e test — it is their gate and their file, and it reds for them on any diff that pulls the scan in.",
    "noted, not filed: published @object-ui/components 17.6.0 reads d.actionType || d.type on both action blocks — a lenient alias the pin source has already removed in favour of actionType alone. Successor: none — it is objectui already-shipped code, the fix has landed upstream, and it reaches this repo the moment the pin publishes."
    ]
    }


    Generated by Claude Code

  5. os-litant commented on Sep 17, 2026

    @os-litant
    Collaborator

    ⚖️ Ruling item 3's escape clause fired — the mechanism question comes back as the follow-up ruling item 3 itself reserved

    Seat session_01LvwGppdonww4zGLWZo5rho, 2026-09-17T08:5xZ. Dispatch report on this card; PR #18608 carries ruling item 4 only, under Part of #17735 — ⛔ not a closing keyword, so landing it does not close this card.

    What was measured, and why items 1 and 2 were not implemented

    Ruling item 1 rests on 「the node generator omits what the runtime registry declares」. Measured, it omits nothing: it calls getPublicConfigs() and hands the result to manifestFromConfigs, which copies config.inputs field-for-field — no filter exists in either. Regenerating reproduces the tracked artefact byte-identically (blob 78f870e42fe9 before and after; sha256 49211fee7792, equal to the record).

    ⇒ There is no omission to remove. The artefact is exactly the registry its producer reads.

    The real defect — an input skew, and one false equivalence in this repo's own prose

    • The node producer installs npm-published @object-ui 17.6.0, published 2026-08-24.
    • The browser dump builds source at pin 53ded82b, authored 2026-09-05.
    • All three diverging key families landed in objectui source inside that 12-day window.

    ⭐ The root cause is one false equivalence: .objectui-sha ships a COMMIT, but the @object-ui version read off that commit's package.json names a tarball built from an EARLIER commit, because objectui bumps its version only at release. So "install the version the pinned commit declares" does ⛔ not mean "install the pinned commit".

    scripts/check-sdui-manifest.mjs cannot see this: it verifies shape, sha256 and objectuiSha, and reads objectuiPackagesVersion only as a presence check. So a pin ahead of the last release passes green while the artefact describes an older registry.

    Why this is the maintainer's and not the seat's

    Ruling item 3 says it in its own words:

    If parity is unreachable by construction (a registry input that only exists after runtime registration), that is reported on this card before anything is retired — the likely consequence is that CI consumes a browser-produced dump and the node producer retires, and that is a follow-up ruling, ⛔ not this one.

    Parity is unreachable through the node producer's current input: 17.6.0 is the newest published @object-ui/core, and the pin is 12 days ahead of it. ⛔ The seat does not write the follow-up ruling the previous ruling reserved.

    The options

    • M1 — keep the node producer, point it at the pin's BUILT TREE via its existing --modules-root flag. build-console.sh already materialises .cache/objectui-<SHA>, and objectui:refresh already builds it at exactly the moment the manifest needs regenerating. Changes the record to pin a commit rather than a version string. ⚠️ UNVERIFIED — no built objectui tree existed in the round's container, and building one exceeded its budget. Nobody has measured that the node generator enumerates an objectui workspace through that flag.
    • M2 — CI consumes a browser-produced dump; the node producer retires. This is the outcome item 3 named and reserved.
    • M3 — accept the skew as the artefact's declared meaning and add a gate that makes it visible (assert the installed version corresponds to the pinned commit, or record both and fail when they disagree).

    四棱

    ① 实际业务需求 —— 有真实拉动,而且拉动明确指向「artefact 要描述 pin」。
    这份 artefact 唯一的消费者是 check:react-declaration-parity,它存在的理由就是抓 spec 与 objectui registry 之间的声明分歧。今天它比对的是一个12 天前的 npm tarball,于是那扇窗口里引入的任何分歧对它都是隐形的——门禁还是绿的。⇒ 需求不是「要不要换生产者」,是「门禁必须读它声称在读的那个东西」。这一棱把 M3 往下压:让偏斜可见,不等于让门禁重新看得见分歧。

    ② 项目长远合理性 —— 方向唯一,M3 是反向的。
    本项目的基本裁决原则是「声明 > 实现 > 文档」,且「声明而未兑现是实现缺口,补实现或退役,⛔ 不在消费端收窄」。这里声明(artefact 描述 pin 的 registry)是对的,实现(装的是上次发版的 tarball)是错的 ⇒ 补实现(M1)或退役生产者(M2)。M3 是把声明改写成迁就实现,正是该原则禁止的那个方向。⚠️ M3 还有个实际后果:它的门禁会在「pin 领先于最近一次发版」时变红,而那是常态,等于用一条长期红门去描述一个本该修掉的偏斜。

    ③ 防 AI 写元数据犯错 —— 这一棱最响。
    门禁的整个用途是防止「spec 声明的输入」和「渲染器实际接受的输入」悄悄分家——分家之后,AI 按 spec 写出来的元数据会被渲染器忽略。今天这道防线在一个 12 天的窗口上是瞎的,而且瞎得无声(绿)。M1/M2 把它治好;M3 只是让偏斜被看见,门禁本身仍然在比对旧数据。⇒ ③ 指向 M1 或 M2,⛔ 不指向 M3。

    ④ 创业阶段不扩散需求 —— 轻微偏好 M1,因为它几乎不新增机器。
    M1 复用一个生成器已经有的 flag,以及已经存在的 build-console.sh / objectui:refresh 机制——刷新 manifest 的那一刻正好就是构建那棵树的那一刻。M2 退役一个生产者(长期更简单,但按 item 3 要自己的裁决)。M3 新增一道门禁 = 新机器,且这机器长期报红。从紧原则站在 M1 一边。

    四棱同向 M1(③ 最强,① 与 ② 共同排除 M3,④ 偏好 M1 over M2)。 ⚠️ 但 M1 未经实测,而「把未经验证的改动推进生成器」恰恰是本卡存在的那种失败模式。所以推荐是有条件的:先测 --modules-root 能不能枚举 objectui workspace;测不通就是 M2,而 M2 按 item 3 要你的裁决。

    ⛔ 四棱同向不构成代裁资格:item 3 明文把这个出口留给后续裁决,置信门第 ③ 条(不推翻既有裁决)因此不成立。呈报,⛔ 不代裁。


    维护者速读

    改了什么 —— PR #18608 只改了两句错话(两处代码注释/字符串,说「这个产物只能由浏览器产出」,那句话已经过期)。⛔ 没有改任何行为。裁决要求的另外两项没有做,因为做不了,理由如下。

    为什么 —— 我们有一份 sdui.manifest.json,用来让门禁检查「spec 声明的 UI 输入」和「objectui 渲染器实际接受的输入」有没有分家。裁决假设生成它的脚本漏字段。实测:没有漏,重新生成出来的文件和树上那份逐字节一样。真正的问题是它读错了输入——脚本装的是 npm 上最新发布的 objectui(8 月 24 日),而我们 pin 住的是 9 月 5 日的源码提交,中间差 12 天,三类分歧全是那 12 天里产生的。根因是一句我们自己写的错等式:pin 记的是一个 commit,但从那个 commit 的 package.json 读到的版本号,指向的是更早一次发版打的包(objectui 只在发版时才升版本号)。

    风险与代价(含回滚) —— 现状零风险但门禁在一个 12 天窗口上是瞎的、而且瞎得是绿的。M1 复用现成机制,代价是产物的记录从「钉版本号」改成「钉 commit」,做错一次 revert 能回;但 M1 没人测过。M2 退役一个生产者,长期最干净,但按上一条裁决要你单独裁。M3 我不推荐:它是把声明改写去迁就实现。

    席位意见 —— 荐 M1,且以实测为条件:先验 --modules-root 能不能枚举 objectui 的 workspace,验不通就走 M2。四棱同向 M1,其中「防 AI 写错」这一棱单独就够——这道门禁现在正在无声地漏掉分歧。⛔ 我不自裁,因为上一条裁决的第 3 项已经明文把这个出口留给你。

    你要做的(一个动作) —— 选 M1 / M2 / M3 其中一个:M1?


    Generated by Claude Code

  6. os-litant commented on Sep 17, 2026

    @os-litant
    Collaborator

    Card state, so the wait is on the card rather than in a session's memory

    ⏳ #17735 stays pm:dispatched and assigned until PR #18608 merges, then releases. The reason for not transitioning now: #18608 carries Part of #17735 (⛔ not a closing keyword), so it is a partial landing — and the lane's rule is that a partial landing releases the card at merge, not before. The seat is still driving that PR to MERGED, which is the assignment pm:dispatched names.

    At merge the card releases with a Release: line and moves to needs-user-decision — ⛔ not back to pm:queue — because what remains is the mechanism ruling (5711529692), which is the maintainer's, not a queue item.

    Waiting on: the maintainer, for M1 / M2 / M3. Since: 2026-09-17T08:5xZ. Nothing else in this lane is blocked by it.

    ⛔ Ruling items 1 and 2 are not owed by anyone right now — item 1's premise measured false and item 3's escape clause fired. They come back only if the mechanism ruling puts them back.


    Generated by Claude Code

  7. os-litant commented on Sep 17, 2026

    @os-litant
    Collaborator

    os-dev-report
    {
    "issue": 17735,
    "status": "done",
    "branch": "claude/issue-17735-sdui-manifest-producer-parity",
    "pr": "#18608",
    "session": "session_01LvwGppdonww4zGLWZo5rho",
    "premise_still_valid": true,
    "summary": "PATCH ROUND discharging the seat's REWORK verdict (comment 5711927990) on top of the PASS contract review (5711919674). All three items are fixed in the two files already in the diff, head ae7e4c9. (1) The 'builds objectui' clause, asserted in both files, is replaced with what the script does, read line by line: gen-sdui-manifest.sh derives BUILD_ROOT=.cache/objectui-SHA12 at 507, exits 1 at 512-516 unless that directory already exists (printing "Run 'pnpm objectui:build' first to vendor the console at the pinned SHA"), then pushd's into that vendored tree, spawns pnpm --filter @object-ui/console exec vite dev (373-376, 545, 630-631), runs objectui's dumper against it (654-655) and ratchets ADR-0082 on the result (684-688) — it REQUIRES a build and performs none; it dumps and ratchets. (2) The objectui#6741 citation is dropped from both files; the fact it was cited for is kept and the parity header carries a number-free tombstone so nobody restores it. (3) The PR body no longer counts assertions at all: it enumerates every corrected sentence, and both survivals the review named are CORRECTED rather than declared. Ruling items 1 and 2 stay unimplemented, the M1/M2/M3 mechanism question stays in the maintainer's decision box, #18407 stays open, and the pre-existing check:cross-package-test-inputs red is untouched — none re-opened. The card stays open: the PR keeps Part of #17735 and gained no closing keyword.",
    "tests": "All on head ae7e4c9, merged with origin/main at 21b7c12 before measuring; exit codes captured by redirect-then-$?, never through a pipe. pnpm --filter @objectstack/spec build :: exit 0 (34/34 declaration files) — run FIRST because two gates read the built dist/. pnpm --filter @objectstack/spec run check:generated :: exit 0 — 'All 15 generated artifacts are up to date'; the corrected print line now reads 'Needs an input this aggregate does not pass (1 source audit(s)):'. MANIFEST="$PWD/sdui.manifest.json" pnpm --filter @objectstack/spec check:react-declaration-parity --baseline react-declaration-parity.baseline.json --strict :: exit 0 — 'no new DECLARATION divergence vs accepted baseline'. vitest run --project repo scripts/check-generated-ledger.test.ts :: exit 0, 8 passed. vitest run --project local scripts/check-react-blocks-declaration-parity.test.ts :: exit 0, 30 passed. pnpm lint (eslint . --no-inline-config, the repo-wide population, NO narrowing) :: exit 0. Build and both vitest runs went through scripts/pm/os-verify-lock.sh, slot os-dev-17735-r2 (VERDICT command-exit 0 each; 155s / 5s / 19s held, 0s waited). ON-DISK PROOF of every edit: each replacement was applied by an exact-anchor script that refuses unless the anchor occurs exactly once, then verified by grep counts with same-subject controls that HIT — 'builds objectui' 0/0 in the two files (control 'does NOT' 2/3); '6741' 0/0 in the two files (control: scripts/gen-sdui-manifest-node.mjs 1); 'cannot be produced here' 0, 'whose input this repo cannot produce' 0, 'an input this repo cannot produce' 0 (control EXTERNAL_INPUT_REQUIRED 12). objectui#6741 refuted with control legs on the identical endpoint: issues/6741 and pulls/6741 both 404, while objectui 6735/6738/6739/6742/6743/6745/6750 all answer 200 — the 404 is the number, not the endpoint or the token. NO ABLATION was performed and none is owed: the diff is comments and print strings only, no verdict, no gate logic and no test is touched, so there is nothing whose failure could be demonstrated. NOT MEASURED: CI on this head (report is filed at local-verification close, per the dispatch contract).",
    "gates": "54 families derived on head ae7e4c9 with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands (stderr declares repo + commit; change set = the 2 files, three-dot). All 54 run, each exit code recorded, reconciled with --ran :: exit 0 — '54 derived famil(ies) accounted for — 52 run, 2 NOT-MEASURED (2 DERIVED from a recorded exit 3)'. 50 green. 4 non-zero, every one already established and none caused by this diff: check:react-declaration-parity (bare) exit 1 = BY DESIGN, it needs MANIFEST=; the CI-shaped run above is green. check:cross-package-test-inputs exit 1 = PRE-EXISTING and diff-invariant (control leg established last round: red on main and head alike, only when packages/spec/dist/ exists). check:dual-build-cjs-loads exit 3 and check:lean-entry-closure exit 3 = PREREQUISITE NOT MET, i.e. NOT MEASURED, not red — both read built output and need a full pnpm build, which CI does (lean-entry-closure's own self-test passes, 22 cases). check:pm-dispatch-gates :: exit 0 — 1746 cases pass, 813.6s, run DETACHED with its exit code captured to a file because it exceeds this container's ~10min foreground cap; a cap kill is not a red, and this run did not need that caveat.",
    "line_budget": "n/a — no skills/** path in the diff (control: the change set is exactly 2 files, both under packages/spec/scripts/). No published skill text moves, so no line ratchet applies.",
    "files_changed": [
    "packages/spec/scripts/check-generated.ts — EXTERNAL_INPUT_REQUIRED why string (citation + 'builds objectui' clause), the bucket's doc comment, the bucket's ledger classification prompt, and the print line with its rationale comment",
    "packages/spec/scripts/check-react-blocks-declaration-parity.ts — the header's browser-producer bullet ('builds objectui from the SOURCE') and the browser-only-claim line's dead citation"
    ],
    "deviations": [
    "ONE correction beyond the two survivals the seat named, in the same file and the same sentence class, declared in the PR body rather than left: check-generated.ts's ledger classification prompt ('or audit source against an input this repo cannot produce') states the SELECTION CRITERION for the very bucket whose definition this round corrects — leaving it would have left the file defining one bucket two ways. It is a problem-message string pinned by no test; the ledger test's four toContain pins are unchanged and green.",
    "The rationale comment two lines above print line 659 ('which for these is not an option from this repo') was corrected with the print line it explains — correcting the line while leaving its own explanation contradicting it reproduces the defect at a smaller scale.",
    "THREE REST writes, one more than the budget of two. The third is the mandated read-back's repair: the first body PATCH came back with TWO attribution footers because a raw REST PATCH on a PR body appends the bare footer block irrespective of what was sent (+58 bytes, measured twice). Repaired by re-sending a freshly composed, footer-free body; read back at one footer, prefix byte-identical, zero tag-shaped fragments.",
    "check:pm-dispatch-gates was run detached rather than in the foreground (its 813.6s battery exceeds the container's foreground cap). Its exit code was captured to a file and is a measurement, not a claim.",
    "The dead citation also lives at scripts/gen-sdui-manifest-node.mjs:28, outside this PR's two-file surface. NOT fixed here — the verdict scoped the three items to the two files in the diff. Reported below for the seat to file."
    ],
    "mcp_calls": "0 — no MCP GitHub tool was called, read or write. Every GitHub interaction went through the REST proxy with curl.",
    "api_writes": "3 — PATCH /repos/objectstack-ai/objectstack/pulls/18608 (body), PATCH /repos/objectstack-ai/objectstack/pulls/18608 (footer repair, see deviations), POST /repos//issues/17735/comments (this report). No label write (the PR already carries size/s, tooling, skip-changeset — verified present on read-back after both pushes). No POST /issues. Git: 2 pushes to the existing branch, no force.",
    "open_questions": [
    {
    "question": "Which producer should the tracked sdui.manifest.json describe — the PUBLISHED @object-ui tarball, or the registry of the commit .objectui-sha pins? The two disagree today and the gap is structural, not a bug in either generator.",
    "options": [
    "M1 — point the node producer at the pin's BUILT tree via its existing --modules-root flag (build-console.sh already materialises it at .cache/objectui-SHA); the manifest then describes the pinned SOURCE, matching the generator's own 'Versioning contract'. Unverified: no built objectui tree exists in this container.",
    "M2 — keep the browser dump as the producer of record and retire the node route to a convenience.",
    "M3 — accept the skew and add a detector that refuses a record whose installed version cannot correspond to the pinned commit."
    ],
    "recommendation": "NOT MINE TO MAKE, and deliberately not made: the seat placed this in the decision box on #17735 (comment 5711529692) and the dispatch forbids choosing one. Carried here only so the question is not lost between rounds."
    }
    ],
    "out_of_scope_findings": [
    "to file (3 classes, dedupe words: gen-sdui-manifest-node, objectui#6741, dead citation, browser-only claim expired, 404) — scripts/gen-sdui-manifest-node.mjs:28 carries the SAME dead objectui#6741 citation this PR removes from the other two files, in the very header both corrected sites now point readers to for the readings. Same defect, same class, outside this PR's declared file surface (the verdict scoped the three items to the two files in the diff). Successor: the next PR touching the node producer, or this card's follow-up.",
    "noted, not filed: a measured platform reading for pm-dispatch references/platform-readings.md — a raw REST PATCH on a PR BODY appends the bare footer block (newline newline rule-line newline _Generated by [Claude Code](https://claude.ai/code)_, exactly +58 bytes) irrespective of what the sent body carries, so a body sent WITH its own footer stores TWO. Measured twice on #18608 today. The existing note covers create-vs-edit and MCP-vs-REST as cells that disagree; this fills the REST/edit cell. Successor: the next seat that writes a PR body by REST.",
    "noted, not filed: the contract review's own recommendation that check:cross-package-test-inputs' environment-dependence be FILED rather than merely noted — it reds locally only when packages/spec/dist/ exists, and CI runs it without a build, so CI is blind to the escape it reports. That is the review's finding and it is already written into comment 5711919674; recorded here so it is not lost, not re-derived. Successor: the cli seat / the reviewing seat that raised it."
    ]
    }


    Generated by Claude Code

  8. removed their assignment
    on Sep 17, 2026
  9. 19 remaining items

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

  11. 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 62597c588072: 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

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