test(core): pin the page list-view residual, and report the usage census objectui#8429's grade is blocked on - #8684
Merged
Conversation
`page` is simultaneously a list-view type `@objectstack/spec`'s own `ListViewSchema` accepts, a member of both published `@object-ui/types` faces, and absent from the set `ListView` draws -- so a spec-valid `type: 'page'` view normalises to `viewType: 'grid'` with its `pageName` mount target left unread in the metadata. PR #8372 closed the DECLARATION half of objectui#8127 by deriving `ViewType` from the spec. This states the renderer half that derivation made visible rather than removed, mechanically instead of in prose. Disposition-free by construction: it asserts today's behaviour, so it reddens if a page renderer is grown (the residual set empties and the normalised output stops being `grid`) and equally if `ViewType` is narrowed back (the published faces stop accepting `page`). Neither open ruling can land silently now. Every set is asserted at its exact size before use -- a census over an empty set passes -- and the `grid` reading carries a discrimination control so a normalizer that answered `grid` for everything would fail. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YBWFb5YgMU5dw8p2VKj16S
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
os-justin
marked this pull request as ready for review
September 8, 2026 22:19
os-justin
enabled auto-merge
September 8, 2026 22:19
This was referenced Sep 9, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #8429. ⛔ Deliberately not
Fixes— that card is the registration of a residual with two open dispositions, and it must stay open until one of them is ruled. This PR takes neither.What this is
objectui#8429 was dispatched for a measurement, not a fix. Two things ship here:
type: 'page'list views (the input triage's re-grading trigger needs, in both directions) — reported below;⛔ No page renderer was grown. ⛔
ViewTypewas not narrowed. Both are rulings, and the second would break the derivation PR #8372 just established.⭐ Deliverable 1 — the census
The question
Triage wrote the trigger and then wrote that its input did not exist: 「
page视图的实际使用面 = 未测量。本卡没有测,本席也没有测。⛔ 按纪律不写成零。」A zero returned because the query was wrong reads identically to a zero returned because the feature is unused, and the two send the card in opposite directions. So every sweep below is reported with its population, its lit control, and a dark control.
Repo half — MEASURED, result 0
Population: every tracked file at
7cdd2b922— 6,958 files (git ls-files | wc -l); 6,873 read as text by the classifier. Not scoped topackages/*/src(a form that matches nothing and excludesapps/,examples/,content/docs/).Six declaration shapes swept for each candidate value, over the whole tree — TS/JS single- and double-quoted literals, JSON quoted-key, YAML, JSX attribute, and a bare quoted token — across all six view-type keys (
type,viewType,specType,defaultViewType,defaultView,activeView):nonsense_control_xyz(dark control)The 162 raw
pagelines are not view declarations. Classified mechanically (a 25-line lookback window for a list-view context, then read individually), all 162 fall into five classes, none of them an authored ListView:PageNodeSchema/OuiPageSchema,{ type: 'page', kind: 'html' | 'react', body/regions }; this isexamples/schema-catalog/src/schemas/components-layout-page/*.json,examples/hello-world/schema.json, and most docs fences;{ type: 'page', pageName }onNavigationItem/ComponentNavItem;registerMetadataResource({ type: 'page' }),<MetadataResourceEditPage type="page">,PagePreview,PageBlockInspector;{ type: 'page', name };Narrowing to the keys that can only mean a view type:
returns 5 lines, all of them this repo talking about the bug: two in
normalize-list-view.test.ts(the existing regression test), three in docblocks (normalize-list-view.ts,views.zod.ts).viewType: 'page'is 2 lines, both prose;viewType: 'grid'is 214.Second, independent probe.
@objectstack/spec@17.3.0'scheckListViewPageMountrequirespageNameon atype: 'page'view, sopageNameis a different spelling of the same question. All 108pageNamelines in the repo sit on navigation items and page routing; objectui's own ListView face does not declare the key at all.Array form (
availableViews/viewTypes/views: [...]carrying'page'): 0 hits; the same shape finds 3 forkanban/calendar, so it is lit.Per-subtree lit control — every subtree containing view declarations is shown non-empty:
page⇒ Repo half: 0 authored
type: 'page'ListViews, on a sweep proven to find the nine kinds that are authored and proven to return 0 for a value that exists nowhere.Corroborating:
CreateViewDialogexcludespageby construction (its picker is a totalRecord<ListViewVisualization, …>), so no in-repo surface can author one.Published-package half — NOT MEASURED
The installed tree was reached: 78,690 files across 1,623 packages under
node_modules/.pnpm. The same sweep returns 82 files forpage, of which 56 are@objectstack/spec+@objectstack/lint— and every one of those is the contract declaring and enforcingpage(the zod source, the dist bundles,json-schema/ui/ListView.json, the liveness ledger), never a usage. The rest arenext,fumadocs,lightningcss— unrelated senses of the word."listViews"appears in 24 installed files and"viewType"in 6, and every one of them is schema machinery (zod bundles, JSON Schemas, liveness ledgers). No installed package ships an authored ListView document of any kind — so "0 page views" there is a census over an empty set, which passes for free.What the census means for the grade — triage's own trigger, applied
anyreal app or installed package declaring one) — not met; nothing found, on a lit sweep.⇒ On the trigger as written, p2 stands. Moving to p3 needs a population this container does not have (a real tenant/app metadata corpus). ⛔ And per triage, never close either way: the contract still accepts
pageand the next author can still write one.⭐ Something the census turned up that outranks it
@objectstack/spec@17.3.0's liveness ledger (liveness/view.json) carries a maintainer ruling of 2026-08-29 on exactly the disposition this card leaves open, verbatim:Upstream also enforces the shape already:
checkListViewPageMountrefuses apageview with nopageName, refusespageNameon any other kind, and refuses a non-emptycolumnsbeside it.⛔ Nothing was acted on. It is reported because it bears directly on the ruling this card is waiting for: it suggests the answer is neither of the two dispositions triage forbade, but a third — a delegating mount — and it says upstream already considers objectui the owner of that half.
⭐ Deliverable 2 — the pin
packages/core/src/utils/__tests__/normalize-list-view.pageResidual-8429.test.ts(9 tests). It states the contradiction mechanically instead of in prose, and changes no behaviour.The sharpest input available: a document
@objectstack/spec's ownListViewSchemaaccepts —— normalises to
viewType: 'grid', with thepageNamemount target still sitting in the metadata, unread.It reddens on either disposition, which is the point:
pagebecomes drawable ⇒ the residual set empties and the output stops beinggrid;ViewType⇒ the published faces stop acceptingpage.Guards against passing for the wrong reason:
success: trueis a reading and not a rubber stamp;'grid'reading carries a discrimination control (kanban→kanban,gantt→gantt), so a normalizer that answeredgridfor everything — strictly worse than the bug — would fail;console.warnfrom #8372 is silenced, not asserted, and ⛔ not treated as a mitigation: it is a signal to the developer; the author still gets a grid. Its own behaviour stays pinned where it was.⭐ Deliverable 3 — the sibling card: it exists, and the premise is stale
Triage asked for a card on the
defaultViewType7-arm family missingchart/tree, noting 「那张卡目前似乎还不存在」.⛔ Not filed — one exists and it is already ruled. objectui#5321, "
ObjectViewSchema.defaultViewTypeomitstreeandchart, so twogenerateViewSchemabranches are unreachable from authored metadata (host-prop only)" — closed as completed on 2026-08-21.Maintainer ruling of 2026-08-20 on that card (recorded verbatim in
ObjectView.tsx): 「其他接受你的建议。」 — option B,treeandchartare recorded as host-composition-only surfaces, deliberately not added to the authored unions.All three surfaces triage named are covered by it:
packages/types/src/objectql.ts:1804, the zod twin atzod/objectql.zod.ts:348(whose docblock says the seven arms are "the declaration's SEVEN-value union on purpose"), andplugin-view's registration (OBJECT_VIEW_HOST_COMPOSITION_VIEW_TYPES, pinned byobjectViewHostSurface.test.tsx, which goes red the day either union grows atreeorchartmember).⇒ The observation is factually right and its reading as a gap is wrong. Filing a new card would re-litigate a standing ruling, and acting on it would redden a pin by design.
Verification
Ablation — four legs, each mutating a READ SITE (never the pin), from a committed tree,
trapon EXIT/INT/TERM with absolute paths. Per-test classification from vitest's JSON reporter; all five death strings counted 0 on every leg. Baseline 9/9 pass.page: trueintoLIST_VIEW_KINDS)core/src/utils/normalize-list-view.ts9ec9c9d6…→5e310ffd…; marker 0→1; lines 529→530 (Δ+1 as declared)expected [] to deeply equal [ 'page' ]), output flips (expected 'page' to be 'grid')ViewType(droppagefrom the enum)types/src/zod/views.zod.ts5c8a30dd…→1334e8e5…; marker 0→1; lines 254→254 (Δ0)pagez.enum(['grid']))types/src/zod/views.zod.ts5c8a30dd…→58a0d14b…; marker 0→1; lines 254→254 (Δ0)expected 1 to be 12,expected 1 to be 9. The census does not pass over an emptied set.ViewTypeat the type leveltypes/src/views.ts, rebuilt so it reacheddist/views.d.ts(verified: line 50 carries theExclude)7e6de89b…→7b331e90…; lines 976→976 (Δ0)tsc -p packages/core/tsconfig.test.jsonexit 2, error on the pin itself:pageResidual-8429.test.ts(146,13): error TS2322: Type '"page"' is not assignable to type 'ViewType'Every leg restored by state:
git hash-objectback to the HEAD blob, marker count back to 0, line total back,git diff HEADempty. Leg D's rebuild was repeated after restore anddist/views.d.ts:50verified back to the derived form;type-checkback to exit 0.pnpm --filter @object-ui/core type-check, the failure came fromnormalize-list-view.ts(197,3)— the existing derived-record totality catches the narrowing before the pin's own annotation is reached (tsc --noEmit && tsc -p tsconfig.test.jsonshort-circuits). The pin's compile-time leg was then isolated on the test program alone, which is where the table's leg D reading comes from.Gates and suites (exit codes captured before any pipe):
pnpm exec vitest run packages/core/src/utils/__tests__/normalize-list-view.pageResidual-8429.test.tsTest Files 1 passed (1) · Tests 9 passed (9)pnpm exec vitest run packages/core/Test Files 133 passed (133) · Tests 2797 passed (2797)pnpm --filter '@object-ui/core^...' build(dependency closure, run first)dist completeness: 126 emitted files verifiedpnpm --filter @object-ui/core type-checknode scripts/check-changeset-presence.mjs✅ 1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)… EMPTY frontmatter — declared as releasing nothingnode scripts/check-governed-queue-guard.mjs --test <both paths>✅ NOT GOVERNED — 2 path(s) checked against 5 governed surface(s)grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]'over both changed filesThe pin is confirmed inside the type-check program, not merely adjacent to it:
tsc -p packages/core/tsconfig.test.json --listFilesnames it among 697 files.skip-changesetis a phantom label in this repo; the real exemption is the empty-frontmatter changeset, which is what.changeset/8429-page-view-residual-pin.mdis.Dedup
Declared, and lit. GitHub's
search/issuesendpoint is blocked for this session (sessions are bound to their configured repositories), so the channel was switched to one targeted MCPsearch_issues. It is self-controlling: it returned #8429 itself and #8127 at the top, so this is not one of the false zeros this repo has measured. Across 15 results, no other card records this residual — #8127 is the declaration half and is closed.Authored by an agent seat; session
https://claude.ai/code/session_01YBWFb5YgMU5dw8p2VKj16S.Generated by Claude Code