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.
edf4954 to
3d34be5
Compare
|
Thanks @astandrik — reviewed carefully and we want this: the capability-aware rebuild is correct (the One thing before merge: the base is ~53 commits behind |
3d34be5 to
bfe8ca6
Compare
|
@DeusData The rebased revision also covers the persistence edge cases found during review: no-change downgrades refresh requested coverage while retaining the stronger stored/effective mode, changed files are re-extracted with Local results on |
Signed-off-by: Anton Standrik <astandrik@yandex-team.ru>
bfe8ca6 to
b036519
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 weakened. Files outside requested discovery continue to use the existing mode-skipped/hash mechanism. A no-change downgrade refreshes coverage metadata without rebuilding graph data. If a persistent artifact already exists, both metadata-only downgrades and full mode upgrades refresh it after the SQLite update.The public MCP API and SQLite schema are unchanged. Existing changed-file threshold and ADR preservation behavior are unchanged.
Regression coverage
fast → moderate: fail-before incremental no-op leftSIMILAR_TOat 0; pass-after rebuild creates similarity data and recordsindex_mode=moderatemoderate → fast: preservesSIMILAR_TOandindex_mode=moderate; the followingmoderateno-op remains stablefull → moderate: preserves full-onlyMacronodes andindex_mode=full; the followingfullno-op remains stable{}triggers a rebuild and restoresindex_modeindex_modeis rejected with length-aware yyjson comparison, rebuilt once, and normalizedVerification
Rebased onto
mainat7235a4d; PR head isbfe8ca6.222 passed, 2 failed224 passed, 1 failedASAN_OPTIONS=detect_leaks=0 build/c/test-runner pipeline—226 passedscripts/test.sh— passed onbfe8ca6, including production build, watchdog regressions, and security allow-list checksmake -f Makefile.cbm cbm— passedmake -f Makefile.cbm lint-format lint-no-suppress— passedgit diff --check upstream/main...HEAD— 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.