Found while measuring objectstack-ai/objectstack#14074 (switcher visualizations whitelisted without a binding block) on origin/main f0f774b0. Recording only, no fix here.
What is measured
packages/plugin-list/src/ListView.tsx availableViews (lines 2084-2153 at f0f774b0) builds the resolvable list from the presence of each visualization's binding: kanban (groupByField), gallery (coverField/imageField), calendar (startDateField), timeline (resolveTimelineDateBinding), gantt (startDateField), map (resolveListMapConfig), tree (parentField), and then intersects it with appearance.allowedVisualizations (ADR-0047: whitelist ∩ resolvable). There is NO chart capability check in that block: chart enters resolvable only through the "always allow switching back to the viewType defined in schema" leg, i.e. when schema.viewType === 'chart'.
Consequence: a grid view that declares a complete chart: block (the ADR-0021 shape dataset / dimensions / values, or the legacy xAxisField / yAxisFields shape) and whitelists ['grid', 'chart'] never offers the Chart toggle. The whitelist filter drops it and falls back to ['grid'].
Runtime probe (vitest, ListView mounted with a registry spy, the same harness as ListView.calendar-binding-7029.test.tsx), whitelist ['grid', X] on a viewType: 'grid' view:
| X |
with its block declared |
with no block |
| kanban, gallery, calendar, timeline, gantt, map, tree |
offered (positive controls, 7/7) |
not offered (7/7) |
| chart |
NOT offered (chart: { dataset: 'ds', dimensions: ['status'], values: ['n'] }) |
not offered |
@objectstack/spec VisualizationTypeSchema (packages/spec/src/ui/view.zod.ts) lists chart as a switcher target, and ListChartConfigSchema is authorable on the list view (chart: key), so the whitelist entry is spec-legal and the binding is declarable; the gate just never reads it.
Precedent
objectui#5042 was the same shape for map (the view-level map block was authorable but inert for the switcher until the gate asked resolveListMapConfig). The fix shape is the same: ask the chart block the question the render branch asks (case 'chart' at ~2608: chartCfg.dataset with values, else the legacy xAxisField/yAxisFields), and push chart when it resolves.
Not in scope here
The legacy inline chart branch also floors xAxisKey at 'name' and the value at 'value' when a chart view is forced with no block (ListView.tsx ~2633-2634; plugin-view/src/ObjectView.tsx ~1439-1440). That is the objectui#7029 / #7070 / #7500 class (an invented binding on the forced path) and is reported to the objectstack PM on objectstack#14074 for routing, not filed here.
Generated by Claude Code
Found while measuring objectstack-ai/objectstack#14074 (switcher visualizations whitelisted without a binding block) on
origin/mainf0f774b0. Recording only, no fix here.What is measured
packages/plugin-list/src/ListView.tsxavailableViews(lines 2084-2153 atf0f774b0) builds theresolvablelist from the presence of each visualization's binding: kanban (groupByField), gallery (coverField/imageField), calendar (startDateField), timeline (resolveTimelineDateBinding), gantt (startDateField), map (resolveListMapConfig), tree (parentField), and then intersects it withappearance.allowedVisualizations(ADR-0047: whitelist ∩ resolvable). There is NO chart capability check in that block:chartentersresolvableonly through the "always allow switching back to the viewType defined in schema" leg, i.e. whenschema.viewType === 'chart'.Consequence: a
gridview that declares a completechart:block (the ADR-0021 shapedataset/dimensions/values, or the legacyxAxisField/yAxisFieldsshape) and whitelists['grid', 'chart']never offers the Chart toggle. The whitelist filter drops it and falls back to['grid'].Runtime probe (vitest, ListView mounted with a registry spy, the same harness as
ListView.calendar-binding-7029.test.tsx), whitelist['grid', X]on aviewType: 'grid'view:chart: { dataset: 'ds', dimensions: ['status'], values: ['n'] })@objectstack/specVisualizationTypeSchema(packages/spec/src/ui/view.zod.ts) listschartas a switcher target, andListChartConfigSchemais authorable on the list view (chart:key), so the whitelist entry is spec-legal and the binding is declarable; the gate just never reads it.Precedent
objectui#5042 was the same shape for
map(the view-levelmapblock was authorable but inert for the switcher until the gate askedresolveListMapConfig). The fix shape is the same: ask the chart block the question the render branch asks (case 'chart'at ~2608:chartCfg.datasetwithvalues, else the legacyxAxisField/yAxisFields), and pushchartwhen it resolves.Not in scope here
The legacy inline chart branch also floors
xAxisKeyat'name'and the value at'value'when a chart view is forced with no block (ListView.tsx ~2633-2634;plugin-view/src/ObjectView.tsx~1439-1440). That is the objectui#7029 / #7070 / #7500 class (an invented binding on the forced path) and is reported to the objectstack PM on objectstack#14074 for routing, not filed here.Generated by Claude Code