Walls vs. Trees
A metaphor for development in any system — and for why building with an AI quietly pulls you toward the wrong one.
It started in the shower. The thought was simple: there are two ways to grow a system, and one of them never knows when to stop. The longer I sat with it, the more it turned into a theory of how to build software alongside an AI without watching it sprawl — including the exact moment, mid-rinse, when the metaphor flipped on me.
01 · The wall
When you prompt an AI at the level of the big picture — "build me the app, here are the twelve things it should do" — you tend to get a wall. A wall is flat. Every brick is the same size and the same weight, laid at the same height, with the same priority. There is no hierarchy and there is no gate. Crucially, there is no stopping point: you can always add another brick. The wall has no opinion about whether it should.
That last property is the whole problem. A brick needs nothing beneath it but the ground, so a wall never has to answer the question "what are you in service of?" Every feature is locally valid on its own terms, which is exactly why the structure sprawls forever. Nothing about it pushes back.
02 · The tree
The alternative is to lay down soil first — a foundation the whole thing can stand on — then plant a single root and grow outward from there. A trunk. Then limbs, then branches, then twigs, each one smaller than the thing it grew from. Now you have a hierarchy: features of genuinely different weights and sizes, arranged so that importance has a shape. And a tree, unlike a wall, was designed to support itself from day one.
My first instinct was that the tree bounds itself because each branch must be smaller than its parent — that the geometry does the work. But that's not quite right, and the correction is the most important part of the whole idea.
A tree isn't bounded by its shape. It's bounded by what it can carry.A real tree can grow new branches forever. What actually stops it is that every branch has to be physically supported by the wood below it, and that support is finite. Translate that into software and the discipline isn't "keep things small." It's: nothing exists unless something beneath it can carry its weight. Every feature has to trace back, through a parent that justifies and supports it, all the way to the root goal. That single rule — provenance, not geometry — is what a wall can never enforce, and it's why the tree knows when to stop.
03 · Wait — my tree should be growing bricks
For a while I had two different things hanging off the ends of my branches and didn't notice they were fighting. The durable, interchangeable, load-bearing units — the CRUD endpoints, the plugins, the components — I'd been calling those bricks, and saying a good system is "a tree at the top, a wall of bricks at the tips." Fine. But I'd also decided the things growing at the tips were leaves. So which is it? Does a branch end in a brick or a leaf? I'd drawn both and waved my hands.
Hang on. If the leaves keep falling off and the branch is the thing that lasts… then I've been watering the wrong part. My tree should be growing BRICKS! (For the record: this is the actual sentence that went through my head, in the shower, with shampoo in. A tree. Growing bricks. Sure, Lulu.)
And the stupid part is — it does. That's what wood is. A branch doesn't stay green; it lignifies. Soft new growth can't bear weight, but over a season it hardens into wood: permanent, structural, load-bearing. Wood is a brick the tree grew itself. So the tree was never the opposite of the wall. The tree is the process that manufactures bricks and knows where to put the next one. A wall is that process stripped out — bricks with no growth, no seasons, no gardener.
A wall is a dead tree someone stacked by hand.Not because the materials differ — bricks are bricks — but because the growth process is gone: nothing is deciding where the next one goes, or whether it earned its place.
04 · Leaves are the proof, not the product
So if bricks are the product, what are the leaves? Tests. And the lignifying picture finally told me what a test is for. A leaf is photosynthetic — temporary machinery that proves a branch can feed itself. It does its work in season, and then it falls. Tests churn; the hardened feature stays. A test isn't what the tree grows — it's how a branch earns the right to harden into a brick.
A branch heavy with green leaves is a feature being actively validated. A branch that never grew any is deadwood — load you're carrying on faith. You don't keep the leaf. You keep what the leaf let you commit to.
The shorthand, in plain terms: the root is the goal, branches are features, leaves are the tests that prove them, and hardened wood is committed, load-bearing code.
05 · Don't grow from green wood
This is the part that actually matters for building with an AI. Prompt big-picture and every feature it proposes is locally valid, so nothing tells it to stop — it lays brick after brick because each one passes inspection alone. The tree supplies the missing rule, and now I can state it precisely: you can't grow from green wood.
Don't extend feature N+1 from feature N until N has hardened — tested, finished, actually bearing weight. New growth comes off cured wood, never the soft tip. That's the stopping gradient I'd been hunting for — not "the budget shrinks with depth," but "the thing beneath you has to have set before you stand on it." It's also plain sense the wall can't express: a wall will happily let you stack a brick on wet mortar and call it progress.
In practice: don't ask the AI to build a dependent feature until the thing it depends on has tests, a stable interface, and is actually finished — not a half-built stub you're both quietly pretending is done.
06 · The DNA every branch grows by
There's a question the whole thing has been dodging: where do the growth rules even come from? Something has to tell each new branch how to behave before it's allowed to harden. In a tree that's the DNA — and the useful part is what DNA isn't. It's not a picture of the finished tree; it never says "branch here, leaf there." It's a small set of rules every part follows as it grows, and the whole shape falls out of them.
When you build with an AI, that role has a filename: AGENTS.md, or CLAUDE.md. It's the one set of instructions every agent reads before it touches the work — your conventions, how things get tested, what's off-limits, how to handle a failure. The rule for what goes in it is simple: it should hold the durable rules of how you build — conventions, boundaries, architectural intent — not a backlog of what you want built. The moment you paste a list of features into it, you've turned a set of rules into a fixed spec — which is how you got the wall back in section one.
AGENTS.md holds the durable rules of how you build — not the current wishlist.This is also where the human's job splits in two, and the difference matters more than it looks. You can steer what's being built right now — prompt, correct, redirect the current session. That fixes the thing in front of you and changes nothing after it. Or you can edit AGENTS.md, so every future run starts already knowing.
A correction can live in three places, and they are not equal. Say it again this session, and it's gone the moment the session ends. Put it in a test, and it catches the mistake after it happens. Put it in AGENTS.md, and the mistake stops happening at all — across the whole project, on every run from here on.
The deepest place to push a lesson isn't a test. It's AGENTS.md.
And there's a move here with no real-world equivalent: you can rewrite the rules mid-project. A lesson the work taught you the hard way at 2pm can be in AGENTS.md by 2:05, and everything built after it inherits it for free. Steering only fixes the case in front of you; editing AGENTS.md is the one correction that compounds.
07 · Prune the twig, not the limb
Now: what happens when the leaves won't take — when a branch can't support its own tests? It should fall. But only the smallest failing branch, never the limb it hangs from. Which isn't how real trees work at all: cut a limb and you lose every twig and leaf past it. Failure cascades outward.
That impossibility is the most useful thing in the whole metaphor, because it names the job. "A parent can fail and its children keep living" has a precise name in software: decoupling. Making the pruning rule true is the entire architectural task. Where it holds, you've isolated the blast radius. Where it doesn't — where pruning one branch takes the subtree with it — you've found a load-bearing brick, and the test on that branch is the most important one in the tree, because its failure cascades.
So I'd restate it as a rule about rollback granularity: when tests fail, revert the twig, never the limb. And this is something a wall fundamentally cannot do — bricks have no tests, and pulling one from the middle either does nothing or drops the whole course above it. There's no clean rollback granularity in a wall. Maybe that's the deepest reason it sprawls: nothing can fail locally, so nothing ever gets pruned, so it only ever grows.
In practice: keep features independently revertible. When a test fails you want to roll back that one unit without unwinding everything built on top of it — so watch for the feature whose failure would take the subtree down with it, and put your strongest tests there.
08 · The branch that passes every test and is still wrong
Here's the case tests can't reach. A branch whose leaves all stay green — it passes everything — but it's in the wrong place, shading out a part of the tree that matters more. That's not a correctness bug. It's an architecture smell, and no leaf can see it, because shade is only visible from outside the tree.
This is the part that is irreducibly the human's. The gardener is the only one who can stand back and notice that a healthy branch is starving a more important one of light. But the gardener is imperfect too — limited attention, half-remembered leaves. So the real question in building with an AI isn't "human or machine?" It's a balance: how much can the AI test against, versus how much can the human proactively point out before the canopy closes over.
09 · Two observers at different zoom levels
The reason the partnership works is that the two of you stand at different distances. The AI sees every leaf up close: it can test exhaustively, but only ever locally. The human sees the silhouette from across the field: the shape, the canopy, where one mass is starving another — but can't inspect every leaf, and half-remembers the ones they think they see.
So you don't have one perfect observer and one flawed one. You have two lossy observers with complementary blind spots: exhaustive-but-local meets global-but-blurry. The collaboration is strong exactly where those gaps don't overlap — and it fails the moment someone works at the wrong zoom. A human burning scarce attention micromanaging twigs the tests already cover. An AI asked to make a canopy-level call it has no vantage to make. Mismatched zoom is the actual bug — not imperfection itself.
10 · The gardener's real skill: turning shade into leaves
And here's the move the whole thing was reaching for. The gardener's skill isn't spotting shade. It's converting shade into leaves. When you notice one branch overshadowing something that matters more, the low-value move is to prune that one branch. The high-value move is to plant a leaf that detects that kind of shading from now on — a lint rule, a dependency constraint, an architecture fitness function, a performance budget.
Every shading pattern you can name, you can usually push down into a test the AI can then police on its own — a new leaf that lets the right things keep hardening. The boundary between "the AI can verify this" and "only the human can see this" isn't fixed; it's a frontier the gardener drags downward every time they catch something. Good prompting is largely the act of turning your own judgment into machinery, so you don't have to keep being present to apply it.
In practice: every time you catch the same kind of mistake by hand, convert it into something automatic — a lint rule, a test, or a line in AGENTS.md — so it's caught without you next time.
The thought, fully unfolded
Which loops all the way back to the wall, and this is the closer I didn't see coming when I stepped out of the shower: a wall has no shade. Every brick sits at the same height, so nothing overshadows anything — which sounds like a feature until you realise it means you can't see what matters either. No importance gradient, nothing to perceive. That's the real cost of stacking bricks by hand instead of growing them: you lose the seasons and the silhouette. The tree's hierarchy is what bounds the AI's growth and what lets you see well enough to steer it — one geometry doing both jobs.
The structure you build for the AI to grow within is the same structure that lets the human see well enough to guide it. Bound the growth and you sharpen the sight — with one geometry.
A wall doesn't free the gardener from judgment. It blinds them to the fact that judgment was ever needed. So don't stack the bricks. Grow them.
This piece started as a literal shower thought and got argued into shape over a long back-and-forth — right up to the moment someone pointed out my tree should be growing bricks, not leaves, and the whole thing clicked a notch tighter. If it resonates — or if you think the tree breaks somewhere I haven't pruned yet — I'd genuinely like to hear it.