---
id: STATE-PFM-NOT-013
title: Address suppression
object: DOM-PFM-NOT-005
product_area: platform
module: notifications
revision: 1
status: draft
design_intent: confirmed
origin: Andrew 2026-10-09 (permanent bounces and complaints suppress; suppression applies even when opt-out
  is ignored), services-platform:docs/communications/architecture.md#2026-10-09 — Final acceptance
implementation_evidence: observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
states:
- name: not suppressed
  meaning: The workspace has no active protection entry for this address.
- name: active
  meaning: Protection withholds all classifications of mail to the address.
- name: released
  meaning: Staff released the protection and its actor, time and explanation remain historical.
transitions:
- from: not suppressed
  to: active
  trigger: Staff add protection, or provider feedback triggers it.
  guard: Address validation applies; staff additions require suppression-create authority.
  side_effects:
  - Withhold later messages before calling the provider.
  who: Feedback processor; association communication administrator
  provenance: test
  source: services-platform:modules/communications/tests/integration/lifecycle/contact-role-compliance-communication.integration.spec.js#suppresses
    the address for the tenant
- from: active
  to: active
  trigger: Protection is requested for an already protected address.
  guard: No additional condition is imposed beyond its source state.
  side_effects:
  - Retain the existing active entry and reason.
  who: Feedback processor; association communication administrator
  provenance: observed
  source: services-platform:modules/communications/services/persistence/suppressions.ts:suppressAddress
- from: active
  to: released
  trigger: Staff release address protection.
  guard: Suppression-update authority and an explanation are required.
  side_effects:
  - Record who released it, when and why.
  who: Association communication administrator
  provenance: observed
  source: services-platform:modules/communications/services/persistence/suppressions.ts:releaseSuppression
- from: released
  to: active
  trigger: New provider feedback or a staff addition protects a released address.
  guard: No additional condition is imposed beyond its source state.
  side_effects:
  - Create another active history entry.
  who: Feedback processor; association communication administrator
  provenance: observed
  source: services-platform:modules/communications/services/persistence/suppressions.ts:suppressAddress
invalid:
- from: released
  to: not suppressed
  why: Releasing protection preserves its historical entry.
- from: active
  to: released
  why: Release requires an explanation and an active entry.
concurrency: A unique index permits one active canonical address per workspace, and repeated additions
  are harmless. The send-claim transaction checks protection again; messages already claimed can race
  with a new suppression.
evidence:
- 'services-platform at ad3f6a65: modules/communications/services/persistence/suppressions.ts; db/communication-suppressions.table.ts;
  aws/api/communications.routes.ts (suppression routes).'
---
# Address suppression

## The Lifecycle

```mermaid
stateDiagram-v2
    state "not suppressed" as s0
    state "active" as s1
    state "released" as s2
    s0 --> s1
    s1 --> s1
    s1 --> s2
    s2 --> s1
```

## Transitions Explained

The transition rows describe stored state changes, their checks and their recorded effects. A queue receive, provider outcome and staff action can reach different lifecycle boundaries.

## What Cannot Happen

Releasing protection preserves its historical entry. Release requires an explanation and an active entry.

## Concurrency and Timing

A unique index permits one active canonical address per workspace, and repeated additions are harmless. The send-claim transaction checks protection again; messages already claimed can race with a new suppression.
