---
status: reconciled-partial
coverage_depth: deep-for-shipped-control-planes
last_walked: 2026-05-29
last_reconciled: 2026-07-18
specs:
  - apps/oshun/web/e2e/profile-notifications-index.spec.ts
  - apps/oshun/web/e2e/profile-notification-preferences.spec.ts
  - apps/oshun/web/e2e/notifications-preferences-api.spec.ts
  - apps/oshun/web/e2e/profile-channel-bindings.spec.ts
  - apps/oshun/web/e2e/telegram-webhook-delivery.spec.ts
  - apps/oshun/web/e2e/telegram-binding-bff.spec.ts
  - apps/oshun/web/e2e/messages-center-bff.spec.ts
  - apps/oshun/bff/src/customer/customer-message-center-store-durability.spec.ts
  - apps/oshun/bff/src/customer/customer-message-center-durability.integration.spec.ts
  - apps/oshun/bff/src/messaging-channels/channel-bindings-store.test.ts
  - apps/oshun/bff/src/messaging-channels/channel-bindings-durability.integration.spec.ts
  - apps/oshun/bff/src/telegram/user-state-durability.spec.ts
  - apps/oshun/bff/src/telegram/user-state-durability.integration.spec.ts
source: WALKTHROUGH/journeys/messages-quiet-hours-and-channel-binding.md
---

# Journey result: Quiet hours, verified channels, and provider boundaries

- **Walked**: 2026-05-29 at `bf12b0f7d8c291499e1df1ec75d4bd21acf3f6b1`. The
  retained result reported a passing route walk through an ephemeral `/tmp`
  script; it did not preserve the script, raw report, browser trace, or provider
  evidence.
- **Reconciled**: 2026-07-18 against the current read-only summary, mutable
  profile controls, preference stores, channel-binding lifecycle and snapshot
  wire, durable message-center delay/replay path, Telegram HMAC routes and
  user-state snapshot, reminder worker, provider router, notification, reminder,
  message-center, and Telegram write-through/erasure suites, and all seven named
  Playwright specs. The message-center, channel-binding, and Telegram unit
  suites passed freshly at eleven, 21, and six cases; their real-Postgres cases
  each collected as one skip without a database URL. This was not a fresh
  application run.
- **Verdict**: **partial / deep for the shipped control planes** — the current
  evidence deeply covers summary-to-editor handoff, quiet-hours and domain
  preference round trips, a non-production email/SMS/WhatsApp verification
  lifecycle, durable custom notification preferences, durable reminder
  schedule/inbox/erasure state, required restart-safe channel bindings, durable
  message-center delay and manual replay, safety bypass, exact profile/session/
  message-continuity erasure and export, and restart-safe Telegram link,
  capture, preference, suppression, export, and erasure state. It does not prove
  production code delivery, an atomic master/window update, automatic
  message-center replay, genuine account step-up, identity convergence, or
  delivery to a profile-bound email/SMS/WhatsApp address.
- **Current authority**:
  [`WALKTHROUGH/journeys/messages-quiet-hours-and-channel-binding.md`](../journeys/messages-quiet-hours-and-channel-binding.md)
  defines the same split authorities and partial outcome.

## Result at a glance

| Interaction                   | Proof · limit                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Read-only summary and handoff | **Proof:** ten browser cases cover the account-scoped four-channel, five-category projection, preference read-back, explicit failure copy, editor link, anonymous redirect, footer behavior, 390 px stacking, standalone mode, and real-service-worker replay. **Limit:** the page is a static projection; its server fetch collapses an unavailable or rejected response into an empty state.                                                                                                                                                                                                                                                                    |
| Quiet-hours and domain editor | **Proof:** five browser cases and twelve real-HTTP cases cover the natural two-write enable flow, start/end time, timezone, normalized weekday mask, digest cadence, all six domain matrices, auth, scope, and validation. The custom preference store now commits through a required database-backed snapshot. **Limit:** the consumer-profile master and custom window remain separate durable records written by separate requests, so partial success can still make their effective values drift.                                                                                                                                                            |
| Email/SMS/WhatsApp binding    | **Proof:** two browser cases drive real BFF request, salted-hash pending state, preview-code verification, wrong-code persistence, secret-free reload, typed removal, 390 px controls, and service-worker behavior. Production requires the snapshot; request, verify, and unbind await candidate persistence. A 21-case unit suite proves verified/pending restart, rollback, race ordering, and erasure fences. **Limit:** only non-production exposes a usable code, and the real-Postgres restart case is environment-gated.                                                                                                                                  |
| Verification-code delivery    | **Proof:** the production branch honestly returns `delivery: missing-config` and omits the plaintext code. **Limit:** no email, SMS, or WhatsApp transport is invoked by the bind route, so a production user cannot complete the lifecycle from this surface.                                                                                                                                                                                                                                                                                                                                                                                                    |
| Bound-address delivery        | **Proof:** current source maps verified binding fields into a reminder recipient, gates matching reminder channels on verified status, and awaits a durable reminder snapshot before acknowledging production schedules or cycles. **Limit:** automatic producers all choose `push`, so their copied email/SMS/WhatsApp fields are ignored; manually scheduled external reminders carry an independently supplied recipient. No named suite proves provider delivery to the stored profile address.                                                                                                                                                               |
| Quiet-hours dispatch          | **Proof:** the sixteen-case BFF suite covers non-essential delay, due replay, crisis-frame hold, incident bypass, and resulting inbox receipts over real HTTP. The required message-center snapshot preserves delayed work, inbox rows, receipts, and holds; failed replay persistence keeps work queued. **Limit:** replay is an explicit admin call without a timer or claim lease, and its `sent`/`delivered` stages are authored by the BFF rather than provider callbacks.                                                                                                                                                                                   |
| Telegram identity seam        | **Proof:** five real-BFF Login Widget/step-up cases verify a valid HMAC, two invalid HMAC forms, the non-sensitive scope set, and action classification; two of the 24 webhook-suite cases add Mini App HMAC rejection. A six-case unit suite proves write-before-publish link/capture state, rollback, restart, ordered erasure fences, and fail-closed production use; its one-case Postgres companion is environment-gated. **Limit:** the public Login Widget still mints an `iris:<telegram-id>` subject rather than one of the three profile rows, so this does not prove convergence with a signed-in profile or bot-provider delivery.                    |
| Removal                       | **Proof:** a verified row rejects DELETE without the literal `channel-revoke` header value, then awaits a durable `unbound` projection. Account deletion durably erases/fences the exact profile channel bindings, Telegram profile/captures, custom preferences, device sessions/tokens, notification read state, reminder continuity, and message-center partition; profile, saved-content, and session exports include the corresponding records. **Limit:** the phrase is client-known confirmation, not primary-credential step-up, and removing one profile channel invokes none of the other erasers or provider, Telegram, device-token, or chat cleanup. |

## Evidence map

This vertical authority ledger keeps three independent planes separate. Solid
edges are exercised by the named application suites; dashed edges mark the
production meaning still missing. The stacked lanes are reading order, not a
claim that profile binding, message-center replay, and Telegram call one
another.

```mermaid
flowchart TB
    A[Profile summary and mutable editor] --> B[Durable binding snapshot plus preview verification]
    B -. missing .-> C[Production code and bound-address delivery]
    C ~~~ D[Separate durable master and preference snapshots]
    D --> E[Message policy, durable delay, and admin replay]
    E -. missing .-> F[Message-center timer, claim lease, and provider callback]
    F ~~~ G[Durable Telegram HMAC identity and user state]
    G -. separate .-> H[Profile binding inventory]
```

## Proven observations

### The historical pass remains a dated route observation, not the current grade

- The old result observed `/profile/notifications`, four channels, four
  categories, and no feature-flag rate limit. The current BFF projection has
  four channels and **five** categories after adding the Arete weekly-review
  row, so the historical count is no longer a product contract.
- The current ten-case index spec proves more than the old walker: account-email
  read-back, master push reflection, Arete reminder reflection, fail-closed
  empty copy, editor navigation, anonymous redirect, touch-safe footer targets,
  phone stacking, standalone mode, and an actual service-worker document replay.
- That suite still does not recover the historical raw walk or rerun the
  feature-flag premise. The old zero-error and zero-failure statements therefore
  remain dated observations at the walked commit.

### The summary and editor expose two different jobs

- `/profile/notifications` is a server-rendered, read-only projection of
  channels and categories. “Change delivery settings” opens
  `/profile?path=notifications`, where the notification matrix and quiet-hours
  controls live. The email/SMS/WhatsApp binding rows live in the broader profile
  settings panel, not in `/messages` and not as switches on the summary page.
- The summary's four channels are email, push, SMS, and Telegram. They are not
  the same inventory as `GET /v1/profile/channels`, whose bindable set is
  exactly email, SMS, and WhatsApp. A summary label therefore cannot be read as
  a verified binding or transport capability.
- A null BFF read becomes zero channels and zero categories with explicit
  recovery copy. That is honest about the unavailable projection, but it does
  not distinguish authentication rejection, network failure, malformed data, and
  a legitimately empty account.

### The profile binding lifecycle is real, secret-safe, and non-production-only

- The bind route is user-scoped and abuse-protected. It accepts only email, SMS,
  or WhatsApp, generates a six-digit code, stores a salted hash with TTL and
  attempt state, and returns a secret-free binding projection. The plaintext
  code is not persisted.
- Non-production returns `delivery: preview` and the code. Production returns
  `delivery: missing-config` with no code. The route does not call the real
  provider router, even when email/Twilio/Meta credentials exist elsewhere in
  the process.
- Verify distinguishes `verified`, `wrong-code`, `expired`, `locked`, and
  `not-pending` as 200 outcomes for an existing row; only an absent binding is
  a 404. The UI can therefore preserve a pending row and explain an incorrect
  code instead of collapsing it into a generic request error.
- The two-case browser suite performs the complete preview-code email lifecycle
  against real HTTP, reloads the full route after verification and removal,
  proves a wrong SMS code remains pending, and checks every affected control at
  a 390 px viewport for 44 px targets and zero page overflow. It does not stop
  and restart the BFF.
- Deployable startup calls `requireDurableChannelBindings` and hydrates the
  snapshot before traffic. Bind, confirm, and unbind clone the last committed
  state, serialize mutation, persist, then publish; persistence failure maps to
  `503`, an erased subject to `409`, and neither a new address nor a burned
  verification attempt leaks into the visible view.
- The 21-case focused store suite proves authoritative-empty boot, verified and
  pending-code restart recovery, user isolation, failed-write rollback,
  exact-subject erasure, adjacent-user preservation, both stale-mutation race
  orders, failed-deletion rollback, and fail-closed missing-sink behavior. Its
  one-case real-Postgres companion repeats verified-state restart and a signed
  profile erasure fence, but collected as skipped here without a database URL.
- The profile export includes the secret-safe binding record, revision, and
  statuses. Account-level profile deletion composes the binding eraser; a
  successful fence rejects stale requests after restart without deleting an
  adjacent subject.

### Quiet hours span two durable snapshots and a non-atomic editor

- The natural UI toggle performs two writes. `/v1/preferences` updates the
  consumer profile's durable `quietHoursEnabled` master flag; a separate
  `PATCH /v1/notifications/preferences` durably updates the window. Time,
  timezone, weekday mask, digest settings, six domain records, and persona
  records share a second database-backed snapshot with per-subject revisions and
  deletion fences.
- GET and PATCH responses overlay the consumer profile's master flag onto the
  preference snapshot's quiet-hours object. The reminder worker does the same.
  The message-center dispatch route, however, reads the preference object's own
  `enabled` field directly. Both authorities survive restart, but the editor's
  sequential requests have no cross-store transaction or compensating rollback;
  a failed second write or direct single-route caller can expose different
  effective state.
- The twelve-case API suite proves same-process PATCH→GET round trips for the
  custom window and every domain × modality × kind record, including scope and
  validation gates. Its first direct PATCH deliberately asserts only that
  `enabled` is a boolean because the response is sourced from the separate
  consumer profile. The named browser/API suites are not restart tests.
- The five-case browser suite proves the natural dual-write toggle, a narrowed
  weekday mask and changed start time after reload, global push gating,
  Nisaba/Metis lanes, and digest recommendation copy. Reload exercises the same
  BFF process.
- Focused notification durability tests now prove write-before-publish rollback,
  ordered retry, restart restoration, exact-subject erasure, adjacent-subject
  preservation, and stale-write rejection for both custom preferences and read
  state. A gated real-Postgres suite repeats restart and erasure-fence proof.

### The message-center proof is a policy seam, not bound-channel transport

- `messages-center-bff.spec.ts` has sixteen real-HTTP cases. Four are directly
  decisive here: a routine message inside the active window is delayed without
  an inbox row; explicit after-window replay writes the row and later receipt
  stages; an active crisis frame holds due replay; and a critical incident
  bypasses delay.
- Quiet-hours delayed jobs share the required message-center snapshot with
  messages, receipts, suppressions, revisions, and deletion fences. Production
  startup hydrates it before traffic, and dispatch awaits persistence before
  returning `202`; no timer claims due work, so an admin must still invoke
  `POST /v1/admin/customer-messages/replay-due`.
- Replay commits a successful message, BFF-authored receipts, and delayed-row
  removal as one candidate. Snapshot failure retains the original job; policy
  rejection or a gate exception becomes a durable queued failure/hold. The
  focused eleven-case unit suite also proves restart recovery, write rollback,
  exact-subject erasure, adjacent-user preservation, and send/delete ordering;
  one database-gated case repeats restart and erasure-fence proof on Postgres.
- This dispatch route does not read `GET /v1/profile/channels` and never invokes
  email, SMS, WhatsApp, push, or Telegram providers. Its channel value selects
  local policy and receipt labels only. Replay authors `sent` and `delivered`
  itself without receiving a provider message id or callback.

### Real reminder transports exist, but the profile-bound handoff is incomplete

- The separate reminder cycle can call real SendGrid/SMTP, Twilio, Meta
  WhatsApp, FCM, APNs, Expo, or Web Push transports when matching credentials
  and recipient fields are present; missing credentials yield `missing-config`,
  never fabricated success. In-app reminder delivery is available independently.
- BFF startup resolves verified email/SMS/WhatsApp binding fields into each
  automatic producer's `MessageRecipient`, and reminder policy suppresses an
  explicitly scheduled email/SMS/WhatsApp channel without a verified binding.
  That is meaningful source wiring, but it does not complete this journey.
- Reminder schedules, delivered-id ownership, the in-app inbox, and
  deleted-recipient fences now share a database-backed snapshot. Production
  requires the sink; schedule, cycle, and erasure mutations serialize, commit
  the candidate snapshot before publishing it in memory, and return explicit
  persistence or deleted-subject failures instead of acknowledging drift.
- Focused durability tests cover failed commits, retry, exact-subject deletion,
  adjacent-subject preservation, in-flight create/delete ordering, legacy-owner
  repair, restart hydration, and a gated real-Postgres restart/erasure path. The
  optional worker now acquires a cycle lease before producing or delivering:
  shared Redis provides the cross-replica fence, while a single-process
  deployment uses an explicit local lease. Lease failure skips the tick without
  consuming scheduled work.
- The streak, Nyx, due-assignment, upcoming-session, and content-drop automatic
  producers all set `channel: 'push'`. The delivery router therefore consults a
  push token and ignores the copied email, phone, and WhatsApp recipient fields.
  Enabling the optional worker does not by itself send to those bound addresses.
- The admin schedule route can submit an email/SMS/WhatsApp reminder, but its
  payload supplies the recipient separately. Awaited snapshot persistence makes
  the schedule durable; the policy check still verifies only that some binding
  exists for the channel, not that the supplied address equals the verified
  address. No named suite demonstrates or closes this join.

### Telegram is a different identity system

- The five-case Telegram binding suite signs a genuine Login Widget payload,
  proves the exact non-sensitive scopes, rejects tampered and missing hashes,
  and classifies six sensitive actions as requiring primary-credential
  challenge. The Login Widget now awaits a durable Telegram user-state binding;
  the authenticated link-token flow, webhook completion, `/unlink`, captures,
  voice preference, and delivery suppression use the same ordered snapshot.
- Production startup requires that snapshot and hydrates it before traffic. The
  six-case focused suite proves candidate-before-publish capture and link
  writes, failed-write rollback, restart restoration, independent profile and
  saved-content fences, adjacent-subject preservation, both write/delete race
  orders, failed-erasure rollback, and fail-closed missing-sink behavior. Its
  one-case real-Postgres companion repeats restart, export, and both erasure
  fences, but collected as skipped here without a database URL.
- The profile export includes secret-safe link, voice, and suppression state;
  raw link nonces are hashed. The saved-content export includes Telegram
  captures. Account deletion composes the profile and capture erasers as two
  independent signed-service categories.
- The public Login Widget route derives `oshunUserId` as
  `iris:<telegram-user-id>`; it does not authenticate a current profile member
  or create an email/SMS/WhatsApp row. The authenticated deep-link account flow
  can bind a profile subject, but the five browser cases do not prove that
  convergence or a profile-inventory projection. Bot reply delivery remains a
  distinct provider path.
- `telegram-webhook-delivery.spec.ts` contains 24 cases, but only its final two
  Mini App cases directly support this binding result, and both are negative
  HMAC branches. The other 22 belong to the Telegram assistant-delivery journey
  and must not inflate this page's ownership proof.

## Boundaries and gaps

- **A durable binding is not a delivered verification code.** The required row
  and its salted code hash survive restart while production still returns
  `missing-config`.
- **A preview code is not production verification.** It exists only outside
  production so development and browser automation can finish the round trip.
- **A verified address is not provider consent.** The profile flow records
  address ownership, not tenant permission, A2P/WhatsApp opt-in, capability,
  residency, suppression, or provider receipt.
- **Recipient resolution is not bound-address delivery.** Automatic producers
  choose push, and manual schedules supply their own recipient object.
- **A durable reminder snapshot is not a bound-recipient join.** It preserves
  exactly the recipient object the producer or admin supplied; it does not prove
  equality with the profile binding.
- **A cycle lease is not a bound-recipient join.** It prevents concurrent
  reminder cycles; it does not prove that a supplied delivery address matches
  the profile's verified binding.
- **Two durable snapshots are not one atomic quiet-hours commit.** The master
  flag and custom window persist independently, while the editor issues two
  requests and neither store rolls the other back after partial failure.
- **A named browser reload is not the retained restart proof.** The source-level
  notification, binding, and Telegram durability suites cover restart and
  erasure, while the seven named Playwright specs keep one BFF process and do
  not retain a backing-tier restart trace.
- **A durable delayed entry is not an automatic replay scheduler.** The job and
  its failure state survive restart, but they move only after an explicit admin
  call; there is no timer, distributed claim, or leader lease.
- **A database-backed snapshot is not multi-writer arbitration.** Ordered
  candidate-before-publish mutation protects one process and acknowledged
  restart state, but does not itself prove concurrent BFF writers cannot replace
  one another's snapshot.
- **A replay-authored receipt is not provider acknowledgment.** The same BFF
  writes the queued, sent, and delivered stages without a provider callback.
- **A static phrase is not account step-up.** `channel-revoke` is shipped in the
  client and compared literally by the server.
- **An unbound row is not a revocation cascade.** Account-level data deletion
  can erase and fence durable profile bindings, device sessions/tokens,
  notification preferences/read state, reminder continuity, and exact-subject
  message-center history/suppressions/delayed work, plus the exact-subject
  Telegram profile and capture partitions. The single profile-channel DELETE
  does not invoke those other erasers; independently supplied recipients,
  provider subscriptions, other bindings, device tokens, Telegram state, Mini
  App sessions, and chat caches are not cancelled by unbinding.
- **A Telegram-derived Iris subject is not a profile channel binding.** It is a
  separate HMAC-backed identity seam with durable link and unlink paths.
  Exact-subject export and erasure do not make `iris:<telegram-id>` the same
  subject as an independently authenticated profile member.
- **Broad suite membership is not direct proof.** Only two of 24 Telegram
  webhook cases concern the Mini App HMAC boundary on this page.
- **Deep control coverage is not a complete delivery journey.** Production code
  transport, atomic master/window updates, safe scheduler ownership,
  profile-bound provider delivery, callbacks, consent, and revocation remain
  outside the grade.
- **Source reconciliation is not execution.** The focused message-center and
  channel-binding unit suites were rerun at **11 passed** and **21 passed**; the
  Telegram durability suite passed **6 cases**. Their database-gated companions
  each collected as **1 skipped** without a URL. None of the seven cited
  Playwright application specs was rerun for this documentation audit.

## Re-run evidence

Run the seven focused specs sequentially against one immutable commit and one
controlled BFF/web environment:

```bash
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/profile-notifications-index.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/profile-notification-preferences.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/notifications-preferences-api.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/profile-channel-bindings.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/telegram-binding-bff.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/telegram-webhook-delivery.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/web exec playwright test -c playwright.config.ts e2e/messages-center-bff.spec.ts --project=chromium --workers=1
pnpm --dir apps/oshun/bff exec vitest run src/customer/customer-message-center-store-durability.spec.ts
OSHUN_ADMIN_DATABASE_URL=postgres://… pnpm --dir apps/oshun/bff exec vitest run -c vitest.integration.config.ts src/customer/customer-message-center-durability.integration.spec.ts
pnpm --dir apps/oshun/bff exec vitest run src/messaging-channels/channel-bindings-store.test.ts
OSHUN_ADMIN_DATABASE_URL=postgres://… pnpm --dir apps/oshun/bff exec vitest run -c vitest.integration.config.ts src/messaging-channels/channel-bindings-durability.integration.spec.ts
pnpm --dir apps/oshun/bff exec vitest run src/telegram/user-state-durability.spec.ts
OSHUN_ADMIN_DATABASE_URL=postgres://… pnpm --dir apps/oshun/bff exec vitest run -c vitest.integration.config.ts src/telegram/user-state-durability.integration.spec.ts
```

Retain the commit, environment mode, storage tier, generated customer and admin
subjects, browser/BFF reports, binding and reminder snapshots, preference
snapshots before and after process restart, erasure-fence read-back, and delayed
message-center job/export state. Record both Postgres-gate outcomes and profile/
saved-content/session export and erasure read-back, including both Telegram
partitions. A production-grade follow-up must also retain verification-code
provider ids, bound-address equality proof, automatic-worker claim/retry
evidence, provider request/callback ids, consent and suppression read-back,
genuine account step-up, and complete revocation audit evidence.

## Source trail

- [Current journey contract](../journeys/messages-quiet-hours-and-channel-binding.md)
- [Current coverage registry](../journeys/coverage.md)
- [Read-only notification summary](../../apps/oshun/web/src/app/profile/notifications/page.tsx)
- [Mutable notification preferences](../../apps/oshun/web/src/components/profile/NotificationPreferences.tsx)
- [Profile channel-binding rows](../../apps/oshun/web/src/components/profile/ChannelBindingsSection.tsx)
- [Channel-binding routes](../../apps/oshun/bff/src/routes/channel-bindings.ts)
- [Channel-binding snapshot store](../../apps/oshun/bff/src/messaging-channels/channel-bindings-store.ts)
- [Channel-binding durability unit suite](../../apps/oshun/bff/src/messaging-channels/channel-bindings-store.test.ts)
- [Gated real-Postgres channel-binding suite](../../apps/oshun/bff/src/messaging-channels/channel-bindings-durability.integration.spec.ts)
- [Durable device-token boundary](../../apps/oshun/bff/src/routes/device-tokens.ts)
- [Profile erasure composition](../../apps/oshun/bff/src/data-deletion/profile-state-eraser.ts)
- [Session and device-token erasure composition](../../apps/oshun/bff/src/data-deletion/session-state-eraser.ts)
- [Durable notification preferences](../../apps/oshun/bff/src/notifications/preferences-store.ts)
- [Notification durability and erasure unit suite](../../apps/oshun/bff/src/notifications/state-durability.test.ts)
- [Gated real-Postgres notification continuity suite](../../apps/oshun/bff/src/notifications/state-durability.integration.test.ts)
- [Notification-preference routes](../../apps/oshun/bff/src/routes/notifications-preferences.ts)
- [Message-center quiet-hours policy](../../apps/oshun/bff/src/routes/customer-message-center.ts)
- [Durable message-center snapshot and delayed replay](../../apps/oshun/bff/src/customer/customer-message-center-store.ts)
- [Message-center durability unit suite](../../apps/oshun/bff/src/customer/customer-message-center-store-durability.spec.ts)
- [Gated real-Postgres message-center suite](../../apps/oshun/bff/src/customer/customer-message-center-durability.integration.spec.ts)
- [Continuity export collector](../../apps/oshun/bff/src/data-export/bundle-builder.ts)
- [Reminder policy, worker, durable snapshot, and erasure fence](../../apps/oshun/bff/src/reminders/reminders-route.ts)
- [Reminder durability and erasure unit suite](../../apps/oshun/bff/src/reminders/reminders-state-durability.test.ts)
- [Gated real-Postgres reminder continuity suite](../../apps/oshun/bff/src/reminders/reminders-state-durability.integration.test.ts)
- [Account-level reminder continuity eraser](../../apps/oshun/bff/src/data-deletion/continuity-state-eraser.ts)
- Automatic push-selected producers:
  [streak](../../apps/oshun/bff/src/reminders/streak-reminder-producer.ts),
  [Nyx](../../apps/oshun/bff/src/reminders/nyx-reminder-bridge.ts),
  [assignment](../../apps/oshun/bff/src/reminders/assignment-reminder-producer.ts),
  [session](../../apps/oshun/bff/src/reminders/session-reminder-producer.ts),
  and
  [content drop](../../apps/oshun/bff/src/reminders/content-drop-reminder-producer.ts)
- [Credential-gated provider router](../../libs/oshun/messaging-channels/src/provider-config-env.ts)
- [Telegram HMAC routes](../../apps/oshun/bff/src/routes/telegram.ts)
- [Durable Telegram user-state store](../../apps/oshun/bff/src/telegram/user-state-store.ts)
- [Telegram durability unit suite](../../apps/oshun/bff/src/telegram/user-state-durability.spec.ts)
- [Gated real-Postgres Telegram suite](../../apps/oshun/bff/src/telegram/user-state-durability.integration.spec.ts)
- [Profile summary browser spec](../../apps/oshun/web/e2e/profile-notifications-index.spec.ts)
- [Profile preference browser spec](../../apps/oshun/web/e2e/profile-notification-preferences.spec.ts)
- [Preference API spec](../../apps/oshun/web/e2e/notifications-preferences-api.spec.ts)
- [Channel-binding browser spec](../../apps/oshun/web/e2e/profile-channel-bindings.spec.ts)
- [Telegram binding BFF spec](../../apps/oshun/web/e2e/telegram-binding-bff.spec.ts)
- [Telegram webhook BFF spec](../../apps/oshun/web/e2e/telegram-webhook-delivery.spec.ts)
- [Message-center BFF spec](../../apps/oshun/web/e2e/messages-center-bff.spec.ts)

## Cross-references

- [Profile view evidence](../customer/09-account/profile.md)
- [Read-only profile notification evidence](../customer/09-account/profile-notifications.md)
- [Shell notification evidence](../shell/05-notifications.md)
- [Messages center journey](../journeys/messages-center-deliver-and-unsubscribe.md)
- [Messages center result](./messages-center-deliver-and-unsubscribe.md)
- [Telegram assistant-delivery journey](../journeys/telegram-bot-assistant-delivery.md)
- [Telegram assistant-delivery result](./telegram-bot-assistant-delivery.md)
- [Current Docs Center coverage audit](../../DOCS_CENTER_PAGE_AUDIT_2026-07-16.md)

## Open questions

- Which provider adapters will deliver binding codes, retain attempt-safe
  provider ids, and surface retryable versus permanent failures without ever
  returning a plaintext production code?
- Which transaction, coordinator, or convergence rule will make the durable
  master flag and durable window/domain/persona snapshot one atomic customer
  intent across two routes and stores?
- Which scheduler will durably claim delayed messages, re-evaluate crisis and
  preference policy, retry idempotently, and acknowledge only after a durable
  transition?
- Which leader-election or claim protocol will make the durable reminder worker
  safe across multiple BFF instances rather than one designated process?
- Should automatic reminder producers select a verified email/SMS/WhatsApp
  binding when push is unavailable, and how will tenant allowlists, explicit
  opt-ins, cost, residency, and fallback order govern that choice?
- How will manual schedules prove their recipient equals the verified binding
  rather than accepting an unrelated address for the same channel?
- Which primary-credential challenge will replace the public revoke phrase, and
  which services must participate in a verifiable revocation cascade?
- Should Telegram Login Widget identity, authenticated account deep-linking,
  Mini App sessions, bot suppression, and profile channel inventory converge on
  one explicit account-binding model or remain separate products?
- Which retained provider and restart run will promote this result from deep
  control-plane coverage to an end-to-end delivery grade?
