Technical debt isn't debt. That's the problem.

"Technical debt" is the most comforting lie in software engineering.
It's a financial metaphor borrowed to make a bad decision sound like a strategic one. Real debt shows up on a statement, accrues a published interest rate, and has someone whose entire job is calling you when you miss a payment. Technical debt has none of that. Nobody sends a reminder. Nothing compounds on a visible schedule. The // TODO: refactor this comment doesn't get more urgent with age - it just gets older, sitting next to code nobody remembers writing for a reason nobody remembers having.
That's not a minor flaw in the metaphor. It's the entire mechanism by which the debt never gets paid.
Real debt has a lender. This doesn't.
When you take on real debt, someone else has skin in the outcome. A bank wants their money back, so they charge interest, set a due date, and report you to a credit bureau if you ignore them. That external pressure is what makes debt a functioning concept instead of just "spending money you don't have."
Technical debt has no lender. The quick fix you shipped under deadline pressure doesn't send you a statement. Nobody calls. The only thing that eventually collects is an incident, months later, in a file nobody's touched since - and by then it doesn't look like debt coming due. It looks like a mystery. "Why is this broken?" "No idea, it was like that when I got here."
The connection between the shortcut and the outage gets lost, because nothing in between ever made the cost visible.
Debt you can see gets paid. Debt you can't see gets inherited by whoever's on call at 2am.
"We'll pay it down later" is a promise with no enforcement mechanism
Every team has said it. Nobody has a system that makes it true.
"Later" isn't a sprint on the roadmap - it's a direction, and directions don't have deadlines. The next sprint has its own deadline pressure, which produces its own shortcuts, which get their own "we'll fix it later." The debt doesn't get paid down. It gets refinanced into next quarter, forever, at zero cost to anyone making that call today.
This isn't a discipline problem. It's a structural one. A metaphor that borrows the language of finance without any of its enforcement - interest, due dates, credit scores - was never going to produce financial behaviour. You get exactly the outcome the incentives support: everyone agrees debt is bad, and debt keeps growing, because agreeing it's bad costs nothing and nobody's the one who actually has to stop and pay it.
Debt implies a choice. A lot of this is just decay.
The financial framing smuggles in another comforting idea: that shipping the shortcut was a deliberate trade-off, weighed and chosen, the way a company might take on debt to fund growth.
Some of it is. Most of it isn't.
Most technical debt isn't a decision at all - it's decay. Code that was fine when it was written and got worse by accumulation: one more special case, one more any type to make the build pass, one more copy-pasted block because refactoring the original felt riskier than duplicating it.
Decay doesn't announce itself as a choice, and it doesn't wait for you to acknowledge it as debt before it starts costing you. The broken-windows effect is well documented in codebases for the same reason it's documented in neighbourhoods: one unrepaired thing signals that unrepaired things are normal here, and the next person adds to the pattern without a second thought. Nobody decided to borrow. Somebody just didn't fix the first window, and now the whole block looks like that.
Calling it "debt" implies intent. Calling it decay is more honest, because decay doesn't need a decision-maker - just neglect.
The reason it never gets measured is that it's never been a number
Ask a team how much technical debt they're carrying and you'll get one of two things: a shrug, or a Jira label with 340 tickets under it that nobody's prioritised in a year. Both answers communicate the same thing: "we don't actually know."
Compare that to asking how much money a company owes. Any competent finance team answers that in one sentence, because debt as a financial concept has always been measured. Technical debt, as most teams practice it, has never been measured the same way. It's a feeling, distributed unevenly across the people who've been burned by specific files.
A feeling can't be gated. You can't set a CI check that fails when the vibe gets worse.
That's the actual gap - not that teams don't care about code quality, but that "code quality" has historically had no number attached to it that means the same thing on Monday as it does eight sprints later. Iris Code scores every file - complexity, security smells, secrets, dependency risk - into a number that means the same thing regardless of who's looking at it or how the sprint felt. Once debt has a number, it stops being a mood and starts being something you can actually track going up or down.
A credit score for code, and a lender who actually calls
The missing piece in the debt metaphor was always the lender - something with an interest in the outcome that isn't just "future you, who is busy."
Iris Code's trend tracking plays that role: it snapshots your workspace score on every scan, so "did this get better or worse" stops being a memory exercise and becomes a chart. Baseline mode goes further and acts like an actual due date - lock in where you are today, and every push after that either holds the line or improves it.
Existing debt doesn't block you. Forcing a team to pay off years of decay before shipping anything new just teaches them to disable the check. But nothing new gets to compound, because the gate catches it the moment it happens instead of eighteen months later when it's someone else's incident.
That's the difference between a metaphor and a mechanism. A metaphor tells you debt is bad. A mechanism tells you, on this specific push, whether you just added to it.
| Layer | Tool | What it enforces |
|---|---|---|
| Editor | Iris Code sidebar | Visible cost at the moment it's created |
| History | Trend tracking snapshots | Whether the codebase is actually improving |
| Enforcement | Baseline mode + gate rules | A due date for new debt, none for old debt |
Technical debt was never going to pay itself down as long as it stayed a metaphor - unmeasured, uncollected, someone else's problem by the time it mattered. Give it a number, track the number, and gate on the number, and it stops being a story your team tells itself about being busy.
It becomes something you can actually watch go down.
Iris Code scores every file on save.
Get per-file health scores, security smell detection, and enforcement rules - directly in VS Code. Free to start, no account required.
Install the extension →