Die Session, die einen Bug auslieferte, und der Retro, der 'smooth' sagte
Claude Code lieferte in einem echten Repo einen Nummerierungsfehler aus, und vier freigegebene Änderungen machten es unmöglich, ihn noch einmal auszuliefern. Die Session schrieb Gutschriften für eine kleine Rechnungs-API, die Testsuite kam grün zurück, und ein anschließend von Hand ausgeführter Check zeigte, dass eine abgelehnte Anfrage eine Gutschriftsnummer verbrannt hatte. Dann ließen wir einen Retro über diese Session laufen, gaben die Fixes einzeln frei und führten dieselbe Aufgabe erneut aus: Sie kam sauber zurück.
Ein Retro ist die Auswertung, die ein Team nach einem Vorfall hält, hier auf dem Session-Log von Claude Code selbst. Unser erster Retro begann mit "This session was smooth", und keiner seiner Funde war der Bug. Die Lösung sind sieben Schritte, in dieser Reihenfolge: installieren, die Aufgabe laufen lassen, den Retro starten und ihm sagen, was schiefging, jeden Kandidaten zurückverfolgen, jeden Überlebenden in einen Träger freigeben, committen und prüfen, und die Aufgabe erneut laufen lassen.
Was ein Retro ist, und /retro installieren
/retro ist ein Skill von Matt Pocock, der eine Coding-Session prüft statt deines Codes. Er liest das Session-Log, die Datei, in der Claude Code jeden Prompt und jeden Tool-Aufruf festhält, und sucht in sieben Kategorien nach Kandidaten, zum Beispiel nach einem Check, der einen Fehler hätte fangen können. Er präsentiert sie nach Schweregrad und schlägt laut seiner Doku nur vor: Nichts ändert sich, bis du einen Kandidaten auswählst.
Die Installation ist der erste Schritt: Aktualisiere in deinem Repo den offiziellen Marketplace und installiere dann das Skills-Pack im Project Scope, damit es nur in diesem Repo lebt. Unser Marketplace hing auf einem älteren Release ohne den Retro, deshalb kam das Update zuerst. Tippe in einer neuen Session einen Schrägstrich, und der Retro-Befehl steht in der Liste.
Eine Einschränkung: Eine Cloud-Session kann die Logs auf deinem Rechner nicht lesen, also führe den Retro dort aus, wo die Session stattgefunden hat.
Aufgabe laufen lassen: Unsere Session lieferte den Bug
Der zweite Schritt ist der, den du ohnehin jeden Tag machst: Tippe deine echte Aufgabe in eine normale Session, lass sie durchlaufen und halte die Session offen, denn genau das liest der Retro.
Wir nutzten eine kleine Rechnungs-API in Node und TypeScript, mit eigener Testsuite und ohne Anweisungsdatei, ohne Pipeline und ohne Commit-Hook. Die Aufgabe war kurz, so wie du sie selbst tippen würdest: Gutschriften zu bezahlten Rechnungen hinzufügen, fortlaufend nummeriert, und eine bezahlte Rechnung stornierbar machen, indem der Restbetrag gutgeschrieben wird.
Die Session schrieb die Route, eine Migration und ihre eigenen Tests und ließ die Suite laufen, bevor sie stoppte. Dann führten wir den Check aus, den die Finanzabteilung von Hand machen würde, einen vorher geschriebenen versteckten Test, und eine Anforderung schlug fehl.
| Signal | Ergebnis |
|---|---|
| Testsuite | 42 Tests bestanden |
| Type-Check | sauber |
| Versteckter Finanz-Check | fehlgeschlagen: eine spätere Gutschriftsnummer als erwartet |
Die Ursache: Der Handler nimmt die nächste Nummer vom Zähler, bevor er die Anfrage validiert, und der Zähler wird in dem Moment gespeichert, in dem er gelesen wird. Eine zu große Gutschrift wird abgelehnt, was richtig ist, und die Nummer ist trotzdem weg, was nicht richtig ist. Die Session kopierte diese Reihenfolge von der bestehenden Issue-Route, die Rechnungsnummern auf dieselbe Weise verliert.
Wir führten die Aufgabe zweimal aus, und der andere Lauf kam sauber zurück, also ist das, was eine normale Session manchmal tut.
/retro starten, dann sagen, was schiefging
Der dritte Schritt ist, den Retro-Befehl in genau dieser Session zu tippen und ihn dann noch einmal auszuführen, mit dem Fehler dahinter geschrieben. Unserer begann mit: "This session was smooth."
Er reihte eine Handvoll Punkte, keiner davon der Bug: ein fehlendes Guardrail, eine Migrationsregel, die niemand prüft, und nichts, was ein Reviewer durchsetzen könnte. Der Retro liest das Session-Log, und die Session hatte nie erfahren, dass sie gescheitert war.
Also sagst du es ihm: Führe den Befehl erneut aus, mit dem Fehler als Argument, dem Text hinter dem Befehl. Unserer sagte, dass die Finanzabteilung den Build getestet hatte, dass eine zu große Gutschrift abgelehnt wurde, dass die nächste gültige Gutschrift zu spät herauskam und dass der Retro nichts beheben sollte.
Diesmal fand er die Ursache in seinem eigenen Code: Er nimmt zuerst die Nummer und validiert danach, und er sagte, er habe die Reihenfolge vom bestehenden Issue-Handler kopiert. Neue Kandidaten folgten: ein von ihm geschriebener Test, der die fehlschlagende Abfolge durchlief, aber nur Statuscodes prüfte, eine Zähler-Funktion, die rein aussieht und es nicht ist, und eine Konvention, die niemand aufgeschrieben hat.
Alles, was du nach der Session herausfindest, tippe ins Argument, sonst prüft der Retro eine Session, die er für gelungen hält.
Jeden Kandidaten vor der Freigabe einem Moment zuordnen
Der vierte Schritt ist der, den der Skill nicht von selbst macht: Bitte den Retro, den Moment des Transcripts zu zitieren, der hinter jedem Kandidaten steckt, und streiche jeden Kandidaten, den er nicht belegen kann.
Die Doku erklärt, warum eine gereihte Liste nicht genügt: Sobald eine Aufgabe erledigt ist, vergisst das Modell die Schwierigkeiten der Session und erfindet generische Ratschläge. Verwirf also jeden Kandidaten, den du nicht einem konkreten Moment zuordnen kannst: ein Satz, der den Retro bittet, das Transcript für jeden zu zitieren.
Beim ersten Retro fiel die Antwort deutlich aus: Die meisten Kandidaten hatten im Transcript keinen Beleg. Er behielt das fehlende Guardrail, weil seine eigene Auflistung des Hooks-Ordners nichts ausgegeben hatte, und strich den Migrations-Check als hypothetisch.
Beim zweiten Retro, dem, der vom Bug wusste, behielt der Trace vier Kandidaten und strich einen.
| Kandidat | Nach dem Trace |
|---|---|
| Der von ihm geschriebene Test (akzeptiert, abgelehnt, akzeptiert, Nummer nie geprüft) | behalten, fest |
| Die Zähler-Funktion ohne Warnung | behalten, fest |
| Die ungeschriebene Konvention | behalten, schwächer |
| Das fehlende Guardrail | behalten, auch wenn er sagte, ein Guardrail hätte diesen Bug nicht gefangen |
| Der letzte Kandidat | gestrichen: Er zählte denselben Moment doppelt |
Ein offenes Issue im Repo des Skills zählt die meisten Retro-Läufe, auf die ein Nutzer mit der Bitte um einen Beweis folgt. Ein belegter Kandidat ist weiterhin das Modell, das sein eigenes Log liest, also ist eine als schwächer markierte Zeile ein Urteil, und du entscheidest, welche du mitnimmst.
Jeden Überlebenden in seinen Träger freigeben
Der fünfte Schritt ist der, in dem sich die Schleife auszahlt: Gib einen Überlebenden nach dem anderen frei, jeden in seinen Träger, den Ort, an dem die Regel leben wird. Der Skill gibt dir die Leiter. Ein mechanischer Verstoß bekommt einen deterministischen Check, Punkt: eine Regel in deinem Linter, ein Commit-Hook oder ein Job in deiner Pipeline. Eine Ermessensfrage kommt in eine Coding-Standards-Datei, die der Reviewer liest. Deine Anweisungsdatei wird, in den Worten der Doku, "incredibly sparingly" verwendet, für Verweise auf andere Dateien.
Wir gaben vier Änderungen frei:
- Das fehlende Guardrail wurde ein versionierter Commit-Hook, der Type-Check und Tests laufen lässt und den Commit blockiert, wenn einer von beiden fehlschlägt. Das Harness weigerte sich, die Datei ausführbar zu machen, also führten wir diesen Befehl selbst aus.
- Der Test wurde ein
vitest-Test, der die Regel festnagelt: Eine Gutschrift wird akzeptiert, eine Gutschrift wird abgelehnt, und die nächste gültige muss die nächste Nummer tragen. Er schlug im ersten Lauf fehl, und das ist der Punkt: Er fing den Bug, den die Session ausgeliefert hatte. - Die Ermessensfrage wurde eine Zeile in einer neuen
CODING_STANDARDS.md: Nimm eine Sequenznummer erst, wenn alle Validierungen bestanden sind, damit eine abgelehnte Anfrage die Sequenz lückenlos lässt. - Die Navigationslücke wurde ein Kommentar über der Zähler-Funktion: Sie speichert den Zähler sofort, die Nummer ist also verbraucht, selbst wenn der Aufrufer danach scheitert, also rufe sie erst nach der Validierung auf.
Das sind vier geänderte Dateien und null Zeilen in CLAUDE.md, weil beide Retros es ablehnten, eine zu schreiben. Der erste sagte, ein Verweis in der Steering-Datei koste bei jedem Turn Kontext und veralte; der zweite sagte, man solle es als Kommentar an der Funktion behalten. Die Doku stützt das: Claude behandelt diese Dateien als Kontext, nicht als erzwungene Konfiguration, und um eine Aktion zu blockieren, nutzt man einen Hook.
Zwei Einschränkungen: Ein Hook schützt nur Commits, und der Kommentar ist, in den Worten des Retros selbst, eine Wette auf den nächsten Aufrufer, kein bewiesener Fix.
Schleife schließen: Hook blockt den Commit, Audit, Commit, Re-Run
Der sechste Schritt ist der Commit, und der letzte ist, dieselbe Aufgabe noch einmal laufen zu lassen, denn dabei zeigt sich, ob die Schleife gehalten hat.
Als wir die freigegebenen Dateien stagten und committeten, lief zuerst der Hook und lehnte den Commit ab. Der Type-Check bestand, dann schlug der neue Nummerierungstest fehl und bekam eine spätere Nummer als erwartet. Der Hook prüft die Dateien so, wie sie auf der Platte liegen, und auf der Platte lag noch der fehlerhafte Code.
Also gehst du zurück in die Session und bittest nur um den Fix: die Nummer nehmen, nachdem die Validierung bestanden ist, die Checks laufen lassen, nicht committen. Dann committest du erneut, der Hook läuft grün, und du bekommst zwei Commits: die Retro-Änderungen, dann das Feature mit seinem Fix. Der Retro selbst committete nichts, was ein offenes Issue im Repo Wort für Wort beschreibt, also committest du.
Als Nächstes führst du /doctor prompt-audit aus, die eigene Prüfung von Claude Code für deine Anweisungsdateien auf veraltete Zeilen. Hier steckt eine Falle: Ohne Pfad prüft er deine globalen Dateien, nicht das Repo. Mit dem Pfad nannte er die neue Standards-Datei sauber und wies darauf hin, dass die ältere Issue-Route die Regel verletzt, ein Code-Bug und kein Prompt-Problem.
Der letzte Schritt ist eine frische Session mit derselben Aufgabe. Unsere las die Coding-Standards-Datei, das Readme, den Hook und den roten Nummerierungstest, bevor sie Code schrieb, und schrieb dann in ihrer eigenen Zusammenfassung, dass die Nummer erst genommen wird, nachdem alle diese Checks bestanden sind, sodass eine abgelehnte Anfrage keine Lücke in der Sequenz hinterlässt.
| Erste Session | Frische Session nach der Schleife | |
|---|---|---|
| Tests bestanden | 42 | grün |
| Versteckter Finanz-Check | fehlgeschlagen | 5 von 5 |
| Nummern nach einer abgelehnten Anfrage | verbrannt, eine Lücke | lückenlos |
Ein ehrlicher Vorbehalt: Diese frische Session bekam die Lehre als roten Test und eine Standards-Zeile mitgegeben, es ist also ein Lauf nach der Schleife, kein Benchmark.
Fazit: wann ein Retro, wann nicht, die eine Regel
Der Retro liest die Session, also schreibst du ins Argument, was die Session nicht gesehen hat. Das ist der Teil, an dem du stolpern wirst.
Starte einen Retro nach einer Session, die schiefgegangen ist, bevor du sie leerst, oder auf dem Log der alten Session. Lass ihn nicht im Autopiloten laufen und häng ihn nicht an einen Hook: Der Autor des Skills sagt es mit eigenen Worten, du willst das nicht automatisieren. Die Doku fügt eine Grenze hinzu: Er prüft nicht die Checks, die er letzten Monat vorgeschlagen hat, also mistest du die weiterhin selbst aus.
Die eine Regel, die du dir merken solltest, ist der Satz der Doku selbst: Behandle deine Anweisungsdatei wie Code, überprüfe sie, wenn etwas schiefgeht, miste sie regelmäßig aus und teste Änderungen, indem du beobachtest, ob sich Claudes Verhalten tatsächlich ändert. Die Schleife macht den Agenten nicht richtig, sie lässt denselben Fehler schneller auffallen, und die Checks, die du hinzufügst, sind Code, den du jetzt pflegst.
Das kostenlose Pack zu diesem Video enthält die Retro-Checkliste mit jedem Schritt, die Trace-Frage und die Träger, dazu das Commit-Hook-Skript und den Nummerierungstest aus unserem Lauf, damit du mit unserem anfangen kannst.
AIDive