Skip to content

Keep Iroh reconnects alive through control-plane outages - #8781

Closed
azooz2003-bit wants to merge 3 commits into
mainfrom
task-iroh-reconnect-reliability
Closed

azooz2003-bit wants to merge 3 commits into
mainfrom
task-iroh-reconnect-reliability

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Jul 23, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #8531

Related lifecycle context: #8573

Summary

  • Keep the last verified signed relay policy active through broker connectivity failures, cooldowns, rate limits, and transient server failures.
  • Give every stored-Mac reconnect caller one actor-owned 30-second hard deadline, cap abandoned Iroh dials at three, and let explicit Retry bypass automatic cooldown.
  • The optional relay limiter infrastructure decision is already on main via Make CMUX_RELAY_TOKEN_RATE_LIMIT_ID optional so deploys survive unset rate-limit envs #8771.

Testing

  • Shared Iroh transport: 467 tests in 56 suites passed.
  • Mobile reconnect selection: 64 tests passed.
  • Tagged macOS build and isolated iOS simulator build passed.
  • Stored-pair startup reached sync.subscribe_ok.
  • Restarting the tagged Mac recovered the iOS subscription and workspace, followed by repeated successful liveness probes.
  • /, /handler/sign-in, and /handler/after-sign-in returned 200 from the local API.

Demo Video

  • No video. Exact-head behavior was verified on the isolated Codex-irrel-49440 simulator and tagged irrel Mac app.

Review Trigger

Automatic repository reviews run on push. No manual Codex review was requested.

Checklist

  • I tested the change locally
  • I added or updated tests for behavior changes
  • Docs and changelog are not needed for this internal reliability change
  • Automatic review bots were triggered by the latest push
  • All code review bot comments are resolved
  • There are no human review comments

@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The PR adds verified cached-policy fallback for eligible broker refresh failures and reworks stored-Mac reconnect deadline handling. It exposes the shared timeout utility, centralizes reconnect timeout settlement, controls retry state and secondary dials, and adds regression coverage.

Iroh policy cache fallback

Layer / File(s) Summary
Cache-eligible broker refresh
Packages/Shared/CmuxIrohTransport/Sources/CmuxIrohTransport/CmxIrohHostRuntime+PolicyRefresh.swift, Packages/Shared/CmuxIrohTransport/Sources/CmuxIrohTransport/CmxIrohHostRuntime.swift
Discovery preflight errors use cached policy when refresh-preservation classification permits it, replacing the removed connectivity-specific helper.
Cached-policy lifecycle coverage
Packages/Shared/CmuxIrohTransport/Tests/CmuxIrohTransportTests/CmxIrohHostRuntimeLifecycleTests.swift
Lifecycle tests cover transient registration failures and broker cooldown preflight errors activating with cached bindings.

Stored-Mac reconnect orchestration

Layer / File(s) Summary
Shared reconnect deadline flow
Packages/iOS/CmuxMobileRPC/Sources/CmuxMobileRPC/RPCTaskTimeout.swift, Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift, Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+ConnectionRecovery.swift
The timeout utility is public, restore and dial work run under one shared deadline, and the recovery caller delegates timeout settlement to the reconnect entry.
Retry and concurrent-work controls
Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift
Explicit retries clear automatic reconnect backoff, and secondary aggregation is suppressed during stored-Mac reconnects.
Deadline and retry regression coverage
Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/ReconnectAttemptDeadlineTests.swift
Tests cover cancellation-resistant deadline races, timeout settlement, explicit retry bypass, abandoned operations, and adjusted hung-redial timing.

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

Sequence Diagram(s)

sequenceDiagram
  participant CmxIrohHostRuntime
  participant TrustBroker
  participant VerifiedPolicyCache
  CmxIrohHostRuntime->>TrustBroker: preflight discovery or register
  TrustBroker-->>CmxIrohHostRuntime: eligible refresh failure
  CmxIrohHostRuntime->>VerifiedPolicyCache: request cached verified policy
  VerifiedPolicyCache-->>CmxIrohHostRuntime: cached binding
  CmxIrohHostRuntime-->>CmxIrohHostRuntime: activate with cached policy
Loading
sequenceDiagram
  participant MobileShellComposite
  participant RPCTaskTimeout
  participant StoredMac
  participant ReconnectState
  MobileShellComposite->>RPCTaskTimeout: enforce reconnect deadline
  RPCTaskTimeout->>StoredMac: await restore and dial
  RPCTaskTimeout-->>MobileShellComposite: outcome or deadline timeout
  MobileShellComposite->>ReconnectState: settle reconnect and record backoff
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (24 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address #8531 by preserving cached policy, bounding reconnect attempts, and clearing retry cooldowns.
Out of Scope Changes check ✅ Passed The changes remain focused on reconnect resilience, deadline handling, and policy-fallback behavior.
Cmux Swift Actor Isolation ✅ Passed PASS: The touched production code stays actor-contained; the new public RPCTaskTimeout is a pure Sendable value type, and the deadline helper/calls remain within the @MainActor shell.
Cmux Swift Blocking Runtime ✅ Passed PASS: The diff removes the old NSLock/continuation race; the timeout remains async/actor-based, and no new blocking waits, sleeps, or sync locks are introduced.
Cmux Browser Automation Off-Main ✅ Passed Diff only touches mobile reconnect/RPC timeout; no browser/WebKit commands, routing, or main-actor automation changes are present.
Cmux Expensive Synchronous Load ✅ Passed No expensive sync history/file load was added or moved; new paths use async actor-backed store reads and in-memory backoff state, not agent-history loaders.
Cmux Cache Substitution Correctness ✅ Passed Cached policy fallback is freshness-checked via validateCachedPolicy and only allowed for verified transient broker failures; cold cache misses still throw.
Cmux No Hacky Sleeps ✅ Passed Changed files are Swift only; the runtime-no-hacky-sleeps rule covers non-Swift runtime scripts, so this PR doesn’t trigger it.
Cmux Algorithmic Complexity ✅ Passed PASS: The only changed code adds a public timeout helper and swaps the race helper to RPCTaskTimeout; no nested scans, rescans, or repeated filtering were introduced.
Cmux Swift Concurrency ✅ Passed PASS: the diff replaces continuation/NSLock timeout racing with async/await and only uses local awaited Tasks; no new Dispatch/Combine/completion-handler APIs or unowned lifecycle Tasks were added.
Cmux Swift @Concurrent ✅ Passed No changed nonisolated async helper lacks @concurrent, and the new reconnect deadline work uses an explicit Task hop; remaining async work is intentionally MainActor-bound.
Cmux Swift Package Boundaries ✅ Passed The new reconnect/policy logic lives in SwiftPM targets (CmuxIrohTransport, CmuxMobileShell, CmuxMobileRPC), with tests in test targets; no app-target boundary violation found.
Cmux Swiftpm Lockfiles ✅ Passed PR diff only changes Swift sources/tests; no .gitignore, Package.swift, .xcodeproj, or Package.resolved files are touched, so the lockfile rule isn’t triggered.
Cmux Swift Logging ✅ Passed No new print/debugPrint/dump/NSLog or modified logging statements appear in the diff; the existing Logger constants predate the change.
Cmux User-Facing Error Privacy ✅ Passed Touched production code only changes reconnect/cache control flow and internal logging; no new user-facing error or recovery text was added.
Cmux Full Internationalization ✅ Passed Only internal deadline logic and API docs changed; no user-facing Swift text or locale/catalog files were added or modified.
Cmux Swiftui State Layout ✅ Passed No new SwiftUI state/layout patterns were introduced; the diff only changes recovery/runtime logic and RPCTaskTimeout, with no ObservableObject, GeometryReader, lazy-row store refs, or render-time...
Cmux Architecture Rethink ✅ Passed It centralizes deadline ownership in one shared helper/actor, removes lock-based race wiring, and keeps reconnect state gated by generation/invariant.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR only changes RPCTaskTimeout and MobileShellComposite+ConnectionRecovery; no NSWindow/NSPanel/WindowGroup/NSWindowController or cmuxAuxiliaryWindowIdentifiers code was added or changed.
Cmux Source Artifacts ✅ Passed All changed paths are intentional Swift source/tests; the rule file allows them, and the diff contains no artifact-like paths or scratch dirs.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Touched production sources only refactor deadline racing and make RPCTaskTimeout public for production use; no new DEBUG/test-only seam or ForTesting accessor was added.
Cmux No Ambient Global State ✅ Passed The diff only adds scoped methods and constructable helper types; no new file-scope mutable state, singletons, or namespace-style global APIs were introduced.
Title check ✅ Passed The title clearly summarizes the main change: preserving Iroh reconnects during control-plane outages.
Description check ✅ Passed The description covers Summary, Testing, Demo Video, Review Trigger, and Checklist with mostly complete details.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task-iroh-reconnect-reliability

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@greptile-apps

greptile-apps Bot commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR hardens Iroh reconnect reliability across two dimensions: the host-side policy layer now falls back to its last verified cached relay policy when broker preflight fails with transient errors (rate limits, cooldowns, 503s) instead of propagating the error and stalling the runtime; and the mobile stored-Mac reconnect deadline is moved from a per-trigger call site in recoverMobileConnection into the shared reconnectActiveMacOutcome entry, so the 30-second hard ceiling is enforced consistently for startup, team-change, manual, and automatic recovery triggers.

  • Broker cache fallback extended (CmxIrohHostRuntime+PolicyRefresh.swift, CmxIrohHostRuntime.swift): preflight errors are now caught and routed through cachedPolicy when preservesVerifiedPolicyDuringRefresh holds; the narrower isConnectivityFailure helper is removed.
  • Shared reconnect deadline (MobileShellComposite.swift): reconnectActiveMacOutcome now owns the raceAgainstDeadline wrapper around the extracted performReconnectActiveMacAttempt, ensuring every lifecycle entry point shares the same wedge protection and abandoned-dial tracking; explicit retry clears transient automatic backoff before attempting.
  • Race implementation cleaned up (MobileShellComposite+ConnectionRecovery.swift): the NSLock-based RaceContinuationOnce is replaced by RPCTaskTimeout (made public for cross-package use), which uses an actor to guarantee exactly-once settlement.

Confidence Score: 5/5

Safe to merge — no correctness regressions found across the broker fallback, deadline centralization, or race implementation changes.

The broker preflight catch routes transient errors through the established cachedPolicy path guarded by preservesVerifiedPolicyDuringRefresh and is covered by two new lifecycle tests. Moving the deadline into reconnectActiveMacOutcome is a net simplification with every caller sharing the same ceiling and abandoned-dial accounting. The NSLock-based RaceContinuationOnce is replaced by the cleaner RPCTaskTimeout actor settlement. No new global state, blocking primitives, or test seams in production source.

No files require special attention.

Important Files Changed

Filename Overview
Packages/Shared/CmuxIrohTransport/Sources/CmuxIrohTransport/CmxIrohHostRuntime+PolicyRefresh.swift Adds a catch block around the broker preflight call so rate-limit, cooldown, and transient 503 errors fall back to the verified cached policy; the previous connectivity-only guard replaced by the richer preservesVerifiedPolicyDuringRefresh predicate.
Packages/Shared/CmuxIrohTransport/Sources/CmuxIrohTransport/CmxIrohHostRuntime.swift Removes the now-superseded isConnectivityFailure static helper; error classification is fully delegated to CmxIrohTrustBrokerClientError.preservesVerifiedPolicyDuringRefresh.
Packages/iOS/CmuxMobileRPC/Sources/CmuxMobileRPC/RPCTaskTimeout.swift Makes RPCTaskTimeout and its primary value() method public for cross-package use from CmuxMobileShell; implementation unchanged, actor-owned race settlement is correct.
Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+ConnectionRecovery.swift Removes the per-trigger deadline race and NSLock-based RaceContinuationOnce; recoverMobileConnection now delegates the full deadline and abandoned-dial accounting to reconnectActiveMacOutcome, and raceAgainstDeadline uses RPCTaskTimeout internally.
Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift Centralises the 30-second deadline inside reconnectActiveMacOutcome; extracts performReconnectActiveMacAttempt; adds clearTransientAutomaticReconnectBackoff on explicit retry; guards secondary aggregation with !isReconnectingStoredMac to prevent competing dials during stored-Mac restore.
Packages/Shared/CmuxIrohTransport/Tests/CmuxIrohTransportTests/CmxIrohHostRuntimeLifecycleTests.swift Adds two test cases covering the new broker-fallback paths: rate-limited/rejected errors use the verified cache without waiting, and a cooldown preflight error activates the cache before any registration.
Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/ReconnectAttemptDeadlineTests.swift Adds three new tests: lifecycle reconnect returns at the shared hard deadline when store restore hangs, explicit retry bypasses automatic Iroh backoff, and the ReconnectDeadlineTestGate actor replaces the unresumable CheckedContinuation stub to avoid a leaked continuation in the wedged-FFI-dial test.

Sequence Diagram

sequenceDiagram
    participant Caller as recoverMobileConnection / retryActiveMacReconnect
    participant Entry as reconnectActiveMacOutcome
    participant Race as raceAgainstDeadline (RPCTaskTimeout)
    participant Impl as performReconnectActiveMacAttempt
    participant Broker as CmxIrohTrustBroker

    Caller->>Entry: reconnectActiveMacOutcome(...)
    Entry->>Entry: claim generation, start restoringDeadline
    Entry->>Race: raceAgainstDeadline(30 s)
    Race->>Impl: performReconnectActiveMacAttempt(generation)
    Impl->>Broker: preflight / register / discover
    alt Broker OK
        Broker-->>Impl: policy
        Impl-->>Race: .connected / .failed
        Race-->>Entry: outcome (deadline still open)
        Entry-->>Caller: StoredMacReconnectOutcome
    else Preflight transient error (rate-limit, cooldown, 503)
        Broker-->>Impl: error
        Note over Impl,Broker: preservesVerifiedPolicyDuringRefresh to cachedPolicy
        Impl-->>Race: .connected (cached binding)
        Race-->>Entry: outcome
        Entry-->>Caller: StoredMacReconnectOutcome
    else Hard deadline fires
        Race-->>Entry: nil (abandoned task tracked)
        Entry->>Entry: finishStoredMacReconnectAttempt + recordTransientBackoff
        Entry-->>Caller: .failed(.timedOut)
    end
Loading

Reviews (3): Last reviewed commit: "fix(ios): signal reconnect deadlines wit..." | Re-trigger Greptile

Comment thread web/app/env.ts
z.string().min(64).max(16_384),
),
CMUX_RELAY_TOKEN_RATE_LIMIT_ID: requireVercelRelayValue(),
CMUX_RELAY_TOKEN_RATE_LIMIT_ID: z.string().min(1).optional(),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Silent rate-limiting gap when env var is omitted

Making CMUX_RELAY_TOKEN_RATE_LIMIT_ID globally optional changes the failure mode from a startup crash (hard to miss) to a running deployment that silently issues relay tokens without any rate limit. The runtime already handles a missing rule ID gracefully (Effect.void), so this is an intentional trade-off — but it removes the "fail fast" safety net that would alert an operator who accidentally deletes or forgets the variable. A misconfigured production deployment will serve unlimited relay tokens with no visible signal until traffic patterns or billing anomalies surface the gap. Consider keeping the env-level requirement and instead catching the not-found sentinel before the process starts, or at minimum emitting a structured startup warning when CMUX_RELAY_TOKEN_RATE_LIMIT_ID is absent on a live Vercel deployment.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@azooz2003-bit
azooz2003-bit force-pushed the task-iroh-reconnect-reliability branch from bcd3aae to eff3aa4 Compare July 24, 2026 00:05

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift`:
- Around line 1890-1894: Update the abandoned reconnect ceiling check in the
timeout handling flow to use a strict less-than comparison, accounting for the
increment performed by registerAbandonedReconnectDial before this check.
Preserve the existing accountID fallback and
recordTransientAutomaticReconnectBackoff behavior while ensuring no retry is
scheduled when abandonedReconnectDialCount equals
maximumAbandonedReconnectDials.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: af2be0d4-36c3-4e71-8399-6703a0848191

📥 Commits

Reviewing files that changed from the base of the PR and between 2c38c06 and bcd3aae.

📒 Files selected for processing (9)
  • Packages/Shared/CmuxIrohTransport/Sources/CmuxIrohTransport/CmxIrohHostRuntime+PolicyRefresh.swift
  • Packages/Shared/CmuxIrohTransport/Sources/CmuxIrohTransport/CmxIrohHostRuntime.swift
  • Packages/Shared/CmuxIrohTransport/Tests/CmuxIrohTransportTests/CmxIrohHostRuntimeLifecycleTests.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+ConnectionRecovery.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift
  • Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/ReconnectAttemptDeadlineTests.swift
  • web/app/env.ts
  • web/services/relay/http.ts
  • web/tests/client-config-env.test.ts
💤 Files with no reviewable changes (1)
  • Packages/Shared/CmuxIrohTransport/Sources/CmuxIrohTransport/CmxIrohHostRuntime.swift

Comment on lines +1890 to +1894
if abandonedReconnectDialCount <= Self.maximumAbandonedReconnectDials,
let accountID = stackUserID ?? identityProvider?.currentUserID {
recordTransientAutomaticReconnectBackoff(accountID: accountID)
}
return .failed(.timedOut)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Off-by-one in the abandoned-dial ceiling check.

maximumAbandonedReconnectDials is documented as the ceiling on concurrently outstanding abandoned dials before automatic retries pause, but registerAbandonedReconnectDial already incremented the count for the just-timed-out dial before this check runs. Using <= schedules another automatic retry when the count already equals the ceiling (3), letting a 4th abandoned dial accumulate before retries actually pause — one more than the documented bound of 3.

🐛 Proposed fix
-        if abandonedReconnectDialCount <= Self.maximumAbandonedReconnectDials,
+        if abandonedReconnectDialCount < Self.maximumAbandonedReconnectDials,
            let accountID = stackUserID ?? identityProvider?.currentUserID {
             recordTransientAutomaticReconnectBackoff(accountID: accountID)
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if abandonedReconnectDialCount <= Self.maximumAbandonedReconnectDials,
let accountID = stackUserID ?? identityProvider?.currentUserID {
recordTransientAutomaticReconnectBackoff(accountID: accountID)
}
return .failed(.timedOut)
if abandonedReconnectDialCount < Self.maximumAbandonedReconnectDials,
let accountID = stackUserID ?? identityProvider?.currentUserID {
recordTransientAutomaticReconnectBackoff(accountID: accountID)
}
return .failed(.timedOut)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift`
around lines 1890 - 1894, Update the abandoned reconnect ceiling check in the
timeout handling flow to use a strict less-than comparison, accounting for the
increment performed by registerAbandonedReconnectDial before this check.
Preserve the existing accountID fallback and
recordTransientAutomaticReconnectBackoff behavior while ensuring no retry is
scheduled when abandonedReconnectDialCount equals
maximumAbandonedReconnectDials.

@azooz2003-bit
azooz2003-bit force-pushed the task-iroh-reconnect-reliability branch from eff3aa4 to 29021b6 Compare July 24, 2026 00:10
@cursor

cursor Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@azooz2003-bit
azooz2003-bit force-pushed the task-iroh-reconnect-reliability branch from 62faea5 to 4d7cb68 Compare July 24, 2026 00:34

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+ConnectionRecovery.swift (1)

862-863: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Stale doc comment: "MainActor-confined" once-guard no longer matches the delegated implementation.

The doc comment above raceAgainstDeadline still says the once-guard is "MainActor-confined," but the reimplementation now delegates settlement to RPCTaskTimeout, whose own doc states the guard works "through an actor" (backed by RPCTaskTimeoutRace, not MainActor). Worth updating the comment so future readers of this concurrency-sensitive path aren't misled about which primitive actually enforces the once-guard.

📝 Suggested comment update
-    /// operation runs in its own task that the deadline path abandons after
-    /// a best-effort cancel; the once-guard is MainActor-confined so exactly
-    /// one side resumes. An abandoned dial retains its captures until it
+    /// operation runs in its own task that the deadline path abandons after
+    /// a best-effort cancel; `RPCTaskTimeout`'s actor-backed once-guard
+    /// ensures exactly one side resumes. An abandoned dial retains its captures until it

Also applies to: 905-932

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite`+ConnectionRecovery.swift
around lines 862 - 863, Update the documentation above raceAgainstDeadline to
remove the outdated “MainActor-confined” description and accurately state that
settlement is guarded through the actor-backed RPCTaskTimeout/RPCTaskTimeoutRace
implementation. Apply the same correction to the corresponding documentation
around the additionally referenced section.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite`+ConnectionRecovery.swift:
- Around line 862-863: Update the documentation above raceAgainstDeadline to
remove the outdated “MainActor-confined” description and accurately state that
settlement is guarded through the actor-backed RPCTaskTimeout/RPCTaskTimeoutRace
implementation. Apply the same correction to the corresponding documentation
around the additionally referenced section.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d582aab2-dd8b-4864-b5c4-1d9fc333a7bc

📥 Commits

Reviewing files that changed from the base of the PR and between 62faea5 and 4d7cb68.

📒 Files selected for processing (2)
  • Packages/iOS/CmuxMobileRPC/Sources/CmuxMobileRPC/RPCTaskTimeout.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+ConnectionRecovery.swift

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

iOS Iroh session flaps every 1-5 min sim↔Mac; auto-redial hangs silently ≥15 min while iroh churns relay DNS (manual Reconnect required)

3 participants