Skip to content

finding(types): series chartType is undeclared and SILENTLY STRIPPED - the normalizer reads it first, measured not live, alias-refusal owed #7694

Description

@claude

Carved out of objectui#7546 by the domain:ui PM seat, on the contract review of PR #7684. #7684 carries Fixes #7546; without this card the finding below survives only as a comment on a closed card and a pin-test comment. That is measured-and-lost, and it is the seat's miss — objectui#7690 rescued the axis-config half of #7546 and this half was not.

The fact, as PR #7684 measured it

normalizeSeries reads str(raw.chartType) ?? str(raw.type). The first limb is undeclared on ChartDataSeriesSchema, which is a non-strict z.object, so an authored chartType on a series is silently stripped by the parse and never reaches that limb.

chartType measured not live on the authoring face, with lit controls, twice:

population chartType control
docs 0 dataKey / name / type / color lit
fixtures 0 lit
designer inputs 0 the chart registration's series is one code input
src literals 0
tests 9 all internal dataKey-shaped, taking ChartRenderer's raw fast path — they never reach the normalizer's first limb

Limb ablation, re-run by the reviewer on 197 files / 2380 tests (5× the author's population): deleting str(raw.chartType) ?? left 2380 passed; the sibling-limb control (deleting ?? str(raw.type)) went 2 failed. The instrument is lit and the zero is a reading.

And the contract of record refuses the name itself: @objectstack/spec@17.2.0 answers Unrecognized key(s) on this chart series: chartType. Did you mean chartType → type? — its alias map already declares chartType a spelling of type. Core's own chart-presentation.ts:122-123 translates authored type → internal chartType, confirming it is the internal spelling.

The ruled shape — option A

The PM ruling on #7546 and the contract review of #7684 both land on A: a named alias refusal pointing at type, the posture the spec itself takes. Not B (fold chartType onto type at parse — the renderer takes chartType FIRST, so the fold would let the alias overwrite the canonical key when both are written, inverting the objectui#7113 precedence rule) and not C (declare it as a second writable name — contradicts the spec's alias map and the three in-repo docblocks calling it the internal spelling; the N-dialects hazard of AGENTS.md #0.1).

⚠️ This is a NARROWING, and that is why it is its own card. { name: 'x', chartType: 'line' } draws a line today through the first limb; a named refusal takes that away. It needs its own changeset grade and its own liveness re-read at the time of implementation — ⛔ do not inherit the readings above as still-true, re-measure them.

Not in scope

⛔ Do not touch the ?? str(raw.type) sibling limb — it is lit (2 red on ablation). ⛔ Do not fold this into #7684; that PR's fence is deliberate. Sibling cards from the same measurement: objectui#7681 (a declared per-series type is dropped on the dataKey fast path), objectui#7682 (variant carries three different unions across four sites), objectui#7690 (the axis-config object dialect).


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

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions