Skip to content

Index worker loses requesting session's allowed root with an existing daemon (0.10.5, Windows) #2183

Description

@samartomar

Problem

Native codebase-memory-mcp 0.10.5 on Windows 11 rejects indexing a new consumer root when it joins an existing account daemon started with a different CBM_ALLOWED_ROOT. Both clients use the exact same CBM_CACHE_DIR; the new client sets its own allowed root to the exact repository being indexed. list_projects succeeds, but index_repository returns outside the allowed root and recommends an account-level allow-root grant.

Reproduction outline

  1. Start a normal MCP session for disposable repository A, with CBM_ALLOWED_ROOT=A and a canonical cache C. Keep that session alive.
  2. From disposable repository B outside A, use the same installed build and cache C, with CBM_ALLOWED_ROOT=B.
  3. Invoke codebase-memory-mcp cli list_projects: succeeds.
  4. Invoke codebase-memory-mcp cli index_repository --repo-path B --mode moderate: rejects B as outside the allowed root.

Observed build fingerprint: f8aee1683f94f7598ae70640a588f27d51811433f046b39c1faf186c17010739. The initial session and existing daemon were preserved. No grants were added and no sandbox settings were relaxed.

Suspected source path

  • main.c routes ordinary CLI tool calls through the daemon and supplies per-client root context.
  • application.c starts an index worker using args, memory budget and output paths; the worker interface does not carry the allowed root.
  • index_supervisor.c spawns the physical worker with inherited environment.
  • The standalone worker server falls back to process CBM_ALLOWED_ROOT in mcp.c.

The source path suggests that the physical worker rechecks the daemon starter's boundary instead of the requesting session's boundary. Worker environment memory was not instrumented; this is a source-based explanation of the observed rejection.

Expected fix and acceptance

Propagate validated request-session authorization to the physical worker without mutating the daemon's shared process environment. Test concurrent A/B sessions: each can index its own allowed root, an out-of-policy request remains denied, and starting/restarting B leaves A usable. Do not require users to widen global grants merely to preserve the documented session-specific boundary.

The configuration documentation also says ordinary one-shot CLI tools do not connect to/start a daemon, while the pinned source above routes them through it. Reconcile that ownership description with executable behavior.

Separate observation

A later two-file fixture within the daemon starter's existing root launched an index worker but did not return within a 120-second bound. Its task-owned processes exited after timeout; the original daemon remained alive. That timeout is not yet diagnosed and is not claimed to have the same cause as the root rejection.

Activity

  1. added
    bugSomething isn't working
    priority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.
    editor/integrationEditor compatibility and CLI integration
    on Sep 19, 2026
  2. DeusData commented on Sep 25, 2026

    @DeusData
    Owner

    Thank you so much, @samartomar, for such a careful report. The reproduction outline, the build fingerprint and especially the source walk (main.c → application.c → index_supervisor.c → the worker's CBM_ALLOWED_ROOT fallback) were spot on. That is exactly the path that was broken: the daemon authorized the request under your session's boundary, but the worker it spawned re-checked against the environment of whoever started the daemon.

    This was fixed in a08b9ec and shipped in v0.11.0. The worker now scopes itself to the canonical repo_path the daemon admitted, installed explicitly as its session root and allowed root. It never falls back to the ambient environment, and a request with no repo_path fails closed. Nothing about the session boundary was widened, and no allow-root grant is needed.

    We re-verified your scenario on current main: a daemon started for root A, then a client for B indexes B, while B→X and A→B are still denied and A→A keeps working. With the fix reverted we got your exact "outside the allowed root" message back.

    You're also right that the docs contradict the code on whether one-shot cli commands use the daemon; we'll correct that separately. If the 120-second hang in your separate observation still happens on v0.11.0, could you open a fresh issue with the fixture shape and the daemon log? Closing this one as fixed in v0.11.0 (a08b9ec); please reopen if you still see it. Thanks again!

  3. DeusData commented on Oct 1, 2026

    @DeusData
    Owner

    Thank you again, @samartomar! The documentation correction promised here is now on main in 7d4a12c (merged via #2350): the README and docs/CONFIGURATION.md now say that one-shot cli commands use, and if needed start, the shared daemon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingeditor/integrationEditor compatibility and CLI integrationpriority/highNeeds near-term maintainer attention; high-impact bug, regression, safety issue, or release blocker.stability/performanceServer crashes, OOM, hangs, high CPU/memorywindowsWindows-specific issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions