The docs sweep¶
Documentation here is written per branch, by whoever builds the feature, and a large batch of merges leaves pages that were each right on their own branch and wrong together: a guide still describing the old default, a "not yet released" for something that was released that afternoon, a README that counts what the code no longer has. A sweep is the audit that finds those, run once before every release, and the one pull request that fixes them. The first one was run on 2026-10-02 after the batch behind v0.19.0; this page is the checklist it used, so the next one does not start from nothing.
A sweep is an audit and one fixing PR, not a rewrite. It fills gaps with
prose grounded in the code and the pull request bodies, fixes contradictions
in favour of the code and docs/DECISIONS.md, and leaves everything else
alone. It never invents a measurement.
The wiki mirror¶
The GitHub wiki is generated from docs/, never written. On every push to
main, .github/workflows/wiki.yml (a GYST wiki-publish.yml caller) runs scripts/gen_wiki.py and replaces
every wiki page with its output, so an edit made in the wiki is lost at the
next push. Corrections go to docs/ by pull request, like any other. The
canonical site stays https://renegade-penguin.github.io/Hammunition/.
To see what the wiki will contain:
.venv/bin/python scripts/gen_wiki.py --out /tmp/wiki-out
.venv/bin/python scripts/gen_wiki.py --check
--check writes nothing; it fails on a name collision or a link that points at
nothing. A new page needs no wiki step: it is in the nav, so it is in the wiki.
The workflow needs the wiki's first page created once in the GitHub UI, because
the wiki's git remote does not exist before that; until then it fails naming
that step.
Set up¶
git fetch -q origin
git worktree add ../Hammunition-docs-sweep -b docs-sweep origin/main
cd ../Hammunition-docs-sweep && python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
Run the engine only with --help and --dry-run, with HOME pointed at a
scratch directory so no real log or station file is touched, and never with
sudo. Nothing is installed or applied on the machine doing the sweep.
Gather what landed¶
git log --merges <last-tag>..origin/main --oneline
git log origin/main --oneline -15
gh pr view N --json title,state,body -q .body # each merged PR since the tag
Read the decisions the batch touched in docs/DECISIONS.md, and every
amendment dated since the last sweep (grep -n "Amendment" docs/DECISIONS.md).
Note which pull requests are still open: their features are not on main
and the docs must not describe them as done. Pull request bodies are the
record of what was measured; the section called "What the bench owes" or "Not
measured" in each is a list of claims the docs must not make.
The six checks¶
For each merged piece, with the file and line of what you find:
- Is there a guide that takes an operator through it end to end? One
page or section, reachable from the nav, that says what to install, what to
run, what the prompts are and what the result looks like. A feature with
only a reference entry in
docs/reference/cli.mdfails this check. - Do the pages agree with each other and with the code? Getting started, the profile pages, the hardware pages, troubleshooting and the CLI reference must give the same answer to "what is the default" and "which command". Check every flag cited against the code (below), and every default against the manifest or the schema.
- Does each page end with what was measured and what was not, per the
guides' convention, and is anything claimed as working that the pull
request body lists as owed to the bench? Check the other direction too: a
page still saying "not yet run" for something a bench session now records
(
docs/reference/bench-verification-5430.md) is as wrong as the reverse. - Is the nav complete and ordered for a newcomer? Every page is in
mkdocs.ymlor is a package page (tests/test_site.pyenforces that), but in-nav is not the same as findable: a guide missing fromdocs/guides/index.md, a page filed under Reference that a newcomer needs on day one, a hardware group that mixes unrelated things. - Do the counts and the status block match? README's status table and
counts, CLAUDE.md's repo layout and decisions table against
docs/DECISIONS.md(the decision record wins),ls catalog/packages | wc -land the like, and the number of bench sessions. - Do the sibling repositories' READMEs still say true things? hammunition-tray, hammunition-gps-tether and hammunition-bunker are read, not edited, in this pull request; what is stale goes into the PR body as a follow-up for each.
Checking flags against the code¶
Every flag a page cites must exist. This reads every heading of
docs/reference/cli.md that names flags and confirms the program's own
--help lists them, and the other way round:
.venv/bin/python - <<'EOF'
import re, subprocess
H = ".venv/bin/hammunition"
txt = open("docs/reference/cli.md").read()
heads = list(re.finditer(r"^### `(hammunition [^`]*)`", txt, re.M))
for i, m in enumerate(heads):
end = heads[i + 1].start() if i + 1 < len(heads) else len(txt)
sec = txt[m.start():end]
words = []
for w in m.group(1).split()[1:]:
if not re.match(r"^[a-z][a-z0-9-]*$", w):
break
words.append(w)
for k in range(len(words), 0, -1):
r = subprocess.run([H, *words[:k], "--help"], capture_output=True, text=True)
if r.returncode == 0:
break
documented = set(re.findall(r"--[a-z][a-z0-9-]+", m.group(1)))
real = set(re.findall(r"--[a-z][a-z0-9-]+", r.stdout)) - {"--help", "--json"}
print(" ".join(words[:k]), "| cited but not real:", sorted(documented - real - {"--help", "--json"}),
"| real but absent from its section:", sorted(f for f in real if f not in sec))
EOF
A flag cited in a guide rather than the reference is checked by hand with
hammunition <verb> --help. The check above skips a heading that covers two
verbs (station show and station set), so run station set --help yourself.
What to fix, and what to leave¶
Fix, in the one branch: a gap with accurate prose and a cross-link; a
contradiction in favour of the code and DECISIONS.md; a nav entry; a count.
Mark anything unmeasured as unmeasured, in the words the pull request used.
Leave alone: generated pages (docs/packages/, docs/profiles/,
docs/reference/ pages with a "Generated by" line), which are regenerated
from their input, never edited. When a generated page is wrong, the input is
a manifest, a profile's documentation: block or a generator script; fix that
and regenerate with the generator named in the page's first line, then run it
with --check. A generator's --check writing nothing is itself tested
(tests/test_docs_generated.py).
Never write the maintainer's callsign, grid square, regions, host name or a
serial number into a page, a commit or a pull request: placeholders only
(N0CALL, N0TST, FN31pr).
Gates¶
make check > /tmp/sweep-make.log 2>&1; echo "make check rc=$?"
nice -n 19 unshare -r .venv/bin/python -m pytest tests -q -p no:cacheprovider \
> /tmp/sweep-pytest.log 2>&1; echo "pytest rc=$?"
make check builds the site with --strict and checks links, including
backticked repository paths. Capture to a log and test the exit status; never
pipe a gate into grep. Each commit goes through
scripts/check_commit_claims.py --rev HEAD.
Then one reviewer (a Sonnet agent), asked to spot-check ten of the new claims by running the commands they cite rather than reading them. Fix what it finds that is Critical or Important.
The pull request¶
Title: "Docs sweep after the