Project identity resolved inconsistently: memory and /resume key on git repo root, transcripts key on cwd
Version: 2.1.226 (also observed under 2.1.222/2.1.223 sessions on disk)
Platform: Linux 6.17.0-41-generic, bash
Summary
For a session started in a subdirectory of a git repo, three features disagree about what "the project" is:
| Feature | Keys on | Resolves to |
|---|---|---|
| Session transcript storage | cwd | ~/.claude/projects/-home-shane-paro-dev-pcsp-apps-ops/ |
| Auto-memory directory | git repo root | ~/.claude/projects/-home-shane-paro-dev-pcsp/memory/ |
| /resume picker | git repo root | lists ~/paro-dev/pcsp sessions |
The result is that a subdirectory session writes its transcripts to one project identity while reading its memory from another, and its /resume picker shows a third party's sessions.
Repro
- Have a git repo at
~/paro-dev/pcspwith a subdirectoryapps/ops. - Give both a memory store:
~/.claude/projects/-home-shane-paro-dev-pcsp/memory/MEMORY.md~/.claude/projects/-home-shane-paro-dev-pcsp-apps-ops/memory/MEMORY.md
cd ~/paro-dev/pcsp/apps/ops && claude
Expected: the session's memory directory is the -apps-ops one, matching where its transcript is written.
Actual:
- The system prompt states the memory dir is
~/.claude/projects/-home-shane-paro-dev-pcsp/memory/(repo root), and the rootMEMORY.mdis injected into context. The-apps-opsstore is never read. - The transcript for that same session is written to
~/.claude/projects/-home-shane-paro-dev-pcsp-apps-ops/<session-id>.jsonl. /resumelists sessions whose recordedcwdis~/paro-dev/pcsp, not~/paro-dev/pcsp/apps/ops.
Evidence
Transcript storage is cleanly cwd-scoped — I verified the cwd field inside the 8 newest transcripts in each directory, with zero crossover:
~/.claude/projects/-home-shane-paro-dev-pcsp 263 sessions, all "cwd":"/home/shane/paro-dev/pcsp"
~/.claude/projects/-home-shane-paro-dev-pcsp-apps-ops 35 sessions, all "cwd":"/home/shane/paro-dev/pcsp/apps/ops"
~/.claude/sessions/<pid>.json also records the correct per-session cwd:
{"pid": 27055, "sessionId": "0221906b-...", "cwd": "/home/shane/paro-dev/pcsp/apps/ops", ...}
{"pid": 656302, "sessionId": "15be3ebb-...", "cwd": "/home/shane/paro-dev/pcsp", ...}
So the cwd is known and correct at session start — memory and /resume are simply not using it.
Impact
This subdirectory session is a deliberately scoped agent: it has its own CLAUDE.md, its own skill set, and a PreToolUse hook confining its edits to apps/ops/. Its whole design assumes an isolated memory store, and its CLAUDE.md documents the rule:
Do NOT write to the root coding agent's memory. If your system prompt hands you that root path, it is wrong for this session.
The hook enforces this on Edit|Write|NotebookEdit, so the bad write is blocked — but the bad read has already happened before the agent's first turn, and there is no hook point for it. The agent begins every session primed with ~100 memory entries belonging to a different agent, and none of its own.
The /resume symptom is worse than cosmetic: selecting a root-repo session from the picker resumes a conversation whose entire context assumes cwd=~/paro-dev/pcsp, but it runs in apps/ops under the restrictive hook.
Suggested fix
Resolve all three from the same source. cwd seems right, since that is what transcript storage and ~/.claude/sessions/*.json already use, and it is what the user actually chose by starting the session there.
If repo-root scoping for /resume is intentional (so a repo's sessions are findable from anywhere in it), then please make it additive and labeled — show the cwd for each entry and default the selection to cwd-scoped — rather than silently substituting the repo root. Memory, in particular, should not fall back to the repo root when a cwd-keyed store exists.
A settings knob (e.g. projectScope: "cwd" | "repo") would also resolve it.
Workarounds in use
claude -c/claude -r <id>instead of the/resumepicker;--continueis documented as cwd-scoped.- An explicit "first action: read the
-apps-opsMEMORY.md" instruction in the subdirectoryCLAUDE.md, since nothing else can correct the preloaded index.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗