Hand off a coding task between AI agents without losing context
An agent's context window fills up, or you want a second model to finish the job. The next agent then starts cold: it re-reads the repository, rediscovers what was decided, and often retries the approach that already failed. Git does not help, because a diff shows what changed, never why or what was tried.
What a good handoff contains
- Done and remaining: where the work stands.
- Decisions and the reason for each, attached to the code they are about.
- Dead ends: what was tried and why it failed, so nobody tries it again.
- What is broken right now and open questions.
- The changes themselves, small enough to fit in the next agent's first prompt.
Writing that by hand at the end of every session is the step everyone skips. Scholion has the agents record it as they go and assembles it for them.
Set up (once)
# the daemon, Postgres and an embedding server, all on 127.0.0.1
export UID GID=$(id -g)
docker compose -f deploy/docker-compose.yml up -d --build
# connect any MCP client, e.g. Claude Code
claude mcp add --transport http av http://localhost:7420/mcp
Agents without MCP use the av CLI, which offers the same operations.
1. The first agent records as it works
av task start --repo shop --title "Bulk discount on cart totals" --goal "..."
av record --kind decision --anchor shop/pricing.py:line_total \
--summary "Apply the bulk discount in pricing.line_total, not in Cart: invoices call pricing directly"
av record --kind attempt --anchor shop/pricing.py:total \
--summary "Tried rounding every line to the cent before summing: totals drift 1-2 cents from invoices"
Each record is one line (at most 200 characters) with an optional body, anchored to a function. If that code changes later, packs flag the record "changed since recorded".
2. Hand off
av handoff --done "Discount in line_total, rounded on the discount amount only." \
--remaining "Tests for the 10-unit threshold" \
--questions "Should the threshold be per line or per order?"
This is the bundle the daemon returned in a recorded run, trimmed:
## State
Remaining: Tests for the 10-unit threshold
Done: Discount in line_total, rounded on the discount amount only.
## Records
- rec:3e5e25f5 attempt: Tried rounding every line to the cent before summing: totals drift 1-2 cents from invoices
anchors: shop/pricing.py:total
- rec:7620c742 decision: Apply the bulk discount in pricing.line_total, not in Cart: invoices call pricing directly
anchors: shop/pricing.py:line_total
## Changes
- line_total (shop/pricing.py:9-13) (diff of just this function)
## Open questions
Question: Should the threshold be per line or per order? Spec says per line.
---
tokens: 544/4000
3. The next agent claims it
AV_AGENT=codex av claim <task-id>
av context --budget 2000
The claim bumps a generation number, so a late write from the first agent is refused instead of silently clobbering the work. The context pack is built without an LLM: seeds from the goal and the changed code, the reference graph, and a token budget. The same state always produces the same pack.
In the recorded run, Codex's first pack was 890 tokens out of 2,000, and it led with Claude's decision and dead end.