Axiom Lift

Claude Code · Codex · OpenCode · memory

Building your own memory for a coding agent: what works, and where it stops

The memory stacks developers build for Claude Code, Codex and OpenCode: hooks, handoff files, stores and MCP servers. A minimal setup that works, the hook facts, and the limits.

30 September 2026

A home-made memory stack of hooks, files and a store, with the points where it breaks marked

Some of the most experienced people using coding agents have built their own memory. This article collects what they build, what works, where it breaks, and a small setup you can copy today.

The issue, as reported

On the Claude Code and Codex issue trackers, the threads start the same way: months of long sessions, repeated compactions, and an agent that keeps losing what was agreed. Then the reporter explains what they built. Several arrived at the same design on their own: files, never the chat. They treat the compaction summary as untrusted output and keep the real state on disk, as a journal of what happened plus a short file of what is true now.

The hook threads are just as consistent: save state before a compaction, put it back afterwards. The sharpest complaint is that a hook before compaction can't change what the summary keeps, so putting things back feels too late.

They are honest about the limits: planning files go stale, parallel agents write conflicting versions of the same file, flat notes lose what was ruled out and why, and rules on disk are still sometimes ignored.

What developers build

Handoff fileThe agent writes a progress note before it stops and reads it at the start. Works well; only as current as its last update.
Hook scriptsSave a copy before compaction, re-inject files after it. Reliable for fixed text; can't steer the summary.
Memory indexA short file of pointers to other memory files, loaded at start. Grows, and only part of it loads.
Own databaseSQLite, Postgres or a vector store: a journal plus derived state. The most capable, and the most upkeep.
Memory MCP serverThe agent asks instead of reading everything. It only knows what something wrote into it.
Parallel agentsShared files go stale or conflict when two sessions write at once.

Why it happens

Everything that exists only in the conversation depends on the summary. Hooks act around that moment, and the docs are precise about what each event can do.

In Claude Code, PreCompact runs before a compaction with the manual or auto matcher, and receives the transcript_path of the conversation. It can block the compaction, but for this event its output goes to the debug log, not to Claude, so it can't add anything to the summary. PostCompact receives the finished compact_summary, and the docs say it "can't affect the compaction result". The way back in is SessionStart with the compact matcher: whatever it prints is added to Claude's context (hooks reference).

Codex has the same shape. Its PreCompact and PostCompact hooks ignore plain text on stdout, and SessionStart hooks that match compact run before the next model request, with their output added as developer context (Codex hooks). OpenCode is the exception: a plugin's experimental.session.compacting hook can add text to the compaction prompt itself (OpenCode plugins).

A compaction in Claude Code: PreCompact can save or block, PostCompact can only watch, SessionStart with the compact matcher puts context back
Where a hook can act around a compaction in Claude Code. The summary itself is out of reach; the way back in is SessionStart.

How to fix it today

This is the smallest setup that holds up in Claude Code: one file of decisions, a full copy of the conversation before each compaction, and the file put back after it. It uses only documented features.

  1. Keep decisions in one file

    Create DECISIONS.md in the project root: one line per decision, with the reason and what was ruled out. Add to CLAUDE.md (or AGENTS.md for Codex and OpenCode): "When we agree a decision, add it to DECISIONS.md with its reason. Mark replaced decisions as superseded instead of deleting them."

    # DECISIONS.md
    - 2026-09-30 · Postgres, not SQLite
      why: concurrent writers · ruled out: SQLite WAL
  2. Save the conversation before each compaction

    Save this as .claude/hooks/save.sh and make it executable (chmod +x). It needs jq. The transcript is written asynchronously, so the last few messages may be missing. Add the folder to .gitignore: it holds everything said, including anything pasted.

    #!/bin/sh
    dir="$CLAUDE_PROJECT_DIR/.claude/transcripts"
    mkdir -p "$dir"
    src=$(jq -r .transcript_path)
    cp "$src" "$dir/$(date +%Y%m%d-%H%M%S).jsonl"
  3. Put the decisions back at start and after compaction

    In .claude/settings.json. SessionStart output is added to Claude's context; startup|resume|compact covers a new session, a resumed one and the moment after a compaction (hooks guide).

    {
      "hooks": {
        "PreCompact": [{
          "matcher": "manual|auto",
          "hooks": [{
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/save.sh"
          }]
        }],
        "SessionStart": [{
          "matcher": "startup|resume|compact",
          "hooks": [{
            "type": "command",
            "command": "cat \"${CLAUDE_PROJECT_DIR}/DECISIONS.md\""
          }]
        }]
      }
    }
  4. Do the same in Codex and OpenCode

    Codex reads the same hooks shape from .codex/hooks.json in the repository (or [hooks] tables in config.toml). Use a SessionStart hook matching compact that prints the file, with a path from the git root, as the Codex hooks docs advise; project hooks load only once the project is trusted. In OpenCode, a plugin in .opencode/plugins/ can push the file's text into the compaction prompt with experimental.session.compacting.

  5. Search the copies when you need the detail

    The saved transcripts are JSON lines, so a plain search finds the conversation behind a decision:

    rg -l "Postgres" .claude/transcripts

What the fix doesn't cover

The setup works. Its limits are the ones the builders describe.

What no hook can do

In Claude Code and Codex, no hook can change what the compaction summary keeps. You can save before, block, or put context back afterwards. Rules on disk are still context, not enforcement.

Three layers of a home-made memory stack, capture, store and recall, each with the point where it tends to break
The home-made stack: each layer works, and each has a point where it quietly stops.

How Axiom Lift solves it

Axiom Lift is the maintained version of this stack. A small helper on your computer reads the conversations Claude Code, Codex and OpenCode already save, so there are no hooks to write. It saves every line before a compaction and captures again at the moment of compaction. Requirements, decisions and corrections are picked out automatically, with nothing to tag and nothing to write up. When you change your mind, the old decision is struck through, never erased, and linked to the moment it was said.

The next session asks over a read-only MCP connection (search_context, get_context) and gets back the few lines that are true now, not the whole history. Before each prompt, Axiom also adds a few lines about what is already decided on that subject. The same record serves all three tools.

Home-made

  • A decisions file someone has to remember to update
  • Hook scripts per tool, maintained by you
  • Raw transcript copies, searched by hand
  • Parallel sessions can overwrite each other's notes
  • Your own store: schema, extraction and pruning to look after

With Axiom

  • Decisions, requirements and corrections picked out automatically
  • Reads the sessions the tools already save; no hooks
  • Every line kept, searchable, decisions filed
  • A changed mind is struck through, not erased
  • One read-only MCP connection for Claude Code, Codex and OpenCode

What it doesn't do: it doesn't change what your tool's summary keeps, stop compaction, or make a model follow a rule. It works with those three tools, not browser chat or phones. Unlike a file in your repository, the history is kept in your account rather than your repository; it is never sold or used for advertising, and you can export or delete it any time. Keep your rules in CLAUDE.md or AGENTS.md; Axiom looks after the decisions and history around them.

Keep every decision without maintaining the stack

One command in the terminal where you use Claude Code, Codex or OpenCode. Free, no card.

Try it free →

Claude, Codex and OpenCode are trademarks of their owners; Axiom works alongside them and is not affiliated.