fix: rebuild index when mode adds capabilities#1090
Conversation
daaeae7 to
d3fc385
Compare
|
Thanks for the mode-capability fix and regression coverage. This is triaged as a normal-priority 0.9.1-rc correctness PR. Review will focus on the capability ordering, rebuilding only when a requested mode adds unavailable graph data, preserving valid incremental state, and keeping same-mode reindex behavior unchanged. |
@DeusData I ran into this while working with a really large repository: https://github.com/ydb-platform/ydb Version 8 wasn’t able to index it at all, but version 9 managed to handle it successfully. Thanks for the improvements — I really love your codebase memory tool! |
d3fc385 to
edf4954
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes incremental routing so it accounts for the capability level of the stored index (via Project.index_mode), forcing a full rebuild when a requested mode requires capabilities the existing index does not have, while preserving stronger stored capabilities during requested-mode downgrades.
Changes:
- Persist
index_modeon theProjectnode during structure pass and parse it during routing to detect capability upgrades. - Route
fast → moderate/full(andmoderate → full) transitions to a full rebuild instead of an incremental no-op. - Run incremental changed-file extraction using an explicit
effective_mode(stored mode) to preserve additive capabilities across downgrades, and add regression tests for mode transitions and malformed/NUL-suffixed metadata.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/test_pipeline.c | Adds regression tests covering mode upgrade rebuilds, downgrade preservation behavior, and malformed/NUL-suffixed index_mode metadata handling. |
| src/pipeline/pipeline.c | Persists Project.index_mode, parses stored mode, and blocks incremental routing when requested mode needs missing capabilities. |
| src/pipeline/pipeline_internal.h | Updates incremental pipeline contract to accept an effective_mode for changed-file extraction. |
| src/pipeline/pipeline_incremental.c | Applies effective_mode to incremental extraction (incl. macro gating) while keeping requested mode for discovery/exclusions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Anton Standrik <astandrik@yandex-team.ru>
edf4954 to
3d34be5
Compare
Summary
index_modeRoot cause
Incremental routing originally considered stored file hashes and the discovered-file threshold, but not the capability level of the stored index. This caused unchanged
fast → moderateupgrades to take the incremental no-op path.After the first fix, changed-file downgrades still re-extracted with the weaker requested mode. That could remove stored capabilities such as
SIMILAR_TOedges or full-modeMacronodes.The metadata parser also compared yyjson strings with
strcmp(). A valid JSON string containing"full" + U+0000 + "garbage"therefore matched"full"at the embedded NUL and could incorrectly select incremental/no-op instead of the conservative rebuild route.Mode transitions
fastmoderate/fullmoderatefullDowngrades keep the stored
index_mode;p->modeand Project metadata are not rewritten. Files outside requested discovery continue to use the existing mode-skipped/hash mechanism.The public MCP API and SQLite schema are unchanged. Existing changed-file threshold and ADR preservation behavior are unchanged.
Regression coverage
fast → moderateleftSIMILAR_TOat 0 because routing selected incremental no-opindex_mode=moderatemoderatebuild, changing a Go file and requestingfastremoved its similarity contributionmoderate → fastkeeps the sameSIMILAR_TOcount andindex_mode=moderate; a followingmoderateno-op remains stablefullbuild, changing a C file and requestingmoderateremoved full-onlyMacronodesfull → moderatepreservesMacronodes andindex_mode=full; a followingfullno-op remains stable{}triggers a rebuild and restoresindex_modeindex_modevalue containing U+0000 afterfullwas treated asfull, selected incremental no-op, and retained a DB-only sentinelindex_mode=fastVerification
222 passed, 2 failed224 passed, 1 failedASAN_OPTIONS=detect_leaks=0 build/c/test-runner pipeline— 225 passedscripts/test.sh— 6015 passed, 1 existing platform skip; watchdog/security checks and production build passedmake -f Makefile.cbm cbm— passedmake -f Makefile.cbm lint-format lint-no-suppress— passedgit diff --check— passedscripts/lint.shwas attempted locally. The environment has nocppcheck, and its Homebrewclang-tidyreports broad pre-existing errors outside this diff. The independent format/no-suppression gates passed; the GitHub lint job is the authoritative full lint check.