esc
Being riclib

The Best Architecture Is the One You Delete

Last week I replaced five systems with one. A NATS KV draft store. A pub/sub bridge. An event publisher. A streaming buffer. A render handler. Each correct. Each solving a real problem. Each doing...

March 22, 2026

Last week I replaced five systems with one. A NATS KV draft store. A pub/sub bridge. An event publisher. A streaming buffer. A render handler. Each correct. Each solving a real problem. Each doing its job. All of them replaced by a two-line flow: write the file to disk, push an HTML update through the tab’s SSE channel.

The five systems were 650 lines of code. The replacement is 40. The features are identical. The new system also works with every LLM provider, which the old one didn’t. Net result: fewer lines, more capability, zero NATS dependencies in the content editing path.

The instinct here is to feel clever. Look at the elegant simplification. Look at the wasted complexity that was there before. Why didn’t we build the simple thing first?

We couldn’t.

The Discovery Tax

Here is the thing nobody tells you about simple architectures: you cannot design them. You can only earn them.

The two-line flow — store.WriteOnly() then tab.SendSSE() — contains five discoveries, and each discovery required building the complex system that the simple one replaces:

Discovery 1: Drafts are just files on disk. The NATS KV draft store taught us this. We built optimistic locking, conflict detection, revision tracking. Then we noticed that git already has all of this. git diff HEAD is your conflict detection. The working copy IS the draft. The committed version IS the published state. We couldn’t have seen this without building the draft store first, because the draft store taught us what a draft actually is: a file that differs from its committed version. That’s git.

Discovery 2: OOB rendering is just SSE. The editor bridge subscribed to NATS events, re-rendered HTML, and broadcast it to browser tabs. But every request already carries a tab session. The tab session already has an SSE channel. The rendering is the same three lines of templ code either way. We couldn’t have seen this without building the bridge, because the bridge taught us that the rendering and the transport are separate concerns — and the transport was already there.

Discovery 3: Publishing is unnecessary when the writer has the channel. The event publisher existed because the tool call handler didn’t have access to the SSE stream. But it did. The tab session was in the request context all along. We built a NATS pub/sub system to cross a gap that wasn’t there. We couldn’t have seen the gap wasn’t there without trying to cross it.

Discovery 4: Streaming buffers are unnecessary when you stream text. The artifact streamer — 280 lines of progressive JSON parsing, in-memory buffering, flush coordination — existed because LLM tool call arguments stream as JSON fragments. Anthropic doesn’t stream tool call arguments at all. We built the buffer for OpenAI, accepted the limitation for Anthropic. Then someone asked: what if the LLM just… wrote the artifact as text in its reply? Text streaming works identically on every provider. The buffer dissolved. We couldn’t have asked this question without building the buffer, because the buffer taught us that the problem was on the wrong layer.

Discovery 5: The handler is the editor. The render handler existed to load content, compute diffs, render HTML, and return it. But loading content is one method call. Computing diffs is a pure function. Rendering HTML is a templ component. The handler was orchestrating three things that compose directly. We couldn’t have seen the composition without building the orchestration, because the orchestration made the pieces visible.

Five systems. Five discoveries. Each system was the tuition for its own replacement.

Gall’s Corollary

Gall’s Law is famous: “A complex system that works is invariably found to have evolved from a simple system that worked.” This is true and useful and cited in every architecture discussion.

But Gall’s Law describes the direction of evolution: simple → complex. It doesn’t describe the direction of discovery, which runs the other way: complex → simple.

The corollary:

The simple system that replaces a complex one could not have been designed first. It can only be discovered by building the complex one and understanding why each piece exists.

Gall says you can’t design a complex system from scratch. The corollary says you can’t design a simple system from scratch either — not if it replaces something complex. The simple system is the output of understanding, not the input. You don’t start with the napkin. You arrive at the napkin after filling the whiteboard.

This is not iteration in the usual sense. Iteration implies refinement — making the same thing better. This is transmutation. The complex system and the simple system don’t share code. They don’t share structure. They share understanding. The simple system is what you build when you know what each piece of the complex system was actually doing.

The Addition Trap

The software industry measures progress by addition. Features added. Lines written. Systems deployed. Sprint velocity. The numbers go up. Stakeholders are pleased.

Nobody measures subtraction. Nobody tracks “systems removed” or “complexity retired” or “dependencies eliminated.” There is no sprint metric for understanding well enough to delete.

This creates a ratchet. Every quarter, the system grows. Every year, the system doubles. Every rewrite, the system triples — because the rewrite reproduces the old system’s features (addition) without the old system’s lessons (which would enable subtraction). The rewrite team doesn’t know why each piece exists, so they rebuild all of them. The cycle repeats.

The ratchet breaks only when someone understands the system deeply enough to ask: “What if we just didn’t?”

What if we just didn’t have a draft store? What if the working copy IS the draft?

What if we just didn’t have a pub/sub bridge? What if the writer already has the channel?

What if we just didn’t stream tool call arguments? What if we streamed text?

Each “what if we didn’t” requires understanding what the system does — not at the code level, but at the purpose level. You can’t ask “what if we didn’t have a draft store” unless you understand what a draft is. And you can’t understand what a draft is without having built a draft store.

The Economics of Earned Simplicity

This means every complex system in your codebase is in one of two states:

Tuition — you’re still learning from it. The complexity is paying for understanding. This is not waste. This is the cost of discovering the simple version. It looks like over-engineering from the outside. From the inside, it’s reconnaissance.

Weight — you’ve learned everything it has to teach, and the simple replacement is visible. Now the complexity is pure drag. Every hour you don’t replace it is interest on a debt that only grows.

The hard part is knowing which state you’re in. The five NATS systems were tuition for about four months. Then, in one conversation, they became weight. The transition happened in the middle of a sentence: “the tab session already has an SSE channel.”

There’s no ceremony. No meeting. No decision matrix. One moment the complex system is the only way. The next moment it’s obvious that it was never the only way — you just needed to build it to see the other way.

The Practitioner’s Question

So what do you do?

You build the complex thing. Consciously. Knowing it might be tuition. Knowing that the simple thing you can’t see yet might be hiding behind the understanding that only the complex thing provides.

And then — this is the part that requires love — you delete it.

Not because it’s broken. Not because it’s wrong. Because you now know enough to write forty lines that do what 650 did. Because the five discoveries are in your head and the simple system is on the napkin and the napkin is correct in a way the whiteboard never was.

The best architecture is the one you delete. Not because deletion is virtuous. Because deletion is proof that you understood what you built well enough to unbuild it.

You can’t design the simple version. You can only earn it.

And the tuition is the complex version you built first.


There’s an encyclopedia where software principles get the roast they deserve — Gall’s Law in a boardroom, YAGNI at a buffet, Zawinski’s Law at a nightclub. And a mythology where these ideas have been arguing with each other for a hundred episodes.


See also: