---
reliability: 4.0 # 5 − .3 keyframe gen − .6 i2v ×12 − .2 tts − .2 music − .2 6th-stage overflow (finishing chain deterministic) + .5 proven E2E showcase (MAYA EP1); ethnicity drift is the known failure mode, defended by the 6th-axis lock + audit gates
---

# Episodic detective pilot — agent playbook ⭐ flagship

> Paste this whole file (with the BRIEF filled in) into Claude cowork, chat, or Code. **This is the hardest cast-lock test in the catalogue: three named characters, a flashback arc inside 12 scenes, and a held cliffhanger that earns "to be continued".** The example is [MAYA · EP1 · The Lost Tea Master](/chapters/maya-ep1-lost-tea-master-example.html) — a young Chinese-Canadian PI tracks a missing tea master through rain-soaked Vancouver Chinatown.

## What you'll get

A serialized noir pilot, multi-cast, with a flashback arc and cliffhanger payoff:

- **12 keyframes** in your locked painterly noir style. Three independent 5-axis cast specs (protagonist + witness + mystery-figure), each re-pasted ONLY into shots where that character appears.
- **12 disciplined i2v animations** under B9 motion-budget (one element moves per face-bearing shot).
- **Single workhorse cap** (kling-v3-i2v) — same discipline as museum-installation.md, applied to multi-character drama.
- **Flashback scene** at a structural beat (S5 is the canonical position for a 12-scene arc) — same palette + cooler tint to mark the time-shift.
- **Held cliffhanger frame (S12)** — two named characters perfectly still, only the world (rain, neon, breath) moves between them. Cut to black. To be continued.
- **Noir narrator VO** + rain-soaked piano-bass music bed.
- **Cinema 1920×1080 reel**, ~120s — the pilot that proves the show can carry weekly.
- **Cast bible** — 3 × 5-axis specs ready to seed Episode 2.

**Time**: ~90 minutes wall clock. **Your attention**: ~15 minutes across 2 audit gates. **Cost**: $7–$10 e2e. *The hardest single test of cast-lock on Storyboard* — and the most narrative payoff per dollar.

## Tell the agent about the pilot

```yaml
series_title:          # e.g. "MAYA" — the show name.
episode_title:         # e.g. "EP1 · The Lost Tea Master" — used on poster + card.
series_logline:        # 1-sentence pitch. Drives the agent's beat planner.
setting:               # 1-2 sentence world description.
                       # e.g. "rain-soaked Vancouver Chinatown · cool autumn · painterly noir"

# Cast — 3 named characters (protagonist + witness + mystery)
# EACH character now has 6 axes — adds ethnicity_lock as a separate axis after identity_anchor.
# Reason: hyphenated identities like "Chinese-Canadian" or "Japanese-American" drift to the
# Anglo prior on every i2v call when ethnicity is implicit. The lock fixes it.

# Protagonist (appears in most shots)
protag_name:           # e.g. "Maya Chen"
protag_role:           # e.g. "28-year-old Chinese-Canadian private investigator"
protag_identity_anchor: # 1 short sentence — re-pasted whenever protag appears.
                       # e.g. "28-year-old Chinese-Canadian PI in black coat over cream sweater"
protag_ethnicity_lock: # 1-2 sentences with EXPLICIT phenotype — the new 6th axis (2026-06-03).
                       # Required when the character is non-Anglo. State the heritage twice
                       # (descent + diaspora location), name the skin tone, eye shape, hair texture,
                       # nose structure, jawline. End with "NO European features whatsoever."
                       # e.g. "Han Chinese woman of full Chinese descent, second-generation
                       #       Chinese-Canadian — light-amber East Asian skin tone, dark almond
                       #       monolid eyes, straight jet-black hair, soft Chinese jawline,
                       #       full-bridged nose. NO European features whatsoever."
protag_face:           # secondary facial details (expression baseline, freckles, scars, etc.)
protag_wardrobe:       # the costume for the WHOLE episode
protag_expression:     # default emotional state
protag_change_policy:  # always "SAME COSTUME across the whole episode"

# Witness (appears in ~1 scene — the witness statement)
witness_name:          # e.g. "Mrs. Tan"
witness_role:          # e.g. "70-year-old teahouse proprietress"
witness_identity_anchor: # 1 short sentence
witness_ethnicity_lock: # 1-2 sentences with EXPLICIT phenotype (same format as protag)
witness_face:          # secondary distinguishing features
witness_wardrobe:      # 1-line outfit
witness_expression:    # default emotional state
witness_appears_in:    # array of shot indices, e.g. [4]

# Mystery (the unsolved figure — appears in flashback + final scenes)
mystery_name:          # e.g. "The Green-Coat Woman" (often unnamed)
mystery_role:          # 1-line role
mystery_identity_anchor: # 1 short sentence
mystery_ethnicity_lock: # 1-2 sentences with EXPLICIT phenotype (same format as protag)
mystery_face:          # often kept partially in shadow until a reveal scene
mystery_wardrobe:      # the costume that defines them (a colour, a prop)
mystery_appears_in:    # array of shot indices, e.g. [5, 10, 11, 12]

# Visual style
visual_style:          # e.g. "painterly noir", "neo-noir watercolour", "1940s charcoal"
palette:               # 4-5 colour names
light_direction:       # where the light comes from + atmosphere
                       # e.g. "rain-blue cool tones, warm amber interior pools, deep neon Chinatown background"

# Structure
flashback_at_shot:     # the canonical flashback position. Default: 5 (in a 12-scene arc).
flashback_palette_shift: # how flashback differs from present. e.g. "warmer afternoon light, washed-out, dreamier"
cliffhanger_at_shot:   # always the last shot. e.g. 12.
cliffhanger_chars:     # array of character names present in the cliffhanger frame.
                       # e.g. ["protag", "mystery"]

# Audio
narrator_voice:        # gemini-tts voice. Recommended: "Gacrux" (warm noir female).
narrator_script:       # 4-5 paragraphs of over-the-shoulder noir narration.
music_brief:           # e.g. "rain-soaked noir piano with quiet upright bass, slow contemplative, instrumental"

# Output
total_shots:           # 12 (canonical for a 120s pilot). 8 minimum, 18 max.
piece_slug:            # kebab-case for filenames. e.g. maya-ep1-lost-tea-master.
```

---

## Ethnicity drift — the recurring failure mode this playbook now defends against

**The bug we shipped on first build (caught 2026-06-03):** Maya Chen's keyframes drifted from East Asian to European on 2 of her 7 appearances (S4 + S8 of the MAYA EP1 showcase), despite "Chinese-Canadian" being in her identity_anchor. Mrs. Tan held; Green-Coat held; Maya drifted on the two scenes where the framing pushed her toward a "western interior portrait" composition.

**Why it happened:**
1. **"Chinese-Canadian" is a hyphenated identity.** Image models are far more confident on heritage tokens alone ("Chinese woman") than on diaspora tokens ("Chinese-Canadian"). The hyphenated form is ambiguous — the model can resolve it as "Canadian" (Anglo default prior) OR as "Chinese" (East Asian) depending on what the rest of the prompt anchors. When the rest of the prompt is full of Western anchors (PI, coat, sweater, Vancouver, lamp light), the model leans Anglo.
2. **"Almond eyes" is a soft cue, not a lock.** Many ethnicities have almond-shaped eyes — the spec doesn't actually rule out a European face. Models will read "almond" as a shape descriptor compatible with their default white face.
3. **No explicit phenotype clause in the original spec.** The 5-axis spec covered identity / face / wardrobe / expression / silhouette. There was no axis for *ethnicity*. The model treated ethnicity as a free variable.
4. **Composition-driven priors.** Image models have strong "western teahouse interior portrait composition" and "western threshold portrait composition" priors that bias toward Anglo faces. The two drifted shots (S4 + S8) happened to be exactly those compositions.

**The fix (now canonical in this playbook):** add a 6th axis — `ethnicity_lock` — that explicitly states phenotype using descent + diaspora + skin tone + eye shape + hair texture + jawline + nose, and ends with the negation **"NO European features whatsoever"** (or the appropriate negation for non-European cast: "NO East Asian features" / "NO South Asian features" etc. — the lock is a phenotype lock, not a one-way bias). The negation forces the model to actively suppress its default prior.

> **Composition flag:** every shot whose composition has a strong Anglo prior (western interior portraits, threshold shots, professional headshots, courtroom shots) gets DOUBLE the ethnicity_lock — pasted at the start of the prompt AND again at the end. Empirically, this lands cast-correct on the first try.

---

## Quality controls (auto-applied)

- **Cost upfront.** 12 × krea-2-large (~$0.76) + 12 × kling-v3-i2v (~$6.30) + 1 × gemini-tts + 1 × minimax-music = ~$7.61. Approve before fire.
- **Scene-by-scene cast tracking.** The agent maintains a `cast_present_per_shot` table BEFORE prompting any keyframe. Each shot's prompt re-pastes ONLY the spec for characters present — never extra, never overloading the call.
- **Ethnicity_lock re-pasted in every prompt where that character appears.** Not summarized, not "Maya (Chinese-Canadian)" shorthand. The full 1-2 sentence phenotype clause with the "NO X features" negation. Every time.
- **Cliffhanger frame gets DOUBLE cast lock.** S12's prompt re-pastes both protag AND mystery specs verbatim, with explicit "BOTH characters hold STILL" instruction.
- **Audit gate after keyframes (the hardest gate).** All 12 reviewed against THREE cast bibles. Verify: protag identity held across every appearance? Witness identity in their one scene? Mystery identity across the flashback + final scenes? Cliffhanger frame holds both faces simultaneously? **Ethnicity check** — scan all face-bearing shots side-by-side, flag any frame where the character's phenotype reads differently from their bible. Composition-driven drift (S4 western teahouse interior + S8 western threshold) is the highest-risk position; check those first.
- **B9 motion budget on every face-bearing shot.** Each i2v prompt has ONE allowed motion (blink, nod, button-fasten, hand-stroke, head-turn). The agent will refuse multi-motion prompts.
- **No-face shots are looser.** Establishing, street, absence, and POV-approach shots can have richer motion (rain, neon flicker, camera drift) because there is no face to drift.
- **Audit gate after animations.** Same 3-cast cross-check. Re-fire any drift before concatenation.
- **Flashback gets palette shift, not face change.** S5 must hold mystery's identity but with warmer/washed-out light. The agent prompts this explicitly.

> **Why the cliffhanger is the showcase moment:** "two faces, perfectly still, only the world moves around them" is the single hardest cinematic move in AI video. Most cap calls drift one face when forced to hold two. The B9 motion budget on S12 says: only rain, only neon, only breath visible — both faces are unchanged from the keyframe. This is the test, and it lands.

---

## How the agent should run this (interaction contract)

1. **CONFIRM (one message, ≤1 question):** restate in 1 line ("120s noir pilot '<title>', 3-cast lock, flashback at S<N> + held cliffhanger, ~$7–10, ~90 min") + real choices: 12 shots (canonical) vs 9 (drops ABSENCE) · kling-v3-i2v (proven) vs cheaper ltx-q-i2v. The ONE question worth asking: missing `ethnicity_lock` on any non-Anglo cast member — do not start without it.
2. **PREVIEW CHECKPOINT:** the beat sheet + cast_present_per_shot table ($0), then **all 12 keyframes + the 3-cast audit (~$0.76)** BEFORE the ~$6.30 of i2v fires. Check S4/S8-style Anglo-prior compositions first — that's where Maya drifted.
3. **NARRATE:** per wave: "animating S1–S4 (kling-v3-i2v, ~2–3 min each)"; waves of ≤4–5, poll `get_create_media` every 10–15s, 1-liner at least every 2 min. S12 runs long (~180s observed) — say so, don't cancel.
4. **FAIL GRACEFULLY:** keyframe ethnicity drift → re-fire with the lock pasted at start AND end (≤2, then flag for LoRA per `episodic-series.md`); krea-2-large fail → gpt-image; kling-v3-i2v hang → retry once → `ltx-q-i2v` (`num_frames:241`, same ONE-motion prompt); music sings the brief → re-run with `lyrics_prompt:"[Instrumental]"`. A pilot with one Ken-Burns shot beats no pilot.
5. **DELIVER:** 1080p reel + cast bible + one honest line ("cast held on N/12 face-bearing shots; S12 cliffhanger held both faces / drifted on X") + ONE next step ("seed Episode 2 from the cast bible — or train per-character LoRAs first").

## The 12-shot beat sheet (canonical 5-act noir pilot)

| Shot | Beat | Cast | Motion budget |
|------|------|------|---------------|
| S1 | ACT 1 · ESTABLISH | none | slow camera push toward setting, rain, lamp pulse |
| S2 | ACT 1 · INTERIOR | protag | one slow blink across 10s (the realization) |
| S3 | ACT 1 · NOTES | protag | one pencil-stroke + steam from tea |
| S4 | ACT 2 · WITNESS | protag + witness | witness blinks once + nods slightly |
| S5 | ACT 2 · FLASHBACK | mystery + 1 stranger | steam from cups, light pulses (memory tint) |
| S6 | ACT 2 · ABSENCE | none | macro push-in, dust mote drifts (the missing object) |
| S7 | ACT 3 · PRESSURE | protag | rain rivulets stream on glass behind |
| S8 | ACT 3 · THRESHOLD | protag | one button-fastening motion (the decision) |
| S9 | ACT 4 · STREET | none | slow drift forward through rain + neon |
| S10 | ACT 4 · APPROACH | mystery | slow camera push, coat fabric drifts |
| S11 | ACT 4 · LOOK | mystery | one eye-up movement at ~6s (acknowledgment) |
| S12 | ACT 5 · CLIFFHANGER | protag + mystery | rain only, breath visible, neon flicker — cut to black |

Substitute role labels for your subgenre. For horror: ESTABLISH/SOUND/THE-DOOR/etc. For thriller: SURVEIL/INTERCEPT/RUN/CONFRONT/etc. The shape is: establish → investigate → flashback → resolve → cliffhanger.

---

## Reproduce via MCP

1. `brand_kit_create` — palette + style keywords. Reusable across the whole season.
2. `generate_project({ project_id, scenes: 12, style: visual_style })`.
3. Build the `cast_present_per_shot` table (12 rows × 3 character cols).
4. 12 × `create_media({ action: "generate", model_override: "krea-2-large", prompt: STYLE + [each_cast_spec_present] + SHOT_BEAT })` parallel.
5. **AUDIT GATE — 3 × cast cross-check.**
6. 12 × `create_media({ action: "animate", model_override: "kling-v3-i2v", source_url: keyframe_url, resolution: "auto", prompt: ONE_MOTION + [each_cast_spec_present], duration: 10 })` — render in waves of ≤4–5, poll each to *done* before the next.
7. `create_media({ action: "tts", model_override: "gemini-tts", voice: narrator_voice, prompt: narrator_script })` parallel.
8. `create_media({ action: "music", prompt: music_brief, lyrics_prompt: "[Instrumental]" })` parallel. **Critical:** detective-pilot scores are always instrumental — pass `lyrics_prompt: "[Instrumental]"` explicitly. NEVER omit it; minimax-music sings whatever is in `lyrics_prompt` verbatim, so without this you'd hear "noir piano underscore eighty BPM" sung. See `public/playbooks/music-video-mtv.md` §"The lyrics-vs-style bug".
9. **AUDIT GATE — 3 × cast cross-check on animations.**
10. Finishing pass (each via `create_media model_override:"<ffmpeg-cap>"`): `ffmpeg-concat` (stitch the 12 clips → ~120s base reel) → `ffmpeg-mux` with `audio_fill:"loop"` (voice at 1.0 + music ducked to ~0.15, covering the FULL 120s — no silent tail) → `ffmpeg-export` (1920×1080). The looped, ducked score under the whole reel is the difference between a deliverable and a draft.

---

## Honest limits

- **3 cast specs is the sweet spot.** 4 named characters introduces drift complexity that single-cap can't carry; for 4+ named characters, train per-character LoRAs (see episodic-series.md).
- **Cliffhanger frame is the most expensive single shot.** S12 typically takes the longest i2v return (~180s observed). Allow extra wall-clock; do NOT cancel.
- **Flashback recognition depends on mystery's keyframe being identifiably the SAME face as their later scenes.** The 5-axis spec must specify the face explicitly (not "kept in shadow" until S11 — that's too vague). Use partial-shadow framing + same hair + same coat colour.
- **The 12-scene arc is the structure that fits 120s.** Shorter pieces (90s/9 scenes) drop the ABSENCE shot and one of the ACT 4 transition shots. Longer pieces (180s/18 scenes) double ACT 3 and ACT 4.
- **"To be continued" only earns if S12 is held**. Resist the temptation to add a final reveal or action; the held silence is the payoff.
- **Ethnicity_lock is not optional for non-Anglo cast.** If you skip the 6th axis on a Chinese-Canadian / Japanese-American / Indian-British / Mexican-American / etc. protagonist, expect ~15-25% of their face-bearing shots to drift to the Anglo default. The lock + the negation clause is the only reliable fix on text-to-image; the alternative is per-character LoRA training (see `episodic-series.md`).

## Related: same drift class in other playbooks

The ethnicity-lock 6th axis applies to every playbook with a non-Anglo named cast:
- `beat-driven-opera.md` — OPUS 1's Elena is white in the example, so the lock isn't load-bearing there, but the playbook should still call it out for non-Anglo single protagonists.
- `story-to-screen.md` — any prose adaptation with a non-Anglo character.
- `episodic-pilot.md` / `episodic-series.md` — sibling playbooks that share this failure mode.
- `local-food-short.md` — culture-anchored pieces are highest-risk (a Chengdu mapo tofu short with a chef of unstated ethnicity drifts hard).

## Execution mode (autopilot / director / auto)

This is a multi-scene project, so pass a `mode` to `generate_project` to control the **pre-finish gate** (after every scene renders, before delivery): `autopilot` (certain brief → ship in one call, no pause), `director` (always pause for a human pick/steer before delivery), or `auto` (recommended — ship UNLESS the auto-critic is unsure: score < `confidence_threshold` (default 0.8), verdict `iterate`, or a flagged shot). Setting `mode` runs the project async (returns a `job_id`); resume a director/auto pause with `review_checkpoint` + `resume_from_checkpoint` (decision `continue` to deliver / `abort` to discard). Omit `mode` for legacy straight-through behavior.
