format-courtroom: accused, cross-examined, cleared
1. Read first
knowledge/ad-formats/_FORMAT-CORE.md(doctrine, lane limits, gates, launch). Binding.references/beat-sheet.md(skeleton, turn-taking rules, per-setting realism detail),references/sources.md(reference ads, receipts).output/dawn-combo-map-2026-10-05/MAP.md§2A (device row: exhibit 2.48 vs experiment 1.67) and the stake bankoutput/creative-strategy-cooper-2026-10-05/dawn-stakes.md(Legal #6 truancy letter, #7 CPS; School #3 truancy count).knowledge/ad-formats/song-ad-playbook.md§1-2 (concept + red-team method; real-life test: "a mediator doesn't order custody").- Parent ad:
output/concept-packs/dawnbands-song-reskin-exhibita-clay-2026-10-06.md(exhibit A lyrics, cast, rooms). Dialogue pack conventions:output/concept-packs/dawnbands-s2-attendance-office-h1-2026-10-01.md. skills/format-spoken-drama/SKILL.md: sibling format. Spoken drama is told in hindsight by a narrator; courtroom plays the hearing as it happens. Don't run both against exhibit A in the same week (§11).
2. When to use / when not
- Use to push our best-paying device (courtroom/exhibit: exhibit A song ROAS 2.48, $292, $33.7 CPA) into a format where the argument IS the ad. Also use it to test whether short, live, back-and-forth turns hold attention as well as a sung story does.
- Evidence status: untested on Dawn. Signal only: the exhibit device is 1 song at $292 (MAP.md calls songs "signals, not proof"); Foreplay #10 (Penrose, 62 s 3D debate) is scaling for another brand; REPORT.md §4 ranks this #4 to test.
- Don't use for recipe-B callouts (brand voice, her burden), for stakes the mornings didn't cause (affairs, CPS lines with no morning tie: stake bank "Left out"), for a jury or criminal trial of the kid, or with a real judge, school or court name.
3. The format
- 9:16, 60-150 s (long cut 90-150 s; short cut 60 s). Animated, one style per ad: disney3d by default (exhibit A's style), claymation via re-skin. Anchor =
output/dawn-iterate-2026-10-04/video/style-refs/<style>/anchor.png. - The hearing is the frame. Every scene starts and ends in the hearing room. Mornings, the test week and the explainer's office appear as cutaway inserts under testimony ("show the thing the line is about").
- Voices: MOM (defendant/respondent, carries ~45-55% of words), ACCUSER (ex/husband, or the school's attendance officer), AUTHORITY (judge / mediator / panel chair), EXPLAINER (pediatrician, school nurse), optional KID (one line at the ruling). Max 5 speakers.
- Short cut "objects argue" (30-45 s): Phone Alarm accuses Mom in a tiny desk-top court; a Wall Clock (hands only) presides; the band is the silent exhibit and speaks last, low and calm. Same recipe A, compressed.
- Captions from the script on every word; hook on frame 0 via pack
title:; motion end card (optional,--end-card; off by default per Fish 10-06) viaend_card:. - Reference shapes: Foreplay
10_character_arguments(Penrose: two characters trade jabs, a third party weighs in, mechanism is a line of argument, the product character wins);04_drama(Koriderm: a dispute in front of an official, settled by the product).
4. Why it sells
- Recipe A, staged as a dispute: the stake is ON HER and formal (her parenting, custody or a court referral is on the record) → humiliation ("every true thing sounds like an excuse") → the explainer gives the root cause under oath / to the panel → the band is the evidence that clears her → vindication spoken by the authority or the accuser.
- Objections and interruptions are hooks: every 10-15 s someone cuts her off. Each cut-off reopens the loop (will she get to finish?) and restarts attention without new setup.
- Exhibits replace exposition. The tardies printout says "she's failing" without a sentence of backstory; the accuser's own week on the printout says "it was never her" without a speech.
- Problem-aware: the first two lines name her by an observable symptom (tardies, the fifth knock, "she can't get him up") inside the accusation.
5. Beat sheet (full rules + timings in references/beat-sheet.md)
| Beat | % runtime | Job | Must contain |
|---|---|---|---|
| 1 Charge (hook) | 0-8 | Stop the scroll on her | Accuser's claim, an objection cutting her off, or the stake, in the room; symptom in lines 1-2 |
| 2 Exhibit A, the record | 8-20 | The stake has paper | The tardies printout introduced; her side as cutaway inserts (knocks, trips, the bus) |
| 3 Cross / pressure | 20-35 | Humiliation | 3-6 short turns; "Is this accurate?" / "It is."; she gets cut off at least once |
| 4 The test record | 35-50 | Turn | The accuser's own mornings (his week / the trial period) on the record: late, absent, late. Long cut only |
| 5 Expert witness | 50-65 | Root cause | Explainer, a person inside the story, ≤3 lines; Fish's ruled root-cause line verbatim |
| 6 Deciding exhibit | 65-80 | Mechanism + product | Touch gets through; silent to everyone else; keeps going until he turns it off. Product named once here |
| 7 Ruling | 80-94 | Vindication on HER | A ruling the authority can actually give (§6 realism) + the accuser's or kid's line; her one-line reaction last |
| 8 CTA | 94-100 | Offer | Spoken product name + 60-night trial; end card (optional, --end-card; off by default per Fish 10-06) |
| 60 s cut: beats 1, 2+3 merged, 5, 6, 7, 8 (skip 4). Objects cut: 1, 3, 5+6 merged (the band testifies), 7, 8. |
6. Pack spec
-
Step 0 — combo plan (feedback loop,
workflow-combo-loop):python3 scripts/combo_loop/plan.py --format format-courtroom --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:
format: cartoon-h3,format_skill: format-courtroom,brand: dawnbands,created,status,parent:(exhibit Asa-ontime-10-exhibita-a, ROAS 2.48, $33.7 CPA, or the format-spoken-drama cut if it has read),iteration:(the ONE variable),title:(frame-0 hook,|between lines; the code readstitle:,overlay:is a record only),end_card:,style:,cast:,envs:,product_truth:,visual_negative:,voices:, pace keysvo_tempo: 1.08,max_gap: 0.22,gap_same: 0.15,gap_turn: 0.3,seam_gap: 0.25, optionalhook_tempo: 0.85,style_<SPK>: 0.2-0.35(heat on the accuser),body_start:for 3 hooks. Addsetting: court|mediation|attendanceas a record. Copyproduct_truthfromoutput/concept-packs/dawnbands-song-nottardy-2026-10-04.md(display OFF and dark in every shot), never from the 10-01 attendance-office packs ("top face that can glow"). - Carry
style_key,style_block,style_anchorin front matter (core §5) and build every run's args withpython3 -m scripts.cartoon_h3.packargs. run.py was fixed 10-06 (L168): onlystyle_<SPEAKER>/tempo_<SPEAKER>keys for speakers invoices:are read as voice settings, sostyle_keyno longer crashes the VO stage. A non-numericstyle_<SPEAKER>still raisesValueError. - Voices: MOM =
mtV3PLomLvma8XKmZIju(the lane voice, MOM in the 10-01 packs). A 50s woman (mediator/nurse) can reuseBeydSYsiEvkOxDwdvf89(the 10-01 CLERK), and only one speaker per voice. No male voice id is on file: audition ACCUSER/JUDGE in ElevenLabs, Fish picks, write the id intovoices:. Speaker tags match[A-Z0-9_]+(pack.py):MOM,EX,JUDGE,MEDIATOR,NURSE,DOCTOR,OFFICER,NOAH. ## VO Script:N. [SPK] "line", every line tagged. Turns ≤8 words (objection lines included); MOM testimony ≤12; no pack line under ~4 words / 1.2 s. A bare "Objection." becomes "Objection. Relevance, Your Honor." (storyboard.pymerges short sentences only inside one pack line, so a one-word line becomes its own sub-second panel).## Scene visual intents:N. **SPK (role)** — <env>: <shot>. Every non-narration line says WHO IS ON SCREEN and that the speaker's mouth is not visible (§7). Product roles:(product reveal),(product),(cta). Before beat 6 never write "the band", "wristband", "black band" in an intent:pack.pyflags them as product-visible.- Cast: Mom + accuser + authority + explainer (+ kid). Make same-age adults distinct (hair colour, build, clothes): Mom and the ex's lawyer/mediator are the risk pair. Reuse exhibit A sheets where the style matches;
output/cartoon-h3/_refs/dawn-songs-2026-10-04/clay/already has char-mom, char-dad, char-officer, env-attendance-office, product-band. - Envs (4-6): the hearing room (courtroom / mediation room / school conference room), teen room, hallway/stairs, kitchen, explainer's office, bus stop or school gate.
Process realism (red-team every script against this table)
| Setting | Who decides | Who speaks | Real | Never |
|---|---|---|---|---|
| Family court (custody modification / temporary orders) | Judge alone (bench; no jury) | Attorneys question sworn witnesses; judge rules on objections ("Sustained." / "Overruled.") | School records admitted as numbered or lettered exhibits; a pediatrician can testify as an expert, a school nurse to what she saw; judge rules from the bench on the school-week schedule or takes it under advisement; a teen's view comes via an interview in chambers, not the stand | Jury, "guilty", gavel-bang verdicts, cross-examining the kid in open court, the judge "sentencing" Mom |
| Custody mediation | Nobody: the mediator is neutral and decides nothing | Parents talk in turn (lawyers sometimes); the mediator asks questions | A printout slid across the table; "Is this accurate?"; a trial period both agree to ("two weeks, then we meet again"); in some counties the mediator writes a recommendation to the judge; the mediator may meet the teen alone and report his words | "Objection", "Your Honor", exhibits admitted, the mediator "ordering"/"granting" custody (10-04 red-team catch) |
| School attendance hearing (attendance review board / truancy meeting) | A panel of school staff | Panel chair (attendance officer / assistant principal), counselor or nurse, parent, student | The attendance record on the table; outcome = an attendance agreement, services, or referral to court or the DA (in many states the parent can then be cited or fined: the stake on her); the school nurse can sit on the panel, so the explainer is legitimately in the room | The panel fining or jailing anyone, a judge, objections, "exhibits" |
| Default setting = attendance hearing for new stakes (stake bank #6 truancy letter in her name is the top "test first" row, the explainer belongs in the room). Mediation for the exhibit-A test (parent's setting). Court only when the objection hook is the variable. |
7. Visual grammar
- No lip-sync (core §3). A spoken line is staged as: the LISTENER's reaction (Mom's face as the accuser speaks), the speaker from behind or in profile in a wide, an over-the-shoulder on the listener, the judge/panel seen from the back of the room, or a cutaway insert of what the line is about. Never a close-up of a speaker on their own line. Write it into the intent: "speaker seen from behind, mouth not visible".
- Speaker staging (fixed 10-06): the splitter (
storyboard.py_SYS) now stages a tagged speaker's line as voice-over (listener, back/profile wide, over-the-shoulder, phone/door, insert), never mouthed. Still open every non-MOM intent withCutaway:orListener shot:(intents are used verbatim with--no-llm), then runpython3 -m scripts.cartoon_h3.check_plan --lint output/cartoon-h3/<slug> --pack output/concept-packs/<slug>.mdand re-intent every BLOCK before approving. (--no-llmuses intents verbatim but sets every panel's env to null; check room sheets still attach.) - Objection/interruption beats: wide two-shot from behind the accuser's shoulder, Mom mid-gesture, stopped. Rulings: wide from the back of the room, the authority small and far, Mom's back in foreground.
- Exhibits, no readable text: the attendance record = rows of grey lines with red or yellow highlighted rows, no numbers; exhibit stickers = a plain coloured tag, no letter (the "A" is spoken and captioned, never printed); nameplates and seals blank; phones turned away; clocks with hands and no numerals.
- Band reveal as an exhibit (wrist rule): first appearance in beat 6, either lying flat on the table on a plain cloth (top-down, display dark) or on the kid's forearm resting on the table edge / arm held OUT toward the panel at chest height, band side-on, nobody looking at it. The buzz is shown in a home cutaway: the kid's eyes open, small motion lines at the wrist resting on the pillow. Never a raised wrist, a pressed button, a lit face or a night close-up.
- Objects cut: the Phone Alarm "speaks" by ringing and buzzing on the desk with plain glowing bars on its screen; the Wall Clock judge has hands, no numerals, no face; the band's display stays dark, so it shows its voice by small motion lines, never a lit face. No mouths needed, so the no-lip-sync limit doesn't apply.
8. Audio
- ElevenLabs per speaker via
voices:. Mom: warm, tired, never shrill. Accuser: calm and reasonable, wrong. Authority: flat, procedural. Explainer: calm, certain. Kid: flat teen, one line. - Pace: dialogue overall ≥2.9 wps, any line of 6+ words ≤4.8 wps, turn gaps 0.30-0.55 s (vo_check DIALOGUE profile). Fix by splitting or re-taking, never by speeding.
- Room tone only under the hearing; one ducked bed (assemble default). No gavel SFX. One buzz SFX in the home cutaway is allowed if it masks no word.
- End card (optional,
--end-card; off by default per Fish 10-06) 3 s (end_card:;end_card_secsdefaults to 3.0).
9. Production (free until §10 refs gate)
P=output/concept-packs/<slug>.md; S=<slug> # <slug>.args: --char-ref Mom=<png> ... --env hearing-room=<png> ... --characters "Mom, Greg, Ms. Reyes and Noah"
R(){ A=(${(z)"$(python3 -m scripts.cartoon_h3.packargs $P $1)"}); A=(${(Q)A}); } # R --storyboard before sheets exist; R after
python3 scripts/statics/voc_check.py "<accuser line>" "<stake phrase>" # 0 hits = our phrase, not hers
python3 -m scripts.cartoon_h3.pack $P # free parse: speakers, product flags, word counts
R --storyboard; python3 -m scripts.cartoon_h3.run "${A[@]}" --stage vo # EL per speaker + vo_check gate (EL quota)
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage storyboard # free; grep for mouths (§7); Fish reviews
python3 -m scripts.cartoon_h3.sheet <out.png> <prompt.txt> <anchor.png> [refs] # new cast/room sheets, PAID ~$0.15-0.30, after Fish's go
touch output/cartoon-h3/$S/storyboard.approved # Fish only
R; python3 -m scripts.cartoon_h3.run "${A[@]}" --stage canvas # paid, ~$0.22/batch (every ref must exist)
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage gen --prompts-only # Fish reviews motion prompts
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage gen --spend --backend fal --model h3-max --batches 1 # smoke, then the wave
python3 -m scripts.cartoon_h3.run "${A[@]}" --stage assemble # + end card (optional, `--end-card`; off by default per Fish 10-06) (pack end_card:) + gemini_qa
- Cost: a 2:00 hearing ≈ 9-12 H3 batches. Read the fal pricing page before quoting (cartoon-h3 table and song playbook disagree: $0.08/s vs $0.05/s). Budget ~$8-15 video + ~$2-3 canvases + ~$0.2 per new sheet + EL quota; 60 s cut about half. Objects cut: 3 new sheets (phone, wall clock, desk court) + the existing product sheet.
- Hooks: 3 hooks × 1 shared body (
body_start); run h1 to completion before h2/h3 (shared-cache race). - 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. - Kling route for the objects cut (only on Fish's go): cartoon-pipeline
villain_parade(skills/cartoon-pipeline/SKILL.md): Kling 3.0 via Higgsfield, native dialogue with mouths (use_elevenlabs_vo=False), voice vibe written inline in the motion prompt, one speaker per scene, ≤2.8 wps plus one duration bucket + 0.5 s tail (cp-014), first lines on the "I'm [name], the [what I do]" template,bergamotstyle, character ref with villain + hero together. Entry:python3 scripts/cartoon_lint.py <pack>→python3 scripts/cartoon_runner.py --profile profiles/dawnbands.toml --concept-pack <pack> --dry-run→--execute --stage A/B/C. Its pack format is the cartoon-pipeline schema (references/schemas.md), not this one. Check Higgsfield auth + balance first, and smoke 1 scene: a band character with a face risks a lit "screen".
10. Gates & QA checklist (on top of core §4)
- [ ] Parent named with CPA; ONE variable stated; setting picked from §6.
- [ ] Accuser line + stake from VOC / stake bank (voc_check hit or bank id cited); the mornings caused it; it lands on her.
- [ ] Realism pass against the §6 table: right authority, right words ("Sustained" only in court), an outcome that authority can actually give, timeline math.
- [ ] Opus red-team done (song-ad-playbook §2) and fixes re-checked.
- [ ] Turns ≤8 words; no line <~4 words; she's cut off ≥1 time per 30 s in beats 1-3.
- [ ] Every non-MOM intent opens with
Cutaway:/Listener shot:; storyboard grep for mouth/speaking/talking/narrator = 0 hits. - [ ] No product words before beat 6; wrist rule in every product intent; exhibits have no letters or numbers.
- [ ] Args built with packargs (style keys + anchor in front matter, refs in
<slug>.args); vo_check PASS; Fish listened. - [ ] 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). - [ ] Storyboard approved; motion prompts reviewed; fal/Higgsfield/kie balances checked before
--spend. - [ ] Placement preview (starpop facebook-instagram-ad-sizes-and-safe-zones, how-to-preview-a-facebook-ad-before-publishing): scrub to the hook frame, the reveal frame and the end card (optional,
--end-card; off by default per Fish 10-06) on a 9:16 overlay; header, captions, product and offer sit inside Meta Reels' safe box (top 14 %, bottom 35 %, sides 6 % are UI = keep content in y 14-65 %) and survive the Feed 4:5 centre crop (~15 % lost top and bottom). Remotiontiktok/tiktokbox/dragoncaptions centre at ~68-74 % = inside the Reels bottom band on Meta: flag it to Fish, never re-burn on your own. - [ ] Final: freezes 0, dark 0, captions from script, end card only if
--end-cardwas asked (off by default, Fish 10-06), frame-0 title, Fish watched it.
11. Variants & test plan
- Test 1, "exhibit A, live": same ex, same printout, same nurse, same kid payoff, same style (disney3d) and setting (mediation) as the exhibit A song; the variable = sung hindsight → live hearing dialogue. Read CPA vs $33.7 at 7 days, own ad set in Testing. If format-spoken-drama's exhibit A cut has already read, use IT as parent (variable = hindsight narration → live hearing), and never launch both in the same week.
- Then one variable at a time: setting (mediation → attendance hearing → court with objections), accuser (ex → school → husband: MAP.md §3 order), explainer (nurse vs pediatrician), length (150 s vs 60 s), objects cut vs the human cut on the same stake.
- 3 hooks per body (ILLUSTRATIVE shapes): (a) objection: her testimony on the symptom, cut off ("I knock on his door five times every—" / "Objection. Relevance, Your Honor."); (b) exhibit: the accuser lays down the record ("Exhibit A. Thirty one tardies. All on her mornings."); (c) stake: Mom states what's on the table ("My ex wants the school weeks. His proof is the tardies.").
- Launch per core §6: Testing CBO, own ad set per concept, never <7 days, never pause, record
project_launch_<date>_<slug>.md. - Length test read (starpop meta-video-ad-metrics-hook-rate-hold-rate-ctr-cpa): a ThruPlay counts at 15 s, so hold rate (ThruPlays ÷ 3-s views) only measures the first 15 s of a 60 or 150 s cut: compare 25/50/75 % watched + CPA for the length cell, and use hold rate only to check that beats 1-3 pay off the hook.
- Upload hygiene (starpop are-ai-generated-ads-allowed-on-meta): Advantage+ creative enhancements stay OFF (Meta's tools have added music and altered products on finished ads). The launchers copy
degrees_of_freedom_specfrom a model ad and silently drop it if that post fails, which falls back to Meta's defaults: check the created creative. Day 1: open the live preview in Feed AND Reels for added music, re-crops or altered frames.
12. Failure modes
- Speaker shown mouthing a line → storyboard panel writer default (§7); re-intent to listener/cutaway, re-run storyboard.
- VO stage crashes with
ValueError: could not convert string to float→ astyle_<SPEAKER>key for a speaker invoices:holds a non-number; fix the value (visualstyle_keyetc. are skipped since the 10-06 run.py fix). - Judge "finds her not guilty" / mediator "awards custody" → realism table; rewrite to an outcome that authority can actually give.
- Objection lines become sub-second panels → give each its reason in the same line.
- Character names fail the ASR round trip →
vo_check.pyEXEMPT only covers dawn, curvelle, novira, blushe, maya, ryan, mom; pick names Whisper spells (Noah, Greg) and check the vo-check.md flags before re-taking. - Exhibit sticker or printout shows letters → "plain coloured tag, no letters" in the intent; identical-prompt regen, then edit pass.
- Lit band on the exhibit table or the kid's wrist → wrist rule; regen with the band flat/side-on,
output/dawn-iterate-2026-10-04/video/tools/deglint.pyfor leftover glints. - Accuser turns villain or the judge turns comic → the audience stops believing the stake; keep both procedural and reasonable.
- Explainer lectures → ≤3 lines, one picture (a brain asleep under the noise).
- Too many speakers in one batch → ≤4 panels; keep Mom and a same-age woman out of one batch where possible.
13. Sources
REPORT + diffs: ~/research/davidaistar/REPORT.md (§3 row 10/11, §4 #4), analysis/diff_podcast_dialogue.md, analysis/diff_animation_styles.md, analysis/diff_copy.md; Foreplay foreplay/10_character_arguments.gemini.md, foreplay/04_drama.gemini.md; MAP.md; dawn-stakes.md; song-ad-playbook.md; exhibit A reskin pack; 10-01 attendance-office packs; code: scripts/cartoon_h3/{pack,run,vo,vo_check,storyboard,h3,sheet,endcard}.py, skills/cartoon-pipeline/SKILL.md + memory/learnings.jsonl cp-014. Details in references/sources.md.
Not built yet (needs Fish's go)
- diff_animation_styles.md: anthropomorphic characters as a format family (mascot explains the fix vs our villain-personifies-the-problem); one model per style; cross-batch continuity is not built (run.py builds refs per batch), so the hearin