Repository navigation
Description
Finding
On the GitHub-hosted iOS Smoke job's simulator (ios.yml → "Run fixture-backed iOS simulator E2E smoke", iPhone 17 Pro, iOS 26.2), the XCUITest runner's XCUIApplication(bundleIdentifier:).state reports .runningForeground for the runner's own target app while a foreign app is demonstrably holding the screen.
Consequence inside the runner (RunnerTests+Lifecycle.swift targetNeedsActivation → RunnerTests+CommandExecution.swift prepareActiveCommandContext): the activation preflight is skipped, the capture is served from the backgrounded app, and no targetActivation fact is stamped (#2682) — correctly so, given the state it read. The divergence is between that state read and the device's actual foreground app, not in the disclosure path.
Evidence
- Failed lane run: https://github.com/callstack/agent-device/actions/runs/35460535722/job/105943468492 —
smoke-ios-target-activation.test.ts, "no foreground disclosure within 90000ms of the handoff to com.apple.Preferences". - Uploaded artifact for that run proves both sides of the contradiction: the pre-handoff screenshot shows the session app rendered (
wait label="Gesture lab"had already passed), the post-handoff screenshot shows Settings on screen, and the 31snapshot -iresponses in between each returned a healthy tree forcom.callstack.agentdevicelabin ~450 ms withtargetActivationabsent. - The same runner build on a local simulator (iPhone 17 Pro, iOS 26.2) discloses on the first capture after the identical handoff:
{"reason":"bundle_changed","priorState":"runningBackground","otherActiveApplicationPid":<pid>}, pid resolvable tocom.apple.Preferences/MobileSafariby hostps, and the following capture discloses nothing. - Same-shape symptom on the Android lane of the same job family is unrelated (
wait timed out for text: Automation lab, a fixture launch issue).
Required behavior
Decide which of these the repo believes, and encode it where the claim lives:
- The runner must not trust
XCUIApplication.statealone as the foreground oracle when the session's app can be observed to be backgrounded by another signal (e.g. the runner's ownactiveApplicationsprobe, which already yieldssoleOtherActiveApplicationPid). Then a CI-simulator capture of a backgrounded app activates and discloses like every other host. - Or the runner documents that target-foreground equality is not observable on CI-hosted simulators, and the live activation lane is declared manual/env-gated with the reason stated at the lane (its current state) so no automatic gate ever waits on that assertion.
Completion conditions
- A named owner decides 1 or 2 and records it (ADR or runner doc comment beside
targetNeedsActivation). - If 1: a lane on the CI simulator asserts the capture activates and carries
targetActivation, and it passes. - If 2:
test/integration/smoke-ios-target-activation.test.tsstates the divergence at the lane, and no CI job depends on that assertion.
Non-goals
Not a claim that physical devices misreport foreground; the physical lane for #2682 is tracked in .device-evidence/CHECKLIST.md.
Activity
fix(#2682): make the activation lane manual and record why the CI sim…
fix(#2682): make the activation lane manual and record why the CI sim…
fix(#2682): make the activation lane manual and record why the CI sim…
fix(#2682): make the activation lane manual and record why the CI sim…
feat(ios-runner): disclose target re-activation on the command that c…
thymikee commentedon Oct 9, 2026
Decision: option 2.
XCUIApplication.stateequal to the target's foreground state isn't observable on CI-hosted simulators, and we won't build a foreground oracle from AX signals.soleOtherActiveApplicationPidshows the accessibility session is alive, not who owns the screen, so combining it with an unreliable state read would only create a second unreliable signal.Option 2's completion conditions are already met on main:
test/integration/smoke-ios-target-activation.test.tsis a manual, env-gated lane. Its header states this divergence and cites this issue, and it isn't inios.ymlorreplays-manual.yml.RunnerTests+CommandDispatch.swift, citing iOS CI simulator: XCUIApplication.state reports runningForeground for the runner target while a foreign app is foreground #2696).Closing. Stronger foreground-owner evidence remains open research under #3106. The observe-only consequence of this limitation is tracked in #3348.