Inspiration
A streamer says “one more game” and plays five more. Chat remembers, but finding the original moment takes work.
We wanted to turn that shared memory into something people could use during a stream.
The name comes from wrestling. A receipt is a shot returned after someone hits you for real. Here, chat returns your own words.
What it does
Receipts lets Twitch chat save a streamer’s promise with !receipt.
The service saves transcript evidence, requests a Twitch clip and confirms the capture in chat.
When the streamer says something that may contradict the promise, Receipts sends the comparison to a private review queue.
The streamer decides whether to approve the stamp. Automatic stamps stay disabled.
The streamer can admit the contradiction, explain a context change or open an appeal. Chat votes with !uphold and !overturn.
The OBS overlay shows the receipt and appeal result. Viewers can use !lore to revisit the channel’s recorded history.
How we built it
We built Receipts with OpenAI Codex, using one principal build thread to coordinate implementation, review and verification.
Codex agents worked on separate tasks. We reviewed their changes and ran the project’s checks before landing them.
A Go server handles Twitch authentication, chat commands, audio capture, receipts and live overlay events.
SQLite stores channel data, evidence, reviews, appeals and provider spending.
Keel provides shared infrastructure for storage, streaming, media processing and cost controls.
Svelte 5 and Chaaya power the browser interface and OBS overlay.
Streamlink and FFmpeg capture broadcast audio. OpenAI transcription converts that audio into source segments.
GPT-6 Luna extracts promises. Embeddings retrieve relevant saved claims. OpenAI Decisions classifies sensitivity and possible contradictions.
The models propose a review. The channel owner controls publication.
We host the application in a Docker container on Hetzner. GitHub Pages serves the Starlight documentation site.
Challenges we faced
The hardest problems appeared between components.
A promise could cross an audio chunk boundary. Transcribing each chunk separately sometimes split the sentence or changed its meaning.
We added overlapping windows of original audio. The ledger records both source ranges before transcription.
Another bug involved exact evidence matching. A valid promise could occupy one sentence inside a longer transcript segment.
We repaired sentence validation while preserving the original source text and timing.
The control dock initially required a manual refresh to show new reviews. It now refreshes its private data every three seconds.
We also found historical reviews appearing before current-session reviews. Approval correctly rejected those older items, but the interface still offered approval buttons.
We restricted the actionable queue to the current session and added authenticated approval tests.
Live testing also exposed cancellation, chat routing and overlay recovery problems. We recorded those failures and added regression coverage.
What we learned
A wrong accusation damages the experience more than a missed contradiction.
Our evaluation found false positives. We kept automatic stamps disabled and made owner review central to the product.
We also learned to treat evidence as a product feature.
A model verdict needs the original promise, the later statement and enough context for a person to disagree.
Durable state matters just as much as detection. Refreshes and retries must preserve decisions without creating duplicate stamps or votes.
Codex helped us move quickly across the stack. Explicit task boundaries, independent review and offline fixtures made that speed useful.
What we are proud of
We completed staged live runs across Twitch chat, audio capture, promise extraction, clip creation, private review, owner approval, appeals and lore.
We checked account isolation and OBS source revocation.
The repository includes offline fixtures, regression tests, evaluation evidence and a development diary.
Judges can explore a recorded demo without connecting Twitch or providing an API key.
What comes next
We want to improve context handling, expand evaluation and make the live setup easier to understand.
We also need fresh hosted observations of OBS clip playback and restart recovery.
We will keep human approval in place while we evaluate detection quality.

Log in or sign up for Devpost to join the conversation.