Week 39: Waarom ik de code review uitzette
Een normale code review kan ontaarden in miljoenen tokens. Deze week zette ik de reviewskill uit en ging ik investeren in de vraag ervóór.
Deze week nam ik een besluit dat ik weken heb uitgesteld: de /code-review skill van Claude Code officieel verbieden. Niet omdat hij slecht werkt — juist omdat hij té goed zijn werk doet, tot in het oneindige door blijft zoeken naar nóg een bevinding, en dat op een manier die kostbaar is geworden.
Een review die zichzelf niet meer stopt
Het patroon was al langer zichtbaar in mijn eigen sessies. Een “gewone” code review op een middelgrote wijziging start met een redelijke intentie: kijk of de fix klopt, of er edge cases gemist zijn, of de tests genoeg dekken. Maar de skill is grondig, en grondig plus agentisch betekent dat hij bij twijfel doorzoekt, herleest, opnieuw redeneert. Bij een aantal reviews deze en vorige weken liep dat op tot bevindingenlijsten van tientallen punten en tokenverbruik dat ik alleen nog in de miljoenen kon uitdrukken. Dat is geen incident meer, dat is een patroon.
Dus heb ik het vastgelegd als beleid, niet als losse observatie: de reviewskill mag niet meer zomaar aangeroepen worden. In de plaats daarvan komt een andere aanpak, per issue, vóórdat er één regel code geschreven wordt.
Twee vragen die eerst beantwoord moeten worden
De nieuwe aanpak draait om een sessie die ik /grill-with-docs noem: een gesprek met Claude Code over het probleem, niet over de oplossing. Daarin moeten twee vragen beantwoord zijn voordat implementatie start:
- Hoe bewijzen we straks dat het werkt?
- Welke foutscenario’s zijn er, en welke accepteren we bewust — en welke niet?
Dat klinkt bijna te simpel om een verandering te zijn, maar het effect is groter dan ik verwachtte. Als ik vooraf al moet benoemen wat “bewijs van functioneren” betekent, dwing ik mezelf om na te denken over wat er getest moet worden, in plaats van dat achteraf aan een reviewskill over te laten die dan zelf maar moet raden wat ik belangrijk vind. En als ik vooraf de foutscenario’s opschrijf — inclusief welke risico’s ik bewust níet afdek — dan is er achteraf geen open vraag meer die een review-agent moet gaan verzinnen. Hij hoeft alleen nog te toetsen: is aan de afgesproken voorwaarden voldaan, ja of nee.
Het is in essentie een verschuiving van kwaliteitscontrole naar kwaliteitsontwerp. Niet de vraag “wat is hier fout aan” achteraf, maar “wat zou hier fout kunnen gaan” vooraf. Dat scheelt niet alleen tokens, het scheelt ook een categorie fouten die een achteraf-review sowieso nooit had gevonden: fouten die ontstaan omdat niemand vooraf had vastgelegd wat “goed” precies inhield.
Waarom dit niet gratis is
Ik wil dit niet mooier maken dan het is. Het verbieden van de reviewskill is een bewust geaccepteerd risico, en dat heb ik ook zo vastgelegd. Een scherp vooraf-gesprek vangt geen fouten die pas tijdens de implementatie zelf ontstaan — een typefout, een verkeerd aangenomen library-gedrag, een edge case die niemand kon voorzien omdat hij niet uit de probleemstelling volgt maar uit de code zelf. Daar is de review-agent, met zijn vermogen om echt door duizenden regels te spitten, gewoon beter in dan een vooraf-gesprek ooit kan zijn.
Wat ik dus eigenlijk doe, is een ruil: minder brede, ongerichte controle achteraf, in ruil voor scherpere, gerichte keuzes vooraf. Die ruil is alleen verstandig als het vooraf-gesprek serieus wordt genomen — als het een generiek rijtje vragen wordt dat ik afvink zonder na te denken, verlies ik het beste van beide werelden in plaats van het beste van één.
De rest van de week bevestigde het patroon
Interessant genoeg zag ik ditzelfde thema terugkomen in ander werk deze week, zonder dat ik het toen als zodanig herkende. Bij een scriptreview voor een podcastaflevering werkte ik met mutatietests: na elke wijziging werden expres foutjes in de code geplant om te checken of de tests ze ook echt vingen. Dat is precies dezelfde logica — niet alleen vragen “is de test groen”, maar vooraf vastleggen wat de test zou moeten vangen, en dat dan verifiëren. Bewijs van functioneren, geoperationaliseerd.
Ook bij een eerdere fix, waarbij een checkout-guard werd toegevoegd om te voorkomen dat een script vanuit een verouderde git-checkout zou draaien, was de aanleiding hetzelfde soort denken: niet repareren wat er fout ging, maar vooraf het foutscenario benoemen en de guard bouwen die het onmogelijk maakt. Een lege-mappen-sweep die ongescopet bleek, is diezelfde week bewust verwijderd in plaats van gerepareerd — omdat repareren een vals gevoel van veiligheid had gegeven zonder het onderliggende risico weg te nemen.
Wat dit met me deed
Ik merk dat deze verschuiving een beetje ongemakkelijk voelt, en dat verrast me niet. Een review achteraf voelt als een vangnet: wat er ook misgaat, er is nog een laatste check. Vooraf beter nadenken voelt kwetsbaarder, want de verantwoordelijkheid ligt duidelijker bij mij. Als het misgaat, kan ik niet meer wijzen naar “de review heeft het niet gevonden” — ik heb zelf niet goed genoeg benoemd wat er getoetst moest worden.
Maar dat ongemak is volgens mij precies het punt. Een deel van waarom reviews zo lang en duur werden, is dat ik ze liet compenseren voor gebrek aan scherpte vooraf. Hoe vager de opdracht, hoe meer een review-agent moet gaan gissen naar wat er bedoeld werd — en gissen kost tokens. Scherper vooraf zijn is dus niet alleen goedkoper, het is ook eerlijker: het legt het gewicht daar waar het hoort, bij de vraag die ik stel, niet bij de controle die erna komt.
Deze blogpost is geschreven met AI-ondersteuning op basis van mijn dagelijkse journals en Claude Code sessiesamenvattingen uit het “365 Days of AI Code” experiment.