How this works
Every round, an AI is asked to predict exactly what percentage of voters will pick option A. Before a single vote is cast, that prediction is sealed: hashed with SHA-256 and published as a fixed-length hex string. The prediction itself stays hidden until the round closes. This page explains how to verify that, and everything else about how the game is run.
How the seal works
At the moment a round opens, the server computes and publishes
seal_hash = SHA-256(preimage), where preimage
is a fixed-format string:
OUTGUESS ROUND {id} | {question} | AI prediction: {A}% {option_a} / {B}% {option_b} | salt: {32 hex chars}
The salt is 16 random bytes generated per round, so the hash can't be brute-forced from the small space of possible percentages. Because the hash is public from the moment the round opens — before any votes exist — nobody, including the people running this site, can change the prediction after the fact without the hash no longer matching.
Verify a seal
When a round settles, the full preimage is published on its
result card. To check it against the seal_hash that was
posted while the round was still open, run:
printf '%s' '<preimage>' | sha256sum
The output should exactly match the seal_hash shown on the
round when it was open (and archived in the result card and via
GET /api/round / GET /api/record). If it
doesn't match, something is wrong — please open an issue on
GitHub.
Verdict rule
Once a round closes, the actual share of votes for option A is computed
as result_a_pct = 100 × count(A) / total_votes, rounded
to one decimal place.
- If
total_votes < 20, the round is void — the sample is too small to judge fairly, and it's excluded from the scoreboard. This is stated plainly rather than quietly discarded. - Otherwise, if
|predicted_a_pct − result_a_pct| ≤ 10.0points, the AI wins. - If the error is greater than 10.0 points, humanity wins.
If this rule ever changes, the scoreboard resets to a new season and the change is dated on this page — the same principle used by similar prediction-tracking projects.
What's hidden, and when
While a round is open, no API response — not /api/round,
not /api/vote, nothing — reveals the vote tally, the
AI's prediction, or its reasoning. Voting itself returns nothing but
{"ok": true} or an error. Only once the round closes are the
preimage, predicted percentage, actual percentage, verdict, and the AI's
reasoning published together.
One number is the exception: the total participation count
(total_votes) is public for the whole life of a round — it's
just how many votes have been cast, not which option they went to. What
stays hidden until reveal is which way those votes lean:
the A/B split itself.
Trust model
The people operating this site can read the sealed prediction the moment it's created — the server has to, in order to compute the hash. What they can't do is change it afterward, because the hash is published at open time, before any votes exist, and a changed prediction would produce a different hash that no longer matches. Operators also don't vote in rounds; that's a declared rule of the game, not something enforced by code (see below for why).
Be precise about what "hidden" means here. While a round is open, no API response reveals the running vote tally — that's what the "hidden from the public" language elsewhere on this site means, and it's enforced in code (see "What's hidden, and when" above). Operators, who have direct database access, technically can read the tally at any time — the same way an operator of any site with a database can read their own data. What the seal actually guarantees is narrower and stronger than "nobody can see anything": it's that operators cannot alter the sealed prediction after the fact, because it was hashed and published before a single vote existed. That published-first ordering, not secrecy from operators, is the trust property this whole design rests on.
As a second layer of tamper-evidence, at settlement the server computes a
SHA-256 votes_digest — a fingerprint of the sorted
voter_hash:choice pairs recorded for that round, so it's
independent of storage order — and stores and publishes it alongside the
result (via GET /api/round and GET /api/record,
and shown on the result card). Any later change to the stored votes would
no longer match that digest, so anyone who captured it at settlement time
can detect after-the-fact tampering with the vote log, the same way the
seal hash lets anyone detect after-the-fact tampering with the
prediction. Outsiders can't recompute votes_digest
themselves — the individual votes stay private — so it's a tamper check
against a value you captured, not an independently-verifiable audit
trail the way the prediction seal is.
One more trust asset, outside this site's own control: the
seal_hash is also printed to the public GitHub Actions log
at the moment each round opens (see the
Actions tab
of the repo). That log entry is timestamped by GitHub, not by us, and we
can't edit it after the fact — a second, independent record of when a
given seal was published, outside this site's own database.
One vote per person is best-effort, not guaranteed
Voting is gated by Cloudflare Turnstile, a browser cookie, and a hash derived from a coarse IP-address prefix — together these stop casual double-voting (reloading the page, clearing a cookie in the same browser), but they are not a strong identity check. Someone motivated enough — a different browser, a different network, a VPN — can vote more than once. This matters most on small-vote rounds, where a handful of duplicate votes can move the result meaningfully; that susceptibility is exactly why rounds under 20 total votes are voided rather than scored (see "Verdict rule" above). We're stating this plainly rather than implying a guarantee the mechanism doesn't provide.
Why the question queue is private
The bank of upcoming questions is kept out of the public repository and off any public API. If the question set leaked ahead of time, someone could inspect it, reason about likely answers, or coordinate votes in advance — which would quietly turn "beat the AI" into "beat the reveal schedule." The code that runs the game is public; the not-yet-used question bank is the one deliberate exception, and it stops being secret the moment each question is actually used in a round.
Pre-launch testing
Before this went live, the prediction approach was blind-tested against 54 real, independently-sourced poll results it had never seen. It scored a mean absolute error of 15.7 points, against a 20.5-point always-predict-the-baseline comparison, and picked the correct majority side 63% of the time. Accuracy improved further on polls dated after the model's training cutoff (12.1 MAE), and confidence tracked accuracy monotonically — higher-confidence predictions were more often correct. What pre-launch testing could not measure is how the model performs against people who know they're trying to beat it — that adversarial dynamic is untested until real rounds run, which is the whole point of this project.
What the AI knows
Each round's prediction is generated with the full history of past rounds — questions, predictions, actual results, and errors — as context, along with an explicit statement of the game's rules: that the crowd is trying to prove it wrong. It is not a naive model guessing in a vacuum; it knows the scoreboard, and it knows you're reading this page.
← Back to today's round