editorial · git:20261014.71d43e0 · 2026-10-14 · sha256 e62cdc05e466d8b9

editorial git:20261014.71d43e0A

Immutable. This exact content never changes and is served at /api/v1/blob/e62cdc05e466d8b9.

---
name: editorial
description: >
  Editorial pack: the 14-step hype video pipeline from transcribe through
  validate, plus auxiliary tools for human-in-the-loop review, notes
  ingestion, cut inspection, boundary review, and script generation.
  Cross-pack steps include scene_describe (understanding), pool_build and
  pool_merge (training), cut (video_editing), and render (rendering).
---

# Editorial

The editorial pack is the backbone of Astrid's video creation pipeline.
It runs the full 14-step progression from raw source media to a validated
rendered video, with cross-pack handoffs to understanding, training,
video_editing, and rendering.

## Pipeline stage order

The numbered pipeline runs steps 0 through 14. Steps from other packs are
shown with their owning pack in parentheses — they are not part of the
editorial pack but are essential to the pipeline flow.

| Step | Stage | Pack | Sentinel / Output | What it does |
|---|---|---|---|---|
| 0 | transcribe | editorial | `transcript.json` | Transcribe source audio to text via Whisper. |
| 1 | scenes | editorial | `scenes.json`, `scene_items.json` | Detect scene boundaries with ffmpeg-driven analysis. |
| 2 | quality_zones | editorial | `quality_zones.json` | Tag arrangement clips with per-zone quality grades. |
| 3 | shots | editorial | `shots.json` | Slice scenes into shot windows for pool building. |
| 4 | triage | editorial | `scene_triage.json` | Triage scenes by quality — gate before pool building. |
| 5 | scene_describe | understanding | `scene_descriptions.json` | Caption each scene with a vision model (OpenAI). |
| 5.5 | video_understand | understanding | — | Synchronized audio+video window inspection. Optional, interleaved between scene_describe and quote_scout. |
| 6 | quote_scout | editorial | `quote_candidates.json` | Scan transcript for quotable lines suitable for hype clips. |
| 7 | pool_build | training | `pool.json` | Build the candidate clip pool from triaged scenes. |
| 8 | pool_merge | training | `pool.json` (mutated) | Merge multiple pools into a unified pool for arrangement. |
| 9 | arrange | editorial | `arrangement.json` | Compose a brief-specific shot arrangement from the pool via LLM. |
| 10 | cut | video_editing | `hype.timeline.json`, `hype.assets.json`, `hype.metadata.json` | Assemble arrangement into the timeline+assets+metadata JSON triple for Remotion. |
| 11 | refine | editorial | `refine.json` + mutated triple | Apply targeted reviewer-driven refinements to the arrangement. |
| 12 | render | rendering | `hype.mp4` | Render the timeline to video through the Remotion compositor. |
| 13 | editor_review | editorial | `editor_review.json` | Run heuristic editorial reviewers over the rendered video. Human-in-the-loop gate. |
| 14 | validate | editorial | `validation.json` | Validate rendered video against timeline and metadata (Whisper + schema). |

### Pipeline flow diagram

```
transcribe → scenes → quality_zones → shots → triage
                 ↓
           scene_describe (understanding, step 5)
                 ↓ (optional 5.5: video_understand)
           quote_scout
                 ↓
           pool_build → pool_merge (training, steps 7-8)
                 ↓
           arrange → cut (video_editing, step 10) → refine
                 ↓
           render (rendering, step 12)
                 ↓
           editor_review → validate
```

## Auxiliary tools (outside numbered pipeline)

These actions are not part of the numbered 0–14 pipeline. They have no
`pipeline_step_order` in their action.yaml and operate standalone.

| Action | What it does |
|---|---|
| `editorial.human_notes` | Convert free-text human editorial notes into structured `editor_review.json` for the pipeline. Optional `--apply` chains a full revise cycle. |
| `editorial.inspect_cut` | Debugging tool: inspect a cut run directory and print a script/structure/clip text report. Supports `--json` and `--clip` flags. Called internally by `editor_review`. |
| `editorial.human_review` | Generic human-gate primitive. Serves an HTML page on localhost, collects human decisions as JSON, blocks until submit. Token-authenticated POSTs. |
| `editorial.boundary_candidates` | Package candidate video frames for visual scene-boundary review. |
| `editorial.script_pipeline` | Preset-driven creative-writing pipeline: generates short scripts through rough attempts, synthesis, style pass, and optional judging. |

## When to use

- Use `editorial.transcribe` through `editorial.validate` in pipeline
  order when running the full hype video workflow. The hype orchestrator
  (`video_editing.hype`) sequences these automatically.
- Run individual editorial actions standalone when you need to re-run
  a specific stage (e.g., re-transcribe with different settings, re-triage
  with adjusted quality thresholds).
- Use `editorial.human_notes` when you have free-text feedback and want
  it converted to structured pipeline inputs.
- Use `editorial.inspect_cut` for debugging a cut run directory — it
  prints a human-readable report of the timeline, assets, and clips.
- Use `editorial.human_review` as a generic human-in-the-loop gate for
  any review workflow (dataset review, eval-grid pick, arrangement
  approval).
- Use `editorial.boundary_candidates` when you want to visually review
  scene boundaries before committing to cuts.
- Use `editorial.script_pipeline` when you need AI-generated creative
  scripts from a preset or prompt.

## Credentials

| Env var | Used by |
|---|---|
| `OPENAI_API_KEY` | transcribe (Whisper API), arrange (LLM), refine (LLM), editor_review (Claude vision), script_pipeline (DeepSeek) |
| `ANTHROPIC_API_KEY` | editor_review (Claude vision model for frame sampling) |

## SDK quick-start

```python
# Transcribe (step 0)
import astrid.sdk as sdk
result = sdk.invoke(
    "editorial.transcribe",
    inputs={"audio": "./source.mp3"},
    out="./out",
)

# Detect scenes (step 1)
result = sdk.invoke(
    "editorial.scenes",
    inputs={"video": "./source.mp4"},
    out="./out",
)

# Quality zones (step 2)
result = sdk.invoke(
    "editorial.quality_zones",
    inputs={"video": "./source.mp4"},
    out="./out",
)

# Shots (step 3)
result = sdk.invoke(
    "editorial.shots",
    inputs={"video": "./source.mp4", "scenes": "./out/scenes.json"},
    out="./out",
)

# Triage (step 4) — quality gate before pool building
result = sdk.invoke(
    "editorial.triage",
    inputs={"scenes": "./out/scenes.json", "shots": "./out/shots.json"},
    out="./out",
)

# Quote scout (step 6) — find quotable lines
result = sdk.invoke(
    "editorial.quote_scout",
    inputs={"transcript": "./out/transcript.json"},
    out="./out",
)

# Arrange (step 9) — compose shot arrangement
result = sdk.invoke(
    "editorial.arrange",
    inputs={
        "pool": "./out/unified_pool.json",
        "brief": "./briefs/my-hype.md",
        "theme": "./themes/default.json",
    },
    out="./out",
)

# Refine (step 11) — last editorial pass before cut
result = sdk.invoke(
    "editorial.refine",
    inputs={
        "arrangement": "./out/arrangement.json",
        "pool": "./out/unified_pool.json",
        "timeline": "./out/hype.timeline.json",
        "assets": "./out/hype.assets.json",
    },
    out="./out",
)

# Editor review (step 13) — human-in-loop gate
result = sdk.invoke(
    "editorial.editor_review",
    inputs={"brief_dir": "./out", "run_dir": "./runs/my-run"},
    out="./out",
)

# Validate (step 14) — schema + Whisper validation
result = sdk.invoke(
    "editorial.validate",
    inputs={
        "video": "./out/hype.mp4",
        "timeline": "./out/hype.timeline.json",
        "metadata": "./out/hype.metadata.json",
    },
    out="./out",
)

# Human notes (auxiliary) — convert feedback to structured inputs
result = sdk.invoke(
    "editorial.human_notes",
    inputs={"notes": "./my-notes.md"},
    out="./out",
)

# Inspect cut (auxiliary) — debug a cut run directory
result = sdk.invoke(
    "editorial.inspect_cut",
    inputs={"run_dir": "./runs/my-run", "json": True},
)

# Human review (auxiliary) — serve review page
result = sdk.invoke(
    "editorial.human_review",
    inputs={"html": "./review-page.html", "data": "./data.json"},
    out="./out",
)

# Boundary candidates (auxiliary) — package frames for review
result = sdk.invoke(
    "editorial.boundary_candidates",
    inputs={
        "video": "./source.mp4",
        "manifest": "./boundary_manifest.json",
    },
    out="./out",
)

# Script pipeline (auxiliary) — generate creative scripts
result = sdk.invoke(
    "editorial.script_pipeline",
    inputs={
        "preset": "hype-intro",
        "prompt": "A dramatic opening scene",
    },
    out="./out",
)
```