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,66 +0,0 @@
1
- {
2
- "verification_commands": [
3
- {
4
- "cmd": "node --test tests/cli.test.js",
5
- "exit_code": 0,
6
- "stdout_contains": [],
7
- "stdout_not_contains": ["not ok "]
8
- },
9
- {
10
- "cmd": "node \"$BENCH_FIXTURE_DIR/verifiers/exact-success.js\"",
11
- "exit_code": 0,
12
- "stdout_contains": ["\"ok\":true"],
13
- "stdout_not_contains": [],
14
- "contract_refs": [
15
- "A cart with duplicate SKUs combines quantities before stock validation and before line promotions.",
16
- "A cart with both `buy_x_get_y_free` and `per_unit_discount_cents` line promotions applies those promotions before the order coupon.",
17
- "Tax is computed from taxable item totals after line promotions and before the order coupon.",
18
- "Shipping uses the subtotal after line discounts and coupon discount to decide whether the free-shipping threshold is met."
19
- ]
20
- },
21
- {
22
- "cmd": "node \"$BENCH_FIXTURE_DIR/verifiers/stock-error.js\"",
23
- "exit_code": 0,
24
- "stdout_contains": ["\"ok\":true"],
25
- "stdout_not_contains": [],
26
- "contract_refs": [
27
- "Combined quantity over stock uses exact error shape `{ \"error\": \"invalid_stock\", \"sku\": string, \"available\": number, \"requested\": number }`.",
28
- "The stock error object includes `sku`, `available`, and `requested`."
29
- ]
30
- },
31
- {
32
- "cmd": "node \"$BENCH_FIXTURE_DIR/verifiers/catalog-source.js\"",
33
- "exit_code": 0,
34
- "stdout_contains": ["\"ok\":true"],
35
- "stdout_not_contains": [],
36
- "contract_refs": [
37
- "Catalog, stock, tax codes, line promotions, coupons, tax rates, shipping, and free-shipping threshold come from `data/catalog.json`. Do not hardcode these values in the command implementation.",
38
- "Changing `data/catalog.json` prices or rates changes command output without code changes."
39
- ]
40
- }
41
- ],
42
- "forbidden_patterns": [
43
- {
44
- "pattern": "catch\\s*\\([^)]*\\)\\s*\\{[^}]*return\\s+(null|undefined|''|\\{\\})",
45
- "description": "silent catch returning fallback in cart path",
46
- "files": ["bin/cli.js"],
47
- "severity": "disqualifier"
48
- },
49
- {
50
- "pattern": "catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}",
51
- "description": "empty catch block",
52
- "files": ["bin/cli.js"],
53
- "severity": "disqualifier"
54
- },
55
- {
56
- "pattern": "/\\*\\s*eslint-disable",
57
- "description": "eslint-disable without scoped justification",
58
- "files": ["bin/cli.js"],
59
- "severity": "disqualifier"
60
- }
61
- ],
62
- "required_files": ["bin/cli.js", "tests/cli.test.js", "data/catalog.json"],
63
- "forbidden_files": [],
64
- "max_deps_added": 0,
65
- "spec_output_files": ["bin/cli.js", "tests/cli.test.js"]
66
- }
@@ -1,10 +0,0 @@
1
- {
2
- "id": "F25-cli-cart-promotion-rules",
3
- "category": "high-risk",
4
- "difficulty": "high",
5
- "timeout_seconds": 1500,
6
- "required_tools": ["node"],
7
- "browser": false,
8
- "deps_change_expected": false,
9
- "intent": "Add a bench-cli cart command that reads a cart JSON file, prices it from data/catalog.json, combines duplicate SKU quantities, applies line promotions before an order coupon, and prints one exact JSON total with cents-based discounts, tax, shipping, and item rows."
10
- }
@@ -1,36 +0,0 @@
1
- #!/usr/bin/env bash
2
- # F25 setup — seed cart catalog and promotion rules.
3
- set -e
4
-
5
- mkdir -p data
6
-
7
- cat > data/catalog.json <<'JSON'
8
- {
9
- "products": {
10
- "TEE": { "unit_cents": 2500, "stock": 10, "tax_code": "standard" },
11
- "BAG": { "unit_cents": 3200, "stock": 4, "tax_code": "standard" },
12
- "MUG": { "unit_cents": 1200, "stock": 20, "tax_code": "exempt" }
13
- },
14
- "line_promotions": [
15
- { "sku": "TEE", "type": "buy_x_get_y_free", "buy_qty": 2, "free_qty": 1 },
16
- { "sku": "BAG", "type": "per_unit_discount_cents", "min_qty": 2, "per_unit_discount_cents": 500 }
17
- ],
18
- "coupons": {
19
- "ORDER10": { "percent": 10, "min_subtotal_cents": 8000 },
20
- "SMALL5": { "percent": 5, "min_subtotal_cents": 2000 }
21
- },
22
- "tax_rates": {
23
- "CA": 0.0825,
24
- "OR": 0,
25
- "NY": 0.08875
26
- },
27
- "taxable_codes": {
28
- "standard": true,
29
- "exempt": false
30
- },
31
- "shipping_cents": 699,
32
- "free_shipping_min_cents": 9000
33
- }
34
- JSON
35
-
36
- exit 0
@@ -1,71 +0,0 @@
1
- ---
2
- id: "F25-cli-cart-promotion-rules"
3
- title: "Cart command with promotion rules"
4
- status: planned
5
- complexity: high
6
- depends-on: []
7
- ---
8
-
9
- # F25 Cart command with promotion rules
10
-
11
- ## Context
12
-
13
- `bench-cli` currently has greeting and version commands only. The task:
14
- add a `cart` command that reads a cart JSON file, prices it from
15
- `data/catalog.json`, combines duplicate SKU quantities, applies line promotions
16
- before an order coupon, and prints one exact JSON total with cents-based
17
- discounts, tax, shipping, and item rows.
18
-
19
- This is checkout promotion math, so every public amount must be integer cents
20
- and stdout must stay machine-readable.
21
-
22
- ## Requirements
23
-
24
- - [ ] `bench-cli cart --input <path>` reads JSON shaped as `{ "state": string, "coupon": string | null, "items": [{ "sku": string, "qty": number }] }`.
25
- - [ ] Catalog, stock, tax codes, line promotions, coupons, tax rates, shipping, and free-shipping threshold come from `data/catalog.json`. Do not hardcode these values in the command implementation.
26
- - [ ] Combine duplicate SKUs before validating stock and before applying line promotions. The output `items` array must contain one row per SKU in first-seen order.
27
- - [ ] Validation happens before any cart total is printed. Invalid JSON, missing `items`, unknown SKU, non-positive or non-integer `qty`, combined quantity over stock, unknown coupon, or unknown state exits `2` and writes exactly one JSON error object to stderr.
28
- - [ ] Combined quantity over stock uses exact error shape `{ "error": "invalid_stock", "sku": string, "available": number, "requested": number }`.
29
- - [ ] On success, write exactly one JSON object to stdout and no stderr. Keys: `subtotal_cents`, `line_discount_cents`, `coupon_discount_cents`, `tax_cents`, `shipping_cents`, `total_cents`, `items`.
30
- - [ ] Each output item row has keys `sku`, `qty`, `line_subtotal_cents`, `line_discount_cents`, and `line_total_cents`.
31
- - [ ] Line promotion `buy_x_get_y_free` applies to the configured SKU as `Math.floor(qty / (buy_qty + free_qty)) * free_qty * unit_cents`.
32
- - [ ] Line promotion `per_unit_discount_cents` applies to the configured SKU only when combined `qty >= min_qty`, and the discount is `per_unit_discount_cents * qty`.
33
- - [ ] `line_discount_cents` is the sum of all item line discounts; each `line_total_cents` is `line_subtotal_cents - line_discount_cents` for that item.
34
- - [ ] `coupon_discount_cents` is `Math.round((subtotal_cents - line_discount_cents) * coupon.percent / 100)` when a coupon is present and the post-line-discount subtotal meets `coupon.min_subtotal_cents`; otherwise `0`.
35
- - [ ] Tax is computed after line promotions and before the order coupon. A product is taxable when its `tax_code` maps to `true` in `catalog.taxable_codes`. Tax rate is `catalog.tax_rates[state]`. Use `Math.round(taxable_post_line_discount_cents * rate)`.
36
- - [ ] `shipping_cents` is `0` when `subtotal_cents - line_discount_cents - coupon_discount_cents >= catalog.free_shipping_min_cents`; otherwise use `catalog.shipping_cents`.
37
- - [ ] `total_cents = subtotal_cents - line_discount_cents - coupon_discount_cents + tax_cents + shipping_cents`.
38
- - [ ] `tests/cli.test.js` is updated. Existing tests still pass AND at least two new tests cover `cart`: one successful cart and one validation failure.
39
-
40
- ## Constraints
41
-
42
- - **No new npm dependencies.**
43
- - **No floating-money output.** All public amounts are integer cents.
44
- - **No silent catches.** If parsing or file reading fails, emit a visible JSON error to stderr and exit `2`.
45
- - **No extra stdout/stderr text** on the success path; downstream tooling parses stdout as JSON.
46
-
47
- ## Out of Scope
48
-
49
- - Inventory mutation or order persistence.
50
- - Adding currencies, locales, or tax jurisdictions beyond `catalog.tax_rates`.
51
- - Adding web UI or server routes.
52
- - Touching `server/`, `web/`, or `tests/server.test.js`.
53
-
54
- ## Verification
55
-
56
- - `node --test tests/cli.test.js` exits 0.
57
- - A cart with duplicate SKUs combines quantities before stock validation and before line promotions.
58
- - A cart with both `buy_x_get_y_free` and `per_unit_discount_cents` line promotions applies those promotions before the order coupon.
59
- - Tax is computed from taxable item totals after line promotions and before the order coupon.
60
- - Shipping uses the subtotal after line discounts and coupon discount to decide whether the free-shipping threshold is met.
61
- - A cart over combined stock exits `2`, prints one JSON error to stderr, and prints no stdout.
62
- - The stock error object includes `sku`, `available`, and `requested`.
63
- - Changing `data/catalog.json` prices or rates changes command output without code changes.
64
- - `git diff --stat` shows only `bin/cli.js` and `tests/cli.test.js` touched (the catalog seed comes from setup, not the arm).
65
-
66
- ## Solo-headroom hypothesis
67
-
68
- A capable solo_claude baseline is expected to miss the interaction between
69
- duplicate-SKU aggregation, line-promotion ordering, coupon ordering, and
70
- tax/shipping thresholds; observable command
71
- `node "$BENCH_FIXTURE_DIR/verifiers/exact-success.js"` exposes the miss.
@@ -1,7 +0,0 @@
1
- Add a bench-cli cart command that reads a cart JSON file, prices it from data/catalog.json, combines duplicate SKU quantities, applies line promotions before an order coupon, and prints one exact JSON total with cents-based discounts, tax, shipping, and item rows.
2
-
3
- The command should be `bench-cli cart --input <path>`. The input JSON has a state, an optional coupon, and item rows with sku and qty. Use integer cents for every public amount. Read all catalog data from `data/catalog.json`; do not hardcode products, stock, tax codes, promotions, coupons, tax rates, shipping, or the free-shipping threshold.
4
-
5
- Duplicate SKUs must be combined before stock validation and before promotion math. On success, stdout must be exactly one JSON object with subtotal, line discount, coupon discount, tax, shipping, total, and one item row per SKU in first-seen order. Validation errors must exit 2, print exactly one JSON error object to stderr, and print no stdout. Combined stock errors must include the sku, available quantity, and requested combined quantity.
6
-
7
- Update `tests/cli.test.js` so existing tests still pass and at least two new tests cover the cart command, including one successful cart and one validation failure. Do not add dependencies or touch the server/web files.
@@ -1,57 +0,0 @@
1
- const assert = require('node:assert');
2
- const fs = require('node:fs');
3
- const os = require('node:os');
4
- const path = require('node:path');
5
- const { spawnSync } = require('node:child_process');
6
-
7
- const workdir = process.env.BENCH_WORKDIR || process.cwd();
8
- const catalogPath = path.join(workdir, 'data', 'catalog.json');
9
- const original = fs.readFileSync(catalogPath, 'utf8');
10
-
11
- try {
12
- const catalog = JSON.parse(original);
13
- catalog.products.TEE.unit_cents = 3333;
14
- catalog.products.TEE.stock = 7;
15
- catalog.tax_rates.OR = 0;
16
- catalog.line_promotions = [];
17
- catalog.coupons = {};
18
- catalog.shipping_cents = 777;
19
- catalog.free_shipping_min_cents = 99999;
20
- fs.writeFileSync(catalogPath, JSON.stringify(catalog, null, 2) + '\n');
21
-
22
- const input = path.join(os.tmpdir(), `cart-source-${process.pid}.json`);
23
- fs.writeFileSync(input, JSON.stringify({
24
- state: 'OR',
25
- coupon: null,
26
- items: [{ sku: 'TEE', qty: 1 }]
27
- }));
28
-
29
- const proc = spawnSync('node', ['bin/cli.js', 'cart', '--input', input], {
30
- cwd: workdir,
31
- encoding: 'utf8'
32
- });
33
-
34
- assert.strictEqual(proc.status, 0, proc.stderr || proc.stdout);
35
- assert.strictEqual(proc.stderr, '');
36
- assert.deepStrictEqual(JSON.parse(proc.stdout), {
37
- subtotal_cents: 3333,
38
- line_discount_cents: 0,
39
- coupon_discount_cents: 0,
40
- tax_cents: 0,
41
- shipping_cents: 777,
42
- total_cents: 4110,
43
- items: [
44
- {
45
- sku: 'TEE',
46
- qty: 1,
47
- line_subtotal_cents: 3333,
48
- line_discount_cents: 0,
49
- line_total_cents: 3333
50
- }
51
- ]
52
- });
53
- } finally {
54
- fs.writeFileSync(catalogPath, original);
55
- }
56
-
57
- process.stdout.write(JSON.stringify({ ok: true }) + '\n');
@@ -1,63 +0,0 @@
1
- const assert = require('node:assert');
2
- const fs = require('node:fs');
3
- const os = require('node:os');
4
- const path = require('node:path');
5
- const { spawnSync } = require('node:child_process');
6
-
7
- const workdir = process.env.BENCH_WORKDIR || process.cwd();
8
- const input = path.join(os.tmpdir(), `cart-success-${process.pid}.json`);
9
-
10
- fs.writeFileSync(input, JSON.stringify({
11
- state: 'CA',
12
- coupon: 'ORDER10',
13
- items: [
14
- { sku: 'TEE', qty: 2 },
15
- { sku: 'BAG', qty: 1 },
16
- { sku: 'TEE', qty: 1 },
17
- { sku: 'MUG', qty: 2 },
18
- { sku: 'BAG', qty: 1 }
19
- ]
20
- }));
21
-
22
- const proc = spawnSync('node', ['bin/cli.js', 'cart', '--input', input], {
23
- cwd: workdir,
24
- encoding: 'utf8'
25
- });
26
-
27
- assert.strictEqual(proc.status, 0, proc.stderr || proc.stdout);
28
- assert.strictEqual(proc.stderr, '');
29
-
30
- const actual = JSON.parse(proc.stdout);
31
- assert.deepStrictEqual(actual, {
32
- subtotal_cents: 16300,
33
- line_discount_cents: 3500,
34
- coupon_discount_cents: 1280,
35
- tax_cents: 858,
36
- shipping_cents: 0,
37
- total_cents: 12378,
38
- items: [
39
- {
40
- sku: 'TEE',
41
- qty: 3,
42
- line_subtotal_cents: 7500,
43
- line_discount_cents: 2500,
44
- line_total_cents: 5000
45
- },
46
- {
47
- sku: 'BAG',
48
- qty: 2,
49
- line_subtotal_cents: 6400,
50
- line_discount_cents: 1000,
51
- line_total_cents: 5400
52
- },
53
- {
54
- sku: 'MUG',
55
- qty: 2,
56
- line_subtotal_cents: 2400,
57
- line_discount_cents: 0,
58
- line_total_cents: 2400
59
- }
60
- ]
61
- });
62
-
63
- process.stdout.write(JSON.stringify({ ok: true }) + '\n');
@@ -1,34 +0,0 @@
1
- const assert = require('node:assert');
2
- const fs = require('node:fs');
3
- const os = require('node:os');
4
- const path = require('node:path');
5
- const { spawnSync } = require('node:child_process');
6
-
7
- const workdir = process.env.BENCH_WORKDIR || process.cwd();
8
- const input = path.join(os.tmpdir(), `cart-stock-${process.pid}.json`);
9
-
10
- fs.writeFileSync(input, JSON.stringify({
11
- state: 'OR',
12
- coupon: null,
13
- items: [
14
- { sku: 'BAG', qty: 2 },
15
- { sku: 'MUG', qty: 1 },
16
- { sku: 'BAG', qty: 3 }
17
- ]
18
- }));
19
-
20
- const proc = spawnSync('node', ['bin/cli.js', 'cart', '--input', input], {
21
- cwd: workdir,
22
- encoding: 'utf8'
23
- });
24
-
25
- assert.strictEqual(proc.status, 2);
26
- assert.strictEqual(proc.stdout, '');
27
- assert.deepStrictEqual(JSON.parse(proc.stderr), {
28
- error: 'invalid_stock',
29
- sku: 'BAG',
30
- available: 4,
31
- requested: 5
32
- });
33
-
34
- process.stdout.write(JSON.stringify({ ok: true }) + '\n');
@@ -1,31 +0,0 @@
1
- # F26 CLI payout ledger rules
2
-
3
- ## Failure mode
4
-
5
- This fixture detects settlement implementations that pass simple payout tests
6
- while mishandling idempotent events, conflicting duplicates, fee ordering,
7
- dispute fees, reserves, minimum payout holds, and top-level totals.
8
-
9
- ## Pipeline phase target
10
-
11
- PLAN must preserve event deduplication and arithmetic order. IMPLEMENT must keep
12
- fee/reserve math in integer cents and avoid hardcoded rules. VERIFY should build
13
- adversarial ledger examples with repeated IDs, refunds, disputes, and reserves.
14
-
15
- ## Why existing fixtures do not cover it
16
-
17
- F16 covers quote math and F25 covers cart promotions, but neither has ledger
18
- idempotency or conflicting duplicate events. F21/F23 cover scheduling and
19
- allocation ordering, not payout ledger arithmetic.
20
-
21
- ## Measurement status
22
-
23
- Headroom run `20260508-f26-headroom` rejected F26 as full-pipeline pair-lift
24
- evidence: bare scored 25, but `solo_claude` scored 98 and passed all 4
25
- verification commands, so the fixture is at solo ceiling. Keep it as a ledger
26
- math control unless the spec is revised to expose a lower solo ceiling.
27
-
28
- ## Retirement
29
-
30
- Retire or replace this fixture if another fixture provides the same
31
- idempotent-ledger signal with cleaner full-pipeline pair headroom.
@@ -1,68 +0,0 @@
1
- {
2
- "verification_commands": [
3
- {
4
- "cmd": "node --test tests/cli.test.js",
5
- "exit_code": 0,
6
- "stdout_contains": [],
7
- "stdout_not_contains": ["not ok "]
8
- },
9
- {
10
- "cmd": "node \"$BENCH_FIXTURE_DIR/verifiers/exact-payout.js\"",
11
- "exit_code": 0,
12
- "stdout_contains": ["\"ok\":true"],
13
- "stdout_not_contains": [],
14
- "contract_refs": [
15
- "Identical duplicate event IDs are applied only once before merchant totals are computed.",
16
- "A payout with charges, a refund, and a dispute computes processing fees, dispute fees, reserves, merchant payouts, and top-level totals exactly.",
17
- "Processing fees apply to charges only; refunds do not reverse processing fees.",
18
- "Dispute events subtract the dispute amount and add one dispute fee per dispute event.",
19
- "Merchant rows preserve first-seen merchant order after idempotent duplicate removal."
20
- ]
21
- },
22
- {
23
- "cmd": "node \"$BENCH_FIXTURE_DIR/verifiers/conflicting-duplicate.js\"",
24
- "exit_code": 0,
25
- "stdout_contains": ["\"ok\":true"],
26
- "stdout_not_contains": [],
27
- "contract_refs": [
28
- "Conflicting duplicate events use exact error shape `{ \"error\": \"conflicting_duplicate\", \"id\": string }`.",
29
- "A conflicting duplicate exits `2`, prints one JSON error to stderr, and prints no stdout.",
30
- "The conflicting duplicate error object includes `error` and `id`."
31
- ]
32
- },
33
- {
34
- "cmd": "node \"$BENCH_FIXTURE_DIR/verifiers/rules-source.js\"",
35
- "exit_code": 0,
36
- "stdout_contains": ["\"ok\":true"],
37
- "stdout_not_contains": [],
38
- "contract_refs": [
39
- "Processing fee percent, fixed fee, dispute fee, reserve percent, and minimum payout threshold come from `data/payout-rules.json`. Do not hardcode these values in the command implementation.",
40
- "Changing `data/payout-rules.json` fee or reserve settings changes command output without code changes."
41
- ]
42
- }
43
- ],
44
- "forbidden_patterns": [
45
- {
46
- "pattern": "catch\\s*\\([^)]*\\)\\s*\\{[^}]*return\\s+(null|undefined|''|\\{\\})",
47
- "description": "silent catch returning fallback in payout path",
48
- "files": ["bin/cli.js"],
49
- "severity": "disqualifier"
50
- },
51
- {
52
- "pattern": "catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}",
53
- "description": "empty catch block",
54
- "files": ["bin/cli.js"],
55
- "severity": "disqualifier"
56
- },
57
- {
58
- "pattern": "/\\*\\s*eslint-disable",
59
- "description": "eslint-disable without scoped justification",
60
- "files": ["bin/cli.js"],
61
- "severity": "disqualifier"
62
- }
63
- ],
64
- "required_files": ["bin/cli.js", "tests/cli.test.js", "data/payout-rules.json"],
65
- "forbidden_files": [],
66
- "max_deps_added": 0,
67
- "spec_output_files": ["bin/cli.js", "tests/cli.test.js"]
68
- }
@@ -1,10 +0,0 @@
1
- {
2
- "id": "F26-cli-payout-ledger-rules",
3
- "category": "high-risk",
4
- "difficulty": "high",
5
- "timeout_seconds": 1500,
6
- "required_tools": ["node"],
7
- "browser": false,
8
- "deps_change_expected": false,
9
- "intent": "Add a bench-cli payout command that reads ledger events from a JSON file, applies idempotent event handling and payout rules from data/payout-rules.json, and prints exact merchant payout totals with processing fees, dispute fees, reserves, and payouts in integer cents."
10
- }
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env bash
2
- # F26 setup — seed payout ledger rules.
3
- set -e
4
-
5
- mkdir -p data
6
-
7
- cat > data/payout-rules.json <<'JSON'
8
- {
9
- "processing_fee_percent": 2.9,
10
- "fixed_fee_cents": 30,
11
- "dispute_fee_cents": 1500,
12
- "reserve_percent": 10,
13
- "minimum_payout_cents": 1000
14
- }
15
- JSON
16
-
17
- exit 0
@@ -1,68 +0,0 @@
1
- ---
2
- id: "F26-cli-payout-ledger-rules"
3
- title: "Payout command with ledger rules"
4
- status: planned
5
- complexity: high
6
- depends-on: []
7
- ---
8
-
9
- # F26 Payout command with ledger rules
10
-
11
- ## Context
12
-
13
- `bench-cli` currently has greeting and version commands only. The task:
14
- add a `payout` command that reads ledger events from a JSON file, applies
15
- idempotent event handling and payout rules from `data/payout-rules.json`, and
16
- prints exact merchant payout totals with processing fees, dispute fees,
17
- reserves, and payouts in integer cents.
18
-
19
- This is settlement math, so duplicate events must not corrupt totals and every
20
- public amount must be integer cents.
21
-
22
- ## Requirements
23
-
24
- - [ ] `bench-cli payout --input <path>` reads JSON shaped as `{ "events": [{ "id": string, "merchant_id": string, "type": "charge" | "refund" | "dispute", "amount_cents": number }] }`.
25
- - [ ] Processing fee percent, fixed fee, dispute fee, reserve percent, and minimum payout threshold come from `data/payout-rules.json`. Do not hardcode these values in the command implementation.
26
- - [ ] Events with the same `id` and identical JSON content are idempotent duplicates and are applied only once.
27
- - [ ] Events with the same `id` but different JSON content are conflicting duplicates. Validation happens before payout totals are printed, exits `2`, writes exactly one JSON error object to stderr, and writes no stdout.
28
- - [ ] Conflicting duplicate events use exact error shape `{ "error": "conflicting_duplicate", "id": string }`.
29
- - [ ] Unknown event type, missing `merchant_id`, missing `id`, non-positive or non-integer `amount_cents`, missing `events`, invalid JSON, or unreadable input exits `2` and writes exactly one JSON error object to stderr.
30
- - [ ] Merchant rows are emitted in first-seen merchant order after idempotent duplicate removal.
31
- - [ ] A `charge` increases `gross_charge_cents` and adds a processing fee of `Math.round(amount_cents * processing_fee_percent / 100) + fixed_fee_cents`.
32
- - [ ] A `refund` increases `refund_cents`. Refunds do not reverse processing fees.
33
- - [ ] A `dispute` increases `dispute_cents` and adds `dispute_fee_cents` from the rules for each dispute event.
34
- - [ ] For each merchant, compute `net_before_reserve = gross_charge_cents - refund_cents - dispute_cents - processing_fee_cents - dispute_fee_cents`.
35
- - [ ] `reserve_cents` is `Math.round(net_before_reserve * reserve_percent / 100)` when `net_before_reserve > 0`; otherwise `0`.
36
- - [ ] `payout_cents = net_before_reserve - reserve_cents`.
37
- - [ ] If `0 < payout_cents < minimum_payout_cents`, keep the merchant row but set `payout_cents` to `0` and add the original positive amount into `reserve_cents`.
38
- - [ ] On success, write exactly one JSON object to stdout and no stderr. Keys: `total_payout_cents`, `total_processing_fee_cents`, `total_dispute_fee_cents`, `total_reserve_cents`, `merchants`.
39
- - [ ] Each merchant row has keys `merchant_id`, `gross_charge_cents`, `refund_cents`, `dispute_cents`, `processing_fee_cents`, `dispute_fee_cents`, `reserve_cents`, `payout_cents`.
40
- - [ ] `tests/cli.test.js` is updated. Existing tests still pass AND at least two new tests cover `payout`: one successful payout and one validation failure.
41
-
42
- ## Constraints
43
-
44
- - **No new npm dependencies.**
45
- - **No floating-money output.** All public amounts are integer cents.
46
- - **No silent catches.** If parsing or file reading fails, emit a visible JSON error to stderr and exit `2`.
47
- - **No extra stdout/stderr text** on the success path; downstream tooling parses stdout as JSON.
48
-
49
- ## Out of Scope
50
-
51
- - Persisting payouts or mutating a ledger.
52
- - Currency conversion.
53
- - Time zones, reporting periods, or settlement dates.
54
- - Adding web UI or server routes.
55
- - Touching `server/`, `web/`, or `tests/server.test.js`.
56
-
57
- ## Verification
58
-
59
- - `node --test tests/cli.test.js` exits 0.
60
- - Identical duplicate event IDs are applied only once before merchant totals are computed.
61
- - A payout with charges, a refund, and a dispute computes processing fees, dispute fees, reserves, merchant payouts, and top-level totals exactly.
62
- - Processing fees apply to charges only; refunds do not reverse processing fees.
63
- - Dispute events subtract the dispute amount and add one dispute fee per dispute event.
64
- - Merchant rows preserve first-seen merchant order after idempotent duplicate removal.
65
- - A conflicting duplicate exits `2`, prints one JSON error to stderr, and prints no stdout.
66
- - The conflicting duplicate error object includes `error` and `id`.
67
- - Changing `data/payout-rules.json` fee or reserve settings changes command output without code changes.
68
- - `git diff --stat` shows only `bin/cli.js` and `tests/cli.test.js` touched (the payout rules seed comes from setup, not the arm).
@@ -1,7 +0,0 @@
1
- Add a bench-cli payout command that reads ledger events from a JSON file, applies idempotent event handling and payout rules from data/payout-rules.json, and prints exact merchant payout totals with processing fees, dispute fees, reserves, and payouts in integer cents.
2
-
3
- The command should be `bench-cli payout --input <path>`. Input JSON has an events array. Events have id, merchant_id, type, and amount_cents. Use the payout rules JSON for processing fee percent, fixed fee, dispute fee, reserve percent, and minimum payout threshold. Do not hardcode those values.
4
-
5
- Identical duplicate event IDs are idempotent and should be applied only once. The same event ID with different content is a conflicting duplicate and must fail before printing totals. Successful output must be one JSON object with top-level totals and merchant rows in first-seen merchant order. Validation errors must exit 2, write one JSON error object to stderr, and write no stdout.
6
-
7
- Update `tests/cli.test.js` so existing tests still pass and at least two new tests cover the payout command, including one successful payout and one validation failure. Do not add dependencies or touch the server/web files.
@@ -1,29 +0,0 @@
1
- const assert = require('node:assert');
2
- const fs = require('node:fs');
3
- const os = require('node:os');
4
- const path = require('node:path');
5
- const { spawnSync } = require('node:child_process');
6
-
7
- const workdir = process.env.BENCH_WORKDIR || process.cwd();
8
- const input = path.join(os.tmpdir(), `payout-conflict-${process.pid}.json`);
9
-
10
- fs.writeFileSync(input, JSON.stringify({
11
- events: [
12
- { id: 'evt-conflict', merchant_id: 'm_1', type: 'charge', amount_cents: 1000 },
13
- { id: 'evt-conflict', merchant_id: 'm_1', type: 'charge', amount_cents: 1001 }
14
- ]
15
- }));
16
-
17
- const proc = spawnSync('node', ['bin/cli.js', 'payout', '--input', input], {
18
- cwd: workdir,
19
- encoding: 'utf8'
20
- });
21
-
22
- assert.strictEqual(proc.status, 2);
23
- assert.strictEqual(proc.stdout, '');
24
- assert.deepStrictEqual(JSON.parse(proc.stderr), {
25
- error: 'conflicting_duplicate',
26
- id: 'evt-conflict'
27
- });
28
-
29
- process.stdout.write(JSON.stringify({ ok: true }) + '\n');
@@ -1,58 +0,0 @@
1
- const assert = require('node:assert');
2
- const fs = require('node:fs');
3
- const os = require('node:os');
4
- const path = require('node:path');
5
- const { spawnSync } = require('node:child_process');
6
-
7
- const workdir = process.env.BENCH_WORKDIR || process.cwd();
8
- const input = path.join(os.tmpdir(), `payout-success-${process.pid}.json`);
9
-
10
- const charge1 = { id: 'evt-1', merchant_id: 'm_1', type: 'charge', amount_cents: 10000 };
11
- fs.writeFileSync(input, JSON.stringify({
12
- events: [
13
- charge1,
14
- { id: 'evt-2', merchant_id: 'm_2', type: 'charge', amount_cents: 5000 },
15
- charge1,
16
- { id: 'evt-3', merchant_id: 'm_1', type: 'refund', amount_cents: 2500 },
17
- { id: 'evt-4', merchant_id: 'm_1', type: 'charge', amount_cents: 3333 },
18
- { id: 'evt-5', merchant_id: 'm_2', type: 'dispute', amount_cents: 2000 }
19
- ]
20
- }));
21
-
22
- const proc = spawnSync('node', ['bin/cli.js', 'payout', '--input', input], {
23
- cwd: workdir,
24
- encoding: 'utf8'
25
- });
26
-
27
- assert.strictEqual(proc.status, 0, proc.stderr || proc.stdout);
28
- assert.strictEqual(proc.stderr, '');
29
- assert.deepStrictEqual(JSON.parse(proc.stdout), {
30
- total_payout_cents: 10539,
31
- total_processing_fee_cents: 622,
32
- total_dispute_fee_cents: 1500,
33
- total_reserve_cents: 1172,
34
- merchants: [
35
- {
36
- merchant_id: 'm_1',
37
- gross_charge_cents: 13333,
38
- refund_cents: 2500,
39
- dispute_cents: 0,
40
- processing_fee_cents: 447,
41
- dispute_fee_cents: 0,
42
- reserve_cents: 1039,
43
- payout_cents: 9347
44
- },
45
- {
46
- merchant_id: 'm_2',
47
- gross_charge_cents: 5000,
48
- refund_cents: 0,
49
- dispute_cents: 2000,
50
- processing_fee_cents: 175,
51
- dispute_fee_cents: 1500,
52
- reserve_cents: 133,
53
- payout_cents: 1192
54
- }
55
- ]
56
- });
57
-
58
- process.stdout.write(JSON.stringify({ ok: true }) + '\n');