Reviewing tasks before they are published¶
The review gate is an optional second model that reads each task's changes before anything leaves the working copy. You configure it per project, and it doesn't have to be the model doing the work. A common setup has a fast model write the code and a stronger one, or one from another vendor, review it.
Until the reviewer approves, nothing a task produced is pushed or merged. If the reviewer asks for changes, you choose what happens: the agent is sent back to fix them, the task fails, or the review is only recorded.
Turning it on¶
In the dashboard, open a project's Overview and click the Review gate card (next to Provider and Executor). The dialog sets:
| Setting | Meaning |
|---|---|
| Review each task … | On or off. Switching it off keeps the other settings. |
| Reviewer provider | claudecode, anthropic, openai, ollama, or Same as the project. |
| Reviewer model | Any model of that provider. With Same as the project and no model, the project's own model reviews its work. |
| Effort | Reasoning effort, for a claudecode reviewer. |
| When changes are requested | fix, block or advisory. See modes. |
| Fix rounds before blocking | How many times fix sends a task back (1–5, default 2). |
| Extra review criteria | Your own rules, sent with every review ("reject any change to migrations"). |
On the command line, cloop review gate does the same in the project
directory:
cloop review gate # show the settings
cloop review gate --enable --provider anthropic --model claude-opus-5-5
cloop review gate --enable --model claude-opus-5-5 --effort high # the project's own provider
cloop review gate --mode block --instructions "Reject changes to migrations/."
cloop review gate --disable
| Flag | Default | Description |
|---|---|---|
--enable / --disable |
Turn the gate on or off | |
--provider |
the project's | Reviewer provider |
--model |
see below | Reviewer model |
--effort |
provider default | Reviewer reasoning effort (claudecode only) |
--mode |
fix |
fix, block or advisory |
--max-fix-rounds |
0 (= 2) |
How many times fix sends a task back, at most 5 |
--instructions |
Extra review criteria | |
--json |
false |
Print the settings as JSON |
The settings are stored in the project's state, not in config.yaml, so they
travel with the project to a remote executor
and apply there too. A run that is already going picks up a change at its next
task.
What happens during a task¶
- Before the agent starts, cloop records the state of every repository under the project and starts holding pushes.
- The agent works as usual, including committing and pushing if its task or the project's instructions say so. A push doesn't reach the remote: git reports it as
! [remote rejected] main -> main (held by cloop's review gate: cloop pushes it after the reviewer approves this task; do not retry)
and cloop records it. The agent's prompt explains this, so the agent carries on. 3. When the agent reports the task done, the reviewer reads every change the task made and answers with a verdict and findings. 4. The verdict decides what happens next (modes). 5. On approval, cloop sends the held pushes itself, and the merges it performs (git mode branches and the parallel merge queue) go ahead.
In multi-agent mode (cloop run --multi-agent), the gate holds the pushes of
all three sub-agents (architect, coder and reviewer), and each is told so, as a
single agent is. The gate then reviews the task once, after the pipeline's own
reviewer, and a fix round resumes the coder's conversation.
A task that changed nothing is not sent to the reviewer, because there is nothing to review or publish. The gate works on git repositories: the project's own and any the task clones inside it. In a project directory that is not a repository and contains none, there is nothing to diff or publish, and the gate records "nothing to review".
Modes¶
| Mode | When the reviewer requests changes |
|---|---|
fix (default) |
The findings go back to the agent (in the same conversation when the provider can resume one, so it still knows what it did), and the result is reviewed again. After Fix rounds attempts without an approval, the task fails. |
block |
The task fails at once. Its diagnosis is the reviewer's findings, and nothing is pushed or merged. |
advisory |
The review is recorded and the work is published anyway. |
The gate fails closed. In fix and block mode, the task is blocked as if the
reviewer had rejected it when the reviewer can't be reached, is misconfigured
(a missing API key, for example), or answers without a verdict twice (after a
malformed answer, cloop asks once more for the right format). An "approve" that
lists a blocker or major finding is treated the same way, because the
reviewer contradicted itself.
A blocked task's commits stay in the working copy where the agent made them, for a person to look at. In git mode its branch stays unmerged. Resetting the task runs it again, and the retry is told what the reviewer found.
If a run ends before the outcome is stored, the gate's decision is kept. cloop
writes each decision about a task to .cloop/artifacts/<id>_verdict.json
before it records the outcome, and recovery reads that file first, whether it
is the next run's recovery or the hub's after it notices the run has gone. A
task the gate failed is recovered as failed, not as the TASK_DONE the agent
printed, so tasks that depend on it don't run on rejected work. If a run ends
while the review is still going, recovery runs the task again. The agent's
pushes were held, so none of its work was published, and the retry is reviewed
like any other task.
What the reviewer sees¶
- The goal, the project's instructions, the task, and the agent's final message.
- A diff per repository: the project's own and any repository the task cloned or created inside it (up to 16, four directory levels deep). The diff compares the working tree with where the task started, covering commits, staged and unstaged edits and new files, so uncommitted work is reviewed too.
- If the agent pushed, the diff starts instead where the remote's copy of the branch forks, because the push would publish everything after that point, including commits that were already unpushed before the task began.
- The commits in that range, and every push waiting for the verdict.
- Changes to cloop's own
.cloop/files, by name only. - Your extra criteria and, in a later round, what the reviewer asked for last time.
The diffs share a 60 KB budget. A review that had to be cut says so, and the
reviewer is told not to approve what it could not see. A claudecode reviewer
can open files for context. It runs with --tools Read,Grep,Glob and
--strict-mcp-config, so it can read but has no tool that edits, writes or
runs anything. Everything the agent wrote is given to the reviewer as material
to review, with an instruction to treat any instructions embedded in it as a
finding.
Which model reviews¶
| Reviewer provider | Reviewer model | Model used |
|---|---|---|
| Same as the project | empty | the project's model |
| Same as the project | set | that model |
| another provider | empty | config.yaml's model for that provider (anthropic.model, …), else its default |
| any | set | that model |
The reviewer uses that provider's usual credentials: the claudecode login, or
the anthropic/openai API key in config.yaml or the environment. Its token
spend is billed to the task in the cost ledger under the reviewer's own provider
and model, marked "(review)".
What gets published — and what never does¶
cloop never pushes a commit the reviewer did not see. It replays a held push only if:
- the commit it sends is the reviewed one or an ancestor of it. If the branch moved after the review, the push is refused, and an accepted push is sent at the reviewed commit, whatever the branch points to by then;
- every commit it would deliver (according to the remote-tracking refs) lies in the range the reviewer read.
A forced push is replayed with --force-with-lease against the remote state the
agent saw, so it can't overwrite work that reached the remote during the review.
Deletions and tags are replayed like any other ref update. If a replay is
refused or fails, the task fails too, because its work was approved but not
delivered. The task record says which push and why.
Merges that cloop performs itself go ahead only when the tree being merged is the tree the reviewer approved.
Where to see the outcome¶
- Task list: a
🔍 reviewed ✓chip, or a red🔍 review: not published. - Task details: a Review gate section with the verdict, the reviewer, the number of rounds, the findings, and what happened to each held push.
- Event history: a
reviewrow per task. - CLI: the task's annotations (
cloop task show <id>), and its failure diagnosis when the gate blocked it.
Limits¶
- A guardrail, not a security boundary. Pushes are held through git's
pushInsteadOfin the agent's environment. An agent that tries to get around the gate can unset it, push to a remote configured with an explicitpushurl, or call a forge's API directly. The gate stops an agent that follows its instructions from publishing unreviewed work. What limits a hostile agent in a sandbox is the git proxy, which enforces branch restrictions outside the sandbox. - Where the reviewer runs. The review runs where the task runs, so for a
remote device it runs inside the task's sandbox. A
claudecodereviewer uses the harness credential granted to the run. Any other provider needs its key available there. The device's owncloopmust be a build that includes the review gate; an older one ignores the setting and runs tasks unreviewed. When such a task comes back done without a review, the hub says so on the task and in the project's event history, and names the upgrade. - Parallel tasks in one working tree see each other's changes, so each review includes whatever the other tasks have changed so far. Turn on worktree isolation to review one task at a time.
- Opening a feature's pull request publishes the feature branch as it is. The pull request is where a person reviews it.