Code review Claude, który dowodzi każdy zgłoszony bug

Code review Claude, który dowodzi każdy zgłoszony bug

Poproś AI o review swojego PR-a, a dostaniesz schludny wynik checklisty: injection sprawdzone, sekrety sprawdzone, auth sprawdzone, wygląda dobrze. Czyta się to jak staranność. Czy faktycznie coś znalazł — to zupełnie inna sprawa, a checklista właśnie po to jest, żeby ukryć przeoczenie. Na co dzień prowadzimy katalog, w którym benchmarkujemy skille Claude, i kiedy własny benchmark wycelowaliśmy w skill do review'ów, który wcześniej oceniliśmy jako pass, przeszedł obok zahardkodowanego sekretu, który złapał baseline bez żadnych wskazówek. Na liście nie było linijki dla tego miejsca, więc reviewer nigdy tam nie zajrzał.

To przeoczenie jest powodem, dla którego istnieje review-discipline — i dlaczego istnieje już w drugiej wersji. Jest darmowy, na licencji MIT: github.com/Skillproofdev/review-discipline. Każde zgłoszone znalezisko musi wskazywać konkretny input, który dociera do kodu i wywołuje błędny wynik — albo trafia do wyniku obniżone do [suspicion], nigdy podane jako fakt. W naszym benchmarku z zaszczepionymi bugami wyłapuje 18,5 z 21 podrzuconych błędów przy zero false positives i udowodnioną ścieżką awarii dla ~100% znalezisk.

Luka: każdy skill do review'u to checklista, a checklisty tunelują uwagę

Zanim napisaliśmy pierwszą linijkę, przejrzeliśmy 321 zindeksowanych skilli do review'u plus samodzielne narzędzia z tej niszy — w tym własny plugin Anthropic do code review. Trzy mechanizmy nie pojawiły się w żadnym z nich jako egzekwowalne reguły dla pojedynczego agenta. Wszystkie trzy prowadzą do tej samej porażki, którą zaobserwowaliśmy w naszym benchmarku.

Checklista mówi reviewerowi, czego ma szukać. To jednocześnie lista tego, co przeoczy. Gdy kategorie nie obejmują danego buga, bug przeżywa — a co gorsza, review i tak wychodzi na zielono, bo każdy istniejący punkt został odhaczony. Review zawodzi na dwa sposoby: zgłaszając nieudowodnione domysły jako fakty (szum) albo po cichu pomijając prawdziwego buga, bo jest mały albo bo cała uwaga poszła na coś bardziej przerażającego (brak pokrycia). Checklista strukturalnie sprzyja obu.

Plugin Anthropic walczy z połową dotyczącą szumu za pomocą równoległych agentów-oceniających, którzy głosują liczbą pewności. To realny mechanizm, ale wymaga wielu agentów i w ogóle nie zajmuje się połową dotyczącą pokrycia. Nikt nie oferuje rozwiązania, które odwraca kształt checklisty: najpierw poluj na wszystko, zanim sięgniesz po jakąkolwiek listę kategorii, potem udowodnij lub oznacz każde znalezisko, i odrzucaj tylko to, co faktycznie potrafisz obalić — w jednym agencie, w jednym instalowalnym pliku.

Osiem reguł, trzech nie egzekwuje nikt inny

Skill to zestaw egzekwowalnych reguł (pełny SKILL.md). Znajome elementy są na miejscu: powaga P0–P3 z realnymi definicjami zamiast wyczucia, dyscyplina zakresu diffa (review zmiany, nie całego kodu), uwagi o brakujących testach powiązane ze zmienionym zachowaniem i zero pochwalnego wypełniacza. Elementy, których nikt inny nie egzekwuje:

  1. Brak udowodnionej ścieżki awarii, brak znaleziska. Każde znalezisko musi wskazać konkretny input lub stan, który dociera do oznaczonego kodu i wywołuje błędny wynik. Nie da się go skonstruować? Trafia jako [suspicion], niżej w rankingu niż każde udowodnione znalezisko — nigdy jako fakt. Nieudowodnione twierdzenie podane jako bug to jedyny zakazany wynik skilla.
  2. Dwa przebiegi, najpierw otwarte polowanie. Przeczytaj zmianę jak atakujący, bez listy kategorii w ręku, i zapisz każdą anomalię — bez progu powagi, coś, co tylko lekko śmierdzi, też trafia na listę. Dopiero potem przejdź standardową checklistę (sekrety, injection, granice, arytmetyka, współbieżność…) w poszukiwaniu tego, co przeoczyło otwarte polowanie. Każdy konkurent jest checklistą; tutaj działa ona jako drugi krok, celowo.
  3. Zabij własne znalezisko, zanim je zgłosisz. Jedna uczciwa próba obalenia na znalezisko — zabezpieczenia wcześniej w łańcuchu, celowe zachowanie, istniejące pokrycie testami, osiągalność — a raport podaje, co zostało sprawdzone. Obalenie to jedyna furtka, przez którą wolno odrzucić znalezisko; „nie chciało mi się tego udowodnić" zamienia się w [suspicion], nie w ciche odrzucenie. Znaleziska, które naprawdę umierają, umierają po cichu.

Regułą, na której wszystko się trzyma, jest kolejność: najpierw szerokość, potem głębokość. Zbierz każdą anomalię bez progu powagi, zanim zweryfikujesz choć jedną, żeby dogłębna analiza jednego buga nigdy nie ucięła polowania na resztę. Brzmi oczywiście. To też dokładnie ta reguła, której brakowało w naszej pierwszej wersji — i powód, dla którego przegrała.

Uczciwy benchmark (razem z wynikami negatywnymi)

Protokół zaszczepionych bugów: prawdziwe próbki kodu (~200–400 linii każda, TypeScript / Python / JS) zaszczepione udokumentowanymi bugami o znanej powadze — logicznymi, bezpieczeństwa, brzegowymi, współbieżności — ze stanem faktycznym zatwierdzonym przed jakimkolwiek przebiegiem. W każdej próbce zostaje też prawdziwy, nietknięty kod, żeby mierzyć false positives. Te same prompty, ten sam model; jedyną zmienną jest to, czy agent najpierw czyta SKILL.md. Pełna metodologia: skillproof.dev/methodology.

4 próbki, 21 zaszczepionych bugów, 12 celowo zdrowych pułapek na false positives. Ciekawą kolumną nie jest base-vs-skill — to v1 vs v2, bo to właśnie nasz własny benchmark wymusił przebudowę.

Metryka Base (bez skilla) Skill v1 Skill v2
Wyłapane zaszczepione bugi (z 21) 17,0 (81%) 16,5 (79%) 18,5 (88%)
Wyłapanie P0 (do wykorzystania / utrata danych) 3/3 3/3 3/3
Wyłapanie P1 (błędne zachowanie, realistyczna ścieżka) 7/7 7/7 7/7
Wyłapanie P2 (ścieżki brzegowe / arytmetyczne) 6/7 4/7 7/7
Sonda z zahardkodowanym sekretem złapana złapana złapana
Wskaźnik false positive 5,6% (1 FP) 0% 0%
Znaleziska z udowodnioną ścieżką awarii ~63% ~100% ~100%
Obniżenia do [suspicion] (uczciwe zastrzeżenia) 0 3 5
Linijki pochwał / wypełniacza obecne brak brak

Spójrz na środkową kolumnę, a zobaczysz porażkę, która nadała temu skillowi nazwę. v1 uzyskał 16,5 — poniżej 17 nieprowadzonego baseline'u. Miał dyscyplinę ścieżki awarii (obciął false positives do zera i udowodnił ~100% swoich znalezisk), ale był gorszy w znajdywaniu bugów, bo zafiksował się na przerażających P0 w jednej próbce i nigdy nie przeszedł po cichych linijkach zaokrągleń pieniężnych. Tunelował uwagę. To nasz publiczny benchmark skilla, który wcześniej oceniliśmy jako pass, złapał ten problem: v1 przeoczył dwa prawdziwe P2 — błąd logiczny w prorate /30 i obcięcie w int(amount × 100) — które baseline wyłapał, po prostu czytając liniowo.

Naprawą była reguła najpierw-szerokość-potem-głębokość. v2 zbiera każdą anomalię bez progu powagi, zanim zweryfikuje którąkolwiek z nich. Wynik: P2 poszło z 4/7 do czystego 7/7 (odzyskał nawet StopIteration na pustym CSV, które przeoczyły zarówno base, jak i v1), całkowity recall wzrósł do 18,5 — ponad 17 baseline'u — a dyscyplina się utrzymała: wciąż zero false positives, wciąż ~100% udowodnionych ścieżek i więcej, nie mniej, uczciwych zastrzeżeń [suspicion] (5 zamiast 3). Pełna trójstronna ocena jest w bench/results/verdict.md.

Benchmark obalił po drodze jeszcze jeden mit, wprost: hipoteza o tunelowaniu uwagi checklisty na sekretach, która zapoczątkowała cały projekt, nie potwierdziła się w przebiegu z zaszczepionymi bugami — wszystkie trzy warianty złapały sondę z zahardkodowanym sekretem (S4-B1). Pierwotne przeoczenie było prawdziwe i to ono nauczyło nas, jak wygląda ten problem; benchmark z zaszczepionymi bugami po prostu pokazał, że to nie sam sekret jest miejscem, gdzie szerokość się opłaca. Opłaca się przy przypadkach brzegowych zaokrągleń pieniężnych. Raportujemy mechanizm, który faktycznie poruszył liczby, a nie ten, który dawał lepszą historię powstania.

Gdzie v2 przegrał — i tak to publikujemy

Nasza metodologia wymaga pokazywania porażek obok zwycięstw. v2 jest najlepszym wariantem we wszystkim, co blokuje merge, ale nie jest ścisłym nadzbiorem v1 i nie będziemy udawać inaczej.

Goniąc za wyczerpującą szerokością, v2 przestał drążyć jedną funkcję (_parse_tags) i przeszedł obok subtelnego podejrzenia głębokiego zagnieżdżenia literal_eval (S2-B5), które jako jedyny złapał przebieg v1 skupiony na głębi. Więc na osi P3 / poza checklistą v2 faktycznie się cofnął — z 2,5/4 u v1 do 1,5/4. Netto to dobra wymiana (+2 średnie za −1 subtelny P3), ale to realny regres na tej jednej osi, nie czysta dominacja. Idealny reviewer to szerokość v2 plus gotowość v1, żeby drążyć jeszcze jeden poziom głębiej w kodzie, który wygląda spokojnie — i wolimy to powiedzieć wprost, niż to wygładzać.

Jest też bug, którego nie złapał żaden wariant: remis na ścisłym < przy wygaśnięciu kuponu (S1-B6), przeoczony zarówno przez base, v1, jak i v2. Skill tnie przeoczenia; nie czyni Claude nieomylnym.

SKILL SKILLPROOF

review-discipline jest darmowy, na licencji MIT, a całość to jeden plik. Przeczytaj osiem reguł, harness z zaszczepionymi bugami i pełny trójstronny werdykt — a potem uruchom go na własnych diffach.

Pobierz review-discipline na GitHub

Instalacja

git clone https://github.com/Skillproofdev/review-discipline ~/.claude/skills/review-discipline

Zrestartuj Claude Code. Jedna komenda — repozytorium jest skillem. Uruchamia się na „review this PR/diff", „check this before merge", „find bugs in" i kontrole przed merge'em — i nie wtrąca się przy pisaniu feature'ów, lintowaniu czysto stylistycznym i recenzji prozy. Dołącza do naszej serii dyscyplin: token-discipline tnie to, ile agent kosztuje, research-discipline tnie to, w czym myli się co do faktów, a ten tnie to, co przeocza review.

DARMOWY PAKIET STARTOWY

Chcesz nasze najwyżej oceniane skille plus checklistę instalacyjną, której używamy przed każdym testem? Wyślemy ci mailem darmowy starter pack.

Odbierz darmowy starter pack

FAQ

Czym różni się to od pluginu Anthropic do code review? Plugin filtruje false positives, każąc równoległym agentom-oceniającym głosować liczbą pewności — skuteczne, ale wymaga wielu agentów i zajmuje się tylko problemem szumu. review-discipline filtruje za pomocą udowodnionej ścieżki awarii w jednym agencie, w jednym instalowalnym pliku, i atakuje też problem pokrycia, którego plugin nie dotyka: regułę otwartego polowania przed checklistą, która podniosła nasz recall dla P2 z 4/7 do 7/7.

Czy „udowodnij każde znalezisko" nie sprawi, że przeoczy rzeczy, których nie da się udowodnić? Nie — od tego jest mechanizm [suspicion]. Prawdziwy bug, dla którego nie da się zbudować ścieżki awarii (potrzebuje stanu runtime'owego, którego nie widać, albo systemu zewnętrznego), i tak zostaje zgłoszony, oznaczony jako [suspicion] i umieszczony niżej niż potwierdzone znaleziska, z jedną linijką o tym, czego brakuje. Narzędziem jest obniżanie pewności, nie odrzucanie. W benchmarku v2 wystawił 5 takich uczciwych zastrzeżeń, zamiast je połknąć.

Czy robi review całego kodu, czy tylko mojego diffa? Tylko zmiany. Znaleziska muszą być spowodowane lub aktywowane przez ten diff; problemy istniejące wcześniej trafiają do krótkiej notki poza zakresem, nie na listę rankingową. Jedyny wyjątek to wcześniej istniejący P0 — żywy sekret albo aktywna podatność — który zawsze zostaje wyraźnie oflagowany. Ten wyjątek istnieje właśnie z powodu przeoczenia z historii powstania skilla.

Czy 18,5/21 wystarczy, żeby pominąć review człowieka? Nie. Łapie każdy blokujący merge P0 i P1 w naszym benchmarku i bije nieprowadzony baseline pod względem całkowitego recall przy zero false positives — co czyni go mocnym pierwszym reviewerem, który nigdy nie odbija pieczątki bez patrzenia i zawsze mówi, co zaatakował. Ale całkowicie przeoczył jednego zaszczepionego buga i oddał subtelny P3 w zamian za szerokość, oba udokumentowane powyżej. Używaj go, żeby oczywiste bugi i te ciche arytmetyczne nie dotarły do człowieka; człowieka zostaw na ostatni poziom głębi.

★ 9.6/10 × 3

Darmowy pakiet startowy

3 skille z naszymi najwyższymi ocenami z testów plus checklista instalacji — zestaw, który sami wgralibyśmy na świeżą maszynę. Za darmo, na e-mail.

Jeden e-mail z pakietem + krótki cotygodniowy przegląd nowych wyników testów. Wypiszesz się, kiedy chcesz.