Research Question: RQ-tdd-quality
How does the workflow structure (from oneshot through iterative to strict TDD with subagents) affect code quality, and does TDD strictness make a difference?
game-of-life-prose
| n, run dates | Code quality | Size | Test quality | Correctness | Cost | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ↓ | ↓ | ↓ | ↓ | ↓ | ○ | ↑ | ↑ | ↑ | ○ | ○ | ↓ | ↓ | ↓ | |
| baseline-oneshot-v1-ccad hocn = 10, 2026-05-14 | 155 ± 8.06 🏆 | 4.80 ± 1.23 🏆 | 31.7 ± 3.30 🏆 | 12.8 ± 1.81 🏆 | 18.8 ± 3.58 🏆 | 33.6 ± 1.78 | 95% ± 1 🏆 | 100%10/10 | 100% ± 0 | 15.0 ± 0.00 | 15.0 ± 0.00 | 1.5 ± 0.4 min 🏆 | 994k ± 224k 🏆 | $0.95 ± 0.22 🏆 |
| baseline-iterative-v1-ccad hocn = 10, 2026-05-14 | 158 ± 8.72 🏆 | 4.10 ± 1.29 🏆 | 32.1 ± 4.61 🏆 | 11.6 ± 1.51 🏆 | 16.2 ± 3.58 🏆 | 32.5 ± 2.80 | 95% ± 1 🏆 | 100%10/10 | 100% ± 0 | 15.0 ± 0.00 | 15.0 ± 0.00 | 1.4 ± 0.2 min 🏆 | 967k ± 175k 🏆 | $0.87 ± 0.11 🏆 |
Runs behind this table
- 2026-05-14_21-27-32_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_21-29-54_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_21-31-17_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_21-32-37_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_21-34-20_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_21-36-00_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_23-33-30_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_23-35-11_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_23-37-10_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_23-38-50_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_23-41-02_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_23-43-02_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_23-44-37_game-of-life-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-14_23-45-58_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_23-47-30_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_23-49-23_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_23-51-06_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_23-52-29_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_23-54-40_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-14_23-56-15_game-of-life-prose_v2-iterative_opus-4-7-no-thinking
claim-office-prose
| n, run dates | Code quality | Size | Test quality | Correctness | Cost | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ↓ | ↓ | ↓ | ↓ | ↓ | ○ | ↑ | ↑ | ↑ | ○ | ○ | ↓ | ↓ | ↓ | |
| baseline-oneshot-v1-ccad hocn = 5, 2026-05-16 | 835 ± 69.19 | 11.6 ± 7.57 | 40.4 ± 7.23 | 8.40 ± 1.14 | 12.2 ± 3.90 | 269 ± 31.15 | 86% ± 8 🏆 | 100%5/5 | 28% ± 6 | 4.20 ± 0.84 | 15.0 ± 0.00 | 3.9 ± 1.0 min | 2.1M ± 736k | $2.01 ± 0.47 |
| baseline-iterative-v1-ccad hocn = 5, 2026-05-16 | 851 ± 46.18 | 15.8 ± 3.70 | 41.4 ± 5.32 | 8.40 ± 2.61 | 11.4 ± 4.77 | 269 ± 10.50 | 87% ± 4 🏆 | 100%5/5 | 28% ± 6 | 4.20 ± 0.84 | 15.0 ± 0.00 | 4.1 ± 0.7 min | 2.1M ± 445k | $1.84 ± 0.29 |
Runs behind this table
- 2026-05-16_09-13-36_claim-office-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-16_09-17-37_claim-office-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-16_09-21-15_claim-office-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-16_09-26-53_claim-office-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-16_09-29-58_claim-office-prose_v1-oneshot_opus-4-7-no-thinking
- 2026-05-16_09-34-18_claim-office-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-16_09-38-15_claim-office-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-16_09-42-34_claim-office-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-16_09-48-02_claim-office-prose_v2-iterative_opus-4-7-no-thinking
- 2026-05-16_09-52-33_claim-office-prose_v2-iterative_opus-4-7-no-thinking
game-of-life-example-mapping
| n, run dates | Code quality | Size | Test quality | Correctness | Cost | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ↓ | ↓ | ↓ | ↓ | ↓ | ○ | ↑ | ↑ | ↑ | ○ | ○ | ↓ | ↓ | ↓ | |
| baseline-inline-tdd-v1-ccad hocn = 10, 2026-05-14 → 05-15 | 166 ± 13.88 | 6.00 ± 1.41 | 32.5 ± 5.84 | 13.7 ± 1.57 | 21.8 ± 3.61 | 31.9 ± 3.48 | 95% ± 1 | 100%10/10 | 100% ± 0 | 15.0 ± 0.00 | 15.0 ± 0.00 | 1.3 ± 0.3 min 🏆 | 799k ± 187k 🏆 | $0.81 ± 0.26 🏆 |
| exact-subagents-v2-testlist-fix-cctest listn = 5, 2026-05-22 → 05-23 | 157 ± 18.06 🏆 | 2.40 ± 0.55 🏆 | 16.4 ± 5.18 🏆 | 5.00 ± 1.41 🏆 | 6.40 ± 2.51 🏆 | 32.0 ± 4.30 | n/c | 100%5/5 | 100% ± 0 | 15.0 ± 0.00 | 15.0 ± 0.00 | 14.0 ± 3.1 min | 10.1M ± 2.1M | $12.86 ± 2.86 |
| exact-single-context-v2-testlist-fix-cctest listn = 5, 2026-05-22 → 05-23 | 154 ± 11.81 🏆 | 4.80 ± 0.45 | 20.8 ± 4.44 | 10.2 ± 2.28 | 17.6 ± 3.44 | 26.6 ± 2.88 | n/c | 100%5/5 | 100% ± 0 | 15.0 ± 0.00 | 15.0 ± 0.00 | 4.9 ± 0.9 min | 8.4M ± 3.4M | $6.48 ± 1.94 |
| exact-hybrid-v2-testlist-fix-cctest listn = 10, 2026-05-22 → 05-23 | 154 ± 18.79 🏆 | 2.40 ± 0.52 🏆 | 14.2 ± 6.25 🏆 | 5.20 ± 1.69 🏆 | 6.50 ± 3.24 🏆 | 29.2 ± 5.53 | n/c | 100%10/10 | 100% ± 0 | 15.0 ± 0.00 | 15.0 ± 0.00 | 8.5 ± 2.5 min | 8.1M ± 1.9M | $6.81 ± 1.55 |
| baseline-end-refactor-only-v1-agent-ccad hocn = 5, 2026-05-25 | 142 ± 14.05 🏆 | 3.00 ± 1.00 🏆 | 17.6 ± 6.27 🏆 | 7.40 ± 2.07 | 10.6 ± 4.93 🏆 | 31.2 ± 3.56 | n/c | 100%5/5 | 100% ± 0 | 15.0 ± 0.00 | 15.0 ± 0.00 | 2.4 ± 0.3 min | 1.5M ± 203k | $2.17 ± 0.39 |
| baseline-end-refactor-only-v1-native-ccad hocn = 5, 2026-05-25 | 146 ± 6.72 🏆 | 2.40 ± 0.89 🏆 | 17.6 ± 6.47 🏆 | 6.80 ± 2.39 🏆 | 9.00 ± 4.47 🏆 | 31.0 ± 4.85 | n/c | 100%5/5 | 100% ± 0 | 15.0 ± 0.00 | 15.0 ± 0.00 | 1.9 ± 0.5 min | 1.3M ± 172k | $1.92 ± 0.43 |
Runs behind this table
- 2026-05-14_21-37-40_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-14_21-38-56_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-14_21-40-35_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-14_23-57-46_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-14_23-59-06_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-15_00-00-24_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-15_00-02-10_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-15_00-03-37_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-15_00-05-17_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-15_00-06-39_game-of-life-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-22_19-39-13_game-of-life-example-mapping_v4.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-39-13_game-of-life-example-mapping_v4.1-testlist-scope-fix_opus-4-7-portkey-no-thinking-2
- 2026-05-22_19-39-13_game-of-life-example-mapping_v4.1-testlist-scope-fix_opus-4-7-portkey-no-thinking-3
- 2026-05-22_19-39-13_game-of-life-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-39-13_game-of-life-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking-2
- 2026-05-22_19-39-13_game-of-life-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking-3
- 2026-05-22_19-39-13_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-39-13_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking-2
- 2026-05-22_19-54-57_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-23_01-28-56_game-of-life-example-mapping_v4.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-23_01-28-56_game-of-life-example-mapping_v4.1-testlist-scope-fix_opus-4-7-portkey-no-thinking-2
- 2026-05-23_01-28-56_game-of-life-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-23_01-33-35_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-23_01-43-13_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-23_01-45-30_game-of-life-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-23_13-58-28_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-23_14-10-52_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-23_14-18-49_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-23_14-26-12_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-23_14-38-06_game-of-life-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-25_18-33-42_game-of-life-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking
- 2026-05-25_18-33-42_game-of-life-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking-2
- 2026-05-25_18-33-42_game-of-life-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking-3
- 2026-05-25_18-36-01_game-of-life-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking
- 2026-05-25_18-36-46_game-of-life-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking
- 2026-05-25_18-44-40_game-of-life-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
- 2026-05-25_18-47-16_game-of-life-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
- 2026-05-25_18-47-31_game-of-life-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
- 2026-05-25_18-49-02_game-of-life-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
- 2026-05-25_18-49-43_game-of-life-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
claim-office-example-mapping
| n, run dates | Code quality | Size | Test quality | Correctness | Cost | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ↓ | ↓ | ↓ | ↓ | ↓ | ○ | ↑ | ↑ | ↑ | ○ | ○ | ↓ | ↓ | ↓ | |
| baseline-inline-tdd-v1-ccad hocn = 5, 2026-05-08 → 05-16 | 992 ± 50.71 | 16.8 ± 6.22 | 51.6 ± 17.16 | 15.4 ± 5.08 | 19.8 ± 5.85 | 317 ± 25.09 | 78% ± 2 | 100%5/5 | 100% ± 0 🏆 | 15.0 ± 0.00 | 15.0 ± 0.00 | 5.2 ± 0.9 min 🏆 | 3.3M ± 546k 🏆 | $2.92 ± 0.52 🏆 |
| exact-subagents-v2-testlist-fix-cctest listn = 5, 2026-05-20 → 05-22 | 622 ± 65.58 🏆 | 13.2 ± 7.53 | 40.8 ± 27.12 🏆 | 16.0 ± 8.97 | 26.8 ± 24.07 🏆 | 157 ± 37.96 | n/c | 100%5/5 | 96% ± 9 🏆 | 14.4 ± 1.34 | 15.0 ± 0.00 | 53.8 ± 15.3 min | 34.9M ± 6.1M | $36.26 ± 5.76 |
| exact-single-context-v2-testlist-fix-cctest listn = 6, 2026-05-22 | 693 ± 78.80 🏆 | 6.83 ± 7.55 🏆 | 32.7 ± 10.19 | 10.2 ± 2.64 | 14.8 ± 4.17 | 167 ± 27.92 | n/c | 100%6/6 | 100% ± 0 🏆 | 15.0 ± 0.00 | 15.0 ± 0.00 | 10.7 ± 2.0 min | 18.7M ± 5.4M | $12.72 ± 3.59 |
| exact-hybrid-v2-testlist-fix-cctest listn = 7, 2026-05-22 → 05-24 | 861 ± 74.51 | 1.29 ± 1.50 🏆 | 18.1 ± 5.11 🏆 | 5.71 ± 2.36 🏆 | 5.71 ± 2.87 🏆 | 191 ± 20.32 | n/c | 100%7/7 | 100% ± 0 🏆 | 15.0 ± 0.00 | 15.0 ± 0.00 | 26.1 ± 8.7 min | 37.9M ± 13.5M | $29.28 ± 9.93 |
| baseline-end-refactor-only-v1-agent-ccad hocn = 5, 2026-05-25 | 814 ± 81.40 | 4.00 ± 4.69 🏆 | 28.4 ± 1.52 | 6.60 ± 1.95 🏆 | 7.40 ± 2.30 🏆 | 246 ± 33.49 | n/c | 100%5/5 | 100% ± 0 🏆 | 15.0 ± 0.00 | 15.0 ± 0.00 | 5.1 ± 0.6 min 🏆 | 3.6M ± 808k 🏆 | $4.02 ± 0.75 |
| baseline-end-refactor-only-v1-native-ccad hocn = 5, 2026-05-25 | 780 ± 75.34 | 6.20 ± 5.45 🏆 | 35.8 ± 11.52 | 8.00 ± 2.92 🏆 | 11.0 ± 4.64 | 239 ± 26.86 | n/c | 100%5/5 | 97% ± 6 🏆 | 14.6 ± 0.89 | 15.0 ± 0.00 | 4.6 ± 0.9 min 🏆 | 3.4M ± 1.1M 🏆 | $3.53 ± 0.61 🏆 |
Runs behind this table
- 2026-05-08_11-36-07_claim-office-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-08_11-42-20_claim-office-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-08_11-46-55_claim-office-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-16_09-56-09_claim-office-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-16_10-01-04_claim-office-example-mapping_v3-basic-tdd_opus-4-7-no-thinking
- 2026-05-20_21-58-27_claim-office-example-mapping_v4.1-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-20_22-41-54_claim-office-example-mapping_v4.1-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-20_23-32-48_claim-office-example-mapping_v4.1-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-21_08-35-47_claim-office-example-mapping_v4.1-testlist-scope-fix_opus-4-7-no-thinking
- 2026-05-22_08-52-17_claim-office-example-mapping_v4.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-29-21_claim-office-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-43-46_claim-office-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-44-03_claim-office-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-44-24_claim-office-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-44-26_claim-office-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-47-05_claim-office-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-48-07_claim-office-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_19-55-03_claim-office-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-22_20-01-47_claim-office-example-mapping_v5.1-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-23_09-06-31_claim-office-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-23_11-00-44_claim-office-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-24_03-09-37_claim-office-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking
- 2026-05-24_03-09-37_claim-office-example-mapping_v6.1-hybrid-testlist-scope-fix_opus-4-7-portkey-no-thinking-2
- 2026-05-25_18-36-34_claim-office-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking
- 2026-05-25_18-38-19_claim-office-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking
- 2026-05-25_18-39-36_claim-office-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking
- 2026-05-25_18-41-56_claim-office-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking
- 2026-05-25_18-43-17_claim-office-example-mapping_v8a-delayed-refactor-agent_opus-4-7-portkey-no-thinking
- 2026-05-25_18-49-39_claim-office-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
- 2026-05-25_18-51-36_claim-office-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
- 2026-05-25_18-51-39_claim-office-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
- 2026-05-25_18-54-44_claim-office-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
- 2026-05-25_18-58-01_claim-office-example-mapping_v8b-delayed-refactor-native_opus-4-7-portkey-no-thinking
Findings
RQ-tdd-quality Findings
Katas: game-of-life (library form, training-known) and claim-office (CLI, novel with ambiguities). Model: opus-4-7-no-thinking (Portkey OR direct, OR-match). 8 workflows (6 on the TDD axis + 2 non-TDD controls end-refactor-only-v1-agent/end-refactor-only-v1-native) × 2 katas = 16 cells, n=103 runs.
Methodological Note — Silent Workflow Drops and Aborted Refactor Loops
During the claim-office collection, one hybrid-v2 run occurred with a missing experiment-done.txt: the model stopped calling tools, Claude exited with exit_code=0/exit_reason=ok, but the workflow did not run to completion — a stop after the test list before the first red cycle (63 s, 11 assistant messages).
In addition, a hybrid-v2 claim-office run with an aborted refactor loop was removed: exit_reason=ok and all tests green, but only 4 instead of the typical 5+ cycles, 10 instead of 14–27 functions, longest function 60 LoC (median 17). The profile is inconsistent with normal hybrid-v2 behavior — the refactor subagent did not decompose the implementation.
These two runs were removed from the n=5 cells and replaced by fresh runs, or not replaced (n=7 for hybrid-v2 claim-office is > min_replicates=5). Rationale: for the TDD workflow question, what matters is the outcome of the workflow that ran through, not full-autonomy stability. In practical use (HITL), an aborted refactor would be fixed by a resume/re-trigger; only under full autonomy does it become a problem. Full-autonomy stability is a research question in its own right (cf. RQ-stability) and lies outside the scope of this RQ.
Overview — Code Quality per Workflow
All metrics in the tables: lower = better. 🏆 = best value per column (also multiple times in case of a tie). Never averaged across katas — game-of-life (~30–40 Production LoC) and claim-office (~150–320 Production LoC) are not comparable.
Kata: game-of-life
| Workflow | n | cognitive_max |
mccabe_max |
longest_function |
smell_total |
production_loc |
code_mass |
|---|---|---|---|---|---|---|---|
| baseline-oneshot-v1-cc | 10 | 18.8 | 12.8 | 31.7 | 4.8 | 33.6 | 155.0 |
| baseline-iterative-v1-cc | 10 | 16.2 | 11.6 | 32.1 | 4.1 | 32.5 | 157.8 |
| baseline-inline-tdd-v1-cc | 10 | 21.8 | 13.7 | 32.5 | 6.0 | 31.9 | 165.6 |
| exact-subagents-v2-testlist-fix-cc | 5 | 6.4 🏆 | 5.0 🏆 | 16.4 | 2.4 🏆 | 32.0 | 156.6 |
| exact-single-context-v2-testlist-fix-cc | 5 | 17.6 | 10.2 | 20.8 | 4.8 | 26.6 🏆 | 154.0 |
| v6.1-hybrid-… | 10 | 6.5 | 5.2 | 14.2 🏆 | 2.4 🏆 | 29.2 | 153.7 |
| baseline-end-refactor-only-v1-agent-cc | 5 | 10.6 | 7.4 | 17.6 | 3.0 | 31.2 | 142.0 🏆 |
| baseline-end-refactor-only-v1-native-cc | 5 | 9.0 | 6.8 | 17.6 | 2.4 🏆 | 31.0 | 145.8 |
Kata: claim-office
| Workflow | n | cognitive_max |
mccabe_max |
longest_function |
smell_total |
production_loc |
code_mass |
|---|---|---|---|---|---|---|---|
| baseline-oneshot-v1-cc | 5 | 12.2 | 8.4 | 40.4 | 11.6 | 269.4 | 835.4 |
| baseline-iterative-v1-cc | 5 | 11.4 | 8.4 | 41.4 | 15.8 | 268.6 | 851.0 |
| baseline-inline-tdd-v1-cc | 5 | 19.8 | 15.4 | 51.6 | 16.8 | 317.4 | 992.4 |
| exact-subagents-v2-testlist-fix-cc | 5 | 26.8 ⚠️ | 16.0 ⚠️ | 40.8 | 13.2 | 156.8 🏆 | 621.6 🏆 |
| exact-single-context-v2-testlist-fix-cc | 6 | 14.8 | 10.2 | 32.7 | 6.8 | 167.2 | 692.7 |
| v6.1-hybrid-… | 7 | 5.7 🏆 | 5.7 🏆 | 18.1 🏆 | 1.3 🏆 | 191.1 | 861.3 |
| baseline-end-refactor-only-v1-agent-cc | 5 | 7.4 | 6.6 | 28.4 | 4.0 | 245.6 | 813.8 |
| baseline-end-refactor-only-v1-native-cc | 5 | 11.0 | 8.0 | 35.8 | 6.2 | 238.8 | 780.2 |
⚠️ subagents-v2 claim-office is bimodal (cognitive_max σ=24, max=68) — occasional extreme misdirections. See F-tdd-quality.9.
Correctness differs between the two katas: on game-of-life all 8 workflows are at verification_pct=1.00. On claim-office it varies between 0.28 (oneshot-v1+iterative-v1, vibe coding on a prose spec) and 1.00 (inline-tdd-v1, single-context-v2, hybrid-v2, end-refactor-only-v1-agent) — see F-tdd-quality.4 and F-tdd-quality.8. mutation_score was collected only for oneshot-v1/iterative-v1/inline-tdd-v1 on game-of-life (0.95 ± 0.01 in all three).
F-tdd-quality.1 — Strict Phase-Structured Workflows with a Refactor Phase Lower cognitive_max and longest_function Drastically
On game-of-life, subagents-v2 and hybrid-v2 reach cognitive_max ≈ 6–7 and mccabe_max ≈ 5 — these are ~⅓ of the values of oneshot-v1/iterative-v1/inline-tdd-v1 (cognitive_max ≈ 16–22, mccabe_max ≈ 12–14). longest_function halves accordingly (13–16 vs. 32). smell_total also halves (≈2.3 vs. 4–6).
On claim-office the pattern holds even more clearly for hybrid-v2: cognitive_max 5.7, mccabe_max 5.7, longest_function 18.1 — all the lowest values of the entire matrix. subagents-v2, by contrast, breaks down on claim-office (see F-tdd-quality.9) — it does stay at the top on code_mass and production_loc (621.6/156.8, each the best across all workflows), but collapses on branching complexity.
Plausible mechanic: subagents-v2 and hybrid-v2 prescribe a dedicated refactor phase per cycle that explicitly reduces complexity — and both separate implementation (green) and refactor architecturally (subagents-v2 via an isolated subagent, hybrid-v2 via a dedicated refactor subagent in the hybrid). The refactor discipline shows up directly in the complexity peaks, not in production_loc — the code does not become shorter, but flatter.
F-tdd-quality.2 — Naive "use TDD" (inline-tdd-v1) Brings No Complexity Advantage over Non-TDD (oneshot-v1/iterative-v1) on game-of-life
On game-of-life, inline-tdd-v1 is at or slightly above oneshot-v1/iterative-v1 in all complexity metrics: cognitive_max 21.8 (inline-tdd-v1) vs. 18.8/16.2 (oneshot-v1/iterative-v1), mccabe_max 13.7 vs. 12.8/11.6, smell_total 6.0 vs. 4.8/4.1, code_mass 165.6 vs. 155/157.8. Function sizes (longest_function, production_loc) are comparable.
On claim-office, inline-tdd-v1 is even clearly worse than oneshot-v1/iterative-v1 in almost all metrics: cognitive_max 19.8 vs. 12.2/11.4, mccabe_max 15.4 vs. 8.4/8.4, longest_function 51.6 vs. 40.4/41.4, production_loc 317.4 vs. 269.4/268.6, code_mass 992.4 vs. 835.4/851.0. The naive "use TDD" approach produces the heaviest code of the whole matrix on the novel kata — the test-first increments drive the implementation into a fragmented structure without a structured cleanup rhythm.
Plausible mechanic: inline-tdd-v1 is a single agent with the minimal instruction "use TDD" and without an enforced red-green-refactor rhythm — no isolated refactor step, no phase structure. On a training-known kata the model produces an orderly solution even without TDD; on a novel kata inline-tdd-v1 appends test satisfaction to test satisfaction incrementally — without periodic refactoring the result becomes clunkier than even a poor oneshot solution. The measurable quality advantage only comes from the structured refactor discipline of the strict workflows (F-tdd-quality.1). The "use TDD" label alone does not suffice — the lever is the enforced refactor step in the rhythm, not the test-first instruction.
Hypothesis H1 ("inline-tdd-v1/subagents-v2/single-context-v2 show lower complexity than oneshot-v1/iterative-v1") therefore does not hold uniformly for all TDD workflows — inline-tdd-v1 reaches (game-of-life) or falls below (claim-office) the non-TDD level; only subagents-v2 (game-of-life) and hybrid-v2 (both katas) separate themselves clearly.
F-tdd-quality.3 — Single Context (single-context-v2) Loses the Complexity Advantage of the Phase-Isolated Subagents (subagents-v2) — But Only on game-of-life
single-context-v2 and subagents-v2 carry the same phase-script content (test-list-scope-fix, test list → red → green → refactor) and differ only in the invocation mechanism: subagents-v2 spawns a fresh subagent per phase (isolated context), single-context-v2 invokes skills in the same context.
On game-of-life, single-context-v2 shows values at the oneshot-v1/iterative-v1/inline-tdd-v1 level in the peak metrics:
| Metric (lower = better) | subagents-v2 (isolated) | single-context-v2 (shared) | Factor single-context-v2 / subagents-v2 |
|---|---|---|---|
cognitive_max |
6.4 🏆 | 17.6 | 2.8× |
mccabe_max |
5.0 🏆 | 10.2 | 2.0× |
longest_function |
16.4 🏆 | 20.8 | 1.3× |
smell_total |
2.4 🏆 | 4.8 | 2.0× |
On claim-office the ordering reverses — single-context-v2 clearly beats subagents-v2:
| Metric (lower = better) | subagents-v2 (isolated) | single-context-v2 (shared) |
|---|---|---|
cognitive_max |
26.8 ⚠️ | 14.8 🏆 |
mccabe_max |
16.0 ⚠️ | 10.2 🏆 |
longest_function |
40.8 | 32.7 🏆 |
smell_total |
13.2 | 6.8 🏆 |
Plausible mechanic: on the short game-of-life test list the fresh subagent context helps, because each phase can survey the whole test list in isolation; on the long claim-office test list the fresh context loses coherence per cycle and re-interprets spec ambiguities differently. single-context-v2 with its shared context benefits from spec consistency within a session. The hybrid hybrid-v2 (skill red/green in the shared context + isolated refactor subagent) combines both strengths and dominates claim-office across the branching and size metrics — see RQ-context (4.3) F-context.1 for the explicit decomposition.
F-tdd-quality.4 — Correctness Differs Only on the Novel Kata, and There It Tracks the Prompt Pairing, Not the Workflow
verification_pct is structurally different on the two katas:
| Kata | oneshot-v1 | iterative-v1 | inline-tdd-v1 | subagents-v2 | single-context-v2 | hybrid-v2 | end-refactor-only-v1-agent | end-refactor-only-v1-native |
|---|---|---|---|---|---|---|---|---|
| game-of-life | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 | 1.00 |
| claim-office | 0.28 | 0.28 | 1.00 | 0.96 | 1.00 | 1.00 | 1.00 | 0.97 |
On game-of-life all 8 workflows are at 100 % (15/15 verification scenarios) — the workflow effect is invisible here, because the model has memorized the solution. On claim-office (novel with ambiguities), oneshot-v1 and iterative-v1 drop to ~28 % (4/15) — the model writes a solution that fails in 11 of 15 scenarios, although both write and pass their own tests. Both run on the prose spec, which the methodology ties to them; all other workflows run on example-mapping and stay at ≥ 96 %, most at 100 %. The smaller deviations at subagents-v2 (0.96) and end-refactor-only-v1-native (0.97) come from 1 run each with verification_pct ∈ {0.80, 0.87} (implementation bugs that do not quite cover the spec — not silent workflow drops).
H4 (correctness independent of the workflow) cannot be decided from this RQ. The cells differ on claim-office, but the split coincides exactly with the prompt pairing: prose cells fail, example-mapping cells pass. TDD on a prose spec fails just the same (RQ-prompt-correctness), so the difference is not attributable to the workflow — see F-tdd-quality.8.
F-tdd-quality.5 — The Cost Range Between Workflows Spans an Order of Magnitude; Strict Workflows Are 5–50× More Expensive; Kata Complexity Scales Linearly
game-of-life
| Workflow | duration_seconds (mean) |
total_tokens (mean) |
|---|---|---|
| baseline-oneshot-v1-cc | 88 | 994 k |
| baseline-iterative-v1-cc | 83 | 967 k |
| baseline-inline-tdd-v1-cc | 75 🏆 | 799 k 🏆 |
| exact-subagents-v2-testlist-fix-cc | 838 | 10.15 M |
| exact-single-context-v2-testlist-fix-cc | 293 | 8.40 M |
| v6.1-hybrid-… | 508 | 8.15 M |
| baseline-end-refactor-only-v1-agent-cc | 143 | 1.47 M |
| baseline-end-refactor-only-v1-native-cc | 116 | 1.32 M |
claim-office
| Workflow | duration_seconds (mean) |
total_tokens (mean) |
|---|---|---|
| baseline-oneshot-v1-cc | 231 | 2.11 M 🏆 |
| baseline-iterative-v1-cc | 244 | 2.12 M |
| baseline-inline-tdd-v1-cc | 312 | 3.28 M |
| exact-subagents-v2-testlist-fix-cc | 3229 | 34.87 M |
| exact-single-context-v2-testlist-fix-cc | 641 | 18.73 M |
| v6.1-hybrid-… | 1569 | 37.88 M ⚠️ |
| baseline-end-refactor-only-v1-agent-cc | 308 | 3.55 M |
| baseline-end-refactor-only-v1-native-cc | 276 🏆 | 3.45 M |
On claim-office, the strict TDD workflows cost 2–5× more than on game-of-life — and hybrid-v2 has the largest token range (σ=13.5 M, max 49.59 M). On claim-office, subagents-v2 takes on average 54 minutes per run — combined with the bimodal risk (F-tdd-quality.9), the worst cost-quality trade-off of the entire matrix.
On both katas, end-refactor-only-v1-agent/end-refactor-only-v1-native are at the oneshot-v1/iterative-v1/inline-tdd-v1 cost level (~1–4 M tokens, 2–5 min) and deliver (on claim-office) considerably better branching complexity than oneshot-v1/iterative-v1/inline-tdd-v1 and correctness comparable to the strict TDD workflows — see F-tdd-quality.6 and F-tdd-quality.8.
F-tdd-quality.6 — Vibe + End Refactoring Reaches the Volume Level of the Strict TDD Workflows at Non-TDD Cost; Branching Complexity Remains Weaker
The non-TDD control group end-refactor-only-v1-agent/end-refactor-only-v1-native (phase 1 implementation without tests → phase 2 tests against prompt.md → phase 3 a single refactor) reaches the level of the strict TDD workflows on the volume metrics at a fraction of the cost.
game-of-life
| Workflow | code_mass |
longest_function |
cognitive_max |
duration_s |
total_tokens |
|---|---|---|---|---|---|
| subagents-v2 (periodic refactor) | 156.6 | 16.4 | 6.4 🏆 | 838 | 10.15 M |
| hybrid-v2 (periodic refactor) | 153.7 | 14.2 🏆 | 6.5 | 508 | 8.15 M |
| end-refactor-only-v1-agent (end refactor, agent) | 142.0 🏆 | 17.6 | 10.6 | 143 | 1.47 M 🏆 |
| end-refactor-only-v1-native (end refactor, command) | 145.8 | 17.6 | 9.0 | 116 🏆 | 1.32 M |
claim-office
| Workflow | code_mass |
longest_function |
cognitive_max |
duration_s |
total_tokens |
|---|---|---|---|---|---|
| subagents-v2 (periodic refactor) | 621.6 🏆 | 40.8 | 26.8 ⚠️ | 3229 | 34.87 M |
| hybrid-v2 (periodic refactor) | 861.3 | 18.1 🏆 | 5.7 🏆 | 1569 | 37.88 M |
| end-refactor-only-v1-agent (end refactor, agent) | 813.8 | 28.4 | 7.4 | 308 | 3.55 M 🏆 |
| end-refactor-only-v1-native (end refactor, command) | 780.2 | 35.8 | 11.0 | 276 🏆 | 3.45 M |
H5 (the periodicity of refactoring matters) is kata-dependent:
- On game-of-life: end-refactor-only-v1-agent/end-refactor-only-v1-native are almost level with subagents-v2/hybrid-v2 on
code_massandlongest_function;cognitive_maxremains subagents-v2/v6.1-dominated (6.4/6.5 vs 9.0/10.6). - On claim-office: hybrid-v2 clearly dominates on branching complexity (
cognitive_max5.7 vs end-refactor-only-v1-agent/b 7.4/11.0) and function size (longest_function18.1 vs 28.4/35.8). subagents-v2 (the code-volume champion at 621.6), by contrast, delivers the worst branching complexity (26.8 ⚠️) — no workflow dominates all metrics on claim-office.
Reading: a single end refactoring after vibe-coding reduces code volume comparably to periodic refactoring, but not the branching depth within individual functions. On a complex kata with longer functions the periodicity advantage becomes more visible — the TDD refactor per cycle decomposes functions early, while an end refactor only smooths them superficially. Consistent with RQ-delayed-refactor "the TDD advantage is branching complexity, not substance".
F-tdd-quality.7 — The Subagent Mechanism for the End Refactor Beats the Slash Command on the Large Kata; Level on the Small Kata
The two non-TDD arms isolate the refactor delivery mechanism at identical refactor content: end-refactor-only-v1-agent spawns a fresh refactor subagent (.claude/agents/refactor.md, Task tool), end-refactor-only-v1-native invokes the same content as a slash command (.claude/commands/refactor.md, Skill tool) inline in the main session context. Both refactor specs are byte-identical (Four Rules of Simple Design + APP mass + naming evaluation + mandatory attempt). Phase 1 and phase 2 are likewise identical.
On game-of-life both mechanisms are practically level:
| Metric (lower = better) | end-refactor-only-v1-agent (subagent) | end-refactor-only-v1-native (command) |
|---|---|---|
cognitive_max mean |
10.6 (max 15) | 9.0 (max 17) |
mccabe_max mean |
7.4 (max 9) | 6.8 (max 11) |
longest_function mean |
17.6 (max 27) | 17.6 (max 27) |
smell_total mean |
3.0 | 2.4 |
total_tokens mean |
1.47 M | 1.32 M |
code_mass mean |
142.0 | 145.8 |
All differences lie within 1 σ (e.g. cognitive_max σ_v8a=4.93, σ_v8b=4.47); no systematic advantage of either mechanism.
On claim-office, end-refactor-only-v1-agent (subagent) clearly dominates on cognitive_max, longest_function and token efficiency:
| Metric (lower = better) | end-refactor-only-v1-agent (subagent) | end-refactor-only-v1-native (command) |
|---|---|---|
cognitive_max mean |
7.4 (max 10) | 11.0 (max 19) |
mccabe_max mean |
6.6 (max 9) | 8.0 (max 13) |
longest_function mean |
28.4 (max 30) | 35.8 (max 49) |
smell_total mean |
4.0 | 6.2 |
total_tokens mean |
2.12 M | 3.45 M |
verification_pct mean |
1.00 | 0.97 |
code_mass mean |
813.8 | 780.2 |
end-refactor-only-v1-agent leads on 6 of 7 metrics; on longest_function the range is particularly tight (end-refactor-only-v1-agent max 30, end-refactor-only-v1-native max 49 — the subagent prevents the outlier functions). end-refactor-only-v1-native needs 63 % more tokens and produces wider distributions.
H6 (subagent delivery matters independently of the content) confirmed on claim-office; no separation on game-of-life. Plausible mechanic: the fresh subagent context relieves the refactor of anchoring bias from phases 1/2 — on the small, training-known game-of-life codebase the bias effect is small and both mechanisms deliver similarly; on the larger novel claim-office codebase with 240+ LoC per solution, the inline command (end-refactor-only-v1-native) carries implicit assumptions from the preceding phases into the refactor, whereas the subagent (end-refactor-only-v1-agent) starts afresh with the refactor. Consistent with RQ-delayed-refactor / F-delayed-refactor.2 (the refactor mechanism is non-trivial), now cleanly isolated from content effects.
F-tdd-quality.8 — Correctness on the Novel Kata Follows the Spec Style, Not the Presence or Timing of Tests
On the novel kata claim-office, correctness splits cleanly by prompt style — and every run in every cell writes tests:
| Workflow | Prompt | Tests written | n | Correctness (external) mean | min |
|---|---|---|---|---|---|
| baseline-oneshot-v1-cc | prose | after impl (6–17 tests) | 5 | 0.28 | 0.20 |
| baseline-iterative-v1-cc | prose | after impl (3–7 tests) | 5 | 0.28 | 0.20 |
| exact-single-context-v1-cc ¹ | prose | test-first | 5 | 0.21 | 0.13 |
| exact-subagents-v2-testlist-fix-cc | example-mapping | test-first | 5 | 0.96 | 0.80 |
| baseline-end-refactor-only-v1-native-cc | example-mapping | after impl | 5 | 0.97 | 0.87 |
| baseline-inline-tdd-v1-cc | example-mapping | test-first | 5 | 1.00 | 1.00 |
| exact-single-context-v2-testlist-fix-cc | example-mapping | test-first | 6 | 1.00 | 1.00 |
| exact-hybrid-v2-testlist-fix-cc | example-mapping | test-first | 7 | 1.00 | 1.00 |
| baseline-end-refactor-only-v1-agent-cc | example-mapping | after impl | 5 | 1.00 | 1.00 |
¹ Counter-cell from RQ-prompt-correctness (F-prompt-correctness.2): same kata, same model (opus-4-7-no-thinking). Not part of this RQ's selector.
With a prose spec, correctness stays at 0.21–0.28 whether the agent codes first and adds tests afterwards or works test-first. With an example-mapping spec it reaches ≥ 0.96 whether the tests come before or after the implementation. The ~70 pp gap between the two groups matches the example-mapping effect RQ-prompt-correctness measures on the same model (0.21 → 0.97); the spec style accounts for the whole difference. The runs below 1.00 at subagents-v2 and end-refactor-only-v1-native are one run each (implementation bugs that miss individual verification scenarios — not silent workflow drops).
Two statements follow, and one does not:
- Given example mapping, test timing does not matter for correctness. end-refactor-only-v1-agent (tests written after the implementation, with the obligation "Cover every spec example") reaches 100 %, level with inline-tdd-v1/single-context-v2/hybrid-v2.
- Test-first does not rescue a prose spec. single-context-v1 on prose is no better than vibe coding on prose.
- Whether a test-writing phase matters at all remains open. No cell lacks tests — oneshot-v1/iterative-v1 write their own — and the methodology keeps oneshot-v1/iterative-v1 on prose, so there is no cell "example mapping without tests". The effect of the test phase itself is not isolable in this design.
On game-of-life all of this is invisible (all 8 workflows at 100 %), because the model has memorized the solution. The split manifests itself only on novel katas.
Consequence for open question #4 ("is a single end refactoring after vibe-coding sufficient?"): Yes for correctness, given a spec with concrete examples and tests that cover them — end-refactor-only-v1-agent reaches 100 % on claim-office, end-refactor-only-v1-native 97 %. Code quality is a separate axis (see F-tdd-quality.6/.7).
F-tdd-quality.9 — The hybrid-v2 Hybrid Is the Most Robust TDD Workflow Across Both Katas; subagents-v2 Is Kata-Unstable
Per-kata complexity ranking on cognitive_max (lower = better):
| Rank | game-of-life | claim-office |
|---|---|---|
| 1 | subagents-v2 (6.4) 🏆 | hybrid-v2 (5.7) 🏆 |
| 2 | hybrid-v2 (6.5) | end-refactor-only-v1-agent (7.4) |
| 3 | end-refactor-only-v1-native (9.0) | end-refactor-only-v1-native (11.0) |
| 4 | end-refactor-only-v1-agent (10.6) | baseline-iterative-v1-cc (11.4) |
| 5 | baseline-iterative-v1-cc (16.2) | baseline-oneshot-v1-cc (12.2) |
| 6 | single-context-v2 (17.6) | single-context-v2 (14.8) |
| 7 | baseline-oneshot-v1-cc (18.8) | baseline-inline-tdd-v1-cc (19.8) |
| 8 | baseline-inline-tdd-v1-cc (21.8) | subagents-v2 (26.8) ⚠️ bimodal |
Strict phase-structured workflows (hybrid-v2, subagents-v2) occupy the leading places on both katas (with the subagents-v2 exception on claim-office); the v8 control group follows directly behind. The weakest TDD workflows (inline-tdd-v1, single-context-v2) and oneshot-v1+prose share the rear third. hybrid-v2 is the only workflow that lands in the top 2 on both katas and holds the top position on claim-office in 4 of 6 quality metrics.
On claim-office, subagents-v2 crashes from rank 1 to rank 8 (cognitive_max mean 26.8, σ=24, max=68) — bimodal with occasional extreme misdirections. On game-of-life, subagents-v2 is the most stable performer. Reading: the subagents-v2 advantage (phase-isolated subagents) only carries on a kata whose test list the model can survey immediately. On claim-office with ~15 test scenarios and many ambiguities, the fresh context loses coherence per phase — the subagent re-interprets the spec per cycle. hybrid-v2 (hybrid: skill red/green in the shared context + isolated refactor) avoids this effect, because red and green share the same context.
Recommendation: hybrid-v2 as the robust default choice across kata complexity. Use subagents-v2 only on katas with a compact test list, otherwise there is a collapse risk.
Caveat: n=5 per claim-office cell, n=10 for oneshot-v1/iterative-v1/inline-tdd-v1 game-of-life. subagents-v2 claim-office cognitive_max σ=24 — the mean is dominated by 1–2 outliers. A larger n could shift the picture, but not the bimodal risk.
Practical Recommendation — Code Quality vs Token Price
Clarification of the Core Question
The original research motivation was: is the TDD cycle with continuous refactoring per cycle more valuable than vibe-coding with a single end refactoring? The data is unambiguous:
Yes, continuous refactoring in the TDD cycle produces measurably better code quality. On claim-office (a complex novel kata), hybrid-v2 clearly wins on 5 of 6 code-quality metrics against the end-refactor controls:
| Metric (lower = better) | hybrid-v2 (periodic) | end-refactor-only-v1-agent (end refactor, agent) | end-refactor-only-v1-native (end refactor, command) | Winner |
|---|---|---|---|---|
cognitive_max |
5.7 | 7.4 | 11.0 | hybrid-v2 |
mccabe_max |
5.7 | 6.6 | 8.0 | hybrid-v2 |
longest_function |
18.1 | 28.4 | 35.8 | hybrid-v2 |
smell_total |
1.3 | 4.0 | 6.2 | hybrid-v2 |
production_loc |
191 | 246 | 239 | hybrid-v2 |
code_mass |
861 | 814 | 780 | end-refactor-only-v1-native (narrowly) |
hybrid-v2 dominates the branching and structure metrics throughout; end-refactor-only-v1-native wins only narrowly on code_mass (a reduction of ~9 %). On game-of-life the pattern is consistent (hybrid-v2 cognitive_max 6.5 vs end-refactor-only-v1-agent/end-refactor-only-v1-native 10.6/9.0; longest_function 14.2 vs 17.6/17.6). The periodicity thesis holds uniformly.
The Trade-off: Token and Wallclock Price
This quality is not free. On claim-office:
| Workflow | cognitive_max |
total_tokens |
duration_s |
Token ratio |
|---|---|---|---|---|
| v8a-delayed (agent) | 7.4 | 3.55 M | 308 | 1.0× |
| v8b-delayed (command) | 11.0 | 3.45 M | 276 | 1.0× |
| v6.1-hybrid | 5.7 | 37.88 M | 1569 | 11× |
| v4.1-strict | 26.8 ⚠️ | 34.87 M | 3229 | 10× |
hybrid-v2 costs 11× more tokens and ~5× more wallclock than end-refactor-only-v1-agent for a reduction of 7.4 → 5.7 in cognitive_max (and further improvements on longest_function, smell_total, production_loc). That is the honest balance sheet.
Recommendation by Use Case
| Situation | Workflow | Rationale |
|---|---|---|
| Long-lived production code — read, refactored, extended often; onboarding-relevant | v6.1-hybrid | Best branching complexity on both katas; the token surcharge amortizes over the code's lifetime |
| Maintenance-critical code with high correctness demands that is not changed frequently | v6.1-hybrid or single-context-v2 | On claim-office, single-context-v2 is the second-best TDD workflow on cognitive_max (14.8) at ~½ the tokens of hybrid-v2 |
| Prototyping / throwaway code — touched rarely or never again | baseline-end-refactor-only-v1-native-cc | Lowest wallclock among the example-mapping workflows; correctness 0.97 level with subagents-v2; cognitive_max (11.0) is acceptable for a short lifetime |
| High iteration frequency under a token budget — many small tasks, frequent re-runs | baseline-end-refactor-only-v1-agent-cc | ~11× cheaper than hybrid-v2; cognitive_max 7.4 (vs hybrid-v2 5.7) is not ideal but acceptable for a short lifetime; 100 % correctness on claim-office |
| Coding from a prose spec | Not recommended for novel problems | oneshot-v1/iterative-v1 on prose break down to 28 % correctness on a novel kata — and TDD on prose does no better (21 %, RQ-prompt-correctness). Concrete examples in the spec are the insurance, not the test phase (F-tdd-quality.8) |
| Correctness counts more than quality (e.g. scripts, tooling, glue code) | baseline-inline-tdd-v1-cc | 100 % correctness on claim-office at 3.28 M tokens — the cheapest correctness workflow; accepts the worst code quality (cog 19.8, largest code_mass) as the price |
v4.1-strict remains not generally recommended because of the bimodal risk on longer test lists (claim-office σ=24, max cog=68). Only on katas with a compact, surveyable test spec.
What This Recommendation Does NOT Cover
- Model dependence: all findings apply to
opus-4-7-no-thinking. On Sonnet/Haiku the ordering can shift (cf. F-emoji-cross-model in RQ-emoji-cross-model: workflow reductions are not model-agnostic). - Domain dependence: the katas are ~30–320 LoC of library/CLI code. The findings are not directly transferable to web apps, database code, or async systems.
- Team factors: HITL workflows (a human reviews the cycle), pair-programming setups, and IDE integration are outside the scope.