snapkitty
compilers
c
python
nasm
sovereign-engine-v2 / src /core /evidence.py
SNAPKITTYWEST's picture
push from SNAPKITTYWEST/sovereign-engine-v2
9abace2 verified
Raw History Blame Contribute Delete
5 kB
"""
Layer 0: WORM Evidence Ledger
Part of SOVEREIGN PYTHON LLM ENGINE
Append-only binary ledger backed by storage.WORMFile (struct-packed records).
No JSON, no text, no injection surface.
"""
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Iterator
from .crypto import ContentHash, Signature, SigningKey, hash_content, sign_artifact
from .storage import WORMFile, WORMRecord
# ─────────────────────────────────────────────
# Evidence Record (public API type)
# ─────────────────────────────────────────────
@dataclass(frozen=True)
class EvidenceRecord:
timestamp_ns: int
event_type: str
content_hash: bytes
signature: bytes
payload: bytes
metadata: bytes
prev_hash: bytes
@property
def timestamp(self) -> float:
return self.timestamp_ns / 1_000_000_000
def _record_from_worm(w: WORMRecord) -> EvidenceRecord:
return EvidenceRecord(
timestamp_ns=w.timestamp_ns,
event_type=w.event_type,
content_hash=w.content_hash,
signature=w.signature,
payload=w.payload,
metadata=w.metadata,
prev_hash=w.prev_hash
)
# ─────────────────────────────────────────────
# WORM Ledger
# ─────────────────────────────────────────────
class WORMLedger:
"""
Write-Once-Read-Many append-only ledger.
Backed by binary struct-packed records (WORMFile).
No JSONL, no text encoding, no injection surface.
Public API is unchanged from the JSONL version β€”
callers pass raw bytes for payload, raw bytes for metadata.
"""
def __init__(self, ledger_path: Path, signing_key: SigningKey | None = None):
self._file = WORMFile(ledger_path, signing_key=signing_key)
self.ledger_path = ledger_path
self.signing_key = signing_key
def append(
self,
event_type: str,
data: bytes | dict | str | None = None,
metadata: bytes | dict | str | None = None
) -> EvidenceRecord:
"""
Append evidence record.
data and metadata accept:
bytes β€” written as-is
dict β€” encoded as UTF-8 key=value pairs (no JSON)
str β€” encoded as UTF-8
None β€” empty bytes
"""
payload = self._coerce(data)
meta = self._coerce(metadata)
rec = self._file.append(event_type, payload, meta)
return _record_from_worm(rec)
def read_all(self) -> list[EvidenceRecord]:
return [_record_from_worm(r) for r in self._file.scan()]
def scan(self) -> Iterator[EvidenceRecord]:
for r in self._file.scan():
yield _record_from_worm(r)
def verify_chain(self) -> bool:
valid, _ = self._file.verify_chain()
return valid
def get_records_by_type(self, event_type: str) -> list[EvidenceRecord]:
return [_record_from_worm(r) for r in self._file.scan_by_type(event_type)]
def count(self) -> int:
return self._file.count()
@staticmethod
def _coerce(value: bytes | dict | str | None) -> bytes:
if value is None:
return b''
if isinstance(value, bytes):
return value
if isinstance(value, str):
return value.encode('utf-8')
if isinstance(value, dict):
# Flat key=value encoding β€” no JSON, no injection
parts = []
for k, v in value.items():
k_s = str(k).replace('=', '_').replace('\n', '_')
v_s = str(v).replace('\n', '_')
parts.append(f"{k_s}={v_s}")
return '\n'.join(parts).encode('utf-8')
return str(value).encode('utf-8')
# ─────────────────────────────────────────────
# Stats helper
# ─────────────────────────────────────────────
def ledger_stats(ledger: WORMLedger) -> dict[str, Any]:
records = ledger.read_all()
event_counts: dict[str, int] = {}
for r in records:
event_counts[r.event_type] = event_counts.get(r.event_type, 0) + 1
return {
'total_records': len(records),
'event_counts': event_counts,
'first_timestamp': records[0].timestamp if records else None,
'last_timestamp': records[-1].timestamp if records else None,
'chain_valid': ledger.verify_chain()
}