Josie Nelder

All work

Cluedefy

A detective game you play by typing your own questions. I built the app, its backend and the AI-assisted pipeline that helps write each mystery.

Role
Product, design and engineering, directing AI agents
Team
Solo
Years
2026
Status
Launch-ready
Disciplines
  • Web
  • API
  • AI
  • Data
  • Infra
  • Mobile

The product

Cluedefy is a detective game for iPhone. Players question suspects and examine evidence by typing, not by picking from a menu: "Speak to Mrs Dunmow", "Take a look at the box".

Every reply is written by hand and goes into the player's notebook. To leave a scene, the player writes what doesn't add up. It only counts if the evidence for it is in their notebook.

Each story ends with an accusation: culprit, method and motive.

Cluedefy’s scene screen in dark mode. The player has typed “Take a look at the box”, and the reply describes a small wooden jewel box: the tray where the garnets lay is empty and everything else is in place. Below the reply, a card reads “Added to notebook: The jewel box”, and a panel asks “What doesn’t add up here?”
A typed probe, matched to an authored lead and added to the notebook.
The opening of the starter mystery, Non-Stop to Sandbourne.

Role

I'm the only person on Cluedefy. I own the product, the design, and the engineering across three codebases: the Expo app, the Firebase backend, and an admin and authoring tool. I also make the editorial decisions on every mystery.

How I work with AI agents

Most of the code is written by AI coding agents that I direct. Each change starts as a product requirements document, which I split into tickets with explicit dependencies. Agents work through them in waves.

  • Specs first. Architecture decisions are recorded as ADRs. Agents check each ticket before starting and stop to ask rather than guess.
  • Models matched to tasks. The most capable model plans mysteries and anything that needs judgement. A faster model implements code tickets.
  • Fresh context for review. Critics and solvers never see the work that produced what they're judging.
  • Automated gates. Tests, type checks, rules tests and schema validation decide whether work lands, not an agent's own report.
  • Irreversible steps stay with me. Agents don't deploy, publish or add dependencies without my approval.

Architecture

The app reads and writes Firestore directly for anything a player owns: published stories, their progress and their notebook.

Anything that needs judging goes through a single game API: a probe, a deduction or an accusation. It's the only component that can read answer keys or change game state.

How Cluedefy fits together Select a part to see what it does. Arrow keys move between parts.

Player-facing app

Cluedefy app

The iPhone game. Players question suspects and examine evidence by typing in their own words. The app reads stories and saves progress in Firestore itself, and sends anything that needs judging to the game API.

Connects to

Player-facing app

Player-facing app

Cluedefy app

The iPhone game. Players question suspects and examine evidence by typing in their own words. The app reads stories and saves progress in Firestore itself, and sends anything that needs judging to the game API.

Connects to

Backend · Cloud Functions

Firebase services

Third parties

Authoring & admin

Read the diagram as a list
  • Player-facing app

    • Cluedefy app (Expo · React Native · iOS). The iPhone game. Players question suspects and examine evidence by typing in their own words. The app reads stories and saves progress in Firestore itself, and sends anything that needs judging to the game API. Connects to: Game API (sends typed questions); Authentication (sends signs in); Analytics (sends usage events); App Check (sends gets a token); Firestore (sends reads stories, saves progress); RevenueCat (sends purchases); Shared contracts (receives generated types).
  • Backend · Cloud Functions

    • Game API (One HTTPS function). A single Cloud Function routes every player action: examine, deduce, accuse, hints, puzzle answers and puzzle hints, reviews and account deletion. Each request must carry the player's sign-in token, every route has a per-player rate limit, and it can turn away any request without an App Check token. Connects to: Cluedefy app (receives typed questions); Deterministic matching (sends first); Firestore (sends server-only game state); Blind playtests (receives plays the real game).
    • Deterministic matching (Runs first). Plain code answers most requests. Keyword and alias matching works out what a question is about; a pre-check rejects empty or repeated deductions and returns cached verdicts; hints and puzzle answers never touch a model at all. Connects to: Game API (receives first); AI fallback (sends fallback only).
    • AI fallback (Genkit, budgeted). When matching can't tell what a question means, Genkit asks Gemini to classify it. Written deductions and the final accusation are graded by Gemini against the authored solution, as structured output that's validated before use. Every model call counts against a per-player daily budget; past it, play carries on without the AI-graded steps. Connects to: Deterministic matching (receives fallback only); Google Gemini (sends classify and grade).
    • Purchase webhook (Server to server). RevenueCat calls this when a purchase changes. It checks a shared secret, then merges the player's plan into their entitlements record. Players can read their entitlements but never write them. Connects to: RevenueCat (receives purchase events); Firestore (sends entitlements).
  • Firebase services

    • Authentication (Firebase Auth). Handles sign-in. The app asks new players to verify their email before they play, and the game API checks the sign-in token on every request. Connects to: Cluedefy app (receives signs in).
    • Analytics (Usage events). Records how players move through the game, so I can see where people get stuck. Players can switch it off in their profile. Connects to: Cluedefy app (receives usage events).
    • App Check (App Attest). Proves a request comes from the genuine app on a real iPhone, using Apple's App Attest. The app attaches a token to each call to the game API. Connects to: Cluedefy app (receives gets a token).
    • Firestore (Rules-tested). Holds stories, player progress, entitlements and reviews. The security rules deny by default: players read published stories and their own records, while answer keys, game state, logs and budgets are server-only. The rules have their own test suite. Connects to: Cluedefy app (receives reads stories, saves progress); Game API (receives server-only game state); Purchase webhook (receives entitlements); Admin app (receives validated import).
    • Storage (Covers). Holds each mystery's cover art. The admin tools upload it and the app loads it by URL. Connects to: Admin app (receives uploads covers).
    • Hosting (Website). Serves Cluedefy's small public website: the home page, privacy policy and support page that the app links to. Connects to: .
  • Third parties

    • Google Gemini (Text and image models). Gemini 2.5 Flash interprets and grades players' free text at runtime, but only when plain code can't. A Gemini image model draws the cover art during authoring. Connects to: AI fallback (receives classify and grade); Authoring workshop (receives cover art).
    • RevenueCat (Purchases). Runs App Store subscriptions and one-off purchases in the app, then tells the backend about each change through the purchase webhook. Connects to: Cluedefy app (receives purchases); Purchase webhook (sends purchase events).
    • Claude (Anthropic). Does the writing and checking in the authoring pipeline: the architect who plans each mystery, the scene writers, the independent critic and the blind solvers. Connects to: Authoring workshop (receives writers' room).
  • Authoring & admin

    • Shared contracts (JSON Schema). JSON schemas define every story, scene and progress record. A script generates TypeScript types from them into the app and the admin tool, and a check fails if those types drift. The backend keeps hand-written copies of the few shapes it needs. Connects to: Cluedefy app (sends generated types); Admin app (sends generated types).
    • Admin app (Vite · React · Express). A local web tool. It validates each story against the contracts, the story graph and the prose rules, then imports it into Firestore. It also uploads covers and manages test access and reviews. Connects to: Shared contracts (receives generated types); Firestore (sends validated import); Storage (sends uploads covers); Authoring workshop (receives finished story).
    • Blind playtests (Two-solver panel). AI solvers play each new story through the real game API, seeing only what a player sees. Their verdict on whether the mystery is fair is the gate before publishing, and I play it through myself as well. Connects to: Authoring workshop (receives each new story); Game API (sends plays the real game).
    • Authoring workshop (Writers' room). Where mysteries are written. An architect model plans each story, scene writers draft it, and an independent critic and machine checks review it. I approve each blueprint and decide what gets published. Connects to: Claude (sends writers' room); Google Gemini (sends cover art); Blind playtests (sends each new story); Admin app (sends finished story).
  • Server-only answer data. Answer keys, deduction configs, game state, logs and budgets live in collections clients can't read. The security rules deny by default and have their own test suite.
  • Shared contracts. JSON Schema defines every story, scene and progress record. A script generates TypeScript types into the app and the admin tool, and a check fails if they drift.
  • Validation before import. A story reaches Firestore only after it passes the schema, fair-play checks on the story graph and a prose linter. The graph checks cover dead ends, clue reachability and machine-solvable puzzles.

Runtime AI

Plain code answers first. Each scene has authored leads with trigger phrases, and a deterministic matcher picks the lead a probe refers to. The player always gets the authored response.

The model never writes text the player reads as fact. Hints and puzzle answers never call a model.

Gemini, through Genkit, is used in two places:

  1. Classifying probes the matcher can't place. The model chooses one of the scene's authored leads, or none. Its structured output is validated before use.
  2. Grading deductions and accusations. Each element (culprit, method, motive) is graded against the authored solution as solved, partial or missing. A correct deduction without its evidence in the notebook gets coaching, not a solve.

A pre-check rejects empty and repeated deductions before any model call, and repeated verdicts are cached.

Every model call counts against a per-player daily budget. Once it's used up, play continues without the AI-graded steps.

Authoring pipeline

Each mystery goes through seven stages:

  1. Blueprint. An architect model plans the solution, each scene's contradiction, where every fact is planted, the red herrings and the puzzles. I approve every blueprint before any prose is written.
  2. Scene writers. One agent per scene, each in a fresh context with only a need-to-know brief and the house style guide.
  3. Integration. The architect checks the drafts against their briefs, edits for voice, and writes the server-only material: answer keys, hints and reveals.
  4. Critics. Fresh agents review each scene and the whole story. Every flag is reworked and re-reviewed by a new critic.
  5. Machine validation. Schema and story-graph checks, puzzle solvers, a prose linter, and a smoke test that sends every character's name to every scene through the real matcher.
  6. Blind panel. Two AI solvers, one methodical and one impatient, play through the real game API with only a player's view. Each has a fixed budget of probes and attempts, and a third solver breaks ties.
  7. My playthrough. I play every story before it's published.

Security and cost

  • Sign-in checked on every request, with per-player rate limits on every route.
  • App Check with Apple's App Attest, so the API can reject requests that don't come from the genuine app.
  • Input caps on every field that reaches a model, with explicit error responses.
  • A per-player daily model budget, checked before each call.
  • Entitlements written only by the server, from a RevenueCat webhook that checks a shared secret.
  • Tests for the Firestore security rules.
JavaScript
// Entitlements: written by the server, read by their owner.
match /entitlements/{userId} {
  allow read: if isOwner(userId);
  allow write: if false;
}

What broke

The starter mystery, Non-Stop to Sandbourne, passed every stage above. A blind solver solved it without hints. In my own playthrough I found six defects:

  • Two hints described testimony I hadn't heard. Scene 1 could be cleared without the witness account that scene 2's deduction depended on.
  • Two characters moved between carriages with no explanation.
  • Typing "Colonel" on its own got no match, because only "the Colonel" was an alias.
  • One scene ended with an instruction to the player instead of a line of story.
  • A notice on the carriage wall was mentioned without saying what it said.

I fixed the story the same day, then changed the process:

  • Setup checks. Each gate only checked its own scene. Now every fact a scene depends on must be available in that scene and pointed to in the narrative, and the smoke test fails stories that break this.
  • More realistic solvers. A strong model asks the right questions; players often don't. The panel gained a budgeted, impatient solver, and every solver must start by typing bare character names.
  • Easy means easy. Any friction in scene 1 of an easy story now blocks it from publishing.
  • Catalogue sweeps. The rule against hints assuming notebook contents only applied to new stories. Rule changes now include a sweep of every story; the first sweep found the same defect in another live one.

Status

Cluedefy is launch-ready. The game, the backend, App Store purchases and a catalogue of panel-tested mysteries are complete.

I've chosen not to publish it yet, because doing so properly means registering a business.

Next: more mysteries through the pipeline, then visual evidence (images that carry clues, checked by a vision model) and audio evidence.