build(agent): new-agents-2#7e3bbc iteration
This commit is contained in:
parent
5bafb64620
commit
7ca2df4ac6
|
|
@ -21,7 +21,14 @@ Testing & Quality
|
||||||
Running Tests
|
Running Tests
|
||||||
- bash test.sh
|
- bash test.sh
|
||||||
|
|
||||||
Extending the MVP
|
- Extending the MVP
|
||||||
|
- Implemented a minimal production-friendly registry extension on GraphOfContracts: list_contracts and unregister_contract for better introspection and lifecycle management.
|
||||||
|
- Added unit tests (pytest) covering core primitives: LocalExperiment, SharedSignals, PlanDelta, and GraphOfContracts workflows.
|
||||||
|
- Plan to add REST/MQTT adapters and a secure aggregation backend in follow-up iterations; groundwork in this patch focuses on strengthening the contract model and making it testable.
|
||||||
|
|
||||||
|
Notes for contributors:
|
||||||
|
- The repo now includes tests/test_contracts.py validating core primitives. Run tests with bash test.sh.
|
||||||
|
- If you extend contracts or add new primitives, add tests accordingly.
|
||||||
- Add more adapters (e.g., Amplitude) with a consistent interface
|
- Add more adapters (e.g., Amplitude) with a consistent interface
|
||||||
- Expand governance with versioned templates and access controls
|
- Expand governance with versioned templates and access controls
|
||||||
- Implement a more robust secure aggregation (secure multi-party computation or differential privacy knobs in practice)
|
- Implement a more robust secure aggregation (secure multi-party computation or differential privacy knobs in practice)
|
||||||
|
|
|
||||||
|
|
@ -83,3 +83,23 @@ class GraphOfContracts:
|
||||||
return None
|
return None
|
||||||
# return a shallow copy to avoid external mutation
|
# return a shallow copy to avoid external mutation
|
||||||
return {"version": entry["version"], "contract": dict(entry["contract"])}
|
return {"version": entry["version"], "contract": dict(entry["contract"])}
|
||||||
|
|
||||||
|
# --- Registry helpers for production-grade usage ---
|
||||||
|
def list_contracts(self) -> Dict[str, Dict[str, Any]]:
|
||||||
|
"""Return a shallow copy of the entire registry for inspection.
|
||||||
|
|
||||||
|
This enables lightweight auditing and debugging tooling to enumerate
|
||||||
|
known contracts without mutating the registry.
|
||||||
|
"""
|
||||||
|
return {k: {"version": v["version"], "contract": dict(v["contract"])} for k, v in self._contracts.items()}
|
||||||
|
|
||||||
|
def unregister_contract(self, name: str) -> bool:
|
||||||
|
"""Remove a contract by name from the registry.
|
||||||
|
|
||||||
|
Returns True if the contract existed and was removed, False otherwise.
|
||||||
|
This operation is non-destructive to other contracts.
|
||||||
|
"""
|
||||||
|
if name in self._contracts:
|
||||||
|
del self._contracts[name]
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
import json
|
||||||
|
from opengrowth_privacy_preserving_federated_ import contracts as c
|
||||||
|
|
||||||
|
|
||||||
|
def test_local_experiment_to_dict():
|
||||||
|
le = c.LocalExperiment(
|
||||||
|
name="TestExperiment",
|
||||||
|
variables={"price": 9.99, "discount": 0.1},
|
||||||
|
privacy_budget={"epsilon": 1.0},
|
||||||
|
metadata={"owner": "alice"},
|
||||||
|
)
|
||||||
|
d = le.to_dict()
|
||||||
|
assert d["name"] == "TestExperiment"
|
||||||
|
assert d["variables"]["price"] == 9.99
|
||||||
|
assert d["privacy_budget"]["epsilon"] == 1.0
|
||||||
|
assert d["metadata"]["owner"] == "alice"
|
||||||
|
|
||||||
|
|
||||||
|
def test_shared_signals_to_dict():
|
||||||
|
ss = c.SharedSignals(
|
||||||
|
signals={"activation_rate": 0.42, "funnel_drop": 0.15},
|
||||||
|
provenance={"source": "mock"},
|
||||||
|
)
|
||||||
|
d = ss.to_dict()
|
||||||
|
assert d["signals"]["activation_rate"] == 0.42
|
||||||
|
assert d["provenance"]["source"] == "mock"
|
||||||
|
|
||||||
|
|
||||||
|
def test_plan_delta_to_dict():
|
||||||
|
pd = c.PlanDelta(delta={"activation": 1}, timestamp="2020-01-01T00:00:00Z", note="init")
|
||||||
|
d = pd.to_dict()
|
||||||
|
assert d["delta"]["activation"] == 1
|
||||||
|
assert d["timestamp"] == "2020-01-01T00:00:00Z"
|
||||||
|
assert d["note"] == "init"
|
||||||
|
|
||||||
|
|
||||||
|
def test_graph_of_contracts_registry_ops():
|
||||||
|
g = c.GraphOfContracts()
|
||||||
|
# register a contract
|
||||||
|
g.register_contract("example", {"hello": "world"}, version="1.0")
|
||||||
|
# get contract
|
||||||
|
reg = g.get_contract("example")
|
||||||
|
assert reg is not None
|
||||||
|
assert reg["version"] == "1.0"
|
||||||
|
assert reg["contract"]["hello"] == "world"
|
||||||
|
# list contracts
|
||||||
|
all_contracts = g.list_contracts()
|
||||||
|
assert "example" in all_contracts
|
||||||
|
# unregister and ensure removal
|
||||||
|
removed = g.unregister_contract("example")
|
||||||
|
assert removed is True
|
||||||
|
all_contracts = g.list_contracts()
|
||||||
|
assert "example" not in all_contracts
|
||||||
Loading…
Reference in New Issue