← All articles

AI Writes the Code, Seniors Own the Release — Our Review Pipeline

On a native iOS + Android project, a developer builds each feature on iOS with AI assistance; once it is merged, an agent ports it 1:1 to native Android, a second agent reviews the port, both apps are tested side by side, and a senior engineer reviews and tests last. How the pipeline works and what each layer catches.

“We build with AI” can mean two very different things. It can mean that code nobody really read goes to production a bit faster. Or it can mean that AI does most of the typing while the review, the testing and the responsibility stay where they always were — with experienced engineers.

We do the second. This article shows what that looks like on a real project: a pair of native apps, one in Swift for iOS and one in Kotlin for Android, where AI agents do a large part of the work and every change still passes through a senior engineer before it ships. We can’t name the client or the project, but we can show the pipeline.

The setup: two native apps, one behaviour

The client needs two native apps that behave the same way. Writing every feature twice by hand is slow, and the two versions tend to drift apart: a validation rule that exists on iOS but not on Android, an edge case handled on one platform only.

So we split the work by what each participant is good at:

  1. A developer builds the feature on iOS, with AI assistance.
  2. An agent ports it to native Android, one to one.
  3. A second agent reviews the port.
  4. Both apps are tested side by side.
  5. A senior engineer reviews and tests last — and owns the release.

Step 1 — iOS: a developer with AI, and a normal pull request

Each feature starts on iOS. The developer works with Claude Code: AI drafts the implementation and the tests, the developer steers, corrects and tests on a real iPhone. The result goes through a normal pull request with mandatory tests in CI and a senior review before it is merged.

That merged iOS change is the most important artifact in the whole pipeline. It is no longer “a description of a feature” — it is a working, reviewed, tested implementation, and it becomes the specification for Android.

Step 2 — Android: an agent ports the merged change, 1:1

When the iOS pull request is merged, we dispatch an agent through our internal agent harness. Its job is narrow and well defined: implement the same change in the native Android app, one to one — same screens, same states, same validation, same error handling, same edge cases.

“One to one” does not mean translating Swift line by line into Kotlin. The behaviour must match; the code must be idiomatic Android. Lifecycle, permissions, background work and navigation follow Android’s rules, not iOS’s. A narrow, well-specified task like this is exactly where agents are strong: the specification is complete, reviewed and executable.

Step 3 — a second agent reviews the port

The porting agent does not review its own work. A separate review agent, with a fresh context and a different instruction — find what is wrong — reads the Android change against the iOS original. It looks for the kinds of problems a port typically introduces:

  • Behaviour that silently differs — an edge case handled on iOS but dropped on Android, a different default, a missing error state.
  • Platform idioms lost in translation — iOS patterns forced onto Android where the lifecycle, threading or permission model works differently.
  • Tests that pass without testing anything — assertions that are always true, mocks that make the test meaningless.
  • Shortcuts around security and data — logging sensitive data, relaxed validation, storage that is less safe than on iOS.

Findings go back into the change before any human spends time on it.

Step 4 — testing both apps side by side

Then both apps are tested in parallel and comparatively: the same scenarios run on the iOS app and on the Android app, and the results are compared. The question is not only “does Android work?” but “does Android behave exactly like iOS?” Testing happens on real iPhones and Android phones, through TestFlight and Google Play Internal Testing builds, not only in simulators.

Step 5 — the senior engineer, last

Nothing reaches users until a senior engineer has reviewed and tested it. Whoever — or whatever — wrote the code, the senior checks the same things every time:

  • Architecture and design — does the change fit the app’s architecture, or does it add complexity that will hurt later?
  • Security and data — authentication, permissions, sensitive data, untrusted input.
  • Tests that are real — do the tests verify the behaviour that matters, or do they just pass?
  • On the device — does it actually work in the app, on a real phone?

The agents make the senior’s review faster, because a lot of noise is already gone. They don’t replace it. The senior is the one who says “this ships” — and the one who answers for it.

What we learned

  • A reviewed implementation is the best prompt. Porting from a merged, tested iOS change works far better than implementing from a written description.
  • Agents should review agents — with a different brief. The same agent that wrote the code is the worst reviewer of it. A second agent told to find problems catches a different class of issues.
  • Compare, don’t just test. For two native apps, “both pass their tests” is weaker than “both behave the same in the same scenarios”.
  • Keep a human at the end, always. AI changes who types the code. It does not change who is responsible for it.

Want to build like this — AI speed with senior accountability? See how we approach AI product development, or read how we built Claude agents for a construction company.