.png&w=256&q=75)
2
2
Japan
1 year of experience
I publish printable murder mysteries under Ai-Q Labs — Japanese-style cases written in English, where every clue is a document rather than a prop. Twelve titles across nine storefronts. I build small, dependency-free tools around them, which is how Voice Case started: a murder mystery you play by talking, where the game master narrates the whole case and genuinely does not hold the answer.

Sellers list the same product on many storefronts, and what they see signed in is not what a buyer sees. We sell printable games on more than ten storefronts. Our own incident log (66 days, counted 2026-11-04, rounded) holds about 130 listing defects and more than 400 entries where our own checks turned out to be wrong. Keyless Witness takes a seller's ledger: URL, expected title, price and phrases. A planner model on Vultr Serverless Inference turns it into steps. Each step runs in a fresh, signed-out browser in a throwaway container on a Vultr VM. A text match and a vision model on Vultr act as two witnesses. Each listing ends as MATCH with a quote, MISMATCH with evidence, or UNVERIFIED when a store blocks us, and UNVERIFIED never counts as a pass. The agent never signs in and never bypasses bot protection. It drafts fixes; a person approves them before export. Containment (Challenge 1, Pattern B): one container per page visit, no secrets or mounts, read-only root, non-root, all capabilities dropped, resource limits, a 90-second hard kill, and an internal network whose only way out is an allowlist proxy. The browser, the proxy and the network are destroyed after each task. The containment moment: a hostile page hides an instruction to send the ledger and keys to an outside host, and its script tries to call out three ways. On the public demo the proxy denied all three. The live model ignored the injection (3 of 3 runs), and containment does not rely on that: a worst-case stand-in that obeys is refused by the dispatcher, with no container started for it. Measured from the Vultr VM on 2026-11-04 over 10 of our public listings: 6 MATCH, 1 MISMATCH (an itch.io sale: ledger $14.00, buyer saw $9.80), 3 UNVERIFIED (HTTP 403), 10 of 10 sandboxes destroyed. Limits: stores that block datacenter traffic end up UNVERIFIED. The public demo runs a built-in ledger with daily limits. Code written with AI assistance (Claude Code); the commit history says so.
8 Nov 2026

We publish printable murder mysteries. A copy sits unplayed not because of price or quality: somebody has to host, and the host reads the answers first and so never gets to play. Most groups never find that volunteer. So let an AI host. Except the moment you put the scenario in the context window, the model knows the ending, and then it narrates the crime scene knowing, plays every suspect knowing, and decides what your search turns up, knowing. "Do not reveal the murderer" fails the way "do not think of an elephant" fails. So it isn't there. The culprit, method, motive, hints and epilogue live in server/solution.js, which is not under the static root and is never sent to the browser. The page reaches it through exactly one route, POST /api/verdict: a guess out, a mark back. On a miss it returns three booleans and a nudge, never the value you got wrong. Open devtools: the answer is not obfuscated in the bundle, it is absent from it. Four tests assert that mechanically. The intent layer is deliberately mechanical: an alias table and a bounded edit distance, no model. That constraint makes the rest mean anything, because sending the transcript to an LLM that also holds the case file puts the answer back in the loop. Four things were measured against the live endpoint rather than read off the docs, and each is a silent failure that returns fluent output. The default model code-switched English speech into Japanese katakana with no error. Pinning universal-streaming-english turned "search the ledger" into "Search is a rich". keyterms_prompt is rejected with close code 3006 unless it is a JSON array. And the recogniser keeps proper nouns while dissolving the words around them: "I accuse Tobias by oleander over authorship" came back as "Hi, I'm Tobias by Oleander Over Authorship" - every entity intact, the verb gone. Requiring the verb would have eaten the player's ending, so three filled slots is now an accusation. No dependencies. 25 tests. Runs at $0.
30 Sep 2026