> For the complete documentation index, see [llms.txt](https://docs.interactive.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.interactive.ai/agents/concepts/policies.md).

# Policies

> **Context** — Policies are one of the two behavioural building blocks of an agent (the other is [routines](/agents/concepts/routines.md)). This page defines the model; [Authoring policies](/agents/guides/authoring-policies.md) covers how to write good ones.
>
> YAML examples follow **manifest schema 6.1.1**. Manifest and content shapes are schema-versioned and differ across runtime versions — see [Versioning & compatibility](/agents/operations/versioning.md).

## What a policy is

A policy is a standalone **condition → action** pair, written in natural language, stored as a versioned YAML document in the platform catalog and referenced from the manifest:

```yaml
id: minimum-driver-age
name: Enforce Minimum Driver Age
condition: >
  The user mentions a driver who is under 21 years old, or asks whether
  someone under 21 can rent.
action: >
  State plainly that the minimum driver age at DriveAway is 21, so the
  booking cannot proceed for that driver. If there is another adult in
  the party who is 21 or older, offer to book under that person's name
  instead. Do not invoke the booking tool with an under-age driver.
criticality: HIGH
```

On every turn, the **policy matcher** evaluates each policy's `condition` against the conversation (in batches of `policy_batch_size`, default 5, per evaluation-model call). When a condition matches, the policy's `action` becomes a binding instruction for the rest of the turn — layered on top of whatever routine is active.

## Fields

| Field              | Type                        | Required | Default            | Meaning                                                                                                                                                                                                                         |
| ------------------ | --------------------------- | -------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`               | string                      | yes      | —                  | Stable identifier the engine keys the policy on. For stored policies it matches the catalog name the document is published under (what the manifest's `context.policies[].id` references).                                      |
| `condition`        | string                      | yes      | —                  | Natural-language condition the matcher evaluates each turn. Required even with `always_match: true`.                                                                                                                            |
| `action`           | string                      | no       | —                  | What the agent must do when the condition matches. May include both tool usage and customer-facing messaging. Omit for an **observation** — a condition-only policy whose match informs the turn without prescribing an action. |
| `name`             | string                      | no       | falls back to `id` | Display label for the platform UI. Cosmetic — not used for matching.                                                                                                                                                            |
| `description`      | string                      | no       | —                  | Free-form rationale shown to operators; not used for matching.                                                                                                                                                                  |
| `criticality`      | `LOW` \| `MEDIUM` \| `HIGH` | no       | `MEDIUM`           | Weight when matched policies compete for attention in a turn.                                                                                                                                                                   |
| `always_match`     | boolean                     | no       | `false`            | Skip the matcher; the policy applies on every turn.                                                                                                                                                                             |
| `track`            | boolean                     | no       | `true`             | When `true`, a policy that has already applied skips re-matching on later turns (fast path). Set `false` to re-evaluate it on every turn.                                                                                       |
| `tools`            | list of strings             | no       | —                  | Tool id(s) the agent may call when this policy applies (`service:tool` form).                                                                                                                                                   |
| `reevaluate_after` | list of strings             | no       | —                  | Tool id(s) whose execution re-triggers this policy's matching (see below).                                                                                                                                                      |
| `metadata`         | object                      | no       | —                  | Arbitrary key/values attached to the policy (e.g. `severity`, `category`); merged with server-derived keys.                                                                                                                     |

Machine-validated rules (the published JSON Schema enforces these): `id` and `condition` required; unknown fields rejected; string fields reject whitespace-only values.

## Policies vs routines

The single most important distinction in the configuration model:

|               | Policy                                                                                | Routine                                                                 |
| ------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| Shape         | One condition → one action                                                            | Multi-node graph                                                        |
| State         | None — re-matched fresh every turn                                                    | Tracks the current node across turns                                    |
| Tool + speech | One `action` may both call a tool and speak — the model handles both in a single turn | Strictly separated: a node either calls tools **or** speaks, never both |
| Use for       | Cross-cutting rules: safety, compliance, tone, escalation triggers                    | Structured flows: collect → fetch → branch → respond                    |

If you find yourself writing a policy whose action is a sequence ("first ask X, then call Y, then confirm Z"), it should be a routine. If you find yourself adding the same guard node to every routine, it should be a policy.

## How matching behaves

* **Per-turn, stateless.** A policy that matched last turn has no special status this turn; the matcher re-reads the conversation.
* **Multiple policies can match simultaneously.** All matched actions are in force for the turn. When they pull in different directions, `criticality` and explicit [priorities](/agents/concepts/priorities.md) decide what wins.
* **`always_match: true`** is for rules that must never depend on a model's judgement of relevance — e.g. regulatory disclaimers, hard prohibitions. Use sparingly: every always-on policy consumes prompt space in every turn.
* **`reevaluate_after`** re-runs this policy's match after the listed tool executes successfully, instead of relying on the match made at the start of the turn. Example: an authentication policy stops matching once `crm:authenticate_customer` has succeeded — listing that tool in `reevaluate_after` makes the engine notice as soon as the call lands. (The manifest-level `context.reevaluation_tools` is the same mechanism with routine-wide scope — see [Reevaluation tools](/agents/concepts/tools.md#reevaluation-tools).)

## Criticality: enforcement vs. cost

`criticality` is more than a conflict tie-breaker — it selects *how hard the engine works to match the policy*, which is a direct enforcement-for-cost trade:

| Level              | How it's matched                                                       | Trade-off                                                                                                                                  |
| ------------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `HIGH`             | Full matching every turn it's in scope; strongest weight in conflicts. | Most reliable firing, at the highest evaluation cost.                                                                                      |
| `MEDIUM` (default) | Full matching; ordinary weight in conflicts.                           | The balanced default for normal business rules.                                                                                            |
| `LOW`              | A separate, lighter-weight matching path.                              | Cheapest to evaluate, but matched less aggressively — a `LOW` policy is the first to yield when it competes with a higher-criticality one. |

In practice:

* **Reserve `HIGH` for rules that must never silently fail to fire** — safety, compliance, money, hard prohibitions. You're paying for reliability.
* **Use `MEDIUM` for the bulk of behavioural rules** — the right default; the engine matches it fully.
* **Use `LOW` for soft, nice-to-have guidance** — tone nudges, optional suggestions — where an occasional miss is acceptable and you'd rather not spend evaluation budget on it.
* Criticality is also a **cost lever across the whole policy set**: every in-scope policy is evaluated each turn (in batches of `policy_batch_size`), so a catalog of all-`HIGH` policies is both the most thorough and the most expensive per turn. Right-size criticality so the spend lands on the rules that matter.

Criticality decides *how reliably a policy fires*; explicit [priorities](/agents/concepts/priorities.md) decide *which of two matched policies wins* a direct conflict. They're complementary — a `HIGH` policy still needs a priority entry to categorically override a routine or another policy.

## Scoping: agent-wide vs routine-scoped

Policies referenced in the manifest's `context.policies` apply agent-wide. A routine can additionally declare its own `policies:` list — policies with the same field shape (an explicit `id` is required), active **only while that routine is active**:

```yaml
# inside a routine document
policies:
  - id: billing-check
    name: Billing Address Check
    condition: "About to finalize a purchase"
    action: >
      Verify the billing address is correct before proceeding with the
      purchase.
    always_match: true
```

Use routine-scoped policies for rules that only make sense mid-flow; keep genuinely global rules in the manifest list so they hold even when no routine is active. Note that routine-scoped policies cannot participate in the manifest's `relationships:` block ([priorities](/agents/concepts/priorities.md) and entailments) — only top-level policies can.

## Referencing from the manifest

```yaml
agent_config:
  context:
    policies:
      - id: minimum-driver-age
        version: 1
      - id: stay-on-topic
        version: 1
```

Version pins are exact. Publishing a new policy version does nothing until a manifest pinning it is deployed — see [Versioning & compatibility](/agents/operations/versioning.md).

## See also

* [Authoring policies](/agents/guides/authoring-policies.md) — patterns and anti-patterns
* [Priorities](/agents/concepts/priorities.md) — resolving conflicts between policies and routines
* [Conversation lifecycle](/agents/concepts/conversation-lifecycle.md) — when matching runs


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.interactive.ai/agents/concepts/policies.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
