joxo

Blog / codex

Handing work from Claude Code to Codex without losing the thread

The second agent never saw the first one's conversation. What a handoff note needs, how to share instructions between the two, and a template to copy.

On this page
  1. Start with the instructions both agents read
  2. Hand off a commit, not a working tree
  3. What the note needs
  4. Let the outgoing agent write it
  5. Make the receiver prove it understood
  6. Where the note lives
  7. When it's two people, not two sessions

Switching agents mid-task is routine now. One is better at the review pass. A teammate lives in a different tool. You want a second opinion on a bug the first agent has circled for an hour. Whatever the reason, the new agent starts with an empty head.

It has not read the conversation. It does not know what the first agent tried, what you ruled out, or why the obvious fix is the wrong one. All it has is the repository and whatever you type next. Most failed handoffs are that gap, and nobody noticed it was a gap.

Start with the instructions both agents read#

Before any single handoff, get the standing instructions right. The two tools read different files, and neither falls back to the other.

Claude Code reads CLAUDE.md. Its memory docs say plainly that it does not read AGENTS.md. Codex reads AGENTS.md: it walks from the repository root down to your working directory, and in each directory it looks for AGENTS.override.md, then AGENTS.md, then any fallback names you configure.

So a repo with only CLAUDE.md is invisible to Codex, and a repo with only AGENTS.md is invisible to Claude Code. The least painful fix is one source of truth and one line of glue. Put the real rules in AGENTS.md, and make CLAUDE.md import it:

md
@AGENTS.md

## Claude Code
- Use plan mode for anything under `src/billing/`.

Claude Code expands @path imports when a session starts, so it sees the same rules Codex sees, plus whatever you add for it. A symlink (ln -s AGENTS.md CLAUDE.md) also works, but it needs extra permissions on Windows, and the import doesn't.

This matters for handoffs because everything stable belongs here: how to run the tests, the naming rules, what never to touch. The handoff note should then carry only what is true of this task, today.

Hand off a commit, not a working tree#

The most common failure we can describe in one sentence: "continue where I left off", said to an agent that is looking at a different directory.

Uncommitted changes live in one working tree. A second agent in another checkout, or on a teammate's laptop, can't see them. So the handoff starts with a commit on a pushed branch:

bash
git add src/export/ tests/export.test.ts
git commit -m "wip(export): CSV streaming works, quoting bug open"
git push -u origin feat/csv-export
git rev-parse --short HEAD

A work-in-progress commit is fine. Squash it when the work lands. A hash is a fixed point: both agents can check out the same bytes and agree on what "done so far" means.

What the note needs#

Think of it as the transcript, compressed to what the next agent can act on. Six things, in this order of importance:

  1. Where. Branch and commit.
  2. The goal in one sentence, as a result someone could check.
  3. State. What works, what doesn't, and what is only assumed.
  4. The next step, singular and concrete. "Fix the quoting bug in escapeCell" beats "finish the exporter".
  5. How to verify. The exact command that goes red now and should go green.
  6. Decisions and dead ends. What was settled and why, and what was tried and failed. This is the part people skip, and it's the part that stops the new agent from happily repeating the failed attempt.

Add open questions that need a human, with a default the agent can take if nobody answers. An example:

md
## Handoff: CSV export
Branch `feat/csv-export` at `a41c9e2`.

Goal: `GET /orders.csv` streams every order for a shop, under 200 MB of memory.

State: streaming works and handles 1M rows in the benchmark. Quoted cells
containing commas are still wrong (see the failing test). Not started: the
UI button.

Next: make `tests/export.test.ts > quotes commas` pass by fixing
`escapeCell` in `src/export/csv.ts`.

Verify: `npm test -- export`

Decided: streaming via `Readable.from`, not building the string in memory.
The first approach (buffer then send) passed tests and ran out of memory at
300k rows, so don't go back to it.
Tried, failed: the `csv-stringify` package; it dropped the BOM Excel needs.

Open question for a human: should refunded orders be included? Default
if nobody answers: include them with a `refunded` column.

Notice what isn't there: the agent's reasoning, a summary of the whole session, adjectives. If it can't change what the next agent does, leave it out.

Let the outgoing agent write it#

The agent that did the work is the best placed to write the note, and it's quick. Keep a standing prompt:

text
Write a handoff note for the next agent. Include: branch and commit
(commit and push first), the goal in one sentence, what works and what
doesn't, the single next step, the exact command to verify it, decisions
made with the reason, anything tried that failed, and open questions with
a default. Keep it under 200 words. Don't summarise the conversation.

Then read it. You are checking for the unverified claim, such as "tests pass" when nobody ran them since the last edit.

Make the receiver prove it understood#

Before the new agent changes anything, ask it for two things: the next step in its own words, and a run of the verify command. If the command doesn't fail the way the note says, the note is wrong, or the checkout is the wrong one, and you have learned that in a minute rather than after twenty minutes of edits.

This is also a cheap check on instructions. If Codex restates the plan and gets a rule wrong, the rule is missing from AGENTS.md, and you fix it once for every future session.

Where the note lives#

Options, roughly in order of how long they survive: the commit message body, the pull request description, a HANDOFF.md on the branch. Our preference is the pull request description, opened as a draft, because the next agent and the human reviewer both read it and it dies with the branch. If you use a file, delete it before merging, or you will carry an out-of-date note forever.

When it's two people, not two sessions#

Everything above works for you moving between tools at one desk. It gets harder when the agents belong to different people. The note has to travel, and arrive in the other agent's context without anyone pasting it in. That is what Joxo's handoffs are for: the branch, the commit and the note go from one agent to the next, and the receiving agent sees them at its next turn. The template above works either way. Write it well and the transport matters much less.