Boris Cherny ships 10–30 pull requests a day and writes essentially zero lines of code by hand. That number spread across developer Twitter in January 2026, and since then I’ve watched teams respond in the worst possible way: spin up ten Claude sessions, produce ten times the chaos.
The workflow matters. What makes it work is not the session count.
Why this is worth your attention
Cherny created Claude Code and leads it at Anthropic. Before that he was a Principal Engineer at Meta. He is not a productivity influencer who dabbled with AI for a week — he built the tool, uses it at extreme volume, and has been candid about what actually drives the numbers.
His description of his own setup: “surprisingly vanilla.” That single word should stop you. A person shipping 25 PRs a day calling his workflow vanilla is the most useful signal he’s shared. The leverage is not in exotic configuration. It’s in disciplined fundamentals executed at scale — and that’s exactly the argument of this post.
The fundamentals, translated to .NET
Plan before you parallelize
Cherny’s most important practice is Plan mode. He iterates until the plan is solid, then switches to auto-accept. His framing: a good plan is what makes the one-shot reliable.
This matters more in a CQRS/event-sourced codebase than almost anywhere else. There are five correct ways to wire a new command in Clean Architecture, and twelve ways that compile but violate your domain invariants. If you skip the plan and let Claude interpret “add a route suspension command” from first principles, you will get something that builds and tests green and is structurally wrong.
My practice: every non-trivial feature starts with an explicit Plan mode prompt that names the bounded context, references the closest existing command as an example, and specifies what “done” looks like before Claude writes a single line. The plan becomes the brief; the brief becomes the constraint.
CLAUDE.md as institutional memory, not a README
Cherny keeps his under ~2,500 tokens. Team-maintained. Logs mistakes — “anytime Claude does something wrong, add it so it won’t repeat.” He tags coworkers’ PRs with @claude to fold review learnings back in.
For a .NET enterprise codebase this means something concrete. Not a tour of your folder structure (Claude can read that). The things it genuinely cannot infer:
- Build flags:
dotnet build -c Releaseto avoid corrupting a developer’s debug lock files. - Test exclusions:
dotnet test --filter "Category!=Integration"for the inner loop; full suite only on a clean run. - EF Core migration rules: never auto-generate migrations against the production schema; always target the dev database; migration naming convention.
- CQRS wiring: which base classes your commands, queries, and handlers extend; where they live; how they register. One example is worth a paragraph of prose.
- Branch etiquette: never commit to the integration branch; PR template location; required reviewers.
- The mistakes section: one line per learnt lesson. “Do not wrap
IMediatorcalls in a try/catch at the command layer — exceptions bubble to the global handler.” That’s it. Add it once, never explain it again.
What the file should not contain: API documentation, architecture diagrams, the history of why you chose EF Core, anything derivable from the code itself. Trim ruthlessly. A bloated CLAUDE.md is worse than none — the model learns to ignore it.
Verification loops wired to your actual toolchain
“Give Claude a way to verify its work and it will 2–3x the quality.” This is the single most actionable thing Cherny says, and the most underused in the teams I talk to.
For .NET: dotnet build is your first gate (seconds, catches most structural problems). Unit tests with --filter "Category!=Integration" are your second (fast, no infrastructure). Integration tests run last, after the plan is validated.
If you’re on .NET Aspire, you can go further. The Aspire dashboard exposes service health and distributed traces. I have a PostToolUse hook that runs dotnet build after every file edit and a slash command that kicks the full test suite before Claude considers a task done. Claude failing its own verification loop catches more bugs than any review I do.
Wire verification in before you scale sessions. Parallelism without feedback loops multiplies errors as fast as it multiplies output.
Automate the inner loop for your specific toolchain
Cherny has a slash command for commit-push-PR. That’s calibrated for GitHub. In Azure DevOps, your equivalent is a skill that runs the filtered test suite, creates a PR against the right target branch with the sprint prefix in the title, links the work item, and sets the required reviewers. It takes twenty minutes to write once and saves the mechanical overhead every single day.
His PostToolUse hooks for auto-formatting: for .NET that’s dotnet format after edits, or csharpier if your team uses it. One hook, zero manual format runs. The model produces consistently formatted code from the start rather than accumulating diff noise.
Isolation: worktrees, not sessions on the same tree
He keeps parallel sessions in separate git checkouts. The goal is isolation — parallel edits that never collide. Git worktrees achieve the same thing without cloning again.
For .NET this maps cleanly to independent bounded contexts. A session working on the fleet-tracking aggregate and a session working on the invoice-generation module touch different projects, different migrations, different tests. They can run in parallel worktrees without risk. What they cannot do in parallel: anything that touches EF Core migrations, Directory.Packages.props, shared infrastructure abstractions, or your Azure Bicep templates. Those are single-threaded by nature.
Where it breaks for a team
Cherny’s setup is optimized for a solo principal engineer who is also the primary reviewer. Four things change at enterprise scale.
Half-migrated codebases compound the problem. If you’re mid-migration from .NET Framework to .NET 8, or halfway through moving from MassTransit 7 to 8, Claude sees both patterns and hedges between them. The human confusion and the model confusion reinforce each other. Finish migrations before you scale sessions — this is the most consistently underestimated risk I see.
CLAUDE.md needs an owner. In his solo setup the file evolves naturally. In a team it gets stale or accumulates contradictions. Assign one person. We review ours in the sprint retrospective: what’s outdated, what mistake deserves a new line, what’s verbose and can be cut.
MCP servers, not ad-hoc CLI. In Azure DevOps the right integration layer is the MCP server, not ad-hoc az CLI calls where Claude guesses flags. A typed surface with the right permission scope, wired once, benefits every session. Same logic applies to GitHub. Pre-allow safe commands via /permissions for everything else.
Model economics at team scale. Opus for all coding is a solo IC’s call. For a team of eight running sessions all day, that’s a real budget decision. In practice: Opus for planning and complex reasoning; Sonnet for routine implementation once the plan is locked. Measure where the corrections happen before committing to a blanket model policy.
What I’m actually running on TrackJack
TrackJack is a fleet and GPS tracking platform: .NET 9, CQRS with event-sourcing, EF Core, Azure DevOps, deployed on Azure.
CLAUDE.md is checked in and reviewed in the sprint retro. EF Core migration rules, command/query wiring patterns with one worked example each, the forbidden patterns section, and a running mistakes list currently at eleven entries.
Every non-trivial feature goes through Plan mode first. Non-negotiable in an event-sourced domain — the wrong aggregate boundary is expensive to undo, and Claude without a brief picks one based on naming heuristics rather than domain knowledge.
The verification loop is dotnet build && dotnet test --filter "Category!=Integration" in a PostToolUse hook. Runs after every file edit. If it fails, Claude sees the output and self-corrects before the task ends.
Three MCP servers: Azure DevOps for PR and work item integration, .NET Aspire for live service health during development, and our internal documentation server.
Parallel sessions run on independent bounded contexts in separate worktrees. Infrastructure changes — migrations, Bicep, shared abstractions — are single-session and sequential.
The part not yet fully landed: the PR feedback loop back into CLAUDE.md. It needs an agreed protocol for who adds what and when. We’re working toward it.
The fundamentals work. The number of sessions is the last thing you should optimize.