Skip to content

--approve-sensitive never lifts the sensitive-root refusal for Windows paths under Program Files #1718

Description

@ezonius

Version

codebase-memory-mcp 0.10.5

Platform

Windows (x64)

Install channel

npm

Binary variant

standard

What happened, and what did you expect?

Summary

On Windows, codebase-memory-mcp allow-root --approve-sensitive <path> records a sensitive-root grant, but
index_repository (and the HTTP UI indexing route) still refuses the exact same path with:

C:/Program Files (x86)/Steam/steamapps/common/Factorio/data: path is a home or credential directory.
To index it anyway, run: codebase-memory-mcp allow-root --approve-sensitive C:/Program Files (x86)/Steam/steamapps/common/Factorio/data

The grant appears to be recorded correctly (with the ! sensitive marker), yet the refusal persists for any
path whose first component under the drive is Program Files / Program Files (x86) — i.e. the escape hatch
is broken exactly where it is needed most.

Root cause

The refusal is a byte-exact string equality check failing across Windows path-separator mismatch.

  1. index_repository calls cbm_workspace_root_allowed (src/mcp/mcp.c:8074). Before that, the repo path is
    canonicalized and its separators are normalized to forward slashes:

    // src/mcp/mcp.c:1396-1398 (canonicalize_repo_path_if_exists)
    if (cbm_canonical_path(repo_path, real, sizeof(real))) {
        cbm_normalize_path_sep(real);
        ...
  2. The candidate path is classified sensitive because Program Files (x86) matches WS_WINDOWS_SYSTEM_TREES
    (src/foundation/workspace.c:159-164), returning CBM_WS_DENY_SENSITIVE from
    cbm_workspace_classify_root.

  3. A sensitive refusal can only be lifted by an exact sensitive-grant match. In cbm_workspace_root_allowed:

    // src/foundation/workspace.c:548
    if (verdict == CBM_WS_DENY_SENSITIVE && match.exact_sensitive) {
        return true;
    }

    match.exact_sensitive is set in ws_match_visit:

    // src/foundation/workspace.c:394-395
    if (sensitive && ws_paths_equal(root, m->candidate)) {
        m->exact_sensitive = true;
    }

    ws_paths_equal is a raw byte comparison (src/foundation/workspace.c:230-232) — it does not normalize
    separators and uses strncmp/strlen with no case folding in ws_is_ancestor_or_equal
    (src/foundation/workspace.c:216-228).

  4. The grant itself is stored with native Windows backslashes because allow-root writes the canonical path
    without normalizing separators (src/main.c:1014-1025cbm_workspace_grant_addfprintf(f, ...),
    src/foundation/workspace.c:480). So the grant file line is:

    !C:\Program Files (x86)\Steam\steamapps\common\Factorio\data
    

    while the candidate the indexer compares against is normalized to:

    C:/Program Files (x86)/Steam/steamapps/common/Factorio/data
    

    "C:\Program Files..." vs "C:/Program Files..." are not byte-equal → exact_sensitive stays false
    the sensitive override is ignored → the path is refused.

Why it only bites Windows system-tree paths

Non-sensitive paths (e.g. E:\Factorio) are allowed as soon as they are contained by a grant
(match.contained, checked via cbm_path_within_root, which does normalize separators and does
case-insensitive comparison on Windows, src/mcp/mcp.c:8406-8419). They never reach the exact-separator
check. Only CBM_WS_DENY_SENSITIVE refusals — which are precisely the Program Files / Users /
credential-name cases — require ws_paths_equal, and that byte compare is where the separator mismatch
kills the override.

Impact

  • allow-root --approve-sensitive becomes a no-op for every Windows path beneath Program Files /
    Program Files (x86) — the most common location for installed software trees (e.g. a Steam game's
    data folder containing moddable prototypes/scripts/API sources).
  • The error message unconditionally suggests the exact command that has already been run and cannot succeed,
    so there is no in-band way to proceed.

Suggested fix

Normalize path separators consistently when comparing a stored grant against a candidate, in
cbm_workspace_grant_add's canonicalization and/or in the equality path used by
cbm_workspace_root_allowed. Concretely:

  • Normalize the stored grant to forward slashes at write time (src/foundation/workspace.c:480), and/or
  • Make the sensitivity override use a separator-insensitive (and on Windows case-insensitive) comparison —
    e.g. reuse cbm_path_within_root/canonical_path_has_root semantics (which already normalize and fold
    case on Windows) for the exact_sensitive test instead of the byte-exact ws_paths_equal.

Note there is also an asymmetry worth unifying: allow-root stores backslashes while index_repository
normalizes to forward slashes, which is the immediate cause of the mismatch. Both paths should agree on the
same canonical form.

Environment

  • OS: Windows (NTFS, case-insensitive)
  • codebase-memory-mcp version: 0.10.5
  • Path type affected: C:\Program Files (x86)\...

Reproduction

Reproduction

On Windows (tested with codebase-memory-mcp 0.10.5):

# 1. Record the sensitive grant
codebase-memory-mcp allow-root --approve-sensitive 'C:/Program Files (x86)/Steam/steamapps/common/Factorio/data'
# -> "allowed root recorded: C:\Program Files (x86)\Steam\steamapps\common\Factorio\data"

# 2. Grant file now contains (note backslashes)
# !C:\Program Files (x86)\Steam\steamapps\common\Factorio\data

# 3. Attempt to index — always refuses despite the recorded grant
codebase-memory-mcp cli index_repository --repo-path 'C:/Program Files (x86)/Steam/steamapps/common/Factorio/data'
# -> "...: path is a home or credential directory. To index it anyway, run: ... --approve-sensitive ..."

Logs


Diagnostics trajectory (memory / performance / leak issues)


Project scale (if relevant)

No response

Confirmations

  • I searched existing issues and this is not a duplicate.
  • My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingux/behaviorDisplay bugs, docs, adoption UXwindowsWindows-specific issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions