diff --git a/solstone/think/cortex.py b/solstone/think/cortex.py index 027ca5bca..73351e9bb 100644 --- a/solstone/think/cortex.py +++ b/solstone/think/cortex.py @@ -258,16 +258,6 @@ class CortexService: name="cortex-status", daemon=True, ).start() - - def _should_request_brain_refresh(self) -> bool: - try: - inspection = inspect_brain_state(datetime.now(timezone.utc)) - except Exception: - return True - projection = inspection["projection"] - if projection["aggregate_state"] in {"checking", "ready"}: - return False - return not projection["runtime_transition_in_progress"] self._spawn_worker = threading.Thread( target=self._run_spawn_worker, name="cortex-spawn-worker", @@ -293,6 +283,16 @@ class CortexService: self.logger.info("Shutdown requested, will exit when idle") self.shutdown_requested.set() + def _should_request_brain_refresh(self) -> bool: + try: + inspection = inspect_brain_state(datetime.now(timezone.utc)) + except Exception: + return True + projection = inspection["projection"] + if projection["aggregate_state"] in {"checking", "ready"}: + return False + return not projection["runtime_transition_in_progress"] + def _handle_callosum_message(self, message: Dict[str, Any]) -> None: """Handle incoming Callosum messages (callback).""" # Filter for cortex tract and request event diff --git a/tests/test_cortex.py b/tests/test_cortex.py index f1824d495..bfd3659ca 100644 --- a/tests/test_cortex.py +++ b/tests/test_cortex.py @@ -127,6 +127,54 @@ def test_cortex_service_initialization(cortex_service, mock_journal): assert cortex_service.talents_dir.exists() +def test_start_starts_spawn_worker_and_stays_resident(cortex_service, monkeypatch): + from solstone.think import cortex + + fake_callosum = MagicMock() + cortex_service.callosum = fake_callosum + monkeypatch.setattr(cortex_service, "_should_request_brain_refresh", lambda: False) + monkeypatch.setattr(cortex_service, "_emit_periodic_status", lambda: None) + + resident_loop_entered = threading.Event() + returned = threading.Event() + errors: list[BaseException] = [] + real_sleep = time.sleep + + def short_sleep(_seconds): + resident_loop_entered.set() + real_sleep(0.01) + + monkeypatch.setattr(cortex.time, "sleep", short_sleep) + + def run_start(): + try: + cortex_service.start() + except BaseException as exc: # pragma: no cover - surfaced below + errors.append(exc) + finally: + returned.set() + + service_thread = threading.Thread(target=run_start, daemon=True) + service_thread.start() + try: + assert resident_loop_entered.wait(1) + assert fake_callosum.start.called + assert cortex_service._spawn_worker is not None + assert cortex_service._spawn_worker.is_alive() + assert service_thread.is_alive() + assert not returned.is_set() + + cortex_service.shutdown_requested.set() + service_thread.join(timeout=1) + assert returned.is_set() + assert errors == [] + finally: + cortex_service.stop_event.set() + if cortex_service._spawn_worker is not None: + cortex_service._spawn_worker.join(timeout=1) + service_thread.join(timeout=1) + + def test_handle_request_dedups_existing_active_file( cortex_service, mock_journal, monkeypatch ):