feat(types): the six held public blocks (action:* and element:definition-list / repeater) validate by their spec ComponentPropsMap rows (objectui#10872, batch 4) - #11180
Conversation
…entPropsMap rows (objectui#10872, batch 4) action:button, action:icon, action:group, action:menu, element:definition-list and element:repeater each get an arm whose `properties` bag is the block's @objectstack/spec 17.5.0 ComponentPropsMap row, by reference. action:button and action:icon also declare the two on* keys their renderers read off the node: `onClick` as a runtime slot, and a flat `onSuccess` refused with a pointer to `properties.onSuccess`. The namespaced ratchet falls 397 -> 391; the handler-key census judges the action reads on their own arms; the import-boundary differential measures the six rows. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
|
changeset-claim-re-read
|
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
…blic-block arms (objectui#10872, batch 4) Six EXCLUSIONS rows, inserted immediately before the PublicBlockComponentSchema entry: each arm is BaseSchema + its type literal + `properties`, which is the block's ComponentPropsMap row by reference, so no TS declaration in this package restates the node. action:button and action:icon also name their onClick runtime slot and flat-onSuccess alias refusal. Nothing else in the file moves. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: PR objectui#11180, card objectui#10872, batch 4 ( Check-runs on the head ( ① Derived judgmentsFindings (the FAIL):
Judged right, each named:
② Semver level
③ Boundary flagsBatch-4 report
Implemented-by: VERDICT: FAIL Generated by Claude Code |
…ick-start readers (objectui#10872, batch 4) The batch-4 taught-node pins read the quick-start's "Add Actions" json fence: the ratchet test's QUICK_START path and held-public-block-arms-10872's taughtActionButton(). The ratchet file's existing entry gains content/docs/guide/quick-start.md in `reads`; the held-arms test gets its own entry with the same read. Answers contract review 5906210193, finding 1. Claude-Session: https://claude.ai/code/session_011p7ikEivgXefNDaE5S5Uec Co-authored-by: Claude <noreply@anthropic.com>
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contract reviewServed-tier: Round 2 on PR objectui#11180, card objectui#10872, batch 4 ( The delta since round 1. Check-runs on the head ( ① Derived judgments
② Semver levelRe-cited from ③ Boundary flagsPatch-round report
Implemented-by: VERDICT: PASS Generated by Claude Code |
Part of #10872
Clause-②: yes (widening: six namespaced component types move from refused-at-type to accepted by their spec rows)
Batch 4 of objectui#10872. The six ADR-0080 public blocks held back until
@objectstack/speccarried aComponentPropsMaprow for each (action:button,action:icon,action:group,action:menu,element:definition-list,element:repeater) are armed by reference to their 17.5.0 rows, the batch-1 method. The card stays open forrecord:line_items(no spec row yet) and the flat-props / envelope-key batch.packages/types/src/__tests__/zod-mirror-parity.test.tscensus (every exported const in ../zod/ is either a registered pair or an excluded one) names exactly the six new exports. The claim puts that file off limits (draft PRs objectui#11115 and objectui#11125 hold it) and says to stop and report the shape, so the six rows are not in this diff. They are in the os-dev report on the card. Measured: with those six rows added, the census passes (37/37, in a scratch copy of the test), andgit merge-fileof the rows against the heads of objectui#11115 (8628df2fd9) and objectui#11125 (a5884b4030) reports 0 conflicts.What changed
packages/types/src/zod/public-blocks.zod.ts: six arms,BaseSchema+ thetypeliteral +properties, which is the block'sComponentPropsMaprow passed straight throughstripImportedDefaults(no member restated). All six joinPublicBlockComponentSchema; the barrel re-exports them.action:button/action:iconalso declare the twoon*keys their renderers read off the node, becausecheck:handler-key-readsrequires every such read to be an arm member:onClick:handlerKeyRefusal(..., 'runtime-slot', ...). The renderer calls it only when it is a function (a code-composed schema), and the row does not declare it. This is theButtonSchema.onClickprecedent.onSuccess:aliasKeyRefusalnamingproperties.onSuccess, where the row declares the post-success{ navigate, openIn }block. This is therecord:alertflat-bodyprecedent (batch 3). The spec's ownPageComponentSchemarefuses the flat key too, as mis-layered.NAMESPACED_REFUSED_AT_TYPEfalls 397 to 391, andARMED_PUBLIC_BLOCKS_10872_BATCH_4names the six. The ratchet's validator import andrefusedAtType(objectui#11069's hunks) are untouched.objectui validatepasses a page whoseaction:buttonis the quick-start's "Add Actions" node, read fromcontent/docs/guide/quick-start.md(the node AGENTS.md Add default props to all components to prevent collapse in designer #4 teaches). It also passes a page of all six in the spec'spropertiesspelling. The control is an undeclared bag prop, which is refused and named.imported-defaults-8317.test.tsmeasures the six rows at the import boundary. They are placed away from objectui#11115's insertion point, and none carries a default or az.lazy, so the lazy count stays 4.public-block-arms-10872.test.tsgetsVALID_BAGrows for the six. Its identity leg now compares by definition, because 17.5.0 publishes these rows as lazy proxies whose methods run on the real schema, so.optional()wraps the object behind the proxy.action:buttonandaction:iconleave the objectui#9573 alias population, which is nowview:form,view:grid,view:list. Their four reads are judged on their own arms. Both the gate docblock and the gate test are amended.10872-held-public-block-arms.md('@object-ui/types': minor). A dated note on the pending10872-public-block-zod-arms.md, whose "Not armed in this release" bullet this falsifies. The zod README lists the six.The spec round's registration notes, re-measured at
main0ffc423b1The arm follows the row, and the row follows the read points. Items 1–3 and 5 are pinned at the validator in
held-public-block-arms-10872.test.ts; item 4 is a renderer reading.action:grouppublishesname, which is read nowhere. Itssizeenum carriesmd, which inline mode hands raw to the primitive. Still true. The arm refuses both, with the row's prescription.element:definition-listpublishescolumnsas the strings'1'/'2', and the renderer compares the number2. Still true. The arm refuses'2'and accepts2.element:repeateradvertisesfields[].label(its TS interface and its registration description), which is never rendered. Still true. The arm refuses it.action:menuspreads...restafterdisabled={loading}. Reproduced with a probe through the realSchemaRendererand registry: an in-flight action (anautoTriggermember whose handler never settles) shows the spinner on both mount channels, but the trigger isdisabled: trueonly on a direct registry mount anddisabled: falsethroughSchemaRenderer, whose forwardeddisabled: undefinedwins. It is reported on the card as a class-(a) finding; it is not fixed here.objectName: the 17.5.0 rows declare it onaction:buttonandaction:icon. Onaction:group/action:menuit rides each member (actions[]members are open records) and is refused at container level. Pinned.The registrations did not move in this PR. Items 1–3 sit in
apps/console/src/__tests__/registry-inputs-spec-parity.test.ts's objectui#11111 ledger, which the maintainer's decision 3 = B routes to objectui#11168 ("nothing else may own an entry"). objectui#11168's slice 1 (theaction:*family, includingrenderers/action/) was claimed at 2026-09-30T05:39Z, before this card's claim. So the registration moves, and the item-4 renderer fix, would duplicate in-flight work. They are reported on the card instead. This PR does not touchregistry-inputs-spec-parity.test.tsor any renderer.Tests and gates (all after the final commit,
c1ea153ad)pnpm exec vitest run packages/types/ packages/cli/src/__tests__/ packages/components/src/renderers/action/ packages/components/src/renderers/basic/ apps/console/src/__tests__/registry-inputs-spec-parity.test.ts: 351 files, 7678 passed, 1 failed. The failure is the zod-mirror-parity census above, and nothing else.block-config-schema-parity-8216,block-config,definition-list-item-keys-8279andPageBlockInspector.retiredBlockProps;examples/schema-catalog/test/;public-contract,html-tier-manifest,component-input-union-specimensandunfulfilled-chart-stubs-8760;metricCardRegisteredInputsStrictFace-11022and plugin-mapbareMapKeyRetired-10393;check-handler-key-read-sites: 5 files, 132 passed.type-checkfor@object-ui/types(three programs;tsconfig.test.jsonlists the three changed test files) and@object-ui/cli, afterpnpm --filter '@object-ui/cli^...' build: exit 0.@object-ui/componentsis not in the diff.--format json).eslint.config.jsconfigures no type-aware parsing, so this diff cannot move a verdict on an untouched file.check-changeset-presence,check:control-bytes,check:new-line-citations(0 new),check:spec-symbols,check:handler-key-reads,check:changeset-claims(report-only),check:pending-changeset-literals,check-changeset-no-major.check:readme-exports. Reason: it needs every package'sdistand reported "the population COLLAPSED" on this unbuilt tree. CI runs it.ablation-replace.mjs: the anchor hit once, the write was verified on disk, and the restore was proven (blob equals HEAD,git diff HEADempty).action:button'sonClick/onSuccessmembers:check:handler-key-readsexits 1 naming both reads, and 2 held-arm tests go red.Overlap
git merge-treeof this head with objectui#11069, #11115 and #11125: my files merge cleanly with all three. objectui#11069 conflicts inpackages/cli/src/commands/check.ts, a file this PR does not touch; the same conflict appears against the base alone.Acceptance notes
action:buttonnode is flat, and the strict face refuses it. AGENTS.md Add default props to all components to prevent collapse in designer #4, the quick-start, the layout guide and the other guides writelabel/actionType/targeton the node. The tolerant faceobjectui validateruns today passes that node (which is what the page pin reads).StrictAnyComponentSchemarefuses exactlyactionTypeandtarget, asPageComponentSchemadoes, and this is pinned as a reading. objectui#11069 movesobjectui validateonto the strict face. When it next mergesmain, this PR's taught-node page pin turns red there. That is the flat-props question foraction:*, which this card holds, and it is raised on the card.children/bodyrefusal: that measurement never covered them. They keepBaseSchema's channels, and the module docblock and README say so.action:groupalso spreads...restonto its wrapping div. This is the item-4 shape on a div.Generated by Claude Code