feat(mobile): push notifications MVP - #6269
Draft
brow wants to merge 1 commit 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
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 adds an MVP, iOS-only version of mobile push notifications.
When a message that would normally badge the in-app Notifications tab arrives in a push-enabled community, Buzz for iOS can show a normal iOS notification with the real message content. Tapping it navigates to the message in Buzz.
The feature is off in normal builds and can be enabled only for internal dogfood builds and explicitly configured relays.
Notifications are delivered best-effort, limited to messages, and not yet enabled for external App Store users.
Summary
Add the dormant-by-default iOS push notification MVP for internal dogfood builds. 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.This PR keeps the external App Store build and relay rollout off. Internal rollout requires both an explicit dogfood build configuration and relay deployment configuration.
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.9,40002,45001, and45003, using the Notifications-tab message eligibility rules.xyz.block.buzz.dogfood.mobile. It embeds the Notification Service Extension, uses App Attest, registers with APNs after permission is granted, enrolls/delegates with the gateway, and publishes relay-scoped leases.Rollout and rollback
Rollout remains internal-only:
mobile/ios/Flutter/PushEnabled.xcconfig.BUZZ_PUSH_ENABLED=trueonly on selected internal relay deployments.The private dogfood release builder must include
PushEnabled.xcconfig, sign the application and Notification Service Extension with their separate provisioning profiles, and map both bundle identifiers during export. The App Store builder does not include the push overlay, so external push remains absent/off.To roll back, set
BUZZ_PUSH_ENABLED=falseon relays. They stop advertising push, accepting leases, matching events, running workers, and sending deliveries. External App Store builds keep the capability absent unless a later change turns it on.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
lefthook run pre-pushcargo clippy -p buzz-push-gateway -p buzz-relay -p buzz-db --all-targets --all-features -- -D warningsswift test --package-path mobile/ios/BuzzPushKit— 51 XCTest cases and 3 Swift Testing casesswift build -c release --package-path mobile/ios/BuzzPushKitjust mobile-checkpython3 scripts/test-ios-pbxproj-semantics.pydeploy/charts/buzz-push-gateway/tests/render.shdeploy/charts/buzz-push-gateway/tests/release-contract.shxyz.block.buzz.dogfood.mobilewithxyz.block.buzz.dogfood.mobile.NotificationServiceembeddedThe repository-wide
just cigate passes, including Rust, desktop, web, and mobile checks, tests, and builds.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, and keychain-access-group entitlements. Before the first push-enabled dogfood candidate, the private release configuration must provide the app and Notification Service Extension identifiers, capabilities, and separate provisioning profiles; local dogfood signing is intentionally not a merge blocker for this source PR.