From ce0fef286e2d07d48a917199a2f37ee1850d8e66 Mon Sep 17 00:00:00 2001 From: Robert Sindall <55975851+rsindall@users.noreply.github.com> Date: Sun, 20 Sep 2026 10:49:44 +0100 Subject: [PATCH 1/3] adr: Web Push for agent attention Propose optional first-party Web Push for existing needs-attention moments so operators without a chat bridge still get a lock-screen ping. --- adrs/web-push-needs-attention.md | 46 ++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 adrs/web-push-needs-attention.md diff --git a/adrs/web-push-needs-attention.md b/adrs/web-push-needs-attention.md new file mode 100644 index 0000000000..06c9e68ab9 --- /dev/null +++ b/adrs/web-push-needs-attention.md @@ -0,0 +1,46 @@ +# Web Push for agent attention + +QM already tells you in the browser when an agent is waiting, but the page has to be open. On a phone, with Slack or other chat bridges turned off, there is no OS-level ping when an agent stops or needs an answer. This ADR proposes first-party Web Push so the same "needs attention" moments can reach the device lock screen without a third-party chat bot. + +## Decision + +Add optional Web Push delivery for attention events that already exist in the product (agent waiting on the user, hard stop / failure that needs a human). Keep chat connectors for teams that want them; Web Push is the built-in path for operators who use the web UI as the primary surface. + +## Context + +- Mobile browsers (notably Chrome on Android) support the Push API and service workers; iOS Safari support exists with constraints but is improving. +- Push payloads must stay small and non-sensitive: title + short body + deep link into the relevant session. No prompts, secrets, or tool output in the notification body. +- Subscriptions are per browser / device and tied to a signed-in user. Revoking access or logging out should drop subscriptions. +- Delivery is best-effort. Failed endpoints get pruned; the in-app attention UI remains the source of truth. + +## Proposed shape + +1. **Service worker** in the web app registers for push and shows a notification that opens the matching session URL. +2. **Subscription store** on the core: endpoint + keys per user/device, created after an explicit "enable notifications" affordance (permission prompt is user-initiated). +3. **VAPID** keys configured on the deployment (`WEB_PUSH_VAPID_PUBLIC_KEY` / `WEB_PUSH_VAPID_PRIVATE_KEY`, or equivalent). Public key is exposed to the client for `pushManager.subscribe`; private key stays server-side. +4. **Trigger points** reuse existing attention signals (for example: agent status moves to waiting / needs input / failed). Do not invent a parallel event bus only for push. +5. **Prefs**: per-user toggle for push on/off; optional quiet hours later if operators ask. Default off until the user opts in. + +## Out of scope (this ADR) + +- Replacing Slack, email, or other connectors. +- Rich media, action buttons that mutate agent state from the notification, or pushing full agent transcripts. +- Guaranteeing delivery on every OS / browser combination on day one (document supported surfaces in the feature notes). + +## Alternatives considered + +- **Keep chat bridges only.** Works for orgs that want Slack; fails for operators who deliberately run without chat and still need a lock-screen ping. +- **Email on attention.** Higher latency and noise; poor fit for "answer now" moments. +- **Native mobile apps.** Heavier; Web Push gets most of the value inside the existing PWA / mobile web surface. + +## Success criteria + +- After opt-in on a supported browser, a controlled "needs attention" event produces a lock-screen (or system) notification that deep-links to the session. +- No sensitive content in the payload beyond what the in-app attention chip already shows. +- Opt-out and logout clear subscriptions; invalid endpoints are removed without operator intervention. + +## Open questions for implementers + +- Exact list of attention statuses that fire push (waiting vs failed vs both). +- Whether multi-device users get one notification per subscription or a single "already notified" coalescing window. +- iOS install / home-screen requirements to document for operators. \ No newline at end of file From 0f28ab4079b72206e8d1a8417f5292d877274993 Mon Sep 17 00:00:00 2001 From: Robert Sindall <55975851+rsindall@users.noreply.github.com> Date: Sun, 20 Sep 2026 10:53:16 +0100 Subject: [PATCH 2/3] adr: shorten Web Push pitch to informal CONTRIBUTING style --- adrs/web-push-needs-attention.md | 47 ++++---------------------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/adrs/web-push-needs-attention.md b/adrs/web-push-needs-attention.md index 06c9e68ab9..1ca29546e1 100644 --- a/adrs/web-push-needs-attention.md +++ b/adrs/web-push-needs-attention.md @@ -1,46 +1,9 @@ -# Web Push for agent attention +# Web Push when an agent needs you -QM already tells you in the browser when an agent is waiting, but the page has to be open. On a phone, with Slack or other chat bridges turned off, there is no OS-level ping when an agent stops or needs an answer. This ADR proposes first-party Web Push so the same "needs attention" moments can reach the device lock screen without a third-party chat bot. +QM already shows "needs attention" in the browser, but that only helps if the tab is open. With chat bridges turned off, there's no lock-screen ping when an agent stops or is waiting on an answer. -## Decision +Ask: add optional first-party Web Push for those existing attention moments. Opt-in only. Small payload (title, short body, deep link into the session). No prompts, secrets, or tool output in the notification. Reuse the attention signals you already have; don't invent a parallel event bus. VAPID keys as deploy config. Chat connectors stay for teams that want them; this is for people who live in the web UI. -Add optional Web Push delivery for attention events that already exist in the product (agent waiting on the user, hard stop / failure that needs a human). Keep chat connectors for teams that want them; Web Push is the built-in path for operators who use the web UI as the primary surface. +Out of scope for now: replacing Slack/email, rich media, action buttons that mutate agent state, pushing transcripts, or promising every OS/browser on day one. -## Context - -- Mobile browsers (notably Chrome on Android) support the Push API and service workers; iOS Safari support exists with constraints but is improving. -- Push payloads must stay small and non-sensitive: title + short body + deep link into the relevant session. No prompts, secrets, or tool output in the notification body. -- Subscriptions are per browser / device and tied to a signed-in user. Revoking access or logging out should drop subscriptions. -- Delivery is best-effort. Failed endpoints get pruned; the in-app attention UI remains the source of truth. - -## Proposed shape - -1. **Service worker** in the web app registers for push and shows a notification that opens the matching session URL. -2. **Subscription store** on the core: endpoint + keys per user/device, created after an explicit "enable notifications" affordance (permission prompt is user-initiated). -3. **VAPID** keys configured on the deployment (`WEB_PUSH_VAPID_PUBLIC_KEY` / `WEB_PUSH_VAPID_PRIVATE_KEY`, or equivalent). Public key is exposed to the client for `pushManager.subscribe`; private key stays server-side. -4. **Trigger points** reuse existing attention signals (for example: agent status moves to waiting / needs input / failed). Do not invent a parallel event bus only for push. -5. **Prefs**: per-user toggle for push on/off; optional quiet hours later if operators ask. Default off until the user opts in. - -## Out of scope (this ADR) - -- Replacing Slack, email, or other connectors. -- Rich media, action buttons that mutate agent state from the notification, or pushing full agent transcripts. -- Guaranteeing delivery on every OS / browser combination on day one (document supported surfaces in the feature notes). - -## Alternatives considered - -- **Keep chat bridges only.** Works for orgs that want Slack; fails for operators who deliberately run without chat and still need a lock-screen ping. -- **Email on attention.** Higher latency and noise; poor fit for "answer now" moments. -- **Native mobile apps.** Heavier; Web Push gets most of the value inside the existing PWA / mobile web surface. - -## Success criteria - -- After opt-in on a supported browser, a controlled "needs attention" event produces a lock-screen (or system) notification that deep-links to the session. -- No sensitive content in the payload beyond what the in-app attention chip already shows. -- Opt-out and logout clear subscriptions; invalid endpoints are removed without operator intervention. - -## Open questions for implementers - -- Exact list of attention statuses that fire push (waiting vs failed vs both). -- Whether multi-device users get one notification per subscription or a single "already notified" coalescing window. -- iOS install / home-screen requirements to document for operators. \ No newline at end of file +If you're aligned, happy for you to implement. Open calls on your side: which statuses fire (waiting vs failed vs both), multi-device coalescing, and what to document for iOS home-screen install. From f5491727db004e1dc175093270efa11bbc658fd0 Mon Sep 17 00:00:00 2001 From: Robert Sindall <55975851+rsindall@users.noreply.github.com> Date: Sun, 20 Sep 2026 10:57:10 +0100 Subject: [PATCH 3/3] adr: match upstream pitch style for Web Push note --- adrs/web-push-needs-attention.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/adrs/web-push-needs-attention.md b/adrs/web-push-needs-attention.md index 1ca29546e1..0871d4b592 100644 --- a/adrs/web-push-needs-attention.md +++ b/adrs/web-push-needs-attention.md @@ -2,8 +2,8 @@ QM already shows "needs attention" in the browser, but that only helps if the tab is open. With chat bridges turned off, there's no lock-screen ping when an agent stops or is waiting on an answer. -Ask: add optional first-party Web Push for those existing attention moments. Opt-in only. Small payload (title, short body, deep link into the session). No prompts, secrets, or tool output in the notification. Reuse the attention signals you already have; don't invent a parallel event bus. VAPID keys as deploy config. Chat connectors stay for teams that want them; this is for people who live in the web UI. +I'd like optional first-party Web Push for those existing attention moments. Opt-in only. Small payload: title, short body, deep link into the session. No prompts, secrets, or tool output in the notification. Reuse the attention signals you already have rather than inventing a parallel event bus. VAPID keys as deploy config. Chat connectors stay for teams that want them; this is for people who live in the web UI. -Out of scope for now: replacing Slack/email, rich media, action buttons that mutate agent state, pushing transcripts, or promising every OS/browser on day one. +What I'm not asking for: replacing Slack or email, rich media, action buttons that mutate agent state, pushing transcripts, or promising every OS and browser on day one. -If you're aligned, happy for you to implement. Open calls on your side: which statuses fire (waiting vs failed vs both), multi-device coalescing, and what to document for iOS home-screen install. +Open calls if you're aligned: which statuses should fire (waiting vs failed vs both), whether multi-device users get one notification per subscription or a short coalescing window, and what to document for iOS home-screen install. Happy for you to implement once the direction looks right.