Uphill refactors allowed early on a fixed cooling schedule.
Source run full-1 at tdd-experiment c3dd988
Contents
Step size
What it changes: Accepts worse designs early then cools.
SilverFewest errorsE 4
One method of the study, from runs full-1. The survey build is the method's single build in run full-1. 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.
How it builds code
The procedure supplied to the agents. Indented lines run under the line above them.
Family: Step size. Idea: Uphill refactors allowed early on a fixed cooling schedule. What it changes in the search: Accepts worse designs early then cools.
throughout:2. Hot may move nouns and verbs. Warm moves verbs. Cold renames and extracts.3. Timebox and allowed rise: hot 45 min 20%. Warm 15 min 5%. Cold 5 min 0%.repeat per feature until none is open:1. Run classic TDD. Log energy per commit: PMD warnings plus jdeps class edges.4. After each green try at most one allowed move on a throwaway branch.5. Pick the move after which the next test needs the fewest changed lines to pass.6. Merge if energy does not rise. Merge a rise within budget with a one-line reason.7. Revert any move still red or over budget when its timebox ends.8. Cool one phase per third of the original test list. Stay cold after.
Once means one agent runs the steps. Repeat per unit means one agent per unit until no unit is open. Throughout means the rule joins every prompt. For up to n starts means separate attempts with the best kept. The harness does means the harness runs the step without an agent. If names the event that starts a stage, and with adds a rule borrowed from another method. Steps are quoted from args.json with their numbers. Tag: verified.
Figure 17.1
Stage flow of Annealed refactoring
Steps 2 and 3.Lane: Throughout.
Steps 1, 4 to 8.Lane: Agent.
Loop: repeat per feature, back to Steps 1, 4 to 8.
2 stages from the run facts, each checked against its block of the steps above. Details and notes are in the stage table. Tag: recomputed.
Loop: repeat per feature, back to Steps 1, 4 to 8.
Stages
Each stage as the run facts list it. Runs as and Note are quoted verbatim and Steps repeats the steps above. Tag: verified.
Stage
Runs as
Steps
Details
Note
Steps 2 and 3
throughout:
2. Hot may move nouns and verbs. Warm moves verbs. Cold renames and extracts. 3. Timebox and allowed rise: hot 45 min 20%. Warm 15 min 5%. Cold 5 min 0%.
none
The timeboxes are red-green cycles: hot 9, warm 3 and cold 1.
Steps 1, 4 to 8
repeat per feature until none is open:
1. Run classic TDD. Log energy per commit: PMD warnings plus jdeps class edges. 4. After each green try at most one allowed move on a throwaway branch. 5. Pick the move after which the next test needs the fewest changed lines to pass. 6. Merge if energy does not rise. Merge a rise within budget with a one-line reason. 7. Revert any move still red or over budget when its timebox ends. 8. Cool one phase per third of the original test list. Stay cold after.
unit feature
If TESTS.md is missing, first write the original test list to it with one line per planned test and commit it. Step 8 counts thirds of that list. Energy comes from ./run.sh lint and ./run.sh deps. A move is tried uncommitted in place of a throwaway branch and reverted with git restore.
Survey build
One build in run full-1.
15/15Functional mark
4E
910,035Cost to completion
625,663M
557,219M_io
2PMD findings
noAlignment
Verdict
One survey build. It passed every hidden test with 1 class, 2 PMD violations and adjusted mutation 0.983. Later commits rewrote 35 percent of the src lines it added, the second highest share of the survey after functions-first. One build cannot show whether that rewriting is typical of the method. Tag: recomputed.
Report summary
The report's class diagram for this design is identical to Figure 17.2 below, so it is shown once. Tag: recomputed.
Functional mark /15
15/15
Hidden pass /76
76/76
Unseen pass /69
69/69
Strict PMD compliance
fail (2 violations)
Mutation score
115/123, 0 not run, adjusted 115/117 (2 of 8 survivors fail hidden tests)
Classes
1
Simple Constructs /5
4
Minimal Duplication /5
4
Modular Structure /5
3
Problem Alignment (tentative) /5
3
Weighted tokens
958,093
Bench median ms
526
Score card
Survey tiles place the survey build among the single survey builds. One build per method describes that build and does not rank the methods. Contrast tiles are medians over the replicates. Tag: recomputed.
Adjusted mutation0.9835th highest of 11 single survey builds, one per method
Classes1joint 10th highest of 11 single survey builds, one per method
Cost to completion910,0354th lowest of 11 single survey builds, one per method
Strict PMD violations24th lowest of 11 single survey builds, one per method
Builds
Best, median and worst order a method's replicates by adjusted mutation, highest first, then lower cost to completion. The median build is the representative. Tag: recomputed.
Same family comes from the methods doc. Nearest and farthest average the rank differences over adjusted mutation, classes and cost to completion of the survey builds, over the metrics both methods have. Anchor Engineering has no survey build, so the replicate medians of adjusted mutation and classes stand in. Cost to completion leaves out such a method, since costs of a different batch do not compare. Tag: recomputed.
Branch method/annealed. 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.
Headline
Functional mark /15
15/15
Hidden pass /76
76/76
Unseen pass /69
69/69
Acceptance pass /6
6/6
Strict PMD compliance
fail (2 violations)
Recomputed from the grader's grade.tsv and summary.json and from metrics.json. The functional mark follows A02-RUBRIC.md: 2 for the original set with no failure, 3 per other set less one per failure, and 4 when every test passes. A02 is the course assignment whose spec and rubric the experiment uses. STA means anticlockwise and STC clockwise sowing. 6-4 and 7-5 are houses and seeds. A02-RUBRIC.md names the original set "Clockwise 6 Houses 4 Seeds". This page names each set by the spec folder its tests play, so the original set reads STA 6-4. Strict PMD compliance passes when PMD with the starter's kalah_pmd.xml finds no violation in src/ and otherwise fails with the count of distinct violations. The lint sets no minimum priority, so rules of every priority count. It covers src/ only, the scope of the starter's ./run.sh lint. A02-RUBRIC.md awards no marks for PMD, so the functional mark leaves it out.
Rubric set
Tests
Failures
Marks
Original set, STA 6-4
testST64SKHHSH_
0
2/2
STC 6-4
testSTC64SKHHSH_
0
3/3
STA 7-5
testST75SKHHSH_
0
3/3
STC 7-5
testSTC75SKHHSH_
0
3/3
All requirements
all tests
0
4/4
Summary metrics
Metric
Value
Tag
Total lines
227 (src 176, own tests 51)
recomputed
Lines of code
181 (src 143, own tests 38)
recomputed
Classes
1
recomputed
Methods
16
recomputed
Fields
3
recomputed
Bench median ms
526
recomputed
Bench volume
100614 inputs, 40083576 output chars
recomputed
Own tests leave out the starter's two Example tests and their ExampleSpec helper. Classes count top-level, nested and anonymous classes in src/.
Quality, costs and audit
Metric
Value
Tag
Mutation score
115/123, 0 not run, adjusted 115/117 (2 of 8 survivors fail hidden tests)
recomputed
PMD lines
1 (2 violations)
recomputed
Dependency edges
0
recomputed
Review scores (superseded)
Alterability 4.5, Code quality principles 3.9, Test quality 3
PMD lines count violations once per file and line. Agent time sums each agent's first to last timestamp, so agents that ran side by side add up. Weighted tokens count input 1, cache creation 1.25, cache read 0.05 and output 5 per token. These are claude-opus-5-5 prices relative to an input token and state no dollar cost. Costs, times and agent calls cover this clone only. The comparison row covers every clone of the method as its count basis states.
Review scores
A blind reviewer agent scored src/ and test/ from 1, worst, to 5, best, so the scores are unchecked. Reasons are the reviewer's own words, verbatim. This review is superseded by the blind rating of three raters in rating.json, whose medians fill the comparison's principle columns.
Reason: Sowing walks one fixed lap and the direction is only a mirror of the printed board, so the change touches just printBoard. That method has two clockwise branches, so the variant still needs edits in two places.
Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.
Reason: The variant is set by two ternaries for houseCount and seedCount. Every index, loop, border and capture formula comes from houseCount, so nothing else changes.
Reason: Formatting and indentation are consistent and the methods are short. The placement is a little loose: the static constant sits after the instance fields, and the helpers are not grouped by role (rules versus printing).
Reason: Names such as sow, capture, storeIndex and seedsInHouses are descriptive, and the short comments explain the lap layout. Bare idioms like 3 - player and 2 * houseCount - last have no named constant or helper.
Reason: Players and houses are 1-based throughout and are accessed uniformly through index/storeIndex. printBoard mixes that convention with direct pits[houseCount] and pits[pits.length - 1] lookups for the stores.
Code quality principles. Item: 4. Used Content. Score /5: 5.
Reason: Every field, constant and helper is used and no dead code remains. The starter's leftover stub output was removed.
Reason: Control flow is a simple loop with early returns, and the methods are small. The while(true) loop with continue and the long compound capture condition take a little effort to follow.
Reason: Helpers like repeat, houses, pit and store remove most repetition. printBoard still repeats the store-plus-houses row assembly in two mirrored if/else blocks.
Reason: All game state, rules and rendering sit in one class around a raw int array, with no board or player abstraction. Functions are single-purpose, but presentation and rules are not split into modules.
Code quality principles. Item: 8. Problem Alignment. Score /5: 3.
Reason: Domain terms like sow, capture, store and house appear in the code. Players are bare ints 1 and 2, the board is an index-arithmetic array, and clockwise exists only as a display flag, which hides the domain model.
Test quality. Item: Test quality. Score /5: 3.
Reason: Eleven clearly named, independent spec-driven tests pin the core rules: empty house, extra turn, skipping the opponent store, capture, no capture, game end and tie. Almost all run only on anticlockwise 6-4, and 7-5 plus clockwise are covered mostly by quit-at-start, so the variants are pinned only thinly.
Audit flags
0 high and 13 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.
Step log
Method agents wrote the LOG.md cells. Agent-written text is shown verbatim and unchecked. Words such as recomputed inside it are the agent's own and are not tags of this page. Its Measure lines describe measurement during the run. Harness scores were measured separately after the run. Agent text may quote git commit times in the host's local zone. Harness times are UTC. Agent, tokens and seconds are recomputed from transcripts by row time. A dash in Agent means no agent run spans the row.
Actions: Wrote UNITS.md (7 units) and TESTS.md (12 tests, hot 1-4). Red KalahTest.testQuitAtStartAnticlockwise64 then green by rendering the board and quitting. Energy at green 0 (PMD 0 + jdeps edges 0). Phase hot (test 1 of 12). One move tried: noun move to a single circular pits array, chosen because sowing for the next test becomes an index walk. A Board class was not tried because its edge would rise energy from 0, beyond any percentage budget. Move green, energy 0 to 0, merged. Ticked unit. Example tests left red as expected until later units.
Actions: Red KalahTest.testOneMovePassesTurnToP2 (spec test/specs/STA_6_4/one_move.txt) then green with a turn loop and an index walk sow. Energy at green 0 (PMD 0 + jdeps edges 0). Phase hot (test 2 of 12). One move tried: extract a houses(pits, player, descending) row verb from printBoard, chosen because the clockwise board in test 3 then only reorders rows. First try raised energy 0 to 3 (LineLength). Wrapped the line within the timebox and energy returned to 0, merged. Ticked unit. Conflict logged: Write and Edit strip trailing spaces that spec prompt lines need, so one sed call added them against the no-sed edit rule.
Actions: Cycle 1: red KalahTest.testQuitAtStartClockwise64 (spec test/specs/STC_6_4/quit_at_start.txt) then green with a clockwise branch in printBoard. Energy 0 (PMD 0 + jdeps edges 0). Phase hot (test 3 of 12). Move tried: noun move of HOUSES and SEEDS constants to houseCount and seedCount instance fields, chosen because test 4 then only sets two fields. First try rose 0 to 5 (LineLength), wrapped within the timebox, energy 0, merged. Cycle 2: red KalahTest.testQuitAtStartAnticlockwise75 (spec test/specs/STA_7_5/quit_at_start.txt) then green by setting the counts from sevenfive. Energy 0. Example testSimpleStart75 also turned green. First third done so cooled to warm. Move tried: extract index(player, house) verb shared by play and houses, chosen because test 5 then checks the chosen pit in one line. Energy 0 to 0, merged. Ticked unit. Spec files were made with cp and Edit on board lines only, which kept the prompt trailing space without sed.
Actions: Red KalahTest.testEmptyHouseAsksAgain (spec test/specs/STA_6_4/empty_house.txt) failing at the House is empty line, then green by checking the chosen pit and continuing the turn loop. Example testUseEmpty also turned green. Energy at green 0 (PMD 0 + jdeps edges 0). Phase warm (test 5 of 12). Move tried: verb change so sow returns the last sown pit, chosen because test 6 then needs only a store check on that pit. Energy 0 to 0, merged. Ticked unit. Conflict logged: Edit stripped trailing spaces on new prompt lines, so one sed call restored them in the spec, and one sed call ticked UNITS.md, both against the no-sed edit rule.
2026-10-16T00:13:26Z. Step: L1,4-8 iteration 5. Unit: Extra turn on the own store and wrapping past the opponent store. Tests added: 2. Cycles: 2. Sha: 085e054. Agent: annealed:L1,4-8#5. Tokens: 1388762. Seconds: 191.958.
Actions: Cycle 1: red KalahTest.testLastSeedInOwnStoreMovesAgain (spec test/specs/STA_6_4/extra_turn.txt) then green by keeping the turn when sow ends in the own store. Energy 0 (PMD 0 + jdeps edges 0). Phase warm (test 6 of 12). Move tried: verb change so sow takes player and house, chosen because test 7 then needs one skip check inside sow. Energy 0 to 0, merged. Cycle 2: red KalahTest.testSowingSkipsOpponentStore (spec test/specs/STA_6_4/wrap_past_store.txt, the opening of examples exactlapemptycapture.txt up to the 9-seed wrap, then a quit) then green by skipping the opponent store in sow. Energy 0. Phase warm (test 7 of 12). Move tried: extract a storeIndex(player) verb, chosen because the capture in test 8 then adds seeds to the store in one call. Energy rose 0 to 1 (TooManyMethods) against a 0 budget, reverted with git restore. Ticked unit. Conflict logged: the wrap spec was built with head and printf appends because Edit strips trailing prompt spaces, against the no-shell edit rule.
Actions: Cycle 1: red KalahTest.testLastSeedInEmptyOwnHouseCaptures (spec test/specs/STA_6_4/capture.txt, the README capture after P1 6 and P2 4) then green with a capture in play. Example testExactLapEmptyCapture also turned green. Energy rose 0 to 2 at green (PMD NcssCount and CyclomaticComplexity on play, jdeps edges 0), a TDD step and no move. Phase warm (test 8 of 12). Move tried: extract a capture(pits, player, last) verb, chosen because test 9 then adds one condition inside it. Energy 2 to 2 (CyclomaticComplexity gone, TooManyMethods in), merged. Cycle 2: red KalahTest.testNoCaptureWhenOppositeHouseEmpty (spec test/specs/STA_6_4/no_capture_opposite_empty.txt) then green by requiring seeds in the opposite house. Energy 2. Phase cold (test 9 of 12, second third done). Move tried: extract storeIndex(player), chosen because the game end scores in test 10 then read each store in one call. Energy 2 to 2, merged. Ticked unit. Deviation: TESTS.md test 9 says no capture after an exact lap, but an exact lap always seeds the opposite house, so the test checks the rule without a lap and the example covers the lap. Conflict logged: Write strips trailing prompt spaces, so one sed call per spec restored them and one sed call ticked UNITS.md, against the no-sed edit rule.
2026-10-16T00:18:32Z. Step: L1,4-8 iteration 7. Unit: Game end with scores and winner or tie. Tests added: 2. Cycles: 2. Sha: 69dd694. Agent: annealed:L1,4-8#7. Tokens: 963555. Seconds: 121.044.
Actions: Cycle 1: red KalahTest.testGameEndsWhenPlayerToMoveHasNoSeeds (spec test/specs/STA_6_4/game_end_winner.txt, copied from examples full_game2.txt because only a full game empties one side) then green by ending the game when the player to move has no seeds in houses and printing scores and the winner. Example testFullGame2 also turned green. Energy rose 2 to 3 at green (PMD class NcssCount, play NcssCount and TooManyMethods, jdeps edges 0), a TDD step and no move. Phase cold (test 10 of 12). Move tried: extract a printResult(io, pits) verb, chosen because the tie in test 11 then changes only the winner line. Energy 3 to 2, merged. Cycle 2: red KalahTest.testGameEndsInATie (spec test/specs/STC_6_4/game_end_tie.txt, copied from examples full_game_tie.txt) then green with a tie branch in printResult. Example testFullGameTie also turned green, so all 17 tests pass. Energy 2. Phase cold (test 11 of 12). Move tried: extract a printGameOver(io, pits, clockwise) verb shared by quit and the game end, chosen because test 12 then needs no game over change. Energy 2 to 2, merged. Ticked unit, no units left. Test 12 (one clockwise move on 7-5) has no unit and was not written.
Raw inputs
metrics.json
summary.json
grade.tsv
costs.json
steps.csv
audit.json
review.json
LOG.md
MEASURE.md
classdiagram.uml
classdiagram.png
classdiagram.svg
collect.tsv
rating.json
MEASURE.md
The method's measure agent answered its Measure line from LOG.md and git. Agent-written text is shown verbatim and unchecked. Words such as recomputed inside it are the agent's own and are not tags of this page. Its Measure lines describe measurement during the run. Harness scores were measured separately after the run. Agent text may quote git commit times in the host's local zone. Harness times are UTC.
# Measure: annealed refactoring
Sources are LOG.md rows 1 to 7 and git log from 46b06f8 to c0d87dd. GAP.md and ATTEMPTS.md do not exist in this clone. Energy is PMD violations under kalah_pmd.xml plus jdeps package edges, as recorded at each green and after each move. No check was rerun for this file.
## Energy per commit
| sha | kind | subject | energy |
|---|---|---|---|
| 540ed36 | green | Show the anti-clockwise 6-4 board and quit at start | 0 |
| c40e6e8 | move | Hold the board as one lap of pits | 0 |
| f7b9ae1 | green | Sow a chosen house and pass the turn | 0 |
| a918b2c | move | Extract the house row | 0 |
| e390b80 | green | Show the clockwise board | 0 |
| 1e72cc4 | move | Hold house and seed counts per game | 0 |
| ba5291b | green | Size the board from sevenfive | 0 |
| 3c81f86 | move | Extract the pit index | 0 |
| 9d12dcb | green | Ask again when the chosen house is empty | 0 |
| 840b308 | move | Return the last sown pit | 0 |
| b0b5cd3 | green | Give another move in the own store | 0 |
| e80f960 | move | Let sow take the player | 0 |
| bb69aa7 | green | Skip the opponent store when sowing wraps | 0 |
| f097997 | green | Capture the opposite seeds | 2 |
| fab8881 | move | Extract the capture | 2 |
| 69668af | green | Skip the capture when the opposite house is empty | 2 |
| 97025e1 | move | Extract the store index | 2 |
| 0db4474 | green | End the game and name the winner | 3 |
| 248d7f9 | move | Extract the result printing | 2 |
| fc063c1 | green | Announce a tie | 2 |
| 406ff81 | move | Extract the game over printing | 2 |
Starter kit, plan, tick and log commits change no code under src and carry the energy of the commit before them. Both rises (0 to 2 and 2 to 3) came from green steps. No committed move raised energy.
## Uphill moves
| measure | count |
|---|---|
| moves tried | 11 |
| moves merged | 10 |
| uphill on first try | 3 |
| uphill kept | 0 |
| uphill repaired to flat within the timebox and merged | 2 (a918b2c 0 to 3, 1e72cc4 0 to 5, both LineLength) |
| uphill reverted | 1 (storeIndex in iteration 5, 0 to 1 TooManyMethods, git restore) |
| downhill moves | 1 (248d7f9, 3 to 2) |
The schedule cooled from hot to warm after test 4 and to cold after test 9. The only uphill try in a warm phase was reverted against a 0 budget. The same storeIndex move merged flat in iteration 6 once energy was already 2.
## Final energy against the classic baseline
Final energy at 406ff81 is 2 (recorded in LOG.md iteration 7). The classic baseline is not present in this clone, so the comparison is made by the harness across arms. 11 of 12 planned tests were written. Test 12 has no unit. All 17 tests passed at the last green.
## Credits and time
Credits and wall time are measured by the harness. LOG.md timestamps span 2026-10-15T23:55:34Z to 2026-10-16T00:18:32Z over 11 red-green cycles.