Skip to content

fix(console,cli,docs): retire three chart keys registered as stubs the charts plugin never fulfils - #9225

Merged
os-tesla merged 1 commit into
mainfrom
claude/issue-8760-unfulfilled-chart-stubs
Sep 12, 2026
Merged

fix(console,cli,docs): retire three chart keys registered as stubs the charts plugin never fulfils#9225
os-tesla merged 1 commit into
mainfrom
claude/issue-8760-unfulfilled-chart-stubs

Conversation

@os-tesla

Copy link
Copy Markdown
Collaborator

Fixes #8760

Ten chart variants were registered as registerLazy stubs pointing at @object-ui/plugin-charts. That package registers eight keys, and three of the ten — line-chart, area-chart, advanced-chart — were not among them. This PR retires those three, corrects the doc that taught one of them, and pins the outcome so the shape cannot come back.


1. What a registered-but-unfulfilled key actually does (measured, and the card's premise needed correcting)

The card says the key "paints OBJUI-001". It does not. Measured on b775500af through the real chain (console registrations, real loadLazy, real SchemaRenderer):

authored node role data-lazy-loading text
pie-chart (fulfilled control) none none draws
line-chart status line-chart Loading line-chart…
area-chart status area-chart Loading area-chart…
advanced-chart status advanced-chart Loading advanced-chart…
totally-unknown-zzz (unknown-key control) alert none Unknown component type: … (OBJUI-001)

The mechanism: SchemaRenderer's lazy branch re-checks hasLazy(type) on every render pass, and Registry.register() deletes a lazy entry only for the keys the loaded module actually registers. An unfulfilled key therefore keeps its entry after the load and every later pass returns the placeholder again. So the observed failure was an endless skeleton, not a red panel — no alert, no error, no console warning. A spinner that never resolves reads to a user as a slow network, which is why this outlived the card that first noticed it.

That makes the grading argument stronger, not weaker: the unknown-key control on the same row is refused loudly, immediately.

2. M1 — fulfilment per variant, measured as the CALL and not the NAME

Driven through the console's own registrations, then await ComponentRegistry.loadLazy(key), then a registry re-check — which is what loadLazy's own docblock instructs callers to do, because it resolves "whether or not the loaded module actually registered the expected type".

variant lazy stub after the real loader verdict
object-chart yes ObjectChartBlock FULFILLED (control)
bar-chart yes ChartBarRenderer FULFILLED (control)
pie-chart yes ChartRenderer FULFILLED (control)
donut-chart yes ChartRenderer FULFILLED (control)
radar-chart yes ChartRenderer FULFILLED (control)
scatter-chart yes ChartRenderer FULFILLED (control)
chart:bar yes ChartRenderer FULFILLED (control)
line-chart yes undefined UNFULFILLED
area-chart yes undefined UNFULFILLED
advanced-chart yes undefined UNFULFILLED

Seven lit controls in the same command, so the probe is looking rather than broken. getKnownTypes() contained all ten — which is the authoring-side half of the defect.

3. M2 — the authored-usage sweep, and the stop condition it clears

R3 makes a positive finding a STOP. Swept both repositories for authored NODES of the three types (not filenames, not prose), with lit controls in the same command:

authored type objectui objectstack
line-chart 1 0
area-chart 0 0
advanced-chart 0 0
bar-chart (lit control) 5 0
chart (lit control) 12 0
object-chart (lit control) 0 1

The single hit is content/docs/plugins/plugin-dashboard.mdx:210 — the doc the card itself puts in the deliverable. No example app, fixture, seed document, preview sample, e2e spec or deployment metadata authors any of the three. ⇒ no STOP.

Two near-misses worth naming because they look like usage and are not:

  • examples/schema-catalog/src/schemas/plugin-charts/area-chart.json and advanced-line-chart.json are FILENAMES. Both author { "type": "chart", "chartType": "area" | "line" }, which is the spelling that already draws.
  • content/docs/guide/component-registry.md:351 shows ComponentRegistry.register('line-chart', LineChart) as a generic example of the register API in a reader's own plugin, not as an ObjectUI key. It is untouched.

Controls discarded rather than kept for padding: pie-chart and object-chart as authored-node controls in objectui both read 0 on both sides, so neither is a control here — object-chart earns its place only in the objectstack column, where it reads 1.

4. The repair chosen, and the argument against the other

Removal (R2's default). The argument against fulfilment is not just "no demand":

  • line-chart and area-chart would duplicate, under a second node key, families the plugin already draws as { "type": "chart", "chartType": "line" | "area" } — resolved by CHART_TYPE_KEYWORD_FAMILIES. Two spellings for one capability is the dialect problem AGENTS.md commandment 0.1 exists to refuse.
  • advanced-chart was never a family at all. It names AdvancedChartImpl, an internal module — registering it would publish an implementation name as an authorable key.
  • The repository has already RULED against arming these. packages/types/src/__tests__/node-slot-registered-arms-8499.test.ts records objectui#8499's decision to leave line-chart unarmed because that card's triage admits arms only for renderers that already draw correctly at runtime — and it carries area-chart in its UNREGISTERED firing-control array, i.e. the repo already asserts that nothing registers it. Fulfilment would red an existing, deliberate control.
  • Measured demand is zero (section 3), so this is declared surface with zero delivery. 声明即强制 cuts toward removing the declaration.

Both stub loops move, and that is load-bearing rather than scope creep. apps/console/src/preview-gallery.tsx is a second registerLazy site for the same plugin carrying line-chart and area-chart, and check:doc-types derives its key universe from the UNION of every such loop. Retiring the keys from register-plugins.ts alone would have left them blessed from the gallery, so the doc gate would have stayed green and the whole retirement would have changed nothing an author can observe. Leg 4 of the ablation below measures exactly that world.

5. M3 — the doc

content/docs/plugins/plugin-dashboard.mdx taught { "type": "line-chart", "data": [], "height": 300 } inside a card body. It now teaches the spelling that draws — chart plus chartType: "line", with rows, xAxisKey and series so the snippet is a complete, valid document — plus a short paragraph naming how chart families are actually selected and a Callout recording why the old key is gone.

6. Ablation matrix — every leg mutated, proved on disk, ran, restored, proved restored

Each leg compares the on-disk blob hash against the HEAD blob hash before running (an equal pair aborts as a no-op, an empty hash aborts as a failure), restores with git checkout HEAD -- PATH, and proves restoration by an empty git diff HEAD — not by an exit code.

leg mutation instrument result
base none console pin / CLI pin / check:doc-types 12 passed · 10 passed · exit 0
1 the three stubs put back in BOTH console loops console pin exit 1 — 8 failed / 4 passed
2 the six entries put back in the CLI snapshot CLI pin exit 1 — 6 failed / 4 passed
3 keys stay retired, doc goes back to line-chart check:doc-types exit 1 — plugin-dashboard.mdx:221 [unregistered-doc-type] type 'line-chart'
4 stubs back AND doc teaches line-chart — the pre-repair world check:doc-types exit 0, green ✅

Leg 3 against leg 4 is the whole card in two readings: the same document, the same gate, green while the unfulfilled stub existed and red once it is gone. That is "refused loudly at authoring time" demonstrated on the real gate rather than asserted.

The 4 tests that stayed GREEN in legs 1 and 2 are exactly the control blocks — the fulfilled variants are unmoved by the mutation in both directions.

7. Pins added

  • apps/console/src/__tests__/unfulfilled-chart-stubs-8760.test.tsx — reads the stub list from the app's own SOURCE (never a copy), drives every key through the REAL loader, and fails on the first one that resolves to nothing. Then the retirement as a RENDER outcome: an authored retired node paints one alert and zero placeholders and names OBJUI-001. Controls: pie-chart and bar-chart resolve to their own distinct renderers, stay in getKnownTypes(), and still draw with no alert and no placeholder — each asserted individually, each non-zero on both sides.
  • packages/cli/src/__tests__/unfulfilled-chart-stubs-retired-8760.test.ts — the authoring-time refusal on the PUBLISHED surface: objectui check over real temporary files now reports Unknown schema type "line-chart" where it was silent. Controls: bar-chart / pie-chart stay silent, the spelling the corrected doc now teaches stays silent, and a firing control proves the instrument can still hear a warning at all.
  • packages/types/src/__tests__/node-slot-registered-arms-8499.test.ts — re-pointed. Its line-chart leg asserted toContain("'line-chart'") over the console source and FIRED on this change with its own message, "the console stub moved — re-derive the premise". It now pins the retirement from both sources, and reads the STUB LIST rather than the whole file, because the file still names all three in the ⛔ comment left behind and a substring search would have been satisfied by a re-registration. 26 tests → 28.

8. Verification

run result
pnpm exec vitest run apps/console/ packages/cli/ packages/types/ 293 files, 4868 tests, all passed
turbo run type-check for the three packages (+ dependency-closure build) 38 tasks successful
pnpm lint (turbo run lint, the CI task graph) 47 tasks successful, exit 0
check:doc-types exit 0 — 644 registered keys (was 650: three bare + three namespaced left)
check:doc-snippets (after its scoped 35-package build) exit 0 — 642 of 642 blocks judged, 0 failed
check:doc-examples · check:doc-fences · check:doc-example-ids · check:doc-example-readers exit 0
check:sdui-registration-pins (after the console build) exit 0 — 16 registrations present in the built console
check:prompt-keys · check:handler-key-reads · check:element-data-source-declaration exit 0
check:readme-exports · check:unreferenced-sources · check:test-path-roots · check:new-line-citations exit 0
check:changeset-presence · check:changeset-no-major · check:changeset-claims exit 0
check:control-bytes exit 0 (7408 tracked text files)
node scripts/regenerate-known-schema-types.mjs --check exit 0 — the committed snapshot matches the derivation
node scripts/markdown-test-inputs.mjs --audit exit 0 — 47 candidates, all adjudicated; the edited doc is already a recorded test input, so no ADJUDICATED row is owed
governed-surface guard NOT GOVERNED — 8 paths checked against 5 surfaces, none matched

Every reading above was taken at c517c72fb, which is this branch's only commit. Exit codes were captured before any pipe.

Acceptance notes

Found and deliberately NOT fixed here:

  • noted, not filed: content/docs/guide/component-registry.md:351 uses line-chart as the example key in a generic ComponentRegistry.register illustration. It teaches the API, not an ObjectUI key, and check:doc-types exempts it by file; changing it would be a style edit on an unrelated document. Carrier if anyone does touch it: the next PR editing that guide.
  • noted, not filed: apps/console/src/register-plugins.ts and apps/console/src/preview-gallery.tsx keep two hand-maintained copies of the chart stub list that nothing compares to each other — this card's own repair had to edit both. A parity pin between the two would be the general fix; today the new console pin covers only register-plugins.ts. Carrier: the next PR that adds a plugin to either list.
  • noted, not filed: check:doc-types blesses any key a registerLazy stub declares, whether or not the target module fulfils it. This card repairs the instance; the class stays open for the other lazy loops (dashboard, map, tree, report, calendar, kanban, timeline, gantt, markdown), which were not measured here. Carrier: no single PR — this is the generalisation of objectui#8760 and would want its own card if the maintainer wants the sweep.

⛔ Not touched, per the card's own scope ruling: objectui#8499's AnyComponentSchema arms. That card is about renderers that already draw; this is the opposite case, and AnyComponentSchema refused all three spellings before this change and refuses them after — a reading this PR did not move and therefore does not claim.

Draft on purpose: not enqueued, no auto-merge, not flipped to ready.


Generated by Claude Code

…e charts plugin never fulfils

`apps/console` registered ten chart variants as `registerLazy` stubs pointing at
`@object-ui/plugin-charts`. That package registers eight keys, and three of the
ten -- `line-chart`, `area-chart`, `advanced-chart` -- were not among them.

An unfulfilled stub does not fail, it succeeds at being useless. At render,
`SchemaRenderer`'s lazy branch re-checks `hasLazy(type)` on every pass and
`Registry.register()` deletes a lazy entry only for the keys the loaded module
actually registers -- so an unfulfilled key keeps its entry and every pass
returns the placeholder. Measured through the real chain: `line-chart` painted
`Loading line-chart...` permanently, with no alert and no error, rather than the
OBJUI-001 panel. At authoring, a stub is enough to enter `getKnownTypes()`, so
`check:doc-types` and the CLI's `KNOWN_SCHEMA_TYPES` snapshot blessed all three
and `content/docs/plugins/plugin-dashboard.mdx` taught one of them.

Removal rather than implementation: `line-chart` / `area-chart` duplicate
families the plugin already draws as `chart` + `chartType`, `advanced-chart`
named an internal module, and an authored-usage sweep over both repositories
found exactly one occurrence -- the doc snippet corrected here -- against lit
controls in the same commands.

Both console stub loops move, because the doc gate's key universe is their
union; the dashboard snippet is corrected to `chart` + `chartType: "line"`; the
generated CLI snapshot is regenerated; and the `line-chart` leg of
`node-slot-registered-arms-8499.test.ts` is re-pointed, reading the stub list
rather than the file so the retirement comment cannot satisfy it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 51 chunks) 3112.4 KB 3134.8 KB
Main entry chunk (gzip) 144.2 KB 350 KB
Entry file index-DjdYhDuc.js
Status PASS

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 500.84KB 114.81KB
core (index.js) 8.52KB 3.41KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 209.38KB 57.92KB
fields (index.js) 247.41KB 62.43KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.21KB 2.26KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.95KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.03KB 13.93KB
plugin-charts (index.js) 71.52KB 19.98KB
plugin-chatbot (index.js) 195.32KB 46.51KB
plugin-dashboard (index.js) 131.27KB 34.62KB
plugin-designer (index.js) 215.68KB 44.27KB
plugin-detail (index.js) 253.02KB 65.74KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.79KB 34.19KB
plugin-gantt (index.js) 166.94KB 41.04KB
plugin-grid (index.js) 211.56KB 57.50KB
plugin-kanban (index.js) 46.10KB 14.33KB
plugin-list (index.js) 112.58KB 27.65KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.54KB 3.31KB
plugin-view (index.js) 84.42KB 20.80KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 94.03KB 31.02KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

Copy link
Copy Markdown
Collaborator Author

Contract review — head c517c72fbfPASS

Reviewed-by: domain:ui PM seat (os-tesla), R16, 2026-09-12T01:5xZ.

Clause-② yes--pair 9225 reads ✓ on both carriers (PR #9225 / card objectui#8760), declaration readable in the fixed spelling, carriers agree. ⛔ Not revised on delivery.

CI: 36 checks, 0 pending, 0 failing.

The premise correction is the most valuable thing in this PR

I dispatched this with the boundary marked: what I had grepped was "registered", not "unfulfilled", and I said the latter was the seat's to measure. It measured it as the CALL — console registrations → real ComponentRegistry.loadLazy → registry re-check — and got 7 of 10 fulfilled, with seven lit controls in the same command.

⭐ It also corrected the card, against the card's own author and against me: an unfulfilled key does NOT paint OBJUI-001. SchemaRenderer re-checks hasLazy on every pass and Registry.register() deletes a lazy entry only for keys the module really registers, so the stub survives the load and the node paints role="status" / Loading line-chart… forever — no alert, no error, no warning, with the unknown-key control on the same run painting OBJUI-001 immediately.

⇒ That strengthens the grading rather than weakening it. A permanent skeleton reads to a user as a slow network; a refused key reads as a mistake they can fix. The card said "worse than an unknown key" and was right for a better reason than it gave.

The stop condition fired clean, and the direction was re-argued rather than inherited

The authored-usage sweep across both repositories returned exactly one hit — content/docs/plugins/plugin-dashboard.mdx:210, the doc this PR corrects — against lit controls in the same commands (bar-chart 5, chart 12, object-chart 1 in the sibling repo). ⛔ No example app, fixture, seed document or preview sample authors any of the three, so nothing stops. ⭐ And the catalog's area-chart.json / advanced-line-chart.json are filenames that author type: 'chart' + chartType — correctly not counted as hits.

Removal over fulfilment is argued on measurement, not taste: line-chart / area-chart would mint a second spelling for families the plugin already draws via chartType; advanced-chart named AdvancedChartImpl, an internal module; and objectui#8499 already ruled line-chart unarmed and carries area-chart in its UNREGISTERED firing-control array, so fulfilment would have reddened an existing deliberate control.

Bump call — agreed

console / cli / types all minor. Three published component keys are withdrawn, and this repo's version policy ships a breaking change as minor. ⚠️ Nothing that worked stops working — the keys resolved to undefined and painted a permanent stub — so an authored document naming them moves from a silent hang to a loud refusal, which is the improvement, not the cost.

Evidence accepted

  • Both console registerLazy loops edited, and that is load-bearing: check:doc-types derives its key universe from the union of register-plugins.ts and preview-gallery.tsx, so moving only one would have changed nothing observable.
  • Legs 3 and 4 are the card in two readings — same document, same gate: with the stub gone the doc teaching line-chart reds ([unregistered-doc-type]), and with the stub restored the same doc goes green. That is the blindness the card is about, demonstrated rather than asserted.
  • Legs 1 and 2 redden the console pin (8 failed) and the CLI pin (6 failed); the 4 that stay green in both are the fulfilled-variant controls, each asserted individually, each non-zero on both sides.
  • An existing pin (node-slot-registered-arms-8499.test.ts) fired on this change with its own "re-derive the premise" message and was re-pointed to read the stub list rather than the file, so a retirement comment cannot satisfy it. ⇒ the pin was strengthened by being tripped, not silenced.

Out-of-scope, noted not filed — ⛔ correctly left alone

register-plugins.ts and preview-gallery.tsx keep two hand-maintained copies of the stub list with nothing comparing them; and check:doc-types blesses any key a stub declares whether or not the module fulfils it — the class stays open for the other nine lazy loops, which were not measured here. ⭐ The seat named that generalisation and declined to sweep it uninstructed. Correct: it would want its own card and the maintainer's word on scope.

Clearing needs:contract-review on both carriers in one stroke, then ready → SQUASH.


Generated by Claude Code

@os-tesla
os-tesla marked this pull request as ready for review September 12, 2026 01:52
@os-tesla
os-tesla added this pull request to the merge queue Sep 12, 2026
Merged via the queue into main with commit 6a4680b Sep 12, 2026
38 checks passed
@os-tesla
os-tesla deleted the claude/issue-8760-unfulfilled-chart-stubs branch September 12, 2026 02:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apps documentation Improvements or additions to documentation package: cli package: types tests

Projects

None yet

2 participants