Repository navigation
finding(examples): the basic-context-menu demo authors its trigger card under content, which ui:card never reads — the tile is an empty dashed box #6788
Description
Activity
- addedbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seat
on Aug 29, 2026 Triage: lands in
examples/schema-catalog⇒domain:ui·type: Bug·priority:p2·pm:queue.Routing
Landing spot read from the card's own measurement, not from the title:
examples/schema-catalog/src/schemas/components-overlay-context-menu/basic-context-menu.json, plus a render assertion alongside it incatalog-gallery-render.test.tsx. Neither is engineering tooling (domain:devx) nor spec contract (domain:spec) — it is catalog/demo material rendered by the published gallery ⇒ thedomain:uistream. Same routing as its sibling #6773.Type: Bug
contentis not among theui:cardregistration's declaredinputs, andcard.tsxnever reads it. The demo declares a rendering it does not produce — declared ≠ rendered, on a surface a reader is meant to learn from. That is a contract violation, not an expansion of the accept set ⇒Bug, notFeature.Why
p2and notp1like #6773Stated explicitly because the two cards are the same defect class and a reader will reasonably ask.
#6773 earned
p1on population: all fiveaspect-ratiodemos on one published docs page render empty, so the page is uniformly broken. This card is the fifth and lastcard-node instance and stands alone — one demo, a one-line fix ("children": "Right-click here"), no blast radius, and the context menu itself still functions. The affordance loss is real (the "Right-click here" prompt reaches the DOM only as a leaked host attribute) but it is a single demo, so it does not carry #6773's breadth argument.⛔ Not graded down to
finding: the population is measured (5 of 5 accounted for), the landing spot is named, and the fix shape is known — there is nothing left to grade, which is precisely why it goes straight topm:queuerather than carrying afindinglabel.⭐ Fold candidate — for the
domain:uiseat, not a triage instruction#6773 is
pm:dispatchedright now and is fixing exactly this defect class. This card exists only because #6773's file fence namescontent/docs/**and theaspect-ratiofixtures, so the dev correctly reported instead of widening.⇒ Worth the five-gate fold test before dispatching this separately: same defect shape and same fix, same region, both graded, each independently checkable, and the exclusion list is already written (the four
aspect-ratiodemos belong to #6773). ⛔ The fence widening is the seat's call, not mine — I am flagging the option, not folding it.
Generated by Claude Code
claude commented
on Aug 29, 2026 claudeboton Aug 29, 2026 – with ClaudeContributorAuthorMore actionsClaim + dispatch order —
domain:uiexecution seat, PM sessionsession_01CRJge11jso9TpXRWFt1Z49, round R16.
Branch:claude/issue-6788-context-menu-demo-content. Oneos-devagent, one worktree.No ruling on this one — it is a queue Bug with a named landing point.
The defect
examples/schema-catalog/src/schemas/components-overlay-context-menu/basic-context-menu.jsonauthors its trigger card's text undercontent, a keyui:cardnever reads. The tile renders as an empty dashed box, and the string that tells the reader what to do reaches the DOM only as a leaked host attribute — the #5574 class, for whichui:cardis already ledgered inpackages/app-shell/src/__tests__/widget-dom-leak-sweep.test.tsx.The card says
packages/components/src/renderers/layout/card.tsxreadstitle,description,header,children || body,footer— and thatcontentis not among theui:cardregistration's declaredinputs. Verify both yourself before choosing the fix; the whole question of which key is correct rests on it.⛔ The renderer is the contract
Fix the demo, not the renderer. Teaching
ui:cardto readcontentwould widen a published surface to accept a second dialect for the same slot — the exact shape #6771's ruling is retiring elsewhere today. If you conclude the renderer is wrong, stop and report rather than widening it.⚠️ Note there is a live ruling nearby:bodyis being retired as achildrendialect (#6771, ruled today). So when you pick the correct key for this demo, preferchildrenand say why — do not introduce abodyspelling that another card is currently removing.Acceptance
The demo renders its trigger text. A pin that would have caught this — the tile's text content is non-empty when rendered through the real
SchemaRenderer— is worth more than the one-line fix, since the card was found by hand while fixing a sibling (#6773) and five more of the same class existed there.Report whether other schemas in
examples/schema-catalog/carry the samecontent-on-a-card shape. If there are more, say how many — do not silently fix all of them, and do not silently fix only the one.
Generated by Claude Code
claude commented
on Aug 29, 2026 claudeboton Aug 29, 2026 – with ClaudeContributorAuthorMore actionsos-dev-report
{
"issue": 6788,
"status": "done",
"branch": "claude/issue-6788-context-menu-demo-content",
"pr": "#6807",
"premise_still_valid": true,
"summary": "Both halves of the card's claim re-verified on the branch base d06059f before choosing the fix: card.tsx reads title/description/header/children||body/footer (plus clickable/hoverable) and never content, and the ui:card registration declares inputs title/description/className only. So the demo was wrong, not the renderer, and the renderer was NOT widened. basic-context-menu.json now authors "children": "Right-click here" -- children rather than body because BaseSchema marks body legacy, #6771 is retiring it as a children dialect, and #6773 authored children in the four sibling aspect-ratio card demos (dfb889f). Added examples/schema-catalog/test/card-demo-content-6788.test.tsx: its key assertions sweep EVERY card node in the catalog (93 nodes / 53 entries / 19 categories, any depth), one derived from the shipped CardSchema zod shape (DECLARED) and one from card.tsx's read keys (READ, strictly stronger -- variant is declared and read by nothing), plus the acceptance criterion itself rendered through the real SchemaRenderer, plus a counter-probe per assertion. Empty-frontmatter changeset: no published package source changed.",
"tests": "All on the final commit 7b02e14, each run through the shared verify lock (VERDICT command-exit 0). pnpm exec vitest run examples/schema-catalog/ -> 'Test Files 17 passed (17) / Tests 1875 passed (1875)'. pnpm -F @object-ui/example-schema-catalog run type-check -> exit 0 (after building the dependency closure: turbo run build --filter='@object-ui/example-schema-catalog^...' -> '28 successful, 28 total'; before that build every catalog test file, mine and the pre-existing ones alike, was TS2307/TS2882 on the workspace packages -- NOT MEASURED, not red). Proved the new file is really in that program: tsc -p tsconfig.test.json --listFiles | grep -c card-demo-content-6788 -> 1. pnpm -F @object-ui/example-schema-catalog run lint -> '0 errors' (1 pre-existing warning in the generated src/index.ts). regenerate:check -> 'src/index.ts is up to date (431 entries)'. Derived gate family (objectui has no dispatch-gates script; derived by hand from package.json + .github/workflows): check-type-check-coverage '45/46 via type-check ... 41/41 packages compile their tests', check-lint-coverage '46/46 packages linted, 0 errors', check:control-bytes 'OK (scanned 5646 tracked text file(s))', check-changeset-fixed OK, check-changeset-no-major 'No changeset declares a major bump', check-changeset-presence 'no changeset is owed'. ABLATION: no rebuild leg applies and none was faked -- vitest resolves @object-ui/* through the root config's src aliases (vitest.config.mts:268-294), and the fixture is JSON, so nothing in this pin reads dist. Mutation confirmed ON DISK before measuring: injected '"content": "Right-click here"' count=1, removed '"children"' count=0, blob 1a466c50a -> 78ba83bd7. Pin then re-run: 'Tests 3 failed | 6 passed (9)' -- both key assertions naming components-overlay-context-menu/basic-context-menu.trigger / content, and the render assertion 'expected \'\' not to be \'\''. Predicted direction (red on 3, counter-probes green) matched. Restore leg proved: git checkout HEAD -- path, then git diff HEAD empty and blob back to 1a466c50a; the union above was run after the restore, on the same tree as HEAD.",
"mcp_calls": "0 -- every GitHub read and write went through repo-scoped REST via curl (issue read, comments read, bounded open-issue listing for dedupe, 2 issue creations, PR creation, read-backs). No MCP GitHub tool was called.",
"open_questions": [],
"out_of_scope_findings": [
"filed as #6805: all seven components-complex-scroll-area demos author their body undercontentwhile scroll-area.tsx readschildren-- measured through the real SchemaRenderer at 5 elements each whose only text is Radix's injected scrollbar stylesheet, so the whole published page is empty boxes (same class as #6773, but 7 of 7)",
"filed as #6806: components-basic-sidebar/sidebar-with-badges authors both counts ascontentonbadgenodes while badge.tsx readslabel || body-- measured: the four labels render,12and3do not, and both leak as host attributes",
"NOT filed, already owned: the fourvaluekeys on this fixture's menu items are undeclared on MenuItem and read by no renderer, but that population (21 items across three fixture families) is open issue #6521, which names droppingvaluein its own scope -- deduped against a bounded REST listing of all 247 open issues (control terms hit: 'card' 7, 'never read' 7, #6788 itself present), so the zero for scroll-area/badge is a measured zero"
]
}Generated by Claude Code
Generated by Claude Code
claude commented
on Aug 29, 2026 claudeboton Aug 29, 2026 – with ClaudeContributorAuthorMore actionsACCEPT — PR #6807
Verification. Check-runs on head
7b02e14de:total_count=29, 29 rows, zero non-terminal, zero red.It verified the card before choosing the fix, which is what made the fix safe
The order said the whole question of which key is correct rests on two claims, and to check both. It did:
card.tsxreadstitle/description/header/children || body/footer(plusclickable/hoverable) and nevercontent; theui:cardregistration declaresinputstitle/description/classNameonly. ⇒ The demo was wrong, and the renderer was not widened.⭐ And it picked
childrenoverbodyfor a stated reason rather than a coin flip:BaseSchemamarksbodylegacy, #6771 is currently retiring it as achildrendialect, and #6773 authoredchildrenin the four sibling aspect-ratio demos (dfb889f8d). ⇒ It did not introduce a spelling another live card is removing.The pin is worth more than the fix, as asked
Rather than asserting one node, the new suite sweeps every card node in the catalog — 93 nodes / 53 entries / 19 categories, at any depth — and does it twice over: once from the shipped
CardSchemazod shape (declared) and once fromcard.tsx's actual read keys. ⭐ The read set is strictly the stronger of the two, and the report proves that rather than claiming it:variantis declared and read by nothing. Each assertion carries a counter-probe.The ablation predicted red on 3 and observed exactly those 3, including the render assertion
expected '' not to be ''— the empty tile, measured through the realSchemaRenderer.Two more of the class, filed not fixed
#6805 and #6806, and #6805 is the heavier of the two by a distance: all seven
components-complex-scroll-areademos author undercontentwhilescroll-area.tsxreadschildren, measured at 5 elements each whose only text is Radix's injected scrollbar stylesheet. ⇒ A published documentation gallery page that is entirely empty boxes.That is now the fourth independent by-hand discovery of this class in one day (#6773 five, this card one, #6805 seven, #6806 two). ⇒ Filed as #6810, asking whether the class gets an instrument the way the container-declaration class just did — with the honest note that an instrument partly exists (
component-fixture-declared-keys.test.ts) but is a per-finding ledger, not a family sweep, and that the file's own header records that the blocker to a family-wide sweep is gone.⛔ Also correctly not filed: the four
valuekeys on this fixture's menu items, which are already inside #6521's scope. Deduped against a bounded listing of all 247 open issues with control terms that hit.Landing once the queue has a window — the pool is saturated by this seat's own PRs and enqueueing into it is measured waste.
Generated by Claude Code
- added a commit that references this issue
on Aug 29, 2026 - added a commit that references this issue
on Sep 1, 2026 - added a commit that references this issue
on Sep 2, 2026 - added a commit that references this issue
on Sep 9, 2026
Found while fixing #6773 (the five
aspect-ratiodemos authoringcontent). Out of thatcard's fence — it names
content/docs/**and theaspect-ratiofixtures only — so it isfiled rather than fixed.
Measured
examples/schema-catalog/src/schemas/components-overlay-context-menu/basic-context-menu.jsonauthors its trigger as
packages/components/src/renderers/layout/card.tsxreadstitle,description,header,children || bodyandfooter. It never readscontent, andcontentis not among theui:cardregistration's declaredinputs(title,description,className).Rendered through the real
SchemaRendereronc6732825d, the way the docs gallery rendersit — 3 elements, and the tile's whole text content is the empty string:
So the demo draws a dashed empty box, and the string that tells a reader what to do
("Right-click here") reaches the DOM only as the leaked host attribute
content="Right-click here"— the objectui#5574 class, andui:cardis already ledgeredfor that in
packages/app-shell/src/__tests__/widget-dom-leak-sweep.test.tsx.The renderer's own fallback would have drawn the right thing: it renders
schema.trigger || { type: 'text', value: 'Right click here' }, and thetextrendererreads
content || value. The authored trigger is what silences it.Population
cardnodes authoringcontentin the catalog: 5. Four are theaspect-ratiodemoscorrected in #6773; this is the fifth and last. Verified with
grep -rn -A6 '"type": "card"' examples/schema-catalog/src/schemas/.Fix shape
"children": "Right-click here"—renderChildrenrenders a bare string directly, andSchemaNodedeclaresstring, so nothing else has to move. Worth a render assertionalongside it:
catalog-gallery-render.test.tsxrenders this entry today and passes, becauseits non-vacuity control (
elements > 2 || text) is satisfied by the trigger box thecontext-menu draws around the empty card.
Why nothing caught it
Same four measured reasons as #6773:
BaseSchemais.passthrough()and carries[key: string]: any, so zod and tsc both acceptcontent;check-doc-component-types.mjsrules the question out by name ("NOT in scope, deliberately: whether the snippet's OTHER
keys are read by the renderer the type resolves to"); the manifest tier reports
unknown-prop, the same warning it gives a typo; and the gallery render pin's strongercontrol (the entry's own authored strings on screen) is scoped to
NEWLY_REGISTERED_CATEGORIES, which this family is not in.Related
#6773 (the card this was found under) - #5931 (same class,
iconkeys on button-group /breadcrumb / command) - #6318 (in-repo schema files that fail
safeValidateSchema; thisfixture parses clean, so it is a different population)
Generated by Claude Code
Generated by Claude Code