Skip to main content
The hard part of a guardrail is not writing it. It is knowing whether turning it on will break real conversations. zespan policy test runs a policy over your project’s own recorded traffic and tells you both sides:
Two things that matter in that output. The false-positive count is broken down per rule, so you can see that rule [1] is the noisy one and fix it rather than abandoning the whole policy. And each false positive comes with the actual conversation, because we hold the trace — not an estimated rate.

Corpora

Test against both sides. A policy tested only against last:7d will look perfect and tell you nothing about what it catches; a policy tested only against issues tells you nothing about what it breaks. The report says so explicitly when one side is missing rather than letting a one-sided result look clean.
Prompts and completions are separate samples. A rule scoped to pre is never evaluated against text the model produced — it would never see that in production, and counting it would invent false positives that cannot happen.

The deny gate

Promoting a policy to enforcement: deny requires either a test result or an explicit opt-out:
This is deliberately not a hard block. A platform engineer mid-incident has to be able to ship, and a gate that cannot be bypassed just gets worked around permanently. But the default path makes you look at the false positives first. A test result is keyed to the policy’s exact content, so editing a rule invalidates it. That is what stops the gate becoming a formality where an old passing test vouches for a policy that has since changed.
In CI, run zespan policy test --against issues on every pull request that touches policies/. The output is what a reviewer needs in order to approve a change to what gets blocked in production.

What a backtest cannot tell you

A backtest only catches what is in the corpus. It cannot catch attack patterns that have not happened to you yet.
That is exactly why the enforcement ladder does not end at a green test. warn against live traffic remains the second line of defence: it sees novel patterns a historical corpus by definition does not contain. Every report carries this note, because a green test is easy to over-read. Rule types that need agent context — loop_detection, tool_misuse, agent_rate_limit and the other agent-scoped types — are not evaluated in a backtest, and the report says which were skipped rather than counting them as clean.

Next steps

The enforcement ladder

dryrun → warn → deny, and why to start at the bottom.

zespan policy

Every verb and flag.

Local evaluation

Evaluate policies in-process instead of over the network.

Policy as code

The authoring loop and ownership model.