Workflow · 2026-05-06

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.

Key takeaways
  • 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:

StateLifetimeWhat survives
The conversation transcriptThe sessionJSONL log on disk, mostly unread
The active context windowUntil /clearNothing
Memory files (~/.claude/memory/)Across sessionsWhatever you manually wrote
Hooks & settingsPermanentConfiguration, 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:

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):

~/my-project
$ 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:

~/my-project
$ 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:

~/my-project
$ 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:

~/my-project
$ 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:

~/.claude/settings.json
// 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:

SessionStart hook output
[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.

Why this is better than a markdown file. The hook reads from a structured DAG, not from your hand-edited prose. It's always in sync with the last commit, because it is the last commit. You never edit it; you commit through it.

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.

~/my-project
$ 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.

ApproachGoodGap
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:

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:

first time only
$ 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)
Who runs what. The three commands above are the only ones a human ever types: install, 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