La sessione che ha rilasciato un bug, e la retro che ha detto liscio
Claude Code ha rilasciato un bug di numerazione su un repo reale, e quattro modifiche approvate hanno reso impossibile rilasciarlo di nuovo. La sessione scriveva note di credito per una piccola API di fatturazione, la suite di test è tornata verde, e un controllo lanciato a mano in seguito ha scoperto che una richiesta rifiutata aveva bruciato un numero di fattura. Abbiamo poi fatto una retro su quella sessione, approvato le correzioni una per una e rilanciato lo stesso task: è uscito pulito.
Una retro è la revisione che un team tiene dopo un incidente, qui eseguita sul log di sessione di Claude Code stesso. La nostra prima retro si è aperta con "This session was smooth", e nessuno dei suoi risultati era il bug. La soluzione sono sette gesti, in ordine: installare, lanciare il task, lanciare la retro e dirle cosa è fallito, ricondurre ogni candidato a un momento, approvare ogni sopravvissuto nel suo carrier, fare commit e audit, e rilanciare il task.
Cos'è una retro, e installare /retro
/retro è una skill di Matt Pocock che rivede una sessione di codice invece del tuo codice. Legge il log di sessione, il file in cui Claude Code tiene ogni prompt e ogni chiamata a uno strumento, e cerca candidati in sette categorie, come un controllo che avrebbe potuto intercettare un errore. Li presenta per gravità e, secondo i suoi docs, si limita a proporre: nulla cambia finché non scegli un candidato.
Installarla è il primo gesto: nel tuo repo, aggiorna il marketplace ufficiale, poi installa il pack di skill a livello di progetto, così vive solo in questo repo. Il nostro marketplace era fermo a una release precedente senza la retro, quindi l'aggiornamento è venuto prima. In una nuova sessione, digita una barra e il comando retro è nell'elenco.
Un limite: una sessione cloud non può leggere i log sulla tua macchina, quindi lancia la retro dove è avvenuta la sessione.
Lancia il tuo task e lascialo finire: la nostra sessione ha rilasciato il bug
Il secondo gesto è quello che fai già ogni giorno: scrivi il tuo task vero in una sessione normale, lascialo finire e tieni aperta la sessione, perché è quello che la retro leggerà.
Abbiamo usato una piccola API di fatturazione in Node e TypeScript, con la sua suite di test e senza file di istruzioni, senza pipeline e senza hook di commit da nessuna parte. Il task era breve, come lo scriveresti tu: aggiungere le note di credito alle fatture pagate, numerate in sequenza, e permettere di annullare una fattura pagata accreditando ciò che resta.
La sessione ha scritto la route, una migrazione e i propri test, e ha lanciato la suite prima di fermarsi. Poi abbiamo lanciato il controllo che farebbe la finanza a mano, un test nascosto scritto in anticipo, e un requisito è fallito.
| Segnale | Risultato |
|---|---|
| Suite di test | 42 test passati |
| Type check | pulito |
| Controllo nascosto della finanza | fallito: numero di nota di credito successivo a quello atteso |
La causa: l'handler prende il numero successivo dal contatore prima di validare la richiesta, e il contatore viene salvato nel momento in cui è letto. Una nota di credito troppo grande viene rifiutata, ed è giusto, e il numero se n'è andato comunque, e questo non è giusto. La sessione ha copiato quell'ordine dalla route di emissione esistente, che perde numeri di fattura allo stesso modo.
Abbiamo lanciato il task due volte e l'altra esecuzione è uscita pulita, quindi questo è ciò che fa una sessione normale una parte delle volte.
Lancia /retro, poi dille cosa è fallito
Il terzo gesto è scrivere il comando retro in quella stessa sessione, poi rilanciarlo con il fallimento scritto dopo. La nostra è partita con: "This session was smooth."
Ha classificato una manciata di voci, nessuna era il bug: una protezione mancante, una regola di migrazione che nessuno controlla e niente che un revisore possa far rispettare. La retro legge il log di sessione, e la sessione non aveva mai saputo di aver fallito.
Quindi glielo dici tu: rilancia il comando con il fallimento come argomento, il testo dopo il comando. Il nostro diceva che la finanza aveva testato la build, che una nota di credito troppo grande veniva rifiutata, che la successiva valida usciva in ritardo, e che la retro non doveva correggere nulla.
Stavolta ha trovato la causa nel suo stesso codice: prende il numero per primo e valida per secondo, e ha detto di aver copiato l'ordine dall'handler di emissione esistente. Sono seguiti nuovi candidati: un test che aveva scritto, che eseguiva la sequenza fallimentare ma controllava solo i codici di stato, una funzione contatore che sembra pura e non lo è, e una convenzione che nessuno ha scritto.
Qualunque cosa tu abbia scoperto dopo la sessione, scrivila nell'argomento, altrimenti la retro fa l'audit di una sessione che crede sia andata bene.
Ricondurre ogni candidato a un momento prima di approvare
Il quarto gesto è quello che la skill non fa da sola: chiedi alla retro di citare il momento della trascrizione dietro ogni candidato, e scarta ogni candidato che non sa mostrare.
I docs spiegano perché un elenco ordinato non basta: quando un lavoro è finito, il modello dimentica le difficoltà della sessione e inventa consigli generici. Quindi scarta ogni candidato che non riesci a ricondurre a un momento specifico: basta una frase che chiede alla retro di citare la trascrizione per ciascuno.
Alla nostra prima retro la risposta è stata schietta: la maggior parte dei candidati non aveva alcun supporto nella trascrizione. Ha tenuto la protezione mancante, perché il suo stesso elenco della cartella degli hook non aveva stampato nulla, e ha scartato il controllo di migrazione come ipotetico.
Alla seconda retro, quella che conosceva il bug, la traccia ha tenuto quattro candidati e ne ha scartato uno.
| Candidato | Dopo la traccia |
|---|---|
| Il test che aveva scritto (accettata, rifiutata, accettata, numero mai controllato) | tenuto, solido |
| La funzione contatore senza avviso | tenuto, solido |
| La convenzione non scritta | tenuto, più debole |
| La protezione mancante | tenuto, anche se ha detto che una protezione non avrebbe intercettato questo bug |
| L'ultimo candidato | scartato: contava lo stesso momento due volte |
Una issue aperta nel repo della skill conta la maggior parte delle esecuzioni della retro seguite da un utente che chiede una prova. Un candidato ricondotto a un momento resta comunque il modello che legge il proprio log, quindi una riga segnata come più debole è un giudizio, e sei tu a decidere quali portare avanti.
Approvare ogni sopravvissuto nel suo carrier
Il quinto gesto è dove il ciclo ripaga: approva un sopravvissuto alla volta, ciascuno nel suo carrier, il posto dove la regola vivrà. La skill ti dà la scala. Una violazione meccanica ottiene un controllo deterministico, punto: una regola nel tuo linter, un hook di commit o un job nella tua pipeline. Una scelta di giudizio va in un file di standard di codice che il revisore legge. Il tuo file di istruzioni si usa, nelle parole dei docs, "incredibly sparingly", per puntatori ad altri file.
Abbiamo approvato quattro modifiche:
- La protezione mancante è diventata un hook di commit tracciato che lancia il type check e i test e blocca il commit se uno dei due fallisce. L'harness ha rifiutato di rendere eseguibile il file, quindi abbiamo lanciato noi quel comando.
- Il test è diventato un test
vitestche blocca la regola: una nota di credito accettata, una nota di credito rifiutata, e la successiva valida deve portare il numero successivo. È fallito alla prima esecuzione, ed è il punto: ha preso il bug che la sessione aveva rilasciato. - La scelta di giudizio è diventata una riga in un nuovo
CODING_STANDARDS.md: prendi un numero di sequenza solo dopo che ogni validazione è passata, così una richiesta rifiutata lascia la sequenza senza buchi. - Il buco di navigazione è diventato un commento sopra la funzione contatore: salva subito il contatore, quindi il numero è speso anche se il chiamante poi fallisce, perciò chiamala solo dopo la validazione.
Sono quattro file modificati e zero righe in CLAUDE.md, perché entrambe le retro hanno rifiutato di scriverne una. La prima ha detto che un puntatore in un file di guida costerebbe contesto a ogni turno e diventerebbe obsoleto; la seconda ha detto di tenerlo come commento sulla funzione. I docs le sostengono: Claude tratta quei file come contesto, non come configurazione imposta, e per bloccare un'azione si usa un hook.
Due limiti: un hook protegge solo i commit, e il commento è, nelle parole della retro stessa, una scommessa sul prossimo chiamante, non una correzione provata.
Chiudere il ciclo: l'hook blocca il commit, audit, commit, rilancio
Il sesto gesto è il commit, e l'ultimo è rilanciare lo stesso task, ed è lì che scopri se il ciclo ha tenuto.
Quando abbiamo messo in staging i file approvati e fatto commit, l'hook è partito per primo e ha rifiutato il commit. Il type check è passato, poi il nuovo test di numerazione è fallito, ricevendo un numero successivo a quello atteso. L'hook controlla i file così come sono sul disco, e il disco conteneva ancora il codice con il bug.
Quindi torna alla sessione e chiedi solo la correzione: prendi il numero dopo che la validazione passa, lancia i controlli, non fare commit. Poi fai di nuovo commit, l'hook passa verde e ottieni due commit: le modifiche della retro, poi la feature con la sua correzione. La retro stessa non ha fatto commit di nulla, cosa che una issue aperta nel repo descrive parola per parola, quindi il commit lo fai tu.
Poi lancia /doctor prompt-audit, il controllo di Claude Code stesso sui tuoi file di istruzioni per righe obsolete. Qui c'è una trappola: senza un percorso, fa l'audit dei tuoi file globali, non del repo. Dato il percorso, ha dichiarato pulito il nuovo file di standard, e ha segnalato che la vecchia route di emissione viola la regola, un bug di codice e non un problema di prompt.
L'ultimo gesto è una sessione nuova con lo stesso task. La nostra ha letto il file di standard di codice, il readme, l'hook e il test di numerazione rosso prima di scrivere qualsiasi codice, poi ha scritto nel proprio riepilogo che il numero viene preso solo dopo che tutti quei controlli passano, così una richiesta rifiutata non lascia buchi nella sequenza.
| Prima sessione | Sessione nuova dopo il ciclo | |
|---|---|---|
| Test passati | 42 | verde |
| Controllo nascosto della finanza | fallito | 5 su 5 |
| Numeri dopo una richiesta rifiutata | bruciati, un buco | senza buchi |
Una precisazione onesta: questa sessione nuova ha ricevuto la lezione sotto forma di test rosso e di riga di standard, quindi è un'esecuzione dopo il ciclo, non un benchmark.
Verdetto: quando lanciare una retro, quando no, la regola unica
La retro legge la sessione, quindi ciò che la sessione non ha visto lo scrivi tu nell'argomento. È la parte su cui inciamperai.
Lancia una retro dopo una sessione andata male, prima di cancellarla, o sul log di una vecchia sessione. Non lanciarla in automatico e non collegarla a un hook: lo dice l'autore della skill con le sue parole, non vuoi automatizzare questa cosa. I docs aggiungono un limite: non fa l'audit dei controlli che ha proposto il mese scorso, quindi sei ancora tu a sfoltirli.
La regola da ricordare è la frase dei docs stessi: tratta il tuo file di istruzioni come codice, rivedilo quando le cose vanno male, sfoltiscilo regolarmente e verifica le modifiche osservando se il comportamento di Claude cambia davvero. Il ciclo non rende l'agente nel giusto, rende solo più veloce intercettare lo stesso errore, e i controlli che aggiungi sono codice che ora devi mantenere.
Il pack gratuito di questo video contiene la checklist della retro con ogni gesto, la domanda di traccia e i carrier, più lo script dell'hook di commit e il test di numerazione del nostro run, così puoi partire dal nostro.
AIDive