Module check_guide_links
Expand description
cargo dev check-guide-links — G15: every guide citation names a live page.
§Why this is a separate command
M7.D7 de-internalised the public rustdoc: it replaced docs/design/…
citations with links to the guide. With no site deployed it had to use the
repository form — a github.com/…/blob/main/docs/<page>.md URL — which resolves
but points at the source file rather than at the published page, and pins a
moving main rather than a version (§1.3.80). M7.D9 swept all 131 of them —
127 in the six documented crates, 4 republished onto generated pages — to
crate::markdown::SITE_PAGE_PREFIX, and this command is what keeps them swept.
It earns its place on the second check. Nothing in the tree notices today when a
doc comment cites a guide page that has been renamed or deleted: rustdoc does
not resolve URLs, mkdocs build --strict never sees a doc comment, and G14
checks the API map rather than prose. A citation of concepts/storage/ after
that page is renamed is a link that looks right in every review and 404s for
every reader.
§The four checks
-
No repository form survives. No file outside
docs/design/spells any ofREPOSITORY_DOCS_PREFIXES— both of GitHub’s, the file form and the directory form. The sweep stays swept: a doc comment written next year cannot quietly reintroduce a repository link, which is how the first 131 accumulated. -
Every site-absolute citation names
latest, and a page that exists. A…/latest/<section>/<page>/URL is parsed back todocs/<section>/<page>.mdand the file is required. This is the check nothing else in the tree can make.The scan keys on the site root, so it finds a citation naming any version segment and then requires the segment to be
markdown::SITE_VERSION. Keying on the whole…/latest/literal — which is what it did until §1.3.141 was closed — meant it could only ever see the citations that were already right:…/atune/dev/concepts/nonexistent/was not a citation to it at all, and passed every check while naming nothing. The exceptions areVERSION_EXEMPTand are printed on every green run. -
No generated page under
docs/carries a site-absolute URL. Rule (4)’s invariant, checked over the files on disk rather than trusted:crate::markdown::site_links_page_relativeis what makes such a URL page-relative, so one surviving means the rewrite did not fire — the page was hand-edited, the citation arrived in a spelling the rewrite refuses (an autolink or bare prose, neither of which has a page-relative form), or the rewrite no longer runs at all. The list of generated pages comes fromgenerate_all::generators, never from a constant here, so a tenth generator is covered by existing. -
No doc comment of a registry crate cites the internal corpus. M7.D7 swept 341 such lines out of the five crates that reach crates.io or
PyPIand nothing stood guard over the result, so the invariant held only until somebody edited a doc comment. SeeREGISTRY_CRATES— including for the half that is counted rather than gated, and why.
§What this command covers, and what it does not
It reads every UTF-8 file in the repository except the directories in
SKIPPED, symbolic links included and each target walked once, so a citation
in a doc comment, a README, a page, a workflow, a
manifest comment or a runtime message string is all equally in scope. That
breadth is the point: the 131 occurrences the sweep found lived in .rs, .md
and .pyi files, and two of them were format! strings a reader sees at run
time rather than doc comments at all.
docs/design/** is exempt from all four checks, deliberately. It is the
internal design corpus (D25), mkdocs.yml’s exclude_docs keeps it off the site,
and it has to be able to quote what the rest of the tree may not write: §1.3.80
records the repository form, and §2’s D38 quotes a …/api/rust/… URL to show
both branches of the link resolver. An exemption that cannot be stated is a hole;
this one is stated here, in EXEMPT, and on every green run’s own output. It
is matched as a path rather than as a string prefix, so it exempts that directory
and nothing that merely begins with its name (is_exempt).
A site URL under one of NOT_A_PAGE is skipped by check 2, and that is a
genuine gap rather than a tidy exclusion — see the constant.
Three things it cannot see, each already owned elsewhere:
- whether a page-relative link resolves.
mkdocs build --strictwithvalidation.links.not_foundandvalidation.links.anchorsdoes that, on every build, which is the whole reason rules (3) and (4) emit relative links at all (D38 sub-decision 3). - whether a generated page equals what its generator would write.
generate-all --mode check(G7) does that. This command reads the file on disk, so the two are a pair in the same sense G7 and G14 are: a hand-edited page that reintroduced an absolute URL fails here, and a generator that would emit one fails there. - whether a
docs.rsURL is right.atune_derivecannot use an intra-doc link —atunedepends on it, so the reverse dependency does not exist — so its three citations are hand-spelleddocs.rsURLs and must stay absolute. Nothing here or anywhere else resolves them; the anchor they name was verified against a realcargo doctree by hand at M7.D9b.
Constants§
- CHECKER 🔒
- This command’s name, for fail-closed error messages.
- DOCS_
DIR 🔒 - Where a guide page lives, for turning a site URL back into a file.
- EXEMPT 🔒
- The one directory exempt from every check, relative to the repository root.
- INTERNAL_
CORPUS 🔒 - The internal corpus, as a doc comment would spell it.
- NOT_
A_ 🔒PAGE - Site paths that are not published from a
docs/**.mdpage, so check 2 has no file to look for. - REGISTRY_
CRATES 🔒 - The crates whose doc comments may not cite the internal corpus, and the crates whose doc comments still do.
- REPOSITORY_
DOCS_ 🔒PREFIXES - The repository forms M7.D7 used and M7.D9b swept away.
- SKIPPED 🔒
- Directory names never descended into.
- VERSION_
EXEMPT 🔒 - Files allowed to name a version segment other than
latest, with the reason.
Functions§
- check_
generated_ 🔒pages - Check 3: no generated page under
docs/publishes a site-absolute URL. - check_
internal_ 🔒corpus - Check 4: no doc comment of a registry crate cites the internal corpus.
- check_
page_ 🔒exists - Check 2: the page a site-absolute citation names exists.
- check_
repository_ 🔒form - Check 1: no repository form appears anywhere.
- cites_
corpus 🔒 - Does this line cite the internal corpus from a rendered doc comment?
- collect_
files 🔒 - Every file under
directory, skippingSKIPPEDdirectory names. - crate_
of 🔒 - The crate a
crates/<name>/src/…path belongs to. - is_
exempt 🔒 - Is this repository-relative path inside the exempt directory?
- page_
source 🔒 - The
docs/source file a site URL’s path came from. - relative_
to_ 🔒root - A path as the repository-relative,
/-separated string a message should name. - report_
internal_ 🔒corpus - Prints what the published
/api/rust/tree still carries, and from where. - run
- Runs the four checks, reporting every failure rather than the first.
- site_
citations 🔒 - Every site-absolute citation on one line, as
(version segment, page path). - unclassifiable 🔒
- Wraps a message as this command’s fail-closed error.
- wrong_
version 🔒 - A citation naming a version segment this tree may not write.