Skip to content

Hold every section landing list to its meta.json — 4 hand-kept lists, and #9604's precedent already says "check them, don't generate them" #10738

Description

@claude

Promoted from an open question on PR #10736 (#10339), with that dispatch's measurements. No gate is red. Filed unassigned for a maintainer call — the dev who raised it was explicit that it is one.

The recurring defect

A section landing page's ## What's in this module bullet list is hand-kept next to a meta.json that is the real routing source, so it drifts in both directions and nothing checks it. Three known instances:

section instance
runtime-services #9604 — chapter list omitted services.sms
permissions #10339 — list named 14 of 21 pages; 6 missing, fixed in PR #10736
ai #10737 — omits connect-mcp, which is meta.json's first content page and is linked nowhere else on that page

The precedent already chose

#9604 did not derive its list. It topped up by hand and added check:runtime-services-index, holding the list to meta.json. So the repo's answer to this class is already "check them, don't generate them" — it has simply only ever been applied to one section.

Why deriving is the wrong shape, measured on permissions

Ruled out on evidence rather than taste, from the #10339 dispatch and re-verified here:

  • content/docs/permissions/meta.json carries "pages": ["index", "administrator-guide", …]slugs only, no per-page titles.
  • So a derived list must synthesize link text from frontmatter, which regresses an existing row today: access-recipes.mdx is titled "Who can see data / automation / interface" and would render as that instead of the curated "Access Recipes".
  • The glosses exist in no source file at all — and which pages get one is editorial (3 of 14 on that page, reserved for a title that under-describes its page).

A landing page is an editorial object, not nav config. Generating it loses exactly the parts a reader benefits from.

Population, measured rather than pattern-matched

Exactly three pages carry a hand-written ## What's in this module bullet index: permissions, api, ai.

Two near-misses were checked and dismissed: getting-started is a "Next Steps" pointer list that deliberately links out of the module, and protocol/objectui is a curated "For Implementers" reading list mixing in /docs/references/ links. Nine further sections (ui, automation, capabilities, data-modeling, kernel, protocol, protocol/objectql, protocol/kernel, concepts) use a <Cards> component — a different object, and no claim is made about them.

Shape, if taken

Hold the list's SET and ORDER to its directory's meta.json, both directions, for the three pages above.

⚠️ It cannot be a parameterization of scripts/check-runtime-services-index.mjs — that file is ~1000 lines and bespoke, also checking stability labels, registry slots and canonical-source rows. It wants a new small gate.

The one stated objection is no longer a blocker. The #10339 report notes such a gate needs "a root package.json check: entry, which is inside the #9465 epic fence". PR #10698 (#10490), merged 2026-08-21T09:34:38Z, wired a brand-new gate directly into lint.yml as a node scripts/… step with no package.json alias, specifically to stay outside that fence. So the fence does not stand in the way.

The honest argument against

Three pages may not be worth a gate. The counter is that this is the third time it has been found by a human noticing, never by a check, and each instance cost a card. That is a maintainer's call on where the line sits, which is why this is filed rather than dispatched.

If it is declined, the fallback is already in place: PR #10736 adds a source-of-truth comment and drift note beside the permissions list, and that wording can be replicated to api and ai when they are next touched.

Refs

#9604 (the precedent, and its gate) · #10339 / PR #10736 (permissions, where this was measured) · #10737 (the ai instance) · #10698 / #10490 (the fence-free wiring pattern)


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions