#!/usr/bin/env python3 """Runtime surface manifest helpers for PlantAI-rag cleanup audits.""" from __future__ import annotations import json from functools import lru_cache from pathlib import Path from typing import Any PROJECT_ROOT = Path(__file__).resolve().parents[1] DEFAULT_MANIFEST_PATH = PROJECT_ROOT / "config" / "runtime_surface_manifest.json" def _as_string_set(value: Any) -> frozenset[str]: if not isinstance(value, list): return frozenset() return frozenset(str(item) for item in value) def _section(manifest: dict[str, Any], name: str) -> dict[str, Any]: value = manifest.get(name) return value if isinstance(value, dict) else {} @lru_cache(maxsize=4) def load_runtime_surface(manifest_path: str | Path = DEFAULT_MANIFEST_PATH) -> dict[str, Any]: path = Path(manifest_path) with path.open("r", encoding="utf-8") as handle: manifest = json.load(handle) if not isinstance(manifest, dict): raise ValueError(f"Runtime surface manifest must be a JSON object: {path}") if int(manifest.get("schema_version") or 0) != 1: raise ValueError(f"Unsupported runtime surface manifest schema: {path}") return manifest def current_runtime_files(manifest: dict[str, Any] | None = None) -> frozenset[str]: manifest = manifest or load_runtime_surface() return _as_string_set(_section(manifest, "current_runtime").get("files")) def current_runtime_prefixes(manifest: dict[str, Any] | None = None) -> tuple[str, ...]: manifest = manifest or load_runtime_surface() return tuple(_as_string_set(_section(manifest, "current_runtime").get("prefixes"))) def required_tracked_files(manifest: dict[str, Any] | None = None) -> frozenset[str]: manifest = manifest or load_runtime_surface() return _as_string_set(manifest.get("required_tracked_files")) def legacy_prefixes(manifest: dict[str, Any] | None = None) -> tuple[str, ...]: manifest = manifest or load_runtime_surface() return tuple(_as_string_set(_section(manifest, "legacy").get("prefixes"))) def legacy_files(manifest: dict[str, Any] | None = None) -> frozenset[str]: manifest = manifest or load_runtime_surface() return _as_string_set(_section(manifest, "legacy").get("files")) def docs_history_files(manifest: dict[str, Any] | None = None) -> frozenset[str]: manifest = manifest or load_runtime_surface() return _as_string_set(_section(manifest, "docs_history").get("files")) def docs_history_prefixes(manifest: dict[str, Any] | None = None) -> tuple[str, ...]: manifest = manifest or load_runtime_surface() return tuple(_as_string_set(_section(manifest, "docs_history").get("prefixes"))) def test_fixture_prefixes(manifest: dict[str, Any] | None = None) -> tuple[str, ...]: manifest = manifest or load_runtime_surface() return tuple(_as_string_set(_section(manifest, "test_fixture").get("prefixes"))) def classify_path(path: str, manifest: dict[str, Any] | None = None) -> str: manifest = manifest or load_runtime_surface() if path in current_runtime_files(manifest) or path.startswith(current_runtime_prefixes(manifest)): return "current_runtime" if path.startswith(test_fixture_prefixes(manifest)): return "test_fixture" if ( path in docs_history_files(manifest) or path.startswith(docs_history_prefixes(manifest)) or path.endswith(".md") ): return "docs_history" if path in legacy_files(manifest) or path.startswith(legacy_prefixes(manifest)): return "legacy_script" return "other_tracked"