---
reliability: 3.2 # 5 − wizper .2 − brand-kit refs .3 − cover (image gen) .3 − quote cards .3 − summary card .3 − 7-stage chain .4; audiogram composition (trim/caption/lower-third/mux/export) deterministic; cap ceiling: typography-heavy — AI text-in-image is the #1 failure mode, hence gpt-image everywhere text appears
---

# Podcast episode to social assets — agent playbook

> Paste this whole file (with the BRIEF filled in) into Claude cowork, chat, or Code. The agent walks through it with you and stops for your approval at every step that matters.

## What you'll get

A complete post-episode social package built from the episode audio you already published. This is what podcast tools like Headliner charge $20/mo for — one playbook, brand-locked across every asset.

- **3-5 audiograms** — 60-second vertical clips of your highlight moments, animated waveform + caption overlays. Reels / TikTok / Shorts native.
- **Updated episode cover art** — 3000×3000 square cover for streaming platforms.
- **Episode summary card** — a single 1:1 image with key quote pulled from the episode, palette-locked.
- **Sponsor read clip** — if you mark a sponsor moment, isolated + branded as its own deliverable.
- **Full episode subtitle SRT** — transcribed, ready to upload as captions on the YouTube video version.
- **Quote-card pack** — 3 pull-quote graphics for Threads / LinkedIn / X.

**Time**: ~20 minutes wall clock. **Your attention**: about 5 minutes across 6 approvals. **Cost**: $0.80 – $1.80 end to end.

## Tell the agent about the episode

```yaml
podcast_url:           # the full episode audio — upload via /upload, or paste the public mp3 URL
episode_title:         # e.g. "EP-47: Why founders should fire themselves first — with Jane Doe"
episode_number:        # 47
show_name:             # the podcast's brand name
episode_summary:       # 2-3 sentence episode description
highlight_moments:     # list of objects, each with timestamp + description (see example below)
sponsor_moment:        # OPTIONAL — { start: "12:30", end: "13:45", sponsor_name: "Acme Coffee" }
brand_palette:         # 4 hex colors space-separated, e.g. #1A1A2E #E94560 #F5F5DC #16213E
host_photo_url:        # OPTIONAL — host portrait, used in lower-thirds on audiograms
episode_slug:          # kebab-case, e.g. ep-47-founders-fire-themselves

# Example highlight_moments format:
# highlight_moments:
#   - { start: "02:15", end: "03:15", description: "the moment Jane explains the trap" }
#   - { start: "18:40", end: "19:35", description: "the founder-CEO transition framework" }
#   - { start: "33:00", end: "33:55", description: "the one-question test for self-firing" }
```

## Quality controls (new — auto-applied)

This playbook leverages the closed quality loop. The agent applies these by default; you don't have to ask:

- **Cost upfront.** Before any multi-step batch fires, the agent calls `submit_plan` with `confirm:false` and shows you the proposed steps + total cost. Nothing runs until you approve.
- **Auto-retry on weak shots.** The server default is `quality_threshold: 0.7`. For brand-locked covers + audiograms the playbook step tells the agent to pass `quality_threshold: 0.85` so a low-confidence first try gets one auto-retry before you see it.
- **Critic verdict on the result.** When a multi-asset step finishes, the agent reads the `critique` field on the response (verdict: ship / iterate, plus issues / missing items) and surfaces it for your review.
- **One-click recovery.** If a step fails, `get_plan` returns a `recovery` hint pointing at `replan({plan_id})` — the agent classifies the failure and proposes a recovery plan you can approve.
- **End-of-project scorecard.** The final wrap-up calls `get_scorecard({project_id})` with succeeded count, mean quality score, critic verdict, total cost, and wall time.

You can override any of these per step: pass `quality_gate: false` on cost-sensitive tries, `quality_threshold: 0.6` for stylized work, or `submit_plan({plan_id, confirm:true})` to skip the cost-preview pause when you trust the chain.

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

1. **CONFIRM (one message, ≤1 question):** restate in 1 line ("EP-<N> → <M> audiograms + cover + quote cards + SRT, brand-locked to your palette, ~$0.80–1.80, ~20 min") + real choices: how many audiograms (3 vs 5) · sponsor clip yes/no · skip the cover if the show art already exists. One question max — usually "are the highlight timestamps right?".
2. **PREVIEW CHECKPOINT:** transcript scan + brand kit + the FIRST audiogram (~$0.20 total) before looping the rest — if the waveform style, caption font, or palette is off, fix it on one clip, not five. Quote-card picks also surface here for a veto.
3. **NARRATE:** per stage: "transcribing 45 min of audio (~3 min)…", "audiogram 2/5 composing (job …)"; poll `get_create_media` every 10–15s; never silent >2 min — the audiogram loop is the long pole.
4. **FAIL GRACEFULLY:** `wizper` fails → `nemotron-asr` (better non-English punctuation anyway); gpt-image garbles cover/quote-card text → retry once → `ideogram-v4` / `mai-image-2.5` (the typography caps) → worst case render textless art + overlay the title via `hyperframes-lower-third`; `hyperframes-caption` unavailable → static waveform via `ffmpeg-overlay`. ≤2 retries per asset; ship the assets that worked with a note on the one that didn't.
5. **DELIVER:** the full pack + one honest line ("quote cards: verify the 3 quotes against the transcript before posting — LLM-picked, timestamps included; cover text verified legible") + ONE next step ("schedule the audiograms across drop week via `publora_publish_post`").

## How this works

Six gates. The brand kit + episode cover lock the visual identity; everything below inherits palette + host_photo automatically. The audiograms are the killer asset — these are what drive episode discovery on social.

## The steps

### Step 0 — Confirm the brief

The agent reads back the BRIEF and lists each highlight moment with its timestamp + description.

**STOP**: "Brief looks right? Highlights listed correctly? (approve / edit highlight [#] / edit [field] [new value])"

### Step 1 — Transcribe full episode (~3 min, ~$0.20)

The agent transcribes `podcast_url` via `wizper` (Whisper-v3) → timestamped SRT for the whole episode. Used in Step 4 (audiograms) for caption overlay and saved as a final deliverable (you can upload as caption track on the YouTube version of the episode).

> **For the agent**: `wizper` returns timestamped segments. For non-English shows or where streaming/punctuation matters, `nemotron-asr` (40 locales, native punctuation) is the alternative.

**STOP**: "Transcript generated. Quick scan for accuracy? (approve / flag timestamp [X:XX] for review)"

### Step 2 — Lock the brand kit (~30s, ~$0.05)

`brand_kit_create` from `brand_palette` + `show_name` (voice keywords inferred from `show_name` + `episode_summary`, 3 reference graphics), then `set_active_brand_kit` so every subsequent asset auto-inherits the palette.

**STOP**: "Approve the brand kit, or refine? (approve / refine [direction])"

### Step 3 — Updated episode cover art (~2 min, ~$0.40)

The agent calls `create_media` with `gpt-image` (because the cover has typography: `show_name`, `episode_title`, `episode_number`). 3000×3000 square, brand-locked palette, premium quality. This is what shows on Spotify / Apple Podcasts / Overcast for this episode.

> **For the agent**: pass `quality_threshold: 0.85`. `gpt-image` for typography reliability — text on AI-generated images is the #1 failure mode and this is the asset most exposed to it. If `host_photo_url` is set, pass as `quality_anchor_url` so the host's likeness can be inset on the cover.

**STOP**: "Episode cover approved? (approve / refine [direction])"

### Step 4 — Generate audiograms (~6 min, ~$0.80)

The agent loops over `highlight_moments`. For each one:

1. `ffmpeg-trim` the audio to the moment's `start`–`end` window
2. `hyperframes-caption` generates an animated-waveform video (9:16, 1080×1920) with the transcript captions burned in at center-frame, brand-palette colors
3. `hyperframes-lower-third` overlays `show_name + episode_number + host_name` at the bottom
4. `ffmpeg-mux` the trimmed audio (Step 4.1) under the composed video with `audio_fill: "loop"` — the spoken clip IS the deliverable, so the audio track must be present and cover the full clip
5. `ffmpeg-export` to `size: "portrait_9_16"` at platform bitrate

Each output: a 60s vertical clip ready to post on Reels / TikTok / Shorts. The animated waveform is what makes audiograms work — it gives motion to what's otherwise a static caption-on-image.

> **For the agent**: pass `quality_threshold: 0.8` on the waveform composition. Use the brand palette's hero color for the waveform's active bars, neutral for background. If `host_photo_url` is set, pass it to the lower-third overlay.

**STOP**: "Audiograms ready. Approve all, or redo specific? (approve / redo [#] [direction])"

### Step 5 — Sponsor clip + quote-card pack (~3 min, ~$0.20)

**If `sponsor_moment` is set**: `ffmpeg-trim` the audio to that window, generate a branded audiogram (Step 4's pipeline) but with `sponsor_name` as a corner watermark and a clean intro/outro card calling out the sponsor. This is a standalone asset — sponsors love that you cut their read as its own deliverable.

**Quote-card pack**: the agent picks the 3 strongest single-line quotes from the transcript (using LLM analysis of the SRT for "tweetable" lines), and renders 3 quote graphics — 1:1 square, brand-palette, large clean typography on quote + small attribution to host + show. Posted to Threads / LinkedIn / X.

> **For the agent**: use `gpt-image` for the quote cards — typography is the entire point. Pass `quality_threshold: 0.85`. If the LLM can't find 3 quotable lines, ask the user to point at favorites by timestamp.

**STOP**: "Sponsor clip + quote cards approved? (approve / redo [which])"

### Step 6 — Episode summary card (~1 min, ~$0.15)

A single 1:1 card combining: episode number + title at top, key takeaway quote in the middle, brand palette + a small `host_photo_url` inset (if supplied). This is what gets pinned to your podcast's social profile when the episode drops.

> **For the agent**: `gpt-image` again for typography. Pass `quality_threshold: 0.85`.

**STOP**: "Summary card approved? (approve / refine)"

### Final step — scorecard wrap-up

Call `get_scorecard({project_id: ...})` — paste output to your channel.

```
Scorecard for cjob_xxx
N/N assets shipped — critic: SHIP
Title: {episode_title}
Steps: N/N succeeded (100%)
Quality: mean X.XX · M/N passed · K retries
Cost: $X.XX actual (est $Y.YY) · Ts wall time
Viewer: <project URL>
```

## When you're done

```
✅ Episode cover (3000×3000): <URL>
✅ Audiograms (60s × N): <URL × N>
✅ Sponsor clip (if generated): <URL>
✅ Quote cards (1:1 × 3): <URL × 3>
✅ Summary card (1:1): <URL>
✅ Full episode SRT: <URL>

Total spent: $X.XX
Total wall-clock: MM:SS
```

## What to do next

Schedule the audiograms to Reels / TikTok / Shorts across the week the episode drops — ask the agent to `publora_publish_post` each one to your connected accounts, or use your own scheduler. Each drives a different segment of audience back to the full episode. Pin the summary card to your show's social profile. Send the sponsor clip directly to the sponsor as proof-of-read.

Upload the episode SRT as the caption track on the YouTube video version of the episode — accessibility + SEO win in one pass.

Save your `brand_palette` and `show_name` in the brief. Every future episode runs this playbook in 20 minutes from "audio uploaded" to "social pack posted." Compare to Headliner / Wavve / Descript at $20-40/mo each, and this is one-shot per episode at $1-2 with brand-kit consistency built in across episodes.

---

## Notes for the agent (only read if a step fails)

**Audiogram waveform**: `hyperframes-caption` is the primary capability; if unavailable, fall back to composing a static-waveform-image overlay via `ffmpeg-overlay` with the audio's spectrogram extracted via direct SDK.

**Quote selection LLM**: ask Gemini Flash via direct SDK to read the SRT and return 3 timestamped "most tweetable" lines as JSON. Don't use the host LLM — keep this cheap.

**Sponsor moment validation**: if `sponsor_moment.end - sponsor_moment.start` is < 30s or > 120s, ask the user to confirm — sponsor reads in that range are unusual and might be a typo.
