#!/usr/bin/env python3 """Aggregate complete-simulation technical evidence without changing release gates.""" from __future__ import annotations import argparse import hashlib import json from pathlib import Path from typing import Any REPORTS = ( "coverage/configuration-startup-runtime.report.json", "coverage/rs274-interpreter-closure.report.json", "coverage/o-word-runtime.report.json", "coverage/tp-blend.report.json", "coverage/task-program-state.report.json", "coverage/motion-state.report.json", "coverage/kinematics-base.report.json", "coverage/advanced-kinematics.report.json", "coverage/hal-graph.report.json", "coverage/component-capability.report.json", "coverage/plc-runtime.report.json", "coverage/device-twin.report.json", "coverage/io-ack.report.json", "coverage/python-runtime-closure.report.json", "coverage/python-api.report.json", "coverage/python-callbacks.report.json", "coverage/trace-export.report.json", "coverage/reconciliation.report.json", "coverage/offline-migration.report.json", "coverage/worker-protocol.report.json", "coverage/editor-workflow.report.json", "coverage/authoritative-panels.report.json", "coverage/machine-view.report.json", "coverage/recovery-ux.report.json", "coverage/native-oracle-closure.report.json", "coverage/startup-matrix-closure.report.json", "coverage/determinism.report.json", "coverage/browser-matrix-closure.report.json", ) 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, output: Path) -> dict[str, Any]: records = [] missing = [] for name in REPORTS: path = root / name if not path.is_file(): missing.append(name) continue try: value = json.loads(path.read_text(encoding="utf-8")) records.append({"path": name, "schema": value.get("schema"), "task_id": value.get("task_id"), "status": value.get("status"), "report_sha256": value.get("report_sha256"), "file_sha256": sha256(path)}) except Exception as exc: records.append({"path": name, "status": "blocked", "error": str(exc)}) verified = [record for record in records if record.get("status") == "verified"] not_verified = [record for record in records if record.get("status") != "verified"] report: dict[str, Any] = { "schema": "complete-simulation-technical-delivery.v1", "context_id": "linuxcnc-2.10.0-pre0-wasm-m1-py-c1", "status": "verified" if not missing and not not_verified else "partial", "technical_track": "complete-linuxcnc-simulation", "report_count": len(records), "verified_count": len(verified), "partial_or_blocked_count": len(not_verified), "missing_reports": missing, "reports": records, "release": {"status": "blocked", "action": "STOP_RELEASE", "candidate_eligible": False, "blockers": ["manifest_seed_unassigned", "accepted_entries_missing", "official_oracle_missing", "configuration_resources_missing", "browser_matrix_unverified", "license_closure_incomplete"]}, "invariants": {"context_lock_unchanged": True, "abi_protocol_schema_unchanged": True, "owner_gate_unchanged": True, "real_hardware_excluded": True, "official_oracle_not_fabricated": True}, "next_action": "release/owner track remains nextTask.md WAIT-OWNER-01; no automatic release acceptance", } report["report_sha256"] = hashlib.sha256(canonical(report).encode()).hexdigest() output.parent.mkdir(parents=True, exist_ok=True) output.write_text(json.dumps(report, ensure_ascii=False, sort_keys=True, indent=2) + "\n", encoding="utf-8") return report def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--repo-root", type=Path, default=Path(__file__).resolve().parents[1]) parser.add_argument("--report", type=Path, default=Path("coverage/complete-simulation-technical-delivery.report.json")) args = parser.parse_args() report = generate(args.repo_root.resolve(), args.repo_root.resolve() / args.report) print(f"technical_delivery={report['status']} reports={report['report_count']} verified={report['verified_count']} release={report['release']['action']}") return 0 if report["status"] in {"verified", "partial"} else 1 if __name__ == "__main__": raise SystemExit(main())