Work on a software project is often linear. Point A to point B. From bug to fix. From task to release. Of course, the process might be complex, with iterations, reviews, forks and branches. In the end, those are just the wheels of train taking the project to where it needs to be. Ideally, cards just speed across the kanban, left to right.
This kind of progress is easy to understand and measure: when the work is complete, the goal will be achieved.
Now let's consider a specific scenario: the urgent task. It could be a bug fix, an important client request. Whatever. We just need to get to Point B, now. Speed is important now, so we are willing to cut some corners.
This is where technical debt comes in. In order to accomplish our goal quickly, we incurred some technical debt: the corners that were cut. "I know this is bad, but we don't have time to do it right. We can come back to it..."
This is also where we run into a contradiction of sorts. Going from A to B was meant to make things better. And it did. The bug was fixed. The feature was delivered. That part is good, for the business, for the code base, for everyone. But in obtaining this positive result, we also made things worse. This is the contradictory part. How is it possible to improve the code while making it worse?
Just about anyone involved in software has observed a scenario like this one. It obviously happens, so if there is a contradiction, it's because our ideas about it need to be adjusted.
This is why concepts like "Technical Debt" and "Code Health" are important. And I would suggest that they require us to consider progress in two different dimensions. Let's go back to our arrows and points A and B.
Depending on how we accomplish the move from A to B, we will end up at a different place in the second dimension, somewhere between "Worse" and "Better".
"Worse" and "Better" refer to the state of the entire code base. "Worse" means that it will be harder, riskier, more expensive, to make the next changes, from B to C, for example.
Or, maybe we take our time and really try to do this right. As a result, we improve the code base along the way.
In both cases, we get to the destination. The bug is squashed, the feature is released, the problem is solved. The result of our actions is not the same, however. In one scenario, we've either made any future work more difficult, expensive or bug-prone. In the other scenario, it future changes will be more pleasant and less expensive; the code base will be easier to maintain. (Real life is more subtle of course, but you get the idea.)
So progress and improving or deteriorating the Code Health of your code, adding to or removing from your technical debt are not contradictory. They are two different dimensions of a single action. And this is why a tool like CodeScene can help, by providing a metric for this second dimension to your work.
Keep on reading! Find out how refactoring recommendations can be based on your own code.