build(agent): semicolon#54de0b iteration

This commit is contained in:
agent-54de0bcc6a17828b 2026-04-24 18:57:12 +02:00
parent 6594b61e12
commit 012a70f60f
16 changed files with 521 additions and 85 deletions

View File

@ -2,11 +2,14 @@
Overview Overview
- BeVault is a modular backbone enforcing and proving Best Execution across multiple equity venues. - BeVault is a modular backbone enforcing and proving Best Execution across multiple equity venues.
- The MVP focuses on a Graph-of-Contracts (GoC) registry, two starter adapters, and deterministic delta-sync with signed deltas. - The current package includes a Graph-of-Contracts (GoC) registry, two starter adapters, a canonical IR bridge, a tamper-evident governance ledger, and deterministic delta-sync with signed deltas.
Tech Stack (Production-Ready) Tech Stack (Production-Ready)
- Language: Python 3.8+ - Language: Python 3.8+
- Core: lightweight dataclasses for LocalArbProblem, SharedSignals, HedgeDelta, AuditLog, PrivacyBudget - Core: lightweight dataclasses for LocalArbProblem, SharedSignals, HedgeDelta, AuditLog, PrivacyBudget
- Bridge: CanonicalIR and stable payload serialization for replay and signing
- Ledger: GovernanceLedger with hash chaining for auditability
- Replay: DeltaSyncEngine with version vectors and signed envelopes
- Registry: GoCRegistry and GraphOfContracts with versioned adapters - Registry: GoCRegistry and GraphOfContracts with versioned adapters
- Adapters: PriceFeedAdapter, BrokerAdapter (starter) - Adapters: PriceFeedAdapter, BrokerAdapter (starter)
- Crypto: HMAC-SHA256 based delta signing (pluggable key material) - Crypto: HMAC-SHA256 based delta signing (pluggable key material)
@ -16,7 +19,10 @@ Tech Stack (Production-Ready)
Project Structure Project Structure
- idea172_bevault_verifiable_best/ - idea172_bevault_verifiable_best/
- __init__.py - __init__.py
- bridge.py
- core.py - core.py
- ledger.py
- replay.py
- signing.py - signing.py
- registry.py - registry.py
- adapters/ - adapters/
@ -32,6 +38,6 @@ Project Structure
- READY_TO_PUBLISH (empty when ready) - READY_TO_PUBLISH (empty when ready)
How to contribute How to contribute
- Start with the MVP: wire two adapters and ensure delta-signing and delta-sync are deterministic. - Start by preserving determinism: keep signing, replay, and ledger hashes stable for identical inputs.
- Expand the GoC registry with new contracts/adapters following the toy DSL seeds. - Expand the GoC registry with new contracts/adapters following the toy DSL seeds.
- Ensure tests cover core contracts, registry operations, and adapter conformance checks. - Ensure tests cover core contracts, registry operations, and adapter conformance checks.

View File

@ -1 +1,32 @@
# BeVault: Verifiable Best-Execution Backbone (MVP) # BeVault: Verifiable Best-Execution Backbone
BeVault is a Python backbone for best-execution workflows across equity venues. It models local optimization problems, privacy-bounded market signals, signed hedge deltas, and tamper-evident governance logs in a small, testable package.
## What It Provides
- Canonical data contracts for `LocalArbProblem`, `SharedSignals`, `HedgeDelta`, `AuditLog`, and `PrivacyBudget`
- HMAC-SHA256 delta signing and verification
- A canonical IR bridge for replay and auditing
- A hash-chained governance ledger
- Deterministic delta-sync with version vectors
- A GoC registry plus starter price-feed and broker adapters
## Modules
- `core.py`: data contracts and toy DSL helpers
- `signing.py`: signing and verification
- `bridge.py`: canonical IR serialization
- `ledger.py`: append-only governance ledger
- `replay.py`: signed delta sync and replay
- `registry.py`: GoC registry and contract catalog
- `adapters/`: starter price-feed and broker adapters
## Verification
Run:
```bash
bash test.sh
```
This installs the package, runs pytest, and builds a source distribution and wheel with `python3 -m build`.

View File

@ -1,8 +1,12 @@
"""BeVault Verifiable Best-Execution Core (package init).""" """BeVault verifiable best-execution backbone."""
from .core import LocalArbProblem, SharedSignals, HedgeDelta, AuditLog, PrivacyBudget from .core import LocalArbProblem, SharedSignals, HedgeDelta, AuditLog, PrivacyBudget
from .bridge import CanonicalIR, canonical_payload, to_canonical_ir
from .ledger import GovernanceLedger
from .adapters import PriceFeedAdapter, BrokerAdapter
from .registry import GoCRegistry, GraphOfContracts from .registry import GoCRegistry, GraphOfContracts
from .signing import sign_delta from .replay import DeltaSyncEngine, SignedDeltaEnvelope, VersionVector
from .signing import sign_delta, verify_delta
__all__ = [ __all__ = [
"LocalArbProblem", "LocalArbProblem",
@ -10,7 +14,17 @@ __all__ = [
"HedgeDelta", "HedgeDelta",
"AuditLog", "AuditLog",
"PrivacyBudget", "PrivacyBudget",
"CanonicalIR",
"canonical_payload",
"to_canonical_ir",
"GovernanceLedger",
"PriceFeedAdapter",
"BrokerAdapter",
"GoCRegistry", "GoCRegistry",
"GraphOfContracts", "GraphOfContracts",
"DeltaSyncEngine",
"SignedDeltaEnvelope",
"VersionVector",
"sign_delta", "sign_delta",
"verify_delta",
] ]

View File

@ -1,4 +1,4 @@
"""Adapter base package for BeVault MVP (price feed, broker).""" """Adapter package for BeVault."""
from .price_feed import PriceFeedAdapter from .price_feed import PriceFeedAdapter
from .broker import BrokerAdapter from .broker import BrokerAdapter

View File

@ -1,6 +1,8 @@
"""Starter BrokerAdapter for BeVault MVP.""" """Broker adapter for BeVault."""
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass
from dataclasses import dataclass, field
from typing import List
from ..core import HedgeDelta from ..core import HedgeDelta
@ -8,12 +10,19 @@ from ..core import HedgeDelta
@dataclass @dataclass
class BrokerAdapter: class BrokerAdapter:
name: str = "broker-v1" name: str = "broker-v1"
version: str = "0.1" version: str = "1.0"
sent_deltas: List[HedgeDelta] = field(default_factory=list)
def send_delta(self, delta: HedgeDelta) -> bool: def send_delta(self, delta: HedgeDelta) -> bool:
# Placeholder: in real life this would push to venue/execution system self.sent_deltas.append(delta)
# Here we simply return True to indicate success
return True return True
def conformance_contract(self) -> dict:
return {
"name": self.name,
"version": self.version,
"accepts": ["HedgeDelta"],
}
__all__ = ["BrokerAdapter"] __all__ = ["BrokerAdapter"]

View File

@ -1,19 +1,45 @@
"""Starter PriceFeedAdapter for BeVault MVP.""" """Price feed adapter for BeVault."""
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass
from ..core import HedgeDelta import hashlib
from dataclasses import dataclass
from typing import Optional
from ..bridge import canonical_payload, to_canonical_ir
from ..core import HedgeDelta, LocalArbProblem, SharedSignals
@dataclass @dataclass
class PriceFeedAdapter: class PriceFeedAdapter:
name: str = "price-feed-v1" name: str = "price-feed-v1"
version: str = "0.1" version: str = "1.0"
def generate_signal(self, asset: str, price: float, latency_ms: float) -> HedgeDelta: def generate_signal(self, asset: str, price: float, latency_ms: float) -> SharedSignals:
# Produce a minimal HedgeDelta as a placeholder signal payload return SharedSignals(asset=asset, price=price, latency_ms=latency_ms)
# In a real system this would produce SharedSignals -> local arb -> delta
return HedgeDelta(asset=asset, hedge_size=price, timestamp=latency_ms, policy_tag="price-feed") def build_delta(
self,
local: LocalArbProblem,
signals: SharedSignals,
hedge_size: Optional[float] = None,
) -> HedgeDelta:
hedge_size = signals.price if hedge_size is None else hedge_size
ir = to_canonical_ir(local, signals)
audit_ref = hashlib.sha256(canonical_payload(ir).encode("utf-8")).hexdigest()
return HedgeDelta(
asset=local.asset,
hedge_size=hedge_size,
timestamp=signals.timestamp,
policy_tag="price-feed",
audit_ref=audit_ref,
)
def conformance_contract(self) -> dict:
return {
"name": self.name,
"version": self.version,
"produces": ["SharedSignals", "HedgeDelta"],
}
__all__ = ["PriceFeedAdapter"] __all__ = ["PriceFeedAdapter"]

View File

@ -1,4 +1,4 @@
"""Bridge: EnergiBridge-inspired IR mapper for BeVault MVP. """Bridge: canonical IR mapper for BeVault.
This module introduces a minimal, canonical representation mapping BeVault This module introduces a minimal, canonical representation mapping BeVault
primitives into a single, serializable IR (Objects/Morphisms/PlanDelta). primitives into a single, serializable IR (Objects/Morphisms/PlanDelta).
@ -9,9 +9,9 @@ interactions and deterministic backtests later in the MVP.
from __future__ import annotations from __future__ import annotations
from dataclasses import asdict, dataclass from dataclasses import asdict, dataclass
from typing import Optional from typing import Any, Dict, Optional
from .core import HedgeDelta, LocalArbProblem, SharedSignals from .core import AuditLog, HedgeDelta, LocalArbProblem, PrivacyBudget, SharedSignals
@dataclass @dataclass
@ -23,9 +23,11 @@ class CanonicalIR:
""" """
version: str version: str
objects: dict objects: Dict[str, Any]
morphisms: dict morphisms: Dict[str, Any]
plan_delta: Optional[dict] = None plan_delta: Optional[Dict[str, Any]] = None
audit_log: Optional[Dict[str, Any]] = None
privacy_budget: Optional[Dict[str, Any]] = None
def to_dict(self) -> dict: def to_dict(self) -> dict:
return { return {
@ -33,10 +35,18 @@ class CanonicalIR:
"objects": self.objects, "objects": self.objects,
"morphisms": self.morphisms, "morphisms": self.morphisms,
"plan_delta": self.plan_delta, "plan_delta": self.plan_delta,
"audit_log": self.audit_log,
"privacy_budget": self.privacy_budget,
} }
def to_canonical_ir(local: LocalArbProblem, signals: SharedSignals, delta: Optional[HedgeDelta] = None) -> CanonicalIR: def to_canonical_ir(
local: LocalArbProblem,
signals: SharedSignals,
delta: Optional[HedgeDelta] = None,
audit_log: Optional[AuditLog] = None,
privacy_budget: Optional[PrivacyBudget] = None,
) -> CanonicalIR:
"""Map BeVault MVP primitives to a CanonicalIR structure. """Map BeVault MVP primitives to a CanonicalIR structure.
This function provides a tiny, deterministic bridge from the MVP domain This function provides a tiny, deterministic bridge from the MVP domain
@ -50,8 +60,17 @@ def to_canonical_ir(local: LocalArbProblem, signals: SharedSignals, delta: Optio
"SharedSignals": asdict_safe(signals), "SharedSignals": asdict_safe(signals),
} }
plan_delta = asdict_safe(delta) if delta is not None else None plan_delta = asdict_safe(delta) if delta is not None else None
audit_payload = asdict_safe(audit_log) if audit_log is not None else None
privacy_payload = asdict_safe(privacy_budget) if privacy_budget is not None else None
return CanonicalIR(version="0.1", objects=objects, morphisms=morphisms, plan_delta=plan_delta) return CanonicalIR(
version="1.0",
objects=objects,
morphisms=morphisms,
plan_delta=plan_delta,
audit_log=audit_payload,
privacy_budget=privacy_payload,
)
def asdict_safe(obj) -> dict: def asdict_safe(obj) -> dict:
@ -66,4 +85,12 @@ def asdict_safe(obj) -> dict:
return {"value": obj} return {"value": obj}
__all__ = ["CanonicalIR", "to_canonical_ir"] def canonical_payload(ir: CanonicalIR) -> str:
"""Serialize a CanonicalIR in a stable form for signing and replay."""
import json
return json.dumps(ir.to_dict(), sort_keys=True, separators=(",", ":"))
__all__ = ["CanonicalIR", "to_canonical_ir", "canonical_payload"]

View File

@ -1,8 +1,10 @@
"""Core data contracts for BeVault MVP (toy DSL seeds).""" """Core data contracts for BeVault."""
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass, field
from typing import List, Optional import json
import time import time
from dataclasses import asdict, dataclass, field
from typing import Any, Dict, List, Optional
@dataclass @dataclass
@ -10,7 +12,16 @@ class LocalArbProblem:
asset: str asset: str
objective: str # e.g., 'min_cost', 'maximize_profit' objective: str # e.g., 'min_cost', 'maximize_profit'
risk_budget: float risk_budget: float
constraints: dict = field(default_factory=dict) constraints: Dict[str, Any] = field(default_factory=dict)
def validate(self) -> None:
if not self.asset:
raise ValueError("asset is required")
if self.risk_budget < 0:
raise ValueError("risk_budget must be non-negative")
def to_dict(self) -> Dict[str, Any]:
return asdict(self)
@dataclass @dataclass
@ -19,7 +30,14 @@ class SharedSignals:
price: float price: float
latency_ms: float latency_ms: float
timestamp: float = field(default_factory=lambda: time.time()) timestamp: float = field(default_factory=lambda: time.time())
metadata: dict = field(default_factory=dict) metadata: Dict[str, Any] = field(default_factory=dict)
def to_dict(self) -> Dict[str, Any]:
return asdict(self)
def is_fresh(self, max_age_seconds: float, now: Optional[float] = None) -> bool:
now = time.time() if now is None else now
return (now - self.timestamp) <= max_age_seconds
@dataclass @dataclass
@ -29,13 +47,37 @@ class HedgeDelta:
timestamp: float = field(default_factory=lambda: time.time()) timestamp: float = field(default_factory=lambda: time.time())
policy_tag: str = "default" policy_tag: str = "default"
signature: Optional[str] = None signature: Optional[str] = None
version_vector: Dict[str, int] = field(default_factory=dict)
audit_ref: Optional[str] = None
def to_signable_dict(self) -> Dict[str, Any]:
return {
"asset": self.asset,
"hedge_size": self.hedge_size,
"timestamp": self.timestamp,
"policy_tag": self.policy_tag,
"version_vector": self.version_vector,
"audit_ref": self.audit_ref,
}
def to_json(self) -> str:
return json.dumps(self.to_signable_dict(), sort_keys=True, separators=(",", ":"))
@dataclass @dataclass
class AuditLog: class AuditLog:
events: List[str] = field(default_factory=list) events: List[Dict[str, Any]] = field(default_factory=list)
entry_ts: float = field(default_factory=lambda: time.time()) entry_ts: float = field(default_factory=lambda: time.time())
def record(self, event_type: str, payload: Optional[Dict[str, Any]] = None) -> None:
self.events.append(
{
"event_type": event_type,
"payload": payload or {},
"timestamp": time.time(),
}
)
@dataclass @dataclass
class PrivacyBudget: class PrivacyBudget:
@ -43,6 +85,14 @@ class PrivacyBudget:
remaining: float remaining: float
reset_epoch: float = field(default_factory=lambda: time.time()) reset_epoch: float = field(default_factory=lambda: time.time())
def consume(self, amount: float) -> bool:
if amount < 0:
raise ValueError("amount must be non-negative")
if amount > self.remaining:
return False
self.remaining -= amount
return True
__all__ = [ __all__ = [
"LocalArbProblem", "LocalArbProblem",
@ -65,8 +115,6 @@ def generate_toy_seed(asset: str = "AAPL", price: float = 100.0):
This helper is intentionally lightweight and is meant for local testing This helper is intentionally lightweight and is meant for local testing
and documentation purposes within the MVP boundaries. and documentation purposes within the MVP boundaries.
""" """
from time import time
local = LocalArbProblem( local = LocalArbProblem(
asset=asset, asset=asset,
objective="min_cost", objective="min_cost",
@ -78,7 +126,7 @@ def generate_toy_seed(asset: str = "AAPL", price: float = 100.0):
asset=asset, asset=asset,
price=price, price=price,
latency_ms=0.5, latency_ms=0.5,
timestamp=time(), timestamp=time.time(),
metadata={"toy_seed": True}, metadata={"toy_seed": True},
) )

View File

@ -0,0 +1,87 @@
"""Append-only governance ledger for BeVault."""
from __future__ import annotations
import hashlib
import json
import time
from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional
def _stable_hash(payload: Dict[str, Any]) -> str:
encoded = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
return hashlib.sha256(encoded).hexdigest()
@dataclass
class LedgerEntry:
index: int
event_type: str
payload: Dict[str, Any]
timestamp: float
previous_hash: str
entry_hash: str
@dataclass
class GovernanceLedger:
"""Tamper-evident event ledger with hash chaining."""
entries: List[LedgerEntry] = field(default_factory=list)
def append(self, event_type: str, payload: Optional[Dict[str, Any]] = None, timestamp: Optional[float] = None) -> LedgerEntry:
timestamp = time.time() if timestamp is None else timestamp
payload = payload or {}
previous_hash = self.entries[-1].entry_hash if self.entries else ""
entry = LedgerEntry(
index=len(self.entries),
event_type=event_type,
payload=payload,
timestamp=timestamp,
previous_hash=previous_hash,
entry_hash="",
)
entry.entry_hash = _stable_hash(
{
"index": entry.index,
"event_type": entry.event_type,
"payload": entry.payload,
"timestamp": entry.timestamp,
"previous_hash": entry.previous_hash,
}
)
self.entries.append(entry)
return entry
def verify(self) -> bool:
previous_hash = ""
for index, entry in enumerate(self.entries):
if entry.index != index:
return False
if entry.previous_hash != previous_hash:
return False
expected_hash = _stable_hash(
{
"index": entry.index,
"event_type": entry.event_type,
"payload": entry.payload,
"timestamp": entry.timestamp,
"previous_hash": entry.previous_hash,
}
)
if entry.entry_hash != expected_hash:
return False
previous_hash = entry.entry_hash
return True
def anchor(self) -> str:
return self.entries[-1].entry_hash if self.entries else ""
def to_dict(self) -> Dict[str, Any]:
return {
"entries": [entry.__dict__ for entry in self.entries],
"anchor": self.anchor(),
}
__all__ = ["GovernanceLedger", "LedgerEntry"]

View File

@ -1,21 +1,19 @@
"""Graph-of-Contracts (GoC) registry and minimal adapters registry. """Graph-of-Contracts (GoC) registry."""
This is a lightweight, production-oriented scaffold for the MVP.
"""
from __future__ import annotations from __future__ import annotations
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Dict, Optional from typing import Any, Dict, List, Optional
from .core import HedgeDelta
# Import adapters to ensure their classes are discoverable when registry loads
from .adapters.price_feed import PriceFeedAdapter
from .adapters.broker import BrokerAdapter from .adapters.broker import BrokerAdapter
from .adapters.price_feed import PriceFeedAdapter
from .core import HedgeDelta
@dataclass @dataclass
class GoCRegistry: class GoCRegistry:
"""Registry for adapters and data contracts (toy GoC).""" """Registry for adapters and data contracts."""
adapters: Dict[str, object] = field(default_factory=dict) adapters: Dict[str, object] = field(default_factory=dict)
contracts: Dict[str, str] = field(default_factory=dict)
metadata: Dict[str, Any] = field(default_factory=dict)
def __post_init__(self): def __post_init__(self):
# Initialize to an empty mapping if not provided # Initialize to an empty mapping if not provided
@ -28,20 +26,49 @@ class GoCRegistry:
def get_adapter(self, name: str) -> Optional[object]: def get_adapter(self, name: str) -> Optional[object]:
return self.adapters.get(name) return self.adapters.get(name)
class GraphOfContracts:
"""Lightweight catalog for contract versions and replay metadata."""
def __init__(self) -> None:
self.contracts: Dict[str, str] = {}
def register_contract(self, name: str, version: str) -> None: def register_contract(self, name: str, version: str) -> None:
self.contracts[name] = version self.contracts[name] = version
def get_contract(self, name: str) -> Optional[str]: def get_contract(self, name: str) -> Optional[str]:
return self.contracts.get(name) return self.contracts.get(name)
def conformance_report(self, adapter_name: str) -> Dict[str, Any]:
adapter = self.get_adapter(adapter_name)
if adapter is None:
return {"adapter": adapter_name, "registered": False, "conforms": False}
required_methods: List[str] = []
if isinstance(adapter, PriceFeedAdapter):
required_methods = ["generate_signal", "conformance_contract"]
elif isinstance(adapter, BrokerAdapter):
required_methods = ["send_delta", "conformance_contract"]
missing = [method for method in required_methods if not hasattr(adapter, method)]
return {
"adapter": adapter_name,
"registered": True,
"conforms": not missing,
"missing": missing,
"contract": getattr(adapter, "conformance_contract", lambda: None)(),
}
class GraphOfContracts:
"""Catalog for contract versions and replay metadata."""
def __init__(self) -> None:
self.contracts: Dict[str, Dict[str, Any]] = {}
def register_contract(self, name: str, version: str, schema: Optional[Dict[str, Any]] = None) -> None:
self.contracts[name] = {"version": version, "schema": schema or {}}
def get_contract(self, name: str) -> Optional[Dict[str, Any]]:
return self.contracts.get(name)
def list_contracts(self): def list_contracts(self):
return list(self.contracts.items()) return list(self.contracts.items())
def to_dict(self) -> Dict[str, Dict[str, Any]]:
return dict(self.contracts)
__all__ = ["GoCRegistry", "GraphOfContracts"] __all__ = ["GoCRegistry", "GraphOfContracts"]

View File

@ -0,0 +1,83 @@
"""Deterministic delta-sync and offline replay utilities."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, Dict, Iterable, List, Optional, Tuple
from .core import HedgeDelta
from .signing import sign_delta, verify_delta
@dataclass
class VersionVector:
clocks: Dict[str, int] = field(default_factory=dict)
def bump(self, actor: str) -> None:
self.clocks[actor] = self.clocks.get(actor, 0) + 1
def merge(self, other: "VersionVector") -> None:
for actor, counter in other.clocks.items():
self.clocks[actor] = max(self.clocks.get(actor, 0), counter)
def copy(self) -> "VersionVector":
return VersionVector(clocks=dict(self.clocks))
def to_dict(self) -> Dict[str, int]:
return dict(self.clocks)
@dataclass
class SignedDeltaEnvelope:
delta: HedgeDelta
actor: str
signature: str
version_vector: VersionVector
def to_dict(self) -> Dict[str, Any]:
return {
"delta": self.delta.to_signable_dict(),
"actor": self.actor,
"signature": self.signature,
"version_vector": self.version_vector.to_dict(),
}
class DeltaSyncEngine:
"""Records and replays signed deltas deterministically."""
def __init__(self, signing_key: bytes) -> None:
self.signing_key = signing_key
self.version_vector = VersionVector()
self.envelopes: List[SignedDeltaEnvelope] = []
def record(self, delta: HedgeDelta, actor: str) -> SignedDeltaEnvelope:
self.version_vector.bump(actor)
delta.version_vector = self.version_vector.to_dict()
delta.signature = sign_delta(delta, self.signing_key)
envelope = SignedDeltaEnvelope(delta=delta, actor=actor, signature=delta.signature, version_vector=self.version_vector.copy())
self.envelopes.append(envelope)
return envelope
def ingest(self, envelope: SignedDeltaEnvelope) -> bool:
if not verify_delta(envelope.delta, self.signing_key, envelope.signature):
return False
self.version_vector.merge(envelope.version_vector)
self.envelopes.append(envelope)
return True
def replay(self) -> List[HedgeDelta]:
ordered = sorted(
self.envelopes,
key=lambda item: (
item.delta.timestamp,
item.actor,
item.signature,
),
)
return [envelope.delta for envelope in ordered]
def history(self) -> List[Dict[str, Any]]:
return [envelope.to_dict() for envelope in self.envelopes]
__all__ = ["DeltaSyncEngine", "SignedDeltaEnvelope", "VersionVector"]

View File

@ -1,18 +1,24 @@
"""Delta signing utilities for BeVault MVP.""" """Delta signing utilities for BeVault."""
from __future__ import annotations from __future__ import annotations
import hmac
import hashlib import hashlib
import hmac
import json
from .core import HedgeDelta from .core import HedgeDelta
def sign_delta(delta: HedgeDelta, key: bytes) -> str: def sign_delta(delta: HedgeDelta, key: bytes) -> str:
"""Sign a HedgeDelta deterministically using HMAC-SHA256. """Sign a HedgeDelta deterministically using HMAC-SHA256."""
The signature is derived from the delta contents (asset, hedge_size, timestamp, policy_tag). payload = json.dumps(delta.to_signable_dict(), sort_keys=True, separators=(",", ":"))
The resulting hex digest is stable for identical inputs and keys.
"""
payload = f"{delta.asset}:{delta.hedge_size}:{delta.timestamp}:{delta.policy_tag}"
return hmac.new(key, payload.encode("utf-8"), hashlib.sha256).hexdigest() return hmac.new(key, payload.encode("utf-8"), hashlib.sha256).hexdigest()
__all__ = ["sign_delta"] def verify_delta(delta: HedgeDelta, key: bytes, signature: str) -> bool:
"""Verify a delta signature in a deterministic way."""
return hmac.compare_digest(sign_delta(delta, key), signature)
__all__ = ["sign_delta", "verify_delta"]

View File

@ -8,7 +8,7 @@ version = "0.1.0"
description = "BeVault: verifiable best-execution backbone prototype with Cross-Venue GoC adapters" description = "BeVault: verifiable best-execution backbone prototype with Cross-Venue GoC adapters"
readme = "README.md" readme = "README.md"
requires-python = ">=3.8" requires-python = ">=3.8"
license = {text = "MIT"} license = "MIT"
authors = [ { name = "OpenCode Team" } ] authors = [ { name = "OpenCode Team" } ]
[tool.setuptools.packages.find] [tool.setuptools.packages.find]

View File

@ -4,7 +4,7 @@ set -euo pipefail
echo "[BeVault] Running tests and packaging sanity checks..." echo "[BeVault] Running tests and packaging sanity checks..."
# Ensure pip tooling is up to date # Ensure pip tooling is up to date
python3 -m pip install --upgrade pip setuptools wheel python3 -m pip install --upgrade pip setuptools wheel build
# Install the package in editable mode for testing imports # Install the package in editable mode for testing imports
python3 -m pip install -e . python3 -m pip install -e .

View File

@ -1,23 +0,0 @@
"""Basic tests for BeVault MVP components."""
import pytest
from idea172_bevault_verifiable_best.core import HedgeDelta
from idea172_bevault_verifiable_best.signing import sign_delta
from idea172_bevault_verifiable_best.registry import GoCRegistry
from idea172_bevault_verifiable_best.adapters.price_feed import PriceFeedAdapter
def test_sign_delta_deterministic():
delta = HedgeDelta(asset="AAPL", hedge_size=1.0, timestamp=1.0, policy_tag="test")
key = b"secret-key"
sig1 = sign_delta(delta, key)
sig2 = sign_delta(delta, key)
assert isinstance(sig1, str) and isinstance(sig2, str)
assert sig1 == sig2
def test_registry_adapters_can_register_and_retrieve():
reg = GoCRegistry()
adapter = PriceFeedAdapter()
reg.register_adapter(adapter)
assert reg.get_adapter(adapter.name) is adapter

95
tests/test_bevault.py Normal file
View File

@ -0,0 +1,95 @@
"""Tests for BeVault core behavior."""
from idea172_bevault_verifiable_best import (
AuditLog,
DeltaSyncEngine,
GovernanceLedger,
GoCRegistry,
HedgeDelta,
LocalArbProblem,
PrivacyBudget,
PriceFeedAdapter,
BrokerAdapter,
SharedSignals,
canonical_payload,
sign_delta,
to_canonical_ir,
verify_delta,
)
def test_sign_and_verify_delta_deterministically():
delta = HedgeDelta(asset="AAPL", hedge_size=1.0, timestamp=1.0, policy_tag="test")
key = b"secret-key"
sig1 = sign_delta(delta, key)
sig2 = sign_delta(delta, key)
assert sig1 == sig2
assert verify_delta(delta, key, sig1)
def test_registry_reports_adapter_conformance():
reg = GoCRegistry()
price = PriceFeedAdapter()
broker = BrokerAdapter()
reg.register_adapter(price)
reg.register_adapter(broker)
reg.register_contract("LocalArbProblem", "1.0")
report = reg.conformance_report(price.name)
assert report["conforms"] is True
assert report["registered"] is True
assert reg.get_adapter(broker.name) is broker
assert reg.get_contract("LocalArbProblem") == "1.0"
def test_canonical_ir_includes_governance_metadata():
local = LocalArbProblem(asset="MSFT", objective="min_cost", risk_budget=10.0)
signals = SharedSignals(asset="MSFT", price=250.0, latency_ms=2.0, timestamp=1.0)
audit = AuditLog()
audit.record("approve", {"desk": "equities"})
budget = PrivacyBudget(asset="MSFT", remaining=5.0)
ir = to_canonical_ir(local, signals, audit_log=audit, privacy_budget=budget)
payload = canonical_payload(ir)
assert ir.version == "1.0"
assert "audit_log" in payload
assert "privacy_budget" in payload
def test_governance_ledger_hash_chain_verifies():
ledger = GovernanceLedger()
first = ledger.append("approve", {"ticket": "abc"}, timestamp=1.0)
second = ledger.append("execute", {"ticket": "abc"}, timestamp=2.0)
assert ledger.verify() is True
assert ledger.anchor() == second.entry_hash
assert first.previous_hash == ""
ledger.entries[0].payload["ticket"] = "mutated"
assert ledger.verify() is False
def test_delta_sync_replays_deterministically():
engine = DeltaSyncEngine(signing_key=b"sync-key")
delta_one = HedgeDelta(asset="AAPL", hedge_size=1.0, timestamp=1.0, policy_tag="a")
delta_two = HedgeDelta(asset="AAPL", hedge_size=2.0, timestamp=0.5, policy_tag="b")
engine.record(delta_one, actor="desk-a")
engine.record(delta_two, actor="desk-b")
replayed = engine.replay()
assert [delta.policy_tag for delta in replayed] == ["b", "a"]
assert replayed[0].signature is not None
def test_price_feed_builds_delta_and_broker_sends_it():
adapter = PriceFeedAdapter()
local = LocalArbProblem(asset="AAPL", objective="min_cost", risk_budget=10.0)
signals = adapter.generate_signal(asset="AAPL", price=101.5, latency_ms=1.2)
delta = adapter.build_delta(local, signals)
broker = BrokerAdapter()
assert broker.send_delta(delta) is True
assert broker.sent_deltas[-1] is delta
assert delta.audit_ref is not None