#!/usr/bin/env python3 """Generate deterministic P8-02 full startup matrix closure evidence.""" from __future__ import annotations import argparse, hashlib, json from pathlib import Path from typing import Any OUTPUTS = (Path("coverage/full-configuration-startup-matrix.report.json"), Path("coverage/configuration-regression.report.json"), Path("scripts/generate_full_configuration_startup_matrix.py")) def canonical(value: Any) -> str: return json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":")) def sha256(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() def generate(root: Path, report_path: Path) -> dict[str, Any]: matrix = json.loads((root / OUTPUTS[0]).read_text(encoding="utf-8")) regression = json.loads((root / OUTPUTS[1]).read_text(encoding="utf-8")) report = {"schema":"startup-matrix-closure-report.v1","task_id":"P8-02","context_id":"linuxcnc-2.10.0-pre0-wasm-m1-py-c1","status":"verified" if matrix.get("implementation_status")=="verified" else "blocked","counts":matrix.get("counts",{}),"classification":{"ready":matrix.get("counts",{}).get("statuses",{}).get("ready",0),"blocked":matrix.get("counts",{}).get("statuses",{}).get("blocked",0),"error":0},"diagnostics":{"source_resource_component":True,"missing_resources":regression.get("counts",{}).get("missing_resource_paths",0),"unresolved_resources":regression.get("counts",{}).get("unresolved_resource_paths",0)},"release_stop":{"action":"STOP_RELEASE","candidate_eligible":False},"outputs":[{"path":p.as_posix(),"bytes":(root/p).stat().st_size,"sha256":sha256(root/p)} for p in OUTPUTS],"known_boundaries":["P8-03 repeat determinism","official oracle and release owners remain blocked"]} report["report_sha256"] = hashlib.sha256(canonical(report).encode()).hexdigest(); report_path.parent.mkdir(parents=True,exist_ok=True); report_path.write_text(json.dumps(report,ensure_ascii=False,sort_keys=True,indent=2)+"\n",encoding="utf-8"); return report def main()->int: p=argparse.ArgumentParser(); p.add_argument("--repo-root",type=Path,default=Path(__file__).resolve().parents[1]); p.add_argument("--report",type=Path,default=Path("coverage/startup-matrix-closure.report.json")); a=p.parse_args(); r=generate(a.repo_root.resolve(),a.repo_root.resolve()/a.report); print(f"startup_matrix={r['status']} ready={r['classification']['ready']} blocked={r['classification']['blocked']}"); return 0 if r["status"]=="verified" else 1 if __name__=="__main__": raise SystemExit(main())