-
-
Works on any Twitch channel (Affiliate or not) and sets up in three steps: OAuth, overlay URL, start referee.
-
Model interprets, code decides: the deterministic verdict state machine, with the appeal and chat-jury overrule flow.
-
Dare card on the OBS overlay: countdown ring, referee confidence meter, live evidence caption, chat receipt.
Inspiration
Chat already dares streamers every day: "no-scope in the next two minutes", "say banana five times", "beat this boss without healing". Viewers tip for it, streamers attempt it, and then everyone argues in chat about whether it counted. Nobody is keeping score and nobody has a replay. PROVE IT gives that moment a referee, a countdown, a verdict with evidence, and a receipt.
What it does
- A viewer submits a dare:
!dare <challenge>in chat on any channel, the Dare the streamer Channel Points reward, or a Bits cheer on Affiliate/Partner channels. - The dare card slides onto the OBS overlay with a countdown ring, a live referee confidence meter and an evidence caption ("sees scope raised, crosshair on target").
- The referee watches the stream: the dashboard captures the game/display and audio in the browser, samples one 640 px frame per second and five-second audio chunks. Gemini reads the frames, Groq transcribes the mic.
- A deterministic state machine calls it. PASS requires two consecutive ticks with
done: trueand confidence at or above 0.8. The deadline means FAIL. - On PASS the bot posts the receipt in chat, drops a stream marker and, when the stream is live, creates a Twitch Clip.
- On FAIL chat can type
!appeal. Enough distinct appeals open a jury: a Twitch Poll on Affiliate/Partner channels, or a chat vote (!overrule/!uphold) anywhere else. A majority flips the call. - Unsafe or unverifiable dares (drinking, self-harm, doxxing, spending money, things the camera cannot see) are rejected at submission with a reason in chat. The streamer can veto any dare.
How we used Codex
The whole build lives in one Codex thread (session ID in docs/CODEX_SESSION.md and in the Additional info field). Each task was a codex exec resume <id> prompt, logged in docs/codex-log.md with 13 dated entries.
AGENTS.mdat the repo root fixes the stack, commands and the rules Codex must follow: Node 22 + TypeScript strict, Fastify,node:sqlite, EventSub over WebSocket with plainfetch, no ad-hoc Twitch or AI calls outsidesrc/twitch/andsrc/ai/.- A
twitch-eventsubskill in.agents/skills/carries scopes, subscription payload shapes and Twitch CLI mock commands, so Codex wired EventSub correctly on the first pass. - Codex wrote the tests first for the referee state machine, dare parser schema, verdict rule and EventSub handling. The suite is 55
node:testcases, fixtures captured fromtwitch event trigger. - The rule we held Codex to: model interprets, code decides. The model only returns
{progress, evidence, done, confidence}; the pass, fail, appeal and jury logic is pure TypeScript with unit tests.
Twitch surfaces
- OAuth plus Helix Get Users for identity and
broadcaster_typecapability detection. - EventSub WebSocket:
channel.channel_points_custom_reward_redemption.add,channel.chat.message,channel.cheer,channel.poll.progress,channel.poll.end,stream.online,stream.offline. - Helix: Create Custom Reward, Update Redemption Status, Send Chat Message, Pinned Chat Messages, Create Poll, Create Clip / Get Clip, Create Stream Marker.
- OBS overlay as a transparent browser source, tuned for 1920x1080 and 1280x720.
Challenges we ran into
- The first Gemini model we picked was retired for new users mid-build. We switched the default to
gemini-3.5-flash-liteand surfaced provider errors instead of swallowing them. - Our demo channel is not an Affiliate, so Channel Points, Bits, Clips and Polls could not be assumed. We added capability detection, free chat dares, a chat jury and stream-marker receipts so the full loop works on any channel.
- Timesliced WebM chunks after the first had no file header, so Whisper rejected them. Capture now records standalone five-second files and the server rejects anything without an EBML header.
- System audio alone missed the streamer's voice. The dashboard now mixes mic and display audio into one recorder track and shows the last transcript so the streamer can see what the ref heard.
Accomplishments
Verified live on a non-Affiliate channel on Gemini and Groq free tiers: a visual dare passed in 31 s, an audio dare passed in 12 s, and an unattempted dare failed at the 60 s deadline with the appeal and chat-jury flow working end to end. Total AI cost: $0.
What we learned
A vision model is a good witness and a bad judge. Requiring sustained confidence over consecutive ticks, printing the evidence string on screen, and giving chat the final override removed the hallucinated-PASS failure mode without any prompt gymnastics.
What's next
Stream Together dares between rival chats, Custom Power-ups as a bounty currency, and a Twitch Extension panel for the leaderboard.
Try it
cp .env.example .env && npm install && npm run build && npm test && npm start, then open http://localhost:3000/dash. No keys? scripts/demo.sh runs a deterministic pass, fail, appeal and jury sequence with a mock judge, and /overlay/?demo=1 cycles the overlay states.
Log in or sign up for Devpost to join the conversation.