Feature request: stable project identity + first-class cross-machine sync for auto memory and portable profile state
Problem
Auto memory is keyed by the munged absolute path of the project directory
(~/.claude/projects/-home-user-projects-foo/memory/). The same project
checked out on two machines with different home layouts — Linux
(/home/user/...) and macOS (/Users/user/...) — therefore gets two
unrelated memory directories. On top of that, the docs state that auto
memory is machine-local by design ("Files are not shared across machines or
cloud environments", https://code.claude.com/docs/en/memory.md).
For anyone who works on the same projects from more than one machine daily,
this splits the assistant's accumulated knowledge: feedback, project
context, and preferences learned on machine A simply don't exist on
machine B.
Our current workaround (works, but is all hand-rolled)
~/.claudeis a git repository pushed to a private GitHub remote.- Memory lives in a canonical, machine-independent bucket inside that repo
(~/.claude/projects/_synced/projects/<workspace>/memory/).
- The live munged-path memory directory on each machine is a symlink
into that bucket, bootstrapped idempotently on first run per machine.
- A
/syncskill is the only actor allowed to commit/pull/push, with
strict semantics (see below).
- A read-only
SessionStarthook diagnoses drift (behind/ahead vs origin,
dirty tree, missing symlink) and reports it at the start of every
session, without ever acting.
Proposal
Two complementary pieces:
- Stable project identity. Key project state (auto memory, per-project
settings) on something machine-independent: the normalized git remote
URL, or a declarable project ID (e.g. in .claude/), with the munged
path as fallback for repos without a remote. This alone removes the need
for the symlink layer.
- An official sync mechanism for the portable part of the profile
(memory, settings, skills, agents, global CLAUDE.md). Account-based sync
would be ideal; a git-backed claude sync command would already cover
the need. Semantics we converged on after real-world use, offered as
prior art:
- fast-forward only, never auto-merge — on divergence, stop and show
both sides;
- a dirty working tree blocks the handoff — uncommitted work is the
only state the other machine cannot observe (it sees ahead/behind,
not your working tree), so it must be surfaced loudly, not noted in
passing;
- a read-only drift check at session start, separate from the action.
Why this is tractable
The auto memory format is already sync-friendly: one file = one fact, plus
a regenerable MEMORY.md index. File-level sync is nearly conflict-free by
construction — the index can be rebuilt after merge. The design is already
there; it's only the transport that's missing.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗