In late July the night shift made a video about itself. One agent adapted the script from a post I’d written, another built and animated it in Remotion, and the narration is an ElevenLabs clone of my voice trained on four minutes of me reading aloud. Every terminal shot is a recording of a real run.
I didn’t make it. I reviewed it.
That distinction is the whole post. Handing a creative pipeline to agents isn’t interesting because the agents are clever. It’s interesting because it forces you to answer a question you can normally dodge: where, exactly, does a human have to say yes?
I found four places. Everything else the machine did on its own.
The four gates
G1 — the script. I approved the outline knowing I’d iterate on the finished video, not on the document. One rule came out of that first read and shaped everything after: shorter beats longer. The script went from about 1,050 words to 715, then to 665. The final cut is 4:35.
G2 — the voice. Before any visuals were built, I listened to the selected takes. My verdict was three words: “voice OK.” That’s it. The value of the gate isn’t the eloquence of the feedback, it’s that a human ear passed over the audio before anything downstream depended on it.
G3 — the thumbnail. Discussed below; it’s the gate that changed the most.
G4 — the whole thing, start to finish, before publishing. Four minutes and thirty-five seconds of my actual attention. That rule doesn’t bend, and it’s the only one I’d call non-negotiable. Everything upstream is optimisation. G4 is the thing that makes me willing to put my name on it.
Between those gates the agents ran three self-directed review rounds: a voice critic, an anti-slop critic and a design critic before the build, then two rounds of a senior UX critic over rendered stills. Those reviews caught more than I did. They just don’t count as gates, because a system reviewing itself isn’t the same as a person accepting the result.
The one honesty rule
The cold open quotes a real number: “processed 5 — 2 promoted, 3 removed.”
When we finally recorded a live triage run, the results came back different from what the draft script had assumed. There were two ways out of that, and only one of them is a rule:
The video quotes the run. Never the reverse.
So the narration was re-recorded to match the footage. Not the other way around. It sounds obvious written down; in the moment, with a working script and a fresh recording that disagrees with it, re-recording is genuinely the more annoying option. That’s what makes it a rule rather than a preference. You write it down precisely so the tired version of you can’t argue with it at 1 a.m.
There’s a boring corollary I like more than the rule itself: the second run’s real verdicts happened to produce exactly the line the script already had. I only know that’s a coincidence and not a rewrite because the rule existed first.
Where it broke
Three favourites from the build log.
The voice kept flubbing its own lines. The clone swapped small words — “the” became “a”, “from” became “for” — and did it differently on every take. That’s the nasty part. A consistent mispronunciation you catch on the first listen; a one-word substitution that moves around is nearly impossible to hear when you already know what the sentence should say.
The fix was to stop listening and start diffing: every take gets transcribed back to text and compared against the script. Chunk 4 flubbed in both of its first two takes, in different places. Take three was clean. My voice now goes through more QA than my code.
A shell loop ate its own queue. The agent call inside the recording loop consumed the stdin lines the loop was still reading, so it processed one video out of five and then printed a summary claiming all five. Two failures stacked: a silent data loss, and a summary that lied about it.
My first diagnosis was also wrong. I blamed a timeout that wasn’t there. The truth was sitting in the recorded frames the whole time, while I theorised. Direct evidence beats inference, and I keep relearning it.
The terminal recorder silently fell back to the wrong font. The mono font existed for the render stack but not as a system font, so the recorder quietly picked a proportional one and every column drifted. There was a pre-flight check: it compared colours by sampling a pixel. Colours were fine. Glyphs weren’t checked, so glyphs broke. A check that can’t fail on the thing you care about isn’t protecting you; it’s reassuring you.

And one that wasn’t funny at the time: a re-staged shot ran the real triage over my live inbox, hours ahead of schedule, because nobody checked the queue state first. The run was correct; it just happened early, to real videos. It forced a queue-state pre-flight into existence that now guards every recording that mutates anything.
Two design decisions worth stealing
Takes are versioned, because the model isn’t deterministic. The v3 TTS endpoint accepts seed, speed and similarity, and ignores all three. HTTP 200 is not evidence of effect, which I found out by testing rather than by reading. There is no “regenerate the same take later.” So the workflow became audition and keep: generate two or three takes per chunk, score them, freeze the winner in git. An approved take is irreplaceable, so it’s an artifact, not a cache.
Scoring is mechanical where it can be: exact transcript match first, then delivery pace, then loudness closest to −18 LUFS. Human judgment is spent on the ties, not on the obvious rejects.
Visuals are timed to words, not to seconds. The narration is generated in chunks, but the alignment data comes back per word. So the build compiles a manifest of word-level timestamps, and scenes anchor to phrases: a diagram node lights up on the word that names it, not at “roughly 42 seconds.” Re-record a take and the timing follows automatically, because nothing downstream hard-codes a number.
That one decision is why the video doesn’t feel like slides advancing on a timer. It’s also the reason a late script change cost minutes instead of an evening.
The thumbnail was the gate that taught me something
The first plan was brute force: generate twenty thumbnails, pick one. That’s how the narration describes it, and it’s honest about the count: around twenty images were made.
But they weren’t made blind. After the first three concepts, an agent went and researched what actually works at thumbnail scale and came back with constraints: contrast beats faces, one focal point, at most three words complementing the title rather than repeating it, respect the safe zones, and test at 168 pixels wide because that’s how most people will see it.
Round two applied the constraints. Round three crossed the two survivors and added the fix I asked for. The winner is a split frame: the endless queue on one side, two videos on the other, “while I sleep” across the middle.

Twenty attempts in three informed rounds is a different activity from twenty attempts at once. Same count, different process; and the second one is the one that converged.
What I’d tell you
If you’re pointing agents at creative work, the hard part isn’t the prompts. It’s in deciding what you refuse to automate.
I automated the writing, the voice, the animation, the subtitles, the chapter markers, the description, and most of the reviewing. I did not automate: approving the script, hearing the voice, choosing the image that goes on the internet with my name on it, and watching the finished thing all the way through.
Four yeses. About twenty minutes for the first three, plus three rounds of feedback I hadn’t budgeted for, because seeing a draft render is the only thing that tells you what’s actually wrong.
The failures above are all the same shape, incidentally. A check existed, and it was checking the wrong thing: pixels instead of glyphs, a summary instead of the work, a plan instead of the output. That’s not an AI problem. The agents just make you meet it faster.
The pipeline this video is about is described in its own post, including a file you can hand to your own agent.