Write claims that must hold with their checks. Build milestones behind a mutation gate and a judge.
Source runs full-1, rep-1 and rep-2 at tdd-experiment c3dd988
Contents
Search and validation
What it changes: The check. Anchors and their criteria gate each milestone.
No award in this survey.
One method of the study, from runs full-1 and rep-1. The survey build is the method's single build in run full-1. A replicate is one of its builds in run rep-1, which ran in a different batch. 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.
rep-1 contrast arm, no survey run. Family: Search and validation. Idea: Write claims that must hold with their checks. Build milestones behind a mutation gate and a judge. What it changes in the search: The check. Anchors and their criteria gate each milestone.
throughout:7. Keep the Book current as the code changes. Log each decision and mark each milestone done.once:1. Write the Anchor Book ANCHORS.md at the clone root from README.md and docs/SPEC.md. It holds the design, each anchor as a claim that must hold about the system, the criterion that verifies it, and the planned chunks of work as milestones.2. Check each anchor against the others and the spec. Log each conflict and the decision taken in the Book.repeat per milestone until none is open:3. Per milestone, turn each of its anchors into tests that check it. Record in the Book which tests verify which anchor. Test names describe behaviour and carry no anchor ids.4. Write code until those tests pass, in an agent test and fix loop.5. Run the deterministic gate: ./run.sh test, ./run.sh lint and ./run.sh mutate. Add tests for surviving mutants that break an anchor.6. Review the milestone as a judge for structure and correctness against its anchors. Fix what the review finds.
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 22.1
Stage flow of Anchor Engineering
Step 7.Lane: Throughout.
Once: steps 1 and 2.Lane: Agent.
Next: Steps 3 to 6.
Steps 3 to 6.Lane: Agent.
Loop: repeat per milestone, back to Steps 3 to 6.
3 stages from the run facts, each checked against its block of the steps above. Details and notes are in the stage table. Tag: recomputed.
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
Step 7
throughout:
7. Keep the Book current as the code changes. Log each decision and mark each milestone done.
none
none
Once: steps 1 and 2
once:
1. Write the Anchor Book ANCHORS.md at the clone root from README.md and docs/SPEC.md. It holds the design, each anchor as a claim that must hold about the system, the criterion that verifies it, and the planned chunks of work as milestones. 2. Check each anchor against the others and the spec. Log each conflict and the decision taken in the Book.
none
none
Steps 3 to 6
repeat per milestone until none is open:
3. Per milestone, turn each of its anchors into tests that check it. Record in the Book which tests verify which anchor. Test names describe behaviour and carry no anchor ids. 4. Write code until those tests pass, in an agent test and fix loop. 5. Run the deterministic gate: ./run.sh test, ./run.sh lint and ./run.sh mutate. Add tests for surviving mutants that break an anchor. 6. Review the milestone as a judge for structure and correctness against its anchors. Fix what the review finds.
unit milestone
none
Replicates
Repeat builds: 5 in run rep-1.
1.000Median adjusted mutation, over 5 replicates in rep-1
6Median classes, over 5 replicates in rep-1
1,039,535Median cost to completion, over 5 replicates in rep-1
16Median CQP, over 5 replicates in rep-1
against Classic greedy TDD: U 25, Holm p 0.016Planned contrast, exact, Holm, rep-1
1.06Consistency score C, exploratory over rep-1 and rep-2, lower is more consistent
Verdict
No survey build and 5 replicates in rep-1. All 5 reached adjusted mutation 1.000 and passed strict PMD compliance with 5 to 8 classes. In the planned contrast it scored higher than Classic greedy TDD, U 25 and Holm p 0.016, while the CQP sensitivity check did not separate the pair. Its steps are the experimenters' own reading of the post Principles of Anchor Engineering. Tag: recomputed.
Report summary
Figure 22.2
Class diagram of rep-1-r08, the representative replicate
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.
Median adjusted mutation1.000over 5 replicates in rep-1
Median classes6over 5 replicates in rep-1
Median cost to completion1,039,535over 5 replicates in rep-1
Median CQP16over 5 replicates in rep-1
Planned contrastagainst Classic greedy TDD: U 25, Holm p 0.016exact, Holm, rep-1
Consistency score C1.06exploratory over rep-1 and rep-2, lower is more consistent
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/rep-1-r02. 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
pass
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
757 (src 272, own tests 485)
recomputed
Lines of code
609 (src 211, own tests 398)
recomputed
Classes
5
recomputed
Methods
28
recomputed
Fields
10
recomputed
Bench median ms
498
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
126/132, 0 not run, adjusted 126/126 (0 of 6 survivors fail hidden tests)
recomputed
PMD lines
0 (0 violations)
recomputed
Dependency edges
8
recomputed
Review scores (superseded)
Alterability 5, Code quality principles 4.5, Test quality 4
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: Direction is treated as a mirror of the drawing. One boolean in BoardView picks the row order, and Board and Game have no direction code at all. A change to direction touches one small branch in one class, and it combines freely with any board size.
Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.
Reason: Board size lives in Variant.from as one ternary of house and seed counts. Board, BoardView and Game all derive everything from houseCount, so supporting 7-5 or another size is a one-line change.
Reason: Files are short and consistently indented, with methods ordered from public to private helpers. Line length is controlled and the layout makes related elements easy to see.
Reason: Class Javadocs state each class's intent, and names such as sow, captureAt, hasMoves and toHouse are clear. Some literals stay unexplained: 3 - player is used for the opponent and 2 * houseCount - pit for the opposite pit. The changed play() Javadoc also no longer describes sowing direction.
Reason: Loops are flat with early returns. The circular pit array and the skip-store loop are compact, but the index arithmetic in captureAt and the own-house range check take some effort to verify.
Reason: The source has almost no repetition, apart from 3 - player appearing in several places without a named opponent helper. The tests repeat the FULL_GAME move list, a seed-total loop and a board-initialisation assertion across files.
Reason: Responsibilities are clearly split. Board holds rules and state with no output, BoardView handles rendering, Game runs the turn loop with IO, Variant handles sizing, and Kalah wires them together. Dependencies are minimal and fields are private.
Code quality principles. Item: 8. Problem Alignment. Score /5: 4.
Reason: Board, house, store, sow and capture follow the domain closely. Modelling clockwise as only a display mirror is valid but implicit, and only the class comments explain it, so a reader looking for sowing direction will not find it in the rules.
Test quality. Item: Test quality. Score /5: 4.
Reason: Tests cover sowing, wrap-around, extra moves, captures, the no-capture case, scoring, all three end results, invalid input, quit, both layouts and both sizes, with a spec file run in each of the four variants. Names are descriptive and cases are independent. Some move scripts were found by search and their expected values are opaque, and fixtures are duplicated.
Audit flags
0 high and 2 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 ANCHORS.md from README.md and docs/SPEC.md with the example specs as format authority. Design, 26 anchors with criteria, five milestones. Conflict check logged C1 to C11 with decisions. No code or tests in this stage, so no ./run.sh call. Standing guidance asks for tests with each change; the step asks for the Book only, so the step was followed
Actions: Wrote UNITS.md with five milestone lines and committed it. Wrote BoardTest and VariantTest from R1 to R9 and saw them fail to compile, then wrote Board and Variant until they passed. Gate: ./run.sh test green for M1 classes with the six example tests red on the stub as expected, lint clean outside the stub Kalah.java after renaming Variant.of to from, mutate left one real survivor (house 1 excluded from the own side) which got a wrap-capture test found with a Python search in .scratch, and two equivalent survivors logged in the Book. Judge review renamed one local. Test map, decisions and M1 done recorded in ANCHORS.md. Lint and mutate were each run twice because the first output was trimmed
Actions: Wrote BoardViewTest from O2 to O5 and O7 with exact spec lines for 6 and 7 houses in both layouts and saw it fail to compile, then wrote BoardView until it passed. Gate: ./run.sh test green for BoardTest, BoardViewTest and VariantTest with the six example tests red on the stub as expected, lint clean outside the stub Kalah.java, mutate killed every BoardView mutant and left only the two equivalent Board survivors from M1. Judge review extracted the repeated house edge into HOUSE_EDGE, after which BoardViewTest and lint were re-run green. Test map, decisions and M2 done recorded in ANCHORS.md. Lint ran three times because the first output was trimmed to the stub lines
2026-10-26T11:01:23Z. Step: L3-6 iter 3. Unit: M3 Game and Kalah.play. Tests added: 7. Cycles: 1. Sha: 2a5c59c. Agent: rep-1-r02:L3-6#3. Tokens: 1181179. Seconds: 300.17.
Actions: Wrote GameTest with the ScriptedIO double from G1, G3, G4, G6, O1, O6 and C9 and saw it fail to compile on the missing IO.readTextFile, then fail on the stub. Wrote Game and wired Kalah.play until it passed. C9 settled on readFromKeyboard with the full prompt. Gate: ./run.sh test green except testFullGame2 and testFullGameTie, which need the M4 game end. quit, useempty, simple_start and exactlapemptycapture now pass. Lint flagged two long lines in Kalah which were wrapped, then clean. Mutate survivors are two in main(), one equivalent range check in Game.toHouse and the two M1 Board survivors, none breaking an anchor. Judge review found no fix. Test map, decisions and M3 done recorded in ANCHORS.md. Lint ran twice because the first output was trimmed
Actions: Wrote GameEndTest from G2, G5, R9 and G6 with the full_game2 and full_game_tie move lists and an 11 move P1 win found by a seeded random search in .scratch, and saw all five fail on the endless loop. Made the Game loop run while the mover has moves and added the score and result lines. Gate: ./run.sh test green for every class including both full game examples, lint clean, mutate left one new equivalent survivor in the winner choice plus the five M3 survivors, none breaking an anchor. Judge review found no fix. Test map, decisions and M4 done recorded in ANCHORS.md
2026-10-26T11:12:51Z. Step: L3-6 iter 5. Unit: M5 All four variants. Tests added: 5. Cycles: 2. Sha: c0e7ed9. Agent: rep-1-r02:L3-6#5. Tokens: 1759965. Seconds: 413.864.
Actions: Wrote one hand computed scenario (extra move, empty house, sowing past the store, capture, quit) as capture_after_extra_move.txt in each of the four variant folders under test/ and VariantSpecTest to play them. First run was red because the Write and Edit tools strip trailing spaces from the prompt lines, so sed restored them. This conflicts with the no sed edits guidance and the step had no other way. Then green with no production change. Gate: ./run.sh test green for all eight classes, lint clean, mutate 126 of 132 with the same six M4 survivors and one timeout, none breaking an anchor. ./run.sh deps and ./run.sh specs test were also run for the X4 and X3 criteria in the Book, which the step does not name. Judge review found no 7-house natural end test, fixed with a 15 move 7-5 game from a seeded search in an independent Python simulator in .scratch, played in both directions. Test map, decisions and M5 done recorded in ANCHORS.md
Class diagram
Class diagrams show class names and relations only. A solid line ending in a hollow triangle points to a parent class and a dashed one to an implemented interface. A line with a diamond at the owning class marks a field and a plain arrow a use. Method and field totals are in the tables.
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
Method is Anchor Engineering. Sources are LOG.md, git log, ANCHORS.md and UNITS.md. GAP.md and ATTEMPTS.md do not exist. Credits and time are measured by the harness and are not recorded here.
## Mutation score at each gate
Only the M5 gate logged a total. The earlier gates logged survivors by name.
| Gate | Score | Survivors | Source |
|---|---|---|---|
| M1 Variant and Board | no total logged | one real survivor (house 1 excluded from the own side) killed by a new wrap capture test. Two equivalent survivors on the own-house check remain | LOG.md iter 1, ANCHORS.md decision log |
| M2 BoardView | no total logged. Every `BoardView` mutant killed | the two equivalent M1 `Board` survivors | LOG.md iter 2 |
| M3 Game and Kalah.play | no total logged | five. Two in `main()`, which grading never calls. One equivalent range check in `Game.toHouse`. The two M1 survivors | LOG.md iter 3 |
| M4 Game end | no total logged | six. One equivalent `>` to `>=` in the winner choice plus the five M3 survivors | LOG.md iter 4 |
| M5 All four variants | 126 of 132 (95.5%) with one timeout | the same six as M4. None breaks an anchor | LOG.md iter 5, ANCHORS.md decision log |
## Anchors with a passing test
26 anchors in four groups. Rules R1 to R9, game flow G1 to G6, output O1 to O7 and constraints X1 to X4.
| Measure | Count |
|---|---|
| Anchors with a Test map entry | 26 of 26 |
| Anchors held by a JUnit test | 24 of 26 |
| Anchors held by a CI check only | 2 of 26. X2 by the `--release 8` compile plus a grep of `src/`. X4 by `./run.sh lint` and `./run.sh deps` |
The last logged gate (M5) ran `./run.sh test` green for all eight classes. The M5 judge fix added the 7-5 natural end test in the same commit c0e7ed9. This call ran no checks, so the pass status is as logged.
## Decisions and conflicts logged
| Kind | Count | Where |
|---|---|---|
| Spec conflicts with decisions | 11 (C1 to C11) | ANCHORS.md conflict check. C9 was left partly open in s1 and settled in M3 |
| Decision log rows | 17 | ANCHORS.md decision log. Book, conflict check, then done, gate and judge review for each of M1 to M5 |
| Conflicts between a step and standing guidance | 3 | LOG.md. s1 wrote the Book with no tests. M5 used sed to restore trailing spaces in spec files. M5 also ran `./run.sh deps` and `./run.sh specs test`, which the step does not name |
## Judge findings found and fixed
| Gate | Found | Fixed | Finding |
|---|---|---|---|
| M1 | 1 | 1 | local `score` inside `score()` renamed `total` |
| M2 | 1 | 1 | repeated `-------+` edge made the constant `HOUSE_EDGE` |
| M3 | 0 | 0 | none |
| M4 | 0 | 0 | none |
| M5 | 1 | 1 | no 7-house natural end test. Added a 15 move 7-5 game played in both directions |
| Total | 3 | 3 | |
## Work totals
| Measure | Value |
|---|---|
| Milestones done | 5 of 5 |
| Red-green cycles | 7 (2, 1, 1, 1, 2) |
| Tests added | 33 (11, 5, 7, 5, 5) |
| Commits before this file | 14 including the starter kit |
| Credits and time | measured by the harness |
Branch method/rep-1-r04. 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
pass
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
843 (src 348, own tests 495)
recomputed
Lines of code
692 (src 265, own tests 427)
recomputed
Classes
7
recomputed
Methods
41
recomputed
Fields
8
recomputed
Bench median ms
579
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
140/145, 0 not run, adjusted 140/140 (0 of 5 survivors fail hidden tests)
recomputed
PMD lines
0 (0 violations)
recomputed
Dependency edges
14
recomputed
Review scores (superseded)
Alterability 5, Code quality principles 4.5, Test quality 4
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 order is the same index walk in both directions, so direction reduces to which BoardPrinter layout is picked. The change lives in two small layout subclasses and one select call, and it combines freely with any Variant.
Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.
Reason: House and seed counts live only in Variant.select. Board indexing and printer widths come from houseCount(), so any size works with either layout without further edits.
Reason: Names such as captureAt, hasMoves and storeIndex are descriptive, and the class Javadocs give the pit-order rationale. The play() Javadoc recasts clockwise as a layout choice without saying that sowing direction follows from it, and the 3 - player and index arithmetic carry no explanation.
Reason: Static select factories, package-private visibility and naming are uniform throughout. Game uses two sentinel styles, the QUIT constant of -1 and a bare 0 from parseHouse.
Code quality principles. Item: 4. Used Content. Score /5: 5.
Reason: Every class and method is used, and the starter's placeholder output is removed. The test-only Board constructor is documented as such and the tests use it heavily.
Reason: Loops and conditionals are flat with early returns. The modular index arithmetic in move and captureAt is compact but takes some thought, and the play loop uses while(true) with several returns.
Reason: Row building, border widths and number formats sit once in BoardPrinter, and each layout differs only in its arguments. The two player perspectives share the same Board code through index helpers.
Reason: Responsibilities split cleanly: Variant holds the counts, Board the rules with no I/O, BoardPrinter and its layouts the rendering, Game the turn loop and Kalah the wiring. Dependencies are narrow and point one way.
Code quality principles. Item: 8. Problem Alignment. Score /5: 4.
Reason: Domain terms such as houses, stores, captures and players map directly onto the code. Treating direction as a print layout is valid but less obvious to a reader who expects a sowing-direction concept tied to the clockwise flag.
Test quality. Item: Test quality. Score /5: 4.
Reason: The tests cover sowing, store skipping, captures for both players, laps, extra turns, game end and all four play() variants, with descriptive names and independent fixtures. The anticlockwise-only GameTest and a reflective concat helper are small weaknesses, and full-game tests across variants are absent.
Audit flags
0 high and 0 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 ANCHORS.md with design, 15 anchors and criteria, 4 milestones and 10 conflict decisions from README, SPEC and example specs. No code or tests per step. No ./run.sh checks since the step names none.
Actions: Wrote UNITS.md (4 milestones). Wrote 17 BoardTest tests for A1-A5, A8 board part and A15, saw compile red, wrote Variant and Board, green. Gate: full test red only in the stub-dependent example tests (M3), lint clean outside the Kalah.java stub after renaming Variant.of and making fields private, mutate 79/87 with one equivalent Board survivor and 7 stub survivors. Judge review logged in the Book. M1 ticked.
Actions: Wrote 6 BoardPrinterTest tests for A10, A11 and A12 board part, saw compile red, wrote abstract BoardPrinter with ClockwiseLayout and AnticlockwiseLayout, green. Gate: full test red only in the stub-dependent example tests (M3), lint clean outside the Kalah.java stub, mutate 108/116 with every printer mutant killed and the same 8 M1 and stub survivors. Judge review found nothing to fix. Deviation logged in the Book: abstract class in place of the planned interface. M2 ticked.
2026-10-26T10:23:04Z. Step: L3-6 iter 3. Unit: M3 Game and Kalah.play. Tests added: 9. Cycles: 2. Sha: 59817d4. Agent: rep-1-r04:L3-6#3. Tokens: 983920. Seconds: 480.488.
Actions: Wrote 8 GameTest tests with a test-only ScriptedIO for A3/A5 game part, A6, A7, A8, A9 and the A12 prompt, saw compile red, wrote Game and replaced the Kalah stub, green with all six example tests. Gate: full test green, lint clean, first mutate left 4 invalid-input mutants so added a C10 reprompt test (cycle 2), then 140/145 with 5 equivalent or out-of-anchor survivors. Judge review found nothing to fix. ./run.sh specs not run since the step names only test, lint and mutate. M3 ticked.
Actions: Gate first: full test green, lint clean, deps run for the A14 criterion, mutate 140/145 with the same 5 equivalent or out-of-anchor survivors. Mutate skips the example tests, so play() flag wiring was unchecked. Wrote 5 KalahTest tests for all four flag pairs and quit, saw red by temporarily swapping the flags in play(), restored with git restore, green. Mutate rerun 140/145. Restriction review (A13) and alterability review (A14) found nothing to fix, logged in the Book. ./run.sh deps run although the step names only test, lint and mutate, because the Book's A14 criterion names it. M4 ticked.
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
Method: Anchor Engineering. Sources are LOG.md, git log and ANCHORS.md. GAP.md and ATTEMPTS.md do not exist in this clone.
## Mutation score at each gate
Scores count killed mutants over valid mutants. Invalid mutants are left out.
| Gate | Commit | Killed / valid | Score | Survivors |
|---|---|---|---|---|
| M1 Variant and Board | 38e39a3 | 79 / 87 | 90.8% | 1 equivalent Board mutant and 7 in the Kalah.java stub |
| M2 BoardPrinter | 9e5915f | 108 / 116 | 93.1% | Same 8 as M1. Every printer mutant killed |
| M3 first run | before 59817d4 | 136 / 145 (inferred) | 93.8% | The 5 below plus 4 invalid-input mutants. A C10 reprompt test then killed those 4 |
| M3 Game and Kalah.play | 59817d4 | 140 / 145 (147 total, 2 invalid) | 96.6% | 5 judged equivalent or outside every anchor |
| M4 Gate and review | e76232b | 140 / 145 | 96.6% | Same 5. Rerun after KalahTest also 140 / 145 |
The M3 first run count is inferred from the LOG.md note that it left 4 more survivors. The log gives no exact figure for it.
## Anchors with a passing test
| Measure | Count |
|---|---|
| Anchors with at least one named passing test | 13 / 15 (A1 to A12 and A15) |
| Anchors met by their criterion | 15 / 15 |
A13 and A14 have no unit test of their own. Their criteria are `./run.sh test` compiling with `--release 8`, `./run.sh lint`, `./run.sh deps` and the M4 restriction and alterability reviews. All of these passed at the M4 gate. KalahTest pins the A14 flag wiring in `play()`. The last recorded full test run is green with 43 tests in 6 classes at e76232b. No test was run for this measure.
## Decisions and conflicts logged
| Kind | Count |
|---|---|
| Conflicts with decisions (C1 to C10) | 10 |
| Decisions log rows (M1 6, M2 4, M3 5, M4 4) | 19 |
| Deviations from plan | 1 (M2 abstract class in place of the planned interface) |
## Judge findings found and fixed
| Milestone | Found | Fixed | Finding |
|---|---|---|---|
| M1 | 2 | 2 | Non-private `Variant` fields and the PMD-banned method name `of` |
| M2 | 0 | 0 | |
| M3 | 0 | 0 | |
| M4 | 0 | 0 | Restriction review (A13) and alterability review (A14) |
| Total | 2 | 2 | |
The gates also found 2 test gaps outside the judge reviews, and both were fixed. At M3 the first mutate run left the invalid-input branch unchecked, so the C10 test was added. At M4 mutate skipped the example tests, so `play()` flag wiring was unchecked and KalahTest was added.
## Run totals from LOG.md
| Measure | Value |
|---|---|
| Red-green cycles | 5 |
| Tests added | 37 |
| Milestones done | 4 / 4 |
## Credits and time
Credits and time are measured by the harness. They are not recorded here.
Branch method/rep-1-r06. 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
pass
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
989 (src 318, own tests 671)
recomputed
Lines of code
814 (src 242, own tests 572)
recomputed
Classes
5
recomputed
Methods
34
recomputed
Fields
10
recomputed
Bench median ms
122
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
142/148, 0 not run, adjusted 142/142 (0 of 6 survivors fail hidden tests)
recomputed
PMD lines
0 (0 violations)
recomputed
Dependency edges
9
recomputed
Review scores (superseded)
Alterability 5, Code quality principles 4.6, Test quality 5
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: Direction is a single boolean read in Variant and passed only to BoardRenderer, which mirrors the layout. Sowing order and game logic need no change, so the whole change case sits in one small class.
Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.
Reason: House and seed counts are two values in Variant.create, and Board, BoardRenderer and Game derive everything from board.houses(). No other code mentions 6, 7, 4 or 5.
Reason: Formatting and indentation are consistent, methods are short, and each file is ordered from public behaviour to private helpers. The original stub's mixed tabs were normalised.
Reason: Names such as sow, captureAt, hasMoves and endWithScores read well, and the class Javadocs give intent. The repeated `3 - player` opponent idiom and literal 1 and 2 player ids have no named helper or constant.
Reason: Player and house numbering is used the same way in Board, BoardRenderer and Game, and StringBuilder helpers in the renderer follow one pattern.
Code quality principles. Item: 4. Used Content. Score /5: 4.
Reason: Variant.houses(), seeds() and isClockwise() are called only from tests, and Board.withPits is a test-only factory in production code. Everything else is used.
Reason: A flat pit array with modular index arithmetic gives one simple sowing loop with early returns. Nesting stays shallow and the turn loop is easy to follow.
Reason: Rendering rows and borders share helpers and the board size drives the loops. The renderer still repeats the clockwise branch twice in print, and the opponent expression `3 - player` appears in several places.
Reason: Variant, Board, BoardRenderer and Game each have one clear job. The variant flags are read in one place, and the rules, output and turn flow are cleanly separated.
Code quality principles. Item: 8. Problem Alignment. Score /5: 5.
Reason: Classes and methods match domain terms such as houses, stores, sowing, capture and score. Treating anti-clockwise as a mirrored layout of the same sowing order fits the spec's display behaviour.
Test quality. Item: Test quality. Score /5: 5.
Reason: Focused, well-named tests cover sowing, store skipping, wrap-around, captures on 6 and 7 houses, extra turns, empty houses, the end of game, ties and both layouts, plus all four variants through play(). Fakes such as ScriptedIO and RecordingIO keep the cases independent.
Audit flags
0 high and 2 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 ANCHORS.md with design, 21 anchors with criteria, 4 milestones and a test map stub. Checked anchors against each other and the spec and logged 10 decisions (D1 to D10). Read example specs to settle format as EXAMPLES.md directs. No code, no tests and no ./run.sh call since the step names no check. Conflict with standing guidance: the implementer brief asks for tests per change, the step asks for none
Actions: Wrote UNITS.md with M1 to M4 and committed it. Wrote VariantTest and BoardTest from A1, A3 to A9, A13 part and A14, saw them fail to compile, added Variant and Board and saw them pass. Gate: ./run.sh test green for the new classes with the six example tests still red as expected before M3. ./run.sh lint clean outside the Kalah.java stub after renaming Variant.of to create and wrapping two lines. ./run.sh mutate 83/92 with two equivalent Board survivors and the stub survivors, all triaged in the Book. Judge review found nothing to fix. Book test map, decisions D11 to D13 and M1 status updated. Conflict with standing guidance: one rename in VariantTest used sed, which the brief asks to avoid
Actions: Wrote BoardRendererTest from A15 to A17, A18 part and A2 part with a RecordingIO helper that rejects embedded newlines. Saw it fail to compile, added BoardRenderer and Variant.renderer() and saw 8 tests pass. Gate: ./run.sh test green for all own classes with the six example tests still red as expected before M3. ./run.sh lint clean outside the Kalah.java stub after wrapping one line. ./run.sh mutate 118/127 with every BoardRenderer and Variant mutant killed and only the triaged M1 survivors and stub left. Judge review found nothing to fix. Book test map, triage, decisions D14 to D16 and M2 status updated. No conflict with standing guidance
Actions: Wrote GameTest from A4, A8, A10 to A13 and KalahTest from A2 with a ScriptedIO helper that re-asks out-of-range answers and rejects embedded newlines. Saw them fail to compile, added Game and replaced the Kalah stub with wiring through Variant, and saw all tests pass including the six example specs. Gate: ./run.sh test 7 classes green. ./run.sh lint clean after wrapping two lines. ./run.sh mutate 141/148 with the Game lower house bound surviving, so added testHouseOutsideOneToSixIsAskedForAgain and reran to 142/148. The rest are equivalent or Kalah.main, triaged in the Book. Judge review found nothing to fix. Book test map, triage, decisions D17 to D20 and M3 status updated. No conflict with standing guidance
Actions: Wrote SourceRestrictionsTest from A19 with three scans of src/kalah for System.exit, file or config access and non-JDK imports. It passed on unchanged code, so planted a System.exit in Kalah.java, saw it fail and restored the file with git restore. Gate: ./run.sh test 8 classes green including all six example specs. ./run.sh lint clean. ./run.sh mutate 142/148 with the same six survivors triaged in M1 and M3 and no new ones. Judge review against all anchors found nothing to fix. A2 deps check not run since the step names only test, lint and mutate, and a grep of src for the flag names stands in. Book test map for A19 to A21, M4 triage, decisions D21 and D22 and M4 status updated. Conflict with standing guidance: the brief asks to see each test fail before the fix, and the A19 test pins code that already complied, so the red came from a planted violation
Class diagram
Class diagrams show class names and relations only. A solid line ending in a hollow triangle points to a parent class and a dashed one to an implemented interface. A line with a diamond at the owning class marks a field and a plain arrow a use. Method and field totals are in the tables.
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: Anchor Engineering, rep-1-r06
Sources are LOG.md, git log, ANCHORS.md and UNITS.md. GAP.md and ATTEMPTS.md do not exist in this clone.
## Mutation score at each gate
| Gate | Commit | Killed / total | Score | Survivors |
|---|---|---|---|---|
| M1 Variant and Board | 5024085 | 83/92 | 90.2% | 2 equivalent `Board` mutants plus the `Kalah.java` stub |
| M2 BoardRenderer | 04a4036 | 118/127 | 92.9% | the 2 M1 `Board` survivors plus the stub. None in `BoardRenderer` or `Variant` |
| M3 Game and Kalah.play, first run | 46cb6b6 | 141/148 | 95.3% | `Game` lower house bound survived and broke A10 |
| M3 after the added test | 46cb6b6 | 142/148 | 95.9% | 6 left, all triaged as equivalent or `Kalah.main` |
| M4 final gate | 5bacef9 | 142/148 | 95.9% | the same 6, no new ones |
All six final survivors are triaged in the ANCHORS.md mutant triage table.
## Anchors with a passing test
| Measure | Count |
|---|---|
| Anchors in the Book | 21 |
| Anchors mapped to at least one passing JUnit test | 19 of 21 (A1 to A19) |
| Anchors verified by a passing check of any kind | 21 of 21. A20 by `./run.sh lint` clean and A21 by `./run.sh mutate` 142/148 with every survivor triaged |
A2's `./run.sh deps` criterion was not run since no step named it. `KalahTest` covers the four variants and a grep of `src/` for the flag names stands in for the dependency check (D22).
## Decisions and conflicts logged
| Measure | Count |
|---|---|
| Decisions in the Book | 22 (D1 to D22) |
| Spec and anchor conflicts resolved before code | 10 (D1 to D10) |
| Design decisions during the milestones | 8 (D11, D12, D14, D15, D17 to D19, D21) |
| Judge review records | 4 (D13, D16, D20, D22) |
| Conflicts with standing guidance logged in LOG.md | 3 (s1 no tests, M1 sed rename, M4 test written after compliant code) |
## Judge findings
| Measure | Count |
|---|---|
| Judge reviews run | 4, one per milestone |
| Findings found | 0 |
| Findings fixed | 0 |
One defect outside the judge reviews was found and fixed. The M3 mutation gate showed the `Game` lower house bound unguarded and testHouseOutsideOneToSixIsAskedForAgain killed it.
## Supporting counts
| Measure | Value |
|---|---|
| Red-green cycles in LOG.md | 4 |
| Tests added in LOG.md | 47 |
| Commits after the starter kit | 14 before this file |
| Final `./run.sh test` | 8 classes green including all six example specs |
## Credits and time
Credits and time are measured by the harness and are not recorded here.
Branch method/rep-1-r08. 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
pass
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
891 (src 277, own tests 614)
recomputed
Lines of code
741 (src 206, own tests 535)
recomputed
Classes
6
recomputed
Methods
34
recomputed
Fields
6
recomputed
Bench median ms
550
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
127/132, 0 not run, adjusted 127/127 (0 of 5 survivors fail hidden tests)
recomputed
PMD lines
0 (0 violations)
recomputed
Dependency edges
12
recomputed
Review scores (superseded)
Alterability 5, Code quality principles 4.5, Test quality 5
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: Direction lives only in which renderer Kalah picks, with Board sowing one logical order for both. A new direction is one small BoardRenderer subclass plus the selection line, and it composes with any board size.
Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.
Reason: House and seed counts are Board constructor arguments chosen once in Kalah.play, and Board, renderer and Game all derive widths and bounds from houseCount. Changing size touches one line and works with either direction.
Reason: Files are short, consistently formatted and ordered public then private helpers. Related methods sit together, and every element is easy to tell apart.
Reason: Names such as sow, captureAt, seedsInHouses and QUIT are descriptive, and the class comments give rationale. Literals such as 3 - player in Game and the 7,5 and 6,4 sizes in Kalah are left unnamed.
Reason: Player and house numbering is 1-based everywhere and both renderers share one shape. Game computes the opponent inline as 3 - player while Board has opponentOf, which is a small inconsistency.
Code quality principles. Item: 4. Used Content. Score /5: 5.
Reason: No dead code or unused members appear in src. Every helper is called and the stub output was fully replaced.
Reason: Loops and conditionals are shallow and the turn loop returns the next player cleanly. The row helper takes five parameters including a boolean ascending flag, and the index arithmetic in captureAt takes some effort to follow.
Reason: Row building, border repetition and index math are each written once. The opponent formula appears twice, and the test files repeat the border constants.
Reason: Board holds rules, BoardRenderer and its subclasses hold layout, Game holds the turn loop and Kalah only wires variants. Dependencies point one way and state is private.
Code quality principles. Item: 8. Problem Alignment. Score /5: 5.
Reason: Classes map to domain concepts such as board, sowing, capture, store and turn. Treating direction as a mirrored view of one sowing order fits the spec closely.
Test quality. Item: Test quality. Score /5: 5.
Reason: Focused, well-named tests pin initial boards, sowing, wrap, store skipping, capture edge cases, extra turns, empty-house reprompt, scoring outcomes and rendering for all four variants. Restriction tests cover the spec's rules. Cases are independent and use a small scripted IO.
Audit flags
1 high and 2 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.
Channel
outside_path
Agent or commit
rep-1-r08:L3-6#1
Tool
Read
Path
<local path>
Marker
<local path>
Disposition
false positive
Channel
outside_path
Definition
A path outside the clone. It is high under a home or temp dir and low elsewhere.
Dispositions from the run's findings.json judge every high flag of their channel.
Evidence: At agent-afda7b1b2b7bdcf54.jsonl:30 the agent reads bc6nn6lfx.txt, the CLI's saved output of its own cat inside the clone at line 24.
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.
Step log, 5 rows and 10 columns
2026-10-26T10:45:10Z. Step: s1. Unit: Anchor Book from README and SPEC. Tests added: 0. Cycles: 0. Sha: 005220c. Agent: rep-1-r08:s1. Tokens: 415571. Seconds: 123.718.
Actions: Wrote ANCHORS.md with design, 23 anchors with criteria, milestones M1 to M4 and 11 conflicts with decisions. No code or tests in this stage. No ./run.sh call because the step names no check
Actions: Wrote UNITS.md with M1 to M4 and committed it. Wrote 16 BoardTest tests for A1 to A8 and A21 counts, saw them fail to compile, then wrote Board until all passed. Gate: ./run.sh test has BoardTest green and the six example tests red as expected until M3. ./run.sh lint is clean for Board with violations only in the Kalah stub. ./run.sh mutate scored 59/68 and a surviving capture boundary mutant on house 1 broke A5, so one test was added and a rerun scored 60/68 with one equivalent Board mutant left. Review against the anchors found no defect. Book updated with the verification map, decision log and M1 done. Standing guidance asks each regression test to be seen failing first. The mutant test passes on correct code by design, so it was only checked against the mutate rerun
2026-10-26T10:54:52Z. Step: L3-6 iteration 2. Unit: M2 BoardRenderer for both layouts and both sizes. Tests added: 9. Cycles: 1. Sha: 95cbcd0. Agent: rep-1-r08:L3-6#2. Tokens: 1565240. Seconds: 272.284.
Actions: Wrote 9 BoardRendererTest tests for A16 to A19 from spec lines in both directions and both sizes plus two digit cells, saw them fail to compile, then wrote the abstract BoardRenderer with ClockwiseRenderer and AnticlockwiseRenderer until all passed. Gate: ./run.sh test has both unit classes green and the six example tests red as expected until M3. ./run.sh lint flagged four lines over 80 characters in BoardRenderer, which were wrapped, and is now clean outside the Kalah stub. ./run.sh mutate killed every renderer mutant, score 89/97, so no mutant test was needed. Review against A16 to A19 found no defect. Book updated with the verification map, decision log and M2 done. UNITS.md ticked
Actions: Wrote 7 GameTest tests for A9 to A15 and A20 with a ScriptedIO fake, saw them fail to compile, then wrote Game, Board.seedsInHouses and the Kalah.play wiring until all passed. Spec files under test/ were tried first and dropped because the editing tools strip each prompt's trailing space, so the scenarios hold their expected lines in Java. Gate: ./run.sh test is green for all five classes including the six example tests. ./run.sh lint reports no violations. ./run.sh mutate left the lower input bound mutant alive, which breaks A15, so one test was added and the rerun scored 127/132 with four equivalent survivors and the main flags left. Review against the anchors found no defect. Book updated with the verification map, decision log and M3 done. UNITS.md ticked. Standing guidance asks each regression test to be seen failing first. The mutant test passes on correct code by design, so it was only checked against the mutate rerun
2026-10-26T11:10:32Z. Step: L3-6 iteration 4. Unit: M4 Gate and review for lint, mutation and restrictions. Tests added: 3. Cycles: 1. Sha: 758bbf7. Agent: rep-1-r08:L3-6#4. Tokens: 727226. Seconds: 372.185.
Actions: Wrote 3 SourceRestrictionsTest tests for A22 and A23 that scan src/kalah for imports, System.exit, file access and flag names. They passed on the existing code, so a planted java.io import, System.exit and flag name in Game turned all three red, then git restore brought them back to green. Gate: ./run.sh test is green for all six classes. ./run.sh lint reports no violations. ./run.sh mutate scored 127/132 with the five equivalent survivors from M3, so no mutant test was needed. mutate ran twice because the first output was cut by head. Review found the Kalah class Javadoc above the imports and moved it onto the class, then test and lint were rerun green. Book updated with the verification map, decision log and M4 done. UNITS.md ticked
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
Method is Anchor Engineering. Sources are `LOG.md`, `git log`, `ANCHORS.md` and `UNITS.md`. `GAP.md` and `ATTEMPTS.md` do not exist in this clone.
## Mutation score at each gate
Scores are killed over total mutants from `./run.sh mutate` as logged in `LOG.md` and the `ANCHORS.md` decision log.
| Gate | First run | After mutant tests | Mutant tests added | Survivors left |
|---|---|---|---|---|
| M1 Board | 59/68 (86.8%) | 60/68 (88.2%) | 1 | one equivalent `Board` mutant plus `Kalah` stub mutants |
| M2 BoardRenderer | 89/97 (91.8%) | 89/97 (91.8%) | 0 | no renderer survivors. `Board` equivalent and `Kalah` stub mutants |
| M3 Game and Kalah.play | score not logged. One mutant alive on the lower input bound | 127/132 (96.2%) | 1 | five equivalent survivors |
| M4 Gate and review | 127/132 (96.2%) | 127/132 (96.2%) | 0 | the same five equivalent survivors |
The five equivalent survivors at M3 and M4 are the two `main` flags, `QUIT` as `-0`, `> to >=` in the winner choice and the `Board` `house < 0` mutant.
## Anchors with a passing test
23 of 23 anchors have at least one named passing test in the `ANCHORS.md` verification map. The final gate at M4 has `./run.sh test` green for all six test classes. A22 and A23 also lean on `--release 8` compilation and `./run.sh lint`, which reports no violations.
## Decisions and conflicts logged
| Kind | Count | Where |
|---|---|---|
| Conflicts with a decision | 11 (C1 to C11) | `ANCHORS.md` Conflicts and decisions |
| Milestone decisions | 15 (M1 4, M2 4, M3 4, M4 3) | `ANCHORS.md` Decision log |
| Conflicts with standing guidance | 2 | `LOG.md` iterations 1 and 3. Mutant tests pass on correct code by design, so each was checked against the mutate rerun instead of a red run |
## Judge findings
No separate judge review is recorded in the clone. The milestone self reviews found 1 defect and fixed it. At M4 the `Kalah` class Javadoc sat above the imports and was moved onto the class, then test and lint were rerun green. Reviews at M1 to M3 found no defect.
## Work totals
| Item | Value |
|---|---|
| Tests added | 37 (17, 9, 8, 3) |
| Red-green cycles | 5 (1, 1, 2, 1) |
| Commits before this file | 12 on top of the starter kit |
## Credits and time
Credits and wall time are measured by the harness. They are not recorded here.
Branch method/rep-1-r14. 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
pass
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
883 (src 353, own tests 530)
recomputed
Lines of code
704 (src 253, own tests 451)
recomputed
Classes
8
recomputed
Methods
40
recomputed
Fields
14
recomputed
Bench median ms
608
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
112/119, 0 not run, adjusted 112/112 (0 of 7 survivors fail hidden tests)
recomputed
PMD lines
0 (0 violations)
recomputed
Dependency edges
16
recomputed
Review scores (superseded)
Alterability 5, Code quality principles 4.6, Test quality 5
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: Direction is modelled as a rendering choice. Variant picks one of two small renderer subclasses and the sowing logic is shared, so the change touches one branch and one 19-line class.
Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.
Reason: House count and seed count live only in the Variant constructor. Board, renderers and game all derive sizes from houseCount(), so 7/5 is a two-literal change.
Reason: Names and short Javadoc explain intent well, such as FIRST, SECOND and oppositeHouse. The literals 7, 6, 5 and 4 in Variant and the position arithmetic in sow and drop have no named constants.
Reason: Players are int indices with FIRST and SECOND throughout. Houses are 1-based in public methods everywhere and both renderers follow the same pattern.
Code quality principles. Item: 4. Used Content. Score /5: 4.
Reason: Almost everything is used. MoveResult wraps a single int and adds little, and Board.FIRST/SECOND stand beside a separate NAMES array in Game.
Reason: Methods are short with shallow nesting. The single-cycle position index in sow and drop, with the 1 - player opponent, takes some careful reading.
Reason: Responsibilities divide cleanly into Variant (flags), Board (rules), BoardRenderer (output) and Game (turn loop and IO). Test-only constructors are package-private.
Code quality principles. Item: 8. Problem Alignment. Score /5: 5.
Reason: Concepts map to the domain: houses, stores, sowing, capture, opposite house and score. The insight that direction only changes layout matches the problem.
Test quality. Item: Test quality. Score /5: 5.
Reason: Focused, well-named unit tests cover sowing laps, store skipping, captures and their edge cases, extra turns, end of game and rendering in both directions and both sizes, with added scenario files per variant. A few tests check several assertions at once.
Audit flags
1 high and 1 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.
Channel
outside_path
Agent or commit
rep-1-r14:L3-6#4
Tool
Read
Path
<local path>
Marker
<local path>
Disposition
false positive
Channel
outside_path
Definition
A path outside the clone. It is high under a home or temp dir and low elsewhere.
Dispositions from the run's findings.json judge every high flag of their channel.
Evidence: At agent-a7b36e14d445b27f8.jsonl:29 the agent reads bs2g8iioe.txt, the CLI's saved output of its own cat inside the clone at line 23.
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 ANCHORS.md with design, 27 anchors and criteria, 6 milestones. Checked anchors against each other, README, SPEC and example specs and logged 12 conflicts with decisions. No code or tests and no ./run.sh call because the step names no checks
Actions: Wrote UNITS.md with 6 milestones and committed it. Wrote 14 tests for A1, A4 to A7 and A12 and saw them fail to compile. Added Variant and Board and saw BoardTest pass. Gate: ./run.sh test passes the model tests and the 6 example tests fail as expected before M4. ./run.sh lint flags only the starter Kalah.java stub. ./run.sh mutate leaves 2 equivalent Board mutants (array row count 2 to 3) with no anchor broken. Review found nothing to fix. Book traceability, decisions and M1 status updated and UNITS.md ticked
Actions: Wrote 11 tests in BoardTurnTest for A8 to A11 and saw them fail to compile. Added MoveResult and made sow return it with store landing and capture. Two M1 full lap tests then failed because a 2N+1 lap always ends in the emptied origin and A10 requires a capture there. Updated their expectations and renamed one. Gate: ./run.sh test passes the model tests and the 6 example tests fail as expected before M4. ./run.sh lint flags only the starter Kalah.java stub. ./run.sh mutate leaves 3 equivalent Board mutants with no anchor broken. Review found nothing to fix. Book traceability, decisions and M2 status updated and UNITS.md ticked
2026-10-26T10:22:02Z. Step: L3-6 iteration 3. Unit: M3 BoardRenderer for both layouts and both sizes. Tests added: 9. Cycles: 2. Sha: b6a3b90. Agent: rep-1-r14:L3-6#3. Tokens: 1889948. Seconds: 579.38.
Actions: Wrote 7 renderer tests for A16 to A18 and one Variant direction test, moved existing tests to the two flag Variant constructor and saw them fail to compile. Added the direction flag to Variant with renderer(), an abstract BoardRenderer and Clockwise and Anticlockwise subclasses and saw all model and renderer tests pass. Gate: ./run.sh test passes them and the 6 example tests fail as expected before M4. ./run.sh lint flags only the starter Kalah.java stub. ./run.sh mutate left the print println removal alive, so one more test records printed lines through a MockIO subclass and kills it. The 4 remaining mutants are equivalent. Review found nothing to fix. Book design, traceability, decisions and M3 status updated and UNITS.md ticked
Actions: Wrote 5 GameTest spec tests with scenario specs under test/game for all four variants and P2 reprompt and saw them fail on the stub. Added Game and made Kalah.play run it and saw them pass. Conflict: the Write and Edit tools strip trailing spaces, so the required trailing space after the prompt in the new spec files was restored with one sed substitution against the rule to edit only with Edit and Write. Gate: ./run.sh test passes all but the two full game example tests that wait on M5. ./run.sh lint reports no violations. ./run.sh mutate left the input lower bound 1 to 0 alive, so a test that records readInteger arguments kills it. The rest are the stub main flags, an equivalent quit value and known equivalent mutants. Review found nothing to fix. Book traceability, decisions and M4 status updated and UNITS.md ticked
2026-10-26T10:36:00Z. Step: L3-6 iteration 5. Unit: M5 Game end, scores and result line. Tests added: 8. Cycles: 1. Sha: 9ad3fa9. Agent: rep-1-r14:L3-6#5. Tokens: 1162156. Seconds: 279.337.
Actions: Wrote 8 GameEndTest tests for A20 to A22 and saw them fail to compile. Added Board.hasMoves and Board.score, a package-private Game constructor taking a Board, and the end check before each prompt with score and result lines, and saw all tests pass. Gate: ./run.sh test passes every test class including both full game example specs. ./run.sh lint reports no violations. ./run.sh mutate killed every new mutant and left only the known stub, equivalent and non-compiling ones, so no test was added. Review found nothing to fix. Book traceability, decisions and M5 status updated and UNITS.md ticked
Actions: M6 anchors A23 to A27 are verified by the gate itself, so no new test was written and no red-green cycle ran. Gate: ./run.sh test passes all 8 test classes under javac --release 8. ./run.sh lint reports no violations. ./run.sh deps shows only Kalah and Variant reading the flags. A source scan finds no System.exit, java.io or outside library. ./run.sh mutate scores 112 of 119 and every survivor is a known stub or equivalent mutant, so no test was added. Review found nothing to fix. Book traceability, C11, decisions and M6 status updated and UNITS.md ticked. Conflict: the UNITS.md tick used one sed substitution against the rule to edit only with Edit and Write. Note: ./run.sh mutate ran twice because the first run wrote to a missing .scratch folder
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
Method: Anchor Engineering. Sources are LOG.md, git log and ANCHORS.md. GAP.md and ATTEMPTS.md do not exist in this clone.
## Mutation score at each gate
Only the M6 gate recorded a full score. Earlier gates logged their survivors only.
| Gate | Score | Survivors left | Tests added for survivors |
|---|---|---|---|
| M1 | not recorded | 2, both equivalent | 0 |
| M2 | not recorded | 3, all equivalent | 0 |
| M3 | not recorded | 4 equivalent after 1 test killed the `print` call removal | 1 |
| M4 | not recorded | stub `main()` flags, equivalent quit value and known equivalents after 1 test killed the input lower bound | 1 |
| M5 | not recorded | only the known stub and equivalent mutants | 0 |
| M6 | 112 of 119 (94 percent) | 7, all known stub or equivalent | 0 |
The M6 run made 120 mutants: 110 killed, 7 survived, 2 timed out and 1 did not compile. No surviving mutant breaks an anchor.
## Anchors with a passing test
27 of 27 anchors have a passing check at the M6 gate, where `./run.sh test` passes all 8 test classes.
- 23 of 27 have a named unit or spec test. These are A1 to A22 and A25.
- A23 is checked by every test compiling under `javac --release 8`.
- A24 is checked by a source scan. A26 is checked by `./run.sh lint`. A27 is checked by `./run.sh mutate`. These three have no dedicated test.
## Decisions and conflicts logged
| Item | Count |
|---|---|
| Spec conflicts with decisions (C1 to C12 in ANCHORS.md) | 12 |
| Decision log rows in ANCHORS.md | 18 |
| Process conflicts in LOG.md (one sed edit to restore trailing spaces in M4 and one sed edit to tick UNITS.md in M6, both against the Edit and Write rule) | 2 |
## Judge findings
No judge review is logged. The six milestone reviews found 0 findings, so 0 were fixed.
## Work done
48 tests added over 7 red-green cycles in 6 milestones, with 15 commits on the branch.
Credits and time are measured by the harness.