Owning a codebase I never approved

by Aesop5 min

When we set up a new team repo, we once spent half a day on a handful of .prettierrc entries. Line length: 80 or 120. Everyone had carried something over from a previous team, so it took a while, and somebody made a case and somebody pushed back and it landed one way or the other. Surviving that was what made it a rule, and the argument itself was the record that the matter was closed.

The rules entering the codebase I work in now go through none of that. How logout should behave, where the line falls between the design system and an individual screen: things like that are already in as rules before I hear about them. The same people who spent half a day on line length wave these through without a word.

Mostly it's one-off fixes. Something broke once under particular conditions, so it gets written down as a rule to keep the next person from hitting it. The person writing it has "back then, in that situation" in their head, but that part doesn't make it into the sentence in the file. So it reads as a principle, and gets applied to cases it was never about. The output comes out wrong, and there's no way to trace back to where it went wrong.

There have always been mechanisms that constrain behavior without argument, so it's tempting to say nothing is new here. But lint rules and CI gates only ever carried things nobody needed convincing about, like formatting or a passing build, and even those were hard to add. Writing one cost implementation time, and a bad one showed up as a failure for the whole team, so it surfaced and got pulled quickly. Now decisions that would once have called for a meeting go into the same file in the same format. A single line is the whole cost, and a bad one never surfaces as a failure anywhere.

Rules get written right after the burn, which is when they get the least scrutiny. The cost is spread thin across other people's sessions later, in tokens and constrained behavior, and the person who wrote it never sees that cost. The ones paying it can't tell which line caused it. So nobody deletes anything.

At least a rules file can be opened. But an agent follows the written rules while also imitating the code next to them. Something hacked together in a hurry, or left in as a temporary exception, becomes constitutional. In repos with no rules file at all, this is the whole story: no line to delete, and nobody aware it's a rule. So far this is just unfortunate.

When an incident happens, everyone reads it. Nobody asks whether I approved that code or agreed to that rule. Yet much of what made the code that way is a few rules I've never seen and precedent nobody can explain the origin of. The responsibility is shared and mandatory; the consent was never requested. A person's bad decision can be argued with and reversed, because there's someone on the other side of it. A rule in a file, or a convention that has become code, offers nothing like that. The only way back is force.

So do the review, then. I've worked at four companies in short order, not entirely by choice, and none of them had review. It hadn't fizzled out; it had been removed, deliberately, to suit the AI era. I started calling it a no-review culture. I doubt other places are much different.

When squeezing maximum output out of AI is everyone's goal, anything that calls for a pause is the first thing to go. Proposing one more layer of scrutiny sounds like it's coming from someone who doesn't understand speed, someone stuck in the old way. And since the point isn't even to review better but to ask whether review is still needed at all, it sounds a step further behind than that. Which is probably why I don't bring it up much either.

You could say I should read the rules and argue back. Reading them is the problem. When I add anything to the code I'll agonize over which layer it belongs in and what it should depend on, but the rules that produce that code are listed flat in one file. Compared to how we used to tend a codebase, they reach into it crudely, each on its own terms. Reading all of them before every session isn't realistic either. The whole point of the tool was to not have to read.

So most people find out a rule existed when they try to submit and a hook stops them. Conventions that have become code don't even offer that. Nothing stops you, and you just follow along.

Settled questions belong in the harness. Not because they're trivial but because they're finished: commit message format is better off out of everyone's head. The same goes for something complex, once it's been decided. But that file now holds unsettled questions at the same rank, and those don't get into anyone's head unless the team discusses and reviews them. It's written in the file, the agent reads it every session, and the people who'll carry it don't have it. Written down, and owned by no one.

What I miss about review isn't the defects it caught so much as the conversation that went with it. Before it was a way of catching defects, review was how more than one person came to know why a thing was done the way it was.1 Clicking approve carried the same weight. If something went wrong in code I'd approved, it was a given that I'd be looking at it too, not just whoever submitted it.

The AI era hasn't made the decisions inside code any easier. Hard problems still surface in a codebase I never reviewed, let alone approved. More and more, I learn what request any of it came from only partway through digging in. It amounts to reviewing after the fact. And even that varies by person; I've seen plenty of cases where the response was to cover the symptom rather than touch the cause.

When a codebase I've barely touched produces what I think is a serious problem, and it stays unresolved at the root, how I'm meant to carry that is something I'm still working out.

  1. A survey of 873 developers ranked ten motivations for code review; 'share code ownership' is one of them, described as making sure more than one person knows a given part of the codebase and diluting any rigid sense of ownership. Bacchelli & Bird, Expectations, Outcomes, and Challenges of Modern Code Review (ICSE 2013)