Behind Kismet

How the draw stays fair (and why the owner can’t peek)

Kismet only works if everyone believes the draw. The moment one person suspects the owner rigged movie night, the product is a fancy way to argue. So fairness isn’t a feature here — it’s the architecture. Four invariants hold it up:

1. The draw happens only on the server

No client — iPhone, Android, browser — ever computes, influences, or previews the pick. At the scheduled draw time, our server selects uniformly at random among the sealed submissions. The app you’re holding is an audience member, not a participant. There is nothing in the binary to tamper with, because the binary was never asked.

2. The seed and result are persisted

Every draw stores its random seed and its outcome. That gives every result a paper trail: what was drawn, when, from how many, with what randomness. “Provably fair” is a strong phrase — this is the receipts version of it.

3. Hidden means hidden — all the way down

Until the draw, submissions are invisible to every participant, including the owner who created the activity — and the rule is enforced at the API, not the UI. No endpoint returns another participant’s pick pre-draw. No websocket payload leaks one. Even our own admin screens don’t surface pick contents. It’s not “the app hides them” — the system never hands them out. And losing picks? Sealed forever, by policy and by test suite.

4. Sealed is immutable

Once the scheduled lock passes, the pool is frozen — no edits, no additions, no owner overrides. (One humane carve-out: an owner who sealed early can reverse that early seal only while the scheduled lock is still in the future. Past the schedule, final is final.) The draw always operates on a pool nobody could adjust after seeing the clock run down.

Why the owner gets no privileges

Every no above is aimed at the person with the most temptation. The owner sets the stage — type, times, invites — and then becomes exactly as powerless as everyone else. That symmetry is what makes “let fate decide” a promise instead of a slogan: fate is only fun when it’s real, and it’s only real when nobody holds the dice.

These four invariants live in our test suite as non-negotiables — changes that would weaken them fail the build. That’s on purpose. Some code should be hard to write.