---
title: Inbox Rules Engine (auto-suppress / archive / snooze matching alerts)
---

# Inbox Rules Engine (auto-suppress / archive / snooze matching alerts)

## What it is

**Inbox Rules** let you write rules that act automatically on new inbox items, so
noisy or known-benign alerts never pile up unread. A rule is a **match** (what to catch)
plus one **action** (what to do): **suppress** it (archive it silently), **archive** it,
or **snooze** it until a time you choose. When a new agent alert arrives, the highest-priority
matching rule fires once and the item is handled before it ever surfaces — no flash, no unread
count bump.

It is **off by default** and lives under the **Automations** panel (the **Inbox Rules**
category in the left list). Turn it on to start writing rules. It is an
**in-development / Lab feature** (`inbox-rules`), so the whole surface only appears when
that feature is enabled.

> **Stage A — the `alert` integration only.** This first stage wires exactly one inbox
> producer: **agent-raised alerts** (the ones from [Inbox Alerts](inbox-alerts.md) — a
> Claude Code session or the CLI `POST /alert`). Other inbox sources (Drip, doc-token,
> digests, approvals) are **not** governed by rules yet; extending to them is a later
> stage. A rule's `sources` criterion and the audit log are already shaped for more
> producers, but only `alert` items flow through the engine today.

## Where to find it

Under the **Automations** panel, in the **Inbox Rules** category in its left-hand list. The surface only appears once its in-development feature switch is on, and the engine itself is **off by default** until you enable it there.

## How it behaves

### Writing a rule

Open **Automations → Inbox Rules → + New rule**. A rule has:

- **Name** — a label for your list.
- **Match** — any combination of these, ANDed together (an item must satisfy every
  criterion you set):
  - **Sources** — the item's integration (Stage A: `alert`).
  - **Dedup key equals / starts with** — match an alert's `dedupKey` exactly or by prefix
    (e.g. prefix `rss-` to catch every RSS-feed notice).
  - **Title contains** — a case-insensitive substring of the alert title.
  - **Title matches (regex)** — an ECMAScript regular expression against the title.
  - **Project** — only items resolved to a given project.
- **Action** — **suppress**, **archive**, or **snooze for a duration**.
- **Priority** — higher numbers take precedence and run first; ties break by age
  (older rule wins). At most one rule fires per alert.
- **Enabled** — a toggle to pause a rule without deleting it.

Suppress and archive are **recoverable** — a suppressed alert is archived, not destroyed,
so it's still in the recently-dismissed view and undoable; the engine never deletes an item
or acts on your behalf beyond hiding it.

### Safety allowlist — critical alerts are never suppressed

A handful of alerts are too important to ever be silently suppressed by a rule, so the
engine **refuses to suppress them** no matter what a rule says — it skips that rule and
keeps looking. These are the alerts that mean something is genuinely wrong with your setup:

- **account re-auth** — you must sign in again; hiding it would break every session.
- **backup failure** — an off-machine backup is failing; losing it risks data loss.
- **low memory** (commit-pressure and physical-RAM cards) — the machine is close to an
  OOM crash.
- **low disk space** — the disk is full and can't write sessions or the database.
- **low-spec hardware** — the machine is below the minimum spec.

A rule can still **archive** or **snooze** one of these if you deliberately choose to —
only permanent **suppression** is blocked, so a real problem always reaches you at least
once.

### How it runs (behaviour)

- **Only new agent alerts trigger it.** The engine runs at the moment a new agent alert is
  created, before the inbox is told about it — so a suppressed item never briefly appears
  and then vanishes. Existing items already in your inbox are not retroactively swept.
- **Highest priority wins, one action.** Enabled + approved rules are checked in priority
  order (then oldest-first); the first that matches fires and the rest are skipped.
- **Every fire is logged.** Each time a rule acts, Omniscio records one audit row (which
  rule, which item, the action, and the outcome — including failures), so you can always
  reconstruct why something disappeared.
- **A rule bug never breaks your alerts.** The engine is wrapped so that any internal error
  degrades to doing nothing (logged) — a bad rule can never stop an alert from being saved.

### Safety & performance notes

- **Regex is bounded.** A title regex pattern is length-capped and validated when you save
  it, and the engine skips the check on an over-long title — so a hand-written pattern can't
  hang on the alert hot path (ReDoS-safe). An invalid pattern simply never matches.
- **No new destructive power.** The only things a rule can do are hide an item recoverably
  (archive/suppress) or defer it (snooze). There is deliberately no rule action that
  approves, rejects, deletes, or otherwise acts on your data.
- **Cheap when off or idle.** With the feature off, or with no matching rule, evaluation is
  a near-zero no-op on the alert path.

## For agents

### Creating rules over the CLI (and why they need approval)

The CLI control server exposes the rules too — `GET/POST /inbox-rules`,
`PATCH/DELETE /inbox-rules/:id`, and `POST /inbox-rules/:id/approve|reject` — so an agent
or script can manage them with the same power as the UI.

But a rule created over the CLI lands **pending**: it does **nothing** until you approve it
in the app. This is the same user-in-the-loop trust boundary automations use — it means an
AI agent can propose a rule but can't silently start suppressing your inbox items on its
own. Rules you create in the UI are approved immediately (you're the user in the loop). A
pending rule shows an **Approve / Reject** control in the list.

```bash
# Propose a rule over the CLI — it lands 'pending' until you approve it in the app.
curl -X POST http://127.0.0.1:19519/inbox-rules \
  -H "Authorization: Bearer $AMC_CLI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"Mute RSS notices","match":{"dedupKeyPrefix":"rss-"},"action":{"type":"suppress"}}'
```

### Where it lives

Contract (invariants + how to change it safely):
[inbox-rules-engine-contract.md](../../.claude/memory/contracts/inbox-rules-engine-contract.md).
Related: [Inbox Alerts](inbox-alerts.md) (the producer Stage A governs),
[Snooze any inbox item](snooze-an-inbox-item.md) (the snooze mechanism a rule reuses).

## Related

The alerts these rules act on — how one is raised, how it is dismissed, and the deduplication every card shares — are described on the [Inbox Alerts](inbox-alerts.md) page, and the inbox they arrive in on the [Inbox overview](inbox-overview.md).
