Filed unassigned by the PM seat (session_01CSoz9uGhaaSgiq3hshtN7L), out of #5923's granted file surface. Recording the class, not the instances — both instances already have cards.
The fact
PageHeaderProps is restated in prose on at least two docs pages, and on 2026-08-24 both copies were measurably wrong at the same time:
| page | defect | card |
|---|
content/docs/guide/layout.md:288 | named the ADR-0087 D2 tombstoned key icon as declared, and omitted five live keys | #5923 (fixed) |
content/docs/layout/page-header.mdx:66-68 | omits two live keys, maxVisible and mobileMaxVisible | #6083 (filed) |
That second one is the load-bearing observation. #5923's fix was written on the assumption that the reference page was the correct copy to defer to — ⛔ it was not. "Consolidate onto one copy" would have consolidated onto a copy that was itself two keys behind. There was no correct copy anywhere in the tree.
Why nothing caught either
Neither claim lives in a code fence, and every doc gate this repo has is fence-shaped:
So a sentence of the form "X declares a / b / c" has no mechanical judge at all in this repository, however precisely it names a shape the tree actually declares. A green run on a file whose prose is wrong is not a false green in the usual sense — the gates are answering a different question correctly. The gap is that nobody is asking this one.
⚠️ Note one premise from #5923's card has since gone stale and should not be carried: content/docs/guide/layout.md is no longer in check-doc-snippet-types' UNGATED_DOCS list (44 entries at runtime; this file is among the covered 178). It is fence-blind regardless — being inside the scan surface bought nothing here, which is itself the point.
Why it is worth a card rather than vigilance
The two pages drifted independently, in different directions, from the same source of truth — one by carrying a retirement that had happened, the other by missing additions. That is not a lapse someone can be more careful about next time; it is what happens when N prose copies track a moving declaration with no ratchet. The same shape recurs anywhere prose restates a declared surface, and this repo does that a lot.
Shape of a fix — sketch, not a design
Something that extracts Name — declares a / b / c-shaped claims from prose and checks the key list against the named shape's declared keys. ⚠️ Two traps a naive implementation walks straight into, both measured on #5923:
- ⛔ Declared keys ≠
safeParse output keys. The output-key reading gives 6 for PageHeaderProps; walking the zod shape gives 11 (10 live + the icon tombstone). An optional key with no default never appears in a parse result, so a gate built on safeParse would have demanded the deletion of actions and aria — it would have enforced the very defect it exists to catch. - ⛔ A retired key must be distinguishable from an absent one.
icon is a retiredKey tombstone carrying its own ADR-0087 D2 message; the correct prose neither lists it as declared nor pretends it never existed.
Cost is real (a prose parser is not free) and the trade against "just don't duplicate the lists" is a judgement for triage — recording it so the choice is made deliberately rather than by nobody.
Reproduce
rg -n 'declares' content/docs/guide/layout.md content/docs/layout/page-header.mdx
node scripts/check-doc-snippet-types.mjs # green on the false prose
node scripts/check-doc-component-types.mjs # green on the false prose
Filed unassigned by the PM seat (
session_01CSoz9uGhaaSgiq3hshtN7L), out of #5923's granted file surface. Recording the class, not the instances — both instances already have cards.The fact
PageHeaderPropsis restated in prose on at least two docs pages, and on 2026-08-24 both copies were measurably wrong at the same time:content/docs/guide/layout.md:288iconas declared, and omitted five live keyscontent/docs/layout/page-header.mdx:66-68maxVisibleandmobileMaxVisibleThat second one is the load-bearing observation. #5923's fix was written on the assumption that the reference page was the correct copy to defer to — ⛔ it was not. "Consolidate onto one copy" would have consolidated onto a copy that was itself two keys behind. There was no correct copy anywhere in the tree.
Why nothing caught either
Neither claim lives in a code fence, and every doc gate this repo has is fence-shaped:
check-doc-component-typesjudges type literals in code blocks;check-doc-snippet-typescompilests/tsxblocks (157 blocks judged on the docs(guide): layout guide's PageHeaderProps list names a retired key and omits three live ones; its registration-inputs claim is two entries behind #5923 branch, all green, while the prose two lines above a fence was false).So a sentence of the form "
Xdeclaresa / b / c" has no mechanical judge at all in this repository, however precisely it names a shape the tree actually declares. A green run on a file whose prose is wrong is not a false green in the usual sense — the gates are answering a different question correctly. The gap is that nobody is asking this one.content/docs/guide/layout.mdis no longer incheck-doc-snippet-types'UNGATED_DOCSlist (44 entries at runtime; this file is among the covered 178). It is fence-blind regardless — being inside the scan surface bought nothing here, which is itself the point.Why it is worth a card rather than vigilance
The two pages drifted independently, in different directions, from the same source of truth — one by carrying a retirement that had happened, the other by missing additions. That is not a lapse someone can be more careful about next time; it is what happens when N prose copies track a moving declaration with no ratchet. The same shape recurs anywhere prose restates a declared surface, and this repo does that a lot.
Shape of a fix — sketch, not a design
Something that extracts⚠️ Two traps a naive implementation walks straight into, both measured on #5923:
Name — declares a / b / c-shaped claims from prose and checks the key list against the named shape's declared keys.safeParseoutput keys. The output-key reading gives 6 forPageHeaderProps; walking the zod shape gives 11 (10 live + theicontombstone). An optional key with no default never appears in a parse result, so a gate built onsafeParsewould have demanded the deletion ofactionsandaria— it would have enforced the very defect it exists to catch.iconis aretiredKeytombstone carrying its own ADR-0087 D2 message; the correct prose neither lists it as declared nor pretends it never existed.Cost is real (a prose parser is not free) and the trade against "just don't duplicate the lists" is a judgement for triage — recording it so the choice is made deliberately rather than by nobody.
Reproduce