Carved by the triage seat from the maintainer ruling on objectstack-ai/objectui#5362 (2026-08-20, decision-inbox session, session session_01PjAP6vbcsg2yMtvySPv1Qo): of the three readings that card offered, the maintainer accepted reading 3 — the object document belongs to @objectstack/spec; objectui re-exports/aligns rather than maintaining a hand-written second copy (the same layer split objectui#3074 applied to PageNodeSchema). This is the contract-first slice that must land before the objectui half; ui#5362 is Blocked-by: this card.
The measured gap (from ui#5362, verified on objectui origin/main = bdf8cf76e)
objectui's ObjectSchemaMetadata hand-declares a subset of the object document. Three keys a real object definition carries are absent from it and from @objectstack/spec 17.0.0's dist/, while shipped objectui runtime reads all three:
| key | read at (objectui) |
|---|
list_views / listViews — both spellings accepted at every read site | ObjectView.tsx:1178,1194,1208 · InterfaceListPage.tsx:56 · AppHeader.tsx:501 · useElementDataSource.ts:104 · MetadataProvider.tsx:420 |
titleFormat | the ADR-0079 object-level display-name resolver (ObjectKanban.tsx:275,295 names the order objectDef.titleFormat → displayNameField → …) |
icon | authored on objects; edited by the metadata-admin object inspector (ObjectDefaultInspector.tsx:94) |
The gap is invisible at the boundary because DataSource.getObjectSchema() returns Promise<any>.
Scope of this card (spec side)
- For each of the three keys: declare it on the spec's object schema with the semantics the runtime already implements, or explicitly rule it out (with the runtime read then owed a fix on the objectui side). "Declared by the type the consumer is told to use, silently read anyway" is the shape being ended — either direction is acceptable, silence is not.
list_views vs listViews: pick one canonical spelling in the declaration; the consumer-side dual-read becomes a deprecation question for the objectui follow-up, not a spec blessing of both.- Whatever ships, objectui's follow-up (ui#5362) derives its client type from the spec export instead of hand-copying — the derivation guard pattern applies.
Tier: contract accept-surface widening ⇒ Clause-②: yes, claude-fable-5.
Refs: objectstack-ai/objectui#5362 (the ruled card, with the full measurement) · objectui#3074 (the PageNodeSchema layer-split precedent) · ADR-0079 (titleFormat resolver order).
Carved by the triage seat from the maintainer ruling on objectstack-ai/objectui#5362 (2026-08-20, decision-inbox session, session
session_01PjAP6vbcsg2yMtvySPv1Qo): of the three readings that card offered, the maintainer accepted reading 3 — the object document belongs to@objectstack/spec; objectui re-exports/aligns rather than maintaining a hand-written second copy (the same layer split objectui#3074 applied toPageNodeSchema). This is the contract-first slice that must land before the objectui half; ui#5362 isBlocked-by:this card.The measured gap (from ui#5362, verified on objectui
origin/main=bdf8cf76e)objectui's
ObjectSchemaMetadatahand-declares a subset of the object document. Three keys a real object definition carries are absent from it and from@objectstack/spec17.0.0'sdist/, while shipped objectui runtime reads all three:list_views/listViews— both spellings accepted at every read siteObjectView.tsx:1178,1194,1208·InterfaceListPage.tsx:56·AppHeader.tsx:501·useElementDataSource.ts:104·MetadataProvider.tsx:420titleFormatObjectKanban.tsx:275,295names the orderobjectDef.titleFormat→displayNameField→ …)iconObjectDefaultInspector.tsx:94)The gap is invisible at the boundary because
DataSource.getObjectSchema()returnsPromise<any>.Scope of this card (spec side)
list_viewsvslistViews: pick one canonical spelling in the declaration; the consumer-side dual-read becomes a deprecation question for the objectui follow-up, not a spec blessing of both.Tier: contract accept-surface widening ⇒
Clause-②: yes,claude-fable-5.Refs: objectstack-ai/objectui#5362 (the ruled card, with the full measurement) · objectui#3074 (the PageNodeSchema layer-split precedent) · ADR-0079 (titleFormat resolver order).