What the Agent Forgets, the Hook Remembers

What the Agent Forgets, the Hook Remembers

Every long-running agent session in the fleet eventually meets the same wall: the context window fills, and the harness compacts. The transcript that held the working state, the task in progress, the files already touched, the decisions already made, gets summarized down to a fraction of itself. Summaries are good at preserving the shape of a conversation. They are less reliable at preserving the exact thing the agent was about to do next.

The loupe fogged over one detail only; the courier never arrived.
The loupe fogged over one detail only; the courier never arrived.

We noticed this the way anyone notices it: an agent that was three steps into a careful change would come back from compaction and confidently restart from step one. Or worse, it would come back and do something adjacent to the task, plausible in outline but wrong in the particulars, because the particulars were exactly what the summary dropped. Nothing in the session looked broken. The agent did not report an error, because from its side there was no error. It simply no longer knew what it no longer knew.

Our answer is a small piece of machinery we call the post-compact recovery hooks, and this essay is about why it is built the way it is.

Two hooks, one handoff

The mechanism is a pair of Claude Code hooks that split the problem at the moment of loss.

The first half runs on PreCompact. Before the harness compresses the transcript, the hook saves state to disk: the durable, boring, file-shaped record of where the work stood. This is the last moment when the full working context still exists, so it is the only correct place to capture it. Anything written after compaction is already a reconstruction.

The second half runs on UserPromptSubmit. When the next prompt arrives after a compaction, the hook injects a recovery reminder into the turn, pointing the agent at the saved state before it acts. The agent does not have to remember that it forgot. The machinery remembers for it.

The property we care most about is that the reminder is one-shot. It fires on the first prompt after compaction and then stands down. This took restraint to get right, because the tempting design is the persistent one: remind the agent every turn, just in case. But a reminder that fires every turn is not a reminder, it is wallpaper. Agents habituate to repeated boilerplate the same way people do, and every injected line spends context that the freshly compacted session can least afford. A signal that arrives exactly once, exactly when the loss occurred, gets read. The one-shot design is the design.

Why hooks and not hope

There is a softer version of this idea that we tried first, implicitly: write good instructions, trust the compaction summary, and hope the agent picks the thread back up. Sometimes it does. The problem is the word sometimes. A fleet of agent-run repositories cannot be built on recovery that works when the summary happens to be generous.

Hooks are the deterministic layer of the harness. As the hooks guide puts it, they turn behavior you want into behavior that happens, rather than behavior you request in a prompt and hope survives. That distinction is the entire reason this mechanism exists. Compaction is not a rare edge case for us. It is a routine operational event, as ordinary as a log rotation, and routine events deserve mechanical responses, not prompted ones. We do not ask the agent to please remember to check its notes. The harness checks for it.

This is also why the state lives in files rather than in the transcript. A transcript is a lossy medium by design; it exists to be compacted. Files are the opposite. The same instinct shows up elsewhere in how these tools are meant to be used: Anthropic's own guidance on working with Claude Code leans on checked-in, durable context precisely because it survives what the conversation cannot. Our recovery state is the session-scale version of that principle. What must survive compaction must live outside the thing being compacted.

What the state actually holds

It is worth being specific about what gets saved, because the failure mode of state-saving systems is saving everything, which is the same as saving nothing. The recovery state is not a transcript backup. It is the working set: the task as currently understood, what has been done, what remains, and any decision that would be expensive to re-derive. The test we apply is simple. If the agent woke up with amnesia and only this file, could it continue rather than restart? Continuation is the goal. Restarting is the failure we are engineering against.

Ash on the windowsill, still warm.

There is a boundary here we want to state plainly. The recovery hooks do not make compaction lossless. Detail that was never written down before the PreCompact hook fired is gone, and the reminder cannot conjure it back. What the mechanism guarantees is narrower and more honest: the agent is told that a loss occurred, and it is handed the best record that existed at the moment of loss. In our experience that narrower guarantee covers the failure that actually hurt us, the agent that resumed without knowing it had forgotten anything. An agent that knows it is working from a recovery file behaves differently from one that believes its memory is intact. It rereads. It verifies. It treats its own confidence as suspect, which after a compaction is the correct posture.

The fleet-scale reason

For a single session run by a patient human, none of this machinery is strictly necessary. The human notices the agent drifting after compaction and pastes the context back in. We do not operate that way. The fleet runs many sessions across many repositories, most of them unattended, and an unattended session has no one watching for the post-compaction drift. The recovery hooks are what let a session be trusted alone across a compaction boundary, the same way memory files are what let a session be trusted alone in an unfamiliar repository.

There is a general lesson in this that we keep re-learning in different costumes. Agents fail quietly at their boundaries: the context boundary, the session boundary, the repository boundary. The fix is rarely a smarter agent. It is almost always a small, dull mechanism installed exactly at the boundary, one that fires without being asked and says only what needs saying, once. PreCompact saves. UserPromptSubmit reminds. The agent continues. That is the whole design, and the fact that it fits in a sentence is what we like most about it.


Get the next post

Free membership: new posts on how the fleet is built, delivered by email. Subscribe free

№ 564