> ## 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.

# The nine gates

> What each gate asks, the order they run in, and why the order is part of the design rather than an implementation detail.

Every authorisation runs the same nine checks in the same order. The order is
fixed, it is part of the specification, and it is doing three jobs at once.

| # | Gate            | What it asks                                   |
| - | --------------- | ---------------------------------------------- |
| 1 | `authority`     | Is there any authority for this at all?        |
| 2 | `status`        | Is the grant active?                           |
| 3 | `window`        | Is now inside the grant's window?              |
| 4 | `scope`         | Does the grant cover this action?              |
| 5 | `clean_context` | Was the context clean, where that is required? |
| 6 | `bounds`        | Do the per-action limits hold?                 |
| 7 | `policy`        | Does the policy on the grant permit it?        |
| 8 | `budget`        | Is there room under the ceiling?               |
| 9 | `review`        | Does this need a person?                       |

## Why this order

**Cheap before expensive.** Gates 1 to 4 are structural: does an authority
exist, is it live, is it in date, does it cover this. They are lookups. Policy
evaluation at gate 7 is the expensive one, and an action that fails at gate 1
never reaches it. That is what makes the check affordable on the path of every
consequential action rather than something you sample.

**Scale before kind.** `bounds` sits ahead of `policy` on purpose. Policy asks
whether this action is permitted; bounds asks how much of it there may be. In
practice the dangerous agent is often the one doing a permitted thing at a scale
nobody set a number on, and that check should not be gated behind the expensive
one.

**Budget is debited last.** After every structural check has passed. An action
refused at gate 1 does not consume the allowance it never used, which sounds
obvious and is the sort of thing that is wrong in systems that reconcile
afterwards.

## Short-circuiting is a feature of the record

The gates short-circuit. When an authorisation stops at gate 7, gates 1 to 6
passed and gates 8 and 9 **were never reached**, and the record says exactly
that rather than leaving them blank or defaulting them to a pass.

<Note>
  This is why a record can be read years later without knowing which release was
  deployed. "Not reached" is a recorded fact about that decision, not an absence
  of data.
</Note>

Here is a real decision from the running demo, refused at gate 7:

```
refund-assistant-enforce:TICKET-98130:p2   ·   prod   ·   issue_refund   BLOCKED

1 authority   passed      4 scope        passed     7 policy   refused
2 status      passed      5 context      passed     8 budget   not reached
3 window      passed      6 bounds       passed     9 review   not reached
```

## Reading a refusal

The gate that stopped an action is the most useful field in the record, because
it tells you which conversation to have.

<AccordionGroup>
  <Accordion title="Stopped at authority, status or window">
    An administrative problem, not a policy one. The grant expired, was revoked,
    or never existed. Somebody needs to issue or renew one; nobody needs to
    debate what the agent should be allowed to do.
  </Accordion>

  <Accordion title="Stopped at scope">
    The agent tried something outside what was granted. Either the agent is
    doing more than intended, or the grant was drawn too narrowly. Both are
    worth knowing and they look identical from a log file.
  </Accordion>

  <Accordion title="Stopped at clean_context">
    Untrusted content entered this trajectory and this action requires that it
    had not. See [Clean context](/concepts/clean-context).
  </Accordion>

  <Accordion title="Stopped at bounds or budget">
    The action was permitted and there was no room. `bounds` is a limit on
    scale, `budget` on spend, and `exhausted` is a different outcome from `deny`
    because retrying cannot help.
  </Accordion>

  <Accordion title="Stopped at policy">
    The rule on the grant refused it. This is the one that is genuinely a policy
    conversation.
  </Accordion>

  <Accordion title="Stopped at review">
    Not a refusal. A person has to decide, and the trajectory parks until they
    do.
  </Accordion>
</AccordionGroup>
