Repository navigation
[Decision] may a kind:'html' page author intrinsic HTML tags (div, a)? The console manifest says no, 3 of 3 shipped html pages say yes, and #19922's fallback cannot go live until one side changes #20112
Description
Ruled: 5852014527 · letter A · 2026-09-27T02:37Z
Restart-when: .objectui-sha on objectstack main names an objectui commit that contains baac95a261 (objectui#10735, PR objectui#10753)
History: this line read Blocked-by: objectstack-ai/objectui#10735 until 2026-09-27. objectui#10735 merged as baac95a261 on 2026-09-27, and this ruling's own unlock reading is the pin, not the upstream merge (5852014527, item 2). The pin f8a9d0fb05 (objectui commit of 2026-09-24) does not carry it ⇒ pm:on-hold on the install surface (triage seat, session_01W89enF2dYV7K4N2Fbfj33f).
Filing gate: ② a decision only the maintainer can make. What a published tier's authors may legally write is a producer-side contract question (objectui). The CLI's gate either arms against the current answer or waits for a new one. Reader: the director seat's decision batch. Ruled A (comment above); this card is now objectstack's execution card in the domain:cli lane, blocked on objectui#10735; #19922 stays held behind it.
Filed by the domain:cli execution seat (#6024, session_01TnPAC1UsTGfHPXVUCL6iLn) from its round on #19922. ⛔ Not a claim. Routing and grading belong to triage.
The question
Should a kind: 'html' page be allowed to author intrinsic HTML tags (div, a, …)?
- Today the manifest the CLI would validate such pages against says no.
- The pages this repository ships say yes.
What was measured
All measurements are on origin/main aa04ea29, by the #19922 round, and re-read by this seat.
-
The manifest.
packages/lint/src/sdui-jsx-baseline.json's header states: "the public tier deliberately declares no intrinsic HTML tags (59 curated blocks; div/a/p absent;htmlis the tier-C escape hatch), while the three shipped html pages author with div/a — every error below is a plain HTML tag, none is a real authoring mistake". It goes on: "What the html tier's legal vocabulary IS remains a producer-side question (objectui); this ledger keeps the gate live and honest while that question settles" (ratchet-to-zero per objectuiui#6779). -
Where the manifest goes.
scripts/build-console.shships the repo-rootsdui.manifest.jsoninside@objectstack/console'sdist(PR fix(sdui-manifest): one producer from objectui's built tree; retire the declaration-parity ratchet and the browser dump #19921, [finding] the tracked rootsdui.manifest.jsonand the browser dump differ on the fields the parity gate consumes (18 of 57 components;dataSourcemissing 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 fallback. The CLI's fallback to that file (
resolveSduiManifest(),packages/cli/src/utils/sdui-manifest.ts) is dead today: [finding] the CLI's@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922, which resolves a subpath the console'sexportsdoes not publish. The fix is measured and ready: resolve@objectstack/console/package.jsonfrom the CLI's own location and joindist/sdui.manifest.json. -
With the file reachable,
examples/app-showcaseflips from exit 0 to exit 1:- on
os validate,os compile(the stepos devandos startspawn) andos lint; - with 200 errors each: 100
jsx-forbidden-tagand 100jsx-unknown-component; - over 3 of 3 in-tree
kind: 'html'pages.
These are the same 200 rows the ledger carries.
- on
So landing #19922's fix before this is settled would:
- stop the repo's default dev app from compiling for anyone with a built console (CI does not compile the showcase with a console dist present, so CI stays green over it);
- at the next release, newly fail
validate/build/dev/startfor every manifest-less customer project whose html pages use intrinsic tags. That narrows what the published CLI accepts, which is BREAKING.
Options (four axes)
- A. The producer declares the html tier's intrinsic vocabulary. objectui adds the intrinsic tags its html-tier renderer accepts to what the manifest declares for html pages. The manifest is regenerated at the pin, the ledger's 200 rows go stale and are deleted, and [finding] the CLI's
@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922 lands unchanged.- Business need: real. html is the escape-hatch tier, and intrinsic HTML is what its authors write.
- Long-term: contract-first. The producer states what its renderer accepts, and the consumer checks against it.
- Anti-AI-error: once armed, the gate rejects only real mistakes (unknown components, bad props) and is trusted.
- Startup focus: one producer-side change, with no new surface in this repository.
- B. Intrinsic tags are illegal on the html tier.
- The showcase's 3 pages are rewritten to public-tier blocks: 200 sites, and the ledger ratchets to zero.
- [finding] the CLI's
@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922 then lands as BREAKING (Clause-②: no (narrowing),minor, with a migration line), because customers' intrinsic-tag html pages newly fail at that release. - Anti-AI-error: strict. The cost is breaking authors on the one tier whose purpose is raw HTML.
- C. Retire the console fallback (ADR-0049 remove arm) and keep only a project's own manifest.
- This is honest about today, but it discards what fix(sdui-manifest): one producer from objectui's built tree; retire the declaration-parity ratchet and the browser dump #19921 shipped the file for: manifest-less projects never get component/prop checking.
- It is the weakest on the anti-AI-error axis.
The domain:cli seat's reading, ⛔ not a ruling: A. It is the only option in which the gate goes live without false positives and without breaking the tier's own authors. Its cost is a producer-side change in objectui. Until the ruling, #19922 stays pm:blocked on this card, with its fix fully specified there.
Related, not this decision
The same round measured that with no manifest reachable, the JSX gate degrades to parse-level validation and says nothing. That is filed separately as #20113, because a notice does not depend on this ruling.
Dedupe: MCP issue search in this repository (html tier intrinsic tags div a legal vocabulary sdui manifest jsx-forbidden-tag showcase html pages ratchet baseline, closed included): 6 hits, none this question. The nearest is #14490 (html tier: the type input of action:button / action:icon). Dedupe words: html tier intrinsic tags div a public-tier manifest · sdui-jsx-baseline ratchet-to-zero showcase html pages · jsx-forbidden-tag div is not an allowed component
Activity
objectstack-fleet commentedon Sep 25, 2026
维护者速读
平台有一类「html 页」,是专门留给作者直接写原生 HTML 的逃生舱。现在两边说法相反:官方组件清单说这类页不能用
div、a这类原生标签,可我们自己内置的 3 个 html 页全都在用。命令行里本该拿这份清单做检查的修复(#19922)已经测好待合,但它一上线,示例应用在装了控制台的机器上立刻编译失败,下个版本还会让所有这样写的客户项目validate/build/dev报错。三条路:
@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922 原样落地。@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922 作为破坏性变更发布,写了原生标签的客户项目在那个版本开始报错。推荐 A。回一个字母:A / B / C。
os-decision-facets
Governing text:
packages/lint/src/sdui-jsx-baseline.jsonheader — "What the html tier's legal vocabulary IS remains a producer-side question (objectui)"; ADR-0080 Decision §3 — "The registry is the contract — the spec owns only the envelope".Prior rulings read: html tier, intrinsic tags, sdui manifest, jsx-forbidden-tag, registry contract → ADR-0080 Decision §3 is the nearest and supports the producer declaring its own vocabulary; no ruling on the html tier's vocabulary; thread: none.
推荐:A。终态:两年后 html 层的合法词表由渲染它的一方声明、构建期按清单检查,与主流做法一致(Salesforce LWC 模板、MDX 都允许标准 HTML 元素,只校验自定义组件)。回退:若 objectui 短期无法声明,维持 #19922 挂起、先落 #20113 的提示行,⛔ 不选 B。
自检:只看①选 A;②③④ 是否翻转:否。
置信缺口:objectui 的 html 层渲染器实际接受哪些原生标签(是否是一个闭合集合)本席未实测;客户项目里 html 页的数量本仓量不到。
裁后执行:A ⇒ 在 objectui 立
domain:ui卡声明 html 层原生标签,清单随 pin 重新生成,账本 200 行删除,#19922 解锁落地;B ⇒domain:cli改写内置 3 页并以破坏性变更落 #19922;C ⇒ 按 ADR-0049 退役控制台回退,#19922 关闭。Triage (English audit line): routed to the decision box —
needs-user-decision·priority:p2(the level of #19922, which it holds) ·domain:cli·pm:blocking(#19922 carriesBlocked-by: #20112). A published tier's legal vocabulary and a change to what the published CLI accepts are both on the manual floor, so triage does not adjudicate it. Triage seat #6015 ·session_01CRZSc7dU8oDStbTbSwhuZe· 2026-09-25T08:01Z.objectstack-fleet commentedon Sep 27, 2026
Ruling: batch #225 item 1 · letter A · maintainer 「其他同意」 2026-09-27T02:37Z
Director seat, summon #30,
session_01AsCNgFBs8HCjwhyHQsFbx3. Batch #225 was presented in the seat chat; the maintainer named two other items for a further mainstream-platform analysis and ruled every remaining item as recommended: 「20149 19995 其他主流平台是怎么处理类似问题的,帮我分析给我建议;其他同意。」Ruled: A — a
kind:'html'page may author the intrinsic tags its renderer registers; the published manifest declares that set;divstays deprecated.Readings this ruling rests on (objectui
origin/main5c61e52, objectstackorigin/main8d1f7ab785), which refine the card's framing:packages/components/src/renderers/basic/html-elements.tsxregisters the sanitised flow/inline set (h1–h6, p, a, blockquote, pre, emphasis, lists, figure/img/hr/br/time and more) with per-taginputsand thechildrenslot (objectui#9910); its header: 「For that tier to live up to its name, the everyday HTML tags an author reaches for … must each resolve to a renderer」.span, table, code, label and the sectioning tags are registered elsewhere. The console's html-tier compile (packages/components/src/renderers/layout/page.tsx) whitelistsComponentRegistry.getKnownTypes(), which is why the three shipped pages render today.sdui.manifest.json(59 components plushtml) isgetPublicConfigs()overPUBLIC_BLOCKS(packages/core/src/registry/public-blocks.ts), which deliberately omits that set and recordsdivas deprecated in favour ofbox(2026-08-29 ruling, objectui#3965 / PR objectui#6878).kind:'html'is author-written HTML expressed as constrained JSX); the standing principle that an undeclared key follows the implementation and the declaration is then written.So the disagreement was never whether html pages may use intrinsic tags (the producer implements and declares them); the published manifest omits the set. B would contradict objectui's own design of the tier and break customers' pages; C discards a delivered check.
Execution (one ruling, both repositories):
domain:ui·pm:queue·priority:p2, filed with this ruling): the published manifest declares the html tier's registered intrinsic set exactly as the registry declares it, with inputs and child slot; ⛔ notdiv; if declaring them would also widen the curated JSON-surface vocabulary (the manifest carries no tier marker), the dev reports the fork instead of widening silently.minor,Clause-②: yes.needs-user-decision→pm:blocked, body lineBlocked-by: objectstack-ai/objectui#10735; the unlock reading is.objectui-shamoved to a sha that carries it (the consumer can install), not the upstream merge. Then, in thedomain:clilane: regeneratesdui.manifest.jsonat the pin, rewrite the showcase'sdivsites toboxand fix any tag that is a real authoring mistake, ratchetpackages/lint/src/sdui-jsx-baseline.jsonto zero, and land [finding] the CLI's@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922 unchanged (patch,Clause-②: no). [finding] the CLI's@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922 stayspm:blockedon this card.divdeprecation has been a dev-only warning since 2026-08-29; under 「创业阶段不渐进」 the renderer's retirement belongs in the ui seat's Acceptance notes.Confidence gaps recorded: the ledger's 200 rows were read only for
aanddiv; the manifest generator's source was not read (its role is taken from thepublic-blocks.tscomment).Generated by Claude Code
objectstack-fleet commentedon Sep 27, 2026
The blocker has landed: objectui#10735 merged as
baac95a261(PR objectui#10753). The port list for this lane followsPosted by the objectui
domain:uiseat #2 (session_014mXUNuFomfj24w7s1pZzhN), which landed it. ⛔ Not a claim; ⛔ not an unlock. This card's own unlock reading still applies:.objectui-shamust move to a sha that carriesbaac95a261. The seat's ACCEPT is on objectui#10735.What objectui now publishes.
getPublicConfigs()appends the html tier's registered intrinsic set,HTML_TIER_INTRINSICS(47 tags). Each entry is stampedtier: 'html'in the projection.manifestFromConfigswritesManifestComponent.tier: 'html'on exactly those entries. Every curated entry serialises byte-identically.div,codeandkbdare absent.What this lane owes, measured by the PR's contract reviews:
packages/sdui-parser/src/{index,types,codegen}.tschanged.check:sdui-locksteprecords those files, so it goes red at the pin bump until the port lands.sdui.manifest.jsonwould declare the 47 tags withouttier.compile()whitelists the keys and ignorestier, so the gate treats them the same either way.sdui.manifest.jsonat the pin with the existing generator (gen-sdui-manifest-node.mjs, which callsgetPublicConfigs()thenmanifestFromConfigs).arows and every other roster tag go stale and are deleted.divrows stay refused (forbidden-tag) until the showcase pages are rewritten tobox, as the ruling says.@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922 stays held behind this card as before.Out of the objectui PR, filed there:
codedraws thefield:codewidget and drops its text.codeis not declared.divis refused by the published manifest but still accepted by the console's html compile, and its registration declares the deprecation for thejsonsurface only. The gate's refusal does not namebox.Generated by Claude Code
feat(core,components): the html tier registers and declares code — an…
feat(components): refuse div on the html tier, naming box (objectui#1…
fix(cli): the JSX page gate says when it ran at parse level only, and…
objectstack-fleet commentedon Sep 29, 2026
Unlock scan: the
Restart-when:condition holds, and the release is refused under the hold double-check.pm:retriageasks triage to re-derive the port list firstdomain:cliexecution PM seat #6024 · sessionlocal_1d2a197c-c20e-4e90-9be8-413d4d432289· unlock scan, written 2026-09-29T00:20Z · ⛔ not a claim;pm:on-holdstays until triage answersThe condition holds.
.objectui-shaonmainisdd3f7e1be356. It was bumped by chore(objectui): bump the console pin to dd3f7e1be356 (carries the injected-client boot fix) with the showcase div→box and trash-icon follow-through #20436 at 2026-09-28T13:39Z, and it containsbaac95a261(objectui#10735). Measured:git merge-base --is-ancestor baac95a261 dd3f7e1be356succeeds in the objectui clone.Why the release is refused. The hold rule releases only on the condition of the latest transition, and refuses when a newer merged PR sits on the card after it. The latest transition to
pm:on-holdwas the body edit at 2026-09-27T16:37Z, which carried no transition comment. After it, two things changed what this card would carry:39b8d510, ancestor ofdd3f7e1be356);So the port list in
5853312677was written before both, and parts of it may already be done or may have changed.Asked of triage (
pm:retriage):dd3f7e1be356: what the three shipped html pages still author, and what the console manifest now declares.pm:queuewith that list, or close it if the pin bump already finished the work.@objectstack/consolemanifest fallback can never resolve:resolveSduiManifest()asks for@objectstack/console/dist/sdui.manifest.json, but the console'sexportsmap publishes only./package.json#19922 (Blocked-by: #20112) and [finding] the JSX page gate looks for the project's sdui.manifest.json in the invoker's cwd, not beside the config the command was given:os validate path/to/objectstack.config.tsfrom elsewhere never reads that project's manifest #20166 (Blocked-by: #19922) follow from whichever answer is chosen.3 remaining items
objectstack-fleet commentedon Sep 29, 2026
Claim: PM loop round 2 of the
domain:cliseat's sessionlocal_1d2a197c(batch3): the lane'spm:blockingcard, first in the selection order; the remaining port finished in stride, as triage allowed (5882165416)Session:
local_1d2a197c-c20e-4e90-9be8-413d4d432289Account:
hotlongBranch:
claude/issue-20112-sdui-parser-tier-portWorktree:
objectstack-issue-20112Domain:
domain:cliSeat:
domain:cli#1File surface (a
domain:devxpackage, kept in this lane at triage's word):packages/sdui-parser/src/index.ts,types.tsandcodegen.ts: objectui#10735'stierplumbing ('html'in the union,ManifestComponent.tier), ported byte-faithfully from objectui at the pindd3f7e1be356;sdui.manifest.json, regenerated, so the html-tier intrinsics carrytier: 'html';check:sdui-lockstepreads, re-recorded;packages/sdui-parser;.changeset/20112-*.mdif a published package changes.Read-only:
packages/cli/**(#19922 is in flight there),packages/spec/**,packages/lint/**. Stop on breach and explain in the reportContainer & model:
S,mode:subagent,model: default tier.Clause-②: yes
Thread-read: 5882165416
Serial constraints cleared:
The file lists of all 9 open PRs were read in this act: none touches packages/sdui-parser, sdui.manifest.json or packages/console. #19922 (this seat, in the same act) is on packages/cli/src/utils/sdui-manifest.ts and does not read tier (compile() ignores it), so the two are disjointTaken 2026-09-29T04:34Z,
origin/mainf11b5f20a. Executes ruling A (5852014527) as triage re-derived it (5882165416): items 2 and 3 are done by PR #20436, and item 1, the locksteptierport, remains.Clause-②: yes(amended in place after the round, on the dev's open question): the port adds'html'to the acceptedRegistryConfigLike.tierunion and atiermember to the exportedManifestComponent, and@objectstack/console's shipped manifest gains the key on 48 entries. That widens a published surface, as objectui declared for the identical act (baac95a261).compile()does not readtier, so no verdict moves.objectstack-fleet commentedon Sep 29, 2026
os-dev-report
{ "issue": 20112, "status": "done", "branch": "claude/issue-20112-sdui-parser-tier-port", "pr": "https://github.com/objectstack-ai/objectstack/pull/20582", "session": "local_1d2a197c-c20e-4e90-9be8-413d4d432289", "premise_still_valid": true, "summary": "Ported objectui#10735's tier plumbing into packages/sdui-parser/src/{index,types,codegen}.ts. The changed lines of each file are cmp-identical to objectui baac95a261, and every added line is verbatim in the file at pin dd3f7e1be356: RegistryConfigLike.tier admits 'html', ManifestComponent.tier?: 'html' is new, manifestFromConfigs writes exactly 'html' or omits the key, and generateBlockList sections the html tier. Regenerated sdui.manifest.json over objectui's built tree at the pin: 48 entries gain \"tier\": \"html\" and nothing else moves (107 keys, same order, 0 other fields changed). The count is 48, not triage's 47, because objectui#10756 added code to the roster before the pin. The re-record touches scripts/sdui-manifest.record.json (sha256 d0666ac585db); objectui-lockstep.json re-records byte-identically, so it was already current. H0-H3 all hold as measured, with one count correction: 48.", "tests": "All at head ffbb0c4802. (1) pnpm --filter @objectstack/sdui-parser build + exec vitest run --maxWorkers=2 + typecheck: 12 files / 199 tests passed, tsc clean; --listFiles shows the new test in the typecheck program. (2) The new file html-tier-manifest.test.ts has 10 cases, all passing. (3) Ablation from the committed fix 9a77e00415: the three sources were restored to f11b5f20a2 under an EXIT/INT/TERM trap. Landing was proven by grep -c (three-arm union 1 to 0, tier?: 'html' 0, html section 0). Result: 2 failed / 8 passed (the stamp case and the block-list case; the other 8 pin readers that must not move), and tsc exit 2 with 6 errors (TS2322 x4, TS2339, TS2367). Restored with git checkout HEAD --: each hash-object equals HEAD and git diff HEAD is empty. The test imports ../index.js (src), so no dist leg applies. (4) Manifest control leg: the unported dist over the same built tree reproduced the tracked artefact byte-for-byte (sha256 4073897dcdc1, file unchanged). Ported: sha256 d0666ac585db, 103874 bytes; check-sdui-manifest OK. (5) H2: check:sdui-lockstep exits 0 on the drift leg (sources at f11b5f20a2) and on head, so it is blind to the union. (6) H3: compile() over capability-map, command-center-jsx and start-here is ok=true, 0 errors, 0 warnings against both the old and new manifest, and the full results are deep-equal (0 of 3 moved). Lit control: deleting box from the manifest gives ok=false, 54 errors. (7) Consumer @objectstack/lint, after building its closure with pnpm --workspace-concurrency=2 --filter '@objectstack/lint^...' build: vitest 115 files / 5358 passed / 5 skipped, including the production witness 'wired run over the three shipped html pages is clean'; typecheck (tsc --noEmit + check:test-typecheck) OK. (8) pnpm lint, the full repo, not narrowed: exit 0. (9) dispatch-gates --commands: 71 derived, all run. --ran reports 68 run, 3 NOT-MEASURED (exit 3), 0 UNRUN. (10) check-issue-citations --base origin/main: exit 0.", "mcp_calls": "0", "api_writes": "3 REST writes: POST /repos/objectstack-ai/objectstack/pulls (draft PR 20582, via with-fleet.sh); POST /repos/objectstack-ai/objectstack/issues/20582/assignees (hotlong, via label-write.mjs, read back to match); POST /repos/objectstack-ai/objectstack/issues/20112/comments (this os-dev-report, via post-stamped.mjs). A first label-write run outside with-fleet exited 3 (no token) and wrote nothing. Plus 3 git pushes of the branch (the empty-branch probe, the port, the changeset), not REST.", "open_questions": [ { "question": "The PR's line 2 is the claim's `Clause-②: no`, copied as the dispatch requires. By the level axis's own definition, clause ② is 'a new key on a published payload', and this PR adds `tier` to 48 entries of the manifest @objectstack/console ships in its dist. It also adds an accepted value to RegistryConfigLike.tier and a member to ManifestComponent. objectui declared `Clause-②: yes` for the identical act (baac95a261). Should the seat flip the line?", "options": [ "A: keep `Clause-②: no`. The level axis stands down; the changeset is minor anyway.", "B: the seat edits PR 20582 line 2 to `Clause-②: yes`. The axis then requires at least one minor, which the changeset already has, so no other change is needed." ], "recommendation": "B. The act matches the gate's definition word for word, and the producer declared yes for the same change. Under either line the gate verdict is green, so the fix costs one body edit and no code." } ], "out_of_scope_findings": [ "class: a · reach: named producer: scripts/gen-sdui-manifest-node.mjs, the sole producer of the tracked sdui.manifest.json, exits 1 on this macOS host with the default TMPDIR · evidence: the runner's resolve hook compares parentURL === RUNNER, where RUNNER is built from os.tmpdir() (file:///var/folders/...). Node reports the realpath (file:///private/var/folders/...), so no bare specifier is re-anchored to the modules root. Result: 16 'Cannot find package @object-ui/...' failures, 'the registry enumeration failed (exit 1)'. With TMPDIR set to a realpath directory the same command exits 0 with 107 components. Fix shape: realpathSync the mkdtemp dir. Not filed, and not fixed here: outside the claim's file surface · dedupe words: gen-sdui-manifest-node TMPDIR realpath macOS · sdui-manifest-runner Cannot find package @object-ui · private/var/folders resolve hook parentURL", "carrier: 承接者:无 · noted, not filed: pnpm check:bash32-floor --self-test fails 7 of 179 cases on this macOS host (native bash 3.2): the coproc, case-fallthrough, case-fallthrough-next, has-v, append-both and pipe-both probes, plus '[[ -v name ]] is shell this host can parse'. The same command fails the same 7 in a detached worktree at f11b5f20a2, so the failure is host-bound and not this diff. CI runs Linux bash 5.", "carrier: 承接者:无 · noted in Acceptance notes, not filed: the two sdui-parser copies still differ outside check:sdui-lockstep's three comparisons. objectui's RegistryConfigLike has lazy?: boolean and a longer isContainer docblock; body-dialect.ts and provenance.ts are absent here; parse, validate, kanban-quick-add and dashboard-widget-options differ outside the recorded region. The gate is blind to type-union drift (H2, both legs green). It was not widened.", "carrier: 承接者:无 · noted in Acceptance notes: gen-sdui-manifest-node.mjs's header says check:sdui-lockstep 'holds the two copies byte-equal'. It holds the grammar region, the code set and the containment predicate only. Stale prose.", "carrier: this PR · noted in Acceptance notes: the pending .changeset/console-dd3f7e1be356.md says the published manifest marks the html tier's elements tier html. For the manifest @objectstack/console ships, that was untrue before this PR and is true once it lands in the same release." ], "gates": { "head": "ffbb0c4802", "derived": "71 derived by dispatch-gates --commands, all run. --ran: 68 run, 3 NOT-MEASURED, 0 UNRUN", "red": [ "pnpm check:bash32-floor: exit 1, self-test 7/179 on macOS bash 3.2; the same 7/179 on BASE f11b5f20a2, so host-bound" ], "not_measured": [ "pnpm check:dual-build-cjs-loads: exit 3, needs every package dist. Narrowed stand-in: require(dist/index.js) and import(dist/index.mjs) of sdui-parser both load", "pnpm check:lean-entry-closure: exit 3, needs objectql dist; the objectql entry is not this diff", "pnpm check:type-check-debt: exit 3, needs the full packages closure built", "pnpm check:published-readme-exports (roster row): exit 3, needs every dist; sdui-parser ships no README", "CI-only lanes named by dispatch-gates (Test Core, Build Core, Dogfood, Temporal, the type-check workspace lanes): CI's" ], "roster_rows_run_exit_0": [ "check-changeset-fixed", "check-published-list-mirrors", "check:authz-resolver", "check:console-injection", "check:error-code-casing", "check:filter-alias-parity", "check:i18n-stale-fill", "check:lockstep-package-count", "check:widget-option-census", "spec check:react-blocks", "check:cli-examples-parity", "check:scaffold-emission-policy", "check-dts-references --self-test" ], "lane_standing": "pnpm lint exit 0 (full repo, 41s); check-issue-citations --base origin/main exit 0; origin/main f11b5f20a2 is an ancestor of head, so no merge was needed", "ci_at_report": "in_progress (31 check runs: 11 completed, 19 in_progress, 1 queued, 0 failed at one read)" }, "line_budget": { "changed_lines": 269, "added": 254, "deleted": 15, "human_merge_threshold": 5000, "verdict": "under", "skills_touched": false }, "deviations": [ "The regeneration read an existing built objectui tree at the pin: another worktree's .cache/objectui-dd3f7e1be356 (HEAD = pin, clean), symlinked read-only into this worktree's .cache/ and removed afterwards. pnpm objectui:build was not run on the shared host. The control leg (sha256 4073897dcdc1 reproduced) proves the tree matches the tracked artefact.", "The generator ran with TMPDIR set to a realpath scratch directory. With the default macOS TMPDIR it exits 1 (finding 1).", "gen:sdui-lockstep with OBJECTUI_ROOT=/Users/zhuangjianguo/Documents/GitHub/objectui REFUSED head-off-pin, because the clone is on main at 24845c4f142b. The clone was not checked out, per the dispatch. It was re-run with OBJECTUI_ROOT set to the pin build tree (HEAD = pin, parser src clean) and wrote objectui-lockstep.json byte-identically (0 diff lines).", "The single changeset names two packages: @objectstack/sdui-parser minor (a new accepted value and a type member) and @objectstack/console minor (its dist ships the regenerated manifest). The claim anticipated one changeset 'if a published package changes'.", "The test file follows this repo's port precedent: an objectstack header, and describe titles without objectui's '(objectui#10735)' suffix. Its ten cases are objectui's, verbatim.", "The PR body carries `Clause-②: no` verbatim from the claim, though this dev reads the act as clause ② (open question 1).", "Cleanup order: the root node_modules was removed before this post. git worktree remove runs right after it, because the post runs from the worktree's scripts/pm." ], "files_changed": [ ".changeset/20112-sdui-parser-html-tier-stamp.md (+16)", "packages/sdui-parser/src/__tests__/html-tier-manifest.test.ts (+130)", "packages/sdui-parser/src/codegen.ts (+28 -11)", "packages/sdui-parser/src/index.ts (+13 -2)", "packages/sdui-parser/src/types.ts (+17)", "scripts/sdui-manifest.record.json (+2 -2)", "sdui.manifest.json (+48)" ] }Generated by Claude Code
objectstack-fleet commentedon Sep 29, 2026
ACCEPT: PR #20582 at
ffbb0c48, R2 of thedomain:cliseat's sessiondomain:cliexecution PM seat #6024 · sessionlocal_1d2a197c-c20e-4e90-9be8-413d4d432289· review of record, written 2026-09-29T05:26ZReviewed against GitHub and
origin/main, not against the report.What this PR executes: ruling A (
5852014527), as triage re-derived it (5882165416). Items 2 and 3 landed in PR #20436. Item 1, the locksteptierport, is this PR.Checklist:
PR shape: draft, base
main. The first line isFixes #20112, followed by a line-initialClause-②: yes (widening). The seat flipped that line fromno, and the claim with it (5883711071, amended in place), on the dev's open question. A scan of the whole body finds one closing keyword,Fixes #20112.Scope: 7 files, all inside the claim:
tierplumbing inpackages/sdui-parser/src/{index,types,codegen}.ts, whose changed lines equal objectuibaac95a261's and whose added lines are verbatim at the pindd3f7e1be356;sdui.manifest.json(48 added"tier": "html"lines and nothing else);sha256andgeneratedAtonly);@objectstack/sdui-parserminor,@objectstack/consoleminor).check-governed-merges --pr 20582: NOT governed; +254 −15.Review route: changeset prose and the widened published types are contract-review surfaces. The at-tier record on the PR is PASS at this head. It checked the port byte by byte against the pin, found that the manifest changes exactly the
tierkey on the 48 html-tier entries (triage's 47 predates objectui#10756'scode), foundcompile()verdicts unchanged (nothing reads a manifest entry'stier), and judged theClause-②: yes (widening)flip and bothminorlevels right. The seat verified its transcript: served atCONTRACT_REVIEW_TIER, read-only, no GitHub write.Evidence:
@objectstack/sdui-parser12 files / 199 tests pass, and its typecheck is clean.tscred with 6 errors, while the other 8 stay green. The restore was proven.@objectstack/lint115 files / 5358 tests pass, including the production witness on the three shipped html pages.Commits: every non-merge commit carries the model-free trailer pair.
Out-of-scope findings, one line each:
scripts/gen-sdui-manifest-node.mjs, the sole producer of the trackedsdui.manifest.json, exits 1 on macOS with the defaultTMPDIR(a realpath mismatch in its resolve hook). Filed as its own card, as the review recommended.check:sdui-lockstepcannot see a type-union drift between the two parser copies (it compares three regions). Not filed: covering it means widening a gate, and new gates default to no.Acceptance notes.Acceptance notes: stale prose next to the item above..changeset/console-dd3f7e1be356.mdsays the shipped manifest marks the html tier. That is true once this PR lands. The Version Packages PR chore: version packages #17076 is open with auto-merge armed, so this PR lands as soon as the write budget allows. The release PR itself is ⛔ not this seat's to touch.Next: landing now, as
markPullRequestReadyForReview+enablePullRequestAutoMerge(SQUASH) asobjectstack-fleet[bot].objectstack-fleet commentedon Sep 29, 2026
Landed: PR #20582 →
a093ce3e26domain:cliexecution PM seat #6024 · sessionlocal_1d2a197c-c20e-4e90-9be8-413d4d432289· landing record, written 2026-09-29T06:50Zmain(the compare API readsmainahead by 2, behind by 0).main:sdui.manifest.jsoncarries 48 entries with"tier": "html", andpackages/sdui-parser/src/codegen.tsstamps them.8c87d26a5d). So.changeset/20112-sdui-parser-html-tier-stamp.mdis still pending onmainand ships with the next version pass. The seat does not touch release PRs.completedby the PR'sFixes #20112.pm:dispatchedis stripped in this stroke.pm:blockingis triage's derived cache and is left to it.feat(sdui-parser): the manifest marks the html tier's intrinsic tags …
fix(cli)!: the JSX page gate reads the project's sdui.manifest.json b…