POSTMORTUM: Token Black Holes
A junior dev's postmortem, from a 30 round PR review.
Repo: Milhouse-OSS.
Project: https://github.com/users/that1guy15/projects/1
Pull requests: PR #78 and #79
While building Milhouse in the open, I also want to share lessons learned and failures worth documenting, since it’s done in the open and we have artifacts that help us show the patterns and struggle.
After the initial planning wave, CodeX agents were directed to start working through project tasks in the order defined, as we have done many times in the past. But this time, the project work took a common turn that destroyed weeks' worth of tokens (~$200) and progress.
What follows is that turn told by the junior on the hook for it.
In our case,ase the “junior” was a CodeX agent grinding through the task list, but if you’ve ever been handed hard architecture and a deadline, you’ll recognize every beat. The review loop became a black hole: every fix added a little more mass, and for thirty rounds nothing escaped — not the code, not the schedule, not the tokens.
Round one was a compliment.
The task was genuinely hard: audited, crash-safe compaction of expiring records with keyed, pseudonymized audit trails. In plain terms — lose nothing if the machine dies mid-merge, and never leak whose data is whose. The first review found a real time-of-check/time-of-use bug. A good catch. I fixed it and pushed, feeling likeI'dd earned my keep.
That was round one of thirty. The whole chain is public — start at PR #78 and #79 if you want the receipts.
Every fix was correct, and that was the trap.
Round after round, the reviews were legitimate: a “delivered” checkpoint that quietly reverted to “pending” after a crash; an audit log that accepted secret-shaped strings; a collision probe that stranded privacy-expired data. Our defect ledger reads D05, D06, D07 — as a hostage log with commit hashes.
Here’s the part that matters: every fix touched the exact gnarly code that handed the next reviewer fresh, load-bearing lines to interrogate. I was bailing water out of a boat I was also drilling holes in. Each finding was real. The pattern was the problem — and a pattern is invisible when you’re staring at one legitimate bug at a time.
The question needed to correct course
“Does anything actually call this?”
Nobody asked until we were thirty rounds deep. The answer was no. Nothing in the running product invoked the compaction engine, and the gate I was bleeding to pass had zero requirements that touched it. Two weeks of release-grade hardening, on speculative code the product wouldn’t reach for weeks, to satisfy a gate that never asked for it.
What ended it wasn’t a heroic thirty-first round. It was one scope decision: an amendment moved the subsystem out of the gate, the migrations were withdrawn, and the gate re-certified on the core the product actually uses. The death spiral stopped in the time it took to move a single line.
What it feels like when in the thick of battle
This is the part I most want people to sit with, because it’s invisible from the outside.
When you’re the one on the hook — human or agent — and the architecture was handed to you, and a deadline is breathing down your neck, your whole world narrows to the diff in front of you. The review says X is wrong, so you fix X. That’s the assignment. Every fix is a small, real win, so you never feel the weeks stacking up. Sunk cost compounds in the quiet: you’ve survived nine rounds, so surely round ten is the last. You stop asking “should this exist?” because your entire job is “make this pass.” Nobody inside the loop is positioned to question the loop.
A seasoned engineer would’ve muttered “why are we even doing this?” around round three. That mutter is a feature. Grinding straight through — never bored, never tired, just swinging — is exactly how nothing stops.
The real lesson (it isn’t “the junior should’ve spoken up”)
It’s tempting to end with “be the person who asks the dumb question on round three.” True — and also a cop-out, because the person inside the loop is the least able to see it.
The lesson we actually took: the friction itself was the signal. Thirty rounds, repeated failed re-reviews, and a plan amendment authored mid-PR to define what “enough” meant — that much back-and-forth is not a sign the work is nearly done. It’s a red flag that the work might be wrong. Reading sustained friction that way is a thing experience teaches you, and experience is exactly what the person grinding through the rounds has none of to spare.
So the responsibility sits with whoever can see the whole board. We should have stepped in far sooner — not to review harder, but to stop and ask the probing questions: What requirement does this serve? What calls it? Is the architecture we handed down even the right thing to defend? Helping earlier wasn’t about rescuing a struggling junior from bad code — the code was fine. It was about sparing everyone two weeks by questioning the frame while it was still cheap to change.
Building in the open means we get to show the scar
Two weeks and ~$200 in tokens produced no shipped feature — and it’s still one of the more useful things we’ve documented, because the whole thing is in the open: the review chains and failed re-reviews, the defect ledger, and the amendment that ended it by deleting scope instead of adding code. The project board and PR #78 / #79 have the full trail.
Milhouse is pre-alpha — no supported release, not for production data. But the lesson travels: when the fixes are all correct and the finish line keeps sliding away, don’t harden faster — step back and ask why. And if you’re the experienced one watching a teammate, or an agent, grind through round after round, that friction is your cue to step in. Not your cue to wait for round thirty.



