Claude Code Compaction: Why Your Session Forgets Mid-Task (and the Fix) A developer shipped ContextForge MCP 0.12.0, which adds a Claude Code SessionStart hook with a "compact" matcher that automatically re-injects saved project decisions after a session compaction. The tool's new `recall` subcommand fetches the 10 most recent memories and up to 5 pending tasks for a linked project and prints them as plain text, which Claude Code appends to context immediately after the summary replaces the original messages. The author argues compaction reliably preserves the gist of a session but drops specific decisions, and that storing those decisions outside the conversation is the fix. Last week I published a piece about handing off a Claude Code session https://contextforge.dev/blog/claude-code-session-handoff-how-to-resume-work without re-explaining everything. A reader left a comment that stuck with me: "Compaction is the limit that actually bites." He was right, and I'd glossed over it. So this post is the one I should have written first. If you searched for "claude code compaction" because your session suddenly stopped knowing things it knew an hour ago, here's what's going on, what actually survives, and the small hook I shipped to fix the part that hurt me most. TL;DR: When a Claude Code session gets long, Claude summarizes the conversation to free space. The summary keeps the gist and drops the details, and the details are usually your decisions. You can't see what got cut. The fix is to keep decisions outside the conversation and put them back after every compaction. ContextForge 0.12.0 does that with a Claude Code hook that runs automatically. Every model has a context window, and a working session fills it fast: file reads, tool output, your back-and-forth. When Claude Code gets close to the limit, it compacts. It writes a summary of everything so far, throws away the original messages, and keeps going with the summary plus whatever hadn't been summarized yet. You can trigger it yourself with /compact , and it also happens on its own when the window fills up. From the outside it looks harmless. The status line says "Compacted," the conversation continues, and Claude still sounds like it knows what you're doing. That's the trap. Here's the part my reader nailed. After a compaction you get the summary plus the tail of messages that hadn't been folded in yet. Where that cut lands depends on the exact moment compaction fired. So no two resumes give you the same context, and from inside the session there's no seam to look for. The summary reads as complete. What actually falls out is predictable, though. Summaries are good at "we're refactoring the retry logic." They're bad at "retry logic goes in the client, not the handler, and we dropped the Redis layer because it added 40ms for nothing." The gist survives. The decisions evaporate. You find out when Claude cheerfully re-adds the caching layer you removed two hours ago. That last line is the whole strategy. --resume won't help you here, because it brings back the same compacted transcript. CLAUDE.md helps for the stable stuff, but it goes stale the moment your decisions move faster than you edit the file I wrote about that in Why Your CLAUDE.md Goes Stale https://contextforge.dev/blog/why-claude-md-goes-stale . What you want is the handful of decisions, stored somewhere compaction can't reach, and reloaded the instant the cut happens. Claude Code has a hooks system, and one of the events is SessionStart with a compact matcher. Anything a command prints there gets added straight into Claude's context right after the summary. That is exactly the moment we need. So in ContextForge MCP 0.12.0, init installs this into your project's .claude/settings.json : { "hooks": { "SessionStart": { "matcher": "compact", "hooks": { "type": "command", "command": "npx -y contextforge-mcp recall" } } } } recall is a new subcommand. It reads which project this folder is linked to, fetches the 10 most recent memories saved for that project and up to 5 pending tasks, and prints them as plain text. Claude Code appends that text to the context. From Claude's point of view, the decisions were never gone. Here's what it looks like in the terminal, right after a compaction: A few things I cared about while building it: npx contextforge-mcp recall yourself from the project folder and see exactly what Claude will see. New to ContextForge? Install the MCP server the usual way, then run this once in your project: npx contextforge-mcp init That writes the memory rules to your CLAUDE.md and, on Claude Code, adds the hook. Nothing else to configure. Full steps are in the docs https://contextforge.dev/docs/compaction-recall . Already using it? Update to 0.12.0 and re-run init in each project. It's idempotent: it only adds what's missing and leaves your existing settings.json and hooks alone. npx contextforge-mcp --version should say 0.12.0 or newer npx contextforge-mcp init adds the hook, prints "already present" next time Then test it: run /compact in a session and ask "what context did you just receive?" If Claude quotes a block that starts with "ContextForge: context restored after compaction," you're set. I'd rather you know this now than find out later. .contextforge file in the repo root to know which project's memories to fetch. Ask the agent to "link project" once and you're done. Does compaction happen without me asking? Yes. Claude Code compacts automatically when the context window fills up, and you can trigger it manually with /compact . Both fire the hook. Does this replace --resume ? No. --resume reopens a session on the same machine; use it. The hook covers what --resume can't: the decisions that a compaction summarized away. They complement each other. Can I see what the hook sends? Run npx contextforge-mcp recall from the project folder. It prints exactly the block Claude receives, or nothing if the project isn't linked or the API key can't be found. Why did the hook print nothing for me? The usual causes: an old CONTEXTFORGE API KEY exported in your shell that overrides the one in ~/.claude.json , an older global install of contextforge-mcp shadowing npx , or the project isn't linked yet. The docs have a short troubleshooting list. Compaction isn't a bug. It's the price of long sessions, and the alternative is a session that stops working. The mistake I made for months was treating the transcript as the thing worth keeping. It isn't. The decisions are. Keep those outside the conversation, hand them back at the right moment, and compaction becomes something you stop noticing. If you want to try it, ContextForge https://contextforge.dev has a free tier and the setup is three commands. And if you're the reader who left that comment: thank you. You were right.