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
knowledge/ad-formats/_FORMAT-CORE.md(doctrine, lane limits, gates, launch). Binding.knowledge/ad-formats/song-ad-playbook.mdin full (PB §1 concept, §2 lyric red-team, §3 Suno, §4 art styles, §5 scene types, §6 production, §7 launch). Binding.references/beat-sheet.md(skeleton, % + word budgets, line rules, short-song cell),references/sources.md(reference ads, diff rows, receipts).output/dawn-combo-map-2026-10-05/MAP.md§2A (what wins) + §3 (the accuser queue) and the stake bank it points to.- Song copy doctrine:
~/.hermes/skills/openclaw-imports/direct-response-copywriter/references/song-dr-ballad-scripting.md; Evolve rules per core §1. - Voice:
output/dawn-iterate-2026-10-04/video/song-voice-refs.md(style strings A/B + negatives). Last run:output/dawn-iterate-2026-10-04/video/RUN-LOG.md. - Product:
knowledge/brands/dawnbands/product-truth.md.
2. When to use / when not
- Use for every new Dawn song: iterate a paying song's LOCKED beat sheet and change ONE thing (PB §1), normally the accuser + the verbatim line, taken in MAP §3 order: school accuses her (truancy letter) → CPS / school social worker → her own kid ("scared of me in the mornings") → her boss.
- Evidence status: signal, not proof. Exhibit A (sa-ontime-10-exhibita-a) $33.7 CPA, ROAS 2.48 on $292; oneweek (sa-ontime-04-oneweek-a) ROAS 1.81 on $1,106; sl0919-h2 $40 CPA at 2:40. Every song number sits on <$1.2K spend. Songs: CPM $49-68, CTR 3.8-4.7 %, frequency builds ~half as fast per $ as statics (MAP §4).
- Don't use for callout/brand-voice angles (recipe B → statics/natives), a brand-voice or character-rap song (SLOP SONG GOAT 0.72), a song with no accuser on mom (the-shirt, drain-mom/dad: 0 purchases), kid-money/college stakes (0.40, 0.58), stakes the mornings didn't cause, or another dad-POV song before the existing one reads. To test song vs story, use
format-spoken-drama. - Husband/MIL songs already exist (five mornings, in my day, always nagging, dad-POV another week) and were never read: the cheapest next read is their own floored ad sets (Meta write, Fish's go), not a new build (MAP §3.5).
3. The format
- 9:16, 3:00-5:30 sung (10-04 promoted songs 336.7 / 228.5 / 262.8 s, finals after
--song-end329.3 / 226.6 / 250.8 s; exhibit A 271.5 s). One art style per song (disney3d, skeleton, claymation, pixar, paper), anchored on a real winner frame (PB §4). - The viewer hears ONE continuous song: a mom 35-54 singing her own story, first person, talk-sung verses + plain belted chorus. Nobody on screen sings (Fish 9-19). The picture shows, literally, what each line says.
- Hook header on frame 0 (
--title-style dragon, held for the first sentence ≥4 s), first sung word ≤0.3 s, captions = typed lyric lines on the sung timings, motion end card (optional,--end-card; off by default per Fish 10-06) over the last 3 s. - Reference shapes: our exhibit A (structure LOCKED); Foreplay
12_musical(Resilia, 7:25 narrative VSL: mentor + mechanism + revenge) and13_suno(Smooche, 5:37 Pixar musical: humiliation → discovery → the rival asks her secret).
4. Why it sells
- Recipe A (MAP §2A): someone close blames HER for the mornings → resentment/humiliation → a witness makes it public → she hands the mornings over and he fails → a credible person inside the story names the root cause → discovery → vindication in front of the accuser. The band is the evidence that clears her, not a pitch.
- Problem-aware: line 1 is the accuser's verbatim line or her stake, in action. The song carries ~4 min of attention at half the frequency build, so one concept lasts longer per dollar (theory, unproven past ~$550/week).
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
-
Step 0 — combo plan (feedback loop,
workflow-combo-loop):python3 scripts/combo_loop/plan.py --format format-song --brand dawn→ pick one combo (a paying parent + ONE changed dimension) and paste its block into the pack front matter / job or spec JSON ("combo": {...}; no file →tags.py register --prefix):combo_avatarcombo_anglecombo_povcombo_authoritycombo_stakecombo_stake_oncombo_emotioncombo_root_causecombo_mechanismcombo_payoffcombo_devicecombo_formatcombo_parentcombo_variablecombo_ad_prefix(= the launched Meta ad-name prefix).python3 scripts/combo_loop/tags.py check <pack>must PASS before concept approval; the weekly refresh reads results back by that prefix. -
Front matter (core §5 + song keys; model on
output/concept-packs/dawnbands-song-nottardy-2026-10-04.md):format: cartoon-h3,format_skill: format-song,brand: dawnbands,parent:(paying song + length/words + CPA),iteration:(the ONE variable),title:(header,|= line break),overlay:,end_card: Dawn Band. It wakes him, not you. 60 nights to try it., optionalend_card_secs/end_card_clip/end_card_product,style+style_key(arun.py --stylechoice: claymation, pixar, disney3d, skeleton, paper, bergamot, bluey),style_block,visual_negative,style_anchor,audio: song (kie.ai Suno),suno_model: V5,suno_style,suno_negative_tags,suno_vocal_gender: f,cast,envs,product_truth. New slug per run. - Lyrics:
## Suno lyrics prompt (custom mode)fenced block (song.py's exact regex) with[Verse N]/[Chorus]/[Bridge]/[Outro]tags only; no[Spoken]tags (PB §3). ## VO Script:N. "lyric line"one sung line per pack line, identical to the lyric block, 5-9 words, numbers spelled out. No[SPEAKER]tags in song packs: a song is one sung voice; tags would split it into dialogue lines. (The splitter's old "mouth moving" speaker rule was removed 10-06; tagged lines are now staged as voice-over.)## Scene visual intents:N. **narrator** — <env>: <named people, doing what, framing>; product lines**narrator (product reveal)**or**cta**(batch ≤3 panels). Every person by name or sheet label; side characters "(not Mom)".<slug>.argsbeside the pack:--char-ref "Label=path",--env name=path,--product-ref,--characters "..."(read bypackargs.py).- Cast: Mom (avatar: ordinary American mom 35-54) + accuser + explainer + kid (+ witness). Check the cast against the avatar before sheets (PB §4: reused sheets carry their old look). Envs: 6-8 rooms (PB §5).
7. Visual grammar
- Shot types per beat: PB §5 table (accusation two-shot, evidence insert, wide wake routine, her cost, witness room, low-point close-up, reversal pings, authority two-shot, discovery, proof, vindication, quiet payoff). ~55 % wide / 35 % close / 10 % medium; 85-98 beats; ≤4 panels per batch.
- Song storyboard gate. Since 10-06 the splitter (
storyboard.py_SYS) carries these rules andpython3 -m scripts.cartoon_h3.check_plan --lint output/cartoon-h3/<slug> --pack output/concept-packs/<slug>.mdchecks every beat (mouthing/sings/mid-sentence, speech verbs, "narrator", lit/glowing band, smartwatch not in the intent, raised/looked-at/pressed wrist, product before the first reveal/cta beat, readable text/clock numerals, bedside wakes, beats <1.2 s; exit 1 on any BLOCK; unnamed people / non-wide wakes = WARN). Lint to 0 BLOCK, then read EVERY beat against the lyric for what a regex can't see, beforestoryboard.approved: - [ ] No mouthing: no "mouth moving", "mid-sentence", "sings", "speaks", "says to camera". Yells/shouts as actions are fine.
- [ ] Every person named (Mom, Caleb, the attendance officer) so the hero sheet attaches; never "a woman", "a mother", "relatives", "the narrator", "blurred figures". Side characters carry "(not Mom)" / "(not Caleb)".
- [ ] Wake shots: WIDE from the doorway, teen fully dressed ON TOP of the duvet, adult at the light switch/blinds; never an adult at the bedside, never a teen under covers, no shower (closed door + steam).
- [ ] Wrist rule: wrists down or resting, band side-on, nobody looking at the wrist; "held up" = arm extended toward people at chest height; presses on the band happen with the band lying on a nightstand; product beats in daylight.
- [ ] No product before the discovery verse (first band beat = beat 8; no band on anyone's wrist earlier).
- [ ] No readable text: papers = yellow stripes, phones/laptops turned away (glow only), clocks hands-only, signs blank, no logos.
- [ ] No split screens / phone-call split frames; two consecutive near-identical shots get different framings (H3 stacks them).
- [ ] Similar-age characters in different batches or visually distinct (hair, colour, build).
- [ ] Buzz shown as eyes opening + cartoon alarm lines; never "vibrates / strong pulse / twitch / jiggles" next to a teen in bed (fal content-policy reject).
- [ ] Real-life plausibility per PB §2 (shift times, who can see what, a mediator doesn't "order" custody).
- [ ] Frame 0 states HER, not the room: beat 1's first panel = Mom + the stake object (the letter, the exhibit) in readable light, a thumbnail that names the persona; never a dark establishing bedroom. The dragon header sits over her face, not over an object or empty set (davidaistar's own mattress song opened on a dark bedroom: 2.05 % thumbstop, his #1 fix; starpop
ai-singing-ad-mattress-case-study,how-to-edit-ai-song-ads-capcut). - Edit beats in
plan.json(keep a.bak), not the pack intents: editing pack visuals after the song is promoted breakssong_clock.
8. Audio
- Engine: Suno V5 on kie via
song.py(PB §3). fal MiniMax Music / ElevenLabs Music are banned for this (wrong genre, word swaps, dropped lines). - Style string rules: the voice is the avatar (Nashville country-pop storyteller woman 35-50, warm slightly husky chest voice, light twang, talk-sung verses, plain belted chorus, tail vibrato, no runs); each song gets its OWN string (genre/BPM/instrument differ: e.g. piano ballad 72 / acoustic pop-folk 96 / heartland country-rock 84); always "clear diction, every word easy to understand, vocals up front, dry clean mix"; ≤400 chars. Negatives always include
R&B, trap, rap, breathy, whisper, heavy reverb, male vocal, choir, autotune, spoken word, mumbling, long intro(fuller list in song-voice-refs.md). No blank-line gaps or "beat switch" wording (Suno inserts 3-7 s pauses). - Take check, then pick:
song.pyscores every take on arrival (output/cartoon-h3/<slug>/song/receipt.json:lyric_checkPASS/REVIEW/FAIL, wps,first_word_s, missing/garbled/review lines). Then: listen at every flagged line (Scribe writes "6:30" for "six-thirty"; not an error); check short lines (≤4 words) word by word, since Suno flips "It was" → "It wasn't"; Gemini audio check (female lead, mom 35-54, clarity 1-10, sung not spoken); throw out male takes; measure gaps >1 s intake-N-words.json. Fix a misspelled brand/name intake-N-words.jsonBEFORE--pick. - Promote:
song.py --pick N --head 0.05(trim keyed on the first LYRIC line, not the first ad-lib) → first sung word ≤0.3 s. - End = the instrumental tail, kept: never hard-cut the resolution. Pick
--song-end <s>at the musical resolution (Suno leaves 6-11 s of outro) so 3-5 s of instrumental follow the last sung word, then set--song-tail= packend_card_secs= that tail (≥3.0): the motion end card (optional,--end-card; off by default per Fish 10-06) fills the whole resolving instrumental and the captions end before it (run.py warns if tail < card). Source: starpophow-to-make-ai-singing-ads-minimax-h3,how-to-edit-ai-song-ads-capcut(the tail is free attention at the moment the song resolves). - No music bed, no SFX: the song is the full mix (
run.py --song).
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
- Shot tiers (core §2b) + draft→final (core §4 gate 6b). Tag every batch A/B/C before approval: run.py does it itself (
scripts/cartoon_h3/tiers.py, alsopython3 -m scripts.cartoon_h3.tiers <run>: A = first batch/hook, reveal/CTA/product beats, 3+ characters in a shot; C = no person in any shot; else B) intoplan.json+<run>/tiers.mdwith the per-batch fal cost; re-tag in review if the word match is wrong. Per-tier models:run.py --tier-models "A=h3-max,B=h3-max,C=h3"(fal only; default =--modelfor every tier, i.e. all H3-max).h3on B/C is a candidate until a one-batch side-by-side passes Fish's eye (registry "How to adopt"). Draft→final:run.py --draft= 480P ($0.05/s vs $0.08/s at 768P, fal page re-read 10-06) into<slug>-draft, seeded from the approved run (VO, plan, approval, canvases), never the shared-body cache, no upscale/end card (optional,--end-card; off by default per Fish 10-06); it prints the native 768P re-render command for the approved batches. Finals re-render natively, never a 480P→--hdupscale (Fish judged native sharper 10-04). A re-render is a new sample: judge staging and prompts on the draft, not the exact take. - Never run
songkie.sh/songfull.sh/songfix.sh/hookrun.shfor a Dawn song: they pass--yes, force--style disney3d,songkie.sh/songfull.shauto-touchstoryboard.approved, andsongfull.sh/hookrun.shhard-code the 9-19 cast. - Lit band in a clip: pose fix + canvas re-render +
--regen Nfirst; free repaint after:python3 $T/tools/deglint.py <clip> <t0> <t1> <x0> <y0> <x1> <y1> [--hue=..] [--largest](fails on skeleton bone). Sweep every product clip at 1 fps by eye. - Cost per ~4-5 min song (PB §6): ~$31-43 on fal (H3 ~$22-30 at h3-max 768P $0.08/s + ~$0.10-0.16 reference surcharge per batch: nottardy's 24 batches quote $24.73 in
tiers.md; canvases $6-10, upscale ~$2.5) + ~$8 sheets + ~24-72 kie credits. Ledger caveat: h3.pyFAL_PRICEwas fixed 10-06 from the fal page (it billed 768P at the 480P rate), so 10-04 ledger H3 numbers understate ~1.6×;run.py --dry-runquotes per batch. Regen budget 8 per song. Check kie/fal/Higgsfield balances before promising a render.
10. Gates & QA checklist (on top of core §4)
- [ ] Parent named with CPA + length/words; ONE variable stated; accuser line from raw VOC/stake bank (cited); mornings caused it; stake lands on her.
- [ ] Beat sheet filled within the word budget (550-630 long; 100-140 short cell); explainer is a person in the story; Fish's root-cause/mechanism lines verbatim.
- [ ] Logic pass → Opus red-team → fix → re-check the fixes (PB §2); Fish approves the lyrics.
- [ ] Own style string, distinct from the last 3 songs; negatives present;
suno_vocal_gender: f. - [ ] Takes: receipt
lyric_checkPASS (or REVIEW lines listened to), short lines exact, female mom voice, gaps <1 s, Fish listened to the pick. - [ ]
--pick N --head 0.05; first lyric ≤0.3 s. - [ ] Cast checked against the avatar; sheets montage-reviewed (empty rooms, dark band, right outfits).
- [ ] §7 storyboard checklist passed on every beat; Fish touched
storyboard.approved. - [ ] Canvas montage eyeballed; motion prompts read (
--prompts-only): no lit-digit, mouthing, "narrator" or "storyboard" wording. - [ ] Smoke batch passed before the wave; balances checked; regen tally ≤8.
- [ ] Every batch tagged tier A/B/C in
storyboard.md; any draft→final pass followed §9's route (drafts never left in a shared-body cache). - [ ] 1 fps lit-band sweep of every product clip; seam/split-screen check.
- [ ] Final: first vocal ≤0.3 s (onset.py), header on frame 0 over Mom (§7), captions = lyric lines, end card (optional,
--end-card; off by default per Fish 10-06) over the whole 3-5 s instrumental tail with captions finished, contact sheet every 2 s read in full, gemini_qa scored (if the in-assemble call returns no score, runscripts/gemini_qa.py --asset <final> --type finalstandalone and read its flags). - [ ] Caption safe zone: moved 10-06 (Fish approved "Move up to ≤62%"): tiktokbox and dragon blocks end at 64 % of the frame (centre ~62 %), tiktok centres at 59 %, all as a % of the height so 720 and 1080 renders match; the dragon header is moved from 8 % to 15 % at assemble (
assemble.title_safe_zone). Finals assembled before 10-06 keep 68/74 % (re-assemble to move them; local, $0). Still view one final in Ads Manager's Reels placement preview before launch.
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)
- 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'
- 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 li
- 25 (P0) Splitter _SYS has none of the song rules; check_plan.py checks only timing/caps; ~100 beats hand-fixed, ~11 lit-band regens on 10-04 SKILL §7 manual checklist; §12 "not built" line
- 21 (P1) One hook per $26-33 song SKILL §11: hooksplice (built) + replace-section (not built)
- 15 (P1, Fish call) On-camera sung chorus untested; overrides 9-19 ruling SKILL §11 test cell, needs Fish's go, not built
- 14, 17, 10, 11 (P2) Song-aware H3 prompt, ≥0.95 slow-down, beat-grid snapping, "no extra in-between panel" canvas line not built; out of scope for a format skill (code changes, Fish's go)