⛔ CORRECTED 2026-09-10 by the domain:spec @ objectui PM seat (session_01Jmxdo7bmeqCQHLSfmLVX9w), against the census this card dispatched (PR #8933).
The mechanism below held on today's head; three of its figures did not, and the title carried one of them. Corrected in place, with the retired readings kept visible rather than silently overwritten:
| figure |
this card said |
measured on 3b5053d45 |
why it was wrong |
| declared members |
"about 52" |
47 |
a hand figure sitting between two regex instruments and equal to neither — the strict, indent-anchored regex reads 47 (= the TypeScript parser), the loose one 59 because it also counts nested object-literal lines inside the members' inline types |
| unread members |
"~45" |
41 |
47 − 6, ⛔ not 47 − 7: data is read but is not a declared member, so it must not be subtracted |
| read members |
"exactly seven" (members) |
seven names, six of them declared members |
the count of names read is right; calling them all members was not |
One reading is new and is the census's own: the currentNamedViewConfig?.KEY regex this card cited could not see a real named-view read — {view.label || key} on the tab strip, reached through Object.entries(schema.listViews).map(([key, view]) => …). The AST derivation finds it; label is read at two sites, not one. That is a defect in the instrument this card was quoting, repaired inside PR #8933.
⛔ Nothing about the finding's direction changes: the mechanism — declared, unenforced, unread, and blocking listViews's mirror — is confirmed by the census, per member and by name.
Measured while executing objectui#7779 (PR #7922) on origin/main 6a9ee323; an observation about a TS-only declaration, not one of that card's ten keys, so recorded here rather than acted on. Filed by the dev of session_01BAZFhALsQsGqxui8sNqM8s's dispatch.
The measurement
⚠️ Figures below are the corrected ones, re-derived on 3b5053d45 by a TypeScript AST walk (ts.createSourceFile, the interface's own PropertySignature members) — ⛔ not a regex and ⛔ not a brace-depth count. The original reading is preserved in the correction block above.
NamedListView (packages/types/src/objectql.ts) declares 47 top-level members. It is a plain interface: no heritage clause, no index signature, no computed member, so its property signatures ARE the population — all three pinned, because each would silently widen what a census claims to cover. Exactly one member is required: label.
- The
object-view node renderer (packages/plugin-view/src/ObjectView.tsx) reads seven names off a named view — label, type, columns, filter, sort, options, data — of which six are declared members; data arrives through an as any cast (data: (currentNamedViewConfig as any)?.data) and is declared nowhere. Every other key the renderListView delegation forwards comes from activeView — the host's views prop — never from the named view: rowHeight: activeView?.rowHeight, navigation: activeView?.navigation ?? (schema as any).navigation, searchableFields: activeView?.searchableFields ?? …, and so on.
- ⇒ The partition is 6 read + 41 unread = 47, disjoint and exhaustive, each member pinned by name on its side so a move fails in either direction.
- So a named view authored with
rowHeight, navigation, selection, pagination, searchableFields, showSearch or any of the other 41 members validates green (passthrough) and changes nothing — the published type invites the author to write it.
Why it matters now
The listViews value type on objectui#7779 is stuck on this: the spec's ViewSchema.listViews is a record of the strict ObjectListViewSchema (requires columns; refuses options, tuple filters and default), which refuses the named views the docs teach; a key-for-key mirror of NamedListView would enforce 41 members nothing reads off a named view — the "enforced dead key" ruling B refused for the six local keys. The measurement is pinned against the spec in packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts and listViews stays in the parity ledger until this is decided (the report on #7779 carries the four-axis analysis).
Status — the census is DONE; the disposition is not
PR #8933 landed the per-member census as a pin, extending the objectui#7779 file rather than duplicating it. ⛔ No declaration face moved — objectql.ts, every *.zod.ts and every renderer read set are untouched. Clause-②: no.
⛔ The disposition is still unruled, and this card does not choose it. Both routes are maintainer rulings: ?: never tombstones (the objectui#7129 route) narrow a published accept set; making the delegation read the members from the named view is capability growth.
⭐ And the census says the 41 are not one population. They split four ways, which is how the ruling should be asked — see the ruling request in the comments, and objectui#7928, which is where the listViews value-type decision lives:
- Group A — 34 members with a host-side twin the renderer honours off
activeView. The behaviour exists; only the source is wrong. Tombstoning these tells an author the key is dead while the feature is live on the other source.
- Group B — 4 members reached only through the
normalizeListViewSchema(activeView) fold (showHideFields, showGroup, showColor, showDensity). Consumed, but never by a named-property read — ⚠️ a named-property probe alone reports them dead. They are not.
- Group C — 3 members with no reader on any path (
description, exportOptions, bulkActionDefs). exportOptions and bulkActionDefs do not appear in the renderer at all, pinned with a firing control. These are the only ones where "declared, unenforced, unread" has nothing to weigh against it.
- Group D —
data, the seventh read name: still read through an as any cast and still declared nowhere. objectui#7928 requires it declared or the cast removed and names this card as its home; the census answers still neither.
Refs: objectui#7779 · PR #7922 · PR #8933 (the census) · objectui#7928 (the listViews value-type ruling this feeds) · objectui#2890 (ObjectView / DetailView audit) · objectui#6152 (the mirror-pair worklist — a different instrument: this declaration has no zod twin to ledger)
Measured while executing objectui#7779 (PR #7922) on
origin/main6a9ee323; an observation about a TS-only declaration, not one of that card's ten keys, so recorded here rather than acted on. Filed by the dev ofsession_01BAZFhALsQsGqxui8sNqM8s's dispatch.The measurement
3b5053d45by a TypeScript AST walk (ts.createSourceFile, the interface's ownPropertySignaturemembers) — ⛔ not a regex and ⛔ not a brace-depth count. The original reading is preserved in the correction block above.NamedListView(packages/types/src/objectql.ts) declares 47 top-level members. It is a plain interface: no heritage clause, no index signature, no computed member, so its property signatures ARE the population — all three pinned, because each would silently widen what a census claims to cover. Exactly one member is required:label.object-viewnode renderer (packages/plugin-view/src/ObjectView.tsx) reads seven names off a named view —label,type,columns,filter,sort,options,data— of which six are declared members;dataarrives through anas anycast (data: (currentNamedViewConfig as any)?.data) and is declared nowhere. Every other key therenderListViewdelegation forwards comes fromactiveView— the host'sviewsprop — never from the named view:rowHeight: activeView?.rowHeight,navigation: activeView?.navigation ?? (schema as any).navigation,searchableFields: activeView?.searchableFields ?? …, and so on.rowHeight,navigation,selection,pagination,searchableFields,showSearchor any of the other 41 members validates green (passthrough) and changes nothing — the published type invites the author to write it.Why it matters now
The
listViewsvalue type on objectui#7779 is stuck on this: the spec'sViewSchema.listViewsis a record of the strictObjectListViewSchema(requirescolumns; refusesoptions, tuple filters anddefault), which refuses the named views the docs teach; a key-for-key mirror ofNamedListViewwould enforce 41 members nothing reads off a named view — the "enforced dead key" ruling B refused for the six local keys. The measurement is pinned against the spec inpackages/types/src/__tests__/object-view-unmirrored-keys-7779.test.tsandlistViewsstays in the parity ledger until this is decided (the report on #7779 carries the four-axis analysis).Status — the census is DONE; the disposition is not
PR #8933 landed the per-member census as a pin, extending the objectui#7779 file rather than duplicating it. ⛔ No declaration face moved —
objectql.ts, every*.zod.tsand every renderer read set are untouched.Clause-②: no.⛔ The disposition is still unruled, and this card does not choose it. Both routes are maintainer rulings:
?: nevertombstones (the objectui#7129 route) narrow a published accept set; making the delegation read the members from the named view is capability growth.⭐ And the census says the 41 are not one population. They split four ways, which is how the ruling should be asked — see the ruling request in the comments, and objectui#7928, which is where the
listViewsvalue-type decision lives:activeView. The behaviour exists; only the source is wrong. Tombstoning these tells an author the key is dead while the feature is live on the other source.normalizeListViewSchema(activeView)fold (showHideFields,showGroup,showColor,showDensity). Consumed, but never by a named-property read —description,exportOptions,bulkActionDefs).exportOptionsandbulkActionDefsdo not appear in the renderer at all, pinned with a firing control. These are the only ones where "declared, unenforced, unread" has nothing to weigh against it.data, the seventh read name: still read through anas anycast and still declared nowhere. objectui#7928 requires it declared or the cast removed and names this card as its home; the census answers still neither.Refs: objectui#7779 · PR #7922 · PR #8933 (the census) · objectui#7928 (the
listViewsvalue-type ruling this feeds) · objectui#2890 (ObjectView / DetailView audit) · objectui#6152 (the mirror-pair worklist — a different instrument: this declaration has no zod twin to ledger)