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,306 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Build the iter-0033c pair-eligible manifest (Codex R0/R0.5 + R0-infra/R0.5-infra).
3
-
4
- Manifest captures the immutable Gate-3 input to iter-0033c-compare.py:
5
- - which fixtures are pair-eligible (high-value ∪ L1≤L0 ∪ F9-if-iter-0033a-passed)
6
- - what the Gate-3 threshold count is
7
- - sha256 over the canonical document so any post-write tampering is detectable
8
-
9
- Hashing pattern is the pre-stamp form lifted from
10
- benchmark/auto-resolve/scripts/pair-plan-lint.py:81-91 — deep-copy the manifest,
11
- zero out `manifest_sha256`, serialize with `sort_keys=True, separators=(",",":"),
12
- ensure_ascii=False, allow_nan=False`, then sha256 the bytes.
13
-
14
- Inputs (all required):
15
- --c1-summary <path> iter-0033 (C1) summary.json (selection grounds; never a comparison baseline)
16
- --f9-judge <path> iter-0033a F9 judge.json (F9 inclusion proof)
17
- --l1-rerun-summary <path> L1 rerun summary archived for provenance, not selection
18
- --output <path> destination .devlyn/manifests/iter-0033c-pair-eligible.json
19
-
20
- Selection rule (frozen pre-registration, iter-0033c §"Pair-eligible fixture set"):
21
- high_value = {F2, F3, F4, F6, F7}
22
- promoted_by_l1_le_l0 = {f ∈ C1 summary | solo_claude.score ≤ bare.score}
23
- conditional_excluded = {F1, F5} # promoted only if L1≤L0
24
- reporting_only = {F8} # excluded from Gate 3
25
- pair_eligible = high_value ∪ promoted_by_l1_le_l0 ∪ {F9 if iter-0033a passed}
26
- − reporting_only
27
- − conditional_excluded that did not get promoted
28
- − current rejected/ceiling registry
29
- """
30
- import argparse
31
- import copy
32
- import hashlib
33
- import json
34
- import re
35
- import subprocess
36
- import sys
37
- from pathlib import Path
38
-
39
- SCRIPT_DIR = Path(__file__).resolve().parent
40
- if str(SCRIPT_DIR) not in sys.path:
41
- sys.path.insert(0, str(SCRIPT_DIR))
42
-
43
- from pair_evidence_contract import is_score, reject_json_constant
44
-
45
- HIGH_VALUE = ["F2", "F3", "F4", "F6", "F7"]
46
- CONDITIONAL = ["F1", "F5"]
47
- REPORTING_ONLY = ["F8"]
48
- REJECTED_REGISTRY = Path(__file__).with_name("pair-rejected-fixtures.sh")
49
-
50
-
51
- def exact_bool(value: object) -> bool | None:
52
- return value if isinstance(value, bool) else None
53
-
54
-
55
- def disqualifier_flag(value: object, *, default: bool = False) -> bool:
56
- if value is None:
57
- return default
58
- parsed = exact_bool(value)
59
- return parsed if parsed is not None else True
60
-
61
-
62
- def file_sha256(path: Path) -> str:
63
- return hashlib.sha256(path.read_bytes()).hexdigest()
64
-
65
-
66
- def canonical_manifest_sha256(manifest: dict) -> str:
67
- """Pre-stamp hash per pair-plan-lint.py:81-91 — zero out the stamp, then sha256."""
68
- pre = copy.deepcopy(manifest)
69
- pre["manifest_sha256"] = ""
70
- s = json.dumps(
71
- pre,
72
- sort_keys=True,
73
- separators=(",", ":"),
74
- ensure_ascii=False,
75
- allow_nan=False,
76
- )
77
- return hashlib.sha256(s.encode("utf-8")).hexdigest()
78
-
79
-
80
- def fixture_short_id(full: str) -> str:
81
- """'F3-backend-contract-risk' -> 'F3'. Pure prefix; matches existing convention."""
82
- return full.split("-", 1)[0] if "-" in full else full
83
-
84
-
85
- def load_rejected_fixture_reasons(path: Path) -> dict[str, str]:
86
- if not path.is_file():
87
- raise ValueError(f"rejected fixture registry not found: {path}")
88
- rejected: dict[str, str] = {}
89
- current: str | None = None
90
- for line in path.read_text().splitlines():
91
- match = re.match(r"\s*([FS]\d+)-\*\|([FS]\d+)\)", line)
92
- if match and match.group(1) == match.group(2):
93
- current = match.group(1)
94
- continue
95
- reason = re.match(r'\s*echo "([^"]+)"', line)
96
- if current and reason:
97
- rejected[current] = reason.group(1)
98
- current = None
99
- return dict(sorted(rejected.items(), key=lambda item: (item[0][0], int(item[0][1:]))))
100
-
101
-
102
- def load_rejected_short_ids(path: Path) -> list[str]:
103
- return list(load_rejected_fixture_reasons(path))
104
-
105
-
106
- def load_json_object(path: Path, label: str) -> dict:
107
- try:
108
- data = json.loads(path.read_text(), parse_constant=reject_json_constant)
109
- except (ValueError, json.JSONDecodeError) as exc:
110
- raise ValueError(f"{label} malformed: invalid JSON") from exc
111
- if not isinstance(data, dict):
112
- raise ValueError(f"{label} malformed: expected object")
113
- return data
114
-
115
-
116
- def compute_promoted_l1_le_l0(c1_rows: list) -> list:
117
- """Return short fixture IDs (e.g. 'F3') where solo_claude.score ≤ bare.score in C1."""
118
- promoted = []
119
- for row in c1_rows:
120
- if not isinstance(row, dict):
121
- continue
122
- raw_arms = row.get("arms")
123
- arms = raw_arms if isinstance(raw_arms, dict) else {}
124
- raw_solo = arms.get("solo_claude")
125
- raw_bare = arms.get("bare")
126
- solo_arm = raw_solo if isinstance(raw_solo, dict) else {}
127
- bare_arm = raw_bare if isinstance(raw_bare, dict) else {}
128
- if (
129
- disqualifier_flag(solo_arm.get("disqualifier"))
130
- or disqualifier_flag(bare_arm.get("disqualifier"))
131
- ):
132
- continue
133
- solo = solo_arm.get("score")
134
- bare = bare_arm.get("score")
135
- if not is_score(solo) or not is_score(bare):
136
- continue
137
- if solo <= bare:
138
- fixture = row.get("fixture")
139
- if isinstance(fixture, str):
140
- promoted.append(fixture_short_id(fixture))
141
- return promoted
142
-
143
-
144
- def mapped_score(judge: dict, arm: str) -> int | None:
145
- mapping = judge.get("_blind_mapping")
146
- if not isinstance(mapping, dict):
147
- return None
148
- letter = next((slot for slot, mapped in mapping.items() if mapped == arm), None)
149
- if letter is None:
150
- return None
151
- raw_scores = judge.get("scores_by_arm")
152
- scores = raw_scores if isinstance(raw_scores, dict) else {}
153
- score = scores.get(arm)
154
- if is_score(score):
155
- return score
156
- legacy = judge.get(f"{letter.lower()}_score")
157
- return legacy if is_score(legacy) else None
158
-
159
-
160
- def mapped_disqualifier(judge: dict, arm: str) -> bool:
161
- mapping = judge.get("_blind_mapping")
162
- if not isinstance(mapping, dict):
163
- return True
164
- letter = next((slot for slot, mapped in mapping.items() if mapped == arm), None)
165
- if letter is None:
166
- return True
167
- raw_by_arm = judge.get("disqualifiers_by_arm")
168
- if raw_by_arm is not None and not isinstance(raw_by_arm, dict):
169
- return True
170
- by_arm = raw_by_arm if isinstance(raw_by_arm, dict) else {}
171
- if arm in by_arm:
172
- entry = by_arm.get(arm)
173
- return disqualifier_flag(
174
- entry.get("disqualifier") if isinstance(entry, dict) else entry
175
- )
176
- raw_legacy = judge.get("disqualifiers")
177
- if raw_legacy is not None and not isinstance(raw_legacy, dict):
178
- return True
179
- legacy = raw_legacy if isinstance(raw_legacy, dict) else {}
180
- return disqualifier_flag(legacy.get(letter))
181
-
182
-
183
- def f9_passed(f9_judge: dict) -> bool:
184
- """iter-0033a passed iff solo_claude beats bare and solo is not disqualified."""
185
- solo = mapped_score(f9_judge, "solo_claude")
186
- bare = mapped_score(f9_judge, "bare")
187
- if solo is None or bare is None:
188
- return False
189
- return solo > bare and not mapped_disqualifier(f9_judge, "solo_claude")
190
-
191
-
192
- def head_sha() -> str:
193
- try:
194
- out = subprocess.check_output(
195
- ["git", "rev-parse", "HEAD"], stderr=subprocess.DEVNULL
196
- )
197
- return out.decode().strip()
198
- except Exception:
199
- return ""
200
-
201
-
202
- def main() -> int:
203
- ap = argparse.ArgumentParser()
204
- ap.add_argument("--c1-summary", required=True)
205
- ap.add_argument("--f9-judge", required=True)
206
- ap.add_argument("--l1-rerun-summary", required=True)
207
- ap.add_argument("--output", required=True)
208
- args = ap.parse_args()
209
-
210
- c1_path = Path(args.c1_summary)
211
- f9_path = Path(args.f9_judge)
212
- l1_path = Path(args.l1_rerun_summary)
213
- out_path = Path(args.output)
214
-
215
- for p, label in [(c1_path, "c1-summary"), (f9_path, "f9-judge"), (l1_path, "l1-rerun-summary")]:
216
- if not p.is_file():
217
- print(f"error: {label} not found: {p}", file=sys.stderr)
218
- return 2
219
-
220
- try:
221
- c1 = load_json_object(c1_path, "c1-summary")
222
- f9 = load_json_object(f9_path, "f9-judge")
223
- rejected_reasons = load_rejected_fixture_reasons(REJECTED_REGISTRY)
224
- rejected_short_ids = list(rejected_reasons)
225
- except ValueError as exc:
226
- print(f"error: {exc}", file=sys.stderr)
227
- return 2
228
-
229
- c1_rows = c1.get("rows")
230
- if not isinstance(c1_rows, list):
231
- print("error: c1-summary malformed: rows must be an array", file=sys.stderr)
232
- return 2
233
-
234
- promoted = compute_promoted_l1_le_l0(c1_rows)
235
- f9_in = f9_passed(f9)
236
-
237
- pair_eligible = list(HIGH_VALUE) # frozen high-value list, ordered
238
- for fx in promoted:
239
- if fx not in pair_eligible and fx not in REPORTING_ONLY:
240
- pair_eligible.append(fx)
241
- if f9_in and "F9" not in pair_eligible:
242
- pair_eligible.append("F9")
243
- pair_eligible = [fx for fx in pair_eligible if fx not in REPORTING_ONLY]
244
- rejected_excluded = sorted(
245
- {fx for fx in pair_eligible if fx in rejected_short_ids},
246
- key=lambda s: (s[0], int(s[1:])),
247
- )
248
- pair_eligible = [fx for fx in pair_eligible if fx not in rejected_short_ids]
249
-
250
- conditional_promoted = [fx for fx in CONDITIONAL if fx in promoted]
251
- conditional_excluded = [fx for fx in CONDITIONAL if fx not in promoted]
252
- pair_eligible_sorted = sorted(pair_eligible, key=lambda s: (s[0], int(s[1:])))
253
- if not pair_eligible_sorted:
254
- rejected_text = ", ".join(rejected_excluded) if rejected_excluded else "none"
255
- print(
256
- "error: no pair-eligible fixtures remain after rejected-registry filtering "
257
- f"(rejected_excluded={rejected_text})",
258
- file=sys.stderr,
259
- )
260
- return 1
261
-
262
- gate3_total = len(pair_eligible_sorted)
263
- gate3_threshold = (gate3_total + 1) // 2 # ≥50% — ceil(gate3_total / 2)
264
-
265
- manifest = {
266
- "schema_version": "1.0",
267
- "iter": "0033c",
268
- "head": head_sha(),
269
- "sources": {
270
- "c1_summary": {"path": str(c1_path), "sha256": file_sha256(c1_path)},
271
- "f9_judge": {"path": str(f9_path), "sha256": file_sha256(f9_path)},
272
- "l1_rerun_summary": {"path": str(l1_path), "sha256": file_sha256(l1_path)},
273
- },
274
- "selection_rule": {
275
- "high_value": HIGH_VALUE,
276
- "promoted_by_l1_le_l0": sorted(set(promoted)),
277
- "f9_included": f9_in,
278
- "f9_passed_iter_0033a": f9_in,
279
- "reporting_only": REPORTING_ONLY,
280
- "conditional_excluded": conditional_excluded,
281
- "conditional_promoted": conditional_promoted,
282
- "rejected_registry": str(REJECTED_REGISTRY),
283
- "rejected_excluded": rejected_excluded,
284
- "rejected_excluded_reasons": {
285
- fixture: rejected_reasons[fixture] for fixture in rejected_excluded
286
- },
287
- },
288
- "fixtures_pair_eligible": pair_eligible_sorted,
289
- "gate3_threshold_count": gate3_threshold,
290
- "gate3_total": gate3_total,
291
- "manifest_sha256": "",
292
- }
293
- manifest["manifest_sha256"] = canonical_manifest_sha256(manifest)
294
-
295
- out_path.parent.mkdir(parents=True, exist_ok=True)
296
- out_path.write_text(json.dumps(manifest, indent=2) + "\n")
297
-
298
- print(f"[manifest] wrote {out_path}")
299
- print(f"[manifest] pair-eligible: {pair_eligible_sorted} "
300
- f"(gate3 ≥ {gate3_threshold} / {gate3_total})")
301
- print(f"[manifest] sha256: {manifest['manifest_sha256']}")
302
- return 0
303
-
304
-
305
- if __name__ == "__main__":
306
- sys.exit(main())
@@ -1,268 +0,0 @@
1
- #!/usr/bin/env python3
2
- """F9 skill-driven arm artifact + transcript fingerprint check.
3
-
4
- Out-of-band per Codex R0.5 §B (iter-0033a): expected.json.verification_commands
5
- apply to ALL arms (run-fixture.sh:472), so a `docs/specs/**` check there would
6
- punish bare. This script runs AFTER run-fixture.sh and asserts skill-driven
7
- arms produced the artifacts the 2-skill ideate→resolve chain should emit.
8
-
9
- Bare arm is exempt by construction.
10
-
11
- Usage:
12
- check-f9-artifacts.py --result-dir <results/<run_id>/F9-e2e-ideate-to-resolve/<arm>>
13
-
14
- Exits:
15
- 0 — all checks pass (or bare arm — exempt).
16
- 1 — skill-driven arm but artifact contract violated.
17
- 2 — invalid invocation (missing args, missing dir).
18
-
19
- Emits a small JSON report at <result-dir>/check-f9-artifacts.json.
20
- """
21
- import argparse
22
- import json
23
- import os
24
- import re
25
- import sys
26
- from pathlib import Path
27
-
28
- from pair_evidence_contract import loads_strict_json_object
29
-
30
-
31
- SKILL_DRIVEN_ARMS = {"variant", "solo_claude", "l2_gated", "l2_risk_probes", "l2_forced"}
32
- EXEMPT_ARMS = {"bare"}
33
-
34
- SPEC_DIR_GLOB = "docs/specs/*/spec.md"
35
- SPEC_EXPECTED_GLOB = "docs/specs/*/spec.expected.json"
36
-
37
- # Transcript fingerprint regexes (negative checks only — `claude -p`
38
- # transcript captures only the agent's final reply, not intermediate
39
- # tool calls; positive resolve invocation evidence lives in state).
40
- RE_AUTO_RESOLVE = re.compile(r"/devlyn:auto-resolve\b")
41
- RE_PREFLIGHT = re.compile(r"/devlyn:preflight\b")
42
-
43
-
44
- def _load_json_object(path: Path) -> tuple[dict | None, str | None]:
45
- try:
46
- data = loads_strict_json_object(path.read_text())
47
- except json.JSONDecodeError as exc:
48
- return None, f"{exc.__class__.__name__}: {exc}"
49
- except ValueError as exc:
50
- if str(exc) == "top-level JSON value must be an object":
51
- return None, "expected JSON object"
52
- return None, f"{exc.__class__.__name__}: {exc}"
53
- return data, None
54
-
55
-
56
- def main() -> int:
57
- p = argparse.ArgumentParser(description=__doc__.split("\n", 1)[0])
58
- p.add_argument("--result-dir", required=True,
59
- help="Path to results/<run_id>/<fixture>/<arm>/")
60
- args = p.parse_args()
61
-
62
- result_dir = Path(args.result_dir)
63
- if not result_dir.is_dir():
64
- print(f"error: result dir not found: {result_dir}", file=sys.stderr)
65
- return 2
66
-
67
- arm = result_dir.name
68
- fixture = result_dir.parent.name
69
-
70
- if fixture != "F9-e2e-ideate-to-resolve":
71
- print(f"error: this script is F9-only (got fixture={fixture})", file=sys.stderr)
72
- return 2
73
-
74
- report = {
75
- "fixture": fixture,
76
- "arm": arm,
77
- "checks": [],
78
- "exempt": False,
79
- "pass": True,
80
- }
81
-
82
- if arm in EXEMPT_ARMS:
83
- report["exempt"] = True
84
- report["checks"].append({"name": "arm-is-bare-exempt", "pass": True})
85
- _write_report(result_dir, report)
86
- return 0
87
-
88
- if arm not in SKILL_DRIVEN_ARMS:
89
- print(f"error: unknown arm '{arm}' (expected one of {SKILL_DRIVEN_ARMS | EXEMPT_ARMS})",
90
- file=sys.stderr)
91
- return 2
92
-
93
- # The fixture's work-dir is referenced from result_dir/timing.json. The
94
- # arm produced files inside that work-dir; we glob from there.
95
- timing_path = result_dir / "timing.json"
96
- work_dir: Path
97
- if timing_path.is_file():
98
- timing, _timing_error = _load_json_object(timing_path)
99
- if timing is not None:
100
- work_dir = Path(timing.get("work_dir", ""))
101
- else:
102
- work_dir = Path("__invalid_timing_work_dir__")
103
- else:
104
- work_dir = Path("__missing_timing_work_dir__")
105
-
106
- if not work_dir.is_dir():
107
- report["checks"].append({
108
- "name": "work-dir-resolvable",
109
- "pass": False,
110
- "reason": f"work_dir from timing.json not usable: {work_dir!r}",
111
- })
112
- report["pass"] = False
113
- _write_report(result_dir, report)
114
- return 1
115
-
116
- # Check 1: docs/specs/<id>-<slug>/spec.md exists.
117
- specs_root = work_dir / "docs" / "specs"
118
- spec_md_files = list(specs_root.glob("*/spec.md")) if specs_root.is_dir() else []
119
- spec_md_present = bool(spec_md_files)
120
- report["checks"].append({
121
- "name": "spec.md-exists-under-docs/specs",
122
- "pass": spec_md_present,
123
- "matched": [str(p.relative_to(work_dir)) for p in spec_md_files],
124
- })
125
- if not spec_md_present:
126
- report["pass"] = False
127
-
128
- # Check 2: spec.expected.json exists at the same dir.
129
- spec_exp_files = list(specs_root.glob("*/spec.expected.json")) if specs_root.is_dir() else []
130
- spec_exp_present = bool(spec_exp_files)
131
- report["checks"].append({
132
- "name": "spec.expected.json-exists-under-docs/specs",
133
- "pass": spec_exp_present,
134
- "matched": [str(p.relative_to(work_dir)) for p in spec_exp_files],
135
- })
136
- if not spec_exp_present:
137
- report["pass"] = False
138
-
139
- # Path-shape regression: the parent dir name should be `<id>-<slug>` shape.
140
- # Both id and slug are kebab-case, so the dir must contain at least one
141
- # hyphen. Bare `<id>/spec.md` (no hyphen) is the legacy shape we reject.
142
- if spec_md_files:
143
- bad_shapes = [p for p in spec_md_files if "-" not in p.parent.name]
144
- report["checks"].append({
145
- "name": "path-shape-id-slug",
146
- "pass": not bad_shapes,
147
- "non_conforming": [str(p.relative_to(work_dir)) for p in bad_shapes],
148
- })
149
- if bad_shapes:
150
- report["pass"] = False
151
-
152
- # Resolve invocation evidence — primary source is pipeline.state.json,
153
- # NOT transcript.txt. `claude -p` only emits the agent's final reply to
154
- # stdout; intermediate Skill / Agent / Bash tool calls do not appear in
155
- # transcript.txt. Therefore "regex /devlyn:resolve --spec in transcript"
156
- # is the wrong source. The authoritative evidence resolve actually ran
157
- # in --spec mode is `state.mode == "spec"` plus `state.source.type ==
158
- # "spec"` plus a populated `state.source.spec_path` pointing under
159
- # `docs/specs/`. Per state-schema.md this is single-source-of-truth.
160
- # Look for the archive first (preferred), then fall back to the live
161
- # in-flight location. NEW resolve currently lands artifacts directly in
162
- # `.devlyn/` and may skip the move-to-runs/ archive step (TODO: separate
163
- # iter to fix archive); both locations carry the same authoritative
164
- # state shape.
165
- archived_paths = list(work_dir.glob(".devlyn/runs/*/pipeline.state.json"))
166
- live_path = work_dir / ".devlyn" / "pipeline.state.json"
167
- state_paths = archived_paths if archived_paths else (
168
- [live_path] if live_path.is_file() else []
169
- )
170
- if not state_paths:
171
- report["checks"].append({
172
- "name": "pipeline.state.json-present",
173
- "pass": False,
174
- "reason": "neither .devlyn/runs/*/pipeline.state.json nor .devlyn/pipeline.state.json found in work_dir",
175
- })
176
- report["pass"] = False
177
- else:
178
- # Read the most recent run.
179
- state_path = sorted(state_paths)[-1]
180
- state, state_error = _load_json_object(state_path)
181
- if state is None:
182
- report["checks"].append({
183
- "name": "pipeline.state.json-parses",
184
- "pass": False,
185
- "reason": state_error,
186
- })
187
- report["pass"] = False
188
-
189
- if state is not None:
190
- archived = "/runs/" in str(state_path)
191
- report["checks"].append({
192
- "name": "pipeline.state.json-present",
193
- "pass": True,
194
- "path": str(state_path.relative_to(work_dir)),
195
- "archived_to_runs_dir": archived,
196
- })
197
- if not archived:
198
- # Not a fail — note for harness developer that NEW resolve
199
- # is skipping the archive step in this run.
200
- report["checks"].append({
201
- "name": "archive-step-completed",
202
- "pass": True,
203
- "warning": "NEW resolve left artifacts in .devlyn/ instead of .devlyn/runs/<id>/ — archive step skipped (separate iter for harness fix)",
204
- })
205
- mode = state.get("mode")
206
- src_type = (state.get("source") or {}).get("type")
207
- spec_path = (state.get("source") or {}).get("spec_path") or ""
208
- spec_under_specs = spec_path.startswith("docs/specs/") and spec_path.endswith("spec.md")
209
- mode_ok = mode == "spec"
210
- src_ok = src_type == "spec"
211
- report["checks"].append({
212
- "name": "state.mode-and-source-spec",
213
- "pass": mode_ok and src_ok and spec_under_specs,
214
- "mode": mode,
215
- "source.type": src_type,
216
- "source.spec_path": spec_path,
217
- })
218
- if not (mode_ok and src_ok and spec_under_specs):
219
- report["pass"] = False
220
-
221
- # Transcript fingerprint — negative checks only. transcript.txt records
222
- # the agent's final reply; if the agent (or any subagent) had invoked
223
- # /devlyn:auto-resolve or /devlyn:preflight, the prompt-following gate
224
- # should still surface the name in the summary. Positive resolve
225
- # evidence lives in state above; here we just rule out the deprecated
226
- # 3-skill chain names.
227
- transcript_path = result_dir / "transcript.txt"
228
- if not transcript_path.is_file():
229
- report["checks"].append({
230
- "name": "transcript-readable",
231
- "pass": False,
232
- "reason": f"transcript.txt missing at {transcript_path}",
233
- })
234
- report["pass"] = False
235
- _write_report(result_dir, report)
236
- return 1
237
-
238
- transcript = transcript_path.read_text(errors="replace")
239
-
240
- auto_resolve_hits = RE_AUTO_RESOLVE.findall(transcript)
241
- report["checks"].append({
242
- "name": "transcript-no-auto-resolve",
243
- "pass": len(auto_resolve_hits) == 0,
244
- "count": len(auto_resolve_hits),
245
- })
246
- if auto_resolve_hits:
247
- report["pass"] = False
248
-
249
- preflight_hits = RE_PREFLIGHT.findall(transcript)
250
- report["checks"].append({
251
- "name": "transcript-no-preflight",
252
- "pass": len(preflight_hits) == 0,
253
- "count": len(preflight_hits),
254
- })
255
- if preflight_hits:
256
- report["pass"] = False
257
-
258
- _write_report(result_dir, report)
259
- return 0 if report["pass"] else 1
260
-
261
-
262
- def _write_report(result_dir: Path, report: dict) -> None:
263
- out_path = result_dir / "check-f9-artifacts.json"
264
- out_path.write_text(json.dumps(report, indent=2) + "\n")
265
-
266
-
267
- if __name__ == "__main__":
268
- sys.exit(main())
@@ -1,108 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Collect patch.diff files into SWE-bench prediction JSONL."""
3
-
4
- from __future__ import annotations
5
-
6
- import argparse
7
- import json
8
- from pathlib import Path
9
- from typing import Any
10
-
11
- from pair_evidence_contract import reject_json_constant
12
-
13
-
14
- def read_jsonl(path: Path) -> list[dict[str, Any]]:
15
- rows: list[dict[str, Any]] = []
16
- with path.open(encoding="utf8") as f:
17
- for line_no, line in enumerate(f, start=1):
18
- if not line.strip():
19
- continue
20
- value = json.loads(line, parse_constant=reject_json_constant)
21
- if not isinstance(value, dict):
22
- raise ValueError(f"{path}:{line_no}: expected JSON object")
23
- rows.append(value)
24
- return rows
25
-
26
-
27
- def instance_ids_from_jsonl(path: Path | None) -> set[str] | None:
28
- if path is None:
29
- return None
30
- ids: set[str] = set()
31
- for row in read_jsonl(path):
32
- instance_id = row.get("instance_id")
33
- if not isinstance(instance_id, str) or not instance_id:
34
- raise ValueError(f"{path}: row missing non-empty instance_id")
35
- ids.add(instance_id)
36
- return ids
37
-
38
-
39
- def collect_from_root(root: Path, patch_name: str, keep: set[str] | None) -> list[tuple[str, Path]]:
40
- patches: list[tuple[str, Path]] = []
41
- seen: set[str] = set()
42
- for patch_path in sorted(root.glob(f"*/{patch_name}")):
43
- instance_id = patch_path.parent.name
44
- if keep is not None and instance_id not in keep:
45
- continue
46
- seen.add(instance_id)
47
- patches.append((instance_id, patch_path))
48
- if keep is not None:
49
- missing = sorted(keep - seen)
50
- if missing:
51
- raise ValueError(f"missing {patch_name} for instance ids: {', '.join(missing)}")
52
- return patches
53
-
54
-
55
- def main() -> int:
56
- parser = argparse.ArgumentParser()
57
- parser.add_argument("--patch-root", required=True, type=Path)
58
- parser.add_argument("--patch-name", default="patch.diff")
59
- parser.add_argument("--instances-jsonl", type=Path, help="Optional filter/validation set.")
60
- parser.add_argument("--model-name", required=True)
61
- parser.add_argument("--out", required=True, type=Path)
62
- parser.add_argument("--allow-empty", action="store_true")
63
- args = parser.parse_args()
64
-
65
- keep = instance_ids_from_jsonl(args.instances_jsonl)
66
- patches = collect_from_root(args.patch_root, args.patch_name, keep)
67
- if not patches:
68
- raise ValueError(f"no {args.patch_name} files found under {args.patch_root}")
69
-
70
- args.out.parent.mkdir(parents=True, exist_ok=True)
71
- written = 0
72
- skipped_empty: list[str] = []
73
- with args.out.open("w", encoding="utf8") as f:
74
- for instance_id, patch_path in patches:
75
- patch = patch_path.read_text(encoding="utf8")
76
- if not patch.strip():
77
- if args.allow_empty:
78
- skipped_empty.append(instance_id)
79
- continue
80
- raise ValueError(f"empty patch for {instance_id}: {patch_path}")
81
- f.write(
82
- json.dumps(
83
- {
84
- "instance_id": instance_id,
85
- "model_name_or_path": args.model_name,
86
- "model_patch": patch,
87
- }
88
- )
89
- + "\n"
90
- )
91
- written += 1
92
- if written == 0:
93
- raise ValueError("no non-empty patches collected")
94
-
95
- report = {
96
- "patch_root": str(args.patch_root),
97
- "patch_name": args.patch_name,
98
- "model_name_or_path": args.model_name,
99
- "out": str(args.out),
100
- "predictions_written": written,
101
- "empty_skipped": skipped_empty,
102
- }
103
- print(json.dumps(report, indent=2))
104
- return 0
105
-
106
-
107
- if __name__ == "__main__":
108
- raise SystemExit(main())