[FEATURE] Make session transcripts/memory project-portable while keeping scratch files local-only (linked by session ID)
Problem Statement
Claude Code currently stores both conversation transcripts (~/.claude/projects/<sanitized-path>/*.jsonl) and session scratch/temp files (%TEMP%\claude\<sanitized-path>\<session-id>\) outside the project directory, keyed off the absolute path of wherever the session was launched from. This causes two separate but related problems:
Transcripts/memory aren't portable. Moving, renaming, or relocating a project folder (or accessing it from a different machine/username, e.g. a networked or cloud-synced drive shared between a laptop and desktop) orphans all prior conversation history and project memory, since both are resolved from the absolute launch path rather than anything tied to the project itself. This is already tracked in #44056, #37513, and #25739.
The sanitized-path bucketing is misleading over a session's lifetime. A session's scratch/temp directory is named after whichever directory it happened to be launched from — not the directory actually being worked in. In practice this means a single long-running or reused session can end up doing substantive work in an entirely different project folder than the one baked into its temp path, and that stale name persists for the life of the session. This is confusing when reviewing tool-approval prompts (the file path stops being a reliable "does this make sense" signal) and gets worse over time as a launch point is reused across unrelated projects.
Proposed Solution
Split these into two storage domains with different portability requirements, joined by a shared identifier:
Transcripts and project memory should be storable inside the project directory itself (e.g. <project>/.claude/sessions/<user-id>-<session-id>.jsonl), so they move, copy, and sync naturally with the project — solving the portability problem directly rather than trying to re-resolve absolute paths across machines.
Scratch/temp files should remain host-local (current %TEMP%//tmp behavior), not relocated into the project directory. This matters specifically for projects living on a network share or cloud-synced folder: scratch churn (autosave checkpoints, command output, intermediate working files) is disposable and high-frequency, and forcing it through project-folder sync/network I/O would add real overhead for data that was never meant to persist.
The session ID (already generated internally) is the natural join key between the two — the portable transcript and the local-only scratch directory for a given session both carry it, so either can be correlated with the other without requiring scratch itself to be portable.
Tagging the transcript filename with a user identifier additionally solves multi-user attribution when a project folder is shared across machines/accounts (who was working on this, and from where), which a purely session-ID-based scheme doesn't address on its own.
Why not just move everything into the project folder?
That's the simpler-sounding fix, but it conflates two things with genuinely different requirements: transcripts/memory are small, meaningful, and worth persisting long-term; scratch is large-volume, high-churn, and disposable by design. Colocating both means either accepting the network/sync overhead for scratch, or building a separate exclusion/cleanup mechanism to keep scratch out of backups and version control — extra complexity that a clean split avoids.
Related issues: #44056, #37513, #25739 (transcript/memory portability), #45745, #25292, #17936, #29629 (scratch/temp handling) — this request sits at the intersection and proposes a mechanism that addresses both without conflating them.
3 Comments
Concrete follow-up to this report, from hitting the actual failure mode:
Two sessions on the same machine illustrate this architectural bug from different angles.
Session 1 (the first project prompting this topic): the agent operated exactly as instructed and never noticed its own settings/permissions were being written into a different, unrelated project's folder — it took the user directly noticing a mismatched path during an approval prompt to catch it. User and agent then filed this issue together.
Session 2 (a new session, no memory of session 1): the agent independently noticed the same contamination pattern on its own this time, unprompted. It correctly reasoned that giving each project its own .claude folder is the right conceptual fix — the user reached the same conclusion independently, in parallel. But once given tools to reference session 1's history, the agent was able to identify why that fix wouldn't actually work: session/settings storage is bound to launch path, not folder existence — a mechanism built into the agent's own architecture, invisible to it until it collided with it. Manually creating folders would not have fixed anything. The user stopped the agent before it took that action.
Net effect: the agent's diagnosis and proposed fix were both correct. Only the underlying architecture made the fix non-functional. This isn't a reasoning failure — it's a structural constraint the agent has no way to detect or self-correct for without hitting it directly, and even then couldn't have caught the contradiction without cross-session history access, which isn't available by default.
Worth considering alongside the storage-portability fix: some way for a session to detect "this settings file shows signs of the known cross-session contamination pattern" and surface that, rather than each session independently re-diagnosing and improvising a fix from scratch.
Additional followup followup (but in english this time):
Claude was given a local folder to be "free" in: Claude Code\
From there, I created a Code Projects\ folder, and in here an Android App\ folder.
Claude was allowed the Root folder of Claude Code\ - and subsequent sub folders, so each project would have it's own playground so to speak and I could "allow all" and not be too worried.
What happened was the first Project launched in the Claude Code\Code Projects\Android App\ and it created .claude here.
I'd naturally assume ,claude would be in Claude Code\, or in each sub folder where .claude was needed for that project's preferences and scratchpad work
but i never looked, didn't really need to.
Eventually Claude Code\Code Projects\Python One\ was created and the project in full swing, and during prompts, the paths for Android One appeared - and that opened this rabbit hole, and I found ALL projects were being directed to the same settings.json file in the lone .claude folder buried in another project. The first session Claude only noticed when I mentioned it - and explained it was "by design" - and then "began to realize" why the design was not "correct", and it was adjacent to issues others have noted in shared environments, so the OP stands on it's own anyway.
These two updates are the result of the Agent in a new Session independently seeing the issue - unprompted, and me stopping it from doing the common sense fixes we both posited - some of which went against it's programming, as explained by the session one Agent - it also did not offer a backup before cleaning the "unrelated data" and tried to create project centric .claude folders it would never be able to use, so again I had to intervene. Session One "knew" it was flawed, but understood it could do nothing, Session Two figured it could fix it, not knowing it could not.
The trigger of this was preparing to upload to a repository, this second session chimed in with - um - this isn't right - and here we are.
Some of the cross contamination data was actually sensitive and was noticed, and probably shouldn't have been retained in the json file anyway - and the Session Two Agent flagged that and then "realized" there were multiple project settings in the file and it "shouldn't be like that".
What's interesting is the Second session wasn't a project per se - it was more of a "chat" so it wasn't using the json file until the upload portion of the chat came about, and it "read it". So cudos to Anthropic for having a flag for things.
So as a test - we made the backup of the json and cleaned out the sensitive data - and I'll see what happens when I next open the Python One session. But the .claude folder remains as is for now - and I'll have to monitor the settings file moving forward.
Either way, this is more of a bug than a feature, and the Agent was able to reason out the whole thing above as both "it's okay because", and "this isn't right because" - twice - with little guidance other than - don't do that - and stop picking at it, it'll get worse :)
Seconded. I develop over multiple machines and have sometimes had to port Claude projects from one user to another user on the same machine - the process is unnecessarily tricky and precarious. While I'm doing it, I can't help but think: why can't I just get Claude to store absolutely everything it needs within the project folder ?! Honestly, I don't know why this isn't the default. Of course, in a GIT managed environment, this could mean that any projects committed to GIT by other people would have all the relevant Claude session information - a good or bad thing depending on circumstances...but that's what .gitignore is for ... !
Finally I would add that when a user activates this feature half way through a session - I think everything should be moved for the user. If they toggle it back, everything would be moved back - so implementation wise, we'd effectively be talking about a controlled file move toggle.