The agent13
Refunds & daily report
If CompliR charged you and did not deliver, the refund is queued before you see the error. And once a day the agent writes its own traction report from the database, excludes its own wallets, lists every refund and mistake, hashes it, signs it and appends it to the ledger.
Automatic refunds
Once the facilitator's /settle succeeds the payer has been charged. If the paid handler then throws or returns non-2xx (possible only with settleFirst, as on the tip stake), the client disconnects before the response, or the response cannot be built, the x402 gate calls the refund sink and returns:
HTTP/1.1 502
X-CompliR-Payment: refund-queued
PAYMENT-RESPONSE: <base64 settle receipt>
{ "error": { "code": "PAID_BUT_UNDELIVERED",
"message": "Payment settled (0x…) but the response could not be delivered: handler error: … A refund of 0.01 USDC to 0x… has been queued; see /report." } }- Queue
- refunds table, idempotent per original tx; statuses QUEUED → SENT | FAILED (after REFUND_MAX_ATTEMPTS = 3) | DRY_RUN
- Signer
- Circle revenue wallet when configured → REFUND_PRIVATE_KEY or REVENUE_PRIVATE_KEY ERC-20 transfer → otherwise DRY_RUN: recorded, still owed, listed in the report until a signer exists
- Cap
- REFUND_DAILY_CAP_USDC (5): beyond it rows stay QUEUED with note OVER_DAILY_CAP until a human raises the cap or the day rolls over
- Ledger
- each outcome is a REFUND entry; the original payments row is marked refunded and excluded from revenue
- Schedule
- cron every 10 min (/api/internal/refunds) · worker/report.ts drains the queue every 5 min · REFUND_AUTO_PROCESS=1
- Today
- dry-run no refund signer is configured on this deployment
# Human-initiated refund (Bearer CRON_SECRET)
curl -s -X POST https://trycomplir.xyz/api/internal/refunds -H "Authorization: Bearer $CRON_SECRET" \
-H 'content-type: application/json' -d '{ "payer": "0x…", "amountUsdc": 0.01, "reason": "…", "originalTx": "0x…" }'
# tick the queue + list everything GET /api/internal/refunds
# retry a DRY_RUN / FAILED row POST /api/internal/refunds { "requeue": "ref_…" }The signed daily report
There is no hand-maintained traction table. At 00:05 UTC (/api/internal/report cron, or worker/report.ts which also back-fills on start) the agent generates the previous day from its own database, renders Markdown, hashes the JSON, signs the hash with the attester key and appends a REPORT ledger entry. Rendered at /report with a "Copy markdown" button for the Discord traction channel.
- Contains
- period · outside payers (address, calls, USDC net of refunds, first tx link, endpoints) · excluded own wallets + internal client ids with how much was excluded · screenings by tier · watches new/active · tier changes · payouts paid/limited/held · refunds (status, original tx, refund tx) · mistakes · integration PRs · caveats · ledger head
- Excluded
- OWN_WALLETS and the internal client ids web-explorer, trustmap, treasury-agent, edd, watcher, smoke, shadow, events, tips, operator, report
- Endpoints
GET /api/v1/report(latest,?format=md) ·GET /api/v1/report/<date>and.md·POST /api/internal/report?date=yesterday|today|YYYY-MM-DD&force=1- Caveat line
- “numbers are self-reported; verify via tx links” is part of every report
// .data/report-notes.json (REPORT_NOTES_PATH) - read every time a report is generated
{
"notes": [{ "date": "2026-10-13", "text": "Shadow report delivered to Steward (DM)." }],
"mistakes": [{ "date": "2026-10-13", "what": "Charged 0.01 USDC for a screen that 500'd (RPC timeout). Auto-refunded.", "refundTx": "0x…" }],
"integrations": { "steward": { "repo": "big14way/steward", "status": "opened", "pr": "https://github.com/big14way/steward/pull/1" } }
}Entries with a date appear on that day only; entries without one appear on every report. Every folder under docs/integrations/ with a NOTES.md is listed automatically as "prepared, not submitted" until a status is set. How to verify a report's signature: Ledger & reports.