feat(perf): time every iOS command against the fixture app

Merged
TH
3d ago
+3181-343

Summary

pnpm perf --platform ios --udid <udid> times every catalog command that the iOS simulator serves, against the fixture app. The suite has 105 steps in 7 scenarios: lifecycle, home reads, catalog, form, automation, heavy feed, and session. The report lists 16 excluded commands with a reason, and ios-suite.test.ts keeps measured + excluded equal to the catalog.

Each sample records wall time, the client daemon_request time, and a profile from its --debug request log. The output is summary.json, report.md, and the raw logs. The nightly workflow and perf:compare come from #3886, which merged into this branch.

  • home-reads/snapshot-forced-tree pins the XCTest tree through the SDK. Its expectation requires tree with the runner's requested-backend code, so a degraded capture fails instead of becoming a baseline.
  • Heavy-feed longpress, swipe, and back fail today (XCTest kAXErrorIllegalArgument). They stay as measured steps so that a fix shows as fixed.
  • Run metadata uses the benchmark's host readers, moved to scripts/lib/bench-host.ts. host-kit and the daemon client export the phase names that the profiler reads.

46 files. This PR is rebased on main after #3884, and main is merged in for #3892.

Validation

  • At 8958314a16, I ran home-reads,heavy-feed locally (3 rounds + 1 warmup, iPhone 17 Pro, iOS 27.0). snapshot-forced-tree was served by tree/healthy/requested-backend ร—3. The only failures were the 3 heavy-feed gaps. The evidence is in the PR comments.
  • At aed5aa7e94, --scenarios automation ran clean (1 warmup + 3 rounds). logs-start โ†’ logs-stop passed 3/3 with no daemon_stuck, now that the #3892 workaround is removed.
  • vitest scripts/perf scripts/lib scripts/ios-snapshot-benchmark: passed.
  • pnpm check:affected --run --head 8958314a16: passed at aed5aa7e94 (exactCommit: true, FAIL-OPEN full set: 36 passed, 25 GitHub-authoritative skips).
  • GitHub owns the native, device, and coverage lanes.

๐Ÿค– Generated with Claude Code