The concept of technical debt is important because it acknowledges that development is an ongoing process of accumulating knowledge and adapting to changing circumstances.
Almost Martin Fowler (hallucinated by chatGPT from the present article)
Engineering power should be optimized for tech debt.
Writers think in and by writing, coder by coding, PM by working out product feature, and a whole company by trying things. It's not a result, it's the process itself. On the contrary, the projected result often shifts during the execution.
Early release, short feedback loop, fast fail. By publishing quickly we are able to understand what we want to build, what are its challenges. Implementations hit dead end or unseen blockers. Products adapt to the discovered consumers and market demands. Startup pivots.
By the mere fact of producing something, its requirements, environment, constraints, change. In the very process of building software lives the growing misalignment and the necessity to address it.
This is tech debt. In the broader sense of technical work that is not immediately understood contributing to new features. The cost of misalignment, however, are very well understood - slower developments, drop in quality, higher risk of bugs, and a longer time to fix them. There is a human cost as well, with engineers attrition, churn, and eventually a dreaded codebase no one knows how to maintain.
This is not tech debt, however, as it's not the result of a trade-off between quality and speed - it's not a choice, neither is it something that could have been worked out by being more, smarter, engineers.
It's the shadow projected by the crafting of software itself. Initial adaptation, from nothing to something, is called feature. But it's the same process that needs to be done over and over as the shape of what we do changes, and forces other shapes to change in the process. Once a software lives it breathe tech debt. It's not a bad thing, it's a structural one.
Fighting against it as a necessary evil, or completely ignore this reality is very dangerous for the teams and their software that tries to stand the test of time.
The question then becomes - how can this realization serve as a strong foundation ? I don't have a comprehensive answer to offer, but some leads come to mind.
Late architecture from the start : choosing tech and architecture that allows for fast refactoring. This is an article on the concept with a functional angle (but it applies to any paradigm)
Practice a constant brainstorming in order to surface system misalignment. Misalignment can be internal, toward the product and features, or towards other systems and interfaces. This should become a game, an art, a creative process. Creating (inventing, surfacing) tech debt.
Organize team culture around a builder attitude, bold initiatives, fast refactoring raids. Few things are more deadly to a codebase than the tired feeling that refactoring is going to be too much/too slow/too complex and that it has to be done "rogue" not to clash with management objectives.
Un-taboo rewriting from scratch as it's never from scratch - experience is gained on product and ecosystem. It can be a perilous bet, but sometimes the discussion needs to happen.
Have people around that are used to this (architects, staff engineers, senior engineers) and give them more power on the team's planning. With the experience, they built the intuition of what's wrong, and usually clear path on how to make it better aligned. They are also more prone to express themselves and negotiate the team's time with other forces (product, stakeholders, etc...)
Those elements are usually found in crafter centric culture, and it's no surprise that management oriented companies struggle with software adaptation. Maybe this is one of the reasons why small startups might be competitive against big companies in shifting environments - they can optimize for adaptation ?
It is said that writing is rewriting. Engineering, in the long run, is refactoring. We should optimize for it from the start.