KI-News · Werkzeuge
/handoff von Matt Pocock:
eine echte Übergabe getestet.
EN Read in English
/handoff soll eine Claude-Code-Session in ein Dokument packen, mit dem eine
andere Session oder ein anderer Agent weiterarbeiten kann. Naheliegende Frage: Warum reicht
dafür nicht das eingebaute /compact? Matt Pococks eigene Antwort darauf steht
weiter unten. Um zu sehen, was der Skill in der Praxis liefert, habe ich mir keine
künstliche Aufgabe ausgedacht, sondern an echtem PlantWiz-Code angefangen, bis eine echte
Blockade kam, und dann genau dort /handoff ausgelöst.
Was der Skill genau vorschreibt
/handoff ist Teil einer größeren Sammlung von Skills, die Matt Pocock (bekannt
aus Total TypeScript) unter dem Namen „Skills for Real Engineers“ veröffentlicht. Die
Installation läuft über npx skills add mattpocock/skills --skill handoff oder
durch Kopieren nach .claude/skills/handoff/. Bemerkenswert ist eine einzelne
Einstellung im Frontmatter der Skill-Datei: disable-model-invocation: true.
Anders als Ponytail aus einem früheren
Beitrag, das sich bei jeder Codeaufgabe automatisch dazuschaltet, lädt sich
/handoff nie von selbst. Es muss explizit aufgerufen werden, entweder über den
Slash-Befehl oder eine Formulierung wie „handoff this conversation“.
Die eigentliche Anweisung an den Agenten lässt sich auf fünf Regeln zusammenfassen:
- Zweck: die laufende Konversation so zusammenfassen, dass eine frische Session die Arbeit fortsetzen kann.
- Speicherort: das Dokument gehört ins temporäre Verzeichnis des Betriebssystems, ausdrücklich nicht ins Arbeitsverzeichnis des Projekts.
- Pflichtabschnitt: eine Liste empfohlener Skills, die die nächste Session aufrufen sollte.
- Keine Duplikate: Inhalte, die bereits in Specs, Plänen, ADRs, Issues, Commits oder Diffs stehen, werden per Pfad oder URL referenziert, nicht kopiert.
- Redaction: API-Keys, Passwörter und personenbezogene Daten müssen aus dem Dokument entfernt werden.
Wird der Skill mit einem Argument aufgerufen, etwa /handoff FCM-Integration
fertigstellen, soll das Dokument gezielt auf diesen Fokus zugeschnitten werden statt
ein allgemeines Protokoll zu sein.
Warum nicht einfach /compact?
Claude Code hat mit /compact längst ein eingebautes Werkzeug, das den Kontext
zusammenfasst. Die naheliegende Frage ist also, wozu es /handoff überhaupt
braucht. Matt Pococks eigene Begründung, in einem
Deep-Dive zu seinem Skill,
benennt das Problem genau: /compact wirkt innerhalb derselben Session. Es
holt einen aus der „Dumb Zone“, dem Qualitätsverlust bei vollem Kontext, zurück in die „Smart
Zone“, überschreibt dabei aber den bisherigen bearbeiteten Stand und bleibt im selben Thread
gefangen.
Sein konkretes Szenario: Man erkennt mitten in einer Session eine Aufgabe, die dort eigentlich
nicht hingehört, „you spot an out-of-scope task mid-session“. Dann bleiben nur zwei schlechte
Optionen. Entweder die laufende Session mit fachfremdem Kontext verwässern, oder kompaktieren
und damit riskieren, dass Details aus der eigentlichen Arbeit verloren gehen. /handoff
löst das, indem nur die relevante Kontextscheibe in eine eigene Datei extrahiert und an eine
neue Session übergeben wird, während die aktuelle „pure and focused“ bleibt,
unangetastet weiterläuft.
Pocock setzt den Skill nach eigener Aussage vor allem in „Grilling-Sessions“ ein, strukturierten Planungsgesprächen mit dem Agenten. Erkennt er dort mittendrin, dass ein Teilaspekt eigentlich in eine andere Session gehört, „belongs in a different session“, schreibt er dafür einen Handoff statt die laufende Planung zu unterbrechen oder zu verwässern.
Kurz zusammengefasst: /compact schafft Platz in derselben Session.
/handoff ist der bewusste Punkt, an dem man verzweigt, statt weiterzumachen. Das
deckt sich mit dem, was in der Skill-Datei selbst steht: disable-model-invocation:
true bedeutet, dass niemand versehentlich verzweigt. Es ist eine Entscheidung, die
jemand explizit trifft, kein automatischer Reflex wie bei drohendem Kontextlimit.
Der Testfall: eine echte Blockade, keine erfundene
PlantWiz speichert Push-Tokens seit Kurzem (push_tokens-Tabelle,
POST /api/push-tokens), und Garten-Todos existieren schon lange. Was fehlt: die
Verbindung dazwischen. Kein Code fragt fällige Todos ab, keine Bibliothek für den Versand ist
installiert, kein Cron-Job existiert. Genau diese Lücke habe ich angefangen zu schließen.
Gebaut hat Claude, unter meiner Anleitung, getDueReminders(): eine SQL-Abfrage
über drei Tabellen (todos → garden_members → push_tokens),
die offene, fällige Todos je registriertem Push-Token gruppiert, plus drei Tests im selben
Mock-Stil wie die bestehende Testsuite, alle grün. Dann kam die Blockade: sendPush()
braucht einen Firebase-Service-Account-Schlüssel für Android und ein APNs-Zertifikat für iOS.
Beides existiert nicht in diesem Projekt, und das kann kein Agent sich ausdenken oder
beschaffen, das musste ich selbst besorgen. Kein technisches Problem, sondern ein fehlendes
Credential, an dieser Stelle also ein ehrlicher, unvermeidbarer Übergabepunkt.
| Ergebnis der Session | Wert |
|---|---|
| Neue Dateien | 2 (Service + Test), keine bestehende Datei verändert |
| Zeilen | 106 |
| Zeichen (Diff) | 3.666 |
| Tests | 3 von 3 grün (npx vitest run) |
| Grund für den Stopp | fehlendes FCM-/APNs-Credential, kein Codeproblem |
Das Handoff-Dokument
An dieser Stelle habe ich /handoff ausgelöst, mit dem Argument „FCM-Integration
fertigstellen“, und die fünf Regeln oben wörtlich befolgt. Das Ergebnis landete, wie
vorgeschrieben, im OS-Temp-Verzeichnis, nicht im Projekt: eine eigenständige Markdown-Datei
mit sechs Abschnitten. Das vollständige Dokument liegt hier unverändert zum Nachlesen.
Handoff-Dokument gegen den eigentlichen Diff
Gleiche Session, gemessen in Zeichen. Kein Kompressionswunder bei dieser Aufgabengröße.
2.956 Zeichen, grob 740 Tokens, gegen 3.666 Zeichen Diff, das sind nur rund 19 % weniger.
Bei einer Aufgabe dieser Größe ist /handoff kein Kompressionswerkzeug, und das
sollte es an dieser Stelle auch nicht sein müssen: Ein Diff lässt sich mit
git diff jederzeit neu erzeugen, dafür braucht es keine Session-Zusammenfassung.
Der eigentliche Wert liegt in dem, was im Diff gar nicht steht: warum
sendPush() nur ein Stub ist, welche drei Dateien im bestehenden Code als Muster
dienten, und dass explizit nichts geschwärzt werden musste, weil nichts Sensibles anfiel. Bei
einer echten, stundenlangen Session mit vielen gelesenen Dateien und Sackgassen dürfte der
Abstand zum Diff deutlich größer ausfallen, weil dort viel mehr Kontext existiert, der nicht
im Diff steht, aber auch nicht mehr gebraucht wird.
Was drin war
- Zweck und Stand: eine knappe Einordnung, was fertig ist und was die nächste Session konkret erledigen soll.
- Vier offene Punkte, nummeriert, der Blocker zuerst benannt und begründet, nicht nur als Stichwort.
- Referenzen statt Kopien:
pushTokens.ts:8,usePushNotifications.ts, die Todo-Tabelle ininit.sql, der Test-Mock-Stil austodos.test.ts, jeweils als Pfad, nicht als eingefügter Code. - Ein expliziter Redaction-Hinweis: keine Secrets gesehen oder gebraucht, der Blocker ist das Fehlen eines Credentials, nicht ein vorhandener Wert.
- Vorgeschlagene Skills: keiner für die FCM-Anbindung selbst nötig, aber
/code-reviewvor dem Merge, mit einem konkreten Hinweis, worauf der Review achten sollte (die Abfrage läuft ungefiltert über alle Gärten).
Was nicht drin war, und warum das auffällt
Vor der Entscheidung für die Push-Erinnerungen hatte ich kurz LAUNCH-TODO.md
gelesen, eine echte Datei mit Vor-Launch-Aufgaben, und sie wieder verworfen, weil sie eher
Betriebsaufgaben als Code enthält. Diese Sackgasse taucht im Handoff-Dokument nicht auf, und
das ist richtig so: Sie war für die nächste Session irrelevant. Aber genau daran zeigt sich
die Grenze des Skills. Er schreibt nicht objektiv mit, was passiert ist, er lässt den
aktuellen Agenten entscheiden, was wichtig war. Bei einer kurzen Session wie dieser ist das
unproblematisch. Bei einer langen Session mit vielen Sackgassen entscheidet derselbe Agent,
der schon mitten in der Aufgabe steckt, ob er die Sackgasse für irrelevant halten darf. Ein
zweites Augenpaar prüft das nicht.
Direkter Vergleich zu den naheliegenden Alternativen
| /handoff | Claude Codes Auto-Kompaktierung | TODO-Kommentar im Code | |
|---|---|---|---|
| Auslösung | manuell, per Slash-Befehl oder Formulierung | automatisch bei Kontextlimit | manuell, vom Menschen geschrieben |
| Ziel | gezielte Übergabe an eine bestimmte nächste Session | dieselbe Session lauffähig halten | Hinweis im Code selbst |
| Enthält Blocker-Begründung | ja, als eigener Abschnitt | nicht gezielt, nur was ohnehin im Kontext stand | nur so viel, wie hineingeschrieben wird |
| Referenziert statt dupliziert | ja, laut Vorgabe | nein, komprimiert den gesamten Verlauf | nein, isolierter Einzeiler |
| Funktioniert Agent-übergreifend | ja, das Dokument ist reiner Text | nein, an die jeweilige Session gebunden | ja, aber ohne Kontext zum „Warum“ |
Wann sich das lohnt
Echte Blockade oder Rollenwechsel
Ein fehlendes Credential, ein Wechsel von Planung zu Umsetzung, ein Sprung zwischen Agenten (etwa planen in Claude Code, umsetzen in Codex). Genau der Fall aus diesem Test.
Kurze, in sich abgeschlossene Aufgabe
/handoff weglassen. Wegen disable-model-invocation: true
passiert das ohnehin nur, wenn es explizit aufgerufen wird, aber es lohnt sich auch
inhaltlich nicht: Ein abgeschlossener Diff braucht keine Übergabe.
Lange Session, dieselbe Person macht weiter
Claude Codes eingebaute Kompaktierung reicht meist aus, weil kein Rollenwechsel
stattfindet. /handoff bringt dort keinen Zusatznutzen gegenüber der
eingebauten Funktion.
/handoff kaum komprimiert, dafür Informationen festgehalten, die im Diff nicht
stehen. Die Redaction-Regel wurde nicht unter realen Bedingungen geprüft, und die Auswahl
dessen, was ins Dokument kommt, bleibt Ermessenssache desselben Agenten, der die Aufgabe
gerade bearbeitet hat.
Skills für Ihr Team auswählen?
Ich richte Claude Code in Entwicklerteams ein, inklusive der Frage, welche Skills wirklich etwas bringen und welche nur Tokens kosten. 30 Minuten Erstgespräch, kostenlos.