# Limits

Limits bound the work a turn does: how many calls, model requests and minutes it may spend, and how many times a step may try. Running out is recorded, and the policy you chose decides what happens next.

Budget: Workflow Budget → Scope: Scope Budget → Step: Attempts → Policy: OnExhausted

Every counter is also capped by the deployment’s ceilings. A tighter limit inside never enlarges a looser one outside.

## A workflow’s Budget

```yaml
Budget:
  Calls: 40
  Rounds: 30
  Duration: PT5M
OnExhausted: BestEffort
```

- `Calls` (integer): Operation calls the turn may make: tools, workflows run by a step, and the calls a model chose.
- `Rounds` (integer): Model requests the turn may make.
- `Duration` (duration): Working time. Time spent waiting for an answer, or while no worker is running, is not counted.
- `MemoryProbes` (integer): Memory reads the turn may make. After the last one, a read answers that memory is closed.

A workflow that declares a `Budget` also declares `OnExhausted`. The budget applies when the workflow opens a turn; a workflow run by another workflow’s step spends its caller’s budget instead.

## Attempts

Most steps take `Attempts`, one by default: how many times the step may try its work when it fails. A model step has already been tried on every eligible provider before an attempt counts as failed. A step that has failed every attempt applies its own `OnExhausted`, or fails; a failure that reaches the workflow fails the turn’s attempt.

## Exhaustion policies

| Policy | What happens |
| --- | --- |
| `BestEffort` | The best valid result already reached is kept and the flow moves on. It never buys more work. |
| `Wait` | Raises Clarification, saying which counter ran out and how much was spent, and continues on the answer. A decline fails the step. |
| `Return: <value>` | The value you give is used in place of a result, and the flow moves on. |

Each step kind accepts the policies its work can honor, and an upload naming another is refused. Running out is always recorded, as `limit.exhausted` and `step.exhausted`, even when the policy lets the turn continue.

## Scopes

A `Scope` gives a group of steps a budget of their own inside the turn’s, with its own policy.

```yaml
- Scope: Verification
  Budget: { Calls: 10 }
  OnExhausted: Wait
  Steps:
    - ExecuteTool: CheckSanctions
      Operations: [Sanctions]
    - ExecuteTool: CheckRegistry
      Operations: [Registry]
```

## Deployment ceilings

Momor’s deployment caps every workflow. An upload that declares a limit above a ceiling is refused. These are the shipped defaults; a deployment may set its own.

| Ceiling | Default | What it bounds |
| --- | --- | --- |
| Rounds | 50 | Model requests in any one region, before a tighter Budget. |
| Turn duration | 30 minutes | A turn’s working time. Crossing it ends the turn as Timeout. |
| Expression size | 1,000 nodes | One expression’s evaluation. |
| Failed attempts | 3 | Failed attempts of one turn before it is Unrecoverable. |
| Lost-turn check | 1 hour | How long a running turn may make no progress before its attempt is counted as lost. |
| Hook attempts | 5 | How many times a failing hook is tried. |
| Ephemeral runs | 30 minutes | Idle time before an ephemeral run is deleted. |
| Guard cache | 15 minutes | How long a Guard keeps a result where it declares no Ttl. |
| Reply length | 32,000 tokens | The most output, reasoning included, each model request asks for. |
