Skip to content

feat(ios): add server-originated encrypted push notifications #196

Closed

Description

@ZingerLittleBee

Closure decision (2026-10-17)

Closed under the maintainer-approved reduced acceptance scope. Implementation tickets #197-#204 are complete, and #205 is closed with the ordinary physical-device flows accepted and the remaining live matrix explicitly skipped.

Implementation is merged in #206, with the separate legacy APNs TLS fix in #217 and the automated/Simulator acceptance record in #218. Existing automated evidence is retained below; it was not rerun for this closure.

Physical-device follow-up used the source at 1709ac5cd56ebc97eaf6d47aeae4b36cf7dd56f7, installed in place on an iPhone 17 Pro Max running iOS 27.0. The installed Debug build was 2.0.0 (1), signed for APNs sandbox. Observed checks passed:

  • Existing login and live data continued to work after installation and ordinary relaunch. This establishes observed login continuity, not complete signed content-key upgrade continuity.
  • Phone software-keyboard input, server search, notification registration, disable/re-enable and registration recovery worked.
  • Current-installation synthetic test notifications displayed decrypted content. The app UI reported APNs acceptance; raw APNs HTTP traces were not independently captured.
  • Tapping a foreground banner from Servers switched to Settings. Tapping a banner on Home resumed ServerBee into Settings. The existing Settings navigation page was retained as designed. These were ordinary notification taps, not cold-launch observations.
  • Refreshing test status preserved the accepted result. No duplicate banner was seen during the brief checks; strict exactly-once counting was not measured.

The current-installation notification master switch was restored to its initial disabled state, with all four business-category subscriptions off and system notification permission retained. No confirmed functional defect was found in the exercised paths.

Explicitly skipped acceptance

The maintainer requested simple, commonly reachable checks and explicitly accepted skipping cumbersome or rarely reached scenarios. The remaining full live matrix is not required for this closure. Production APNs, strict foreground duplicate counting and background/terminated arrival timing, cold notification launch, actual business-category delivery/isolation, permission/identity/revocation/fault recovery matrices and complete signed-upgrade key continuity remain unverified. The original unchecked items below are preserved as unrun evidence, not converted into passing checks or treated as outstanding blockers under the reduced scope.

All dated status and verification checkpoints below are historical. This closure decision supersedes their previous OPEN/full-acceptance requirement while preserving their evidence limits.


Historical status (2026-10-16)

OPEN: the implementation is merged, but the full specification is not yet accepted. #206 implemented the encrypted mobile notification pipeline; #217 fixed the separate legacy direct-APNs TLS path; #218 records the latest acceptance checkpoint. Do not infer incomplete implementation solely from old unchecked lists or historical dependency text.

Evidence: implementation merged in #206; acceptance checkpoint merged in #218. Candidate Server CI passed 90 mobile-push integration and 95 mobile-router tests. iOS CI passed 473 tests, zero skipped, including all three actual Rust ciphertext consumers. The unchanged Worker has 73 workerd plus one native ingress test; unchanged bilingual guidance has passing documentation CI. Local zh-Hans verification passed 64/64 and all six native redirect-boundary checks passed. Earlier-SHA Worker/docs results are reused evidence, not a fresh candidate-wide run.

The dedicated ServerBee Worker is deployed. One authorized real APNs sandbox test reached a dedicated Simulator: registration revision 2, persisted Server receipt accepted/Accepted, NSE-decrypted background presentation, and opening the existing notification from a terminated app into Settings. No simctl push injection was used. The system required side-swipe to open; earlier failed harness attempts remain recorded. Initial enqueue and raw APNs HTTP responses were not separately captured; the Server receipt reports the Relay/APNs verdict and still correctly says presentation=unobserved. The dedicated session was revoked and confirmed absent. This is not physical-device or production evidence.

Implementation tracking

Remaining acceptance

Remaining prerequisites: an available unlocked physical iPhone, identified installed build and prior signed-upgrade baseline, development/distribution builds for the respective APNs environments, and an authorized isolated setup for business-event and failure/recovery tests. The prior shared-demo authorization was used for one directed synthetic test with business subscriptions disabled; it is not evidence for those remaining scenarios. No speculative implementation gap is established by these missing observations.

Dated checkpoints below are historical. This status supersedes earlier statements that the Worker is undeployed or that all live APNs checks are unrun; production and physical-device gates remain pending.


Architecture decision update (2026-10-03)

The approved simplification in #206 replaces the initial, unreleased App Attest and stateful-grant design with a public, stateless Cloudflare Workers Relay. The current requirements below supersede that earlier admission design: App Attest, strict app-version/distribution checks, challenges, grant issuance/inspection/renewal/revocation, and Relay SQLite are removed without a replacement authorization system. Server authentication, installation ownership, content-key lifecycle, account isolation, and recipient policy remain required. Implementation is on the #206 branch at 22c828c4517734b0814240ca4bbe751d126ffa3d, with all 17 current PR checks green. Current exact-head evidence is recorded below and in #206; previous validation of the old architecture is historical only. Worker deployment and non-sending configuration-shape checks are verified; APNs signing-key validity, provider acceptance and real signed-device verification remain unverified.

Problem Statement

ServerBee users need timely iPhone notifications when monitored Servers raise or recover from alerts, security rules match, or scheduled tasks finish with problems. Browser and WebSocket updates are insufficient while the iOS app is backgrounded or not running.

At the original investigation, ServerBee had partial APNs support whose lifecycle could lose device registration during authentication refresh. It lacked category and recipient selection, per-device APNs environment handling, and correct notification-target identity. Those findings motivate this work; source and local test progress must still be distinguished from working background or terminated-app delivery.

Users of the official iOS app must not need their own Apple Developer credentials or a separately signed app. Self-hosted Server operators must not receive the publisher's APNs private key. Notification content should remain private from the shared delivery infrastructure.

Solution

Deliver Server-originated mobile notifications through this pipeline:

ServerBee Server -> dedicated ServerBee Push Relay -> APNs -> iOS.

Users explicitly enable Mobile notification subscriptions by category in iOS Settings. iOS registers its installation, APNs token/environment and content-key material with the authenticated Server at /api/mobile/push/encrypted-register. The Server selects eligible recipients, AES-256-GCM encrypts each notification for its installation, and persists pending delivery for up to 30 minutes. The public Relay forwards the unchanged encrypted envelope to APNs using the official app's credentials. An iOS Notification Service Extension decrypts the content before presentation.

Alerts include trigger and recovery notifications. Security notifications follow existing security alert rules and are restricted to administrators. Scheduled tasks, including manually started runs, notify the appropriate owner once per completed run, with failures enabled by subscription and successful results separately opt-in. Notification taps open the relevant authenticated detail rather than an unrelated screen.

User Stories

  1. As an iOS user, I want alert notifications while the app is backgrounded, so that I can react without keeping the dashboard open.
  2. As an iOS user, I want notifications when the app is not running, so that closing it does not stop monitoring notifications.
  3. As an official-app user, I want notifications without provisioning Apple certificates, so that enabling them does not require an Apple Developer account.
  4. As a self-hosted Server operator, I want my Server to originate notifications, so that local event and account policies remain authoritative.
  5. As a user, I want a clear explanation of the relay and privacy boundary before granting permission, so that I understand where delivery metadata goes.
  6. As a user, I want to enable notifications explicitly in iOS Settings, so that signing in does not unexpectedly prompt me for notification permission.
  7. As a user, I want separate subscriptions for alerts, security, and task outcomes, so that I receive the categories relevant to me.
  8. As a user, I want the app to show preferences confirmed by the Server, so that a failed save is not presented as successful.
  9. As a user, I want visible permission and registration status, so that I can distinguish disabled permission from a delivery setup failure.
  10. As a user, I want to retry registration and open system notification settings, so that I can repair setup without reinstalling the app.
  11. As a user, I want a test notification to my current installation, so that I can verify my own setup without notifying other users.
  12. As a subscribed user, I want alert-trigger notifications, so that I know when an enabled monitoring rule requires attention.
  13. As a subscribed user, I want recovery notifications, so that I know when a previously reported alert returns to normal.
  14. As a user, I want alerts to respect existing maintenance and suppression policies, so that planned work does not generate unwanted mobile notifications.
  15. As a user, I want Mobile notification subscriptions to work without an APNs channel or notification group, so that setup is possible entirely from iOS.
  16. As an administrator, I want security notifications to follow enabled security rules, thresholds, exclusions, and deduplication, so that routine raw detection events do not flood my phone.
  17. As an administrator, I want notifications for admitted SSH new-IP login, brute-force, and port-scan rule matches, so that I can respond to relevant security findings.
  18. As a member, I want notification delivery to respect my current role, so that subscribing cannot expose administrator-only security or task information.
  19. As a manual task initiator, I want the final outcome of my scheduled-task run, so that I know whether the operation I requested completed.
  20. As an automatic task's creator, I want notifications for its final failures, so that unattended executions can receive attention.
  21. As a task recipient, I want success notifications to be optional, so that routine successful runs do not interrupt me by default.
  22. As a task recipient, I want one summary after all target Servers finish, so that a multi-Server run does not generate a notification per machine.
  23. As a task recipient, I want intermediate retries to remain silent, so that transient failures are not confused with the final outcome.
  24. As a task recipient, I want the final summary to identify failures, timeouts, offline targets, and execution denials, so that I can assess the run accurately.
  25. As a task recipient, I want commands and command output excluded from push content, so that potentially sensitive execution details remain behind authentication.
  26. As a user, I want to tap an alert notification and open the corresponding alert, so that I can inspect its actual history and state.
  27. As an administrator, I want to tap a security notification and open the relevant Server security detail, so that I can investigate its context.
  28. As a task recipient, I want to tap a task notification and open that run's results, so that I do not have to locate the run manually.
  29. As a user opening a notification from a terminated app, I want its target retained until login restoration completes, so that startup timing does not lose the tap.
  30. As a user, I want unavailable or deleted notification targets to fall back safely, so that an old notification does not strand me on a broken detail screen.
  31. As a user who changed accounts or deployments, I want old notifications prevented from navigating within my current account, so that identities cannot be confused.
  32. As a foreground user, I want one system notification banner, so that APNs and WebSocket updates do not create duplicate banners for the same event.
  33. As a signed-in user, I want routine authentication refresh to preserve notification registration, so that receiving notifications does not depend on relaunching the app.
  34. As a user, I want permission and registration reconciled after returning to the app or recovering connectivity, so that transient setup failures can recover.
  35. As a user, I want registration bound to my installation and authenticated account, so that another user cannot overwrite or unregister it by guessing its identifier.
  36. As a user signing out, I want subsequent delivery for that account stopped, so that account notifications do not continue after logout.
  37. As an administrator revoking a mobile device or account credentials, I want queued delivery to respect revocation, so that previously queued messages do not bypass the new policy.
  38. As a user, I want expired sessions and removed roles to stop eligible delivery, so that an old registration does not retain access indefinitely.
  39. As a user with multiple devices, I want each subscribed installation evaluated independently, so that success or failure for one device does not suppress another's delivery.
  40. As a development or distribution user, I want my device's APNs environment handled correctly, so that sandbox and production devices can coexist.
  41. As a user, I want notification content encrypted between my Server and installation, so that the relay cannot read Server names, IP addresses, alert messages, or task summaries.
  42. As a user, I want a generic notification fallback when decryption cannot complete, so that failures do not expose plaintext through another path.
  43. As an app publisher, I want APNs signing credentials retained only by the relay, so that public Server distribution does not disclose them.
  44. As a relay operator, I want fixed APNs destinations and topic, hard request-size bounds, timeouts, and bounded best-effort source/target/instance-wide limits, so that a deliberately public relay has basic resource-abuse controls with honest limitations.
  45. As a user, I want notification registration to depend on authenticated Server ownership and system notification permission without an App Attest gate, while login, key isolation, and account-safe navigation remain enforced.
  46. As a Server operator, I want pending deliveries to survive restart and temporary relay outages, so that accepted local work is not discarded immediately.
  47. As a user, I want notifications older than 30 minutes discarded, so that an outage does not end with a flood of stale messages.
  48. As a Server operator, I want failures classified as accepted, retryable, permanent, or expired, so that delivery problems can be diagnosed accurately.
  49. As a user whose device token changes, I want stale send responses unable to delete its replacement, so that recovery cannot be undone by a late response.
  50. As a user, I want an APNs configuration or payload error distinguished from an invalid device token, so that valid registration is not erased by an unrelated provider error.
  51. As an existing notification-channel user, I want external channels to retain their configured behavior, so that mobile delivery does not alter Webhook, Telegram, Bark, or email workflows.
  52. As a user migrating to relay delivery, I want an event delivered through one mobile path, so that the legacy APNs channel and automatic delivery do not both notify the same new registration.
  53. As an English or Simplified Chinese user, I want localized settings, status, and notification text, so that the feature is understandable in my selected language.
  54. As a maintainer, I want automated contract tests and separate real-device evidence, so that local test success is not mistaken for verified APNs presentation.

Implementation Decisions

  • Architecture and ownership: use a dedicated public, stateless Cloudflare Workers Relay, separate from Heeler's deployed relay, exposing one POST /v1/send delivery endpoint. ServerBee Server owns authenticated registration, event selection, subscriptions, user/installation ownership, and durable pending delivery. The Relay owns APNs credential custody and bounded transport. Apple credentials are never distributed in the app or self-hosted Server. Refer to the revised mobile-notification relay ADR; Agent Authority and enrollment behavior are unaffected.
  • Reuse existing behavior: extend the existing mobile registration, authentication, alert evaluation, security rule evaluation, task-run aggregation, iOS notification manager, and navigation responsibilities. Heeler is reference material for public stateless transport, encryption, early delegate setup, APNs transport, and privacy disclosure; do not copy its SSH ownership model or modify its deployed relay.
  • Subscription API: use authenticated /api/mobile/push/encrypted-register and the current-installation subscription/status and targeted-test operations. Derive user and installation ownership from the authenticated mobile context. Reject cross-user changes and unauthorized categories. Return confirmed preferences and actionable registration status, expose OpenAPI contracts, and update generated client contracts as needed. Keep the legacy /api/mobile/push/register compatibility route distinct from this encrypted registration flow. iOS does not obtain a Relay challenge, attestation, or grant.
  • Registration data: persist the stable installation identity, authenticated user/session association, APNs token and environment, notification key identity, category preferences, optional task-success preference, and registration revision. Token or key replacement must be versioned. Remove active grant metadata and lifecycle dependencies while preserving existing ownership protections through forward-only migrations.
  • Recipient policy: alerts go to eligible subscribed users. Security rule notifications require a current administrator role. Scheduled-task outcomes go to the manual initiator or, for automatic runs, the creator, subject to current task access. Evaluate each installation independently and revalidate user existence, role, valid mobile session, subscription, and registration revision before sending.
  • Event gates: alert trigger/recovery and security notifications reuse existing rule filtering, maintenance handling, and notification suppression. Mobile enqueueing must not require a notification group. A security-rule match generates the security category once rather than a second general-alert delivery. Generate stable logical event identities for deduplication.
  • Task boundaries: notify only after every target of a scheduled-task run reaches its final outcome. Aggregate final results by run, excluding superseded retry failures. A capability denial, offline target, exhausted failure, or final timeout contributes to a failed summary. Successful summaries require explicit opt-in. Link to the same run identity; exclude commands and output from notification content.
  • Authentication lifecycle: atomically preserve and rebind valid installation registration during ordinary credential refresh. Logout, device revocation, password changes, user deletion, and mobile-session expiry stop future eligible sends, including queued messages. In-flight operations must use captured identity/revision and reject stale completion. Revocation cannot retract notifications already accepted by APNs.
  • Content encryption: use a versioned AES-256-GCM envelope with per-installation content keys, authenticated metadata, fresh nonces, and cross-language interoperability vectors. Bind deployment, account, category, event identity, and navigation target inside encrypted content. The iOS copy resides in shared Keychain storage accessible to the Notification Service Extension; the Server copy is exchanged only through authenticated secure registration. No plaintext notification content or content keys go to the Relay; only its fixed generic fallback is unencrypted.
  • Public Relay boundary and accepted risk: accept a device token, APNs environment, event identity/expiry and the existing AEAD envelope without caller attestation or a delivery grant. Do not replace the removed App Attest/grant layer with a renamed authorization service. An attacker knowing a valid target token can submit junk or replay ciphertext and cause a generic fallback notification; arbitrary or self-owned-token requests can consume Relay/APNs quota without knowing another user's token. AEAD protects authentic business content and confidentiality, not public endpoint abuse. Server recipient checks still govern legitimate Server-originated sends.
  • Relay state and transport: keep no persistent registration/admission database or Relay SQLite. Use WebCrypto APNs JWT signing with bounded reuse and platform fetch, fixed APNs hosts and operator-controlled topic/environment bindings. Apply hard streaming body limits before parsing, schema/envelope/APNs payload bounds, timeouts and bounded concurrency. Keep source-IP, target-token and instance-wide rate-limit state bounded; these are best-effort per-instance protections that reset with Workers isolates, not strict globally coordinated quota enforcement. Forward ciphertext unchanged with fixed generic fallback text, correct push type/priority/expiry, and provider-reason classification. Do not log plaintext notification content, tokens, content keys, signing material or request bodies.
  • Durable delivery: persist encrypted pending messages per logical event and eligible installation, unique against duplicate enqueueing, with expiry 30 minutes after the event. Resume eligible messages after restart; retry transient network failures, rate limits, and temporary provider errors with bounded backoff. Discard expired or newly ineligible work. Keep accepted, retryable, permanent, and expired outcomes distinct. Ambiguous network failures do not permit a claim of exactly-once presentation.
  • Safe cleanup: delete or invalidate registration only for a classified terminal device condition and only if the sending revision still matches. Do not interpret every HTTP 400 response as an invalid token. Configuration, payload, authorization, and environment failures require their own recovery paths.
  • iOS experience: retain one active deployment/account. Add category settings, task-success opt-in, permission and registration status, retry, a targeted test, and system-settings access. Request system permission only after explicit enablement. Reconcile registration on launch, foreground entry, and connectivity recovery. Failed saves remain visible and do not falsely update confirmed preferences.
  • Receiving and navigation: install the notification delegate early and buffer callbacks/taps until dependencies and authentication are ready. Decrypt in the Notification Service Extension, falling back to generic text on failure. In the foreground, show the system banner without another WebSocket banner. Route alerts by complete alert identity, security to relevant Server security detail, and tasks by run identity. Reject deployment/account mismatches and unauthorized targets; safely fall back for deleted or unavailable resources.
  • Compatibility: retain legitimate existing external-channel behavior. Explicitly separate relay registrations from legacy direct-APNs delivery so the same event cannot fan out through both paths to a newly registered installation. Document legacy migration behavior; do not silently send legacy plaintext through the official encrypted relay or require existing notification groups for the new subscriptions.
  • Privacy and documentation: explain before permission is requested that the Relay observes APNs tokens/environment, source IPs, timing, request size, event identity/expiry, envelope key identifiers and hashed identity metadata, and ciphertext, while lacking content keys. Explain the public endpoint's residual spam/resource-abuse risk and best-effort limit scope. Update English and Chinese mobile and configuration documentation together, and keep user-facing iOS strings localized.
  • Dependencies and deployment: use platform WebCrypto and Workers fetch for the Relay rather than retained App Attest/CBOR/certificate-validation or Node-specific transport dependencies. Follow repository dependency rules. Provide isolated Worker configuration, APNs signing requirements, secret/binding names, and a deployment runbook. Configured infrastructure and a signed app remain prerequisites for real-device validation; local compilation does not prove deployment or live delivery.

Testing Decisions

  • Confirmed primary seam: test the feature through the existing Server HTTP/integration harness and real event/lifecycle entry points. Use real migrated SQLite, real authentication and ownership checks, real rule evaluation, real task-run aggregation, and real outbox behavior. Substitute the external Relay network boundary rather than mocking internal policy modules or repository persistence.
  • Test external behavior: assert which installation receives which logical event, whether a revoked or unsubscribed recipient stops receiving, what the API reports, what survives restart, and which detail a tap opens. Avoid tests coupled to private helper calls, internal query layout, or incidental task scheduling.
  • Server prior art: extend the existing mobile-auth HTTP integration suite and push cross-user ownership tests. Follow existing security-rule tests for exclusions, maintenance, and deduplication, and existing scheduler tests for retry and final-result behavior. Keep existing authorization regressions covered.
  • Server acceptance matrix: include registration before and after access-token refresh; logout/device/password/user revocation; session expiry and role change; member versus administrator categories; manual initiator versus automatic creator; multiple devices; failed preference updates; duplicate enqueueing; restart recovery; 30-minute expiry; transient versus permanent relay errors; stale-token cleanup races; and no dependency on a notification group.
  • Task acceptance matrix: cover single and multiple target Servers, failure followed by successful retry, exhausted failures, offline targets, capability denials, timeouts, successful-run opt-in, unauthorized recipients, and exactly one logical summary at the final-run boundary. Do not treat an intermediate result or incomplete run as a completed successful run.
  • Relay boundary: exercise the actual Workers request handler with only outbound APNs networking substituted. Verify public token/environment sends, absence of challenge/grant routes and attestation configuration, unchanged ciphertext, fixed hosts/topic, both allowed APNs environments, payload/header correctness, WebCrypto JWT signing/caching, and provider-reason classification. Test hard streaming limits without trusting Content-Length, malformed and oversized payloads, bounded rate-limit maps, per-source/per-target/instance caps, timeouts/concurrency, and non-secret diagnostics. Do not claim these controls enforce a strict global quota or eliminate public endpoint abuse.
  • Encryption interoperability: share fixed vectors across Rust and Swift. Verify valid decrypt/render/target behavior, tampering, wrong key, unsupported version, identity binding, and size limits. Include assertions that relay requests and queued message content do not contain plaintext notification data or content keys.
  • iOS boundary: extend existing push-router, deep-link navigation, and logout-order tests. Use thin substitutes only for system permission/token callbacks, Keychain test isolation, and authenticated HTTP boundaries where native services cannot run in unit tests. Cover early callbacks, cold-launch buffering, registration recovery without App Attest or grants, stale identity/generation, preferences, decryption, foreground presentation, and safe navigation fallback. Heeler's registration and encrypted-envelope tests are reference patterns.
  • Tooling checks: regenerate the iOS project after new targets or sources; run relevant iOS builds/tests, Server integration suites, changed-crate formatting and required Clippy checks, generated API/client checks, localization review, and documentation contract checks using repository entry points. Report executed test counts and relevant failures.
  • Separate real-device acceptance: using an explicitly authorized, isolated configured Worker Relay and correctly signed app, verify authenticated Server registration, sandbox/production environment handling, encrypted APNs notifications in foreground/background/terminated states, cold-launch taps, token refresh, logout/account revocation, and category changes. Record provider acceptance separately from observed presentation and navigation. Simulator tests, stubbed APNs responses, and a successful build do not satisfy this layer. Worker code and APNs configuration shape are verified, but signing-key validity and these live checks remain unverified.

Out of Scope

  • Interactive terminal/one-shot command-result notifications, Agent upgrade results, and manual Incident CRUD notifications.
  • Raw security-event fan-out that bypasses existing security alert rules.
  • Multi-account or multi-deployment storage and automatic account switching from a notification.
  • Critical-alert entitlements, Live Activities, notification action buttons, or a second WebSocket-driven notification banner.
  • Restoring App Attest, strict app-version/distribution gates, challenge or delivery-grant services, Relay SQLite, or introducing a replacement authorization system; distributing the official app's APNs private key also remains out of scope.
  • Requiring users to sign their own app or provision their own Apple Developer credentials for the official-app workflow.
  • Replacing existing external notification channels, redesigning their secret storage, or unrelated monitoring/authentication refactors.
  • Guaranteed APNs presentation, exactly-once phone display, or replaying notifications older than 30 minutes.
  • Modifying or deploying Heeler's existing relay.
  • Deployment, Apple account mutations, secret installation, production configuration changes, code pushes, releases, or PR creation as an automatic consequence of this specification.

Further Notes

  • These requirements synthesize the user's selected design decisions. The user also confirmed the testing seams: Server integration behavior as the primary seam, separate iOS and Relay boundary checks, and distinct real-device acceptance.
  • Historical context: the original specification followed read-only investigation of ServerBee and Heeler. Implementation and automated validation were subsequently recorded in feat(mobile): add encrypted notifications through push relay #206. That old-architecture evidence is historical and must not be reused as proof of the current simplification or of live APNs/device behavior.
  • Publishing this specification authorizes issue creation and the requested triage label. It does not by itself authorize deploying infrastructure or installing credentials.
  • Keep implementation readiness distinct from live validation readiness. Missing relay deployment, Apple configuration, or signed-device access must be reported explicitly, with completed local checks retained as their own evidence.
  • Official protocol references: APNs registration, APNs signing keys, and notification content modification. App Attest references in earlier revisions belong to the superseded design.

Implementation verification checkpoint (2026-10-03)

PR #206 records final head 22c828c4517734b0814240ca4bbe751d126ffa3d and all 17 green checks, including main CI, 424 passing iOS tests and two Rust-to-Worker trace producers, and 61 Worker tests plus one real ingress-cancellation regression. All three native ciphertext consumers ran and passed; no XCTest tests were skipped. Bilingual documentation and generated API contracts were checked on the same head.

The checks above are automated implementation evidence for the identity-corrected head.

The official main app, Notification Service Extension and test bundle identifiers are app.serverbee, app.serverbee.notifications and app.serverbee.tests. Private/shared Keychain groups use $(AppIdentifierPrefix)app.serverbee and $(AppIdentifierPrefix)app.serverbee.push. Historical com.serverbee.mobile / com.serverbee.mobile.push Keychain service labels are intentionally retained for stored-credential compatibility; they are not bundle identifiers. Static identity-drift checks and testOfficialIdentityReadsHistoricalServiceInDefaultPrivateGroup passed. Signed-device upgrade continuity remains unverified.

Deployment/configuration checkpoint (2026-10-03, 19:48 UTC): The existing Worker deployment is active. APNS_TOPIC is now app.serverbee; the optional APNS_ENVIRONMENTS override was removed, so the configured default permits sandbox and production. Existing encrypted credential bindings were retained. A safe empty-object POST now returns 400 InvalidRequest instead of 503 RelayNotConfigured. This establishes accepted configuration shape only, not signing-key validity or APNs provider acceptance. No request to Apple's APNs provider was made. The Worker runtime bundle is byte-identical between ae5add3 and 22c828c, so no code redeploy was needed.

Live APNs sandbox/production provider acceptance and delivery, signed-device upgrade continuity, and signed physical-device presentation and taps remain NOT RUN. The issue remains open; these results do not convert the live acceptance requirements into completed work.

Activity

  1. ZingerLittleBee commented on Oct 16, 2026

    @ZingerLittleBee
    OwnerAuthor

    Closing as completed under the maintainer-approved reduced acceptance scope. Implementation is merged and #205 is closed with the physical sandbox smoke checks accepted. The remaining full live matrix is explicitly skipped and unverified, including production, strict lifecycle/duplicate measurements, business-category isolation and signed-upgrade key continuity. The issue body records the evidence and preserves the original unrun checkboxes; closure does not mean those scenarios passed. No confirmed defect was found in the exercised paths.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified, ready for an AFK agent

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions