[BUG] Auto-memory writes prompt every time since 2.1.280 when CLAUDE_CONFIG_DIR's projects/ is a symlink to ~/.claude/projects (allow rules, hooks and auto mode cannot approve)
Environment
- Claude Code 2.1.283 native install on macOS (Darwin 25.6), launched from the VS Code extension,
permissions.defaultMode: auto. The 2.1.284 binary carries the same logic. - Several account profiles:
CLAUDE_CONFIG_DIR=~/.claude-profiles/<profile>, whereprojects,settings.json,skills,plugins,commandsandCLAUDE.mdinside each profile are symlinks to~/.claude/<same name>, so sessions and auto-memory are shared across profiles.
Symptom
Since 2.1.280, every Edit/Write to the session's own auto-memory directory <CLAUDE_CONFIG_DIR>/projects/<slug>/memory/*.md shows
This will modify /Users/<me>/.claude/projects/<slug>/memory/<file>.md (outside working directory) via a symlink
with only Yes / No. There is no "always allow", and in auto mode the classifier never approves it, so every memory note costs a manual click. 2.1.278 never prompted (transcripts show 2.1.278 through 2026-09-28 and the prompts start with 2.1.280 / 2.1.283).
What does not help
permissions.allowwithEdit(~/.claude/projects/*/memory/**)andEdit(~/.claude-profiles/*/projects/*/memory/**)still prompts.permissions.additionalDirectoriesdoes not apply because the sensitive-file check runs first.- A
PreToolUsehook (matcherEdit|Write) returningpermissionDecision: "allow"fires (the transcript recordshook_successwithallow) but the prompt is still shown.
Root cause as read from the 2.1.283 bundle
- Since 2.1.280 the write check builds the spellings
[requested path, symlink landing](changelog: "Fixed writes through a symlinked path being judged by their in-tree spelling"). - The auto-memory carve-out ("auto memory files are allowed for writing") is evaluated for every spelling and all of them must allow. It compares with
startsWith(<CLAUDE_CONFIG_DIR>/projects/<slug>/memory/), so the landing spelling~/.claude/projects/...fails and the combined result is passthrough. - The sensitive-file check then flags the
.claudepath segment of the landing and returns ask. Because the requested spelling alone is safe while the landing is not, the result is marked not classifier-approvable, so auto mode has to ask a person. permissions.allowrules are evaluated only after that check, so they never apply.
Expected
Writes to the session's own auto-memory directory should be auto-allowed whether or not <CLAUDE_CONFIG_DIR>/projects is a symlink. For example, compare the carve-out against the realpath of the auto-memory directory as well, or treat the resolved auto-memory directory as non-sensitive as #79206 proposes.
Steps to reproduce
mkdir -p ~/.claude-profiles/p1
ln -s ~/.claude/projects ~/.claude-profiles/p1/projects
ln -s ~/.claude/settings.json ~/.claude-profiles/p1/settings.json
export CLAUDE_CONFIG_DIR=~/.claude-profiles/p1
cd <any project> && claude # auto mode
# ask Claude to save a memory note -> the prompt above appears on every write
Control experiment: the same layout but with the real directory outside any .claude segment (for example ~/.claude-shared/projects, with ~/.claude/projects symlinked to it) plus allow rules covering both spellings makes the writes auto-approved (tool_use to tool_result 0.07 s, versus 12 to 41 s while waiting for the prompt).
Related
- #97585 auto mode prompts per write through a user-created symlink since 2.1.280
- #79206 auto-memory under
~/.claudegated as a sensitive file, "always allow" does not persist - The 2.1.283 changelog fixed the "started in a subdirectory of a git repository" variant of the auto-memory sensitive-file block; the symlinked
CLAUDE_CONFIG_DIRvariant remains.