devlyn-cli 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. package/AGENTS.md +2 -2
  2. package/CLAUDE.md +2 -2
  3. package/README.md +22 -113
  4. package/bin/devlyn.js +13 -225
  5. package/bin/instruction-templates.json +752 -1
  6. package/bin/instructions.js +101 -17
  7. package/config/skills/_shared/adapters/grok.md +1 -2
  8. package/config/skills/_shared/archive_run.py +15 -3
  9. package/config/skills/_shared/judge-role-evidence.py +21 -1
  10. package/config/skills/_shared/runtime-principles.md +1 -1
  11. package/config/skills/_shared/spec-verify-check.py +0 -653
  12. package/config/skills/_shared/state-phase-write.py +371 -30
  13. package/config/skills/_shared/task-complete.py +635 -143
  14. package/config/skills/_shared/terminal-claim-check.py +229 -4
  15. package/config/skills/_shared/verify-merge-findings.py +93 -2
  16. package/config/skills/devlyn:ideate/SKILL.md +3 -4
  17. package/config/skills/devlyn:ideate/references/elicitation.md +2 -35
  18. package/config/skills/devlyn:ideate/references/from-spec-mode.md +3 -18
  19. package/config/skills/devlyn:ideate/references/project-mode.md +1 -16
  20. package/config/skills/devlyn:ideate/references/spec-template.md +0 -2
  21. package/config/skills/devlyn:queue/SKILL.md +6 -4
  22. package/config/skills/devlyn:resolve/SKILL.md +16 -25
  23. package/config/skills/devlyn:resolve/references/free-form-mode.md +0 -14
  24. package/config/skills/devlyn:resolve/references/outer-loop.md +1 -1
  25. package/config/skills/devlyn:resolve/references/phases/build-gate.md +1 -1
  26. package/config/skills/devlyn:resolve/references/phases/cleanup.md +3 -3
  27. package/config/skills/devlyn:resolve/references/phases/implement.md +1 -1
  28. package/config/skills/devlyn:resolve/references/phases/probe-derive.md +1 -16
  29. package/config/skills/devlyn:resolve/references/phases/verify.md +4 -9
  30. package/config/skills/devlyn:resolve/references/state-schema.md +9 -7
  31. package/config/skills/devlyn:resolve/references/task-completion.md +46 -37
  32. package/{config/skills → optional-skills}/code-health-standards/SKILL.md +4 -13
  33. package/{config/skills → optional-skills}/code-review-standards/SKILL.md +4 -12
  34. package/{config/skills → optional-skills}/root-cause-analysis/SKILL.md +4 -12
  35. package/{config/skills → optional-skills}/ui-implementation-standards/SKILL.md +4 -14
  36. package/package.json +1 -57
  37. package/benchmark/auto-resolve/BENCHMARK-DESIGN.md +0 -289
  38. package/benchmark/auto-resolve/BENCHMARK-RESULTS.md +0 -341
  39. package/benchmark/auto-resolve/README.md +0 -696
  40. package/benchmark/auto-resolve/RUBRIC.md +0 -177
  41. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/NOTES.md +0 -34
  42. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/expected.json +0 -68
  43. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/metadata.json +0 -10
  44. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/setup.sh +0 -4
  45. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/spec.md +0 -44
  46. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.ko.txt +0 -8
  47. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.txt +0 -8
  48. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/NOTES.md +0 -68
  49. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/expected.json +0 -60
  50. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/metadata.json +0 -10
  51. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/setup.sh +0 -17
  52. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/spec.md +0 -51
  53. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/task.txt +0 -9
  54. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/verifiers/invalid.js +0 -29
  55. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/verifiers/parallel.js +0 -50
  56. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/NOTES.md +0 -75
  57. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/expected.json +0 -52
  58. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/metadata.json +0 -10
  59. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/setup.sh +0 -171
  60. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/spec.md +0 -50
  61. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/task.txt +0 -9
  62. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/NOTES.md +0 -89
  63. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/expected.json +0 -74
  64. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/metadata.json +0 -10
  65. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/setup.sh +0 -251
  66. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/spec.md +0 -57
  67. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/task.txt +0 -13
  68. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/verifiers/replay-malformed-body.js +0 -64
  69. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/NOTES.md +0 -104
  70. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/expected.json +0 -46
  71. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/metadata.json +0 -10
  72. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/setup.sh +0 -336
  73. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/spec.md +0 -51
  74. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/task.txt +0 -9
  75. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/NOTES.md +0 -38
  76. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/expected.json +0 -64
  77. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/metadata.json +0 -10
  78. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/setup.sh +0 -32
  79. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/spec.md +0 -63
  80. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/task.txt +0 -7
  81. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/exact-success.js +0 -54
  82. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/no-hardcoded-pricing.js +0 -47
  83. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/stock-error.js +0 -45
  84. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/NOTES.md +0 -57
  85. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected-pair-plan-registry.json +0 -170
  86. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected.json +0 -84
  87. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/metadata.json +0 -21
  88. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-fail.json +0 -214
  89. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-pass.json +0 -223
  90. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/setup.sh +0 -5
  91. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/spec.md +0 -55
  92. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/task.txt +0 -14
  93. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/NOTES.md +0 -39
  94. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/expected.json +0 -62
  95. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/metadata.json +0 -10
  96. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/setup.sh +0 -2
  97. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/spec.md +0 -67
  98. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/task.txt +0 -7
  99. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/verifiers/error-order.js +0 -55
  100. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/verifiers/priority-blocked.js +0 -48
  101. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/NOTES.md +0 -35
  102. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/expected.json +0 -56
  103. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/metadata.json +0 -10
  104. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/setup.sh +0 -2
  105. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/spec.md +0 -64
  106. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/task.txt +0 -7
  107. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/verifiers/conflicting-duplicate.js +0 -34
  108. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/verifiers/idempotent-close.js +0 -41
  109. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/NOTES.md +0 -39
  110. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/expected.json +0 -56
  111. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/metadata.json +0 -10
  112. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/setup.sh +0 -2
  113. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/spec.md +0 -76
  114. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/task.txt +0 -7
  115. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/verifiers/priority-rollback.js +0 -64
  116. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/verifiers/single-warehouse-fefo.js +0 -66
  117. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/NOTES.md +0 -40
  118. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/expected.json +0 -66
  119. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/metadata.json +0 -10
  120. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/setup.sh +0 -36
  121. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/spec.md +0 -71
  122. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/task.txt +0 -7
  123. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/catalog-source.js +0 -57
  124. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/exact-success.js +0 -63
  125. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/stock-error.js +0 -34
  126. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/NOTES.md +0 -31
  127. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/expected.json +0 -68
  128. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/metadata.json +0 -10
  129. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/setup.sh +0 -17
  130. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/spec.md +0 -68
  131. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/task.txt +0 -7
  132. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/conflicting-duplicate.js +0 -29
  133. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/exact-payout.js +0 -58
  134. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/rules-source.js +0 -56
  135. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/NOTES.md +0 -35
  136. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected-pair-plan-registry.json +0 -162
  137. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected.json +0 -67
  138. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/metadata.json +0 -19
  139. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/setup.sh +0 -4
  140. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/spec.md +0 -55
  141. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/task.txt +0 -9
  142. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/NOTES.md +0 -34
  143. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/expected.json +0 -57
  144. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/metadata.json +0 -10
  145. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/setup.sh +0 -2
  146. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/spec.md +0 -67
  147. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/task.txt +0 -7
  148. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/verifiers/duplicate-event-error.js +0 -35
  149. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/verifiers/priority-transfer-rollback.js +0 -53
  150. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/NOTES.md +0 -38
  151. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/expected.json +0 -57
  152. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/metadata.json +0 -10
  153. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/setup.sh +0 -2
  154. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/spec.md +0 -70
  155. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/task.txt +0 -3
  156. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/verifiers/duplicate-renewal-error.js +0 -42
  157. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/verifiers/priority-credit-rollback.js +0 -70
  158. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/NOTES.md +0 -47
  159. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/expected.json +0 -57
  160. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/metadata.json +0 -10
  161. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/setup.sh +0 -6
  162. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/spec.md +0 -48
  163. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/task.txt +0 -9
  164. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/NOTES.md +0 -45
  165. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/expected.json +0 -65
  166. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/metadata.json +0 -10
  167. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/setup.sh +0 -55
  168. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/spec.md +0 -48
  169. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/task.txt +0 -7
  170. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/NOTES.md +0 -43
  171. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/expected.json +0 -77
  172. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/metadata.json +0 -10
  173. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/setup.sh +0 -4
  174. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/spec.md +0 -48
  175. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/task.txt +0 -10
  176. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/NOTES.md +0 -57
  177. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/expected.json +0 -76
  178. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/metadata.json +0 -10
  179. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/setup.sh +0 -36
  180. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/spec.md +0 -45
  181. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/task.txt +0 -7
  182. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/NOTES.md +0 -53
  183. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/expected.json +0 -63
  184. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/metadata.json +0 -10
  185. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/setup.sh +0 -4
  186. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/spec.md +0 -48
  187. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/task.txt +0 -1
  188. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/NOTES.md +0 -105
  189. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/expected.json +0 -74
  190. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/metadata.json +0 -10
  191. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/setup.sh +0 -28
  192. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/spec.md +0 -59
  193. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/task.txt +0 -5
  194. package/benchmark/auto-resolve/fixtures/SCHEMA.md +0 -188
  195. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/NOTES.md +0 -37
  196. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/RETIRED.md +0 -13
  197. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/expected.json +0 -56
  198. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/metadata.json +0 -10
  199. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/setup.sh +0 -18
  200. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/spec.md +0 -69
  201. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/task.txt +0 -7
  202. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/verifiers/exact-proration.js +0 -48
  203. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/verifiers/rules-source-and-conflict.js +0 -79
  204. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/NOTES.md +0 -54
  205. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/RETIRED.md +0 -7
  206. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/expected.json +0 -67
  207. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/metadata.json +0 -10
  208. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/setup.sh +0 -2
  209. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/spec.md +0 -67
  210. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/task.txt +0 -5
  211. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/policy-precedence.js +0 -72
  212. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/validation-and-immutability.js +0 -43
  213. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/validation-boundary.js +0 -116
  214. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/NOTES.md +0 -35
  215. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/RETIRED.md +0 -12
  216. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/expected.json +0 -58
  217. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/metadata.json +0 -10
  218. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/setup.sh +0 -2
  219. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/spec.md +0 -73
  220. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/task.txt +0 -17
  221. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/verifiers/mixed-idempotent-settlement.js +0 -53
  222. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/verifiers/rejection-boundaries.js +0 -74
  223. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/NOTES.md +0 -28
  224. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/RETIRED.md +0 -15
  225. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/expected.json +0 -57
  226. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/metadata.json +0 -10
  227. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/setup.sh +0 -50
  228. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/spec.md +0 -59
  229. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/task.txt +0 -9
  230. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/ordered-settlement.js +0 -88
  231. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/reject-invalid.js +0 -45
  232. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/NOTES.md +0 -30
  233. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/RETIRED.md +0 -16
  234. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/expected.json +0 -64
  235. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/metadata.json +0 -10
  236. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/setup.sh +0 -21
  237. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/spec.md +0 -58
  238. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/task.txt +0 -9
  239. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/dup-op.js +0 -54
  240. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/priority-apply.js +0 -82
  241. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/rollback.js +0 -77
  242. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/NOTES.md +0 -99
  243. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/RETIRED.md +0 -18
  244. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/expected.json +0 -64
  245. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/metadata.json +0 -10
  246. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/setup.sh +0 -4
  247. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/spec.md +0 -61
  248. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/task.txt +0 -9
  249. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/correctness-small.js +0 -135
  250. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/scale.js +0 -100
  251. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/validation.js +0 -75
  252. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/NOTES.md +0 -93
  253. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/RETIRED.md +0 -16
  254. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/expected.json +0 -65
  255. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/metadata.json +0 -10
  256. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/setup.sh +0 -18
  257. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/spec.md +0 -66
  258. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/task.txt +0 -9
  259. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/correctness-small.js +0 -84
  260. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/scale.js +0 -184
  261. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/validation.js +0 -74
  262. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/NOTES.md +0 -60
  263. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/RETIRED.md +0 -29
  264. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/expected.json +0 -73
  265. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/metadata.json +0 -10
  266. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/setup.sh +0 -28
  267. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/spec.md +0 -58
  268. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/task.txt +0 -5
  269. package/benchmark/auto-resolve/fixtures/test-repo/README.md +0 -12
  270. package/benchmark/auto-resolve/fixtures/test-repo/bin/cli.js +0 -63
  271. package/benchmark/auto-resolve/fixtures/test-repo/package-lock.json +0 -823
  272. package/benchmark/auto-resolve/fixtures/test-repo/package.json +0 -22
  273. package/benchmark/auto-resolve/fixtures/test-repo/playwright.config.js +0 -17
  274. package/benchmark/auto-resolve/fixtures/test-repo/server/index.js +0 -37
  275. package/benchmark/auto-resolve/fixtures/test-repo/tests/cli.test.js +0 -25
  276. package/benchmark/auto-resolve/fixtures/test-repo/tests/server.test.js +0 -58
  277. package/benchmark/auto-resolve/fixtures/test-repo/web/index.html +0 -37
  278. package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.json +0 -25
  279. package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.md +0 -10
  280. package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.json +0 -18
  281. package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.md +0 -9
  282. package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.json +0 -18
  283. package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.md +0 -9
  284. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F16-cli-quote-tax-rules/l2_risk_probes/result.json +0 -28
  285. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F23-cli-fulfillment-wave/l2_risk_probes/result.json +0 -28
  286. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F25-cli-cart-promotion-rules/l2_risk_probes/result.json +0 -30
  287. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/full-pipeline-pair-gate.json +0 -82
  288. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/full-pipeline-pair-gate.md +0 -18
  289. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/headroom-gate.json +0 -46
  290. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/headroom-gate.md +0 -17
  291. package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.json +0 -28
  292. package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.md +0 -15
  293. package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.json +0 -28
  294. package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.md +0 -15
  295. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/F21-cli-scheduler-priority/l2_risk_probes/result.json +0 -32
  296. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.json +0 -44
  297. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.md +0 -16
  298. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.json +0 -18
  299. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.md +0 -9
  300. package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.json +0 -28
  301. package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.md +0 -15
  302. package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.json +0 -28
  303. package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.md +0 -15
  304. package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.json +0 -28
  305. package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.md +0 -15
  306. package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.json +0 -28
  307. package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.md +0 -15
  308. package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.json +0 -28
  309. package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.md +0 -15
  310. package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.json +0 -28
  311. package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.md +0 -15
  312. package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.json +0 -28
  313. package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.md +0 -15
  314. package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.json +0 -28
  315. package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.md +0 -15
  316. package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.json +0 -28
  317. package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.md +0 -15
  318. package/benchmark/auto-resolve/run-real-benchmark.md +0 -303
  319. package/benchmark/auto-resolve/scripts/audit-headroom-rejections.py +0 -441
  320. package/benchmark/auto-resolve/scripts/audit-pair-evidence.py +0 -1256
  321. package/benchmark/auto-resolve/scripts/build-pair-eligible-manifest.py +0 -306
  322. package/benchmark/auto-resolve/scripts/check-f9-artifacts.py +0 -268
  323. package/benchmark/auto-resolve/scripts/collect-swebench-predictions.py +0 -108
  324. package/benchmark/auto-resolve/scripts/compile-report.py +0 -493
  325. package/benchmark/auto-resolve/scripts/fetch-swebench-instances.py +0 -129
  326. package/benchmark/auto-resolve/scripts/frozen-verify-gate.py +0 -434
  327. package/benchmark/auto-resolve/scripts/full-pipeline-pair-gate.py +0 -612
  328. package/benchmark/auto-resolve/scripts/headroom-gate.py +0 -378
  329. package/benchmark/auto-resolve/scripts/iter-0033c-compare.py +0 -683
  330. package/benchmark/auto-resolve/scripts/iter-0033c-l1-summary.py +0 -97
  331. package/benchmark/auto-resolve/scripts/judge-opus-pass.sh +0 -542
  332. package/benchmark/auto-resolve/scripts/judge.sh +0 -565
  333. package/benchmark/auto-resolve/scripts/oracle-scope-tier-a.py +0 -256
  334. package/benchmark/auto-resolve/scripts/oracle-scope-tier-b.py +0 -287
  335. package/benchmark/auto-resolve/scripts/oracle-test-fidelity.py +0 -328
  336. package/benchmark/auto-resolve/scripts/pair-candidate-frontier.py +0 -469
  337. package/benchmark/auto-resolve/scripts/pair-plan-idgen.py +0 -401
  338. package/benchmark/auto-resolve/scripts/pair-plan-lint.py +0 -475
  339. package/benchmark/auto-resolve/scripts/pair-rejected-fixtures.sh +0 -103
  340. package/benchmark/auto-resolve/scripts/pair_evidence_contract.py +0 -270
  341. package/benchmark/auto-resolve/scripts/prepare-swebench-frozen-case.py +0 -273
  342. package/benchmark/auto-resolve/scripts/prepare-swebench-frozen-corpus.py +0 -148
  343. package/benchmark/auto-resolve/scripts/prepare-swebench-solver-worktree.py +0 -210
  344. package/benchmark/auto-resolve/scripts/recent-benchmark-summary.py +0 -232
  345. package/benchmark/auto-resolve/scripts/run-fixture.sh +0 -1024
  346. package/benchmark/auto-resolve/scripts/run-frozen-verify-pair.sh +0 -683
  347. package/benchmark/auto-resolve/scripts/run-full-pipeline-pair-candidate.sh +0 -458
  348. package/benchmark/auto-resolve/scripts/run-headroom-candidate.sh +0 -336
  349. package/benchmark/auto-resolve/scripts/run-iter-0033c.sh +0 -208
  350. package/benchmark/auto-resolve/scripts/run-suite.sh +0 -251
  351. package/benchmark/auto-resolve/scripts/run-swebench-frozen-corpus.sh +0 -310
  352. package/benchmark/auto-resolve/scripts/run-swebench-solver-batch.sh +0 -257
  353. package/benchmark/auto-resolve/scripts/ship-gate.py +0 -391
  354. package/benchmark/auto-resolve/scripts/solo-ceiling-avoidance.py +0 -53
  355. package/benchmark/auto-resolve/scripts/solo-headroom-hypothesis.py +0 -77
  356. package/benchmark/auto-resolve/scripts/swebench-frozen-matrix.py +0 -478
  357. package/benchmark/auto-resolve/scripts/test-audit-headroom-rejections.sh +0 -288
  358. package/benchmark/auto-resolve/scripts/test-audit-pair-evidence.sh +0 -1672
  359. package/benchmark/auto-resolve/scripts/test-benchmark-arg-parsing.sh +0 -1015
  360. package/benchmark/auto-resolve/scripts/test-build-pair-eligible-manifest.sh +0 -491
  361. package/benchmark/auto-resolve/scripts/test-check-f9-artifacts.sh +0 -91
  362. package/benchmark/auto-resolve/scripts/test-frozen-verify-gate.sh +0 -517
  363. package/benchmark/auto-resolve/scripts/test-full-pipeline-pair-gate.sh +0 -610
  364. package/benchmark/auto-resolve/scripts/test-headroom-gate.sh +0 -401
  365. package/benchmark/auto-resolve/scripts/test-iter-0033c-compare.sh +0 -525
  366. package/benchmark/auto-resolve/scripts/test-iter-0033c-l1-summary.sh +0 -254
  367. package/benchmark/auto-resolve/scripts/test-lint-fixtures.sh +0 -580
  368. package/benchmark/auto-resolve/scripts/test-pair-candidate-frontier.sh +0 -591
  369. package/benchmark/auto-resolve/scripts/test-run-full-pipeline-pair-candidate.sh +0 -497
  370. package/benchmark/auto-resolve/scripts/test-run-headroom-candidate.sh +0 -401
  371. package/benchmark/auto-resolve/scripts/test-run-swebench-solver-batch.sh +0 -111
  372. package/benchmark/auto-resolve/scripts/test-ship-gate.sh +0 -1189
  373. package/benchmark/auto-resolve/scripts/test-swebench-frozen-case.sh +0 -1221
  374. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/NOTES.md +0 -28
  375. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/expected.json +0 -63
  376. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/metadata.json +0 -10
  377. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/setup.sh +0 -3
  378. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/spec.md +0 -47
  379. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/task.txt +0 -1
  380. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/NOTES.md +0 -34
  381. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/expected.json +0 -53
  382. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/metadata.json +0 -10
  383. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/setup.sh +0 -3
  384. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/spec.md +0 -50
  385. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/task.txt +0 -1
  386. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/verifiers/duplicate-order-error.js +0 -27
  387. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/verifiers/priority-stock-reservation.js +0 -44
  388. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/NOTES.md +0 -34
  389. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/expected.json +0 -55
  390. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/metadata.json +0 -10
  391. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/setup.sh +0 -3
  392. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/spec.md +0 -52
  393. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/task.txt +0 -1
  394. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/verifiers/duplicate-ticket-error.js +0 -29
  395. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/verifiers/priority-agent-assignment.js +0 -48
  396. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/NOTES.md +0 -34
  397. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/expected.json +0 -55
  398. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/metadata.json +0 -10
  399. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/setup.sh +0 -3
  400. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/spec.md +0 -55
  401. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/task.txt +0 -1
  402. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/verifiers/duplicate-return-error.js +0 -43
  403. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/verifiers/priority-return-routing.js +0 -70
  404. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/NOTES.md +0 -37
  405. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/expected.json +0 -54
  406. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/metadata.json +0 -10
  407. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/setup.sh +0 -3
  408. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/spec.md +0 -59
  409. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/task.txt +0 -1
  410. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/verifiers/credit-ledger-priority.js +0 -98
  411. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/verifiers/duplicate-charge-error.js +0 -38
  412. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/NOTES.md +0 -36
  413. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/expected.json +0 -56
  414. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/metadata.json +0 -10
  415. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/setup.sh +0 -3
  416. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/spec.md +0 -59
  417. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/task.txt +0 -1
  418. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/verifiers/duplicate-refund-error.js +0 -41
  419. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/verifiers/priority-refund-ledger.js +0 -65
  420. package/config/skills/_shared/pair-plan-schema.md +0 -298
  421. package/scripts/lint-fixtures.sh +0 -352
  422. package/scripts/lint-shadow-fixtures.sh +0 -58
  423. package/scripts/lint-skills.sh +0 -4265
  424. package/scripts/test-owner-phases.py +0 -193
@@ -1,97 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Build iter-0033c L1 rerun summary from per-fixture judge/result artifacts."""
3
- from __future__ import annotations
4
-
5
- import argparse
6
- import json
7
- import sys
8
- from pathlib import Path
9
- from typing import Any
10
-
11
- SCRIPT_DIR = Path(__file__).resolve().parent
12
- if str(SCRIPT_DIR) not in sys.path:
13
- sys.path.insert(0, str(SCRIPT_DIR))
14
-
15
- from pair_evidence_contract import is_score, is_strict_number, loads_strict_json_object
16
-
17
-
18
- SCORE_ARMS = ("solo_claude", "l2_gated", "l2_forced", "bare")
19
-
20
-
21
- def load_json(path: Path) -> dict[str, Any]:
22
- try:
23
- data = loads_strict_json_object(path.read_text(encoding="utf8"))
24
- except (ValueError, json.JSONDecodeError):
25
- return {}
26
- return data
27
-
28
-
29
- def score_for(judge: dict[str, Any], arm: str, mapping: dict[str, Any]) -> int | None:
30
- letter = next(
31
- (slot for slot, mapped in mapping.items() if slot in {"A", "B", "C"} and mapped == arm),
32
- None,
33
- )
34
- if letter is None:
35
- return None
36
- raw_scores = judge.get("scores_by_arm")
37
- scores = raw_scores if isinstance(raw_scores, dict) else {}
38
- score = scores.get(arm)
39
- if is_score(score):
40
- return score
41
- legacy = judge.get(f"{letter.lower()}_score")
42
- return legacy if is_score(legacy) else None
43
-
44
-
45
- def strict_number(value: object) -> object:
46
- return value if is_strict_number(value) else None
47
-
48
-
49
- def build_summary(results_dir: Path, run_id: str, git_sha: str) -> dict[str, Any]:
50
- rows = []
51
- for fx_dir in sorted(p for p in results_dir.iterdir() if p.is_dir()):
52
- judge_path = fx_dir / "judge.json"
53
- if not judge_path.is_file():
54
- continue
55
- judge = load_json(judge_path)
56
- raw_mapping = judge.get("_blind_mapping")
57
- mapping = raw_mapping if isinstance(raw_mapping, dict) else {}
58
- arms = {}
59
- for arm_name in SCORE_ARMS:
60
- score = score_for(judge, arm_name, mapping)
61
- if score is None and arm_name not in set(mapping.values()):
62
- continue
63
- arm_dir = fx_dir / arm_name
64
- result = load_json(arm_dir / "result.json") if (arm_dir / "result.json").is_file() else {}
65
- arms[arm_name] = {
66
- "score": score,
67
- "wall_s": strict_number(result.get("elapsed_seconds")),
68
- "verify_score": strict_number(result.get("verify_score")),
69
- "files_changed": result.get("files_changed"),
70
- "timed_out": result.get("timed_out"),
71
- "disqualifier": result.get("disqualifier"),
72
- }
73
- rows.append({"fixture": fx_dir.name, "arms": arms})
74
- return {
75
- "run_id": run_id,
76
- "git_sha": git_sha,
77
- "fixtures_total": len(rows),
78
- "rows": rows,
79
- }
80
-
81
-
82
- def main() -> int:
83
- parser = argparse.ArgumentParser()
84
- parser.add_argument("--results-dir", required=True, type=Path)
85
- parser.add_argument("--out", required=True, type=Path)
86
- parser.add_argument("--run-id", required=True)
87
- parser.add_argument("--git-sha", required=True)
88
- args = parser.parse_args()
89
-
90
- summary = build_summary(args.results_dir, args.run_id, args.git_sha)
91
- args.out.write_text(json.dumps(summary, indent=2) + "\n", encoding="utf8")
92
- print(f"[l1-rerun-summary] wrote {args.out} (fixtures={summary['fixtures_total']})")
93
- return 0
94
-
95
-
96
- if __name__ == "__main__":
97
- raise SystemExit(main())
@@ -1,542 +0,0 @@
1
- #!/usr/bin/env bash
2
- # judge-opus-pass.sh — POST-RUN Opus dual-judge sidecar.
3
- #
4
- # Runs Opus (the Claude CLI's default model) over the SAME sanitized blind prompts that judge.sh wrote
5
- # (judge-prompt.txt), producing a parallel judge-opus.json alongside the
6
- # canonical judge.json. Does NOT modify judge.sh and does NOT change the
7
- # measurement contract for the in-flight run — this is a sidecar that adds
8
- # cross-judge data after the suite finishes.
9
- #
10
- # Why: judge.sh runs GPT-5.5 today; variant arms run Codex BUILD/FIX on
11
- # GPT-5.5 too — self-judgment bias. Opus pass tests inter-judge agreement.
12
- #
13
- # iter-0025 (B-1) rewrite — 3-arm aware. Prior version computed only legacy
14
- # `variant_score / bare_score / margin` from A/B slots (Codex R0 caught: F1
15
- # has variant in C; F6/F9 have bare in C — legacy parser silently produced
16
- # wrong margins on iter-0020 mappings). This version mirrors judge.sh post
17
- # iter-0023:
18
- # - Reads `_blind_mapping` from gpt judge.json (A/B/C → arm name).
19
- # - Requires C-slot score when C is present in mapping.
20
- # - Computes `scores_by_arm`, `margins.{variant_over_bare, solo_over_bare,
21
- # variant_over_solo}`, and per-arm 4-axis breakdown.
22
- # - Validates each axis cell ∈ [0, 25] (clamp + record under
23
- # `_axis_validation`, same shape as judge.sh).
24
- # - Always re-judges (no skip-on-exists) so cross-judge results never go
25
- # stale.
26
- # - Aggregator computes per-axis solo_claude-bare (L1-L0) disagreement vs
27
- # GPT (the decisive metric per Codex R0 Q1 — falsification rule: any axis
28
- # disagreement >2 means iter-0021/0023 L1 readout is single-judge artifact).
29
- #
30
- # Usage:
31
- # judge-opus-pass.sh --run-id <ID>
32
- #
33
- # Reads: results/<run-id>/<fixture>/judge-prompt.txt (blind A/B/C prompt)
34
- # results/<run-id>/<fixture>/judge.json (blind mapping)
35
- # Writes: results/<run-id>/<fixture>/judge-opus.json (Opus's parsed result)
36
- # results/<run-id>/cross-judge-summary.json (agreement metrics)
37
-
38
- set -euo pipefail
39
-
40
- usage() { echo "usage: $0 --run-id <ID>"; exit 1; }
41
- require_value() {
42
- local flag="$1"
43
- local value="${2:-}"
44
- if [ -z "$value" ] || [[ "$value" == --* ]]; then
45
- echo "$flag requires a value" >&2
46
- exit 1
47
- fi
48
- }
49
-
50
- RUN_ID=""
51
- while [ $# -gt 0 ]; do
52
- case "$1" in
53
- --run-id) require_value "$1" "${2:-}"; RUN_ID="$2"; shift 2;;
54
- *) usage;;
55
- esac
56
- done
57
- [ -n "$RUN_ID" ] || usage
58
-
59
- BENCH_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
60
- RES_ROOT="$BENCH_ROOT/results/$RUN_ID"
61
- [ -d "$RES_ROOT" ] || { echo "no results dir: $RES_ROOT"; exit 1; }
62
-
63
- python3 - "$RES_ROOT" "$BENCH_ROOT/scripts" <<'PY'
64
- import json
65
- import pathlib
66
- import sys
67
- sys.path.insert(0, sys.argv[2])
68
- from pair_evidence_contract import loads_strict_json_object
69
-
70
- def is_score(value):
71
- return isinstance(value, int) and not isinstance(value, bool) and 0 <= value <= 100
72
-
73
- res_root = pathlib.Path(sys.argv[1])
74
- errors = []
75
- for fixture_dir in sorted(p for p in res_root.glob("F*/") if p.is_dir()):
76
- judge_path = fixture_dir / "judge.json"
77
- prompt_path = fixture_dir / "judge-prompt.txt"
78
- if not judge_path.exists() or not prompt_path.exists():
79
- continue
80
- judge = loads_strict_json_object(judge_path.read_text())
81
- mapping = judge.get("_blind_mapping")
82
- if not isinstance(mapping, dict):
83
- errors.append(f"{fixture_dir.name}: judge blind mapping missing")
84
- continue
85
- mapped_arms = {arm for slot, arm in mapping.items() if slot in {"A", "B", "C"}}
86
- required = {"bare", "solo_claude"}
87
- raw_scores = judge.get("scores_by_arm")
88
- scores = raw_scores if isinstance(raw_scores, dict) else {}
89
- if "variant" in scores:
90
- required.add("variant")
91
- malformed_scores = sorted(arm for arm, score in scores.items() if not is_score(score))
92
- if malformed_scores:
93
- errors.append(f"{fixture_dir.name}: scores_by_arm malformed score(s): {', '.join(malformed_scores)}")
94
- missing = sorted(required - mapped_arms)
95
- if missing:
96
- errors.append(f"{fixture_dir.name}: judge blind mapping missing arm(s): {', '.join(missing)}")
97
- unmapped_scores = sorted(set(scores) - mapped_arms)
98
- if unmapped_scores:
99
- errors.append(f"{fixture_dir.name}: scores_by_arm without blind mapping: {', '.join(unmapped_scores)}")
100
-
101
- if errors:
102
- for error in errors:
103
- print(f"[opus-judge] ✗ {error}", file=sys.stderr)
104
- raise SystemExit(2)
105
- PY
106
-
107
- command -v claude >/dev/null 2>&1 || { echo "claude CLI not on PATH"; exit 1; }
108
-
109
- CLAUDE_CLI_VER=$(claude --version 2>/dev/null || echo "claude-cli unknown")
110
- JUDGE_MODEL_ALIAS="opus-default"
111
-
112
- echo "[opus-judge] run-id=$RUN_ID cli=$CLAUDE_CLI_VER model=$JUDGE_MODEL_ALIAS"
113
-
114
- processed=0
115
- skipped=0
116
- failed=0
117
-
118
- for fixture_dir in "$RES_ROOT"/F*/; do
119
- [ -d "$fixture_dir" ] || continue
120
- fid=$(basename "$fixture_dir")
121
- prompt_f="$fixture_dir/judge-prompt.txt"
122
- gpt_judge_f="$fixture_dir/judge.json"
123
- opus_out_raw="$fixture_dir/judge-opus-output.txt"
124
- opus_judge_f="$fixture_dir/judge-opus.json"
125
-
126
- if [ ! -f "$prompt_f" ] || [ ! -f "$gpt_judge_f" ]; then
127
- echo "[opus-judge] skip $fid (missing prompt or gpt judge)"
128
- skipped=$((skipped + 1))
129
- continue
130
- fi
131
-
132
- echo "[opus-judge] judging $fid ..."
133
-
134
- # Codex R1 #2: drop any stale judge-opus.json before re-judging. Otherwise
135
- # a parse failure here keeps the previous run's file and the aggregator
136
- # silently reads it.
137
- rm -f "$opus_judge_f"
138
-
139
- # Strict MCP isolation matches the variant arm contract — no user MCP
140
- # leakage into the judge call. Run from a clean tmp CWD so it can't peek
141
- # at project files that might leak arm identity.
142
- JUDGE_CWD="/tmp/opus-judge-$RUN_ID-$fid"
143
- rm -rf "$JUDGE_CWD"
144
- mkdir -p "$JUDGE_CWD"
145
-
146
- set +e
147
- ( cd "$JUDGE_CWD" && claude -p "$(cat "$prompt_f")" \
148
- --dangerously-skip-permissions \
149
- --strict-mcp-config --mcp-config '{"mcpServers":{}}' \
150
- ) > "$opus_out_raw" 2>&1
151
- rc=$?
152
- set -e
153
- rm -rf "$JUDGE_CWD"
154
-
155
- if [ $rc -ne 0 ]; then
156
- echo "[opus-judge] ✗ $fid claude -p exit=$rc (output preserved at $opus_out_raw)"
157
- failed=$((failed + 1))
158
- continue
159
- fi
160
-
161
- python3 - "$opus_out_raw" "$gpt_judge_f" "$opus_judge_f" "$CLAUDE_CLI_VER" "$JUDGE_MODEL_ALIAS" "$BENCH_ROOT/scripts" <<'PY' || { echo "[opus-judge] ✗ $fid parse failed"; failed=$((failed + 1)); continue; }
162
- import sys, json, pathlib
163
- sys.path.insert(0, sys.argv[6])
164
- from pair_evidence_contract import loads_strict_json_object, reject_json_constant
165
-
166
- def is_score(value):
167
- return isinstance(value, int) and not isinstance(value, bool) and 0 <= value <= 100
168
-
169
- def is_bool(value):
170
- return isinstance(value, bool)
171
-
172
- raw = pathlib.Path(sys.argv[1]).read_text()
173
- gpt = loads_strict_json_object(pathlib.Path(sys.argv[2]).read_text())
174
- target = pathlib.Path(sys.argv[3])
175
- cli_ver = sys.argv[4].strip()
176
- model_alias = sys.argv[5].strip()
177
-
178
- # Robust JSON extraction — last valid {} block with required score keys.
179
- mapping = gpt.get("_blind_mapping")
180
- if not isinstance(mapping, dict):
181
- raise SystemExit("gpt judge.json _blind_mapping must be an object")
182
- required_score_keys = ["a_score", "b_score"]
183
- if "C" in mapping:
184
- required_score_keys.append("c_score")
185
-
186
- decoder = json.JSONDecoder(parse_constant=reject_json_constant)
187
- brace_positions = [i for i, c in enumerate(raw) if c == '{']
188
- chosen = None
189
- for pos in reversed(brace_positions):
190
- try:
191
- obj, _ = decoder.raw_decode(raw[pos:])
192
- except json.JSONDecodeError:
193
- continue
194
- if isinstance(obj, dict) and all(k in obj for k in required_score_keys):
195
- chosen = obj
196
- break
197
- if chosen is None:
198
- raise SystemExit(
199
- f"no valid JSON with keys {required_score_keys} in opus output: {sys.argv[1]}"
200
- )
201
- invalid_scores = [key for key in required_score_keys if not is_score(chosen.get(key))]
202
- if invalid_scores:
203
- raise SystemExit(f"invalid opus score value(s): {', '.join(invalid_scores)}")
204
-
205
- # Axis validation — mirror judge.sh post iter-0023.
206
- AXIS_KEYS = ("spec", "constraint", "scope", "quality")
207
- BREAKDOWN_KEYS = ("a_breakdown", "b_breakdown", "c_breakdown")
208
- axis_invalid_cells = []
209
- for bk in BREAKDOWN_KEYS:
210
- if bk not in chosen or not isinstance(chosen[bk], dict):
211
- continue
212
- for axis in AXIS_KEYS:
213
- if axis not in chosen[bk]:
214
- continue
215
- v = chosen[bk][axis]
216
- if isinstance(v, bool) or not isinstance(v, (int, float)) or v < 0 or v > 25:
217
- axis_invalid_cells.append({"breakdown": bk, "axis": axis, "value": v})
218
- chosen[bk][axis] = max(0, min(25, int(v) if not isinstance(v, bool) and isinstance(v, (int, float)) else 0))
219
- chosen["_axis_validation"] = {
220
- "out_of_range_count": len(axis_invalid_cells),
221
- "out_of_range_cells": axis_invalid_cells,
222
- "axis_range": [0, 25],
223
- }
224
- if axis_invalid_cells:
225
- sys.stderr.write(
226
- f"[opus-judge] WARNING: {len(axis_invalid_cells)} axis cell(s) out of [0,25] "
227
- f"clamped: {axis_invalid_cells}\n"
228
- )
229
-
230
- # Reuse GPT's blind mapping verbatim (same blind A/B/C decoded the same way).
231
- chosen["_blind_mapping"] = mapping
232
- chosen["_judge_cli"] = cli_ver
233
- chosen["_judge_model"] = model_alias
234
-
235
- # scores_by_arm + margins — mirror judge.sh post iter-0023.
236
- slot_keys = ["a_score", "b_score", "c_score"]
237
- slot_letters = ["A", "B", "C"]
238
- scores_by_arm = {}
239
- for letter, key in zip(slot_letters, slot_keys):
240
- arm = mapping.get(letter)
241
- if arm is not None and key in chosen and is_score(chosen[key]):
242
- scores_by_arm[arm] = chosen[key]
243
- chosen["scores_by_arm"] = scores_by_arm
244
-
245
- def margin(left, right):
246
- if left in scores_by_arm and right in scores_by_arm:
247
- return scores_by_arm[left] - scores_by_arm[right]
248
- return None
249
-
250
- chosen["margins"] = {
251
- "variant_over_bare": margin("variant", "bare"),
252
- "solo_over_bare": margin("solo_claude", "bare"),
253
- "variant_over_solo": margin("variant", "solo_claude"),
254
- }
255
-
256
- # Per-arm axis breakdown.
257
- breakdowns_by_arm = {}
258
- for letter, bk in zip(slot_letters, BREAKDOWN_KEYS):
259
- arm = mapping.get(letter)
260
- if arm is not None and bk in chosen:
261
- breakdowns_by_arm[arm] = chosen[bk]
262
- chosen["breakdowns_by_arm"] = breakdowns_by_arm
263
-
264
- # Per-arm critical_findings + disqualifiers (same shape judge.sh emits).
265
- raw_findings_letters = chosen.get("critical_findings")
266
- findings_letters = raw_findings_letters if isinstance(raw_findings_letters, dict) else {}
267
- chosen["findings_by_arm"] = {
268
- mapping[l]: findings_letters.get(l, []) for l in slot_letters if l in mapping
269
- }
270
- raw_dq_letters = chosen.get("disqualifiers")
271
- dq_letters = raw_dq_letters if isinstance(raw_dq_letters, dict) else {}
272
- invalid_dq_letters = [
273
- letter for letter in slot_letters
274
- if letter in dq_letters and not is_bool(dq_letters.get(letter))
275
- ]
276
- if invalid_dq_letters:
277
- raise SystemExit(f"invalid opus disqualifier value(s): {', '.join(invalid_dq_letters)}")
278
- dq_by_arm = {}
279
- for l in slot_letters:
280
- if l not in mapping:
281
- continue
282
- arm = mapping[l]
283
- dq_by_arm[arm] = {
284
- "disqualifier": dq_letters.get(l, False) is True,
285
- "reason": str(dq_letters.get(f"{l}_reason", "") or ""),
286
- }
287
- chosen["disqualifiers_by_arm"] = dq_by_arm
288
-
289
- # Winner letter → arm.
290
- w = chosen.get("winner")
291
- if w in slot_letters and w in mapping:
292
- chosen["winner_arm"] = mapping[w]
293
- elif w == "tie":
294
- chosen["winner_arm"] = "tie"
295
- else:
296
- chosen["winner_arm"] = None
297
-
298
- # Legacy fields kept for back-compat.
299
- a_arm = mapping.get("A")
300
- b_arm = mapping.get("B")
301
- chosen["variant_score"] = scores_by_arm.get("variant")
302
- chosen["bare_score"] = scores_by_arm.get("bare")
303
- chosen["solo_score"] = scores_by_arm.get("solo_claude")
304
- if chosen["variant_score"] is not None and chosen["bare_score"] is not None:
305
- chosen["margin"] = chosen["variant_score"] - chosen["bare_score"]
306
- else:
307
- chosen["margin"] = None
308
-
309
- target.write_text(json.dumps(chosen, indent=2))
310
- print(
311
- f"[opus-judge] {target.parent.name} "
312
- f"v={chosen.get('variant_score')} l1={chosen.get('solo_score')} l0={chosen.get('bare_score')} "
313
- f"solo_claude-bare={chosen['margins']['solo_over_bare']} "
314
- f"variant-solo_claude={chosen['margins']['variant_over_solo']}"
315
- )
316
- PY
317
- processed=$((processed + 1))
318
- done
319
-
320
- echo "[opus-judge] judge passes: processed=$processed skipped=$skipped failed=$failed"
321
-
322
- # Aggregate cross-judge agreement, including per-axis solo_claude-bare (L1-L0) disagreement.
323
- python3 - "$RES_ROOT" "$BENCH_ROOT/scripts" <<'PY'
324
- import json, pathlib, sys, math
325
- sys.path.insert(0, sys.argv[2])
326
- from pair_evidence_contract import loads_strict_json_object
327
-
328
- def is_score(value):
329
- return isinstance(value, int) and not isinstance(value, bool) and 0 <= value <= 100
330
-
331
- res_root = pathlib.Path(sys.argv[1])
332
- rows = []
333
- axis_keys = ("spec", "constraint", "scope", "quality")
334
-
335
- for fdir in sorted(res_root.glob("F*/")):
336
- g_f = fdir / "judge.json"
337
- o_f = fdir / "judge-opus.json"
338
- if not g_f.exists() or not o_f.exists():
339
- continue
340
- g = loads_strict_json_object(g_f.read_text())
341
- o = loads_strict_json_object(o_f.read_text())
342
-
343
- # Per-axis solo_claude-bare (L1-L0) for both judges.
344
- # Codex R1 #1: judge.sh historically writes `a/b/c_breakdown` plus
345
- # `_blind_mapping`, NOT `breakdowns_by_arm`. iter-0020 judge.json files
346
- # are in that historical shape. Derive per-arm breakdowns from letter
347
- # fields when `breakdowns_by_arm` is absent; fail loudly when neither
348
- # source is available so axis disagreement never silently falls to zero.
349
- def blind_mapping(j):
350
- raw_mapping = j.get("_blind_mapping")
351
- return raw_mapping if isinstance(raw_mapping, dict) else {}
352
-
353
- def mapped_arm_set(j):
354
- mapping = blind_mapping(j)
355
- return {arm for slot, arm in mapping.items() if slot in {"A", "B", "C"}}
356
-
357
- def axis_l1_l0(j, label):
358
- mapped_arms = mapped_arm_set(j)
359
- bka = j.get("breakdowns_by_arm") or {}
360
- if {"solo_claude", "bare"}.issubset(mapped_arms) and "solo_claude" in bka and "bare" in bka:
361
- l1 = bka["solo_claude"]; l0 = bka["bare"]
362
- else:
363
- mapping = blind_mapping(j)
364
- slot_letters = ["A", "B", "C"]
365
- slot_breakdowns = ["a_breakdown", "b_breakdown", "c_breakdown"]
366
- derived = {}
367
- for letter, bk in zip(slot_letters, slot_breakdowns):
368
- arm = mapping.get(letter)
369
- if arm is not None and bk in j:
370
- derived[arm] = j[bk]
371
- if "solo_claude" not in derived or "bare" not in derived:
372
- raise SystemExit(
373
- f"[cross-judge] {label} judge.json missing breakdowns for solo_claude/bare; "
374
- "expected either `breakdowns_by_arm` or `a/b/c_breakdown` + `_blind_mapping`"
375
- )
376
- l1 = derived["solo_claude"]; l0 = derived["bare"]
377
- return {a: (l1.get(a, 0) - l0.get(a, 0)) for a in axis_keys}
378
-
379
- def mapped_scores(j):
380
- mapped_arms = mapped_arm_set(j)
381
- raw_scores = j.get("scores_by_arm")
382
- scores = raw_scores if isinstance(raw_scores, dict) else {}
383
- return {arm: score for arm, score in scores.items() if arm in mapped_arms and is_score(score)}
384
-
385
- def margin_from_scores(scores, left, right):
386
- if left in scores and right in scores:
387
- return scores[left] - scores[right]
388
- return None
389
-
390
- def mapped_winner(j, scores):
391
- winner = j.get("winner_arm")
392
- if winner == "tie" or winner in scores:
393
- return winner
394
- return None
395
-
396
- g_axes = axis_l1_l0(g, f"gpt {fdir.name}")
397
- o_axes = axis_l1_l0(o, f"opus {fdir.name}")
398
- axis_disagreement = {a: o_axes[a] - g_axes[a] for a in axis_keys}
399
-
400
- g_scores = mapped_scores(g)
401
- o_scores = mapped_scores(o)
402
- g_l1_l0 = margin_from_scores(g_scores, "solo_claude", "bare")
403
- o_l1_l0 = margin_from_scores(o_scores, "solo_claude", "bare")
404
- g_v_l0 = margin_from_scores(g_scores, "variant", "bare")
405
- o_v_l0 = margin_from_scores(o_scores, "variant", "bare")
406
- g_winner = mapped_winner(g, g_scores)
407
- o_winner = mapped_winner(o, o_scores)
408
- margin_l1_l0_diff = (
409
- abs(g_l1_l0 - o_l1_l0) if g_l1_l0 is not None and o_l1_l0 is not None else None
410
- )
411
- margin_v_l0_diff = (
412
- abs(g_v_l0 - o_v_l0) if g_v_l0 is not None and o_v_l0 is not None else None
413
- )
414
-
415
- rows.append({
416
- "fixture": fdir.name,
417
- "gpt_scores": g_scores,
418
- "opus_scores": o_scores,
419
- "gpt_margin_l1_l0": g_l1_l0,
420
- "opus_margin_l1_l0": o_l1_l0,
421
- "margin_l1_l0_diff": margin_l1_l0_diff,
422
- "gpt_margin_v_l0": g_v_l0,
423
- "opus_margin_v_l0": o_v_l0,
424
- "margin_v_l0_diff": margin_v_l0_diff,
425
- "gpt_axis_l1_l0": g_axes,
426
- "opus_axis_l1_l0": o_axes,
427
- "axis_disagreement": axis_disagreement,
428
- "winner_agree": g_winner is not None and o_winner is not None and g_winner == o_winner,
429
- "gpt_winner": g_winner,
430
- "opus_winner": o_winner,
431
- })
432
-
433
- if not rows:
434
- print("[cross-judge] no paired judgements found")
435
- sys.exit(0)
436
-
437
- n = len(rows)
438
-
439
- # Suite-level per-axis solo_claude-bare (L1-L0) sum (both judges) and disagreement.
440
- g_axis_sum = {a: sum(r["gpt_axis_l1_l0"][a] for r in rows) for a in axis_keys}
441
- o_axis_sum = {a: sum(r["opus_axis_l1_l0"][a] for r in rows) for a in axis_keys}
442
- axis_sum_disagreement = {a: o_axis_sum[a] - g_axis_sum[a] for a in axis_keys}
443
- max_abs_axis_disagreement = max(abs(v) for v in axis_sum_disagreement.values())
444
-
445
- # Per-axis falsification rule (Codex R0 Q1): any axis-sum disagreement >2 → single-judge artifact.
446
- THRESHOLD = 2
447
- falsified_by_axis = max_abs_axis_disagreement > THRESHOLD
448
- flipped_axes = [a for a, v in axis_sum_disagreement.items() if abs(v) > THRESHOLD]
449
-
450
- # Suite avg solo_claude-bare (L1-L0, both judges) — Codex R1 #3: divide by valid-count, report denom.
451
- gpt_l1_l0_valid = [r["gpt_margin_l1_l0"] for r in rows if r["gpt_margin_l1_l0"] is not None]
452
- opus_l1_l0_valid = [r["opus_margin_l1_l0"] for r in rows if r["opus_margin_l1_l0"] is not None]
453
- gpt_l1_l0_avg = (sum(gpt_l1_l0_valid) / len(gpt_l1_l0_valid)) if gpt_l1_l0_valid else None
454
- opus_l1_l0_avg = (sum(opus_l1_l0_valid) / len(opus_l1_l0_valid)) if opus_l1_l0_valid else None
455
- suite_avg_diff = (
456
- abs(gpt_l1_l0_avg - opus_l1_l0_avg)
457
- if gpt_l1_l0_avg is not None and opus_l1_l0_avg is not None else None
458
- )
459
-
460
- # Sign agreement — Codex R1 #4: 3-way sign (-, 0, +) so tie vs positive don't agree.
461
- def sign3(v):
462
- if v is None:
463
- return None
464
- return 1 if v > 0 else (-1 if v < 0 else 0)
465
-
466
- sign_agree_v_l0 = sum(
467
- 1 for r in rows
468
- if r["gpt_margin_v_l0"] is not None and r["opus_margin_v_l0"] is not None
469
- and sign3(r["gpt_margin_v_l0"]) == sign3(r["opus_margin_v_l0"])
470
- )
471
- sign_agree_l1_l0 = sum(
472
- 1 for r in rows
473
- if r["gpt_margin_l1_l0"] is not None and r["opus_margin_l1_l0"] is not None
474
- and sign3(r["gpt_margin_l1_l0"]) == sign3(r["opus_margin_l1_l0"])
475
- )
476
- sign_valid_l1_l0 = sum(
477
- 1 for r in rows
478
- if r["gpt_margin_l1_l0"] is not None and r["opus_margin_l1_l0"] is not None
479
- )
480
- sign_valid_v_l0 = sum(
481
- 1 for r in rows
482
- if r["gpt_margin_v_l0"] is not None and r["opus_margin_v_l0"] is not None
483
- )
484
- winner_agree = sum(1 for r in rows if r["winner_agree"])
485
-
486
- l1_l0_diffs = [r["margin_l1_l0_diff"] for r in rows if r["margin_l1_l0_diff"] is not None]
487
- mean_abs_l1_l0_diff = (sum(l1_l0_diffs) / len(l1_l0_diffs)) if l1_l0_diffs else None
488
-
489
- summary = {
490
- "n_fixtures": n,
491
- "threshold": THRESHOLD,
492
- "falsified_by_axis_disagreement": falsified_by_axis,
493
- "flipped_axes": flipped_axes,
494
- "axis_sum_l1_l0": {
495
- "gpt": g_axis_sum,
496
- "opus": o_axis_sum,
497
- "disagreement": axis_sum_disagreement,
498
- "max_abs_disagreement": max_abs_axis_disagreement,
499
- },
500
- "suite_avg_l1_l0": {
501
- "gpt": gpt_l1_l0_avg,
502
- "opus": opus_l1_l0_avg,
503
- "abs_diff": suite_avg_diff,
504
- "gpt_valid_count": len(gpt_l1_l0_valid),
505
- "opus_valid_count": len(opus_l1_l0_valid),
506
- },
507
- "winner_agree_count": winner_agree,
508
- "sign_agree_l1_l0": sign_agree_l1_l0,
509
- "sign_valid_count_l1_l0": sign_valid_l1_l0,
510
- "sign_agree_variant_over_bare": sign_agree_v_l0,
511
- "sign_valid_count_variant_over_bare": sign_valid_v_l0,
512
- "mean_abs_l1_l0_margin_diff": mean_abs_l1_l0_diff,
513
- "mean_abs_l1_l0_valid_count": len(l1_l0_diffs),
514
- "rows": rows,
515
- }
516
- out = res_root / "cross-judge-summary.json"
517
- out.write_text(json.dumps(summary, indent=2))
518
-
519
- def fmt_metric(value):
520
- return f"{value:.2f}" if value is not None else "na"
521
-
522
- print(
523
- f"[cross-judge] n={n} "
524
- f"falsified={falsified_by_axis} flipped_axes={flipped_axes} "
525
- f"max_axis_disagreement={max_abs_axis_disagreement} "
526
- f"gpt_l1_l0_avg={fmt_metric(gpt_l1_l0_avg)} "
527
- f"opus_l1_l0_avg={fmt_metric(opus_l1_l0_avg)} "
528
- f"suite_avg_diff={fmt_metric(suite_avg_diff)}"
529
- )
530
- print(f"[cross-judge] axis_sum_l1_l0: gpt={g_axis_sum} opus={o_axis_sum} disagree={axis_sum_disagreement}")
531
- print(f"[cross-judge] wrote {out}")
532
- PY
533
-
534
- # Hard-fail summary if any fixture in the selected result set lacks a paired judgement.
535
- EXPECTED_FIXTURES=$(ls -d "$RES_ROOT"/F*/ 2>/dev/null | wc -l | awk '{print $1}')
536
- PAIRED=$(find "$RES_ROOT" -maxdepth 2 -name 'judge-opus.json' | wc -l | awk '{print $1}')
537
- echo "[opus-judge] expected_fixtures=$EXPECTED_FIXTURES paired=$PAIRED"
538
- if [ "$PAIRED" -ne "$EXPECTED_FIXTURES" ]; then
539
- echo "[opus-judge] ✗ paired ($PAIRED) != expected ($EXPECTED_FIXTURES) — sidecar incomplete; do not interpret cross-judge until all fixtures judged."
540
- exit 2
541
- fi
542
- echo "[opus-judge] done: processed=$processed skipped=$skipped failed=$failed"