"""Recorded documentation checks built from existing owning-module contracts.""" from __future__ import annotations from pathlib import Path import uuid from .catalog import stage from .common import state_root from .workspace import load_project, selected_repositories LIMITATIONS = [ "Static baseline, marker coverage and known display slots do not prove complete workflow or linguistic coverage.", "Computed labels, configured documentation providers and runtime module/permission combinations still require manual review.", "Audit findings do not edit documentation, translate text, publish evidence or close a review issue.", ] def build_doc_stages(args) -> list[dict]: workspace = Path(args.workspace_root).resolve() project = load_project(workspace, getattr(args, "project", None)) if getattr(args, "project", None): raise ValueError( "The docs audit currently targets GovOPlaN manifest/locale contracts. Register another project's documentation checks in its check profiles." ) selected = selected_repositories( project, getattr(args, "repo", []), changed=getattr(args, "changed", False) ) if getattr(args, "changed", False) and not selected: return [] meta = next(repo.path for repo in project.repositories if repo.name == "govoplan") core = next( repo.path for repo in project.repositories if repo.name == "govoplan-core" ) output = ( state_root(workspace, getattr(args, "state_dir", None)) / "artifacts" / f"docs-{uuid.uuid4().hex}" ) reason = "Reuse the existing owning-module documentation and translation checks" labels = [ "{node}", str(meta / "tools/devkit/audit-display-labels.mjs"), "--workspace-root", str(workspace), ] for repo in selected: labels.extend(["--repo", repo.name]) stages = [ stage( "docs.manifests", "Static user/admin documentation and manifest contracts", [ "{python}", str(meta / "tools/checks/check-manifest-shapes.py"), "--workspace-root", str(workspace), "--require-architecture", ], meta, reason=reason, timeout_seconds=600, ), stage( "docs.interface-inventory", "Existing EN/DE markers, high-risk help and interface declarations", [ "{python}", str(meta / "tools/inventory/platform-interface-inventory.py"), "--workspace-root", str(workspace), "--strict", "--strict-declarations", "--strict-endpoints", "--output-dir", str(output), ], meta, reason="Shared inventory remains workspace-wide; --repo narrows only the additional plain-label audit", timeout_seconds=600, ), stage( "docs.translation-structure", "Existing translation key/structural-value guard", ["{node}", str(core / "webui/scripts/audit-i18n-structural.mjs")], core / "webui", reason=reason, ), stage( "docs.plain-display-labels", "Plain display labels and owning catalog registration", labels, meta, reason="Supplement the marker inventory with known display slots; dynamic cases are review candidates", timeout_seconds=600, ), ] # These constraints belong to the saved evidence, not only the immediate # CLI response. The publisher already validates bounded coverage_notes. stages[0]["coverage_notes"] = list(LIMITATIONS) return stages def audit(args) -> dict: from .runner import run_checks result = run_checks(args, build_doc_stages(args)) result["limitations"] = list(LIMITATIONS) result.setdefault("_exit_code", 0) summary = result.setdefault("summary", []) summary.extend(note for note in LIMITATIONS if note not in summary) return result def register(subparsers) -> None: docs = subparsers.add_parser( "docs", help="Audit existing documentation and translation contracts" ) commands = docs.add_subparsers(dest="docs_command", required=True) command = commands.add_parser( "audit", help="Run recorded checks; never edit or generate translations" ) command.add_argument( "--repo", action="append", default=[], help="Repository/alias for plain-label checks; shared checks stay workspace-wide", ) command.add_argument("--changed", action="store_true") command.add_argument("--jobs", type=int, default=2) command.add_argument("--dry-run", action="store_true") command.set_defaults(handler=audit, profile="docs")