You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Nested git repos never reindex on branch switch: watcher only tracks session_project, index_status reports false freshness #1429
In a multi-repo monorepo workspace (parent git root + many nested independent git checkouts), background auto-watch / reindex only tracks the MCP session project (cwd root). Branch switches and HEAD moves in already-indexed nested repositories are ignored.
Worse: index_status / list_projects surface livebranch / head_sha from disk git, while the knowledge graph remains on the previously indexed tree. Agents therefore treat a stale graph as fresh and answer structural questions incorrectly with no error signal.
This is a high-severity reliability issue for agent workflows: silent wrong answers, not a hard failure.
/path/to/workspace/ ← git root; MCP session_root
group/nested-service/ ← nested independent git repo (already indexed)
other-nested-repos/ ← also indexed as separate projects
Session project name: derived from parent path (e.g. Users-...-workspace)
Nested project name: e.g. nested-service (indexed earlier via index_repository)
The nested repo has mutually exclusive branch trees (different modules/files per branch). Example: branch A has module service-variant-a/, branch B has service-variant-b/ instead.
Reproduction
Start MCP from the parent monorepo root. Confirm autoindex/watcher only registers the session project:
Branch B → fewer/different nodes; service-variant-b/* present, variant A gone from file_hashes
Switch back + reindex → graph matches branch A again
So the pipeline can rebuild correctly; automatic path never targets the nested project.
Note: omitting --name derived a second project name from absolute path, leaving the original project stale. Separate naming footgun, but not the core bug.
Root cause (source read on main / v0.9.0-era tree)
1. Watcher registration is session-scoped only
register_watcher_if_enabled only watches srv->session_project / srv->session_root:
/* Register the session project with the background watcher for ongoing * change detection — unless auto_watch is disabled. */staticvoidregister_watcher_if_enabled(cbm_mcp_server_t*srv) {
if (!srv->watcher||srv->session_project[0] =='\0'||srv->session_root[0] =='\0') {
return;
}
...
cbm_watcher_watch(srv->watcher, srv->session_project, srv->session_root);
}
Already-indexed nested projects are never registered unless the MCP session cwd is that nested root.
2. Watcher can detect checkout when registered
watcher.c tracks git rev-parse HEAD and treats HEAD movement (commit / checkout / pull) as a change. Nested repos never reach this path.
3. Parent git HEAD does not move when a nested repo switches branches
Even continuous reindex of the session/parent project does not rebuild the nested project's DB. Nested .git trees are separate indexes.
4. False freshness compounds the failure
index_status / project list git fields read live git state (also discussed in #1213). After a nested branch switch, agents see matching branch/sha and assume the graph is current — while search_graph still returns symbols deleted on disk.
Docs: state clearly that auto_watch only covers the session project today, and nested multi-repo setups need per-repo reindex or separate sessions until (1) lands.
Workaround (current)
After every git switch / checkout in a nested indexed repo:
Summary
In a multi-repo monorepo workspace (parent git root + many nested independent git checkouts), background auto-watch / reindex only tracks the MCP session project (cwd root). Branch switches and HEAD moves in already-indexed nested repositories are ignored.
Worse:
index_status/list_projectssurface livebranch/head_shafrom disk git, while the knowledge graph remains on the previously indexed tree. Agents therefore treat a stale graph as fresh and answer structural questions incorrectly with no error signal.This is a high-severity reliability issue for agent workflows: silent wrong answers, not a hard failure.
Environment
codebase-memory-mcp 0.9.0(darwin-arm64 release binary)auto_index=true,auto_watch=true,auto_index_limit=50000~/.cache/codebase-memory-mcpSetup shape (common agent monorepo)
Users-...-workspace)nested-service(indexed earlier viaindex_repository)The nested repo has mutually exclusive branch trees (different modules/files per branch). Example: branch A has module
service-variant-a/, branch B hasservice-variant-b/instead.Reproduction
No
watcher.watchline appears for the nested project.codebase-memory-mcp cli index_status --project nested-service # nodes ~N, graph contains symbols under service-variant-a/Actual
index_status.git.branch/head_shanodes/edgessearch_graphfor branch-A-only symbolsservice-variant-a/)search_graphfor branch-B pathssearch_code(disk grep)watcher.reindexfor nested projectExpected
Either:
HEADmoves; orHEAD; andindex_statusexposes an indexed HEAD (orstale: true), not only live git metadata that always looks current.Control: manual reindex works
service-variant-b/*present, variant A gone fromfile_hashesSo the pipeline can rebuild correctly; automatic path never targets the nested project.
Note: omitting
--namederived a second project name from absolute path, leaving the original project stale. Separate naming footgun, but not the core bug.Root cause (source read on main / v0.9.0-era tree)
1. Watcher registration is session-scoped only
register_watcher_if_enabledonly watchessrv->session_project/srv->session_root:Already-indexed nested projects are never registered unless the MCP session cwd is that nested root.
2. Watcher can detect checkout when registered
watcher.ctracksgit rev-parse HEADand treats HEAD movement (commit / checkout / pull) as a change. Nested repos never reach this path.3. Parent git HEAD does not move when a nested repo switches branches
Even continuous reindex of the session/parent project does not rebuild the nested project's DB. Nested
.gittrees are separate indexes.4. False freshness compounds the failure
index_status/ project list git fields read live git state (also discussed in #1213). After a nested branch switch, agents see matching branch/sha and assume the graph is current — whilesearch_graphstill returns symbols deleted on disk.Related open issues (distinct but compounding):
This report is specifically: unwatched nested projects + live git metadata on stale graphs.
Impact
Severity: high for agent reliability (silent incorrect graph).
Suggested fixes (shortest path first)
root_pathis under session root / configured roots), not onlysession_project.indexed_head_sha(and branch) at successful index time; expose inindex_statuswithstale = (indexed_head_sha != live_head_sha).stale, either auto-queue reindex or return an explicit staleness flag on graph tools so agents do not trust results blindly.auto_watchonly covers the session project today, and nested multi-repo setups need per-repo reindex or separate sessions until (1) lands.Workaround (current)
After every
git switch/ checkout in a nested indexed repo:Or keep one clone per long-lived branch as separate project roots (avoids in-place branch switches).
Offer
Happy to refine the repro into a small fixture (parent repo + nested repo with two branches of divergent file trees) if useful for a regression test.