Skip to content

docs: propose a retrievability lint - #104

Open
coderdan wants to merge 2 commits into
mainfrom
docs/retrievability-lint-proposal
Open

docs: propose a retrievability lint#104
coderdan wants to merge 2 commits into
mainfrom
docs/retrievability-lint-proposal

Conversation

@coderdan

Copy link
Copy Markdown
Contributor

Proposal only — no script yet. Worth agreeing the rules before writing the thing that enforces them.

Why

The mechanical failures from this session's 404 work were bugs, and bugs stay fixed. The editorial half regresses one page at a time, and nothing notices.

The reason it goes unnoticed is structural. Retrieval matches a query against a chunk, not a page — a section lifted out of the document that gave it context. A section headed ## How it works, on a page titled Overview, in a folder called Concepts, names its subject exactly nowhere. It reads perfectly well to a reviewer going through the page top to bottom, which is why review does not catch it.

Measured today

content/docs on main, 90 hand-written pages, generated api-reference trees excluded:

Signal Today
Headings (H2–H4) 624
Bare generic headings 26
Question-shaped headings 6
Chunks naming no product entity in their first 600 chars 65
Orphan back-references 0
Descriptions absent or outside 110–158 chars 49

The proposal in one line

scripts/validate-retrievability.ts beside validate-links, validate-content-api, validate-mermaid and validate-v2-redirects, wired into the same prebuild. Rules 1 and 3 as hard failures; rules 2 and 4 as ratcheting baselines in scripts/fixtures/retrievability-baseline.json, failing only on increase.

Ratcheting rather than failing outright because 65 and 49 are too many to fix in one pass, and rule 2 has genuine false positives — a section can legitimately inherit its subject from two paragraphs up.

What it will not do

These rules check that a chunk carries its subject, not that it answers anything. A page can pass all four and still be unretrievable. The real test is a retrieval eval — fixed question set, run against the live docs, check what comes back — which is worth building once the mechanical rules stop finding things, not before.

Open questions for review

  • Is 110–158 still the right description range, and should section index stubs be exempt or just rewritten?
  • Rule 2's 600-character window and entity list are both guesses. Worth a look.
  • Should the nav-boilerplate allowlist (Related, Next steps, Before you start, In this section) be exactly that set?

Related: CIP-3339 (AI-agent readiness — this is its enforcement arm) and CIP-3337 (docs correctness CI — same gate, different axis: that one asks whether the docs are true, this one whether they can be found).

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
public-docs Ready Ready Preview Sep 1, 2026 2:40am UTC

Request Review

An SEO consultant's read of these docs: "Excellent docs: built to be read by
a developer, not retrieved by a model."

The mechanical half of that has been worked through — absolute urls in
llms.txt, source urls in llms-full.txt, 77 redirects off the pre-V2 tree, the
.md rewrite, working links in the markdown views. Those were bugs, and bugs
stay fixed.

The editorial half does not stay fixed. It regresses one page at a time and
nothing notices, because the defect is invisible to a human reviewer by
construction: a section headed "How it works" reads fine to someone going
through the page top to bottom, and names its subject nowhere once a retriever
lifts it out.

Defines the four rules concretely enough to check — a heading names its
subject, a chunk names an entity, no orphan back-references, frontmatter
descriptions present and in range — with today's counts measured against
content/docs (624 headings, 26 bare generic, 6 question-shaped, 65 entity-free
chunks, 0 back-references, 49 off-spec descriptions).

Proposes scripts/validate-retrievability.ts beside the existing validate-*
gates in prebuild: rules 1 and 3 as hard failures, 2 and 4 as ratcheting
baselines, since 65 and 49 are too many to fail on today and rule 2 has real
false positives.

States the limit plainly: these are proxies for shape, not for whether a chunk
answers anything. The real test is a retrieval eval, which is worth building
once the mechanical rules stop finding things.

No script yet — this is the proposal to agree on before writing one.
Review question: we have broken-link checks in CI, so why did the
root-relative links in the markdown views go unnoticed?

Because they are not broken. validate-links.ts resolves against the
collections as the app serves them — content/docs at baseUrl "" — so
/reference/auth/clients is a correct link to a real page. It also rejects the
absolute form outright, since Next's basePath prepends /docs and a /docs
prefix would resolve to /docs/docs/…. Both judgements are right for the HTML
rendering, which is the only one it models.

The markdown view is a second rendering with no basePath and no browser, where
the same link resolves against the origin and 404s. A source-level check
cannot see that, and should not be bent into trying.

Adds rule 5: render what /docs/<path>.mdx returns and assert no root-relative
link survives it. Hard failure — an invariant of the route rather than a matter
of degree — and it generalises: anything that reshapes content on the way out
needs its output asserted, not its input.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant