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.
134 lines
4.8 KiB
Python
Executable File
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")
|