What works where
One table. What Control Zero does on your agent today, and where a limit comes from the agent's own hook API rather than from us.
Every row is taken from the SDK's own capability declarations (CoverageDecl).
This page is written by hand. The generated, CI-gated copy of this matrix lives in the SDK repository, where a drift gate fails the build if that page and the implementation disagree. That gate covers only the generated page, not this one. So the authority on your installation is the SDK itself:
controlzero coverage --json # this matrix, as your installed SDK declares it
The --json flag is what emits the machine-readable matrix; a bare
controlzero coverage prints only a short per-host summary. If the two
disagree, trust controlzero coverage --json and tell us.
The matrix
| Your agent | Blocks a bad call | Masks secrets | Covers |
|---|---|---|---|
| Claude Code | Yes | Yes | every tool |
| Gemini CLI | Yes | Yes | every tool |
| Cursor IDE | Yes | No | every tool |
| Kiro CLI | Yes | No | every tool |
| Codex CLI | Interactive TUI: yes. Headless codex exec: no | No | shell/exec, interactive TUI only |
| Cursor CLI | Yes | No | shell/exec |
| Antigravity | Interactive: yes. Headless: advisory | No | every tool |
| Kiro IDE | No | No | nothing — no tool call reaches us |
Blocks a bad call — a deny rule stops the tool before it runs. Not a
warning after the fact.
Masks secrets — a mask rule strips the sensitive value out of the
arguments and lets the call proceed. Where masking is unavailable, a mask match
denies instead. The secret never reaches the tool either way; you lose the
convenience, not the protection.
On Codex CLI, enforcement depends on how Codex is run, and the difference is
total rather than partial. In the interactive TUI, a deny on a Bash command
stops it before it runs. In headless codex exec, Codex dispatches no
hooks at all (upstream Codex
#26452, open) — Control Zero is
never called, so nothing is evaluated, nothing is blocked, and nothing is
recorded. An unattended or CI Codex run is therefore entirely ungated, and its
absence from your audit log is not evidence that nothing happened. Do not put
codex exec on a path where a deny has to hold. Separately, even in the TUI a
deny on an apply_patch write or an MCP tool call is not imposed by Codex today
(#27833, open).
On Antigravity, the covered surface is wide — every tool family is delivered to Control Zero and recorded. What is conditional is the enforcement. A deny is expected to stop the call in Antigravity's default interactive mode, but in its headless and always-proceed modes a deny is advisory, and a denied call has been observed to run anyway. Control Zero cannot see which mode is active, so we cannot tell you which of the two you are getting. It does fail closed in one specific sense: if our hook produces no output at all, the call is denied rather than allowed through.
Treat Antigravity as recorded everywhere and enforced only when you know the host is interactive. If a call must not run, put an enforcing surface in front of it.
On Kiro IDE, no tool call reaches Control Zero. The host does not deliver tool calls to our hook, so they are neither blocked nor recorded — and their absence from the audit log is not evidence they did not happen. Use Kiro IDE for the surfaces it does expose, and do not count it as coverage.
Why masking is limited
Masking needs the agent to accept rewritten tool arguments. That is a much stronger ask than accepting a yes/no verdict, and most agents do not offer it.
Codex CLI — its hook contract permits updatedInput only alongside
permissionDecision: "allow". Masking would therefore also auto-approve the
call, overriding Codex's own confirmation prompt. That would make a command
containing a secret face less scrutiny than the same command without one. We
will not make that trade.
Cursor — the field exists and is documented, but does not reliably work.
Public reports show updated_input silently discarded for Write, and empty
stdin on remote workspaces. Believing we masked when we did not is the one
failure with no recovery, so we do not claim it.
Kiro CLI, Antigravity — no argument-rewrite field exists in the hook protocol at all. Kiro CLI's contract is exit-code only; its standard output is explicitly discarded.
We have asked upstream in each case.
Why Kiro IDE does not govern tool calls
Kiro IDE's hook provider historically did not act on a hook's exit code: any output caused the tool call to be intercepted and the model told the tool did not run, leaving the decision to the model. It also delivered arguments without the tool's name, so rules matching on a tool could not be evaluated.
Kiro 1.0 ships a provider that fixes both. We have not raised our claim yet, because we do not claim a capability we have not observed working end to end. When we do, this page changes with the code, not before.
If you need enforcement on Kiro, use Kiro CLI. It honours exit codes and covers every tool family.
If you only remember one thing
Claude Code and Gemini CLI get the full feature set, including in-place masking.
Cursor IDE, Kiro CLI and Cursor CLI enforce — a deny stops the call — and a mask rule denies rather than masking. Check the Covers column: Cursor CLI evaluates shell/exec only.
Codex CLI enforces in its interactive TUI only. Headless codex exec
dispatches no hooks, so those runs are neither blocked nor recorded. Keep CI off
codex exec if a deny has to hold.
Antigravity records every tool family, but its enforcement depends on the mode it is running in and we cannot detect that mode. Recorded everywhere; enforced only when interactive.
Kiro IDE governs no tool call. It neither blocks nor records them. Put an enforcing surface in the path of anything that matters.
Checking your own setup
controlzero doctor # detected agents, installed hooks, effective policy
controlzero coverage --json # this matrix, as your installed SDK declares it
If coverage and this page ever disagree, trust coverage — it is reading
your actual installation, and this page is maintained by hand — and tell us so
we can correct it.
Our commitment
We would rather tell you a capability is missing than let you assume it is there. A governance tool whose gaps are invisible is worse than no tool, because it also removes the suspicion that would have made you check.
Equally, we will not undersell what works. Every claim above is taken from the
SDK's own CoverageDecl data — the same data controlzero coverage --json
exports.