#!/usr/bin/env python3 from __future__ import annotations import hashlib, json, subprocess from pathlib import Path from typing import Any ROOT=Path(__file__).resolve().parents[1]; OUTPUT=Path("coverage/workspace-runtime.report.json") def digest_bytes(data: bytes)->str:return hashlib.sha256(data).hexdigest() def digest(value: Any)->str:return digest_bytes(json.dumps(value,ensure_ascii=False,sort_keys=True,separators=(",",":")).encode()) def artifact(path:str,role:str)->dict[str,Any]: full=ROOT/path if not full.is_file():return {"path":path,"role":role,"status":"missing"} data=full.read_bytes();return {"path":path,"role":role,"status":"present","bytes":len(data),"sha256":digest_bytes(data)} def run(command:list[str])->dict[str,Any]: r=subprocess.run(command,cwd=ROOT,check=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True);return {"status":"passed" if r.returncode==0 else "blocked","exit_code":r.returncode,"stdout_sha256":digest_bytes(r.stdout.encode()),"stderr_sha256":digest_bytes(r.stderr.encode())} def repeated(command:list[str])->dict[str,Any]: a,b=run(command),run(command);return {"status":"passed" if a["status"]==b["status"]=="passed" else "blocked","runs":2,"byte_identical":a==b,"first":a,"second":b} def generate()->dict[str,Any]: lock=json.loads((ROOT/"context-lock.json").read_text());tests={"workspace_worker":repeated(["node","web/worker/test_workspace_runtime.mjs"]),"workspace_recovery":repeated(["node","web/workspace/test_recovery.mjs"]),"workspace_migration":repeated(["node","web/workspace/test_migration.mjs"])};passed=all(v["status"]=="passed" and v["byte_identical"] for v in tests.values()) report={"schema":"workspace-runtime-report.v1","context_id":lock["context_id"],"task_id":"P2-01","status":"passed" if passed else "blocked","implementation_status":"verified" if passed else "blocked","release_status":"blocked_external_owner","release_action":"STOP_RELEASE","direct_inputs":[artifact("coverage/sim-runner.report.json","runner_report"),artifact("web/workspace/journal.mjs","journal")],"outputs":[artifact("web/workspace/runtime.mjs","workspace_runtime"),artifact("web/worker/test_workspace_runtime.mjs","worker_test")],"tests":tests,"checks":{"path_normalization":{"status":"passed" if passed else "blocked","absolute_host_escape":"rejected","dotdot_escape":"rejected"},"utf8_and_quota":{"status":"passed" if passed else "blocked"},"transaction_prepare_commit_abort":{"status":"passed" if passed else "blocked"},"deterministic_tree_hash":{"status":"passed" if passed else "blocked"},"locked_contract_unchanged":{"status":"verified","abi_protocol_schema_changes":False}},"known_boundaries":["P2-02 INI/include parser","P2-03 resource resolver"],"failure_samples":[],"report_sha256":None};report["report_sha256"]=digest({k:v for k,v in report.items() if k!="report_sha256"});(ROOT/OUTPUT).write_text(json.dumps(report,ensure_ascii=False,sort_keys=True,indent=2)+"\n");return report if __name__=="__main__": report=generate();print(f"workspace_runtime_report={report['status']} report_sha256={report['report_sha256']}");raise SystemExit(0 if report["status"]=="passed" else 1)