The gap is a prerequisite
A plan for a search screen came back naming two components that did not exist. No code had been written yet, so nothing was blocked. A missing block should stop a feature, and planning is the cheapest place to find out.
Early on, when the model hit a component we didn't have, its plan would just create one.
It needed a checkbox. Our React Native library didn't have a checkbox. So the plan came back proposing a native checkbox element, styled inside the feature, and there is nothing stupid about that. It's the locally correct answer. But it's also how a codebase ends up with checkboxes nobody owns.
I caught it when I reviewed the implementation plan. Nothing had been built yet, so there was nothing to unwind. But catching it that way depended on me reading the plan closely, every time, which is not something to build on.
What the plan was
This series has been making one argument. A model does better work assembling pieces that already exist than inventing them, because a piece that exists has already had its decisions made. A component library settles what a checkbox is. The layer above it settles what this app's recurring arrangements are. What's left for the model is composition, which is a smaller and more reliable job than design.
There is an obvious hole in that, and this is the post about the hole. What happens when the piece it needs isn't there?
I was loaned to a team for two weeks to help move our company's app to React Native. There were two of us doing the work, and I was the one on loan. Everything we did there started from a written spec for a screen. A skill read that spec and produced an implementation plan against the components we already had. (A skill, here, is a set of written instructions a model loads when the work matches.)
The plan came back in three parts:
- The business logic the screen needed.
- The components it would compose, each one called by its existing name rather than described, and how it would arrange them.
- The components that would have to be created first, called out at the top of the document.
That last part did one thing only. It named what was missing. It did not propose how to build it, did not sketch an API, and did not offer a fallback. Creating a component was a different skill and a different piece of work, out of band from this plan entirely.
That is the rule this series is named after, enforced at the one moment it's cheap. Compose from what exists. When you can't, say so instead of inventing something.
The screen
The screen I was porting was provider search. Someone picks a specialty and gets a list back. Above the results sits a row of filter chips, each one narrowing them further. Which languages the provider speaks. Whether they see people in person or virtually. Tap a chip and what opens underneath it is a checkbox group.
We had a lot of the app by then. Still no checkbox. And this screen needed more than one: a checkbox group is assembled out of checkboxes, so the plan named two prerequisites rather than one. They were flagged as two separate components, in that order, because that is the order they had to be built in.
That is the shape of a real gap. A plan can name every piece a screen needs and still need one of them built before another, and it can say so without any of it being a problem. The plan doing that is the plan working.
So I went and built them, using the skills I'd written for creating new component library components. It took an hour to implement these two. Then I re-ran the skill that generates the implementation plan, which updates a plan in place rather than writing a new one, to see whether it now found components it could compose against. It did, and it composed against them without an argument.
An hour, because almost nothing about that checkbox was still open. The design team had already produced Figma designs for every component, and I pulled the element into the skill through an MCP server, which is a standard way of giving a model a live connection to another system, here Figma itself. The Figma designs used the same design tokens as the code (the named values for color, spacing and typography that both sides agree on), so the mapping was mechanical. The skill took the element, carried its token names straight over, and applied our conventions for writing a component.
All of that existed because my company already had Figma designs for our web component library, which I'd helped build. We decided what a checkbox was years before any of this. So I was moving a settled decision onto a second platform rather than making one, which is the easiest version of this job there is.
So the hour doesn't include deciding what a checkbox is. We had already paid for that, years earlier, on another platform.
Why it stopped writing its own checkbox
Nothing about the checkbox the model wanted to write was wrong on its face, which is what makes that failure the one worth engineering against. A screen needs a checkbox and a checkbox is not hard to write. The cost arrives later, somewhere else, to somebody else.
What fixed it was hardening the skill, through a loop that deserves its own post. The rule that did most of the work was narrower than "compose, don't create," and it's the first thing I'd give to someone else trying this. I wrote it into the skill as an explicit instruction: no decision may be deferred to implementation time. Every decision goes in the plan. Every decision gets justified there. A model that arrives at implementation still holding an open question has broken the rule.
That rule is what makes a plan worth reviewing closely. The native checkbox element was sitting in the document with a justification attached, so I could ask why. Either the justification held up, or the plan got corrected while correcting it was cheap. The plan had committed to everything the code would do, so the surprises I did hit came out of the spec rather than out of the plan leaving something open.
Forbidding deferral is also what drags the missing checkbox into the open. The model isn't allowed to leave that question for later, so it answers it in the plan, in front of me, and there are only two answers: a component we have, or a component we don't. The wrong one becomes a sentence I read rather than a file I go looking for. It can still make the wrong call. But it has to make it out loud.
A prerequisite, not a task
The distinction that the rest of this turns on: a missing block is a prerequisite to the feature, not a task inside it.
A task inside the feature gets built under the feature's deadline, by an engineer whose success is measured by the screen shipping. What comes out is a local implementation with a shared name: something built to satisfy one screen, called a checkbox as though it serves all of them. It may get promoted to a reusable component later, if anyone remembers. By then the shape it took under deadline is the shape other screens have built against, and changing it is no longer free.
A prerequisite is a different thing on a different clock. It gets built as a component and reviewed as one, and the feature starts after it exists. None of that follows from calling it a prerequisite. It follows from it no longer sitting inside the feature's deadline. No rush to figure out what to do after development has already started.
Which raises the obvious objection. You have just invented a queue, and somebody is now waiting on it.
What the queue actually cost
I've run this, though not on the React Native rewrite. There I found the gap and filled it the same afternoon, so there was no handoff and nobody ever waited. That run tells you nothing about what a queue costs.
At a previous company we built a design system while building the product, which meant new components turned up constantly and they needed designs. No model wrote those plans. We wrote them ourselves, and we found the gaps by reading them. We worked in two-week sprints, and every designer's time was already allocated. So a component the plan said was missing went into the next sprint as design work, which allowed the engineer to build the feature in the sprint after that.
The engineer was not sitting still. They were working on something else, because the gap had been found during planning rather than three days into a sprint. That is the entire trick, and it is what made the gate affordable for the team. We did not miss our sprint goals over it.
The screen itself waited, and I can't tell you whether that wait was worth what it bought, because nobody ran that project the other way.
The gate ran in both directions, which matters more than it sounds. If a design wanted a layout very close to one we already had, it was on engineering to ask why we needed a second one. Design and engineering both had to justify their position and agree. "This design wants a new component and the reason isn't good enough" was a legitimate outcome, and so was "no, this one is genuinely different." What was not legitimate was an engineer settling it alone, mid-implementation, because raising it would have cost too much time to complete their assigned work.
Where the spec comes into it
None of this works if the spec is vague, because a plan can only be as decided as the thing it's planning from.
On the rewrite the specs were reverse-engineered. We were moving an existing app from Ionic to React Native and keeping the functionality, so a skill read the old code and wrote the spec for each feature, and a second skill reviewed that spec against the code for gaps, ambiguity and contradictions. It still missed things.
Then I read the spec myself, against the old code, and decided whether it was good enough to plan from. That call was mine, and so was the one on the implementation plan it produced, and so was the one on the code after that. I want to be plain about it, because a chain of skills handing documents to each other sounds like something that runs without anyone. It doesn't. At every step, there's a person reviewing the work.
Things still got through. We'd start implementing and find something the spec had never settled. That goes back into the spec, and the plan gets regenerated from it, rather than getting decided in the file where it surfaced. Other times the implementation plan was where we noticed, which is cheaper.
Where the line falls between the spec and the plan is not technical versus non-technical. It's decisions only the business can make versus decisions the system should make. A useful test: if we got this wrong, who is upset, a customer or an engineer? "Does a canceled order appear in order history" sounds technical and is a spec question, because a customer is the one who notices. "Which component renders the list" is a plan question.
That test is my conviction rather than my report. On the rewrite there was no product owner reaching past a line, because the answers were all sitting in an app that already worked. I read them out of the old code. Nobody had to decide what the product should do.
What stays your job
The skill finds the gap. It doesn't tell you what to do about it.
Whether a missing component is a real gap or a design that should have reused something is a judgment call, and it's the one I'd least want automated. So is whether the thing you're about to create belongs in the library at all, or in the app, or only on this screen. That question is most of what the first post in this series was about, and most of what the composite layer was about after it.
And a plan that composes is not the same as a plan that's right. It can reach for the wrong component, arrange two correct ones badly, or describe a screen that doesn't do what the spec asked for. Finding the gap early removes one way of going wrong. The review is still yours.
The limits
The detection and the routing are lived. A skill produced a plan from a spec with a prerequisites section, I acted on it, and the plan then composed against what I'd built. That happened, repeatedly, over two weeks.
The organizational gate is only half lived. The sprint version is real and I ran it, but at a company building a design system alongside a product, before any of this involved a model. On the rewrite, one person detected the gap and filled it, so nothing about handoffs or turnaround was tested there at all.
The hour depended on a design team, a Figma file with matching tokens, and a web library I'd helped build that had already answered the question.
And the biggest one: we were rewriting an app that already existed. We knew what we were building. The back-and-forth between product, design, and engineering that usually fills the planning phase mostly didn't apply, because the answers were already running in production. Greenfield is a different problem. You feel your way, you build something to see how it behaves, and the spec is partly an output of that rather than an input to it. I don't know what this gate looks like when nobody yet knows what the screen is for.
Back to the plan
Two components that didn't exist, named at the top of a document, before a line of code was written.
That is the boring version, and the boring version is the point. The same missing checkbox found three days into a sprint is a different thing entirely. Then one engineer decides it, under a deadline, in the file they happen to be working in, and what ships is a checkbox whose name promises more than it is.
Same gap either way. What changes is where you are standing when you find it. At that point in the work I was holding a document and nothing else.