Files
govoplan/tools/devkit/govoplan_devkit/docs.py
T
zemion 2ffdb23f69
Dependency Audit / dependency-audit (push) Successful in 1m45s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Successful in 11m30s
feat(devkit): add resumable workspace automation and UI review tooling
Verified with the coordinated workspace changes by devkit full run
2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed).
This shared UI pass does not mark the individual module reviews complete.
2026-09-09 02:03:17 +02:00

134 lines
4.8 KiB
Python
Executable File

"""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")