Approval policy
A project’s approval policy decides who has to approve a build before its review can be complete. Builds and snapshots explains what review complete means and what it changes.
The policy only applies when a review approves changes. A reviewer can always finish a review that rejects something, because a rejection doesn’t need a quorum.
Where to set it
Project admins set the policy in Settings → Review Policy, then select Save changes. You can also keep it in the repository with the review_policy section of .pixmoat.yaml. It’s a project-global setting: builds don’t read it from the file, so change it in Settings (see Project configuration).
Without a configured policy, a review that approves anything still needs one human approval.
What each setting requires
| Setting | .pixmoat.yaml key | What it requires |
|---|---|---|
| Minimum approvals | min_approvals | At least this many different people approved screenshots in the build. The lowest value is 1. |
| Required approver role | required_role | At least one of those approvers is a Project Admin or an Org Admin. Organization owners and admins count for either. None turns the rule off. |
| Require distinct approver | require_distinct_from_author | Nothing today. pixmoat doesn’t record who started a review, so this rule is always met. For two-person review, use Minimum approvals (see below). |
| Require CODEOWNERS approval | require_codeowner_approval | Every screenshot with mapped code owners or default reviewers is approved by one of them or an organization admin. See CODEOWNERS for a limit. |
| Branch scope | applies_to_branches | The policy only applies to builds on matching branches. Enter one branch name or glob pattern per line, such as release/*. Leave it empty to cover every branch. |
| Allow agents to finish review | agent_may_finish | Whether an AI agent may finish a review the policy covers. |
Approvals count only when a person made them, one screenshot at a time or with Approve all. Approvals made by an AI agent, and the automatic approval of Flaky and Quarantined screenshots, never count. Because Minimum approvals is at least 1, a person always has to approve before a review on a covered branch can finish.
Why an agent’s approval doesn’t count
The policy exists so that a person has signed off on what ships. An AI agent approves with a token, not as a person, so its approvals can’t stand in for one. In the review, a screenshot an agent approved shows an Agent badge and “Approved by agent”. The decision is kept, but the build still needs the human approvals the policy asks for. For a screenshot to count, a person has to select Change and approve it themselves. Settings → Review Policy notes this next to Minimum approvals: “Agent approvals are excluded unless they use an approver project token.”
Without human approvals, a review an agent worked through stays open with the Review policy not met banner. Allow agents to finish review decides whether an agent may finish a covered review at all. It doesn’t lower what the policy requires.
Minimum approvals above 1
Each screenshot keeps one approver: the last person who approved it. If a second reviewer approves a screenshot that’s already approved, they replace the first approver instead of adding to the count.
So with Minimum approvals set to 2, two people have to approve different screenshots in the same build. A build with only one screenshot to approve can’t meet a minimum of 2. Set a higher minimum only for branches where builds usually change several screenshots, using Branch scope.
CODEOWNERS
Code owners come from the CODEOWNERS file the Playwright client uploads with each build. See Connect Playwright.
pixmoat matches the file’s patterns against snapshot names, not against your source files, when the build finishes. A rule for a source folder such as /src/checkout/ @team-checkout matches no snapshot. Write rules for your snapshot names instead, for example checkout* @team-checkout for every snapshot whose name starts with checkout. As in Git hosts, the last matching rule wins, and * matches everything. If your repository’s CODEOWNERS file is only about source files, snapshots get the owners of its catch-all * rule, or none.
Owner handles such as @team-checkout only count once they’re mapped to pixmoat users. Project admins map them in Settings → Owner Map: select + Add owner handle, enter the handle and select the members it stands for. Mapped owners are added to each matching screenshot as requested reviewers. A handle that isn’t mapped still shows next to the screenshot, but it can’t approve anything, and a screenshot whose owners aren’t mapped to anyone has no owner requirement.
Default reviewers, in the same section, are requested for screenshots that no CODEOWNERS rule matches. The review page lists everyone still needed under Awaiting review from, and Assigned to me filters the list to your screenshots.
Limit: with Require CODEOWNERS approval on, the rule also covers screenshots that didn’t change, and those can’t be approved. If a screenshot that matches its baseline has a mapped owner or a default reviewer, the review can’t finish while the rule is on. Until this is fixed, turn the rule on only with a CODEOWNERS file whose rules cover just the snapshots you want owners to approve, and don’t set default reviewers.
When the policy isn’t met
The review page shows a Review policy not met banner that lists what’s missing, for example “Need 2 distinct approvers (currently 1)”. Finish review stays visible but disabled, with the tooltip “Review policy requirements not met”.
While the policy isn’t met:
- The build isn’t approved, and no baseline changes.
- If a Git provider is connected and the project is in blocking mode, the commit status stays failed. See GitLab CI.
Once the missing people approve, any reviewer can select Finish review.
The verdict gate doesn’t enforce the policy
The CI gate in Connect Playwright reads the build’s verdict. The verdict looks at each screenshot’s current decision, not at whether the review is finished or the policy is met. It becomes PASS as soon as every New and Changed screenshot has an Approve decision, even if one person made them all and the review isn’t finished.
If a merge must wait for the policy, block merges on the pixmoat commit status instead of, or as well as, the verdict gate. In blocking mode, the commit status only passes once the review is complete with the policy met. GitLab CI and Bitbucket show how.
A project token with both the review and approve scopes counts as one approver while its approval remains the current decision. It cannot satisfy required-role, distinct-author or CODEOWNERS rules. See Approver tokens.