perf(ios): check surface hosts inside the snapshot bridge, not with pgrep

TH
1d ago
+1151-630

Summary

Fixes #2751. A warm bridge-served Simulator snapshot has no ready runner, so each capture first spawned the host presence probe (pgrep -f Ɨ2 plus ps).

  • When no runner can answer, the bridge request names the registered host executables. The guest scans the process table in place (sysctl, before and after capture) and refuses with system-surface-host-present (host carries this SIMULATOR_UDID) or system-surface-host-unverified. bridgeFailureDisposition classifies both as a capture-scoped system-surface-host consequence, so they go to the runner and never retire the generation. The host probe is deleted.
  • Rejected (ADR 0004): caching absent until the next action, since a poll after a tap caches it before the host starts; trusting the bridge tree, which shows the occluded app (#2438).
  • stats.backends counts the serving producer (simulator-ax-bridge, not xctest); suite merges sum each run's counts.
  • 33 files.

Validation

Head 364eee6c3b, iPhone Air, iOS 27.0.

  • Tests: exact host processes on the real resolver and acquisition paths (0 pgrep, 3 ps); native scan on live decoys (scoped present, other device absent, unscoped unverified, an exited host absent through processExited, a sibling Name.app/NameHelper or an env value naming the fragment not a match); producer counts and merge; the registry stays inside the guest's host and length bounds. The native scan test is darwin-only; Linux CI skips it.
  • Live, SafariViewService lingering, no runner: guest refused system-surface-host-present (11 ms); runner served. The unverified refusal and the post-capture scan were not run live; see the PR comment for why.
  • Ten-step batch, 3 alternating rounds vs a0e7c7dc23, all no-runner, load 171–201, per-step medians (ms):
step12345678910
main9193999910592918592110
PR39333637383548374239
  • Warm bridge snapshots spawn 0 pgrep and 3 ps, not zero: ps -o lstart= pid-reuse reads (resolver 1, acquisition 2), about 5 ms each. Replacing them needs a new guest identity API.
  • Native scan test, run explicitly on darwin at 364eee6c3b: 6/6 passed (see the PR comment for the list).
  • pnpm check:affected --run --head 364eee6c3b did not reach unit. Both attempts (run-jIkwLy, run-9g6v8s) failed vitest-related on unrelated provider-integration timeouts at host load 300–410. apple-platform-output-guard failed 2/2 on main and passed 2/2 on this branch; apple-app-log-runtime-provider passed 2/2 run alone. The last full pass was 3b6bf10b82 (run-SD1NXc).

šŸ¤– Generated with Claude Code