Agent handoff document: pass a coding task between AI agents

A fresh session, a different assistant, or a teammate has to pick up where an agent stopped. This is the document that makes that possible — a template, a filled-in example, and the two ways the next reader consumes it.

Updated

Why does an agent handoff need a document at all?

Context windows end, sessions get closed, and the assistant that started the work is not the one that finishes it. What survives is whatever was written down. A handoff document is a compact, honest account of the state of a task: what was done, what was verified, what is still broken, and what to do next. It is not a transcript, and it deliberately does not carry repository access, credentials, or the previous conversation — only text.

What should an agent handoff document contain?

Nine sections, in this order. Copy the template into your project or ask your assistant to fill it in.

# Agent handoff: <task name>

## Objective
One paragraph: what "done" means, and what must not change.

## Repository and branch
- Repo:
- Branch:
- Base:

## Relevant commit
<hash> — <subject>. Everything below describes the tree at this commit.

## Completed changes
- ...

## Files affected
```
path/one.ts   (new | modified)
```

## Commands run and results
```
npm test  → 14 passed
```

## Unresolved problems
1. ...

## Decisions and constraints
- ...

## Next steps
1. ...

Two of these do most of the work. Commands run and results saves the next agent from re-running a ten-minute test suite to learn what you already know. Relevant commit lets it check git log -1 and see immediately whether the summary still matches the branch.

What does a filled-in handoff look like?

A fictional but realistic one: an agent moved session storage to Redis behind a feature flag, ran the tests, and stopped before the CI and staging work. Everything the next agent needs is in the document, including the pre-existing lint warning it should not waste time on.

agent-handoff.md

2,790 characters · fictional example, same file as the download

Agent handoff: migrate session storage to Redis

Objective

Move acme/shop-web session storage from the in-process memory store to Redis so sessions survive deploys and work across multiple instances. Keep the public cookie format unchanged.

Repository and branch

  • Repo: github.com/acme/shop-web
  • Branch: chore/redis-sessions (pushed)
  • Base: main at 4f2c9a1

Relevant commit

b71e0d3 — "Add Redis session store behind SESSION_STORE flag". Everything below describes the tree at this commit. If git log -1 on the branch shows a different hash, this document is stale.

Completed changes

  • Added lib/session/redis-store.ts implementing the SessionStore interface (get, set, touch, destroy) with a 7-day TTL.
  • lib/session/index.ts picks the store from SESSION_STORE=memory|redis (default memory, so nothing changes until the flag flips).
  • docker-compose.yml gains a redis:7-alpine service for local dev.
  • .env.example documents REDIS_URL and SESSION_STORE.

Files affected

lib/session/redis-store.ts      (new)
lib/session/index.ts            (modified)
lib/session/memory-store.ts     (unchanged, still default)
docker-compose.yml              (modified)
.env.example                    (modified)
tests/session/redis-store.test.ts (new)

Commands run and results

npm test -- session         → 14 passed, 0 failed
npm run type-check          → clean
npm run lint                → 1 warning (unused import in memory-store.ts, pre-existing)
docker compose up redis     → healthy on :6379
SESSION_STORE=redis npm run dev → login/logout works; cart persists across a server restart

Unresolved problems

  1. Session touch on every request doubles Redis round-trips. Left as is; measure before optimizing.
  2. tests/session/redis-store.test.ts needs a live Redis. It is skipped in CI (describe.skipIf(!process.env.REDIS_URL)). CI has no Redis service yet.
  3. Not tested: concurrent logins from two instances. Needs the staging environment.

Decisions and constraints

  • Cookie name and signing stay identical, so a rollout does not log anyone out.
  • No session data migration: memory-store sessions are lost on the first deploy with SESSION_STORE=redis. Product agreed (deploy at low traffic, Tuesday 04:00 UTC).
  • Do not add ioredis; the project already uses redis@4.

Next steps

  1. Add a Redis service to .github/workflows/ci.yml and unskip the store test.
  2. Set REDIS_URL and SESSION_STORE=redis in staging; run the two-instance login check.
  3. Open the PR from chore/redis-sessionsmain with this document as the description; request review from the platform team.
  4. After merge: flip the flag in production during the agreed window, watch session_store_errors for one hour.

How do I publish the handoff and pass the link on?

From Claude Code or Cursor with the Docs MD MCP server connected, at the end of the session:

Write an agent-handoff.md for the work in this session using the nine-section
template, then share it with a 7-day expiry and give me both links.

You get a rendered URL and a raw URL. Paste the raw URL into the next session's first message, or into the issue the teammate will pick up. Without MCP, the same thing from a shell:

curl -s -X POST https://docs-md.com/api/share \
  -H "Content-Type: application/json" \
  --data-binary @<(jq -Rs '{content: ., filename: "agent-handoff.md", expiry: "7d"}' agent-handoff.md) \
  | jq -r '.rawUrl'

How does the next agent or person read it?

  • A person opens the rendered link: headings, the file list as a code block, the results table, and a table of contents in the sidebar.
  • An assistant with an HTTP tool fetches https://docs-md.com/raw/<id> and gets the markdown as text/markdown. A first message such as "Read https://docs-md.com/raw/… and continue from its next steps" is enough.

Before acting on the summary, the next agent should compare the commit in the document with the branch head. If they differ, someone worked after the handoff was written, and the document is a starting point rather than the truth.

What are the limits?

  • 120,000 characters per share; a handoff should be far shorter than that.
  • The link is public to anyone who has it. Never include tokens, keys, or customer data.
  • Expiry removes the page at its URL; it does not recall copies already fetched.
  • The next agent needs its own repository access. The handoff carries a summary, not permissions.

See also: share an implementation plan for review and the REST API.

FAQ

How do I hand off a coding task to another AI agent?

Have the current agent write a handoff document: objective, repo and branch, the commit its summary describes, completed changes, files touched, commands it ran with their results, unresolved problems, decisions, and next steps. Publish it as a link. The next agent reads the raw markdown URL; a human reads the rendered page.

What should an agent handoff document contain?

The nine sections in the template on this page. The two that are most often missing and most valuable are "commands run and results" (so the next agent does not repeat them) and "relevant commit" (so it can tell whether the summary is stale).

How can another coding assistant read my markdown progress report?

Give it the raw URL, https://docs-md.com/raw/<id>, which returns plain text/markdown. Any assistant that can fetch a URL — Claude Code, Cursor, Codex, a custom agent with an HTTP tool — can read it directly. The rendered URL without /raw/ is for people.

Does the handoff transfer repository access or conversation history?

No. It transfers a written summary only: no repo access, no credentials, no files, no chat state. The next agent still needs its own checkout and permissions. That is why the document names the branch and commit explicitly.

How long should a handoff link live?

Match the expiry to the task: 1 day for a same-day session switch, 7 days for a task that waits on a teammate. Use "never" only for handoffs you will link from a README or an issue for the long term. The link is public to anyone who has it.