Files
agent-desirecore/web/solver-report/scripts/verify-static-release.py
2026-08-30 14:01:19 -04:00

67 lines
2.8 KiB
Python

#!/usr/bin/env python3
import hashlib
import json
import pathlib
import sys
root = pathlib.Path(sys.argv[1]).resolve()
integrity = json.loads((root / "integrity.json").read_text(encoding="utf-8"))
failures = []
for entry in integrity["entries"]:
raw_path = entry.get("path")
if (
not isinstance(raw_path, str)
or not raw_path
or "//" in raw_path
or "\\" in raw_path
or "%" in raw_path
or "?" in raw_path
or "#" in raw_path
):
failures.append({"path": str(raw_path), "issue": "unsafe-path"})
continue
relative_path = pathlib.PurePosixPath(raw_path)
if relative_path.is_absolute() or any(part in ("", ".", "..") for part in relative_path.parts):
failures.append({"path": raw_path, "issue": "unsafe-path"})
continue
path = (root / pathlib.Path(*relative_path.parts)).resolve()
if path == root or root not in path.parents:
failures.append({"path": raw_path, "issue": "path-escape"})
continue
if not path.is_file():
failures.append({"path": raw_path, "issue": "missing"})
continue
data = path.read_bytes()
digest = hashlib.sha256(data).hexdigest()
if len(data) != entry["bytes"] or digest != entry["sha256"]:
failures.append({"path": raw_path, "issue": "mismatch"})
manifest = json.loads((root / "data" / "manifest.json").read_text(encoding="utf-8"))
build = json.loads((root / "build.json").read_text(encoding="utf-8"))
if build.get("gates", {}).get("publicReleasePrivacy") != "pass":
failures.append({"path": "build.json", "issue": "public-release-privacy-gate"})
if build.get("gates", {}).get("decisionTrees") != "pass":
failures.append({"path": "build.json", "issue": "decision-tree-gate"})
if build.get("publicReleaseAttestationSha256") != manifest.get("publicReleaseAttestationSha256"):
failures.append({"path": "build.json", "issue": "public-release-attestation-mismatch"})
if (
build.get("buildId") != manifest.get("buildId")
or build.get("contentRootSha256") != manifest.get("contentRootSha256")
or integrity.get("contentRootSha256") != manifest.get("contentRootSha256")
or build.get("publicEvidenceRoots") != manifest.get("publicEvidenceRoots")
or build.get("counts") != manifest.get("counts")
or build.get("integrityEntries") != len(integrity.get("entries", []))
or not any(entry.get("path") == "build.json" for entry in integrity.get("entries", []))
):
failures.append({"path": "build.json", "issue": "build-manifest-integrity-projection"})
result = {
"buildId": manifest["buildId"],
"contentRootSha256": manifest["contentRootSha256"],
"chapters": len(manifest["chapters"]),
"integrityEntries": len(integrity["entries"]),
"failures": failures,
"passed": not failures,
}
print(json.dumps(result, ensure_ascii=False))
raise SystemExit(0 if result["passed"] else 1)