Skip to content

finding(types): 39 handler keys a registered renderer READS are declared by no arm — accepted and KEPT by the passthrough, on main today #7804

Description

@os-sam

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.onAddRecordpackages/components/src/renderers/complex/data-table.tsx:2606; data-display.zod.ts
  • data-table::DataTableSchema.onBatchSavedata-table.tsx:1724
  • data-table::DataTableSchema.onCellChangedata-table.tsx:1572
  • data-table::DataTableSchema.onColumnResizedata-table.tsx:1466
  • data-table::DataTableSchema.onRowActionDefdata-table.tsx:501
  • data-table::DataTableSchema.onRowClickdata-table.tsx:2184
  • data-table::DataTableSchema.onRowSavedata-table.tsx:1664
  • tree-view::TreeViewSchema.onNodeClickpackages/components/src/renderers/data-display/tree-view.tsx:98; data-display.zod.ts

packages/plugin-detail

  • detail::DetailSchema.onAddCommentpackages/plugin-detail/src/DetailView.tsx:1522; crud.zod.ts
  • detail::DetailSchema.onNavigateDetailView.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 / .onSuccesspackages/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.onNavigatepackages/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 / .onQuickAddpackages/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 / .onPageSizeChangepackages/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 / .onRowClickpackages/plugin-list/src/ObjectGallery.tsx:228; objectql.zod.ts

packages/plugin-view

  • object-view::ObjectViewSchema.onNavigatepackages/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:

  1. '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.
  2. 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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions