
Kodgranskning som bevisar varje flaggad bugg
Be en AI granska din PR och du får ett prydligt checklisteresultat tillbaka: injektion kontrollerad, hemligheter kontrollerade, autentisering kontrollerad, ser bra ut. Det läses som noggrannhet. Om granskningen faktiskt hittade något är en helt annan sak — och checklistan är precis det som döljer missen. Vi driver en katalog som benchmarkar Claude-skills på heltid, och när vi riktade vårt eget benchmark mot en granskningsskill vi redan godkänt gick den förbi en hårdkodad hemlighet som baslinjen utan skill fångade. Listan hade ingen rad för just det stället, så granskaren tittade aldrig dit.
Den missen är anledningen till att review-discipline finns, och till att den finns i sin andra version. Den är gratis och MIT-licensierad: github.com/Skillproofdev/review-discipline. Varje fynd den rapporterar måste peka ut en konkret indata som når koden och ger ett felaktigt utfall — annars skickas det nedgraderat som [misstanke], aldrig påstått som fakta. På vårt bench med planterade buggar fångar den 18,5 av 21 planterade buggar med noll falska positiva och en påvisad felväg för ~100% av fynden.
Luckan: varje granskningsskill är en checklista, och checklistor tunnelseendar
Innan vi skrev en enda rad kartlade vi 321 kartlagda granskningsskills plus fältet i övrigt — inklusive Anthropics egen code-review-plugin. Tre mekanismer fanns i ingen av dem som regler som går att tvinga fram i en enda agent. Alla tre går tillbaka till samma fel vi bevittnade i vårt bench.
En checklista säger åt granskaren vad den ska leta efter. Det är också en lista över vad den ska titta förbi. När kategorierna inte täcker buggen överlever buggen — och värre, granskningen kommer ändå tillbaka grön, för varje ruta som finns blev ikryssad. De två sätt en granskning misslyckas på är att rapportera obevisade gissningar som fakta (brus) och att i tysthet hoppa över en riktig bugg för att den är liten eller för att en läskigare en tog all uppmärksamhet (missad täckning). En checklista är strukturellt bra på att producera båda.
Anthropics plugin bekämpar bruset med parallella scorer-agenter som röstar fram ett konfidenstal. Det är en riktig mekanism, men den kräver flera agenter och adresserar inte täckningshalvan alls. Ingen levererar det som vänder på checklistans form: jaga allt innan du tar fram någon kategorilista, bevisa eller märk varje fynd i efterhand, och släpp bara det du faktiskt kan motbevisa — i en agent, i en installerbar fil.
Åtta regler, tre som ingen annan tvingar fram
Skillen är en uppsättning regler (hela SKILL.md). Det välbekanta finns med: P0–P3-allvarlighetsgrad med riktiga definitioner istället för magkänsla, diff-scope-disciplin (granska ändringen, inte hela kodbasen), kommentarer om saknade tester kopplade till den ändrade koden, och noll beröm-utfyllnad. Delarna ingen annan tvingar fram:
- Ingen påvisad felväg, inget fynd. Varje fynd måste peka ut en konkret indata eller ett tillstånd som når den flaggade koden och ger ett felaktigt utfall. Går det inte att konstruera en? Då skickas det som
[misstanke], rankat under varje bevisat fynd — aldrig som fakta. Ett obevisat påstående framställt som en bugg är skillens enda förbjudna utdata. - Två genomgångar, öppen jakt först. Läs ändringen som en angripare utan kategorilista i handen och skriv upp varje avvikelse — inget lägsta allvarlighetsgrad, en sak som bara känns lite konstig skrivs ändå ner. Först därefter svepas den vanliga checklistan igenom (hemligheter, injektion, gränsvärden, aritmetik, samtidighet …) för att fånga vad den öppna jakten missade. Varje konkurrent är checklistan; här körs den sist, med flit.
- Döda ditt eget fynd innan du rapporterar det. Ett ärligt motbevisningsförsök per fynd — skyddande kod uppströms, avsiktligt beteende, befintlig testtäckning, nåbarhet — och rapporten säger vad som kontrollerades. Motbevisning är den enda grinden som får släppa ett fynd; "jag orkade inte bevisa det" blir en
[misstanke], inte en tyst strykning. Fynd som verkligen dör, dör tyst.
Den bärande regeln är ordningen: bredd före djup. Samla varje avvikelse utan lägsta allvarlighetsgrad innan du verifierar en enda, så att djupdykningen i en bugg aldrig kan trunkera jakten på resten. Det låter självklart. Det är också exakt den regel vår första version saknade — och anledningen till att den förlorade.
Det ärliga benchmarket (negativa resultat inkluderade)
Protokoll med planterade buggar: riktiga kodexempel (~200–400 rader vardera, TypeScript / Python / JS) planterade med dokumenterade buggar med känd allvarlighetsgrad — logik, säkerhet, edge case, samtidighet — med facit fastställt innan någon körning. Riktig, intakt kod finns kvar i varje exempel för att mäta falska positiva. Samma prompt, samma modell; den enda variabeln är om agenten läser SKILL.md först. Fullständig metodik: skillproof.dev/methodology.
4 exempel, 21 planterade buggar, 12 avsiktligt friska fällor för falska positiva. Den intressanta kolumnen är inte bas mot skill — det är v1 mot v2, för det är vårt eget bench som tvingade fram ombygget.
| Mått | Bas (utan skill) | Skill v1 | Skill v2 |
|---|---|---|---|
| Planterade buggar fångade (av 21) | 17,0 (81%) | 16,5 (79%) | 18,5 (88%) |
| P0-fångst (utnyttjbar / dataförlust) | 3/3 | 3/3 | 3/3 |
| P1-fångst (felaktigt beteende, realistisk väg) | 7/7 | 7/7 | 7/7 |
| P2-fångst (edge case / aritmetikvägar) | 6/7 | 4/7 | 7/7 |
| Hårdkodad hemlighet, testfråga | fångad | fångad | fångad |
| Andel falska positiva | 5,6% (1 FP) | 0% | 0% |
| Fynd med påvisad felväg | ~63% | ~100% | ~100% |
[misstanke]-nedgraderingar (ärliga reservationer) |
0 | 3 | 5 |
| Berömrader / utfyllnad | fanns | ingen | ingen |
Läs mittenkolumnen så ser du felet som gav skillen dess namn. v1 fick 16,5 — under baslinjens 17. Den hade felvägsdisciplinen (den fick ner falska positiva till noll och bevisade ~100% av sina fynd), men den var sämre på att hitta buggar, för att den låste fast blicken på de läskiga P0-buggarna i ett exempel och svepte aldrig igenom de tysta avrundningsraderna för pengar. Den tunnelseende. Vårt publika bench av en skill vi redan godkänt är det som fångade det: v1 missade två riktiga P2-buggar — ett prorate /30-logikfel och en int(amount × 100)-avrundning — som baslinjen fångade bara genom att läsa linjärt.
Fixen var regeln om bredd före djup. v2 samlar varje avvikelse utan lägsta allvarlighetsgrad innan den verifierar någon av dem. Resultat: P2 gick från 4/7 till ett rent 7/7 (den återfångade till och med en tom-CSV StopIteration som både bas och v1 missade), total träffgrad klättrade till 18,5 — förbi basens 17 — och disciplinen höll: fortfarande noll falska positiva, fortfarande ~100% påvisade felvägar, och fler ärliga [misstanke]-reservationer (5 mot 3) snarare än färre. Hela 3-vägsbedömningen finns i bench/results/verdict.md.
En myt som benchmarket också avlivade, rakt av: hypotesen om checklistetunnelseende kring hemligheter, som drev igång hela projektet, reproducerades inte i den planterade körningen — alla tre grenarna fångade testfrågan med den hårdkodade hemligheten (S4-B1). Den ursprungliga missen var verklig och det är den som lärde oss problemets form; det planterade benchmarket visade bara att hemligheten själv inte är där bredd lönar sig. Avrundningsfallen med pengar är det. Vi rapporterar mekanismen som faktiskt flyttade siffrorna, inte den som gav den bättre ursprungshistorien.
Där v2 förlorade — publicerat ändå
Vår metodik kräver att förlusterna redovisas bredvid vinsterna. v2 är den bästa grenen på allt som blockerar en merge, men den är inte en strikt övermängd av v1, och vi låtsas inte om något annat.
I jakten på uttömmande bredd slutade v2 att borra i en funktion (_parse_tags) och gick förbi en subtil literal_eval-misstanke om djup nästling (S2-B5) som v1:s djupfokuserade genomgång unikt hade fångat. Så på axeln P3 / utanför checklistan gick v2 faktiskt bakåt — från v1:s 2,5/4 ner till 1,5/4. Netto är det ett bra byte (+2 medelsvåra mot −1 subtil P3), men det är en riktig försämring på just den axeln, ingen ren dominans. Den idealiska granskaren är v2:s bredd plus v1:s vilja att borra en nivå till i tystlåten kod — och vi berättar det hellre än att runda av det.
Det finns också en bugg ingen gren fångade: en strikt <-gräns för kupongutgång (S1-B6), missad av bas, v1 och v2 samtliga. Skillen minskar missarna; den gör inte Claude ofelbar.
SKILLPROOF SKILL
review-discipline är gratis, MIT, och hela grejen är en enda fil. Läs de åtta reglerna, testriggen för planterade buggar och hela 3-vägsbedömningen — kör den sedan mot dina egna diffar.
Hämta review-discipline på GitHubInstallation
git clone https://github.com/Skillproofdev/review-discipline ~/.claude/skills/review-discipline
Starta om Claude Code. Ett kommando — repot är skillen. Den triggas av "granska den här PR:n/diffen", "kolla det här innan merge", "hitta buggar i" och kontroller inför merge — och håller sig undan när det gäller ny funktionalitet, ren stillinting eller prosagranskning. Den ansluter till vår disciplinserie: token-discipline minskar vad en agent kostar, research-discipline minskar vad den har fel om fakta, och den här minskar vad en granskning missar.
GRATIS STARTPAKET
Vill du ha våra bäst testade skills plus installationschecklistan vi kör inför varje test? Vi mejlar dig det gratis startpaketet.
Hämta det gratis startpaketetFAQ
Hur skiljer sig det här från Anthropics code-review-plugin? Pluginet filtrerar bort falska positiva genom att låta parallella scorer-agenter rösta fram ett konfidenstal — effektivt, men det kräver flera agenter och angriper bara brusproblemet. review-discipline filtrerar med en påvisad felväg i en enda agent, i en installerbar fil, och angriper dessutom täckningsproblemet som pluginet inte rör: regeln om öppen jakt före checklista, som lyfte vår egen P2-träffgrad från 4/7 till 7/7.
Gör inte "bevisa varje fynd" att den missar sådant den inte kan påvisa?
Nej — det är [misstanke]-mekanismen. En riktig bugg du inte kan bygga en felväg för (kräver körtidstillstånd du inte kan se, eller ett externt system) rapporteras ändå, märkt [misstanke] och rankad under de bekräftade fynden, med en rad om vad som saknas. Att nedgradera konfidens är verktyget; att släppa är det inte. I benchmarket lämnade v2 5 sådana ärliga reservationer istället för att svälja dem.
Granskar den hela kodbasen eller bara min diff? Bara ändringen. Fynd måste orsakas eller aktiveras av den här diffen; befintliga problem hamnar i en kort notis utanför scope, inte i den rankade listan. Det enda undantaget är en befintlig P0 — en aktiv hemlighet eller aktiv sårbarhet — som alltid flaggas tydligt. Det undantaget finns just på grund av missen i ursprungshistorien.
Räcker 18,5/21 för att hoppa över mänsklig granskning? Nej. Den fångar varje P0 och P1 som blockerar merge i vårt bench och slår en ostyrd baslinje på total träffgrad med noll falska positiva — vilket gör den till en stark första granskare som aldrig stämplar godkänt utan att kolla och alltid namnger vad den angrep. Men den missade en planterad bugg helt och bytte bort en subtil P3 mot bredd, båda dokumenterade ovan. Använd den för att se till att de uppenbara och de tysta aritmetikbuggarna aldrig når en människa; behåll människan för den sista nivån av djup.
★ 9.6/10 × 3
Gratis startpaket
De 3 skills som fått våra högsta testbetyg plus installationschecklistan — setupen vi själva skulle lägga på en ny maskin. Gratis, via e-post.