---
name: session-handoff
description: Compacts a long working session into a handoff document that lets a fresh agent or a teammate resume the work with no lost context — state, decisions, open threads, exact commands and next steps. Use when context is getting long, before switching agents or models, at the end of a work session, or when the user asks to "hand this off", "save progress" or "write a summary for tomorrow".
license: MIT
compatibility: Any project. Writes a markdown file; git optional for capturing branch and diff state.
metadata:
  category: productivity
  version: "1.0.0"
---

# Session Handoff

A handoff is judged by one test: can someone with zero memory of this conversation pick up in under five minutes and not repeat a mistake we already made? Write for that reader.

## When to trigger

- Context window is more than about two-thirds used, or the conversation has been running for more than an hour of edits.
- You are about to switch tools, models or people.
- Work is being paused for the day, or a blocking question was sent to a human.
- The user asks for a summary, status or handoff.

## Step 1 — Capture ground truth, not memory

Run these and paste the relevant output into the handoff rather than paraphrasing from memory:

```bash
git status --short
git branch --show-current
git log --oneline origin/main..HEAD
git diff --stat
# the project's test command, e.g.
pnpm test 2>&1 | tail -20
```

Also list any files you created outside git (scratch scripts, notes, downloaded data) with their paths.

## Step 2 — Write the document

Save to `docs/handoffs/<yyyy-mm-dd>-<topic>.md` (or `HANDOFF.md` at the repo root if the project has no docs folder). Keep it under one screen where possible; link to files instead of quoting them.

```
# Handoff — <topic> — <date>

## Goal (1–2 sentences)
What we are trying to achieve and how we will know it is done.

## Current state
- Branch: feat/invoice-status (3 commits ahead of main)
- Tests: 44 pass, 2 fail (invoice.test.ts: "rejects refund after 30 days" — expected, not yet implemented)
- Uncommitted: src/invoices/repo.ts (half-done setStatus)

## Done
- Bullet list of completed steps with commit hashes.

## Decisions made (and why)
- Chose check constraint over Postgres enum because migrations rename badly. (user agreed)
- Rejected: storing status in JSONB — not indexable.

## Things that did not work — do not retry
- `prisma migrate dev` fails on CI because shadow DB is missing; use `prisma migrate deploy` there.
- The mock for `sendEmail` must be reset between tests or the second test sees two calls.

## Open questions / blockers
- Waiting on @user: should partial refunds be allowed? (asked 14:20)

## Next steps (ordered, each verifiable)
1. Finish `setStatus` in repo.ts; verify with `pnpm test src/invoices`.
2. Wire the Server Action in app/invoices/actions.ts; verify by submitting the form.
3. ...

## How to run
- Setup: `pnpm i && cp .env.example .env && pnpm db:migrate`
- Tests: `pnpm test`
- Dev: `pnpm dev` → http://localhost:3000/invoices

## Key files
- src/invoices/repo.ts — data access
- docs/specs/2026-09-01-invoice-status.md — spec
```

## Step 3 — Prune the conversation's noise

Do **not** include: the full narrative of what you tried in order, long code pastes, tool output that is reproducible by running a command, or opinions without a decision. If a detail matters only if a specific failure recurs, put it under "did not work" as one line.

## Step 4 — Verify the handoff

- [ ] Every "next step" names a file and a verification command.
- [ ] Every decision has a reason; every rejected option is listed once.
- [ ] The test and git state is pasted, not described.
- [ ] Open questions name who is expected to answer.
- [ ] A new reader needs no other document to start (or the links are present).
- [ ] Secrets, tokens and personal data are not in the file.

Then commit the handoff file (or tell the user where it is) and, if the session continues, keep working from the handoff rather than from memory — it is now the source of truth.

## Resuming from a handoff

When starting a session with a handoff present: read it first, re-run the "How to run" and test commands to confirm the state still matches, then begin at the first unfinished next step. If the state has drifted (new commits, failing tests), update the handoff before doing anything else.

## Pitfalls

- Summaries written from memory drift from reality; run the commands.
- "Refactor the auth module" is not a next step; "extract `verifySession` from middleware.ts into lib/auth.ts, verify with `pnpm test lib/auth`" is.
- Listing every file touched is noise; list the files the next person must open.
- Do not bury the blocker at the bottom; if work is blocked, say so in the first section.
- A handoff that is longer than the work remaining is a sign to cut it down.
