devlyn-cli 3.2.1 → 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 (423) hide show
  1. package/AGENTS.md +2 -2
  2. package/CLAUDE.md +2 -2
  3. package/README.md +12 -102
  4. package/bin/devlyn.js +13 -225
  5. package/bin/instruction-templates.json +6 -0
  6. package/config/skills/_shared/adapters/grok.md +1 -2
  7. package/config/skills/_shared/archive_run.py +15 -3
  8. package/config/skills/_shared/judge-role-evidence.py +21 -1
  9. package/config/skills/_shared/runtime-principles.md +1 -1
  10. package/config/skills/_shared/spec-verify-check.py +0 -653
  11. package/config/skills/_shared/state-phase-write.py +351 -25
  12. package/config/skills/_shared/task-complete.py +635 -143
  13. package/config/skills/_shared/terminal-claim-check.py +229 -4
  14. package/config/skills/_shared/verify-merge-findings.py +93 -2
  15. package/config/skills/devlyn:ideate/SKILL.md +3 -4
  16. package/config/skills/devlyn:ideate/references/elicitation.md +2 -35
  17. package/config/skills/devlyn:ideate/references/from-spec-mode.md +3 -18
  18. package/config/skills/devlyn:ideate/references/project-mode.md +1 -16
  19. package/config/skills/devlyn:ideate/references/spec-template.md +0 -2
  20. package/config/skills/devlyn:queue/SKILL.md +6 -4
  21. package/config/skills/devlyn:resolve/SKILL.md +16 -25
  22. package/config/skills/devlyn:resolve/references/free-form-mode.md +0 -14
  23. package/config/skills/devlyn:resolve/references/outer-loop.md +1 -1
  24. package/config/skills/devlyn:resolve/references/phases/build-gate.md +1 -1
  25. package/config/skills/devlyn:resolve/references/phases/cleanup.md +3 -3
  26. package/config/skills/devlyn:resolve/references/phases/implement.md +1 -1
  27. package/config/skills/devlyn:resolve/references/phases/probe-derive.md +1 -16
  28. package/config/skills/devlyn:resolve/references/phases/verify.md +4 -9
  29. package/config/skills/devlyn:resolve/references/state-schema.md +9 -7
  30. package/config/skills/devlyn:resolve/references/task-completion.md +46 -37
  31. package/{config/skills → optional-skills}/code-health-standards/SKILL.md +4 -13
  32. package/{config/skills → optional-skills}/code-review-standards/SKILL.md +4 -12
  33. package/{config/skills → optional-skills}/root-cause-analysis/SKILL.md +4 -12
  34. package/{config/skills → optional-skills}/ui-implementation-standards/SKILL.md +4 -14
  35. package/package.json +1 -57
  36. package/benchmark/auto-resolve/BENCHMARK-DESIGN.md +0 -289
  37. package/benchmark/auto-resolve/BENCHMARK-RESULTS.md +0 -341
  38. package/benchmark/auto-resolve/README.md +0 -696
  39. package/benchmark/auto-resolve/RUBRIC.md +0 -177
  40. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/NOTES.md +0 -34
  41. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/expected.json +0 -68
  42. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/metadata.json +0 -10
  43. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/setup.sh +0 -4
  44. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/spec.md +0 -44
  45. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.ko.txt +0 -8
  46. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.txt +0 -8
  47. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/NOTES.md +0 -68
  48. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/expected.json +0 -60
  49. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/metadata.json +0 -10
  50. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/setup.sh +0 -17
  51. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/spec.md +0 -51
  52. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/task.txt +0 -9
  53. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/verifiers/invalid.js +0 -29
  54. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/verifiers/parallel.js +0 -50
  55. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/NOTES.md +0 -75
  56. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/expected.json +0 -52
  57. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/metadata.json +0 -10
  58. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/setup.sh +0 -171
  59. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/spec.md +0 -50
  60. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/task.txt +0 -9
  61. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/NOTES.md +0 -89
  62. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/expected.json +0 -74
  63. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/metadata.json +0 -10
  64. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/setup.sh +0 -251
  65. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/spec.md +0 -57
  66. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/task.txt +0 -13
  67. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/verifiers/replay-malformed-body.js +0 -64
  68. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/NOTES.md +0 -104
  69. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/expected.json +0 -46
  70. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/metadata.json +0 -10
  71. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/setup.sh +0 -336
  72. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/spec.md +0 -51
  73. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/task.txt +0 -9
  74. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/NOTES.md +0 -38
  75. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/expected.json +0 -64
  76. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/metadata.json +0 -10
  77. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/setup.sh +0 -32
  78. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/spec.md +0 -63
  79. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/task.txt +0 -7
  80. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/exact-success.js +0 -54
  81. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/no-hardcoded-pricing.js +0 -47
  82. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/stock-error.js +0 -45
  83. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/NOTES.md +0 -57
  84. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected-pair-plan-registry.json +0 -170
  85. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected.json +0 -84
  86. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/metadata.json +0 -21
  87. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-fail.json +0 -214
  88. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-pass.json +0 -223
  89. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/setup.sh +0 -5
  90. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/spec.md +0 -55
  91. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/task.txt +0 -14
  92. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/NOTES.md +0 -39
  93. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/expected.json +0 -62
  94. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/metadata.json +0 -10
  95. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/setup.sh +0 -2
  96. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/spec.md +0 -67
  97. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/task.txt +0 -7
  98. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/verifiers/error-order.js +0 -55
  99. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/verifiers/priority-blocked.js +0 -48
  100. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/NOTES.md +0 -35
  101. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/expected.json +0 -56
  102. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/metadata.json +0 -10
  103. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/setup.sh +0 -2
  104. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/spec.md +0 -64
  105. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/task.txt +0 -7
  106. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/verifiers/conflicting-duplicate.js +0 -34
  107. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/verifiers/idempotent-close.js +0 -41
  108. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/NOTES.md +0 -39
  109. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/expected.json +0 -56
  110. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/metadata.json +0 -10
  111. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/setup.sh +0 -2
  112. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/spec.md +0 -76
  113. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/task.txt +0 -7
  114. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/verifiers/priority-rollback.js +0 -64
  115. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/verifiers/single-warehouse-fefo.js +0 -66
  116. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/NOTES.md +0 -40
  117. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/expected.json +0 -66
  118. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/metadata.json +0 -10
  119. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/setup.sh +0 -36
  120. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/spec.md +0 -71
  121. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/task.txt +0 -7
  122. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/catalog-source.js +0 -57
  123. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/exact-success.js +0 -63
  124. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/stock-error.js +0 -34
  125. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/NOTES.md +0 -31
  126. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/expected.json +0 -68
  127. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/metadata.json +0 -10
  128. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/setup.sh +0 -17
  129. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/spec.md +0 -68
  130. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/task.txt +0 -7
  131. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/conflicting-duplicate.js +0 -29
  132. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/exact-payout.js +0 -58
  133. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/rules-source.js +0 -56
  134. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/NOTES.md +0 -35
  135. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected-pair-plan-registry.json +0 -162
  136. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected.json +0 -67
  137. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/metadata.json +0 -19
  138. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/setup.sh +0 -4
  139. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/spec.md +0 -55
  140. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/task.txt +0 -9
  141. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/NOTES.md +0 -34
  142. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/expected.json +0 -57
  143. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/metadata.json +0 -10
  144. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/setup.sh +0 -2
  145. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/spec.md +0 -67
  146. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/task.txt +0 -7
  147. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/verifiers/duplicate-event-error.js +0 -35
  148. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/verifiers/priority-transfer-rollback.js +0 -53
  149. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/NOTES.md +0 -38
  150. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/expected.json +0 -57
  151. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/metadata.json +0 -10
  152. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/setup.sh +0 -2
  153. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/spec.md +0 -70
  154. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/task.txt +0 -3
  155. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/verifiers/duplicate-renewal-error.js +0 -42
  156. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/verifiers/priority-credit-rollback.js +0 -70
  157. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/NOTES.md +0 -47
  158. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/expected.json +0 -57
  159. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/metadata.json +0 -10
  160. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/setup.sh +0 -6
  161. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/spec.md +0 -48
  162. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/task.txt +0 -9
  163. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/NOTES.md +0 -45
  164. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/expected.json +0 -65
  165. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/metadata.json +0 -10
  166. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/setup.sh +0 -55
  167. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/spec.md +0 -48
  168. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/task.txt +0 -7
  169. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/NOTES.md +0 -43
  170. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/expected.json +0 -77
  171. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/metadata.json +0 -10
  172. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/setup.sh +0 -4
  173. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/spec.md +0 -48
  174. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/task.txt +0 -10
  175. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/NOTES.md +0 -57
  176. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/expected.json +0 -76
  177. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/metadata.json +0 -10
  178. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/setup.sh +0 -36
  179. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/spec.md +0 -45
  180. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/task.txt +0 -7
  181. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/NOTES.md +0 -53
  182. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/expected.json +0 -63
  183. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/metadata.json +0 -10
  184. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/setup.sh +0 -4
  185. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/spec.md +0 -48
  186. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/task.txt +0 -1
  187. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/NOTES.md +0 -105
  188. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/expected.json +0 -74
  189. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/metadata.json +0 -10
  190. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/setup.sh +0 -28
  191. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/spec.md +0 -59
  192. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/task.txt +0 -5
  193. package/benchmark/auto-resolve/fixtures/SCHEMA.md +0 -188
  194. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/NOTES.md +0 -37
  195. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/RETIRED.md +0 -13
  196. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/expected.json +0 -56
  197. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/metadata.json +0 -10
  198. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/setup.sh +0 -18
  199. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/spec.md +0 -69
  200. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/task.txt +0 -7
  201. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/verifiers/exact-proration.js +0 -48
  202. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/verifiers/rules-source-and-conflict.js +0 -79
  203. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/NOTES.md +0 -54
  204. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/RETIRED.md +0 -7
  205. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/expected.json +0 -67
  206. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/metadata.json +0 -10
  207. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/setup.sh +0 -2
  208. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/spec.md +0 -67
  209. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/task.txt +0 -5
  210. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/policy-precedence.js +0 -72
  211. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/validation-and-immutability.js +0 -43
  212. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/validation-boundary.js +0 -116
  213. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/NOTES.md +0 -35
  214. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/RETIRED.md +0 -12
  215. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/expected.json +0 -58
  216. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/metadata.json +0 -10
  217. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/setup.sh +0 -2
  218. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/spec.md +0 -73
  219. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/task.txt +0 -17
  220. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/verifiers/mixed-idempotent-settlement.js +0 -53
  221. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/verifiers/rejection-boundaries.js +0 -74
  222. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/NOTES.md +0 -28
  223. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/RETIRED.md +0 -15
  224. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/expected.json +0 -57
  225. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/metadata.json +0 -10
  226. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/setup.sh +0 -50
  227. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/spec.md +0 -59
  228. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/task.txt +0 -9
  229. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/ordered-settlement.js +0 -88
  230. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/reject-invalid.js +0 -45
  231. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/NOTES.md +0 -30
  232. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/RETIRED.md +0 -16
  233. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/expected.json +0 -64
  234. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/metadata.json +0 -10
  235. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/setup.sh +0 -21
  236. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/spec.md +0 -58
  237. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/task.txt +0 -9
  238. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/dup-op.js +0 -54
  239. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/priority-apply.js +0 -82
  240. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/rollback.js +0 -77
  241. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/NOTES.md +0 -99
  242. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/RETIRED.md +0 -18
  243. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/expected.json +0 -64
  244. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/metadata.json +0 -10
  245. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/setup.sh +0 -4
  246. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/spec.md +0 -61
  247. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/task.txt +0 -9
  248. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/correctness-small.js +0 -135
  249. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/scale.js +0 -100
  250. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/validation.js +0 -75
  251. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/NOTES.md +0 -93
  252. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/RETIRED.md +0 -16
  253. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/expected.json +0 -65
  254. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/metadata.json +0 -10
  255. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/setup.sh +0 -18
  256. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/spec.md +0 -66
  257. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/task.txt +0 -9
  258. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/correctness-small.js +0 -84
  259. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/scale.js +0 -184
  260. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/validation.js +0 -74
  261. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/NOTES.md +0 -60
  262. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/RETIRED.md +0 -29
  263. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/expected.json +0 -73
  264. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/metadata.json +0 -10
  265. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/setup.sh +0 -28
  266. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/spec.md +0 -58
  267. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/task.txt +0 -5
  268. package/benchmark/auto-resolve/fixtures/test-repo/README.md +0 -12
  269. package/benchmark/auto-resolve/fixtures/test-repo/bin/cli.js +0 -63
  270. package/benchmark/auto-resolve/fixtures/test-repo/package-lock.json +0 -823
  271. package/benchmark/auto-resolve/fixtures/test-repo/package.json +0 -22
  272. package/benchmark/auto-resolve/fixtures/test-repo/playwright.config.js +0 -17
  273. package/benchmark/auto-resolve/fixtures/test-repo/server/index.js +0 -37
  274. package/benchmark/auto-resolve/fixtures/test-repo/tests/cli.test.js +0 -25
  275. package/benchmark/auto-resolve/fixtures/test-repo/tests/server.test.js +0 -58
  276. package/benchmark/auto-resolve/fixtures/test-repo/web/index.html +0 -37
  277. package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.json +0 -25
  278. package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.md +0 -10
  279. package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.json +0 -18
  280. package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.md +0 -9
  281. package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.json +0 -18
  282. package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.md +0 -9
  283. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F16-cli-quote-tax-rules/l2_risk_probes/result.json +0 -28
  284. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F23-cli-fulfillment-wave/l2_risk_probes/result.json +0 -28
  285. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F25-cli-cart-promotion-rules/l2_risk_probes/result.json +0 -30
  286. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/full-pipeline-pair-gate.json +0 -82
  287. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/full-pipeline-pair-gate.md +0 -18
  288. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/headroom-gate.json +0 -46
  289. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/headroom-gate.md +0 -17
  290. package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.json +0 -28
  291. package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.md +0 -15
  292. package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.json +0 -28
  293. package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.md +0 -15
  294. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/F21-cli-scheduler-priority/l2_risk_probes/result.json +0 -32
  295. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.json +0 -44
  296. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.md +0 -16
  297. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.json +0 -18
  298. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.md +0 -9
  299. package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.json +0 -28
  300. package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.md +0 -15
  301. package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.json +0 -28
  302. package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.md +0 -15
  303. package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.json +0 -28
  304. package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.md +0 -15
  305. package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.json +0 -28
  306. package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.md +0 -15
  307. package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.json +0 -28
  308. package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.md +0 -15
  309. package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.json +0 -28
  310. package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.md +0 -15
  311. package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.json +0 -28
  312. package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.md +0 -15
  313. package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.json +0 -28
  314. package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.md +0 -15
  315. package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.json +0 -28
  316. package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.md +0 -15
  317. package/benchmark/auto-resolve/run-real-benchmark.md +0 -303
  318. package/benchmark/auto-resolve/scripts/audit-headroom-rejections.py +0 -441
  319. package/benchmark/auto-resolve/scripts/audit-pair-evidence.py +0 -1256
  320. package/benchmark/auto-resolve/scripts/build-pair-eligible-manifest.py +0 -306
  321. package/benchmark/auto-resolve/scripts/check-f9-artifacts.py +0 -268
  322. package/benchmark/auto-resolve/scripts/collect-swebench-predictions.py +0 -108
  323. package/benchmark/auto-resolve/scripts/compile-report.py +0 -493
  324. package/benchmark/auto-resolve/scripts/fetch-swebench-instances.py +0 -129
  325. package/benchmark/auto-resolve/scripts/frozen-verify-gate.py +0 -434
  326. package/benchmark/auto-resolve/scripts/full-pipeline-pair-gate.py +0 -612
  327. package/benchmark/auto-resolve/scripts/headroom-gate.py +0 -378
  328. package/benchmark/auto-resolve/scripts/iter-0033c-compare.py +0 -683
  329. package/benchmark/auto-resolve/scripts/iter-0033c-l1-summary.py +0 -97
  330. package/benchmark/auto-resolve/scripts/judge-opus-pass.sh +0 -542
  331. package/benchmark/auto-resolve/scripts/judge.sh +0 -565
  332. package/benchmark/auto-resolve/scripts/oracle-scope-tier-a.py +0 -256
  333. package/benchmark/auto-resolve/scripts/oracle-scope-tier-b.py +0 -287
  334. package/benchmark/auto-resolve/scripts/oracle-test-fidelity.py +0 -328
  335. package/benchmark/auto-resolve/scripts/pair-candidate-frontier.py +0 -469
  336. package/benchmark/auto-resolve/scripts/pair-plan-idgen.py +0 -401
  337. package/benchmark/auto-resolve/scripts/pair-plan-lint.py +0 -475
  338. package/benchmark/auto-resolve/scripts/pair-rejected-fixtures.sh +0 -103
  339. package/benchmark/auto-resolve/scripts/pair_evidence_contract.py +0 -270
  340. package/benchmark/auto-resolve/scripts/prepare-swebench-frozen-case.py +0 -273
  341. package/benchmark/auto-resolve/scripts/prepare-swebench-frozen-corpus.py +0 -148
  342. package/benchmark/auto-resolve/scripts/prepare-swebench-solver-worktree.py +0 -210
  343. package/benchmark/auto-resolve/scripts/recent-benchmark-summary.py +0 -232
  344. package/benchmark/auto-resolve/scripts/run-fixture.sh +0 -1024
  345. package/benchmark/auto-resolve/scripts/run-frozen-verify-pair.sh +0 -683
  346. package/benchmark/auto-resolve/scripts/run-full-pipeline-pair-candidate.sh +0 -458
  347. package/benchmark/auto-resolve/scripts/run-headroom-candidate.sh +0 -336
  348. package/benchmark/auto-resolve/scripts/run-iter-0033c.sh +0 -208
  349. package/benchmark/auto-resolve/scripts/run-suite.sh +0 -251
  350. package/benchmark/auto-resolve/scripts/run-swebench-frozen-corpus.sh +0 -310
  351. package/benchmark/auto-resolve/scripts/run-swebench-solver-batch.sh +0 -257
  352. package/benchmark/auto-resolve/scripts/ship-gate.py +0 -391
  353. package/benchmark/auto-resolve/scripts/solo-ceiling-avoidance.py +0 -53
  354. package/benchmark/auto-resolve/scripts/solo-headroom-hypothesis.py +0 -77
  355. package/benchmark/auto-resolve/scripts/swebench-frozen-matrix.py +0 -478
  356. package/benchmark/auto-resolve/scripts/test-audit-headroom-rejections.sh +0 -288
  357. package/benchmark/auto-resolve/scripts/test-audit-pair-evidence.sh +0 -1672
  358. package/benchmark/auto-resolve/scripts/test-benchmark-arg-parsing.sh +0 -1015
  359. package/benchmark/auto-resolve/scripts/test-build-pair-eligible-manifest.sh +0 -491
  360. package/benchmark/auto-resolve/scripts/test-check-f9-artifacts.sh +0 -91
  361. package/benchmark/auto-resolve/scripts/test-frozen-verify-gate.sh +0 -517
  362. package/benchmark/auto-resolve/scripts/test-full-pipeline-pair-gate.sh +0 -610
  363. package/benchmark/auto-resolve/scripts/test-headroom-gate.sh +0 -401
  364. package/benchmark/auto-resolve/scripts/test-iter-0033c-compare.sh +0 -525
  365. package/benchmark/auto-resolve/scripts/test-iter-0033c-l1-summary.sh +0 -254
  366. package/benchmark/auto-resolve/scripts/test-lint-fixtures.sh +0 -580
  367. package/benchmark/auto-resolve/scripts/test-pair-candidate-frontier.sh +0 -591
  368. package/benchmark/auto-resolve/scripts/test-run-full-pipeline-pair-candidate.sh +0 -497
  369. package/benchmark/auto-resolve/scripts/test-run-headroom-candidate.sh +0 -401
  370. package/benchmark/auto-resolve/scripts/test-run-swebench-solver-batch.sh +0 -111
  371. package/benchmark/auto-resolve/scripts/test-ship-gate.sh +0 -1189
  372. package/benchmark/auto-resolve/scripts/test-swebench-frozen-case.sh +0 -1221
  373. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/NOTES.md +0 -28
  374. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/expected.json +0 -63
  375. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/metadata.json +0 -10
  376. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/setup.sh +0 -3
  377. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/spec.md +0 -47
  378. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/task.txt +0 -1
  379. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/NOTES.md +0 -34
  380. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/expected.json +0 -53
  381. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/metadata.json +0 -10
  382. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/setup.sh +0 -3
  383. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/spec.md +0 -50
  384. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/task.txt +0 -1
  385. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/verifiers/duplicate-order-error.js +0 -27
  386. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/verifiers/priority-stock-reservation.js +0 -44
  387. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/NOTES.md +0 -34
  388. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/expected.json +0 -55
  389. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/metadata.json +0 -10
  390. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/setup.sh +0 -3
  391. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/spec.md +0 -52
  392. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/task.txt +0 -1
  393. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/verifiers/duplicate-ticket-error.js +0 -29
  394. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/verifiers/priority-agent-assignment.js +0 -48
  395. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/NOTES.md +0 -34
  396. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/expected.json +0 -55
  397. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/metadata.json +0 -10
  398. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/setup.sh +0 -3
  399. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/spec.md +0 -55
  400. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/task.txt +0 -1
  401. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/verifiers/duplicate-return-error.js +0 -43
  402. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/verifiers/priority-return-routing.js +0 -70
  403. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/NOTES.md +0 -37
  404. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/expected.json +0 -54
  405. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/metadata.json +0 -10
  406. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/setup.sh +0 -3
  407. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/spec.md +0 -59
  408. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/task.txt +0 -1
  409. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/verifiers/credit-ledger-priority.js +0 -98
  410. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/verifiers/duplicate-charge-error.js +0 -38
  411. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/NOTES.md +0 -36
  412. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/expected.json +0 -56
  413. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/metadata.json +0 -10
  414. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/setup.sh +0 -3
  415. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/spec.md +0 -59
  416. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/task.txt +0 -1
  417. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/verifiers/duplicate-refund-error.js +0 -41
  418. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/verifiers/priority-refund-ledger.js +0 -65
  419. package/config/skills/_shared/pair-plan-schema.md +0 -298
  420. package/scripts/lint-fixtures.sh +0 -352
  421. package/scripts/lint-shadow-fixtures.sh +0 -58
  422. package/scripts/lint-skills.sh +0 -4265
  423. package/scripts/test-owner-phases.py +0 -238
@@ -1,257 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Prepare SWE-bench solver worktrees, run a direct solver, and collect patches.
3
- set -euo pipefail
4
-
5
- usage() {
6
- cat >&2 <<EOF
7
- usage: $0 --instances-jsonl <path> --predictions-out <path>
8
- [--instance-id ID ...] [--limit N] [--model-name NAME]
9
- [--repos-root <path>] [--worktrees-root <path>]
10
- [--timeout-seconds N] [--copy-devlyn-context] [--resume]
11
-
12
- Runs Claude Code directly against each selected SWE-bench instance without
13
- reading gold patch/test_patch fields. Each worktree receives patch.diff plus
14
- direct-transcript.txt and claude-direct-debug.log. At the end, patch.diff files
15
- are collected into a SWE-bench predictions JSONL.
16
- EOF
17
- exit "${1:-1}"
18
- }
19
-
20
- INSTANCES_JSONL=""
21
- PREDICTIONS_OUT=""
22
- MODEL_NAME="claude-direct"
23
- REPOS_ROOT="benchmark/auto-resolve/external/swebench/repos-solver"
24
- WORKTREES_ROOT="benchmark/auto-resolve/external/swebench/worktrees"
25
- TIMEOUT_SECONDS=2400
26
- COPY_DEVLYN_CONTEXT=0
27
- RESUME=0
28
- LIMIT=""
29
- INSTANCE_IDS=()
30
-
31
- require_value() {
32
- local flag="$1"
33
- local value="${2:-}"
34
- if [ -z "$value" ] || [[ "$value" == --* ]]; then
35
- echo "$flag requires a value" >&2
36
- exit 1
37
- fi
38
- }
39
-
40
- while [ $# -gt 0 ]; do
41
- case "$1" in
42
- --instances-jsonl) require_value "$1" "${2:-}"; INSTANCES_JSONL="$2"; shift 2;;
43
- --predictions-out) require_value "$1" "${2:-}"; PREDICTIONS_OUT="$2"; shift 2;;
44
- --model-name) require_value "$1" "${2:-}"; MODEL_NAME="$2"; shift 2;;
45
- --repos-root) require_value "$1" "${2:-}"; REPOS_ROOT="$2"; shift 2;;
46
- --worktrees-root) require_value "$1" "${2:-}"; WORKTREES_ROOT="$2"; shift 2;;
47
- --timeout-seconds) require_value "$1" "${2:-}"; TIMEOUT_SECONDS="$2"; shift 2;;
48
- --copy-devlyn-context) COPY_DEVLYN_CONTEXT=1; shift;;
49
- --resume) RESUME=1; shift;;
50
- --limit) require_value "$1" "${2:-}"; LIMIT="$2"; shift 2;;
51
- --instance-id) require_value "$1" "${2:-}"; INSTANCE_IDS+=("$2"); shift 2;;
52
- -h|--help) usage 0;;
53
- *) echo "unknown arg: $1" >&2; usage 1;;
54
- esac
55
- done
56
-
57
- [ -n "$INSTANCES_JSONL" ] || usage 1
58
- [ -n "$PREDICTIONS_OUT" ] || usage 1
59
- [ -f "$INSTANCES_JSONL" ] || { echo "instances JSONL not found: $INSTANCES_JSONL" >&2; exit 1; }
60
- case "$TIMEOUT_SECONDS" in ''|*[!0-9]*) echo "--timeout-seconds must be an integer" >&2; exit 1;; esac
61
- [ "$TIMEOUT_SECONDS" -gt 0 ] || { echo "--timeout-seconds must be > 0" >&2; exit 1; }
62
- if [ -n "$LIMIT" ]; then
63
- case "$LIMIT" in ''|*[!0-9]*) echo "--limit must be an integer" >&2; exit 1;; esac
64
- [ "$LIMIT" -gt 0 ] || { echo "--limit must be > 0" >&2; exit 1; }
65
- fi
66
- command -v claude >/dev/null 2>&1 || { echo "claude command not found" >&2; exit 1; }
67
- mkdir -p "$REPOS_ROOT" "$WORKTREES_ROOT" "$(dirname "$PREDICTIONS_OUT")"
68
-
69
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
70
- TMP_IDS="$(mktemp)"
71
- TMP_SELECTED_INSTANCES="$(mktemp)"
72
- trap 'rm -f "$TMP_IDS" "$TMP_SELECTED_INSTANCES"' EXIT
73
-
74
- selection_args=("$INSTANCES_JSONL" "$TMP_SELECTED_INSTANCES" "$LIMIT")
75
- if [ "${#INSTANCE_IDS[@]}" -gt 0 ]; then
76
- selection_args+=("${INSTANCE_IDS[@]}")
77
- fi
78
-
79
- python3 - "$SCRIPT_DIR" "${selection_args[@]}" > "$TMP_IDS" <<'PY'
80
- import json
81
- import sys
82
- from pathlib import Path
83
- sys.path.insert(0, sys.argv[1])
84
- from pair_evidence_contract import reject_json_constant
85
-
86
- instances_path = Path(sys.argv[2])
87
- selected_path = Path(sys.argv[3])
88
- limit = int(sys.argv[4]) if sys.argv[4] else None
89
- requested = sys.argv[5:]
90
- requested_set = set(requested)
91
- rows = []
92
- with instances_path.open(encoding="utf8") as f:
93
- for line_no, line in enumerate(f, start=1):
94
- if not line.strip():
95
- continue
96
- row = json.loads(line, parse_constant=reject_json_constant)
97
- if not isinstance(row, dict):
98
- raise SystemExit(f"{instances_path}:{line_no}: expected JSON object")
99
- instance_id = row.get("instance_id")
100
- if not isinstance(instance_id, str) or not instance_id:
101
- raise SystemExit(f"{instances_path}:{line_no}: missing instance_id")
102
- if requested_set and instance_id not in requested_set:
103
- continue
104
- rows.append(row)
105
- if limit is not None and len(rows) >= limit:
106
- break
107
- if requested_set:
108
- missing = sorted(requested_set - {row["instance_id"] for row in rows})
109
- if missing:
110
- raise SystemExit(f"requested instance ids not found: {', '.join(missing)}")
111
- for instance_id in rows:
112
- print(instance_id["instance_id"])
113
- with selected_path.open("w", encoding="utf8") as f:
114
- for row in rows:
115
- f.write(json.dumps(row) + "\n")
116
- PY
117
-
118
- run_solver() {
119
- local worktree
120
- worktree="$(cd "$1" && pwd -P)"
121
- local timeout_seconds="$2"
122
- local prompt_file="$worktree/solve-prompt.txt"
123
- local transcript="$worktree/direct-transcript.txt"
124
- local debug_log="$worktree/claude-direct-debug.log"
125
- local timeout_flag="$worktree/.solver-timed-out"
126
-
127
- rm -f "$transcript" "$debug_log" "$timeout_flag"
128
- set +e
129
- set -m
130
- (
131
- cd "$worktree"
132
- exec claude \
133
- -p "$(cat "$prompt_file")" \
134
- --dangerously-skip-permissions \
135
- --effort xhigh \
136
- --strict-mcp-config \
137
- --mcp-config '{"mcpServers":{}}' \
138
- --debug-file "$debug_log" \
139
- </dev/null
140
- ) > "$transcript" 2>&1 &
141
- local child_pid=$!
142
- set +m
143
-
144
- (
145
- sleep "$timeout_seconds"
146
- if kill -0 "$child_pid" 2>/dev/null; then
147
- : > "$timeout_flag"
148
- kill -TERM -- "-$child_pid" 2>/dev/null
149
- sleep 5
150
- kill -KILL -- "-$child_pid" 2>/dev/null
151
- fi
152
- ) &
153
- local watchdog_pid=$!
154
-
155
- wait "$child_pid"
156
- local invoke_exit=$?
157
- kill -TERM "$watchdog_pid" 2>/dev/null || true
158
- wait "$watchdog_pid" 2>/dev/null || true
159
-
160
- if [ -f "$timeout_flag" ]; then
161
- rm -f "$timeout_flag"
162
- invoke_exit=124
163
- fi
164
- set -e
165
- return "$invoke_exit"
166
- }
167
-
168
- write_patch() {
169
- local worktree
170
- worktree="$(cd "$1" && pwd -P)"
171
- (
172
- cd "$worktree"
173
- git add -N -- . \
174
- ':(exclude).claude/**' \
175
- ':(exclude)CLAUDE.md' \
176
- ':(exclude)benchmark/**' \
177
- ':(exclude)docs/roadmap/phase-1/*.md' \
178
- ':(exclude)solve-prompt.txt' \
179
- ':(exclude)direct-transcript.txt' \
180
- ':(exclude)claude-direct-debug.log' \
181
- ':(exclude)latest' \
182
- ':(exclude).solver-timed-out' >/dev/null 2>&1 || true
183
- git diff --binary -- . \
184
- ':(exclude).claude/**' \
185
- ':(exclude)CLAUDE.md' \
186
- ':(exclude)benchmark/**' \
187
- ':(exclude)docs/roadmap/phase-1/*.md' \
188
- ':(exclude)solve-prompt.txt' \
189
- ':(exclude)direct-transcript.txt' \
190
- ':(exclude)claude-direct-debug.log' \
191
- ':(exclude)latest' \
192
- ':(exclude).solver-timed-out' > patch.diff
193
- )
194
- }
195
-
196
- while IFS= read -r instance_id; do
197
- [ -n "$instance_id" ] || continue
198
- worktree="$WORKTREES_ROOT/$instance_id"
199
- if [ "$RESUME" -eq 1 ] && [ -s "$worktree/patch.diff" ]; then
200
- echo "[swebench-solver] skip existing patch: $instance_id"
201
- continue
202
- fi
203
-
204
- echo "[swebench-solver] prepare: $instance_id"
205
- prepare_cmd=(
206
- python3 "$SCRIPT_DIR/prepare-swebench-solver-worktree.py"
207
- --instances-jsonl "$INSTANCES_JSONL"
208
- --instance-id "$instance_id"
209
- --repos-root "$REPOS_ROOT"
210
- --worktrees-root "$WORKTREES_ROOT"
211
- )
212
- if [ "$COPY_DEVLYN_CONTEXT" -eq 1 ]; then
213
- prepare_cmd+=(--copy-devlyn-context)
214
- fi
215
- "${prepare_cmd[@]}" > "$worktree.prepare.json"
216
-
217
- echo "[swebench-solver] solve: $instance_id"
218
- if run_solver "$worktree" "$TIMEOUT_SECONDS"; then
219
- invoke_exit=0
220
- else
221
- invoke_exit=$?
222
- fi
223
- write_patch "$worktree"
224
- python3 - "$worktree" "$instance_id" "$invoke_exit" <<'PY'
225
- import json
226
- import subprocess
227
- import sys
228
- from pathlib import Path
229
-
230
- worktree = Path(sys.argv[1])
231
- instance_id = sys.argv[2]
232
- invoke_exit = int(sys.argv[3])
233
- patch = worktree / "patch.diff"
234
- stat = subprocess.run(
235
- ["git", "-C", str(worktree), "diff", "--stat", "--", "."],
236
- text=True,
237
- capture_output=True,
238
- check=False,
239
- )
240
- report = {
241
- "instance_id": instance_id,
242
- "invoke_exit": invoke_exit,
243
- "patch_path": str(patch),
244
- "patch_bytes": patch.stat().st_size if patch.exists() else 0,
245
- "diff_stat": stat.stdout.strip(),
246
- }
247
- (worktree / "solver-result.json").write_text(json.dumps(report, indent=2) + "\n", encoding="utf8")
248
- print(json.dumps(report, indent=2))
249
- PY
250
- done < "$TMP_IDS"
251
-
252
- python3 "$SCRIPT_DIR/collect-swebench-predictions.py" \
253
- --patch-root "$WORKTREES_ROOT" \
254
- --instances-jsonl "$TMP_SELECTED_INSTANCES" \
255
- --model-name "$MODEL_NAME" \
256
- --out "$PREDICTIONS_OUT" \
257
- --allow-empty
@@ -1,391 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- ship-gate.py — apply RUBRIC.md ship thresholds to a suite run's summary.json.
4
-
5
- Usage:
6
- ship-gate.py --run-id <ID> # check gates, return 0/1 via exit code
7
- ship-gate.py --run-id <ID> --bless # if PASS, promote summary to baselines/shipped.json
8
-
9
- Exits 0 on PASS, 1 on FAIL.
10
- """
11
- from __future__ import annotations
12
- import argparse, json, pathlib, sys, shutil, datetime
13
-
14
- SCRIPT_DIR = pathlib.Path(__file__).resolve().parent
15
- if str(SCRIPT_DIR) not in sys.path:
16
- sys.path.insert(0, str(SCRIPT_DIR))
17
-
18
- from pair_evidence_contract import reject_json_constant
19
-
20
-
21
- def load_dict_json(path: pathlib.Path) -> tuple[dict | None, str | None]:
22
- try:
23
- data = json.loads(path.read_text(), parse_constant=reject_json_constant)
24
- except (ValueError, json.JSONDecodeError):
25
- return None, "invalid JSON"
26
- if not isinstance(data, dict):
27
- return None, "expected object"
28
- return data, None
29
-
30
-
31
- def object_or_empty(value) -> dict:
32
- return value if isinstance(value, dict) else {}
33
-
34
-
35
- def rows_from_summary(summary: dict, failures: list[str]) -> list[dict]:
36
- raw_rows = summary.get("rows")
37
- if not isinstance(raw_rows, list):
38
- failures.append("summary rows missing or malformed — measurement invalid")
39
- return []
40
- rows = [row for row in raw_rows if isinstance(row, dict)]
41
- if len(rows) != len(raw_rows):
42
- failures.append("summary rows contain non-object entries — measurement invalid")
43
- return rows
44
-
45
-
46
- def int_or_none(value) -> int | None:
47
- return value if isinstance(value, int) and not isinstance(value, bool) else None
48
-
49
-
50
- def number_or_none(value) -> int | float | None:
51
- if isinstance(value, bool):
52
- return None
53
- return value if isinstance(value, (int, float)) else None
54
-
55
-
56
- def bool_or_none(value) -> bool | None:
57
- return value if isinstance(value, bool) else None
58
-
59
-
60
- def axis_invalid_count(rows: list[dict], arm: str, failures: list[str]) -> int:
61
- total = 0
62
- for row in rows:
63
- arms = object_or_empty(row.get("arms"))
64
- payload = object_or_empty(arms.get(arm))
65
- raw_count = payload.get("_axis_validation_out_of_range_count", 0)
66
- count = number_or_none(raw_count)
67
- if count is None:
68
- failures.append(f"{arm} axis count malformed — measurement invalid")
69
- elif count > 0:
70
- total += 1
71
- return total
72
-
73
-
74
- def unmapped_axis_invalid_count(rows: list[dict], failures: list[str]) -> int:
75
- total = 0
76
- for row in rows:
77
- raw_count = row.get("_axis_validation_unmapped_out_of_range_count", 0)
78
- count = number_or_none(raw_count)
79
- if count is None:
80
- failures.append("unmapped axis count malformed — measurement invalid")
81
- elif count > 0:
82
- total += 1
83
- return total
84
-
85
-
86
- def is_known_limit(row: dict) -> bool:
87
- raw_category = row.get("category")
88
- category = raw_category.lower() if isinstance(raw_category, str) else ""
89
- return category in {"edge", "known-limit"}
90
-
91
-
92
- def main() -> int:
93
- p = argparse.ArgumentParser()
94
- p.add_argument("--run-id", required=True)
95
- p.add_argument("--bless", action="store_true")
96
- p.add_argument("--accept-missing", action="store_true",
97
- help="skip hard-floor gates that require fixtures not yet implemented "
98
- "(F9 and the 7-of-9 count) — only for suites in bootstrap")
99
- args = p.parse_args()
100
-
101
- root = pathlib.Path(__file__).resolve().parent.parent
102
- summary_p = root / "results" / args.run_id / "summary.json"
103
- if not summary_p.exists():
104
- print(f"no summary at {summary_p}", file=sys.stderr); return 1
105
- summary, summary_error = load_dict_json(summary_p)
106
- if summary is None:
107
- print(f"measurement invalid: malformed summary.json ({summary_error})", file=sys.stderr)
108
- return 1
109
-
110
- baseline_p = root / "history" / "baselines" / "shipped.json"
111
- baseline = None
112
- if baseline_p.exists():
113
- baseline, _ = load_dict_json(baseline_p)
114
- if baseline is None:
115
- baseline = None
116
-
117
- failures: list[str] = []
118
- warnings: list[str] = []
119
- rows = rows_from_summary(summary, failures)
120
-
121
- # Hard floor 1: no disqualifier in variant
122
- hard_floor_violations = int_or_none(summary.get("hard_floor_violations"))
123
- if hard_floor_violations is None:
124
- failures.append("summary hard_floor_violations missing or malformed — measurement invalid")
125
- elif hard_floor_violations > 0:
126
- failures.append(f"{hard_floor_violations} variant disqualifier(s) — see report")
127
- variant_axis_invalid = axis_invalid_count(rows, "variant", failures)
128
- if variant_axis_invalid > 0:
129
- failures.append(
130
- f"variant axis-invalid: {variant_axis_invalid} fixture(s) have out-of-range axis cells — "
131
- "re-judge before trusting L2 margins"
132
- )
133
- bare_axis_invalid = axis_invalid_count(rows, "bare", failures)
134
- if bare_axis_invalid > 0:
135
- failures.append(
136
- f"bare axis-invalid: {bare_axis_invalid} fixture(s) have out-of-range axis cells — "
137
- "re-judge before trusting margins"
138
- )
139
- unmapped_axis_invalid = unmapped_axis_invalid_count(rows, failures)
140
- if unmapped_axis_invalid > 0:
141
- failures.append(
142
- f"judge axis-invalid unmapped: {unmapped_axis_invalid} fixture(s) have out-of-range axis cells "
143
- "that could not be mapped to an arm — re-judge before trusting margins"
144
- )
145
-
146
- # Hard floor 2: F9 must pass (skipped during bootstrap via --accept-missing)
147
- # Variant arm legacy gate kept for L2 baseline comparability.
148
- # iter-0033a (2026-04-30): renamed F9 dir from -to-preflight to -to-resolve to
149
- # match the shipped 2-skill contract (no preflight). The OLD pre-rename id
150
- # is preserved in fixtures/retired/ for replay.
151
- f9_row = next((r for r in rows if r.get("fixture") == "F9-e2e-ideate-to-resolve"), None)
152
- if f9_row is None:
153
- if not args.accept_missing:
154
- failures.append("F9 (E2E novice flow) missing — add fixture or run with --accept-missing")
155
- else:
156
- f9_margin = number_or_none(f9_row.get("margin"))
157
- if f9_margin is None:
158
- failures.append("F9 (E2E novice flow) margin missing or malformed — measurement invalid")
159
- elif f9_margin < 5:
160
- failures.append("F9 (E2E novice flow) must have variant margin ≥ +5")
161
-
162
- for row in rows:
163
- if not is_known_limit(row):
164
- continue
165
- margin = number_or_none(row.get("margin"))
166
- if margin is not None and (margin < -3 or margin > 3):
167
- warnings.append(
168
- f"{row.get('fixture')} known-limit margin {margin:+g} outside expected [-3,+3] range"
169
- )
170
-
171
- # Hard floor 3: at least 7 gated fixtures with margin ≥ +5
172
- # (skipped during bootstrap via --accept-missing)
173
- gated_fixtures = int_or_none(summary.get("gated_fixtures"))
174
- margin_ge_5_count = int_or_none(summary.get("margin_ge_5_count"))
175
- if gated_fixtures is None or margin_ge_5_count is None:
176
- failures.append("summary gated fixture counts missing or malformed — measurement invalid")
177
- elif gated_fixtures > 0 and margin_ge_5_count < 7:
178
- if not args.accept_missing:
179
- failures.append(
180
- f"only {margin_ge_5_count} of {gated_fixtures} "
181
- f"gated fixtures have variant margin ≥ +5 (need ≥ 7)"
182
- )
183
-
184
- # iter-0023 — L1 (solo_claude) gates per NORTH-STAR.md ops test #1.
185
- # Codex R1 (this iter) caught that ship-gate enforced only legacy L2
186
- # `variant` margin and never read `solo_over_bare`. Now NORTH-STAR's
187
- # documented L1 floor (≥ +5 on at least 7 gated fixtures, F9 ≥ +5, no L1
188
- # disqualifier) is mechanically enforced.
189
- raw_arms_present = summary.get("arms_present")
190
- if raw_arms_present is not None and not isinstance(raw_arms_present, dict):
191
- failures.append("summary arms_present malformed — measurement invalid")
192
- arms_present = object_or_empty(raw_arms_present)
193
- raw_margins_avg = summary.get("margins_avg")
194
- margins_avg = object_or_empty(raw_margins_avg)
195
- raw_solo_present = arms_present.get("solo_claude")
196
- solo_present = bool_or_none(raw_solo_present)
197
- if raw_solo_present is not None and solo_present is None:
198
- failures.append("summary arms_present.solo_claude malformed — measurement invalid")
199
- if solo_present is True:
200
- if raw_margins_avg is not None and not isinstance(raw_margins_avg, dict):
201
- failures.append("summary margins_avg malformed — measurement invalid")
202
- l1_dq_by_fixture: dict[str, bool] = {}
203
- for r in rows:
204
- fixture = str(r.get("fixture"))
205
- l1 = object_or_empty(object_or_empty(r.get("arms")).get("solo_claude"))
206
- raw_l1_dq = l1.get("disqualifier")
207
- parsed_l1_dq = bool_or_none(raw_l1_dq)
208
- if raw_l1_dq is not None and parsed_l1_dq is None:
209
- failures.append(f"{fixture} L1 disqualifier malformed — measurement invalid")
210
- l1_dq_by_fixture[fixture] = True
211
- else:
212
- l1_dq_by_fixture[fixture] = parsed_l1_dq is True
213
-
214
- l1_avg = margins_avg.get("solo_over_bare")
215
- if l1_avg is not None and number_or_none(l1_avg) is None:
216
- failures.append("L1 (solo_over_bare) suite avg malformed — measurement invalid")
217
- elif l1_avg is not None and l1_avg < 5:
218
- warnings.append(
219
- f"L1 (solo_over_bare) suite avg {l1_avg:+.1f} below NORTH-STAR floor +5 "
220
- "(reporting only — per-fixture L1 gates below are decisive)"
221
- )
222
- # F9 L1 floor
223
- if f9_row is not None:
224
- f9_l1 = object_or_empty(f9_row.get("margins")).get("solo_over_bare")
225
- if f9_l1 is None:
226
- if not args.accept_missing:
227
- failures.append("F9 L1 (solo_over_bare) margin missing — measurement invalid")
228
- elif number_or_none(f9_l1) is None:
229
- failures.append("F9 L1 (solo_over_bare) margin malformed — measurement invalid")
230
- elif f9_l1 < 5:
231
- failures.append(f"F9 L1 (solo_over_bare) margin {f9_l1:+g} < +5 floor")
232
- # 7-fixture L1 floor — headroom-aware (added 2026-05-02 per iter-0033 R4
233
- # Codex collab + NORTH-STAR amendment + RUBRIC hard-floor 3 update).
234
- # A fixture is excluded from the denominator when 100 - L0_score < 5
235
- # AND L1_score >= 95 AND the L1 arm has no disqualifier / CRITICAL-HIGH
236
- # finding / watchdog timeout / regression worse than gate #4. Excluded
237
- # fixtures become fixture-rotation candidates if RUBRIC's
238
- # two-shipped-version saturation rule fires.
239
- l1_ge_5 = 0
240
- l1_gated = 0
241
- l1_excluded_headroom = []
242
- for r in rows:
243
- if is_known_limit(r):
244
- continue
245
- arms = object_or_empty(r.get("arms"))
246
- l0 = object_or_empty(arms.get("bare"))
247
- l1 = object_or_empty(arms.get("solo_claude"))
248
- l0_score = number_or_none(l0.get("score"))
249
- l1_score = number_or_none(l1.get("score"))
250
- m = number_or_none(object_or_empty(r.get("margins")).get("solo_over_bare"))
251
- if m is None:
252
- continue
253
- # Headroom carve-out — must satisfy ALL conditions:
254
- # (a) bare ceiling-near (100 - L0 < 5)
255
- # (b) L1 also ceiling-near (>=95)
256
- # (c) L1 arm clean (no disqualifier, no axis-invalid, fix-loop didn't fail)
257
- l1_dq_here = l1_dq_by_fixture.get(str(r.get("fixture")), False)
258
- l1_axis_count = number_or_none(l1.get("_axis_validation_out_of_range_count", 0))
259
- l1_axis_inv = bool(l1_axis_count is not None and l1_axis_count > 0)
260
- if (
261
- l0_score is not None and l1_score is not None
262
- and (100 - l0_score) < 5 and l1_score >= 95
263
- and not l1_dq_here and not l1_axis_inv
264
- ):
265
- l1_excluded_headroom.append({
266
- "fixture": r.get("fixture"),
267
- "l0_score": l0_score,
268
- "l1_score": l1_score,
269
- "margin": m,
270
- })
271
- continue
272
- l1_gated += 1
273
- if m >= 5:
274
- l1_ge_5 += 1
275
- if l1_gated > 0 and l1_ge_5 < 7 and not args.accept_missing:
276
- failures.append(
277
- f"L1: only {l1_ge_5} of {l1_gated} headroom-available fixtures have solo_over_bare ≥ +5 (need ≥ 7)"
278
- )
279
- if l1_excluded_headroom:
280
- warnings.append(
281
- "L1 headroom-excluded (saturation candidates per RUBRIC two-shipped-version rule): "
282
- + ", ".join(
283
- f"{x['fixture']} (L0={x['l0_score']} L1={x['l1_score']} margin={x['margin']:+g})"
284
- for x in l1_excluded_headroom
285
- )
286
- )
287
- # L1 disqualifier floor
288
- l1_dq = sum(
289
- 1 for r in rows
290
- if l1_dq_by_fixture.get(str(r.get("fixture")), False)
291
- )
292
- if l1_dq > 0:
293
- failures.append(f"L1 disqualifier(s): {l1_dq} solo_claude arm(s) hit a disqualifier")
294
- # L1 axis-validity gate (judge.sh records out-of-range axis cells under
295
- # `_axis_validation` per fixture). If any L1 row has invalid axis data,
296
- # the L1 score for that row is not trustworthy.
297
- l1_axis_invalid = 0
298
- for r in rows:
299
- av = object_or_empty(object_or_empty(r.get("arms")).get("solo_claude"))
300
- inv = av.get("_axis_validation_out_of_range_count")
301
- count = number_or_none(inv)
302
- if inv is not None and count is None:
303
- failures.append("L1 axis count malformed — measurement invalid")
304
- elif count is not None and count > 0:
305
- l1_axis_invalid += 1
306
- if l1_axis_invalid > 0:
307
- failures.append(
308
- f"L1 axis-invalid: {l1_axis_invalid} fixture(s) have out-of-range axis cells — "
309
- "re-judge before trusting L1 margins"
310
- )
311
-
312
- # Hard floor 4: no per-fixture regression worse than −5 vs shipped baseline
313
- if baseline:
314
- prev_rows = {
315
- r["fixture"]: r for r in baseline.get("rows", [])
316
- if isinstance(r, dict) and isinstance(r.get("fixture"), str)
317
- }
318
- for r in rows:
319
- if is_known_limit(r):
320
- continue
321
- fid = r.get("fixture")
322
- prev = prev_rows.get(fid)
323
- current_score = number_or_none(r.get("variant_score"))
324
- previous_score = number_or_none(prev.get("variant_score")) if prev else None
325
- if prev and current_score is not None and previous_score is not None:
326
- delta = current_score - previous_score
327
- if delta < -5:
328
- failures.append(f"{fid} regressed {delta:+g} vs shipped (floor: −5)")
329
-
330
- # Soft gate: suite average margin drop > 3
331
- if baseline:
332
- current_margin_avg = number_or_none(summary.get("margin_avg"))
333
- baseline_margin_avg = number_or_none(baseline.get("margin_avg"))
334
- if current_margin_avg is None:
335
- failures.append("suite margin missing — measurement invalid")
336
- elif baseline_margin_avg is None:
337
- warnings.append("shipped baseline margin malformed; skipping suite margin delta")
338
- else:
339
- margin_delta = current_margin_avg - baseline_margin_avg
340
- if margin_delta < -3:
341
- warnings.append(f"suite margin dropped {margin_delta:+.1f} vs shipped (soft gate: > −3)")
342
-
343
- # Soft gate: any fixture that was > +5 before is now ≤ 0
344
- if baseline:
345
- prev_rows = {
346
- r["fixture"]: r for r in baseline.get("rows", [])
347
- if isinstance(r, dict) and isinstance(r.get("fixture"), str)
348
- }
349
- for r in rows:
350
- fid = r.get("fixture")
351
- prev = prev_rows.get(fid)
352
- prev_margin = number_or_none(prev.get("margin")) if prev else None
353
- current_margin = number_or_none(r.get("margin"))
354
- if prev and prev_margin is not None and prev_margin > 5:
355
- if current_margin is None:
356
- warnings.append(f"{fid} margin missing; was {prev_margin:+g}")
357
- elif current_margin <= 0:
358
- warnings.append(
359
- f"{fid} lost its margin: was {prev_margin:+g}, now {current_margin:+g}"
360
- )
361
-
362
- verdict = "PASS" if not failures else "FAIL"
363
- print(f"\n═══ SHIP-GATE VERDICT: {verdict} ═══\n")
364
- if failures:
365
- print("Hard-floor failures:")
366
- for f in failures:
367
- print(f" ✗ {f}")
368
- print()
369
- if warnings:
370
- print("Soft-gate warnings:")
371
- for w in warnings:
372
- print(f" ⚠ {w}")
373
- print()
374
- if not failures and not warnings:
375
- print("No gate violations. Suite is ship-ready.")
376
-
377
- # Bless if PASS + --bless — opt-in promotion to shipped baseline.
378
- # Per BENCHMARK-DESIGN.md Karpathy Check, automatic history mutation is
379
- # deferred until after the suite format stabilizes; `--bless` stays as
380
- # the explicit promotion path, and `summary.json` inside the run dir
381
- # is the durable record for ad-hoc inspection.
382
- if verdict == "PASS" and args.bless:
383
- baseline_p.parent.mkdir(parents=True, exist_ok=True)
384
- shutil.copyfile(summary_p, baseline_p)
385
- print(f"\nBlessed: {baseline_p}")
386
-
387
- return 0 if verdict == "PASS" else 1
388
-
389
-
390
- if __name__ == "__main__":
391
- sys.exit(main())