@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.
- package/README.md +44 -17
- package/dist/commands/audit-replay.js +267 -0
- package/dist/commands/audit-replay.js.map +1 -0
- package/dist/commands/init.js +28 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +2 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mandate-verify.js +75 -27
- package/dist/commands/mandate-verify.js.map +1 -1
- package/dist/config.js +17 -1
- package/dist/config.js.map +1 -1
- package/dist/did.js +262 -41
- package/dist/did.js.map +1 -1
- package/dist/index.js +33 -7
- package/dist/index.js.map +1 -1
- package/dist/surface.js +4 -1
- package/dist/surface.js.map +1 -1
- package/package.json +1 -1
- package/templates/bills-agent/README.md +8 -5
- package/templates/bills-agent/agents/bills-agent/.env.example +3 -3
- package/templates/bills-agent/agents/bills-agent/AGENTS.md +1 -1
- package/templates/bills-agent/agents/bills-agent/CLAUDE.md +1 -1
- package/templates/bills-agent/agents/bills-agent/README.md +62 -22
- package/templates/bills-agent/agents/bills-agent/SYSTEM_PROMPT.md +1 -1
- package/templates/bills-agent/agents/bills-agent/agent.yaml +2 -2
- package/templates/bills-agent/agents/bills-agent/package.json +14 -11
- package/templates/bills-agent/agents/bills-agent/src/kit.ts +193 -0
- package/templates/bills-agent/agents/bills-agent/test/adversarial.test.ts +8 -7
- package/templates/bills-agent/agents/bills-agent/test/check.test.ts +19 -2
- package/templates/bills-agent/agents/bills-agent/test/cli.test.ts +72 -24
- package/templates/bills-agent/agents/bills-agent/test/fixtures/excursao-300.transcript.jsonl +2 -0
- package/templates/bills-agent/agents/bills-agent/test/fixtures/material-400.transcript.jsonl +2 -0
- package/templates/bills-agent/agents/bills-agent/test/inspect.test.ts +124 -0
- package/templates/bills-agent/agents/bills-agent/test/provider.test.ts +25 -0
- package/templates/bills-agent/agents/bills-agent/test/scenarios.test.ts +10 -9
- package/templates/bills-agent/agents/bills-agent/tsconfig.json +0 -1
- package/templates/bills-agent/package.json +5 -2
- package/templates/bills-agent/packages/agent-core/README.md +2 -0
- package/templates/bills-agent/packages/agent-core/package.json +1 -1
- package/templates/bills-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
- package/templates/bills-agent/packages/agent-core/src/api/rail.ts +16 -0
- package/templates/bills-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
- package/templates/bills-agent/packages/agent-core/src/approval.ts +16 -2
- package/templates/bills-agent/packages/agent-core/src/bundle.ts +50 -4
- package/templates/bills-agent/packages/agent-core/src/channels.ts +140 -0
- package/templates/bills-agent/packages/agent-core/src/check.ts +90 -8
- package/templates/bills-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/bills-agent/packages/agent-core/src/engine.ts +119 -18
- package/templates/bills-agent/packages/agent-core/src/hash.ts +13 -0
- package/templates/bills-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/bills-agent/packages/agent-core/src/manifest.ts +1 -1
- package/templates/bills-agent/packages/agent-core/src/rail.ts +16 -2
- package/templates/bills-agent/packages/agent-core/src/receipt-verification.ts +401 -0
- package/templates/bills-agent/packages/agent-core/src/state-machine.ts +3 -1
- package/templates/bills-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
- package/templates/bills-agent/packages/agent-core/src/stubs/rail.ts +19 -2
- package/templates/bills-agent/packages/agent-core/src/types.ts +28 -0
- package/templates/bills-agent/packages/agent-core/test/approval.test.ts +36 -2
- package/templates/bills-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/bills-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/bills-agent/packages/agent-core/test/engine.test.ts +73 -1
- package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/bills-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/bills-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/bills-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/bills-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/bills-agent/packages/agent-core/test/receivables.test.ts +51 -0
- package/templates/bills-agent/packages/agent-runtime/README.md +68 -0
- package/templates/bills-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/bills-agent/packages/agent-runtime/package.json +23 -0
- package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/adversarial.ts +36 -44
- package/templates/bills-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/types.ts +124 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
- package/templates/bills-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
- package/templates/bills-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/start.ts +245 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
- package/templates/bills-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
- package/templates/bills-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/bills-agent/packages/agent-runtime/src/index.ts +12 -0
- package/templates/bills-agent/packages/agent-runtime/src/inspect.ts +797 -0
- package/templates/bills-agent/packages/agent-runtime/src/kit.ts +206 -0
- package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/poll.ts +22 -11
- package/templates/{collections-agent/agents/collections-agent → bills-agent/packages/agent-runtime}/src/scenarios.ts +50 -34
- package/templates/bills-agent/{agents/bills-agent → packages/agent-runtime}/src/setup.ts +88 -66
- package/templates/bills-agent/packages/agent-runtime/src/terminal.ts +154 -0
- package/templates/{collections-agent/agents/collections-agent/channels/webhook/index.ts → bills-agent/packages/agent-runtime/src/webhook.ts} +1 -1
- package/templates/bills-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/bills-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/bills-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
- package/templates/bills-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/bills-agent/vitest.config.ts +1 -1
- package/templates/collections-agent/README.md +8 -5
- package/templates/collections-agent/agents/collections-agent/.env.example +14 -0
- package/templates/collections-agent/agents/collections-agent/AGENTS.md +6 -4
- package/templates/collections-agent/agents/collections-agent/CLAUDE.md +6 -4
- package/templates/collections-agent/agents/collections-agent/README.md +184 -16
- package/templates/collections-agent/agents/collections-agent/agent.yaml +3 -3
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/README.md +111 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1042.json +11 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/acordo-1103.json +11 -0
- package/templates/collections-agent/agents/collections-agent/channels/whatsapp/templates.json +23 -0
- package/templates/collections-agent/agents/collections-agent/package.json +12 -10
- package/templates/collections-agent/agents/collections-agent/runbook.md +52 -1
- package/templates/collections-agent/agents/collections-agent/src/kit.ts +265 -0
- package/templates/collections-agent/agents/collections-agent/test/adversarial.test.ts +9 -8
- package/templates/collections-agent/agents/collections-agent/test/check.test.ts +43 -1
- package/templates/collections-agent/agents/collections-agent/test/cli.test.ts +56 -18
- package/templates/collections-agent/agents/collections-agent/test/fixtures/agreed-1042-awaiting-payer.transcript.jsonl +4 -0
- package/templates/collections-agent/agents/collections-agent/test/scenarios.test.ts +11 -10
- package/templates/collections-agent/agents/collections-agent/test/webhook.test.ts +4 -7
- package/templates/collections-agent/agents/collections-agent/test/whatsapp-poll.test.ts +271 -0
- package/templates/collections-agent/agents/collections-agent/test/whatsapp.test.ts +213 -0
- package/templates/collections-agent/agents/collections-agent/tsconfig.json +0 -1
- package/templates/collections-agent/package.json +3 -1
- package/templates/collections-agent/packages/agent-core/README.md +2 -0
- package/templates/collections-agent/packages/agent-core/package.json +1 -1
- package/templates/collections-agent/packages/agent-core/src/api/charge-rail.ts +27 -6
- package/templates/collections-agent/packages/agent-core/src/api/rail.ts +16 -0
- package/templates/collections-agent/packages/agent-core/src/api/sandbox-payer.ts +20 -7
- package/templates/collections-agent/packages/agent-core/src/approval.ts +16 -2
- package/templates/collections-agent/packages/agent-core/src/bundle.ts +50 -4
- package/templates/collections-agent/packages/agent-core/src/channels.ts +140 -0
- package/templates/collections-agent/packages/agent-core/src/check.ts +90 -8
- package/templates/collections-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/collections-agent/packages/agent-core/src/engine.ts +119 -18
- package/templates/collections-agent/packages/agent-core/src/hash.ts +13 -0
- package/templates/collections-agent/packages/agent-core/src/index.ts +3 -0
- package/templates/collections-agent/packages/agent-core/src/manifest.ts +1 -1
- package/templates/collections-agent/packages/agent-core/src/rail.ts +16 -2
- package/templates/collections-agent/packages/agent-core/src/receipt-verification.ts +401 -0
- package/templates/collections-agent/packages/agent-core/src/state-machine.ts +3 -1
- package/templates/collections-agent/packages/agent-core/src/stubs/charge-rail.ts +2 -0
- package/templates/collections-agent/packages/agent-core/src/stubs/rail.ts +19 -2
- package/templates/collections-agent/packages/agent-core/src/types.ts +28 -0
- package/templates/collections-agent/packages/agent-core/test/approval.test.ts +36 -2
- package/templates/collections-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/collections-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/collections-agent/packages/agent-core/test/engine.test.ts +73 -1
- package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/collections-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/collections-agent/packages/agent-core/test/helpers.ts +1 -1
- package/templates/collections-agent/packages/agent-core/test/manifest.test.ts +2 -2
- package/templates/collections-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/collections-agent/packages/agent-core/test/receivables.test.ts +51 -0
- package/templates/collections-agent/packages/agent-runtime/README.md +68 -0
- package/templates/collections-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/collections-agent/packages/agent-runtime/package.json +23 -0
- package/templates/collections-agent/{agents/collections-agent → packages/agent-runtime}/src/adversarial.ts +29 -50
- package/templates/collections-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/types.ts +124 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
- package/templates/collections-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
- package/templates/collections-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/start.ts +245 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
- package/templates/collections-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
- package/templates/collections-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/collections-agent/packages/agent-runtime/src/index.ts +12 -0
- package/templates/collections-agent/packages/agent-runtime/src/inspect.ts +797 -0
- package/templates/collections-agent/packages/agent-runtime/src/kit.ts +206 -0
- package/templates/collections-agent/packages/agent-runtime/src/poll.ts +105 -0
- package/templates/{bills-agent/agents/bills-agent → collections-agent/packages/agent-runtime}/src/scenarios.ts +98 -26
- package/templates/collections-agent/packages/agent-runtime/src/setup.ts +229 -0
- package/templates/collections-agent/packages/agent-runtime/src/terminal.ts +154 -0
- package/templates/collections-agent/packages/agent-runtime/src/webhook.ts +131 -0
- package/templates/collections-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/collections-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/collections-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
- package/templates/collections-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/collections-agent/vitest.config.ts +1 -1
- package/templates/hello-agent/LICENSE +21 -0
- package/templates/hello-agent/README.md +23 -0
- package/templates/hello-agent/_gitignore +10 -0
- package/templates/hello-agent/agents/hello-agent/.env.example +5 -0
- package/templates/hello-agent/agents/hello-agent/AGENTS.md +15 -0
- package/templates/hello-agent/agents/hello-agent/CLAUDE.md +15 -0
- package/templates/hello-agent/agents/hello-agent/README.md +33 -0
- package/templates/hello-agent/agents/hello-agent/SYSTEM_PROMPT.md +19 -0
- package/templates/hello-agent/agents/hello-agent/agent.yaml +19 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/exfiltration.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/false-authority.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/fractioning.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/evals/adversarial/webhook-replay.json +6 -0
- package/templates/hello-agent/agents/hello-agent/evals/eval.yaml +7 -0
- package/templates/hello-agent/agents/hello-agent/guardrails.json +8 -0
- package/templates/hello-agent/agents/hello-agent/mandate.example.json +17 -0
- package/templates/hello-agent/agents/hello-agent/package.json +19 -0
- package/templates/hello-agent/agents/hello-agent/runbook.md +10 -0
- package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.json +6 -0
- package/templates/hello-agent/agents/hello-agent/scenarios/happy-path.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.json +6 -0
- package/templates/hello-agent/agents/hello-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
- package/templates/hello-agent/agents/hello-agent/src/bills.ts +23 -0
- package/templates/hello-agent/agents/hello-agent/src/kit.ts +33 -0
- package/templates/hello-agent/agents/hello-agent/tools.json +11 -0
- package/templates/hello-agent/agents/hello-agent/tsconfig.json +9 -0
- package/templates/hello-agent/package.json +30 -0
- package/templates/hello-agent/packages/agent-core/README.md +21 -0
- package/templates/hello-agent/packages/agent-core/package.json +24 -0
- package/templates/hello-agent/packages/agent-core/src/agent.ts +125 -0
- package/templates/hello-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
- package/templates/hello-agent/packages/agent-core/src/api/client.ts +53 -0
- package/templates/hello-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
- package/templates/hello-agent/packages/agent-core/src/api/rail.ts +117 -0
- package/templates/hello-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
- package/templates/hello-agent/packages/agent-core/src/approval.ts +123 -0
- package/templates/hello-agent/packages/agent-core/src/bundle.ts +159 -0
- package/templates/hello-agent/packages/agent-core/src/channels.ts +140 -0
- package/templates/hello-agent/packages/agent-core/src/check.ts +253 -0
- package/templates/hello-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/hello-agent/packages/agent-core/src/engine.ts +885 -0
- package/templates/hello-agent/packages/agent-core/src/escalate.ts +85 -0
- package/templates/hello-agent/packages/agent-core/src/events.ts +40 -0
- package/templates/hello-agent/packages/agent-core/src/guardrails.ts +45 -0
- package/templates/hello-agent/packages/agent-core/src/hash.ts +62 -0
- package/templates/hello-agent/packages/agent-core/src/ids.ts +10 -0
- package/templates/hello-agent/packages/agent-core/src/index.ts +32 -0
- package/templates/hello-agent/packages/agent-core/src/mandate.ts +100 -0
- package/templates/hello-agent/packages/agent-core/src/manifest.ts +76 -0
- package/templates/hello-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
- package/templates/hello-agent/packages/agent-core/src/providers/replay.ts +63 -0
- package/templates/hello-agent/packages/agent-core/src/providers/types.ts +39 -0
- package/templates/hello-agent/packages/agent-core/src/rail.ts +101 -0
- package/templates/hello-agent/packages/agent-core/src/receipt-verification.ts +401 -0
- package/templates/hello-agent/packages/agent-core/src/revocation.ts +30 -0
- package/templates/hello-agent/packages/agent-core/src/secrets.ts +30 -0
- package/templates/hello-agent/packages/agent-core/src/state/store.ts +307 -0
- package/templates/hello-agent/packages/agent-core/src/state-machine.ts +148 -0
- package/templates/hello-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
- package/templates/hello-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
- package/templates/hello-agent/packages/agent-core/src/stubs/rail.ts +141 -0
- package/templates/hello-agent/packages/agent-core/src/tools.ts +55 -0
- package/templates/hello-agent/packages/agent-core/src/types.ts +134 -0
- package/templates/hello-agent/packages/agent-core/test/approval.test.ts +117 -0
- package/templates/hello-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/hello-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/hello-agent/packages/agent-core/test/engine.test.ts +596 -0
- package/templates/hello-agent/packages/agent-core/test/escalate.test.ts +42 -0
- package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/hello-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/hello-agent/packages/agent-core/test/helpers.ts +139 -0
- package/templates/hello-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
- package/templates/hello-agent/packages/agent-core/test/manifest.test.ts +45 -0
- package/templates/hello-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/hello-agent/packages/agent-core/test/receivables.test.ts +316 -0
- package/templates/hello-agent/packages/agent-core/test/secrets.test.ts +28 -0
- package/templates/hello-agent/packages/agent-core/test/state-machine.test.ts +67 -0
- package/templates/hello-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
- package/templates/hello-agent/packages/agent-core/tsconfig.json +10 -0
- package/templates/hello-agent/packages/agent-runtime/README.md +68 -0
- package/templates/hello-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/hello-agent/packages/agent-runtime/package.json +23 -0
- package/templates/hello-agent/packages/agent-runtime/src/adversarial.ts +169 -0
- package/templates/hello-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/types.ts +124 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
- package/templates/hello-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
- package/templates/hello-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/start.ts +245 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
- package/templates/hello-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
- package/templates/hello-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/hello-agent/packages/agent-runtime/src/index.ts +12 -0
- package/templates/hello-agent/packages/agent-runtime/src/inspect.ts +797 -0
- package/templates/hello-agent/packages/agent-runtime/src/kit.ts +206 -0
- package/templates/hello-agent/packages/agent-runtime/src/poll.ts +105 -0
- package/templates/hello-agent/packages/agent-runtime/src/scenarios.ts +268 -0
- package/templates/hello-agent/packages/agent-runtime/src/setup.ts +229 -0
- package/templates/hello-agent/packages/agent-runtime/src/terminal.ts +154 -0
- package/templates/hello-agent/packages/agent-runtime/src/webhook.ts +131 -0
- package/templates/hello-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/hello-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/hello-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
- package/templates/hello-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/hello-agent/tsconfig.base.json +16 -0
- package/templates/hello-agent/vitest.config.ts +12 -0
- package/templates/kits.lock.json +60 -12
- package/templates/supplier-payments-agent/LICENSE +21 -0
- package/templates/supplier-payments-agent/README.md +23 -0
- package/templates/supplier-payments-agent/_gitignore +10 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/.env.example +7 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/AGENTS.md +21 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/CLAUDE.md +21 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/README.md +118 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/SYSTEM_PROMPT.md +29 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/agent.yaml +26 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.json +12 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/batch-tampering.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap-mandate.json +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.json +10 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/beneficiary-swap.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.json +13 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/exfiltration.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.json +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/false-authority.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.json +15 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/fractioning.transcript.jsonl +6 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.json +10 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/model-total.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.json +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/prompt-injection.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/adversarial/webhook-replay.json +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/evals/eval.yaml +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/guardrails.json +15 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/mandate.example.json +70 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/package.json +26 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/runbook.md +19 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.json +14 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/beneficiary-not-allowed.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.json +12 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/cap-exceeded.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.json +20 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/escalated-above-threshold.transcript.jsonl +7 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.json +19 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/happy-path.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.json +21 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/mandate-revoked.transcript.jsonl +9 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.json +21 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/partial-batch-failure.transcript.jsonl +3 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.json +12 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/scenarios/prompt-injection.transcript.jsonl +2 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/kit.ts +176 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/batch-payout.ts +345 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/modules/pix-out.ts +118 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/src/payables.ts +76 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/adversarial.test.ts +53 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/batch.test.ts +384 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/check.test.ts +109 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/test/scenarios.test.ts +81 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/tools.json +53 -0
- package/templates/supplier-payments-agent/agents/supplier-payments-agent/tsconfig.json +9 -0
- package/templates/supplier-payments-agent/package.json +36 -0
- package/templates/supplier-payments-agent/packages/agent-core/README.md +21 -0
- package/templates/supplier-payments-agent/packages/agent-core/package.json +24 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/agent.ts +125 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/charge-rail.ts +175 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/client.ts +53 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/mandate-status.ts +58 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/rail.ts +117 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/api/sandbox-payer.ts +58 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/approval.ts +123 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/bundle.ts +159 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/channels.ts +140 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/check.ts +253 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/clock.ts +42 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/engine.ts +885 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/escalate.ts +85 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/events.ts +40 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/guardrails.ts +45 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/hash.ts +62 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/ids.ts +10 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/index.ts +32 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/mandate.ts +100 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/manifest.ts +76 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/providers/anthropic.ts +76 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/providers/replay.ts +63 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/providers/types.ts +39 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/rail.ts +101 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/receipt-verification.ts +401 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/revocation.ts +30 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/secrets.ts +30 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/state/store.ts +307 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/state-machine.ts +148 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/charge-rail.ts +195 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/mandate-status.ts +57 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/stubs/rail.ts +141 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/tools.ts +55 -0
- package/templates/supplier-payments-agent/packages/agent-core/src/types.ts +134 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/approval.test.ts +117 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/bundle.test.ts +85 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/clock.test.ts +25 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/engine.test.ts +596 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/escalate.test.ts +42 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt-keys.json +18 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/fixtures/staging-receipt.json +24 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/helpers.ts +139 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/mandate-status.test.ts +153 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/manifest.test.ts +45 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receipt-verification.test.ts +316 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/receivables.test.ts +316 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/secrets.test.ts +28 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/state-machine.test.ts +67 -0
- package/templates/supplier-payments-agent/packages/agent-core/test/transitions.type-test.ts +59 -0
- package/templates/supplier-payments-agent/packages/agent-core/tsconfig.json +10 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/README.md +68 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/bin.mjs +32 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/package.json +23 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/adversarial.ts +169 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/agent.ts +68 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/contact.ts +13 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/index.ts +72 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/rules.ts +120 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/types.ts +124 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/cloud-api.ts +358 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/emulator.ts +206 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/evidence.ts +109 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/index.ts +225 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/open.ts +143 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/present.ts +47 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/run.ts +113 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/channels/whatsapp/session.ts +113 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/cli.ts +98 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/check.ts +15 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/decide.ts +63 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/eval.ts +58 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/inspect.ts +100 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll-whatsapp.ts +317 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/poll.ts +144 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/reconcile.ts +42 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/rerun.ts +86 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/resume.ts +43 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start-whatsapp.ts +131 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/start.ts +245 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/verify.ts +129 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/commands/webhook.ts +39 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/default-kit.ts +83 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/index.ts +12 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/inspect.ts +797 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/kit.ts +206 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/poll.ts +105 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/scenarios.ts +268 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/setup.ts +229 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/terminal.ts +154 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/src/webhook.ts +131 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/inspect.test.ts +336 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/verify-cli.test.ts +127 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-cloud-api.test.ts +232 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-emulator.integration.test.ts +204 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-evidence.test.ts +94 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-rules.test.ts +174 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/test/whatsapp-session.test.ts +135 -0
- package/templates/supplier-payments-agent/packages/agent-runtime/tsconfig.json +9 -0
- package/templates/supplier-payments-agent/tsconfig.base.json +16 -0
- package/templates/supplier-payments-agent/vitest.config.ts +12 -0
- package/templates/bills-agent/agents/bills-agent/channels/terminal/index.ts +0 -108
- package/templates/bills-agent/agents/bills-agent/src/commands/approve.ts +0 -9
- package/templates/bills-agent/agents/bills-agent/src/commands/check.ts +0 -13
- package/templates/bills-agent/agents/bills-agent/src/commands/consent.ts +0 -26
- package/templates/bills-agent/agents/bills-agent/src/commands/decide.ts +0 -45
- package/templates/bills-agent/agents/bills-agent/src/commands/deny.ts +0 -7
- package/templates/bills-agent/agents/bills-agent/src/commands/eval.ts +0 -37
- package/templates/bills-agent/agents/bills-agent/src/commands/reconcile.ts +0 -38
- package/templates/bills-agent/agents/bills-agent/src/commands/rerun.ts +0 -65
- package/templates/bills-agent/agents/bills-agent/src/commands/resume.ts +0 -30
- package/templates/bills-agent/agents/bills-agent/src/main.ts +0 -185
- package/templates/collections-agent/agents/collections-agent/channels/terminal/index.ts +0 -178
- package/templates/collections-agent/agents/collections-agent/src/commands/approve.ts +0 -10
- package/templates/collections-agent/agents/collections-agent/src/commands/check.ts +0 -13
- package/templates/collections-agent/agents/collections-agent/src/commands/decide.ts +0 -48
- package/templates/collections-agent/agents/collections-agent/src/commands/deny.ts +0 -7
- package/templates/collections-agent/agents/collections-agent/src/commands/eval.ts +0 -39
- package/templates/collections-agent/agents/collections-agent/src/commands/poll.ts +0 -35
- package/templates/collections-agent/agents/collections-agent/src/commands/reconcile.ts +0 -38
- package/templates/collections-agent/agents/collections-agent/src/commands/rerun.ts +0 -55
- package/templates/collections-agent/agents/collections-agent/src/commands/resume.ts +0 -30
- package/templates/collections-agent/agents/collections-agent/src/commands/webhook.ts +0 -36
- package/templates/collections-agent/agents/collections-agent/src/main.ts +0 -193
- package/templates/collections-agent/agents/collections-agent/src/setup.ts +0 -250
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `npm run check`: the manifest is the index, and the files it points to
|
|
3
3
|
* must agree with it. Fails on a contradiction between `agent.yaml` and
|
|
4
|
-
* `SYSTEM_PROMPT.md`, `tools.json
|
|
5
|
-
* and `CLAUDE.md` diverging, and on a missing `mcp`, `cli` or
|
|
4
|
+
* `SYSTEM_PROMPT.md`, `tools.json`, `guardrails.json` or `channels/`, on
|
|
5
|
+
* `AGENTS.md` and `CLAUDE.md` diverging, and on a missing `mcp`, `cli` or
|
|
6
|
+
* `schema`.
|
|
6
7
|
*/
|
|
7
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
8
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
8
9
|
import { join } from "node:path";
|
|
9
10
|
import { parse as parseYaml } from "yaml";
|
|
11
|
+
import { ConversationScriptSchema, TemplateRegistrySchema, TEMPLATE_REGISTRY_FILE, templateArity } from "./channels.js";
|
|
10
12
|
import { GuardrailsSchema } from "./guardrails.js";
|
|
11
13
|
import { loadManifest, ManifestSchema, type LoadedManifest } from "./manifest.js";
|
|
12
14
|
import { MandateSchema } from "./mandate.js";
|
|
@@ -58,6 +60,9 @@ export function checkAgent(agentDir: string): CheckReport {
|
|
|
58
60
|
|
|
59
61
|
// tools.json
|
|
60
62
|
let toolNames: string[] = [];
|
|
63
|
+
// Hoisted: the receipt-verification rule below needs it, and only a payment
|
|
64
|
+
// seals a receipt.
|
|
65
|
+
let hasPayment = false;
|
|
61
66
|
const toolsPath = loaded.resolvePath(manifest.tools);
|
|
62
67
|
if (!existsSync(toolsPath)) error("tools_missing", `${manifest.tools} does not exist`);
|
|
63
68
|
else {
|
|
@@ -65,7 +70,7 @@ export function checkAgent(agentDir: string): CheckReport {
|
|
|
65
70
|
if (!parsed.success) error("tools_invalid", parsed.error.message);
|
|
66
71
|
else {
|
|
67
72
|
toolNames = [...parsed.data.meta_tools, ...parsed.data.local_tools].map((t) => t.name);
|
|
68
|
-
|
|
73
|
+
hasPayment = parsed.data.meta_tools.some((t) => t.effect === "payment");
|
|
69
74
|
const declaresPixOut = manifest.maturity["pix-out"] !== undefined;
|
|
70
75
|
if (declaresPixOut && !hasPayment) error("tools_contradict_manifest", "agent.yaml declares pix-out maturity but tools.json has no payment meta-tool");
|
|
71
76
|
if (!declaresPixOut && hasPayment) error("tools_contradict_manifest", "tools.json has a payment meta-tool but agent.yaml declares no pix-out maturity");
|
|
@@ -92,6 +97,55 @@ export function checkAgent(agentDir: string): CheckReport {
|
|
|
92
97
|
}
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
// channels: the declaration and what the agent ships, checked BOTH ways.
|
|
101
|
+
//
|
|
102
|
+
// A channel is the runner's, but the conversations are the agent's, so
|
|
103
|
+
// `channels: [terminal, whatsapp]` is a claim about files. Declaring
|
|
104
|
+
// whatsapp without shipping a conversation gives a reader a channel that
|
|
105
|
+
// cannot be driven; shipping one without declaring it hides a surface the
|
|
106
|
+
// agent answers on. Both are errors, and a script that no longer parses is
|
|
107
|
+
// one too, because the simulator and this check read the same schema.
|
|
108
|
+
if (!manifest.channels.includes("terminal")) {
|
|
109
|
+
error("channels_terminal_missing", "agent.yaml must declare the terminal channel: `npm start` opens it and it needs no account");
|
|
110
|
+
}
|
|
111
|
+
// `templates.json` is the one file in there that is NOT a conversation: it
|
|
112
|
+
// is the local registry of the templates the agent declares it sends, which
|
|
113
|
+
// is what makes "this name was never registered here" a refusal the channel
|
|
114
|
+
// can make instead of a 400 from Meta. A conversation therefore cannot be
|
|
115
|
+
// called `templates`, and this is the only place that says so.
|
|
116
|
+
const whatsappDir = join(agentDir, "channels", "whatsapp");
|
|
117
|
+
const scripts = existsSync(whatsappDir) ? readdirSync(whatsappDir).filter((f) => f.endsWith(".json") && f !== TEMPLATE_REGISTRY_FILE).sort() : [];
|
|
118
|
+
if (manifest.channels.includes("whatsapp") && scripts.length === 0) {
|
|
119
|
+
error("channels_not_shipped", "agent.yaml declares the whatsapp channel but channels/whatsapp/ ships no conversation for the simulator to drive");
|
|
120
|
+
}
|
|
121
|
+
if (!manifest.channels.includes("whatsapp") && scripts.length > 0) {
|
|
122
|
+
error("channels_undeclared", `channels/whatsapp/ ships ${scripts.length} conversation(s) but agent.yaml does not declare the whatsapp channel`);
|
|
123
|
+
}
|
|
124
|
+
for (const file of scripts) {
|
|
125
|
+
const parsed = ConversationScriptSchema.safeParse(JSON.parse(readFileSync(join(whatsappDir, file), "utf8")));
|
|
126
|
+
if (!parsed.success) error("channels_script_invalid", `channels/whatsapp/${file}: ${parsed.error.message}`);
|
|
127
|
+
else if (parsed.data.name !== file.replace(/\.json$/, "")) error("channels_script_invalid", `channels/whatsapp/${file} declares name ${parsed.data.name}`);
|
|
128
|
+
}
|
|
129
|
+
const registryPath = join(whatsappDir, TEMPLATE_REGISTRY_FILE);
|
|
130
|
+
if (existsSync(registryPath)) {
|
|
131
|
+
const parsed = TemplateRegistrySchema.safeParse(JSON.parse(readFileSync(registryPath, "utf8")));
|
|
132
|
+
if (!parsed.success) error("channels_templates_invalid", `channels/whatsapp/${TEMPLATE_REGISTRY_FILE}: ${parsed.error.message}`);
|
|
133
|
+
else {
|
|
134
|
+
// A body with no placeholder takes no variables, and one with `{{3}}`
|
|
135
|
+
// and no `{{2}}` cannot be filled: Meta numbers them from 1 without
|
|
136
|
+
// gaps, and a send that skips one is a 132000 nobody sees until the
|
|
137
|
+
// first real message goes out.
|
|
138
|
+
for (const template of parsed.data.templates) {
|
|
139
|
+
const arity = templateArity(template.body);
|
|
140
|
+
for (let n = 1; n <= arity; n += 1) {
|
|
141
|
+
if (!new RegExp(`\\{\\{\\s*${n}\\s*\\}\\}`).test(template.body)) {
|
|
142
|
+
error("channels_templates_invalid", `channels/whatsapp/${TEMPLATE_REGISTRY_FILE}: ${template.name} uses {{${arity}}} but never {{${n}}}; Meta numbers variables from 1 with no gaps`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
95
149
|
// mandate.example.json
|
|
96
150
|
const mandatePath = loaded.resolvePath(manifest.mandate_schema);
|
|
97
151
|
if (!existsSync(mandatePath)) error("mandate_missing", `${manifest.mandate_schema} does not exist`);
|
|
@@ -139,7 +193,23 @@ export function checkAgent(agentDir: string): CheckReport {
|
|
|
139
193
|
}
|
|
140
194
|
}
|
|
141
195
|
|
|
142
|
-
// Wording the
|
|
196
|
+
// Wording the docs must not carry UNQUALIFIED (section 6).
|
|
197
|
+
//
|
|
198
|
+
// Until ent#1633 the phrase was forbidden outright, because nothing in the
|
|
199
|
+
// product supported it. A receipt sealed since then carries an Ed25519
|
|
200
|
+
// signature over `codespar-receipt:v1:<id>:<chain>` that anybody can check
|
|
201
|
+
// against the published key set, so the claim is now true — of that, and of
|
|
202
|
+
// nothing else here. Every receipt sealed BEFORE the change carries no such
|
|
203
|
+
// signature and never will, and the approval artifact is still HMAC with a
|
|
204
|
+
// local development key.
|
|
205
|
+
//
|
|
206
|
+
// So the rule is no longer "never write it". It is two conditions, and an
|
|
207
|
+
// agent has to meet both. The agent must actually MINT a receipt that
|
|
208
|
+
// carries the seal — only a payment does, and `maturity` is where the agent
|
|
209
|
+
// says so — and the doc must NAME the mechanism, which is the word that
|
|
210
|
+
// tells a reader which of the two claims is being made.
|
|
211
|
+
const verificationMaturity = manifest.maturity["receipt-verification"];
|
|
212
|
+
const sealsVerifiableReceipts = hasPayment && verificationMaturity !== undefined && verificationMaturity !== "blocked";
|
|
143
213
|
for (const file of ["README.md", "runbook.md", "SYSTEM_PROMPT.md"]) {
|
|
144
214
|
const path = join(agentDir, file);
|
|
145
215
|
if (!existsSync(path)) {
|
|
@@ -147,8 +217,12 @@ export function checkAgent(agentDir: string): CheckReport {
|
|
|
147
217
|
continue;
|
|
148
218
|
}
|
|
149
219
|
const text = readFileSync(path, "utf8").toLowerCase();
|
|
150
|
-
|
|
151
|
-
|
|
220
|
+
const claims = text.includes("verificável por terceiro") || text.includes("verifiable by a third party") || text.includes("third-party verifiable");
|
|
221
|
+
if (!claims) continue;
|
|
222
|
+
if (!sealsVerifiableReceipts) {
|
|
223
|
+
error("doc_overclaims", `${file} claims third-party verifiability, and this agent seals nothing that carries it: only a payment receipt gets an Ed25519 signature, and agent.yaml declares receipt-verification as \`${verificationMaturity ?? "absent"}\``);
|
|
224
|
+
} else if (!text.includes("ed25519")) {
|
|
225
|
+
error("doc_overclaims", `${file} claims third-party verifiability without naming Ed25519; the receipt's asymmetric seal is the only thing here a third party can check, and receipts sealed before it — and the approval artifact — are HMAC`);
|
|
152
226
|
}
|
|
153
227
|
}
|
|
154
228
|
|
|
@@ -165,7 +239,15 @@ export function checkAgent(agentDir: string): CheckReport {
|
|
|
165
239
|
if (!keys.includes("CODESPAR_API_KEY") || !keys.includes("ANTHROPIC_API_KEY")) error("env_example_incomplete", ".env.example must declare CODESPAR_API_KEY and ANTHROPIC_API_KEY");
|
|
166
240
|
}
|
|
167
241
|
|
|
168
|
-
|
|
242
|
+
// `receipt-verification` used to be a warning at `live`, because Ed25519 did
|
|
243
|
+
// not exist. It does (ent#1633), so what is left to check is the coherence
|
|
244
|
+
// the other maturity rules check: only a PAYMENT seals a receipt. A paid
|
|
245
|
+
// charge is reported by the API with no chain and no signature, so an agent
|
|
246
|
+
// that issues receivables and declares this capability beyond `blocked` is
|
|
247
|
+
// claiming a verification its records cannot carry.
|
|
248
|
+
if (verificationMaturity !== undefined && verificationMaturity !== "blocked" && !hasPayment) {
|
|
249
|
+
error("maturity_overclaims", "agent.yaml declares receipt-verification beyond `blocked` and tools.json has no payment meta-tool; only a payment seals a receipt, and a paid charge carries no signature to verify");
|
|
250
|
+
}
|
|
169
251
|
|
|
170
252
|
return { ok: findings.every((f) => f.level !== "error"), agent: manifest.name, findings };
|
|
171
253
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A clock pinned to an instant the caller chose, for a run whose outcome must
|
|
3
|
+
* not depend on the hour it happens to execute at (the CI, a demo, a test).
|
|
4
|
+
* `ExecutionEngine`, the stubs, the status gate and the loop all take a
|
|
5
|
+
* `clock` dependency; this is the one the one-shot runner hands them when
|
|
6
|
+
* `--now` or `CODESPAR_AGENT_NOW` is set. The scenario runner freezes its own
|
|
7
|
+
* clock the same way.
|
|
8
|
+
*
|
|
9
|
+
* The clock advances one second per read so no two events share an instant,
|
|
10
|
+
* which is what the scenario runner does too.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export const FIXED_CLOCK_ENV = "CODESPAR_AGENT_NOW";
|
|
14
|
+
|
|
15
|
+
export class InvalidFixedClockError extends Error {
|
|
16
|
+
constructor(value: string, source: string) {
|
|
17
|
+
super(`${source} must be an ISO 8601 instant (e.g. 2026-09-23T14:00:00-03:00), got "${value}"`);
|
|
18
|
+
this.name = "InvalidFixedClockError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** A clock that starts at `iso` and ticks one second per read. Throws on a value `Date` cannot parse. */
|
|
23
|
+
export function fixedClock(iso: string, source = "--now"): () => Date {
|
|
24
|
+
const start = new Date(iso);
|
|
25
|
+
if (!/^\d{4}-\d{2}-\d{2}T/.test(iso.trim()) || Number.isNaN(start.getTime())) throw new InvalidFixedClockError(iso, source);
|
|
26
|
+
let current = start.getTime() - 1000;
|
|
27
|
+
return () => {
|
|
28
|
+
current += 1000;
|
|
29
|
+
return new Date(current);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The clock a command runs with: the `--now` flag, else `CODESPAR_AGENT_NOW`
|
|
35
|
+
* from the environment, else `undefined` (the wall clock, the caller's default).
|
|
36
|
+
*/
|
|
37
|
+
export function resolveFixedClock(flag: string | undefined, env: NodeJS.ProcessEnv = process.env): (() => Date) | undefined {
|
|
38
|
+
if (flag !== undefined) return fixedClock(flag, "--now");
|
|
39
|
+
const fromEnv = env[FIXED_CLOCK_ENV];
|
|
40
|
+
if (fromEnv !== undefined && fromEnv.trim() !== "") return fixedClock(fromEnv, FIXED_CLOCK_ENV);
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
@@ -20,11 +20,11 @@ import { itemsHash, sha256Hex } from "./hash.js";
|
|
|
20
20
|
import { newId } from "./ids.js";
|
|
21
21
|
import { mandateExpired, payeeAllowed, resolveBeneficiary, windowCap, windowStart, type Mandate } from "./mandate.js";
|
|
22
22
|
import type { Manifest } from "./manifest.js";
|
|
23
|
-
import type { PaymentRail, RailPayment } from "./rail.js";
|
|
23
|
+
import type { PaymentRail, RailOutcome, RailPayment } from "./rail.js";
|
|
24
24
|
import type { MandateStatusReport, MandateStatusSource } from "./revocation.js";
|
|
25
25
|
import { isTerminal, transition, type Execution, type ExecutionState } from "./state-machine.js";
|
|
26
26
|
import type { StateStore } from "./state/store.js";
|
|
27
|
-
import type { Actor, ApprovalArtifact, ApprovalMode, ExecutionItem, ExecutionReason, ItemOutcome } from "./types.js";
|
|
27
|
+
import type { Actor, ApprovalArtifact, ApprovalMode, ExecutionBatch, ExecutionItem, ExecutionReason, ItemOutcome } from "./types.js";
|
|
28
28
|
|
|
29
29
|
export interface ProposedItem {
|
|
30
30
|
/** An alias from the mandate's named payees, or a raw payee key. */
|
|
@@ -54,6 +54,13 @@ export interface Proposal {
|
|
|
54
54
|
items: ProposedItem[];
|
|
55
55
|
/** What the model said the total was. Recorded; never used to pay. */
|
|
56
56
|
claimed_total?: number;
|
|
57
|
+
/**
|
|
58
|
+
* The batch this proposal is one line of, when it is one. The kit computes
|
|
59
|
+
* it once over the whole ordered list before drafting any of it; the core
|
|
60
|
+
* stamps it on the execution and every artifact of that execution carries
|
|
61
|
+
* it. The core never invents one and never fills one in.
|
|
62
|
+
*/
|
|
63
|
+
batch?: ExecutionBatch;
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
export type DraftResult =
|
|
@@ -119,6 +126,7 @@ export class ExecutionEngine {
|
|
|
119
126
|
|
|
120
127
|
const items = proposal.items.map((p) => this.resolveItem(p));
|
|
121
128
|
const total = items.reduce((sum, i) => sum + i.amount, 0);
|
|
129
|
+
if (proposal.batch) assertBatchBinding(proposal.batch);
|
|
122
130
|
const id = newId("exe");
|
|
123
131
|
const execution: Execution<"drafted"> = {
|
|
124
132
|
id,
|
|
@@ -131,6 +139,7 @@ export class ExecutionEngine {
|
|
|
131
139
|
currency: this.deps.mandate.currency,
|
|
132
140
|
...(proposal.claimed_total !== undefined ? { model_claimed_total: proposal.claimed_total } : {}),
|
|
133
141
|
items_hash: itemsHash(items),
|
|
142
|
+
...(proposal.batch ? { batch: proposal.batch } : {}),
|
|
134
143
|
mandate: { id: this.deps.mandate.id, version: this.deps.mandate.version },
|
|
135
144
|
idempotency_key: `idk_${sha256Hex(`${this.deps.runId}:${id}`).slice(0, 32)}`,
|
|
136
145
|
blocking_reasons: [],
|
|
@@ -140,7 +149,7 @@ export class ExecutionEngine {
|
|
|
140
149
|
updated_at: now.toISOString(),
|
|
141
150
|
};
|
|
142
151
|
this.deps.store.saveExecution(execution);
|
|
143
|
-
this.record("execution.drafted", id, { items: execution.items, total, model_claimed_total: proposal.claimed_total ?? null, mode: this.deps.mode });
|
|
152
|
+
this.record("execution.drafted", id, { items: execution.items, total, model_claimed_total: proposal.claimed_total ?? null, mode: this.deps.mode, batch: execution.batch ?? null });
|
|
144
153
|
|
|
145
154
|
return { ok: true, execution: await this.evaluateDraft(execution) };
|
|
146
155
|
}
|
|
@@ -333,20 +342,26 @@ export class ExecutionEngine {
|
|
|
333
342
|
*/
|
|
334
343
|
private async dispatch(execution: Execution<"executing">, payments: RailPayment[]): Promise<Execution> {
|
|
335
344
|
const outcomes: ItemOutcome[] = [...execution.outcomes];
|
|
345
|
+
const unknown: string[] = [];
|
|
336
346
|
this.deps.store.updateOutbox(execution.idempotency_key, "sent", undefined, this.clock().toISOString());
|
|
337
347
|
|
|
338
348
|
for (const [index, payment] of payments.entries()) {
|
|
339
349
|
if (outcomes.some((o) => o.index === index)) continue;
|
|
340
|
-
|
|
350
|
+
// The dispatch line is the request. `idempotency_key` is what makes a retry the same payment, so the bundle names it next to the attempt.
|
|
351
|
+
this.record("rail.dispatch", execution.id, { attempt_id: payment.attempt_id, payee: payment.payee, amount: payment.amount_minor, rail: this.deps.rail.name, idempotency_key: execution.idempotency_key });
|
|
341
352
|
const outcome = await this.deps.rail.pay(payment);
|
|
342
|
-
this.record("rail.outcome", execution.id, { attempt_id: payment.attempt_id, status: outcome.status, ...(outcome
|
|
353
|
+
this.record("rail.outcome", execution.id, { attempt_id: payment.attempt_id, status: outcome.status, ...railAnswer(outcome) });
|
|
343
354
|
if (outcome.status === "uncertain") {
|
|
344
355
|
this.record("rail.uncertain", execution.id, { attempt_id: payment.attempt_id, code: outcome.code, message: outcome.message });
|
|
345
|
-
|
|
356
|
+
// No outcome is recorded because there is none. The siblings are still
|
|
357
|
+
// sent: an unknown answer about THIS payee says nothing about the next
|
|
358
|
+
// one, and the execution stays open until reconciliation settles it.
|
|
359
|
+
unknown.push(`attempt ${payment.attempt_id}: ${outcome.code} — outcome unknown, kept for reconciliation`);
|
|
360
|
+
continue;
|
|
346
361
|
}
|
|
347
362
|
if (outcome.status === "failed") {
|
|
348
363
|
outcomes.push({ index, attempt_id: payment.attempt_id, status: "failed", code: outcome.code, error: `${outcome.code}: ${outcome.message}` });
|
|
349
|
-
|
|
364
|
+
continue;
|
|
350
365
|
}
|
|
351
366
|
if (outcome.status === "accepted") {
|
|
352
367
|
// A receivable was issued; the payer decides the rest. Nothing settles here.
|
|
@@ -357,21 +372,29 @@ export class ExecutionEngine {
|
|
|
357
372
|
outcomes.push({ index, attempt_id: payment.attempt_id, status: "settled", transaction_id: outcome.transaction_id, ...(outcome.receipt_id ? { receipt_id: outcome.receipt_id } : {}) });
|
|
358
373
|
await this.ingestSettlement(execution, index, payment, outcome.receipt_id, PAYMENT_SUCCEEDED);
|
|
359
374
|
}
|
|
360
|
-
return this.close({ ...execution, outcomes }, payments.length);
|
|
375
|
+
return this.close({ ...execution, outcomes }, payments.length, unknown.join("; ") || undefined);
|
|
361
376
|
}
|
|
362
377
|
|
|
363
378
|
/**
|
|
364
379
|
* Closes an `executing` execution from its recorded outcomes: stays while a
|
|
365
|
-
* receivable is accepted and unpaid,
|
|
366
|
-
* when every attempt settled
|
|
380
|
+
* receivable is accepted and unpaid, stays while any attempt has no outcome
|
|
381
|
+
* at all, failed if any attempt failed, settled when every attempt settled.
|
|
382
|
+
*
|
|
383
|
+
* The order matters. An execution does not close while one of its attempts
|
|
384
|
+
* is unknown, even when another one failed: "some of this moved and one of
|
|
385
|
+
* them we cannot see" is not a closed outcome, and closing it as `failed`
|
|
386
|
+
* would report a batch as finished while a payment may still be in flight.
|
|
367
387
|
*/
|
|
368
|
-
private close(execution: Execution<"executing">, attempts: number): Execution {
|
|
388
|
+
private close(execution: Execution<"executing">, attempts: number, unknownDetail?: string): Execution {
|
|
369
389
|
const at = this.clock().toISOString();
|
|
370
390
|
const updated: Execution<"executing"> = { ...execution, updated_at: at };
|
|
371
391
|
const accepted = execution.outcomes.filter((o) => o.status === "accepted");
|
|
372
392
|
if (accepted.length > 0) {
|
|
373
393
|
return this.leaveAwaiting(updated, `${accepted.length} receivable(s) issued and unpaid: ${accepted.map((o) => o.transaction_id ?? o.attempt_id).join(", ")}`);
|
|
374
394
|
}
|
|
395
|
+
if (execution.outcomes.length < attempts) {
|
|
396
|
+
return this.leaveUnresolved(updated, unknownDetail ?? `${execution.outcomes.length} of ${attempts} attempt(s) have an outcome`);
|
|
397
|
+
}
|
|
375
398
|
const failed = execution.outcomes.find((o) => o.status === "failed");
|
|
376
399
|
if (failed) {
|
|
377
400
|
this.deps.store.updateOutbox(execution.idempotency_key, "failed", execution.outcomes, at);
|
|
@@ -438,6 +461,7 @@ export class ExecutionEngine {
|
|
|
438
461
|
}
|
|
439
462
|
}
|
|
440
463
|
|
|
464
|
+
|
|
441
465
|
/**
|
|
442
466
|
* Fetches into the bundle the receipts of settled attempts the bundle does
|
|
443
467
|
* not hold yet (a settlement that arrived by event names a receipt id and
|
|
@@ -480,7 +504,7 @@ export class ExecutionEngine {
|
|
|
480
504
|
const prior = outcomes.find((o) => o.index === index);
|
|
481
505
|
// Settled and failed are final. An accepted receivable is looked at again: its payer may have acted.
|
|
482
506
|
if (prior && prior.status !== "accepted") continue;
|
|
483
|
-
const seen = await this.deps.rail.lookup(payment.attempt_id, payment);
|
|
507
|
+
const seen = await this.deps.rail.lookup(payment.attempt_id, payment, prior?.transaction_id);
|
|
484
508
|
const found = seen ? seen.status : "absent";
|
|
485
509
|
const stored = this.deps.store.appendEvent({
|
|
486
510
|
run_id: this.deps.runId,
|
|
@@ -494,8 +518,12 @@ export class ExecutionEngine {
|
|
|
494
518
|
if (stored) this.deps.bundle.event({ ...stored, actor: this.agentActor });
|
|
495
519
|
if (!seen || seen.status === "uncertain" || seen.status === "in_flight") {
|
|
496
520
|
if (prior) continue; // the receivable is known to exist; the rail just did not answer this time
|
|
497
|
-
|
|
498
|
-
|
|
521
|
+
// One attempt the rail cannot answer for does not stop us learning
|
|
522
|
+
// about the others. A lookup moves no money, so there is nothing to
|
|
523
|
+
// be careful about here, and stopping would mean a later attempt's
|
|
524
|
+
// settlement is never recorded at all.
|
|
525
|
+
unresolved ??= `attempt ${payment.attempt_id}: ${seen ? seen.status : "unknown to the rail"}; a human decides, nothing is re-sent`;
|
|
526
|
+
continue;
|
|
499
527
|
}
|
|
500
528
|
const replace = (outcome: ItemOutcome) => {
|
|
501
529
|
const at = outcomes.findIndex((o) => o.index === index);
|
|
@@ -509,7 +537,6 @@ export class ExecutionEngine {
|
|
|
509
537
|
}
|
|
510
538
|
if (seen.status === "failed") {
|
|
511
539
|
replace({ index, attempt_id: payment.attempt_id, status: "failed", code: seen.code, error: `${seen.code}: ${seen.message}` });
|
|
512
|
-
if (!prior) break;
|
|
513
540
|
continue;
|
|
514
541
|
}
|
|
515
542
|
replace({ index, attempt_id: payment.attempt_id, status: "settled", transaction_id: seen.transaction_id, ...(seen.receipt_id ? { receipt_id: seen.receipt_id } : {}) });
|
|
@@ -643,6 +670,27 @@ export class ExecutionEngine {
|
|
|
643
670
|
return true;
|
|
644
671
|
}
|
|
645
672
|
|
|
673
|
+
/**
|
|
674
|
+
* A durable claim for work whose unit is bigger than one execution: a batch
|
|
675
|
+
* line, a scheduled instruction. `claimed` reads which execution covers a
|
|
676
|
+
* key, `claim` records it. Same cursor table as `markShown`, which is this
|
|
677
|
+
* with a boolean answer.
|
|
678
|
+
*
|
|
679
|
+
* It exists because a tool handler's only durable surface is this engine,
|
|
680
|
+
* and a batch that must not pay the same payee twice across runs has to
|
|
681
|
+
* remember which execution already covers each line. What a held claim
|
|
682
|
+
* MEANS is the kit's to decide: the engine records the pairing and reads
|
|
683
|
+
* nothing into it, because "settled, so skip" and "denied, so retry" are
|
|
684
|
+
* the batch's rules and not the state machine's.
|
|
685
|
+
*/
|
|
686
|
+
claimed(key: string): string | undefined {
|
|
687
|
+
return this.deps.store.getCursor(`claim:${key}`);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
claim(key: string, executionId: string): void {
|
|
691
|
+
this.deps.store.setCursor(`claim:${key}`, executionId);
|
|
692
|
+
}
|
|
693
|
+
|
|
646
694
|
// ---- reads --------------------------------------------------------------
|
|
647
695
|
|
|
648
696
|
get(executionId: string): Execution | undefined {
|
|
@@ -653,6 +701,22 @@ export class ExecutionEngine {
|
|
|
653
701
|
return this.deps.store.listExecutions({ ...filter, mandate_id: this.deps.mandate.id });
|
|
654
702
|
}
|
|
655
703
|
|
|
704
|
+
/**
|
|
705
|
+
* The items `draft()` would build from these proposals, resolved against
|
|
706
|
+
* the mandate and WITHOUT the validation that refuses one. It exists for a
|
|
707
|
+
* caller that must hash a whole list before it drafts any of it — a batch
|
|
708
|
+
* computing its `batch_hash` — and it does not throw on purpose: a line the
|
|
709
|
+
* core will refuse is still a line of the presented list, and dropping it
|
|
710
|
+
* from the hash would make a batch holding a broken line hash the same as
|
|
711
|
+
* the shorter batch without it, which is the hole `batch_hash` closes.
|
|
712
|
+
*
|
|
713
|
+
* It resolves nothing the draft will not resolve identically, which is what
|
|
714
|
+
* makes the hash computed here the hash the drafts below carry.
|
|
715
|
+
*/
|
|
716
|
+
preview(items: readonly ProposedItem[]): ExecutionItem[] {
|
|
717
|
+
return items.map((p) => this.previewItem(p));
|
|
718
|
+
}
|
|
719
|
+
|
|
656
720
|
// ---- helpers ------------------------------------------------------------
|
|
657
721
|
|
|
658
722
|
/**
|
|
@@ -687,15 +751,19 @@ export class ExecutionEngine {
|
|
|
687
751
|
}
|
|
688
752
|
|
|
689
753
|
private resolveItem(proposed: ProposedItem): ExecutionItem {
|
|
690
|
-
const known = resolveBeneficiary(this.deps.mandate, proposed.payee);
|
|
691
754
|
const amount = Math.trunc(proposed.amount);
|
|
692
755
|
if (!Number.isFinite(amount) || amount <= 0) throw new Error(`amount must be a positive integer in minor units, got ${proposed.amount}`);
|
|
693
756
|
if (proposed.due_date !== undefined && !/^\d{4}-\d{2}-\d{2}$/.test(proposed.due_date)) throw new Error(`due_date must be YYYY-MM-DD, got ${proposed.due_date}`);
|
|
757
|
+
return this.previewItem(proposed);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
private previewItem(proposed: ProposedItem): ExecutionItem {
|
|
761
|
+
const known = resolveBeneficiary(this.deps.mandate, proposed.payee);
|
|
694
762
|
return {
|
|
695
763
|
...(known ? { alias: known.alias } : {}),
|
|
696
764
|
beneficiary: known?.name ?? proposed.payee,
|
|
697
765
|
payee: known?.payee ?? proposed.payee,
|
|
698
|
-
amount,
|
|
766
|
+
amount: Math.trunc(proposed.amount),
|
|
699
767
|
currency: this.deps.mandate.currency,
|
|
700
768
|
...(proposed.description ? { description: proposed.description } : {}),
|
|
701
769
|
...(proposed.due_date ? { due_date: proposed.due_date } : {}),
|
|
@@ -712,6 +780,7 @@ export class ExecutionEngine {
|
|
|
712
780
|
beneficiary: item.beneficiary,
|
|
713
781
|
purpose: this.deps.mandate.purpose,
|
|
714
782
|
agent_id: this.deps.mandate.agent_id,
|
|
783
|
+
consumer_id: this.deps.mandate.consumer_id,
|
|
715
784
|
...(item.description ? { description: item.description } : {}),
|
|
716
785
|
...(item.due_date ? { due_date: item.due_date } : {}),
|
|
717
786
|
actor: this.agentActor,
|
|
@@ -758,7 +827,7 @@ export class ExecutionEngine {
|
|
|
758
827
|
private storeApproval(artifact: ApprovalArtifact): void {
|
|
759
828
|
this.deps.store.saveApproval(artifact);
|
|
760
829
|
this.deps.bundle.approval(artifact);
|
|
761
|
-
this.record("approval.created", artifact.execution_id, { approval_id: artifact.approval_id, approver: artifact.approver, items_hash: artifact.items_hash, escalation: artifact.escalation ?? null });
|
|
830
|
+
this.record("approval.created", artifact.execution_id, { approval_id: artifact.approval_id, approver: artifact.approver, items_hash: artifact.items_hash, batch: artifact.batch ?? null, escalation: artifact.escalation ?? null });
|
|
762
831
|
}
|
|
763
832
|
|
|
764
833
|
private persist<S extends ExecutionState>(execution: Execution<S>): Execution<S> {
|
|
@@ -782,3 +851,35 @@ export class ExecutionEngine {
|
|
|
782
851
|
return execution;
|
|
783
852
|
}
|
|
784
853
|
}
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* A batch binding is the kit's to compute and the core's to refuse when it
|
|
857
|
+
* cannot be true. `index` outside `count`, or a `count` of zero, would let a
|
|
858
|
+
* bundle say "line 5 of 3" and make the "N of M" an artifact reader sees
|
|
859
|
+
* meaningless, so it is rejected where the execution is minted rather than
|
|
860
|
+
* carried into the signature.
|
|
861
|
+
*/
|
|
862
|
+
function assertBatchBinding(batch: ExecutionBatch): void {
|
|
863
|
+
if (!batch.ref.trim()) throw new Error("batch.ref must name the batch");
|
|
864
|
+
if (!batch.batch_hash.trim()) throw new Error("batch.batch_hash must be the hash of the presented lines");
|
|
865
|
+
if (!Number.isInteger(batch.count) || batch.count < 1) throw new Error(`batch.count must be a positive integer, got ${batch.count}`);
|
|
866
|
+
if (!Number.isInteger(batch.index) || batch.index < 0 || batch.index >= batch.count) {
|
|
867
|
+
throw new Error(`batch.index must be a position inside the batch (0..${batch.count - 1}), got ${batch.index}`);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* What the rail answered about one attempt, as the bundle records it: the
|
|
873
|
+
* identifiers a reader follows the money by, and never `raw`, which carries
|
|
874
|
+
* whatever the provider chose to echo back.
|
|
875
|
+
*/
|
|
876
|
+
function railAnswer(outcome: RailOutcome): Record<string, unknown> {
|
|
877
|
+
switch (outcome.status) {
|
|
878
|
+
case "accepted":
|
|
879
|
+
return { transaction_id: outcome.transaction_id, sandbox: outcome.sandbox };
|
|
880
|
+
case "settled":
|
|
881
|
+
return { transaction_id: outcome.transaction_id, receipt_id: outcome.receipt_id, money_moved: outcome.money_moved, sandbox: outcome.sandbox };
|
|
882
|
+
default:
|
|
883
|
+
return { code: outcome.code, message: outcome.message };
|
|
884
|
+
}
|
|
885
|
+
}
|
|
@@ -39,6 +39,19 @@ export function itemsHash(items: readonly ExecutionItem[]): string {
|
|
|
39
39
|
return `sha256:${sha256Hex(canonicalJson(canonical))}`;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* The hash of a batch's ordered lines, bound into every artifact of that
|
|
44
|
+
* batch. It IS `itemsHash` over the whole list and deliberately not a second
|
|
45
|
+
* canonicalisation: the same fields decide the set that decide the line, so a
|
|
46
|
+
* reader who concatenates the batch's lines in order and hashes them gets the
|
|
47
|
+
* batch's hash back, and any line moved, re-priced, added or dropped changes
|
|
48
|
+
* it. Order is part of it — `index` names a position, and a position only
|
|
49
|
+
* means something in a list whose order is fixed.
|
|
50
|
+
*/
|
|
51
|
+
export function batchHash(lines: readonly ExecutionItem[]): string {
|
|
52
|
+
return itemsHash(lines);
|
|
53
|
+
}
|
|
54
|
+
|
|
42
55
|
export function hmacSha256Hex(key: Buffer, payload: string): string {
|
|
43
56
|
return createHmac("sha256", key).update(payload).digest("hex");
|
|
44
57
|
}
|
|
@@ -5,11 +5,14 @@ export * from "./ids.js";
|
|
|
5
5
|
export * from "./approval.js";
|
|
6
6
|
export * from "./manifest.js";
|
|
7
7
|
export * from "./guardrails.js";
|
|
8
|
+
export * from "./channels.js";
|
|
8
9
|
export * from "./mandate.js";
|
|
9
10
|
export * from "./escalate.js";
|
|
11
|
+
export * from "./clock.js";
|
|
10
12
|
export * from "./secrets.js";
|
|
11
13
|
export * from "./revocation.js";
|
|
12
14
|
export * from "./rail.js";
|
|
15
|
+
export * from "./receipt-verification.js";
|
|
13
16
|
export * from "./tools.js";
|
|
14
17
|
export * from "./bundle.js";
|
|
15
18
|
export * from "./engine.js";
|
|
@@ -34,7 +34,7 @@ export const ManifestSchema = z
|
|
|
34
34
|
default_approval: z.enum(["human", "mandate"]),
|
|
35
35
|
escalate_above: EscalateAboveSchema.optional(),
|
|
36
36
|
mcp: z.string().regex(PINNED_PACKAGE, "mcp must pin an exact version, e.g. @codespar/mcp@0.5.8"),
|
|
37
|
-
cli: z.string().regex(PINNED_PACKAGE, "cli must pin an exact version, e.g. @codespar/cli@0.
|
|
37
|
+
cli: z.string().regex(PINNED_PACKAGE, "cli must pin an exact version, e.g. @codespar/cli@0.14.0"),
|
|
38
38
|
tools: z.string(),
|
|
39
39
|
guardrails: z.string(),
|
|
40
40
|
mandate_schema: z.string(),
|
|
@@ -15,6 +15,8 @@ export interface RailPayment {
|
|
|
15
15
|
payee: string;
|
|
16
16
|
purpose: string;
|
|
17
17
|
agent_id: string;
|
|
18
|
+
/** The principal the agent acts for (the mandate's `consumer_id`). A receivable settles into THIS identity's account; `POST /v1/charges` needs it on the wire. */
|
|
19
|
+
consumer_id?: string;
|
|
18
20
|
description?: string;
|
|
19
21
|
/** Display name of the counterparty (a receivable's debtor). The rail that issues a charge needs it; a payout rail ignores it. */
|
|
20
22
|
beneficiary?: string;
|
|
@@ -70,6 +72,14 @@ export interface RailReceipt {
|
|
|
70
72
|
/** Null when the API seals nothing for this kind of record. */
|
|
71
73
|
chain: string | null;
|
|
72
74
|
receipt_sig: string | null;
|
|
75
|
+
/** The Ed25519 signature CodeSpar seals alongside the HMAC (base64url) and
|
|
76
|
+
* the published key that made it. Null on a receipt sealed before the API
|
|
77
|
+
* had the capability, on a record the API seals nothing for (a paid
|
|
78
|
+
* charge), and on the stub rail, which is not CodeSpar and must not look
|
|
79
|
+
* like it. Carried onto the bundle's copy so THAT copy is what a third
|
|
80
|
+
* party checks: `npm run verify runs/<run-id>/receipts/<id>.json`. */
|
|
81
|
+
receipt_sig_ed25519: string | null;
|
|
82
|
+
receipt_sig_kid: string | null;
|
|
73
83
|
/** Section 4.5: the kit stamps the actor onto the local copy of every receipt. */
|
|
74
84
|
actor: Actor;
|
|
75
85
|
raw: unknown;
|
|
@@ -81,7 +91,11 @@ export type RailLookup = RailOutcome | { status: "in_flight" } | undefined;
|
|
|
81
91
|
export interface PaymentRail {
|
|
82
92
|
readonly name: "stub" | "codespar" | "stub-charge" | "codespar-charge";
|
|
83
93
|
pay(payment: RailPayment): Promise<RailOutcome>;
|
|
84
|
-
/**
|
|
85
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Answers the outcome of an attempt already presented, `in_flight` while the rail is still on it, or `undefined` when the rail
|
|
96
|
+
* never saw it. `transactionId` is the rail's own id for the attempt when the core recorded one (an accepted receivable): a rail
|
|
97
|
+
* whose read is keyed on its id and not on the caller's key looks it up by that.
|
|
98
|
+
*/
|
|
99
|
+
lookup(attemptId: string, payment: RailPayment, transactionId?: string): Promise<RailLookup>;
|
|
86
100
|
receipt(receiptId: string, actor: Actor): Promise<RailReceipt | undefined>;
|
|
87
101
|
}
|