An agency product for running paid media was built by prompting, and for a while that was enough. Within about three months the codebase was past the size a prompt can hold. Every further step got harder, and progress started arriving with regression bugs. It could keep moving only under an LLM operator — a person directing the model, with the tests and the boundaries of the system in the loop.
The product is real. An agency or an in-house team connects ad accounts, asks an AI chat about the campaigns, and runs dashboards, billing, client intake, and a content library from one Laravel and React application. Prompting built that. Prompting also built it fast enough that, in about three months, no single prompt could see the whole thing.
That is the point where vibe coding turns on the app:
The app did not need to be thrown away, and it did not need another round of generating the whole product. It needed an LLM operator: a person who directs the model at the part of the system a change actually touches, and who holds the tests, the types, and the boundaries while the model writes.
Vibe coding is a fast way to get an idea into software. It stays fast while the codebase is small enough for a prompt to hold. Past that, each new prompt has more existing behavior to collide with, and the collision shows up as a regression. The app gets harder to move the larger it gets. That is not a bad week. It is the shape of the method.
What that looks like on an app of this size:
The chapter before this one is how a vibecoded prototype becomes a production product in four working weeks. This is the chapter after: the product keeps growing, and prompting it whole stops being a way to make progress. Read that story.
The product stayed. Paid media, the chat, the dashboards, the billing — still one Laravel application, still growing. The difference is that a change is now an operated change. The next feature does not have to cost the last one.
File counts are from the repository: 1,285 PHP files, of which 360 are test files, plus 34 domain models and 89 migrations. About three months is the life of that repository up to this size. We are not publishing a measured regression rate. The pattern is what the size makes likely: a prompt cannot see the whole system, so progress and breakage arrive together until an operator is in the loop.
Past a certain size, another prompt is how the regressions get in. An operator is how the app keeps moving. Fifteen minutes is enough to tell which one you are in.