Engineering

Why most technical debt is a decision, not an accident

Editorial · Reveneau · November 5, 2026

Why most technical debt is a decision, not an accident

We have sat in the meeting where a team decides to skip the edge case. Not by accident: out loud, in a stand-up or a pull request thread, someone says "we don't have time to handle that properly before the deadline, let's ship the simple version and come back to it." Then the deadline passes, the team moves to the next thing, and six months later somebody finds the gap and calls it "technical debt that built up over time." It did not build up. It was chosen, on a specific day, by a specific person, for a specific reason. The problem is not that the choice was made. The problem is that nobody wrote it down.

That distinction matters more than it sounds. Here is the short version of what changes when a team treats technical debt as a decision instead of an accident:

The metaphor was never about sloppiness

The term "technical debt" comes from Ward Cunningham, a software engineer who coined it in the early 1990s while explaining to his manager why a financial application needed rework. His point was narrow and specific: it is fine to ship code based on your current best understanding of a problem, the same way it is fine to borrow money, as long as you know you are borrowing and you plan to pay it back. He was not describing rushed or careless work. He was describing a deliberate tradeoff between shipping now with a simpler model and shipping later with a fuller one.

Somewhere between that original idea and how most teams use the phrase today, the deliberateness got lost. "Technical debt" turned into a catch-all label for anything unfinished, confusing, or hard to maintain, whether or not anyone chose it on purpose. That loss of precision is the actual problem. A team cannot manage what it cannot name correctly, and calling every kind of unfinished work "debt" makes it impossible to tell which parts were a real, knowing tradeoff and which parts were just a mistake nobody caught.

Deadline pressure is the real cause, and developers already know it

We do not need to guess at this. In Stripe's 2018 Developer Coefficient survey, which polled more than 1,000 developers and more than 1,000 C-level executives across the US, UK, France, Germany, and Singapore through Harris Poll, 79 percent of developers said that not being given sufficient time to fix poor-quality code has a negative impact on their morale. Another 79 percent said the same about changing priorities that result in discarded code or wasted time. These are not developers complaining about a mystery force called "debt." These are developers describing a decision that was made above them, under time pressure, that they had to live with.

The same survey found developers spend an average of 13.5 hours a week addressing technical debt, out of a 41.1-hour work week. That is not a rounding error. That is a third of a work week going toward paying interest on choices that were, in most cases, made under a deadline by someone trying to hit a date. The debt did not appear out of nowhere. It was the price of a decision that got made in a hurry and then forgotten.

Naming the tradeoff at the time changes what happens next

Here is the mechanism, stated plainly: a decision that is named when it is made can be evaluated later. A decision that is never named cannot be evaluated at all, because nobody remembers it was a decision.

If a team writes down, at the moment they skip a validation check or ship a simplified version of a feature, exactly what they skipped and why, that note becomes something the team can act on. They can revisit it on a schedule. They can weigh whether the deadline that justified it was worth the cost. They can decide, with real information, whether the shortcut is still acceptable six months later or whether it has quietly become the reason a customer hit a bug. None of that is possible if the shortcut just disappears into the code with no record.

Compare that to what actually happens most of the time. The shortcut ships. The deadline is hit. Everyone moves to the next project. Nobody writes anything down, because writing it down feels like admitting the work is not finished, and nobody wants to say that out loud during a crunch. Then, later, someone finds the gap, and it reads exactly like a mistake, because there is no evidence it was ever anything else. The team spends time reconstructing a decision that already happened once, badly, the first time.

The responsibility splits two ways, and both sides have to hold up their end

A developer who takes a shortcut without saying so is hiding information the team needs. A manager who sets a deadline without asking what got cut is asking for a result without asking what it costs. Both failures look the same from the outside: a gap in the code that nobody can explain later. But they need different fixes.

The developer's job is to surface the tradeoff, not to make it disappear. That can be a line in a pull request description, a short comment at the point in the code where the shortcut lives, or an entry in a shared list the team already keeps. It does not need to be long. It needs to exist, written by the person who made the call, at the time they made it, not reconstructed from memory afterward.

The manager's job is to actually hear that tradeoff and decide, knowingly, whether it is worth the deadline. That sounds obvious, but it rarely happens, because most deadlines are set before anyone knows what shortcuts they will require. The fix is not to stop setting deadlines. It is to build in a moment, even a short one, where the team says what will not get the full treatment, and someone with the authority to accept that risk actually accepts it out loud.

Automated checks turn a named tradeoff into a tracked one

This is where an eval suite, meaning a set of automated checks written from the specification before code ships, earns its place in the process. Two different things happen once that check exists.

First, it catches the debt nobody chose on purpose: the edge case that was missed because the spec was unclear, not because anyone decided to skip it. That is not a tradeoff. That is a gap in understanding, and a check that runs against the real specification finds it before a customer does.

Second, for the debt that was chosen deliberately, a check tied to the skipped requirement keeps the tradeoff visible instead of letting it fade. If a team knowingly ships without handling a rare input format, a check that fails on that input, clearly labeled as "not yet handled, tracked in [ticket]," keeps the decision in front of the team on every future change. It stops being a fact only one person remembers. It becomes a fact the whole pipeline remembers.

In the work we do, that is the actual difference between debt that gets managed and debt that gets forgotten. The check does not remove the need for judgment about which tradeoffs are worth making. It makes sure the tradeoff stays a decision the team can revisit, instead of quietly becoming a mystery six months later.

What this means for the next deadline

The next time a deadline forces a shortcut, the fix is not to avoid the shortcut. Sometimes the shortcut is the right call. The fix is to say so, in writing, at the moment it happens: what got skipped, why, and what it will cost if it is left alone. That single habit is worth more than any backlog-grooming session aimed at a pile of debt nobody can explain.

Thanks to the engineers who have talked us through their own backlogs and were honest about which items on them they actually remembered choosing. Most could not say. That gap, more than the debt itself, is the thing worth fixing.

Debt you name is a plan. Debt you do not name is just a surprise waiting for a date.

Sources

Common questions

Is technical debt always bad?

No. Technical debt is a tool, the same way a financial loan is a tool. Taking the faster, less complete path to hit a real deadline can be the right call, as long as someone names the tradeoff at the time and the team has a plan to pay it down before the interest (the ongoing cost of working around the shortcut) gets too high.

Why do teams treat technical debt as an accident instead of a choice?

Because naming a shortcut as a shortcut in the moment feels like admitting the work is not finished, and nobody wants to say that during a deadline crunch. It is easier, in the moment, to just ship and move on, which is exactly what turns a visible tradeoff into an invisible one that shows up later with no record of why it exists.

Who is responsible for technical debt: the developer or the person setting the deadline?

Both, but the responsibility splits differently than most teams assume. The developer is responsible for surfacing that a shortcut is being taken and what it costs; the person setting the deadline is responsible for hearing that tradeoff and deciding, knowingly, whether the deadline is worth it.

How do you tell the difference between technical debt and just bad code?

Technical debt is a shortcut taken knowingly to meet a real constraint, with a plan to revisit it. Bad code is a shortcut nobody chose on purpose: it is what happens when there was no deadline pressure at all, just an unclear spec, no review, or no automated checks to catch the gap before it shipped.

What does "naming the debt" actually look like day to day?

A short, written note at the point the shortcut is taken: what was skipped, why, and what it will cost later if it is not revisited. It can be a comment in the code, a line in the pull request description, or an entry in a shared tracking document, as long as it is written by the person who made the tradeoff, at the time they made it.

Does an eval suite (automated checks written from the spec) help with technical debt?

Yes, in two ways. It catches the debt that is not a deliberate tradeoff, the gaps that come from an incomplete spec or a missed edge case, before they ship. And for debt that is chosen on purpose, a failing check tied to the skipped requirement makes it visible on every future change instead of disappearing into the code.

Should every technical debt tradeoff be written down, even small ones?

The ones worth writing down are the ones that trade correctness, security, or a real edge case for speed. A naming convention you are not thrilled with is not technical debt in the sense that matters here; a validation rule you skipped because the deadline did not allow time to build it is, and that is the kind of decision that needs a record.

What happens when technical debt is never named at the time it is created?

It becomes indistinguishable from a mistake. Six months later, nobody remembers whether a gap in the code was a deliberate tradeoff under a real deadline or a bug nobody caught, so nobody can judge whether it is safe to leave alone or urgent to fix, and the team ends up either fixing things that were fine or ignoring things that were not.

Does this apply to AI-generated code as much as human-written code?

It applies more, because the tradeoff happens faster and is easier to miss. When a team asks for a feature quickly and accepts the first version that passes a quick check, the decision to skip a fuller implementation still gets made, just without a person visibly typing the shortcut, which makes it even more important to write the tradeoff down at the time.

How does Reveneau handle technical debt in the work it does?

In the work we do, we treat a knowing shortcut as a recorded decision, not a silent one: what was skipped, why, and what check would catch it if it becomes a problem. Because every change has to pass an eval suite written from the specification before it ships, a shortcut that skips part of the spec shows up as a named, tracked gap rather than an invisible one.