build(agent): new-agents-2#7e3bbc iteration
This commit is contained in:
parent
e37a251d0f
commit
7b6cba3164
19
README.md
19
README.md
|
|
@ -6,6 +6,7 @@ What you will find in this repository
|
||||||
- A production-oriented Python MVP with a small, extensible architecture.
|
- A production-oriented Python MVP with a small, extensible architecture.
|
||||||
- Core primitives: policy DSL, verifiable routing logs, ZKP prototype, auditable ledger, adapters, privacy-preserving statistics, and governance.
|
- Core primitives: policy DSL, verifiable routing logs, ZKP prototype, auditable ledger, adapters, privacy-preserving statistics, and governance.
|
||||||
- A test suite with basic unit tests for each primitive.
|
- A test suite with basic unit tests for each primitive.
|
||||||
|
- MVP extension: versioned policy blocks and a toy policy DSL example (see policy.py changes).
|
||||||
- A packaging and publishing readiness plan (AGENTS.md, READY_TO_PUBLISH).
|
- A packaging and publishing readiness plan (AGENTS.md, READY_TO_PUBLISH).
|
||||||
|
|
||||||
How to run locally
|
How to run locally
|
||||||
|
|
@ -18,3 +19,21 @@ Hooking into packaging
|
||||||
- This package is prepared for Python packaging under the name `idea164_bexproof_verifiable_best` as per the publishing requirements.
|
- This package is prepared for Python packaging under the name `idea164_bexproof_verifiable_best` as per the publishing requirements.
|
||||||
|
|
||||||
Note: See AGENTS.md for architectural guidelines and how future agents should contribute.
|
Note: See AGENTS.md for architectural guidelines and how future agents should contribute.
|
||||||
|
|
||||||
|
Toy policy snippet (example)
|
||||||
|
- Simple legacy policy shape (supported by load_policy):
|
||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"rules": {
|
||||||
|
"price_improvement_min": 0.001,
|
||||||
|
"latency_budget_ms": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- Versioned policy blocks (new in this MVP):
|
||||||
|
{
|
||||||
|
"blocks": [
|
||||||
|
{"version": 1, "rules": {"price_improvement_min": 0.001, "latency_budget_ms": 10}},
|
||||||
|
{"version": 2, "rules": {"price_improvement_min": 0.0015, "latency_budget_ms": 8}}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Only the highest-version block will be applied by load_policy when blocks are present. This enables governance-driven policy evolution without breaking existing deployments.
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,11 @@
|
||||||
This module provides a lightweight policy container and a tiny evaluator.
|
This module provides a lightweight policy container and a tiny evaluator.
|
||||||
Policies are represented as JSON-like strings for simplicity in this MVP.
|
Policies are represented as JSON-like strings for simplicity in this MVP.
|
||||||
In production, replace with a proper DSL parser and validator.
|
In production, replace with a proper DSL parser and validator.
|
||||||
|
|
||||||
|
Enhancement: support versioned policy blocks to enable multi-version governance
|
||||||
|
and policy evolution. The loader will select the highest-versioned block if a
|
||||||
|
policy contains a "blocks" array. If the policy uses the legacy shape
|
||||||
|
{"version": ..., "rules": ...}, it is still supported for backward compatibility.
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import json
|
import json
|
||||||
|
|
@ -27,10 +32,30 @@ def load_policy(policy_text: str) -> Policy:
|
||||||
data = json.loads(policy_text.replace("'", '"'))
|
data = json.loads(policy_text.replace("'", '"'))
|
||||||
except Exception:
|
except Exception:
|
||||||
raise ValueError("Policy text is not valid JSON or Python-like dict string")
|
raise ValueError("Policy text is not valid JSON or Python-like dict string")
|
||||||
if not isinstance(data, dict) or "version" not in data or "rules" not in data:
|
|
||||||
raise ValueError("Policy must contain 'version' and 'rules' keys")
|
# Support both legacy shape and versioned blocks:
|
||||||
|
# Legacy: { "version": 1, "rules": { ... } }
|
||||||
|
# Versioned: { "blocks": [ { "version": 1, "rules": { ... } }, ... ] }
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
raise ValueError("Policy must be a JSON object")
|
||||||
|
|
||||||
|
# If versioned blocks are present, pick the highest version
|
||||||
|
if "blocks" in data and isinstance(data["blocks"], list):
|
||||||
|
blocks = data["blocks"]
|
||||||
|
if not blocks:
|
||||||
|
raise ValueError("Policy blocks list is empty")
|
||||||
|
# Find block with max version
|
||||||
|
best = max(blocks, key=lambda b: int(b.get("version", 0)))
|
||||||
|
if not isinstance(best, dict) or "version" not in best or "rules" not in best:
|
||||||
|
raise ValueError("Policy block must contain 'version' and 'rules' keys")
|
||||||
|
return Policy(version=int(best["version"]), rules=best["rules"])
|
||||||
|
|
||||||
|
# Legacy single-block shape
|
||||||
|
if "version" in data and "rules" in data:
|
||||||
return Policy(version=int(data["version"]), rules=data["rules"])
|
return Policy(version=int(data["version"]), rules=data["rules"])
|
||||||
|
|
||||||
|
raise ValueError("Policy must contain 'version' and 'rules' keys or a 'blocks' array")
|
||||||
|
|
||||||
|
|
||||||
def evaluate_policy(log: Dict[str, Any], policy: Policy) -> bool:
|
def evaluate_policy(log: Dict[str, Any], policy: Policy) -> bool:
|
||||||
# Minimal evaluation: all top-level rules keys are checked if present in log
|
# Minimal evaluation: all top-level rules keys are checked if present in log
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
import json
|
||||||
|
from bexproof.policy import load_policy, evaluate_policy
|
||||||
|
|
||||||
|
|
||||||
|
def test_policy_load_with_blocks_selects_latest_version():
|
||||||
|
policy_text = json.dumps({
|
||||||
|
"blocks": [
|
||||||
|
{"version": 1, "rules": {"latency_budget_ms": 5}},
|
||||||
|
{"version": 2, "rules": {"latency_budget_ms": 3, "price_improvement_min": 0.0005}},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
policy = load_policy(policy_text)
|
||||||
|
assert policy.version == 2
|
||||||
|
assert policy.rules.get("latency_budget_ms") == 3
|
||||||
|
# Ensure evaluate_policy works with the loaded policy
|
||||||
|
log = {"order_id": "ORDX", "venue": "VENUEX", "latency_ms": 3, "price_improvement": 0.001}
|
||||||
|
assert evaluate_policy(log, policy) is True
|
||||||
Loading…
Reference in New Issue