feat(devkit): add resumable workspace automation and UI review tooling
Dependency Audit / dependency-audit (push) Successful in 1m45s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Successful in 11m30s

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.
This commit is contained in:
2026-09-09 02:03:17 +02:00
parent 14b19fbead
commit 2ffdb23f69
67 changed files with 17306 additions and 94 deletions
@@ -9,6 +9,7 @@ from collections import Counter
from dataclasses import asdict, is_dataclass
import importlib
import json
import os
from pathlib import Path
import re
import subprocess
@@ -40,6 +41,11 @@ REFERENCE_LOCALE = "de"
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--workspace-root",
type=Path,
help="Authoritative directory containing registered checkouts; never falls back to another workspace.",
)
parser.add_argument(
"--output-dir",
type=Path,
@@ -87,8 +93,9 @@ def main() -> int:
args = parser.parse_args()
catalog = json.loads((META_ROOT / "repositories.json").read_text(encoding="utf-8"))
workspace_root = _resolve_workspace_root(catalog)
webui = _extract_webui()
workspace_root = _resolve_workspace_root(catalog, args.workspace_root)
_validate_repository_roots(catalog, workspace_root)
webui = _extract_webui(workspace_root)
backend_endpoints = _extract_backend_endpoints(catalog, workspace_root)
manifests = _extract_manifests(catalog, workspace_root)
endpoint_declarations = _load_endpoint_declarations(
@@ -109,6 +116,10 @@ def main() -> int:
else None
),
)
inventory["workspace_root"] = str(workspace_root)
inventory["workspace_selection"] = (
"explicit" if args.workspace_root is not None else "legacy-discovery"
)
output_dir = args.output_dir.resolve()
output_dir.mkdir(parents=True, exist_ok=True)
@@ -212,7 +223,16 @@ def _strict_failures(
return failures
def _resolve_workspace_root(catalog: dict[str, Any]) -> Path:
def _resolve_workspace_root(
catalog: dict[str, Any], explicit_root: Path | None = None
) -> Path:
if explicit_root is not None:
root = explicit_root.expanduser().resolve()
if not root.is_dir():
raise ValueError("The explicit inventory workspace root must be an existing directory")
return root
# Compatibility for direct legacy callers only. Managed callers always
# supply their selected root; a partial checkout must not borrow sources.
sibling_root = META_ROOT.parent.resolve()
configured_root = Path(str(catalog["default_parent"])).expanduser().resolve()
repositories = catalog.get("repositories")
@@ -233,15 +253,44 @@ def _resolve_workspace_root(catalog: dict[str, Any]) -> Path:
return sibling_root if sibling_count >= configured_count else configured_root
def _extract_webui() -> dict[str, Any]:
def _validate_repository_roots(catalog: dict[str, Any], workspace_root: Path) -> None:
repositories = catalog.get("repositories")
if not isinstance(repositories, list):
raise ValueError("repository catalog has no repositories array")
for repository in repositories:
if not isinstance(repository, dict) or not isinstance(repository.get("path"), str):
raise ValueError("Invalid inventory repository path")
relative = Path(repository["path"])
if not repository["path"] or relative.is_absolute() or ".." in relative.parts:
raise ValueError("Inventory repository paths must remain inside the selected workspace")
root = workspace_root / relative
# Missing optional checkouts are allowed; links to another checkout are
# not evidence for the selected workspace.
if not root.resolve().is_relative_to(workspace_root):
raise ValueError("Inventory repository path escapes the selected workspace")
for source in (root / "src", root / "webui/src"):
if not source.resolve().is_relative_to(workspace_root):
raise ValueError("Inventory source root escapes the selected workspace")
def _extract_webui(workspace_root: Path | None = None) -> dict[str, Any]:
helper = META_ROOT / "tools" / "inventory" / "extract-webui-structure.mjs"
argv = [os.environ.get("NODE", "node"), str(helper), str(META_ROOT)]
if workspace_root is not None:
argv.extend(["--workspace-root", str(workspace_root)])
completed = subprocess.run(
["node", str(helper), str(META_ROOT)],
argv,
check=True,
capture_output=True,
text=True,
)
return json.loads(completed.stdout)
result = json.loads(completed.stdout)
if workspace_root is not None and (
not isinstance(result, dict)
or result.get("workspaceRoot") != str(workspace_root.resolve())
):
raise ValueError("WebUI collector did not confirm the selected inventory workspace")
return result
def _extract_backend_endpoints(
@@ -255,6 +304,8 @@ def _extract_backend_endpoints(
if not source_root.is_dir():
continue
for source_path in sorted(source_root.rglob("*.py")):
if not source_path.resolve().is_relative_to(workspace_root):
raise ValueError("Backend source path escapes the selected workspace")
try:
tree = ast.parse(
source_path.read_text(encoding="utf-8"),
@@ -346,15 +397,26 @@ def _extract_manifests(
catalog: dict[str, Any],
workspace_root: Path,
) -> list[dict[str, Any]]:
_validate_repository_roots(catalog, workspace_root)
source_roots = [
workspace_root / repository["path"] / "src"
for repository in catalog["repositories"]
if (workspace_root / repository["path"] / "src").is_dir()
]
core_root = next(
(workspace_root / repository["path"] / "src"
for repository in catalog["repositories"]
if repository.get("name") == "govoplan-core"),
workspace_root / "govoplan-core/src",
)
if not (core_root / "govoplan_core/core/platform_interfaces.py").is_file():
raise ValueError("Inventory requires Core interface sources in the selected workspace")
_assert_workspace_imports(workspace_root)
sys.path[:0] = [str(path) for path in source_roots]
from govoplan_core.core.platform_interfaces import ( # noqa: PLC0415
manifest_interface_catalog,
)
_assert_workspace_imports(workspace_root)
manifests: list[dict[str, Any]] = []
for repository in catalog["repositories"]:
@@ -366,7 +428,12 @@ def _extract_manifests(
manifest_path.relative_to(source_root).with_suffix("").parts
)
loaded = importlib.import_module(module_name)
source = getattr(loaded, "__file__", None)
if not isinstance(source, str) or Path(source).resolve() != manifest_path.resolve():
raise ValueError("Manifest import did not resolve to its selected workspace source")
_assert_workspace_imports(workspace_root)
manifest = loaded.get_manifest()
_assert_workspace_imports(workspace_root)
frontend = manifest.frontend
manifests.append(
{
@@ -452,6 +519,26 @@ def _extract_manifests(
return sorted(manifests, key=lambda item: item["id"])
def _assert_workspace_imports(workspace_root: Path) -> None:
# An editable installation or cached import must not stand in for a missing
# optional checkout. Direct callers with another workspace use a fresh
# process instead of replacing already-loaded application packages.
for name, module in list(sys.modules.items()):
# The Meta tools may audit a separate checkout; they are not module
# contributions and must not be confused with application packages.
package = name.partition(".")[0]
if not package.startswith("govoplan_") or package in {
"govoplan_devkit", "govoplan_release"
}:
continue
filename = getattr(module, "__file__", None)
locations = list(getattr(module, "__path__", ()))
if isinstance(filename, str):
locations.append(filename)
if any(not Path(location).resolve().is_relative_to(workspace_root) for location in locations):
raise ValueError("A GovOPlaN import originates outside the selected inventory workspace")
def _assemble_inventory(
*,
webui: dict[str, Any],