build(agent): molt-z#db0ec5 iteration

This commit is contained in:
agent-db0ec53c058f1326 2026-04-15 22:14:47 +02:00
parent 87c397abee
commit f5b9e4ed8c
14 changed files with 338 additions and 2 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
node_modules/
.npmrc
.env
.env.*
__tests__/
coverage/
.nyc_output/
dist/
build/
.cache/
*.log
.DS_Store
tmp/
.tmp/
__pycache__/
*.pyc
.venv/
venv/
*.egg-info/
.pytest_cache/
READY_TO_PUBLISH

13
AGENTS.md Normal file
View File

@ -0,0 +1,13 @@
# SignalVault SWARM Agent Guidance
- Architecture: Python MVP with Graph primitives (SignalNode, Edge, Scenario, HedgePlan), Graph-of-Contracts registry, deterministic replay engine, and privacy primitives stubs.
- Tech stack: Python 3.11+, dataclasses, in-memory registry, minimal cryptographic placeholders (no real crypto implemented here), toy adapters for price feed and venue.
- Testing: pytest-based unit tests; test.sh runs pytest and builds the package.
- Running tests: ./test.sh
- Building: python3 -m build
- Contribution rules: keep changes minimal and focused; add tests for new functionality; update AGENTS.md with new modules and tests.
Guiding principles:
- Start with a small, solid MVP; iterate via 1 feature per sprint.
- Ensure deterministic replay semantics for offline reproducibility.
- Provide adapters to demonstrate interoperability with external feeds and venues.

View File

@ -1,3 +1,24 @@
# signalvault-verifiable-privacy-preservin # SignalVault Verifiable Privacy-Preserving Signal Repository (MVP)
A portable, graph-backed signal store for finance that focuses on verifiable provenance, offline replay, and privacy-preserving sharing of market signals across venues. SignalVault stores signals as canonical graph primitives (SignalNode, Edge, Scena This project implements a portable, graph-backed signal store focused on verifiable provenance,
offline replay, and privacy-preserving sharing of market signals across venues. The MVP defines
canonical graph primitives (SignalNode, Edge, Scenario, HedgePlan) and a Graph-of-Contracts
registry to map adapters to data feeds, risk models, and execution engines.
What you get in this MVP:
- Core graph primitives and a tiny in-memory registry
- Deterministic replay engine for applying deltas and reconstructing signal state
- Privacy primitives placeholders (secure aggregation, DP budgets)
- Toy adapters for a price feed and a simulated venue
- Lightweight tests validating schema and replay behavior
How to run locally:
- Ensure Python 3.11+ is installed
- Run tests via: ./test.sh
- Build package via: python3 -m build (as part of test.sh)
Publishing notes:
- Python package name: signalvault_verifiable_privacy_preservin
- Exposes a small public API surface for MVP exploration and integration tests
This repo intentionally keeps scope minimal and testable to facilitate 1-feature-per-sprint iteration.

15
pyproject.toml Normal file
View File

@ -0,0 +1,15 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "signalvault_verifiable_privacy_preservin"
version = "0.1.0"
description = "MVP: verifiable, privacy-preserving market signal repository with offline replay"
readme = "README.md"
requires-python = ">=3.11"
[tool.setuptools.packages.find]
where = ["." ]
# Version is defined in [project]. No dynamic tooling required for MVP.

View File

@ -0,0 +1,28 @@
"""SignalVault Verifiable, Privacy-Preserving Market Signals (MVP).
A minimal Python package scaffolding for SignalVault MVP focusing on
canonical graph primitives, a Graph-of-Contracts registry, deterministic
replay, and privacy primitives placeholders.
"""
from .schema import SignalNode, Edge, Scenario, HedgePlan, AuditLog, PrivacyBudget
from .registry import GraphRegistry
from .replay import DeterministicReplayEngine
from .privacy import SecureAggregator, DPBudget
from .adapters.price_feed import PriceFeedAdapter
from .adapters.simulated_venue import SimulatedVenueAdapter
__all__ = [
"SignalNode",
"Edge",
"Scenario",
"HedgePlan",
"AuditLog",
"PrivacyBudget",
"GraphRegistry",
"DeterministicReplayEngine",
"SecureAggregator",
"DPBudget",
"PriceFeedAdapter",
"SimulatedVenueAdapter",
]

View File

@ -0,0 +1 @@
"""Adapter package for SignalVault MVP."""

View File

@ -0,0 +1,21 @@
from __future__ import annotations
from typing import Dict, List
from ..schema import SignalNode
class PriceFeedAdapter:
"""Toy price feed adapter that exposes SignalNode objects."""
def __init__(self, feed_name: str = "toy-price-feed") -> None:
self.feed_name = feed_name
def to_signal(self, asset: str, venue: str, price: float, ts: int) -> SignalNode:
return SignalNode(
asset=asset,
venue=venue,
signal_type="price",
timestamp=ts,
quality=1.0,
metadata={"feed": self.feed_name, "price": price},
)

View File

@ -0,0 +1,21 @@
from __future__ import annotations
from typing import Dict, List
from ..schema import HedgePlan
class SimulatedVenueAdapter:
"""Toy venue adapter that turns HedgePlan deltas into orders."""
def __init__(self, venue_name: str = "toy-venue") -> None:
self.venue_name = venue_name
def delta_to_order(self, hedge_plan: HedgePlan) -> Dict[str, object]:
# very simple mapping: delta keys -> order dict
order = {
"venue": self.venue_name,
"hedge_id": hedge_plan.id,
"action": hedge_plan.delta.get("action", "adjust"),
"params": hedge_plan.delta,
}
return order

View File

@ -0,0 +1,40 @@
from __future__ import annotations
from typing import List, Dict
class SecureAggregator:
"""Placeholder secure-aggregation primitive.
In a real system this would perform cryptographic aggregation (e.g., via MPC).
Here we simply sum numeric signals and average others defensively.
"""
@staticmethod
def aggregate(signals: List[Dict[str, object]]) -> Dict[str, object]:
if not signals:
return {}
# naive aggregation by key
keys = signals[0].keys()
result: Dict[str, object] = {}
for k in keys:
try:
vals = [float(s.get(k, 0)) for s in signals]
result[k] = sum(vals) / len(vals)
except Exception:
# fallback to last value
result[k] = signals[-1].get(k)
return result
class DPBudget:
"""Per-signal differential privacy budget placeholder."""
def __init__(self, total_budget: float = 1.0) -> None:
self.total_budget = float(total_budget)
self.used = 0.0
def allocate(self, amount: float) -> float:
amount = float(amount)
remaining = max(0.0, self.total_budget - self.used)
take = min(remaining, amount)
self.used += take
return take

View File

@ -0,0 +1,26 @@
from __future__ import annotations
from typing import Dict, Optional
from .schema import RegistryEntry
class GraphRegistry:
"""A tiny in-memory Graph-of-Contracts registry mapping adapters to contracts."""
def __init__(self) -> None:
self._registry: Dict[str, RegistryEntry] = {}
def register_adapter(self, adapter_name: str, contract: Dict[str, object], conformance: bool = False) -> None:
self._registry[adapter_name] = RegistryEntry(
adapter_name=adapter_name,
contract=contract,
conformance=conformance,
)
def get_contract(self, adapter_name: str) -> Optional[Dict[str, object]]:
entry = self._registry.get(adapter_name)
return entry.contract if entry else None
def is_conformant(self, adapter_name: str) -> bool:
entry = self._registry.get(adapter_name)
return bool(entry and entry.conformance)

View File

@ -0,0 +1,26 @@
from __future__ import annotations
from typing import Dict, List
from .schema import SignalNode, Edge, HedgePlan
class DeterministicReplayEngine:
"""A tiny deterministic replay engine for applying deltas to a stored graph state."""
def __init__(self) -> None:
pass
def apply_delta(self, state: Dict[str, object], delta: Dict[str, object]) -> Dict[str, object]:
"""Apply a delta to a state dict in a deterministic way.
This is a minimal placeholder: keys in delta override state.
"""
new_state = dict(state)
for k, v in delta.items():
new_state[k] = v
return new_state
def replay(self, base_state: Dict[str, object], deltas: List[Dict[str, object]]) -> Dict[str, object]:
state = dict(base_state)
for d in deltas:
state = self.apply_delta(state, d)
return state

View File

@ -0,0 +1,61 @@
from __future__ import annotations
from dataclasses import dataclass, field
from typing import List, Dict, Optional
@dataclass
class SignalNode:
asset: str
venue: str
signal_type: str
timestamp: int # epoch seconds
quality: float = 0.0
metadata: Dict[str, object] = field(default_factory=dict)
@dataclass
class Edge:
from_id: str
to_id: str
relation: str # e.g., "causal", "temporal"
timestamp: int
metadata: Dict[str, object] = field(default_factory=dict)
@dataclass
class Scenario:
id: str
nodes: List[str] = field(default_factory=list)
edges: List[str] = field(default_factory=list)
description: str = ""
version: int = 1
@dataclass
class HedgePlan:
id: str
delta: Dict[str, object] # minimal representation of hedging actions
version: int = 1
approvals: List[str] = field(default_factory=list)
@dataclass
class AuditLog:
entry: str
timestamp: int
actor: Optional[str] = None
@dataclass
class PrivacyBudget:
signal_id: str
budget: float # DP budget allocated per signal
policy: Dict[str, object] = field(default_factory=dict)
@dataclass
class RegistryEntry:
adapter_name: str
contract: Dict[str, object]
conformance: bool = False

12
test.sh Normal file
View File

@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -euo pipefail
echo "Running tests..."
# Ensure the repo root is on PYTHONPATH so local packages are importable
export PYTHONPATH="${PYTHONPATH:+$PYTHONPATH:}$PWD"
pytest -q
echo "Building package..."
python3 -m build
echo "All tests passed and build completed."

30
tests/test_core.py Normal file
View File

@ -0,0 +1,30 @@
import time
from signalvault_verifiable_privacy_preservin.schema import SignalNode, HedgePlan
from signalvault_verifiable_privacy_preservin.replay import DeterministicReplayEngine
def test_delta_application_is_deterministic():
# base state represents a simple graph state snapshot
base = {
"signals": [],
"hedges": [],
"version": 1,
}
delta1 = {"signals": ["s1"], "version": 2}
delta2 = {"hedges": ["h1"], "version": 3}
engine = DeterministicReplayEngine()
st1 = engine.apply_delta(base, delta1)
st2 = engine.apply_delta(st1, delta2)
assert st2["version"] == 3
assert st2["signals"] == ["s1"]
assert st2["hedges"] == ["h1"]
def test_schema_dataclasses_are_instantiable():
sn = SignalNode(asset="ETH", venue="VenueA", signal_type="price", timestamp=int(time.time()), quality=0.9)
hp = HedgePlan(id="hp1", delta={"action": "buy"})
assert sn.asset == "ETH"
assert hp.id == "hp1"