Docs Autopilot (how docs stay current)
-
Diff-driven
The agent reads
git diffand proposes doc edits as a unified patch. -
Scope-limited
It is only allowed to modify
mkdocs/docs/**andmkdocs.yml. -
Repair rounds
Rejected hunks get a diff repair round, then a whole-page replacement round, before anything is dropped.
-
Auto-deployed
Updated docs are built and deployed (via
mike) to GitHub Pages (gh-pages).
Dev workflow Docs scripts (repo)
This requires an API key
The cloud autopilot will not generate docs unless GitHub Actions has OPENAI_API_KEY configured as a repository secret.
What runs on every push
There are two GitHub Actions workflows:
Docs Autopilot (push):- Builds a plan artifact from
git diff - Calls the LLM to generate a unified diff patch
- Applies + commits doc updates back to the branch
- Regenerates the full config reference from Pydantic + glossary
-
Verifies
mkdocs build --strict -
Publish MkDocs (mike): - Builds the site
- Deploys to
gh-pagesusingmike(version:latest)
Required GitHub configuration
In GitHub:
- Go to Settings → Secrets and variables → Actions
- Add Repository secret:
OPENAI_API_KEY
Optional variables:
OPENAI_MODEL(default:gpt-5)
Local testing
Plan only:
Generate + apply patch (requires OPENAI_API_KEY):
export OPENAI_API_KEY=...
python scripts/docs_ai/generate_docs_from_diff.py --base origin/main --llm openai --apply
uv run python scripts/generate_config_reference_docs.py --clean
mkdocs build --strict
Repair rounds (what happens when a patch doesn't apply)
git apply sometimes rejects a hunk because a page changed after the diff was computed. Before the generator drops a file, it tries two recovery rounds:
- Diff repair round — the model re-emits only the rejected files, against their real current text.
- Page repair round (default on) — for files still rejected, the model returns each page's complete new content between
### FILE: <path>and### END FILEmarkers. Whole-page replacements pass the same safety checks as hunks: only already-rejected files may be written, only paths undermkdocs/docs/, and delete limits still apply (bootstrap runs with--base EMPTYmay rewrite wholesale).
Anything still failing after both rounds is dropped with a ::warning::docs-autopilot: line, and the raw replies (mkdocs-docs-llm-repair-raw.txt, mkdocs-docs-llm-page-repair-raw.txt) are kept so you can see what the model actually said. Set DOCS_AUTOPILOT_PAGE_REPAIR=0 to skip the page repair round.
Bootstrap / catch-up (one time)
If you need a “generate everything” pass (e.g., first setup, or docs are badly behind), run against the git empty tree:
python scripts/docs_ai/generate_docs_from_diff.py --base EMPTY --output mkdocs-docs-plan.md
export OPENAI_API_KEY=...
python scripts/docs_ai/generate_docs_from_diff.py --base EMPTY --llm openai --apply
mkdocs build --strict
In GitHub Actions, run Docs Autopilot (push) manually with base_ref=EMPTY.
Guardrails (why this is safe-ish)
- The model is constrained to a docs-only patch (no code edits)
- The build must pass
mkdocs build --strict - The prompt includes strict accuracy rules (API is under
/api, default ports, no leaking internal plans)