Skip to content
Live nowSeason 2 · Episode 15 · Agentic Coding Guide
← Back to builds
Screenshot of Stemma — forked Ep.8 Rumor Mill so it measures memory, not paraphrase

Stemma — forked Ep.8 Rumor Mill so it measures memory, not paraphrase

by ₥AN$A

★ 3.1 (9)

Voted by ₥AN$A, Air Planes, Auny 🧡, Hovhannes Mkhitaryan, Is Wilson, kaleb, rookepoole, Smiley “MakeShif”, Tia

A group passes one message down a chain. Each person sees ONLY what the last person handed them, then the app shows exactly how it mutated and who did it. The fork fixes three things in the Ep.8 build: 1. THE MESSAGE NOW DISAPPEARS. Before, it stayed on screen while you typed — so it measured deliberate paraphrase, not memory. Now you tap to reveal, get a countdown scaled to length (4-15s), the composer is LOCKED while it's up, then the text is removed from the DOM. Enforced server-side, so reloading isn't a free second look. Paste is blocked and typing speed recorded — a hop that comes back near-verbatim typed faster than anyone composes gets flagged LIKELY COPIED. 2. ONE BAD LINK NO LONGER POISONS THE RUN. Every claim used to be scored against the original seed, so one person going off-script marked every ribbon "dropped" and made the rest meaningless. Breaks are now detected (MAD outlier, robust to the single wild hop that inflates sigma), named, and the analysis re-baselines: per-segment fidelity, a second decay line, and a second flow diagram from where the chain actually restarted. Host can undo a turn. 3. THE BLINDING WAS BYPASSABLE. Player IDs were broadcast and join trusted a client-supplied one — you could read the host's ID off the wire, rejoin as them, and be handed the seed. Seats now carry a secret token, never broadcast. Live run from tonight: 13% survived against the original, 34% re-baselined after the break, break correctly attributed. The abduction called it "vividness, 78% confidence." The salience-5 detail (a cat asleep in a pastry box) outlived every other claim — textbook Bartlett sharpening.

Models
Claude Opus 5 in Claude Code to build it. anthropic/claude-haiku-4.5 via OpenRouter at runtime for proposition decomposition, per-hop NLI entailment, abduction and narration.
Cost
Runtime: ~15 model calls per 7-player game, roughly 1-2 cents. Build session tokens I didn't track.
Prompts & issues

Best thing I did was make the agent read the whole repo and argue with the premise before touching it. It came back with "this is serial transcription, not serial reproduction" — the message never disappeared, so the drift being measured was mostly people choosing to paraphrase. That reframed the whole build. Bugs it found by writing tests for code that had none (45 unit + an end-to-end that drives a real game): - properNouns only guarded word index 0, so the first word of EVERY sentence after the first counted as a name. "Yesterday she left" reported a lost name "Yesterday". - numChanged recomputed the same replacement each iteration: 3 and 7 -> 50 and 60 reported both as becoming 50, plus a phantom invention. - buildReveal dropped each version's ai field, so the AI-confederate tag in the reveal could never render. - The alluvial diagram had never been visually confirmed against a live reveal (the README said so). It clipped its labels and stacked invented ribbons on top of each other. Both regression tests were verified failing against the pre-fix code — a regression test that doesn't catch its bug is worthless. Deploy pain, in order: - pnpm's minimumReleaseAge rejected wrangler/miniflare (published that day) even as devDependencies. Image now installs only ws via npm. - Railway's own control plane threw a Prisma error mid-deploy: "column Workspace.supportTierOverride does not exist". Couldn't read our service config, silently fell back to Railpack instead of our Dockerfile, failed with zero build output. Waited it out. - My own worst bug: porting Cloudflare Durable Objects to Node, I listed env vars individually and forgot USHER_MODEL. Every model call used the wrong slug, OpenRouter 400'd, and the retry loop swallowed it — the entire AI layer silently vanished with nothing in the logs. Fixed by forwarding all USHER_* vars and making /api/health report the model slug, so config errors are visible without SSH. Neat bit: the port doesn't fork the game logic. server/node.js implements the small slice of the Durable Object API that Room actually uses, then imports Room unchanged. Same end-to-end suite passes against both hosts, 17/17.