# Limits & guardrails

> The Govern group puts boundaries around everything the rest of the Console enables. This page covers Token limits, Directories, Defaults and Gateway & Guardrails: spend budgets, directory scoping, account defaults, and policy screens on top of the platform's always-on safety floor. Plugins, Roles and Human-in-the-Loop have their own pages. As of September 25, 2026, OpenEng AI isn't live yet.

The **Govern** group puts boundaries around everything the rest of the
Console enables: spend budgets, directory scoping, account defaults, and
policy screens on top of the platform's always-on safety floor. This page
covers **Token limits**, **Directories**, **Defaults** and **Gateway &
Guardrails**; the group's other three pages, [Plugins](plugins.md),
[Roles](roles.md) and [Human-in-the-Loop](human-in-the-loop.md), have their own
guides ([below](#the-rest-of-govern)).

> [!WARNING] Status on September 25, 2026: OpenEng AI isn't live yet
> The Console and Web Console interfaces load, but the OpenEng AI API routes and the Broker aren't
> deployed. Nothing can be saved or published, and no AI engine can register or connect. Pro,
> Enterprise and pay-as-you-go launch in Q4 2026 and can't be purchased yet. This page describes
> OpenEng AI as it works once those services are live ([status](ai.md)).

*Figure: The Govern group — seven pages of boundaries. Token limits, Directories and Gateway edit in slide-overs with per-row Versions, Edit and Delete actions; Defaults is a settings page; Plugins, Roles and Human-in-the-Loop have their own guides.*

## Token limits

Per-day, per-role, and per-model token budgets, published with your
config and enforced by the engine's gateway on every model call, per calendar
day.

**Fields** (any subset, but at least one; blanks and zeros are ignored):

- **Name** — for your lists in the Console; the engine reads only the budgets.
- **Per day** — a total daily budget across all models and roles.
- **Per role** — budgets keyed by model role (the roles listed on
  [Models](models.md#role-models)).
- **Per model** — budgets keyed by the model's display id.

Amounts accept shorthand — `500k`, `2M`, `1B` — and are stored as plain
numbers.

You can author multiple limit items; at publish they merge into **one**
budget object, where the **tightest enabled value wins** per key. Disabled
items don't contribute. That makes layering safe: keep a generous account
default plus a strict experiment-time item you enable when needed.

A limit that's reached doesn't stop the run silently: the run pauses and asks
whether to proceed, the same boost-or-proceed prompt a config's per-component
token caps raise (see [Approvals](human-in-the-loop.md#approvals)).
**Proceed** waives that limit for the rest of the turn; declining, or no one
able to answer, stops the run with
`daily token budget reached for '<key>' (<used> of <limit> tokens)`.
Per-component caps for one config are set in the config builder's
[Token caps](configs.md#token-caps) step.

> **Tip:** A token limit is the single highest-value guardrail for scheduled
> and autonomous work — a runaway 2 a.m. job hits the budget, not your
> machine.

## Directories

Directory configuration and scoping defaults — the paths agents may treat as
workspaces, each with an optional **trusted** flag.

- **Path** — a literal absolute path on the machines that pull the config
  (`/home/me/projects` or `~/projects`). Paths are **literal** (no glob
  patterns; the editor refuses them) and node-local.
- **Trusted** — trusted entries widen where agents may work without asking.
  Keep an entry but switch trust off to stage it without effect.

Trust interacts with the engine's permission model: the live trust state is
tracked per machine, in the engine's trusted list `~/.openeng/trust.json`
([the engine's files](engine.md#files)); directory entries published here
arrive with the config. On a machine, a trusted directory (or any directory
under it) is where the agent may run shell commands and where a project's
`.mcp.json` servers may start ([MCP servers](mcp.md)).

> **Note:** The current engine build doesn't yet merge published directory
> entries into a machine's trusted list. Until it does, a directory counts as
> trusted on a machine only if it's in that machine's `trust.json`, whose
> shape is `{ "dirs": ["/home/me/projects"] }`.

## Defaults

A settings page for account-wide defaults. It is settings, not a config: it
never creates or publishes a configuration, and **Save** writes it
explicitly.

- **Role models** — one slot per model role, the eleven roles grouped into
  five bands (Routing, Planning, Execution, Quality, Research). Each slot binds
  a model from your **My models** list (drag a model chip onto the slot or use
  its picker), or stays empty. The embedded roles the engine's model daemon
  serves aren't listed: they can't be overridden.
- **Resource caps** — CPU, GPU, Memory and Storage, each a percentage of the
  machine the *whole* agent system may use (10% by default). For example, CPU
  10% means the engine's governor admits agents, workers and models only while
  together they fit within a tenth of the machine's cores. The governor is
  cooperative (it doesn't impose OS-level limits), the published engine is
  CPU-only, and catalog models run in your own Ollama daemon, outside it.

In a config, roles are bound in its **Models** step and the four percentages
are set in its **Resources** step ([Configs](configs.md)). On a machine, the
engine resolves each role from a plan step's pinned model first, then the
agent's own binding, then the config's binding.

> **Note:** Honesty banner — the engine reads a **published config**, not
> this page. The Console shows the Defaults role slots as the inherited value
> in the model and agent editors, but for a value to reach a machine, set it
> in the config (its Models and Resources steps) and publish.

## Gateway & Guardrails

Every model call, worker action, MCP/cell invocation, and search on your
machines flows through a two-level gateway. Its **floor** — the platform's
non-negotiable baseline — is always on and not editable:

| Floor policy | Stage | What it does |
|---|---|---|
| `floor:envelope` | input · output | Size/shape sanity on every invocation before it runs, and schema validation of structured model responses |
| `floor:authz` | input | Authorization on every action: the plan ∩ trust ∩ zone grant check |
| `floor:secret-egress` | input | Blocks resolved secret values (your placeholders' values) from leaving toward external destinations (models, MCP servers, cells, sandboxes, search) |
| `floor:secret-redact` | output | Redacts resolved secret values (your placeholders' values, 8 characters or longer) from responses before they reach context, logs or later steps; it doesn't detect other secret-shaped text |
| `floor:meter` | output | Budget metering: stamps token and size use on every call |

Every floor policy fails closed except `floor:meter`, which fails open
(metering never blocks work).

The page (**Gateway** in the nav) renders the floor as locked rows, grouped
by stage, each expandable to its purpose, then lets you add **your own
guardrails** on top. Each guardrail's fields:

| Field | Values | Meaning |
|---|---|---|
| **Policy id** | your identifier | `floor:` ids are refused — the floor can't be shadowed |
| **Evaluator** | a built-in evaluator id (picker) | size, schema, grant, meter, secret-egress, secret-redact, injection-heuristic, injection, groundedness (see below) |
| **Stage** | `input` · `output` | Screen before or after the call |
| **Classes** | model · worker · mcp · cell · sandbox · host · search | Which invocation classes it applies to (at least one) |
| **Tier** | 0–2 | Evaluation tier |
| **Mode** | `sync` · `async` · `sampled:<r>` | Sampled takes a rate in (0, 1] |
| **Action** | `block` · `redact` · `pass` · `flag` | What happens on a hit |
| **Failure** | `open` · `closed` | If the evaluator itself fails: allow or refuse |
| **Applies to** | a scoping expression (optional) | Prefix-checked against the policy grammar: `provenance:mcp` (or `cell`, `search`), `principal.nodeType:<type>`, `principal.node:<id>`, `target:<prefix>` |

The evaluator picker offers only evaluators the engine actually has, so a
config can never name one that doesn't exist:

| Evaluator | Checks | Tier |
|---|---|---|
| `builtin:size-v1` | Payload size limits | 0 |
| `builtin:schema-v1` | Envelope and structured-output schema | 0 |
| `builtin:grant-v1` | Authorization: plan, trust and zone grants | 0 |
| `builtin:meter-v1` | Consumption stamping for meters and budgets | 0 |
| `builtin:secret-egress-v1` | Secrets leaving in request payloads | 1 |
| `builtin:secret-redact-v1` | Secrets in responses (redacts them) | 1 |
| `builtin:injection-heuristic-v1` | Prompt injection, by heuristic | 1 |
| `builtin:injection-v1` | Prompt injection, model-backed | 2 |
| `builtin:groundedness-v1` | Groundedness, model-backed | 2 |

Token-condition policies author alongside guardrails (a **Kind** switch in
the editor): a scope such as `class:model` or `target:model:ext:*`, with a
per-run, per-minute and/or per-day limit. The engine consumes guardrails today
(token conditions are deferred engine-side and labeled accordingly: they
publish with your config, grouped separately in the list, with a "not yet
enforced" badge).

A config picks which of your gateway policies it uses in the config builder's
**Routes** step ([Configs](configs.md#components)).

## The rest of Govern

- **[Plugins](plugins.md)** — Gateway guards you attach on top of the floor — gate, transform, observe or enrich any call, with built-in modules or your own https endpoint.
- **[Roles](roles.md)** — Behavioral rule-sets from the roles catalog that make an agent work like a named professional. Not the same as model roles.
- **[Human-in-the-Loop](human-in-the-loop.md)** — Pause a run for a person's approval at a boundary you choose, and decide every request from one queue.

## Plan & tier notes

Token limits, Directories, Defaults and Gateway are open on **every plan** —
boundaries are never paywalled. The floor applies to every account
regardless of plan. On the other Govern pages, built-in plugins are free while
external plugin endpoints, Roles and Human-in-the-Loop need Pro or Enterprise,
which launch in Q4 2026 and can't be purchased yet
([Plans & billing](account.md#ai-pricing)).

## Troubleshooting

**Runs stop with a budget message.** A token limit was hit and the
proceed prompt was declined (or no one answered it). Check which key
(per-day / role / model) — remember the *tightest enabled* item wins, so
look for a strict experiment item left enabled.

**My limit doesn't seem to apply.** Zeros are ignored; the item may be
disabled; and the machine must be running a config version published after
your change ([which config the engine serves](engine.md#config-selection)).

**A guardrail id is rejected.** You used a `floor:` prefix — reserved for
the platform floor. Pick your own id.

**Directory entry didn't change agent behavior.** Paths are literal — no
globs — and node-local; check the path exists as written on that machine,
and confirm the live trust state there (`~/.openeng/trust.json`; see the note
under [Directories](#directories)).
