from idea154_civicmesh_studio_federated.contracts import Asset, LocalModel, PlanDelta, SharedSignals def test_contract_hashes_are_stable(): model = LocalModel( neighborhood_id="north", assets=[Asset(asset_id="light-1", asset_type="street-light", neighborhood_id="north", capacity_kw=1.2)], energy_limit_kw=10.0, ) same_model = LocalModel( neighborhood_id="north", assets=[Asset(asset_id="light-1", asset_type="street-light", neighborhood_id="north", capacity_kw=1.2)], energy_limit_kw=10.0, ) assert model.content_hash() == same_model.content_hash() def test_plan_delta_serializes_canonically(): delta = PlanDelta(neighborhood_id="south", iteration=2, actions={"pump_dispatch_m3": 4.5}, notes="ok") assert '"pump_dispatch_m3":4.5' in delta.canonical_json() def test_shared_signals_round_trip(): signals = SharedSignals(neighborhood_id="east", source="weather", forecast_demand_kw=5.0, available_capacity_kw=3.0) assert signals.model_dump()["neighborhood_id"] == "east"