FoolProof — get scammed here, so it never happens out there
Inspiration
In 2025, Americans reported $15.9 billion lost to fraud — a record, up 27% in a single year — and $3.5 billion of it came from imposter scams alone (FTC). What struck us wasn't the size of the number. It was the mismatch between how money is lost and how financial literacy is taught.
Every tool we found was passive: articles, videos, quizzes. But nobody loses $2,000 to a quiz. Money is taken in live conversation — a convincing person, applying pressure, in the moment, before you have time to think. And the scams targeting people our age don't look like "scams" at all: they look like a dream internship DM, a toll-fee text, a first apartment lease.
You don't build a reflex by reading about one. So we built the opposite of a literacy app: a room full of AI adversaries that try to rob you — safely.
What it does
FoolProof is an adversarial training simulator. You enter the Gauntlet and face five playable scams, each a live AI character running a documented manipulation playbook:
- 🤝 Quick Cash Danny — a payday lender hiding a triple-digit APR inside "$15 per $100"
- 💼 The Dream Internship — the fake-check overpayment job scam hitting students right now
- 📞 The Fraud Alert — a bank imposter, in full voice mode: spoofed caller ID, a real ringtone, TTS voice, live captions
- 🏠 The Lease Signing — a real 18-clause lease with three poisoned clauses, plus a plain-English jargon translator
- 🚗 The Toll Text — a smishing scam generated by our own Scam Factory pipeline from a real FTC alert
During a round you can flag any message with one of ten named manipulation tactics (urgency pressure, fee burial, authority impersonation, isolation…). When you decide — take the deal, negotiate, or walk — an independent AI referee grades the whole transcript, and you get the Evidence File: your conversation annotated in the margins (CAUGHT / RESISTED / FELL FOR IT), with every buried mechanic literally un-redacting on screen, and one number in red: exactly what your decision would have cost.
The app even demos itself: a hands-free auto-demo takes the cursor, plays a real round, flags a tactic, takes the bad deal, and opens the evidence — nothing mocked, nothing pre-recorded.
How we built it
Three strictly separated engines, because separation is the technical argument:
1. The adversary engine. Every scammer is a persona plus a JSON playbook — beats, escalation rules, and required concessions (accurate facts the character must admit when cornered precisely). Online, it's a live Claude character streamed over SSE with a hidden [[beat:bN]] marker tracking playbook progress. Offline, a scripted state machine runs the same playbook through the same wire format — kill the API key and the demo cannot break.
2. The referee. A second, independent model call receives the transcript, our 10-tactic taxonomy, the playbook's ground truth, and the player's live flags, and returns strict-JSON findings. The scammer never grades its own exam. (Offline, a deterministic grader scores the round instead.)
3. The damage engine. Every dollar is deterministic TypeScript — pure functions, 27 unit tests, zero AI. The payday engine implements the real fee structure:
$$\text{APR} = \frac{\$15}{\$100} \times \frac{365}{14} \times 100\% \approx 391.07\%$$
The internship engine implements the Reg CC provisional-credit timeline: deposit a counterfeit \$2,480 check, "keep" \$350, forward \$2,130 — then day 7 the check bounces, the bank reverses the whole provisional credit, and the loss is
$$\$2{,}130 + \$35_{\text{returned-item fee}} = \$2{,}165 \;\approx\; 6.2 \text{ weeks of the promised salary}$$
Each scenario's key computation is also independently re-run by Wolfram|Alpha at debrief time and badged on the Evidence File — two systems, one number, or the badge refuses to render.
Stack: React 18 + TypeScript + Vite, Tailwind on a custom case-file design system, Framer Motion (redaction reveals, stamp animations), Express + SQLite/Drizzle (including a hand-rolled 40-line session store so logins survive restarts), Anthropic API with SSE streaming, browser SpeechSynthesis/SpeechRecognition for voice mode, deployed on Render.
Scaling content, not code: our Scam Factory turns a pasted FTC alert into a complete new adversary — persona, five-tactic playbook, offline fallback, damage spec — with our code validating every field and freezing the math. The Toll Text scenario didn't exist until the pipeline built it.
Challenges we ran into
- Streaming around a hidden control channel. The adversary streams tokens live, but its trailing
[[beat:bN]]marker must never reach the screen — so the SSE writer holds back a 14-character tail until it's provably not the marker, then strips it before persisting. - Making "offline" identical, not degraded. The scripted fallback had to match the live path's wire shape exactly — same SSE frames, same referee schema — so the UI can't tell which engine it's talking to.
- A demo that drives a real app. The auto-demo types into actual React controlled inputs (native-setter events), clicks real buttons, and survives its own timing: we hit a bug where the progress bar re-rendered the popup 60×/second, and each render's fresh callback identity restarted the typewriter — permanently blank text — fixed by pinning callbacks in refs.
- Making instant AI feel human. Scripted replies arrived instantly, which read as robotic — we added a 1.1–1.9s "typing…" beat before the first token.
- Small production landmines: the popular SQLite session-store package hardcodes a
sessionstable name that collided with our rounds table (we wrote our own), and Vite binds IPv6 so our port-cleanup script had to scan both stacks.
What we learned
That trust is an architecture decision: the moment we separated who plays the scammer, who grades, and who computes the money, every claim in our pitch became checkable. That accessibility is load-bearing when your whole thesis is "jargon is where the money hides" — the plain-English lease translator and the Atkinson Hyperlegible toggle aren't add-ons, they're the product. And that the most persuasive thing a hackathon project can do is lose to you convincingly: watching yourself get taken for \$2,165 by a chirpy recruiter teaches more than any infographic we could have made.
What's next
Difficulty tiers where adversaries get subtler as your catch-rate rises, white-label playbook tooling so a credit union's fraud team can author scenarios without touching code, and a monthly adversary drop tracked to FTC alerts — because the scams don't stop evolving, and now neither do we.
Get scammed here — so it never happens out there.
Built With
- anthropic-api
- bettersqlite-3
- concurrently
- dotenv
- drizzle-orm
- express-session
- express.js
- framer-motion
- lucide-react
- node.js-24
- npm
- opus4.8
- react
- react-router
- recharts
- render
- sonnet4.6
- sqlite
- sse-streaming
- tailwindcss
- tanstack-react-query
- tsx
- vite
- vitest
- web-speeches-api
Log in or sign up for Devpost to join the conversation.