Cohort Ad Pipeline
One composition, N prospects, one click. The pipeline behind every Roof Radar contractor ad. This page walks through every step so you can see what each node does, what changes when you swap it, and what NOT to mess with unless you know what you're breaking.
The shape of the pipeline
The cohort pipeline takes five inputs and produces one mp4 per prospect row. The five inputs:
- Cohort CSV — one row per prospect (company, contact, ZIP)
- Deep Intel JSON — per-company research data (pain points, gold details, paid leads)
- Voice reference — your cloned voice in a clean WAV
- Script lines — the per-line text the voice will read
- Stills — the beat-by-beat images for the composition
Open the prebuilt graph in the Studio: /studio?template=cohort-ad-pipeline
Step by step
1. Cohort CSV
The list of prospects to render. Each row is one ad. The renderer iterates top to bottom; HYBRIG_COHORT_LIMIT=N caps how many fire.
If you change it: add/remove prospects. The output filename follows the slug of the company name. What breaks: nothing — but a row missing from Deep Intel renders with empty personalization fields (no opener line about the contractor by name).
2. Deep Intel lookup
Matches each CSV row to a research record by company name (case-insensitive). Pulls painPoint, goldDetail, paidLeadsOn — the per-prospect ammo that makes the opener feel personal rather than generic.
If you change it: swap the source JSON to point at a different research dataset. The schema is canonical camelCase (decisionMaker, painPoint, etc.). What breaks: the opener falls back to a generic line if the company name doesn't match. Missing entries log a warning and continue.
3. F5-TTS chunked + leak strip
Voice clone, but per-line. Generates one WAV per script line, transcribes each chunk with faster-whisper, and trims any phantom prefix the model hallucinates from the reference clip. Concatenates clean chunks with 250ms pads. Probes the final WAV duration so the composition can size visuals to fit.
If you change it: swap voice_ref for a different speaker. Trim voice_ref to 5-15s (F5-TTS's recommended range); shorter degrades clone quality, longer over-conditions. What breaks: if voice_ref_text contains brand or industry words, the model may bleed them into chunk starts. Whisper strip catches most of it but use a neutral reference transcript when in doubt.
Why this exists: F5-TTS bleeds the reference audio into chunk starts ~80% of the time. On Peak Custom Remodeling's render, 14 of 16 chunks had phantom prefix bleed (verified 2026-05-13). The leak strip is mandatory for cohort renders, not optional.
4. VO-driven composition
Renders the slideshow. Reads the probed voice duration and expands or shrinks the elastic beat (Beat 20 in the StopKnockingBlind composition) so the visual exits ~0.5s after the audio. No silent tails, no audio cutoffs.
If you change it: swap stills or change beat durations. Beat 20 is the elastic beat; the rest are hardcoded. What breaks: if the VO is wildly off the expected length, Beat 20 clamps at [3s, 30s]. A clamp hit means the composition needs structural redesign — open a fresh issue, don't fight the clamp.
The principle: every scene, every image, every word, every moment needs a reason for existing. If there's no audio paired with it, the shot doesn't need to keep going. VO-driven sizing bakes this into the renderer.
What changes when you swap parts
- Different voice ref → different speaker, same script + visuals
- Different script → same voice + visuals, new dialogue + arc
- Different stills → new visuals, voice + script unchanged
- Different Deep Intel → personalization tokens shift (pain point, paid leads)
- Different CSV → different prospects rendered, everything else unchanged
The pipeline is intentionally modular — every node is swap-without-breaking-others unless it produces an output another node depends on (voice → composition is a hard dependency; CSV row count is not).
Where the work happens
Every node above runs locally on your machine — F5-TTS on your GPU, Whisper on CPU, Remotion rendering frames on your GPU. No cloud step in the cohort pipeline. The only cloud touch is the optional Deep Intel research data, which is just JSON sitting on disk.
See the clean-plate compositing lesson for why per-prospect personalization happens at composition time, not at image-generation time.