#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later """Validate the fail-closed Phase-0.5 machine-readable decision records.""" from __future__ import annotations import argparse import json from pathlib import Path BLOCKED_SHA256 = "4be1c17b4964f2b68c39b5145bc4af4619c32512d60269ecf5c39728b390fa63" def load(path: Path) -> dict[str, object]: document = json.loads(path.read_text(encoding="utf-8")) if not isinstance(document, dict): raise RuntimeError(f"{path}: expected object") return document def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--root", type=Path, required=True) args = parser.parse_args() root = args.root.resolve() audit = load(root / "manifests/runtime/phase-0.5-startup-audit.json") decision = load(root / "manifests/runtime/minimal-startup-artifact-decision.json") matrix = load(root / "manifests/runtime/kernelwrite-proof-matrix.json") denylist = load(root / "manifests/artifact-denylist.json") if audit.get("decision") != "BLOCKED" or audit["artifact"]["built"] is not False: raise RuntimeError("startup audit no longer blocks artifact construction") if audit["artifact"]["execution_eligible"] is not False: raise RuntimeError("startup audit claims execution eligibility") if audit["loader_evidence"]["caller_source_present"] is not False: raise RuntimeError("audit claims an unreviewed loader caller") required_reachable = { "__patch_init", "kernel_copyin", "kernel_copyout", "kernel_set_ucred_attrs", "kernel_set_ucred_caps", } reachable = set(audit["crt1_static_evidence"]["reachable_prohibited_functions"]) if reachable != required_reachable: raise RuntimeError(f"reachable kernel-write inventory changed: {reachable}") if decision.get("decision") != "BLOCKED" or decision["artifact"]["built"] is not False: raise RuntimeError("non-build decision changed") if decision["execution"]["execution_eligible"] is not False: raise RuntimeError("non-build record claims execution eligibility") if any(value is not None for value in ( decision["artifact"]["filename"], decision["artifact"]["sha256"], decision["artifact"]["size"], )): raise RuntimeError("non-build decision fabricates artifact bytes") statuses = {entry["status"] for entry in matrix["entries"]} if statuses != {"SAFE", "UNSAFE", "UNPROVEN"}: raise RuntimeError(f"review matrix lacks a status class: {statuses}") if [entry["sha256"] for entry in denylist["entries"]] != [BLOCKED_SHA256]: raise RuntimeError("permanent blocked hash changed") print("Phase-0.5 machine-readable BLOCKED decision is consistent") return 0 if __name__ == "__main__": raise SystemExit(main())