Skip to main content

Write the Tests. The Agent Handles the Rest.

· 11 min read

"In theory, there is no difference between theory and practice. In practice, there is." — Jan L.A. van de Snepscheut

The last article established the machinery: neural networks are pure functions, agents are loops, context is the input. That's the theory. Now let's talk about what actually happens when you sit down to build with these things.

The Boring Truth About AI Coding Agents

· 21 min read

Updated March 23, 2026

"Any sufficiently advanced technology is indistinguishable from magic." — Arthur C. Clarke

You describe what you want. The agent writes code, edits files, runs tests — sometimes across dozens of steps without you touching the keyboard. When it works, it feels like magic.

Writing Simple Code

· 6 min read

"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." — Tony Hoare

Simple code is not a consolation prize for teams that can't handle complexity. It's the goal.

Software Is an Encoding

· 6 min read

"Programs are meant to be read by humans and only incidentally for computers to execute." — Donald Knuth

Code is documentation. Not a supplement to documentation — the thing itself.

Stop Rewriting, Start Steering

· 6 min read

"Make the change easy, then make the easy change." — Kent Beck

In a previous article, I argued that legacy code is a people problem, not a technology problem. A rewrite is rarely the answer. But if you're not rewriting, what are you doing? You still have a system that's hard to work with. You still have users who need things to get better. So how do you actually change a legacy system?

The Real Problem with Legacy Code

· 5 min read

"Legacy code is code without tests." — Michael Feathers, Working Effectively with Legacy Code

Feathers is right, but he's only describing a symptom. The real problem with legacy code isn't technical. It's a people problem.

The Shape of a Test Suite

· 10 min read

Most test suites are shaped wrong. Not because the individual tests are bad, but because the overall structure creates redundancy, obscures intent, and makes the system harder to change. If your test suite feels like a burden rather than a safety net, the shape is probably the problem.

I've written before about the problems with the test pyramid as a mental model. This article is the constructive follow-up: what should you build instead?

Async/Await is Misleading

· 5 min read

Updated February 21, 2026

Async/await exists to make asynchronous code read like synchronous code. That's the sales pitch, and it's true - as far as it goes. A single async operation does read more cleanly with await than with nested callbacks or chained .then() calls.

But there's a trade-off hiding behind that cleaner syntax, and most developers never think about it explicitly: async/await makes the sequential flow of one operation easier to read while making the concurrent state of your whole program harder to reason about.

That's a real trade-off, and in most programs, it's the wrong one.