Repository navigation
feat(plugin-list)!: a chart list view binds only an ADR-0021 dataset; the legacy chart binding retires on every route (objectui#6152, round 15) - #12060
Conversation
…bjectui#6152, round 15) A chart list view binds only an ADR-0021 dataset. ListView's resolveListChartBinding loses its legacy leg (xAxisField / categoryField, yAxisFields / valueField, aggregation) and the chart branch its inline aggregate with the 'name' / 'value' floors; app-shell's object page and plugin-view's generateViewSchema lose the same path. A chart block that names no dataset now builds the unbound node, which ObjectChart refuses on screen (objectui#8168). plugin-view's kanban branch stops reading kanban.conditionalFormatting, which every door that judges the list view's kanban block refuses. The development-only flat-key warnings on both object-view routes stop naming keys every per-kind block refuses. Fixtures re-judged; prose that said the axes are still read updated; dated notes on two pending changesets; one new changeset. Claude-Session: https://claude.ai/code/session_01CijGnfWLxTLUFcJkY2ouUw Co-authored-by: Claude <noreply@anthropic.com>
…ListView and ObjectChart (objectui#6152, round 15) plugin-list does not depend on plugin-charts, so its type-check refused the pin's side-effect import. app-shell depends on both, so the real-route pin lives there; the node each relay composes stays pinned beside each relay. Claude-Session: https://claude.ai/code/session_01CijGnfWLxTLUFcJkY2ouUw Co-authored-by: Claude <noreply@anthropic.com>
…remains (objectui#6152, round 15) The three object-page source scans anchored their same-class control on the chart branch's `|| 'value'` measure floor, which this round retired. As each case instructed: no fabricated binding floor remains in this face, so the calendar and gallery cases now assert that none does, and the gantt control moves to the permanent display-name anchor beside the same assertion. Claude-Session: https://claude.ai/code/session_01CijGnfWLxTLUFcJkY2ouUw Co-authored-by: Claude <noreply@anthropic.com>
✅ 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
|
Contract reviewServed-tier: Read: card objectui#6152 (body and all 93 comments; the round-13 to round-15 rulings and reports are comments 6077447919, 6077535247, 6079839306, 6080145603, 6080177854, 6081672623 and the seat's Q1 answer 6081752038), PR objectui#12060 (body, the 26-file list, the net diff against its merge base, which is round 14's landing), the three changed source files and the five named packages' manifests at this head, the spec's list-view blocks in the sibling checkout for the warning lists, and this head's check-runs. Nothing built, run or re-run. An isolated subagent of the seat session signed below; the dispatch order and the seat's own conclusions were not inputs. Check-runs on this head, read at 2026-10-09T13:33Z: 43 runs, one head: 40 success, 3 skipped by design (dependabot, Test (coverage), Test (coverage shard N/4)), 0 in progress, 0 failed. Success includes Type Check, Lint, Spec Main Shape Gate, Build and E2E, Test (dist pins), Governed Surface Queue Guard, Line Citation Gate, Bundle Analysis, the five changeset gates (Declaration, Bump Policy, Fixed Group Check, Claim Re-read, Overwrite Report) and all 8 Test shards and the Test aggregate. Every gate-carrying run has concluded, none red. The verdict below is the contract face; the gate verdicts are the runs' own conclusions. ① Derived judgmentsEvery accept-set or surface change the diff implies, each judged against the tree at this head:
② Semver level
③ Boundary flagsDev deviations (report 6081672623), each answered:
Open question Q1 (what a dataset-less chart view shows): the seat answered A (the built objectui#8168 refusal), with C filed as objectstack#22491 for the spec seat and B not taken. Agreed: the built shape is loud and none of the dispatch's stop shapes; closing the door (C) is the contract-first half (#0.1); a list-view-only screen (B) would add release text in every locale for a population with zero writers in reach. The dev's H3 reading (the host Out-of-scope findings:
Implemented-by: VERDICT: PASS Generated by Claude Code |
Fixes #6152
Clause-②: no
Round 15 of objectui#6152: class D of the round-13 census (the legacy chart binding), plus the two items round 14's ACCEPT (
6079839306, item 3) carried here. Claim6080177854; rulings6077535247(Q1 → C, Q2 → A). Base:mainat3fd8625. Every gate below was read at head48f102b.What changes
A chart list view binds only an ADR-0021
dataset, on every route. The pre-ADR-0021 inline axes (xAxisField/categoryField,yAxisFields/valueField,aggregation) are refused by name at every door: the spec'sListChartConfigSchemais a strict object ofchartType/dataset/dimensions/values, and theoptionsbag is that block's own partial. Three routes still read them and drew an inline aggregate, floored at'name'/'value'when the block declared nothing. All three are retired:@object-ui/plugin-list,ListView.tsx:resolveListChartBindingloses its legacy leg.ListChartBindinglosescategoryField/valueField, and itsshapeis'dataset' | 'unbound'. The capability gate asks the same resolver, so it no longer offers Chart for a legacy block.case 'chart'loses the legacy return and its floors. A block that names nodatasetbuilds the UNBOUND node:{ type: 'object-chart', objectName, chartType, filter }.@object-ui/app-shell,views/ObjectView.tsx: the object page's own chart branch inrenderListViewis retired too. It readxAxisField,yAxisFields[0],aggregation, andseries/filteroff the block. The census did not list it as a reader (H1 below). It now builds the same unbound node, without a filter.@object-ui/plugin-view,ObjectView.tsx: the same retirement ingenerateViewSchema'scase 'chart'.ObjectChartrefuses the unbound node on screen with its objectui#8168 screen (chart-missing-category-axis,role="alert"). It no longer aggregates on a name nobody wrote.Carried from round 14 (ACCEPT item 3):
kanban.conditionalFormatting(H3 below). The view-levelconditionalFormattingof the active hostviewsentry is the one place the key is read.generateViewSchemaand app-shell'srenderListViewno longer name keys every per-kind block refuses. They used to tell an author to move those keys into the block.dateField,groupBy,groupField,imageFieldandsubtitleField.xAxisField,subjectField,endField,cardFields,yAxisFields,aggregationandseries.Prose: comments that said the list-view relays still read the axes were updated in:
ListView.tsx;objectql.zod.tsandobjectql.ts(@object-ui/types, comments only);ObjectChart.tsx(@object-ui/plugin-charts): theresolveChartCategoryFielddocblock and the 8168 docblock, comments only. The refusal path's code is untouched.The pending
.changeset/6152-list-view-readers-retired.mdand.changeset/6152-list-view-options-bag.mdeach gain an append-only dated note, because their "the legacy chart axes are still read" sentence goes false. The new.changeset/6152-list-view-legacy-chart-retired.mddeclares:minorfor plugin-list, app-shell and plugin-view (breaking for a stored chart view that names nodataset);patchfor plugin-charts and types (comments only);Measured before any edit
H2: what a
chartview with no dataset renders once the legacy branch is gone. A scratch probe rendered the realListViewand the realObjectChart(deleted afterwards):ListViewSchemaACCEPTSviewType: 'chart'with no block, andoptions: { chart: { chartType } }with no dataset. The spec's view write door (VIEW_METADATA_MEMBERS.listOverlay) ACCEPTS both too. So door-legal views reach this path, besides stored legacy rows.main. Those views drew an aggregate grouped bynamethat countedvalue: the floors.ObjectChart:role="alert"). Its remedy reads "Declare one of: aggregate.groupBy, xAxisKey, xAxis.field", which isObjectChart's vocabulary, not the list view's dataset block.objectNamenordatasetrenders blank.case 'chart'that returns nothing leaves the memoundefined, and the render site dereferencesviewComponentSchema.type: a crash (read from source).So shape 1 is the only loud answer within this surface. It is what is built. Naming the dataset block on screen would need new release text in every locale pack, which is outside this surface. That is open question Q1 in the report on objectui#6152, with options.
H3: does any door that feeds plugin-view's kanban branch accept
kanban.conditionalFormatting? Each door was read with a control:unrecognized_keysat the block; each control accepted): the named-view record (the spec'sViewSchema.listViews, and objectui'sObjectViewSchema/StrictAnyComponentSchema/safeValidateSchemaover it), the spec's authoringListViewSchema, the view write door (listOverlay), and objectui'sListViewSchemain both nestings.viewsentry (ObjectViewProps['views']). It declares nokanbanmember, only[key: string]: any. Atscprobe compiledkanban.conditionalFormatting, the round-14-retiredkanban.groupFieldand an arbitrarykanban.zzz_not_a_keyalike. Its control is the one declared block,tree: it refusedparentFeild(TS2561).kanban. It admits keys round 14 retired on this same branch, so it does not count as a door that accepts the key. Every door that judges the key refuses it, so the read retires.ObjectKanbanSchemadoes declareconditionalFormatting, but that is theobject-kanbanNODE's member, not the list view's block.Fixtures re-judged (three dispositions)
ListView.chart-capability-7544ListView.searchWithheldTreeChart-10326,ListView.datasetChartToolbarFilter-10327,ListView.datasetChartAppliedFilter-10512,ListView.selfQueryingViewsToolbarState-10250chartview naming no dataset. The switch case uses the dataset block, the only one the gate offers.ObjectView.chartRelay-7823false. The pointer still carries the block whole.ObjectView.chartConfigForward-7891ObjectView.refreshInPlace-10035ObjectView.calendarBinding-7029,ObjectView.galleryBinding-7547,ObjectView.ganttBinding-7070ObjectView.kanbanConditionalFormattingObjectChart.absentCategoryAxisRefusal-8168ObjectView.namedViewProtocolKeys-8980, typesobject-chart-legacy-axis-keys-retired-10608__tests__/listViewLegacyChartRetired-6152ListViewand the realObjectChart. Five shapes with no dataset each give the refusal and no aggregate query; the dataset block, as control, is not refused. It lives in app-shell becauseplugin-listdoes not depend onplugin-charts, soplugin-list's type-check refused it (TS2882).ObjectView.legacyChartRetired-6152titleFieldis the lit control).Source scans: no fabricated binding floor remains. The same-class control of the three app-shell source scans was anchored on the chart branch's
|| 'value'measure floor, and this PR deletes it. No one-rung fabricated binding floor remains in app-shell'sObjectView.tsx. What is left floors:'name';typeat'grid';'bar'.As instructed, the calendar and gallery cases now assert that NONE remains. Each still has a machinery control on
'name'. The gantt control moves to that anchor beside the same assertion.Census candidates left unchanged and still right:
CreateViewDialog.chartBinding-11576andObjectView.createChartView-11576(the writer writes the dataset block), andInterfaceListPage.treeChartRelay-11572.Ablations (reverse verification)
Each leg went through objectstack
scripts/ablation-replace.mjsin wrap mode. That tool carries its own EXIT/INT/TERM trap and proves its restore; a belt trap in the driver restored every path too. Every leg hit its anchor exactly once. After every leg the blob equalled HEAD andgit diff HEADwas empty for all three source files. Nodistis involved: the suites resolve these packages tosrcthrough the vitest aliases.name/valuefloors backresolvescomes backkanban.conditionalFormattingagaingroupFieldagainxAxisFieldagainGates (head
48f102b)--maxWorkers=2, underos-verify-lock): 648 files in four chunks. The battery is every test that imports or namesListView.tsx, eitherObjectView.tsx,ObjectChart.tsx,objectql.tsorobjectql.zod.tsby relative path, or theplugin-list/plugin-view/plugin-chartspackage names; every changed test; and the wholescripts/__tests__suite. Result: 646 files passed and 2 skipped; 15019 tests passed and 2 skipped. Every chunk printedVERDICT command-exit 0. The first run of chunk 0 found the three source-scan controls above red; they were converted and the chunk re-run green at this head.turbo run build --filter='@object-ui/console^...' --concurrency=2, exit 0): exit 0 at this head for@object-ui/types,plugin-charts,plugin-list,plugin-view,app-shelland@object-ui/console. Each run echoed itstype-checkscript.--no-inline-config --format json) on the 23 changed TS files: 0 errors. The modified files carry 574 warnings at this head, the same 574 as onmain; the two new test files add 7no-explicit-anywarnings (the house harness). The linted population iseslint.config.js's**/*.{ts,tsx}globs. Linting is not type-aware (noparserOptions.project), so no untouched file's verdict can move. Repo-widepnpm lintis CI's.check-changeset-presence,-no-major,-fixed,-claims,-overwrite(report-only: the two dated notes, declarations unchanged) andcheck-pending-changeset-literals.main3,240,183 B gzip; head 3,239,902 B; delta −281 B. Headroom toMAX_EAGER_CLOSURE_GZIP_BYTES(3,281,467, untouched): 41,565 B.check-eager-closure-budgetexit 0.check-sdui-registration-pins;check-control-bytes;check-new-cross-file-line-citations(0 new);check-vi-mock-specifiers/-inherit/-override-shape;check-test-path-roots;check-type-check-coverageandcheck-lint-coverage;check-phantom-dependencies;check-handler-key-read-sites;check-unreferenced-sources;check-i18n-call-site-keys;check-spec-symbol-derivation;check-object-metadata-write-doors;check-element-data-source-declaration;check-governed-queue-guard --test(NOT GOVERNED).Acceptance notes
ObjectChartissue onefindof the object's rows (no$top) before it refuses. The probe measured onefindand noaggregate. This PR makes every chart view that names no dataset reach that path. It is in the report on objectui#6152 as a finding and as part of Q1.UnifiedViewConfig.chartin@object-ui/types(designer.ts) still types the legacy axes. It is exported and has no consumer in this repository. Noted, not filed.object-charttombstone messages still describexAxisField/yAxisFields/aggregationas "the list-view chart block's spelling". That is published refusal text, left unchanged here.startDateFieldon a kanban view) and point at the view's own kind. This predates this PR and is development-only console text.Session:
https://claude.ai/code/session_01CijGnfWLxTLUFcJkY2ouUw(a subagent run for thedomain:spec @ objectuiseat).Generated by Claude Code