build(agent): molt-z#db0ec5 iteration
This commit is contained in:
parent
7e891bda72
commit
7af52d7e88
|
|
@ -15,3 +15,10 @@ How to run tests
|
|||
Notes
|
||||
- This MVP focuses on minimal, well-scoped components to enable end-to-end interoperability with adapters and the ADMM-lite solver.
|
||||
- See core/bridge.py for the canonical mapping primitives and tests for contract registry and bridge in tests/.
|
||||
|
||||
## MVP Enhancements
|
||||
- Added a lightweight Graph-of-Contracts in core/graph_of_contracts.py to map adapters to versioned contracts.
|
||||
- Added a minimal thread-safe enhancement to ContractRegistry (core/contracts.py) for concurrency safety.
|
||||
- Added a minimal DSL sketch documenting the LocalProblem/SharedVariables/PlanDelta data contracts (docs/dsl_sketch.md).
|
||||
- Added a minimal in-repo DSL documentation and a sample Graph-of-Contracts scaffold to accelerate adapter onboarding.
|
||||
- Documentation and a ready-to-publish readiness baton in READY_TO_PUBLISH (to signal MVP stability when publishing).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Dict
|
||||
import threading
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -55,13 +56,34 @@ class ContractRegistry:
|
|||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
# In-memory, versioned registry with simple thread-safety for MVP
|
||||
self._store: Dict[str, Dict[str, ContractDefinition]] = {}
|
||||
self._lock = threading.RLock()
|
||||
|
||||
def add_contract(self, name: str, version: str, schema: Dict[str, Any]) -> None:
|
||||
self._store.setdefault(name, {})[version] = ContractDefinition(name, version, schema)
|
||||
with self._lock:
|
||||
self._store.setdefault(name, {})[version] = ContractDefinition(name, version, schema)
|
||||
|
||||
def get_contract(self, name: str, version: str) -> ContractDefinition | None:
|
||||
return self._store.get(name, {}).get(version)
|
||||
with self._lock:
|
||||
return self._store.get(name, {}).get(version)
|
||||
|
||||
def list_contracts(self) -> Dict[str, Dict[str, ContractDefinition]]:
|
||||
return self._store
|
||||
with self._lock:
|
||||
# Return a shallow copy to avoid external mutation
|
||||
return {k: dict(v) for k, v in self._store.items()}
|
||||
|
||||
# Convenience helpers for MVP tooling
|
||||
def has_contract(self, name: str, version: str) -> bool:
|
||||
with self._lock:
|
||||
return version in self._store.get(name, {})
|
||||
|
||||
def remove_contract(self, name: str, version: str) -> bool:
|
||||
with self._lock:
|
||||
if name in self._store and version in self._store[name]:
|
||||
del self._store[name][version]
|
||||
# Clean up empty dicts
|
||||
if not self._store[name]:
|
||||
del self._store[name]
|
||||
return True
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Dict, Optional
|
||||
|
||||
from .contracts import ContractDefinition
|
||||
|
||||
|
||||
class GraphOfContracts:
|
||||
"""Lightweight registry graph mapping adapters to contract versions.
|
||||
|
||||
This is intentionally minimal: it stores per-adapter contracts organized by
|
||||
contract name -> version -> ContractDefinition, enabling plug-and-play across
|
||||
domain adapters while keeping a canonical reference per adapter.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
# adapter_name -> contract_name -> version -> ContractDefinition
|
||||
self._graph: Dict[str, Dict[str, Dict[str, ContractDefinition]]] = {}
|
||||
|
||||
def register(self, adapter: str, contract_name: str, version: str, schema: Dict[str, object]) -> None:
|
||||
self._graph.setdefault(adapter, {})
|
||||
self._graph[adapter].setdefault(contract_name, {})[version] = ContractDefinition(
|
||||
name=contract_name,
|
||||
version=version,
|
||||
schema=schema,
|
||||
)
|
||||
|
||||
def get_contract(self, adapter: str, contract_name: str, version: str) -> Optional[ContractDefinition]:
|
||||
return self._graph.get(adapter, {}).get(contract_name, {}).get(version)
|
||||
|
||||
def list_adapter_contracts(self, adapter: str) -> Dict[str, Dict[str, ContractDefinition]]:
|
||||
return self._graph.get(adapter, {})
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
# DSL Sketch: Core CatOpt-Graph Primitives
|
||||
|
||||
This document provides a minimal sketch for the DSL that describes LocalProblems,
|
||||
SharedVariables, PlanDelta, and related contracts used by adapters and the ADMM-lite
|
||||
core.
|
||||
|
||||
LocalProblem
|
||||
- asset_id: identifier of the local optimization problem on the device
|
||||
- payload: dictionary containing domain-specific problem data (e.g., objective terms, constraints)
|
||||
|
||||
SharedVariables
|
||||
- iter_id: iteration counter for synchronization rounds
|
||||
- values: map of signals that are shared across the mesh (e.g., dual variables, summaries)
|
||||
|
||||
DualVariables
|
||||
- iter_id: iteration counter
|
||||
- values: dual variables per shared signal
|
||||
|
||||
PlanDelta
|
||||
- iter_id: iteration counter
|
||||
- delta: aggregated changes to be applied to local plans
|
||||
|
||||
PrivacyBudget
|
||||
- budget_id: identifier for privacy budget instance
|
||||
- limits: per-signal DP budgets or leakage limits
|
||||
|
||||
AuditLog
|
||||
- entry_id: unique log entry identifier
|
||||
- payload: audit metadata for reconciliation steps
|
||||
|
||||
Notes
|
||||
- All messages should include per-message metadata (version, timestamp, nonce, crypto-tag).
|
||||
- Identity should be established via DIDs or short-lived certificates; transport should be TLS-secured.
|
||||
|
||||
This sketch intentionally stays minimal to accelerate MVP integration.
|
||||
Loading…
Reference in New Issue