You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Decision: what value type should ObjectViewSchema.listViews's mirror enforce — the spec record by reference, the local NamedListView, its seven read members with the rest retired, or stay ledgered? #7928
Filed by the domain:spec @ objectui execution seat (session session_01BAZFhALsQsGqxui8sNqM8s) as the carrier for the one key ruling B could not disposition. ⛔ domain:* and grading are triage's.
Figures corrected 2026-09-06T04:0xZ — the counts first published here were wrong and are restated below from the measurement that re-derived them (see the correction note at the end). Anything quoting this card should quote the current numbers: 47 declared members, 41 unread, six read declared members (not "about 52 / ~45 / seven").
Why this card exists at all. PR #7922 (objectui#7779) dispositions nine of the ten unmirrored ObjectViewSchema keys and carries Fixes #7779, so that card closes. listViews stays in the UnmirroredDeclared ledger under the ruling's own fallback clause — measured, not deferred by preference. Without this card the remedy would be referenced in a closed thread and owned by nobody, which is the exact failure this lane已 paid for twice: objectui#5741's body records how the row-predicate spelling question sat as "#4075 step 3, parked in the decision inbox" for months while no card ever carried it. So it gets a carrier the moment it becomes homeless, not later.
What is measured
The two candidate value types disagree, and each loses something real:
NamedListView declares 47 top-level members. The renderer reads seven keys off a named view — label, type, columns, filter, sort, options, data — but only six of those are declared members: data is not declared on NamedListView at all and reaches the renderer through an as any cast (packages/plugin-view/src/ObjectView.tsx:1815, (currentNamedViewConfig as any)?.data). So 41 declared members are unread (47 − 6), and one read key is undeclared — the mirror image of this card's own defect.
The spec value (ViewSchema.listViews → ObjectListViewSchema by identity, strict, columns its only required key) accepts the schema-catalog's { label, columns } but refuses: the README / plugin-view.mdx form { label: 'All Users' } (at columns); a type + filter view with no columns (at columns); content/docs/api/schema-reference.md's ObjectQL tuple filter [["owner", "=", "…"]] (at filter.0) and its default: true (unrecognized key); options (unrecognized key); a partial kanban: { groupByField } (at kanban.columns).
The writers disagree too: the README and the mdx author the local shape, schema-reference.md authors tuple filters, and app-shell's ViewPreview.tsx:113 spreads a spec-shaped view body into listViews.
So mirroring the spec value by reference refuses documented, taught forms; mirroring NamedListView key-for-key enforces 41 members nothing reads — the "enforced dead key" shape ruling B refused for the six local keys.
Options
option
what it costs
A
mirror the spec record by reference (ObjectListViewSchema)
refuses the README / mdx / schema-reference forms above; the north-star shape, but the renderer does not honour a spec-shaped named view today, so it declares something that does not run. Breaks the docs; leaves app-shell's ViewPreview (which already writes the spec shape) alone
B
mirror the local NamedListView key-for-key (47 members)
every documented example stays green; fossilizes 41 unread members as contract — the shape ruling B rejected for the six. Breaks ViewPreview.tsx
C (dev's recommendation)
mirror the six read declared members and retire the 41 unread ones (?: never + retirementTombstone(), the #7129 route), staged after #7924's per-member census; the seventh read key, data, has to be declared or its cast removed as part of it
shrinks the surface to what runs; costs the census card first, and retiring published members is "Breaking for authored metadata". Also breaks ViewPreview.tsx. ⚠️ Note this is a local shape — choosing it decides that for this one key the local vocabulary is the contract and the spec slot is not, which differs from what was already ruled for navigation / searchableFields / filterableFields
one key declared-not-enforced, pinned against the spec so a spec relaxation or a renderer change re-takes the measurement; honest interim, zero cost to keep
决策四维分析
实际业务需求:实测只有六个已声明成员被渲染器读取(第七个 data 根本没声明,靠 as any 进去),写入方却分三派(README / mdx 写本地形、schema-reference.md 写元组过滤器、app-shell 的 ViewPreview 塞规范形)。今天没有任何一种写法能被完整兑现——A 会拒掉文档正在教的形状,B 把 41 个没人读的成员变成契约,C 把契约缩到真正跑得通的那六个并顺手处理掉 data 这个「读了但没声明」的洞。
Seat recommendation: C, staged as #7924 (the per-member census, which must also decide data) → then the mirror. D is the status quo and costs nothing to keep while the census runs, so this card is not urgent — but it must not be uncarded.
⚠️ Note for whoever executes: option A only becomes correct together with a renderer change that honours a spec-shaped named view; ⛔ do not ship A as a type-only edit on the assumption that the renderer will follow.
Correction note (2026-09-06T04:0xZ). This card first said "about 52" members and "~45 unread", and cited the block as objectql.ts:1957-2134. All three were wrong or stale: a contract-review pass counted 47 top-level members with the pin's own regex at three refs (merge-base, old tip, new head — 47 at each; the looser regex that counts nested object-literal lines gives 59, which is where "about 52" came from), and the patch-round dev then found that 41, not 40 or 45, is the unread count, because data is read but was never a declared member. The line range moved 26 lines with an origin/main merge and is dropped rather than re-quoted — a member count and the interface name are the durable citation; a line range in a long-lived body goes stale by construction. The same wrong figures are in PR #7922's body and in three source comments on its branch; that PR is in the merge queue and cannot be updated, so the correction lands as a follow-up PR (recorded on objectui#7779).
Refs: objectui#7779 (ruling B, the nine dispositioned keys) · PR #7922 · #7924 (the NamedListView liveness census that option C needs, and where data's declared-or-cast question belongs) · #7923 (the schema-reference.md docs defect measured alongside) · #7129 / #7623 (the retirement route) · #6152 (the parity worklist).
Filed by the
domain:spec@ objectui execution seat (sessionsession_01BAZFhALsQsGqxui8sNqM8s) as the carrier for the one key ruling B could not disposition. ⛔domain:*and grading are triage's.Why this card exists at all. PR #7922 (objectui#7779) dispositions nine of the ten unmirrored
ObjectViewSchemakeys and carriesFixes #7779, so that card closes.listViewsstays in theUnmirroredDeclaredledger under the ruling's own fallback clause — measured, not deferred by preference. Without this card the remedy would be referenced in a closed thread and owned by nobody, which is the exact failure this lane已 paid for twice: objectui#5741's body records how the row-predicate spelling question sat as "#4075 step 3, parked in the decision inbox" for months while no card ever carried it. So it gets a carrier the moment it becomes homeless, not later.What is measured
The two candidate value types disagree, and each loses something real:
NamedListViewdeclares 47 top-level members. The renderer reads seven keys off a named view —label,type,columns,filter,sort,options,data— but only six of those are declared members:datais not declared onNamedListViewat all and reaches the renderer through anas anycast (packages/plugin-view/src/ObjectView.tsx:1815,(currentNamedViewConfig as any)?.data). So 41 declared members are unread (47 − 6), and one read key is undeclared — the mirror image of this card's own defect.ViewSchema.listViews→ObjectListViewSchemaby identity, strict,columnsits only required key) accepts the schema-catalog's{ label, columns }but refuses: the README /plugin-view.mdxform{ label: 'All Users' }(atcolumns); atype+filterview with nocolumns(atcolumns);content/docs/api/schema-reference.md's ObjectQL tuple filter[["owner", "=", "…"]](atfilter.0) and itsdefault: true(unrecognized key);options(unrecognized key); a partialkanban: { groupByField }(atkanban.columns).schema-reference.mdauthors tuple filters, and app-shell'sViewPreview.tsx:113spreads a spec-shaped view body intolistViews.So mirroring the spec value by reference refuses documented, taught forms; mirroring
NamedListViewkey-for-key enforces 41 members nothing reads — the "enforced dead key" shape ruling B refused for the six local keys.Options
ObjectListViewSchema)ViewPreview(which already writes the spec shape) aloneNamedListViewkey-for-key (47 members)ViewPreview.tsx?: never+retirementTombstone(), the #7129 route), staged after #7924's per-member census; the seventh read key,data, has to be declared or its cast removed as part of itViewPreview.tsx.navigation/searchableFields/filterableFieldsmaincarries after PR #7922)决策四维分析
data根本没声明,靠as any进去),写入方却分三派(README / mdx 写本地形、schema-reference.md写元组过滤器、app-shell 的ViewPreview塞规范形)。今天没有任何一种写法能被完整兑现——A 会拒掉文档正在教的形状,B 把 41 个没人读的成员变成契约,C 把契约缩到真正跑得通的那六个并顺手处理掉data这个「读了但没声明」的洞。hideEmptyonrecord:detailssections: the spec REFUSES the key,@object-ui/typesdeclares it, the zod mirror omits it, and the renderer honours it — plushideEmpty: falseis not an override #7129 的退役路线一致,但它是本地形,与本卡另外三个键已裁的「按规范槽引用」方向不同,需要明知而选。listViews内容都静默通过;A 会让 AI 写出的规范形视图校验通过却只渲染一部分——比拒绝更坏;B 让 41 个死键继续绿灯;只有 C 做到「错值在键上被拒、死成员按名被拒」,并让data要么被声明要么被去掉。Seat recommendation: C, staged as #7924 (the per-member census, which must also decide
data) → then the mirror. D is the status quo and costs nothing to keep while the census runs, so this card is not urgent — but it must not be uncarded.Correction note (2026-09-06T04:0xZ). This card first said "about 52" members and "~45 unread", and cited the block as
objectql.ts:1957-2134. All three were wrong or stale: a contract-review pass counted 47 top-level members with the pin's own regex at three refs (merge-base, old tip, new head — 47 at each; the looser regex that counts nested object-literal lines gives 59, which is where "about 52" came from), and the patch-round dev then found that 41, not 40 or 45, is the unread count, becausedatais read but was never a declared member. The line range moved 26 lines with anorigin/mainmerge and is dropped rather than re-quoted — a member count and the interface name are the durable citation; a line range in a long-lived body goes stale by construction. The same wrong figures are in PR #7922's body and in three source comments on its branch; that PR is in the merge queue and cannot be updated, so the correction lands as a follow-up PR (recorded on objectui#7779).Refs: objectui#7779 (ruling B, the nine dispositioned keys) · PR #7922 · #7924 (the
NamedListViewliveness census that option C needs, and wheredata's declared-or-cast question belongs) · #7923 (theschema-reference.mddocs defect measured alongside) · #7129 / #7623 (the retirement route) · #6152 (the parity worklist).