From 96db8ae1577b9af932b26be453fb75579712103a Mon Sep 17 00:00:00 2001 From: agent-dd492b85242a98c5 Date: Mon, 20 Apr 2026 14:30:41 +0200 Subject: [PATCH] build(agent): new-agents-3#dd492b iteration --- README.md | 1 + .../__init__.py | 2 +- .../contracts.py | 26 +++++++++++++++++++ .../tests/test_core.py | 26 +++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 80ae404..d7796aa 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ This MVP provides core contracts, a registry scaffold, two starter adapters, a M What’s included - Core data contracts: Signal, SignalDelta, ProvenanceProof, PrivacyBudget, AuditLog +- New primitives: AggregatedSignal and PlanDelta for cross-venue analytics and incremental plan updates - Graph-of-Contracts registry scaffold - Two starter adapters: ExchangeA and BrokerB - Merkle provenance module for verifiable signal anchoring diff --git a/mercurymesh_privacy_preserving_market_da/__init__.py b/mercurymesh_privacy_preserving_market_da/__init__.py index e1cb61f..9c3d483 100644 --- a/mercurymesh_privacy_preserving_market_da/__init__.py +++ b/mercurymesh_privacy_preserving_market_da/__init__.py @@ -6,7 +6,7 @@ It is intentionally small but feature-complete for MVP deployment and testing. """ -from .contracts import Signal, SignalDelta, ProvenanceProof, PrivacyBudget, AuditLog +from .contracts import Signal, SignalDelta, ProvenanceProof, PrivacyBudget, AuditLog, AggregatedSignal, PlanDelta from .registry import GraphOfContractsRegistry from .adapters import VenueAdapter, ExchangeVenueAdapterA, BrokerVenueAdapterB from .provenance import MerkleProvenance diff --git a/mercurymesh_privacy_preserving_market_da/contracts.py b/mercurymesh_privacy_preserving_market_da/contracts.py index 27b2678..c24e18b 100644 --- a/mercurymesh_privacy_preserving_market_da/contracts.py +++ b/mercurymesh_privacy_preserving_market_da/contracts.py @@ -60,3 +60,29 @@ class AuditLog: def to_json(self) -> str: return to_json(asdict(self)) + + +@dataclass +class AggregatedSignal: + """Cross-venue aggregated signal with privacy budgeting.""" + venue_set: List[str] + feature_vector: Dict[str, float] + privacy_budget_used: float + nonce: int = 0 + merkle_proof: List[str] = field(default_factory=list) + + def to_json(self) -> str: + return to_json(asdict(self)) + + +@dataclass +class PlanDelta: + """Incremental updates to analytics plans (e.g., reweighting, windows).""" + delta_id: str + venue: str + timestamp: int + delta: Dict[str, Any] + version: int = 1 + + def to_json(self) -> str: + return to_json(asdict(self)) diff --git a/mercurymesh_privacy_preserving_market_da/tests/test_core.py b/mercurymesh_privacy_preserving_market_da/tests/test_core.py index 00e9e96..f42f498 100644 --- a/mercurymesh_privacy_preserving_market_da/tests/test_core.py +++ b/mercurymesh_privacy_preserving_market_da/tests/test_core.py @@ -27,3 +27,29 @@ def test_merkle_provenance_root_basic(): s2 = Signal(venue="B", timestamp=2, metrics={"m": 2}, version=1) root = MerkleProvenance.merkle_root([s1, s2]) assert isinstance(root, str) and len(root) > 0 + + +def test_aggregated_signal_dataclass_json_roundtrip(): + from mercurymesh_privacy_preserving_market_da.contracts import AggregatedSignal + a = AggregatedSignal( + venue_set=["ExchangeA", "BrokerB"], + feature_vector={"liquidity_proxy": 0.42, "volatility_proxy": 0.15}, + privacy_budget_used=0.05, + nonce=7, + ) + # Ensure fields exist + assert isinstance(a.venue_set, list) + assert isinstance(a.feature_vector, dict) + assert a.privacy_budget_used == 0.05 + + +def test_plan_delta_dataclass_json_roundtrip(): + from mercurymesh_privacy_preserving_market_da.contracts import PlanDelta + d = PlanDelta( + delta_id="delta-001", + venue="ExchangeA", + timestamp=12345, + delta={"weight": 0.7}, + version=1, + ) + assert d.delta_id == "delta-001"