idea161-civicpulse-privacy-.../idea161_civicpulse_privacy_.../governance.py

41 lines
1.4 KiB
Python

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()