Kalah TDD study · Part 12 of 29 · Designs

Noun-verb map

Plan classes from spec nouns and methods from verbs. Fill linked stubs.

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

Contents

Structure first

What it changes: The map. Fixed before any code.

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.

Family: Structure first. Idea: Plan classes from spec nouns and methods from verbs. Fill linked stubs. What it changes in the search: The map. Fixed before any code.

once:1. Gather the spec and its acceptance tests. Write tests for any untested feature.2. Extract every noun and verb as Noun: -verb lists. Trim to the domain.3. Mark parents as Noun(Parent). Split nouns over 4 verbs. Apply Clean Code names.4. Replace duplicate verbs with references written as verb1(Noun2.verb3).5. Script-check for cycles, dangling references and nouns over 4 verbs. Fix each.6. Scaffold stubs that throw a TODO naming the referenced method. Fill one per prompt.7. Run the tests. Fix one failing test per prompt with the smallest change.8. Lint with no suppressions. Prune unused methods. Diff a regenerated map against the plan.

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 12.1

Stage flow of Noun-verb map

Stage flow of Noun-verb map8 stages in run order across the lanes Agent.AgentAgentOnce: step 1Once: step 2Once: step 3Once: step 4Once: step 5Once: step 6Commit cap 60Once: step 7Commit cap 40Once: step 8
  1. Once: step 1. Lane: Agent.

    Next: Once: step 2.

  2. Once: step 2. Lane: Agent.

    Next: Once: step 3.

  3. Once: step 3. Lane: Agent.

    Next: Once: step 4.

  4. Once: step 4. Lane: Agent.

    Next: Once: step 5.

  5. Once: step 5. Lane: Agent.

    Next: Once: step 6.

  6. Once: step 6. Commit cap 60. Lane: Agent.

    Next: Once: step 7.

  7. Once: step 7. Commit cap 40. Lane: Agent.

    Next: Once: step 8.

  8. Once: step 8. Lane: Agent.

8 stages from the run facts, each checked against its block of the steps above. Details and notes are in the stage table. Tag: recomputed.

Text version: Stage flow of Noun-verb map
  1. Once: step 1. Lane: Agent.

    Next: Once: step 2.

  2. Once: step 2. Lane: Agent.

    Next: Once: step 3.

  3. Once: step 3. Lane: Agent.

    Next: Once: step 4.

  4. Once: step 4. Lane: Agent.

    Next: Once: step 5.

  5. Once: step 5. Lane: Agent.

    Next: Once: step 6.

  6. Once: step 6. Commit cap 60. Lane: Agent.

    Next: Once: step 7.

  7. Once: step 7. Commit cap 40. Lane: Agent.

    Next: Once: step 8.

  8. Once: step 8. Lane: Agent.

Stages

Each stage as the run facts list it. Runs as and Note are quoted verbatim and Steps repeats the steps above. Tag: verified.

StageRuns asStepsDetailsNote
Once: step 1once:1. Gather the spec and its acceptance tests. Write tests for any untested feature.nonenone
Once: step 2once:2. Extract every noun and verb as Noun: -verb lists. Trim to the domain.nonenone
Once: step 3once:3. Mark parents as Noun(Parent). Split nouns over 4 verbs. Apply Clean Code names.nonenone
Once: step 4once:4. Replace duplicate verbs with references written as verb1(Noun2.verb3).nonenone
Once: step 5once:5. Script-check for cycles, dangling references and nouns over 4 verbs. Fix each.nonenone
Once: step 6once:6. Scaffold stubs that throw a TODO naming the referenced method. Fill one per prompt.commit cap 60One prompt in the step is one commit here.
Once: step 7once:7. Run the tests. Fix one failing test per prompt with the smallest change.commit cap 40One prompt in the step is one commit here.
Once: step 8once:8. Lint with no suppressions. Prune unused methods. Diff a regenerated map against the plan.nonenone

Survey build

One build in run full-1.

15/15Functional mark
21E
918,336Cost to completion
545,018M
415,798M_io
0PMD findings
noAlignment

Replicates

Repeat builds: 5 in run rep-1.

0.964Median adjusted mutation, over 5 replicates in rep-1
15Median classes, over 5 replicates in rep-1
1,334,836Median cost to completion, over 5 replicates in rep-1
16Median CQP, over 5 replicates in rep-1
against Functions first, classes later: U 9, Holm p 0.548Planned contrast, exact, Holm, rep-1
1.65Consistency score C, exploratory over rep-1 and rep-2, lower is more consistent

Verdict

One survey build and 5 replicates. All 6 builds passed strict PMD compliance, with 14 classes in the survey build and 15 to 19 in the replicates. Its replicates' median adjusted mutation was 0.964. The test against Functions first, classes later did not detect a difference (Holm p 0.548). Its observed consistency score C of 1.65 was the highest among the seven replicated methods. This exploratory test did not detect a difference in spread. Tag: recomputed.

Report summary

The report's class diagram for this design is identical to Figure 12.2 below, so it is shown once. Tag: recomputed.

Functional mark /1515/15
Hidden pass /7676/76
Unseen pass /6969/69
Strict PMD compliancepass
Mutation score88/115, 0 not run, adjusted 88/109 (21 of 27 survivors fail hidden tests)
Classes14
Simple Constructs /54
Minimal Duplication /54
Modular Structure /53
Problem Alignment (tentative) /54
Weighted tokens961,206
Bench median ms562

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.80710th highest of 11 single survey builds, one per method
Classes142nd highest of 11 single survey builds, one per method
Cost to completion918,3365th lowest of 11 single survey builds, one per method
Strict PMD violations0joint 1st lowest of 11 single survey builds, one per method
Median adjusted mutation0.964over 5 replicates in rep-1
Median classes15over 5 replicates in rep-1
Median cost to completion1,334,836over 5 replicates in rep-1
Median CQP16over 5 replicates in rep-1
Planned contrastagainst Functions first, classes later: U 9, Holm p 0.548exact, Holm, rep-1
Consistency score C1.65exploratory 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.

Survey build (full-1)

Buildnoun-verb
Adjusted mutation0.807
Classes14
Cost to completion918,336
Strict PMD violations0

Figure 12.2

Class diagram of method/noun-verb

kalahBoardConsoleDisplayGameGameOverHouseKalahMovePitPlayerPromptSideStoreVariant

14 classes and 57 links. Tag: recomputed.

Text version: Class diagram of method/noun-verb
  1. Package kalah: Board, Console, Display, Game, GameOver, House, Kalah, Move, Pit, Player, Prompt, Side, Store, Variant
  2. Board uses House
  3. Board uses Pit
  4. Board uses Player
  5. Display uses Board
  6. Display holds Board
  7. Display uses Console
  8. Display holds Console
  9. Display uses Player
  10. Display holds Player
  11. Display uses Store
  12. Display uses Variant
  13. Display holds Variant
  14. Game uses Board
  15. Game holds Board
  16. Game uses Display
  17. Game holds Display
  18. Game uses GameOver
  19. Game holds GameOver
  20. Game uses Move
  21. Game uses Player
  22. Game holds Player
  23. Game uses Prompt
  24. Game holds Prompt
  25. Game uses Side
  26. GameOver uses Display
  27. GameOver holds Display
  28. GameOver uses Side
  29. GameOver holds Side
  30. House uses Pit
  31. House extends Pit
  32. Kalah uses Board
  33. Kalah uses Console
  34. Kalah uses Display
  35. Kalah uses Game
  36. Kalah uses Player
  37. Kalah uses Prompt
  38. Kalah uses Variant
  39. Move uses Board
  40. Move holds Board
  41. Move uses House
  42. Move uses Pit
  43. Move uses Player
  44. Move holds Player
  45. Move uses Store
  46. Player uses House
  47. Player uses Store
  48. Player holds Store
  49. Player uses Variant
  50. Prompt uses Console
  51. Prompt extends Console
  52. Prompt uses Player
  53. Side uses House
  54. Side uses Player
  55. Side holds Player
  56. Side uses Store
  57. Store uses Pit
  58. Store extends Pit

Best replicate (rep-1-r07)

Replicaterep-1-r07
MethodNoun-verb map
Adjusted mutation0.989
Unadjusted mutation0.940
Classes15
Cost to completion1,174,050
CQP16
CQP accepted12
Strict PMD violations0
Buildbest

Figure 12.3

Class diagram of rep-1-r07

kalahBoardBoardViewChoiceReaderDirectionGameHouseKalahMessageViewMovePitPlayerScoreStoreTurnVariant

15 classes and 70 links. Tag: recomputed.

Text version: Class diagram of rep-1-r07
  1. Package kalah: Board, BoardView, ChoiceReader, Direction, Game, House, Kalah, MessageView, Move, Pit, Player, Score, Store, Turn, Variant
  2. Board uses House
  3. Board holds House
  4. House uses Board
  5. Board uses Player
  6. Player uses Board
  7. Board uses Store
  8. Board holds Store
  9. Store uses Board
  10. BoardView uses Board
  11. BoardView holds Board
  12. BoardView uses Direction
  13. BoardView holds Direction
  14. BoardView uses House
  15. BoardView uses Player
  16. BoardView uses Store
  17. ChoiceReader uses Board
  18. ChoiceReader holds Board
  19. ChoiceReader uses House
  20. ChoiceReader uses Player
  21. Game uses Board
  22. Game uses BoardView
  23. Game uses ChoiceReader
  24. Game uses MessageView
  25. Game holds MessageView
  26. Game uses Score
  27. Game uses Turn
  28. Game holds Turn
  29. Game uses Variant
  30. House uses Pit
  31. House extends Pit
  32. House uses Player
  33. Player uses House
  34. House uses Store
  35. Kalah uses Game
  36. Kalah uses Variant
  37. MessageView uses BoardView
  38. MessageView holds BoardView
  39. MessageView uses Player
  40. MessageView uses Score
  41. MessageView holds Score
  42. Move uses Board
  43. Move holds Board
  44. Move uses House
  45. Move uses Pit
  46. Move uses Player
  47. Move holds Player
  48. Move uses Store
  49. Pit uses Board
  50. Pit uses Player
  51. Pit holds Player
  52. Player uses Store
  53. Store uses Player
  54. Score uses Board
  55. Score holds Board
  56. Score uses House
  57. Score uses Player
  58. Score uses Store
  59. Store uses Pit
  60. Store extends Pit
  61. Turn uses Board
  62. Turn holds Board
  63. Turn uses ChoiceReader
  64. Turn holds ChoiceReader
  65. Turn uses House
  66. Turn uses MessageView
  67. Turn holds MessageView
  68. Turn uses Move
  69. Turn uses Player
  70. Turn holds Player
  71. Variant uses Direction

Median replicate (rep-1-r19)

Replicaterep-1-r19
MethodNoun-verb map
Adjusted mutation0.964
Unadjusted mutation0.922
Classes15
Cost to completion1,260,350
CQP16
CQP accepted12
Strict PMD violations0
Buildmedian

Figure 12.4

Class diagram of rep-1-r19

kalahBoardBoardViewGameHouseKalahMovePitPlayerPromptResultViewRulesScoreSowingStoreTurn

15 classes and 64 links. Tag: recomputed.

Text version: Class diagram of rep-1-r19
  1. Package kalah: Board, BoardView, Game, House, Kalah, Move, Pit, Player, Prompt, ResultView, Rules, Score, Sowing, Store, Turn
  2. Board uses House
  3. Board uses Pit
  4. Board uses Player
  5. Board uses Sowing
  6. Board holds Sowing
  7. Board uses Store
  8. BoardView uses Board
  9. BoardView holds Board
  10. BoardView uses House
  11. BoardView uses Player
  12. BoardView uses Rules
  13. BoardView holds Rules
  14. Game uses Board
  15. Game holds Board
  16. Game uses BoardView
  17. Game holds BoardView
  18. Game uses Move
  19. Game uses Player
  20. Game uses Prompt
  21. Game uses ResultView
  22. Game uses Score
  23. Game uses Turn
  24. Game holds Turn
  25. House uses Pit
  26. House extends Pit
  27. Pit uses House
  28. House uses Player
  29. Kalah uses Board
  30. Kalah uses BoardView
  31. Kalah uses Game
  32. Kalah uses Rules
  33. Move uses Board
  34. Move holds Board
  35. Move uses House
  36. Move holds House
  37. Move uses Pit
  38. Move uses Player
  39. Move holds Player
  40. Move uses Prompt
  41. Move holds Prompt
  42. Move uses Sowing
  43. Move uses Store
  44. Pit uses Player
  45. Pit holds Player
  46. Prompt uses Player
  47. ResultView uses Player
  48. ResultView uses Score
  49. ResultView holds Score
  50. Score uses Board
  51. Score holds Board
  52. Score uses House
  53. Score uses Player
  54. Sowing uses House
  55. Sowing uses Pit
  56. Sowing holds Pit
  57. Sowing uses Player
  58. Sowing uses Store
  59. Store uses House
  60. Store uses Pit
  61. Store extends Pit
  62. Store uses Player
  63. Turn uses Move
  64. Turn uses Player
  65. Turn holds Player

Worst replicate (rep-1-r10)

Replicaterep-1-r10
MethodNoun-verb map
Adjusted mutation0.776
Unadjusted mutation0.750
Classes19
Cost to completion1,615,015
CQP16
CQP accepted12
Strict PMD violations0
Buildworst

Figure 12.5

Class diagram of rep-1-r10

kalahBoardBoardRendererBoardSetupCaptureDirectionGameHouseHouseRowRendererInputKalahMoveOutputPitPlayerResultPrinterScoreSowingStoreTurn

19 classes and 100 links. Tag: recomputed.

Text version: Class diagram of rep-1-r10
  1. Package kalah: Board, BoardRenderer, BoardSetup, Capture, Direction, Game, House, HouseRowRenderer, Input, Kalah, Move, Output, Pit, Player, ResultPrinter, Score, Sowing, Store, Turn
  2. Board uses House
  3. Board uses Pit
  4. Board uses Player
  5. Player uses Board
  6. Board uses Store
  7. Board holds Store
  8. BoardRenderer uses Board
  9. BoardRenderer uses Direction
  10. BoardRenderer holds Direction
  11. BoardRenderer uses HouseRowRenderer
  12. BoardRenderer holds HouseRowRenderer
  13. BoardRenderer uses Player
  14. BoardRenderer uses Store
  15. BoardSetup uses Board
  16. BoardSetup uses House
  17. BoardSetup uses Player
  18. BoardSetup uses Store
  19. Capture uses Board
  20. Capture holds Board
  21. Capture uses House
  22. House uses Capture
  23. Capture uses Player
  24. Capture holds Player
  25. Capture uses Store
  26. Store uses Capture
  27. Game uses Board
  28. Game holds Board
  29. Game uses ResultPrinter
  30. Game holds ResultPrinter
  31. Game uses Score
  32. Game holds Score
  33. Game uses Turn
  34. Game holds Turn
  35. House uses Pit
  36. House extends Pit
  37. House uses Player
  38. Player uses House
  39. HouseRowRenderer uses Board
  40. HouseRowRenderer uses Direction
  41. HouseRowRenderer holds Direction
  42. HouseRowRenderer uses House
  43. HouseRowRenderer uses Player
  44. Kalah uses Board
  45. Kalah uses BoardRenderer
  46. Kalah uses BoardSetup
  47. Kalah uses Direction
  48. Kalah uses Game
  49. Kalah uses Input
  50. Kalah uses ResultPrinter
  51. Kalah uses Score
  52. Kalah uses Turn
  53. Move uses Board
  54. Move holds Board
  55. Move uses Capture
  56. Move uses House
  57. Move holds House
  58. Move uses Pit
  59. Move uses Player
  60. Move holds Player
  61. Move uses Sowing
  62. Move holds Sowing
  63. Move uses Store
  64. Output uses Board
  65. Output uses BoardRenderer
  66. Output holds BoardRenderer
  67. Output uses Player
  68. Pit uses Capture
  69. Pit uses Player
  70. Pit holds Player
  71. Player uses Input
  72. Player uses Store
  73. Store uses Player
  74. ResultPrinter uses BoardRenderer
  75. ResultPrinter uses Output
  76. ResultPrinter extends Output
  77. ResultPrinter uses Player
  78. ResultPrinter uses Score
  79. Score uses Board
  80. Score holds Board
  81. Score uses House
  82. Score uses Player
  83. Score uses Store
  84. Sowing uses Board
  85. Sowing holds Board
  86. Sowing uses Pit
  87. Sowing holds Pit
  88. Sowing uses Player
  89. Sowing holds Player
  90. Store uses Pit
  91. Store extends Pit
  92. Turn uses Board
  93. Turn holds Board
  94. Turn uses House
  95. Turn uses Input
  96. Turn holds Input
  97. Turn uses Move
  98. Turn uses Output
  99. Turn holds Output
  100. Turn uses Player
  101. Turn holds Player

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.

Records

Replicates (rep-1)

Replicates (rep-1), 5 rows and 10 columns
ReplicateMethodAdjusted mutationUnadjusted mutation
rep-1-r07Noun-verb map0.9890.940
rep-1-r10Noun-verb map0.7760.750
rep-1-r13Noun-verb map0.8350.783
rep-1-r19Noun-verb map0.9640.922
rep-1-r20Noun-verb map0.9780.927
ReplicateClassesCost to completionCQP
rep-1-r07151,174,05016
rep-1-r10191,615,01516
rep-1-r13161,334,83616
rep-1-r19151,260,35016
rep-1-r20151,454,26416
ReplicateCQP acceptedStrict PMD violationsBuild
rep-1-r07120best
rep-1-r10120worst
rep-1-r13120-
rep-1-r19120median
rep-1-r20120-

Consistency

MethodNoun-verb map
Adjusted mutation1.61
Unadjusted mutation2.18
Classes1.43
Cost to completion1.34
Strict PMD violationsat bound
CQP accepted0.00
Consistency score C1.65

Clone reports

Each clone's own report, as in its REPORT.md.

Noun-verb map: functional mark 15/15, strict PMD pass, classes 14, weighted tokens 961,206

Noun-verb map

Branch method/noun-verb. 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 /1515/15
Hidden pass /7676/76
Unseen pass /6969/69
Acceptance pass /66/6
Strict PMD compliancepass

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 setTestsFailuresMarks
Original set, STA 6-4testST64SKHHSH_02/2
STC 6-4testSTC64SKHHSH_03/3
STA 7-5testST75SKHHSH_03/3
STC 7-5testSTC75SKHHSH_03/3
All requirementsall tests04/4
Summary metrics
MetricValueTag
Total lines515 (src 485, own tests 30)recomputed
Lines of code400 (src 378, own tests 22)recomputed
Classes14recomputed
Methods60recomputed
Fields30recomputed
Bench median ms562recomputed
Bench volume100614 inputs, 40083576 output charsrecomputed

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
MetricValueTag
Mutation score88/115, 0 not run, adjusted 88/109 (21 of 27 survivors fail hidden tests)recomputed
PMD lines0 (0 violations)recomputed
Dependency edges41recomputed
Review scores (superseded)Alterability 5, Code quality principles 3.8, Test quality 3unchecked
Tokens4,798,738 (input 222, cache creation 432,681, cache read 4,325,059, output 40,776)recomputed
Weighted tokens961,206recomputed
Wall time0:23:39recomputed
Agent time0:22:46recomputed
Agent calls9recomputed
Audit flags1 high, 20 low, 1 of 1 high have a dispositionrecomputed

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.

Review scores, 11 rows and 4 columns

Alterability. Item: Change Case 1: sow seeds anti-clockwise. Score /5: 5.

Reason: Direction is read in a single place, the isClockwise branch in Display.showBoard, which reuses one row helper for both layouts. Sowing and capture logic need no change for either direction.

Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.

Reason: House count and starting seeds come only from Variant.houseCount and initialSeeds, and the board, rendering and loops scale from that count. Changing or adding a size touches one class.

Code quality principles. Item: 1. Clear Presentation. Score /5: 4.

Reason: Small files with consistent indentation and wrapping make the classes easy to scan. Display mixes board rendering with message output, and Console sits apart from the Prompt subclass that extends it, which blurs where IO lives.

Code quality principles. Item: 2. Explanatory Language. Score /5: 4.

Reason: Names such as sow, endsInOwnStore, captureOpposite and oppositeHouse read like the rules, and the javadoc lines give intent. The Game constructor comment about a coupling limit explains process instead of design, and the literals 6/7 and 4/5 in Variant have no named constants.

Code quality principles. Item: 3. Consistent Code. Score /5: 3.

Reason: houseCount is threaded as a separate argument into Game, Move, Side and Prompt although Variant and Player already know it. IO is wrapped twice, once as the Console for Display and again through Prompt extends Console, so the same concern has two instances.

Code quality principles. Item: 4. Used Content. Score /5: 3.

Reason: Prompt.readChoice only forwards to readHouse, GameOver.announceResult is a public step used once, and Board.houses duplicates the house lists Player already holds. Board.seedsIn and isEmpty only forward to Player.

Code quality principles. Item: 5. Simple Constructs. Score /5: 3.

Reason: Move.capture loops over every house to find whether the last pit is the mover's own house, where a direct check would do. Side.hasMoves accumulates a boolean through the whole loop when an early return is plainer, and Board.nextPit uses indexOf on every seed.

Code quality principles. Item: 6. Minimal Duplication. Score /5: 4.

Reason: The two clockwise and anticlockwise board layouts share one row() helper, and the score and has-moves loops each appear once. The house loops over 1..houseCount repeat across Side, Move and Display, and the two Player constructors repeat the house setup.

Code quality principles. Item: 7. Modular Structure. Score /5: 4.

Reason: Pit, House, Store, Player, Board, Move, Side, Game and GameOver each carry one clear job, and the direction choice stays inside Display. Using inheritance from Console for Prompt and pushing a raw houseCount into many classes adds coupling that a shared Variant or Board would avoid.

Code quality principles. Item: 8. Problem Alignment. Score /5: 5.

Reason: The model uses the domain terms houses, stores, sowing, capture, extra turn and opposite house directly. It also shows that the direction only changes the board layout because the sowing ring stays the same in both variants.

Test quality. Item: Test quality. Score /5: 3.

Reason: Six spec-driven tests with clear names cover quit, extra turn, capture and wrapping past the own store across several variants that the starter examples leave out. Coverage is uneven: there are no unit tests of Move, Board or Side, no empty-house or game-end tests, and anticlockwise 7-5 capture and some variant combinations are missing.

Audit flags

1 high and 20 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.

Channelpmd_suppression
Agent or commitcc5687300b78b80b098164789201396925dad08a
Tool-
PathMEASURE.md:41
MarkerNOPMD
Dispositionfalse positive
Channelpmd_suppression
DefinitionA NOPMD or PMD @SuppressWarnings in any line a commit added, prose included.

Dispositions from the run's findings.json judge every high flag of their channel.

pmd_suppression. Verdict: false positive. Tag: verified.

Evidence: MEASURE.md:41 is the measure agent's sentence saying no @SuppressWarnings or NOPMD appears. git grep NOPMD over src and test on method/noun-verb finds none.

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, 8 rows and 10 columns

2026-10-15T23:55:46Z. Step: s1. Unit: Step 1 gather spec and acceptance tests. Tests added: 6. Cycles: 1. Sha: 7ef987a. Agent: noun-verb:s1. Tokens: 428706. Seconds: 160.858.

Actions: Gathered README, SPEC and the 6 example specs. Untested features found: anti-clockwise 7-5 variant, extra turn after ending in store, capture with non-empty opposite house, sowing past own store onto opponent houses. Added 6 hand-computed spec files under test/specs and VariantSpecTest. One ./run.sh test run: all 6 new tests red on the stub as expected (green waits for later steps). Untested and left open: a full game won by one player (only the win line format is inferred), invalid house input.

2026-10-15T23:56:27Z. Step: s2. Unit: Step 2 extract noun-verb lists. Tests added: 0. Cycles: 0. Sha: 27c31d3. Agent: noun-verb:s2. Tokens: 262900. Seconds: 36.928.

Actions: Wrote design/MAP.md with a raw Noun: -verb extraction from README, SPEC, EXAMPLES and the spec files, then a list trimmed to the domain (Kalah, Game, Variant, Board, Player, House, Store, Move, Console). Dropped tooling and assessment nouns and folded seed, pit, sowing, capture, score and messages into owning nouns. Board keeps 6 verbs for step 3 to split. No code or tests changed and no ./run.sh call since the step names no check.

2026-10-15T23:57:13Z. Step: s3. Unit: Step 3 parents, splits and Clean Code names. Tests added: 0. Cycles: 0. Sha: b044d39. Agent: noun-verb:s3. Tokens: 157490. Seconds: 45.536.

Actions: Added a stage s3 section to design/MAP.md. Marked House(Pit), Store(Pit), Prompt(Console) and Display(Console) and moved shared verbs to the parents. Split Game into Game and GameOver, Board into Board and Side, and Console into Prompt and Display, so no noun has over 4 verbs. Renamed verbs to Clean Code names (playTurn, opponent, nextPit, oppositeHouse, takeAll, endsInOwnStore, show*). Listed duplicates for step 4. No code or tests changed and no ./run.sh call since the step names no check. Edit made via a bash heredoc append for speed, which conflicts with the standing Edit/Write-only guidance.

2026-10-15T23:57:41Z. Step: s4. Unit: Step 4 replace duplicate verbs with references. Tests added: 0. Cycles: 0. Sha: 27a9041. Agent: noun-verb:s4. Tokens: 188165. Seconds: 28.407.

Actions: Added a stage s4 section to design/MAP.md. Six duplicates became references: Kalah.play(Game.play), Board.seedsIn(Pit.seeds), Board.isEmpty(House.isEmpty), Prompt.readChoice(Console.readHouse), Game.isOver(Side.hasMoves) and GameOver.announceResult(Display.showScores). Verbs that compose others (GameOver.quit, GameOver.finish, Move.capture, Side.score) stay owners. No code or tests changed and no ./run.sh call since the step names no check.

2026-10-15T23:58:57Z. Step: s5. Unit: Step 5 script-check the map. Tests added: 0. Cycles: 2. Sha: 8a109f8. Agent: noun-verb:s5. Tokens: 382657. Seconds: 73.391.

Actions: Added design/check_map.py, which parses the last map section of design/MAP.md and reports cycles over reference and parent edges, dangling references and parents, self references and nouns over 4 verbs counting inherited ones. Cycle 1 checked it red against an uncommitted bad fixture in .scratch (all 5 seeded problems caught). Cycle 2 counted inherited verbs, which turned the map red on Display(Console) with 6 verbs. Fixed by dropping the Console parent from Display so it holds a Console instead, recorded in a stage s5 map section. Script now reports 14 nouns and 0 problems. No cycles or dangling references were found. No Java code or tests changed and no ./run.sh call since the step names no check.

2026-10-16T00:12:05Z. Step: s6. Unit: Step 6 scaffold stubs and fill one per prompt. Tests added: 0. Cycles: 0. Sha: 53af53a. Agent: noun-verb:s6. Tokens: 1869982. Seconds: 790.088.

Actions: Commit 631f45d scaffolded one class per map noun (Kalah, Game, GameOver, Variant, Board, Side, Player, Pit, House, Store, Move, Console, Prompt, Display) with each verb throwing UnsupportedOperationException "TODO X.y", where reference verbs name the referenced method (Kalah.play names Game.play, Board.seedsIn names Pit.seeds and so on). Constructors and fields were written as wiring in the scaffold. Then 36 commits filled one method each, leaving no TODO. Deviations from the s5 map: Player gained number() for the prompt label, Move gained private captureOpposite and Display gained private row, divider, storeLabel and repeat helpers. Kalah.play now runs Game.play in place of the stub board. No ./run.sh call and no tests since step 6 names no check, which conflicts with the standing guidance to run static checks and related tests per change. Compilation and the specs are first checked in step 7. Known risk for step 7: the s1 spec files under test/specs end prompts with "quit:" while the examples end with "quit: " plus a space.

2026-10-16T00:13:20Z. Step: s7. Unit: Step 7 run the tests and fix one failing test per prompt. Tests added: 0. Cycles: 6. Sha: 48e8b56. Agent: noun-verb:s7. Tokens: 619300. Seconds: 71.54.

Actions: First ./run.sh test compiled cleanly. The 6 example tests passed and all 6 VariantSpecTest tests failed on one cause: the s1 spec files under test/specs ended each prompt with "quit:" while the example specs and examples/EXAMPLES.md (the stated authority on format) end it with "quit: " plus a space. The code was right, so each fix was the smallest test-data change. Six commits each fixed one spec file and turned one test green: STA 6-4 capture, STC 6-4 capture, STC 6-4 wrap, STA 7-5 quit, STC 7-5 extra turn and STA 7-5 extra turn. The final ./run.sh test passes all 12 tests in 3 classes. No production code changed. Each spec edit used a BSD sed substitution because the Edit tool trims the needed trailing space, which conflicts with the standing Edit/Write-only guidance.

2026-10-16T00:15:38Z. Step: s8. Unit: Step 8 lint, prune and diff the regenerated map. Tests added: 0. Cycles: 2. Sha: c40e22e. Agent: noun-verb:s8. Tokens: 755259. Seconds: 134.267.

Actions: First ./run.sh lint reported one violation: CouplingBetweenObjects 9 on Game (threshold 5). Cycle 1 added Move.play (sow, own-store check, capture, returns whether the turn passes) and made Move.skips private, which dropped the Move and Pit locals from Game. Lint then reported 7. Cycle 2 moved the wiring of Variant, Player, Board, Display and Prompt from the Game constructor into Kalah.play, so Game takes its parts and couples to 5. Lint then reported no violations. No suppressions exist in src or test. Every non-private method has a caller, so nothing was pruned. Added a stage s8 map section regenerated from code with its diff against the s5 plan: Player +number (from s6), Move +play and skips now private, Kalah does the wiring. design/check_map.py reports 14 nouns and 0 problems on it. Only ./run.sh lint ran since the step names no other check, which conflicts with the standing guidance to run related tests after each change. The two refactor commits were not run through ./run.sh test and the compile is unchecked in this stage.

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: noun-verb map

Sources are LOG.md, git log (60 commits) and design/MAP.md. GAP.md and ATTEMPTS.md do not exist in this clone.

## Credits per step

Credits and wall time are measured by the harness and are not recorded here. LOG.md gives the per-step work counts below.

| step | unit | cycles | tests added | commits | head sha |
|---|---|---|---|---|---|
| s1 | gather spec and acceptance tests | 1 | 6 | 1 | 7ef987a |
| s2 | extract noun-verb lists | 0 | 0 | 1 | 27c31d3 |
| s3 | parents, splits and names | 0 | 0 | 1 | b044d39 |
| s4 | duplicate verbs to references | 0 | 0 | 1 | 27a9041 |
| s5 | script-check the map | 2 | 0 | 1 | 8a109f8 |
| s6 | scaffold and fill stubs | 0 | 0 | 37 | 53af53a |
| s7 | run tests and fix one per prompt | 6 | 0 | 6 | 48e8b56 |
| s8 | lint, prune and diff the map | 2 | 0 | 3 | c40e22e |

Commit counts per step are taken from git log subjects and exclude the "Log stage" commits.

## Map defects caught at step 5

One real map defect. design/check_map.py found `Display(Console)` holding 6 verbs once inherited verbs counted, over the limit of 4. The fix dropped the Console parent so Display holds a Console. No cycles, dangling references or self references were found in the map. The 5 problems caught in cycle 1 were seeded in a test fixture to prove the script and are not map defects.

## Plan drift at step 8

The stage s8 map regenerated from code differs from the stage s5 plan in 4 places.

| drift | introduced | cause |
|---|---|---|
| `Player.number` added | s6 | prompt label needs the player number |
| `Move.play` added | s8 | lint coupling limit of 5 on Game |
| `Move.skips` made private | s8 | only `sow` calls it |
| `Kalah.play` wires Variant, Player, Board, Display and Prompt | s8 | lint coupling limit of 5 on Game |

Private helpers added in s6 (`Move.captureOpposite` and Display's `row`, `divider`, `storeLabel` and `repeat`) are not part of the map and are not counted. No verb was pruned. The two s8 refactor commits were not run through ./run.sh test, so their behaviour is unchecked.

## Suppressions or build-file edits attempted

None. No `@SuppressWarnings` or `NOPMD` appears in src or test. run.sh, kalah_pmd.xml and bin have no commit after the starter kit. The lint violation was fixed in code.

Process conflicts logged instead: a bash heredoc edit in s3, sed edits of spec files in s7 and no test run after the s6 and s8 code changes.
Replicate rep-1-r07: functional mark 15/15, strict PMD pass, classes 15, weighted tokens 1,232,148

Replicate rep-1-r07

Branch method/rep-1-r07. 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 /1515/15
Hidden pass /7676/76
Unseen pass /6969/69
Acceptance pass /66/6
Strict PMD compliancepass

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 setTestsFailuresMarks
Original set, STA 6-4testST64SKHHSH_02/2
STC 6-4testSTC64SKHHSH_03/3
STA 7-5testST75SKHHSH_03/3
STC 7-5testSTC75SKHHSH_03/3
All requirementsall tests04/4
Summary metrics
MetricValueTag
Total lines550 (src 524, own tests 26)recomputed
Lines of code426 (src 407, own tests 19)recomputed
Classes15recomputed
Methods69recomputed
Fields29recomputed
Bench median ms597recomputed
Bench volume100614 inputs, 40083576 output charsrecomputed

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
MetricValueTag
Mutation score94/100, 0 not run, adjusted 94/95 (1 of 6 survivors fail hidden tests)recomputed
PMD lines0 (0 violations)recomputed
Dependency edges53recomputed
Review scores (superseded)Alterability 5, Code quality principles 4.2, Test quality 3unchecked
Tokens7,118,731 (input 284, cache creation 384,186, cache read 6,650,439, output 83,822)recomputed
Weighted tokens1,232,148recomputed
Wall time0:19:31recomputed
Agent time0:18:45recomputed
Agent calls9recomputed
Audit flags1 high, 1 low, 1 of 1 high have a dispositionrecomputed

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.

Review scores, 11 rows and 4 columns

Alterability. Item: Change Case 1: sow seeds anti-clockwise. Score /5: 5.

Reason: Sowing walks one pit ring for both directions, and the flag reaches only BoardView, which mirrors the rows. The change case touches Variant, Direction and one if in BoardView.print, and that works with either board size.

Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.

Reason: House and seed counts live only in Variant. Board, BoardView, ChoiceReader and the capture opposite all derive from houseCount, so the change is two ternaries.

Code quality principles. Item: 1. Clear Presentation. Score /5: 5.

Reason: Formatting is consistent and files are small. Each class is ordered with constructor, public API, then private helpers.

Code quality principles. Item: 2. Explanatory Language. Score /5: 4.

Reason: Names and one-line Javadocs carry intent, and QUIT is a named constant. Null as the quit or tie signal is explained only in comments, and the 7/5 and 6/4 literals have no names.

Code quality principles. Item: 3. Consistent Code. Score /5: 4.

Reason: The style is uniform. Store access is inconsistent because Player.store(board) and Player.houses(board) duplicate Board lookups and are used only in some places.

Code quality principles. Item: 4. Used Content. Score /5: 4.

Reason: Nearly everything is used. Player.store is a redundant alias for Board.store, and the Store.captureFor no-op exists only to fit the polymorphic hook.

Code quality principles. Item: 5. Simple Constructs. Score /5: 4.

Reason: Methods are short with shallow nesting. Null returns for quit and tie, and the boolean-return take() driving the loop, add small control-flow subtleties.

Code quality principles. Item: 6. Minimal Duplication. Score /5: 4.

Reason: Row rendering is shared through storeFirstRow and storeLastRow, and printing goes through MessageView. Iterating houses appears in both Board and Player, and the store accessor is duplicated.

Code quality principles. Item: 7. Modular Structure. Score /5: 4.

Reason: Responsibilities are cleanly split across model, move, turn, input and views. Player depending on Board for houses and store couples the enum to the board, and Direction is a thin boolean wrapper.

Code quality principles. Item: 8. Problem Alignment. Score /5: 5.

Reason: Classes map to domain terms: Pit, House, Store, Board, Move, Turn and Score. Capture and next-pit rules sit on the pits they concern.

Test quality. Item: Test quality. Score /5: 3.

Reason: Five added end-to-end specs fill variant gaps such as anti-clockwise 7-5, a P1 win and an empty house, and each test name says what it covers. No unit tests pin the capture, skip-opponent-store or wraparound rules in isolation.

Audit flags

1 high and 1 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.

Channelpmd_suppression
Agent or commitc045e628efdcfa864819f0c2b59c9129018b2e17
Tool-
PathMEASURE.md:41
MarkerNOPMD
Dispositionfalse positive
Channelpmd_suppression
DefinitionA NOPMD or PMD @SuppressWarnings in any line a commit added, prose included.

Dispositions from the run's findings.json judge every high flag of their channel.

pmd_suppression. Verdict: false positive. Tag: verified.

Evidence: MEASURE.md:41 at commit c045e62 is the measure agent's sentence saying no NOPMD appears. git grep of NOPMD and SuppressWarnings over src and test on the branch finds none.

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, 8 rows and 10 columns

2026-10-26T10:05:40Z. Step: s1. Unit: Gather spec and acceptance tests; test untested features. Tests added: 5. Cycles: 0. Sha: fb72f5a. Agent: rep-1-r07:s1. Tokens: 1057886. Seconds: 195.545.

Actions: Read README, SPEC, EXAMPLES and the six example specs. Built a scratch reference model that reproduces all six example specs exactly and used it to find gaps: no anti-clockwise 7-5 spec, no P1 win, no anti-clockwise empty-house choice, no 7-5 capture, extra turn, store skip or game end. Added five specs under test/ with AddedSpecTest; all five run red on the stub as expected. Conflict: the generated full-game spec bodies were assembled with cat from scratch output in place of the Write tool, since they are oracle output. No implementation in this stage so no red-green cycles ran.

2026-10-26T10:06:28Z. Step: s2. Unit: Extract noun-verb lists and trim to the domain. Tests added: 0. Cycles: 0. Sha: 1ab31f1. Agent: rep-1-r07:s2. Tokens: 271905. Seconds: 46.93.

Actions: Read README and SPEC and the output lines of all specs. Wrote design/NOUN_VERB_MAP.md with a raw Noun: -verb extraction and a trimmed domain list of ten nouns. Dropped test infrastructure, assessment, restrictions and documents. Folded pit, seed, opponent, sowing and change case into other nouns. Board and Console exceed 4 verbs and are left for the step 3 split. No code so no red-green cycles and no checks ran.

2026-10-26T10:07:16Z. Step: s3. Unit: Mark parents, split nouns over 4 verbs, apply Clean Code names. Tests added: 0. Cycles: 0. Sha: 7a95b3b. Agent: rep-1-r07:s3. Tokens: 330916. Seconds: 56.98.

Actions: Added a step 3 section to design/NOUN_VERB_MAP.md. House and Store take the parent Pit. Board split into Board lookups and Move rules. Console split into ChoiceReader, BoardView and MessageView. Renamed ten verbs with a reasons table. Every noun now has at most 4 verbs. No code so no red-green cycles and no checks ran.

2026-10-26T10:08:18Z. Step: s4. Unit: Replace duplicate verbs with references. Tests added: 0. Cycles: 0. Sha: 248d896. Agent: rep-1-r07:s4. Tokens: 215657. Seconds: 45.348.

Actions: Added a step 4 section to design/NOUN_VERB_MAP.md. Seventeen duplicate verbs became references written as verb1(Noun2.verb3) with a table naming the owning noun and why. Board keeps the pit lookups, Pit the count and Score the totals. Player.houses and Player.store now refer to Board. No code so no red-green cycles and no checks ran. Conflict: LOG.md row appended with echo in place of the Edit tool.

2026-10-26T10:09:18Z. Step: s5. Unit: Script-check the map for cycles, dangling references and nouns over 4 verbs. Tests added: 0. Cycles: 0. Sha: a47fa31. Agent: rep-1-r07:s5. Tokens: 355036. Seconds: 62.583.

Actions: Wrote design/check_map.py. It parses the last noun list in design/NOUN_VERB_MAP.md and reports reference cycles, dangling references, unknown parents and nouns over 4 verbs. A planted bad map in .scratch tripped all four checks. The step 4 map gave 13 nouns and 0 problems so no fixes were needed. Added a script check section to the map. No code so no red-green cycles and no ./run.sh checks ran.

2026-10-26T10:14:43Z. Step: s6. Unit: Scaffold stubs that throw a TODO naming the referenced method and fill one per prompt. Tests added: 0. Cycles: 0. Sha: 5191e52. Agent: rep-1-r07:s6. Tokens: 3140035. Seconds: 331.257.

Actions: Commit 074f17b scaffolded the 13 map nouns as classes in src/kalah with every map verb throwing UnsupportedOperationException naming the method and its reference, such as "TODO Move.sow(Direction.next)". Kalah.play now delegates to Game.play. Then 31 commits filled one stub each in dependency order, leaves first, ending with Game.play. No TODO stub is left. Deviations from the map: added accessors Player.number, Pit.owner, House.number, Board.houseCount and Direction.isClockwise plus private BoardView helpers, and Player.houses and Player.store take the Board. Direction.next steps the same pit ring in both variants because the example specs differ only in how the board is drawn. Conflict: the step names no checks so no ./run.sh call ran, no tests were added and the code is not yet compiled. Standing guidance asks for tests and static checks on each change. Step 7 runs the tests.

2026-10-26T10:15:30Z. Step: s7. Unit: Run the tests and fix one failing test per prompt. Tests added: 0. Cycles: 0. Sha: 8b9410a. Agent: rep-1-r07:s7. Tokens: 281018. Seconds: 39.854.

Actions: Ran ./run.sh test twice. The code compiled and all 3 test classes passed on the first run: AddedSpecTest 5 tests, ExampleClockwiseTest 3 and ExampleAnticlockwiseTest 3. No test failed so no fix was needed, no red-green cycle ran and no code commit was made. Only this LOG.md row was committed.

2026-10-26T10:20:19Z. Step: s8. Unit: Lint with no suppressions, prune unused methods, diff a regenerated map against the plan. Tests added: 0. Cycles: 2. Sha: 4e59de1. Agent: rep-1-r07:s8. Tokens: 1225607. Seconds: 291.357.

Actions: First ./run.sh lint gave 72 findings: 65 LineLength, 2 InstanceOfUse, 2 CastUse and CouplingBetweenObjects on Board 7, Game 11 and Move 6. Fixed with no suppressions in a31ef75. Pit.next and Pit.captureFor with House and Store overrides replace the instanceof checks. A new Turn holds the player to move so Game drops to 5 types. Move.play wraps sow, endsInStore and capture. Board takes the house and seed counts. Long lines wrapped. Second lint left one LineLength in Game and the third was clean. ./run.sh test passed 3 of 3 classes after each change. Pruning found no public method without a caller. Direction.next and its unused houseCount field went, and ChoiceReader.prompt, Game.quit and Game.end became private. Added design/regen_map.py, which rebuilds the noun list from src and diffs it against the step 4 list. The 22 differences are tabled in design/NOUN_VERB_MAP.md in 4e59de1. No tests added because the step is behaviour preserving and the existing specs cover it.

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: noun-verb map. Sources are LOG.md, git log and design/NOUN_VERB_MAP.md. GAP.md and ATTEMPTS.md do not exist in this clone.

## Credits per step

Credits and time are measured by the harness. They are not recorded here. LOG.md gives the work per step.

| Step | Unit | Tests added | Cycles | Commits |
|---|---|---|---|---|
| s1 | Spec tests for untested features | 5 | 0 | 2 |
| s2 | Noun-verb extraction and trim | 0 | 0 | 2 |
| s3 | Parents, splits and names | 0 | 0 | 2 |
| s4 | References for duplicate verbs | 0 | 0 | 2 |
| s5 | Script check of the map | 0 | 0 | 2 |
| s6 | Scaffold stubs and fill one per prompt | 0 | 0 | 33 |
| s7 | Run tests and fix failures | 0 | 0 | 1 |
| s8 | Lint, prune and regenerate the map | 0 | 2 | 3 |

Commit counts include each stage's LOG.md commit. The starter kit commit is excluded.

## Map defects caught at step 5

Zero. design/check_map.py found 13 nouns and 0 problems on the step 4 map: no cycles, no dangling references, no unknown parents and no noun over 4 verbs. A planted bad map in .scratch tripped all four checks, so the checker can detect each class. The step 4 map stood with no fixes.

## Plan drift at step 8

design/regen_map.py rebuilt the noun list from src/kalah and found 22 differences against the step 4 plan. design/NOUN_VERB_MAP.md groups them into 8 causes.

| Cause | Drift |
|---|---|
| PMD InstanceOfUse and CastUse | Direction.next moved to Pit.next. Move.capture moved to Pit.captureFor. |
| PMD CouplingBetweenObjects | New noun Turn. Game.takeTurn removed. Move.sow and Move.endsInStore private behind Move.play. MessageView.printBoard added. Board takes counts in place of Variant. |
| Pruning | Game.quit, Game.end and ChoiceReader.prompt made private. |
| Stage s6 accessors | Board.houseCount, House.number, Pit.owner, Player.number and Direction.isClockwise. |

Most drift came from lint rules the map did not anticipate. Stage s6 had already added the accessors and changed the Player.houses and Player.store signatures.

## Suppressions or build-file edits attempted

Zero. Stage s8 cleared all 72 PMD findings with no suppressions. The git history has no SuppressWarnings or NOPMD. No commit after the starter kit touches run.sh, kalah_pmd.xml, UsingPMD.html or cqp.html. The working tree has no uncommitted changes to them.
Replicate rep-1-r10: functional mark 15/15, strict PMD pass, classes 19, weighted tokens 1,670,959

Replicate rep-1-r10

Branch method/rep-1-r10. 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 /1515/15
Hidden pass /7676/76
Unseen pass /6969/69
Acceptance pass /66/6
Strict PMD compliancepass

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 setTestsFailuresMarks
Original set, STA 6-4testST64SKHHSH_02/2
STC 6-4testSTC64SKHHSH_03/3
STA 7-5testST75SKHHSH_03/3
STC 7-5testSTC75SKHHSH_03/3
All requirementsall tests04/4
Summary metrics
MetricValueTag
Total lines642 (src 620, own tests 22)recomputed
Lines of code489 (src 473, own tests 16)recomputed
Classes19recomputed
Methods85recomputed
Fields35recomputed
Bench median ms739recomputed
Bench volume100614 inputs, 40083576 output charsrecomputed

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
MetricValueTag
Mutation score66/88, 0 not run, adjusted 66/85 (19 of 22 survivors fail hidden tests)recomputed
PMD lines0 (0 violations)recomputed
Dependency edges75recomputed
Review scores (superseded)Alterability 4.5, Code quality principles 3.6, Test quality 3unchecked
Tokens10,968,721 (input 350, cache creation 444,465, cache read 10,404,950, output 118,956)recomputed
Weighted tokens1,670,959recomputed
Wall time0:25:47recomputed
Agent time0:24:48recomputed
Agent calls9recomputed
Audit flags1 high, 6 low, 1 of 1 high have a dispositionrecomputed

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.

Review scores, 11 rows and 4 columns

Alterability. Item: Change Case 1: sow seeds anti-clockwise. Score /5: 4.

Reason: Direction only affects BoardRenderer and HouseRowRenderer, so the sowing order stays the same and only the drawing mirrors. The boolean is wrapped in a thin Direction class and its isClockwise checks are spread over two renderers.

Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.

Reason: BoardSetup takes houseCount and seedsPerHouse and everything else derives sizes from the board. The variant is one ternary in Kalah.selectVariant, although its 7/5 and 6/4 literals are unnamed.

Code quality principles. Item: 1. Clear Presentation. Score /5: 4.

Reason: Small files with consistent formatting and short methods. Placement is sometimes odd, such as private helpers placed between public methods in BoardRenderer and HouseRowRenderer.

Code quality principles. Item: 2. Explanatory Language. Score /5: 3.

Reason: Most classes have useful one-line docs, but some names mislead: houseOf returns a list, createPits returns a Board, and validate is a query. Variant numbers 7, 5, 6, 4 have no named constants.

Code quality principles. Item: 3. Consistent Code. Score /5: 3.

Reason: Houses are reached both through board.houseOf and through Player.ownedHouses, and stores both ways too. ResultPrinter extends Output while Turn depends on Output, which splits printing across an odd hierarchy.

Code quality principles. Item: 4. Used Content. Score /5: 3.

Reason: Several pass-through methods add nothing: Game.start only calls runTurns, Turn.switchPlayer and grantExtraTurn wrap one call, and Player.chooseHouse forwards to Input. BoardSetup.fillHouses is exposed for no caller.

Code quality principles. Item: 5. Simple Constructs. Score /5: 4.

Reason: Control flow is shallow and readable, and the do-while in Game is clear. Some indirection, such as polymorphic offerCapture and Board's recomputed filtering in houseOf, adds more steps than the logic needs.

Code quality principles. Item: 6. Minimal Duplication. Score /5: 4.

Reason: Rendering reuses renderCells and houseDashes, and the scoring loop runs over players. There is little repetition apart from the duplicated BoardSetup(...).createPits() call in selectVariant.

Code quality principles. Item: 7. Modular Structure. Score /5: 4.

Reason: Responsibilities are split cleanly into board, pits, sowing, capture, turn and rendering, and fields are scoped tightly. Player depends on Board and Input for trivial forwarding, and ResultPrinter inheriting from Output couples the two printers.

Code quality principles. Item: 8. Problem Alignment. Score /5: 4.

Reason: The domain vocabulary maps closely to the game: House, Store, Pit, Sowing, Capture, Turn and Score, with the linked pit ring modelling the sowing order. Direction as a pure rendering concern fits the spec, but the name hides that sowing itself never changes.

Test quality. Item: Test quality. Score /5: 3.

Reason: GapSpecTest adds four clearly named spec-file scenarios for an anticlockwise 7-5 start, an extra turn, captures, and a clockwise capture. There are no unit tests for Sowing, Capture, Score or rendering, and edge rules such as lap captures and ties stay unpinned.

Audit flags

1 high and 6 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.

Channelpmd_suppression
Agent or commitc05dcb062faf8fd7c563788bc660b75f4a01a1a6
Tool-
PathMEASURE.md:39
MarkerNOPMD
Dispositionfalse positive
Channelpmd_suppression
DefinitionA NOPMD or PMD @SuppressWarnings in any line a commit added, prose included.

Dispositions from the run's findings.json judge every high flag of their channel.

pmd_suppression. Verdict: false positive. Tag: verified.

Evidence: MEASURE.md:39 at commit c05dcb0 is the measure agent's sentence saying no NOPMD appears. git grep of NOPMD and SuppressWarnings over src and test on the branch finds none.

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, 8 rows and 10 columns

2026-10-26T10:04:46Z. Step: s1. Unit: gather spec and acceptance tests. Tests added: 4. Cycles: 0. Sha: 2813f67. Agent: rep-1-r10:s1. Tokens: 511277. Seconds: 141.887.

Actions: Read README.md, docs/SPEC.md, examples/EXAMPLES.md and the six example specs. Found gaps: anti-clockwise 7-5 variant, last seed in store, capture with non-empty opposite house. Added four hand-derived spec files under test/specs and GapSpecTest. Ran ./run.sh test GapSpecTest: 4 errors on the stub (red, expected). No production code, so no green phase. Untested and left: a full game that P1 wins.

2026-10-26T10:05:44Z. Step: s2. Unit: extract noun-verb lists. Tests added: 0. Cycles: 0. Sha: fe0e19c. Agent: rep-1-r10:s2. Tokens: 289059. Seconds: 53.753.

Actions: Read README.md, docs/SPEC.md, examples/EXAMPLES.md and example specs. Wrote design/noun-verb-map.md with a raw Noun: -verb extraction of 32 nouns and a trimmed domain list of 13 nouns. Dropped test infrastructure, build rules and presentation synonyms. Merged Opponent, Capture, Tie, Winner, Turn, Prompt, Message and Variant into other nouns. Listed the spec behaviours each noun must cover. Parents and splits over 4 verbs left for s3. No tests or code, so no checks run and no red-green cycles.

2026-10-26T10:06:44Z. Step: s3. Unit: mark parents, split nouns, Clean Code names. Tests added: 0. Cycles: 0. Sha: 16c895b. Agent: rep-1-r10:s3. Tokens: 183799. Seconds: 58.592.

Actions: Added a Parents, splits and names section to design/noun-verb-map.md. Pit made the parent of House and Store and ResultPrinter a child of Output. Split the five nouns over 4 verbs: Game into Game and Turn, Board into Board and BoardSetup, Move into Move and Capture, BoardRenderer into BoardRenderer and HouseRowRenderer, Output into Output and ResultPrinter. Renamed verbs to Clean Code names with booleans as questions and listed each rename with its reason. Updated the behaviours list to the new names. 19 nouns, none over 4 verbs. No tests or code, so no checks run and no red-green cycles.

2026-10-26T10:07:42Z. Step: s4. Unit: replace duplicate verbs with references. Tests added: 0. Cycles: 0. Sha: a52ea93. Agent: rep-1-r10:s4. Tokens: 190777. Seconds: 50.607.

Actions: Added a References section to design/noun-verb-map.md. Rewrote 20 verbs across 13 nouns as verb1(Noun2.verb3) where they repeat work another noun owns, such as Turn -hasLegalMove(House.isEmpty), Sowing -dropSeed(Pit.addSeeds) and Output -printBoard(BoardRenderer.render). Orchestrating verbs stay plain. A table lists each duplicate and its owner. Set aside the self-reference Score -resultMessage(Score.compareTotals) because the form names another noun. No reference cycles by inspection, and the script check is left for s5. No tests or code, so no checks run and no red-green cycles.

2026-10-26T10:08:38Z. Step: s5. Unit: script-check the noun-verb map. Tests added: 0. Cycles: 0. Sha: 16d52b4. Agent: rep-1-r10:s5. Tokens: 262453. Seconds: 53.366.

Actions: Added design/check_map.py. It parses the References list in design/noun-verb-map.md and flags nouns over 4 verbs, unknown parents, self-references, dangling references and verb or noun cycles, with parent verbs inherited. Confirmed it catches each fault on a seeded bad map in .scratch. The real map passes with 19 nouns and 0 problems, so nothing needed fixing. Recorded the check and result in a Script check section of the map. No tests or code, so ./run.sh not run and no red-green cycles.

2026-10-26T10:16:42Z. Step: s6. Unit: scaffold stubs and fill one per prompt. Tests added: 0. Cycles: 0. Sha: a7ae414. Agent: rep-1-r10:s6. Tokens: 5837984. Seconds: 489.16.

Actions: Commit 12c35df scaffolded 18 classes in src/kalah, one per noun of the References list, with Player as an enum and Store(Pit) empty. Every map verb became a stub throwing UnsupportedOperationException with a TODO naming the referenced method, or the verb itself when plain. Then filled one stub per commit, 55 fills in 55 commits, bottom up from Pit to Kalah.play. No TODO is left. Additions beyond the map: constructors, the protected Output.io() accessor for ResultPrinter, and private helpers BoardRenderer.houseDashes and HouseRowRenderer.renderCells. Board.houseOf returns a player's houses as a list, so lookup by number happens in Turn.take. Direction.stepFrom always steps forward because the pit ring is in sowing order for both directions, and the clockwise flag only mirrors the drawing. Input.readChoice uses readFromKeyboard with an empty prompt because Output.printPrompt prints the prompt. Step 6 names no checks, so ./run.sh was not run, and compile errors or failing tests are left for s7. No tests added and no red-green cycles.

2026-10-26T10:18:59Z. Step: s7. Unit: run the tests and fix failing tests. Tests added: 0. Cycles: 4. Sha: a7ccd40. Agent: rep-1-r10:s7. Tokens: 903436. Seconds: 135.611.

Actions: First ./run.sh test compiled cleanly. Both example classes passed (6 tests). All 4 GapSpecTest tests failed on the prompt line because the s1 hand-written specs under test/specs dropped the trailing space that every example spec has after "quit:". The production output matches the examples, so the specs were wrong. Fixed one spec file per commit and reran GapSpecTest after each: 4, 3, 2, 1, then 0 failures. Final ./run.sh test: 3 classes, 10 tests, all pass. Conflict logged: Edit and Write strip trailing spaces and so could not make the fix, so each file got one BSD sed substitution of the prompt line, against the standing rule to edit only with Edit and Write. No production code changed and no tests added.

2026-10-26T10:26:39Z. Step: s8. Unit: lint, prune, regenerate and diff the map. Tests added: 0. Cycles: 5. Sha: 86ff61e. Agent: rep-1-r10:s8. Tokens: 2578298. Seconds: 457.74.

Actions: First ./run.sh lint gave 74 violations with no suppressions in src: 60 LineLength, 5 CouplingBetweenObjects (Board, Game, Kalah, Move, Turn), 4 InstanceOfUse, 4 CastUse and 1 ShortMethodName. Fixed them in four commits with ./run.sh test and ./run.sh lint after each. Wrapped long lines and renamed Output.io to printLine. Linked the pits into a ring with typed house and store fields on Board, pruning Board.pitAfter and Direction.stepFrom. Replaced the capture type test with Pit.offerCapture in House and Store and moved the seed loop to Sowing.sowFrom. Let Turn hold the mover and return whether play goes on, which dropped Optional from Game and Turn and slimmed Kalah. A fifth commit made the Sowing step helpers private. Final lint: 0 violations. Final ./run.sh test: 3 classes, all pass. Added design/regen_map.py, which rebuilt the map from src and found no unused method. Recorded its diff against the plan in design/noun-verb-map.md: 2 verbs dropped, 7 added, and Pit now over the 4-verb limit. check_map.py still passes on the plan. Conflict logged: step 8 names only lint, but ./run.sh test also ran after each refactor to keep behaviour fixed. No tests added.

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: noun-verb map. Sources are LOG.md, git log and design/noun-verb-map.md. GAP.md and ATTEMPTS.md do not exist in this clone.

## Credits per step

Credits and time are measured by the harness. They are not recorded in this clone.

| step | unit | commits | cycles | tests added |
|---|---|---|---|---|
| s1 | gather spec and acceptance tests | 1 | 0 | 4 |
| s2 | extract noun-verb lists | 1 | 0 | 0 |
| s3 | mark parents, split nouns, Clean Code names | 1 | 0 | 0 |
| s4 | replace duplicate verbs with references | 1 | 0 | 0 |
| s5 | script-check the noun-verb map | 1 | 0 | 0 |
| s6 | scaffold stubs and fill one per prompt | 56 | 0 | 0 |
| s7 | run the tests and fix failing tests | 4 | 4 | 0 |
| s8 | lint, prune, regenerate and diff the map | 6 | 5 | 0 |

Commit counts exclude the per-step "Log stage" commits.

## Map defects caught at step 5

0 defects in the real map. design/check_map.py reported 19 nouns and 0 problems. It caught every fault on a seeded bad map in .scratch, which shows the check works but counts no real defect. The one self-reference, Score -resultMessage(Score.compareTotals), was set aside by hand at s4 before the script ran.

## Plan drift at step 8

design/regen_map.py rebuilt the map from src/kalah and diffed its public verbs against the References list.

| change | count | verbs |
|---|---|---|
| dropped | 2 | Board -pitAfter, Direction -stepFrom |
| added | 7 | Pit -linkTo -next -offerCapture, House -offerCapture, Store -offerCapture, Output -printLine, Sowing -sowFrom |

Total drift is 9 verbs against a plan of 19 nouns. Pit now has 6 verbs and breaks the 4-verb limit. No method is unused. Lint drove the drift. The causes were 5 CouplingBetweenObjects, 4 InstanceOfUse and 4 CastUse violations.

## Suppressions or build-file edits attempted

0 suppressions. No NOPMD or SuppressWarnings appears in src or test, and LOG.md records lint passing with no suppressions.
0 build-file edits. run.sh and kalah_pmd.xml are unchanged since the starter kit commit.
One rule conflict was logged at s7. Four spec files under test/specs were edited with BSD sed because Edit and Write strip trailing spaces. These are test data files and no build file.
Replicate rep-1-r13: functional mark 15/15, strict PMD pass, classes 16, weighted tokens 1,392,442

Replicate rep-1-r13

Branch method/rep-1-r13. 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 /1515/15
Hidden pass /7676/76
Unseen pass /6969/69
Acceptance pass /66/6
Strict PMD compliancepass

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 setTestsFailuresMarks
Original set, STA 6-4testST64SKHHSH_02/2
STC 6-4testSTC64SKHHSH_03/3
STA 7-5testST75SKHHSH_03/3
STC 7-5testSTC75SKHHSH_03/3
All requirementsall tests04/4
Summary metrics
MetricValueTag
Total lines546 (src 528, own tests 18)recomputed
Lines of code423 (src 410, own tests 13)recomputed
Classes16recomputed
Methods65recomputed
Fields31recomputed
Bench median ms659recomputed
Bench volume100614 inputs, 40083576 output charsrecomputed

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
MetricValueTag
Mutation score101/129, 0 not run, adjusted 101/121 (20 of 28 survivors fail hidden tests)recomputed
PMD lines0 (0 violations)recomputed
Dependency edges48recomputed
Review scores (superseded)Alterability 5, Code quality principles 3.9, Test quality 3unchecked
Tokens6,674,721 (input 258, cache creation 415,253, cache read 6,146,047, output 113,163)recomputed
Weighted tokens1,392,442recomputed
Wall time0:24:20recomputed
Agent time0:23:15recomputed
Agent calls9recomputed
Audit flags1 high, 19 low, 1 of 1 high have a dispositionrecomputed

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.

Review scores, 11 rows and 4 columns

Alterability. Item: Change Case 1: sow seeds anti-clockwise. Score /5: 5.

Reason: Direction is a strategy chosen once in Variant, and Board, Player.houses and Sowing all walk the board via pitAfter. Changing the direction touches only the Direction implementations and one selector line.

Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.

Reason: House count and seed count live only in Variant. Board, BoardView and the house walking derive everything from houseCount, so the change is two literals.

Code quality principles. Item: 1. Clear Presentation. Score /5: 4.

Reason: Small classes with consistent formatting and short methods. The private static repeat helper sits between the public render methods, and some methods are ordered loosely.

Code quality principles. Item: 2. Explanatory Language. Score /5: 4.

Reason: Names are descriptive and the class Javadocs and why-comments help, such as the store placement and capture comments. The 'House is empty' message also covers out-of-range numbers, and literals like 7, 6, 5, 4 are not named constants.

Code quality principles. Item: 3. Consistent Code. Score /5: 4.

Reason: Uniform final package-private classes, constructor injection and naming. Some helpers are private while similar ones such as renderTopRow and renderStore are package-private with no visible reason.

Code quality principles. Item: 4. Used Content. Score /5: 4.

Reason: Nearly everything is used. renderTopRow, renderBottomRow and renderStore are wider than needed, and GameResult.winner returning Optional<Integer> is only used internally.

Code quality principles. Item: 5. Simple Constructs. Score /5: 3.

Reason: Most methods are short and flat. The Board constructor placement via direction.next and isBottomRow, and Player.houses walking around the board to find its houses, are clever and take effort to follow.

Code quality principles. Item: 6. Minimal Duplication. Score /5: 4.

Reason: Row rendering shares startRow and endRow, and sowing order is computed in one place. Player.houses is recomputed by walking the board on every call from several sites, but the logic itself is not duplicated.

Code quality principles. Item: 7. Modular Structure. Score /5: 4.

Reason: Clear responsibilities across Board, Sowing, Turn, Game, GameResult, BoardView and Console. Player depends on Board and Board on Player ownership, giving some circular coupling.

Code quality principles. Item: 8. Problem Alignment. Score /5: 4.

Reason: Domain terms such as Pit, Sowing, Move, Turn and Score match the game well. Modelling the board as screen positions with direction-derived ownership is less natural than the domain view of player sides.

Test quality. Item: Test quality. Score /5: 3.

Reason: Three named acceptance specs add capture and extra-turn coverage for two variants on top of the example specs. There are no unit tests for Board, Sowing, Move or the store-skipping rule, and the variant coverage of the new specs is partial.

Audit flags

1 high and 19 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.

Channelpmd_suppression
Agent or commitd379baed356d6703c8b03e9bd0ba9d80b83fca4d
Tool-
PathMEASURE.md:40
MarkerNOPMD
Dispositionfalse positive
Channelpmd_suppression
DefinitionA NOPMD or PMD @SuppressWarnings in any line a commit added, prose included.

Dispositions from the run's findings.json judge every high flag of their channel.

pmd_suppression. Verdict: false positive. Tag: verified.

Evidence: MEASURE.md:40 at commit d379bae is the measure agent's sentence saying no NOPMD appears. git grep of NOPMD and SuppressWarnings over src and test on the branch finds none.

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, 8 rows and 10 columns

2026-10-26T10:45:30Z. Step: s1. Unit: Gather spec and acceptance tests. Tests added: 3. Cycles: 0. Sha: 6b9ae53. Agent: rep-1-r13:s1. Tokens: 430499. Seconds: 147.679.

Actions: Gathered README, SPEC and six example specs. Added AcceptanceTest with three hand-simulated specs under test/ for untested features: clockwise capture, README clockwise extra turn and wrap, anti-clockwise 7-5 variant with capture. Step names no check so ./run.sh was not run; the new tests are expected red on the stub. Untested still: skipping the opponent store, a P1 win message.

2026-10-26T10:46:18Z. Step: s2. Unit: Extract noun-verb lists. Tests added: 0. Cycles: 0. Sha: 536ce43. Agent: rep-1-r13:s2. Tokens: 274012. Seconds: 42.486.

Actions: Wrote design/NOUN_VERB_MAP.md with a raw Noun: -verb extraction from README, SPEC and example specs, then a trimmed domain list of 13 nouns. Dropped test, build and marking nouns; merged Pit, Sowing, Opponent, Capture, Prompt, Message and Change case. Board (7 verbs), Game (5) and Move (5) exceed 4 verbs and are left for the s3 split. Step names no check so ./run.sh was not run.

2026-10-26T10:47:16Z. Step: s3. Unit: Parents, splits and Clean Code names. Tests added: 0. Cycles: 0. Sha: 17ddacf. Agent: rep-1-r13:s3. Tokens: 209412. Seconds: 58.155.

Actions: Added a Parents, splits and names section to design/NOUN_VERB_MAP.md. Marked House(Pit), Store(Pit), Clockwise(Direction), AntiClockwise(Direction) and Console(IO). Split Board (7) into Board and Sowing, Game (5) into Game and GameResult, Move (5) into Move and Sowing, and moved Player score to Score. Every noun now has at most 4 verbs. Renamed verbs to Clean Code names. Duplicates stay for s4. Step names no check so ./run.sh was not run. The map section was appended with a shell heredoc, which conflicts with the edit-tool guidance.

2026-10-26T10:48:02Z. Step: s4. Unit: Replace duplicate verbs with references. Tests added: 0. Cycles: 0. Sha: 44685d1. Agent: rep-1-r13:s4. Tokens: 247074. Seconds: 46.562.

Actions: Added a References section to design/NOUN_VERB_MAP.md. Wrote 17 verb1(Noun2.verb3) references, for example Kalah -play(Game.play), Player -canMove(House.isEmpty), Turn -isRepeated(Sowing.endsInStore) and GameResult -winner(Score.compare). Direction -next overrides in Clockwise and AntiClockwise stay as inheritance. Every noun still has at most 4 verbs. Cycle and dangling checks are left for s5. Step names no check so ./run.sh was not run.

2026-10-26T10:49:21Z. Step: s5. Unit: Script-check the noun-verb map. Tests added: 0. Cycles: 0. Sha: 23ef7b1. Agent: rep-1-r13:s5. Tokens: 432670. Seconds: 75.857.

Actions: Added design/check_map.py. It parses the References section, resolves inherited verbs through parents and reports cycles in the verb reference graph, dangling references and nouns over 4 verbs. Exits 1 on any problem. A seeded broken map in .scratch showed all three problem kinds. The real map gave 0 problems, so nothing needed fixing. Added a Checks section to design/NOUN_VERB_MAP.md. It notes 19 references, which corrects the count of 17 in the s4 row. The step names no ./run.sh check so it was not run.

2026-10-26T10:57:02Z. Step: s6. Unit: Scaffold stubs and fill them. Tests added: 0. Cycles: 0. Sha: 5acc891. Agent: rep-1-r13:s6. Tokens: 2133176. Seconds: 463.574.

Actions: Scaffolded 18 classes under src/kalah from the References section in one commit (a9030ac). Each verb stub threw a TODO naming its referenced method, or itself when unreferenced. Then filled the 42 stubs one per commit, 42 commits, with leaf verbs first and Game.play last. No TODO is left. Deviations from the map: Board stores pits by screen position and Direction.next steps up or down that numbering, so the anti-clockwise variant reuses the same layout. BoardView needs pits by position, so Board -houseAt became -pitAt and Player -houses now walks Board.pitAfter. Turn -prompt returns the prompt text because Console.readLine prints it through IO.readFromKeyboard. GameResult -winner returns the player number. Private helpers Board.placeSide, Board.isBottomRow, Sowing.isOpponentStore, BoardView.renderHouse, BoardView.repeat and Game.end were added. The step names no check, so ./run.sh was not run and nothing has been compiled. Its standing guidance to run static checks conflicts with this. The commits were made through a .scratch/commit.sh helper that stages one file by path.

2026-10-26T10:59:02Z. Step: s7. Unit: Run the tests and fix failing tests. Tests added: 0. Cycles: 3. Sha: 55f2f3e. Agent: rep-1-r13:s7. Tokens: 675985. Seconds: 117.262.

Actions: First ./run.sh test compiled and both Example classes passed. The three AcceptanceTest specs failed on line 7 because the s1 spec files lost the trailing space after the prompt "quit: ". Fixed one spec per commit by restoring that space, with ./run.sh test AcceptanceTest after each: capture STC 6-4, capture STA 7-5, then extra turn STC 6-4. No production code changed. Final ./run.sh test: 3 classes run, 0 failed. The Edit tool drops trailing spaces, so the spec edits used sed -i, which conflicts with the edit-tool guidance.

2026-10-26T11:05:27Z. Step: s8. Unit: Lint, prune and diff a regenerated map. Tests added: 0. Cycles: 3. Sha: 125f893. Agent: rep-1-r13:s8. Tokens: 2057440. Seconds: 397.214.

Actions: First ./run.sh lint gave 28 distinct findings: CastUse and InstanceOfUse on House and Store narrowing, CouplingBetweenObjects 7 on Board and 10 on Game, and LineLength. No suppressions were added. Three lint-driven refactor cycles, each followed by a green ./run.sh test: merged House and Store into Pit and pruned both classes (cd2bb38); moved the current player and move sowing into Turn, the quit choice into Move and the wiring into Kalah, pruning Game.isOver, Game.takeTurn, Turn.nextPlayer and Turn.isRepeated (406fe47); wrapped GameResult lines (b6113ed). Final ./run.sh lint has 0 findings and final ./run.sh test runs 3 classes with 0 failed. A grep found no other uncalled method. Added design/regen_map.py, which writes design/REGENERATED_MAP.md from the code and diffs it against the plan: 19 differences, each explained in a new section of design/NOUN_VERB_MAP.md, and 0 check problems. The step names no ./run.sh deps or mutate run, so neither ran.

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.

Figure 12.6

Class diagram of method/rep-1-r13
kalahAntiClockwiseBoardBoardViewClockwiseConsoleDirectionGameGameResultKalahMovePitPlayerScoreSowingTurnVariant

16 classes and 67 links. Tag: recomputed.

Text version: Class diagram of method/rep-1-r13
  1. Package kalah: AntiClockwise, Board, BoardView, Clockwise, Console, Direction, Game, GameResult, Kalah, Move, Pit, Player, Score, Sowing, Turn, Variant
  2. AntiClockwise extends Direction
  3. Board uses AntiClockwise
  4. Board uses Clockwise
  5. Board uses Direction
  6. Board holds Direction
  7. Board uses Pit
  8. Board holds Pit
  9. Board uses Player
  10. Player uses Board
  11. Board uses Variant
  12. BoardView uses Board
  13. BoardView uses Console
  14. BoardView holds Console
  15. BoardView uses Pit
  16. BoardView uses Player
  17. Clockwise extends Direction
  18. Game uses Board
  19. Game holds Board
  20. Game uses BoardView
  21. Game holds BoardView
  22. Game uses Console
  23. Game holds Console
  24. Game uses GameResult
  25. Game holds GameResult
  26. Game uses Turn
  27. Game holds Turn
  28. GameResult uses Board
  29. GameResult uses Console
  30. GameResult holds Console
  31. GameResult uses Player
  32. GameResult uses Score
  33. GameResult holds Score
  34. Kalah uses Board
  35. Kalah uses BoardView
  36. Kalah uses Console
  37. Kalah uses Game
  38. Kalah uses GameResult
  39. Kalah uses Player
  40. Kalah uses Turn
  41. Kalah uses Variant
  42. Move uses Board
  43. Move uses Pit
  44. Move uses Player
  45. Pit uses Player
  46. Pit holds Player
  47. Player uses Pit
  48. Score uses Board
  49. Score holds Board
  50. Score uses Pit
  51. Score uses Player
  52. Score holds Player
  53. Sowing uses Board
  54. Sowing holds Board
  55. Sowing uses Pit
  56. Sowing holds Pit
  57. Sowing uses Player
  58. Sowing holds Player
  59. Turn uses Board
  60. Turn uses Console
  61. Turn holds Console
  62. Turn uses Move
  63. Turn uses Player
  64. Turn holds Player
  65. Turn uses Sowing
  66. Variant uses AntiClockwise
  67. Variant uses Clockwise
  68. Variant uses Direction
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: Noun-verb map. Sources are LOG.md, git log and design/NOUN_VERB_MAP.md. GAP.md and ATTEMPTS.md do not exist in this clone.

## Credits per step

Credits and time are measured by the harness. This file does not record them. LOG.md gives the per-step work below.

| step | unit | cycles | tests added | commits |
|---|---|---|---|---|
| s1 | Gather spec and acceptance tests | 0 | 3 | 2 |
| s2 | Extract noun-verb lists | 0 | 0 | 2 |
| s3 | Parents, splits and Clean Code names | 0 | 0 | 2 |
| s4 | Replace duplicate verbs with references | 0 | 0 | 2 |
| s5 | Script-check the noun-verb map | 0 | 0 | 3 |
| s6 | Scaffold stubs and fill them | 0 | 0 | 44 |
| s7 | Run the tests and fix failing tests | 3 | 0 | 4 |
| s8 | Lint, prune and diff a regenerated map | 3 | 0 | 5 |

Commit counts include each step's LOG.md commit. The branch holds 64 commits after the starter kit.

## Map defects caught at step 5

Zero. design/check_map.py found no cycles, no dangling references and no noun over 4 verbs in the real map. A seeded broken map in .scratch showed the script detects all three kinds. The step corrected one count in the log: the map has 19 references and the s4 row said 17.

## Plan drift at step 8

design/regen_map.py reports 19 differences between the code and the planned References section, with 0 check problems on the regenerated map. The main drift groups are these.
- House and Store merged into Pit to clear PMD CastUse and InstanceOfUse.
- Board.-houseAt became -pitAt in s6 for screen-position rendering.
- Game.-isOver, Game.-takeTurn, Turn.-nextPlayer, Turn.-isRepeated and Turn.-readHouseOrQuit were removed to cut Game coupling from 10. Turn and Kalah took that work.
- Move.-houseNumber became -house and Move.-isQuit replaced an Optional.
- Turn.-prompt, Sowing.-capturesAt and Sowing.-capture became private.
- Console wraps IO and does not extend it.

s6 also logged earlier deviations that feed this drift, such as six private helpers and Board numbering pits by screen position.

## Suppressions and build-file edits attempted

Zero. LOG.md s8 records no suppressions added. No commit after the starter kit touches run.sh, kalah_pmd.xml, docs/, examples/, resources/ or test/kalah/Example*.java. A grep finds no SuppressWarnings or NOPMD in src or test. Lint went from 28 findings to 0 through code changes only.
Replicate rep-1-r19: functional mark 15/15, strict PMD pass, classes 15, weighted tokens 1,312,880

Replicate rep-1-r19

Branch method/rep-1-r19. 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 /1515/15
Hidden pass /7676/76
Unseen pass /6969/69
Acceptance pass /66/6
Strict PMD compliancepass

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 setTestsFailuresMarks
Original set, STA 6-4testST64SKHHSH_02/2
STC 6-4testSTC64SKHHSH_03/3
STA 7-5testST75SKHHSH_03/3
STC 7-5testSTC75SKHHSH_03/3
All requirementsall tests04/4
Summary metrics
MetricValueTag
Total lines550 (src 524, own tests 26)recomputed
Lines of code424 (src 405, own tests 19)recomputed
Classes15recomputed
Methods69recomputed
Fields28recomputed
Bench median ms601recomputed
Bench volume100614 inputs, 40083576 output charsrecomputed

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
MetricValueTag
Mutation score106/115, 0 not run, adjusted 106/110 (4 of 9 survivors fail hidden tests)recomputed
PMD lines0 (0 violations)recomputed
Dependency edges45recomputed
Review scores (superseded)Alterability 5, Code quality principles 4.1, Test quality 3unchecked
Tokens5,630,799 (input 220, cache creation 420,306, cache read 5,103,856, output 106,417)recomputed
Weighted tokens1,312,880recomputed
Wall time0:21:17recomputed
Agent time0:20:23recomputed
Agent calls9recomputed
Audit flags1 high, 2 low, 1 of 1 high have a dispositionrecomputed

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.

Review scores, 11 rows and 4 columns

Alterability. Item: Change Case 1: sow seeds anti-clockwise. Score /5: 5.

Reason: Direction is read only in BoardView.print, which swaps the row layout. Sowing order stays as it is, so the change touches one method and works with either board size.

Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.

Reason: House and seed counts live only in Rules, and Board, BoardView and Score all derive sizes from the lists. Nothing hard-codes 6 or 4.

Code quality principles. Item: 1. Clear Presentation. Score /5: 4.

Reason: Classes are small and laid out consistently with short methods. Game.start's while(true) with two early returns and Move reaching through board.sowing().lastPit() slightly obscure the flow.

Code quality principles. Item: 2. Explanatory Language. Score /5: 4.

Reason: Names like Sowing, Turn, endsInCapture and grantExtraTurn read as domain terms, and the brief doc comments explain why. The Pit.asHouse null-return idiom and Turn.grantExtraTurn's name hide simple checks.

Code quality principles. Item: 3. Consistent Code. Score /5: 4.

Reason: Package-private final classes, constructor injection and naming are uniform throughout. Store lookup mixes ordinal indexing with list-based house access, which is a small inconsistency.

Code quality principles. Item: 4. Used Content. Score /5: 4.

Reason: Almost all code is used. Board.sowing() exists only so Move can query the last pit, and Turn.grantExtraTurn is a pass-through that adds little.

Code quality principles. Item: 5. Simple Constructs. Score /5: 4.

Reason: Plain loops and lists keep the logic simple. The asHouse null check and do-while with indexOf in Sowing are a little indirect for what they do.

Code quality principles. Item: 6. Minimal Duplication. Score /5: 4.

Reason: Row drawing, border building and totals are each written once. The last-pit queries in Move repeat asHouse/owner checks in two methods.

Code quality principles. Item: 7. Modular Structure. Score /5: 4.

Reason: Model, rules, view and game loop sit in separate cohesive classes. Move is coupled to Board's Sowing internals, and Turn depends on Move only to delegate one call.

Code quality principles. Item: 8. Problem Alignment. Score /5: 5.

Reason: Classes map directly onto Kalah concepts: houses, stores, sowing ring, opposite-house capture, turns and score. The variant flags map to one Rules object.

Test quality. Item: Test quality. Score /5: 3.

Reason: Five added spec-file tests fill variant gaps such as anticlockwise 7-5 and the clockwise quit and full game, and their names are clear. There are no focused unit tests for sowing, store skipping or capture, so failures only show up as whole-transcript mismatches.

Audit flags

1 high and 2 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.

Channelpmd_suppression
Agent or commite35018bacd17fb2b7580d8de27e57ca4f7db6ad3
Tool-
PathMEASURE.md:28
MarkerNOPMD
Dispositionfalse positive
Channelpmd_suppression
DefinitionA NOPMD or PMD @SuppressWarnings in any line a commit added, prose included.

Dispositions from the run's findings.json judge every high flag of their channel.

pmd_suppression. Verdict: false positive. Tag: verified.

Evidence: MEASURE.md:28 at commit e35018b is the measure agent's sentence saying no NOPMD appears. git grep of NOPMD and SuppressWarnings over src and test on the branch finds none.

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, 8 rows and 10 columns

2026-10-26T10:47:38Z. Step: s1. Unit: Gather spec and acceptance tests; test untested features. Tests added: 5. Cycles: 1. Sha: dbbf6b1. Agent: rep-1-r19:s1. Tokens: 1514063. Seconds: 274.804.

Actions: Read README, SPEC, EXAMPLES and the six example specs. Built a scratch reference model in .scratch that reproduces all six example specs exactly and used it to derive five new specs under test/ (STA 7-5 simple start, STA 7-5 full game P1 wins with P2 out of moves, STA 6-4 use empty, STC 6-4 quit, STC 6-4 full game P1 wins). Added SpecVariantsTest; ./run.sh test SpecVariantsTest is red 5 of 5 on the stub as expected, and ./run.sh specs test also played them (extra check beyond the step). Conflict: Write and Edit strip trailing spaces, so the required trailing space after each prompt was added with sed. Untested and left out: out-of-range input, because MockIO's reprompt output is undocumented.

2026-10-26T10:48:26Z. Step: s2. Unit: Extract nouns and verbs; trim to the domain. Tests added: 0. Cycles: 0. Sha: 9da5df1. Agent: rep-1-r19:s2. Tokens: 272665. Seconds: 43.787.

Actions: Read README, SPEC and EXAMPLES with the example spec end-of-game lines. Wrote design/MAP.md with a raw Noun: -verb extraction (31 nouns) and a trimmed domain list (14 nouns) with the reason for each drop. No code or tests changed and no checks run because the step names none. Parents, splits and references are left for stage s3 and s4.

2026-10-26T10:49:21Z. Step: s3. Unit: Mark parents, split nouns over 4 verbs, apply Clean Code names. Tests added: 0. Cycles: 0. Sha: d47b1e1. Agent: rep-1-r19:s3. Tokens: 234472. Seconds: 52.276.

Actions: Added a stage s3 section to design/MAP.md. Marked House(Pit) and Store(Pit) and folded Variant and Direction into Rules. Split Board (5 verbs) by moving -print to BoardView and moved Score -printResult to ResultView. Renamed 18 verbs to intention-revealing names with boolean queries as is, has or ends. Every noun now has 4 verbs or fewer. No code or tests changed and no checks run because the step names none. Duplicate verbs are left for stage s4.

2026-10-26T10:50:17Z. Step: s4. Unit: Replace duplicate verbs with references. Tests added: 0. Cycles: 0. Sha: 92ae0df. Agent: rep-1-r19:s4. Tokens: 218529. Seconds: 55.313.

Actions: Added a stage s4 section to design/MAP.md. Found 19 duplicate verbs and wrote each as verb1(Noun2.verb3) pointing at the owning noun. House and Store -owner lift to Pit -owner. Output and input verbs reference IO. Empty, count and last-pit tests reference House, Pit and Sowing. Score -totalFor references Pit.seedCount because README scores houses plus store. No code or tests changed and no checks run because the step names none. Cycle and dangling-reference script check left for stage s5.

2026-10-26T10:51:26Z. Step: s5. Unit: Script-check the map for cycles, dangling references and nouns over 4 verbs. Tests added: 0. Cycles: 0. Sha: f9339f1. Agent: rep-1-r19:s5. Tokens: 330444. Seconds: 67.058.

Actions: Added design/check_map.py, which parses the last Map after section of design/MAP.md, resolves references through parents and checks dangling references, method-level and noun-level cycles and declared-verb counts over 4. On the s4 map it reports 0 dangling of 23 references, 0 cycles and 0 of 16 nouns over 4 verbs, so nothing needed fixing. A seeded faulty map in .scratch made it report all four fault kinds, so the check is live. Recorded the result in a stage s5 section of design/MAP.md. No Java code or tests changed and no ./run.sh checks run because the step names none.

2026-10-26T10:56:30Z. Step: s6. Unit: Scaffold TODO stubs from the s4 map and fill one per prompt. Tests added: 0. Cycles: 0. Sha: dad0381. Agent: rep-1-r19:s6. Tokens: 1503310. Seconds: 310.512.

Actions: Commit 45c195f scaffolded 14 classes under src/kalah (Player, Pit, House, Store, Rules, Sowing, Board, BoardView, Turn, Move, Prompt, Score, ResultView, Game) and replaced the Kalah.play stub. Each of the 36 map verbs threw a TODO naming its referenced method, or its own name for a leaf verb. Then 36 commits each filled one stub, leaves first and Kalah.play last, so no TODO remains. Deviations from the map: wiring outside the verbs was written in the scaffold (constructors, House.linkOpposite, Board.house, Board.houses, Board.store, Board.sowing, Turn.current) plus private format helpers in BoardView and ResultView. Player is an enum, so -name is the inherited name(). Game.end takes a playedOut flag because quitting prints no scores. Prompt.show prints the prompt and readChoice calls readFromKeyboard with an empty prompt, which is unverified against MockIO. No ./run.sh check ran because the step names none, so compilation and the tests are unverified until stage s7. Conflict: standing guidance asks for checks on changed code. The step governs, so none ran.

2026-10-26T10:57:09Z. Step: s7. Unit: Run the tests and fix one failing test per prompt. Tests added: 0. Cycles: 0. Sha: 6e844c4. Agent: rep-1-r19:s7. Tokens: 184304. Seconds: 36.711.

Actions: Ran ./run.sh test once at 6e844c4. It compiled and reported OK (5 tests) across 3 classes with 0 failed, including the full-game example tests and SpecVariantsTest. With no failing test there was nothing to fix, so no code changed and no fix commit was made. Only this LOG.md row was committed.

2026-10-26T11:03:00Z. Step: s8. Unit: Lint with no suppressions, prune unused methods, diff a regenerated map. Tests added: 0. Cycles: 1. Sha: 9bda445. Agent: rep-1-r19:s8. Tokens: 1191784. Seconds: 347.928.

Actions: First ./run.sh lint reported 92 findings: 85 LineLength, 3 InstanceOfUse, 2 CastUse and CouplingBetweenObjects on Board (9) and Game (8). One rework in 918b147 wrapped long lines, replaced instanceof and casts with Pit.asHouse, moved the sowing loop to Sowing, gave Move the prompt, sow and capture, made Kalah.play build Rules, Board and BoardView, and swapped Board maps for lists. It also pruned the unused House.houseNumber and Board.store and moved removeAllSeeds to House. The second ./run.sh lint was clean with no suppressions. 9bda445 added a regenerated Map after s8 and a diff table against the s4 plan to design/MAP.md. Conflict: standing guidance asks for tests on changed code. The step names only lint, so ./run.sh test and design/check_map.py did not run and behaviour after the rework is unverified.

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: Noun-verb map. Sources are LOG.md, git log and design/MAP.md. GAP.md and ATTEMPTS.md do not exist in this clone.

## Credits per step

Credits and time are measured by the harness. This clone does not record them.

## Map defects caught at step 5

Zero. `design/check_map.py` on the s4 map found 0 of 23 dangling references, 0 method cycles, 0 noun cycles and 0 of 16 nouns over 4 verbs. A seeded faulty map in .scratch made it report all four fault kinds, so the check was live. Step s7 then found 0 failing tests in 5, so no map defect surfaced later as a test failure.

## Plan drift at step 8

8 of 16 nouns drifted from the s4 plan across 9 verb changes. The drift came from one lint rework in 918b147 that cleared 92 PMD findings.

| Cause | Changes |
|---|---|
| CouplingBetweenObjects on Board (9) and Game (8) | Kalah builds Rules, Board and BoardView. Game -start and -takeTurn now reference BoardView and Move. Board -sow moved its loop into Sowing -sow. Move owns choose, sow and capture |
| InstanceOfUse and CastUse | Pit -removeAllSeeds replaced by -asHouse. Board -capture now references House.removeAllSeeds |
| Pruning unused methods | House -houseNumber and the Board store accessor removed. Score -totalFor now references Board.storeSeeds |
| Visibility | Sowing -nextPit and -isSkipped and Move -endsInCapture became private |

Unchanged nouns: Rules, BoardView, Player, Turn, Prompt, ResultView, IO and Store. Every noun keeps 4 map verbs or fewer after s8. Behaviour after the rework is unverified because step s8 ran only lint.

## Suppressions or build-file edits attempted

Zero suppressions and zero build-file edits. `git log` shows run.sh and kalah_pmd.xml changed only in the starter commit ff53319. `git grep` finds no SuppressWarnings, NOPMD or CHECKSTYLE markers in src or test. The second `./run.sh lint` in s8 was clean with no suppressions. No ATTEMPTS.md records any attempt.
Replicate rep-1-r20: functional mark 15/15, strict PMD pass, classes 15, weighted tokens 1,508,326

Replicate rep-1-r20

Branch method/rep-1-r20. 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 /1515/15
Hidden pass /7676/76
Unseen pass /6969/69
Acceptance pass /66/6
Strict PMD compliancepass

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 setTestsFailuresMarks
Original set, STA 6-4testST64SKHHSH_02/2
STC 6-4testSTC64SKHHSH_03/3
STA 7-5testST75SKHHSH_03/3
STC 7-5testSTC75SKHHSH_03/3
All requirementsall tests04/4
Summary metrics
MetricValueTag
Total lines522 (src 485, own tests 37)recomputed
Lines of code400 (src 375, own tests 25)recomputed
Classes15recomputed
Methods63recomputed
Fields28recomputed
Bench median ms570recomputed
Bench volume100614 inputs, 40083576 output charsrecomputed

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
MetricValueTag
Mutation score89/96, 0 not run, adjusted 89/91 (2 of 7 survivors fail hidden tests)recomputed
PMD lines0 (0 violations)recomputed
Dependency edges56recomputed
Review scores (superseded)Alterability 5, Code quality principles 3.8, Test quality 3unchecked
Tokens8,857,615 (input 308, cache creation 438,411, cache read 8,309,995, output 108,901)recomputed
Weighted tokens1,508,326recomputed
Wall time0:23:41recomputed
Agent time0:22:45recomputed
Agent calls9recomputed
Audit flags1 high, 5 low, 1 of 1 high have a dispositionrecomputed

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.

Review scores, 11 rows and 4 columns

Alterability. Item: Change Case 1: sow seeds anti-clockwise. Score /5: 5.

Reason: The direction is shown to be purely a rendering mirror. SowingPath ignores it and only the BoardPrinter clockwise branch differs, so the change lives in one if statement in one class.

Alterability. Item: Change Case 2: 7 houses with 5 seeds. Score /5: 5.

Reason: Variant.houseCount and initialSeeds are the only place 7 and 5 appear. Side, BoardPrinter borders and House.opposite all derive from the count.

Code quality principles. Item: 1. Clear Presentation. Score /5: 4.

Reason: Small, consistently formatted classes with short Javadoc headers. Board.sow is a little hard to follow because sowing happens inside a method named lastPit.

Code quality principles. Item: 2. Explanatory Language. Score /5: 3.

Reason: Most names follow the domain (House, Store, Side, SowingPath). Move.lastPit actually performs the sowing, and the quit marker 0 is passed around as a house number, which misleads the reader.

Code quality principles. Item: 3. Consistent Code. Score /5: 4.

Reason: Constructors, printers and loops share one style throughout. Mutation is mixed between the protected seedCount field and public methods, and some helpers are public while others are private without a clear rule.

Code quality principles. Item: 4. Used Content. Score /5: 3.

Reason: Player.chooseHouse and Player.score only forward to Prompter and Score. Game.quit and end are thin wrappers, Board.capture and Game.takeTurn are public for no caller, and the return value of lastPit is never used.

Code quality principles. Item: 5. Simple Constructs. Score /5: 4.

Reason: Plain loops and lists keep the logic simple. Move.landedHouse does get(indexOf(last)) to stand in for a cast, and SowingPath looks up indexOf on every seed.

Code quality principles. Item: 6. Minimal Duplication. Score /5: 4.

Reason: Board drawing, store formatting and side construction are each written once. The leftStore and rightStore helpers differ only by one leading bar.

Code quality principles. Item: 7. Modular Structure. Score /5: 4.

Reason: Model, sowing path, printing and prompting are separated cleanly. Responsibilities leak in places: Player depends on Prompter and Score, and Move both mutates the board and answers questions about the result.

Code quality principles. Item: 8. Problem Alignment. Score /5: 4.

Reason: Classes follow Kalah concepts and the insight that direction only mirrors the display keeps the rules in one place. Routing quit through an int sentinel and Player.chooseHouse fit the domain less well.

Test quality. Item: Test quality. Score /5: 3.

Reason: Seven clearly named, independent spec-file tests add coverage for the 7-5 anti-clockwise variant, captures and P1 wins. They are only end-to-end transcripts, with no unit tests on sowing, capture or skipping the opponent's store, and the variant matrix is covered unevenly.

Audit flags

1 high and 5 low flags from agent tool calls and the method's commits. Only audit.json lists the low flags.

Channelpmd_suppression
Agent or commit18834b0e61e4f3bd45352f32be764344db95a1ac
Tool-
PathMEASURE.md:42
MarkerNOPMD
Dispositionfalse positive
Channelpmd_suppression
DefinitionA NOPMD or PMD @SuppressWarnings in any line a commit added, prose included.

Dispositions from the run's findings.json judge every high flag of their channel.

pmd_suppression. Verdict: false positive. Tag: verified.

Evidence: MEASURE.md:42 at commit 18834b0 is the measure agent's sentence saying no NOPMD appears. git grep of NOPMD and SuppressWarnings over src and test on the branch finds none.

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, 8 rows and 10 columns

2026-10-26T10:07:26Z. Step: s1. Unit: Gather spec and acceptance tests; test untested features. Tests added: 7. Cycles: 1. Sha: f03e9fd. Agent: rep-1-r20:s1. Tokens: 1486087. Seconds: 303.742.

Actions: Read README, SPEC, EXAMPLES and the six example specs. Untested features found: anti-clockwise 7-5 variant, 7-house capture opposite, 7-house store landing, P1 win output. Built a scratch oracle in .scratch that reproduces all six example specs byte for byte and used it to generate 7 spec files under test/specs, tested by VariantSpecTest. Conflict: the Write tool strips the trailing space the prompt lines need, so the spec bodies were written by a shell script from oracle output against the no-scripted-edits guidance. ./run.sh test: 13 tests, all red on the stub as expected; green belongs to later stages.

2026-10-26T10:08:27Z. Step: s2. Unit: Extract nouns and verbs as Noun: -verb lists; trim to the domain. Tests added: 0. Cycles: 0. Sha: c84ce1a. Agent: rep-1-r20:s2. Tokens: 329776. Seconds: 55.288.

Actions: Read README, SPEC, EXAMPLES and the example and test specs. Wrote design/MAP.md with the full extraction (35 nouns) and a trimmed domain list of 12 nouns. Dropped tooling and brief nouns, hid the test harness behind IO, merged Pit into House and Store, Sowing into Move and Message and Prompt into Display. Over-4-verb nouns (Board, Display) left for the stage 3 split. No checks named so ./run.sh was not run. No code change so no red-green cycles.

2026-10-26T10:09:07Z. Step: s3. Unit: Mark parents, split nouns over 4 verbs, apply Clean Code names. Tests added: 0. Cycles: 0. Sha: d22d732. Agent: rep-1-r20:s3. Tokens: 201947. Seconds: 38.937.

Actions: Added a stage s3 section to design/MAP.md. Pit made the parent of House(Pit) and Store(Pit) holding -seeds -receiveSeed. Split Board into Board and Side, Move into Move and SowingPath, Display into BoardPrinter, Prompter and ResultPrinter. Renamed Input to MoveReader, Score -compare to -winner, Variant -seedCount to -initialSeeds, House -takeAll to -takeAllSeeds. All 17 nouns now have 4 verbs or fewer. No checks named so ./run.sh was not run. No code change so no red-green cycles. LOG.md appended with printf since the Write tool would rewrite the file.

2026-10-26T10:10:02Z. Step: s4. Unit: Replace duplicate verbs with references. Tests added: 0. Cycles: 0. Sha: 9eb3b05. Agent: rep-1-r20:s4. Tokens: 241691. Seconds: 51.64.

Actions: Added a stage s4 section to design/MAP.md. 15 verbs became references such as play(Game.start), score(Score.total), lastPit(SowingPath.next), isEmpty(Pit.seeds) and the printing verbs as print(IO.println). All references point to leaf nouns so no cycle was introduced. No checks named so ./run.sh was not run. No code change so no red-green cycles. LOG.md appended with printf since the Write tool would rewrite the file.

2026-10-26T10:11:10Z. Step: s5. Unit: Script-check the map for cycles, dangling references and nouns over 4 verbs. Tests added: 0. Cycles: 0. Sha: 4486123. Agent: rep-1-r20:s5. Tokens: 303712. Seconds: 60.703.

Actions: Wrote design/mapcheck.py checking verbs per noun, dangling parents, dangling reference nouns and verbs with inheritance, and verb and noun cycles. Seeded a bad map in .scratch and saw every check fire. The stage s4 map passed (17 nouns, 15 references, 2 parents) so nothing needed fixing. Added a stage s5 section to design/MAP.md. The script went in one commit and the MAP note in a second because the first Edit missed. No checks named so ./run.sh was not run. No code change so no red-green cycles. LOG.md appended with printf since the Write tool would rewrite the file.

2026-10-26T10:18:30Z. Step: s6. Unit: Scaffold stubs that throw a TODO naming the referenced method; fill one per prompt. Tests added: 0. Cycles: 0. Sha: 22d1a76. Agent: rep-1-r20:s6. Tokens: 4095846. Seconds: 448.385.

Actions: One scaffold commit added a class per stage s4 noun (16 classes plus Kalah) with every map verb throwing UnsupportedOperationException("TODO <referenced method>"). Then 39 fill commits, one method each, bottom up from Pit to Kalah.play. No TODO remains. Deviations from the map: Player is an enum so opponent needs no wiring; House.opposite, Score.total, Player.score and Player.chooseHouse take the Side, Player, Score or MoveReader they need as a parameter; Move.lastPit(House) sows the seeds and records the last pit, and Board.sow calls capture itself; BoardPrinter.print has private row helpers. Prompter prints the prompt with IO.print and MoveReader reads with readFromKeyboard(""), as the map references say. The step names no check so ./run.sh was not run and nothing was compiled; compile and test results belong to stage s7. No test runs, so 0 red-green cycles.

2026-10-26T10:19:16Z. Step: s7. Unit: Run the tests and fix one failing test per prompt. Tests added: 0. Cycles: 0. Sha: fc0fd78. Agent: rep-1-r20:s7. Tokens: 283859. Seconds: 52.339.

Actions: Ran ./run.sh test on the stage s6 code. It compiled and all 3 test classes passed (ExampleClockwiseTest 3, ExampleAnticlockwiseTest 3, VariantSpecTest 7). No failing test so no fix commits and no red-green cycles. A second ./run.sh test was run to read the summary lines and gave the same result. Only LOG.md was committed.

2026-10-26T10:24:45Z. Step: s8. Unit: Lint with no suppressions, prune unused methods, diff a regenerated map against the plan. Tests added: 0. Cycles: 4. Sha: 7e3f2bb. Agent: rep-1-r20:s8. Tokens: 1734664. Seconds: 318.74.

Actions: First ./run.sh lint found LineLength in 6 files, CastUse in Board.sow and CouplingBetweenObjects on Board (7) and Game (9). Four lint red-green cycles took it to 0 violations with no suppressions. Long lines were wrapped. Move.landedHouse replaced the cast. Side builds from Variant and Board holds two Side fields (a Side[] array still counted 6). Kalah.play wires Board, BoardPrinter, Prompter and ResultPrinter into Game. MoveReader merged into Prompter. Board.sow takes a house number via the new Side.house. A grep of callers found no unused method, so nothing was pruned. Move.lastPit's return value is now unused but it stays as the map verb. A scratch script regenerated the map from src/kalah. Diff against stage s4: +Move.landedHouse +Side.house +Prompter.readHouseNumber +Prompter.isQuit -MoveReader. Recorded as stage s8 in design/MAP.md. It passes mapcheck.py. Conflict: the step names only lint, so ./run.sh test was not run after the refactor and behaviour was not rechecked.

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.

Figure 12.7

Class diagram of method/rep-1-r20
kalahBoardBoardPrinterGameHouseKalahMovePitPlayerPrompterResultPrinterScoreSideSowingPathStoreVariant

15 classes and 70 links. Tag: recomputed.

Text version: Class diagram of method/rep-1-r20
  1. Package kalah: Board, BoardPrinter, Game, House, Kalah, Move, Pit, Player, Prompter, ResultPrinter, Score, Side, SowingPath, Store, Variant
  2. Board uses House
  3. Board uses Move
  4. Board uses Player
  5. Board uses Side
  6. Board holds Side
  7. Board uses SowingPath
  8. SowingPath uses Board
  9. Board uses Store
  10. Board uses Variant
  11. BoardPrinter uses Board
  12. BoardPrinter uses House
  13. BoardPrinter uses Player
  14. BoardPrinter uses Side
  15. BoardPrinter uses Store
  16. BoardPrinter uses Variant
  17. BoardPrinter holds Variant
  18. Game uses Board
  19. Game holds Board
  20. Game uses BoardPrinter
  21. Game holds BoardPrinter
  22. Game uses House
  23. Game uses Move
  24. Game uses Player
  25. Game holds Player
  26. Game uses Prompter
  27. Game holds Prompter
  28. Game uses ResultPrinter
  29. Game holds ResultPrinter
  30. Game uses Side
  31. House uses Pit
  32. House extends Pit
  33. House uses Side
  34. Side uses House
  35. Kalah uses Board
  36. Kalah uses BoardPrinter
  37. Kalah uses Game
  38. Kalah uses Prompter
  39. Kalah uses ResultPrinter
  40. Kalah uses Variant
  41. Move uses House
  42. Move uses Pit
  43. Move holds Pit
  44. Move uses Side
  45. Move holds Side
  46. Move uses SowingPath
  47. Move holds SowingPath
  48. Player uses Prompter
  49. Prompter uses Player
  50. Player uses Score
  51. Score uses Player
  52. ResultPrinter uses Board
  53. ResultPrinter uses BoardPrinter
  54. ResultPrinter holds BoardPrinter
  55. ResultPrinter uses Player
  56. ResultPrinter uses Score
  57. Score uses Board
  58. Score holds Board
  59. Score uses House
  60. Score uses Side
  61. Score uses Store
  62. Side uses Store
  63. Side holds Store
  64. Side uses Variant
  65. SowingPath uses Pit
  66. SowingPath uses Player
  67. SowingPath uses Side
  68. SowingPath uses Store
  69. SowingPath holds Store
  70. Store uses Pit
  71. Store extends Pit
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

Sources are LOG.md, git log and design/MAP.md. GAP.md and ATTEMPTS.md do not exist in this clone.

## Credits per step

Credits and time are measured by the harness and are not recorded here. LOG.md gives the per-step work counts.

| step | unit | tests added | cycles | commits |
|---|---|---|---|---|
| s1 | Spec tests for untested features | 7 | 1 | 2 |
| s2 | Noun and verb extraction | 0 | 0 | 2 |
| s3 | Parents, splits and names | 0 | 0 | 2 |
| s4 | Duplicate verbs to references | 0 | 0 | 2 |
| s5 | Script check of the map | 0 | 0 | 3 |
| s6 | Scaffold and fill stubs | 0 | 0 | 41 |
| s7 | Run tests and fix failures | 0 | 0 | 1 |
| s8 | Lint, prune and map diff | 0 | 4 | 5 |

Commit counts include each step's LOG.md commit. The s8 count includes its log commit 7500154.

## Map defects caught at step 5

0. design/mapcheck.py checked verbs per noun, dangling parents, dangling references and cycles. A seeded bad map in .scratch fired every check. The stage s4 map passed with 17 nouns, 15 references and 2 parents.

## Plan drift at step 8

5 changes between the stage s4 plan and the map regenerated from src/kalah.

| change | cause |
|---|---|
| + Move.landedHouse | Replaced a House cast flagged by CastUse |
| + Side.house | Board.sow takes a house number to cut coupling |
| + Prompter.readHouseNumber | MoveReader merged into Prompter to cut Game coupling |
| + Prompter.isQuit | Same merge |
| - noun MoveReader | Same merge |

Nouns went from 17 to 16. Every other noun and verb matches. Stage s6 also changed some signatures by adding parameters, which the map does not show.

## Suppressions or build-file edits attempted

0. LOG.md for s8 reports 0 lint violations with no suppressions. A grep of src and test finds no SuppressWarnings or NOPMD. git log shows run.sh and kalah_pmd.xml only in the starter kit commit ff53319.

Terms and columns

See Methodology: measures and the Glossary for the terms and table columns this page uses.