Bound iOS pairing attempts

Merged
LA
4mo ago
+6563-535

Summary

  • make RPC request timeouts return without waiting for stuck transport cancellation to unwind
  • cap one iOS pairing attempt to a single 8s budget across QR, pasted QR, and manual host connect
  • dismiss the QR scanner sheet before handing scanned content into the shared pairing path

Tests

  • swift test --package-path Packages/iOS/CmuxMobileShell
  • swift test --package-path Packages/iOS/CmuxMobileRPC
  • swift test --package-path Packages/iOS/CmuxMobileShellUI (blocked: local GhosttyKit.xcframework binary artifact is absent)

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


[!NOTE]
High Risk
Large changes to authentication lifecycle, token races, and sign-out—security-critical paths—with substantial new concurrency/timeout behavior on mobile RPC pairing.

Overview
iOS pairing & RPC — User-initiated pairing is capped by a single 8s attempt budget (default on MobileSyncRuntime); per-RPC timeouts clip to whatever time remains. MobileCoreRPCClient uses one RPCRequestDeadline for Stack token fetch/force-refresh, connect, and send, with RPCStackTokenGate deduping and briefly blocking retries after timeouts. MobileRPCConnectAttemptRegistry and abandoned-connect cleanup close slow or superseded connects without blocking later attempts; host-status probes can attach a cached token via stackAccessTokenForStatusProvider.

Auth — Launch CMUXAuthState.primed treats a cached user with known tokens as signed in immediately (validation continues in the background) and adds a shorter sessionRestore timeout (8s) so restore fails open instead of sticking on “Restoring session”. AuthCoordinator gains coordinator-owned phases for credential exchange, validation, token-touching calls, and post-sign-in hooks, plus sign-in preflight that cancels/waits on stale token work; sign-out coordinates credential capture, cancels in-flight work, and clears late token writes. storedAccessToken() is added on TokenProviding for non-mutating reads.

CLI & CI — New cmux sessions / session-debug reads ~/.cmuxterm/*-hook-sessions.json with filters and optional Codex index/transcript hints (no live socket). CI runs CmuxAuthRuntime Swift Testing suites individually via --filter.

Reviewed by Cursor Bugbot for commit 810f2f783f95d28c7d930ebbda1be2ad86afba25. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Bounds iOS pairing to a single 8s attempt and tightens auth/RPC deadlines so timeouts fail fast without piling up connects or token fetches. Launch authenticates cached users immediately and adds a cmux sessions list CLI for session-restore diagnostics with localized help.

  • New Features

    • Pairing: one 8s attempt budget across QR, pasted QR, and manual host connect; per-request timeouts clip to the remaining budget; per-route gating via MobileRPCConnectAttemptRegistry with one bounded retry and a brief hard-gate/reset if late close hangs; stored‑Mac reconnects reuse an in‑flight attempt.
    • Auth: 8s sessionRestore; a cached user with stored tokens is treated as signed in while validation runs; token read/refresh, credential exchange, validation, and post‑sign‑in hooks are bounded and tracked; sign‑in preflight cancels/awaits stale token work; dev auto‑login is skipped when tokens exist; adds non‑mutating storedAccessToken().
    • RPC: one request deadline covers Stack token acquisition/force‑refresh, connect, and send; RPCStackTokenGate dedupes normal and force‑refresh token fetches and briefly suppresses retries after timeouts; slow or preinstalled connects are closed before sending; request‑queue tombstones are fixed and connect retry is allowed after a timeout; host‑status probes use a cached token via stackAccessTokenForStatusProvider.
    • CLI: cmux sessions list (alias session-debug) lists/filters saved agent hook sessions from ~/.cmuxterm with optional Codex transcript/index hints; localized usage/help.
  • Bug Fixes

    • Scanner sheet dismisses before handing QR to pairing; session‑restore timeouts preserve the cached session instead of leaving the app on “Restoring session.”
    • Timed‑out/cancelled RPCs return requestTimedOut and then tear down connects without blocking other waiters; timed‑out Stack token acquisition maps to a retryable requestTimedOut in CMUXMobileRuntime.
    • Sign‑out cancels in‑flight credential exchanges/validations and drops late token writes so stale sessions cannot resurrect.
    • SystemDeliveredNotificationClearer no‑ops outside the app bundle; stabilize tests and deflake CmuxAuthRuntime CI by running Swift Testing suites individually.

Summary by CodeRabbit

  • New Features
    • Added a configurable pairing-attempt deadline that bounds the full QR and manual pairing flow (with a sensible default).
  • Improvements
    • Pairing request timeouts are now strictly budgeted against the overall deadline for quicker, more consistent failures.
    • Cached-session/auth flows authenticate immediately when cached tokens are available and use phase-appropriate timeouts (including a session-restore deadline).
    • The pairing scanner sheet dismisses immediately after a successful scan.
    • RPC request timeouts now close slow connections before stale authenticated requests are sent.
  • Tests
    • Added/expanded coverage for pairing-attempt deadlines, session-restore timeout behavior, and RPC timeout connection closing.