Agent Governance Toolkitagent-governance-toolkit 4.1.0 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
28 small wins to finish your pathNext lesson

Shadow mode: watching without acting

Before a policy blocks anything in production, you want to see what it would do to real traffic. Shadow mode runs the whole gate and lets nothing through: an allowed call is recorded as a simulation rather than run.

The flag on the kernel

Example
from agent_control_plane import AgentKernel, PolicyEngine

policy = PolicyEngine()
policy.add_constraint("support", ["lookup_order", "issue_refund"])
shadow = AgentKernel(policy_engine=policy, shadow_mode=True)
print(shadow.intercept_tool_execution("support", "lookup_order", {"order_id": "A17"}))

In lesson 5 an allowed call returned None, meaning proceed. With shadow_mode=True the same allowed call comes back as a dictionary with status of simulated instead. The gate ran, the call was permitted, and nothing was handed back to execute.

A blocked call is still blocked

Example
from agent_control_plane import AgentKernel, PolicyEngine

policy = PolicyEngine()
policy.add_constraint("support", ["lookup_order", "issue_refund"])
shadow = AgentKernel(policy_engine=policy, shadow_mode=True)
verdict = shadow.intercept_tool_execution("support", "delete_order", {})
print(verdict["status"], "|", verdict["mute"])

Shadow mode changes only the allowed path. A policy violation is refused exactly as in enforcing mode, with the muting verdict from lesson 5. So shadow mode never lets through something a policy forbids; it withholds the calls a policy would have allowed.

Running an agent in the dark

Example
from agent_control_plane import AgentKernel, PolicyEngine
from pretend_agent_governance import PretendAgent, TOOLS, REFUNDS

policy = PolicyEngine()
policy.add_constraint("support", ["lookup_order", "issue_refund"])
shadow = AgentKernel(policy_engine=policy, shadow_mode=True)
agent = PretendAgent()
for message in ["Where is order A17?", "refund order A17 for 40", "delete order A17"]:
    tool, args = agent.decide(message)
    verdict = shadow.intercept_tool_execution("support", tool, args)
    print(f"{tool:13}", verdict["status"] if verdict else "allowed")
print("refunds actually made:", len(REFUNDS))

Two calls were allowed and simulated, one was blocked, and no refund was made: the money-moving tool never ran, because a simulated verdict is not a green light to call it. That is what shadow mode is for. Point it at a copy of live traffic, read the log, and see what the policy would do before it does it for real.

This is the imperative counterpart of the audit action from lesson 14. The audit action, written in a policy document, lets a call through and marks it worth recording; shadow mode, set on the kernel, holds every allowed call back and records the simulation. Both watch without the real consequence; they differ in whether the call still runs.

Try it yourself
  • Turn shadow_mode off and run the same loop; note which tools now run for real.
  • Add a FlightRecorder from lesson 20 and read what shadow mode logs for a simulated call.
  • Give the agent a message that routes to send_email and see whether shadow mode simulates or blocks it.

This is what real progress feels like.