Repository navigation
Add Orca Relay desktop and mobile transport - #8536
Conversation
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>
|
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 Validation under Node 24.18.0:
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>
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>
… 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).
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
Co-authored-by: Orca <help@stably.ai>
…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
… 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).
* 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>
…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
Summary
Adds Orca Relay end to end while preserving account-free LAN/Tailscale pairing as the preferred path:
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 lintpnpm typecheckpnpm 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 buildSupported Node 24 validation:
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 🐋