Generative technical debt

I’m somewhat in agreement with the first half of Jamie Lord’s post on Nearly Right (Engineering leaders demand systems design skills as AI coding assistants produce mounting technical debt), and Jason Gorman made a good point about unreadable code being a form of technical debt (he coined the term ‘codemanship’, which I’m going to borrow). In my opinion, ‘AI’ generated code absolutely should not find its way into the codebase of critical software, unchecked, regardless of what some bastardised implementation of Agile might demand. Substandard software can cost lives, as we know from the Post Office Horizon scandal, and we have a responsibility to maintain standards.

Just in case you’re not familiar with the term ’technical debt’, Lord defined it well in one sentence:

‘An effect that’s being more and more widely reported is the increase in time it’s taking developers to modify or fix code that was generated by Large Language Models. '

More broadly, if we don’t put in the work of properly engineering software from the start, it becomes increasingly harder to modify, and even patch, over time. The software likely wouldn’t run as efficiently as it could, and its performance might degrade (memory leaks are a common symptom I’ve observed in legacy software).

By the by, one should never commission a software project with the assumption it has a lifetime of x number of years. In my experience, even relatively inconsequential applicayions become critical services, they get extended beyond their intended uses, and projects to replace larger systems always run years past their deadlines.

I came across plenty of examples of technical debt in the past. Occasionally I’d find a dependency version that included breaking changes, which meant a few lines of code also needed changing. When there was a lot of non-engineered code, those minor changes would break multiple other things, and what should have been a straightforward patching task became a substantial rewrite. Other times I spent hours refactoring code just because it looked too amateur to be in production.

Good engineering practices are the best mitigation. In separating code into abstractions, implementations, base classes, extensions and single-responsiblity methods that could be repurposed, we can really minimise the amount of work needed to modify the software, and there’s far less chance of it breaking after deployment.

Now, my main gripe with the whole generative ‘AI’ code thing is that it’s incapable of codemanship. Hell, ChatGPT can’t even form an opinion on a basic political issue, so it’s definitely not going to form a reasoned opinion on something as complex as which code patterns are more appropriate for a given situation. Instead, it would produce something that’s partially derivative of whatever crap was ingested - essentially it’s the coding equivalent of ‘AI’ slop. That crap would include amateur code from tuorial projects, snippets posted as off-hand answers to questions on Stack Overflow, and virtually anything it can find within a code tag, among other things. Adding that straight into a codebase would worsen technical debt.

Unlike Lord, I don’t think ‘AI’ has that much utility in software development, beyond maybe being a resource-intensive way of finding information that’s not well documented. A junior developer can still produce better code than some generative LLM, and s/he can learn how to apply best practices.

Longer-term, we’d start experiencing a shortage of software engineering expertise, without junior developers to learn. There is no coding ‘boot camp’ or undergraduate programme that could teach codemanship, and there is no undergraduate course that’s not exclusively about object-oriented programming that could teach it either. Learning to code is easy. Transitioning from development to engineering and codemanship is frustratingly hard, and it’s a craft learned through years of grind.

The other major, potentially catastrophic, problem I see will be caused by our reliance on third-party abstractions for development. I’m thinking specifically of ’low-code’ platforms that might be hiding a considerable amount of technical debt in whatever implements the services. Paradoxically, ’low-code’ can be a way of preventing technical debt, if the right platform is used, but we should be very concerned about statements lke this:

‘Salesforce paused engineering hiring in late 2024, citing AI productivity gains. A survey of 500 technology leaders found 72% plan to cut entry-level hiring whilst 64% increase investment in AI tools.’

The technology leaders here probably represent the handful of vendors that organisations are increasingly outsourcing their infrastructure to, and those vendors are becoming single points of failure for large swathes of the Internet. We only need to recall the AWS and Cloudflare outtages, both of which happened within the space of a fortnight, to understand what that means. Salesforce, incidentally, bought Mulesoft a while ago, and many corporations are utterly dependent on Mulesoft for their integrations platforms.

I don’t believe this is the future of software development, though. Development and engineering best practices came about, over the course of decades, because professionals recognised that substandard code is unacceptable in a word in which our lives are dependent on software. Widespread outtages will become frequent enough to force a rethink of design choices.

The ‘AI’ bubble will burst, and we know it’s going to burst because ‘AI’ is being rammed down our throats by vendors and companies desperately looking for ways to infest their products with it. The demand for ‘AI’ just doesn,’t exist to justify the hundreds of £billions (around £1.2 trillion within the last few years) investors had blown on the concept.