| import json | |
| import hashlib | |
| from datetime import datetime, timezone | |
| from typing import Any, Dict | |
| DRP_EVENT_SPEC = "drp-event-v0" | |
| DRP_BUNDLE_SPEC = "drp-bundle-v0" | |
| def canon(obj: Any) -> bytes: | |
| """Canonical JSON encoding (stable for hashing/verifying across machines).""" | |
| return json.dumps( | |
| obj, | |
| ensure_ascii=False, | |
| sort_keys=True, | |
| separators=(",", ":"), | |
| ).encode("utf-8") | |
| def sha256_hex(b: bytes) -> str: | |
| return hashlib.sha256(b).hexdigest() | |
| def now_utc_iso() -> str: | |
| return datetime.now(timezone.utc).isoformat() | |
| def hash_event(event: Dict[str, Any]) -> str: | |
| """Hash event excluding its own 'hash' field (if present).""" | |
| e = dict(event) | |
| e.pop("hash", None) | |
| return sha256_hex(canon(e)) |