"""validate_calibration_change_ledger_v1.py — CALIBRATION_CHANGE_LEDGER_V1 validator""" from __future__ import annotations import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] PATH = ROOT / "Temp" / "calibration_change_ledger_v4.json" def main() -> int: if not PATH.exists(): print("CALIBRATION_CHANGE_LEDGER_FAIL: missing Temp/calibration_change_ledger_v4.json") return 1 try: data = json.loads(PATH.read_text(encoding="utf-8")) except Exception as exc: print(f"CALIBRATION_CHANGE_LEDGER_FAIL: invalid json ({exc})") return 1 changes = data.get("changes") if isinstance(data.get("changes"), list) else [] ledger_without_change_count = int(data.get("threshold_change_without_ledger_count") or 0) linked = data.get("linked_outcome_artifacts") if isinstance(data.get("linked_outcome_artifacts"), list) else [] missing = [] for idx, item in enumerate(changes): if not isinstance(item, dict): missing.append(f"changes[{idx}] not object") continue for key in ("threshold_id", "outcome_link", "registry_link"): if key not in item: missing.append(f"changes[{idx}] missing {key}") ok = bool(changes) and ledger_without_change_count == 0 and "Temp/outcome_ledger_v1.json" in linked and not missing if ok: print("CALIBRATION_CHANGE_LEDGER_OK") print(f"changes={len(changes)} linked_outcome_artifacts={len(linked)}") return 0 print("CALIBRATION_CHANGE_LEDGER_FAIL") print(f"changes={len(changes)} threshold_change_without_ledger_count={ledger_without_change_count} linked={linked}") if missing: for item in missing[:10]: print(f"- {item}") return 1 if __name__ == "__main__": raise SystemExit(main())