Repository navigation
fix(index): a repeat full index keeps the name words of files it didn't change - #3017
Merged
Merged
Conversation
…'t change A library indexAll() over an existing index cleared the name-segment vocabulary (the words in symbol names that the prompt hook and codegraph_explore match plain-language questions against) before extraction. The store skips files whose content hash is unchanged, so their names were never written back: a second run with no edits left the table empty, and a run after an edit kept only the edited files' names. Sync and healSegmentVocabIfEmpty() repair only a completely empty table, so a partial one stayed that way. A cancelled run emptied the table as well, because the clear ran before the abort check. The CLI was not affected: `codegraph index` recreates the database first. The table is now cleared up front only when the database is fresh. Over an existing graph it is kept, and once a run completes without being cancelled, one DELETE drops the rows of names that no symbol carries any more (file and import nodes don't count, as on the write path). That keeps the orphan cleanup the clear used to do. The prune also resets the session's set of names already written, so a pruned name that comes back later in the same session gets its rows again instead of being skipped. Validation: - Kit repro with the PR's fixture: on main a second indexAll() took the table from 11 rows to 0, an edit plus a third run left 4, and a cancelled run emptied it. With the fix it stays at 11 rows, the renamed class's 3 rows give way to the new name's 3, and a cancel keeps them all. - 5 new tests in segment-vocab.test.ts; 4 fail on main's source, and the fresh-database guard passes on both. Three mutations are caught: no prune, no reset of the written-names set, no clear on a fresh database. - CLI: `codegraph init` then `codegraph index` write the same 11 rows on main and with the fix. - Real repo, vscode src/vs/base + src/vs/editor (1,388 files, 56,406 nodes, 66,250 vocabulary rows), a library indexAll() over the existing index, 3 interleaved runs per arm: main empties the table (66,250 to 0 rows); the fix keeps all 66,250. The prune takes 40 ms of each run, and the runs take the same time (median 8.37 s on main, 8.13 s with the fix). - Cost at scale: the prune statement takes 288 ms on a 10x replica of that index (564,060 nodes), and about 1.2 s on a synthetic graph with 505k vocabulary rows (170k distinct names); a full re-index of that size re-parses every file. Reimplements PR #2252 by @rudycelekli. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
colbymchenry
force-pushed
the
claude/fix-vocab-reindex
branch
from
October 29, 2026 18:42
76d1ffd to
009cc45
Compare
This was referenced Oct 29, 2026
inth3shadows
added a commit
to inth3shadows/codegraph
that referenced
this pull request
Oct 29, 2026
Brings 4955eac..787eafb (colbymchenry#3014, colbymchenry#3017, colbymchenry#3020, colbymchenry#3018, colbymchenry#3023). Clean auto-merge. README: drop colbymchenry#2871 (closed upstream; colbymchenry#2934 merged in its place, and name-matcher already matches upstream).
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.
Summary
A program that uses CodeGraph as a library and runs
indexAll()again on a project it has already indexed no longer empties the name-word vocabulary: the words in symbol names that the prompt hook andcodegraph_exploreuse to match a plain-language question ("how does the order state machine work") to a symbol (OrderStateMachine).Reimplements #2252 by @rudycelekli, who found the bug.
Root cause
CodeGraph.indexAllclearedname_segment_vocabbefore extraction on every run. Over an existing graph the store skips files whose content hash is unchanged, so their names were never written back:syncandhealSegmentVocabIfEmpty()repair only a completely empty table, a partly filled one stayed that way;codegraph indexwas not affected: it recreates the database before indexing, so every run there is a fresh one.Fix
freshDb), as before forinitandcodegraph index.DELETEdrops the rows of names that no symbol carries any more (file and import nodes don't count, as on the write path). That keeps the orphan cleanup the clear used to do. It runs after resolution, so a name a framework pass renamed is covered too.segmentedNames), so a pruned name that comes back later in the same session gets its rows again instead of being skipped as already seen.rebuildNameSegmentVocab(), which pages with LIMIT/OFFSET.Validation
Kit repro with the PR's fixture: on main a second
indexAll()took the table from 11 rows to 0, an edit plus a third run left 4, and a cancelled run emptied it. With the fix it stays at 11 rows, the renamed class's 3 rows give way to the new name's 3, and a cancel keeps them all.5 new tests in
__tests__/segment-vocab.test.ts, which compare the table itself with the segments of every symbol name in the graph (getSegmentMatcheshides orphan rows, so a prune shows only in the table). 4 fail on main's source; the fresh-database guard passes on both. Mutations caught: no prune, no reset of the written-names set, no clear on a fresh database.CLI:
codegraph initthencodegraph indexwrite the same 11 rows on main and with the fix.Real repo, vscode
src/vs/base+src/vs/editor(1,388 files, 56,406 nodes, 66,250 vocabulary rows; vscode 69e9e92f), a libraryindexAll()over the existing index, 3 interleaved runs per arm:Prune cost at scale: 288 ms on a 10× replica of that index (564,060 nodes), about 1.2 s on a synthetic graph with 505k vocabulary rows (170k distinct names). A full re-index of that size re-parses every file.
Rebased onto main 4955eac (fix(rust): use bindings follow Rust's scopes, and module paths walk the crate's modules #3014, Rust resolution only); the diff is unchanged (same patch-id), and the measurements above were taken on the first base, e7c9ffd.
Full suite on this exact commit (009cc45, on main 4955eac), native kernel built: 784 files, 9,286 tests passed, 0 failed, 85 skipped (
--maxWorkers=2, no reruns).Left out
indexAll(), which only prunes.codegraph indexrebuilds it, andsyncand the prompt hook still refill a table that is completely empty. Refilling on every full index would cost about another 0.6 s per 400k symbols for a one-time repair.🤖 Generated with Claude Code