config: Set automatic dependency-source indexing disabled by default

Define CBM_DEFAULT_AUTO_INDEX_DEPS and use it in depindex, MCP request handling, hook guidance, and the config registry. Replace the two quality presets with four exact streamlined/classic presets that state whether automatic installed dependency-source indexing is enabled. Keep rank and optional-graph benchmark ablations on the dependency-disabled baseline.

Document that index_dependencies remains available and disabling automation does not delete stored dependency projects.

Verification: CBM_ONLY_SUITE=cli make -f Makefile.cbm test (243 passed); CBM_ONLY_SUITE=depindex make -f Makefile.cbm test (40 passed); CBM_ONLY_SUITE=input_validation make -f Makefile.cbm test (56 passed).
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
This commit is contained in:
Andrew Hundt
2026-07-22 15:17:40 -04:00
parent 4950cc7268
commit 79ae9437f2
10 changed files with 247 additions and 134 deletions
+5 -1
View File
@@ -508,6 +508,8 @@ codebase-memory-mcp config set tool_mode streamlined # concise surface; reve
codebase-memory-mcp config set auto_index_deps true # index installed dependency APIs
codebase-memory-mcp config set auto_dep_limit 20 # import-ranked dependency package cap; 0=unlimited
codebase-memory-mcp config preset list # list named capability/API configurations
codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-disabled
codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-enabled
codebase-memory-mcp config set auto_watch false # don't register background git watcher (default: true)
codebase-memory-mcp config set default_response_format json # full JSON objects instead of compact TOON tables
codebase-memory-mcp config reset auto_index # reset to default
@@ -520,7 +522,9 @@ indexing and first-response codebase context are automatic when configured. Use
directly and uses `search_graph`, then `trace_path`, then `get_code_snippet` for
structural discovery. Automatic repository indexing obeys
`auto_index`/`auto_index_limit`; automatic dependency indexing obeys
`auto_index_deps`/`auto_dep_limit`.
`auto_index_deps`/`auto_dep_limit` and is disabled by default. Explicit
`index_dependencies` calls remain available; disabling automation does not delete
dependency projects that are already indexed.
### Environment Variables
+16 -10
View File
@@ -86,7 +86,7 @@ for any registry key):
| `tool_mode` | `streamlined` | MCP discovery surface: `streamlined` or `classic`. |
| `context_injection` | `true` | Include codebase schema and stats automatically in the first `search_graph` response. |
| `rank_enabled` | `true` | Compute PageRank, LinkRank, and degree views used by relevance ranking. |
| `auto_index_deps` | `true` | Index installed dependency APIs for cross-package search and tracing. |
| `auto_index_deps` | `false` | Automatically index installed dependency source for cross-package search and tracing. |
| `auto_dep_limit` | `20` | Import-ranked automatic dependency package cap; `0` is unlimited. |
| `similarity_enabled` | `true` | Create MinHash similarity edges in applicable index modes. |
| `semantic_edges_enabled` | `true` | Create semantic-related edges in applicable index modes. |
@@ -107,17 +107,23 @@ silently leak into a comparison:
```bash
codebase-memory-mcp config preset list
codebase-memory-mcp config preset apply streamlined-quality
codebase-memory-mcp config preset apply classic-quality
codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-disabled
codebase-memory-mcp config preset apply streamlined-automatic-dependency-source-indexing-enabled
codebase-memory-mcp config preset apply classic-automatic-dependency-source-indexing-disabled
codebase-memory-mcp config preset apply classic-automatic-dependency-source-indexing-enabled
```
`streamlined-quality` is the recommended default surface with all measured quality
capabilities enabled. `classic-quality` changes only the API discovery surface while
retaining those capabilities. The `rank-disabled`, `dependency-disabled`,
`optional-graph-disabled`, and `minimal-indexing` presets are explicit ablations;
the CLI labels them as quality tradeoffs when applied. Environment variables remain
higher priority than stored preset values, and the command returns nonzero with a
warning when an active override prevents the requested effective configuration.
The four product presets pair the `streamlined` or `classic` tool surface with an
explicit automatic dependency-source indexing state. All four enable the same rank,
similarity, semantic-edge, Git-history, and HTTP-link capabilities. The disabled
variants bound default indexing latency, CPU, memory, and stored graph size; the
enabled variants add installed dependency-source coverage up to `auto_dep_limit`.
`index_dependencies` remains available for explicit packages. Disabling automation
stops future automatic dependency indexing but does not delete dependency projects
already indexed. `rank-disabled`, `optional-graph-disabled`, and `minimal-indexing`
are benchmark ablations, and the CLI labels them accordingly. Environment variables
remain higher priority than stored preset values, and preset application returns
nonzero when an active override prevents the requested effective configuration.
## 3. UI Settings
+52 -55
View File
@@ -9978,80 +9978,75 @@ typedef struct {
const char *description;
const cbm_config_preset_value_t *values;
size_t value_count;
bool quality_tradeoff;
bool benchmark_ablation;
} cbm_config_preset_t;
#define PRESET_VALUE(key_, value_) {key_, value_}
#define PRESET_COUNT(values_) (sizeof(values_) / sizeof((values_)[0]))
#define PRESET_QUALITY_VALUES(auto_index_deps_, rank_, similarity_, semantic_, git_, http_) \
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, rank_), \
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, auto_index_deps_), \
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, similarity_), \
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, semantic_), \
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, git_), \
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, http_)
static const cbm_config_preset_value_t PRESET_STREAMLINED_QUALITY[] = {
static const cbm_config_preset_value_t PRESET_STREAMLINED_DEPS_DISABLED[] = {
PRESET_VALUE(CBM_CONFIG_TOOL_MODE, CBM_CONFIG_TOOL_MODE_STREAMLINED),
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "true"),
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "true"),
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "true", "true", "true",
"true", "true"),
};
static const cbm_config_preset_value_t PRESET_CLASSIC_QUALITY[] = {
static const cbm_config_preset_value_t PRESET_STREAMLINED_DEPS_ENABLED[] = {
PRESET_VALUE(CBM_CONFIG_TOOL_MODE, CBM_CONFIG_TOOL_MODE_STREAMLINED),
PRESET_QUALITY_VALUES("true", "true", "true", "true", "true", "true"),
};
static const cbm_config_preset_value_t PRESET_CLASSIC_DEPS_DISABLED[] = {
PRESET_VALUE(CBM_CONFIG_TOOL_MODE, CBM_CONFIG_TOOL_MODE_CLASSIC),
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "true"),
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "true"),
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "true", "true", "true",
"true", "true"),
};
static const cbm_config_preset_value_t PRESET_CLASSIC_DEPS_ENABLED[] = {
PRESET_VALUE(CBM_CONFIG_TOOL_MODE, CBM_CONFIG_TOOL_MODE_CLASSIC),
PRESET_QUALITY_VALUES("true", "true", "true", "true", "true", "true"),
};
static const cbm_config_preset_value_t PRESET_RANK_DISABLED[] = {
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "true"),
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "true"),
};
static const cbm_config_preset_value_t PRESET_DEPENDENCY_DISABLED[] = {
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "false"),
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "true"),
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "true"),
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "false", "true", "true", "true",
"true"),
};
static const cbm_config_preset_value_t PRESET_OPTIONAL_GRAPH_DISABLED[] = {
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "true"),
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "false"),
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "false", "false", "false", "false",
"false"),
};
static const cbm_config_preset_value_t PRESET_MINIMAL_INDEXING[] = {
PRESET_VALUE(CBM_CONFIG_RANK_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_AUTO_INDEX_DEPS, "false"),
PRESET_VALUE(CBM_CONFIG_SIMILARITY_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_GITHISTORY_ENABLED, "false"),
PRESET_VALUE(CBM_CONFIG_HTTPLINKS_ENABLED, "false"),
PRESET_QUALITY_VALUES(CBM_DEFAULT_AUTO_INDEX_DEPS_STR, "false", "false", "false", "false",
"false"),
};
static const cbm_config_preset_t CBM_CONFIG_PRESETS[] = {
{"streamlined-quality", "recommended streamlined API with all measured quality capabilities",
PRESET_STREAMLINED_QUALITY, PRESET_COUNT(PRESET_STREAMLINED_QUALITY), false},
{"classic-quality", "classic API with the same full-quality graph capabilities",
PRESET_CLASSIC_QUALITY, PRESET_COUNT(PRESET_CLASSIC_QUALITY), false},
{"streamlined-automatic-dependency-source-indexing-disabled",
"streamlined API; automatic installed dependency-source indexing disabled",
PRESET_STREAMLINED_DEPS_DISABLED, PRESET_COUNT(PRESET_STREAMLINED_DEPS_DISABLED), false},
{"streamlined-automatic-dependency-source-indexing-enabled",
"streamlined API; automatic installed dependency-source indexing enabled",
PRESET_STREAMLINED_DEPS_ENABLED, PRESET_COUNT(PRESET_STREAMLINED_DEPS_ENABLED), false},
{"classic-automatic-dependency-source-indexing-disabled",
"classic API; automatic installed dependency-source indexing disabled",
PRESET_CLASSIC_DEPS_DISABLED, PRESET_COUNT(PRESET_CLASSIC_DEPS_DISABLED), false},
{"classic-automatic-dependency-source-indexing-enabled",
"classic API; automatic installed dependency-source indexing enabled",
PRESET_CLASSIC_DEPS_ENABLED, PRESET_COUNT(PRESET_CLASSIC_DEPS_ENABLED), false},
{"rank-disabled", "exact PageRank/LinkRank ablation; lowers measured ranking quality",
PRESET_RANK_DISABLED, PRESET_COUNT(PRESET_RANK_DISABLED), true},
{"dependency-disabled", "exact dependency-indexing ablation; removes dependency API results",
PRESET_DEPENDENCY_DISABLED, PRESET_COUNT(PRESET_DEPENDENCY_DISABLED), true},
{"optional-graph-disabled", "disable optional graph passes but retain dependency indexing",
{"optional-graph-disabled",
"disable optional graph passes; dependency-source automation stays disabled",
PRESET_OPTIONAL_GRAPH_DISABLED, PRESET_COUNT(PRESET_OPTIONAL_GRAPH_DISABLED), true},
{"minimal-indexing", "lowest measured indexing cost; disables rank and dependency results",
{"minimal-indexing", "disable optional graph passes and dependency-source automation",
PRESET_MINIMAL_INDEXING, PRESET_COUNT(PRESET_MINIMAL_INDEXING), true},
{NULL, NULL, NULL, 0, false},
};
@@ -10090,7 +10085,7 @@ static void cbm_config_print_presets(void) {
printf("Named presets (applied atomically):\n");
for (size_t i = 0; CBM_CONFIG_PRESETS[i].name; i++) {
printf(" %-24s %s%s\n", CBM_CONFIG_PRESETS[i].name, CBM_CONFIG_PRESETS[i].description,
CBM_CONFIG_PRESETS[i].quality_tradeoff ? " [quality tradeoff]" : "");
CBM_CONFIG_PRESETS[i].benchmark_ablation ? " [benchmark ablation]" : "");
}
}
@@ -10534,11 +10529,13 @@ const cbm_config_entry_t CBM_CONFIG_REGISTRY[] = {
"'unweighted' = raw connection count regardless of type. "
"'calls_only' = only count direct function call connections — best for finding the most-called functions."},
/* ── Dependencies ── */
{"auto_index_deps", "true", NULL, "Dependencies",
"Auto-index installed packages from package.json, Cargo.toml, go.mod, etc.",
{CBM_CONFIG_AUTO_INDEX_DEPS, CBM_DEFAULT_AUTO_INDEX_DEPS_STR, NULL, "Dependencies",
"Automatically index installed dependency source for cross-package search and tracing",
"true|false",
"Enable to trace calls into dependencies (e.g. find all callers of a library function). "
"Disable for faster indexing when cross-package search is not needed."},
"Disabled by default to bound indexing latency, CPU, memory, and stored graph size. Enable when "
"automatic dependency-source coverage is worth that cost; auto_dep_limit bounds each discovery "
"pass. index_dependencies remains available for explicit packages. Disabling this setting stops "
"future automatic dependency indexing; it does not delete dependency projects already indexed."},
{CBM_CONFIG_AUTO_DEP_LIMIT, CBM_STRINGIFY(CBM_DEFAULT_AUTO_DEP_LIMIT), NULL, "Dependencies",
"Max number of packages to auto-index",
"0-10000",
+3 -3
View File
@@ -1158,7 +1158,7 @@ static ha_guidance_config_t ha_load_guidance_config(void) {
.auto_index = true,
.context_injection = true,
.auto_watch = true,
.auto_index_deps = true,
.auto_index_deps = CBM_DEFAULT_AUTO_INDEX_DEPS,
.auto_index_limit = CBM_DEFAULT_AUTO_INDEX_LIMIT,
.auto_dep_limit = CBM_DEFAULT_AUTO_DEP_LIMIT,
};
@@ -1171,8 +1171,8 @@ static ha_guidance_config_t ha_load_guidance_config(void) {
result.context_injection =
cbm_config_get_effective_bool(cfg, CBM_CONFIG_CONTEXT_INJECTION, true);
result.auto_watch = cbm_config_get_effective_bool(cfg, CBM_CONFIG_AUTO_WATCH, true);
result.auto_index_deps =
cbm_config_get_effective_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, true);
result.auto_index_deps = cbm_config_get_effective_bool(
cfg, CBM_CONFIG_AUTO_INDEX_DEPS, CBM_DEFAULT_AUTO_INDEX_DEPS);
result.auto_index_limit =
cbm_config_get_effective_int(cfg, CBM_CONFIG_AUTO_INDEX_LIMIT,
CBM_DEFAULT_AUTO_INDEX_LIMIT);
+2 -4
View File
@@ -740,10 +740,8 @@ int cbm_discover_installed_deps(cbm_pkg_manager_t mgr, const char *project_root,
/* ── Auto-Index ────────────────────────────────────────────────── */
int cbm_dep_auto_index_effective_limit(cbm_config_t *cfg, int default_limit) {
if (!cfg) {
return default_limit;
}
if (!cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, true)) {
if (!cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS,
CBM_DEFAULT_AUTO_INDEX_DEPS)) {
return 0;
}
+2
View File
@@ -45,6 +45,8 @@ static const char *CBM_MANIFEST_FILES[] = {
};
/* Default limits (convention: -1=unlimited, 0=disabled, >0=limit) */
#define CBM_DEFAULT_AUTO_INDEX_DEPS false
#define CBM_DEFAULT_AUTO_INDEX_DEPS_STR "false"
#define CBM_DEFAULT_AUTO_DEP_LIMIT 20
#define CBM_DEFAULT_DEP_MAX_FILES 1000
+3 -1
View File
@@ -2557,7 +2557,9 @@ static int cbm_mcp_overlay_compaction_max_generations(cbm_mcp_server_t *srv) {
}
static int cbm_mcp_effective_auto_dep_limit(cbm_mcp_server_t *srv, const char *args_json) {
bool enabled = cbm_config_get_bool(srv ? srv->config : NULL, CBM_CONFIG_AUTO_INDEX_DEPS, true);
bool enabled = cbm_config_get_bool(srv ? srv->config : NULL,
CBM_CONFIG_AUTO_INDEX_DEPS,
CBM_DEFAULT_AUTO_INDEX_DEPS);
if (cbm_mcp_has_arg(args_json, CBM_CONFIG_AUTO_INDEX_DEPS)) {
enabled = cbm_mcp_get_bool_arg_default(args_json, CBM_CONFIG_AUTO_INDEX_DEPS, enabled);
}
+103 -8
View File
@@ -4171,6 +4171,39 @@ TEST(cli_hook_augment_subagent_no_project_guidance_is_read_only) {
PASS();
}
TEST(cli_hook_augment_guidance_uses_dependency_default) {
char tmpdir[256];
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-default-XXXXXX");
if (!cbm_mkdtemp(tmpdir))
FAIL("cbm_mkdtemp failed");
cli_env_snapshot_t cache = {0};
cli_env_snapshot_t auto_index_deps = {0};
cli_env_snapshot_t auto_dep_limit = {0};
ASSERT_TRUE(cli_env_snapshot(&cache, "CBM_CACHE_DIR"));
ASSERT_TRUE(cli_env_snapshot(&auto_index_deps, "CBM_AUTO_INDEX_DEPS"));
ASSERT_TRUE(cli_env_snapshot(&auto_dep_limit, "CBM_AUTO_DEP_LIMIT"));
cbm_setenv("CBM_CACHE_DIR", tmpdir, 1);
cbm_unsetenv("CBM_AUTO_INDEX_DEPS");
cbm_unsetenv("CBM_AUTO_DEP_LIMIT");
const char *input =
"{\"hook_event_name\":\"SessionStart\","
"\"cwd\":\"/definitely-not-indexed/default-dependency-guidance\"}";
char *output = cbm_hook_augment_lifecycle_json(input);
ASSERT_NOT_NULL(output);
ASSERT_NOT_NULL(strstr(output, "auto_index_deps=false"));
ASSERT_NOT_NULL(strstr(output, "index_dependencies"));
ASSERT_NULL(strstr(output, "Dependencies: automatic"));
free(output);
cli_env_restore(&auto_dep_limit);
cli_env_restore(&auto_index_deps);
cli_env_restore(&cache);
test_rmdir_r(tmpdir);
PASS();
}
TEST(cli_hook_augment_guidance_tracks_tool_and_dependency_config) {
char tmpdir[256];
snprintf(tmpdir, sizeof(tmpdir), "/tmp/cli-hook-config-XXXXXX");
@@ -6932,6 +6965,24 @@ TEST(cli_config_registry_auto_dep_limit_uses_shared_default) {
PASS();
}
TEST(cli_config_registry_auto_index_deps_defaults_disabled) {
const cbm_config_entry_t *found = NULL;
for (int i = 0; CBM_CONFIG_REGISTRY[i].key; i++) {
if (strcmp(CBM_CONFIG_REGISTRY[i].key, CBM_CONFIG_AUTO_INDEX_DEPS) == 0) {
found = &CBM_CONFIG_REGISTRY[i];
break;
}
}
ASSERT_NOT_NULL(found);
ASSERT_STR_EQ(found->default_val, "false");
ASSERT_STR_EQ(found->range, "true|false");
ASSERT_NOT_NULL(strstr(found->description, "installed dependency source"));
ASSERT_NOT_NULL(strstr(found->guidance, "index_dependencies"));
ASSERT_NOT_NULL(strstr(found->guidance, "does not delete"));
PASS();
}
TEST(cli_config_registry_reindex_startup_guidance_is_precise) {
const cbm_config_entry_t *found = NULL;
for (int i = 0; CBM_CONFIG_REGISTRY[i].key; i++) {
@@ -7017,14 +7068,55 @@ TEST(cli_config_presets_apply_exact_capability_sets) {
cbm_config_t *cfg = cbm_config_open(tmpdir);
ASSERT_NOT_NULL(cfg);
ASSERT_EQ(cbm_config_apply_preset(cfg, "streamlined-quality"), 0);
ASSERT_STR_EQ(cbm_config_get(cfg, CBM_CONFIG_TOOL_MODE, ""), "streamlined");
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, false));
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, false));
static const struct {
const char *name;
const char *tool_mode;
bool auto_index_deps;
} cases[] = {
{"streamlined-automatic-dependency-source-indexing-disabled", "streamlined", false},
{"streamlined-automatic-dependency-source-indexing-enabled", "streamlined", true},
{"classic-automatic-dependency-source-indexing-disabled", "classic", false},
{"classic-automatic-dependency-source-indexing-enabled", "classic", true},
};
for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_RANK_ENABLED, "false"), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS,
cases[i].auto_index_deps ? "false" : "true"),
0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_SIMILARITY_ENABLED, "false"), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_SEMANTIC_EDGES_ENABLED, "false"), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_GITHISTORY_ENABLED, "false"), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_HTTPLINKS_ENABLED, "false"), 0);
ASSERT_EQ(cbm_config_apply_preset(cfg, cases[i].name), 0);
ASSERT_STR_EQ(cbm_config_get(cfg, CBM_CONFIG_TOOL_MODE, ""), cases[i].tool_mode);
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, false));
ASSERT_EQ(cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS,
!cases[i].auto_index_deps),
cases[i].auto_index_deps);
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_SIMILARITY_ENABLED, false));
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_SEMANTIC_EDGES_ENABLED, false));
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_GITHISTORY_ENABLED, false));
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_HTTPLINKS_ENABLED, false));
}
ASSERT_NEQ(cbm_config_apply_preset(cfg, "streamlined-quality"), 0);
ASSERT_NEQ(cbm_config_apply_preset(cfg, "classic-quality"), 0);
ASSERT_NEQ(cbm_config_apply_preset(cfg, "dependency-disabled"), 0);
ASSERT_EQ(cbm_config_apply_preset(cfg, "rank-disabled"), 0);
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, true));
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, true));
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_SIMILARITY_ENABLED, false));
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_SEMANTIC_EDGES_ENABLED, false));
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_GITHISTORY_ENABLED, false));
ASSERT_TRUE(cbm_config_get_bool(cfg, CBM_CONFIG_HTTPLINKS_ENABLED, false));
ASSERT_EQ(cbm_config_apply_preset(cfg, "optional-graph-disabled"), 0);
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, true));
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, true));
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_SIMILARITY_ENABLED, true));
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_SEMANTIC_EDGES_ENABLED, true));
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_GITHISTORY_ENABLED, true));
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_HTTPLINKS_ENABLED, true));
ASSERT_EQ(cbm_config_apply_preset(cfg, "minimal-indexing"), 0);
ASSERT_FALSE(cbm_config_get_bool(cfg, CBM_CONFIG_RANK_ENABLED, true));
@@ -7070,7 +7162,8 @@ TEST(cli_config_command_dispatches_presets) {
/* Stored preset values remain deterministic, but an active environment
* override must be reported through a nonzero command status. */
cbm_setenv("CBM_TOOL_MODE", CBM_CONFIG_TOOL_MODE_CLASSIC, 1);
char *overridden_args[] = {"preset", "apply", "streamlined-quality"};
char *overridden_args[] = {
"preset", "apply", "streamlined-automatic-dependency-source-indexing-disabled"};
ASSERT_NEQ(cbm_cmd_config(3, overridden_args), 0);
cfg = cbm_config_open(tmpdir);
ASSERT_NOT_NULL(cfg);
@@ -7643,6 +7736,7 @@ SUITE(cli) {
RUN_TEST(cli_hook_augment_lifecycle_output_contract);
RUN_TEST(cli_hook_augment_subagent_tier_router_contract);
RUN_TEST(cli_hook_augment_subagent_no_project_guidance_is_read_only);
RUN_TEST(cli_hook_augment_guidance_uses_dependency_default);
RUN_TEST(cli_hook_augment_guidance_tracks_tool_and_dependency_config);
RUN_TEST(cli_hook_augment_post_read_event_and_path_contract);
RUN_TEST(cli_hook_augment_hermes_dialect_contract);
@@ -7755,6 +7849,7 @@ SUITE(cli) {
RUN_TEST(cli_config_registry_includes_dep_ranking_toggle);
RUN_TEST(cli_config_registry_includes_query_max_rows);
RUN_TEST(cli_config_registry_auto_dep_limit_uses_shared_default);
RUN_TEST(cli_config_registry_auto_index_deps_defaults_disabled);
RUN_TEST(cli_config_registry_reindex_startup_guidance_is_precise);
RUN_TEST(cli_configuration_doc_auto_index_default_matches_registry);
RUN_TEST(cli_config_delete);
+2 -2
View File
@@ -1081,8 +1081,8 @@ TEST(test_auto_index_deps_config_limit_policy) {
cbm_config_t *cfg = cbm_config_open(cache_tmp);
ASSERT_NOT_NULL(cfg);
ASSERT_EQ(cbm_dep_auto_index_effective_limit(cfg, CBM_DEFAULT_AUTO_DEP_LIMIT),
CBM_DEFAULT_AUTO_DEP_LIMIT);
ASSERT_EQ(cbm_dep_auto_index_effective_limit(NULL, CBM_DEFAULT_AUTO_DEP_LIMIT), 0);
ASSERT_EQ(cbm_dep_auto_index_effective_limit(cfg, CBM_DEFAULT_AUTO_DEP_LIMIT), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "false"), 0);
ASSERT_EQ(cbm_dep_auto_index_effective_limit(cfg, CBM_DEFAULT_AUTO_DEP_LIMIT), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "true"), 0);
+59 -50
View File
@@ -14,6 +14,7 @@
#include <mcp/mcp.h>
#include <store/store.h>
#include <cli/cli.h>
#include <depindex/depindex.h>
#include <yyjson/yyjson.h>
#include <string.h>
#include <stdlib.h>
@@ -1459,7 +1460,7 @@ TEST(path_project_autoindex_respects_file_limit) {
/* ══════════════════════════════════════════════════════════════════
* Path-based auto-index must run dependency auto-indexing exactly like
* the session-root branch: auto_index_deps (default true) triggers
* the session-root branch: explicit auto_index_deps=true triggers
* cbm_mcp_auto_index_deps after the project index; config can disable
* it or cap it via auto_dep_limit. Analysis:
* notes/2026-07-21-2332-path-autoindex-dependency-asymmetry-analysis.md
@@ -1531,55 +1532,12 @@ TEST(path_project_autoindex_indexes_dependencies) {
ASSERT_NOT_NULL(cbm_mkdtemp(target_tmp));
ASSERT_EQ(setup_path_dep_target(target_tmp), 0);
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
ASSERT_NOT_NULL(srv);
const char *old_auto_index = getenv("CBM_AUTO_INDEX");
char *old_auto_index_copy = old_auto_index ? strdup(old_auto_index) : NULL;
cbm_setenv("CBM_AUTO_INDEX", "true", 1);
bool project_indexed = false;
char *dep_resp = NULL;
run_path_dep_queries(srv, session_tmp, target_tmp, "path_dep_sentinel",
&project_indexed, &dep_resp);
bool dep_indexed = dep_resp && strstr(dep_resp, "path_dep_sentinel") != NULL;
free(dep_resp);
cbm_mcp_server_free(srv);
if (old_auto_index_copy) {
cbm_setenv("CBM_AUTO_INDEX", old_auto_index_copy, 1);
free(old_auto_index_copy);
} else {
cbm_unsetenv("CBM_AUTO_INDEX");
}
th_cleanup(target_tmp);
th_cleanup(session_tmp);
ASSERT_TRUE(project_indexed);
/* RED before the fix: the path branch never called
* cbm_mcp_auto_index_deps, so the vendored dep was silently absent
* even though auto_index_deps defaults to true. */
ASSERT_TRUE(dep_indexed);
PASS();
}
TEST(path_project_autoindex_deps_disabled_by_config) {
char session_tmp[256];
snprintf(session_tmp, sizeof(session_tmp), "/tmp/cbm_path_depoff_sess_XXXXXX");
ASSERT_NOT_NULL(cbm_mkdtemp(session_tmp));
ASSERT_EQ(th_write_file(TH_PATH(session_tmp, "main.c"), "void session_dep_fn(void) {}\n"),
0);
char target_tmp[256];
snprintf(target_tmp, sizeof(target_tmp), "/tmp/cbm_path_depoff_tgt_XXXXXX");
ASSERT_NOT_NULL(cbm_mkdtemp(target_tmp));
ASSERT_EQ(setup_path_dep_target(target_tmp), 0);
char cfg_tmp[256];
snprintf(cfg_tmp, sizeof(cfg_tmp), "/tmp/cbm_path_depoff_cfg_XXXXXX");
snprintf(cfg_tmp, sizeof(cfg_tmp), "/tmp/cbm_path_depon_cfg_XXXXXX");
ASSERT_NOT_NULL(cbm_mkdtemp(cfg_tmp));
cbm_config_t *cfg = cbm_config_open(cfg_tmp);
ASSERT_NOT_NULL(cfg);
ASSERT_EQ(cbm_config_set(cfg, "auto_index_deps", "false"), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "true"), 0);
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
ASSERT_NOT_NULL(srv);
@@ -1608,7 +1566,58 @@ TEST(path_project_autoindex_deps_disabled_by_config) {
th_cleanup(session_tmp);
ASSERT_TRUE(project_indexed);
/* auto_index_deps=false must keep the path branch dep-free. */
/* The enabled preset path must run the same dependency indexing helper as
* session-root indexing. */
ASSERT_TRUE(dep_indexed);
PASS();
}
TEST(path_project_autoindex_deps_disabled_by_default) {
char session_tmp[256];
snprintf(session_tmp, sizeof(session_tmp), "/tmp/cbm_path_depoff_sess_XXXXXX");
ASSERT_NOT_NULL(cbm_mkdtemp(session_tmp));
ASSERT_EQ(th_write_file(TH_PATH(session_tmp, "main.c"), "void session_dep_fn(void) {}\n"),
0);
char target_tmp[256];
snprintf(target_tmp, sizeof(target_tmp), "/tmp/cbm_path_depoff_tgt_XXXXXX");
ASSERT_NOT_NULL(cbm_mkdtemp(target_tmp));
ASSERT_EQ(setup_path_dep_target(target_tmp), 0);
char cfg_tmp[256];
snprintf(cfg_tmp, sizeof(cfg_tmp), "/tmp/cbm_path_depoff_cfg_XXXXXX");
ASSERT_NOT_NULL(cbm_mkdtemp(cfg_tmp));
cbm_config_t *cfg = cbm_config_open(cfg_tmp);
ASSERT_NOT_NULL(cfg);
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
ASSERT_NOT_NULL(srv);
cbm_mcp_server_set_config(srv, cfg);
const char *old_auto_index = getenv("CBM_AUTO_INDEX");
char *old_auto_index_copy = old_auto_index ? strdup(old_auto_index) : NULL;
cbm_setenv("CBM_AUTO_INDEX", "true", 1);
bool project_indexed = false;
char *dep_resp = NULL;
run_path_dep_queries(srv, session_tmp, target_tmp, "path_dep_sentinel",
&project_indexed, &dep_resp);
bool dep_indexed = dep_resp && strstr(dep_resp, "path_dep_sentinel") != NULL;
free(dep_resp);
cbm_mcp_server_free(srv);
cbm_config_close(cfg);
if (old_auto_index_copy) {
cbm_setenv("CBM_AUTO_INDEX", old_auto_index_copy, 1);
free(old_auto_index_copy);
} else {
cbm_unsetenv("CBM_AUTO_INDEX");
}
th_cleanup(cfg_tmp);
th_cleanup(target_tmp);
th_cleanup(session_tmp);
ASSERT_TRUE(project_indexed);
/* The product default must keep automatic path indexing dep-free. */
ASSERT_FALSE(dep_indexed);
PASS();
}
@@ -1645,7 +1654,7 @@ TEST(path_project_autoindex_honors_auto_dep_limit) {
ASSERT_NOT_NULL(cbm_mkdtemp(cfg_tmp));
cbm_config_t *cfg = cbm_config_open(cfg_tmp);
ASSERT_NOT_NULL(cfg);
ASSERT_EQ(cbm_config_set(cfg, "auto_index_deps", "true"), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "true"), 0);
ASSERT_EQ(cbm_config_set(cfg, "auto_dep_limit", "1"), 0);
cbm_mcp_server_t *srv = cbm_mcp_server_new(NULL);
@@ -1697,7 +1706,7 @@ TEST(dep_search_hint_names_index_dependencies_when_deps_disabled) {
cbm_config_t *cfg = cbm_config_open(tmp);
ASSERT_NOT_NULL(cfg);
ASSERT_EQ(cbm_config_set(cfg, "auto_index_deps", "false"), 0);
ASSERT_EQ(cbm_config_set(cfg, CBM_CONFIG_AUTO_INDEX_DEPS, "false"), 0);
cbm_mcp_server_set_config(srv, cfg);
/* "deps" expands to "validation-test.dep" (prefix match, zero rows).
@@ -1856,7 +1865,7 @@ void suite_input_validation(void) {
RUN_TEST(path_project_auto_indexes_separate_directory);
RUN_TEST(path_project_autoindex_respects_file_limit);
RUN_TEST(path_project_autoindex_indexes_dependencies);
RUN_TEST(path_project_autoindex_deps_disabled_by_config);
RUN_TEST(path_project_autoindex_deps_disabled_by_default);
RUN_TEST(path_project_autoindex_honors_auto_dep_limit);
RUN_TEST(dep_search_hint_names_index_dependencies_when_deps_disabled);
RUN_TEST(regression_trace_path_tool_name_still_works);