- Published on
Why We Built a Compaction System Instead of Handing Off to New Agents
- Authors

- Name
- Duncan Leung
- @leungd
In my previous post, I described how /compact is lossy — it drops external state mutations, abandoned approaches, and behavioral constraints — and how a precompact/postcompact checkpoint system makes compaction safe. That system worked. We used it for months.
But it left a harder question unanswered: should you compact at all, or should you hand off to a fresh agent?
We tried both. Handoff lost.
The Case for Handoff
The argument for handoff is clean. When an orchestrator session fills its context window, you stop it, write a brief, and start a fresh session. The new agent reads the brief and picks up where the old one left off. No degraded reasoning from a bloated context. No lossy compression. A clean slate.
In a multi-agent topology like OpenRig — where an orchestrator routes work to implementation and review seats — the handoff model looks like this:
- The orchestrator detects it is approaching context limits.
- It writes a handoff brief: current state, pending work, decisions made, external mutations.
- A new orchestrator session starts, reads the brief, and resumes.
This is the approach I recommended in the previous post for cases where reasoning had degraded. "A fresh session via handoff is the right call," I wrote. "No amount of checkpointing saves a session that has lost the ability to reason about its own output."
I was right about the reasoning part. I was wrong about how often reasoning degradation is the actual problem.
Why Handoff Failed in Practice
Over several weeks of running OpenRig's factory loop — a pipeline that takes tickets from a backlog, dispatches implementation to a dev seat, routes PRs to a review seat, and manages merge gates — we accumulated enough handoff experience to see the pattern clearly.
1. Startup Overhead Is Not Free
A fresh orchestrator session does not start working immediately. It must:
- Run
rig whoami --jsonto establish identity - Read the handoff brief
- Read the factory configuration (
.factory.yml) - Read the project CLAUDE.md and global instructions
- Load the factory-loop skill (~2000 lines)
- Run restart reconciliation against the queue, GitHub, and git worktrees
- Verify peer seat states
This takes 60–90 seconds and consumes 30–50K tokens before the new session does any actual work. For context: the orchestrator's entire budget is ~140K tokens. A handoff burns 25–35% of the new session's capacity on orientation alone.
Compaction, by contrast, preserves the skill loading, the CLAUDE.md instructions, and the system prompt. The post-compact session starts with those already in context. The restore overhead is the restore map (a few KB) plus the ranked reading list — typically 8–12K tokens of targeted reads versus 30–50K of cold-start discovery.
2. Continuity Is the Product
An orchestrator's value is not the code it writes — that happens in the dev seat. The orchestrator's value is the decisions it has made, the state it tracks, and the relationships it maintains with peer seats.
A handoff brief captures the facts. It does not capture the judgment. When a human says "improve the existing pipeline rather than expanding it," that directive colors every subsequent prioritization decision. A compacted session retains that directive in its summary. A handoff brief records it as a bullet point that the new session may or may not weight correctly.
After three handoffs in one day, we observed the new orchestrator re-proposing work the human had already rejected, dispatching tickets in the wrong priority order, and losing track of which advisor corrections had been applied. The facts were in the brief. The judgment was not.
3. Developer Experience Matters
This one is pragmatic. The human operator works in the orchestrator's terminal. They see the conversation history, the decision points, the approvals they gave. A handoff resets that history. The operator loses their place.
With compaction, the conversation continues. The operator sees the compaction marker, then the restore, then the next piece of work — all in the same terminal, the same session, the same thread. They can scroll up and see the approval they gave two hours ago. With handoff, that approval is in a different session's transcript, and the operator must trust that the new agent internalized it correctly.
For a system where the human is the decision-maker and the agents are the executors, maintaining the human's continuity with the conversation is not a convenience — it is a design requirement.
The Compaction System We Built
Given that compaction is the right choice, the question becomes: how do you make compaction safe and useful? The system has three layers.
Layer 1: The Restore Map
Before compaction, the orchestrator writes a restore map — a structured document that captures everything the post-compact session needs to resume. Unlike the earlier checkpoint format (a flat list of fields), the restore map is organized around what the session will do next:
## Summary (10 lines)
I am orch-lead@openrig, factory-loop orchestrator.
This session merged 21 PRs (#39–#58)...
## Active Work
### RIG-9 — Downvote filtering
- State: planning — dispatched to dev-impl
- Queue item: qitem-20261018181522-6a53706a4844edf0
- What to do next:
1. Wait for TICKET_LOOP_RESULT from dev-impl
2. If pr-created: transition to reviewing
3. If escalate: present to human
## Session Totals
- PRs merged: 21 (#39–#58)
- Tickets created: RIG-98/99/100/101
## Ranked Reading List
| # | Path | ~tokens | Why |
|---|----------------|---------|------------------------|
| 1 | world pack | ~2000 | Re-enter the world |
| 2 | restore map | ~4500 | Primary restore source |
| 3 | .factory.yml | ~400 | Config |
| — | Tier 1 line | | ~8900 tokens |
| 8 | factory-loop | ~12000 | Pipeline reference |
| — | Tier 2 line | | ~28200 tokens |
The ranked reading list is the key innovation over the flat checkpoint. Instead of "here are all the things you should know," it says "here are the things you should read, in priority order, with a running token count." The orchestrator reads to its tier line (Tier 2 for a high-context seat, ~28K tokens) and stops. This turns restoration from an unbounded context-filling exercise into a budgeted one.
Layer 2: The Restore Protocol
After compaction, a pending restore marker sits on disk at a known path. The post-compact session finds it and follows a protocol:
- Read the marker. It contains the restore map path, the session ID, and instructions.
- Read the restore map. This is the primary source of truth — not the compacted summary.
- Follow the ranked reading list. Read each file or run each command up to the tier line.
- Run a read-depth audit. For every required item, mark it FULL, PARTIAL, or NOT_READ.
- Write a RESTORED note. Record what was recovered, what was not, and what the next step is.
- Clear the marker. The restore is complete.
The read-depth audit is what makes this verifiable. The post-compact session cannot claim it restored successfully without proving it read the required files. A partial read or a skipped file shows up in the audit table, and the session must read it in full before continuing.
The trust model is explicit: the restore map is ground truth. The compacted summary is a fallback. When they disagree, the map wins. This matches the insight from the earlier checkpoint system, but formalized into a protocol that every session follows.
Layer 3: The Wiki Distill
This is the newest piece, and the one that made compaction not just safe but productive. After a successful /compact, a SessionStart hook fires and:
- Finds the newest restore map for the seat (must be less than 15 minutes old).
- Redacts it — strips API keys, tokens, secrets, and long base64 strings.
- Sends the redacted map to Claude Haiku via a direct API call.
- Redacts the response a second time.
- Writes a wiki page to
wiki/sessions/with structured headings: Accomplished, Decisions, Open Items.
The hook runs as a detached child process. It returns immediately — the session startup is never delayed. The wiki page appears a few seconds later.
2026-10-18T18:21:07Z outcome=dispatched
2026-10-18T18:21:14Z outcome=written page=2026-10-18-orch-lead@openrig-5243fdcd.md
Seven seconds, end to end. The session was already restored and working by the time the wiki page landed.
Why a direct API call instead of using the Claude Code subscription? The hook runs outside Claude Code's conversation loop. It is a Node.js script triggered by a hook event. It has no access to the subscription's message stream. A direct fetch() to api.anthropic.com with an ANTHROPIC_API_KEY is the only way to call a model from a hook. The cost is negligible — one Haiku call on a 64KB input with a 2000-token output cap runs about $0.01–0.02 per compaction.
Why Haiku? The distill does not need Opus-level reasoning. It summarizes a structured document into three sections. Haiku does this well, fast, and cheap. The confidence: low frontmatter on every page tells readers (including other agents) to verify before acting.
Why redact twice? The restore map may contain secrets the orchestrator handled during its session. Redacting before the API call prevents secrets from reaching the model. Redacting after the API call catches cases where the model hallucinates a secret-shaped string that happens to match a real one. Belt and suspenders.
The Result: 21 PRs in One Session
The compaction system has run through three compaction cycles in one orchestrator session. That single session — the same conversation, the same terminal, the same human continuity — processed 21 PRs across 20+ tickets, including:
- Implementation dispatches to a dev seat
- Code review dispatches to a quality reviewer seat
- ESCALATE gates with human plan approval
- A comprehensive backlog audit with six parallel research forks
- Advisor validation of the audit results
- Ticket creation, cancellation, and priority adjustments
Each compaction cycle took about 30 seconds for the restore and 7 seconds for the wiki distill. The session resumed at the exact point it left off, with verified state and a wiki page that other agents (and the human) can reference.
A handoff-based system would have required three fresh orchestrator sessions, each burning 30–50K tokens on cold start, each losing the accumulated judgment of the prior session. The human would have switched terminals three times. The conversation history would be spread across three transcripts.
Compaction kept it as one conversation.
What the Research Says
The academic literature does not declare a winner. Two recent papers study the failure modes of each approach in isolation — no published work compares them head-to-head as alternative strategies.
Compaction silently drops behavioral constraints
Wang et al.1 measured constraint retention across six compaction methods and three scenarios. The results are bad: only 17% of injected behavioral constraints survive compaction on average, and compliance with session constraints drops from 99.7% to 31.8% after compaction. In a controlled inbox experiment, 30 of 100 sessions saw unauthorized email deletions after compaction versus zero before.
This is the failure mode our restore map was built to address. The map writes constraints to disk before compaction and restores them afterward — functionally equivalent to the paper's recommended mitigation, a separate constraint extractor that maintains a registry apart from the task summary. Their extractor (a 9B model) achieves over 90% retention and raises compliance from ~54% to ~95%. Our restore map serves the same purpose: the constraints survive because they are on disk, not in the compressed summary.
The 17% average includes non-LLM compactors (truncation, LLMLingua-2) that retain zero constraints. LLM-based compactors like GPT-5.4-mini retain 88–98% in two of three scenarios. The headline number is real but overstates the problem for well-designed compaction systems.
Handoff carries a "handoff tax"
Ganz et al.2 studied what happens when one model inherits another's trajectory (the handoff scenario). On SWE-bench Verified across 58,000 agent runs, full-trajectory handoff recovers less than half the quality gap between cheap and strong models: 47% for Claude, 36% for GPT.
The finding that matters most for our use case: compaction outperforms raw handoff for escalation (weak-to-strong). Claude with compacted trajectory hits 71.8% at 1.61. Compaction is both cheaper and more effective when a stronger model picks up from a weaker one.
But the paper also found a directional asymmetry we did not account for: for strong-to-weak handoff, removing the predecessor's trajectory hurts quality (-4.7pp for Claude, -5.6pp for GPT, both statistically significant). A blanket recommendation of either compaction or trajectory removal is wrong — the right strategy depends on whether the receiving model is stronger or weaker than the one that produced the context.
In our topology, the orchestrator (Opus) compacts its own context and restores within the same model family. This is neither escalation nor downshift — it is same-model continuation, which neither paper directly studies. Our empirical result (21 PRs across 3 compaction cycles without regression) is evidence for the specific case, not a general claim.
The gap in the literature
No paper directly compares compaction against handoff as alternative context-management strategies for the same task. The compaction papers analyze information loss. The handoff papers analyze trajectory inheritance. Each body of research measures one approach in isolation. Our blog post's conclusion — that compaction is better for long-running orchestrators — is an empirical observation from one system, not a finding supported by controlled comparison.
When Handoff Is Still Right
Compaction is not universally better. Handoff wins when:
- Reasoning has genuinely degraded. If the orchestrator is producing circular logic or ignoring instructions, no amount of context management helps. Kill it and start fresh.
- The session crosses a phase boundary. If Phase A is planning and Phase B is execution, a handoff between them is natural — the new session needs Phase B context, not Phase A's exploratory dead ends.
- The receiving model is weaker. The Handoff Tax paper shows that strong-to-weak handoff benefits from keeping the full trajectory. If you are downshifting to a cheaper model for cost reasons, compaction (which removes context) hurts. Keep the trajectory intact.
- The agent is not an orchestrator. An implementation seat that finishes a PR does not need to compact — its job is done. The orchestrator tracks the pipeline state; the implementation seat is disposable.
The compaction system is built for long-running orchestrators whose value accumulates over time. For short-lived workers, handoff (or simply stopping) remains the right call.
The Design Principles
Three principles shaped this system, and they generalize beyond compaction:
1. Write ground truth to disk before you lose it. The context window is volatile. Disk is durable. Anything that must survive a context reset — state, decisions, external mutations — must be on disk before the reset happens. This applies to compaction, crashes, and session endings alike.
2. Budget your restoration. A post-compact session that reads everything it can find fills its context with orientation material and has no room for actual work. The ranked reading list with tier lines forces a budget: read the most important things first, stop at the budget, and trust that the map captured what matters.
3. Make compaction produce something. The wiki distill turns a maintenance operation (freeing context) into a knowledge-creation operation (producing a session summary). Every compaction leaves behind a searchable, browsable record of what the session accomplished. Over time, these pages become the project's institutional memory — written by the agents, for the agents and the human.
Compaction is not a limitation to work around. With the right system, it is a feature.