Repository navigation
fix(mcp): re-arm the watcher after lock contention, report freshness, refuse answers from changed files (#1959) - #1980
Closed
danusha2345 wants to merge 5 commits into
Closed
danusha2345 wants to merge 5 commits into
danusha2345 wants to merge 5 commits into
Conversation
…#1964) A directory removal adds no pending file, only needsFullScan. The retry after a failed sync (lock contention or a generic failure) was gated on pending files alone, so the owed full reconcile was dropped and the removed directory's files kept their nodes. Reschedule while needsFullScan is set as well. A regression test also pins the mid-sync scope-change case, which already follows a scoped pass with a full scan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… degradation (colbymchenry#1959) Explore already refuses to render source from a file that changed while auto-sync was off. search, callers, callees and impact answer from the same frozen graph but kept replying, naming the changed file as if its edges were current. They now take the same refusal: the indexed files an answer names as locations are hashed against the index, and a drifted one is named instead of the answer. codegraph_node keeps its own drift gate, which serves the changed file's current bytes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
|
Thanks @danusha2345! Your commits here were carried into #2043 (authorship preserved) together with #1978, with follow-up changes from review, and that is now merged. Closing this one in favour of it. It will be in the next release. |
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.
Addresses asks 1, 2 and 3 of #1959. Ask 6 (the lock's age test) is a separate PR, and ask 5 already holds on
main. The fallback walk honours.git/info/excludeandcore.excludesFile; a probe with a corrupted.git/indexconfirmed it.Stacked on #1977. The first commit is that PR's one-line watcher fix. Without it a re-armed watcher whose catch-up sync fails would never retry, since the catch-up is a full scan with no pending files.
Problem
With many sessions on one checkout, another writer holding the lock is normal. When it holds the lock past the watcher's retry budget, the watcher degrades and stays off for the rest of the session. Queries keep answering from the frozen index under a prose banner. The report has
codegraph_explorereturning unrelated symbols for code edited after the watcher stopped.Fix
codegraph_statusover MCP reports the last index time and how many tracked files were added, changed or removed since. It uses the same computation ascodegraph status --json, run in a worker thread so the daemon's event loop isn't blocked by a git or file walk. A timeout or failure reportsunknown, never a false zero.codegraph_explore's rendered files, and the indexed files thatcodegraph_search,codegraph_callers,codegraph_calleesandcodegraph_impactname as locations. They are hashed against the index even when size and mtime look unchanged. If any changed, the answer is withheld and the changed files are named, so the agent reads them. Answers from unchanged files are still served, under the degraded banner. The refusal is a success-shaped response, notisError, and a refused explore is not recorded as source the session has seen.codegraph_nodekeeps its own drift gate from Stale index + fresh disk read: codegraph_node/codegraph_explore return a DIFFERENT symbol's code under the requested name, while asserting "verbatim, current on-disk source … do not Read" — verified through a real serve --mcp #1474, which serves a changed file's current bytes.Tests
watcher.test.ts: re-arm after lock contention keeps the stale state until a full scan commits; a failed re-arm is throttled; a watcher degraded by a persistent generic sync failure is not re-armed.mcp-staleness-banner.test.ts: the recovering banner and status section, and re-arm on the next tool call.mcp-status-freshness.test.ts: the counts go from0/0/0to one added, one changed and one removed, both for working-tree edits and for a commit made after indexing.mcp-stale-refusal.test.ts: explore refuses a changed file even with its size and mtime restored, and serves an unchanged one; callers and search refuse when a file they name changed.extraction.test.ts: the git-failure walk honours.git/info/excludeandcore.excludesFile.Full suite on this branch (Linux, Node 22, native kernel): all tests pass except the known
extraction.test.tspool-worker crash from #1779 (fixed by #1883), which is intermittent and also occurs onmain; that file alone passes 655/655.🤖 Generated with Claude Code