Skip to main content
Notification policy decides whether and what to notify each recipient — filter by category, honour quiet hours, and redact content per privacy level, all before the message leaves the gateway.
This is the policy layer — the whether and what to notify. It sits above Push Delivery Store (delivery guarantee) and before Real-Time Push Notifications (transport).

Quick Start

1

Gate a notification with the default policy

Apply DEFAULT_PREFERENCE to decide whether an agent’s event should notify you.
2

Per-recipient preference with quiet hours

Subscribe to specific categories and stay silent overnight unless the event is urgent.
3

Detail-level redaction

Pick how much content leaves the gateway with DetailLevel.

How It Works

Every notifier calls one pure function before delivery; the decision carries the send flag and the already-redacted content. evaluate() is pure and side-effect-free, so any process can call it at delivery-decision time without I/O. Pass prefs=None to fall back to DEFAULT_PREFERENCE; pass now=None to use the current time localised to prefs.timezone.

The Three Concerns

Categories

A recipient opts into each event class independently; an un-opted category is suppressed with reason category_not_subscribed.

Quiet Hours

A per-recipient local window suppresses non-urgent categories; urgent events override when urgent_overrides_quiet=True. The window is half-open [start, end). When start == end the window is empty (never quiet). When start > end it wraps past midnight — (22:00, 07:30) means 22:00–24:00 ∪ 00:00–07:30. A naive now is treated as already local; an aware now is converted to prefs.timezone via stdlib zoneinfo. An unknown timezone name falls back silently to the naive time.

Detail Levels

Three levels control how much content leaves the gateway.

Which Detail Level Should I Pick?

Match the level to how trusted the destination surface is.

Configuration Options

NotificationPreference

Also exposes .allows(category) → bool, whether this recipient opted into category.

NotificationDecision

evaluate(...)

DEFAULT_PREFERENCE

Applied when a recipient has set nothing: the two interaction-blocking categories are on, at the identified (no-content) detail level, with no quiet hours.

Common Patterns

Gate a scheduler completion notification — the recipient opts into AGENT_FINISHED, and it is not urgent.
Approval request during quiet hours — the recipient is inside their window, but the urgent flag overrides it.
Privacy-first mobile push — DetailLevel.PRIVATE so the lock-screen never shows content.

Best Practices

Match the default detail to where notifications land. Use PRIVATE for mobile lock-screens where anyone nearby can read the preview, IDENTIFIED for shared team channels that route by agent, and DETAILED only for trusted single-user desktops. DEFAULT_PREFERENCE uses IDENTIFIED as a safe middle ground.
Treat APPROVAL_REQUESTED and AGENT_QUESTION as urgent by convention — they block an agent from continuing until you answer. Pass is_urgent=True for these so quiet hours never strand a paused agent. Keep failure alerts (SCHEDULED_TASK_FAILED, BACKGROUND_TASK_FAILED) non-urgent unless your operations demand overnight paging.
The window is half-open [start, end). A same-day window needs start < end (e.g. (09:00, 17:00)); an overnight window needs start > end (e.g. (22:00, 07:30)), which wraps across midnight. Setting start == end produces an empty window — never quiet. Always set timezone to the recipient’s IANA zone so now localises correctly; a naive now is assumed already local and an unknown zone falls back to the naive time.
Lower detail protects content but forces the recipient to open the app to act. If a notification only exists to prompt an approval, IDENTIFIED is usually enough — the recipient knows which agent to open. Reserve DETAILED for events where the content itself is the action (e.g. a failure stack trace) and the destination is trusted.

User Interaction Flow

An operator sets a preference once; later events are gated automatically by the policy.

Real-Time Push Notifications

The PushClient / WebSocket transport this policy sits above

Push Delivery Store

The durable at-least-once delivery this policy composes with