{"slug": "claude-code-compaction-why-your-session-forgets-mid-task-and-the-fix", "title": "Claude Code Compaction: Why Your Session Forgets Mid-Task (and the Fix)", "summary": "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.", "body_md": "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.\n\nIf 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.\n\n**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.\n\nEvery 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.\n\nFrom 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.\n\nHere'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.\n\nWhat 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.\n\nThat 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.\n\nClaude 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.\n\nSo in ContextForge MCP 0.12.0, `init` installs this into your project's `.claude/settings.json`:\n\n```\n{\n  \"hooks\": {\n    \"SessionStart\": [\n      {\n        \"matcher\": \"compact\",\n        \"hooks\": [\n          { \"type\": \"command\", \"command\": \"npx -y contextforge-mcp recall\" }\n        ]\n      }\n    ]\n  }\n}\n```\n\n`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.\n\nHere's what it looks like in the terminal, right after a compaction:\n\nA few things I cared about while building it:\n\n`npx contextforge-mcp recall` yourself from the project folder and see exactly what Claude will see.\n**New to ContextForge?** Install the MCP server the usual way, then run this once in your project:\n\n```\nnpx contextforge-mcp init\n```\n\nThat 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).\n\n**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.\n\n```\nnpx contextforge-mcp --version   # should say 0.12.0 or newer\nnpx contextforge-mcp init        # adds the hook, prints \"already present\" next time\n```\n\nThen 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.\n\nI'd rather you know this now than find out later.\n\n`.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.\n**Does compaction happen without me asking?**\n\nYes. Claude Code compacts automatically when the context window fills up, and you can trigger it manually with `/compact`. Both fire the hook.\n\n**Does this replace `--resume`?**\n\nNo. `--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.\n\n**Can I see what the hook sends?**\n\nRun `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.\n\n**Why did the hook print nothing for me?**\n\nThe 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.\n\nCompaction 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.\n\nIf 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.", "url": "https://wpnews.pro/news/claude-code-compaction-why-your-session-forgets-mid-task-and-the-fix", "canonical_source": "https://dev.to/alfredoizjr/claude-code-compaction-why-your-session-forgets-mid-task-and-the-fix-cef", "published_at": "2026-09-24 17:00:43+00:00", "updated_at": "2026-09-24 17:30:07.525392+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "large-language-models", "mlops"], "entities": ["Claude Code", "ContextForge", "ContextForge MCP 0.12.0", "Anthropic"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/claude-code-compaction-why-your-session-forgets-mid-task-and-the-fix", "markdown": "https://wpnews.pro/news/claude-code-compaction-why-your-session-forgets-mid-task-and-the-fix.md", "text": "https://wpnews.pro/news/claude-code-compaction-why-your-session-forgets-mid-task-and-the-fix.txt", "jsonld": "https://wpnews.pro/news/claude-code-compaction-why-your-session-forgets-mid-task-and-the-fix.jsonld"}}