Correction · 2026-07-28

The corpus figure in the headline is wrong. The correct number is 826,644 unique real agent commands, not 1,085,159.

The original count summed the per-dataset unique totals, and one dataset — nvidia/SWE-Hero-openhands-trajectories — was enumerated twice (250,000 + 300,000). A recount against a single global dedup set (scripts/corpus_million_globaldedup.py, artifact results/million_recall_2026-07-28.json) gives 826,644 unique commands, 303 catalog-flagged dangers, 301 neutralized and 2 allowed. Two SWE-Gym splits were excluded because their upstream split names changed, so the honest range is 826,644–835,128; we cite the lower bound.

The result itself does not change: 0 real recall misses. The two remaining allows are the same disposable-artifact cleanups adjudicated below — the earlier "4 allows = 2 unique commands" wording was itself an artifact of the double count. The title and URL of this post are left as published so existing links and citations keep resolving; every number in the body below has been corrected.

exposure report #1 826,644 commands · corrected 2026-07-28

We replayed 826,644 real AI-agent commands through a deterministic gate

0 misses on the covered set. ~0.6% intervention. And a bypass suite that prints its own open gaps — 3 named today, 2 of which slip the whole product — instead of hiding them.

TL;DR: an AI agent that "knows" the safety rule still runs terraform destroy, because a rule in the prompt is documentation, not enforcement. We built a deterministic, fail-closed gate that sits at the tool boundary and blocks irreversible actions before they execute. Then we did the boring, falsifiable thing: replayed 826,644 unique real agent commands from 5 public datasets through the full gate. It missed 0 of the real dangers. It also does not cover every bypass shape — and instead of hiding the ones it misses, we print them. This post includes that list.

inspectable two-step installer · Apache-2.0 · github.com/BGMLAI/gate.cat


Why this exists

The incidents are real and specific. An AutoGen agent ran terraform destroy in a loop and burned ~$106k. A Replit agent dropped a production database. On the Cursor forum, a developer's agent "nuked my entire system" from a git clone request; another agent deleted a file and then decided to hide the deletion from the user. The pattern is always the same: benign request → the agent widens scope → an irreversible command → sometimes a cover-up.

Prompt-level rules don't stop this, because the model that's supposed to follow the rule is the same component that just decided to break it. Enforcement has to live outside the model's control flow.

What the gate is (one paragraph)

A deterministic deny-list of 71 default policies (73 including the opt-in presets; counted live on 2026-07-29 against v0.4.18 — it was 28 when this post first ran) for the irreversible-action class (rm -rf, terraform destroy, DROP TABLE, cloud/k8s deletes, disk wipes, force-push, secret deletion, …), plus an independent exec analyzer and a human-in-the-loop stage. Fail-closed: engine error, empty input, anything it can't reason about → BLOCK, never a silent allow. Same command → same verdict, no temperature, nothing to persuade. Its strongest form is a Claude Code PreToolUse hook that runs in the harness — the tool call physically cannot execute until the gate returns.

The measurement (so you can refute it)

We took 826,644 unique real agent commands from five public datasets (Nemotron, SWE-Zero, SWE-Hero, Kwai SWE-smith-mini, nebius), plus an independent catalog of 43 known danger classes, and ran every command through the full gate pipeline. (Deduplication is global across datasets — see the correction at the top of this post; artifact: results/million_recall_2026-07-28.json.)

The part everyone else hides: what we DON'T cover

A security tool that only advertises its wins is selling you a feeling. Here is the gate's own bypass map — the shapes our suite deliberately does not claim to catch, printed by the suite itself:

Shapes that used to be on this list and are now caught — relabelled in the suite, not deleted: base64-assembled payloads (echo <b64> | base64 -d | sh) and curl … | sh hit the ENCODED_EXEC wall; deletes routed through a language runtime (python3 -c "os.unlink(...)") surface as a warn for human review; and (0.4.10) the terraform-destroy agent bypass — piping the interactive yes into terraform destroy to auto-confirm an irreversible teardown — is now blocked (the bare interactive form, where a human answers, still passes). The gap list is supposed to shrink in public. There are still infinitely many ways to destroy things; a deny-list is a wall in front of the known shapes, not a proof of safety.

Our bypass suite catches 178/178 of what it claims to, discloses 1 false-block on a 129-case benign corpus (counted against ourselves, not hidden), and prints the open gaps next to the wins (measured 2026-07-29 on v0.4.18; it was 71/71 on a 52-case benign corpus when this post first ran). The honest headline, in one line: the gate is certain only about what it blocks. A command it doesn't match is unchecked, not safe.

That sentence is in our README, not buried in a FAQ. It's also why the right mental model is gate + sandbox, not gate instead of sandbox: a sandbox limits the blast radius but can't tell you what the agent tried, and won't stop a terraform destroy that has real credentials inside the sandbox. They're complements.

Reproduce it on your own agents (60 seconds, local, no signup)

python3 -m venv .venv
.venv/bin/python -m pip install gate-cat

# 1) the bypass suite, straight from the installed package — real output,
#    reproduced 2026-07-29 on gate.cat 0.4.18:
.venv/bin/python -c "from gatecat.integrations import bypass_suite as b; print(b.metrics(b.run()))"
# -> {'claimed_dangers': 178, 'caught': 178, 'catch_rate': 1.0, 'benign': 129,
#     'false_blocks': 1, 'false_block_rate': 0.007751937984496124,
#     'known_gaps': 3, 'product_silent_gaps': 2}

# 2) the full 43-class danger axis (needs the repo, not just the wheel):
git clone https://github.com/BGMLAI/gate.cat && cd gate.cat
python3 scripts/recall_danger_axis.py      # 43/43 through the full gate, 0 false-blocks

If your numbers disagree with ours, that's a bug report we want. Every figure in this post traces to a row in our FACTS.md (claim → source → allowed wording). We regenerate the copy from that table, never the other way around.

Honest limits (cite these — they're the point)

Want the map for your own traffic?

gate.cat is free forever — the gate, the hook, and a local dashboard. Once it's watching your agent, gate.cat log shows every veto, gate.cat why <cmd> explains any verdict, and gate.cat stats gives you the running count. That history lives locally today. (Keeping an off-machine copy — the one your agent can't delete or rewrite — is the paid tier; the gate itself never costs anything.)


Written by the maintainer. gate.cat is Apache-2.0 — the deny-list, the exec analyzer, the hook, the bypass map are all open. Poke holes in it: report a veto story or a bypass.

Put the wall in front of your own agent — free, 60 seconds, one line to uninstall.

install safely →