refactor: exorcise it before you nuke it from orbit

It's the retro after the third incident this quarter, and someone says it: we should just rewrite the whole thing. Someone else finishes the line from Aliens. Nuke the entire site from orbit. The Haunted October finale is a field guide for un-haunting a legacy codebase without burning it down: why technical debt survives, why the big-bang rewrite brings the ghosts back even with AI that claims it can migrate COBOL, and the six steps that actually get rid of them.

October 30, 202620 min

Show Notes#

It's the retro after the third incident this quarter. The whiteboard has one sticky note under "What went well," and it says "Pizza." Then someone in the back says it: we should just rewrite the whole thing. And someone else finishes the line from Aliens. Take off and nuke the entire site from orbit. It's the only way to be sure.

Tomorrow is Halloween, and this is the exorcism episode: a field guide for un-haunting a legacy codebase without burning it down. I start with why technical debt survives. There's no time, no mandate, no glory, and the haunted system is usually the one making too much money to stop. Then the opposite trap: the big-bang rewrite drops every behavior nobody wrote down, and the ghosts come back in the requirements. That holds even now that OpenAI says its newest models can migrate COBOL. AI made the nuke cheaper. It didn't make the recon optional.

Then the steps. Say the ghosts' names out loud. Add observability before you touch anything. Find out what's actually load-bearing and put tests around it. Remove the rest slowly, behind feature flags, strangler fig style. Rename what you keep and write down why. And accept that some ghosts stay. Plus the part of Aliens nobody remembers: Ripley earned that line by going in first, and they never actually got to nuke it. If you don't decide, the reactor decides.

If you've ever asked for a rewrite, or had to answer someone who did, this one is for you. A known ghost is not the same as an unknown one.

Read full transcript

It's the retro after the third incident this quarter. The whiteboard has three columns. What went well? What didn't go well? Action items. The first column has one sticky note on it, and it says "Pizza."

Everyone is tired. The floorboard function broke again. The cron job on the box nobody owns did something at 2 a.m. again. And there's a table in the database that everyone has agreed to stop talking about, which is now its own action item from last quarter, still open.

And then somebody in the back, usually the most talented engineer in the room, the one who's been there long enough to be really, really, really sick of it, leans back in their chair and says, "Honestly, we should just rewrite the whole thing."

And I swear, there's only one more person in the room who's seen Aliens enough times, who leans in and finishes it for them. "Take off and nuke the entire site from orbit. It's the only way to be sure."

And everybody laughs, because honestly, we've all thought it. I've been in that meeting more times than I can count. I've been the person who suggested rewriting it, and I've also said the quote, and I've also, unfortunately, been the director who had to answer it.

And I want to spend time this episode on one thing about that line that nobody remembers. Ripley was right. But the important part isn't the line. It's what happened before she said it.

Welcome back to Chaotic Commits. I'm Joanne Skiles. I'm an engineer. I teach computer science. I advise companies on how their AI systems are actually designed. And my research is on transparent systems, which, this month especially, has felt a lot like being a paranormal investigator on a very small budget.

Tomorrow is Halloween. This whole month we've been walking through the haunted house. The floorboard everyone steps over. The cron job from an engineer who left years ago. The table in the basement that something writes to every morning.

This is the one where we get rid of them. Some of them. Not all of them. Ghosts are stubborn.

But you can un-haunt a codebase. It's not fast. It's not dramatic. It's not a big heroic rewrite. It's a sequence of fairly boring decisions made over months by a team that decided to stop stepping around the floorboard and find out what it was.

And the full rewrite, the nuke from orbit, is a real option. It's just not the first one. You gotta earn it.

So, let's get into it.

Before we get to the field guide, I want to be honest about why most haunted codebases stay haunted. Because it's not that engineers don't know how to fix things. We love fixing things. You have to physically restrain some of them. It's that nothing in the organization is pointed at it.

There's no time. The roadmap is full. The roadmap is always full.

There's no mandate, because nobody above you has said "go deal with the basement issue," because nobody above you knows there's a basement issue.

And there's no glory. Nobody gets promoted for the incident that didn't happen. You can spend a whole quarter making a system boring and safe, and in the performance review, it looks like you spent a quarter not shipping anything. And the system works. Sort of. Mostly. Except at 2 a.m. when someone looks at it wrong.

There's a moment in that same scene in Aliens. Right after Ripley says nuke it from orbit, Burke, the company man, the guy representing the corporation that owns the colony, says, hold on, "This installation has a substantial dollar value attached to it."

And we all hate him. Rightly. Burke's the worst. But I've sat in a lot of planning meetings, and I have to tell you, he's not wrong about the dollar value. The haunted system is usually the one making the money. It's the checkout. It's billing. It's the thing the business runs on. That's why it's haunted in the first place. It was too important to stop, so it never got cleaned up. So it got scarier and scarier, and it got even harder to stop.

The dollar value is the reason it never gets fixed, and the dollar value is the reason it has to.

Now here's the trap on the other side. When the frustration finally boils over, the move that a lot of teams reach for is: rewrite all of it. New language, new architecture, clean slate. And the big-bang rewrite has a famous failure mode.

You rewrite the system based off of what you think it does. But the old system doesn't just do what you think it does. It also does all the things nobody remembers it doing. The weird rounding rule in the floorboard function that finance depends on. The cron job that quietly fixes up bad data every night. The trigger in the basement.

The rewrite drops all of those. Not on purpose. It's because nobody knew they were there. So you launch the shiny new house, and within a month, the ghosts are back. Because they weren't in the walls. They were in the requirements nobody wrote down. You just moved them.

And I'll be honest, that trap got a lot more tempting this month. Because earlier this month, OpenAI announced its newest models got dramatically better at migrating COBOL, the decades-old code a lot of banks still run on. OpenAI says that on its own COBOL migration test, the new model gets about 87% of the tasks right, and close to 98% if you let it think harder. A task only counts if the translated program matches the output byte for byte on every one of OpenAI's hidden test cases. The generation before it was around 5%.

And look, that's a real jump. I'm not going to pretend it isn't. But it's a score on OpenAI's test, and the test cases aren't public. What it shows is that the translations behave like the original on the inputs they tested. Not on every possible input. And that's not a success rate for migrating a bank. And the people who've actually done these migrations keep saying the same thing: translating the code is not the same as replacing the system.

Because here's the thing. Translated code can run with zero errors and still round money differently than the original did. That's the floorboard function. A clean translation, in a shiny new language, of a system nobody did recon on. Every behavior nobody remembers, either carried over or quietly dropped, and no way to tell which until finance calls.

The tool got faster at the rewrite. It might even help you find some of what the old system is secretly doing. But a translation score can't tell you whether you found all of it, or whether you've kept it.

AI makes the nuke cheaper. It doesn't make the recon optional.

So let's go back to Ripley's line and what people forget. She doesn't say it at the beginning of the movie. At the beginning, the marines go in, confident. They're loud, they've got big guns, they walk into the colony with motion trackers beeping, and they go deep into the building to see what's actually there.

And it goes really, really badly. But they come out of it knowing something they didn't know when they went in. They've seen the scale of the thing. They know what they're dealing with.

And that's when Ripley says nuke it from orbit. Not before the recon. After. She earned the line by going in first.

That's the first two steps of the field guide, and they're both about going in before you decide anything.

Step one: say it out loud. You can't exorcise something you're pretending isn't there. Most haunted teams have a list of things they've collectively agreed not to talk about. The floorboard. The box nobody owns. The table with "old" in the name that you still use.

Write the list. And I mean actually write the list. Put each ghost in the tracker with a name. "The calculate_order_totals function." "Everything in the crontab on util-02." And say it in the retro, out loud: "These are the things we're afraid of."

It sounds silly, but trust me, it isn't. Half of what keeps ghosts alive is that nobody's allowed to say their name in a meeting.

Step two: bring a light before you bring a hammer. Before you change anything, instrument it. You have to make it visible.

For the floorboard function, add logging. Who's calling it? How often? Which code paths does it take? What shape of answer comes back? Not every raw argument and return value dumped into your logs, especially when it's touching money or customer data. Mask what's sensitive, sample if it's hot, and put an expiration date on it, so your recon logs don't become the next thing in the basement.

Let it run through a full business cycle. If the weird path only runs at month-end close, two weeks in the middle of the month will tell you it doesn't exist. You will learn more about that function from one honest cycle of logs than from two years of stepping around it. Usually what you learn is that most of the scary code paths never run, and the one weird one runs a lot.

For the cron box, take inventory of every job on it, and find out what each one touches. For the basement table, find out exactly what writes to it and exactly what reads it, down to the column.

That's your motion tracker. It doesn't fix anything. It tells you where things are, and how close.

And notice what we haven't done yet. We haven't deleted anything. Recon isn't the time to fix the house. It's the time to find out what's in it.

Now you know what's in the house. So step three is the most important step, and it's the one the rewrite always skips. Figure out what's actually load-bearing.

Because not every ghost is evil. That's the thing nobody tells you about haunted codebases. Some of the scariest-looking code in the system is scary because it's doing something really, really important, but really, really badly. The floorboard might be structural. The locked room might actually be where the money is.

And in my experience, this is the step where the mood in the room changes. Because the logs come back, and you find out that the floorboard function has a rounding rule for one specific country's tax law that nobody remembered and finance absolutely depends on. Or that one of those cron jobs is the only thing keeping two systems in sync.

That's not debt. That's a requirement that nobody wrote down.

But you have to check it first. Something the old system does is not automatically something it's supposed to do. Take the rounding rule to whoever actually owns the tax requirement and ask: is this the rule, or is this a bug that we've been living with? Because sometimes the ghost is protecting a regulation. Sometimes it's been getting the regulation wrong, very consistently, since like 2014.

Once the person who owns the rule says yes, that's it, then before anybody nukes anything, you get it off the planet. You write it down as a real requirement. You put tests around it, a test that says "for this country, round like this," with a comment explaining why. Now it's not a ghost. It's a feature, with a name and a witness.

Step four. Now, and only now, remove what isn't load-bearing. Slowly. Behind feature flags, with a rollout plan, one piece at a time.

If you've heard of the strangler fig pattern, this is that. You build a new path next to the old one, move traffic over a piece at a time, and the old path gets quieter and quieter until one day nothing calls it. And then you delete it.

The catch is the seam. You need a clean place to cut over, somewhere you can send a request down the old path or the new one and know which one handled it. And if both paths write to the same tables or call the same downstream system, decide who owns that data during the overlap. Otherwise, you haven't replaced a ghost. Now you've got two of them fighting over the same floorboard.

The best exorcism you'll ever run is the one where you delete something old and nothing happens.

Step five. Rename what you're keeping, and write down why.

If you decide to keep a column called do_not_use, rename it to what it actually is. If the function is called process_thing_v3, give it a name a new hire could guess. Renaming isn't cosmetic. It's a message to whoever comes next. It says this thing has an owner, and someone looked at it on purpose.

But please be careful about this. A better name is still a change. Rename a column and every report, job, and dashboard reading the old name breaks. And some of them belong to teams who've never heard of you. You already found the consumers in recon. So add the new name next to the old one, move everybody over, and retire the old name last.

Document the decision, not just the code. Not "this function calculates totals." The code already says that part, right? "We keep this rounding rule because of this tax requirement, and we considered removing it in October 2026 and didn't, because of this." That's the note that would have saved everyone a year of stepping around the floorboard.

A ghost is just a decision whose reasons got lost. Write those reasons down, and guess what? It's not a ghost anymore.

Now, as you can tell, I really like movies. So let's go back to Aliens, and the part of Aliens I think about more than any other. They never actually get to nuke it from orbit. Ripley makes the call, everyone agrees, and then the dropship, their only way off the planet, crashes before they can leave. So they're stuck.

And the colony gets destroyed anyway. Because during that first chaotic trip in, the shooting damaged the reactor's cooling system. Nobody decided to blow it up. The damage was already done, and the reactor went critical on its own schedule, not theirs.

That's the other way the nuke happens. If you don't decide, the reactor decides.

I've seen this. Heck, I've lived this. The team that never gets the time to clean up the haunted system, quarter after quarter. And then one day there's an outage big enough that leadership panics, and the rewrite gets approved overnight. Not as a plan. As an emergency, with a deadline and no recon, and none of the requirements nobody wrote down.

So the boring, careful work isn't just the alternative to the nuke. It's how you keep the right to choose the nuke, if it ever really is the answer.

And sometimes it really is the answer. I want to be fair about that. Sometimes you do the recon, and you find out what's load-bearing. You get those requirements off the planet with tests. You look at what's left, and the honest answer is: this whole thing needs to go. That's a legitimate call. Ripley was right. But it's a call you make with your motion tracker data, not with your frustration from the retro.

And then the last step of the field guide. Step six, the one I think matters most. Accept that some ghosts stay.

Not every haunting can be fully resolved. Some systems cost more to remove than to carry. Some of those cron jobs are doing something too important to touch right now. Some of the basement has to stay because a regulator says so.

That's okay. The goal is never a perfectly clean house. Nobody lives in one of those, as far as I know. The goal is a house where you know what you're living with.

The floorboard still creaks, but now it has a name, an owner, two tests, and a comment that explains the tax rule. When the new hire steps on it, nobody makes a sound. Somebody just goes, "Oh yeah, that's the rounding thing. Here's the doc."

That's what success looks like. Not silence. Explanation. A known ghost is not the same as an unknown one.

Tomorrow is Halloween, and I want to land this month somewhere honest. A haunted house is not a failure state. It's what happens to anything that runs long enough and matters enough. Every system was new once. Every house was built by somebody with good intentions, on a deadline, making the best call they could with what they knew.

The floorboard was a fix for a real bug. The cron job got a launch out the door on time. The trigger was a safety net from a careful engineer having a stressful week.

The ghosts aren't evidence that somebody failed. They're evidence that somebody was here and did something that mattered, and didn't get the time to write down why.

So this is your job now. Not to burn the house down. Not to tiptoe through it forever. Go in with that light. Find out everything that's load-bearing. Get that stuff off the planet. Let go of what isn't. Write down why, and make peace with the ones that stay.

And if, after all that, the answer really is nuke it from orbit, then you'll know. Not because you were tired in a retro, but because you went in and looked.

That's the only way to be sure.

That's this episode of Chaotic Commits. I'm Joanne Skiles, and if there's someone on your team who says "let's just rewrite it" in every retro, send them this one before the next retro. You know who it is. It might be you.

New episodes wherever you get podcasts. No highlight reel, just the commit history.