@codespar/cli 0.14.0 → 0.16.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 (538) hide show
  1. package/README.md +44 -17
  2. package/dist/commands/audit-replay.js +267 -0
  3. package/dist/commands/audit-replay.js.map +1 -0
  4. package/dist/commands/init.js +28 -0
  5. package/dist/commands/init.js.map +1 -1
  6. package/dist/commands/login.js +2 -1
  7. package/dist/commands/login.js.map +1 -1
  8. package/dist/commands/mandate-verify.js +75 -27
  9. package/dist/commands/mandate-verify.js.map +1 -1
  10. package/dist/config.js +17 -1
  11. package/dist/config.js.map +1 -1
  12. package/dist/did.js +262 -41
  13. package/dist/did.js.map +1 -1
  14. package/dist/index.js +33 -7
  15. package/dist/index.js.map +1 -1
  16. package/dist/surface.js +4 -1
  17. package/dist/surface.js.map +1 -1
  18. package/package.json +1 -1
  19. package/templates/bills-agent/README.md +8 -5
  20. package/templates/bills-agent/agents/bills-agent/.env.example +3 -3
  21. package/templates/bills-agent/agents/bills-agent/AGENTS.md +1 -1
  22. package/templates/bills-agent/agents/bills-agent/CLAUDE.md +1 -1
  23. package/templates/bills-agent/agents/bills-agent/README.md +62 -22
  24. package/templates/bills-agent/agents/bills-agent/SYSTEM_PROMPT.md +1 -1
  25. package/templates/bills-agent/agents/bills-agent/agent.yaml +2 -2
  26. package/templates/bills-agent/agents/bills-agent/package.json +14 -11
  27. package/templates/bills-agent/agents/bills-agent/src/kit.ts +193 -0
  28. package/templates/bills-agent/agents/bills-agent/test/adversarial.test.ts +8 -7
  29. package/templates/bills-agent/agents/bills-agent/test/check.test.ts +19 -2
  30. package/templates/bills-agent/agents/bills-agent/test/cli.test.ts +72 -24
  31. package/templates/bills-agent/agents/bills-agent/test/fixtures/excursao-300.transcript.jsonl +2 -0
  32. package/templates/bills-agent/agents/bills-agent/test/fixtures/material-400.transcript.jsonl +2 -0
  33. package/templates/bills-agent/agents/bills-agent/test/inspect.test.ts +124 -0
  34. package/templates/bills-agent/agents/bills-agent/test/provider.test.ts +25 -0
  35. package/templates/bills-agent/agents/bills-agent/test/scenarios.test.ts +10 -9
  36. package/templates/bills-agent/agents/bills-agent/tsconfig.json +0 -1
  37. package/templates/bills-agent/package.json +5 -2
  38. package/templates/bills-agent/packages/agent-core/README.md +2 -0
  39. package/templates/bills-agent/packages/agent-core/package.json +1 -1
  40. package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
  41. package/templates/bills-agent/packages/agent-core/src/api/rail.ts +16 -0
  42. package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
  43. package/templates/bills-agent/packages/agent-core/src/approval.ts +16 -2
  44. package/templates/bills-agent/packages/agent-core/src/bundle.ts +50 -4
  45. package/templates/bills-agent/packages/agent-core/src/channels.ts +140 -0
  46. package/templates/bills-agent/packages/agent-core/src/check.ts +90 -8
  47. package/templates/bills-agent/packages/agent-core/src/clock.ts +42 -0
  48. package/templates/bills-agent/packages/agent-core/src/engine.ts +119 -18
  49. package/templates/bills-agent/packages/agent-core/src/hash.ts +13 -0
  50. package/templates/bills-agent/packages/agent-core/src/index.ts +3 -0
  51. package/templates/bills-agent/packages/agent-core/src/manifest.ts +1 -1
  52. package/templates/bills-agent/packages/agent-core/src/rail.ts +16 -2
  53. package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  54. package/templates/bills-agent/packages/agent-core/src/state-machine.ts +3 -1
  55. package/templates/bills-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
  56. package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +19 -2
  57. package/templates/bills-agent/packages/agent-core/src/types.ts +28 -0
  58. package/templates/bills-agent/packages/agent-core/test/approval.test.ts +36 -2
  59. package/templates/bills-agent/packages/agent-core/test/bundle.test.ts +85 -0
  60. package/templates/bills-agent/packages/agent-core/test/clock.test.ts +25 -0
  61. package/templates/bills-agent/packages/agent-core/test/engine.test.ts +73 -1
  62. package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  63. package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  64. package/templates/bills-agent/packages/agent-core/test/helpers.ts +1 -1
  65. package/templates/bills-agent/packages/agent-core/test/manifest.test.ts +2 -2
  66. package/templates/bills-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  67. package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +51 -0
  68. package/templates/bills-agent/packages/agent-runtime/README.md +68 -0
  69. package/templates/bills-agent/packages/agent-runtime/bin.mjs +32 -0
  70. package/templates/bills-agent/packages/agent-runtime/package.json +23 -0
  71. package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/adversarial.ts +36 -44
  72. package/templates/bills-agent/packages/agent-runtime/src/agent.ts +68 -0
  73. package/templates/bills-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  74. package/templates/bills-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  75. package/templates/bills-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  76. package/templates/bills-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  77. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  78. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  79. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  80. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  81. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  82. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  83. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  84. package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  85. package/templates/bills-agent/packages/agent-runtime/src/cli.ts +98 -0
  86. package/templates/bills-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  87. package/templates/bills-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  88. package/templates/bills-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  89. package/templates/bills-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  90. package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  91. package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  92. package/templates/bills-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  93. package/templates/bills-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  94. package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  95. package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  96. package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  97. package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  98. package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  99. package/templates/bills-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  100. package/templates/bills-agent/packages/agent-runtime/src/index.ts +12 -0
  101. package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +797 -0
  102. package/templates/bills-agent/packages/agent-runtime/src/kit.ts +206 -0
  103. package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/poll.ts +22 -11
  104. package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/scenarios.ts +50 -34
  105. package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/setup.ts +88 -66
  106. package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +154 -0
  107. package/templates/{collections-agent/agents/collections-agent/channels/webhook/index.ts → bills-agent/packages/agent-runtime/src/webhook.ts} +1 -1
  108. package/templates/bills-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  109. package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  110. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  111. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  112. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  113. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  114. package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  115. package/templates/bills-agent/packages/agent-runtime/tsconfig.json +9 -0
  116. package/templates/bills-agent/vitest.config.ts +1 -1
  117. package/templates/collections-agent/README.md +8 -5
  118. package/templates/collections-agent/agents/collections-agent/.env.example +14 -0
  119. package/templates/collections-agent/agents/collections-agent/AGENTS.md +6 -4
  120. package/templates/collections-agent/agents/collections-agent/CLAUDE.md +6 -4
  121. package/templates/collections-agent/agents/collections-agent/README.md +184 -16
  122. package/templates/collections-agent/agents/collections-agent/agent.yaml +3 -3
  123. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +111 -0
  124. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1042.json +11 -0
  125. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1103.json +11 -0
  126. package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +23 -0
  127. package/templates/collections-agent/agents/collections-agent/package.json +12 -10
  128. package/templates/collections-agent/agents/collections-agent/runbook.md +52 -1
  129. package/templates/collections-agent/agents/collections-agent/src/kit.ts +265 -0
  130. package/templates/collections-agent/agents/collections-agent/test/adversarial.test.ts +9 -8
  131. package/templates/collections-agent/agents/collections-agent/test/check.test.ts +43 -1
  132. package/templates/collections-agent/agents/collections-agent/test/cli.test.ts +56 -18
  133. package/templates/collections-agent/agents/collections-agent/test/fixtures/agreed-1042-awaiting-payer.transcript.jsonl +4 -0
  134. package/templates/collections-agent/agents/collections-agent/test/scenarios.test.ts +11 -10
  135. package/templates/collections-agent/agents/collections-agent/test/webhook.test.ts +4 -7
  136. package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +271 -0
  137. package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +213 -0
  138. package/templates/collections-agent/agents/collections-agent/tsconfig.json +0 -1
  139. package/templates/collections-agent/package.json +3 -1
  140. package/templates/collections-agent/packages/agent-core/README.md +2 -0
  141. package/templates/collections-agent/packages/agent-core/package.json +1 -1
  142. package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
  143. package/templates/collections-agent/packages/agent-core/src/api/rail.ts +16 -0
  144. package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
  145. package/templates/collections-agent/packages/agent-core/src/approval.ts +16 -2
  146. package/templates/collections-agent/packages/agent-core/src/bundle.ts +50 -4
  147. package/templates/collections-agent/packages/agent-core/src/channels.ts +140 -0
  148. package/templates/collections-agent/packages/agent-core/src/check.ts +90 -8
  149. package/templates/collections-agent/packages/agent-core/src/clock.ts +42 -0
  150. package/templates/collections-agent/packages/agent-core/src/engine.ts +119 -18
  151. package/templates/collections-agent/packages/agent-core/src/hash.ts +13 -0
  152. package/templates/collections-agent/packages/agent-core/src/index.ts +3 -0
  153. package/templates/collections-agent/packages/agent-core/src/manifest.ts +1 -1
  154. package/templates/collections-agent/packages/agent-core/src/rail.ts +16 -2
  155. package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  156. package/templates/collections-agent/packages/agent-core/src/state-machine.ts +3 -1
  157. package/templates/collections-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
  158. package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +19 -2
  159. package/templates/collections-agent/packages/agent-core/src/types.ts +28 -0
  160. package/templates/collections-agent/packages/agent-core/test/approval.test.ts +36 -2
  161. package/templates/collections-agent/packages/agent-core/test/bundle.test.ts +85 -0
  162. package/templates/collections-agent/packages/agent-core/test/clock.test.ts +25 -0
  163. package/templates/collections-agent/packages/agent-core/test/engine.test.ts +73 -1
  164. package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  165. package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  166. package/templates/collections-agent/packages/agent-core/test/helpers.ts +1 -1
  167. package/templates/collections-agent/packages/agent-core/test/manifest.test.ts +2 -2
  168. package/templates/collections-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  169. package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +51 -0
  170. package/templates/collections-agent/packages/agent-runtime/README.md +68 -0
  171. package/templates/collections-agent/packages/agent-runtime/bin.mjs +32 -0
  172. package/templates/collections-agent/packages/agent-runtime/package.json +23 -0
  173. package/templates/collections-agent/{agents/collections-agent → packages/agent-runtime}/src/adversarial.ts +29 -50
  174. package/templates/collections-agent/packages/agent-runtime/src/agent.ts +68 -0
  175. package/templates/collections-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  176. package/templates/collections-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  177. package/templates/collections-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  178. package/templates/collections-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  179. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  180. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  181. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  182. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  183. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  184. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  185. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  186. package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  187. package/templates/collections-agent/packages/agent-runtime/src/cli.ts +98 -0
  188. package/templates/collections-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  189. package/templates/collections-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  190. package/templates/collections-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  191. package/templates/collections-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  192. package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  193. package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  194. package/templates/collections-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  195. package/templates/collections-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  196. package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  197. package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  198. package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  199. package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  200. package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  201. package/templates/collections-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  202. package/templates/collections-agent/packages/agent-runtime/src/index.ts +12 -0
  203. package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +797 -0
  204. package/templates/collections-agent/packages/agent-runtime/src/kit.ts +206 -0
  205. package/templates/collections-agent/packages/agent-runtime/src/poll.ts +105 -0
  206. package/templates/{bills-agent/agents/bills-agent → collections-agent/packages/agent-runtime}/src/scenarios.ts +98 -26
  207. package/templates/collections-agent/packages/agent-runtime/src/setup.ts +229 -0
  208. package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +154 -0
  209. package/templates/collections-agent/packages/agent-runtime/src/webhook.ts +131 -0
  210. package/templates/collections-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  211. package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  212. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  213. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  214. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  215. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  216. package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  217. package/templates/collections-agent/packages/agent-runtime/tsconfig.json +9 -0
  218. package/templates/collections-agent/vitest.config.ts +1 -1
  219. package/templates/hello-agent/LICENSE +21 -0
  220. package/templates/hello-agent/README.md +23 -0
  221. package/templates/hello-agent/_gitignore +10 -0
  222. package/templates/hello-agent/agents/hello-agent/.env.example +5 -0
  223. package/templates/hello-agent/agents/hello-agent/AGENTS.md +15 -0
  224. package/templates/hello-agent/agents/hello-agent/CLAUDE.md +15 -0
  225. package/templates/hello-agent/agents/hello-agent/README.md +33 -0
  226. package/templates/hello-agent/agents/hello-agent/SYSTEM_PROMPT.md +19 -0
  227. package/templates/hello-agent/agents/hello-agent/agent.yaml +19 -0
  228. package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.json +6 -0
  229. package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
  230. package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.json +6 -0
  231. package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.transcript.jsonl +2 -0
  232. package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.json +6 -0
  233. package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.transcript.jsonl +2 -0
  234. package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.json +6 -0
  235. package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.transcript.jsonl +2 -0
  236. package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.json +6 -0
  237. package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
  238. package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.json +6 -0
  239. package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
  240. package/templates/hello-agent/agents/hello-agent/evals/adversarial/webhook-replay.json +6 -0
  241. package/templates/hello-agent/agents/hello-agent/evals/eval.yaml +7 -0
  242. package/templates/hello-agent/agents/hello-agent/guardrails.json +8 -0
  243. package/templates/hello-agent/agents/hello-agent/mandate.example.json +17 -0
  244. package/templates/hello-agent/agents/hello-agent/package.json +19 -0
  245. package/templates/hello-agent/agents/hello-agent/runbook.md +10 -0
  246. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.json +6 -0
  247. package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.transcript.jsonl +2 -0
  248. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.json +6 -0
  249. package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
  250. package/templates/hello-agent/agents/hello-agent/src/bills.ts +23 -0
  251. package/templates/hello-agent/agents/hello-agent/src/kit.ts +33 -0
  252. package/templates/hello-agent/agents/hello-agent/tools.json +11 -0
  253. package/templates/hello-agent/agents/hello-agent/tsconfig.json +9 -0
  254. package/templates/hello-agent/package.json +30 -0
  255. package/templates/hello-agent/packages/agent-core/README.md +21 -0
  256. package/templates/hello-agent/packages/agent-core/package.json +24 -0
  257. package/templates/hello-agent/packages/agent-core/src/agent.ts +125 -0
  258. package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
  259. package/templates/hello-agent/packages/agent-core/src/api/client.ts +53 -0
  260. package/templates/hello-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
  261. package/templates/hello-agent/packages/agent-core/src/api/rail.ts +117 -0
  262. package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
  263. package/templates/hello-agent/packages/agent-core/src/approval.ts +123 -0
  264. package/templates/hello-agent/packages/agent-core/src/bundle.ts +159 -0
  265. package/templates/hello-agent/packages/agent-core/src/channels.ts +140 -0
  266. package/templates/hello-agent/packages/agent-core/src/check.ts +253 -0
  267. package/templates/hello-agent/packages/agent-core/src/clock.ts +42 -0
  268. package/templates/hello-agent/packages/agent-core/src/engine.ts +885 -0
  269. package/templates/hello-agent/packages/agent-core/src/escalate.ts +85 -0
  270. package/templates/hello-agent/packages/agent-core/src/events.ts +40 -0
  271. package/templates/hello-agent/packages/agent-core/src/guardrails.ts +45 -0
  272. package/templates/hello-agent/packages/agent-core/src/hash.ts +62 -0
  273. package/templates/hello-agent/packages/agent-core/src/ids.ts +10 -0
  274. package/templates/hello-agent/packages/agent-core/src/index.ts +32 -0
  275. package/templates/hello-agent/packages/agent-core/src/mandate.ts +100 -0
  276. package/templates/hello-agent/packages/agent-core/src/manifest.ts +76 -0
  277. package/templates/hello-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
  278. package/templates/hello-agent/packages/agent-core/src/providers/replay.ts +63 -0
  279. package/templates/hello-agent/packages/agent-core/src/providers/types.ts +39 -0
  280. package/templates/hello-agent/packages/agent-core/src/rail.ts +101 -0
  281. package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  282. package/templates/hello-agent/packages/agent-core/src/revocation.ts +30 -0
  283. package/templates/hello-agent/packages/agent-core/src/secrets.ts +30 -0
  284. package/templates/hello-agent/packages/agent-core/src/state/store.ts +307 -0
  285. package/templates/hello-agent/packages/agent-core/src/state-machine.ts +148 -0
  286. package/templates/hello-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
  287. package/templates/hello-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
  288. package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +141 -0
  289. package/templates/hello-agent/packages/agent-core/src/tools.ts +55 -0
  290. package/templates/hello-agent/packages/agent-core/src/types.ts +134 -0
  291. package/templates/hello-agent/packages/agent-core/test/approval.test.ts +117 -0
  292. package/templates/hello-agent/packages/agent-core/test/bundle.test.ts +85 -0
  293. package/templates/hello-agent/packages/agent-core/test/clock.test.ts +25 -0
  294. package/templates/hello-agent/packages/agent-core/test/engine.test.ts +596 -0
  295. package/templates/hello-agent/packages/agent-core/test/escalate.test.ts +42 -0
  296. package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  297. package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  298. package/templates/hello-agent/packages/agent-core/test/helpers.ts +139 -0
  299. package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
  300. package/templates/hello-agent/packages/agent-core/test/manifest.test.ts +45 -0
  301. package/templates/hello-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  302. package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +316 -0
  303. package/templates/hello-agent/packages/agent-core/test/secrets.test.ts +28 -0
  304. package/templates/hello-agent/packages/agent-core/test/state-machine.test.ts +67 -0
  305. package/templates/hello-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
  306. package/templates/hello-agent/packages/agent-core/tsconfig.json +10 -0
  307. package/templates/hello-agent/packages/agent-runtime/README.md +68 -0
  308. package/templates/hello-agent/packages/agent-runtime/bin.mjs +32 -0
  309. package/templates/hello-agent/packages/agent-runtime/package.json +23 -0
  310. package/templates/hello-agent/packages/agent-runtime/src/adversarial.ts +169 -0
  311. package/templates/hello-agent/packages/agent-runtime/src/agent.ts +68 -0
  312. package/templates/hello-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  313. package/templates/hello-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  314. package/templates/hello-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  315. package/templates/hello-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  316. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  317. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  318. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  319. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  320. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  321. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  322. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  323. package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  324. package/templates/hello-agent/packages/agent-runtime/src/cli.ts +98 -0
  325. package/templates/hello-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  326. package/templates/hello-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  327. package/templates/hello-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  328. package/templates/hello-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  329. package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  330. package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  331. package/templates/hello-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  332. package/templates/hello-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  333. package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  334. package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  335. package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  336. package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  337. package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  338. package/templates/hello-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  339. package/templates/hello-agent/packages/agent-runtime/src/index.ts +12 -0
  340. package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +797 -0
  341. package/templates/hello-agent/packages/agent-runtime/src/kit.ts +206 -0
  342. package/templates/hello-agent/packages/agent-runtime/src/poll.ts +105 -0
  343. package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +268 -0
  344. package/templates/hello-agent/packages/agent-runtime/src/setup.ts +229 -0
  345. package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +154 -0
  346. package/templates/hello-agent/packages/agent-runtime/src/webhook.ts +131 -0
  347. package/templates/hello-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  348. package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  349. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  350. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  351. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  352. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  353. package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  354. package/templates/hello-agent/packages/agent-runtime/tsconfig.json +9 -0
  355. package/templates/hello-agent/tsconfig.base.json +16 -0
  356. package/templates/hello-agent/vitest.config.ts +12 -0
  357. package/templates/kits.lock.json +60 -12
  358. package/templates/supplier-payments-agent/LICENSE +21 -0
  359. package/templates/supplier-payments-agent/README.md +23 -0
  360. package/templates/supplier-payments-agent/_gitignore +10 -0
  361. package/templates/supplier-payments-agent/agents/supplier-payments-agent/.env.example +7 -0
  362. package/templates/supplier-payments-agent/agents/supplier-payments-agent/AGENTS.md +21 -0
  363. package/templates/supplier-payments-agent/agents/supplier-payments-agent/CLAUDE.md +21 -0
  364. package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +118 -0
  365. package/templates/supplier-payments-agent/agents/supplier-payments-agent/SYSTEM_PROMPT.md +29 -0
  366. package/templates/supplier-payments-agent/agents/supplier-payments-agent/agent.yaml +26 -0
  367. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.json +12 -0
  368. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.transcript.jsonl +3 -0
  369. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap-mandate.json +9 -0
  370. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.json +10 -0
  371. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
  372. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.json +13 -0
  373. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.transcript.jsonl +3 -0
  374. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.json +9 -0
  375. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.transcript.jsonl +3 -0
  376. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.json +15 -0
  377. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.transcript.jsonl +6 -0
  378. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.json +10 -0
  379. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
  380. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.json +9 -0
  381. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
  382. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/webhook-replay.json +9 -0
  383. package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/eval.yaml +9 -0
  384. package/templates/supplier-payments-agent/agents/supplier-payments-agent/guardrails.json +15 -0
  385. package/templates/supplier-payments-agent/agents/supplier-payments-agent/mandate.example.json +70 -0
  386. package/templates/supplier-payments-agent/agents/supplier-payments-agent/package.json +26 -0
  387. package/templates/supplier-payments-agent/agents/supplier-payments-agent/runbook.md +19 -0
  388. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.json +14 -0
  389. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +2 -0
  390. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.json +12 -0
  391. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.transcript.jsonl +2 -0
  392. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.json +20 -0
  393. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.transcript.jsonl +7 -0
  394. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.json +19 -0
  395. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.transcript.jsonl +3 -0
  396. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.json +21 -0
  397. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.transcript.jsonl +9 -0
  398. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.json +21 -0
  399. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.transcript.jsonl +3 -0
  400. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.json +12 -0
  401. package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
  402. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +176 -0
  403. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +345 -0
  404. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/pix-out.ts +118 -0
  405. package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/payables.ts +76 -0
  406. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/adversarial.test.ts +53 -0
  407. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +384 -0
  408. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/check.test.ts +109 -0
  409. package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/scenarios.test.ts +81 -0
  410. package/templates/supplier-payments-agent/agents/supplier-payments-agent/tools.json +53 -0
  411. package/templates/supplier-payments-agent/agents/supplier-payments-agent/tsconfig.json +9 -0
  412. package/templates/supplier-payments-agent/package.json +36 -0
  413. package/templates/supplier-payments-agent/packages/agent-core/README.md +21 -0
  414. package/templates/supplier-payments-agent/packages/agent-core/package.json +24 -0
  415. package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +125 -0
  416. package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
  417. package/templates/supplier-payments-agent/packages/agent-core/src/api/client.ts +53 -0
  418. package/templates/supplier-payments-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
  419. package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +117 -0
  420. package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
  421. package/templates/supplier-payments-agent/packages/agent-core/src/approval.ts +123 -0
  422. package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +159 -0
  423. package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +140 -0
  424. package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +253 -0
  425. package/templates/supplier-payments-agent/packages/agent-core/src/clock.ts +42 -0
  426. package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +885 -0
  427. package/templates/supplier-payments-agent/packages/agent-core/src/escalate.ts +85 -0
  428. package/templates/supplier-payments-agent/packages/agent-core/src/events.ts +40 -0
  429. package/templates/supplier-payments-agent/packages/agent-core/src/guardrails.ts +45 -0
  430. package/templates/supplier-payments-agent/packages/agent-core/src/hash.ts +62 -0
  431. package/templates/supplier-payments-agent/packages/agent-core/src/ids.ts +10 -0
  432. package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +32 -0
  433. package/templates/supplier-payments-agent/packages/agent-core/src/mandate.ts +100 -0
  434. package/templates/supplier-payments-agent/packages/agent-core/src/manifest.ts +76 -0
  435. package/templates/supplier-payments-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
  436. package/templates/supplier-payments-agent/packages/agent-core/src/providers/replay.ts +63 -0
  437. package/templates/supplier-payments-agent/packages/agent-core/src/providers/types.ts +39 -0
  438. package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +101 -0
  439. package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +401 -0
  440. package/templates/supplier-payments-agent/packages/agent-core/src/revocation.ts +30 -0
  441. package/templates/supplier-payments-agent/packages/agent-core/src/secrets.ts +30 -0
  442. package/templates/supplier-payments-agent/packages/agent-core/src/state/store.ts +307 -0
  443. package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +148 -0
  444. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
  445. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
  446. package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +141 -0
  447. package/templates/supplier-payments-agent/packages/agent-core/src/tools.ts +55 -0
  448. package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +134 -0
  449. package/templates/supplier-payments-agent/packages/agent-core/test/approval.test.ts +117 -0
  450. package/templates/supplier-payments-agent/packages/agent-core/test/bundle.test.ts +85 -0
  451. package/templates/supplier-payments-agent/packages/agent-core/test/clock.test.ts +25 -0
  452. package/templates/supplier-payments-agent/packages/agent-core/test/engine.test.ts +596 -0
  453. package/templates/supplier-payments-agent/packages/agent-core/test/escalate.test.ts +42 -0
  454. package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
  455. package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
  456. package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +139 -0
  457. package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
  458. package/templates/supplier-payments-agent/packages/agent-core/test/manifest.test.ts +45 -0
  459. package/templates/supplier-payments-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
  460. package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +316 -0
  461. package/templates/supplier-payments-agent/packages/agent-core/test/secrets.test.ts +28 -0
  462. package/templates/supplier-payments-agent/packages/agent-core/test/state-machine.test.ts +67 -0
  463. package/templates/supplier-payments-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
  464. package/templates/supplier-payments-agent/packages/agent-core/tsconfig.json +10 -0
  465. package/templates/supplier-payments-agent/packages/agent-runtime/README.md +68 -0
  466. package/templates/supplier-payments-agent/packages/agent-runtime/bin.mjs +32 -0
  467. package/templates/supplier-payments-agent/packages/agent-runtime/package.json +23 -0
  468. package/templates/supplier-payments-agent/packages/agent-runtime/src/adversarial.ts +169 -0
  469. package/templates/supplier-payments-agent/packages/agent-runtime/src/agent.ts +68 -0
  470. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
  471. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/index.ts +72 -0
  472. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
  473. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/types.ts +124 -0
  474. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
  475. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
  476. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
  477. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
  478. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
  479. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
  480. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
  481. package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
  482. package/templates/supplier-payments-agent/packages/agent-runtime/src/cli.ts +98 -0
  483. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/check.ts +15 -0
  484. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
  485. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
  486. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
  487. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
  488. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
  489. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
  490. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
  491. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
  492. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
  493. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +245 -0
  494. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
  495. package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
  496. package/templates/supplier-payments-agent/packages/agent-runtime/src/default-kit.ts +83 -0
  497. package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +12 -0
  498. package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +797 -0
  499. package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +206 -0
  500. package/templates/supplier-payments-agent/packages/agent-runtime/src/poll.ts +105 -0
  501. package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +268 -0
  502. package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +229 -0
  503. package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +154 -0
  504. package/templates/supplier-payments-agent/packages/agent-runtime/src/webhook.ts +131 -0
  505. package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
  506. package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
  507. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
  508. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
  509. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
  510. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
  511. package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
  512. package/templates/supplier-payments-agent/packages/agent-runtime/tsconfig.json +9 -0
  513. package/templates/supplier-payments-agent/tsconfig.base.json +16 -0
  514. package/templates/supplier-payments-agent/vitest.config.ts +12 -0
  515. package/templates/bills-agent/agents/bills-agent/channels/terminal/index.ts +0 -108
  516. package/templates/bills-agent/agents/bills-agent/src/commands/approve.ts +0 -9
  517. package/templates/bills-agent/agents/bills-agent/src/commands/check.ts +0 -13
  518. package/templates/bills-agent/agents/bills-agent/src/commands/consent.ts +0 -26
  519. package/templates/bills-agent/agents/bills-agent/src/commands/decide.ts +0 -45
  520. package/templates/bills-agent/agents/bills-agent/src/commands/deny.ts +0 -7
  521. package/templates/bills-agent/agents/bills-agent/src/commands/eval.ts +0 -37
  522. package/templates/bills-agent/agents/bills-agent/src/commands/reconcile.ts +0 -38
  523. package/templates/bills-agent/agents/bills-agent/src/commands/rerun.ts +0 -65
  524. package/templates/bills-agent/agents/bills-agent/src/commands/resume.ts +0 -30
  525. package/templates/bills-agent/agents/bills-agent/src/main.ts +0 -185
  526. package/templates/collections-agent/agents/collections-agent/channels/terminal/index.ts +0 -178
  527. package/templates/collections-agent/agents/collections-agent/src/commands/approve.ts +0 -10
  528. package/templates/collections-agent/agents/collections-agent/src/commands/check.ts +0 -13
  529. package/templates/collections-agent/agents/collections-agent/src/commands/decide.ts +0 -48
  530. package/templates/collections-agent/agents/collections-agent/src/commands/deny.ts +0 -7
  531. package/templates/collections-agent/agents/collections-agent/src/commands/eval.ts +0 -39
  532. package/templates/collections-agent/agents/collections-agent/src/commands/poll.ts +0 -35
  533. package/templates/collections-agent/agents/collections-agent/src/commands/reconcile.ts +0 -38
  534. package/templates/collections-agent/agents/collections-agent/src/commands/rerun.ts +0 -55
  535. package/templates/collections-agent/agents/collections-agent/src/commands/resume.ts +0 -30
  536. package/templates/collections-agent/agents/collections-agent/src/commands/webhook.ts +0 -36
  537. package/templates/collections-agent/agents/collections-agent/src/main.ts +0 -193
  538. package/templates/collections-agent/agents/collections-agent/src/setup.ts +0 -250
@@ -1,17 +1,26 @@
1
1
  # collections-agent
2
2
 
3
- The merchant's agent that collects. The payer answers the message about an open agreement; the agent proposes terms inside a negotiation envelope (discount ceiling, instalments, due-date window, collection hours); on acceptance the code issues one bolepix per instalment with an idempotency key, shows the QR and the copy-and-paste in the conversation, and closes the cycle when `commerce.charge.paid` or `commerce.charge.expired` arrives: "recebemos, acordo quitado". Terminal first; WhatsApp later.
3
+ [![rail: bolepix](https://img.shields.io/badge/rail-bolepix-2E8B57)](agent.yaml) [![maturity: sandbox](https://img.shields.io/badge/maturity-sandbox-orange)](agent.yaml) [![approval: human | mandate](https://img.shields.io/badge/approval-human_%7C_mandate-555)](agent.yaml) [![charge → settled: 10 s](https://img.shields.io/badge/charge_%E2%86%92_settled-10_s-8A2BE2)](#quickstart)
4
4
 
5
- ```
5
+ The merchant's collections agent. A customer replies about an open debt; the agent proposes terms inside a negotiation envelope (maximum discount, number of instalments, due-date window, collection hours), and once the customer accepts, the code issues one bolepix per instalment, shows the QR code and the copy-and-paste Pix code in the chat, and closes the loop when the charge is paid or expires. Two channels: the terminal, and WhatsApp against a local Cloud API emulator that needs no Meta account.
6
+
7
+ ## Quickstart
8
+
9
+ Node 22.13+ and a sandbox key (`csk_test_...`) from [codespar.dev/auth/signup](https://codespar.dev/auth/signup). No money moves: a sandbox payer plays the customer's bank.
10
+
11
+ ```sh
6
12
  git clone https://github.com/codespar/agent-starter-kits && cd agent-starter-kits
7
- cp agents/collections-agent/.env.example agents/collections-agent/.env # CODESPAR_API_KEY (csk_test_...) and ANTHROPIC_API_KEY
8
- npm install && npm start --workspace=agents/collections-agent
13
+ cp agents/collections-agent/.env.example agents/collections-agent/.env # paste your csk_test_ key
14
+ npm install # at the repo root (npm workspace)
15
+ npm run start:collections
9
16
  pagador> oi, recebi a mensagem sobre o acordo do pedido 1042
10
17
  ```
11
18
 
12
- `npm install` runs at the repository root (it is an npm workspace). You type as the payer; the operator's approval, in `human` mode, is asked on the same keyboard and labelled `[operador]`.
19
+ You type as the customer. In `human` mode the operator's approval is asked on the same keyboard, labelled `[operador]`. Without a real `ANTHROPIC_API_KEY` (empty or the `.env.example` placeholder) the agent replays the recorded scenario.
13
20
 
14
- ## What it proves
21
+ Scaffold instead of cloning: `npx -y @codespar/cli@0.14.0 init my-agent --template collections-agent`.
22
+
23
+ ## What it shows
15
24
 
16
25
  | Contract | How |
17
26
  |---|---|
@@ -22,13 +31,159 @@ pagador> oi, recebi a mensagem sobre o acordo do pedido 1042
22
31
  | Two modes, one envelope | `approval: human` (default): the operator approves each issuance. `approval: mandate`: the agent issues alone inside the envelope and asks the operator above R$ 3.000,00. Same code, same states, same records. |
23
32
  | Readable refusal | Discount, instalments, due date, hours, cap, unknown debtor, revoked policy: each names itself in the trail and in the chat. |
24
33
  | Survives a restart | Kill the process after the issuance, run `npm run resume` then `npm run poll`: one charge, one settlement. |
34
+ | Closes days later, on the channel | `npm run poll -- --channel whatsapp` comes back to a conversation whose run ended, and confirms by approved template once the 24-hour window has shut. |
25
35
  | Sandbox by construction | A key that does not start with `csk_test_` fails before any network call. The sandbox payer is a test-environment route the API refuses to a live key. |
26
36
 
27
37
  ## How the loop closes: poll, and a webhook when you have one
28
38
 
29
39
  The API delivers `commerce.charge.*` through triggers to a URL. A terminal has none, so the kit's default is to LOOK: `GET /v1/charges/{id}` every three seconds (the stub's fixture, offline) through the core's `reconcile`, which is read-only on the rail and never re-issues. The first look that finds the instrument payable prints the QR (as an image, in the terminal) with the copy-and-paste under it; the look that finds it paid or expired closes the execution and tells the payer once. `npm run poll` continues after a restart or a timeout; nothing shown twice, nothing said twice, because both marks live in `state.db`.
30
40
 
31
- `channels/webhook/` is the other closer, a documented stub: the receiving contract of a trigger delivery (`X-CodeSpar-Signature: t=..,v1=..`, body `{ id, type, data: { payment_id } }`), signature verification with the trigger's secret, dedup by event id, and `npm run webhook` to run it on localhost. Registering the trigger and exposing the URL are the developer's steps (`codespar triggers create`). See `docs/OPEN_QUESTIONS.md` section 21.
41
+ The webhook is the other closer, a documented stub (`packages/agent-runtime/src/webhook.ts`, `npm run webhook`; there is no `channels/webhook/` directory, and since wave 4 `channels/` means something specific): the receiving contract of a trigger delivery (`X-CodeSpar-Signature: t=..,v1=..`, body `{ id, type, data: { payment_id } }`), signature verification with the trigger's secret, dedup by event id, and `npm run webhook` to run it on localhost. Registering the trigger and exposing the URL are the developer's steps (`codespar triggers create`). See `docs/OPEN_QUESTIONS.md` section 21.
42
+
43
+ ## The WhatsApp channel
44
+
45
+ This is the agent WhatsApp is for: the debtor answers a message, the agent
46
+ proposes terms, the payable code goes into the conversation, and "recebemos,
47
+ acordo quitado" closes it. The channel has two backends behind one interface,
48
+ and they are **the same code with a different base URL**.
49
+
50
+ The house simulator is [`dyvit-wa-sim`](https://github.com/fabianocruz/whatsapp-simulator)
51
+ (MIT), a local emulator of the WhatsApp Cloud API, published to npm as
52
+ `@dyvit/whatsapp-simulator-cli`. It is not ours and it is not a dependency:
53
+ `npm run whatsapp:emulator` fetches the pinned version with `npx` and runs it on
54
+ `127.0.0.1:4290`. Start it in one terminal, run the agent in another:
55
+
56
+ ```sh
57
+ npm run whatsapp:emulator # terminal 1
58
+ npm run start:collections -- --channel whatsapp --conversation acordo-1042
59
+ npm run start:collections -- --channel whatsapp --conversation acordo-1042 --scripted --mode mandate --simulate-payer --now 2026-09-23T14:00:00-03:00
60
+ ```
61
+
62
+ `--conversation` is required because the agent ships two, and which person you
63
+ are messaging is not a default: `acordo-1042` is Joana and ends paid,
64
+ `acordo-1103` is Ana Paula and ends expired (add `--payer expires`).
65
+
66
+ **Why somebody else's emulator instead of a fake in this repo.** A mock we
67
+ wrote would agree with us by construction — it would accept our payloads
68
+ because we wrote both sides, and the day Meta refused one we would find out in
69
+ production. This one answers `POST /v22.0/{phone-number-id}/messages` with the
70
+ Cloud API's own response shape and posts back the same signed
71
+ `x-hub-signature-256` webhooks, so what runs against it is the adapter itself.
72
+ It also has a clock we can move (`POST /_sim/clock`), which a replay finishing
73
+ in seconds cannot otherwise have. No Meta account, no credential, and no
74
+ traffic that leaves the machine. What it does NOT cover is measured, with the
75
+ exact payloads, in `docs/OPEN_QUESTIONS.md` §46 — chief among them that it
76
+ prices the 24-hour window but does not enforce it.
77
+
78
+ `--scripted` replays the debtor's turns from `channels/whatsapp/<name>.json`,
79
+ which is what an agent ships for this channel: the contact the conversation is
80
+ bound to, the agreement it may be about, and the person's turns. Each turn is
81
+ pushed through the emulator's `POST /_sim/inbound`, so a scripted turn takes
82
+ the same path a real one would — including the signature check on the way
83
+ back. The behaviour is the runner's (`packages/agent-runtime/src/channels/`);
84
+ the conversations are the agent's, and `npm run check` fails if the two
85
+ disagree in either direction.
86
+
87
+ **The rules are above the backend, so a backend is not a way around one.**
88
+ Every outbound message is checked before anything carries it: nothing outside
89
+ the collection hours (`guardrails.envelope.collection_hours`), nothing to a
90
+ contact other than the one the conversation is bound to, nothing naming
91
+ another debtor's agreement (by its alias, which is what the agent's own book calls it), and no CPF or CNPJ in a message. A refused message
92
+ is not a failed delivery — it never left the process — and it is recorded as
93
+ such in the conversation log. A Pix copy-and-paste and a boleto line are their
94
+ own message kind and are not read as prose, which is why the document rule does
95
+ not refuse the thing that pays.
96
+
97
+ **The operator is not on WhatsApp.** In `approval: human` the question is asked
98
+ on the operator's console and never in the conversation; that is not a check,
99
+ it is the wiring. One caveat, and it is a real one: an INTERACTIVE simulator
100
+ run reads both the debtor's turns and the operator's answer from the same
101
+ keyboard, so one person plays both parts. `--scripted` has no such problem,
102
+ and a scripted `human` run without `--approve` is refused rather than left
103
+ waiting.
104
+
105
+ **Going live is a base URL.** `--backend cloud-api` reads
106
+ `WHATSAPP_PHONE_NUMBER_ID`, `WHATSAPP_ACCESS_TOKEN`, `WHATSAPP_VERIFY_TOKEN`
107
+ and `WHATSAPP_APP_SECRET` from your `.env` (commented out and empty in
108
+ `.env.example`) and refuses to open without them, by name. It is the same
109
+ class the emulator runs, pointed at `graph.facebook.com` instead — which is
110
+ also how the channel decides it is live, and therefore how the
111
+ consent-evidence builder decides an act was observed by somebody.
112
+ **This repo has never run one against Meta**: the shapes are written from
113
+ Meta's published documentation, and the first live run is yours. Two pieces
114
+ are stubs and say so: template APPROVAL (a Meta Business account reviews
115
+ templates; the channel only knows the names this agent declares) and sending
116
+ the QR as an IMAGE (that needs a media upload or a public URL, and this repo
117
+ hosts neither, so the copy-and-paste goes as its own text message — which is
118
+ the string that pays; the emulator would accept the image, so that gap is
119
+ ours).
120
+
121
+ **The conversation is part of the proof.** Each run writes `channel.jsonl` into
122
+ its bundle: every message in and out, in order, with the delivery state and any
123
+ refusal, and the contact masked, because the bundle travels. Inbound lines also
124
+ carry the PROVIDER's timestamp, which is what a later process counts the
125
+ 24-hour window from — see the poll below.
126
+
127
+ ### Agreed on Tuesday, paid on Friday
128
+
129
+ The ordinary collection does not close inside the turn that issued the charge.
130
+ The debtor agrees now and pays days later, and by then WhatsApp's 24-hour
131
+ customer-service window has shut: the only thing a business may send is a
132
+ template Meta approved in advance.
133
+
134
+ ```sh
135
+ npm run poll -- --channel whatsapp --conversation acordo-1042
136
+ ```
137
+
138
+ It comes back to the conversation from the RECORD — the bundle's
139
+ `channel.jsonl` plus `state.db` — looks at the receivable the way the terminal
140
+ poll does, and puts the outcome back into that same conversation, appended
141
+ under the QR it confirms rather than into a second folder. **Free-form while
142
+ the window is open, template once it has shut**, and which of the two is the
143
+ window's decision, not the command's.
144
+
145
+ Three things it will not do. Nothing waiting for a payer is a clean no-op that
146
+ exits 0 and never opens the channel — a cron that fails on an empty queue is a
147
+ cron somebody turns off. Polling twice tells the person once, because the
148
+ cursor that says so lives in `state.db` and outlives the process. And a charge
149
+ that expired gets the expiry template, never the paid one.
150
+
151
+ Which executions belong to the conversation is decided by its `subject` — the
152
+ agreement alias it is allowed to name. That is the same rule that keeps one
153
+ debtor's agreement out of another's chat, used in the other direction.
154
+
155
+ **The templates are the agent's**, declared in
156
+ [`channels/whatsapp/templates.json`](channels/whatsapp/templates.json) with the
157
+ name, the language and the body as submitted. `npm run check` validates it, and
158
+ the channel refuses a name nobody declared, a language the template was not
159
+ registered in, and a variable count the body has no placeholders for — the
160
+ three things a local registry can see that Meta answers with a 4xx. Whether
161
+ Meta APPROVED a template is not knowable from here and stays yours.
162
+
163
+ **Consent in the conversation is wired and deliberately unused here.**
164
+ `attestation.evidence` on the consent submit accepts four keys on this channel
165
+ (`contact`, `message_id`, `session_id`, `provider_ts`) and the channel builds
166
+ exactly those — but only from a backend that talked to a real provider, which
167
+ is decided by the base URL being Meta's. An act the emulator observed was
168
+ observed by nobody, so the builder refuses and says why. This agent has no
169
+ consent step to carry it either: the collection policy is the merchant's own
170
+ file. See `docs/OPEN_QUESTIONS.md` section 43.
171
+
172
+ ### The gate
173
+
174
+ `npm run whatsapp:gate` runs the whole cycle three times from a clean state,
175
+ with nobody at a keyboard, and asserts the final state and the shape of the
176
+ conversation each time — not the wording. It needs the emulator running and
177
+ FAILS rather than skips when it is not, so the gate never passes against
178
+ nothing. It runs in the CI, which starts the emulator in its own step.
179
+
180
+ A fourth run covers the case the other three cannot reach: agree, move the
181
+ conversation's clock 26 hours, let the sandbox payer pay, poll. It asserts the
182
+ execution settled and the confirmation went out as a TEMPLATE. Read that
183
+ precisely: the emulator PRICES the 24-hour window and does not ENFORCE it
184
+ (`docs/OPEN_QUESTIONS.md` §46a), so what passes is OUR choice of carrier and
185
+ not the provider refusing the alternative. The day the emulator enforces the
186
+ window, that run gets stronger without changing.
32
187
 
33
188
  ## The sandbox payer
34
189
 
@@ -41,27 +196,30 @@ Read from `agent.yaml`, field `maturity`:
41
196
  | Capability | Maturity | Meaning |
42
197
  |---|---|---|
43
198
  | `bolepix-receivables` | sandbox | Cobranca com vencimento through the CodeSpar sandbox, paid by the sandbox payer. No real money. |
44
- | `receipt-verification` | blocked | Waits for Ed25519; and the API seals no record for a paid charge today (the paid charge as the API reports it is what the bundle keeps, marked `kind: "charge"`, unsealed). |
199
+ | `receipt-verification` | blocked | Ed25519 landed on the API's payment receipts, and this agent mints none: the API still seals no record for a paid charge, so what the bundle keeps is the paid charge as the API reports it, marked `kind: "charge"`, with no chain and no signature to check. |
45
200
 
46
201
  What the agent applies on its own (`guardrails.json`): the envelope (15% maximum discount, up to 3 instalments, due dates within 90 days, R$ 50,00 minimum instalment, collection hours 08:00–20:00 in America/Sao_Paulo), the escalation threshold (R$ 3.000,00 per agreement in `mandate`), and "the core's total wins" when the model states another.
47
202
 
48
- Out of this delivery: WhatsApp, a policy signed by the API for the receiving side (section 16 of the spec: candidate to product), `npm run inspect`, the `codespar init --template` scaffold.
203
+ Not in this kit yet: a policy signed by the API for the receiving side (section 16 of the spec, candidate to product), and a mandate born in the conversation (see the channel section below).
49
204
 
50
205
  ## Commands
51
206
 
52
207
  | Command | Does |
53
208
  |---|---|
54
209
  | `npm start` | Interactive terminal. You are the payer; the operator's approval is asked on the same keyboard. |
55
- | `npm start -- --input "oi, recebi a mensagem sobre o acordo do pedido 1042" [--approve] [--simulate-payer] [--wait 60] [--json]` | One turn, no prompt. Without `ANTHROPIC_API_KEY` it replays the recorded scenario whose first turn is that input. `--json`: machine data on stdout, people on stderr (add npm's `-s` when piping). Exit code 3 when a receivable is still waiting. |
210
+ | `npm start -- --input "oi, recebi a mensagem sobre o acordo do pedido 1042" [--approve] [--simulate-payer] [--wait 60] [--json] [--now <ISO>]` | One turn, no prompt. Without `ANTHROPIC_API_KEY` it replays the recorded scenario whose first turn is that input. `--json`: machine data on stdout, people on stderr (add npm's `-s` when piping). Exit code 3 when a receivable is still waiting. `--now 2026-09-23T14:00:00-03:00` pins the clock the guardrails read (collection hours `08:00-20:00`, the due-date window, every timestamp) instead of the wall clock; the CI gate passes it so the fixture is inside collection hours at any hour. `CODESPAR_AGENT_NOW` in the environment is the same pin and reaches every command (`approve`, `resume`, `poll`, `rerun`, `reconcile`); the flag wins when both are set. |
211
+ | `npm start -- --channel whatsapp [--scripted] [--conversation <name>] [--backend simulator\|cloud-api]` | The conversation channel. The default backend is the local emulator (`npm run whatsapp:emulator`, no Meta account and no credential); `--scripted` replays the debtor's turns from `channels/whatsapp/`. See [The WhatsApp channel](#the-whatsapp-channel). |
56
212
  | `npm start -- --scenario <name> [--mode human\|mandate] [--rail stub\|api]` | A scenario pack from `scenarios/`. With `--rail api` and a test key the charge, the poll and the sandbox payer are real, and `cycle_seconds` is measured. |
57
213
  | `npm run check` | The manifest gate: fails if the prompt, tools or guardrails contradict `agent.yaml`, if `AGENTS.md` and `CLAUDE.md` differ, or if `mcp`, `cli` or `schema` are missing. |
58
214
  | `npm run eval` | The adversarial suite (`evals/adversarial/`) and every scenario in every mode, on the replay provider and the stub rail. |
59
215
  | `npm run approve <execution-id>` / `npm run deny <execution-id>` | The operator's decision as its own command: decides an execution left in `awaiting_approval`, writes the section 4.2 artifact, runs it through the same last gate `npm start` uses, and waits for the payer (`--wait`, `--simulate-payer`). |
60
- | `npm run poll [--wait <s>] [--simulate-payer]` | Keeps looking at every receivable still waiting for its payer. Shows an instrument not shown yet, tells the payer the outcome once, fetches the paid record. |
61
- | `npm run webhook [--port 8787] [--secret <trigger secret>]` | The receiving end of `channels/webhook` on localhost. A stub: you register the trigger and expose the URL. |
216
+ | `npm run poll [--wait <s>] [--simulate-payer] [--payer pays\|expires\|never]` | Keeps looking at every receivable still waiting for its payer. Shows an instrument not shown yet, tells the payer the outcome once, fetches the paid record. `--payer` scripts the stub's fixture, which is how "nobody paid and it expired" is reachable at all: a due date passes between two runs, never inside one. |
217
+ | `npm run poll -- --channel whatsapp --conversation <name>` | The same, back in the conversation. Free-form while the 24-hour window is open, an approved template once it has shut. Nothing waiting is a clean no-op; polling twice tells the person once. See [Agreed on Tuesday, paid on Friday](#agreed-on-tuesday-paid-on-friday). |
218
+ | `npm run webhook [--port 8787] [--secret <trigger secret>]` | The receiving end of a trigger delivery, on localhost. A stub: you register the trigger and expose the URL. |
62
219
  | `npm run resume` | After a crash: dispatches only what the outbox proves was never sent, reconciles the rest from the rail. Never issues twice. |
63
220
  | `npm run rerun <run-id>` | Replays a recorded run with no network and checks the state sequence matches; the payer's behaviour (paid, expired) is read from the recording. |
64
221
  | `npm run reconcile` | Compares local state with the rail. One look, read-only; names what is waiting for a payer, what is uncertain, what record is missing locally. |
222
+ | `npm run inspect <run-id> [--json] [--html <file>]` | The proof bundle of that run read back as a timeline: who proposed what, who approved it and when (with the `items_hash` and the escalation trigger when one fired), under which version of the mandate, every state transition with its actor, which call went out under which idempotency key, what the rail answered, and which receipts came back. `--json` puts the whole report on stdout and nothing else; `--html` writes one self-contained page that opens from disk with nothing fetched. Payees are masked the way the bundle masks them, and the conversation is reported as counts, not text. |
65
223
 
66
224
  ## The proof bundle
67
225
 
@@ -73,19 +231,29 @@ approval.json the approval artifacts of the run (section 4.2 of the sp
73
231
  mandate.snapshot.json the collection policy as it was, debtors' documents masked
74
232
  events.jsonl every transition, every look, every charge event, every message to the payer, each with its actor
75
233
  receipts/ the paid charges as the API reports them, each stamped with the actor (kind: charge, unsealed)
76
- run.json mode, rail, policy id
234
+ run.json mode, rail, policy id and the version it ran under
77
235
  ```
78
236
 
79
237
  No key and no secret is written there. Documents are masked; the payer's document is never in a message.
80
238
 
81
- ## What this README declares
239
+ `verify.json` is the one file section 11 names and this repository does not
240
+ write: it is the output of `codespar audit replay`, which is not a registered
241
+ command of `@codespar/cli`, and the spec forbids a second implementation of
242
+ the hash-chain check. `npm run inspect` says so in as many words instead of
243
+ leaving the absence to be guessed at.
244
+
245
+ Read the bundle back with `npm run inspect <run-id>`: the negotiated terms,
246
+ who approved them, each receivable the rail accepted, the instrument the payer
247
+ was shown as it became payable, and what closed the cycle.
248
+
249
+ ## Limits and stubs
82
250
 
83
251
  - A policy for the receiving side, signed by the organization, does not exist in the API; the collection policy is the merchant's own file (`mandate.example.json`, in the shape of the consumer mandate, where the named entries are the debtors with an open agreement) and the envelope is the kit's code. Candidate to product (section 16 of the spec).
84
252
  - The approval artifact is signed by HMAC with a **local development key** (`.codespar/approval.key`). This is a stub: the CodeSpar API does not sign approval lists today. It proves what was approved to whoever runs the agent.
85
253
  - The API seals no record for a paid charge. The bundle keeps the paid charge as the API reports it, with `simulated: true` when the sandbox payer paid it. Nothing here is proof to anyone outside the merchant.
86
- - Revocation and the kill switch run against a **local stub** of the AgentGate (`packages/agent-core/src/stubs/agentgate.ts`); the collection policy has no API-side status to read.
254
+ - Revocation and the kill switch run against a **local stub** (`LocalMandateStatusStub` in `packages/agent-core/src/stubs/mandate-status.ts`); the collection policy has no API-side status to read.
87
255
  - The `actor` of every call is carried locally on every event, approval and record copy. The API has no `actor` field on the wire today.
88
- - Collection over WhatsApp has rules: hours, secrecy of the debt, no embarrassment, LGPD. The prompt codifies them; the envelope enforces the hours; the code never sends a document.
256
+ - Collection over WhatsApp has rules: hours, secrecy of the debt, no embarrassment, LGPD. Two of them are decidable and are code above the channel, on every backend: nothing is sent outside the collection hours, a message goes to the bound contact and to no other number, a message may not name another debtor's agreement, and a CPF or CNPJ in a message is refused. The other two are the prompt's and the operator's: no code reads a sentence and tells whether it shames somebody.
89
257
  - CodeSpar does not host or run this agent. The repository delivers it; whoever runs it, runs it.
90
258
  - What the agent issues inside the policy was authorized by the merchant, and the approval artifact proves what. The split of loss between partner, institution and CodeSpar on an authorized but wrong receivable is contractual and not yet written.
91
259
 
@@ -12,17 +12,17 @@ escalate_above:
12
12
  # the first charge to a debtor is the normal case, not a risk. No `outside_hours` either: collection hours are a LEGAL
13
13
  # rule the envelope refuses in both modes (guardrails.envelope.collection_hours), not an escalation.
14
14
  mcp: "@codespar/mcp@0.5.8"
15
- cli: "@codespar/cli@0.13.0" # the published version on 2026-09-23 (docs/OPEN_QUESTIONS.md section 1)
15
+ cli: "@codespar/cli@0.14.0" # the published version on 2026-09-23 (docs/OPEN_QUESTIONS.md section 1)
16
16
  tools: ./tools.json
17
17
  guardrails: ./guardrails.json
18
18
  mandate_schema: ./mandate.example.json
19
19
  # The API's own names (plan of 2026-09-23, section 1). `paid` and `expired` close the cycle; `cancelled` closes it as failed;
20
20
  # `created` is when a cobranca com vencimento becomes payable (the kit reads that from the status poll).
21
21
  events: [commerce.charge.created, commerce.charge.paid, commerce.charge.expired, commerce.charge.cancelled]
22
- channels: [terminal]
22
+ channels: [terminal, whatsapp] # the second channel is the one this agent is FOR; `npm run check` confirms channels/whatsapp/ ships a conversation
23
23
  maturity:
24
24
  bolepix-receivables: sandbox
25
- receipt-verification: blocked # waits for Ed25519; and the API seals no record for a paid charge today
25
+ receipt-verification: blocked # Ed25519 landed, but the API still seals no record for a paid charge: no chain, no signature to verify
26
26
  scenarios: ./scenarios/
27
27
  evals: ./evals/
28
28
  agents_md: ./AGENTS.md
@@ -0,0 +1,111 @@
1
+ # channels/whatsapp
2
+
3
+ What this agent ships for the WhatsApp channel: the CONVERSATIONS. One JSON
4
+ file each, and the file is the whole thing a runner cannot know — which
5
+ number, which debtor, which agreement, and what the person said.
6
+
7
+ The behaviour is the runner's, in
8
+ [`packages/agent-runtime/src/channels/`](../../../../packages/agent-runtime/src/channels):
9
+ the adapter, the rules, the Cloud API backend. Nothing about WhatsApp lives
10
+ here, and the emulator the backend talks to is somebody else's repository
11
+ (`npm run whatsapp:emulator`).
12
+
13
+ ## One file
14
+
15
+ ```json
16
+ {
17
+ "name": "acordo-1042",
18
+ "description": "what this conversation is",
19
+ "channel": "whatsapp",
20
+ "contact": "+5511987654321",
21
+ "subject": "acordo-1042",
22
+ "turns": [{ "text": "oi, recebi a mensagem sobre o acordo do pedido 1042" }]
23
+ }
24
+ ```
25
+
26
+ `contact` is the only number this conversation may reach: the channel refuses
27
+ an outbound message addressed anywhere else, which is how the debt stays
28
+ between the store and the person who owes it. `subject` is the only agreement
29
+ it may name, which is the same rule in the other direction. `turns` are the
30
+ PERSON's, and only the person's — what the agent answers comes from the model
31
+ or from a recorded transcript, never from here, for the same reason a scenario
32
+ pack asserts a final state rather than a wording.
33
+
34
+ `name` must match the file name, and `npm run check` fails on a file that no
35
+ longer parses, on a declared channel with no conversation, and on a
36
+ conversation the manifest does not declare.
37
+
38
+ ## And one file that is not a conversation
39
+
40
+ `templates.json` is the reserved name in this directory: the LOCAL registry of
41
+ the templates this agent sends. A conversation therefore cannot be called
42
+ `templates`.
43
+
44
+ ```json
45
+ {
46
+ "channel": "whatsapp",
47
+ "templates": [
48
+ {
49
+ "name": "acordo_quitado",
50
+ "language": "pt_BR",
51
+ "description": "what this template is for and what {{1}} means",
52
+ "body": "Oi! Recebemos o pagamento do {{1}} e ele esta quitado. Obrigado!"
53
+ }
54
+ ]
55
+ }
56
+ ```
57
+
58
+ Outside the 24 hours that follow the person's last message WhatsApp carries an
59
+ approved template and nothing else, so an agent that ever speaks after that —
60
+ and a collections agent does it constantly, because the debtor agrees on
61
+ Tuesday and pays on Friday — has to own one per outcome. `npm run poll --
62
+ --channel whatsapp` is what sends them; `src/kit.ts` maps an outcome to a name
63
+ in `outcomeTemplate`, and the language comes from here rather than from the
64
+ kit, so there is one source for it.
65
+
66
+ What this file PROVES is narrow and worth stating exactly: the agent declared
67
+ the name, so a send of a name nobody declared is refused here instead of
68
+ 400-ing at Meta, along with a language the template was not registered in and a
69
+ variable count the body has no placeholders for. Whether **Meta approved it**
70
+ is a status inside a Business account and is not knowable from this repository.
71
+ Registering the template and getting it approved is yours. `body` is here for a
72
+ reader — nothing composes a message from it, Meta holds the approved copy — but
73
+ its `{{n}}` placeholders are counted, and `npm run check` refuses a body that
74
+ skips a number.
75
+
76
+ ## The numbers and the people here are fixtures
77
+
78
+ Like `src/agreements.ts`. `+5511987654321` reaches nobody, Joana Ribeiro is
79
+ invented, and the documents in the book have valid check digits because the
80
+ clearing house validates them. Never put a real contact or a real document in
81
+ one of these files: they are committed, and the simulator does not need one.
82
+
83
+ ## Running it
84
+
85
+ ```sh
86
+ npm run whatsapp:emulator # once, at the repo root
87
+ npm start -- --channel whatsapp --conversation acordo-1042 # you type as Joana
88
+ npm start -- --channel whatsapp --conversation acordo-1042 --scripted # the turns above, replayed
89
+ npm start -- --channel whatsapp --conversation acordo-1103 --scripted --payer expires
90
+ ```
91
+
92
+ `--conversation` is required: this agent ships two, and which person you are
93
+ messaging is not a default. `acordo-1042` ends paid; `acordo-1103` is the other
94
+ ending, where nobody pays and the charge expires.
95
+
96
+ To close a cycle whose payment landed after the run ended — the ordinary case,
97
+ and the one the commands above cannot reach:
98
+
99
+ ```sh
100
+ npm run poll -- --channel whatsapp --conversation acordo-1042
101
+ ```
102
+
103
+ It resumes the conversation from the bundle plus `state.db` and confirms the
104
+ outcome: free-form while the 24-hour window is open, an approved template from
105
+ `templates.json` once it has shut.
106
+
107
+ The default backend is the local Cloud API emulator: no Meta account, no
108
+ credential, nothing leaving the machine. `npm run whatsapp:gate` at the
109
+ repository root runs the whole cycle over it three times from a clean state
110
+ and asserts the final state each time, plus a fourth run that agrees now, moves
111
+ the conversation's clock past 24 hours, pays, and polls.
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "acordo-1042",
3
+ "description": "The runbook over WhatsApp: Joana answers the message about order #1042, the agent proposes terms inside the envelope, she accepts in full, the bolepix is issued, the QR goes into the conversation with the copy-and-paste as its own message underneath, the sandbox payer pays, and the agent writes 'recebemos, acordo quitado'. The debtor's turns are here; what the agent answers is the model's, never this file.",
4
+ "channel": "whatsapp",
5
+ "contact": "+5511987654321",
6
+ "subject": "acordo-1042",
7
+ "turns": [
8
+ { "text": "oi, recebi a mensagem sobre o acordo do pedido 1042" },
9
+ { "text": "fechado, pago à vista", "after_seconds": 20 }
10
+ ]
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "acordo-1103",
3
+ "description": "The other ending, over WhatsApp: Ana Paula asks to settle order #1103, the bolepix is issued and the QR goes into the conversation, and nobody pays it. The charge expires, the execution closes as failed with reason charge_expired, no record is written, and she is told once and offered a new one. Needs the stub rail's fixture payer (`--payer expires`): the API's sandbox payer only pays.",
4
+ "channel": "whatsapp",
5
+ "contact": "+5511976543210",
6
+ "subject": "acordo-1103",
7
+ "turns": [
8
+ { "text": "oi, sou a Ana Paula, do pedido 1103, quero quitar" },
9
+ { "text": "pode emitir", "after_seconds": 15 }
10
+ ]
11
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "channel": "whatsapp",
3
+ "templates": [
4
+ {
5
+ "name": "acordo_quitado",
6
+ "language": "pt_BR",
7
+ "description": "The cycle closed with the receivable paid, told outside the 24-hour window. The normal collections case: the debtor agrees on Tuesday and pays on Friday, and by then this is the only message WhatsApp will carry. {{1}} is the agreement alias, which is also the only agreement this conversation may name.",
8
+ "body": "Oi! Recebemos o pagamento do {{1}} e ele esta quitado. Obrigado!"
9
+ },
10
+ {
11
+ "name": "acordo_cobranca_vencida",
12
+ "language": "pt_BR",
13
+ "description": "The receivable reached its due date unpaid. The same message the terminal sends free-form, and it has to be its own template: a debtor whose charge expired must not be told the agreement is settled. {{1}} is the agreement alias.",
14
+ "body": "Oi! A cobranca do {{1}} venceu sem pagamento. Se quiser, emito uma nova dentro das mesmas condicoes."
15
+ },
16
+ {
17
+ "name": "acordo_cobranca_cancelada",
18
+ "language": "pt_BR",
19
+ "description": "The receivable was cancelled, so nothing was paid and nothing is owed on it. {{1}} is the agreement alias.",
20
+ "body": "Oi! A cobranca do {{1}} foi cancelada e nada foi pago. Qualquer coisa, e so falar por aqui."
21
+ }
22
+ ]
23
+ }
@@ -6,21 +6,23 @@
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "scripts": {
9
- "start": "node --disable-warning=ExperimentalWarning --import tsx src/main.ts",
10
- "check": "node --disable-warning=ExperimentalWarning --import tsx src/commands/check.ts",
11
- "eval": "node --disable-warning=ExperimentalWarning --import tsx src/commands/eval.ts",
12
- "resume": "node --disable-warning=ExperimentalWarning --import tsx src/commands/resume.ts",
13
- "rerun": "node --disable-warning=ExperimentalWarning --import tsx src/commands/rerun.ts",
14
- "reconcile": "node --disable-warning=ExperimentalWarning --import tsx src/commands/reconcile.ts",
15
- "poll": "node --disable-warning=ExperimentalWarning --import tsx src/commands/poll.ts",
16
- "webhook": "node --disable-warning=ExperimentalWarning --import tsx src/commands/webhook.ts",
17
- "approve": "node --disable-warning=ExperimentalWarning --import tsx src/commands/approve.ts",
18
- "deny": "node --disable-warning=ExperimentalWarning --import tsx src/commands/deny.ts",
9
+ "start": "codespar-agent start",
10
+ "check": "codespar-agent check",
11
+ "inspect": "codespar-agent inspect",
12
+ "eval": "codespar-agent eval",
13
+ "resume": "codespar-agent resume",
14
+ "rerun": "codespar-agent rerun",
15
+ "reconcile": "codespar-agent reconcile",
16
+ "poll": "codespar-agent poll",
17
+ "webhook": "codespar-agent webhook",
18
+ "approve": "codespar-agent approve",
19
+ "deny": "codespar-agent deny",
19
20
  "typecheck": "tsc --noEmit -p tsconfig.json",
20
21
  "test": "vitest run --pool=forks --maxWorkers=1 --root ../.. agents/collections-agent"
21
22
  },
22
23
  "dependencies": {
23
24
  "@codespar/agent-core": "0.1.0",
25
+ "@codespar/agent-runtime": "0.1.0",
24
26
  "qrcode-terminal": "0.12.0"
25
27
  },
26
28
  "devDependencies": {
@@ -18,9 +18,60 @@ Then flip the key: `npm start --workspace=agents/collections-agent -- --mode man
18
18
 
19
19
  Without a key: `npm start --workspace=agents/collections-agent -- --scenario happy-path` runs the same script on the stub rail and the recorded model, in both modes, in under a second. `--scenario charge-expired` shows the other ending.
20
20
 
21
+ ## The same scene on WhatsApp
22
+
23
+ The terminal is where the runbook is timed, because the five-minute contract
24
+ is a terminal contract and WhatsApp is deliberately outside it. But the scene
25
+ above is a WhatsApp scene — a debtor replying to a message — so it is worth
26
+ filming on the channel it is written for:
27
+
28
+ ```sh
29
+ npm run whatsapp:emulator # terminal 1
30
+ npm run start:collections -- --channel whatsapp --conversation acordo-1042 --simulate-payer
31
+ ```
32
+
33
+ The conversation goes through a local emulator of the WhatsApp Cloud API
34
+ (`dyvit-wa-sim`, MIT, at a pinned npm version): you type as Joana, the store
35
+ answers, the copy-and-paste arrives as its own message (which is how a person
36
+ actually pays — a code inside a picture cannot be copied), and "recebemos,
37
+ acordo quitado" closes it. No Meta account, no credential. For the phone frame,
38
+ run the emulator's own web app and point it at `http://127.0.0.1:4290`. In
39
+ `approval: human` the operator's question is still on the console, labelled
40
+ `[operador]`, and never in the conversation.
41
+
42
+ The scene above closes inside one run, which is the demo and not the ordinary
43
+ week. The ordinary week is that Joana agrees today and pays on Friday, and by
44
+ then WhatsApp carries only an approved template. That take is two commands:
45
+
46
+ ```sh
47
+ npm run start:collections -- --channel whatsapp --conversation acordo-1042 # she agrees; nobody pays yet
48
+ npm run poll:collections -- --channel whatsapp --conversation acordo-1042 # days later: the payment landed
49
+ ```
50
+
51
+ The poll comes back to the conversation from the bundle plus `state.db` and
52
+ sends the confirmation as a template from
53
+ `channels/whatsapp/templates.json` — because the 24-hour window has shut. Run
54
+ it while the window is still open and it writes freely instead; which of the
55
+ two is the window's decision, not the command's. Run it twice and nothing is
56
+ sent the second time.
57
+
58
+ For a take with no typing at all, and for the CI:
59
+
60
+ ```sh
61
+ npm run whatsapp:gate # three runs from a clean state, plus the one across a shut window
62
+ ```
63
+
64
+ Measured 2026-09-24, against the emulator: three runs, `settled` each time,
65
+ one receivable, one record, two messages in and eight out, the same shape
66
+ every run. That is the
67
+ wave-4 gate — "três execuções do zero sem intervenção" — and it runs on every
68
+ pull request. The fourth run is the week above, compressed: agree, move the
69
+ conversation's clock 26 hours, pay, poll, `settled` with the confirmation
70
+ carried by the `acordo_quitado` template.
71
+
21
72
  ## Measured
22
73
 
23
- First real attempt on staging, 2026-09-23 15:10:49Z, `org_demo`: the conversation, the approval and the dispatch were real; `POST /v1/charges` answered `no_eligible_providers (eligibility_empty)` in 1.15 s because the demo org has no Celcoin connection, the only issuer of the bolepix the sandbox payer can pay. The forty seconds are proven on the stub rail and the fixture payer, not on staging. Details, request ids and the three probes in `docs/OPEN_QUESTIONS.md` section 22.
74
+ Second real run on staging, 2026-09-23 18:03:16Z, `org_demo`, replay provider, `--scenario happy-path --mode human --rail api`: **10 s from the issuance to `settled`** (create answered in 4.1 s, the instrument registered on the second look, the sandbox payer paid, the next look found `settlement: confirmed`), 15 s for the whole scenario. Charge `9fa7974e-9d1c-452e-aa01-64e9272f4f52`, execution `exe_624615ee1de452c5`. The first run of the day stopped at the issuance (no Celcoin on the demo org until ent#1613). Details, request ids and the three walls in `docs/OPEN_QUESTIONS.md` sections 22 and 31.
24
75
 
25
76
  ## Going to production
26
77