Building
Building · ◉ Evergreen

The reversible MVP that quietly became load-bearing.

by · ·4 min·Working Theory

Reversibility isn't a property of the thing you built — it's a property of how many other things now depend on it, and you don't control that number. The discipline for catching the moment your stopgap stopped being temporary.

Every team has one. A script someone runs by hand on the first of the month. A Google Sheet that three dashboards secretly read from. A hardcoded list of “supported regions” that was supposed to live two weeks until the real config system shipped. None of these were built to last. That was the whole point — they were temporary, so you cut the corners on purpose. No tests, no migration path, no error handling worth the name. “Temporary” was the permission slip that let you move fast.

And then the thing worked. People used it. People built on top of it. And now it’s eight months later and that hand-run script is in the critical path of your billing, and nobody left on the team remembers it was supposed to be thrown away.

Here’s the uncomfortable part: nothing changed. The script is exactly as fragile as the day you wrote it. What changed is everything around it. You labeled it reversible, and then a hundred small acts of other people’s trust made it irreversible without asking you.

That’s the trap worth naming. Reversibility isn’t a property of the thing you built. It’s a property of how many other things now depend on it — and you don’t control that number. Your teammates and your users do, every time they wire one more process through your stopgap. A piece of code becomes load-bearing not when you decide it’s important, but when someone else’s work breaks if yours does. With enough dependents, every behavior you shipped — even the accidental ones, even the bug you never fixed because “it’s temporary” — becomes a promise you’re now quietly obligated to keep.

The debt here is sneaky because it doesn’t come due when you take it on. The day you write the throwaway script, the corner-cutting is genuinely fine — it really is temporary, in your head. The debt comes due later, on the day someone bets their feature on it. And by then the justification (“it’s just temporary”) has quietly expired while the artifact kept running.

So what do you actually do? Not “never build stopgaps” — stopgaps are how 0→1 works. The discipline is narrower than that.

Watch dependence, not the roadmap label. Your plan says “temporary.” That tells you nothing. The real signal is the first time someone else’s thing breaks when yours hiccups — the first support ticket, the first “hey, is the regions list down?” That’s the moment the label stopped being true, and it almost never coincides with a planning cycle.

Put the expiry on the thing, not in your memory. A genuinely temporary artifact has either a real kill date with a named owner, or an explicit trigger: “the moment anything in production reads from this, we harden it or replace it.” A “temporary” thing with no expiry mechanism isn’t temporary. It’s un-hardened permanent infrastructure that nobody has admitted is permanent yet.

Keep the throwaway actually throw-away-able. A true stopgap is one nobody can build on — it lives behind a flag, on a branch, as a manual process you deliberately don’t document as an interface. The instant you document it, publish its shape, or let a second system integrate with it, you’ve converted it into load-bearing infrastructure. Documentation is adoption’s on-ramp.

And when it does cross the line, pick a side. Either fund it — stop apologizing for the script and give it the tests and the owner that load-bearing things deserve — or deprecate it on purpose, with a real replacement and an overlap window. What you must not do is leave it in the limbo where it’s simultaneously critical and unowned. That limbo is where outages are born, usually at 2 a.m., usually on a holiday.

deps time → load-bearing threshold roadmap label: “temporary” (never moves)

actual dependence

harden it — or kill it — here (not when the plan says so)
The gap that bites: the label stays flat at “temporary” while real dependence climbs past the line. The crossing — not the roadmap — is the deadline. Original diagram · Working Theory

“Temporary” is a prediction, and predictions you make about your own code skew optimistic every single time. The reversible MVP doesn’t become load-bearing through a decision you could have reviewed. It becomes load-bearing through adoption you weren’t watching. The senior move isn’t avoiding the stopgap — it’s catching the exact moment the label stops being true, and changing the thing, or changing the label, before the pager changes it for you.

Liked this? Get the next one in Working Theory.

Going weekly in August (it's in beta now). One genuinely interesting read on building, the brain, and the science most people missed.

Subscribe →
Got a reaction, a counter-example, or something I missed? Reply by email — I read everything.
◉ join in

Where have you hit this — in a product you use, or one you're building?

Threads open here soon. For now, the conversation lives two clicks away — discuss on GitHub, or just reply by email. I read and answer everything.