Filed by the dev seat implementing objectui#7753's derivation gate. These are that gate's own first-run findings: it is landing with them in an exemption ledger (KNOWN_UNDECLARED_READS) because every fix is a packages/PKG/src change and #7753 is dispatched Clause-② no. This card owns the fixes; the ledger rows name it and drain as they land.
The exposure, restated
BaseSchema is .passthrough(). A key an arm does not declare is not refused — it stops being judged and the value is KEPT, then reaches the renderer that reads it. That is objectui#7664's measured mechanism ({ type: 'kanban', columns: [], onCardClick: { action: 'toast' } } went REFUSED to ACCEPTED with {"action":"toast"} surviving into the parsed output). objectui#7753's card calls this out for keys that LEAVE an arm; the 39 below are the other half of the same class — keys that were never on the arm at all, while a registered renderer reads them off the authored document.
Each is an authored onX: { action: 'toast' } that parses GREEN today and is then handed to a call site expecting a function. AlertDialogSchema.onAction was exactly this shape until objectui#7104 declared it, so this class has landed before.
Measured, per site
Census: every real ComponentRegistry.register('TYPE', C, ...) call in packages/PKG/src, the schema.onX / props.onX reads inside C and inside every component C hands THE SAME DOCUMENT to, judged against the arm whose type: z.literal('TYPE') selects it. Population derived on both halves; nothing here is a hand-written list. 106 arms, 216 registrations (120 with an arm), 62 reachable reads, 39 of them undeclared.
Reproduce with node scripts/check-handler-key-read-sites.mjs --list once objectui#7753's PR lands.
packages/components
button::ButtonSchema.onSuccess — read at packages/components/src/renderers/action/action-button.tsx:219; arm in form.zod.ts
icon::IconSchema.onSuccess — read at packages/components/src/renderers/action/action-icon.tsx:145; arm in layout.zod.ts
data-table::DataTableSchema.onAddRecord — packages/components/src/renderers/complex/data-table.tsx:2606; data-display.zod.ts
data-table::DataTableSchema.onBatchSave — data-table.tsx:1724
data-table::DataTableSchema.onCellChange — data-table.tsx:1572
data-table::DataTableSchema.onColumnResize — data-table.tsx:1466
data-table::DataTableSchema.onRowActionDef — data-table.tsx:501
data-table::DataTableSchema.onRowClick — data-table.tsx:2184
data-table::DataTableSchema.onRowSave — data-table.tsx:1664
tree-view::TreeViewSchema.onNodeClick — packages/components/src/renderers/data-display/tree-view.tsx:98; data-display.zod.ts
packages/plugin-detail
detail::DetailSchema.onAddComment — packages/plugin-detail/src/DetailView.tsx:1522; crud.zod.ts
detail::DetailSchema.onNavigate — DetailView.tsx:635
packages/plugin-form
Both 'object-form' and 'form' register ObjectFormRenderer, so the same reads land on two arms.
object-form::ObjectFormSchema.onCancel / .onError / .onOpenChange / .onStepChange / .onSuccess — packages/plugin-form/src/ObjectForm.tsx:260, 259, 424, 359, 258; objectql.zod.ts
form::FormSchema.onError / .onOpenChange / .onStepChange / .onSuccess — same lines; form.zod.ts (FormSchema declares onSubmit, onChange, onCancel only)
packages/plugin-grid
object-grid::ObjectGridSchema.onNavigate — packages/plugin-grid/src/ObjectGrid.tsx:2053; objectql.zod.ts
grid::GridSchema.onNavigate — same read site; layout.zod.ts
packages/plugin-kanban
'object-kanban' registers the same ObjectKanbanRenderer as 'kanban', and ObjectKanbanSchema declares no handler key at all — so the three keys objectui#7664 ledgered on the 'kanban' arm are unledgered and undeclared on its sibling key.
object-kanban::ObjectKanbanSchema.onCardClick / .onCardMove / .onQuickAdd — packages/plugin-kanban/src/index.tsx:194, 193, 197; objectql.zod.ts
packages/plugin-list
Both 'list-view' and 'list' register ListViewRenderer.
list-view::ListViewSchema.onAddRecord / .onBulkAction / .onDensityChange / .onNavigate / .onPageSizeChange — packages/plugin-list/src/ListView.tsx:3816, 4075, 1354, 2210, 4158; objectql.zod.ts
list::ListSchema.onAddRecord / .onBulkAction / .onDensityChange / .onNavigate / .onPageSizeChange — same lines; data-display.zod.ts
object-gallery::ObjectGallerySchema.onCardClick / .onRowClick — packages/plugin-list/src/ObjectGallery.tsx:228; objectql.zod.ts
packages/plugin-view
object-view::ObjectViewSchema.onNavigate — packages/plugin-view/src/ObjectView.tsx:966; objectql.zod.ts
What a fix looks like, and what is NOT decided here
Per key, the objectui#6124 disposition has to be MEASURED, not assumed — handlerKeyRefusal(key, 'runtime-slot', ...) where the value reaches the renderer, 'retired' where it does not, and the #6124 ledger updated alongside. Two questions this card does not settle:
'list' and 'grid' and 'form'. A plugin registers each of those base types to its own object-backed renderer, so a read lands on an arm minted for a different component (ListSchema is data-display.zod.ts's simple list). Whether the fix is to declare the keys on those arms or to stop claiming the type is a ruling, not a mechanical edit.
- Batching. These are nine packages. Splitting per package is probably right; the ledger drains row by row either way.
Refs: objectui#7753 (the gate) · objectui#6124 (the ruling that minted the ledger) · objectui#7664 / PR #7743 (the instance) · objectui#7104 (the last time a renderer was found reading an UNDECLARED key).
Filed by the dev seat implementing objectui#7753's derivation gate. These are that gate's own first-run findings: it is landing with them in an exemption ledger (
KNOWN_UNDECLARED_READS) because every fix is apackages/PKG/srcchange and #7753 is dispatched Clause-②no. This card owns the fixes; the ledger rows name it and drain as they land.The exposure, restated
BaseSchemais.passthrough(). A key an arm does not declare is not refused — it stops being judged and the value is KEPT, then reaches the renderer that reads it. That is objectui#7664's measured mechanism ({ type: 'kanban', columns: [], onCardClick: { action: 'toast' } }went REFUSED to ACCEPTED with{"action":"toast"}surviving into the parsed output). objectui#7753's card calls this out for keys that LEAVE an arm; the 39 below are the other half of the same class — keys that were never on the arm at all, while a registered renderer reads them off the authored document.Each is an authored
onX: { action: 'toast' }that parses GREEN today and is then handed to a call site expecting a function.AlertDialogSchema.onActionwas exactly this shape until objectui#7104 declared it, so this class has landed before.Measured, per site
Census: every real
ComponentRegistry.register('TYPE', C, ...)call inpackages/PKG/src, theschema.onX/props.onXreads insideCand inside every componentChands THE SAME DOCUMENT to, judged against the arm whosetype: z.literal('TYPE')selects it. Population derived on both halves; nothing here is a hand-written list. 106 arms, 216 registrations (120 with an arm), 62 reachable reads, 39 of them undeclared.Reproduce with
node scripts/check-handler-key-read-sites.mjs --listonce objectui#7753's PR lands.packages/components
button::ButtonSchema.onSuccess— read atpackages/components/src/renderers/action/action-button.tsx:219; arm inform.zod.tsicon::IconSchema.onSuccess— read atpackages/components/src/renderers/action/action-icon.tsx:145; arm inlayout.zod.tsdata-table::DataTableSchema.onAddRecord—packages/components/src/renderers/complex/data-table.tsx:2606;data-display.zod.tsdata-table::DataTableSchema.onBatchSave—data-table.tsx:1724data-table::DataTableSchema.onCellChange—data-table.tsx:1572data-table::DataTableSchema.onColumnResize—data-table.tsx:1466data-table::DataTableSchema.onRowActionDef—data-table.tsx:501data-table::DataTableSchema.onRowClick—data-table.tsx:2184data-table::DataTableSchema.onRowSave—data-table.tsx:1664tree-view::TreeViewSchema.onNodeClick—packages/components/src/renderers/data-display/tree-view.tsx:98;data-display.zod.tspackages/plugin-detail
detail::DetailSchema.onAddComment—packages/plugin-detail/src/DetailView.tsx:1522;crud.zod.tsdetail::DetailSchema.onNavigate—DetailView.tsx:635packages/plugin-form
Both
'object-form'and'form'registerObjectFormRenderer, so the same reads land on two arms.object-form::ObjectFormSchema.onCancel/.onError/.onOpenChange/.onStepChange/.onSuccess—packages/plugin-form/src/ObjectForm.tsx:260, 259, 424, 359, 258;objectql.zod.tsform::FormSchema.onError/.onOpenChange/.onStepChange/.onSuccess— same lines;form.zod.ts(FormSchemadeclaresonSubmit,onChange,onCancelonly)packages/plugin-grid
object-grid::ObjectGridSchema.onNavigate—packages/plugin-grid/src/ObjectGrid.tsx:2053;objectql.zod.tsgrid::GridSchema.onNavigate— same read site;layout.zod.tspackages/plugin-kanban
'object-kanban'registers the sameObjectKanbanRendereras'kanban', andObjectKanbanSchemadeclares no handler key at all — so the three keys objectui#7664 ledgered on the'kanban'arm are unledgered and undeclared on its sibling key.object-kanban::ObjectKanbanSchema.onCardClick/.onCardMove/.onQuickAdd—packages/plugin-kanban/src/index.tsx:194, 193, 197;objectql.zod.tspackages/plugin-list
Both
'list-view'and'list'registerListViewRenderer.list-view::ListViewSchema.onAddRecord/.onBulkAction/.onDensityChange/.onNavigate/.onPageSizeChange—packages/plugin-list/src/ListView.tsx:3816, 4075, 1354, 2210, 4158;objectql.zod.tslist::ListSchema.onAddRecord/.onBulkAction/.onDensityChange/.onNavigate/.onPageSizeChange— same lines;data-display.zod.tsobject-gallery::ObjectGallerySchema.onCardClick/.onRowClick—packages/plugin-list/src/ObjectGallery.tsx:228;objectql.zod.tspackages/plugin-view
object-view::ObjectViewSchema.onNavigate—packages/plugin-view/src/ObjectView.tsx:966;objectql.zod.tsWhat a fix looks like, and what is NOT decided here
Per key, the objectui#6124 disposition has to be MEASURED, not assumed —
handlerKeyRefusal(key, 'runtime-slot', ...)where the value reaches the renderer,'retired'where it does not, and the #6124 ledger updated alongside. Two questions this card does not settle:'list'and'grid'and'form'. A plugin registers each of those base types to its own object-backed renderer, so a read lands on an arm minted for a different component (ListSchemaisdata-display.zod.ts's simple list). Whether the fix is to declare the keys on those arms or to stop claiming the type is a ruling, not a mechanical edit.Refs: objectui#7753 (the gate) · objectui#6124 (the ruling that minted the ledger) · objectui#7664 / PR #7743 (the instance) · objectui#7104 (the last time a renderer was found reading an UNDECLARED key).