Notifications: opt-in architecture (shared enable flag, manager autostart, liveness) + evidence-based defaults

Author: ErikBjareCreated Sep 8, 2026Updated Sep 8, 2026

Problem

The notifications settings panel (AwNotifySettings, shared thresholds for Android/desktop) is now reachable (ActivityWatch/aw-webui#972 fixed the 404), but on default desktop installs it is silently inert: neither aw-qt nor aw-tauri autostarts aw-notify by default, so thresholds get saved to /0/settings/aw-notify and nothing consumes them. Android is the opposite: NotifyWorker runs by default with baked-in alerts. Users have also reported not being able to turn the module on at all (#1175).

Product stance (Erik): notifications must be opt-in — but with excellent opt-in defaults, grounded in the intervention/nudging literature (positive reward framing over limit-nagging, timing at natural breakpoints, habituation avoidance), plus user-facing guidance on using them effectively. A research pass to derive those defaults is running separately and will be linked here.

Design

1. Opt-in flag in the shared settings key. enabled: false by default in /0/settings/aw-notify — single source of truth for all platforms. Android's NotifyWorker honors the same flag (today it defaults on; unify to opt-in with a migration note).

2. Managers read the flag at startup and start aw-notify iff enabled. This is a one-directional manager→server read after server-up (managers already start/probe the server; no module management enters the server).

3. Tray toggle for immediacy. aw-qt/aw-tauri get an "Enable notifications" tray item that writes the flag AND starts/stops the module immediately. The webui toggle alone takes effect on next launch; the tray covers "I want it now". No webui→manager channel is introduced.

4. Liveness without manager coupling. aw-notify sends a periodic heartbeat to its own bucket (aw-notify_<host>). The settings panel derives "running / not running (how to enable)" from bucket freshness — server-data-only, works on every surface including remote/Android.

5. Module management stays OUT of the webui/server. The server remains pure storage/query; process control stays with the managers. (If module control ever needs a remote surface it should be a manager-owned endpoint — out of scope here.)

6. Target aw-notify-rs. Python aw-notify is deprecated (ActivityWatch/aw-notify#16); the enable-flag + heartbeat work lands in aw-notify-rs (which already reads the shared settings API, ActivityWatch/aw-notify-rs#38). This also makes an always-run-silent fallback viable later if wanted, but the opt-in autostart design above doesn't need it.

Evidence-based defaults (separate deliverable, feeds this issue)

  • Default alert set + thresholds + timing rules with citations (JITAI, notification-fatigue/habituation, framing effects, implementation intentions)
  • User-facing doc: how to use notifications for reward/nudging effectively; linked from the settings panel
  • Ties into the existing reward-framing direction: achievements/streaks (ActivityWatch/aw-android#205), anomaly-detection alerts (ActivityWatch/aw-android#200)

Prior work

  • ActivityWatch/aw-android#201 (shared settingsStore + webui config surface — the panel this builds on)
  • ActivityWatch/aw-android#196 (Android aw-notify support)
  • ActivityWatch/aw-notify-rs#38 (shared config via settings API)
  • ActivityWatch/aw-notify#8 (user demand for configurable category prompts)
  • #1175 (module cannot be toggled on — the UX gap this closes)

Rough scope by repo

Repo Work
aw-notify-rs honor enabled flag; heartbeat bucket
aw-qt / aw-tauri read flag at startup; tray toggle (write flag + start/stop)
aw-webui enable toggle in panel; liveness display from bucket freshness; link usage doc
aw-android honor shared enabled flag (migrate from default-on)
docs user guidance page from the research deliverable

Source: ActivityWatch/activitywatch