Commit Graph
110 Commits
Author SHA1 Message Date
Andrew Hundt 43d100acaa feat(pipeline): defer containment semantic refresh
Add opt-in incremental_derived_refresh=stale_on_incremental for full/moderate containment incremental publishes. The default remains eager; when configured, containment skips global semantic/similarity refresh and marks semantic_edges stale so existing MCP/query warnings remain accurate.

Validation: diff-check, source-safety, ASan/UBSan test-runner rebuild, pipeline, cli, mcp, pagerank, graph_buffer, incremental, and product build logs are recorded in the plan and forensics notes.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-05 06:48:13 -04:00
Andrew Hundt 4ac8c422c7 perf(pipeline): defer global derived refresh for exact deltas
Add an opt-in incremental_derived_refresh=stale_on_exact policy for full and moderate exact incremental publishes. The default remains eager, while the opt-in path reuses existing derived-view staleness semantics so semantic/similarity queries warn until an eager index run or full reindex rebuilds global edges.

The exact path now skips synchronous SIMILAR_TO/SEMANTICALLY_RELATED recomputation only when file-delta publish marks semantic_edges stale. Broad fallback, overlay, delete, rename, and replacement publish behavior remain conservative.

Validation: CBM_ONLY_SUITE=pipeline build/c/test-runner (330 passed); focused derived-refresh/config tests passed; make -f Makefile.cbm lint-source-safety passed; make -j10 -f Makefile.cbm cbm passed; isolated full-mode benchmark measured 40.153 ms incremental vs 415.058 ms fresh full (10.337x).
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-04 14:50:08 -04:00
Andrew Hundt 0f684ddc08 feat(mcp): trigger overlay compaction after publish
Add opt-in overlay_compaction_policy=after_publish with a bounded overlay_compaction_max_generations setting. index_repository now starts a one-shot compaction worker only after a successful incremental_overlay publish and reports the trigger status in the response.\n\nValidation:\n- make -f Makefile.cbm -j8 build/c/test-runner\n- CBM_ONLY_SUITE=mcp build/c/test-runner\n- CBM_ONLY_SUITE=pipeline build/c/test-runner\n- make -f Makefile.cbm -j8 cbm\n- git diff --check\n- bash scripts/check-source-safety.sh src/mcp/mcp.c src/cli/cli.c src/pipeline/pipeline.h tests/test_mcp.c tests/test_pipeline.c

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-04 04:45:48 -04:00
Andrew Hundt a6fb2720f4 feat(pipeline): publish opt-in exact deltas to overlay
Add a default-off overlay_publish policy for bounded exact-delta incremental runs. When enabled, eligible non-noop exact deltas publish ready overlay rows and dirty freshness without mutating canonical graph rows, while default canonical behavior remains unchanged.

Use the latest complete canonical generation as the overlay base, avoid reserving a canonical generation for successful overlay publishes, and report incremental_overlay in pipeline telemetry and benchmark parsing.

Add focused store and pipeline canaries for latest complete generation lookup, opt-in overlay visibility, canonical invisibility, dirty overlay_ready state, and absence of stray reserved canonical generations.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-04 01:54:46 -04:00
Andrew Hundt 3b2b552a15 fix(cypher): align query row defaults with upstream
Restore the Cypher executor safety ceiling to upstream's 100000 rows and expose the MCP query_graph default as query_max_rows. Explicit max_rows arguments remain caller-authoritative; omitted max_rows uses the config default. Add CLI registry and MCP coverage for the new discoverable default.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-03 22:20:15 -04:00
Andrew Hundt 16f683a98f fix(cli): make subcommand help non-mutating
Return install, uninstall, and update subcommand help before auto-answer parsing, home lookup, index scans, prompts, release checks, downloads, or file mutation.

Refresh top-level usage for existing install/update flags and add focused CLI tests that prove help works with HOME and USERPROFILE unset.

Validation: product build /private/tmp/cbm-cli-help-build1.log rc 0; ASan test-runner build /private/tmp/cbm-cli-help-test-runner-build2.log rc 0; CLI suite /private/tmp/cbm-cli-help-cli-suite2.log rc 0 (118/118); source-safety /private/tmp/cbm-cli-help-source-safety1.log rc 0; manual help smoke outputs under /private/tmp/cbm-cli-help-{install,uninstall,update}1.*.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-02 17:59:41 -04:00
Andrew Hundt 3b8de83b8e feat(pagerank): support incremental rank deferral
Add an opt-in rank_refresh=stale_on_incremental policy while preserving eager as the default and stale_on_exact as exact-only. Replacement publishes now mark rank-derived views stale before refresh, and MCP index, autoindex, and watcher paths share a publish-kind mapper so refresh policy is applied consistently.

Validation: make -f Makefile.cbm -j8 cbm rc=0 (/private/tmp/cbm-rank-refresh-dry-build1.log); make -f Makefile.cbm -j8 build/c/test-runner rc=0 (/private/tmp/cbm-rank-refresh-dry-test-runner-build1.log); CBM_ONLY_SUITE=pagerank build/c/test-runner rc=0, 57/57 (/private/tmp/cbm-rank-refresh-dry-pagerank2.log); CBM_ONLY_SUITE=pipeline build/c/test-runner rc=0, 307/307 (/private/tmp/cbm-rank-refresh-dry-pipeline2.log); make -f Makefile.cbm lint-source-safety rc=0 (/private/tmp/cbm-rank-refresh-dry-source-safety1.log); git diff --check clean.

Benchmark note: stale_on_exact vs stale_on_incremental self-dogfood comparison is still pending because the escalated uv benchmark run was rejected by the environment usage limit. Historical baseline remains /private/tmp/cbm-pan6-no-late-fallback-selfdogfood-cap256.json.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-02 17:40:02 -04:00
Andrew Hundt 179d0bb498 feat(pipeline): configure exact frontier limits
Add config-backed exact delta changed/affected frontier limits while preserving the conservative defaults. Exact delete and upsert paths now read the effective limits through shared pipeline getters instead of hardcoded live caps.

Add TDD coverage for default clamping, registry entries, and a configured 5-file inbound frontier that publishes exact and matches a fresh rebuild. Extend the incremental benchmark harness with repeatable --config key=value overrides so cap experiments are reproducible.

Validation: ASan/UBSan test-runner build rc=0; CBM_ONLY_SUITE=pipeline passed 304/304; source-safety rc=0 after harness edit; production cbm build rc=0; benchmark pycompile rc=0. Self-dogfood one_source_file with incremental_exact_max_affected_paths=64 passed canonical/oracle/cleanup checks but still fell back to containment with exact_reason=inbound_edges_require_full and only 3.30x speedup, so incremental remains off by default.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-02 14:10:41 -04:00
Andrew Hundt 9c674c12b6 fix(cli): reuse portable filesystem helpers
Use existing CBM filesystem helpers for CLI existence-only checks and agent directory detection. Keep metadata-dependent stat calls unchanged.

Use cbm_move_file_no_replace for the Windows running-binary rename-aside path so the update fallback goes through the same portable no-replace move abstraction as the rest of the codebase.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-01 21:49:28 -04:00
Andrew Hundt 428ef427f1 fix(cli): scan all fallback cli paths
Use the fallback path array length for cbm_find_cli instead of the unrelated retry-count constant. This keeps CLI agent detection tied to the path list and prevents future constant drift from skipping later fallback locations.

Add a focused .cargo/bin fallback regression so path index 3 remains covered alongside the existing PATH and .local/bin cases.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-01 21:44:16 -04:00
Andrew Hundt fec4883101 fix(cli): use portable tag allocation
Use cbm_strdup when copying the latest-release tag in the update check path. This keeps CLI allocation portable through the existing compatibility wrapper without changing behavior or ownership.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-01 21:20:47 -04:00
Andrew Hundt 3ad25bfd79 fix(cli): tighten reindex startup guidance
Avoid describing reindex_on_startup as always-fresh. The setting only refreshes stale indexes during startup/staleness checks, so the generated config help now says that directly.\n\nAdd a focused CLI registry test to keep the old overclaim from returning.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-01 21:13:59 -04:00
Andrew Hundt a64f7eac28 fix(cli): clarify hook reminder guidance
Clarify the Codex/Gemini/Antigravity SessionStart reminder so it recommends graph tools before broad grep for structural code discovery instead of implying they replace file reads. Spell out that auto-indexing uses the MCP server CWD or explicit repo paths when enabled, and add a focused Codex hook regression assertion for the wording.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-01 20:40:19 -04:00
Andrew Hundt 414ccb3d1a perf(pagerank): defer exact-delta rank refresh
Add rank_refresh=eager|stale_on_exact with eager as the default. The opt-in stale_on_exact policy skips synchronous PageRank/LinkRank/node_degree recompute only after exact incremental graph publishes when dependency indexing did not run and rank-derived views are already marked stale.

The stale metadata check is deliberate: if rank views are missing, complete, or otherwise not explicitly stale, the helper falls back to eager recompute so stale scores are not served as fresh. Existing search/trace paths already omit stale rank and warn through derived-view freshness state.

Validation: make -j8 -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=pagerank ./build/c/test-runner; CBM_ONLY_SUITE=pipeline ./build/c/test-runner; CBM_ONLY_SUITE=mcp ./build/c/test-runner; CBM_ONLY_SUITE=cli ./build/c/test-runner; bash scripts/check-source-safety.sh; bash scripts/test-source-safety.sh; git diff --check; make -j8 -f Makefile.cbm cbm; isolated CLI smoke with incremental_reindex=always and rank_refresh=stale_on_exact showed incremental.exact.done files=2 and pagerank.defer without pagerank.done on the second exact-delta run.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-01 12:39:21 -04:00
Andrew Hundt 4578bc73b9 fix(pagerank): honor rank scope config
Wire the rank_scope config value into cbm_pagerank_compute_with_config so config-backed PageRank and LinkRank can select full, project, or dependency scope.

Keep the default as full to preserve existing project-plus-dependency behavior, and clear the full project/dependency rank prefix before writing any narrower scope because the rank tables do not persist scope.

Update the config registry wording and add a regression test for full-to-project stale-row cleanup, invalid-scope fallback, and config temp-dir cleanup.

Validation: git diff --check; bash scripts/check-source-safety.sh; CBM_ONLY_SUITE=pagerank ./build/c/test-runner; CBM_ONLY_SUITE=cli ./build/c/test-runner; make -j8 -f Makefile.cbm build/c/test-runner.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-01 09:08:31 -04:00
Andrew Hundt c0bdd70498 fix(mcp): clarify autoindex tool descriptions
Clarify that graph-backed default tools can trigger first-use auto-indexing, while search_code searches source for an already indexed/current project. Align MCP schemas, installed CLI guidance, and SessionStart reminders with the actual handler paths.

Add a tool-consolidation regression so future schema/help text does not claim all default tools auto-index.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-07-01 05:42:30 -04:00
Andrew Hundt 3261ce9383 fix(cli): harden install path formatting
Add cbm_getenv_fits so path-like environment values can fail closed when set but too long, instead of being silently truncated by bounded copies or falling back to HOME.

Use checked formatting for Claude hook command/script paths, install/uninstall Claude config paths, install/update binary targets, and PATH directory writes. Overlong paths now return or report an error before mutating a truncated location.

Add focused CLI regressions for overlong hook homes and CLAUDE_CONFIG_DIR, plus platform coverage for the new environment helper.

Validation: make -f Makefile.cbm cbm; make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=cli ./build/c/test-runner; CBM_ONLY_SUITE=platform ./build/c/test-runner; bash scripts/check-source-safety.sh; git diff --check.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-30 17:49:19 -04:00
Andrew Hundt 404feb8210 fix(cli): reject overlong config paths
Validate CLI config and instruction parent paths before creating directories so truncated fixed buffers cannot create a different target. Route JSON and markdown writes through the existing cbm_write_file_atomic helper for consistent replace semantics.

Add regression coverage for overlong JSON config and instruction paths to prove failed writes do not create truncated parent directories.

Validation: make -f Makefile.cbm cbm; make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=cli ./build/c/test-runner; bash scripts/check-source-safety.sh; git diff --check.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-30 17:33:06 -04:00
Andrew Hundt 8335b78719 docs(cli): clarify hook stdout semantics
Make SessionStart hook comments explicit that stdout is harness-injected session context, not MCP protocol output. This removes vague same-methodology wording without changing install or hook behavior.

Validation: CBM_ONLY_SUITE=cli ./build/c/test-runner; bash scripts/check-source-safety.sh; git diff --check.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-30 17:19:05 -04:00
Andrew Hundt cbacf99e74 docs(cli): list dependency ranking config
search_graph already reads search_disable_dep_ranking, and the MCP schema names that config key. Add it to CBM_CONFIG_REGISTRY so config list/get guidance exposes the same setting users see in the API description.

Add a CLI registry regression test for the key, default, range, and dependency-ranking guidance. This does not change search behavior, MCP schemas, DB schema, or tool visibility.

Validated with make -f Makefile.cbm build/c/test-runner, CBM_ONLY_SUITE=cli ./build/c/test-runner, CBM_ONLY_SUITE=tool_consolidation ./build/c/test-runner, git diff --check, and bash scripts/check-source-safety.sh.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-30 07:19:07 -04:00
Andrew Hundt 5f4ca14968 fix(cli): decouple session hook matchers
Use the Claude SessionStart matcher array length instead of the unrelated NUM_DIRS constant, and expose the helper with a Claude-specific name that matches the Gemini session hook API.

Add a focused CLI regression test that verifies startup, resume, clear, and compact SessionStart hooks are all installed and removed.

Validation: make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=cli ./build/c/test-runner; bash scripts/check-source-safety.sh; git diff --check.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-30 05:35:11 -04:00
Andrew Hundt ec650bb3ce fix(cli): classify planned skill installs
Add a skill_dirs_planned array to the install --plan receipt and route planned Claude Code skill directory writes there instead of instruction_files_planned.

This keeps the no-mutation install receipt accurate for agents reviewing planned changes before install. Real install behavior and hook upsert paths are unchanged.

Validation: make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=cli ./build/c/test-runner; bash scripts/check-source-safety.sh; git diff --check; make -f Makefile.cbm cbm; HOME=/private/tmp/cbm-install-plan-smoke-20260630 ./build/c/codebase-memory-mcp install --plan.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-30 05:28:24 -04:00
Andrew Hundt 809b1db87a docs(cli): clarify installed guidance
Update generated agent instructions and SessionStart reminder text to use the same explicit auto-index conditions as the MCP schema: auto_index=true and under auto_index_limit.

Also describe search_code as text/regex source search instead of graph-augmented grep, avoiding an overclaim about behavior.

Validation: make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=mcp ./build/c/test-runner; CBM_ONLY_SUITE=tool_consolidation ./build/c/test-runner; CBM_ONLY_SUITE=cli ./build/c/test-runner; bash scripts/check-source-safety.sh; git diff --check.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-30 05:19:48 -04:00
Andrew Hundt 0225ddb8b8 docs(api): clarify auto-index conditions
Tighten MCP and installed hook wording so auto-index behavior is described by its actual gates: auto_index=true and the repository remaining under auto_index_limit.

This keeps the streamlined/classic tool surfaces, hook matchers, and install behavior unchanged while making the descriptions more actionable for MCP clients and CLI hook users.

Validation: make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=mcp ./build/c/test-runner; CBM_ONLY_SUITE=tool_consolidation ./build/c/test-runner; CBM_ONLY_SUITE=cli ./build/c/test-runner; bash scripts/check-source-safety.sh; git diff --check.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-30 05:15:01 -04:00
Andrew Hundt a0581987f5 fix: align OpenClaw and worktree discovery
Port upstream OpenClaw MCP config behavior to the fork branch: OpenClaw now writes nested mcp.servers entries with enabled, command, and args instead of the generic mcpServers shape, while preserving existing config.

Also skip .claude-worktrees during discovery to avoid indexing stale duplicate worktree content alongside the existing .claude and .worktrees exclusions.

Verified: build/c/test-runner; build/c/codebase-memory-mcp; CBM_ONLY_SUITE=cli (107); CBM_ONLY_SUITE=discover (84).
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 17:21:55 -04:00
Andrew Hundt 608b51374e fix: apply autoindex limits consistently
Use the bounded discover count for startup, first-use, and explicit path autoindexing so CBM_AUTO_INDEX_LIMIT cannot be bypassed by a later MCP handler path.

Move sync first-use indexing into resolve_project_store via a shared MCP-local helper, leaving REQUIRE_STORE responsible for joining an in-flight startup index and reporting missing stores. This avoids duplicate indexing attempts and duplicate over-limit warnings while preserving structured stderr logging.

Add an input-validation regression for over-limit explicit path projects and clarify the config help text to say the limit counts indexable files.

Verified: build/c/test-runner; build/c/codebase-memory-mcp; CBM_ONLY_SUITE=input_validation (44), mcp (113), discover (83), cli (104).
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 17:09:51 -04:00
Andrew Hundt ba3d97c66a fix: bound autoindex with discover filters
Use the discover walker for MCP autoindex file-limit checks instead of shelling out to git ls-files, so non-git roots and ignored files follow the same filters as indexing.

Add typed effective config helpers so env-backed registry settings such as CBM_AUTO_INDEX_LIMIT and CBM_REINDEX_ON_STARTUP are honored consistently by MCP startup logic.

Repair the CBM_ONLY_SUITE discover allowlist and add regressions for bounded non-git discovery counts and env-over-db config priority.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 16:41:31 -04:00
Andrew Hundt b0858ee1b6 fix: preserve config store during index cleanup
Install, update, and uninstall cleanup paths are scoped to project indexes, but the old .db predicate also selected _config.db. Add a shared project-index predicate, exclude the persistent config store, and keep list/count/remove behavior consistent.

Verification: make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=cli build/c/test-runner; make -B -f Makefile.cbm build/c/codebase-memory-mcp.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 16:14:36 -04:00
Andrew Hundt a1120631da docs: clarify tool surface descriptions
Remove brittle hardcoded tool-count wording from MCP hidden-tool and CLI config descriptions. Keep the concrete tool names and discovery instructions intact so maintainers and MCP clients see the same capabilities without stale numeric claims.

Verification: make -f Makefile.cbm build/c/test-runner build/c/codebase-memory-mcp; CBM_ONLY_SUITE=tool_consolidation build/c/test-runner; CBM_ONLY_SUITE=mcp build/c/test-runner; CBM_ONLY_SUITE=cli build/c/test-runner.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 15:59:12 -04:00
Andrew Hundt abadfae9ed fix: default incremental reindex to full rebuilds
Default incremental_reindex to off so normal indexing uses the existing full atomic rebuild path until the disk incremental implementation avoids full-graph load, quality-pass, FTS rebuild, and dump work. This matches the measured behavior where small FastAPI edits can be slower through the current incremental path than a full rebuild.

Keep fast and always as explicit opt-ins for benchmarking and canary tests. Update pipeline tests that intentionally validate legacy incremental behavior to set incremental_reindex=always locally instead of relying on production defaults.

Validation: make -f Makefile.cbm build/c/test-runner cbm; CBM_ONLY_SUITE=pipeline build/c/test-runner: 212 passed; CBM_ONLY_SUITE=cli build/c/test-runner: 102 passed; git diff --check.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 12:27:27 -04:00
Andrew Hundt a7e80d8a61 fix: guard slow incremental reindex routing
Add a config-backed incremental_reindex policy with default fast so full and moderate indexes rebuild atomically instead of entering the current disk incremental path, which still performs full-graph quality work and can be slower than a clean rebuild. Keep always for benchmarking and off for deterministic full rebuilds.

Harden the existing incremental path around allocation failures before mutation: classify, changed-file list, graph buffer creation, changed-path set, and deleted-path copies now fail closed or preserve existing nodes rather than dereferencing NULL or recording corrupt path arrays.

Reuse the existing pipeline nanosecond constant for file-hash mtimes and keep the dedicated incremental suite opted into incremental_reindex=always so its canaries continue exercising the legacy disk incremental implementation.

Validation: make -f Makefile.cbm build/c/test-runner cbm; CBM_ONLY_SUITE=pipeline build/c/test-runner: 212 passed; CBM_ONLY_SUITE=cli build/c/test-runner: 102 passed; CBM_ONLY_SUITE=mcp build/c/test-runner: 113 passed; CBM_ONLY_SUITE=tool_consolidation build/c/test-runner: 94 passed; git diff --check.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 12:14:52 -04:00
Andrew Hundt 9105f0f73e fix: keep CLI auto-index defaults config-backed
Attach the normal config store before one-shot CLI tool dispatch so CLI calls honor the same registry defaults and env/config overrides as the stdio MCP server. This keeps explicit path search auto-indexing enabled by default for user-facing CLI calls while embedded/no-config helpers remain manual unless CBM_AUTO_INDEX explicitly opts in.

Clarify tool/config/help strings to describe the real behavior: streamlined lists 5 core tools plus _hidden_tools discovery, get_architecture is available after reveal or classic mode, and default tools can auto-index the server CWD or explicit repository paths when enabled.

Validation:

- make -f Makefile.cbm cbm build/c/test-runner

- CBM_ONLY_SUITE=mcp build/c/test-runner: 113 passed

- CBM_ONLY_SUITE=tool_consolidation build/c/test-runner: 94 passed

- CBM_ONLY_SUITE=input_validation build/c/test-runner: 43 passed

- CBM_ONLY_SUITE=cli build/c/test-runner: 102 passed

- CLI smoke: isolated explicit repo path auto-indexed without CBM_AUTO_INDEX=true and returned cli_autoindex_sentinel

- CLI stdout/stderr split: JSON on stdout, logs on stderr

- git diff --check

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 11:52:43 -04:00
Andrew Hundt d9e97ba2ca fix: clarify MCP API guidance
Document search_graph query as the BM25 path and make clear that graph filters and sort_by do not apply there.

Describe semantic_query as an array that appends separate semantic_results instead of implying it changes the normal result ranking.

Update installed agent guidance and hooks to prefer the streamlined get_code surface, avoid hyperbole, and describe auto-indexing as best-effort.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 10:46:41 -04:00
Andrew Hundt 5a5af98c88 fix: prevent broad install stops and Codex hook duplicates
Limit install/update process termination to MCP servers running the exact target binary path instead of every process named codebase-memory-mcp. This prevents fake HOME or alternate-prefix installs from killing unrelated agent sessions.

Make Codex config upserts idempotent when the MCP table and SessionStart hook share config.toml. Preserve hook sentinels during MCP section replacement and repair stale duplicate/orphan CMM hook blocks on the next upsert.

Verification: make -f Makefile.cbm cbm; make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=cli build/c/test-runner; fake-HOME install --force collapsed a corrupted Codex config to one MCP section and one SessionStart hook.
Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 10:30:19 -04:00
Andrew Hundt 794e25cb06 docs: correct MCP tool references
Update generated CLI skill text, packaged skill docs, and npm README examples for the current MCP surface: trace_path is the canonical trace tool, index_dependencies is present, and the streamlined/default surface should not be described as exactly 14 tools.

Replace unsupported search_graph direction examples with supported query_graph degree queries and fix stale query/result-limit wording in generated help. Keep measured performance/preprint claims unchanged.

Verified with: make -f Makefile.cbm cbm; make -f Makefile.cbm build/c/test-runner; CBM_ONLY_SUITE=cli build/c/test-runner; git diff --check.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 09:46:39 -04:00
Andrew Hundt 60cad1ebbb fix: consolidate trace API and rank persistence
Use trace_path as the single public call-tracing tool across classic and streamlined MCP surfaces, while exposing existing semantic_query and search_code mode parameters in the advertised schemas. Keep the streamlined surface compact, but ensure the hidden-tool reveal covers the full classic capability set without trace aliases.

Persist PageRank, LinkRank, and node_degree rows with direct VALUES inserts instead of per-row SELECT probes. The node/edge project is loaded once with the graph rows so full-scope dependency attribution stays identical to the previous behavior.

Add focused coverage for dependency project attribution, streamlined parameter contracts, and targeted suite allowlist entries so these checks cannot silently run zero tests.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 08:36:56 -04:00
Andrew Hundt 0370d52f4d fix: harden index persistence and MCP outputs
Make index writes and artifact refreshes use verified temp files plus atomic replacement, preserving Windows replace semantics and avoiding fixed temp-path collisions.

Thread the remaining pipeline confidence knobs through config while keeping zero-valued defaults backward compatible with existing upstream behavior.

Tighten route-node gates and architecture route output so infra URL nodes stay queryable in the graph but do not pollute get_architecture route summaries; preserve code-created absolute URL routes for all language extractors.

Harden MCP and CLI path handling around cache paths, grep scratch files, update downloads, checksum validation, stale checks, and project DB discovery without writing protocol noise to stdout.

Add regression coverage for corrupt-DB recovery, concurrent atomic writes, tmp-prefixed project DBs, duplicate search result fields, route output filtering, config registry entries, and focused suite selectors.

Validated with: git diff --check; make -f Makefile.cbm build/c/test-runner; focused suites security, artifact, graph_buffer, sqlite_writer, store_search, store_bulk, store_pragmas, store_checkpoint, watcher, infrascan, pipeline, store_nodes, mcp, cli, parallel, tool_consolidation, incremental, and store_arch; make -f Makefile.cbm cbm; isolated dogfood index/query run.

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-28 06:34:23 -04:00
Andrew Hundt 74a5c63eff feat(mcp): split search_code_graph into focused tools (§4b)
Replace the consolidated search_code_graph mega-tool — which merged graph
search + source grep + cypher behind two nearly disjoint parameter
families — with the three existing focused tools as the DEFAULT surface:
search_graph (graph/structural), search_code (source grep), query_graph
(cypher). These are drawn from TOOLS[] (single schema source, DRY);
trace_call_path + get_code remain on the default surface. The
search_code_graph schema and its thin dispatch router are deleted; the
underlying handlers (handle_search_graph/search_code/query_graph) stay.

The _hidden_tools progressive-disclosure hint now lists 11 hidden tools
(was 14). Repointed three user-facing hint strings (handle_trace_call_path
missing-name and function-not-found; two unknown-tool path hints) from the
deleted tool to search_graph.

Tests updated to the new 5-tool surface:
- tests/test_mcp.c: mcp_tools_list + server_handle_tools_list assert the
  5 default tools present and search_code_graph absent.
- tests/test_tool_consolidation.c: renamed streamlined_mode_shows_3_tools
  -> ..._5_default_tools; repurposed the two search_code_graph dispatch
  tests into search_graph_dispatch / query_graph_dispatch (query_graph
  handler accepts both cypher= and query=); revised
  schema_compact_documented_as_graph_only (the graph-vs-source compact
  collision it warned about no longer exists post-split).
- tests/test_input_validation.c: remapped 16 dispatch calls by mode --
  cypher -> query_graph, source-grep -> search_code, graph/structural ->
  search_graph.
- tests/test_depindex.c: tool_index_dependencies_listed asserts
  search_graph (was search_code_graph).
- src/cli/cli.c: six config-description strings (search_limit, tool_mode,
  context_injection, compact, default_sort_by, default_include_dependencies).

Back-compat: blast radius is in-repo only (0 references in Go internal/cmd,
docs, or the CGO wrapper). External callers of search_code_graph must
switch to search_graph / search_code / query_graph, which are strictly
more capable. query_graph keeps its query= backward-compat alias.

Context -- of the three section-4 fixes in the merge plan, only section 4b
was a real change: section 4c (function<->class edges) was already
implemented (commit b950bf2 added the missing MEMBER_OF reverse-edge
coverage), and section 4a (passive resources) was already mitigated by
inject_context_once plus the get_graph_schema/get_architecture/index_status
tools -- both verified against code, not assumed.

Gate: 5981 passed / 2 failed (the 2 are the deferred B1 store-layer
incremental failures, unrelated to section 4b).

Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
2026-06-24 22:00:24 -04:00
Andrew Hundt 92f3b86f7a merge(upstream/main): integrate DeusData main into api-consolidation
Deep --no-ff merge of upstream DeusData/main (597 commits, merge-base 988d975)
into fork api-consolidation (HEAD 3018b22), producing a superset that combines
upstream breadth with the fork's surviving depth.

Upstream additions integrated: semantic/embedding search (vendored/nomic),
minhash/SimHash, cross-repo + cross-file LSP + route + pkgmap passes, artifact
import/export, path_alias, git_context, hook_augment, Windows support
(compat_fs/compat_thread), the UI layer, and ~140 expanded tree-sitter grammars.

Fork depth retained: PageRank/LinkRank ranking (src/pagerank/; sort_by=
relevance/linkrank/degree/calls), dependency indexing (src/depindex/;
CBM_INDEX_MODE=DEP), token reduction, and HTTP-endpoint discovery
(src/pipeline/httplink.c, pass_httplinks.c).

Conflict resolution (27 regions across the 39-file intersection):
- src/mcp/mcp.c: kept the fork superset handler pattern (resolve_project_store +
  expand_project_param + inject_context_once) as the single path; UNIONed the
  tool dispatch table; emit status:"indexed", excluded[], cross_service trace.
- src/store/store.c: upstream base + fork pagerank/linkrank/node_degree tables
  and sort_by plumbing; cbm_store_node_degree now excludes INHERITS
  (WHERE type != 'INHERITS'); removed the duplicate cbm_store_get_db.
- src/pipeline/pipeline.c: took upstream run_extraction_phase; grafted the fork
  passes (httplinks, normalize, flush_store dump branch); call
  cbm_pipeline_set_committed_counts before cbm_gbuf_dump_to_sqlite.
- internal/cbm/lang_specs.c: 158 entries combining the fork section_node_types
  with upstream ts_factory/embedded_imports; wired 13 orphaned type-arrays.
- src/depindex/depindex.h: renamed CBM_PATH_MAX -> CBM_DEP_PATH_MAX (it collided
  with constants.h enum CBM_PATH_MAX=1024) + 11 call sites in depindex.c.
- Makefile.cbm: upstream grammar/nomic units + fork CGO targets; added
  httplink.c + pass_httplinks.c to PIPELINE_SRCS; removed mongoose NOSAN
  machinery (mongoose was deleted upstream).
- httplinks restored (the merge silently deleted them because the fork had left
  them unchanged since the base): httplink.c/.h, pass_httplinks.c,
  tests/test_httplink.c; registered RUN_SUITE(httplink) in tests/test_main.c.
- CBM_INDEX_MODE enum unified to FULL=0, MODERATE=1, FAST=2, DEP=3.

Completeness (dual-parent check): 0 upstream files dropped from the merge tree;
6 fork files dropped, all intentional (upstream-superseded): CHANGELOG.md,
vendored/mimalloc/src/{arena-abandon,segment-map,segment}.c,
vendored/mongoose/{mongoose.c,mongoose.h}. Fork features (pagerank, depindex,
token_reduction, httplink) verified present and registered in tests/test_main.c.
src/pipeline/pass_parallel.c has an identical function set to upstream (49=49,
none dropped); the large line-deltas vs upstream are within-function divergence
of the fork extractor, not dropped functions.

Gate (run manually; hooks skip on merge commits): build green
(make -f Makefile.cbm cbm, exit 0); full C test suite 5980 passed / 2 failed /
0 crashes. The fork's pre-existing ASan crash in build_project_list_error_srv is
fixed by upstream's mcp.c rewrite, so the merge is strictly better than the fork
baseline on the crash axis.

Known issue, tracked separately (NOT a merge defect): 2 nondeterministic
failures in tests/test_incremental.c — incr_db_deleted_recovery:772 (diff_pct)
and incr_accuracy_vs_full:803 (full_nodes vs incr_nodes). Cause: the fork's
extractor (internal/cbm/extract_*.c) and parallel-resolve Route-node creation
are not thread-safe under the concurrent use of upstream's parallel pipeline
(run_parallel_pipeline), producing nondeterministic route/infra HANDLES edges
(~234k edge swing between runs). Sequential extraction (CBM_WORKERS=1) is
deterministic and correct. Root cause, bisect, and repro are documented in
notes/2026-06-24-fork-vs-upstream-divergence-assessment.md (section 8f); the fix
is deferred to a dedicated thread-safety audit (the make test-tsan target is
currently a stub and needs wiring).
2026-06-24 16:12:00 -04:00
Jeremy MaserangandClaude Opus 4.8 c13a9db612 fix(cli): const-qualify local pointers in codex_hook_strip for gcc 15
Under -D_GNU_SOURCE with optimization, glibc's string.h macros make
strstr() on a `const char *` (with a constant needle) yield a
`const char *`. gcc 15 then rejects assigning that to `char *` with
-Werror=discarded-qualifiers, breaking the build:

    src/cli/cli.c:1503: error: initialization discards 'const'
    qualifier from pointer target type [-Werror=discarded-qualifiers]

Minimal repro (gcc 15.2):
    const char *c = "hello";
    char *p = strstr(c, "ell");   // gcc -D_GNU_SOURCE -O2 -Werror=discarded-qualifiers

codex_hook_strip only reads through begin/end/cut (offset math and
byte comparisons, never writes), so making them `const char *` is the
correct fix and preserves the function's existing const contract
(`content` is already const). The malloc'd output buffer stays char *.
No behavior change; build succeeds on gcc 15.2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Jeremy Maserang <gothuncc@gothaunty.com>
2026-06-23 15:31:56 -04:00
b63aa9dc39 fix(cli): copy and sign the built binary on install instead of re-signing the stale target (#473)
* fix(cli): copy and sign the built binary on install instead of re-signing the stale target

`install` (especially with --force) only ad-hoc-signed whatever already sat at
~/.local/bin/codebase-memory-mcp and never copied the binary the operator ran
install from. An operator who built from source and ran `install -y --force`
was silently left with the OLD binary at the target — running stale code while
believing they had upgraded (#472).

Install now mirrors `update`: detect the running binary, copy it to the
canonical target (skipping the copy when we already ARE the target, which would
otherwise truncate the running file), make it executable, ad-hoc sign the
TARGET, and point all agent configs at the target. A different pre-existing
binary is only replaced with --force or interactive confirmation; --dry-run
reports the intended swap without touching anything.

The copy+sign also resolves the secondary report: a hand-copied clang build is
linker-signed (flags=0x20002) and gets Killed:9 when spawned by an MCP host —
re-signing ad-hoc (flags=0x2) makes it launchable, which install now does for
the placed binary.

Adds cbm_copy_binary_to_target() (with a same-file guard) plus regression tests
covering the binary swap and the self-copy guard.

Closes #472

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Shane McCarron <shane.mccarron@corvexconnect.com>

* fix(cli): address QA round 1

Extend cli_install_same_file_guard_issue472 with a symlink case: two distinct
path strings resolving to the same inode (which a non-canonical
cbm_detect_self_path vs the hardcoded target can produce) must also be detected
as same-file and skipped, not truncated. POSIX-only (#ifndef _WIN32).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Shane McCarron <shane.mccarron@corvexconnect.com>

* test(cli): guard install copy exec-bit assertion to POSIX

cli_install_copies_binary_to_target_issue472 asserted the executable bit on the
copied target, but cbm_copy_binary_to_target only chmods on POSIX (the exec bit
is not meaningful on Windows, and MinGW stat() derives it from the file
extension). Wrap the stat/S_IXUSR assertion in #ifndef _WIN32 so test-windows
passes; the content and creation assertions still run on all platforms.

Refs #472

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Shane McCarron <shane.mccarron@corvexconnect.com>

---------

Signed-off-by: Shane McCarron <shane.mccarron@corvexconnect.com>
Co-authored-by: Shane McCarron <shane.mccarron@corvexconnect.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 22:03:37 +02:00
Martin Vogel 69c16cada4 fix: deliver the static -portable linux binary on all install/update paths
The standard linux release binary dynamically links glibc 2.38+ and
GLIBCXX_3.4.32, so it fails to start on Debian 11, Ubuntu 20.04/22.04,
RHEL/Rocky 8/9, Amazon Linux 2, etc. — yet install.sh, the npm and PyPI
wrappers, and the binary's own self-update all fetched it by default,
contradicting the "single static binary" promise.

Point every linux install + self-update path at the fully-static
"-portable" asset (gcc -static), which has no glibc floor. macOS/Windows
are unaffected and unchanged.

- install.sh, pkg/npm/install.js, pkg/pypi _cli.py: select -portable on linux
- src/cli/cli.c: self-update download URL AND checksum archive name both use
  -portable on linux (they must match or the update fails checksum verify)
- scripts/smoke-test.sh: assert linux self-update targets the -portable asset
- scripts/ci/check-glibc-compat.sh: new guard — runs the binary inside
  debian:bullseye (glibc 2.31) and asserts it starts
- _smoke.yml: run the guard on the portable binary in smoke-linux-portable

Reproduced: standard binary -> "GLIBC_2.38 not found" on glibc 2.31;
portable binary runs cleanly.
2026-06-09 11:36:00 +02:00
Martin Vogel 13bd10812a fix(install): correct Antigravity CLI config paths (2026 unification)
Antigravity support targeted the pre-unification layout, so it never actually
configured the CLI:
- detection probed ~/.gemini/antigravity/ — the CLI now installs under
  ~/.gemini/antigravity-cli/ (brain/, mcp/, settings.json)
- MCP config was written to ~/.gemini/antigravity/mcp_config.json — Antigravity
  reads the SHARED ~/.gemini/config/mcp_config.json (mcpServers, command/args)
- the SessionStart hook + AGENTS.md targeted the stale dir

Point detection at ~/.gemini/antigravity-cli/, write the MCP server to the
shared ~/.gemini/config/mcp_config.json (creating ~/.gemini/config if needed),
and place AGENTS.md + the SessionStart reminder under ~/.gemini/antigravity-cli/.
Install, uninstall, install --plan, the detection test, and the README table
updated.
2026-05-31 21:02:51 +02:00
Martin Vogel 6c71244e63 feat(hooks): SessionStart reminders for Codex, Gemini CLI, Antigravity (#330)
Codex, Gemini CLI, and Antigravity all gained lifecycle-hook support, so give
them the same non-blocking SessionStart reminder Claude Code has — stdout is
injected as session context, nudging the agent to use codebase-memory-mcp
graph tools before grep.

- Codex: append a sentinel-delimited [[hooks.SessionStart]] block to
  ~/.codex/config.toml (idempotent upsert, preserves other content, removable).
- Gemini CLI: SessionStart hook in ~/.gemini/settings.json, reusing the shared
  JSON hook upsert (alongside the existing BeforeTool reminder).
- Antigravity: same JSON hook in ~/.gemini/antigravity/settings.json (it shares
  Gemini hook semantics).

The reminder command is written to be valid both as a TOML single-quoted
literal and a JSON string (no single quotes, no newlines). Wired into install,
uninstall, and the install --plan receipt. remove_hooks_json now prunes an
emptied event key so removal leaves no stale "<Event>": [] cruft. README
Multi-Agent table updated. Tests cover Codex upsert/idempotency/removal and
Gemini parity.
2026-05-31 19:39:31 +02:00
Martin Vogel 4c38c5a275 feat(install): add install --plan machine-readable receipt (#388)
An installer that configures MCP entries, instruction files, Skills, and hooks
across many agents should let callers see what it will mutate before it does.
`--dry-run` already lists planned writes in human-readable form; this adds the
machine-readable `agent.install.plan.v1` JSON receipt the issue asked for.

`install --plan` runs the real install dispatch in record-only mode — a global
g_install_plan recorder that each write-site function appends to (at the same
point it would write) while all mutations are disabled — then emits JSON with
agents_detected, config_files_planned, instruction_files_planned,
hooks_planned, writes_started:false, network_after_install:false, and
next_safe_command. Because the plan is recorded on the actual install code
path, it cannot drift from real behavior. No config is written, no index
deleted, no network used.

cbm_build_install_plan_json is exposed for testing; the test asserts the
receipt content AND that building it creates no config files.
2026-05-31 18:15:40 +02:00
Martin Vogel 30dfa952d9 fix(install): emit fish-native PATH syntax for fish configs (#319)
cbm_ensure_path appended `export PATH="<dir>:$PATH"` to every shell rc,
including config.fish — which is a syntax error in fish and broke users
fish config. Detect a .fish target and emit `fish_add_path <dir>` instead
(idempotent, prepends only if absent). POSIX shells are unchanged.
2026-05-31 16:13:47 +02:00
Martin Vogel 61453e928f test(hooks): guard PreToolUse gate shim against predictable temp file (#384)
The symlink-attack vector (predictable /tmp/cbm-code-discovery-gate-$PPID)
was removed in c29e6d5 when the blocking bash gate became a stateless
compiled augmenter writing to stdout only. Add a regression guard so a
predictable temp/state file can never be reintroduced: assert the emitted
gate shim contains no /tmp path and no $PPID, and delegates to hook-augment.

Export cbm_install_hook_gate_script (was static) so the security property
is directly testable.
2026-05-31 13:32:08 +02:00
Martin Vogel f88d0315ac fix(install): detect Cursor IDE and register MCP config (#222)
Cursor was never in the editor-detection table, so install/update only
ever wrote the VS Code config and silently skipped ~/.cursor/mcp.json,
even when Cursor was present. Uninstall removed the Cursor entry but a
subsequent install never re-created it.

Detect ~/.cursor/ as the Cursor agent, register the MCP server in
~/.cursor/mcp.json (mcpServers format, same as Windsurf/Gemini) on
install, remove it on uninstall, and list Cursor in detected agents.
2026-05-31 13:21:31 +02:00
Martin Vogel 0485d3f3b1 fix(cli): probe Windows PATHEXT variants in find_in_path (#221)
Agent CLIs on Windows are installed as .cmd/.ps1/.exe shims (e.g. opencode
via mise/npm), but find_in_path only probed the bare name, so they weren't
detected. Try .exe/.cmd/.bat/.ps1 per PATH entry on Windows.

Relates to #221 (opencode not detected). The install-time taskkill 'eq'
error from the same report is addressed separately — cbm_kill_other_instances
now uses _spawnvp with an argv array rather than a shell string.
2026-05-31 12:54:58 +02:00
Shane McCarron dedd33d975 fix(install): respect $CLAUDE_CONFIG_DIR in install/uninstall/update
Route Claude Code config paths (skills, .mcp.json, .claude.json,
settings.json, hook scripts) and agent detection through
CLAUDE_CONFIG_DIR-aware helpers, falling back to ~/.claude. Hook command
strings written to settings.json keep the legacy tilde form when the env
var is unset, so existing configs stay portable across HOME values. Prints
a one-line migration nudge when CLAUDE_CONFIG_DIR is set and a legacy
~/.claude tree still exists.

Adds cli_detect_agents_finds_claude_via_env and isolates CLAUDE_CONFIG_DIR
in the existing detection tests so the runner env can't leak in.

Distilled from #321 onto current main (adapts to the v0.7.0 non-blocking
augmenter hook signature, which the original branch predated). Closes #320.
2026-05-30 15:22:37 +02:00