Files
orca/src/shared/mobile-relay-close-codes.ts
T
Jinwoo HongandOrca 77b154d5dd Add Orca Relay desktop and mobile transport (#8536)
* 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>
2026-07-14 11:47:05 -07:00

52 lines
2.0 KiB
TypeScript

export const MOBILE_RELAY_CLOSE_CODE = {
BAD_OUTER_CREDENTIAL: 4401,
HOST_OFFLINE: 4404,
PEER_DROPPED: 4408,
WRONG_CELL: 4409,
LIMIT_EXCEEDED: 4429,
DRAINING: 4503
} as const
export type MobileRelayCloseCode =
(typeof MOBILE_RELAY_CLOSE_CODE)[keyof typeof MOBILE_RELAY_CLOSE_CODE]
export type MobileRelayLeg = 'host-control' | 'host-data' | 'phone-invite' | 'phone-resume'
export type MobileRelayRecovery =
| { kind: 'disable-relay-credential'; directUnaffected: true }
| { kind: 'wait-for-host-revival' }
| { kind: 'reconnect-fresh-e2ee'; fullJitter: true }
| { kind: 'resolve-invite-through-director-ws'; requireStrictlyNewerEpoch: true }
| { kind: 'resolve-resume-through-director-post' }
| { kind: 'request-director-assignment' }
| { kind: 'backoff'; fullJitter: true }
| { kind: 'resolve-configured-director'; fullJitter: true }
export function mobileRelayRecoveryFor(
code: MobileRelayCloseCode,
leg: MobileRelayLeg
): MobileRelayRecovery {
switch (code) {
case MOBILE_RELAY_CLOSE_CODE.BAD_OUTER_CREDENTIAL:
return { kind: 'disable-relay-credential', directUnaffected: true }
case MOBILE_RELAY_CLOSE_CODE.HOST_OFFLINE:
return { kind: 'wait-for-host-revival' }
case MOBILE_RELAY_CLOSE_CODE.PEER_DROPPED:
return { kind: 'reconnect-fresh-e2ee', fullJitter: true }
case MOBILE_RELAY_CLOSE_CODE.WRONG_CELL:
if (leg === 'phone-invite') {
return { kind: 'resolve-invite-through-director-ws', requireStrictlyNewerEpoch: true }
}
return leg === 'phone-resume'
? { kind: 'resolve-resume-through-director-post' }
: { kind: 'request-director-assignment' }
case MOBILE_RELAY_CLOSE_CODE.LIMIT_EXCEEDED:
return { kind: 'backoff', fullJitter: true }
case MOBILE_RELAY_CLOSE_CODE.DRAINING:
return { kind: 'resolve-configured-director', fullJitter: true }
}
}
export function isMobileRelayCloseCode(value: number): value is MobileRelayCloseCode {
return Object.values(MOBILE_RELAY_CLOSE_CODE).some((code) => code === value)
}