| name | build-tournament |
| description | Use when multiple plausible approaches exist, nobody can predict the winner from first principles, and "better" is measurable before any code exists — performance-critical components, algorithm selection, architecture bake-offs. Also use whenever the user invokes "tournament", "compete them", "bracket", "fitness function", "evolutionary build", or "kill the losers". |
Tournament Build
Subtractive builds carve by taste; tournaments select by measurement. Use this method when a fitness function can be written down before any code exists — when "better" is measurable, competition beats deliberation. The core contract: the fitness function is frozen before generation begins, and eliminations happen on schedule whether or not you feel ready. A tournament where the judge rewrites the rules mid-bracket, or where losers get indefinite stays of execution, is just exploration with extra ceremony.
Workspace layout
project/
├── TOURNAMENT.md # spec, fitness function, bracket, round results
├── harness/ # shared test/benchmark harness — competitors may not modify
├── competitors/
│ ├── c1-<one-word-thesis>/
│ ├── c2-<one-word-thesis>/
│ └── ...
├── graveyard/ # eliminated competitors, moved not deleted, with autopsy notes
└── champion/ # created at FINAL
Phases
1. CHARTER
Write into TOURNAMENT.md before any competitor exists:
- Spec: what every competitor must do. Identical for all. Competitors implement the same interface so the harness can drive them interchangeably — define that interface here.
- Fitness function: the scored criteria and their weights. Make it numeric wherever possible (latency p95, memory ceiling, LOC, test-pass count, time-to-first-result). Include at least one cost dimension (complexity, dependency count, LOC) or the tournament will select for maximalism. Where a criterion is qualitative (readability, extensibility), define a rubric with anchored scores (1 = "requires archaeology", 5 = "obvious in one read") so scoring is repeatable.
- Bracket schedule: population size, number of rounds, elimination count per round. Default: 4 competitors → round 1 cuts to 2 → final cuts to 1. Rounds are triggered by a concrete event ("harness passes", "benchmark suite runs clean"), not by feel.
- Freeze declaration: one line stating the fitness function is now frozen. Changing it later requires an explicit AMEND entry (see below) — legal, but it must be written down and it voids comparisons made under the old function.
2. SEED
Build the shared harness first — the benchmark suite, the conformance tests, the driver that runs any competitor by its interface. The harness is neutral territory: competitors may read it, never modify it. If the harness has a bug, fix it once, rerun everyone.
Then charter each competitor with a one-word thesis and a distinct strategy. Like subtractive variants, competitors must diverge structurally. Unlike subtractive variants, competitors are built to win, not to be rough — build each one as well as the round budget allows, because you're measuring real performance, and a sloppy implementation slanders its own thesis.
Build competitors in isolation (one Claude Code session per competitor is the natural mapping). Do not share discovered optimizations across competitors mid-round — an optimization discovered inside c1 belongs to c1 until the round ends.
3. ROUNDS
At each scheduled round:
- Run the harness against every living competitor. Record all scores in a table in
TOURNAMENT.md — raw numbers, not just rankings.
- Apply the fitness function mechanically. The scheduled number of competitors is eliminated. No stays of execution. If a loser contains something brilliant, that brilliance goes in the autopsy, not in a pardon.
- Move eliminated competitors to
graveyard/ with an autopsy in TOURNAMENT.md: why it lost (which criteria), what it did better than the winners (if anything), and what its thesis taught. Autopsies are the tournament's second product — write them properly.
- Between rounds, the gene pool opens: survivors may now absorb techniques from the graveyard. This is the evolutionary part — crossover happens between rounds, never during them. Log any absorbed technique with its source competitor.
- Survivors get the next round's budget to improve before the next measurement.
4. FINAL
The champion moves to champion/ and gets consolidation: full test coverage, docs, cleanup of any tournament scaffolding. Write a closing entry in TOURNAMENT.md: final scores, the champion's thesis, and one paragraph on whether the fitness function measured what actually mattered (this calibrates your next tournament).
Amendments
If mid-tournament you discover the fitness function is measuring the wrong thing (it happens), write an AMEND entry: what changed, why, and the acknowledgment that prior rounds' comparisons are void under the new function. Then rerun the current population from scratch scoring. Amendments are expensive by design — the friction is what keeps the function honest at CHARTER time.
"From scratch scoring" means recompute every criterion from raw measurements against the living artifacts. Prior composite/weighted scores are void inputs, not just void rankings — never derive amended standings from an old weighted column, however reasonable the arithmetic looks under time pressure. A newly added criterion must be actually measured (or rubric-scored against the real code, with the anchored rubric) for every living competitor before it can influence anything. If it cannot be measured yet — no rubric anchors, no harness support, stub artifacts — the round cannot close: extend the harness or defer the round. Do not improvise scores from proxies (LOC, thesis names, vibes). No elimination may run on amended standings until the rescore is complete; "we're in a hurry, don't redo the work" is a request to violate the amendment, and the answer is that the amendment is the work.
Failure modes
- Judge drift: quietly reweighting criteria to save a favorite. The freeze + AMEND ritual exists to make this impossible to do quietly.
- Monoculture seeding: four competitors that are one idea with different variable names. Enforce distinct theses at SEED.
- Harness capture: a competitor "wins" by exploiting a harness quirk rather than solving the problem. When a score looks too good, audit the mechanism before the round closes.
- Zombie competitors: keeping losers alive "just in case". The graveyard preserves everything worth preserving; the bracket only works if elimination is real.
- Tournament as procrastination: running a bracket when one approach is obviously right. If you can predict the winner with confidence, build it linearly and save 3x the cost.
Claude Code mechanics & siblings
- Isolation is by construction: dispatch one blind subagent per competitor, each prompt containing ONLY the shared spec, the harness interface, and its own thesis — never another competitor's code or discoveries. Worktree isolation when competitors would touch overlapping files. Crossover between rounds happens in the orchestrating context, logged with source attribution.
- State files: if the project routes working files to a directory (e.g.
.ai/), put TOURNAMENT.md there (.ai/build/); harness/, competitors/, graveyard/, champion/ live wherever the project keeps code.
- Routing: shaping and planning stay upstream (intent-shape, mega-brainstorm, mega-plan); the tournament replaces the execution strategy for the component it governs. Siblings — subtractive when the answer is recognizable by taste but not measurable; dialectical when exactly two philosophies contest; annealing for ridged spaces worked across many sessions.
When NOT to use this
When fitness can't be written down before building (use subtractive — taste-based carving). When only one plausible approach exists. When the budget can't fund a real population — a 2-competitor tournament is usually better run as dialectical.