True incremental indexing: clean-rebuild parity, 6x post-edit indexing speedup, explicit freshness, and graph-derived search ranking - #1245
Open
ahundt wants to merge 980 commits into
Open
Conversation
Add CBM_STRINGIFY in src/foundation/constants.h:10-12 and replace the duplicate CBM_SCHEMA_STRINGIFY definitions in src/store/store.c:11848-12812. Use CBM_CONFIG_AUTO_DEP_LIMIT and CBM_STRINGIFY(CBM_DEFAULT_AUTO_DEP_LIMIT) in src/cli/cli.c:10542 so registry help and runtime dependency selection share one key and default. Add cli_config_registry_auto_dep_limit_uses_shared_default in tests/test_cli.c:6922. Verification: CLI 241 passed; store_arch 61 passed; schema_declared_property_keys 3 passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Write runs.json, steps.jsonl, results.json, artifacts.json, facts.json, and hashed manifests from scripts/benchmark-incremental-speed.py. Record candidate revision/build context from scripts/run-benchmark-experiments.py and keep absent legacy metadata as explicit unknown facts. Use experiment terminology for new runner, composition, autotune, provenance, and documentation records while retaining legacy campaign keys, flags, paths, and the shim at compatibility boundaries. Verified by 182 Python tests (1 skipped, 25 subtests), a rebuilt-binary smoke with 18 emitted step rows, and Draft 2020-12 validation of the generated facts bundle against docs/schema/benchmark-facts-v1.schema.json. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
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>
…onments Make automatic_dependency_source_indexing_disabled the benchmark default and add the paired enabled profile. Scope candidate_native_configuration to older candidates, reject unbacked capability claims, and pin all latest-product graph capabilities so one-factor ablations remain comparable. Remove inherited CBM_* product variables, retain isolated per-case caches, record native worker selection, and emit requested/effective configuration facts without inventing defaults for candidate-native or legacy reports. Keep retained historical reports readable. Verification: uv run --with pytest python -m pytest tests/test_benchmark_incremental_speed.py tests/test_benchmark_experiments.py tests/test_benchmark_experiments_shim.py tests/test_autotune.py tests/test_summarize_benchmark_results.py (184 passed, 1 skipped); ruff format --check and ruff check passed for all touched Python files. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
scripts/run-benchmark-experiments.py now distinguishes decoded JSON integers and finite numbers from booleans in validate_plan, validate_cell, and expand_matrix_spec. This rejects true/false schema versions, identity versions, repetitions, timeouts, frontier sizes, exact caps, and accepted exit codes while retaining positive fractional direct-cell timeouts. tests/test_benchmark_experiments.py covers each rejected boolean field and cross-checks build_automatic_spec capability declarations against benchmark-incremental-speed.py resolve_config_overrides to prevent the two profile maps from drifting. Verification: 185 passed, 1 skipped, 34 subtests passed in the benchmark Python set; 7,228 passed, 1 skipped in make -f Makefile.cbm test; ruff format --check and git diff --check passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Define CBM_MAX_AUTO_DEP_LIMIT in src/depindex/depindex.h and route src/depindex/depindex.c plus src/mcp/mcp.c through cbm_dep_normalize_configured_limit. Values 1..10000 remain caps, 0 remains unlimited, and negative or oversized legacy/internal values fall back to CBM_DEFAULT_AUTO_DEP_LIMIT instead of becoming unbounded. Parse config integers through cbm_config_parse_decimal_int in src/cli/cli.c so ERANGE and values outside INT_MIN..INT_MAX return the caller default rather than narrowing to int. Reject persisted auto_dep_limit values outside 0..10000, derive the registry range and MCP schema maximum from CBM_MAX_AUTO_DEP_LIMIT, and cover the boundaries in tests/test_cli.c, tests/test_depindex.c, and tests/test_mcp.c. Verified: cli 243 passed; depindex 40 passed; mcp 273 passed; bash scripts/check-source-safety.sh passed; git diff --check passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Read signed and unsigned yyjson integers into int64_t or uint64_t in cbm_mcp_get_int_arg at src/mcp/mcp.c before converting to int. Values below INT_MIN or above INT_MAX now return the caller default instead of wrapping; this prevents an oversized auto_dep_limit such as 4294967297 from narrowing to 1 before dependency-limit validation. tests/test_mcp.c covers positive and negative 64-bit overflow inputs. Verified: CBM_ONLY_SUITE=mcp make -f Makefile.cbm test: 273 passed; git diff --check passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Set incremental_reindex=always and name its alternatives full_rebuild and fast_mode_indexes_only in src/pipeline/pipeline.h and src/cli/cli.c. Replace eager/stale_on_* development spellings with at_publish and defer_*_reindexes for derived-result and rank refresh policies. Keep obsolete spellings out of the product registry. Restrict pass_calls.c same-target registry metadata canonicalization to exact store-backed scratch graphs, preserving LSP target precedence without adding a lookup to normal full or parallel indexing. Verification: pipeline 385 passed; cli 243 passed; mcp 273 passed; tool_consolidation 113 passed; pagerank 60 passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Read canonical and historical config spellings from scripts/benchmark-config-spellings-v1.json so mixed candidate runs translate only renamed key/value pairs. Run the once-per-binary probe under a temporary CBM_CACHE_DIR while holding CONFIG_SPELLING_MODES_LOCK. This prevents rank_refresh detection from mutating candidate-default experiment state or racing across workers. Mark cache state unknown when imported reports did not record it, display-canonicalize retained fact labels without rewriting inputs, and reject conflicting old/new values after canonicalization. Verification: 176 passed and 34 subtests; ruff format --check and ruff check passed; jq parsed the spelling map; git diff --check passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Add docs/benchmark-terminology.json with 86 validated definitions and 17 ordered step IDs, then generate docs/BENCHMARK_TERMINOLOGY.md and src/foundation/profile_terms_generated.h from that single source. Emit terminology_version, canonical terminology SHA-256, and generator SHA-256 in v2 fact bundles and manifests. Preserve docs/schema/benchmark-facts-v1.schema.json byte-for-byte and load retained v1 bundles without inventing missing terminology metadata. Verify with 192 passed, 1 skipped, and 34 subtests across the benchmark experiment, shim, normalization, and report suites; Draft 2020-12 validation for both new schemas; scripts/check-source-safety.sh; generator no-drift check; ruff; and git diff --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Add scripts/benchmark_fact_comparisons.py and docs/schema/benchmark-comparisons-v1.schema.json to group repetitions by effective implementation, capability, scope, cache, host, harness, terminology, and correctness contracts. Emit elapsed ratios only for parity_manifest_and_contract_v1 pairs; emit capability differences without ratios for capability_delta_manifest_v1 pairs; preserve source run and occurrence IDs and outer lifecycle wall-time rows. Extend fact_result_rows() with graph, freshness, and retrieval-quality outcomes and append generated comparison artifacts from generate_report(). Retained reports without fact bundles remain readable and report comparison status as unavailable. Define the versioned join and formula IDs in benchmark terminology 1.1.0. Verified 198 passed, 1 skipped, and 34 subtests; Draft 2020-12 schema validation, Ruff, source-safety, and git diff checks pass. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Move incremental_speed.py, run_experiments.py, summarize_results.py, fact_comparisons.py, autotune.py, active v2 schemas, terminology.json, configuration spelling data, and shell harnesses into benchmarks/. Keep scripts/_benchmark_compat.py plus historical Python and shell filenames as thin compatibility frontends. Preserve docs/schema/benchmark-facts-v1.schema.json because retained v1 bundles embed that exact URI; accept the former v2 URI only while loading retained results. Regenerate docs/BENCHMARK_TERMINOLOGY.md and src/foundation/profile_terms_generated.h from benchmarks/terminology.json. Update CONTRIBUTING.md, MAINTAINERS.md, docs/BENCHMARK_EXPERIMENTS.md, docs/EVALUATION_PLAN.md, and tests to use canonical paths. Verification: 205 passed, 1 skipped, 34 subtests passed; Ruff E4/E7/E9/F passed; comparisons-v1 schema validation passed for 42 retained bundles and 91 comparisons; generator --check, bash -n, git diff --check, and scripts/check-source-safety.sh passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Restore scripts/benchmark-index.sh, scripts/benchmark-search-graph.sh, and scripts/clone-bench-repos.sh to their upstream/main paths and exact blob hashes 756bda0, cc94147, and 883e078. Rename the branch-created single-run harness to benchmarks/run_benchmark.py. Remove historical Python frontends and scripts/_benchmark_compat.py so canonical benchmark execution has no shim or sys.path mutation. Add resolve_benchmark_script_path() and validate_benchmark_script_digest() in benchmarks/run_experiments.py. Retained scripts/benchmark-incremental-speed.py plan entries resolve at execution time without rewriting archived plans; missing cells fail closed when the resolved harness SHA-256 differs from the recorded benchmark_script_sha256. Ignore benchmark-results/ and *.facts/ while retaining the existing .worktrees/ ignore. Document run_benchmark.py versus run_experiments.py and preserve retained campaign flag and directory spellings. Verification: 207 passed, 1 skipped, 34 subtests passed; retained 42-cell audit reported 42 complete, 0 missing, 0 corrupt, 0 unplanned; Ruff E4/E7/E9/F, terminology generator --check, comparisons-v1 schema validation, git diff --check, and scripts/check-source-safety.sh passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
src/depindex/depindex.c mapped auto_dep_limit=0 to INT_MAX, then multiplied max_results by 5 for the manifest query and allocated INT_MAX entries for vendored dependencies. Saturate the query limit, size manifest results from returned rows, and share geometric candidate growth between npm and vendored discovery. tests/test_depindex.c covers INT_MAX discovery for both vendored Make dependencies and manifest-backed Python dependencies. CBM_ONLY_SUITE=depindex make -f Makefile.cbm test: 42 passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Move semantic_pair_classification and historical_speedup out of per-row loops in benchmarks/summarize_results.py, use pairwise for monotonic count validation, and make subprocess check behavior explicit. Use contextlib.suppress for expected score-conversion and process-group cleanup errors, and render capability differences and lifecycle rows without append-only transformation loops. Verified with Ruff E4/E7/E9/F/B/SIM/PERF/PLW (PERF401 excluded as a readability-neutral preference), Ruff format, and 204 passed, 1 skipped, 34 subtests across the five retained benchmark suites. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Exact incremental publication could retain lsp_constructor confidence 0.85 for a package re-export while a fresh rebuild emitted import_map confidence 0.95 for the same canonical target. Restrict calls_refresh_reexport_resolution in src/pipeline/pass_calls.c to store-backed exact publication and require cbm_pipeline_import_map_entry_is_reexport to prove the current IMPORTS edge re-exports the selected qualified name. Direct imports and different LSP targets retain existing precedence. Reuse import_map_source_file in src/pipeline/pass_pkgmap.c and centralize direct import-map strategy recognition in src/pipeline/registry.c. Configure pipeline_minhash_incremental_new_clone with incremental_derived_results_refresh=at_publish so its SIMILAR_TO freshness assertion explicitly requests derived-view regeneration. Verified: registry 61 passed; pipeline 385 passed; simhash 24 passed; incremental 164 passed; git diff --cached --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
cbm_cli_print_main_help omitted check_index_coverage even though classic tools/list and installed evidence guidance advertise it. Add the tool beside index_status and correct README.md classic-tool counts from 15 to 16. Verified: build/c/codebase-memory-mcp --help prints config preset <list|apply> and check_index_coverage; CLI suite 243 passed; git diff --cached --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
ha_load_guidance_config previously rendered any negative auto_dep_limit from a retained or manually edited _config.db as unlimited, while dependency indexing falls back to CBM_DEFAULT_AUTO_DEP_LIMIT. Reuse cbm_dep_normalize_configured_limit, document the configured and effective sentinel contracts in src/depindex/depindex.h, and consolidate the raw-config fixture in tests/test_helpers.h. Clarify in docs/BENCHMARK_EXPERIMENTS.md that retired script paths are load-time aliases rather than executable wrappers. Verified CBM_ONLY_SUITE=cli (243 passed), CBM_ONLY_SUITE=pagerank (60 passed), CBM_ONLY_SUITE=depindex (42 passed), changed-line clang-format checks, and git diff --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
build_automatic_spec emitted optional-graph-disabled and minimal-indexing with identical candidate labels and capability manifests, repeating the same measurements under two names. Emit only minimal-indexing in new automatic plans. Keep optional_graph_disabled as a retained-plan loader alias backed by the shared MINIMAL_INDEXING_CAPABILITIES map, document that compatibility boundary, and assert candidate/capability signature uniqueness. Correct the auto_dep_limit effective-sentinel comment in src/depindex/depindex.c. Verified 207 passed, 1 skipped, and 34 subtests across the six benchmark Python suites; Ruff format/check and git diff --check passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
docs/BENCHMARK_EXPERIMENTS.md presented optional_graph_disabled as a current command even though new experiment plans emit only minimal_indexing. Document minimal_indexing as the active command and retain optional_graph_disabled solely as a historical-plan loader alias. Align README.md with the 16-tool classic contract asserted by tests/test_tool_consolidation.c, remove a stale source-line reference in tests/test_mcp.c, and use CBM_DEFAULT_AUTO_INDEX_LIMIT for CLI fallback assertions. Verification: CBM_ONLY_SUITE=cli make -f Makefile.cbm test (243 passed); CBM_ONLY_SUITE=mcp make -f Makefile.cbm test (273 passed); bash scripts/check-source-safety.sh. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Apply Ruff's canonical single-line formatting to the Path expressions that load benchmarks/fact_comparisons.py and benchmarks/summarize_results.py. Verification: uv run --with pytest python -m pytest tests/test_benchmark_fact_comparisons.py tests/test_summarize_benchmark_results.py -q (55 passed); ruff format --check and ruff check over benchmarks and benchmark tests. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
src/depindex/depindex.c now applies dep_max_files with CBM_MODE_DEP bounded discovery before parsing, skips oversized packages atomically, preserves the existing cbm_dep_auto_index_effective API as a wrapper, and records package/file-cap statistics. src/mcp/mcp.c returns dependency_auto_index fields and actionable index_dependencies recovery from index_repository. src/cli/hook_augment.c reports active auto_dep_limit and dep_max_files values through the shared normalizers; disabled and unlimited configurations omit inapplicable recovery text. README.md, docs/CONFIGURATION.md, and the cli.c registry document the enforced behavior. Tests replace the former 1000==1000 assertion with real skip/unlimited fixtures and cover serialized MCP feedback plus config-sensitive hook guidance. Verification: CLI 243 passed; MCP 274 passed; depindex 42 passed; tool_consolidation 113 passed; input_validation 56 passed; bash scripts/check-source-safety.sh; git diff --cached --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
CLAUDE.md previously described internal/cbm as a Go/CGO wrapper even though CONTRIBUTING.md identifies the project as a pure C binary and internal/cbm contains Tree-sitter extraction code. Name that actual ownership instead.\n\nCONTRIBUTING.md hardcoded 14 MCP tools while src/mcp/mcp.c now derives the canonical count from TOOLS. Remove the drift-prone count and retain the JSON-RPC transport description.\n\nVerification: git diff --check Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
A unique_name registry fallback could bind a C call such as format() to an unrelated Variable extracted from a JSON schema. Registry insertion order then changed the CALLS target between incremental and clean benchmark graphs. Add cbm_pipeline_should_suppress_weak_noncallable_call_target in src/pipeline/pipeline_internal.h and apply it in resolve_single_call and resolve_file_calls. Keep Function, Method, type-like constructors, exact LSP targets, and strong same_module/import_map matches so callable C variables remain supported. Add focused coverage in tests/test_pipeline.c and tests/test_lang_contract.c. Verified CBM_ONLY_SUITE=pipeline (386 passed) and CBM_ONLY_SUITE=lang_contract (39 passed). Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Indent the inputSchema contract comment with the surrounding _hidden_tools object construction in cbm_mcp_tools_list_range at src/mcp/mcp.c:3158. This corrects session-introduced changed-line drift without reformatting pre-existing repository-wide violations.\n\nVerification: CBM_ONLY_SUITE=mcp make -f Makefile.cbm test (274 passed); bash scripts/check-source-safety.sh; git diff --cached --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
tests/test_matrix_known_classes.c previously treated any CALLS edge in the C++ operator[] fixture as proof of operator resolution. The edge was actually a weak match to a data field and disappeared when cbm_pipeline_should_suppress_weak_noncallable_call_target began enforcing callable targets.\n\nRename the case to state its contract, require zero false CALLS edges, retain the observed USAGE edge, and leave the missing operator[] desugaring documented as a known gap.\n\nVerification: CBM_ONLY_SUITE=matrix_known_classes make -f Makefile.cbm test (43 passed); git diff --cached --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Previous behavior: the hosted macOS LSan job stopped in scripts/test.sh step 0g before compilation when mktemp -d returned `mkdtemp failed ... Invalid argument`. Change: tests/test_makefile_logged_command.sh now uses the existing repository pattern `mktemp -d 2>/dev/null || mktemp -d -t cbm-makefile-log`. Both BSD and GNU forms still fail the test when neither can create the private work directory. Rationale: preserve the logged-command status contract while tolerating one transient default-template failure on the hosted macOS runner. Production sources, runtime bounds, and leak instrumentation are unchanged. Files: tests/test_makefile_logged_command.sh; notes/2026-08-09-upstream-main-10cb0e03-merge-assessment.md. Verification: bash -n passed; the normal harness passed under /bin/sh; an exported mktemp test double forced the first call to fail and the fallback run passed; git diff --check passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Previous behavior: section_cold_storm printed only 300 bytes of failed client output, then main() deleted the isolated cache and its cbm-daemon.log. The daemon-side shutdown reason was therefore unavailable after a Windows cold-storm timeout. Change: the failure branch at tests/windows/test_daemon_stability.py:364 reads and prints the final 32 KiB of cache-storm/logs/cbm-daemon.log before cleanup. Missing logs remain a visible diagnostic and do not change the test result. The pass path, subprocess schedule, timeout values, and product code are unchanged. Verification: uv run python parsed the file with ast.parse; git diff --cached --check passed. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Previous behavior: cli_concurrent_ui_then_standard_install_leaves_coherent_standard_set copied, hashed, and ad-hoc signed the full ASan/UBSan test runner before either child reached cli_install_order_reserve. The ubuntu-latest gcc 2/3 shard spent 430 seconds in the cli suite and failed at tests/test_cli.c:1853 with UI child did not acquire the deterministic activation lease. Change: tests/test_cli.c:1815 resolves the running test executable and hard-links it at the temporary install target. cbm_cmd_install therefore takes its existing same-file path while both children still execute the runtime-asset publication, flock ordering, UI-pack observation, and stale-pack removal assertions. Rationale: binary publication is covered separately; this test owns runtime-set locking. Removing irrelevant O(binary-size) staging prevents host load and sanitizer image size from controlling its synchronization. Verification: three concurrent ASan/UBSan targeted runs passed in 2.46-2.48 seconds; make -f Makefile.cbm lint-ci passed; git diff --cached --check passed. Production runtime, memory, latency, and asymptotic bounds are unchanged. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Previous behavior: when the production-binary supervisor probe missed Pipeline failed, tests/test_worker_error_response.sh:96 printed only client stdout and stderr. On Windows the client reported version_cohort.claimed_unheld followed by CBM daemon could not start within 30000 ms, but cleanup removed the cache before the daemon-side startup failure was visible. Change: the existing failure branch now prints the final 32 KiB of cache-supervisor/logs/cbm-daemon.log, or names the missing path. Passing behavior, timeouts, process ordering, cleanup, and product code are unchanged. Verification: bash -n tests/test_worker_error_response.sh passed; git diff --cached --check passed. A full local run correctly stopped at an unrelated active older-build cohort conflict, and no user daemon was interrupted. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
…anitizer stacks Previous behavior: the two uninstall activation tests planted codebase-memory-mcp.exe under the POSIX $HOME/.local/bin default, while cbm_cmd_uninstall resolves an omitted Windows --dir through %LOCALAPPDATA%/Programs/codebase-memory-mcp. The success case failed at ASSERT(!(binary_preserved)); the refusal case could pass without observing its intended file. Failed suites without a test-framework FAIL line printed only 15 tail lines, reducing the UI ASan abort to the shadow-byte legend and ==2000==ABORTING. Changes: tests/test_cli.c:2214 and tests/test_cli.c:2276 pass --dir=<fixture bin_dir> to both lifecycle tests. scripts/run-tests-parallel.sh:318 prints bounded context around ERROR/SUMMARY AddressSanitizer and UBSan runtime-error anchors before the existing tail. Verification: both focused ASan/UBSan uninstall tests passed independently; tests/test_parallel_harness_contract.sh passed; bash -n scripts/run-tests-parallel.sh passed; git diff --cached --check passed. Product runtime, allocation, and latency paths are unchanged. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
MemorySanitizer was absent from TF_SANITIZER_ACTIVE at tests/test_framework.h:38, so test_py_lsp_bench.c enforced its 150 ms native ceiling against a 270.28 ms instrumented run and test_incremental.c enforced its 2304 MiB production RSS ceiling against 3220 MiB of shadow/origin-inflated RSS. Add __has_feature(memory_sanitizer) to the shared test-framework predicate and make incr_memory_instrumentation_active() reuse that predicate while retaining MallocScribble and Guard Malloc detection. Native latency and RSS ceilings remain unchanged; the runtime, allocation count, and asymptotic bounds are unaffected. Verified by rebuilding build/c/test-runner with ASan/UBSan; py_lsp_bench passed at 32.29 ms; cs_lsp_bench passed at 15.63 ms; incremental/incr_full_index passed at 3876 ms with 1144 MiB RSS delta; and x86_64 Linux preprocessing selected TF_SANITIZER_ACTIVE=0 natively and __has_feature(memory_sanitizer)=1 with -fsanitize=memory. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Previous behavior: destination 9953c32 shipped external UI and integration sidecars plus release variants. Upstream d58afe5 recorded that this layout did not reduce the roughly three Microsoft !ml findings across dry runs and broke the unsuffixed archive names consumed by package manifests. What changed: - Makefile.cbm:427 and Makefile.cbm:1507-1509 retain depindex and PageRank sources while linking generated embedded_assets.c into the release executable. - src/main.c:1129 and src/ui/config.c:44 reject non-exact --ui and --port values before daemon admission with actionable errors. - src/pipeline/pipeline.c:3278-3295 reports main and sidecar rollback failures and returns persistence failure when cancellation rollback cannot restore the prior generation. - src/store/store.c:1291-2175 keeps upstream Windows file-API normalization on SQLite open, prepare, backup, seal, and dump paths. - src/cli/client_adapter.c:33-41 retains zero-length and SIZE_MAX growth guards from api-consolidation. - scripts/test.sh:239 and scripts/test.sh:320 keep vendored integrity and generation-bound embedded UI readiness in the canonical harness. - release scripts and npm, PyPI, and Go wrappers publish one unsuffixed four-member archive and one cached executable while retaining lease and concurrent-winner handling. Security rationale: upstream 93696ae measured that externalization moved rather than removed Microsoft heuristic findings; Makefile.cbm:231 and scripts/ci/check-binary-composition.sh retain separate executable/read-only ELF segments. The VirusTotal gate accepts only one disclosed Microsoft label ending in !ml and rejects every other malicious, suspicious, short, or malformed result. Verification: - final staged product build and ad-hoc signature passed - UI suite: 20 passed - pipeline rollback: 2 passed; destination-prepare cancellation: 1 passed - CLI installer-handoff test: 1 passed - embedded daemon readiness: 3 scenarios passed - Go: 42 passed; npm: 11 passed; PyPI unittest: 28 passed - vendored integrity and 8-archive/32-association extraction contracts passed - invalid --ui=maybe and --port=0 exited 2 with exact errors - staged diff whitespace and secret-pattern checks passed Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Previous behavior: upstream 4ed8d38 generated cbm_embedded_lookup as an O(A) linear scan, while destination 9953c32 used O(log A) binary search in cbm_ui_asset_lookup. main_run_daemon_ctl also parsed --port with atoi, so --port=9749x reached active-daemon status handling. What changed: - src/ui/embedded_assets.h:28 defines one O(log A), O(1)-memory lookup used by generated and stub asset tables. - scripts/embed-frontend.sh:55 forces LC_ALL=C bytewise ordering before emitting the table, and line 183 calls the shared binary search. - src/ui/config.c:59 parses ports in one bounded pass and preserves output values on failure. - src/main.c:2270 routes daemon-control ports through the same exact parser as MCP startup. - scripts/smoke-test.sh:2980 requires --port=9749x to fail before endpoint access with the exact range error. - tests/test_ui.c:312-316 covers first, middle, last, missing, and NULL asset lookups. Verification: - the new lookup test first failed to compile because cbm_embedded_lookup_sorted did not exist - nosan UI suite: 21 passed - generated embedded release binary built and passed codesign verification - all three generation-bound daemon readiness scenarios passed - daemon status --port=9749x exits 1 with error: --port requires a value between 1 and 65535 - main --port=65536 exits 2 with its exact actionable error - bash syntax and staged whitespace checks passed Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Keep one TSTreeCursor across py_bind_module_epoch registry lookups so top-level class filtering is O(R*N) with O(1) auxiliary storage instead of restarting indexed-child scans. Route cbm_registry_finalize_into method-index entries to its scratch arena, skip empty import specs, and avoid no-op LSP timing for unsupported languages. Record startup-subtracted instructions and cycles in run_native_extraction_comparison.py. The 41-pair arm64 matrix has exact output parity; Python scale latency is 47.21% below destination 9953c32 and 56.51% below upstream 4ed8d38. Verification: ASan/UBSan 8,637 passed and 2 skipped; TSan 1,349 passed and 2 skipped; MallocScribble 8,637 passed and 2 skipped; Guard Malloc 1,366 passed; Apple leaks 0 bytes; Clang analyzer exit 0. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Add the exact streamlined SessionStart script from destination commit 9953c32 to the finite migration allowlist. Static upstream re-embedding had retained only the older released identity, so activation could leave the later owned hook behind. Correct cli_update_agent_configs_finish_before_guard_release to pass argc=1 for its one-element argv array; the previous argc=2 caused the canonical ASan stack-buffer-overflow. Verification: isolated hook migration test passed; CLI ASan/UBSan suite 325/325; canonical ASan/UBSan 8,637 passed and 2 skipped. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Replace the superseded 10cb0e0 parent, test, installation, and benchmark facts with the 9953c32/4ed8d384 merge record through 5504dcf. Record ASan/UBSan 8,637/2, TSan 1,349/2, leaks 0 bytes, MallocScribble 8,637/2, Guard Malloc 1,366, and the exact 41-pair benchmark artifact ad21bfe84d0701d845d6b625f794c06692ddf7a6902efc88e04fa096dddc6b8f. Document the O(R*N) Python class scan, O(log A) asset lookup, strict O(L) parsers, both parents' retained capabilities, measured sub-1% shared-path equivalence, and the guarded publication/CI gates. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Record matching build/install SHA-256 30ed57eeee097a4aeff8f90a355b3da86c5159464586b0fb4794dfd17731d1f1, mode 755, strict code-sign verification, version/help output, and the installed MCP initialize response. Record zero production npm vulnerabilities and the 941-commit author-matching DCO audit. No codebase-memory-mcp process was active during installation. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Merge upstream main ad010b1 as the second parent. Keep the branch's unsuffixed single-composition archive paths and take upstream's SMOKE_REQUIRE_UI=1 assertions for Unix, Windows, and portable artifact smoke legs. Verification: YAML parse; venue-parity contract; smoke-fixture contract; Windows single-binary bundle contract. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
clang-format-20 rejected five layouts in parse_ui_flags, the daemon UI configuration call, rollback_quarantined_generation, prepare_existing_generation_for_replace, and cbm_embedded_lookup_sorted. Apply only the formatter-prescribed wrapping in src/main.c, src/pipeline/pipeline.c, and src/ui/embedded_assets.h; control flow and expressions remain unchanged. Verified with scripts/lint.sh --ci, make -f Makefile.cbm test (8,637 passed; 2 platform skips), and a byte-identical native extraction benchmark runner (dc1d8ecc6af78c7893e7df5247d0cf73f354149ab29c9b2e9cfb2ac032077d5a). Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Merge exact upstream parent aa6d740. src/foundation/diagnostics.c now obtains rss_bytes and peak_rss_bytes from cbm_mem_rss() and cbm_mem_peak_rss() instead of Linux mimalloc commit counters that can wrap through size_t. Preserve this branch’s process CPU counters, private diagnostics paths, retained-trajectory control event, and export-based soak cache isolation. The optional five-second diagnostics path remains O(1) time and O(1) space; normal request paths remain unchanged. Verified with diagnostics 7/7, memory/RSS 51/51, scripts/lint.sh --ci, cppcheck, clang-format, no-skip policy, and source-safety checks. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Record merge 8778050 with exact parents a2e019f and aa6d740, including cbm_mem_rss()/cbm_mem_peak_rss() lateral-path analysis and retained api-consolidation behavior. Reference the rotated 41-pair benchmark artifact aa4b0930907ec0d8e4dfcf79432053610b12aa68cb51fd89ad7b183996c700ae, full ASan/UBSan 8637/2 result, TSan 1349/2 result, zero-leak diagnostics lane, and installed binary SHA-256 08c8125485cd46a240b958ddfeec436fd356fdf68f1ada3ba25105a48cb24443. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Phase 9b-9 searched for the unrelated phrase 'unknown argument' even though cbm_cmd_update() rejects the retired flag with 'error: unknown update option: --standard'. Require that exact fail-loud message on macOS and Linux. Verified with bash -n, cli_activation_commands_reject_malformed_and_unknown_flags (1/1), the production-binary rejection predicate, and the canonical CI lint/source-safety gate. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Windows shard 2/2 failed the hang_after_summary contract because windows_descendants() launched PowerShell/WMI inside a one-second cleanup grace; a probe startup timeout was treated as a live descendant. Use CreateToolhelp32Snapshot plus Process32FirstW/Process32NextW and typed CloseHandle calls. Cleanup still fails closed on snapshot or enumeration errors, retains O(P) time and O(1) auxiliary space, and removes the subprocess-startup race. Verified with tests/test_parallel_harness_contract.sh, uv run python -m py_compile scripts/run-test-wave.py, and the canonical CI lint/source-safety gate. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
…te stores Previous behavior: application_session_open() called cbm_mcp_server_new(NULL), which opened an in-memory store, then immediately released that pristine store for every accepted daemon session. Extract the store-independent MCP server initialization into mcp_server_new_unbacked(). Keep public cbm_mcp_server_new(NULL) behavior unchanged, and let daemon sessions use the internal cbm_mcp_server_new_without_store() path before their required session context is set. The daemon application regression now compares a test-only atomic memory-store-open counter before and after session creation while retaining the existing no-cached-store assertion. Verified with make test (8,637 passed, 2 skipped), daemon_application (51 passed), daemon_runtime (47 passed), daemon_bootstrap (24 passed), daemon_ipc (47 passed), the full daemon stability guard, and 20 consecutive six-client cold-start waves. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Both Windows test shards stopped at tests/test_cli.c:9727 because test_released_streamlined_session_hook_script was referenced only by the POSIX lifecycle test and -Werror rejected the unused fixture. Seed that exact released SessionStart script in cli_windows_claude_hook_scripts_migrate_and_uninstall_all_owned_shapes(), run cbm_install_agent_configs(), and require the owned extensionless script to be removed. This covers both released SessionStart identities on Windows without changing product code. Verified with the ASan/UBSan CLI and agent-client lane (355 passed), clang-format, source-safety, and git diff --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
The prior release record stopped at product merge 8778050 and labeled the older 10cb0e0 consolidation base as the final-parent merge base. Record exact parents a2e019f and aa6d740, their ad010b1 merge base, the f0627b1 storeless daemon-session path, 41-repetition extraction results, five-sample cold-session results, a60199a Windows lifecycle coverage, and the remaining hosted/install gates. Preserve the measured allocator-page limitation instead of claiming every memory counter is lower. Files: - notes/2026-08-09-upstream-main-10cb0e03-merge-assessment.md Verification: - make -f Makefile.cbm test: 8,637 passed, 2 skipped - make -f Makefile.cbm lint-ci - make -f Makefile.cbm lint-source-safety - release prose and artifact fact assertions - scripts/check-dco.sh aa6d740..HEAD: 949 commits signed off Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
The Windows worker-error transport guard passed 4,522 unit tests, then the supervisor timed out because its shell exported CBM_TEST_DAEMON_RUNTIME_PARENT as an empty string. main_daemon_endpoint_new() pre-read that value and passed a non-NULL empty path, bypassing cbm_daemon_bootstrap_endpoint_new()\x27s established empty-is-unset rule. Remove the duplicate environment lookup and pass NULL to the shared bootstrap helper. Nonempty test overrides still flow through that helper, while invalid nonempty paths continue to fail at the IPC boundary. Files: - src/main.c Verification: - TEST_SEAMS=1 simulated-Windows worker error-response regression - native worker error-response regression - daemon_bootstrap ASan/UBSan suite: 24 passed - TEST_SEAMS=0 production SHA-256 unchanged at 14ab8e54db1f735a9e8e69067ce88c319f5b69113c694f3da3a73c5d5064dd90 - make -f Makefile.cbm lint-ci - make -f Makefile.cbm lint-source-safety Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Record the hosted a60199a Windows shard results: 4,522/23 and 3,812/47 unit outcomes followed by the shared empty-runtime-parent timeout. Document add6e20 delegating CBM_TEST_DAEMON_RUNTIME_PARENT handling to cbm_daemon_bootstrap_endpoint_new(NULL), the exact 8,637/0/2 ASan/UBSan result, both-parent asymptotic bounds, benchmark artifact hashes, and installed release SHA-256 14ab8e54db1f735a9e8e69067ce88c319f5b69113c694f3da3a73c5d5064dd90. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
…s backstop Merge upstream main 61b3b1b into 8b6d321 as exact parents. Resolve the sole conflict by retaining defs, calls, usages, type_refs, and rw benchmark output while taking upstream e628d9d's 30,000 ms liveness-only bound. The 50% sanitizer resolution-ratio assertion remains the performance gate; the flaky 150/1,500 ms absolute wall-clock gate is removed. Verification: CBM_ONLY_SUITE=py_lsp_bench make -f Makefile.cbm test passed 1 test at 98% resolution with 56 defs, 56 calls, 55 resolved calls, 176 usages, 25 type refs, and 20 read/write records. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
The release record still named a2e019f and aa6d740 as the exact merge parents after upstream/main advanced to v0.10.0. Record caf8128 parents 8b6d321 and 61b3b1b, the py-LSP liveness conflict resolution, the 8,637-pass ASan/UBSan result, and the 953-commit DCO audit. Replace the old extraction table with the neutral-harness 2-warmup/41-repetition matrix: 615 exact-output samples, result SHA-256 cd9aa079, byte-identical final/first-parent runners, 56.38% lower Python-scale latency, and 51.22% fewer Python-scale instructions than upstream. File: notes/2026-08-09-upstream-main-10cb0e03-merge-assessment.md Verification: git diff --cached --check; scripts/check-dco.sh 61b3b1b..HEAD (953 commits); make -f Makefile.cbm test (8,637 passed, 2 skipped); focused py_lsp_bench (1 passed); neutral runner all suites (4 passed each); native extraction comparison (615 samples, zero output differences). Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Both hosted CLANG64 shards built build/c-ui-open/codebase-memory-mcp.exe, while scripts/test.sh:325 passed the canonical extensionless Make target. Python os.path.isfile() rejected that path before the three readiness checks ran. tests/test_daemon_open_readiness.py:330 adds resolve_binary_path(), which selects an existing .exe sibling only on Windows. Missing paths still reach the existing SETUP FAIL exit-2 branch. tests/test_daemon_open_readiness_path.py:14 adds the stdlib regression. notes/2026-08-09-upstream-main-10cb0e03-merge-assessment.md records the parent ownership, CI evidence, O(1) test-only bound, publication state, and unchanged product benchmark identity. Verification: uv run python -m unittest discover -s tests -p test_*.py (272 passed, 1 skipped); uv run python tests/test_daemon_open_readiness_path.py (1 passed); uv run python tests/test_daemon_open_readiness.py build/c-ui-open-path-fix/codebase-memory-mcp (3 readiness cases passed); nonexistent binary returned exit 2 with SETUP FAIL; make -f Makefile.cbm lint-ci; make -f Makefile.cbm lint-source-safety. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
The hosted Windows fixture passed all three UI readiness checks, then tests/test_daemon_open_readiness.py:379 raised WinError 32 while TemporaryDirectory removed cache-active/logs/cbm-daemon.log. Endpoint status was already absent, but the exact daemon PID still held its log handle. tests/test_daemon_open_readiness.py:61 now waits up to five seconds on that PID through a Windows SYNCHRONIZE handle. stop_daemon() retains its force-kill backstop and raises if the PID remains after the second bounded wait. tests/test_daemon_open_readiness_path.py:24 locks the cleanup ordering. notes/2026-08-09-upstream-main-10cb0e03-merge-assessment.md records the hosted evidence, O(1) handle space, bounded wait, and unchanged product and benchmark trees. Verification: uv run python tests/test_daemon_open_readiness_path.py (2 passed); uv run python -m unittest discover -s tests -p test_*.py (273 passed, 1 skipped); uv run python tests/test_daemon_open_readiness.py build/c-ui-open-path-fix/codebase-memory-mcp (3 readiness cases passed); nonexistent binary returned exit 2 with SETUP FAIL; make -f Makefile.cbm lint-ci; make -f Makefile.cbm lint-source-safety. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
A final registered client could move the coordinator to STOPPING while another transport connection was already accepted but had not completed HELLO. runtime_service_stop_ephemeral_if_idle_locked deferred service shutdown, but the coordinator's narrower client census overrode that guard with coordinator_stopping. Hold the nested coordinator open for every runtime service, release that hold when runtime_service_begin_stopping_locked selects a terminal transition, and make a zero-client hold release enter STOPPING immediately. Standalone coordinator last-client behavior and permanent runtime behavior remain unchanged. Add daemon_runtime_final_disconnect_preserves_accepted_slow_hello, which failed before the fix at ASSERT(service_stayed_running) with reason=coordinator_stopping and now requires the accepted peer's exact HELLO to succeed in the same generation. Verified: focused ASan/UBSan final-disconnect tests (3 passed); slow-HELLO capacity, permanent lifetime, explicit stop refusal, and standalone last-client tests (1 passed each); make -f Makefile.cbm lint-format; make -f Makefile.cbm lint-source-safety; git diff --check. Signed-off-by: Andrew Hundt <ATHundt@gmail.com>
Owner
|
Thank you for the substantial follow-up and for working through the earlier blockers. We have recorded the updated benchmark, scope changes, and current DCO state. This still needs a fresh end-to-end correctness and security review of the current diff before we can make any merge commitment. Please keep contributor-authored commits DCO-compliant. If maintainers ultimately distill part of the work into a separate implementation, we will preserve clear contributor credit through appropriate co-authoring or explicit attribution. The review queue remains full, but this is queued for that fresh review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. What does this PR do?
Hey, thanks again for the cool project! This PR continues my earlier PR #151. This Aug 2 addresses your requests: the
api-consolidationbranch is now merged with upstream main. Two true merge commits bring in every upstream commit throughf0c65fb2a997(2026-07-29):d0f00de6bd6dcombines upstream560ad40d19b2with the previously verified headb42801f3f765and resolves all 14 textual conflicts, and41fd25cdd86bintegrates thef0c65fb2a997release-hardening wave. No history was rewritten; both parents are preserved in each merge. At that merge the branch was 0 commits behind upstream main, and every upstream commit throughf0c65fb2a997remains contained here, so CI can run. A third merge,a0f4380b6f18(2026-08-01), integrates every upstream commit throughd6be58ef9d43(2026-07-31). At the time of writing (2026-08-02 16:39 UTC,d6be58ef9d43) that is still the upstream main head, so the branch has caught main and is 0 commits behind. Every defect claim in section 4 was re-verified at that revision. Beyond the three merges, 37 follow-up commits fix defects found while validating the merged results (listed with their verification in each commit message). The merge also removed the 86 committed soak/memlab run-log files (1.3 MiB) reported separately as issue #1330; upstream has since removed them on main in66326c2c.The core claim is unchanged: upstream main's post-edit indexing is labeled incremental but returns a graph that differs from an independent clean rebuild in 3 of 3 repetitions on the measured build, that is, the graph it serves after an edit is incorrect, and upstream's own source comment documents that
FILE_CHANGES_WITHandDATA_FLOWSedges are not reproduced incrementally (pipeline_incremental.c:351-360atd6be58ef9d43). This PR makes incremental source-structure indexing exact, and in its default configuration indexes the same large-codebase edit 3.2× faster than the measured upstream build (569 vs 1,828 ms). After an edit the server names every deferred derived view (rank, routes, semantic edges, architecture), omits stale rank values where returning them would mislead, and withincremental_derived_results_refresh=at_publishproduces a graph identical to the clean rebuild in 3 of 3 repetitions while still beating its own full rebuild (8,568 vs 9,768 ms).The PR adds optional indexing of installed dependency sources with package identity, optional graph-derived search ranking, and a shorter default MCP tool list, and it extends the read-only Cypher subset, Git-snapshot change detection, and semantic analysis. One attribution correction to my previous description: the shared daemon is upstream's subsystem (
src/daemon/, merged here on 2026-07-23); this PR retains it and contributes fixes and hardening on it, listed in section 2. Since findings like these are easy to misread from descriptions alone, I would appreciate review against the code, tests, and published run reports rather than summaries.The full classic API, request schemas, and upstream 3D visualization are retained. Every major capability has a one-command switch and defaults can be trivially revised if preferred.
2. Capabilities and controls
Every setting is declared in one registry with its default, accepted values, and environment override:
CBM_CONFIG_REGISTRYinsrc/cli/cli.c:12997. Two commands control everything:The six preset bundles pair a tool surface (
streamlined-orclassic-) withautomatic-dependency-source-indexing-disabledor-enabled, plus therank-disabledandminimal-indexingbenchmark ablations (codebase-memory-mcp config preset listshows each name with its description; the apply transaction iscbm_config_apply_preset()incli.c:12925). When an environment override pins one of a preset's keys, apply returns status 1 rather than claiming an ineffective change.File names below are unique in the tree and live under
src/; each switch is the exact argument list forcodebase-memory-mcp, with the default in parentheses. Line numbers are at the branch head7433fee6bed3.cbm_pipeline_run_incremental()pipeline_incremental.c:2826config set incremental_reindex always(default
always;full_rebuildrebuilds atomically from scratch andfast_mode_indexes_onlyrestricts incremental reindexing to fast-mode indexes)at_publishrecomputes everything immediately and matches the clean rebuild exactlycbm_pipeline_run_incremental()pipeline_incremental.c:2826config set incremental_derived_results_refresh at_publishconfig set rank_refresh at_publish(default:
defer_all_incremental_reindexesfor both)auto_indexdefault at session start, suppress release notices for dev builds, initialize the active-image fingerprint before comparison, validate fingerprint-cache epochs and admit cross-volume caches, and initialize capped memory once in the daemon instead of in every CLI frontendmain_run_daemon_ctl()main.c:1728daemon start/daemon stop/daemon status(default: session-managed, started automatically)
MEMBER_OFreverse edge and a cross-language normalization pass that repairs extraction-miss cases, so classes participate in traversals and inherit rank from their members instead of staying disconnectedprocess_def()pass_definitions.c:279repair:
pass_normalize.czz_order_core, moved from ninth to firstcbm_pagerank_compute()pagerank.c:407config set rank_enabled false(default
true)index_dependenciesindexes named packages on demand, and when installed packages exceedauto_dep_limit(default 20, 0 = unlimited, max 10,000) the most-imported packages are selected, ranked by project import referencescbm_dep_auto_index_effective()depindex.c:984ranking:
depindex.c:583-616config set auto_index_deps true(default
false)_hidden_tools; calling_hidden_toolsreveals the full classic tool list live, no restart (upstream advertises all tools and curates only statically via startup--profileflags)cbm_mcp_tools_list_range()mcp.c:3429config set tool_mode classic(default
streamlined)formatoverride and an actionable invalid-format error; the merged head keeps upstream's UTF-8 output guard so quoting or truncation cannot split a multibyte charactercbm_mcp_response_format()mcp.c:2685config set default_response_format json(default
toon)auto_indexin
CBM_CONFIG_REGISTRYconfig set auto_index false(default
true; upstream defaults tofalseand skips with a log hint)WITH, and optional-match semantics; adds multi-key ordering, output caps, and schema-aware rejection of unsupported syntax; the tool description, parser, and executor share one definition, and the query schema is stable against incidental storage changescbm_cypher_execute_impl()cypher.c:9091cbm_pipeline_pass_semantic_edges()pass_semantic_edges.c:1783config set semantic_edges_enabled falseconfig set similarity_enabled false(default
truefor both)cbm_git_snapshot_read()git_snapshot.c:319config set githistory_enabled false(default
true)pass_route_nodes.c, run in both the full and incremental pipelines) and adds a dedicated pass that links each HTTP call site to its handler, fixing missing or misclassified linkscbm_pipeline_pass_httplinks()pass_httplinks.c:1375config set httplinks_enabled false(default
true)build_fingerprint_modein
CBM_CONFIG_REGISTRYconfig set build_fingerprint_mode always_rehash(default
cached_exact)3. Measured results
The headline numbers come from a 39-cell benchmark experiment: 13 configurations, each run 3 times, paired and interleaved across configurations to reduce timing drift, on production builds in isolated Linux Docker containers (clang-18,
-O2, 16 build jobs, 16 container CPUs, container--init, fresh case-owned repositories and caches, arm64). Every cell applies the same real C source edit to a large codebase, runs incremental indexing, and compares the resulting graph with a separate clean rebuild after the same edit; every configuration also passes 12 retrieval-evidence checks (4 post-edit retrieval probes across the 3 repetitions: the changed file, its source text, its graph node, and its architecture evidence). All 39 planned cells completed with zero missing, corrupt, duplicate, or unplanned cells. Docker Desktop exposed 7.75 GiB despite the requested 16 GiB limit; the largest observed candidate peak was about 1.6 GiB, so no run was memory-capacity limited.Two scope statements, up front. First, the measured upstream build is
aedb979f5570(upstream main as of 2026-06-28), pinned when the benchmark cohort was frozen; the upstream main now merged into this branch isd6be58ef9d43(2026-07-31). The graph-correctness defect reproduced on the measured comparator, and at current upstream maind6be58ef9d43upstream's source still documents non-reproduced incremental edges (pipeline_incremental.c:351-360, the file is unchanged sincef0c65fb2a997) with no parity verification mechanism. Second, this matrix ran at PR revision2c2de761a24e, so its timing ratios apply to the named revisions, edit, and machine; a second full 39-cell matrix has since re-measured the merged branch head7433fee6bed3against an upstream build atd6be58ef9d43(below). What the merged head does run is the full test suite, including the incremental-parity tests, at the final verified head listed in section 7.All timings are medians (p50) over the 3 repetitions. Repeated query p50 is the median latency of the repeated read-only graph queries the retrieval probes issue within each candidate's persistent MCP session, so it measures a warm service, not process startup. Response payload p50 is the exact default tool-response size (tokens are the recorded deterministic bytes/4 estimate). Peak RSS is the highest peak resident memory observed across the 3 repetitions. "Deferred views named" means the server explicitly names each optional derived view awaiting recomputation after the fast source-structure refresh, and the freshness-scoped comparison still checks every remaining canonical node, edge, property, and file hash against the independent rebuild. A clean rebuild of the same post-edit tree is the ground truth: a post-edit graph that differs from it is incorrect, and queries against it can return wrong answers.
aedb979f5570, defaultminimal-indexingpresetUpstream main's post-edit reindex is labeled incremental but returns an incorrect graph, one that differs from the ground-truth rebuild (speed bought with wrong answers), while this PR's default is both 3.2× faster on the edit (569 vs 1,828 ms) and exact on non-stale source structure. The minimal preset outputs a graph identical to the clean rebuild while indexing the edit 3.6× faster (508 vs 1,828 ms) and full-indexing 1.37× faster (5.136 vs 7.055 s) than the measured upstream build. Two metrics go the other way and I state them plainly: upstream's repeated read-only query latency is lower (6.2 vs 16.7 to 23.2 ms; this PR's replies carry first-response freshness and provenance context and are 29% smaller, 429 vs 604 bytes), and upstream's full index is faster than this PR's default configuration (7.055 vs 10.029 s) because the default enables optional capabilities upstream does not have: disabling semantic edges alone brings the full index to 6.659 s, and the rank, similarity, git-history, and route ablations measure 9.269 to 10.140 s. Upstream peak RSS was not recorded in this run, so no memory comparison against upstream is claimed.
Refresh-at-publish recomputes every global derived result (rank, semantic edges, architecture, routes) immediately after the edit; at 8,568 ms that is still faster than its own 9,768 ms full rebuild, which is the only other way to get them all fresh. It is opt-in; the default defers exactly that graph-wide work and names the deferred views until refreshed.
Automatic dependency indexing stays off by default so its cost stays out of the default first index: enabling it indexed this workload's six installed packages in about 27 s of dependency work at first index, which is work upstream cannot do, and after an edit, checking unchanged dependencies cost 13 ms.
Two earlier development checkpoints (
c9726c7fd9b7,0fcb7e109518) ran in the same matrix and quantify what the post-merge work fixed: their native configurations auto-indexed dependencies (about 20.5 to 20.8 s of the 43.8 s full index) and carried a since-removed startup regression that pushed repeated queries to 187 to 206 ms; the current default full-indexes in 10.0 s with 23.2 ms repeated queries, and both checkpoints also failed the canonical-graph gate that the current head passes.A second 39-cell matrix re-measured the merged result: same container design (13 configurations, 3 repetitions each, paired-interleaved, isolated Linux Docker containers, arm64, 16 container CPUs), run at branch head
7433fee6bed3(2026-08-02) with the upstream comparator freshly built atd6be58ef9d43, the upstream main head this branch merges. All 39 planned cells completed with zero missing, corrupt, duplicate, or unplanned cells. The mutation differs from the first matrix (a new isolated C source file is added instead of editing an existing one), so timings are not comparable between the two matrices. Upstream's default again served an incorrect post-mutation graph in 3 of 3 repetitions: it differs from the ground-truth rebuild of the same tree, so queries after the edit can return wrong answers, and upstream ships no mechanism that detects this. Every configuration of this PR passed its graph gate.d6be58ef9d43, defaultminimal-indexingpresetminimal-indexingis the measured Pareto frontier of this matrix: no passing, fully measured candidate in the same workload is at least as good on overall quality and every cost axis while strictly better on any. All speed comparisons below are how much faster this PR is than current main (d6be58ef9d43) in this matrix; a negative value means slower, and every negative is bought by a named capability gain. Post-mutation indexing: +578% (473 vs 3,208 ms) at upstream-equivalent capabilities and +513% (523 ms) at the default, roughly 6x either way, and correct where upstream's result is incorrect. Clean rebuild: -6% (8.025 vs 7.508 s) at upstream-equivalent capabilities (parity verification runs in the test and benchmark harness, so it adds nothing here; the difference is graph-building work this branch always does, including theMEMBER_OFclass-connectivity repair and exact statistics publication, with no single component isolated by an ablation, and at this price the post-mutation graph is verified correct where upstream's is incorrect); -13% (8.674 s) at the default, which adds ranking, similarity, git history, and route linking with the measured benefits in the table below; +81% (4.141 s) withminimal-indexing, fully correct. Repeated query: -2% (17.6 vs 17.3 ms) at upstream-equivalent capabilities, closing the first matrix's 3 to 4x gap, -14% (20.0 ms) at the default, +4% (16.6 ms) withminimal-indexing, at effectively equal peak memory (1,532 vs 1,536 MB). In this workload upstream's default reply is smaller (306 vs 407 bytes); the PR's replies carry the first-response freshness and provenance context described above. Refresh-at-publish again produced the fully identical graph while beating its own clean rebuild (7,805 ms vs 8,437 ms).The default's remaining costs are itemized capability prices, not overhead, and each is refundable with one switch. Overhead, cost that returns no value, is what this head (
7433fee6bed3) removed: the first matrix's repeated-query deficit does not reproduce (17.6 ms with upstream-equivalent capabilities vs upstream's 17.3 ms), and the like-for-like clean rebuild is -6% (0.52 s, 8.025 vs 7.508 s) at equal peak memory. Parity verification runs in the test and benchmark harness, not in production indexing, so that 0.52 s is not a verification tax: it is graph-building work this branch always does, including theMEMBER_OFclass-connectivity repair and exact statistics publication, with no single component isolated by an ablation. What the build delivers at that price is the guarantee upstream does not offer at any price: the post-mutation result is verified correct. Every cost above that baseline is priced below against the same build with exactly that capability toggled (all other defaults unchanged); the default configuration's own rebuild spread is [8.437, 9.599 s] over 3 repetitions, so prices under 0.6 s are smaller than that spread and should be read as approximate:SEMANTICALLY_RELATEDpair matches the clean rebuild, none missing, none spuriousconfig set semantic_edges_enabled falseconfig set rank_enabled falseSIMILAR_TOedges for near-duplicate discoveryconfig set similarity_enabled falseconfig set httplinks_enabled falseFILE_CHANGES_WITHcoupling edges and Git-scoped incremental change detectionconfig set githistory_enabled falseconfig set auto_index_deps trueSummed, the default's entire repeated-query premium over upstream at the merged head (
7433fee6bed3) is 2.7 ms (20.0 vs 17.3 ms). The one axis where upstream is faster like-for-like is the clean rebuild, where this PR is -6%; what stands on the other side of that price is the post-mutation result: +578% (473 vs 3,208 ms) with a verified-correct graph, where upstream's faster-looking incremental serves an incorrect graph, one that differs from its own ground-truth rebuild in 3 of 3 repetitions, speed bought with wrong answers and no switch that refunds it.Result-quality contribution of the two new optional capabilities, isolated on one PR build (
13a4679b27f6) and test project by repeating the same index-then-query measurement 5 times per state, alternating the capability between enabled and disabled. MRR (Mean Reciprocal Rank) rewards placing the known correct answer near the top, Hit@1 and Hit@5 report whether it appears first or within the first five, nDCG@5 (normalized Discounted Cumulative Gain) rewards correct ordering within the first five, and task success means the task's named expected answer was returned:zz_order_core) ahead of eight lexical-only decoyszz_order_corereturned 1st of 9; MRR, Hit@1, Hit@5, nDCG@5, task success all 1.000zz_order_core9th of 9; MRR 0.111, the other four metrics 0canonicalDependencyAPI) with its dependency, package, and read-only provenance on the same resultcanonicalDependencyAPIreturned 1st, with package identitycanonicalDependencyAPIabsentSemantic refresh quality was re-verified in the same matrix: with refresh at publish, every judged
SEMANTICALLY_RELATEDpair matches the clean rebuild, with none missing and none spurious.4. Upstream main defects this PR corrects
Every claim in this table was re-verified by direct code reading at upstream main
d6be58ef9d43(2026-07-31, the revision merged into this branch) unless a different revision is named; upstream file:line references are at that revision.d6be58ef9d43cbm_pipeline_run_incremental()pipeline_incremental.cFILE_CHANGES_WITHandDATA_FLOWSedges are not reproduced incrementally (pipeline_incremental.c:351-360); no parity guarantee or verification mechanism exists; measured divergence 3 of 3 onaedb979f5570resolve_store()mcp.cresolve_store_internal,mcp.c:2081-2083); upstream's daemon single-ownership makes cross-process replacement rarer but the check is still absentWITHstages, optional matches, and multi-keyORDER BYcompute correctlycbm_cypher_execute_impl()cypher.cparse_order_by_clauseparses exactly one ordering key, so secondaryORDER BYkeys are silently dropped (cypher.c:1699-1709); the aggregate, post-WITH, and optional-match failures were verified on the measured comparatoraedb979f5570; upstream has since fixed aggregate-column classification and two optional-match defects (PRs #1221, #1177, #1385, contained here through thed6be58ef9d43merge), while multi-keyORDER BYremains absent upstreamLIMITlowers but cannot bypass the configured row cap, and truncation is reported with the limiting condition instead of being silentscan_pattern_nodes()cypher.cmax_rowstimes a fixed growth factor before inline property filters andWHERErun (cypher.c:3027-3052, cap applied atcypher.c:3037), so matching rows past the prefix are discardedauto_indexin
CBM_CONFIG_REGISTRYfalseand an unset value skips indexing with only a log hint (mcp.c:11156-11169)MEMBER_OFreverse edge and a cross-language repair pass for extraction-miss casesprocess_def()pass_definitions.c:279repair:
pass_normalize.cDEFINES_METHODonly when extraction supplies the parent; there is no reverse edge and no repair pass (pass_normalize.cdoes not exist upstream), so extraction-miss classes stay disconnectedindex_statusreports whether the working tree is dirty and whether the index matches itadd_git_context_json()mcp.cadd_git_context_json(mcp.c:2242) emits branch and commit identity but no working-tree-state field; upstream's watcher tracks a dirty signature internally but does not report it as provenancecbm_pipeline_githistory_compute_with_limits()pass_githistory.c:646FILE_CHANGES_WITHcandidates at a hard-coded 8,192 (MAX_COUPLINGS,pass_githistory.c:346) collected in hash-table iteration order with no sort, no configuration, and no log (pass_githistory.c:215-217, 331), so on a history with more qualifying pairs the emitted coupling edges are an arbitrary subset rather than the strongest couplings; per-file temporal facts stop at the first 16,384 files encountered (MAX_FILE_TEMPORAL,pass_githistory.c:406)Three defect claims from my previous description are retired because re-auditing upstream showed them already fixed there: the half-opened SQLite handle on failed open (closed upstream in
e6e9c58e, before the measured comparator), the config-linking pass's large stack arrays (the pass was rewritten upstream and now holds only small static tables), and the dropped route-discovery pass (rebuilt upstream aspass_route_nodes.c; the merged branch keeps upstream's pass and adds its own, section 2). Shutdown lifecycle also converged: upstream's daemon now joins worker threads and plumbs cancellation, and the merged branch carries both sides' shutdown work; this PR's remaining distinct contribution there is the verification discipline (leak gate, cancellation and reaping tests) rather than a defect claim.One further upstream hard-limit defect is fixed here but deliberately kept out of the table, because neither tree currently wires the affected scanner into a production pass: upstream's env-URL walker holds a fixed 512-byte-per-frame path stack and silently skips directories nested deeper than 256 levels (
pass_envscan.c:514, 532atd6be58ef9d43). This branch's walker uses dynamically grown path storage (walk_path.h), logs unrepresentable bindings instead of dropping them, and pins both behaviors with the regression testsenvscan_walks_more_than_256_pending_directoriesandenvscan_accepts_root_path_longer_than_512_bytes.Every remaining row is regression-tested. Defects found while merging upstream and validating the result were fixed before this update; each is documented in its commit message. Two behaviors are boundaries rather than defects: the Cypher subset does not claim full openCypher conformance, and optional derived results refresh on the documented deferred schedule. Production
src/contains nosystem()calls, and the heap-leak gate reports 0 leaked bytes at the final verified head.5. Compatibility, breaking changes, and migration
config set tool_mode classicrestores the classic list on a running installation. Streamlined and classic surfaces answer from the same graph and Cypher contract.daemon stoprefusal while committed clients remain, and orderly SIGINT/SIGTERM shutdown (cancel and reap work, join background threads, close transports, release claims and leases, remove the endpoint). This PR's daemon changes are the fixes listed in section 2.--reset-indexesis passed; the system-wide upgrade verified at an earlier head preserved all 462 existing indexes across 17 detected clients. The installer recognizes configuration written by earlier development builds and replaces it canonically instead of rejecting it, keeps user-owned TOML child tables when replacing a managed parent table, and refuses to overwrite genuinely user-edited entries.d6be58ef9d43, the repository's CI has run its full matrix on this pull request at7433fee6bed3: the test shards (Linux gcc, macOS 14 and 15-intel, Windows CLANG64), ThreadSanitizer on three platforms, lint, smoke on Linux, macOS, and Windows, CodeQL, and the security gates all pass; the DCO sign-off check is the only failing check.6. How to run the tests
The full suite passed with zero failures at the final verified head (7,823 passed, 2 platform-specific skips), and the CI lint gates (
lint-ci) exit 0 there. The suite includes generalized extraction and incremental tests across C, C++, Go, Python, JavaScript, TypeScript, Java, Kotlin, and Rust, mixed-language call resolution, the daemon lifecycle, bootstrap, and IPC suites, and the tests that arrived with the merged upstream commits. The benchmark runner records exact candidate commits, binary SHA-256 values, compiler and optimization flags, CPU and memory allocation, environment overrides, case cleanup, and invalid-run status in an immutable audit manifest.7. Evidence and revisions
f0c65fb2a997d6be58ef9d43d0f00de6bd6d560ad40d19b2and the previous verified headb42801f3f765; all 14 textual conflicts resolved, no history rewrite41fd25cdd86bf0c65fb2a997a0f4380b6f18d6be58ef9d43; no history rewrite24aa8a415f5c7433fee6bed32c2de761a24eaedb979f5570c9726c7fd9b7,0fcb7e10951813a4679b27f6All experiments ran on production builds. The first 39-cell run set's immutable audit manifest has SHA-256
1becd57c00edbe965073f4d7c9a79cca8812947f207ed51851c856369aa2c002, and the second run set's (branch head7433fee6bed3, 2026-08-02) has SHA-2561e8f0d96128bd352107a0fb1633bcb0bcbd696a5ea8cb8226569d62e580a65e0; each experiment root retains the input specification, per-run manifests, container environment records, logs, build identities, and cleanup status, so the numbers are independently reproducible with the command above. The generated reports are published in a gist; its current tree contains the 2026-07-28 run set and the earlier 39-cell runbe2097bdbf14, and the focused ranking, dependency, and semantic reports remain in the gist revision history.Ranking follows PageRank (Brin and Page, 1998) and LinkRank (Kim, Son, and Jeong, 2010); nDCG (Järvelin and Kekäläinen, 2002) defines the ranking metric; RepoGraph (ICLR 2025) motivates repository graphs. The repository experiments, not the citations, are the evidence that this implementation works.
8. Checklist
make -f Makefile.cbm testat the final verified head: 7,823 passed, 2 platform-specific skips)make -f Makefile.cbm lint-ciexit 0 at the final verified head: cppcheck 2.20, LLVM 20 clang-format, suppression-policy and source-safety checks; the previous body's 49 open findings and 20 formatting violations are cleared)