Skip to content

Repository files navigation

CALLED IT

This is a game. Every token balance, invoice, tier and rate limit in this app is simulated play money. Nothing here reflects real API usage or real cost.

A prediction game dressed as an AI API billing console. Confidence is metered: the surer you claim to be, the more tokens the call costs — and the less it pays back when you turn out to be right. Run out of tokens and your account is rate limited.

Stack: Next.js (app router) · MongoDB Atlas + Atlas Vector Search · Voyage AI (voyage-3) embeddings · Claude (claude-opus-5).

Setup

cp .env.local.example .env.local     # fill in the values
npm install
npm run seed                          # 6 accounts, ~90 calls, embedded + priced
npm run dev

npm run seed prints the Atlas Vector Search index definition and tries to create it. If it can't, paste the printed JSON into Atlas → Atlas Search → Create Search Index → JSON Editor → Vector Search on the predictions collection, named prediction_vectors. Check status with npm run index:create. Until it's queryable the app falls back to in-memory cosine similarity and labels which path it used, so the demo never hard-fails.

Token economy

Every account is provisioned with 10,000 simulated tokens.

Stake (charged on open) round((100 + confidence × 8) / 10) × 10
Payout (correct) round(stake ÷ (confidence / 100))
Payout (wrong) 0
Balance 10,000 − Σ staked + Σ returned, floored at 0

So a 95%-confidence call costs 860 and returns 905 — 45 tokens of upside for maximum swagger. A 30%-confidence call costs 340 and returns 1,133. Conviction is expensive, long shots pay, and being loudly wrong is the fastest way to zero.

Tiers are derived from balance, not stored: Enterprise ≥ 13,000, Pro ≥ 8,000, Free ≥ 500, Deprecated below 500. Deprecated accounts are rate limited — the new-call form is replaced by a 429 panel and the API rejects writes with HTTP 402.

Brier score and calibration gap survive as secondary accuracy stats: brier = (confidence/100 − outcome)², calibrationGap = |mean confidence − accuracy|. Behavioural titles (Oracle, Serial Reoffender, Coward, Doomer, Broken Clock) are still computed from the record.

Seeded standings land as: two Enterprise, one Pro, two Free, and Dev Kapoor bankrupt at 0 and rate limited — he promised to start waking up at 5am four times, reworded each time, at 88–95% confidence, and was wrong every time.

Progression

Separate from the money. XP rewards calibration, not volume: the largest term is a calibration bonus that decays cubically with the gap, multiplied by a reliability ramp so one lucky call can't fake it. Eight ranks, from Talking Out Loud to Group Chat Prophet.

The result is a deliberate tension the leaderboard makes visible: Marcus Lin has the most tokens (14,282) by never committing above 55% confidence, but Priya Raman outranks him on XP (1,260, rank 7) with 4,700 fewer tokens and a 3% calibration gap. The bank rewards timidity; the rank rewards being right about how right you are.

Fourteen achievements, all derived from the record rather than stored — Long Shot, Loud And Wrong, Same Take Again, Untouchable. Locked ones stay visible on the shelf so there's something to chase.

Features

Pull the receipts — Atlas Vector Search over one player's own history using the current call's embedding, then Claude roasts them citing specific past calls with dates and confidences. The roast is deliberately short and punchy — it builds to one specific date and number as the punchline.

Forecast the forecaster — submitting a new call runs vector search over that player's settled history first. Accuracy and average confidence on similar calls are computed in code (never by the model), handed to Claude, and returned as a pre-authorisation risk note with an estimated real probability. Nothing is billed until you confirm. Editing the text or the slider invalidates the review.

Settlement desk (/demo) — operator panel. Force any pending call correct or wrong, see the payout, and watch balances, tiers and rate limits recompute in a live standings rail.

The demo (60 seconds)

  1. Landing page is the money shot — balances, tiers, sparklines, and Dev Kapoor at the bottom flagged 429 RATE LIMITED.
  2. Open Dev Kapoor. Four wrong 5am promises, each reworded, each ~90% confident. Balance zero, rank 2, new-call form replaced by the 429 panel.
  3. Open a solvent account, type a call on a topic they have history with, hit Review risk before billing — the risk desk quotes their own record back.
  4. Pull the receipts on any call — vector search, roast, voice.
  5. /demo → settle a pending call on stage (C correct, W wrong, arrows to select). The payout floats off the row, the balance rolls, the tier changes and the standings reorder in place.

API

Route Body Does
POST /api/predictions {playerId, text, confidence, category, deadline} Bills the stake, embeds, stores, recomputes score + balance. 402 if rate limited
POST /api/predictions/:id/resolve {status: "correct"|"wrong"|"open", note?} Settles, pays out, recomputes score + balance
POST /api/receipts {playerId, predictionId} or {playerId, text, confidence} Vector search → Claude roast
POST /api/forecast {playerId, text, confidence} Vector search over settled calls → Claude risk note

About

A prediction game where confidence is billed. Stake tokens on everyday calls; Atlas Vector Search finds the same wrong take you made before and Claude roasts you for it.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages