Technology

July 28, 2025

Claude Code Memory Guide 2025: The Four-Layer Memory Stack

A complete beginner's guide to making Claude Code remember everything across sessions using CLAUDE.md, primer.md, memory.sh, and git hooks - four simple layers that solve the context persistence problem.

The Problem

Claude Code has no memory between sessions by default. Every new session starts fresh, losing context about your rules, preferences, project history, and next steps. The solution is a four-layer memory system using text files and a shell script.

---

The Four Layers

Layer 1 - CLAUDE.md (Static)

Your permanent rules, code style preferences, and project conventions written once.

Layer 2 - primer.md (Dynamic)

The current state of your project that Claude rewrites at the end of every session.

Layer 3 - memory.sh (Live)

A shell script run at session start that pulls fresh data from git and injects context.

Layer 4 - Git Hook (Automatic)

A post-commit hook that logs every commit to a memory file with zero manual effort.

---

Layer 1: CLAUDE.md - Your Permanent Rulebook

Claude Code automatically reads this file before every session. It's your "briefing document" describing who you are, how you work, and your project details.

What to Include

  1. Project Identity - Description, purpose, tech stack, users
  2. Coding Conventions - Tabs vs spaces, quote style, language preferences
  3. Architectural Decisions - Key structural choices and rationale
  4. Things Claude Must Never Do - Explicit restrictions
  5. Primer Rewrite Instruction - Critical instruction to update primer.md every session

Example CLAUDE.md

# Project: My SaaS App

## What This Project Is
A subscription-based task manager for small teams.
Backend: Node.js + Express. Database: PostgreSQL.
Frontend: React + TypeScript. Auth: JWT tokens.
Deployed on: Railway (backend), Vercel (frontend).

## Code Conventions
- Always use TypeScript
- Use single quotes for strings
- 2-space indentation
- All async functions must have try/catch
- Use named exports, not default exports

## Architecture Rules
- All DB queries go through /src/db/queries/
- All API calls from frontend go through /src/lib/api.ts
- Environment variables accessed only through /src/config.ts

## Never Do
- Never use any type in TypeScript
- Never store secrets in code
- Never write inline CSS styles
- Never modify DB schema without discussion

## SESSION MANAGEMENT (CRITICAL)
At the end of EVERY session, you must rewrite primer.md completely.
Include:
1. Current state of the project
2. What was accomplished this session
3. Immediate next steps (specific, actionable)
4. Any open blockers or unresolved issues
5. Any important decisions made this session

---

Layer 2: primer.md - The Living State Document

This is the most powerful layer. Claude reads primer.md at session start alongside CLAUDE.md, then completely rewrites it at session end. This ensures the next session starts with full context.

What a Good primer.md Contains

# Project State - Updated: 2025-06-14

## Current Status
Working on the team invitation flow. The invite email
sending is complete and tested. The invite acceptance
page (/accept-invite) is 70% done - form renders
but the token validation endpoint is not yet wired up.

## What Was Done This Session
- Built POST /api/invites endpoint (creates invite + sends email)
- Created InviteEmail template in /src/emails/InviteEmail.tsx
- Added invite record to the DB (new table: team_invites)
- Wrote unit tests for the invite creation logic (all passing)

## Immediate Next Steps
1. Build POST /api/invites/accept endpoint
2. Wire up the AcceptInvitePage form to call endpoint
3. Handle expired token case (tokens expire after 48 hours)
4. Add invite list to team settings page

## Open Blockers
- Resend (email provider) has a sending limit of 100/day
- AcceptInvitePage redirect logic incomplete for new users

## Key Decisions Made
- Invite tokens are UUIDs stored hashed in the DB
- Invites expire after 48 hours (configurable)
- A user can be re-invited after expiry

Initial primer.md

For your first session, create a simple starter:

# Project State

Project is in early development.
No sessions completed yet.
Starting fresh - see CLAUDE.md for project overview.

---

Layer 3: memory.sh - Live Git Context at Launch

A shell script that queries git history, finds recent changes, checks for errors, and injects all this as context at session start.

The Script

#!/bin/bash
# memory.sh - Inject live git context into Claude Code

echo "=== CLAUDE CODE SESSION CONTEXT ==="
echo ""

# Current git branch
echo "Current branch:"
git branch --show-current
echo ""

# Last 5 commits
echo "Recent commits (last 5):"
git log --oneline -5
echo ""

# Uncommitted changes
echo "Files modified (not yet committed):"
git status --short
echo ""

# Changes in last 24 hours
echo "Files changed in last 24 hours:"
git diff --name-only HEAD@{1.day.ago} HEAD 2>/dev/null || echo "No changes"
echo ""

# Recent errors
echo "Recent errors (last 10 lines of error.log):"
if [ -f "error.log" ]; then
  tail -10 error.log
else
  echo "No error.log found"
fi
echo ""

echo "=== END OF SESSION CONTEXT ==="
echo "Paste the above output into Claude Code when starting your session."

How to Use

  1. Make executable (one-time): chmod +x memory.sh
  2. Run at session start: bash memory.sh
  3. Copy output and paste into Claude Code before requesting work

---

Layer 4: Git Hook - Automatic Commit Logging

Every commit is automatically logged to project-memory.md with zero manual effort, creating a complete history.

Setting Up the Post-Commit Hook

Create .git/hooks/post-commit:

#!/bin/bash
# Auto-log every commit to project-memory.md

COMMIT_HASH=$(git log -1 --format="%h")
COMMIT_MSG=$(git log -1 --format="%s")
COMMIT_DATE=$(git log -1 --format="%ci")
MEMORY_FILE="project-memory.md"

# Create file with header if it doesn't exist
if [ ! -f "$MEMORY_FILE" ]; then
  echo "# Project Memory Log" > "$MEMORY_FILE"
  echo "Auto-generated by git post-commit hook." >> "$MEMORY_FILE"
  echo "" >> "$MEMORY_FILE"
fi

# Append the new commit
echo "- [$COMMIT_DATE] $COMMIT_HASH: $COMMIT_MSG" >> "$MEMORY_FILE"

Make it executable: chmod +x .git/hooks/post-commit

---

Final Project Structure

your-project/
  CLAUDE.md            Layer 1: permanent rules
  primer.md            Layer 2: current state (Claude rewrites)
  memory.sh            Layer 3: live context injector
  project-memory.md    Layer 4: auto commit log
  .git/
    hooks/
      post-commit      Layer 4: hook that writes log
  src/                 your code

---

Session Workflow

Session Start

  1. Run bash memory.sh and paste output to Claude
  2. Claude automatically reads CLAUDE.md + primer.md
  3. You have full context - start working

During Session

  • Work normally with Claude
  • Git hook logs each commit to project-memory.md automatically

Session End

  • Tell Claude: "End of session - please rewrite primer.md now"
  • Claude rewrites primer.md with current state, next steps, blockers

Next Session

  • Run bash memory.sh, paste output
  • Claude picks up exactly where you left off

---

Quick Reference

  • CLAUDE.md - Static, you write once. Rules, conventions, preferences.
  • primer.md - Dynamic, Claude rewrites every session. Current state, next steps, blockers.
  • memory.sh - Live, you run at session start. Git branch, recent commits, changed files.
  • project-memory.md - Automatic, git hook writes every commit. Timestamped commit log.

---

Getting Started

You don't need a perfect CLAUDE.md on day one. Start with your project description and the primer rewrite instruction, then add more rules as you discover what Claude needs to know.

One-Command Install

curl -sL tunerlabs.com/tools/claude-code-memory/install.sh | bash

This creates all four files and the git hook automatically.

Setup Checklist

  1. Create CLAUDE.md with rules + primer rewrite instruction
  2. Create initial primer.md (even just a few lines)
  3. Create memory.sh and run chmod +x memory.sh
  4. Create .git/hooks/post-commit and run chmod +x post-commit
  5. Commit all new files to git
  6. At end of first session, ask Claude to rewrite primer.md

Written by Shyam Achuthan