build(agent): molt-by#23c260 iteration

This commit is contained in:
agent-23c260159794913b 2026-04-16 23:54:20 +02:00
parent 581963cabf
commit 89140c4027
3 changed files with 92 additions and 0 deletions

View File

@ -12,6 +12,7 @@ and a registry as the project evolves.
""" """
from .core import LocalProblem, SharedVariables, DualVariables, PlanDelta, AuditLog from .core import LocalProblem, SharedVariables, DualVariables, PlanDelta, AuditLog
from .transport import TLSChannel
from .registry import GraphOfContracts from .registry import GraphOfContracts
__all__ = [ __all__ = [
@ -21,4 +22,5 @@ __all__ = [
"PlanDelta", "PlanDelta",
"AuditLog", "AuditLog",
"GraphOfContracts", "GraphOfContracts",
"TLSChannel",
] ]

32
src/energiamesh/sync.py Normal file
View File

@ -0,0 +1,32 @@
from __future__ import annotations
"""Delta-sync helpers for EnergiaMesh MVP.
This module provides a tiny, dependency-free toy delta generator that can be
used by adapters to evolve local problem state and shared variables in a
controlled way. It intentionally keeps the logic small while being a clear
public API surface for MVP wiring.
"""
from typing import Any, Dict
import time
from energiamesh.core import LocalProblem, SharedVariables, PlanDelta
def compute_delta(lp: LocalProblem, sv: SharedVariables) -> PlanDelta:
"""Create a minimal delta from a LocalProblem and SharedVariables.
This is deliberately simple: it captures the latest forecast-ish signal (if
present) and the local problem id to demonstrate how a downstream consumer
might apply incremental updates.
"""
payload: Dict[str, Any] = {}
if sv.signals:
# Copy a representative signal (best-effort; shallow copy is fine for MVP)
for k, v in sv.signals.items():
payload[f"forecast:{k}"] = v
break # keep payload small for MVP
delta = PlanDelta(delta=payload, delta_id=f"d-{int(time.time())}")
return delta

View File

@ -0,0 +1,58 @@
from __future__ import annotations
import time
import os
import threading
from typing import Any, Dict
class TLSChannel:
"""Lightweight, test-friendly TLS-like transport channel.
This is a minimal stand-in for a real TLS transport used in MVP wiring.
It provides a secure envelope around messages and a simple replay-protection
mechanism via an in-memory nonce store per channel.
"""
def __init__(self, peer_id: str, tls_config: Dict[str, Any] | None = None) -> None:
self.peer_id = peer_id
self.tls_config = tls_config or {}
self._seen_nonces = set()
self._lock = threading.Lock()
def _generate_nonce(self) -> str:
# Simple, filesystem-backed randomness for a nonce
return os.urandom(16).hex()
def send(self, payload: Dict[str, Any]) -> Dict[str, Any]:
"""Wrap payload into a secure envelope for transmission."""
nonce = self._generate_nonce()
envelope = {
"secure": True,
"from": self.peer_id,
"payload": payload,
"nonce": nonce,
"ts": time.time(),
"tls_meta": {
"tls_version": self.tls_config.get("version", "TLS1.3"),
"cipher": self.tls_config.get("cipher", "AES-256-GCM"),
},
}
with self._lock:
self._seen_nonces.add(nonce)
return envelope
def receive(self, envelope: Dict[str, Any]) -> Dict[str, Any]:
"""Unwrap a secure envelope, performing a minimal replay check."""
if not isinstance(envelope, dict) or not envelope.get("secure"):
raise ValueError("Invalid envelope: missing secure flag")
nonce = envelope.get("nonce")
if not nonce:
raise ValueError("Invalid envelope: missing nonce")
with self._lock:
if nonce in self._seen_nonces:
raise ValueError("Replay detected for nonce: {}".format(nonce))
self._seen_nonces.add(nonce)
# Return the inner payload for higher-level handling
return envelope["payload"]