helper used only by the POSIX fork harness below */
| 10574 | |
| 10575 | #ifndef _WIN32 /* helper used only by the POSIX fork harness below */ |
| 10576 | static int idx853_supervised_autowatch_check(const char *repo_dir, const char *cache_dir) { |
| 10577 | /* Become a supervisor host with the kill switch OFF — the real prod MCP |
| 10578 | * server's state. Done in the FORKED CHILD only (see harness) so the parent |
| 10579 | * test-runner's process-wide host mark stays clear (#845 invariant). Bound the |
| 10580 | * worker so a stuck spawn cannot run long under the fork+alarm net. */ |
| 10581 | cbm_index_supervisor_mark_host(); |
| 10582 | cbm_unsetenv("CBM_INDEX_SUPERVISOR"); |
| 10583 | cbm_setenv("CBM_INDEX_MAX_RESTARTS", "1", 1); |
| 10584 | cbm_setenv("CBM_INDEX_WORKER_TIMEOUT_S", "30", 1); |
| 10585 | |
| 10586 | cbm_config_t *cfg = cbm_config_open(cache_dir); |
| 10587 | cbm_store_t *wstore = cbm_store_open_memory(); |
| 10588 | cbm_watcher_t *watcher = wstore ? cbm_watcher_new(wstore, NULL, NULL) : NULL; |
| 10589 | if (!cfg || !watcher) { |
| 10590 | if (watcher) { |
| 10591 | cbm_watcher_free(watcher); |
| 10592 | } |
| 10593 | if (wstore) { |
| 10594 | cbm_store_close(wstore); |
| 10595 | } |
| 10596 | if (cfg) { |
| 10597 | cbm_config_close(cfg); |
| 10598 | } |
| 10599 | return IDX853_SETUP_FAIL; |
| 10600 | } |
| 10601 | /* auto_index=true → maybe_auto_index launches autoindex_thread for the fresh |
| 10602 | * project; auto_watch=false → the gate this guard exercises. */ |
| 10603 | cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX, "true"); |
| 10604 | cbm_config_set(cfg, CBM_CONFIG_AUTO_WATCH, "false"); |
| 10605 | |
| 10606 | /* detect_session derives session_root/session_project from the cwd. */ |
| 10607 | char old_cwd[1024]; |
| 10608 | if (!cbm_getcwd(old_cwd, sizeof(old_cwd)) || cbm_chdir(repo_dir) != 0) { |
| 10609 | cbm_watcher_free(watcher); |
| 10610 | cbm_store_close(wstore); |
| 10611 | cbm_config_close(cfg); |
| 10612 | return IDX853_SETUP_FAIL; |
| 10613 | } |
| 10614 | |
| 10615 | int spawns_before = cbm_index_supervisor_spawn_count(); |
| 10616 | int code = IDX853_SETUP_FAIL; |
| 10617 | |
| 10618 | cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL); |
| 10619 | if (srv) { |
| 10620 | cbm_mcp_server_set_watcher(srv, watcher); |
| 10621 | cbm_mcp_server_set_config(srv, cfg); |
| 10622 | char *resp = cbm_mcp_server_handle( |
| 10623 | srv, "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{}}"); |
| 10624 | free(resp); |
| 10625 | /* free() joins the autoindex thread → the supervised worker has finished |
| 10626 | * and the registration decision (buggy or gated) has executed. */ |
| 10627 | cbm_mcp_server_free(srv); |
| 10628 | |
| 10629 | int spawns_after = cbm_index_supervisor_spawn_count(); |
| 10630 | int watch_count = cbm_watcher_watch_count(watcher); |
| 10631 | |
| 10632 | if (spawns_after == spawns_before) { |
| 10633 | code = IDX853_NO_SPAWN; /* supervised branch never ran — not a valid probe */ |
no test coverage detected