Stateful AI · the model is the gameplay

One of them is lying to your face.

Something's been stolen; three suspects are in the room. You question them in plain English and they answer in character — and the guilty one keeps insisting on an alibi that doesn't hold. Cross-examine, catch the contradiction, name the thief. The suspects' answers, their nerves, the lie they cling to: all the model.

A real case (local 7B, $0 — seed 7)

⌁ the safe in the office was emptied (after midnight).
In the room: Priya, Sam, Omar. One of them is lying.
Priya: "I was in the cellar alone, just like I said during the investigation. Nobody was with me."
Sam: "I was on the terrace, alone. Anyone saying otherwise is mistaken."
Omar: "I was in the garden with Priya the whole time. We stayed there until morning, just enjoying the quiet."

› you ask Priya about Omar's claim:

Priya: "No, I wasn't with Omar during the crime. I was in the cellar alone, as I always am after work."

› accuse Omar

➜ The thief was Omar. He claimed the garden with Priya — but Priya was never there.
✅ Case closed — you caught the contradiction.

Omar invented a corroborator who wouldn't corroborate. The model played the lie and the nerves; the contradiction was always there to be caught.

Why every case is fair

A deterministic floor guarantees the catch. The case, the guilty party, and one guaranteed-catchable contradiction are generated by seeded, unit-tested code: innocents tell the truth and corroborate; the guilty one lies about where they were and falsely names an innocent who'll deny it. So every case is solvable and checkable, no matter what the model says.

The model is the voice, never the verdict. Each suspect answers strictly within their assigned facts — the LLM supplies character and nerves, not the truth of the case. $0-local (any OpenAI-compatible endpoint, stdlib only); degrades to a flat scripted suspect if no model is up.

← all the playable models