Files
deusdata--codebase-memory-mcp/tests/test_daemon_bootstrap.c
Martin Vogel d58afe562d revert(release): re-embed runtime assets into the single shipped binary
Externalizing the integration templates (#1492/#1493) and the UI bundle
(#1501/#1503) was done to reduce the Microsoft `Wacatac.B!ml` surface. It did
not work: across dry runs the flagged artifact count stayed at ~3 and the
detections merely moved between artifacts.

Dissection of run 31286803592 shows there is no structural cause to fix. The
verdicts split across every axis at once — linux-amd64 (dynamic) flagged while
linux-amd64-portable (static) is clean, but linux-arm64 (dynamic) clean while
linux-arm64-portable (static) is flagged. The two macOS binaries have identical
segment structure and split clean/flagged. Siblings from one build landed in
different variant buckets (.B vs .C). Entropy is low everywhere
(code_vectors.bin 4.166, grammar tables 3.464 bits/byte, against 7.5-8.0 for
packed payloads), so the packed-payload hypothesis is excluded too.

So the complexity bought nothing, and installation goes back to being
self-contained: one binary that carries its own UI and agent integration
templates, with no adjacent data file that has to resolve before `install`
works. Only the UI-capable composition ships from now on, under the historical
unsuffixed archive name.

Removed: src/ui/asset_pack.{c,h}, asset_pack_stub.c, asset_manifest_stub.c,
scripts/pack-ui-assets.mjs, src/cli/integration_assets.{c,h},
assets/cbm-integrations.json, scripts/gen-integrations-hash.sh, the
--verify-runtime-assets probe (nothing adjacent left to verify), and the
composition gates A6/A7 whose property is now deliberately inverted.

Restored: scripts/embed-frontend.sh, src/ui/embedded_{assets.h,stub.c}, the
compiled-in hook/adapter template bodies, and the embed/EMBED_OBJS build path.

Kept from the reverted commits, re-applied by hand where a wholesale file
restore would have dropped them:
  - cbm_module_path_utf8() in both self-path sites. GetModuleFileNameA renders
    through the ANSI code page and mangles non-ASCII install paths.
  - the /__cbm/ui-readiness HMAC proof, secure_random and cbm_hmac_sha256, so
    `daemon start --open` still waits for a genuine CBM listener.
  - X-Content-Type-Options: nosniff on served assets.
  - the MinGW noexecstack gate, -lbcrypt, and the cppcheck/zip CI fixes.

Archives are now codebase-memory-mcp-<os>-<arch>[-portable] with exactly four
members (binary, LICENSE, installer, THIRD_PARTY_NOTICES.md). That restores the
names every static package manifest already points at — aur, chocolatey,
homebrew, scoop, winget and glama were all broken by the -ui- rename.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-08-09 13:06:42 +02:00

796 lines
36 KiB
C

/* RED contract for early process-role classification. */
#include "test_framework.h"
#include "daemon/bootstrap.h"
#include "daemon/ipc.h"
#include "daemon/service.h"
#include "foundation/compat.h"
#include "foundation/compat_fs.h"
#include "foundation/compat_thread.h"
#include "foundation/platform.h"
#include <stdatomic.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
enum {
BOOTSTRAP_TEST_PATH_CAP = 1024,
BOOTSTRAP_TEST_TIMEOUT_MS = 2000,
BOOTSTRAP_TEST_SHORT_TIMEOUT_MS = 20,
};
static const char BOOTSTRAP_BUILD_A[] =
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
static const char BOOTSTRAP_BUILD_B[] =
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
typedef struct {
char parent[BOOTSTRAP_TEST_PATH_CAP];
char runtime_dir[BOOTSTRAP_TEST_PATH_CAP];
cbm_daemon_ipc_endpoint_t *endpoint;
} bootstrap_endpoint_fixture_t;
typedef struct {
atomic_int cohort_acquire_count;
atomic_int cohort_release_count;
atomic_int lock_held;
atomic_int spawn_count;
atomic_int probe_count;
atomic_int lock_attempt_count;
atomic_int handoff_count;
atomic_int diagnostic_count;
atomic_int reserved_probes_remaining;
atomic_int terminal_probes_remaining;
atomic_bool available;
atomic_bool connect_after_reserved;
atomic_bool connect_requires_unlocked;
cbm_daemon_bootstrap_probe_status_t forced_probe;
cbm_version_cohort_status_t forced_cohort;
char diagnostic[CBM_DAEMON_CONFLICT_MESSAGE_SIZE];
} bootstrap_fake_ops_t;
typedef struct {
const cbm_daemon_bootstrap_config_t *config;
const cbm_daemon_bootstrap_ops_t *ops;
atomic_int *ready;
atomic_bool *go;
cbm_daemon_bootstrap_result_t result;
cbm_daemon_bootstrap_status_t status;
} bootstrap_thread_call_t;
static cbm_daemon_build_identity_t bootstrap_identity(const char *version, const char *build) {
cbm_daemon_build_identity_t identity = {
.semantic_version = version,
.build_fingerprint = build,
.cache_fingerprint = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
.protocol_abi = 3,
.store_abi = 11,
.feature_abi = 7,
};
return identity;
}
static bool bootstrap_endpoint_fixture_start(bootstrap_endpoint_fixture_t *fixture,
const char *tag) {
memset(fixture, 0, sizeof(*fixture));
int written = snprintf(fixture->parent, sizeof(fixture->parent), "%s/cbm-bootstrap-%s-XXXXXX",
cbm_tmpdir(), tag);
if (written <= 0 || written >= (int)sizeof(fixture->parent) || !cbm_mkdtemp(fixture->parent)) {
return false;
}
fixture->endpoint = cbm_daemon_bootstrap_endpoint_new(fixture->parent);
const char *runtime_dir =
fixture->endpoint ? cbm_daemon_ipc_endpoint_runtime_dir(fixture->endpoint) : NULL;
if (!runtime_dir) {
return false;
}
written = snprintf(fixture->runtime_dir, sizeof(fixture->runtime_dir), "%s", runtime_dir);
return written > 0 && written < (int)sizeof(fixture->runtime_dir);
}
static void bootstrap_endpoint_fixture_finish(bootstrap_endpoint_fixture_t *fixture) {
cbm_daemon_ipc_endpoint_free(fixture->endpoint);
if (fixture->runtime_dir[0] != '\0') {
(void)cbm_rmdir(fixture->runtime_dir);
}
if (fixture->parent[0] != '\0') {
(void)cbm_rmdir(fixture->parent);
}
memset(fixture, 0, sizeof(*fixture));
}
static cbm_daemon_bootstrap_probe_status_t bootstrap_fake_probe(
void *opaque, const cbm_daemon_ipc_endpoint_t *endpoint,
const cbm_daemon_build_identity_t *identity, uint32_t timeout_ms,
cbm_daemon_runtime_client_t **client_out, cbm_daemon_runtime_connect_result_t *result_out) {
(void)endpoint;
(void)identity;
(void)timeout_ms;
bootstrap_fake_ops_t *fake = opaque;
atomic_fetch_add(&fake->probe_count, 1);
memset(result_out, 0, sizeof(*result_out));
*client_out = NULL;
int reserved_remaining = atomic_load(&fake->reserved_probes_remaining);
while (reserved_remaining > 0 &&
!atomic_compare_exchange_weak(&fake->reserved_probes_remaining, &reserved_remaining,
reserved_remaining - 1)) {}
if (reserved_remaining > 0) {
if (reserved_remaining == 1 && atomic_load(&fake->connect_after_reserved)) {
atomic_store(&fake->available, true);
}
return CBM_DAEMON_BOOTSTRAP_PROBE_RESERVED;
}
int terminal_remaining = atomic_load(&fake->terminal_probes_remaining);
while (terminal_remaining > 0 &&
!atomic_compare_exchange_weak(&fake->terminal_probes_remaining, &terminal_remaining,
terminal_remaining - 1)) {}
if (terminal_remaining > 0) {
return CBM_DAEMON_BOOTSTRAP_PROBE_TERMINAL;
}
if (fake->forced_probe == CBM_DAEMON_BOOTSTRAP_PROBE_RESERVED) {
return fake->forced_probe;
}
if (fake->forced_probe == CBM_DAEMON_BOOTSTRAP_PROBE_CONFLICT) {
result_out->status = CBM_DAEMON_RUNTIME_CONNECT_CONFLICT;
result_out->hello_status = CBM_DAEMON_HELLO_BUILD_CONFLICT;
snprintf(result_out->message, sizeof(result_out->message),
"CBM daemon could not start: conflicting versions");
return fake->forced_probe;
}
if (fake->forced_probe == CBM_DAEMON_BOOTSTRAP_PROBE_TERMINAL) {
return fake->forced_probe;
}
if (atomic_load(&fake->available) && atomic_load(&fake->connect_requires_unlocked) &&
atomic_load(&fake->lock_held) != 0) {
return CBM_DAEMON_BOOTSTRAP_PROBE_RESERVED;
}
if (atomic_load(&fake->available)) {
result_out->status = CBM_DAEMON_RUNTIME_CONNECT_ACCEPTED;
result_out->hello_status = CBM_DAEMON_HELLO_COMPATIBLE;
result_out->client_id = 1;
*client_out = (cbm_daemon_runtime_client_t *)(uintptr_t)1;
return CBM_DAEMON_BOOTSTRAP_PROBE_CONNECTED;
}
return CBM_DAEMON_BOOTSTRAP_PROBE_UNAVAILABLE;
}
static cbm_version_cohort_status_t bootstrap_fake_cohort_acquire(
void *opaque, const cbm_daemon_ipc_endpoint_t *endpoint,
const cbm_daemon_build_identity_t *identity, uint64_t deadline_ms,
cbm_daemon_bootstrap_cohort_t *cohort_out, cbm_daemon_conflict_t *conflict_out) {
(void)endpoint;
(void)deadline_ms;
bootstrap_fake_ops_t *fake = opaque;
atomic_fetch_add(&fake->cohort_acquire_count, 1);
*cohort_out = NULL;
memset(conflict_out, 0, sizeof(*conflict_out));
if (fake->forced_cohort == CBM_VERSION_COHORT_CONFLICT) {
cbm_daemon_build_identity_t active = bootstrap_identity("2.3.0", BOOTSTRAP_BUILD_A);
(void)cbm_daemon_hello_compare(&active, identity, conflict_out);
return fake->forced_cohort;
}
if (fake->forced_cohort != CBM_VERSION_COHORT_OK) {
return fake->forced_cohort;
}
*cohort_out = fake;
return CBM_VERSION_COHORT_OK;
}
static void bootstrap_fake_cohort_release(void *opaque, cbm_daemon_bootstrap_cohort_t cohort) {
bootstrap_fake_ops_t *fake = opaque;
if (cohort == fake) {
atomic_fetch_add(&fake->cohort_release_count, 1);
}
}
static int bootstrap_fake_lock(void *opaque, const cbm_daemon_ipc_endpoint_t *endpoint,
cbm_daemon_bootstrap_lock_t *lock_out) {
(void)endpoint;
bootstrap_fake_ops_t *fake = opaque;
atomic_fetch_add(&fake->lock_attempt_count, 1);
int expected = 0;
if (!atomic_compare_exchange_strong(&fake->lock_held, &expected, 1)) {
return 0;
}
*lock_out = fake;
return 1;
}
static bool bootstrap_fake_unlock(void *opaque, cbm_daemon_bootstrap_lock_t *lock_io) {
bootstrap_fake_ops_t *fake = opaque;
if (lock_io && *lock_io == fake) {
atomic_store(&fake->lock_held, 0);
*lock_io = NULL;
return true;
}
return lock_io && !*lock_io;
}
static bool bootstrap_fake_handoff(void *opaque, cbm_daemon_bootstrap_lock_t lock) {
bootstrap_fake_ops_t *fake = opaque;
if (lock != fake || atomic_load(&fake->lock_held) != 1) {
return false;
}
atomic_fetch_add(&fake->handoff_count, 1);
return true;
}
static bool bootstrap_fake_spawn(void *opaque, const cbm_daemon_bootstrap_launch_spec_t *spec) {
bootstrap_fake_ops_t *fake = opaque;
/* Client bootstrap must only ever spawn the EPHEMERAL two-argument
* shape; the permanent shape belongs exclusively to `daemon start`. */
bool exact = spec && spec->argc == 2U && spec->argv[0] &&
spec->argv[1] && !spec->argv[2] &&
strcmp(spec->argv[1], CBM_DAEMON_INTERNAL_ARG) == 0 && spec->detached &&
!spec->inherit_standard_handles && !spec->use_shell &&
atomic_load(&fake->handoff_count) > 0 && atomic_load(&fake->lock_held) == 1;
if (!exact) {
return false;
}
atomic_fetch_add(&fake->spawn_count, 1);
atomic_store(&fake->available, true);
return true;
}
static void bootstrap_fake_diagnostic(void *opaque, const char *message) {
bootstrap_fake_ops_t *fake = opaque;
atomic_fetch_add(&fake->diagnostic_count, 1);
snprintf(fake->diagnostic, sizeof(fake->diagnostic), "%s", message ? message : "");
}
static cbm_daemon_bootstrap_ops_t bootstrap_fake_callbacks(bootstrap_fake_ops_t *fake) {
cbm_daemon_bootstrap_ops_t ops = {
.context = fake,
.cohort_acquire = bootstrap_fake_cohort_acquire,
.cohort_release = bootstrap_fake_cohort_release,
.probe = bootstrap_fake_probe,
.startup_lock_try_acquire = bootstrap_fake_lock,
.startup_lock_prepare_handoff = bootstrap_fake_handoff,
.startup_lock_release = bootstrap_fake_unlock,
.spawn_daemon = bootstrap_fake_spawn,
.visible_diagnostic = bootstrap_fake_diagnostic,
};
return ops;
}
static void *bootstrap_thread_execute(void *opaque) {
bootstrap_thread_call_t *call = opaque;
atomic_fetch_add(call->ready, 1);
while (!atomic_load(call->go)) {
const struct timespec pause = {0, 1000000L};
(void)cbm_nanosleep(&pause, NULL);
}
call->status = cbm_daemon_bootstrap_execute_with_ops(call->config, call->ops, &call->result);
return NULL;
}
static cbm_daemon_process_role_t classify(int argc, char **argv) {
return cbm_daemon_process_role(argc, argv);
}
TEST(daemon_bootstrap_classifies_default_and_ui_as_mcp_clients) {
char *plain[] = {"codebase-memory-mcp", NULL};
char *ui[] = {"codebase-memory-mcp", "--ui=true", "--port=9750", NULL};
ASSERT_EQ(classify(1, plain), CBM_DAEMON_PROCESS_MCP_CLIENT);
ASSERT_EQ(classify(3, ui), CBM_DAEMON_PROCESS_MCP_CLIENT);
ASSERT_TRUE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_MCP_CLIENT));
PASS();
}
TEST(daemon_bootstrap_classifies_stateless_commands_without_client) {
char *version[] = {"codebase-memory-mcp", "--version", NULL};
char *help[] = {"codebase-memory-mcp", "--profile", "--help", NULL};
char *install[] = {"codebase-memory-mcp", "install", "--dry-run", NULL};
char *uninstall[] = {"codebase-memory-mcp", "uninstall", NULL};
char *update[] = {"codebase-memory-mcp", "update", "-n", NULL};
ASSERT_EQ(classify(2, version), CBM_DAEMON_PROCESS_STATELESS);
ASSERT_EQ(classify(3, help), CBM_DAEMON_PROCESS_STATELESS);
ASSERT_EQ(classify(3, install), CBM_DAEMON_PROCESS_STATELESS);
ASSERT_EQ(classify(2, uninstall), CBM_DAEMON_PROCESS_STATELESS);
ASSERT_EQ(classify(3, update), CBM_DAEMON_PROCESS_STATELESS);
ASSERT_FALSE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_STATELESS));
PASS();
}
TEST(daemon_bootstrap_classifies_config_as_coordinated_local_cli) {
char *list[] = {"codebase-memory-mcp", "config", "list", NULL};
char *set[] = {"codebase-memory-mcp", "config", "set", "auto_watch", "false", NULL};
char *help[] = {"codebase-memory-mcp", "config", "--help", NULL};
ASSERT_EQ(classify(3, list), CBM_DAEMON_PROCESS_LOCAL_CLI);
ASSERT_EQ(classify(5, set), CBM_DAEMON_PROCESS_LOCAL_CLI);
ASSERT_EQ(classify(3, help), CBM_DAEMON_PROCESS_STATELESS);
ASSERT_FALSE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_LOCAL_CLI));
PASS();
}
TEST(daemon_bootstrap_cli_help_is_stateless_but_tool_calls_are_local) {
char *tool_help[] = {"codebase-memory-mcp", "cli", "search_graph", "--help", NULL};
char *tool_call[] = {"codebase-memory-mcp", "cli", "search_graph", "{}", NULL};
ASSERT_EQ(classify(4, tool_help), CBM_DAEMON_PROCESS_STATELESS);
ASSERT_EQ(classify(4, tool_call), CBM_DAEMON_PROCESS_LOCAL_CLI);
ASSERT_FALSE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_LOCAL_CLI));
PASS();
}
TEST(daemon_bootstrap_cli_arguments_cannot_reclassify_the_process) {
char *install_value[] = {
"codebase-memory-mcp", "cli", "search_code", "--query", "install", NULL};
char *version_value[] = {"codebase-memory-mcp", "cli", "search_code", "--query",
"--version", NULL};
ASSERT_EQ(classify(5, install_value), CBM_DAEMON_PROCESS_LOCAL_CLI);
ASSERT_EQ(classify(5, version_value), CBM_DAEMON_PROCESS_LOCAL_CLI);
PASS();
}
TEST(daemon_bootstrap_internal_roles_never_take_client_leases) {
static char build[] = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
char *daemon[] = {"codebase-memory-mcp", CBM_DAEMON_INTERNAL_ARG, NULL};
char *worker[] = {"codebase-memory-mcp", "cli", "--index-worker", "--index-worker-build", build,
"index_repository", "{}", "--response-out", "/tmp/response", NULL};
char *malformed_worker[] = {"codebase-memory-mcp", "cli", "--index-worker",
"index_repository", "{}", NULL};
char *reserved_user_value[] = {"codebase-memory-mcp", "cli", "search_code", "--query",
"--index-worker", NULL};
char *hook[] = {"codebase-memory-mcp", "hook-augment", NULL};
ASSERT_EQ(classify(2, daemon), CBM_DAEMON_PROCESS_DAEMON);
ASSERT_EQ(classify(9, worker), CBM_DAEMON_PROCESS_WORKER);
ASSERT_EQ(classify(5, malformed_worker), CBM_DAEMON_PROCESS_INVALID);
ASSERT_EQ(classify(5, reserved_user_value), CBM_DAEMON_PROCESS_INVALID);
ASSERT_EQ(classify(2, hook), CBM_DAEMON_PROCESS_HOOK_CLIENT);
ASSERT_FALSE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_DAEMON));
ASSERT_FALSE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_WORKER));
ASSERT_TRUE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_HOOK_CLIENT));
PASS();
}
TEST(daemon_bootstrap_rejects_ambiguous_internal_daemon_argv) {
char *missing[] = {NULL};
char *mixed[] = {"codebase-memory-mcp", CBM_DAEMON_INTERNAL_ARG, "cli", NULL};
ASSERT_EQ(classify(0, missing), CBM_DAEMON_PROCESS_INVALID);
ASSERT_EQ(classify(3, mixed), CBM_DAEMON_PROCESS_INVALID);
ASSERT_FALSE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_INVALID));
PASS();
}
TEST(daemon_bootstrap_uses_one_stable_per_account_endpoint) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "stable-endpoint"));
cbm_daemon_ipc_endpoint_t *second = cbm_daemon_bootstrap_endpoint_new(fixture.parent);
ASSERT_NOT_NULL(second);
ASSERT_STR_EQ(cbm_daemon_ipc_endpoint_address(fixture.endpoint),
cbm_daemon_ipc_endpoint_address(second));
cbm_daemon_ipc_endpoint_free(second);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
TEST(daemon_bootstrap_launches_only_exact_detached_hidden_role) {
cbm_daemon_bootstrap_launch_spec_t spec;
ASSERT_TRUE(cbm_daemon_bootstrap_launch_spec_init("/tmp/cbm exact", &spec));
ASSERT_EQ(spec.argc, 2U);
ASSERT_STR_EQ(spec.executable_path, "/tmp/cbm exact");
ASSERT_STR_EQ(spec.argv[0], "/tmp/cbm exact");
ASSERT_STR_EQ(spec.argv[1], CBM_DAEMON_INTERNAL_ARG);
ASSERT_NULL(spec.argv[2]);
ASSERT_TRUE(spec.detached);
ASSERT_FALSE(spec.inherit_standard_handles);
ASSERT_FALSE(spec.use_shell);
PASS();
}
TEST(daemon_bootstrap_permanent_daemon_argv_is_byte_exact) {
char *permanent[] = {"codebase-memory-mcp", CBM_DAEMON_INTERNAL_ARG, CBM_DAEMON_PERMANENT_ARG,
NULL};
char *reordered[] = {"codebase-memory-mcp", CBM_DAEMON_PERMANENT_ARG, CBM_DAEMON_INTERNAL_ARG,
NULL};
char *repeated[] = {"codebase-memory-mcp", CBM_DAEMON_INTERNAL_ARG, CBM_DAEMON_INTERNAL_ARG,
NULL};
char *extended[] = {"codebase-memory-mcp", CBM_DAEMON_INTERNAL_ARG, CBM_DAEMON_PERMANENT_ARG,
"extra", NULL};
char *wrong_flag[] = {"codebase-memory-mcp", CBM_DAEMON_INTERNAL_ARG, "--permanent", NULL};
ASSERT_EQ(classify(3, permanent), CBM_DAEMON_PROCESS_DAEMON);
ASSERT_EQ(classify(3, reordered), CBM_DAEMON_PROCESS_INVALID);
ASSERT_EQ(classify(3, repeated), CBM_DAEMON_PROCESS_INVALID);
ASSERT_EQ(classify(4, extended), CBM_DAEMON_PROCESS_INVALID);
ASSERT_EQ(classify(3, wrong_flag), CBM_DAEMON_PROCESS_INVALID);
PASS();
}
TEST(daemon_bootstrap_daemon_ctl_token_routes_after_cli) {
char *start[] = {"codebase-memory-mcp", "daemon", "start", NULL};
char *stop[] = {"codebase-memory-mcp", "daemon", "stop", NULL};
char *status[] = {"codebase-memory-mcp", "daemon", "status", NULL};
char *help[] = {"codebase-memory-mcp", "daemon", "--help", NULL};
/* `daemon` after `cli` is opaque tool input, never a control command. */
char *opaque[] = {"codebase-memory-mcp", "cli", "search_code", "daemon", "start", NULL};
ASSERT_EQ(classify(3, start), CBM_DAEMON_PROCESS_DAEMON_CTL);
ASSERT_EQ(classify(3, stop), CBM_DAEMON_PROCESS_DAEMON_CTL);
ASSERT_EQ(classify(3, status), CBM_DAEMON_PROCESS_DAEMON_CTL);
ASSERT_EQ(classify(3, help), CBM_DAEMON_PROCESS_STATELESS);
ASSERT_EQ(classify(5, opaque), CBM_DAEMON_PROCESS_LOCAL_CLI);
ASSERT_FALSE(cbm_daemon_process_role_requires_client(CBM_DAEMON_PROCESS_DAEMON_CTL));
PASS();
}
TEST(daemon_bootstrap_permanent_launch_spec_is_exact) {
cbm_daemon_bootstrap_launch_spec_t spec;
ASSERT_TRUE(cbm_daemon_bootstrap_launch_spec_init_permanent("/tmp/cbm exact", &spec));
ASSERT_EQ(spec.argc, 3U);
ASSERT_STR_EQ(spec.argv[0], "/tmp/cbm exact");
ASSERT_STR_EQ(spec.argv[1], CBM_DAEMON_INTERNAL_ARG);
ASSERT_STR_EQ(spec.argv[2], CBM_DAEMON_PERMANENT_ARG);
ASSERT_NULL(spec.argv[3]);
ASSERT_TRUE(spec.detached);
ASSERT_FALSE(spec.inherit_standard_handles);
ASSERT_FALSE(spec.use_shell);
PASS();
}
TEST(daemon_bootstrap_stateless_roles_bypass_every_daemon_operation) {
bootstrap_fake_ops_t fake = {0};
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_STATELESS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_BYPASSED);
ASSERT_EQ(result.status, CBM_DAEMON_BOOTSTRAP_BYPASSED);
ASSERT_EQ(atomic_load(&fake.cohort_acquire_count), 0);
ASSERT_EQ(atomic_load(&fake.probe_count), 0);
ASSERT_EQ(atomic_load(&fake.spawn_count), 0);
ASSERT_EQ(atomic_load(&fake.diagnostic_count), 0);
PASS();
}
TEST(daemon_bootstrap_cohort_conflict_is_visible_before_probe_or_spawn) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "cohort-conflict"));
bootstrap_fake_ops_t fake = {0};
fake.forced_cohort = CBM_VERSION_COHORT_CONFLICT;
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_B);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 50,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_CONFLICT);
ASSERT_EQ(result.status, CBM_DAEMON_BOOTSTRAP_CONFLICT);
ASSERT_EQ(atomic_load(&fake.cohort_acquire_count), 1);
ASSERT_EQ(atomic_load(&fake.cohort_release_count), 0);
ASSERT_EQ(atomic_load(&fake.probe_count), 0);
ASSERT_EQ(atomic_load(&fake.lock_attempt_count), 0);
ASSERT_EQ(atomic_load(&fake.spawn_count), 0);
ASSERT_EQ(atomic_load(&fake.diagnostic_count), 1);
ASSERT_NOT_NULL(strstr(fake.diagnostic, "conflicting CBM process is active"));
ASSERT_NOT_NULL(strstr(fake.diagnostic, "Close all CBM sessions and commands"));
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
TEST(daemon_bootstrap_existing_exact_daemon_connects_without_spawn) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "existing"));
bootstrap_fake_ops_t fake = {0};
atomic_store(&fake.available, true);
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_A);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 50,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_EQ(result.status, CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_NOT_NULL(result.client);
ASSERT_FALSE(result.daemon_spawned);
ASSERT_EQ(atomic_load(&fake.spawn_count), 0);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
TEST(daemon_bootstrap_conflict_is_visible_and_never_spawns) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "conflict"));
bootstrap_fake_ops_t fake = {0};
fake.forced_probe = CBM_DAEMON_BOOTSTRAP_PROBE_CONFLICT;
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_B);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 50,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_CONFLICT);
ASSERT_EQ(result.status, CBM_DAEMON_BOOTSTRAP_CONFLICT);
ASSERT_NULL(result.client);
ASSERT_EQ(atomic_load(&fake.spawn_count), 0);
ASSERT_EQ(atomic_load(&fake.diagnostic_count), 1);
ASSERT_NOT_NULL(strstr(fake.diagnostic, "conflicting versions"));
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
TEST(daemon_bootstrap_terminal_generation_that_never_exits_is_not_replaced) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "terminal"));
bootstrap_fake_ops_t fake = {0};
fake.forced_probe = CBM_DAEMON_BOOTSTRAP_PROBE_TERMINAL;
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_A);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_HOOK_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 1,
.startup_timeout_ms = BOOTSTRAP_TEST_SHORT_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_FAILED);
ASSERT_EQ(atomic_load(&fake.lock_held), 0);
ASSERT_EQ(atomic_load(&fake.spawn_count), 0);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
/* RED for final-session/new-session overlap: STOPPING is a temporary state of
* the previous same-build generation. Once that generation disappears, the
* already-running bootstrap attempt must serialize and become the new first
* client instead of forcing the coding agent to restart its MCP process. */
TEST(daemon_bootstrap_terminal_then_absent_spawns_replacement) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "terminal-absent"));
bootstrap_fake_ops_t fake = {0};
atomic_store(&fake.terminal_probes_remaining, 1);
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_A);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 1,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_TRUE(result.daemon_spawned);
ASSERT_EQ(atomic_load(&fake.spawn_count), 1);
ASSERT(atomic_load(&fake.lock_attempt_count) >= 1);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
TEST(daemon_bootstrap_reserved_generation_becomes_connectable_without_spawn) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "reserved-connect"));
bootstrap_fake_ops_t fake = {0};
atomic_store(&fake.reserved_probes_remaining, 2);
atomic_store(&fake.connect_after_reserved, true);
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_A);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 1,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_EQ(result.status, CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_FALSE(result.daemon_spawned);
ASSERT_EQ(atomic_load(&fake.lock_attempt_count), 0);
ASSERT_EQ(atomic_load(&fake.spawn_count), 0);
ASSERT(atomic_load(&fake.probe_count) >= 3);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
/* RED for the equivalent race when the old listener vanishes without first
* returning the explicit STOPPING response. Startup serialization decides
* whether absence is now safe; a historical RESERVED sample is not sticky. */
TEST(daemon_bootstrap_reserved_then_absent_spawns_replacement) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "reserved-absent"));
bootstrap_fake_ops_t fake = {0};
atomic_store(&fake.reserved_probes_remaining, 1);
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_A);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 1,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_EQ(result.status, CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_TRUE(result.daemon_spawned);
ASSERT(atomic_load(&fake.lock_attempt_count) >= 1);
ASSERT_EQ(atomic_load(&fake.spawn_count), 1);
ASSERT(atomic_load(&fake.probe_count) > 1);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
/* RED for the native Windows lock order: after spawn, the generation claim or
* lifetime reservation becomes visible before the client can connect. Daemon
* participant teardown needs startup ownership, so bootstrap must release its
* handoff once that generation is observable. */
TEST(daemon_bootstrap_releases_handoff_when_spawned_generation_is_reserved) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "spawn-admission"));
bootstrap_fake_ops_t fake = {0};
atomic_store(&fake.connect_requires_unlocked, true);
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_A);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 1,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
ASSERT_EQ(cbm_daemon_bootstrap_execute_with_ops(&config, &ops, &result),
CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_EQ(result.status, CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_TRUE(result.daemon_spawned);
ASSERT_NOT_NULL(result.client);
ASSERT_EQ(atomic_load(&fake.spawn_count), 1);
ASSERT_EQ(atomic_load(&fake.lock_held), 0);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
TEST(daemon_bootstrap_rejected_connect_is_reserved_and_never_unavailable) {
cbm_daemon_runtime_connect_result_t capacity = {0};
capacity.status = CBM_DAEMON_RUNTIME_CONNECT_REJECTED;
snprintf(capacity.message, sizeof(capacity.message), "CBM daemon connection capacity reached");
ASSERT_EQ(cbm_daemon_bootstrap_classify_failed_connect(&capacity, 1),
CBM_DAEMON_BOOTSTRAP_PROBE_RESERVED);
ASSERT_EQ(cbm_daemon_bootstrap_classify_failed_connect(&capacity, 0),
CBM_DAEMON_BOOTSTRAP_PROBE_RESERVED);
ASSERT_EQ(cbm_daemon_bootstrap_classify_failed_connect(&capacity, -1),
CBM_DAEMON_BOOTSTRAP_PROBE_RESERVED);
cbm_daemon_runtime_connect_result_t stopping = capacity;
snprintf(stopping.message, sizeof(stopping.message), "CBM daemon is stopping");
ASSERT_EQ(cbm_daemon_bootstrap_classify_failed_connect(&stopping, 1),
CBM_DAEMON_BOOTSTRAP_PROBE_TERMINAL);
cbm_daemon_runtime_connect_result_t absent = {0};
absent.status = CBM_DAEMON_RUNTIME_CONNECT_ERROR;
ASSERT_EQ(cbm_daemon_bootstrap_classify_failed_connect(&absent, 1),
CBM_DAEMON_BOOTSTRAP_PROBE_RESERVED);
ASSERT_EQ(cbm_daemon_bootstrap_classify_failed_connect(&absent, 0),
CBM_DAEMON_BOOTSTRAP_PROBE_UNAVAILABLE);
ASSERT_EQ(cbm_daemon_bootstrap_classify_failed_connect(&absent, -1),
CBM_DAEMON_BOOTSTRAP_PROBE_ERROR);
PASS();
}
TEST(daemon_bootstrap_concurrent_first_clients_spawn_one_daemon) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "startup-race"));
bootstrap_fake_ops_t fake = {0};
cbm_daemon_bootstrap_ops_t ops = bootstrap_fake_callbacks(&fake);
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_A);
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = "/tmp/cbm",
.connect_timeout_ms = 10,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
atomic_int ready = 0;
atomic_bool go = false;
bootstrap_thread_call_t calls[2] = {
{.config = &config, .ops = &ops, .ready = &ready, .go = &go},
{.config = &config, .ops = &ops, .ready = &ready, .go = &go},
};
cbm_thread_t threads[2];
ASSERT_EQ(cbm_thread_create(&threads[0], 0, bootstrap_thread_execute, &calls[0]), 0);
ASSERT_EQ(cbm_thread_create(&threads[1], 0, bootstrap_thread_execute, &calls[1]), 0);
uint64_t ready_deadline = cbm_now_ms() + BOOTSTRAP_TEST_TIMEOUT_MS;
while (atomic_load(&ready) != 2 && cbm_now_ms() < ready_deadline) {
const struct timespec pause = {0, 1000000L};
(void)cbm_nanosleep(&pause, NULL);
}
atomic_store(&go, true);
ASSERT_EQ(cbm_thread_join(&threads[0]), 0);
ASSERT_EQ(cbm_thread_join(&threads[1]), 0);
ASSERT_EQ(calls[0].status, CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_EQ(calls[1].status, CBM_DAEMON_BOOTSTRAP_CONNECTED);
ASSERT_EQ(atomic_load(&fake.spawn_count), 1);
ASSERT_TRUE(calls[0].result.daemon_spawned != calls[1].result.daemon_spawned);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
#ifdef __APPLE__
/* RED: the old double-fork returned success before its grandchild attempted
* posix_spawn, hiding an immediate launch error behind the full timeout. */
TEST(daemon_bootstrap_darwin_launch_failure_is_synchronous) {
bootstrap_endpoint_fixture_t fixture;
ASSERT_TRUE(bootstrap_endpoint_fixture_start(&fixture, "darwin-missing"));
cbm_daemon_build_identity_t identity = bootstrap_identity("2.4.0", BOOTSTRAP_BUILD_A);
char missing[BOOTSTRAP_TEST_PATH_CAP];
int written = snprintf(missing, sizeof(missing), "%s/definitely-missing-cbm", fixture.parent);
ASSERT(written > 0 && written < (int)sizeof(missing));
cbm_daemon_bootstrap_config_t config = {
.role = CBM_DAEMON_PROCESS_MCP_CLIENT,
.endpoint = fixture.endpoint,
.identity = &identity,
.executable_path = missing,
.connect_timeout_ms = 1,
.startup_timeout_ms = BOOTSTRAP_TEST_TIMEOUT_MS,
};
cbm_daemon_bootstrap_result_t result;
uint64_t started = cbm_now_ms();
ASSERT_EQ(cbm_daemon_bootstrap_execute(&config, &result), CBM_DAEMON_BOOTSTRAP_FAILED);
uint64_t elapsed = cbm_now_ms() - started;
ASSERT_FALSE(result.daemon_spawned);
ASSERT(elapsed < BOOTSTRAP_TEST_TIMEOUT_MS / 2U);
bootstrap_endpoint_fixture_finish(&fixture);
PASS();
}
#endif
SUITE(daemon_bootstrap) {
RUN_TEST(daemon_bootstrap_classifies_default_and_ui_as_mcp_clients);
RUN_TEST(daemon_bootstrap_classifies_stateless_commands_without_client);
RUN_TEST(daemon_bootstrap_classifies_config_as_coordinated_local_cli);
RUN_TEST(daemon_bootstrap_cli_help_is_stateless_but_tool_calls_are_local);
RUN_TEST(daemon_bootstrap_cli_arguments_cannot_reclassify_the_process);
RUN_TEST(daemon_bootstrap_internal_roles_never_take_client_leases);
RUN_TEST(daemon_bootstrap_rejects_ambiguous_internal_daemon_argv);
RUN_TEST(daemon_bootstrap_uses_one_stable_per_account_endpoint);
RUN_TEST(daemon_bootstrap_launches_only_exact_detached_hidden_role);
RUN_TEST(daemon_bootstrap_permanent_daemon_argv_is_byte_exact);
RUN_TEST(daemon_bootstrap_daemon_ctl_token_routes_after_cli);
RUN_TEST(daemon_bootstrap_permanent_launch_spec_is_exact);
RUN_TEST(daemon_bootstrap_stateless_roles_bypass_every_daemon_operation);
RUN_TEST(daemon_bootstrap_cohort_conflict_is_visible_before_probe_or_spawn);
RUN_TEST(daemon_bootstrap_existing_exact_daemon_connects_without_spawn);
RUN_TEST(daemon_bootstrap_conflict_is_visible_and_never_spawns);
RUN_TEST(daemon_bootstrap_terminal_generation_that_never_exits_is_not_replaced);
RUN_TEST(daemon_bootstrap_terminal_then_absent_spawns_replacement);
RUN_TEST(daemon_bootstrap_reserved_generation_becomes_connectable_without_spawn);
RUN_TEST(daemon_bootstrap_reserved_then_absent_spawns_replacement);
RUN_TEST(daemon_bootstrap_releases_handoff_when_spawned_generation_is_reserved);
RUN_TEST(daemon_bootstrap_rejected_connect_is_reserved_and_never_unavailable);
RUN_TEST(daemon_bootstrap_concurrent_first_clients_spawn_one_daemon);
#ifdef __APPLE__
RUN_TEST(daemon_bootstrap_darwin_launch_failure_is_synchronous);
#endif
}