Pipeline Hub

format-song

Long-form sung cartoon story ad (3-5.5 min), the "accused mom, vindicated" story (Dawn recipe A) sung in the first person by a mom's voice on Suno, animated on cartoon-h3 with the song as the clock. Dawn's best video format.

Lane: cartoon-h3 song · not built yet: 6 (see below) · source: /Users/ayden/.openclaw/workspace/skills/format-song

SKILL.mdbeat-sheet.mdsources.mdEvals (6)Learnings (16)
1. Read first2. When to use / when not3. The format4. Why it sells5. Beat sheet (full rules + word budgets in references/beat-sheet.md)6. Pack spec7. Visual grammar8. Audio9. Production (free until the song spend; every paid step is Fish's)10. Gates & QA checklist (on top of core §4)11. Variants & test plan (one variable per ad set; launch per PB §7 + core §6)12. Failure modes13. Sources

format-song — accused, tested, vindicated (sung)

This skill WRAPS the binding playbook knowledge/ad-formats/song-ad-playbook.md (cited below as PB §n). It does not restate it: it adds the beat sheet with word budgets, the missing storyboard checklist, the variant cells from the 10-06 songs diff, and the code truths a run trips on.

1. Read first

2. When to use / when not

3. The format

4. Why it sells

5. Beat sheet (full rules + word budgets in references/beat-sheet.md)

Budget a ~4:30 song at ~2.0-2.5 sung wps (Suno sings ~1.9-2.6 regardless of the prompt) = 550-630 sung words, the parent's count (PB §2).

# Beat % runtime Words Must contain
1 Accuser hook 0-4 20-25 Accuser's verbatim VOC line (or her stake) in line 1, in action; overlay = this line
2 Her world 4-17 80-100 She is the alarm: knocks, trips, times; generic failed solutions; her own cost (late to work)
3 Chorus 1 17-23 35-45 "The record vs the mornings" hook phrase, plain, repeatable; sung ~1.5 wps
4 Public escalation + witness 23-35 80-90 One new person/room sees the blame (mediator, attendance officer, family dinner); concrete cost
5 Hand-over test 35-45 65-75 "Then you do it" / "let's see"; 2-3 failed mornings fast; accuser reasonable and wrong
6 Low point + reversal 45-52 35-45 "Maybe it's me" alone and still; then the pings/the kid's text that turn it
7 Explainer 52-60 40-50 Credible person INSIDE the story; Fish's root-cause line verbatim; ≤3 lines
8 Discovery 60-70 50-60 FIRST band appearance; she wears it first; touch gets through, silent to everyone else, keeps going until he turns it off
9 Vindication 70-94 100-115 Proof (kid out on time, nobody at the door) → the kid clears her in front of the accuser, arm held OUT → mirrored final chorus
10 CTA / close 94-100 25-30 Close line + "60 nights" sung; end card (optional, --end-card; off by default per Fish 10-06) carries name + offer

6. Pack spec

7. Visual grammar

8. Audio

9. Production (free until the song spend; every paid step is Fish's)

cd ~/.openclaw/workspace; P=output/concept-packs/<slug>.md; S=<slug>; T=output/dawn-iterate-2026-10-04/video
python3 -m scripts.cartoon_h3.song --pack $P --takes 2               # 2 kie tasks = 4 takes, ~12 cr/task (~24 cr) — Fish's go
python3 -m scripts.cartoon_h3.song --pack $P --pick N --head 0.05     # promote the chosen take (free)
python3 -m scripts.cartoon_h3.sheet <out.png> <prompt.txt> <style_anchor.png> [product-cutout-unlit.png]   # ~$0.22 each, Fish's go
A=(${(z)"$(python3 -m scripts.cartoon_h3.packargs $P --storyboard)"}); A=(${(Q)A})
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage storyboard        # free; run §7 checklist on every beat
touch output/cartoon-h3/$S/storyboard.approved                        # Fish only
A=(${(z)"$(python3 -m scripts.cartoon_h3.packargs $P)"}); A=(${(Q)A})   # all refs must exist now (core §5 packargs)
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage canvas --canvas-workers 4                 # paid, ~$0.22/batch
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage gen --prompts-only                        # Fish reads motion prompts
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage gen --spend --backend fal --model h3-max --batches 1   # smoke
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage gen --spend --backend fal --model h3-max --gen-workers 8 --auto-regen 1
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage upscale --hd                                     # paid, ~$2.5/song (fal upscale)
df -h ~ ; REMOTION_CHUNK_FRAMES=1500 python3 -m scripts.cartoon_h3.run "${A[@]}" --stage assemble --hd \
  --caption-mode tiktokbox --title-style dragon --song-end <s> --song-tail <tail = end_card_secs, 3-5>   # + (optional end card) + gemini_qa
python3 $T/tools/onset.py output/cartoon-h3/$S/$S-final-endcard.mp4 8                        # first vocal ≤0.3 s
mkdir -p output/cartoon-h3/$S/postqa; $T/tools/contact.sh output/cartoon-h3/$S/$S-final-endcard.mp4 output/cartoon-h3/$S/postqa/contact 2   # read every page

10. Gates & QA checklist (on top of core §4)

11. Variants & test plan (one variable per ad set; launch per PB §7 + core §6)

Cell The one variable How Status
Next song accuser + verbatim line (MAP §3 queue) new pack from the parent's locked beat sheet default
Re-skin art style python3 -m scripts.cartoon_h3.reskin --from-pack <pack> --style <style> (lane song) or --from-video <final.mp4> --script <lines.txt> --style <style> --slug <new> (exhibit A); Fish re-approves the storyboard built 10-06; exhibit-A clay re-skin pack DRAFT
3 hooks first verse only needs an in-lane base run + a base pack with body_start (none of exhibit A / oneweek / sl0919 is in output/cartoon-h3/; the 10-04 song packs have no body_start), so a paying parent first needs a re-render or the not-built concat step. Built route: python3 -m scripts.cartoon_h3.hooksplice --pack <hookN pack> --base <base run dir> [--take N\|auto] → run.py --song --stage storyboard → hooksplice --copy-body → canvas/gen with --batches <hook batches> → assemble. Hook = its own Suno song in the SAME style string. Ad names <concept>-h<i>-l1; score with python3 -m scripts.cartoon_h3.readout --concept <c> built (9-19 sl0919 h1-h3)
3 hooks via kie replace-section first verse only, same voice/key/tempo ≥10 s window; Suno re-renders ~30-60 s around it, swap the WHOLE song, regenerate only batches inside the window (~$3-5 + ~20 kie cr per hook) Not built yet (needs Fish's go): song.py has no replace-section path; done once by hand 9-26
Short song length: 45-60 s, ~100-140 words, product at ~⅓ TEST cell against the ≥3 min rule (MAP §3); same accuser, style string and art style as the parent; beat sheet in references; ~$8 Fish's go; own floored ad set
Sung chorus on camera 2-4 chorus beats become Mom singing to camera same audio + beats via reskin machinery + vocal stem Fish ruled against it 9-19. Test cell only with his explicit go; not built: no lipsync beat flag, h3.py tells H3 "no lip-sync", run.py's QA prompt asserts nobody mouths words
Motion end card (optional, --end-card; off by default per Fish 10-06) 3D product spin pack end_card_clip: <spin.mp4> (wired) asset missing: only knowledge/brands/dawnbands/product-cutout-unlit.png exists; a spin needs a ~$0.5-1 i2v render, Fish's go
- Hooks for a song: (a) the accuser's line, (b) her stake ("They put my name on a truancy letter."), (c) the test ("I gave him the mornings for one week."). ILLUSTRATIVE.
- Launch: own ad set in Testing, cloned from the parent's, $40/day floor, PDP link everywhere (check_links), meta_preflight, read day 3, verdict day 7 vs the parent CPA; read CPA + lifetime frequency + days live, not CTR alone. Never reduce a song on hook rate / thumbstop / hold: the format filters hard on purpose (davidaistar's mattress song: 25.7 % left at 2 s, 4.4 % at 11 s, ~1 % at 45 s, thumbstop 2.05 %, yet 4.95 ROAS on $2,239 over 2+ months; his number, one ad; starpop ai-song-ads-vs-ai-voiceover-ads). Never pause; reduce. Record project_launch_<date>_<slug>.md.

12. Failure modes

Failure Fix
Splitter writes mouthing / "narrator" / unnamed people / bedside wakes / lit-band poses (100 beats hand-fixed on 10-04) Built 10-06: song rules in storyboard.py _SYS + check_plan.lint_beats(); run python3 -m scripts.cartoon_h3.check_plan --lint output/cartoon-h3/<slug> --pack output/concept-packs/<slug>.md (exit 1 on BLOCK) then the §7 checklist by eye
[SPEAKER] tags in a song pack → "mouth moving" panels narrator-only lines; never tag speakers
--no-llm panels say "while the narrator says" don't use --no-llm in songs, or scrub "narrator" in plan.json
Band lit like a smartwatch (10 clips on 10-04) pose, not wording: wrists down, arm out, presses off-wrist, daylight; else deglint
Suno flips a short line / drops a word / sings male / pauses 3-7 s more takes; pick the right one; rewrite 2-word lines ("It was true."); kie separate-vocals stem splice for one word (9-26)
Hook takes via hooksplice start ~0.6 s in (HEAD = 0.60 constant) accept and note, or change the constant with Fish's go
Changed vo.mp3 / edited pack intents → stale song_clock move plan/state/canvases aside; edit plan.json beats instead
Remotion ENOSPC on a 4-5 min HD render df first, REMOTION_CHUNK_FRAMES=1500, one assemble at a time
Post-assemble patches (sign paint-out, logo blur) lost on re-assemble re-apply from the run log; patch the -final-endcard.mp4 master only
Two near-identical consecutive shots stacked into a split frame distinct framings; free crop+scale for that window
lyric_check.py / postqa.py only resolve dawnbands-song-<slug>-2026-10-04 use song.py's receipt check + onset.py + contact.sh + gemini_qa standalone
Cost under-reported price-table caveat in §9

13. Sources

knowledge/ad-formats/song-ad-playbook.md; _FORMAT-CORE.md; ~/research/davidaistar/REPORT.md, analysis/diff_songs.md (rows 3-25, top 5), analysis/gemini_8NzJJ3e7uZ4.md, analysis/gemini_PmXqgiFn9_Y.md, foreplay/12_musical.gemini.md, foreplay/13_suno.gemini.md; output/dawn-combo-map-2026-10-05/MAP.md; output/dawn-iterate-2026-10-04/video/RUN-LOG.md + song-voice-refs.md; scripts/cartoon_h3/{song,run,storyboard,check_plan,endcard,reskin,hooksplice,h3}.py; skills/cartoon-h3/SKILL.md; memory project_song_lane_2026-09-19.md, reference_kie_ai_suno.md.

Not built yet (needs Fish's go)

Every line in this skill that mentions something not built, roughly de-duplicated. Some items repeat in different words.