Skip to content

auto_watch is session-scoped and keyed by path-derived name — override-named indexes never refresh, and a watching session silently forks a duplicate index #1660

Description

@7hr1LL

Environment

  • Version: codebase-memory-mcp 0.10.3 (--version), single Mach-O arm64 binary at ~/.local/bin.
  • OS: macOS (Darwin 25.6.0), daemon under launchd (daemon start, KeepAlive=false).
  • Config (config list): auto_watch = true, auto_index = false, auto_index_limit = 50000, ui-lang = auto.

Summary

Two coupled behaviors make auto_watch=true fail to keep an index fresh in exactly the setups where
background freshness matters most — headless/CI clients, subagent-only workflows, and any project indexed
under a --name override:

  1. The watcher is session-scoped. The background git watcher is registered only when an interactive
    MCP client connects (watcher.watch) and torn down on disconnect (watcher.unwatch). A print-mode /
    one-shot client acquires no watch, ephemeral subagents share a parent bridge and hold none, and a project
    with no live interactive session goes stale indefinitely — despite auto_watch=true.
  2. The watch keys by the path-derived name, never the --name override. An index stored under an
    override name receives zero watcher.watch events (orphaned/stale). Worse: when a real session later
    opens the same path, the daemon creates a second full index under the derived name instead of
    refreshing the override-named one — a silent duplicate (2× disk, and the original stays stale).

The server-advertised contract "once indexed, watched projects auto-refresh in the background" silently does
not hold for these cases.

Reproduction (minimal)

# 1. Index a repo under an override name.
codebase-memory-mcp cli index_repository --repo-path /path/to/repo --name my-alias

# 2. Edit + commit a tracked file in /path/to/repo.

# 3. Inspect — 'my-alias' is never refreshed by the watcher:
codebase-memory-mcp cli index_status --project my-alias        # stale; mtime unchanged

# 4. Open an INTERACTIVE MCP session with cwd=/path/to/repo (auto_watch=true), idle.

# 5. Daemon log now shows a watch on the DERIVED name + a brand-new index:
#    watcher.watch project=<path-derived-name> path=/path/to/repo
#    -> project '<path-derived-name>' is created & indexed; 'my-alias' STILL stale.

<path-derived-name> = the path with separators flattened, e.g.
/Users/me/code/project-aUsers-me-code-project-a.

Evidence (live 0.10.3 daemon)

A. Every watch binds the derived name; override names are never watched. grep -c over the daemon log
(project names anonymized; counts verbatim):

watcher.watch project=… occurrences
alpha (override name) 0
beta (override name) 0
Users-me-code-project-a (derived, same repo as alpha) 6
Users-me-code-project-b (derived) 31

Sample line — the project key is always the flattened path, the --name never appears:

level=info msg=watcher.watch project=Users-me-code-project-a path=/Users/me/code/project-a

The override-named project (alpha) sat stale for ~2 days until a manual index_repository.

B. The duplicate index, on disk. Two coverage reports for the SAME repo, ~1 min apart, identical
parse_partial=11 file set — one under the derived name, one under the override name:

logs/Users-me-code-project-a-<t1>.log   # 02:39:29  project=Users-me-code-project-a
logs/alpha-<t2>.log                     # 02:40:42  project=alpha

C. Session lifecycle is the trigger. A steadily-used project (project-b above) shows 31 watcher.watch
interleaved with watcher.unwatch — connect/disconnect cycling — confirming the watch lives and dies with
the interactive session, not the project.

D. config --help documents the design as session-scoped:

auto_watch   default=true   Register background git watcher on session connect

Impact

  • Headless / CI / print-mode (-p) clients: never fresh.
  • Subagent-only workflows: never fresh (shared parent bridge holds the only watch, if any).
  • Any --name-overridden project: never fresh and silently duplicated when a session opens its path.
  • Users read "watched projects auto-refresh" and trust a stale index. The duplicate wastes disk and hides
    the staleness behind a fresh-looking twin under a different name.

Requested changes

  1. Persistent watch_projects config (or a watch add/list/remove subcommand). A declared set of repo
    roots the daemon watches unconditionally at startup, independent of any client session. Decouples
    freshness from an interactive session and fixes the headless/subagent/CI case. Today config exposes only
    4 keys — none declare a standing watch.

  2. Root-path-matched watch binding (the core fix). Resolve the watch target — and the index it
    refreshes — by canonical repo root path, not by display name. If a project already exists for that
    root under any name, refresh THAT project; never create a derived-name twin for an already-indexed root.
    Keep --name as a pure display alias over the path identity. This single change eliminates both the
    orphaning (#A) and the duplicate (#B).

  3. A rename / alias tool. rename_project --project <old> --name <new> (or an alias) so an existing
    index can be renamed to the derived name / carry an alias without today's index-new → verify → delete-old
    migration dance.

  4. Document + retune the hook-augment deadline. The SessionStart/SubagentStart hook-augment enforces a
    hard 2000 ms default deadline; on cold subagent starts it silently times out — 16
    hook-augment: deadline_exceeded ms=2000 events in a single session — starving subagents of graph
    context (frequently misread as "subagents don't use CBM"). The log line itself points to
    CBM_HOOK_DEADLINE_MS, but the knob is undocumented. Please (a) document the env var, (b) raise the
    default (≈4000 ms), and/or (c) make hook-augment non-blocking so a slow augment degrades to "no extra
    context" without affecting the turn.

Happy to test a patch against this install and report back with the same log-grep evidence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    editor/integrationEditor compatibility and CLI integrationstability/performanceServer crashes, OOM, hangs, high CPU/memoryux/behaviorDisplay bugs, docs, adoption UX

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions