From cc3b63e5a7b82582506ab337e26edef85cf91bc1 Mon Sep 17 00:00:00 2001 From: agent-dd492b85242a98c5 Date: Sun, 19 Apr 2026 19:53:14 +0200 Subject: [PATCH] build(agent): new-agents-3#dd492b iteration --- README.md | 5 +++++ nova_plan/toy_contracts.py | 42 +++++++++++++++++++++++++++++++++++++ tests/test_toy_contracts.py | 19 +++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 nova_plan/toy_contracts.py create mode 100644 tests/test_toy_contracts.py diff --git a/README.md b/README.md index c5882e3..6925006 100644 --- a/README.md +++ b/README.md @@ -73,3 +73,8 @@ Interop Demo - A tiny demonstration script nova_plan/examples/demo_energi_bridge_demo.py showcases how core NovaPlan primitives map to a canonical representation via EnergiBridge, and how a simple CaC contract can be registered for provenance. - Run: python3 -m nova_plan.examples.demo_energi_bridge_demo - This script is non-destructive and safe to run in a test environment; it prints a couple of canonical representations to stdout for quick inspection. + +Toy interoperability seeds +- A tiny toy contract seed (toy-lp) and associated signing helpers are provided in nova_plan/toy_contracts.py to bootstrap interoperability testing between adapters. +- A small unit test (tests/test_toy_contracts.py) exercises contract registration and signing against a simple signer. +- This is intended for MVP bootstrapping and CI experiments; it is not a production contract, but it demonstrates how to seed a contract registry and provenance flow. diff --git a/nova_plan/toy_contracts.py b/nova_plan/toy_contracts.py new file mode 100644 index 0000000..8e1b53d --- /dev/null +++ b/nova_plan/toy_contracts.py @@ -0,0 +1,42 @@ +"""Toy contract seeds for interoperability testing. + +This module provides a tiny, self-contained contract seed representing a +LocalProblem-like contract. It is intended for bootstrapping adapter plumbing and +interoperability tests without requiring a full production contract pipeline. +""" +from __future__ import annotations + +from nova_plan.contracts import CaCContract, CaCRegistry, sign_ca_contract, SignedCaCContract, SignerStore + + +def toy_local_problem_contract() -> CaCContract: + """Return a minimal toy CaCContract representing a LocalProblem seed.""" + contract = CaCContract( + contract_id="toy-lp", + version=1, + content={ + "type": "LocalProblemSeed", + "domain": "space", + "assets": ["rover1", "habitat1"], + "objective": {"type": "min-energy"}, + "constraints": ["deadline<=t", "power<=Pmax"], + }, + ) + CaCRegistry.register(contract) + return contract + + +def sign_toy_contract(signer_id: str) -> "SignedCaCContract | None": + """Sign the toy contract if a signer key is registered, returning a SignedCaCContract. + + If no signer key exists, this returns None. This keeps MVP semantics simple. + """ + # Ensure the toy contract exists in the registry + if CaCRegistry.get("toy-lp") is None: + toy_local_problem_contract() + + contract = CaCRegistry.get("toy-lp") + if contract is None: + return None # pragma: no cover + signed = sign_ca_contract(contract, signer_id) + return signed diff --git a/tests/test_toy_contracts.py b/tests/test_toy_contracts.py new file mode 100644 index 0000000..b74437e --- /dev/null +++ b/tests/test_toy_contracts.py @@ -0,0 +1,19 @@ +import pytest + +from nova_plan.toy_contracts import toy_local_problem_contract, sign_toy_contract +from nova_plan.contracts import SignerStore + + +def test_toy_contract_seed_and_signing(): + # Register a simple signer key for MVP provenance + SignerStore.register("tester", "secret-key-123") + + # Create toy contract and ensure it's registered in the CaC registry + contract = toy_local_problem_contract() + assert contract.contract_id == "toy-lp" + + # Sign the toy contract and ensure a signature is produced + signed = sign_toy_contract("tester") + assert signed is not None + assert hasattr(signed, "signature") + assert signed.signature is not None