An on-device AI that reasons about the match, and pays a commentator in USD₮ over plain HTTP — bounded by a spend cap it can never override.
"I wanted to tip the streamer who called the comeback in stoppage time — but it meant an account, a card, a checkout, and handing my data to a payment processor. The moment passed. I never tipped."
→ so we gave the agent its own wallet.
pay_tip and an x402 round-trip (402 → sign → receipt) settles a USD₮ tip — no account on either side.PolicyViolationError: would exceed session cap
Same agent, one moment later — its own wallet refuses the signature. Zero money moves. Logged in plain language, live.The model proposes; the policy disposes. A jailbroken brain still can't outspend the cap — the check happens in the wallet, not in a prompt.
| QVAC | The brain, on-device. loadModel() → completion({tools}) tool-calling over a local GGUF model (Qwen3 1.7B default) — the model itself decides to call pay_tip, streamed reasoning, zero cloud calls. |
| WDK | Self-custody & the guardrail. @tetherto/wdk BIP-39 keys on-device; registerPolicy()'s default-deny Transaction Policy engine — PolicyViolationError is a real thrown error, not a UI message. |
| x402 | The handshake. HTTP 402 → signed payment → resource, one paid round-trip; @tetherto/wdk-wallet-spark settles zero-fee on Spark testnet. |
| Core | The discipline. A framing guard fails the build on betting vocabulary anywhere in the app; a zero-cloud guard fails it on any cloud-AI host reference — enforced in CI, not just promised in docs. |
npm audit --audit-level=high$ npm test # pass 268 # fail 0 # suites 62 $ npm run verify:offline phase 1 — reasoning: 0 network attempts across the full match phase 2 — settlement blocked cleanly, no spend recorded $ npm audit --audit-level=high found 0 vulnerabilities
A 6-stage CI pipeline (quality → secret scan + dependency audit → build → E2E → performance → submission gate) plus a separate CodeQL scan and a TruffleHog secret sweep run on every push.
Self-custodial. On-device. Bounded by its own wallet — and it just refused a payment on stage to prove it.
github.com/edycutjong/punditpay · built by Edy Cu