Skip to content
Goatfied

workflows

Code-review-first agents: validating changes before they run

Coding agents that propose changes in pull requests before execution let developers review and approve edits rather than debug autonomous commits.

2026-11-068 min readBy Goatfied
Code-review-first agents: validating changes before they run

Most coding agents make edits the moment they decide what to do. They open files, rewrite functions, push commits—sometimes dozens of them—before you've seen a single diff. When something breaks three edits deep, you're left reverse-engineering what the agent thought it was doing.

Code-review-first agents flip this. They propose changes, show you exactly what will happen, and wait for approval before touching your repository. The pattern mirrors how experienced engineers work: draft the fix, review the diff, then merge. It turns out the same discipline that makes human collaboration safer also makes agent loops auditable, reversible, and far easier to trust in production environments.

Why execution-first agents create problems

An agent that writes code directly into your working tree optimizes for speed but trades away control. You see the results only after files change. If the agent misunderstands a requirement or introduces a regression, you're debugging both the original problem and the agent's attempted solution.

The cost compounds in team settings. When an agent commits half-finished work, it pollutes git history, triggers CI pipelines on broken code, and forces teammates to interpret what was supposed to happen. Rollback becomes archaeological work: which of these eight commits do we revert?

Agents that edit in place also make it hard to enforce quality gates. You can't lint code that hasn't been written yet, and running tests after the agent finishes means failures arrive as surprises rather than constraints. The agent operates outside the same compile-test-review cycle that keeps human-authored code reliable.

The review-first loop: plan, propose, validate

A code-review-first agent treats every set of changes as a pull request in waiting. The loop looks like this:

1. Plan: The agent reasons about the task and decides what files to modify

2. Propose: It generates diffs and presents them for review—either human or automated

3. Validate: Linters, type checkers, and tests run against the proposed changes

4. Approve or revise: A human accepts the diff, requests changes, or the agent retries based on validation failures

5. Apply: Only after approval does the agent write changes to disk

This sequence keeps the agent's decision-making visible at every step. You see the plan before it executes. You catch type errors before they land in main. You can reject a diff that's technically correct but violates your architecture without having to undo committed work.

Goatfied's agent loop is built around this flow. When an agent runs a task, it generates a proposed diff, validates it through configured checks (compile, lint, test), and surfaces the result for review. Changes stay in a staging area until you approve. The agent can retry on failures, but it never blindly pushes broken code.

Approval paths: human gates and automated checks

Not every diff needs human eyes. The decision of when to require manual approval versus auto-merging through automated validation depends on risk tolerance and context.

For exploratory work—refactoring a single module, updating dependencies—you might configure the agent to proceed if all checks pass. The validation gates (unit tests green, no lint errors, types resolve) provide enough signal. You review the work afterward as a normal PR.

For changes that touch critical paths—authentication, billing, data pipelines—a human approval step makes sense even if tests pass. The agent still generates the diff and validates it, but it waits for you to confirm the approach before applying changes.

The key is making both paths explicit. An agent shouldn't guess whether a change is safe to auto-merge. Your workflow should declare: these file patterns or these task types require human review, everything else can proceed on green checks.

Small diffs and retry loops

Code-review-first agents work best when they propose small, focused diffs. A 10-line change to a single function is easy to review and cheap to retry if validation fails. A 400-line rewrite across six files is hard to reason about and expensive to regenerate.

This changes how you prompt agents. Instead of "refactor the entire user service," you break work into stages: "extract validation logic into pure functions," then "update callers to use the new validator," then "remove deprecated validator class." Each stage produces a reviewable diff. Each can validate independently.

When validation fails, the agent retries with tighter constraints. If a proposed change breaks type checking, the agent sees the compiler error, adjusts its plan, and regenerates the diff. The retry happens in the proposal layer—before any code lands in your repository.

Goatfied surfaces this as the constraint phase: after the agent drafts a diff, the system runs validations and feeds failures back as constraints for the next iteration. The loop tightens until the diff passes or the agent hits a retry limit and asks for human guidance.

Audit trails for every change

Review-first agents naturally create audit logs. Every proposed diff is a record: what the agent planned, what checks ran, whether it passed validation, who approved it. If a change causes an incident three weeks later, you can trace back to the exact reasoning.

This matters for regulated industries where "an AI agent changed this code" isn't an acceptable answer in a compliance audit. The paper trail needs to show: the agent proposed a change, automated tests validated it, a human reviewed the diff, and the change merged through normal CI/CD.

The log also improves agent performance over time. When you reject a diff, you can annotate why: "violates our error-handling standard" or "changes API contract without deprecation period." Those annotations become examples the agent references in future tasks, tightening its understanding of your team's conventions.

Integrating with existing review workflows

Code-review-first agents don't require new infrastructure. They produce diffs, which map cleanly to the pull request or merge request model every modern VCS supports.

An agent can create a draft PR, populate the description with its reasoning, and request review from the relevant team members. The diff goes through your existing review process: GitHub's code owners approve it, CI pipelines run, automated policies check for secrets or license violations.

For self-hosted setups, the agent can stage changes locally, run validation, and present a summary of what it plans to merge. You review in your editor, accept or reject, and the agent applies the diff or retries.

The pattern also works with hierarchical approval. Junior agents propose changes reviewed by senior agents, which propose larger refactors reviewed by humans. Each layer applies the same validate-then-approve loop, catching issues before they propagate.

What changes need review?

Not every agent task benefits from a review gate. Configuration changes—updating a dependency version, reformatting code—can often auto-merge if checks pass. The diff is mechanical, and the validation provides enough signal.

Code that changes behavior—new features, bug fixes, API modifications—usually justifies review. Even if tests pass, a human should confirm the agent understood the requirement correctly and didn't introduce subtle regressions.

A practical heuristic: if you'd review a teammate's PR for this change, the agent's diff needs review too. If you'd trust a linter or test suite to catch problems, the agent can proceed on green checks.

Building agents that explain their diffs

A diff alone doesn't tell you much. Seeing + if user.is_premium(): doesn't explain why the agent added that check or what edge case it's solving.

Review-first agents should include context with every proposed change: what task they're solving, which files they're modifying, and why each edit is necessary. The explanation can be lightweight—a few sentences per changed function—but it should connect the diff back to the original goal.

Goatfied's agents generate PR descriptions alongside diffs, linking proposed changes to the task prompt. If the agent is fixing a bug, the description references the error message and explains how the diff addresses it. If it's adding a feature, it outlines the new behavior and points to updated tests.

This explanatory layer turns review from "does this code look right?" into "does this approach solve the problem I asked for?" The second question is easier for humans to answer and catches misunderstandings the agent's validation steps might miss.

Related posts

Code-review-first agents: validating changes before they run | Goatfied Blog