diff --git a/Makefile b/Makefile index 56141f6..83cd9d9 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,9 @@ frontend: ## lint: verify formatting (no changes) lint: dotnet format $(SLN) --verify-no-changes + # Only pages in mkdocs.yml's nav are published, and mkdocs keeps a build green + # when one is missing โ€” so the nav is checked here rather than not at all. + python3 infra/check-docs-nav.py ## build: release build build: diff --git a/infra/check-docs-nav.py b/infra/check-docs-nav.py new file mode 100755 index 0000000..ef51803 --- /dev/null +++ b/infra/check-docs-nav.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 +"""Fail when a page under docs/ is missing from mkdocs.yml's nav. + +docs/ is the source of truth (CLAUDE.md ยง12), but only the pages listed in the nav +are published โ€” and mkdocs' own `omitted_files: warn` keeps a build green while +silently dropping them, which is how every ADR after 0010 and every runbook but +ci.md fell off the site. + +ponytail: a substring test, not a YAML parse โ€” a page's path either appears in +mkdocs.yml or it doesn't, and that needs no dependency. +""" + +import sys +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] +nav = (ROOT / "mkdocs.yml").read_text() + +missing = sorted( + str(page.relative_to(ROOT / "docs")) + for page in (ROOT / "docs").rglob("*.md") + if str(page.relative_to(ROOT / "docs")) not in nav +) + +if missing: + print(f"{len(missing)} page(s) under docs/ are not in mkdocs.yml's nav:") + print("\n".join(f" {m}" for m in missing)) + sys.exit(1) + +print("docs nav complete: every page under docs/ is published")