Skip to content

finding(types,plugin-charts): ObjectChartSchema anchors nothing — ObjectChart is published as props: any, and four keys its own producers write are declared on neither copy #7946

Description

@claude

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions