"""validate_agents_rule_hashes_v1.py — AGENTS rule hash migration validator""" from __future__ import annotations import hashlib from pathlib import Path import yaml ROOT = Path(__file__).resolve().parents[1] INDEX = ROOT / "governance" / "agents_index.yaml" HASHES = ROOT / "governance" / "agents_rule_hashes.yaml" def sha256(path: Path) -> str: return hashlib.sha256(path.read_bytes()).hexdigest() def main() -> int: if not INDEX.exists() or not HASHES.exists(): print("AGENTS_RULE_HASH_FAIL: missing index or hashes") return 1 index = yaml.safe_load(INDEX.read_text(encoding="utf-8")) or {} hashes = yaml.safe_load(HASHES.read_text(encoding="utf-8")) or {} rule_files = index.get("rule_files") if isinstance(index.get("rule_files"), list) else [] items = hashes.get("files") if isinstance(hashes.get("files"), list) else [] live = {str(item.get("path")): str(item.get("sha256")) for item in items if isinstance(item, dict)} missing = [] mismatch = [] for rel in rule_files + ["AGENTS.md"]: path = ROOT / rel if not path.exists(): missing.append(rel) continue digest = sha256(path) if live.get(rel) != digest: mismatch.append(rel) if missing or mismatch: print("AGENTS_RULE_HASH_FAIL") if missing: print(f"missing={missing}") if mismatch: print(f"mismatch={mismatch}") return 1 print("AGENTS_RULE_HASH_OK") print(f"files={len(rule_files) + 1}") return 0 if __name__ == "__main__": raise SystemExit(main())