The Boy Scout Rule Has a Speed Limit

Leave the code better than you found it — yes. But the noblest rule in software has a failure mode, and it looks like a one-line bugfix that arrives as a 600-line PR.

leave it cleaner30…within limits
Tom
Academic Professor of Software Heuristics
Mar 21, 2026
6 min read

The pull request was titled "Fix null check in invoice export." A one-line bug, genuinely. But the diff was 611 lines across 14 files, because on the way to the null check, the author had — with the very best intentions — renamed a confusing module, converted a class to the newer style, reordered some imports, deleted two unused functions, and modernized a loop that offended them. Every single change was an improvement. The reviewer approved it in despair rather than conviction, and when the export broke in production the following week, the culprit took hours to find: one of the "harmless" cleanups had changed an evaluation order that something, somewhere, silently depended on.

I keep this story on file because it's the perfect specimen of a good principle metastasizing. The principle is the Boy Scout Rule, and I want to defend it and fence it in the same essay.

The rule, as intended

The Boy Scout Rule entered our vocabulary through Robert C. Martin, adapting the scouting ethos: leave the campground cleaner than you found it. Applied to code: whenever you touch a file, make some small improvement beyond your immediate task. Fix the misleading name. Add the missing test. Delete the dead branch.

The economic argument is sound and, I'd argue, beautiful. Codebases decay by default — every rushed patch and every "temporary" hack raises the entropy — and scheduled cleanup ("we'll refactor next quarter") is the most reliably canceled meeting in software. The Boy Scout Rule replaces the big bang that never comes with a maintenance strategy that compounds: thousands of tiny improvements applied precisely where people are already working, which is precisely where improvements matter most. Code nobody touches doesn't urgently need to be clean; code touched weekly does, and the rule allocates effort there automatically.

I believe in the rule. I teach the rule. And yet.

Where good intentions become scope creep

The failure mode is that the rule bounds the direction of the extra work but not the amount. "Cleaner than you found it" is satisfied by fixing one typo — and also by a 600-line beautification crusade. Everything in between is left to temperament, and engineers, bless us, have temperaments.

Unbounded scouting fails in four specific ways:

It destroys the review. As I discussed in my piece on PR batch size, a reviewer's power comes from checking a diff against a stated intent. A mixed diff — one behavioral fix buried in fourteen files of tidying — forces the reviewer to classify every hunk before judging it. The one line that can break production is camouflaged by 610 that shouldn't. Camouflage is exactly the wrong property for risky lines to have.

It couples risk. When the mixed PR causes an incident, you can't revert the bugfix without reverting the cleanup, or vice versa. Small, single-intent changes are cheap to undo; braided ones must be unpicked.

It burns the blame trail. Tools like git blame and git bisect are archaeology instruments, and mass cosmetic edits are a sandstorm across the dig site. When every line of a file was "last touched" by a formatting pass, the question why does this line exist? gets harder for everyone, forever.

It invites Chesterton's fence. G.K. Chesterton's old parable: don't remove a fence until you know why it was put up. The odd-looking code you're tempted to "fix in passing" is sometimes load-bearing — a workaround for a vendor quirk, a deliberate evaluation order, a fix for an incident that predates you. The passing cleanup, done in the margins of another task, is exactly the context in which nobody checks. My invoice-export story is a fence story.

Notice what all four have in common: none of them say the cleanup was wrong. They say it was wrongly packaged.

A proportionality test

So where's the line? I offer three questions, in increasing order of importance.

Is it proportionate? The cleanup should be a rounding error against the main change — a rule of thumb I give students is that scouting should stay within shouting distance of ten percent of the diff. Fixing a name in a function you're already modifying: proportionate. Renaming a module from a one-line fix: that's not scouting, that's a land war.

Is it adjacent? Improve the campsite you're camping in — the function you're editing, the file you're already forcing the reviewer to load. The moment your cleanup pulls in files the actual task never touches, you've left scouting and entered roaming.

Is it separable — and if so, why isn't it separate? Behavior-preserving tidying and behavior changes answer different review questions and carry different risks. Kent Beck's Tidy First? discipline applies: if the cleanup is big enough to matter, it's big enough for its own commit — and if it's bigger than that, its own PR, which you can send first. A two-PR sequence ("tidy: extract and rename, no behavior change" followed by "fix: null check in export") takes ten extra minutes and would have saved my exporters their incident. The reviewer of PR one asks only "is this truly neutral?"; the reviewer of PR two sees one line, naked and reviewable.

There's also a fourth, softer question worth asking: do I understand why it's like this? If the ugliness might be a fence, the Boy Scout move isn't silent removal — it's a comment, a question to the author, or a TODO with a ticket. Scouts map terrain they don't yet understand; they don't bulldoze it.

When the campground needs a bulldozer

Some code is beyond incremental rescue — the haunted module everyone routes around, the file where every improvement fights twelve others. The Boy Scout Rule is honestly the wrong tool there, and pretending otherwise produces either despair or the 600-line "bugfix."

Big renovations deserve big-renovation treatment: a stated case, a design conversation, characterization tests pinned around existing behavior before restructuring, and a planned sequence of small PRs. The rule of thumb I use: the moment your "while I'm here" exceeds what a reviewer can verify in passing, it stops being a courtesy and becomes a project. Projects deserve daylight — tickets, discussion, sequencing — not smuggling.

And a word on the AI-era version of this temptation: assistants have made sweeping "improvements" nearly free to generate — ask for a bugfix, receive a renovation. Free to generate is not free to review, revert, or archaeologize. The proportionality test doesn't care who typed the diff.

The seminar summary

  1. Keep scouting, always. One small, adjacent improvement per task. The compounding is real; forfeit it and the campground rots.
  2. Cap it. If the cleanup approaches a tenth of the diff or wanders into untouched files, stop and split.
  3. Separate tidying from behavior. Different commits at minimum; separate PRs when either is nontrivial. Tidy-first beats tidy-alongside.
  4. Respect the fences. Before deleting odd code in passing, spend two minutes on git blame. If the answer isn't obvious, ask — in the PR, where the answer gets recorded.
  5. Escalate honestly. When incremental won't cut it, say so and propose the renovation as a project. Smuggled renovations get neither good review nor credit.

Leave the campground cleaner than you found it — one campsite at a time, with the ranger's eyes open, and never by burning it down on the way to fixing a tent peg.

refactoringboy-scout-rulescope-creepcode-review
Written by
Tom
Academic Professor of Software Heuristics · Firetrail review team
More Principles