"""Tamper-evident ledger scaffold for BeXProof. This ledger appends entries with a simple hash-chain to provide an auditable trail. It's a lightweight MVP; a production system would use a proper append-only store. """ from __future__ import annotations import json import time import hashlib from pathlib import Path from typing import Dict, Any class TamperProofLedger: def __init__(self, path: str = "bexproof_ledger.log"): self.path = Path(path) self.path.parent.mkdir(parents=True, exist_ok=True) self._last_hash = self._load_last_hash() def _load_last_hash(self) -> str: if not self.path.exists(): return "" # no previous hash # read last line to pull last hash if present last = None with self.path.open("r", encoding="utf-8") as f: for line in f: last = line if not last: return "" try: obj = json.loads(last) return obj.get("hash", "") except Exception: return "" def _hash_entry(self, entry: Dict[str, Any], prev_hash: str) -> str: payload = json.dumps(entry, sort_keys=True).encode("utf-8") data = payload + prev_hash.encode("utf-8") return hashlib.sha256(data).hexdigest() def append(self, entry: Dict[str, Any]) -> Dict[str, Any]: prev_hash = self._last_hash or "" h = self._hash_entry(entry, prev_hash) record = { "entry": entry, "timestamp": int(time.time() * 1000), "prev_hash": prev_hash, "hash": h, } with self.path.open("a", encoding="utf-8") as f: f.write(json.dumps(record, sort_keys=True) + "\n") self._last_hash = h return record