Skip to content

Commit e7e04f1

Browse files
os-zhuangclaude
andauthored
chore(liveness): bring page under the spec liveness gate (#2267)
Adds packages/spec/liveness/page.json and registers `page` in the governed-types list (check-liveness.mts). All 17 authorable PageSchema properties are classified with evidence: 14 live (objectui consumers as prose), 1 experimental (variables), 2 dead (recordReview/blankLayout — removed page types, framework#2265 + objectui#1949). Gate passes (exit 0); no new warnings vs baseline. Page tests still 81/81. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 5737261 commit e7e04f1

3 files changed

Lines changed: 90 additions & 1 deletion

File tree

.changeset/page-liveness-ledger.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
"@objectstack/spec": patch
3+
---
4+
5+
chore(liveness): bring `page` under the spec liveness gate
6+
7+
Onboards the `page` metadata type to the ADR-0049/#1919 liveness ledger
8+
(`packages/spec/liveness/page.json`) and adds it to the governed-types list in
9+
`check-liveness.mts`. Every authorable PageSchema property now declares a
10+
status with evidence: 17 properties — 14 `live` (objectui renderer consumers
11+
cited as prose), 1 `experimental` (`variables` — provider/hook exist, no
12+
end-to-end consumer), 2 `dead` (`recordReview` / `blankLayout` — their page
13+
types were removed in framework#2265 and objectui dropped all references in
14+
objectui#1949; the fields stay @deprecated pending hard-removal). CI now fails
15+
if a new page property lands unclassified.

packages/spec/liveness/page.json

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"type": "page",
3+
"_note": "PageSchema (UI). Renderers live in objectui, so consumers are cited as prose in `note` (not `evidence`, which resolves framework file:line). Seeded from the Studio page-design dogfood (framework#2254/#2261/#2265). Containers (variables/regions/interfaceConfig/slots/aria) classified at top level — one drill level, no divergent sub-statuses. `recordReview`/`blankLayout` are `dead`: their page types (record_review/blank) were removed from PageTypeSchema (framework#2265) and objectui dropped all references (objectui#1949); the fields remain @deprecated pending hard-removal.",
4+
"props": {
5+
"name": {
6+
"status": "live",
7+
"note": "page identity; objectui page renderer + runtime route/metadata key."
8+
},
9+
"label": {
10+
"status": "live",
11+
"note": "display title (nav + page header) — objectui renderers."
12+
},
13+
"description": {
14+
"status": "live",
15+
"note": "navigation description — objectui."
16+
},
17+
"icon": {
18+
"status": "live",
19+
"note": "navigation icon — objectui."
20+
},
21+
"type": {
22+
"status": "live",
23+
"note": "objectui PageView (app-shell/src/views/PageView.tsx) + components/renderers/layout/page.tsx dispatch on the page kind (record/home/app/utility/list). Only these render — roadmap types removed (PAGE_TYPE_ROADMAP, framework#2265)."
24+
},
25+
"variables": {
26+
"status": "experimental",
27+
"note": "Page-local state. objectui mounts PageVariablesProvider + usePageVariables (react/src/hooks/usePageVariables.tsx) with default-value init, but no shipped consumer reads/writes them end-to-end (no element:record_picker writer; not injected into the visible/CEL context). Spec field is @experimental. Complete-or-remove tracked separately."
28+
},
29+
"object": {
30+
"status": "live",
31+
"note": "record-page binding + interfaceConfig source object — objectui PageView / InterfaceListPage."
32+
},
33+
"recordReview": {
34+
"status": "dead",
35+
"note": "Config for the removed `record_review` page type (no renderer; dropped from PageTypeSchema, framework#2265; objectui refs removed in objectui#1949). Field kept @deprecated — enforce-or-remove: slated for hard-removal."
36+
},
37+
"blankLayout": {
38+
"status": "dead",
39+
"note": "Config for the removed `blank` page type (no renderer; dropped from PageTypeSchema, framework#2265; objectui refs removed in objectui#1949). Field kept @deprecated — enforce-or-remove: slated for hard-removal."
40+
},
41+
"template": {
42+
"status": "live",
43+
"note": "layout template (e.g. header-sidebar-main) selects the region arrangement — objectui components/renderers/layout/page.tsx + containers.tsx."
44+
},
45+
"regions": {
46+
"status": "live",
47+
"note": "region → component tree rendering (header/main/sidebar/footer) — objectui components/renderers/layout/page.tsx + containers.tsx."
48+
},
49+
"isDefault": {
50+
"status": "live",
51+
"note": "default-page selection for an object/page-type — objectui page resolution."
52+
},
53+
"assignedProfiles": {
54+
"status": "live",
55+
"note": "profile-scoped page audience; objectui bridges it (react/src/spec-bridge/bridges/page.ts) to PageLayout.assignedProfiles. End-to-end enforcement not independently verified (necessary-not-sufficient, ADR-0054)."
56+
},
57+
"interfaceConfig": {
58+
"status": "live",
59+
"note": "the entire Airtable-parity list surface (source/columns/filterBy/appearance/userFilters/userActions/addRecord/buttons/recordAction/...) — objectui app-shell/src/views/InterfaceListPage.tsx + PageView.tsx. Verified in browser during the dogfood (grid+kanban+filters)."
60+
},
61+
"aria": {
62+
"status": "live",
63+
"note": "ARIA attributes applied by objectui renderers."
64+
},
65+
"kind": {
66+
"status": "live",
67+
"note": "full vs slotted record-page composition — objectui plugin-detail/src/index.tsx (buildDefaultPageSchema)."
68+
},
69+
"slots": {
70+
"status": "live",
71+
"note": "slotted-page override map (header/actions/alerts/highlights/details/tabs/discussion) — objectui plugin-detail; Preview render in objectui#1948. Verified in the Studio Design slot editor during the dogfood."
72+
}
73+
}
74+
}

packages/spec/scripts/liveness/check-liveness.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const repoRoot = resolve(specRoot, '../..');
5353
const ledgerRoot = join(specRoot, 'liveness');
5454

5555
// Governed metadata types, rolled out highest-frequency / highest-risk first.
56-
const GOVERNED = ['object', 'field', 'flow', 'action', 'hook', 'permission', 'role', 'agent', 'tool', 'skill', 'dataset'];
56+
const GOVERNED = ['object', 'field', 'flow', 'action', 'hook', 'permission', 'role', 'agent', 'tool', 'skill', 'dataset', 'page'];
5757

5858
// ADR-0010 provenance/lock overlay fields — system-stamped, on every type; auto-live.
5959
const FRAMEWORK_FIELDS = new Set([

0 commit comments

Comments
 (0)