---
id: CAP-PFM-NOT-007
title: Route and send notification deliveries
feature: FEAT-PFM-NOT-02
product_area: platform
module: notifications
revision: 1
status: draft
product_intent: proposed
implementation_evidence: partially-observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/proposals/notifications/23-decisions.md#D-02'
  - 'services-platform:docs/proposals/notifications/23-decisions.md#D-09'
  - >-
    services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#4.
    Assumptions
purpose: >-
  Platform records channel selection and delivery progress while keeping
  unavailable channels explicit.
outcomes:
  - Channel work records delivery progress and adapter outcomes.
  - >-
    Retries and event deduplication limit repeated processing within the
    implemented safeguards.
concepts:
  - CON-PFM-NOT-003
actors:
  - ACT-PFM-031
surfaces:
  - job
preconditions: []
postconditions: []
permissions: []
rules:
  - id: BR-CAP-PFM-NOT-007-01
    statement: >-
      For individual recipients, the current release selects console delivery
      and records it delivered when creating the notice.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js#writes
      the console delivery delivered at once and records every other supported
      channel as not available until its milestone
    origin: >-
      services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#4.
      Assumptions
    note: >-
      Plan assumption A7: in the relevant milestone every person receives every
      definition in the console.
  - id: BR-CAP-PFM-NOT-007-02
    statement: >-
      Other supported personal channels are skipped until their e-mail, Slack,
      Teams or text milestone; Unsupported channels receive an unsupported
      resolution.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/unit/channel-resolution.spec.js#names
      the milestone of each channel that is not available
    origin: none
  - id: BR-CAP-PFM-NOT-007-03
    statement: >-
      An installed adapter selects a channel only when its reachability check
      accepts the recipient; otherwise resolution retains the adapter's
      explanation.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/unit/channel-resolution.spec.js#skips
      a channel whose adapter says the person cannot be reached, with the
      adapter’s reason
    origin: none
  - id: BR-CAP-PFM-NOT-007-04
    statement: >-
      Due chat and text deliveries use dedicated work queues; console and e-mail
      delivery do not use that queued-delivery mechanism.
    kind: policy
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/unit/channel-resolution.spec.js#delivers
      chat and SMS as queued work, and the console and e-mail not
    origin: none
  - id: BR-CAP-PFM-NOT-007-05
    statement: >-
      A send lock allows one consumer to act on a queued delivery; Redelivery of
      a final delivery does not send it again.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/persistence/deliveries.integration.spec.js#lets
      only one of two consumers racing for the send win it
    origin: none
  - id: BR-CAP-PFM-NOT-007-06
    statement: >-
      Transient failures retry with thirty-second exponential backoff, capped at
      thirty minutes and jittered by twenty percent; the eighth receive fails as
      attempts exhausted and dead-letters the item; permanent refusals fail
      immediately; thrown adapter errors enter transient recovery.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/dispatch/deliver-delivery.integration.spec.js#fails
      the delivery attempts_exhausted on the last receive and gives the item
      back at once to reach the dead-letter queue
    origin: none
  - id: BR-CAP-PFM-NOT-007-07
    statement: >-
      Notice status is calculated from selected deliveries as routed,
      delivering, delivered, partially delivered, failed or no channel; Skipped,
      cancelled and expired deliveries are excluded, and superseded notices keep
      their status.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/unit/instance-status.spec.js#is
      partially delivered when one delivered and another failed, none still
      active
    origin: none
  - id: BR-CAP-PFM-NOT-007-08
    statement: >-
      Normal lifecycle transitions cannot reopen final deliveries; Skips require
      a reason, and rendered delivery payloads cannot exceed 8 KB; Explicit
      operator retry is a separate operation.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/persistence/deliveries.integration.spec.js#never
      moves a delivery out of a final status
    origin: none
  - id: BR-CAP-PFM-NOT-007-09
    statement: >-
      Provider reports append delivery events, deduplicate repeated event
      identities and retain only the latest fifty events without rejecting
      further reports.
    kind: policy
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/persistence/deliveries.integration.spec.js#keeps
      the newest fifty events of a delivery and drops the oldest, never refusing
      the report
    origin: none
  - id: BR-CAP-PFM-NOT-007-10
    statement: >-
      Console, e-mail and text are native channels; Customer Slack and Microsoft
      Teams connections use the integration platform.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: >-
      services-platform:docs/proposals/notifications/23-decisions.md#D-02. Slack
      and Teams are integrations; e-mail, in-app and SMS are native
    origin: 'services-platform:docs/proposals/notifications/23-decisions.md#D-02'
    note: >-
      Only the console adapter (and Rhythm HQ's system Slack adapter) exist at
      the pinned commit; e-mail, Slack, Teams and text adapters are later
      milestones.
  - id: BR-CAP-PFM-NOT-007-11
    statement: Teams remains unavailable until Andrew resumes its milestone.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: >-
      services-platform:docs/proposals/notifications/23-decisions.md#D-09.
      Microsoft: one Entra application, one Azure Bot, catalog distribution
      first
    origin: 'services-platform:docs/proposals/notifications/23-decisions.md#D-09'
scenarios:
  - id: SC-CAP-PFM-NOT-007-01
    given: The notification type offers console and e-mail routes.
    when: Platform creates Jane's recipient notice.
    then: >-
      Console records delivery success while e-mail selection explains its
      pending milestone.
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js#writes
      the console delivery delivered at once and records every other supported
      channel as not available until its milestone
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-NOT-003
related:
  - CAP-PFM-NOT-012
  - CAP-PFM-NOT-013
  - CAP-PFM-NOT-015
  - CAP-PFM-NOT-008
journeys:
  - JNY-PFM-NOT-003
open_questions: []
evidence:
  - >-
    Pinned evidence inventory 1:
    services-platform:docs/proposals/notifications/23-decisions.md;
    services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md;
    services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js;
    services-platform:modules/notifications/tests/unit/channel-resolution.spec.js;
    services-platform:modules/notifications/tests/integration/services/persistence/deliveries.integration.spec.js;
    services-platform:modules/notifications/tests/integration/services/dispatch/deliver-delivery.integration.spec.js;
    services-platform:modules/notifications/tests/unit/instance-status.spec.js
controls: [TC-AVL-001, TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-IAM-001, TC-IAM-006, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-002, TC-PI-001, TC-PI-002, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Route and send notification deliveries

## Purpose

Platform records channel selection and delivery progress while keeping unavailable channels explicit.

## How It Works

Platform resolves channels against the definition and installed adapters. Personal delivery currently chooses the console. Unavailable channels retain an explanation instead of silently disappearing. Installed adapters report whether they can reach the destination. Queued channels hand due deliveries to their dedicated work mechanism. A consumer locks a delivery before sending and treats repeated final items as completed work. Temporary failures use bounded retry while permanent refusals stop immediately. Delivery events and aggregate notice status record progress independently of personal read state.

The rule rows define this outcome; the acceptance set identifies existing proof and proposed checks. Implementation evidence alone does not approve the observed details.

## Relationships

Recipient selection supplies the eligible people and their audience explanations.
