Repository navigation
0.5.0 — the gate, measured and improved in steps; a reference policy judge
Everything in this release was measured before it was kept, on the same 609 AgentDojo
pairs, and the numbers are in RESULTS.md next to the ones they replace.
The gate, six steps
| Step | Change | Utility, clean | Attack success |
|---|---|---|---|
| 0.4.0 | baseline | 64.9% | 12.6% |
| 1 | a value the user named is theirs, even if an untrusted document also contains it | 75.3% | 13.6% |
| 3 | a fetch is gated on where it goes | 73.2% | 9.5% |
| 2 | content taint — a link or identifier copied from untrusted text into a message body, prose never | 73.2% | 8.9% |
| 5 | the whole policy set drafted from tool schemas, no hand input | 71.1% | 8.9% |
Strict mode is at 0.0% on all four suites. What remains at 8.9% is two known shapes,
named in the docs. The replay itself was fixed on the way: a blocked fetch is a stopped
attack, not a successful one — the injection phase now runs only when a tool result
actually delivered the injection.
A reference policy judge
PolicyGate shipped as a seam with no judge. reasongate.judges.AnthropicJudge is the
first one — off by default, pip install "reasongate[judge]", the core stays
zero-dependency. Measured on the real corpus against the 59% of attacks no input filter
can see:
| Judge | Policy | Recall on the core's misses | Benign flagged |
|---|---|---|---|
| Opus 5 | 4 rules | 85.3% | 3.8% |
| Haiku 4.5 | 4 rules | 77.3% | 6.3% |
| Opus 5 | 5 rules | 92.4% | 25.3% |
The fifth rule was a policy-authoring error the judge itself exposed — it named the
rule — and dropping it is reported as a trade, not a fix. Verdicts are committed under
eval/verdicts/ so the measurement reproduces without the API.
With a model in the loop
Claude Haiku 4.5 and Sonnet 4.5 refused every AgentDojo injection with the gate off. The
gate added no security there and cost 12.5 points of utility. Reported as such rather than
fished for a weaker model: against these models on these attacks, a capability gate is
insurance against the case where the model's judgement fails, priced.
Also
- Multi-hop taint through tool results (
GateSession); authorization no longer launders a
tainted destination; list-valued destinations matched per element. - Tool-call adapters for Anthropic, OpenAI and MCP;
policies_from_schemas. - The gate is memoized per segment: 0.30 ms for a six-token message against a 2 KB
document, verified decision-identical. eval/agentdojo_gate.py(replay and--llm),eval/policy_judge.py,eval/misses.py.
95 tests, Python 3.9–3.12, zero dependencies.