| name | notifications |
| description | Multi-channel notifications. Adding a new notification kind, group, or channel; in-app + email delivery; per-user prefs; project-level gates; idempotency. |
Notifications
When to use: Adding a notification kind / group / channel, touching the notifications table or users.notification_preferences, wiring a new source event into the notification pipeline, or debugging in-app / email delivery.
Always read dev-docs/notifications.md for the full picture before editing. This skill is the action-oriented summary.
Vocabulary (and what NOT to confuse)
Three orthogonal axes — keep them straight:
| Axis | Type | Examples | Lives in |
|---|
| Kind | flat enum (event-type) | incident.event, incident.opened, incident.closed, wrapped.report, custom.message | NOTIFICATION_KIND_META in @domain/notifications |
| Group | user-visible category | incidents, wrapped_reports, custom_messages | NOTIFICATION_GROUPS in @domain/shared |
| Channel | delivery surface | email, (later: slack, ...) | per-channel worker + registry |
AlertIncidentKind (issue.new / / ) is a axis — it lives inside the payload and gates the producer step at the project level. It is a . The mapping today: and → (one-shot, ); → + later (sustained, transitions from null). The producer derives the notification kind from , so adding a new sustained or eventful alert kind is purely a change.