Skip to content

edycutjong/treble

The Treble

The Treble ⚽🤖

A trustless prediction pot where an on-device AI stakes its own money against you.

The Treble

Watch the 3-min demo Landing Pitch Deck

Tether Developers Cup Track


Judges — Reading Guide

Commit-pinned permalinks to the parts worth reading + why/how/trade-off for every Tether stack piece.


Pear WDK QVAC Node Apache 2.0 Tests CI/CD Pipeline


📸 See it in action

One real run of npm run demo: four Autobase peers converge fully offline — the on-device AI 'The Gaffer' stakes its own USD₮ under a WDK Transaction-Policy cap, its post-kickoff pick change and its result vote are both REJECTED by every peer, the pot settles zero-sum, and all four peers reach a byte-identical state hash. Final: Humans 0 – 1 AI Pundit.
A single real run of npm run demo — four Autobase peers, fully offline, ~20s. The AI can win the pot; it cannot cheat. (Same run as copy-pasteable text below.)

$ npm run demo

⚽ THE TREBLE — humans vs. the machine, no server, no house, no cloud

🏆 pot opened  "Kitchen Table Clásico" — Brazil vs Argentina, buy-in 20 USD₮
👤 Ana  staked 20 USD₮ tx sim0xf6a9cffaea1a9…  pick 3-1 (keys on their own device)
👤 Bo   staked 20 USD₮ tx sim0x99a5a43bb4fbc…  pick 0-0 (keys on their own device)
👤 Cai  staked 20 USD₮ tx sim0x1e9519b925278…  pick 1-2 (keys on their own device)

🤖 THE GAFFER (its OWN keypair + WDK wallet, Transaction Policy cap 20 USD₮)
   policy pre-flight: ALLOW (allow-bounded-usdt-stake)
   🧠 [brain: heuristic] "Backing 1-1 the draw — argentina unbeaten in 14
      competitive matches" confidence 60%
   💰 autonomously staked 20 USD₮ tx sim0xd2be4b99cd834… from its own wallet

🔒 KICKOFF — pot locked on the shared append-only ledger
🚫 Bo tried to change his pick after kickoff → REJECTED by every peer
🚫 the machine tried to vote on the result → REJECTED (agent-has-no-result-authority)
✅ result finalized by 2/3 staked humans (quorum)

💸 settlement — winners release their own bond, losers pay winners
Σ CHECK  paid 80 USD₮ == staked 80 USD₮  ✓ zero-sum, no house cut
CONVERGENCE  4 peers, one shared state hash  ✓ byte-identical everywhere

🏁 THE MACHINE TAKES THE POT  Humans 0 – 1 AI Pundit

Stake → tamper-evident pick lock → human consensus → deterministic split. Four real Autobase peers, real WDK Transaction Policies, real receipts — in ~20 seconds, fully offline.

🧠 The real on-device QVAC model, actually run — not just claimed. The [brain: heuristic] above is a disclosed fallback so the default demo runs offline in seconds. Below is an unedited capture of npm run demo -- --brain qvac (2026-07-14): Qwen3 1.7B downloaded and run on-device, deciding through the identical seat → policy → ledger path as the heuristic brain above.

🤖 THE GAFFER (writer ffb247f2…b192, its OWN keypair + WDK wallet, Transaction Policy cap 20 USD₮)
   joined the pot as agent — wallet sim1bqy6o7u5ba…
   policy pre-flight: ALLOW (allow-bounded-usdt-stake)
   thinking about Brazil vs Argentina (brain: qvac)…
   🧠 [brain: qvac] "Argentina's high press exposes their left flank, while Brazil's direct
      wing play and rapid counters can exploit the rain-slowed Argentina's short passing
      game." confidence 70%
   💰 autonomously staked 20 USD₮ tx sim0x51e47f6ad7f88… from its own wallet

🏁 THE MACHINE TAKES THE POT  Humans 0 – 1 AI Pundit

That rationale is genuine model output through completion() tool-calling, not a template — it reads differently every run. Reproduce it yourself: npm run demo -- --brain qvac (or npm run agent -- <invite> --brain qvac for a live pot); first run downloads Qwen3 1.7B (~1 GB) via @qvac/sdk. Nothing about the QVAC wiring is mocked.


💡 The problem & the twist

Every friend group runs a tournament pot, and every pot has the same two flaws: someone has to hold the money, and someone has to be trusted not to "misremember" their pick. Meanwhile, everyone argues about whether an AI could out-predict the group — but "AI plays too" normally means a cloud API with someone else's wallet.

The Treble rebuilds the pot with no treasurer and no server — and gives the AI a real seat at the table:

  • 🪙 Self-custodial stakes — every player (human and machine) bonds USD₮ from a wallet only they control. No custodian anywhere.
  • 🧠 An on-device opponent — the AI pundit reasons about the match locally via QVAC, streams a one-line rationale, and stakes its own money with its own keys.
  • 🔒 Tamper-evident picks — signed, append-only Hypercore logs, linearized by Autobase, frozen at kickoff. A post-kickoff edit is rejected by every peer.
  • ⚖️ The machine can't cheat — it has strictly less power than humans: no result votes, no locking, no inviting accomplices. Enforced by the consensus reducer, tested over the wire.
  • 💸 Deterministic settlement — a quorum of staked humans confirms the score; Σ payouts == Σ stakes to the micro-USD₮, dust assigned deterministically.

🏗️ Architecture & stack

Layer Technology Why it is load-bearing
P2P state Pear: Corestore → Hypercore → Autobase → Hyperbee, Hyperswarm rooms, Protomux seat-requests The multi-writer pot with no server; the AI is just another writer
Money @tetherto/wdk 1.0.0-beta.12 + a custom WalletManager (sim engine) / wdk-wallet-solana (devnet) Self-custody for every participant; the agent's cap is WDK's real default-deny Transaction Policy engine
Mind @qvac/sdk 0.14.0 completion() tool-calling (submit_pick), Qwen3 1.7B on-device The pick is a genuine on-device model decision — zero cloud calls
Consensus core Pure deterministic reducer (src/core/reducer.js) Every peer applies identical rules → byte-identical state hashes
flowchart TD
  subgraph Humans[Human peers — self-custodial]
    H1[Hypercore: stake/pick/vote]
    HW[WDK wallet]
  end
  subgraph Agent[AI pundit — self-custodial, on-device]
    QV[QVAC completion tool-calling<br/>forms pick + rationale]
    AW[WDK wallet — own keys<br/>Transaction Policy cap]
    QV --> AW
  end
  H1 --> AB{{Autobase reducer<br/>linearized, invariant-enforcing}}
  AW --> H2[Hypercore: agent stake/pick] --> AB
  AB --> V[Hyperbee view: pot · picks · result · splits]
  HS([Hyperswarm topic = invite key]) -.discovery.- Humans & Agent
  V --> PAY[human quorum → deterministic split] --> W[(bond accounts settle<br/>losers pay winners)]
Loading

Full details: ARCHITECTURE.md

🚀 Getting started

Prerequisites: Node ≥ 20. Optional: Pear runtime for the desktop UI, a local GGUF model for the QVAC brain.

npm install
npm run demo  # the full humans-vs-machine match, offline, ~20s

For judges: npm run demo needs no keys, no accounts, no network. Try --outcome humans, --outcome refund, or type your own pot:

node src/cli.js create --buy-in 20 --kickoff-mins 30   # prints a treble1… invite
node src/cli.js join <invite>                          # a friend, second terminal/device
npm run agent -- <invite>                              # the AI pundit joins by itself
pear run .                                             # desktop UI (Pear runtime)

The QVAC brain: the demo/CI default is a disclosed deterministic heuristic (label: [brain: heuristic]) so everything runs without a ~1 GB model download. Run the real on-device LLM with npm run agent -- <invite> --brain qvac (first run downloads Qwen3 1.7B via @qvac/sdk — the model empirically verified to emit well-formed tool calls on-device), or point TREBLE_QVAC_MODEL at any local GGUF. The seat, policy cap and ledger path are identical for both brains.

Real-chain settlement: the wallet layer is engine-modular. --engine solana uses @tetherto/wdk-wallet-solana on devnet (install it, fund the printed address from a faucet). The default sim engine is a disclosed local ledger so the whole flow — including policy enforcement — is verifiable offline.

🧪 Testing & CI

198 tests, 664 assertions (brittle) — 100% line, function AND branch coverage on src. The only c8-ignored lines are true I/O boundaries or provably-unreachable defensive guards, each labelled with an honest reason: the live QVAC model calls, real Hyperswarm/DHT sockets, the CLI/agent process bootstrap, the optional Solana module, and the demo's own invariant self-checks (proven in the reducer/settlement suites). Count is verified, not typed (npm run test:count); coverage is gated at 100/100/100 (npm run coverage).

npm test               # unit + integration (incl. multi-peer Autobase over real replication streams)
npm run coverage       # the suite under c8 with the honesty gate (100% lines/functions on src)
npm run e2e            # the full demo × 4 scenarios (3 outcomes + policy-decline)
npm run verify:p2p     # proves no server: convergence + server-socket tripwires
npm run verify:offline # proves on-device: full agent flow with networking booby-trapped
npm run bench          # reproducible p50/p95
npm run lint           # standard
npm run check:ready    # submission readiness gate (fails on placeholders/stale claims)
Layer Tool Status
Code quality standard (ESLint) ✅ zero warnings
Unit + integration brittle — 198 tests / 664 asserts
Coverage c8 — 100% lines, functions & branches on src ✅ gated (npm run coverage)
E2E 4-peer demo × 4 scenarios (incl. policy-decline) + 2 verifiers
Security (SAST) CodeQL ✅ workflow
Security (SCA + secrets) Dependabot + npm audit + TruffleHog ✅ workflow
CI/CD 6-stage pipeline (quality → security → build → e2e → perf → gate)

What the tests actually pin down (depth over count): pick immutability incl. backdated timestamps, Σ payouts == Σ stakes with deterministic dust, agent parity (same rules) and agent inferiority (no votes/locks/grants — verified over real replication, including the "agent seats an accomplice bot" attack), the WDK policy engine throwing real PolicyViolationErrors, cumulative session caps that simulations can't drain, state-hash convergence across 3–4 peers, and escrowless settlement where every winner is made exactly whole.

📊 Benchmarks (reproducible)

npm run bench — Apple M1 Max, Node 22 (your numbers will vary; the script prints its methodology and writes bench-results.json):

Path p50 p95
Consensus core — full 8-member pot lifecycle (40 ops incl. finality + split) 0.59 ms (≈65k ops/s) 0.75 ms
Append on one peer → byte-identical state on the other (real Autobase replication) 5.7 ms 7.0 ms
Agent seam — seat grant → policy pre-flight → pick → bonded on the ledger 13.1 ms 15.9 ms

🛡️ Why ONLY Pear + QVAC + WDK

  • Pear: Autobase is the trustless pot — the agent is just another writer; Hypercore makes picks tamper-evident; Hyperswarm makes an invite a room. Without it: a server plus a trusted timestamper.
  • WDK: self-custodial accounts for humans and the machine; the agent's cap is WDK's real policy engine (registerPolicy → default-deny → PolicyViolationError). Without it: a custodian puppeting an "AI wallet".
  • QVAC: completion() tool-calling makes the pick a genuine local model decision; the offline verifier proves reasoning needs no network. Without it: a cloud API — neither private nor yours.

Take any one out and The Treble is impossible, not merely harder → SPONSOR_DEFENSE.md

⚠️ Honest limitations

  • Escrowless settlement: losers owe winners per the deterministic plan; a dishonest peer could refuse to execute their legs. The tamper-evident debt record survives them; an on-chain escrow is the v2 path. (AUDIT_REPORT)
  • Consensus collusion — including solo self-Sybil: a strict majority of staked humans (or a single human self-Sybiling enough extra writer keys to out-vote everyone alone — no recruiting required) could finalize a wrong score; each fake identity still costs its own real stake. Documented, not hidden — full threat model in AUDIT_REPORT.md.
  • Sim engine by default: demo settlement runs on a disclosed local ledger; the WDK policy engine governing it is real. Devnet is a config swap, not a rewrite.
  • @tetherto/wdk is beta (pinned to 1.0.0-beta.12); the QVAC-brain path depends on local hardware for model speed.
  • Real-chain settlement not yet captured: every run above (including the screenshot at the top) settles on the disclosed local sim ledger. A devnet run (--engine solana, one human + one agent stake, tx hashes pasted here) is the one artifact still open — the wallet engine seam is wired and ready (SPONSOR_DEFENSE.md).

📖 Prior work & disclosure (hackathon rule #8/judging)

Built during the official window (June 28 – July 14, 2026). Same-team sibling projects The Kitty (trustless pot, Pear×WDK) and PunditPay (on-device paying pundit, QVAC×WDK) share the design lineage — The Treble is the all-three fusion, and this repository's code is written for this build. Third-party: the Holepunch stack, @tetherto/wdk, @qvac/sdk (all Apache-2.0/MIT), brittle, standard. The tetherto/qvac-examples repos (esp. qvac-coffee-conversation) informed the QVAC tool-calling shape. No cloud AI APIs anywhere.

📁 Project structure

build/
├── src/core/    reducer · ops · split · settlement · money · canonical   (the consensus core)
├── src/p2p/     TreblePot (Corestore→Autobase→Hyperbee, Hyperswarm, invites)
├── src/wallet/  WDK facade · sim WalletManager · policy caps · bond accounts
├── src/agent/   strategies · QVAC brain · disclosed heuristic · AgentSeat · runner
├── src/cli.js   demo / create / join (judge-runnable)
├── index.html+app.js  Pear desktop UI          
├── landing/     one-page explainer
├── test/        198 tests (brittle)        
├── scripts/     bench · verifiers · seed · e2e · readiness
└── docs/        architecture · submission · demo · sponsor-defense · audits · friction log · pitch deck · assets

📄 License

Apache-2.0 © 2026 Edy Cu — as the Tether Developers Cup rules require, and happily.

🙏 Acknowledgments

Built for the Tether Developers Cup 2026. Thank you to the Pear, QVAC and WDK teams for shipping stacks where "no server, no custodian, no cloud" is something you can actually type npm install for — and to you, for reviewing this. We wanted to know if we could out-pick a machine that reasons about football; now it has its own wallet, and we genuinely don't always win.

About

⚽🤖 The Treble — serverless AI-vs-humans football prediction pot: an on-device AI pundit (QVAC) holds its own WDK keys and stakes into a tamper-evident Pear P2P pot alongside humans. Tether Developers Cup.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors