Back to Field Notes

The Guardrails Around AI-Generated Code

The tooling moved. The bar didn't. AI-generated code needs the same engineering rigor as anything else, with a couple of extras bolted on.

TL;DRAI doesn't get to skip code review, architectural tests, linters, or the build pipeline. Project-specific rule files keep the model in your conventions. Architecture decisions stay human. Everything else is the same engineering you were already doing.

Here is the standard I actually apply: if I wouldn't accept this code from a junior on their first day, I don't accept it from the model either. Same read, same questions, same reasons for sending it back. Everything below is just what it takes to hold that line when the code arrives faster than I can read it carefully.

The controls are the boring ones

None of them are AI-specific. Architectural tests that turn the build red when a module reaches into another module's internals, so structure is enforced by the build rather than by memory. Linters and build-time validation for the obvious things. The test pipeline, unchanged. Human review on every diff, no silent merges, mine included. I wrote up the architectural test side separately: the rules I run, and the baseline trick that makes them adoptable in an existing codebase.

The one thing I add for AI is a project rule file: the conventions of this codebase, written down where the assistant reads them, so it works in the project's idiom instead of its own averaged-out idea of what C# should look like. It helps, and it is not enforcement. Instructions are advisory to a model in a way that a failing test is not, so the rule file shapes the first draft and the pipeline decides what merges.

What I don't hand over

The model can propose anything. Three classes of decision stay mine: architecture, security boundaries, and changes to the data model.

They have the same problem in common. In government and healthcare work, the constraint that decides these is usually not in the repository at all. It is in a data protection assessment, a client's threat model, an authorization model someone negotiated with a security officer two years ago, or the migration path across a table that is already in production. The model can see the code. It cannot see the constraint, so it writes something that fits the code and quietly breaks the thing the code was shaped around. Those are also the decisions you discover you got wrong long after the cheap moment to change your mind has passed.

So it proposes and I decide, and I have to be able to say why. If the only answer to "why is it built this way" is that the assistant suggested it, then nobody has decided anything yet, and someone will be paying to undo it later.

The tooling moved. The bar didn't.


Timothy De Bock

Timothy De Bock

Full-stack .NET platform engineer specializing in government, healthcare & security sectors.