Notification copy that honours the three privacy modes #24

Closed
opened 2026-08-18 15:06:56 -05:00 by null · 0 comments
Owner

Nothing sends a notification yet. NotificationPrivacy is stored, defaults to DISCREET, and is chosen during onboarding — and no code has ever read it.

PRODUCT_PLAN.md §28 gives three modes and, for each, what may appear on a lock screen versus inside the app:

Mode Lock screen Inside
Discreet (default) "Quick check-in — Something may be coming up." "Your period is likely in about 2 days."
Maximum privacy "Reminder" — no health information at all same
Direct "Your period may start in 2 days." same

Build the copy selection as a pure function — privacy mode plus notification kind plus the day count in, title/text/visibility out — so it is testable without an emulator and without Robolectric. That matters more here than anywhere else in the app: this is the one surface where a mistake is visible to somebody who is not the user.

The traps:

  • Android's lock-screen behaviour is visibility on the notification, and VISIBILITY_PRIVATE shows the public version of the notification, which you must supply. Setting the private text and forgetting setPublicVersion leaks the private text.
  • A heads-up notification shows its content over whatever is on screen. High importance plus Discreet mode is a contradiction.
  • The channel name itself appears in system settings and in some surfaces — "Period reminders" is a leak in a way "Reminders" is not.

Verify: a pure unit test asserts that for every notification kind, the lock-screen text in Discreet and Maximum privacy contains none of the words "period", "fertile", "ovulation" or "cycle", and that Direct is the only mode that does; plus a test that every kind supplies a public version.

Nothing sends a notification yet. `NotificationPrivacy` is stored, defaults to `DISCREET`, and is chosen during onboarding — and no code has ever read it. PRODUCT_PLAN.md §28 gives three modes and, for each, what may appear on a **lock screen** versus inside the app: | Mode | Lock screen | Inside | | --- | --- | --- | | Discreet (default) | "Quick check-in — Something may be coming up." | "Your period is likely in about 2 days." | | Maximum privacy | "Reminder" — no health information at all | same | | Direct | "Your period may start in 2 days." | same | Build the copy selection as a **pure function** — privacy mode plus notification kind plus the day count in, title/text/visibility out — so it is testable without an emulator and without Robolectric. That matters more here than anywhere else in the app: this is the one surface where a mistake is visible to somebody who is not the user. The traps: - Android's lock-screen behaviour is `visibility` on the notification, and `VISIBILITY_PRIVATE` shows the **public version** of the notification, which you must supply. Setting the private text and forgetting `setPublicVersion` leaks the private text. - A heads-up notification shows its content over whatever is on screen. High importance plus Discreet mode is a contradiction. - The channel name itself appears in system settings and in some surfaces — "Period reminders" is a leak in a way "Reminders" is not. Verify: a pure unit test asserts that for every notification kind, the lock-screen text in Discreet and Maximum privacy contains none of the words "period", "fertile", "ovulation" or "cycle", and that Direct is the only mode that does; plus a test that every kind supplies a public version.
null added this to the Batch 05 — Notifications milestone 2026-08-18 15:06:56 -05:00
null closed this issue 2026-08-18 15:27:02 -05:00
Sign in to join this conversation.
No Label
P0
P1
P2
release-blocker
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: null/Privacy-Period-Tracker#24
No description provided.