- "Technical debt" (usefully) divorces the idea of implementation velocity from business outcomes. You have a thirty year old system written in a language barely anyone understands anymore; but, its still generating profit for the business. This is technical debt; its "useful" to separate from business outcomes because it enables you to consider it as one factor, among many, to overall business outcomes, rather than prematurely co-mingling the two ideas.
- Similar to the generality "all code is technical debt" I'll make one of my own: "All technical debt is abstraction assumption failure". You've got an abstraction; you assume it behaves some way; it doesn't. You've got an abstraction; you need to add new functionality behind that abstraction; you assumed this is a good place or a good way to add this functionality; it isn't. The vast majority of technical debt is just this. There may be a couple more categories like "we can't hire people to work in this language" or even something like system performance, but the vast majority of technical debt is a failure of understanding of some abstraction.
- That previous statement does not assert that this is an invalid way of viewing technical debt. "Understanding" the code is literally the most important job of software engineers; less "engineer" and more "museum keeper" sometimes. I've never liked the term "bad abstraction" because it shifts the responsibility of being understood to the abstraction, and not the engineer. It encourages "code bad, rewrite" mentality. Sometimes that is the best course, but I think its always a bad idea to tackle that without understanding the abstraction, and if you understand the abstraction then you probably wouldn't be calling for a rewrite because its "bad"; you'll be calling it for more specific reasons.
- Unilaterally classifying all code as technical debt isn't just wrong; its asinine. "Technical debt" is a useful way of thinking about some code; if you remove that from your lexicon, you may start believing that all code either is or isn't technical debt. If all code is technical debt, your ability to think about the quality of code holistically, with its nuance, is reduced durastically. If you think no code is technical debt, you'll inevitably walk down the path of hyper-engineering perfect giga-systems that, even if they work flawlessly and satisfy all business needs, took way too long to build, cost way too much to run, and inevitably still confuse your replacement in six years.