diff --git a/src/cosmosmesh_privacy_preserving_federated/__init__.py b/src/cosmosmesh_privacy_preserving_federated/__init__.py index 73806c4..ee8a6f9 100644 --- a/src/cosmosmesh_privacy_preserving_federated/__init__.py +++ b/src/cosmosmesh_privacy_preserving_federated/__init__.py @@ -11,3 +11,4 @@ __all__ = [ "AuditLog", "GraphOfContracts", ] +from .canonical_bridge import map_to_ir # re-export for MVP bridge wiring diff --git a/src/cosmosmesh_privacy_preserving_federated/canonical_bridge.py b/src/cosmosmesh_privacy_preserving_federated/canonical_bridge.py new file mode 100644 index 0000000..c0c879d --- /dev/null +++ b/src/cosmosmesh_privacy_preserving_federated/canonical_bridge.py @@ -0,0 +1,4 @@ +# Compatibility shim: re-export map_to_ir from the underscored package path +from cosmosmesh_privacy_preserving_federated_ import canonical_bridge as _cb + +map_to_ir = _cb.map_to_ir diff --git a/src/cosmosmesh_privacy_preserving_federated_/canonical_bridge.py b/src/cosmosmesh_privacy_preserving_federated_/canonical_bridge.py new file mode 100644 index 0000000..c86ace8 --- /dev/null +++ b/src/cosmosmesh_privacy_preserving_federated_/canonical_bridge.py @@ -0,0 +1,37 @@ +from dataclasses import dataclass +from typing import Any, Dict, List + + +@dataclass +class IRPrimitive: + name: str + payload: Dict[str, Any] + + +@dataclass +class CanonicalBridgeIR: + objects: List[IRPrimitive] + morphisms: List[IRPrimitive] + plan_delta: IRPrimitive + privacy_budget: IRPrimitive + audit_log: IRPrimitive + version: str = "1.0" + + +def map_to_ir(local_problem: Dict[str, Any]) -> CanonicalBridgeIR: + """ + Lightweight mapper that canonicalizes CosmosMesh primitives to a vendor-agnostic IR. + This is intentionally small and focused to bootstrap cross-domain adapters during MVP. + """ + obj = IRPrimitive(name="LocalProblem", payload=local_problem) + morph = IRPrimitive(name="SharedVariables", payload={"forecasts": [], "priors": {}, "version": 1}) + plan = IRPrimitive(name="PlanDelta", payload={"delta": {}, "timestamp": local_problem.get("timestamp")}) + privacy = IRPrimitive(name="PrivacyBudget", payload={"budget": local_problem.get("privacy_budget", {})}) + audit = IRPrimitive(name="AuditLog", payload={"entries": []}) + return CanonicalBridgeIR( + objects=[obj], + morphisms=[morph], + plan_delta=plan, + privacy_budget=privacy, + audit_log=audit, + )