CCLearn

Settle design arguments with three PRs, not a whiteboard

When a team disagrees about an approach, have Claude build the competing implementations as real PRs in separate worktrees and compare the diffs, instead of arguing it out in a design doc.

docs corroborate

The official documentation describes the mechanism this relies on. The technique itself is community practice.

What this costs you if it is wrong

Every prototype you open is review load on someone else. Three PRs nobody reads is worse than the five-minute conversation you skipped, and a diff only settles choices that show up in a diff: API shape, dependency, data model. It says nothing about operational cost, on-call burden, or who owns it in a year. Prototype branches also run real tooling: each worktree needs its own .env and dependency install, and a prototype hitting a staging database or a paid API does so three times over. Delete the losing branches deliberately; a half-built alternative left on the remote gets cargo-culted later.

Two engineers disagree about how a change should be structured. One wants an event bus, the other wants direct calls, and a third thinks both are premature. The default move is a doc: someone writes up the options, people comment for a week, and the decision gets made on prose about code that does not exist yet.

Build all three instead. Then read the diffs.

The mechanic

Give each candidate its own worktree so the branches never touch each other's files:

bash
claude --worktree proto-event-bus
claude --worktree proto-direct-calls
claude --worktree proto-inline

Each session gets the same spec and a different constraint:

text
Implement notification fan-out for order state changes, using an internal
event bus. Keep the change inside src/notifications/ and its tests. Do not
refactor callers beyond what the approach requires. Open a PR when the
existing test suite passes.

Then stop reading the arguments and read the shape:

bash
git diff --stat main...worktree-proto-event-bus
git diff --stat main...worktree-proto-direct-calls
git diff --stat main...worktree-proto-inline

The interesting number is usually not lines added. It is how many files outside the feature directory each option had to touch, and how many test files it broke.

What actually changes

Arguing in a docBuilding the candidates
Comparing descriptions of codeComparing code
Blast radius is assertedBlast radius is git diff --stat
"This will be hard to test" is an opinionThe test file either exists or it doesn't
Cheap to start, slow to endCosts three implementations up front
Works async, across teams, across time zonesNeeds someone to read three PRs
The losing option leaves no artifactThe losing branches are real and must be deleted

The last row cuts both ways. A rejected PR is a much better record of why than a paragraph in a doc — but only if you write down the reason before deleting the branch.

The bottleneck moves, it does not disappear

Producing three implementations does not make the decision free — it converts a writing problem into a reading problem. If your team cannot review three prototypes faster than it can argue for a week, you have not saved anything. Budget the review the way you would budget the doc:

  • Cap it. Two or three candidates, one feature directory, one shared test suite. Not /batch-scale fan-out.
  • Give every prototype the same acceptance criterion, so "it passes" means the same thing in each branch.
  • Timebox the prototypes so a candidate that is not working in an hour loses on that basis.
  • Have Claude summarize the three diffs against each other before humans open any of them, in one session that can read all three worktrees.

What the docs do and don't back

Every mechanism here is documented. Worktrees isolate parallel sessions so the edits never collide. A forked subagent exists specifically for when you "want to try several approaches in parallel from the same starting point." Checkpointing lists "exploring alternatives" as a use case. /batch already spawns worktree-isolated subagents that each open a pull request. Artifacts even offer to "lay out several design or implementation options side by side."

What the docs never say is that you should use any of this to resolve a disagreement between people. That step is a team norm, not a product feature, and nothing in the documentation claims prototypes should displace design docs.

What is unverified

The claim comes from a talk by an Anthropic engineering lead describing how one team — the Claude Code team — works. It is a report of a norm, not a measured result. Nobody has shown that teams which prototype decide better, or faster, or that the reviewers stay willing to read three PRs after the tenth time you do this. The transcript backing it is a community machine transcription, so treat the exact wording as approximate even where the substance holds.

What would settle it, on your own team: pick the next three design arguments, run one as a doc and two as competing branches, and record the wall-clock time from "we disagree" to "we merged something" plus whether the decision got reopened within a month. That is a measurement your team can make and the docs cannot.

Checkpoint

  • For the disagreement in front of you right now, would the answer show up in a git diff --stat? If not, this technique is the wrong tool.
    Show answer

    Only you can call this one, and the test is concrete: a diff settles what shows up in a diff — API shape, dependency, data model, and above all how many files outside the feature directory each option had to touch and how many test files it broke. It says nothing about operational cost, on-call burden, or who owns the thing in a year. If your disagreement is really about cost, ownership, or an audience who will never open the repo, a doc still wins, and building three branches spends three implementations answering a question they cannot answer.

  • Who is going to read the losing PRs, and have they agreed to?
    Show answer

    If you cannot name the person, the experiment is not planned yet. Producing three implementations converts a writing problem into a reading problem, and every prototype you open is review load on someone who did not agree to this. Ask the reviewers before you open anything, and say up front which candidate you expect to survive and that the other two are meant to be closed. Cap it at two or three candidates on one feature directory, and have Claude summarize the three diffs against each other — in one session that can read all three worktrees — before any human opens a PR.

  • Where does the reason the losers lost get written down before you delete the branches?
    Show answer

    Somewhere that outlives the branch: the PR description, the commit that lands the winner, or the short design note you were trying to skip. A rejected PR is a better record of why than a paragraph in a doc, but only if you write the reason down before deleting the branch. Then delete the losers deliberately — a half-built alternative left on the remote gets cargo-culted later, and one deleted with no recorded reason means the same argument reopens with no artifact left to point at.

Where this came from

Official pages that back this