<!-- https://avertgate.com/docs/constraints-approval · Policy -->

# Constraints and approval

Some calls to the same tool can be free, some forbidden and some approval-gated; the difference lies in the arguments.

## constraints (block)

If an argument constraint is violated the call becomes BLOCK.

<!-- policy.yaml -->
```yaml
- name: "issue_refund"
  allow: true
  constraints:
    amount:  { max: 500 }                 # numeric upper bound
    reason:  { enum: [damaged, late] }    # allowed values
    order_id: { regex: "^ORD-[0-9]{6}$" } # format
```

| Key | Check |
| --- | --- |
| `min`, `max` | Numeric lower/upper bound. |
| `enum` | The value must be one of the listed values. |
| `regex` | The value must match the pattern. An invalid regex configuration blocks the call. |

## require_approval_when (send to approval)

When a threshold is reached it asks a human instead of rejecting:

<!-- policy.yaml -->
```yaml
- name: "issue_refund"
  allow: true
  constraints:
    amount: { max: 5000 }      # above 5000: hard block
  require_approval_when:
    amount: { min: 500 }       # 500 and above: human approval
```

So 0–499 is automatic, 500–5000 needs approval and anything above 5000 is blocked.

## require_approval (always approve)

Every call goes to approval regardless of arguments. For the approval flow see [Approval flow](/docs/approvals).
