emile bosch (ツ)

← all writing

Making things comprehensible for us feeble humans

Nov 8, 2026 · 6 min read · #engineering · #ai · #code quality · #complexity

In October OpenAI dumped 372 math results on the internet in one go. One of them was a proof of the Unique Games Conjecture, a problem people in complexity theory have been chewing on for over twenty years. A computer checked the proof. It’s probably correct. And yet, as Scott Aaronson wrote, “no human has understood just about any of these proofs yet.”

Dana Moshkovitz has worked on that conjecture since 2009. Her first reaction to the paper: “so horribly written that it’s impossible to read it without AI help”, built on “some alien craziness”. She then spent weeks, together with Subhash Khot, who came up with the conjecture, and a bunch of other experts, just to draw a map of it that other humans could follow.

I recognise that feeling. I’m sure AI makes me a lot faster. But my agents write more code in a day than I can read in a week, and if I don’t do anything about it, I slowly lose track of what’s in there. Correct code that nobody understands is a problem waiting for a bad night.

So a big part of my job now is dumbing things down. Making whatever the agents produce cost me as few brain cycles as possible.

Brain cycles are what runs out first

You pay for every if you have to follow and every level of nesting you have to keep in your head. A 200-line function you have to read to the end before you know what it does.

This was a problem long before AI. A field study that followed 78 professional developers found they spend about 58% of their time just trying to understand code. Agents make the pile bigger, and they don’t care how it reads. An agent will happily write six nested ternaries that work fine. I’m the one who has to debug it later. If it takes me twenty minutes to get what it does, the agent didn’t save me much.

Keep the architecture dumb

The biggest win is the structure. That’s what my plugin architecture is for: a feature lives in its own folder, behind a contract. To understand it I only need to look in that folder, not hold the whole app in my head.

I even have a script for it, the footprint. You give it a feature’s files and it counts how many places in the rest of the app would break if you deleted them. Few touchpoints means easy to delete. Funny enough, it also means easy to understand.

Measure it

I don’t trust my gut on readability anymore, so I measure it.

One script scores every file on how many decisions it makes, how deep the nesting goes, how long the longest function is and how much React state it juggles. Roughly how much you need to keep in your head at once.

Another one rolls the whole codebase up into a single number I call cognitive debt. Complex functions, giant files, a ternary inside a ternary, any types that make you guess, copy-pasted code where a fix in one copy misses the other: it all adds up, as points per thousand lines, graded A to E. Most of it builds on SonarSource’s Cognitive Complexity, a measure for how hard code is to understand. That’s a different thing from how hard it is to test.

My chat workspace scores a C. Not great! But there’s a baseline in the repo and the check fails when the number goes up, so every change has to leave things at least as readable as before.

A map of the code

Scores alone don’t help you find your way around, so I also built a code navigator: a keyboard-driven browser for a codebase.

It finds near-duplicates, functions with the same shape under different names. That’s exactly the kind of copy that piles up with agents, and that a text search never finds. GitClear’s 2025 report found that 2024 was the first year copy-pasted lines outnumbered refactored ones, so it’s not just me. Under the hood every function becomes a MinHash fingerprint (a cousin of SimHash), so comparing thousands of them takes less than a second. Then you get the two side by side with the identical lines dimmed, and your eye goes straight to the differences.

It draws the imports as a dependency matrix, an old systems engineering trick from 1981. A busy column is something everything depends on, so read it first and change it last. Anything above the diagonal points back up, which means a cycle. On my table app it found eleven files importing back up into one route table. Oops.

It ranks risk as complexity times the lines no test runs, so a branchy function nobody tests ends up above a long boring one.

And it has tours: a walk through the code, one sentence per stop. An agent writes the first draft from what the index knows, every reference gets checked against the real code, and then a human fixes it up. Basically the map Moshkovitz had to build for that proof.

Agents can ask for all of this over MCP, so they can look up the hotspots and duplicates themselves before they start hacking.

None of these numbers say whether code is good. A long flat switch reads easier than a short knot of nested conditions. They just tell me where to spend my attention.

Sweeps and guardrails

Every now and then I do a sweep: point the agents at the worst files and let them simplify. Split the long functions, flatten the nesting, merge the duplicates. The scores tell them where to start and whether it worked, and the tests make sure nothing broke.

Guardrails catch things while they’re being written. Network calls only in the API layer. Browser storage in one place only. An empty catch has to explain why it’s empty. No stray console.log. Every rule file says why the rule exists, so the agent gets the reason too.

You need both. Agents can make a mess faster than any sweep can clean it up.

Ruby had this right

Ruby was probably the best language ever for this. Matz designed it to make programmers happy, and in practice that meant code that reads like what it does. Small methods, clear names, hardly any ceremony. You’d open a Ruby class and just get it.

I want that comprehension high back. Except now the code is TypeScript, written by agents, at ten times the volume. The language isn’t going to give it to me for free, so I have to enforce it.

A comprehension score?

What I’d really like is one number for how many brain cycles something costs. How long does it take a person to understand this file, this feature, this change?

The debt score gets part of the way. I think the real one would also look at names that lie about what they do, how much you have to jump around to follow one flow, and how much of the rest of the system you need to know before one piece makes sense.

Agents already optimize for test coverage and performance budgets when you ask them to. I don’t see why they couldn’t optimize for my feeble brain too.

enjoyed this? there's 21 years more where that came from

More writing →

← previous

DeepSeek makes me optimistic

next →

Make it easy to undo your fuckups