Skip to main content

Protection Levels: Monitor, Protect, Govern

Vesanor offers three levels of workflow governance. Start with Monitor, move to Protect when you're ready to block, and upgrade to Govern when you need durable server-backed state and stronger evidence.


The three levels

LevelWhat it doesBlocks bad calls?Server-backed state?Best for
MonitorCaptures every tool call. Computes what enforcement would do, but doesn't apply it.NoNoLearning what your agent does, shadow testing
ProtectEnforces contracts locally. Blocks illegal tool calls before they execute.YesNoMost teams. Fast local governance, zero infrastructure.
GovernAdds durable server-backed session state, pending-call tracking, and stronger evidence.YesYesShared sessions, durable review trails, stricter operational controls

Monitor — watch without blocking

Monitor mode captures everything your agent does without changing its behavior. Use it to understand your agent before writing enforcement rules.

import OpenAI from "openai";
import { replay } from "@vesanor/replay";

const session = replay(client, {
contractsDir: "./contracts",
agent: "my-agent",
mode: "shadow", // Compute enforcement, don't apply it
apiKey: process.env.VESANOR_API_KEY,
});

// Agent runs normally — nothing blocked
const response = await session.client.chat.completions.create({
model: "gpt-4o-mini",
messages,
tools,
});

What you get:

  • Every tool call captured with full context
  • shadow_delta — shows what would have been blocked by your contracts
  • Counterfactual analysis on the dashboard
  • No risk — your agent behaves exactly as before

When to use Monitor:

  • First deployment of replay() — see what your contracts would catch
  • Testing new contracts before enabling enforcement
  • Capture-first review without blocking

Protect — block locally, no server needed

Protect mode enforces contracts on every call. Illegal tool calls are blocked before they execute. No server connection needed — everything runs in-process.

const session = replay(client, {
contractsDir: "./contracts",
agent: "my-agent",
mode: "enforce", // Block illegal calls
gate: "reject_all", // Throw on any blocked call
});

// This call passes — lookup_customer is valid in triage phase
const response = await session.client.chat.completions.create({
model: "gpt-4o-mini",
messages,
tools,
});

// Check session state at any time
const state = session.getState();
console.log(state.currentPhase); // "customer_identified"
console.log(state.totalStepCount); // 1
console.log(state.forbiddenTools); // []

What you get:

  • Contract enforcement on every call (phases, preconditions, limits, forbidden tools)
  • Tool narrowing — illegal tools removed before the LLM sees them
  • Session state tracking across calls
  • Kill switch (session.kill())
  • Local captures for debugging

What you don't get:

  • Server-backed durable state (if your process crashes, state is lost)
  • Governed execution receipts or durable commit records
  • Multi-worker coordination

When to use Protect:

  • Most teams, most use cases
  • Single-process agents
  • Fast iteration on contracts
  • When you don't need a durable server-backed trail

Govern — server-backed governed sessions

Govern mode connects to the Vesanor server. Session state is durable. Every governed call goes through a preflight/proposal/receipt pipeline that creates a durable server-backed record.

const session = replay(client, {
contractsDir: "./contracts",
agent: "my-agent",
mode: "enforce",
apiKey: process.env.VESANOR_API_KEY, // Connects to server
tools: { // Wrap tool executors
issue_refund: myRefundFunction,
delete_record: myDeleteFunction,
},
});

What you get (on top of Protect):

  • Durable session state — survives process crashes
  • Governed execution receipts — Replay records that a wrapped tool path ran with specific arguments
  • Authoritative commit decisions for the governed session state
  • Prepared request binding — each call is bound to a specific session state version
  • Graceful degradation — falls back to Protect if server is unreachable

When to use Govern:

  • Multi-worker agents that need shared state
  • Durable review and recovery across crashes or retries
  • High-risk workflows where server-backed session state and approvals matter
  • Cases where local-only state is not enough

How to migrate between levels

The migration path is additive. Each level builds on the previous one.

Step 1: observe() to Monitor

If you're already using observe(), switch to replay() with shadow mode:

// Before: observe()
const { client, flush } = observe(openai, {
apiKey: process.env.VESANOR_API_KEY,
});

// After: replay() in shadow mode
const session = replay(openai, {
contractsDir: "./contracts",
agent: "my-agent",
mode: "shadow",
apiKey: process.env.VESANOR_API_KEY,
});
const guardedClient = session.client;

Note: observe() monkey-patches your client in place. replay() returns a wrapper — you must use session.client, not the original client.

Step 2: Monitor to Protect

Change mode from "shadow" to "enforce":

const session = replay(openai, {
contractsDir: "./contracts",
agent: "my-agent",
mode: "enforce", // Now blocking
gate: "reject_all",
});

Step 3: Protect to Govern

Add your API key and wrap your tool executors:

const session = replay(openai, {
contractsDir: "./contracts",
agent: "my-agent",
mode: "enforce",
apiKey: process.env.VESANOR_API_KEY, // Server connection
tools: { // Governed execution
issue_refund: myRefundFunction,
},
});

Choosing the right level

Do you need to block bad calls?
No → Monitor (shadow mode)
Yes ↓

Do you need server-backed state or durable governed records?
No → Protect (local enforcement)
Yes ↓

Do you need server-backed receipts and state coordination?
No → Protect with API key (server captures, local enforcement)
Yes → Govern (server-backed governed pipeline)

Most teams should start with Protect. It's fast, effective, and requires no infrastructure. Move to Govern when your workflow needs durable server-backed state, approvals, or coordination.


What stays the same across all levels

Regardless of protection level:

  • Same contract format — YAML contracts work at all levels
  • Same enforcement pipeline — narrow, pre-check, validate, gate
  • Same session state model — phases, preconditions, forbidden tools, limits
  • Same kill switchsession.kill() works at every level
  • Same APIsession.client, session.getState(), session.getHealth()

The main difference is where state lives (local vs server) and how much of the execution path is durably recorded.


Next steps

  • Quickstart — get running in 5 minutes with Protect mode
  • Govern Mode — deep dive into server-backed governed sessions
  • Shadow Mode — test contracts safely before enabling