Finally it CONVERGES `dashboard.widgets[].compareTo` (#5011) — the one entry in this step that is not a removal but a vocabulary merge, and the one whose defect was worst-shaped. The widget declared three arms with confident TSDoc; the analytics executor implements one contract, `DatasetSelection.compareTo` = `{ kind, dimension? }`, which has no `offset` in it. On the ADR-0021 dataset path the two string arms were DROPPED by the renderer (a comparison silently absent from a widget whose author asked for one) and `{ offset }` was forwarded into that contract with no dimension, so the executor threw `compareTo requires a timeDimension "undefined"` and errored the whole widget. All three arms worked on the legacy inline chart path. Same key, two fates — and the failing one was the path the spec itself calls canonical, which is why this ranks above an ordinary declared-but-unread key: the documentation was actively teaching a shape that crashes. The widget now declares the executor's own words, so `declared = enforced` holds by construction with no second vocabulary left to drift. `dimension` is optional and resolved by the EXECUTOR (one dated time dimension → that one; zero or several → a loud error naming the candidates), which is a producer-side resolution rule, not the consumer-side tolerance PD #12 forbids. The bare strings and `{ offset: '1y' }` replay mechanically; every other `{ offset }` duration is a semantic TODO below, because `previousPeriod` shifts by the resolved window's own length and rewriting `7d` into it would change which rows the comparison counts. The converged slot is also union-free, which is not cosmetic: zod collapses a failed union into one bare `Invalid input` and #5014 showed that curated guidance inside a union arm never reaches the author at all.
0 commit comments