Found while implementing objectui#7891 (removing ObjectView's undeclared chart.config
forward). Filed rather than folded into that PR: it is the MECHANISM that made #7891's
defect invisible, it lives in packages/types/ and packages/plugin-charts/ — both
outside that card's file surface — and acting on it is a design decision, not a rung.
What is measured, on origin/main f5d2acc
ObjectChartSchema exists twice and is exported from both — the TS interface
(packages/types/src/objectql.ts:2840) and the zod schema
(packages/types/src/zod/objectql.zod.ts:939). Neither anchors anything, for two
independent reasons.
1. The component they describe takes props: any.
packages/plugin-charts/src/ObjectChart.tsx:275
export const ObjectChart = (props: any) => {
and the published .d.ts carries that through verbatim:
packages/plugin-charts/dist/ObjectChart.d.ts:58
export declare const ObjectChart: (props: any) => React.JSX.Element;
So every schema={{ … }} literal handed to ObjectChart is type-checked against
nothing at all. MEASURED: removing both as any casts from the two object-chart
literals in packages/app-shell/src/views/ObjectView.tsx leaves tsc --noEmit GREEN,
over a program --listFiles confirms contains that file. The casts were inert; they read
as load-bearing and were not. That is why #7891's undeclared config rung survived from
the day it was written until someone read the spec by hand.
2. Four keys the producers actually write are declared on neither copy.
ObjectView's two object-chart literals write, between them, xAxisKey, series,
aggregate and filter. None of the four appears on the TS interface or the zod schema.
They are not dead either — packages/plugin-charts/src/ChartRenderer.tsx:132-134 reads
schema.series and schema.xAxisKey by name. The zod copy sits on BaseSchema, which is
.passthrough(), so they arrive and are read while their VALUES go unchecked.
3. A drift between the two copies, in passing. The zod schema declares colors (the
overloaded positional-palette / value-map union); the TS interface does not.
Why this is worth a card
objectui#6576's 2026-08-31 ruling (option A) anchored ObjectGallerySchema to
ObjectGalleryProps.schema precisely so a published widget schema would stop being a
document nothing reads, and pinned the read census in
__tests__/widget-schema-anchors-6576.test.ts. ObjectChart was not given that
treatment. ObjectChartSchema is what #6576 called the before-state: a published shape
with no prop type bound to it.
It is also the OTHER DIRECTION from objectui#7559. That card owns the input side — a
missing rung is invisible because viewDef is an untyped record. This is the output side:
an EXTRA, undeclared rung is invisible because the consuming component's props are any.
Same silence, opposite sign, different seam. It is likewise not objectui#7690, which is
about the SDUI ChartSchema's axis-config object dialect — a different schema and a
different key set.
What is NOT decided
Do not open with "declare the four keys". ADR-0049 is enforce-or-remove and both arms are
live per key: series and xAxisKey have real read sites, but whether they are AUTHORABLE
on an object-chart node — as opposed to internal keys the relay computes, which is what
series: vals.map(...) looks like — is exactly the question objectui#7891 turned out to
hinge on. A liveness read per key, with lit controls, comes first. Anchoring the prop type
(#6576's option A) and declaring the keys are separable decisions and may want separate
cards.
Repo: objectstack-ai/objectui. Related: objectui#7891, objectui#6576, objectui#7559,
objectui#7690.
Generated by Claude Code
Found while implementing objectui#7891 (removing
ObjectView's undeclaredchart.configforward). Filed rather than folded into that PR: it is the MECHANISM that made #7891's
defect invisible, it lives in
packages/types/andpackages/plugin-charts/— bothoutside that card's file surface — and acting on it is a design decision, not a rung.
What is measured, on
origin/mainf5d2accObjectChartSchemaexists twice and is exported from both — the TS interface(
packages/types/src/objectql.ts:2840) and the zod schema(
packages/types/src/zod/objectql.zod.ts:939). Neither anchors anything, for twoindependent reasons.
1. The component they describe takes
props: any.and the published
.d.tscarries that through verbatim:So every
schema={{ … }}literal handed toObjectChartis type-checked againstnothing at all. MEASURED: removing both
as anycasts from the two object-chartliterals in
packages/app-shell/src/views/ObjectView.tsxleavestsc --noEmitGREEN,over a program
--listFilesconfirms contains that file. The casts were inert; they readas load-bearing and were not. That is why #7891's undeclared
configrung survived fromthe day it was written until someone read the spec by hand.
2. Four keys the producers actually write are declared on neither copy.
ObjectView's two object-chart literals write, between them,xAxisKey,series,aggregateandfilter. None of the four appears on the TS interface or the zod schema.They are not dead either —
packages/plugin-charts/src/ChartRenderer.tsx:132-134readsschema.seriesandschema.xAxisKeyby name. The zod copy sits onBaseSchema, which is.passthrough(), so they arrive and are read while their VALUES go unchecked.3. A drift between the two copies, in passing. The zod schema declares
colors(theoverloaded positional-palette / value-map union); the TS interface does not.
Why this is worth a card
objectui#6576's 2026-08-31 ruling (option A) anchored
ObjectGallerySchematoObjectGalleryProps.schemaprecisely so a published widget schema would stop being adocument nothing reads, and pinned the read census in
__tests__/widget-schema-anchors-6576.test.ts.ObjectChartwas not given thattreatment.
ObjectChartSchemais what #6576 called the before-state: a published shapewith no prop type bound to it.
It is also the OTHER DIRECTION from objectui#7559. That card owns the input side — a
missing rung is invisible because
viewDefis an untyped record. This is the output side:an EXTRA, undeclared rung is invisible because the consuming component's props are
any.Same silence, opposite sign, different seam. It is likewise not objectui#7690, which is
about the SDUI
ChartSchema's axis-config object dialect — a different schema and adifferent key set.
What is NOT decided
Do not open with "declare the four keys". ADR-0049 is enforce-or-remove and both arms are
live per key:
seriesandxAxisKeyhave real read sites, but whether they are AUTHORABLEon an object-chart node — as opposed to internal keys the relay computes, which is what
series: vals.map(...)looks like — is exactly the question objectui#7891 turned out tohinge on. A liveness read per key, with lit controls, comes first. Anchoring the prop type
(#6576's option A) and declaring the keys are separable decisions and may want separate
cards.
Repo: objectstack-ai/objectui. Related: objectui#7891, objectui#6576, objectui#7559,
objectui#7690.
Generated by Claude Code