Method

Your AI wrote the Apex. Who reviewed it, and was it the same AI?

An AI coding agent can write the class, write the test, run the test and fix its own failure in one task. That is fast. It is not a review. Here is what an independent review looks like, drawn out step by step, with a worked example in plain Apex.

Start with what the agent does, in Salesforce’s own words. In the agentic workflow, Agentforce Vibes “generates the Apex class, handler, and test class together as a coordinated unit.” It “runs tests, reads failures, and iterates toward a fix within the same task.” You approve the plan once, and “it executes all changes” (Salesforce: Understand Agentic Development).

So the thing that wrote the code also wrote the test, ran the test, and decided the failure was fixed. That is not a complaint about the tool. It is a description of a loop with one participant.

Salesforce says the next part out loud. “Human review isn’t optional” (Understand Agentic Development). Output “is nondeterministic. The same prompt can produce different results across sessions. Always verify” (Salesforce: Trust and Verification). And on the admin setup page: “All AI-generated code should be reviewed before deployment to production” (Salesforce: Settings and Permissions). The same trust page draws a useful line: “Permission modes protect your filesystem. Code review protects your application.”

Everyone agrees on the word “review.” The gap is what the word means on a Tuesday afternoon when the sprint is late.

What “reviewed” often means

Self-review

  1. PromptA developer describes the change.
  2. AI builderWrites the class, writes the test, runs the test, fixes the failure.
  3. Same AI: “looks good”Asked to check its own work.
  4. Deploy
Figure 1. One participant. The code, the test and the verdict all come from the same model, in the same session, with the same assumptions.

Asking the same agent “does this look right?” is not a review. Gearset’s write-up of Vibes draws the same line, contrasting its scanner with “asking an AI to check its own output” (Gearset blog). Gearset’s code-review page puts it more bluntly: “AI reviewing AI-generated code compounds accuracy risks” (Gearset: Code Reviews).

A worked example: code and test that agree, and are both wrong

Here is the shape of bug that self-review cannot catch. A developer asks for a method that returns open follow-up tasks for a set of accounts, of the type the business calls a “Business Review.” The agent writes this. The class is generic and invented for this article.

FollowUpTaskService.cls
public with sharing class FollowUpTaskService {
    // Open follow-up tasks of the Business Review type for the given accounts.
    public static List<Task> openBusinessReviews(Set<Id> accountIds) {
        return [
            SELECT Id, Subject, ActivityDate, WhatId
            FROM Task
            WHERE WhatId IN :accountIds
              AND Type = 'Business Review'
              AND IsClosed = false
        ];
    }
}
Figure 2. Generic Apex written for this article. It reads cleanly and does what it says.

Then it writes the test, in the same task.

FollowUpTaskServiceTest.cls
@IsTest
private class FollowUpTaskServiceTest {
    @IsTest
    static void returnsOpenBusinessReviews() {
        Account acct = new Account(Name = 'Test Account');
        insert acct;
        insert new Task(
            Subject = 'Quarterly review',
            WhatId = acct.Id,
            Type = 'Business Review',
            Status = 'Not Started'
        );

        List<Task> found = FollowUpTaskService.openBusinessReviews(new Set<Id>{ acct.Id });

        System.assertEquals(1, found.size(), 'Expected one open Business Review task');
    }
}
Figure 3. The test builds its own record with the same value the code filters on.

Now suppose the org’s Task Type list does not contain “Business Review.” Maybe the business says it that way but the field holds a different label. The code returns nothing in production, every time. The test still passes, because the test made its own record with the value the code expects. The test proves the code agrees with itself. It says nothing about the org.

This is not a made-up risk. In the build described in our field note, a repair filtered on a task type that was not in the org’s list of 44 values. Both reviews passed it, and the tests were green, because the tests created their own matching records. The full account is in 38 days, six reviews, one script that says no.

Three things would have caught it, and none of them is the builder checking itself:

  1. A reviewer that did not write it, asked a specific question. Not “does this look right?” but “list every literal value this code filters on, and where in the org each one is defined.” A reviewer with no stake in the code tends to ask where the string came from.
  2. A person checking the reviewer’s list against the live org. Open the field’s picklist values in a sandbox that matches production and compare. A review checks code against itself. Only someone with access to the org can check it against the org.
  3. A test that reads from the org’s own definitions where it can, instead of inventing the value it is about to assert on. That is a habit, and the reviewer can ask for it.

The harness, drawn out

Here is the loop we use instead, and the one we set up with teams. It has more than one participant on purpose.

Independent review

  1. PromptA developer, or a ticket, describes the change.
  2. BuilderAn AI writes the class and the test in a sandbox. It never touches production.
  3. FreezeEvery file is hashed. One fingerprint for the exact package.
  4. Review 1A different model, or a person. Reads only the frozen copy. Returns GO, GO-WITH-CHANGES or NO-GO.
    Review 2Different again. Same frozen copy. Records the fingerprint before and after.
  5. Gate scriptTwo different reviewers, no NO-GO, fingerprint unchanged and equal to what is about to deploy. Otherwise it refuses.
  6. Named person says goIn writing, for this exact release.
  7. ProductionCheck-only validation first, then deploy the validated job.
Figure 4. The harness. A NO-GO sends the change back to the builder and starts a fresh freeze. Every finding also becomes a line in one shared lesson file the team reads the next day.

In words, step by step:

  1. The builder works in a sandbox. Nothing automated reaches production.
  2. When the build is done, it is frozen. Hash every file in the deployable folders, sorted by path, then hash that list. That one fingerprint names the exact package.
  3. Two reviewers read the frozen copy, not the live folder. Neither wrote the code. For us that means AI models from vendors other than the builder’s, or a person. Each records the fingerprint before and after. If it moved, the review is void.
  4. Each reviewer returns one line: who it is, a verdict, and its findings. A NO-GO means a fix round and a fresh freeze. Old verdicts are never reused on new code.
  5. Someone checks every finding against the org before writing a fix. Reviewers can be confidently wrong, too.
  6. A script reads the verdicts and refuses unless there are two landed reviews from two different reviewers, neither is NO-GO, and the fingerprint still matches the bytes about to deploy.
  7. A named person says go. The script cannot do this part. We say so, because teams tend to overstate what their automation enforces.
  8. Production is two steps. A check-only validation, then a quick deploy of that validated job. Not a fresh package.

The builder never reviews its own build. Change one byte after the review, and the review no longer counts.

What a verdict looks like

Keep the format boring, so a script can read it. Here is the shape of a verdicts file for the example above, with placeholder names and a shortened fingerprint.

verdicts.txt
freeze: 3f9a2c… -> 3f9a2c…
REVIEWER_A REVIEW_DONE NO-GO
  MAJOR  FollowUpTaskService: filter value 'Business Review' not traced to the org's Task Type list
  MAJOR  FollowUpTaskServiceTest: test inserts the value it asserts on; proves nothing about the org
REVIEWER_B REVIEW_DONE GO-WITH-CHANGES
  MINOR  FollowUpTaskService: comment says "follow-up" but the filter only covers one type
Figure 5. An illustrative verdicts file. One NO-GO is enough for the gate to refuse. The fix goes back to the builder and gets a fresh freeze.

Notice the second reviewer missed the main bug and flagged something smaller. That happens. It is why there are two reviewers, and why a person still checks findings against the org.

This sits next to your tools, not instead of them

Static scanners are good at the things they are built for. Gearset describes its Code Reviews as deterministic, applying “the same deterministic checks to all code, whether written by humans or AI” (Gearset: Code Reviews). A Gearset post from September 30, 2026, argues that an agent “should do what an agent does well: analyze, surface insights, clarify, and build,” and that “Deterministic solutions should handle the rest: CI/CD with quality gates, testing, code review, and backups” (Gearset blog: the Agentic Development Lifecycle).

We agree with that split. A scanner checks code against rules. A reviewer that did not write the code checks it against the intent. A person checks it against the org. None of the three replaces the others, and none of them should be the builder.

If your team has just switched on an AI coding tool, the minimum is small. Write down who reviews, make sure it is not the builder, tie the review to the exact files, and name the person who says go. The release-gate checklist we use is on the playbook page.

Sources

Every outside page below was read on October 15, 2026. Pages change; the link is the page we read.

  1. Salesforce Developers, Understand Agentic Developmenthttps://developer.salesforce.com/docs/platform/agentforcevibes/guide/afv-agentic-dev.html
  2. Salesforce Developers, Trust and Verificationhttps://developer.salesforce.com/docs/platform/agentforcevibes/guide/afv-trust.html
  3. Salesforce Developers, Settings and Permissionshttps://developer.salesforce.com/docs/platform/agentforcevibes/guide/afv-admin-settings.html
  4. Gearset blog, Agentforce Vibes: governing AI-generated code in your Salesforce orghttps://gearset.com/blog/agentforce-vibes-governing-ai-generated-code-in-your-salesforce-org/
  5. Gearset, Salesforce code review automation solutionhttps://gearset.com/solutions/code-reviews/
  6. Gearset blog, What is the Agentic Development Lifecycle and do you need it? (September 30, 2026)https://gearset.com/blog/the-agentic-development-lifecycle/

Where the numbers come from

  • The Apex in Figures 2 and 3 and the verdicts file in Figure 5 were written for this article. They are not from any customer or employer org.
  • The 44-value filter case is from our own field note, linked above.

Independent. Not affiliated with Salesforce.