Skip to content

No gate judges prose that restates a declared surface — three docs pages measured wrong about PageHeaderProps in one day #6086

Description

@yinlianghui

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:

pagedefectcard
content/docs/guide/layout.md:288named the ADR-0087 D2 tombstoned key icon as declared, and omitted five live keys#5923 (fixed)
content/docs/layout/page-header.mdx:66-68omits 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:

  1. 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.
  2. 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

Metadata

Metadata

Labels

domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopm:dispatchedtooling

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions