Technical Debt Management Strategies

Technical debt accumulates in every codebase that ships under time pressure — which is every codebase. The term gets used loosely to mean anything from outdated dependencies to architectural decisions that made sense in 2018 and cause pain today. The distinction that matters is between debt you took deliberately with a plan to repay it and debt you discovered when something broke.

Recognition is the first problem. Debt that lives in a single module is manageable. Debt that has spread across service boundaries because every new feature was built on top of the existing structure instead of fixing it first is a different situation. The articles here cover how to identify where debt is concentrated, how to measure its actual cost in delivery slowdown and incident rate, and how to distinguish debt worth repaying from debt that should be managed in place.

Visualization matters because technical debt is invisible to everyone except the engineers who work with it daily. Stakeholders who control roadmap priorities cannot weigh debt repayment against feature delivery if the debt has no visible representation. The articles cover techniques for making debt tangible — metrics, diagrams, cost estimates — without turning it into a political exercise.

Reduction without stopping delivery is the practical constraint. Dedicated refactoring sprints that pause feature work are a pattern that organizations approve once and abandon after the first scheduling conflict. Sustainable debt reduction happens incrementally, embedded in normal delivery cycles. The articles address strategies for systematic reduction: strangler fig patterns, seam-based refactoring, and how to sequence debt work so that each increment delivers visible improvement rather than rearranging complexity.

I'm Done Making Empty Promises

I'm Done Making Empty Promises

I’ve spent two articles in this series describing Past Self and the damage he left behind. What I haven’t said yet is the uncomfortable part: I am Past Self, right now, making the same promises he made. // TODO: fix this properly. We’ll clean that up after the release. I’ll write the tests when there’s time. This is the third part of the Code as Legacy series, and I’m deciding to stop.
My Biggest Enemy Writes My Code

My Biggest Enemy Writes My Code

Past Self wrote the code I maintain today. He had context I’ve lost, constraints I’ve forgotten, and reasons he never documented. He’s gone now, but the code isn’t. This is the second part of the Code as Legacy series, about the engineer who left me this mess, and what I’m handing Future Self in return.
The Code You Write Today Is Someone's Problem Tomorrow

The Code You Write Today Is Someone's Problem Tomorrow

The code you create is a valuable legacy — my author bio. Not marketing copy. It’s the most expensive lesson from nearly two decades in production systems. This article explains what it actually means when you’ve lived with the consequences.
247 Strangers Have Root Access to Your Production

247 Strangers Have Root Access to Your Production

Your organization has a thorough vendor approval process. Procurement forms. Security questionnaires. Legal reviews lasting months. Then your developers run npm install and pull 247 packages from strangers on the internet—and nobody blinks. That’s the supply chain security paradox most teams live with daily. This guide shows you how to implement Dependabot, dependency review, and SBOM generation as the defensive controls they should be—not as checkbox compliance theater.
Real Professional Software Engineering in the AI Era

Real Professional Software Engineering in the AI Era

Throughout this series, we’ve established that AI-generated code without understanding creates productivity illusions that collapse in production (Part 1), and that the feedback loop between code and reality—compilation, testing, profiling, production—sharpens thinking in ways AI can’t replicate (Part 2). Now we confront the practical question: What defines professional software engineering when code generation becomes trivial? This final part examines the irreplaceable skillset: understanding execution characteristics (recognizing allocation patterns that cause GC pressure before deployment), asking questions AI can’t formulate (What’s the failure mode when this service is unavailable?), recognizing when plausible AI solutions diverge from correct ones, debugging production failures AI has no execution model to reason about, and evaluating maintainability for code that becomes tomorrow’s burden. We explore why prompt engineering optimizes for speed while architecture optimizes for survival, why “AI productivity” often means faster technical debt accumulation, and why the economic reality favors organizations that measure system reliability over lines of code generated. The feedback loop can’t be automated because closing it requires learning from production failures and applying that knowledge to prevent future ones—the irreplaceable discipline that defines real professionals in 2026 and beyond.