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,475 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- pair-plan-lint.py — validate a `pair-plan.json` against its registry and
4
- the `pair-plan-schema.md` hard rules.
5
-
6
- Inputs:
7
- --plan <path> path to pair-plan.json (required)
8
- --registry <path> override registry path (default: resolved from
9
- plan.source.canonical_id_registry_path)
10
- --quiet suppress stderr human summary
11
-
12
- Output:
13
- stdout — `{"ok": bool, "errors": [{code, message, ...}, ...]}` (machine-readable)
14
- stderr — short human summary unless --quiet (skipped on --quiet)
15
-
16
- Exit code:
17
- 0 on pass, 1 on fail.
18
-
19
- Schema source: config/skills/_shared/pair-plan-schema.md (iter-0022 ship).
20
- """
21
- import argparse
22
- import copy
23
- import hashlib
24
- import json
25
- import pathlib
26
- import sys
27
-
28
- from pair_evidence_contract import reject_json_constant
29
-
30
- SCHEMA_VERSION = "1"
31
- AUTHORITY_ORDER_CANONICAL = [
32
- "spec.md",
33
- "expected.json/rubric",
34
- "phase prompt",
35
- "model preference",
36
- ]
37
- REQUIRED_TOP_LEVEL = [
38
- "schema_version",
39
- "plan_status",
40
- "planning_mode",
41
- "source",
42
- "authority_order",
43
- "rounds",
44
- "accepted_invariants",
45
- "rejected_alternatives",
46
- "unresolved",
47
- "escalated_to_user",
48
- "model_stamps",
49
- ]
50
- REQUIRED_SOURCE_FIELDS = [
51
- "spec_path",
52
- "spec_sha256",
53
- "rubric_path",
54
- "rubric_sha256",
55
- "canonical_id_registry_path",
56
- "canonical_id_registry_sha256",
57
- ]
58
-
59
-
60
- # ---------------------------------------------------------------------------
61
- # JSON loading with strict-keys.
62
- # ---------------------------------------------------------------------------
63
- def _strict_pairs(pairs):
64
- keys = [k for k, _ in pairs]
65
- if len(keys) != len(set(keys)):
66
- raise ValueError("duplicate key in pair-plan.json")
67
- return dict(pairs)
68
-
69
-
70
- def load_strict_json(path):
71
- with open(path, "r", encoding="utf-8") as f:
72
- return json.load(
73
- f,
74
- object_pairs_hook=_strict_pairs,
75
- parse_constant=reject_json_constant,
76
- )
77
-
78
-
79
- # ---------------------------------------------------------------------------
80
- # Hash helpers.
81
- # ---------------------------------------------------------------------------
82
- def file_sha256(path):
83
- with open(path, "rb") as f:
84
- return hashlib.sha256(f.read()).hexdigest()
85
-
86
-
87
- def canonical_pre_stamp_sha256(plan):
88
- pre = copy.deepcopy(plan)
89
- pre["model_stamps"] = {}
90
- s = json.dumps(
91
- pre,
92
- sort_keys=True,
93
- separators=(",", ":"),
94
- ensure_ascii=False,
95
- allow_nan=False,
96
- )
97
- return hashlib.sha256(s.encode("utf-8")).hexdigest()
98
-
99
-
100
- # ---------------------------------------------------------------------------
101
- # Individual checks (each returns a list of error dicts).
102
- # ---------------------------------------------------------------------------
103
- PLAN_STATUS_VALID = {"final", "blocked", "draft"}
104
- PLANNING_MODE_VALID = {"solo", "pair"}
105
- ACCEPTED_INVARIANT_REQUIRED_FIELDS = ("id", "source_refs", "operational_check", "authority")
106
-
107
-
108
- def check_top_level_shape(plan):
109
- errs = []
110
- if not isinstance(plan, dict):
111
- return [{"code": "plan_not_object", "message": "pair-plan.json root must be a JSON object"}]
112
- for f in REQUIRED_TOP_LEVEL:
113
- if f not in plan:
114
- errs.append({"code": "missing_top_level_field", "field": f,
115
- "message": f"required top-level field missing: {f}"})
116
- if plan.get("schema_version") != SCHEMA_VERSION:
117
- errs.append({"code": "schema_version_mismatch",
118
- "expected": SCHEMA_VERSION,
119
- "got": plan.get("schema_version"),
120
- "message": f"schema_version must be {SCHEMA_VERSION!r}"})
121
- if plan.get("plan_status") not in PLAN_STATUS_VALID:
122
- errs.append({"code": "plan_status_invalid",
123
- "got": plan.get("plan_status"),
124
- "message": f"plan_status must be one of {sorted(PLAN_STATUS_VALID)}"})
125
- if plan.get("planning_mode") not in PLANNING_MODE_VALID:
126
- errs.append({"code": "planning_mode_invalid",
127
- "got": plan.get("planning_mode"),
128
- "message": f"planning_mode must be one of {sorted(PLANNING_MODE_VALID)}"})
129
- return errs
130
-
131
-
132
- def check_accepted_invariants_shape(plan):
133
- """Each accepted_invariants[] item MUST carry id + source_refs + operational_check + authority.
134
- A plan with empty/missing operational_check has nothing for BUILD/EVAL/CRITIC to enforce."""
135
- errs = []
136
- for i, item in enumerate(plan.get("accepted_invariants") or []):
137
- if not isinstance(item, dict):
138
- errs.append({"code": "accepted_invariant_not_object",
139
- "index": i,
140
- "message": f"accepted_invariants[{i}] is not a JSON object"})
141
- continue
142
- for f in ACCEPTED_INVARIANT_REQUIRED_FIELDS:
143
- if f not in item or item[f] in (None, "", []):
144
- errs.append({"code": "accepted_invariant_missing_field",
145
- "index": i,
146
- "id": item.get("id"),
147
- "field": f,
148
- "message": f"accepted_invariants[{i}].{f} missing or empty"})
149
- return errs
150
-
151
-
152
- def check_registry_shape(registry):
153
- """Lint MUST reject unsorted required_invariants and unknown top-level fields per schema doc."""
154
- errs = []
155
- allowed = {"schema_version", "fixture_id", "generated_at", "generated_from", "required_invariants"}
156
- extra = sorted(set(registry.keys()) - allowed)
157
- if extra:
158
- errs.append({"code": "registry_unknown_field",
159
- "fields": extra,
160
- "message": f"canonical_id_registry.json has unknown top-level fields: {extra}"})
161
- inv = registry.get("required_invariants") or []
162
- ids = [e.get("id") for e in inv]
163
- if ids != sorted(ids):
164
- errs.append({"code": "registry_unsorted",
165
- "message": "required_invariants[] must be sorted lexicographically by id"})
166
- return errs
167
-
168
-
169
- def check_authority_order(plan):
170
- if plan.get("authority_order") != AUTHORITY_ORDER_CANONICAL:
171
- return [{"code": "authority_order_drift",
172
- "expected": AUTHORITY_ORDER_CANONICAL,
173
- "got": plan.get("authority_order"),
174
- "message": "authority_order must be the canonical 4-string snapshot"}]
175
- return []
176
-
177
-
178
- def check_unresolved_status(plan):
179
- unresolved = plan.get("unresolved") or []
180
- status = plan.get("plan_status")
181
- if len(unresolved) > 0 and status not in ("blocked", "draft"):
182
- return [{"code": "unresolved_with_final_status",
183
- "unresolved_count": len(unresolved),
184
- "plan_status": status,
185
- "message": "unresolved is non-empty but plan_status is not 'blocked' or 'draft'"}]
186
- return []
187
-
188
-
189
- def check_escalated_status(plan):
190
- escalated = plan.get("escalated_to_user") or []
191
- status = plan.get("plan_status")
192
- errs = []
193
- if escalated:
194
- if status in ("blocked", "draft"):
195
- return errs
196
- for i, item in enumerate(escalated):
197
- if "user_resolution" not in item:
198
- errs.append({"code": "escalated_without_resolution",
199
- "index": i,
200
- "id": item.get("id"),
201
- "message": "escalated_to_user[] item missing user_resolution while plan_status is final"})
202
- return errs
203
-
204
-
205
- def check_planning_mode_rounds(plan):
206
- mode = plan.get("planning_mode")
207
- rounds = plan.get("rounds") or []
208
- if mode == "pair" and len(rounds) < 1:
209
- return [{"code": "pair_mode_no_rounds",
210
- "message": "planning_mode=pair requires rounds.length >= 1"}]
211
- if mode == "solo" and len(rounds) != 0:
212
- return [{"code": "solo_mode_with_rounds",
213
- "message": "planning_mode=solo requires rounds.length == 0"}]
214
- return []
215
-
216
-
217
- def check_accepted_ids_in_registry(plan, registry):
218
- registry_ids = {e["id"] for e in registry.get("required_invariants", [])}
219
- errs = []
220
- for i, item in enumerate(plan.get("accepted_invariants") or []):
221
- rid = item.get("id")
222
- if rid not in registry_ids:
223
- errs.append({"code": "accepted_id_not_in_registry",
224
- "index": i,
225
- "id": rid,
226
- "message": f"accepted_invariants[{i}].id={rid!r} not present in registry"})
227
- return errs
228
-
229
-
230
- def check_registry_coverage(plan, registry):
231
- """Every registry required_invariants[].id must be accounted for in a final plan.
232
-
233
- Coverage is enforced only when plan_status == "final" — draft / blocked
234
- plans are allowed to have un-decided ids in `unresolved[]` (Hard Rule #1
235
- in pair-plan-schema.md) without tripping coverage. `unresolved[]` items
236
- of shape `{id, note}` count as accounted-for at the structural level.
237
- """
238
- if plan.get("plan_status") != "final":
239
- return []
240
- registry_ids = [e["id"] for e in registry.get("required_invariants", [])]
241
- accepted = {item.get("id") for item in (plan.get("accepted_invariants") or [])}
242
- rejected_conflicts = set()
243
- for item in plan.get("rejected_alternatives") or []:
244
- for cid in item.get("conflicts_with_ids", []) or []:
245
- rejected_conflicts.add(cid)
246
- escalated = {item.get("id") for item in (plan.get("escalated_to_user") or [])}
247
- unresolved = {item.get("id") for item in (plan.get("unresolved") or []) if isinstance(item, dict)}
248
- accounted = accepted | rejected_conflicts | escalated | unresolved
249
- errs = []
250
- for rid in registry_ids:
251
- if rid not in accounted:
252
- errs.append({"code": "missing_required_id",
253
- "id": rid,
254
- "message": f"registry id {rid!r} is not in accepted_invariants, rejected_alternatives.conflicts_with_ids, escalated_to_user, or unresolved"})
255
- return errs
256
-
257
-
258
- def check_model_stamps(plan):
259
- stamps = plan.get("model_stamps") or {}
260
- errs = []
261
- for who in ("claude", "codex"):
262
- s = stamps.get(who)
263
- if not isinstance(s, dict):
264
- errs.append({"code": "stamp_missing", "who": who,
265
- "message": f"model_stamps.{who} missing or not an object"})
266
- continue
267
- if s.get("status") not in ("sign", "block"):
268
- errs.append({"code": "stamp_status_invalid", "who": who,
269
- "got": s.get("status"),
270
- "message": f"model_stamps.{who}.status must be 'sign' or 'block'"})
271
- if "signed_plan_sha256" not in s:
272
- errs.append({"code": "stamp_sha_missing", "who": who,
273
- "message": f"model_stamps.{who}.signed_plan_sha256 missing"})
274
- if plan.get("plan_status") == "final":
275
- for who in ("claude", "codex"):
276
- s = stamps.get(who) or {}
277
- if s.get("status") != "sign":
278
- errs.append({"code": "final_with_non_sign_stamp",
279
- "who": who,
280
- "status": s.get("status"),
281
- "message": f"plan_status=final requires model_stamps.{who}.status=sign"})
282
- return errs
283
-
284
-
285
- def check_signed_pre_stamp_sha(plan):
286
- expected = canonical_pre_stamp_sha256(plan)
287
- stamps = plan.get("model_stamps") or {}
288
- claude_sha = (stamps.get("claude") or {}).get("signed_plan_sha256")
289
- codex_sha = (stamps.get("codex") or {}).get("signed_plan_sha256")
290
- errs = []
291
- if claude_sha != codex_sha:
292
- errs.append({"code": "stamp_sha_disagree",
293
- "claude_sha": claude_sha,
294
- "codex_sha": codex_sha,
295
- "message": "model_stamps.{claude,codex}.signed_plan_sha256 must be byte-identical"})
296
- for who, sha in [("claude", claude_sha), ("codex", codex_sha)]:
297
- if sha is not None and sha != expected:
298
- errs.append({"code": "stamp_sha_mismatch_canonical",
299
- "who": who,
300
- "got": sha,
301
- "expected": expected,
302
- "message": f"model_stamps.{who}.signed_plan_sha256 does not equal canonical pre-stamp sha"})
303
- return errs
304
-
305
-
306
- def check_source_file_shas(plan, plan_path):
307
- """Each source.<x>_sha256 must equal the raw-bytes sha256 of the referenced file."""
308
- src = plan.get("source") or {}
309
- plan_dir = pathlib.Path(plan_path).resolve().parent
310
- errs = []
311
- pairs = [
312
- ("spec_path", "spec_sha256"),
313
- ("expected_path", "expected_sha256"),
314
- ("rubric_path", "rubric_sha256"),
315
- ("canonical_id_registry_path", "canonical_id_registry_sha256"),
316
- ]
317
- for path_field, sha_field in pairs:
318
- # expected_path is optional only when expected.json is genuinely absent;
319
- # rubric/registry/spec are always required.
320
- if path_field == "expected_path" and path_field not in src:
321
- continue
322
- if path_field not in src:
323
- errs.append({"code": "source_path_missing",
324
- "field": path_field,
325
- "message": f"source.{path_field} missing"})
326
- continue
327
- if sha_field not in src:
328
- errs.append({"code": "source_sha_missing",
329
- "field": sha_field,
330
- "message": f"source.{sha_field} missing"})
331
- continue
332
- path_str = src[path_field]
333
- path_abs = _resolve_repo_path(path_str, plan_dir)
334
- if path_abs is None:
335
- errs.append({"code": "source_path_unreadable",
336
- "field": path_field,
337
- "path": str(path_abs),
338
- "message": f"source.{path_field} resolves to a path that does not exist"})
339
- continue
340
- actual = file_sha256(path_abs)
341
- if actual != src[sha_field]:
342
- errs.append({"code": "source_sha_drift",
343
- "field": sha_field,
344
- "expected": src[sha_field],
345
- "actual": actual,
346
- "path": str(path_abs),
347
- "message": f"source.{sha_field} does not match raw-bytes sha of {path_str}"})
348
- return errs
349
-
350
-
351
- # ---------------------------------------------------------------------------
352
- # Path resolution — repo-relative paths in plan/source live in the repo,
353
- # but the plan itself can be anywhere (e.g. /tmp during tests). Try three
354
- # anchors in order: absolute path → git-root ancestor of plan_dir → cwd.
355
- # Returns the first existing absolute path, or None if no anchor yields one.
356
- # ---------------------------------------------------------------------------
357
- def _git_root_ancestor(start):
358
- s = pathlib.Path(start).resolve()
359
- while s != s.parent:
360
- if (s / ".git").exists():
361
- return s
362
- s = s.parent
363
- return None
364
-
365
-
366
- def _resolve_repo_path(path_str, plan_dir):
367
- p = pathlib.Path(path_str)
368
- if p.is_absolute():
369
- return p if p.exists() else None
370
- candidates = []
371
- repo_root = _git_root_ancestor(plan_dir)
372
- if repo_root is not None:
373
- candidates.append((repo_root / p).resolve())
374
- candidates.append((pathlib.Path.cwd() / p).resolve())
375
- candidates.append((plan_dir / p).resolve())
376
- seen = set()
377
- for c in candidates:
378
- if c in seen:
379
- continue
380
- seen.add(c)
381
- if c.exists():
382
- return c
383
- return None
384
-
385
-
386
- def resolve_registry_from_plan(plan, plan_path):
387
- src = plan.get("source") or {}
388
- p = src.get("canonical_id_registry_path")
389
- if p is None:
390
- return None
391
- plan_dir = pathlib.Path(plan_path).resolve().parent
392
- return _resolve_repo_path(p, plan_dir)
393
-
394
-
395
- # ---------------------------------------------------------------------------
396
- # Top-level lint.
397
- # ---------------------------------------------------------------------------
398
- def lint(plan_path, registry_override=None):
399
- try:
400
- plan = load_strict_json(plan_path)
401
- except json.JSONDecodeError as e:
402
- return {"ok": False, "errors": [{"code": "plan_invalid_json",
403
- "message": f"plan parse error: {e}"}]}
404
- except ValueError as e:
405
- code = "plan_duplicate_keys" if "duplicate key" in str(e) else "plan_invalid_json"
406
- return {"ok": False, "errors": [{"code": code,
407
- "message": str(e)}]}
408
- except FileNotFoundError:
409
- return {"ok": False, "errors": [{"code": "plan_not_found",
410
- "message": f"plan file not found: {plan_path}"}]}
411
-
412
- # top-level shape first; skip downstream checks if shape is broken
413
- shape_errs = check_top_level_shape(plan)
414
- if shape_errs:
415
- return {"ok": False, "errors": shape_errs}
416
-
417
- # resolve registry
418
- if registry_override:
419
- registry_path = pathlib.Path(registry_override).resolve()
420
- else:
421
- registry_path = resolve_registry_from_plan(plan, plan_path)
422
- if registry_path is None or not registry_path.exists():
423
- return {"ok": False, "errors": [{
424
- "code": "registry_unreachable",
425
- "registry_path": str(registry_path) if registry_path else None,
426
- "message": "could not resolve canonical_id_registry; provide --registry or fix source.canonical_id_registry_path",
427
- }]}
428
- try:
429
- registry = load_strict_json(registry_path)
430
- except (json.JSONDecodeError, ValueError) as e:
431
- return {"ok": False, "errors": [{"code": "registry_invalid",
432
- "registry_path": str(registry_path),
433
- "message": str(e)}]}
434
-
435
- errors = []
436
- errors += check_registry_shape(registry)
437
- errors += check_authority_order(plan)
438
- errors += check_accepted_invariants_shape(plan)
439
- errors += check_unresolved_status(plan)
440
- errors += check_escalated_status(plan)
441
- errors += check_planning_mode_rounds(plan)
442
- errors += check_accepted_ids_in_registry(plan, registry)
443
- errors += check_registry_coverage(plan, registry)
444
- errors += check_model_stamps(plan)
445
- errors += check_signed_pre_stamp_sha(plan)
446
- errors += check_source_file_shas(plan, plan_path)
447
-
448
- return {"ok": not errors, "errors": errors,
449
- "registry_path": str(registry_path)}
450
-
451
-
452
- def main():
453
- ap = argparse.ArgumentParser()
454
- ap.add_argument("--plan", required=True)
455
- ap.add_argument("--registry", default=None,
456
- help="Override registry path (default: source.canonical_id_registry_path)")
457
- ap.add_argument("--quiet", action="store_true")
458
- args = ap.parse_args()
459
-
460
- verdict = lint(args.plan, registry_override=args.registry)
461
-
462
- print(json.dumps(verdict, indent=2, sort_keys=True))
463
- if not args.quiet:
464
- if verdict["ok"]:
465
- print(f"pair-plan-lint: PASS — {args.plan} (registry: {verdict.get('registry_path')})", file=sys.stderr)
466
- else:
467
- print(f"pair-plan-lint: FAIL — {args.plan} ({len(verdict['errors'])} error(s))", file=sys.stderr)
468
- for e in verdict["errors"]:
469
- print(f" [{e.get('code')}] {e.get('message')}", file=sys.stderr)
470
-
471
- sys.exit(0 if verdict["ok"] else 1)
472
-
473
-
474
- if __name__ == "__main__":
475
- main()
@@ -1,103 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Shared rejected/ceiling pair-candidate fixture registry.
3
- # Includes active fixtures and calibrated shadow controls that should not spend
4
- # pair-candidate runs unless explicitly requested for diagnostics.
5
-
6
- rejected_pair_fixture_reason() {
7
- local fid="$1"
8
- case "$fid" in
9
- F1-*|F1)
10
- echo "trivial calibration fixture; every arm is expected to one-shot it"
11
- ;;
12
- F2-*|F2)
13
- echo "bare 83 / solo_claude 95 in 20260512-f2-medium-headroom"
14
- ;;
15
- F3-*|F3)
16
- echo "bare 97 / solo_claude 99 in 20260511-f3-http-error-headroom"
17
- ;;
18
- F4-*|F4)
19
- echo "bare 70 / solo_claude 92 with bare disqualifier in 20260512-f4-web-headroom"
20
- ;;
21
- F5-*|F5)
22
- echo "bare 99 / solo_claude 99 in 20260512-f5-fixloop-headroom"
23
- ;;
24
- F6-*|F6)
25
- echo "bare 97 / solo_claude 96 in 20260512-f6-checksum-headroom"
26
- ;;
27
- F7-*|F7)
28
- echo "bare 99 / solo_claude 100 in 20260512-f7-scope-headroom"
29
- ;;
30
- F8-*|F8)
31
- echo "known-limit ambiguity fixture; expected margin is [-3,+3], not pair-lift evidence"
32
- ;;
33
- F9-*|F9)
34
- echo "bare 60 / solo_claude 90 with bare headroom 0 and bare judge disqualifier in 20260512-f9-e2e-headroom"
35
- ;;
36
- F10-*|F10)
37
- echo "bare 75 / solo_claude 94 in 20260507-f10-f11-tier1-full-pipeline"
38
- ;;
39
- F11-*|F11)
40
- echo "bare 98 / solo_claude 97 in 20260507-f10-f11-tier1-full-pipeline"
41
- ;;
42
- F12-*|F12)
43
- echo "bare 85 / solo_claude 99 in 20260511-f12-webhook-headroom"
44
- ;;
45
- F15-*|F15)
46
- echo "bare 99 / solo_claude 94 in 20260511-f15-concurrency-headroom"
47
- ;;
48
- F22-*|F22)
49
- echo "bare 94 / solo_claude 98 in 20260508-f22-exact-error-headroom"
50
- ;;
51
- F26-*|F26)
52
- echo "solo_claude scored 98 in 20260508-f26-headroom"
53
- ;;
54
- F27-*|F27)
55
- echo "solo_claude scored 94 in 20260511-f27-headroom-smoke-061401"
56
- ;;
57
- F28-*|F28)
58
- echo "corrected-oracle reverify scored solo_claude 98 in 20260511-f28-policy-oraclefix-reverified-pair"
59
- ;;
60
- F29-*|F29)
61
- echo "corrected headroom scored solo_claude 92 in 20260510-f29-headroom-v2"
62
- ;;
63
- F30-*|F30)
64
- echo "solo_claude scored 98 in 20260511-f30-headroom-v1"
65
- ;;
66
- F31-*|F31)
67
- echo "solo_claude scored 98 with bare disqualifiers in 20260512-f31-seat-rebalance-headroom"
68
- ;;
69
- F32-*|F32)
70
- echo "bare 33 / solo_claude 98 in 20260512-f32-subscription-renewal-headroom"
71
- ;;
72
- F34-*|F34)
73
- echo "bare 92 / solo_claude 88 in iter-0039-headroom-f34-f35"
74
- ;;
75
- F35-*|F35)
76
- echo "bare 50 / solo_claude 97 in iter-0039-headroom-f34-f35"
77
- ;;
78
- F36-*|F36)
79
- echo "bare 50 / solo_claude 96 with solo timeout in iter-0041-headroom-f36-f37"
80
- ;;
81
- F37-*|F37)
82
- echo "bare 75 / solo_claude 96 with solo invoke failure in iter-0041-headroom-f36-f37"
83
- ;;
84
- S2-*|S2)
85
- echo "bare 33 / solo_claude 99 with solo timeout in 20260513-s2-inventory-headroom"
86
- ;;
87
- S3-*|S3)
88
- echo "bare 33 / solo_claude 99 with solo timeout in 20260513-s3-ticket-headroom"
89
- ;;
90
- S4-*|S4)
91
- echo "bare 33 / solo_claude 98 with solo timeout in 20260513-s4-return-headroom"
92
- ;;
93
- S5-*|S5)
94
- echo "bare 33 / solo_claude 98 with solo timeout in 20260513-s5-credit-headroom"
95
- ;;
96
- S6-*|S6)
97
- echo "bare 33 / solo_claude 98 with solo timeout in 20260514-s6-refund-headroom-v1"
98
- ;;
99
- *)
100
- return 1
101
- ;;
102
- esac
103
- }