AI News · Tools
Matt Pocock's /handoff:
testing a real handover.
DE Auf Deutsch lesen
/handoff is meant to pack a Claude Code session into a document that another
session or agent can continue from. The obvious question: why isn't the built-in
/compact enough for that? Matt Pocock's own answer to that is further down.
To see what the skill actually delivers, I didn't make up an artificial task. I started on
real PlantWiz code, kept going until I hit a real blocker, and triggered
/handoff right there.
What the skill actually prescribes
/handoff is part of a larger collection of skills that Matt Pocock (known from
Total TypeScript) publishes under the name "Skills for Real Engineers." Installation runs
via npx skills add mattpocock/skills --skill handoff or by copying it to
.claude/skills/handoff/. One single setting in the skill file's frontmatter
stands out: disable-model-invocation: true. Unlike Ponytail from an
earlier post, which automatically kicks
in on every coding task, /handoff never loads itself. It has to be invoked
explicitly, either via the slash command or a phrase like "handoff this conversation."
The actual instruction to the agent boils down to five rules:
- Purpose: summarize the ongoing conversation so a fresh session can continue the work.
- Location: the document belongs in the operating system's temp directory, explicitly not in the project's working directory.
- Mandatory section: a list of recommended skills the next session should invoke.
- No duplicates: content that already lives in specs, plans, ADRs, issues, commits or diffs gets referenced by path or URL, not copied.
- Redaction: API keys, passwords and personal data must be removed from the document.
If the skill is called with an argument, for example /handoff finish the FCM
integration, the document is meant to be tailored to that focus instead of being a
general log.
Why not just use /compact?
Claude Code has had a built-in tool that summarizes context for a long time now:
/compact. The obvious question, then, is why /handoff is needed at
all. Matt Pocock's own reasoning, in a
deep dive on his skill,
names the problem precisely: /compact works within the same
session. It pulls you out of the "Dumb Zone," the quality loss that comes with a
full context, back into the "Smart Zone," but in doing so it overwrites the work done so far
and stays trapped in the same thread.
His concrete scenario: you spot a task mid-session that doesn't actually belong there, "you
spot an out-of-scope task mid-session." That leaves only two bad options. Either dilute the
running session with unrelated context, or compact it and risk losing details from the
actual work. /handoff solves this by extracting only the relevant slice of
context into its own file and handing it to a new session, while the
current one stays "pure and focused," running on untouched.
By his own account, Pocock uses the skill mainly in "grilling sessions," structured planning conversations with the agent. When he notices partway through that some sub-aspect actually "belongs in a different session," he writes a handoff for it instead of interrupting or diluting the ongoing planning.
In short: /compact makes room within the same session.
/handoff is the deliberate point where you branch off instead of continuing.
That matches what's in the skill file itself: disable-model-invocation: true
means nobody branches off by accident. It's a decision someone makes explicitly, not an
automatic reflex triggered by an approaching context limit.
The test case: a real blocker, not a made-up one
PlantWiz has recently started storing push tokens (push_tokens table,
POST /api/push-tokens), and garden to-dos have existed for a long time. What's
missing: the connection between the two. No code queries due to-dos, no library for sending
is installed, no cron job exists. That's exactly the gap I started closing.
Claude built getDueReminders(), under my direction: a SQL query across three
tables (todos → garden_members → push_tokens) that
groups open, due to-dos by registered push token, plus three tests in the same mock style as
the existing test suite, all green. Then came the blocker: sendPush() needs a
Firebase service account key for Android and an APNs certificate for iOS. Neither exists in
this project, and that isn't something an agent can invent or obtain; I had to get it myself.
Not a technical problem but a missing credential, and at that point an honest, unavoidable
handoff point.
| Session result | Value |
|---|---|
| New files | 2 (service + test), no existing file changed |
| Lines | 106 |
| Characters (diff) | 3,666 |
| Tests | 3 of 3 green (npx vitest run) |
| Reason for the stop | missing FCM/APNs credential, not a code problem |
The handoff document
At this point I triggered /handoff, with the argument "finish the FCM
integration," and followed the five rules above to the letter. The result landed, as
prescribed, in the OS temp directory, not in the project: a standalone Markdown file with
six sections. The full document is available here, unchanged, for reference.
Handoff document vs. the actual diff
Same session, measured in characters. No compression miracle at this task size.
2,956 characters, roughly 740 tokens, against 3,666 characters of diff, that's only about
19% less. At a task of this size, /handoff isn't a compression tool, and it
arguably shouldn't have to be one here: a diff can be regenerated any time with
git diff, so it doesn't need a session summary for that. The real value lies in
what's not in the diff at all: why sendPush() is only a stub, which three
existing files served as patterns, and that explicitly nothing had to be redacted because
nothing sensitive came up. For a real, hours-long session with many files read and dead
ends, the gap to the diff is likely to be much larger, because there's far more context
there that isn't in the diff but also isn't needed anymore.
What was in it
- Purpose and status: a brief framing of what's done and what the next session should concretely do.
- Four open items, numbered, with the blocker named and explained first, not just as a keyword.
- References instead of copies:
pushTokens.ts:8,usePushNotifications.ts, the to-do table ininit.sql, the test mock style fromtodos.test.ts, each as a path, not inserted code. - An explicit redaction note: no secrets seen or needed, the blocker is the absence of a credential, not an existing value.
- Suggested skills: none needed for the FCM integration itself, but
/code-reviewbefore merging, with a concrete pointer for what the review should watch for (the query runs unfiltered across all gardens).
What wasn't in it, and why that stands out
Before deciding on push reminders, I had briefly read LAUNCH-TODO.md, an actual
file with pre-launch tasks, and discarded it again because it contains operational tasks
more than code. That dead end doesn't show up in the handoff document, and that's the right
call: it was irrelevant to the next session. But that's exactly where the skill's limit
shows. It doesn't objectively record what happened; it lets the current agent decide what
mattered. For a short session like this one, that's not a problem. For a long session with
many dead ends, the same agent already deep in the task is the one deciding whether a dead
end can be considered irrelevant. No second pair of eyes checks that.
Direct comparison to the obvious alternatives
| /handoff | Claude Code's auto-compaction | TODO comment in code | |
|---|---|---|---|
| Trigger | manual, via slash command or phrase | automatic at the context limit | manual, written by a human |
| Goal | targeted handover to a specific next session | keep the same session working | a note in the code itself |
| Includes blocker reasoning | yes, as its own section | not specifically, only what was already in context | only as much as gets written in |
| References instead of duplicating | yes, by design | no, compresses the entire history | no, isolated one-liner |
| Works across agents | yes, the document is plain text | no, tied to the specific session | yes, but without context on the "why" |
When it's worth it
Real blocker or role change
A missing credential, a switch from planning to implementation, a jump between agents (say, planning in Claude Code, implementing in Codex). Exactly the case from this test.
Short, self-contained task
Skip /handoff. Because of disable-model-invocation: true
that happens anyway unless it's explicitly invoked, but it also doesn't pay off
content-wise: a finished diff doesn't need a handover.
Long session, same person continues
Claude Code's built-in compaction is usually enough, because no role change
happens. /handoff brings no extra benefit there over the built-in
function.
/handoff barely compressed anything,
but it did capture information that isn't in the diff. The redaction rule wasn't tested
under real conditions, and the choice of what makes it into the document remains at the
discretion of the same agent that just did the work.
Choosing skills for your team?
I set up Claude Code in developer teams, including the question of which skills actually pay off and which just cost tokens. 30-minute intro call, free of charge.