Writing the end-of-session handoff

SkillAI & models

How to write the end-of-session handoff — the residue of what this session could not fix. Activate when the user asks for a handoff, when a session is ending with a known failure still standing, or when you are about to call something "pre-existing", "unrelated" or "not mine". The load-bearing rule is that a handoff is what remains AFTER you fixed everything you could reach, never an alternative to fixing it.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Writing the end-of-session handoff skill

What this skill tells your AI

The instructions your AI receives, as published by alexandermattturner/agent-glovebox in .claude/skills/handoff/SKILL.md and read by ahel’s review.

The doctrine

Fix first, hand off the remainder. A handoff entry is a failure this session did not cause and could not fix on this branch. A failure your own diff caused is yours. A clean session writes nothing and says nothing — never "no handoff needed".

An intermittent test failure is not a handoff item. The ci-triage skill owns it, including the rule that hardware you lack is never an exit. Two flakes still hand back, one line each: one an OPEN PR already covers (name that PR), and one blocked by a credential you lack that stops you from committing a runnable reproduction at all (name the credential).

The four steps

  1. Fix what you can reach. Work every item on this branch until only the unreachable remain. Needing another PR is not a reason to defer — open it.
  2. Earn "pre-existing". Reproduce the failure on the unmodified base before you call it unrelated:
    umask 022 && git worktree add --detach /tmp/claude-worktrees/base origin/main
    
    Then run the exact failing command there and quote what it printed. A claim you did not run is a hypothesis, and it says so. Reproducing it on the base earns "pre-existing", never "not mine": a red base blocks every branch, so the fix rides the PR you already have open. Merge origin/main into your branch and run it again before you hand anything back — a failure only that merge produces is yours however green both sides are alone.
  3. Deduplicate. Search issues and pull requests, because a multi-PR effort is tracked by an issue that no PR search finds:
    • mcp__github__search_issues and mcp__github__search_pull_requests, both with owner/repo and fields: ["number","state","title"].
    • gh pr list --search is GraphQL and answers 403 in a web session, so the MCP tools are the only route that works on both surfaces.
    • An OPEN tracking issue owns the item: add your row by EDITING that issue, and file no second one.
    • Read the PR state: OPEN gets one line naming it and no fresh investigation; MERGED means main already carries the fix, so drop the item; CLOSED covers nothing, so the item stands.
  4. Paste it in chat, in full. Never a bare file path: on the host the reader has no shell to open one, and inside the sandbox /tmp dies at teardown. Commit a copy only when it is worth keeping.

The shape

Lead with one line per item — what is broken, where, whether a PR already covers it. Then the handoff itself, written for a session that shares none of this one's context.

Write it self-contained: the next session cannot open a file you name. It starts in a fresh container, so a scratch file, a plan file and a worktree path are all gone, and a committed path it can read still costs it a turn to find. Carry the content in the prompt — the failing lines, the verdict text, the assertion, the command's output — and cite a path only beside that content. A committed path is a pointer for a reader who already has the substance, never a substitute for it.

  • the full path and the exact command,
  • the reproduction, and what it printed,
  • each claim labelled observed or hypothesised,
  • the PR or issue number that already covers it, when one does.

Size each handoff to one session

A handoff a session cannot finish comes back as another handoff, so estimate it before you write it. The bounds are the ones root CLAUDE.md's Delegation and Testing sections and the babysit-prs skill's dispatch band already set:

  1. Count the units. A unit is work one sub-agent finishes on its ~100k tokens with ONE verification command: a verb to home, a donor diff to take and rename, a check script to give a second arm, a test file to write. A row that flips with no code edit is not a unit.
  2. Find the width. The writing fleet caps at four agents and at half nproc, lower under load. On a 4-core host that is two units at once. A read-only agent spends no CPU and does not count against the width.
  3. Find the depth. Count the longest chain of units where each needs the one before it landed. No width shortens a chain.
  4. Count the CI rounds. Root CLAUDE.md § Testing bounds local testing per PR and per session, and each worktree agent provisions its own ~1 GB toolchain. A unit whose proof needs a live runner (a microVM shard, a KVM leg) is proved by a CI round instead, and rounds on one branch are serial: a push cancels the run before it.
  5. Cut at the seam. Start from about two fleet rounds of units (2 x width), a chain of about three, and about three CI rounds. No cap in the tree sources those three figures, so revise them against what this session observed. Past any of them, cut where the next unit needs the previous unit landed. Name that seam in both handoffs, and have the second cut its branch from the first's.

Write the unit count, the width you assumed, the seam, and which units are independent into the handoff. A handoff that does not say which units are independent is run serially, which is the schedule the estimate exists to prevent.

Inside the sandbox, add the guardrail friction you hit

_GLOVEBOX_PROTECTION_TIER set in the environment means you are in the microVM (glovebox never sets IS_SANDBOX). On the host, skip this half.

List only what you empirically ran into, one line each with the command and its observed output: a Bash-sandbox denial and its error text, a tool that exited 0 on a blocked read, a guardrail whose message did not name its remedy. Never speculate — an invented one sends someone to fix a boundary that works.

Not a handoff item

  • A rule you obeyed, a bug in the code under test, an edge you fixed.
  • Friction from this repo's own tooling that a small fix would remove — you fix that. An ## Also noticed line in chat carries what stayed unfixed, as a code location or reproducer and its consequence.
  • Anything you could still do in this session. Naming a piece of work is not delivering it.

Signals

GitHub stars
63
Forks
11
Last commit
Sep 2026
Hacker News mentions
20
Advanced
Catalog kind
skill
Gateway key
handoff-alexandermattturner
Source
github.com/alexandermattturner/agent-glovebox