# Why reads are never gated: designing an approval gate people keep on (/blog/reads-are-never-gated)

![Illustration: A small friendly robot with a round camera-eye head sits on a bench reading an open book.](/blog/reads-are-never-gated/hero.webp)

Reads are never gated in Smart Approval because a gate that interrupts looking gets switched off within a day. A search, a listing, reading a message: these go straight through. Only writes are judged against your policy, and only the actions your sentences name pause for a person. That restraint is what keeps the gate on.

**Reads go straight through**

* Claude Code, on a customer's $240 refund request, reads first
* Reads, never sent to the judge: `gmail__search_emails` (the customer's thread), `linear__search_issues` (a known bug on the order), `memory__search_memory` (how past refunds went)
* Policy: "Replies to customers who have written to us first are fine. Ask me before any refund over $100."
* Write, allowed: `slack__post_message`, a reply to a customer who wrote first
* Write, ask: `stripe__stripe_api_write`, refund $240, held as a card for a person

## Why does gating everything fail? \[#why-does-gating-everything-fail]

Most of an agent's work is reading. It searches, lists, opens, compares, and only then acts. If each of those steps raises a prompt, the person on the other end learns one thing fast: approve without reading. A prompt that is always answered yes protects nothing. The next step is to turn the gate off, and now the one refund that mattered runs with no one in front of it.

A gate people keep on has to be quiet by default and loud on purpose. The design in [Smart Approval](/docs/approvals) follows from that. Reads never reach the judge. Writes are judged. Your written sentences decide the writes they describe, and a default behavior you choose decides the rest.

So the first question is what counts as a read. A read is a tool that only looks at something. A write changes state somewhere: a message posted, a page created, a refund issued, a pull request merged. Reads are never gated. Every write made through CoreSpeed is judged.

The judge sees the annotations a tool author set, such as read-only and destructive, and treats them as hints. Whether a call is destructive is judged from what the operation and its arguments would do, such as deleting data or causing a loss nothing can undo. A tool marked `destructiveHint` does not automatically ask; a call that would delete something is weighed on its own.

The gate sits between the tool call and execution, in front of the tools, so one rulebook covers every agent and client on the team. It only sees calls made through CoreSpeed.

## What happens to a write your policy never mentions? \[#what-happens-to-a-write-your-policy-never-mentions]

Your policy is sentences, read in context for every judged call. Here is the example from the docs:

```text
Sam handles support. Replies to customers who have written to us first are
fine. Ask me before anything goes to a public channel or an external company,
and before any refund over $100. Never post on our behalf about pricing,
funding, or anything that reads like a product promise.
```

Some call will fall outside everything you wrote. A default behavior decides it:

| Setting            | A write nobody wrote about                |
| ------------------ | ----------------------------------------- |
| Relaxed            | runs                                      |
| Balanced (default) | runs, unless it is destructive, then asks |
| Strict             | asks, for every write                     |
| Lockdown           | refused, for every write, without asking  |

Written rules beat the default. A sentence that addresses the action decides it, whatever the default says. So on Balanced, an ordinary write your policy never mentioned goes through. If that is wrong for your team, raise the default to Strict or write the sentence. The sentence is usually better. It is specific, and every save is a new policy version that records who wrote it and when.

An admin writes the organization's text, which is the ceiling. A member can add their own text, and it can only make things stricter for their own calls.

## Which guards sit above every verdict? \[#which-guards-sit-above-every-verdict]

Three verdicts exist: Allow, Ask and Deny. Two guards sit above all of them. A low-confidence answer becomes Ask. An Allow that looks like prompt injection becomes Ask.

A third rule covers the judge itself failing: a timeout, an outage, a call too large to read, an error. That case is decided by a separate setting on the policy page whose only options are Ask (the default) and Deny. The default behavior does not apply. No failure path lets a write run.

That asymmetry is deliberate. A gate can be wrong in two directions. Asking about a safe write costs a click. Running an unsafe one costs whatever it did. The guards all lean the same way.

## What does the judge see? \[#what-does-the-judge-see]

Your policy. The tool's name and description. The annotations its author set. Who is calling and from which client. How often this caller has used the same tool recently. The argument values, so a sentence about who an email goes to can be applied; turn off "Let the judge read call arguments" on the policy page if you would rather it did not see them. Your agent's conversation is never sent.

The judge is Jev, TypeSafe's System One model. It answers typed questions with calibrated probabilities in one pass, a few seconds at most, and the thresholds that turn a probability into a verdict are deterministic and auditable. A number under the threshold is what turns into Ask.

Before relying on a sentence, use Test policy. It runs a hypothetical call through the same evaluation the gate uses, and nothing is frozen, executed or queued.

## Where does the decision land? \[#where-does-the-decision-land]

An Ask becomes a card: in the dashboard queue, by email, or in Slack through the CoreSpeed bot an admin installs once. Whichever channel decides first wins, and the action runs exactly once. Every verdict is written to the [activity trail](/docs/activity), with the approval id on a gated call.

Smart Approval is a public beta and is off until an organization turns it on at Dashboard → Approvals. The [launch post](/blog/introducing-smart-approval) has the fair comparison with the guards inside Claude Code and Codex.

## FAQ \[#faq]

**Does a read ever pause?**
No. A tool that only looks at something goes straight through and is never sent to the judge.

**On Balanced, does a Slack message my policy never mentioned run?**
Yes. An ordinary write the policy is silent on runs on Balanced. Write a sentence about public channels if you want it to pause.

**What happens if the judge times out?**
The failure setting decides: Ask by default, or Deny if you chose that. A failed evaluation never allows a write.

**Can a member loosen the organization's policy for their own calls?**
No. Member text can only make things stricter for that member's calls.

**Does the judge read my agent's conversation?**
No. It sees the policy, the tool, its annotations, the caller and client, recent use of the same tool, and, unless you turn it off, the argument values.