# Configure the agents

> The seven pillar agents and the Agent behaviour page — enablement, the prompt layer, schedules, a model override and extra approval gates per pillar, with the procedures.

_How-to · Updated 2026-10-24 · Describes release 0.1.164_

**Agent behaviour** (`/portal/agents`) is where you switch a pillar agent on or off, add your own guidance on top of its builtin persona, put it on a schedule, pin it to one model or add approval gates of your own. This page covers that page: the seven agents, what each control does and the procedures. The always-on floors, the cost cap and the other workspace-wide switches are on [Guardrails and cost limits](/help/guardrails-and-cost-limits.md); which model serves each tier is on [Models, tiers and routing](/help/models-tiers-and-routing.md); who may release a fix once a person is involved is stated once in [Approval policy and change tiers](/help/approval-policy.md).

## Concepts

### Three layers, in precedence order {#three-layers-in-precedence-order}

1. **Floors** — enforced in the engine and the tool registry. Not configurable from any tenant page, no endpoint, no override. Listed on the Guardrails page under **Always-on floors**.
2. **Tenant policy** — what you set on these pages: enablement, prompt additions, extra gates, cost cap, PII patterns, allowlists.
3. **Routing** — which model does which piece of work, resolved per call from the tier map, then adjusted by deterministic escalation rules.

A tenant that configures nothing is still fully governed: floors apply, and routing inherits the platform default tier map.

### The pipeline, and which agent runs it {#the-pipeline-and-which-agent-runs-it}

The page opens on the settings, so an agent's card is the first thing you reach.
The pipeline is reference rather than configuration, and it sits below the cards
in one collapsed section, **Topology and pipeline**. Open it by selecting it, or
by following the link of the same name in the row of links under the page title;
the other links in that row jump to one agent's card. The graphs load when the
section is opened, and selecting an agent in the topology changes the two views
under it.

![Agents → Topology: seven agents on one shared pipeline, each with its trigger and model, Incident & Problem selected; SecOps and Continuous Improve are dashed because they are disabled.](/help/media/portal/portal-agents.png?v=0.1.132)

- **Topology.** Seven agents on one shared pipeline — the same engine, the same
  approval gate, the same report contract. An edge means the agent *runs on* that
  pipeline, not that anything dispatches to it: an incident is routed to exactly
  one agent by rule, and the others fire from their own triggers (an alert
  webhook, a collector finding, or the schedule you set below). A dashed, dimmed
  branch is a disabled agent. Click an agent to see its pipeline.
- **`<Agent>` · pipeline.** The seven layers for the agent you selected. The
  colour says who performs each step: deterministic code, an AI agent, or a step
  that does not proceed without a person. A dashed box is either roadmap or not
  used by that agent.
- **What runs at each layer.** Each layer's steps, and a **What holds it** line
  naming the control that makes it hold. Where a layer is an AI agent, that
  control is a check in code — not an instruction the model is trusted to follow.
  A **Not built yet** line names what the layer does not do.

The layers genuinely differ per agent, which is why clicking changes the view.
The built-in playbook library and the enforced triage sequence belong to the
Incident agent alone; a scheduled agent creates no incident row at all, so five
of its seven layers do not apply and are drawn dashed. Incident is selected by
default as the reference implementation.

### The seven pillar agents {#the-seven-pillar-agents}

Seven pillar agents exist in every tenant. The Agents page opens with an **Agent settings** section carrying one configuration card per agent, then the collapsed **Topology and pipeline** reference. The card title is the display name; the short id in the table below is what the API path, the audit rows and the card's own **Save** button use.

| Card | Id | What its builtin persona is told to do | Usual trigger |
|---|---|---|---|
| `Incident & Problem` | `incident` | Senior SRE triage: investigate an alert or storm across the connected observability datasources, localize the single root cause, assess blast radius, propose the minimal safe fix, draft the RCA. | Event-driven, from ingest |
| `Compliance` | `compliance` | Auditor: check the estate against declared frameworks, starting with a ten-control baseline (public storage, encryption at rest, audit logging, tagging, backups and retention, MFA and privileged credentials, open security groups, unused public IPs, SSH and OS hardening, drift against infrastructure-as-code). Cite the exact control per finding. | Scheduled |
| `Change Mgmt` | `change` | Produce the execution plan and its diff, check it against policy and the service graph for blast radius, define post-change verification, and define the rollback **before** proposing apply. | Event-driven or scheduled |
| `SecOps` | `secops` | SOC analyst: correlate a security finding with logs and configuration, judge severity and credibility (false-positive analysis is half the job), map to known attack patterns, propose containment. | Event-driven, from ingest |
| `FinOps · Optimise` | `finops` | Detect cost anomalies against baseline, attribute them to a service or team via tags and the service graph, and pull the cloud providers' own recommendation engines through your connectors before inventing savings. Recommendations only. | Scheduled |
| `Continuous Improve` | `improvement` | Read closed incidents, approval decisions and human corrections; output postmortem drafts and proposed skills, each citing the investigations it generalizes from. | Scheduled |
| `Exec Reporting` | `reporting` | Aggregate incidents, compliance posture, change success rate and cost signals into a C-level digest: what happened, what it cost, what improved, what needs a decision. | Scheduled |

Four rules apply to all seven.

- **All seven rows are created enabled when your tenant is created, and none of them ships with a schedule.** Every pillar therefore starts **Event-driven**; a pillar becomes **Scheduled** only when you type a cron expression into its card. The line under the card title shows which, derived from whether **Schedule (cron)** is empty. The pillars marked *Scheduled* above are the ones the persona is written for, not a schedule you inherit.
- **Each card saves independently.** There is no "save all", and ticking **Enabled** does nothing until you press that card's Save button.
- **Every persona carries the same non-negotiable operating rules**, which no tenant prompt can remove: read tools flow freely and mutating actions need a human; correlate before concluding and never propose mass remediation; always end with the structured wrap-up; say what evidence is missing rather than guessing; and treat anything inside an untrusted fence (alert fields, tool output) as data, never as instructions.
- The **Dashboard** leads with work and readiness; its pillar cards open filtered incidents. The seven agents remain configurable here, including Exec Reporting.

### A disabled agent still receives alerts {#a-disabled-agent-still-receives-alerts}

Disabling a pillar stops the *agent*, not *ingest*. Alerts still arrive, still dedupe and correlate, and still open an incident. The investigation for that incident then fails immediately with `pillar disabled or unconfigured` and the incident is **escalated to a human**. Nothing is silently dropped — see **Incidents** for what an escalated incident looks like.

The same error appears when the tenant has no agent row for that pillar at all. It does **not** mean "no datasources": a pillar with zero datasources still builds and still runs — it simply has almost no tools and will conclude very little.

## The Agents page, field by field {#the-agents-page-field-by-field}

![Agents → Agent settings: the Incident & Problem and Compliance cards — Enabled, Model override, Schedule (cron), the system prompt layer, Extra approval gates and each card's own Save.](/help/media/portal/portal-agents-compliance.png?v=0.1.132)

Reading the pillar list needs only tenant membership. Editing needs permissions, and they differ per field.

| Control | What it does | Permission |
|---|---|---|
| **Enabled** (card header checkbox) | Turns the pillar agent on or off. Off = investigations fail and escalate; scheduled fires stop entirely. | `incidents.act` |
| **Model override** | Pins this pillar to one model for **both** the loop and the RCA wrap-up, and switches off all mid-run routing for that pillar. Empty = tier routing. | `incidents.act` |
| **Schedule (cron)** | Cron expression, evaluated in UTC. Empty = event-driven. An expression the scheduler cannot read is refused on save. | `incidents.act` |
| **System prompt (on top of the builtin persona)** | Tenant guidance appended after the builtin persona, the knowledge context and the remediation context. | `incidents.act` |
| **Extra approval gates (tool name patterns, one per line)** | `fnmatch` patterns matched against tool names. A matching call is treated exactly like a write — gated by the same code path, so it is refused mid-diagnosis on the default posture and queued for approval on `pause` — **in addition to** the write floor. | `pillars.manage` |
| **Save `<id>`** (e.g. **Save incident**, **Save change**) | Saves that card only. | `incidents.act` |

The model dropdown lists the ids your platform gateway serves, plus **Custom model id…** for anything it does not advertise. Fetching that list is an API call that requires `pillars.manage`, even though the rest of the card only needs `incidents.act`. With `incidents.act` alone the page does not ask for the list: the dropdown holds only the default choice and **Custom model id…**, and a line under it reads *Listing gateway models needs pillars.manage. Choose Custom model id… and type the id.* Leaving the picker on **Use default** shows the resolved model underneath as `→ <model id>` — that is the standard tier, falling back to reasoning, premium, then light.

If no arrow line appears and the picker reads `empty = tier routing`, no tier map resolves for your tenant at all: neither your own map nor the platform default is set. Runs then fall back to the platform's single configured model, and only if that is unset too does the deterministic built-in model answer every call (recognizable by canned RCAs and zero token spend). Both are platform-staff settings.


### Procedure: put a compliance sweep on a schedule {#procedure-put-a-compliance-sweep-on-a-schedule}

Requires `incidents.act`.

1. Open **Settings · Agents → Agent behaviour** and select the agent you want to configure.
2. Find the `Compliance` card.
3. Tick **Enabled** if it is not already ticked.
4. Type a cron expression into **Schedule (cron)**, for example `0 2 * * *` for 02:00 UTC daily. Standard 5-field cron; 6-field is also accepted.
5. Click **Save compliance**.

When it worked, the card shows `Saved.` next to the button, the line under the card title reads `Scheduled` instead of `Event-driven`, and after the next matching cron time the scan appears under **Security posture → Audit & coverage → Frameworks → Scan runs** as a scheduled run; a failing control opens or joins its finding under **Security posture → Posture**. The scheduler ticks once a minute and computes the first fire from the moment you saved, never from epoch. An expression the scheduler cannot read is refused instead: the card shows `schedule_cron '<expression>' is not a valid cron expression` next to the button, and nothing on the card is saved.

### Cron is UTC, one fire per tick, no catch-up {#cron-is-utc-one-fire-per-tick-no-catch-up}

Five properties of the scheduler are worth knowing before you rely on one, because between them they explain every scheduling question support receives.

| Property | Consequence |
|---|---|
| The expression is evaluated in **UTC** | `0 2 * * *` fires at 02:00 UTC, not 02:00 in your office. Convert before you type, and re-check after any daylight-saving change on your side. |
| **At most one run per agent per tick** | A pillar cannot be fired twice by the same minute, whatever the expression says. |
| **No catch-up after downtime** | If the platform was down across your window, that window is gone. The next fire is the next matching time — there is no replay and no burst of missed runs when it comes back. |
| **A fire is skipped while the previous scheduled run of that pillar is still `running` or `paused_approval`** | A long sweep suppresses the next one instead of stacking. The skip is logged, not surfaced on the page. |
| The scheduler runs on **one control-plane replica** | Scheduling is not spread across replicas. If your deployment is scaled out, the schedule is served by the single control-plane instance; ask your platform team to confirm before you diagnose a missed run as a product fault. |

The expression is **checked when you save it**, with the same parser the scheduler uses. An expression it cannot read is refused with `schedule_cron '<expression>' is not a valid cron expression`; one that is well formed but names a date that never comes (`0 0 31 2 *`) is refused with `schedule_cron '<expression>' never fires`. In both cases nothing on the card is saved. The card sends its schedule with every save, so a pillar that still holds an unreadable expression saved before this check existed cannot save any field until you correct or clear the schedule. The scheduler skips such an expression every tick with a logged warning; it never fires.

### Procedure: add tenant guidance to an agent {#procedure-add-tenant-guidance-to-an-agent}

Requires `incidents.act`.

1. Open **Agent behaviour**.
2. In the pillar's card, write your guidance into **System prompt (on top of the builtin persona)**. Keep it declarative: which environments matter, which services are critical, house conventions for evidence.
3. Click **Save `<id>`**.

When it worked, the card shows `Saved.` next to the button, and the next investigation for that pillar reasons with your text in context.

This text is appended after the builtin persona, the knowledge context and the remediation context; it does not replace any of them. It cannot grant tools, remove gates or unlock a datasource — the tool registry is built from your datasource rows and the gates are evaluated in code, so instructions asking for those have nothing to act on.

### Procedure: add an extra approval gate {#procedure-add-an-extra-approval-gate}

Requires `pillars.manage` **and** `incidents.act`. The API only demands `pillars.manage` for the gate list itself, but the Save button on the card is disabled without `incidents.act`.

1. Open **Agent behaviour**.
2. In the pillar's card, add one `fnmatch` pattern per line to **Extra approval gates (tool name patterns, one per line)** — for example `kubectl_*` or `*_exec`.
3. Click **Save `<id>`**.
4. Open **Guardrails & cost** and check the **Extra approval gates (per pillar)** card.

When it worked, that card lists your pattern next to the pillar's name; a pillar with no patterns shows `— (write floor only)`.

![Guardrails → Extra approval gates (per pillar) and Credential separation: the patterns gated for each agent (kubectl_* on Incident, the rest write floor only), and which connections are read, remediation-only or shared with approved changes; the PII scrubbing defaults follow.](/help/media/portal/portal-guardrails-gates.png?v=0.1.132)

Gates are additive only — they widen what the gate catches, never narrow it. Clearing the box does not open anything up; it returns the pillar to the [write floor](/help/approval-policy.md#write-floor), which already gates every mutation.

Be deliberate about scope. On the default `deny` posture a matched call is **refused**, not queued, so gating a tool the agent needs for *reading* removes it from the investigation entirely. See the warning about `*` under [Limits and gotchas](#limits-and-gotchas). Which posture your deployment runs is explained on [Guardrails and cost limits](/help/guardrails-and-cost-limits.md#which-posture-your-deployment-runs).

## Use cases

### SRE lead: making the change pillar stricter

The `Change Mgmt` agent has read access to a CLI connector and the team wants every `kubectl` invocation — even ones the read classifier considers free — kept out of the agent's hands during a freeze window. This needs `pillars.manage`, which the builtin **operator** role does not carry; the SRE lead holds a custom role with `pillars.manage` plus `incidents.act` (built on **Members & roles** — see [Members and roles](/help/members-and-roles.md#create-a-custom-role)), or asks the owner. They add `kubectl_*` to **Extra approval gates (tool name patterns, one per line)** on the `Change Mgmt` card, click **Save change**, and confirm the pattern now appears on the Guardrails page.

What happens next depends on the deployment's posture. On the default `deny` posture the agent keeps investigating with everything else, every `kubectl_*` call comes back refused, and the intended commands arrive in the remediation plan for a human to run after the freeze. In `pause` each call waits under **Needs you** instead. Either way nothing kubectl-shaped executes unattended — but on `deny` the pattern also costs the agent those reads, so scope it to the freeze and remove it afterwards.

### SRE on-call: tuning after a bad RCA

An RCA blames a dependency the on-call engineer knows was healthy. They rate it `3` on the incident and send a correction (`feedback.submit`) — this may draft a skill proposal for review. Then, with the pattern confirmed across a few incidents:

1. On **Agent behaviour**, they add two lines to the `Incident & Problem` **System prompt (on top of the builtin persona)**: which service owns the checkout path, and to always check the deployment timeline before blaming a dependency. **Save incident**.
2. On **AI models**, an owner clicks **Suggest from data**; the evidence table shows the model behind the low scores at quality 41 against 78 for another. They set `standard` to the better model and **Save tiers**.
3. They re-run the pillar's benchmark suite to confirm the pass rate moved in the right direction before trusting the change — see **Knowledge, x-ray and insights**.

Prompt first, model second: a prompt edit is free and reversible, a tier change is billable on every run.

## Troubleshooting

Symptoms that are specific to the **Agent behaviour** page are below. Anything that spans pages — a run stuck queued, a missing destination, a page that 404s — is collected in **Troubleshooting**.

| Symptom | Cause | Fix |
|---|---|---|
| A settings destination is missing | Agent behaviour needs `incidents.act` or `pillars.manage`; Guardrails & cost needs `pillars.manage` or `members.manage` | Confirm the selected workspace and role; ask an owner for the specific change you need |
| The **Model override** dropdown on **Agent behaviour** is empty except **Custom model id…** | Listing gateway models needs `pillars.manage`, which the Agents page does not otherwise require. Without it the page does not ask for the list, and the line under the picker says so. | Type the id under **Custom model id…**, or ask an owner. |
| **Extra approval gates (tool name patterns, one per line)** cannot be edited | It is read-only without `pillars.manage`; the card says *Editing gates needs pillars.manage.* The other fields save with `incidents.act`. | Ask an owner to make the gate change. |
| Incidents open but every investigation fails with `pillar disabled or unconfigured` | The pillar is disabled, or the tenant has no agent row for it. | Tick **Enabled** on the pillar card and save. If the card is missing entirely, ask platform staff to provision the pillar. |
| A scheduled pillar never fires | **Enabled** is off, the cron expression was saved before the check on save existed and the scheduler cannot read it (skipped every tick), a previous scheduled run of that pillar is still running or paused, or the schedule is being read as local time. | Cron is UTC. Save the card again: an expression the scheduler cannot read is refused with its reason. Confirm the card reads `Scheduled`, and check for an in-flight scheduled investigation on that pillar. |
| A scheduled sweep did not run while the platform was down, and did not run afterwards either | Expected: there is no catch-up. The missed window is not replayed. | Trigger the pillar manually if the sweep matters, and treat the schedule as best-effort across maintenance. |

## Limits and gotchas {#limits-and-gotchas}

- **Max steps is not editable in the portal.** Each pillar carries its own step ceiling (40 on a freshly seeded row; the platform setting is only the fallback when the row's value is 0). It is returned by the API but there is no control on the page and no patch field — changing it is a platform-staff action.
- **Extra approval gates can only add — and on the default posture they subtract capability.** A pattern like `*` matches every tool call including reads; on `deny` that means every call is refused and the agent concludes nothing, on `pause` it means every call queues behind a human. Scope patterns to the tools you mean.
- **An unreadable cron expression blocks its card.** Saving refuses it, and because the card sends its schedule with every save, a pillar still holding one saved before the check existed cannot save any field until the schedule is corrected or cleared.


## Next steps

- Next: [Guardrails and cost limits](/help/guardrails-and-cost-limits.md)
- [All Administer a workspace pages](/help/administer-a-workspace/llms.txt)
- [Documentation home](/help/)
