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,493 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- compile-report.py — aggregate one run's fixture artifacts into a summary.
4
-
5
- Usage:
6
- compile-report.py --run-id <ID> [--label <VERSION>]
7
-
8
- Reads: benchmark/auto-resolve/results/<run-id>/<fixture>/{judge.json, variant/result.json, bare/result.json}
9
- Writes:
10
- results/<run-id>/summary.json (machine)
11
- results/<run-id>/report.md (human)
12
-
13
- The report is the output of `npx devlyn-cli benchmark`. Ship-gate.py consumes summary.json.
14
- """
15
- from __future__ import annotations
16
- import argparse, json, pathlib, sys, subprocess, datetime
17
-
18
- SCRIPT_DIR = pathlib.Path(__file__).resolve().parent
19
- if str(SCRIPT_DIR) not in sys.path:
20
- sys.path.insert(0, str(SCRIPT_DIR))
21
-
22
- from pair_evidence_contract import is_score, is_strict_number, loads_strict_json_object
23
-
24
- KNOWN_ARMS = {"variant", "solo_claude", "bare"}
25
- PASS_VERDICTS = {"PASS", "PASS_WITH_ISSUES"}
26
-
27
-
28
- def verify_score_clean(value) -> bool:
29
- return is_strict_number(value) and value >= 1.0
30
-
31
-
32
- def exact_bool(value):
33
- if value is True or value is False:
34
- return value
35
- if value is None:
36
- return False
37
- return None
38
-
39
-
40
- def skill_verdict_clean(result: dict, arm: str) -> bool:
41
- if arm == "bare":
42
- return True
43
- return (
44
- result.get("terminal_verdict") in PASS_VERDICTS
45
- and result.get("verify_verdict") in PASS_VERDICTS
46
- )
47
-
48
-
49
- def utc_now_iso() -> str:
50
- return datetime.datetime.now(datetime.UTC).isoformat(timespec="seconds").replace("+00:00", "Z")
51
-
52
-
53
- def load_dict_json(path: pathlib.Path) -> dict:
54
- if not path.exists():
55
- return {}
56
- try:
57
- data = loads_strict_json_object(path.read_text())
58
- except (ValueError, json.JSONDecodeError):
59
- return {}
60
- return data
61
-
62
-
63
- def git_sha() -> str:
64
- try:
65
- return subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip()
66
- except Exception:
67
- return "unknown"
68
-
69
-
70
- def git_branch() -> str:
71
- try:
72
- return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"], text=True).strip()
73
- except Exception:
74
- return "unknown"
75
-
76
-
77
- def axis_validation_breakdown(judge: dict):
78
- raw_validation = judge.get("_axis_validation")
79
- validation = raw_validation if isinstance(raw_validation, dict) else {}
80
- cells = validation.get("out_of_range_cells") or []
81
- declared_count = validation.get("out_of_range_count")
82
- total_invalid = max(
83
- declared_count if isinstance(declared_count, int) else 0,
84
- len(cells) if isinstance(cells, list) else 0,
85
- )
86
- raw_blind_mapping = judge.get("_blind_mapping")
87
- blind_mapping = raw_blind_mapping if isinstance(raw_blind_mapping, dict) else {}
88
- breakdown_to_letter = {
89
- "a_breakdown": "A",
90
- "b_breakdown": "B",
91
- "c_breakdown": "C",
92
- }
93
- by_arm = {}
94
- mapped_count = 0
95
- unmapped_cells = []
96
- if not isinstance(cells, list):
97
- return by_arm, total_invalid, [{"reason": "out_of_range_cells is not a list"}]
98
- for cell in cells:
99
- if not isinstance(cell, dict):
100
- unmapped_cells.append(cell)
101
- continue
102
- letter = breakdown_to_letter.get(cell.get("breakdown"))
103
- arm = blind_mapping.get(letter) if letter else None
104
- if arm in KNOWN_ARMS:
105
- by_arm.setdefault(arm, []).append(cell)
106
- mapped_count += 1
107
- else:
108
- unmapped_cells.append(cell)
109
- unmapped_count = max(0, total_invalid - mapped_count)
110
- if unmapped_count > len(unmapped_cells):
111
- unmapped_cells.extend(
112
- {"reason": "out_of_range_count exceeds mapped cells"}
113
- for _ in range(unmapped_count - len(unmapped_cells))
114
- )
115
- return by_arm, unmapped_count, unmapped_cells
116
-
117
-
118
- def blind_mapped_arms(judge: dict) -> set[str]:
119
- mapping = judge.get("_blind_mapping")
120
- if not isinstance(mapping, dict):
121
- return set()
122
- return {arm for key, arm in mapping.items() if key in {"A", "B", "C"}}
123
-
124
-
125
- def strict_number(value):
126
- return value if is_strict_number(value) else None
127
-
128
-
129
- def main() -> int:
130
- p = argparse.ArgumentParser()
131
- p.add_argument("--run-id", required=True)
132
- p.add_argument("--label", default=None, help="version label, e.g. v3.6")
133
- args = p.parse_args()
134
-
135
- bench_root = pathlib.Path(__file__).resolve().parent.parent
136
- res_root = bench_root / "results" / args.run_id
137
- if not res_root.is_dir():
138
- print(f"no results dir: {res_root}", file=sys.stderr); return 1
139
-
140
- fixtures = sorted([d.name for d in res_root.iterdir() if d.is_dir()])
141
- rows = []
142
- for fid in fixtures:
143
- fdir = res_root / fid
144
- judge_path = fdir / "judge.json"
145
- if not judge_path.exists():
146
- rows.append({"fixture": fid, "status": "NO_JUDGE", "reason": "judge.json missing"})
147
- continue
148
- judge = load_dict_json(judge_path)
149
- # iter-0019: 3-arm aware. judge.json now carries scores_by_arm /
150
- # findings_by_arm / disqualifiers_by_arm / margins. Older judge.json
151
- # can populate legacy fields, but any score still requires a matching
152
- # _blind_mapping arm before downstream consumers may trust it.
153
- raw_scores_by_arm = judge.get("scores_by_arm")
154
- scores_by_arm = raw_scores_by_arm if isinstance(raw_scores_by_arm, dict) else {}
155
- if not scores_by_arm:
156
- if is_score(judge.get("variant_score")):
157
- scores_by_arm["variant"] = judge["variant_score"]
158
- if is_score(judge.get("bare_score")):
159
- scores_by_arm["bare"] = judge["bare_score"]
160
-
161
- raw_findings_by_arm = judge.get("findings_by_arm")
162
- findings_by_arm = raw_findings_by_arm if isinstance(raw_findings_by_arm, dict) else {}
163
- raw_dq_by_arm = judge.get("disqualifiers_by_arm")
164
- dq_by_arm = raw_dq_by_arm if isinstance(raw_dq_by_arm, dict) else {}
165
- axis_invalid_by_arm, axis_unmapped_count, axis_unmapped_cells = axis_validation_breakdown(judge)
166
- mapped_arms = blind_mapped_arms(judge)
167
- trusted_scores_by_arm = {
168
- arm: score for arm, score in scores_by_arm.items()
169
- if arm in mapped_arms and is_score(score)
170
- }
171
-
172
- arm_results = {}
173
- for arm in ("variant", "solo_claude", "bare"):
174
- res_p = fdir / arm / "result.json"
175
- arm_results[arm] = load_dict_json(res_p)
176
- var_res = arm_results["variant"]
177
- solo_res = arm_results["solo_claude"]
178
- bare_res = arm_results["bare"]
179
-
180
- meta_p = bench_root / "fixtures" / fid / "metadata.json"
181
- category = "unknown"
182
- if meta_p.exists():
183
- try:
184
- category = load_dict_json(meta_p).get("category", "unknown")
185
- except Exception:
186
- pass
187
-
188
- def wall_ratio(numer, denom):
189
- if is_strict_number(numer) and is_strict_number(denom):
190
- return round(numer / denom, 2)
191
- return None
192
-
193
- # Disqualifier flags per arm = OR of deterministic result.json flag and
194
- # judge's subjective flag (from new dq_by_arm map; fall back to legacy
195
- # A/B-letter shape if present).
196
- def arm_dq_judge(arm: str):
197
- if arm in dq_by_arm:
198
- entry = dq_by_arm[arm]
199
- value = entry.get("disqualifier") if isinstance(entry, dict) else entry
200
- parsed = exact_bool(value)
201
- return (parsed is True or parsed is None, parsed is None)
202
- raw_mapping = judge.get("_blind_mapping")
203
- mapping = raw_mapping if isinstance(raw_mapping, dict) else {}
204
- for letter in ("A", "B", "C"):
205
- if mapping.get(letter) == arm:
206
- raw_dqs = judge.get("disqualifiers")
207
- dqs = raw_dqs if isinstance(raw_dqs, dict) else {}
208
- parsed = exact_bool(dqs.get(letter))
209
- return (parsed is True or parsed is None, parsed is None)
210
- return False, False
211
-
212
- def critical_findings_for(arm: str):
213
- entry = findings_by_arm.get(arm)
214
- if isinstance(entry, list):
215
- return entry
216
- if entry:
217
- return [entry]
218
- return []
219
-
220
- # Per-arm payload — arm absent = scores_by_arm key absent, downstream
221
- # consumers null-check.
222
- arms_block = {}
223
- for arm in ("variant", "solo_claude", "bare"):
224
- r = arm_results.get(arm) or {}
225
- raw_score = scores_by_arm.get(arm)
226
- score = trusted_scores_by_arm.get(arm)
227
- blind_mapping_arm_missing = raw_score is not None and arm not in mapped_arms
228
- judge_dq, judge_dq_malformed = arm_dq_judge(arm)
229
- result_bool_values = {
230
- field: exact_bool(r.get(field))
231
- for field in ("disqualifier", "timed_out", "invoke_failure", "environment_contamination")
232
- }
233
- malformed_boolean_fields = [
234
- field for field, value in result_bool_values.items() if value is None
235
- ]
236
- det_dq = bool(
237
- result_bool_values["disqualifier"] is True
238
- or result_bool_values["timed_out"] is True
239
- or result_bool_values["invoke_failure"] is True
240
- or result_bool_values["environment_contamination"] is True
241
- or bool(malformed_boolean_fields)
242
- or not verify_score_clean(r.get("verify_score"))
243
- or not skill_verdict_clean(r, arm)
244
- or blind_mapping_arm_missing
245
- )
246
- arms_block[arm] = {
247
- "score": score,
248
- "wall_s": strict_number(r.get("elapsed_seconds")),
249
- "verify_score": strict_number(r.get("verify_score")),
250
- "files_changed": r.get("files_changed"),
251
- "timed_out": result_bool_values["timed_out"] is True,
252
- "invoke_failure": result_bool_values["invoke_failure"] is True,
253
- "invoke_failure_reason": r.get("invoke_failure_reason"),
254
- "environment_contamination": result_bool_values["environment_contamination"] is True,
255
- "disqualifier": judge_dq or det_dq,
256
- "dq_judge": judge_dq,
257
- "dq_judge_malformed": judge_dq_malformed,
258
- "dq_deterministic": det_dq,
259
- "malformed_boolean_fields": malformed_boolean_fields,
260
- "blind_mapping_arm_missing": blind_mapping_arm_missing,
261
- "critical_findings": critical_findings_for(arm),
262
- "_axis_validation_out_of_range_count": len(axis_invalid_by_arm.get(arm, [])),
263
- "_axis_validation_out_of_range_cells": axis_invalid_by_arm.get(arm, []),
264
- }
265
-
266
- # Pairwise margins are derived from trusted mapped scores only. Cached
267
- # judge-side margins are redundant and can be stale if a partial artifact
268
- # is reused.
269
- def m(left, right, key):
270
- if left not in mapped_arms or right not in mapped_arms:
271
- return None
272
- l = trusted_scores_by_arm.get(left); r2 = trusted_scores_by_arm.get(right)
273
- if l is None or r2 is None:
274
- return None
275
- return l - r2
276
-
277
- def trusted_winner():
278
- winner = judge.get("winner_arm")
279
- if winner == "tie":
280
- return winner
281
- if winner in trusted_scores_by_arm:
282
- return winner
283
- return None
284
-
285
- row = {
286
- "fixture": fid,
287
- "category": category,
288
- "arms": arms_block,
289
- # Pairwise margins (positive = first arm beat second).
290
- "margins": {
291
- "variant_over_bare": m("variant", "bare", "variant_over_bare"),
292
- "solo_over_bare": m("solo_claude", "bare", "solo_over_bare"),
293
- "variant_over_solo": m("variant", "solo_claude", "variant_over_solo"),
294
- },
295
- # Wall ratios per pairwise comparison (NORTH-STAR.md tests #2/#7
296
- # generalized): each layer must beat previous-layer-best-of-N.
297
- "wall_ratios": {
298
- "variant_over_bare": wall_ratio(arms_block["variant"]["wall_s"], arms_block["bare"]["wall_s"]),
299
- "solo_over_bare": wall_ratio(arms_block["solo_claude"]["wall_s"], arms_block["bare"]["wall_s"]),
300
- "variant_over_solo": wall_ratio(arms_block["variant"]["wall_s"], arms_block["solo_claude"]["wall_s"]),
301
- },
302
- "winner": trusted_winner(),
303
- "_axis_validation_unmapped_out_of_range_count": axis_unmapped_count,
304
- "_axis_validation_unmapped_out_of_range_cells": axis_unmapped_cells,
305
- # Legacy fields preserved so older summary readers still parse.
306
- "variant_score": arms_block["variant"]["score"],
307
- "bare_score": arms_block["bare"]["score"],
308
- "margin": m("variant", "bare", "variant_over_bare"),
309
- "variant_disqualifier": arms_block["variant"]["disqualifier"],
310
- "variant_dq_judge": arms_block["variant"]["dq_judge"],
311
- "variant_dq_deterministic": arms_block["variant"]["dq_deterministic"],
312
- "variant_wall_s": arms_block["variant"]["wall_s"],
313
- "bare_wall_s": arms_block["bare"]["wall_s"],
314
- "wall_ratio_variant_over_bare": wall_ratio(
315
- arms_block["variant"]["wall_s"], arms_block["bare"]["wall_s"]),
316
- "variant_verify_score": arms_block["variant"]["verify_score"],
317
- "bare_verify_score": arms_block["bare"]["verify_score"],
318
- "variant_files_changed": arms_block["variant"]["files_changed"],
319
- "bare_files_changed": arms_block["bare"]["files_changed"],
320
- "critical_findings_variant": arms_block["variant"]["critical_findings"],
321
- "critical_findings_bare": arms_block["bare"]["critical_findings"],
322
- }
323
- rows.append(row)
324
-
325
- # Aggregate
326
- scored = [r for r in rows if r.get("variant_score") is not None]
327
- excluded_known_limit = [r for r in scored if r.get("category") == "edge"] # F8 and similar
328
- gated_rows = [r for r in scored if r.get("category") != "edge"]
329
-
330
- def avg(values):
331
- vals = [v for v in values if v is not None]
332
- return round(sum(vals) / len(vals), 1) if vals else None
333
-
334
- # iter-0019: per-arm averages (whichever arms ran).
335
- arm_avg = {}
336
- for arm in ("variant", "solo_claude", "bare"):
337
- arm_avg[arm] = avg([(r.get("arms", {}).get(arm) or {}).get("score") for r in scored])
338
-
339
- # Pairwise margin averages (positive = first arm wins on average).
340
- def margin_avg(key):
341
- return avg([(r.get("margins") or {}).get(key) for r in scored])
342
-
343
- margins_avg = {
344
- "variant_over_bare": margin_avg("variant_over_bare"),
345
- "solo_over_bare": margin_avg("solo_over_bare"),
346
- "variant_over_solo": margin_avg("variant_over_solo"),
347
- }
348
- # Pairwise wall-ratio averages.
349
- def wall_avg(key):
350
- return avg([(r.get("wall_ratios") or {}).get(key) for r in scored])
351
-
352
- wall_ratio_avg_by_pair = {
353
- "variant_over_bare": wall_avg("variant_over_bare"),
354
- "solo_over_bare": wall_avg("solo_over_bare"),
355
- "variant_over_solo": wall_avg("variant_over_solo"),
356
- }
357
-
358
- # margin_ge_5_count over the iter-0018-era variant-vs-bare metric,
359
- # because the legacy ship-gate.py reads that. Pair-aware gates get
360
- # added in iter-0021 / 0022 once the data shape stabilizes.
361
- margin_ge_5 = sum(1 for r in gated_rows if (r.get("margin") or 0) >= 5)
362
- disqualifier_count = sum(1 for r in rows if r.get("variant_disqualifier"))
363
-
364
- # arm-presence flags so consumers know whether the iter is 2-arm legacy
365
- # or 3-arm post-iter-0019.
366
- has_solo = any(
367
- (arm := (r.get("arms", {}).get("solo_claude") or {})).get("score") is not None
368
- or arm.get("wall_s") is not None
369
- or bool(arm.get("disqualifier"))
370
- for r in rows
371
- )
372
-
373
- summary = {
374
- "run_id": args.run_id,
375
- "label": args.label,
376
- "git_sha": git_sha(),
377
- "branch": git_branch(),
378
- "completed_at": utc_now_iso(),
379
- "fixtures_total": len(rows),
380
- "fixtures_scored": len(scored),
381
- # Legacy 2-arm fields kept for ship-gate.py + history readers.
382
- "variant_avg": arm_avg.get("variant"),
383
- "bare_avg": arm_avg.get("bare"),
384
- "margin_avg": margins_avg.get("variant_over_bare"),
385
- "hard_floor_violations": disqualifier_count,
386
- "margin_ge_5_count": margin_ge_5,
387
- "gated_fixtures": len(gated_rows),
388
- "known_limit_fixtures": len(excluded_known_limit),
389
- "wall_ratio_variant_over_bare_avg": wall_ratio_avg_by_pair.get("variant_over_bare"),
390
- # iter-0019 — 3-arm aware aggregates.
391
- "arms_present": {"variant": True, "solo_claude": has_solo, "bare": True},
392
- "scores_avg_by_arm": arm_avg,
393
- "margins_avg": margins_avg,
394
- "wall_ratio_avg_by_pair": wall_ratio_avg_by_pair,
395
- "rows": rows,
396
- }
397
- (res_root / "summary.json").write_text(json.dumps(summary, indent=2))
398
-
399
- # Render human-readable report
400
- lines = [
401
- f"# Benchmark Suite Run — {summary['completed_at']}",
402
- "",
403
- f"Run-id: `{args.run_id}`",
404
- f"Label: `{args.label or '(unlabeled)'}`",
405
- f"Branch: `{summary['branch']}`",
406
- f"Git SHA: `{summary['git_sha'][:12]}`",
407
- "",
408
- "| Fixture | Category | variant (L2) | solo_claude (L1) | bare (L0) | variant-bare | solo_claude-bare | variant-solo_claude | Winner | Wall variant/solo_claude/bare | Wall variant/solo_claude | Wall variant/bare |",
409
- "|---------|----------|--------------|------------------|-----------|--------------|-------------------|----------------------|--------|--------------------------------|--------------------------|-------------------|",
410
- ]
411
- for r in rows:
412
- if r.get("variant_score") is None:
413
- lines.append(f"| {r['fixture']} | — | — | — | — | — | — | — | NO_JUDGE | — | — | — |")
414
- continue
415
- arms = r.get("arms", {}) or {}
416
- v = arms.get("variant", {}) or {}
417
- s = arms.get("solo_claude", {}) or {}
418
- b = arms.get("bare", {}) or {}
419
- margins = r.get("margins", {}) or {}
420
- wallr = r.get("wall_ratios", {}) or {}
421
- def fmt_score(arm):
422
- if arm.get("score") is None:
423
- return "—"
424
- tag = " ⚠DQ" if arm.get("disqualifier") else (" ⏱TO" if arm.get("timed_out") else "")
425
- return f"{arm['score']}{tag}"
426
- def fmt_margin(v): return f"{v:+d}" if isinstance(v, int) else "—"
427
- def fmt_wall(arm):
428
- return f"{arm['wall_s']}s" if arm.get("wall_s") else "?"
429
- l2_l0_wall = f"{wallr.get('variant_over_bare'):.1f}x" if wallr.get("variant_over_bare") else "—"
430
- l2_l1_wall = f"{wallr.get('variant_over_solo'):.1f}x" if wallr.get("variant_over_solo") else "—"
431
- wall_triplet = f"{fmt_wall(v)}/{fmt_wall(s)}/{fmt_wall(b)}"
432
- lines.append(
433
- f"| {r['fixture']} | {r['category']} | {fmt_score(v)} | {fmt_score(s)} | {fmt_score(b)} | "
434
- f"{fmt_margin(margins.get('variant_over_bare'))} | {fmt_margin(margins.get('solo_over_bare'))} | "
435
- f"{fmt_margin(margins.get('variant_over_solo'))} | {r.get('winner') or '—'} | "
436
- f"{wall_triplet} | {l2_l1_wall} | {l2_l0_wall} |"
437
- )
438
- def fmt_avg(v): return f"{v:.1f}" if isinstance(v, (int, float)) else "n/a"
439
- def fmt_signed(v): return f"{v:+.1f}" if isinstance(v, (int, float)) else "n/a"
440
- def fmt_ratio(v): return f"{v:.1f}x" if isinstance(v, (int, float)) else "n/a"
441
- margin_avg_val = summary.get("margin_avg")
442
- margin_avg_str = fmt_signed(margin_avg_val)
443
- wall_ratio_str = fmt_ratio(summary.get("wall_ratio_variant_over_bare_avg"))
444
-
445
- lines += [
446
- "",
447
- f"**Suite average variant (L2) score:** {fmt_avg(summary['variant_avg'])}",
448
- ]
449
- if summary.get("arms_present", {}).get("solo_claude"):
450
- lines.append(f"**Suite average solo_claude (L1) score:** {fmt_avg(summary['scores_avg_by_arm'].get('solo_claude'))}")
451
- lines += [
452
- f"**Suite average bare (L0) score:** {fmt_avg(summary['bare_avg'])}",
453
- "",
454
- f"**variant (L2) vs bare (L0) margin avg:** {margin_avg_str} (ship floor: +5, NORTH-STAR preferred: +8)",
455
- ]
456
- if summary.get("arms_present", {}).get("solo_claude"):
457
- ms = summary.get("margins_avg", {}) or {}
458
- ws = summary.get("wall_ratio_avg_by_pair", {}) or {}
459
- lines += [
460
- f"**solo_claude (L1) vs bare (L0) margin avg:** {fmt_signed(ms.get('solo_over_bare'))} (NORTH-STAR L1 contract: ≥+5)",
461
- f"**variant (L2) vs solo_claude (L1) margin avg:** {fmt_signed(ms.get('variant_over_solo'))} (NORTH-STAR L2 contract: ≥+5 on pair-eligible)",
462
- f"**Wall ratio variant (L2) / bare (L0):** {fmt_ratio(ws.get('variant_over_bare'))}",
463
- f"**Wall ratio solo_claude (L1) / bare (L0):** {fmt_ratio(ws.get('solo_over_bare'))}",
464
- f"**Wall ratio variant (L2) / solo_claude (L1):** {fmt_ratio(ws.get('variant_over_solo'))}",
465
- ]
466
- else:
467
- lines.append(f"**Wall ratio variant (L2) / bare (L0) mean:** {wall_ratio_str} (no solo_claude arm in this run)")
468
- lines += [
469
- f"**Hard-floor violations:** {summary['hard_floor_violations']}",
470
- f"**Fixtures with margin ≥ +5:** {summary['margin_ge_5_count']} / {summary['gated_fixtures']} (gate: ≥ 7)",
471
- ]
472
- # Critical findings digest — per-arm sections.
473
- def has_findings(arm):
474
- return bool((arm or {}).get("critical_findings"))
475
- cf_rows = [r for r in rows if any(has_findings((r.get("arms") or {}).get(a)) for a in ("variant", "solo_claude", "bare"))]
476
- if cf_rows:
477
- lines += ["", "## Critical Findings", ""]
478
- for r in cf_rows:
479
- lines.append(f"### {r['fixture']}")
480
- for arm_label, arm_key in [("variant (L2)", "variant"), ("solo_claude (L1)", "solo_claude"), ("bare (L0)", "bare")]:
481
- arm = (r.get("arms") or {}).get(arm_key) or {}
482
- if has_findings(arm):
483
- lines.append(f"**{arm_label}:**")
484
- for f in arm["critical_findings"]:
485
- lines.append(f"- {f}")
486
- lines.append("")
487
- (res_root / "report.md").write_text("\n".join(lines))
488
- print((res_root / "report.md").read_text())
489
- return 0
490
-
491
-
492
- if __name__ == "__main__":
493
- sys.exit(main())
@@ -1,129 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Fetch SWE-bench instances as JSONL without Hugging Face Python deps."""
3
-
4
- from __future__ import annotations
5
-
6
- import argparse
7
- import json
8
- import sys
9
- import urllib.parse
10
- import urllib.request
11
- from pathlib import Path
12
- from typing import Any
13
-
14
- from pair_evidence_contract import reject_json_constant
15
-
16
-
17
- DATASETS = {
18
- "lite": "princeton-nlp/SWE-bench_Lite",
19
- "verified": "princeton-nlp/SWE-bench_Verified",
20
- "full": "princeton-nlp/SWE-bench",
21
- }
22
-
23
-
24
- def fetch_rows(dataset: str, split: str, offset: int, length: int) -> dict[str, Any]:
25
- params = urllib.parse.urlencode(
26
- {
27
- "dataset": dataset,
28
- "config": "default",
29
- "split": split,
30
- "offset": offset,
31
- "length": length,
32
- }
33
- )
34
- url = f"https://datasets-server.huggingface.co/rows?{params}"
35
- with urllib.request.urlopen(url, timeout=60) as response:
36
- return json.load(response, parse_constant=reject_json_constant)
37
-
38
-
39
- def positive_int(value: str) -> int:
40
- try:
41
- parsed = int(value)
42
- except ValueError as exc:
43
- raise argparse.ArgumentTypeError("must be an integer") from exc
44
- if parsed <= 0:
45
- raise argparse.ArgumentTypeError("must be > 0")
46
- return parsed
47
-
48
-
49
- def main() -> int:
50
- parser = argparse.ArgumentParser()
51
- parser.add_argument("--dataset", choices=sorted(DATASETS), default="lite")
52
- parser.add_argument("--dataset-id", help="Override the Hugging Face dataset id.")
53
- parser.add_argument("--split", default="test")
54
- parser.add_argument("--limit", type=positive_int, help="Fetch at most N rows.")
55
- parser.add_argument("--page-size", type=int, default=100)
56
- parser.add_argument("--instance-id", action="append", help="Keep only these instance ids.")
57
- parser.add_argument("--out", required=True, type=Path)
58
- args = parser.parse_args()
59
-
60
- if args.page_size <= 0:
61
- raise ValueError("--page-size must be > 0")
62
- dataset = args.dataset_id or DATASETS[args.dataset]
63
- keep = set(args.instance_id or [])
64
- rows: list[dict[str, Any]] = []
65
- offset = 0
66
- total: int | None = None
67
-
68
- while True:
69
- remaining = args.page_size
70
- if args.limit is not None:
71
- remaining = min(remaining, max(args.limit - len(rows), 0))
72
- if remaining == 0:
73
- break
74
- page = fetch_rows(dataset, args.split, offset, remaining)
75
- if total is None:
76
- total = int(page.get("num_rows_total") or 0)
77
- page_rows = page.get("rows") or []
78
- if not isinstance(page_rows, list):
79
- raise ValueError("fetched page malformed: rows must be a list")
80
- if not page_rows:
81
- break
82
- for row_index, wrapper in enumerate(page_rows, start=1):
83
- if not isinstance(wrapper, dict):
84
- raise ValueError(f"malformed fetched row {row_index}: wrapper must be object")
85
- row = wrapper.get("row")
86
- if not isinstance(row, dict):
87
- raise ValueError(f"malformed fetched row {row_index}: row must be object")
88
- instance_id = row.get("instance_id")
89
- if not isinstance(instance_id, str) or not instance_id:
90
- raise ValueError(f"malformed fetched row {row_index}: instance_id must be a non-empty string")
91
- if keep and instance_id not in keep:
92
- continue
93
- rows.append(row)
94
- if args.limit is not None and len(rows) >= args.limit:
95
- break
96
- offset += len(page_rows)
97
- if offset >= total:
98
- break
99
-
100
- if keep:
101
- found = {row.get("instance_id") for row in rows}
102
- missing = sorted(keep - found)
103
- if missing:
104
- raise ValueError(f"requested instance ids not found in fetched split: {', '.join(missing)}")
105
- args.out.parent.mkdir(parents=True, exist_ok=True)
106
- with args.out.open("w", encoding="utf8") as f:
107
- for row in rows:
108
- f.write(json.dumps(row, ensure_ascii=False) + "\n")
109
- print(
110
- json.dumps(
111
- {
112
- "dataset": dataset,
113
- "split": args.split,
114
- "rows_written": len(rows),
115
- "rows_total": total,
116
- "out": str(args.out),
117
- },
118
- indent=2,
119
- )
120
- )
121
- return 0
122
-
123
-
124
- if __name__ == "__main__":
125
- try:
126
- raise SystemExit(main())
127
- except Exception as exc:
128
- print(f"fetch-swebench-instances: {exc}", file=sys.stderr)
129
- raise SystemExit(1)