Present and Callable
Generation went to zero and removal did not. A fleet will write you a second way to do anything, and the old way keeps its wiring, its flag, and its ability to execute.
By Jason Waldrip, with Claude Opus 5 16:20 9 min read
You asked for a change to how pricing gets calculated. The diff comes back Friday afternoon: a new function, clean and tested, wrapped in a flag, with the old function still sitting right below it in the same file. There’s a fallback that routes to the old behavior if the new one throws. You read it, and it’s careful work. You approve it, because you would have approved the same thing from a person.
Nothing was removed. Not that day, and not in the forty other changes that landed the same way this quarter. Every one of them was defensible on its own.
the safe move at every single review
Addition is the low-risk answer to almost any review question, and it always has been. A new path can’t break the thing already running. A removed path might, and the person who removed it owns whatever comes next. So the careful reviewer, the good one, the one you want, keeps saying yes to the version that leaves the old thing alone.
That bias used to be self-limiting. Every extra path cost somebody an afternoon of typing, and afternoons were the budget. Nobody wrote a second implementation of pricing on a whim, because the first one had taken a week and they remembered.
Now a fleet writes the second implementation while you’re in a meeting. It writes the flag, the fallback, the adapter that lets both versions coexist, and the tests that prove both work. All of that is real work performed correctly. The generation cost went to zero, and the cost of removal did not move at all, because removal was never about typing. It’s about proving that nothing depends on the thing you’re about to take out, and proof is the expensive part.
So the two operations came unglued. One of them got free, and it happens to be the one that grows the system.
the code was dead for nine years and it still traded
On August 1, 2012, Knight Capital deployed new order-routing code to eight servers. A technician copied it to seven of them. The eighth kept running what was already there, including a feature called Power Peg that Knight had stopped using in 2003.
The SEC’s order describes what that old code was doing in the meantime, and the phrasing is better than anything I could write: “Despite the lack of use, the Power Peg functionality remained present and callable at the time of the RLP deployment.”
The new code reused a flag that used to switch Power Peg on. Knight meant to delete the old code. The order says so in as many words, that they intended to remove it, and the deletion is the one step that didn’t happen. When the flag went to yes on that eighth server, nine-year-old logic woke up and started routing orders with a counter that had been moved out from under it in 2005 and never retested against it.
Forty-five minutes. Four million executions, 397 million shares, and a $460 million loss. Five days later a group of investors put $400 million in and took most of the company, and by December Knight had agreed to be sold.
Read that back with a fleet in mind. Nothing about Knight’s failure required an agent, and nothing about it is exotic. Dead code nobody got around to removing, sitting on the one host a deploy missed, switched on by a flag that used to mean something else. Ordinary mistakes, all of them cheap on the day they were made. What’s different now is the rate at which a codebase manufactures the first one.
the fence you’re allowed to remove
I’ve argued the other side of this, so let me square it.
I’ve written that the rewrite looks free now and that the ugliness in an old file is scar tissue from incidents you weren’t there for. I’ve written that when a fleet ships schema changes, you should let the dead column sit rather than reclaim it on a tidiness reflex. Both of those say leave it alone. This one says take it out. The difference is which way the change travels.
Deleting a column is one way. The data is gone and no pipeline you own brings it back. Deleting code is a round trip: it’s in the history, and restoring it costs you a git revert and some embarrassment. Those are different categories of act, and the fact that they feel the same in a diff is most of why people get them backwards. The cheap deletion gets skipped and the expensive one gets waved through.
Chesterton’s rule about the fence in the road is usually quoted as an argument for never touching anything, which is not what it says. It says go and find out why the fence is there, and then you may remove it. The finding out is the price of admission. That’s exactly the work a fleet can’t do from inside the diff, because the reason a path exists is rarely in the code and almost never in the branch it’s looking at. It’s in an incident from two years ago, a customer contract, a compliance answer somebody gave once. You have that. The agent doesn’t.
count the paths, not the lines
Here’s the shift I’d make in how you measure the thing you own.
Lines of code stopped being interesting the moment they stopped being expensive. The number that matters now is how many distinct ways a request can be served, because that’s the number your on-call has to hold in their head at 2am, the number your test matrix has to cover, and the number an attacker gets to choose from. Every flag doubles it. Every fallback adds one. Every second implementation you kept “just until we’re sure” is a live branch of the system, not a comment about your intentions.
At Phoneware, the whole mandate is that arithmetic. Portal customizations lived in per-customer JavaScript bundles and app backends were stranded in n8n flows, which meant the answer to “how does this behave for this customer” was a different codebase per customer. The replacement is one monorepo with a manifest that cascades reseller to domain to role. That work is only worth anything at the moment the old bundle stops being served. Until then it’s the same number of behaviors plus one more, and the one more is the one nobody has operated yet.
So make removal something you ship, not something you file.
- The replacement isn’t done until the old path is gone. Not “done, cleanup ticket filed.” Done means one way to do it. If the new path needs to bake behind a flag first, fine, that’s what flags are for. Put the delete on the calendar with a name against it the same day you turn the flag on, because a flag with no removal date is a permanent fork in your logic wearing a temporary costume.
- Ask the fleet to find the callers, and you make the call. Exhaustively tracing every reference to a function across a large repo is genuinely one of the things agents are excellent at, and it’s the tedious half of a deletion. Let it produce the evidence. Keep the judgment about whether the path is load-bearing for a reason nobody wrote down.
- Make “has this run” answerable. If you can’t tell from your own telemetry whether a code path has served a request in ninety days, you can’t retire anything with confidence, and you’ll default to leaving it in. A counter on the branch you plan to remove costs an hour and turns an argument into a fact.
- Review the shape, not just the change. The diff is one path. The question worth asking out loud is what the total came to: did this change leave the system with more ways to run than it had this morning, and was that on purpose?
None of this is a brake on the fleet. Generating more, faster, is the entire point and I’m not giving that up. But a system where addition is free and subtraction is manual doesn’t stay in balance on its own, and the drift is invisible in every individual review, which is precisely why it survives review.
So go back to Friday. Both pricing functions are still in that file, the flag is on, and the new path is serving everything. The old one hasn’t run since March. It’s still wired in, still reachable, still one repurposed flag away from an afternoon nobody wants. Who on your team could tell you, today, how many paths like that are live in your system? And if the answer is nobody, is that a number that’s been going up or down since you handed the keyboard to the fleet?
Jason Waldrip is a fractional CTO and CAIO through The Bushido Collective, working with founders drowning in AI-generated code and teams scaling past the leadership that got them here. If your codebase has grown every week this year and nothing has come out of it, that’s the conversation to have. Work with me.
A note on how this was made: I wrote this with AI assistance. The frame and the calls on what matters are mine. The model did most of the drafting, and the Knight Capital details come from the SEC’s own order rather than one of the many retellings. Worth saying plainly in a piece about work handed to machines.