The typical AI-assisted code review workflow has the relationship backwards. Teams feed a model a diff, ask whether the change is acceptable, then assign a human to quickly scan the output and approve it. This inverts where the real value should sit.

An AI model can read every line without fatigue and apply consistent standards across pull requests. What it cannot do is understand your organization's engineering standards, context from past decisions, or whether a change should exist at all. Most critically, no machine can be held accountable. Judgment needs intent, and accountability needs a person.

A better model splits the work: agents handle verification by checking changes against defined rules and gathering evidence, while people make the actual judgment calls. Aviator has built this approach into Aviator Verify, a tool structured around seven sequential components.

The anatomy of an intent-driven review

Every change should be evaluated against two layers. Acceptance criteria describe what a specific change is supposed to accomplish. Invariants are the standing rules of an engineering organization or team—standards that hold true regardless of the change.

Without invariants, standards exist only in engineers' memories, forcing either everyone to remember every rule or relying on reviewers to catch obvious agent errors. Without criteria, code may follow all the rules but fail to solve the actual problem, leading agents to overengineer or miss the mark entirely.

Click to enlarge image.

The seven components build both layers, verify changes against them, and route the decision to a human:

  1. Invariants (defined before any change): standing team rules drawn from prior code reviews
  2. Intent and acceptance criteria (captured during the coding session): why the change exists and how it should behave
  3. Core decisions (captured during the coding session): choices made along the way and who made them
  4. A test plan (built at submit): criteria and applicable invariants converted into scenarios
  5. Evidence (gathered at submit): proof from a running environment backing every verdict
  6. A review (decided by a person): intent, decisions, and evidence, approved or rejected—not code
  7. Invariants refreshed (updated after merge): waivers and recurring comments that sharpen the rules

1. Invariants

Most teams encode their standards informally. Senior engineers voice review comments like "Use the Money type for anything with a currency" or "No direct writes to the users table" or "Every error path emits a counter." Each rule gets typed repeatedly, and AI agents keep repeating the same mistakes because the rule was never documented where an agent or verifier could check it.

An invariant is that rule, written once and checked on every matching change. Collectively, invariants form an AI error registry—a running catalog of patterns the team keeps correcting. Agent instruction files like CLAUDE.md help as generation inputs, but the same non-deterministic agent that wrote the code is asked to follow them, with no proof it did. Invariants belong on the verification side, checked by a deterministic script or a separate agent that returns a verdict for each rule.

Team PR history already contains most invariants. Aviator Verify reads GitHub comments and drafts invariants from patterns it finds. It also extracts them from CONTRIBUTING.md, agent instruction files, or on-the-spot when someone tags @aviator invariant in a PR comment or Slack thread.

Three factors determine whether an invariant becomes useful or just noise:

  • Ownership: every draft goes to the team it belongs to with the reason it was proposed, and goes live only after that team approves it
  • Wording: assert the outcome and leave implementation open, so the rule survives renames and file moves
  • Scope: a rule should only run where it can break—a frontend invariant has no business checking database migrations

2. Intent and acceptance criteria

Writing a detailed spec upfront takes time, gets written before implementation teaches anyone anything, and diverges the moment coding begins. The most accurate intent already exists in the coding session itself. Every time an agent asks a question and an engineer makes a decision, acceptance criteria are being defined in real time. There is no reason to discard all that context when the session ends.

Intent explains why the change was made. Acceptance criteria explain how it should behave. Verify captures both from the session the engineer already conducted. An agent skill and a hook run before the agent opens a pull request. The agent extracts intent and criteria from everything it observed in the session, and the engineer reviews and corrects them before submission.

3. Core decisions

A decision is any point where a change could have taken a different path: where state lives, what happens when a dependency fails, whether to reuse an existing helper or write a new one. AI-written pull requests are full of such calls, and almost none appear in the diff itself.

Click to enlarge image.

An AI-written PR is full of calls like these, and almost none of them show up in the diff.

Verify records decisions alongside intent, labeling humans and agents separately so reviewers know who made which call and can challenge it.

4. A test plan

At submission, Verify reads intent and criteria and uses the diff to identify which invariants apply. Both layers merge into a single list of scenarios: the steps an agent takes to validate behavior, derived from requirements rather than code. The engineer stays focused on the change while the registry enforces standards.

5. Evidence

When the same model writes and reviews code, they share the same blind spots. Verification must be structurally separate from generation and must produce more than an opinion.

When the same model writes and reviews the code, they share the same blind spots.

Verify spins up a preview environment and dispatches verifier agents to run the scenarios. They capture screenshots, database state, server logs, and console logs. Every verdict—for a criterion or an invariant—points to that evidence. For UI changes, the verifier actually clicks through the interface and confirms the result.

A preview environment is not necessary on day one. Code scans handle structural checks directly from the diff with no infrastructure, and many invariants convert to deterministic scripts. A preview becomes worthwhile once criteria start asking about behavior the diff cannot show.

6. A review

This is where people return to the process, and the work looks fundamentally different. As a reviewer, you examine evidence rather than reading code line by line. You read the intent, examine the hot spots where core changes occur, go through the decisions and the verdict on each criterion and invariant, and open the live preview if you want to see the change firsthand.

Click to enlarge image.

The pull request workflow barely changes. Verify adds a link to the review, the diff stays in place, and results are reported as a status check similar to CI behavior. The reviewer answers one question: does the evidence match what the team agreed to build? They approve, push back on a decision, ask for another scenario, or waive a failed invariant with a reason. That is judgment, and someone owns it.

7. Invariants refreshed

Most reviews end at merge, and everything they learned disappears. The next PR makes the same mistake, and the same comment appears again. Invariants preserve what each review learned. When an invariant fails on a PR, the author can waive it with a reason: perhaps it does not apply, perhaps the invariant is wrong, or perhaps it gets fixed separately. The team owning the invariants sees every waiver.

Insights show which invariants apply most frequently, how often each one fails, and why people waive them. An invariant that keeps getting waived is wrong, so the team rewrites or narrows it. A comment reviewers keep typing becomes the next draft. This way invariants become a continuously maintained set of rules that guard every code change.

Click to enlarge image.

Where to start

Do not activate everything at once. Begin with invariants, since they are the cheapest component and PR history already contains them. Month one will feel like double work, with the team still reviewing code while the registry fills up. In month two, invariants catch enough that reviews shrink. By month three, reviewers read intent, decisions, and evidence, and open the diff only when something does not add up.

The review process your team already performs is full of rules waiting to be written down. Aviator Verify converts them into invariants, verifies every change against them, and leaves decisions to people.