Skip to content

Add Orca Relay desktop and mobile transport - #8536

Merged
Jinwoo-H merged 44 commits into
mainfrom
Jinwoo-H/mobile-relay
Jul 14, 2026
Merged

Jinwoo-H merged 44 commits into
mainfrom
Jinwoo-H/mobile-relay

Conversation

@Jinwoo-H

@Jinwoo-H Jinwoo-H commented Jul 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds Orca Relay end to end while preserving account-free LAN/Tailscale pairing as the preferred path:

  • desktop auth lifecycle, scoped relay-token exchange integration, director assignment, host proof/control, data transports, origin-aware drain/rebind, revoke durability, and thin Mobile settings status UI;
  • additive pairing offers and E2EE v2 with transcript binding, directional keys, session/counter framing, bounded queues, and the exact legacy direct path for version skew;
  • mobile pairing races, crash-safe credential reconciliation, configured-director recovery, native credential storage, stable logical RPC cutover, endpoint hysteresis, and relay E2EE connect/migration;
  • shared strict protocol fixtures, recovery matrices, and adversarial integration coverage.

Relay remains free but requires desktop Orca sign-in. The phone does not sign in, there is no rollout flag, and older desktop/mobile counterparts continue through the additive offer and legacy direct path.

Review-only area PRs (do not merge independently):

This combined PR is the sole merge candidate.

Screenshots

The settings UI is intentionally thin pending the separately designed final UI. No screenshot attached yet.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test (the full unsupported-Node-26 run passed 2,766 files and exposed 10 failures; under required Node 24, nine passed in isolation and the one branch-caused stale assertion was corrected and passed)
  • pnpm build
  • Added adversarial protocol, E2EE, auth lifecycle, broker, pairing/recovery, endpoint, migration, cleanup, UI, and real local-relay integration tests

Supported Node 24 validation:

  • 309 focused desktop/shared files: 3,022 passing tests, 2 files / 4 tests skipped;
  • all 224 mobile files: 1,571 passing tests, 2 skipped;
  • max-lines ratchet, standalone mobile typecheck, mobile lint, and mobile format checks passed;
  • each of the 10 files that failed under Node 26 was rerun independently; all pass after correcting the migrated connection-count assertion.

AI Review Report

Adversarial review focused on the protocol state machines, close-code recovery, E2EE downgrade/replay/reflection/counter handling, auth epoch races, global credential-install idempotency, invite fallback, generation fencing, origin ownership during drain, crash recovery, logical-session cutover, and bounded resource behavior. It found and corrected stale async ownership, relay-origin drain/rebind, mobile journal/reconciliation, configured-director recovery-matrix, settings-test isolation, and runtime integration-test seam issues.

Cross-platform review preserved runtime path APIs and existing platform abstractions; the thin UI adds no platform-specific shortcut behavior. Relay transports work for local, native/WSL, and SSH-hosted desktop runtimes because the desktop initiates outbound cloud connections and mobile RPC wiring remains host-runtime scoped.

Security Audit

Reviewed strict/bounded protocol parsing, query-free bearer transport, issuer/audience/purpose pinning, host key-possession proof, relayHostId/device binding, E2EE transcript confirmation before device authorization, nonce/counter uniqueness, queue limits, credential redaction, SecureStore use, IPC ownership, stale-generation fencing, durable revoke ordering, and direct/relay authorization-mode reconciliation. Broad auth-plane bearer tokens are never accepted by the relay, and the phone supplies no authoritative identity/version fields.

Cloud service and infrastructure changes are tracked and merged separately in stablyai/orca-cloud.

Notes

The four stacked draft PRs exist only to make area review manageable. Review this PR for the integrated merge.

Remaining rollout gates are operational rather than hidden behind flags: public stamped-cell DNS/certificates and live migration, aggregate auth/cell load and soaks, game days, released-counterpart version skew, physical LTE/NAT latency, mobile-to-desktop-to-SSH acceptance, and production launch criteria. These must be completed before public launch even if code review lands earlier.

Made with Orca 🐋

Jinwoo-H and others added 28 commits July 12, 2026 21:14
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
# Conflicts:
#	src/main/ipc/mobile.test.ts
#	src/main/ipc/mobile.ts
#	src/renderer/src/components/settings/MobilePane.tsx
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
@Jinwoo-H

Copy link
Copy Markdown
Contributor Author

Implementation checkpoint (2026-07-13)

Live-path tracing found and fixed one Phase 3 gap before served acceptance: native direct-only profiles bypassed endpoint lifecycle ownership, so the specified automatic existing-pair relay upgrade could not run. Commit b2c61b7fd adds a crash-durable direct-upgrade journal/controller, authoritative committed/not-found reconciliation, method_not_found compatibility, foreground/reconnect retry, durable credential-before-overlay publication, host-removal fencing/cleanup, and handoff to the relay endpoint supervisor.

Validation under Node 24.18.0:

  • 19 focused upgrade/controller/supervisor/host-store tests
  • root and mobile pnpm typecheck
  • full mobile oxlint + oxfmt check
  • max-lines ratchet
  • full mobile suite: 227 files passed, 1,583 tests passed, 2 skipped

Production infrastructure is still admission-disabled. Cloud PR #66 corrected disabled-source read-only preflight; three production preflight runs targeted c1/c2/c3 and passed exact-origin TLS/readiness, runtime identity/digest, fresh heartbeat, zero-work, and survivor checks without mutation. Served simulator relay evidence will follow after the one-time staging OAuth credential fill. This PR remains draft and must not be merged yet.

Co-authored-by: Orca <help@stably.ai>
Jinwoo-H and others added 2 commits July 13, 2026 21:07
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
@Jinwoo-H
Jinwoo-H marked this pull request as ready for review July 14, 2026 03:04
Jinwoo-H and others added 3 commits July 13, 2026 23:05
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
nwparker added a commit that referenced this pull request Jul 14, 2026
… reconnect (#8498 #8129)

Take-over of #8605 (issue #8591). Ships #8498 (worktree resync + pull-to-refresh + cache write-through) and #8129 (idempotent notification replay on reconnect). Fixes the original PR's field mismatch (seq vs notificationSeq) and adds the missing notifications.getMissedSince mobile RPC allowlist entry. #6784 and #4500 held back to avoid conflicting with the relay work (#8536). Co-authored-by: Brandon Bennett (@branben).
Jinwoo-H and others added 3 commits July 14, 2026 04:43
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
@Jinwoo-H
Jinwoo-H merged commit 77b154d into main Jul 14, 2026
8 checks passed
@bbingz bbingz mentioned this pull request Jul 24, 2026
8 of 11 tasks
brennanb2025 added a commit that referenced this pull request Aug 1, 2026
…ued after the write (#11458)

* fix(mobile): stop serving a pre-write host-list snapshot to loads issued after the write

removeHost/persistHost await hostListMutation, but the in-flight loadHosts()
de-dupe handed back a pass that started BEFORE the write committed, so a load
issued after removal repainted the removed host card (#8791). Every durable
write now drops the shared pass via host-list-load-sharing.ts so the next
caller reads fresh; concurrent loads with no write between them still share
one Keychain pass.

Also extracts the host action sheet into host-list-action-sheet-actions.ts to
pin closeBeforePress on Edit host + Remove (the freeze half of #8791, already
fixed by #8536).

* fix(mobile): invalidate host loads after token writes

* fix(mobile): protect host token cache from stale reads
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
… reconnect (stablyai#8498 stablyai#8129)

Take-over of stablyai#8605 (issue stablyai#8591). Ships stablyai#8498 (worktree resync + pull-to-refresh + cache write-through) and stablyai#8129 (idempotent notification replay on reconnect). Fixes the original PR's field mismatch (seq vs notificationSeq) and adds the missing notifications.getMissedSince mobile RPC allowlist entry. stablyai#6784 and stablyai#4500 held back to avoid conflicting with the relay work (stablyai#8536). Co-authored-by: Brandon Bennett (@branben).
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
* feat(mobile): define relay protocol groundwork

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): implement replay-safe E2EE v2 sessions

Co-authored-by: Orca <help@stably.ai>

* test(auth): lock cloud refresh single-flight

Co-authored-by: Orca <help@stably.ai>

* test(mobile): complete E2EE v2 adversarial coverage

Co-authored-by: Orca <help@stably.ai>

* refactor(runtime): unify mobile socket wiring

Co-authored-by: Orca <help@stably.ai>

* feat(runtime): add relay control and data clients

Co-authored-by: Orca <help@stably.ai>

* feat(runtime): coordinate desktop relay sessions

Co-authored-by: Orca <help@stably.ai>

* fix(auth): fence stale cloud session mutations

Co-authored-by: Orca <help@stably.ai>

* feat(runtime): add relay pairing and durable revoke

Co-authored-by: Orca <help@stably.ai>

* feat(runtime): add relay credential pairing RPCs

Co-authored-by: Orca <help@stably.ai>

* feat(settings): show Orca Relay sign-in status

Co-authored-by: Orca <help@stably.ai>

* test(relay): prove desktop lifecycle and E2EE splice

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): persist relay pairing state

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): race direct and relay pairing

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): recover pairing through relay director

Co-authored-by: Orca <help@stably.ai>

* fix(relay): preserve origin controls during drain

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): recover interrupted relay pairing

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): add stable relay RPC sessions

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): supervise direct and relay endpoints

Co-authored-by: Orca <help@stably.ai>

* Cover mobile relay director fallback matrix

Co-authored-by: Orca <help@stably.ai>

* Fix relay settings component test isolation

Co-authored-by: Orca <help@stably.ai>

* Remove unrelated merge formatting drift

Co-authored-by: Orca <help@stably.ai>

* Update runtime connection count integration assertion

Co-authored-by: Orca <help@stably.ai>

* Run mobile typecheck through pnpm

Co-authored-by: Orca <help@stably.ai>

* feat(relay): gate desktop controls on mobile demand

Co-authored-by: Orca <help@stably.ai>

* test(mobile): cover served relay recovery

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): upgrade direct pairings to relay

Co-authored-by: Orca <help@stably.ai>

* fix(relay): harden mobile reconnect and teardown

Co-authored-by: Orca <help@stably.ai>

* fix(auth): clarify account sign-in state

Co-authored-by: Orca <help@stably.ai>

* fix(auth): polish sign-in completion flow

Co-authored-by: Orca <help@stably.ai>

* fix(auth): clarify sign-out confirmation

Co-authored-by: Orca <help@stably.ai>

* fix(auth): simplify sign-in completion page

Co-authored-by: Orca <help@stably.ai>

* feat(mobile): add per-device pairing connection mode

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): stabilize pairing option layout

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): give pairing choices stable space

Co-authored-by: Orca <help@stably.ai>

* fix(mobile): stabilize pairing QR regeneration

Co-authored-by: Orca <help@stably.ai>

* Animate mobile pairing flow height

Co-authored-by: Orca <help@stably.ai>

* Configure auth in packaged builds

Co-authored-by: Orca <help@stably.ai>

* Make Orca Relay pairing an opt-in beta

Co-authored-by: Orca <help@stably.ai>

* Show Relay beta details on hover

Co-authored-by: Orca <help@stably.ai>

* Refine mobile relay pairing choice

Co-authored-by: Orca <help@stably.ai>

* Polish Orca Relay pairing controls

Co-authored-by: Orca <help@stably.ai>

* Keep mobile contract fallback test additive

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
…ued after the write (stablyai#11458)

* fix(mobile): stop serving a pre-write host-list snapshot to loads issued after the write

removeHost/persistHost await hostListMutation, but the in-flight loadHosts()
de-dupe handed back a pass that started BEFORE the write committed, so a load
issued after removal repainted the removed host card (stablyai#8791). Every durable
write now drops the shared pass via host-list-load-sharing.ts so the next
caller reads fresh; concurrent loads with no write between them still share
one Keychain pass.

Also extracts the host action sheet into host-list-action-sheet-actions.ts to
pin closeBeforePress on Edit host + Remove (the freeze half of stablyai#8791, already
fixed by stablyai#8536).

* fix(mobile): invalidate host loads after token writes

* fix(mobile): protect host token cache from stale reads
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant