#!/usr/bin/env python3 """Check maturity-engine against the NetKingdom security layer model (§5, §11). This is an Engine (PIP). The checkable claims: - INTENT.md frontmatter declares the layer and governs (GH-DEC-2026-017 §1) - layer.yaml is derived: marked `derived: true`, `derived_from: INTENT.md`, and declares layer=engine, role=pip - both layer values are in §3's closed four-token vocabulary and are compared after an ASCII case fold (A9); nothing is re-spelled. A disagreement that survives the fold is reported as a finding, not resolved by precedence (A11) - neither form carries a standard or companion version in any key or value, including a version-bearing `standard:` or `companion:` path (A12 r2, GH-DEC-2026-020 §1-§2). Comments and `schema_version` are not reached, and stance/claims/classification files are out of scope (GH-DEC-2026-020 §3) - no pep_stance path - no catalogued Tooling client (OpenBao, key-cape, cluster) - sqlite3 is this PIP's own store and is allowed Every run prints the standard text it checks against (VALIDATED_AGAINST) and the scope it ranged over (GH-DEC-2026-020 §4: the version belongs to the run). Exit 0 clean, 1 undeclared Tooling contact, 2 declaration malformed. """ from __future__ import annotations import argparse import ast import re import sys from pathlib import Path import yaml # The standard text this checker was built and validated against, printed on # every run (GH-DEC-2026-020 §4; kings-guard's pattern). A declaration MUST NOT # carry this (A12); the run does. Bump it when re-validated against a newer # accepted text. VALIDATED_AGAINST = ( "net-kingdom/canon/standards/security-layer-model_v0.7.md" " (+ GH-DEC-2026-017, GH-DEC-2026-020 / A12 r2)" ) # §3 as amended (A9): closed, four tokens, compared after an ASCII case fold. LAYER_VOCABULARY = {"taxonomy", "tooling", "engine", "staff"} def _fold(value: object) -> str: """ASCII case-fold: two spellings of a token are one token.""" return str(value).strip().encode("ascii", "ignore").decode().lower() ROOT = Path(__file__).resolve().parents[1] SRC = ROOT / "src" / "maturity_engine" DECL = ROOT / "layer.yaml" INTENT = ROOT / "INTENT.md" # What this run ranges over. Declaration files only: stance, claims and # evidence-classification maps are deliberately NOT in scope (GH-DEC-2026-020 §3). SCOPE = "INTENT.md frontmatter, layer.yaml, imports under src/maturity_engine" # A12 r2: a version anywhere in the declaration, not only a key literally named # `standard_version`. `schema_version` is the file format's own version, not a # standard version, and is not reached (GH-DEC-2026-020 §1). EXEMPT_VERSION_KEYS = {"schema_version"} # A version-bearing path or file name, e.g. `security-layer-model_v0.7.md`, # `.../v0.2/companion.md`. Matched only against whitespace-free values, so prose # notes citing a rule's history are not mistaken for a pin. VERSIONED_PATH = re.compile(r"(?i)(?:^|[_\-/.])v\d+(?:\.\d+)*(?:$|[_\-/.])") # Keys that name a standard or companion: any version-like token in their value counts. STANDARD_KEYS = {"standard", "companion", "framework"} BARE_VERSION = re.compile(r"\d+\.\d+") def version_findings(data: object, where: str) -> list[str]: """Every place a standard or companion version appears in a declaration.""" found: list[str] = [] def walk(node: object, path: str, key: str | None) -> None: if isinstance(node, dict): for k, v in node.items(): ks = str(k) if ks in EXEMPT_VERSION_KEYS: continue if "version" in ks.lower(): found.append(f"{where}: key '{path}{ks}' carries a version") walk(v, f"{path}{ks}.", ks) elif isinstance(node, list): for i, v in enumerate(node): walk(v, f"{path}{i}.", key) elif isinstance(node, str): value = node.strip() label = path.rstrip(".") if key and key.lower() in STANDARD_KEYS and BARE_VERSION.search(value): found.append(f"{where}: '{label}' value {value!r} carries a version") elif value and not any(c.isspace() for c in value) and VERSIONED_PATH.search(value): found.append(f"{where}: '{label}' value {value!r} is a version-bearing path") walk(data, "", None) return found def _fail_versions(findings: list[str]) -> None: print( "FAIL: a layer declaration MUST NOT carry a standard or companion version, " "in any key or value (GH-DEC-2026-017 §5, GH-DEC-2026-020, A12 r2)", file=sys.stderr, ) for line in findings: print(f" {line}", file=sys.stderr) raise SystemExit(2) TOOLING_IMPORTS = { "hvac": "OpenBao / Vault client", "bao": "OpenBao client", "kubernetes": "cluster client", "kubernetes_asyncio": "cluster client", "ldap3": "direct LDAP client (key-cape tooling)", "python_ldap": "direct LDAP client (key-cape tooling)", } def load_declaration() -> dict: if not DECL.exists(): print(f"FAIL: no declaration at {DECL.relative_to(ROOT)} (§11)", file=sys.stderr) raise SystemExit(2) try: data = yaml.safe_load(DECL.read_text()) except yaml.YAMLError as exc: print(f"FAIL: {DECL.name} is not parseable: {exc}", file=sys.stderr) raise SystemExit(2) from exc for key in ("layer", "role", "repository", "tooling_contacts", "derived", "derived_from"): if key not in data: print(f"FAIL: {DECL.name} missing required key '{key}' (§11)", file=sys.stderr) raise SystemExit(2) if data["derived"] is not True: print( f"FAIL: {DECL.name} must be marked 'derived: true' (§11, GH-DEC-2026-017 §1)", file=sys.stderr, ) raise SystemExit(2) if data["derived_from"] != "INTENT.md": print( f"FAIL: {DECL.name} derives from {data['derived_from']!r}; §11 names INTENT.md", file=sys.stderr, ) raise SystemExit(2) findings = version_findings(data, DECL.name) if findings: _fail_versions(findings) if _fold(data["layer"]) not in LAYER_VOCABULARY: print( f"FAIL: {DECL.name} layer {data['layer']!r} is outside §3's closed vocabulary " f"{sorted(LAYER_VOCABULARY)} (case-insensitive)", file=sys.stderr, ) raise SystemExit(2) if _fold(data["layer"]) != "engine": print(f"FAIL: declared layer is {data['layer']!r}, expected 'engine'", file=sys.stderr) raise SystemExit(2) if _fold(data["role"]) != "pip": print(f"FAIL: declared role is {data['role']!r}, expected 'pip'", file=sys.stderr) raise SystemExit(2) if data.get("pep_stance"): print("FAIL: pep_stance is set; this engine is not PEP-shaped", file=sys.stderr) raise SystemExit(2) return data def intent_frontmatter() -> dict: text = INTENT.read_text() match = re.match(r"^---\n(.*?)\n---\n", text, re.DOTALL) if not match: print("FAIL: INTENT.md has no YAML frontmatter (§11)", file=sys.stderr) raise SystemExit(2) meta = yaml.safe_load(match.group(1)) if not isinstance(meta, dict): print("FAIL: INTENT.md frontmatter is not a mapping", file=sys.stderr) raise SystemExit(2) if "layer" not in meta: print( "FAIL: INTENT.md frontmatter has no 'layer:' key — that is the declaration (§11)", file=sys.stderr, ) raise SystemExit(2) findings = version_findings(meta, "INTENT.md frontmatter") if findings: _fail_versions(findings) if _fold(meta["layer"]) not in LAYER_VOCABULARY: print( f"FAIL: INTENT.md layer {meta['layer']!r} is outside §3's closed vocabulary " f"{sorted(LAYER_VOCABULARY)} (case-insensitive)", file=sys.stderr, ) raise SystemExit(2) return meta def imported_modules(path: Path) -> set[str]: try: tree = ast.parse(path.read_text()) except SyntaxError: return set() found: set[str] = set() for node in ast.walk(tree): if isinstance(node, ast.Import): found.update(alias.name.split(".")[0] for alias in node.names) elif isinstance(node, ast.ImportFrom): if node.level == 0 and node.module: found.add(node.module.split(".")[0]) return found def scan() -> list[tuple[Path, str, str]]: hits: list[tuple[Path, str, str]] = [] for path in sorted(SRC.rglob("*.py")): for module in sorted(imported_modules(path)): if module in TOOLING_IMPORTS: hits.append((path, module, TOOLING_IMPORTS[module])) return hits def main() -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--report", action="store_true") args = parser.parse_args() # GH-DEC-2026-020 §4: every run states what it checks against and its scope, # on stdout, before any verdict — so a failing run carries it too. print(f"check_layer_conformance: validated against {VALIDATED_AGAINST}; scope: {SCOPE}") decl = load_declaration() intent = intent_frontmatter() # A11: the derived form MUST agree with the governing one. Case is folded # first (A9), so a mismatch here is a real layer disagreement — a finding # in its own right, reported rather than resolved away by precedence. if _fold(intent["layer"]) != _fold(decl["layer"]): print( f"FAIL: layer disagreement after case fold — INTENT.md (governs) " f"{intent['layer']!r} vs layer.yaml (derived) {decl['layer']!r}", file=sys.stderr, ) return 2 if _fold(intent.get("role", "")) != _fold(decl["role"]): print( f"FAIL: INTENT.md role {intent.get('role')!r} != layer.yaml {decl['role']!r}", file=sys.stderr, ) return 2 hits = scan() if hits: print("FAIL: catalogued Tooling-layer client in an Engine that does not own it", file=sys.stderr) for path, module, what in hits: print(f" {path.relative_to(ROOT)}: imports {module!r} — {what}", file=sys.stderr) return 1 if args.report: print( f"maturity-engine — layer {intent['layer']} (INTENT.md, governs), role {decl['role']}" ) print(f" layer.yaml: derived from {decl['derived_from']}, layer: {decl['layer']}") print(f" tooling contacts: {len(decl.get('tooling_contacts') or [])}") print(f" non-tooling clients: {len(decl.get('non_tooling_clients') or [])}") print(" pep_stance: none") print(f" checker validated against: {VALIDATED_AGAINST}") print(f" scope: {SCOPE}") else: print( f"OK: Engine/PIP declaration holds; no catalogued Tooling client in " f"{SRC.relative_to(ROOT)}; validated against {VALIDATED_AGAINST}; scope: {SCOPE}" ) return 0 if __name__ == "__main__": raise SystemExit(main())