AIDive

Claude Code wypuścił buga. Zablokowałem go 4 poprawkami

AIDive · Opublikowano

Agenty do kodowania

Sesja, która wypuściła buga, i retro, które powiedziało, że było gładko

Claude Code wypuścił buga w numeracji na prawdziwym repo, a cztery zatwierdzone zmiany sprawiły, że nie da się go wypuścić ponownie. Sesja pisała noty kredytowe dla małego API do faktur, zestaw testów wyszedł zielony, a sprawdzenie wykonane później ręcznie pokazało, że odrzucone żądanie spaliło numer faktury. Potem zrobiliśmy retro tej sesji, zatwierdziliśmy poprawki jedna po drugiej i uruchomiliśmy to samo zadanie jeszcze raz: wyszło czysto.

Retro to przegląd, który zespół robi po incydencie, tutaj wykonany na logu sesji samego Claude Code. Nasze pierwsze retro zaczęło się od "This session was smooth" i żadne z jego ustaleń nie było tym bugiem. Rozwiązanie to siedem gestów, po kolei: zainstaluj, puść zadanie, puść retro i powiedz mu, co poszło nie tak, wskaż moment dla każdego kandydata, zatwierdź każdego ocalałego do jego nośnika, zrób commit i audyt, a na końcu puść zadanie jeszcze raz.

Czym jest retro i instalacja /retro

/retro to skill Matta Pococka, który przegląda sesję kodowania zamiast twojego kodu. Czyta log sesji, czyli plik, w którym Claude Code trzyma każdy prompt i każde wywołanie narzędzia, i szuka kandydatów w siedmiu kategoriach, na przykład kontroli, która mogła wyłapać błąd. Przedstawia ich według wagi i, zgodnie ze swoimi docsami, tylko proponuje: nic się nie zmienia, dopóki nie wybierzesz kandydata.

Instalacja to pierwszy gest: w swoim repo zaktualizuj oficjalny marketplace, a potem zainstaluj paczkę skilli w zakresie projektu, żeby żyła tylko w tym repo. Nasz marketplace był przypięty do starszego wydania bez retro, więc najpierw przyszła aktualizacja. W nowej sesji wpisz ukośnik, a komenda retro będzie na liście.

Jedno ograniczenie: sesja w chmurze nie może czytać logów z twojej maszyny, więc puść retro tam, gdzie odbyła się sesja.

Puść zadanie i daj mu skończyć: nasza sesja wypuściła buga

Drugi gest to ten, który i tak robisz codziennie: wpisz swoje prawdziwe zadanie w zwykłej sesji, daj jej skończyć i zostaw sesję otwartą, bo właśnie to retro będzie czytać.

Użyliśmy małego API do faktur w Node i TypeScript, z własnym zestawem testów i bez pliku z instrukcjami, bez pipeline'u i bez hooka commitu gdziekolwiek. Zadanie było krótkie, tak jak sam byś je wpisał: dodać noty kredytowe do opłaconych faktur, numerowane po kolei, i pozwolić unieważnić opłaconą fakturę przez zaksięgowanie tego, co zostało.

Sesja napisała route, migrację i własne testy, a przed zatrzymaniem puściła zestaw testów. Potem uruchomiliśmy kontrolę, którą ręcznie zrobiłaby księgowość, ukryty test napisany wcześniej, i jeden wymóg padł.

Sygnał Wynik
Zestaw testów 42 testy przeszły
Type check czysty
Ukryta kontrola księgowa nie przeszła: późniejszy numer noty kredytowej niż oczekiwany

Przyczyna: handler bierze następny numer z licznika, zanim zwaliduje żądanie, a licznik jest zapisywany w chwili odczytu. Zbyt duża nota kredytowa zostaje odrzucona, co jest poprawne, a numer i tak przepada, co już poprawne nie jest. Sesja skopiowała tę kolejność z istniejącej route'y wystawiania, która gubi numery faktur w ten sam sposób.

Uruchomiliśmy zadanie dwa razy i drugie podejście wyszło czysto, więc tak zachowuje się zwykła sesja przynajmniej część razy.

Puść /retro, potem powiedz mu, co poszło nie tak

Trzeci gest to wpisanie komendy retro w tej samej sesji, a potem puszczenie jej jeszcze raz z opisem porażki po niej. Nasza zaczęła tak: "This session was smooth."

Uszeregowała kilka pozycji, żadna nie była tym bugiem: brakujące zabezpieczenie, reguła migracji, której nikt nie sprawdza, i nic, co recenzent mógłby egzekwować. Retro czyta log sesji, a sesja nigdy nie dowiedziała się, że zawiodła.

Więc mówisz mu to sam: puść komendę ponownie z porażką jako argumentem, czyli tekstem po komendzie. Nasz mówił, że księgowość przetestowała build, że zbyt duża nota kredytowa została odrzucona, że następna poprawna wyszła spóźniona i że retro ma niczego nie naprawiać.

Tym razem znalazło przyczynę we własnym kodzie: najpierw bierze numer, a dopiero potem waliduje, i powiedziało, że skopiowało tę kolejność z istniejącego handlera wystawiania. Potem pojawili się nowi kandydaci: test, który napisało i który uruchamiał nieudaną sekwencję, ale sprawdzał tylko kody statusu, funkcja licznika, która wygląda na czystą, a nią nie jest, i konwencja, której nikt nie spisał.

Cokolwiek odkryjesz po sesji, wpisz to w argument, bo inaczej retro audytuje sesję, która według niego poszła dobrze.

Przed zatwierdzeniem prześledź każdego kandydata do momentu

Czwarty gest to ten, którego skill sam nie robi: poproś retro o zacytowanie momentu transkryptu za każdym kandydatem i odrzuć każdego, którego nie potrafi pokazać.

Docsy tłumaczą, dlaczego uszeregowana lista nie wystarcza: gdy zadanie jest skończone, model zapomina o zmaganiach sesji i wymyśla ogólne rady. Odrzuć więc każdego kandydata, którego nie umiesz powiązać z konkretnym momentem: wystarczy jedno zdanie z prośbą, by retro zacytowało transkrypt dla każdego.

Przy naszym pierwszym retro odpowiedź była szczera: większość kandydatów nie miała oparcia w transkrypcie. Zostawiło brakujące zabezpieczenie, bo jego własny wypis folderu z hookami nic nie wydrukował, a kontrolę migracji odrzuciło jako hipotetyczną.

Przy drugim retro, tym, które wiedziało o bugu, śledzenie zostawiło czterech kandydatów i odrzuciło jednego.

Kandydat Po śledzeniu
Test, który napisało (przyjęta, odrzucona, przyjęta, numer nigdy nie sprawdzony) zostaje, pewny
Funkcja licznika bez ostrzeżenia zostaje, pewna
Niespisana konwencja zostaje, słabsza
Brakujące zabezpieczenie zostaje, choć powiedziało, że zabezpieczenie nie wyłapałoby tego buga
Ostatni kandydat odrzucony: liczył ten sam moment dwa razy

Otwarte issue w repo skilla zlicza większość uruchomień retro, po których użytkownik prosił o dowód. Prześledzony kandydat to wciąż model czytający własny log, więc wiersz oznaczony jako słabszy to osąd, a ty decydujesz, których pociągniesz dalej.

Zatwierdź każdego ocalałego do jego nośnika

Piąty gest to miejsce, gdzie pętla się opłaca: zatwierdzaj ocalałych po jednym, każdego do jego nośnika, czyli miejsca, w którym reguła będzie żyć. Skill daje ci drabinę. Naruszenie mechaniczne dostaje deterministyczną kontrolę, kropka: regułę w linterze, hook commitu albo zadanie w pipeline. Decyzja oparta na osądzie trafia do pliku standardów kodowania, który czyta recenzent. Twój plik z instrukcjami jest używany, słowami docsów, "incredibly sparingly", na wskaźniki do innych plików.

Zatwierdziliśmy cztery zmiany:

  • Brakujące zabezpieczenie stało się śledzonym hookiem commitu, który puszcza type check i testy i blokuje commit, jeśli któreś padnie. Harness odmówił nadania plikowi prawa wykonywania, więc tę komendę uruchomiliśmy sami.
  • Test stał się jednym testem vitest, który blokuje regułę: nota kredytowa przyjęta, nota kredytowa odrzucona, a następna poprawna musi dostać następny numer. Padł przy pierwszym uruchomieniu, i o to chodzi: złapał buga, którego sesja wypuściła.
  • Decyzja oparta na osądzie stała się jedną linią w nowym CODING_STANDARDS.md: bierz numer sekwencji dopiero po przejściu wszystkich walidacji, żeby odrzucone żądanie zostawiało sekwencję bez dziur.
  • Luka w nawigacji stała się jednym komentarzem nad funkcją licznika: zapisuje licznik natychmiast, więc numer jest wydany, nawet jeśli wywołujący potem zawiedzie, więc wołaj ją dopiero po walidacji.

To cztery zmienione pliki i zero linii w CLAUDE.md, bo oba retro odmówiły jej napisania. Pierwsze powiedziało, że wskaźnik w pliku sterującym kosztowałby kontekst w każdej turze i się zestarzał; drugie, żeby zostawić go jako komentarz przy funkcji. Docsy to potwierdzają: Claude traktuje te pliki jako kontekst, nie wymuszoną konfigurację, a żeby zablokować akcję, używa się hooka.

Dwa ograniczenia: hook chroni tylko commity, a komentarz jest, słowami samego retro, zakładem na następnego wywołującego, nie sprawdzoną poprawką.

Domknij pętlę: hook blokuje commit, audyt, commit, ponowny bieg

Szósty gest to commit, a ostatni to puszczenie tego samego zadania jeszcze raz, i właśnie wtedy okaże się, czy pętla się utrzymała.

Gdy dodaliśmy zatwierdzone pliki do staging i zrobiliśmy commit, hook uruchomił się pierwszy i odrzucił commit. Type check przeszedł, potem nowy test numeracji padł, dostając późniejszy numer niż oczekiwany. Hook sprawdza pliki takie, jakie są na dysku, a na dysku nadal był zbugowany kod.

Wróć więc do sesji i poproś tylko o poprawkę: bierz numer po przejściu walidacji, puść kontrole, nie rób commitu. Potem zrób commit jeszcze raz, hook przechodzi na zielono i dostajesz dwa commity: zmiany retro, a potem funkcję z jej poprawką. Samo retro niczego nie zacommitowało, co otwarte issue w repo opisuje słowo w słowo, więc commit robisz ty.

Następnie puść /doctor prompt-audit, własną kontrolę Claude Code twoich plików z instrukcjami pod kątem przestarzałych linii. Jest tu pułapka: bez ścieżki audytuje twoje pliki globalne, nie repo. Po podaniu ścieżki uznało nowy plik standardów za czysty i zgłosiło, że starsza route wystawiania łamie regułę, a to błąd w kodzie, nie problem z promptem.

Ostatni gest to świeża sesja z tym samym zadaniem. Nasza przeczytała plik standardów kodowania, readme, hook i czerwony test numeracji, zanim napisała jakikolwiek kod, a potem napisała we własnym podsumowaniu, że numer jest brany dopiero po przejściu wszystkich tych kontroli, więc odrzucone żądanie nie zostawia dziury w sekwencji.

Pierwsza sesja Świeża sesja po pętli
Testy, które przeszły 42 zielone
Ukryta kontrola księgowa nie przeszła 5 z 5
Numery po odrzuconym żądaniu spalone, dziura bez dziur

Jedno uczciwe zastrzeżenie: ta świeża sesja dostała lekcję jako czerwony test i linię standardów, więc to bieg po pętli, nie benchmark.

Werdykt: kiedy puszczać retro, kiedy nie, jedna reguła

Retro czyta sesję, więc to, czego sesja nie widziała, wpisujesz w argument. To jest część, na której się potkniesz.

Puść retro po sesji, która poszła źle, zanim ją wyczyścisz, albo na logu starej sesji. Nie puszczaj go na autopilocie i nie podpinaj pod hooka: autor skilla mówi to własnymi słowami, nie chcesz tego automatyzować. Docsy dodają ograniczenie: nie audytuje kontroli, które zaproponowało w zeszłym miesiącu, więc nadal sam je przycinasz.

Jedna reguła do zapamiętania to zdanie z docsów: traktuj swój plik z instrukcjami jak kod, przeglądaj go, gdy coś idzie źle, przycinaj regularnie i testuj zmiany, obserwując, czy zachowanie Claude naprawdę się zmienia. Pętla nie sprawia, że agent ma rację, sprawia tylko, że ten sam błąd łapie się szybciej, a kontrole, które dodajesz, to kod, który teraz utrzymujesz.

Darmowa paczka do tego filmu zawiera checklistę retro z każdym gestem, pytanie śledzące i nośniki, a także skrypt hooka commitu i test numeracji z naszego biegu, więc możesz zacząć od naszych.

Darmowe zasoby

Źródła

Najczęstsze pytania

Co robi skill /retro Matta Pococka?
Przegląda sesję Claude Code zamiast twojego kodu, czytając log sesji z każdym promptem i wywołaniem narzędzia. Szuka kandydatów w siedmiu kategoriach, szereguje ich według wagi i tylko proponuje: nic się nie zmienia, dopóki nie wybierzesz kandydata.
Dlaczego retro powiedziało, że sesja była gładka?
Retro czyta log sesji, a nasza sesja nigdy nie dowiedziała się, że zawiodła: jej 42 testy i type check były zielone. Buga złapała dopiero ukryta kontrola księgowa, więc pierwsze retro zaczęło się od 'This session was smooth' i go nie zauważyło.
Jak sprawić, żeby retro znalazło porażkę, której sesja nie zauważyła?
Puść komendę retro drugi raz i wpisz porażkę po niej jako argument. Nasz mówił, że księgowość znalazła odrzuconą notę kredytową i spóźniony następny numer, a tym razem retro doszło do przyczyny we własnym kodzie, który brał numer przed walidacją.
Jak sprawić, żeby retro udowodniło swoje ustalenia?
Poproś je o zacytowanie momentu transkryptu za każdym kandydatem i odrzucenie tych, których nie potrafi pokazać. Przy naszym pierwszym retro większość kandydatów nie miała oparcia; przy drugim śledzenie zostawiło czterech i odrzuciło jednego.
Czy powinienem wpisać regułę do CLAUDE.md?
Nie domyślnie: zatwierdziliśmy cztery zmiany i napisaliśmy zero linii w CLAUDE.md. Docsy mówią, że Claude traktuje go jako kontekst, nie wymuszoną konfigurację, więc reguła mechaniczna należy do hooka lub testu, a decyzja oparta na osądzie do pliku standardów kodowania.
Kiedy powinienem puścić retro na sesji Claude Code?
Puść je po sesji, która poszła źle, zanim ją wyczyścisz, albo na logu starej sesji. Nie automatyzuj go i nie podpinaj pod hooka: jego autor mówi, że nie chcesz tego automatyzować.

Powiązane filmy