---
id: CAP-PFM-NOT-008
title: Recover notification processing and retain its history
feature: FEAT-PFM-NOT-02
product_area: platform
module: notifications
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes:
  - NT-ACC-0206
  - NT-ACC-0207
  - PLAT-M23-S15
  - PLAT-M23-S16
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#2. Scope'
  - >-
    services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#PLAT-M23-S15
  - >-
    services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#PLAT-M23-S16
purpose: >-
  Platform recovers interrupted processing and maintains bounded, isolated
  notification history.
outcomes:
  - Expired leases become eligible for recovery.
  - >-
    Reconciliation and retention process stored notification history, with
    alarms for missing dispatcher and reconciliation activity.
concepts:
  - CON-PFM-NOT-003
actors:
  - ACT-PFM-031
surfaces:
  - job
preconditions: []
postconditions: []
permissions: []
rules:
  - id: BR-CAP-PFM-NOT-008-01
    statement: >-
      Dispatch briefly claims workspace entries, publishes batches of ten
      outside a transaction and deletes only acknowledged entries; Rejected
      entries await another run; claimed entries are left alone; Scheduled
      dispatch visits all workspaces, while a nudge targets one.
    kind: policy
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#keeps
      a row the queue refused, and offers it again on the next run
    origin: none
  - id: BR-CAP-PFM-NOT-008-02
    statement: >-
      A crash after publication but before deletion leaves the entry available
      for recovery; repeated processing avoids duplicate records.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js#leaves
      work for the next run when a run died between the publish and the delete,
      and the repeat makes nothing twice
    origin: >-
      services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#PLAT-M23-S15
  - id: BR-CAP-PFM-NOT-008-03
    statement: >-
      A redelivered item whose request already exists makes no further records
      and only nudges dispatch.
    kind: invariant
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/orchestration/orchestrate-request.integration.spec.js#recognizes
      a redelivered item by its record, writes nothing more and nudges the
      dispatcher
    origin: none
  - id: BR-CAP-PFM-NOT-008-04
    statement: >-
      The request consumer acknowledges recorded and unreadable items; future
      work receives visibility until due, or a new delayed copy when another
      receive would exhaust it; Item exceptions are reported independently so
      other batch items proceed.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/dispatch/process-request-batch.integration.spec.js#replaces
      a request that is not due with a fresh delayed copy when the next receive
      would be the last
    origin: none
  - id: BR-CAP-PFM-NOT-008-05
    statement: >-
      Nightly reconciliation at 03:40 UTC runs per operational workspace;
      Sending deliveries ambiguous for fifteen minutes fail without resending;
      chat or text work lost for over an hour is requeued; unprocessed queue
      entries past expiry become expired requests.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/reconcile/reconcile-tenant.integration.spec.js#settles
      a delivery left sending past the ambiguity window failed ambiguous, and
      the instance with it, never resending
    origin: none
  - id: BR-CAP-PFM-NOT-008-06
    statement: >-
      Retention removes requests, deliveries, events and notice keys older than
      thirteen calendar months in batches; Text challenges disappear one day
      after expiry; Notice partitions retain thirteen months and prepare two
      ahead; inserts without a partition fail.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/reconcile/reconcile-tenant.integration.spec.js#deletes
      requests, deliveries, events, instance keys and challenges past it and
      keeps what is younger
    origin: none
    note: >-
      The architecture records thirteen months as an internal retention choice.
      Andrew must decide any longer product policy.
  - id: BR-CAP-PFM-NOT-008-07
    statement: >-
      Workspace deletion purges notification data; reset clears notices and
      delivery work but preserves configuration, personal preferences and
      text-usage accounting.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/integration/services/persistence/tenant-purges.integration.spec.js#removes
      the operational records and leaves the configuration and the metering as
      they were
    origin: none
  - id: BR-CAP-PFM-NOT-008-08
    statement: >-
      The approved restriction excludes message bodies, addresses and tokens
      from logs and metrics.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: documented
    source: >-
      services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#PLAT-M23-S16
    origin: >-
      services-platform:docs/milestones/plans/PLAT-M23-plan.humanized.md#PLAT-M23-S16
    note: >-
      This is an approved restriction, not a universal observation: unexpected
      adapter exception messages are logged without redaction; see the linked
      record.
  - id: BR-CAP-PFM-NOT-008-09
    statement: >-
      Workspace tables apply row-level security; Recorded exceptions cover the
      shared definition registry and reconciliation job root; steps and events
      inherit job ownership instead of separate workspace identifiers.
    kind: invariant
    enforced_at:
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/notifications/tests/unit/registry-tables.spec.js#exempts
      exactly the catalog among the module’s tables as a tenantless registry,
      with a reason
    origin: none
  - id: BR-CAP-PFM-NOT-008-10
    statement: >-
      Deployment defines an operations-paging alarm when the notification
      dispatcher records no run in a fifteen-minute interval, treating missing
      metric data as a breach.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-platform:modules/notifications/aws/logic/notifications-functions.lambda.ts:createDispatcherSilenceAlarm
    origin: none
    note: >-
      This is deployment configuration evidence; the examination does not
      establish a fresh live alarm execution.
  - id: BR-CAP-PFM-NOT-008-11
    statement: >-
      Deployment defines an operations-paging alarm when nightly notification
      reconciliation records no scheduled run for two consecutive days, treating
      missing metric data as a breach.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: observed
    source: >-
      services-platform:modules/notifications/aws/logic/notifications-reconcile.lambda.ts:createNotificationsReconcileFunctions
    origin: none
    note: >-
      This is deployment configuration evidence; the examination does not
      establish a fresh live alarm execution.
scenarios:
  - id: SC-CAP-PFM-NOT-008-01
    given: Dispatch publishes work but exits before deleting its queue entry.
    when: A recovery run processes the surviving entry.
    then: Repeated publication produces no second recipient notice for Jane.
    provenance: test
    source: >-
      react-console:acceptance/notifications/playwright/journeys/pipeline/NT-ACC-0206.spec.ts#NT-ACC-0206
edge_cases: []
constraints: []
depends_on: []
related:
  - CAP-PFM-NOT-002
  - CAP-PFM-NOT-006
  - CAP-PFM-NOT-007
journeys: []
open_questions: []
evidence:
  - >-
    Pinned evidence inventory 1:
    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/integration/services/reconcile/reconcile-tenant.integration.spec.js;
    services-platform:modules/notifications/tests/unit/registry-tables.spec.js
  - >-
    Pinned evidence inventory 2:
    services-platform:modules/notifications/tests/integration/services/dispatch/dispatch-notifications.integration.spec.js;
    services-platform:modules/notifications/tests/integration/services/dispatch/process-request-batch.integration.spec.js;
    services-platform:modules/notifications/tests/integration/services/persistence/tenant-purges.integration.spec.js;
    react-console:acceptance/notifications/playwright/journeys/pipeline/NT-ACC-0206.spec.ts
controls: [TC-AVL-001, TC-AVL-004, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CHG-005, TC-CHG-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-002, TC-LOG-003, 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-PRV-004, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Recover notification processing and retain its history

## Purpose

Platform recovers interrupted processing and maintains bounded, isolated notification history.

## How It Works

Dispatch claims a bounded set of queue entries and publishes outside the database transaction. Only acknowledged publication removes an entry. Consumer processing recognizes repeated requests so interruption can be recovered. Not-before requests return to the queue without early delivery. Scheduled reconciliation examines stale sending states and missing queued work. Retention clears aged records and maintains notice partitions. Workspace reset preserves configuration while deleting operational history. Row-level security and explicit job exceptions define the database boundary.

The product should enforce the approved logging restriction for unexpected adapter exceptions as well as normal delivery outcomes.

## Relationships

This outcome supplies shared notification records used by publication, recipient handling and review.
