diff --git a/core/models.py b/core/models.py index da126c1..cb4654e 100644 --- a/core/models.py +++ b/core/models.py @@ -1,6 +1,8 @@ from __future__ import annotations from dataclasses import dataclass, field +import time +import uuid from typing import List, Dict, Any @@ -29,6 +31,18 @@ class PlanDelta: delta_id: str fleet_id: str changes: Dict[str, Any] + # Metadata for verifiable reconciliation and auditing + version: int = 1 + nonce: str | None = None + timestamp: float | None = None + + def __post_init__(self): + # Ensure timestamp is set for auditing + if self.timestamp is None: + self.timestamp = time.time() + # Ensure a unique nonce for replay-safe reconciliation + if self.nonce is None: + self.nonce = uuid.uuid4().hex @dataclass diff --git a/tests/test_fleetopt.py b/tests/test_fleetopt.py index 711c2bf..f6590a5 100644 --- a/tests/test_fleetopt.py +++ b/tests/test_fleetopt.py @@ -70,3 +70,8 @@ def test_two_fleets_cross_exchange_basic(): delta = asyncio.get_event_loop().run_until_complete(run()) assert delta.fleet_id == plan_a.fleet_id assert isinstance(delta.changes, dict) + # New metadata should be present and well-formed + assert isinstance(delta.version, int) + assert delta.version >= 1 + assert isinstance(delta.nonce, str) and len(delta.nonce) > 0 + assert isinstance(delta.timestamp, float)