Measured while fixing #4626 (PR #4630). Filed unassigned. Duplicate-searched (keyword + the two renderer paths + TooltipSchema / TextSchema): no open issue covers it. This is the CLASS question #4626 raised, re-filed standalone with sharper evidence, because #4626's own framing of it turned out to be understated in one direction and wrong in another.
The class
#4626 asked whether an authored key a renderer does not read should be a publish-time rejection rather than silence. Measuring the two entries it named shows the problem is worse than "the entry used the wrong key": for a single registered type there are three places a key can be declared, and they disagree with each other. An author following any one of them can still render blank.
The three surfaces, for one component type:
- the TypeScript schema interface in
packages/types
- the
inputs array in the ComponentRegistry.register(...) meta
- what the renderer function actually reads off
schema
Two measured specimens
tooltip — surface 1 contradicts 2 and 3, and following surface 1 renders blank
packages/types/src/overlay.ts:266 declares children: SchemaNode — required, and it is the only slot the interface declares for the trigger. trigger is declared neither there nor on BaseSchema.
packages/components/src/renderers/overlay/tooltip.tsx:28 reads schema.trigger; line 31 reads schema.content || schema.body. children is read nowhere.
- The registry meta at the same file declares
trigger / content / body.
So an author who follows TooltipSchema — the type the package publishes — authors children and gets a blank tile. That is exactly what the catalog entry did, and it type-checks. The fix in PR #4630 makes the entry author trigger, which is a key TooltipSchema does not declare.
text — surface 2 declares a key surface 1 does not have, and the renderer accepts both
packages/types/src/layout.ts:56 declares value?: string. There is no content on TextSchema, and none on BaseSchema.
- The registry meta declares
content as required: true and defaultProps uses content.
packages/components/src/renderers/basic/text.tsx:35 and :40 both read schema.content || schema.value.
Both spellings work at runtime; each is "the declared one" depending on which surface you read. #4626 asserted that value is not read, and used that to explain a blank tile — measured, value IS read and the tile was not blank.
Why this is worth deciding rather than patching entry by entry
The catalog is the corpus AI authoring tools retrieve from, and this repo's stated aim is making AI-authored metadata hard to get wrong. Today the same type teaches two spellings, the published TypeScript interface can be the WRONG one, and there is no gate anywhere that compares the three. Silent-blank is the failure mode, which no red-tile sweep catches — objectui#4616's non-vacuity control found the tooltip case only because the tile drew literally nothing.
Worth deciding, in rough order of leverage:
- Should the three surfaces be reconciled per type, and which one is canonical? (The registry meta is the only one a designer/inspector reads; the TS interface is the only one an author's editor reads.)
- Should a gate assert that every
inputs name exists on the type interface, and that every key a renderer reads is declared? A source-level check is plausible for the meta-vs-type half.
- Should an undeclared key on a registered type be rejected at publish time rather than ignored?
Refs #4626, #4616, PR #4630.
Generated by Claude Code
Measured while fixing #4626 (PR #4630). Filed unassigned. Duplicate-searched (keyword + the two renderer paths +
TooltipSchema/TextSchema): no open issue covers it. This is the CLASS question #4626 raised, re-filed standalone with sharper evidence, because #4626's own framing of it turned out to be understated in one direction and wrong in another.The class
#4626 asked whether an authored key a renderer does not read should be a publish-time rejection rather than silence. Measuring the two entries it named shows the problem is worse than "the entry used the wrong key": for a single registered type there are three places a key can be declared, and they disagree with each other. An author following any one of them can still render blank.
The three surfaces, for one component type:
packages/typesinputsarray in theComponentRegistry.register(...)metaschemaTwo measured specimens
tooltip— surface 1 contradicts 2 and 3, and following surface 1 renders blankpackages/types/src/overlay.ts:266declareschildren: SchemaNode— required, and it is the only slot the interface declares for the trigger.triggeris declared neither there nor onBaseSchema.packages/components/src/renderers/overlay/tooltip.tsx:28readsschema.trigger; line 31 readsschema.content || schema.body.childrenis read nowhere.trigger/content/body.So an author who follows
TooltipSchema— the type the package publishes — authorschildrenand gets a blank tile. That is exactly what the catalog entry did, and it type-checks. The fix in PR #4630 makes the entry authortrigger, which is a keyTooltipSchemadoes not declare.text— surface 2 declares a key surface 1 does not have, and the renderer accepts bothpackages/types/src/layout.ts:56declaresvalue?: string. There is nocontentonTextSchema, and none onBaseSchema.contentasrequired: trueanddefaultPropsusescontent.packages/components/src/renderers/basic/text.tsx:35and:40both readschema.content || schema.value.Both spellings work at runtime; each is "the declared one" depending on which surface you read. #4626 asserted that
valueis not read, and used that to explain a blank tile — measured,valueIS read and the tile was not blank.Why this is worth deciding rather than patching entry by entry
The catalog is the corpus AI authoring tools retrieve from, and this repo's stated aim is making AI-authored metadata hard to get wrong. Today the same type teaches two spellings, the published TypeScript interface can be the WRONG one, and there is no gate anywhere that compares the three. Silent-blank is the failure mode, which no red-tile sweep catches — objectui#4616's non-vacuity control found the tooltip case only because the tile drew literally nothing.
Worth deciding, in rough order of leverage:
inputsname exists on the type interface, and that every key a renderer reads is declared? A source-level check is plausible for the meta-vs-type half.Refs #4626, #4616, PR #4630.
Generated by Claude Code