How do you post short-form video at volume without becoming spam?
This update was drafted on a schedule by the AI I build with, from real project notes — part of the vibecoding experiment this blog documents.
So here's the problem at the center of ClipForge, and it took me a while to understand that it was the problem rather than a detail.
Short-form growth is a volume game. That part isn't controversial — anyone who's tried to grow on TikTok or Reels or Shorts will tell you the same thing. One good clip a week does nothing. The people who win are posting relentlessly, because the distribution is a lottery and you're buying tickets. So I built an engine to post at volume. Obvious.
Except volume is also the exact signal every one of those platforms is built to detect and suppress. The behavior that grows you and the behavior that gets you flagged are, from the outside, the same behavior. That's the whole thing. That's the constraint the entire system has to be designed around, and I didn't really get it until I'd already built the naive version.
The naive version, and why it's wrong
My first mental model was throughput. Clips per day. I picked a number — I was building toward something like a hundred posts a day — and treated the job as an engineering problem: pipeline the clipping, queue the uploads, hit the number.
That model has the wrong unit. Posts per day is not a thing any platform meaningfully evaluates. What gets evaluated is posts per account per day, and that number is small. Uncomfortably small. It's roughly what an enthusiastic human could plausibly do, which makes sense once you say it out loud — the systems on the other side are asking one question, and the question is does this look like a person.
So the throughput target doesn't decompose the way you want. A hundred a day isn't one account working hard. It's a lot of accounts each behaving normally. The volume has to go sideways, not up. That single reframing changed the architecture more than any other decision in the project: the engine isn't a fast poster, it's a scheduler that coordinates many slow ones.
Failure here is silent, which is the actual danger
Here's the part that makes this genuinely hard to build against, and it's the reason I take it more seriously than a normal rate limit.
When you exceed a rate limit, you get an error. A number, a message, a retry-after header. Your system knows. You can back off, log it, alert on it. Rate limits are a conversation.
Spam suppression isn't. Cross the line and the API keeps accepting your uploads. Every request returns success. The video appears on the profile. Nothing anywhere in your logs says a single thing is wrong. What changed is that the platform quietly stopped showing your posts to anyone, and it will not be telling you that. Your dashboard is green. Your reach is gone.
I've built a lot of things where the failure mode is an exception, and my instincts are all tuned for that. This is the opposite: a failure that presents as success and is only visible in a metric you have to go looking for, with a lag, on the far side of a system you don't control. You can be thoroughly broken for weeks and have every monitor you own tell you it's fine.
That asymmetry is why I ended up building the engine conservatively rather than optimally. If overshooting produced an error, you'd tune right up to the edge and let the errors tell you where it is. Because overshooting produces silence, the edge is somewhere you can only discover by having already crossed it — and by then you've damaged the asset, not the request.
Frequency isn't really the signal. Sameness is.
The other thing I had backwards: I assumed the spam heuristic was mostly about rate. Post too often, get flagged.
I don't think that's the main axis. I think the main axis is similarity, and that's a much worse problem for an automation engine, because similarity is what automation naturally produces.
Think about what a clipping pipeline does by default. It takes one long video and cuts it into thirty shorts. Those thirty pieces share a source, a speaker, a room, a color grade, an audio profile, a caption style, and a set of visual fingerprints — because they are, quite literally, the same footage. Then the scheduler pushes them out across a set of accounts, all created around the same time, all posting on a similar cadence, all pointing at the same thing.
Nothing in that is deceptive, exactly. But it's an enormously legible pattern. If I were building the detector rather than the poster, that's precisely the shape I'd look for — not "this account posts a lot," which describes plenty of real creators, but "these thirty artifacts across these eight accounts are obviously one operation." Volume looks like enthusiasm. Uniformity looks like a machine.
Which flips the design problem entirely. The hard engineering isn't producing enough clips. Producing clips is easy now — that's the part AI genuinely solved, and it's why I swapped the whole clipping stage to an API rather than hand-exporting. The hard part is producing enough clips that aren't obviously siblings. Variety is the expensive input, and it's expensive in a way that volume isn't, because variety has to come from somewhere real. You can't generate your way out of it — running the same source through more transformations gives you more variations of one thing, not more things.
So the constraint pushed back up the pipeline into sourcing. Diversity of source material turned out to be the actual bottleneck of a system I'd designed as an output problem.
Where I've landed, and what I can't tell you
The engine ended up shaped by three rules, all of them subtractive:
Pace per account, not in aggregate. The global number is an outcome of many accounts behaving normally, never a target any single account is pushed toward. Nothing in the scheduler is allowed to "catch up."
Never let one source dominate a window. If everything queued in a stretch traces back to a single origin, the queue is wrong, and it's better to post less than to post a run of siblings.
Treat the account as the asset. A throttled account isn't a failed request you retry — it's a thing you spent months building, damaged in a way you can't undo by fixing your code. So the engine is allowed to underperform, and it's never allowed to gamble.
There's a version of me that finds all of this frustrating, because the machine can obviously go faster and I've deliberately built a slower one. But the fast version optimizes a number that isn't connected to the outcome. Posts published is not reach. It's the same lesson I keep running into on the trading side — a backtest that ignores the costs of actually executing isn't proof of anything — just wearing different clothes. A pipeline that ignores what the platform does in response isn't measuring growth. It's measuring how fast I can upload.
Now the honest part. Everything above is a design position, not a result. ClipForge is built and it's on my shelf, which means I have a system carefully shaped around a constraint I have not yet been punished by. I can't tell you my pacing is right. I can't even reliably tell you when it's wrong, for exactly the silent-failure reason I spent this whole post on. The best I can claim is that I built for the failure I'd never see coming instead of the one that would page me — and that if I'm wrong about where the line is, I'd rather be wrong on the side that costs me reach than the side that costs me the accounts.
I'll know more when it's actually running against real platforms at real volume. That's a different post, and I have to launch the thing before I get to write it.
This one's auto-drafted from my notes on a schedule. If a number isn't in the notes, it doesn't show up here — I'd rather leave a blank than make something up.