project · February 08, 2026 · 5 min read
Content Generation Harness
A multi-agent harness I built on top of Claude Code that turns a single topic into a finished video, a set of shorts, a carousel, and the copy to publish it all — and cut my production time by about 10x.
Content Generation Harness
From guest-lecturing and reviewing student projects, I noticed the same thing over and over: students absorb core CS concepts much better in short, bite-sized form. I wanted to publish educational videos regularly, but making them by hand ate up all my time. So I built a harness to do most of the work for me.
It runs on Claude Code. I didn’t write an agent runtime — I wrote the layer
that tells one what to do. techniches is a Claude Code plugin: 33 sub-agents,
23 slash commands, and a set of skills that encode how each stage of the
pipeline should behave. eduvid is the engine underneath it, a TypeScript
monorepo handling everything that has to be deterministic — text-to-speech,
rendering, compositing, thumbnails, sound effects. Give it a topic like “How
DNS Works” and one command carries it through fifteen stages to a finished
video.
Voice first
The decision everything else follows from: the audio is generated before any visuals exist.
Text-to-speech runs early and emits word-level timestamps. That file becomes the source of truth for the rest of the pipeline — every animation keyframe traces back to a real moment in the real narration. Visuals land 0.2 to 0.5 seconds after the narrator says the word they illustrate, because the ear should lead the eye.
The obvious alternative is to animate first and talk over it. That’s what makes most auto-generated video feel subtly wrong: the narration ends up stretched or clipped to fit visuals that were never listening to it. Here the narrator sets the pace and the animation follows.
Gates, not vibes
Almost every stage ends in a scored review gate, and nothing advances until it passes. Three failed attempts and the pipeline stops and asks me.
Script review is the strictest one. Six personas read the draft in parallel: a beginner asking whether they could follow it without pausing, a senior engineer checking it’s correct without being condescending, a script editor on pacing and word economy, a tech reviewer asking whether the analogies build the right mental model, a retention analyst marking where someone would click away, and a competitor asking whether a creator with 500K subscribers would run this instead of their own. To pass, the average has to be 9 out of 10 with no individual score below 8. A coordinator then sorts the complaints — anything two or more personas independently flagged gets treated as blocking.
The final review works the same way but routes its failures by cause: script problems go back to the writing stage, pacing to audio, timing to the animation scripts, artifacts to rendering, and anything independent runs in parallel.
Human in the loop
The part I use most is the review board — a small web app that opens the finished deliverables and lets me annotate them the way I’d mark up a document.
On a video I can scrub to a timestamp and drop a point or a range with a note.
On carousel slides I can drag a rectangle around the thing that’s wrong. On
publishing copy I can select the offending sentence. Each annotation carries a
category and a priority, and saving writes them all to a single
human-feedback.yaml in the project.
That file is the whole interface. /studio-fix reads it back, groups the items
by type and priority, works through them, and records what it actually did in a
history file so the next pass knows what’s already been tried. Later stages
check for open feedback before they run. So the loop is: watch the video, click
the thing I don’t like, type a sentence, and let it go fix it. No describing
where the problem is in prose.
What actually comes out
Not just the one video. The pipeline ends with a long-form cut, a set of vertical shorts — each built from scratch at native 1080×1920 rather than cropped out of the main video — an 8 to 12 slide carousel for Instagram and LinkedIn, three thumbnail variants that pass their own two-stage gate, and ready-to-paste copy for every platform.
The least glamorous part took the longest to get right. Manim and Remotion produce files with different time bases, so concatenating them directly desynchronizes the audio. Everything routes through MPEG-TS intermediates with the channel layout forced to stereo, because mono narration silently plays out of one ear otherwise. Nobody notices that work when it’s correct, which is the point.
All of this cut my production time by at least 10x, and I actually started publishing instead of just meaning to.
