Circuit is ten daily puzzle games on one site with one record across them: Cipher, Abacus, Atlas, Doublets, Fathom, Hardwood, Hivemind, Keystone, Meridian and Outlier. The people who play dailies every morning play them on a dozen unrelated sites, with a separate streak on each and no way to tell whether they are getting better. Circuit starts from the bet that the games are the inventory and the layer across them is the product. Anyone can play from the first tap; signing in with Google keeps the streak beyond the browser.
The success bar was set before any code: about twenty friends and I play most mornings and keep our streaks. Strangers who stay, and eventually pay, would be better, but the design doesn't depend on them. What it does depend on is the operating side: a puzzle supply that never misses a morning, content that agents drafted and reviewers checked, and a cost of zero.

A puzzle plays only after someone approves it
Nothing is drawn on request. Each puzzle is generated ahead of time and stored, and it moves through three states: a draft until a reviewer approves it on the admin page, approved until its day arrives, and live from then on. A Cron Trigger runs at 05:01 UTC, one minute after the day turns, promotes everything approved up to today, and drafts the next 14 days for any game that has none. A second run at 05:31 promotes again, so a failed first run is covered.
The order of those rules is the point. An approved puzzle is playable from the start of its day, and the cron's promotion records that rather than causing it, so a late or missed cron run costs nobody a puzzle. The build refuses to ship a bad answer list: it fails if a word is on the blocklist, if an answer is over its par budget, or if a bundled word module is out of date.

One standing, honest at small numbers
Games give scores that cannot be compared: guesses used, a factor off, points. The obvious common currency, your percentile against today's players, breaks at twenty players. It moves in steps of 1 in 20 and swings on who happened to show up. So every puzzle ships with a par, computed by a reference solver and capped, which works with one player.
Then I played every game, and par read worse on screen than it did on paper. It left the interface. It still sets each puzzle's difficulty and the rotation, but the solved screen now shows the result as one large figure, your last 30 days of that game, your streak, and how you compare with everyone else today. That comparison appears only once 10 players have finished the puzzle. Before that, nothing is shown in its place.
There is only one streak, site-wide, and finishing any one daily keeps it going. Miss a day and the streak survives if you finish that day's puzzle from the archive within 48 hours, twice in any 30 days. A repaired day is marked as repaired.

Content drafted by agents, gated by blind review
Ten games a day for months is a lot of content. Agents drafted the questions, a pipeline checked them, and reviewers who hadn't seen the answers sampled them against bars set before the results came in. Two of those gates failed first.
Keystone shows clue words and asks for the word that links them. The plan was to score guesses by GloVe word-vector similarity. Measured on the drafted rounds, GloVe accepted 29.7% of bridge rounds against a gate of 40%, and ConceptNet Numberbatch managed 32.9%. So bridge rounds moved to drafted boards of graded answers, and only the closest-word rounds kept GloVe. The bank that shipped holds 806 rounds. Its first final review failed: recall 0.82 and within-one 0.87, against bars of 0.90. Once the boards were widened, a second review passed at 0.96 and 0.94.
Fathom is napkin math, three questions a day, scored by how many orders of magnitude off you are, averaged. It began as recall of national statistics and was rebuilt around questions worth working out. Of 737 drafted, 116 shipped after research, blind estimates, checking every source against the opened page, and a screen for napkin math. The bar was 80% of a 40-question sample enjoyed, and the last sample missed it by one, at 31 of 40. Every question a reviewer didn't enjoy was cut. I shipped the 116 knowing that.
| Gate | Bar | First result | Shipped on |
|---|---|---|---|
| Keystone word vectors (bridge rounds) | 40% accepted | 29.7% | drafted boards instead |
| Keystone final review, recall / within-one | 0.90 / 0.90 | 0.82 / 0.87 | 0.96 / 0.94 after widening |
| Fathom, enjoyed in a sample of 40 | 32 | 24 | 31; shipped by decision |
Free tiers as the design brief
Circuit runs on Cloudflare Workers Free and Neon Free, so its limits shaped the code. A request gets 10 ms of CPU, and the gzipped Worker stays under 2,050 KiB. Fathom's and Keystone's question text lives in Postgres, reached through Hyperdrive; only indexes, par tables and the attribute games' fact tables are bundled, so the runtime never runs a solver. The cap applies to cron runs too: six games' first draws in one run measured about 9 ms, so generation is split between the 05:01 and 05:31 runs, each game in exactly one. The games list and today's live set are remembered per isolate for 60 seconds.
The deploy script exists because of a trap in the adapter. OpenNext copies every .env file it finds into the bundle as fallback values, so a plain deploy could ship a laptop's secrets as production's defaults. The script blanks them before upload, so a missing secret fails closed. The same rule runs through the rest: the admin allowlist means nobody when it's unset, and the cron route returns an error and does nothing without its token.
The games keep changing after launch without breaking anyone's day. Hardwood's card now has six clues, from height and rookie year to latest team and conference, and a play begun on the old card finishes on it. Hivemind and Outlier now play one stage at a time. The new cell colours are tested for contrast and for colour-blind players.
What isn't done yet is written down too. I have no usage numbers worth citing, and Fathom's 116-question bank is due a top-up before its first repeats come round.