Notifications & Nudges
Notifications & Updates Intelligence
Three separable fixes from an on-device review: honest session counts, device-local push suppression/collapse, and a resolve action for Updates.
Situation
An on-device review of the live notification + Updates experience surfaced three issues: the EOD wrap stated a confident-but-wrong "177 conversations" (actually a raw, inflated event count); proactive pushes fire for every surfaced item and stack repetitively even when the item is already visible on-screen; and Updates items can never be cleared once handled. Three separable tracks, each its own PR, build order T1 → T2 → T3.
T1 fixes a live trust bug (Worker-only, smallest); T2 kills daily push noise via per-device foreground suppression and collapsing repeat batches; T3 adds a manual, purely subtractive resolve action plus tighter, resolve-aware retention.
Key decisions
Count sessions, not events
"Conversations" becomes countSessions over today's feed message timestamps (new session after a >30min gap) plus discrete task_sessions — never a raw interactionCount of logged events.
Busyness from edge-countable signals, not chat volume
Mentions handled, digs run, and session counts feed the teaser as labelled facts; calendar meeting-hours is flagged as the strongest signal but deferred — parsing agenda prose is explicitly rejected as fragile.
Device-local push suppression, not global focus-tracking
Each device decides for itself whether to show a push based on its own foreground state (web SW clients.matchAll, Android ProcessLifecycleOwner) — so a focused desktop never silences the phone and vice versa.
Collapsing batch notifications
Batch pushes get a fixed tag/collapse_key so a new "awaiting you" replaces the prior one instead of stacking, and titles lead with the most urgent item/people instead of a bare count.
Resolve is purely subtractive
A manual per-item resolve marks an Updates item strikethrough-and-greyed in place; it never creates a tracked task, keeping Updates a triage surface rather than a to-do list.
Retention tightens and becomes resolve-aware
Resolved items are kept 24h then dropped; unresolved items are now kept only 3 days (a change from the prior indefinite retention) — implemented as a single pruneUpdates predicate in the EOD decay tick.
Architecture
Two Worker-side session-counting helpers fix the accuracy bug; per-device foreground checks and a collapse key fix the noise; a resolved_at column and prune rewrite fix retention.
interactionCount data line.clients.matchAll({type:'window'}) check — skips showNotification when a focused/visible client already exists.ProcessLifecycleOwner suppresses the system notification when the app is already in foreground.resolved_at on an Updates row (migration-added column).Risks & guardrails
Trust erosion from wrong counts
The "177 conversations" bug is a confident-but-wrong statement, which is worse than an admitted unknown — this is the reason T1 ships first despite being the smallest change.
Device-local suppression could under- or over-suppress
Guarded by scoping the foreground check to each device independently rather than a shared/global state, so no single device's focus silences another's notification.
Retention tightening loses data
Unresolved items dropping from indefinite to 3 days is called out explicitly as a behaviour change, not just a bugfix — worth flagging before it ships.
Collapse could hide a genuinely new urgent item
Mitigated by the informative-title change (leads with the most urgent item/person) so a collapsed notification still surfaces what's new, not just a stale count.
Delivery
T1 — EOD/briefing accuracy
Worker-only: session-counting helpers replace the raw event count; ships first as the smallest fix to a live trust bug.
T2 — Notification intelligence
Worker batchDigest title change + web service-worker foreground check + Android foreground-suppression service; kills daily push noise.
T3 — Updates resolve + retention
Migration adds resolved_at; POST /updates/resolve route; web resolve UI; EOD decay tick reworked to resolve-aware retention.
Out of scope
docs/superpowers/specs/2026-06-16-notifications-updates-intelligence-design.md