Skip to content

docs(plugin-dashboard): the charts example authors a line widget bound to a dataset; the card widget with nested children retires (objectui#11484) - #11523

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-11484-dashboard-mdx-card-fence
Oct 3, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-11484-dashboard-mdx-card-fence

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #11484

content/docs/plugins/plugin-dashboard.mdx, section "Dashboard with Charts": the json fence's "Sales Trend" widget was a card with a nested chart node in children. It now takes the widget shape the package README teaches since objectui#7035: "type": "line" names the chart family, and the widget binds "dataset": "sales" with dimensions and values. The lead-in and the callout are rewritten with it. They taught type: "chart" + chartType for a dashboard chart, and the widget slot refuses that spelling too (probe: a widget { type: "chart", chartType: "line", dataset, dimensions, values } and a widget { type: "line", chartType: "line", ... } are both refused by DashboardComponentSchema, tolerant and strict).

The schema is not the wrong side here: card is outside the closed widget-type vocabulary (DashboardWidgetTypeSchema: the spec's chart families plus list / custom), the widget-slot component arm admits metric-card only, and a widget declares no children slot.

Validator verdicts, before and after

1. The card's own instrument, scripts/measure-strict-authoring-face.mjs --json, after pnpm --filter @object-ui/types build. These are readings at the two commits named, not live counts:

reading before, 8366accd13 after, 6e925b98ab
dashboard nodes refused by the strict twin 1 0
dashboard nodes red under the face as shipped 1 0
docs corpus, nodes red today 16 15
dashboard: rows in redTodayReasons type invalid_value, children invalid_type, (root) unrecognized_keys, (root) invalid_type none

2. A direct probe: the fence is extracted from the page and parsed with @object-ui/types/zod from the built dist/.

face before after
DashboardComponentSchema (tolerant) REFUSED: invalid_value at widgets.1.type, unrecognized_keys children at widgets.1 ACCEPTED
deriveStrictAuthoringSchema(DashboardComponentSchema) REFUSED, same issues ACCEPTED
StrictAnyComponentSchema REFUSED, same issues ACCEPTED
TypeScript face: DashboardComponentSchema from built dist/index.d.ts, tsc --strict TS2322 on type: "card" and on children compiles clean

C3: which docs gate judges json fences on this page

None judges a json fence's schema validity, so the fixed fence has no gate pin. Per the ruling, no gate is added.

  • check:doc-types (scripts/check-doc-component-types.mjs) reads the type literals in every code block under content/docs/**, json fences included. It only asks whether each type names a registered component; its header says it "answers one question only — does the type exist". card and chart are registered, so the refused fence passed it. Measured: I put the old fence back on this branch's tree (an ablation through ablation-replace.mjs, restored to HEAD's blob). The probe refuses it and check:doc-types exits 0.
  • check:doc-snippets compiles ts / tsx fences only.
  • check:doc-examples and check:doc-example-readers read JSDoc @example blocks under packages/NAME/src, not content/docs/**.

The one instrument that sees this class is the report-only measurement script above.

Why the README twin's pie widget is not copied

The README example also carries a pie widget, and check:doc-types refuses pie on this page. pie names no registered component, and the gate's DOC_TYPE_EXEMPTIONS row for this page covers metric, metric-card, bar and line only. Measured by ablation: with the pie widget added, all three schema faces accept the fence and check:doc-types exits 1 with [unregistered-doc-type] type 'pie' (json). The exemption lives in scripts/check-doc-component-types.mjs, outside this claim's file surface. So the fence keeps the metric card and the line widget.

Local verification, at 6e925b9

  • node scripts/check-control-bytes.mjs, check:doc-types, node scripts/check-prompt-component-keys.mjs, check:doc-example-ids, check:doc-fences (with --self-test), node scripts/check-doc-links.mjs and check:new-line-citations all exit 0.
  • node scripts/check-changeset-presence.mjs exits 0: "No source or published contract of a released package changed in this range, so no changeset is owed." This PR has no changeset file.
  • node scripts/markdown-test-inputs.mjs --changed names this page as a test input, so CI runs the full suite.
  • Locally I ran a narrowed set: pnpm exec vitest run scripts/__tests__/unconsumed-widget-option-claim-6186.test.ts scripts/__tests__/check-doc-component-types.test.ts passed 2 files and 131 tests. The first reads this page. The second covers the gate whose exemptions and key-table scan read it.
  • NOT MEASURED locally: the other tests that read content/docs/** as data, because the shared verification lock timed out three times behind a sibling's full-suite run. CI runs them.
  • NOT MEASURED locally: check:doc-snippets, because the diff touches no ts / tsx fence. The doc-snippet-types workflow runs it.

Acceptance notes

  • packages/cli/src/__tests__/unfulfilled-chart-stubs-retired-8760.test.ts has a case named "the spelling the corrected dashboard doc teaches is accepted". Its comment says this page teaches { type: 'chart', chartType: 'line' }. After this PR the page no longer teaches that spelling. The case still pins a true fact (the CLI accepts a chart node), and only its name and comment point at this page. Not filed; carrier: none.

The dispatch session is session_01HRYqpqGcWpJuJkDmbRF75w (domain:devx seat 2 PM, claim comment 5963526230).


Generated by Claude Code

…d to a dataset

The "Dashboard with Charts" fence authored its Sales Trend widget as a
`card` with a nested `chart` node in `children`. `card` is outside the
closed widget-type vocabulary and a widget declares no `children` slot,
so DashboardComponentSchema refuses it on the tolerant and the strict
authoring face, and the TypeScript face refuses it too. The fence now
takes the package README's widget shape: `type: "line"` naming the
chart family, bound to a `dataset` with `dimensions` and `values`. The
lead-in and the callout no longer teach `type: "chart"` + `chartType`
for a widget, which the strict widget schema refuses as well.

Claude-Session: https://claude.ai/code/session_01HRYqpqGcWpJuJkDmbRF75w
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Oct 3, 2026
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

changeset-claim-re-read

⚠️ 2 pending changeset(s) describe a file this change touches

Their bodies publish verbatim into the CHANGELOG at the next release, so this is a request to re-read them against your diff — addressed here because you are the one seat that can answer it without re-deriving anything.

⛔ Nothing here blocks, and nothing here is a verdict on your change. This gate exits 0, is not a required context, and judges name resolution, never meaning: it asked whether a pending body names a file you touched. "Is this sentence still true?" is the one question it will not answer, and the one you are being asked to answer.

.changeset/11483-metric-card-needs-value.md

  • names content/docs/plugins/plugin-dashboard.mdx → content/docs/plugins/plugin-dashboard.mdx — edited by this change

    • What changed. DashboardWidgetTypeSchema is now the spec's families plus list and custom, so the slot reads a metric-card through its component arm alone. The TypeScript twin, DashboardWidgetTypeName, drops DashboardComponentWidgetType the same way. DASHBOARD_COMPONENT_WIDGET_TYPES still lists metric-card: it is the component arm's type, and only that. - What now refuses that did not. Directly in widgets[], both faces refuse a metric-card with no value. That holds whatever else the card carries: title, description, id and layout, a dataset with values, or its figure under options (options: { value }), which the tolerant face accepted. On its own, DashboardWidgetSchema (zod) refuses type: 'metric-card' at type. On the TypeScript face, 'metric-card' is no longer a DashboardWidgetTypeName, so assigning it to that type is a compile error. - Why no widget key stands in for value. This was measured through the real DashboardRenderer and DashboardGridLayout. A dataset makes the dashboard draw DatasetWidget in the card's place, by a rule that does not read the type; the card is never mounted. options is spread onto the node as literal props: a second spelling of value, not a binding. No other widget key reached the figure. - What does not move. On the TypeScript face, DashboardWidgetSchema['type'] still includes 'metric-card'. That interface is also the read type of every widgets[] entry, and the component arm stays assignable to it. So a metric-card literal with no value still compiles directly in widgets[], while the validator refuses it on both faces. A metric-card in a widget's legacy component envelope is judged as before: there, the tolerant face's BaseSchema fallback still accepts a card that fails the arm. Every metric-card in the schema catalog, the READMEs and the docs fences carries its value. The one docs example that did not, under "TypeScript Support" in content/docs/plugins/plugin-dashboard.mdx, is rewritten.

.changeset/8760-unfulfilled-chart-stubs.md

  • names content/docs/plugins/plugin-dashboard.mdx → content/docs/plugins/plugin-dashboard.mdx — edited by this change

    • At render. SchemaRenderer's lazy branch re-checks hasLazy(type) on every pass and returns the Loading ANGLE-BRACKETS(type)… placeholder. Registry.register() deletes a lazy entry only for keys the loaded module actually registers, so for an unfulfilled key the entry SURVIVES the load and every later pass takes the same branch. Measured on b775500af through the real chain: { "type": "line-chart" } painted role="status" / data-lazy-loading="line-chart" / Loading line-chart…, permanently. Not the OBJUI-001 panel the card expected — no alert, no error, no console warning. A skeleton that never resolves reads to a user as a slow network. - At authoring. A stub is enough to put a key into getKnownTypes(), so check:doc-types and the CLI's generated KNOWN_SCHEMA_TYPES snapshot both blessed all three. content/docs/plugins/plugin-dashboard.mdx taught "type": "line-chart" inside a card body, and every gate was green on it.

Read the paragraph, not the line: both false halves of the objectui#8617 claim sat in one paragraph, and correcting either alone would have left it asserting the same wrong thing.

If a claim did go false, correct the body. That is precedented and prose-only, frontmatter untouched; check-changeset-overwrite.mjs will report the correction as its own case 2 ("correcting a declaration on purpose … legitimate"), which is the intended shape — one gate asks for the read, the other records the write.

Not covered, stated so nobody reads this as more: a born-false claim that spells no line address at all (objectui#9495 coordinated one by ORDINAL — "a grep finds that member first" — and deciding that means reading what the sentence means), a claim spelled as a symbol or a package rather than a backticked file name, and a file named ambiguously.

Angle-bracketed names in the quoted prose above are rewritten as ANGLE-BRACKETS(name): GitHub deletes tag-shaped fragments from a stored body, and a quote that silently loses the identifier it is about is worse than a visible repair.

Compared the checked-out tree with 8366accd1 (merge-base with origin/main): 1 file(s) changed outside .changeset/, read against 2061 pending declaration(s) that publish a body (2692 pending in total). · run

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 3, 2026 01:17
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 3, 2026 01:17
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 3, 2026
Merged via the queue into main with commit 6903eaf Oct 3, 2026
41 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-11484-dashboard-mdx-card-fence branch October 3, 2026 01:33
os-tesla pushed a commit that referenced this pull request Oct 3, 2026
Brings objectui#11484 (the plugin page's charts example, PR #11523); it merges
cleanly beside this branch's sections of the same page.

Claude-Session: https://claude.ai/code/session_01XvhGmGAP79ZB8swnkapxPC
Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

2 participants