Behind Kismet

Hidden means hidden: engineering invisible picks

“The picks are hidden until the draw” sounds like a checkbox. It’s actually a discipline that touches every layer of the system — because a secret is only as good as its leakiest endpoint.

The threat model is your own curiosity

Nobody’s nation-state is attacking movie night. The realistic adversary is a curious owner with a browser inspector, a crew member watching the network tab, or a future developer adding a convenient field to an API response. The defense is the same for all three: the data never leaves the server.

What “never leaves” means in practice

  • API responses carry booleans, not bodies. Pre-draw, an activity’s roster says has_submitted: true — never what. Your own pick is the only one you can read back.
  • Realtime events count; they don’t describe. The live “3 of 5 picks in” moment is powered by counts alone. A websocket frame that included pick contents would be a leak with excellent latency.
  • The admin panel is on the outside too. Support tooling shows activity state, never submission contents. Operational access isn’t a peek license.
  • The reveal unseals exactly one. At the draw, the winner’s payload becomes readable. The losers never make the trip — sealed rows stay sealed, forever.

Tested like an invariant, not a feature

Policy tests assert the negative space: that endpoints do not return other picks pre-draw, that events do not carry payloads, that the winner is the only unsealed row after a draw. Negative tests are the ones that catch a helpful refactor six months later — the whole point is making the leak fail CI before it ships.

The product payoff

All this machinery buys one emotional outcome: submitting feels safe. The quiet friend’s real preference enters the pool because nobody can see it, judge it, or lobby against it. Fairness is the architecture; honesty is what it purchases.