Code Quality and Clean Code Principles

“Quality” is the word teams reach for when a codebase frustrates them and nobody wants to argue about specifics. The articles in this collection try to put specifics back: which metric actually predicts maintainability, which Clean Code rule survives contact with a real change request, which analyzer warning is signal and which is decoration. Quality without a measurement attached is taste, and taste does not survive a team rotation.

The metric-focused content treats cyclomatic complexity, maintainability index, and class coupling as imperfect proxies rather than thresholds. The same number means different things in a CQRS handler and in a parser. Articles cover how to configure code metrics in Visual Studio and dotnet tooling so the output reflects intent — and when to ignore the numbers because the context invalidates them.

Analyzer and nullable-reference-type content sits at the boundary between style and correctness. Turning on TreatWarningsAsErrors, adopting <Nullable>enable</Nullable> in a legacy project, and choosing which Roslyn rules to enforce in .editorconfig are not aesthetic choices — they decide what kind of bug your CI is allowed to ship. The articles walk through staged adoption strategies rather than the all-or-nothing flag flip that most teams attempt and abandon.

Testing strategy gets the same treatment. Coverage percentages are easy to game; mutation testing exposes assertions that test nothing. Articles examine where mutation testing pays for its runtime cost, where it produces noise, and how to read the surviving mutants without rewriting the entire suite.

The social dimension runs through everything. Quality practices that one engineer pushes through review get reverted by the next rotation unless they live in tooling. The recurring theme is moving quality out of opinion and into configuration that fails the build — so the standard outlives whoever set it.

The Codebase Doesn't Know You Quit

The Codebase Doesn't Know You Quit

The first four parts of this series treated legacy as something between me and myself: Past Self leaving code for Future Self, with an AI in the middle. That framing is incomplete. Code outlives employment, not just memory. The companies I worked for have forgotten most of what I did there. The repositories haven’t. This is the fifth part of the Code as Legacy series, about the legacy you leave when you’re not around to defend it.
The Machine Writes. The Legacy Is Still Mine.

The Machine Writes. The Legacy Is Still Mine.

Part three ended with me promising to stop adding to Past Self’s pile. I was already wrong. I’m not the only author anymore: Copilot and Claude finish methods before I’ve finished thinking, shipping code under my name with my git config as the committer. This is part four of the Code as Legacy series, about what changes when the author is partly a machine.
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.