# Shadow mode

A policy that observes instead of enforcing: every request is decided and sealed as observe, with what the policy would have done.

Status: Live · Updated: 2026-09-13
For: finance
Source: https://enruta.ai/docs/shadow-mode

Shadow mode is how a policy is tried before it is trusted. The policy runs on every request; a decision that would have been `step_up` or `deny` comes back as `observe`, the mandate is issued as on `allow`, and the record says what an enforcing policy would have done.

## Turning it on

Set `shadow: true` on the policy in the console editor (the editor notes that `observe` decisions are sealed and reported, never enforced) or in the document sent to `POST /v0/policies`. Signing it produces a new version; taking it off produces another. Any policy can be in shadow mode; a company that already runs an enforcing policy can shadow a stricter draft next to it.

## What `observe` means

| Field | Value on an observed request |
|---|---|
| `decision.result` | `observe` |
| `decision.shadow_result` | `{ result: "step_up" \| "deny", reasons: [...] }`: what the policy would have done |
| `decision.reasons` | `[]`; the reasons live in `shadow_result` |
| `approval_required` | `false`; nothing enters the approval queue |
| Budget | Reserved exactly as on `allow` |
| Mandate and credential | Issued as on `allow`; the money moves if the agent pays |
| Record | Sealed like an `allow`; counted in the weekly report as observed |
| Risk assessment | Made and signed as always; `action` reflects the enforcing outcome (`manual_review` or `blocked`) so the merchant’s signal is honest |

Two rules. Each step is decided on its own: an `observe` on one request carries no authorization into the next. And an observed decision goes to the weekly report, not to the approval queue: nobody is asked to sign something that was not enforced.

## What the agent sees

```ts
request_payment(…)
→ {
  decision: { result: "observe", reasons: [], shadow_result: { result: "step_up", reasons: ["approval_required"] } },
  mandate: { id: "mnd_01M2T7…", amount: "180.00", … },
  risk: { action: "manual_review", score: 0 },
  record_id: "rec_01M2T7…",
  summary: "Observed (shadow mode): allowed; an enforcing policy would have asked a person (approval_required)."
}
```

The skill tells the agent to say so to the person in one line and carry on. Hosts with MCP Apps show the decision card with an “Observed (shadow mode)” badge.

## Two uses

- **Before enforcing.** A team that has never had a policy shadows one for four weeks and reads the report: how many requests would have stepped up, how many would have been denied and why. That report is the reason to switch it on.
- **Before tightening.** A team with a live policy shadows the next version (a lower cap, a new approval threshold) and sees what it would have stopped before anybody is interrupted.

## What is reported

The [weekly report](https://enruta.ai/docs/weekly-report) counts observed decisions and lists their `shadow_result` reasons next to the exceptions. `GET /v0/records?kind=payment` and the console’s payments list filter on `observe`. The [compliance export](https://enruta.ai/docs/compliance-export) includes them like any record.

> Budget and shadow mode: an observed request reserves the budget like an allowed one, so the budget line in the report reflects money that actually moved. Whether the shadow result should additionally be computed against an unreserved budget is an open question for the November release; the report notes the rule it applied.
