#!/usr/bin/env python3
import json,hashlib,sys,zipfile,subprocess
from pathlib import Path
can=lambda x:json.dumps(x,sort_keys=True,separators=(",",":"),ensure_ascii=True).encode();sha=lambda b:hashlib.sha256(b).hexdigest();r=Path(sys.argv[1]);v=json.loads((r/"verifier-input.json").read_text());m=json.loads((r/"candidate-manifest.json").read_text());inv=json.loads((r/"hash-inventory.json").read_text());assert sha((r/"candidate-manifest.json").read_bytes())==v["manifest_sha256"];full=m.pop("full_candidate_digest");assert full==sha(can(m))==v["full_candidate_digest"];m["full_candidate_digest"]=full;actual={str(p.relative_to(r)) for p in r.rglob("*") if p.is_file()};indexed={x["path"] for x in inv["entries"]};controls={"candidate-manifest.json","hash-inventory.json","verifier-input.json"};assert actual==indexed|controls
for x in inv["entries"]:p=r/x["path"];assert p.stat().st_size==x["bytes"] and sha(p.read_bytes())==x["sha256"]
assert (r/"status-pre.nul").read_bytes()==(r/"status-post.nul").read_bytes();d=json.loads((r/"bindings/source-delta.json").read_text());assert len(d["files"])==4 and d["diff_sha256"]=="cb15bb8067e665eaaf5a5d0b0d70a8058e0986962a54917b708b9a5e5e9d9a87";assert sha((r/"source-delta/authenticated-fix-evidence/exact.diff").read_bytes())==d["diff_sha256"]
with zipfile.ZipFile(r/"artifacts/hermes_agent-0.17.0-py3-none-any.whl") as z:
 for x in m["production_sources"]:assert sha(z.read(x["path"]))==x["sha256"]
pred=r/"historical/e2f-candidate";subprocess.run(["python",str(pred/"verify_candidate.py"),str(pred)],check=True,stdout=subprocess.DEVNULL);assert m["readiness"]=="READY_FOR_FRESH_GATE18_20";print(json.dumps({"status":"PASS","full":full,"core":m["core_candidate_digest"],"wheel":m["wheel_sha256"],"inventory_count":len(inv["entries"]),"unindexed":0,"delta_count":4,"production_parity":len(m["production_sources"]),"predecessor_verified":True,"ready":True},sort_keys=True))
