> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackra.figentra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 0223 — Notifications: more channels, cascading templates, manual sends and preferences

> Accepted, amended by 0270, 0294 · 2026-10-20

> [!NOTE]
>
> Amended by [0294](/adr/0294-programming-model-v3-grammar-folders-identities-and-naming.md), the
> programming model v3. A notification extends `Notification({ category })`. It is placed in the
> `resources/<model>/` folder of the model it concerns, and it is triggered by the type of its
> `recipients(event)` parameter. Each channel is a method the class declares, and a channel with no
> method is not sent. The mail body is a React Email `.mail.tsx` file bound by name. SMS and push
> text are ICU messages in the lang files. Tenant copy changes through lang overrides and
> email-template documents, never through code. The package `@stackra/mail` is renamed
> `@stackra/notifications`. Decisions 1 to 4 are unchanged in substance. The rename does not move
> preferences: the note on decision 5 from
> [0270](/adr/0270-builder-architecture-one-editor-kernel-document-kinds-and-collaboration-levels.md)
> still applies.
>
> Enforcement of this note: planned — STA-338 (the kind-path check for `resources/<model>/`);
> STA-340 (gen checks: no channel method; a missing mail template; a missing SMS lang key in any
> locale; an SMS over its length limit).

> [!NOTE]
>
> Amended by
> [0270](/adr/0270-builder-architecture-one-editor-kernel-document-kinds-and-collaboration-levels.md)
> (decision 12): decision 5's "notifications package" is now the notifications service,
> `@figentra/service-notifications`, which owns notification preferences.

> [!NOTE]
>
> Amends [0086](/adr/0086-notifications-full-engine-all-channels-free.md).

## Context

[0086](/adr/0086-notifications-full-engine-all-channels-free.md) made every channel free. The owner's notification answers N3 to N5, B36 (mem L686–688, L696–697, 2026-10-20) add channels, cascading templates, manual sends and where preferences live.

## Decision

1. **Channels (N3).** Adds Unifonic and Taqnyat for SMS, the WhatsApp Cloud API, web push with VAPID, voice through Twilio, and chat apps (Slack, Teams and Telegram).
2. **Single layer (N4).** Notifications is the one delivery layer. Every channel goes through it.
3. **Templates (N5).** Templates come from code defaults, then tenant overrides, then a console editor. The cascade follows the scope chain.
4. **Manual sends.** A person can send a notification at any scope, with guardrails. The permission `notifications.message.send` is never granted by default.
5. **Preferences (B36).** Notification preferences live in the notifications package, an exception to the settings rule (ADR 0213).
6. **Spec location.** The notifications spec lives at `.agents/specs/sta-35-notifications`.

## Consequences

* A tenant can change a template without a deploy, and the default is always there.
* A manual send is a permission grant, so it can be audited and revoked.

## Enforcement

planned — the cascade test covers code default, tenant override and console edit; the default-deny of `notifications.message.send` is checked by the permission catalogue.

## Supersedes and sources

Supersedes: none. Amends: [0086](/adr/0086-notifications-full-engine-all-channels-free.md). Sources: owner notification answers N3–N5, B36 (`stackra-decisions-2026-10-19.md` L686–688, L696–697, 2026-10-20). Closes gap B9 (spec path).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.