Every LLM-based coding agent hits a wall. Not an error wall, not a logic wall .; a context window wall. The prompt accumulates tool calls, responses, file contents, and intermediate reasoning until there is physically no room left for the next operation. What happens at that moment determines whether the agent finishes the task or stumbles into incoherence.
Most agents do what chat applications have done for years: they compact. They ask the LLM to summarise the conversation so far, replace the raw history with a condensed version, and keep going. This works reasonably well for Q&A sessions where the user wants a single answer. For coding tasks .; multi-file edits, test debugging, refactoring with cascading changes .; compaction is catastrophic.
I spent months watching compacted agents lose track of what they were doing, repeat failed approaches, violate user constraints stated earlier in the conversation, and produce inconsistent edits because they could not remember which files they had already modified. Eventually I stopped compacting and started handing work to a fresh agent with a structured document describing exactly what happened and what to do next.
This post explains why long coding sessions degrade, what compaction loses, why code changes demand more than a generic summary, and how RaggieCode's structured handover mechanism solves the problem.
Why Long Coding Sessions Degrade
A coding agent's context window is not just a conversation log. It contains:
- System prompts with role definitions, tool descriptions, and behavioral rules
- Code exploration results: file structures, function signatures, symbol definitions
- Tool call histories: every
GetSymbolSourceCode,ReplaceText,Shellinvocation - Test outputs: assertions, stack traces, coverage reports
- User messages: requirements, clarifications, mid-task changes
- Intermediate reasoning: the LLM's chain-of-thought about what to do next
Each of these components is essential for coherent execution. The system prompt tells the agent what tools it has. The exploration results tell it where symbols live. The test outputs tell it whether a change succeeded. The user messages carry constraints and preferences.
As the session grows, the agent must spend an increasing fraction of its limited context window on the accumulated history rather than on current work. The LLM's attention is diluted across thousands of tokens of past tool calls. Retrieval of specific details .; "what was that error message again?" .; becomes unreliable because the information is buried in a sea of earlier turns. The agent slows down, makes more mistakes, and eventually hits the token limit.
What Compaction Loses
Context compaction seems like a reasonable solution: ask the LLM to summarise the conversation and replace the history with a shorter version. The problem is that summaries are lossy by design, and the information they lose is precisely the information a coding agent needs most.
Decision Rationale
A compacted summary might say "chose SQLite over PostgreSQL." It will not say why. The next agent, reading the summary, has no idea whether SQLite was chosen for performance, simplicity, portability, or because the data volume is low. That matters when the next agent needs to decide whether to add a migration tool, use connection pooling, or switch to PostgreSQL later. Without the rationale, it makes decisions in a vacuum.
Failed Approaches
Summaries are biased toward outcomes. They describe what worked. Failed approaches, dead ends, and approaches that were tried and rejected are almost always omitted. A compacted session looks like a success story. The next agent is condemned to repeat the same dead ends because it never learns they were tried. I have watched compacted agents re-run the same failing test three times across three compactions, each time trying the same fix that the original agent already attempted and abandoned.
Exact Error Messages
"Tests failed" is not actionable. "Tests failed: test_login_invalid_email
expected INVALID_EMAIL but got VALIDATION_ERROR" is actionable.
A summary condenses the first into the second, stripping the specific error code that the
next agent needs to fix the problem. The next agent must either re-run the test (wasting
time and tokens) or guess at the error.
User Constraints
Constraints stated early in a conversation are the first thing compaction drops. If the user said "do not touch the database layer" in turn 3, and compaction happens at turn 30, that constraint is gone. The next agent might blithely modify the database schema.
Change Boundaries
"Modified 3 files" is not useful. "Created validators.py, updated
views.py line 42-58, updated routes.py line 15" is useful.
Without knowing exactly what changed and where, the next agent cannot tell whether a
newly observed bug was introduced by the previous agent or pre-existed.
Goal Drift Across Multiple Compactions
The most insidious failure mode: when a task requires multiple compactions, each summary is a lossy compression of the previous summary. The original goal degrades with each pass. After three compactions, the agent might be implementing something very different from what the user asked for, and nobody .; not the user, not the agent .; will notice until the results are wrong.
Why Code Changes Require More Than a Generic Summary
Chat sessions and coding sessions differ in a fundamental way: chat is about information, coding is about state.
In a chat session, the user asks a question and the assistant answers. The only state is the conversational context. If a summary drops the fact that the user mentioned Python 3.10, the next turn can ask for clarification. The cost of a lost detail is a minor annoyance.
In a coding session, the agent modifies files, runs commands, and changes the actual state of the codebase. A lost detail means:
- A file is modified inconsistently with previous edits
- A test that was already passing is broken by a redundant change
- A constraint is violated because it was mentioned early and forgotten
- A failing test is never fixed because the next agent does not know it failed
- A design decision is reversed because the rationale was lost
The consequences are not conversational friction. They are broken code, failed builds, and wasted developer time debugging regressions introduced by the agent itself.
This is why a generic "summarise the conversation" approach is fundamentally inadequate for coding agents. The handover document must be structured, exhaustive, and field-specific. Each type of information .; decisions, changes, failures, constraints, next steps .; needs its own dedicated slot that cannot be omitted.
The Structured Handover Format
RaggieCode's handover document is a JSON object with exactly 12 fields. Each field captures one dimension of session state that compaction would lose. Together they form a complete picture of what happened, why, what changed, and what to do next.
| # | Field | Purpose |
|---|---|---|
| 01 | original_goal |
The user's original request. Never changes across multiple handovers, preventing goal drift. |
| 02 | current_objective |
What the agent was working on when the handover triggered. More granular than the original goal. |
| 03 | code_state |
Branch, last commit hash, and summary of modified files. Ground truth for what has changed. |
| 04 | important_files_and_symbols |
Files and symbols most relevant to the objective. The new agent loads these directly without rediscovery. |
| 05 | decisions_made |
Design decisions and rationale. Prevents re-debating settled questions. |
| 06 | changes_applied |
Every file creation, modification, or deletion, with summaries of each change. |
| 07 | test_results |
Which tests passed, which failed, and their error messages. |
| 08 | errors_and_failed_attempts |
Approaches that did not work and why. Prevents repeating dead ends. |
| 09 | user_constraints |
Explicit restrictions or preferences the user expressed during the session. |
| 10 | things_not_to_repeat |
Actions the next agent must avoid duplicating. Saves time and prevents redundant work. |
| 11 | exact_next_step |
The precise next action. Not "continue working" but "run pytest tests/test_auth.py to verify." |
| 12 | relevant_messages_tool_calls |
Key user messages, agent responses, and tool results as a highlight reel of the session. |
The key insight here is that each field exists because compaction would lose it.
Field 5 (decisions_made) exists because summaries drop rationale. Field 8
(errors_and_failed_attempts) exists because summaries focus on successes.
Field 10 (things_not_to_repeat) exists because compacted agents repeat work.
Field 1 (original_goal) exists because goal drift across multiple compactions
is the single worst failure mode of the summarisation approach.
The full specification of the handover schema, including real-world examples of each field, is documented in the Agent Handover documentation. The implementation lives in the RaggieCode GitHub repository under the agent prompt loop and handover generation modules.
How a Fresh Agent Resumes
The handover document is not just stored for debugging. It is executable context. When RaggieCode detects that the context window is approaching its limit (currently checked before every LLM call, with a configurable margin), it generates the handover document, serialises it, and passes it to a fresh agent session.
The new session loads the handover directly into its system prompt. The LLM wakes up and sees:
## SESSION HANDOVER
The previous session ran out of context. Continue its work
based on the information below. Do NOT repeat actions listed
in "things_not_to_repeat". Start with the action in
"exact_next_step".
--- HANDOVER DOCUMENT ---
{12 structured fields}
--- END HANDOVER DOCUMENT ---
From the very first token of the new session, the agent knows:
- What the user originally asked for (field 1)
- Where the previous agent was in the task (field 2)
- What has already been done (fields 3, 4, 6)
- Why decisions were made (field 5)
- What failed and what was tried (fields 7, 8)
- What to avoid repeating (field 10)
- What to do immediately (field 11)
It does not re-index the codebase (the semantic index persists on disk in
.raggie/.code_index.raggie). It does not ask the user "what were you working
on?" It does not re-read files it already knows about. It directly loads the important
files and symbols from field 4, checks the git state from field 3, and executes the
exact next step from field 11.
The result is a session transition that the user barely notices. The terminal shows a brief handover notice, and then normal output resumes. No re-explaining, no lost work, no regression from forgotten details.
This mechanism also integrates with RaggieCode's todo list system. When a handover occurs mid-todo-list, the active todo list is preserved in the SQLite database. On the next startup, if an incomplete todo list is detected, the agent offers to resume it. The handover document records which tasks are complete and which one is pending, giving the new agent both the macro plan (the todo list) and the micro state (the handover document).
Tradeoffs and Limitations
Structured handover is not a universal solution. It has real tradeoffs that are worth understanding.
Handover Quality Depends on the LLM
The handover document is generated by the same LLM that is running the session. A model with weak instruction-following may produce an incomplete or inaccurate handover. GPT-4o, Claude 3.5+, and DeepSeek V3+ produce reliable documents. Smaller models may drop fields or include hallucinated details. The handover is only as good as the model that generates it.
Token Overhead
A detailed handover document can consume 2K–5K tokens in the new session. For users with small context windows (8K or 16K), this is a significant fraction of the available space. Frequent handovers on small-window models leave less room for actual work. This is a genuine cost, though it is usually offset by the elimination of repeated exploration and failed attempts.
No Full Transcript
The handover document is not a transcript. It is a structured summary. If a subtle detail does not fit into any of the 12 fields, it is lost. The tradeoff is deliberate: a full transcript would be too large to fit in the new session's context window. The handover prioritises actionability over completeness. It captures everything the next agent needs to do, but not everything the previous agent saw.
User Context Can Be Missed
The handover check runs before each LLM call. If the user sends a message just as the
handover triggers, that message may not be included in relevant_messages_tool_calls.
The window of loss is small (a single user turn) but non-zero. In practice, the tight
integration with the prompt loop means this is rare.
Not a Version Control System
The handover captures a snapshot of changes, but it is not a replacement for proper
version control. RaggieCode maintains a built-in git repository at
.raggie/git/ precisely for this reason. If you need to roll back changes,
use /undo. The handover is about continuity, not history.
When to Compact vs When to Hand Over
Context compaction is not always the wrong choice. For simple tasks .; a single question about the codebase, a one-edit fix, a read-only exploration .; compaction works fine and costs fewer tokens than a full handover. The overhead of generating a 12-field JSON document and starting a fresh session is not justified for a two-turn interaction.
Handover becomes necessary when:
- The task spans multiple files and multiple edits
- There are test failures to track and fix
- Design decisions were made that the next agent must respect
- The user stated constraints that must be preserved
- The task may require multiple sessions to complete
In practice, any task that a human developer would describe as "substantial" .; adding a feature, refactoring a module, migrating a database, fixing a chain of failing tests .; benefits from structured handover over compaction.
Why This Matters
The context window is the fundamental constraint on LLM-based agents today. No amount of prompt engineering or model improvement will eliminate it .; larger windows help, but they still fill up eventually. The question is not whether an agent will hit the limit, but what happens when it does.
Context compaction treats the symptom by squeezing the conversation into less space. Structured handover treats the cause by transferring task state to a fresh session with zero information loss on the dimensions that matter: what was done, why, and what to do next.
The difference is the difference between a summary and a specification. A summary tells you what happened. A specification tells you what to build. Coding agents need specifications, not summaries, because they are building things, not having conversations.
RaggieCode's handover mechanism is open source and implemented in the main agent prompt loop. If you are building an AI coding agent or wondering why your current agent loses track of complex tasks, the agent handover documentation provides the full specification, and the source code shows every detail of the implementation. The 12-field schema, the handover generation logic, and the session startup code are all there for you to study, modify, or adapt.