| OS permission dialog on first launch | Just-in-time asks tied to user actions |
| Firing the OS dialog with no priming (push, location) | Soft-ask screen first; escalate only on "yes" |
| Soft-prompt refusal labeled "No" / "Don't allow" | "Not now" — soft, honest, re-askable |
| Re-priming every session after "Not now" | Cap 2–3, spaced days apart, new benefit each time |
| "Enable notifications to continue" wall | Never gate core features on non-essential permissions |
| Promo pushes through the transactional channel | Strict category separation; promo is opt-in |
| "We miss you 😢" content-free win-backs | Reference the user's own state (streak, draft, activity) or send nothing |
| One master notification toggle | Per-category preference center + digest options |
| Ignoring quiet hours / timezones | Local quiet hours on by default for non-urgent sends |
| Denial → silently broken feature | Inline explainer + Settings deep link + fallback channel |
| Asking for contacts/location "for later use" | Ask when the invite/map screen is actually open |
| Requesting "Always" location upfront | "While Using" first; upgrade contextually |
| Badge that never clears | Badge counts actionable items only; clears on view |
| Measuring dialog-grant rate as success | Optimize retained opt-in (still enabled at day 30) |
| Same push to all timezones at HQ time | Send-time per user's local time / inferred active hours |
| Stacking two OS dialogs back-to-back | One permission per moment; the second waits for its own trigger |
| Notification deep-links to the app home screen | Deep-link to the exact item the notification names |
| Preference changes applied client-side only | Honor server-side immediately; a re-sent muted category is spam |