You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Found while implementing #6805 + #6806 (the scroll-area/badgecontent pair), by censusing
every badge node in the catalog to size that PR's corpus sweep. Out of that PR's fence — it
names the two badge nodes authoring content in sidebar-with-badges — so it is filed
rather than fixed.
Same defect class as #6773 / #6788 / #6805 / #6806, a different phantom key. Those four are
all content. This one is children, and that difference is why none of the existing
instruments see it.
Measured
packages/components/src/renderers/data-display/badge.tsx:32 renders schema.label || renderChildren(schema.body). It reads label and body. It does not read children — unlike card.tsx, which reads children || body.
Seven catalog badge nodes author children anyway. Census over all 431 fixtures, on origin/main26896c689:
badge nodes 40 in 12 categories
keys authored on them: type 40 · variant 36 · label 31 · className 8 ·
children 7 · content 2
The content 2 are #6806, repaired in PR for #6805/#6806. The children 7 are this card:
components-basic-span/default-badge children: [ text ]
components-basic-span/secondary-badge children: [ text ]
components-basic-span/status-badges .children[0..2] children: [ text ] (3 nodes)
core-schema-renderer/nested-schema-example ...children[0..1] children: "Nested" /
children: "Components"
Rendered through the real SchemaRenderer the way the docs gallery renders them:
entry elements text
components-basic-span/default-badge 2 ""
components-basic-span/secondary-badge 2 ""
components-basic-span/status-badges 5 ""
core-schema-renderer/nested-schema-example 13 "Parent ComponentSibling Component
All rendered from a single schema tree"
Three of those entries draw literally nothing — the whole demo is one empty pill. The
fourth renders its surrounding prose and silently drops both badges (Nested and Components are absent from its text).
components-basic-span is a badge category: three of its entries are empty boxes on the
published page.
⭐ Why every existing instrument is blind to this one
This is the part worth keeping. The content members of this class are caught, in principle,
by two different signals. This variant emits neither.
catalog-gallery-render.test.tsx passes — via a THIRD escape route. Its non-vacuity
control is elements > WRAPPER_ELEMENTS || text, with WRAPPER_ELEMENTS = 2. Measured in
that file's own harness:
Neither zod nor tsc: BaseSchema is .passthrough() and carries [key: string]: any, and children is declared on BaseSchema — so this is worse than the content case, where
at least a declared-key check would bite. children is declared and unread, which is
exactly the shape PR docs(context-menu): author the trigger card's text under the key ui:card reads #6807's "READ set is strictly stronger than the DECLARED set" note
calls out, with variant as its example.
⛔ Why this is filed, not fixed — the repair key is a genuine decision
The content members had one mechanical answer. This one has two, and they differ in kind:
A. Re-author the seven fixtures to label. Cheap, matches the 31 badge nodes that
already author label, converges the corpus on one spelling. But five of the seven author children: [ a text node ], so this flattens a node into a string, and it does not help the
next author who writes children on a badge because every other container renderer accepts
it.
⇒ this needs a ruling, not a sweep. Related to #6810 (the open needs-user-decision card
asking whether this class gets a global instrument): this is the fifth rediscovery, the
first one under a different key, and the first that the leak signature cannot find.
Related
#6810 (the decision card for this class) · #6805 · #6806 · #6788 · #6773 · #6771 (retiring body) · #5574 (the DOM-leak class the content members belong to and this one does not)
Found while implementing #6805 + #6806 (the
scroll-area/badgecontentpair), by censusingevery
badgenode in the catalog to size that PR's corpus sweep. Out of that PR's fence — itnames the two
badgenodes authoringcontentinsidebar-with-badges— so it is filedrather than fixed.
Same defect class as #6773 / #6788 / #6805 / #6806, a different phantom key. Those four are
all
content. This one ischildren, and that difference is why none of the existinginstruments see it.
Measured
packages/components/src/renderers/data-display/badge.tsx:32rendersschema.label || renderChildren(schema.body). It readslabelandbody. It doesnot read
children— unlikecard.tsx, which readschildren || body.Seven catalog
badgenodes authorchildrenanyway. Census over all 431 fixtures, onorigin/main26896c689:The
content 2are #6806, repaired in PR for #6805/#6806. Thechildren 7are this card:Rendered through the real
SchemaRendererthe way the docs gallery renders them:Three of those entries draw literally nothing — the whole demo is one empty pill. The
fourth renders its surrounding prose and silently drops both badges (
NestedandComponentsare absent from its text).components-basic-spanis a badge category: three of its entries are empty boxes on thepublished page.
⭐ Why every existing instrument is blind to this one
This is the part worth keeping. The
contentmembers of this class are caught, in principle,by two different signals. This variant emits neither.
No DOM leak. The
contentmembers leak the authored string to the host element ascontent="..."— the finding: the DOM-leak sweep never reachespackages/components/src/renderers/**— four layout/basic renderers still carry the unfixed spread #5574 signature, and what made finding(docs,examples): all fiveaspect-ratiodocs demos authorcontent, a key the renderer never reads — every demo on the published page renders an empty ratio box #6773/finding(examples): the basic-context-menu demo authors its trigger card undercontent, which ui:card never reads — the tile is an empty dashed box #6788/finding(examples): all seven components-complex-scroll-area demos author their body undercontent, which ui:scroll-area never reads — every box on the page is empty #6805/finding(examples): sidebar-with-badges authors its two counts undercontent, which ui:badge never reads — the badges render empty #6806 findable byattribute sweep. Measured here:
leaked[content] = 0on all four entries.childrenis apipeline key the renderer machinery consumes, so it never reaches the DOM. A leak sweep
cannot find this.
catalog-gallery-render.test.tsxpasses — via a THIRD escape route. Its non-vacuitycontrol is
elements > WRAPPER_ELEMENTS || text, withWRAPPER_ELEMENTS = 2. Measured inthat file's own harness:
The empty badge's own host element is the third element, so a demo that draws nothing
but an empty pill clears the control on the pill. That is distinct from the two escapes
already recorded on finding(examples): all seven components-complex-scroll-area demos author their body under
content, which ui:scroll-area never reads — every box on the page is empty #6805 (Radix's injected scrollbar stylesheet counting as text) andfinding(examples): sidebar-with-badges authors its two counts under
content, which ui:badge never reads — the badges render empty #6806 (a large correct render hiding a small omission). ⇒ three different holes in thesame control, which strengthens the [Decision] What instrument stops the container-declaration class regenerating — and do the remaining 45 get fixed before it lands? #6779-style argument that the instrument belongs
per-renderer rather than in a stricter global threshold.
Neither zod nor tsc:
BaseSchemais.passthrough()and carries[key: string]: any, andchildrenis declared onBaseSchema— so this is worse than thecontentcase, whereat least a declared-key check would bite.
childrenis declared and unread, which isexactly the shape PR docs(context-menu): author the trigger card's text under the key ui:card reads #6807's "READ set is strictly stronger than the DECLARED set" note
calls out, with
variantas its example.⛔ Why this is filed, not fixed — the repair key is a genuine decision
The
contentmembers had one mechanical answer. This one has two, and they differ in kind:label. Cheap, matches the 31badgenodes thatalready author
label, converges the corpus on one spelling. But five of the seven authorchildren: [ a text node ], so this flattens a node into a string, and it does not help thenext author who writes
childrenon a badge because every other container renderer acceptsit.
badge.tsxto readchildren || body, the waycard.tsxalready does. Makesthe renderer consistent with its siblings and fixes all seven fixtures without touching
them. But it widens a published renderer's read set, which AGENTS.md #0.1 governs, and
finding(sdui-parser/components): the manifest tier reports
unknown-proponbody— the one child-list key 10+ registrations actually honour #6771 is retiringbodyas achildrendialect — so the right spelling under B ischildren || bodytoday andchildrenafter finding(sdui-parser/components): the manifest tier reportsunknown-proponbody— the one child-list key 10+ registrations actually honour #6771 lands.⇒ this needs a ruling, not a sweep. Related to #6810 (the open
needs-user-decisioncardasking whether this class gets a global instrument): this is the fifth rediscovery, the
first one under a different key, and the first that the leak signature cannot find.
Related
#6810 (the decision card for this class) · #6805 · #6806 · #6788 · #6773 · #6771 (retiring
body) · #5574 (the DOM-leak class thecontentmembers belong to and this one does not)Generated by Claude Code
Generated by Claude Code