diff --git a/tests/test_session.py b/tests/test_session.py index 8b824a76..37b9df25 100644 --- a/tests/test_session.py +++ b/tests/test_session.py @@ -8041,6 +8041,54 @@ class TestMemoryIndexSnapshotLifecycle: assert get_storage().get_memory_index_snapshot(session.ws_id) is not None + def test_first_capture_waits_through_catalog_prefix_churn(self, tmp_db): + """Cold MCP catalog callbacks may invalidate several capture plans.""" + session = _make_registered_session(ws_id="catalog-churn-index", user_id="owner") + generation = session._claim_generation(principal_id="owner") + session._memory_index_admission_generation = generation + candidate = { + "content": '', + "principal_id": "owner", + "project_id": "", + "project_name": "", + "entry_count": 0, + "char_count": 66, + "invalid_description_count": 0, + } + attempts = 0 + + def acquire( + _ws_id: str, + _principal_id: str, + *, + commit_context: Any, + ) -> dict[str, Any]: + nonlocal attempts + attempts += 1 + if attempts <= 4: + session._invalidate_system_prefix() + with commit_context(candidate): + pass + return candidate + + with ( + patch( + "turnstone.core.session.acquire_memory_index_snapshot", + side_effect=acquire, + ), + patch("turnstone.core.session.time.sleep") as sleep, + ): + session._admit_memory_index_request( + session._primary_lane(), + my_generation=generation, + principal_id="owner", + ) + + assert attempts == 5 + assert [item.args[0] for item in sleep.call_args_list] == [0.025, 0.05, 0.1, 0.2] + assert session._memory_index_snapshot == candidate + assert "