What a page needs and how it looks are separate stages

Jesse James Richard
|
Apr 15, 2026
|
10 min read
#AI & Agents
#Architecture

The builder turns a customer's prompt and their uploaded materials into a finished marketing page, laid out and written and styled, in a sequence of steps. Each step is a model call with a narrow job, because a single prompt cannot do the whole thing. For a few weeks in early April, that sequence produced pages that were wrong in a way no test could catch.

The bug that never threw

A generated page would come back structurally confused. One announced three pricing plans in its opening and left room for two. One led with testimonials before the page had made any claim worth vouching for. One introduced a section that the rest of the page never built. Nothing errored. Every stage returned valid output. The page rendered in a browser exactly as asked. It simply did not hold together, and a customer looking at it would not think this is a software bug. They would think this company's site looks off, and they would be right in the way that loses a sale.

When I went looking for the broken stage, there wasn't one. The step that breaks a page into sections had proposed a reasonable set of sections. The step that lays a page out had proposed a reasonable layout. Read on their own, both were fine. They just did not agree with each other about what the page was. Two stages had each decided the structure of the page, in isolation, and nothing in the code had noticed they were answering the same question twice.

Two answers to one question

Two of the jobs in that sequence are easy to confuse, and the confusion is the whole problem. One job is deciding what the page should be made of, the claims it makes, the proof it offers, the things it asks a visitor to do. A different job is deciding how those pieces are arranged, which ones become sections, what order they run in, how the columns divide. On a whiteboard the two are obviously separate. In a chain of model calls they overlap, because every call is capable enough to do a little of both, and the natural way to build the chain is to let each step improve the result as it passes through. So the step meant to decide contents also sketches a layout, and the step meant to arrange the layout also adds or drops a section it has decided the page needs. Each change looks like an improvement on its own. What has actually happened is that two different steps have each decided the structure of the page, from their own view of it, and the two structures do not match.

In ordinary code, an overlap like that usually announces itself. Two functions that both set the same field collide, a type complains or a test fails, and you find the exact place they disagreed. Model calls do not collide. Each one returns a complete, valid result and hands it on. The step that arranges the page returns a perfectly good arrangement, and it has done nothing wrong. It did the job it was given. It just had no way to know the page it was handed was already shaped by an earlier step that thought that same job was its own. Nothing between them checks whether the two agree, so no error fires. The page comes out as a mix of two structures that were never reconciled, and that mix has no structure of its own. From the outside it looks like the model being unreliable. The real problem is that two steps were allowed to answer the same question, and no one was put in charge of the answer.

Model calls do not collide.

The cut

So I split the two jobs between the two steps and let neither reach into the other.

The first step, the one that reads the customer's materials, I call the content step. It used to do both jobs at once. It decided what the page should say and, in the same pass, roughed out how those parts should be arranged. I cut it back to the first job. It now produces one thing, a plain list of what the page should contain, the testimonials it can draw on, the pricing it should show, the features and process steps and questions it should answer. That list says nothing about layout. I call the list the inventory, and there is nothing in it to arrange, because it records what the page is made of and not how the page is built.

The second step lays the page out, and I call it the designer. It became the only place any arranging happens. It takes the inventory and decides the actual page, which items become sections, in what order, how the columns divide, which parts are given weight. Every structural decision is now the designer's to make. The content step can no longer overrule those decisions, because the content step no longer makes any. It produces a list, and turning that list into a page is the designer's job alone.

One stage answers what. The next answers how. Neither can answer both.

One page, before and after

The builder makes dozens of these pages a day for businesses like a small accounting company. Its materials name the clients it serves, the services it sells, a few lines past clients have written, and its rates. Under the old sequence, the content step read all of that and proposed a set of sections, an intro, services, testimonials, pricing, a closing prompt to book a call. Reasonable. Then the designer read the same materials over again and made its own structural choices, and because it was working from the source rather than a settled decision, it would sometimes split the services across two sections, or lift one strong testimonial into a section of its own, or drop the pricing because the page had already run long. The finished page was a compromise between two steps that never spoke, and the customer got whichever compromise happened to fall out.

Under the split, the content step reads those same materials and emits only the inventory, the services, the testimonials, the pricing, the set of claims. It builds no sections. The designer receives that inventory and decides, once and alone, that the page runs an intro, then services as a three-column band, then a single testimonial pulled wide, then pricing, then the booking prompt. There is one structural plan, made by the designer from a list it does not get to second-guess. If the pricing goes missing from the finished page now, one of the two steps could have dropped it, and there is one place to look.

The handoff between them is typed, and the boundary is enforced by that type. Content flows one way across it and layout flows the other, and neither step can reach back through it. The designer never sees the raw prompt and the uploaded files as an invitation to re-decide what belongs on the page. It sees a manifest of what belongs, and its entire job is the arrangement of that manifest.

Why an instruction is not enough

The separation cannot be kept by asking the steps to behave. A prompt that tells a step to not re-decide the structure is a request, and a capable model talks itself out of a request the moment it sees a page it thinks it could improve. So the boundary is built instead of asked for. Only one step can decide the structure, and the others cannot, no matter what they are told. The content step cannot lay out a page, because it emits no layout. The designer cannot invent content it was never handed, because it builds only from the inventory in front of it. Each step is held to its own question by the shape of what it can produce, not by a line of prose. A data shape with nowhere to put the overstepping decision cannot be talked out of anything.

What the split buys

The immediate return is pages that hold together, which is not a small matter when the product is a website builder and structural incoherence is a common reason an AI-built site reads as untrustworthy. A customer forgives a plain page. They do not forgive one that argues with itself.

The larger return shows up when something goes wrong. Before the split, a wrong page was almost impossible to debug. Both steps had shaped its structure, so there was no way to point to the one that got it wrong. All you could say was that the model had produced something incoherent, which is not a complaint you can act on. Now the two jobs live in different steps with a typed handoff between them, so a wrong page can be traced to the step that caused it. If the content is right and the layout is wrong, the fault is in the designer, so I fix the designer and leave the content step alone.

There is a familiar name for half of this. Splitting a system so each piece has one job, so you can change that piece without breaking the others, is separation of concerns, and every engineer trusts it to keep a codebase manageable as it grows. The other half is what got separated. These two jobs are not two pieces of code. They are two kinds of judgment, deciding what a page should say and deciding how it should look, the work of an editor and the work of a designer. Because it is a separation of concerns, it behaves like one. I can change how a page looks without touching what it says, and change what it says without breaking how it looks. Either side can grow on its own. We have always known how to do this with code. Doing it with the decisions a model makes is the new part.

Before the split
After the split

Who decides structure

Both steps, each from its own view

Only the designer, from the inventory

When they disagree

Nothing notices; the page mixes two structures

Cannot happen; one step owns the answer

A wrong page

Untraceable, both steps shaped it

Traced to one step, and fixed there

New kind of content

Risks re-tangling the two jobs

One inventory entry the designer places

It also made the builder safe to grow. A new kind of content, a comparison table, a logo strip, is one more entry in the inventory and one more item the designer knows how to place. Adding it does not touch the stage that decides what a page needs, and it does not touch the authority over layout. The two questions stayed two questions as the builder took on more of them, which is why the range of pages it can build has climbed without the pipeline losing the separation it started from.

The principle, kept

The builder has more stages than these two, and more of this discipline has been pushed through it since. The first load-bearing rule was this one, and it carries to any pipeline built out of models. If two stages can both answer a structural question, they will, and they will disagree. The cure is not a sharper instruction telling a stage to hold back. It is building each step so it cannot make the other's decision at all. Decide what a page contains before you decide how it looks, put the two in separate steps that cannot do each other's job, and the page comes out whole.

Have questions?

If you're interested in my work or Giant Context, contact me!

Contact Jesse
More
Sitemap
Privacy Policy
Terms of Service
Cookie Policy
Hosted on
What a page needs and how it looks are separate stages | Jesse James Richard