Repository navigation
[finding] ADR-0082 D4 ratchet: react-blocks <ObjectForm> gains 17 registry-only props after objectui#4648/#4901 — spec has not caught up #9392
Description
Filed by the domain:spec execution seat while landing #9356 (the console pin bump past objectui#3951 / PR #4909).
What was found
Running pnpm sdui:manifest (the ADR-0082 D4 spec↔registry declaration-parity ratchet) at the new pin (82a94170c405) reports new declaration divergence against the accepted baseline (packages/spec/react-declaration-parity.baseline.json), on exactly one block:
⚠ <ObjectForm> (object-form): 16 declared by both, 7 spec-only, 17 registry-only
registry declares, spec does not: modalCloseButton, contentLayout, confirmOnDiscard,
customFields, initialData, readOnly, submitText, cancelText, nextText, prevText,
showSubmit, showCancel, showReset, successMessage, navigateOnSuccess, resetOnSuccess,
mobile
## Baseline ratchet
⚠ NEW declaration divergence vs accepted baseline:
- <ObjectForm>: new registry-only input(s) not in baseline: cancelText, confirmOnDiscard,
contentLayout, customFields, initialData, mobile, modalCloseButton, navigateOnSuccess,
nextText, prevText, readOnly, resetOnSuccess, showCancel, showReset, showSubmit,
submitText, successMessage
The baseline's prior entry for ObjectForm was "registryOnly": [] — this is a genuinely new gap, not a previously-known one growing.
Note this is the react-blocks parity channel (<ObjectForm>, the legacy component-prop check), not the SDUI object-* channel — the separate "SDUI object-* blocks" section in the same run reports object-form: ✓ 39 declared by both, 0 spec-only, 0 registry-only (clean). So the SDUI object-form block's spec schema is already caught up; only the react-blocks <ObjectForm> interface (in packages/spec/src/ui/react-blocks.ts) is behind.
Root cause, traced
objectui 375efb402 — "feat(plugins): publish the four GA object- blocks' authoring surfaces (objectui#4648) (objectui#4901)"* — added registry inputs declarations for keys the ObjectFormRenderer already implemented but never declared (its own changeset: "object-form +20 (record binding, button labels, post-submit behaviour, mobile overrides)"). It registers those inputs at both ComponentRegistry.register('object-form', …) (the SDUI channel, spec already matches) and ComponentRegistry.register('form', ObjectFormRenderer, …) (packages/plugin-form/src/index.tsx:159, the react-blocks channel spec has not been updated for).
Each of the 17 keys is documented in objectui's own registration with a description citing the renderer read site, e.g.:
modalCloseButton— "Show the modal presentation's close button. Read at ObjectForm.tsx:361 and honoured by ModalForm."confirmOnDiscard— "Ask before discarding unsaved edits when a drawer/modal form is dismissed."customFields— "Field definitions merged over the set generated from object metadata."initialData— "Alternate spelling ofinitialValuesthat the drawer/modal presentations read FIRST."- plus
contentLayout,readOnly,submitText,cancelText,nextText,prevText,showSubmit,showCancel,showReset,successMessage,navigateOnSuccess,resetOnSuccess,mobile.
Why this is filed rather than fixed in #9356
#9356 is a mechanical pin bump; its scope explicitly excludes any edit under packages/spec/src/**. The fix here — declaring these 17 keys on the react-blocks ObjectForm authorable interface in packages/spec/src/ui/react-blocks.ts (or ruling that some subset is deliberately NOT promoted to spec, the way objectui's own changeset names 10 object-grid legacy spellings it deliberately did NOT publish) — is exactly the judgment call AGENTS.md's declared=enforced doctrine wants a human/spec seat to make, not a pin-bump script to paper over via --update.
Suggested next step
Either:
- A. Declare the (subset of) these keys the maintainer wants authorable on
packages/spec/src/ui/react-blocks.ts'sObjectForminterface, matching objectui's already-published, already-implemented registry surface — each already has a description ready to adapt from objectui's registration; or - B. If any are deliberately NOT meant to become spec-authorable (e.g.
mobileas an internal-only override), rule that explicitly and runpnpm sdui:manifest -- --update(frompackages/spec) to re-accept the baseline with a recorded reason.
Not run in #9356: leaving packages/spec/react-declaration-parity.baseline.json untouched, so the ratchet still reports this divergence until a spec/overlay seat resolves it either way.
Refs: #9356 (the pin bump that surfaced this) · objectui#4648 / objectui#4901 (PR 375efb402, the source of the new registry declarations) · ADR-0082 D4 (the ratchet itself).
Activity
os-support-ai commentedon Aug 18, 2026
Triage: first-touch grading ⇒
needs-user-decision,domain:spec, type Task. The A/B choice is which of 17 registry-only<ObjectForm>props become spec-authorable — declaring any of them widens the authorable surface, and ruling any of them out needs a recorded baseline re-accept; both branches are contract-shape calls on the manual floor. The ratchet is honestly red until then (baseline deliberately untouched by #9356, per the card — the right shape).Four-facet card face:
object-gridprecedent the card cites) — declare-all adds 17 permanent obligations in one stroke.Recommendation: hybrid per facet 4 — declare the authoring-meaningful subset (button labels,
readOnly,confirmOnDiscard, post-submit behaviour), baseline-with-reason the internal/legacy spellings (initialDataas an alternate spelling,mobileif internal). The spec seat can pre-slice the 17 for the ruling. (Triage seat, sessionsession_019gCKd9EZfQ6MbGTnMHHJvW.)Generated by Claude Code
os-support-ai commentedon Aug 18, 2026
Maintainer ruling (2026-08-18, live PM chat with the triage seat, session
session_01EUZUjvnLsqwHVkXkTv8TKQ; verbatim: 「其他接受你的建议」, applying the triage recommendation delivered for this card).Ruled: the mixed disposition.
ObjectForminterface (14 keys):modalCloseButton,contentLayout,confirmOnDiscard,customFields,readOnly,submitText,cancelText,nextText,prevText,showSubmit,showCancel,showReset,successMessage,resetOnSuccess— adapting the descriptions objectui's own registrations already carry.initialData(an alias spelling ofinitialValues— aliases are not promoted into spec, per the alias-convergence direction),mobile(internal override, not an authoring surface), andnavigateOnSuccess(explicitly parked pending the "action success navigation" family ruling on feat(actions): api 型动作需要「成功后跳转到服务端返回的记录」能力(ActionSchema 跳转键 + 响应进入插值作用域) #9474/script actions can only redirect to a NEW TAB — the redirectUrl convention has no same-tab (SPA route) form #9566 and objectui#5034 — declaring it now risks freezing a spelling that family is about to shape; revisit whenonSuccesslands).Returned to
pm:queue, staysdomain:spec. Dispatch note for the spec seat: runpnpm sdui:manifest -- --updateonly for the three baselined keys with the reasons above; the 14 declarations clear the ratchet the honest way. Clause-② assessment at dispatch/ACCEPT per house rule (spec surface; declaring implemented-and-published keys is catch-up, but the seat applies the label loop as usual).Generated by Claude Code
feat(spec): declare 14 registry-published ObjectForm props on the rea…