Giving Claude Code Persistent Memory Across Sessions
Anthropic gives you a memory primitive. h5i gives you the layers above it, versioned reasoning, per-commit snapshots, and automatic injection at session start, so the next session always knows what the last one was thinking.
- Durable agent memory should be a side effect of commits, not a markdown file you must remember to hand-edit.
- h5i layers a commit-pinned reasoning DAG, commit-keyed memory snapshots, and a SessionStart hook over the memory primitive.
- The memory directory is the one artifact you snapshot explicitly (h5i capture memory); the context workspace auto-snapshots on every commit.
An auditable workspace records every prompt, decision, and milestone in your repo, and this post covers how h5i surfaces that record at the start of every new session so you never lose the thread.
You ship a feature with Claude Code on Friday. Monday morning you start a new session, and Claude has no idea what you were working on. Not because the codebase changed, it didn't, but because everything Claude knew lived inside the prior session's context window, and that window is gone.
The fix everyone reaches for first is a memory file: jot the project state into
~/.claude/memory/<repo>.md and prepend it to every new session. That works
for ten lines of project background. It does not work for "what files did I edit yesterday,
which milestones are done, where am I uncertain, and what was the trade-off I rejected at
14:22 last Thursday." That information is the reasoning, not the project description,
and it has structure. A flat markdown file flattens it.
h5i sits in front of Claude Code's memory primitive and adds three layers, a structured
reasoning workspace, automatic per-commit snapshots, and a SessionStart hook that
injects the right slice of it into every new session. Once it's installed, you stop
re-explaining yourself.
What /clear actually destroys
A Claude Code session has four kinds of state. When the session ends or you run /clear,
they evaporate at different rates:
| State | Lifetime | What survives |
|---|---|---|
| The conversation transcript | The session | JSONL log on disk, mostly unread |
| The active context window | Until /clear | Nothing |
Memory files (~/.claude/memory/) | Across sessions | Whatever you manually wrote |
| Hooks & settings | Permanent | Configuration, not knowledge |
Memory files are the only thing Claude carries forward by default, and they're a free-form text blob. There is no structure for "milestones," no link from a sentence in the file to the commit it describes, no automatic refresh when you commit code, and no way to branch the memory the way you branch code when you explore an alternative.
So engineers do what engineers do: they invent ad hoc structure inside the markdown file, ## Done, ## TODO, ## Decisions, and update it manually. The first
week is fine. By week three the file is stale, contradictory, and nobody trusts it.
The three layers above the memory primitive
h5i treats memory the way Git treats files: as a thing you commit, branch, diff, and push. Concretely, it adds three refs to your repo and three classes of write operation:
- Reasoning workspace,
refs/h5i/context. A versioned DAG of OBSERVE / THINK / ACT / NOTE entries plus milestones. Branches like git, merges like git, and snapshotted automatically — pinned to the git SHA — on everyh5i capture commit. - Memory snapshots,
refs/h5i/memory.h5i capture memorycopies~/.claude/projects/<repo>/memory/and keys it to the current commit, so the memory directory becomes something you candiffandrestoreper SHA. - Session notes,
refs/h5i/notes. The exploration footprint of each session, files read vs. edited, uncertainty signals, blind edits.
All three are git refs, so they push and pull alongside your code. None of them touch your working tree.
The reasoning workspace
Run this once per project (or per major task):
$ h5i recall context init --goal "Migrate the auth service from Sessions to JWT" ✔ .h5i-ctx/ workspace initialized branch: main · goal recorded
During work you never type these by hand. The PostToolUse hook
(h5i hook claude sync) fires automatically as Claude reads and edits, recording an
OBSERVE on every read and an ACT on every write. The commands below are just the equivalent
of what the hook emits for you:
$ h5i recall context trace --kind OBSERVE \ "session.rs uses tower_sessions; refresh_token belongs in JwtClient" $ h5i recall context trace --kind THINK \ "Issue refresh tokens server-side; access tokens stay client-side. 15-min TTL." $ h5i recall context trace --kind ACT \ "Replaced session middleware with JwtMiddleware in src/api/mod.rs"
And after a logical milestone the workspace is checkpointed. The Stop hook
(h5i hook claude finish) mines THINK and NOTE entries and records the checkpoint
when the turn ends; Claude can also mark one explicitly:
$ h5i recall context commit "JWT middleware in place" \ --detail "Sessions middleware removed; tests pass; refresh-token path TODO" ◆ milestone m1 recorded · DAG node 4f7a2bc
The trace and milestones live in refs/h5i/context. Every entry is a DAG node with a parent
pointer, so reasoning has a topology, not just a timeline. When you fork an alternative, you
h5i recall context branch experiment/refresh-rotation, work the side path, and either merge it
back or abandon it. Either way, the abandoned branch is still there in history; you can always
recover the rejected design.
Memory snapshots, pinned to git commits
The reasoning workspace rides along on every h5i capture commit automatically. The
Claude memory directory is the one artifact you snapshot with an explicit command: run
h5i capture memory after a substantial session and h5i copies
~/.claude/projects/<repo>/memory/ into .git/.h5i/memory/<commit-oid>/,
keyed to the current commit. The snapshot is keyed by the git SHA, so memory is a first-class
versioned artifact:
$ h5i recall memory log 9e21b04 2026-05-06 11:45 3 files snapshotted +12 -3 a3f8c12 2026-05-05 14:02 3 files snapshotted +5 -1 7216039 2026-05-04 09:18 2 files snapshotted initial $ h5i recall memory diff a3f8c12 9e21b04 +++ ~/.claude/projects/my-project/memory/decisions.md + - 2026-05-06: Switched to RS256 keys (HS256 felt fragile for multi-service) - - 2026-05-04: Considering HS256 with shared secret per service
You can h5i recall memory restore <sha> to recover the memory file as it stood at any past
commit, push it to teammates with h5i share push, or simply diff it against last week's
version to see how your understanding has shifted.
The SessionStart hook: zero-friction restoration
The previous two sections are the boring infrastructure. The thing that actually changes day-to-day life is the hook that runs every time you open Claude Code:
// Written once by a human: `h5i hook setup --write` — the four handlers below then fire automatically { "hooks": { "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "h5i hook claude prompt" }] }], "SessionStart": [{ "hooks": [{ "type": "command", "command": "h5i hook session-start" }] }], "PostToolUse": [{ "matcher": "Edit|Write|Read", "hooks": [{ "type": "command", "command": "h5i hook claude sync" }] }], "Stop": [{ "hooks": [{ "type": "command", "command": "h5i hook claude finish" }] }] } }
Now every new session begins with a synthetic system message that looks like this:
[h5i] Context workspace active — prior reasoning follows. branch=main goal=Migrate the auth service from Sessions to JWT milestones=2 commits=4 trace_lines=89+12 m0: [x] JWT middleware in place m1: [x] Refresh-token endpoint wired up m2: [ ] Token rotation across deployments [h5i] Last decisions & actions: THINK: RS256 keys; HS256 felt fragile for multi-service ACT: Replaced session middleware with JwtMiddleware in src/api/mod.rs NOTE: TODO: integration test for refresh during deploy [h5i] Use `h5i recall context show` for full details.
The cost is calibrated by the --depth flag. Default is depth 2, about 2,000-5,000 tokens, the
timeline view above. Depth 1 is a compact 800-token index for token-conscious workflows;
depth 3 dumps the full OBSERVE/THINK/ACT log. Claude can step up the depth itself when it
needs more, by running h5i recall context show --depth 3.
Branching reasoning
The most underused feature is h5i recall context branch. Suppose you're halfway through the JWT
migration and want to explore using biscuit tokens instead. You don't want to lose your
current thread, but you also don't want the side-quest polluting your main reasoning history.
$ h5i recall context branch experiment/biscuit \ --purpose "evaluate biscuit tokens as JWT alternative" # ... Claude explores; you trace the experiment ... $ h5i recall context checkout main $ h5i recall context merge experiment/biscuit ✔ Merged 6 trace entries · 1 milestone (rejected → reason recorded)
The rejected branch stays in history. Six months later, when someone says "why didn't we use biscuit?", you have the whole evaluation, with the prompts, the readings, and the reasons, not "I think we tried that once."
How this compares to markdown memory and vendor session features
Two things already solve part of this problem, and it's worth being fair about where each one is enough.
| Approach | Good | Gap |
|---|---|---|
Markdown memory (CLAUDE.md, ~/.claude/memory/) |
Zero dependencies, human-readable, edits in any editor, trackable in git if it lives in the repo. | Flat prose with no link from a line to the commit it describes; manual upkeep, so it drifts; no branching; you trust your own discipline to keep it current. |
Session resume (claude --continue / --resume) |
Restores the exact prior transcript with full fidelity, no setup, nothing to maintain. | Tied to one machine's local session store; not versioned, not pinned to a commit, not shareable with a teammate; a /clear or a fresh checkout elsewhere loses it. Resumes a conversation, not a structured record of decisions linked to code. |
| h5i context + memory refs | A commit-pinned DAG of reasoning plus commit-keyed memory snapshots, branchable, diffable, and pushable to teammates; injected automatically at session start. | One-time hook setup; refs travel only via h5i share push, not plain git push; memory snapshots are as fresh as your last h5i capture memory. |
The honest summary: for a ten-line project note, a markdown file is the right tool and h5i is overkill. Session resume is the right tool when you simply walked away mid-task on the same machine. h5i earns its keep once the reasoning matters across days, machines, or teammates, and you want it tied to the code rather than to your memory of having written it down.
Failure modes worth knowing
The mechanism is plumbing, and plumbing has edges. Four are worth internalizing before you rely on it:
- Unshared refs.
refs/h5i/*are not moved by a plaingit push. A teammate who only runsgit pullgets your code and none of the reasoning. Publish withh5i share push; they fetch withh5i share pull. - Snapshot staleness. The context workspace auto-snapshots on every commit, but the memory directory does not — it only captures as of your last
h5i capture memory. Forget to run it andh5i recall memory restorehands back an older state. Make it a habit at the end of a real session. - Empty snapshots. Claude Code creates the memory directory lazily on first write. If you snapshot before anything has been written, h5i records an empty snapshot (zero files) so the commit is still tracked, rather than failing — useful to know when a restore comes back blank.
- Token budget. Depth 3 injects the full trace, which on a long-lived workspace is large. Keep the SessionStart cost predictable with the default depth 2 (or depth 1), and reach for depth 3 on demand.
FAQ
Does h5i replace Claude Code's memory files? No. It sits on top of the memory directory. Your CLAUDE.md and ~/.claude memory keep working; h5i adds the versioned reasoning workspace, commit-keyed memory snapshots, and automatic injection at session start.
Are h5i refs pushed by a normal git push? No. refs/h5i/context, refs/h5i/memory, and refs/h5i/notes travel via h5i share push / h5i share pull only.
How many tokens does the SessionStart hook inject? Depth 2 (default) is a ~2,000-5,000 token timeline; depth 1 is a ~800-token index; depth 3 is the full OBSERVE/THINK/ACT log.
Is the memory snapshot automatic? The context workspace is, on every h5i capture commit. The memory directory is snapshotted by the explicit h5i capture memory.
Can I recover an approach I rejected? Yes — a reasoning branch keeps the rejected line of work in history with its prompts and the reason it was dropped.
Try it on your next task
The minimum useful workflow is three commands once, then nothing:
$ curl -fsSL https://raw.githubusercontent.com/h5i-dev/h5i/main/install.sh | sh $ cd your-project && h5i init $ h5i hook setup --write --scope user # writes the 4 hooks into ~/.claude/settings.json (idempotent)
h5i init, and h5i hook setup --write once.
After that the four hooks fire on their own inside Claude Code — SessionStart
injects prior context, UserPromptSubmit records your verbatim prompt,
PostToolUse emits OBSERVE/ACT traces, and Stop mines THINK/NOTE
and checkpoints the milestone. You never type h5i hook claude … yourself; you
just use Claude Code. Humans reach for h5i recall … only to inspect
the record (h5i recall memory log, h5i recall context show).
From there, the SessionStart hook does the work. You'll notice it the first time you open a
new Claude Code session a week after a hard problem and Claude already knows where you stopped.
Memory as plumbing, not discipline
The thread running through all of this is that durable agent memory shouldn't depend on you remembering to write it down. A hand-edited markdown file is only as current as your last moment of conscientiousness; it drifts the instant you're busy, which is exactly when you most need it. Tying memory to commits inverts that: the record is produced as a side effect of the work, pinned to the SHA it describes, and replayed automatically when you sit back down.
That reframing also changes what "memory" means. It is no longer a paragraph of project
background but a structured, branchable history of reasoning — what you observed,
what you decided, what you rejected and why — restored at the granularity of a commit. The
cost is one-time setup and a couple of habits (h5i capture memory at the end of a
real session, h5i share push to bring teammates along). The payoff is that the
next session, the next machine, and the next teammate all start from where the last one left
off rather than from a blank context window. Use a markdown file when ten lines is genuinely
enough; reach for this when losing the thread actually costs you.
Try h5i on your next AI-assisted branch
Create a sandboxed workspace, capture the run, and post a review-ready PR brief. h5i is open source, Apache 2.0, and works alongside any git remote.
Star on GitHub Back to docs