How a Tiny Team Ships Like a Big One

Claude reviews every PR we open. Only the risky ones ever reach a human.

How we codified review judgment as a severity-by-scope matrix so an AI reviewer can be the only reviewer for routine changes - and never for the risky ones.

5 min readcode-reviewclaudebedrockci-cd

A pull request opens in our monorepo. A 👀 reaction appears on it. A few minutes later there are inline comments - each tagged with a severity, each carrying a ready-to-run fix prompt - and a verdict: approve, comment, or request changes. For four out of five of our PRs, that reviewer is the only reviewer they will ever have.

It's Claude, running on Amazon Bedrock, in every one of our seven repos. Getting comfortable with that took longer than building the workflow, and the thing that finally got us there had nothing to do with the model: we had to stop treating review judgment as vibes and write it down as a decision matrix.

Review was our worst bottleneck

At our size, code review was the bottleneck with the worst failure mode. PRs queued behind the two people with context; a Saturday-evening fix waited for a Monday-morning approval; authors context-switched away and came back cold. And when we started running agents that open fixes around the clock, the math broke completely - you cannot staff a human review queue for a fleet that doesn't sleep. The choice was: let review quality collapse, or codify what "review" actually means.

What we built

The core of the system is two classifications and one rule.

  1. Every PR gets a change-scope class: Major, Minor, or Patch. Schema changes, auth-adjacent code, new dependencies, infrastructure - Major. Contained behavior changes - Minor. Typo-grade mechanical changes - Patch.
  2. Every finding gets a severity: P0 to P3, from "this will corrupt data" down to "nit."
  3. The verdict is a pure function of those two axes. Any P0 or P1 finding: request changes, blocking. Minor or Patch with nothing above P2: approve - no human needed. Major: the bot may comment, but it is structurally forbidden from approving. A human reviews every Major change, every time, no matter how clean it looks.

That last cell of the matrix carries the whole arrangement. A reviewer cautious everywhere would have drowned us in noise, and one lenient everywhere would have rubber-stamped risk - so we drew the line where risk actually lives, in the scope of the change, and pinned the bot to it.

The verdict matrix · click to enlarge

Around that core, the details that make it livable:

  1. A TDD gate. A diff that changes behavior with no test changes is an automatic blocking P1. The escape hatch is a tests-exempt label - applied by a human, intended for docs, config, and emergencies, and visible in the audit trail.
  2. Every finding ships a fix prompt. Under each comment is a copy-pasteable instruction block for a coding agent. A P2 at 11 pm goes: read comment, paste prompt into the agent, review its patch, push. The reviewer doesn't just complain; it hands you the shovel.
  3. A lessons file. When the bot's feedback gets corrected or a comment turns out to be repeat noise, the lesson is written down and loaded into future reviews. Same idea as onboarding a junior reviewer - except the notes actually get read.
  4. Least-privilege plumbing. The workflow authenticates to AWS with GitHub OIDC and assumes a role that can do exactly one thing: invoke Bedrock models. No stored keys, nothing else in the account. The model is pinned to an exact version, so review behavior doesn't drift under us overnight. And anyone can re-summon the reviewer with a /review comment.
  5. A bench of specialists. Behind the generalist sits a five-persona bench - security (scoped to OWASP/CWE-referenced findings), code quality, performance, test coverage, and documentation accuracy - each defined as a read-only subagent. Review composes better as five narrow perspectives than one omniscient prompt.

Real numbers

  1. 80% of our PRs are reviewed only by AI - the remaining 20% are the Major ones, plus anything a human is pulled into by a P0/P1.
  2. Every PR, across all 7 repos. No repo is too small; consistency is the point.
  3. ~4 of every 5 agent-authored PRs are accepted through this gate - the same gate our SRE fleet's fixes flow through.
  4. The reviewer runs on the same Bedrock setup as the rest of our fleet: inside our AWS account, scoped IAM, no data leaving our environment.

Where the humans sit

Humans review 100% of Major changes - the bot can't approve them even if it finds nothing. Humans apply tests-exempt; the bot can only demand tests, never waive them. Changes to the review workflow itself skip auto-review entirely and go human-only - we didn't want the gate approving edits to its own judgment. And when the bot blocks something a human disagrees with, the human wins - and the disagreement becomes a lessons-file entry.

Steal this

The two-axis matrix is the trick, and it costs you an afternoon. Severity alone over-blocks (every nit becomes a standoff); change-scope alone under-blocks (a "small" auth change sails through). Write down your own Major/Minor/Patch definitions, your severity rubric, and the verdict function - then hand that document to your reviewer, whether it's an AI or a new teammate. If you do nothing else, do the fix prompts: a review comment that includes the instruction to resolve it turns your review queue from a list of complaints into a list of half-finished fixes.

These reviews are the outer loop - the gate code passes on its way out. The inner loop - why our "platform team" is a terminal UI and fourteen markdown files - lands here in two weeks. Next week in the product track: nothing regenerated twice.


This post is part of How a Tiny Team Ships Like a Big One, a series on how six builders run a production AI company. Building at Aithon - if this is how you want to work, talk to us.