Brutalist Software
For as long as I’ve written code, the virtues were fixed: DRY, clean code, small functions, abstract the moment you see a pattern twice. We called them timeless. They were never timeless. They were ergonomics for one specific reader: the human, with limited working memory, easily bored, slow to type, allergic to repetition. We optimized code for that reader because that reader was the only one who ever read it.
That reader is no longer alone. Agents write code now, and they read nothing like us. Generating text is almost free for an agent, so the verbosity we flinch at barely costs it. But its context window is small and expensive, it holds no memory of the rest of the repository between glances, and the instant it can’t see something, it doesn’t pause — it guesses. Our scarce resource was patience. Its scarce resource is attention: how much of the system it can hold in view at once.
I call that response brutalist software. The name comes from buildings rather than the bare-HTML “brutalist web design” you may have seen. Architectural brutalism stripped structures down to raw concrete and exposed frame, with nothing hiding what holds the thing up. Its bet was that honesty about structure beats the comfort of a facade. Like the buildings, brutalist software lets anyone standing in front of it see what is load-bearing. What you read is what runs. No action at a distance.
The axis is locality: how many jumps a reader has to make to be sure that touching one thing won’t break another. fetch instead of an SDK goes down a level; raw SQL instead of an ORM goes up one. Brutalism minimizes the jumps, whichever direction they go.
An abstraction earns its place when it is self-evident at the point of use; you understand it by looking at it. It is forbidden when understanding it costs more than one cheap, local jump.
stripe.charges.create() explains itself; you never open its source to know what it does. user.posts, in an ORM that quietly fires a query per row, does not; nothing at the call site tells you that a single attribute access is an N+1 waiting to happen. One reads like what it does. The other reads like a lie of omission. That gap is the whole philosophy, and it is the gap an agent pays for, in context, every time it reads your code.