مهندسی سامانه‌های یادگیری و مَکنو · فصل ۵ — Governance، Notification، Tutor، Portfolio و Trust · 315

Web Push and Email Notification Delivery

Design a multi-channel notification delivery contract that separates notification intent, user/channel permission, subscription or address validity, dispatch idempotency, provider acceptance, delivery/bounce/complaint evidence, suppression and revocation; preserves unknown delivery when no reliable receipt exists; and routes retry or fallback without overriding user consent or fabricating a delivered state. می‌تواند «Web Push و Email Notification Delivery» را در یک سامانه‌ی یادگیری محدود با state/evidence/governance و QA مناسب طراحی کند.

Web Push و Email Notification Delivery — fa-IR

Lesson summary

Design a multi-channel notification delivery contract that separates notification intent, user/channel permission, subscription or address validity, dispatch idempotency, provider acceptance, delivery/bounce/complaint evidence, suppression and revocation; preserves unknown delivery when no reliable receipt exists; and routes retry or fallback without overriding user consent or fabricating a delivered state.

می‌تواند «Web Push و Email Notification Delivery» را در یک سامانه‌ی یادگیری محدود با state/evidence/governance و QA مناسب طراحی کند.

This lesson produces

می‌تواند «Web Push و Email Notification Delivery» را در یک سامانه‌ی یادگیری محدود با state/evidence/governance و QA مناسب طراحی کند.

Who it is for

Foundation

Use a field map, one worked scenario and explicit state vocabulary before independent construction.

Repair

Identify the failed evidence dimension, use the smallest mutated fixture and rerun only the affected gate.

Experienced

Compress definitions; require trade-off defense, counterexample analysis and changed-context transfer.

Prerequisites

A provider accepted the request. Did the learner receive anything?

An assignment reminder is queued for Web Push. The learner later revokes push permission, while email fallback remains allowed. An older push request already received a provider 201 Created, but no end-user delivery signal exists. If the product stores all of that as sent=true, it loses the facts needed to suppress the revoked send, preserve the earlier event as UNKNOWN_DELIVERY, and issue a permitted fallback without creating a duplicate.

In this lesson you build Notification Consent, Dispatch & Delivery Evidence Matrix v1. The matrix keeps notification intent, purpose, channel permission, endpoint/address validity, preference version, dispatch identity, provider acceptance, delivery/bounce/complaint evidence, suppression, retry budget, fallback, and final certainty as separate states.

Core rule: permission authorizes an attempt; provider acceptance records transport evidence; only explicit delivery evidence can strengthen delivery certainty.

For: learning-platform engineers, notification-service designers, reliability engineers, privacy/product reviewers, and QA teams. Not for: proving a learner read a message, inventing consent from a product goal, treating DKIM as inbox delivery, or retrying across a preference change without recomputing eligibility.

Route orientation and ownership boundary

MKN-022 owns only Web Push and Email Notification Delivery. Its frozen prerequisite is MKN-021. MKN-021 owns contributor/editorial governance and MKN-023 owns AI Tutor grounding/evaluation; this lesson does not absorb either outcome.

Foundation learners use a field map and one guided mutation. Repair learners isolate the first invalidated state and rerun only the affected gate. Experienced learners defend retry, suppression, fallback, and observability trade-offs without collapsing provider responses into one success flag.

Checkpoints: F1 state the ownership boundary and one non-goal; F2 diagnose a queued push after permission revocation; F3 rebuild a changed-context dispatch after endpoint rotation, preference-version change, and a transient email failure.

Mental model: intent → eligibility → idempotent dispatch → evidence → bounded final state

Use this ordered pipeline:

notification intent → purpose + current preference → channel permission/validity → idempotent dispatch → provider evidence → delivery/bounce/complaint evidence → suppression/retry/fallback → final state

Never collapse these layers. A notification can be authorized but not queued, queued but suppressed before dispatch, accepted by a provider but delivery-unknown, temporarily failed and retryable, permanently bounced, or complaint-suppressed. The state machine must preserve those distinctions because retry and fallback decisions depend on them.

Foundation contract: version every fact that can invalidate a send

The frozen evidence dimensions are: notification_intent_id, channel, purpose, consent_state, permission_state, push_subscription_ref, subscription_expiry, email_address_ref, preference_version, template_version, dispatch_id, idempotency_key, provider_message_id, queued_at, accepted_at, delivery_signal_at, bounce_class, complaint_state, suppression_state, revocation_state, retry_count, retry_budget, fallback_channel, dkim_state, and unknown_delivery.

Minimum invariants:

  1. The dispatch decision binds to the current preference version, not the version present when work was first queued.
  2. Push permission and push-subscription validity are checked at dispatch time. Revocation suppresses future attempts.
  3. A logical dispatch has a stable idempotency identity. A retry cannot silently become a second logical notification.
  4. Provider acceptance is not promoted to end-user delivery without a reliable delivery signal.
  5. DKIM authentication is email-authentication evidence, not inbox placement, read receipt, or learner engagement.
  6. Permanent bounce or complaint evidence suppresses future email attempts according to the local policy; a transient failure consumes retry budget without becoming DELIVERED.
  7. Fallback requires both current preference/permission and an explicit fallback policy; product urgency cannot override revocation.
  8. Missing decisive evidence remains UNKNOWN, HOLD, or INSUFFICIENT_EVIDENCE instead of a positive state.

Deep explanation: what the external standards prove—and what they do not

W3C Push API. The current Push API defines a push subscription as a delivery context between user agent and push service. It associates subscriptions with endpoints, optional expiration, Service Worker registration, refresh, deactivation, and the push permission. The current Working Draft also states that permission revocation deactivates affected subscriptions. This is strong evidence for subscription/permission lifecycle mechanics. It does not define MAKNOW notification purposes, preference versions, retry budgets, or fallback policy.

RFC 8030. Web Push separates application server, push service, and user agent. An application server can request push-message delivery and receive 201 Created from the push service. RFC 8030 explicitly distinguishes acceptance by the push service from delivery to the user agent. It also defines optional receipt-related interactions and reliability considerations. Therefore provider accepted is a transport state, not a learner-delivery claim.

DKIM (RFC 6376). DKIM lets a signing domain claim responsibility for an email message using a cryptographic signature. A valid DKIM state helps authenticate message origin/responsibility, but it does not prove inbox delivery, visibility, reading, or pedagogical effect.

The remaining rules—purpose taxonomy, consent ledger, preference versioning, idempotency construction, retry budget, fallback precedence, suppression windows, complaint handling, and learner-facing communication policy—are MAKNOW DESIGN and must be governed locally.

Worked examples

Example A — accepted push, unknown delivery

Preference PREF-17 permits push with email fallback. Push permission is granted and subscription PS-88 is current. Dispatch D-PUSH-41 is submitted once with idempotency key N-441|push|PREF-17. The push service returns an acceptance identifier, but no reliable end-user delivery signal exists.

Correct result: preserve accepted_at, keep unknown_delivery=true, and do not write DELIVERED. Whether a retry is allowed depends on the explicit retry policy and the semantics of the provider evidence—not on a wish to make the reminder “successful.”

Example B — permission revoked after queueing

The same reminder was queued at 09:00. At 09:03 the learner revokes push permission. The worker begins processing the old queue item at 09:05. The worker must read the current permission/preference version before dispatch. The push attempt becomes SUPPRESSED_REVOKED; the old queue timestamp does not preserve permission.

If current preferences permit email fallback, create a new channel-specific idempotent dispatch derived from the same intent and current preference version. Do not reuse the stale push dispatch identity and do not send both channels merely because both were once eligible.

Example C — temporary email failure

Email fallback is allowed. DKIM signing is configured and the provider accepts the submission, but later reports a temporary failure. dkim_state=PASS remains authentication evidence; it is not delivery evidence. If retry count is below budget and no complaint/suppression exists, retry the same logical email dispatch idempotently. If the retry budget is exhausted, stop and escalate/expire according to policy rather than creating a fresh dispatch to evade the budget.

Failure modes that create false confidence

  • sent=true after provider acceptance. Loses the distinction between queue, provider acceptance, user-agent delivery, inbox placement, and read state.
  • Queue-time permission snapshot. A worker sends after permission or preference has changed.
  • Retry with a new idempotency key. Converts an uncertain transport attempt into duplicate-notification risk.
  • Fallback as an override. Product urgency chooses another channel despite a current opt-out or suppression state.
  • DKIM-as-delivery. Authentication evidence is mislabeled as inbox evidence.
  • Temporary bounce as permanent failure—or permanent bounce as retryable. Retry policy ignores bounce class.
  • Complaint ignored. Future sends continue despite suppression-required evidence.
  • Subscription rotation ignored. A stale endpoint is retried instead of recomputing channel validity from the current subscription.
  • Unknown coerced to success. Missing receipt evidence is converted to DELIVERED because dashboards prefer a simple metric.

Alternatives and trade-offs

At-most-once vs retry. At-most-once behavior minimizes duplicates but can increase missed notifications under uncertain provider states. Retrying improves delivery opportunity but requires stable idempotency semantics and a finite retry budget.

Push-first vs channel-independent planning. Push-first can reduce email volume but risks coupling the orchestration model to one channel. A channel-independent intent ledger is more verbose but makes preference changes, fallback, and audit behavior explicit.

Provider-specific delivery receipts vs portable certainty. Provider receipts can improve observability where they exist, but a portable contract must preserve UNKNOWN_DELIVERY when an equivalent reliable signal is absent. Do not normalize the weakest provider into a fabricated universal delivery state.

Immediate fallback vs delayed fallback. Immediate fallback can create duplicates when a primary channel is merely delayed. Delayed fallback reduces duplication but may miss time-sensitive value. The correct policy is local and must name the trigger, delay, current-permission recheck, and cancellation rule.

Experienced bridge: treat notification delivery as a ledgered distributed system

Production implementations should make the evidence model observable. Queue messages carry intent ID, preference version, channel, and logical idempotency identity. Workers reject stale preference versions. Provider callbacks are appended as evidence, not destructive state rewrites. Complaint/bounce events feed suppression independently. A reconciler can detect accepted-but-unknown, retry-budget exhaustion, stale endpoint references, or orphaned dispatches.

Metrics should separate intent created, eligible, dispatch attempted, provider accepted, reliable delivery signal observed, temporary failure, permanent failure, complaint, suppressed, and unknown. A single “delivery rate” is useful only if its denominator and evidence semantics are explicit.

Guided and independent practice

Guided. Run MKN-022-LAB1 on the baseline fixture. Populate the evidence matrix and derive the terminal state. Then apply the mutation “revoke push permission after queueing but before dispatch.” Name the first invalidated field and the minimal safe action.

Independent. Diagnose four cases: provider acceptance claimed as delivery; retry with a different idempotency key; email complaint with fallback still configured; and old push retry after a preference-version update. For each case, state the decisive evidence, terminal state, and whether any fallback is still permitted.

Transfer. The push subscription rotates and the email provider returns a temporary failure after a preference-version update. Rebuild the decision from current permission, current preference version, the new endpoint reference, prior provider evidence, retry count/budget, and fallback permission. The baseline decision label is not an oracle.

Verification and evidence

The Lab is fully offline and synthetic: JSON fixtures plus deterministic Python rules, no network, provider API, production address, or learner data. It verifies current preference binding, push permission/subscription validity, idempotency reuse, provider-acceptance vs delivery separation, DKIM boundary, bounce/complaint suppression, retry budget, permitted fallback, and changed-context recomputation.

A valid evidence row answers: What was the notification purpose? Which preference version authorized the channel? Was permission still valid at dispatch? Which endpoint/address was current? What logical dispatch/idempotency identity was used? What did the provider actually prove? Is delivery known or unknown? Was there a bounce or complaint? Is the channel suppressed or revoked? Is retry budget available? Is fallback currently permitted? Why is the final state no stronger than this evidence?

Assessment and transfer gate

Four blocking assessments:

  1. Explain MKN-022 ownership and one adjacent non-goal.
  2. Build the complete notification evidence matrix for the baseline synthetic fixture.
  3. Diagnose push-permission revocation after queueing but before dispatch and give the minimum safe repair.
  4. Transfer: recompute the dispatch after subscription rotation, preference-version update, and temporary email failure without duplicating the notification.

The transfer fails if it copies the baseline verdict, relies on queue-time permission, changes idempotency merely to “try again,” treats provider acceptance/DKIM as delivery, or uses fallback contrary to current preference/suppression evidence.

References, freshness, and authority boundaries

W3C — Push API, latest published version https://www.w3.org/TR/push-api/ FACT: current published Working Draft defines push subscriptions, endpoint/expiration, subscription refresh/deactivation, Service Worker relationship, and push permission; permission revocation deactivates affected subscriptions. Boundary: it does not define MAKNOW purpose, preference, retry, or fallback policy.

IETF RFC 8030 — Generic Event Delivery Using HTTP Push https://www.rfc-editor.org/info/rfc8030/ FACT: defines Web Push protocol roles and message-delivery interactions. A push-service 201 Created acceptance does not itself prove delivery to the user agent. Boundary: transport semantics, not learner communication authority.

IETF RFC 6376 — DomainKeys Identified Mail (DKIM) Signatures https://www.rfc-editor.org/info/rfc6376/ FACT: enables a signing domain to claim responsibility for a message through a cryptographic signature. Boundary: not proof of inbox placement, reading, or learner engagement.

Sources were rechecked 2026-09-13. Recheck the evolving W3C Push API by 2027-01-15 or earlier on a materially newer publication; recheck RFC status/errata at the same time or earlier on relevant updates. Purpose taxonomy, preference/consent ledger, idempotency construction, retry budget, fallback policy, suppression policy, and delivery-certainty vocabulary remain MAKNOW DESIGN.

Assessment

There is no answer key in this lesson pack; answer it yourself and mark honestly. "Needs review" sends the lesson to your review queue.

Assessment rubric
  1. Identity and contract — owns notification delivery only.
  2. Exact evidence binding — current permission/preference, endpoint/address, dispatch identity and provider evidence remain traceable.
  3. Negative evidence — revocation, unknown delivery, bounce/complaint and suppression stay typed.
  4. Bounded decision — provider acceptance/DKIM cannot be promoted to delivery; retry/fallback cannot override consent.
  5. Transfer — rotated subscription + changed preference + temporary email failure are independently recomputed without duplicate dispatch.

References & freshness

W3C Push API — latest published version
·
RFC 8030 — Generic Event Delivery Using HTTP Push
·
RFC 6376 — DomainKeys Identified Mail (DKIM) Signatures
·
MAKNOW MKN-022 frozen Bible and effective runtime overlay
·

Case studies

Lab files

Offline synthetic notification-delivery state machine. Run python run_checks.py. The fixtures contain no production address or provider credential. Derive states from current permission/preference, endpoint validity, idempotency, provider evidence, bounce/complaint, retry budget and fallback policy.