---
id: STATE-PFM-TNL-005
title: Deletion notice delivery
object: DOM-PFM-TNL-005
product_area: platform
module: tenant-lifecycle
revision: 1
status: draft
design_intent: confirmed
origin: services-platform:docs/tenants/tenant-lifecycle-plan.md#§5.5 Notices (approved 2026-10-09; D4 Andrew 2026-10-09)
implementation_evidence: partially-observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
states:
- name: pending
  meaning: The recorded notice awaits delivery at its due instant.
- name: delivered
  meaning: The provider accepted the notice and its outcome is recorded.
- name: suppressed
  meaning: Environment policy withheld the message and the obligation counts as satisfied.
- name: failed
  meaning: The latest recorded send attempt failed; a later caller can retry.
transitions:
- from: pending
  to: delivered
  trigger: A caller sends a notice whose due time has arrived.
  guard: The recipient configuration and provider accept delivery.
  side_effects:
  - Store recipients, provider reference and delivery time.
  who: deletion schedule job or purge job
  provenance: observed
  source: services-platform:modules/tenants/services/deletion/notices/send-notices.ts:sendDueTenantDeletionNotices
- from: pending
  to: suppressed
  trigger: A caller attempts delivery under restrictive environment policy.
  guard: The sender withholds delivery to every recipient.
  side_effects:
  - Record suppression as satisfaction of the notice gate.
  who: deletion schedule job or purge job
  provenance: observed
  source: services-platform:modules/tenants/services/deletion/notices/send-notices.ts:sendDueTenantDeletionNotices
- from: pending
  to: failed
  trigger: A due-notice delivery attempt fails.
  guard: Delivery or outcome recording throws; recipient setup failures can stop before per-notice handling.
  side_effects:
  - Record an attempt and safe error when per-notice handling runs.
  - Emit the notice-failure metric.
  who: deletion schedule job or purge job
  provenance: observed
  source: services-platform:modules/tenants/services/deletion/notices/send-notices.ts:sendDueTenantDeletionNotices
- from: failed
  to: delivered
  trigger: The schedule retries an unsatisfied notice.
  guard: The notice is due and still pending or failed.
  side_effects:
  - Store the accepted delivery outcome.
  who: deletion schedule job
  provenance: observed
  source: services-platform:modules/tenants/services/deletion/tenant-deletion-schedule-operations.ts:tenantDeletionScheduleOperations
- from: failed
  to: suppressed
  trigger: A later attempt withholds all recipients.
  guard: The notice remains due and the environment policy suppresses delivery.
  side_effects:
  - Store suppression as a satisfied obligation.
  who: deletion schedule job
  provenance: inferred
  source: services-platform:modules/tenants/services/deletion/notices/send-notices.ts
invalid: []
concurrency: The sender has no exclusive row claim. Unique obligation slots prevent duplicate rows rather than duplicate
  messages. Schedule notice retries use exponential waits with six retry attempts, then a six-hour revisit; the
  execution ends after at most one year. Final purge notices have no independent perpetual retry loop.
invariants:
- INV-DOM-PFM-TNL-005-05
- INV-DOM-PFM-TNL-005-07
evidence:
- 'services-platform at ad3f6a65: modules/tenants/services/deletion/notices/*.ts; services/deletion/notice-schedule.ts;
  db/tenant-deletion-notices.table.ts; aws/logic/tenant-deletion-notice.alarm.ts.'
- 'FND-PFM-TNL-056: due selection excludes terminal rows but the outcome setter has no transition guard.'
---

# Deletion Notice Delivery

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> pending: obligation recorded at its due time
  pending --> delivered: provider accepted
  pending --> suppressed: environment withheld every recipient
  pending --> failed: send failed
  failed --> delivered: sent on a later wake-up
  failed --> suppressed: withheld on a later wake-up
  delivered --> [*]
  suppressed --> [*]
```

## Transitions Explained

Notice rows record obligations for the request, reminders and decision outcomes. The schedule sends due messages; purge work sends completion and failure messages. Accepted or suppressed delivery satisfies the corresponding gate. A failed per-notice send records its error for another attempt.

Failures while preparing recipients can occur before any individual outcome is recorded. Delivery is an external action followed by persistence, so provider acceptance does not guarantee the row was updated.

## What Cannot Happen

The due-notice reader excludes delivered and suppressed rows. This selection rule avoids ordinary resending, but it is not a state-machine guard on the outcome writer. A crash or overlapping sends can produce another message before the completed outcome is visible.

## Concurrency and Timing

The sender has no exclusive row claim. Unique obligation slots prevent duplicate rows rather than duplicate messages. Schedule notice retries use exponential waits with six retry attempts, then a six-hour revisit; the execution ends after at most one year. Final purge notices have no independent perpetual retry loop.
