feat(mobile): push notifications MVP - #6269
Draft
brow wants to merge 24 commits into
Draft
Conversation
Signed-off-by: Tom Brow <tomb@squareup.com>
brow
force-pushed
the
codex/ios-push-internal
branch
from
August 18, 2026 23:25
c7a089a to
d69b89c
Compare
Signed-off-by: Tom Brow <tomb@block.xyz>
…ifications-pr * origin/main: (33 commits) fix(hooks): scope pre-push lanes to branch merge-base diff (#6423) Enforce a three-day dependency cooldown (#6426) perf(desktop): resolve references without directory scans (#6328) feat(llm): stamp thinking effort on call-completed log line (#6424) Fix cross-owner relay agent mentions in owner-only builds (#6338) feat(cli): accept Buzz message links for thread reads (#6359) feat(workflows): add workflow editor (#6248) fix(desktop): preserve huddle speech boundaries (#6397) test(desktop): use a wordlist-safe separator in passphrase word-count test (#6356) fix(models): curate Databricks alias-aware labels for 5 missing endpoints (#6360) fix(acp): guard against unrequested public relay skills (#6394) feat(desktop): refine context-aware Projects collaboration (#6396) fix(desktop): distinguish duplicate agent devices (#6337) feat(desktop): close Buzz window with Cmd+W (#6314) refactor(prompt): simplify Buzz agent guidance (#6340) feat(desktop): make Projects workspaces selectable (#6368) Add Buzz-native collaboration benchmarks (#6264) Polish mobile timeline and emoji interactions (#6297) feat(desktop): make the Projects overview follow the selected section (#6335) refactor(desktop): coordinate TTS playback (#6341) ... Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
|
Independent validation on 2026-08-20:
Operational blockers before dogfood E2E:
No merge, deployment, credential change, or TestFlight release was performed. |
|
Owner handoff for the validated blockers:
Please keep APNs/App Attest credentials out of GitHub comments, manifests, logs, and Buzz. |
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
…ifications-pr * origin/main: (38 commits) fix(composer): preserve caret when inserting mentions mid-message (#6531) chore(deps): update rust crate async-trait to v0.1.92 (#6094) chore(deps): update dependency sonner to v2.0.8 (#6093) chore(deps): update rust crate http-body-util to v0.1.4 (#5452) chore(deps): update rust crate http to v1.4.2 (#5451) chore(deps): update rust crate futures-util to v0.3.33 (#5448) chore(deps): update rust crate futures to v0.3.33 (#5445) chore(deps): update dependency @tauri-apps/api to v2.11.1 (#5444) chore(deps): update ubuntu:24.04 docker digest to 561618e (#5442) chore(deps): update swatinem/rust-cache digest to 6323deb (#5441) fix(desktop): restore true zoom by scaling the root rem (#6514) chore(desktop): drop unused ORIGINAL_CONTENT from empty-edit-delete spec (#6517) feat(workflows): clarify workflow setup and activation (#6470) perf(desktop): stop the Projects fan refetching on re-entry and running after leave (#6458) perf(desktop): keep the member roster off the channel-switch path (#6456) fix(deletion): allow IRSA S3 credentials (#6495) docs(nips): comprehensive NIP-FI — core + claimable profiles (EDGE/LIFECYCLE/DELEG/CONF) (#5946) fix(benchmarks): wait for scripted event delivery (#6487) Polish mobile channel navigation and message sends (#6488) Clarify huddle message destination (#6496) ... Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
…ifications-pr * origin/main: fix(desktop): emit singular `mention` feed category so alerts route correctly (#6665) fix(mobile): recover stale and shuffled messages (#6691) feat(mobile): browse and join open channels (#6243) show mention counts in channel notifications (#6696) fix(desktop): hide selection formatting tray on composer right-click (#6683) fix(desktop): stabilize members dialog scrolling (#6670) fix(desktop): keep member runtime status off the UI thread (#6445) perf(desktop): persist channel heads, collapse thread reads and reply sends (#6572) Downgrade desktop Huddles to audio protocol v2 (#6610) Polish Huddle participant interactions (#6312) Downgrade mobile Huddles to audio protocol v2 (#6558) perf(desktop): make the Projects surface render-cheap (#6460) refactor(acp): clarify agent prompt sections (#6501) Add mobile Huddles voice MVP (#6056) feat(desktop-messages): keep agents addressed across messages (#6315) fix(desktop): remove Buzz entity link previews (#6512) Signed-off-by: Tom Brow <tomb@block.xyz> # Conflicts: # mobile/lib/features/channels/channels_provider.dart # mobile/lib/shared/auth/auth_provider.dart # mobile/lib/shared/community/community_provider.dart # mobile/test/shared/auth/auth_provider_test.dart # mobile/test/shared/community/community_provider_test.dart # scripts/mobile-worktree-overrides.sh
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
…ifications-pr * origin/main: Centralize replaceable event persistence (#6660) feat(workflows): discover trigger filter values (#6712) feat(desktop): simplify the message action rail (#6529) fix(desktop): restore icon-only remote marker (#6491) fix(ci): prevent poisoned Rust caches (#6618) docs(security): route reports through private advisories (#6728) fix(composer): wrap Buzz chip labels without orphaning icons (#6581) fix(desktop): bound thread /query and surface load errors, not false-empty (#6447) Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: Tom Brow <tomb@block.xyz> Co-authored-by: Codex <noreply@openai.com> Ai-assisted: true
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR implements MVP, iOS-only, NIP-PL-compliant push notifications.
A relay with
BUZZ_PUSH_ENABLEDwill send a push notification for any message that appears in the in-app Notifications tab.Enablement and configuration
Enrollment flow
The first time the client first connects to a relay with
BUZZ_PUSH_ENABLED:sequenceDiagram autonumber participant App as Buzz iOS app participant iOS participant Relay as Buzz relay participant Attest as Apple App Attest participant Gateway as Push gateway App->>Relay: Fetch NIP-11 push capability Relay-->>App: Push profile, current relay public key, and limits par App->>iOS: Request notification permission iOS-->>App: Permission result and App->>iOS: Register for remote notifications iOS-->>App: Device token end App->>Gateway: Request installation challenge Gateway-->>App: Single-use challenge App->>Attest: Attest installation transcript Attest-->>App: Attestation proof App->>Gateway: Enroll device token and proof Gateway-->>App: Installation handle App->>Gateway: Request delegation challenge Gateway-->>App: Single-use challenge App->>Attest: Assert relay-key delegation Attest-->>App: Assertion App->>Gateway: Create delegation Gateway-->>App: Opaque endpoint grant App->>Relay: Publish encrypted push lease and filters Relay-->>App: Lease acknowledgedPush-time flow
relay → push gateway → APNs -> NSE -> Notification Center
Privacy characteristics
Known limitations
The APNs wake payload is intentionally constant and opaque: it contains no originating community or message identifier, in keeping with the implemented NIP-PL privacy design.
The Notification Service Extension must therefore reconnect to the relay and resolve eligible messages after each wake. Around overlapping wakes, timing boundaries, or resolution windows, notification presentation may occasionally omit an expected message or display a message more than once.
This best-effort behavior is deliberately accepted for the current implementation and will be measured during the internal rollout to determine whether the user experience is acceptable before any broader deployment; the implementation does not claim exactly-once presentation.
Summary
Add the relay-controlled iOS push notification MVP. This refreshes the end-to-end work from #2744 onto current
main, retains only the best-effort delivery behavior needed from #3347, and includes exact-message notification routing from #6159. Lossless catch-up remains deferred. The earlier drafts remain unchanged for comparison.Rollout authority lives on the relay.
BUZZ_PUSH_ENABLEDdefaults tofalse; only explicitly enabled relay deployments advertise a valid push capability and participate in push delivery.What changed
push.buzz.xyzgateway. A verified App Attest application ID selects the APNs topic, certificate identity, connection pool, and environment. The client cannot select an APNs topic.BUZZ_PUSH_ENABLED, defaulting tofalse, as the relay deployment gate. NIP-11 advertisement, lease acceptance, matching, workers, and gateway delivery all require the gate.nip-pldescriptor as its sole activation signal.9,40002,45001, and45003, using the Notifications-tab message eligibility rules.Rollout and rollback
Rollout remains internal-only:
BUZZ_PUSH_ENABLED=trueonly on selected internal relay deployments.Every signed iOS artifact now includes the app push entitlements and embedded Notification Service Extension. The private release configuration must sign the application and extension with their separate provisioning profiles and map both bundle identifiers during export.
To roll back, set
BUZZ_PUSH_ENABLED=falseon relays. They stop advertising push, accepting leases, matching events, running workers, and sending deliveries. Clients connected to a relay without a valid capability remain inactive.Server metrics cover enrollment, delegation, lease acceptance, match and delivery outcomes, APNs status, queue age, and delivery latency. NSE resolution outcomes and exact-message versus channel-fallback taps are manually counted during dogfood validation until privacy-preserving client telemetry is designed.
Validation
The prior development-stack hardware demo proved real sandbox APNs delivery and visibly fetched, signature-verified notification content on an iPhone 12 mini using the normal mobile development identity. Exact-message routing is covered by the refreshed implementation and tests. Signed dogfood-artifact validation, including a manual notification tap into the intended message, is the next release-validation step after the change reaches
mainand an immutable internal candidate reaches Mobile Releases/Comp Portal.Provisioning note
This change adds the
aps-environment, App Attest, application-group, keychain-access-group, and Communication Notifications requirements. Before the first internal candidate, the private release configuration must provide the application and Notification Service Extension identifiers, capabilities, and separate provisioning profiles. Local dogfood signing is intentionally not a merge blocker for this source PR.