---
name: generate-script
description: Generate screenplay script episodes in manual batch mode — pauses after each batch for user-driven /compact. Use when you want control between script generation batches.
allowed-tools: Read, Write, Glob, Bash
argument-hint: "[project] [--fresh|--from N]"
---

# /generate-script - Clean Context Generation

Generate episodes with a **fresh context window for each batch**. After each batch validates, pauses for the user to run `/compact` and `/load-context` before continuing.

## Why Use This

The autonomous `/autogenerate-scripts` keeps accumulating context across batches, which can cause:
- Voice drift over long sessions
- Format rules getting paraphrased
- Treatment content becoming vague
- Accumulated cruft from fixes/retries

`/generate-script` solves this by giving each batch a clean context window.

---

## Usage

```
/generate-script [project]
/generate-script [project] --fresh
/generate-script [project] --from [batch]
```

**Examples:**
```
/generate-script leviathan              # Resume from last checkpoint
/generate-script leviathan --fresh      # Backup, clear, start from ep 1
/generate-script leviathan --from 6     # Resume from batch 6
```

---

## The Workflow

### Per-Batch Cycle

```
┌─────────────────────────────────────────────────────────────┐
│ 1. Load context for current batch                           │
│    - Read treatment.md (current batch section)              │
│    - Read characters.md (voice patterns)                    │
│    - Read format_v12/SKILL.md (constraints)                 │
│    - Read last 2 episodes (continuity)                      │
├─────────────────────────────────────────────────────────────┤
│ 2. Generate 5 episodes                                      │
│    - Follow Kill Box structure                              │
│    - Execute treatment prose                                │
│    - Hit THE MOMENT and cliffhanger image                   │
│    - Save to /scripting/episodes/ep_XXX.md                  │
├─────────────────────────────────────────────────────────────┤
│ 3. Run checkpoint validation                                │
│    - python3 .claude/hooks/save_checkpoint.py ./[project] N │
│    - If FAIL → fix episodes → retry validation              │
│    - Repeat until PASS                                      │
├─────────────────────────────────────────────────────────────┤
│ 4. BATCH COMPLETE - Clean context                           │
│    Output:                                                  │
│    ┌─────────────────────────────────────────────────────┐  │
│    │ BATCH [N] COMPLETE. Episodes [X]-[Y] validated.    │  │
│    │                                                     │  │
│    │ Run these commands to continue:                     │  │
│    │   /compact                                          │  │
│    │   /generate-script [project]                               │  │
│    └─────────────────────────────────────────────────────┘  │
│                                                             │
│    WAIT for user to run commands before continuing.         │
└─────────────────────────────────────────────────────────────┘
```

### Full Series Flow

```
Batch 1 → validate → STOP → /compact → /generate-script →
Batch 2 → validate → STOP → /compact → /generate-script →
...
Batch 12 → validate → COMPLETE
```

---

## Execution Instructions

When `/generate-script [project]` is invoked:

### Step 1: Load Context (MANDATORY)

**Invoke `/load-context [project] generate` FIRST.** This skill loads all required files:
- `/CONSTANTS.md`
- `/skills/format_v12/SKILL.md`
- `/[project]/treatment.md`
- `/[project]/ORCHESTRATION.md`
- `/[project]/scripting/bible/characters.md`
- `/[project]/_pipeline/state/current_state.json`
- Last 2 episodes (if any exist)

**Do NOT skip this step.** Do NOT just read the files manually—invoke the skill so it reports the current position and confirms context is loaded.

### Step 2: Identify Current Batch

From `current_state.json`:
- `next_batch` = batch to generate
- If `next_batch` > 12, generation is complete

### Step 3: Generate Batch

For each episode in the batch (5 episodes):

1. **Read treatment.md** for this episode:
   - Prose paragraph (what happens)
   - THE MOMENT (must land)
   - Cliffhanger image (end on this)

2. **Generate episode** following Kill Box structure:
   - HOOK → SETUP → ESCALATION → TURN → CLIFFHANGER
   - 450-500 words (see `CONSTANTS.md`)
   - ≤40% dialogue (see `CONSTANTS.md`)
   - ≤8 exchanges (see `CONSTANTS.md`)
   - Behavioral DNA in action blocks
   - Voice per characters.md stage

3. **Save to** `/[project]/scripting/episodes/ep_XXX.md`

4. **IMMEDIATELY validate with episode_metrics.py:**
   ```bash
   python3 /tools/episode_metrics.py ./[project]/scripting/episodes/ep_XXX.md --json
   ```
   - Check `is_valid` in the JSON output
   - If `true`: proceed to next episode
   - If `false`:
     a. Run with `--prompt` flag to get fix instructions:
        ```bash
        python3 /tools/episode_metrics.py ./[project]/scripting/episodes/ep_XXX.md --prompt
        ```
     b. Apply the fix instructions to the episode
     c. Re-validate (max 3 attempts)
   - Do NOT proceed to next episode until `is_valid: true`
   - Do NOT estimate—the validator counts accurately
   - Do NOT blame the validator if your estimate was wrong

   **CRITICAL: Validator Counting Method**

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

   **The validator counts ALL words in the file including:**
   - Headers (`# 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 fix workflow:**
   - Word count HIGH by N: Remove ~N words from action blocks
   - Word count LOW by N: Add ~N words of sensory detail
   - Exchanges HIGH: Consolidate dialogue (each character cue = 1 exchange)

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

5. **Run cinematization pass** (after word count validates):
   - Scan for literary prose patterns ("He realized...", internal states, psychology narration)
   - Transform to cinematic alternatives (physical evidence, reactions, externalized dialogue)
   - Re-validate word count if content changed
   - See `/skills/format_v12/SKILL.md` → CINEMATIZATION PASS for transformation strategies

6. **Run subtext pass** (after cinematization):
   - Flag on-the-nose dialogue ("I'm scared", "I don't trust you", direct answers)
   - Transform using deflection, displacement, action, evasion
   - Target ~70% subtext, ~30% direct
   - See `/skills/format_v12/SKILL.md` → SUBTEXT PASS for examples

7. **Apply deviation auto-fix protocols** (see `/DEVIATION_RULES.md`):
   - Word count over: Regenerate with trim focus (max 2x, then flag)
   - Word count under: Regenerate until ≥450 (no limit)
   - Dialogue excess: Regenerate with dialogue cap reminder
   - Pattern violation: Regenerate with forced pattern interrupt

### Step 4: Validate Batch

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

**If validation FAILS:**
1. Read failing episodes
2. Fix identified issues
3. Re-run checkpoint
4. Repeat until PASS

**If validation PASSES:**
Continue to Step 5.

### Step 5: Output Completion Message

```
═══════════════════════════════════════════════════════════════
BATCH [N] COMPLETE
═══════════════════════════════════════════════════════════════

Episodes [X]-[Y] validated and saved.

Cliffhanger distribution (series so far):
  Mid-action: XX% ([N] episodes)
  Aftermath:  XX% ([N] episodes)

Hook distribution (series so far):
  Silent:   XX% ([N] episodes)
  Dialogue: XX% ([N] episodes)

───────────────────────────────────────────────────────────────
TO CONTINUE WITH FRESH CONTEXT:

  /compact
  /generate-script [project]

───────────────────────────────────────────────────────────────
Progress: [N]/12 batches ([X]/60 episodes)
═══════════════════════════════════════════════════════════════
```

**IMPORTANT:** After outputting this message, STOP. Do not continue to the next batch. Wait for the user to run `/compact` and re-invoke `/generate-script`.

---

## Parameters

| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `project` | Yes | — | Project folder name (e.g., `leviathan`) |
| `--fresh` | No | off | Backup current episodes, reset state, start from ep 1 |
| `--from [N]` | No | — | Resume from specific batch number |

### --fresh Flag

When invoked with `--fresh`:

1. **Backup current episodes:**
   ```bash
   mkdir -p ./[project]/backups/episodes_backup_[TIMESTAMP]/
   mv ./[project]/scripting/episodes/ep_*.md ./[project]/backups/episodes_backup_[TIMESTAMP]/
   ```

2. **Reset state:**
   ```json
   {
     "last_completed_batch": 0,
     "last_completed_episode": 0,
     "next_batch": 1
   }
   ```

3. **Begin with Batch 1**

### --from [N] Flag

Resume from a specific batch:

1. Backup episodes from batch N onward
2. Reset state to batch N-1
3. Continue with batch N

---

## Comparison: /generate-script vs /autogenerate-scripts

| Aspect | /generate-script | /autogenerate-scripts |
|--------|-----------|---------------|
| Context handling | User manually runs /compact + /generate-script | Auto-reloads via Skill tool after each batch |
| User interaction | Pauses after each batch for user action | Fully autonomous—runs until all 60 episodes |
| Context compaction | Asks user to run /compact | Auto-recovers by invoking /load-context |
| Voice drift risk | Minimal (fresh context per batch) | Low (auto-reload between batches) |
| Speed | Slower (manual pauses) | Faster (no pauses) |
| Best for | Maximum control, manual review | Hands-off generation |

**Both commands now reload context between batches.** The difference is:
- `/generate-script` pauses for user review and manual context clearing
- `/autogenerate-scripts` handles everything autonomously (never asks user for input)

---

## Quick Reference

```
/generate-script [project]           # Resume with clean context per batch
/generate-script [project] --fresh   # Backup → Reset → Start from ep 1

WORKFLOW:
  1. /generate-script [project]      ← Generate batch N
  2. [Batch validates]
  3. "BATCH N COMPLETE"
  4. /compact                  ← Clear context
  5. /generate-script [project]      ← Generate batch N+1
  6. Repeat until Episode 60
```

---

## State Persistence

Progress is saved in `./[project]/_pipeline/state/current_state.json`:

```json
{
  "project": "leviathan",
  "last_completed_batch": 5,
  "last_completed_episode": 25,
  "next_batch": 6,
  "generation": {
    "last_validated": 25,
    "last_checkpoint": "2026-01-20T...",
    "validation_passed": true
  }
}
```

This file persists across `/compact` calls, allowing seamless resumption.

---

## Troubleshooting

### "Missing treatment.md"

Run `/treatment [project]` first to create the master generation input.

### Validation keeps failing

Check specific issues in checkpoint output:
- Word count: Add/remove action description
- Exchanges: Consolidate dialogue blocks
- Patterns: Vary hook/cliffhanger types

### Lost track of position

Check `current_state.json` for `next_batch` and `last_completed_episode`.

---

*This skill ensures each batch gets fresh context, preventing drift across the 60-episode generation.*
