diff --git a/.changeset/23434-sha-less-read-points.md b/.changeset/23434-sha-less-read-points.md new file mode 100644 index 00000000000..1d3a4e379e3 --- /dev/null +++ b/.changeset/23434-sha-less-read-points.md @@ -0,0 +1,13 @@ +--- +'@objectstack/spec': patch +--- + +The sha-less objectui `File.tsx:NNN` read points that have a liveness row leave the published spec source and move into that row. Two live citations with no ledger row stay in `packages/spec/src`, named under "Unchanged on purpose" below. + +Clause-②: no + +- **Sha-less line citations.** Ten live read-point records named an objectui file by line, with no SHA. Each moves into the note of its liveness row as `objectui @SHA FILE#SYMBOL`, re-read at objectui `b9814b334`, and the source comment now names the row: `data/field.zod.ts` (`field.json`, rows `step` and `dimensions`), `ui/action.zod.ts` and `system/translation.zod.ts` (`action.json`, row `description`), `ui/bulk-action.zod.ts` (`view.json`, row `list.bulkActionDefs`), `ui/view.zod.ts` (`view.json`, rows `list.filter`, `list.sort` and `list.userFilters`) and `ui/i18n-label-resolver.ts` (`page.json`, row `regions`). +- **Two stale renderer claims are no longer stated.** For an action bound to an object, the console's description resolver no longer falls back from `objects.{object}._actions.{action}.description` to `globalActions.{action}.description`. objectui's bulk-param option type is no longer closed. The comments in `ui/action.zod.ts`, `system/translation.zod.ts` and `ui/bulk-action.zod.ts` said both. They now state only the contract, and the ledger records the current reading. +- **`liveness/view.json`, row `list.exportOptions`** names its reader by symbol instead of by line. +- **Unchanged on purpose.** Retirement history stays where it is: the `areas[].order` record in `ui/app.zod.ts` and the `widgets[].aria` record in `ui/dashboard.zod.ts`. Two citations with no ledger row also stay: the build-progress phase reading in `ai/build-progress.zod.ts`, and the "pin this view" trace on `ViewItemSchema` in `ui/view.zod.ts`. +- No schema, type, export, default, accept or refuse change. No `.describe()` text changed. diff --git a/packages/spec/liveness/action.json b/packages/spec/liveness/action.json index b9f265a2934..bc31102c686 100644 --- a/packages/spec/liveness/action.json +++ b/packages/spec/liveness/action.json @@ -13,8 +13,8 @@ "description": { "status": "live", "verifiedAt": "2026-08-10", - "evidence": "objectui @5e52495 packages/app-shell/src/views/ActionParamDialog.tsx:215 renders it as the dialog's DialogDescription; objectui @5e52495 packages/app-shell/src/hooks/useConsoleActionRuntime.tsx:206 and objectui packages/app-shell/src/views/RecordDetailView.tsx:586 both feed it as `description: actionDescription(objForI18n, action?.name, action?.description)`; objectui packages/i18n/src/useObjectLabel.ts:463 resolves objects.{o}._actions.{a}.description then globalActions.{a}.description then this literal; framework: packages/cli/src/utils/i18n-extract.ts emits the key and packages/spec/src/system/translation.zod.ts declares the translation slot.", - "note": "Added #7367 — the RENDERER half predates the key by design: the consumer chain above shipped while `ActionSchema` (strictObject) refused `description`, so no producer could reach it (the mirror image of declared-but-unenforced). Live from the moment this key exists: the dialog reads `action.description` directly, no second input required. Mechanism for the 2026-08-10 ruling on #7278 — an action with `params` carries its confirm question here instead of in `confirmText`, so one decision is one dialog." + "evidence": "objectui @b9814b334 packages/app-shell/src/views/ActionParamDialog.tsx#ActionParamDialog renders it as the dialog's DialogDescription, falling back to the generic `actionDialog.description` string; objectui @b9814b334 packages/app-shell/src/hooks/useConsoleActionRuntime.tsx#paramCollectionHandler and objectui @b9814b334 packages/app-shell/src/views/RecordDetailView.tsx#paramCollectionHandler both feed it as `actionDescription(objForI18n, action?.name, action?.description)`; objectui @b9814b334 packages/i18n/src/useObjectLabel.ts#actionDescription resolves it through objectui @b9814b334 packages/i18n/src/useObjectLabel.ts#actionSuffixes, reading objects.{o}._actions.{a}.description for an action with a key object or globalActions.{a}.description for one without, never both, then this literal; framework: packages/cli/src/utils/i18n-extract.ts emits the key and packages/spec/src/system/translation.zod.ts declares the translation slot.", + "note": "Added #7367 — the RENDERER half predates the key by design: the consumer chain above shipped while `ActionSchema` (strictObject) refused `description`, so no producer could reach it (the mirror image of declared-but-unenforced). Live from the moment this key exists: the dialog reads `action.description` directly, no second input required. Mechanism for the 2026-08-10 ruling on #7278 — an action with `params` carries its confirm question here instead of in `confirmText`, so one decision is one dialog. Moved out of spec source, #23434: packages/spec/src/ui/action.zod.ts (this key's docblock) and packages/spec/src/system/translation.zod.ts (the translation slot's comment) cited this chain by line, sha-less. Re-read at objectui @b9814b334 on 2026-10-15: the object-then-global fallback both described, and this entry's evidence with them, is gone — objectui#11439 retired it, so the client resolves one bundle entry the way packages/spec/src/system/i18n-resolver.ts#actionTranslationNode does." }, "objectName": { "status": "live", diff --git a/packages/spec/liveness/field.json b/packages/spec/liveness/field.json index 1a13c967199..0d4853e13c3 100644 --- a/packages/spec/liveness/field.json +++ b/packages/spec/liveness/field.json @@ -192,7 +192,7 @@ "step": { "status": "live", "verifiedAt": "2026-08-08", - "note": "CAVEAT — RENDERER-only: objectui SliderField.tsx:14 reads `field.step ?? 1`; the write path never validates the grid (record-validator.ts's numeric branch enforces min/max for slider and reads step nowhere). Ruled UI-only and deliberately unenforced 2026-08-08 (#6514) — see docs/audits/2026-06-dead-surface-disposition-plan.md (P2 field) and the comment beside the declaration in src/data/field.zod.ts." + "note": "CAVEAT — RENDERER-only: objectui @b9814b334 packages/fields/src/widgets/SliderField.tsx#SliderField reads `sliderField?.step ?? 1` and hands it to the Slider (re-read 2026-10-15; first cited by line, sha-less, here and in packages/spec/src/data/field.zod.ts beside the declaration — moved out of spec source, #23434); the write path never validates the grid (record-validator.ts's numeric branch enforces min/max for slider and reads step nowhere). Ruled UI-only and deliberately unenforced 2026-08-08 (#6514) — see docs/audits/2026-06-dead-surface-disposition-plan.md (P2 field) and the comment beside the declaration in src/data/field.zod.ts." }, "group": { "status": "live", @@ -329,7 +329,7 @@ }, "dimensions": { "status": "live", - "note": "vector field — objectui VectorField.tsx:11 reads the flat `dimensions` prop. The live authoring path; `Field.vector(n)` emits this. (The dead nested `vectorConfig` block was removed in 16.0, #2377.)" + "note": "vector field — objectui @b9814b334 packages/fields/src/widgets/VectorField.tsx#VectorField reads the flat `dimensions` prop (`vectorField?.dimensions`, the value's length when unset; re-read 2026-10-15; first cited by line, sha-less, here and in packages/spec/src/data/field.zod.ts beside the declaration — moved out of spec source, #23434). The live authoring path; `Field.vector(n)` emits this. (The dead nested `vectorConfig` block was removed in 16.0, #2377.)" }, "inlineTitle": { "status": "live", diff --git a/packages/spec/liveness/page.json b/packages/spec/liveness/page.json index 955126178f1..87d769021cb 100644 --- a/packages/spec/liveness/page.json +++ b/packages/spec/liveness/page.json @@ -54,7 +54,7 @@ "verifiedAt": "2026-08-10", "evidenceScope": "cross-repo", "evidence": "objectui: packages/components/src/renderers/layout/page.tsx:290 branches on schema.regions, :197-204 resolves the named slots (header/sidebar/main/aside/footer) and appends the remainder below main at :211, and :157 flattens their components for the JSX-source path — measured objectui @11c1e71e", - "note": "region → component tree rendering (header/main/sidebar/footer). RE-CITED 2026-08-10 (#7133/#7142): same split-citation pruning as `template` — at objectui @11c1e71e the containers.tsx half names `regions` only in a comment (:798, 'page:section — thin wrapper used inside regions'). Verdict unchanged: LIVE. Component-level liveness stays unclassified (undrilled container, #4956); one component key carries a verdict OUTSIDE this file: `components[].responsive` is a retiredKey tombstone (#11027, ADR-0049 D2 — dead on a two-repo measurement; see the file _note). COMPONENT-MEMBER READ POINTS (moved out of packages/spec/src, #23434; ruling 6165388570 letter C, Q1 A as the seat read it): an EVIDENCE LIST only — no verdict is asserted, so component-level liveness stays unclassified as above. Each entry names the ComponentPropsMap row and member it reads, then its read points in the spelling `objectui @SHA FILE#SYMBOL` (the SHA is the objectui tree the point was last read in; a pin hop moves nothing here, and a renamed or deleted symbol is the event that re-measures it). Inside one entry, a letter defined at its head abbreviates a repeated file: with `P = objectui @SHA FILE`, `P#a P#b` reads `objectui @SHA FILE#a`, `objectui @SHA FILE#b`. Entries, in source order: [1] page:header (H = objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageHeaderRenderer): title (`schema?.title ?? schema?.properties?.title`), the refused `icon` (resolved only per header action) and `breadcrumb` (an empty slot), `actions` (resolvedHeaderActions then headerActionPlan), recordChrome (`=== false` on either carrier, branching the header), showStar and showCopyId (the record chip), maxVisible and mobileMaxVisible (`?? 3` / `?? 1`), all in H; re-read 2026-10-15, first cited sha-less; [2] page:tabs (T = objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageTabsRenderer): tabStyle (`schema?.properties?.type || schema?.tabStyle || 'line'`), alwaysShowStrip (`schema?.alwaysShowStrip === true || schema?.properties?.alwaysShowStrip === true`), items[].value (`it.value`, falling back to `tab-${idx}`; the refused `key` is the designer's `page:tabs.items.itemFields` input in objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-config.ts#BLOCK_CONFIG), all in T; the retired props key `type` (the reason for the rename): left unhoisted by objectui @b9814b334 packages/react/src/SchemaRenderer.tsx#HOIST_PROTECTED_KEYS, and skipped as a base prop by objectui @b9814b334 packages/sdui-parser/src/validate.ts#BASE_PROPS; re-read 2026-10-15, first cited sha-less; [3] page:tabs items[].icon (C = objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx): C#triggerClass (`LazyIcon` inside the TabsTrigger) in C#PageTabsRenderer; published by its registration's `items` input; vocabulary objectui @b9814b334 packages/components/src/lib/lazy-icon.tsx#getLazyIcon; [4] page:tabs items[].visibleWhen (the tab-item evaluator: `data` is the row, bare fields spread flat, ambient roots after it): objectui @1fb1ced36243 packages/components/src/renderers/layout/containers.tsx#isItemVisible (its ExpressionEvaluator) in PageTabsRenderer; [5] record:details / record:highlights / record:related_list / record:quick_actions .requiredPermissions (RECORD_BLOCK_REQUIRED_PERMISSIONS_DESCRIPTION; R = objectui @b9814b334 packages/plugin-detail/src/renderers/, P = objectui @b9814b334 packages/permissions/src/): the gate `perms.hasCapabilities(required)` and the notice in R record-details.tsx#RecordDetailsBody, R record-highlights.tsx#highlightsAllowed (RecordHighlightsBody), R record-related-list.tsx#RecordRelatedListBody, R record-quick-actions.tsx#RecordQuickActionsBody; earlier withholding: no record R record-details.tsx#RecordDetailsBody, no object and the related read gate R record-related-list.tsx#RecordRelatedListBody; a gated highlights registers no fields R record-highlights.tsx#RecordHighlightsBody (useRegisterHighlightFields); ALL OF THEM and fail-open on unreported P MePermissionsProvider.tsx#hasCapabilities; fail-open P PermissionProvider.tsx#ALL_CAPABILITIES and P usePermissions.ts#NO_PROVIDER_PERMISSIONS; the binding wrapper (objectui#12294) objectui @b9814b334 packages/plugin-detail/src/renderers/recordBinding.tsx#recordBindingBlock; [6] record:details sections[].headerColor (closed enum, #12126): the six class literals of objectui @b9814b334 packages/plugin-detail/src/headerColor.ts#headerColorClass (objectui#6294, merged 2026-08-25); re-read 2026-10-15, first cited sha-less; [7] record:details sections[] hideEmpty, collapsible, showBorder and the #11661 trio (renderer defaults measured; the trio at objectui @190fbd01): objectui @190fbd01 packages/plugin-detail/src/renderers/record-details.tsx#RecordDetailsRenderer and objectui @190fbd01 packages/plugin-detail/src/DetailSection.tsx#DetailSection (`hideEmpty ?? true`; the undeclared `s.title ?? s.label` limb); [8] record:related_list.parentDataSource (the name): the sibling record blocks' binding read objectui @f0532d8a packages/plugin-detail/src/renderers/recordBinding.tsx#recordBindingBlock (`isElementDataSourceConfig(schema.dataSource)`), measured on objectui main; [9] record:details sections[].count (read since objectui c08c9332a, objectui#12192): objectui @b9814b334 packages/plugin-detail/src/renderers/record-details.tsx#countField (inside filteredSections; fills every `{{ count }}` hole); [10] record:related_list.parentDataSource (PLANNED): the objectui measurement is the file _note's (objectui @f0532d8a, the record context read in RecordRelatedListBody); no new evidence here; [11] record:activity guidance `items` / `loading` (host feed slot; R = objectui @89cad75d5570 packages/plugin-detail/src/renderers/): R record-activity.tsx#hostItems and R record-activity.tsx#loading in RecordActivityRenderer; record:chatter / record:discussion `feed` reads neither, R record-chatter.tsx#RecordChatterRenderer; [12] record:chatter.position (vocabulary bottom / right / left, #8762): objectui @665661ab0932 packages/plugin-detail/src/RecordChatterPanel.tsx#position (`right`/`left` dock vs `bottom` in-flow); the designer's CHATTER_INPUTS and the merge fallback in objectui @665661ab0932 packages/plugin-detail/src/renderers/record-chatter.tsx#RecordChatterRenderer; [13] record:reference_rail (RecordReferenceRailProps): objectui @b9814b334 packages/plugin-detail/src/renderers/record-reference-rail.tsx#RecordReferenceRailRenderer ( an entry `icon` is unread, `title` a raw React child); the synthesizer emitting `icon` objectui @b9814b334 packages/plugin-detail/src/synth/buildDefaultPageSchema.ts#buildDefaultPageSchema; re-read 2026-10-15, first cited sha-less; [14] record:alert, record:quick_actions, record:history: objectui @b9814b334 packages/plugin-detail/src/renderers/record-alert.tsx#RecordAlertRenderer, objectui @b9814b334 packages/plugin-detail/src/renderers/record-quick-actions.tsx#RecordQuickActionsRenderer, objectui @b9814b334 packages/plugin-detail/src/renderers/record-history.tsx#RecordHistoryRenderer and objectui @b9814b334 packages/plugin-detail/src/HistoryTimeline.tsx#HistoryTimeline (each renderer's ACTUAL reads, against its registration's declared inputs); re-read 2026-10-15, first cited sha-less; [15] record:line_items (RecordLineItemsProps; L = objectui @31971ff1e28f packages/plugin-form/src/LineItemsPanel.tsx): registered as `line_items` (namespace `record`) in objectui @31971ff1e28f packages/plugin-form/src/index.tsx with its mapping objectui @31971ff1e28f packages/plugin-form/src/index.tsx#RECORD_LINE_ITEMS_DATA_SOURCE; the fifteen `schema.KEY` reads in L#LineItemsPanel (childObject L#heldReloadRef; parentObject L#parentObject; parentId, recordId L#parentId; amountField, totalField L#parentPatch; filter L#scopeFilter; limit L#message; columns L#gridField (applyColumnPermissions)); the gate objectui @31971ff1e28f packages/react/src/element-data-source/ElementDataSourceGate.tsx#useElementDataSourceSchema; read set unchanged at objectui main d59f11c0d3dc; [16] record:line_items guidance (addLabel, sortField, onRowExpand not handed to the grid): objectui @9dfaca654311 packages/plugin-form/src/LineItemsPanel.tsx#gridField; [17] record:approvals (RecordApprovalsProps, EMPTY key set; A = objectui @47b1f0bb71 packages/app-shell/src/views/): registered as `approvals` (namespace `record`) in A record-approvals-renderer.tsx#RecordApprovalsRenderer; approvals A record-approvals-renderer.tsx#hostApprovals, threaded by A RecordDetailView.tsx#RecordDetailView and emitted by objectui @47b1f0bb71 packages/plugin-detail/src/synth/buildDefaultPageSchema.ts#buildDefaultPageSchema; currentUserId falls back in A RecordApprovalsPanel.tsx#isSubmitter; Studio page create seeds without options in A metadata-admin/anchors.ts#synth; [18] page:accordion items[].value (refused): objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageAccordionRenderer overwrites it with `panel-${idx}`; the designer input `page:accordion.items.itemFields` in objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-config.ts#BLOCK_CONFIG (objectui#7973); re-read 2026-10-15, first cited sha-less; [19] page:accordion items[].icon (C = objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx): C#commonChildren (`LazyIcon` in the AccordionTrigger) inside C#PageAccordionRenderer; published by its `accordion` registration's `items` input; vocabulary objectui @b9814b334 packages/components/src/lib/lazy-icon.tsx#getLazyIcon; [20] page:accordion.variant: objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageAccordionRenderer (`schema?.variant ?? schema?.properties?.variant ?? 'flush'`); re-read 2026-10-15, first cited sha-less; [21] element:text.variant retired `heading` / `subheading`: objectui @89cad75d55 packages/components/src/renderers/basic/elements.tsx#VARIANT_TAG; [22] element:button.icon (B = objectui @b9814b334 packages/components/src/renderers/form/button.tsx, R = objectui @b9814b334 packages/components/src/renderers/action/resolve-icon.ts): B#Icon (resolveIcon) and its render on either side of the label in B#ButtonRenderer; R#resolveIcon R#describeIconLookup R#toPascalCase R#iconNameMap R#recordIconName (the vocabulary: the generated objectui @b9814b334 packages/components/src/lib/lucide-record-icon-names.ts#LUCIDE_RECORD_ICON_NAME_TABLE); contrast objectui @b9814b334 packages/components/src/lib/lazy-icon.tsx#getLazyIcon; no `icon` in the registration's inputs inside B#ButtonRenderer (objectui#9910 added the `children` slot input); history: the read point moved files on the hop onto objectui 9602dc820, and the registration ranges were first wrong-since-written at objectui a472b0716; [23] action:* rows, the effective executor and the runner's reads (R = objectui @b9814b334 packages/core/src/actions/ActionRunner.ts, first read at objectui @1fb1ced36243 with every anchor at the same symbols; A = objectui @b9814b334 packages/components/src/renderers/action/): executor resolution R#execute (`action.type || action.actionType || action.name`); forwarded executor A action-button.tsx#forwarded, A action-icon.tsx#forwarded (`type: schema.actionType`), A action-group.tsx#paramsPayload, A action-menu.tsx#paramsPayload (`type: action.type`); the name leg documented in A action-button.tsx#forwarded; built-in executors and the `navigation` alias R#ActionRunner (`builtinExecutors`), url navigation executeUrl / executeNavigation / navigateTo in R#ActionRunner; no console host handler under `url` / `navigation`: objectui @b9814b334 packages/app-shell/src/console/ConsoleShell.tsx, packages/app-shell/src/hooks/useConsoleActionRuntime.tsx, packages/app-shell/src/console/AppContent.tsx, packages/app-shell/src/hooks/useObjectActions.ts; onSuccess R#handlePostExecution R#readOnSuccessNavigation; operation read before any executor R#execute (isUpdateOperationAction), forwarded A action-button.tsx#forwarded; patch merged only when a plain object (executeUpdateOperation in R#ActionRunner); unchanged at objectui main 866763bd and 72594f29; [24] section 4b, the action:* quartet and element:* lists (shared reads; A = objectui @b9814b334 packages/components/src/renderers/action/): publication objectui @b9814b334 packages/core/src/registry/public-blocks.ts#PUBLIC_BLOCKS; `autoTrigger` \"NOT persisted metadata\" in the header of A auto-trigger.ts#useAutoTriggerOnce; the Button primitive vocabulary objectui @b9814b334 packages/components/src/ui/button.tsx#buttonVariants; `objectName` forwarded by A action-button.tsx#forwarded and A action-icon.tsx#forwarded, and per member by A action-group.tsx#paramsPayload and A action-menu.tsx#paramsPayload; history: objectui#11168 slices 1-2, objectui#11212 (fail-closed `visible`), objectui#11182 (host `disabled` verdict), objectui#11344 (`outcomeMessages`), objectui#11638 (member `properties.params` read retired), objectui#11839 (disabled reason), objectui#11880 (repeater binding), objectui#12085 (repeater publishes only the binding); [25] action:button (ActionButtonPropsSchema; B = objectui @b9814b334 packages/components/src/renderers/action/action-button.tsx; the retired gate's quoted first line `type: schema.actionType,` holds at B#forwarded): name B#isVisible (diagnostic label) B#forwarded; label B#button (React child) B#isVisible B#forwarded; icon B#Icon (resolveIcon); actionType B#forwarded (`type`); variant, size B#variant and its `size` twin; visible B#isVisible B#ActionButtonRenderer (hasDeclaredVisibilityGate); disabled B#isDisabled B#button; params B#staticValues (withUndoBaseline) and objectui @b9814b334 packages/components/src/renderers/action/static-params.ts#readStaticParamValues; the forwarded set B#forwarded (outcomeMessages forwarded since objectui#11344, left unpublished in the registration's inputs inside B#ActionButtonRenderer); undo baseline B#withUndoBaseline; [26] action:icon (ActionIconPropsSchema; I = objectui @b9814b334 packages/components/src/renderers/action/action-icon.tsx; the retired gate's quoted first line `type: schema.actionType,` holds at I#forwarded): size not read I#size (fixed `'icon'`); the forward I#forwarded (no undoable / recordIdField; outcomeMessages since objectui#11344); label I#isVisible I#forwarded I#button (aria-label, initial letter, DisabledReasonTrigger heading) I#ActionIconRenderer (tooltip); visible I#isVisible I#ActionIconRenderer; disabled I#isDisabledPred I#button; variant I#variant; params I#staticValues (readStaticParamValues); [27] action:group / action:menu members (actionContainerMember; G = objectui @2e818d0b51ec packages/components/src/renderers/action/action-group.tsx, M = objectui @2e818d0b51ec packages/components/src/renderers/action/action-menu.tsx, P = objectui @2e818d0b51ec packages/components/src/renderers/action/static-params.ts): drawn G#InlineActionButton G#DropdownActionItem M#ActionMenuItem; visible G#useMemberVisible M#useMenuActionVisible; size (group only) G#btnSize; tags G#showSeparator; locations G#actions (actionRendersAt); forwarded G#staticValues M#staticValues (the forward block); object params forwarded on `api` and dropped, with a development-build warning only, for every other `type` P#readActionEntryParamValues (first cited at objectui @0abd4f9f8, same symbol); refused: properties.params P#readMemberStaticParamValues, className G#handleClick, autoTrigger M#ActionAutoTrigger (useAutoTriggerOnce), onClick G#handleExecute M#handleExecute; the array forward (the retired gate's quoted first line `const paramsPayload: ActionDef = Array.isArray(action.params)`) objectui @b9814b334 packages/components/src/renderers/action/action-group.tsx#paramsPayload and objectui @b9814b334 packages/components/src/renderers/action/action-menu.tsx#paramsPayload, other values objectui @b9814b334 packages/components/src/renderers/action/static-params.ts#readActionEntryParamValues; the fork measured at objectui @ab1879721595, files byte-identical at objectui main 2abec3a96; [28] action:group (ActionGroupPropsSchema; G = objectui @b9814b334 packages/components/src/renderers/action/action-group.tsx): actions G#declaredActions G#actions (actionRendersAt) G#useMemberVisible G#paramsPayload; display G#display; label, icon, variant, size G#TriggerIcon (the trigger; size raw to inline members) G#btnSize; visible G#isVisible; the host `disabled` verdict (objectui#11182) G#ActionGroupRenderer; group `name` unread (the comment above G#ActionGroupRenderer, objectui#11168); the registration's inputs inside G#ActionGroupRenderer; [29] action:menu (ActionMenuPropsSchema; M = objectui @b9814b334 packages/components/src/renderers/action/action-menu.tsx): actions M#ActionMenuRenderer M#ActionMenuItem M#ActionAutoTrigger M#paramsPayload; label, icon, variant, size, visible and the host `disabled` verdict (objectui#11182) M#ActionMenuRenderer; the registration's inputs inside M#ActionMenuRenderer (objectui#11168 slice 1); [30] element:definition-list (ElementDefinitionListPropsSchema; L = objectui @b9814b334 packages/components/src/renderers/basic/data-list.tsx; the retired gate's quoted first line `const props = readProps<{` holds at L#props): items, columns (`=== 2`), inline, term, description L#DefinitionListRenderer (an item's `description` shown through L#toText: a string or number as text, an object as JSON; first cited at objectui @89cad75d55); the registration's number enum and optional `items` (objectui#11168 slice 2) at its `definition-list` registration in L; the designer's number control objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-config.ts#BLOCK_CONFIG; [31] element:repeater (ElementRepeaterPropsSchema; L = objectui @b9814b334 packages/components/src/renderers/basic/data-list.tsx; the quoted first line `const props = readProps<{` holds at L#props in L#RepeaterRenderer): object, filter, sort, limit, emptyText, divided, titleField, fields L#RepeaterRenderer; the binding L#dataBinding (useElementDataSource, objectui#11880, aaba8655a); resolved filter tokens L#filterScope; delivery objectui @b9814b334 packages/data-objectstack/src/index.ts#ObjectStackAdapter (translateFilterArray arm) and objectui @b9814b334 packages/data-objectstack/src/index.ts#serializeOrderBy; the registration wrapped by elementDataSourceBlock publishes no `object` input since objectui#12085 (ce991bd70); the registration's `object` required flag read at objectui @20c6d351a; [32] object-grid.aggregations[] (GridAggregationSchema): objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx#groupHeaders (useGroupedData) and objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx#serverGroupSource (useServerGroupHeaders); the grid's own function vocabulary objectui @89cad75d55 packages/plugin-grid/src/useGroupedData.ts#AggregationType (unchanged at objectui @b9814b334); [33] object-grid (ObjectGridPropsSchema, per key; E = objectui @eb7f586b packages/plugin-grid/src/ObjectGrid.tsx): columns, fields E#schemaFields; filter E#schemaFilterSource (toFilterNode); defaultFilters E#cols (legacy fallback); sort E#schemaSort; defaultSort E#cols; pagination, pageSize, showPagination E#lastFindParamsRef E#schemaPageSize E#paginationEnabled; searchableFields, showSearch E#trimmedSearch E#searchEnabled; rowHeight E#ObjectGrid (resolveRowHeightMode); grouping, aggregations E#grouping E#groupValueFormatter; rowColor E#getRowClassName; conditionalFormatting E#predicateFields E#rules; selection, selectable E#ObjectGrid; rowActions E#rowActionsList; batchActions, bulkActions E#declaredBulkActions; bulkActionDefs E#legacyBulkNames; navigation E#navigation; editable, singleClickEdit, resizable, resizableColumns, reorderableColumns E#dataTableSchema; frozenColumns E#effectiveFrozenColumns; showColumnTypeIcons E#fieldMeta; exportOptions, operations E#declared; label, title E#fileNameFor E#dataTableSchema; data, staticData E#getDataConfig; [#20694] description objectui @db11afd4967c packages/plugin-grid/src/ObjectGrid.tsx#resolvedDescription (drawn as `gridDescription`); emptyState objectui @db11afd4967c packages/plugin-grid/src/ObjectGrid.tsx#authoredEmptyState (DataEmptyState in renderedGridContent); keyboardNavigation 0 read points at objectui @db11afd4967c, 15 hit lines at objectui @ab1879721595 and at objectui @b9814b334 against 3 then 4 for the control `schema.editable` (the fourth objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx#carriesConcurrencyToken); [34] object-grid.description, object-grid.emptyState (B = objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx): description objectui @db11afd4967c packages/plugin-grid/src/ObjectGrid.tsx#resolvedDescription; emptyState title/message B#authoredEmptyTitle (resolveInlineI18nLabel, objectui#11227 carried by 6158e4c93; raw at objectui @89cad75d5570) drawn in B#renderedGridContent, link (objectui#12270, b434f5f47) B#renderedGridContent (EmptyStateLink); [35] object-grid.columns (ListViewSchema.shape.columns; A = objectui @ab1879721595 packages/plugin-grid/src/ObjectGrid.tsx): A#normalizeColumns (first-entry dispatch) A#cols A#fieldName (resolvesToDataColumn); the retired `colOverride?.options` read: A#groupValueFormatter A#rawOptions (objectui b0bf413, objectui#11544); the footer summary's off-contract column keys objectui @ab1879721595 packages/plugin-grid/src/useColumnSummary.ts#columnHints; [36] object-grid.fields (O = objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx): O#schemaFields O#fieldsToShow O#generateColumns; the host hand-off projection O#getSelectFields; [37] object-grid.filter: objectui @53ded82b packages/plugin-grid/src/ObjectGrid.tsx#ObjectGrid (toFilterNode before `$filter`); [38] object-grid.sort (S = objectui @53ded82b packages/plugin-grid/src/ObjectGrid.tsx): S#schemaSort S#cols (the fetch path's string arm and array arm) S#declaredSort (parseSchemaSort, `TableSortItem[]`); the registration's array input objectui @53ded82b packages/plugin-grid/src/index.tsx (`{ name: 'sort', type: 'array' }`); [39] object-grid.defaultSort (REMOVED, tombstone; D = objectui @190fbd01d packages/plugin-grid/src/ObjectGrid.tsx): D#cols (`$orderby` fallback) and D#declaredSort (`[schema.defaultSort]`); [40] object-grid.pagination (D = objectui @d18322415 packages/plugin-grid/src/ObjectGrid.tsx): pageSize D#lastFindParamsRef D#schemaPageSize D#pageSize; pageSizeOptions D#dataTableSchema; presence D#paginationEnabled; the registry input objectui @d18322415 packages/plugin-grid/src/index.tsx (`pagination`, type object); [41] object-grid members read at objectui @89cad75d55 (O = objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx): rowHeight O#resolveRowHeightMode; aggregations O#groupHeaders (useGroupedData) O#serverGroupSource (useServerGroupHeaders); conditionalFormatting O#getRowStyle (resolveConditionalFormatting); rowColor O#getRowClassName (useRowColor); selection and selectable O#ObjectGrid (the selection-mode branch) O#dataTableSchema (`selectable`), read by objectui @89cad75d55 packages/components/src/renderers/complex/data-table.tsx#resolveSelectionMode; rowActions O#rowActionsDeclared; bulkActions, batchActions O#declaredBulkActions (`batchActions ?? bulkActions`); bulkActionDefs O#legacyBulkNames (resolveBulkActions); [42] object-grid.navigation: objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx#navigation (useNavigationOverlay); [43] object-grid.keyboardNavigation (built by objectui 154075ab1, objectui#11068; declared ahead of its reader, which read nothing at objectui @db11afd4967c): objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx#dataTableSchema (`schema.keyboardNavigation ?? inlineEditable`) with objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx#inlineEditable; objectui @b9814b334 packages/components/src/renderers/complex/data-table.tsx#DataTableRenderer (default false, `role=\"grid\"`, the roving tabIndex), objectui @b9814b334 packages/components/src/renderers/complex/data-table.tsx#navigationTarget and objectui @b9814b334 packages/components/src/renderers/complex/data-table.tsx#handleCellKeyDown; [44] object-grid.resizableColumns (REMOVED, tombstone): objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx#dataTableSchema (`schema.resizable ?? schema.resizableColumns ?? true`); [45] object-grid.operations (GridOperationsSchema; O = objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx): create O#dataTableSchema (showAddRow); update, delete O#wantDeleteAction; export O#handleExport O#dataTableSchema (exportable) O#exportEnabled; a declared block replaces the default O#explicitOperations; [46] object-grid.data: the registry input objectui @b9814b334 packages/plugin-grid/src/index.tsx#GRID_QUERY_INPUTS (`{ name: 'data', type: 'object' }`, held by gridDataInputContract.test.ts); re-read 2026-10-15, first cited sha-less; [47] object-metric.aggregate (ObjectMetricAggregateSchema; M = objectui @89cad75d55 packages/plugin-dashboard/src/ObjectMetricWidget.tsx): field, function M#computeOne; function also M#fieldUnitApplies (answersInFieldUnit) M#inferredFormat (min/max width); groupBy M#computeOne (objectAggregateSpecQuery; floored at `'_all'`) typed on M#ObjectMetricWidgetProps (`ChartAggregate['groupBy']`); objectui's unit-rule pin ObjectMetricWidget.countNotCurrency-10356.test.tsx mounts one tile per AggregationFunction member; [48] object-metric.trend (ObjectMetricTrendSchema; W = objectui @89cad75d55 packages/plugin-dashboard/src/): drawn in W MetricWidget.tsx#MetricWidget (`{value}%`, direction arrow), caption W MetricWidget.tsx#localizedTrendLabel (pickLocalized); declared on W MetricWidget.tsx#MetricWidgetProps, mirrored on W ObjectMetricWidget.tsx#ObjectMetricWidgetProps; replaced by a derived trend in W ObjectMetricWidget.tsx#effectiveTrend; [49] object-metric.drillDown (ObjectMetricDrillDownSchema; A = objectui @ab1879721595): enabled A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#drillEnabled (isDrillEnabled); title A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#drawerTitle (resolveDrillTitle against an empty event); target, columns, maxRows A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#drillDrawer (DrillDownDrawer); `filter` / `mode` refused as objectui's own A packages/types/src/data-display.ts#ObjectMetricDrillDownConfig refuses them; measured writers, objectui's drill-down member pins A packages/plugin-dashboard/src/__tests__/objectMetricDrillDownMembers-8071.test.tsx and A packages/plugin-dashboard/src/__tests__/ObjectMetricWidget.drillRoutedToSharedDrawer-8970.test.tsx; [50] object-metric.drillDown.report (R = objectui @2e818d0b51ec packages/plugin-dashboard/src/): handed verbatim in R ObjectMetricWidget.tsx#drillDrawer; drawn when R DrillDownDrawer.tsx#isDatasetBoundReport holds (R DrillDownDrawer.tsx#isReportDrill), joining the metric filter into `runtimeFilter` (R DrillDownDrawer.tsx#body); typed `SpecReportInput` in objectui @2e818d0b51ec packages/types/src/data-display.ts; the fork measured at objectui @ab1879721595, both files byte-identical at objectui main 2abec3a96; [51] object-metric.compareTo (ObjectMetricCompareToSchema; A = objectui @ab1879721595): A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#comparisonFilter (second aggregate over shiftFilterByCompareTo) and A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#derivedTrend (compareToTrendLabelKey); both dispatch on `kind === 'previousYear'` in A packages/core/src/utils/compare-to.ts#shiftFilterByCompareTo and A packages/core/src/utils/compare-to.ts#compareToTrendLabelKey; `dimension` \"deliberately never read on this path\" in that module's header; [52] object-metric (ObjectMetricPropsSchema): objectui @eb7f586b packages/plugin-dashboard/src/ObjectMetricWidget.tsx#ObjectMetricWidgetProps (the complete destructured read set); [53] object-metric.icon (B = objectui @b9814b334 packages/plugin-dashboard/src/): published by B index.tsx#ObjectMetricBlock (`{ name: 'icon', type: 'string' }`); destructured and forwarded by B ObjectMetricWidget.tsx#ObjectMetricWidget; resolved and drawn by B MetricWidget.tsx#MetricWidget (getLazyIcon, guarded on a string); vocabulary objectui @b9814b334 packages/components/src/lib/lazy-icon.tsx#getLazyIcon; not B MetricCard.tsx (off this key's path); [54] object-metric.filter: the analytics wire lowering objectui @53ded82b packages/data-objectstack/src/index.ts#lowerAnalyticsFilterForWire (objectui#7754); before it the adapter at objectui @a472b07 posted an array verbatim (a 400, #15828); [55] object-kanban.columns[] lane (ObjectKanbanLaneSchema; K = objectui @89cad75d55 packages/plugin-kanban/src/): id K index.tsx#bucketCardsIntoColumns; title K ObjectKanban.tsx#localizeColumn; cards K index.tsx#bucketCardsIntoColumns (kept ahead of the bucketed records); limit K KanbanImpl.tsx#isLimitExceeded; className K KanbanImpl.tsx#KanbanColumnView; collapsed K KanbanImpl.tsx#isColumnCollapsed; [56] object-kanban (ObjectKanbanPropsSchema; E = objectui @eb7f586b packages/plugin-kanban/src/ObjectKanban.tsx): columns E#effectiveColumns; filter E#fetchData (`$filter`); data E#boundData; cardTitle, titleField E#explicitTitleField; cardFields E#explicitCardFields; swimlaneField, grouping E#effectiveSwimlaneField; coverImageField, conditionalFormatting via objectui @eb7f586b packages/plugin-kanban/src/index.tsx#KanbanRenderer (the spread of the authored bag); limit objectui @b9814b334 packages/plugin-kanban/src/ObjectKanban.tsx#query (`$top: resolveRowLimit(schema.limit, DEFAULT_KANBAN_FETCH_BATCH_SIZE)`), first re-read at objectui @87af769e9 where `$top: schema.limit ?? DEFAULT_KANBAN_LIMIT` had become resolveRowLimit; [57] object-kanban.columns (the first-entry dispatch): objectui @89cad75d55 packages/plugin-kanban/src/ObjectKanban.tsx#effectiveColumns (string arm only without `groupBy`); [58] object-kanban.filter: objectui @53ded82b packages/plugin-kanban/src/ObjectKanban.tsx#ObjectKanban (`$filter: schema.filter`, verbatim, lowered by ObjectStackAdapter.convertQueryParams through translateFilterArray); [59] object-kanban.limit (B = objectui @b9814b334): query B packages/plugin-kanban/src/ObjectKanban.tsx#query (`$top: resolveRowLimit(schema.limit, DEFAULT_KANBAN_FETCH_BATCH_SIZE)`) with B packages/plugin-kanban/src/ObjectKanban.tsx#DEFAULT_KANBAN_FETCH_BATCH_SIZE and the resolved filter B packages/plugin-kanban/src/ObjectKanban.tsx#filterScope; mapping B packages/plugin-kanban/src/index.tsx#OBJECT_KANBAN_DATA_SOURCE (`limit: 'limit'`); type B packages/types/src/objectql.ts#ObjectKanbanSchema (`limit?: number`); docs B content/docs/plugins/plugin-kanban.mdx (`limit: 250` snippet and Properties row); precedence B packages/react/src/element-data-source/ElementDataSourceGate.tsx#useElementDataSourceSchema (binding cap over this key; a view's pagination.pageSize only when unset) and B packages/react/src/element-data-source/ElementDataSourceGate.tsx#isUsableRowLimit; the saved-view fallback B packages/core/src/data-scope/element-data-source.ts#savedViewRawLimit; first re-read at objectui @87af769e9 2026-09-20; [60] object-master-detail-form (ObjectMasterDetailFormPropsSchema): objectui @eb7f586b packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailForm; auto-derivation objectui @eb7f586b packages/plugin-form/src/deriveMasterDetail.ts; the `formType` pair objectui's MasterDetailFormSchema declares; [61] object-kanban.quickAdd (RETIRED, tombstone; K = objectui @b9814b334 packages/plugin-kanban/src/): K index.tsx#KanbanRenderer passes `quickAdd` / `onQuickAdd` (the host-mounted React component); gated on both in K KanbanImpl.tsx#KanbanColumnView; K KanbanBoardCore.tsx#KanbanBoardCoreProps reads neither off `schema` (objectui#11234); K ObjectKanban.tsx#ObjectKanban names `quickAdd` and `onQuickAdd` 2 times each (both in comments) against 11 for `onCardClick` (method: occurrences in that file, re-counted 2026-10-15); no `kanban-ui` registration at that sha (objectui#8257; the name survives only in tests and the changelog); through objectui @db11afd49 the board's spread forwarded the key; [62] object-kanban.conditionalFormatting (A = objectui @ab1879721595): A packages/plugin-kanban/src/KanbanBoardCore.tsx#processedColumns hands it to the board; A packages/plugin-kanban/src/KanbanImpl.tsx#getCardStyles evaluates it through A packages/core/src/evaluator/listConditional.ts#resolveConditionalFormatting, the evaluator of A packages/plugin-grid/src/ObjectGrid.tsx#getRowStyle; objectui's declaration A packages/types/src/zod/objectql.zod.ts#KanbanConditionalFormattingRuleSchema and A packages/types/src/objectql.ts#KanbanConditionalFormattingRule (objectui#11522, landed by objectui#11532 c73cdb5695); the stored-dialect arms in A packages/plugin-kanban/src/KanbanImpl.tsx#getCardStyles; blank-predicate fallback A packages/core/src/evaluator/listConditional.ts#evalRowPredicate; the four reader files byte-identical at objectui main 2e818d0b51; the writer census also read objectui at main; [63] object-kanban.navigation (K = objectui @b9814b334 packages/plugin-kanban/src/ObjectKanban.tsx): K#navConfig (`schema.navigation ?? { mode: 'drawer' }`) K#navigation (useNavigationOverlay) K#boardView (card click) K#renderRecordOverlay (NavigationOverlay); first re-derived at objectui @87af769e9, where the `(schema as any)` cast was still spelled; [64] object-calendar flat field keys (OBJECT_CALENDAR_FLAT_FIELD_GUIDANCE): objectui @b9814b334 packages/plugin-calendar/src/ObjectCalendar.tsx#getCalendarConfig (the backward-compat flat fallback); re-read 2026-10-15, first cited sha-less; [65] object-calendar (ObjectCalendarPropsSchema; C = objectui @eb7f586b packages/plugin-calendar/src/ObjectCalendar.tsx): calendar C#getCalendarConfig; defaultView C#schemaDefaultView; locale, loading via the registry shell objectui @eb7f586b packages/plugin-calendar/src/index.tsx; [66] object-calendar.calendar (CalendarConfigSchema by reference; C = objectui @89cad75d55 packages/plugin-calendar/src/ObjectCalendar.tsx): C#getCalendarConfig returns the block; its five bindings read in C#queryFilter, C#handleEventDropDefault and C#submitQuickCreate; [67] object-calendar.filter: objectui @53ded82b packages/plugin-calendar/src/ObjectCalendar.tsx#fetchData (`$filter: schema.filter`, verbatim); [68] object-tree.navigation: objectui @89cad75d55 packages/plugin-tree/src/ObjectTree.tsx#navigation (useNavigationOverlay); [69] object-calendar.sort: objectui @53ded82b packages/plugin-calendar/src/ObjectCalendar.tsx#fetchData (`$orderby: convertSortToQueryParams(schema.sort)`), whose sink objectui @53ded82b packages/core/src/utils/sort-query.ts#convertSortToQueryParams still lowered the string clause there; no `sort` input on objectui @53ded82b packages/plugin-calendar/src/index.tsx; [70] object-timeline flat config keys (OBJECT_TIMELINE_FLAT_CONFIG_GUIDANCE): the backward-compat flat rung (with the `dateField` alias) in objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#startDateField and its siblings; emitted by objectui @b9814b334 packages/plugin-list/src/ListView.tsx#viewComponentSchema (`case 'timeline'`); re-read 2026-10-15, first cited sha-less; [71] object-calendar.navigation (C = objectui @b9814b334 packages/plugin-calendar/src/ObjectCalendar.tsx): C#navConfig (`schema.navigation ?? { mode: 'drawer' }`) C#navigation (useNavigationOverlay) C#calendarView (event click) C#renderRecordOverlay (NavigationOverlay); [72] object-timeline.mapping (ObjectTimelineMappingSchema; A = objectui @ab1879721595 packages/plugin-timeline/src/ObjectTimeline.tsx; unchanged at objectui main 94985a92ba): title A#titleField; date A#startDateField; description A#descField; variant A#variantField; declared on A#ObjectTimelineProps (`mapping`) and A#TimelineMappingSchema; [73] object-timeline.items[] arms (R = objectui @2e818d0b51ec packages/plugin-timeline/src/renderer.tsx; unchanged at objectui main 2abec3a96): gantt bar startDate / endDate R#dimensions R#calculateDateRange, variant and title in R#TimelineRenderer (the bar and its tooltip); feed entry time R#dateLabel and title, description, variant, icon, content (renderChildren), className in R#TimelineRenderer; gantt row label R#TimelineRenderer (TimelineGanttLabel), items R#classifyGanttRows; vocabulary objectui @2e818d0b51ec packages/types/src/data-display.ts#TimelineItemVariant; element shape and refinement objectui @2e818d0b51ec packages/types/src/zod/data-display.zod.ts#TimelineItemSchema and objectui @2e818d0b51ec packages/types/src/zod/data-display.zod.ts#timelineItemsFitVariant; [74] object-form.layout retired values `inline` / `grid` (OBJECT_FORM_LAYOUT_RETIRED; P = objectui @f8a9d0fb0 packages/plugin-form/src/): folded to 'vertical' in P ObjectForm.tsx#SimpleObjectForm; only 'vertical' / 'horizontal' passed through by P ObjectForm.tsx#drawerLayout, ObjectForm.tsx#modalLayout, DrawerForm.tsx#formLayout, ModalForm.tsx#formLayout; 'vertical' hard-coded in P TabbedForm.tsx#TabbedForm, SplitForm.tsx#panes, WizardForm.tsx#WizardForm; [75] object-form.mobile (ObjectFormMobileSchema; F = objectui @89cad75d55 packages/plugin-form/src/ObjectForm.tsx): F#mobileOpts (the flat arm); stickyActions F#formSchema; stepper, stepperMinFields, stepperFieldsPerStep F#stepperMode; fullscreenLongText F#fieldsWithMobile; the `data-mobile-form` marker in F#SimpleObjectForm; [76] object-form.fields and object-master-detail-form.fields (formFieldNameList): objectui @ab1879721595 packages/plugin-form/src/MasterDetailForm.tsx#parentSchema (hands `fields` over verbatim), read by objectui @ab1879721595 packages/plugin-form/src/ObjectForm.tsx#fieldsToShow and objectui @ab1879721595 packages/plugin-form/src/flatFields.ts#buildFlatFields (a stored `{ name }` entry drawn by name; any other object entry warned by warnUnresolvedTopLevelField); unchanged at objectui main 94985a92ba; the retired inline field entry an author was taught by objectui @ab1879721595 skills/objectui/guides/page-builder.md (its object-form example; first cited sha-less); [77] object-form.customFields[] `grid` widget keys (minRows, maxRows, allowAdd, allowDelete, allowReorder, totalField, addLabel, sortField; W = objectui @9dfaca654311 packages/fields/src/widgets/GridField.tsx): declared on objectui @9dfaca654311 packages/types/src/field-types.ts#GridFieldMetadata, carried by objectui @9dfaca654311 packages/types/src/form.ts#FormField, mirrored in objectui @9dfaca654311 packages/types/src/zod/form.zod.ts#FormFieldSchema; read W#cfg W#allowAdd W#removeRow (minRows) W#totalField W#showTotal W#emit (sortField) W#GridFieldBody (maxRows, allowReorder, addLabel); objectui#11610 (merge 2abec3a96c) camelCased them; the parent-field `totalField` hand-off objectui @9dfaca654311 packages/plugin-form/src/LineItemsPanel.tsx#gridField and objectui @9dfaca654311 packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailLines; the writer shape (one `grid` field carrying all eight camelCase keys) objectui @9dfaca654311 examples/schema-catalog/src/schemas/fields-grid/line-items-grid.json; [78] object-form.customFields[] retired snake_case `grid` keys (OBJECT_FORM_GRID_WIDGET_SNAKE_KEYS): objectui @9dfaca654311 packages/types/src/field-types.ts#GRID_FIELD_RETIRED_KEYS; refused by objectui @9dfaca654311 packages/fields/src/widgets/GridField.tsx#GridField, tombstoned on objectui @9dfaca654311 packages/types/src/field-types.ts#GridFieldMetadata and objectui @9dfaca654311 packages/types/src/form.ts#FormField, named in objectui @9dfaca654311 packages/types/src/zod/form.zod.ts#FormFieldSchema (retiredGridFieldKey); [79] object-form.customFields[].validation: objectui @2e818d0b51ec packages/components/src/renderers/form/form.tsx#rules (inside renderFormField: minLength/maxLength/min/max spread as `{ value, message }`, `required` read only as a message string); objectui's declaration objectui @2e818d0b51ec packages/types/src/form.ts#FieldValidationRules; [80] object-timeline.navigation: objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#navigation (useNavigationOverlay) and objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#effectiveSchema (entry click, overlay); re-read 2026-10-15, first cited sha-less, when the read still spelled `(schema as any).navigation`; [81] object-form.customFields[].options[] (buildObjectFormRuntimeOption; F = objectui @2e818d0b51ec packages/components/src/renderers/form/form.tsx): label, value F#BuiltinSelectControl and objectui @2e818d0b51ec packages/core/src/evaluator/optionRules.ts#optionDisplayLabel (the four option widgets); visibleWhen F#cascade (resolveCascadingOptions; each widget's useCascadingOptions); description objectui @2e818d0b51ec packages/fields/src/widgets/LookupField.tsx#filteredOptions; `value` a runtime value: F#BuiltinSelectControl (matchOptionValue), objectui @2e818d0b51ec packages/types/src/zod/form.zod.ts#SelectOptionSchema (deliberate divergence comment), objectui @2e818d0b51ec packages/plugin-designer/src/ObjectManager.tsx#formSchema (writes `{ label, value }` pairs); unchanged at objectui main fd060f076; [82] object-form.customFields[] and the inline section entry (buildObjectFormRuntimeField; F = objectui @2e818d0b51ec packages/components/src/renderers/form/form.tsx, W = objectui @2e818d0b51ec packages/fields/src/widgets/): merge objectui @2e818d0b51ec packages/plugin-form/src/customFieldsMerge.ts#mergeCustomFields from objectui @2e818d0b51ec packages/plugin-form/src/ObjectForm.tsx#generateField; carrier F#builtinBranchHasNoControl (`field.field || field`); field row F#renderFormField (name, label, description, type, required, disabled, readonly, hidden, colSpan via F#colSpanClass), widget F#resolvedType, validation F#rules, the three `*When` rules F#ruleState, placeholder and inputType F#builtinBranchHasNoControl, options and dependsOn F#cascade, multiple F#resolvedType; layout objectui @2e818d0b51ec packages/plugin-form/src/autoLayout.ts#resolveColSpan (span, colSpan) and objectui @2e818d0b51ec packages/plugin-form/src/fieldGroups.ts#deriveFieldGroupSections (group); widgets W TextAreaField.tsx#rows, FileField.tsx#multiple (accept, multiple), VectorField.tsx#dimensions, LookupField.tsx#referenceTo, NumberField.tsx#NumberField (min, max), F#renderFieldComponent (minLength, maxLength), FormulaField.tsx#returnType, SummaryField.tsx#summaryType, GridField.tsx#allColumns (columns); read and refused: visibleOn F#ruleState, condition F#legacyConditionCel, id F#fieldKey; a measured writer, the object-manager create / edit dialog (a `formType: 'modal'` block): objectui @b9814b334 packages/plugin-designer/src/ObjectManager.tsx#formSchema (first cited sha-less); [83] object-form / object-master-detail-form sections[].fields[] `{ field }` entry (buildObjectFormSectionFieldEntry): objectui @2e818d0b51ec packages/plugin-form/src/sectionFields.ts#resolveSectionEntry (names an object field by `field`, every other key overrides its generated definition; label/placeholder/helpText copied as they stand); [84] object-form / object-master-detail-form sections[] (buildObjectFormSection; F = objectui @2e818d0b51ec packages/plugin-form/src/ObjectForm.tsx): handed over verbatim by objectui @2e818d0b51ec packages/plugin-form/src/MasterDetailForm.tsx#parentSchema; name, label F#sectionCtx (heading) F#inertPredicateSections (per-formType maps); collapsible, collapsed F#collapse (resolveSectionCollapse); visibleWhen F#sectionCtx (divider-row predicate); columns F#secCols F#clampCol (a NUMBER only); pane objectui @2e818d0b51ec packages/plugin-form/src/SplitForm.tsx#paneOf; the inline runtime field drawn as it stands in objectui @2e818d0b51ec packages/plugin-form/src/sectionFields.ts#resolveSectionEntry; objectui's own declaration objectui @2e818d0b51ec packages/types/src/objectql.ts#ObjectFormSection; [85] object-form (ObjectFormPropsSchema: the UNION of `schema.*` reads of the simple form and the sub-forms it forwards the bag into): objectui @eb7f586b packages/plugin-form/src/ObjectForm.tsx#ObjectForm, with TabbedForm, WizardForm, SplitForm, DrawerForm, ModalForm under objectui @eb7f586b packages/plugin-form/src/; `layout` `inline` / `grid` folded to `vertical` there while the registry inputs and the designer palette offered them; [86] object-form.fields (the `{ name }` entry retired from the authoring faces by objectui#11550): a census of objectui @ab1879721595 found it written only by fixtures probing the stored read and the refusal; [87] object-form.customFields: objectui @2e818d0b51ec packages/plugin-form/src/customFieldsMerge.ts#mergeCustomFields (merged over the generated fields); at objectui @2e818d0b51ec the open runtime field spelled the eight `grid` widget keys in snake_case, camelCased by objectui#11610 (carried at objectui @9dfaca654311); [88] object-form.contentLayout: objectui @89cad75d55 packages/plugin-form/src/ModalForm.tsx#renderContent (`schema.contentLayout === 'tabbed' && groups.length > 1`), declared on objectui @89cad75d55 packages/plugin-form/src/ModalForm.tsx#ModalFormSchema; [89] object-form.submitBehavior: objectui @89cad75d55 packages/plugin-form/src/ObjectForm.tsx#handleSubmit and objectui @89cad75d55 packages/plugin-form/src/WizardForm.tsx#handleStepSubmit (switch on `kind`), redirect `url` judged by objectui @89cad75d55 packages/plugin-form/src/submitRedirect.ts#resolveSubmitRedirect (FormViewSchema.safeParse); [90] object-form.navigateOnSuccess: objectui @89cad75d55 packages/plugin-form/src/successBehavior.ts#resolveSuccessNavigate, called from objectui @89cad75d55 packages/plugin-form/src/ObjectForm.tsx#handleSubmit and objectui @89cad75d55 packages/plugin-form/src/WizardForm.tsx#handleStepSubmit; a refused value reported on the success toast in objectui @89cad75d55 packages/plugin-form/src/ObjectForm.tsx#handleSubmit; [91] object-master-detail-form.details[] (the eleven entry keys): objectui @31971ff1e28f packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailDetailConfig and every `d.KEY` read in objectui @31971ff1e28f packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailLines; re-read at objectui @89cad75d5570 for #21589; [92] object-master-detail-form.details[].sortField (REMOVED, tombstone): objectui @89cad75d5570 packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailDetailConfig (no `sortField` member), derived by objectui @89cad75d5570 packages/plugin-form/src/deriveMasterDetail.ts#deriveDetail (SORT_FIELD_NAMES) and handed to the grid as `sort_field` in objectui @89cad75d5570 packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailLines; at objectui @9dfaca654311 the same hand-off spells `sortField` (objectui#11610) from objectui @9dfaca654311 packages/plugin-form/src/deriveMasterDetail.ts#deriveDetail; an entry the renderer does not resolve loads no child schema (objectui @9dfaca654311 packages/plugin-form/src/MasterDetailForm.tsx#entries); [93] object-master-detail-form.sections, .fields: objectui @2e818d0b51ec packages/plugin-form/src/MasterDetailForm.tsx#parentSchema (handed to the parent object-form verbatim); [94] object-map flat config keys (OBJECT_MAP_FLAT_CONFIG_GUIDANCE): objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#getMapConfig (branch 2) and objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#warnOnShadowedFlatMapKeys and objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#FLAT_MAP_CONFIG_KEYS; emitted by objectui @b9814b334 packages/plugin-view/src/ObjectView.tsx#ObjectView and objectui @b9814b334 packages/plugin-list/src/ListView.tsx#viewComponentSchema (`case 'map'`); re-read 2026-10-15, first cited sha-less at the then pin; [95] object-map (ObjectMapPropsSchema, per key; P = objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx, C = objectui @b9814b334 packages/core/src/utils/record-source.ts, I = objectui @b9814b334 packages/plugin-map/src/index.tsx): data P#getDataConfig C#resolveRecordSourceConfig (rung 1; the deleted array head and its carriers are recorded in the docblock above P#FLAT_MAP_CONFIG_KEYS); staticData C#resolveRecordSourceConfig (rung 2); objectName C#resolveRecordSourceConfig (rung 3) P#navigation P#warnOnLegacyFilterMapConfig P#warnOnTopLevelStyleUrl P#warnOnShadowedFlatMapKeys (cache keys) P#recordSourceObjectName (useSettledSchema); filter P#queryFilter P#fetchData (`$filter` on both fetches); sort P#fetchData (convertSortToQueryParams); map P#getMapConfig (branch 1; validates against ObjectMapConfigSchema) I#ObjectMapRenderer (its registration's `map` input); mapStyle P#getMapConfig (`schema.mapStyle || schema.map?.style`) I#ObjectMapRenderer; navigation P#navigation I#ObjectMapRenderer; enableClustering P#clusteredData I#ObjectMapRenderer; measured and not declared: style P#warnOnTopLevelStyleUrl (read only to say it is not a map style); [96] object-map.filter: objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#queryFilter (useResolvedFilter) and objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#fetchData (`$filter` on the inline and the object fetch); the registration's `filter` input objectui @b9814b334 packages/plugin-map/src/index.tsx#ObjectMapRenderer; [97] object-map.sort: objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#fetchData (convertSortToQueryParams to `$orderby`, both fetches); the registration's array-form `sort` input (objectui#8220) objectui @b9814b334 packages/plugin-map/src/index.tsx#ObjectMapRenderer; [98] object-map.navigation: objectui @89cad75d55 packages/plugin-map/src/ObjectMap.tsx#navigation (hands `schema.navigation` to useNavigationOverlay) and objectui @89cad75d55 packages/react/src/hooks/useNavigationOverlay.ts#useNavigationOverlay (`navigation?.mode ?? 'page'`); [99] object-gantt flat config keys (OBJECT_GANTT_FLAT_CONFIG_GUIDANCE): objectui @b9814b334 packages/plugin-gantt/src/ObjectGantt.tsx#FLAT_GANTT_CONFIG_KEYS and objectui @b9814b334 packages/plugin-gantt/src/ObjectGantt.tsx#getGanttConfig (branch 2 reads them; a present `gantt` block is taken whole and the flat keys beside it named as ignored); re-read 2026-10-15, first cited sha-less at the then pin; [100] object-gantt.markers (objectGanttMarker): G = objectui @ab1879721595 packages/plugin-gantt/src/GanttView.tsx: objectui @ab1879721595 packages/plugin-gantt/src/ObjectGantt.tsx#ganttView (hands `schema.markers` to GanttView verbatim); date G#markers (time-zone re-base) G#resolvedMarkers (axis mapping, drops unparsable or out-of-range dates); color G#resolvedMarkers (`m.color || 'hsl(var(--primary))'`); drawn in G#GanttView and in G#buildExportSvg; the declaration taken: objectui @ab1879721595 packages/types/src/objectql.ts#ObjectGanttSchema and objectui @ab1879721595 packages/types/src/zod/objectql.zod.ts#ObjectGanttSchema (`markers`); unchanged at objectui main 94985a92ba; [101] object-gantt (ObjectGanttPropsSchema, per key; P = objectui @b9814b334 packages/plugin-gantt/src/ObjectGantt.tsx, C = objectui @b9814b334 packages/core/src/utils/record-source.ts): data P#rawDataConfig C#resolveRecordSourceConfig (rung 1); staticData C#resolveRecordSourceConfig (rung 2); objectName (rung 3) P#persistLayoutKey P#navigation; filter P#queryFilter P#reload (`$filter`); sort P#reload (convertSortToQueryParams to `$orderby`); gantt P#getGanttConfig (branch 1, validated against the spec's GanttConfigSchema) and objectui @b9814b334 packages/plugin-gantt/src/index.tsx#ObjectGanttRenderer (its registration's `gantt` object input); navigation P#navConfig P#navigation; label P#ganttView (resolveInlineI18nLabel, export file-name chain); skipWeekends, holidays P#workingCalendar; persistLayout, viewName P#persistLayoutKey; markers, criticalPath, showBaselines, readOnly, mobileReadOnly P#ganttView, readOnly also P#renderRecordOverlay; measured and not declared: title (absent from the P#ganttView export-name chain), row cap (P#reload spreads nonGridRowCeilingQuery, marked not authorable), search and searchableFields P#searchTerm P#reload (host-generated by objectui @b9814b334 packages/plugin-list/src/ListView.tsx#viewComponentSchema, its `case 'gantt'` arm); [102] object-gantt.navigation: objectui @89cad75d55 packages/plugin-gantt/src/ObjectGantt.tsx#navConfig (`schema.navigation ?? { mode: 'drawer' }`) and objectui @89cad75d55 packages/plugin-gantt/src/ObjectGantt.tsx#navigation (useNavigationOverlay); [103] object-tree flat config keys (OBJECT_TREE_FLAT_CONFIG_GUIDANCE: parentField, labelField, titleField, fields, defaultExpandedDepth): objectui @b9814b334 packages/plugin-tree/src/ObjectTree.tsx#getTreeConfig (reads the flat spellings ahead of the `tree` block; the `schema.titleField` rung's retirement is recorded in its docblock above `fieldKey`, objectui#8841), objectui @b9814b334 packages/plugin-list/src/ListView.tsx#viewComponentSchema (its `case 'tree'` arm emits parentField, `labelField: treeCfg.labelField || 'name'`, fields, defaultExpandedDepth and no titleField since objectui 3fd862510), objectui @b9814b334 packages/plugin-tree/src/index.tsx#treeInputs (`{ name: 'tree', type: 'object' }`, no flat input); [104] object-tree (ObjectTreePropsSchema, per key; P = objectui @b9814b334 packages/plugin-tree/src/ObjectTree.tsx, C = objectui @b9814b334 packages/core/src/utils/record-source.ts): data P#dataConfig (resolveRecordSourceConfig with the `view-data` arm) and C#resolveRecordSourceConfig (rung 1, authoredDataIsOnTheDeclaredArm); staticData C#resolveRecordSourceConfig (rung 2); objectName (rung 3) P#headerObjectName P#navigation P#renderRecordOverlay (each behind resolveRecordSourceObjectName) P#parentField (detectParentField); filter P#queryFilter (useResolvedFilter) P#fetchData (`$filter` on the object fetch and on the inline ValueDataSource query); tree P#getTreeConfig and objectui @b9814b334 packages/plugin-tree/src/index.tsx#treeInputs; navigation P#navigation (useNavigationOverlay); host-prop `data` (not the authored key) P#passed; measured and not declared: sort (no `$orderby` in P#fetchData), row cap (P#fetchData spreads nonGridRowCeilingQuery); [105] object-tree.objectName (optional because no ElementDataSourceGate wiring): objectui @b9814b334 packages/plugin-tree/src/index.tsx#ObjectTreeRenderer has 0 occurrences of `ElementDataSourceGate` (re-counted 2026-10-15), against controls objectui @b9814b334 packages/plugin-gantt/src/index.tsx#ObjectGanttRenderer, packages/plugin-grid/src/index.tsx, packages/plugin-calendar/src/index.tsx (3 each) and packages/plugin-map/src/index.tsx#ObjectMapRenderer (4); method: occurrences of the identifier in each `src/index.tsx`; [106] object-timeline (ObjectTimelinePropsSchema, per key; P = objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx, R = objectui @b9814b334 packages/plugin-timeline/src/renderer.tsx, I = objectui @b9814b334 packages/plugin-timeline/src/index.tsx): objectName P#ObjectTimeline (fetch gate) P#useSettledSchema P#fetchesForItself P#invalidationNonce P#fetchData P#handleRefresh P#effectiveItems P#navigation; timeline P#timelineConfig; filter P#queryFilter P#filterKey P#fetchData; sort P#sortKey P#fetchData (convertSortToQueryParams); limit P#fetchData (resolveRowLimit) P#DEFAULT_TIMELINE_LIMIT P#describeRefusedRowLimit; items P#hasInlineItems P#fetchesForItself P#effectiveItems P#hasAuthoredItems; data P#hasInlineData P#fetchesForItself P#rawData; descriptionField P#descField; mapping P#titleField P#startDateField P#descField P#variantField; variant P#hasAuthoredItems (the `timeline-unsupported-variant` refusal, objectui#6655) and I#OBJECT_TIMELINE_INPUTS; navigation P#navigation P#effectiveSchema; dateFormat, rowLabel, minDate, maxDate R#TimelineRenderer (rowLabel and minDate/maxDate in its gantt branch, R#findUnusableGanttDate) off P#effectiveSchema; measured and not declared: bind P#boundData (useDataScope), className P#effectiveSchema; [107] object-timeline.data (read off React props, not `schema`; the prop channel is SchemaRenderer's `properties.*` hoist, objectui @b9814b334 packages/react/src/SchemaRenderer.tsx#SchemaRenderer, with `object-timeline` absent from objectui @b9814b334 packages/core/src/utils/record-source.ts#RECORD_SOURCE_DATA_ARM_BY_TYPE): objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#hasInlineData (loading seed), objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#fetchesForItself (the query skip the fetch effect reads), objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#rawData (row source `(props as any).data || boundData || fetchedData`), objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#effectiveItems (the `timeline` field bindings a fetched row takes); [108] object-timeline.items: objectui @2e818d0b51ec packages/types/src/data-display.ts#TimelineFeedItem and objectui @2e818d0b51ec packages/types/src/data-display.ts#TimelineGanttItem (the declared authored entry, ruled on objectui#6356), handed to the rail verbatim at objectui @2e818d0b51ec packages/plugin-timeline/src/ObjectTimeline.tsx#effectiveItems (`if (schema.items) return schema.items`); [109] record:reference_rail, record:alert, record:quick_actions, record:history, record:line_items (rows): key sets measured from the renderers' read points; the per-key read points are recorded under each props schema below; [110] record:approval_decision (row, EMPTY key set): objectui @d03b022 packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.tsx#ApprovalDecisionRenderer (landed in objectui a368ccb, module-internal at d03b022; discards `schema`, draws from the record context); [111] record:attachments (row, EMPTY key set): objectui @47b1f0bb71 packages/app-shell/src/views/record-attachments-renderer.tsx#RecordAttachmentsRenderer (registered as `attachments` in the `record` namespace; discards `schema`); [112] cloud-connection:panel, marketplace:installed-list (rows, EMPTY key sets): objectui @b9814b334 packages/app-shell/src/console/cloud-connection/CloudConnectionPanel.tsx#CloudConnectionPanel and objectui @b9814b334 packages/app-shell/src/console/marketplace/InstalledListWidget.tsx#InstalledList (each registration is `() => `; re-read 2026-10-15, first measured sha-less at the then pin); [113] mcp:connect-agent (row, EMPTY key set): objectui @b9814b334 packages/app-shell/src/console/connect/ConnectAgentWidget.tsx#ConnectAgent (registration `() => `; re-read 2026-10-15, first measured sha-less at the then pin); [114] element:definition-list, element:repeater (rows: the three-part string-arm evidence): objectui @b9814b334 packages/components/src/renderers/basic/data-list.tsx#DefinitionListRenderer and objectui @b9814b334 packages/components/src/renderers/basic/data-list.tsx#RepeaterRenderer (both registered in the `element` namespace), objectui @b9814b334 packages/core/src/registry/public-blocks.ts#PUBLIC_BLOCKS (publication), objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-types.ts#BLOCK_TYPE_META (palette), objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-config.ts#BLOCK_CONFIG (each block's inspector); [115] action:button, action:group, action:menu, action:icon (rows): objectui @b9814b334 packages/core/src/registry/public-blocks.ts#PUBLIC_BLOCKS (the four `action:*` members), registered under objectui packages/components/src/renderers/action/ in the `action` namespace; [116] object-map, object-gantt, object-tree (row key sets; per-key read points under each props schema): objectui @b9814b334 packages/plugin-map/src/index.tsx#ObjectMapRenderer, objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#ObjectMap, objectui @b9814b334 packages/plugin-gantt/src/index.tsx#ObjectGanttRenderer, objectui @b9814b334 packages/plugin-gantt/src/ObjectGantt.tsx#ObjectGantt, objectui @b9814b334 packages/plugin-tree/src/index.tsx#ObjectTreeRenderer, objectui @b9814b334 packages/plugin-tree/src/ObjectTree.tsx#ObjectTree; [117] object-timeline (row key set; per-key read points under ObjectTimelinePropsSchema): objectui @b9814b334 packages/plugin-timeline/src/index.tsx#ObjectTimelineRenderer (the `object-timeline` and `timeline` registrations), objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#ObjectTimeline, objectui @b9814b334 packages/plugin-timeline/src/renderer.tsx#TimelineRenderer; [118] EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT rows statistic, card, button (the top-level text keys each renderer reads back; R = objectui @82a9417 packages/components/src/renderers/, re-verified identical at objectui 6c68b13 on 2026-08-18): statistic `label`, `value`, `description` R data-display/statistic.tsx#StatisticRenderer; card `title`, `description` R layout/card.tsx#CardRenderer; button `label` R form/button.tsx#ButtonRenderer; the deliberate `text` omission, `schema.content || schema.value`, at its `text` registration in R basic/text.tsx; [119] PageComponent.dataSource, the PLANNED API binding (ElementApiDataSourceSchema; its record is this file's `_note`; R = objectui @7578323a544e packages/core/src/): `read.url`'s refusal of a `./` path, measured against the console's `apiBase` promotion of a root-relative `/api/…` path only, R actions/ActionRunner.ts#navigateTo; `read.method` GET alone because every read (find, findOne, aggregate) sends an explicit `method: 'GET'`, R adapters/ApiDataSource.ts#ApiDataSource; no renderer reads the binding yet, the hook admitting only a string `object`, R data-scope/element-data-source.ts#isElementDataSourceConfig; [120] PageComponent.visibleWhen (the component-level evaluator's roots): the ambient scope (`current_user`, `user`, `ctx.user`, `os.user`, `features`, nothing else) objectui @1fb1ced36243 packages/app-shell/src/providers/ExpressionProvider.tsx#buildExpressionScope; composed with `record` (only when the page has a row) and `page` by objectui @1fb1ced36243 packages/react/src/SchemaRenderer.tsx#configEvaluationScope; no `data` root (objectui#9308) in objectui @1fb1ced36243 packages/react/src/SchemaRenderer.tsx#evaluatedSchema; the files identical at objectui main f228d710; the `page:tabs` item-level evaluator is the `page:tabs items[].visibleWhen` entry;" + "note": "region → component tree rendering (header/main/sidebar/footer). RE-CITED 2026-08-10 (#7133/#7142): same split-citation pruning as `template` — at objectui @11c1e71e the containers.tsx half names `regions` only in a comment (:798, 'page:section — thin wrapper used inside regions'). Verdict unchanged: LIVE. Component-level liveness stays unclassified (undrilled container, #4956); one component key carries a verdict OUTSIDE this file: `components[].responsive` is a retiredKey tombstone (#11027, ADR-0049 D2 — dead on a two-repo measurement; see the file _note). COMPONENT-MEMBER READ POINTS (moved out of packages/spec/src, #23434; ruling 6165388570 letter C, Q1 A as the seat read it): an EVIDENCE LIST only — no verdict is asserted, so component-level liveness stays unclassified as above. Each entry names the ComponentPropsMap row and member it reads, then its read points in the spelling `objectui @SHA FILE#SYMBOL` (the SHA is the objectui tree the point was last read in; a pin hop moves nothing here, and a renamed or deleted symbol is the event that re-measures it). Inside one entry, a letter defined at its head abbreviates a repeated file: with `P = objectui @SHA FILE`, `P#a P#b` reads `objectui @SHA FILE#a`, `objectui @SHA FILE#b`. Entries, in source order: [1] page:header (H = objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageHeaderRenderer): title (`schema?.title ?? schema?.properties?.title`), the refused `icon` (resolved only per header action) and `breadcrumb` (an empty slot), `actions` (resolvedHeaderActions then headerActionPlan), recordChrome (`=== false` on either carrier, branching the header), showStar and showCopyId (the record chip), maxVisible and mobileMaxVisible (`?? 3` / `?? 1`), all in H; re-read 2026-10-15, first cited sha-less; [2] page:tabs (T = objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageTabsRenderer): tabStyle (`schema?.properties?.type || schema?.tabStyle || 'line'`), alwaysShowStrip (`schema?.alwaysShowStrip === true || schema?.properties?.alwaysShowStrip === true`), items[].value (`it.value`, falling back to `tab-${idx}`; the refused `key` is the designer's `page:tabs.items.itemFields` input in objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-config.ts#BLOCK_CONFIG), items[].label (`translateLabel(pickLocalized(it.label, language), language, ttLabel)`: the inline locale map first, then the bundle, the order packages/spec/src/ui/i18n-label-resolver.ts mirrors, whose module docblock cited it by line, sha-less, until #23434; objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageAccordionRenderer composes an accordion item's label the same way), all in T; the retired props key `type` (the reason for the rename): left unhoisted by objectui @b9814b334 packages/react/src/SchemaRenderer.tsx#HOIST_PROTECTED_KEYS, and skipped as a base prop by objectui @b9814b334 packages/sdui-parser/src/validate.ts#BASE_PROPS; re-read 2026-10-15, first cited sha-less; [3] page:tabs items[].icon (C = objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx): C#triggerClass (`LazyIcon` inside the TabsTrigger) in C#PageTabsRenderer; published by its registration's `items` input; vocabulary objectui @b9814b334 packages/components/src/lib/lazy-icon.tsx#getLazyIcon; [4] page:tabs items[].visibleWhen (the tab-item evaluator: `data` is the row, bare fields spread flat, ambient roots after it): objectui @1fb1ced36243 packages/components/src/renderers/layout/containers.tsx#isItemVisible (its ExpressionEvaluator) in PageTabsRenderer; [5] record:details / record:highlights / record:related_list / record:quick_actions .requiredPermissions (RECORD_BLOCK_REQUIRED_PERMISSIONS_DESCRIPTION; R = objectui @b9814b334 packages/plugin-detail/src/renderers/, P = objectui @b9814b334 packages/permissions/src/): the gate `perms.hasCapabilities(required)` and the notice in R record-details.tsx#RecordDetailsBody, R record-highlights.tsx#highlightsAllowed (RecordHighlightsBody), R record-related-list.tsx#RecordRelatedListBody, R record-quick-actions.tsx#RecordQuickActionsBody; earlier withholding: no record R record-details.tsx#RecordDetailsBody, no object and the related read gate R record-related-list.tsx#RecordRelatedListBody; a gated highlights registers no fields R record-highlights.tsx#RecordHighlightsBody (useRegisterHighlightFields); ALL OF THEM and fail-open on unreported P MePermissionsProvider.tsx#hasCapabilities; fail-open P PermissionProvider.tsx#ALL_CAPABILITIES and P usePermissions.ts#NO_PROVIDER_PERMISSIONS; the binding wrapper (objectui#12294) objectui @b9814b334 packages/plugin-detail/src/renderers/recordBinding.tsx#recordBindingBlock; [6] record:details sections[].headerColor (closed enum, #12126): the six class literals of objectui @b9814b334 packages/plugin-detail/src/headerColor.ts#headerColorClass (objectui#6294, merged 2026-08-25); re-read 2026-10-15, first cited sha-less; [7] record:details sections[] hideEmpty, collapsible, showBorder and the #11661 trio (renderer defaults measured; the trio at objectui @190fbd01): objectui @190fbd01 packages/plugin-detail/src/renderers/record-details.tsx#RecordDetailsRenderer and objectui @190fbd01 packages/plugin-detail/src/DetailSection.tsx#DetailSection (`hideEmpty ?? true`; the undeclared `s.title ?? s.label` limb); [8] record:related_list.parentDataSource (the name): the sibling record blocks' binding read objectui @f0532d8a packages/plugin-detail/src/renderers/recordBinding.tsx#recordBindingBlock (`isElementDataSourceConfig(schema.dataSource)`), measured on objectui main; [9] record:details sections[].count (read since objectui c08c9332a, objectui#12192): objectui @b9814b334 packages/plugin-detail/src/renderers/record-details.tsx#countField (inside filteredSections; fills every `{{ count }}` hole); [10] record:related_list.parentDataSource (PLANNED): the objectui measurement is the file _note's (objectui @f0532d8a, the record context read in RecordRelatedListBody); no new evidence here; [11] record:activity guidance `items` / `loading` (host feed slot; R = objectui @89cad75d5570 packages/plugin-detail/src/renderers/): R record-activity.tsx#hostItems and R record-activity.tsx#loading in RecordActivityRenderer; record:chatter / record:discussion `feed` reads neither, R record-chatter.tsx#RecordChatterRenderer; [12] record:chatter.position (vocabulary bottom / right / left, #8762): objectui @665661ab0932 packages/plugin-detail/src/RecordChatterPanel.tsx#position (`right`/`left` dock vs `bottom` in-flow); the designer's CHATTER_INPUTS and the merge fallback in objectui @665661ab0932 packages/plugin-detail/src/renderers/record-chatter.tsx#RecordChatterRenderer; [13] record:reference_rail (RecordReferenceRailProps): objectui @b9814b334 packages/plugin-detail/src/renderers/record-reference-rail.tsx#RecordReferenceRailRenderer ( an entry `icon` is unread, `title` a raw React child); the synthesizer emitting `icon` objectui @b9814b334 packages/plugin-detail/src/synth/buildDefaultPageSchema.ts#buildDefaultPageSchema; re-read 2026-10-15, first cited sha-less; [14] record:alert, record:quick_actions, record:history: objectui @b9814b334 packages/plugin-detail/src/renderers/record-alert.tsx#RecordAlertRenderer, objectui @b9814b334 packages/plugin-detail/src/renderers/record-quick-actions.tsx#RecordQuickActionsRenderer, objectui @b9814b334 packages/plugin-detail/src/renderers/record-history.tsx#RecordHistoryRenderer and objectui @b9814b334 packages/plugin-detail/src/HistoryTimeline.tsx#HistoryTimeline (each renderer's ACTUAL reads, against its registration's declared inputs); re-read 2026-10-15, first cited sha-less; [15] record:line_items (RecordLineItemsProps; L = objectui @31971ff1e28f packages/plugin-form/src/LineItemsPanel.tsx): registered as `line_items` (namespace `record`) in objectui @31971ff1e28f packages/plugin-form/src/index.tsx with its mapping objectui @31971ff1e28f packages/plugin-form/src/index.tsx#RECORD_LINE_ITEMS_DATA_SOURCE; the fifteen `schema.KEY` reads in L#LineItemsPanel (childObject L#heldReloadRef; parentObject L#parentObject; parentId, recordId L#parentId; amountField, totalField L#parentPatch; filter L#scopeFilter; limit L#message; columns L#gridField (applyColumnPermissions)); the gate objectui @31971ff1e28f packages/react/src/element-data-source/ElementDataSourceGate.tsx#useElementDataSourceSchema; read set unchanged at objectui main d59f11c0d3dc; [16] record:line_items guidance (addLabel, sortField, onRowExpand not handed to the grid): objectui @9dfaca654311 packages/plugin-form/src/LineItemsPanel.tsx#gridField; [17] record:approvals (RecordApprovalsProps, EMPTY key set; A = objectui @47b1f0bb71 packages/app-shell/src/views/): registered as `approvals` (namespace `record`) in A record-approvals-renderer.tsx#RecordApprovalsRenderer; approvals A record-approvals-renderer.tsx#hostApprovals, threaded by A RecordDetailView.tsx#RecordDetailView and emitted by objectui @47b1f0bb71 packages/plugin-detail/src/synth/buildDefaultPageSchema.ts#buildDefaultPageSchema; currentUserId falls back in A RecordApprovalsPanel.tsx#isSubmitter; Studio page create seeds without options in A metadata-admin/anchors.ts#synth; [18] page:accordion items[].value (refused): objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageAccordionRenderer overwrites it with `panel-${idx}`; the designer input `page:accordion.items.itemFields` in objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-config.ts#BLOCK_CONFIG (objectui#7973); re-read 2026-10-15, first cited sha-less; [19] page:accordion items[].icon (C = objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx): C#commonChildren (`LazyIcon` in the AccordionTrigger) inside C#PageAccordionRenderer; published by its `accordion` registration's `items` input; vocabulary objectui @b9814b334 packages/components/src/lib/lazy-icon.tsx#getLazyIcon; [20] page:accordion.variant: objectui @b9814b334 packages/components/src/renderers/layout/containers.tsx#PageAccordionRenderer (`schema?.variant ?? schema?.properties?.variant ?? 'flush'`); re-read 2026-10-15, first cited sha-less; [21] element:text.variant retired `heading` / `subheading`: objectui @89cad75d55 packages/components/src/renderers/basic/elements.tsx#VARIANT_TAG; [22] element:button.icon (B = objectui @b9814b334 packages/components/src/renderers/form/button.tsx, R = objectui @b9814b334 packages/components/src/renderers/action/resolve-icon.ts): B#Icon (resolveIcon) and its render on either side of the label in B#ButtonRenderer; R#resolveIcon R#describeIconLookup R#toPascalCase R#iconNameMap R#recordIconName (the vocabulary: the generated objectui @b9814b334 packages/components/src/lib/lucide-record-icon-names.ts#LUCIDE_RECORD_ICON_NAME_TABLE); contrast objectui @b9814b334 packages/components/src/lib/lazy-icon.tsx#getLazyIcon; no `icon` in the registration's inputs inside B#ButtonRenderer (objectui#9910 added the `children` slot input); history: the read point moved files on the hop onto objectui 9602dc820, and the registration ranges were first wrong-since-written at objectui a472b0716; [23] action:* rows, the effective executor and the runner's reads (R = objectui @b9814b334 packages/core/src/actions/ActionRunner.ts, first read at objectui @1fb1ced36243 with every anchor at the same symbols; A = objectui @b9814b334 packages/components/src/renderers/action/): executor resolution R#execute (`action.type || action.actionType || action.name`); forwarded executor A action-button.tsx#forwarded, A action-icon.tsx#forwarded (`type: schema.actionType`), A action-group.tsx#paramsPayload, A action-menu.tsx#paramsPayload (`type: action.type`); the name leg documented in A action-button.tsx#forwarded; built-in executors and the `navigation` alias R#ActionRunner (`builtinExecutors`), url navigation executeUrl / executeNavigation / navigateTo in R#ActionRunner; no console host handler under `url` / `navigation`: objectui @b9814b334 packages/app-shell/src/console/ConsoleShell.tsx, packages/app-shell/src/hooks/useConsoleActionRuntime.tsx, packages/app-shell/src/console/AppContent.tsx, packages/app-shell/src/hooks/useObjectActions.ts; onSuccess R#handlePostExecution R#readOnSuccessNavigation; operation read before any executor R#execute (isUpdateOperationAction), forwarded A action-button.tsx#forwarded; patch merged only when a plain object (executeUpdateOperation in R#ActionRunner); unchanged at objectui main 866763bd and 72594f29; [24] section 4b, the action:* quartet and element:* lists (shared reads; A = objectui @b9814b334 packages/components/src/renderers/action/): publication objectui @b9814b334 packages/core/src/registry/public-blocks.ts#PUBLIC_BLOCKS; `autoTrigger` \"NOT persisted metadata\" in the header of A auto-trigger.ts#useAutoTriggerOnce; the Button primitive vocabulary objectui @b9814b334 packages/components/src/ui/button.tsx#buttonVariants; `objectName` forwarded by A action-button.tsx#forwarded and A action-icon.tsx#forwarded, and per member by A action-group.tsx#paramsPayload and A action-menu.tsx#paramsPayload; history: objectui#11168 slices 1-2, objectui#11212 (fail-closed `visible`), objectui#11182 (host `disabled` verdict), objectui#11344 (`outcomeMessages`), objectui#11638 (member `properties.params` read retired), objectui#11839 (disabled reason), objectui#11880 (repeater binding), objectui#12085 (repeater publishes only the binding); [25] action:button (ActionButtonPropsSchema; B = objectui @b9814b334 packages/components/src/renderers/action/action-button.tsx; the retired gate's quoted first line `type: schema.actionType,` holds at B#forwarded): name B#isVisible (diagnostic label) B#forwarded; label B#button (React child) B#isVisible B#forwarded; icon B#Icon (resolveIcon); actionType B#forwarded (`type`); variant, size B#variant and its `size` twin; visible B#isVisible B#ActionButtonRenderer (hasDeclaredVisibilityGate); disabled B#isDisabled B#button; params B#staticValues (withUndoBaseline) and objectui @b9814b334 packages/components/src/renderers/action/static-params.ts#readStaticParamValues; the forwarded set B#forwarded (outcomeMessages forwarded since objectui#11344, left unpublished in the registration's inputs inside B#ActionButtonRenderer); undo baseline B#withUndoBaseline; [26] action:icon (ActionIconPropsSchema; I = objectui @b9814b334 packages/components/src/renderers/action/action-icon.tsx; the retired gate's quoted first line `type: schema.actionType,` holds at I#forwarded): size not read I#size (fixed `'icon'`); the forward I#forwarded (no undoable / recordIdField; outcomeMessages since objectui#11344); label I#isVisible I#forwarded I#button (aria-label, initial letter, DisabledReasonTrigger heading) I#ActionIconRenderer (tooltip); visible I#isVisible I#ActionIconRenderer; disabled I#isDisabledPred I#button; variant I#variant; params I#staticValues (readStaticParamValues); [27] action:group / action:menu members (actionContainerMember; G = objectui @2e818d0b51ec packages/components/src/renderers/action/action-group.tsx, M = objectui @2e818d0b51ec packages/components/src/renderers/action/action-menu.tsx, P = objectui @2e818d0b51ec packages/components/src/renderers/action/static-params.ts): drawn G#InlineActionButton G#DropdownActionItem M#ActionMenuItem; visible G#useMemberVisible M#useMenuActionVisible; size (group only) G#btnSize; tags G#showSeparator; locations G#actions (actionRendersAt); forwarded G#staticValues M#staticValues (the forward block); object params forwarded on `api` and dropped, with a development-build warning only, for every other `type` P#readActionEntryParamValues (first cited at objectui @0abd4f9f8, same symbol); refused: properties.params P#readMemberStaticParamValues, className G#handleClick, autoTrigger M#ActionAutoTrigger (useAutoTriggerOnce), onClick G#handleExecute M#handleExecute; the array forward (the retired gate's quoted first line `const paramsPayload: ActionDef = Array.isArray(action.params)`) objectui @b9814b334 packages/components/src/renderers/action/action-group.tsx#paramsPayload and objectui @b9814b334 packages/components/src/renderers/action/action-menu.tsx#paramsPayload, other values objectui @b9814b334 packages/components/src/renderers/action/static-params.ts#readActionEntryParamValues; the fork measured at objectui @ab1879721595, files byte-identical at objectui main 2abec3a96; [28] action:group (ActionGroupPropsSchema; G = objectui @b9814b334 packages/components/src/renderers/action/action-group.tsx): actions G#declaredActions G#actions (actionRendersAt) G#useMemberVisible G#paramsPayload; display G#display; label, icon, variant, size G#TriggerIcon (the trigger; size raw to inline members) G#btnSize; visible G#isVisible; the host `disabled` verdict (objectui#11182) G#ActionGroupRenderer; group `name` unread (the comment above G#ActionGroupRenderer, objectui#11168); the registration's inputs inside G#ActionGroupRenderer; [29] action:menu (ActionMenuPropsSchema; M = objectui @b9814b334 packages/components/src/renderers/action/action-menu.tsx): actions M#ActionMenuRenderer M#ActionMenuItem M#ActionAutoTrigger M#paramsPayload; label, icon, variant, size, visible and the host `disabled` verdict (objectui#11182) M#ActionMenuRenderer; the registration's inputs inside M#ActionMenuRenderer (objectui#11168 slice 1); [30] element:definition-list (ElementDefinitionListPropsSchema; L = objectui @b9814b334 packages/components/src/renderers/basic/data-list.tsx; the retired gate's quoted first line `const props = readProps<{` holds at L#props): items, columns (`=== 2`), inline, term, description L#DefinitionListRenderer (an item's `description` shown through L#toText: a string or number as text, an object as JSON; first cited at objectui @89cad75d55); the registration's number enum and optional `items` (objectui#11168 slice 2) at its `definition-list` registration in L; the designer's number control objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-config.ts#BLOCK_CONFIG; [31] element:repeater (ElementRepeaterPropsSchema; L = objectui @b9814b334 packages/components/src/renderers/basic/data-list.tsx; the quoted first line `const props = readProps<{` holds at L#props in L#RepeaterRenderer): object, filter, sort, limit, emptyText, divided, titleField, fields L#RepeaterRenderer; the binding L#dataBinding (useElementDataSource, objectui#11880, aaba8655a); resolved filter tokens L#filterScope; delivery objectui @b9814b334 packages/data-objectstack/src/index.ts#ObjectStackAdapter (translateFilterArray arm) and objectui @b9814b334 packages/data-objectstack/src/index.ts#serializeOrderBy; the registration wrapped by elementDataSourceBlock publishes no `object` input since objectui#12085 (ce991bd70); the registration's `object` required flag read at objectui @20c6d351a; [32] object-grid.aggregations[] (GridAggregationSchema): objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx#groupHeaders (useGroupedData) and objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx#serverGroupSource (useServerGroupHeaders); the grid's own function vocabulary objectui @89cad75d55 packages/plugin-grid/src/useGroupedData.ts#AggregationType (unchanged at objectui @b9814b334); [33] object-grid (ObjectGridPropsSchema, per key; E = objectui @eb7f586b packages/plugin-grid/src/ObjectGrid.tsx): columns, fields E#schemaFields; filter E#schemaFilterSource (toFilterNode); defaultFilters E#cols (legacy fallback); sort E#schemaSort; defaultSort E#cols; pagination, pageSize, showPagination E#lastFindParamsRef E#schemaPageSize E#paginationEnabled; searchableFields, showSearch E#trimmedSearch E#searchEnabled; rowHeight E#ObjectGrid (resolveRowHeightMode); grouping, aggregations E#grouping E#groupValueFormatter; rowColor E#getRowClassName; conditionalFormatting E#predicateFields E#rules; selection, selectable E#ObjectGrid; rowActions E#rowActionsList; batchActions, bulkActions E#declaredBulkActions; bulkActionDefs E#legacyBulkNames; navigation E#navigation; editable, singleClickEdit, resizable, resizableColumns, reorderableColumns E#dataTableSchema; frozenColumns E#effectiveFrozenColumns; showColumnTypeIcons E#fieldMeta; exportOptions, operations E#declared; label, title E#fileNameFor E#dataTableSchema; data, staticData E#getDataConfig; [#20694] description objectui @db11afd4967c packages/plugin-grid/src/ObjectGrid.tsx#resolvedDescription (drawn as `gridDescription`); emptyState objectui @db11afd4967c packages/plugin-grid/src/ObjectGrid.tsx#authoredEmptyState (DataEmptyState in renderedGridContent); keyboardNavigation 0 read points at objectui @db11afd4967c, 15 hit lines at objectui @ab1879721595 and at objectui @b9814b334 against 3 then 4 for the control `schema.editable` (the fourth objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx#carriesConcurrencyToken); [34] object-grid.description, object-grid.emptyState (B = objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx): description objectui @db11afd4967c packages/plugin-grid/src/ObjectGrid.tsx#resolvedDescription; emptyState title/message B#authoredEmptyTitle (resolveInlineI18nLabel, objectui#11227 carried by 6158e4c93; raw at objectui @89cad75d5570) drawn in B#renderedGridContent, link (objectui#12270, b434f5f47) B#renderedGridContent (EmptyStateLink); [35] object-grid.columns (ListViewSchema.shape.columns; A = objectui @ab1879721595 packages/plugin-grid/src/ObjectGrid.tsx): A#normalizeColumns (first-entry dispatch) A#cols A#fieldName (resolvesToDataColumn); the retired `colOverride?.options` read: A#groupValueFormatter A#rawOptions (objectui b0bf413, objectui#11544); the footer summary's off-contract column keys objectui @ab1879721595 packages/plugin-grid/src/useColumnSummary.ts#columnHints; [36] object-grid.fields (O = objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx): O#schemaFields O#fieldsToShow O#generateColumns; the host hand-off projection O#getSelectFields; [37] object-grid.filter: objectui @53ded82b packages/plugin-grid/src/ObjectGrid.tsx#ObjectGrid (toFilterNode before `$filter`); [38] object-grid.sort (S = objectui @53ded82b packages/plugin-grid/src/ObjectGrid.tsx): S#schemaSort S#cols (the fetch path's string arm and array arm) S#declaredSort (parseSchemaSort, `TableSortItem[]`); the registration's array input objectui @53ded82b packages/plugin-grid/src/index.tsx (`{ name: 'sort', type: 'array' }`); [39] object-grid.defaultSort (REMOVED, tombstone; D = objectui @190fbd01d packages/plugin-grid/src/ObjectGrid.tsx): D#cols (`$orderby` fallback) and D#declaredSort (`[schema.defaultSort]`); [40] object-grid.pagination (D = objectui @d18322415 packages/plugin-grid/src/ObjectGrid.tsx): pageSize D#lastFindParamsRef D#schemaPageSize D#pageSize; pageSizeOptions D#dataTableSchema; presence D#paginationEnabled; the registry input objectui @d18322415 packages/plugin-grid/src/index.tsx (`pagination`, type object); [41] object-grid members read at objectui @89cad75d55 (O = objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx): rowHeight O#resolveRowHeightMode; aggregations O#groupHeaders (useGroupedData) O#serverGroupSource (useServerGroupHeaders); conditionalFormatting O#getRowStyle (resolveConditionalFormatting); rowColor O#getRowClassName (useRowColor); selection and selectable O#ObjectGrid (the selection-mode branch) O#dataTableSchema (`selectable`), read by objectui @89cad75d55 packages/components/src/renderers/complex/data-table.tsx#resolveSelectionMode; rowActions O#rowActionsDeclared; bulkActions, batchActions O#declaredBulkActions (`batchActions ?? bulkActions`); bulkActionDefs O#legacyBulkNames (resolveBulkActions); [42] object-grid.navigation: objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx#navigation (useNavigationOverlay); [43] object-grid.keyboardNavigation (built by objectui 154075ab1, objectui#11068; declared ahead of its reader, which read nothing at objectui @db11afd4967c): objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx#dataTableSchema (`schema.keyboardNavigation ?? inlineEditable`) with objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx#inlineEditable; objectui @b9814b334 packages/components/src/renderers/complex/data-table.tsx#DataTableRenderer (default false, `role=\"grid\"`, the roving tabIndex), objectui @b9814b334 packages/components/src/renderers/complex/data-table.tsx#navigationTarget and objectui @b9814b334 packages/components/src/renderers/complex/data-table.tsx#handleCellKeyDown; [44] object-grid.resizableColumns (REMOVED, tombstone): objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx#dataTableSchema (`schema.resizable ?? schema.resizableColumns ?? true`); [45] object-grid.operations (GridOperationsSchema; O = objectui @89cad75d55 packages/plugin-grid/src/ObjectGrid.tsx): create O#dataTableSchema (showAddRow); update, delete O#wantDeleteAction; export O#handleExport O#dataTableSchema (exportable) O#exportEnabled; a declared block replaces the default O#explicitOperations; [46] object-grid.data: the registry input objectui @b9814b334 packages/plugin-grid/src/index.tsx#GRID_QUERY_INPUTS (`{ name: 'data', type: 'object' }`, held by gridDataInputContract.test.ts); re-read 2026-10-15, first cited sha-less; [47] object-metric.aggregate (ObjectMetricAggregateSchema; M = objectui @89cad75d55 packages/plugin-dashboard/src/ObjectMetricWidget.tsx): field, function M#computeOne; function also M#fieldUnitApplies (answersInFieldUnit) M#inferredFormat (min/max width); groupBy M#computeOne (objectAggregateSpecQuery; floored at `'_all'`) typed on M#ObjectMetricWidgetProps (`ChartAggregate['groupBy']`); objectui's unit-rule pin ObjectMetricWidget.countNotCurrency-10356.test.tsx mounts one tile per AggregationFunction member; [48] object-metric.trend (ObjectMetricTrendSchema; W = objectui @89cad75d55 packages/plugin-dashboard/src/): drawn in W MetricWidget.tsx#MetricWidget (`{value}%`, direction arrow), caption W MetricWidget.tsx#localizedTrendLabel (pickLocalized); declared on W MetricWidget.tsx#MetricWidgetProps, mirrored on W ObjectMetricWidget.tsx#ObjectMetricWidgetProps; replaced by a derived trend in W ObjectMetricWidget.tsx#effectiveTrend; [49] object-metric.drillDown (ObjectMetricDrillDownSchema; A = objectui @ab1879721595): enabled A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#drillEnabled (isDrillEnabled); title A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#drawerTitle (resolveDrillTitle against an empty event); target, columns, maxRows A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#drillDrawer (DrillDownDrawer); `filter` / `mode` refused as objectui's own A packages/types/src/data-display.ts#ObjectMetricDrillDownConfig refuses them; measured writers, objectui's drill-down member pins A packages/plugin-dashboard/src/__tests__/objectMetricDrillDownMembers-8071.test.tsx and A packages/plugin-dashboard/src/__tests__/ObjectMetricWidget.drillRoutedToSharedDrawer-8970.test.tsx; [50] object-metric.drillDown.report (R = objectui @2e818d0b51ec packages/plugin-dashboard/src/): handed verbatim in R ObjectMetricWidget.tsx#drillDrawer; drawn when R DrillDownDrawer.tsx#isDatasetBoundReport holds (R DrillDownDrawer.tsx#isReportDrill), joining the metric filter into `runtimeFilter` (R DrillDownDrawer.tsx#body); typed `SpecReportInput` in objectui @2e818d0b51ec packages/types/src/data-display.ts; the fork measured at objectui @ab1879721595, both files byte-identical at objectui main 2abec3a96; [51] object-metric.compareTo (ObjectMetricCompareToSchema; A = objectui @ab1879721595): A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#comparisonFilter (second aggregate over shiftFilterByCompareTo) and A packages/plugin-dashboard/src/ObjectMetricWidget.tsx#derivedTrend (compareToTrendLabelKey); both dispatch on `kind === 'previousYear'` in A packages/core/src/utils/compare-to.ts#shiftFilterByCompareTo and A packages/core/src/utils/compare-to.ts#compareToTrendLabelKey; `dimension` \"deliberately never read on this path\" in that module's header; [52] object-metric (ObjectMetricPropsSchema): objectui @eb7f586b packages/plugin-dashboard/src/ObjectMetricWidget.tsx#ObjectMetricWidgetProps (the complete destructured read set); [53] object-metric.icon (B = objectui @b9814b334 packages/plugin-dashboard/src/): published by B index.tsx#ObjectMetricBlock (`{ name: 'icon', type: 'string' }`); destructured and forwarded by B ObjectMetricWidget.tsx#ObjectMetricWidget; resolved and drawn by B MetricWidget.tsx#MetricWidget (getLazyIcon, guarded on a string); vocabulary objectui @b9814b334 packages/components/src/lib/lazy-icon.tsx#getLazyIcon; not B MetricCard.tsx (off this key's path); [54] object-metric.filter: the analytics wire lowering objectui @53ded82b packages/data-objectstack/src/index.ts#lowerAnalyticsFilterForWire (objectui#7754); before it the adapter at objectui @a472b07 posted an array verbatim (a 400, #15828); [55] object-kanban.columns[] lane (ObjectKanbanLaneSchema; K = objectui @89cad75d55 packages/plugin-kanban/src/): id K index.tsx#bucketCardsIntoColumns; title K ObjectKanban.tsx#localizeColumn; cards K index.tsx#bucketCardsIntoColumns (kept ahead of the bucketed records); limit K KanbanImpl.tsx#isLimitExceeded; className K KanbanImpl.tsx#KanbanColumnView; collapsed K KanbanImpl.tsx#isColumnCollapsed; [56] object-kanban (ObjectKanbanPropsSchema; E = objectui @eb7f586b packages/plugin-kanban/src/ObjectKanban.tsx): columns E#effectiveColumns; filter E#fetchData (`$filter`); data E#boundData; cardTitle, titleField E#explicitTitleField; cardFields E#explicitCardFields; swimlaneField, grouping E#effectiveSwimlaneField; coverImageField, conditionalFormatting via objectui @eb7f586b packages/plugin-kanban/src/index.tsx#KanbanRenderer (the spread of the authored bag); limit objectui @b9814b334 packages/plugin-kanban/src/ObjectKanban.tsx#query (`$top: resolveRowLimit(schema.limit, DEFAULT_KANBAN_FETCH_BATCH_SIZE)`), first re-read at objectui @87af769e9 where `$top: schema.limit ?? DEFAULT_KANBAN_LIMIT` had become resolveRowLimit; [57] object-kanban.columns (the first-entry dispatch): objectui @89cad75d55 packages/plugin-kanban/src/ObjectKanban.tsx#effectiveColumns (string arm only without `groupBy`); [58] object-kanban.filter: objectui @53ded82b packages/plugin-kanban/src/ObjectKanban.tsx#ObjectKanban (`$filter: schema.filter`, verbatim, lowered by ObjectStackAdapter.convertQueryParams through translateFilterArray); [59] object-kanban.limit (B = objectui @b9814b334): query B packages/plugin-kanban/src/ObjectKanban.tsx#query (`$top: resolveRowLimit(schema.limit, DEFAULT_KANBAN_FETCH_BATCH_SIZE)`) with B packages/plugin-kanban/src/ObjectKanban.tsx#DEFAULT_KANBAN_FETCH_BATCH_SIZE and the resolved filter B packages/plugin-kanban/src/ObjectKanban.tsx#filterScope; mapping B packages/plugin-kanban/src/index.tsx#OBJECT_KANBAN_DATA_SOURCE (`limit: 'limit'`); type B packages/types/src/objectql.ts#ObjectKanbanSchema (`limit?: number`); docs B content/docs/plugins/plugin-kanban.mdx (`limit: 250` snippet and Properties row); precedence B packages/react/src/element-data-source/ElementDataSourceGate.tsx#useElementDataSourceSchema (binding cap over this key; a view's pagination.pageSize only when unset) and B packages/react/src/element-data-source/ElementDataSourceGate.tsx#isUsableRowLimit; the saved-view fallback B packages/core/src/data-scope/element-data-source.ts#savedViewRawLimit; first re-read at objectui @87af769e9 2026-09-20; [60] object-master-detail-form (ObjectMasterDetailFormPropsSchema): objectui @eb7f586b packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailForm; auto-derivation objectui @eb7f586b packages/plugin-form/src/deriveMasterDetail.ts; the `formType` pair objectui's MasterDetailFormSchema declares; [61] object-kanban.quickAdd (RETIRED, tombstone; K = objectui @b9814b334 packages/plugin-kanban/src/): K index.tsx#KanbanRenderer passes `quickAdd` / `onQuickAdd` (the host-mounted React component); gated on both in K KanbanImpl.tsx#KanbanColumnView; K KanbanBoardCore.tsx#KanbanBoardCoreProps reads neither off `schema` (objectui#11234); K ObjectKanban.tsx#ObjectKanban names `quickAdd` and `onQuickAdd` 2 times each (both in comments) against 11 for `onCardClick` (method: occurrences in that file, re-counted 2026-10-15); no `kanban-ui` registration at that sha (objectui#8257; the name survives only in tests and the changelog); through objectui @db11afd49 the board's spread forwarded the key; [62] object-kanban.conditionalFormatting (A = objectui @ab1879721595): A packages/plugin-kanban/src/KanbanBoardCore.tsx#processedColumns hands it to the board; A packages/plugin-kanban/src/KanbanImpl.tsx#getCardStyles evaluates it through A packages/core/src/evaluator/listConditional.ts#resolveConditionalFormatting, the evaluator of A packages/plugin-grid/src/ObjectGrid.tsx#getRowStyle; objectui's declaration A packages/types/src/zod/objectql.zod.ts#KanbanConditionalFormattingRuleSchema and A packages/types/src/objectql.ts#KanbanConditionalFormattingRule (objectui#11522, landed by objectui#11532 c73cdb5695); the stored-dialect arms in A packages/plugin-kanban/src/KanbanImpl.tsx#getCardStyles; blank-predicate fallback A packages/core/src/evaluator/listConditional.ts#evalRowPredicate; the four reader files byte-identical at objectui main 2e818d0b51; the writer census also read objectui at main; [63] object-kanban.navigation (K = objectui @b9814b334 packages/plugin-kanban/src/ObjectKanban.tsx): K#navConfig (`schema.navigation ?? { mode: 'drawer' }`) K#navigation (useNavigationOverlay) K#boardView (card click) K#renderRecordOverlay (NavigationOverlay); first re-derived at objectui @87af769e9, where the `(schema as any)` cast was still spelled; [64] object-calendar flat field keys (OBJECT_CALENDAR_FLAT_FIELD_GUIDANCE): objectui @b9814b334 packages/plugin-calendar/src/ObjectCalendar.tsx#getCalendarConfig (the backward-compat flat fallback); re-read 2026-10-15, first cited sha-less; [65] object-calendar (ObjectCalendarPropsSchema; C = objectui @eb7f586b packages/plugin-calendar/src/ObjectCalendar.tsx): calendar C#getCalendarConfig; defaultView C#schemaDefaultView; locale, loading via the registry shell objectui @eb7f586b packages/plugin-calendar/src/index.tsx; [66] object-calendar.calendar (CalendarConfigSchema by reference; C = objectui @89cad75d55 packages/plugin-calendar/src/ObjectCalendar.tsx): C#getCalendarConfig returns the block; its five bindings read in C#queryFilter, C#handleEventDropDefault and C#submitQuickCreate; [67] object-calendar.filter: objectui @53ded82b packages/plugin-calendar/src/ObjectCalendar.tsx#fetchData (`$filter: schema.filter`, verbatim); [68] object-tree.navigation: objectui @89cad75d55 packages/plugin-tree/src/ObjectTree.tsx#navigation (useNavigationOverlay); [69] object-calendar.sort: objectui @53ded82b packages/plugin-calendar/src/ObjectCalendar.tsx#fetchData (`$orderby: convertSortToQueryParams(schema.sort)`), whose sink objectui @53ded82b packages/core/src/utils/sort-query.ts#convertSortToQueryParams still lowered the string clause there; no `sort` input on objectui @53ded82b packages/plugin-calendar/src/index.tsx; [70] object-timeline flat config keys (OBJECT_TIMELINE_FLAT_CONFIG_GUIDANCE): the backward-compat flat rung (with the `dateField` alias) in objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#startDateField and its siblings; emitted by objectui @b9814b334 packages/plugin-list/src/ListView.tsx#viewComponentSchema (`case 'timeline'`); re-read 2026-10-15, first cited sha-less; [71] object-calendar.navigation (C = objectui @b9814b334 packages/plugin-calendar/src/ObjectCalendar.tsx): C#navConfig (`schema.navigation ?? { mode: 'drawer' }`) C#navigation (useNavigationOverlay) C#calendarView (event click) C#renderRecordOverlay (NavigationOverlay); [72] object-timeline.mapping (ObjectTimelineMappingSchema; A = objectui @ab1879721595 packages/plugin-timeline/src/ObjectTimeline.tsx; unchanged at objectui main 94985a92ba): title A#titleField; date A#startDateField; description A#descField; variant A#variantField; declared on A#ObjectTimelineProps (`mapping`) and A#TimelineMappingSchema; [73] object-timeline.items[] arms (R = objectui @2e818d0b51ec packages/plugin-timeline/src/renderer.tsx; unchanged at objectui main 2abec3a96): gantt bar startDate / endDate R#dimensions R#calculateDateRange, variant and title in R#TimelineRenderer (the bar and its tooltip); feed entry time R#dateLabel and title, description, variant, icon, content (renderChildren), className in R#TimelineRenderer; gantt row label R#TimelineRenderer (TimelineGanttLabel), items R#classifyGanttRows; vocabulary objectui @2e818d0b51ec packages/types/src/data-display.ts#TimelineItemVariant; element shape and refinement objectui @2e818d0b51ec packages/types/src/zod/data-display.zod.ts#TimelineItemSchema and objectui @2e818d0b51ec packages/types/src/zod/data-display.zod.ts#timelineItemsFitVariant; [74] object-form.layout retired values `inline` / `grid` (OBJECT_FORM_LAYOUT_RETIRED; P = objectui @f8a9d0fb0 packages/plugin-form/src/): folded to 'vertical' in P ObjectForm.tsx#SimpleObjectForm; only 'vertical' / 'horizontal' passed through by P ObjectForm.tsx#drawerLayout, ObjectForm.tsx#modalLayout, DrawerForm.tsx#formLayout, ModalForm.tsx#formLayout; 'vertical' hard-coded in P TabbedForm.tsx#TabbedForm, SplitForm.tsx#panes, WizardForm.tsx#WizardForm; [75] object-form.mobile (ObjectFormMobileSchema; F = objectui @89cad75d55 packages/plugin-form/src/ObjectForm.tsx): F#mobileOpts (the flat arm); stickyActions F#formSchema; stepper, stepperMinFields, stepperFieldsPerStep F#stepperMode; fullscreenLongText F#fieldsWithMobile; the `data-mobile-form` marker in F#SimpleObjectForm; [76] object-form.fields and object-master-detail-form.fields (formFieldNameList): objectui @ab1879721595 packages/plugin-form/src/MasterDetailForm.tsx#parentSchema (hands `fields` over verbatim), read by objectui @ab1879721595 packages/plugin-form/src/ObjectForm.tsx#fieldsToShow and objectui @ab1879721595 packages/plugin-form/src/flatFields.ts#buildFlatFields (a stored `{ name }` entry drawn by name; any other object entry warned by warnUnresolvedTopLevelField); unchanged at objectui main 94985a92ba; the retired inline field entry an author was taught by objectui @ab1879721595 skills/objectui/guides/page-builder.md (its object-form example; first cited sha-less); [77] object-form.customFields[] `grid` widget keys (minRows, maxRows, allowAdd, allowDelete, allowReorder, totalField, addLabel, sortField; W = objectui @9dfaca654311 packages/fields/src/widgets/GridField.tsx): declared on objectui @9dfaca654311 packages/types/src/field-types.ts#GridFieldMetadata, carried by objectui @9dfaca654311 packages/types/src/form.ts#FormField, mirrored in objectui @9dfaca654311 packages/types/src/zod/form.zod.ts#FormFieldSchema; read W#cfg W#allowAdd W#removeRow (minRows) W#totalField W#showTotal W#emit (sortField) W#GridFieldBody (maxRows, allowReorder, addLabel); objectui#11610 (merge 2abec3a96c) camelCased them; the parent-field `totalField` hand-off objectui @9dfaca654311 packages/plugin-form/src/LineItemsPanel.tsx#gridField and objectui @9dfaca654311 packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailLines; the writer shape (one `grid` field carrying all eight camelCase keys) objectui @9dfaca654311 examples/schema-catalog/src/schemas/fields-grid/line-items-grid.json; [78] object-form.customFields[] retired snake_case `grid` keys (OBJECT_FORM_GRID_WIDGET_SNAKE_KEYS): objectui @9dfaca654311 packages/types/src/field-types.ts#GRID_FIELD_RETIRED_KEYS; refused by objectui @9dfaca654311 packages/fields/src/widgets/GridField.tsx#GridField, tombstoned on objectui @9dfaca654311 packages/types/src/field-types.ts#GridFieldMetadata and objectui @9dfaca654311 packages/types/src/form.ts#FormField, named in objectui @9dfaca654311 packages/types/src/zod/form.zod.ts#FormFieldSchema (retiredGridFieldKey); [79] object-form.customFields[].validation: objectui @2e818d0b51ec packages/components/src/renderers/form/form.tsx#rules (inside renderFormField: minLength/maxLength/min/max spread as `{ value, message }`, `required` read only as a message string); objectui's declaration objectui @2e818d0b51ec packages/types/src/form.ts#FieldValidationRules; [80] object-timeline.navigation: objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#navigation (useNavigationOverlay) and objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#effectiveSchema (entry click, overlay); re-read 2026-10-15, first cited sha-less, when the read still spelled `(schema as any).navigation`; [81] object-form.customFields[].options[] (buildObjectFormRuntimeOption; F = objectui @2e818d0b51ec packages/components/src/renderers/form/form.tsx): label, value F#BuiltinSelectControl and objectui @2e818d0b51ec packages/core/src/evaluator/optionRules.ts#optionDisplayLabel (the four option widgets); visibleWhen F#cascade (resolveCascadingOptions; each widget's useCascadingOptions); description objectui @2e818d0b51ec packages/fields/src/widgets/LookupField.tsx#filteredOptions; `value` a runtime value: F#BuiltinSelectControl (matchOptionValue), objectui @2e818d0b51ec packages/types/src/zod/form.zod.ts#SelectOptionSchema (deliberate divergence comment), objectui @2e818d0b51ec packages/plugin-designer/src/ObjectManager.tsx#formSchema (writes `{ label, value }` pairs); unchanged at objectui main fd060f076; [82] object-form.customFields[] and the inline section entry (buildObjectFormRuntimeField; F = objectui @2e818d0b51ec packages/components/src/renderers/form/form.tsx, W = objectui @2e818d0b51ec packages/fields/src/widgets/): merge objectui @2e818d0b51ec packages/plugin-form/src/customFieldsMerge.ts#mergeCustomFields from objectui @2e818d0b51ec packages/plugin-form/src/ObjectForm.tsx#generateField; carrier F#builtinBranchHasNoControl (`field.field || field`); field row F#renderFormField (name, label, description, type, required, disabled, readonly, hidden, colSpan via F#colSpanClass), widget F#resolvedType, validation F#rules, the three `*When` rules F#ruleState, placeholder and inputType F#builtinBranchHasNoControl, options and dependsOn F#cascade, multiple F#resolvedType; layout objectui @2e818d0b51ec packages/plugin-form/src/autoLayout.ts#resolveColSpan (span, colSpan) and objectui @2e818d0b51ec packages/plugin-form/src/fieldGroups.ts#deriveFieldGroupSections (group); widgets W TextAreaField.tsx#rows, FileField.tsx#multiple (accept, multiple), VectorField.tsx#dimensions, LookupField.tsx#referenceTo, NumberField.tsx#NumberField (min, max), F#renderFieldComponent (minLength, maxLength), FormulaField.tsx#returnType, SummaryField.tsx#summaryType, GridField.tsx#allColumns (columns); read and refused: visibleOn F#ruleState, condition F#legacyConditionCel, id F#fieldKey; a measured writer, the object-manager create / edit dialog (a `formType: 'modal'` block): objectui @b9814b334 packages/plugin-designer/src/ObjectManager.tsx#formSchema (first cited sha-less); [83] object-form / object-master-detail-form sections[].fields[] `{ field }` entry (buildObjectFormSectionFieldEntry): objectui @2e818d0b51ec packages/plugin-form/src/sectionFields.ts#resolveSectionEntry (names an object field by `field`, every other key overrides its generated definition; label/placeholder/helpText copied as they stand); [84] object-form / object-master-detail-form sections[] (buildObjectFormSection; F = objectui @2e818d0b51ec packages/plugin-form/src/ObjectForm.tsx): handed over verbatim by objectui @2e818d0b51ec packages/plugin-form/src/MasterDetailForm.tsx#parentSchema; name, label F#sectionCtx (heading) F#inertPredicateSections (per-formType maps); collapsible, collapsed F#collapse (resolveSectionCollapse); visibleWhen F#sectionCtx (divider-row predicate); columns F#secCols F#clampCol (a NUMBER only); pane objectui @2e818d0b51ec packages/plugin-form/src/SplitForm.tsx#paneOf; the inline runtime field drawn as it stands in objectui @2e818d0b51ec packages/plugin-form/src/sectionFields.ts#resolveSectionEntry; objectui's own declaration objectui @2e818d0b51ec packages/types/src/objectql.ts#ObjectFormSection; [85] object-form (ObjectFormPropsSchema: the UNION of `schema.*` reads of the simple form and the sub-forms it forwards the bag into): objectui @eb7f586b packages/plugin-form/src/ObjectForm.tsx#ObjectForm, with TabbedForm, WizardForm, SplitForm, DrawerForm, ModalForm under objectui @eb7f586b packages/plugin-form/src/; `layout` `inline` / `grid` folded to `vertical` there while the registry inputs and the designer palette offered them; [86] object-form.fields (the `{ name }` entry retired from the authoring faces by objectui#11550): a census of objectui @ab1879721595 found it written only by fixtures probing the stored read and the refusal; [87] object-form.customFields: objectui @2e818d0b51ec packages/plugin-form/src/customFieldsMerge.ts#mergeCustomFields (merged over the generated fields); at objectui @2e818d0b51ec the open runtime field spelled the eight `grid` widget keys in snake_case, camelCased by objectui#11610 (carried at objectui @9dfaca654311); [88] object-form.contentLayout: objectui @89cad75d55 packages/plugin-form/src/ModalForm.tsx#renderContent (`schema.contentLayout === 'tabbed' && groups.length > 1`), declared on objectui @89cad75d55 packages/plugin-form/src/ModalForm.tsx#ModalFormSchema; [89] object-form.submitBehavior: objectui @89cad75d55 packages/plugin-form/src/ObjectForm.tsx#handleSubmit and objectui @89cad75d55 packages/plugin-form/src/WizardForm.tsx#handleStepSubmit (switch on `kind`), redirect `url` judged by objectui @89cad75d55 packages/plugin-form/src/submitRedirect.ts#resolveSubmitRedirect (FormViewSchema.safeParse); [90] object-form.navigateOnSuccess: objectui @89cad75d55 packages/plugin-form/src/successBehavior.ts#resolveSuccessNavigate, called from objectui @89cad75d55 packages/plugin-form/src/ObjectForm.tsx#handleSubmit and objectui @89cad75d55 packages/plugin-form/src/WizardForm.tsx#handleStepSubmit; a refused value reported on the success toast in objectui @89cad75d55 packages/plugin-form/src/ObjectForm.tsx#handleSubmit; [91] object-master-detail-form.details[] (the eleven entry keys): objectui @31971ff1e28f packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailDetailConfig and every `d.KEY` read in objectui @31971ff1e28f packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailLines; re-read at objectui @89cad75d5570 for #21589; [92] object-master-detail-form.details[].sortField (REMOVED, tombstone): objectui @89cad75d5570 packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailDetailConfig (no `sortField` member), derived by objectui @89cad75d5570 packages/plugin-form/src/deriveMasterDetail.ts#deriveDetail (SORT_FIELD_NAMES) and handed to the grid as `sort_field` in objectui @89cad75d5570 packages/plugin-form/src/MasterDetailForm.tsx#MasterDetailLines; at objectui @9dfaca654311 the same hand-off spells `sortField` (objectui#11610) from objectui @9dfaca654311 packages/plugin-form/src/deriveMasterDetail.ts#deriveDetail; an entry the renderer does not resolve loads no child schema (objectui @9dfaca654311 packages/plugin-form/src/MasterDetailForm.tsx#entries); [93] object-master-detail-form.sections, .fields: objectui @2e818d0b51ec packages/plugin-form/src/MasterDetailForm.tsx#parentSchema (handed to the parent object-form verbatim); [94] object-map flat config keys (OBJECT_MAP_FLAT_CONFIG_GUIDANCE): objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#getMapConfig (branch 2) and objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#warnOnShadowedFlatMapKeys and objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#FLAT_MAP_CONFIG_KEYS; emitted by objectui @b9814b334 packages/plugin-view/src/ObjectView.tsx#ObjectView and objectui @b9814b334 packages/plugin-list/src/ListView.tsx#viewComponentSchema (`case 'map'`); re-read 2026-10-15, first cited sha-less at the then pin; [95] object-map (ObjectMapPropsSchema, per key; P = objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx, C = objectui @b9814b334 packages/core/src/utils/record-source.ts, I = objectui @b9814b334 packages/plugin-map/src/index.tsx): data P#getDataConfig C#resolveRecordSourceConfig (rung 1; the deleted array head and its carriers are recorded in the docblock above P#FLAT_MAP_CONFIG_KEYS); staticData C#resolveRecordSourceConfig (rung 2); objectName C#resolveRecordSourceConfig (rung 3) P#navigation P#warnOnLegacyFilterMapConfig P#warnOnTopLevelStyleUrl P#warnOnShadowedFlatMapKeys (cache keys) P#recordSourceObjectName (useSettledSchema); filter P#queryFilter P#fetchData (`$filter` on both fetches); sort P#fetchData (convertSortToQueryParams); map P#getMapConfig (branch 1; validates against ObjectMapConfigSchema) I#ObjectMapRenderer (its registration's `map` input); mapStyle P#getMapConfig (`schema.mapStyle || schema.map?.style`) I#ObjectMapRenderer; navigation P#navigation I#ObjectMapRenderer; enableClustering P#clusteredData I#ObjectMapRenderer; measured and not declared: style P#warnOnTopLevelStyleUrl (read only to say it is not a map style); [96] object-map.filter: objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#queryFilter (useResolvedFilter) and objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#fetchData (`$filter` on the inline and the object fetch); the registration's `filter` input objectui @b9814b334 packages/plugin-map/src/index.tsx#ObjectMapRenderer; [97] object-map.sort: objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#fetchData (convertSortToQueryParams to `$orderby`, both fetches); the registration's array-form `sort` input (objectui#8220) objectui @b9814b334 packages/plugin-map/src/index.tsx#ObjectMapRenderer; [98] object-map.navigation: objectui @89cad75d55 packages/plugin-map/src/ObjectMap.tsx#navigation (hands `schema.navigation` to useNavigationOverlay) and objectui @89cad75d55 packages/react/src/hooks/useNavigationOverlay.ts#useNavigationOverlay (`navigation?.mode ?? 'page'`); [99] object-gantt flat config keys (OBJECT_GANTT_FLAT_CONFIG_GUIDANCE): objectui @b9814b334 packages/plugin-gantt/src/ObjectGantt.tsx#FLAT_GANTT_CONFIG_KEYS and objectui @b9814b334 packages/plugin-gantt/src/ObjectGantt.tsx#getGanttConfig (branch 2 reads them; a present `gantt` block is taken whole and the flat keys beside it named as ignored); re-read 2026-10-15, first cited sha-less at the then pin; [100] object-gantt.markers (objectGanttMarker): G = objectui @ab1879721595 packages/plugin-gantt/src/GanttView.tsx: objectui @ab1879721595 packages/plugin-gantt/src/ObjectGantt.tsx#ganttView (hands `schema.markers` to GanttView verbatim); date G#markers (time-zone re-base) G#resolvedMarkers (axis mapping, drops unparsable or out-of-range dates); color G#resolvedMarkers (`m.color || 'hsl(var(--primary))'`); drawn in G#GanttView and in G#buildExportSvg; the declaration taken: objectui @ab1879721595 packages/types/src/objectql.ts#ObjectGanttSchema and objectui @ab1879721595 packages/types/src/zod/objectql.zod.ts#ObjectGanttSchema (`markers`); unchanged at objectui main 94985a92ba; [101] object-gantt (ObjectGanttPropsSchema, per key; P = objectui @b9814b334 packages/plugin-gantt/src/ObjectGantt.tsx, C = objectui @b9814b334 packages/core/src/utils/record-source.ts): data P#rawDataConfig C#resolveRecordSourceConfig (rung 1); staticData C#resolveRecordSourceConfig (rung 2); objectName (rung 3) P#persistLayoutKey P#navigation; filter P#queryFilter P#reload (`$filter`); sort P#reload (convertSortToQueryParams to `$orderby`); gantt P#getGanttConfig (branch 1, validated against the spec's GanttConfigSchema) and objectui @b9814b334 packages/plugin-gantt/src/index.tsx#ObjectGanttRenderer (its registration's `gantt` object input); navigation P#navConfig P#navigation; label P#ganttView (resolveInlineI18nLabel, export file-name chain); skipWeekends, holidays P#workingCalendar; persistLayout, viewName P#persistLayoutKey; markers, criticalPath, showBaselines, readOnly, mobileReadOnly P#ganttView, readOnly also P#renderRecordOverlay; measured and not declared: title (absent from the P#ganttView export-name chain), row cap (P#reload spreads nonGridRowCeilingQuery, marked not authorable), search and searchableFields P#searchTerm P#reload (host-generated by objectui @b9814b334 packages/plugin-list/src/ListView.tsx#viewComponentSchema, its `case 'gantt'` arm); [102] object-gantt.navigation: objectui @89cad75d55 packages/plugin-gantt/src/ObjectGantt.tsx#navConfig (`schema.navigation ?? { mode: 'drawer' }`) and objectui @89cad75d55 packages/plugin-gantt/src/ObjectGantt.tsx#navigation (useNavigationOverlay); [103] object-tree flat config keys (OBJECT_TREE_FLAT_CONFIG_GUIDANCE: parentField, labelField, titleField, fields, defaultExpandedDepth): objectui @b9814b334 packages/plugin-tree/src/ObjectTree.tsx#getTreeConfig (reads the flat spellings ahead of the `tree` block; the `schema.titleField` rung's retirement is recorded in its docblock above `fieldKey`, objectui#8841), objectui @b9814b334 packages/plugin-list/src/ListView.tsx#viewComponentSchema (its `case 'tree'` arm emits parentField, `labelField: treeCfg.labelField || 'name'`, fields, defaultExpandedDepth and no titleField since objectui 3fd862510), objectui @b9814b334 packages/plugin-tree/src/index.tsx#treeInputs (`{ name: 'tree', type: 'object' }`, no flat input); [104] object-tree (ObjectTreePropsSchema, per key; P = objectui @b9814b334 packages/plugin-tree/src/ObjectTree.tsx, C = objectui @b9814b334 packages/core/src/utils/record-source.ts): data P#dataConfig (resolveRecordSourceConfig with the `view-data` arm) and C#resolveRecordSourceConfig (rung 1, authoredDataIsOnTheDeclaredArm); staticData C#resolveRecordSourceConfig (rung 2); objectName (rung 3) P#headerObjectName P#navigation P#renderRecordOverlay (each behind resolveRecordSourceObjectName) P#parentField (detectParentField); filter P#queryFilter (useResolvedFilter) P#fetchData (`$filter` on the object fetch and on the inline ValueDataSource query); tree P#getTreeConfig and objectui @b9814b334 packages/plugin-tree/src/index.tsx#treeInputs; navigation P#navigation (useNavigationOverlay); host-prop `data` (not the authored key) P#passed; measured and not declared: sort (no `$orderby` in P#fetchData), row cap (P#fetchData spreads nonGridRowCeilingQuery); [105] object-tree.objectName (optional because no ElementDataSourceGate wiring): objectui @b9814b334 packages/plugin-tree/src/index.tsx#ObjectTreeRenderer has 0 occurrences of `ElementDataSourceGate` (re-counted 2026-10-15), against controls objectui @b9814b334 packages/plugin-gantt/src/index.tsx#ObjectGanttRenderer, packages/plugin-grid/src/index.tsx, packages/plugin-calendar/src/index.tsx (3 each) and packages/plugin-map/src/index.tsx#ObjectMapRenderer (4); method: occurrences of the identifier in each `src/index.tsx`; [106] object-timeline (ObjectTimelinePropsSchema, per key; P = objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx, R = objectui @b9814b334 packages/plugin-timeline/src/renderer.tsx, I = objectui @b9814b334 packages/plugin-timeline/src/index.tsx): objectName P#ObjectTimeline (fetch gate) P#useSettledSchema P#fetchesForItself P#invalidationNonce P#fetchData P#handleRefresh P#effectiveItems P#navigation; timeline P#timelineConfig; filter P#queryFilter P#filterKey P#fetchData; sort P#sortKey P#fetchData (convertSortToQueryParams); limit P#fetchData (resolveRowLimit) P#DEFAULT_TIMELINE_LIMIT P#describeRefusedRowLimit; items P#hasInlineItems P#fetchesForItself P#effectiveItems P#hasAuthoredItems; data P#hasInlineData P#fetchesForItself P#rawData; descriptionField P#descField; mapping P#titleField P#startDateField P#descField P#variantField; variant P#hasAuthoredItems (the `timeline-unsupported-variant` refusal, objectui#6655) and I#OBJECT_TIMELINE_INPUTS; navigation P#navigation P#effectiveSchema; dateFormat, rowLabel, minDate, maxDate R#TimelineRenderer (rowLabel and minDate/maxDate in its gantt branch, R#findUnusableGanttDate) off P#effectiveSchema; measured and not declared: bind P#boundData (useDataScope), className P#effectiveSchema; [107] object-timeline.data (read off React props, not `schema`; the prop channel is SchemaRenderer's `properties.*` hoist, objectui @b9814b334 packages/react/src/SchemaRenderer.tsx#SchemaRenderer, with `object-timeline` absent from objectui @b9814b334 packages/core/src/utils/record-source.ts#RECORD_SOURCE_DATA_ARM_BY_TYPE): objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#hasInlineData (loading seed), objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#fetchesForItself (the query skip the fetch effect reads), objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#rawData (row source `(props as any).data || boundData || fetchedData`), objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#effectiveItems (the `timeline` field bindings a fetched row takes); [108] object-timeline.items: objectui @2e818d0b51ec packages/types/src/data-display.ts#TimelineFeedItem and objectui @2e818d0b51ec packages/types/src/data-display.ts#TimelineGanttItem (the declared authored entry, ruled on objectui#6356), handed to the rail verbatim at objectui @2e818d0b51ec packages/plugin-timeline/src/ObjectTimeline.tsx#effectiveItems (`if (schema.items) return schema.items`); [109] record:reference_rail, record:alert, record:quick_actions, record:history, record:line_items (rows): key sets measured from the renderers' read points; the per-key read points are recorded under each props schema below; [110] record:approval_decision (row, EMPTY key set): objectui @d03b022 packages/app-shell/src/views/approval-decision/ApprovalDecisionPanel.tsx#ApprovalDecisionRenderer (landed in objectui a368ccb, module-internal at d03b022; discards `schema`, draws from the record context); [111] record:attachments (row, EMPTY key set): objectui @47b1f0bb71 packages/app-shell/src/views/record-attachments-renderer.tsx#RecordAttachmentsRenderer (registered as `attachments` in the `record` namespace; discards `schema`); [112] cloud-connection:panel, marketplace:installed-list (rows, EMPTY key sets): objectui @b9814b334 packages/app-shell/src/console/cloud-connection/CloudConnectionPanel.tsx#CloudConnectionPanel and objectui @b9814b334 packages/app-shell/src/console/marketplace/InstalledListWidget.tsx#InstalledList (each registration is `() => `; re-read 2026-10-15, first measured sha-less at the then pin); [113] mcp:connect-agent (row, EMPTY key set): objectui @b9814b334 packages/app-shell/src/console/connect/ConnectAgentWidget.tsx#ConnectAgent (registration `() => `; re-read 2026-10-15, first measured sha-less at the then pin); [114] element:definition-list, element:repeater (rows: the three-part string-arm evidence): objectui @b9814b334 packages/components/src/renderers/basic/data-list.tsx#DefinitionListRenderer and objectui @b9814b334 packages/components/src/renderers/basic/data-list.tsx#RepeaterRenderer (both registered in the `element` namespace), objectui @b9814b334 packages/core/src/registry/public-blocks.ts#PUBLIC_BLOCKS (publication), objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-types.ts#BLOCK_TYPE_META (palette), objectui @b9814b334 packages/app-shell/src/views/metadata-admin/previews/block-config.ts#BLOCK_CONFIG (each block's inspector); [115] action:button, action:group, action:menu, action:icon (rows): objectui @b9814b334 packages/core/src/registry/public-blocks.ts#PUBLIC_BLOCKS (the four `action:*` members), registered under objectui packages/components/src/renderers/action/ in the `action` namespace; [116] object-map, object-gantt, object-tree (row key sets; per-key read points under each props schema): objectui @b9814b334 packages/plugin-map/src/index.tsx#ObjectMapRenderer, objectui @b9814b334 packages/plugin-map/src/ObjectMap.tsx#ObjectMap, objectui @b9814b334 packages/plugin-gantt/src/index.tsx#ObjectGanttRenderer, objectui @b9814b334 packages/plugin-gantt/src/ObjectGantt.tsx#ObjectGantt, objectui @b9814b334 packages/plugin-tree/src/index.tsx#ObjectTreeRenderer, objectui @b9814b334 packages/plugin-tree/src/ObjectTree.tsx#ObjectTree; [117] object-timeline (row key set; per-key read points under ObjectTimelinePropsSchema): objectui @b9814b334 packages/plugin-timeline/src/index.tsx#ObjectTimelineRenderer (the `object-timeline` and `timeline` registrations), objectui @b9814b334 packages/plugin-timeline/src/ObjectTimeline.tsx#ObjectTimeline, objectui @b9814b334 packages/plugin-timeline/src/renderer.tsx#TimelineRenderer; [118] EXPRESSION_BINDABLE_TEXT_KEYS_BY_COMPONENT rows statistic, card, button (the top-level text keys each renderer reads back; R = objectui @82a9417 packages/components/src/renderers/, re-verified identical at objectui 6c68b13 on 2026-08-18): statistic `label`, `value`, `description` R data-display/statistic.tsx#StatisticRenderer; card `title`, `description` R layout/card.tsx#CardRenderer; button `label` R form/button.tsx#ButtonRenderer; the deliberate `text` omission, `schema.content || schema.value`, at its `text` registration in R basic/text.tsx; [119] PageComponent.dataSource, the PLANNED API binding (ElementApiDataSourceSchema; its record is this file's `_note`; R = objectui @7578323a544e packages/core/src/): `read.url`'s refusal of a `./` path, measured against the console's `apiBase` promotion of a root-relative `/api/…` path only, R actions/ActionRunner.ts#navigateTo; `read.method` GET alone because every read (find, findOne, aggregate) sends an explicit `method: 'GET'`, R adapters/ApiDataSource.ts#ApiDataSource; no renderer reads the binding yet, the hook admitting only a string `object`, R data-scope/element-data-source.ts#isElementDataSourceConfig; [120] PageComponent.visibleWhen (the component-level evaluator's roots): the ambient scope (`current_user`, `user`, `ctx.user`, `os.user`, `features`, nothing else) objectui @1fb1ced36243 packages/app-shell/src/providers/ExpressionProvider.tsx#buildExpressionScope; composed with `record` (only when the page has a row) and `page` by objectui @1fb1ced36243 packages/react/src/SchemaRenderer.tsx#configEvaluationScope; no `data` root (objectui#9308) in objectui @1fb1ced36243 packages/react/src/SchemaRenderer.tsx#evaluatedSchema; the files identical at objectui main f228d710; the `page:tabs` item-level evaluator is the `page:tabs items[].visibleWhen` entry;" }, "assignedProfiles": { "status": "dead", diff --git a/packages/spec/liveness/view.json b/packages/spec/liveness/view.json index 0db4d586190..d7ac89e5b50 100644 --- a/packages/spec/liveness/view.json +++ b/packages/spec/liveness/view.json @@ -49,9 +49,9 @@ }, "filter": { "status": "live", - "note": "objectui: ListView.tsx client-side filter shaping (audit L15); no list-render prop reaches the server query (audit data-flow note)." + "note": "objectui: ListView.tsx client-side filter shaping (audit L15); no list-render prop reaches the server query (audit data-flow note). The console's filter rows carry a React list key that the wire door removes before the parse (packages/spec/src/ui/view.zod.ts, the VIEW_CONSOLE_ROW_DECORATIONS header and the ViewFilterRule docblock; moved out of spec source, #23434): `id: crypto.randomUUID()` is stamped on each new row by objectui @b9814b334 packages/components/src/custom/filter-builder.tsx#FilterBuilder (its `addCondition`), and again on a stored filter read back into the builder by objectui @b9814b334 packages/plugin-view/src/config/view-config-utils.ts#parseTriplet and objectui @b9814b334 packages/plugin-view/src/config/view-config-utils.ts#parseSingleOrNested (both reached from that file's parseSpecFilter); re-read 2026-10-15, first cited by line, sha-less." }, - "sort": {"status": "live", "note": "objectui: ListView.tsx (audit L15).", "children": {"field": {"status": "live", "verifiedAt": "2026-09-13", "evidenceScope": "in-repo", "note": "Read in this repo by `normalizeSortNodes` (packages/metadata-protocol/src/protocol.ts:3468, `fromElement`), which reads `el.field` off every sort entry and is the funnel every metadata ingress passes through; it lowers onto the engine `orderBy`. Drilled here rather than inherited because #17053 retired the bare string arm of this union, which is what made the entry's own keys visible to the walk."}, "order": {"status": "live", "verifiedAt": "2026-09-13", "evidenceScope": "in-repo", "note": "Read in this repo by `normalizeSortNodes` (packages/metadata-protocol/src/protocol.ts:3468) alongside `field`, and validated by its `direction()` helper (:3447) which refuses anything but 'asc'/'desc'. Divergence from `field` would be the signal worth recording; there is none \u2014 a sort entry is inert without both."}}}, + "sort": {"status": "live", "note": "objectui: ListView.tsx (audit L15). The console's sort rows carry the same React list key (packages/spec/src/ui/view.zod.ts, the VIEW_CONSOLE_ROW_DECORATIONS header and the sort entry's docblock; moved out of spec source, #23434): `id: crypto.randomUUID()` is stamped by objectui @b9814b334 packages/components/src/custom/sort-builder.tsx#SortBuilder (its `normalize`, for a row without one, and its `addItem`), and again on a stored sort read back by objectui @b9814b334 packages/plugin-view/src/config/view-config-utils.ts#toSortItems; re-read 2026-10-15, first cited by line, sha-less.", "children": {"field": {"status": "live", "verifiedAt": "2026-09-13", "evidenceScope": "in-repo", "note": "Read in this repo by `normalizeSortNodes` (packages/metadata-protocol/src/protocol.ts:3468, `fromElement`), which reads `el.field` off every sort entry and is the funnel every metadata ingress passes through; it lowers onto the engine `orderBy`. Drilled here rather than inherited because #17053 retired the bare string arm of this union, which is what made the entry's own keys visible to the walk."}, "order": {"status": "live", "verifiedAt": "2026-09-13", "evidenceScope": "in-repo", "note": "Read in this repo by `normalizeSortNodes` (packages/metadata-protocol/src/protocol.ts:3468) alongside `field`, and validated by its `direction()` helper (:3447) which refuses anything but 'asc'/'desc'. Divergence from `field` would be the signal worth recording; there is none \u2014 a sort entry is inert without both."}}}, "searchableFields": { "status": "live", "note": "objectui: ListView.tsx (audit L15)." @@ -186,7 +186,7 @@ "bulkActionDefs": { "status": "live", "evidence": "packages/spec/src/ui/bulk-action.zod.ts", - "note": "objectui: ListView.tsx:1343 forwards rich defs to ObjectGrid (BulkActionDialog). Dispatch: useBulkExecutor.ts run() — per-record fan-out by default; execution:'aggregate' defs go through the ONE-call bulkCall branch injecting params._selectedIds (ObjectGrid.runBulkActionAggregate, objectui#3139). Verified objectui@4bf612c. #4457 gave the def a SHAPE (it was z.record(z.any())): the entry schema is BulkActionDefSchema, strict, and it refuses the combinations that parse but the executor never reads — so this row's liveness now covers the keys inside a def, not just the array. A PROMOTED def's field-backed params (packages/spec/src/ui/bulk-action.zod.ts; moved out of spec source, #23434): resolved when the dialog opens by objectui main @dca25aff2 packages/plugin-grid/src/resolveBulkActions.ts#resolvePromotedBulkParams through `resolveActionParams` (objectui 29b99490), then renamed onto the bulk vocabulary by the same file's #toBulkParam, which carries the field's type, translated label, options, required, description, placeholder, defaultValue, multiple, `dependsOn`, `accept` and `maxSize` (plus a reference-bearing field's reference and display field) and drops the lookup settings." + "note": "objectui: ListView.tsx:1343 forwards rich defs to ObjectGrid (BulkActionDialog). Dispatch: useBulkExecutor.ts run() — per-record fan-out by default; execution:'aggregate' defs go through the ONE-call bulkCall branch injecting params._selectedIds (ObjectGrid.runBulkActionAggregate, objectui#3139). Verified objectui@4bf612c. #4457 gave the def a SHAPE (it was z.record(z.any())): the entry schema is BulkActionDefSchema, strict, and it refuses the combinations that parse but the executor never reads — so this row's liveness now covers the keys inside a def, not just the array. A PROMOTED def's field-backed params (packages/spec/src/ui/bulk-action.zod.ts; moved out of spec source, #23434): resolved when the dialog opens by objectui main @dca25aff2 packages/plugin-grid/src/resolveBulkActions.ts#resolvePromotedBulkParams through `resolveActionParams` (objectui 29b99490), then renamed onto the bulk vocabulary by the same file's #toBulkParam, which carries the field's type, translated label, options, required, description, placeholder, defaultValue, multiple, `dependsOn`, `accept` and `maxSize` (plus a reference-bearing field's reference and display field) and drops the lookup settings. An authored param's `options[]` entries (packages/spec/src/ui/bulk-action.zod.ts, the `.passthrough()` rationale; moved out of spec source, #23434): objectui @b9814b334 packages/plugin-grid/src/components/bulkParamToField.ts#bulkParamToField spreads each entry into the field metadata (`options?.map(o => ({ ...o, value: String(o.value) }))`), so every extra key reaches the widget, whose option vocabulary is objectui @b9814b334 packages/types/src/field-types.ts#SelectOptionMetadata, extending objectui @b9814b334 packages/types/src/select-option.ts#SelectOptionBase (`color`, `visibleWhen`, `disabled` and `icon` beyond the pair); the select cell reads `option?.color` in objectui @b9814b334 packages/fields/src/index.tsx#SelectCellRenderer. The renderer's own param type now agrees: objectui @b9814b334 packages/types/src/objectql.ts#BulkActionParam types an `options` entry open (an index signature, citing objectstack#4001), where the source's sha-less reading had it closed (`Array<{ label; value }>`). Re-read 2026-10-15, first cited by line, sha-less." }, "virtualScroll": { "status": "dead", @@ -207,7 +207,7 @@ "exportOptions": { "status": "live", "verifiedAt": "2026-08-13", - "note": "objectui: ObjectGrid.tsx reads five object keys — formats/streaming (:1596-:1611), maxRecords/includeHeaders/fileNamePrefix (:1620-:1631) — re-measured objectui origin/main@878140b. Object form adopted at #8010 (option A ruling 2026-08-12): the spec used to publish a bare format array the renderer never read (.formats on an array is undefined), so no declaration was both type-legal and functional; the bare array stays accepted and lifts to { formats } at parse. Sub-value 'pdf' removed same change (#1301 NOT_PLANNED) — enum error map carries the prescription; conversion view-export-options-pdf-removed strips stored sources." + "note": "objectui reads five object keys: `formats` and `streaming` in objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx#exportableFormats (the menu's format set), and `maxRecords`, `includeHeaders` and `fileNamePrefix` (with `streaming` again, for the server-stream choice) in objectui @b9814b334 packages/plugin-grid/src/ObjectGrid.tsx#handleExport — re-read 2026-10-15; first measured by line at objectui origin/main@878140b, respelled by symbol under #23434. Object form adopted at #8010 (option A ruling 2026-08-12): the spec used to publish a bare format array the renderer never read (.formats on an array is undefined), so no declaration was both type-legal and functional; the bare array stays accepted and lifts to { formats } at parse. Sub-value 'pdf' removed same change (#1301 NOT_PLANNED) — enum error map carries the prescription; conversion view-export-options-pdf-removed strips stored sources." }, "userActions": { "status": "live", @@ -246,7 +246,7 @@ }, "userFilters": { "status": "live", - "note": "objectui: UserFilters.tsx — element/fields/tabs/showAllRecords wired (audit L15); object views narrow to ObjectUserFiltersSchema (ADR-0047 amendment, #2679/objectui#2338)." + "note": "objectui: UserFilters.tsx — element/fields/tabs/showAllRecords wired (audit L15); object views narrow to ObjectUserFiltersSchema (ADR-0047 amendment, #2679/objectui#2338). `allowAddTab` (packages/spec/src/ui/view.zod.ts, the #5073 close record; moved out of spec source, #23434): read as `config.allowAddTab` by objectui @b9814b334 packages/plugin-list/src/UserFilters.tsx#UserFilters and handed to objectui @b9814b334 packages/plugin-list/src/UserFilters.tsx#TabFilters, which draws the add-tab affordance and holds the added tabs in component state only; re-read 2026-10-15, first cited by line, sha-less." }, "responsive": { "status": "dead", diff --git a/packages/spec/src/data/field.zod.ts b/packages/spec/src/data/field.zod.ts index 47e43cb54cf..d0986c18966 100644 --- a/packages/spec/src/data/field.zod.ts +++ b/packages/spec/src/data/field.zod.ts @@ -1812,9 +1812,10 @@ export const FieldSchema = lazySchema(() => { language: z.string().optional().describe('Programming language for syntax highlighting (e.g., javascript, python, sql)'), // `step` is the slider's **UI increment** and deliberately NOT a stored-value constraint — // ADR-0049's "ledger" half, ruled 2026-08-08 (#6514). Note it is renderer-LIVE, not dead, - // which is why it is NOT in the pruned list above and never joins it: objectui's - // `packages/fields/src/widgets/SliderField.tsx:14` reads it (`field.step ?? 1`) and hands it - // to the Slider, and `packages/spec/liveness/field.json` ledgers it `live` on that evidence. + // which is why it is NOT in the pruned list above and never joins it: objectui's slider + // widget reads it (`step ?? 1`) and hands it to the Slider, and + // `packages/spec/liveness/field.json` ledgers it `live` on that evidence (row `step`, which + // records the read point). // What it does not do is BIND the written value: the numeric branch of // `packages/objectql/src/validation/record-validator.ts` enforces `min`/`max` for `slider` // and reads `step` nowhere. The settings-side ruling (#6199 / PR #6501, which DID enforce a @@ -1832,7 +1833,8 @@ export const FieldSchema = lazySchema(() => { currencyConfig: CurrencyConfigSchema.optional().describe('Which currency an amount is in: for a currency field, and for a formula field whose returnType is currency. Absent: dynamic mode.'), // Vector field — flat dimensionality (the live authoring path). - // The renderer reads this flat sibling (objectui VectorField.tsx:11). + // The renderer reads this flat sibling (read point recorded in + // `liveness/field.json`, row `dimensions`). dimensions: z.number().int().min(1).max(10000).optional().describe('Vector dimensionality (e.g., 1536 for OpenAI embeddings)'), /** diff --git a/packages/spec/src/system/translation.zod.ts b/packages/spec/src/system/translation.zod.ts index 0ab19643b91..d66a623cbef 100644 --- a/packages/spec/src/system/translation.zod.ts +++ b/packages/spec/src/system/translation.zod.ts @@ -155,10 +155,10 @@ const actionTranslationSchema = (surface: string) => strictObject({ }, }, { label: z.string().optional().describe('Translated action label'), - // The address `useObjectLabel.actionDescription` already resolves — - // `objects.{object}._actions.{action}.description`, falling back to - // `globalActions.{action}.description` (objectui - // packages/i18n/src/useObjectLabel.ts:463). Declared here with #7367's + // The address objectui's `actionDescription` resolver already reads — + // `objects.{object}._actions.{action}.description` for an action bound to an + // object, `globalActions.{action}.description` for an object-less one (read + // points recorded in `liveness/action.json`, row `description`). Declared here with #7367's // `ActionSchema.description`: a bundle could not carry the string the // resolver was already looking for. description: z.string().optional().describe('Translated action description — the explanatory line under the title in the action\'s param dialog'), diff --git a/packages/spec/src/ui/action.zod.ts b/packages/spec/src/ui/action.zod.ts index 073984fbf71..a3270bbbcfb 100644 --- a/packages/spec/src/ui/action.zod.ts +++ b/packages/spec/src/ui/action.zod.ts @@ -962,16 +962,15 @@ const actionObject = () => strictObject({ * Explanatory line shown in the action's PARAM DIALOG, under the title. * * The renderer half already exists and predates this key: objectui's - * `ActionParamDialog` renders it as the dialog's `DialogDescription` - * (`objectui packages/app-shell/src/views/ActionParamDialog.tsx:215`, falling + * `ActionParamDialog` renders it as the dialog's `DialogDescription` (falling * back to the generic `actionDialog.description` string), fed by * `actionDescription(objectName, actionName, action.description)` from two - * independent handlers — `useConsoleActionRuntime.tsx:206` and - * `RecordDetailView.tsx:586`. The resolver - * (`objectui packages/i18n/src/useObjectLabel.ts:463`) reads - * `objects.{object}._actions.{action}.description`, falls back to - * `globalActions.{action}.description`, then to this literal. Until #7367 no - * producer could reach any of it: this shape refused the key. + * independent param-collection handlers. The resolver reads the translated + * copy at `objects.{object}._actions.{action}.description` for an action bound + * to an object, or at `globalActions.{action}.description` for an object-less + * one, never both, and falls back to this literal (read points recorded in + * `liveness/action.json`, row `description`). Until #7367 no producer could + * reach any of it: this shape refused the key. * * **Use it for the question the dialog is asking.** An action that collects * params and ALSO sets `confirmText` shows the user two dialogs for one diff --git a/packages/spec/src/ui/bulk-action.zod.ts b/packages/spec/src/ui/bulk-action.zod.ts index e3af9316d2e..5074f748755 100644 --- a/packages/spec/src/ui/bulk-action.zod.ts +++ b/packages/spec/src/ui/bulk-action.zod.ts @@ -69,16 +69,12 @@ import { FieldType } from '../data/field.zod'; // ships. // - `params[].options[]` is `.passthrough()` — and since the parent closed it // is the ONE open level left here. Still measured, never inherited from a -// neighbour by symmetry. objectui's option TYPE is closed -// (`Array<{ label; value }>`, `packages/types/src/objectql.ts:271`), but the -// type is not what an authored option meets: `bulkParamToField` SPREADS each -// entry — `options?.map(o => ({ ...o, value: String(o.value) }))`, -// `packages/plugin-grid/src/components/bulkParamToField.ts:131` — so every -// extra key survives verbatim into the field metadata, where the widget -// vocabulary is `SelectOptionMetadata` -// (`packages/types/src/field-types.ts:288`): `color` / `icon` / `disabled` / -// `visibleWhen` beyond the pair, and read (`option?.color`, -// `packages/fields/src/index.tsx:1089`). Stripping here therefore DELETES +// neighbour by symmetry. The renderer SPREADS each authored entry into the +// field metadata it hands the widget (`{ ...o, value: String(o.value) }`), +// so every extra key survives verbatim, and the widget's option vocabulary +// carries `color` / `icon` / `disabled` / `visibleWhen` beyond the pair, +// with `color` read by the select cell (read points recorded in +// `liveness/view.json`, row `list.bulkActionDefs`). Stripping here therefore DELETES // authored widget config the renderer would have honoured — the silent // narrowing this file exists to stop. Until #4001's 2026-08-03 re-measure // this level was bare strip while the ledger prose called it open: one diff --git a/packages/spec/src/ui/i18n-label-resolver.ts b/packages/spec/src/ui/i18n-label-resolver.ts index cb714bad097..aa2b20731c2 100644 --- a/packages/spec/src/ui/i18n-label-resolver.ts +++ b/packages/spec/src/ui/i18n-label-resolver.ts @@ -132,9 +132,9 @@ * translation *bundle*, addressed by convention * (`objects.._views..label`). This module resolves form **2**, the * map the author inlined. They compose in that order at objectui's own call - * sites (`translateLabel(pickLocalized(label, language), language)` — - * `packages/components/src/renderers/layout/containers.tsx:530-532`): resolve - * the inline map first, then look the resulting string up in the bundle. + * sites (`translateLabel(pickLocalized(label, language), …)`; read points + * recorded in `liveness/page.json`, row `regions`): resolve the inline map + * first, then look the resulting string up in the bundle. */ import type { I18nLabel } from './i18n.zod'; diff --git a/packages/spec/src/ui/view.zod.ts b/packages/spec/src/ui/view.zod.ts index 8d14dc3c89d..1e6e38545ff 100644 --- a/packages/spec/src/ui/view.zod.ts +++ b/packages/spec/src/ui/view.zod.ts @@ -452,12 +452,11 @@ export function normalizeFilterOperator(op: unknown): string { // console's row builders create the same problem from the other side, and this // is that function's write-path twin. // -// The producer is a React list key, not a protocol decision: the filter builder -// (`components/src/custom/filter-builder.tsx:228`, re-stamped on read-back at -// `plugin-view/src/config/view-config-utils.ts:146`/`:160`) and the sort builder -// (`components/src/custom/sort-builder.tsx:68`/`:94`) both stamp -// `id: crypto.randomUUID()` on every row they render, so those ids reach the -// wire. [#20051] They no longer reach the store: `saveMetaItem` stores the +// The producer is a React list key, not a protocol decision: the console's +// filter builder and sort builder both stamp `id: crypto.randomUUID()` on every +// row they render, and again on a stored row read back into them (read points +// recorded in `liveness/view.json`, rows `list.filter` and `list.sort`), so +// those ids reach the wire. [#20051] They no longer reach the store: `saveMetaItem` stores the // parsed value of every key a body carries, and the ids are removed before the // parse. // @@ -961,10 +960,9 @@ function foldAuthoredViewFilterOperator(op: ViewFilterOperator): string { * this split; that hotfix is now retired rather than left standing. * * **Why the reopen was needed, and why it no longer is.** The filter builder - * objectui renders stamps `id: crypto.randomUUID()` on every row it creates - * (`components/src/custom/filter-builder.tsx:228`; stamped again when a stored - * filter is read back into the builder — - * `plugin-view/src/config/view-config-utils.ts:146`/`:160`). `saveMetaItem` + * objectui renders stamps `id: crypto.randomUUID()` on every row it creates, + * and again when a stored filter is read back into the builder (read points + * recorded in `liveness/view.json`, row `list.filter`). `saveMetaItem` * validated the PUT body and then persisted the AUTHORED body verbatim (until * #20051), so that `id` was on the wire and in the store. Closed *without* a wire route, this * shape turned every filter write carrying one into a 422 — measured on all @@ -1698,8 +1696,8 @@ export const UserFilterFieldSchema = lazySchema(() => strictObject({ * ## Why it could not just be closed (the 批 18 blocker) * * objectui's renderer reads `config.allowAddTab` and renders an "add tab" - * affordance from it (`packages/plugin-list/src/UserFilters.tsx:182` and - * `:742`); its own `UserFiltersSchema` declared the key. The spec's did not — + * affordance from it (read points recorded in `liveness/view.json`, row + * `list.userFilters`); its own `UserFiltersSchema` declared the key. The spec's did not — * and the difference between the two shapes was *exactly* that one key. * * That gap was not inert, because the metadata write path did NOT persist @@ -2799,9 +2797,9 @@ const ListViewShapeSchema = lazySchema(() => strictObject({ * What made the first attempt a regression: `view-metadata-schema.test.ts` * pins `sort: [{ id, field, order }]` as *"the exact shape * normalizeViewMetadata persists on a console column-sort PUT"*, and `id` is - * a UI row identity objectui stamps per row - * (`components/src/custom/sort-builder.tsx:68`, `:94` — - * `crypto.randomUUID()`), persisted verbatim because `saveMetaItem` stored the + * a UI row identity objectui's sort builder stamps per row + * (`crypto.randomUUID()`; read points recorded in `liveness/view.json`, row + * `list.sort`), persisted verbatim because `saveMetaItem` stored the * original body (until #20051). **`.strip()` on a wire member could not rescue it** — it * re-opens the TOP level only, and this is a nested block reached through that * member. See {@link stripViewConsoleDecorations}, which removes the