Kalah TDD study · Part 1 of 29 · Introduction

12 ways to test-drive Kalah

An AI coding agent built the same Java Kalah game with each test-driven design. 6 awards pick the stand-outs.

Source runs full-1, tcp-1-list2, rep-1, rep-2 and tcp-1 at tdd-experiment c3dd988

Contents

The study

Classic greedy TDD writes the smallest failing test and then the smallest change that passes it. Do TDD variants that plan the class structure first, change the step size, try several starts or change how the tests check the code lead an AI coding agent to a better Kalah solution?

Best overall

Functions first, classes later

Test-drive pure functions.

12Designs
6Awards
40Replicate builds

Run ended 2026-10-16. Model Claude Opus 5.5 (claude-opus-5-5). Runs: full-1 survey, tcp-1-list2 list reliability, rep-1 planned contrasts, rep-2 planned contrasts. 11 survey methods. Claims carry a tag. Recomputed means redone from source data. Verified means checked against a primary source. Unchecked means written or judged by an agent and not checked.

The methods text on these pages is from methods doc 12f026f6. The runs this page names were built under these doc versions, by short sha256: full-1 64606950, tcp-1-list2 12f026f6, rep-1 12f026f6, rep-2 12f026f6, tcp-1 1f11dd37.

Read on with Experimental design and approach, Methodology: harness and protocol and Results: survey (full-1), or pick any of the 29 parts.

Awards

The first five awards rank the 11 full-1 survey builds, lower first, with ties sharing a place. The consistency badge covers seven replicated designs in rep-1 and rep-2. The full-1 survey ended 2026-10-16. A medal only styles a place and carries no score. M and M_io read curve.json, E sums the distinct PMD findings, adjusted surviving mutants, hidden failures and unseen failures, and alignment needs both the blind CQP rating agreeing with PMD and PMD reporting no issue. recomputed

Cheapest

Lowest cost to completion. A bronze badge that does not contribute to best overall.

Most consistent design

Lowest observed C among seven replicated designs. Exploratory. The global spread test did not detect a difference (p 0.464). Scope and limits.

Award places as the report states them
Best overall

Lowest sum of ranks on M, E and alignment. Ties use average ranks. Badges do not contribute.

  1. Gold Functions first, classes later, rank sum 11.0
  2. Silver Mapped-path TDD, rank sum 13.0
  3. Bronze Most informative next test, rank sum 14.5
Most cost effective

Lowest M among builds scoring 15/15. M_io recomputes the curve without output-token costs.

  1. Gold Functions first, classes later, M 470,362, M_io 441,270
  2. Silver Most informative next test, M 477,347, M_io 448,873
  3. Bronze Held-out TDD, M 519,499, M_io 443,244
Fewest errors

Lowest additive count of PMD findings, adjusted surviving mutants and hidden and unseen failures.

  1. Gold Mapped-path TDD, E 2
  2. Silver Annealed refactoring, E 4
  3. Joint third · Bronze Functions first, classes later, E 5
  4. Joint third · Bronze Property-based TDD, E 5
Best CQP/PMD alignment

CQP agrees with PMD on all eight principles and PMD reports no issue. Agreement limits.

  1. Gold Mapped-path TDD, mean rating median 4.0
Cheapest

Lowest cost to completion. A bronze badge that does not contribute to best overall.

  • Bronze badge Most informative next test, 708,760 weighted tokens
Most consistent design

Lowest observed C among seven replicated designs. Exploratory. The global spread test did not detect a difference (p 0.464). Scope and limits.

  • Bronze badge Most informative next test, C 0.38, p 0.464

Methods gives each method's scores. Columns under Supporting data defines each column and the Glossary under Scope and terms each short label.

The designs

One card per method in run order. Each gives the method's family and idea from the methods doc, its final clone's class diagram and its headline scores. A contrast arm with no survey run shows its representative replicate. The A02 reference comes last and apart.

Here each card gives a design's headline scores. Its page holds the full method card and class diagram.

Classic greedy TDD

Smallest failing test then smallest passing change.

One build, run full-1

Functional mark
15/15
E
10
Cost to completion
804,727

Noun-verb map

Plan classes from spec nouns and methods from verbs.

One build, run full-1

Functional mark
15/15
E
21
Cost to completion
918,336

Mapped-path TDD

Walk the map leaves first toward one acceptance test at a time.

Best overall, silverFewest errors, goldBest CQP/PMD alignment, gold

One build, run full-1

Functional mark
15/15
E
2
Cost to completion
2,058,511

Functions first, classes later

Test-drive pure functions.

Best overall, goldMost cost effective, goldFewest errors, bronze

One build, run full-1

Functional mark
15/15
E
5
Cost to completion
1,195,424

Coarse-to-fine TDD

One big step per feature.

One build, run full-1

Functional mark
15/15
E
6
Cost to completion
926,685

Annealed refactoring

Uphill refactors allowed early on a fixed cooling schedule.

Fewest errors, silver

One build, run full-1

Functional mark
15/15
E
4
Cost to completion
910,035

Multi-start TDD

Independent attempts on one locked suite.

One build, run full-1

Functional mark
15/15
E
20
Cost to completion
1,255,948

Most informative next test

Write the test that rules out the most wrong implementations.

Best overall, bronzeMost cost effective, silverCheapest, bronzeMost consistent design, bronze

One build, run full-1

Functional mark
15/15
E
9
Cost to completion
708,760

Property-based TDD

State rules over input regions.

Fewest errors, bronze

One build, run full-1

Functional mark
15/15
E
5
Cost to completion
1,171,669

Held-out TDD

Visible tests drive the loop.

Most cost effective, bronze

One build, run full-1

Functional mark
15/15
E
33
Cost to completion
801,898

Anchor Engineering

Write claims that must hold with their checks.

Median of 5 builds, run rep-1

Median adjusted mutation
1.000
Median classes
6
Median cost to completion
1,039,535

Headline

Correctness11 of 11methods with a full functional mark
Quality (CQP seam)3 of 11methods passing strict PMD compliance
Cost0.8 to 2.1 millionweighted tokens per method

The study has a survey and two contrast runs. A survey ran 11 methods once each in run full-1. Planned contrasts then ran 5 replicates each of four methods in run rep-1 and in run rep-2 of three new methods plus Classic greedy TDD, seven methods in all. Every build reached the functional ceiling of 15/15. In rep-1 Anchor Engineering scored a higher adjusted mutation score than Classic greedy TDD, all 5 replicates at 1.000 against a median of 0.984, with Holm p 0.016. The test did not detect a difference between Functions first, classes later and Noun-verb map (Holm p 0.548). In rep-2 the M tests did not detect a difference from Classic greedy TDD. Held-out TDD scored lower on adjusted mutation (Holm p 0.024) in this task and batch. recomputed

Figure 1.1

PMD violations against weighted tokens

Informs Q8 and Q11.

The 3 methods with no violation used 1.0 to 2.1 million weighted tokens, the other 8 used 0.8 to 1.3 million.

One mark per method, placed by the weighted tokens of all its clones and the PMD violations of its final clone. Labelled marks pass strict PMD compliance. The A02 reference has no token counts, so it has no mark. recomputed

024681000.511.522.5Weighted tokens, millionsPMD violationsclassic: 843,734 weighted tokens, 10 PMD violationsnoun-verb: 961,206 weighted tokens, 0 PMD violationsmapped-path: 2,126,219 weighted tokens, 0 PMD violationsfunctions-first: 1,273,066 weighted tokens, 0 PMD violationstpp: 1,291,180 weighted tokens, 7 PMD violationscoarse-to-fine: 969,366 weighted tokens, 6 PMD violationsannealed: 958,093 weighted tokens, 2 PMD violationsmulti-start: 1,295,799 weighted tokens, 5 PMD violationsmutation-guided: 760,686 weighted tokens, 9 PMD violationsproperty-based: 1,234,954 weighted tokens, 5 PMD violationsheld-out: 844,959 weighted tokens, 4 PMD violationsnoun-verbmapped-pathfunctions-first
BaselineStructure firstStep sizeSearch and validation
Data
Table view, 11 rows and 5 columns
MethodSlugFamilyWeighted tokensPMD violations
Classic greedy TDDclassicBaseline843,73410
Noun-verb mapnoun-verbStructure first961,2060
Mapped-path TDDmapped-pathStructure first2,126,2190
Functions first, classes laterfunctions-firstStructure first1,273,0660
Transformation Priority Premise TDDtppStep size1,291,1807
Coarse-to-fine TDDcoarse-to-fineStep size969,3666
Annealed refactoringannealedStep size958,0932
Multi-start TDDmulti-startSearch and validation1,295,7995
Most informative next testmutation-guidedSearch and validation760,6869
Property-based TDDproperty-basedSearch and validation1,234,9545
Held-out TDDheld-outSearch and validation844,9594

Figure 1.2

Adjusted mutation per replicate, rep-1

Informs Q12, Q13 and Q21.

Medians over each method's replicates: Functions first, classes later 0.927, Noun-verb map 0.964, Anchor Engineering 1.000, Classic greedy TDD 0.984.

One row per method in planned pair order. Each dot is one replicate build, the tick is the median and the whisker spans the lowest to the highest. The ringed dot is the representative build, the middle of five by adjusted mutation, then cost. Hollow diamonds are the single survey build of each method from the earlier full-1 run, a different batch. They stay out of every median, span and test. recomputed

0.70.80.91Adjusted mutation scoreFunctions first, classes laterFunctions first, classes later: median 0.927rep-1-r03: 0.848 adjusted mutationrep-1-r05: 0.992 adjusted mutationrep-1-r11: 1.000 adjusted mutationrep-1-r12: 0.927 adjusted mutationrep-1-r12: 0.927 adjusted mutationrep-1-r16: 0.841 adjusted mutationfunctions-first, full-1 survey build: 0.959 adjusted mutationFunctions first, classes later: median 0.927Noun-verb mapNoun-verb map: median 0.964rep-1-r07: 0.989 adjusted mutationrep-1-r10: 0.776 adjusted mutationrep-1-r13: 0.835 adjusted mutationrep-1-r19: 0.964 adjusted mutationrep-1-r19: 0.964 adjusted mutationrep-1-r20: 0.978 adjusted mutationnoun-verb, full-1 survey build: 0.807 adjusted mutationNoun-verb map: median 0.964Anchor EngineeringAnchor Engineering: median 1.000rep-1-r02: 1.000 adjusted mutationrep-1-r04: 1.000 adjusted mutationrep-1-r06: 1.000 adjusted mutationrep-1-r08: 1.000 adjusted mutationrep-1-r08: 1.000 adjusted mutationrep-1-r14: 1.000 adjusted mutationAnchor Engineering: median 1.000Classic greedy TDDClassic greedy TDD: median 0.984rep-1-r01: 0.992 adjusted mutationrep-1-r09: 0.993 adjusted mutationrep-1-r15: 0.981 adjusted mutationrep-1-r17: 0.903 adjusted mutationrep-1-r18: 0.984 adjusted mutationrep-1-r18: 0.984 adjusted mutationclassic, full-1 survey build: 1.000 adjusted mutationClassic greedy TDD: median 0.984
Functions first, classes laterNoun-verb mapAnchor EngineeringClassic greedy TDDSurvey build, earlier batch
Data
Table view, 23 rows and 4 columns
MethodBuildSourceAdjusted mutation
Functions first, classes laterrep-1-r03rep-1 replicate0.848
Functions first, classes laterrep-1-r05rep-1 replicate0.992
Functions first, classes laterrep-1-r11rep-1 replicate1.000
Functions first, classes laterrep-1-r12rep-1 replicate, representative0.927
Functions first, classes laterrep-1-r16rep-1 replicate0.841
Noun-verb maprep-1-r07rep-1 replicate0.989
Noun-verb maprep-1-r10rep-1 replicate0.776
Noun-verb maprep-1-r13rep-1 replicate0.835
Noun-verb maprep-1-r19rep-1 replicate, representative0.964
Noun-verb maprep-1-r20rep-1 replicate0.978
Anchor Engineeringrep-1-r02rep-1 replicate1.000
Anchor Engineeringrep-1-r04rep-1 replicate1.000
Anchor Engineeringrep-1-r06rep-1 replicate1.000
Anchor Engineeringrep-1-r08rep-1 replicate, representative1.000
Anchor Engineeringrep-1-r14rep-1 replicate1.000
Classic greedy TDDrep-1-r01rep-1 replicate0.992
Classic greedy TDDrep-1-r09rep-1 replicate0.993
Classic greedy TDDrep-1-r15rep-1 replicate0.981
Classic greedy TDDrep-1-r17rep-1 replicate0.903
Classic greedy TDDrep-1-r18rep-1 replicate, representative0.984
Functions first, classes laterfunctions-firstfull-1 survey build0.959
Noun-verb mapnoun-verbfull-1 survey build0.807
Classic greedy TDDclassicfull-1 survey build1.000

Key findings

All 11 methods score the functional mark 15/15, hidden 76/76, unseen 69/69 and acceptance 6/6. Only functions-first, mapped-path and noun-verb pass strict PMD compliance, as the reference does. The other 8 fail with 2 to 10 violations. The methods also differ in size, structure, mutation, cost, time, bench and rated code quality. recomputed

  • The 3 methods with no violation used 1.0 to 2.1 million weighted tokens, the other 8 used 0.8 to 1.3 million. recomputed PMD violations against weighted tokens
  • The 3 methods that pass strict PMD compliance have 6, 14 and 16 classes, and the other 8 have at most 5. recomputed PMD violations against classes
  • Mutation scores run from 75% (held-out) to 95% (mapped-path). recomputed Mutation score per method
  • Bench medians run from 205 ms (tpp) to 606 ms (held-out). recomputed Bench run times per method
  • Medians over each method's replicates: Functions first, classes later 0.927, Noun-verb map 0.964, Anchor Engineering 1.000, Classic greedy TDD 0.984. recomputed Adjusted mutation per replicate, rep-1
  • Medians over each method's replicates: Functions first, classes later 6, Noun-verb map 15, Anchor Engineering 6, Classic greedy TDD 2. recomputed Classes per replicate, rep-1
  • Medians over each method's replicates: Functions first, classes later 1,339,770, Noun-verb map 1,334,836, Anchor Engineering 1,039,535, Classic greedy TDD 1,033,995. recomputed Cost to completion per replicate, rep-1
  • Medians over each method's replicates: Functions first, classes later 15, Noun-verb map 16, Anchor Engineering 16, Classic greedy TDD 14. recomputed CQP per replicate, rep-1
  • Medians over each method's replicates: Held-out TDD 0.777, Classic greedy TDD 1.000, Coarse-to-fine TDD 1.000, Most informative next test 1.000. recomputed Adjusted mutation per replicate, rep-2
  • Medians over each method's replicates: Held-out TDD 3, Classic greedy TDD 1, Coarse-to-fine TDD 3, Most informative next test 3. recomputed Classes per replicate, rep-2
  • Medians over each method's replicates: Held-out TDD 973,901, Classic greedy TDD 1,011,641, Coarse-to-fine TDD 926,033, Most informative next test 1,068,727. recomputed Cost to completion per replicate, rep-2
  • Medians over each method's replicates: Held-out TDD 17, Classic greedy TDD 13, Coarse-to-fine TDD 16, Most informative next test 16. recomputed CQP per replicate, rep-2
  • Medians over each method's replicates: Held-out TDD 607308, Classic greedy TDD 601555, Coarse-to-fine TDD 559186, Most informative next test 735111. recomputed M per replicate, rep-2
  • Exploratory. Consistency scores C: Functions first, classes later 1.14, Noun-verb map 1.65, Anchor Engineering 1.06, Classic greedy TDD 0.87, Held-out TDD 0.96, Coarse-to-fine TDD 1.06, Most informative next test 0.38. The spread of C across methods gives permutation p 0.464. recomputed Consistency score per method
  • In the planned rep-1 contrast all 5 Anchor Engineering replicates reached adjusted mutation 1.000 against a median of 0.984 for Classic greedy TDD, exact Mann-Whitney U 25 and Holm p 0.016 over the two contrasts. Functions first, classes later and Noun-verb map did not differ, U 16 and Holm p 0.548. The CQP sensitivity check separated neither pair, Holm p 0.333. recomputed Findings table
  • In the planned rep-2 contrasts no survey leader differed from Classic greedy TDD on M, exact Mann-Whitney U 11 for Held-out TDD, 9 for Coarse-to-fine TDD and 17 for Most informative next test, each with Holm p 1.000 over the three contrasts. On adjusted mutation score, the fallback outcome, Held-out TDD scored lower than Classic greedy TDD, a median of 0.777 against 1.000, U 0 and Holm p 0.024. The other two leaders gave Holm p 1.000. recomputed Findings table
  • Over the seven replicated methods of rep-1 and rep-2 consistency score C runs from 0.38 for mutation-guided to 1.65 for noun-verb, and a permutation test of its spread across methods gives p 0.464. With 5 to 10 replicates each, no method is shown more consistent than another. recomputed Findings table
  • Output tokens per request rose from 148 in full-1 to 605 in rep-1, with an agent CLI change from 2.1.295 to 2.1.308 between the batches and identical prompts and launch scripts. So weighted-token costs of full-1 and rep-1 do not compare. rep-2 ran on CLI 2.1.309 at 495 output tokens per request. recomputed Findings table
  • Cache reads are 90.1 to 95.8 percent of each method's tokens. Weighted tokens count a cache read at 0.05, so they span 760686 to 2126219 while raw tokens span 4795045 to 19389975. recomputed Findings table
  • tpp and mapped-path parse the typed house with Integer.parseInt and no range check, so a non-number or a house off the board throws. The other 12 clones read through IO.readInteger with bounds. No example spec sends such input, both clones pass every hidden and unseen test and the README does not say what invalid input should do. verified Findings table

About the data

  • Awards rank the 11 survey builds of run full-1, one build per design.
  • Runs rep-1 and rep-2 made 40 repeat builds of 7 designs. Replicate medians and C come from them, and each design names its own runs and build counts.
  • Run tcp-1 is not ranked here. Five arms with one test-list order each for random, coverage, cost, risk and usage at seed 20261020.
  • Each run is its own batch, so costs from different runs do not compare.
  • The full research report is the full study report.

Terms

Functional mark
Marks out of 15 from the hidden course tests, scored as the A02 rubric does.
E
Errors: distinct PMD findings plus adjusted surviving mutants, those the hidden tests kill, plus failed hidden and unseen tests. Lower is better.
Cost to completion
Weighted tokens the agents spent to finish the build.
M
The trapezoidal checkpoint-area estimate of weighted-token cost per hidden test. Lower is better.
M_io
A sensitivity check that recomputes M without output-token costs.
Alignment
The blind code-quality rating agrees with PMD on every principle and PMD finds no issue.
C
Consistency score over repeat builds of one design. Lower means steadier results. Exploratory.
PMD
A static analysis tool for Java. A finding is one rule broken in one place.
Weighted tokens
Model tokens weighted by price: input 1, cache write 1.25, cache read 0.05, output 5.
APFDc-H
How early the hidden tests pass: the area under the hidden pass curve over weighted tokens spent, divided by the cost to completion.
CQP
Code Quality Principles, the course's design principles. A CQP score sums the blind rating's medians over four of them, 4 to 20.
Adjusted mutation
Surviving mutants missed by the hidden suite are excluded. They may be equivalent or expose gaps in that suite. Higher is better.
Planned contrast
A comparison of two designs fixed before the builds ran, tested over their repeat builds.
U
The exact two-sided Mann-Whitney statistic of a planned contrast: how many pairs of builds, one from each design, have this design's value above the other's, a tie counting half.
Holm
A correction that raises each contrast's p value, the chance of a gap this large with no real difference, so testing several contrasts at once keeps the false alarm rate at its usual level.

The glossary defines every term the study pages use.

Contents

All 29 parts in reading order, grouped as the sidebar groups them. Part numbers match the header of each page.

Introduction

  1. 12 ways to test-drive Kalah An AI coding agent built the same Java Kalah game with each test-driven design. 6 awards pick the stand-outs.

Approach

  1. Experimental design and approach The study question, the task, the runs and arms, their caps and where the study sits in the course.

Methodology

  1. Methodology: harness and protocol How each design runs: stages, prompts and agents, the held-out split, blind review and the audit.
  2. Methodology: measures Every metric with its formula, inputs and source module.
  3. Methodology: analysis and validity Award scoring, the statistical tests and the threats to validity.

Results

  1. Results: survey (full-1) One build of each design in the survey run full-1.
  2. Results: planned contrasts Planned contrasts over five replicates per arm in runs rep-1 and rep-2.
  3. Results: consistency across runs How much each design varies between replicate builds.
  4. Results: test order (tcp-1) One candidate test list built in five orders in run tcp-1.

Discussion

  1. Critical questions The questions the study set out to answer and the status of each answer.

Designs

  1. Classic greedy TDD Smallest failing test then smallest passing change.
  2. Noun-verb map Plan classes from spec nouns and methods from verbs. Fill linked stubs.
  3. Mapped-path TDD Walk the map leaves first toward one acceptance test at a time.
  4. Functions first, classes later Test-drive pure functions. Cluster them into classes later.
  5. Transformation Priority Premise TDD Pick tests the simplest ranked transformation can pass.
  6. Coarse-to-fine TDD One big step per feature. Drop a gear when it stalls.
  7. Annealed refactoring Uphill refactors allowed early on a fixed cooling schedule.
  8. Multi-start TDD Independent attempts on one locked suite. Score rule fixed first.
  9. Most informative next test Write the test that rules out the most wrong implementations.
  10. Property-based TDD State rules over input regions. Generators sample and shrink.
  11. Held-out TDD Visible tests drive the loop. Hidden tests measure overfitting.
  12. Anchor Engineering Write claims that must hold with their checks. Build milestones behind a mutation gate and a judge.
  13. A02 reference (not part of the comparison) The A02 reference build by a human with AI, shown beside the designs and not compared with them.

Reference

  1. Glossary Every term the study pages use.

Data

  1. Supporting data: findings The findings table and the audit flag dispositions.
  2. Supporting data: contrasts and replicates Contrast, consistency and replicate tables for rep-1 and rep-2.
  3. Supporting data: method table The method table, with each column linked to its measure.
  4. Supporting data: ratings List reliability and rating agreement for each run.
  5. Supporting data: run records The run records of full-1, rep-1 and rep-2.