Notifications
Notifications are the last step of triage: once an event
routes to queue+notify or ultra, one consumer decides whether it should actually
interrupt you right now, and if so, what it should say.
Routing per severity
Section titled “Routing per severity”Only triage decisions at queue+notify or ultra reach the
notify consumer at all, page-inbox and plain queue routes never generate a
notification. From there, focus filtering applies:
Toggle focus mode from the “Focus mode, only ultra notifications pass” checkbox on
/settings/triage, or programmatically with the ops.modes.set tool. This is exactly
why the severity config calls ultra “overrides focus”, it is the one level focus mode
can never suppress. See Not now for the broader interruption-control
surface this plugs into.
Disclosure templates
Section titled “Disclosure templates”What a notification actually says is controlled per severity level by its disclosure
setting (configured alongside the level’s prompt and route at /settings/triage):
| Disclosure | Renders as |
|---|---|
source-count (default) |
"1 important event · mail", the count and the source, no content. |
preview (opt-in) |
The event’s own text, an actual content preview. |
source-count is the safer default: a notification never leaks message content to a
lock screen or a notification tray unless you explicitly opted a level into preview.
Delivery providers
Section titled “Delivery providers”Delivery sits behind a small provider interface, deliver(notification), so each surface
plugs in its own mechanism without touching the routing or filtering logic above:
The notify consumer writes a toast outbox row; every open browser window
subscribed to the toast WebSocket topic renders it as an in-app toast. This is the
always-on delivery path, it works with zero OS-level permissions.
The desktop app subscribes to the same toast topic and renders
a native OS Notification for each one. Filtering already happened server-side by
the time it reaches the desktop client, an ultra notification plays its native
sound, everything else arrives silently. Clicking a notification routes you to
context relevant to the event.
Mobile devices register an Expo push token
(ops.devices.capabilities.expoPushToken); the notify consumer sends a push payload
templated with the level name and the disclosure-rendered body. ultra sets push
priority to high and the iOS interruption level to time-sensitive, the one
combination that pierces the OS’s own Focus mode on the device, mirroring what
focus/no-comms filtering does inside Subspace itself.
Every provider is backed by a fake in tests and under PROVIDERS=fake: nothing leaves
the process, sends land on the outbox instead so specs can assert on exactly what would
have gone out.