# Microdrama Development-to-Scripting Workflow

> **▶ SUPERSEDED FOR ORIENTATION (2026-06-07).** For the current topography / tools / protocols map,
> read **`recoil/docs/PIPELINE_SSOT.md`** (the workflow SSOT). This file is retained only as the
> `/engine-check` audit target and for the largely-current narrative Phases 1–7; its visual-pipeline
> sections are stale (see below).

> **STALENESS WARNING (2026-04-25):** This document predates the June 1 refactor and describes the pre-CP-1/CP-2 architecture. The visual-production sections (Phase 8 Two-Pass Architecture, Phases 8-12 in the overview, "Starsend intake path", "Starsend Render Extraction" references) are inaccurate as of 2026-04-25 — the visual pipeline now uses scene-level coverage passes (Formats A/B/C) via ProductionLoop, PassStore, and `recoil/pipeline/cli/generate.py`, not router-pipeline render extraction. The narrative-engine portion (Phases 1-7) is largely current. Do not rely on the visual-pipeline sections for current behavior. Cross-reference: `audit-2026-04-25/pipeline-map.md` for current data flow, `recoil/pipeline/docs/coverage-pass-strategy.md` for the coverage pass spec. Scheduled rewrite: post-CP-2 verification (~2026-06-08).

> **The definitive specification for taking a project from concept to generated episodes.**
> This spec uses 10 granular phases with explicit validation gates.

---

## Overview

```
┌─────────────────────────────────────────────────────────────────┐
│                    DEVELOPMENT PHASE                             │
│  Location: /projects/[project]/development/                      │
│  Command: /develop [project]                                     │
│  Output: 34-point checklist complete                             │
│  Documents: Exploratory format, human-readable                   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    VALIDATION GATES                              │
│  Command: /validate [project]                                    │
│  1. Behavioral DNA Gate (validate_behavioral_dna.py)             │
│  2. Arc Validation Gate                                          │
│  3. Comprehensive validation                                     │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    PROMOTION TO SCRIPTING                        │
│  Command: /promote [project]   ← HARD GATE                       │
│  Transforms development docs → scripting format                 │
│  Creates: /[project]/ folder with standardized files             │
│  Gate: validate_pre_treatment.py                                 │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    TREATMENT GENERATION                          │
│  Command: /treatment [project]                                   │
│  Input: episode_arc.md + bible + characters.md                   │
│  Output: treatment.md (prose paragraphs with THE MOMENT)         │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    TREATMENT VALIDATION                          │
│  python3 /tools/validate_treatment.py ./[project]        │
│  Checks: word counts, continuity, threads, distribution          │
│  + Mandatory two-pass close read (between-episode transitions)   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    EPISODE GENERATION                            │
│  Input: treatment.md + characters.md + state.json                │
│  Process: Batch generation with checkpoint validation            │
│  Output: /episodes/ep_XXX.md                                     │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    POST-GENERATION PIPELINE                      │
│  Command: /finish [project]  (or run steps individually)         │
│  1. Script Doctor: /script-doctor → diagnostic brief             │
│  2. Extract Annotations: --to-annotations → annotations.json    │
│  3. Apply Revisions: apply_annotations.py → auto REWRITE/DELETE │
│  4. Re-validate: episode_metrics.py on all modified episodes     │
│  5. Verify: --verify pass (informational, doesn't block)         │
│  6. Compile: compile_episodes.py → .fountain output              │
│  FLAG annotations → manual review via /rewrite or /revise        │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    VISUAL PRODUCTION PIPELINE                    │
│  8. Script Breakdown: /breakdown → breakdown.json + global_bible │
│  9. Visual Design: visual_bible.md (lens package, HEX palettes)  │
│  10. Storyboard: /storyboard → storyboards/storyboard_ep_N.json │
│  11. Starsend Render Extraction → per-ep manifests (5 groups)    │
│  12. Frame/Video Generation: Starsend pipeline (NBP/Kling/Veo)  │
└─────────────────────────────────────────────────────────────────┘
```

---

## PHASE 1: DEVELOPMENT (34-Point Checklist)

### Location
`/projects/[project]/development/`

### Documents Created

| Document | Purpose | Format |
|----------|---------|--------|
| `STATUS.md` | Track 34-point checklist progress | Checklist with decision log |
| `characters.md` | **REQUIRED** — Sections 1, 5 + Character Arcs | Static (DNA, voice, visual) + Dynamic (transformation, arc) |
| `pressure_test_results.md` | Section 2: Collision sequences | Non-canonical episodes, theme discovery |
| `thematic_spine.md` | Section 3: Theme articulation | After collision discovery |
| `relationship_map.md` | Section 5: Emotional Architecture | Stages, markers, ache, earning schedule |
| `structure_outline.md` | Section 7: Structure | Acts, sequences, beats, 61-episode skeleton |
| `plant_payoff_plan.md` | Section 7: Threads | Seeds, payoff windows, echoes |

**Optional documents:**
| `world.md` | Section 6: World | Setting, rules, factions |

> **Note:** `characters.md` is REQUIRED and must use the standard format (see `/templates/dev_templates/characters_template.md`). The validator parses `## CHARACTER NAME` headers and `### Behavioral DNA` sections.

### Development Format Freedom

Development documents can be:
- Exploratory and verbose
- Numbered by checklist section (1.1, 1.2, etc.)
- Full of notes, alternatives, decisions

This format is for **human development**, not machine parsing.

### Exit Criteria

- [ ] All 34 checklist items marked complete in STATUS.md
- [ ] Collision sequence written (non-canonical)
- [ ] Theme articulated from collision (not designed upfront)
- [ ] All 6 required development documents exist (see table above)

---

## PHASE 2: VALIDATION GATES

### Gate Order

1. **Behavioral DNA Gate** — validates `characters.md` directly (no transform needed)
2. **Arc Validation Gate** — validates `structure_outline.md`
3. **/validate command** — comprehensive check
4. **Promotion** — transforms development docs to scripting format

### No Transform Required for Validation

`characters.md` uses a standardized format that validators can parse directly. The format uses `## CHARACTER NAME` headers and `### Behavioral DNA` sections. See `/templates/dev_templates/characters_template.md` for the required structure.

### Running Gates

```bash
# Gate 1: Behavioral DNA
python3 .claude/hooks/validate_behavioral_dna.py ../projects/[project]/development

# Gate 2: Arc Validation (automated + pairwise for subjective scoring)
python3 /tools/validate_arc.py ../projects/[project]/development           # Tier 1: Automated checks
python3 /tools/validate_arc.py ../projects/[project]/development --pairwise  # Tier 2: Generate scoring prompts
# (Full specification: /evaluation/arc_validation_gate.md)

# Gate 3: Comprehensive
/validate [project]

# Gate 4: Promotion
/promote [project]

# Gate 5: Pre-Treatment (after promotion, before treatment)
python3 .claude/hooks/validate_pre_treatment.py ./[project]
```

---

## PHASE 3: PROMOTION TO SCRIPTING

### Command

```
/promote [project]
/promote [project] --dry-run     # Preview without writing files
/promote [project] --force       # Overwrite existing scripting folder
```

### Prerequisites (HARD GATES)

Before promotion can proceed, ALL must pass:

| Gate | Requirement | Validator |
|------|-------------|-----------|
| Checklist | 34/34 STATUS.md items complete | Manual check |
| Documents | Required development docs exist | promote_agent |
| Behavioral DNA | Characters have filmable DNA | `validate_behavioral_dna.py` |
| Arc Structure | 61 episodes defined | promote_agent |
| /validate | Comprehensive validation passes | `/validate [project]` |

**If any gate fails, promotion is blocked.**

### What Promotion Does

1. **Creates scripting folder** at `/[project]/`
2. **Transforms** development docs → standardized scripting format
3. **Initializes** state tracking
4. **Preserves** development folder (no deletion)

### Folder Structure Created

```
/[project]/
├── bible/
│   ├── series_bible.md        ← From: thematic_spine.md, structure_outline.md, world.md
│   ├── characters.md          ← From: characters.md (COPIED DIRECTLY)
│   └── episode_arc.md         ← From: structure.md (EXPANDED)
├── state/
│   └── current_state.json     ← Initialized
├── episodes/                  ← Empty, ready for generation
├── ORCHESTRATION.md           ← Project-specific generation rules
└── treatment.md               ← Generated in next phase
```

### Characters File (No Transformation)

**`characters.md` is copied directly** from development to `bible/characters.md`.

The development format already uses the standardized structure required by validators:
- Character-name headers (`## CHARACTER NAME`)
- `### Behavioral DNA` sections with filmable behaviors
- `### Voice DNA` sections with speech patterns
- `### Character Arc` sections with transformation schedule

**Template:** `/templates/dev_templates/characters_template.md`

No transformation is needed because the development template is already parseable by validators.

### Episode Arc Expansion (TWO-STEP PROCESS)

**Step 1: Python Skeleton** (`promote_project.py` — automatic)
- Creates `episode_arc.md` with 8 sequence headers
- Generates 61 episode rows with `[FILL]` placeholders
- Includes verification templates
- Extracts thread names from `plant_payoff_plan.md`

**Step 2: AI Fills Details** (promote_agent — manual)
- Reads development documents: `structure_outline.md`, `plant_payoff_plan.md`, `characters.md`, `thematic_spine.md`
- Fills per-episode details:
  - **One-Line** — Episode summary
  - **Cliffhanger** — Specific image/line ending
  - **Type** — Cliffhanger code (M-CF, M-PT, A-RE, etc.)
  - **Intensity** — 1-10 rating
- Verifies:
  - 61/61 episodes filled (no `[FILL]` remaining)
  - Cliffhanger distribution: 70-85% Mid-Action, 15-30% Aftermath (per CONSTANTS.md)
  - Emotional beats (💔) at: Ep 10, 15, 20, 26, 30, 32-33, 36, 42, 45, 50, 60-61
  - Intensity curve builds with peaks at key episodes

**Production format** (episode_arc.md) after filling:
- All 61 episodes with one-line summaries
- Cliffhanger text and type codes
- Intensity scores
- Thread markers
- Action/emotional beat flags

### State Initialization

```json
{
  "project": "[project]",
  "last_completed_batch": 0,
  "last_completed_episode": 0,
  "checkpoints": [],
  "cliffhanger_history": [],
  "hook_history": [],
  "voice_baselines": {}
}
```

---

## PHASE 4: TREATMENT GENERATION

### Pre-Treatment Gate

Before treatment generation, run:
```bash
python3 .claude/hooks/validate_pre_treatment.py ./[project]
```

This verifies all promotion outputs exist and are valid.

### Prerequisites

- [ ] Promotion complete (`/promote [project]`)
- [ ] `bible/episode_arc.md` exists with 61 episodes
- [ ] `bible/characters.md` exists and passes behavioral DNA validation
- [ ] `bible/series_bible.md` exists with content
- [ ] `state/current_state.json` initialized

### Input Documents

Generator reads:
1. `episode_arc.md` — What happens in each episode
2. `characters.md` — Behavioral DNA, voice patterns, character arcs
3. `series_bible.md` — World, theme, constraints

### Output

`treatment.md` with:
- Thread index
- Per-episode: metadata, threads, THE MOMENT, prose paragraph, cliffhanger image
- VOICE SEED in Episode 1

### Command

```
/treatment [project]
```

Or batch:
```
/treatment [project] --batch 1-10
```

> **Batch size note:** Treatment uses 10-episode batches while generation uses 5-episode batches (see `CONSTANTS.md` → Series Structure). Treatment prose is smaller per episode (~50-65 words vs. 450-500 words for scripts), so the model benefits from seeing more narrative context at once. Generation needs shorter batches because full episode scripts consume more context and the model must maintain finer-grained quality control.

---

## PHASE 5: TREATMENT VALIDATION

### Why Validate

Treatment is the primary input for episode generation. Errors here propagate to all episodes.

### Validation Command

```bash
python3 /tools/validate_treatment.py ./[project]
```

### What It Checks

| Check | Requirement |
|-------|-------------|
| Coverage | All 61 episodes present |
| THE MOMENT | Each episode has one |
| VOICE SEED | Episode 1 has it |
| Word counts | Total 3000-4000 (see CONSTANTS.md), key episodes meet minimums |
| Cliffhanger images | Each episode ends with bracketed image |
| Thread coherence | All PLANTs have PAYOFFs |
| Pattern variety | No 4+ consecutive same **subtype** (Ep 11+). Different subtypes within the same main category (e.g., M-CF → M-PT → M-CT) are fine. Main-category runs are informational soft flags only. |
| Ep 10 urgency | Contains physical danger element |

### Close Read (Mandatory Two-Pass)

After automated validation passes, a human-directed close read catches what validators cannot:

**Pass 1:** Read sequentially (ep 1→61). Check between-episode transitions:
- Cliffhanger → hook resolution (does the next episode acknowledge how the previous one ended?)
- Spatial continuity (characters don't teleport between episodes)
- Thread advancement (planted threads advance or pay off on schedule)
- Motivation bridges (character decisions are grounded in what just happened)

**Pass 2:** Re-read after Pass 1 fixes are applied. Catches:
- Issues introduced by Pass 1 fixes
- Problems obscured by the original errors
- Reverse-direction gaps (hook references something that wasn't in the previous cliffhanger)

**The close read is not done until two consecutive passes find zero issues**, or all remaining issues are acknowledged as intentional.

**Scope boundary:** Treatment close read covers *between-episode* transitions only. *Within-episode* transitions (Kill Box segment flow, dialogue consistency, intra-scene spatial tracking) are script doctor territory.

### Fix Loop

If validation fails:
1. Read specific failures
2. Edit treatment.md
3. Re-run validation
4. Repeat until pass

---

## PHASE 6: EPISODE GENERATION

### Prerequisites

- [ ] Treatment validated
- [ ] `characters.md` exists in bible/
- [ ] `current_state.json` initialized

### Input Documents

Generator reads:
1. `treatment.md` — THE MOMENT, prose, cliffhanger image
2. `characters.md` — Behavioral DNA, voice patterns, character arcs
3. `current_state.json` — Position, history

### Generation Loop

```
FOR each batch of 5 episodes:
    1. Read treatment for batch
    2. Read last 2 completed episodes (continuity)
    3. Read characters.md (behavioral DNA)

    FOR each episode in batch:
        4. Apply behavioral DNA to action
        5. Use THE MOMENT as North Star
        6. Hit cliffhanger image exactly
        7. Maintain voice patterns
        8. Write shot-aware action blocks
        9. Save to /episodes/ep_XXX.md
        10. Verify: python3 /tools/episode_metrics.py [filepath] --json
            - Check `is_valid` in output
            - If `false`: run with --prompt flag, apply fixes, re-validate
            - Do NOT proceed until `is_valid: true`

    ## WORD COUNT VALIDATION (CRITICAL)

    **Claude cannot count words accurately while generating.** Only Python scripts provide correct counts.

    **The validator counts ALL words in the file including:**
    - Headers and metadata (# Episode X: Title)
    - Kill Box timestamps ([00:00-00:05])
    - Cliffhanger/hook type annotations
    - Everything from start to end of file

    **Exchange counting:** Each character cue = 1 exchange (not speaker transitions).

    **Iterative Validation Workflow:**
    1. Generate episode (aim for ~470-480 words by feel)
    2. Run: `python3 /tools/episode_metrics.py [file] --json`
    3. If invalid (e.g., "515 words, max 500"):
       - Remove ~15-20 words from action descriptions
       - Re-run validation
       - Repeat until valid
    4. Do NOT trust header word count estimates—they are approximations

    **Tips for trimming:**
    - Remove one 15-20 word sentence from action
    - Cut adjectives/adverbs that don't add visual info
    - Combine short action blocks

    **Do NOT:**
    - Rewrite from scratch when small edits suffice
    - Blame the validator when your estimate was wrong

    11. Run checkpoint validation
    12. IF fail: fix and retry
    13. Update state.json
    14. MANDATORY RELOAD (prevents context drift):
        - Re-read treatment.md for next batch
        - Re-read characters.md
        - Re-read format_v12/SKILL.md
    15. Continue to next batch
```

### Narrative Integrity Rules

During generation, maintain narrative integrity:

| Rule | Description |
|------|-------------|
| **No episode numbers in prose** | Reference events by WHAT HAPPENED, not "Episode 10" |
| **Visual callbacks** | Must be filmable; don't narrate the connection |
| **Authorial voice** | Prose must be transparent; no "we see..." language |
| **Transition logic** | Every transition (inter-episode AND intra-episode) must connect via THEREFORE or BUT, never AND THEN |

**Transition Logic:** Applies at two levels. *Inter-episode:* Each cliffhanger must set up the next hook via causal connection (THEREFORE) or complication (BUT). Never AND THEN. Check spatial continuity, character positioning, emotional carry-over. *Intra-episode:* Each Kill Box section boundary (HOOK→SETUP→ESCALATION→TURN→CLIFFHANGER) must be driven by the previous section. Watch for convenience — obstacles, locations, or characters that appear without setup. See `/appendix_a_cliffhangers_hooks.md` → Transition Logic.

**Full reference:** `/skills/format_v12/SKILL.md` → Narrative Integrity Rules, Transition Integrity sections

### Behavioral DNA Application

**Critical:** The behavioral DNA must appear ON SCREEN, not just in development docs.

| DNA Element | How It Appears in Episodes |
|-------------|---------------------------|
| On-screen behaviors | Describe in action blocks (2-3 per batch, varied) |
| Stress behavior | Show at KEY MOMENTS only (not every conflict) |
| Signature line | Include in dialogue (2-3 per act, high-stakes) |
| Orthogonal trait | Show naturally when story allows — not forced |
| Contradiction | Build toward, pay off at key moments |

**Anti-Repetition:** See `/CONSTANTS.md` → Character Expression Variety for frequency guidance.

### Deviation Handling

When generation produces episodes outside constraints:
1. Follow auto-regeneration protocols in `/DEVIATION_RULES.md`
2. Log all deviations to `state/deviation_log.json`
3. Flagged issues are addressed during `/rewrite` phase

**Philosophy:** All deviations are handled through regeneration. Human intervention comes during rewrite.

### Goal-Backward Verification

At batches 3, 6, 9, 12, and 13, verify arc trajectory:
- Thread resolution count vs target
- Emotional beats hit vs schedule
- Arc progress percentage
- See `/CONSTANTS.md` → Goal-Backward Verification for targets

### Commands

```
/generate-script [project]                    # Manual: pauses after each batch for /compact
/generate-script [project] --fresh            # Backup, clear, start from ep 1
/generate-script [project] --from [batch]     # Resume from specific batch

/autogenerate-scripts [project]               # Autonomous: runs continuously, auto-reloads
/autogenerate-scripts [project] --fresh

/generate-script-orchestrated [project]       # Orchestrated: fresh sub-agent per batch
/generate-script-orchestrated [project] --fresh
/generate-script-orchestrated [project] --from [batch]
```

### Generation Mode Comparison

| Mode | Context Management | User Interaction | Best For |
|------|-------------------|------------------|----------|
| `/generate` | User runs `/compact` between batches | Pauses after each batch | Maximum control |
| `/autogenerate` | Auto-reload, single agent | Fully autonomous | Speed, hands-off |
| `/generate-orchestrated` | Fresh sub-agent spawned per batch | Autonomous with verification | Production quality |

**All three produce identical output format** and use the same validation pipeline (`save_checkpoint.py`).

### Orchestrated Generation Architecture

`/generate-orchestrated` uses a two-tier architecture:

```
┌─────────────────────────────────────────────────────────────┐
│                     ORCHESTRATOR AGENT                       │
│  Maintains: Thread tracker, emotional beat map, pattern state│
│  Context size: ~2-3K tokens (lightweight)                    │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────┐  ┌─────────────┐       ┌─────────────┐     │
│  │ Batch 1     │  │ Batch 2     │  ...  │ Batch 13    │     │
│  │ Sub-Agent   │  │ Sub-Agent   │       │ Sub-Agent   │     │
│  │ (fresh)     │  │ (fresh)     │       │ (fresh)     │     │
│  └─────────────┘  └─────────────┘       └─────────────┘     │
└─────────────────────────────────────────────────────────────┘
```

**Benefits:**
- Each batch gets pristine context (no accumulated drift)
- Orchestrator retains clarity for cross-series verification
- Can verify "did thread planted in ep 12 pay off in ep 58?"
- Pattern violations caught with specific episode references

**Files:**
- Orchestrator state: `/[project]/state/orchestrator_state.json`
- Batch summaries: `/[project]/state/batch_N_summary.json`
- Verification tools: `/tools/verify_*.py`, `orchestrator_verify.py`

**Agent protocols:**
- Orchestrator: `/agents/orchestrator_agent.md`
- Batch: `/agents/batch_agent.md`

---

## PHASE 7: EPISODE VALIDATION

### Per-Batch Checkpoint

```bash
python3 .claude/hooks/save_checkpoint.py ./[project] [batch_number]
```

### Three-Gate Validation

| Gate | Checks | Fail Behavior |
|------|--------|---------------|
| Gate 1: Mechanical | Word count, dialogue %, exchanges, format, **meta-references** | Hard fail |
| Gate 2: Quality | Pattern variety (subtype-level, not main category), beats present, continuity | Hard fail |
| Gate 3: Dramatic QC | Voice, register, behavioral DNA, earning | Soft fail (flags) |

**Meta-reference check:** Gate 1 now includes detection of "Episode N" patterns in prose. The audience doesn't track episode numbers—they experience events. Reference what happened, not production metadata.

### Voice Contamination Check

At batches 3, 6, 9, 12, 13:
```bash
python3 .claude/hooks/baseline_comparison.py ./[project] [batch_number]
```

---

## PHASE 8: SCRIPT BREAKDOWN

### Purpose

Extract visual production assets from completed episodes for AI pipeline conditioning. The breakdown is the bridge between written scripts and visual production — it identifies every visual element needed to generate frames and video.

### Prerequisites

- [ ] Episodes generated and validated (Phase 6-7 complete)
- [ ] `bible/characters.md` exists (wardrobe, props, visual descriptions)

### Command

```
/breakdown [project] [ep N-M]
```

### What It Produces

`/[project]/visual/breakdown.json` conforming to `/templates/breakdown_schema.json`.

Per-episode breakdown includes:
- **Characters:** Visual descriptions, wardrobe phases, hair/makeup states, continuity notes
- **Props:** Descriptions, materials, colors (with HEX), ownership, state changes
- **Locations:** Architecture, materials, lighting, atmosphere, color palette (HEX)
- **VFX:** Overlays, practical effects, compositing needs
- **Continuity:** Injuries, emotional states, prop positions, time-of-day

### Location Consolidation

After regex extraction, the breakdown agent consolidates raw locations into canonical entries. Script headers generate many variant strings for the same physical space (e.g., `JINX'S COMPARTMENT LEVEL -7` vs `JINX'S COMPARTMENT LEVEL -7 - NIGHT CYCLE`). Consolidation:

1. **Merges time-of-day variants** into a single canonical location with lighting variants
2. **Groups sub-locations** under parent spaces (e.g., `CROWN CHAMBER` + `CROWN CHAMBER ENTRANCE`)
3. **Assigns habitat zones** — every project identifies 4-6 zones, each gets a hero key art image
4. **Gemini reconciliation** for ambiguous merges (mirrors character variant reconciliation in `batch_generate_refs.py`)

All sub-locations within a zone derive their visual DNA from the zone hero image. This reduces location reference generation from N independent images to 4-6 hero key art images plus prompt-level variations.

**Agent protocol:** `/agents/breakdown_agent.md` (Step 1.5)
**Working example:** `/leviathan/visual/habitat_zones.md` (72 locations -> 5 zones, 6 hero images)

### Validation

```bash
python3 /tools/validate_breakdown.py \
  /[project]/visual/breakdown.json \
  /[project]/ --report
```

Exit codes: 0 = clean, 1 = hard errors (FAIL), 2 = warnings (matches CONSTANTS.md).

### Prompt Generation

After extraction, generate reference prompts for all assets:

```
/breakdown [project] --prompts ref
```

This populates `prompts.reference` fields in breakdown.json. Character prompts use a structured format (`{ hero: string, variants: { name: string } }`). The hero prompt is a full identity description; each variant prompt is a rich wardrobe/state description (60-120 words). `batch_generate_refs.py` generates 5 angle shots per variant (front, profile, three-quarter, full body, back) by prepending angle instruction + character identity. Location and prop prompts are plain strings. All prompts are engine-agnostic — no flags like `--ar`, `--s`, `--raw`.

### Visual Tools

| Tool | Purpose |
|------|---------|
| **Production Console** (`/editors/production_console.html`) | Unified tabbed app — Revision, Grammar, Visual Bible, Breakdown, Storyboard, Shotlist, Dailies. Replaces standalone editors. |
| Reference Workshop (Console → References link, or `_standalone/references_editor.html`) | Edit prompts, browse/replace generated refs, auto-save to disk, lock per wardrobe variant |
| Visual QC (`/tools/visual_qc.py`) | Audit breakdown.json for visual production readiness |
| Visual Gate (`/tools/visual_gate.py`) | Two-gate automated QC for generated keyframes: Gate 1 artifact detection + Gate 2 semantic alignment (Gemini 2.5 Flash) |
| Storyboard Review (Console → Storyboard tab, or `_standalone/storyboard_review.html`) | Gate-aware frame review — auto-loads gate scores, filters edge cases, human override |
| Breakdown Editor (Console → Breakdown tab, or `_standalone/breakdown_editor.html`) | Visual asset management and review |

### Two-Pass Architecture (Recoil → Starsend)

Script breakdown feeds into Starsend's render extraction pipeline via a two-pass architecture:

- **Pass 1 (Gemini 3.1 Pro):** Structural synthesis — reads all episodes at once, finds character phases, lighting profiles, lighting motifs, location consolidation. Leverages Gemini's 1M+ token context window. Output: `global_bible.json` with `[OPUS_ENRICHMENT]` placeholders for prose fields.
- **Pass 2 (Opus 4.6):** Prose enrichment — takes Gemini's structural output, writes dense evocative descriptions, wardrobe prose, reference prompts.

`breakdown.json` (for production console, visual-design, ref generation) is **derived** from `global_bible.json` — pure schema translation, no LLM needed.

Starsend intake path: `/breakdown` → camera-test → global bible → storyboard pass → per-episode render manifests.

### Data Flow

Breakdown outputs feed into:
- **Reference Workshop** — prompts sent to batch generator, results browsed/replaced, refs saved to `visual/refs/`
- **Visual Design** (Phase 9) — HEX palettes, wardrobe, props inform visual_bible.md
- **Storyboard** (Phase 10) — wardrobe phases, hair/makeup, props, lighting per shot
- **Starsend Render Extraction** — global bible + camera-tested episodes → per-episode render manifests with 5 consumer groups (routing, prompt, spatial, asset, audio)

---

## PHASE 9: VISUAL DESIGN

### Purpose

Establish the project's visual language before frame generation. Creates the **visual_bible.md** — the production-ready visual design document consumed by the storyboard agent and generation pipeline.

### Prerequisites

- [ ] Breakdowns exist for at least the first few episodes (REQUIRED — visual design needs asset inventory)
- [ ] Character visual descriptions established in `bible/characters.md`

### What It Produces

`/[project]/visual_bible.md` using the template `/templates/visual_bible_template.md`.

The visual bible defines:
- **Color Palette:** Global and per-location HEX palettes
- **Characters:** Visual summaries, wardrobe per arc phase, signature props, reference images
- **Props:** Visual descriptions with materials, colors (HEX), light behavior, state changes
- **Locations:** Architecture, materials, lighting, atmosphere, color palettes (HEX)
- **VFX Elements:** Type, colors, behavior, production notes
- **Lens Package:** Primary, close-up, wide, specialty lenses + film stock reference
- **Lighting Guides:** Per-mood/scenario setups with exact prompt language
- **Flux 2 Reference Slot Assignments:** Character identity (1-5: front, profile, 3/4, full body, back), props (6), environment (7-8), lighting (9), pose/layout (10)

### Lens Package

The lens package is a creative constraint mimicking professional film production practice — most films limit lens choices to a small set to maintain a consistent visual language.

| Lens | Default | Use For |
|------|---------|---------|
| Primary | 50mm f/2.0 | MS, MCU, dialogue, general coverage (per CONSTANTS.md) |
| Close-Up | 85mm f/1.4 | ECU, CU, emotional beats, detail shots (per CONSTANTS.md) |
| Wide | 24mm f/8 | Establishing shots, environmental, action (per CONSTANTS.md) |
| Specialty | Varies | Project-specific (macro, tilt-shift, etc.) |

Film stock (e.g., "Kodak Vision3 500T") is a **per-project creative choice** codified in `visual_bible.md`. It is appended by `prompt_engine.py` at generation time — **not** baked into storyboard prose (per Storyboard Prose Spec v1.0). Repeating film stock in both the visual bible and per-shot prose causes "concept bleeding" where the model over-indexes on repeated tokens.

### Reference Image Generation

Reference images are generated via `batch_generate_refs.py` using the Gemini API (or fal.ai fallback) from engine-agnostic photorealistic prompts.

**Pipeline:**
1. `/breakdown [project] --prompts ref` generates rich photorealistic prompts (60-120 words) for all assets
2. `batch_generate_refs.py [project]/` sends prompts to Gemini API with image validation + auto-retry
3. Results browsed in **Reference Workshop** (Console → References link, or `_standalone/references_editor.html`)
4. Workshop writes images to disk (`visual/refs/`) via File System Access API
5. Approved refs locked per wardrobe variant → feeds Flux 2 slots 1-5

Each character variant gets 5 angle shots (front, profile, three-quarter, full body, back) auto-generated from a single wardrobe description prompt. The batch script prepends the angle instruction and character identity. All prompts are engine-agnostic — no flags like `--ar`, `--s`, `--raw`. See `/appendix_f_midjourney_v7_protocols.md` for legacy MJ V7 reference.

### Process

Visual Design is a **guided phase** using the `/visual-design` skill:
1. Reviews breakdown.json for visual asset inventory
2. Fills out visual_bible_template.md with user guidance
3. Generates character reference sheets (5 angles per wardrobe variant via batch_generate_refs.py)
4. Locks reference images and HEX palettes via Reference Workshop
5. Establishes lens package based on project tone

**Command:** `/visual-design [project]`

Modes:
- Default: Full guided creation
- `--audit`: Check completeness of existing visual_bible.md
- `--validate`: Cross-reference against breakdown.json
- `--section [name]`: Focus on one section (characters, locations, props, vfx, lens, lighting)

### Validation Gate

After creating `visual_bible.md`, run:

```bash
python3 /tools/validate_visual_bible.py \
  /[project]/visual_bible.md /[project]/ --prompt
```

Exit codes: 0=clean, 1=fail (blocks storyboard), 2=warnings (review recommended).

### Reference

- Skill: `.claude/skills/visual-design/SKILL.md`
- Agent: `/agents/visual_design_agent.md`
- Validator: `/tools/validate_visual_bible.py`
- Template: `/templates/visual_bible_template.md`
- Flux 2 protocols: `/appendix_e_flux2_protocols.md`
- MJ V7 protocols: `/appendix_f_midjourney_v7_protocols.md`
- Reference Workshop: Production Console → References link (`/editors/_standalone/references_editor.html`)
- Visual QC: `/tools/visual_qc.py`

---

## PHASE 10: STORYBOARD GENERATION

### Purpose

Convert episode scripts into structured JSON storyboards with full generation parameters — hybrid prose prompts, camera settings, lighting, color, and production notes. The storyboard is the direct input for frame and video generation.

### Prerequisites

- [ ] Episode scripts exist (Phase 6)
- [ ] Visual bible exists (Phase 9) — or fallback to series_bible.md
- [ ] Breakdown exists (Phase 8) — optional but recommended

### Command

```
/storyboard [project] ep [N]
/storyboard [project] ep [N] --edit
/storyboard [project] ep [N] --from-shotlist
```

### What It Produces

`/[project]/storyboards/storyboard_ep_NNN.json` conforming to `/templates/storyboard_schema.json` (version 2).

Schema version 2 includes:
- **Lens package** — project camera constraints from visual_bible.md
- **Prose prompts** — dense visual fact payloads per **Storyboard Prose Spec v1.0** (first_frame / last_frame)
- **Generation metadata** — structured camera, lighting, color, reference slots per shot
- **Atmospheric inference** — implicit visual details derived from emotion + location
- **HEX color palettes** — per-episode and per-shot from visual_bible.md

### Storyboard Prose Spec v1.0

Storyboard `first_frame`, `last_frame`, and `hero_frame` fields follow a Gemini-validated specification optimized for generation model survival. Key rules:

- **No camera/lens/film stock in prose** — engine prepends these from visual_bible / project_config
- **Dense visual facts, not narrative prose** — comma-separated [Adjective]+[Noun] pairs
- **Sliding word budgets** — ECU 15-25, CU/MCU 25-35, MS/LS/WIDE 30-40, two-character 40-60
- **Physical symptoms only** — no abstract emotions (Mute B&W Monitor Rule)
- **last_frame = first_frame with targeted deltas** — locks latent coordinates for unchanged elements in FLF video
- **No HEX codes in prompts** — natural language color descriptions only

Full spec and banned terms list: `/agents/storyboard_agent.md` Step 4.
Gemini consultation: `recoil/pipeline/consultations/storyboard_prose_optimization/SYNTHESIS.md`.
Validation: `validate_storyboard.py` enforces prose spec as warnings via `check_prose_spec()`.

### Validation

```bash
# Structural + Grammar validation
python3 /tools/validate_storyboard.py \
  /[project]/storyboards/storyboard_ep_NNN.json \
  /[project]/episodes/ep_NNN.md \
  --project /[project]/ --json

# Motion complexity analysis
python3 /tools/motion_complexity.py \
  /[project]/storyboards/storyboard_ep_NNN.json --suggest

# Save version before any edits
python3 /tools/storyboard_version.py save \
  /[project]/storyboards/storyboard_ep_NNN.json -m "post-storyboard"
```

Checks: beat coverage, script coverage, hallucination detection, enum validity, dimension multiples of 16, **shot grammar** (scale variety, jump cuts, establishing shots, scene coverage), **motion complexity** classification.

### Shot Grammar Gate

Added to `validate_storyboard.py` as `check_shot_grammar()`. Enforces universal film grammar:

| Check | Rule | Severity |
|-------|------|----------|
| Scale variety | No 3+ consecutive shots at same scale | Hard fail |
| Establishing shots | Scene boundary should open with WIDE/LS | Warning |
| Jump cut risk | Same subject + scale + angle in adjacent shots | Hard fail |
| Shot scale rhythm | Flag 5+ shots with no scale variation | Warning |
| Scene coverage | Every scene has tight + wide shots | Warning |

Shot count target (default 18-24) is **genre-configurable** via `project_config.json → shots_per_episode`. Falls back to `CONSTANTS.md → SHOTS_PER_EPISODE`.

### Motion Complexity Classifier

`/tools/motion_complexity.py` analyzes each shot and tags LOW / MEDIUM / HIGH:

| Complexity | Characteristics | Suggested Approach |
|------------|----------------|-------------------|
| LOW | Static camera, minimal motion, single subject | held_frame_push / held_frame_static |
| MEDIUM | Camera push/pull, gesture, moderate motion | standard_flf |
| HIGH | Tracking, character rotation, multi-character, physics | triptych_split_flf |

Use `--enrich` to write `motion_complexity` and `motion_complexity_score` to storyboard JSON. Use `--apply-suggestions` to also update `generation_approach`.

### Storyboard Versioning

`/tools/storyboard_version.py` tracks revisions per shot:

```bash
storyboard_version.py save <sb.json> -m "reason"    # Save version
storyboard_version.py list <sb.json>                 # Version history
storyboard_version.py diff <sb.json> [v1] [v2]      # Per-shot diff
storyboard_version.py revert <sb.json> <version>     # Undo (auto-saves current first)
storyboard_version.py changed <sb.json> [v1] [v2]   # Shot IDs that changed (for selective previz)
```

Versions stored in `storyboards/_versions/`. Per-shot hashing tracks only generation-affecting fields — metadata changes don't trigger re-generation.

### Pre-Production Gate

Before committing GPU resources, run:

```bash
python3 /tools/validate_pre_production.py /[project]/ [--episode N]
```

Checks: visual bible valid, breakdown exists, storyboard grammar passes, previz reviewed, LoRA status. Exit code 0 = safe to generate.

### Previz Standard

| Parameter | Value | Notes |
|-----------|-------|-------|
| Model | Z-Image Turbo + LoRA | `fal-ai/z-image/turbo/lora` |
| Resolution | 512x896 | 9:16 vertical |
| Steps | 8 | No cost difference vs fewer steps (fal.ai charges per MP) |
| Cost | ~$0.0039/frame | $0.0085/MP at 0.459 MP |
| Cost/episode | ~$0.08-0.10 | 21 shots per episode |

Calibration tested 2026-02-09. 2-step unusable, 3-step has deformation, 4-step clean but same price as 8-step. 8-step gives best quality at no extra cost.

**Tool:** `/tools/generate_previz.py` — generates one hero keyframe per shot, writes `previz_manifest.json` + `previz_review.html` contact sheet.

```bash
python3 /tools/generate_previz.py /[project]/ --episode N          # full episode
python3 /tools/generate_previz.py /[project]/ --episode N --dry-run # cost estimate only
python3 /tools/generate_previz.py /[project]/ --episode N --changed-only  # selective regen
```

### Agent Protocol

`/agents/storyboard_agent.md` (AI Cinematographer — creative visual direction)

Downstream mechanical specs: `/agents/shotlist_agent.md`

### Data Flow

```
episodes/ep_NNN.md ──────────────┐
bible/characters.md ─────────────┤
visual/breakdown.json ───────────┤──→ /storyboard agent ──→ storyboards/storyboard_ep_NNN.json
visual_bible.md ─────────────────┤    (AI Cinematographer)         │
appendix_e_flux2_protocols.md ───┘                                 ▼
                                                      Shotlist Agent / Editor
                                                      (mechanical execution specs)
                                                                   │
                                                                   ▼
                                                    generate_previz.py
                                                    (hero frame per shot, 512x896, z-image turbo)
                                                                   │
                                                                   ▼
                                                    generate_storyboard_keyframes.py
                                                    (full production: T2I + upscale + video)
```

### Downstream Consumers

| Consumer | What It Reads |
|----------|---------------|
| **Production Console** (`/editors/production_console.html`) | Unified 7-tab app — all editors in one interface with shared project/episode state |
| **Shotlist Editor** (Console → Shotlist tab, or `_standalone/shotlist_editor.html`) | Full JSON — visual editing |
| **Storyboard Editor** (Console → Storyboard tab, or `_standalone/storyboard_editor.html`) | Storyboard review — annotation interface |
| **Storyboard Review** (Console → Storyboard tab, or `_standalone/storyboard_review.html`) | Gate-aware frame review — auto-loads visual_gate scores, filters edge cases |
| **Visual Gate** (`/tools/visual_gate.py`) | Per-shot automated QC — reads storyboard JSON + frame manifests + character refs |
| **generate_previz.py** (`/tools/generate_previz.py`) | shots[] hero frame — prompt compiler (frame_type="hero"), character detection, generation type |
| **generate_from_storyboard.py** | shots[].first_frame, shots[].last_frame, generation_metadata, dimensions, seed |
| **Human review** | All fields — the JSON is the source of truth for visual production |

---

## VISUAL PRODUCTION INFRASTRUCTURE

This section documents the cloud GPU, model inventory, training pipeline, and API services that support Phases 8-10 and downstream frame/video generation. It is the canonical reference for what is installed, what is tested, and what is planned.

### Cloud GPU: RunPod A100

| Property | Value |
|----------|-------|
| GPU | NVIDIA A100 80GB |
| Network volume | 100GB persistent (survives pod restarts) |
| ComfyUI version | 0.12.1 (Flux 2 native support) |
| Disk usage | ~87GB / 100GB |
| SSH | Direct TCP (not proxy — proxy blocks automation) |
| Status | **ACTIVE** — pod provisioned, models installed, T2I and multi-ref tested |

The network volume persists all models and custom nodes across pod stop/start cycles. Without it, ~75GB of models would need redownloading each session. The pod is started on-demand and stopped when not in use to minimize cost.

**Custom Nodes Installed:**
- ComfyUI-WanVideoWrapper (Kijai) -- WAN 2.2 video nodes
- ComfyUI-VideoHelperSuite -- VHS_VideoCombine for video output
- ComfyUI-KJNodes -- utility nodes
- ComfyUI-Manager -- package manager

### Model Inventory

**Flux 2 Dev FP8 (Image Generation) -- TESTED, WORKING:**

| Model | Size | Path | Purpose |
|-------|------|------|---------|
| `flux2_dev_fp8mixed.safetensors` | 34GB | `models/diffusion_models/` | Diffusion model |
| `mistral_3_small_flux2_fp8.safetensors` | 17GB | `models/text_encoders/` | Text encoder (Mistral-3 24B VLM) |
| `flux2-vae.safetensors` | 321MB | `models/vae/` | VAE decoder |

- First generation: ~48s (model load into VRAM). Subsequent: ~15-20s.
- VRAM usage: ~20GB on A100, leaving ~60GB for LoRA + references + high resolution.
- Native multi-reference: up to 10 images via `ReferenceLatent` node chaining.
- Text-to-image and multi-reference both verified working.

**WAN 2.2 I2V (Video Generation) -- DOWNLOADED, NOT YET TESTED:**

| Model | Size | Path | Purpose |
|-------|------|------|---------|
| `wan2.2_i2v_high_noise_14B_fp8_scaled.safetensors` | 14GB | `models/unet/` | Video diffusion model |
| `umt5_xxl_fp8_e4m3fn_scaled.safetensors` | 6.3GB | `models/text_encoders/` | Text encoder |
| `wan2.2_vae.safetensors` | 1.4GB | `models/vae/` | Video VAE |
| `clip_vision_h.safetensors` | 1.2GB | `models/clip_vision/` | CLIP vision encoder |

- Image-to-video interpolation from approved keyframes.
- Sandwich workflow planned: Flux 2 generates start + end frame, WAN interpolates between them.

**Retired Models:**
- Flux.1-dev, IPAdapter Flux (Shakker-Labs), Flux 1 text encoders, Flux 1 VAE -- all deleted, replaced by Flux 2.

### LoRA Training Pipeline

**Tool:** `tools/train_lora.py`
**Candidate Gen:** `tools/batch_threepass.py` (recommended) or `batch_generate_refs.py --hybrid` (alternative) or `engine_shootout.py --threepass` (single angle)
**Registry:** `[project]/visual/lora_registry.json`
**Best Practices:** `docs/archive/lora_training_best_practices.md` (archived — LoRA pipeline eliminated Feb 27, 2026)
**Engine Specs:** `docs/archive/candidate_generation_engines.md` (archived)
**Status:** ACTIVE — Jinx T2I + video LoRAs trained and registered, Kian pending

| Property | Value |
|----------|-------|
| Platform | fal.ai (Flux 2 Trainer for T2I, WAN 2.2 Trainer for video) |
| Cost | Z-Image: ~$0.85/1K steps (~$1.70/char), Flux 2: ~$3/1K steps (~$4.50/char), Video: ~$2/1K steps (~$25/char) |
| Output | `.safetensors` file (T2I: 1 file, video: 2 files high-noise + low-noise) |
| Trigger word | Per-character (e.g., `JNXCHAR` for Jinx) |
| Training images | 25-30 per character, varied backgrounds (5-10 environments), 3-5 wardrobe variations, multiple angles and expressions |
| Strategy | **One LoRA per character** (not per wardrobe). Wardrobe controlled by prompt + reference images. |

**LoRA is a permanent IP asset.** Once trained, the `.safetensors` file does not change. A character trained today generates identically years from now. Marginal cost per generation is near zero after the initial $1.70-4.50 training investment.

**Candidate Generation — Three-Pass Sequential Pipeline (Recommended):**

Three engines chained sequentially, each handling what it does best (see `archive/candidate_generation_engines.md` for full specs — archived pipeline):

| Pass | Engine | Speed | Cost/img | Purpose |
|------|--------|-------|----------|---------|
| 1 | Qwen Multi-Angle (fal.ai) | ~7-37s | $0.035 | Angle geometry from hero (14 angles, 40 steps, skin texture + proportionality prompts) |
| 2 | NBP / Gemini 3 Pro (Google) | ~20-40s | $0.134 | Background swap + expression + identity lock + skin texture |
| 3 | SeedVR2 (fal.ai) | ~5-10s | $0.001 | Non-generative quality upscale (skipped on face angles) |
| | **Total per angle** | **~25-56s** | **~$0.036-0.170** | Varies by routing (face 2-pass, body 3-pass, back 2-pass) |

`--threepass`: Smart pipeline routing — face angles: Qwen MA → NBP (skin priority, skip SeedVR2). Body angles: Qwen MA → NBP → SeedVR2 (proportionality + upscale). Back/profile: Qwen MA → SeedVR2. Best quality, accurate angles, clean skin detail.

Legacy modes (`--hybrid parallel`, `--hybrid twopass`) still available but not recommended — Gemini Flash can't hold angles reliably.

**Process:**
1. Generate 7-8 keystone images in MidJourney (neutral poses, key angles)
2. Place in `[project]/visual/lora_candidates/[CHAR]/keystones/`
3. `batch_threepass.py [project]/ --character CHAR` — Three-pass candidates (recommended), or `batch_generate_refs.py --hybrid` (alternative). **Environment rotation pulls from `breakdown.json` habitat zones** — requires `/breakdown` to have run first. Falls back to generic environments if no breakdown exists.
4. Curate in `lora_picker.html` → select 15-25 best candidates
5. `train_lora.py [project] prepare CHAR --from-candidates --target-model z_image` — Build training ZIP
6. `train_lora.py [project] submit CHAR --type z_image` — Submit training (non-blocking)
7. `train_lora.py [project] status CHAR --wait` — Poll until done, auto-download + register
8. `train_lora.py [project] show` — Display registry status

**Dataset Requirements:**
- 25-30 images per character (final curated set)
- 3-5 wardrobe variations (captioned explicitly — prevents outfit baking into identity)
- 5-10 distinct backgrounds sourced from habitat zones (no all-white sets — causes overfitting and "prompt inertia")
- 5-7 distinct expressions, neutral dominant (~40%)
- Mixed angle sources (three-pass pipeline or hybrid Qwen + Gemini)
- Natural language captions (model-aware length: Z-Image 20-50 words, Flux 2 30-80 words)

**Concurrent Training:** Multiple characters can train as concurrent fal.ai jobs. A 3-character series trains in ~30 minutes for ~$5-14 total (Z-Image) or ~$9-75 total (all model types).

### API Services

| Service | Purpose | Cost | Status |
|---------|---------|------|--------|
| **fal.ai** | LoRA training (Z-Image, Flux 2, WAN 2.2 trainers), Qwen Multi-Angle candidate generation, T2I/video inference | Z-Image: ~$0.85/1K steps, Flux 2: ~$3/1K steps, Video: ~$2/1K steps, Qwen: ~$0.035/img | ACTIVE |
| **Google Gemini API** | Script doctor (1M context diagnostic), reference/candidate image generation (`batch_generate_refs.py`) | $100/mo Google Cloud credits (Ultra subscription) | ACTIVE |
| **Google AI Studio** | Script doctor manual workflow (free tier, copy-paste) | Free | ACTIVE |

### Setup-Based Generation Model

**Principle:** Generate setups, not shots. Every return to the same camera position reuses the same keyframe. This mirrors physical film production and reduces generation cost by ~54%.

A **setup** defines a unique camera position (framing, subject, background, angle, lighting, lens). Multiple shots share the same setup -- the only difference is expression/gesture, which comes from the text prompt.

**Example:** A 20-shot conversation scene requires only 4 setups (wide master, CU character A, CU character B, OTS). The storyboard agent assigns each shot to a setup. Keyframe generation runs once per setup, not once per shot.

**Generation types per shot:**

| Type | When | Cost |
|------|------|------|
| `wan_i2v` | Physical movement, gesture, action | Full render |
| `held_frame_with_push` | Reaction shots, listening | Single frame + Ken Burns zoom (no WAN) |
| `held_frame_static` | Brief cutaway, insert | Single frame only |
| `wan_i2v_from_previous` | Continuation within same setup | Uses end frame of previous segment |

**Full specification:** `/[project]/visual/COVERAGE_MODEL.md`

### Habitat Zone Concept

**Problem:** A typical series has 60-70+ unique script locations. Generating a unique background for each is expensive and produces inconsistent results.

**Solution:** Consolidate locations into 4-6 **habitat zones** per project. Each zone gets one **hero key art image** that establishes materials, color temperature, lighting logic, and scale. All sub-locations within a zone derive from that hero image's visual DNA -- same materials, same lighting, different framing and details.

**Per-project pattern:**
1. Identify 4-6 habitat zones from script breakdown locations
2. Generate 1 hero key art image per zone (Midjourney, Gemini, or Flux 2)
3. All sub-locations inherit zone visual DNA via prompt variations
4. Per-episode location references = crop/adjust hero + specific scene prompts

**Example (Leviathan):**

| Zone | Locations | Episodes | Hero Images |
|------|-----------|----------|-------------|
| Lower Decks (Salvage Territory) | 13 | 1-8, 45-49 | 1 |
| Mid-Ship Infrastructure | 25 | 4, 8-13, 28-38, 48-49 | 1 |
| The Root (Organic Growth) | 16 | 14-28, 45-46 | 1 |
| Crown Level (Command) | 6 | 38-49 | 1 |
| Shuttle Bay & Planet Surface | 12 | 49-61 | 2 (bay + surface) |
| **Total** | **72** | **1-61** | **6** |

72 script locations reduced to 6 hero images. This pattern scales to any project.

**Full specification:** `/[project]/visual/habitat_zones.md`

---

## Document Format Specifications

### characters.md (Development → Production)

The same file is used in both development and production. Validators expect this structure:

```markdown
# [PROJECT] — Characters

## [CHARACTER NAME] — [ROLE/ARCHETYPE]

### Behavioral DNA

**On-Screen Behaviors:**
1. [Specific filmable behavior]
2. [Specific filmable behavior]
3. [Specific filmable behavior]

**Stress Behavior:** [Specific, not generic]

**Signature Line:** "[Exact quote]"

**Orthogonal Trait:** [Non-theme-serving detail]

**Contradiction:** [Pattern-break description]

### Voice DNA

**Idiom:** [Speech pattern description]

**Humor Type:** [GALLOWS HUMOR / DRY DEADPAN / CRUEL WIT / EARNEST / NONE]

**Anti-Patterns (NEVER says):**
- [Pattern to avoid]
- [Pattern to avoid]

**Sample Dialogue:**
> "[Example line]"
> "[Example line]"

### Character Arc

**Arc Type:** [Positive/Negative/Flat/Disillusionment/Revelation]
**The Lie:** [What they believe]
**The Truth:** [What they'll discover]
**Transformation Schedule:** [When mask cracks occur]

---

## [NEXT CHARACTER] — [ROLE]
...
```

**Template:** `/templates/dev_templates/characters_template.md`

### episode_arc.md (Production)

**Creation:** Two-step process (see "Episode Arc Expansion" above)
1. Python creates skeleton with `[FILL]` placeholders
2. AI fills per-episode details from dev documents

**Input:** treatment.md reads this for THE MOMENT and cliffhanger assignments

```markdown
# [PROJECT] — Episode Arc

## HOW TO USE THIS DOCUMENT
[Usage instructions, flexibility markers legend]

### Cliffhanger Types
**Mid-Action:** M-PT (Physical Threat), M-CF (Confrontation), M-PU (Pursuit), M-CH (Choice), M-CT (Catch)
**Aftermath:** A-RE (Reveal), A-CO (Consequence), A-PS (Psychological), A-SI (Silent), A-CT (Catastrophe), A-DE (Decision)

---

## SEQUENCE 1: THE AWAKENING (Ep 1-8)

**Function:** Establish world, protagonist, inciting incident
**Thematic:** [Thematic stance at start of sequence]
**Action Beats:** [Count and episode numbers]

| Ep | One-Line | Cliffhanger | Type | Intensity |
|----|----------|-------------|------|-----------|
| 1 | Jinx finds pristine cryo-pod over abyss. Kian wakes violent. | Kian's hand on her throat: "Identify sector." | M-CF | 9 |
| 2 | [Summary] | [Specific image/line] | M-PT | 8 |
...

---

## VERIFICATION
[Action beat distribution, emotional beat schedule, cliffhanger distribution, intensity curve]

## PLANT/PAYOFF TRACKING
[Thread names with plant/payoff episode mappings]
```

### treatment.md (Production)

```markdown
# [PROJECT] — Treatment

> [Logline]

---

## THREAD INDEX

| Thread | Plant | Advances | Payoff | Description |
|--------|-------|----------|--------|-------------|
...

---

## ACT I: [NAME] (Episodes 1-15)

### Sequence 1: [Name] (Episodes 1-8)

---

### Episode 1: "[Title]"
**Sequence:** 1 | **Beat:** CATALYST | **Hook:** SILENT | **Cliffhanger:** MID-ACTION (M-CF)
**Threads:** [PLANT: Thread Name]
**THE MOMENT:** [Specific image/line] — [why it matters]
**VOICE SEED:** "[Exact line]" — [what it establishes]

[Prose paragraph, 125-150 words for Ep 1]

**[CLIFFHANGER: Specific visual/line]**

---

### Episode 2: "[Title]"
...
```

---

## Validation Script Compatibility

### validate_behavioral_dna.py

**File Search Order:**
1. `[project]/bible/characters.md` (production - new standard)
2. `[project]/bible/character_voices.md` (production - legacy)
3. `[project]/characters.md` (development)

**Required Format:**
```markdown
## CHARACTER NAME — ROLE

### Behavioral DNA

**On-Screen Behaviors:**
1. [Specific filmable behavior]
2. [Specific filmable behavior]
3. [Specific filmable behavior]

**Stress Behavior:** [Specific, not generic]

**Signature Line:** "[Exact quote]"

**Orthogonal Trait:** [Non-theme-serving detail]

**Contradiction:** [Pattern-break description]
```

**Validation Checks:**
- 3+ on-screen behaviors per character (filmable, not backstory)
- Stress behavior is specific (not "gets quiet")
- Signature line passes swap test
- Orthogonal trait defined
- Contradiction defined

**Template:** `/templates/dev_templates/characters_template.md`

---

## Quick Reference: What Goes Where

| Phase | Reads From | Writes To |
|-------|------------|-----------|
| Development | Brain, research | `/projects/[project]/development/*.md` |
| Promotion | `/projects/[project]/development/` | `/[project]/bible/`, `/[project]/state/` |
| Treatment | `bible/episode_arc.md`, `bible/*.md` | `treatment.md` |
| Generation | `treatment.md`, `bible/characters.md` | `/episodes/ep_XXX.md` |
| Validation | Various | Exit codes, reports |
| Breakdown | `episodes/`, `bible/characters.md` | `visual/breakdown.json`, `state/visual/global_bible.json` |
| Visual Design | Breakdowns, characters.md | `visual_bible.md` |
| Storyboard | Episodes, breakdowns, visual_bible.md | `storyboards/storyboard_ep_NNN.json` |
| Render Extraction | Camera-tested eps, global bible, storyboards | `state/visual/render_manifests/ep_NNN_manifest.json` |

---

*This is the authoritative workflow specification. All other docs should reference this.*
