Skip to main content

The enforcement model

When you run nanny run, Nanny becomes the parent process of your agent. It reads [start].cmd from nanny.toml, spawns it as a child, and owns the process lifecycle. Every tool call the agent makes is evaluated before it happens. Two checks, in order. The allowlist runs first: a tool that is not in [tools] allowed is denied before any rule sees it. Then your rules run, in registration order, and the first one to refuse ends the evaluation. A denial kills the child process immediately. The process cannot catch, delay, or prevent the stop. An ExecutionStopped event is emitted with the reason, and Nanny exits non-zero.

Multi-agent governance

When multiple agents run in the same process, as in CrewAI, LangGraph, AutoGen, or any framework that orchestrates agents within a single Python or Rust runtime, the enforcement model above applies to all of them simultaneously. A single nanny run governs the entire fleet. @agent("role") names which phase of the run the events that follow belong to, so every verdict in the log can be attributed to the agent that produced it. Tool calls from every agent flow through the same allowlist and the same rules: one nanny run governs the whole fleet. For cross-process and cross-machine enforcement, use the governance server.

What Nanny enforces

Two things, and both are about authority: Both require the agent to report its tool calls, through the Rust SDK macros or the Python SDK decorators. Tokens are measured, never enforced. They are recorded for attribution, so you can answer what a run cost, and no ceiling stops a run for spending them. Liability attaches to what an agent was allowed to do, not to how much it used.

Passthrough mode

When running outside nanny run, every macro becomes a no-op:
This means you can ship instrumented code and run it in development, CI, and production without Nanny, until you explicitly wrap it with nanny run. The behaviour is identical either way.