Skip to content

refactor(ios-runner): key runner retry decisions on typed failures, not message text - #2831

Merged
thymikee merged 2 commits into
chore/2791-runner-dead-pathsfrom
refactor/2786-runner-typed-retry-codes
Sep 23, 2026
Merged

thymikee merged 2 commits into
chore/2791-runner-dead-pathsfrom
refactor/2786-runner-typed-retry-codes

Conversation

@thymikee

@thymikee thymikee commented Sep 23, 2026

Copy link
Copy Markdown
Member

Summary

Stacked on #2828.

The runner's retry decisions no longer read message text (Swift only, 6 files):

  • shouldRetryResponse reads the runner-internal ErrorPayload.retryableFailure, which ErrorPayload.targetAppUnavailable sets. It is not encoded, so the wire JSON and TS decoding do not change. Only read-only commands reached these responses, so retry behavior is the same.
  • Deleted the "main thread execution timed out" branch: that text is only ever a Swift NSError.
  • Deleted the "timed out" + .snapshot branch: snapshot takes executeSnapshotDispatched and never reaches executeOnMainSafely.

Differences from the issue: the kAXErrorServerNotFound match stays because it is XCTest's own exception reason, which has no typed handle. The completion grep still finds that one commented line.

Closes #2786

Validation

Rebased onto main at a913cb222. Signed macOS host lane: 241/241 at 2d7ec919a. check:affected --run is green at the stack head 60e533284. The evidence below is from before the rebase.

Tested SHA 2700f2f3e.

  • pnpm check:affected --run: green.
  • Signed macOS host lane: 239/239 tests executed, which matches the source count. check:xctest-selection passes. The iOS simulator build succeeded.
  • Regression evidence: with the old Lifecycle.swift restored, the new retry tests fail.
  • Live check on the iPhone 17 Pro simulator: open, snapshot -i, screenshot, find get text, and close all passed. The unavailable-target retry was not reproduced live; unit tests cover it.
  • Review (/code-review high): fixed the Models test placement, added a field-drift check, and switched to the shared fixture. Rejected adding a wire code (it changes the AppError code), restructuring the catcher (out of scope), and logging the retry reason (single case).

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Sep 23, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
Installed (including dependencies) 4.80 MB 4.80 MB -31 B
Package (unpacked) 4.80 MB 4.80 MB -31 B
Package (download) 1.43 MB 1.43 MB +122 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 26.7 ms 27.2 ms +0.4 ms
CLI --help 81.1 ms 80.3 ms -0.8 ms

@thymikee

Copy link
Copy Markdown
Member Author

Reviewed at 2700f2f. Retry decisions now use typed failure reasons instead of message text, and the retry outcomes stay the same. The code looks right.

The Smoke Tests failure at live-snapshot-depth-frontier.ts:126 is unrelated. It also fails on main and #2832 fixes it.

This needs #2828 to merge first.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Sep 23, 2026
@thymikee
thymikee added this pull request to stack #2830 September 23, 2026 17:20
thymikee and others added 2 commits September 23, 2026 19:48
…res, not message text

The response retry now reads a runner-internal `retryableFailure` that the target-app-unavailable
responses carry from the place they are produced; it is excluded from encoding so the host sees the
same error JSON. The exception retry drops the main-thread-timeout branch (that text is only ever a
Swift NSError, never an ObjC exception reason) and the snapshot timeout branch (snapshot dispatches
through its own recovery loop and never reaches the exception catcher).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Moves the wire-shape pin to a Models test file and adds a field-drift check: every stored
ErrorPayload field except the runner-internal retryable failure must reach the encoded JSON.
The exception-retry test builds its commands through the shared fixture helper.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@thymikee
thymikee force-pushed the refactor/2786-runner-typed-retry-codes branch from 2700f2f to 2d7ec91 Compare September 23, 2026 18:08
@thymikee
thymikee merged commit 4bce8fa into main Sep 23, 2026
24 of 35 checks passed
@thymikee
thymikee deleted the refactor/2786-runner-typed-retry-codes branch September 23, 2026 18:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(ios-runner): Swift retry decisions keyed on message text → typed codes

1 participant