cosmosmesh-privacy-preservi.../src/cosmosmesh_privacy_preservi.../ledger.py

55 lines
1.6 KiB
Python

"""Experiment ledger for CosmosMesh MVP.
Records environment, topology, and delta outcomes to enable reproducible demos
and deterministic replay when disconnections occur.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional
@dataclass
class DeltaRecord:
delta_id: str
outcome: str
details: Dict[str, Any] = field(default_factory=dict)
def to_dict(self) -> Dict[str, Any]:
return {"delta_id": self.delta_id, "outcome": self.outcome, "details": self.details}
@dataclass
class ExperimentLedger:
environment_version: str
seed_space: str
topology: str
hardware_config: Dict[str, Any]
code_version_hash: str
deltas: List[DeltaRecord] = field(default_factory=list)
proofs: List[str] = field(default_factory=list) # placeholder for Merkle proofs
def record_delta(self, delta_id: str, outcome: str, details: Optional[Dict[str, Any]] = None) -> None:
self.deltas.append(DeltaRecord(delta_id=delta_id, outcome=outcome, details=details or {}))
def add_proof(self, proof: str) -> None:
self.proofs.append(proof)
def to_dict(self) -> Dict[str, Any]:
return {
"environment_version": self.environment_version,
"seed_space": self.seed_space,
"topology": self.topology,
"hardware_config": self.hardware_config,
"code_version_hash": self.code_version_hash,
"deltas": [d.to_dict() for d in self.deltas],
"proofs": self.proofs,
}
def __len__(self) -> int: # convenience
return len(self.deltas)
__all__ = ["ExperimentLedger"]