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

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.
- Keep decisions in one file
Create
DECISIONS.mdin the project root: one line per decision, with the reason and what was ruled out. Add toCLAUDE.md(orAGENTS.mdfor 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 - Save the conversation before each compaction
Save this as
.claude/hooks/save.shand make it executable (chmod +x). It needsjq. 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" - Put the decisions back at start and after compaction
In
.claude/settings.json.SessionStartoutput is added to Claude's context;startup|resume|compactcovers 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\"" }] }] } } - Do the same in Codex and OpenCode
Codex reads the same
hooksshape from.codex/hooks.jsonin the repository (or[hooks]tables inconfig.toml). Use aSessionStarthook matchingcompactthat 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 withexperimental.session.compacting. - 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.
- It records only what gets written down. The decisions file depends on the agent, or you, remembering to update it, and that fails most in the long sessions where it matters.
- The copies are raw. A saved transcript has every line but no structure. Finding which decision replaced which, weeks later, is a search you run by hand.
- It is per tool. Three tools means three sets of hooks, and a decision made in Codex doesn't reach Claude Code unless both read the same file.
- Growing it is a project of its own. A database or memory MCP server fixes search, but then you maintain the extraction, the schema, the pruning and the stale entries.
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.

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.
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.
