Boris Cherny ship 10–30 pull requests per dag en schrijft in eigen hand vrijwel geen code meer. Dat getal verspreide zich in januari 2026 via developer-Twitter, en sindsdien heb ik teams er op de slechtste manier op reageren: tien Claude-sessies opstarten en tien keer zo veel chaos produceren.

De workflow doet ertoe. Maar wat hem effectief maakt is niet het aantal sessies.


Waarom dit serieus te nemen is

Cherny heeft Claude Code gemaakt en leidt het bij Anthropic. Daarvoor was hij Principal Engineer bij Meta. Hij is geen productiviteitsinfluencer die een week met AI heeft gespeeld — hij bouwde het gereedschap, gebruikt het op extreme schaal, en is openhartig over wat de aantallen werkelijk drijft.

Zijn beschrijving van zijn eigen setup: “verrassend gewoon.” Dat ene woord zou je moeten doen stoppen. Iemand die 25 PRs per dag ship en zijn workflow gewoon noemt, geeft daarmee het meest bruikbare signaal dat hij heeft gedeeld. De hefboom zit niet in een exotische configuratie. Die zit in gedisciplineerde fundamenten op schaal — en dat is precies het argument van deze post.


De fundamenten, vertaald naar .NET

Plan eerst, parallelliseer later

Cherny’s belangrijkste praktijk is Plan mode. Hij itereert totdat het plan solide is, daarna schakelt hij over op automatisch accepteren. Zijn formulering: een goed plan maakt de one-shot betrouwbaar.

Dit telt zwaarder in een CQRS/event-sourced codebase dan vrijwel overal elders. Er zijn vijf correcte manieren om een nieuw commando te bedraden in Clean Architecture, en twaalf varianten die compileren maar jouw domeineinvarianten schenden. Als je het plan overslaat en Claude “voeg een route-suspensiecommando toe” puur op zijn eigen inzicht laat interpreteren, krijg je iets dat bouwt, testen haalt en structureel verkeerd is.

Mijn praktijk: elke niet-triviale feature begint met een expliciete Plan mode-prompt die de bounded context benoemt, verwijst naar het dichtstbijzijnde bestaande commando als voorbeeld, en specificeert hoe “klaar” eruitziet voordat Claude één regel schrijft.

CLAUDE.md als institutioneel geheugen, niet als README

Cherny houdt zijn bestand onder ~2.500 tokens. Team-onderhouden. Logt fouten: “als Claude iets verkeerd doet, voeg het toe zodat het niet herhaalt.” Hij tagt collega’s’ PRs met @claude om review-learnings terug te voegen.

Voor een .NET enterprise-codebase betekent dit concreet. Niet een rondleiding door je mappenstructuur (dat kan Claude zelf lezen). De dingen die het werkelijk niet kan afleiden:

  • Bouwvlaggen: dotnet build -c Release om de debug-lockfiles van een ontwikkelaar niet te corrumperen.
  • Testuitsluitingen: dotnet test --filter "Category!=Integration" voor de binnenste loop; volledige suite alleen bij een schone run.
  • EF Core-migratieregels: nooit auto-genereren tegen het productieschema; altijd gericht op de ontwikkeldatabase; naamgevingsconventie voor migraties.
  • CQRS-bedrading: welke basisklassen je commando’s, queries en handlers uitbreiden; waar ze staan; hoe ze registreren. Eén voorbeeld is meer waard dan een alinea proza.
  • Branch-etiquette: nooit direct committen op de integratiebranche; locatie van het PR-template; verplichte reviewers.
  • De foutensectie: één regel per geleerde les. “Wikkel IMediator-aanroepen niet in een try/catch op de commandlaag — uitzonderingen borrelen door naar de globale handler.” Dat is het. Één keer toevoegen, nooit meer uitleggen.

Wat het bestand niet moet bevatten: API-documentatie, architectuurdiagrammen, de geschiedenis waarom je EF Core hebt gekozen, alles wat afleidbaar is uit de code. Snoeï meedogenloos. Een opgezwollen CLAUDE.md is slechter dan geen: het model leert hem te negeren.

Verificatielussen gekoppeld aan jouw toolchain

“Geef Claude een manier om zijn werk te verifiëren en het verbetert de kwaliteit 2–3×.” Dit is het meest bruikbare wat Cherny zegt, en het meest onderbenut in teams die ik spreek.

Voor .NET: dotnet build is je eerste gate (seconden, vangt de meeste structurele problemen). Unittests met --filter "Category!=Integration" zijn je tweede (snel, geen infrastructuur). Integratietests komen als laatste, nadat het plan is gevalideerd.

Op .NET Aspire kun je verder gaan. Het Aspire-dashboard legt servicegezondheid en gedistribueerde traces bloot. Ik heb een PostToolUse-hook die dotnet build draait na elke bestandswijziging en een slash command dat de volledige testsuite doorloopt voordat Claude een taak als gedaan beschouwt. Claude dat zijn eigen verificatielus niet haalt, vangt meer bugs dan elke review die ik doe.

Koppel verificatie in voordat je sessies opschaalt. Parallellisme zonder feedbacklussen vermenigvuldigt fouten even snel als het output vermenigvuldigt.

Automatiseer de binnenste loop voor jouw toolchain

Cherny heeft een slash command voor commit-push-PR. In Azure DevOps is het equivalent een skill die de gefilterde testsuite draait, een PR aanmaakt tegen de juiste doelbranche met het sprint-prefix in de titel, het werkitem koppelt en de verplichte reviewers instelt. Eenmalig schrijven, dagelijks de mechanische overhead besparen.

Zijn PostToolUse-hooks voor auto-formattering: voor .NET is dat dotnet format na bewerkingen, of csharpier als je team dat gebruikt. Één hook, nul handmatige formaatrondes.

Isolatie: worktrees, niet sessies op dezelfde tree

Hij houdt parallelle sessies in aparte git-checkouts. Het doel is isolatie — parallelle bewerkingen die nooit botsen. Git worktrees bereiken hetzelfde zonder opnieuw te klonen.

Voor .NET past dit precies op onafhankelijke bounded contexts. Een sessie die aan het fleet-tracking-aggregaat werkt en een sessie die aan de factuurmodule werkt, raken verschillende projecten, andere migraties, andere tests. Ze kunnen parallel draaien in worktrees zonder risico. Wat ze niet parallel kunnen doen: alles wat EF Core-migraties, Directory.Packages.props, gedeelde infrastructuurabstracties of je Azure Bicep-templates raakt. Dat is van nature enkelvoudig-threaded.


Waar het stukloopt voor een team

Cherny’s setup is geoptimaliseerd voor een solo-principal-engineer die ook de primaire reviewer is. Vier dingen veranderen op enterprise-schaal.

Half-gemigreerde codebases verergeren het probleem. Als je halverwege een migratie van .NET Framework naar .NET 8 zit, of halverwege de overstap van MassTransit 7 naar 8, ziet Claude beide patronen en aarzelt ertussen. De menselijke verwarring en de modelverwarring versterken elkaar. Rond migraties af voordat je sessies opschaalt — dit is het meest consequent onderschatte risico dat ik zie.

CLAUDE.md heeft een eigenaar nodig. In zijn solo-setup evolueert het bestand natuurlijk. In een team raakt het verouderd of accumuleert het tegenstrijdigheden. Wijs één persoon aan. Wij bespreken de onze in de sprint-retrospective: wat is verouderd, welke fout verdient een nieuwe regel, wat is omslachtig en kan worden geknipt.

MCP-servers, niet ad-hoc CLI. In Azure DevOps is de juiste integratielaag de MCP-server, niet ad-hoc az CLI-aanroepen waarbij Claude vlaggen raadt. Een getypeerd oppervlak met de juiste permissiescope, één keer bedraad, ten goede aan elke sessie. Dezelfde logica geldt voor GitHub. Sta veilige commando’s vooraf toe via /permissions voor al het overige.

Modeleconomie op teamschaal. Opus voor alle code is de keuze van een solo-IC. Voor een team van acht dat de hele dag sessies draait, is dat een echte budgetbeslissing. In de praktijk: Opus voor planning en complexe redenering; Sonnet voor routineimplementatie zodra het plan vergrendeld is. Meet waar de correcties optreden voordat je een modelbrede beleid vaststelt.


Wat ik daadwerkelijk draai op TrackJack

TrackJack is een vloot- en GPS-trackingplatform: .NET 9, CQRS met event-sourcing, EF Core, Azure DevOps, gedeployed op Azure.

CLAUDE.md staat ingecheckt en wordt besproken in de sprint-retrospective. EF Core-migratieregels, command/query-bedrading met één uitgewerkt voorbeeld elk, de verboden-patronen-sectie, en een lopende foutenlijst van momenteel elf vermeldingen.

Elke niet-triviale feature gaat eerst door Plan mode. Niet-onderhandelbaar in een event-sourced domein — de verkeerde aggregaatgrens is duur te herstellen, en Claude zonder briefing kiest op basis van naamheuristieken in plaats van domeinkennis.

De verificatielus is dotnet build && dotnet test --filter "Category!=Integration" in een PostToolUse-hook. Draait na elke bestandswijziging. Als het mislukt, ziet Claude de output en corrigeert zichzelf voordat de taak eindigt.

Drie MCP-servers: Azure DevOps voor PR- en werkitemintegratie, .NET Aspire voor live servicegezondheid tijdens ontwikkeling, en onze interne documentatieserver.

Parallelle sessies draaien op onafhankelijke bounded contexts in aparte worktrees. Infrastructuurwijzigingen — migraties, Bicep, gedeelde abstracties — zijn enkelvoudig-sessie en sequentieel.

Het deel dat nog niet volledig gelandt is: de PR-feedbacklus terug naar CLAUDE.md. Dat vereist een overeengekomen protocol voor wie wat toevoegt en wanneer. We werken ernaartoe.

De fundamenten werken. Het aantal sessies is het laatste wat je moet optimaliseren.