Uh oh!
There was an error while loading. Please reload this page.
fix(types): retire the designer-surface dashboard aria pair (#5852) - #6104
Merged
Merged
Conversation
Remove `DashboardConfig.aria` (packages/types/src/designer.ts) and turn its Zod
twin `DashboardConfigSchema.aria` (packages/types/src/zod/complex.zod.ts) into an
ADR-0049 retirement tombstone.
The pair declared `{ label?, description? }` — spellings that match neither
@objectstack/spec's `AriaProps` (`ariaLabel`/`ariaDescribedBy`/`role`) nor any
renderer vocabulary, so no read point could have consumed them. Re-measured on
main: zero `.aria` reads in plugin-designer/src, plugin-dashboard/src and
apps/console/src (the same grep family finds the live `schema.aria` reads in
plugin-detail and plugin-list); zero occurrences of either name in objectstack;
and DashboardConfigPanel.tsx — the panel the interface's doc comment claims to
serve — imports neither name.
- TS half: plain deletion + in-place comment tombstone, mirroring the landed
shape of #5855 (#5830) on the sibling `DashboardComponentSchema.aria`. The
interface's `[key: string]: any` catch-all means an authored `aria` still
compiles; what goes is the type-level suggestion and the false contract claim.
- Zod half: `z.never({ error }).optional().describe(...)` rather than a plain
delete. Measured: `DashboardConfigSchema` is a bare `z.object` with no
`.strict()`, so a deletion would have turned an accepted-and-PRESERVED key
into a silently STRIPPED one (the #6068 behaviour). Loud refusal is this
package's ruled outcome for retirements (data-display.zod.ts
StaticTableColumnSchema, the set crud.zod.ts `confirm` established).
- Tests: the aria-only pin in dashboard-config.test.ts is FLIPPED, not deleted —
it now asserts refusal by name and message, with two controls (an undeclared
key still rides through, proving the red is the tombstone and not strictness;
a legal config still parses). The `aria:` line in the full-config TS literal is
replaced by a removal note; kept, it would have green-washed through the index
signature.
Claude-Session: https://claude.ai/code/session_01CSoz9uGhaaSgiq3hshtN7L
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>Contributor
✅ Console Performance Budget
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
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 24, 2026 17:35
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#5852
Retires the designer-surface dashboard
ariapair:DashboardConfig.aria(
packages/types/src/designer.ts) and its Zod twinDashboardConfigSchema.aria(
packages/types/src/zod/complex.zod.ts).The premise, re-measured on
main(not inherited)The pair declared
{ label?: string; description?: string }— spellings thatmatch neither
@objectstack/spec'sAriaPropsvocabulary(
ariaLabel/ariaDescribedBy/role) nor anything a renderer maps..arianon-test reads inplugin-designer/src,plugin-dashboard/src,apps/console/srcDashboardConfigSchemarefs outsidepackages/typesDashboardConfigtype refs outsidepackages/typesindex.tsre-export, 2 test files only)objectstackrepo (3637731)PageNodeSchemaby the identical greppackages/types.ariamember reads by the identical grepplugin-detail/renderers/record-quick-actions.tsx:201,record-path.tsx,plugin-list/ListView.tsx:2661The controls matter: a zero-hit grep with no known-present control is an untested
instrument, not a measurement.
The card's second claim also holds.
packages/plugin-dashboard/src/DashboardConfigPanel.tsx— the panel
DashboardConfig's own doc comment says it serves — importsConfigPanelSchemafrom@object-ui/componentsand neitherDashboardConfignor
DashboardConfigSchema, and contains noariaread. So this is aretirement, not a wiring card.
The shape, mirrored from #5830 / PR #5855
That sibling's landed shape was: delete the TS member, leave an in-place comment
tombstone, and let the Zod twin refuse the key by name with a message (it
inherited a
retiredKeytombstone from the spec). Its aria-only test wasreplaced by a house-style removal note, not silently dropped.
This card has no spec tombstone to inherit —
DashboardConfigis adesigner-local model. Mirroring #5830's end state rather than only its
mechanism:
DashboardConfigcarries[key: string]: any, so an authoredariastill compiles; what is removed isthe type-level suggestion and the false contract claim. Same honest caveat
finding(types):
DashboardComponentSchema.ariadeclares a key the spec tombstoned and no renderer reads — stale "Aligned with @objectstack/spec AriaPropsSchema" claim #5830 recorded for its own index signature.z.never({ error }).optional().describe(...),following this package's existing convention (
data-display.zod.tsStaticTableColumnSchema, the setcrud.zod.tsconfirmestablished), whosedoc block states the ruling directly: "Loud refusal is the ruled outcome."
Why not a plain deletion of the Zod key — measured, not assumed
DashboardConfigSchemais a barez.objectwith no.strict(). Measured onbuilt
dist/before the change:So a plain deletion would have converted an accepted-and-preserved key into a
silently dropped one — quiet data loss, and precisely the #6068 behaviour
("a plain
z.objectwith no.strict()strips unknown keys rather than refusingthem"). After the tombstone, measured on
dist/:z.never({ error })rather than a barez.never()because the bare form refuseswith zod's generic
Invalid input: expected never, received object— the key isnamed only via the issue path and the
.describe()text never reaches theauthor.
Test readers — flipped, not deleted
Both references live in
packages/types/src/__tests__/dashboard-config.test.ts:aria:line inside the "should accept a full DashboardConfig" TS literal→ replaced with a removal note. Kept, it would have gone on compiling through
the index signature while asserting the opposite of the contract — the exact
green-wash finding(types):
DashboardComponentSchema.ariadeclares a key the spec tombstoned and no renderer reads — stale "Aligned with @objectstack/spec AriaPropsSchema" claim #5830 called out.it('should validate aria accessibility attributes'), which assertedsuccess === true→ flipped to assert refusal by name and message, plus twocontrols. Note that after a plain deletion this test would have stayed
green (unknown key stripped), which is why the flip matters.
Verification
Predicted before running: after a removal the sweeps must stay green (the
positive evidence nothing consumed the pair), and that green is weak alone — so a
counter-probe must show the same instrument going red.
pnpm --filter @object-ui/types type-checkvitest run packages/types/src --maxWorkers=2turbo run type-check --filter='...@object-ui/types' --concurrency=2 --forcenode scripts/check-changeset-presence.mjsnode scripts/check-changeset-no-major.mjsnode scripts/check-changeset-fixed.mjspnpm check:esm-specifiersnpx eslintover the 3 changed files,--format jsonno-explicit-anygrep -naPcontrol-byte class on changed filesAll run on committed head
697226d36. The cold sweep is deliberately--force:an earlier run reported 77/78 cached, which is indistinguishable from a build
that never looked.
Filter direction demonstrated, not asserted: prefix
...@object-ui/typesmatches 43 packages (downstream dependents); suffix
@object-ui/types...matches 1 (itself — the package has no workspace deps). The
@object-ui/types^...build form prints "No projects matched the filters" andexits 0; that zero-match is genuine here, provable from the manifest,
whose only deps are the external
@objectstack/specandzod.Counter-probe (at the
dist/layer, after committing)Downstream resolves
@object-ui/typesthroughexportstodist/, so asource-only mutation would leave the sweep green and read as "nothing consumes
it". Renamed the genuinely-consumed
PageNodeSchemainlayout.ts, proved themutation on disk in both directions (injected marker present / removed text
absent), rebuilt, and proved it reached
dist/layout.d.ts:packages/componentstsc --noEmit: exit 0 → exit 2. The instrument has teeth.TS7006atrenderers/layout/page.tsx:597(collapsed inference), not the crispTS2305— because the failing build never re-emitteddist/index.d.ts, so thebarrel still re-exported a symbol
layout.d.tsno longer had.dist/(0 files),PageNodeSchemaback, this PR's own changes still present indist/,git diff HEAD --statempty, andpackages/componentstsc --noEmitback toexit 0 — so the red was caused solely by the ablation.
Mutation/restore ran under
trap … EXIT INT TERMwith a cwd-independentgit -Cpinned to the worktree path pluscheckout --, and the edit wascommitted first so the trap could not revert un-committed work along with the
probe (the #5859 lesson).
Changeset
minorper the public-type-break policy (nevermajor—check-changeset-no-major.mjsrefuses it outright). It names both retiredspellings verbatim so a host can grep its own sources, states the two directions
separately (narrowed TS suggestion vs. changed runtime accept/reject), and
carries the external caveat: in-repo zero is not npm zero, and stored dashboard
configuration is not reachable from this seat.
Generated by Claude Code