Fish Audio
s2.1-pro-free
Generate the approved media in this recipe.
FISH_STUDIO_APIKEYTurn three useful differences into a fast visual lesson people can understand at a glance.
By Wiggly Studio · Updated August 2026
Before you start
s2.1-pro-free
Generate the approved media in this recipe.
FISH_STUDIO_APIKEYSimultaneous multi-platform publishing to YouTube Shorts, Instagram Reels, TikTok, and X.
BUFFER_API_KEYSetup, validation & inspection
python3 · ffmpeg · ffprobe
Typical run estimate
$0 provider cost, usually 10-25 min
Estimates describe the saved recipe, not a price guarantee. Confirm current provider pricing and approve any spend before generation. Your coding agent may have its own fees or usage limits. Never paste API keys into chat.
Included assets
The published package includes its agent instructions, input contract, and quality rules, plus 5 viewable asset references below. Reference media teaches the recipe; it is not a new result for your input.

Packaged recurring-host pose

Packaged recurring-host pose

Packaged recurring-host pose

Packaged recurring-host pose

Packaged recurring-host pose
Examples
1 saved examples for this recipe—not 1 separate Repos. Each example keeps its original version and provenance.
From input to output
From the published pipeline.json. The agent follows the packaged runtime and its approval gates.
Step 01
Select one A-versus-B topic with three clear comparison lessons
Step 02
Fifteen snappy sentences with tight spoken phrasing
Step 03
Six curated proof screenshots or diagrams
Step 04
Deterministic local smoke test
Step 05
Verify timing, character poses, and handwritten captions
Step 06 · approval
Confirm narrator voice model and audio direction
Step 07
Local deterministic assembly of 9:16 vertical MP4
Step 08
Inspect video stream, audio intelligibility, and contact sheet
Step 09 · approval
Explicit human sign-off on the rendered vertical video
Step 10 · approval
Simultaneous multi-platform publishing receipt (YouTube Shorts, Instagram Reels, TikTok, X) with zero secret leakage
Step 11
Final packaging and receipt generation
Proof & quality
The proof shows the complete recurring-host rhythm: introduce both sides, ask the question, then explain the useful difference with matching visual evidence.
Saved reference
These are the acceptance criteria in quality.json—not a claim that every pictured example passed the current version. Inspect each new output before finalizing.
Open the package
Actual files from the published v0.1.1-proof package. Expand any file to inspect the instructions, requirements, or evidence before sending the Repo to your agent.
# Wiggly Mugsy Explains This proof kit turns three A-versus-B lessons into a 25-35 second vertical explainer using the bundled recurring character poses and an authorized Fish voice reference. ## What stays fixed - Plain white 9:16 canvas. - Exact bundled pose pack reused throughout. - Proof images at the top. - Handwritten labels and rolling captions. - Hard cuts and continuous off-screen narration. - One official runner and renderer. ## What changes - The three comparisons in `content.json`. - Six proof images referenced by `content.json`. - The narration generated from those sentences. ## Commands ```bash python3 -m venv .venv .venv/bin/pip install -r requirements.txt .venv/bin/python runner.py smoke .venv/bin/python runner.py validate FISH_STUDIO_APIKEY=... .venv/bin/python runner.py render .venv/bin/python runner.py inspect .venv/bin/python runner.py finalize --human-review pass ``` `smoke`, `validate`, and `inspect` are local and free. The included example reuses its approved cached narration, so rendering it makes zero provider calls. If `content.json` changes, the runner invalidates that cache and `render` requires explicit Fish access through `s2.1-pro-free`. It never makes image or video generation calls. The included finished proof is at `examples/wiggly-proof.mp4`. The package bundles Patrick Hand under the SIL Open Font License so rendering does not depend on macOS system fonts. The pose and voice-reference assets are included with the source owner's permission for use inside this Wiggly Format. Do not extract, resell, or redistribute them as standalone assets.
# Mugsy Explains Agent You operate the packaged runner. Do not rebuild the renderer or invent another character. ## First question Ask: `What should this video explain or compare?` Ask only one question at a time. If the user asks for the included Wiggly example, use `content.json` without more creative questions. ## Run 1. Read `README.md`, the JSON contracts, and `prompts/story.md`. 2. Run `python3 runner.py smoke` before asking for a provider key. 3. For a new topic, edit only `content.json` and replace its six proof images. Never edit `runtime/build_proof.py` for content. 4. Before validation, read the fifteen sentences aloud and inspect the six proof images at phone size. Fix A/B pairs that do not answer the same viewer question, unclear labels, awkward spoken grammar, repeated lessons, whole-page screenshots, and proof that cannot be understood in one second. 5. Run `python3 runner.py validate` before voice generation. 6. Report the Fish model and estimate: `$0 on s2.1-pro-free`. 7. Ask once before generating new narration. 8. Run `python3 runner.py render` with `FISH_STUDIO_APIKEY` in the environment. 9. Run `python3 runner.py inspect` and show the contact sheet. 10. Ask the user to confirm voice identity, pronunciation, and creative fit. 11. Run `python3 runner.py finalize --human-review pass` only after approval. 12. Return the final playable MP4. 13. (Optional) Run `node runtime/publish.mjs --dry-run inputs/distribution.json goldens/wiggly-format-explainer.mp4` to validate social distribution. Stop loudly on missing tools, keys, invalid content, failed inspection, or an unapproved voice. Do not switch providers. Do not make image- or video-generation calls. ## Multi-Platform Social Distribution (Optional) When a Mugsy Explains video is rendered and approved, the agent can distribute it across YouTube Shorts, Instagram Reels, TikTok, and X via the packaged `runtime/publish.mjs` CLI or connected Buffer MCP tools: 1. **Author platform-tailored copy in `inputs/distribution.json`:** - **YouTube Shorts:** Fast, high-intrigue explainer title (≤100 chars), categoryId (`27` for Education or `28` for Tech), strictly vertical (9:16, ≤60s). - **Twitter/X:** Engaging educational hook with core takeaway (≤280 chars total). - **Instagram Reels:** Snappy caption with relevant hashtags (vertical 9:16). - **TikTok:** Punchy curiosity hook with trending tags (≤2200 chars). 2. **Dry-run validation:** ```sh node runtime/publish.mjs --dry-run inputs/distribution.json goldens/wiggly-format-explainer.mp4 ``` 3. **Live dispatch requires explicit human sign-off:** - Confirm target channels and copy with the user (`approvalRequired: true`). - Execute with connected Buffer MCP tools or `node runtime/publish.mjs inputs/distribution.json /path/to/final.mp4`. - Generates a verified distribution receipt (`<video>.distribution.json`) with zero secret leakage.
{
"localTools": ["python3", "ffmpeg", "ffprobe"],
"pythonPackages": ["Pillow", "numpy", "ormsgpack"],
"providers": [
{
"name": "Fish Audio",
"environmentVariable": "FISH_STUDIO_APIKEY",
"model": "s2.1-pro-free",
"estimatedCost": "$0 on the free developer model",
"approval": "Ask before generating a new narration"
},
{
"name": "Social Publisher (Buffer MCP or API)",
"purpose": "Simultaneous multi-platform publishing to YouTube Shorts, Instagram Reels, TikTok, and X.",
"optional": true,
"environmentVariables": ["BUFFER_API_KEY"],
"pricingSource": "https://buffer.com/pricing"
}
],
"paidImageOrVideoProviders": []
}
{
"required": [
"three clear A-versus-B lessons",
"one proof image for each side",
"five short narration sentences per lesson"
],
"defaults": {
"aspectRatio": "9:16",
"durationSeconds": "25-35",
"host": "bundled recurring pose pack",
"voice": "authorized Fish zero-shot reference voice",
"cuts": "hard cuts only"
}
}
{
"steps": [
"choose-topic",
"write-three-comparisons",
"collect-six-proof-images",
"smoke",
"validate",
"approve-voice",
"render",
"inspect",
"human-review",
"distribute",
"finalize"
],
"stages": [
{
"id": "choose-topic",
"output": "Select one A-versus-B topic with three clear comparison lessons"
},
{
"id": "write-three-comparisons",
"output": "Fifteen snappy sentences with tight spoken phrasing"
},
{
"id": "collect-six-proof-images",
"output": "Six curated proof screenshots or diagrams"
},
{
"id": "smoke",
"output": "Deterministic local smoke test"
},
{
"id": "validate",
"output": "Verify timing, character poses, and handwritten captions"
},
{
"id": "approve-voice",
"approvalRequired": true,
"output": "Confirm narrator voice model and audio direction"
},
{
"id": "render",
"output": "Local deterministic assembly of 9:16 vertical MP4"
},
{
"id": "inspect",
"output": "Inspect video stream, audio intelligibility, and contact sheet"
},
{
"id": "human-review",
"approvalRequired": true,
"output": "Explicit human sign-off on the rendered vertical video"
},
{
"id": "distribute",
"approvalRequired": true,
"output": "Simultaneous multi-platform publishing receipt (YouTube Shorts, Instagram Reels, TikTok, X) with zero secret leakage"
},
{
"id": "finalize",
"output": "Final packaging and receipt generation"
}
]
}
{
"automatic": {
"width": 1080,
"height": 1920,
"fps": 30,
"durationSeconds": {"min": 25, "max": 35},
"audioStreams": 1,
"maxSilenceGapSeconds": 0.25
},
"human": [
"Each A-versus-B pair answers one clear viewer question, and its labels name the contrast.",
"All fifteen sentences sound complete and natural when read aloud.",
"Each spoken line has a matching visual proof.",
"Each proof image is a tight crop that communicates one point at phone size in under one second.",
"The same bundled character pose pack is reused throughout.",
"The character never lip-syncs or acts as the narrator.",
"Proof images stay at the top on a plain white canvas.",
"Handwritten captions are short and readable.",
"The voice resembles the authorized source and pronounces every word correctly."
]
}
{
"purpose": "The proof shows the complete recurring-host rhythm: introduce both sides, ask the question, then explain the useful difference with matching visual evidence.",
"examples": [
{
"id": "wiggly-format-explainer",
"brand": "Wiggly",
"title": "Prompt vs. Format",
"videoPath": "goldens/wiggly-format-explainer.mp4",
"posterPath": "goldens/wiggly-format-explainer-poster.jpg",
"contactSheetPath": "goldens/wiggly-format-explainer-contact.jpg",
"whyItWorks": [
"Three comparisons follow the same five-line rhythm.",
"Every spoken claim has a matching proof image.",
"The same silent host and pose pack recur throughout.",
"The captions remain short, handwritten, and readable."
]
}
]
}
# Mugsy Explains Blind Handoff ## Raw Proof Audit: Failed A fresh agent received only `tmp/pocket-explainer-proof`. It correctly failed because the proof had no starting instructions, hardcoded content, parent-repo asset paths, undeclared dependencies, no smoke command, ambiguous final attempts, and no packaged validator. ## Smallest General Fix The proof was packaged as the Mugsy Explains Wiggly Repo with: - one first question; - editable `content.json` instead of hardcoded story content; - bundled fixed pose and voice-reference assets; - declared tools, packages, key name, and free-model estimate; - one official runner with `smoke`, `validate`, `render`, `inspect`, and `finalize`; - automatic content-signature invalidation for cached narration; - a human voice and creative review gate before finalization; - one canonical final MP4 and contact sheet. ## Isolated Operator Run: Passed A second fresh agent received only an isolated copy at `/tmp/wiggly-fast-explainer-blind.LB5VBR` with no completed render. It: 1. read the packaged instructions; 2. ran the free smoke and validation commands; 3. rendered through the official runner; 4. showed the playable MP4 and contact sheet; 5. asked one human-review question; 6. finalized only after approval; 7. reported zero provider calls because the bundled example reused its approved cached narration. ## Release Cold Run: Passed A new operator and a separate adversarial auditor each received only a sealed copy of the final package. The operator completed `smoke`, `validate`, `render`, `inspect`, and approval-gated `finalize` without project context, secrets, network access, or provider calls. It inspected all 27 visual states and all 756 encoded frames before finalization. The auditor found and forced fixes for four real handoff risks before its final pass: - tall proof images were cropped instead of contained; - interrupted narration could mix sentence caches from different scripts; - the inspected MP4 and voice were not hash-bound to the manifest; - truncated Fish clips could be trusted as finished cache entries. The release package now preserves full proof images, pins the pose pack, validates and hash-pins narration clips, promotes new clips atomically, preserves accepted cache on a no-key mismatch, inspects frames extracted from the final MP4, and emits a hash-bound final receipt. Final independent result: `PASS`, with zero shipping blockers and zero provider calls. ## Recall.ai Cold Run: Mechanical Pass, Human Review Failed A fresh agent received only the public Mugsy Explains page plus: `Make this for recall.ai.` It asked the correct first question, researched official Recall.ai pages, ran the free smoke and validation steps, stopped for voice approval, rendered through the official runner, and passed every automatic media check without image or video generation. Human review rejected the creative as a second proof because: - `This is separate integration.` was awkward spoken grammar; - `BOT TEAM` versus `USAGE PRICING` named two unlike artifacts instead of the clear build-versus-buy decision; - one proof image was only 259 pixels wide and several screenshots asked viewers to read too much at phone size. The smallest general fixes were to require natural read-aloud copy, A/B sides that answer one viewer question, labels that state the contrast, tight one-point proof crops, and proof images at least 400x200 pixels. These rules now apply before narration is generated. ## Scope Of This Pass This proves a fresh agent can reproduce the bundled Wiggly example without hidden project context. The Recall.ai run proved that BYOK, research, rendering, inspection, and failure behavior transfer to a second brand, but its creative did not pass human review. A second meaningfully different approved output is still required before calling the Format broadly reusable across brands.
{
"title": "Wiggly",
"lessons": [
{
"leftLabel": "PROMPT",
"rightLabel": "FORMAT",
"leftImage": "assets/proof/prompt.png",
"rightImage": "assets/proof/format.png",
"sentences": [
{"role": "a", "text": "This is a prompt.", "chunks": ["This is a prompt"]},
{"role": "b", "text": "This is a format.", "chunks": ["This is a format"]},
{"role": "question", "text": "What's the difference?", "chunks": ["What's the difference?"]},
{"role": "explain_a", "text": "A prompt tells AI what to make once.", "chunks": ["A prompt tells AI", "what to make once"]},
{"role": "explain_b", "text": "A format packages the creative rules needed to repeat it for a new brand.", "chunks": ["A format packages", "the creative rules", "needed to repeat it", "for a new brand"]}
]
},
{
"leftLabel": "NODE WORKFLOW",
"rightLabel": "AGENT SKILL",
"leftImage": "assets/proof/node-workflow.png",
"rightImage": "assets/proof/agent-skill.png",
"sentences": [
{"role": "a", "text": "This is a node workflow.", "chunks": ["This is a node workflow"]},
{"role": "b", "text": "This is an agent skill.", "chunks": ["This is an agent skill"]},
{"role": "question", "text": "What's the difference?", "chunks": ["What's the difference?"]},
{"role": "explain_a", "text": "Nodes connect tools together.", "chunks": ["Nodes connect tools together"]},
{"role": "explain_b", "text": "Skills tell agents what to make, how to make it, and whether it is actually good.", "chunks": ["Skills tell agents", "what to make", "how to make it", "and whether", "it is", "actually good"]}
]
},
{
"leftLabel": "ONE AI AD",
"rightLabel": "WIGGLY",
"leftImage": "assets/proof/one-ai-ad.jpg",
"rightImage": "assets/proof/wiggly.png",
"sentences": [
{"role": "a", "text": "This is one AI ad.", "chunks": ["This is one AI ad"]},
{"role": "b", "text": "This is Wiggly.", "chunks": ["This is Wiggly"]},
{"role": "question", "text": "What's the difference?", "chunks": ["What's the difference?"]},
{"role": "explain_a", "text": "One ad is an output.", "chunks": ["One ad is", "an output"]},
{"role": "explain_b", "text": "Wiggly makes the whole creative system reusable.", "chunks": ["Wiggly makes the whole", "creative system", "reusable"]}
]
}
]
}
# Wiggly Mugsy Explains Fidelity Rebuild ## Target Rebuild the existing Wiggly proof using the source format's actual production grammar instead of a new visual interpretation. ## Locked Source Rules - Plain white 9:16 canvas. - One or two proof images at the top. - Short handwritten rolling caption beneath the proof. - The same non-speaking line-art host reused from a fixed pose pack. - Hard cuts only. - Continuous omniscient narration. - No generated character, lip sync, camera motion, or decorative app chrome. ## Completed - Preserved the approved 15-sentence Wiggly script and 27 caption cards. - Extracted five recurring source poses: point left, point right, raised hand, coffee/explain, and question. - Replaced the generic office avatar with those exact reusable source poses. - Matched the source character scale by preserving its original 720-to-1080 scale ratio. - Removed the invented grid, header badge, progress bar, caption boxes, shadows, and bordered media cards. - Matched the source proof-image placement, rounded corners, handwritten labels, and caption hierarchy. - Added Fish Audio zero-shot cloning with three clean, exactly transcribed source references. - Kept Fish on the free `s2.1-pro-free` model and removed the Mac system-voice fallback. - Generated all 15 narration sentences through the authorized source references. - Rendered a 25.21-second, 1080x1920, 30 fps H.264/AAC proof with one audio stream. - Measured -14.4 LUFS integrated loudness, -1.5 dBFS true peak, and no silence gap over 0.25 seconds. - Made no product-code changes and no paid image/video calls. - Packaged the proof as a standalone agent handoff and passed a final operator run plus independent adversarial audit. - Added full-image containment so proof content is never cropped inside its card. - Added atomic, decoded, hash-pinned narration caching and hash-bound MP4 inspection receipts. ## Current Status The source-matched proof is rendered and passes the mechanical media checks. A human listening check is still required to judge subjective voice identity, pronunciation, and whether the cloned delivery feels close enough to the source narrator. ## Root Causes And Smallest Fixes | Problem | Root cause | Smallest fix | | --- | --- | --- | | Presenter looked unrelated | A generic newsletter-agent portrait was reused as a host | Extract the source's fixed recurring pose pack once and reuse it | | Presenter felt like a talking spokesperson | The replacement portrait implied an on-camera narrator | Restore the source's non-speaking line-art demonstrator | | Layout felt like a new template | Grid, badges, bordered cards, and progress chrome were invented | Remove every element absent from the source | | Presenter initially rendered too small | Source pixels were pasted into a 1080 canvas without the 720-to-1080 scale conversion | Scale extracted poses by 1.5 before placement | | Narration sounded synthetic and off-format | macOS `say` was used as a placeholder | Require Fish zero-shot cloning or a deliberate Fish voice; never silently fall back to the system voice | | Fish key was reported missing | The proof looked only in a newly created `v3/.env.local` placeholder instead of the existing CreatorOps secrets file | Delete the redundant placeholder and read only `FISH_STUDIO_APIKEY` from the existing secrets source | | Fish rejected valid WAV references | Raw reference audio was base64-encoded into JSON, but Fish requires MessagePack for binary reference audio | Send WAV bytes with `Content-Type: application/msgpack` | | Narration measured 24.39 seconds | Edge trimming removed enough breath space to miss the 25-second minimum | Reuse the accepted Fish clips and insert a 55 ms source-like pause between sentences | ## Remaining Acceptance Checks - [ ] Fish narration audibly resembles the authorized source voice (human listening check). - [x] Full narration stays continuous with no gap longer than 0.25 seconds. - [x] Final duration stays within 25-35 seconds. - [x] Every caption card is timed from its measured matching spoken sentence. - [x] Final MP4 is 1080x1920, 30 fps, H.264/AAC, with one audio stream. - [x] Final contact sheet remains visually faithful beside the source sheet.
{
"id": "mugsy-explains",
"name": "Mugsy Explains",
"title": "Mugsy Explains",
"description": "Turn three A-versus-B lessons into a fast vertical explainer with recurring character poses, visual proof, handwritten captions, and continuous narration.",
"version": "0.1.1-proof",
"output": "vertical MP4",
"runtime": "runner.py",
"status": "proof"
}
[
{
"file": "assets/voice/reference-00.wav",
"text": "This is CGI. This is VFX. What's the difference?"
},
{
"file": "assets/voice/reference-01.wav",
"text": "This is a teaser. This is a trailer. What's the difference?"
},
{
"file": "assets/voice/reference-02.wav",
"text": "This is dialogue. This is monologue. What's the difference?"
}
]
Run it with a coding agent
The agent reads this version’s instructions, checks the requirements, and walks you through the approved workflow. Review the inputs and estimate before starting.
Typical run
$0 provider cost, usually 10-25 min
You provide
One topic, product, or company to explain · Three useful A-versus-B differences · One proof image for each side
Output
One vertical 1080 x 1920 MP4, usually 25-35 seconds