devlyn-cli 3.2.1 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (423) hide show
  1. package/AGENTS.md +2 -2
  2. package/CLAUDE.md +2 -2
  3. package/README.md +12 -102
  4. package/bin/devlyn.js +13 -225
  5. package/bin/instruction-templates.json +6 -0
  6. package/config/skills/_shared/adapters/grok.md +1 -2
  7. package/config/skills/_shared/archive_run.py +15 -3
  8. package/config/skills/_shared/judge-role-evidence.py +21 -1
  9. package/config/skills/_shared/runtime-principles.md +1 -1
  10. package/config/skills/_shared/spec-verify-check.py +0 -653
  11. package/config/skills/_shared/state-phase-write.py +351 -25
  12. package/config/skills/_shared/task-complete.py +635 -143
  13. package/config/skills/_shared/terminal-claim-check.py +229 -4
  14. package/config/skills/_shared/verify-merge-findings.py +93 -2
  15. package/config/skills/devlyn:ideate/SKILL.md +3 -4
  16. package/config/skills/devlyn:ideate/references/elicitation.md +2 -35
  17. package/config/skills/devlyn:ideate/references/from-spec-mode.md +3 -18
  18. package/config/skills/devlyn:ideate/references/project-mode.md +1 -16
  19. package/config/skills/devlyn:ideate/references/spec-template.md +0 -2
  20. package/config/skills/devlyn:queue/SKILL.md +6 -4
  21. package/config/skills/devlyn:resolve/SKILL.md +16 -25
  22. package/config/skills/devlyn:resolve/references/free-form-mode.md +0 -14
  23. package/config/skills/devlyn:resolve/references/outer-loop.md +1 -1
  24. package/config/skills/devlyn:resolve/references/phases/build-gate.md +1 -1
  25. package/config/skills/devlyn:resolve/references/phases/cleanup.md +3 -3
  26. package/config/skills/devlyn:resolve/references/phases/implement.md +1 -1
  27. package/config/skills/devlyn:resolve/references/phases/probe-derive.md +1 -16
  28. package/config/skills/devlyn:resolve/references/phases/verify.md +4 -9
  29. package/config/skills/devlyn:resolve/references/state-schema.md +9 -7
  30. package/config/skills/devlyn:resolve/references/task-completion.md +46 -37
  31. package/{config/skills → optional-skills}/code-health-standards/SKILL.md +4 -13
  32. package/{config/skills → optional-skills}/code-review-standards/SKILL.md +4 -12
  33. package/{config/skills → optional-skills}/root-cause-analysis/SKILL.md +4 -12
  34. package/{config/skills → optional-skills}/ui-implementation-standards/SKILL.md +4 -14
  35. package/package.json +1 -57
  36. package/benchmark/auto-resolve/BENCHMARK-DESIGN.md +0 -289
  37. package/benchmark/auto-resolve/BENCHMARK-RESULTS.md +0 -341
  38. package/benchmark/auto-resolve/README.md +0 -696
  39. package/benchmark/auto-resolve/RUBRIC.md +0 -177
  40. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/NOTES.md +0 -34
  41. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/expected.json +0 -68
  42. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/metadata.json +0 -10
  43. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/setup.sh +0 -4
  44. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/spec.md +0 -44
  45. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.ko.txt +0 -8
  46. package/benchmark/auto-resolve/fixtures/F1-cli-trivial-flag/task.txt +0 -8
  47. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/NOTES.md +0 -68
  48. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/expected.json +0 -60
  49. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/metadata.json +0 -10
  50. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/setup.sh +0 -17
  51. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/spec.md +0 -51
  52. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/task.txt +0 -9
  53. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/verifiers/invalid.js +0 -29
  54. package/benchmark/auto-resolve/fixtures/F10-persist-write-collision/verifiers/parallel.js +0 -50
  55. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/NOTES.md +0 -75
  56. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/expected.json +0 -52
  57. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/metadata.json +0 -10
  58. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/setup.sh +0 -171
  59. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/spec.md +0 -50
  60. package/benchmark/auto-resolve/fixtures/F11-batch-import-all-or-nothing/task.txt +0 -9
  61. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/NOTES.md +0 -89
  62. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/expected.json +0 -74
  63. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/metadata.json +0 -10
  64. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/setup.sh +0 -251
  65. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/spec.md +0 -57
  66. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/task.txt +0 -13
  67. package/benchmark/auto-resolve/fixtures/F12-webhook-raw-body-signature/verifiers/replay-malformed-body.js +0 -64
  68. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/NOTES.md +0 -104
  69. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/expected.json +0 -46
  70. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/metadata.json +0 -10
  71. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/setup.sh +0 -336
  72. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/spec.md +0 -51
  73. package/benchmark/auto-resolve/fixtures/F15-frozen-diff-race-review/task.txt +0 -9
  74. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/NOTES.md +0 -38
  75. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/expected.json +0 -64
  76. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/metadata.json +0 -10
  77. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/setup.sh +0 -32
  78. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/spec.md +0 -63
  79. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/task.txt +0 -7
  80. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/exact-success.js +0 -54
  81. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/no-hardcoded-pricing.js +0 -47
  82. package/benchmark/auto-resolve/fixtures/F16-cli-quote-tax-rules/verifiers/stock-error.js +0 -45
  83. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/NOTES.md +0 -57
  84. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected-pair-plan-registry.json +0 -170
  85. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/expected.json +0 -84
  86. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/metadata.json +0 -21
  87. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-fail.json +0 -214
  88. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/pair-plan.sample-pass.json +0 -223
  89. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/setup.sh +0 -5
  90. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/spec.md +0 -55
  91. package/benchmark/auto-resolve/fixtures/F2-cli-medium-subcommand/task.txt +0 -14
  92. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/NOTES.md +0 -39
  93. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/expected.json +0 -62
  94. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/metadata.json +0 -10
  95. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/setup.sh +0 -2
  96. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/spec.md +0 -67
  97. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/task.txt +0 -7
  98. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/verifiers/error-order.js +0 -55
  99. package/benchmark/auto-resolve/fixtures/F21-cli-scheduler-priority/verifiers/priority-blocked.js +0 -48
  100. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/NOTES.md +0 -35
  101. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/expected.json +0 -56
  102. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/metadata.json +0 -10
  103. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/setup.sh +0 -2
  104. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/spec.md +0 -64
  105. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/task.txt +0 -7
  106. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/verifiers/conflicting-duplicate.js +0 -34
  107. package/benchmark/auto-resolve/fixtures/F22-cli-ledger-close/verifiers/idempotent-close.js +0 -41
  108. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/NOTES.md +0 -39
  109. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/expected.json +0 -56
  110. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/metadata.json +0 -10
  111. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/setup.sh +0 -2
  112. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/spec.md +0 -76
  113. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/task.txt +0 -7
  114. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/verifiers/priority-rollback.js +0 -64
  115. package/benchmark/auto-resolve/fixtures/F23-cli-fulfillment-wave/verifiers/single-warehouse-fefo.js +0 -66
  116. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/NOTES.md +0 -40
  117. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/expected.json +0 -66
  118. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/metadata.json +0 -10
  119. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/setup.sh +0 -36
  120. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/spec.md +0 -71
  121. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/task.txt +0 -7
  122. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/catalog-source.js +0 -57
  123. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/exact-success.js +0 -63
  124. package/benchmark/auto-resolve/fixtures/F25-cli-cart-promotion-rules/verifiers/stock-error.js +0 -34
  125. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/NOTES.md +0 -31
  126. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/expected.json +0 -68
  127. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/metadata.json +0 -10
  128. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/setup.sh +0 -17
  129. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/spec.md +0 -68
  130. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/task.txt +0 -7
  131. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/conflicting-duplicate.js +0 -29
  132. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/exact-payout.js +0 -58
  133. package/benchmark/auto-resolve/fixtures/F26-cli-payout-ledger-rules/verifiers/rules-source.js +0 -56
  134. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/NOTES.md +0 -35
  135. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected-pair-plan-registry.json +0 -162
  136. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/expected.json +0 -67
  137. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/metadata.json +0 -19
  138. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/setup.sh +0 -4
  139. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/spec.md +0 -55
  140. package/benchmark/auto-resolve/fixtures/F3-backend-contract-risk/task.txt +0 -9
  141. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/NOTES.md +0 -34
  142. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/expected.json +0 -57
  143. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/metadata.json +0 -10
  144. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/setup.sh +0 -2
  145. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/spec.md +0 -67
  146. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/task.txt +0 -7
  147. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/verifiers/duplicate-event-error.js +0 -35
  148. package/benchmark/auto-resolve/fixtures/F31-cli-seat-rebalance/verifiers/priority-transfer-rollback.js +0 -53
  149. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/NOTES.md +0 -38
  150. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/expected.json +0 -57
  151. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/metadata.json +0 -10
  152. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/setup.sh +0 -2
  153. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/spec.md +0 -70
  154. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/task.txt +0 -3
  155. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/verifiers/duplicate-renewal-error.js +0 -42
  156. package/benchmark/auto-resolve/fixtures/F32-cli-subscription-renewal/verifiers/priority-credit-rollback.js +0 -70
  157. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/NOTES.md +0 -47
  158. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/expected.json +0 -57
  159. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/metadata.json +0 -10
  160. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/setup.sh +0 -6
  161. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/spec.md +0 -48
  162. package/benchmark/auto-resolve/fixtures/F4-web-browser-design/task.txt +0 -9
  163. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/NOTES.md +0 -45
  164. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/expected.json +0 -65
  165. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/metadata.json +0 -10
  166. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/setup.sh +0 -55
  167. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/spec.md +0 -48
  168. package/benchmark/auto-resolve/fixtures/F5-fix-loop-red-green/task.txt +0 -7
  169. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/NOTES.md +0 -43
  170. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/expected.json +0 -77
  171. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/metadata.json +0 -10
  172. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/setup.sh +0 -4
  173. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/spec.md +0 -48
  174. package/benchmark/auto-resolve/fixtures/F6-dep-audit-native-module/task.txt +0 -10
  175. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/NOTES.md +0 -57
  176. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/expected.json +0 -76
  177. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/metadata.json +0 -10
  178. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/setup.sh +0 -36
  179. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/spec.md +0 -45
  180. package/benchmark/auto-resolve/fixtures/F7-out-of-scope-trap/task.txt +0 -7
  181. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/NOTES.md +0 -53
  182. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/expected.json +0 -63
  183. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/metadata.json +0 -10
  184. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/setup.sh +0 -4
  185. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/spec.md +0 -48
  186. package/benchmark/auto-resolve/fixtures/F8-known-limit-ambiguous/task.txt +0 -1
  187. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/NOTES.md +0 -105
  188. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/expected.json +0 -74
  189. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/metadata.json +0 -10
  190. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/setup.sh +0 -28
  191. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/spec.md +0 -59
  192. package/benchmark/auto-resolve/fixtures/F9-e2e-ideate-to-resolve/task.txt +0 -5
  193. package/benchmark/auto-resolve/fixtures/SCHEMA.md +0 -188
  194. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/NOTES.md +0 -37
  195. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/RETIRED.md +0 -13
  196. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/expected.json +0 -56
  197. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/metadata.json +0 -10
  198. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/setup.sh +0 -18
  199. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/spec.md +0 -69
  200. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/task.txt +0 -7
  201. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/verifiers/exact-proration.js +0 -48
  202. package/benchmark/auto-resolve/fixtures/retired/F27-cli-subscription-proration/verifiers/rules-source-and-conflict.js +0 -79
  203. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/NOTES.md +0 -54
  204. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/RETIRED.md +0 -7
  205. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/expected.json +0 -67
  206. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/metadata.json +0 -10
  207. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/setup.sh +0 -2
  208. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/spec.md +0 -67
  209. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/task.txt +0 -5
  210. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/policy-precedence.js +0 -72
  211. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/validation-and-immutability.js +0 -43
  212. package/benchmark/auto-resolve/fixtures/retired/F28-cli-return-authorization/verifiers/validation-boundary.js +0 -116
  213. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/NOTES.md +0 -35
  214. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/RETIRED.md +0 -12
  215. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/expected.json +0 -58
  216. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/metadata.json +0 -10
  217. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/setup.sh +0 -2
  218. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/spec.md +0 -73
  219. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/task.txt +0 -17
  220. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/verifiers/mixed-idempotent-settlement.js +0 -53
  221. package/benchmark/auto-resolve/fixtures/retired/F30-cli-credit-hold-settlement/verifiers/rejection-boundaries.js +0 -74
  222. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/NOTES.md +0 -28
  223. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/RETIRED.md +0 -15
  224. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/expected.json +0 -57
  225. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/metadata.json +0 -10
  226. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/setup.sh +0 -50
  227. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/spec.md +0 -59
  228. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/task.txt +0 -9
  229. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/ordered-settlement.js +0 -88
  230. package/benchmark/auto-resolve/fixtures/retired/F34-cli-settle-inflight/verifiers/reject-invalid.js +0 -45
  231. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/NOTES.md +0 -30
  232. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/RETIRED.md +0 -16
  233. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/expected.json +0 -64
  234. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/metadata.json +0 -10
  235. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/setup.sh +0 -21
  236. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/spec.md +0 -58
  237. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/task.txt +0 -9
  238. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/dup-op.js +0 -54
  239. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/priority-apply.js +0 -82
  240. package/benchmark/auto-resolve/fixtures/retired/F35-cli-apply-journal/verifiers/rollback.js +0 -77
  241. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/NOTES.md +0 -99
  242. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/RETIRED.md +0 -18
  243. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/expected.json +0 -64
  244. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/metadata.json +0 -10
  245. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/setup.sh +0 -4
  246. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/spec.md +0 -61
  247. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/task.txt +0 -9
  248. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/correctness-small.js +0 -135
  249. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/scale.js +0 -100
  250. package/benchmark/auto-resolve/fixtures/retired/F36-cli-session-admission/verifiers/validation.js +0 -75
  251. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/NOTES.md +0 -93
  252. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/RETIRED.md +0 -16
  253. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/expected.json +0 -65
  254. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/metadata.json +0 -10
  255. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/setup.sh +0 -18
  256. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/spec.md +0 -66
  257. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/task.txt +0 -9
  258. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/correctness-small.js +0 -84
  259. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/scale.js +0 -184
  260. package/benchmark/auto-resolve/fixtures/retired/F37-cli-rule-lookup/verifiers/validation.js +0 -74
  261. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/NOTES.md +0 -60
  262. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/RETIRED.md +0 -29
  263. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/expected.json +0 -73
  264. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/metadata.json +0 -10
  265. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/setup.sh +0 -28
  266. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/spec.md +0 -58
  267. package/benchmark/auto-resolve/fixtures/retired/F9-e2e-ideate-to-preflight/task.txt +0 -5
  268. package/benchmark/auto-resolve/fixtures/test-repo/README.md +0 -12
  269. package/benchmark/auto-resolve/fixtures/test-repo/bin/cli.js +0 -63
  270. package/benchmark/auto-resolve/fixtures/test-repo/package-lock.json +0 -823
  271. package/benchmark/auto-resolve/fixtures/test-repo/package.json +0 -22
  272. package/benchmark/auto-resolve/fixtures/test-repo/playwright.config.js +0 -17
  273. package/benchmark/auto-resolve/fixtures/test-repo/server/index.js +0 -37
  274. package/benchmark/auto-resolve/fixtures/test-repo/tests/cli.test.js +0 -25
  275. package/benchmark/auto-resolve/fixtures/test-repo/tests/server.test.js +0 -58
  276. package/benchmark/auto-resolve/fixtures/test-repo/web/index.html +0 -37
  277. package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.json +0 -25
  278. package/benchmark/auto-resolve/results/20260507-f10-f11-tier1-full-pipeline/headroom-gate.md +0 -10
  279. package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.json +0 -18
  280. package/benchmark/auto-resolve/results/20260508-f22-exact-error-headroom/headroom-gate.md +0 -9
  281. package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.json +0 -18
  282. package/benchmark/auto-resolve/results/20260508-f26-headroom/headroom-gate.md +0 -9
  283. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F16-cli-quote-tax-rules/l2_risk_probes/result.json +0 -28
  284. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F23-cli-fulfillment-wave/l2_risk_probes/result.json +0 -28
  285. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/F25-cli-cart-promotion-rules/l2_risk_probes/result.json +0 -30
  286. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/full-pipeline-pair-gate.json +0 -82
  287. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/full-pipeline-pair-gate.md +0 -18
  288. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/headroom-gate.json +0 -46
  289. package/benchmark/auto-resolve/results/20260510-f16-f23-f25-combined-proof/headroom-gate.md +0 -17
  290. package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.json +0 -28
  291. package/benchmark/auto-resolve/results/20260511-f12-webhook-headroom/headroom-gate.md +0 -15
  292. package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.json +0 -28
  293. package/benchmark/auto-resolve/results/20260511-f15-concurrency-headroom/headroom-gate.md +0 -15
  294. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/F21-cli-scheduler-priority/l2_risk_probes/result.json +0 -32
  295. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.json +0 -44
  296. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/full-pipeline-pair-gate.md +0 -16
  297. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.json +0 -18
  298. package/benchmark/auto-resolve/results/20260511-f21-current-riskprobes-v1/headroom-gate.md +0 -9
  299. package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.json +0 -28
  300. package/benchmark/auto-resolve/results/20260511-f3-http-error-headroom/headroom-gate.md +0 -15
  301. package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.json +0 -28
  302. package/benchmark/auto-resolve/results/20260512-f2-medium-headroom/headroom-gate.md +0 -15
  303. package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.json +0 -28
  304. package/benchmark/auto-resolve/results/20260512-f31-seat-rebalance-headroom/headroom-gate.md +0 -15
  305. package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.json +0 -28
  306. package/benchmark/auto-resolve/results/20260512-f32-subscription-renewal-headroom/headroom-gate.md +0 -15
  307. package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.json +0 -28
  308. package/benchmark/auto-resolve/results/20260512-f4-web-headroom/headroom-gate.md +0 -15
  309. package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.json +0 -28
  310. package/benchmark/auto-resolve/results/20260512-f5-fixloop-headroom/headroom-gate.md +0 -15
  311. package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.json +0 -28
  312. package/benchmark/auto-resolve/results/20260512-f6-checksum-headroom/headroom-gate.md +0 -15
  313. package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.json +0 -28
  314. package/benchmark/auto-resolve/results/20260512-f7-scope-headroom/headroom-gate.md +0 -15
  315. package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.json +0 -28
  316. package/benchmark/auto-resolve/results/20260512-f9-e2e-headroom/headroom-gate.md +0 -15
  317. package/benchmark/auto-resolve/run-real-benchmark.md +0 -303
  318. package/benchmark/auto-resolve/scripts/audit-headroom-rejections.py +0 -441
  319. package/benchmark/auto-resolve/scripts/audit-pair-evidence.py +0 -1256
  320. package/benchmark/auto-resolve/scripts/build-pair-eligible-manifest.py +0 -306
  321. package/benchmark/auto-resolve/scripts/check-f9-artifacts.py +0 -268
  322. package/benchmark/auto-resolve/scripts/collect-swebench-predictions.py +0 -108
  323. package/benchmark/auto-resolve/scripts/compile-report.py +0 -493
  324. package/benchmark/auto-resolve/scripts/fetch-swebench-instances.py +0 -129
  325. package/benchmark/auto-resolve/scripts/frozen-verify-gate.py +0 -434
  326. package/benchmark/auto-resolve/scripts/full-pipeline-pair-gate.py +0 -612
  327. package/benchmark/auto-resolve/scripts/headroom-gate.py +0 -378
  328. package/benchmark/auto-resolve/scripts/iter-0033c-compare.py +0 -683
  329. package/benchmark/auto-resolve/scripts/iter-0033c-l1-summary.py +0 -97
  330. package/benchmark/auto-resolve/scripts/judge-opus-pass.sh +0 -542
  331. package/benchmark/auto-resolve/scripts/judge.sh +0 -565
  332. package/benchmark/auto-resolve/scripts/oracle-scope-tier-a.py +0 -256
  333. package/benchmark/auto-resolve/scripts/oracle-scope-tier-b.py +0 -287
  334. package/benchmark/auto-resolve/scripts/oracle-test-fidelity.py +0 -328
  335. package/benchmark/auto-resolve/scripts/pair-candidate-frontier.py +0 -469
  336. package/benchmark/auto-resolve/scripts/pair-plan-idgen.py +0 -401
  337. package/benchmark/auto-resolve/scripts/pair-plan-lint.py +0 -475
  338. package/benchmark/auto-resolve/scripts/pair-rejected-fixtures.sh +0 -103
  339. package/benchmark/auto-resolve/scripts/pair_evidence_contract.py +0 -270
  340. package/benchmark/auto-resolve/scripts/prepare-swebench-frozen-case.py +0 -273
  341. package/benchmark/auto-resolve/scripts/prepare-swebench-frozen-corpus.py +0 -148
  342. package/benchmark/auto-resolve/scripts/prepare-swebench-solver-worktree.py +0 -210
  343. package/benchmark/auto-resolve/scripts/recent-benchmark-summary.py +0 -232
  344. package/benchmark/auto-resolve/scripts/run-fixture.sh +0 -1024
  345. package/benchmark/auto-resolve/scripts/run-frozen-verify-pair.sh +0 -683
  346. package/benchmark/auto-resolve/scripts/run-full-pipeline-pair-candidate.sh +0 -458
  347. package/benchmark/auto-resolve/scripts/run-headroom-candidate.sh +0 -336
  348. package/benchmark/auto-resolve/scripts/run-iter-0033c.sh +0 -208
  349. package/benchmark/auto-resolve/scripts/run-suite.sh +0 -251
  350. package/benchmark/auto-resolve/scripts/run-swebench-frozen-corpus.sh +0 -310
  351. package/benchmark/auto-resolve/scripts/run-swebench-solver-batch.sh +0 -257
  352. package/benchmark/auto-resolve/scripts/ship-gate.py +0 -391
  353. package/benchmark/auto-resolve/scripts/solo-ceiling-avoidance.py +0 -53
  354. package/benchmark/auto-resolve/scripts/solo-headroom-hypothesis.py +0 -77
  355. package/benchmark/auto-resolve/scripts/swebench-frozen-matrix.py +0 -478
  356. package/benchmark/auto-resolve/scripts/test-audit-headroom-rejections.sh +0 -288
  357. package/benchmark/auto-resolve/scripts/test-audit-pair-evidence.sh +0 -1672
  358. package/benchmark/auto-resolve/scripts/test-benchmark-arg-parsing.sh +0 -1015
  359. package/benchmark/auto-resolve/scripts/test-build-pair-eligible-manifest.sh +0 -491
  360. package/benchmark/auto-resolve/scripts/test-check-f9-artifacts.sh +0 -91
  361. package/benchmark/auto-resolve/scripts/test-frozen-verify-gate.sh +0 -517
  362. package/benchmark/auto-resolve/scripts/test-full-pipeline-pair-gate.sh +0 -610
  363. package/benchmark/auto-resolve/scripts/test-headroom-gate.sh +0 -401
  364. package/benchmark/auto-resolve/scripts/test-iter-0033c-compare.sh +0 -525
  365. package/benchmark/auto-resolve/scripts/test-iter-0033c-l1-summary.sh +0 -254
  366. package/benchmark/auto-resolve/scripts/test-lint-fixtures.sh +0 -580
  367. package/benchmark/auto-resolve/scripts/test-pair-candidate-frontier.sh +0 -591
  368. package/benchmark/auto-resolve/scripts/test-run-full-pipeline-pair-candidate.sh +0 -497
  369. package/benchmark/auto-resolve/scripts/test-run-headroom-candidate.sh +0 -401
  370. package/benchmark/auto-resolve/scripts/test-run-swebench-solver-batch.sh +0 -111
  371. package/benchmark/auto-resolve/scripts/test-ship-gate.sh +0 -1189
  372. package/benchmark/auto-resolve/scripts/test-swebench-frozen-case.sh +0 -1221
  373. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/NOTES.md +0 -28
  374. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/expected.json +0 -63
  375. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/metadata.json +0 -10
  376. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/setup.sh +0 -3
  377. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/spec.md +0 -47
  378. package/benchmark/auto-resolve/shadow-fixtures/S1-cli-lang-flag/task.txt +0 -1
  379. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/NOTES.md +0 -34
  380. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/expected.json +0 -53
  381. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/metadata.json +0 -10
  382. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/setup.sh +0 -3
  383. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/spec.md +0 -50
  384. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/task.txt +0 -1
  385. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/verifiers/duplicate-order-error.js +0 -27
  386. package/benchmark/auto-resolve/shadow-fixtures/S2-cli-inventory-reservation/verifiers/priority-stock-reservation.js +0 -44
  387. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/NOTES.md +0 -34
  388. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/expected.json +0 -55
  389. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/metadata.json +0 -10
  390. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/setup.sh +0 -3
  391. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/spec.md +0 -52
  392. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/task.txt +0 -1
  393. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/verifiers/duplicate-ticket-error.js +0 -29
  394. package/benchmark/auto-resolve/shadow-fixtures/S3-cli-ticket-assignment/verifiers/priority-agent-assignment.js +0 -48
  395. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/NOTES.md +0 -34
  396. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/expected.json +0 -55
  397. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/metadata.json +0 -10
  398. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/setup.sh +0 -3
  399. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/spec.md +0 -55
  400. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/task.txt +0 -1
  401. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/verifiers/duplicate-return-error.js +0 -43
  402. package/benchmark/auto-resolve/shadow-fixtures/S4-cli-return-routing/verifiers/priority-return-routing.js +0 -70
  403. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/NOTES.md +0 -37
  404. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/expected.json +0 -54
  405. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/metadata.json +0 -10
  406. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/setup.sh +0 -3
  407. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/spec.md +0 -59
  408. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/task.txt +0 -1
  409. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/verifiers/credit-ledger-priority.js +0 -98
  410. package/benchmark/auto-resolve/shadow-fixtures/S5-cli-credit-grant-ledger/verifiers/duplicate-charge-error.js +0 -38
  411. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/NOTES.md +0 -36
  412. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/expected.json +0 -56
  413. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/metadata.json +0 -10
  414. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/setup.sh +0 -3
  415. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/spec.md +0 -59
  416. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/task.txt +0 -1
  417. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/verifiers/duplicate-refund-error.js +0 -41
  418. package/benchmark/auto-resolve/shadow-fixtures/S6-cli-refund-window-ledger/verifiers/priority-refund-ledger.js +0 -65
  419. package/config/skills/_shared/pair-plan-schema.md +0 -298
  420. package/scripts/lint-fixtures.sh +0 -352
  421. package/scripts/lint-shadow-fixtures.sh +0 -58
  422. package/scripts/lint-skills.sh +0 -4265
  423. package/scripts/test-owner-phases.py +0 -238
@@ -1,469 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Report active pair-candidate fixture frontier.
3
-
4
- This is a spending guard for solo<pair work. It answers three questions before
5
- new provider calls:
6
- - which active fixtures are already rejected by measured headroom/design,
7
- - which active fixtures remain pair-candidate eligible,
8
- - which eligible fixtures already have passing full-pipeline pair evidence.
9
- """
10
- from __future__ import annotations
11
-
12
- import argparse
13
- import json
14
- import math
15
- import pathlib
16
- import re
17
- import subprocess
18
- import sys
19
- from typing import Any
20
-
21
- SCRIPT_DIR = pathlib.Path(__file__).resolve().parent
22
- if str(SCRIPT_DIR) not in sys.path:
23
- sys.path.insert(0, str(SCRIPT_DIR))
24
-
25
- from pair_evidence_contract import (
26
- all_known_pair_trigger_reasons,
27
- best_pair_evidence,
28
- has_canonical_pair_trigger_reason,
29
- has_known_pair_trigger_reason,
30
- is_strict_number,
31
- loads_strict_json_object,
32
- normalize_pair_evidence_row,
33
- )
34
-
35
-
36
- def fixture_short(name: str) -> str:
37
- return name.split("-", 1)[0] if "-" in name else name
38
-
39
-
40
- def sort_fixture_key(name: str) -> tuple[int, str]:
41
- short = fixture_short(name)
42
- match = re.fullmatch(r"F(\d+)", short)
43
- return (int(match.group(1)) if match else 10_000, name)
44
-
45
-
46
- def active_fixtures(fixtures_root: pathlib.Path) -> list[str]:
47
- if not fixtures_root.is_dir():
48
- raise ValueError(f"fixtures root missing: {fixtures_root}")
49
- return sorted(
50
- [
51
- path.name
52
- for path in fixtures_root.iterdir()
53
- if path.is_dir() and re.fullmatch(r"F\d+-.+", path.name)
54
- ],
55
- key=sort_fixture_key,
56
- )
57
-
58
-
59
- def registry_short_ids(registry: pathlib.Path) -> set[str]:
60
- if not registry.is_file():
61
- raise ValueError(f"rejected fixture registry missing: {registry}")
62
- rejected: set[str] = set()
63
- for line in registry.read_text().splitlines():
64
- match = re.match(r"\s*([FS]\d+)-\*\|([FS]\d+)\)", line)
65
- if match and match.group(1) == match.group(2):
66
- rejected.add(match.group(1))
67
- if not rejected:
68
- raise ValueError(f"rejected fixture registry has no fixture entries: {registry}")
69
- return rejected
70
-
71
-
72
- def rejected_reason(registry: pathlib.Path, fixture: str) -> str | None:
73
- proc = subprocess.run(
74
- [
75
- "bash",
76
- "-c",
77
- 'source "$1"; rejected_pair_fixture_reason "$2"',
78
- "bash",
79
- str(registry),
80
- fixture,
81
- ],
82
- text=True,
83
- stdout=subprocess.PIPE,
84
- stderr=subprocess.PIPE,
85
- check=False,
86
- )
87
- if proc.returncode == 0:
88
- return proc.stdout.strip()
89
- return None
90
-
91
-
92
- def load_json_object(path: pathlib.Path) -> dict[str, Any]:
93
- try:
94
- data = loads_strict_json_object(path.read_text())
95
- except (OSError, ValueError, json.JSONDecodeError):
96
- raise ValueError(f"pair evidence artifact malformed: {path}") from None
97
- return data
98
-
99
-
100
- def pair_gate_rows(path: pathlib.Path, gate: dict[str, Any]) -> list[dict[str, Any]]:
101
- rows = gate.get("rows")
102
- if not isinstance(rows, list) or not rows:
103
- raise ValueError(f"pair evidence artifact rows malformed: {path}")
104
- if not all(isinstance(row, dict) for row in rows):
105
- raise ValueError(f"pair evidence artifact rows malformed: {path}")
106
- return rows
107
-
108
-
109
- def pair_result_trigger_reasons(
110
- results_root: pathlib.Path,
111
- *,
112
- run_id: str,
113
- fixture: str,
114
- pair_arm: str,
115
- ) -> list[str]:
116
- path = results_root / run_id / fixture / pair_arm / "result.json"
117
- try:
118
- result = loads_strict_json_object(path.read_text())
119
- except (OSError, ValueError, json.JSONDecodeError):
120
- return []
121
- trigger = result.get("pair_trigger")
122
- if not isinstance(trigger, dict):
123
- return []
124
- reasons = trigger.get("reasons")
125
- if not (
126
- isinstance(reasons, list)
127
- and reasons
128
- and all(isinstance(reason, str) for reason in reasons)
129
- and has_known_pair_trigger_reason(reasons)
130
- and all_known_pair_trigger_reasons(reasons)
131
- and has_canonical_pair_trigger_reason(reasons)
132
- ):
133
- return []
134
- return reasons
135
-
136
-
137
- def passing_pair_evidence(
138
- results_root: pathlib.Path,
139
- *,
140
- min_pair_margin: int,
141
- max_pair_solo_wall_ratio: float,
142
- ) -> dict[str, list[dict[str, Any]]]:
143
- evidence: dict[str, list[dict[str, Any]]] = {}
144
- if not results_root.is_dir():
145
- return evidence
146
- for gate_path in sorted(results_root.glob("*/full-pipeline-pair-gate.json")):
147
- gate = load_json_object(gate_path)
148
- if gate.get("verdict") != "PASS":
149
- continue
150
- run_id = str(gate.get("run_id") or gate_path.parent.name)
151
- pair_arm = gate.get("pair_arm")
152
- for row in pair_gate_rows(gate_path, gate):
153
- if row.get("status") != "PASS":
154
- continue
155
- fixture = row.get("fixture")
156
- if not isinstance(fixture, str):
157
- continue
158
- candidate_row = row
159
- if row.get("pair_trigger_reasons") is None and isinstance(pair_arm, str):
160
- reasons = pair_result_trigger_reasons(
161
- results_root,
162
- run_id=run_id,
163
- fixture=fixture,
164
- pair_arm=pair_arm,
165
- )
166
- if reasons:
167
- candidate_row = dict(row)
168
- candidate_row["pair_trigger_reasons"] = reasons
169
- candidate_row["pair_trigger_has_canonical_reason"] = True
170
- evidence_row = normalize_pair_evidence_row(
171
- fixture=fixture,
172
- run_id=run_id,
173
- pair_arm=pair_arm,
174
- row=candidate_row,
175
- )
176
- if evidence_row is None:
177
- continue
178
- pair_margin = evidence_row["pair_margin"]
179
- wall_ratio = evidence_row["pair_solo_wall_ratio"]
180
- if pair_margin < min_pair_margin or wall_ratio > max_pair_solo_wall_ratio:
181
- continue
182
- evidence.setdefault(fixture, []).append(evidence_row)
183
- return evidence
184
-
185
-
186
- def build_report(
187
- *,
188
- fixtures_root: pathlib.Path,
189
- registry: pathlib.Path,
190
- results_root: pathlib.Path,
191
- min_pair_margin: int = 5,
192
- max_pair_solo_wall_ratio: float = 3.0,
193
- ) -> dict[str, Any]:
194
- fixtures = active_fixtures(fixtures_root)
195
- rejected_short = registry_short_ids(registry)
196
- evidence_by_fixture = passing_pair_evidence(
197
- results_root,
198
- min_pair_margin=min_pair_margin,
199
- max_pair_solo_wall_ratio=max_pair_solo_wall_ratio,
200
- )
201
-
202
- rows: list[dict[str, Any]] = []
203
- for fixture in fixtures:
204
- reason = rejected_reason(registry, fixture) if fixture_short(fixture) in rejected_short else None
205
- evidence = evidence_by_fixture.get(fixture, [])
206
- if reason:
207
- status = "rejected"
208
- elif evidence:
209
- status = "pair_evidence_passed"
210
- else:
211
- status = "candidate_unmeasured"
212
- rows.append(
213
- {
214
- "fixture": fixture,
215
- "short_id": fixture_short(fixture),
216
- "status": status,
217
- "rejected_reason": reason,
218
- "passing_pair_evidence": evidence,
219
- }
220
- )
221
-
222
- rejected_total = sum(1 for row in rows if row["status"] == "rejected")
223
- candidate_total = sum(1 for row in rows if row["status"] != "rejected")
224
- pair_evidence_total = sum(
225
- 1 for row in rows if row["status"] == "pair_evidence_passed"
226
- )
227
- unmeasured_candidate_total = sum(
228
- 1 for row in rows if row["status"] == "candidate_unmeasured"
229
- )
230
- best_pairs = [
231
- best
232
- for row in rows
233
- if row["status"] == "pair_evidence_passed"
234
- for best in [best_pair_evidence(row["passing_pair_evidence"])]
235
- if best is not None
236
- ]
237
- pair_margins = [
238
- item["pair_margin"]
239
- for item in best_pairs
240
- if isinstance(item.get("pair_margin"), int)
241
- ]
242
- wall_ratios = [
243
- item["pair_solo_wall_ratio"]
244
- for item in best_pairs
245
- if is_strict_number(item.get("pair_solo_wall_ratio"))
246
- ]
247
-
248
- return {
249
- "verdict": "PASS" if unmeasured_candidate_total == 0 else "FAIL",
250
- "min_pair_margin": min_pair_margin,
251
- "max_pair_solo_wall_ratio": max_pair_solo_wall_ratio,
252
- "fixtures_total": len(rows),
253
- "rejected_total": rejected_total,
254
- "candidate_total": candidate_total,
255
- "pair_evidence_total": pair_evidence_total,
256
- "unmeasured_candidate_total": unmeasured_candidate_total,
257
- "rejected_count": rejected_total,
258
- "candidate_count": candidate_total,
259
- "pair_evidence_count": pair_evidence_total,
260
- "unmeasured_count": unmeasured_candidate_total,
261
- "pair_margin_avg": average(pair_margins),
262
- "pair_margin_min": min(pair_margins) if pair_margins else None,
263
- "pair_solo_wall_ratio_avg": average(wall_ratios),
264
- "pair_solo_wall_ratio_max": round(max(wall_ratios), 2) if wall_ratios else None,
265
- "rows": rows,
266
- }
267
-
268
-
269
- def write_markdown(path: pathlib.Path, report: dict[str, Any]) -> None:
270
- lines = [
271
- "# Pair Candidate Frontier",
272
- "",
273
- f"Active fixtures: {report['fixtures_total']}",
274
- f"Verdict: {report['verdict']}",
275
- f"Rejected fixtures: {report['rejected_total']}",
276
- f"Candidate fixtures: {report['candidate_total']}",
277
- f"Candidates with passing pair evidence: {report['pair_evidence_total']}",
278
- f"Unmeasured candidates: {report['unmeasured_candidate_total']}",
279
- f"Minimum pair margin required: {format_margin(report.get('min_pair_margin'))}",
280
- f"Maximum pair/solo wall ratio allowed: {format_wall_ratio(report.get('max_pair_solo_wall_ratio'))}",
281
- f"Average pair margin: {format_decimal_margin(report.get('pair_margin_avg'))}",
282
- f"Minimum pair margin: {format_margin(report.get('pair_margin_min'))}",
283
- f"Average pair/solo wall ratio: {format_wall_ratio(report.get('pair_solo_wall_ratio_avg'))}",
284
- f"Maximum pair/solo wall ratio: {format_wall_ratio(report.get('pair_solo_wall_ratio_max'))}",
285
- "",
286
- "| Fixture | Status | Verdict | Evidence | Pair arm | Triggers | Hypothesis trigger | Bare | Solo_claude | Pair | Margin | Wall ratio | Rejected reason |",
287
- "|---|---|---|---|---|---|---|---:|---:|---:|---:|---:|---|",
288
- ]
289
- for row in report["rows"]:
290
- evidence = row["passing_pair_evidence"]
291
- best = best_pair_evidence(evidence)
292
- evidence_text = best.get("run_id", "") if best else ""
293
- pair_arm = best.get("pair_arm", "") if best else ""
294
- triggers = format_trigger_reasons(best.get("pair_trigger_reasons")) if best else ""
295
- lines.append(
296
- f"| {row['fixture']} | {row['status']} | {row['status']} | {evidence_text} | {pair_arm} | {triggers} | "
297
- f"{format_bool(best.get('pair_trigger_has_hypothesis_reason') if best else None)} | "
298
- f"{format_number(best.get('bare_score') if best else None)} | "
299
- f"{format_number(best.get('solo_score') if best else None)} | "
300
- f"{format_number(best.get('pair_score') if best else None)} | "
301
- f"{format_margin(best.get('pair_margin') if best else None)} | "
302
- f"{format_wall_ratio(best.get('pair_solo_wall_ratio') if best else None)} | "
303
- f"{row.get('rejected_reason') or ''} |"
304
- )
305
- path.write_text("\n".join(lines) + "\n", encoding="utf8")
306
-
307
-
308
- def average(values: list[int | float]) -> float | None:
309
- return round(sum(values) / len(values), 2) if values else None
310
-
311
-
312
- def format_number(value: Any) -> str:
313
- return str(value) if isinstance(value, int) else ""
314
-
315
-
316
- def format_decimal_margin(value: Any) -> str:
317
- return f"{value:+.2f}" if isinstance(value, (int, float)) else ""
318
-
319
-
320
- def format_margin(value: Any) -> str:
321
- return f"{value:+d}" if isinstance(value, int) else ""
322
-
323
-
324
- def format_wall_ratio(value: Any) -> str:
325
- return f"{value:.2f}x" if is_strict_number(value) else ""
326
-
327
-
328
- def format_trigger_reasons(value: Any) -> str:
329
- if not isinstance(value, list) or not all(isinstance(item, str) for item in value):
330
- return ""
331
- return ",".join(value)
332
-
333
-
334
- def format_bool(value: Any) -> str:
335
- return str(value).lower() if isinstance(value, bool) else ""
336
-
337
-
338
- def print_summary(report: dict[str, Any]) -> None:
339
- print(
340
- "fixtures={fixtures_total} rejected={rejected_total} "
341
- "candidates={candidate_total} pair_evidence={pair_evidence_total} "
342
- "unmeasured={unmeasured_candidate_total} verdict={verdict}".format(**report)
343
- )
344
- if report.get("pair_evidence_total"):
345
- print(
346
- "pair_margin_avg={avg} pair_margin_min={min_margin} "
347
- "wall_avg={wall_avg} wall_max={wall_max}".format(
348
- avg=format_decimal_margin(report.get("pair_margin_avg")),
349
- min_margin=format_margin(report.get("pair_margin_min")),
350
- wall_avg=format_wall_ratio(report.get("pair_solo_wall_ratio_avg")),
351
- wall_max=format_wall_ratio(report.get("pair_solo_wall_ratio_max")),
352
- )
353
- )
354
- for row in report["rows"]:
355
- if row["status"] != "pair_evidence_passed":
356
- continue
357
- best = best_pair_evidence(row["passing_pair_evidence"])
358
- if not best:
359
- continue
360
- print(
361
- "{fixture}: bare={bare} solo_claude={solo} pair={pair} arm={arm} margin={margin} "
362
- "wall={wall} run={run} verdict=pair_evidence_passed triggers={triggers} "
363
- "hypothesis_trigger={hypothesis_trigger}".format(
364
- fixture=row["fixture"],
365
- bare=format_number(best.get("bare_score")),
366
- solo=format_number(best.get("solo_score")),
367
- pair=format_number(best.get("pair_score")),
368
- arm=best.get("pair_arm") or "",
369
- margin=format_margin(best.get("pair_margin")),
370
- wall=format_wall_ratio(best.get("pair_solo_wall_ratio")),
371
- run=best.get("run_id") or "",
372
- triggers=format_trigger_reasons(best.get("pair_trigger_reasons")),
373
- hypothesis_trigger=format_bool(best.get("pair_trigger_has_hypothesis_reason")),
374
- )
375
- )
376
-
377
-
378
- def print_final_verdict(report: dict[str, Any]) -> None:
379
- if report.get("verdict") == "PASS":
380
- print("PASS pair-candidate-frontier", flush=True)
381
- else:
382
- print("FAIL pair-candidate-frontier", flush=True)
383
-
384
-
385
- def main() -> int:
386
- parser = argparse.ArgumentParser()
387
- parser.add_argument(
388
- "--fixtures-root",
389
- type=pathlib.Path,
390
- default=pathlib.Path("benchmark/auto-resolve/fixtures"),
391
- )
392
- parser.add_argument(
393
- "--registry",
394
- type=pathlib.Path,
395
- default=pathlib.Path(__file__).with_name("pair-rejected-fixtures.sh"),
396
- )
397
- parser.add_argument(
398
- "--results-root",
399
- type=pathlib.Path,
400
- default=pathlib.Path("benchmark/auto-resolve/results"),
401
- )
402
- parser.add_argument("--out-json", type=pathlib.Path)
403
- parser.add_argument("--out-md", type=pathlib.Path)
404
- parser.add_argument(
405
- "--fail-on-unmeasured",
406
- action="store_true",
407
- help="exit 1 when active candidate_unmeasured fixtures remain",
408
- )
409
- parser.add_argument(
410
- "--min-pair-margin",
411
- type=int,
412
- default=5,
413
- help="minimum pair-over-solo margin required to count passing pair evidence",
414
- )
415
- parser.add_argument(
416
- "--max-pair-solo-wall-ratio",
417
- type=float,
418
- default=3.0,
419
- help="maximum pair/solo wall-time ratio allowed to count passing pair evidence",
420
- )
421
- args = parser.parse_args()
422
- if args.min_pair_margin < 1:
423
- print("error: --min-pair-margin must be >= 1", file=sys.stderr)
424
- return 2
425
- if not math.isfinite(args.max_pair_solo_wall_ratio) or args.max_pair_solo_wall_ratio <= 0:
426
- print("error: --max-pair-solo-wall-ratio must be finite and > 0", file=sys.stderr)
427
- return 2
428
-
429
- try:
430
- report = build_report(
431
- fixtures_root=args.fixtures_root,
432
- registry=args.registry,
433
- results_root=args.results_root,
434
- min_pair_margin=args.min_pair_margin,
435
- max_pair_solo_wall_ratio=args.max_pair_solo_wall_ratio,
436
- )
437
- except ValueError as exc:
438
- print(f"error: {exc}", file=sys.stderr)
439
- return 2
440
-
441
- if args.out_json:
442
- args.out_json.parent.mkdir(parents=True, exist_ok=True)
443
- args.out_json.write_text(json.dumps(report, indent=2) + "\n", encoding="utf8")
444
- if args.out_md:
445
- args.out_md.parent.mkdir(parents=True, exist_ok=True)
446
- write_markdown(args.out_md, report)
447
- if not args.out_json and not args.out_md:
448
- print(json.dumps(report, indent=2))
449
- else:
450
- print_summary(report)
451
- print_final_verdict(report)
452
- if args.fail_on_unmeasured and report["unmeasured_candidate_total"] > 0:
453
- unmeasured = [
454
- row["fixture"]
455
- for row in report["rows"]
456
- if row["status"] == "candidate_unmeasured"
457
- ]
458
- print(
459
- "unmeasured candidate fixture(s): " + ", ".join(unmeasured),
460
- file=sys.stderr,
461
- )
462
- if not args.out_json and not args.out_md:
463
- print("FAIL pair-candidate-frontier", file=sys.stderr, flush=True)
464
- return 1
465
- return 0
466
-
467
-
468
- if __name__ == "__main__":
469
- sys.exit(main())