Skip to content

Delivery channels

Five ways an alert can reach you. Each is independent — a webhook fires whether or not the window is open, and a toast appears whether or not you configured a webhook.

In-app toasts

On by default (swarm.alerts.toast). Critical alerts are sticky and stay until dismissed; a page that scrolls past unnoticed is not a page. Clicking one opens that cluster's tab and lands on the alert.

OS notifications

Off by default (swarm.alerts.os_notifications), because they are the channel that reaches you when Cleat is minimised — which is also the channel with the most per-platform caveats:

  • macOS — requires a bundled .app. A loose binary run from a build directory has no bundle identifier, and the notification centre refuses it. Cleat says so at startup rather than failing silently
  • Windows — tray balloon notifications. No action buttons
  • Linux — needs notify-send (from libnotify-bin on Debian and Ubuntu). Without it there is nothing to deliver through

Settings → Swarm has a Send test notification button that reports what actually happened, including "we didn't try". Use it — the failure modes here are invisible otherwise.

Sound

Off by default (swarm.alerts.sound). Adding an audio device to a terminal application reads as a regression to anyone who did not ask for it.

Three cues, one per severity, so they can be told apart without looking. Never plays for Info, and never when an alert resolves — "it came back" does not need to interrupt anyone, and a flapping service would otherwise sound on both edges.

You can replace the critical cue with your own WAV. Use the Play button rather than typing a path: a path that is wrong plays nothing, and you find out during the incident it was meant to announce.

Webhooks

Off by default (swarm.alerts.webhooks_enabled). Slack, Discord, or any endpoint that accepts JSON.

The URL is a credential. For Slack and Discord, anyone holding the URL can post to that channel indefinitely, so Cleat keeps it in your system keychain and never in its database. The editor shows you the host of a stored URL and never the path, and never reads it back into the field.

URLs must be https, with an exception for loopback so you can test against a local listener.

Local commands

Off by default (swarm.alerts.allow_commands), and reachable only from Settings — never from the Swarm view, and never from an imported rule set, so a configuration somebody shared cannot start processes on your machine.

Alert data is passed in CLEAT_SWARM_* environment variables and never as command arguments, and no shell is involved. That is what stops a service named by an attacker becoming part of a command line.