Defines a notification delivery state machine that retries transient failures without duplicating user-visible messages and explains delayed, failed, or suppressed delivery truthfully in product history.
Package status: reference context ready for human review. The contract and test scenarios are complete, but no claim is made that an adopting implementation has passed them.
Decision
Assign one notification and channel-delivery identity, persist each attempt, and retry only classified transient outcomes with capped exponential backoff and jitter. Terminal, suppressed, and expired states never retry automatically.
Scope
- Delivery identity, attempt state, provider outcome classification, schedule, expiry, duplicate suppression, status display, cancellation, and manual retry.
- Email, push, SMS, or webhook-style notification delivery.
- At-least-once worker behavior with idempotent provider handoff where available.
Outside this block
- The notification content template or business action that triggered it.
- Promising exactly-once presentation when the downstream provider cannot support it.
Contract
- One logical delivery has a stable ID independent of worker attempts.
- Attempt records include scheduled/start/end times, provider request identity, classified outcome, and redacted diagnostic code.
- Only explicitly transient categories retry; invalid address/token, opt-out, policy suppression, and content rejection are terminal or corrective states.
- Backoff, jitter, maximum attempts, absolute expiry, and provider retry hints are bounded profile values.
- Cancellation prevents unsent attempts and records whether an in-flight handoff may still arrive.
- User-facing history distinguishes queued, delayed, sent-to-provider, delivered when confirmed, failed, expired, and suppressed.
Implementation guidance
- Use a durable queue or schedule table plus an atomic attempt claim lease.
- Reuse a provider idempotency or collapse key when supported, and keep it stable across retry attempts.
- Separate provider acceptance from confirmed delivery.
- Deduplicate source events before creating the logical notification.
Failure handling and safeguards
- A worker crash after provider acceptance resolves through provider/request lookup or reuses the same handoff identity.
- A rate-limit response honors a bounded retry hint; it does not schedule beyond notification expiry.
- A recovered device token creates a new authorized delivery transition, not mutation of prior attempt evidence.
Verification and operations
- Measure first-attempt success, retry recovery, terminal categories, expiry, queue lag, duplicate source suppression, uncertain handoffs, and confirmed-delivery latency.
- Alert on provider-specific outcome shifts and growing retry cohorts.
- Test crash points and repeated queue delivery with a deterministic provider stub.
The executable-looking examples in this package are fixtures and acceptance contracts. Run
python tools/validate.py from the collection root to check package structure and metadata; then
implement and execute the scenarios in the target repository.
Adoption assumptions
- Names and numeric values in
example.yamlare an adoption profile, not universal defaults. - The adopting team must map actors, data classes, error vocabulary, and ownership to its system.
References
- No external normative source is required; this package defines a project decision.