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,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');