Your AI reviewer needs a document you probably haven’t written

Y

Every mobile team I know has now tried pointing a language model at a pull request. Most of them tried it the same way: a workflow file, an API key, and a prompt that says something like you are an experienced code reviewer, review this diff.

The results are always the same shape. The model proposes better variable names. It flags a null check the compiler already guarantees. It asks for a comment above a function whose name already says what the comment would say. It is fast, it is unfailingly polite, and within two weeks the whole team has learned to scroll past it.

The usual conclusion is that the models aren’t good enough yet. I don’t think that’s it. I ran a tuned review agent privately against real production pull requests for months before I proposed one to anybody, and the thing that made it useful had almost nothing to do with the model.

The model doesn’t know what correct means here

Ask a language model to review code with no further context and it will review it against the average of all code. That average is real and it is not useless — it contains genuine consensus about naming, about dead code, about obvious resource leaks. But it is exactly the layer your team already agrees on, already lints for, and already catches in human review without effort.

What it cannot contain is your codebase. It does not know that in your repository, mapping a wire format into a domain model happens in one specific module and nowhere else. It does not know that you use one type for state and a different one for events, and why. It does not know which of your modules is forbidden from importing which other module. So it says nothing about any of that, because it has nothing to say.

Everything expensive in a mobile codebase lives in that gap. Not in whether a variable is named well, but in whether business logic ended up two modules from where it belongs, and whether anyone will notice before it has three call sites.

The uncomfortable part

Here is where it stops being a tooling problem.

You cannot give the model your architectural rules if you have not written them down. And most teams have not. What they usually have is a page saying they follow Clean Architecture, a diagram borrowed from a blog post, and a shared understanding that lives in the heads of whoever has been there longest — which reviews inconsistently, disappears when that person changes teams, and cannot be handed to anything.

I found this the ordinary way. Building a feature, I went to check how the surrounding screens were structured, and found several different architectures in use, none obviously wrong, and no document anywhere that said which was correct. Nobody was being careless. There was simply nothing to be correct against.

So the honest sequence is not adopt an AI reviewer. It is:

  1. Write down what correct looks like.
  2. Derive the review rules from that document.
  3. Then, and only then, automate.

Skipping straight to step three gets you a linter with opinions and a subscription.

What “written down” has to mean

Not every architecture document can be enforced. Most cannot. The test I use is whether a rule derived from it could actually fire on a real diff — whether it is specific enough to be wrong.

Some questions your document should answer without a human in the room:

  • Given any file, which layer is it in, and how would you know from its location alone?
  • Which modules may not depend on which other modules, stated as a rule rather than as a diagram?
  • Where does parsing a wire format belong? Where does business logic belong when two screens need it?
  • For a state holder, which type carries state and which carries one-shot events — and what breaks if you use the wrong one?

That last one is a good example of the difference. “Use appropriate types for your UI state” is unenforceable. “One-shot events use a type that does not replay to new collectors, because a replaying type will re-fire navigation and snackbars on rotation” is a rule. It names the mistake, it names the symptom, and a model can find it in a diff.

Writing this is not glamorous and it is not fast. Mine ran to about sixty-five thousand characters across twenty-five sections and subpages, covering module creation, each data layer, dependency injection wiring, and testing guidance for every layer. It took the form it did because I kept hitting questions I could not answer with a link.

Then put it in the repository. A standard in a wiki drifts from the code the moment either changes, because nothing forces them to move together. In the repository, an architectural change and the documentation of it can land in the same pull request, and a reviewer can require that they do.

Deriving the rules, not inventing them

Now the part that determines whether your team keeps the tool or mutes it.

Every rule in the ruleset should trace back to a section of the standard. If you cannot point at the paragraph a rule enforces, you are not encoding an agreed standard — you are adding a personal preference and giving it a robot’s voice and a permanent seat in every review.

I take this seriously enough to have declined rules on that basis, including ones suggested by people more senior than me. The reasoning is not precious about authorship. It is that a review agent applies to every diff, every day, and nobody can argue with it in the moment. If it enforces a pattern with no precedent in the codebase and no line in the document, you have manufactured an authority that nobody agreed to and everybody now has to satisfy. The document decides. The ruleset implements. When they disagree, the document wins and the ruleset changes.

Two practical consequences follow.

Prefer structure over style. Formatters and linters already own style, they are faster, and they are never wrong about it. Spend your rules on the things static analysis genuinely cannot see: layering violations, logic in the wrong module, boundary types leaking across a contract. That is where a model earns its cost.

A rule that never fires is decoration; a rule that fires on everything gets muted. Both failures look like activity. Watch which of your rules actually catch things over a few weeks, and delete the ones that don’t.

The boring parts that are not optional

Three things I would not skip, none of them clever.

Repository-facing automation holds a token, which makes it an attack surface. Pull requests from forks have to be rejected outright, and who can trigger a run has to be gated on their relationship to the repository. This is not advanced — it is table stakes — but first implementations miss it constantly.

Cost is a real line item once the thing runs on every diff. Measure it before rollout rather than discovering it in an invoice.

And decide ownership before you have two of these. If a second implementation appears — and it will, because this is an obvious idea and you are not the only person having it — the useful outcome is rarely for one to win. Split it: the workflow belongs to whoever owns the repository’s automation, and the review rules belong to the platform they cover, so a rule change for a platform requires a reviewer from that platform. Without that split, the two copies re-diverge inside a year and nobody can say whose version is the real one.

Know when it won’t transfer

One caution, because I have watched this go wrong.

Backend teams often point their agents at existing contributor and agent-facing documentation, and it works. It is tempting to copy that pattern straight across. But it works there partly because those repositories have the senior density to keep those documents honest — enough people who notice when the docs stop matching reality, and who care enough to fix them.

Copy the pattern into a repository that has neither the documents nor that density and you get a reviewer grounded in nothing, confidently citing a file that has been wrong for two years. The prerequisite was never the tool.

What actually changed

It is tempting to say the agent improved the codebase. It didn’t.

Writing the document improved the codebase. The arguments that produced it improved the codebase. The agent’s contribution was to make that document apply to every diff instead of the diffs I personally had time to read — which is a real contribution, and a smaller one than the marketing suggests.

So the interesting question in 2026 isn’t whether a model can write your code. It’s what you had to write down before one could review it. An architecture standard nobody wrote is also an architecture standard no agent can enforce, and finding that out costs a subscription and about two weeks of everyone’s goodwill.

Write the document. The tooling is the easy half.

About the author

Evana Puig

Add Comment

Evana Puig

Get in touch

Staff mobile engineer, 14 years across Android and iOS. I write the architecture standards mobile organizations code against, and the automated review that enforces them. Author of Android App Distribution at Kodeco. Fully remote.