Skip to content

fix: keep iOS runner status transport visible#663

Merged
thymikee merged 1 commit into
mainfrom
codex/ios-runner-status-visible-transport
Jun 2, 2026
Merged

fix: keep iOS runner status transport visible#663
thymikee merged 1 commit into
mainfrom
codex/ios-runner-status-visible-transport

Conversation

@thymikee
Copy link
Copy Markdown
Member

@thymikee thymikee commented Jun 2, 2026

Summary

Status commands now return directly from the iOS runner transport journal while non-status runner commands execute on a dedicated serial queue. This makes accepted/started observable during long XCTest work without app activation, XCTest dispatch, or retry logic on the status path.

Cleanup pass included:

  • Dropped redundant UTF-8 string re-encoding before command decode.
  • Converted malformed runner requests/status probes to INVALID_ARGS with actionable hints.
  • Kept execution failures as COMMAND_FAILED with runner-log guidance.
  • Kept non-status command ordering serial through the dedicated command execution queue.

Acceptance coverage:

  • status can answer while another command is waiting on main-thread XCTest work.
  • status remains journal-only and bypasses app activation/XCTest dispatch/retry logic.
  • Long-running command status reports started before terminal state.
  • Non-status runner commands remain serial through the command execution queue.
  • User-facing request/status errors now include higher-fidelity codes and hints.

Touched files: 4. Scope stayed within iOS runner transport/execution plus one focused smoke fixture.

Validation

  • node --test test/integration/smoke-ios-runner-status-visible-transport.test.ts passed.
  • pnpm check:quick passed.
  • pnpm format passed.
  • pnpm build:xcuitest passed after the original transport work and again after the cleanup pass.
  • pnpm build and pnpm clean:daemon passed before manual runtime validation.
  • iOS simulator manual validation on booted iPhone 17 Pro (C25DBB5B-9254-4293-A8D5-2785C78DE03A) passed with isolated temp state dir /var/folders/65/fz9_2bsj6fzgct46vx226s8c0000gn/T/agent-device-codex-status-visible-transport-1780366621109: long tapSeries command manual-long-1780366641029 was still running when runner status returned in 7 ms with lifecycleState: "started"; second mutating tapSeries completed after the long command (longElapsedMs=13253, secondElapsedMs=15669). Runner session C25DBB5B-9254-4293-A8D5-2785C78DE03A:51693:1780366634495 was stopped, and process inspection showed no stale runner/xcodebuild process.

Known gap: runner status is not exposed as a public daemon/CLI command, so the simulator status probe targeted the runner protocol directly after starting the runner session.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

Size Report

Metric Base Current Diff
JS raw 1.1 MB 1.1 MB -3.0 kB
JS gzip 361.7 kB 360.8 kB -825 B
npm tarball 464.9 kB 464.2 kB -655 B
npm unpacked 1.5 MB 1.5 MB +350 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 25.3 ms 25.5 ms +0.2 ms
CLI --help 39.9 ms 40.2 ms +0.3 ms

Top changed chunks:

Chunk Raw diff Gzip diff
dist/src/2415.js -3.0 kB -825 B

@thymikee thymikee force-pushed the codex/ios-runner-status-visible-transport branch from 1e630d6 to 0589c7c Compare June 2, 2026 02:26
Copy link
Copy Markdown
Member Author

thymikee commented Jun 2, 2026

Review

This is a clean separation of concerns: status answers synchronously on transportQueue while everything else is dispatched to the serial commandExecutionQueue, so a long main-thread XCTest command no longer blocks status probes. The smoke fixture asserting the long:accepted → long:started → second:accepted → long:completed → second:started → second:completed ordering is a good behavioral lock on "status stays visible, mutations stay serial."

I checked the obvious risk — commandJournal is now read on transportQueue (accept, status) while mutated on commandExecutionQueue (start, finish, fail) — and RunnerCommandJournal guards every operation with its internal NSLock, so this is race-free. 👍

Notes:

  1. No double-accept. handleRequestBody now calls commandJournal.accept directly and then executeAccepted (which only does start/finish), bypassing execute for the transport path. Confirmed executeAccepted doesn't re-accept, so acceptance happens exactly once. The standalone execute(command:) still accepts+executes for any other callers (tests) — just make sure nothing routes transport traffic back through execute, or you'd get a redundant accept.

  2. Cleanups are good. Dropping the redundant UTF-8 re-encode (decoding Command straight from body) and mapping malformed requests/oversized bodies to INVALID_ARGS + execution failures to COMMAND_FAILED, each with an actionable hint, is a real fidelity improvement over the old generic "\(error)" messages.

  3. Error mapping in the async block. The catch converting a thrown command error to a 500 COMMAND_FAILED is correct, but note executeAccepted also records commandJournal.fail(...) before rethrowing — so a failed command lands as failed in the journal and a 500 on the wire. That's consistent, just confirming it's intended that both channels report the failure.

LGTM pending CI / simulator validation (noted the runner status isn't exposed as a public command, so this leans on the smoke fixture + manual probe).


Generated by Claude Code

Copy link
Copy Markdown
Member Author

@thymikee thymikee left a comment

Choose a reason for hiding this comment

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

Reviewed current head 0589c7c70. No blocking findings.

The transport/status split keeps status journal-only and leaves non-status commands serialized through the command execution queue. Validation coverage and manual simulator evidence match the acceptance criteria. Keep an eye on downstream rebases because this Swift transport surface may overlap with later runner-retention/status work, but this PR looks good as-is.

@thymikee thymikee merged commit 3ae2472 into main Jun 2, 2026
18 checks passed
@thymikee thymikee deleted the codex/ios-runner-status-visible-transport branch June 2, 2026 03:23
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 2, 2026

PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-02 03:23 UTC

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