Skip to content
All articles

3,025 pull requests in ten months: an AI-assisted delivery process, from the inside

A training platform for education providers started in an AI app builder and is now a multi-tenant SaaS with a web app, native iOS and Android apps, 160 serverless functions and 1,048 automated test files. Over ten months, 3,025 pull requests were merged into it, most of them written by coding agents and every one of them reviewed, tested and released through the same seven stages. A second platform, for a hospitality business, went through 2,133 in six months the same way. This is what that process looks like day to day, where the two hard gates sit, and what I would set up first if I started again tomorrow.

11 min read

1. The setup: one lead engineer, several agents, one process

I was architect and lead engineer end to end. The coding was done largely by agents, Claude Code and Codex, working on tickets in parallel, each in its own branch. That only works if the agents can't do damage on their own, so the process came before the speed: React on Vercel, Supabase Postgres with row-level security on every table, edge functions and scheduled jobs, native apps whose design tokens are generated from the web CSS, and a release pipeline that treats every change the same way, whoever wrote it.

3,025 merged pull requests in ten months is about 300 a month. The number itself is not the point; what matters is that each of them was small enough to review, reversible, and went through staging before production. The guide I wrote about this process describes the seven stages in compact form. Here is how they play out in practice.

2. Guardrails before the first prompt

Every repository has a short instruction file the agents read at the start of each session: the architecture in a few lines, the conventions, how to run the tests, and a list of what an agent may and may not do. The hard rules are few and absolute. Authentication, payments, data deletion and secrets always need a human approval. Agents never touch production data or real customer accounts; they get test accounts in staging and nothing else.

The instruction file is not documentation for its own sake. It is the cheapest way to stop the same mistake twice. Without it, every session starts from zero and an agent will happily repeat a migration pattern that broke staging last week. With it, the lesson is written down once and every future session starts with it.

markdown
# AGENTS.md (excerpt)
## Never without a human approval
- auth, payments, data deletion, secrets, production config
## Never
- push to main, touch production data or real customer accounts
## Always
- one ticket = one PR; migrations idempotent, dry-run before merge
- run unit tests + type check before asking for review
## Lessons (append, never delete)
- <date>: <what went wrong> -> <the rule that prevents it>
Seven stages, two hard gates. Agents write the code; people approve what reaches production; every lesson goes back into the guardrails.
AI-assisted delivery in seven stages: guardrails (instruction file, hard rules), small pull requests (one ticket, one PR), staging (same build as production), verify (tests and an AI browser check, gate: tests green), impact check (risk and way back, gate: a person approves), ship and watch (smoke tests, monitoring, one issue per failure) and learn (lessons back into the instruction files), with a loop from the last stage back to the first.

3. Small, reversible changes, staging first

One ticket, one pull request, with branch protection on main so nobody, human or agent, pushes directly. A pull request that changes a thousand lines across ten features can't be reviewed properly, however good the reviewer, so agents are asked for the smallest change that closes the ticket. Database migrations are idempotent and run as a dry run against the target database before anything merges.

Every change reaches a staging environment with the same build and configuration as production before it goes anywhere near customers. When the release goes out, only the functions that actually changed are deployed, which keeps each release small and each rollback obvious. This is the unglamorous part, and it is where most of the speed comes from: when every step is small and reversible, nobody has to be afraid of merging.

4. Verify like a user, not like a compiler

Green types and green unit tests are necessary and not enough. The platform has 1,048 automated test files, and type-check and lint run against baselines that may only improve, so the agents can't quietly make things worse. The first hard gate sits here: nothing merges unless the tests are green.

On top of that, a flow is checked the way a user would experience it. I built an AI browser tester for this: you describe the flow in plain language, for example 'a trainer creates a session, a learner signs in with the QR code, the trainer sees the signature without reloading', and an agent drives a real Chrome through it and returns a pass or fail with console errors, failed requests and a fix prompt. Setting up such a test takes nine steps instead of around two hundred, and multi-role flows like the one above are exactly where conventional tests are thin.

5. Impact check, then a person says yes

Before a release goes to production, a short table answers four questions: what changes, who is affected, what is the risk and what is the way back. Agents draft it from the pull requests; I read it. This is the second hard gate: a person approves every production merge. It takes minutes, because the changes are small and the table is short, and it catches the cases where a technically correct change is the wrong thing to do on a Friday afternoon or during a customer's audit week.

The point is not distrust of the agents. The point is that release decisions involve context the code doesn't contain: a customer about to onboard, a support backlog, a planned migration. That context lives with people, so the decision does too.

markdown
## Release <date> — impact check (template, example rows)
| change                         | who is affected        | risk   | way back                 |
|--------------------------------|------------------------|--------|--------------------------|
| attendance flow change         | trainers, learners     | low    | revert PR, redeploy fn   |
| new invoice field              | admins of all tenants  | medium | migration is additive    |
| CRM scoring update             | sales users            | low    | feature flag off         |
Approved by: ____  (no production merge without a name here)

6. Ship, watch, and let failures open tickets

After every deploy, smoke tests run against the vital routes of the live system, such as sign-in and checkout. If one breaks, the deploy turns red and the change is rolled back. Monitoring watches outcomes rather than CPU: did attendance get recorded, did the invoice go out. Each failure opens one issue automatically, and the issue closes itself when the check recovers, so the backlog shows real problems and not alert noise.

Underneath sits the safety net nobody sees: encrypted backups seven times a day, files mirrored to a second provider, and a nightly restore into a separate twin project that proves the backups work. With agents writing code at this pace, being able to undo anything, including data, is what makes the pace acceptable.

7. Close the loop, and measure the right things

Every incident, every review comment that repeats, every migration that failed on staging ends with one question: which line in the instruction file would have prevented this? That line gets added. Customer replies are drafted by an agent and sent by a person. Over months this is what turns a fast team into a safe one: the rules grow with the product.

Measure lead time from ticket to production, change failure rate, merged pull requests per week and bugs found by users, the same kind of delivery metrics the DORA research uses. Don't measure lines of code; agents produce those for free. If you want to start, start with the guardrails and staging, not with more agents. The readiness check below shows where a codebase stands before you add speed.

Interactive

Is your AI-built app ready for production?

Tick what is already true. The gaps that are left are your to-do list, in order.

0/12 ready

Your next three steps

  1. Code lives in Git; changes go through pull requests
  2. No secret keys in the frontend; server keys only on the server
  3. Row-level security (or equivalent) on every table
Get a production-readiness review
All calculators and checklists

Takeaway

Agents can write most of the code. The process decides whether that's a risk or an advantage: small reversible changes, two hard gates owned by people, and every lesson written back into the rules.

More articles

    Get in touch

    Tell me what you're building. I'll reply within 1–2 business days.

    Dominik Heinrich
    Company
    MADO Consulting

    Available worldwide, remote. On-site on request, depending on the country.

    I reply within 1–2 business days. Free slots: see the calendar

    Opens Calendly's booking calendar here. Loading it sends data to Calendly (see Impressum).