Skip to content

feat: bridge Claude auto-memory back to parent project - #3

Merged
thebrubaker merged 1 commit into
mainfrom
joel/claude-memory-handler
May 20, 2026
Merged

thebrubaker merged 1 commit into
mainfrom
joel/claude-memory-handler

Conversation

@thebrubaker

Copy link
Copy Markdown
Owner

Summary

  • Solves orphaned Claude auto-memory: when a session in an exp branch wrote learnings, they landed in ~/.claude/projects/<branch-slug>/memory/ and died when the branch was trashed. Now they're symlinked back to the parent project's memory dir, surviving branch lifecycle.
  • New core/memory-bridge.ts module with pure functions (claudeProjectSlug, claudeProjectDir, claudeMemoryDir, bridgeMemory); 11 new tests.
  • New memory_bridge config key (default true) + EXP_MEMORY_BRIDGE env var to disable.
  • exp new JSON output now includes memoryBridge: "linked" | "exists" | "skipped" | "off".

Shape pivot

Originally written as autoMemoryDirectory in .claude/settings.local.json. End-to-end verification via cmux + a real Claude session showed Claude ignores that key at the project-local layer (security restriction — only user-level settings are honored). Symlink approach validated end-to-end after pivot: launched Claude in a fresh test branch, asked it to write a memory, confirmed the file landed at the parent's slug via realpath.

Coupling note

The symlink approach is load-bearing on three Claude conventions: memory dir location under ~/.claude/projects/, slug rule (/ and . → -), and on-disk markdown storage. No documented hook or API lets a project declare an alias identity today. Documented in CLAUDE.md so future-me knows where to look if this breaks.

Closes DIG-198.

Test plan

  • Unit tests pass (bun test — 151/151)
  • Typecheck clean
  • Lint clean
  • Binary builds
  • End-to-end verified via cmux: clean project, fresh branch, claude session, memory file resolves to parent slug
  • Dogfood on a real project (next step on main after merge)

🤖 Generated with Claude Code

Claude's auto-memory writes to ~/.claude/projects/<slug>/memory/ where
slug is derived from the git-resolved repo root. Exp branches are
isolated APFS clones with their own .git, so each branch gets its own
slug — memory written during branch sessions is orphaned the moment
the branch is trashed.

Originally shaped to write autoMemoryDirectory into the branch's
.claude/settings.local.json, but verified empirically that Claude
only honors that setting from user-level settings (deliberate
security restriction). Symlinking the branch's would-be memory dir
to the parent's works below Claude's API surface: Claude resolves
its memory dir from cwd as usual and the bytes follow the symlink.

End-to-end verified by launching claude in a clean test branch and
confirming the written memory file resolves to the parent's slug.

Coupling note: the symlink approach is load-bearing on Claude's
storage conventions (path under ~/.claude/projects/, slug rule,
on-disk markdown). All documented in CLAUDE.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@thebrubaker
thebrubaker force-pushed the joel/claude-memory-handler branch from 595fab3 to b15800d Compare May 20, 2026 20:49
@thebrubaker
thebrubaker merged commit 61ec8eb into main May 20, 2026
@thebrubaker
thebrubaker deleted the joel/claude-memory-handler branch May 20, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant