When an AI agent writes the code, who reviews it? The rules that keep "approved" meaning something.
In the first post in this series, Nothing Should Merge on an AI's Word, one of the gate's checks was "a person approves it." That sounds like the easy part. It's not.
With human-written code, the author and the reviewer are obviously different people. With AI-written code, the line blurs. Someone writes a prompt, an agent writes the change, and the same someone looks at the diff and clicks approve. Technically a human approved it. In practice, nobody but the requester ever looked.
That's the problem this post is about: keeping approval a real second opinion when the "author" is an agent.
The prompter is the author
The person who starts an AI session is the closest thing that change has to an author. They chose the task, steered the agent, and probably accepted its first plan. They're also the person most likely to approve it quickly, because it does what they asked.
So the rule should be the same as for human code: the person who launched the session can't be the one who approves it, as long as someone else can.
In AI CodeOps that's built in. A code-change review needs one approval from someone other than the person who launched the session. That makes it a two-person rule whenever a second approver exists. The launcher can still reject their own change, because stopping something never needs a second opinion.
Don't lock out the solo developer
A strict two-person rule has an obvious failure: a team of one can never ship anything. Small teams then switch the rule off entirely, and it never comes back on.
The better rule is conditional. The launcher can't approve when anyone else in the workspace can. A solo workspace can still approve its own work. The moment a second approver joins, the two-person rule applies on its own, with no settings to remember.
Five rules that keep approval honest
Separation of duties is the headline, but a few smaller rules matter just as much.
1. Editing after approval resets it. If the change is edited after someone approved it, the approval goes back to pending. Otherwise "approve now, fix it up later" turns an approval into a blank check. This is the same idea as the tested-version rule from the first post: approval applies to a version, not to a pull request.
2. One reject ends it. A single rejection closes the request. Another person's approval doesn't reopen it. If one reviewer saw a real problem, three approvals from people who didn't shouldn't outvote them.
3. A reject needs a reason. Approvals take an optional note. Rejections require a reason. A bare "no" teaches the requester nothing and tends to get worked around.
4. People are counted, not clicks. Votes are counted per distinct person, and voting again replaces your earlier vote. Nobody gets two votes by clicking twice.
5. Approvals expire. A code-change review expires after 7 days. A week-old approval was given against a codebase that has since moved, so it's asked for again.
Approval is one check, not the only one
Approval doesn't open the pull request on its own. The pull request opens only if the quality gate also passes: tests ran on this version, no high or critical findings are open, and policy allows it.
That separation matters. A reviewer shouldn't have to re-run the tests in their head or re-check every file path against policy. The gate handles evidence. The person answers the question only a person can answer: is this the change we actually want?
Policies decide when to ask
Not every action needs a human, and asking for everything trains people to click "approve" without reading. Policies let you decide where approval is worth the interruption.
Each policy rule is allow, ask or deny. When several rules match, the strictest one wins: deny beats ask, and ask beats allow.
A few patterns that work well:
-
Protected paths. Rules on file patterns, such as
infra/**or anything under auth and payments, are checked when the pull request opens, against every file the change touches. The agent can still write the change; it just can't ship it without passing the rule. - Ask before starting risky work. Dispatching certain workflows or agents can be set to ask, so a person signs off before the session even starts.
- Some actions can't wait. Running a shell command, calling an MCP tool or deploying can't pause for a person, so those can only be allowed or denied, never "ask." That's a useful constraint: it forces you to decide ahead of time.
- Try rules in log-only mode first. A rule set to log only records what it would have done without blocking anything. Run it for a week, check what it would have stopped, and then enforce it.
Every policy change is saved as a new version with an audit entry, so "who loosened this rule?" always has an answer.
Approvals belong in the record
The last piece connects to the next post in this series. The approval, the list of people who were eligible to approve, and each vote with its time and note all go into the change's signed evidence pack. Months later, "who approved this?" isn't a Slack search. It's a field in a record you can verify.
The checklist
- The launcher doesn't approve. Require someone other than the person who started the session, whenever someone else can.
- Keep solo teams working. Make the rule conditional instead of switching it off.
- Approve versions, not pull requests. Any edit after approval resets it.
- Let one "no" win, and make it explain itself.
- Ask only where it matters. Use protected paths and ask rules for risky areas, and try new rules in log-only mode first.
An approval is only worth something if the person giving it could have said no, and wasn't the one who asked for the change.
AI CodeOps is free during the open beta and free forever for non-commercial open-source projects. The full rules are in the approvals and policies docs.
Drafted with AI assistance and edited by the AI CodeOps team.
Top comments (0)