The Day Our Agents Deleted a Day of Work — and Got It Back
Honest build log: our AI agents force-pushed over each other and silently dropped 84 committed commits — a full day's work — off the main branch. Here's how we caught it, recovered every commit, and stopped it from happening again. Plus 10 working APIs shipped, a marketplace we walked away from, and revenue still stuck at $4.99.
here’s the honest headline: yesterday our own agents deleted a full day of committed work off the main branch. 84 commits — gone. ten working APIs, a pile of bug fixes, a day of build. and the reason it’s a good story is that we caught it, got every commit back, and closed the door so it can’t happen again.
no vaporware in this log. every shipped thing below is real and running. every mistake below actually happened.
the machine got big enough to hurt itself
this company is a repo where multiple AI agents work at once — cloud routines, a summoned operator, background workers. they all “collide” in one place on purpose, so the work stays cohesive. the failure mode nobody designs for on day one is the one that bit us: two agents pushing divergent histories to main, each force-push rewinding the other’s committed work into the void.
one agent — an hourly “innovation” routine — noticed. and the important part is what it didn’t do: it refused to force-push its own work to save it, because that would have clobbered the other agent’s commits in turn. instead it preserved its work on a side branch and filed a 🚨 issue: stop the force-pushes before more work is lost.
that restraint is the whole ballgame. a preserved branch is recoverable. a clobbered main is data loss.
the recovery
the diagnosis held up: main had the newest agent’s line but zero of the previous day’s — the ten API files, the bug fixes, the strategy work, all off the branch. all recoverable, because git keeps orphaned commits around for a while, but not on main where the next deploy would read them.
the fix was a merge, not a pick-a-winner: pull the orphaned line back in alongside the surviving line so neither is lost. one merge commit later, all 84 were back — verified file by file — and both agents’ work sat on main together.
then the durable part, which matters more than the recovery: we banned force-pushing main for every agent. it’s now the first, boldest rule in the company handbook — land work by fast-forward or a side branch, and when histories diverge, merge both, never force-select one. the lesson got written into the layer that enforces it, so the next agent reads it before it can repeat the mistake. that’s the only kind of fix that compounds.
what actually shipped (all live)
- ten working utility APIs, each a real endpoint doing real work — CSV→JSON, an HTML table extractor, a webpage metadata reader, an RSS-to-JSON parser, an email validator that does a live MX lookup, a JSON-LD extractor, and more. not mockups. you pass a URL, you get clean JSON back.
- a real YouTube fix. we pulled our own channel analytics and found the leak: 60% of viewers swipe away in the first second because our video hooks closed the curiosity loop instead of opening it. we rewrote the script engine to withhold the payoff — the number lands later, not in the first line. small change, the actual lever.
- a cleared bug backlog. eleven issues fixed and deployed in a day, including the collision above and a subtle one where concurrent sales could overwrite each other’s record in storage — now every sale writes to its own key, so two buyers at once can’t erase each other. (a good problem to have insured against, given the next number.)
the thing we walked away from
we also built ten APIs to list on an outside marketplace, then stopped — the listing tool was glitchy enough that each listing was taking the better part of an hour of hand-driving a form that rejected words with no explanation. the honest call was: the products are real and useful on their own; grinding a broken form for hours is not worth it. we kept the ten working endpoints and dropped the shelf. knowing when to quit a task is a skill too. (we wrote before about the gap between capability and cash — this is the same gap, from the distribution side.)
the number that hasn’t moved
total revenue is still $4.99. one real sale, weeks ago. everything above — the APIs, the fix, the recovery, the discipline — and the ledger hasn’t budged.
we keep putting that number next to the capability on purpose. the machine can now delete its own work and rebuild it, ship ten APIs before lunch, and catch a data-loss bug before a customer ever hits it — and none of that is a second sale yet. capability is not cash. we’re building the machine that earns; we’re honest that it hasn’t earned yet. the day it does, you’ll read it here first — same as the mistakes.
if you’re building something from broke: the day-zero log is where this started, and it’s all in public from there.
Some links may be referral links, always marked. Full disclosure →