How an Agent Session Survives Compaction
mksglu/context-mode treats a long AI-assisted engineering session as more than a stream of messages. The system must preserve the state of the work: which files matter, which tasks remain, what the user decided, which errors are unresolved, and what the agent was trying to accomplish. This chapter follows that state from hook capture through local SQLite storage to compaction and resume. The practical value is knowing what a restored session can reliably recover, what remains searchable rather than visible, and how database and host capabilities set the ceiling on continuity.
The real object to preserve is work state
A conversation transcript is a poor recovery format. It contains the user’s goal alongside tool arguments, raw outputs, repeated status messages, intermediate failures, and explanations that may no longer matter. Replaying it all after compaction would consume the same scarce context that caused compaction in the first place. It would also make the model reconstruct the current task from chronology instead of presenting the state that matters now.
Context-mode takes a different route. Its hooks extract structured events as the agent works. A file edit becomes a file event. A task tool call becomes task state. A user correction can become a decision. A failed command can become an error or a discovered constraint. Git activity, environment changes, plan-mode transitions, external references, and subagent results can also be recorded. The event is not the whole transcript; it is a compact representation of a transition that may affect what the agent should do next.
This distinction is the difference between source memory and work-state memory. The ContentStore remembers material such as a specification or an issue export. The session pipeline remembers the evolving relationship between the agent, the user, and the workspace. A searchable document can tell the agent what an API guide says. It cannot, by itself, tell the agent that the user rejected the first migration plan or that a test failed after a particular file was edited.
The event pipeline therefore captures state at the tool boundary, where changes and decisions become observable. It does not need to understand the entire meaning of the conversation. It needs enough structure to answer operational questions after the original messages have been compacted or a new session has resumed.
Capture before the conversation disappears
The lifecycle begins with host hooks. After a tool call completes, the PostToolUse path receives the tool name, inputs, and result. It ensures that session metadata exists, extracts relevant events, attributes them to the project and session, and writes them to the local SessionDB. The hook is designed to be fast and local: no network request, no language model, and no need to place the captured result back into the active conversation.
Extraction is selective in shape but not careless about meaning. A Read, Edit, Write, or patch can identify a file transition. A task event can preserve the subject and later status. A plan event can record entry, exit, approval, rejection, or a plan-file write. An error event can preserve the failure signal. A user question can be reduced to a question-and-answer decision rather than storing a raw object that would be difficult to interpret on restore.
Some events are created through a small handshake between hooks. For example, the pre-tool route may know that a WebFetch or large Read was redirected, but loading the native database in that early hook could interfere with its stdout contract. It writes a marker instead. PostToolUse consumes the marker and records the rejected approach or the bytes that were kept out of context. This preserves the event without making the pre-execution response fragile.
The same pattern handles information that is otherwise invisible to a normal tool-result hook. A session-start hook can capture project rules loaded before ordinary tools run. The server can leave a retrieval marker for a later ordinary hook because the PostToolUse path does not fire for context-mode’s own MCP calls.