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,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
- }