September 2, 2025
AI didn't make engineering discipline obsolete. It made it the whole job.
Tests, small PRs, readable code, documentation: every engineering best practice just got more valuable, because every one of them is about managing change, and change is what AI multiplied. But one practice has no guardian at all, and it's the one that decides whether your codebase survives the next two years.
There’s a story making the rounds in engineering circles, and I understand why it’s comforting: AI writes cleaner code than most humans, so the old disciplines matter less now. Fewer reviews. Lighter process. Let the tools carry it.
I think that story has it exactly backwards, and I want to walk through why, starting not with architecture but with the humble stuff: tests, naming, small pull requests. The things every senior engineer preaches and every deadline erodes.
Best practices were never about writing code
Here’s the thing about engineering best practices that gets forgotten: almost none of them exist to help you write code. They exist to help you change code later, safely, without holding the whole system in your head.
Think about what each one actually buys:
What each practice is really for
Tests
Not proof of correctness. Confidence to change something six months from now without fear.
Readable code & naming
Cheap onboarding for the next person, who is usually you, later, with no memory of why.
Small PRs
Units of change a human can actually hold in their head and meaningfully judge.
Docs & ADRs
Shared memory. The decisions that outlive the people and conversations that made them.
The common denominator: every practice manages the cost and risk of future change. None of them is about typing speed.
Now ask: what did AI coding tools actually change? Not correctness per line, not fundamentally. What they changed is volume of change. Teams that shipped five PRs a day ship fifteen. Refactors that would have been postponed forever now happen in an afternoon, because generating the code is no longer the expensive part.
If best practices are the machinery for managing change, and AI just multiplied change, then every one of those practices became more load-bearing, not less. Tests matter more because more code lands between human readings. Naming matters more because more code is read by people who didn’t write it, including the models generating the next change on top of it. Docs matter more because they’re now consumed by agents as well as people.
The data backs this up, and it’s not subtle:
What the industry data shows
Sources: GitClear AI Code Quality research, Google's 2024 DORA report, and GitHub Copilot research. Every figure here is somebody else's; we have not run a study of our own on this and are not going to invent one.
GitClear’s number is the one I keep coming back to. Across 211 million changed lines, 2024 was the first year that copy-pasted code exceeded refactored code. Duplication rising in lockstep with AI assistance. That isn’t a story about bad code. It’s a story about system-level properties degrading while everyone’s attention stays at the line level.
The practices that scale themselves, and the one that doesn’t
Here’s where it gets interesting. Not all best practices are equally at risk, because not all of them depend on a human paying attention.
Most of the classics have a guardian that scales automatically. Style has linters. Correctness has tests and CI. Even readability has help now, since coding assistants are genuinely good at naming and idiom. Crank the volume to 10x, and these hold the line, because the enforcement is mechanical and per-file.
But look at what’s left unguarded:
Every practice has a guardian. Except one.
| Practice | Who enforces it | Holds at 10x volume? |
|---|---|---|
| Consistent style & formatting | Linters, formatters | ✓ Automatic |
| Correctness | Tests, CI, type systems | ✓ Automatic |
| Readable code, good names | Review norms + coding assistants | ✓ Mostly |
| Small, focused diffs | Team norms | ✓ If you insist |
| What your docs say about the code | Nobody | ✗ Goes stale silently |
| Dependency direction & boundaries | Nobody | ✗ Erodes silently |
| Modules keeping their internals private | Nobody | ✗ Erodes silently |
| No dependency cycles | Nobody | ✗ Erodes silently |
The unguarded rows share a property: they're global. You cannot check them by looking at one file, one diff, or one PR. They exist only in the relationships between components, which is exactly what per-file tooling can't see.
This is the transition the comforting story misses. The practices that survived the volume increase are the local ones. The practice with no guardian is architecture: what your docs say the system is, which component depends on which, whether boundaries hold, whether the shape is drifting. And architecture is the practice where damage compounds hardest, because you can’t refactor your way out of a shape problem one file at a time.
Why architecture decays at exactly AI speed
Before AI tools, there was an accidental safety mechanism nobody designed: the speed of human typing. Code changed about as fast as a senior engineer could keep a mental model of it. Reading diffs was a workable proxy for “is the system still healthy?” because the system changed slowly enough for a head to track.
Output scaled. Oversight didn't.
The bottleneck on writing disappeared. The bottleneck on noticing what the writing did to the system is still one human head, reading diffs.
That proxy is now broken, and here’s the mechanism. A diff shows you lines. It does not show you that those lines made a sentence in your own README false, or created the first-ever edge from your core into a plugin, or closed a cycle across five packages. That information lives in the relationship between this change and everything around it: other files, other documents, every change before it. It is structurally absent from the thing your reviewers are reading. Here is a real one:
The same pull request, two representations
Ericsson/ecchronos #1786, a real pull request. The call moved to a new class, SchemaRefresher; the sentence on the right did not move with it. It sits in a file the diff does not contain, so no amount of careful diff-reading surfaces it, and it is still on master. The whole story.
This is the pattern that shows up when you go and look. Across thirty recent open-source pull requests we analysed, most moved nothing structural at all — and a handful did something a reviewer would want to know about and could not have seen: a public interface losing a method that twelve components depend on, a component reaching into two packages it had never touched, a README describing an API that no longer exists. Every one of those pull requests was reviewed by people who are good at their jobs. The information simply was not in front of them.
The bill comes due quietly
The failure mode of high-volume AI development isn’t dramatic. Nothing crashes. The failure mode is a codebase that accumulates coupling, cycles, and misplaced responsibilities one clean-looking PR at a time, until one day the symptoms surface as things nobody connects back to architecture: builds got slow. Onboarding takes months. Every estimate has a fudge factor because every change touches more than it should.
So what do you actually do?
Keep every practice you already have. They matter more now, not less; that’s the whole first half of this post. But be honest about the gap: nothing in your current setup is watching the graph.
Closing that gap doesn’t mean hiring architects to trace dependencies by hand, and it certainly doesn’t mean slowing your team down to pre-AI speed. It means giving the one unguarded practice the same thing every other practice already has: an automatic, per-PR guardian.
That’s what Striff is. It reads the architecture your docs already describe, turns every checkable sentence into a rule, and evaluates each one at both revisions of every pull request. Alongside the rules, fourteen structural checks speak up only when something happened that the diff cannot show: a first-ever edge between two packages, a cycle closing, a reach into another module’s internals, a public contract shrinking under things that depend on it. On the rest it reports clean and tells you what it looked at.
The bar is deliberately high, and the consequence is that it is quiet. That is the same bargain your linter makes: you trust it because it does not shout. Your linter guards style, your CI guards correctness, and what you wrote down about the shape of the system finally gets a guardian of its own, at whatever speed your team ships.
Install it on a repository and open your next pull request.