Your AI's memory shouldn't live on one laptop: putting Claude Code memory in the repo
How we moved Claude Code's project memory out of the hidden ~/.claude folder and into the git repo — so the whole team and every AI tool can see, review, and improve it — using a one-line Windows trick and a .gitignore for the secret bits.
The problem: memory in a silo
Modern AI coding assistants remember things between sessions. Claude Code does it with a dead-simple mechanism: a folder of markdown files plus an index, auto-loaded every session:
That's great for one developer. But it has three problems for a team:
It's invisible. The memory lives under your user profile, outside the repo. A teammate never sees it. New hires start from zero. There's no review, no history, no diff.
It drifts. Each developer's AI accumulates its own private, slightly-different memory. "Why does Claude do X on your machine but not mine?" — because the memory is different.
Other AIs can't read it. Cursor, Gemini, Copilot each have their own memory format and never look at Claude's folder.
The knowledge your AI learns about your codebase — conventions, gotchas, where things live — is some of the most valuable context you have. Keeping it in a hidden per-laptop folder wastes it.
The insight: it's just files + a folder path
Two facts make the fix trivial:
The memory is plain markdown — perfectly at home in git.
The auto-load is just a folder path. If we can make that path point into the repo, Claude reads and writes the in-repo files without knowing the difference.
On Windows you redirect a folder path with a directory junction — and crucially, junctions need no admin rights (unlike symbolic links, which need Developer Mode or elevation). So:
Claude auto-loads from the junction → reads the repo files. When it saves a new memory mid-session, the write travels through the junction → lands in the repo file → ready to commit. Single source of truth, zero copies, zero drift.
The how-to (5 steps)
Tip: mklink /J from a bash shell can silently no-op due to quoting. New-Item -ItemType Junction from PowerShell is far more reliable — that's what our setup-memory-junction.ps1 uses.
The slug is the absolute repo path with the drive letter lower-cased and every : \ / . replaced by -: C:\Projects\Mapper\m4n.map → c--Projects-Mapper-m4n-map. Our setup script computes it for you and falls back to a copy if a machine can't junction.
The catch nobody mentions: secrets
Here's the part you must not skip. The moment memory becomes a committed, possibly-pushed artifact, anything sensitive in it leaks. When we audited ours we found no raw passwords — but several memories quietly carried internal infrastructure detail: database names, internal IPs, service usernames, "this JWT still needs rotating," live CORS/IIS endpoints. Fine in a hidden local folder; not fine in a repo that might reach a public mirror.
The fix is a scoped .gitignore right next to the files:
Those files still live on disk for Claude (via the junction) — they're just never committed. Share the knowledge, keep the secrets and infra local.
Best practices we landed on
- Junction, don't copy. A copy-sync means Claude's mid-session writes land in .claude and silently diverge from the repo. The junction makes writes land in the repo — that's the whole point.
- Split shareable knowledge from personal/secret with .gitignore. Project conventions and architecture → shared. Credentials, internal infra, and purely-personal machine settings → local.
- One fact per file, always indexed. Small atomic files diff cleanly and recall precisely; the MEMORY.md index is the one thing loaded every session, so keep it to one scannable line per memory.
- Treat memory like code. It's in git now — review it in PRs, see who changed what, prune in commits. A wrong memory is a bug; fix it like one.
- Prune stale memory. Old memory systems accumulate. We found a whole dead .aim/ knowledge store (a JSON graph DB + an archived 245 KB append-log) still in the tree — delete what's superseded. 6.Reach the other AIs through your sync layer. Junctions only help Claude. We feed the same facts into GEMINI.md / .cursor/rules via the existing .ai/ "manage-once" sync, so every tool sees one source.
The anatomy of a good memory
Each file is one fact with a tiny frontmatter so recall can decide relevance:
Real examples from our repo
These are actual memories now living in memories/repo/ — note how each is one crisp, actionable fact:
feedback_no_overengineering— Project is overengineered; break god files, remove dead code, never add code without need.
feedback_tldr_report_on_completion— On every completion give a TLDR: tokens (total + per-subagent), time, components used, done, to-do, issues, options — plus ~3-minute status pulses during long work.
project_god_file_refactoring— Split god files behind a barrel, modules ≤300 lines, keep the public export stable, characterization tests first; e.g. edgeConversion.ts 1198→218 + 12 modules.
project_github_issues_tracking— GitHub issues live on the clientrepo remote (Kaidanov/data-flow-mapper-pro), NOT the primary azure remote; local mirror is client/docs/YYYY-MM-DD-issues.md.
Personal/secret ones (DB creds, internal IPs) exist too — they're the ones we .gitignore.
The result
Memory is now a first-class, reviewable part of the repository. New developers inherit the team's accumulated AI context on git clone + one setup command. Memories improve in pull requests. Other AI tools get the same facts through the sync layer. And the secrets stay home.
Your AI's memory is too valuable to live on one laptop. Put it where the team — and every tool — can see it.




Top comments (0)