Filed by the domain:spec @ objectui seat (objectui#5734) as the landing chore for accepted PR objectui#5760.packages/spec is this lane's sole owner, so the decision lands here; the downstream consumer is objectui#2890, now pm:blocked on this card.
Filed unassigned. Not claimed.
Why this exists — the carrier gap, not the question, is the reason
objectui#2890 ("migrate the remaining ListView legacy vocabulary") has run its scope down over five PRs. Its 2026-08-06 triage narrowed the queue scope to two items, both of which landed today in PR objectui#5760. What remains in the card body is a single family, and triage named it explicitly as out of scope because it is blocked upstream, here:
- A6:
objectName → data.provider: 'object', and its sibling viewType. - Related, same face:
conditionalFormatting / exportOptions, where objectui's shapes are supersets carrying capability the spec cannot express — they want promotion, not a rename.
No card has ever carried this. That is the whole reason for filing rather than leaving a note: this lane has now been burned twice by exactly that shape. objectui#5330 exists only because "#4075 step 3" was cited for months as parked in the decision inbox while no card carried it, leaving objectui#4807 blocked on a ruling with no carrier. And objectstack#7917's live-tenant channel has sat uncarried since 2026-08-13. An uncarried phase is not a small piece of debt in this repo — it is the failure mode that keeps producing these cards.
The question
@objectstack/spec's packages/spec/src/ui/react-blocks.ts deliberately maintains two vocabularies for the same node:
dataProps: ['columns', 'sort', 'searchableFields', 'userFilters', 'pagination',
'grouping', 'rowHeight', 'selection', 'rowActions', 'inlineEdit']
interactions: [ OBJECT_NAME, viewType, filters, navigation, onRowClick, onNavigate,
{ name: 'fields', … }, options ]
objectName, tuple-filters and fields are the React-tier prop names; columns / rowHeight are the metadata-tier names. This is enforced, not decorative — packages/lint/src/validate-react-page-props.ts checks real JSX against REACT_BLOCKS, and react-conformance.baseline.json ratchets the spec↔component prop diff.
So objectui cannot retire objectName from its ListView surface unilaterally: doing so would contradict a prop the spec currently declares and lints for. Either react-blocks.ts drops it too, or the React tier keeps a permanently separate vocabulary and objectui's A6 is metadata-only forever. Same for viewType, whose spec counterpart type is objectui's component discriminator.
Why it is a decision rather than work
Both directions move a public contract face:
- Converge — the React tier adopts the metadata-tier spelling. Retires a declared, linted prop name; every React host authoring
objectName in JSX must migrate. Protocol/published-surface change. - Formalise the split — state that the React tier and the metadata tier keep separate vocabularies permanently, and record it where the next sweep looks. Cheap today, but it makes a two-vocabulary surface a standing commitment, and it is the shape AGENTS.md #0.1 warns about when it happens by drift rather than by decision.
⛔ Not auto-adjudicated: this is a protocol/public-contract question and lands squarely on the manual floor either way. The four-facet analysis belongs to whoever grades this — I am the consuming seat, and the accept-set call is not mine to make.
What is NOT being asked
conditionalFormatting / exportOptions are listed above for completeness because triage grouped them, but they are a promotion question (objectui's shapes are supersets), not the vocabulary question. They may want their own card; grading this one should not silently absorb them.
Downstream
- objectui#2890 —
pm:blocked, Blocked-by: this card. Its two queued items are delivered (PR objectui#5760, merged af3861f); this family is all that remains of its body. - Refs: objectui#5760 (the PR that ran the scope down) · objectui#2890's 2026-08-06 triage comment (the narrowing) ·
packages/spec/src/ui/react-blocks.ts · packages/lint/src/validate-react-page-props.ts.
Note for triage
Type not pre-filled: converging retires a declared public prop (Feature/protocol-change shape), while formalising the split declares an existing state (Task shape). The direction decides the type, so guessing it now would prejudge the ruling.
Filed by the
domain:spec@ objectui seat (objectui#5734) as the landing chore for accepted PR objectui#5760.packages/specis this lane's sole owner, so the decision lands here; the downstream consumer is objectui#2890, nowpm:blockedon this card.Filed unassigned. Not claimed.
Why this exists — the carrier gap, not the question, is the reason
objectui#2890 ("migrate the remaining ListView legacy vocabulary") has run its scope down over five PRs. Its 2026-08-06 triage narrowed the queue scope to two items, both of which landed today in PR objectui#5760. What remains in the card body is a single family, and triage named it explicitly as out of scope because it is blocked upstream, here:
objectName→data.provider: 'object', and its siblingviewType.conditionalFormatting/exportOptions, where objectui's shapes are supersets carrying capability the spec cannot express — they want promotion, not a rename.No card has ever carried this. That is the whole reason for filing rather than leaving a note: this lane has now been burned twice by exactly that shape. objectui#5330 exists only because "#4075 step 3" was cited for months as parked in the decision inbox while no card carried it, leaving objectui#4807 blocked on a ruling with no carrier. And objectstack#7917's live-tenant channel has sat uncarried since 2026-08-13. An uncarried phase is not a small piece of debt in this repo — it is the failure mode that keeps producing these cards.
The question
@objectstack/spec'spackages/spec/src/ui/react-blocks.tsdeliberately maintains two vocabularies for the same node:objectName, tuple-filtersandfieldsare the React-tier prop names;columns/rowHeightare the metadata-tier names. This is enforced, not decorative —packages/lint/src/validate-react-page-props.tschecks real JSX againstREACT_BLOCKS, andreact-conformance.baseline.jsonratchets the spec↔component prop diff.So objectui cannot retire
objectNamefrom its ListView surface unilaterally: doing so would contradict a prop the spec currently declares and lints for. Eitherreact-blocks.tsdrops it too, or the React tier keeps a permanently separate vocabulary and objectui's A6 is metadata-only forever. Same forviewType, whose spec counterparttypeis objectui's component discriminator.Why it is a decision rather than work
Both directions move a public contract face:
objectNamein JSX must migrate. Protocol/published-surface change.⛔ Not auto-adjudicated: this is a protocol/public-contract question and lands squarely on the manual floor either way. The four-facet analysis belongs to whoever grades this — I am the consuming seat, and the accept-set call is not mine to make.
What is NOT being asked
conditionalFormatting/exportOptionsare listed above for completeness because triage grouped them, but they are a promotion question (objectui's shapes are supersets), not the vocabulary question. They may want their own card; grading this one should not silently absorb them.Downstream
pm:blocked,Blocked-by:this card. Its two queued items are delivered (PR objectui#5760, mergedaf3861f); this family is all that remains of its body.packages/spec/src/ui/react-blocks.ts·packages/lint/src/validate-react-page-props.ts.Note for triage
Type not pre-filled: converging retires a declared public prop (
Feature/protocol-change shape), while formalising the split declares an existing state (Taskshape). The direction decides the type, so guessing it now would prejudge the ruling.