Testing the policy before it ships
A policy is code, and code that guards refunds and deletions is worth a test. A handful of assertions, run in CI, turn the gate into something that fails a build the day a change lets a forbidden call through.
test_policy.py
import os
import tempfile
from agent_guard import build_gate
def gate():
db = os.path.join(tempfile.mkdtemp(), "audit.db")
allowed, _ = build_gate(db)
return allowed
def test_delete_is_blocked():
allowed, why = gate()("delete_order", {"order_id": "A17"})
assert allowed is False
def test_big_refund_needs_a_human():
allowed, why = gate()("issue_refund", {"amount": 4000})
assert allowed is False
assert why == "block_big_refunds"
def test_lookup_is_allowed():
allowed, why = gate()("lookup_order", {"order_id": "A17"})
assert allowed is TrueEach test builds a fresh gate over its own database and asserts one thing the policy promises: a delete is blocked, a large refund needs a human, a lookup is allowed. They call build_gate from lesson 26, so they test the same gate the agent uses, not a copy of the rules.
Running the tests
pytest -q -p no:warnings test_policy.pyThree passed. Run this in CI on every change to the policy file or the gate, and a rule that stops blocking delete_order, or a typo that lets a four-thousand refund through, turns the build red before it reaches production.
That is where the course leads: a support agent whose every tool call is checked against a tool allow-list and a policy file, recorded in a log that cannot be edited without detection, and tested before it ships. Each of those was built in an earlier lesson; this part put them in one place and gave them a test.
- Change
refunds.yamlto allow refunds up to 500 and watch which test fails. - Add a test that
send_emailis refused and make it pass. - Add a fourth message to the agent and a test that pins its outcome.
You understood something today that you didn't yesterday.