Repository navigation
[finding] the sdui-parser lockstep has drifted again since the record was taken: objectui carries 26 diagnostic codes, this copy 24 — inert-quick-add and member-type-mismatch exist only on the renderer side #17645
Description
os-decision-facets
① 项目长远合理性:不变量写的是「两份拷贝在诊断码上逐字节一致」;补齐缩小特例(恢复不变量),声明允许的不对称则是契约增生 —— 每多一个被声明的例外都是永久义务。⇒ 指向补齐。
② 实际业务拉动:今天零人撞上 —— 门禁现在是绿的(实测 exit 0,24 码,pin 53ded82bf7a4 自立卡起 5 天未动)。活着的危害是「渲染器能发出保存闸门永不发出的诊断」,真实但无已报事故;痛点要到下次 pin bump 才落到某个不相干的 PR 头上。⇒ 零拉动,默认 defer 或 remove。
③ 防 AI 犯错:两份拷贝静默地不一致,正是「静默容忍」;闭合枚举与响亮拒绝要求二者选一 —— 要么两侧都拒绝(补齐),要么把例外显式登记进记录与检查器。⇒ 反对「什么都不做且不记录」。
④ 创业阶段不扩散:声明一条「允许的不对称」是 declare-and-maintain;补齐是 remove 掉分歧本身。⇒ 指向补齐。
Prior rulings read: sdui-lockstep,diagnostic code,objectui port,lockstep drift → 0 hits; none
推荐:A。 自检「只看①选 A;②③④ 是否翻转:③④ 同向 A,只有 ② 反向」——② 会翻转结论,当且仅当那两个码确实是渲染器专属的。而那正是本席从这个容器里答不出的事实问题。
- A — 两个码都补齐到本仓
packages/sdui-parser,恢复逐字节一致。 - B — 只补
member-type-mismatch;把inert-quick-add判为渲染器专属,并把这条不对称显式登记进记录与检查器。 - C — 两个都不补,把二者都判为渲染器专属并显式登记。
- D — 推迟到下次 pin bump 被迫面对。
⚠️ 代价已被本卡测出:届时红的是一个与此毫无关系的 bump PR,而成因已六天。
置信缺口:objectui 未在本容器检出。 本席只复算了本仓一侧(7 源文件 / 24 码,与卡一致,tree 8fe5cb8e5,2026-09-16T14:1xZ);对侧的 26 码、多出的 kanban-quick-add.ts、以及 inert-quick-add 到底守着什么,⛔ 全部 UNAUDITED,只能引立卡席的读数。⇒ ②③ 两棱的事实底座本席够不到。
Surfaced while porting objectstack#13957 into objectui (objectui#7235, objectui PR for branch claude/issue-7235-html-tier-discriminator-attr). Filed rather than folded in: that port is objectui-only and adds zero diagnostic codes; this is a pre-existing divergence it merely made visible.
The contract
objectstack#12719 states the invariant scripts/check-sdui-lockstep.mjs mechanises, quoted from the checker's own header:
both copies byte-agree on the accepted grammar and on diagnostic codes.
The measurement
Taken with this repo's own extractor (fingerprintOf from scripts/check-sdui-lockstep.mjs), run against three trees — no hand-rolled parallel implementation:
| tree | source files | diagnostic codes |
|---|---|---|
| objectstack (this copy, today) | 7 | 24 |
objectui at the pinned rev 53ded82bf7a4 |
7 | 24 |
objectui origin/main 567f3701 (today) |
8 | 26 |
- present in objectui, absent here:
inert-quick-add,member-type-mismatch - present here, absent in objectui: none — the drift is one-directional
- the extra objectui source file is
packages/sdui-parser/src/kanban-quick-add.ts
The two codes trace to objectui#8285 (kanban Quick Add reported rather than dropped) and objectui#8067 (member-kind unions). Both landed in objectui after 2026-09-05, which is the date the vendored record was taken — so both are inside the blind spot the checker's own header names:
CANNOT see objectui moving AFTER the record was taken. That direction needs objectui at check time, which is the shape this repo declined.
Why this is a finding and not noise
- The gate is green today and will red at the next pin bump.
pnpm check:sdui-locksteppasses right now (measured: self-test exit 0, gate exit 0, "agrees on all 24 diagnostic code(s)"). It compares THIS tree against the record, and the record still describes the 24-code objectui of 2026-09-05. The moment.objectui-shamoves andpnpm gen:sdui-lockstepre-records, the record gains two codes this copy does not have, and the gate reds — naming a divergence whose cause is six days old and nothing to do with whichever PR happens to be bumping the pin. - The harm the invariant exists to stop is live in the meantime. A renderer that can emit a diagnostic the save gate never emits is the dialect split objectstack#12719 describes, in the direction where the save gate is the more permissive of the two.
- The pattern already has two closed precedents — objectstack#12719 (
inert-expression) and objectstack#12814 (union-armtype-mismatch) — each a code that landed in objectui first and was ported here afterwards. This is the third instance, so it is a recurrence of a known class rather than a novel one.
What is NOT claimed here
- ⛔ This is not a claim that the two codes should be ported as-is.
inert-quick-addconcerns a control gated on a runtime slot no parsed page can write, which may be a genuinely renderer-only concern; that judgement is the porting decision, not this card's. - ⛔ It is not a claim that the pinned record is wrong. The record correctly describes objectui at
53ded82bf7a4. - The two-code gap and the one-file gap are measured; whether either is deliberate is not.
Reproduction (zero network, zero build beyond an install)
node -e "import('./scripts/check-sdui-lockstep.mjs').then(m=>console.log(m.fingerprintOf('.').codes.length))"
…then the same fingerprintOf against a materialised objectui origin/main packages/sdui-parser/src tree. Both numbers above came out of exactly that, in one container, minutes apart. The control that keeps the difference from being an artefact of the extractor pre-exists the reading: the SAME extractor, on the SAME objectui repo, at the PINNED revision, returns 24 and the matching file list — so it is demonstrably sensitive to the class of drift being reported, and the 26 is not a quirk of how it was invoked.
Raised by an ObjectStack development agent working objectui#7235; the objectui-side port itself is unaffected and adds no code to either set (its before/after fingerprints are byte-identical).
Generated by Claude Code
Activity