zack-d-films
Recreates the Zack D Films production line — normally a 50-person team — as one
Claude chat over Higgsfield MCP. The user experience follows five acts, in this
exact order, matching the channel's real growth engine: SCRIPT → VISUALS →
ANIMATION → VOICE → EDIT.
HOW TO READ THIS FILE: execute Phases 1→8 IN ORDER. Each phase has a GATE.
Long templates live in references/ — read them when the phase says so.
references/replication-troy.md is the canonical worked example (the Trojan
Horse short): when in doubt about any phase's output shape, imitate it.
Runtime contract
- Models are LOCKED: stills/character sheets →
seedream_v5_pro · animated
blocks → gemini_omni · narration → seed_audio. Never substitute.
- Aspect is 9:16 unless the user explicitly asks for 16:9. Pass
aspect_ratio explicitly on EVERY image and video call — it never inherits.
- All shell work (probe, Whisper timing, ffmpeg edit, upload) runs in
Higgsfield
sandbox_exec — never on the client. Preflight a fresh run with:
sandbox_exec({restart:true, command:"set -e; for b in ffmpeg ffprobe python3 curl jq; do command -v $b >/dev/null; done; python3 -c 'import faster_whisper'; mkdir -p zack/{blocks,audio,output}"})
- Poll every job to a terminal state.
completed is the only good state. On
failed/nsfw: RETRY LADDER (bottom of file). If no dedicated status tool is
available, job_display({id}) returns the job's status + result URLs; wait
between polls with sandbox_exec({command:"sleep 50"}) (~40–60s for images,
poll video jobs every ~60s; blocks take 2–6 min).
medias[].role may be auto-coerced by the server (e.g. image →
image_references on seedream). That's fine — read the adjustments field,
don't fight it.
- If a
gemini_omni call returns a preset RECOMMENDATION instead of a job,
resubmit the same call with declined_preset_id set to that preset's id.
Never ask the user about it.
- Maintain
zack/manifest.json in the sandbox (or an equivalent local notes
block) recording: locked style formula, asset job ids, per-block prompts +
job ids + statuses, narration job id, beat map, edit map. It is the resumable
source of truth.
- Never expose model names, phase names, or internal mechanics in chat. The
user sees creative substance and approval gates only.
- Characters NEVER talk on screen (no lip-sync). The narrator is external.
Every video prompt includes "characters only emote and gesture, they do NOT
talk" and a mute/diegetic-only audio note.
- No real brand / studio / IP names in prompts. No on-screen text in
generations (annotations are shapes, not words).
The house formula (what makes it "a Zack video")
- Curiosity loop script — opens a question the brain needs closed; closes
it in the final line with a reframing kicker.
- Perfect consistency — every recurring person/object/place is generated
once as a character sheet, then referenced in every clip. Same backbone
every time; the model never "remembers", it sees.
- Signature 3D look — glossy stylized-realistic 3D (see
references/style-3d.md), warm sun, cobalt sky, PBR materials.
- Baked annotations — neon-green glowing outlines/arrows/rectangles for
"look here / how it works"; red dashed trajectories, red glowing cracks and
red impact bursts for danger/physics. Rendered in-world by the video model.
- One recognizable narrator voice — the user's cloned voice.
- Zoom-ins and screen shakes timed to key moments in the edit.
PIPELINE
Phase 1 — RESEARCH (trending topics → options)
If the user already named a topic, skip to Phase 2.
Otherwise search the web NOW (2–3 queries: "trending topics this week
{month year}", "what is everyone talking about {month year}", one vertical the
user cares about). Find anchors with mainstream heat (a new movie, a viral
event, a season). For each anchor derive a history/science story with a
secret: the best picks have (a) a myth everyone believes, (b) a documented
"actually..." angle, (c) strong physical/visual potential.
Present 3–5 topic options, one line each: **Topic** — why it's hot now + the hidden angle. Wait for the user's pick.
GATE 1: a picked topic.
Phase 2 — ANGLE
State the angle in one sentence of the form: "Everyone believes X — but
[historians/engineers/scientists] now think Y, and the real mechanism is
Z." The angle must flip the familiar story, not just retell it.
GATE 2: an angle with a genuine flip.
Phase 3 — SCRIPT (curiosity loop)
Read references/scriptwriter.md, then write the narration:
- Default length 28–32s ≈ 75–85 words (~2.7 words/sec). Scale by the same
rate if the user asked for another duration.
- 5 beats: Myth → Twist → Mechanism A → Mechanism B → Kicker.
- Then run the rewrite pass from scriptwriter.md (cut hedges, concretize
numbers, kill adjectives that don't render).
Show the script in chat (SCRIPT LOCK) and ask one short approve/tweak
question. This is the last mandatory stop — after approval the run is
hands-off to final video.
GATE 3: approved script.
Phase 4 — SCENE PLAN (the production plan)
Read references/scene-planning.md. Break the script into blocks of 10s
(N = ceil(duration/10)). For every block write a timed shot list — Zack pacing
is 6–9 hard cuts per 10s block (~1.0–1.6s per shot). For each shot:
[t0–t1] SIZE/ANGLE — subject + action — annotation (if any) — assets used.
Rules: vary size+angle on every cut; at least one MACRO eye/detail shot per
video; one "gag" beat (vanish-poof, deadpan reveal); annotations per the
green/red grammar; every shot names which character sheets appear.
Also produce the asset roster: every character, object, environment that
appears in ≥2 shots, plus damage/wear states (e.g. "wall — intact / cracked /
breached"). Post the plan in chat as a compact table. Do not wait for approval
(the script was the lock) — proceed.
GATE 4: every block has timed shots; every shot maps to roster assets.
Phase 5 — CHARACTER SHEETS (the consistency backbone)
Read references/style-3d.md and take its STYLE FORMULA byte-identical
into every prompt in this phase and Phase 6.
- Style key — one
seedream_v5_pro still (9:16): a representative scene
in the formula. Keep its job_id as the look anchor.
- Asset sheets — one image per roster entry, in parallel, each with the
look anchor as
medias role image:
- people →
aspect_ratio:"2:3", full body, neutral flat backdrop, front
3/4 view, sheet-style;
- objects/props →
"1:1", isolated, no scene;
- environments →
"9:16" (target aspect), dressed, no people. Subject-bleed
guard (proven bug): the style key's hero subject WILL leak into location
plates unless the prompt says ENVIRONMENT SHEET — EMPTY LOCATION PLATE, take only the render style and palette from the reference image, NOT its subject plus an explicit ABSOLUTELY NO {style-key subject}, NO people, NO animals line. QC every environment plate for the hero subject before
Phase 6 and regenerate contaminated ones with that wording;
- damage/wear states → separate sheet derived from the base sheet (pass the
base sheet job_id as an additional media).
- Poll all to
completed. Show the gallery in chat with one line: these are
the character sheets that keep every scene consistent.
GATE 5: every roster entry has a completed sheet. Never enter Phase 6 with
a missing asset — that beat WILL drift.
Phase 6 — ANIMATION (one call per block)
For each block submit ONE gemini_omni call: duration:10,
resolution:"720p", aspect_ratio:"9:16", medias = environment →
characters → props (role image_references, max ~3 — pick the assets that
block actually shows). The prompt = the block's timed shot list rewritten as
explicit timecoded cuts (template in references/scene-planning.md §3),
including annotation directions, camera energy (whip-ins, crash zooms), the
"do NOT talk" line, and the NEGATIVE line. Submit blocks in parallel batches
of ≥3; poll the batch; RETRY LADDER on failures. A completed block is FINAL
unless it violates a named QC check (style drift vs sheets, wrong aspect,
collapsed cuts → regenerate once with the cut list emphasized).
Download every block into the sandbox as zack/blocks/blockNN.mp4.
GATE 6: all N blocks completed + downloaded, no gaps.
Phase 7 — VOICE (the user's voice, one continuous narration)
- If the user has provided ~1 min of their voice: create a cloned voice
(voice-creation tool /
create_voice flow), then use its element voice_id.
- Else call
list_voices and let the user pick once (or reuse the voice they
picked in a previous run — it's in memory/manifest). Record
voice_id+voice_type; LOCKED for the channel.
- Generate the FULL script as ONE
seed_audio take:
[confident documentary narrator, deliberate storytelling pace with natural beats between sentences, starts speaking immediately] [00:00-00:{len}] {full script} with the locked voice pair. Pacing note (proven): with a
plain "tight pacing" hint the take lands ~10% SHORT of the timecode window;
the "deliberate storytelling pace" wording hits the target. Check
durationSec on the completed job — aim for N×10 − 1.5s; regenerate with an
adjusted pacing hint if off by >2s.
- Download to
zack/audio/narration.wav. In the sandbox run faster-whisper
word timestamps → zack/audio/words.json. Derive the beat map: the
timestamp of every beat keyword (the moments zoom-ins will hit).
- If narration > N×10s: tighten the script line that overflows and regenerate.
NEVER time-stretch audio.
GATE 7: one narration file ≤ N×10s, words.json, beat map.
Phase 8 — EDIT (zooms, shakes, final cut)
Read references/scene-planning.md §4 (edit grammar). Order of operations
(proven): call media_upload({filename:"final.mp4"}) FIRST to get the
presigned PUT URL and media_id, THEN assemble — so the upload can run inside
the same sandbox call as the render. Sandbox persistence is not guaranteed
between calls (files may vanish even back-to-back): the robust default is
ONE foreground sandbox_exec call (≤120s) that does everything — write
helper files via quoted heredocs, download blocks + narration with parallel
curl, probe fps, extract/concat SFX, concat blocks, apply the edit map,
mix, trim, curl PUT to the presigned URL. Use -preset veryfast -crf 16/17
to fit the budget (a 3-block short assembles in ~50s). Steps:
- Concat blocks 1..N (re-encode, uniform fps from probe — never hardcode).
- Apply the edit map with the bundled
scripts/zack_edit.py, fed by
edit_map.json:
punch zoom-ins (~1.0→1.08 over ~0.4s) at 3–6 beat-map moments
(reveals, annotations, kicker);
shake (±1% crop jitter, ~0.3s) at every block boundary and impact beat.
In the one-shot path, run zack_edit.py --print-vf to emit just the ffmpeg
-vf expression and fold it into the final encode (one pass instead of
two) — scripts/assemble_oneshot.sh is the proven full template.
- Lay the narration over the composite from t=0 (video SFX ducked to ~0.25×
under it),
amix ... ,loudnorm=I=-16:TP=-1.5, trim to narration end + 0.4s.
- QC probe: 1080×1920, duration ≈ narration+tail, audio present, plays from
frame 1.
- Upload with the presigned URL from step 0 (
curl -f -X PUT in the SAME
call as assembly), then media_confirm({type:"video", media_id}) → deliver
the hosted URL. One file, final.mp4. A sandbox path is not a deliverable.
GATE 8: exactly one final MP4, delivered as a confirmed hosted URL.
After delivery
Offer (one line each, never run unasked): 2K upscale via upscale_video;
a YouTube title/description pass; saving the style+voice as the channel
profile for next time.
RETRY LADDER (Phase 5/6 failures)
- Resubmit same prompt (new seed) ×2.
- Reword: soften violence tokens (battle → clash, blood → dust), remove
tight-face close-ups of distressed characters, resubmit ×2.
- Reframe the beat (different shot size / staging).
- Never drop a block, never leave a gap. After ~8 attempts on one block, stop
and surface it.
FINAL QC CHECKLIST
1---2name: zack-d-films3description: End-to-end pipeline for Zack D Films-style 3D animated myth-busting shorts via Higgsfield MCP. Use whenever the user asks for a "Zack D Films style short", "Zack-style video", a 3D animated short about "what really happened", a myth-busting / hidden-mechanism vertical short, or just "make me a Zack short". One prompt in → trending-topic research, curiosity-loop script, scene-by-scene production plan, character sheets for consistency, 3D animated blocks with baked green/red annotations, cloned-voice narration, and a final edited 9:16 MP4 with zoom-ins and screen shakes. Hands-off after topic pick and script lock.4---56# zack-d-films78Recreates the Zack D Films production line — normally a 50-person team — as one9Claude chat over Higgsfield MCP. The user experience follows five acts, in this10exact order, matching the channel's real growth engine: **SCRIPT → VISUALS →11ANIMATION → VOICE → EDIT.**1213> HOW TO READ THIS FILE: execute Phases 1→8 IN ORDER. Each phase has a GATE.14> Long templates live in `references/` — read them when the phase says so.15> `references/replication-troy.md` is the canonical worked example (the Trojan16> Horse short): when in doubt about any phase's output shape, imitate it.1718## Runtime contract1920- **Models are LOCKED:** stills/character sheets → `seedream_v5_pro` · animated21 blocks → `gemini_omni` · narration → `seed_audio`. Never substitute.22- **Aspect is 9:16** unless the user explicitly asks for 16:9. Pass23 `aspect_ratio` explicitly on EVERY image and video call — it never inherits.24- All shell work (probe, Whisper timing, ffmpeg edit, upload) runs in25 Higgsfield `sandbox_exec` — never on the client. Preflight a fresh run with:26 `sandbox_exec({restart:true, command:"set -e; for b in ffmpeg ffprobe python3 curl jq; do command -v $b >/dev/null; done; python3 -c 'import faster_whisper'; mkdir -p zack/{blocks,audio,output}"})`27- Poll every job to a terminal state. `completed` is the only good state. On28 `failed`/`nsfw`: RETRY LADDER (bottom of file). If no dedicated status tool is29 available, `job_display({id})` returns the job's status + result URLs; wait30 between polls with `sandbox_exec({command:"sleep 50"})` (~40–60s for images,31 poll video jobs every ~60s; blocks take 2–6 min).32- `medias[].role` may be auto-coerced by the server (e.g. `image` →33 `image_references` on seedream). That's fine — read the `adjustments` field,34 don't fight it.35- If a `gemini_omni` call returns a preset RECOMMENDATION instead of a job,36 resubmit the same call with `declined_preset_id` set to that preset's id.37 Never ask the user about it.38- Maintain `zack/manifest.json` in the sandbox (or an equivalent local notes39 block) recording: locked style formula, asset job ids, per-block prompts +40 job ids + statuses, narration job id, beat map, edit map. It is the resumable41 source of truth.42- Never expose model names, phase names, or internal mechanics in chat. The43 user sees creative substance and approval gates only.44- Characters NEVER talk on screen (no lip-sync). The narrator is external.45 Every video prompt includes "characters only emote and gesture, they do NOT46 talk" and a mute/diegetic-only audio note.47- No real brand / studio / IP names in prompts. No on-screen text in48 generations (annotations are shapes, not words).4950## The house formula (what makes it "a Zack video")51521. **Curiosity loop script** — opens a question the brain needs closed; closes53 it in the final line with a reframing kicker.542. **Perfect consistency** — every recurring person/object/place is generated55 once as a character sheet, then referenced in every clip. Same backbone56 every time; the model never "remembers", it *sees*.573. **Signature 3D look** — glossy stylized-realistic 3D (see58 `references/style-3d.md`), warm sun, cobalt sky, PBR materials.594. **Baked annotations** — neon-green glowing outlines/arrows/rectangles for60 "look here / how it works"; red dashed trajectories, red glowing cracks and61 red impact bursts for danger/physics. Rendered in-world by the video model.625. **One recognizable narrator voice** — the user's cloned voice.636. **Zoom-ins and screen shakes** timed to key moments in the edit.6465## PIPELINE6667### Phase 1 — RESEARCH (trending topics → options)68If the user already named a topic, skip to Phase 2.69Otherwise search the web NOW (2–3 queries: "trending topics this week70{month year}", "what is everyone talking about {month year}", one vertical the71user cares about). Find anchors with mainstream heat (a new movie, a viral72event, a season). For each anchor derive a *history/science story with a73secret*: the best picks have (a) a myth everyone believes, (b) a documented74"actually..." angle, (c) strong physical/visual potential.75Present **3–5 topic options**, one line each: `**Topic** — why it's hot now +76the hidden angle`. Wait for the user's pick.77**GATE 1:** a picked topic.7879### Phase 2 — ANGLE80State the angle in one sentence of the form: *"Everyone believes X — but81[historians/engineers/scientists] now think Y, and the real mechanism is82Z."* The angle must flip the familiar story, not just retell it.83**GATE 2:** an angle with a genuine flip.8485### Phase 3 — SCRIPT (curiosity loop)86Read `references/scriptwriter.md`, then write the narration:87- Default length 28–32s ≈ **75–85 words** (~2.7 words/sec). Scale by the same88 rate if the user asked for another duration.89- 5 beats: **Myth → Twist → Mechanism A → Mechanism B → Kicker.**90- Then run the rewrite pass from scriptwriter.md (cut hedges, concretize91 numbers, kill adjectives that don't render).92Show the script in chat (SCRIPT LOCK) and ask one short approve/tweak93question. This is the last mandatory stop — after approval the run is94hands-off to final video.95**GATE 3:** approved script.9697### Phase 4 — SCENE PLAN (the production plan)98Read `references/scene-planning.md`. Break the script into **blocks of 10s**99(N = ceil(duration/10)). For every block write a timed shot list — Zack pacing100is **6–9 hard cuts per 10s block** (~1.0–1.6s per shot). For each shot:101`[t0–t1] SIZE/ANGLE — subject + action — annotation (if any) — assets used`.102Rules: vary size+angle on every cut; at least one MACRO eye/detail shot per103video; one "gag" beat (vanish-poof, deadpan reveal); annotations per the104green/red grammar; every shot names which character sheets appear.105Also produce the **asset roster**: every character, object, environment that106appears in ≥2 shots, plus damage/wear states (e.g. "wall — intact / cracked /107breached"). Post the plan in chat as a compact table. Do not wait for approval108(the script was the lock) — proceed.109**GATE 4:** every block has timed shots; every shot maps to roster assets.110111### Phase 5 — CHARACTER SHEETS (the consistency backbone)112Read `references/style-3d.md` and take its STYLE FORMULA **byte-identical**113into every prompt in this phase and Phase 6.1141. **Style key** — one `seedream_v5_pro` still (9:16): a representative scene115 in the formula. Keep its job_id as the look anchor.1162. **Asset sheets** — one image per roster entry, in parallel, each with the117 look anchor as `medias` role `image`:118 - people → `aspect_ratio:"2:3"`, full body, neutral flat backdrop, front119 3/4 view, sheet-style;120 - objects/props → `"1:1"`, isolated, no scene;121 - environments → `"9:16"` (target aspect), dressed, no people. **Subject-bleed122 guard (proven bug):** the style key's hero subject WILL leak into location123 plates unless the prompt says `ENVIRONMENT SHEET — EMPTY LOCATION PLATE,124 take only the render style and palette from the reference image, NOT its125 subject` plus an explicit `ABSOLUTELY NO {style-key subject}, NO people,126 NO animals` line. QC every environment plate for the hero subject before127 Phase 6 and regenerate contaminated ones with that wording;128 - damage/wear states → separate sheet derived from the base sheet (pass the129 base sheet job_id as an additional media).1303. Poll all to `completed`. Show the gallery in chat with one line: these are131 the character sheets that keep every scene consistent.132**GATE 5:** every roster entry has a completed sheet. Never enter Phase 6 with133a missing asset — that beat WILL drift.134135### Phase 6 — ANIMATION (one call per block)136For each block submit ONE `gemini_omni` call: `duration:10`,137`resolution:"720p"`, `aspect_ratio:"9:16"`, `medias` = environment →138characters → props (role `image_references`, max ~3 — pick the assets that139block actually shows). The prompt = the block's timed shot list rewritten as140explicit timecoded cuts (template in `references/scene-planning.md` §3),141including annotation directions, camera energy (whip-ins, crash zooms), the142"do NOT talk" line, and the NEGATIVE line. Submit blocks in parallel batches143of ≥3; poll the batch; RETRY LADDER on failures. A `completed` block is FINAL144unless it violates a named QC check (style drift vs sheets, wrong aspect,145collapsed cuts → regenerate once with the cut list emphasized).146Download every block into the sandbox as `zack/blocks/blockNN.mp4`.147**GATE 6:** all N blocks completed + downloaded, no gaps.148149### Phase 7 — VOICE (the user's voice, one continuous narration)150- If the user has provided ~1 min of their voice: create a cloned voice151 (voice-creation tool / `create_voice` flow), then use its element voice_id.152- Else call `list_voices` and let the user pick once (or reuse the voice they153 picked in a previous run — it's in memory/manifest). Record154 `voice_id`+`voice_type`; LOCKED for the channel.155- Generate the FULL script as ONE `seed_audio` take:156 `[confident documentary narrator, deliberate storytelling pace with natural157 beats between sentences, starts speaking immediately] [00:00-00:{len}]158 {full script}` with the locked voice pair. **Pacing note (proven):** with a159 plain "tight pacing" hint the take lands ~10% SHORT of the timecode window;160 the "deliberate storytelling pace" wording hits the target. Check161 `durationSec` on the completed job — aim for N×10 − 1.5s; regenerate with an162 adjusted pacing hint if off by >2s.163- Download to `zack/audio/narration.wav`. In the sandbox run faster-whisper164 word timestamps → `zack/audio/words.json`. Derive the **beat map**: the165 timestamp of every beat keyword (the moments zoom-ins will hit).166- If narration > N×10s: tighten the script line that overflows and regenerate.167 NEVER time-stretch audio.168**GATE 7:** one narration file ≤ N×10s, words.json, beat map.169170### Phase 8 — EDIT (zooms, shakes, final cut)171Read `references/scene-planning.md` §4 (edit grammar). **Order of operations172(proven):** call `media_upload({filename:"final.mp4"})` FIRST to get the173presigned PUT URL and media_id, THEN assemble — so the upload can run inside174the same sandbox call as the render. **Sandbox persistence is not guaranteed175between calls** (files may vanish even back-to-back): the robust default is176ONE foreground `sandbox_exec` call (≤120s) that does everything — write177helper files via quoted heredocs, download blocks + narration with parallel178`curl`, probe fps, extract/concat SFX, concat blocks, apply the edit map,179mix, trim, `curl PUT` to the presigned URL. Use `-preset veryfast -crf 16/17`180to fit the budget (a 3-block short assembles in ~50s). Steps:1811. Concat blocks 1..N (re-encode, uniform fps from probe — never hardcode).1822. Apply the **edit map** with the bundled `scripts/zack_edit.py`, fed by183 `edit_map.json`:184 - `punch` zoom-ins (~1.0→1.08 over ~0.4s) at 3–6 beat-map moments185 (reveals, annotations, kicker);186 - `shake` (±1% crop jitter, ~0.3s) at every block boundary and impact beat.187 In the one-shot path, run `zack_edit.py --print-vf` to emit just the ffmpeg188 `-vf` expression and fold it into the final encode (one pass instead of189 two) — `scripts/assemble_oneshot.sh` is the proven full template.1903. Lay the narration over the composite from t=0 (video SFX ducked to ~0.25×191 under it), `amix ... ,loudnorm=I=-16:TP=-1.5`, trim to narration end + 0.4s.1924. QC probe: 1080×1920, duration ≈ narration+tail, audio present, plays from193 frame 1.1945. Upload with the presigned URL from step 0 (`curl -f -X PUT` in the SAME195 call as assembly), then `media_confirm({type:"video", media_id})` → deliver196 the hosted URL. One file, `final.mp4`. A sandbox path is not a deliverable.197**GATE 8:** exactly one final MP4, delivered as a confirmed hosted URL.198199### After delivery200Offer (one line each, never run unasked): 2K upscale via `upscale_video`;201a YouTube title/description pass; saving the style+voice as the channel202profile for next time.203204## RETRY LADDER (Phase 5/6 failures)2051. Resubmit same prompt (new seed) ×2.2062. Reword: soften violence tokens (battle → clash, blood → dust), remove207 tight-face close-ups of distressed characters, resubmit ×2.2083. Reframe the beat (different shot size / staging).2094. Never drop a block, never leave a gap. After ~8 attempts on one block, stop210 and surface it.211212## FINAL QC CHECKLIST213- [ ] One vertical 1080×1920 MP4, narration synced, no dead air > 1s.214- [ ] Every recurring element visually identical across blocks (sheet-driven).215- [ ] Annotations: green = reveal, red = danger/physics; no on-screen words.216- [ ] ≥1 macro eye/detail shot; ≥1 gag beat; kicker closes the loop.217- [ ] Zoom-ins on reveals; shakes on impacts/boundaries.218- [ ] No brand/IP names; characters never lip-sync.