Autonomy Levels

How SYRIS decides what it executes automatically versus what requires confirmation, and the full gate matrix.

Autonomy level is the system-wide operating mode that, combined with risk level, determines whether an action executes immediately, requires operator approval, or is blocked outright.

Autonomy is always interpreted together with risk level and tool scopes. The same action may produce different gate outcomes at different autonomy levels.

Autonomy levels (A0–A4)

LevelNameEffectful actions
A0Suggest-onlyNever executes effectful actions. All actions produce a dry-run preview.
A1Confirm requiredExecutes effectful actions only after explicit operator approval.
A2Scoped autonomyLow-risk actions execute automatically. Medium and high require approval.
A3High autonomyLow and medium actions execute automatically. High requires approval.
A4Full autonomyLow, medium, and high execute automatically. Critical requires approval.

A4 is dangerous and typically disabled. All levels still respect hard safety overrides. See safety/risk-and-gates.

Risk levels

RiskExamplesTypical gate at A2
LowRead-only queries, status checks, local notesALLOW
MediumControlling a single device, sending to a private channel, creating a calendar eventCONFIRM
HighDeleting data, controlling many devices, sending broadly, quiet-hours notificationsCONFIRM
CriticalPurchases, public posting, irreversible actions, wide blast radiusHARD BLOCK

Confirmation gates

A gate creates a persisted Approval record containing:

  • why — the human-readable reason the action was gated
  • what — the exact serialised payload that will execute on approval (no surprises)
  • how_to_approve — the API call required: e.g. POST /approvals/{id}/approve
  • expires_at — the deadline; expired approvals are handled per operator configuration

Approvals are audited and trace_id-linked to the originating event or task. See architecture/data-contracts for the full Approval schema.

Gate decision matrix

The matrix is a lookup table in safety/gates.py. Hard overrides are applied before the matrix lookup. See safety/risk-and-gates for override details.

Key: ALLOW = execute immediately; CONFIRM = create Approval and block; PREVIEW = dry-run only (A0 suggest mode); HARD BLOCK = refuse outright regardless of approval.

LOWMEDIUMHIGHCRITICAL
A0PREVIEWPREVIEWPREVIEWPREVIEW
A1CONFIRMCONFIRMCONFIRMHARD BLOCK
A2ALLOWCONFIRMCONFIRMHARD BLOCK
A3ALLOWALLOWCONFIRMHARD BLOCK
A4ALLOWALLOWALLOWCONFIRM

Dry-run previews

For tools that declare supports_preview = True, the gate matrix PREVIEW action (and opt-in CONFIRM flow) triggers a dry-run before execution:

  • Message render preview
  • Device state diff (before → after)
  • Patch previews for code changes
  • "What will happen" summary

Execution reuses the same idempotency_key as the preview to ensure no duplication.

Hard safety constraints

These apply at every autonomy level without exception:

  • Least-privilege scopes are enforced on every tool call.
  • Secrets are never exposed in audit payloads or logs.
  • Redaction is applied to all stored payloads.
  • Anti-spam and anti-flap policies remain active.

See safety/risk-and-gates for the full override specification.

 
```md safety/risk-and-gates
---
title: Risk Classification and Gates
description: How risk level is determined, the four hard safety overrides, and the dry-run preview protocol.
---
 
Risk level and gate decisions are computed in `safety/risk.py` and `safety/gates.py`. This page covers risk classification and the overrides that apply before the gate matrix. The matrix itself is in [safety/autonomy-levels](/docs/safety/autonomy-levels).
 
## Risk classification
 
Risk is assigned at two levels: a default for the tool, and per-action overrides in `risk_map`. The classifier in `safety/risk.py` starts from the base risk and applies adjusters that can **only increase** it:
 

base_risk = tool.risk_map.get(action, tool.risk_default)

Adjusters (applied in order; each can raise risk by one level): +1 if target is a broadcast or group channel (not private) +1 if action is destructive (delete, wipe, reset) +1 if blast_radius > threshold (e.g. all-home device control) +1 if current time is within quiet hours

final_risk = min(base_risk + sum(adjusters), RiskLevel.CRITICAL)

 
Adjusters can never lower risk. `CRITICAL` is the ceiling.
 
## Hard safety overrides
 
These four overrides are evaluated **before** the gate matrix. They can only increase the gate action — they never lower it to `ALLOW`.
 
### 1. Secrets scope
 
If a tool call requires any secret-access scope, the gate action is always `CONFIRM` — even at `A4` with `low` risk. Secrets access is never silently permitted.
 
### 2. Quiet hours + medium/high risk
 
If the current time falls within a configured quiet hours window **and** `risk >= medium`, the gate action escalates to `CONFIRM`. This prevents automated medium/high-risk actions during off-hours regardless of autonomy level.
 
### 3. Anti-flap
 
If the same tool, action, and target fired within the anti-flap cooldown window, the gate action is `BLOCK`. An `AuditEvent("gate.antiflap_block")` is emitted with the reason. This prevents rapid repeated executions from device event storms.
 
### 4. Notification storm
 
If outbound notifications in the past hour exceed `MAX_NOTIFICATIONS_PER_HOUR`, all further notification tool calls are blocked. An `AuditEvent("gate.storm_block")` is emitted. The alarm subsystem raises an alarm when this threshold is hit.
 
## Dry-run preview protocol
 
When the gate matrix returns `PREVIEW` (A0 suggest-only) or the gate flow requests a preview before `CONFIRM`:
 
1. The tool executor calls `tool.preview(action, request, context)`.
2. `PreviewResult` is returned to the caller without executing the action.
3. If the operator proceeds, execution uses the **same** `idempotency_key` as the preview call to prevent duplicate side effects.
4. Tools that do not support preview return `None` from `preview()`; the gate flow handles this gracefully (no preview shown, execution still blocked if `CONFIRM` required).
 
For the full gate matrix, see [safety/autonomy-levels](/docs/safety/autonomy-levels).
 
## Related
 
- [safety/autonomy-levels](/docs/safety/autonomy-levels)
- [integrations/tool-runtime](/docs/integrations/tool-runtime)
- [architecture/data-contracts](/docs/architecture/data-contracts)
- [ops/secrets](/docs/ops/secrets)