Appendix A - 22. Doc-hygiene lints (index coverage, autogen provenance)
The Structure of Doc-hygiene lints (index coverage, autogen provenance) — its shape at a glance:
A family of lints reads the doc corpus and its emitter registry, checking three mechanical invariants: every doc indexed, every emitted file provenance-headed, every cross-reference resolving.
flowchart LR
Docs[(Doc corpus)] --> Lints{{Doc-hygiene lints}}
Reg[(Autogen-target registry)] --> Lints
Lints -->|indexed · headed · links resolve| Pass([Build proceeds])
Lints -->|missing entry / header / dead link| Fail([Build blocked])
Accessible description: doc-hygiene lints read the doc corpus and the autogen-target registry, checking that every doc is indexed, every emitted file carries its provenance header, and every cross-reference resolves; the build proceeds when all hold and is blocked on any missing entry, header, or dead link.
Projected from the catalogue entry governance-doc-controls / Doc-hygiene lints (index coverage, autogen provenance).
On this page: Intent · Motivation · Applicability · Structure · Sample Code · Consequences · Example use within DocAble · Related Patterns
Intent
Intent — A family of lints that hold documentation to mechanical checks (index coverage, auto-generated-file provenance headers, cross-reference validity), so docs cannot silently drift, go stale, or be hand-edited where they will be overwritten.
Motivation
Docs drift silently in ways a diff doesn't reveal: an auto-generated file gets hand-edited and is then overwritten (the edit lost), a new doc never gets added to the index (unfindable), a cross-reference points at a moved or renamed file (dead). The failure is stale or misleading docs that agents then trust as ground truth, and it recurs continuously as the doc corpus grows.
Applicability
- A doc index to check coverage against.
- An autogen-target registry (
_AUTOGEN_TARGETS) and a provenance-header convention emitters honor. - Resolvable-reference checking for the cross-ref lint.
- An exemption escape (
noqa/ an EXEMPT field) for the legitimate special cases, or the lint false-positives on them.
Structure
The Structure diagram appears at the top of this page.
Sample Code
Each lint is a mechanical presence check the reviewer's eye slides past. The provenance check verifies an emitted file declares its emitter in the first lines — so a hand-edit, which will be overwritten, is caught — and the coverage check verifies every doc appears in the index.
import re, sys
def lint_provenance(path: str, head_lines: list[str], is_autogen) -> list[str]:
if not is_autogen(path):
return []
for line in head_lines[:5]: # provenance must appear in the first non-blank lines
if re.search(r"GENERATED by .+ — regen via ", line):
return []
return [f"{path}: auto-generated file lacks a provenance header — hand-edits will be overwritten"]
def lint_index_coverage(all_docs: set[str], indexed: set[str]) -> list[str]:
return [f"{d}: not listed in the doc index (unfindable)" for d in sorted(all_docs - indexed)]
if __name__ == "__main__":
findings = [] # accumulate across all docs; wire is_autogen to your emitter registry
print("\n".join(findings))
sys.exit(1 if findings else 0)
Consequences
- Mechanical only. These lints verify a doc is indexed and fresh, never that its prose is correct: a well-formed, well-indexed, wrong document passes.
- Registry maintenance. The autogen-target registry and the provenance convention are surfaces that need upkeep as emitters are added.
- False positives on legitimate exceptions require an escape hatch, which is itself a small hole.
- AUDIT → BLOCKING migration risk. Flipping to blocking before the corpus is clean wedges the pipeline on pre-existing drift.
Example use within DocAble
- The index-coverage lint (every doc indexed).
- The autogen-provenance lint + its autogen-targets registry.
- Cross-reference / link-resolution lints.
Related Patterns
- See also (family) — claude-md-rule-index: the flagship "documentation with a hard-counterpart lint" this mechanism generalizes to the whole corpus.
- See also (sibling) — meta-model-consumption: the same "read the substrate at lint-time" move, applied to queryable models rather than prose docs.
- See also (sibling) — mandatory-snippet-table: documentation (snippets) enforced by a lint, on the dispatch side.