> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rotascale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Move up the ladder

> Observe to shadow to canary to enforce, one grant at a time, and what to watch at each rung before you climb.

Enforcement is a mode on a grant, not a global switch. Move one grant, watch it,
then move the next.

<Steps>
  <Step title="Sit in observe for a fortnight">
    Against real traffic, not a staging replay. You are looking for the gap
    between what you believe the agent does and what it attempts.

    ```python theme={"system"}
    # Nothing to change in your code. The mode lives on the grant.
    decision = rs.authorize(...)
    decision.suppressed      # True when a refusal was recorded, not applied
    decision.policy_outcome  # what the policy decided
    decision.enforcement_mode
    ```

    <Tip>
      The first week reliably contains at least one behaviour nobody knew about.
      That finding is usually worth the integration on its own.
    </Tip>
  </Step>

  <Step title="Move to shadow and feed it your incumbent">
    Shadow exercises the full decision path, still refusing nothing. Pass what
    your existing system or reviewer decided, and the **divergence** is the
    signal:

    ```python theme={"system"}
    rs.authorize(..., incumbent_decision="approved")
    ```

    Where the policy and your incumbent disagree is where one of them is wrong.
    Usually it is the policy, and finding that out here costs nothing.
  </Step>

  <Step title="Canary">
    The first rung that refuses. Pick the grant where a mistake is most
    expensive rather than the one that is easiest, because the cheap one teaches
    you nothing about the hard case.

    Watch refusal volume for a fortnight. A rate near zero usually means the
    bounds are drawn too wide to be doing work, not that everything is fine.
  </Step>

  <Step title="Enforce">
    Refusals apply to everything under the grant. Nothing changes in your code;
    the exceptions you already handle start being raised for real.
  </Step>
</Steps>

## What to check before each step up

* **Are refusals being handled by type?** A bare `except Blocked` that swallows
  `Exhausted` and `Gated` is survivable in observe and is an incident in
  enforce.
* **Does the on-call team know what a refusal looks like?** The console names
  the gate and the reason. Somebody should have seen one before it wakes them.
* **Is the failure mode agreed?** Enforcement fails closed. If your team cannot
  accept that, decide it now and record it, rather than discovering it during
  an outage.

## Rolling back

Move the grant down a rung. It takes effect on the next authorisation, and the
records either side say which mode was live, so the change is legible
afterwards rather than being a gap in the timeline.
