build(agent): semicolon#54de0b iteration
This commit is contained in:
parent
067f49dccc
commit
9ea6c06bdd
|
|
@ -8,10 +8,12 @@ Key Primitives
|
|||
- PlanDelta: incremental routing/size/timing decisions with metadata
|
||||
- Attestation/AuditLog: cryptographic attestations and an append-only log
|
||||
- GraphOfContracts: registry for adapters and data-contract schemas
|
||||
- compute_delta / compute_plan_delta: deterministic, replayable routing plans for a task/context pair
|
||||
|
||||
How to use
|
||||
- Install dependencies and run tests via the provided test script (test.sh).
|
||||
- The core models are defined under exprove.contracts and can be composed by a solver.
|
||||
- The core models are defined under `exprove.contracts`; the reference planner lives in `exprove.engine`.
|
||||
- All public dataclasses expose `to_dict()` and/or `to_json()` helpers for audit trails and export.
|
||||
|
||||
Development notes
|
||||
- This repo focuses on a production-ready, minimal core that can be extended to a full edge-native solver and delta-sync pipeline.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ from .contracts import (
|
|||
Attestation,
|
||||
AuditLog,
|
||||
GraphOfContracts,
|
||||
compute_delta,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
|
|
@ -22,4 +23,5 @@ __all__ = [
|
|||
"Attestation",
|
||||
"AuditLog",
|
||||
"GraphOfContracts",
|
||||
"compute_delta",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, asdict
|
||||
from typing import Dict, Any, List
|
||||
import json
|
||||
from dataclasses import dataclass, asdict, field
|
||||
from typing import Dict, Any, List, Optional
|
||||
|
||||
|
||||
def to_json(obj: Any) -> str:
|
||||
return json.dumps(obj, default=lambda o: o.__dict__, sort_keys=True)
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -11,7 +16,10 @@ class LocalExecutionTask:
|
|||
instrument: str
|
||||
venue: str
|
||||
objective: str
|
||||
constraints: Dict[str, Any]
|
||||
constraints: Dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
def to_json(self) -> str:
|
||||
return to_json(asdict(self))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
|
@ -24,6 +32,9 @@ class SharedMarketContext:
|
|||
version: int
|
||||
contract_id: str
|
||||
|
||||
def to_json(self) -> str:
|
||||
return to_json(asdict(self))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
|
|
@ -35,7 +46,10 @@ class PlanDelta:
|
|||
timestamp: float
|
||||
author: str
|
||||
contract_id: str
|
||||
privacy_budget: float
|
||||
privacy_budget: Optional[float] = None
|
||||
|
||||
def to_json(self) -> str:
|
||||
return to_json(asdict(self))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
|
@ -50,6 +64,9 @@ class Attestation:
|
|||
contract_id: str
|
||||
version: int
|
||||
|
||||
def to_json(self) -> str:
|
||||
return to_json(asdict(self))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return asdict(self)
|
||||
|
||||
|
|
@ -57,7 +74,13 @@ class Attestation:
|
|||
@dataclass
|
||||
class AuditLog:
|
||||
"""Append-only log of attestations and approvals."""
|
||||
entries: List[Attestation]
|
||||
entries: List[Attestation] = field(default_factory=list)
|
||||
|
||||
def add(self, attestation: Attestation) -> None:
|
||||
self.entries.append(attestation)
|
||||
|
||||
def to_json(self) -> str:
|
||||
return to_json([asdict(entry) for entry in self.entries])
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {"entries": [e.to_dict() for e in self.entries]}
|
||||
|
|
@ -67,17 +90,19 @@ class AuditLog:
|
|||
class GraphOfContracts:
|
||||
"""Registry for adapters and data-contract schemas."""
|
||||
registry: Dict[str, Any]
|
||||
version: int = 1
|
||||
adapters: Optional[Dict[str, Any]] = None
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if self.adapters is None:
|
||||
self.adapters = self.registry
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {"registry": self.registry}
|
||||
return {"registry": self.registry, "version": self.version, "adapters": self.adapters}
|
||||
|
||||
|
||||
def compute_delta(task: LocalExecutionTask, ctx: SharedMarketContext) -> PlanDelta:
|
||||
"""Deterministic, minimal PlanDelta from inputs.
|
||||
|
||||
This is intentionally deterministic (timestamp=0.0) for replayability in tests
|
||||
and backtesting scenarios. Real deployments can replace this with a richer solver.
|
||||
"""
|
||||
"""Deterministic, minimal PlanDelta from inputs."""
|
||||
delta = {
|
||||
"action": "hold",
|
||||
"reason": "base-case",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
"""Deterministic execution planner for ExProve."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
from typing import Any, Dict
|
||||
|
||||
from .contracts import LocalExecutionTask, SharedMarketContext, PlanDelta
|
||||
|
||||
|
||||
def _deterministic_delta(task: LocalExecutionTask, ctx: SharedMarketContext) -> Dict[str, Any]:
|
||||
seed_input = f"{task.task_id}:{task.instrument}:{task.venue}:{ctx.version}:{ctx.contract_id}"
|
||||
digest = hashlib.sha256(seed_input.encode("utf-8")).hexdigest()
|
||||
return {
|
||||
"route": [task.venue],
|
||||
"size_adjustment": int(digest[:6], 16) % 1000,
|
||||
"timestamp": 0.0,
|
||||
"hash_seed": digest,
|
||||
}
|
||||
|
||||
|
||||
def compute_plan_delta(task: LocalExecutionTask, ctx: SharedMarketContext, *, author: str) -> PlanDelta:
|
||||
return PlanDelta(
|
||||
delta=_deterministic_delta(task, ctx),
|
||||
timestamp=0.0,
|
||||
author=author,
|
||||
contract_id=ctx.contract_id,
|
||||
privacy_budget=None,
|
||||
)
|
||||
|
|
@ -8,7 +8,7 @@ version = "0.1.0"
|
|||
description = "Open-source Execution Provenance Engine for cross-venue equity trading (core primitives)"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.8"
|
||||
license = {text = "MIT"}
|
||||
license = "MIT"
|
||||
authors = [ { name = "ExProve Team" } ]
|
||||
dependencies = [
|
||||
"dataclasses; python_version < '3.7'",
|
||||
|
|
|
|||
Loading…
Reference in New Issue