Skip to content

feat(relay): silence mobile notifications while the desktop is focused - #8637

Open
ahalekelly wants to merge 7 commits into
pingdotgg:mainfrom
ahalekelly:skip-push-while-desktop-focused
Open

feat(relay): silence mobile notifications while the desktop is focused#8637
ahalekelly wants to merge 7 commits into
pingdotgg:mainfrom
ahalekelly:skip-push-while-desktop-focused

Conversation

@ahalekelly

@ahalekelly ahalekelly commented Aug 29, 2026

Copy link
Copy Markdown

🤖 Generated by Claude Code

What Changed

Agent-activity publishes carry a signed notify flag, separating "update the phone's state" from "alert the user".

  • RelayAgentActivityPublishRequest and the signed proof payload gain notify: boolean, decoding to true when omitted.
  • The server always publishes state so mobile cards and Live Activities stay current. notify is false while any client is visible and focused and the host is awake and unlocked, from the client-activity leases and host power state BackgroundPolicy already tracks. Focus is global: a user watching the app gets no phone alerts for any thread.
  • The relay verifies notify against the signed proof and, when false, sends Live Activity updates with no alert and skips push notifications entirely.

A state published silently is not re-alerted when focus is later lost; the user saw it on screen.

Compatibility

Desktop/server Relay Result
old new Request and proof omit notify; both decode to true and match, so publishes verify and alert as before (tested in contracts and relay).
new old The old relay's schema drops the unknown key and its proof check ignores it; alerts on every publish, as today.

Mobile is unaffected in every combination: the flag only travels server → relay, and a silent update is a Live Activity update with alert: null, which the app already handles.

Why

Every published completed/failed/waiting_* state becomes a push. When T3 Code is focused on desktop the user is already watching, so the phone buzzing is noise — but the phone's state still has to converge, so the server can't just skip the publish. Without a channel split the alternatives are hold-and-replay (bursts late pushes for work the user already saw; #4747, +847 lines) or dropping publishes (stale cards, lost tombstones).

Related: #780, #4747.

UI Changes

None.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Note

Medium Risk
Changes signed publish verification and APNs delivery semantics for agent awareness; mismatched or tampered notify rejects publishes, but legacy omitting notify still defaults to alerting.

Overview
Agent-activity publishes now carry a signed notify flag so the relay can refresh mobile cards and Live Activities without ringing the phone when the user is already watching on desktop.

The local server still publishes every state change, but AgentAwarenessRelay sets notify to false when BackgroundPolicy.hasFocusedClient sees a visible, focused client and the host is awake and unlocked (not suspended or locked). That value is bound into the JWT proof and HTTP payload. RelayAgentActivityPublishRequest / proof schemas add notify with decode default true when omitted for older publishers.

On the relay, signature verification requires proof and request notify to match. AgentActivityPublisher and ApnsDeliveries honor notify: false by skipping notification-only push fallbacks and sending Live Activity updates/ends with alert: null; no companion push is queued on end. Updates published silently while focused are not re-alerted when focus is lost later.

Reviewed by Cursor Bugbot for commit ba72b28. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Silence mobile push notifications while a desktop client is focused

  • Adds hasFocusedClient(snapshot) to BackgroundPolicy to detect a visible, focused client while the host is awake and unlocked
  • AgentAwarenessRelay.make computes notify = !hasFocusedClient(...) and includes it in the signed publish proof and relay payload
  • AgentActivityPublisher and ApnsDeliveries honor notify=false by suppressing push notification alerts while still updating Live Activities
  • Adds notify boolean to RelayAgentActivityPublishProofPayload and RelayAgentActivityPublishRequest schemas, defaulting to true for legacy decodes
  • EnvironmentPublishSignatures.verify rejects requests where the signed proof notify does not match the request notify
  • Risk: old clients that omit notify default to true (no behavior change), but any mismatch between proof and request notify is now rejected — verify callers in Api.ts always forward the same value

Macroscope summarized ba72b28.

…used

State is always published so mobile cards and Live Activities stay current. The notify field tells the relay whether to alert, and is false while a desktop client is visible and focused, derived from the client-activity leases already reported to BackgroundPolicy.
@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a995f562-0519-466e-8d61-55e34a3df4e0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Aug 29, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7f8c2f8. Configure here.

Comment thread packages/contracts/src/relay.ts
@macroscopeapp

macroscopeapp Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a cross-service, user-visible policy that automatically changes mobile push and Live Activity alert behavior based on desktop focus and host state. It is backward compatible at the protocol level and well tested, but the production blast radius and automatic notification gate warrant human review.

You can add or adjust custom eligibility rules. Learn more.

ahalekelly and others added 3 commits August 29, 2026 11:47
Servers built before the field existed keep publishing to the relay; their updates alert as they always did.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ahalekelly
ahalekelly force-pushed the skip-push-while-desktop-focused branch from c765b8f to 749b285 Compare August 29, 2026 19:13
@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Aug 29, 2026
Remove the hasFocusedClient branch enumeration, the schema-default test
duplicated by the signature compat test, and the notify pass-through
assertions in AgentActivityPublisher. Share the waiting fixture in
ApnsDeliveries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ahalekelly ahalekelly changed the title feat(relay): publish agent activity silently while the desktop is focused feat(relay): silence notifications while the desktop is focused Aug 30, 2026
@ahalekelly ahalekelly changed the title feat(relay): silence notifications while the desktop is focused feat(relay): silence mobile notifications while the desktop is focused Aug 30, 2026
ahalekelly and others added 2 commits August 29, 2026 19:06
Build the notification only when notify is true, so silent publishes do
not parse preferences for a payload they discard, and the single notify
gate covers both the end alert and the companion push. Add a test that a
silent end never enqueues the companion push.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Snapshot leases are already filtered by isLeaseActive at the snapshot's
own instant, so the re-check and its now parameter could never change
the result.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ahalekelly

Copy link
Copy Markdown
Author

Compatibility issues found by the bots are fixed, it passed claude /code-review as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant