devlyn-cli 3.2.1 → 3.3.1

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 +8 -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 +660 -150
  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 +47 -38
  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,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)