from __future__ import annotations import hashlib import json from datetime import datetime from typing import List from .models import PlanDelta class GovernanceLedger: def __init__(self) -> None: self.chain: List[dict] = [] # each entry: {index, hash, prev_hash, delta, ts} def _hash_entry(self, prev_hash: str, entry: dict) -> str: data = json.dumps({"prev_hash": prev_hash, "entry": entry}, sort_keys=True) return hashlib.sha256(data.encode("utf-8")).hexdigest() def append(self, delta: PlanDelta) -> str: prev_hash = self.chain[-1]["hash"] if self.chain else "0" * 64 entry = { "version": delta.version, "plan": delta.plan, "provenance": delta.provenance, "signature": delta.signature, "ts": datetime.utcnow().isoformat() + "Z", } entry_hash = self._hash_entry(prev_hash, entry) self.chain.append({"index": len(self.chain), "hash": entry_hash, "prev_hash": prev_hash, "entry": entry}) return entry_hash def root(self) -> str: if not self.chain: return "0" * 64 return self.chain[-1]["hash"] def attest(self, delta: PlanDelta, key: str = "ledger") -> str: # Lightweight attest placeholder payload = delta.to_json() return hashlib.sha256((payload + "::" + key).encode("utf-8")).hexdigest()