Skip to content

[finding] Nothing enforces the form-section name convention in content/docs/** examples — os:check passes because name is .optional() #10830

Description

@claude

Found while implementing #10709 (PR #10827). Filing separately — adding a gate is a
different defect class from adding a name attribute, and it would widen that PR's
verification surface.

The observation

Form-section examples in content/docs/** can drift from the name convention
indefinitely without any gate reddening. Two mechanisms look like they would catch it,
and neither can:

  1. packages/lint's translation-section-name-missing
    (packages/lint/src/validate-translatable-sections.ts:95) walks app metadata
    collectionEntries, walkPageComponents, viewContainerSites. It never sees an
    .mdx code fence. Its severity is 'warning' in any case.
  2. {/* os:check */} fencesare type-checked against the live spec by
    packages/spec/scripts/check-skill-examples.ts. But name is .optional() in
    packages/spec/src/ui/component.zod.ts:825, so a nameless section type-checks
    clean
    . content/docs/ui/forms.mdx's first block carries an os:check marker and
    still shipped a nameless section.

So the docs surface that teaches the convention is the one surface where the convention
is unenforced.

Why it looks like a recurring class rather than a one-off

The same defect has now been counted three times, by hand, each time with a different
number:

passclaimedactual
#10579"three of five ... over four ui/ pages"undercount; missed forms.mdx entirely
#10709"7 of 15 across 5 pages"undercount by one
PR #108278 of 16 across 5 pages (pre-sweep, measured at b6bb2ee454^)

Each pass corrected its predecessor's instrument and introduced a subtler version of the
same error: #10579's scan was single-line, #10709's was multi-line but still required {
to begin a fresh line, so it missed forms.mdx's sections: [{ inline form. A mechanical
check would settle the count once instead of re-deriving it per card.

Possible shapes (not a recommendation — this needs triage)

  • Extend an existing docs gate to require name on sections[] object literals in
    content/docs/** TS fences. Bracket-matching, not line-matching — the parser used for
    PR docs(ui): name the 5 remaining nameless form sections in content/docs/ui #10827's census is ~80 lines and is in that PR's description.
  • Or narrower: have check:skill-examples apply a docs-only strictness overlay for keys
    that are .optional() in the schema but conventional in authored examples.

Both are speculative on the cost side; the underlying observation (nothing enforces it)
is the part that is measured.

⚠️ Not proposing that name become required in the schema — it is .optional()
deliberately (a nameless section is legal and renders its authored label), and #10709's
own body treats that as settled. This is about the docs examples, not the contract.

Back-links: #10709, #10827, #10579, #10616

Generated by Claude Code


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions