Skip to content

fix(ios): pair through every trusted route - #456

Merged
milind-soni merged 1 commit into
mainfrom
codex/connectivity-foundation
Aug 25, 2026
Merged

fix(ios): pair through every trusted route#456
milind-soni merged 1 commit into
mainfrom
codex/connectivity-foundation

Conversation

@milind-soni

@milind-soni milind-soni commented Aug 25, 2026

Copy link
Copy Markdown
Owner

What changed

  • probes every address in a pairing invite concurrently before spending its credential
  • preserves the advertised security order, so a fast LAN response cannot outrank Tailscale
  • sends the pairing POST only to a verified OpenMausBot endpoint
  • safely replays one logical redemption after a lost response without creating an orphan device
  • persists the route that actually worked and keeps the invite retryable
  • actively erases the short-lived recovery token from desktop memory at expiry

Why

Initial pairing previously tried only the first QR address. If that MagicDNS or Bonjour name did not resolve on the phone, a working LAN address in the same QR was never attempted. Fallback rotation only began after pairing, so it could not help.

Verification

  • swift test: 144 passed
  • full iOS simulator app build: succeeded (iPhone 17 Pro, iOS 26.5)
  • companion focused suite: 39 passed
  • project TypeScript typecheck: passed
  • companion production build: passed
  • full repository suite before final review fixes: 1,839 tests counted, 18 skipped, 0 failed
  • packaged-server smoke test: passed

Compatibility

Older mobile clients still get exactly-once pairing. Older desktop companions remain supported; the iOS client does not retry an authoritative HTTP rejection. The wire change is one optional pairRequestId field.

Summary by CodeRabbit

  • New Features

    • Pairing now retries safely using a stable request ID, preventing duplicate device registrations.
    • iOS pairing automatically checks available connection routes and falls back to the first reachable route.
    • Successful pairing preserves the preferred connection route and additional available hosts.
    • Existing clients continue to use the previous pairing behavior.
  • Bug Fixes

    • Improved recovery from temporary connection, routing, and decoding failures during pairing.

@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openmausbot-docs Ready Ready Preview Aug 25, 2026 8:02am

Request Review

@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 76b86ffa-a090-4704-8fe4-a8d6928e2526

📥 Commits

Reviewing files that changed from the base of the PR and between e40954b and b7dcd8d.

📒 Files selected for processing (9)
  • companion/src/devices.ts
  • companion/src/index.ts
  • companion/src/proxy.ts
  • companion/test/devices.test.ts
  • companion/test/proxy.test.ts
  • ios/App/PairingView.swift
  • ios/App/Session.swift
  • ios/Sources/CompanionCore/Client.swift
  • ios/Tests/CompanionCoreTests/PairingTests.swift

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

Pairing redemption now supports request-ID replay recovery. The iOS client probes advertised hosts, selects a healthy route, retries eligible failures, and persists the successful endpoint and server-provided pairing data.

Changes

Pairing recovery and route failover

Layer / File(s) Summary
Companion replay recovery
companion/src/devices.ts, companion/test/devices.test.ts
DeviceRegistry caches successful redemptions by request ID and credential digest until pairing expiry. Explicit window changes and expiry clear replay state. Legacy redemptions remain exactly once.
Redemption request propagation
companion/src/proxy.ts, companion/src/index.ts, companion/test/proxy.test.ts
The proxy forwards pairRequestId through the pairing API. End-to-end tests verify repeated redemption returns the original token.
iOS route probing and retry
ios/Sources/CompanionCore/Client.swift, ios/Tests/CompanionCoreTests/PairingTests.swift
The client validates /api/health, selects routes in advertised priority order, retries transport and decoding failures, and reports PairingRouteError when routes are exhausted.
iOS pairing state integration
ios/App/PairingView.swift, ios/App/Session.swift
The app preserves request IDs across retryable failures, resets them for new pairing attempts, and stores the server-selected name and ordered hosts from PairingOutcome.

Estimated code review effort: 4 (Complex) | ~60 minutes

Merge Risk: ⚪ Minimal · up to b7dcd

The pairing changes are supported by passing tests and builds, with no actionable merge-blocking risk remaining beyond normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant PairingView
  participant Session
  participant CompanionClient
  participant HealthEndpoint
  participant PairingEndpoint
  PairingView->>Session: Submit pairing request with pairRequestId
  Session->>CompanionClient: Select first reachable route
  CompanionClient->>HealthEndpoint: Probe advertised hosts
  HealthEndpoint-->>CompanionClient: Return validated service identity
  CompanionClient->>PairingEndpoint: Redeem credential
  PairingEndpoint-->>CompanionClient: Return pairing response
  CompanionClient-->>Session: Return response and winning connection
Loading

Suggested reviewers: mnthr7, claude

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 30 functions across 9 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: iOS pairing now tries every trusted route. It is concise and specific.
Description check ✅ Passed The description explains what changed, why it changed, how it was verified, and compatibility behavior. It is detailed and aligned with the pull request objectives, although it omits the template chec…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains what changed, why it changed, how it was verified, and compatibility behavior. It is detailed and aligned with the pull request objectives, although it omits the template checklist and screenshots section.

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/connectivity-foundation

Comment @coderabbitai help to get the list of available commands.

@milind-soni
milind-soni merged commit 70f8591 into main Aug 25, 2026
8 checks passed
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