diff --git a/loopx/control_plane/todos/contract.py b/loopx/control_plane/todos/contract.py index 04f0e27d77..4ebe815956 100644 --- a/loopx/control_plane/todos/contract.py +++ b/loopx/control_plane/todos/contract.py @@ -1115,7 +1115,9 @@ def _metadata_value_is_present(value: Any) -> bool: _TodoMetadataField( key, _nonempty_metadata_text, - write_normalizer=_truthy_value, + write_normalizer=normalize_todo_generation + if key == "material_change_generation" + else _truthy_value, ) for key in TODO_MONITOR_METADATA_FIELDS ), diff --git a/tests/control_plane/test_todo_metadata_schema.py b/tests/control_plane/test_todo_metadata_schema.py index c4126946c8..26e46703f5 100644 --- a/tests/control_plane/test_todo_metadata_schema.py +++ b/tests/control_plane/test_todo_metadata_schema.py @@ -54,6 +54,7 @@ def test_todo_metadata_round_trip_preserves_canonical_values() -> None: result_hash="abc123", consecutive_no_change="2", material_change="false", + material_change_generation=0, max_no_change_before_replan="3", note="focused validation passed", evidence="receipt cqr_123", @@ -124,6 +125,7 @@ def test_todo_metadata_round_trip_preserves_canonical_values() -> None: "result_hash": "abc123", "consecutive_no_change": "2", "material_change": "false", + "material_change_generation": "0", "max_no_change_before_replan": "3", "note": "focused validation passed", "evidence": "receipt cqr_123",