Conditional Nature of Technical Debt

Ipek Ozkaya gives a typical, representative example of a Technical Debt accumulation case in “Does principal really exist in technical debt?”: a project development team selects a particular application framework at the start of the project and while going deep into the implementation phase realizes the framework does not fit part of the project needs and/or causes redundant work to mitigate framework related risks or compensate of its deficiencies. The question arises: should the framework be replaced or kept in place given the amount of work to replace it including functionality rework, integration, learning efforts, risks introduced by the new framework selection, etc.

Let us look at the possible root causes of the technical debt at hand located at the early stage of the project when the framework selection is originally done:

  1. Functionality to be developed on top of the framework is not sufficiently defined by the analyst, product owner, UX designer.
  2. Relevant quality attributes such as maintainability, performance, interoperability, maturity, and other ones important for framework selection are not well understood.
  3. Important constraints such as familiarity of the framework to the team or overall level of competence/ability to work within provided features, patterns, and paradigms, and others are not accounted for.
  4. The framework is selected without proper consideration of the above architectural drivers, or driver prioritization is not done right, or drivers contradict to each other too much. Frequently, simple prototyping or even involvement of a knowledgable expert might have prevented a poor choice.
  5. Even if the above drivers are collected, analyzed, and the best effort is made to select the most fitting framework the market state does not allow to choose the framework accommodating all of the high priority drivers. Such a framework might not exist or have prohibitive licensing terms, etc.
  6. Finally, the nature of software development business might cause requirement changes in such a way the framework cannot properly address anymore. For instance, the approach to UX is changed so much it does not match patterns supported by the framework anymore.

In practice, some or all of the items in this range might happen and critically affect the framework choice. Retrospective analysis can often reveal which of them had a place in reality. The main point here is that poor framework selection is an objective event and at the same time calculation of the attached Principal is conditional. What should it include:

  • Reluctance to allocate a business analyst for two weeks to analyze system requirements?
  • Decision to save money on the licensing fees for the optimal choice and to go with the suboptimal open source candidate?
  • 2 days unspent on the deeper verification of the framework candidates and prototyping for them?
  • Incompetence of the involved architect who selected the framework based on “Coolness” instead of “Maturity”?
  • One of a thousand of other possible reasons to make a bad decision?

Next, development starts and technical debt starts invisibly mounting with each new piece of code developed on top of the selected framework. The further the dev team goes into work the more apparent the issues grow and the more effort it would potentially take to re-make the decision did the team decide to do so. When does the “first responsible moment” happen, the moment when the evidence of the poor choice becomes visible and the amount of technical debt is not too high to pay it in full?

Lastly, at a certain point of development timeline the decision maker is faced with two strategical options:

  1. Replace the framework and refactor the system implementation accordingly.
  2. Keep the framework and learn to work around its deficiencies based on the already acquired practical knowledge of its internals and peculiarities.

In the first case we would obviously include into technical debt estimation much of the effort spent on the original implementation and all the effort to reimplement it for the framework replacement. One additional contributor is higher risks associated with making a new ground breaking architectural decision so late into the development and close to the release.

In the second case we do not include the second type of effort and should be more careful with the first part. Likely we would only count extra effort we have not had spent on implementation if we had chosen a different (reference) framework from the very beginning. We would also pay this debt differently from the first case.

Hopefully, this discussion shows we can hardly speak of Principal and Interest associated with technical debt as single values or simple time-dependent formulas. They are rather complex functions of multiple variables, some of them being subjective.

In this context I see the technical debt framework, most significantly, as a decision support toolset which allows estimating and comparing technical debt variants based on the combinations from space of the variables like above.

Does principal really exist in technical debt ?

Ipek Ozkaya
Feb 5, 2016

The inability to conceptually and quantitatively clarify how to map financial concepts captured powerfully within the financial debt metaphor to software hinders our progress in research and application of technical debt in practice. In particular, there is increasing conceptual mismatches in articulating and calculating interest. Consequently, the tendency to equate any code quality issue that a static analysis tool may find to the principal or interest of technical debt in the software realm puts us on the wrong path.

In this note I will map interest and principal to their economic foundations and argue that a fine tuned quantification of technical debt requires defining their counterparts, in some cases completely dispensing them. Let us start by recalling the financial definitions:

Debt – in its simplest form, a financial debt is an obligation to repay an amount you owe. Repaying the amount means repaying the principal and the accrued interest.

Principal – initial amount borrowed

Interest – money paid at a rate or as a fixed amount for the use of money lent

Interest rate – the percentage of the principal to be paid, often regularly until the debt is paid back in full, as compensation for the loss of the initial borrowed amount value

Variable interest rate — an interest rate that fluctuates over time

Period – duration that the debt is paid back, hence interest is calculated against.

Steve McConnell’s technical debt definition has been the one that stuck with the community; a design or construction approach that’s expedient in the short term but that creates a technical context in which the same work will cost more to do later than it would cost to do now. Cost more is a proxy for the interest. What we are borrowing, the thing that we have an obligation to repay, is the construction approach often referred to as a short-cut. We are committing to “pay that back” by calling that approach “technical debt”.

In the literature there are two classes of technical debt quantification, repayment strategies if you will, exist.

Lump sum repayment – Lump sum repayment typically takes a code quality lens. This approach looks at the entire software and equates all the code quality violation found as technical debt principal and interest. While there is acknowledgement that all issues found are not of equal importance, the resulting lump sum quantification does not provide enough context for project managers or team members to decide how to respond.

Variable repayment – Variable repayment focuses on the rework, accumulated rework as often referred to. What is quantified for recognizing the accumulated rework are measures related to maintainability, such as defect proneness, time to add new issues in addition to redoing the initial design approach. This approach differs from the lump sum repayment as it scopes the conditions of the debt. The ideal repayment strategy here is doing the rework as soon as possible, i.e. pay back the principal, to avoid interest, i.e. additional defects. This approach assumes that the cost of required changes can be bucketed cleanly as rework of the original design + eliminating the side effects.

In financial debt, the consequences of just paying the interest is never getting out of debt. Principal in software has a very short span, it is only applicable during decision making. I argue that we never pay back the actual principal in software, we only deal with reducing or eliminating interest and principal gets factored into that activity. One-to-one mapping of the principal is often not feasible. Software changes, but not in the form of a backwards looking lens as in financial debt where when we borrow 5K we pay back 5K + the interest. Consider the following example, in a recent project that we studied the development team did not understand the requirements well enough and picked a UI Framework that was not best suited for the project. After several months of development it finally came to a state where they had to spend more and more of their time trying to figure out the root causes of the odd behavior of the UI framework that they did not foresee. Driven by this problem they decided to step back and rearchitect the UI framework, but since a significant amount of functionality had already been built they also had further knowledge about their expectations from a UI framework and picked a solution that they would not have gone with to start with in the first place. They definitely had technical debt and significant rework, but there is probably not much value in capturing it as principal + interest when they are in a position to make the rearchitecting decision. Given a one-to-one mapping does not exist, philosophically arguing principal quantification and articulation sets us back.

I argue that the goal of any effective technical debt management strategy is to reduce or eliminate the variable interest of technical debt, not pay back principal. Consequently, interest takes three forms and different quantification approaches are required for each:
1) Visible interest: interest already accumulated and currently visible
You have some code clones: a developer did some “cut-and-paste-and-modify” of a fragment of code, about 20 times throughout the system. But the software works fine. Identified classes that are highly coupled through a code analysis tool is also a form of potential visible interest.

2) Probabilistic interest: possible future interest (accumulation) that builds-up if the issue is not fixed.
In our example above, the UI framework has unanticipated behavior, but you have implemented it already and made it work one way or another. The question is what is the likelihood that as the system continues to evolve this behavior will cause other issues and will the team be able to continue development around it.

3) Sweeping interest: the design related added cost as a result of remediation (.e.g. removing additional patching)
If we decide to change the design we need to change the code clones in all of the 20 places (as articulated in #1 above) each of which may require additional design fixes, and create a utility to call the code from a single location. Or in the example in #2, if we decide to change the UI framework we need to ensure that we not only cleanly introduce the new framework and but ensure not to leave any of the workarounds related to fixing the odd behavior.

Cost of remediation does take into account principal. But since we have already established that it is most likely not the same work as the initial decision cost of remediation comes down to the following:

Cost of remediation = work on (sweeping interest + visible interest + new design)

Let us also take a look at the period, duration the debt is paid back and during which interest accumulates. In finance the period of the debt has an influence on the accumulated interest. The longer the period the higher the interest. In technical debt this too is probabilistic, the lower the probability of the changes executing the debt area, the lower the impact of the period.

Not all technical debt accumulates all of the three interests. By articulating technical debt in terms of these three kinds of interests as a starting point concrete payback and quantification strategies can be articulated. For example in the examples above, the visible interest is low because the software works, so the developers should evaluate the probabilistic interest. If for example they have only occasionally new features requiring changes in the cloned code, and when that occurs it is in one of the areas only they may articulate the probabilistic interest to be low, hence decide postpone remediation. In a different scenario, if the developers find that new changes push them to create new clones of the same code, adding to both visible and probabilistic interest, remediation may need to be done.

Solely focusing on interest and its probabilistic and deterministic forms can allow us to better take advantage of existing tools and develop an economic model for technical debt quantification and communication.

Technical Debt Management

Sorry for posting so late in this blog. But one of the advantages of being late is that I could read all the previous entries. I’d like to pick up the thread Carolyn initiated (on Feb 11) on the “decision what TD to manage”

As an architect working most of my time in industrial product development (at Siemens) a thoughtful decision on what TD to manage is really essential to balance the need between delivering a viable product (release) with useful, market-competitive features and the demand for industrial-grade design and code quality. Herb Sutter expressed this “conflict” well: “Features are your asset, Code is your liability.” In real-world development TD is always present, due to reasons noted by various authors in this blog and the literature

  • The (conscious) decision to trade quality for speed – and, therefore, the need for a later refactoring (Ward Cunningham’s original motivation for the TD metaphor)
  • Wrong or unsustainable design and technology decisions, or to end-of-life of chosen technologies
  • Changes in requirements and business cases are not addressed in existing design and code
  • Process-Quality Paradox: processes are designed to bring discipline to development – but at times they can lead to situations that can decrease quality
  • Architecting by Osmosis (see Damian’s blog post)

TD is also not necessarily a consequence of bad decision making or neglecting the need for action if consciously taken! For instance, a design and technology decision by itself might be highly viable, but if the project team does not have the skills to understand, use, or implement it correctly, debt likely occurs. Often this fact is noticed first time when the system is already under implementation. As another example, long-living systems regularly experience significant changes in requirements or even their business case. What was a sustainable design and code before is insufficient and a debt after such changes.

Putting the analysis of TD root causes aside for a moment, management of technical debt is a continuous activity performed by architects. Continuous on an almost day-to-day basis. This puts the following four requirements on any TD management environment

TD identification and assessment must be performed to a large extent automatically and daily. As an architect, my job is to guide development each and every day – thus I need a daily overview of all concerns of architectural interest, which includes the current state of TD in the system. The blog post by Andriy Shapochka (Technical Debt Evaluation in the context of Architecture Assessment) suggested addressing TD in the context of architecture evaluations. While I am an advocate of regular architecture evaluations, and also support Andriy’s suggestion to make TD an explicit concern in such evaluations, they are too much ritual for day-to-day support. As such they are an important, but complementary guidance for TD identification and management. Fortunately, there are a lot of (open source) tools out there that do the job. They may not be perfect, but they are good enough for practical application (perhaps after some configuration and additional plug-in development)

Identified TD must be put automatically into the working context of development to decide where in the system it is of value to manage it. Knowing what TD is present in the system, and where it is present in the system is only one side of the coin. The second side of the coin is a suggestion of which TD to address. For instance, if there is heavy TD in a module that is not touched at all in the current release but is of sufficient functional and operational quality, I actually do not care. On the other hand, if TD is in a module that experiences many code changes due to feature development, there is need for action, since the TD may hinder feature development progress and quality. Note that this activity is not about TD prioritization, but about general TD management (see Carolyn’s posts). Ideally, the metrics that give me this information are simple and meaningful for an architect. For instance:

  • TD occurs in modules to be touched when realizing the user stories of the next increment / release
  • TD occurs in areas where technology changes are planned
  • Current coding activities in a module are to a large extend refactoring and scaffolding rather than real feature extensions (noticed by a lot of code move, remove, change activities)
  • Current coding activities in a module spread out or ripple through to other modules far too often
  • Increased coding activity is in architectural sensitivity and trade-off points
  • Getting (unit) tests to green appears to be tricky, requiring multiple iterations of code changes in a module

A lot of techniques can be used for this purpose – mainly based on software analytics. Coding activities are analyzed regarding their nature (e.g., extensions, changes, refactoring) and quantity, and related to architectural, technology, and quality concerns of interest. Both for the concerns of interest of the current increment / release in particular, but also for the upcoming increments / releases in general. In the end architects get advanced support to decide where it is of value to actually address TD.

TD to manage must be prioritized according to concrete increment / release goals. Once it is known in what modules of a system to address TD it is necessary to prioritize the TD observed in these modules. This prioritization should be in direct support of concrete TD pay-off goals for the current or next increments / releases. For instance, the integration of new functionality into the system, or the replacement of an outdated / no-longer-available technology. If, in a given context, certain TD causes rippling effects to other modules, it is likely of higher priority than TD that stays internal to the module. TD in module areas that are hard to get stable or modified to prepare for upcoming functional extensions is likely of higher priority than TD in module areas that are only moderately changed during an increment or release. Several blog posts are already addressing TD prioritization, so I am sure there is a wealth of techniques available to address the prioritization question.

Measures to address TD must balance effort and value. In my personal experience, technology-oriented people tend towards perfectionism, seeking for measures to fully resolve a technical debt. Despite the fact that I doubt this is possible in an agile world where requirements and technology is in constant flux, it is definitely not economic. TD was originally coined as a metaphor that connected technical with financial concerns. As software project business is – to a large extent – driven by financial concerns, a pure technological view is not helpful. What if, for example, a perfect resolution of an identified high priority TD is not achievable in the given timeframe for the next release? Just starting and stopping (for a short time) at the release date is not an option.

More important is the ability to deliver a stable, working solution, regardless of how much TD is in it. Being able to deliver on time, on functionality, and on quality may from a purely technical perspective, therefore, require “compromises” in the TD resolution measures. In my IEEE software article on management of technical debt I discussed situations where from a project perspective it was better to pay the interest than resolving the debt. Most interesting was a project, where a “debt conversion” was the best choice. The existing technical debt was not properly resolved, but addressed by a measure that was “cheap” and “doable” in time, but targeted at the symptom and not the root cause of the TD. This was necessary to meet the contractually defined delivery date of the system. From the perspective of TD management the debt conversion “bought” the project team time to address the TD properly, at the expense of some “interest” — which was visibly lower than then the original interest, but still big enough to not neglect the TD in future releases.

 

For a sustainable TD management, it is also important to understand and address the root causes of TD. As said above, there will always be TD in a system. Part of the TD handling is TD management (as above) but equally important are measures to minimize TD:

  • A paper I recommend to read in this context is “Software Process versus Design Quality: Tug of War?” that discusses the dependencies of process and quality / TD.
  • Other research is in the direction of architecture styles and patterns that minimize TD or the effect of TD on an entire system. For instance, the larger the system, the more likely TD will occur, and the more chances are that a specific TD spreads across the entire system. Microservices are probably the most widely known architectural, developmental, and organizational approach that has a positive effect on TD. Microservices promise less TD because each Microservice is developed, deployed, and evolved by an independent small “two pizza” team sitting in “ear-shot distance”. Microservices also promise to limit the outreach of a specific TD inside a Microservice to at most its borders, since each Microservice is a self-contained deployment and execution unit that it is to the largest extent independent of other Microservices.
  • Educational measures can limit the occurrence of TD substantially, i.e., regular technical trainings for all roles in software development regarding deliberate design and coding practices. In the architect’s responsibility is also to create designs that are appropriate for the system and also comprehensible and realizable by a development team with a given skill set. The technically smartest solution is often not the best solution from a project perspective.

Going into depth on how to address TD root causes is probably worth its own blog entry, so I leave it by the above short and exemplary considerations.

To conclude, in professional software development both continuous TD management and a consequent identification and addressing of TD root causes is essential to keep TD in a system at an affordable level.

Technical Debt Evaluation in The Context of Architecture Assessment

This note is to outline problematics of technical debt in the context of field consulting, namely, assessments of the larger commercial enterprise systems.

One of our company (SoftServe Inc.) primary consulting specialties is Architectural Assessments of the software built by our clients. The typical assessment goals might include identification and analysis of maintainability, performance, security and other issues and risks related to the quality of the software design and implementation. These issues can cause or influence money losses in product operation and sales as well as other adverse impacts on the business goals.

A typical assessment flow is presented on the diagram:

Screenshot 2016-02-17 12.07.58

Combination of qualitative and quantitative analysis lies at the heart of our assessment approach. Qualitative analysis is based on the Architectural Tradeoff Analysis Methodology (ATAM). Quantitative Analysis might combine code quality metrics computation, performance profiling, cost-benefit analysis (CBAM) and other techniques.

An architectural assessment is always time-boxed to a few weeks while the product size and complexity might vary up to millions of LOC and at tens or hundreds of subsystems or coarse components. In many cases its critical part is location of the TD items and analysis of their impact on the product development, maintenance, and operation, and as a result associated costs, business goals, and other indicators important for the product business stakeholders.

Hence, the major practical need of an assessor is in:

  • Well defined time-boxed process of TD items identification
  • Toolset to support this process
  • Meaningful approach to semi-automatically evaluate the TD associated costs
  • TD item prioritization technique based on the above

Given these four items the other assessment activities can be easily accomplished by a professional assessing architect.

Additionally, it should be noted that Technical Debt often affects the business not in its part caused by the code smells, design anti-patterns, or broken code conventions. Its worst consequences arise from such issues as:

  • Improper decomposition of the code into interdependent and integrated modules
  • Overengineering or redundant complexity of application structure, components, and communication patterns
  • Inadequate selection of the architectural patterns
  • Bad 3rd party technology choices (hosting platform, data storage, programming language, etc.)
  • Inefficient integration contracts
  • Security issues (DDOS protection, auth, encryption, etc.)
  • DevOps anti-patterns related to deployment, continuos delivery, and other types of operations
  • Suboptimal data structures
  • Other violations of quality attribute requirements for the system

A comprehensive approach to identify TD across those areas and to analyze it uniformly for impact with the goal to determine an optimal vector of application of limited resources (people, budget, time) in order to maximize ROI from TD liquidation is likely a most useful research subject from the business perspective.

Which are the best techniques to be used for code and architectural debt identification?

We are particularly interested (University of Milano Bicocca-Software Evolution and Reverse Engineering Lab) in the identification of code and architectural issues that can be the source of technical debt at code and architectural level, in the automated support for the identification of these issues and in the prioritization of the most critical ones.

Our Work.
Respect to code level issues, we worked on code smells detection both through metrics-based and machine learning-based techniques (ESE-2015). Regarding the metric-based approach, we developed a code smells detection tool (JcodeOdor), we defined an Intensity Index to evaluate and prioritize the most critical smells to be removed (MTD2015) and we defined some filters to remove false positive instances (ICSE2015-poster, SANER 2016).

Respect to architectural level issues we performed an empirical study on the possible correlations existing among code smells and architectural smells. We are working also with other colleagues on the definition of a catalogue and classification of architectural smells.

We experimented different commercial and open source tools (e.g., inFusion, Structure101, Sonarqube, Sonargraph) with the aim to evaluate their support in the identification of architectural smells or other problems at architectural level, in the evaluation of the usefulness of the Technical Debt Index they provide (SAC2016), and the support these tools offer for the refactoring of architectural problems (WICSA2016). We observed and found many limitations in the tools and different problems to effectively use the computed Technical Debt Indexes, e.g.:
• Tools usually do not exploit historical and/or dynamic information to assess TD.
• Tools detect different relevant issues, and sometimes provide integration with IDEs to show issues in context, but they do not leverage the IDE features to trigger and automate refactoring operations.
• The way time/costs are associated to TD index values is arbitrary and not supported by evidence; even if the index provides a good approximation of TD, its prioritization suffers from this lack of a solid link with measures that can be used for decision-making.

Future Work
We are interested in defining and providing an Architectural/Technical Debt measure that can be effectively used and that takes into account also the history of a project. We also plan to enhance the detection of architectural smells by developing a new tool or collaborating with researchers already working in this direction. We would like also to exploit our experience in design pattern detection (JSS-2015) to enhance the identification of architectural smells, e.g., prioritizing architectural smells that affect subsystems considered more “critical” due to the presence of some specific design patterns.

Another direction we are interested in is the integration of data and software analysis to reach a more precise and holistic assessment of the debt of a system. We had some experience of this kind (JSME-2013) in recovering conceptual schemas from data-intensive systems.

Defects or Technical debt?

Philippe Kruchten
Feb 16, 2016

As the concept of technical debt gains some visibility and momentum, we witness a tendency to put all forms of quality issues, and even plain old defects under the umbrella of ‘technical debt.’

In this memo, I argue that this is wrong for several reasons:

  • Relabelling defects as technical debt does not help, it weakens the concept of technical debt, and give some unnecessary glamour to defects.
  • If all defects are technical debt, then the concept of technical debt becomes pretty useless.
  • We can establish some objective criteria to distinguish both, right from the definition of technical debt; and yes, detractors will always find some (sometimes convoluted) marginal cases.
  • The decisions we have to make about technical debt and defects are similar but not identical, and do not use the same criteria

The root of the problem — definitions

To ground the debate, let me give definitions for some of the terms I’ll use:

  • Software quality: the degree to which a system, component or process meets customer or users needs and expectation. (Source: IEEE std 610)
  • Defect: a condition in a software product that does not meet a stated requirement, or users’ or customers’ expectation, in other words: an error, flaw, fault in a computer program or system that causes it to produce an incorrect or unexpected result, that may lead to a failure, or to behave in unintended ways. We often call most of them “bugs” (Sources: RUP and IEEE std 1044).
  • Technical debt: A design or construction approach that’s expedient in the short term but that creates a technical context in which the same work will cost more to do later than it would cost to do now. (Source: Steve McConnell).

Defect and technical debt share some characteristics: they both deal with quality affecting the value of the product; they have a cost associated with it: the cost to fix, therefore some immediate or long term financial impact.

But there are some key difference. Technical debt deals with Internal quality, whereas defect deals more with External quality and Quality-in-use (as defined by ISO 9126 or ISO 25000). The impact of technical debt is not a loss of functionality (the system works), nor a loss of external quality, but a loss in maintainability and evolvability. The cost of future development is higher because of technical debt.

Defects are mistakes. They should not be there. Technical debt is the result of a compromise, a trade off, made explicitly, consciously, or not.

Condition Y in the system is technical debt if the cost of doing X now is higher because of Y.

Sorting them out

There are clear cut cases:

1) if an input out of bounds cause your program to crash, it is hard to argue that this is just a case of technical debt, making the system more costly to evolve. This fall squarely in the definition of a defect.

2) if your choice of database technology make the addition of new features to the system very costly, but everything works fine and is correct from the user perspective, the fact that you could have used another one is hard to label as a defect or a bug. It does a perfect job now and in the future.

There are some marginal “boundary” cases, where it is actually hard to distinguish, but in the majority of cases, it is better to separate defects from technical debt. So we can apply a simple criterion: are you paying some for of interest because of this condition as you evolve the system?

3)
Let us use a 3rd example:
Your static analyzer detects a place of the code where there is a potential for SQL injection, leading to a security breach.

Is this a defect or a technical debt item?

You could argue that the system works perfectly like this (so it sounds like technical debt like the example number 2) above with your sub-optimal choice of database), but there is a high risk of a failure. Furthermore you do not have a higher cost of evolving the system because of this potential vulnerability.

So this is just a defect. Indeed it is a defect associated with a high risk. If there is an attack , there may be some huge liability down the road, but this is not interest. if your house burn because of some bad electrical wiring, you will incur some high cost, but it is not additional interest on some mortgage debt.

It is likely that a static analyser would detect both: high risks defects and technical debt items, and maybe in some organizations this is where the confusion defect-tech debt comes from.

4)

There are cases where a technical debt item can lead eventually to a defect. Let us illustrate this with a 4th example: You have some code clones: a developer did some “cut-and-paste-and-modify” of a fragment of code, about 20 times throughout the system. But the software works fine. This is technical debt, because a) the system is working fine, but b) each evolution of the system that affect this particular snippet has to be done 20 times, instead of a single point of maintenance, so there is some form of constant interest.
Now the day a developer makes an update and carries the update only in 18 of the 20 occurrences, you may have introduced a defect or two.

Interestingly, because code clones are mostly found by static analysers, most of our community would say that code clones are a typical example of code-level technical debt.

5)

We can construct convoluted example of a clear defect, that remains for a long time in the system and incurs some form of interest, and therefore could also be labelled at technical debt.

Let me throw one: the caching mechanism does not recover properly after a loss of communication with a remote server. So rather than fixing it, developers used a workaround, they created a simple local log file where they write things, and use this log file to restore the remote server in proper state after communication is reestablished. As more occurrences of this happen, the workaround gets used more often and becomes refined, as some cost. The original defect in the caching mechanism is still there. And fixing it will be more and more costly as the workaround takes root. We have here something that is both a defect (ignored) and technical debt (the workaround to the defect).

Product decisions

I’ve argued elsewhere (Kruchten 2010) that:

  • new functionality
  • defects
  • technical debt
  • and architectural or infrastructure improvements

should be handled together when it come to make decisions about what to do next: for the next development cycle, the next release. They all four bring value to the system, but all four have a cost.

The cost of a defect may be immediate and hurting the product, the value of a new feature may be obvious from a sales perspective. So defects and and new features tend to have priority over technical debt reduction and architectural improvements, which have a value much harder to articulate, and require some analysis of cost and opportunity over a longer time period.

But the notion of risk needs to come into play, too. A latent defect like the SQL code injection case above may not affect the system right now (it works), but there is a risk of severe losses in the future. Labeling this defect ‘technical debt’ does not quite do it credit. There is another term for such defects: vulnerabilities. They are latent defects with a high risk of significant future loss.

Similarly, I advocate that we do not confuse vulnerabilities with technical debt.

Defect debt?

Then there is the extension of the notion of debt to a large amount of defects not fixed: defect debt due to accumulation (Akabarinasaji 2015), and and to debt-prone bugs (Xuan 2012).

While I understand that there is some loss of productivity (akin to interest of technical debt), I remain convinced that if there are defects, affecting some external quality or quality-in-use of the software product, and are not included in our definition of technical debt, we should not call them debt.

For “debt-prone bugs” having them in a bug tracking system does not make them bugs or defect. For example: Something identified with a tag “Fix me” or “to do, either has currently no impact on the external quality, and therefore it is technical debt, rt has some impact on the system, and is a defect. These are just identified technical debt item, stored and managed in the bug tracking system (which is a good thing).

Correlations?

It may be the case that high level of technical debt are correlated with high level of defects and vulnerabilities. But while we may have some intuition of this based on a few anecdotal evidence, this is not a clear case.

References

  • IEEE (1990). IEEE Std 610 – IEEE Standard Glossary of Software Engineering Terminology.
  • ISO/IEC (2004), ISO 9126:2004 Software engineering– Product Quality. Geneva: ISO, 2004.
  • McConnell, S. (2007). Technical debt. Retrieved from http://blogs.construx.com/blogs/stevemcc/archive/2007/11/01/technical-debt-2.aspx
  • Kruchten, Ph. (2010). What colours is your backlog? http://www.infoq.com/news/2010/05/what-color-backlog
  • Kruchten, Ph. R. L. Nord, and I. Ozkaya (2012), “Technical debt: from metaphor to theory and practice,” IEEE Software 29(6), pp.18-21, November 2012. DOI: 10.1109/MS.2012.167
  • Xuan, J., Hu, Y., & Jiang, H. (2012). Debt-Prone Bugs: Technical Debt in Software Maintenance. International Journal of Advancements in Computing Technology(IJACT), 4(19), 453-461.
  • Akbarinasaji, S. (2015). Toward Measuring Defect Debt and Developing a Recommender system for their prioritization. Ryerson University. Montréal, Canada. (unpublished work)

Software Modeling and Technical Debt

Over the last decade the technical debt metaphor has gained in popularity, and many tools exist today that can calculate the debt associated with a miscellany of source code, yet no corpus of studies have investigated the effects that model refactoring has on technical debt of resulting source code generated from models.

The research question I am investigating is:
What is the influence of Model Smells on the technical debt of generated source code?

My laboratory, in collaboration with the University of Concepción in Chile have made good progress in understanding the link between models and source code technical debt. We have found some literature, but not much relevant information is available on this topic.

In order to move forward we need to understand if model smell removal produces code that has less technical debt. At the same time, we improve models with a different objective function in mind (i.e., readability, understandability and visualization).

In order to make progress in the modeling community when transforming models into code, do we need to be technical debt aware?