D1127 — A doc-owner map warns when a page is left untouched¶
Decision. scripts/doc-owners.tsv maps path globs to the docs page that
describes them, mirroring the path-mappable rows of docs/index.md
§Documentation maintenance rules. scripts/pr-triage.sh feeds its classified
file rows to scripts/doc-owners.sh, which prints a WARN for every mapped glob
with at least 10 production lines changed (added plus deleted, kind() of the
triage) whose page is not in the change. A line Docs: none - <reason> in the PR
body silences the warnings and is echoed back, so the reviewer reads the reason.
- A WARN, not a BLOCK.
blockedis untouched and--gatekeeps its exit status. The rule becomes a BLOCK only when its measured false-positive rate on a sample of recent first-parent commits is low enough to trust; until then the contract reviewer reads the lines through its mandate and verifies each against the diff. - One page per row, one glob per row. An area several pages describe maps to
the page
docs/index.mdnames first. A glob is a shellcasepattern limited to*and?, where*also crosses/: plain bash 3.2, no new dependency. The tests run one table through that matcher and through their Go translation, so the two cannot disagree. - The logic is a script of its own, a pure filter on stdin, so it is tested
like
scripts/ci-filters.sh;pr-triage.shhas no test of its own. - Fail open. The call in
pr-triage.shprints oneWARNline if the script fails and carries on: a broken map must not fail the requiredplan-gatecheck.internal/repodocskeeps the map valid (well formed, pages exist, every glob matches a file, every page is named in the maintenance table). - A row ships only if it is useful. Over a sample of at least 100 commits, a
row's page may be untouched in at most half of the commits that cross the
threshold; the
internal/gitxpackage as a whole failed that and is mapped torealign.goonly.
Why. The docs drifted from the code because nothing noticed the page that was
not touched; the table in docs/index.md is read by whoever remembers it. The
cheapest signal that reaches author and reviewer is a line in the triage they
already run. The escape line keeps a refactor from being forced to edit a page it
does not change.
Alternatives rejected.
- Blocking now: the false-positive rate is the real risk, and a required check that cries wolf teaches authors to add the escape line by reflex.
- Inline in
pr-triage.sh: it would ship without a test. - A per-glob threshold or several pages per row: more configuration than the signal is worth.
Consequences. plan-gate runs the base branch's pr-triage.sh under
pull_request_target, so the PR that adds this feature does not exercise it; the
script reads the map and the PR body as data and executes nothing from the PR. A
glob that matches nothing disables its row silently, which
TestDocOwnersGlobsMatchAFile pins. A renamed file shows as old => new in
git diff --numstat, which no glob matches, so the pre-PR local run can
under-report a rename.