learnaiwithrafa
ClaudeWorkflows

A Good Handoff Is Mostly a List of Dead Ends

Compaction and `/resume` both preserve what happened. Neither preserves what you decided against — and the abandoned attempts are the most expensive thing in a long session. Here's the handoff file that fixes it, the prompt that writes it, and the one-liner that generates it from a session you already closed.

8 min read4 sources
  • #claude-code
  • #context
  • #handoff
  • #sessions

Three hours into a session you've tried the streaming approach and abandoned it, ruled out two libraries, and found out the test suite lies about one specific case. Then the window fills, the session compacts, and twenty minutes later Claude proposes the streaming approach.

That isn't a memory failure. It's a design decision, and it's documented. Claude Code's docs list exactly what a compaction summary keeps: "your requests and intent, key technical concepts, files examined or modified with important code snippets, errors and how they were fixed, pending tasks, and current work." Then: "It replaces the verbatim conversation: full tool outputs and intermediate reasoning are gone."

Every dead end you hit lives in intermediate reasoning. It never became a file, never became a diff, never became a fixed error — so nothing on disk records it. Compaction preserves what happened. Your rejected branches never happened. That asymmetry is the entire handoff problem.

/resume is not a handoff

The obvious objection: why write anything down when claude --resume exists? Because resume solves a different problem. The docs are explicit that a resumed session restores "the full history, including tool calls and results" — so you reopen the exact bloated window you were trying to escape, and it compacts again shortly after. That's continuation, not consolidation.

Three more limits, worth knowing before you treat it as your safety net:

  • It's directory-scoped. Session ID lookup covers the current project directory and its git worktrees, nothing else. Resume from the wrong folder and you get No conversation found with session ID.
  • It expires. Transcripts sit at ~/.claude/projects/<project>/<session-id>.jsonl under a 30-day retention by default (cleanupPeriodDays). Last quarter's hard-won debugging is already deleted.
  • The file isn't a document. "The entry format is internal to Claude Code and changes between versions, so scripts that parse these files directly can break on any release." A transcript is an append log, not knowledge.

And /export, which renders the conversation as readable text? That one is explicitly for a person to read. Pasting 40k tokens of rendered transcript into a fresh session is the worst of both worlds: you pay full price for the noise and Claude still has to re-derive every conclusion.

The file shape

One file per task, at a path you'll actually open — I use notes/handoff-<task>.md. Six sections, in this order, because that's the order a cold reader needs them in:

# Handoff — <task> · <date> · session <name>

## GOAL
One sentence. Plus how we'll know it's done (the command, the test, the check).

## STATE
- Done:
- In progress:  ← name the exact file and what's half-edited
- Open:

## DECISIONS
- Chose X over Y because Z.

## RULED OUT — do not retry
- Tried A → failed with <exact error or reason>.
  Retry only if <what would have to change>.

## GROUND TRUTH
Files touched · the command that proves it works · every ID, URL, version
and number the work depends on.

## NEXT
The single next command or edit, runnable without asking me anything.

RULED OUT is not a nice-to-have appendix. It's the one section nothing in your toolchain will reconstruct for you, and it's the reason the file exists at all. Everything above it, a fresh session could re-derive from the code in ten minutes. That section it can only re-derive by repeating your mistakes.

The prompt that writes it

Paste this into the session that's about to die:

Write a handoff to notes/handoff-<task>.md so a fresh session with zero
conversation history can take this over. Use exactly these sections:

GOAL — one sentence, plus how we'll know it's done.
STATE — Done / In progress (name the exact file and what's half-edited) / Open.
DECISIONS — each choice we locked in, with the reason. No reason? Say so.
RULED OUT — every approach we tried and abandoned, the exact error or reason it
  failed, and what would have to change for it to be worth retrying. Do not
  compress this section. It is the point of the file.
GROUND TRUTH — files touched, the command that proves it works, and every ID,
  URL, version and number the work depends on.
NEXT — the single next command or edit, runnable without asking me anything.

Rules: no praise, no recap of the conversation, no advice, no suggestions I
didn't ask for. If you can't tell whether something was decided or only
discussed, put it under Open and mark it "unconfirmed". Every line has to be
something that actually happened in this session, not something you're
inferring right now.

That last rule is doing real work. Ask a model to summarise a session and it will helpfully smooth over the gaps with plausible reconstruction — which is how a handoff quietly turns into fiction. Naming the constraint keeps the file auditable.

Then, in the fresh session:

Read notes/handoff-<task>.md. Don't start work yet. Tell me in three lines:
the goal, the next action, and anything in RULED OUT you would otherwise
have tried.

That third line is the test. If Claude names something it was about to attempt, the file already paid for itself. If it names nothing, your RULED OUT section is too vague to bite.

The move almost nobody knows

You don't have to be inside a session to generate its handoff. Claude Code's docs show a headless path: send a prompt to an existing session by ID and capture the answer as structured JSON.

claude -p --resume <session-id> --output-format json \
  "Output only the handoff file body. <the prompt above, minus the file path>" \
  | jq -r '.result' > notes/handoff-checkout-bug.md

This is the escape hatch for the session you already closed, or the one you walked away from at 1am. Anything inside the 30-day window is still reachable. Grab the ID from the /resume picker — Ctrl+A widens it to every project on the machine.

Two neighbours worth keeping in the kit. /branch copies the conversation so far into a new session ID and leaves the original untouched, which is the right tool when you want to try the risky approach instead of writing down that it failed. And a SessionEnd hook can archive the transcript automatically, if you'd rather not think about it at all.

Why this is a skill, not a trick

Anthropic's context-engineering write-up names the underlying pattern: structured note-taking, where an agent "regularly writes notes stored externally" and reads them back after a reset. Their sharpest illustration is Claude playing Pokémon — after a context reset, "the agent reads its own notes and continues multi-hour training sequences." Same essay, on the hard part of compaction: "maximize recall to ensure your compaction prompt captures every relevant piece of information from the trace, then iterate to improve precision." Recall first, precision second. Which is exactly why RULED OUT tells the model not to compress it.

If the same section keeps showing up in handoff after handoff, stop copying it forward by hand. Claude Code lets you add a "Compact Instructions" section to CLAUDE.md to steer what every automatic compaction preserves — that's where a standing "always keep the list of rejected approaches" belongs. Once it's structural, you stop paying for it every time.

The EM angle

This is the same artifact you already owe a human. A teammate picking up your half-finished branch needs the goal, the state, the decisions and the dead ends — in that order. Write handoffs for Claude for a month and your PR descriptions and standup updates get sharper too, because you've been drilling the one thing most engineers skip: writing down what you tried and why you stopped.

If you're interviewing for remote roles in the US or EU, that's not a soft skill. Distributed teams run on written state, and "here's what I ruled out and why" is the clearest signal there is that you can work with people eight hours away.

Do this today

Take your longest open session — the messy one you keep resuming — and run the handoff prompt on it now. Then read only the RULED OUT section. If it comes back empty or vague, you just learned something uncomfortable: three hours of eliminated options were about to evaporate. Save the file, /clear, and reload it with the three-line check. Four minutes, and it's the cheapest insurance in your whole setup.

Sources