Reviewing an App You Didn't Write
What to read when the agent hands it over
An agent builds the app in half an hour, and then the bill arrives: it is your code now, in your repository, and somebody has to read it before it carries anything real. That reading is the expensive part of agent-built software, and it is the part nobody demos.
How expensive depends on one number that has nothing to do with the model: how much of the application is yours. Every line the agent wrote is a line someone reviews. Every line it did not write — because a package already had it — is a line that was reviewed once, by whoever wrote the package, and is now the same in every project that uses it. A framework with strong opinions is worth less to a person typing than it is to a person reading after an agent.
Universal or Regira? The review surface of generated code is whatever the framework did not already own, so the leverage is in conventions, not in the model. Any stack where the conventional path is also the documented one gets this, and the reading order below transfers: find the file where domain decisions concentrate, read it first. The seams themselves are Regira Entities — one registration per entity, a search object as the request vocabulary, an input shape that decides untouched-versus-emptied, write rules registered once — and the Filtering and Writing in Regira Entities series explain each of them.
What the agent actually wrote
Open the diff of a generated back end and it is thin. Per entity: the model, the two shapes it takes over the wire, the object that says what can be searched, one registration, and the seed data. Per screen: a list and a form, generated and then filled in.
What is not in the diff is the part that usually goes wrong. Turning a query string into a filter, composing that filter with the ones that apply to every query, paging with a ceiling the caller cannot raise, deciding whether an absent child list means unchanged or deleted, normalizing text so a search matches without accents — none of that was written for your project. It came from packages, it is the same code every other project runs, and it has been wrong and fixed somewhere else already.
So the review is not "did the agent write good plumbing". It is "did the agent describe my domain correctly", which is a question you are qualified to answer and a compiler is not.
Read it in this order
Six things, in the order that finds a domain mistake before a naming quibble.
- The registration per entity. One call per entity holds the domain decisions: what can be filtered, what can be sorted, what may be included, which collections the entity owns, and which rules run on write. If the agent misunderstood the brief, it shows here first — an owned collection that should have been an entity of its own, a filter nobody asked for, a missing include that turns one screen into fifty queries.
- The input shape, for the collections it carries. A save that sends no child list must leave those children alone; one that sends an empty list must delete them. That distinction is the single most expensive thing to get wrong, and it is decided by what the input shape declares — the difference between untouched and emptied.
- The search object. It is the public vocabulary of your API: every question a caller is allowed to ask, and nothing else. Read it as an interface, not as a class — what belongs in it.
- The rules that run on every save. Validation, timestamps, computed fields, normalized text: registered once per entity, applied to every write, including the seeder's — one place for all of it.
- The seeder. It is documentation of what the agent thinks your data looks like, and because it writes through the same services an API call goes through, five hundred rows are also a small load test of the filters and sorting the registration declares.
- One list screen and one form. The rest are copies of these two, so a problem found here is a problem found everywhere.
Only the first four carry business risk. In an app whose users own their rows, add one check no reading replaces: sign in as a second user and ask for the first user's record and one of its files by id; both must answer 404.
What you are not reviewing
Filter composition, paging bounds, the write path's diffing of owned rows, text normalization, tree queries, the rules that apply to every query whatever the endpoint. These arrive as package code, identical in every project, and they are where the subtle bugs live.
The practical case for putting a framework under an agent at all follows from that. The agent does not rebuild them — the time and tokens of a run go into your domain, not into re-deriving pagination for the ninth time. And when one of them turns out to be wrong, the fix arrives as a version bump rather than as a change you have to make, review and regression-test in every repository that ever had an agent write it from scratch.
Three places you will meet this
A pull request from an agent session. Each step of a staged brief is its own session, so it is its own review. Read the registration and the input shape before anything else; approve or reject on the domain, then let the rest be style.
The same app, six months later. Less code means the next session still fits in context: the agent re-reads the documentation instead of re-reading your bespoke plumbing, which is why the second change costs about what the first one did.
The version bump. Generated code you own does not improve on its own. Package code does, which is an argument for keeping the generated part small on purpose. The guides improve too, but only for the next run: an app generated before they had the agent scope an owner's attachments keeps unscoped files until someone asks for the change.
The trade-offs
You take on a dependency and its opinions, and its conventions only pay off once your team has learned them — the first review is slower than the tenth. The free tier's ceiling shapes the domain model, which is a design constraint the brief has to live with. And none of this removes the need to read the domain code: it makes that the only part you must read, which is a smaller promise than "the agent was right", and a more honest one.
Why not let the agent write the plumbing too? It will, if you ask — and the result usually works. But then it is yours: your paging edge case, your filter composition, your upgrade path, reviewed by the same person who is already reviewing the domain and has a finite budget of attention. Plausible code and tested code look identical in a diff. The whole value of the arrangement is that the agent writes the part only you can check, and reaches for a package for the part you would rather not.
Docs: the Regira Entities framework and the agent-built samples at Regira/Regira-Samples. Regira Entities is commercial with a free tier; the samples are MIT.
Versions: the guides have the agent scope an owner's attachments since Regira 6.5.0.