fix(swift-ios): passive computers no longer delay cold start#23415
Problem
Cold-launching the SwiftUI client with a healthy active computer and a passive computer that accepts TCP but never answers HTTP keeps “Connecting to T3 Code” visible until the passive shell request times out. The first snapshot waits for every enabled computer, hiding the active computer's ready threads.
Change
Load the active computer's shell before returning the first uncached snapshot, then reconcile and publish passive computers in the existing cancellable startup task. Cached startup also publishes the fresh active shell before loading passive computers. Session and environment generation checks discard obsolete loads; passive startup work no longer holds the active route-recovery counter. Existing multi-environment tests now await passive hydration through client events; a gated regression covers prompt active startup and later passive publication.
Scope and approval
Fixes https://github.com/pingdotgg/t3code/issues/14699
GitCafe: https://git.cafe/pingdotgg/t3code/issues/14699
Triaged bug via the automated issue flow. The issue and maintainer triage establish that active home should appear independently of passive computers. This targets t3code/rebuild-mobile-app-swift, where the native client lives.
Verification
CI on 9a68fd2: 33 checks passed; Contract fixtures and native tests failed. GitCafe exposes no run record, log, summary, or annotations, so the cause remains undiagnosed; no passing native build/test is claimed. The independent Cursor webhook also failed after one retry. Native CI failure requires investigation on macOS or access to the Actions log before merge.
git diff --check: passed.Added
testColdStartDoesNotWaitForAPassiveComputerAndPublishesItAfterwardsin the existingNativeMultiEnvironmentTestssuite. Updated passive-dependent workspace, terminal, and subagent fixtures to await observable hydration. The regression uses a named XCTest expectation and releases its held passive request on failure. These native tests are not run here.Real isolated main servers on loopback ports 47621/47622: both shells returned HTTP 200; with B silent, A returned in 8 ms while B timed out after 6008 ms; with B refused, A returned in 6 ms and B failed in 1 ms. After seeding A through real RPC with one project and one stopped thread, A returned both in 73 ms while B timed out after 6055 ms. This verifies host conditions only, not SwiftUI cold-start behavior. Runtime transcript.
Native command attempted:
cd apps/swift-ios && ./Scripts/ci-test.shexits with[swift-ios-ci] error: missing required command: xcodebuild. Native build, focused tests, and before/after cold-launch timing are unverified — cannot-verify ios-swift on this Linux VM. No red-test failure or passing native test is claimed.Recording fixture matrix and evidence status: all ten native rows remain unverified (0/10 captured). Required recordings cover empty/cached startup with answering, silent, and refused peers, partial cache, route recovery, session switch, and cancellation. No native before/after captures or pixel diffs are available.
Changed surface: native SwiftUI startup and its test fixtures. Web, desktop, React Native, server contracts, provider adapters, and ongoing passive refresh behavior are unaffected.
Models: Claude Opus 5.5 and GPT-6.1 Sol, through T3 Code's Claude Agent and Codex harnesses.
Checks
Failing5
- Build and TypecheckGitHubFailed
- CheckGitHubFailed
- Failed
- Release SmokeGitHubFailed
- Test Server 3GitHubFailed
Added 3 commits
Approvability
Verdict: Approved at dbfa670
Macroscope's review found this PR approvable — Home now becomes usable after the active computer loads, while other saved computers populate asynchronously. Existing cancellation and session safeguards limit stale updates, with no material change to permissions or data operations.
You can add or adjust custom eligibility rules. Learn more.
Thread transfer impact
✅ Thread transfer remains within every enforced ceiling.
ℹ️ No successful
mainbaseline artifact is available yet. This run establishes the initial measurement.
| Provider | Metric | Main baseline | This PR | Impact | PR ceiling | |
|---|---|---|---|---|---|---|
| Codex | Total thread wire | — | 5.0 KiB | — | 6.8 KiB | ✅ |
| Codex | Thread snapshot wire | — | 3.8 KiB | — | 4.9 KiB | ✅ |
| Codex | Live turn WebSocket wire | — | 1.2 KiB | — | 2.0 KiB | ✅ |
| Codex | Live turn WebSocket decoded | — | 20.9 KiB | — | 29.3 KiB | ✅ |
| Codex | Live turn messages | — | 2 | — | 8 | ✅ |
| Claude | Total thread wire | — | 5.0 KiB | — | 6.8 KiB | ✅ |
| Claude | Thread snapshot wire | — | 3.8 KiB | — | 4.9 KiB | ✅ |
| Claude | Live turn WebSocket wire | — | 1.2 KiB | — | 2.0 KiB | ✅ |
| Claude | Live turn WebSocket decoded | — | 21.2 KiB | — | 29.3 KiB | ✅ |
| Claude | Live turn messages | — | 2 | — | 8 | ✅ |
Baseline: unavailable · PR result: dbfa670 · Source CI: failure
Scenario and decoded snapshot size
10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
- Codex decoded thread snapshot: 108.5 KiB
- Claude decoded thread snapshot: 108.8 KiB
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.
Added 3 commits
The automated pipeline stopped on this pull request and will not merge it:
these checks fail on dbfa670d6e, also when run again: Contract fixtures and native tests, Release Smoke, Test Server 3, and the rework changed nothing:
No change pushed; the branch stays at dbfa670d6e. The requested merge of origin/main is wrong for this PR: #23415 targets t3code/rebuild-mobile-app-swift (f021c92cc9), not main, and that branch is 3,655 commits behind main. A trial merge conflicted in AGENTS.md, docs/user/permission-modes.md, pnpm-lock.yaml, scripts/package.json and vite.config.ts, and would have put thousands of unrelated main commits into this PR's diff, so I aborted it. None of the three failing checks comes from the PR's five touched files (NativeFeatureClient.swift and four FeatureTests files). (1) Contract fixtures and native tests: the Xcode build fails compiling apps/swift-ios/Features/Chat/FeatureThreadToolsToolbar.swift, a base-branch file, on ToolbarItemGroup.visibilityPriority and toolbarMinimizationBehavior, which the runner's SDK lacks. main has no apps/swift-ios, so merging it could not fix this. (2) Release Smoke: vp install --lockfile-only fails with ERR_PNPM_UNUSED_PATCH for node-pty@1.2.0-beta.15 and @expo/fingerprint@0.21.5, which is base-branch lockfile and patch state. (3) Test Server 3: apps/server UsageService.test.ts 'reports saved usage of a removed directory only for windows it reaches' gets [] instead of one record, in server code inherited from the base branch. These need fixing on t3code/rebuild-mobile-app-swift (sync it with main and fix the runner Xcode or toolbar APIs), not in this PR. The PR's fix itself is unchanged.
It stays open for a person to finish or close.