From 42e5395066485884d0f9b5c405eedf41dc8a99f1 Mon Sep 17 00:00:00 2001 From: agent-db0ec53c058f1326 Date: Fri, 17 Apr 2026 01:01:30 +0200 Subject: [PATCH] build(agent): molt-z#db0ec5 iteration --- nova_plan/contracts.py | 3 ++ nova_plan/energi_bridge.py | 60 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 nova_plan/energi_bridge.py diff --git a/nova_plan/contracts.py b/nova_plan/contracts.py index 97e4a91..6f5f296 100644 --- a/nova_plan/contracts.py +++ b/nova_plan/contracts.py @@ -19,6 +19,9 @@ class PlanDelta: # Optional fields to support CRDT-like, partition-tolerant merges parent_version: int | None = None sequence: int | None = None + # Optional contract and signature fields to support Contract-as-Code (CaC) + contract_id: str | None = None + signature: str | None = None def to_json(self) -> str: return json.dumps(asdict(self)) diff --git a/nova_plan/energi_bridge.py b/nova_plan/energi_bridge.py new file mode 100644 index 0000000..7b26935 --- /dev/null +++ b/nova_plan/energi_bridge.py @@ -0,0 +1,60 @@ +"""EnergiBridge: a minimal, production-friendly bridge for NovaPlan interoperability. + +This module provides a small, production-oriented scaffold that maps NovaPlan +primitives to a CatOpt-like canonical representation and exposes a simple +Contract-as-Code (CaC) workflow for interoperability across adapters. + +- to_object(local_problem) and to_morphism(plan_delta) reuse the existing + catoptBridge logic already in nova_plan.catopt_bridge. +- EnergiBridge.register_contract(contract_id, content, key) signs and stores a + contract artifact in the in-repo CaC registry, enabling provenance for adapters. + +The implementation is intentionally small and non-breaking so existing tests +continue to pass. It serves as a deliberate MVP wiring point for future +feature growth. +""" + +from __future__ import annotations + +from typing import Any, Dict + +from nova_plan.catopt_bridge import to_object, delta_to_morphism +from nova_plan.contracts import PlanDelta, CaCContract, CaCRegistry, sign_ca_contract + + +class EnergiBridge: + """Canonical EnergiBridge facade for cross-domain interoperability. + + Provides helpers to map core primitives to canonical representations and + to publish a signed contract artifact for governance and replay-safe + interoperability. + """ + + def __init__(self, signer_key: str | None = None) -> None: + self.signer_key = signer_key + + # Canonical mapping helpers (thin wrappers around existing bridge logic) + def to_object(self, local_problem) -> object: + """Convert a LocalProblem to a canonical ObjectI via existing bridge.""" + return to_object(local_problem) + + def to_morphism(self, plan_delta: PlanDelta, contract_id: str = "default") -> object: + """Convert a PlanDelta to a canonical Morphism, with optional contract_id.""" + return delta_to_morphism(plan_delta, contract_id=contract_id) + + # CaC publishing interface + def register_contract(self, contract_id: str, content: Dict[str, Any], key: str) -> CaCContract: + """Sign and register a contract artifact in the CaC registry. + + - contract_id: unique id for the contract artifact + - content: the contract content payload (big or small, domain-specific) + - key: signing key (private material); used to derive a signature deterministically + Returns the signed CaCContract object and registers it in CaCRegistry. + """ + contract = CaCContract(contract_id=contract_id, version=1, content=content) + signed = sign_ca_contract(contract, key) + CaCRegistry.register(signed) + return signed + + +__all__ = ["EnergiBridge"]