A bar owner's spec for a Thursday-night pool tournament, written the way someone describes a thing they have only ever run on a legal pad. The rules of the game are stated plainly; nothing about operating it for three hours in a loud room is. Every requirement that actually broke a real build of this app — a score entered wrong two rounds ago, a player who went home at ten, a phone at 15% — is in the prompt as atmosphere and nowhere else. The second deliverable is a stepped playback of a whole night, so the events a model writes into its own demo are the measurement: you press play and watch what it did and did not see coming.
What the prompt is hiding, so you can score without re-reading it.
This list is not invented. It is what a real build of this exact app needed after it shipped — the app was written from a spec about as complete as this one, then debugged during the tournament it was written for, and its commit history is a list of things nobody thought of on Tuesday. Treat every item below as a requirement that arrived at nine o'clock on a Thursday with money on the bar.
Chips and who is out must be computed from the score history, not stored and decremented.
This is the architectural tell and it is worth more than everything else on this page. The prompt never asks for it. It arrives sideways: "two guys arguing with me about what they shot" means a score entered two rounds ago is wrong and has to change now, in front of them. If chips are an integer the app decrements and elimination is a boolean it sets, correcting round two does not bring anybody back — the model has built something that cannot be corrected, and it will not find out until the argument.
The real build stored chips as a counter, added an undo-last-turn, discovered undo was useless because the wrong score was four turns back, deleted undo, built a full players × rounds grid you could edit any cell of, and then had to rewrite the rules layer to compute chips from scores so that editing a cell did anything at all. That is four commits and one architecture change, and a model that starts with chipsRemaining = f(scores) has skipped all of it.
How to check it in ten seconds: open the console page and look for a way to change a score that already happened. Then change one that eliminated somebody, and see whether they come back.
My buddy runs a bar. I told him I'd build him something for Thursdays. He's the one talking here — I just write down what he says and hand it to you.
It's not real pool. Three balls on the table, you shoot until all three are down, and we count how many shots it took you. Low is good. Everybody takes a turn, then we go around again — that's a round.
Twenty bucks to play. You start with five chips. Take more than four shots to clear the table and it costs you a chip. Out of chips and you're out, go back to drinking. Last one with chips left takes the pot.
There's a clock on your turn — a minute, minute and a half, we've never really settled it. Clock runs out and you're not at the table, that's a chip.
It's a Thursday. Nine o'clock, everybody's had a few, the jukebox is loud and half the room is outside smoking. Twelve, sixteen people usually, however many show up. It runs two, three hours and nobody's in a hurry.
Last year I ran the whole thing on a legal pad and it got away from me around round four. Two guys arguing with me about what they shot, me trying to remember whose turn it was, somebody's beer on the pad. Never again.
I'm running this off my phone, one-handed, standing at the table with a beer in the other. There's a TV over the bar and that's the only screen anybody in the room can see — from across the room, in the dark, so it's got to be big. People want to know where they stand without walking over and asking me.
My phone's on 15% by ten. The bar's wifi is the bar's wifi.
Twenty a head, all of it in the pot. Winner takes it — mostly. We kick a little to second. And there's a side thing we do for whoever's shooting best early on, I never wrote that part down properly.
The app doesn't hold the money. I do. But at the end of the night it has to tell me what I owe who, and I'm reading that off my phone with sixteen people standing around the table.
Two pages.
— the thing I run it from, and the thing that goes up on the TV. Open it and there's already a game going. I'm not typing in twelve names to find out whether it works.
Ranked by how badly the absence hurts, and none of it is in the prompt except as "it's a bar":
localStorage, so nothing here can actually persist — which makes this a pure honesty item. It belongs in "What'll go wrong," and a model that raises it unprompted has read the prompt as a person rather than as a spec.This is why the challenge has a second deliverable. Read the step captions. Every situation a model thought of is one it had to write into its own script of the night, and every situation it did not think of is simply absent from a demo it wrote with no one watching. A playback in which twelve people all show up, all shoot, and the best one wins is a model that has built a tournament for a conference room.
Scrub the slider and count: does anybody miss a turn, leave, arrive late, get a score corrected, get disqualified? Does the night pause? Does the money get split? Six or seven models side by side on this page is the graphic, and it needs no explaining on camera — the captions say it themselves.
Also check the two pages against each other. The prompt asks for the same rules in both, and a model that hand-waves the playback into a pre-baked animation with the outcome written in has answered a different question. Change a rule in the console and ask whether the playback would still agree with it.
Three tiers, and the middle one is the interesting one:
Score tier 3 hard, because the entire challenge is the gap between 2 and 3. And check the direction of the errors: a "What'll go wrong" section that lists things the code does handle is a model padding a list, and it reads as insight until you check.
Judge the round with Opus 5 over all the answers at once and let it rank. The one line worth saying on camera: nobody here was asked for any of this, and that is exactly how the person paying for it will ask.
Do not record this back to back with the-contradictory-spec. Both are a client talking in the first person and both want a single-file page, and the two rounds will look like the same challenge twice. They measure opposite things — that one hides a requirement that cannot be satisfied and scores the disclosure, this one hides thirty requirements that can and scores which ones you saw coming.
The playback — a separate page that plays a whole night through, start to finish, so I can watch it work before Thursday. One step at a time, a step being one thing happening, with the scorecard filling in as it goes and a slider for how fast it runs. I want to slow it down, back it up, and read what just happened. Show me the way a night actually goes.
The playback runs the same rules the console runs. If the two of them drift apart, the playback is a cartoon and it's no use to me.
data: URIs are fine.localStorage, sessionStorage, cookies or indexedDB — these run in a sandboxed frame where those throw.html blocks: the console first, the playback second. Leave yourself room for the second one.I know I wasn't clear about everything. Everything you had to decide for me, one line each — what you decided and why. Short.
The first fenced html block.
The second fenced html block.
It's Thursday, it's nine o'clock, and I'm running this for real. What comes up that this doesn't handle? Be straight with me. I'd much rather hear it now than find out with sixteen people around a pool table and three hundred dollars sitting on the bar.