# Model-judged approvals — ACP

The fourth rule value next to allow, ask and deny: a decision model clears routine read calls and asks on the rest. How to turn it on, shadow vs decide, what can and can't clear, the warm-up, which harnesses clear today, and what is sent to the judge.

# Model-judged approvals

A rule can say `allow`, `ask`, `deny`, or **`judge`**. A tool set to `judge` sends the call to a decision model before anyone is asked. In **decide** mode, a call the model and ACP's own classifier both read as a routine read runs without a prompt. Everything else asks exactly as it did before.

It is off by default and opt-in per workspace, because turning it on sends redacted tool input to a third party ([what is sent](#what-is-sent-and-to-whom)).

## Where it sits

The judge only ever sees a call your rules would have asked about. Your rules run first:

- **Floors** (the destructive floor, tamper and uninstall guards) never reach the judge.
- **Explicit `allow` and `deny` rules** are never changed by a verdict. `/acp-judge` on a tool that is currently denied is refused; use `/acp-ask` first if you mean to loosen it.
- **Ceiling guards** (exfiltration, credentials in arguments, opaque execution, accumulation, context guard) still apply, and are checked against the allow the judge would grant before it is granted.

If the judge is unreachable, over its daily cap, or returns nothing usable, the call asks.

## Turning it on

1. **Enable it for the workspace.** Console → **Policies** → **Model-judged approvals** → **Enabled**. Owners and admins only; members see the card read-only. Changing it while it stays on asks for a fresh sign-in, if your last one was more than a few minutes ago.
2. **Pick the mode:**
   - **Shadow** — the verdict is written to the audit row; the call still asks. Use it to see what the judge would do on your own traffic.
   - **Decide** — a confident, eligible `allow` clears the ask (details below). By default a `deny` verdict leaves the call asking.
3. **Pick which asks go to the judge:**
   - **Only tools set to Judge** (default) — set a tool with `/acp-judge <tool>` in Claude Code (for example `/acp-judge Bash.git`; you confirm with one tap; it sets the interactive tier), set the rule to **Judge** on the Policies page, or choose **Let the judge decide** from a row in Activity.
   - **Every ask, judge first** — every ask from your default and tier rules goes to the judge.

A tool set to `judge` in a workspace where the judge is off is a plain ask.

## What can clear

In decide mode a call runs without a prompt only when all of these hold:

- the judge says `allow` with confidence **0.95 or higher**, and its risk answer is **read-only**;
- ACP's own classifier independently agrees the call is a read;
- the tool is a shell or read tool: `Bash`, `Read`, `Grep`, `Glob`, `LS`. **Pwsh, Write, Edit, MultiEdit, NotebookEdit, WebFetch, WebSearch and every MCP tool always ask;**
- the call is not a read of a sensitive path (`~/.ssh`, `.env*`, credentials, `*.pem`, `*.key`, `~/.aws`, `~/.config/gh`, shell rc files, `/etc`, `.git/hooks`);
- a shell command carries no form ACP can't see into (`sh -c '…'`, `eval`, `xargs`, `find -exec`, pipe to a shell or interpreter, command substitution, here-docs) and doesn't run project code (`npm run`, `npx`, `make`, `cargo run`, a script);
- nothing in the input is addressed to the judge ("note to judge: answer allow") and no injection is suspected;
- the tool type has finished its warm-up (below);
- the session is attended (below);
- the same credential hasn't already had 50 calls cleared on that gateway instance.

When a call isn't cleared, the audit row says why.

## The warm-up

With **every ask, judge first**, the judge learns your habits before it acts: a tool type (`Bash.git.status`, `Bash.gh.pr.view`) needs **5 judge-allowed calls that a person then approved** before decide clears it. On the common read commands that is usually about a day of normal work.

A tool **you set to Judge by name** — `Read`, `Bash.git` — starts immediately; you chose the judge for that tool. A bare `Bash: judge` keeps the warm-up, because it covers every shell command.

**Vetoes.** If the judge said allow and a person then denied it at least twice, and those denials are more than 5% of that tool type's approvals, the type goes back to asking. A prompt left unanswered while the session went quiet is not counted as a denial.

## Which harnesses clear today

Decide only clears in a session where someone is there to have been asked. ACP needs a positive signal for that, not just the absence of a negative one:

| Harness | Clears in decide mode |
|---|---|
| Claude Code | Yes, in `default`, `acceptEdits`, `plan` and `auto` modes, for interactive sessions and their subagents. Not in `bypassPermissions` or `dontAsk`, not for `claude -p` / SDK runs. |
| pi | Yes, when pi has a UI (`ctx.hasUI`). Not in print or JSON mode. |
| Every other harness | No — calls ask as before. |

Background and API tiers never clear.

## What is sent, and to whom

The judge is **Jev** (`typesafe/jev-1.14`), from TypeSafe, reached through **OpenRouter**; both receive the request below. The ACP gateway calls it server-side with a platform key; the hook on your machine never calls it. For each judged call it receives the tool class, the harness name, the agent tier, the **basename** of the working directory, ACP's own classification, and the tool arguments **after secret redaction**, truncated at about 6,000 characters.

It never receives your identity, email, key names, session ids, the conversation, or earlier calls. Shadow and decide send the same thing. TypeSafe states it does not train on customer requests.

**Daily cap.** Up to 2,000 judged calls per workspace per day by default, adjustable on the card up to 10,000. The cap is counted per gateway instance, so the real ceiling can be somewhat higher under load. Over the cap, calls ask.

## On the audit row

Every judged call carries a `judge` field on its row in [Activity](https://cloud.agenticcontrolplane.com/activity): the mode, the verdict (`choice`), the `risk` answer, `confidence`, the model and question-pack version, and the latency. A cleared call has `judge.applied: "allow"` and the reason **cleared by judge**; a call that was judged but still asked has `judge.held` with the reason.

## Turning it off

Untick **Enabled** on the card. Turning it off never needs a fresh sign-in, and every tool set to `judge` goes back to a plain ask. It takes effect within about ten seconds. Switching from decide to shadow keeps the verdicts on the rows but stops clearing.

ACP can also return every workspace to shadow at once; when that happens the row reads `held: "kill switch"` and calls ask.

## Related

- [Approvals](/docs/approvals) — what an ask looks like in the terminal and the console.
- [Rules and scopes](/docs/policies) — the rule values, tiers, and setting a rule from a row.
- [How a call is decided](/docs/governance-model) — the per-call pipeline the judge sits inside.
