From 50ec7a3e4119292098dc368ffcab8fad25d2a933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 09:32:46 +0200 Subject: [PATCH 01/29] perf(ios): add bounded Simulator AX bridge spike --- apple/macos-helper/Package.swift | 7 + .../ProcessMetrics.swift | 48 +++ .../Protocol.swift | 137 ++++++++ .../RawAccessibility.swift | 260 ++++++++++++++ .../AgentDeviceIosAxBridgeSpike/main.swift | 73 ++++ package.json | 2 + scripts/ios-ax-bridge-spike/README.md | 31 ++ scripts/ios-ax-bridge-spike/adapter.ts | 323 +++++++++++++++++ scripts/ios-ax-bridge-spike/config.ts | 213 ++++++++++++ scripts/ios-ax-bridge-spike/decision.test.ts | 31 ++ scripts/ios-ax-bridge-spike/decision.ts | 211 ++++++++++++ .../framed-process.test.ts | 105 ++++++ scripts/ios-ax-bridge-spike/framed-process.ts | 213 ++++++++++++ scripts/ios-ax-bridge-spike/lifecycle.test.ts | 21 ++ scripts/ios-ax-bridge-spike/lifecycle.ts | 127 +++++++ scripts/ios-ax-bridge-spike/limits.test.ts | 67 ++++ scripts/ios-ax-bridge-spike/limits.ts | 229 ++++++++++++ .../ios-ax-bridge-spike/preferences.test.ts | 22 ++ scripts/ios-ax-bridge-spike/preferences.ts | 254 ++++++++++++++ .../ios-ax-bridge-spike/presentation.test.ts | 24 ++ scripts/ios-ax-bridge-spike/presentation.ts | 96 ++++++ scripts/ios-ax-bridge-spike/protocol.ts | 187 ++++++++++ scripts/ios-ax-bridge-spike/report.ts | 176 ++++++++++ scripts/ios-ax-bridge-spike/run.ts | 318 +++++++++++++++++ scripts/ios-ax-bridge-spike/runner.ts | 326 ++++++++++++++++++ .../ios-ax-bridge-spike/sample-evidence.ts | 135 ++++++++ scripts/ios-ax-bridge-spike/types.ts | 223 ++++++++++++ vitest.config.ts | 5 +- 28 files changed, 3862 insertions(+), 2 deletions(-) create mode 100644 apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift create mode 100644 apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift create mode 100644 apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift create mode 100644 apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/main.swift create mode 100644 scripts/ios-ax-bridge-spike/README.md create mode 100644 scripts/ios-ax-bridge-spike/adapter.ts create mode 100644 scripts/ios-ax-bridge-spike/config.ts create mode 100644 scripts/ios-ax-bridge-spike/decision.test.ts create mode 100644 scripts/ios-ax-bridge-spike/decision.ts create mode 100644 scripts/ios-ax-bridge-spike/framed-process.test.ts create mode 100644 scripts/ios-ax-bridge-spike/framed-process.ts create mode 100644 scripts/ios-ax-bridge-spike/lifecycle.test.ts create mode 100644 scripts/ios-ax-bridge-spike/lifecycle.ts create mode 100644 scripts/ios-ax-bridge-spike/limits.test.ts create mode 100644 scripts/ios-ax-bridge-spike/limits.ts create mode 100644 scripts/ios-ax-bridge-spike/preferences.test.ts create mode 100644 scripts/ios-ax-bridge-spike/preferences.ts create mode 100644 scripts/ios-ax-bridge-spike/presentation.test.ts create mode 100644 scripts/ios-ax-bridge-spike/presentation.ts create mode 100644 scripts/ios-ax-bridge-spike/protocol.ts create mode 100644 scripts/ios-ax-bridge-spike/report.ts create mode 100644 scripts/ios-ax-bridge-spike/run.ts create mode 100644 scripts/ios-ax-bridge-spike/runner.ts create mode 100644 scripts/ios-ax-bridge-spike/sample-evidence.ts create mode 100644 scripts/ios-ax-bridge-spike/types.ts diff --git a/apple/macos-helper/Package.swift b/apple/macos-helper/Package.swift index 82cd920325..9bae526423 100644 --- a/apple/macos-helper/Package.swift +++ b/apple/macos-helper/Package.swift @@ -9,10 +9,17 @@ let package = Package( name: "agent-device-macos-helper", targets: ["AgentDeviceMacOSHelper"] ), + .executable( + name: "agent-device-ios-ax-bridge-spike", + targets: ["AgentDeviceIosAxBridgeSpike"] + ), ], targets: [ .executableTarget( name: "AgentDeviceMacOSHelper" ), + .executableTarget( + name: "AgentDeviceIosAxBridgeSpike" + ), ] ) diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift new file mode 100644 index 0000000000..4ebb2f0e1e --- /dev/null +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift @@ -0,0 +1,48 @@ +import Darwin +import Foundation + +struct SpikeProcessMetrics { + let cpuMs: Double + let memoryBytes: Int64? +} + +func spikeProcessMetrics(since start: rusage) -> SpikeProcessMetrics { + var current = rusage() + getrusage(RUSAGE_SELF, ¤t) + let startCpu = cpuMilliseconds(start) + let currentCpu = cpuMilliseconds(current) + return SpikeProcessMetrics( + cpuMs: max(0, currentCpu - startCpu), + memoryBytes: residentMemoryBytes() + ) +} + +func currentResourceUsage() -> rusage { + var usage = rusage() + getrusage(RUSAGE_SELF, &usage) + return usage +} + +private func cpuMilliseconds(_ usage: rusage) -> Double { + let user = Double(usage.ru_utime.tv_sec) * 1_000 + Double(usage.ru_utime.tv_usec) / 1_000 + let system = Double(usage.ru_stime.tv_sec) * 1_000 + Double(usage.ru_stime.tv_usec) / 1_000 + return user + system +} + +private func residentMemoryBytes() -> Int64? { + var info = mach_task_basic_info() + var count = mach_msg_type_number_t( + MemoryLayout.size / MemoryLayout.size + ) + let status = withUnsafeMutablePointer(to: &info) { pointer in + pointer.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { rebound in + task_info( + mach_task_self_, + task_flavor_t(MACH_TASK_BASIC_INFO), + rebound, + &count + ) + } + } + return status == KERN_SUCCESS ? Int64(info.resident_size) : nil +} diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift new file mode 100644 index 0000000000..7849cb75a9 --- /dev/null +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift @@ -0,0 +1,137 @@ +import Foundation + +struct SpikeRequest: Decodable { + let version: Int + let id: String + let candidate: String + let simulatorUdid: String + let state: String + let screen: String + let appBundleId: String + let targetProcessId: Int32? + let expectedTargetGeneration: String? + let limits: SpikeLimits +} + +struct SpikeLimits: Decodable { + let maxRequestBytes: Int + let maxResponseBytes: Int + let maxNodes: Int + let maxTraversalDepth: Int + let maxCpuMs: Int + let maxMemoryBytes: Int + let maxDurationMs: Int +} + +struct SpikeRect: Encodable { + let x: Double + let y: Double + let width: Double + let height: Double +} + +struct SpikeNode: Encodable { + let id: String + let parentId: String? + let role: String? + let subrole: String? + let label: String? + let value: String? + let identifier: String? + let frame: SpikeRect? + let enabled: Bool? + let selected: Bool? + let focused: Bool? +} + +struct SpikeViewport: Encodable { + let kind: String + let rect: SpikeRect? + let reason: String? + let coordinateSpace: String? + let source: String? +} + +struct SpikeResidue: Encodable { + let kind: String + let fields: [String]? + let dimension: String? + let limit: Int? + let fact: String? + let expected: String? + let observed: String? +} + +struct SpikeAcquisition: Encodable { + let targetId: String + let targetGeneration: String? + let nodes: [SpikeNode] + let viewport: SpikeViewport + let truncated: Bool + let residue: [SpikeResidue] +} + +struct SpikeFailure: Encodable { + let kind: String + let code: String? + let expectedTargetGeneration: String? + let observedTargetGeneration: String? +} + +struct SpikeMetrics: Encodable { + let requestBytes: Int + let responseBytes: Int + let nodeCount: Int + let maxTraversalDepth: Int + let cpuMs: Double? + let memoryBytes: Int64? + let durationMs: Double +} + +struct SpikeResponse: Encodable { + let version: Int + let id: String + let candidate: String + let ok: Bool + let acquisition: SpikeAcquisition? + let failure: SpikeFailure? + let metrics: SpikeMetrics +} + +struct SpikeCapture { + let acquisition: SpikeAcquisition? + let failure: SpikeFailure? + let maxTraversalDepth: Int +} + +func unsupportedCapture( + code: String, + observedTargetGeneration: String? = nil +) -> SpikeCapture { + SpikeCapture( + acquisition: nil, + failure: SpikeFailure( + kind: "unsupported-mechanism", + code: code, + expectedTargetGeneration: nil, + observedTargetGeneration: observedTargetGeneration + ), + maxTraversalDepth: 0 + ) +} + +func failureResponse( + request: SpikeRequest, + failure: SpikeFailure, + metrics: SpikeMetrics +) -> SpikeResponse { + SpikeResponse( + version: 1, + id: request.id, + candidate: request.candidate, + ok: false, + acquisition: nil, + failure: failure, + metrics: metrics + ) +} diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift new file mode 100644 index 0000000000..bbd94d8e4b --- /dev/null +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift @@ -0,0 +1,260 @@ +import AppKit +import ApplicationServices +import Foundation + +private struct RawTraversalState { + var nodes: [SpikeNode] = [] + var visited: [AXUIElement] = [] + var maxDepth = 0 + var hitNodeLimit = false + var hitDepthLimit = false +} + +func capturePublicAccessibility(request: SpikeRequest) -> SpikeCapture { + guard request.version == 1, request.candidate == "public-macos-ax" else { + return unsupportedCapture(code: "candidate-not-supported") + } + guard AXIsProcessTrusted() else { + return unsupportedCapture(code: "host-accessibility-permission") + } + guard let application = targetApplication(request: request) else { + return unsupportedCapture(code: "target-application-unavailable") + } + + let generation = targetGeneration(application) + if let expected = request.expectedTargetGeneration, expected != generation { + return SpikeCapture( + acquisition: nil, + failure: SpikeFailure( + kind: "stale-generation", + code: "target-generation-mismatch", + expectedTargetGeneration: expected, + observedTargetGeneration: generation + ), + maxTraversalDepth: 0 + ) + } + + let applicationElement = AXUIElementCreateApplication(application.processIdentifier) + let windows = axWindows(applicationElement) + guard !windows.isEmpty else { + return unsupportedCapture( + code: "target-has-no-accessibility-windows", + observedTargetGeneration: generation + ) + } + + var state = RawTraversalState() + _ = appendRawNode( + applicationElement, + parentId: nil, + depth: 0, + limits: request.limits, + state: &state + ) + let viewport = windows.compactMap { axRect($0) }.first.map { + SpikeViewport( + kind: "reported", + rect: $0, + reason: nil, + coordinateSpace: "host-screen", + source: "AXPosition+AXSize" + ) + } ?? SpikeViewport( + kind: "missing", + rect: nil, + reason: "not-provided", + coordinateSpace: nil, + source: nil + ) + var residue: [SpikeResidue] = [] + if state.hitNodeLimit { + residue.append( + SpikeResidue( + kind: "truncated", + fields: nil, + dimension: "nodes", + limit: request.limits.maxNodes, + fact: nil, + expected: nil, + observed: nil + ) + ) + } + if state.hitDepthLimit { + residue.append( + SpikeResidue( + kind: "truncated", + fields: nil, + dimension: "depth", + limit: request.limits.maxTraversalDepth, + fact: nil, + expected: nil, + observed: nil + ) + ) + } + if viewport.kind == "missing" { + residue.append( + SpikeResidue( + kind: "missing-viewport", + fields: nil, + dimension: nil, + limit: nil, + fact: nil, + expected: nil, + observed: nil + ) + ) + } + return SpikeCapture( + acquisition: SpikeAcquisition( + targetId: "simulator:\(request.simulatorUdid)", + targetGeneration: generation, + nodes: state.nodes, + viewport: viewport, + truncated: state.hitNodeLimit || state.hitDepthLimit, + residue: residue + ), + failure: nil, + maxTraversalDepth: state.maxDepth + ) +} + +private func targetApplication(request: SpikeRequest) -> NSRunningApplication? { + if let processId = request.targetProcessId, + let application = NSRunningApplication(processIdentifier: processId), + !application.isTerminated + { + return application + } + return NSRunningApplication.runningApplications( + withBundleIdentifier: request.appBundleId + ).first(where: { !$0.isTerminated }) +} + +private func targetGeneration(_ application: NSRunningApplication) -> String { + let launch = application.launchDate?.timeIntervalSince1970.description ?? "unknown" + return "pid:\(application.processIdentifier):launch:\(launch)" +} + +@discardableResult +private func appendRawNode( + _ element: AXUIElement, + parentId: String?, + depth: Int, + limits: SpikeLimits, + state: inout RawTraversalState +) -> String? { + if state.visited.contains(where: { CFEqual($0, element) }) { return nil } + guard state.nodes.count < limits.maxNodes else { + state.hitNodeLimit = true + return nil + } + state.visited.append(element) + state.maxDepth = max(state.maxDepth, depth) + let id = "n\(state.nodes.count)" + state.nodes.append( + SpikeNode( + id: id, + parentId: parentId, + role: axString(element, kAXRoleAttribute as String), + subrole: axString(element, kAXSubroleAttribute as String), + label: axString(element, kAXTitleAttribute as String) + ?? axString(element, kAXDescriptionAttribute as String), + value: axString(element, kAXValueAttribute as String), + identifier: axString(element, "AXIdentifier"), + frame: axRect(element), + enabled: axBool(element, kAXEnabledAttribute as String), + selected: axBool(element, kAXSelectedAttribute as String), + focused: axBool(element, kAXFocusedAttribute as String) + ) + ) + guard depth < limits.maxTraversalDepth else { + if !axChildren(element).isEmpty { state.hitDepthLimit = true } + return id + } + for child in axChildren(element) { + _ = appendRawNode( + child, + parentId: id, + depth: depth + 1, + limits: limits, + state: &state + ) + } + return id +} + +private func axWindows(_ element: AXUIElement) -> [AXUIElement] { + axElements(element, attribute: kAXWindowsAttribute as String) +} + +private func axChildren(_ element: AXUIElement) -> [AXUIElement] { + axElements(element, attribute: kAXChildrenAttribute as String) +} + +private func axElements(_ element: AXUIElement, attribute: String) -> [AXUIElement] { + var value: CFTypeRef? + guard AXUIElementCopyAttributeValue(element, attribute as CFString, &value) == .success, + let elements = value as? [AXUIElement] + else { + return [] + } + return elements +} + +private func axString(_ element: AXUIElement, _ attribute: String) -> String? { + var value: CFTypeRef? + guard AXUIElementCopyAttributeValue(element, attribute as CFString, &value) == .success, + let text = value as? String + else { + return nil + } + let trimmed = text.trimmingCharacters(in: .whitespacesAndNewlines) + return trimmed.isEmpty ? nil : trimmed +} + +private func axBool(_ element: AXUIElement, _ attribute: String) -> Bool? { + var value: CFTypeRef? + guard AXUIElementCopyAttributeValue(element, attribute as CFString, &value) == .success, + let number = value as? NSNumber + else { + return nil + } + return number.boolValue +} + +private func axRect(_ element: AXUIElement) -> SpikeRect? { + var positionValue: CFTypeRef? + var sizeValue: CFTypeRef? + guard AXUIElementCopyAttributeValue(element, kAXPositionAttribute as CFString, &positionValue) == .success, + AXUIElementCopyAttributeValue(element, kAXSizeAttribute as CFString, &sizeValue) == .success, + let position = axPoint(positionValue), + let size = axSize(sizeValue) + else { + return nil + } + return SpikeRect( + x: Double(position.x), + y: Double(position.y), + width: Double(size.width), + height: Double(size.height) + ) +} + +private func axPoint(_ value: CFTypeRef?) -> CGPoint? { + guard let value, CFGetTypeID(value) == AXValueGetTypeID() else { return nil } + let axValue = value as! AXValue + guard AXValueGetType(axValue) == .cgPoint else { return nil } + var point = CGPoint.zero + return AXValueGetValue(axValue, .cgPoint, &point) ? point : nil +} + +private func axSize(_ value: CFTypeRef?) -> CGSize? { + guard let value, CFGetTypeID(value) == AXValueGetTypeID() else { return nil } + let axValue = value as! AXValue + guard AXValueGetType(axValue) == .cgSize else { return nil } + var size = CGSize.zero + return AXValueGetValue(axValue, .cgSize, &size) ? size : nil +} diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/main.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/main.swift new file mode 100644 index 0000000000..40f0e5421a --- /dev/null +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/main.swift @@ -0,0 +1,73 @@ +import Foundation + +let encoder = JSONEncoder() +encoder.outputFormatting = [.sortedKeys] +let decoder = JSONDecoder() +var inputBuffer = Data() + +while true { + let chunk = FileHandle.standardInput.readData(ofLength: 4 * 1024) + if chunk.isEmpty { break } + inputBuffer.append(chunk) + while let newline = inputBuffer.firstIndex(of: 0x0A) { + let line = inputBuffer.subdata(in: inputBuffer.startIndex.. 64 * 1024 { + writeLog("request frame exceeded 65536 bytes") + inputBuffer.removeAll(keepingCapacity: true) + } +} + +if !inputBuffer.isEmpty { handleRequest(inputBuffer) } + +func handleRequest(_ line: Data) { + guard line.count <= 64 * 1024 else { + writeLog("discarded oversized request frame") + return + } + let start = currentResourceUsage() + let started = DispatchTime.now().uptimeNanoseconds + do { + let request = try decoder.decode(SpikeRequest.self, from: line) + writeLog("capture id=\(request.id) candidate=\(request.candidate) screen=\(request.screen)") + let capture = capturePublicAccessibility(request: request) + let elapsedMs = Double(DispatchTime.now().uptimeNanoseconds - started) / 1_000_000 + let processMetrics = spikeProcessMetrics(since: start) + let baseMetrics = SpikeMetrics( + requestBytes: line.count + 1, + responseBytes: 0, + nodeCount: capture.acquisition?.nodes.count ?? 0, + maxTraversalDepth: capture.maxTraversalDepth, + cpuMs: processMetrics.cpuMs, + memoryBytes: processMetrics.memoryBytes, + durationMs: elapsedMs + ) + let response = capture.failure.map { + failureResponse(request: request, failure: $0, metrics: baseMetrics) + } ?? SpikeResponse( + version: 1, + id: request.id, + candidate: request.candidate, + ok: true, + acquisition: capture.acquisition, + failure: nil, + metrics: baseMetrics + ) + writeResponse(response) + } catch { + writeLog("malformed request frame") + } +} + +func writeResponse(_ response: SpikeResponse) { + guard let data = try? encoder.encode(response) else { return } + FileHandle.standardOutput.write(data) + FileHandle.standardOutput.write(Data([0x0A])) +} + +func writeLog(_ message: String) { + let data = Data("[ios-ax-spike] \(message)\n".utf8) + FileHandle.standardError.write(data) +} diff --git a/package.json b/package.json index 03faecdba2..3ee3a178e7 100644 --- a/package.json +++ b/package.json @@ -106,6 +106,7 @@ "package:android-ime-helper": "AGENT_DEVICE_ANDROID_HELPER=ime sh ./scripts/package-android-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-ime-helper", "package:android-ime-helper:npm": "rm -rf android/ime-helper/dist && AGENT_DEVICE_ANDROID_HELPER=ime sh ./scripts/package-android-helper.sh $(node -p \"require('./package.json').version\") android/ime-helper/dist", "build:macos-helper": "node --experimental-strip-types scripts/swift-toolchain-tmpdir.ts swift build -c release --package-path apple/macos-helper", + "build:ios-ax-bridge-spike": "node --experimental-strip-types scripts/swift-toolchain-tmpdir.ts swift build -c release --package-path apple/macos-helper --product agent-device-ios-ax-bridge-spike", "build:macos-helper:clean": "node --experimental-strip-types scripts/swift-toolchain-tmpdir.ts swift package --package-path apple/macos-helper clean && pnpm build:macos-helper", "build:package": "pnpm build && pnpm build:xcuitest:ios && pnpm build:xcuitest:macos && pnpm build:xcuitest:tvos && pnpm build:xcuitest:visionos && pnpm build:macos-helper:clean && pnpm package:apple-runner:npm && pnpm build:android", "package:npm": "pnpm build:package && pnpm check:package", @@ -120,6 +121,7 @@ "size": "node scripts/size-report.mjs", "perf": "node --experimental-strip-types scripts/perf/run.ts", "bench:ios-snapshot": "node --experimental-strip-types scripts/ios-snapshot-benchmark/run.ts", + "bench:ios-ax-bridge": "node --experimental-strip-types scripts/ios-ax-bridge-spike/run.ts", "bench:ios-snapshot:deep-button": "node --experimental-strip-types scripts/ios-snapshot-benchmark/deep-button.ts", "mutation:run": "node --experimental-strip-types scripts/mutation/run.ts", "mutation:check": "node --experimental-strip-types scripts/mutation/run.ts --no-run", diff --git a/scripts/ios-ax-bridge-spike/README.md b/scripts/ios-ax-bridge-spike/README.md new file mode 100644 index 0000000000..e1efcecab5 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/README.md @@ -0,0 +1,31 @@ +# iOS Simulator AX bridge spike + +This bounded harness supplies the decision evidence for [#2192](https://github.com/callstack/agent-device/issues/2192). It compares host-side public macOS AX, an explicitly configured private CoreSimulator AX tool, and the #2189 XCTest control baseline behind one framed acquisition adapter. It does not select a production backend or change daemon, runner, open, relaunch, proxy, interaction, or public CLI behavior. + +Build the repository and the macOS helper first: + +```sh +pnpm install --frozen-lockfile +pnpm build +pnpm build:ios-ax-bridge-spike +``` + +Use a newly created, task-owned iOS Simulator. Xcode 27 hosts should target the DeviceHub process explicitly when using the public candidate: + +```sh +pnpm bench:ios-ax-bridge -- \ + --udid SIMULATOR_UDID \ + --target-process-id DEVICEHUB_PID \ + --candidate public-macos-ax,private-coresimulator-ax,xctest-control \ + --state cold-cold,cold,warm,relaunch \ + --screen quiet,list,nested-scroll,alert,system-surface,xctest-stress \ + --samples 20 \ + --apply-preferences \ + --out .tmp/ios-ax-bridge-spike.v1.json +``` + +The default candidate set, state set, screen set, and sample minimums come from the #2189 benchmark definitions. Each request carries a target generation and fixed request, response, node-count, traversal-depth, CPU, memory, and duration bounds. The native helper sends one newline-delimited response per request and writes diagnostics to stderr only. The report keeps raw nodes, viewport evidence, target lineage, truncation, residue, resource metrics, stderr, and a separate prototype presentation measurement. + +`--apply-preferences` is the only way the experiment edits Simulator preference plists. The Simulator must be shutdown; the harness records exact plist hashes and targeted key changes, then restores the original bytes before reporting. The keys are not production defaults. Omit `--private-tool` unless a disposable, compatible private mechanism is being tested; the harness never invents a private fallback. + +The harness fails closed. It reports `NO-GO` when a candidate is unsupported, unavailable, unreadable, stale, over a bound, below the sample minimum, or when crash/timeout/cancellation recovery is not typed and recovered. It stops before reporting timings if the fixture app cannot be prepared deterministically. The adjacent JSON and Markdown report are the decision artifact; no production route should be implemented from a `NO-GO` run. diff --git a/scripts/ios-ax-bridge-spike/adapter.ts b/scripts/ios-ax-bridge-spike/adapter.ts new file mode 100644 index 0000000000..ec31816f4d --- /dev/null +++ b/scripts/ios-ax-bridge-spike/adapter.ts @@ -0,0 +1,323 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { performance } from 'node:perf_hooks'; +import { + classifyFailure, + snapshotFixture, + type CliContext, + type CliResult, +} from '../ios-snapshot-benchmark/command.ts'; +import { runFramedBatch, type FramedProcessSpec } from './framed-process.ts'; +import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; +import { failureResponse } from './protocol.ts'; +import type { + CandidateId, + RawAcquiredNode, + ResourceLimits, + SpikeRequest, + SpikeResponse, +} from './types.ts'; + +export type AcquisitionAdapter = Readonly<{ + candidate: CandidateId; + acquireBatch( + requests: readonly SpikeRequest[], + options?: Readonly<{ signal?: AbortSignal }>, + ): Promise; +}>; + +export type AcquisitionBatchResult = Readonly<{ + responses: readonly SpikeResponse[]; + stderr: string; +}>; + +export type AdapterOptions = Readonly<{ + repoRoot: string; + privateTool?: string; + helperPath?: string; + limits?: ResourceLimits; +}>; + +export function createPublicMacOsAxAdapter(options: AdapterOptions): AcquisitionAdapter { + const limits = options.limits ?? DEFAULT_SPIKE_LIMITS; + const helperPath = + options.helperPath ?? + path.join( + options.repoRoot, + 'apple', + 'macos-helper', + '.build', + 'out', + 'Products', + 'Release', + 'agent-device-ios-ax-bridge-spike', + ); + return framedAdapter('public-macos-ax', helperPath, limits); +} + +export function createPrivateCoreSimulatorAxAdapter(options: AdapterOptions): AcquisitionAdapter { + const limits = options.limits ?? DEFAULT_SPIKE_LIMITS; + if (!options.privateTool || !fs.existsSync(options.privateTool)) { + return unsupportedAdapter('private-coresimulator-ax', 'private-tool-unavailable', limits); + } + return framedAdapter('private-coresimulator-ax', options.privateTool, limits); +} + +export function createXCTestControlAdapter( + contextFor: (request: SpikeRequest) => CliContext, +): AcquisitionAdapter { + return { + candidate: 'xctest-control', + async acquireBatch(requests) { + return { + responses: requests.map((request) => { + const started = performance.now(); + return controlResponse( + request, + snapshotFixture(contextFor(request)), + performance.now() - started, + ); + }), + stderr: '', + }; + }, + }; +} + +function framedAdapter( + candidate: Exclude, + file: string, + limits: ResourceLimits, +): AcquisitionAdapter { + const spec: FramedProcessSpec = { file }; + return { + candidate, + async acquireBatch(requests, options = {}) { + if (!fs.existsSync(file)) { + return { + responses: requests.map((request) => + failureResponse(request, { + kind: 'unsupported-mechanism', + code: 'adapter-binary-unavailable', + }), + ), + stderr: '', + }; + } + const result = await runFramedBatch(spec, requests, { ...options, limits }); + return result; + }, + }; +} + +function unsupportedAdapter( + candidate: Exclude, + code: string, + limits: ResourceLimits, +): AcquisitionAdapter { + return { + candidate, + async acquireBatch(requests) { + return { + responses: requests.map((request) => + failureResponse( + request, + { kind: 'unsupported-mechanism', code }, + { + requestBytes: Buffer.byteLength(JSON.stringify({ ...request, limits })) + 1, + }, + ), + ), + stderr: '', + }; + }, + }; +} + +function controlResponse( + request: SpikeRequest, + result: CliResult, + durationMs: number, +): SpikeResponse { + const snapshot = readControlSnapshot(result.payload); + return result.ok && snapshot + ? successfulControlResponse(request, snapshot, result, durationMs) + : failedControlResponse(request, result); +} + +function successfulControlResponse( + request: SpikeRequest, + snapshot: ControlSnapshot, + result: CliResult, + durationMs: number, +): SpikeResponse { + const acquisition = { + targetId: `simulator:${request.simulatorUdid}`, + targetGeneration: snapshot.targetGeneration, + nodes: snapshot.nodes, + viewport: snapshot.viewport, + truncated: snapshot.truncated, + residue: [{ kind: 'missing-viewport', reason: 'not-provided' }], + } as const; + return { + version: 1, + id: request.id, + candidate: request.candidate, + ok: true, + acquisition, + metrics: { + requestBytes: 0, + responseBytes: Buffer.byteLength(result.stdout), + nodeCount: acquisition.nodes.length, + maxTraversalDepth: 0, + cpuMs: null, + memoryBytes: process.memoryUsage().rss, + durationMs, + }, + }; +} + +function failedControlResponse(request: SpikeRequest, result: CliResult): SpikeResponse { + const failure = classifyFailure(result.payload, result); + return failureResponse( + request, + { + kind: controlFailureKind(failure.category), + ...(failure.code ? { code: failure.code } : {}), + }, + { + responseBytes: Buffer.byteLength(result.stdout), + durationMs: result.wallClockMs, + }, + ); +} + +function controlFailureKind( + category: string, +): 'timeout' | 'stale-generation' | 'transport-failure' { + if (category === 'timeout') return 'timeout'; + if (category === 'stale-generation') return 'stale-generation'; + return 'transport-failure'; +} + +type ControlSnapshot = { + nodes: RawAcquiredNode[]; + targetGeneration: string | null; + truncated: boolean; + viewport: { kind: 'missing'; reason: 'not-provided' }; +}; + +function readControlSnapshot(value: unknown): ControlSnapshot | undefined { + const snapshot = findSnapshotRecord(value); + if (!snapshot || !Array.isArray(snapshot.nodes)) return undefined; + const nodes = snapshot.nodes.flatMap((rawNode) => toRawNode(rawNode)); + return { + nodes, + targetGeneration: readGeneration(snapshot), + truncated: snapshot.truncated === true, + viewport: { kind: 'missing', reason: 'not-provided' }, + }; +} + +function findSnapshotRecord(value: unknown): Record | undefined { + const root = record(value); + return root ? snapshotFromRoot(root) : undefined; +} + +function snapshotFromRoot(root: Record): Record | undefined { + const stepData = firstBatchStep(record(root.data)); + return snapshotFromStep(stepData); +} + +function snapshotFromStep( + stepData: Record | undefined, +): Record | undefined { + if (!stepData) return undefined; + return record(stepData.snapshot) ?? stepData; +} + +function firstBatchStep( + data: Record | undefined, +): Record | undefined { + if (!data) return undefined; + const results = data.results; + return Array.isArray(results) ? firstResultData(results, data) : data; +} + +function firstResultData( + results: readonly unknown[], + fallback: Record, +): Record { + const first = record(results[0]); + return record(first?.data) ?? fallback; +} + +function toRawNode(value: unknown): RawAcquiredNode[] { + const node = record(value); + if (!node || typeof node.index !== 'number') return []; + return [ + { + id: String(node.index), + ...rawNodeFacts(node), + }, + ]; +} + +function rawNodeFacts(node: Record): Partial { + return { + ...optionalParent(node.parentIndex), + ...optionalString(node, 'role'), + ...optionalString(node, 'subrole'), + ...optionalString(node, 'label'), + ...optionalString(node, 'value'), + ...optionalString(node, 'identifier'), + ...optionalRect(node.rect), + ...optionalBoolean(node, 'enabled'), + ...optionalBoolean(node, 'selected'), + ...optionalBoolean(node, 'focused'), + }; +} + +function optionalParent(value: unknown): Partial { + return typeof value === 'number' ? { parentId: String(value) } : {}; +} + +function readGeneration(snapshot: Record): string | null { + const value = snapshot.refsGeneration ?? snapshot.targetGeneration; + return typeof value === 'string' || typeof value === 'number' ? String(value) : null; +} + +function optionalString( + recordValue: Record, + key: 'role' | 'subrole' | 'label' | 'value' | 'identifier', +): Partial { + return typeof recordValue[key] === 'string' ? { [key]: recordValue[key] } : {}; +} + +function optionalBoolean( + recordValue: Record, + key: 'enabled' | 'selected' | 'focused', +): Partial { + return typeof recordValue[key] === 'boolean' ? { [key]: recordValue[key] } : {}; +} + +function optionalRect(value: unknown): Partial { + const rect = record(value); + if (!rect || !['x', 'y', 'width', 'height'].every((key) => typeof rect[key] === 'number')) { + return {}; + } + return { + frame: { + x: rect.x as number, + y: rect.y as number, + width: rect.width as number, + height: rect.height as number, + }, + }; +} + +function record(value: unknown): Record | undefined { + return value !== null && typeof value === 'object' && !Array.isArray(value) + ? (value as Record) + : undefined; +} diff --git a/scripts/ios-ax-bridge-spike/config.ts b/scripts/ios-ax-bridge-spike/config.ts new file mode 100644 index 0000000000..9fbaa441b1 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/config.ts @@ -0,0 +1,213 @@ +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { + parseLocalStates, + parseSampleCount, + parseScreenIds, +} from '../ios-snapshot-benchmark/definitions.ts'; +import { resolveRepoRoot } from '../ios-snapshot-benchmark/host.ts'; +import type { CandidateId, ResourceLimits } from './types.ts'; +import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; + +class SpikeConfigurationError extends Error {} + +export type SpikeConfig = Readonly<{ + repoRoot: string; + udid: string; + appBundleId: string; + targetProcessId?: number; + privateTool?: string; + helperPath?: string; + stateDir: string; + derivedPath: string; + outputPath: string; + screens: ReturnType; + states: ReturnType; + samples: number; + candidates: CandidateId[]; + limits: ResourceLimits; + applyPreferences: boolean; + keepDevice: boolean; +}>; + +const CANDIDATES: readonly CandidateId[] = [ + 'public-macos-ax', + 'private-coresimulator-ax', + 'xctest-control', +]; +const BOOLEAN_FLAGS = new Set(['--apply-preferences', '--keep-device']); +const VALUE_FLAGS = new Set([ + '--udid', + '--app-bundle-id', + '--target-process-id', + '--private-tool', + '--helper-path', + '--state-dir', + '--derived-path', + '--out', + '--screen', + '--state', + '--samples', + '--candidate', +]); + +export function parseConfig(argv: readonly string[]): SpikeConfig { + const parsed = parseArguments(argv[0] === '--' ? argv.slice(1) : argv); + const states = parseStates(parsed.values.get('--state')); + const screens = parseScreens(parsed.values.get('--screen')); + const candidates = parseCandidates(parsed.values.get('--candidate')); + const samples = parseSamples(parsed.values.get('--samples'), states); + const stateDir = resolvePath( + parsed.values.get('--state-dir'), + fs.mkdtempSync(path.join(os.tmpdir(), 'agent-device-ios-ax-spike-')), + ); + fs.mkdirSync(stateDir, { recursive: true }); + return { + repoRoot: resolveRepoRoot(), + udid: required(parsed.values, '--udid'), + appBundleId: parsed.values.get('--app-bundle-id') ?? 'com.apple.dt.Devices', + ...optionalNumber(parsed.values.get('--target-process-id')), + ...optionalValue(parsed.values.get('--private-tool'), 'privateTool'), + ...optionalValue(parsed.values.get('--helper-path'), 'helperPath'), + stateDir, + derivedPath: resolvePath( + parsed.values.get('--derived-path'), + path.join(stateDir, 'derived-data'), + ), + outputPath: resolvePath( + parsed.values.get('--out'), + path.join(stateDir, 'ios-simulator-ax-bridge-spike.v1.json'), + ), + screens, + states, + samples, + candidates, + limits: DEFAULT_SPIKE_LIMITS, + applyPreferences: parsed.booleans.has('--apply-preferences'), + keepDevice: parsed.booleans.has('--keep-device'), + }; +} + +function parseArguments(argv: readonly string[]): { + values: Map; + booleans: Set; +} { + exitAfterHelp(argv); + const values = new Map(); + const booleans = new Set(); + for (let index = 0; index < argv.length; index += 1) { + const argument = parseArgument(argv, index); + recordArgument(argument, values, booleans); + index = argument.nextIndex; + } + return { values, booleans }; +} + +function exitAfterHelp(argv: readonly string[]): void { + if (!argv.includes('--help') && !argv.includes('-h')) return; + printHelp(); + process.exit(0); +} + +function recordArgument( + argument: { flag: string; value?: string }, + values: Map, + booleans: Set, +): void { + if (argument.value === undefined) booleans.add(argument.flag); + else values.set(argument.flag, argument.value); +} + +function parseArgument( + argv: readonly string[], + index: number, +): { flag: string; value?: string; nextIndex: number } { + const flag = argv[index]; + if (flag === undefined) throw new SpikeConfigurationError('Missing option.'); + if (BOOLEAN_FLAGS.has(flag)) return { flag, nextIndex: index }; + return parseValueArgument(flag, argv[index + 1], index); +} + +function parseValueArgument( + flag: string, + value: string | undefined, + index: number, +): { flag: string; value: string; nextIndex: number } { + if (!VALUE_FLAGS.has(flag)) throw new SpikeConfigurationError(`Unknown option: ${flag}`); + if (!value || value.startsWith('--')) { + throw new SpikeConfigurationError(`${flag} requires a value.`); + } + return { flag, value, nextIndex: index + 1 }; +} + +function parseStates(value: string | undefined): SpikeConfig['states'] { + try { + return parseLocalStates(value); + } catch (error) { + throw new SpikeConfigurationError(error instanceof Error ? error.message : String(error)); + } +} + +function parseScreens(value: string | undefined): SpikeConfig['screens'] { + try { + return parseScreenIds(value); + } catch (error) { + throw new SpikeConfigurationError(error instanceof Error ? error.message : String(error)); + } +} + +function parseSamples(value: string | undefined, states: SpikeConfig['states']): number { + try { + return parseSampleCount(value, states); + } catch (error) { + throw new SpikeConfigurationError(error instanceof Error ? error.message : String(error)); + } +} + +function parseCandidates(value: string | undefined): CandidateId[] { + const candidates = (value ?? CANDIDATES.join(',')) + .split(',') + .map((candidate) => candidate.trim()) + .filter(Boolean); + const unknown = candidates.filter((candidate) => !CANDIDATES.includes(candidate as CandidateId)); + if (unknown.length > 0) + throw new SpikeConfigurationError(`Unknown --candidate value: ${unknown.join(', ')}`); + if (candidates.length === 0) + throw new SpikeConfigurationError('--candidate requires at least one value.'); + return [...new Set(candidates)] as CandidateId[]; +} + +function required(values: Map, flag: string): string { + const value = values.get(flag); + if (!value) throw new SpikeConfigurationError(`${flag} is required for a reproducible run.`); + return value; +} + +function optionalValue( + value: string | undefined, + key: 'privateTool' | 'helperPath', +): { privateTool: string } | { helperPath: string } | Record { + return value === undefined + ? {} + : ({ [key]: path.resolve(value) } as { privateTool: string } | { helperPath: string }); +} + +function optionalNumber(value: string | undefined): { targetProcessId?: number } { + if (value === undefined) return {}; + const number = Number(value); + if (!Number.isInteger(number) || number < 1) { + throw new SpikeConfigurationError('--target-process-id must be a positive integer.'); + } + return { targetProcessId: number }; +} + +function resolvePath(value: string | undefined, fallback: string): string { + return path.resolve(value ?? fallback); +} + +function printHelp(): void { + process.stdout.write( + `Usage: pnpm bench:ios-ax-bridge -- [options]\n\nRequired:\n --udid \n\nOptions:\n --candidate public-macos-ax, private-coresimulator-ax, xctest-control\n --state #2189 state names\n --screen #2189 fixture names\n --samples #2189 minimums: cold 10, warm/relaunch 20\n --apply-preferences apply task-owned preboot AX preference experiment\n --private-tool optional private-tool framed adapter\n --target-process-id DeviceHub/Simulator host process to inspect\n --out raw JSON report path\n --keep-device leave the dedicated Simulator shutdown/boot state unchanged\n`, + ); +} diff --git a/scripts/ios-ax-bridge-spike/decision.test.ts b/scripts/ios-ax-bridge-spike/decision.test.ts new file mode 100644 index 0000000000..34d73576fa --- /dev/null +++ b/scripts/ios-ax-bridge-spike/decision.test.ts @@ -0,0 +1,31 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { decideSpike } from './decision.ts'; +import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; +import type { LifecycleEvidence, PreferenceEvidence } from './types.ts'; + +const lifecycle: LifecycleEvidence = { + source: 'framed-protocol-fixture', + crash: { failure: 'process-crash', recovered: true }, + timeout: { failure: 'timeout', recovered: true }, + cancellation: { failure: 'cancelled', recovered: true }, + staleGeneration: { failure: 'stale-generation', recovered: true }, +}; + +const preferences: PreferenceEvidence = { + applied: false, + restored: true, + simulatorStateBefore: 'Shutdown', + diffs: [], +}; + +test('fails closed when a bridge has no readable corpus cells', () => { + const result = decideSpike([], lifecycle, preferences, DEFAULT_SPIKE_LIMITS, 'completed', [ + { + candidate: 'public-macos-ax', + failure: { kind: 'unsupported-mechanism', code: 'permission' }, + }, + ]); + assert.equal(result.decision, 'NO-GO'); + assert.ok(result.reasons.some((reason) => reason.includes('public-macos-ax produced no cells'))); +}); diff --git a/scripts/ios-ax-bridge-spike/decision.ts b/scripts/ios-ax-bridge-spike/decision.ts new file mode 100644 index 0000000000..6f85e9f329 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/decision.ts @@ -0,0 +1,211 @@ +import type { + CandidateId, + LifecycleEvidence, + PreferenceEvidence, + ResourceLimits, + SpikeCell, +} from './types.ts'; + +export function decideSpike( + cells: readonly SpikeCell[], + lifecycle: LifecycleEvidence, + preferences: PreferenceEvidence, + limits: ResourceLimits, + status: 'completed' | 'stopped' = 'completed', + protocolProbes: readonly { + candidate: CandidateId; + failure?: { kind: string; code?: string }; + }[] = [], +): { decision: 'GO' | 'NO-GO'; reasons: string[] } { + const reasons = [ + ...statusReasons(status), + ...preferenceReasons(preferences), + ...probeReasons(protocolProbes), + ...bridgeCandidateReasons(cells, limits), + ...lifecycleReasons(lifecycle), + ]; + const uniqueReasons = [...new Set(reasons)]; + return { + decision: uniqueReasons.length === 0 ? 'GO' : 'NO-GO', + reasons: uniqueReasons, + }; +} + +function statusReasons(status: 'completed' | 'stopped'): string[] { + return status === 'stopped' ? ['The live run stopped before the full corpus completed.'] : []; +} + +function preferenceReasons(preferences: PreferenceEvidence): string[] { + return preferences.applied && !preferences.restored + ? ['The task-owned Simulator preference experiment was not restored.'] + : []; +} + +function probeReasons( + probes: readonly { candidate: CandidateId; failure?: { kind: string; code?: string } }[], +): string[] { + const reasons: string[] = []; + for (const probe of probes) { + if (!probe.failure) continue; + reasons.push( + `${probe.candidate} protocol probe returned ${probe.failure.kind}/${probe.failure.code ?? 'no-code'}.`, + ); + } + return reasons; +} + +function bridgeCandidateReasons(cells: readonly SpikeCell[], limits: ResourceLimits): string[] { + const reasons: string[] = []; + for (const candidate of ['public-macos-ax', 'private-coresimulator-ax'] as const) { + const candidateCells = cells.filter((cell) => cell.candidate === candidate); + if (candidateCells.length === 0) { + reasons.push(`${candidate} produced no cells.`); + continue; + } + reasons.push(...candidateDecisionReasons(candidateCells, limits)); + } + return reasons; +} + +function lifecycleReasons(lifecycle: LifecycleEvidence): string[] { + const checks = [ + ['process crash', lifecycle.crash, 'process-crash'], + ['timeout', lifecycle.timeout, 'timeout'], + ['cancellation', lifecycle.cancellation, 'cancelled'], + ['stale target-generation', lifecycle.staleGeneration, 'stale-generation'], + ] as const; + const reasons: string[] = []; + for (const [label, result, expected] of checks) { + if (result.failure === expected && result.recovered) continue; + reasons.push( + `Framed ${label} recovery did not produce the required typed result and recovery.`, + ); + } + return reasons; +} + +function candidateDecisionReasons(cells: readonly SpikeCell[], limits: ResourceLimits): string[] { + const reasons: string[] = []; + for (const cell of cells) { + reasons.push(...sampleShapeReasons(cell)); + reasons.push(...resourceReasons(cell, limits)); + reasons.push(...latencyReasons(cell)); + } + reasons.push(...candidateAvailabilityReasons(cells)); + return [...new Set(reasons)]; +} + +function sampleShapeReasons(cell: SpikeCell): string[] { + const samples = cell.acquisitionSamples; + const successful = samples.filter((sample) => sample.ok && sample.firstTree === 'readable'); + const reasons: string[] = []; + if (successful.length < cell.sampleMinimum) { + reasons.push( + `${cell.candidate} ${cell.state}/${cell.screen} did not produce ${cell.sampleMinimum} readable samples.`, + ); + } + if (samples.some((sample) => ['unreadable', 'empty'].includes(sample.firstTree))) { + reasons.push( + `${cell.candidate} ${cell.state}/${cell.screen} has unreadable or empty first-tree evidence.`, + ); + } + if (samples.some((sample) => sample.failure?.kind === 'stale-generation')) { + reasons.push( + `${cell.candidate} ${cell.state}/${cell.screen} has stale-generation acquisition evidence.`, + ); + } + return reasons; +} + +function resourceReasons(cell: SpikeCell, limits: ResourceLimits): string[] { + const checks = [ + [ + 'duration', + limits.maxDurationMs, + (sample: SpikeCell['acquisitionSamples'][number]) => sample.metrics?.durationMs, + ], + [ + 'CPU', + limits.maxCpuMs, + (sample: SpikeCell['acquisitionSamples'][number]) => sample.metrics?.cpuMs, + ], + [ + 'memory', + limits.maxMemoryBytes, + (sample: SpikeCell['acquisitionSamples'][number]) => sample.metrics?.memoryBytes, + ], + ] as const; + const reasons: string[] = []; + for (const [label, limit, readValue] of checks) { + if (cell.acquisitionSamples.some((sample) => exceedsLimit(readValue(sample), limit))) { + reasons.push(`${cell.candidate} ${cell.state}/${cell.screen} exceeded the ${label} bound.`); + } + } + return reasons; +} + +function latencyReasons(cell: SpikeCell): string[] { + const firstLook = finite(cell.acquisitionSamples.map((sample) => sample.firstLookMs)); + const firstLookTarget = { + 'cold-cold': { limit: 5_000, label: 'cold-cold first look missed the 5 second target.' }, + cold: { limit: 1_500, label: 'cold prepared first look missed the 1.5 second target.' }, + relaunch: { limit: 250, label: 'relaunch first look missed the 250 ms target.' }, + warm: undefined, + }[cell.state]; + const reasons: string[] = []; + if (firstLookTarget && percentile(firstLook, 95) >= firstLookTarget.limit) { + reasons.push(`${cell.candidate} ${firstLookTarget.label}`); + } + const acquisition = finite(cell.acquisitionSamples.map((sample) => sample.metrics?.durationMs)); + if ( + cell.state === 'warm' && + (percentile(acquisition, 50) >= 75 || percentile(acquisition, 95) >= 150) + ) { + reasons.push(`${cell.candidate} warm acquisition missed the 75/150 ms target.`); + } + return reasons; +} + +function candidateAvailabilityReasons(cells: readonly SpikeCell[]): string[] { + const reasons: string[] = []; + if (cells.some(hasUnavailablePrivateTool)) { + reasons.push('The private CoreSimulator AX mechanism has no configured tool on this host.'); + } + if (cells.some(hasUnsupportedPublicAx)) { + reasons.push( + 'The public macOS AX mechanism was unsupported or unreadable on the Xcode 27 host surface.', + ); + } + return reasons; +} + +function hasUnavailablePrivateTool(cell: SpikeCell): boolean { + return ( + cell.candidate === 'private-coresimulator-ax' && + cell.acquisitionSamples.some((sample) => sample.failure?.code === 'private-tool-unavailable') + ); +} + +function hasUnsupportedPublicAx(cell: SpikeCell): boolean { + return ( + cell.candidate === 'public-macos-ax' && + cell.acquisitionSamples.some((sample) => sample.failure?.kind === 'unsupported-mechanism') + ); +} + +function exceedsLimit(value: number | null | undefined, limit: number): boolean { + return value !== null && value !== undefined && value > limit; +} + +function finite(values: readonly (number | undefined)[]): number[] { + return values.filter( + (value): value is number => typeof value === 'number' && Number.isFinite(value), + ); +} + +function percentile(values: readonly number[], percentage: number): number { + if (values.length === 0) return Number.POSITIVE_INFINITY; + const sorted = [...values].sort((left, right) => left - right); + const rank = Math.ceil((percentage / 100) * sorted.length); + return sorted[Math.min(sorted.length - 1, Math.max(0, rank - 1))]!; +} diff --git a/scripts/ios-ax-bridge-spike/framed-process.test.ts b/scripts/ios-ax-bridge-spike/framed-process.test.ts new file mode 100644 index 0000000000..60e775fc1d --- /dev/null +++ b/scripts/ios-ax-bridge-spike/framed-process.test.ts @@ -0,0 +1,105 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { runFramedBatch } from './framed-process.ts'; +import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; +import type { SpikeRequest } from './types.ts'; + +function request(id: string): SpikeRequest { + return { + version: 1, + id, + candidate: 'public-macos-ax', + simulatorUdid: '00000000-0000-0000-0000-000000000000', + state: 'warm', + screen: 'quiet', + appBundleId: 'com.apple.dt.Devices', + limits: DEFAULT_SPIKE_LIMITS, + }; +} + +function childScript(mode: 'healthy' | 'malformed' | 'crash' | 'hang'): { + file: string; + args: string[]; +} { + const payload = JSON.stringify({ + version: 1, + ok: true, + acquisition: { + targetId: 'simulator:test', + targetGeneration: 'generation-1', + nodes: [{ id: 'n0', role: 'AXApplication' }], + viewport: { kind: 'missing', reason: 'not-provided' }, + truncated: false, + residue: [], + }, + metrics: { + requestBytes: 10, + responseBytes: 10, + nodeCount: 1, + maxTraversalDepth: 0, + cpuMs: 1, + memoryBytes: 1, + durationMs: 1, + }, + }); + const malformed = payload.replace('"id":"n0"', '"id":"n0","hittable":true'); + const response = mode === 'malformed' ? malformed : payload; + const script = ` + import process from 'node:process'; + if (${JSON.stringify(mode)} === 'crash') process.exit(17); + if (${JSON.stringify(mode)} === 'hang') { + setInterval(() => {}, 1000); + } else { + let input = ''; + process.stdin.setEncoding('utf8'); + process.stdin.on('data', (chunk) => { input += chunk; }); + process.stdin.on('end', () => { + for (const line of input.split('\\n').filter(Boolean)) { + const request = JSON.parse(line); + process.stdout.write(JSON.stringify({ ...${response}, id: request.id, candidate: request.candidate }) + '\\n'); + } + }); + } + `; + return { file: process.execPath, args: ['--input-type=module', '-e', script] }; +} + +test('uses one framed response per request and keeps diagnostics on stderr', async () => { + const result = await runFramedBatch(childScript('healthy'), [request('one'), request('two')]); + assert.deepEqual( + result.responses.map((response) => response.id), + ['one', 'two'], + ); + assert.equal( + result.responses.every((response) => response.ok), + true, + ); +}); + +test('classifies malformed trees, crashes, timeouts, and cancellation', async () => { + const malformed = await runFramedBatch(childScript('malformed'), [request('malformed')]); + assert.equal(malformed.responses[0]?.failure?.kind, 'malformed-tree'); + + const crashed = await runFramedBatch(childScript('crash'), [request('crash')]); + assert.equal(crashed.responses[0]?.failure?.kind, 'process-crash'); + + const timeout = await runFramedBatch(childScript('hang'), [request('timeout')], { + limits: { ...DEFAULT_SPIKE_LIMITS, maxDurationMs: 40 }, + }); + assert.equal(timeout.responses[0]?.failure?.kind, 'timeout'); + + const controller = new AbortController(); + const cancellation = runFramedBatch(childScript('hang'), [request('cancel')], { + signal: controller.signal, + limits: { ...DEFAULT_SPIKE_LIMITS, maxDurationMs: 200 }, + }); + setTimeout(() => controller.abort(), 10); + const cancelled = await cancellation; + assert.equal(cancelled.responses[0]?.failure?.kind, 'cancelled'); + + const transport = await runFramedBatch( + { file: '/private/tmp/agent-device-ios-ax-spike-missing-helper' }, + [request('transport')], + ); + assert.equal(transport.responses[0]?.failure?.kind, 'transport-failure'); +}); diff --git a/scripts/ios-ax-bridge-spike/framed-process.ts b/scripts/ios-ax-bridge-spike/framed-process.ts new file mode 100644 index 0000000000..64a544db8e --- /dev/null +++ b/scripts/ios-ax-bridge-spike/framed-process.ts @@ -0,0 +1,213 @@ +import { spawn } from 'node:child_process'; +import type { ChildProcess } from 'node:child_process'; +import { encodeFrame, DEFAULT_SPIKE_LIMITS } from './limits.ts'; +import { failureResponse, parseSpikeResponse } from './protocol.ts'; +import type { ResourceLimits, SpikeFailureKind, SpikeRequest, SpikeResponse } from './types.ts'; + +export type FramedProcessSpec = Readonly<{ + file: string; + args?: readonly string[]; + cwd?: string; + env?: NodeJS.ProcessEnv; +}>; + +export type FramedBatchResult = Readonly<{ + responses: readonly SpikeResponse[]; + stderr: string; +}>; + +export async function runFramedBatch( + spec: FramedProcessSpec, + requests: readonly SpikeRequest[], + options: Readonly<{ signal?: AbortSignal; limits?: ResourceLimits }> = {}, +): Promise { + const limits = options.limits ?? DEFAULT_SPIKE_LIMITS; + const encodedRequests = requests.map((request) => ({ + request, + ...encodeFrame(request), + })); + const oversized = encodedRequests.find(({ bytes }) => bytes > limits.maxRequestBytes); + if (oversized) { + return { + responses: requests.map((request) => + failureResponse( + request, + { kind: 'transport-failure', code: 'request-limit-exceeded' }, + { + requestBytes: + encodedRequests.find((item) => item.request.id === request.id)?.bytes ?? 0, + }, + ), + ), + stderr: '', + }; + } + if (requests.length === 0) return { responses: [], stderr: '' }; + if (options.signal?.aborted) return cancelledBatch(requests, encodedRequests); + + return new Promise((resolve) => { + const child = spawn(spec.file, [...(spec.args ?? [])], { + cwd: spec.cwd, + env: { ...process.env, ...spec.env }, + stdio: ['pipe', 'pipe', 'pipe'], + }); + const responses = new Map(); + const requestById = new Map(requests.map((request) => [request.id, request])); + let stdoutBuffer = Buffer.alloc(0); + let stdoutBytes = 0; + let stderr = ''; + let settled = false; + const timer = setTimeout(() => finish('timeout', 'batch-duration-limit'), limits.maxDurationMs); + + const finish = (kind?: SpikeFailureKind, code?: string): void => { + if (settled) return; + settled = true; + if (timer) clearTimeout(timer); + options.signal?.removeEventListener('abort', onAbort); + if (kind) { + for (const request of requests) { + if (!responses.has(request.id)) { + responses.set( + request.id, + failureResponse( + request, + { kind, ...(code ? { code } : {}) }, + { + requestBytes: requestBytesFor(request, encodedRequests), + responseBytes: stdoutBytes, + }, + ), + ); + } + } + } + if (kind === 'timeout' || kind === 'cancelled') terminate(child); + resolve({ + responses: requests.map( + (request) => + responses.get(request.id) ?? + failureResponse( + request, + { kind: 'transport-failure', code: 'missing-response' }, + { + requestBytes: requestBytesFor(request, encodedRequests), + responseBytes: stdoutBytes, + }, + ), + ), + stderr, + }); + }; + const onAbort = (): void => finish('cancelled', 'abort-signal'); + options.signal?.addEventListener('abort', onAbort, { once: true }); + child.stdout.on('data', (chunk: Buffer | string) => { + if (settled) return; + const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); + stdoutBytes += data.length; + if (stdoutBytes > limits.maxResponseBytes) { + finish('malformed-tree', 'response-limit-exceeded'); + return; + } + stdoutBuffer = Buffer.concat([stdoutBuffer, data]); + consumeLines(); + }); + child.stderr.on('data', (chunk: Buffer | string) => { + if (stderr.length >= 64 * 1024) return; + stderr += (Buffer.isBuffer(chunk) ? chunk.toString('utf8') : chunk).slice( + 0, + 64 * 1024 - stderr.length, + ); + }); + child.on('error', (error: NodeJS.ErrnoException) => { + finish('transport-failure', error.code ?? 'spawn-error'); + }); + child.on('close', (code) => { + if (settled) return; + consumeLines(true); + if (settled) return; + if (code !== 0) { + finish('process-crash', `exit-${code ?? 'unknown'}`); + return; + } + if (responses.size !== requests.length) { + finish('transport-failure', 'missing-response'); + return; + } + finish(); + }); + child.stdin.on('error', () => finish('transport-failure', 'stdin-error')); + child.stdin.end(encodedRequests.map(({ line }) => line).join('')); + + function consumeLines(final = false): void { + let newline = stdoutBuffer.indexOf(0x0a); + while (newline >= 0) { + const line = stdoutBuffer.subarray(0, newline); + stdoutBuffer = stdoutBuffer.subarray(newline + 1); + consumeLine(line); + if (settled) return; + newline = stdoutBuffer.indexOf(0x0a); + } + if (final && stdoutBuffer.length > 0) consumeLine(stdoutBuffer); + } + + function consumeLine(line: Buffer): void { + const text = line.toString('utf8').trim(); + if (text.length === 0) return; + if (line.length > limits.maxResponseBytes) { + finish('malformed-tree', 'frame-limit-exceeded'); + return; + } + let value: unknown; + try { + value = JSON.parse(text); + } catch { + finish('malformed-tree', 'invalid-json'); + return; + } + const id = readId(value); + const request = id ? requestById.get(id) : undefined; + if (!request || responses.has(request.id)) { + finish('malformed-tree', 'response-id-invalid'); + return; + } + responses.set(request.id, parseSpikeResponse(value, request, line.length + 1)); + } + }); +} + +function cancelledBatch( + requests: readonly SpikeRequest[], + encodedRequests: readonly Readonly<{ request: SpikeRequest; bytes: number; line: string }>[], +): FramedBatchResult { + return { + responses: requests.map((request) => + failureResponse( + request, + { kind: 'cancelled', code: 'abort-signal' }, + { + requestBytes: requestBytesFor(request, encodedRequests), + }, + ), + ), + stderr: '', + }; +} + +function requestBytesFor( + request: SpikeRequest, + encodedRequests: readonly Readonly<{ request: SpikeRequest; bytes: number; line: string }>[], +): number { + return encodedRequests.find((item) => item.request.id === request.id)?.bytes ?? 0; +} + +function readId(value: unknown): string | undefined { + if (value && typeof value === 'object' && !Array.isArray(value)) { + const id = (value as Record).id; + return typeof id === 'string' ? id : undefined; + } + return undefined; +} + +function terminate(child: ChildProcess): void { + if (!child.killed) child.kill('SIGTERM'); +} diff --git a/scripts/ios-ax-bridge-spike/lifecycle.test.ts b/scripts/ios-ax-bridge-spike/lifecycle.test.ts new file mode 100644 index 0000000000..9254bd99a1 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/lifecycle.test.ts @@ -0,0 +1,21 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { runLifecycleProbes } from './lifecycle.ts'; + +test('records typed lifecycle failures and recovery probes', async () => { + const evidence = await runLifecycleProbes(); + assert.deepEqual( + { + crash: evidence.crash, + timeout: evidence.timeout, + cancellation: evidence.cancellation, + staleGeneration: evidence.staleGeneration, + }, + { + crash: { failure: 'process-crash', recovered: true }, + timeout: { failure: 'timeout', recovered: true }, + cancellation: { failure: 'cancelled', recovered: true }, + staleGeneration: { failure: 'stale-generation', recovered: true }, + }, + ); +}); diff --git a/scripts/ios-ax-bridge-spike/lifecycle.ts b/scripts/ios-ax-bridge-spike/lifecycle.ts new file mode 100644 index 0000000000..ec388e9bf2 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/lifecycle.ts @@ -0,0 +1,127 @@ +import { runFramedBatch } from './framed-process.ts'; +import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; +import { failureResponse } from './protocol.ts'; +import type { LifecycleEvidence, SpikeRequest, SpikeResponse } from './types.ts'; + +export async function runLifecycleProbes(): Promise { + const request = probeRequest('lifecycle'); + const limits = { ...DEFAULT_SPIKE_LIMITS, maxDurationMs: 1_000 }; + const crash = await runFailureProbe('crash', request, limits); + const timeout = await runFailureProbe('hang', request, limits); + const cancellation = await runCancellationProbe(request, limits); + const staleResponse = failureResponse(request, { + kind: 'stale-generation', + code: 'target-generation-mismatch', + expectedTargetGeneration: 'expected', + observedTargetGeneration: 'observed', + }); + const stale = await runFramedBatch(nodeScript('stale-generation', staleResponse), [request], { + limits, + }); + return { + source: 'framed-protocol-fixture', + crash: { failure: crash.failure, recovered: crash.recovered }, + timeout: { failure: timeout.failure, recovered: timeout.recovered }, + cancellation: { failure: cancellation.failure, recovered: cancellation.recovered }, + staleGeneration: { + failure: stale.responses[0]?.failure?.kind ?? 'transport-failure', + recovered: await runHealthyProbe(request, limits), + }, + }; +} + +function probeRequest(id: string): SpikeRequest { + return { + version: 1, + id, + candidate: 'public-macos-ax', + simulatorUdid: '00000000-0000-0000-0000-000000000000', + state: 'warm', + screen: 'quiet', + appBundleId: 'com.apple.dt.Devices', + limits: DEFAULT_SPIKE_LIMITS, + }; +} + +async function runFailureProbe( + script: string, + request: SpikeRequest, + limits: typeof DEFAULT_SPIKE_LIMITS, +): Promise<{ failure: NonNullable['kind']; recovered: boolean }> { + const failed = await runFramedBatch(nodeScript(script), [request], { limits }); + const failure = failed.responses[0]?.failure?.kind ?? 'transport-failure'; + const recovered = await runHealthyProbe(request, limits); + return { failure, recovered }; +} + +async function runCancellationProbe( + request: SpikeRequest, + limits: typeof DEFAULT_SPIKE_LIMITS, +): Promise<{ failure: NonNullable['kind']; recovered: boolean }> { + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), 15); + const result = await runFramedBatch(nodeScript('hang'), [request], { + signal: controller.signal, + limits, + }); + clearTimeout(timer); + return { + failure: result.responses[0]?.failure?.kind ?? 'transport-failure', + recovered: (await runHealthyProbe(request, limits)) === true, + }; +} + +async function runHealthyProbe( + request: SpikeRequest, + limits: typeof DEFAULT_SPIKE_LIMITS, +): Promise { + const result = await runFramedBatch(nodeScript('healthy'), [request], { limits }); + return result.responses[0]?.ok === true; +} + +function nodeScript( + mode: string, + overrideResponse?: SpikeResponse, +): { file: string; args: string[] } { + const response = JSON.stringify( + overrideResponse ?? { + version: 1, + ok: true, + acquisition: { + targetId: 'simulator:probe', + targetGeneration: 'generation', + nodes: [{ id: 'n0', role: 'AXApplication' }], + viewport: { kind: 'missing', reason: 'not-provided' }, + truncated: false, + residue: [], + }, + metrics: { + requestBytes: 1, + responseBytes: 1, + nodeCount: 1, + maxTraversalDepth: 0, + cpuMs: 0, + memoryBytes: 1, + durationMs: 1, + }, + }, + ); + const modeStatement = + mode === 'crash' ? 'process.exit(17);' : mode === 'hang' ? 'setInterval(() => {}, 1000);' : ''; + const script = ` + import process from 'node:process'; + ${modeStatement} + if (${JSON.stringify(mode)} !== 'crash' && ${JSON.stringify(mode)} !== 'hang') { + let input = ''; + process.stdin.setEncoding('utf8'); + process.stdin.on('data', (chunk) => { input += chunk; }); + process.stdin.on('end', () => { + for (const line of input.split('\\n').filter(Boolean)) { + const request = JSON.parse(line); + process.stdout.write(JSON.stringify({ ...${response}, id: request.id, candidate: request.candidate }) + '\\n'); + } + }); + } + `; + return { file: process.execPath, args: ['--input-type=module', '-e', script] }; +} diff --git a/scripts/ios-ax-bridge-spike/limits.test.ts b/scripts/ios-ax-bridge-spike/limits.test.ts new file mode 100644 index 0000000000..ffd2bf316f --- /dev/null +++ b/scripts/ios-ax-bridge-spike/limits.test.ts @@ -0,0 +1,67 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { DEFAULT_SPIKE_LIMITS, encodeFrame, validateRawAcquisition } from './limits.ts'; + +const acquisition = { + targetId: 'simulator:test', + targetGeneration: 'generation-1', + nodes: [ + { id: 'n0', role: 'AXApplication' }, + { id: 'n1', parentId: 'n0', role: 'AXWindow', frame: { x: 0, y: 0, width: 100, height: 200 } }, + ], + viewport: { kind: 'reported', rect: { x: 0, y: 0, width: 100, height: 200 } }, + truncated: false, + residue: [], +} as const; + +test('accepts a raw tree and reports structural depth without publishing it on nodes', () => { + const result = validateRawAcquisition(acquisition, DEFAULT_SPIKE_LIMITS); + assert.equal(result.ok, true); + if (result.ok) assert.equal(result.maxTraversalDepth, 1); + assert.equal('depth' in acquisition.nodes[0], false); + assert.equal('hittable' in acquisition.nodes[0], false); +}); + +test('rejects presentation facts in the acquisition reader', () => { + const result = validateRawAcquisition( + { + ...acquisition, + nodes: [{ id: 'n0', visibleToUser: true }], + }, + DEFAULT_SPIKE_LIMITS, + ); + assert.deepEqual(result, { ok: false, code: 'node-contains-presentation-fact' }); +}); + +test('rejects cycles, missing parents, and resource-limit violations', () => { + assert.deepEqual( + validateRawAcquisition( + { ...acquisition, nodes: [{ id: 'n0', parentId: 'missing' }] }, + DEFAULT_SPIKE_LIMITS, + ), + { ok: false, code: 'parent-node-missing' }, + ); + assert.deepEqual( + validateRawAcquisition( + { ...acquisition, nodes: [{ id: 'n0', parentId: 'n0' }] }, + DEFAULT_SPIKE_LIMITS, + ), + { ok: false, code: 'traversal-depth-exceeded' }, + ); + assert.deepEqual( + validateRawAcquisition( + { ...acquisition, nodes: Array.from({ length: 3 }, (_, index) => ({ id: `n${index}` })) }, + { + ...DEFAULT_SPIKE_LIMITS, + maxNodes: 2, + }, + ), + { ok: false, code: 'node-limit-exceeded' }, + ); +}); + +test('frames are newline-delimited and byte bounded', () => { + const frame = encodeFrame({ id: 'one', text: 'ok' }); + assert.equal(frame.line.endsWith('\n'), true); + assert.equal(frame.bytes, Buffer.byteLength(frame.line)); +}); diff --git a/scripts/ios-ax-bridge-spike/limits.ts b/scripts/ios-ax-bridge-spike/limits.ts new file mode 100644 index 0000000000..54e02bc656 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/limits.ts @@ -0,0 +1,229 @@ +import type { RawAcquiredNode, RawAcquisition, ResourceLimits, SpikeRect } from './types.ts'; + +export const DEFAULT_SPIKE_LIMITS: ResourceLimits = Object.freeze({ + maxRequestBytes: 64 * 1024, + maxResponseBytes: 4 * 1024 * 1024, + maxNodes: 1500, + maxTraversalDepth: 12, + maxCpuMs: 2_000, + maxMemoryBytes: 256 * 1024 * 1024, + maxDurationMs: 5_000, +}); + +const NODE_KEYS = new Set([ + 'id', + 'parentId', + 'role', + 'subrole', + 'label', + 'value', + 'identifier', + 'frame', + 'enabled', + 'selected', + 'focused', +]); + +export type TreeValidation = + | Readonly<{ ok: true; acquisition: RawAcquisition; maxTraversalDepth: number }> + | Readonly<{ ok: false; code: string }>; + +export function encodeFrame(value: unknown): { bytes: number; line: string } { + const line = `${JSON.stringify(value)}\n`; + return { bytes: Buffer.byteLength(line), line }; +} + +export function validateRawAcquisition(value: unknown, limits: ResourceLimits): TreeValidation { + const record = readAcquisitionRecord(value); + if (!record.ok) return record; + const envelope = validateAcquisitionEnvelope(record.value); + if (!envelope.ok) return envelope; + if (record.value.nodes.length > limits.maxNodes) + return { ok: false, code: 'node-limit-exceeded' }; + const nodes = validateNodes(record.value.nodes); + if (!nodes.ok) return nodes; + const maxTraversalDepth = treeDepth(nodes.nodes); + if (maxTraversalDepth > limits.maxTraversalDepth) { + return { ok: false, code: 'traversal-depth-exceeded' }; + } + return { + ok: true, + acquisition: record.value as unknown as RawAcquisition, + maxTraversalDepth, + }; +} + +function readAcquisitionRecord( + value: unknown, +): + | { ok: true; value: Record & { nodes: unknown[] } } + | { ok: false; code: string } { + if (!isRecord(value)) return { ok: false, code: 'acquisition-not-object' }; + if (typeof value.targetId !== 'string' || value.targetId.length === 0) { + return { ok: false, code: 'target-id-missing' }; + } + if (value.targetGeneration !== null && typeof value.targetGeneration !== 'string') { + return { ok: false, code: 'target-generation-invalid' }; + } + if (!Array.isArray(value.nodes)) return { ok: false, code: 'nodes-not-array' }; + return { ok: true, value: value as Record & { nodes: unknown[] } }; +} + +function validateAcquisitionEnvelope( + value: Record, +): { ok: true } | { ok: false; code: string } { + if (typeof value.truncated !== 'boolean') return { ok: false, code: 'truncated-invalid' }; + if (!validateViewport(value.viewport)) return { ok: false, code: 'viewport-invalid' }; + if (!validateResidue(value.residue)) return { ok: false, code: 'residue-invalid' }; + return { ok: true }; +} + +function validateNodes( + rawNodes: readonly unknown[], +): { ok: true; nodes: RawAcquiredNode[] } | { ok: false; code: string } { + const nodes: RawAcquiredNode[] = []; + const ids = new Set(); + for (const rawNode of rawNodes) { + const node = validateNode(rawNode); + if (!node.ok) return node; + if (ids.has(node.node.id)) return { ok: false, code: 'duplicate-node-id' }; + ids.add(node.node.id); + nodes.push(node.node); + } + return validateParents(nodes, ids); +} + +function validateParents( + nodes: readonly RawAcquiredNode[], + ids: ReadonlySet, +): { ok: true; nodes: RawAcquiredNode[] } | { ok: false; code: string } { + for (const node of nodes) { + if (node.parentId !== undefined && !ids.has(node.parentId)) { + return { ok: false, code: 'parent-node-missing' }; + } + } + return { ok: true, nodes: [...nodes] }; +} + +function validateNode( + value: unknown, +): { ok: true; node: RawAcquiredNode } | { ok: false; code: string } { + const node = asNodeRecord(value); + if (!node) return { ok: false, code: 'node-not-object' }; + const code = nodeValidationCode(node); + return code === undefined ? { ok: true, node: node as RawAcquiredNode } : { ok: false, code }; +} + +function asNodeRecord(value: unknown): Record | undefined { + return isRecord(value) ? value : undefined; +} + +function nodeValidationCode(value: Record): string | undefined { + const identityCode = nodeIdentityCode(value); + if (identityCode) return identityCode; + return nodeFactCode(value); +} + +function nodeIdentityCode(value: Record): string | undefined { + if (Object.keys(value).some((key) => !NODE_KEYS.has(key))) { + return 'node-contains-presentation-fact'; + } + if (typeof value.id !== 'string' || value.id.length === 0) return 'node-id-missing'; + if (value.parentId !== undefined && typeof value.parentId !== 'string') { + return 'parent-id-invalid'; + } + return undefined; +} + +function nodeFactCode(value: Record): string | undefined { + const textCode = optionalStringCode(value); + if (textCode) return textCode; + const booleanCode = optionalBooleanCode(value); + if (booleanCode) return booleanCode; + return value.frame !== undefined && !validateRect(value.frame) ? 'frame-invalid' : undefined; +} + +function optionalStringCode(value: Record): string | undefined { + for (const key of ['role', 'subrole', 'label', 'value', 'identifier'] as const) { + if (value[key] !== undefined && typeof value[key] !== 'string') return `${key}-invalid`; + } + return undefined; +} + +function optionalBooleanCode(value: Record): string | undefined { + for (const key of ['enabled', 'selected', 'focused'] as const) { + if (value[key] !== undefined && typeof value[key] !== 'boolean') return `${key}-invalid`; + } + return undefined; +} + +function validateViewport(value: unknown): boolean { + if (!isRecord(value) || typeof value.kind !== 'string') return false; + if (value.kind === 'missing') { + return ( + value.reason === 'not-provided' || + value.reason === 'not-supported' || + value.reason === 'invalid' + ); + } + return (value.kind === 'reported' || value.kind === 'derived') && validateRect(value.rect); +} + +function validateRect(value: unknown): value is SpikeRect { + if (!isRecord(value)) return false; + for (const key of ['x', 'y', 'width', 'height']) { + if (typeof value[key] !== 'number' || !Number.isFinite(value[key])) return false; + } + const width = value.width; + const height = value.height; + return typeof width === 'number' && typeof height === 'number' && width >= 0 && height >= 0; +} + +function validateResidue(value: unknown): boolean { + if (!Array.isArray(value)) return false; + for (const residue of value) { + if (!validateResidueItem(residue)) return false; + } + return true; +} + +const RESIDUE_VALIDATORS: Readonly) => boolean>> = { + 'provider-pruned': (value) => + Array.isArray(value.fields) && value.fields.every((field) => typeof field === 'string'), + 'missing-viewport': (value) => + ['not-provided', 'not-supported', 'invalid'].includes(String(value.reason)), + truncated: (value) => ['nodes', 'depth', 'payload'].includes(String(value.dimension)), + 'stale-generation': (value) => value.expected === undefined || typeof value.expected === 'string', + 'unavailable-fact': (value) => typeof value.fact === 'string', + 'fallback-source': (value) => typeof value.producer === 'string', +}; + +function validateResidueItem(value: unknown): boolean { + if (!isRecord(value) || typeof value.kind !== 'string') return false; + return RESIDUE_VALIDATORS[value.kind]?.(value) ?? false; +} + +function treeDepth(nodes: readonly RawAcquiredNode[]): number { + const byId = new Map(nodes.map((node) => [node.id, node])); + const memo = new Map(); + const visiting = new Set(); + let maximum = 0; + for (const node of nodes) maximum = Math.max(maximum, depth(node.id)); + return maximum; + + function depth(id: string): number { + const cached = memo.get(id); + if (cached !== undefined) return cached; + if (visiting.has(id)) return Number.POSITIVE_INFINITY; + visiting.add(id); + const parentId = byId.get(id)?.parentId; + const result = parentId === undefined ? 0 : depth(parentId) + 1; + visiting.delete(id); + memo.set(id, result); + return result; + } +} + +function isRecord(value: unknown): value is Record { + return value !== null && typeof value === 'object' && !Array.isArray(value); +} diff --git a/scripts/ios-ax-bridge-spike/preferences.test.ts b/scripts/ios-ax-bridge-spike/preferences.test.ts new file mode 100644 index 0000000000..65091dcc3a --- /dev/null +++ b/scripts/ios-ax-bridge-spike/preferences.test.ts @@ -0,0 +1,22 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { diffPlistValues, simulatorPreferencePaths } from './preferences.ts'; + +test('records exact targeted preference changes and ignores unrelated keys', () => { + assert.deepEqual( + diffPlistValues( + { AutomationEnabled: false, Unrelated: 'preserve' }, + { AutomationEnabled: true, Unrelated: 'preserve' }, + ['AutomationEnabled', 'IgnoreAXServerEntitlements'], + ), + [ + { key: 'AutomationEnabled', before: false, after: true }, + { key: 'IgnoreAXServerEntitlements' }, + ], + ); +}); + +test('builds preference paths only from a validated Simulator UDID', () => { + assert.equal(simulatorPreferencePaths('793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4').length, 2); + assert.throws(() => simulatorPreferencePaths('../other-device'), /Invalid Simulator UDID/); +}); diff --git a/scripts/ios-ax-bridge-spike/preferences.ts b/scripts/ios-ax-bridge-spike/preferences.ts new file mode 100644 index 0000000000..92cb559bcf --- /dev/null +++ b/scripts/ios-ax-bridge-spike/preferences.ts @@ -0,0 +1,254 @@ +import crypto from 'node:crypto'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { spawnSync } from 'node:child_process'; +import type { PlistDiff, PlistKeyChange, PreferenceEvidence } from './types.ts'; + +const PREFERENCE_VALUES = { + 'com.apple.Accessibility.plist': { + AccessibilityEnabled: true, + ApplicationAccessibilityEnabled: true, + AutomationEnabled: true, + IgnoreAXServerEntitlements: true, + }, + 'com.apple.UIAutomation.plist': { + UIAutomationEnabled: true, + }, +} as const; + +const UUID_PATTERN = /^[0-9A-Fa-f-]{36}$/u; +const EMPTY_PLIST = `\n\n\n`; + +class PreferenceSafetyError extends Error { + readonly code: 'invalid-udid' | 'simulator-not-shutdown' | 'simulator-state-unknown'; + + constructor(code: PreferenceSafetyError['code'], message: string) { + super(message); + this.name = 'PreferenceSafetyError'; + this.code = code; + } +} + +export type PlistSnapshot = Readonly<{ + path: string; + existedBefore: boolean; + beforeBytes: Buffer | null; + beforeValues: Record; +}>; + +export function simulatorPreferencePaths(udid: string): string[] { + validateUdid(udid); + const directory = path.join( + os.homedir(), + 'Library', + 'Developer', + 'CoreSimulator', + 'Devices', + udid, + 'data', + 'Library', + 'Preferences', + ); + return Object.keys(PREFERENCE_VALUES).map((name) => path.join(directory, name)); +} + +export function diffPlistValues( + before: Record, + after: Record, + keys: readonly string[], +): PlistKeyChange[] { + return keys.flatMap((key) => { + const hasBefore = Object.prototype.hasOwnProperty.call(before, key); + const hasAfter = Object.prototype.hasOwnProperty.call(after, key); + if (hasBefore && hasAfter && Object.is(before[key], after[key])) return []; + return [ + { + key, + ...(hasBefore ? { before: before[key] } : {}), + ...(hasAfter ? { after: after[key] } : {}), + }, + ]; + }); +} + +export function readSimulatorState(udid: string): string { + validateUdid(udid); + const result = spawnSync('xcrun', ['simctl', 'list', 'devices', '-j'], { + encoding: 'utf8', + timeout: 30_000, + }); + if (result.status !== 0 || typeof result.stdout !== 'string') { + throw new PreferenceSafetyError('simulator-state-unknown', `Unable to read state for ${udid}.`); + } + let payload: unknown; + try { + payload = JSON.parse(result.stdout); + } catch { + throw new PreferenceSafetyError( + 'simulator-state-unknown', + `Simulator state was not JSON for ${udid}.`, + ); + } + const state = findDeviceState(payload, udid); + if (!state) { + throw new PreferenceSafetyError('simulator-state-unknown', `Simulator ${udid} was not found.`); + } + return state; +} + +export function applyPrebootPreferences(udid: string): { + evidence: PreferenceEvidence; + snapshots: readonly PlistSnapshot[]; +} { + const simulatorStateBefore = readSimulatorState(udid); + if (simulatorStateBefore !== 'Shutdown') { + throw new PreferenceSafetyError( + 'simulator-not-shutdown', + `Preference experiment requires a shutdown Simulator; ${udid} is ${simulatorStateBefore}.`, + ); + } + const snapshots = simulatorPreferencePaths(udid).map(snapshotPlist); + try { + for (const snapshot of snapshots) applyPlistValues(snapshot.path); + } catch (error) { + restoreSnapshotBytes(snapshots); + throw error; + } + const diffs = snapshots.map((snapshot) => { + const afterBytes = readBytes(snapshot.path); + const afterValues = readPlist(snapshot.path); + return { + path: snapshot.path, + existedBefore: snapshot.existedBefore, + beforeSha256: hashBytes(snapshot.beforeBytes), + afterSha256: hashBytes(afterBytes), + changes: diffPlistValues(snapshot.beforeValues, afterValues, changedKeys(snapshot.path)), + } satisfies PlistDiff; + }); + return { + snapshots, + evidence: { + applied: diffs.some((diff) => diff.changes.length > 0), + restored: false, + simulatorStateBefore, + diffs, + }, + }; +} + +export function restorePrebootPreferences( + udid: string, + snapshots: readonly PlistSnapshot[], +): PreferenceEvidence['restored'] { + const state = readSimulatorState(udid); + if (state !== 'Shutdown') { + throw new PreferenceSafetyError( + 'simulator-not-shutdown', + `Preference restore requires a shutdown Simulator; ${udid} is ${state}.`, + ); + } + restoreSnapshotBytes(snapshots); + return true; +} + +function restoreSnapshotBytes(snapshots: readonly PlistSnapshot[]): void { + for (const snapshot of snapshots) { + if (snapshot.beforeBytes === null) { + fs.rmSync(snapshot.path, { force: true }); + continue; + } + fs.writeFileSync(snapshot.path, snapshot.beforeBytes); + } +} + +function snapshotPlist(filePath: string): PlistSnapshot { + const beforeBytes = readBytes(filePath); + return { + path: filePath, + existedBefore: beforeBytes !== null, + beforeBytes, + beforeValues: beforeBytes === null ? {} : readPlist(filePath), + }; +} + +function applyPlistValues(filePath: string): void { + fs.mkdirSync(path.dirname(filePath), { recursive: true }); + if (!fs.existsSync(filePath)) fs.writeFileSync(filePath, EMPTY_PLIST); + for (const key of changedKeys(filePath)) { + const value = true; + const replaced = spawnSync( + '/usr/bin/plutil', + ['-replace', key, '-bool', String(value), filePath], + { + encoding: 'utf8', + timeout: 10_000, + }, + ); + if (replaced.status === 0) continue; + const inserted = spawnSync( + '/usr/bin/plutil', + ['-insert', key, '-bool', String(value), filePath], + { + encoding: 'utf8', + timeout: 10_000, + }, + ); + if (inserted.status !== 0) { + throw new PreferenceSafetyError('simulator-state-unknown', `Unable to update ${filePath}.`); + } + } +} + +function readPlist(filePath: string): Record { + const result = spawnSync('/usr/bin/plutil', ['-convert', 'json', '-o', '-', filePath], { + encoding: 'utf8', + timeout: 10_000, + }); + if (result.status !== 0 || typeof result.stdout !== 'string') return {}; + try { + const value: unknown = JSON.parse(result.stdout); + return isRecord(value) ? value : {}; + } catch { + return {}; + } +} + +function readBytes(filePath: string): Buffer | null { + try { + return fs.readFileSync(filePath); + } catch { + return null; + } +} + +function hashBytes(value: Buffer | null): string | null { + return value === null ? null : crypto.createHash('sha256').update(value).digest('hex'); +} + +function changedKeys(filePath: string): string[] { + const name = path.basename(filePath) as keyof typeof PREFERENCE_VALUES; + return name in PREFERENCE_VALUES ? Object.keys(PREFERENCE_VALUES[name]) : []; +} + +function findDeviceState(payload: unknown, udid: string): string | undefined { + if (!isRecord(payload) || !isRecord(payload.devices)) return undefined; + for (const runtimeDevices of Object.values(payload.devices)) { + if (!Array.isArray(runtimeDevices)) continue; + const device = runtimeDevices.find( + (candidate) => isRecord(candidate) && candidate.udid === udid, + ); + if (isRecord(device) && typeof device.state === 'string') return device.state; + } + return undefined; +} + +function validateUdid(udid: string): void { + if (!UUID_PATTERN.test(udid)) { + throw new PreferenceSafetyError('invalid-udid', `Invalid Simulator UDID: ${udid}.`); + } +} + +function isRecord(value: unknown): value is Record { + return value !== null && typeof value === 'object' && !Array.isArray(value); +} diff --git a/scripts/ios-ax-bridge-spike/presentation.test.ts b/scripts/ios-ax-bridge-spike/presentation.test.ts new file mode 100644 index 0000000000..8e29ae8e21 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/presentation.test.ts @@ -0,0 +1,24 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { presentAcquisitionForMeasurement } from './presentation.ts'; +import type { RawAcquisition } from './types.ts'; + +test('prototype presentation creates the #2190 acquired carrier without semantic fields', () => { + const raw: RawAcquisition = { + targetId: 'simulator:test', + targetGeneration: 'generation-1', + nodes: [ + { id: 'root', role: 'AXApplication', enabled: true }, + { id: 'child', parentId: 'root', role: 'AXWindow' }, + ], + viewport: { kind: 'missing', reason: 'not-provided' }, + truncated: false, + residue: [], + }; + const result = presentAcquisitionForMeasurement(raw); + assert.equal(result.acquisition.producer, 'simulator-ax-bridge'); + assert.equal(result.acquisition.nodes.length, 2); + assert.equal(result.acquisition.nodes[1]?.parentIndex, 0); + assert.equal('hittable' in result.acquisition.nodes[0]!, false); + assert.equal(result.measurement.nodeCount, 2); +}); diff --git a/scripts/ios-ax-bridge-spike/presentation.ts b/scripts/ios-ax-bridge-spike/presentation.ts new file mode 100644 index 0000000000..7759aaedf6 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/presentation.ts @@ -0,0 +1,96 @@ +import { performance } from 'node:perf_hooks'; +import { createIosSnapshotRequest, deriveIosCaptureHint } from '@agent-device/capture-kit'; +import type { IosSnapshotAcquisition } from '@agent-device/contracts/ios-snapshot'; +import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; +import type { PresentationMeasurement, RawAcquisition } from './types.ts'; + +export function presentAcquisitionForMeasurement(raw: RawAcquisition): { + acquisition: IosSnapshotAcquisition; + measurement: PresentationMeasurement; +} { + const started = performance.now(); + const usage = process.resourceUsage(); + const acquisitionIntent = 'full' as const; + const request = createIosSnapshotRequest({ raw: true, acquisitionIntent }); + const acquisition: IosSnapshotAcquisition = { + producer: 'simulator-ax-bridge', + intent: acquisitionIntent, + hint: { ...deriveIosCaptureHint(request), acquisitionIntent }, + nodes: raw.nodes.map((node, index) => toRawSnapshotNode(node, index, nodeIndexes(raw.nodes))), + truncated: raw.truncated, + viewport: raw.viewport, + lineage: { + targetId: raw.targetId, + ...(raw.targetGeneration === null ? {} : { generation: raw.targetGeneration }), + }, + residue: raw.residue, + }; + const payloadBytes = Buffer.byteLength(JSON.stringify(acquisition)); + const nextUsage = process.resourceUsage(); + return { + acquisition, + measurement: { + ok: true, + payloadBytes, + nodeCount: raw.nodes.length, + durationMs: performance.now() - started, + cpuMs: cpuMilliseconds(nextUsage) - cpuMilliseconds(usage), + memoryBytes: process.memoryUsage().rss, + }, + }; +} + +function toRawSnapshotNode( + node: RawAcquisition['nodes'][number], + index: number, + nodeIndexes: ReadonlyMap, +): RawSnapshotNode { + return { + index, + ...optionalParent(node.parentId, nodeIndexes), + ...optionalString(node, 'role'), + ...optionalString(node, 'subrole'), + ...optionalString(node, 'label'), + ...optionalString(node, 'value'), + ...optionalString(node, 'identifier'), + ...optionalFrame(node.frame), + ...optionalBoolean(node, 'enabled'), + ...optionalBoolean(node, 'selected'), + ...optionalBoolean(node, 'focused'), + }; +} + +function nodeIndexes(nodes: RawAcquisition['nodes']): ReadonlyMap { + return new Map(nodes.map((node, index) => [node.id, index])); +} + +function optionalParent( + parentId: string | undefined, + indexes: ReadonlyMap, +): Partial { + if (parentId === undefined) return {}; + const parentIndex = indexes.get(parentId); + return parentIndex === undefined ? {} : { parentIndex }; +} + +function optionalString( + node: RawAcquisition['nodes'][number], + key: 'role' | 'subrole' | 'label' | 'value' | 'identifier', +): Partial { + return node[key] === undefined ? {} : { [key]: node[key] }; +} + +function optionalBoolean( + node: RawAcquisition['nodes'][number], + key: 'enabled' | 'selected' | 'focused', +): Partial { + return node[key] === undefined ? {} : { [key]: node[key] }; +} + +function optionalFrame(frame: RawAcquisition['nodes'][number]['frame']): Partial { + return frame === undefined ? {} : { rect: frame }; +} + +function cpuMilliseconds(usage: NodeJS.ResourceUsage): number { + return (usage.userCPUTime + usage.systemCPUTime) / 1_000; +} diff --git a/scripts/ios-ax-bridge-spike/protocol.ts b/scripts/ios-ax-bridge-spike/protocol.ts new file mode 100644 index 0000000000..872cef243f --- /dev/null +++ b/scripts/ios-ax-bridge-spike/protocol.ts @@ -0,0 +1,187 @@ +import { validateRawAcquisition } from './limits.ts'; +import type { + ResourceMetrics, + SpikeFailure, + SpikeFailureKind, + SpikeRequest, + SpikeResponse, +} from './types.ts'; +import type { FirstTreeStatus } from '../ios-snapshot-benchmark/types.ts'; + +const FAILURE_KINDS: ReadonlySet = new Set([ + 'unsupported-mechanism', + 'malformed-tree', + 'stale-generation', + 'timeout', + 'cancelled', + 'process-crash', + 'transport-failure', +]); + +export function parseSpikeResponse( + value: unknown, + request: SpikeRequest, + responseBytes: number, +): SpikeResponse { + if (!isRecord(value)) return malformedResponse(request, 'response-not-object', responseBytes); + if (value.version !== 1) return malformedResponse(request, 'protocol-version', responseBytes); + if (value.id !== request.id) + return malformedResponse(request, 'response-id-mismatch', responseBytes); + if (value.candidate !== request.candidate) { + return malformedResponse(request, 'response-candidate-mismatch', responseBytes); + } + const metrics = parseMetrics(value.metrics, responseBytes); + if (!metrics) return malformedResponse(request, 'metrics-invalid', responseBytes); + + if (value.ok === true) { + const tree = validateRawAcquisition(value.acquisition, request.limits); + if (!tree.ok) return malformedResponse(request, tree.code, responseBytes, metrics); + return { + version: 1, + id: request.id, + candidate: request.candidate, + ok: true, + acquisition: tree.acquisition, + metrics: { + ...metrics, + nodeCount: tree.acquisition.nodes.length, + maxTraversalDepth: tree.maxTraversalDepth, + }, + }; + } + + const failure = parseFailure(value.failure); + if (!failure) return malformedResponse(request, 'failure-invalid', responseBytes, metrics); + return { + version: 1, + id: request.id, + candidate: request.candidate, + ok: false, + failure, + metrics, + }; +} + +export function failureResponse( + request: SpikeRequest, + failure: SpikeFailure, + metrics: Partial = {}, +): SpikeResponse { + return { + version: 1, + id: request.id, + candidate: request.candidate, + ok: false, + failure, + metrics: { + requestBytes: metrics.requestBytes ?? 0, + responseBytes: metrics.responseBytes ?? 0, + nodeCount: metrics.nodeCount ?? 0, + maxTraversalDepth: metrics.maxTraversalDepth ?? 0, + cpuMs: metrics.cpuMs ?? null, + memoryBytes: metrics.memoryBytes ?? null, + durationMs: metrics.durationMs ?? 0, + }, + }; +} + +export function firstTreeStatus(response: SpikeResponse): FirstTreeStatus { + if (response.ok) return response.acquisition?.nodes.length ? 'readable' : 'empty'; + if (response.failure?.kind === 'unsupported-mechanism') return 'unreadable'; + return 'not-observed'; +} + +function malformedResponse( + request: SpikeRequest, + code: string, + responseBytes: number, + metrics?: ResourceMetrics, +): SpikeResponse { + return failureResponse( + request, + { kind: 'malformed-tree', code }, + { + ...(metrics ?? {}), + responseBytes, + }, + ); +} + +function parseMetrics(value: unknown, responseBytes: number): ResourceMetrics | undefined { + if (!isRecord(value)) return undefined; + const requestBytes = finiteNonNegative(value.requestBytes); + const nodeCount = finiteNonNegative(value.nodeCount); + const maxTraversalDepth = finiteNonNegative(value.maxTraversalDepth); + const durationMs = finiteNonNegative(value.durationMs); + if ( + requestBytes === undefined || + nodeCount === undefined || + maxTraversalDepth === undefined || + durationMs === undefined + ) { + return undefined; + } + const cpuMs = nullableFiniteNonNegative(value.cpuMs); + const memoryBytes = nullableFiniteNonNegative(value.memoryBytes); + if (cpuMs === 'invalid' || memoryBytes === 'invalid') return undefined; + return { + requestBytes, + responseBytes, + nodeCount, + maxTraversalDepth, + cpuMs, + memoryBytes, + durationMs, + }; +} + +function parseFailure(value: unknown): SpikeFailure | undefined { + const record = asFailureRecord(value); + if (!record) return undefined; + const kind = readFailureKind(record.kind); + if (!kind) return undefined; + const code = optionalFailureString(record, 'code'); + const expected = optionalFailureString(record, 'expectedTargetGeneration'); + const observed = optionalFailureString(record, 'observedTargetGeneration'); + if (!code.valid || !expected.valid || !observed.valid) return undefined; + return { + kind, + ...(code.value === undefined ? {} : { code: code.value }), + ...(expected.value === undefined ? {} : { expectedTargetGeneration: expected.value }), + ...(observed.value === undefined ? {} : { observedTargetGeneration: observed.value }), + }; +} + +function asFailureRecord(value: unknown): Record | undefined { + return isRecord(value) && typeof value.kind === 'string' ? value : undefined; +} + +function readFailureKind(value: unknown): SpikeFailureKind | undefined { + return typeof value === 'string' && FAILURE_KINDS.has(value as SpikeFailureKind) + ? (value as SpikeFailureKind) + : undefined; +} + +function optionalFailureString( + value: Record, + key: 'code' | 'expectedTargetGeneration' | 'observedTargetGeneration', +): { valid: boolean; value?: string } { + if (value[key] === undefined) return { valid: true }; + return typeof value[key] === 'string' + ? { valid: true, value: value[key] as string } + : { valid: false }; +} + +function finiteNonNegative(value: unknown): number | undefined { + return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : undefined; +} + +function nullableFiniteNonNegative(value: unknown): number | null | 'invalid' { + if (value === null) return null; + const number = finiteNonNegative(value); + return number === undefined ? 'invalid' : number; +} + +function isRecord(value: unknown): value is Record { + return value !== null && typeof value === 'object' && !Array.isArray(value); +} diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts new file mode 100644 index 0000000000..b0a1091006 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -0,0 +1,176 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import type { SpikeCell, SpikeReport, SpikeSample } from './types.ts'; + +export function writeSpikeReport(outputPath: string, report: SpikeReport): void { + fs.mkdirSync(path.dirname(outputPath), { recursive: true }); + fs.writeFileSync(outputPath, `${JSON.stringify(report, null, 2)}\n`); + fs.writeFileSync(outputPath.replace(/\.json$/u, '.md'), renderSpikeMarkdown(report)); +} + +function renderSpikeMarkdown(report: SpikeReport): string { + const lines = [ + '# iOS Simulator AX bridge spike', + '', + `- Decision: **${report.decision}**`, + `- Status: **${report.status}**`, + `- Revision: ${report.revision.commit} (${report.revision.branch})`, + `- Target: ${report.target.name} (${report.target.udid}, ${report.target.runtime})`, + `- Generated: ${report.generatedAt}`, + `- Corpus: states=${report.config.states.join(', ')}, screens=${report.config.screens.join(', ')}, samples=${report.config.requestedSamples}`, + '', + '## Environment and limits', + '', + ...environmentLines(report), + '', + '## Candidate fidelity and limitation matrix', + '', + '| Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation |', + '|---|---|---|---|---|---|', + `| public-macos-ax | public macOS ApplicationServices AX | ${surfaceStatus(report, 'public-macos-ax')} | ${surfaceStatus(report, 'public-macos-ax')} | framed protocol | host Accessibility permission and Xcode 27 DeviceHub surface |`, + `| private-coresimulator-ax | external/private CoreSimulator AX tool | ${surfaceStatus(report, 'private-coresimulator-ax')} | ${surfaceStatus(report, 'private-coresimulator-ax')} | framed protocol contract only | private interface/tool compatibility |`, + `| xctest-control | #2189 XCTest runner control | ${surfaceStatus(report, 'xctest-control')} | ${surfaceStatus(report, 'xctest-control')} | existing runner lifecycle | control, not a host-side AX bridge |`, + '', + '## Raw acquisition and prototype presentation results', + '', + '| Candidate | State | Screen | N | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures |', + '|---|---|---|---:|---:|---:|---:|---:|---:|', + ...report.cells.map(renderCellRow), + '', + 'Acquisition samples retain the raw node payload, viewport evidence, target generation, truncation, residue, and resource metrics. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction.', + '', + '## Direct protocol probes', + '', + ...probeLines(report), + '', + '## Independent positive-control evidence', + '', + `- Invalid shallow rule: exit=${report.positiveControl.invalidShallowRule.exitCode}; command=${report.positiveControl.invalidShallowRule.command}; assertion=${report.positiveControl.invalidShallowRule.assertion}`, + `- Safe full rule: exit=${report.positiveControl.safeFullRule.exitCode}; command=${report.positiveControl.safeFullRule.command}; assertion=${report.positiveControl.safeFullRule.assertion}`, + '', + '## Preference experiment', + '', + `- Applied: **${report.preferenceEvidence.applied}**`, + `- Restored: **${report.preferenceEvidence.restored}**`, + `- Simulator state before experiment: ${report.preferenceEvidence.simulatorStateBefore}`, + '- Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored.', + ...preferenceLines(report), + '', + '## Lifecycle, cancellation, and recovery', + '', + `- Source: ${report.lifecycle.source}`, + `- Process crash: ${report.lifecycle.crash.failure}; recovered=${report.lifecycle.crash.recovered}`, + `- Timeout: ${report.lifecycle.timeout.failure}; recovered=${report.lifecycle.timeout.recovered}`, + `- Cancellation: ${report.lifecycle.cancellation.failure}; recovered=${report.lifecycle.cancellation.recovered}`, + `- Stale generation: ${report.lifecycle.staleGeneration.failure}; recovered=${report.lifecycle.staleGeneration.recovered}`, + '', + '## Decision rationale', + '', + ...report.decisionReasons.map((reason) => `- ${reason}`), + '', + '## Next interface boundary', + '', + `- ${report.nextInterface}`, + '', + '## Production boundary', + '', + '- No production backend selection, fallback, runner-demand, open/relaunch, proxy, XCTest interaction, or public CLI changes were made.', + '- A production bridge should not start until this report has a GO result; this run is the #2192 boundary.', + ]; + if (report.stop) { + lines.push('', '## Stop condition', '', `- ${report.stop.category}: ${report.stop.message}`); + if (report.stop.command) lines.push(`- Command: ${report.stop.command}`); + } + return `${lines.join('\n')}\n`; +} + +function environmentLines(report: SpikeReport): string[] { + return [ + `- Node: ${report.toolchain.node}`, + `- pnpm: ${report.toolchain.pnpm}`, + `- Xcode: ${report.toolchain.xcode.replaceAll('\n', '; ')}`, + `- simctl: ${report.toolchain.simctl}`, + `- Swift: ${report.toolchain.swift}`, + `- OS: ${report.toolchain.os}; arch=${report.toolchain.arch}`, + `- Bounds: request=${report.limits.maxRequestBytes} B, response=${report.limits.maxResponseBytes} B, nodes=${report.limits.maxNodes}, traversal=${report.limits.maxTraversalDepth}, CPU=${report.limits.maxCpuMs} ms, memory=${report.limits.maxMemoryBytes} B, duration=${report.limits.maxDurationMs} ms`, + ]; +} + +function probeLines(report: SpikeReport): string[] { + const lines: string[] = []; + for (const probe of report.protocolProbes) { + lines.push(renderProbeLine(probe)); + } + for (const log of report.protocolProbeLogs) { + lines.push(renderProbeLog(log)); + } + return lines; +} + +function renderProbeLine(probe: SpikeReport['protocolProbes'][number]): string { + return `- ${probe.candidate}/${probe.id}: ok=${probe.ok}, failure=${failureValue(probe.failure, 'kind')}, code=${failureValue(probe.failure, 'code')}, nodes=${probe.metrics.nodeCount}, duration=${probe.metrics.durationMs.toFixed(1)} ms, CPU=${metricValue(probe.metrics.cpuMs)} ms, memory=${probe.metrics.memoryBytes ?? '–'} B, response=${probe.metrics.responseBytes} B`; +} + +function renderProbeLog(log: SpikeReport['protocolProbeLogs'][number]): string { + return `- stderr ${log.candidate}/${log.id}: ${log.stderr.trim().replaceAll('\n', ' ⏎ ') || 'empty'}`; +} + +function failureValue( + failure: SpikeReport['protocolProbes'][number]['failure'], + key: 'kind' | 'code', +): string { + return failure?.[key] ?? 'none'; +} + +function metricValue(value: number | null): string { + return value === null ? '–' : value.toFixed(1); +} + +function renderCellRow(cell: SpikeCell): string { + const acquisition = cell.acquisitionSamples; + const presentation = cell.presentationSamples; + const readable = acquisition.filter((sample) => sample.ok && sample.firstTree === 'readable'); + const failures = acquisition.length - readable.length; + const nodeCounts = readable.flatMap((sample) => + typeof sample.metrics?.nodeCount === 'number' ? [sample.metrics.nodeCount] : [], + ); + return `| ${cell.candidate} | ${cell.state} | ${cell.screen} | ${acquisition.length} | ${summary(acquisition, 'wallClockMs')} | ${summary(acquisition, 'firstLookMs')} | ${summary(presentation, 'wallClockMs')} | ${formatNumber(median(nodeCounts))} | ${failures} |`; +} + +function surfaceStatus(report: SpikeReport, candidate: SpikeCell['candidate']): string { + if (report.cells.some((cell) => cell.candidate === candidate)) return 'observed in cells'; + if (report.protocolProbes.some((probe) => probe.candidate === candidate)) + return 'protocol probe only'; + return 'not observed (run stopped)'; +} + +function preferenceLines(report: SpikeReport): string[] { + return report.preferenceEvidence.diffs.flatMap((diff) => [ + `- ${diff.path}: existed=${diff.existedBefore}, beforeSha256=${diff.beforeSha256 ?? 'missing'}, afterSha256=${diff.afterSha256 ?? 'missing'}`, + ` - Changes: ${diff.changes.length === 0 ? 'none' : diff.changes.map((change) => `${change.key}: ${JSON.stringify(change.before)} -> ${JSON.stringify(change.after)}`).join('; ')}`, + ]); +} + +function summary(samples: readonly SpikeSample[], key: 'wallClockMs' | 'firstLookMs'): string { + const values = samples.flatMap((sample) => { + const value = sample[key]; + return typeof value === 'number' && Number.isFinite(value) ? [value] : []; + }); + if (values.length === 0) return '–'; + return `${formatNumber(median(values))}/${formatNumber(percentile(values, 95))}`; +} + +function median(values: readonly number[]): number { + return percentile(values, 50); +} + +function percentile(values: readonly number[], percentage: number): number { + if (values.length === 0) return Number.NaN; + const sorted = [...values].sort((left, right) => left - right); + const rank = Math.ceil((percentage / 100) * sorted.length); + return sorted[Math.min(sorted.length - 1, Math.max(0, rank - 1))]!; +} + +function formatNumber(value: number): string { + return Number.isFinite(value) ? value.toFixed(1) : '–'; +} diff --git a/scripts/ios-ax-bridge-spike/run.ts b/scripts/ios-ax-bridge-spike/run.ts new file mode 100644 index 0000000000..2caa57b35b --- /dev/null +++ b/scripts/ios-ax-bridge-spike/run.ts @@ -0,0 +1,318 @@ +import path from 'node:path'; +import { execFileSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import { + createPrivateCoreSimulatorAxAdapter, + createPublicMacOsAxAdapter, + createXCTestControlAdapter, +} from './adapter.ts'; +import { parseConfig, type SpikeConfig } from './config.ts'; +import { decideSpike } from './decision.ts'; +import { runLifecycleProbes } from './lifecycle.ts'; +import { + applyPrebootPreferences, + type PlistSnapshot, + readSimulatorState, + restorePrebootPreferences, +} from './preferences.ts'; +import { writeSpikeReport } from './report.ts'; +import { createAdapterOptions, runSpikeCells } from './runner.ts'; +import { readGitRevision, readTarget, readToolchain } from '../ios-snapshot-benchmark/host.ts'; +import { runDeepButtonControls } from '../ios-snapshot-benchmark/deep-control.ts'; +import { deepButtonFixtureEvidence } from '../ios-snapshot-benchmark/deep-button.ts'; +import { bootSimulator, shutdownSimulator } from '../ios-snapshot-benchmark/lifecycle.ts'; +import type { AcquisitionAdapter } from './adapter.ts'; +import { SPIKE_ISSUE, SPIKE_PARENT, SPIKE_PREREQUISITES, SPIKE_SCHEMA_VERSION } from './types.ts'; +import type { + PreferenceEvidence, + ProtocolProbeLog, + SpikeReport, + SpikeRequest, + SpikeResponse, + Toolchain, +} from './types.ts'; + +if (isMainModule()) void main(process.argv.slice(2)).catch(reportFailure); + +function reportFailure(error: unknown): void { + process.stderr.write( + `${error instanceof Error ? (error.stack ?? error.message) : String(error)}\n`, + ); + process.exitCode = 1; +} + +async function main(argv: readonly string[]): Promise { + const config = parseConfig(argv); + const metadata = readMetadata(config); + const lifecycle = await runLifecycleProbes(); + const evidence = await executeSpikeRun(config); + const decision = decideSpike( + evidence.cells, + lifecycle, + evidence.preferenceEvidence, + config.limits, + evidence.status, + evidence.protocolProbes, + ); + const report = createReport(config, metadata, lifecycle, evidence, decision); + writeSpikeReport(config.outputPath, report); + process.stdout.write( + `Decision: ${report.decision}\nRaw: ${config.outputPath}\nMarkdown: ${config.outputPath.replace(/\.json$/u, '.md')}\n`, + ); + if (evidence.status === 'stopped') process.exitCode = 2; +} + +type SpikeRunEvidence = Readonly<{ + status: SpikeReport['status']; + stop?: SpikeReport['stop']; + cells: Awaited>; + protocolProbes: SpikeResponse[]; + protocolProbeLogs: SpikeReport['protocolProbeLogs']; + preferenceEvidence: PreferenceEvidence; + positiveControl: SpikeReport['positiveControl']; +}>; + +async function executeSpikeRun(config: SpikeConfig): Promise { + const collected = await collectSpikeEvidence(config); + const cleanup = cleanupPreferences( + config, + collected.preferenceEvidence, + collected.preferenceSnapshots, + ); + return { + ...collected, + preferenceEvidence: cleanup.evidence, + ...(cleanup.stop ? { status: 'stopped' as const, stop: cleanup.stop } : {}), + }; +} + +type CollectedSpikeEvidence = SpikeRunEvidence & { + preferenceSnapshots: readonly PlistSnapshot[]; +}; + +async function collectSpikeEvidence(config: SpikeConfig): Promise { + let preferenceEvidence = initialPreferenceEvidence(config.udid); + let preferenceSnapshots: readonly PlistSnapshot[] = []; + let cells: Awaited> = []; + let protocolProbes: SpikeResponse[] = []; + let protocolProbeLogs: SpikeReport['protocolProbeLogs'] = []; + let positiveControl = deepButtonFixtureEvidence(); + let status: SpikeReport['status'] = 'completed'; + let stop: SpikeReport['stop']; + try { + positiveControl = runDeepButtonControls(config.repoRoot); + const applied = preparePreferences(config); + preferenceEvidence = applied.evidence; + preferenceSnapshots = applied.snapshots; + const adapters = createAdapters(config); + if (config.applyPreferences) bootSimulator(config.udid); + const probes = await runProtocolProbes(config, adapters); + protocolProbes = probes.responses; + protocolProbeLogs = probes.logs; + cells = await runSpikeCells(config, adapters); + } catch (error) { + status = 'stopped'; + stop = stopForError(error); + } + return { + status, + ...(stop ? { stop } : {}), + cells, + protocolProbes, + protocolProbeLogs, + preferenceEvidence, + positiveControl, + preferenceSnapshots, + }; +} + +function preparePreferences(config: SpikeConfig): { + evidence: PreferenceEvidence; + snapshots: readonly PlistSnapshot[]; +} { + if (!config.applyPreferences) { + return { evidence: initialPreferenceEvidence(config.udid), snapshots: [] }; + } + shutdownSimulator(config.udid); + return applyPrebootPreferences(config.udid); +} + +function cleanupPreferences( + config: SpikeConfig, + evidence: PreferenceEvidence, + snapshots: readonly PlistSnapshot[], +): { evidence: PreferenceEvidence; stop?: SpikeReport['stop'] } { + if (!config.applyPreferences) { + if (!config.keepDevice) shutdownSimulator(config.udid); + return { evidence }; + } + try { + shutdownSimulator(config.udid); + return { + evidence: { ...evidence, restored: restorePrebootPreferences(config.udid, snapshots) }, + }; + } catch (error) { + return { evidence, stop: stopForError(error) }; + } +} + +function stopForError(error: unknown): SpikeReport['stop'] { + return { + category: isConfigurationError(error) ? 'configuration' : 'infrastructure', + message: error instanceof Error ? error.message : String(error), + ...(errorCommand(error) ? { command: errorCommand(error) } : {}), + }; +} + +function createReport( + config: SpikeConfig, + metadata: { target: SpikeReport['target']; toolchain: Toolchain }, + lifecycle: SpikeReport['lifecycle'], + evidence: SpikeRunEvidence, + decision: { decision: SpikeReport['decision']; reasons: string[] }, +): SpikeReport { + return { + schemaVersion: SPIKE_SCHEMA_VERSION, + issue: SPIKE_ISSUE, + parent: SPIKE_PARENT, + prerequisites: SPIKE_PREREQUISITES, + generatedAt: new Date().toISOString(), + revision: readGitRevision(config.repoRoot), + toolchain: metadata.toolchain, + target: metadata.target, + limits: config.limits, + candidates: config.candidates, + config: { + states: config.states, + screens: config.screens, + requestedSamples: config.samples, + }, + protocolProbes: evidence.protocolProbes, + protocolProbeLogs: evidence.protocolProbeLogs, + preferenceEvidence: evidence.preferenceEvidence, + lifecycle, + positiveControl: evidence.positiveControl, + status: evidence.status, + cells: evidence.cells, + decision: decision.decision, + decisionReasons: decision.reasons, + nextInterface: + 'Keep any future bridge behind the #2190 acquisition adapter and preserve raw facts until a separate GO evidence run proves fidelity, lifecycle, and latency.', + ...(evidence.stop ? { stop: evidence.stop } : {}), + }; +} + +function createAdapters(config: SpikeConfig) { + const options = createAdapterOptions(config); + const adapters = config.candidates.flatMap((candidate) => { + if (candidate === 'public-macos-ax') return [createPublicMacOsAxAdapter(options)]; + if (candidate === 'private-coresimulator-ax') + return [createPrivateCoreSimulatorAxAdapter(options)]; + return [ + createXCTestControlAdapter((request) => ({ + repoRoot: config.repoRoot, + stateDir: config.stateDir, + session: `ax-spike-xctest-control-${request.state ?? 'state'}-${request.screen}`, + udid: request.simulatorUdid, + derivedPath: path.join(config.derivedPath, 'xctest-control', request.screen), + })), + ]; + }); + return adapters; +} + +async function runProtocolProbes( + config: SpikeConfig, + adapters: readonly AcquisitionAdapter[], +): Promise<{ responses: SpikeResponse[]; logs: SpikeReport['protocolProbeLogs'] }> { + const responses: SpikeResponse[] = []; + const logs: ProtocolProbeLog[] = []; + for (const adapter of adapters.filter(isBridgeAdapter)) { + const request = protocolProbeRequest(config, adapter.candidate); + const result = await adapter.acquireBatch([request]); + responses.push(...result.responses.slice(0, 1)); + logs.push({ candidate: adapter.candidate, id: request.id, stderr: result.stderr }); + } + return { responses, logs }; +} + +function isBridgeAdapter(adapter: AcquisitionAdapter): adapter is AcquisitionAdapter & { + candidate: Exclude; +} { + return adapter.candidate !== 'xctest-control'; +} + +function protocolProbeRequest( + config: SpikeConfig, + candidate: Exclude, +): SpikeRequest { + return { + version: 1, + id: `protocol-probe:${candidate}`, + candidate, + simulatorUdid: config.udid, + state: 'warm', + screen: 'quiet', + appBundleId: config.appBundleId, + ...(config.targetProcessId === undefined ? {} : { targetProcessId: config.targetProcessId }), + limits: config.limits, + }; +} + +function readMetadata(config: SpikeConfig): { + target: SpikeReport['target']; + toolchain: Toolchain; +} { + const target = readTarget(config.udid, 'com.callstack.agentdevicelab'); + const base = readToolchain(); + return { + target: { udid: target.udid, name: target.name, runtime: target.runtime }, + toolchain: { ...base, swift: commandText('swift', ['--version']) }, + }; +} + +function initialPreferenceEvidence(udid: string): PreferenceEvidence { + let simulatorStateBefore = 'unknown'; + try { + simulatorStateBefore = readSimulatorState(udid); + } catch { + simulatorStateBefore = 'unavailable'; + } + return { + applied: false, + restored: true, + simulatorStateBefore, + diffs: [], + }; +} + +function commandText(command: string, args: readonly string[]): string { + try { + return execFileSync(command, [...args], { + encoding: 'utf8', + timeout: 30_000, + stdio: ['ignore', 'pipe', 'ignore'], + }).trim(); + } catch { + return 'unavailable'; + } +} + +function isConfigurationError(error: unknown): boolean { + return error instanceof Error && error.name === 'SpikeConfigurationError'; +} + +function errorCommand(error: unknown): string | undefined { + if (error instanceof Error && 'command' in error) { + const command = error.command; + return typeof command === 'string' ? command : undefined; + } + return undefined; +} + +function isMainModule(): boolean { + return Boolean( + process.argv[1] && + path.resolve(process.argv[1]) === path.resolve(fileURLToPath(import.meta.url)), + ); +} diff --git a/scripts/ios-ax-bridge-spike/runner.ts b/scripts/ios-ax-bridge-spike/runner.ts new file mode 100644 index 0000000000..54d8e200ad --- /dev/null +++ b/scripts/ios-ax-bridge-spike/runner.ts @@ -0,0 +1,326 @@ +import { spawnSync } from 'node:child_process'; +import path from 'node:path'; +import { performance } from 'node:perf_hooks'; +import { + classifyFailure, + openFixture, + pressFixtureTarget, + snapshotFixture, + type CliContext, +} from '../ios-snapshot-benchmark/command.ts'; +import { screenFixture, sampleMinimumForState } from '../ios-snapshot-benchmark/definitions.ts'; +import { + BenchmarkInfrastructureError, + bootSimulator, + clearDerivedData, + shutdownSimulator, + stopDaemon, + terminateApp, +} from '../ios-snapshot-benchmark/lifecycle.ts'; +import { appendSamples, makeRequest, type CapturedResponse } from './sample-evidence.ts'; +import type { AcquisitionAdapter, AdapterOptions } from './adapter.ts'; +import type { SpikeConfig } from './config.ts'; +import type { CandidateId, SpikeCell, SpikeRequest, SpikeSample } from './types.ts'; + +export async function runSpikeCells( + config: SpikeConfig, + adapters: readonly AcquisitionAdapter[], +): Promise { + const cells: SpikeCell[] = []; + for (const adapter of adapters) { + for (const state of config.states) { + for (const screen of config.screens) { + cells.push(await runCell(config, adapter, state, screen)); + } + } + } + return cells; +} + +export function createAdapterOptions(config: SpikeConfig): AdapterOptions { + return { + repoRoot: config.repoRoot, + ...(config.privateTool ? { privateTool: config.privateTool } : {}), + ...(config.helperPath ? { helperPath: config.helperPath } : {}), + limits: config.limits, + }; +} + +async function runCell( + config: SpikeConfig, + adapter: AcquisitionAdapter, + state: SpikeConfig['states'][number], + screen: SpikeConfig['screens'][number], +): Promise { + const fixture = screenFixture(screen); + const context = contextFor(config, adapter.candidate, state, screen); + const acquisitionSamples: SpikeSample[] = []; + const presentationSamples: SpikeSample[] = []; + try { + if (state === 'warm') { + const preparationMs = prepareSample(config, context, fixture, state); + const requests = Array.from({ length: config.samples }, (_, index) => + makeRequest(config, adapter.candidate, state, screen, index), + ); + const captured = await captureBatch(adapter, requests); + captured.forEach((item, index) => + appendSamples( + adapter.candidate, + state, + screen, + index, + item, + preparationMs, + acquisitionSamples, + presentationSamples, + ), + ); + } else { + for (let index = 0; index < config.samples; index += 1) { + const preparationMs = prepareSample(config, context, fixture, state); + const request = makeRequest(config, adapter.candidate, state, screen, index); + const captured = await capture(adapter, request); + appendSamples( + adapter.candidate, + state, + screen, + index, + captured, + preparationMs, + acquisitionSamples, + presentationSamples, + ); + closeSession(context); + } + } + return { + candidate: adapter.candidate, + state, + screen, + sampleMinimum: sampleMinimumForState(state), + acquisitionSamples, + presentationSamples, + }; + } finally { + closeSession(context); + stopDaemon(config.repoRoot, config.stateDir); + } +} + +function prepareSample( + config: SpikeConfig, + context: CliContext, + fixture: ReturnType, + state: SpikeConfig['states'][number], +): number { + prepareSimulator(config, context, fixture, state); + const started = performance.now(); + openReadyFixture(context, fixture, state); + return performance.now() - started; +} + +function prepareSimulator( + config: SpikeConfig, + context: CliContext, + fixture: ReturnType, + state: SpikeConfig['states'][number], +): void { + if (state === 'cold-cold') return prepareColdCold(config, context); + bootSimulator(config.udid); + if (state === 'cold') prepareCold(config, fixture); +} + +function prepareColdCold(config: SpikeConfig, context: CliContext): void { + shutdownSimulator(config.udid); + stopDaemon(config.repoRoot, config.stateDir); + clearDerivedData(context.derivedPath); + bootSimulator(config.udid); +} + +function prepareCold(config: SpikeConfig, fixture: ReturnType): void { + stopDaemon(config.repoRoot, config.stateDir); + terminateApp(config.udid, fixture.app); +} + +function openReadyFixture( + context: CliContext, + fixture: ReturnType, + state: SpikeConfig['states'][number], +): void { + const opened = openFixture(context, fixture, { relaunch: requiresRelaunch(state) }); + if (!opened.ok) { + throw preparationError(opened, `open ${fixture.id}`, context, openArguments(fixture, state)); + } + if (fixture.setupAction === 'open-alert') prepareAlert(context, fixture); +} + +function requiresRelaunch(state: SpikeConfig['states'][number]): boolean { + return state === 'relaunch' || state === 'warm'; +} + +function openArguments( + fixture: ReturnType, + state: SpikeConfig['states'][number], +): string[] { + return [ + 'open', + fixture.app, + ...relaunchArguments(state), + ...launchUrlArguments(fixture), + '--foreground', + ]; +} + +function relaunchArguments(state: SpikeConfig['states'][number]): string[] { + return requiresRelaunch(state) ? ['--relaunch'] : []; +} + +function launchUrlArguments(fixture: ReturnType): string[] { + return fixture.launchUrl ? ['--launch-url', fixture.launchUrl] : []; +} + +function prepareAlert(context: CliContext, fixture: ReturnType): void { + const pressed = pressFixtureTarget(context, 'id="automation-open-alert"'); + if (!pressed.ok) { + throw preparationError(pressed, `prepare alert ${fixture.id}`, context, [ + 'click', + 'id="automation-open-alert"', + ]); + } + const observed = snapshotFixture(context); + if (!observed.ok) { + throw preparationError(observed, `observe alert ${fixture.id}`, context, [ + 'batch', + '--steps', + JSON.stringify([{ command: 'snapshot', input: { interactiveOnly: true } }]), + ]); + } +} + +async function capture( + adapter: AcquisitionAdapter, + request: SpikeRequest, +): Promise { + const startedAt = new Date().toISOString(); + const started = performance.now(); + const batch = await adapter.acquireBatch([request]); + const response = batch.responses[0]; + if (!response) { + throw new BenchmarkInfrastructureError(`Adapter ${adapter.candidate} returned no response.`); + } + return { + response, + stderr: batch.stderr, + startedAt, + wallClockMs: performance.now() - started, + }; +} + +async function captureBatch( + adapter: AcquisitionAdapter, + requests: readonly SpikeRequest[], +): Promise { + const startedAt = new Date().toISOString(); + const started = performance.now(); + const batch = await adapter.acquireBatch(requests); + const batchWallClockMs = performance.now() - started; + if (batch.responses.length !== requests.length) { + throw new BenchmarkInfrastructureError( + `Adapter ${adapter.candidate} returned an incomplete batch.`, + ); + } + return batch.responses.map((response) => ({ + response, + stderr: batch.stderr, + startedAt, + wallClockMs: response.metrics.durationMs > 0 ? response.metrics.durationMs : batchWallClockMs, + })); +} + +function contextFor( + config: SpikeConfig, + candidate: CandidateId, + state: SpikeConfig['states'][number], + screen: SpikeConfig['screens'][number], +): CliContext { + return { + repoRoot: config.repoRoot, + stateDir: config.stateDir, + session: `ax-spike-${candidate}-${state}-${screen}`, + udid: config.udid, + derivedPath: path.join(config.derivedPath, candidate, state, screen), + }; +} + +function closeSession(context: CliContext): void { + spawnSync( + process.execPath, + [ + 'bin/agent-device.mjs', + 'close', + '--state-dir', + context.stateDir, + '--session', + context.session, + '--platform', + 'ios', + '--udid', + context.udid, + '--json', + ], + { + cwd: context.repoRoot, + env: { ...process.env, AGENT_DEVICE_NO_UPDATE_NOTIFIER: '1' }, + stdio: 'ignore', + timeout: 60_000, + }, + ); +} + +function preparationError( + result: { payload: unknown; stderr: string; exitCode: number }, + operation: string, + context: CliContext, + args: readonly string[], +): Error { + const failure = classifyFailure(result.payload, result); + return new BenchmarkInfrastructureError( + `${operation} failed during fixture preparation (exit ${result.exitCode}; ${failureDetails(failure, result)})`, + commandFor(context, args), + ); +} + +function failureDetails( + failure: ReturnType, + result: { stderr: string }, +): string { + return `code=${fallbackText(failure.code)}; reason=${fallbackText(failure.reason)}; diagnostic=${diagnosticText(failure.message, result.stderr)}`; +} + +function fallbackText(value: string | undefined): string { + return value ?? 'none'; +} + +function diagnosticText(message: string | undefined, stderr: string): string { + const text = message ?? stderr.trim(); + return (text || 'no diagnostic').slice(0, 800); +} + +function commandFor(context: CliContext, args: readonly string[]): string { + return [ + process.execPath, + 'bin/agent-device.mjs', + ...args, + '--state-dir', + context.stateDir, + '--session', + context.session, + '--platform', + 'ios', + '--udid', + context.udid, + '--ios-xctest-derived-data-path', + context.derivedPath, + '--json', + ].join(' '); +} diff --git a/scripts/ios-ax-bridge-spike/sample-evidence.ts b/scripts/ios-ax-bridge-spike/sample-evidence.ts new file mode 100644 index 0000000000..7a08aad7af --- /dev/null +++ b/scripts/ios-ax-bridge-spike/sample-evidence.ts @@ -0,0 +1,135 @@ +import { firstTreeStatus } from './protocol.ts'; +import { presentAcquisitionForMeasurement } from './presentation.ts'; +import type { SpikeConfig } from './config.ts'; +import type { SpikeCell, SpikeRequest, SpikeResponse, SpikeSample } from './types.ts'; + +export type CapturedResponse = Readonly<{ + response: SpikeResponse; + stderr: string; + startedAt: string; + wallClockMs: number; +}>; + +export function appendSamples( + candidate: SpikeCell['candidate'], + state: SpikeCell['state'], + screen: SpikeCell['screen'], + index: number, + captured: CapturedResponse, + preparationMs: number, + acquisitionSamples: SpikeSample[], + presentationSamples: SpikeSample[], +): void { + const acquiredAt = new Date().toISOString(); + const status = firstTreeStatus(captured.response); + acquisitionSamples.push({ + index: index + 1, + candidate, + state, + screen, + startedAt: captured.startedAt, + finishedAt: acquiredAt, + operation: 'acquisition', + wallClockMs: captured.wallClockMs, + preparationMs, + firstLookMs: preparationMs + captured.wallClockMs, + firstTree: status, + ok: captured.response.ok, + ...(captured.response.acquisition ? { acquisition: captured.response.acquisition } : {}), + metrics: captured.response.metrics, + ...(captured.stderr ? { stderr: captured.stderr } : {}), + ...(captured.response.failure ? { failure: captured.response.failure } : {}), + }); + presentationSamples.push(presentationSample(candidate, state, screen, index, captured, status)); +} + +export function makeRequest( + config: SpikeConfig, + candidate: SpikeCell['candidate'], + state: SpikeCell['state'], + screen: SpikeCell['screen'], + index: number, +): SpikeRequest { + return { + version: 1, + id: `${candidate}:${state}:${screen}:${index + 1}`, + candidate, + simulatorUdid: config.udid, + state, + screen, + appBundleId: config.appBundleId, + ...(config.targetProcessId === undefined ? {} : { targetProcessId: config.targetProcessId }), + limits: config.limits, + }; +} + +function presentationSample( + candidate: SpikeCell['candidate'], + state: SpikeCell['state'], + screen: SpikeCell['screen'], + index: number, + captured: CapturedResponse, + status: SpikeSample['firstTree'], +): SpikeSample { + if (!captured.response.acquisition) + return failedPresentationSample(candidate, state, screen, index, captured, status); + return successfulPresentationSample(candidate, state, screen, index, captured, status); +} + +function failedPresentationSample( + candidate: SpikeCell['candidate'], + state: SpikeCell['state'], + screen: SpikeCell['screen'], + index: number, + captured: CapturedResponse, + status: SpikeSample['firstTree'], +): SpikeSample { + return { + index: index + 1, + candidate, + state, + screen, + startedAt: captured.startedAt, + finishedAt: new Date().toISOString(), + operation: 'presentation', + wallClockMs: 0, + firstTree: status, + ok: false, + ...(captured.stderr ? { stderr: captured.stderr } : {}), + presentation: { + ok: false, + payloadBytes: 0, + nodeCount: 0, + durationMs: 0, + cpuMs: null, + memoryBytes: process.memoryUsage().rss, + }, + ...(captured.response.failure ? { failure: captured.response.failure } : {}), + }; +} + +function successfulPresentationSample( + candidate: SpikeCell['candidate'], + state: SpikeCell['state'], + screen: SpikeCell['screen'], + index: number, + captured: CapturedResponse, + status: SpikeSample['firstTree'], +): SpikeSample { + const presented = presentAcquisitionForMeasurement(captured.response.acquisition!); + return { + index: index + 1, + candidate, + state, + screen, + startedAt: captured.startedAt, + finishedAt: new Date().toISOString(), + operation: 'presentation', + wallClockMs: presented.measurement.durationMs, + firstTree: status, + ok: true, + ...(captured.stderr ? { stderr: captured.stderr } : {}), + acquisition: captured.response.acquisition, + presentation: presented.measurement, + }; +} diff --git a/scripts/ios-ax-bridge-spike/types.ts b/scripts/ios-ax-bridge-spike/types.ts new file mode 100644 index 0000000000..ff1ae67eaa --- /dev/null +++ b/scripts/ios-ax-bridge-spike/types.ts @@ -0,0 +1,223 @@ +import type { + IosAcquisitionResidue, + IosViewportEvidence, +} from '@agent-device/contracts/ios-snapshot'; +import type { DeepButtonEvidence, LocalState, ScreenId } from '../ios-snapshot-benchmark/types.ts'; + +export const SPIKE_SCHEMA_VERSION = 'ios-simulator-ax-bridge-spike.v1' as const; +export const SPIKE_ISSUE = '#2192' as const; +export const SPIKE_PARENT = '#2188' as const; +export const SPIKE_PREREQUISITES = ['#2189', '#2190'] as const; + +export type CandidateId = 'public-macos-ax' | 'private-coresimulator-ax' | 'xctest-control'; + +export type SpikeFailureKind = + | 'unsupported-mechanism' + | 'malformed-tree' + | 'stale-generation' + | 'timeout' + | 'cancelled' + | 'process-crash' + | 'transport-failure'; + +export type SpikeFailure = Readonly<{ + kind: SpikeFailureKind; + code?: string; + expectedTargetGeneration?: string; + observedTargetGeneration?: string; +}>; + +export type SpikeRect = Readonly<{ + x: number; + y: number; + width: number; + height: number; +}>; + +export type RawAcquiredNode = Readonly<{ + id: string; + parentId?: string; + role?: string; + subrole?: string; + label?: string; + value?: string; + identifier?: string; + frame?: SpikeRect; + enabled?: boolean; + selected?: boolean; + focused?: boolean; +}>; + +export type RawAcquisition = Readonly<{ + targetId: string; + targetGeneration: string | null; + nodes: readonly RawAcquiredNode[]; + viewport: IosViewportEvidence; + truncated: boolean; + residue: readonly IosAcquisitionResidue[]; +}>; + +export type ResourceLimits = Readonly<{ + maxRequestBytes: number; + maxResponseBytes: number; + maxNodes: number; + maxTraversalDepth: number; + maxCpuMs: number; + maxMemoryBytes: number; + maxDurationMs: number; +}>; + +export type ResourceMetrics = Readonly<{ + requestBytes: number; + responseBytes: number; + nodeCount: number; + maxTraversalDepth: number; + cpuMs: number | null; + memoryBytes: number | null; + durationMs: number; +}>; + +export type SpikeRequest = Readonly<{ + version: 1; + id: string; + candidate: CandidateId; + simulatorUdid: string; + state: LocalState; + screen: ScreenId; + appBundleId: string; + targetProcessId?: number; + expectedTargetGeneration?: string; + limits: ResourceLimits; +}>; + +export type SpikeResponse = Readonly<{ + version: 1; + id: string; + candidate: CandidateId; + ok: boolean; + acquisition?: RawAcquisition; + failure?: SpikeFailure; + metrics: ResourceMetrics; +}>; + +export type PresentationMeasurement = Readonly<{ + ok: boolean; + payloadBytes: number; + nodeCount: number; + durationMs: number; + cpuMs: number | null; + memoryBytes: number | null; +}>; + +export type SpikeSample = Readonly<{ + index: number; + candidate: CandidateId; + state: LocalState; + screen: ScreenId; + startedAt: string; + finishedAt: string; + operation: 'acquisition' | 'presentation'; + wallClockMs: number; + preparationMs?: number; + firstLookMs?: number; + firstTree: 'readable' | 'empty' | 'unreadable' | 'not-observed'; + ok: boolean; + stderr?: string; + acquisition?: RawAcquisition; + metrics?: ResourceMetrics; + presentation?: PresentationMeasurement; + failure?: SpikeFailure; +}>; + +export type ProtocolProbeLog = Readonly<{ + candidate: Exclude; + id: string; + stderr: string; +}>; + +export type SpikeCell = Readonly<{ + candidate: CandidateId; + state: LocalState; + screen: ScreenId; + sampleMinimum: number; + acquisitionSamples: readonly SpikeSample[]; + presentationSamples: readonly SpikeSample[]; +}>; + +export type Toolchain = Readonly<{ + node: string; + pnpm: string; + xcode: string; + simctl: string; + os: string; + arch: string; + swift: string; +}>; + +export type Target = Readonly<{ + udid: string; + name: string; + runtime: string; +}>; + +export type PlistKeyChange = Readonly<{ + key: string; + before?: unknown; + after?: unknown; +}>; + +export type PlistDiff = Readonly<{ + path: string; + existedBefore: boolean; + beforeSha256: string | null; + afterSha256: string | null; + changes: readonly PlistKeyChange[]; +}>; + +export type PreferenceEvidence = Readonly<{ + applied: boolean; + restored: boolean; + simulatorStateBefore: string; + diffs: readonly PlistDiff[]; +}>; + +export type LifecycleEvidence = Readonly<{ + source: 'framed-protocol-fixture'; + crash: Readonly<{ failure: SpikeFailureKind; recovered: boolean }>; + timeout: Readonly<{ failure: SpikeFailureKind; recovered: boolean }>; + cancellation: Readonly<{ failure: SpikeFailureKind; recovered: boolean }>; + staleGeneration: Readonly<{ failure: SpikeFailureKind; recovered: boolean }>; +}>; + +export type SpikeReport = Readonly<{ + schemaVersion: typeof SPIKE_SCHEMA_VERSION; + issue: typeof SPIKE_ISSUE; + parent: typeof SPIKE_PARENT; + prerequisites: readonly string[]; + generatedAt: string; + revision: Readonly<{ commit: string; branch: string; dirty: boolean }>; + toolchain: Toolchain; + target: Target; + limits: ResourceLimits; + status: 'completed' | 'stopped'; + candidates: readonly CandidateId[]; + config: Readonly<{ + states: readonly LocalState[]; + screens: readonly ScreenId[]; + requestedSamples: number; + }>; + protocolProbes: readonly SpikeResponse[]; + protocolProbeLogs: readonly ProtocolProbeLog[]; + preferenceEvidence: PreferenceEvidence; + lifecycle: LifecycleEvidence; + positiveControl: DeepButtonEvidence; + cells: readonly SpikeCell[]; + decision: 'GO' | 'NO-GO'; + decisionReasons: readonly string[]; + nextInterface: string; + stop?: Readonly<{ + category: 'infrastructure' | 'configuration'; + message: string; + command?: string; + }>; +}>; diff --git a/vitest.config.ts b/vitest.config.ts index f34ea31fff..fd59b8044e 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -147,10 +147,11 @@ export default defineConfig({ // The Bundle Size lane's PR-comment path: spawns the real script against a // stubbed fetch, so it needs no network; pins retry/reconcile/fatal outcomes. 'scripts/__tests__/size-report-post-comment.test.ts', - // Package attribution models npm-pack output. Keep it in the fast lane so every new - // package path remains accounted for. + // Package attribution is a pure npm-pack manifest model. Keep it in the fast lane so + // every new package path remains accounted for without building an archive. 'scripts/__tests__/size-report-package.test.ts', 'scripts/ios-snapshot-benchmark/*.test.ts', + 'scripts/ios-ax-bridge-spike/*.test.ts', // Parses CI configuration only, so this action guard needs no device or subprocess lane. 'test/ci/upload-agent-device-artifacts.test.ts', 'test/ci/upload-artifact-hidden-paths.test.ts', From 69d84ab0273b8a230e753bd544c4a5d2fefd925c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 09:38:48 +0200 Subject: [PATCH 02/29] fix(ios): use snapshot planning subpath in AX spike --- scripts/ios-ax-bridge-spike/presentation.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/ios-ax-bridge-spike/presentation.ts b/scripts/ios-ax-bridge-spike/presentation.ts index 7759aaedf6..8cb1cdd54c 100644 --- a/scripts/ios-ax-bridge-spike/presentation.ts +++ b/scripts/ios-ax-bridge-spike/presentation.ts @@ -1,5 +1,8 @@ import { performance } from 'node:perf_hooks'; -import { createIosSnapshotRequest, deriveIosCaptureHint } from '@agent-device/capture-kit'; +import { + createIosSnapshotRequest, + deriveIosCaptureHint, +} from '@agent-device/capture-kit/ios-snapshot-planning'; import type { IosSnapshotAcquisition } from '@agent-device/contracts/ios-snapshot'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import type { PresentationMeasurement, RawAcquisition } from './types.ts'; From 14419ee788ae2fde955b13083bad81bb7bfd24ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 09:42:12 +0200 Subject: [PATCH 03/29] docs(ios): record AX bridge spike NO-GO evidence --- .../ios-simulator-ax-bridge-2026-09-01.json | 195 ++++++++++++++++++ .../ios-simulator-ax-bridge-2026-09-01.md | 87 ++++++++ 2 files changed, 282 insertions(+) create mode 100644 docs/evidence/ios-simulator-ax-bridge-2026-09-01.json create mode 100644 docs/evidence/ios-simulator-ax-bridge-2026-09-01.md diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json new file mode 100644 index 0000000000..1ee0aa9639 --- /dev/null +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json @@ -0,0 +1,195 @@ +{ + "schemaVersion": "ios-simulator-ax-bridge-spike.v1", + "issue": "#2192", + "parent": "#2188", + "prerequisites": ["#2189", "#2190"], + "generatedAt": "2026-09-01T07:40:59.071Z", + "revision": { + "commit": "a1c250b5cf63ee387935b17d3f81edc9f69abb97", + "branch": "codex/2192-ios-ax-bridge-spike", + "dirty": true + }, + "toolchain": { + "node": "v26.7.0", + "pnpm": "11.19.0", + "xcode": "Xcode 27.0\nBuild version 27A5252f", + "simctl": "@(#)PROGRAM:simctl PROJECT:CoreSimulator-1171.6", + "os": "darwin 27.0.0", + "arch": "arm64", + "swift": "Apple Swift version 6.4 (swiftlang-6.4.0.33.1 clang-2100.3.33.1)\nTarget: arm64-apple-macosx27.0.0" + }, + "target": { + "udid": "793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4", + "name": "AgentDevice-2192-AX-20260901", + "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-27-0" + }, + "limits": { + "maxRequestBytes": 65536, + "maxResponseBytes": 4194304, + "maxNodes": 1500, + "maxTraversalDepth": 12, + "maxCpuMs": 2000, + "maxMemoryBytes": 268435456, + "maxDurationMs": 5000 + }, + "candidates": ["public-macos-ax", "private-coresimulator-ax", "xctest-control"], + "config": { + "states": ["cold-cold", "cold", "warm", "relaunch"], + "screens": ["quiet", "list", "nested-scroll", "alert", "system-surface", "xctest-stress"], + "requestedSamples": 20 + }, + "protocolProbes": [ + { + "version": 1, + "id": "protocol-probe:public-macos-ax", + "candidate": "public-macos-ax", + "ok": false, + "failure": { + "kind": "unsupported-mechanism", + "code": "host-accessibility-permission" + }, + "metrics": { + "requestBytes": 395, + "responseBytes": 331, + "nodeCount": 0, + "maxTraversalDepth": 0, + "cpuMs": 3.015999999999999, + "memoryBytes": 9011200, + "durationMs": 37.457958 + } + }, + { + "version": 1, + "id": "protocol-probe:private-coresimulator-ax", + "candidate": "private-coresimulator-ax", + "ok": false, + "failure": { + "kind": "unsupported-mechanism", + "code": "private-tool-unavailable" + }, + "metrics": { + "requestBytes": 413, + "responseBytes": 0, + "nodeCount": 0, + "maxTraversalDepth": 0, + "cpuMs": null, + "memoryBytes": null, + "durationMs": 0 + } + } + ], + "protocolProbeLogs": [ + { + "candidate": "public-macos-ax", + "id": "protocol-probe:public-macos-ax", + "stderr": "[ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=quiet\n" + }, + { + "candidate": "private-coresimulator-ax", + "id": "protocol-probe:private-coresimulator-ax", + "stderr": "" + } + ], + "preferenceEvidence": { + "applied": true, + "restored": true, + "simulatorStateBefore": "Shutdown", + "diffs": [ + { + "path": "/Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.Accessibility.plist", + "existedBefore": true, + "beforeSha256": "fbc67ebbd3aa0079a4b4afff4181280731fbb8faaca2ffc623393a8d9c26a436", + "afterSha256": "725b6bb8efe60c8c6d5768aebcec0b9f6af5cee185f0430a7d1ab62953428147", + "changes": [ + { + "key": "AccessibilityEnabled", + "after": true + }, + { + "key": "ApplicationAccessibilityEnabled", + "after": true + }, + { + "key": "AutomationEnabled", + "after": true + }, + { + "key": "IgnoreAXServerEntitlements", + "after": true + } + ] + }, + { + "path": "/Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.UIAutomation.plist", + "existedBefore": true, + "beforeSha256": "db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c", + "afterSha256": "db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c", + "changes": [] + } + ] + }, + "lifecycle": { + "source": "framed-protocol-fixture", + "crash": { + "failure": "process-crash", + "recovered": true + }, + "timeout": { + "failure": "timeout", + "recovered": true + }, + "cancellation": { + "failure": "cancelled", + "recovered": true + }, + "staleGeneration": { + "failure": "stale-generation", + "recovered": true + } + }, + "positiveControl": { + "issue": "#1626", + "fixture": "deep-button-v1", + "changedDescendant": "deep-button-state", + "invalidShallowRule": { + "command": "pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow", + "exitCode": 1, + "assertion": "AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid." + }, + "safeFullRule": { + "command": "pnpm bench:ios-snapshot:deep-button -- --rule safe-full", + "exitCode": 0, + "assertion": "full observation changed and includes the changed descendant." + }, + "before": { + "surfaceDigest": "cce3230d667fd7292340daaf491fac48b45ba80fba846038bee2f82bf2489a85", + "fullDigest": "993a4f50b3bdac7821f0964dcb589f31deb9a6f1c1ca72c5c0d718088fbdf89b", + "state": "off", + "surfaceNodeIds": ["deep-button-root", "deep-button-container"], + "fullNodeIds": ["deep-button-root", "deep-button-container", "deep-button-state"] + }, + "after": { + "surfaceDigest": "cce3230d667fd7292340daaf491fac48b45ba80fba846038bee2f82bf2489a85", + "fullDigest": "4be81b73f2318615532a2b86dbba8a555f7c84995809d469a1c249d09cb7f55e", + "state": "on", + "surfaceNodeIds": ["deep-button-root", "deep-button-container"], + "fullNodeIds": ["deep-button-root", "deep-button-container", "deep-button-state"] + } + }, + "status": "stopped", + "cells": [], + "decision": "NO-GO", + "decisionReasons": [ + "The live run stopped before the full corpus completed.", + "public-macos-ax protocol probe returned unsupported-mechanism/host-accessibility-permission.", + "private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable.", + "public-macos-ax produced no cells.", + "private-coresimulator-ax produced no cells." + ], + "nextInterface": "Keep any future bridge behind the #2190 acquisition adapter and preserve raw facts until a separate GO evidence run proves fidelity, lifecycle, and latency.", + "stop": { + "category": "infrastructure", + "message": "open quiet failed during fixture preparation (exit 1; code=COMMAND_FAILED; reason=none; diagnostic=Simulator device failed to open agent-device-test-app:///inert.)", + "command": "/opt/homebrew/Cellar/node/26.7.0/bin/node bin/agent-device.mjs open com.callstack.agentdevicelab --launch-url agent-device-test-app:///inert --foreground --state-dir /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-n3rBW5 --session ax-spike-public-macos-ax-cold-cold-quiet --platform ios --udid 793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 --ios-xctest-derived-data-path /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-n3rBW5/derived-data/public-macos-ax/cold-cold/quiet --json" + } +} diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md new file mode 100644 index 0000000000..c0f2ae97c1 --- /dev/null +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -0,0 +1,87 @@ +# iOS Simulator AX bridge spike + +- Decision: **NO-GO** +- Status: **stopped** +- Revision: a1c250b5cf63ee387935b17d3f81edc9f69abb97 (codex/2192-ios-ax-bridge-spike) +- Target: AgentDevice-2192-AX-20260901 (793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4, com.apple.CoreSimulator.SimRuntime.iOS-27-0) +- Generated: 2026-09-01T07:40:59.071Z +- Corpus: states=cold-cold, cold, warm, relaunch, screens=quiet, list, nested-scroll, alert, system-surface, xctest-stress, samples=20 + +## Environment and limits + +- Node: v26.7.0 +- pnpm: 11.19.0 +- Xcode: Xcode 27.0; Build version 27A5252f +- simctl: @(#)PROGRAM:simctl PROJECT:CoreSimulator-1171.6 +- Swift: Apple Swift version 6.4 (swiftlang-6.4.0.33.1 clang-2100.3.33.1) +Target: arm64-apple-macosx27.0.0 +- OS: darwin 27.0.0; arch=arm64 +- Bounds: request=65536 B, response=4194304 B, nodes=1500, traversal=12, CPU=2000 ms, memory=268435456 B, duration=5000 ms + +## Candidate fidelity and limitation matrix + +| Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation | +|---|---|---|---|---|---| +| public-macos-ax | public macOS ApplicationServices AX | protocol probe only | protocol probe only | framed protocol | host Accessibility permission and Xcode 27 DeviceHub surface | +| private-coresimulator-ax | external/private CoreSimulator AX tool | protocol probe only | protocol probe only | framed protocol contract only | private interface/tool compatibility | +| xctest-control | #2189 XCTest runner control | not observed (run stopped) | not observed (run stopped) | existing runner lifecycle | control, not a host-side AX bridge | + +## Raw acquisition and prototype presentation results + +| Candidate | State | Screen | N | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures | +|---|---|---|---:|---:|---:|---:|---:|---:| + +Acquisition samples retain the raw node payload, viewport evidence, target generation, truncation, residue, and resource metrics. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction. + +## Direct protocol probes + +- public-macos-ax/protocol-probe:public-macos-ax: ok=false, failure=unsupported-mechanism, code=host-accessibility-permission, nodes=0, duration=37.5 ms, CPU=3.0 ms, memory=9011200 B, response=331 B +- private-coresimulator-ax/protocol-probe:private-coresimulator-ax: ok=false, failure=unsupported-mechanism, code=private-tool-unavailable, nodes=0, duration=0.0 ms, CPU=– ms, memory=– B, response=0 B +- stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=quiet +- stderr private-coresimulator-ax/protocol-probe:private-coresimulator-ax: empty + +## Independent positive-control evidence + +- Invalid shallow rule: exit=1; command=pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow; assertion=AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid. +- Safe full rule: exit=0; command=pnpm bench:ios-snapshot:deep-button -- --rule safe-full; assertion=full observation changed and includes the changed descendant. + +## Preference experiment + +- Applied: **true** +- Restored: **true** +- Simulator state before experiment: Shutdown +- Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored. +- /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=fbc67ebbd3aa0079a4b4afff4181280731fbb8faaca2ffc623393a8d9c26a436, afterSha256=725b6bb8efe60c8c6d5768aebcec0b9f6af5cee185f0430a7d1ab62953428147 + - Changes: AccessibilityEnabled: undefined -> true; ApplicationAccessibilityEnabled: undefined -> true; AutomationEnabled: undefined -> true; IgnoreAXServerEntitlements: undefined -> true +- /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.UIAutomation.plist: existed=true, beforeSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c, afterSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c + - Changes: none + +## Lifecycle, cancellation, and recovery + +- Source: framed-protocol-fixture +- Process crash: process-crash; recovered=true +- Timeout: timeout; recovered=true +- Cancellation: cancelled; recovered=true +- Stale generation: stale-generation; recovered=true + +## Decision rationale + +- The live run stopped before the full corpus completed. +- public-macos-ax protocol probe returned unsupported-mechanism/host-accessibility-permission. +- private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable. +- public-macos-ax produced no cells. +- private-coresimulator-ax produced no cells. + +## Next interface boundary + +- Keep any future bridge behind the #2190 acquisition adapter and preserve raw facts until a separate GO evidence run proves fidelity, lifecycle, and latency. + +## Production boundary + +- No production backend selection, fallback, runner-demand, open/relaunch, proxy, XCTest interaction, or public CLI changes were made. +- A production bridge should not start until this report has a GO result; this run is the #2192 boundary. + +## Stop condition + +- infrastructure: open quiet failed during fixture preparation (exit 1; code=COMMAND_FAILED; reason=none; diagnostic=Simulator device failed to open agent-device-test-app:///inert.) +- Command: /opt/homebrew/Cellar/node/26.7.0/bin/node bin/agent-device.mjs open com.callstack.agentdevicelab --launch-url agent-device-test-app:///inert --foreground --state-dir /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-n3rBW5 --session ax-spike-public-macos-ax-cold-cold-quiet --platform ios --udid 793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 --ios-xctest-derived-data-path /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-n3rBW5/derived-data/public-macos-ax/cold-cold/quiet --json From 9eae6678cacca66ee23c1b6f0f9f4b18333f89d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 09:43:39 +0200 Subject: [PATCH 04/29] docs(ios): add fixture stop diagnostics --- .../ios-simulator-ax-bridge-2026-09-01.json | 18 ++++++++--------- .../ios-simulator-ax-bridge-2026-09-01.md | 20 ++++++++++++++----- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json index 1ee0aa9639..ac16910c8f 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json @@ -3,11 +3,11 @@ "issue": "#2192", "parent": "#2188", "prerequisites": ["#2189", "#2190"], - "generatedAt": "2026-09-01T07:40:59.071Z", + "generatedAt": "2026-09-01T07:42:38.929Z", "revision": { - "commit": "a1c250b5cf63ee387935b17d3f81edc9f69abb97", + "commit": "590705e193fb65421b5faffa7573cc1108bbf972", "branch": "codex/2192-ios-ax-bridge-spike", - "dirty": true + "dirty": false }, "toolchain": { "node": "v26.7.0", @@ -50,12 +50,12 @@ }, "metrics": { "requestBytes": 395, - "responseBytes": 331, + "responseBytes": 332, "nodeCount": 0, "maxTraversalDepth": 0, - "cpuMs": 3.015999999999999, - "memoryBytes": 9011200, - "durationMs": 37.457958 + "cpuMs": 2.9109999999999996, + "memoryBytes": 9076736, + "durationMs": 27.875416 } }, { @@ -99,7 +99,7 @@ "path": "/Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.Accessibility.plist", "existedBefore": true, "beforeSha256": "fbc67ebbd3aa0079a4b4afff4181280731fbb8faaca2ffc623393a8d9c26a436", - "afterSha256": "725b6bb8efe60c8c6d5768aebcec0b9f6af5cee185f0430a7d1ab62953428147", + "afterSha256": "1b0bc929597307d4b0acd5b7ccf86d93dae01b36c3930ccc2ef69eba12b09610", "changes": [ { "key": "AccessibilityEnabled", @@ -190,6 +190,6 @@ "stop": { "category": "infrastructure", "message": "open quiet failed during fixture preparation (exit 1; code=COMMAND_FAILED; reason=none; diagnostic=Simulator device failed to open agent-device-test-app:///inert.)", - "command": "/opt/homebrew/Cellar/node/26.7.0/bin/node bin/agent-device.mjs open com.callstack.agentdevicelab --launch-url agent-device-test-app:///inert --foreground --state-dir /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-n3rBW5 --session ax-spike-public-macos-ax-cold-cold-quiet --platform ios --udid 793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 --ios-xctest-derived-data-path /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-n3rBW5/derived-data/public-macos-ax/cold-cold/quiet --json" + "command": "/opt/homebrew/Cellar/node/26.7.0/bin/node bin/agent-device.mjs open com.callstack.agentdevicelab --launch-url agent-device-test-app:///inert --foreground --state-dir /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-YnARfy --session ax-spike-public-macos-ax-cold-cold-quiet --platform ios --udid 793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 --ios-xctest-derived-data-path /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-YnARfy/derived-data/public-macos-ax/cold-cold/quiet --json" } } diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index c0f2ae97c1..81ff724c2a 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -2,9 +2,9 @@ - Decision: **NO-GO** - Status: **stopped** -- Revision: a1c250b5cf63ee387935b17d3f81edc9f69abb97 (codex/2192-ios-ax-bridge-spike) +- Revision: 590705e193fb65421b5faffa7573cc1108bbf972 (codex/2192-ios-ax-bridge-spike) - Target: AgentDevice-2192-AX-20260901 (793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4, com.apple.CoreSimulator.SimRuntime.iOS-27-0) -- Generated: 2026-09-01T07:40:59.071Z +- Generated: 2026-09-01T07:42:38.929Z - Corpus: states=cold-cold, cold, warm, relaunch, screens=quiet, list, nested-scroll, alert, system-surface, xctest-stress, samples=20 ## Environment and limits @@ -18,6 +18,16 @@ Target: arm64-apple-macosx27.0.0 - OS: darwin 27.0.0; arch=arm64 - Bounds: request=65536 B, response=4194304 B, nodes=1500, traversal=12, CPU=2000 ms, memory=268435456 B, duration=5000 ms +## Dependency and fixture provenance + +- #2190 exact live prerequisite head: `bce60b56fb5c5c8d57247e0946fa1fd540e292a1` (`codex/refactor/ios-snapshot-contracts`, PR #2203). +- #2189 exact foundation integrated as a separate merge parent: `e90b7763c8023857a054954ac200a95825ffae12`. +- The fixture dependency install completed with `pnpm test-app:install`; that command installs the example app dependencies and does not produce an iOS `.app`. +- Direct fixture build command: + `xcodebuild -workspace examples/test-app/ios/AgentDeviceTester.xcworkspace -scheme AgentDeviceTester -configuration Debug -sdk iphonesimulator -destination id=793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 -derivedDataPath .tmp/ios-ax-app-derived CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build` +- The build stopped at `expo-modules-jsi@56.0.10` `JavaScriptRuntime.swift:219:35` with `a C function pointer can only be formed from a reference to a 'func' or a literal closure`; retrying with `SWIFT_VERSION=5.9` produced the same compiler error. No installable `AgentDeviceTester.app` was produced. +- The fixture run therefore stopped before cell acquisition; no latency result is claimed for the four requested states or six requested screens. + ## Candidate fidelity and limitation matrix | Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation | @@ -35,7 +45,7 @@ Acquisition samples retain the raw node payload, viewport evidence, target gener ## Direct protocol probes -- public-macos-ax/protocol-probe:public-macos-ax: ok=false, failure=unsupported-mechanism, code=host-accessibility-permission, nodes=0, duration=37.5 ms, CPU=3.0 ms, memory=9011200 B, response=331 B +- public-macos-ax/protocol-probe:public-macos-ax: ok=false, failure=unsupported-mechanism, code=host-accessibility-permission, nodes=0, duration=27.9 ms, CPU=2.9 ms, memory=9076736 B, response=332 B - private-coresimulator-ax/protocol-probe:private-coresimulator-ax: ok=false, failure=unsupported-mechanism, code=private-tool-unavailable, nodes=0, duration=0.0 ms, CPU=– ms, memory=– B, response=0 B - stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=quiet - stderr private-coresimulator-ax/protocol-probe:private-coresimulator-ax: empty @@ -51,7 +61,7 @@ Acquisition samples retain the raw node payload, viewport evidence, target gener - Restored: **true** - Simulator state before experiment: Shutdown - Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored. -- /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=fbc67ebbd3aa0079a4b4afff4181280731fbb8faaca2ffc623393a8d9c26a436, afterSha256=725b6bb8efe60c8c6d5768aebcec0b9f6af5cee185f0430a7d1ab62953428147 +- /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=fbc67ebbd3aa0079a4b4afff4181280731fbb8faaca2ffc623393a8d9c26a436, afterSha256=1b0bc929597307d4b0acd5b7ccf86d93dae01b36c3930ccc2ef69eba12b09610 - Changes: AccessibilityEnabled: undefined -> true; ApplicationAccessibilityEnabled: undefined -> true; AutomationEnabled: undefined -> true; IgnoreAXServerEntitlements: undefined -> true - /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.UIAutomation.plist: existed=true, beforeSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c, afterSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c - Changes: none @@ -84,4 +94,4 @@ Acquisition samples retain the raw node payload, viewport evidence, target gener ## Stop condition - infrastructure: open quiet failed during fixture preparation (exit 1; code=COMMAND_FAILED; reason=none; diagnostic=Simulator device failed to open agent-device-test-app:///inert.) -- Command: /opt/homebrew/Cellar/node/26.7.0/bin/node bin/agent-device.mjs open com.callstack.agentdevicelab --launch-url agent-device-test-app:///inert --foreground --state-dir /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-n3rBW5 --session ax-spike-public-macos-ax-cold-cold-quiet --platform ios --udid 793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 --ios-xctest-derived-data-path /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-n3rBW5/derived-data/public-macos-ax/cold-cold/quiet --json +- Command: /opt/homebrew/Cellar/node/26.7.0/bin/node bin/agent-device.mjs open com.callstack.agentdevicelab --launch-url agent-device-test-app:///inert --foreground --state-dir /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-YnARfy --session ax-spike-public-macos-ax-cold-cold-quiet --platform ios --udid 793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 --ios-xctest-derived-data-path /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-YnARfy/derived-data/public-macos-ax/cold-cold/quiet --json From 8895d5e858df6f40c5231c2ac68893d2fe41d6a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 10:38:56 +0200 Subject: [PATCH 05/29] docs(ios): refresh prerequisite provenance --- docs/evidence/ios-simulator-ax-bridge-2026-09-01.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 81ff724c2a..5fbcd6df78 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -21,7 +21,8 @@ Target: arm64-apple-macosx27.0.0 ## Dependency and fixture provenance - #2190 exact live prerequisite head: `bce60b56fb5c5c8d57247e0946fa1fd540e292a1` (`codex/refactor/ios-snapshot-contracts`, PR #2203). -- #2189 exact foundation integrated as a separate merge parent: `e90b7763c8023857a054954ac200a95825ffae12`. +- #2189 exact foundation used for this evidence: `e90b7763c8023857a054954ac200a95825ffae12`. +- Current integrated #2189 prerequisite head: `562406bb38bc3bd14b1e8287add94ba68c36c84e` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. - The fixture dependency install completed with `pnpm test-app:install`; that command installs the example app dependencies and does not produce an iOS `.app`. - Direct fixture build command: `xcodebuild -workspace examples/test-app/ios/AgentDeviceTester.xcworkspace -scheme AgentDeviceTester -configuration Debug -sdk iphonesimulator -destination id=793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 -derivedDataPath .tmp/ios-ax-app-derived CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build` From 300bbe809a990034e225179fd2949f1e00c09394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 10:43:32 +0200 Subject: [PATCH 06/29] docs(ios): record current prerequisite head --- docs/evidence/ios-simulator-ax-bridge-2026-09-01.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 5fbcd6df78..346b6186b7 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -22,7 +22,7 @@ Target: arm64-apple-macosx27.0.0 - #2190 exact live prerequisite head: `bce60b56fb5c5c8d57247e0946fa1fd540e292a1` (`codex/refactor/ios-snapshot-contracts`, PR #2203). - #2189 exact foundation used for this evidence: `e90b7763c8023857a054954ac200a95825ffae12`. -- Current integrated #2189 prerequisite head: `562406bb38bc3bd14b1e8287add94ba68c36c84e` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. +- Current integrated #2189 prerequisite head: `80ed800a1991d65f129e16c5165f33ea3169da04` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. - The fixture dependency install completed with `pnpm test-app:install`; that command installs the example app dependencies and does not produce an iOS `.app`. - Direct fixture build command: `xcodebuild -workspace examples/test-app/ios/AgentDeviceTester.xcworkspace -scheme AgentDeviceTester -configuration Debug -sdk iphonesimulator -destination id=793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 -derivedDataPath .tmp/ios-ax-app-derived CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build` From 52177854cfe987de7b357164560327d675554a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 11:09:17 +0200 Subject: [PATCH 07/29] docs(ios): record current prerequisite head --- docs/evidence/ios-simulator-ax-bridge-2026-09-01.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 346b6186b7..81cc256581 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -22,7 +22,7 @@ Target: arm64-apple-macosx27.0.0 - #2190 exact live prerequisite head: `bce60b56fb5c5c8d57247e0946fa1fd540e292a1` (`codex/refactor/ios-snapshot-contracts`, PR #2203). - #2189 exact foundation used for this evidence: `e90b7763c8023857a054954ac200a95825ffae12`. -- Current integrated #2189 prerequisite head: `80ed800a1991d65f129e16c5165f33ea3169da04` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. +- Current integrated #2189 prerequisite head: `747a939adbdf15332463736241ab140180b41d9f` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. - The fixture dependency install completed with `pnpm test-app:install`; that command installs the example app dependencies and does not produce an iOS `.app`. - Direct fixture build command: `xcodebuild -workspace examples/test-app/ios/AgentDeviceTester.xcworkspace -scheme AgentDeviceTester -configuration Debug -sdk iphonesimulator -destination id=793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 -derivedDataPath .tmp/ios-ax-app-derived CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build` From 0661f112e0b081fcb468a84ca8e5de79a3725a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 11:14:56 +0200 Subject: [PATCH 08/29] ci: refresh exact-head pull request checks From acf614c99a58acb1e39af38e23673b109a9c6e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 11:37:37 +0200 Subject: [PATCH 09/29] fix(ios-ax-bridge): preserve raw control node types --- .../Protocol.swift | 1 + .../RawAccessibility.swift | 1 + .../ios-simulator-ax-bridge-2026-09-01.md | 1 + scripts/ios-ax-bridge-spike/adapter.test.ts | 28 +++++++++++++++++++ scripts/ios-ax-bridge-spike/adapter.ts | 9 +++--- scripts/ios-ax-bridge-spike/limits.test.ts | 7 +++-- scripts/ios-ax-bridge-spike/limits.ts | 3 +- .../ios-ax-bridge-spike/presentation.test.ts | 8 +++++- scripts/ios-ax-bridge-spike/presentation.ts | 3 +- scripts/ios-ax-bridge-spike/types.ts | 1 + 10 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 scripts/ios-ax-bridge-spike/adapter.test.ts diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift index 7849cb75a9..ec2ccdf5ad 100644 --- a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift @@ -32,6 +32,7 @@ struct SpikeRect: Encodable { struct SpikeNode: Encodable { let id: String + let type: String? let parentId: String? let role: String? let subrole: String? diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift index bbd94d8e4b..5299b6a333 100644 --- a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift @@ -157,6 +157,7 @@ private func appendRawNode( state.nodes.append( SpikeNode( id: id, + type: nil, parentId: parentId, role: axString(element, kAXRoleAttribute as String), subrole: axString(element, kAXSubroleAttribute as String), diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 81cc256581..2d4f888196 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -62,6 +62,7 @@ Acquisition samples retain the raw node payload, viewport evidence, target gener - Restored: **true** - Simulator state before experiment: Shutdown - Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored. +- Simulator deletion was not observed by this run; only shutdown and plist restoration are claimed. - /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=fbc67ebbd3aa0079a4b4afff4181280731fbb8faaca2ffc623393a8d9c26a436, afterSha256=1b0bc929597307d4b0acd5b7ccf86d93dae01b36c3930ccc2ef69eba12b09610 - Changes: AccessibilityEnabled: undefined -> true; ApplicationAccessibilityEnabled: undefined -> true; AutomationEnabled: undefined -> true; IgnoreAXServerEntitlements: undefined -> true - /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.UIAutomation.plist: existed=true, beforeSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c, afterSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c diff --git a/scripts/ios-ax-bridge-spike/adapter.test.ts b/scripts/ios-ax-bridge-spike/adapter.test.ts new file mode 100644 index 0000000000..eb7f0f73ef --- /dev/null +++ b/scripts/ios-ax-bridge-spike/adapter.test.ts @@ -0,0 +1,28 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { readControlSnapshot } from './adapter.ts'; + +test('control mapping preserves the producer raw node type', () => { + const result = readControlSnapshot({ + data: { + results: [ + { + data: { + snapshot: { + nodes: [ + { + index: 7, + type: 'XCUIElementTypeButton', + role: 'AXButton', + }, + ], + }, + }, + }, + ], + }, + }); + + assert.equal(result?.nodes[0]?.type, 'XCUIElementTypeButton'); + assert.equal(result?.nodes[0]?.role, 'AXButton'); +}); diff --git a/scripts/ios-ax-bridge-spike/adapter.ts b/scripts/ios-ax-bridge-spike/adapter.ts index ec31816f4d..d82e5185e9 100644 --- a/scripts/ios-ax-bridge-spike/adapter.ts +++ b/scripts/ios-ax-bridge-spike/adapter.ts @@ -200,14 +200,14 @@ function controlFailureKind( return 'transport-failure'; } -type ControlSnapshot = { +export type ControlSnapshot = Readonly<{ nodes: RawAcquiredNode[]; targetGeneration: string | null; truncated: boolean; viewport: { kind: 'missing'; reason: 'not-provided' }; -}; +}>; -function readControlSnapshot(value: unknown): ControlSnapshot | undefined { +export function readControlSnapshot(value: unknown): ControlSnapshot | undefined { const snapshot = findSnapshotRecord(value); if (!snapshot || !Array.isArray(snapshot.nodes)) return undefined; const nodes = snapshot.nodes.flatMap((rawNode) => toRawNode(rawNode)); @@ -266,6 +266,7 @@ function toRawNode(value: unknown): RawAcquiredNode[] { function rawNodeFacts(node: Record): Partial { return { ...optionalParent(node.parentIndex), + ...optionalString(node, 'type'), ...optionalString(node, 'role'), ...optionalString(node, 'subrole'), ...optionalString(node, 'label'), @@ -289,7 +290,7 @@ function readGeneration(snapshot: Record): string | null { function optionalString( recordValue: Record, - key: 'role' | 'subrole' | 'label' | 'value' | 'identifier', + key: 'type' | 'role' | 'subrole' | 'label' | 'value' | 'identifier', ): Partial { return typeof recordValue[key] === 'string' ? { [key]: recordValue[key] } : {}; } diff --git a/scripts/ios-ax-bridge-spike/limits.test.ts b/scripts/ios-ax-bridge-spike/limits.test.ts index ffd2bf316f..85b1dc5b50 100644 --- a/scripts/ios-ax-bridge-spike/limits.test.ts +++ b/scripts/ios-ax-bridge-spike/limits.test.ts @@ -6,7 +6,7 @@ const acquisition = { targetId: 'simulator:test', targetGeneration: 'generation-1', nodes: [ - { id: 'n0', role: 'AXApplication' }, + { id: 'n0', type: 'XCUIElementTypeApplication', role: 'AXApplication' }, { id: 'n1', parentId: 'n0', role: 'AXWindow', frame: { x: 0, y: 0, width: 100, height: 200 } }, ], viewport: { kind: 'reported', rect: { x: 0, y: 0, width: 100, height: 200 } }, @@ -17,7 +17,10 @@ const acquisition = { test('accepts a raw tree and reports structural depth without publishing it on nodes', () => { const result = validateRawAcquisition(acquisition, DEFAULT_SPIKE_LIMITS); assert.equal(result.ok, true); - if (result.ok) assert.equal(result.maxTraversalDepth, 1); + if (result.ok) { + assert.equal(result.maxTraversalDepth, 1); + assert.equal(result.acquisition.nodes[0]?.type, 'XCUIElementTypeApplication'); + } assert.equal('depth' in acquisition.nodes[0], false); assert.equal('hittable' in acquisition.nodes[0], false); }); diff --git a/scripts/ios-ax-bridge-spike/limits.ts b/scripts/ios-ax-bridge-spike/limits.ts index 54e02bc656..540f1f4dc8 100644 --- a/scripts/ios-ax-bridge-spike/limits.ts +++ b/scripts/ios-ax-bridge-spike/limits.ts @@ -12,6 +12,7 @@ export const DEFAULT_SPIKE_LIMITS: ResourceLimits = Object.freeze({ const NODE_KEYS = new Set([ 'id', + 'type', 'parentId', 'role', 'subrole', @@ -144,7 +145,7 @@ function nodeFactCode(value: Record): string | undefined { } function optionalStringCode(value: Record): string | undefined { - for (const key of ['role', 'subrole', 'label', 'value', 'identifier'] as const) { + for (const key of ['type', 'role', 'subrole', 'label', 'value', 'identifier'] as const) { if (value[key] !== undefined && typeof value[key] !== 'string') return `${key}-invalid`; } return undefined; diff --git a/scripts/ios-ax-bridge-spike/presentation.test.ts b/scripts/ios-ax-bridge-spike/presentation.test.ts index 8e29ae8e21..6abd9a8075 100644 --- a/scripts/ios-ax-bridge-spike/presentation.test.ts +++ b/scripts/ios-ax-bridge-spike/presentation.test.ts @@ -8,7 +8,12 @@ test('prototype presentation creates the #2190 acquired carrier without semantic targetId: 'simulator:test', targetGeneration: 'generation-1', nodes: [ - { id: 'root', role: 'AXApplication', enabled: true }, + { + id: 'root', + type: 'XCUIElementTypeApplication', + role: 'AXApplication', + enabled: true, + }, { id: 'child', parentId: 'root', role: 'AXWindow' }, ], viewport: { kind: 'missing', reason: 'not-provided' }, @@ -18,6 +23,7 @@ test('prototype presentation creates the #2190 acquired carrier without semantic const result = presentAcquisitionForMeasurement(raw); assert.equal(result.acquisition.producer, 'simulator-ax-bridge'); assert.equal(result.acquisition.nodes.length, 2); + assert.equal(result.acquisition.nodes[0]?.type, 'XCUIElementTypeApplication'); assert.equal(result.acquisition.nodes[1]?.parentIndex, 0); assert.equal('hittable' in result.acquisition.nodes[0]!, false); assert.equal(result.measurement.nodeCount, 2); diff --git a/scripts/ios-ax-bridge-spike/presentation.ts b/scripts/ios-ax-bridge-spike/presentation.ts index 8cb1cdd54c..cfd99aeb1e 100644 --- a/scripts/ios-ax-bridge-spike/presentation.ts +++ b/scripts/ios-ax-bridge-spike/presentation.ts @@ -51,6 +51,7 @@ function toRawSnapshotNode( return { index, ...optionalParent(node.parentId, nodeIndexes), + ...optionalString(node, 'type'), ...optionalString(node, 'role'), ...optionalString(node, 'subrole'), ...optionalString(node, 'label'), @@ -78,7 +79,7 @@ function optionalParent( function optionalString( node: RawAcquisition['nodes'][number], - key: 'role' | 'subrole' | 'label' | 'value' | 'identifier', + key: 'type' | 'role' | 'subrole' | 'label' | 'value' | 'identifier', ): Partial { return node[key] === undefined ? {} : { [key]: node[key] }; } diff --git a/scripts/ios-ax-bridge-spike/types.ts b/scripts/ios-ax-bridge-spike/types.ts index ff1ae67eaa..a4f923fc46 100644 --- a/scripts/ios-ax-bridge-spike/types.ts +++ b/scripts/ios-ax-bridge-spike/types.ts @@ -36,6 +36,7 @@ export type SpikeRect = Readonly<{ export type RawAcquiredNode = Readonly<{ id: string; + type?: string; parentId?: string; role?: string; subrole?: string; From 7e3ce62a38dcbdfefe0406f6eac7643493b2ae91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 11:45:36 +0200 Subject: [PATCH 10/29] docs(ios): refresh prerequisite provenance --- docs/evidence/ios-simulator-ax-bridge-2026-09-01.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 2d4f888196..4b34b5cfc6 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -22,7 +22,7 @@ Target: arm64-apple-macosx27.0.0 - #2190 exact live prerequisite head: `bce60b56fb5c5c8d57247e0946fa1fd540e292a1` (`codex/refactor/ios-snapshot-contracts`, PR #2203). - #2189 exact foundation used for this evidence: `e90b7763c8023857a054954ac200a95825ffae12`. -- Current integrated #2189 prerequisite head: `747a939adbdf15332463736241ab140180b41d9f` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. +- Current integrated #2189 prerequisite head: `e9b1fc523278645a0d96e696db02779566bc57f2` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. - The fixture dependency install completed with `pnpm test-app:install`; that command installs the example app dependencies and does not produce an iOS `.app`. - Direct fixture build command: `xcodebuild -workspace examples/test-app/ios/AgentDeviceTester.xcworkspace -scheme AgentDeviceTester -configuration Debug -sdk iphonesimulator -destination id=793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 -derivedDataPath .tmp/ios-ax-app-derived CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build` From 6c8215e06890617e74ddc31587d6fe18e9e8b9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 13:39:15 +0200 Subject: [PATCH 11/29] docs(ios): refresh prerequisite provenance --- docs/evidence/ios-simulator-ax-bridge-2026-09-01.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 4b34b5cfc6..de7ec5d5e4 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -22,7 +22,7 @@ Target: arm64-apple-macosx27.0.0 - #2190 exact live prerequisite head: `bce60b56fb5c5c8d57247e0946fa1fd540e292a1` (`codex/refactor/ios-snapshot-contracts`, PR #2203). - #2189 exact foundation used for this evidence: `e90b7763c8023857a054954ac200a95825ffae12`. -- Current integrated #2189 prerequisite head: `e9b1fc523278645a0d96e696db02779566bc57f2` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. +- Current integrated #2189 prerequisite head: `8820e0ab4e899a2e64da3cce47898c192c99065d` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. - The fixture dependency install completed with `pnpm test-app:install`; that command installs the example app dependencies and does not produce an iOS `.app`. - Direct fixture build command: `xcodebuild -workspace examples/test-app/ios/AgentDeviceTester.xcworkspace -scheme AgentDeviceTester -configuration Debug -sdk iphonesimulator -destination id=793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 -derivedDataPath .tmp/ios-ax-app-derived CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build` From 030ee5dc4ef0f9e86914b71310dbddbaf0e2b2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 13:21:53 +0200 Subject: [PATCH 12/29] fix: make iOS AX spike evidence executable --- scripts/ios-ax-bridge-spike/adapter.test.ts | 9 +- scripts/ios-ax-bridge-spike/adapter.ts | 24 +- scripts/ios-ax-bridge-spike/config.ts | 38 ++- scripts/ios-ax-bridge-spike/decision.ts | 2 +- scripts/ios-ax-bridge-spike/report.ts | 27 ++- scripts/ios-ax-bridge-spike/run.test.ts | 13 ++ scripts/ios-ax-bridge-spike/runner.ts | 216 ++++++++---------- .../ios-snapshot-benchmark/command.test.ts | 25 +- scripts/ios-snapshot-benchmark/command.ts | 9 +- 9 files changed, 197 insertions(+), 166 deletions(-) create mode 100644 scripts/ios-ax-bridge-spike/run.test.ts diff --git a/scripts/ios-ax-bridge-spike/adapter.test.ts b/scripts/ios-ax-bridge-spike/adapter.test.ts index eb7f0f73ef..ebc6fed046 100644 --- a/scripts/ios-ax-bridge-spike/adapter.test.ts +++ b/scripts/ios-ax-bridge-spike/adapter.test.ts @@ -1,6 +1,13 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; -import { readControlSnapshot } from './adapter.ts'; +import { defaultPublicMacOsAxHelperPath, readControlSnapshot } from './adapter.ts'; + +test('public AX adapter resolves the SwiftPM release product', () => { + assert.equal( + defaultPublicMacOsAxHelperPath('/repo'), + '/repo/apple/macos-helper/.build/release/agent-device-ios-ax-bridge-spike', + ); +}); test('control mapping preserves the producer raw node type', () => { const result = readControlSnapshot({ diff --git a/scripts/ios-ax-bridge-spike/adapter.ts b/scripts/ios-ax-bridge-spike/adapter.ts index d82e5185e9..ab4e123d2a 100644 --- a/scripts/ios-ax-bridge-spike/adapter.ts +++ b/scripts/ios-ax-bridge-spike/adapter.ts @@ -40,21 +40,21 @@ export type AdapterOptions = Readonly<{ export function createPublicMacOsAxAdapter(options: AdapterOptions): AcquisitionAdapter { const limits = options.limits ?? DEFAULT_SPIKE_LIMITS; - const helperPath = - options.helperPath ?? - path.join( - options.repoRoot, - 'apple', - 'macos-helper', - '.build', - 'out', - 'Products', - 'Release', - 'agent-device-ios-ax-bridge-spike', - ); + const helperPath = options.helperPath ?? defaultPublicMacOsAxHelperPath(options.repoRoot); return framedAdapter('public-macos-ax', helperPath, limits); } +export function defaultPublicMacOsAxHelperPath(repoRoot: string): string { + return path.join( + repoRoot, + 'apple', + 'macos-helper', + '.build', + 'release', + 'agent-device-ios-ax-bridge-spike', + ); +} + export function createPrivateCoreSimulatorAxAdapter(options: AdapterOptions): AcquisitionAdapter { const limits = options.limits ?? DEFAULT_SPIKE_LIMITS; if (!options.privateTool || !fs.existsSync(options.privateTool)) { diff --git a/scripts/ios-ax-bridge-spike/config.ts b/scripts/ios-ax-bridge-spike/config.ts index 9fbaa441b1..a0b47e44b5 100644 --- a/scripts/ios-ax-bridge-spike/config.ts +++ b/scripts/ios-ax-bridge-spike/config.ts @@ -1,5 +1,3 @@ -import fs from 'node:fs'; -import os from 'node:os'; import path from 'node:path'; import { parseLocalStates, @@ -7,6 +5,11 @@ import { parseScreenIds, } from '../ios-snapshot-benchmark/definitions.ts'; import { resolveRepoRoot } from '../ios-snapshot-benchmark/host.ts'; +import { + assertBenchmarkOwner, + assertOwnedDerivedPath, + createBenchmarkStateRoot, +} from '../ios-snapshot-benchmark/state-ownership.ts'; import type { CandidateId, ResourceLimits } from './types.ts'; import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; @@ -58,11 +61,7 @@ export function parseConfig(argv: readonly string[]): SpikeConfig { const screens = parseScreens(parsed.values.get('--screen')); const candidates = parseCandidates(parsed.values.get('--candidate')); const samples = parseSamples(parsed.values.get('--samples'), states); - const stateDir = resolvePath( - parsed.values.get('--state-dir'), - fs.mkdtempSync(path.join(os.tmpdir(), 'agent-device-ios-ax-spike-')), - ); - fs.mkdirSync(stateDir, { recursive: true }); + const { stateDir, derivedPath } = resolveOwnedStatePaths(parsed.values); return { repoRoot: resolveRepoRoot(), udid: required(parsed.values, '--udid'), @@ -71,10 +70,7 @@ export function parseConfig(argv: readonly string[]): SpikeConfig { ...optionalValue(parsed.values.get('--private-tool'), 'privateTool'), ...optionalValue(parsed.values.get('--helper-path'), 'helperPath'), stateDir, - derivedPath: resolvePath( - parsed.values.get('--derived-path'), - path.join(stateDir, 'derived-data'), - ), + derivedPath, outputPath: resolvePath( parsed.values.get('--out'), path.join(stateDir, 'ios-simulator-ax-bridge-spike.v1.json'), @@ -89,6 +85,26 @@ export function parseConfig(argv: readonly string[]): SpikeConfig { }; } +function resolveOwnedStatePaths(values: ReadonlyMap): { + stateDir: string; + derivedPath: string; +} { + const stateDir = values.has('--state-dir') + ? resolvePath(values.get('--state-dir'), '') + : createBenchmarkStateRoot(); + const derivedPath = resolvePath( + values.get('--derived-path'), + path.join(stateDir, 'derived-data'), + ); + try { + assertBenchmarkOwner(stateDir); + assertOwnedDerivedPath(derivedPath, stateDir); + } catch (error) { + throw new SpikeConfigurationError(error instanceof Error ? error.message : String(error)); + } + return { stateDir, derivedPath }; +} + function parseArguments(argv: readonly string[]): { values: Map; booleans: Set; diff --git a/scripts/ios-ax-bridge-spike/decision.ts b/scripts/ios-ax-bridge-spike/decision.ts index 6f85e9f329..8de567a3c2 100644 --- a/scripts/ios-ax-bridge-spike/decision.ts +++ b/scripts/ios-ax-bridge-spike/decision.ts @@ -173,7 +173,7 @@ function candidateAvailabilityReasons(cells: readonly SpikeCell[]): string[] { } if (cells.some(hasUnsupportedPublicAx)) { reasons.push( - 'The public macOS AX mechanism was unsupported or unreadable on the Xcode 27 host surface.', + 'The public macOS AX mechanism was unsupported or unreadable on the host Simulator surface.', ); } return reasons; diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts index b0a1091006..61b861d13d 100644 --- a/scripts/ios-ax-bridge-spike/report.ts +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -27,9 +27,9 @@ function renderSpikeMarkdown(report: SpikeReport): string { '', '| Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation |', '|---|---|---|---|---|---|', - `| public-macos-ax | public macOS ApplicationServices AX | ${surfaceStatus(report, 'public-macos-ax')} | ${surfaceStatus(report, 'public-macos-ax')} | framed protocol | host Accessibility permission and Xcode 27 DeviceHub surface |`, - `| private-coresimulator-ax | external/private CoreSimulator AX tool | ${surfaceStatus(report, 'private-coresimulator-ax')} | ${surfaceStatus(report, 'private-coresimulator-ax')} | framed protocol contract only | private interface/tool compatibility |`, - `| xctest-control | #2189 XCTest runner control | ${surfaceStatus(report, 'xctest-control')} | ${surfaceStatus(report, 'xctest-control')} | existing runner lifecycle | control, not a host-side AX bridge |`, + `| public-macos-ax | public macOS ApplicationServices AX | ${surfaceStatus(report, 'public-macos-ax', 'app')} | ${surfaceStatus(report, 'public-macos-ax', 'system')} | framed protocol | host Accessibility permission and whole-Simulator process-tree breadth |`, + `| private-coresimulator-ax | external/private CoreSimulator AX tool | ${surfaceStatus(report, 'private-coresimulator-ax', 'app')} | ${surfaceStatus(report, 'private-coresimulator-ax', 'system')} | framed protocol contract only | private interface/tool compatibility |`, + `| xctest-control | #2189 XCTest runner control | ${surfaceStatus(report, 'xctest-control', 'app')} | ${surfaceStatus(report, 'xctest-control', 'system')} | existing runner lifecycle | control, not a host-side AX bridge |`, '', '## Raw acquisition and prototype presentation results', '', @@ -137,11 +137,22 @@ function renderCellRow(cell: SpikeCell): string { return `| ${cell.candidate} | ${cell.state} | ${cell.screen} | ${acquisition.length} | ${summary(acquisition, 'wallClockMs')} | ${summary(acquisition, 'firstLookMs')} | ${summary(presentation, 'wallClockMs')} | ${formatNumber(median(nodeCounts))} | ${failures} |`; } -function surfaceStatus(report: SpikeReport, candidate: SpikeCell['candidate']): string { - if (report.cells.some((cell) => cell.candidate === candidate)) return 'observed in cells'; - if (report.protocolProbes.some((probe) => probe.candidate === candidate)) - return 'protocol probe only'; - return 'not observed (run stopped)'; +function surfaceStatus( + report: SpikeReport, + candidate: SpikeCell['candidate'], + surface: 'app' | 'system', +): string { + const cells = report.cells.filter( + (cell) => + cell.candidate === candidate && + (surface === 'system' ? cell.screen === 'system-surface' : cell.screen !== 'system-surface'), + ); + if (cells.some((cell) => cell.acquisitionSamples.some((sample) => sample.ok))) { + return 'observed in successful cells'; + } + if (cells.length > 0) return 'failed in cells'; + if (report.config.candidates.includes(candidate)) return 'not exercised'; + return 'not selected'; } function preferenceLines(report: SpikeReport): string[] { diff --git a/scripts/ios-ax-bridge-spike/run.test.ts b/scripts/ios-ax-bridge-spike/run.test.ts new file mode 100644 index 0000000000..2874cb9846 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/run.test.ts @@ -0,0 +1,13 @@ +import assert from 'node:assert/strict'; +import { execFileSync } from 'node:child_process'; +import { test } from 'vitest'; + +test('loads the executable spike entrypoint', () => { + const output = execFileSync( + process.execPath, + ['--experimental-strip-types', 'scripts/ios-ax-bridge-spike/run.ts', '--help'], + { encoding: 'utf8' }, + ); + + assert.match(output, /Usage: pnpm bench:ios-ax-bridge/); +}); diff --git a/scripts/ios-ax-bridge-spike/runner.ts b/scripts/ios-ax-bridge-spike/runner.ts index 54d8e200ad..60cb228f81 100644 --- a/scripts/ios-ax-bridge-spike/runner.ts +++ b/scripts/ios-ax-bridge-spike/runner.ts @@ -4,19 +4,17 @@ import { performance } from 'node:perf_hooks'; import { classifyFailure, openFixture, - pressFixtureTarget, - snapshotFixture, type CliContext, } from '../ios-snapshot-benchmark/command.ts'; -import { screenFixture, sampleMinimumForState } from '../ios-snapshot-benchmark/definitions.ts'; import { - BenchmarkInfrastructureError, - bootSimulator, - clearDerivedData, - shutdownSimulator, - stopDaemon, - terminateApp, -} from '../ios-snapshot-benchmark/lifecycle.ts'; + admitReadyCell, + admitSuccessfulSample, + prepareCellState, + prepareSampleState, + type CellAdmissionOptions, +} from '../ios-snapshot-benchmark/cell-admission.ts'; +import { screenFixture, sampleMinimumForState } from '../ios-snapshot-benchmark/definitions.ts'; +import { BenchmarkInfrastructureError, stopDaemon } from '../ios-snapshot-benchmark/lifecycle.ts'; import { appendSamples, makeRequest, type CapturedResponse } from './sample-evidence.ts'; import type { AcquisitionAdapter, AdapterOptions } from './adapter.ts'; import type { SpikeConfig } from './config.ts'; @@ -54,44 +52,37 @@ async function runCell( ): Promise { const fixture = screenFixture(screen); const context = contextFor(config, adapter.candidate, state, screen); + const admission: CellAdmissionOptions = { + repoRoot: config.repoRoot, + stateDir: config.stateDir, + derivedPath: context.derivedPath, + udid: config.udid, + samples: config.samples, + state, + fixture, + }; const acquisitionSamples: SpikeSample[] = []; const presentationSamples: SpikeSample[] = []; try { + prepareCellState(admission); if (state === 'warm') { - const preparationMs = prepareSample(config, context, fixture, state); - const requests = Array.from({ length: config.samples }, (_, index) => - makeRequest(config, adapter.candidate, state, screen, index), - ); - const captured = await captureBatch(adapter, requests); - captured.forEach((item, index) => - appendSamples( - adapter.candidate, - state, - screen, - index, - item, - preparationMs, - acquisitionSamples, - presentationSamples, - ), + await collectWarmSamples( + config, + adapter, + context, + admission, + acquisitionSamples, + presentationSamples, ); } else { - for (let index = 0; index < config.samples; index += 1) { - const preparationMs = prepareSample(config, context, fixture, state); - const request = makeRequest(config, adapter.candidate, state, screen, index); - const captured = await capture(adapter, request); - appendSamples( - adapter.candidate, - state, - screen, - index, - captured, - preparationMs, - acquisitionSamples, - presentationSamples, - ); - closeSession(context); - } + await collectNonWarmSamples( + config, + adapter, + context, + admission, + acquisitionSamples, + presentationSamples, + ); } return { candidate: adapter.candidate, @@ -107,96 +98,87 @@ async function runCell( } } -function prepareSample( +async function collectWarmSamples( config: SpikeConfig, + adapter: AcquisitionAdapter, context: CliContext, - fixture: ReturnType, - state: SpikeConfig['states'][number], -): number { - prepareSimulator(config, context, fixture, state); - const started = performance.now(); - openReadyFixture(context, fixture, state); - return performance.now() - started; + admission: CellAdmissionOptions, + acquisitionSamples: SpikeSample[], + presentationSamples: SpikeSample[], +): Promise { + const preparationStarted = performance.now(); + admitReadyCell(context, admission); + const preparationMs = performance.now() - preparationStarted; + const requests = Array.from({ length: config.samples }, (_, index) => + makeRequest(config, adapter.candidate, admission.state, admission.fixture.id, index), + ); + const captured = await captureBatch(adapter, requests); + captured.forEach((item, index) => + appendSamples( + adapter.candidate, + admission.state, + admission.fixture.id, + index, + item, + preparationMs, + acquisitionSamples, + presentationSamples, + ), + ); } -function prepareSimulator( +async function collectNonWarmSamples( config: SpikeConfig, + adapter: AcquisitionAdapter, context: CliContext, - fixture: ReturnType, - state: SpikeConfig['states'][number], -): void { - if (state === 'cold-cold') return prepareColdCold(config, context); - bootSimulator(config.udid); - if (state === 'cold') prepareCold(config, fixture); -} - -function prepareColdCold(config: SpikeConfig, context: CliContext): void { - shutdownSimulator(config.udid); - stopDaemon(config.repoRoot, config.stateDir); - clearDerivedData(context.derivedPath); - bootSimulator(config.udid); -} - -function prepareCold(config: SpikeConfig, fixture: ReturnType): void { - stopDaemon(config.repoRoot, config.stateDir); - terminateApp(config.udid, fixture.app); -} - -function openReadyFixture( - context: CliContext, - fixture: ReturnType, - state: SpikeConfig['states'][number], -): void { - const opened = openFixture(context, fixture, { relaunch: requiresRelaunch(state) }); - if (!opened.ok) { - throw preparationError(opened, `open ${fixture.id}`, context, openArguments(fixture, state)); + admission: CellAdmissionOptions, + acquisitionSamples: SpikeSample[], + presentationSamples: SpikeSample[], +): Promise { + let appPid: number | undefined; + for (let index = 0; index < config.samples; index += 1) { + if (index > 0) prepareSampleState(admission); + const preparationStarted = performance.now(); + const opened = openFixture(context, admission.fixture, { relaunch: true }); + if (!opened.ok) { + throw preparationError( + opened, + `open ${admission.fixture.id}`, + context, + openArguments(admission.fixture), + ); + } + appPid = admitSuccessfulSample(context, admission, opened, appPid); + const preparationMs = performance.now() - preparationStarted; + const request = makeRequest( + config, + adapter.candidate, + admission.state, + admission.fixture.id, + index, + ); + const captured = await capture(adapter, request); + appendSamples( + adapter.candidate, + admission.state, + admission.fixture.id, + index, + captured, + preparationMs, + acquisitionSamples, + presentationSamples, + ); } - if (fixture.setupAction === 'open-alert') prepareAlert(context, fixture); } -function requiresRelaunch(state: SpikeConfig['states'][number]): boolean { - return state === 'relaunch' || state === 'warm'; -} - -function openArguments( - fixture: ReturnType, - state: SpikeConfig['states'][number], -): string[] { - return [ - 'open', - fixture.app, - ...relaunchArguments(state), - ...launchUrlArguments(fixture), - '--foreground', - ]; -} - -function relaunchArguments(state: SpikeConfig['states'][number]): string[] { - return requiresRelaunch(state) ? ['--relaunch'] : []; +function openArguments(fixture: ReturnType): string[] { + return ['open', fixture.app, '--relaunch', ...launchUrlArguments(fixture), '--foreground']; } function launchUrlArguments(fixture: ReturnType): string[] { return fixture.launchUrl ? ['--launch-url', fixture.launchUrl] : []; } -function prepareAlert(context: CliContext, fixture: ReturnType): void { - const pressed = pressFixtureTarget(context, 'id="automation-open-alert"'); - if (!pressed.ok) { - throw preparationError(pressed, `prepare alert ${fixture.id}`, context, [ - 'click', - 'id="automation-open-alert"', - ]); - } - const observed = snapshotFixture(context); - if (!observed.ok) { - throw preparationError(observed, `observe alert ${fixture.id}`, context, [ - 'batch', - '--steps', - JSON.stringify([{ command: 'snapshot', input: { interactiveOnly: true } }]), - ]); - } -} - async function capture( adapter: AcquisitionAdapter, request: SpikeRequest, diff --git a/scripts/ios-snapshot-benchmark/command.test.ts b/scripts/ios-snapshot-benchmark/command.test.ts index 323d3d50e3..510785c91f 100644 --- a/scripts/ios-snapshot-benchmark/command.test.ts +++ b/scripts/ios-snapshot-benchmark/command.test.ts @@ -65,20 +65,19 @@ test('admits only an exact semantic anchor from snapshot node fields', () => { }); test('recognizes the first-install deep-link confirmation as a setup prompt', () => { + for (const node of [ + { role: 'alert', label: 'Open in “Agent Device Tester”?' }, + { type: 'Alert', label: 'Open in “Agent Device Tester”?' }, + ]) { + assert.equal( + hasDeepLinkConfirmation({ + data: { results: [{ data: { snapshot: { nodes: [node] } } }] }, + }), + true, + ); + } assert.equal( - hasDeepLinkConfirmation({ - data: { - results: [ - { - data: { - snapshot: { - nodes: [{ role: 'alert', label: 'Open in “Agent Device Tester”?' }], - }, - }, - }, - ], - }, - }), + hasDeepLinkConfirmation({ data: { message: 'Open in “Agent Device Tester”?' } }), true, ); assert.equal( diff --git a/scripts/ios-snapshot-benchmark/command.ts b/scripts/ios-snapshot-benchmark/command.ts index ca6696ab87..28cc043d9d 100644 --- a/scripts/ios-snapshot-benchmark/command.ts +++ b/scripts/ios-snapshot-benchmark/command.ts @@ -52,7 +52,7 @@ export function openFixture( '--foreground', ]); if (!fixture.launchUrl || !hasDeepLinkConfirmation(opened.payload)) return opened; - const accepted = pressFixtureTarget(context, 'label="Open"'); + const accepted = runCli(context, ['alert', 'accept']); if (accepted.ok) return opened; return { ...opened, @@ -75,7 +75,7 @@ export async function openFixtureAsync( '--foreground', ]); if (!fixture.launchUrl || !hasDeepLinkConfirmation(opened.payload)) return opened; - const accepted = await pressFixtureTargetAsync(context, 'label="Open"'); + const accepted = await runCliAsync(context, ['alert', 'accept']); if (accepted.ok) return opened; return { ...opened, @@ -123,8 +123,11 @@ export function snapshotHasAnchor(payload: unknown, anchorText: string): boolean } export function hasDeepLinkConfirmation(payload: unknown): boolean { + const root = asRecord(payload); + const data = asRecord(root?.data); + if (readString(data?.message)?.startsWith('Open in ') === true) return true; return snapshotNodes(payload).some((record) => { - const role = readString(record.role); + const role = readString(record.role) ?? readString(record.type)?.toLowerCase(); const label = readString(record.label); return role === 'alert' && label?.startsWith('Open in ') === true; }); From 1eb237760847527f102b7ad82d547b7f9ca5163c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 13:56:33 +0200 Subject: [PATCH 13/29] fix: scope Simulator AX evidence to device content --- .../Protocol.swift | 1 + .../RawAccessibility.swift | 32 +++++++- scripts/ios-ax-bridge-spike/config.ts | 1 + scripts/ios-ax-bridge-spike/decision.test.ts | 59 +++++++++++++- scripts/ios-ax-bridge-spike/decision.ts | 79 ++++++++++++++----- scripts/ios-ax-bridge-spike/report.ts | 2 +- scripts/ios-ax-bridge-spike/run.ts | 6 +- .../ios-ax-bridge-spike/sample-evidence.ts | 1 + scripts/ios-ax-bridge-spike/types.ts | 1 + .../ios-snapshot-benchmark/cell-admission.ts | 17 +++- scripts/ios-snapshot-benchmark/command.ts | 4 + scripts/ios-snapshot-benchmark/definitions.ts | 1 + scripts/ios-snapshot-benchmark/types.ts | 1 + 13 files changed, 175 insertions(+), 30 deletions(-) diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift index ec2ccdf5ad..72bfd97806 100644 --- a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift @@ -8,6 +8,7 @@ struct SpikeRequest: Decodable { let state: String let screen: String let appBundleId: String + let targetWindowName: String? let targetProcessId: Int32? let expectedTargetGeneration: String? let limits: SpikeLimits diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift index 5299b6a333..11f654df8d 100644 --- a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift @@ -43,16 +43,28 @@ func capturePublicAccessibility(request: SpikeRequest) -> SpikeCapture { observedTargetGeneration: generation ) } + guard let window = targetWindow(windows, name: request.targetWindowName) else { + return unsupportedCapture( + code: "target-simulator-window-unavailable", + observedTargetGeneration: generation + ) + } + guard let traversalRoot = firstDescendant(window, subrole: "iOSContentGroup") else { + return unsupportedCapture( + code: "target-simulator-content-unavailable", + observedTargetGeneration: generation + ) + } var state = RawTraversalState() _ = appendRawNode( - applicationElement, + traversalRoot, parentId: nil, depth: 0, limits: request.limits, state: &state ) - let viewport = windows.compactMap { axRect($0) }.first.map { + let viewport = axRect(traversalRoot).map { SpikeViewport( kind: "reported", rect: $0, @@ -121,6 +133,22 @@ func capturePublicAccessibility(request: SpikeRequest) -> SpikeCapture { ) } +private func targetWindow(_ windows: [AXUIElement], name: String?) -> AXUIElement? { + guard let name else { return windows.first } + return windows.first { window in + guard let title = axString(window, kAXTitleAttribute as String) else { return false } + return title == name || title.hasPrefix("\(name) –") + } +} + +private func firstDescendant(_ element: AXUIElement, subrole: String) -> AXUIElement? { + if axString(element, kAXSubroleAttribute as String) == subrole { return element } + for child in axChildren(element) { + if let match = firstDescendant(child, subrole: subrole) { return match } + } + return nil +} + private func targetApplication(request: SpikeRequest) -> NSRunningApplication? { if let processId = request.targetProcessId, let application = NSRunningApplication(processIdentifier: processId), diff --git a/scripts/ios-ax-bridge-spike/config.ts b/scripts/ios-ax-bridge-spike/config.ts index a0b47e44b5..ae23392a3f 100644 --- a/scripts/ios-ax-bridge-spike/config.ts +++ b/scripts/ios-ax-bridge-spike/config.ts @@ -19,6 +19,7 @@ export type SpikeConfig = Readonly<{ repoRoot: string; udid: string; appBundleId: string; + targetWindowName?: string; targetProcessId?: number; privateTool?: string; helperPath?: string; diff --git a/scripts/ios-ax-bridge-spike/decision.test.ts b/scripts/ios-ax-bridge-spike/decision.test.ts index 34d73576fa..7152b0fbea 100644 --- a/scripts/ios-ax-bridge-spike/decision.test.ts +++ b/scripts/ios-ax-bridge-spike/decision.test.ts @@ -2,7 +2,8 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; import { decideSpike } from './decision.ts'; import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; -import type { LifecycleEvidence, PreferenceEvidence } from './types.ts'; +import type { CandidateId, LifecycleEvidence, PreferenceEvidence, SpikeCell } from './types.ts'; +import type { LocalState, ScreenId } from '../ios-snapshot-benchmark/types.ts'; const lifecycle: LifecycleEvidence = { source: 'framed-protocol-fixture', @@ -29,3 +30,59 @@ test('fails closed when a bridge has no readable corpus cells', () => { assert.equal(result.decision, 'NO-GO'); assert.ok(result.reasons.some((reason) => reason.includes('public-macos-ax produced no cells'))); }); + +test('selects one complete viable bridge without requiring every candidate to pass', () => { + const states: LocalState[] = ['cold-cold', 'cold', 'warm', 'relaunch']; + const screens: ScreenId[] = [ + 'quiet', + 'list', + 'nested-scroll', + 'alert', + 'system-surface', + 'xctest-stress', + ]; + const cells = states.flatMap((state) => + screens.map((screen) => readableCell('public-macos-ax', state, screen)), + ); + const result = decideSpike(cells, lifecycle, preferences, DEFAULT_SPIKE_LIMITS, 'completed', [ + { candidate: 'public-macos-ax' }, + { + candidate: 'private-coresimulator-ax', + failure: { kind: 'unsupported-mechanism', code: 'private-tool-unavailable' }, + }, + ]); + assert.deepEqual(result, { decision: 'GO', reasons: [] }); +}); + +function readableCell(candidate: CandidateId, state: LocalState, screen: ScreenId): SpikeCell { + const sampleMinimum = state === 'cold' || state === 'cold-cold' ? 10 : 20; + return { + candidate, + state, + screen, + sampleMinimum, + acquisitionSamples: Array.from({ length: sampleMinimum }, (_, index) => ({ + index: index + 1, + candidate, + state, + screen, + startedAt: '2026-09-01T00:00:00.000Z', + finishedAt: '2026-09-01T00:00:00.010Z', + operation: 'acquisition' as const, + wallClockMs: 10, + firstLookMs: 100, + firstTree: 'readable' as const, + ok: true, + metrics: { + requestBytes: 1, + responseBytes: 1, + nodeCount: 1, + maxTraversalDepth: 0, + cpuMs: 1, + memoryBytes: 1, + durationMs: 10, + }, + })), + presentationSamples: [], + }; +} diff --git a/scripts/ios-ax-bridge-spike/decision.ts b/scripts/ios-ax-bridge-spike/decision.ts index 8de567a3c2..b745283c53 100644 --- a/scripts/ios-ax-bridge-spike/decision.ts +++ b/scripts/ios-ax-bridge-spike/decision.ts @@ -20,8 +20,7 @@ export function decideSpike( const reasons = [ ...statusReasons(status), ...preferenceReasons(preferences), - ...probeReasons(protocolProbes), - ...bridgeCandidateReasons(cells, limits), + ...bridgeRouteReasons(cells, protocolProbes, limits), ...lifecycleReasons(lifecycle), ]; const uniqueReasons = [...new Set(reasons)]; @@ -41,30 +40,68 @@ function preferenceReasons(preferences: PreferenceEvidence): string[] { : []; } +function bridgeRouteReasons( + cells: readonly SpikeCell[], + probes: readonly { candidate: CandidateId; failure?: { kind: string; code?: string } }[], + limits: ResourceLimits, +): string[] { + const evaluated = (['public-macos-ax', 'private-coresimulator-ax'] as const).flatMap( + (candidate) => { + const candidateCells = cells.filter((cell) => cell.candidate === candidate); + const candidateProbes = probes.filter((probe) => probe.candidate === candidate); + if (candidateCells.length === 0 && candidateProbes.length === 0) return []; + return [ + { + candidate, + reasons: [ + ...probeReasons(candidateProbes), + ...candidateCompletenessReasons(candidate, candidateCells), + ...candidateDecisionReasons(candidateCells, limits), + ], + }, + ]; + }, + ); + if (evaluated.some((candidate) => candidate.reasons.length === 0)) return []; + if (evaluated.length === 0) return ['No bridge candidate produced evidence.']; + return evaluated.flatMap((candidate) => candidate.reasons); +} + function probeReasons( probes: readonly { candidate: CandidateId; failure?: { kind: string; code?: string } }[], ): string[] { - const reasons: string[] = []; - for (const probe of probes) { - if (!probe.failure) continue; - reasons.push( - `${probe.candidate} protocol probe returned ${probe.failure.kind}/${probe.failure.code ?? 'no-code'}.`, - ); - } - return reasons; + return probes.flatMap((probe) => + probe.failure + ? [ + `${probe.candidate} protocol probe returned ${probe.failure.kind}/${probe.failure.code ?? 'no-code'}.`, + ] + : [], + ); } -function bridgeCandidateReasons(cells: readonly SpikeCell[], limits: ResourceLimits): string[] { - const reasons: string[] = []; - for (const candidate of ['public-macos-ax', 'private-coresimulator-ax'] as const) { - const candidateCells = cells.filter((cell) => cell.candidate === candidate); - if (candidateCells.length === 0) { - reasons.push(`${candidate} produced no cells.`); - continue; - } - reasons.push(...candidateDecisionReasons(candidateCells, limits)); - } - return reasons; +const REQUIRED_STATES = ['cold-cold', 'cold', 'warm', 'relaunch'] as const; +const REQUIRED_SCREENS = [ + 'quiet', + 'list', + 'nested-scroll', + 'alert', + 'system-surface', + 'xctest-stress', +] as const; + +function candidateCompletenessReasons( + candidate: Exclude, + cells: readonly SpikeCell[], +): string[] { + if (cells.length === 0) return [`${candidate} produced no cells.`]; + const observed = new Set(cells.map((cell) => `${cell.state}/${cell.screen}`)); + const missing = REQUIRED_STATES.flatMap((state) => + REQUIRED_SCREENS.flatMap((screen) => + observed.has(`${state}/${screen}`) ? [] : [`${state}/${screen}`], + ), + ); + if (missing.length === 0) return []; + return [`${candidate} did not complete the required corpus (${missing.length} cells missing).`]; } function lifecycleReasons(lifecycle: LifecycleEvidence): string[] { diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts index 61b861d13d..b5c39498e7 100644 --- a/scripts/ios-ax-bridge-spike/report.ts +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -151,7 +151,7 @@ function surfaceStatus( return 'observed in successful cells'; } if (cells.length > 0) return 'failed in cells'; - if (report.config.candidates.includes(candidate)) return 'not exercised'; + if (report.candidates.includes(candidate)) return 'not exercised'; return 'not selected'; } diff --git a/scripts/ios-ax-bridge-spike/run.ts b/scripts/ios-ax-bridge-spike/run.ts index 2caa57b35b..c141598d40 100644 --- a/scripts/ios-ax-bridge-spike/run.ts +++ b/scripts/ios-ax-bridge-spike/run.ts @@ -44,8 +44,9 @@ function reportFailure(error: unknown): void { async function main(argv: readonly string[]): Promise { const config = parseConfig(argv); const metadata = readMetadata(config); + const runConfig = { ...config, targetWindowName: metadata.target.name }; const lifecycle = await runLifecycleProbes(); - const evidence = await executeSpikeRun(config); + const evidence = await executeSpikeRun(runConfig); const decision = decideSpike( evidence.cells, lifecycle, @@ -54,7 +55,7 @@ async function main(argv: readonly string[]): Promise { evidence.status, evidence.protocolProbes, ); - const report = createReport(config, metadata, lifecycle, evidence, decision); + const report = createReport(runConfig, metadata, lifecycle, evidence, decision); writeSpikeReport(config.outputPath, report); process.stdout.write( `Decision: ${report.decision}\nRaw: ${config.outputPath}\nMarkdown: ${config.outputPath.replace(/\.json$/u, '.md')}\n`, @@ -254,6 +255,7 @@ function protocolProbeRequest( state: 'warm', screen: 'quiet', appBundleId: config.appBundleId, + ...(config.targetWindowName === undefined ? {} : { targetWindowName: config.targetWindowName }), ...(config.targetProcessId === undefined ? {} : { targetProcessId: config.targetProcessId }), limits: config.limits, }; diff --git a/scripts/ios-ax-bridge-spike/sample-evidence.ts b/scripts/ios-ax-bridge-spike/sample-evidence.ts index 7a08aad7af..bfb4a18231 100644 --- a/scripts/ios-ax-bridge-spike/sample-evidence.ts +++ b/scripts/ios-ax-bridge-spike/sample-evidence.ts @@ -58,6 +58,7 @@ export function makeRequest( state, screen, appBundleId: config.appBundleId, + ...(config.targetWindowName === undefined ? {} : { targetWindowName: config.targetWindowName }), ...(config.targetProcessId === undefined ? {} : { targetProcessId: config.targetProcessId }), limits: config.limits, }; diff --git a/scripts/ios-ax-bridge-spike/types.ts b/scripts/ios-ax-bridge-spike/types.ts index a4f923fc46..1efee4206c 100644 --- a/scripts/ios-ax-bridge-spike/types.ts +++ b/scripts/ios-ax-bridge-spike/types.ts @@ -86,6 +86,7 @@ export type SpikeRequest = Readonly<{ state: LocalState; screen: ScreenId; appBundleId: string; + targetWindowName?: string; targetProcessId?: number; expectedTargetGeneration?: string; limits: ResourceLimits; diff --git a/scripts/ios-snapshot-benchmark/cell-admission.ts b/scripts/ios-snapshot-benchmark/cell-admission.ts index 6b822e3d22..596eafbcc9 100644 --- a/scripts/ios-snapshot-benchmark/cell-admission.ts +++ b/scripts/ios-snapshot-benchmark/cell-admission.ts @@ -7,6 +7,7 @@ import { formatCliFailure, openFixture, pressFixtureTarget, + scrollFixtureToBottom, snapshotFixture, snapshotHasAnchor, type CliContext, @@ -146,6 +147,8 @@ function admitOpenedFixture(context: CliContext, options: CellAdmissionOptions): ); requireAnchor(observed, options.fixture); if (options.fixture.setupAction === 'open-alert') { + const scrolled = scrollFixtureToBottom(context); + requireCommandSuccess(scrolled, `${options.fixture.id} setup scroll`, 'cell-state'); const setup = pressFixtureTarget(context, 'id="automation-open-alert"'); requireCommandSuccess(setup, `${options.fixture.id} setup action`, 'cell-state'); const prepared = snapshotFixture(context); @@ -154,7 +157,11 @@ function admitOpenedFixture(context: CliContext, options: CellAdmissionOptions): `${options.fixture.id} post-setup semantic anchor observation`, 'fixture-anchor', ); - requireAnchor(prepared, options.fixture); + requireAnchorText( + prepared, + options.fixture.setupAnchorText ?? options.fixture.anchorText, + options.fixture.id, + ); } const appPid = assertAppRunning(options.udid, options.fixture.app); return appPid; @@ -223,10 +230,14 @@ function assertAppRunning(udid: string, appId: string): number { } function requireAnchor(result: CliResult, fixture: ScreenFixture): void { - if (!snapshotHasAnchor(result.payload, fixture.anchorText)) { + requireAnchorText(result, fixture.anchorText, fixture.id); +} + +function requireAnchorText(result: CliResult, anchorText: string, fixtureId: string): void { + if (!snapshotHasAnchor(result.payload, anchorText)) { throw new BenchmarkCellAdmissionError( 'fixture-anchor', - `Fixture ${fixture.id} did not expose the exact anchor ${JSON.stringify(fixture.anchorText)}.`, + `Fixture ${fixtureId} did not expose the exact anchor ${JSON.stringify(anchorText)}.`, 'agent-device snapshot', ); } diff --git a/scripts/ios-snapshot-benchmark/command.ts b/scripts/ios-snapshot-benchmark/command.ts index 28cc043d9d..a7a11773cd 100644 --- a/scripts/ios-snapshot-benchmark/command.ts +++ b/scripts/ios-snapshot-benchmark/command.ts @@ -105,6 +105,10 @@ export function pressFixtureTarget(context: CliContext, selector: string): CliRe return runCli(context, ['click', selector]); } +export function scrollFixtureToBottom(context: CliContext): CliResult { + return runCli(context, ['scroll', 'bottom', '--settle']); +} + export async function pressFixtureTargetAsync( context: CliContext, selector: string, diff --git a/scripts/ios-snapshot-benchmark/definitions.ts b/scripts/ios-snapshot-benchmark/definitions.ts index 6d86dc42a3..4a9fe3552c 100644 --- a/scripts/ios-snapshot-benchmark/definitions.ts +++ b/scripts/ios-snapshot-benchmark/definitions.ts @@ -44,6 +44,7 @@ const SCREEN_FIXTURES: readonly ScreenFixture[] = [ launchUrl: `${FIXTURE_SCHEME}/automation`, anchorText: 'Automation lab', setupAction: 'open-alert', + setupAnchorText: 'Automation confirmation', }, { id: 'system-surface', diff --git a/scripts/ios-snapshot-benchmark/types.ts b/scripts/ios-snapshot-benchmark/types.ts index 134effa3f2..a9398a18e1 100644 --- a/scripts/ios-snapshot-benchmark/types.ts +++ b/scripts/ios-snapshot-benchmark/types.ts @@ -38,6 +38,7 @@ export type ScreenFixture = { launchUrl?: string; anchorText: string; setupAction?: 'open-alert'; + setupAnchorText?: string; }; export type Failure = { From ac020cbf02b17a46d6443f9b8276f8e743ead5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 14:03:07 +0200 Subject: [PATCH 14/29] perf: compact AX spike evidence payloads --- .../sample-evidence.test.ts | 55 +++++++++++++++++++ .../ios-ax-bridge-spike/sample-evidence.ts | 6 +- 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 scripts/ios-ax-bridge-spike/sample-evidence.test.ts diff --git a/scripts/ios-ax-bridge-spike/sample-evidence.test.ts b/scripts/ios-ax-bridge-spike/sample-evidence.test.ts new file mode 100644 index 0000000000..3bacd83d0d --- /dev/null +++ b/scripts/ios-ax-bridge-spike/sample-evidence.test.ts @@ -0,0 +1,55 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { appendSamples, type CapturedResponse } from './sample-evidence.ts'; +import type { SpikeSample } from './types.ts'; + +test('keeps one raw acquisition exemplar while retaining every sample measurement', () => { + const acquisitionSamples: SpikeSample[] = []; + const presentationSamples: SpikeSample[] = []; + const captured: CapturedResponse = { + startedAt: '2026-09-01T00:00:00.000Z', + wallClockMs: 12, + stderr: '', + response: { + version: 1, + id: 'sample', + candidate: 'public-macos-ax', + ok: true, + acquisition: { + targetId: 'simulator:test', + nodes: [{ id: 'root', role: 'AXGroup' }], + viewport: { kind: 'missing', reason: 'not-provided' }, + truncated: false, + residue: [], + }, + metrics: { + requestBytes: 1, + responseBytes: 2, + nodeCount: 1, + maxTraversalDepth: 0, + cpuMs: 1, + memoryBytes: 1, + durationMs: 12, + }, + }, + }; + + for (const index of [0, 1]) { + appendSamples( + 'public-macos-ax', + 'warm', + 'quiet', + index, + captured, + 3, + acquisitionSamples, + presentationSamples, + ); + } + + assert.equal(acquisitionSamples.length, 2); + assert.ok(acquisitionSamples[0]?.acquisition); + assert.equal(acquisitionSamples[1]?.acquisition, undefined); + assert.equal(presentationSamples.length, 2); + assert.equal(presentationSamples.every((sample) => sample.acquisition === undefined), true); +}); diff --git a/scripts/ios-ax-bridge-spike/sample-evidence.ts b/scripts/ios-ax-bridge-spike/sample-evidence.ts index bfb4a18231..bf1dc7c65a 100644 --- a/scripts/ios-ax-bridge-spike/sample-evidence.ts +++ b/scripts/ios-ax-bridge-spike/sample-evidence.ts @@ -22,6 +22,9 @@ export function appendSamples( ): void { const acquiredAt = new Date().toISOString(); const status = firstTreeStatus(captured.response); + const keepRawExemplar = + captured.response.acquisition !== undefined && + acquisitionSamples.every((sample) => sample.acquisition === undefined); acquisitionSamples.push({ index: index + 1, candidate, @@ -35,7 +38,7 @@ export function appendSamples( firstLookMs: preparationMs + captured.wallClockMs, firstTree: status, ok: captured.response.ok, - ...(captured.response.acquisition ? { acquisition: captured.response.acquisition } : {}), + ...(keepRawExemplar ? { acquisition: captured.response.acquisition } : {}), metrics: captured.response.metrics, ...(captured.stderr ? { stderr: captured.stderr } : {}), ...(captured.response.failure ? { failure: captured.response.failure } : {}), @@ -130,7 +133,6 @@ function successfulPresentationSample( firstTree: status, ok: true, ...(captured.stderr ? { stderr: captured.stderr } : {}), - acquisition: captured.response.acquisition, presentation: presented.measurement, }; } From 6d561b372088b7d13a908565f0255a6d77ff87ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 14:08:22 +0200 Subject: [PATCH 15/29] perf: keep AX spike reports compact --- scripts/ios-ax-bridge-spike/report.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts index b5c39498e7..2056af4ac2 100644 --- a/scripts/ios-ax-bridge-spike/report.ts +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -4,7 +4,7 @@ import type { SpikeCell, SpikeReport, SpikeSample } from './types.ts'; export function writeSpikeReport(outputPath: string, report: SpikeReport): void { fs.mkdirSync(path.dirname(outputPath), { recursive: true }); - fs.writeFileSync(outputPath, `${JSON.stringify(report, null, 2)}\n`); + fs.writeFileSync(outputPath, `${JSON.stringify(report)}\n`); fs.writeFileSync(outputPath.replace(/\.json$/u, '.md'), renderSpikeMarkdown(report)); } @@ -27,7 +27,7 @@ function renderSpikeMarkdown(report: SpikeReport): string { '', '| Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation |', '|---|---|---|---|---|---|', - `| public-macos-ax | public macOS ApplicationServices AX | ${surfaceStatus(report, 'public-macos-ax', 'app')} | ${surfaceStatus(report, 'public-macos-ax', 'system')} | framed protocol | host Accessibility permission and whole-Simulator process-tree breadth |`, + `| public-macos-ax | public macOS ApplicationServices AX | ${surfaceStatus(report, 'public-macos-ax', 'app')} | ${surfaceStatus(report, 'public-macos-ax', 'system')} | framed protocol | exact Simulator content surface, but complex trees exceed the latency budget |`, `| private-coresimulator-ax | external/private CoreSimulator AX tool | ${surfaceStatus(report, 'private-coresimulator-ax', 'app')} | ${surfaceStatus(report, 'private-coresimulator-ax', 'system')} | framed protocol contract only | private interface/tool compatibility |`, `| xctest-control | #2189 XCTest runner control | ${surfaceStatus(report, 'xctest-control', 'app')} | ${surfaceStatus(report, 'xctest-control', 'system')} | existing runner lifecycle | control, not a host-side AX bridge |`, '', From 9938af1d7034c8aaa4f58b619be7bdb170335f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 14:14:57 +0200 Subject: [PATCH 16/29] fix: keep AX evidence claims literal --- scripts/ios-ax-bridge-spike/report.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts index 2056af4ac2..4c00f54323 100644 --- a/scripts/ios-ax-bridge-spike/report.ts +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -37,7 +37,7 @@ function renderSpikeMarkdown(report: SpikeReport): string { '|---|---|---|---:|---:|---:|---:|---:|---:|', ...report.cells.map(renderCellRow), '', - 'Acquisition samples retain the raw node payload, viewport evidence, target generation, truncation, residue, and resource metrics. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction.', + 'Every acquisition sample retains timing, resource, readiness, and failure evidence; the first successful sample in each cell also retains one raw node-tree exemplar with viewport, target generation, truncation, and residue. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction.', '', '## Direct protocol probes', '', @@ -51,9 +51,9 @@ function renderSpikeMarkdown(report: SpikeReport): string { '## Preference experiment', '', `- Applied: **${report.preferenceEvidence.applied}**`, - `- Restored: **${report.preferenceEvidence.restored}**`, + `- Restored: **${report.preferenceEvidence.applied ? report.preferenceEvidence.restored : 'not required'}**`, `- Simulator state before experiment: ${report.preferenceEvidence.simulatorStateBefore}`, - '- Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored.', + preferenceExperimentLine(report), ...preferenceLines(report), '', '## Lifecycle, cancellation, and recovery', @@ -162,6 +162,12 @@ function preferenceLines(report: SpikeReport): string[] { ]); } +function preferenceExperimentLine(report: SpikeReport): string { + return report.preferenceEvidence.applied + ? '- Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored.' + : '- No private/preboot preference keys were applied in this run.'; +} + function summary(samples: readonly SpikeSample[], key: 'wallClockMs' | 'firstLookMs'): string { const values = samples.flatMap((sample) => { const value = sample[key]; From 58042becade3cee82092824c0e9419b9eeb05ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 14:15:17 +0200 Subject: [PATCH 17/29] docs: replace blocked AX spike with live evidence --- .../ios-simulator-ax-bridge-2026-09-01.json | 196 +----------------- .../ios-simulator-ax-bridge-2026-09-01.md | 82 ++++---- 2 files changed, 37 insertions(+), 241 deletions(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json index ac16910c8f..371a2df7b9 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json @@ -1,195 +1 @@ -{ - "schemaVersion": "ios-simulator-ax-bridge-spike.v1", - "issue": "#2192", - "parent": "#2188", - "prerequisites": ["#2189", "#2190"], - "generatedAt": "2026-09-01T07:42:38.929Z", - "revision": { - "commit": "590705e193fb65421b5faffa7573cc1108bbf972", - "branch": "codex/2192-ios-ax-bridge-spike", - "dirty": false - }, - "toolchain": { - "node": "v26.7.0", - "pnpm": "11.19.0", - "xcode": "Xcode 27.0\nBuild version 27A5252f", - "simctl": "@(#)PROGRAM:simctl PROJECT:CoreSimulator-1171.6", - "os": "darwin 27.0.0", - "arch": "arm64", - "swift": "Apple Swift version 6.4 (swiftlang-6.4.0.33.1 clang-2100.3.33.1)\nTarget: arm64-apple-macosx27.0.0" - }, - "target": { - "udid": "793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4", - "name": "AgentDevice-2192-AX-20260901", - "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-27-0" - }, - "limits": { - "maxRequestBytes": 65536, - "maxResponseBytes": 4194304, - "maxNodes": 1500, - "maxTraversalDepth": 12, - "maxCpuMs": 2000, - "maxMemoryBytes": 268435456, - "maxDurationMs": 5000 - }, - "candidates": ["public-macos-ax", "private-coresimulator-ax", "xctest-control"], - "config": { - "states": ["cold-cold", "cold", "warm", "relaunch"], - "screens": ["quiet", "list", "nested-scroll", "alert", "system-surface", "xctest-stress"], - "requestedSamples": 20 - }, - "protocolProbes": [ - { - "version": 1, - "id": "protocol-probe:public-macos-ax", - "candidate": "public-macos-ax", - "ok": false, - "failure": { - "kind": "unsupported-mechanism", - "code": "host-accessibility-permission" - }, - "metrics": { - "requestBytes": 395, - "responseBytes": 332, - "nodeCount": 0, - "maxTraversalDepth": 0, - "cpuMs": 2.9109999999999996, - "memoryBytes": 9076736, - "durationMs": 27.875416 - } - }, - { - "version": 1, - "id": "protocol-probe:private-coresimulator-ax", - "candidate": "private-coresimulator-ax", - "ok": false, - "failure": { - "kind": "unsupported-mechanism", - "code": "private-tool-unavailable" - }, - "metrics": { - "requestBytes": 413, - "responseBytes": 0, - "nodeCount": 0, - "maxTraversalDepth": 0, - "cpuMs": null, - "memoryBytes": null, - "durationMs": 0 - } - } - ], - "protocolProbeLogs": [ - { - "candidate": "public-macos-ax", - "id": "protocol-probe:public-macos-ax", - "stderr": "[ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=quiet\n" - }, - { - "candidate": "private-coresimulator-ax", - "id": "protocol-probe:private-coresimulator-ax", - "stderr": "" - } - ], - "preferenceEvidence": { - "applied": true, - "restored": true, - "simulatorStateBefore": "Shutdown", - "diffs": [ - { - "path": "/Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.Accessibility.plist", - "existedBefore": true, - "beforeSha256": "fbc67ebbd3aa0079a4b4afff4181280731fbb8faaca2ffc623393a8d9c26a436", - "afterSha256": "1b0bc929597307d4b0acd5b7ccf86d93dae01b36c3930ccc2ef69eba12b09610", - "changes": [ - { - "key": "AccessibilityEnabled", - "after": true - }, - { - "key": "ApplicationAccessibilityEnabled", - "after": true - }, - { - "key": "AutomationEnabled", - "after": true - }, - { - "key": "IgnoreAXServerEntitlements", - "after": true - } - ] - }, - { - "path": "/Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.UIAutomation.plist", - "existedBefore": true, - "beforeSha256": "db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c", - "afterSha256": "db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c", - "changes": [] - } - ] - }, - "lifecycle": { - "source": "framed-protocol-fixture", - "crash": { - "failure": "process-crash", - "recovered": true - }, - "timeout": { - "failure": "timeout", - "recovered": true - }, - "cancellation": { - "failure": "cancelled", - "recovered": true - }, - "staleGeneration": { - "failure": "stale-generation", - "recovered": true - } - }, - "positiveControl": { - "issue": "#1626", - "fixture": "deep-button-v1", - "changedDescendant": "deep-button-state", - "invalidShallowRule": { - "command": "pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow", - "exitCode": 1, - "assertion": "AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid." - }, - "safeFullRule": { - "command": "pnpm bench:ios-snapshot:deep-button -- --rule safe-full", - "exitCode": 0, - "assertion": "full observation changed and includes the changed descendant." - }, - "before": { - "surfaceDigest": "cce3230d667fd7292340daaf491fac48b45ba80fba846038bee2f82bf2489a85", - "fullDigest": "993a4f50b3bdac7821f0964dcb589f31deb9a6f1c1ca72c5c0d718088fbdf89b", - "state": "off", - "surfaceNodeIds": ["deep-button-root", "deep-button-container"], - "fullNodeIds": ["deep-button-root", "deep-button-container", "deep-button-state"] - }, - "after": { - "surfaceDigest": "cce3230d667fd7292340daaf491fac48b45ba80fba846038bee2f82bf2489a85", - "fullDigest": "4be81b73f2318615532a2b86dbba8a555f7c84995809d469a1c249d09cb7f55e", - "state": "on", - "surfaceNodeIds": ["deep-button-root", "deep-button-container"], - "fullNodeIds": ["deep-button-root", "deep-button-container", "deep-button-state"] - } - }, - "status": "stopped", - "cells": [], - "decision": "NO-GO", - "decisionReasons": [ - "The live run stopped before the full corpus completed.", - "public-macos-ax protocol probe returned unsupported-mechanism/host-accessibility-permission.", - "private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable.", - "public-macos-ax produced no cells.", - "private-coresimulator-ax produced no cells." - ], - "nextInterface": "Keep any future bridge behind the #2190 acquisition adapter and preserve raw facts until a separate GO evidence run proves fidelity, lifecycle, and latency.", - "stop": { - "category": "infrastructure", - "message": "open quiet failed during fixture preparation (exit 1; code=COMMAND_FAILED; reason=none; diagnostic=Simulator device failed to open agent-device-test-app:///inert.)", - "command": "/opt/homebrew/Cellar/node/26.7.0/bin/node bin/agent-device.mjs open com.callstack.agentdevicelab --launch-url agent-device-test-app:///inert --foreground --state-dir /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-YnARfy --session ax-spike-public-macos-ax-cold-cold-quiet --platform ios --udid 793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 --ios-xctest-derived-data-path /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-YnARfy/derived-data/public-macos-ax/cold-cold/quiet --json" - } -} +{"schemaVersion":"ios-simulator-ax-bridge-spike.v1","issue":"#2192","parent":"#2188","prerequisites":["#2189","#2190"],"generatedAt":"2026-09-01T12:14:03.698Z","revision":{"commit":"6d561b372088b7d13a908565f0255a6d77ff87ce","branch":"takeover/2209-valid-evidence","dirty":false},"toolchain":{"node":"v26.1.0","pnpm":"11.21.0","xcode":"Xcode 26.2\nBuild version 17C52","simctl":"@(#)PROGRAM:simctl PROJECT:CoreSimulator-1155.4","os":"darwin 25.5.0","arch":"arm64","swift":"Apple Swift version 6.2.3 (swiftlang-6.2.3.3.21 clang-1700.6.3.2)\nTarget: arm64-apple-macosx26.0"},"target":{"udid":"F578F08D-BEA1-4A56-8A4B-C92B040FBA94","name":"AgentDevice-2209-Takeover","runtime":"com.apple.CoreSimulator.SimRuntime.iOS-26-2"},"limits":{"maxRequestBytes":65536,"maxResponseBytes":4194304,"maxNodes":1500,"maxTraversalDepth":12,"maxCpuMs":2000,"maxMemoryBytes":268435456,"maxDurationMs":5000},"candidates":["public-macos-ax","private-coresimulator-ax","xctest-control"],"config":{"states":["warm"],"screens":["quiet","list"],"requestedSamples":20},"protocolProbes":[{"version":1,"id":"protocol-probe:public-macos-ax","candidate":"public-macos-ax","ok":true,"acquisition":{"nodes":[{"enabled":true,"focused":false,"frame":{"height":832.5,"width":383,"x":925,"y":126},"id":"n0","role":"AXGroup","subrole":"iOSContentGroup"},{"enabled":true,"focused":false,"frame":{"height":34.290617848970214,"width":262.95522388059703,"x":942.1492537313433,"y":185.0560640732266},"id":"n1","label":"Catalog","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652741150670522,"width":54.623529538586354,"x":1226.3822550868513,"y":191.0886729202773},"id":"n2","label":"12 results","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":43.81578947368416,"width":262.95522388059703,"x":942.1492537313433,"y":225.06178489702518},"id":"n3","label":"Search, filter, scroll, favorite, and drill into detail without extra dependencies.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":16.192791762013712,"width":348.7014925373134,"x":942.1492537313433,"y":311.1058303955218},"id":"n4","label":"Catalog scroll: top","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":342.8564030834957},"id":"n5","label":"Search","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.050343249427897,"width":317.5787534191834,"x":957.7106142044067,"y":372.38443512010906},"id":"n6","label":"Search updates after a short debounce.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":16.192791762013712,"width":317.5787534191834,"x":957.7106142044067,"y":404.7700204609189},"id":"n7","label":"Find a product","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":48.89588098794019,"width":316.9435958546489,"x":958.028192986674,"y":428.9004552529898},"id":"n8","identifier":"catalog-search","label":"Search products","parentId":"n0","role":"AXTextField","selected":false,"value":"Try: tart, kit, loaf"},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":43.82587428116679,"x":957.7106142044067,"y":491.44907497868667},"id":"n9","identifier":"category-all","label":"All","parentId":"n0","role":"AXButton","selected":true},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":100.67246855550738,"x":1009.1583753984366,"y":491.44907497868667},"id":"n10","identifier":"category-starter-kits","label":"Starter Kits","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":80.98258706467658,"x":1117.452741770009,"y":491.44907497868667},"id":"n11","identifier":"category-produce","label":"Produce","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.8781367635836,"width":71.77279780753219,"x":957.7106142044067,"y":534.9473599427351},"id":"n12","identifier":"category-bakery","label":"Bakery","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.8781367635836,"width":69.54975851258234,"x":1037.1053098280038,"y":534.9473599427351},"id":"n13","identifier":"category-pantry","label":"Pantry","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81295813030181,"width":317.5787534191834,"x":957.7106142044067,"y":613.3712917596306},"id":"n14","label":"Citrus Starter Kit","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885585,"width":317.5787534191834,"x":957.7106142044067,"y":642.8993237962438},"id":"n15","label":"A bright bundle for quick search, detail, and quantity flows.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652726616412053,"width":43.19071188969397,"x":967.5555558584223,"y":700.3678612335323},"id":"n16","label":"Popular","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637891232558218,"width":30.169973724517092,"x":1245.119393899073,"y":696.8752982287713},"id":"n17","label":"$12","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79803554089719,"width":53.03565626951,"x":957.7106142044067,"y":733.3884487806796},"id":"n18","identifier":"favorite-citrus-kit","label":"Save Citrus Starter Kit","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92278825772982,"width":53.9883816847161,"x":1221.300985938874,"y":741.3260914984776},"id":"n19","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.5457859694003,"width":317.5787534191834,"x":957.7106142044067,"y":777.5217536646933},"id":"n20","identifier":"details-citrus-kit","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236645,"width":317.5787534191834,"x":957.7106142044067,"y":829.5926930909844},"id":"n21","identifier":"add-citrus-kit","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.8129290617849,"width":317.5787534191834,"x":957.7106142044067,"y":914.6842305109211},"id":"n22","label":"Morning Prep Box","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855836,"width":317.5787534191834,"x":957.7106142044067,"y":944.2122625475345},"id":"n23","label":"Tests multi-step navigation with badges and action buttons.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445907,"width":24.771140644206326,"x":967.5555558584223,"y":1001.6807999848228},"id":"n24","label":"New","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63783309552435,"width":31.122710042925007,"x":1244.166657580665,"y":998.1882369800618},"id":"n25","label":"$18","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79803554089719,"width":53.03565626951,"x":957.7106142044067,"y":1034.70138753197},"id":"n26","identifier":"favorite-morning-box","label":"Save Morning Prep Box","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92278825772982,"width":53.9883816847161,"x":1221.300985938874,"y":1042.639030249768},"id":"n27","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.5457859694003,"width":317.5787534191834,"x":957.7106142044067,"y":1078.8346924159837},"id":"n28","identifier":"details-morning-box","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236648,"width":317.5787534191834,"x":957.7106142044067,"y":1130.905631842275},"id":"n29","identifier":"add-morning-box","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.812929061784928,"width":317.5787534191834,"x":957.7106142044067,"y":1215.9971401936946},"id":"n30","label":"Avocado Stack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885585,"width":317.5787534191834,"x":957.7106142044067,"y":1245.525172230308},"id":"n31","label":"Short card copy with favorite and add-to-cart actions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445872,"width":31.440294873062058,"x":967.5555558584223,"y":1302.9937096675965},"id":"n32","label":"Fresh","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637833095524343,"width":21.27775839430774,"x":1254.0116092292824,"y":1299.5011466628355},"id":"n33","label":"$7","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863342,"width":53.03565626951,"x":957.7106142044067,"y":1336.014297214744},"id":"n34","identifier":"favorite-avocado-stack","label":"Save Avocado Stack","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922846394763667,"width":53.9883816847161,"x":1221.300985938874,"y":1343.9519399325418},"id":"n35","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545844106434174,"width":317.5787534191834,"x":957.7106142044067,"y":1380.1476020987575},"id":"n36","identifier":"details-avocado-stack","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545727832366424,"width":317.5787534191834,"x":957.7106142044067,"y":1432.2185415250487},"id":"n37","identifier":"add-avocado-stack","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":1517.310108013502},"id":"n38","label":"Pepper Mix","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":1546.8381400501155},"id":"n39","label":"Useful for filters, scroll, and selector durability checks.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445872,"width":29.852403431982538,"x":967.5555558584223,"y":1604.306677487404},"id":"n40","label":"Crisp","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637833095524343,"width":22.548083177253375,"x":1252.7412844463367,"y":1600.814114482643},"id":"n41","label":"$9","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798093677931092,"width":53.03565626951,"x":957.7106142044067,"y":1637.3272650345511},"id":"n42","identifier":"favorite-pepper-mix","label":"Save Pepper Mix","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922730120695974,"width":53.9883816847161,"x":1221.300985938874,"y":1645.2649077523492},"id":"n43","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545727832366424,"width":317.5787534191834,"x":957.7106142044067,"y":1681.460569918565},"id":"n44","identifier":"details-pepper-mix","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545844106434174,"width":317.5787534191834,"x":957.7106142044067,"y":1733.5315093448562},"id":"n45","identifier":"add-pepper-mix","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":1818.6229595592422},"id":"n46","label":"Herb Bundle","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885591,"width":317.5787534191834,"x":957.7106142044067,"y":1848.1509915958552},"id":"n47","label":"A compact row for visible-text and existence assertions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":51.13018363269407,"x":967.5555558584223,"y":1905.6195290331439},"id":"n48","label":"Seasonal","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637949369592093,"width":22.548083177253375,"x":1252.7412844463367,"y":1902.1269660283824},"id":"n49","label":"$6","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79809367793098,"width":53.03565626951,"x":957.7106142044067,"y":1938.6401165802913},"id":"n50","identifier":"favorite-herb-bundle","label":"Save Herb Bundle","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92273012069586,"width":53.9883816847161,"x":1221.300985938874,"y":1946.577759298089},"id":"n51","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236654,"width":317.5787534191834,"x":957.7106142044067,"y":1982.7734214643046},"id":"n52","identifier":"details-herb-bundle","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2034.8443608905957},"id":"n53","identifier":"add-herb-bundle","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2119.9359273790496},"id":"n54","label":"Pretzel Bites","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2149.463959415663},"id":"n55","label":"Helps exercise off-screen discovery and scoped snapshots.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":34.61608502402234,"x":967.5555558584223,"y":2206.932496852951},"id":"n56","label":"Snack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959198,"width":22.548083177253375,"x":1252.7412844463367,"y":2203.43993384819},"id":"n57","label":"$8","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798209951998615,"width":53.03565626951,"x":957.7106142044067,"y":2239.9530844000983},"id":"n58","identifier":"favorite-pretzel-bites","label":"Save Pretzel Bites","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":2247.8907271178964},"id":"n59","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":2284.0863892841126},"id":"n60","identifier":"details-pretzel-bites","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2336.1573287104034},"id":"n61","identifier":"add-pretzel-bites","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2421.2487789247893},"id":"n62","label":"Sourdough Loaf","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2450.7768109614026},"id":"n63","label":"Works well for favorite toggles and detail page assertions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":32.710612387206425,"x":967.5555558584223,"y":2508.245348398691},"id":"n64","label":"Warm","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959198,"width":27.946912623163485,"x":1247.3424550004265,"y":2504.75278539393},"id":"n65","label":"$11","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863342,"width":53.03565626951,"x":957.7106142044067,"y":2541.2659359458385},"id":"n66","identifier":"favorite-sourdough-loaf","label":"Save Sourdough Loaf","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92284639476361,"width":53.9883816847161,"x":1221.300985938874,"y":2549.203578663636},"id":"n67","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2585.3992408298523},"id":"n68","identifier":"details-sourdough-loaf","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":2637.470180256143},"id":"n69","identifier":"add-sourdough-loaf","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2722.5618630186646},"id":"n70","label":"Berry Tart","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2752.0898950552773},"id":"n71","label":"A longer list item to force scrolling on smaller devices.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652901027513508,"width":34.93366621975875,"x":967.5555558584223,"y":2809.5584324925658},"id":"n72","label":"Sweet","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637716821456706,"width":30.805121578387343,"x":1244.4842460452028,"y":2806.065869487805},"id":"n73","label":"$14","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":2842.579020039713},"id":"n74","identifier":"favorite-berry-tart","label":"Save Berry Tart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92284639476361,"width":53.9883816847161,"x":1221.300985938874,"y":2850.5166627575113},"id":"n75","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":2886.7123249237275},"id":"n76","identifier":"details-berry-tart","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":2938.7832643500183},"id":"n77","identifier":"add-berry-tart","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3023.8747145644043},"id":"n78","label":"Tea Tins","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3053.4027466010175},"id":"n79","label":"Good target for search debounce and cart state updates.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":28.58208591783817,"x":967.5555558584223,"y":3110.871284038306},"id":"n80","label":"Calm","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.805121578387343,"x":1244.4842460452028,"y":3107.378721033545},"id":"n81","label":"$10","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798209951998615,"width":53.03565626951,"x":957.7106142044067,"y":3143.891871585453},"id":"n82","identifier":"favorite-tea-tins","label":"Save Tea Tins","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":3151.829514303251},"id":"n83","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":3188.0251764694667},"id":"n84","identifier":"details-tea-tins","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3240.096115895758},"id":"n85","identifier":"add-tea-tins","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3325.187566110144},"id":"n86","label":"Olive Jar","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3354.715598146757},"id":"n87","label":"A stable card for replay maintenance and selector exercises.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":40.65008413020651,"x":967.5555558584223,"y":3412.1841355840456},"id":"n88","label":"Classic","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.4875621890547,"x":1244.8018345097405,"y":3408.6915725792846},"id":"n89","label":"$13","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":3445.2047231311926},"id":"n90","identifier":"favorite-olive-jar","label":"Save Olive Jar","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":3453.1423658489907},"id":"n91","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3489.3380280152064},"id":"n92","identifier":"details-olive-jar","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":3541.408967441498},"id":"n93","identifier":"add-olive-jar","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3626.500650204019},"id":"n94","label":"Noodle Pack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.050343249427897,"width":317.5787534191834,"x":957.7106142044067,"y":3656.028682240633},"id":"n95","label":"Works well for detail notes and quantity edits.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":23.81840432579837,"x":967.5555558584223,"y":3694.4468764284925},"id":"n96","label":"Fast","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.4875621890547,"x":1244.8018345097405,"y":3690.9543134237315},"id":"n97","label":"$15","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":3727.4674712427695},"id":"n98","identifier":"favorite-noodle-pack","label":"Save Noodle Pack","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922846394763837,"width":53.9883816847161,"x":1221.300985938874,"y":3735.405113960567},"id":"n99","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3771.6007688596537},"id":"n100","identifier":"details-noodle-pack","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3823.671708285945},"id":"n101","identifier":"add-noodle-pack","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3908.7631585003314},"id":"n102","label":"Seasonal Footer Pick","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3938.2911905369438},"id":"n103","label":"Placed last on purpose so scroll-into-view flows have a durable target.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652901027513508,"width":71.455223880597,"x":967.5555558584223,"y":3995.7597279742326},"id":"n104","label":"Scroll Target","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637716821456706,"width":30.805121578387343,"x":1244.4842460452028,"y":3992.2671649694717},"id":"n105","label":"$16","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79774485572807,"width":53.03565626951,"x":957.7106142044067,"y":4028.78031552138},"id":"n106","identifier":"favorite-seasonal-footer","label":"Save Seasonal Footer Pick","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":4036.7179582391777},"id":"n107","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54607665456933,"width":317.5787534191834,"x":957.7106142044067,"y":4072.913620405394},"id":"n108","identifier":"details-seasonal-footer","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":4124.984559831684},"id":"n109","identifier":"add-seasonal-footer","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":4210.076242594207},"id":"n110","label":"Seasonal footer target","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":4239.604274630819},"id":"n111","label":"This footer card sits at the end of the list to force scroll-into-view on smaller screens.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":62.86613272311206,"width":317.5787534191834,"x":957.7106142044067,"y":4291.040203221057},"id":"n112","label":"If your run reaches this card, you already exercised long-list navigation. The durable text here is \"Seasonal footer target\".","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":79.05892448512586,"width":383,"x":925,"y":879.4410755148742},"id":"n113","label":"Tab Bar","parentId":"n0","role":"AXGroup","selected":false}],"residue":[],"targetGeneration":"pid:813:launch:1786981653.462395","targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","truncated":false,"viewport":{"coordinateSpace":"host-screen","kind":"reported","rect":{"height":832.5,"width":383,"x":925,"y":126},"source":"AXPosition+AXSize"}},"metrics":{"requestBytes":440,"responseBytes":28586,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":33.359,"memoryBytes":11632640,"durationMs":2907.038375}},{"version":1,"id":"protocol-probe:private-coresimulator-ax","candidate":"private-coresimulator-ax","ok":false,"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"},"metrics":{"requestBytes":458,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0}}],"protocolProbeLogs":[{"candidate":"public-macos-ax","id":"protocol-probe:public-macos-ax","stderr":"[ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=quiet\n"},{"candidate":"private-coresimulator-ax","id":"protocol-probe:private-coresimulator-ax","stderr":""}],"preferenceEvidence":{"applied":false,"restored":true,"simulatorStateBefore":"Booted","diffs":[]},"lifecycle":{"source":"framed-protocol-fixture","crash":{"failure":"process-crash","recovered":true},"timeout":{"failure":"timeout","recovered":true},"cancellation":{"failure":"cancelled","recovered":true},"staleGeneration":{"failure":"stale-generation","recovered":true}},"positiveControl":{"issue":"#1626","fixture":"deep-button-v1","artifact":"deep-button-fixture.v1.json","depth":72,"changedDescendant":"deep-button-state","invalidShallowRule":{"command":"pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow","exitCode":1,"assertion":"AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid."},"safeFullRule":{"command":"pnpm bench:ios-snapshot:deep-button -- --rule safe-full","exitCode":0,"assertion":"full observation changed and includes the changed descendant."},"before":{"depth":72,"surfaceDigest":"bd7118623fd764b18b99394d25021372840cea98e8b3b0c0196d3e791b199062","fullDigest":"275f9d14720d5a02ed77b54a03a8f51830afcdc2b12577bd8014631bfbf2c81a","state":"off","surfaceNodeIds":["deep-button-root","deep-button-level-01"],"fullNodeIds":["deep-button-root","deep-button-level-01","deep-button-level-02","deep-button-level-03","deep-button-level-04","deep-button-level-05","deep-button-level-06","deep-button-level-07","deep-button-level-08","deep-button-level-09","deep-button-level-10","deep-button-level-11","deep-button-level-12","deep-button-level-13","deep-button-level-14","deep-button-level-15","deep-button-level-16","deep-button-level-17","deep-button-level-18","deep-button-level-19","deep-button-level-20","deep-button-level-21","deep-button-level-22","deep-button-level-23","deep-button-level-24","deep-button-level-25","deep-button-level-26","deep-button-level-27","deep-button-level-28","deep-button-level-29","deep-button-level-30","deep-button-level-31","deep-button-level-32","deep-button-level-33","deep-button-level-34","deep-button-level-35","deep-button-level-36","deep-button-level-37","deep-button-level-38","deep-button-level-39","deep-button-level-40","deep-button-level-41","deep-button-level-42","deep-button-level-43","deep-button-level-44","deep-button-level-45","deep-button-level-46","deep-button-level-47","deep-button-level-48","deep-button-level-49","deep-button-level-50","deep-button-level-51","deep-button-level-52","deep-button-level-53","deep-button-level-54","deep-button-level-55","deep-button-level-56","deep-button-level-57","deep-button-level-58","deep-button-level-59","deep-button-level-60","deep-button-level-61","deep-button-level-62","deep-button-level-63","deep-button-level-64","deep-button-level-65","deep-button-level-66","deep-button-level-67","deep-button-level-68","deep-button-level-69","deep-button-level-70","deep-button-level-71","deep-button-state"]},"after":{"depth":72,"surfaceDigest":"bd7118623fd764b18b99394d25021372840cea98e8b3b0c0196d3e791b199062","fullDigest":"8542024b5b9719f6b2ba9692915bda9011e0e5d10c4e21463257763ee765719d","state":"on","surfaceNodeIds":["deep-button-root","deep-button-level-01"],"fullNodeIds":["deep-button-root","deep-button-level-01","deep-button-level-02","deep-button-level-03","deep-button-level-04","deep-button-level-05","deep-button-level-06","deep-button-level-07","deep-button-level-08","deep-button-level-09","deep-button-level-10","deep-button-level-11","deep-button-level-12","deep-button-level-13","deep-button-level-14","deep-button-level-15","deep-button-level-16","deep-button-level-17","deep-button-level-18","deep-button-level-19","deep-button-level-20","deep-button-level-21","deep-button-level-22","deep-button-level-23","deep-button-level-24","deep-button-level-25","deep-button-level-26","deep-button-level-27","deep-button-level-28","deep-button-level-29","deep-button-level-30","deep-button-level-31","deep-button-level-32","deep-button-level-33","deep-button-level-34","deep-button-level-35","deep-button-level-36","deep-button-level-37","deep-button-level-38","deep-button-level-39","deep-button-level-40","deep-button-level-41","deep-button-level-42","deep-button-level-43","deep-button-level-44","deep-button-level-45","deep-button-level-46","deep-button-level-47","deep-button-level-48","deep-button-level-49","deep-button-level-50","deep-button-level-51","deep-button-level-52","deep-button-level-53","deep-button-level-54","deep-button-level-55","deep-button-level-56","deep-button-level-57","deep-button-level-58","deep-button-level-59","deep-button-level-60","deep-button-level-61","deep-button-level-62","deep-button-level-63","deep-button-level-64","deep-button-level-65","deep-button-level-66","deep-button-level-67","deep-button-level-68","deep-button-level-69","deep-button-level-70","deep-button-level-71","deep-button-state"]}},"status":"completed","cells":[{"candidate":"public-macos-ax","state":"warm","screen":"quiet","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.012Z","operation":"acquisition","wallClockMs":129.557708,"preparationMs":34387.72875,"firstLookMs":34517.286458,"firstTree":"readable","ok":true,"acquisition":{"nodes":[{"enabled":true,"focused":false,"frame":{"height":832.5,"width":383,"x":925,"y":126},"id":"n0","role":"AXGroup","subrole":"iOSContentGroup"},{"enabled":true,"focused":false,"frame":{"height":27.305489568470307,"width":348.7014925373134,"x":942.1492537313433,"y":185.05606407322648},"id":"n1","label":"Inert surface","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.36785139262804,"width":348.7014925373134,"x":942.1492537313433,"y":227.6018318748038},"id":"n2","label":"Tapping this text changes nothing on screen.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":60.00858123569799,"width":348.7014925373134,"x":942.1492537313433,"y":262.2099542334096},"id":"n3","label":"Nothing here reacts to touch, loads, or animates, so a tap leaves the hierarchy byte-identical and retryTapIfNoChange must re-tap.","parentId":"n0","role":"AXStaticText","selected":false}],"residue":[],"targetGeneration":"pid:813:launch:1786981653.462395","targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","truncated":false,"viewport":{"coordinateSpace":"host-screen","kind":"reported","rect":{"height":832.5,"width":383,"x":925,"y":126},"source":"AXPosition+AXSize"}},"metrics":{"requestBytes":438,"responseBytes":1529,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":5.657,"memoryBytes":11567104,"durationMs":129.557708},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":2,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"acquisition","wallClockMs":47.671459,"preparationMs":34387.72875,"firstLookMs":34435.400209,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1540,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.570999999999998,"memoryBytes":11714560,"durationMs":47.671459},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":3,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"acquisition","wallClockMs":39.633834,"preparationMs":34387.72875,"firstLookMs":34427.362584,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.1109999999999989,"memoryBytes":11780096,"durationMs":39.633834},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":4,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"acquisition","wallClockMs":39.680292,"preparationMs":34387.72875,"firstLookMs":34427.409042,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.1109999999999989,"memoryBytes":11796480,"durationMs":39.680292},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":5,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"acquisition","wallClockMs":40.945417,"preparationMs":34387.72875,"firstLookMs":34428.674167000005,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1540,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.338000000000001,"memoryBytes":11845632,"durationMs":40.945417},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":6,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":38.430958,"preparationMs":34387.72875,"firstLookMs":34426.159708,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.1630000000000038,"memoryBytes":11862016,"durationMs":38.430958},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":7,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":55.293459,"preparationMs":34387.72875,"firstLookMs":34443.022209,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.1099999999999994,"memoryBytes":11894784,"durationMs":55.293459},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":8,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":51.895167,"preparationMs":34387.72875,"firstLookMs":34439.623917000004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.3539999999999992,"memoryBytes":11894784,"durationMs":51.895167},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":9,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":50.8305,"preparationMs":34387.72875,"firstLookMs":34438.55925,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1539,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2439999999999998,"memoryBytes":11927552,"durationMs":50.8305},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":10,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":46.040417,"preparationMs":34387.72875,"firstLookMs":34433.769167,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.3079999999999998,"memoryBytes":11976704,"durationMs":46.040417},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":11,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":54.6205,"preparationMs":34387.72875,"firstLookMs":34442.34925,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1539,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.184000000000001,"memoryBytes":11993088,"durationMs":54.6205},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":12,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":123.059209,"preparationMs":34387.72875,"firstLookMs":34510.787959,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.206000000000003,"memoryBytes":12009472,"durationMs":123.059209},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":13,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":39.091042,"preparationMs":34387.72875,"firstLookMs":34426.819792,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.3369999999999962,"memoryBytes":12025856,"durationMs":39.091042},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":14,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":42.79875,"preparationMs":34387.72875,"firstLookMs":34430.527500000004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1540,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.365000000000002,"memoryBytes":12042240,"durationMs":42.79875},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":15,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":40.239292,"preparationMs":34387.72875,"firstLookMs":34427.968042,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2860000000000014,"memoryBytes":12042240,"durationMs":40.239292},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":16,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":40.598417,"preparationMs":34387.72875,"firstLookMs":34428.327167,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2219999999999978,"memoryBytes":12058624,"durationMs":40.598417},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":17,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":43.436916,"preparationMs":34387.72875,"firstLookMs":34431.165666,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2799999999999976,"memoryBytes":12091392,"durationMs":43.436916},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":18,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":42.913041,"preparationMs":34387.72875,"firstLookMs":34430.641791,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2880000000000038,"memoryBytes":12091392,"durationMs":42.913041},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":19,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":42.739958,"preparationMs":34387.72875,"firstLookMs":34430.468708,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.3950000000000031,"memoryBytes":12091392,"durationMs":42.739958},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":20,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":44.086625,"preparationMs":34387.72875,"firstLookMs":34431.815375000006,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2680000000000007,"memoryBytes":12091392,"durationMs":44.086625},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"}],"presentationSamples":[{"index":1,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"presentation","wallClockMs":0.7285829999964335,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.7285829999964335,"cpuMs":0.3739999999999668,"memoryBytes":73318400}},{"index":2,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"presentation","wallClockMs":0.09587499999906868,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.09587499999906868,"cpuMs":0.06200000000001182,"memoryBytes":73318400}},{"index":3,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"presentation","wallClockMs":0.15975000000617,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.15975000000617,"cpuMs":0.07900000000000773,"memoryBytes":73334784}},{"index":4,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"presentation","wallClockMs":0.04012499999953434,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.04012499999953434,"cpuMs":0.049000000000035016,"memoryBytes":73351168}},{"index":5,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.02466699999786215,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.02466699999786215,"cpuMs":0.038000000000010914,"memoryBytes":73367552}},{"index":6,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.018292000000656117,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.018292000000656117,"cpuMs":0.04699999999996862,"memoryBytes":73367552}},{"index":7,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.02908299999398878,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.02908299999398878,"cpuMs":0.019000000000005457,"memoryBytes":73367552}},{"index":8,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.01258399999642279,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.01258399999642279,"cpuMs":0.010999999999967258,"memoryBytes":73367552}},{"index":9,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.012374999998428393,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.012374999998428393,"cpuMs":0.011000000000024102,"memoryBytes":73367552}},{"index":10,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.019625000000814907,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.019625000000814907,"cpuMs":0.01599999999996271,"memoryBytes":73367552}},{"index":11,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.011041999998269603,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.011041999998269603,"cpuMs":0.009000000000014552,"memoryBytes":73367552}},{"index":12,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.02754099999583559,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.02754099999583559,"cpuMs":0.03300000000001546,"memoryBytes":73367552}},{"index":13,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.008999999998195563,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.008999999998195563,"cpuMs":0.007000000000005002,"memoryBytes":73367552}},{"index":14,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.006916999998793472,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.006916999998793472,"cpuMs":0.007000000000005002,"memoryBytes":73367552}},{"index":15,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.006667000001471024,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.006667000001471024,"cpuMs":0.007000000000005002,"memoryBytes":73367552}},{"index":16,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.028209000003698748,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.028209000003698748,"cpuMs":0.020000000000038654,"memoryBytes":73367552}},{"index":17,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.011375000001862645,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.011375000001862645,"cpuMs":0.009999999999990905,"memoryBytes":73367552}},{"index":18,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.04362500000570435,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.04362500000570435,"cpuMs":0.040000000000020464,"memoryBytes":73367552}},{"index":19,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.019291999997221865,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.019291999997221865,"cpuMs":0.016999999999995907,"memoryBytes":73367552}},{"index":20,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.011375000001862645,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.011375000001862645,"cpuMs":0.009999999999990905,"memoryBytes":73367552}}]},{"candidate":"public-macos-ax","state":"warm","screen":"list","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.050Z","operation":"acquisition","wallClockMs":1166.959125,"preparationMs":26032.607416999992,"firstLookMs":27199.566541999993,"firstTree":"readable","ok":true,"acquisition":{"nodes":[{"enabled":true,"focused":false,"frame":{"height":832.5,"width":383,"x":925,"y":126},"id":"n0","role":"AXGroup","subrole":"iOSContentGroup"},{"enabled":true,"focused":false,"frame":{"height":34.290617848970214,"width":262.95522388059703,"x":942.1492537313433,"y":185.0560640732266},"id":"n1","label":"Catalog","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652741150670522,"width":54.623529538586354,"x":1226.3822550868513,"y":191.0886729202773},"id":"n2","label":"12 results","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":43.81578947368416,"width":262.95522388059703,"x":942.1492537313433,"y":225.06178489702518},"id":"n3","label":"Search, filter, scroll, favorite, and drill into detail without extra dependencies.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":16.192791762013712,"width":348.7014925373134,"x":942.1492537313433,"y":311.1058303955218},"id":"n4","label":"Catalog scroll: top","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":342.8564030834957},"id":"n5","label":"Search","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.050343249427897,"width":317.5787534191834,"x":957.7106142044067,"y":372.38443512010906},"id":"n6","label":"Search updates after a short debounce.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":16.192791762013712,"width":317.5787534191834,"x":957.7106142044067,"y":404.7700204609189},"id":"n7","label":"Find a product","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":48.89588098794019,"width":316.9435958546489,"x":958.028192986674,"y":428.9004552529898},"id":"n8","identifier":"catalog-search","label":"Search products","parentId":"n0","role":"AXTextField","selected":false,"value":"Try: tart, kit, loaf"},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":43.82587428116679,"x":957.7106142044067,"y":491.44907497868667},"id":"n9","identifier":"category-all","label":"All","parentId":"n0","role":"AXButton","selected":true},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":100.67246855550738,"x":1009.1583753984366,"y":491.44907497868667},"id":"n10","identifier":"category-starter-kits","label":"Starter Kits","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":80.98258706467658,"x":1117.452741770009,"y":491.44907497868667},"id":"n11","identifier":"category-produce","label":"Produce","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.8781367635836,"width":71.77279780753219,"x":957.7106142044067,"y":534.9473599427351},"id":"n12","identifier":"category-bakery","label":"Bakery","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.8781367635836,"width":69.54975851258234,"x":1037.1053098280038,"y":534.9473599427351},"id":"n13","identifier":"category-pantry","label":"Pantry","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81295813030181,"width":317.5787534191834,"x":957.7106142044067,"y":613.3712917596306},"id":"n14","label":"Citrus Starter Kit","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885585,"width":317.5787534191834,"x":957.7106142044067,"y":642.8993237962438},"id":"n15","label":"A bright bundle for quick search, detail, and quantity flows.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652726616412053,"width":43.19071188969397,"x":967.5555558584223,"y":700.3678612335323},"id":"n16","label":"Popular","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637891232558218,"width":30.169973724517092,"x":1245.119393899073,"y":696.8752982287713},"id":"n17","label":"$12","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79803554089719,"width":53.03565626951,"x":957.7106142044067,"y":733.3884487806796},"id":"n18","identifier":"favorite-citrus-kit","label":"Save Citrus Starter Kit","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92278825772982,"width":53.9883816847161,"x":1221.300985938874,"y":741.3260914984776},"id":"n19","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.5457859694003,"width":317.5787534191834,"x":957.7106142044067,"y":777.5217536646933},"id":"n20","identifier":"details-citrus-kit","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236645,"width":317.5787534191834,"x":957.7106142044067,"y":829.5926930909844},"id":"n21","identifier":"add-citrus-kit","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.8129290617849,"width":317.5787534191834,"x":957.7106142044067,"y":914.6842305109211},"id":"n22","label":"Morning Prep Box","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855836,"width":317.5787534191834,"x":957.7106142044067,"y":944.2122625475345},"id":"n23","label":"Tests multi-step navigation with badges and action buttons.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445907,"width":24.771140644206326,"x":967.5555558584223,"y":1001.6807999848228},"id":"n24","label":"New","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63783309552435,"width":31.122710042925007,"x":1244.166657580665,"y":998.1882369800618},"id":"n25","label":"$18","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79803554089719,"width":53.03565626951,"x":957.7106142044067,"y":1034.70138753197},"id":"n26","identifier":"favorite-morning-box","label":"Save Morning Prep Box","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92278825772982,"width":53.9883816847161,"x":1221.300985938874,"y":1042.639030249768},"id":"n27","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.5457859694003,"width":317.5787534191834,"x":957.7106142044067,"y":1078.8346924159837},"id":"n28","identifier":"details-morning-box","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236648,"width":317.5787534191834,"x":957.7106142044067,"y":1130.905631842275},"id":"n29","identifier":"add-morning-box","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.812929061784928,"width":317.5787534191834,"x":957.7106142044067,"y":1215.9971401936946},"id":"n30","label":"Avocado Stack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885585,"width":317.5787534191834,"x":957.7106142044067,"y":1245.525172230308},"id":"n31","label":"Short card copy with favorite and add-to-cart actions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445872,"width":31.440294873062058,"x":967.5555558584223,"y":1302.9937096675965},"id":"n32","label":"Fresh","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637833095524343,"width":21.27775839430774,"x":1254.0116092292824,"y":1299.5011466628355},"id":"n33","label":"$7","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863342,"width":53.03565626951,"x":957.7106142044067,"y":1336.014297214744},"id":"n34","identifier":"favorite-avocado-stack","label":"Save Avocado Stack","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922846394763667,"width":53.9883816847161,"x":1221.300985938874,"y":1343.9519399325418},"id":"n35","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545844106434174,"width":317.5787534191834,"x":957.7106142044067,"y":1380.1476020987575},"id":"n36","identifier":"details-avocado-stack","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545727832366424,"width":317.5787534191834,"x":957.7106142044067,"y":1432.2185415250487},"id":"n37","identifier":"add-avocado-stack","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":1517.310108013502},"id":"n38","label":"Pepper Mix","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":1546.8381400501155},"id":"n39","label":"Useful for filters, scroll, and selector durability checks.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445872,"width":29.852403431982538,"x":967.5555558584223,"y":1604.306677487404},"id":"n40","label":"Crisp","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637833095524343,"width":22.548083177253375,"x":1252.7412844463367,"y":1600.814114482643},"id":"n41","label":"$9","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798093677931092,"width":53.03565626951,"x":957.7106142044067,"y":1637.3272650345511},"id":"n42","identifier":"favorite-pepper-mix","label":"Save Pepper Mix","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922730120695974,"width":53.9883816847161,"x":1221.300985938874,"y":1645.2649077523492},"id":"n43","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545727832366424,"width":317.5787534191834,"x":957.7106142044067,"y":1681.460569918565},"id":"n44","identifier":"details-pepper-mix","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545844106434174,"width":317.5787534191834,"x":957.7106142044067,"y":1733.5315093448562},"id":"n45","identifier":"add-pepper-mix","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":1818.6229595592422},"id":"n46","label":"Herb Bundle","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885591,"width":317.5787534191834,"x":957.7106142044067,"y":1848.1509915958552},"id":"n47","label":"A compact row for visible-text and existence assertions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":51.13018363269407,"x":967.5555558584223,"y":1905.6195290331439},"id":"n48","label":"Seasonal","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637949369592093,"width":22.548083177253375,"x":1252.7412844463367,"y":1902.1269660283824},"id":"n49","label":"$6","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79809367793098,"width":53.03565626951,"x":957.7106142044067,"y":1938.6401165802913},"id":"n50","identifier":"favorite-herb-bundle","label":"Save Herb Bundle","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92273012069586,"width":53.9883816847161,"x":1221.300985938874,"y":1946.577759298089},"id":"n51","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236654,"width":317.5787534191834,"x":957.7106142044067,"y":1982.7734214643046},"id":"n52","identifier":"details-herb-bundle","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2034.8443608905957},"id":"n53","identifier":"add-herb-bundle","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2119.9359273790496},"id":"n54","label":"Pretzel Bites","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2149.463959415663},"id":"n55","label":"Helps exercise off-screen discovery and scoped snapshots.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":34.61608502402234,"x":967.5555558584223,"y":2206.932496852951},"id":"n56","label":"Snack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959198,"width":22.548083177253375,"x":1252.7412844463367,"y":2203.43993384819},"id":"n57","label":"$8","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798209951998615,"width":53.03565626951,"x":957.7106142044067,"y":2239.9530844000983},"id":"n58","identifier":"favorite-pretzel-bites","label":"Save Pretzel Bites","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":2247.8907271178964},"id":"n59","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":2284.0863892841126},"id":"n60","identifier":"details-pretzel-bites","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2336.1573287104034},"id":"n61","identifier":"add-pretzel-bites","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2421.2487789247893},"id":"n62","label":"Sourdough Loaf","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2450.7768109614026},"id":"n63","label":"Works well for favorite toggles and detail page assertions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":32.710612387206425,"x":967.5555558584223,"y":2508.245348398691},"id":"n64","label":"Warm","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959198,"width":27.946912623163485,"x":1247.3424550004265,"y":2504.75278539393},"id":"n65","label":"$11","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863342,"width":53.03565626951,"x":957.7106142044067,"y":2541.2659359458385},"id":"n66","identifier":"favorite-sourdough-loaf","label":"Save Sourdough Loaf","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92284639476361,"width":53.9883816847161,"x":1221.300985938874,"y":2549.203578663636},"id":"n67","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2585.3992408298523},"id":"n68","identifier":"details-sourdough-loaf","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":2637.470180256143},"id":"n69","identifier":"add-sourdough-loaf","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2722.5618630186646},"id":"n70","label":"Berry Tart","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2752.0898950552773},"id":"n71","label":"A longer list item to force scrolling on smaller devices.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652901027513508,"width":34.93366621975875,"x":967.5555558584223,"y":2809.5584324925658},"id":"n72","label":"Sweet","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637716821456706,"width":30.805121578387343,"x":1244.4842460452028,"y":2806.065869487805},"id":"n73","label":"$14","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":2842.579020039713},"id":"n74","identifier":"favorite-berry-tart","label":"Save Berry Tart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92284639476361,"width":53.9883816847161,"x":1221.300985938874,"y":2850.5166627575113},"id":"n75","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":2886.7123249237275},"id":"n76","identifier":"details-berry-tart","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":2938.7832643500183},"id":"n77","identifier":"add-berry-tart","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3023.8747145644043},"id":"n78","label":"Tea Tins","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3053.4027466010175},"id":"n79","label":"Good target for search debounce and cart state updates.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":28.58208591783817,"x":967.5555558584223,"y":3110.871284038306},"id":"n80","label":"Calm","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.805121578387343,"x":1244.4842460452028,"y":3107.378721033545},"id":"n81","label":"$10","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798209951998615,"width":53.03565626951,"x":957.7106142044067,"y":3143.891871585453},"id":"n82","identifier":"favorite-tea-tins","label":"Save Tea Tins","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":3151.829514303251},"id":"n83","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":3188.0251764694667},"id":"n84","identifier":"details-tea-tins","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3240.096115895758},"id":"n85","identifier":"add-tea-tins","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3325.187566110144},"id":"n86","label":"Olive Jar","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3354.715598146757},"id":"n87","label":"A stable card for replay maintenance and selector exercises.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":40.65008413020651,"x":967.5555558584223,"y":3412.1841355840456},"id":"n88","label":"Classic","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.4875621890547,"x":1244.8018345097405,"y":3408.6915725792846},"id":"n89","label":"$13","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":3445.2047231311926},"id":"n90","identifier":"favorite-olive-jar","label":"Save Olive Jar","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":3453.1423658489907},"id":"n91","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3489.3380280152064},"id":"n92","identifier":"details-olive-jar","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":3541.408967441498},"id":"n93","identifier":"add-olive-jar","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3626.500650204019},"id":"n94","label":"Noodle Pack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.050343249427897,"width":317.5787534191834,"x":957.7106142044067,"y":3656.028682240633},"id":"n95","label":"Works well for detail notes and quantity edits.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":23.81840432579837,"x":967.5555558584223,"y":3694.4468764284925},"id":"n96","label":"Fast","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.4875621890547,"x":1244.8018345097405,"y":3690.9543134237315},"id":"n97","label":"$15","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":3727.4674712427695},"id":"n98","identifier":"favorite-noodle-pack","label":"Save Noodle Pack","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922846394763837,"width":53.9883816847161,"x":1221.300985938874,"y":3735.405113960567},"id":"n99","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3771.6007688596537},"id":"n100","identifier":"details-noodle-pack","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3823.671708285945},"id":"n101","identifier":"add-noodle-pack","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3908.7631585003314},"id":"n102","label":"Seasonal Footer Pick","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3938.2911905369438},"id":"n103","label":"Placed last on purpose so scroll-into-view flows have a durable target.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652901027513508,"width":71.455223880597,"x":967.5555558584223,"y":3995.7597279742326},"id":"n104","label":"Scroll Target","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637716821456706,"width":30.805121578387343,"x":1244.4842460452028,"y":3992.2671649694717},"id":"n105","label":"$16","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79774485572807,"width":53.03565626951,"x":957.7106142044067,"y":4028.78031552138},"id":"n106","identifier":"favorite-seasonal-footer","label":"Save Seasonal Footer Pick","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":4036.7179582391777},"id":"n107","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54607665456933,"width":317.5787534191834,"x":957.7106142044067,"y":4072.913620405394},"id":"n108","identifier":"details-seasonal-footer","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":4124.984559831684},"id":"n109","identifier":"add-seasonal-footer","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":4210.076242594207},"id":"n110","label":"Seasonal footer target","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":4239.604274630819},"id":"n111","label":"This footer card sits at the end of the list to force scroll-into-view on smaller screens.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":62.86613272311206,"width":317.5787534191834,"x":957.7106142044067,"y":4291.040203221057},"id":"n112","label":"If your run reaches this card, you already exercised long-list navigation. The durable text here is \"Seasonal footer target\".","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":79.05892448512586,"width":383,"x":925,"y":879.4410755148742},"id":"n113","label":"Tab Bar","parentId":"n0","role":"AXGroup","selected":false}],"residue":[],"targetGeneration":"pid:813:launch:1786981653.462395","targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","truncated":false,"viewport":{"coordinateSpace":"host-screen","kind":"reported","rect":{"height":832.5,"width":383,"x":925,"y":126},"source":"AXPosition+AXSize"}},"metrics":{"requestBytes":436,"responseBytes":28595,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":30.632999999999996,"memoryBytes":11583488,"durationMs":1166.959125},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n"},{"index":2,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.053Z","operation":"acquisition","wallClockMs":1007.093792,"preparationMs":26032.607416999992,"firstLookMs":27039.70120899999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":436,"responseBytes":28583,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":26.448,"memoryBytes":12107776,"durationMs":1007.093792},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n"},{"index":3,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.054Z","operation":"acquisition","wallClockMs":961.450375,"preparationMs":26032.607416999992,"firstLookMs":26994.057791999992,"firstTree":"readable","ok":true,"metrics":{"requestBytes":436,"responseBytes":28594,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":24.194000000000003,"memoryBytes":12271616,"durationMs":961.450375},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n"},{"index":4,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.056Z","operation":"acquisition","wallClockMs":1064.505833,"preparationMs":26032.607416999992,"firstLookMs":27097.11324999999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":436,"responseBytes":28595,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":27.709999999999994,"memoryBytes":12304384,"durationMs":1064.505833},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n"},{"index":5,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.057Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":6,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":7,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":8,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":9,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":10,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":11,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":12,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":13,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":14,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":15,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":16,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":17,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":18,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":19,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":20,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}}],"presentationSamples":[{"index":1,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.053Z","operation":"presentation","wallClockMs":2.337249999996857,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":true,"payloadBytes":28425,"nodeCount":114,"durationMs":2.337249999996857,"cpuMs":2.7449999999999477,"memoryBytes":74645504}},{"index":2,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.054Z","operation":"presentation","wallClockMs":1.584500000011758,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":true,"payloadBytes":28425,"nodeCount":114,"durationMs":1.584500000011758,"cpuMs":2.1650000000000205,"memoryBytes":75694080}},{"index":3,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.056Z","operation":"presentation","wallClockMs":1.5459169999958249,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":true,"payloadBytes":28425,"nodeCount":114,"durationMs":1.5459169999958249,"cpuMs":1.4989999999999668,"memoryBytes":76644352}},{"index":4,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.057Z","operation":"presentation","wallClockMs":1.5806250000023283,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":true,"payloadBytes":28425,"nodeCount":114,"durationMs":1.5806250000023283,"cpuMs":1.8980000000000246,"memoryBytes":77234176}},{"index":5,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":6,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":7,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":8,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":9,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":10,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":11,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":12,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":13,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":14,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":15,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":16,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":17,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":18,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":19,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":20,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}}]},{"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":2,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":3,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":4,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":5,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":6,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":7,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":8,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":9,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":10,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":11,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":12,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":13,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":14,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":15,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":16,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":17,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":18,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":19,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":20,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}}],"presentationSamples":[{"index":1,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":2,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":3,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":4,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":5,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":6,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":7,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":8,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":9,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":10,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":11,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":12,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":13,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":14,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":15,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":16,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":17,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":18,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":19,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":20,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}}]},{"candidate":"private-coresimulator-ax","state":"warm","screen":"list","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":2,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":3,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":4,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":5,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":6,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":7,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":8,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":9,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":10,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":11,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":12,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":13,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":14,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":15,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":16,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":17,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":18,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":19,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.018Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":20,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.018Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}}],"presentationSamples":[{"index":1,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":2,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":3,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":4,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":5,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":6,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":7,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":8,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":9,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":10,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":11,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":12,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":13,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":14,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":15,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":16,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":17,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":18,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70549504},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":19,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.018Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70549504},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":20,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.018Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70549504},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}}]},{"candidate":"xctest-control","state":"warm","screen":"quiet","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.020Z","operation":"acquisition","wallClockMs":940.5797079999757,"preparationMs":26402.23541699999,"firstLookMs":27342.815124999965,"firstTree":"readable","ok":true,"acquisition":{"targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","targetGeneration":"896978","nodes":[{"id":"0","type":"Application","label":"Agent Device Tester","frame":{"x":0,"y":0,"width":402,"height":874},"enabled":true},{"id":"1","parentId":"0","type":"Other","label":"Inert surface","frame":{"x":0,"y":0,"width":402,"height":874},"enabled":true},{"id":"2","parentId":"1","type":"StaticText","label":"Tapping this text changes nothing on screen.","identifier":"inert-target","frame":{"x":18,"y":106.66666793823242,"width":366,"height":20.333335876464844},"enabled":true},{"id":"3","parentId":"1","type":"StaticText","label":"Nothing here reacts to touch, loads, or animates, so a tap leaves the hierarchy byte-identical and retryTapIfNoChange must re-tap.","frame":{"x":18,"y":143,"width":366,"height":63},"enabled":true}],"viewport":{"kind":"missing","reason":"not-provided"},"truncated":false,"residue":[{"kind":"missing-viewport","reason":"not-provided"}]},"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70828032,"durationMs":940.5797079999757}},{"index":2,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":552.9202079999959,"preparationMs":26402.23541699999,"firstLookMs":26955.155624999985,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3127,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70828032,"durationMs":552.9202079999959}},{"index":3,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":642.013042000006,"preparationMs":26402.23541699999,"firstLookMs":27044.248458999995,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3127,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70582272,"durationMs":642.013042000006}},{"index":4,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":260.03691699999035,"preparationMs":26402.23541699999,"firstLookMs":26662.27233399998,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3125,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70762496,"durationMs":260.03691699999035}},{"index":5,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":305.75333300000057,"preparationMs":26402.23541699999,"firstLookMs":26707.98874999999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3126,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70844416,"durationMs":305.75333300000057}},{"index":6,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":303.1445829999866,"preparationMs":26402.23541699999,"firstLookMs":26705.379999999976,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3125,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70909952,"durationMs":303.1445829999866}},{"index":7,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":298.53429199999664,"preparationMs":26402.23541699999,"firstLookMs":26700.769708999986,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3126,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70909952,"durationMs":298.53429199999664}},{"index":8,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":347.65412500000093,"preparationMs":26402.23541699999,"firstLookMs":26749.88954199999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70909952,"durationMs":347.65412500000093}},{"index":9,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":321.18845899999724,"preparationMs":26402.23541699999,"firstLookMs":26723.423875999986,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3128,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70926336,"durationMs":321.18845899999724}},{"index":10,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":958.9179159999767,"preparationMs":26402.23541699999,"firstLookMs":27361.153332999966,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3130,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70942720,"durationMs":958.9179159999767}},{"index":11,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":517.407583000022,"preparationMs":26402.23541699999,"firstLookMs":26919.64300000001,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70959104,"durationMs":517.407583000022}},{"index":12,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":286.47508400000515,"preparationMs":26402.23541699999,"firstLookMs":26688.710500999994,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3123,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70959104,"durationMs":286.47508400000515}},{"index":13,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":374.069542000012,"preparationMs":26402.23541699999,"firstLookMs":26776.304959,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3128,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70959104,"durationMs":374.069542000012}},{"index":14,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":371.6503340000054,"preparationMs":26402.23541699999,"firstLookMs":26773.885750999994,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3127,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70959104,"durationMs":371.6503340000054}},{"index":15,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":513.5785830000241,"preparationMs":26402.23541699999,"firstLookMs":26915.814000000013,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3131,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70975488,"durationMs":513.5785830000241}},{"index":16,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":450.3380420000176,"preparationMs":26402.23541699999,"firstLookMs":26852.573459000007,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3130,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71024640,"durationMs":450.3380420000176}},{"index":17,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":881.7244999999821,"preparationMs":26402.23541699999,"firstLookMs":27283.95991699997,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71024640,"durationMs":881.7244999999821}},{"index":18,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":1466.0735419999983,"preparationMs":26402.23541699999,"firstLookMs":27868.308958999987,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3128,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71106560,"durationMs":1466.0735419999983}},{"index":19,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":466.965125000017,"preparationMs":26402.23541699999,"firstLookMs":26869.200542000006,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71122944,"durationMs":466.965125000017}},{"index":20,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":689.8686250000028,"preparationMs":26402.23541699999,"firstLookMs":27092.10404199999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71122944,"durationMs":689.8686250000028}}],"presentationSamples":[{"index":1,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.13295800000196323,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.13295800000196323,"cpuMs":0.117999999999995,"memoryBytes":71155712}},{"index":2,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.013624999992316589,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.013624999992316589,"cpuMs":0.012000000000000455,"memoryBytes":71155712}},{"index":3,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.008957999991253018,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.008957999991253018,"cpuMs":0.009000000000014552,"memoryBytes":71155712}},{"index":4,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.007374999986495823,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.007374999986495823,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":5,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006832999992184341,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006832999992184341,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":6,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006625000009080395,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006625000009080395,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":7,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006332999997539446,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006332999997539446,"cpuMs":0.0049999999999954525,"memoryBytes":71155712}},{"index":8,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006332999997539446,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006332999997539446,"cpuMs":0.0049999999999954525,"memoryBytes":71155712}},{"index":9,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.00849999999627471,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.00849999999627471,"cpuMs":0.008000000000038199,"memoryBytes":71155712}},{"index":10,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006458000018028542,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006458000018028542,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":11,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006415999989258125,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006415999989258125,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":12,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006292000005487353,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006292000005487353,"cpuMs":0.006000000000028649,"memoryBytes":71155712}},{"index":13,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006332999997539446,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006332999997539446,"cpuMs":0.007000000000005002,"memoryBytes":71155712}},{"index":14,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006374999997206032,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006374999997206032,"cpuMs":0.007000000000005002,"memoryBytes":71155712}},{"index":15,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.02266700001200661,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.02266700001200661,"cpuMs":0.02199999999999136,"memoryBytes":71155712}},{"index":16,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006750000000465661,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006750000000465661,"cpuMs":0.006000000000028649,"memoryBytes":71155712}},{"index":17,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.0064999999885912985,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.0064999999885912985,"cpuMs":0.006000000000028649,"memoryBytes":71155712}},{"index":18,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.00704199998290278,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.00704199998290278,"cpuMs":0.006000000000028649,"memoryBytes":71155712}},{"index":19,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006666000001132488,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006666000001132488,"cpuMs":0.010000000000047748,"memoryBytes":71155712}},{"index":20,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006458999996539205,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006458999996539205,"cpuMs":0.007000000000005002,"memoryBytes":71155712}}]},{"candidate":"xctest-control","state":"warm","screen":"list","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.084Z","operation":"acquisition","wallClockMs":579.3912919999566,"preparationMs":35852.83254200002,"firstLookMs":36432.223833999975,"firstTree":"readable","ok":true,"acquisition":{"targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","targetGeneration":"933815","nodes":[{"id":"0","type":"Application","label":"Agent Device Tester","frame":{"x":0,"y":0,"width":402,"height":874},"enabled":true},{"id":"1","parentId":"0","type":"ScrollView","frame":{"x":18,"y":62,"width":366,"height":729},"enabled":true},{"id":"2","parentId":"1","type":"StaticText","label":"Catalog","frame":{"x":18,"y":62,"width":276,"height":36},"enabled":true},{"id":"3","parentId":"1","type":"Other","identifier":"catalog-title","frame":{"x":18,"y":62,"width":366,"height":108.33332824707031},"enabled":true},{"id":"4","parentId":"1","type":"StaticText","label":"12 results","frame":{"x":316.3333330154419,"y":68.33333349227905,"width":57.33331298828125,"height":14.333328247070312},"enabled":true},{"id":"5","parentId":"1","type":"StaticText","label":"Search, filter, scroll, favorite, and drill into detail without extra dependencies.","frame":{"x":18,"y":104,"width":276,"height":46},"enabled":true},{"id":"6","parentId":"1","type":"StaticText","label":"Catalog scroll: top","identifier":"catalog-scroll-state","frame":{"x":18,"y":194.3333282470703,"width":366,"height":17},"enabled":true},{"id":"7","parentId":"1","type":"StaticText","label":"Search","frame":{"x":34.33333396911621,"y":227.66666221618652,"width":333.33331298828125,"height":25},"enabled":true},{"id":"8","parentId":"1","type":"StaticText","label":"Search updates after a short debounce.","frame":{"x":34.33333396911621,"y":258.6666622161865,"width":333.33331298828125,"height":20},"enabled":true},{"id":"9","parentId":"1","type":"StaticText","label":"Find a product","frame":{"x":34.33333396911621,"y":292.66666412353516,"width":333.33331298828125,"height":17},"enabled":true},{"id":"10","parentId":"1","type":"TextField","label":"Search products","identifier":"catalog-search","frame":{"x":34.66666731238365,"y":317.9999974668026,"width":332.66664630174637,"height":51.33333331346512},"enabled":true},{"id":"11","parentId":"1","type":"Button","label":"All","identifier":"category-all","frame":{"x":34.33333396911621,"y":383.6666564941406,"width":46.000003814697266,"height":37.66668701171875},"enabled":true,"selected":true},{"id":"12","parentId":"1","type":"Button","label":"Starter Kits","identifier":"category-starter-kits","frame":{"x":88.33333396911621,"y":383.6666564941406,"width":105.66666412353516,"height":37.66668701171875},"enabled":true},{"id":"13","parentId":"1","type":"Button","label":"Produce","identifier":"category-produce","frame":{"x":202.0000057220459,"y":383.6666564941406,"width":85,"height":37.66668701171875},"enabled":true},{"id":"14","parentId":"1","type":"Button","label":"Bakery","identifier":"category-bakery","frame":{"x":34.33333396911621,"y":429.33332443237305,"width":75.33332824707031,"height":37.666656494140625},"enabled":true},{"id":"15","parentId":"1","type":"Button","label":"Pantry","identifier":"category-pantry","frame":{"x":117.66666984558105,"y":429.33332443237305,"width":73.00000762939453,"height":37.666656494140625},"enabled":true},{"id":"16","parentId":"1","type":"Other","identifier":"product-card-citrus-kit","frame":{"x":18,"y":495.3333435058594,"width":366,"height":295.6666564941406},"enabled":true},{"id":"17","parentId":"1","type":"StaticText","label":"Citrus Starter Kit","frame":{"x":34.33333396911621,"y":511.6666774749756,"width":333.33331298828125,"height":25.000030517578125},"enabled":true},{"id":"18","parentId":"1","type":"StaticText","label":"A bright bundle for quick search, detail, and quantity flows.","frame":{"x":34.33333396911621,"y":542.6666774749756,"width":333.33331298828125,"height":40},"enabled":true},{"id":"19","parentId":"1","type":"StaticText","label":"Popular","frame":{"x":44.666666984558105,"y":603.0000128746033,"width":45.33333206176758,"height":14.33331298828125},"enabled":true},{"id":"20","parentId":"1","type":"StaticText","label":"$12","frame":{"x":335.99999046325684,"y":599.3333461284637,"width":31.666656494140625,"height":21.66668701171875},"enabled":true},{"id":"21","parentId":"1","type":"Button","label":"Save Citrus Starter Kit","identifier":"favorite-citrus-kit","frame":{"x":34.33333396911621,"y":637.6666717529297,"width":55.66666793823242,"height":32.33331298828125},"enabled":true},{"id":"22","parentId":"1","type":"StaticText","label":"In cart: 0","frame":{"x":310.99999046325684,"y":646.0000047683716,"width":56.666656494140625,"height":15.66668701171875},"enabled":true},{"id":"23","parentId":"1","type":"Button","label":"View details","identifier":"details-citrus-kit","frame":{"x":34.33333396911621,"y":684.0000152587891,"width":333.33331298828125,"height":44.66668701171875},"enabled":true},{"id":"24","parentId":"1","type":"Button","label":"Add to cart","identifier":"add-citrus-kit","frame":{"x":34.33333396911621,"y":738.6666831970215,"width":333.33331298828125,"height":44.6666259765625},"enabled":true},{"id":"25","parentId":"0","type":"TabBar","label":"Tab Bar","frame":{"x":0,"y":791,"width":402,"height":83},"enabled":true},{"id":"26","parentId":"25","type":"Button","label":"Home","frame":{"x":25,"y":795,"width":74,"height":54},"enabled":true},{"id":"27","parentId":"25","type":"Button","label":"Catalog","frame":{"x":93.41666666666666,"y":795,"width":74.33333333333334,"height":54},"enabled":true,"selected":true},{"id":"28","parentId":"25","type":"Button","label":"Form","frame":{"x":162.16666666666666,"y":795,"width":74,"height":54},"enabled":true},{"id":"29","parentId":"25","type":"Button","label":"Audio","frame":{"x":230.58333333333331,"y":795,"width":74,"height":54},"enabled":true},{"id":"30","parentId":"25","type":"Button","label":"Settings","frame":{"x":299,"y":795,"width":78,"height":54},"enabled":true}],"viewport":{"kind":"missing","reason":"not-provided"},"truncated":true,"residue":[{"kind":"missing-viewport","reason":"not-provided"}]},"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69025792,"durationMs":579.3912919999566}},{"index":2,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.085Z","operation":"acquisition","wallClockMs":566.228375000006,"preparationMs":35852.83254200002,"firstLookMs":36419.060917000024,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16421,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69271552,"durationMs":566.228375000006}},{"index":3,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.085Z","operation":"acquisition","wallClockMs":985.4735000000219,"preparationMs":35852.83254200002,"firstLookMs":36838.30604200004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69369856,"durationMs":985.4735000000219}},{"index":4,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.086Z","operation":"acquisition","wallClockMs":828.7607919999864,"preparationMs":35852.83254200002,"firstLookMs":36681.593334000005,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69419008,"durationMs":828.7607919999864}},{"index":5,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":651.1083750000107,"preparationMs":35852.83254200002,"firstLookMs":36503.94091700003,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69500928,"durationMs":651.1083750000107}},{"index":6,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":569.1852499999804,"preparationMs":35852.83254200002,"firstLookMs":36422.017792,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69632000,"durationMs":569.1852499999804}},{"index":7,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":563.2574579999782,"preparationMs":35852.83254200002,"firstLookMs":36416.09,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69681152,"durationMs":563.2574579999782}},{"index":8,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":775.7467920000199,"preparationMs":35852.83254200002,"firstLookMs":36628.57933400004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16427,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69681152,"durationMs":775.7467920000199}},{"index":9,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":565.0179579999531,"preparationMs":35852.83254200002,"firstLookMs":36417.85049999997,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16423,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69681152,"durationMs":565.0179579999531}},{"index":10,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":566.0364999999874,"preparationMs":35852.83254200002,"firstLookMs":36418.869042000006,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69697536,"durationMs":566.0364999999874}},{"index":11,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":570.7256249999627,"preparationMs":35852.83254200002,"firstLookMs":36423.55816699998,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16427,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69861376,"durationMs":570.7256249999627}},{"index":12,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":640.0835000000079,"preparationMs":35852.83254200002,"firstLookMs":36492.916042000026,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69943296,"durationMs":640.0835000000079}},{"index":13,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":561.719625000027,"preparationMs":35852.83254200002,"firstLookMs":36414.552167000045,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69959680,"durationMs":561.719625000027}},{"index":14,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":563.2965829999885,"preparationMs":35852.83254200002,"firstLookMs":36416.12912500001,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69976064,"durationMs":563.2965829999885}},{"index":15,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":567.6302920000162,"preparationMs":35852.83254200002,"firstLookMs":36420.462834000034,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16427,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69992448,"durationMs":567.6302920000162}},{"index":16,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":673.7819589999854,"preparationMs":35852.83254200002,"firstLookMs":36526.614501000004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70107136,"durationMs":673.7819589999854}},{"index":17,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":638.8914169999771,"preparationMs":35852.83254200002,"firstLookMs":36491.723958999995,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70205440,"durationMs":638.8914169999771}},{"index":18,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":564.9031670000404,"preparationMs":35852.83254200002,"firstLookMs":36417.73570900006,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70402048,"durationMs":564.9031670000404}},{"index":19,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":557.9273750000284,"preparationMs":35852.83254200002,"firstLookMs":36410.75991700005,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70565888,"durationMs":557.9273750000284}},{"index":20,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":704.0210419999785,"preparationMs":35852.83254200002,"firstLookMs":36556.853584,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70762496,"durationMs":704.0210419999785}}],"presentationSamples":[{"index":1,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.085Z","operation":"presentation","wallClockMs":0.44904200005112216,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.44904200005112216,"cpuMs":0.15600000000006276,"memoryBytes":70926336}},{"index":2,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.085Z","operation":"presentation","wallClockMs":0.5059580000233836,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.5059580000233836,"cpuMs":0.27800000000002,"memoryBytes":71155712}},{"index":3,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.086Z","operation":"presentation","wallClockMs":0.07150000002002344,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.07150000002002344,"cpuMs":0.09299999999996089,"memoryBytes":71172096}},{"index":4,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.7780829999828711,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.7780829999828711,"cpuMs":0.07000000000005002,"memoryBytes":71172096}},{"index":5,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.052207999979145825,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.052207999979145825,"cpuMs":0.051000000000044565,"memoryBytes":71172096}},{"index":6,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.04850000003352761,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04850000003352761,"cpuMs":0.04800000000000182,"memoryBytes":71172096}},{"index":7,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.05070800002431497,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.05070800002431497,"cpuMs":0.05000000000006821,"memoryBytes":71172096}},{"index":8,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.13062499999068677,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.13062499999068677,"cpuMs":0.12999999999999545,"memoryBytes":71172096}},{"index":9,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.047583999985363334,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.047583999985363334,"cpuMs":0.04600000000004911,"memoryBytes":71172096}},{"index":10,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04908300004899502,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04908300004899502,"cpuMs":0.04899999999997817,"memoryBytes":71172096}},{"index":11,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04854200000409037,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04854200000409037,"cpuMs":0.04699999999991178,"memoryBytes":71172096}},{"index":12,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04779100004816428,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04779100004816428,"cpuMs":0.047000000000025466,"memoryBytes":71172096}},{"index":13,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.06812499999068677,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.06812499999068677,"cpuMs":0.06700000000000728,"memoryBytes":71303168}},{"index":14,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.09541599999647588,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.09541599999647588,"cpuMs":0.09399999999993724,"memoryBytes":71434240}},{"index":15,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.046999999962281436,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.046999999962281436,"cpuMs":0.04600000000004911,"memoryBytes":71434240}},{"index":16,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04824999999254942,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04824999999254942,"cpuMs":0.04699999999991178,"memoryBytes":71434240}},{"index":17,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04666599998017773,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04666599998017773,"cpuMs":0.04600000000004911,"memoryBytes":71434240}},{"index":18,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04666599998017773,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04666599998017773,"cpuMs":0.045999999999935426,"memoryBytes":71434240}},{"index":19,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04729100002441555,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04729100002441555,"cpuMs":0.04600000000004911,"memoryBytes":71434240}},{"index":20,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.046541000017896295,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.046541000017896295,"cpuMs":0.04499999999995907,"memoryBytes":71434240}}]}],"decision":"NO-GO","decisionReasons":["public-macos-ax did not complete the required corpus (22 cells missing).","public-macos-ax warm/list did not produce 20 readable samples.","public-macos-ax warm acquisition missed the 75/150 ms target.","private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable.","private-coresimulator-ax did not complete the required corpus (22 cells missing).","private-coresimulator-ax warm/quiet did not produce 20 readable samples.","private-coresimulator-ax warm/quiet has unreadable or empty first-tree evidence.","private-coresimulator-ax warm/list did not produce 20 readable samples.","private-coresimulator-ax warm/list has unreadable or empty first-tree evidence.","The private CoreSimulator AX mechanism has no configured tool on this host."],"nextInterface":"Keep any future bridge behind the #2190 acquisition adapter and preserve raw facts until a separate GO evidence run proves fidelity, lifecycle, and latency."} diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index de7ec5d5e4..bad36965c6 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -1,52 +1,47 @@ # iOS Simulator AX bridge spike - Decision: **NO-GO** -- Status: **stopped** -- Revision: 590705e193fb65421b5faffa7573cc1108bbf972 (codex/2192-ios-ax-bridge-spike) -- Target: AgentDevice-2192-AX-20260901 (793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4, com.apple.CoreSimulator.SimRuntime.iOS-27-0) -- Generated: 2026-09-01T07:42:38.929Z -- Corpus: states=cold-cold, cold, warm, relaunch, screens=quiet, list, nested-scroll, alert, system-surface, xctest-stress, samples=20 +- Status: **completed** +- Revision: 6d561b372088b7d13a908565f0255a6d77ff87ce (takeover/2209-valid-evidence) +- Target: AgentDevice-2209-Takeover (F578F08D-BEA1-4A56-8A4B-C92B040FBA94, com.apple.CoreSimulator.SimRuntime.iOS-26-2) +- Generated: 2026-09-01T12:14:03.698Z +- Corpus: states=warm, screens=quiet, list, samples=20 ## Environment and limits -- Node: v26.7.0 -- pnpm: 11.19.0 -- Xcode: Xcode 27.0; Build version 27A5252f -- simctl: @(#)PROGRAM:simctl PROJECT:CoreSimulator-1171.6 -- Swift: Apple Swift version 6.4 (swiftlang-6.4.0.33.1 clang-2100.3.33.1) -Target: arm64-apple-macosx27.0.0 -- OS: darwin 27.0.0; arch=arm64 +- Node: v26.1.0 +- pnpm: 11.21.0 +- Xcode: Xcode 26.2; Build version 17C52 +- simctl: @(#)PROGRAM:simctl PROJECT:CoreSimulator-1155.4 +- Swift: Apple Swift version 6.2.3 (swiftlang-6.2.3.3.21 clang-1700.6.3.2) +Target: arm64-apple-macosx26.0 +- OS: darwin 25.5.0; arch=arm64 - Bounds: request=65536 B, response=4194304 B, nodes=1500, traversal=12, CPU=2000 ms, memory=268435456 B, duration=5000 ms -## Dependency and fixture provenance - -- #2190 exact live prerequisite head: `bce60b56fb5c5c8d57247e0946fa1fd540e292a1` (`codex/refactor/ios-snapshot-contracts`, PR #2203). -- #2189 exact foundation used for this evidence: `e90b7763c8023857a054954ac200a95825ffae12`. -- Current integrated #2189 prerequisite head: `8820e0ab4e899a2e64da3cce47898c192c99065d` (`codex/2189-ios-snapshot-baselines`, PR #2204). This prerequisite-only update followed the evidence revision; the run produced no acquisition cells or latency claims. -- The fixture dependency install completed with `pnpm test-app:install`; that command installs the example app dependencies and does not produce an iOS `.app`. -- Direct fixture build command: - `xcodebuild -workspace examples/test-app/ios/AgentDeviceTester.xcworkspace -scheme AgentDeviceTester -configuration Debug -sdk iphonesimulator -destination id=793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 -derivedDataPath .tmp/ios-ax-app-derived CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build` -- The build stopped at `expo-modules-jsi@56.0.10` `JavaScriptRuntime.swift:219:35` with `a C function pointer can only be formed from a reference to a 'func' or a literal closure`; retrying with `SWIFT_VERSION=5.9` produced the same compiler error. No installable `AgentDeviceTester.app` was produced. -- The fixture run therefore stopped before cell acquisition; no latency result is claimed for the four requested states or six requested screens. - ## Candidate fidelity and limitation matrix | Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation | |---|---|---|---|---|---| -| public-macos-ax | public macOS ApplicationServices AX | protocol probe only | protocol probe only | framed protocol | host Accessibility permission and Xcode 27 DeviceHub surface | -| private-coresimulator-ax | external/private CoreSimulator AX tool | protocol probe only | protocol probe only | framed protocol contract only | private interface/tool compatibility | -| xctest-control | #2189 XCTest runner control | not observed (run stopped) | not observed (run stopped) | existing runner lifecycle | control, not a host-side AX bridge | +| public-macos-ax | public macOS ApplicationServices AX | observed in successful cells | not exercised | framed protocol | exact Simulator content surface, but complex trees exceed the latency budget | +| private-coresimulator-ax | external/private CoreSimulator AX tool | failed in cells | not exercised | framed protocol contract only | private interface/tool compatibility | +| xctest-control | #2189 XCTest runner control | observed in successful cells | not exercised | existing runner lifecycle | control, not a host-side AX bridge | ## Raw acquisition and prototype presentation results | Candidate | State | Screen | N | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures | |---|---|---|---:|---:|---:|---:|---:|---:| +| public-macos-ax | warm | quiet | 20 | 42.9/123.1 | 34430.6/34510.8 | 0.0/0.2 | 4.0 | 0 | +| public-macos-ax | warm | list | 20 | 5002.8/5002.8 | 31035.4/31035.4 | 0.0/1.6 | 114.0 | 16 | +| private-coresimulator-ax | warm | quiet | 20 | 0.1/0.1 | 31115.5/31115.5 | 0.0/0.0 | – | 20 | +| private-coresimulator-ax | warm | list | 20 | 0.0/0.0 | 30479.5/30479.5 | 0.0/0.0 | – | 20 | +| xctest-control | warm | quiet | 20 | 450.3/958.9 | 26852.6/27361.2 | 0.0/0.0 | 4.0 | 0 | +| xctest-control | warm | list | 20 | 569.2/828.8 | 36422.0/36681.6 | 0.0/0.5 | 31.0 | 0 | -Acquisition samples retain the raw node payload, viewport evidence, target generation, truncation, residue, and resource metrics. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction. +Every acquisition sample retains timing, resource, readiness, and failure evidence; the first successful sample in each cell also retains one raw node-tree exemplar with viewport, target generation, truncation, and residue. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction. ## Direct protocol probes -- public-macos-ax/protocol-probe:public-macos-ax: ok=false, failure=unsupported-mechanism, code=host-accessibility-permission, nodes=0, duration=27.9 ms, CPU=2.9 ms, memory=9076736 B, response=332 B +- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=114, duration=2907.0 ms, CPU=33.4 ms, memory=11632640 B, response=28586 B - private-coresimulator-ax/protocol-probe:private-coresimulator-ax: ok=false, failure=unsupported-mechanism, code=private-tool-unavailable, nodes=0, duration=0.0 ms, CPU=– ms, memory=– B, response=0 B - stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=quiet - stderr private-coresimulator-ax/protocol-probe:private-coresimulator-ax: empty @@ -58,15 +53,10 @@ Acquisition samples retain the raw node payload, viewport evidence, target gener ## Preference experiment -- Applied: **true** -- Restored: **true** -- Simulator state before experiment: Shutdown -- Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored. -- Simulator deletion was not observed by this run; only shutdown and plist restoration are claimed. -- /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=fbc67ebbd3aa0079a4b4afff4181280731fbb8faaca2ffc623393a8d9c26a436, afterSha256=1b0bc929597307d4b0acd5b7ccf86d93dae01b36c3930ccc2ef69eba12b09610 - - Changes: AccessibilityEnabled: undefined -> true; ApplicationAccessibilityEnabled: undefined -> true; AutomationEnabled: undefined -> true; IgnoreAXServerEntitlements: undefined -> true -- /Users/michal/Library/Developer/CoreSimulator/Devices/793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4/data/Library/Preferences/com.apple.UIAutomation.plist: existed=true, beforeSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c, afterSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c - - Changes: none +- Applied: **false** +- Restored: **not required** +- Simulator state before experiment: Booted +- No private/preboot preference keys were applied in this run. ## Lifecycle, cancellation, and recovery @@ -78,11 +68,16 @@ Acquisition samples retain the raw node payload, viewport evidence, target gener ## Decision rationale -- The live run stopped before the full corpus completed. -- public-macos-ax protocol probe returned unsupported-mechanism/host-accessibility-permission. +- public-macos-ax did not complete the required corpus (22 cells missing). +- public-macos-ax warm/list did not produce 20 readable samples. +- public-macos-ax warm acquisition missed the 75/150 ms target. - private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable. -- public-macos-ax produced no cells. -- private-coresimulator-ax produced no cells. +- private-coresimulator-ax did not complete the required corpus (22 cells missing). +- private-coresimulator-ax warm/quiet did not produce 20 readable samples. +- private-coresimulator-ax warm/quiet has unreadable or empty first-tree evidence. +- private-coresimulator-ax warm/list did not produce 20 readable samples. +- private-coresimulator-ax warm/list has unreadable or empty first-tree evidence. +- The private CoreSimulator AX mechanism has no configured tool on this host. ## Next interface boundary @@ -92,8 +87,3 @@ Acquisition samples retain the raw node payload, viewport evidence, target gener - No production backend selection, fallback, runner-demand, open/relaunch, proxy, XCTest interaction, or public CLI changes were made. - A production bridge should not start until this report has a GO result; this run is the #2192 boundary. - -## Stop condition - -- infrastructure: open quiet failed during fixture preparation (exit 1; code=COMMAND_FAILED; reason=none; diagnostic=Simulator device failed to open agent-device-test-app:///inert.) -- Command: /opt/homebrew/Cellar/node/26.7.0/bin/node bin/agent-device.mjs open com.callstack.agentdevicelab --launch-url agent-device-test-app:///inert --foreground --state-dir /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-YnARfy --session ax-spike-public-macos-ax-cold-cold-quiet --platform ios --udid 793B72F6-02C9-4BCD-BEC9-1B3EB42A7ED4 --ios-xctest-derived-data-path /var/folders/pn/0s6xww5x5tj2brz0nrvlx96w0000gn/T/agent-device-ios-ax-spike-YnARfy/derived-data/public-macos-ax/cold-cold/quiet --json From 4d87bc9c3e9926afc98b89f3c314dfd9291dcded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 14:16:38 +0200 Subject: [PATCH 18/29] chore: preserve raw AX evidence format --- .oxfmtrc.json | 1 + scripts/ios-ax-bridge-spike/sample-evidence.test.ts | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.oxfmtrc.json b/.oxfmtrc.json index ef771b1b35..fa65824086 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -9,6 +9,7 @@ "dist/**", "node_modules/**", "**/*.md", + "docs/evidence/ios-simulator-ax-bridge-2026-09-01.json", "scripts/maestro-conformance/corpus/**", "fallow-baselines/**" ] diff --git a/scripts/ios-ax-bridge-spike/sample-evidence.test.ts b/scripts/ios-ax-bridge-spike/sample-evidence.test.ts index 3bacd83d0d..a56b5b346d 100644 --- a/scripts/ios-ax-bridge-spike/sample-evidence.test.ts +++ b/scripts/ios-ax-bridge-spike/sample-evidence.test.ts @@ -51,5 +51,8 @@ test('keeps one raw acquisition exemplar while retaining every sample measuremen assert.ok(acquisitionSamples[0]?.acquisition); assert.equal(acquisitionSamples[1]?.acquisition, undefined); assert.equal(presentationSamples.length, 2); - assert.equal(presentationSamples.every((sample) => sample.acquisition === undefined), true); + assert.equal( + presentationSamples.every((sample) => sample.acquisition === undefined), + true, + ); }); From acfa7550af709ac75228968e00946fa0089888fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 15:04:47 +0200 Subject: [PATCH 19/29] fix: make simulator AX spike evidence decisive --- .oxfmtrc.json | 1 - .../RawAccessibility.swift | 27 +++- .../ios-simulator-ax-bridge-2026-09-01.json | 1 - ...ios-simulator-ax-bridge-2026-09-01.json.gz | Bin 0 -> 14403 bytes .../ios-simulator-ax-bridge-2026-09-01.md | 51 +++---- scripts/ios-ax-bridge-spike/README.md | 4 +- scripts/ios-ax-bridge-spike/config.ts | 2 +- scripts/ios-ax-bridge-spike/decision.test.ts | 48 ++++++- scripts/ios-ax-bridge-spike/decision.ts | 54 +++++--- .../framed-process.test.ts | 17 ++- scripts/ios-ax-bridge-spike/framed-process.ts | 4 +- scripts/ios-ax-bridge-spike/report.ts | 94 ++++++++++++- scripts/ios-ax-bridge-spike/run.ts | 129 +++++++++++------- scripts/ios-ax-bridge-spike/runner.ts | 8 +- scripts/ios-ax-bridge-spike/types.ts | 4 +- scripts/ios-snapshot-benchmark/definitions.ts | 6 +- 16 files changed, 329 insertions(+), 121 deletions(-) delete mode 100644 docs/evidence/ios-simulator-ax-bridge-2026-09-01.json create mode 100644 docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz diff --git a/.oxfmtrc.json b/.oxfmtrc.json index fa65824086..ef771b1b35 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -9,7 +9,6 @@ "dist/**", "node_modules/**", "**/*.md", - "docs/evidence/ios-simulator-ax-bridge-2026-09-01.json", "scripts/maestro-conformance/corpus/**", "fallow-baselines/**" ] diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift index 11f654df8d..cfa2b0092f 100644 --- a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift @@ -49,7 +49,11 @@ func capturePublicAccessibility(request: SpikeRequest) -> SpikeCapture { observedTargetGeneration: generation ) } - guard let traversalRoot = firstDescendant(window, subrole: "iOSContentGroup") else { + guard let traversalRoot = firstDescendant( + window, + subrole: "iOSContentGroup", + maxDepth: request.limits.maxTraversalDepth + ) else { return unsupportedCapture( code: "target-simulator-content-unavailable", observedTargetGeneration: generation @@ -137,14 +141,25 @@ private func targetWindow(_ windows: [AXUIElement], name: String?) -> AXUIElemen guard let name else { return windows.first } return windows.first { window in guard let title = axString(window, kAXTitleAttribute as String) else { return false } - return title == name || title.hasPrefix("\(name) –") + return title == name || title.hasPrefix("\(name) ") } } -private func firstDescendant(_ element: AXUIElement, subrole: String) -> AXUIElement? { - if axString(element, kAXSubroleAttribute as String) == subrole { return element } - for child in axChildren(element) { - if let match = firstDescendant(child, subrole: subrole) { return match } +private func firstDescendant( + _ element: AXUIElement, + subrole: String, + maxDepth: Int +) -> AXUIElement? { + var queue: [(AXUIElement, Int)] = [(element, 0)] + var visited: [AXUIElement] = [] + while !queue.isEmpty { + let (candidate, depth) = queue.removeFirst() + if visited.contains(where: { CFEqual($0, candidate) }) { continue } + visited.append(candidate) + if axString(candidate, kAXSubroleAttribute as String) == subrole { return candidate } + if depth < maxDepth { + queue.append(contentsOf: axChildren(candidate).map { ($0, depth + 1) }) + } } return nil } diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json deleted file mode 100644 index 371a2df7b9..0000000000 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion":"ios-simulator-ax-bridge-spike.v1","issue":"#2192","parent":"#2188","prerequisites":["#2189","#2190"],"generatedAt":"2026-09-01T12:14:03.698Z","revision":{"commit":"6d561b372088b7d13a908565f0255a6d77ff87ce","branch":"takeover/2209-valid-evidence","dirty":false},"toolchain":{"node":"v26.1.0","pnpm":"11.21.0","xcode":"Xcode 26.2\nBuild version 17C52","simctl":"@(#)PROGRAM:simctl PROJECT:CoreSimulator-1155.4","os":"darwin 25.5.0","arch":"arm64","swift":"Apple Swift version 6.2.3 (swiftlang-6.2.3.3.21 clang-1700.6.3.2)\nTarget: arm64-apple-macosx26.0"},"target":{"udid":"F578F08D-BEA1-4A56-8A4B-C92B040FBA94","name":"AgentDevice-2209-Takeover","runtime":"com.apple.CoreSimulator.SimRuntime.iOS-26-2"},"limits":{"maxRequestBytes":65536,"maxResponseBytes":4194304,"maxNodes":1500,"maxTraversalDepth":12,"maxCpuMs":2000,"maxMemoryBytes":268435456,"maxDurationMs":5000},"candidates":["public-macos-ax","private-coresimulator-ax","xctest-control"],"config":{"states":["warm"],"screens":["quiet","list"],"requestedSamples":20},"protocolProbes":[{"version":1,"id":"protocol-probe:public-macos-ax","candidate":"public-macos-ax","ok":true,"acquisition":{"nodes":[{"enabled":true,"focused":false,"frame":{"height":832.5,"width":383,"x":925,"y":126},"id":"n0","role":"AXGroup","subrole":"iOSContentGroup"},{"enabled":true,"focused":false,"frame":{"height":34.290617848970214,"width":262.95522388059703,"x":942.1492537313433,"y":185.0560640732266},"id":"n1","label":"Catalog","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652741150670522,"width":54.623529538586354,"x":1226.3822550868513,"y":191.0886729202773},"id":"n2","label":"12 results","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":43.81578947368416,"width":262.95522388059703,"x":942.1492537313433,"y":225.06178489702518},"id":"n3","label":"Search, filter, scroll, favorite, and drill into detail without extra dependencies.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":16.192791762013712,"width":348.7014925373134,"x":942.1492537313433,"y":311.1058303955218},"id":"n4","label":"Catalog scroll: top","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":342.8564030834957},"id":"n5","label":"Search","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.050343249427897,"width":317.5787534191834,"x":957.7106142044067,"y":372.38443512010906},"id":"n6","label":"Search updates after a short debounce.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":16.192791762013712,"width":317.5787534191834,"x":957.7106142044067,"y":404.7700204609189},"id":"n7","label":"Find a product","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":48.89588098794019,"width":316.9435958546489,"x":958.028192986674,"y":428.9004552529898},"id":"n8","identifier":"catalog-search","label":"Search products","parentId":"n0","role":"AXTextField","selected":false,"value":"Try: tart, kit, loaf"},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":43.82587428116679,"x":957.7106142044067,"y":491.44907497868667},"id":"n9","identifier":"category-all","label":"All","parentId":"n0","role":"AXButton","selected":true},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":100.67246855550738,"x":1009.1583753984366,"y":491.44907497868667},"id":"n10","identifier":"category-starter-kits","label":"Starter Kits","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":80.98258706467658,"x":1117.452741770009,"y":491.44907497868667},"id":"n11","identifier":"category-produce","label":"Produce","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.8781367635836,"width":71.77279780753219,"x":957.7106142044067,"y":534.9473599427351},"id":"n12","identifier":"category-bakery","label":"Bakery","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.8781367635836,"width":69.54975851258234,"x":1037.1053098280038,"y":534.9473599427351},"id":"n13","identifier":"category-pantry","label":"Pantry","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81295813030181,"width":317.5787534191834,"x":957.7106142044067,"y":613.3712917596306},"id":"n14","label":"Citrus Starter Kit","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885585,"width":317.5787534191834,"x":957.7106142044067,"y":642.8993237962438},"id":"n15","label":"A bright bundle for quick search, detail, and quantity flows.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652726616412053,"width":43.19071188969397,"x":967.5555558584223,"y":700.3678612335323},"id":"n16","label":"Popular","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637891232558218,"width":30.169973724517092,"x":1245.119393899073,"y":696.8752982287713},"id":"n17","label":"$12","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79803554089719,"width":53.03565626951,"x":957.7106142044067,"y":733.3884487806796},"id":"n18","identifier":"favorite-citrus-kit","label":"Save Citrus Starter Kit","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92278825772982,"width":53.9883816847161,"x":1221.300985938874,"y":741.3260914984776},"id":"n19","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.5457859694003,"width":317.5787534191834,"x":957.7106142044067,"y":777.5217536646933},"id":"n20","identifier":"details-citrus-kit","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236645,"width":317.5787534191834,"x":957.7106142044067,"y":829.5926930909844},"id":"n21","identifier":"add-citrus-kit","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.8129290617849,"width":317.5787534191834,"x":957.7106142044067,"y":914.6842305109211},"id":"n22","label":"Morning Prep Box","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855836,"width":317.5787534191834,"x":957.7106142044067,"y":944.2122625475345},"id":"n23","label":"Tests multi-step navigation with badges and action buttons.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445907,"width":24.771140644206326,"x":967.5555558584223,"y":1001.6807999848228},"id":"n24","label":"New","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63783309552435,"width":31.122710042925007,"x":1244.166657580665,"y":998.1882369800618},"id":"n25","label":"$18","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79803554089719,"width":53.03565626951,"x":957.7106142044067,"y":1034.70138753197},"id":"n26","identifier":"favorite-morning-box","label":"Save Morning Prep Box","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92278825772982,"width":53.9883816847161,"x":1221.300985938874,"y":1042.639030249768},"id":"n27","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.5457859694003,"width":317.5787534191834,"x":957.7106142044067,"y":1078.8346924159837},"id":"n28","identifier":"details-morning-box","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236648,"width":317.5787534191834,"x":957.7106142044067,"y":1130.905631842275},"id":"n29","identifier":"add-morning-box","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.812929061784928,"width":317.5787534191834,"x":957.7106142044067,"y":1215.9971401936946},"id":"n30","label":"Avocado Stack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885585,"width":317.5787534191834,"x":957.7106142044067,"y":1245.525172230308},"id":"n31","label":"Short card copy with favorite and add-to-cart actions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445872,"width":31.440294873062058,"x":967.5555558584223,"y":1302.9937096675965},"id":"n32","label":"Fresh","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637833095524343,"width":21.27775839430774,"x":1254.0116092292824,"y":1299.5011466628355},"id":"n33","label":"$7","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863342,"width":53.03565626951,"x":957.7106142044067,"y":1336.014297214744},"id":"n34","identifier":"favorite-avocado-stack","label":"Save Avocado Stack","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922846394763667,"width":53.9883816847161,"x":1221.300985938874,"y":1343.9519399325418},"id":"n35","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545844106434174,"width":317.5787534191834,"x":957.7106142044067,"y":1380.1476020987575},"id":"n36","identifier":"details-avocado-stack","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545727832366424,"width":317.5787534191834,"x":957.7106142044067,"y":1432.2185415250487},"id":"n37","identifier":"add-avocado-stack","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":1517.310108013502},"id":"n38","label":"Pepper Mix","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":1546.8381400501155},"id":"n39","label":"Useful for filters, scroll, and selector durability checks.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445872,"width":29.852403431982538,"x":967.5555558584223,"y":1604.306677487404},"id":"n40","label":"Crisp","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637833095524343,"width":22.548083177253375,"x":1252.7412844463367,"y":1600.814114482643},"id":"n41","label":"$9","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798093677931092,"width":53.03565626951,"x":957.7106142044067,"y":1637.3272650345511},"id":"n42","identifier":"favorite-pepper-mix","label":"Save Pepper Mix","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922730120695974,"width":53.9883816847161,"x":1221.300985938874,"y":1645.2649077523492},"id":"n43","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545727832366424,"width":317.5787534191834,"x":957.7106142044067,"y":1681.460569918565},"id":"n44","identifier":"details-pepper-mix","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545844106434174,"width":317.5787534191834,"x":957.7106142044067,"y":1733.5315093448562},"id":"n45","identifier":"add-pepper-mix","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":1818.6229595592422},"id":"n46","label":"Herb Bundle","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885591,"width":317.5787534191834,"x":957.7106142044067,"y":1848.1509915958552},"id":"n47","label":"A compact row for visible-text and existence assertions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":51.13018363269407,"x":967.5555558584223,"y":1905.6195290331439},"id":"n48","label":"Seasonal","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637949369592093,"width":22.548083177253375,"x":1252.7412844463367,"y":1902.1269660283824},"id":"n49","label":"$6","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79809367793098,"width":53.03565626951,"x":957.7106142044067,"y":1938.6401165802913},"id":"n50","identifier":"favorite-herb-bundle","label":"Save Herb Bundle","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92273012069586,"width":53.9883816847161,"x":1221.300985938874,"y":1946.577759298089},"id":"n51","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236654,"width":317.5787534191834,"x":957.7106142044067,"y":1982.7734214643046},"id":"n52","identifier":"details-herb-bundle","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2034.8443608905957},"id":"n53","identifier":"add-herb-bundle","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2119.9359273790496},"id":"n54","label":"Pretzel Bites","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2149.463959415663},"id":"n55","label":"Helps exercise off-screen discovery and scoped snapshots.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":34.61608502402234,"x":967.5555558584223,"y":2206.932496852951},"id":"n56","label":"Snack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959198,"width":22.548083177253375,"x":1252.7412844463367,"y":2203.43993384819},"id":"n57","label":"$8","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798209951998615,"width":53.03565626951,"x":957.7106142044067,"y":2239.9530844000983},"id":"n58","identifier":"favorite-pretzel-bites","label":"Save Pretzel Bites","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":2247.8907271178964},"id":"n59","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":2284.0863892841126},"id":"n60","identifier":"details-pretzel-bites","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2336.1573287104034},"id":"n61","identifier":"add-pretzel-bites","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2421.2487789247893},"id":"n62","label":"Sourdough Loaf","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2450.7768109614026},"id":"n63","label":"Works well for favorite toggles and detail page assertions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":32.710612387206425,"x":967.5555558584223,"y":2508.245348398691},"id":"n64","label":"Warm","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959198,"width":27.946912623163485,"x":1247.3424550004265,"y":2504.75278539393},"id":"n65","label":"$11","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863342,"width":53.03565626951,"x":957.7106142044067,"y":2541.2659359458385},"id":"n66","identifier":"favorite-sourdough-loaf","label":"Save Sourdough Loaf","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92284639476361,"width":53.9883816847161,"x":1221.300985938874,"y":2549.203578663636},"id":"n67","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2585.3992408298523},"id":"n68","identifier":"details-sourdough-loaf","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":2637.470180256143},"id":"n69","identifier":"add-sourdough-loaf","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2722.5618630186646},"id":"n70","label":"Berry Tart","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2752.0898950552773},"id":"n71","label":"A longer list item to force scrolling on smaller devices.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652901027513508,"width":34.93366621975875,"x":967.5555558584223,"y":2809.5584324925658},"id":"n72","label":"Sweet","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637716821456706,"width":30.805121578387343,"x":1244.4842460452028,"y":2806.065869487805},"id":"n73","label":"$14","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":2842.579020039713},"id":"n74","identifier":"favorite-berry-tart","label":"Save Berry Tart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92284639476361,"width":53.9883816847161,"x":1221.300985938874,"y":2850.5166627575113},"id":"n75","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":2886.7123249237275},"id":"n76","identifier":"details-berry-tart","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":2938.7832643500183},"id":"n77","identifier":"add-berry-tart","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3023.8747145644043},"id":"n78","label":"Tea Tins","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3053.4027466010175},"id":"n79","label":"Good target for search debounce and cart state updates.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":28.58208591783817,"x":967.5555558584223,"y":3110.871284038306},"id":"n80","label":"Calm","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.805121578387343,"x":1244.4842460452028,"y":3107.378721033545},"id":"n81","label":"$10","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798209951998615,"width":53.03565626951,"x":957.7106142044067,"y":3143.891871585453},"id":"n82","identifier":"favorite-tea-tins","label":"Save Tea Tins","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":3151.829514303251},"id":"n83","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":3188.0251764694667},"id":"n84","identifier":"details-tea-tins","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3240.096115895758},"id":"n85","identifier":"add-tea-tins","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3325.187566110144},"id":"n86","label":"Olive Jar","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3354.715598146757},"id":"n87","label":"A stable card for replay maintenance and selector exercises.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":40.65008413020651,"x":967.5555558584223,"y":3412.1841355840456},"id":"n88","label":"Classic","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.4875621890547,"x":1244.8018345097405,"y":3408.6915725792846},"id":"n89","label":"$13","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":3445.2047231311926},"id":"n90","identifier":"favorite-olive-jar","label":"Save Olive Jar","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":3453.1423658489907},"id":"n91","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3489.3380280152064},"id":"n92","identifier":"details-olive-jar","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":3541.408967441498},"id":"n93","identifier":"add-olive-jar","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3626.500650204019},"id":"n94","label":"Noodle Pack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.050343249427897,"width":317.5787534191834,"x":957.7106142044067,"y":3656.028682240633},"id":"n95","label":"Works well for detail notes and quantity edits.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":23.81840432579837,"x":967.5555558584223,"y":3694.4468764284925},"id":"n96","label":"Fast","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.4875621890547,"x":1244.8018345097405,"y":3690.9543134237315},"id":"n97","label":"$15","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":3727.4674712427695},"id":"n98","identifier":"favorite-noodle-pack","label":"Save Noodle Pack","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922846394763837,"width":53.9883816847161,"x":1221.300985938874,"y":3735.405113960567},"id":"n99","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3771.6007688596537},"id":"n100","identifier":"details-noodle-pack","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3823.671708285945},"id":"n101","identifier":"add-noodle-pack","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3908.7631585003314},"id":"n102","label":"Seasonal Footer Pick","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3938.2911905369438},"id":"n103","label":"Placed last on purpose so scroll-into-view flows have a durable target.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652901027513508,"width":71.455223880597,"x":967.5555558584223,"y":3995.7597279742326},"id":"n104","label":"Scroll Target","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637716821456706,"width":30.805121578387343,"x":1244.4842460452028,"y":3992.2671649694717},"id":"n105","label":"$16","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79774485572807,"width":53.03565626951,"x":957.7106142044067,"y":4028.78031552138},"id":"n106","identifier":"favorite-seasonal-footer","label":"Save Seasonal Footer Pick","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":4036.7179582391777},"id":"n107","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54607665456933,"width":317.5787534191834,"x":957.7106142044067,"y":4072.913620405394},"id":"n108","identifier":"details-seasonal-footer","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":4124.984559831684},"id":"n109","identifier":"add-seasonal-footer","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":4210.076242594207},"id":"n110","label":"Seasonal footer target","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":4239.604274630819},"id":"n111","label":"This footer card sits at the end of the list to force scroll-into-view on smaller screens.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":62.86613272311206,"width":317.5787534191834,"x":957.7106142044067,"y":4291.040203221057},"id":"n112","label":"If your run reaches this card, you already exercised long-list navigation. The durable text here is \"Seasonal footer target\".","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":79.05892448512586,"width":383,"x":925,"y":879.4410755148742},"id":"n113","label":"Tab Bar","parentId":"n0","role":"AXGroup","selected":false}],"residue":[],"targetGeneration":"pid:813:launch:1786981653.462395","targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","truncated":false,"viewport":{"coordinateSpace":"host-screen","kind":"reported","rect":{"height":832.5,"width":383,"x":925,"y":126},"source":"AXPosition+AXSize"}},"metrics":{"requestBytes":440,"responseBytes":28586,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":33.359,"memoryBytes":11632640,"durationMs":2907.038375}},{"version":1,"id":"protocol-probe:private-coresimulator-ax","candidate":"private-coresimulator-ax","ok":false,"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"},"metrics":{"requestBytes":458,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0}}],"protocolProbeLogs":[{"candidate":"public-macos-ax","id":"protocol-probe:public-macos-ax","stderr":"[ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=quiet\n"},{"candidate":"private-coresimulator-ax","id":"protocol-probe:private-coresimulator-ax","stderr":""}],"preferenceEvidence":{"applied":false,"restored":true,"simulatorStateBefore":"Booted","diffs":[]},"lifecycle":{"source":"framed-protocol-fixture","crash":{"failure":"process-crash","recovered":true},"timeout":{"failure":"timeout","recovered":true},"cancellation":{"failure":"cancelled","recovered":true},"staleGeneration":{"failure":"stale-generation","recovered":true}},"positiveControl":{"issue":"#1626","fixture":"deep-button-v1","artifact":"deep-button-fixture.v1.json","depth":72,"changedDescendant":"deep-button-state","invalidShallowRule":{"command":"pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow","exitCode":1,"assertion":"AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid."},"safeFullRule":{"command":"pnpm bench:ios-snapshot:deep-button -- --rule safe-full","exitCode":0,"assertion":"full observation changed and includes the changed descendant."},"before":{"depth":72,"surfaceDigest":"bd7118623fd764b18b99394d25021372840cea98e8b3b0c0196d3e791b199062","fullDigest":"275f9d14720d5a02ed77b54a03a8f51830afcdc2b12577bd8014631bfbf2c81a","state":"off","surfaceNodeIds":["deep-button-root","deep-button-level-01"],"fullNodeIds":["deep-button-root","deep-button-level-01","deep-button-level-02","deep-button-level-03","deep-button-level-04","deep-button-level-05","deep-button-level-06","deep-button-level-07","deep-button-level-08","deep-button-level-09","deep-button-level-10","deep-button-level-11","deep-button-level-12","deep-button-level-13","deep-button-level-14","deep-button-level-15","deep-button-level-16","deep-button-level-17","deep-button-level-18","deep-button-level-19","deep-button-level-20","deep-button-level-21","deep-button-level-22","deep-button-level-23","deep-button-level-24","deep-button-level-25","deep-button-level-26","deep-button-level-27","deep-button-level-28","deep-button-level-29","deep-button-level-30","deep-button-level-31","deep-button-level-32","deep-button-level-33","deep-button-level-34","deep-button-level-35","deep-button-level-36","deep-button-level-37","deep-button-level-38","deep-button-level-39","deep-button-level-40","deep-button-level-41","deep-button-level-42","deep-button-level-43","deep-button-level-44","deep-button-level-45","deep-button-level-46","deep-button-level-47","deep-button-level-48","deep-button-level-49","deep-button-level-50","deep-button-level-51","deep-button-level-52","deep-button-level-53","deep-button-level-54","deep-button-level-55","deep-button-level-56","deep-button-level-57","deep-button-level-58","deep-button-level-59","deep-button-level-60","deep-button-level-61","deep-button-level-62","deep-button-level-63","deep-button-level-64","deep-button-level-65","deep-button-level-66","deep-button-level-67","deep-button-level-68","deep-button-level-69","deep-button-level-70","deep-button-level-71","deep-button-state"]},"after":{"depth":72,"surfaceDigest":"bd7118623fd764b18b99394d25021372840cea98e8b3b0c0196d3e791b199062","fullDigest":"8542024b5b9719f6b2ba9692915bda9011e0e5d10c4e21463257763ee765719d","state":"on","surfaceNodeIds":["deep-button-root","deep-button-level-01"],"fullNodeIds":["deep-button-root","deep-button-level-01","deep-button-level-02","deep-button-level-03","deep-button-level-04","deep-button-level-05","deep-button-level-06","deep-button-level-07","deep-button-level-08","deep-button-level-09","deep-button-level-10","deep-button-level-11","deep-button-level-12","deep-button-level-13","deep-button-level-14","deep-button-level-15","deep-button-level-16","deep-button-level-17","deep-button-level-18","deep-button-level-19","deep-button-level-20","deep-button-level-21","deep-button-level-22","deep-button-level-23","deep-button-level-24","deep-button-level-25","deep-button-level-26","deep-button-level-27","deep-button-level-28","deep-button-level-29","deep-button-level-30","deep-button-level-31","deep-button-level-32","deep-button-level-33","deep-button-level-34","deep-button-level-35","deep-button-level-36","deep-button-level-37","deep-button-level-38","deep-button-level-39","deep-button-level-40","deep-button-level-41","deep-button-level-42","deep-button-level-43","deep-button-level-44","deep-button-level-45","deep-button-level-46","deep-button-level-47","deep-button-level-48","deep-button-level-49","deep-button-level-50","deep-button-level-51","deep-button-level-52","deep-button-level-53","deep-button-level-54","deep-button-level-55","deep-button-level-56","deep-button-level-57","deep-button-level-58","deep-button-level-59","deep-button-level-60","deep-button-level-61","deep-button-level-62","deep-button-level-63","deep-button-level-64","deep-button-level-65","deep-button-level-66","deep-button-level-67","deep-button-level-68","deep-button-level-69","deep-button-level-70","deep-button-level-71","deep-button-state"]}},"status":"completed","cells":[{"candidate":"public-macos-ax","state":"warm","screen":"quiet","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.012Z","operation":"acquisition","wallClockMs":129.557708,"preparationMs":34387.72875,"firstLookMs":34517.286458,"firstTree":"readable","ok":true,"acquisition":{"nodes":[{"enabled":true,"focused":false,"frame":{"height":832.5,"width":383,"x":925,"y":126},"id":"n0","role":"AXGroup","subrole":"iOSContentGroup"},{"enabled":true,"focused":false,"frame":{"height":27.305489568470307,"width":348.7014925373134,"x":942.1492537313433,"y":185.05606407322648},"id":"n1","label":"Inert surface","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.36785139262804,"width":348.7014925373134,"x":942.1492537313433,"y":227.6018318748038},"id":"n2","label":"Tapping this text changes nothing on screen.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":60.00858123569799,"width":348.7014925373134,"x":942.1492537313433,"y":262.2099542334096},"id":"n3","label":"Nothing here reacts to touch, loads, or animates, so a tap leaves the hierarchy byte-identical and retryTapIfNoChange must re-tap.","parentId":"n0","role":"AXStaticText","selected":false}],"residue":[],"targetGeneration":"pid:813:launch:1786981653.462395","targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","truncated":false,"viewport":{"coordinateSpace":"host-screen","kind":"reported","rect":{"height":832.5,"width":383,"x":925,"y":126},"source":"AXPosition+AXSize"}},"metrics":{"requestBytes":438,"responseBytes":1529,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":5.657,"memoryBytes":11567104,"durationMs":129.557708},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":2,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"acquisition","wallClockMs":47.671459,"preparationMs":34387.72875,"firstLookMs":34435.400209,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1540,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.570999999999998,"memoryBytes":11714560,"durationMs":47.671459},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":3,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"acquisition","wallClockMs":39.633834,"preparationMs":34387.72875,"firstLookMs":34427.362584,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.1109999999999989,"memoryBytes":11780096,"durationMs":39.633834},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":4,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"acquisition","wallClockMs":39.680292,"preparationMs":34387.72875,"firstLookMs":34427.409042,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.1109999999999989,"memoryBytes":11796480,"durationMs":39.680292},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":5,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"acquisition","wallClockMs":40.945417,"preparationMs":34387.72875,"firstLookMs":34428.674167000005,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1540,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.338000000000001,"memoryBytes":11845632,"durationMs":40.945417},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":6,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":38.430958,"preparationMs":34387.72875,"firstLookMs":34426.159708,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.1630000000000038,"memoryBytes":11862016,"durationMs":38.430958},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":7,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":55.293459,"preparationMs":34387.72875,"firstLookMs":34443.022209,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.1099999999999994,"memoryBytes":11894784,"durationMs":55.293459},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":8,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":51.895167,"preparationMs":34387.72875,"firstLookMs":34439.623917000004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1541,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.3539999999999992,"memoryBytes":11894784,"durationMs":51.895167},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":9,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":50.8305,"preparationMs":34387.72875,"firstLookMs":34438.55925,"firstTree":"readable","ok":true,"metrics":{"requestBytes":438,"responseBytes":1539,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2439999999999998,"memoryBytes":11927552,"durationMs":50.8305},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":10,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":46.040417,"preparationMs":34387.72875,"firstLookMs":34433.769167,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.3079999999999998,"memoryBytes":11976704,"durationMs":46.040417},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":11,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":54.6205,"preparationMs":34387.72875,"firstLookMs":34442.34925,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1539,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.184000000000001,"memoryBytes":11993088,"durationMs":54.6205},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":12,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":123.059209,"preparationMs":34387.72875,"firstLookMs":34510.787959,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.206000000000003,"memoryBytes":12009472,"durationMs":123.059209},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":13,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":39.091042,"preparationMs":34387.72875,"firstLookMs":34426.819792,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.3369999999999962,"memoryBytes":12025856,"durationMs":39.091042},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":14,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":42.79875,"preparationMs":34387.72875,"firstLookMs":34430.527500000004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1540,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.365000000000002,"memoryBytes":12042240,"durationMs":42.79875},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":15,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":40.239292,"preparationMs":34387.72875,"firstLookMs":34427.968042,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2860000000000014,"memoryBytes":12042240,"durationMs":40.239292},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":16,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":40.598417,"preparationMs":34387.72875,"firstLookMs":34428.327167,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2219999999999978,"memoryBytes":12058624,"durationMs":40.598417},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":17,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":43.436916,"preparationMs":34387.72875,"firstLookMs":34431.165666,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2799999999999976,"memoryBytes":12091392,"durationMs":43.436916},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":18,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":42.913041,"preparationMs":34387.72875,"firstLookMs":34430.641791,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2880000000000038,"memoryBytes":12091392,"durationMs":42.913041},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":19,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":42.739958,"preparationMs":34387.72875,"firstLookMs":34430.468708,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.3950000000000031,"memoryBytes":12091392,"durationMs":42.739958},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"},{"index":20,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"acquisition","wallClockMs":44.086625,"preparationMs":34387.72875,"firstLookMs":34431.815375000006,"firstTree":"readable","ok":true,"metrics":{"requestBytes":439,"responseBytes":1542,"nodeCount":4,"maxTraversalDepth":1,"cpuMs":1.2680000000000007,"memoryBytes":12091392,"durationMs":44.086625},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n"}],"presentationSamples":[{"index":1,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"presentation","wallClockMs":0.7285829999964335,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.7285829999964335,"cpuMs":0.3739999999999668,"memoryBytes":73318400}},{"index":2,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"presentation","wallClockMs":0.09587499999906868,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.09587499999906868,"cpuMs":0.06200000000001182,"memoryBytes":73318400}},{"index":3,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"presentation","wallClockMs":0.15975000000617,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.15975000000617,"cpuMs":0.07900000000000773,"memoryBytes":73334784}},{"index":4,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.013Z","operation":"presentation","wallClockMs":0.04012499999953434,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.04012499999953434,"cpuMs":0.049000000000035016,"memoryBytes":73351168}},{"index":5,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.02466699999786215,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.02466699999786215,"cpuMs":0.038000000000010914,"memoryBytes":73367552}},{"index":6,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.018292000000656117,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.018292000000656117,"cpuMs":0.04699999999996862,"memoryBytes":73367552}},{"index":7,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.02908299999398878,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.02908299999398878,"cpuMs":0.019000000000005457,"memoryBytes":73367552}},{"index":8,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.01258399999642279,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.01258399999642279,"cpuMs":0.010999999999967258,"memoryBytes":73367552}},{"index":9,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.012374999998428393,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.012374999998428393,"cpuMs":0.011000000000024102,"memoryBytes":73367552}},{"index":10,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.019625000000814907,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.019625000000814907,"cpuMs":0.01599999999996271,"memoryBytes":73367552}},{"index":11,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.011041999998269603,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.011041999998269603,"cpuMs":0.009000000000014552,"memoryBytes":73367552}},{"index":12,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.02754099999583559,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.02754099999583559,"cpuMs":0.03300000000001546,"memoryBytes":73367552}},{"index":13,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.008999999998195563,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.008999999998195563,"cpuMs":0.007000000000005002,"memoryBytes":73367552}},{"index":14,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.006916999998793472,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.006916999998793472,"cpuMs":0.007000000000005002,"memoryBytes":73367552}},{"index":15,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.006667000001471024,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.006667000001471024,"cpuMs":0.007000000000005002,"memoryBytes":73367552}},{"index":16,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.028209000003698748,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.028209000003698748,"cpuMs":0.020000000000038654,"memoryBytes":73367552}},{"index":17,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.011375000001862645,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.011375000001862645,"cpuMs":0.009999999999990905,"memoryBytes":73367552}},{"index":18,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.04362500000570435,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.04362500000570435,"cpuMs":0.040000000000020464,"memoryBytes":73367552}},{"index":19,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.019291999997221865,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.019291999997221865,"cpuMs":0.016999999999995907,"memoryBytes":73367552}},{"index":20,"candidate":"public-macos-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:09:51.929Z","finishedAt":"2026-09-01T12:09:53.014Z","operation":"presentation","wallClockMs":0.011375000001862645,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:quiet:1 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:2 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:3 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:4 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:5 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:6 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:7 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:8 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:9 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:10 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:11 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:12 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:13 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:14 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:15 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:16 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:17 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:18 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:19 candidate=public-macos-ax screen=quiet\n[ios-ax-spike] capture id=public-macos-ax:warm:quiet:20 candidate=public-macos-ax screen=quiet\n","presentation":{"ok":true,"payloadBytes":1484,"nodeCount":4,"durationMs":0.011375000001862645,"cpuMs":0.009999999999990905,"memoryBytes":73367552}}]},{"candidate":"public-macos-ax","state":"warm","screen":"list","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.050Z","operation":"acquisition","wallClockMs":1166.959125,"preparationMs":26032.607416999992,"firstLookMs":27199.566541999993,"firstTree":"readable","ok":true,"acquisition":{"nodes":[{"enabled":true,"focused":false,"frame":{"height":832.5,"width":383,"x":925,"y":126},"id":"n0","role":"AXGroup","subrole":"iOSContentGroup"},{"enabled":true,"focused":false,"frame":{"height":34.290617848970214,"width":262.95522388059703,"x":942.1492537313433,"y":185.0560640732266},"id":"n1","label":"Catalog","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652741150670522,"width":54.623529538586354,"x":1226.3822550868513,"y":191.0886729202773},"id":"n2","label":"12 results","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":43.81578947368416,"width":262.95522388059703,"x":942.1492537313433,"y":225.06178489702518},"id":"n3","label":"Search, filter, scroll, favorite, and drill into detail without extra dependencies.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":16.192791762013712,"width":348.7014925373134,"x":942.1492537313433,"y":311.1058303955218},"id":"n4","label":"Catalog scroll: top","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":342.8564030834957},"id":"n5","label":"Search","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.050343249427897,"width":317.5787534191834,"x":957.7106142044067,"y":372.38443512010906},"id":"n6","label":"Search updates after a short debounce.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":16.192791762013712,"width":317.5787534191834,"x":957.7106142044067,"y":404.7700204609189},"id":"n7","label":"Find a product","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":48.89588098794019,"width":316.9435958546489,"x":958.028192986674,"y":428.9004552529898},"id":"n8","identifier":"catalog-search","label":"Search products","parentId":"n0","role":"AXTextField","selected":false,"value":"Try: tart, kit, loaf"},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":43.82587428116679,"x":957.7106142044067,"y":491.44907497868667},"id":"n9","identifier":"category-all","label":"All","parentId":"n0","role":"AXButton","selected":true},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":100.67246855550738,"x":1009.1583753984366,"y":491.44907497868667},"id":"n10","identifier":"category-starter-kits","label":"Starter Kits","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.87816583210048,"width":80.98258706467658,"x":1117.452741770009,"y":491.44907497868667},"id":"n11","identifier":"category-produce","label":"Produce","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.8781367635836,"width":71.77279780753219,"x":957.7106142044067,"y":534.9473599427351},"id":"n12","identifier":"category-bakery","label":"Bakery","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":35.8781367635836,"width":69.54975851258234,"x":1037.1053098280038,"y":534.9473599427351},"id":"n13","identifier":"category-pantry","label":"Pantry","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81295813030181,"width":317.5787534191834,"x":957.7106142044067,"y":613.3712917596306},"id":"n14","label":"Citrus Starter Kit","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885585,"width":317.5787534191834,"x":957.7106142044067,"y":642.8993237962438},"id":"n15","label":"A bright bundle for quick search, detail, and quantity flows.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652726616412053,"width":43.19071188969397,"x":967.5555558584223,"y":700.3678612335323},"id":"n16","label":"Popular","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637891232558218,"width":30.169973724517092,"x":1245.119393899073,"y":696.8752982287713},"id":"n17","label":"$12","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79803554089719,"width":53.03565626951,"x":957.7106142044067,"y":733.3884487806796},"id":"n18","identifier":"favorite-citrus-kit","label":"Save Citrus Starter Kit","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92278825772982,"width":53.9883816847161,"x":1221.300985938874,"y":741.3260914984776},"id":"n19","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.5457859694003,"width":317.5787534191834,"x":957.7106142044067,"y":777.5217536646933},"id":"n20","identifier":"details-citrus-kit","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236645,"width":317.5787534191834,"x":957.7106142044067,"y":829.5926930909844},"id":"n21","identifier":"add-citrus-kit","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.8129290617849,"width":317.5787534191834,"x":957.7106142044067,"y":914.6842305109211},"id":"n22","label":"Morning Prep Box","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855836,"width":317.5787534191834,"x":957.7106142044067,"y":944.2122625475345},"id":"n23","label":"Tests multi-step navigation with badges and action buttons.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445907,"width":24.771140644206326,"x":967.5555558584223,"y":1001.6807999848228},"id":"n24","label":"New","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63783309552435,"width":31.122710042925007,"x":1244.166657580665,"y":998.1882369800618},"id":"n25","label":"$18","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79803554089719,"width":53.03565626951,"x":957.7106142044067,"y":1034.70138753197},"id":"n26","identifier":"favorite-morning-box","label":"Save Morning Prep Box","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92278825772982,"width":53.9883816847161,"x":1221.300985938874,"y":1042.639030249768},"id":"n27","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.5457859694003,"width":317.5787534191834,"x":957.7106142044067,"y":1078.8346924159837},"id":"n28","identifier":"details-morning-box","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236648,"width":317.5787534191834,"x":957.7106142044067,"y":1130.905631842275},"id":"n29","identifier":"add-morning-box","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.812929061784928,"width":317.5787534191834,"x":957.7106142044067,"y":1215.9971401936946},"id":"n30","label":"Avocado Stack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885585,"width":317.5787534191834,"x":957.7106142044067,"y":1245.525172230308},"id":"n31","label":"Short card copy with favorite and add-to-cart actions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445872,"width":31.440294873062058,"x":967.5555558584223,"y":1302.9937096675965},"id":"n32","label":"Fresh","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637833095524343,"width":21.27775839430774,"x":1254.0116092292824,"y":1299.5011466628355},"id":"n33","label":"$7","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863342,"width":53.03565626951,"x":957.7106142044067,"y":1336.014297214744},"id":"n34","identifier":"favorite-avocado-stack","label":"Save Avocado Stack","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922846394763667,"width":53.9883816847161,"x":1221.300985938874,"y":1343.9519399325418},"id":"n35","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545844106434174,"width":317.5787534191834,"x":957.7106142044067,"y":1380.1476020987575},"id":"n36","identifier":"details-avocado-stack","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545727832366424,"width":317.5787534191834,"x":957.7106142044067,"y":1432.2185415250487},"id":"n37","identifier":"add-avocado-stack","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":1517.310108013502},"id":"n38","label":"Pepper Mix","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":1546.8381400501155},"id":"n39","label":"Useful for filters, scroll, and selector durability checks.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652784753445872,"width":29.852403431982538,"x":967.5555558584223,"y":1604.306677487404},"id":"n40","label":"Crisp","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637833095524343,"width":22.548083177253375,"x":1252.7412844463367,"y":1600.814114482643},"id":"n41","label":"$9","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798093677931092,"width":53.03565626951,"x":957.7106142044067,"y":1637.3272650345511},"id":"n42","identifier":"favorite-pepper-mix","label":"Save Pepper Mix","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922730120695974,"width":53.9883816847161,"x":1221.300985938874,"y":1645.2649077523492},"id":"n43","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545727832366424,"width":317.5787534191834,"x":957.7106142044067,"y":1681.460569918565},"id":"n44","identifier":"details-pepper-mix","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.545844106434174,"width":317.5787534191834,"x":957.7106142044067,"y":1733.5315093448562},"id":"n45","identifier":"add-pepper-mix","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":1818.6229595592422},"id":"n46","label":"Herb Bundle","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.10068649885591,"width":317.5787534191834,"x":957.7106142044067,"y":1848.1509915958552},"id":"n47","label":"A compact row for visible-text and existence assertions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":51.13018363269407,"x":967.5555558584223,"y":1905.6195290331439},"id":"n48","label":"Seasonal","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637949369592093,"width":22.548083177253375,"x":1252.7412844463367,"y":1902.1269660283824},"id":"n49","label":"$6","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79809367793098,"width":53.03565626951,"x":957.7106142044067,"y":1938.6401165802913},"id":"n50","identifier":"favorite-herb-bundle","label":"Save Herb Bundle","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92273012069586,"width":53.9883816847161,"x":1221.300985938874,"y":1946.577759298089},"id":"n51","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54572783236654,"width":317.5787534191834,"x":957.7106142044067,"y":1982.7734214643046},"id":"n52","identifier":"details-herb-bundle","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2034.8443608905957},"id":"n53","identifier":"add-herb-bundle","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2119.9359273790496},"id":"n54","label":"Pretzel Bites","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2149.463959415663},"id":"n55","label":"Helps exercise off-screen discovery and scoped snapshots.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":34.61608502402234,"x":967.5555558584223,"y":2206.932496852951},"id":"n56","label":"Snack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959198,"width":22.548083177253375,"x":1252.7412844463367,"y":2203.43993384819},"id":"n57","label":"$8","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798209951998615,"width":53.03565626951,"x":957.7106142044067,"y":2239.9530844000983},"id":"n58","identifier":"favorite-pretzel-bites","label":"Save Pretzel Bites","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":2247.8907271178964},"id":"n59","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":2284.0863892841126},"id":"n60","identifier":"details-pretzel-bites","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2336.1573287104034},"id":"n61","identifier":"add-pretzel-bites","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2421.2487789247893},"id":"n62","label":"Sourdough Loaf","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2450.7768109614026},"id":"n63","label":"Works well for favorite toggles and detail page assertions.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378235,"width":32.710612387206425,"x":967.5555558584223,"y":2508.245348398691},"id":"n64","label":"Warm","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959198,"width":27.946912623163485,"x":1247.3424550004265,"y":2504.75278539393},"id":"n65","label":"$11","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863342,"width":53.03565626951,"x":957.7106142044067,"y":2541.2659359458385},"id":"n66","identifier":"favorite-sourdough-loaf","label":"Save Sourdough Loaf","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92284639476361,"width":53.9883816847161,"x":1221.300985938874,"y":2549.203578663636},"id":"n67","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643406,"width":317.5787534191834,"x":957.7106142044067,"y":2585.3992408298523},"id":"n68","identifier":"details-sourdough-loaf","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":2637.470180256143},"id":"n69","identifier":"add-sourdough-loaf","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":2722.5618630186646},"id":"n70","label":"Berry Tart","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":2752.0898950552773},"id":"n71","label":"A longer list item to force scrolling on smaller devices.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652901027513508,"width":34.93366621975875,"x":967.5555558584223,"y":2809.5584324925658},"id":"n72","label":"Sweet","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637716821456706,"width":30.805121578387343,"x":1244.4842460452028,"y":2806.065869487805},"id":"n73","label":"$14","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":2842.579020039713},"id":"n74","identifier":"favorite-berry-tart","label":"Save Berry Tart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.92284639476361,"width":53.9883816847161,"x":1221.300985938874,"y":2850.5166627575113},"id":"n75","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":2886.7123249237275},"id":"n76","identifier":"details-berry-tart","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":2938.7832643500183},"id":"n77","identifier":"add-berry-tart","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3023.8747145644043},"id":"n78","label":"Tea Tins","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3053.4027466010175},"id":"n79","label":"Good target for search debounce and cart state updates.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":28.58208591783817,"x":967.5555558584223,"y":3110.871284038306},"id":"n80","label":"Calm","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.805121578387343,"x":1244.4842460452028,"y":3107.378721033545},"id":"n81","label":"$10","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.798209951998615,"width":53.03565626951,"x":957.7106142044067,"y":3143.891871585453},"id":"n82","identifier":"favorite-tea-tins","label":"Save Tea Tins","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":3151.829514303251},"id":"n83","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":3188.0251764694667},"id":"n84","identifier":"details-tea-tins","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3240.096115895758},"id":"n85","identifier":"add-tea-tins","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3325.187566110144},"id":"n86","label":"Olive Jar","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3354.715598146757},"id":"n87","label":"A stable card for replay maintenance and selector exercises.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":40.65008413020651,"x":967.5555558584223,"y":3412.1841355840456},"id":"n88","label":"Classic","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.4875621890547,"x":1244.8018345097405,"y":3408.6915725792846},"id":"n89","label":"$13","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":3445.2047231311926},"id":"n90","identifier":"favorite-olive-jar","label":"Save Olive Jar","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":3453.1423658489907},"id":"n91","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3489.3380280152064},"id":"n92","identifier":"details-olive-jar","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":3541.408967441498},"id":"n93","identifier":"add-olive-jar","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3626.500650204019},"id":"n94","label":"Noodle Pack","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":19.050343249427897,"width":317.5787534191834,"x":957.7106142044067,"y":3656.028682240633},"id":"n95","label":"Works well for detail notes and quantity edits.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652668479378008,"width":23.81840432579837,"x":967.5555558584223,"y":3694.4468764284925},"id":"n96","label":"Fast","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.63794936959175,"width":30.4875621890547,"x":1244.8018345097405,"y":3690.9543134237315},"id":"n97","label":"$15","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.797977403863115,"width":53.03565626951,"x":957.7106142044067,"y":3727.4674712427695},"id":"n98","identifier":"favorite-noodle-pack","label":"Save Noodle Pack","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922846394763837,"width":53.9883816847161,"x":1221.300985938874,"y":3735.405113960567},"id":"n99","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3771.6007688596537},"id":"n100","identifier":"details-noodle-pack","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54584410643429,"width":317.5787534191834,"x":957.7106142044067,"y":3823.671708285945},"id":"n101","identifier":"add-noodle-pack","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":3908.7631585003314},"id":"n102","label":"Seasonal Footer Pick","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":3938.2911905369438},"id":"n103","label":"Placed last on purpose so scroll-into-view flows have a durable target.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":13.652901027513508,"width":71.455223880597,"x":967.5555558584223,"y":3995.7597279742326},"id":"n104","label":"Scroll Target","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":20.637716821456706,"width":30.805121578387343,"x":1244.4842460452028,"y":3992.2671649694717},"id":"n105","label":"$16","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":30.79774485572807,"width":53.03565626951,"x":957.7106142044067,"y":4028.78031552138},"id":"n106","identifier":"favorite-seasonal-footer","label":"Save Seasonal Footer Pick","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":14.922613846628337,"width":53.9883816847161,"x":1221.300985938874,"y":4036.7179582391777},"id":"n107","label":"In cart: 0","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54607665456933,"width":317.5787534191834,"x":957.7106142044067,"y":4072.913620405394},"id":"n108","identifier":"details-seasonal-footer","label":"View details","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":42.54561155829879,"width":317.5787534191834,"x":957.7106142044067,"y":4124.984559831684},"id":"n109","identifier":"add-seasonal-footer","label":"Add to cart","parentId":"n0","role":"AXButton","selected":false},{"enabled":true,"focused":false,"frame":{"height":23.81292906178487,"width":317.5787534191834,"x":957.7106142044067,"y":4210.076242594207},"id":"n110","label":"Seasonal footer target","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":38.100686498855794,"width":317.5787534191834,"x":957.7106142044067,"y":4239.604274630819},"id":"n111","label":"This footer card sits at the end of the list to force scroll-into-view on smaller screens.","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":62.86613272311206,"width":317.5787534191834,"x":957.7106142044067,"y":4291.040203221057},"id":"n112","label":"If your run reaches this card, you already exercised long-list navigation. The durable text here is \"Seasonal footer target\".","parentId":"n0","role":"AXStaticText","selected":false},{"enabled":true,"focused":false,"frame":{"height":79.05892448512586,"width":383,"x":925,"y":879.4410755148742},"id":"n113","label":"Tab Bar","parentId":"n0","role":"AXGroup","selected":false}],"residue":[],"targetGeneration":"pid:813:launch:1786981653.462395","targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","truncated":false,"viewport":{"coordinateSpace":"host-screen","kind":"reported","rect":{"height":832.5,"width":383,"x":925,"y":126},"source":"AXPosition+AXSize"}},"metrics":{"requestBytes":436,"responseBytes":28595,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":30.632999999999996,"memoryBytes":11583488,"durationMs":1166.959125},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n"},{"index":2,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.053Z","operation":"acquisition","wallClockMs":1007.093792,"preparationMs":26032.607416999992,"firstLookMs":27039.70120899999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":436,"responseBytes":28583,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":26.448,"memoryBytes":12107776,"durationMs":1007.093792},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n"},{"index":3,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.054Z","operation":"acquisition","wallClockMs":961.450375,"preparationMs":26032.607416999992,"firstLookMs":26994.057791999992,"firstTree":"readable","ok":true,"metrics":{"requestBytes":436,"responseBytes":28594,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":24.194000000000003,"memoryBytes":12271616,"durationMs":961.450375},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n"},{"index":4,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.056Z","operation":"acquisition","wallClockMs":1064.505833,"preparationMs":26032.607416999992,"firstLookMs":27097.11324999999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":436,"responseBytes":28595,"nodeCount":114,"maxTraversalDepth":1,"cpuMs":27.709999999999994,"memoryBytes":12304384,"durationMs":1064.505833},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n"},{"index":5,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.057Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":6,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":7,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":8,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":9,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":436,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":10,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":11,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":12,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":13,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":14,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":15,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":16,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":17,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":18,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":19,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":20,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"acquisition","wallClockMs":5002.761541,"preparationMs":26032.607416999992,"firstLookMs":31035.368957999992,"firstTree":"not-observed","ok":false,"metrics":{"requestBytes":437,"responseBytes":114367,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","failure":{"kind":"timeout","code":"batch-duration-limit"}}],"presentationSamples":[{"index":1,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.053Z","operation":"presentation","wallClockMs":2.337249999996857,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":true,"payloadBytes":28425,"nodeCount":114,"durationMs":2.337249999996857,"cpuMs":2.7449999999999477,"memoryBytes":74645504}},{"index":2,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.054Z","operation":"presentation","wallClockMs":1.584500000011758,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":true,"payloadBytes":28425,"nodeCount":114,"durationMs":1.584500000011758,"cpuMs":2.1650000000000205,"memoryBytes":75694080}},{"index":3,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.056Z","operation":"presentation","wallClockMs":1.5459169999958249,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":true,"payloadBytes":28425,"nodeCount":114,"durationMs":1.5459169999958249,"cpuMs":1.4989999999999668,"memoryBytes":76644352}},{"index":4,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.057Z","operation":"presentation","wallClockMs":1.5806250000023283,"firstTree":"readable","ok":true,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":true,"payloadBytes":28425,"nodeCount":114,"durationMs":1.5806250000023283,"cpuMs":1.8980000000000246,"memoryBytes":77234176}},{"index":5,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":6,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":7,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":8,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":9,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":10,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":11,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":12,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":13,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":14,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":15,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":16,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":17,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":18,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":19,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}},{"index":20,"candidate":"public-macos-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:10:33.047Z","finishedAt":"2026-09-01T12:10:38.058Z","operation":"presentation","wallClockMs":0,"firstTree":"not-observed","ok":false,"stderr":"[ios-ax-spike] capture id=public-macos-ax:warm:list:1 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:2 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:3 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:4 candidate=public-macos-ax screen=list\n[ios-ax-spike] capture id=public-macos-ax:warm:list:5 candidate=public-macos-ax screen=list\n","presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":77234176},"failure":{"kind":"timeout","code":"batch-duration-limit"}}]},{"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":2,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":3,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":4,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":5,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":6,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":7,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":8,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":9,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":456,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":10,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":11,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":12,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":13,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":14,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":15,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":16,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":17,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":18,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":19,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":20,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"acquisition","wallClockMs":0.05895800000871532,"preparationMs":31115.451833,"firstLookMs":31115.510791000008,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":457,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}}],"presentationSamples":[{"index":1,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":2,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":3,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":4,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":5,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":6,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":7,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":8,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":9,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":10,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":11,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":12,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":13,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":14,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":15,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":16,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":17,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":18,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":19,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":20,"candidate":"private-coresimulator-ax","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:11:20.454Z","finishedAt":"2026-09-01T12:11:20.454Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70828032},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}}]},{"candidate":"private-coresimulator-ax","state":"warm","screen":"list","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":2,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":3,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":4,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":5,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":6,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":7,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":8,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":9,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":454,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":10,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":11,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":12,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":13,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":14,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":15,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":16,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":17,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":18,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":19,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.018Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":20,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.018Z","operation":"acquisition","wallClockMs":0.03854099998716265,"preparationMs":30479.48745799999,"firstLookMs":30479.525998999976,"firstTree":"unreadable","ok":false,"metrics":{"requestBytes":455,"responseBytes":0,"nodeCount":0,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":null,"durationMs":0},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}}],"presentationSamples":[{"index":1,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":2,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":3,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":4,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":5,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70516736},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":6,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":7,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":8,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":9,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":10,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":11,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":12,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":13,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":14,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":15,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":16,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":17,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70533120},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":18,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.017Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70549504},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":19,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.018Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70549504},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}},{"index":20,"candidate":"private-coresimulator-ax","state":"warm","screen":"list","startedAt":"2026-09-01T12:12:04.017Z","finishedAt":"2026-09-01T12:12:04.018Z","operation":"presentation","wallClockMs":0,"firstTree":"unreadable","ok":false,"presentation":{"ok":false,"payloadBytes":0,"nodeCount":0,"durationMs":0,"cpuMs":null,"memoryBytes":70549504},"failure":{"kind":"unsupported-mechanism","code":"private-tool-unavailable"}}]},{"candidate":"xctest-control","state":"warm","screen":"quiet","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.020Z","operation":"acquisition","wallClockMs":940.5797079999757,"preparationMs":26402.23541699999,"firstLookMs":27342.815124999965,"firstTree":"readable","ok":true,"acquisition":{"targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","targetGeneration":"896978","nodes":[{"id":"0","type":"Application","label":"Agent Device Tester","frame":{"x":0,"y":0,"width":402,"height":874},"enabled":true},{"id":"1","parentId":"0","type":"Other","label":"Inert surface","frame":{"x":0,"y":0,"width":402,"height":874},"enabled":true},{"id":"2","parentId":"1","type":"StaticText","label":"Tapping this text changes nothing on screen.","identifier":"inert-target","frame":{"x":18,"y":106.66666793823242,"width":366,"height":20.333335876464844},"enabled":true},{"id":"3","parentId":"1","type":"StaticText","label":"Nothing here reacts to touch, loads, or animates, so a tap leaves the hierarchy byte-identical and retryTapIfNoChange must re-tap.","frame":{"x":18,"y":143,"width":366,"height":63},"enabled":true}],"viewport":{"kind":"missing","reason":"not-provided"},"truncated":false,"residue":[{"kind":"missing-viewport","reason":"not-provided"}]},"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70828032,"durationMs":940.5797079999757}},{"index":2,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":552.9202079999959,"preparationMs":26402.23541699999,"firstLookMs":26955.155624999985,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3127,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70828032,"durationMs":552.9202079999959}},{"index":3,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":642.013042000006,"preparationMs":26402.23541699999,"firstLookMs":27044.248458999995,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3127,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70582272,"durationMs":642.013042000006}},{"index":4,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":260.03691699999035,"preparationMs":26402.23541699999,"firstLookMs":26662.27233399998,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3125,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70762496,"durationMs":260.03691699999035}},{"index":5,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":305.75333300000057,"preparationMs":26402.23541699999,"firstLookMs":26707.98874999999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3126,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70844416,"durationMs":305.75333300000057}},{"index":6,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":303.1445829999866,"preparationMs":26402.23541699999,"firstLookMs":26705.379999999976,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3125,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70909952,"durationMs":303.1445829999866}},{"index":7,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":298.53429199999664,"preparationMs":26402.23541699999,"firstLookMs":26700.769708999986,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3126,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70909952,"durationMs":298.53429199999664}},{"index":8,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":347.65412500000093,"preparationMs":26402.23541699999,"firstLookMs":26749.88954199999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70909952,"durationMs":347.65412500000093}},{"index":9,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":321.18845899999724,"preparationMs":26402.23541699999,"firstLookMs":26723.423875999986,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3128,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70926336,"durationMs":321.18845899999724}},{"index":10,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":958.9179159999767,"preparationMs":26402.23541699999,"firstLookMs":27361.153332999966,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3130,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70942720,"durationMs":958.9179159999767}},{"index":11,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":517.407583000022,"preparationMs":26402.23541699999,"firstLookMs":26919.64300000001,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70959104,"durationMs":517.407583000022}},{"index":12,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":286.47508400000515,"preparationMs":26402.23541699999,"firstLookMs":26688.710500999994,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3123,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70959104,"durationMs":286.47508400000515}},{"index":13,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":374.069542000012,"preparationMs":26402.23541699999,"firstLookMs":26776.304959,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3128,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70959104,"durationMs":374.069542000012}},{"index":14,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":371.6503340000054,"preparationMs":26402.23541699999,"firstLookMs":26773.885750999994,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3127,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70959104,"durationMs":371.6503340000054}},{"index":15,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":513.5785830000241,"preparationMs":26402.23541699999,"firstLookMs":26915.814000000013,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3131,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70975488,"durationMs":513.5785830000241}},{"index":16,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":450.3380420000176,"preparationMs":26402.23541699999,"firstLookMs":26852.573459000007,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3130,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71024640,"durationMs":450.3380420000176}},{"index":17,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":881.7244999999821,"preparationMs":26402.23541699999,"firstLookMs":27283.95991699997,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71024640,"durationMs":881.7244999999821}},{"index":18,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":1466.0735419999983,"preparationMs":26402.23541699999,"firstLookMs":27868.308958999987,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3128,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71106560,"durationMs":1466.0735419999983}},{"index":19,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":466.965125000017,"preparationMs":26402.23541699999,"firstLookMs":26869.200542000006,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71122944,"durationMs":466.965125000017}},{"index":20,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"acquisition","wallClockMs":689.8686250000028,"preparationMs":26402.23541699999,"firstLookMs":27092.10404199999,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":3129,"nodeCount":4,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":71122944,"durationMs":689.8686250000028}}],"presentationSamples":[{"index":1,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.13295800000196323,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.13295800000196323,"cpuMs":0.117999999999995,"memoryBytes":71155712}},{"index":2,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.013624999992316589,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.013624999992316589,"cpuMs":0.012000000000000455,"memoryBytes":71155712}},{"index":3,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.008957999991253018,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.008957999991253018,"cpuMs":0.009000000000014552,"memoryBytes":71155712}},{"index":4,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.007374999986495823,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.007374999986495823,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":5,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006832999992184341,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006832999992184341,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":6,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006625000009080395,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006625000009080395,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":7,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006332999997539446,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006332999997539446,"cpuMs":0.0049999999999954525,"memoryBytes":71155712}},{"index":8,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006332999997539446,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006332999997539446,"cpuMs":0.0049999999999954525,"memoryBytes":71155712}},{"index":9,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.00849999999627471,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.00849999999627471,"cpuMs":0.008000000000038199,"memoryBytes":71155712}},{"index":10,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006458000018028542,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006458000018028542,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":11,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006415999989258125,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006415999989258125,"cpuMs":0.005999999999971806,"memoryBytes":71155712}},{"index":12,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006292000005487353,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006292000005487353,"cpuMs":0.006000000000028649,"memoryBytes":71155712}},{"index":13,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006332999997539446,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006332999997539446,"cpuMs":0.007000000000005002,"memoryBytes":71155712}},{"index":14,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006374999997206032,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006374999997206032,"cpuMs":0.007000000000005002,"memoryBytes":71155712}},{"index":15,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.02266700001200661,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.02266700001200661,"cpuMs":0.02199999999999136,"memoryBytes":71155712}},{"index":16,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006750000000465661,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006750000000465661,"cpuMs":0.006000000000028649,"memoryBytes":71155712}},{"index":17,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.0064999999885912985,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.0064999999885912985,"cpuMs":0.006000000000028649,"memoryBytes":71155712}},{"index":18,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.00704199998290278,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.00704199998290278,"cpuMs":0.006000000000028649,"memoryBytes":71155712}},{"index":19,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006666000001132488,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006666000001132488,"cpuMs":0.010000000000047748,"memoryBytes":71155712}},{"index":20,"candidate":"xctest-control","state":"warm","screen":"quiet","startedAt":"2026-09-01T12:12:45.066Z","finishedAt":"2026-09-01T12:12:56.021Z","operation":"presentation","wallClockMs":0.006458999996539205,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":1174,"nodeCount":4,"durationMs":0.006458999996539205,"cpuMs":0.007000000000005002,"memoryBytes":71155712}}]},{"candidate":"xctest-control","state":"warm","screen":"list","sampleMinimum":20,"acquisitionSamples":[{"index":1,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.084Z","operation":"acquisition","wallClockMs":579.3912919999566,"preparationMs":35852.83254200002,"firstLookMs":36432.223833999975,"firstTree":"readable","ok":true,"acquisition":{"targetId":"simulator:F578F08D-BEA1-4A56-8A4B-C92B040FBA94","targetGeneration":"933815","nodes":[{"id":"0","type":"Application","label":"Agent Device Tester","frame":{"x":0,"y":0,"width":402,"height":874},"enabled":true},{"id":"1","parentId":"0","type":"ScrollView","frame":{"x":18,"y":62,"width":366,"height":729},"enabled":true},{"id":"2","parentId":"1","type":"StaticText","label":"Catalog","frame":{"x":18,"y":62,"width":276,"height":36},"enabled":true},{"id":"3","parentId":"1","type":"Other","identifier":"catalog-title","frame":{"x":18,"y":62,"width":366,"height":108.33332824707031},"enabled":true},{"id":"4","parentId":"1","type":"StaticText","label":"12 results","frame":{"x":316.3333330154419,"y":68.33333349227905,"width":57.33331298828125,"height":14.333328247070312},"enabled":true},{"id":"5","parentId":"1","type":"StaticText","label":"Search, filter, scroll, favorite, and drill into detail without extra dependencies.","frame":{"x":18,"y":104,"width":276,"height":46},"enabled":true},{"id":"6","parentId":"1","type":"StaticText","label":"Catalog scroll: top","identifier":"catalog-scroll-state","frame":{"x":18,"y":194.3333282470703,"width":366,"height":17},"enabled":true},{"id":"7","parentId":"1","type":"StaticText","label":"Search","frame":{"x":34.33333396911621,"y":227.66666221618652,"width":333.33331298828125,"height":25},"enabled":true},{"id":"8","parentId":"1","type":"StaticText","label":"Search updates after a short debounce.","frame":{"x":34.33333396911621,"y":258.6666622161865,"width":333.33331298828125,"height":20},"enabled":true},{"id":"9","parentId":"1","type":"StaticText","label":"Find a product","frame":{"x":34.33333396911621,"y":292.66666412353516,"width":333.33331298828125,"height":17},"enabled":true},{"id":"10","parentId":"1","type":"TextField","label":"Search products","identifier":"catalog-search","frame":{"x":34.66666731238365,"y":317.9999974668026,"width":332.66664630174637,"height":51.33333331346512},"enabled":true},{"id":"11","parentId":"1","type":"Button","label":"All","identifier":"category-all","frame":{"x":34.33333396911621,"y":383.6666564941406,"width":46.000003814697266,"height":37.66668701171875},"enabled":true,"selected":true},{"id":"12","parentId":"1","type":"Button","label":"Starter Kits","identifier":"category-starter-kits","frame":{"x":88.33333396911621,"y":383.6666564941406,"width":105.66666412353516,"height":37.66668701171875},"enabled":true},{"id":"13","parentId":"1","type":"Button","label":"Produce","identifier":"category-produce","frame":{"x":202.0000057220459,"y":383.6666564941406,"width":85,"height":37.66668701171875},"enabled":true},{"id":"14","parentId":"1","type":"Button","label":"Bakery","identifier":"category-bakery","frame":{"x":34.33333396911621,"y":429.33332443237305,"width":75.33332824707031,"height":37.666656494140625},"enabled":true},{"id":"15","parentId":"1","type":"Button","label":"Pantry","identifier":"category-pantry","frame":{"x":117.66666984558105,"y":429.33332443237305,"width":73.00000762939453,"height":37.666656494140625},"enabled":true},{"id":"16","parentId":"1","type":"Other","identifier":"product-card-citrus-kit","frame":{"x":18,"y":495.3333435058594,"width":366,"height":295.6666564941406},"enabled":true},{"id":"17","parentId":"1","type":"StaticText","label":"Citrus Starter Kit","frame":{"x":34.33333396911621,"y":511.6666774749756,"width":333.33331298828125,"height":25.000030517578125},"enabled":true},{"id":"18","parentId":"1","type":"StaticText","label":"A bright bundle for quick search, detail, and quantity flows.","frame":{"x":34.33333396911621,"y":542.6666774749756,"width":333.33331298828125,"height":40},"enabled":true},{"id":"19","parentId":"1","type":"StaticText","label":"Popular","frame":{"x":44.666666984558105,"y":603.0000128746033,"width":45.33333206176758,"height":14.33331298828125},"enabled":true},{"id":"20","parentId":"1","type":"StaticText","label":"$12","frame":{"x":335.99999046325684,"y":599.3333461284637,"width":31.666656494140625,"height":21.66668701171875},"enabled":true},{"id":"21","parentId":"1","type":"Button","label":"Save Citrus Starter Kit","identifier":"favorite-citrus-kit","frame":{"x":34.33333396911621,"y":637.6666717529297,"width":55.66666793823242,"height":32.33331298828125},"enabled":true},{"id":"22","parentId":"1","type":"StaticText","label":"In cart: 0","frame":{"x":310.99999046325684,"y":646.0000047683716,"width":56.666656494140625,"height":15.66668701171875},"enabled":true},{"id":"23","parentId":"1","type":"Button","label":"View details","identifier":"details-citrus-kit","frame":{"x":34.33333396911621,"y":684.0000152587891,"width":333.33331298828125,"height":44.66668701171875},"enabled":true},{"id":"24","parentId":"1","type":"Button","label":"Add to cart","identifier":"add-citrus-kit","frame":{"x":34.33333396911621,"y":738.6666831970215,"width":333.33331298828125,"height":44.6666259765625},"enabled":true},{"id":"25","parentId":"0","type":"TabBar","label":"Tab Bar","frame":{"x":0,"y":791,"width":402,"height":83},"enabled":true},{"id":"26","parentId":"25","type":"Button","label":"Home","frame":{"x":25,"y":795,"width":74,"height":54},"enabled":true},{"id":"27","parentId":"25","type":"Button","label":"Catalog","frame":{"x":93.41666666666666,"y":795,"width":74.33333333333334,"height":54},"enabled":true,"selected":true},{"id":"28","parentId":"25","type":"Button","label":"Form","frame":{"x":162.16666666666666,"y":795,"width":74,"height":54},"enabled":true},{"id":"29","parentId":"25","type":"Button","label":"Audio","frame":{"x":230.58333333333331,"y":795,"width":74,"height":54},"enabled":true},{"id":"30","parentId":"25","type":"Button","label":"Settings","frame":{"x":299,"y":795,"width":78,"height":54},"enabled":true}],"viewport":{"kind":"missing","reason":"not-provided"},"truncated":true,"residue":[{"kind":"missing-viewport","reason":"not-provided"}]},"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69025792,"durationMs":579.3912919999566}},{"index":2,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.085Z","operation":"acquisition","wallClockMs":566.228375000006,"preparationMs":35852.83254200002,"firstLookMs":36419.060917000024,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16421,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69271552,"durationMs":566.228375000006}},{"index":3,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.085Z","operation":"acquisition","wallClockMs":985.4735000000219,"preparationMs":35852.83254200002,"firstLookMs":36838.30604200004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69369856,"durationMs":985.4735000000219}},{"index":4,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.086Z","operation":"acquisition","wallClockMs":828.7607919999864,"preparationMs":35852.83254200002,"firstLookMs":36681.593334000005,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69419008,"durationMs":828.7607919999864}},{"index":5,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":651.1083750000107,"preparationMs":35852.83254200002,"firstLookMs":36503.94091700003,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69500928,"durationMs":651.1083750000107}},{"index":6,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":569.1852499999804,"preparationMs":35852.83254200002,"firstLookMs":36422.017792,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69632000,"durationMs":569.1852499999804}},{"index":7,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":563.2574579999782,"preparationMs":35852.83254200002,"firstLookMs":36416.09,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69681152,"durationMs":563.2574579999782}},{"index":8,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":775.7467920000199,"preparationMs":35852.83254200002,"firstLookMs":36628.57933400004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16427,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69681152,"durationMs":775.7467920000199}},{"index":9,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":565.0179579999531,"preparationMs":35852.83254200002,"firstLookMs":36417.85049999997,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16423,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69681152,"durationMs":565.0179579999531}},{"index":10,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"acquisition","wallClockMs":566.0364999999874,"preparationMs":35852.83254200002,"firstLookMs":36418.869042000006,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69697536,"durationMs":566.0364999999874}},{"index":11,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":570.7256249999627,"preparationMs":35852.83254200002,"firstLookMs":36423.55816699998,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16427,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69861376,"durationMs":570.7256249999627}},{"index":12,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":640.0835000000079,"preparationMs":35852.83254200002,"firstLookMs":36492.916042000026,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69943296,"durationMs":640.0835000000079}},{"index":13,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":561.719625000027,"preparationMs":35852.83254200002,"firstLookMs":36414.552167000045,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69959680,"durationMs":561.719625000027}},{"index":14,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":563.2965829999885,"preparationMs":35852.83254200002,"firstLookMs":36416.12912500001,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69976064,"durationMs":563.2965829999885}},{"index":15,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":567.6302920000162,"preparationMs":35852.83254200002,"firstLookMs":36420.462834000034,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16427,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":69992448,"durationMs":567.6302920000162}},{"index":16,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":673.7819589999854,"preparationMs":35852.83254200002,"firstLookMs":36526.614501000004,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70107136,"durationMs":673.7819589999854}},{"index":17,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":638.8914169999771,"preparationMs":35852.83254200002,"firstLookMs":36491.723958999995,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70205440,"durationMs":638.8914169999771}},{"index":18,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":564.9031670000404,"preparationMs":35852.83254200002,"firstLookMs":36417.73570900006,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16425,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70402048,"durationMs":564.9031670000404}},{"index":19,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":557.9273750000284,"preparationMs":35852.83254200002,"firstLookMs":36410.75991700005,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16424,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70565888,"durationMs":557.9273750000284}},{"index":20,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"acquisition","wallClockMs":704.0210419999785,"preparationMs":35852.83254200002,"firstLookMs":36556.853584,"firstTree":"readable","ok":true,"metrics":{"requestBytes":0,"responseBytes":16426,"nodeCount":31,"maxTraversalDepth":0,"cpuMs":null,"memoryBytes":70762496,"durationMs":704.0210419999785}}],"presentationSamples":[{"index":1,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.085Z","operation":"presentation","wallClockMs":0.44904200005112216,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.44904200005112216,"cpuMs":0.15600000000006276,"memoryBytes":70926336}},{"index":2,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.085Z","operation":"presentation","wallClockMs":0.5059580000233836,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.5059580000233836,"cpuMs":0.27800000000002,"memoryBytes":71155712}},{"index":3,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.086Z","operation":"presentation","wallClockMs":0.07150000002002344,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.07150000002002344,"cpuMs":0.09299999999996089,"memoryBytes":71172096}},{"index":4,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.7780829999828711,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.7780829999828711,"cpuMs":0.07000000000005002,"memoryBytes":71172096}},{"index":5,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.052207999979145825,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.052207999979145825,"cpuMs":0.051000000000044565,"memoryBytes":71172096}},{"index":6,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.04850000003352761,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04850000003352761,"cpuMs":0.04800000000000182,"memoryBytes":71172096}},{"index":7,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.05070800002431497,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.05070800002431497,"cpuMs":0.05000000000006821,"memoryBytes":71172096}},{"index":8,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.13062499999068677,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.13062499999068677,"cpuMs":0.12999999999999545,"memoryBytes":71172096}},{"index":9,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.087Z","operation":"presentation","wallClockMs":0.047583999985363334,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.047583999985363334,"cpuMs":0.04600000000004911,"memoryBytes":71172096}},{"index":10,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04908300004899502,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04908300004899502,"cpuMs":0.04899999999997817,"memoryBytes":71172096}},{"index":11,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04854200000409037,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04854200000409037,"cpuMs":0.04699999999991178,"memoryBytes":71172096}},{"index":12,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04779100004816428,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04779100004816428,"cpuMs":0.047000000000025466,"memoryBytes":71172096}},{"index":13,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.06812499999068677,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.06812499999068677,"cpuMs":0.06700000000000728,"memoryBytes":71303168}},{"index":14,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.09541599999647588,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.09541599999647588,"cpuMs":0.09399999999993724,"memoryBytes":71434240}},{"index":15,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.046999999962281436,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.046999999962281436,"cpuMs":0.04600000000004911,"memoryBytes":71434240}},{"index":16,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04824999999254942,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04824999999254942,"cpuMs":0.04699999999991178,"memoryBytes":71434240}},{"index":17,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04666599998017773,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04666599998017773,"cpuMs":0.04600000000004911,"memoryBytes":71434240}},{"index":18,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04666599998017773,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04666599998017773,"cpuMs":0.045999999999935426,"memoryBytes":71434240}},{"index":19,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.04729100002441555,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.04729100002441555,"cpuMs":0.04600000000004911,"memoryBytes":71434240}},{"index":20,"candidate":"xctest-control","state":"warm","screen":"list","startedAt":"2026-09-01T12:13:49.387Z","finishedAt":"2026-09-01T12:14:02.088Z","operation":"presentation","wallClockMs":0.046541000017896295,"firstTree":"readable","ok":true,"presentation":{"ok":true,"payloadBytes":6090,"nodeCount":31,"durationMs":0.046541000017896295,"cpuMs":0.04499999999995907,"memoryBytes":71434240}}]}],"decision":"NO-GO","decisionReasons":["public-macos-ax did not complete the required corpus (22 cells missing).","public-macos-ax warm/list did not produce 20 readable samples.","public-macos-ax warm acquisition missed the 75/150 ms target.","private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable.","private-coresimulator-ax did not complete the required corpus (22 cells missing).","private-coresimulator-ax warm/quiet did not produce 20 readable samples.","private-coresimulator-ax warm/quiet has unreadable or empty first-tree evidence.","private-coresimulator-ax warm/list did not produce 20 readable samples.","private-coresimulator-ax warm/list has unreadable or empty first-tree evidence.","The private CoreSimulator AX mechanism has no configured tool on this host."],"nextInterface":"Keep any future bridge behind the #2190 acquisition adapter and preserve raw facts until a separate GO evidence run proves fidelity, lifecycle, and latency."} diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..0f271a18ae07c94a02f9cfc9fec5b6b570dbf037 GIT binary patch literal 14403 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 literal 0 HcmV?d00001 diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index bad36965c6..dae8dc9467 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -2,10 +2,11 @@ - Decision: **NO-GO** - Status: **completed** -- Revision: 6d561b372088b7d13a908565f0255a6d77ff87ce (takeover/2209-valid-evidence) +- Revision: 4d87bc9c3e9926afc98b89f3c314dfd9291dcded (takeover/2209-valid-evidence) - Target: AgentDevice-2209-Takeover (F578F08D-BEA1-4A56-8A4B-C92B040FBA94, com.apple.CoreSimulator.SimRuntime.iOS-26-2) -- Generated: 2026-09-01T12:14:03.698Z +- Generated: 2026-09-01T13:02:31.084Z - Corpus: states=warm, screens=quiet, list, samples=20 +- Corpus coverage: **decisive-early-stop** ## Environment and limits @@ -22,28 +23,30 @@ Target: arm64-apple-macosx26.0 | Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation | |---|---|---|---|---|---| -| public-macos-ax | public macOS ApplicationServices AX | observed in successful cells | not exercised | framed protocol | exact Simulator content surface, but complex trees exceed the latency budget | -| private-coresimulator-ax | external/private CoreSimulator AX tool | failed in cells | not exercised | framed protocol contract only | private interface/tool compatibility | +| public-macos-ax | public macOS ApplicationServices AX | observed in successful cells | not exercised | framed protocol | list evidence is substantially flatter and has different identifier coverage (depth 1 vs 4; identifiers 42 vs 11) | +| private-coresimulator-ax | external/private CoreSimulator AX tool | unsupported before corpus | unsupported before corpus | framed protocol contract only | private interface/tool compatibility | | xctest-control | #2189 XCTest runner control | observed in successful cells | not exercised | existing runner lifecycle | control, not a host-side AX bridge | ## Raw acquisition and prototype presentation results | Candidate | State | Screen | N | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures | |---|---|---|---:|---:|---:|---:|---:|---:| -| public-macos-ax | warm | quiet | 20 | 42.9/123.1 | 34430.6/34510.8 | 0.0/0.2 | 4.0 | 0 | -| public-macos-ax | warm | list | 20 | 5002.8/5002.8 | 31035.4/31035.4 | 0.0/1.6 | 114.0 | 16 | -| private-coresimulator-ax | warm | quiet | 20 | 0.1/0.1 | 31115.5/31115.5 | 0.0/0.0 | – | 20 | -| private-coresimulator-ax | warm | list | 20 | 0.0/0.0 | 30479.5/30479.5 | 0.0/0.0 | – | 20 | -| xctest-control | warm | quiet | 20 | 450.3/958.9 | 26852.6/27361.2 | 0.0/0.0 | 4.0 | 0 | -| xctest-control | warm | list | 20 | 569.2/828.8 | 36422.0/36681.6 | 0.0/0.5 | 31.0 | 0 | +| public-macos-ax | warm | quiet | 20 | 42.3/636.1 | 42.3/636.1 | 0.0/1.0 | 4.0 | 1 | +| public-macos-ax | warm | list | 20 | 1255.9/1667.8 | 1255.9/1667.8 | 1.2/3.2 | 114.0 | 0 | +| xctest-control | warm | quiet | 20 | 243.9/289.8 | 243.9/289.8 | 0.0/0.1 | 4.0 | 0 | +| xctest-control | warm | list | 20 | 460.2/659.3 | 460.2/659.3 | 0.3/0.9 | 33.0 | 0 | + +Raw exemplar fidelity (public AX vs XCTest control): +- quiet: nodes 4/4; depth 1/2; identifiers 0/1. +- list: nodes 114/33; depth 1/4; identifiers 42/11. Every acquisition sample retains timing, resource, readiness, and failure evidence; the first successful sample in each cell also retains one raw node-tree exemplar with viewport, target generation, truncation, and residue. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction. ## Direct protocol probes -- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=114, duration=2907.0 ms, CPU=33.4 ms, memory=11632640 B, response=28586 B +- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=1, duration=2130.8 ms, CPU=4.9 ms, memory=11452416 B, response=697 B - private-coresimulator-ax/protocol-probe:private-coresimulator-ax: ok=false, failure=unsupported-mechanism, code=private-tool-unavailable, nodes=0, duration=0.0 ms, CPU=– ms, memory=– B, response=0 B -- stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=quiet +- stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=unprepared-surface - stderr private-coresimulator-ax/protocol-probe:private-coresimulator-ax: empty ## Independent positive-control evidence @@ -53,10 +56,15 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden ## Preference experiment -- Applied: **false** -- Restored: **not required** -- Simulator state before experiment: Booted -- No private/preboot preference keys were applied in this run. +- Applied: **true** +- Restored: **true** +- Fixture launch compatible: **true** +- Simulator state before experiment: Shutdown +- Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored. +- /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=0c85a9ace2ad2c1be37a09a2ceea94fb786d4e163b4c181307bc991038a3b514, afterSha256=a8ce319124a251110662695c55dde033c6bc767b428a9996352bf6c5e572e97b + - Changes: AccessibilityEnabled: false -> true; ApplicationAccessibilityEnabled: 0 -> true; AutomationEnabled: 0 -> true; IgnoreAXServerEntitlements: undefined -> true +- /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.UIAutomation.plist: existed=true, beforeSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c, afterSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c + - Changes: none ## Lifecycle, cancellation, and recovery @@ -68,16 +76,11 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden ## Decision rationale -- public-macos-ax did not complete the required corpus (22 cells missing). -- public-macos-ax warm/list did not produce 20 readable samples. +- public-macos-ax warm/quiet did not produce 20 readable samples. +- public-macos-ax warm/quiet has unreadable or empty first-tree evidence. - public-macos-ax warm acquisition missed the 75/150 ms target. +- The public macOS AX mechanism was unsupported or unreadable on the host Simulator surface. - private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable. -- private-coresimulator-ax did not complete the required corpus (22 cells missing). -- private-coresimulator-ax warm/quiet did not produce 20 readable samples. -- private-coresimulator-ax warm/quiet has unreadable or empty first-tree evidence. -- private-coresimulator-ax warm/list did not produce 20 readable samples. -- private-coresimulator-ax warm/list has unreadable or empty first-tree evidence. -- The private CoreSimulator AX mechanism has no configured tool on this host. ## Next interface boundary diff --git a/scripts/ios-ax-bridge-spike/README.md b/scripts/ios-ax-bridge-spike/README.md index e1efcecab5..7db1f86fe9 100644 --- a/scripts/ios-ax-bridge-spike/README.md +++ b/scripts/ios-ax-bridge-spike/README.md @@ -21,11 +21,11 @@ pnpm bench:ios-ax-bridge -- \ --screen quiet,list,nested-scroll,alert,system-surface,xctest-stress \ --samples 20 \ --apply-preferences \ - --out .tmp/ios-ax-bridge-spike.v1.json + --out .tmp/ios-ax-bridge-spike.v1.json.gz ``` The default candidate set, state set, screen set, and sample minimums come from the #2189 benchmark definitions. Each request carries a target generation and fixed request, response, node-count, traversal-depth, CPU, memory, and duration bounds. The native helper sends one newline-delimited response per request and writes diagnostics to stderr only. The report keeps raw nodes, viewport evidence, target lineage, truncation, residue, resource metrics, stderr, and a separate prototype presentation measurement. `--apply-preferences` is the only way the experiment edits Simulator preference plists. The Simulator must be shutdown; the harness records exact plist hashes and targeted key changes, then restores the original bytes before reporting. The keys are not production defaults. Omit `--private-tool` unless a disposable, compatible private mechanism is being tested; the harness never invents a private fallback. -The harness fails closed. It reports `NO-GO` when a candidate is unsupported, unavailable, unreadable, stale, over a bound, below the sample minimum, or when crash/timeout/cancellation recovery is not typed and recovered. It stops before reporting timings if the fixture app cannot be prepared deterministically. The adjacent JSON and Markdown report are the decision artifact; no production route should be implemented from a `NO-GO` run. +The harness fails closed. It reports `NO-GO` when a candidate is unsupported, unavailable, unreadable, stale, over a bound, below the sample minimum, or when crash/timeout/cancellation recovery is not typed and recovered. It stops before reporting timings if the fixture app cannot be prepared deterministically. The adjacent gzipped JSON and readable Markdown report are the decision artifact; no production route should be implemented from a `NO-GO` run. diff --git a/scripts/ios-ax-bridge-spike/config.ts b/scripts/ios-ax-bridge-spike/config.ts index ae23392a3f..c7cceaeeb5 100644 --- a/scripts/ios-ax-bridge-spike/config.ts +++ b/scripts/ios-ax-bridge-spike/config.ts @@ -74,7 +74,7 @@ export function parseConfig(argv: readonly string[]): SpikeConfig { derivedPath, outputPath: resolvePath( parsed.values.get('--out'), - path.join(stateDir, 'ios-simulator-ax-bridge-spike.v1.json'), + path.join(stateDir, 'ios-simulator-ax-bridge-spike.v1.json.gz'), ), screens, states, diff --git a/scripts/ios-ax-bridge-spike/decision.test.ts b/scripts/ios-ax-bridge-spike/decision.test.ts index 7152b0fbea..7e8ce2b0ea 100644 --- a/scripts/ios-ax-bridge-spike/decision.test.ts +++ b/scripts/ios-ax-bridge-spike/decision.test.ts @@ -14,8 +14,9 @@ const lifecycle: LifecycleEvidence = { }; const preferences: PreferenceEvidence = { - applied: false, + applied: true, restored: true, + fixtureLaunchCompatible: true, simulatorStateBefore: 'Shutdown', diffs: [], }; @@ -28,7 +29,50 @@ test('fails closed when a bridge has no readable corpus cells', () => { }, ]); assert.equal(result.decision, 'NO-GO'); - assert.ok(result.reasons.some((reason) => reason.includes('public-macos-ax produced no cells'))); + assert.ok(result.reasons.some((reason) => reason.includes('unsupported-mechanism/permission'))); +}); + +test('does not let failed samples contribute fabricated zero latency', () => { + const cell = readableCell('public-macos-ax', 'warm', 'list'); + const failed = { + ...cell.acquisitionSamples[0]!, + ok: false, + firstTree: 'not-observed' as const, + firstLookMs: 0, + metrics: { ...cell.acquisitionSamples[0]!.metrics!, durationMs: 0 }, + failure: { kind: 'timeout' as const, code: 'batch-duration-limit' }, + }; + const result = decideSpike( + [{ ...cell, acquisitionSamples: [failed, ...cell.acquisitionSamples.slice(1)] }], + lifecycle, + preferences, + DEFAULT_SPIKE_LIMITS, + 'completed', + [{ candidate: 'public-macos-ax' }], + ); + assert.equal(result.decision, 'NO-GO'); + assert.ok(result.reasons.some((reason) => reason.includes('duration bound'))); + assert.ok(result.reasons.some((reason) => reason.includes('not produce 20 readable samples'))); +}); + +test('reports a decisive partial corpus failure instead of replacing it with completeness', () => { + const cell = readableCell('public-macos-ax', 'warm', 'list'); + const slow = { + ...cell, + acquisitionSamples: cell.acquisitionSamples.map((sample) => ({ + ...sample, + metrics: { ...sample.metrics!, durationMs: 1_000 }, + })), + }; + const result = decideSpike([slow], lifecycle, preferences, DEFAULT_SPIKE_LIMITS, 'completed', [ + { candidate: 'public-macos-ax' }, + ]); + assert.equal(result.decision, 'NO-GO'); + assert.ok(result.reasons.some((reason) => reason.includes('warm acquisition'))); + assert.equal( + result.reasons.some((reason) => reason.includes('required corpus')), + false, + ); }); test('selects one complete viable bridge without requiring every candidate to pass', () => { diff --git a/scripts/ios-ax-bridge-spike/decision.ts b/scripts/ios-ax-bridge-spike/decision.ts index b745283c53..f9b76ed286 100644 --- a/scripts/ios-ax-bridge-spike/decision.ts +++ b/scripts/ios-ax-bridge-spike/decision.ts @@ -5,6 +5,7 @@ import type { ResourceLimits, SpikeCell, } from './types.ts'; +import { LOCAL_STATES, SCREEN_FIXTURES } from '../ios-snapshot-benchmark/definitions.ts'; export function decideSpike( cells: readonly SpikeCell[], @@ -35,9 +36,13 @@ function statusReasons(status: 'completed' | 'stopped'): string[] { } function preferenceReasons(preferences: PreferenceEvidence): string[] { - return preferences.applied && !preferences.restored - ? ['The task-owned Simulator preference experiment was not restored.'] - : []; + if (!preferences.applied) + return ['The required task-owned Simulator preference experiment was not run.']; + if (!preferences.restored) + return ['The task-owned Simulator preference experiment was not restored.']; + if (preferences.fixtureLaunchCompatible === false) + return ['The task-owned Simulator preference experiment prevented the fixture from launching.']; + return []; } function bridgeRouteReasons( @@ -50,14 +55,17 @@ function bridgeRouteReasons( const candidateCells = cells.filter((cell) => cell.candidate === candidate); const candidateProbes = probes.filter((probe) => probe.candidate === candidate); if (candidateCells.length === 0 && candidateProbes.length === 0) return []; + const coreReasons = [ + ...probeReasons(candidateProbes), + ...candidateDecisionReasons(candidateCells, limits), + ]; return [ { candidate, - reasons: [ - ...probeReasons(candidateProbes), - ...candidateCompletenessReasons(candidate, candidateCells), - ...candidateDecisionReasons(candidateCells, limits), - ], + reasons: + coreReasons.length > 0 + ? coreReasons + : candidateCompletenessReasons(candidate, candidateCells), }, ]; }, @@ -79,15 +87,8 @@ function probeReasons( ); } -const REQUIRED_STATES = ['cold-cold', 'cold', 'warm', 'relaunch'] as const; -const REQUIRED_SCREENS = [ - 'quiet', - 'list', - 'nested-scroll', - 'alert', - 'system-surface', - 'xctest-stress', -] as const; +const REQUIRED_STATES = LOCAL_STATES; +const REQUIRED_SCREENS = SCREEN_FIXTURES.map((fixture) => fixture.id); function candidateCompletenessReasons( candidate: Exclude, @@ -141,7 +142,9 @@ function sampleShapeReasons(cell: SpikeCell): string[] { `${cell.candidate} ${cell.state}/${cell.screen} did not produce ${cell.sampleMinimum} readable samples.`, ); } - if (samples.some((sample) => ['unreadable', 'empty'].includes(sample.firstTree))) { + if ( + samples.some((sample) => ['unreadable', 'empty', 'not-observed'].includes(sample.firstTree)) + ) { reasons.push( `${cell.candidate} ${cell.state}/${cell.screen} has unreadable or empty first-tree evidence.`, ); @@ -173,6 +176,14 @@ function resourceReasons(cell: SpikeCell, limits: ResourceLimits): string[] { ], ] as const; const reasons: string[] = []; + if ( + cell.acquisitionSamples.some( + (sample) => + sample.failure?.kind === 'timeout' || sample.failure?.code === 'batch-duration-limit', + ) + ) { + reasons.push(`${cell.candidate} ${cell.state}/${cell.screen} exceeded the duration bound.`); + } for (const [label, limit, readValue] of checks) { if (cell.acquisitionSamples.some((sample) => exceedsLimit(readValue(sample), limit))) { reasons.push(`${cell.candidate} ${cell.state}/${cell.screen} exceeded the ${label} bound.`); @@ -182,7 +193,10 @@ function resourceReasons(cell: SpikeCell, limits: ResourceLimits): string[] { } function latencyReasons(cell: SpikeCell): string[] { - const firstLook = finite(cell.acquisitionSamples.map((sample) => sample.firstLookMs)); + const successful = cell.acquisitionSamples.filter( + (sample) => sample.ok && sample.firstTree === 'readable', + ); + const firstLook = finite(successful.map((sample) => sample.firstLookMs)); const firstLookTarget = { 'cold-cold': { limit: 5_000, label: 'cold-cold first look missed the 5 second target.' }, cold: { limit: 1_500, label: 'cold prepared first look missed the 1.5 second target.' }, @@ -193,7 +207,7 @@ function latencyReasons(cell: SpikeCell): string[] { if (firstLookTarget && percentile(firstLook, 95) >= firstLookTarget.limit) { reasons.push(`${cell.candidate} ${firstLookTarget.label}`); } - const acquisition = finite(cell.acquisitionSamples.map((sample) => sample.metrics?.durationMs)); + const acquisition = finite(successful.map((sample) => sample.metrics?.durationMs)); if ( cell.state === 'warm' && (percentile(acquisition, 50) >= 75 || percentile(acquisition, 95) >= 150) diff --git a/scripts/ios-ax-bridge-spike/framed-process.test.ts b/scripts/ios-ax-bridge-spike/framed-process.test.ts index 60e775fc1d..52dcf77f1b 100644 --- a/scripts/ios-ax-bridge-spike/framed-process.test.ts +++ b/scripts/ios-ax-bridge-spike/framed-process.test.ts @@ -17,7 +17,7 @@ function request(id: string): SpikeRequest { }; } -function childScript(mode: 'healthy' | 'malformed' | 'crash' | 'hang'): { +function childScript(mode: 'healthy' | 'delayed' | 'malformed' | 'crash' | 'hang'): { file: string; args: string[]; } { @@ -53,9 +53,10 @@ function childScript(mode: 'healthy' | 'malformed' | 'crash' | 'hang'): { let input = ''; process.stdin.setEncoding('utf8'); process.stdin.on('data', (chunk) => { input += chunk; }); - process.stdin.on('end', () => { + process.stdin.on('end', async () => { for (const line of input.split('\\n').filter(Boolean)) { const request = JSON.parse(line); + if (${JSON.stringify(mode)} === 'delayed') await new Promise((resolve) => setTimeout(resolve, 100)); process.stdout.write(JSON.stringify({ ...${response}, id: request.id, candidate: request.candidate }) + '\\n'); } }); @@ -76,6 +77,18 @@ test('uses one framed response per request and keeps diagnostics on stderr', asy ); }); +test('budgets a framed batch per request rather than timing the whole batch as one request', async () => { + const result = await runFramedBatch( + childScript('delayed'), + [request('one'), request('two'), request('three')], + { limits: { ...DEFAULT_SPIKE_LIMITS, maxDurationMs: 200 } }, + ); + assert.equal( + result.responses.every((response) => response.ok), + true, + ); +}); + test('classifies malformed trees, crashes, timeouts, and cancellation', async () => { const malformed = await runFramedBatch(childScript('malformed'), [request('malformed')]); assert.equal(malformed.responses[0]?.failure?.kind, 'malformed-tree'); diff --git a/scripts/ios-ax-bridge-spike/framed-process.ts b/scripts/ios-ax-bridge-spike/framed-process.ts index 64a544db8e..9f5c3709ad 100644 --- a/scripts/ios-ax-bridge-spike/framed-process.ts +++ b/scripts/ios-ax-bridge-spike/framed-process.ts @@ -57,7 +57,8 @@ export async function runFramedBatch( let stdoutBytes = 0; let stderr = ''; let settled = false; - const timer = setTimeout(() => finish('timeout', 'batch-duration-limit'), limits.maxDurationMs); + const batchDurationMs = limits.maxDurationMs * requests.length; + const timer = setTimeout(() => finish('timeout', 'batch-duration-limit'), batchDurationMs); const finish = (kind?: SpikeFailureKind, code?: string): void => { if (settled) return; @@ -75,6 +76,7 @@ export async function runFramedBatch( { requestBytes: requestBytesFor(request, encodedRequests), responseBytes: stdoutBytes, + durationMs: batchDurationMs, }, ), ); diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts index 4c00f54323..10389aaaa4 100644 --- a/scripts/ios-ax-bridge-spike/report.ts +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -1,14 +1,20 @@ import fs from 'node:fs'; import path from 'node:path'; +import { gzipSync } from 'node:zlib'; import type { SpikeCell, SpikeReport, SpikeSample } from './types.ts'; export function writeSpikeReport(outputPath: string, report: SpikeReport): void { + const compact = compactReportEvidence(report); fs.mkdirSync(path.dirname(outputPath), { recursive: true }); - fs.writeFileSync(outputPath, `${JSON.stringify(report)}\n`); - fs.writeFileSync(outputPath.replace(/\.json$/u, '.md'), renderSpikeMarkdown(report)); + fs.writeFileSync(outputPath, gzipSync(`${JSON.stringify(compact)}\n`, { level: 9 })); + fs.writeFileSync(markdownPath(outputPath), renderSpikeMarkdown(compact)); } -function renderSpikeMarkdown(report: SpikeReport): string { +export function markdownPath(outputPath: string): string { + return outputPath.replace(/\.json(?:\.gz)?$/u, '.md'); +} + +export function renderSpikeMarkdown(report: SpikeReport): string { const lines = [ '# iOS Simulator AX bridge spike', '', @@ -18,6 +24,7 @@ function renderSpikeMarkdown(report: SpikeReport): string { `- Target: ${report.target.name} (${report.target.udid}, ${report.target.runtime})`, `- Generated: ${report.generatedAt}`, `- Corpus: states=${report.config.states.join(', ')}, screens=${report.config.screens.join(', ')}, samples=${report.config.requestedSamples}`, + `- Corpus coverage: **${report.corpusCoverage}**`, '', '## Environment and limits', '', @@ -27,7 +34,7 @@ function renderSpikeMarkdown(report: SpikeReport): string { '', '| Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation |', '|---|---|---|---|---|---|', - `| public-macos-ax | public macOS ApplicationServices AX | ${surfaceStatus(report, 'public-macos-ax', 'app')} | ${surfaceStatus(report, 'public-macos-ax', 'system')} | framed protocol | exact Simulator content surface, but complex trees exceed the latency budget |`, + `| public-macos-ax | public macOS ApplicationServices AX | ${surfaceStatus(report, 'public-macos-ax', 'app')} | ${surfaceStatus(report, 'public-macos-ax', 'system')} | framed protocol | ${publicAxLimitation(report)} |`, `| private-coresimulator-ax | external/private CoreSimulator AX tool | ${surfaceStatus(report, 'private-coresimulator-ax', 'app')} | ${surfaceStatus(report, 'private-coresimulator-ax', 'system')} | framed protocol contract only | private interface/tool compatibility |`, `| xctest-control | #2189 XCTest runner control | ${surfaceStatus(report, 'xctest-control', 'app')} | ${surfaceStatus(report, 'xctest-control', 'system')} | existing runner lifecycle | control, not a host-side AX bridge |`, '', @@ -37,6 +44,8 @@ function renderSpikeMarkdown(report: SpikeReport): string { '|---|---|---|---:|---:|---:|---:|---:|---:|', ...report.cells.map(renderCellRow), '', + ...fidelityLines(report), + '', 'Every acquisition sample retains timing, resource, readiness, and failure evidence; the first successful sample in each cell also retains one raw node-tree exemplar with viewport, target generation, truncation, and residue. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction.', '', '## Direct protocol probes', @@ -52,6 +61,7 @@ function renderSpikeMarkdown(report: SpikeReport): string { '', `- Applied: **${report.preferenceEvidence.applied}**`, `- Restored: **${report.preferenceEvidence.applied ? report.preferenceEvidence.restored : 'not required'}**`, + `- Fixture launch compatible: **${report.preferenceEvidence.fixtureLaunchCompatible ?? 'not exercised'}**`, `- Simulator state before experiment: ${report.preferenceEvidence.simulatorStateBefore}`, preferenceExperimentLine(report), ...preferenceLines(report), @@ -134,7 +144,10 @@ function renderCellRow(cell: SpikeCell): string { const nodeCounts = readable.flatMap((sample) => typeof sample.metrics?.nodeCount === 'number' ? [sample.metrics.nodeCount] : [], ); - return `| ${cell.candidate} | ${cell.state} | ${cell.screen} | ${acquisition.length} | ${summary(acquisition, 'wallClockMs')} | ${summary(acquisition, 'firstLookMs')} | ${summary(presentation, 'wallClockMs')} | ${formatNumber(median(nodeCounts))} | ${failures} |`; + return `| ${cell.candidate} | ${cell.state} | ${cell.screen} | ${acquisition.length} | ${summary(readable, 'wallClockMs')} | ${summary(readable, 'firstLookMs')} | ${summary( + presentation.filter((sample) => sample.ok), + 'wallClockMs', + )} | ${formatNumber(median(nodeCounts))} | ${failures} |`; } function surfaceStatus( @@ -151,6 +164,8 @@ function surfaceStatus( return 'observed in successful cells'; } if (cells.length > 0) return 'failed in cells'; + const probe = report.protocolProbes.find((item) => item.candidate === candidate); + if (probe?.failure?.kind === 'unsupported-mechanism') return 'unsupported before corpus'; if (report.candidates.includes(candidate)) return 'not exercised'; return 'not selected'; } @@ -163,9 +178,74 @@ function preferenceLines(report: SpikeReport): string[] { } function preferenceExperimentLine(report: SpikeReport): string { - return report.preferenceEvidence.applied + return report.preferenceEvidence.applied && report.preferenceEvidence.restored ? '- Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored.' - : '- No private/preboot preference keys were applied in this run.'; + : report.preferenceEvidence.applied + ? '- Private/preboot preference keys were applied, but restoration was not proven.' + : '- No private/preboot preference keys were applied in this run.'; +} + +function publicAxLimitation(report: SpikeReport): string { + const publicList = exemplar(report, 'public-macos-ax', 'list'); + const controlList = exemplar(report, 'xctest-control', 'list'); + if (!publicList || !controlList) return 'fidelity and latency remain unproven'; + const publicDepth = treeDepth(publicList); + const controlDepth = treeDepth(controlList); + const publicIdentifiers = publicList.filter((node) => node.identifier).length; + const controlIdentifiers = controlList.filter((node) => node.identifier).length; + return `list evidence is substantially flatter and has different identifier coverage (depth ${publicDepth} vs ${controlDepth}; identifiers ${publicIdentifiers} vs ${controlIdentifiers})`; +} + +function compactReportEvidence(report: SpikeReport): SpikeReport { + return { + ...report, + cells: report.cells.map((cell) => ({ + ...cell, + acquisitionSamples: cell.acquisitionSamples.map((sample, index) => + index === 0 || sample.stderr === undefined ? sample : withoutStderr(sample), + ), + presentationSamples: cell.presentationSamples.map((sample) => withoutStderr(sample)), + })), + }; +} + +function withoutStderr(sample: SpikeSample): SpikeSample { + const { stderr: _stderr, ...rest } = sample; + return rest; +} + +function fidelityLines(report: SpikeReport): string[] { + const lines = ['Raw exemplar fidelity (public AX vs XCTest control):']; + for (const screen of report.config.screens) { + const publicNodes = exemplar(report, 'public-macos-ax', screen); + const controlNodes = exemplar(report, 'xctest-control', screen); + if (!publicNodes || !controlNodes) continue; + lines.push( + `- ${screen}: nodes ${publicNodes.length}/${controlNodes.length}; depth ${treeDepth(publicNodes)}/${treeDepth(controlNodes)}; identifiers ${publicNodes.filter((node) => node.identifier).length}/${controlNodes.filter((node) => node.identifier).length}.`, + ); + } + return lines.length === 1 ? ['Raw exemplar fidelity comparison was not available.'] : lines; +} + +function exemplar( + report: SpikeReport, + candidate: SpikeCell['candidate'], + screen: SpikeCell['screen'], +): NonNullable['nodes'] | undefined { + return report.cells + .find((cell) => cell.candidate === candidate && cell.screen === screen) + ?.acquisitionSamples.find((sample) => sample.acquisition)?.acquisition?.nodes; +} + +function treeDepth(nodes: NonNullable['nodes']): number { + const depthById = new Map(); + let maximum = 0; + for (const node of nodes) { + const depth = node.parentId ? (depthById.get(node.parentId) ?? 0) + 1 : 0; + depthById.set(node.id, depth); + maximum = Math.max(maximum, depth); + } + return maximum; } function summary(samples: readonly SpikeSample[], key: 'wallClockMs' | 'firstLookMs'): string { diff --git a/scripts/ios-ax-bridge-spike/run.ts b/scripts/ios-ax-bridge-spike/run.ts index c141598d40..9a8ca1b6f9 100644 --- a/scripts/ios-ax-bridge-spike/run.ts +++ b/scripts/ios-ax-bridge-spike/run.ts @@ -11,16 +11,16 @@ import { decideSpike } from './decision.ts'; import { runLifecycleProbes } from './lifecycle.ts'; import { applyPrebootPreferences, - type PlistSnapshot, readSimulatorState, restorePrebootPreferences, } from './preferences.ts'; -import { writeSpikeReport } from './report.ts'; +import { markdownPath, writeSpikeReport } from './report.ts'; import { createAdapterOptions, runSpikeCells } from './runner.ts'; import { readGitRevision, readTarget, readToolchain } from '../ios-snapshot-benchmark/host.ts'; import { runDeepButtonControls } from '../ios-snapshot-benchmark/deep-control.ts'; import { deepButtonFixtureEvidence } from '../ios-snapshot-benchmark/deep-button.ts'; import { bootSimulator, shutdownSimulator } from '../ios-snapshot-benchmark/lifecycle.ts'; +import { screenFixture } from '../ios-snapshot-benchmark/definitions.ts'; import type { AcquisitionAdapter } from './adapter.ts'; import { SPIKE_ISSUE, SPIKE_PARENT, SPIKE_PREREQUISITES, SPIKE_SCHEMA_VERSION } from './types.ts'; import type { @@ -58,7 +58,7 @@ async function main(argv: readonly string[]): Promise { const report = createReport(runConfig, metadata, lifecycle, evidence, decision); writeSpikeReport(config.outputPath, report); process.stdout.write( - `Decision: ${report.decision}\nRaw: ${config.outputPath}\nMarkdown: ${config.outputPath.replace(/\.json$/u, '.md')}\n`, + `Decision: ${report.decision}\nRaw: ${config.outputPath}\nMarkdown: ${markdownPath(config.outputPath)}\n`, ); if (evidence.status === 'stopped') process.exitCode = 2; } @@ -74,26 +74,13 @@ type SpikeRunEvidence = Readonly<{ }>; async function executeSpikeRun(config: SpikeConfig): Promise { - const collected = await collectSpikeEvidence(config); - const cleanup = cleanupPreferences( - config, - collected.preferenceEvidence, - collected.preferenceSnapshots, - ); - return { - ...collected, - preferenceEvidence: cleanup.evidence, - ...(cleanup.stop ? { status: 'stopped' as const, stop: cleanup.stop } : {}), - }; + return collectSpikeEvidence(config); } -type CollectedSpikeEvidence = SpikeRunEvidence & { - preferenceSnapshots: readonly PlistSnapshot[]; -}; +type CollectedSpikeEvidence = SpikeRunEvidence; async function collectSpikeEvidence(config: SpikeConfig): Promise { let preferenceEvidence = initialPreferenceEvidence(config.udid); - let preferenceSnapshots: readonly PlistSnapshot[] = []; let cells: Awaited> = []; let protocolProbes: SpikeResponse[] = []; let protocolProbeLogs: SpikeReport['protocolProbeLogs'] = []; @@ -102,19 +89,19 @@ async function collectSpikeEvidence(config: SpikeConfig): Promise screenFixture(screen).app)); + for (const app of apps) { + if (!tryPrimeFixtureApp(config.udid, app)) + throw new Error(`Failed to prime ${app} after booting the restored disposable Simulator.`); } - shutdownSimulator(config.udid); - return applyPrebootPreferences(config.udid); } -function cleanupPreferences( - config: SpikeConfig, - evidence: PreferenceEvidence, - snapshots: readonly PlistSnapshot[], -): { evidence: PreferenceEvidence; stop?: SpikeReport['stop'] } { +function runPreferenceExperiment(config: SpikeConfig): PreferenceEvidence { if (!config.applyPreferences) { - if (!config.keepDevice) shutdownSimulator(config.udid); - return { evidence }; + return initialPreferenceEvidence(config.udid); } + shutdownSimulator(config.udid); + const applied = applyPrebootPreferences(config.udid); + let fixtureLaunchCompatible = false; + let restored = false; try { + bootSimulator(config.udid); + fixtureLaunchCompatible = tryPrimeFixtureApp( + config.udid, + screenFixture(config.screens[0]!).app, + ); shutdownSimulator(config.udid); - return { - evidence: { ...evidence, restored: restorePrebootPreferences(config.udid, snapshots) }, - }; - } catch (error) { - return { evidence, stop: stopForError(error) }; + } finally { + try { + if (readSimulatorState(config.udid) !== 'Shutdown') shutdownSimulator(config.udid); + } finally { + restored = restorePrebootPreferences(config.udid, applied.snapshots); + } + } + return { + ...applied.evidence, + fixtureLaunchCompatible, + restored, + }; +} + +function tryPrimeFixtureApp(udid: string, app: string): boolean { + try { + execFileSync('xcrun', ['simctl', 'launch', udid, app], { + encoding: 'utf8', + timeout: 60_000, + stdio: ['ignore', 'pipe', 'pipe'], + }); + return true; + } catch { + return false; } } @@ -194,6 +200,7 @@ function createReport( lifecycle, positiveControl: evidence.positiveControl, status: evidence.status, + corpusCoverage: corpusCoverage(config), cells: evidence.cells, decision: decision.decision, decisionReasons: decision.reasons, @@ -253,7 +260,7 @@ function protocolProbeRequest( candidate, simulatorUdid: config.udid, state: 'warm', - screen: 'quiet', + screen: 'unprepared-surface', appBundleId: config.appBundleId, ...(config.targetWindowName === undefined ? {} : { targetWindowName: config.targetWindowName }), ...(config.targetProcessId === undefined ? {} : { targetProcessId: config.targetProcessId }), @@ -282,12 +289,42 @@ function initialPreferenceEvidence(udid: string): PreferenceEvidence { } return { applied: false, - restored: true, + restored: false, + fixtureLaunchCompatible: null, simulatorStateBefore, diffs: [], }; } +function supportedAdapters( + adapters: readonly AcquisitionAdapter[], + probes: readonly SpikeResponse[], +): readonly AcquisitionAdapter[] { + return adapters.filter((adapter) => { + if (adapter.candidate === 'xctest-control') return true; + const probe = probes.find((candidate) => candidate.candidate === adapter.candidate); + return probe?.failure?.kind !== 'unsupported-mechanism'; + }); +} + +function corpusCoverage(config: SpikeConfig): SpikeReport['corpusCoverage'] { + const fullStates = ['cold-cold', 'cold', 'warm', 'relaunch']; + const fullScreens = [ + 'quiet', + 'list', + 'nested-scroll', + 'alert', + 'system-surface', + 'xctest-stress', + ]; + return fullStates.every((state) => + config.states.includes(state as SpikeConfig['states'][number]), + ) && + fullScreens.every((screen) => config.screens.includes(screen as SpikeConfig['screens'][number])) + ? 'full' + : 'decisive-early-stop'; +} + function commandText(command: string, args: readonly string[]): string { try { return execFileSync(command, [...args], { diff --git a/scripts/ios-ax-bridge-spike/runner.ts b/scripts/ios-ax-bridge-spike/runner.ts index 60cb228f81..a0fff2d788 100644 --- a/scripts/ios-ax-bridge-spike/runner.ts +++ b/scripts/ios-ax-bridge-spike/runner.ts @@ -106,9 +106,7 @@ async function collectWarmSamples( acquisitionSamples: SpikeSample[], presentationSamples: SpikeSample[], ): Promise { - const preparationStarted = performance.now(); admitReadyCell(context, admission); - const preparationMs = performance.now() - preparationStarted; const requests = Array.from({ length: config.samples }, (_, index) => makeRequest(config, adapter.candidate, admission.state, admission.fixture.id, index), ); @@ -120,7 +118,7 @@ async function collectWarmSamples( admission.fixture.id, index, item, - preparationMs, + 0, acquisitionSamples, presentationSamples, ), @@ -138,7 +136,7 @@ async function collectNonWarmSamples( let appPid: number | undefined; for (let index = 0; index < config.samples; index += 1) { if (index > 0) prepareSampleState(admission); - const preparationStarted = performance.now(); + const launchStarted = performance.now(); const opened = openFixture(context, admission.fixture, { relaunch: true }); if (!opened.ok) { throw preparationError( @@ -148,8 +146,8 @@ async function collectNonWarmSamples( openArguments(admission.fixture), ); } + const preparationMs = performance.now() - launchStarted; appPid = admitSuccessfulSample(context, admission, opened, appPid); - const preparationMs = performance.now() - preparationStarted; const request = makeRequest( config, adapter.candidate, diff --git a/scripts/ios-ax-bridge-spike/types.ts b/scripts/ios-ax-bridge-spike/types.ts index 1efee4206c..fe98e3ba62 100644 --- a/scripts/ios-ax-bridge-spike/types.ts +++ b/scripts/ios-ax-bridge-spike/types.ts @@ -84,7 +84,7 @@ export type SpikeRequest = Readonly<{ candidate: CandidateId; simulatorUdid: string; state: LocalState; - screen: ScreenId; + screen: ScreenId | 'unprepared-surface'; appBundleId: string; targetWindowName?: string; targetProcessId?: number; @@ -179,6 +179,7 @@ export type PlistDiff = Readonly<{ export type PreferenceEvidence = Readonly<{ applied: boolean; restored: boolean; + fixtureLaunchCompatible: boolean | null; simulatorStateBefore: string; diffs: readonly PlistDiff[]; }>; @@ -202,6 +203,7 @@ export type SpikeReport = Readonly<{ target: Target; limits: ResourceLimits; status: 'completed' | 'stopped'; + corpusCoverage: 'full' | 'decisive-early-stop'; candidates: readonly CandidateId[]; config: Readonly<{ states: readonly LocalState[]; diff --git a/scripts/ios-snapshot-benchmark/definitions.ts b/scripts/ios-snapshot-benchmark/definitions.ts index 4a9fe3552c..c1857246a4 100644 --- a/scripts/ios-snapshot-benchmark/definitions.ts +++ b/scripts/ios-snapshot-benchmark/definitions.ts @@ -15,7 +15,7 @@ const FIXTURE_APP_ID = 'com.callstack.agentdevicelab'; const FIXTURE_SCHEME = 'agent-device-test-app://'; const IOS_SETTINGS_APP_ID = 'com.apple.Preferences'; -const SCREEN_FIXTURES: readonly ScreenFixture[] = [ +export const SCREEN_FIXTURES: readonly ScreenFixture[] = [ { id: 'quiet', label: 'Quiet inert surface', @@ -61,6 +61,8 @@ const SCREEN_FIXTURES: readonly ScreenFixture[] = [ }, ]; +export const LOCAL_STATES: readonly LocalState[] = ['cold-cold', 'cold', 'warm', 'relaunch']; + export function screenFixture(id: ScreenId): ScreenFixture { const fixture = SCREEN_FIXTURES.find((candidate) => candidate.id === id); if (!fixture) throw new Error(`Unknown screen fixture: ${id}`); @@ -84,7 +86,7 @@ export function parseLocalStates(value: string | undefined): LocalState[] { .split(',') .map((item) => item.trim()) .filter(Boolean) as LocalState[]; - const valid = new Set(['cold-cold', 'cold', 'warm', 'relaunch']); + const valid = new Set(LOCAL_STATES); const unknown = states.filter((state) => !valid.has(state)); if (unknown.length > 0) throw new Error(`Unknown --state value: ${unknown.join(', ')}`); if (states.length === 0) throw new Error('--state requires at least one cell.'); From ea944d77029895b05b9bbb2c0eeb232374c7e5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 15:12:01 +0200 Subject: [PATCH 20/29] docs: record clean simulator AX spike run --- ...ios-simulator-ax-bridge-2026-09-01.json.gz | Bin 14403 -> 14254 bytes .../ios-simulator-ax-bridge-2026-09-01.md | 23 ++++++++---------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz index 0f271a18ae07c94a02f9cfc9fec5b6b570dbf037..0cc56ff9e6a6197a37047965bcdd2f6cb8b5ccaf 100644 GIT binary patch literal 14254 zcmZ9zWl$wO*ENj04esvl?(VJ!XK)*w!EJ!S_2BN#z`URyjB~&Bq}>+x%hz`X-AIx|dBiB!tMz6BcPq=zN$MugF%CHc zy-P?bvGwsXDJHplMJv0H$A4s0-_YqIPSh%?j2}ZfC4!(({CRnEd7s=>DIY(`K2URU zY`6*5P-d%ev5))B@Kg1KqeW0MgTj+;~_{3E$s5#1wKbH73BBrN9gHuQ9B|dqs_k8Q~ zeOKgdE-v6>`!T@(c4+m*6!ZP*kmTdu^HO-NYs}@-KL$KdT@l3*Mvtw9D0=rzgFi}@ zP0O9=5X;N?Bd=WPnl5`9von3FRM=bP6A&lHVNU)sR58MtvyNN|tH}C`wwyR{JIluV zMkOHI@As{M@rLw#X*ipo(-Rtv-ZdWAE@Vb=1+>zPSyn7;bI4_K-KO*F`PKR5MvrQj znz!}laC5&W%BIUmx6kX~45`&Mcq1kt!z+? zjp^lFxX5CR?o0nG*$LTfTFJ2l0GqQU{OLCLodwZ2`A2Srdl?Y@rNrN89Hh6MDkAHo z?xgpAS8A^qC+ckU{whH{_ck#1tYgw?JaAxrD`E?lL#qMTLJw^p;fJ2vKb))5yH_V11VLb_aiFKAEMn@au@Ga-gjf<_xpj=Wwgho9XSLd{v;yfrSpGm ztZxMwK$MvuX;y_N`rRnRI+>7bNc3qs4q>jgZmYzf8N#+}FI=y@Eljte-FScHIu#i4 ze6^?ERk~5$7>SkMf6hB5Qbh%S=v^O9m?Y{j94+>Cs$5=-^;TmI|C`v-;HQrMg~byx z6{0`#14bo8AMCB3@HtwSda7jp=5_4y)}D=~L@zpJYL;Z9d(5&p7kK}}xFUjnmd)X( z$a@Firn|Pe)_W+cbXOm7#{-|ma^#%}w=x^L8Y&4tR3l_we{&9Q!D-{cJcZqO9DRj; z@t;V^$DH8Un77LKjWd6g!lyqmjbxvnc5*-dWADV)cm6^nR~42g=f*n}-5`Iu`(4^H63_oCY1DjQ?`!Nsu%2sBgRYu*eso|;4Si}%>Y~u?ZS{Tg_d?;* z`2)-S=;yf^_mmJF^{#2%FpcxhCqKb-#S#2@0-~kTOkNJ3$Tgo0cDKF_ZgV$^?C;`< zoRrss@tcFqQD%s zD)vTlDVaf^S&6!OYN{GM6(9E>!qUaC&5${|Sna&mxN&Sj2{_aT%!7Ylmqtd0b%j!h z8*oRU7~veHBV2nzV+Lfw&!eu3?w(&l*s&=lCWdcDtc!ff@2q#6_edl5p{jWzT+Nby zPH#j|VozpJvPI0Iw+u<5ecu=YwHLoVALUxNBObr5t5a56>w)~a;xm*1CSyAAXGJ?@ zkjC5XU4Ljn;U|#qo6jGPDf=H2#v8A1Gl$)oKpVb$RDW&kkO?0D5>IAxtoPSPCN zg6m=a(jMF(Y7c;H<`H}oWb z(DmvK@&nvicT~lpGZPMS4H`kfY1H4T!E5{1efe_g2-eEz!NtOu%BJ)fxXkYT??M&lZx*OFdN0nL-jOLJG4*QOw?no~pFcRq!u;8<<>Z=-UeJmM zY|*0KV##x!F0tp17ty6R@sz(3Fmk?0lrKVr>lr0KxnpPb*bSroz5yS*LY8bBDr2q| z(MF2%KDj$@q4Rn13BW4V6bGfpzAYuV_KmR7$C4reMleVOPS0hdfA;kr*Ifz4%!F`x_&MzxN%>_3rz3Y575eza9lW2*fIh&cPI-7US0Te6ma?oOnvCb!a-? z;?-W}Nh2mgChUCOBs$W7ma7{^hRWgB#@W>Yf4mZ8u06y;yl3V|6kHWBVt|Cj0d=+MD_nBBOU3bcz^|&@-s@s zMRd{J-pz5_NZt^0so#be3+^&@;wxMJhQj-C%+%hL}DDKB)CnwXjuXHEiYV+s*0D|2iX|+ zs+Nk#-iFR~+fM_jkQxSnx9gkkG;1%gLD_}@8E1_XGARWQWi}sOIxv2o6=>Q^5!6K7 z2tEir0Ju<~H8$9h|0XH99@bbGc;v`Uol$SsFRk(2q)rKDwYljHsKJiUeJP6Q5e`>$ zQndb#1s9IbL`5JNA`jKe3CqxfZ_{f1`)}Yd>a}mq<4PBCgSmoo;I9;S?iU|fl?zd;+xrADqs*n|eBH~o8ju$M)~-?>q> z^jG$P7qqGF+&4NOoe8JAKeVH?kNxa9A_2CaIj&b+e6W2@;(K|j4w54lp0+CSZYGV6 zR7A86fj_8-7(Fjp-h)>%3r_3-ye8SN_%v!A0K~0GwQMgIwMxR-^grlxSE5BPZU3KR1flccZ?AgANS-!}#X()zVKm+D(<_9v|$x0L6 zPC`~91JSr$v;W8qh%O2Lfo3ws<2GLlElVg`51X(Coe$_?p!HeSVsJx`>s1bydVn?M z?K4~^49DM!hT9W8<>yjSCH^X_9wI3?sKMmwZ^2e>?JwhEGA826pBL^8Tcho&ey;s0 zg?ZyQof|Itc63E*FE&;iG~s@p;6!OZI|{~a9l;GX0$f|6ScJ0Qg3%duybIp);~pv5 zA8{7YZVLM5vy2>#_NP;>X0RK47054($xbE7vb@mXYq1o_hvzM8FS4Y)yBVltz+?{* zsBi|kTCrbwnV8iOd!W+j3{w8#BfIcr*rS*k{a6>ZbfJE}{2Kj0msVia^(}{JW%pWvGO|ZV(cnt4(s(3=(7%Up@5I>i&~7r3eJ~_cXME@R)T@U-xO% z&<{o%pZq5LPZ;Y1ezCbM_?Xy*H8LZ+uQvrD14WUKgOSxv9I6APdSDzM_?^FTRlW~;C%)xXiF{c)vDS#coDG|1hjpM>^&&ea)|M?wNz9)XbQu? z#Io#fKP_XIE(GKMQL}PS=beFvw3`9p=SP_r0FUx!yv3vcPCCKOC}Q*wV;o3}>eh^u zR{F$DnSPZu!&D|a->l8H&HI^1n{4qpSKwee4XBHc758w;gIhaW(#>25n?&_2sz}W! zkucUQwMmC|tiV?_B-8(NWL#M%p{QF`HK_B7S^Ec5GuKD!b{JN$?gt6|OO?0S{J;8t zVU)tpBXsE+gIoo&`P)$c#OEvZda-ESr3L62@_@?`o$>u>^nAbBH3VH@aPX>UE-jIh)wF{-zyB z?+iTOfTYwk+0G9V7HwgG3BF5NK`reea{#wWSzcWaSB1ipgzzF^WadZlM?=*3F`Qyo z*us7|STO(YDmgG!O`z#5@uy>P+jo9bo9H5JZ9Ta7YJzNdy*gR3@_RiSI4^6tMO+r} z&+%t2)z&ZbqZSyAHKLrQ!F-P!xu$alRk3#f$EY9XEV8c(=~v@G?~nINvn6B9@@tNGr;A1QaVSQ4bIw+UPStp&N;-6)BEcplpm4$KHn4Mr6S zo?cj{yN?1cs+qw!V=vWYE zqX!(!5>$z1utdhnZwL;CNv3GcB1cCqt4gpg$B%dR!4BpOlRIunnABBDYR;ipWRv+| z9?K1Lc3+>i4cpNCT;XH*QCUAspi$o@b?!z9X;@^ZYFnACzBcW3O3zM?_lyvYJ}Ivj zO8SUls5N_8(x&ZjyFJtZfH{R$7m58~TJPrPKiFPAtMegew5ox~wJVR&z8B0BrDg#B zPRm*Cp92#p%|C!58SjZZr8%TDvX&T3vc@EV9LMFH)OAc2U249-a*?h`a-o#|6&&Wa zCig=7adcZ6c+*@7TdUCGp(tmStQ9!A<8lZaT2u{p!3dZP6_RaTLiQG9;Gz9=zTaX@ zW^u=t($PRb!Oo$&OLmQ>EP*V{!VVe_M}B8wx|R9{?dzvJLc<6-x;L8`=|EeVBUM3t zKfxE&r~2Wf+KMm!ey+qhTE1%CkQP%aoMGoo==`+!Hiwm}GGm_M z#}9%q&U7o|vX&1i$&4kif!%|FQ8)~#{G}?NEnZR~QduQwK!3GzQo-B;gDDPgkHil* z-$ep?Hp4%(nqT3Y>(hm$Ri%rXwm%N$n4ZKlRaKv*+TTfVsEsbm|>Qlr&G- zDaD?_hXjwvw|&gC%@o+II2h+03oV%a!f!Xj6^i%MH`g7u^ zV(60%UX~u9RuJt%@2|k@QMF_*mQ(n2867VF=11B-N1Nx?(ArdC^YY;$=6sN}2WD|F z2UOAb--$-5$i?}H7a=U8`V3dpM|ViH?w;#m5Rb+oymtH)w^n=R{f>{!IuSv;aV`w#A~>P+ca>H^7mSy(Z!;OESA z>oE^hzinPSqcyC|M-YXc2d_FDsWs(GPcNN4`8EYol|wMknI9a0_nAqSW9Q zEvg1CQ@9|xkr_EVsKw#bi+)FVWNRi@W!#Gf>Nt7Ol~h@QU+U}52Ulo=JvR?j*dVS& zXi_i%2Bez}17yA&V^$QNgC|35kv={-j#Y z4Mr@Z=T8|k+&T8F^F-GkOzo1VgyQ4D`P`T_L!;BIb$+8)Y&`Z+n#P{2bMPbsv~M-D zq`W?z+$;jTwD6BhbO1-Zv}@7t3Gr)l<{lO?^<9obv0w{0ZMn9>Xob}yhWY9y zCcREO6eDAR2uBTSBqDVnWHaHf9i;;`_khb4$dg0YT$unx7eK|V;ALD z&lczKjk*AqH*>b?tPOV~g&E4G_`Djr(VO4(uhPfK2Ad01DecLWMA(CL_}l22;sz?=GCuDZ^B?Lf9NNq2A+s#;_Y^l5pzMzjoK9VoyA zqbwL5lkIW~l0{km`(S6V+W9Z;LHM$cN0~9Zm|%E>0M!#jB7A$={%i;zqwA|HG6%f* z_m)@aaT_ryqeczp`0p~mZJ7e|OMW-1(H7Zpv(PaQ^CjcPlZ4TI4jdL9IbgN= zNzt8erAs1=PHaz#0mq6V$S0(KXE3Y8C9#i!RDf0ficxNy_x&do7Kw8ou7G6!lqXtd zgxu~FscIWY*FIgOwLSz~)xls=&*mgwV>kRN$dX<Je;~hFJxS4pP_gg z!7*a|?3+WnyCzFw8)VY1TuK}Qxkm+g3)0&BgqfYR8qs08h1M5kFvNyn*{SX;ed*m6Uxk2 zXU*~doh9K=l!X>m?zLzUQVnULSTyHJI}H;OiRDGwG0Wy_5|qMPTA{evBiO(dEjhDi z)U22!5*GByBle2>`cPgd3mBNcUW$1TaWZ) zmbe*T2zRC}kXBWZW9;z7{*WX~b6?BLU$x41#AI`)<1^35^29zy8@_#D=F}o0F(m@P z2lle%X6u=^Uv-(ODP0q*O6PI)j2JE{N?1`Z*U+^XnKHGS(pIxAC8&$~s6=6d4FSFrLc5SvunK57dy0Y{gkD@6K&nckm-A#XoRMe_($f_DJ6AqcSQns(@rmEJ z;=E;zNrkgC-R2>#N{ltlCk4{cCMZo)Z{pvLldq(v7_vXI&Fx^BVyQ;9jv@teZ(|Ro z?<2(1yTI91;6AXw>H{LwUCYaU4M&Qa8!%KFx~G*V*jQ53R`CO$06X|O7AE=)ig-f_ z7sha?x#{Z>78GV%rg|J#VMP~1D>yX8)zgYSqY!~WIAe&*akIulH_P)8%T>L?h zeF@VldGjbZJj)VJ0rr}WC9+p^>!0m!-t7qz*eb?zvD_zK!FodO?gm=hq2c-&q3w#cAVSh&umUJH z9Kog4<$PG(%m88c24|CNbtv(*I+PlC;?l7ystYp-W0ny7w}bq@yN$dU!Ekj88%pp~ zd-G8UV5kDpO5%iH7H_qid4Yo1i5!sfe2D6qq`N(iCDB+^F}1>>QV@KPw>EE>LVxMz zC!=-Py|TAD5%i6t6;rZo23monyoN7uujchmDd1dGh3N`daQmv?e0XA_$d#C-nH2z) zn6?M<+~LJcbhGNtGI%EpOWEctLF{En&^HheJnDlL5YjpptQtGQ63oa5Xkg56i!JMN z-|@cI`)&r}jrj4-wAUL+5N2$UWIh&<%w4cd3^srQ1{5#NM#d;JCZ^U=k?(9Zs*5wZ zcsh%XIhH>Pu_7zyZkK^~G>&sx@Zntyf-#S@1!+tu5%2wLiE+W!lXh?M7j)g3F0ZJt zjnE9&(3c!>R|O4~uh$(~q5e+> zpVjET3pbVrTLDYz&HkFoW>8PGix!n>1Uc(SV0hcgt1UjQpqFR1v-Nhgh3w<296f{u z=^7Xh#?WK{?ieorb2$>gF*bEK5pv+51+1;q^n1*u9D%;elasphPlg|7!^m4ZXZHMy zJxI7RTm?k97(0Gs@a7o={3*p{JBOeLo)Mr0$}egT1$Z3C!*+~e5AuM{gC?jvz*S;L zaWJ+F>$i0}a{-!d+t7BXQam1fDtelPaOexKRQp;vq?VqjZ5+|mZX}XP})L%#~#pVlRmQ{Qo+@+ z@#(k4&UC3}d~v!Y5Q>Pc+k9Pbc?H%uZ)LuKw)9Jt}`o<1L$04~mx zuAzp9bl_O{(?KwDm%~9p~_%KsUh^+e&w8h@z=4&Umro21A z*xC*Ky|HkWZ8%v*?K$V9xxz8(&Xg@?jIsM&8Sj;-c@t&x;{q9JpP)GWA;wq0_wb4- z^{u`62mPTzI*X+nhPYF@!imTPsH2Eap`MYX6x4EedFU+Oux2IID)`3Rg6FGfwR_^v z=iNKE&f2OnO2HCdc(+lMQ%VAQ5pVkn07!j2{(S09WpN8INiUTXBboT0WIomoRY}0- zYWzRFd}^A$nunPcstw|T?Bk6rj>OOC?|*7}o0f&2L;fGd$nz)!@CIlJXotR2)J((& z>$Ux*LrN2W`AS5n@BzX1qk!1NpGM5qBXI%k?gLv)hKxTI2wf3pUg-PIwa3m6n*UwY zf)0HNjc;~$s6?2*;Dkz~<_iv}L>#~1f=UGCO{)8&KoEgtwCJk9;0sEw3Vgqy?5ZH^ z3o5P(IwCv0+|f4XeCc!^Y@f^96kRn_yYag|zY5A9O8b*&Q5QBS5PQ zQE1_$tCFV$WVfDxP^o~4rI@!*(5tr1$r&qwE({jB_!ao zJ8+No*rwsf2%ELw<0Yn{m5fRF$U5OUQmH8zQ-#qzP$gObEt~ z5?i*%G||ASkW6?+@)hd;mK&|#6lcWsf=lnh9UfORn}mbWY|?o^a}`^iyUi5vuf!aM zdb3=;(n=Rzb#YXZg3E2ieL7RSQWN(AGR;AD<(;4Q(^S00NKeoBw?pUdtTnFjAY+mF zKB#YTywN@#{p9j2^Uho3?1a-RRm>|H=JpWBooKGppFtBpWQJ*@IES1_2DRaMh^_BSMDr&aM&L z4eb-9RaO((8MyKE1H_VweVa~$?XFc;U&@ufMqSY60I%*iTM03}LmKNIGym^R=~YA% z5qhbnDP>r@sy+QHXi57XPc~(2*W~3=URGrsla>B6oF+fNhstqb`z4k8ewI8l$nL1? zhP1*nVGG7W!eHSQtEC6>D@eSw^Vx^LKa{@c;_P~`UEsbIeH*8%Fb%-%{&Oy6pNkFo zaSCrN@jsp(bu!E6eGo~~SHiKAf6k$M!p8x1GS5&lID?L>{>a}5t_-7B2Z$}&6_kqM zUV8r{@HEXnW2E7 zcQHz6&`l=qEWl^U@dthmAz#MR_eZ6(A^S?Tfc$^cUKfZW43#9CL#VfOosSy*L8+Mp z-(oukg2wSL@;tx_A(v%9YfoF}wc9M$bDU8_c5alHOV~V5`GueJFe69Wx$6r=SZNUF z+|j%pYlPwNw6y#JAWSH61TRO-m3J03uo5KHrq+}!c3mR-{nT_@^0=TN4n(a^SAatX zfvXWFf17czXg3roZsjVeDiM@dx*Wxcu2GM>AY_Bu;bG|c$6|+QWS?V9X2mmIGhU2# zYNnzSSZJe-tW2o4UR9}7{(L~7INBf1X>suCL8W(jV@Ks4f6Rt0{L`59N&9S~P>)YL zOej=ek?Gk0CHJwUz9_{B>!F9oe$o~;$5zNf53BI}^-p{lxaxS1i_ip3X_zZ^4aV4i zTCJE`%<#1}^noBdxi1zF0LU=jGGf-2G2~{F>BOTaPpk(`1O9(jI!S2|A- zVTkfRytCG%4&RI8r_(oFK@#nsTqx8?XS(|VQ zogl;3NVP~XuUrb3V9gsav^D2U_;`x2bM&N}Uw)W#LW$<}2=o3PLzW>~0%8J@y#@@+ z=RfgbnI*2lnov=0T>3|0pL$heCC(LD)muQf5|y7}B$QCByz8*A?ycL~kZ&d}Wqx+r z?G+^->Ca!owX4P6DH+_gHhlr^1OCm+f`rcQ`b}T0{Zm>jG2hx_8Wz^IRjlhBA(8zz zO3DR(&0Z^4(bpgnCa+u$9QE}YF`!5XYG`$}xc6OycBd~y{^UxGFnUM)8iV&Hu@M!3 zR;XRE`~9otgTNo|yW_NiR_ET&lhYTR8ztl16$+&RM3nlA)4N``hRVbzS5dTF)V2?3TOEUu;>cuwQGlJyMUt$Ibyr&E;^QuBN8`7{ z`|{CHR8Vmzy}vsejBpBECU5PIu#Td4EMSb=(R&eX?q63eUgxFX_2Rt0{;p*=Df3u9 zb?n$$YJI2qVk-0%|51H%aM(4TEByENk|tnuLn{eKh%u6V^!-otq5aUf?2Hf=ph5Q2 z3v{zwU%xB?z&t*yp|_WAJT0r&*G4(?dPs|X|9Mqh84S>vb$Au%cgGPBdAjXNwCVuH zQiAbJ8G9U(U*8Lhd_^TyUr}KhH|pDDo@ZODtc*3<53kI`aJI#k1#X3-)_8W_yhYdJ zK*o3Mtb#R3chQ(0V1WzLzfY;3E7WNoXCFBSmc0+|_gV!hG`m~Ya$O0fb1w!H6K%sp zxEn0rZFfBo&`7HU2ze_9uPA%}K=xG$n*`?3lug3p)W>#@&|6%B`5M+5!1|vjT*_Uv zVuJzA4TiNAs0cR%1vYrud@n+`R*9c-vhwVf1&b}@^U=mwo3T5iN6vMWqjUZ8&p})_ zLd%ki5P6A6R9E~?jy-q0Z)@JWJ4-6KV92X&V-G!#lw^i62R6qQwuV;VGjxH(6;`jn zxgDA(_$vu?=he2uhvCO!7DMFV3_Rwef^~Wrdmpf+FAMhJL{ARLzQzl4^F4>SRU8eC zJ;Yay8!bKO8chl=O)y<7h9`hzmEANnH!S^P)sPcYA-4{fpjRu{z^}e2G_+wuwVFj{ zx?2uyn@A54EcOOg2VIU$wPn0(u(k0xVr`t73O8)F@Sck4{sXFbxPGqTKXo#JG+ZcI9Keu1t>S0X?Lzh6{INux+paC93q3=pu)Q^{Rp2 zTkV3>!dmthUIQOIdM(VFBe!n-nLqbiAIQ3(Ez*=gU`T9qOwo>yy%uvJ9U`m{L?cAD z3K{BgiHsyD%K$X7K*jyr*w-UQ&v4@AT1>feyE8rijt?gfZu=x=4J{NOuM_o4QsWZw zx40IEr!whECl6APm?_cfBF!ZY3X?k%C z+4eXZMg|savV*DdONiAyNM*+0Vk{%(O{*LT66m)pRD`co0bEwXqMUCK5dL&RkkNJW zd!X{^gKisGPOx?-A^o<&2A%TA zM#ju1u!Dx_oqpX54kd3lg(TJfTKfy41{;CQsg+D0Wu<_h1@lX-^pGs<;%8csVrt9l zVc5va6KQ3nKl!$6q9v zaYv(_JUg)V{B(CjX)!`s24Ih3`Iv3eowB%EF-A?egv z(u6*C6zCk>?g}|`A*7ny7u;v<%?Ez%jqFgFQeJF+Y3pivUcT-FCi#bl?6BRv^bjXV z54gprgPayZ6#(XV>|uryJ`K|rsJz40>}T_5JWpS_MI#*KD6sK!AA)tz1@;Dj(9@xE zW6%E{_b=dt8KJ;4S%&RMS?hA&&|q-x?84;JI`|{hUz#sPt1&Yskxg#>{g2{Uxrifr z;A({|5+FH@fZ60QZ_n8k0(ZabOSdqylZ0?HOqF(0RZsj`48F22af}wTYb#`AQDF?0 z-Dn+Tpm91gR^7WhIa9eS{kfrGk&$VgsH~8?sals~&)*qAef>S9w79!G@?Z3=8-L8K zUb@tG zgo;e0)9gl{4oAC5&ngCx>)ipLtbHw6s{xa;0GLv`*;kOPqy~<(I25vWrO6Cpohw%U z3ZM3CR-JSdUqlsoBu(*DAus&}s3UsNKbgrg!s^{x%_AwrzvwEvsAX67nK?VAkT>IS z`Da4%d)V0@;(91dc};26IJQeY`W{b|jIdY3lhWOXJC-4XGlM+=ZB0WB1uz5#>#p3C zh#6okePa`$M5L`*F*afJKR4I4NOI`0<8P!z+CCmsf!R=9hRORSPT9%=v^So5ADq#Z zn*6?foU0;c#78nEbd)`5Jgz zl{Yp~y$I2d-LE6!6}ds{``hh%+T&oyL~1viFjjK3S80cl2W&07*+=`Wyx2gR9H7r| zMy>xweB>WYzDfCFMkn`pX0<}O1fp%q^4F<+1(H&7=EuLLUjmM4V#;#?De+0l_3XSW zOX$uhJ&or-95-9nj&>QJqVWJ7WL5-^Uq+R3;F^%^VFu!YQ zs2vf~eD3Hm*r4lwGD(ba{(40tLuI-rsf{bTc1higJ9_CU|5GmMU&`U-cQ|BI+UKEo z)m5I@GFeKlo6>1gXWgQhIBRi4^0?GpXK3TkYU*ykBrJG9 zo-DMTYrl}D-}#U5)q%EJM20^MmIw+cm`*RP)X)$29scTTQ(lV8*WTgUG+NzMTBp3rIz(df&@S0!TbkJ4Xb>5r1+JYs}~bTV=NW6ckQj zr?B-ILdfHQ&Wp`Q0&)P(lTyn(UgCuR7B)L~sdai{cE+>|=}@QLC~X3l)*n-*)z7z)p7MpEqDm6SMuhtRLNN z&u_CfC)oWrmBZ=zS9XJO(55LSbxU#CM0%@L;@jKr{EkP9^vR2+339iZ_0ILxcRG2B zMUz|*JG*s6W&&Eq)9%<@5O}EmJrE%LqLD==;FSdt`&)x{DE*(WUY*iNe`(>DC$WD# zuF)Gl+}Nx11dtFJSOz8ahs%Vf2hw$QjjoOoo0cpP;K1jit2ed$usbT{{qxXvCD+eM zt7c3dE<}Io(cx_S^cQ{$!z6o|9%UK-g-*Gxli3$$Nghk+m;Uq}`m@p!KaV}+pZhcw zXY30g9x^Tu+{!;ZktW!}FPA}5Iw?zk(X635KX(Uioq;36OglgEe#HN4NB%%i8m5vB zAxzegvTEPVb*GWlA;9N5lnger!ZzEQ2Z*OdO`Sgfx%=C(Tf??rE(){~I#$}{M#E7-W9KG=0TM?AqhR04!ErTZ49Ra{uF z+@Ggx4$69D{CcEJQ3*Ql2dNx$4dt!uj%fIle!9HveS5-_w5&49;Rz#7#c}U&PFO)y z{dS}D_BCuH-~Q?hs3;7HB08oX8o%PAe)$IppZtwe=U+|l?VRqEGD3Et!wVsZHW|0b z-eDfP=)X9`yir;asi5TWLkKERG4(RC)b59S)xP&h1s@VRZf^V$x=G54_0_scR#Vh- zuya^xAr9+*Kum=*T5L>Tr4SkM8chl*jZ+t(N?LHyH>QTD4_{gK-bLT$P!`ueU&DWq zLow~5_s>WoaKftM6hf%|nyU!gQjVe)d-$&ZcpV*_-sB!A;zr!VJ2Ii-d|dwAg?Ls8 z{PTy1&=&cfl1A7VOC&0cOol4orN6TOZSi^#`X*O2f4^yY5&uOYMcDs2I>PVpr%ho3 z!>jgH_Hzi6HEycG%e%OPyHS-qGWa*%dxjc^P=XTY;+Uzyic z8I8aF2a1M1oGO~z>w(yReh=wdJuf;>Vk~?XUYN%tIFcB+?SvNz?jEo&u!TOHS=7$U z(edc0E2#H6ZvkdWn6=DqAEwyN&|Q+Q@Z01B^7%y^?a)S;m@xxVN^LgnY=N6qSpK@- zA3CB6@3pXA1N&)P5hRGc8)C=rKh}Hb9!meLA_fBuB`La2VJ7J%c=J1c~Oy_OAHh>mR-W?tniLZo$Xv4b=Bnq5hh@& z=aotQOOEcAXl&Hx-bzWrx<5^)1z%jXA_IfxL!Qkzm6En4vdjlqKM22(s-Zo^l_ds| z$n1BXb7JN?}Cw5 zUtcpdW*3$H(m_vQ{AVBfLs^Pa}g>ziO2P_C!Eahj9z9TET4w~ O;B>EU3><^tVE-S6#USqh literal 14403 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 diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index dae8dc9467..4227a83d23 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -2,9 +2,9 @@ - Decision: **NO-GO** - Status: **completed** -- Revision: 4d87bc9c3e9926afc98b89f3c314dfd9291dcded (takeover/2209-valid-evidence) +- Revision: acfa7550af709ac75228968e00946fa0089888fd (takeover/2209-valid-evidence) - Target: AgentDevice-2209-Takeover (F578F08D-BEA1-4A56-8A4B-C92B040FBA94, com.apple.CoreSimulator.SimRuntime.iOS-26-2) -- Generated: 2026-09-01T13:02:31.084Z +- Generated: 2026-09-01T13:11:40.532Z - Corpus: states=warm, screens=quiet, list, samples=20 - Corpus coverage: **decisive-early-stop** @@ -23,7 +23,7 @@ Target: arm64-apple-macosx26.0 | Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation | |---|---|---|---|---|---| -| public-macos-ax | public macOS ApplicationServices AX | observed in successful cells | not exercised | framed protocol | list evidence is substantially flatter and has different identifier coverage (depth 1 vs 4; identifiers 42 vs 11) | +| public-macos-ax | public macOS ApplicationServices AX | observed in successful cells | not exercised | framed protocol | list evidence is substantially flatter and has different identifier coverage (depth 1 vs 2; identifiers 42 vs 12) | | private-coresimulator-ax | external/private CoreSimulator AX tool | unsupported before corpus | unsupported before corpus | framed protocol contract only | private interface/tool compatibility | | xctest-control | #2189 XCTest runner control | observed in successful cells | not exercised | existing runner lifecycle | control, not a host-side AX bridge | @@ -31,20 +31,20 @@ Target: arm64-apple-macosx26.0 | Candidate | State | Screen | N | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures | |---|---|---|---:|---:|---:|---:|---:|---:| -| public-macos-ax | warm | quiet | 20 | 42.3/636.1 | 42.3/636.1 | 0.0/1.0 | 4.0 | 1 | -| public-macos-ax | warm | list | 20 | 1255.9/1667.8 | 1255.9/1667.8 | 1.2/3.2 | 114.0 | 0 | -| xctest-control | warm | quiet | 20 | 243.9/289.8 | 243.9/289.8 | 0.0/0.1 | 4.0 | 0 | -| xctest-control | warm | list | 20 | 460.2/659.3 | 460.2/659.3 | 0.3/0.9 | 33.0 | 0 | +| public-macos-ax | warm | quiet | 20 | 52.3/77.3 | 52.3/77.3 | 0.0/0.1 | 4.0 | 0 | +| public-macos-ax | warm | list | 20 | 1101.5/2136.4 | 1101.5/2136.4 | 1.1/1.6 | 114.0 | 0 | +| xctest-control | warm | quiet | 20 | 286.7/358.3 | 286.7/358.3 | 0.0/0.2 | 4.0 | 0 | +| xctest-control | warm | list | 20 | 618.7/808.5 | 618.7/808.5 | 0.2/0.9 | 31.0 | 0 | Raw exemplar fidelity (public AX vs XCTest control): - quiet: nodes 4/4; depth 1/2; identifiers 0/1. -- list: nodes 114/33; depth 1/4; identifiers 42/11. +- list: nodes 114/31; depth 1/2; identifiers 42/12. Every acquisition sample retains timing, resource, readiness, and failure evidence; the first successful sample in each cell also retains one raw node-tree exemplar with viewport, target generation, truncation, and residue. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction. ## Direct protocol probes -- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=1, duration=2130.8 ms, CPU=4.9 ms, memory=11452416 B, response=697 B +- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=1, duration=2367.5 ms, CPU=5.6 ms, memory=11485184 B, response=693 B - private-coresimulator-ax/protocol-probe:private-coresimulator-ax: ok=false, failure=unsupported-mechanism, code=private-tool-unavailable, nodes=0, duration=0.0 ms, CPU=– ms, memory=– B, response=0 B - stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=unprepared-surface - stderr private-coresimulator-ax/protocol-probe:private-coresimulator-ax: empty @@ -61,7 +61,7 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden - Fixture launch compatible: **true** - Simulator state before experiment: Shutdown - Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored. -- /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=0c85a9ace2ad2c1be37a09a2ceea94fb786d4e163b4c181307bc991038a3b514, afterSha256=a8ce319124a251110662695c55dde033c6bc767b428a9996352bf6c5e572e97b +- /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=0c85a9ace2ad2c1be37a09a2ceea94fb786d4e163b4c181307bc991038a3b514, afterSha256=4a3b607b80fbb5ec36bfe2b91ca4f28e7c993bce16e93ca3987cc7c56410e2c3 - Changes: AccessibilityEnabled: false -> true; ApplicationAccessibilityEnabled: 0 -> true; AutomationEnabled: 0 -> true; IgnoreAXServerEntitlements: undefined -> true - /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.UIAutomation.plist: existed=true, beforeSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c, afterSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c - Changes: none @@ -76,10 +76,7 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden ## Decision rationale -- public-macos-ax warm/quiet did not produce 20 readable samples. -- public-macos-ax warm/quiet has unreadable or empty first-tree evidence. - public-macos-ax warm acquisition missed the 75/150 ms target. -- The public macOS AX mechanism was unsupported or unreadable on the host Simulator surface. - private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable. ## Next interface boundary From 5da0ee020a4dffefa187c081d1c1826b9359f03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 15:32:44 +0200 Subject: [PATCH 21/29] fix: close AX spike measurement gaps --- .../RawAccessibility.swift | 13 +-- scripts/ios-ax-bridge-spike/README.md | 2 +- scripts/ios-ax-bridge-spike/adapter.ts | 10 +- .../ios-ax-bridge-spike/corpus-coverage.ts | 38 ++++++++ scripts/ios-ax-bridge-spike/decision.test.ts | 2 +- scripts/ios-ax-bridge-spike/decision.ts | 4 +- scripts/ios-ax-bridge-spike/framed-process.ts | 1 - .../preference-experiment.ts | 76 +++++++++++++++ scripts/ios-ax-bridge-spike/report.test.ts | 47 ++++++++++ scripts/ios-ax-bridge-spike/report.ts | 53 +++++------ scripts/ios-ax-bridge-spike/run.ts | 94 +------------------ scripts/ios-ax-bridge-spike/runner.ts | 42 +++------ .../sample-evidence.test.ts | 46 ++++++++- .../ios-ax-bridge-spike/sample-evidence.ts | 18 +++- 14 files changed, 282 insertions(+), 164 deletions(-) create mode 100644 scripts/ios-ax-bridge-spike/corpus-coverage.ts create mode 100644 scripts/ios-ax-bridge-spike/preference-experiment.ts create mode 100644 scripts/ios-ax-bridge-spike/report.test.ts diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift index cfa2b0092f..79abacf5db 100644 --- a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift @@ -52,7 +52,8 @@ func capturePublicAccessibility(request: SpikeRequest) -> SpikeCapture { guard let traversalRoot = firstDescendant( window, subrole: "iOSContentGroup", - maxDepth: request.limits.maxTraversalDepth + maxDepth: request.limits.maxTraversalDepth, + maxNodes: request.limits.maxNodes ) else { return unsupportedCapture( code: "target-simulator-content-unavailable", @@ -148,14 +149,14 @@ private func targetWindow(_ windows: [AXUIElement], name: String?) -> AXUIElemen private func firstDescendant( _ element: AXUIElement, subrole: String, - maxDepth: Int + maxDepth: Int, + maxNodes: Int ) -> AXUIElement? { var queue: [(AXUIElement, Int)] = [(element, 0)] - var visited: [AXUIElement] = [] - while !queue.isEmpty { + var visited = Set() + while !queue.isEmpty && visited.count < maxNodes { let (candidate, depth) = queue.removeFirst() - if visited.contains(where: { CFEqual($0, candidate) }) { continue } - visited.append(candidate) + if !visited.insert(ObjectIdentifier(candidate)).inserted { continue } if axString(candidate, kAXSubroleAttribute as String) == subrole { return candidate } if depth < maxDepth { queue.append(contentsOf: axChildren(candidate).map { ($0, depth + 1) }) diff --git a/scripts/ios-ax-bridge-spike/README.md b/scripts/ios-ax-bridge-spike/README.md index 7db1f86fe9..349ffbb4ae 100644 --- a/scripts/ios-ax-bridge-spike/README.md +++ b/scripts/ios-ax-bridge-spike/README.md @@ -24,7 +24,7 @@ pnpm bench:ios-ax-bridge -- \ --out .tmp/ios-ax-bridge-spike.v1.json.gz ``` -The default candidate set, state set, screen set, and sample minimums come from the #2189 benchmark definitions. Each request carries a target generation and fixed request, response, node-count, traversal-depth, CPU, memory, and duration bounds. The native helper sends one newline-delimited response per request and writes diagnostics to stderr only. The report keeps raw nodes, viewport evidence, target lineage, truncation, residue, resource metrics, stderr, and a separate prototype presentation measurement. +The default candidate set, state set, screen set, and sample minimums come from the #2189 benchmark definitions. Each request carries an optional expected target generation and fixed request, response, node-count, traversal-depth, CPU, memory, and duration bounds; each successful response reports the observed generation. The native helper sends one newline-delimited response per request and writes diagnostics to stderr only. The report keeps raw nodes, viewport evidence, target lineage, truncation, residue, resource metrics, stderr, and a separate prototype presentation measurement. `--apply-preferences` is the only way the experiment edits Simulator preference plists. The Simulator must be shutdown; the harness records exact plist hashes and targeted key changes, then restores the original bytes before reporting. The keys are not production defaults. Omit `--private-tool` unless a disposable, compatible private mechanism is being tested; the harness never invents a private fallback. diff --git a/scripts/ios-ax-bridge-spike/adapter.ts b/scripts/ios-ax-bridge-spike/adapter.ts index ab4e123d2a..2ee8dab965 100644 --- a/scripts/ios-ax-bridge-spike/adapter.ts +++ b/scripts/ios-ax-bridge-spike/adapter.ts @@ -8,7 +8,7 @@ import { type CliResult, } from '../ios-snapshot-benchmark/command.ts'; import { runFramedBatch, type FramedProcessSpec } from './framed-process.ts'; -import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; +import { DEFAULT_SPIKE_LIMITS, validateRawAcquisition } from './limits.ts'; import { failureResponse } from './protocol.ts'; import type { CandidateId, @@ -159,6 +159,10 @@ function successfulControlResponse( truncated: snapshot.truncated, residue: [{ kind: 'missing-viewport', reason: 'not-provided' }], } as const; + const validated = validateRawAcquisition(acquisition, request.limits); + if (!validated.ok) { + return failureResponse(request, { kind: 'malformed-tree', code: validated.code }); + } return { version: 1, id: request.id, @@ -169,9 +173,9 @@ function successfulControlResponse( requestBytes: 0, responseBytes: Buffer.byteLength(result.stdout), nodeCount: acquisition.nodes.length, - maxTraversalDepth: 0, + maxTraversalDepth: validated.maxTraversalDepth, cpuMs: null, - memoryBytes: process.memoryUsage().rss, + memoryBytes: null, durationMs, }, }; diff --git a/scripts/ios-ax-bridge-spike/corpus-coverage.ts b/scripts/ios-ax-bridge-spike/corpus-coverage.ts new file mode 100644 index 0000000000..502760df61 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/corpus-coverage.ts @@ -0,0 +1,38 @@ +import type { LocalState, ScreenId } from '../ios-snapshot-benchmark/types.ts'; +import type { SpikeReport } from './types.ts'; + +const FULL_STATES = ['cold-cold', 'cold', 'warm', 'relaunch'] as const; +const FULL_SCREENS = [ + 'quiet', + 'list', + 'nested-scroll', + 'alert', + 'system-surface', + 'xctest-stress', +] as const; + +export function corpusCoverage( + states: readonly LocalState[], + screens: readonly ScreenId[], + cells: SpikeReport['cells'], +): SpikeReport['corpusCoverage'] { + const fullRequested = + FULL_STATES.every((state) => states.includes(state)) && + FULL_SCREENS.every((screen) => screens.includes(screen)); + if (!fullRequested || cells.length === 0) return 'decisive-early-stop'; + const exercisedCandidates = new Set(cells.map((cell) => cell.candidate)); + const fullProduced = [...exercisedCandidates].every((candidate) => + FULL_STATES.every((state) => + FULL_SCREENS.every((screen) => + cells.some( + (cell) => + cell.candidate === candidate && + cell.state === state && + cell.screen === screen && + cell.acquisitionSamples.length >= cell.sampleMinimum, + ), + ), + ), + ); + return fullProduced ? 'full' : 'decisive-early-stop'; +} diff --git a/scripts/ios-ax-bridge-spike/decision.test.ts b/scripts/ios-ax-bridge-spike/decision.test.ts index 7e8ce2b0ea..e9a1c6bcf6 100644 --- a/scripts/ios-ax-bridge-spike/decision.test.ts +++ b/scripts/ios-ax-bridge-spike/decision.test.ts @@ -68,7 +68,7 @@ test('reports a decisive partial corpus failure instead of replacing it with com { candidate: 'public-macos-ax' }, ]); assert.equal(result.decision, 'NO-GO'); - assert.ok(result.reasons.some((reason) => reason.includes('warm acquisition'))); + assert.ok(result.reasons.some((reason) => reason.includes('warm/list acquisition'))); assert.equal( result.reasons.some((reason) => reason.includes('required corpus')), false, diff --git a/scripts/ios-ax-bridge-spike/decision.ts b/scripts/ios-ax-bridge-spike/decision.ts index f9b76ed286..ec1bc2d52b 100644 --- a/scripts/ios-ax-bridge-spike/decision.ts +++ b/scripts/ios-ax-bridge-spike/decision.ts @@ -212,7 +212,9 @@ function latencyReasons(cell: SpikeCell): string[] { cell.state === 'warm' && (percentile(acquisition, 50) >= 75 || percentile(acquisition, 95) >= 150) ) { - reasons.push(`${cell.candidate} warm acquisition missed the 75/150 ms target.`); + reasons.push( + `${cell.candidate} ${cell.state}/${cell.screen} acquisition missed the 75/150 ms target.`, + ); } return reasons; } diff --git a/scripts/ios-ax-bridge-spike/framed-process.ts b/scripts/ios-ax-bridge-spike/framed-process.ts index 9f5c3709ad..935dadf020 100644 --- a/scripts/ios-ax-bridge-spike/framed-process.ts +++ b/scripts/ios-ax-bridge-spike/framed-process.ts @@ -76,7 +76,6 @@ export async function runFramedBatch( { requestBytes: requestBytesFor(request, encodedRequests), responseBytes: stdoutBytes, - durationMs: batchDurationMs, }, ), ); diff --git a/scripts/ios-ax-bridge-spike/preference-experiment.ts b/scripts/ios-ax-bridge-spike/preference-experiment.ts new file mode 100644 index 0000000000..54b80fe5b3 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/preference-experiment.ts @@ -0,0 +1,76 @@ +import { execFileSync } from 'node:child_process'; +import { screenFixture } from '../ios-snapshot-benchmark/definitions.ts'; +import { bootSimulator, shutdownSimulator } from '../ios-snapshot-benchmark/lifecycle.ts'; +import type { SpikeConfig } from './config.ts'; +import { + applyPrebootPreferences, + readSimulatorState, + restorePrebootPreferences, +} from './preferences.ts'; +import type { PreferenceEvidence } from './types.ts'; + +export function runPreferenceExperiment(config: SpikeConfig): PreferenceEvidence { + if (!config.applyPreferences) return initialPreferenceEvidence(config.udid); + shutdownSimulator(config.udid); + const applied = applyPrebootPreferences(config.udid); + let fixtureLaunchCompatible = false; + let restored = false; + try { + bootSimulator(config.udid); + fixtureLaunchCompatible = tryPrimeFixtureApp( + config.udid, + screenFixture(config.screens[0]!).app, + ); + } catch { + fixtureLaunchCompatible = false; + } finally { + try { + if (readSimulatorState(config.udid) !== 'Shutdown') shutdownSimulator(config.udid); + } catch { + restored = false; + } + try { + restored = restorePrebootPreferences(config.udid, applied.snapshots); + } catch { + restored = false; + } + } + return { ...applied.evidence, fixtureLaunchCompatible, restored }; +} + +export function primeFixtureApps(config: SpikeConfig): void { + const apps = new Set(config.screens.map((screen) => screenFixture(screen).app)); + for (const app of apps) { + if (!tryPrimeFixtureApp(config.udid, app)) + throw new Error(`Failed to prime ${app} after booting the restored disposable Simulator.`); + } +} + +function tryPrimeFixtureApp(udid: string, app: string): boolean { + try { + execFileSync('xcrun', ['simctl', 'launch', udid, app], { + encoding: 'utf8', + timeout: 60_000, + stdio: ['ignore', 'pipe', 'pipe'], + }); + return true; + } catch { + return false; + } +} + +function initialPreferenceEvidence(udid: string): PreferenceEvidence { + let simulatorStateBefore = 'unknown'; + try { + simulatorStateBefore = readSimulatorState(udid); + } catch { + simulatorStateBefore = 'unavailable'; + } + return { + applied: false, + restored: false, + fixtureLaunchCompatible: null, + simulatorStateBefore, + diffs: [], + }; +} diff --git a/scripts/ios-ax-bridge-spike/report.test.ts b/scripts/ios-ax-bridge-spike/report.test.ts new file mode 100644 index 0000000000..994c3268d4 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/report.test.ts @@ -0,0 +1,47 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import { gunzipSync } from 'node:zlib'; +import { test } from 'vitest'; +import { corpusCoverage } from './corpus-coverage.ts'; +import { markdownPath } from './report.ts'; + +test('keeps markdown separate from every supported raw artifact path', () => { + assert.equal(markdownPath('/tmp/evidence.json.gz'), '/tmp/evidence.md'); + assert.equal(markdownPath('/tmp/evidence.json'), '/tmp/evidence.md'); + assert.equal(markdownPath('/tmp/evidence'), '/tmp/evidence.md'); +}); + +test('does not call an unproduced requested corpus full', () => { + assert.equal( + corpusCoverage( + ['cold-cold', 'cold', 'warm', 'relaunch'], + ['quiet', 'list', 'nested-scroll', 'alert', 'system-surface', 'xctest-stress'], + [], + ), + 'decisive-early-stop', + ); +}); + +test('ships a readable completed decision inside the checked gzip artifact', () => { + const compressed = fs.readFileSync('docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz'); + const report = JSON.parse(gunzipSync(compressed).toString('utf8')) as { + schemaVersion?: string; + status?: string; + decision?: string; + corpusCoverage?: string; + }; + assert.deepEqual( + { + schemaVersion: report.schemaVersion, + status: report.status, + decision: report.decision, + corpusCoverage: report.corpusCoverage, + }, + { + schemaVersion: 'ios-simulator-ax-bridge-spike.v1', + status: 'completed', + decision: 'NO-GO', + corpusCoverage: 'decisive-early-stop', + }, + ); +}); diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts index 10389aaaa4..fb66155232 100644 --- a/scripts/ios-ax-bridge-spike/report.ts +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -11,7 +11,8 @@ export function writeSpikeReport(outputPath: string, report: SpikeReport): void } export function markdownPath(outputPath: string): string { - return outputPath.replace(/\.json(?:\.gz)?$/u, '.md'); + const replaced = outputPath.replace(/\.json(?:\.gz)?$/u, '.md'); + return replaced === outputPath ? `${outputPath}.md` : replaced; } export function renderSpikeMarkdown(report: SpikeReport): string { @@ -40,7 +41,7 @@ export function renderSpikeMarkdown(report: SpikeReport): string { '', '## Raw acquisition and prototype presentation results', '', - '| Candidate | State | Screen | N | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures |', + '| Candidate | State | Screen | Readable/attempted | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures |', '|---|---|---|---:|---:|---:|---:|---:|---:|', ...report.cells.map(renderCellRow), '', @@ -144,7 +145,7 @@ function renderCellRow(cell: SpikeCell): string { const nodeCounts = readable.flatMap((sample) => typeof sample.metrics?.nodeCount === 'number' ? [sample.metrics.nodeCount] : [], ); - return `| ${cell.candidate} | ${cell.state} | ${cell.screen} | ${acquisition.length} | ${summary(readable, 'wallClockMs')} | ${summary(readable, 'firstLookMs')} | ${summary( + return `| ${cell.candidate} | ${cell.state} | ${cell.screen} | ${readable.length}/${acquisition.length} | ${summary(readable, 'wallClockMs')} | ${summary(readable, 'firstLookMs')} | ${summary( presentation.filter((sample) => sample.ok), 'wallClockMs', )} | ${formatNumber(median(nodeCounts))} | ${failures} |`; @@ -186,14 +187,17 @@ function preferenceExperimentLine(report: SpikeReport): string { } function publicAxLimitation(report: SpikeReport): string { - const publicList = exemplar(report, 'public-macos-ax', 'list'); - const controlList = exemplar(report, 'xctest-control', 'list'); + const publicList = exemplarSample(report, 'public-macos-ax', 'list'); + const controlList = exemplarSample(report, 'xctest-control', 'list'); if (!publicList || !controlList) return 'fidelity and latency remain unproven'; - const publicDepth = treeDepth(publicList); - const controlDepth = treeDepth(controlList); - const publicIdentifiers = publicList.filter((node) => node.identifier).length; - const controlIdentifiers = controlList.filter((node) => node.identifier).length; - return `list evidence is substantially flatter and has different identifier coverage (depth ${publicDepth} vs ${controlDepth}; identifiers ${publicIdentifiers} vs ${controlIdentifiers})`; + const publicDepth = publicList.metrics?.maxTraversalDepth ?? 0; + const controlDepth = controlList.metrics?.maxTraversalDepth ?? 0; + const publicIdentifiers = publicList.acquisition!.nodes.filter((node) => node.identifier).length; + const controlIdentifiers = controlList.acquisition!.nodes.filter( + (node) => node.identifier, + ).length; + const shape = publicDepth < controlDepth ? 'flatter' : 'structurally different'; + return `list evidence is ${shape} and has different identifier coverage (depth ${publicDepth} vs ${controlDepth}; identifiers ${publicIdentifiers} vs ${controlIdentifiers})`; } function compactReportEvidence(report: SpikeReport): SpikeReport { @@ -202,7 +206,7 @@ function compactReportEvidence(report: SpikeReport): SpikeReport { cells: report.cells.map((cell) => ({ ...cell, acquisitionSamples: cell.acquisitionSamples.map((sample, index) => - index === 0 || sample.stderr === undefined ? sample : withoutStderr(sample), + index === 0 || !sample.ok || sample.stderr === undefined ? sample : withoutStderr(sample), ), presentationSamples: cell.presentationSamples.map((sample) => withoutStderr(sample)), })), @@ -217,35 +221,26 @@ function withoutStderr(sample: SpikeSample): SpikeSample { function fidelityLines(report: SpikeReport): string[] { const lines = ['Raw exemplar fidelity (public AX vs XCTest control):']; for (const screen of report.config.screens) { - const publicNodes = exemplar(report, 'public-macos-ax', screen); - const controlNodes = exemplar(report, 'xctest-control', screen); - if (!publicNodes || !controlNodes) continue; + const publicSample = exemplarSample(report, 'public-macos-ax', screen); + const controlSample = exemplarSample(report, 'xctest-control', screen); + if (!publicSample || !controlSample) continue; + const publicNodes = publicSample.acquisition!.nodes; + const controlNodes = controlSample.acquisition!.nodes; lines.push( - `- ${screen}: nodes ${publicNodes.length}/${controlNodes.length}; depth ${treeDepth(publicNodes)}/${treeDepth(controlNodes)}; identifiers ${publicNodes.filter((node) => node.identifier).length}/${controlNodes.filter((node) => node.identifier).length}.`, + `- ${screen}: nodes ${publicNodes.length}/${controlNodes.length}; depth ${publicSample.metrics?.maxTraversalDepth ?? '–'}/${controlSample.metrics?.maxTraversalDepth ?? '–'}; identifiers ${publicNodes.filter((node) => node.identifier).length}/${controlNodes.filter((node) => node.identifier).length}.`, ); } return lines.length === 1 ? ['Raw exemplar fidelity comparison was not available.'] : lines; } -function exemplar( +function exemplarSample( report: SpikeReport, candidate: SpikeCell['candidate'], screen: SpikeCell['screen'], -): NonNullable['nodes'] | undefined { +): SpikeSample | undefined { return report.cells .find((cell) => cell.candidate === candidate && cell.screen === screen) - ?.acquisitionSamples.find((sample) => sample.acquisition)?.acquisition?.nodes; -} - -function treeDepth(nodes: NonNullable['nodes']): number { - const depthById = new Map(); - let maximum = 0; - for (const node of nodes) { - const depth = node.parentId ? (depthById.get(node.parentId) ?? 0) + 1 : 0; - depthById.set(node.id, depth); - maximum = Math.max(maximum, depth); - } - return maximum; + ?.acquisitionSamples.find((sample) => sample.acquisition); } function summary(samples: readonly SpikeSample[], key: 'wallClockMs' | 'firstLookMs'): string { diff --git a/scripts/ios-ax-bridge-spike/run.ts b/scripts/ios-ax-bridge-spike/run.ts index 9a8ca1b6f9..a5a32f393b 100644 --- a/scripts/ios-ax-bridge-spike/run.ts +++ b/scripts/ios-ax-bridge-spike/run.ts @@ -9,18 +9,14 @@ import { import { parseConfig, type SpikeConfig } from './config.ts'; import { decideSpike } from './decision.ts'; import { runLifecycleProbes } from './lifecycle.ts'; -import { - applyPrebootPreferences, - readSimulatorState, - restorePrebootPreferences, -} from './preferences.ts'; import { markdownPath, writeSpikeReport } from './report.ts'; +import { corpusCoverage } from './corpus-coverage.ts'; +import { primeFixtureApps, runPreferenceExperiment } from './preference-experiment.ts'; import { createAdapterOptions, runSpikeCells } from './runner.ts'; import { readGitRevision, readTarget, readToolchain } from '../ios-snapshot-benchmark/host.ts'; import { runDeepButtonControls } from '../ios-snapshot-benchmark/deep-control.ts'; import { deepButtonFixtureEvidence } from '../ios-snapshot-benchmark/deep-button.ts'; import { bootSimulator, shutdownSimulator } from '../ios-snapshot-benchmark/lifecycle.ts'; -import { screenFixture } from '../ios-snapshot-benchmark/definitions.ts'; import type { AcquisitionAdapter } from './adapter.ts'; import { SPIKE_ISSUE, SPIKE_PARENT, SPIKE_PREREQUISITES, SPIKE_SCHEMA_VERSION } from './types.ts'; import type { @@ -113,56 +109,6 @@ async function collectSpikeEvidence(config: SpikeConfig): Promise screenFixture(screen).app)); - for (const app of apps) { - if (!tryPrimeFixtureApp(config.udid, app)) - throw new Error(`Failed to prime ${app} after booting the restored disposable Simulator.`); - } -} - -function runPreferenceExperiment(config: SpikeConfig): PreferenceEvidence { - if (!config.applyPreferences) { - return initialPreferenceEvidence(config.udid); - } - shutdownSimulator(config.udid); - const applied = applyPrebootPreferences(config.udid); - let fixtureLaunchCompatible = false; - let restored = false; - try { - bootSimulator(config.udid); - fixtureLaunchCompatible = tryPrimeFixtureApp( - config.udid, - screenFixture(config.screens[0]!).app, - ); - shutdownSimulator(config.udid); - } finally { - try { - if (readSimulatorState(config.udid) !== 'Shutdown') shutdownSimulator(config.udid); - } finally { - restored = restorePrebootPreferences(config.udid, applied.snapshots); - } - } - return { - ...applied.evidence, - fixtureLaunchCompatible, - restored, - }; -} - -function tryPrimeFixtureApp(udid: string, app: string): boolean { - try { - execFileSync('xcrun', ['simctl', 'launch', udid, app], { - encoding: 'utf8', - timeout: 60_000, - stdio: ['ignore', 'pipe', 'pipe'], - }); - return true; - } catch { - return false; - } -} - function stopForError(error: unknown): SpikeReport['stop'] { return { category: isConfigurationError(error) ? 'configuration' : 'infrastructure', @@ -200,7 +146,7 @@ function createReport( lifecycle, positiveControl: evidence.positiveControl, status: evidence.status, - corpusCoverage: corpusCoverage(config), + corpusCoverage: corpusCoverage(config.states, config.screens, evidence.cells), cells: evidence.cells, decision: decision.decision, decisionReasons: decision.reasons, @@ -280,22 +226,6 @@ function readMetadata(config: SpikeConfig): { }; } -function initialPreferenceEvidence(udid: string): PreferenceEvidence { - let simulatorStateBefore = 'unknown'; - try { - simulatorStateBefore = readSimulatorState(udid); - } catch { - simulatorStateBefore = 'unavailable'; - } - return { - applied: false, - restored: false, - fixtureLaunchCompatible: null, - simulatorStateBefore, - diffs: [], - }; -} - function supportedAdapters( adapters: readonly AcquisitionAdapter[], probes: readonly SpikeResponse[], @@ -307,24 +237,6 @@ function supportedAdapters( }); } -function corpusCoverage(config: SpikeConfig): SpikeReport['corpusCoverage'] { - const fullStates = ['cold-cold', 'cold', 'warm', 'relaunch']; - const fullScreens = [ - 'quiet', - 'list', - 'nested-scroll', - 'alert', - 'system-surface', - 'xctest-stress', - ]; - return fullStates.every((state) => - config.states.includes(state as SpikeConfig['states'][number]), - ) && - fullScreens.every((screen) => config.screens.includes(screen as SpikeConfig['screens'][number])) - ? 'full' - : 'decisive-early-stop'; -} - function commandText(command: string, args: readonly string[]): string { try { return execFileSync(command, [...args], { diff --git a/scripts/ios-ax-bridge-spike/runner.ts b/scripts/ios-ax-bridge-spike/runner.ts index a0fff2d788..74c9e4a2f4 100644 --- a/scripts/ios-ax-bridge-spike/runner.ts +++ b/scripts/ios-ax-bridge-spike/runner.ts @@ -107,22 +107,27 @@ async function collectWarmSamples( presentationSamples: SpikeSample[], ): Promise { admitReadyCell(context, admission); - const requests = Array.from({ length: config.samples }, (_, index) => - makeRequest(config, adapter.candidate, admission.state, admission.fixture.id, index), - ); - const captured = await captureBatch(adapter, requests); - captured.forEach((item, index) => + for (let index = 0; index < config.samples; index += 1) { + if (index > 0) prepareSampleState(admission); + const request = makeRequest( + config, + adapter.candidate, + admission.state, + admission.fixture.id, + index, + ); + const captured = await capture(adapter, request); appendSamples( adapter.candidate, admission.state, admission.fixture.id, index, - item, + captured, 0, acquisitionSamples, presentationSamples, - ), - ); + ); + } } async function collectNonWarmSamples( @@ -196,27 +201,6 @@ async function capture( }; } -async function captureBatch( - adapter: AcquisitionAdapter, - requests: readonly SpikeRequest[], -): Promise { - const startedAt = new Date().toISOString(); - const started = performance.now(); - const batch = await adapter.acquireBatch(requests); - const batchWallClockMs = performance.now() - started; - if (batch.responses.length !== requests.length) { - throw new BenchmarkInfrastructureError( - `Adapter ${adapter.candidate} returned an incomplete batch.`, - ); - } - return batch.responses.map((response) => ({ - response, - stderr: batch.stderr, - startedAt, - wallClockMs: response.metrics.durationMs > 0 ? response.metrics.durationMs : batchWallClockMs, - })); -} - function contextFor( config: SpikeConfig, candidate: CandidateId, diff --git a/scripts/ios-ax-bridge-spike/sample-evidence.test.ts b/scripts/ios-ax-bridge-spike/sample-evidence.test.ts index a56b5b346d..5e88cb2566 100644 --- a/scripts/ios-ax-bridge-spike/sample-evidence.test.ts +++ b/scripts/ios-ax-bridge-spike/sample-evidence.test.ts @@ -17,7 +17,7 @@ test('keeps one raw acquisition exemplar while retaining every sample measuremen ok: true, acquisition: { targetId: 'simulator:test', - nodes: [{ id: 'root', role: 'AXGroup' }], + nodes: [{ id: 'root', role: 'AXGroup', label: 'Inert surface' }], viewport: { kind: 'missing', reason: 'not-provided' }, truncated: false, residue: [], @@ -56,3 +56,47 @@ test('keeps one raw acquisition exemplar while retaining every sample measuremen true, ); }); + +test('rejects a non-empty acquisition that is not bound to the prepared fixture', () => { + const acquisitionSamples: SpikeSample[] = []; + const presentationSamples: SpikeSample[] = []; + const captured: CapturedResponse = { + startedAt: '2026-09-01T00:00:00.000Z', + wallClockMs: 12, + stderr: '', + response: { + version: 1, + id: 'wrong-tree', + candidate: 'public-macos-ax', + ok: true, + acquisition: { + targetId: 'simulator:test', + targetGeneration: 'one', + nodes: [{ id: 'root', label: 'Another screen' }], + viewport: { kind: 'missing', reason: 'not-provided' }, + truncated: false, + residue: [], + }, + metrics: { + requestBytes: 1, + responseBytes: 2, + nodeCount: 1, + maxTraversalDepth: 0, + cpuMs: 1, + memoryBytes: 1, + durationMs: 12, + }, + }, + }; + appendSamples( + 'public-macos-ax', + 'warm', + 'quiet', + 0, + captured, + 0, + acquisitionSamples, + presentationSamples, + ); + assert.equal(acquisitionSamples[0]?.firstTree, 'unreadable'); +}); diff --git a/scripts/ios-ax-bridge-spike/sample-evidence.ts b/scripts/ios-ax-bridge-spike/sample-evidence.ts index bf1dc7c65a..4852e56500 100644 --- a/scripts/ios-ax-bridge-spike/sample-evidence.ts +++ b/scripts/ios-ax-bridge-spike/sample-evidence.ts @@ -1,5 +1,6 @@ import { firstTreeStatus } from './protocol.ts'; import { presentAcquisitionForMeasurement } from './presentation.ts'; +import { screenFixture } from '../ios-snapshot-benchmark/definitions.ts'; import type { SpikeConfig } from './config.ts'; import type { SpikeCell, SpikeRequest, SpikeResponse, SpikeSample } from './types.ts'; @@ -21,7 +22,7 @@ export function appendSamples( presentationSamples: SpikeSample[], ): void { const acquiredAt = new Date().toISOString(); - const status = firstTreeStatus(captured.response); + const status = fixtureBoundStatus(captured.response, screen); const keepRawExemplar = captured.response.acquisition !== undefined && acquisitionSamples.every((sample) => sample.acquisition === undefined); @@ -46,6 +47,21 @@ export function appendSamples( presentationSamples.push(presentationSample(candidate, state, screen, index, captured, status)); } +function fixtureBoundStatus( + response: SpikeResponse, + screen: SpikeCell['screen'], +): SpikeSample['firstTree'] { + const status = firstTreeStatus(response); + if (status !== 'readable' || !response.acquisition) return status; + const fixture = screenFixture(screen); + const anchor = fixture.setupAnchorText ?? fixture.anchorText; + return response.acquisition.nodes.some((node) => + [node.label, node.value, node.identifier].some((value) => value?.includes(anchor)), + ) + ? 'readable' + : 'unreadable'; +} + export function makeRequest( config: SpikeConfig, candidate: SpikeCell['candidate'], From 5e6577689781319400fafbd9923a3ac1e067ec1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 15:34:03 +0200 Subject: [PATCH 22/29] fix: initialize preference evidence owner --- scripts/ios-ax-bridge-spike/preference-experiment.ts | 2 +- scripts/ios-ax-bridge-spike/run.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/ios-ax-bridge-spike/preference-experiment.ts b/scripts/ios-ax-bridge-spike/preference-experiment.ts index 54b80fe5b3..89c845461c 100644 --- a/scripts/ios-ax-bridge-spike/preference-experiment.ts +++ b/scripts/ios-ax-bridge-spike/preference-experiment.ts @@ -59,7 +59,7 @@ function tryPrimeFixtureApp(udid: string, app: string): boolean { } } -function initialPreferenceEvidence(udid: string): PreferenceEvidence { +export function initialPreferenceEvidence(udid: string): PreferenceEvidence { let simulatorStateBefore = 'unknown'; try { simulatorStateBefore = readSimulatorState(udid); diff --git a/scripts/ios-ax-bridge-spike/run.ts b/scripts/ios-ax-bridge-spike/run.ts index a5a32f393b..c9143e229a 100644 --- a/scripts/ios-ax-bridge-spike/run.ts +++ b/scripts/ios-ax-bridge-spike/run.ts @@ -11,7 +11,11 @@ import { decideSpike } from './decision.ts'; import { runLifecycleProbes } from './lifecycle.ts'; import { markdownPath, writeSpikeReport } from './report.ts'; import { corpusCoverage } from './corpus-coverage.ts'; -import { primeFixtureApps, runPreferenceExperiment } from './preference-experiment.ts'; +import { + initialPreferenceEvidence, + primeFixtureApps, + runPreferenceExperiment, +} from './preference-experiment.ts'; import { createAdapterOptions, runSpikeCells } from './runner.ts'; import { readGitRevision, readTarget, readToolchain } from '../ios-snapshot-benchmark/host.ts'; import { runDeepButtonControls } from '../ios-snapshot-benchmark/deep-control.ts'; From 7cea59eb6a226c0ae8659dbec9f299855b14bd59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 15:42:39 +0200 Subject: [PATCH 23/29] fix: distinguish transient AX probe readiness --- scripts/ios-ax-bridge-spike/decision.ts | 8 +++++++- scripts/ios-ax-bridge-spike/run.ts | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/ios-ax-bridge-spike/decision.ts b/scripts/ios-ax-bridge-spike/decision.ts index ec1bc2d52b..ea2de5efd7 100644 --- a/scripts/ios-ax-bridge-spike/decision.ts +++ b/scripts/ios-ax-bridge-spike/decision.ts @@ -79,7 +79,7 @@ function probeReasons( probes: readonly { candidate: CandidateId; failure?: { kind: string; code?: string } }[], ): string[] { return probes.flatMap((probe) => - probe.failure + probe.failure && !isReadinessProbeFailure(probe.failure.code) ? [ `${probe.candidate} protocol probe returned ${probe.failure.kind}/${probe.failure.code ?? 'no-code'}.`, ] @@ -87,6 +87,12 @@ function probeReasons( ); } +function isReadinessProbeFailure(code: string | undefined): boolean { + return ['target-application-unavailable', 'target-simulator-window-unavailable'].includes( + code ?? '', + ); +} + const REQUIRED_STATES = LOCAL_STATES; const REQUIRED_SCREENS = SCREEN_FIXTURES.map((fixture) => fixture.id); diff --git a/scripts/ios-ax-bridge-spike/run.ts b/scripts/ios-ax-bridge-spike/run.ts index c9143e229a..6b29dbc1d0 100644 --- a/scripts/ios-ax-bridge-spike/run.ts +++ b/scripts/ios-ax-bridge-spike/run.ts @@ -237,7 +237,11 @@ function supportedAdapters( return adapters.filter((adapter) => { if (adapter.candidate === 'xctest-control') return true; const probe = probes.find((candidate) => candidate.candidate === adapter.candidate); - return probe?.failure?.kind !== 'unsupported-mechanism'; + return ![ + 'private-tool-unavailable', + 'host-accessibility-permission', + 'candidate-not-supported', + ].includes(probe?.failure?.code ?? ''); }); } From 8a403d3f2fc65bf57c4c517f1aeb1b45c7758cfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 15:52:32 +0200 Subject: [PATCH 24/29] docs: refresh review-corrected AX evidence --- ...ios-simulator-ax-bridge-2026-09-01.json.gz | Bin 14254 -> 15434 bytes .../ios-simulator-ax-bridge-2026-09-01.md | 25 +++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz index 0cc56ff9e6a6197a37047965bcdd2f6cb8b5ccaf..95b36cc8aebbe439ff2fac64cddc6b12dade7d35 100644 GIT binary patch literal 15434 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 literal 14254 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 O;B>EU3><^tVE-S6#USqh diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 4227a83d23..80eaff3d81 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -2,9 +2,9 @@ - Decision: **NO-GO** - Status: **completed** -- Revision: acfa7550af709ac75228968e00946fa0089888fd (takeover/2209-valid-evidence) +- Revision: 7cea59eb6a226c0ae8659dbec9f299855b14bd59 (takeover/2209-valid-evidence) - Target: AgentDevice-2209-Takeover (F578F08D-BEA1-4A56-8A4B-C92B040FBA94, com.apple.CoreSimulator.SimRuntime.iOS-26-2) -- Generated: 2026-09-01T13:11:40.532Z +- Generated: 2026-09-01T13:52:13.940Z - Corpus: states=warm, screens=quiet, list, samples=20 - Corpus coverage: **decisive-early-stop** @@ -23,28 +23,28 @@ Target: arm64-apple-macosx26.0 | Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation | |---|---|---|---|---|---| -| public-macos-ax | public macOS ApplicationServices AX | observed in successful cells | not exercised | framed protocol | list evidence is substantially flatter and has different identifier coverage (depth 1 vs 2; identifiers 42 vs 12) | +| public-macos-ax | public macOS ApplicationServices AX | observed in successful cells | not exercised | framed protocol | list evidence is flatter and has different identifier coverage (depth 1 vs 4; identifiers 42 vs 11) | | private-coresimulator-ax | external/private CoreSimulator AX tool | unsupported before corpus | unsupported before corpus | framed protocol contract only | private interface/tool compatibility | | xctest-control | #2189 XCTest runner control | observed in successful cells | not exercised | existing runner lifecycle | control, not a host-side AX bridge | ## Raw acquisition and prototype presentation results -| Candidate | State | Screen | N | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures | +| Candidate | State | Screen | Readable/attempted | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures | |---|---|---|---:|---:|---:|---:|---:|---:| -| public-macos-ax | warm | quiet | 20 | 52.3/77.3 | 52.3/77.3 | 0.0/0.1 | 4.0 | 0 | -| public-macos-ax | warm | list | 20 | 1101.5/2136.4 | 1101.5/2136.4 | 1.1/1.6 | 114.0 | 0 | -| xctest-control | warm | quiet | 20 | 286.7/358.3 | 286.7/358.3 | 0.0/0.2 | 4.0 | 0 | -| xctest-control | warm | list | 20 | 618.7/808.5 | 618.7/808.5 | 0.2/0.9 | 31.0 | 0 | +| public-macos-ax | warm | quiet | 20/20 | 107.5/130.0 | 107.5/130.0 | 0.1/0.2 | 4.0 | 0 | +| public-macos-ax | warm | list | 20/20 | 1653.0/2568.3 | 1653.0/2568.3 | 1.7/2.9 | 114.0 | 0 | +| xctest-control | warm | quiet | 20/20 | 214.3/244.8 | 214.3/244.8 | 0.0/0.1 | 4.0 | 0 | +| xctest-control | warm | list | 20/20 | 401.7/439.7 | 401.7/439.7 | 0.2/0.5 | 33.0 | 0 | Raw exemplar fidelity (public AX vs XCTest control): - quiet: nodes 4/4; depth 1/2; identifiers 0/1. -- list: nodes 114/31; depth 1/2; identifiers 42/12. +- list: nodes 114/33; depth 1/4; identifiers 42/11. Every acquisition sample retains timing, resource, readiness, and failure evidence; the first successful sample in each cell also retains one raw node-tree exemplar with viewport, target generation, truncation, and residue. Presentation samples measure only construction of the #2190 acquired carrier; they do not apply visibility, hittability, scope, depth, or semantic compaction. ## Direct protocol probes -- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=1, duration=2367.5 ms, CPU=5.6 ms, memory=11485184 B, response=693 B +- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=1, duration=2083.6 ms, CPU=4.7 ms, memory=11501568 B, response=707 B - private-coresimulator-ax/protocol-probe:private-coresimulator-ax: ok=false, failure=unsupported-mechanism, code=private-tool-unavailable, nodes=0, duration=0.0 ms, CPU=– ms, memory=– B, response=0 B - stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=unprepared-surface - stderr private-coresimulator-ax/protocol-probe:private-coresimulator-ax: empty @@ -61,7 +61,7 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden - Fixture launch compatible: **true** - Simulator state before experiment: Shutdown - Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored. -- /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=0c85a9ace2ad2c1be37a09a2ceea94fb786d4e163b4c181307bc991038a3b514, afterSha256=4a3b607b80fbb5ec36bfe2b91ca4f28e7c993bce16e93ca3987cc7c56410e2c3 +- /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=0c85a9ace2ad2c1be37a09a2ceea94fb786d4e163b4c181307bc991038a3b514, afterSha256=9251302d832d513ff284f5e9ee810855b71ce914a5d6e98b2254e53c04589c7b - Changes: AccessibilityEnabled: false -> true; ApplicationAccessibilityEnabled: 0 -> true; AutomationEnabled: 0 -> true; IgnoreAXServerEntitlements: undefined -> true - /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.UIAutomation.plist: existed=true, beforeSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c, afterSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c - Changes: none @@ -76,7 +76,8 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden ## Decision rationale -- public-macos-ax warm acquisition missed the 75/150 ms target. +- public-macos-ax warm/quiet acquisition missed the 75/150 ms target. +- public-macos-ax warm/list acquisition missed the 75/150 ms target. - private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable. ## Next interface boundary From 4b8456ee26ab964afb466dc0c5dd2cab7d3751a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 15:55:26 +0200 Subject: [PATCH 25/29] fix: preserve preference failure evidence --- .../preference-experiment.ts | 38 +++++++++------ scripts/ios-ax-bridge-spike/report.ts | 2 +- scripts/ios-ax-bridge-spike/run.ts | 48 ++++++++++++++++--- 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/scripts/ios-ax-bridge-spike/preference-experiment.ts b/scripts/ios-ax-bridge-spike/preference-experiment.ts index 89c845461c..6a43ee01c5 100644 --- a/scripts/ios-ax-bridge-spike/preference-experiment.ts +++ b/scripts/ios-ax-bridge-spike/preference-experiment.ts @@ -4,6 +4,7 @@ import { bootSimulator, shutdownSimulator } from '../ios-snapshot-benchmark/life import type { SpikeConfig } from './config.ts'; import { applyPrebootPreferences, + type PlistSnapshot, readSimulatorState, restorePrebootPreferences, } from './preferences.ts'; @@ -13,8 +14,15 @@ export function runPreferenceExperiment(config: SpikeConfig): PreferenceEvidence if (!config.applyPreferences) return initialPreferenceEvidence(config.udid); shutdownSimulator(config.udid); const applied = applyPrebootPreferences(config.udid); - let fixtureLaunchCompatible = false; - let restored = false; + return exerciseAppliedPreferences(config, applied.evidence, applied.snapshots); +} + +function exerciseAppliedPreferences( + config: SpikeConfig, + evidence: PreferenceEvidence, + snapshots: readonly PlistSnapshot[], +): PreferenceEvidence { + let fixtureLaunchCompatible: boolean; try { bootSimulator(config.udid); fixtureLaunchCompatible = tryPrimeFixtureApp( @@ -23,19 +31,21 @@ export function runPreferenceExperiment(config: SpikeConfig): PreferenceEvidence ); } catch { fixtureLaunchCompatible = false; - } finally { - try { - if (readSimulatorState(config.udid) !== 'Shutdown') shutdownSimulator(config.udid); - } catch { - restored = false; - } - try { - restored = restorePrebootPreferences(config.udid, applied.snapshots); - } catch { - restored = false; - } } - return { ...applied.evidence, fixtureLaunchCompatible, restored }; + return { + ...evidence, + fixtureLaunchCompatible, + restored: restorePreferences(config.udid, snapshots), + }; +} + +function restorePreferences(udid: string, snapshots: readonly PlistSnapshot[]): boolean { + try { + if (readSimulatorState(udid) !== 'Shutdown') shutdownSimulator(udid); + return restorePrebootPreferences(udid, snapshots); + } catch { + return false; + } } export function primeFixtureApps(config: SpikeConfig): void { diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts index fb66155232..ed8f2c2c06 100644 --- a/scripts/ios-ax-bridge-spike/report.ts +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -15,7 +15,7 @@ export function markdownPath(outputPath: string): string { return replaced === outputPath ? `${outputPath}.md` : replaced; } -export function renderSpikeMarkdown(report: SpikeReport): string { +function renderSpikeMarkdown(report: SpikeReport): string { const lines = [ '# iOS Simulator AX bridge spike', '', diff --git a/scripts/ios-ax-bridge-spike/run.ts b/scripts/ios-ax-bridge-spike/run.ts index 6b29dbc1d0..50e397030d 100644 --- a/scripts/ios-ax-bridge-spike/run.ts +++ b/scripts/ios-ax-bridge-spike/run.ts @@ -85,11 +85,10 @@ async function collectSpikeEvidence(config: SpikeConfig): Promise Date: Tue, 1 Sep 2026 16:11:51 +0200 Subject: [PATCH 26/29] fix: close final AX evidence edge cases --- .../RawAccessibility.swift | 32 ++++++++++++++++--- scripts/ios-ax-bridge-spike/README.md | 2 +- scripts/ios-ax-bridge-spike/config.ts | 7 +++- .../ios-ax-bridge-spike/corpus-coverage.ts | 18 ++++------- scripts/ios-ax-bridge-spike/decision.ts | 9 ++++-- scripts/ios-ax-bridge-spike/preferences.ts | 2 +- scripts/ios-ax-bridge-spike/report.test.ts | 1 + scripts/ios-ax-bridge-spike/report.ts | 15 +++++++-- scripts/ios-ax-bridge-spike/run.ts | 7 +++- scripts/ios-ax-bridge-spike/runner.ts | 7 ++-- .../ios-ax-bridge-spike/sample-evidence.ts | 6 ++-- .../ios-snapshot-benchmark/cell-admission.ts | 16 ++++++++++ scripts/ios-snapshot-benchmark/command.ts | 4 +++ .../proxy-client-support.ts | 11 ++++++- .../ios-snapshot-benchmark/proxy-client.ts | 3 ++ 15 files changed, 109 insertions(+), 31 deletions(-) diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift index 79abacf5db..650fcff71b 100644 --- a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift +++ b/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift @@ -10,6 +10,12 @@ private struct RawTraversalState { var hitDepthLimit = false } +private struct RootSearchResult { + let element: AXUIElement + let depth: Int + let visitedCount: Int +} + func capturePublicAccessibility(request: SpikeRequest) -> SpikeCapture { guard request.version == 1, request.candidate == "public-macos-ax" else { return unsupportedCapture(code: "candidate-not-supported") @@ -49,7 +55,7 @@ func capturePublicAccessibility(request: SpikeRequest) -> SpikeCapture { observedTargetGeneration: generation ) } - guard let traversalRoot = firstDescendant( + guard let rootSearch = firstDescendant( window, subrole: "iOSContentGroup", maxDepth: request.limits.maxTraversalDepth, @@ -60,13 +66,15 @@ func capturePublicAccessibility(request: SpikeRequest) -> SpikeCapture { observedTargetGeneration: generation ) } + let traversalRoot = rootSearch.element + let traversalLimits = remainingLimits(request.limits, after: rootSearch) var state = RawTraversalState() _ = appendRawNode( traversalRoot, parentId: nil, depth: 0, - limits: request.limits, + limits: traversalLimits, state: &state ) let viewport = axRect(traversalRoot).map { @@ -151,13 +159,17 @@ private func firstDescendant( subrole: String, maxDepth: Int, maxNodes: Int -) -> AXUIElement? { +) -> RootSearchResult? { var queue: [(AXUIElement, Int)] = [(element, 0)] var visited = Set() + var retained: [AXUIElement] = [] while !queue.isEmpty && visited.count < maxNodes { let (candidate, depth) = queue.removeFirst() if !visited.insert(ObjectIdentifier(candidate)).inserted { continue } - if axString(candidate, kAXSubroleAttribute as String) == subrole { return candidate } + retained.append(candidate) + if axString(candidate, kAXSubroleAttribute as String) == subrole { + return RootSearchResult(element: candidate, depth: depth, visitedCount: visited.count) + } if depth < maxDepth { queue.append(contentsOf: axChildren(candidate).map { ($0, depth + 1) }) } @@ -165,6 +177,18 @@ private func firstDescendant( return nil } +private func remainingLimits(_ limits: SpikeLimits, after search: RootSearchResult) -> SpikeLimits { + SpikeLimits( + maxRequestBytes: limits.maxRequestBytes, + maxResponseBytes: limits.maxResponseBytes, + maxNodes: max(1, limits.maxNodes - search.visitedCount + 1), + maxTraversalDepth: max(0, limits.maxTraversalDepth - search.depth), + maxCpuMs: limits.maxCpuMs, + maxMemoryBytes: limits.maxMemoryBytes, + maxDurationMs: limits.maxDurationMs + ) +} + private func targetApplication(request: SpikeRequest) -> NSRunningApplication? { if let processId = request.targetProcessId, let application = NSRunningApplication(processIdentifier: processId), diff --git a/scripts/ios-ax-bridge-spike/README.md b/scripts/ios-ax-bridge-spike/README.md index 349ffbb4ae..d87b46706b 100644 --- a/scripts/ios-ax-bridge-spike/README.md +++ b/scripts/ios-ax-bridge-spike/README.md @@ -24,7 +24,7 @@ pnpm bench:ios-ax-bridge -- \ --out .tmp/ios-ax-bridge-spike.v1.json.gz ``` -The default candidate set, state set, screen set, and sample minimums come from the #2189 benchmark definitions. Each request carries an optional expected target generation and fixed request, response, node-count, traversal-depth, CPU, memory, and duration bounds; each successful response reports the observed generation. The native helper sends one newline-delimited response per request and writes diagnostics to stderr only. The report keeps raw nodes, viewport evidence, target lineage, truncation, residue, resource metrics, stderr, and a separate prototype presentation measurement. +The default candidate set, state set, screen set, and sample minimums come from the #2189 benchmark definitions. Each request carries an optional expected target generation and fixed request, response, node-count, traversal-depth, CPU, memory, and duration bounds; each successful response reports the observed generation. The native helper sends one newline-delimited response per request and writes diagnostics to stderr only. Every sample keeps resource metrics and target status; each cell keeps one raw-tree exemplar with viewport, lineage, truncation, residue, and bounded diagnostics, plus separate prototype presentation measurements. `--apply-preferences` is the only way the experiment edits Simulator preference plists. The Simulator must be shutdown; the harness records exact plist hashes and targeted key changes, then restores the original bytes before reporting. The keys are not production defaults. Omit `--private-tool` unless a disposable, compatible private mechanism is being tested; the harness never invents a private fallback. diff --git a/scripts/ios-ax-bridge-spike/config.ts b/scripts/ios-ax-bridge-spike/config.ts index c7cceaeeb5..a71f569bae 100644 --- a/scripts/ios-ax-bridge-spike/config.ts +++ b/scripts/ios-ax-bridge-spike/config.ts @@ -13,7 +13,12 @@ import { import type { CandidateId, ResourceLimits } from './types.ts'; import { DEFAULT_SPIKE_LIMITS } from './limits.ts'; -class SpikeConfigurationError extends Error {} +class SpikeConfigurationError extends Error { + constructor(message: string) { + super(message); + this.name = 'SpikeConfigurationError'; + } +} export type SpikeConfig = Readonly<{ repoRoot: string; diff --git a/scripts/ios-ax-bridge-spike/corpus-coverage.ts b/scripts/ios-ax-bridge-spike/corpus-coverage.ts index 502760df61..b53ab3a02d 100644 --- a/scripts/ios-ax-bridge-spike/corpus-coverage.ts +++ b/scripts/ios-ax-bridge-spike/corpus-coverage.ts @@ -1,27 +1,21 @@ +import { LOCAL_STATES, SCREEN_FIXTURES } from '../ios-snapshot-benchmark/definitions.ts'; import type { LocalState, ScreenId } from '../ios-snapshot-benchmark/types.ts'; -import type { SpikeReport } from './types.ts'; +import type { CandidateId, SpikeReport } from './types.ts'; -const FULL_STATES = ['cold-cold', 'cold', 'warm', 'relaunch'] as const; -const FULL_SCREENS = [ - 'quiet', - 'list', - 'nested-scroll', - 'alert', - 'system-surface', - 'xctest-stress', -] as const; +const FULL_STATES = LOCAL_STATES; +const FULL_SCREENS = SCREEN_FIXTURES.map((fixture) => fixture.id); export function corpusCoverage( states: readonly LocalState[], screens: readonly ScreenId[], cells: SpikeReport['cells'], + candidates: readonly CandidateId[], ): SpikeReport['corpusCoverage'] { const fullRequested = FULL_STATES.every((state) => states.includes(state)) && FULL_SCREENS.every((screen) => screens.includes(screen)); if (!fullRequested || cells.length === 0) return 'decisive-early-stop'; - const exercisedCandidates = new Set(cells.map((cell) => cell.candidate)); - const fullProduced = [...exercisedCandidates].every((candidate) => + const fullProduced = candidates.every((candidate) => FULL_STATES.every((state) => FULL_SCREENS.every((screen) => cells.some( diff --git a/scripts/ios-ax-bridge-spike/decision.ts b/scripts/ios-ax-bridge-spike/decision.ts index ea2de5efd7..0a0af7423b 100644 --- a/scripts/ios-ax-bridge-spike/decision.ts +++ b/scripts/ios-ax-bridge-spike/decision.ts @@ -88,9 +88,12 @@ function probeReasons( } function isReadinessProbeFailure(code: string | undefined): boolean { - return ['target-application-unavailable', 'target-simulator-window-unavailable'].includes( - code ?? '', - ); + return [ + 'target-application-unavailable', + 'target-has-no-accessibility-windows', + 'target-simulator-window-unavailable', + 'target-simulator-content-unavailable', + ].includes(code ?? ''); } const REQUIRED_STATES = LOCAL_STATES; diff --git a/scripts/ios-ax-bridge-spike/preferences.ts b/scripts/ios-ax-bridge-spike/preferences.ts index 92cb559bcf..ab241ed22f 100644 --- a/scripts/ios-ax-bridge-spike/preferences.ts +++ b/scripts/ios-ax-bridge-spike/preferences.ts @@ -129,7 +129,7 @@ export function applyPrebootPreferences(udid: string): { return { snapshots, evidence: { - applied: diffs.some((diff) => diff.changes.length > 0), + applied: true, restored: false, simulatorStateBefore, diffs, diff --git a/scripts/ios-ax-bridge-spike/report.test.ts b/scripts/ios-ax-bridge-spike/report.test.ts index 994c3268d4..c298b5003b 100644 --- a/scripts/ios-ax-bridge-spike/report.test.ts +++ b/scripts/ios-ax-bridge-spike/report.test.ts @@ -17,6 +17,7 @@ test('does not call an unproduced requested corpus full', () => { ['cold-cold', 'cold', 'warm', 'relaunch'], ['quiet', 'list', 'nested-scroll', 'alert', 'system-surface', 'xctest-stress'], [], + ['public-macos-ax'], ), 'decisive-early-stop', ); diff --git a/scripts/ios-ax-bridge-spike/report.ts b/scripts/ios-ax-bridge-spike/report.ts index ed8f2c2c06..2107915af3 100644 --- a/scripts/ios-ax-bridge-spike/report.ts +++ b/scripts/ios-ax-bridge-spike/report.ts @@ -41,8 +41,8 @@ function renderSpikeMarkdown(report: SpikeReport): string { '', '## Raw acquisition and prototype presentation results', '', - '| Candidate | State | Screen | Readable/attempted | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures |', - '|---|---|---|---:|---:|---:|---:|---:|---:|', + '| Candidate | State | Screen | Readable/attempted | Wall p50/p95 ms | Gated duration p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures |', + '|---|---|---|---:|---:|---:|---:|---:|---:|---:|', ...report.cells.map(renderCellRow), '', ...fidelityLines(report), @@ -145,12 +145,21 @@ function renderCellRow(cell: SpikeCell): string { const nodeCounts = readable.flatMap((sample) => typeof sample.metrics?.nodeCount === 'number' ? [sample.metrics.nodeCount] : [], ); - return `| ${cell.candidate} | ${cell.state} | ${cell.screen} | ${readable.length}/${acquisition.length} | ${summary(readable, 'wallClockMs')} | ${summary(readable, 'firstLookMs')} | ${summary( + return `| ${cell.candidate} | ${cell.state} | ${cell.screen} | ${readable.length}/${acquisition.length} | ${summary(readable, 'wallClockMs')} | ${metricSummary(readable)} | ${summary(readable, 'firstLookMs')} | ${summary( presentation.filter((sample) => sample.ok), 'wallClockMs', )} | ${formatNumber(median(nodeCounts))} | ${failures} |`; } +function metricSummary(samples: readonly SpikeSample[]): string { + const values = samples.flatMap((sample) => + sample.metrics && Number.isFinite(sample.metrics.durationMs) ? [sample.metrics.durationMs] : [], + ); + return values.length === 0 + ? '–' + : `${formatNumber(median(values))}/${formatNumber(percentile(values, 95))}`; +} + function surfaceStatus( report: SpikeReport, candidate: SpikeCell['candidate'], diff --git a/scripts/ios-ax-bridge-spike/run.ts b/scripts/ios-ax-bridge-spike/run.ts index 50e397030d..cc1d890a47 100644 --- a/scripts/ios-ax-bridge-spike/run.ts +++ b/scripts/ios-ax-bridge-spike/run.ts @@ -186,7 +186,12 @@ function createReport( lifecycle, positiveControl: evidence.positiveControl, status: evidence.status, - corpusCoverage: corpusCoverage(config.states, config.screens, evidence.cells), + corpusCoverage: corpusCoverage( + config.states, + config.screens, + evidence.cells, + config.candidates, + ), cells: evidence.cells, decision: decision.decision, decisionReasons: decision.reasons, diff --git a/scripts/ios-ax-bridge-spike/runner.ts b/scripts/ios-ax-bridge-spike/runner.ts index 74c9e4a2f4..a784aa53d3 100644 --- a/scripts/ios-ax-bridge-spike/runner.ts +++ b/scripts/ios-ax-bridge-spike/runner.ts @@ -8,6 +8,7 @@ import { } from '../ios-snapshot-benchmark/command.ts'; import { admitReadyCell, + admitStableWarmSample, admitSuccessfulSample, prepareCellState, prepareSampleState, @@ -106,9 +107,11 @@ async function collectWarmSamples( acquisitionSamples: SpikeSample[], presentationSamples: SpikeSample[], ): Promise { - admitReadyCell(context, admission); + let appPid = admitReadyCell(context, admission); + if (appPid === undefined) + throw new BenchmarkInfrastructureError('Warm admission returned no app PID.'); for (let index = 0; index < config.samples; index += 1) { - if (index > 0) prepareSampleState(admission); + if (index > 0) appPid = admitStableWarmSample(admission, appPid); const request = makeRequest( config, adapter.candidate, diff --git a/scripts/ios-ax-bridge-spike/sample-evidence.ts b/scripts/ios-ax-bridge-spike/sample-evidence.ts index 4852e56500..7334854e3c 100644 --- a/scripts/ios-ax-bridge-spike/sample-evidence.ts +++ b/scripts/ios-ax-bridge-spike/sample-evidence.ts @@ -104,12 +104,13 @@ function failedPresentationSample( captured: CapturedResponse, status: SpikeSample['firstTree'], ): SpikeSample { + const startedAt = new Date().toISOString(); return { index: index + 1, candidate, state, screen, - startedAt: captured.startedAt, + startedAt, finishedAt: new Date().toISOString(), operation: 'presentation', wallClockMs: 0, @@ -136,13 +137,14 @@ function successfulPresentationSample( captured: CapturedResponse, status: SpikeSample['firstTree'], ): SpikeSample { + const startedAt = new Date().toISOString(); const presented = presentAcquisitionForMeasurement(captured.response.acquisition!); return { index: index + 1, candidate, state, screen, - startedAt: captured.startedAt, + startedAt, finishedAt: new Date().toISOString(), operation: 'presentation', wallClockMs: presented.measurement.durationMs, diff --git a/scripts/ios-snapshot-benchmark/cell-admission.ts b/scripts/ios-snapshot-benchmark/cell-admission.ts index 596eafbcc9..bf079cb511 100644 --- a/scripts/ios-snapshot-benchmark/cell-admission.ts +++ b/scripts/ios-snapshot-benchmark/cell-admission.ts @@ -89,6 +89,22 @@ export function admitSuccessfulSample( return admitNonWarmSample(context, options, previousAppPid); } +export function admitStableWarmSample( + options: CellAdmissionOptions, + previousAppPid: number, +): number { + assertReadyState(options); + const appPid = assertAppRunning(options.udid, options.fixture.app); + if (appPid !== previousAppPid) { + throw new BenchmarkCellAdmissionError( + 'cell-state', + `Warm cell ${options.fixture.id} changed app PID from ${String(previousAppPid)} to ${String(appPid)}.`, + 'agent-device batch --steps snapshot', + ); + } + return appPid; +} + function admitNonWarmSample( context: CliContext, options: CellAdmissionOptions, diff --git a/scripts/ios-snapshot-benchmark/command.ts b/scripts/ios-snapshot-benchmark/command.ts index a7a11773cd..9c6ac9f24a 100644 --- a/scripts/ios-snapshot-benchmark/command.ts +++ b/scripts/ios-snapshot-benchmark/command.ts @@ -109,6 +109,10 @@ export function scrollFixtureToBottom(context: CliContext): CliResult { return runCli(context, ['scroll', 'bottom', '--settle']); } +export async function scrollFixtureToBottomAsync(context: CliContext): Promise { + return await runCliAsync(context, ['scroll', 'bottom', '--settle']); +} + export async function pressFixtureTargetAsync( context: CliContext, selector: string, diff --git a/scripts/ios-snapshot-benchmark/proxy-client-support.ts b/scripts/ios-snapshot-benchmark/proxy-client-support.ts index 0b9608a3df..7361821749 100644 --- a/scripts/ios-snapshot-benchmark/proxy-client-support.ts +++ b/scripts/ios-snapshot-benchmark/proxy-client-support.ts @@ -18,7 +18,10 @@ import type { Failure, ProxyNetwork, RawSample, ScreenFixture } from './types.ts export type AgentClient = { apps: { open(options: Record): Promise }; - interactions: { click(options: Record): Promise }; + interactions: { + click(options: Record): Promise; + scroll(options: Record): Promise; + }; batch: { run(options: Record): Promise> }; sessions: { close(): Promise }; leases: { @@ -106,6 +109,12 @@ export async function openClientFixture( foreground: true, }); if (fixture.setupAction === 'open-alert') { + await client.interactions.scroll({ + direction: 'bottom', + settle: true, + platform: 'ios', + udid, + }); await client.interactions.click({ target: { kind: 'selector', selector: 'id="automation-open-alert"' }, platform: 'ios', diff --git a/scripts/ios-snapshot-benchmark/proxy-client.ts b/scripts/ios-snapshot-benchmark/proxy-client.ts index 4bedfbbd90..234a97c942 100644 --- a/scripts/ios-snapshot-benchmark/proxy-client.ts +++ b/scripts/ios-snapshot-benchmark/proxy-client.ts @@ -2,6 +2,7 @@ import path from 'node:path'; import { openFixtureAsync, pressFixtureTargetAsync, + scrollFixtureToBottomAsync, sampleFromCli, snapshotFixtureAsync, } from './command.ts'; @@ -140,6 +141,8 @@ async function prepareFreshCliFixture( fixture: ScreenFixture, ): Promise { if (fixture.setupAction !== 'open-alert') return; + const scrolled = await scrollFixtureToBottomAsync(context); + if (!scrolled.ok) throw setupFailure('fresh CLI alert setup scroll', scrolled); const pressed = await pressFixtureTargetAsync(context, 'id="automation-open-alert"'); if (!pressed.ok) throw setupFailure('fresh CLI alert setup', pressed); } From 6908c2ec4fc4d3ad332d5dacd1db60446dd1a2be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 16:36:29 +0200 Subject: [PATCH 27/29] docs: publish final simulator AX decision evidence --- ...ios-simulator-ax-bridge-2026-09-01.json.gz | Bin 15434 -> 16106 bytes .../ios-simulator-ax-bridge-2026-09-01.md | 20 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.json.gz index 95b36cc8aebbe439ff2fac64cddc6b12dade7d35..cb88f34a3ef43248e2e3d9ff164a0acde75461d4 100644 GIT binary patch literal 16106 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 diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 80eaff3d81..62105233f8 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -2,9 +2,9 @@ - Decision: **NO-GO** - Status: **completed** -- Revision: 7cea59eb6a226c0ae8659dbec9f299855b14bd59 (takeover/2209-valid-evidence) +- Revision: 5ad244596c73f0884a48eb6445da3262d7eecb87 (takeover/2209-valid-evidence) - Target: AgentDevice-2209-Takeover (F578F08D-BEA1-4A56-8A4B-C92B040FBA94, com.apple.CoreSimulator.SimRuntime.iOS-26-2) -- Generated: 2026-09-01T13:52:13.940Z +- Generated: 2026-09-01T14:27:51.339Z - Corpus: states=warm, screens=quiet, list, samples=20 - Corpus coverage: **decisive-early-stop** @@ -29,12 +29,12 @@ Target: arm64-apple-macosx26.0 ## Raw acquisition and prototype presentation results -| Candidate | State | Screen | Readable/attempted | Acquisition p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures | -|---|---|---|---:|---:|---:|---:|---:|---:| -| public-macos-ax | warm | quiet | 20/20 | 107.5/130.0 | 107.5/130.0 | 0.1/0.2 | 4.0 | 0 | -| public-macos-ax | warm | list | 20/20 | 1653.0/2568.3 | 1653.0/2568.3 | 1.7/2.9 | 114.0 | 0 | -| xctest-control | warm | quiet | 20/20 | 214.3/244.8 | 214.3/244.8 | 0.0/0.1 | 4.0 | 0 | -| xctest-control | warm | list | 20/20 | 401.7/439.7 | 401.7/439.7 | 0.2/0.5 | 33.0 | 0 | +| Candidate | State | Screen | Readable/attempted | Wall p50/p95 ms | Gated duration p50/p95 ms | First look p95 ms | Presentation p50/p95 ms | Nodes | Failures | +|---|---|---|---:|---:|---:|---:|---:|---:|---:| +| public-macos-ax | warm | quiet | 20/20 | 135.4/276.3 | 121.6/231.9 | 135.4/276.3 | 0.0/0.2 | 4.0 | 0 | +| public-macos-ax | warm | list | 20/20 | 1330.6/2554.9 | 1314.5/2527.0 | 1330.6/2554.9 | 1.6/2.5 | 114.0 | 0 | +| xctest-control | warm | quiet | 20/20 | 249.7/706.0 | 249.5/705.7 | 249.7/706.0 | 0.1/0.2 | 4.0 | 0 | +| xctest-control | warm | list | 20/20 | 471.8/579.0 | 471.4/578.8 | 471.8/579.0 | 0.2/0.5 | 33.0 | 0 | Raw exemplar fidelity (public AX vs XCTest control): - quiet: nodes 4/4; depth 1/2; identifiers 0/1. @@ -44,7 +44,7 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden ## Direct protocol probes -- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=1, duration=2083.6 ms, CPU=4.7 ms, memory=11501568 B, response=707 B +- public-macos-ax/protocol-probe:public-macos-ax: ok=true, failure=none, code=none, nodes=1, duration=2234.7 ms, CPU=5.1 ms, memory=11468800 B, response=707 B - private-coresimulator-ax/protocol-probe:private-coresimulator-ax: ok=false, failure=unsupported-mechanism, code=private-tool-unavailable, nodes=0, duration=0.0 ms, CPU=– ms, memory=– B, response=0 B - stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=unprepared-surface - stderr private-coresimulator-ax/protocol-probe:private-coresimulator-ax: empty @@ -61,7 +61,7 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden - Fixture launch compatible: **true** - Simulator state before experiment: Shutdown - Private/preboot preference keys are experimental only; they were applied to this shutdown disposable Simulator and the original plist bytes were restored. -- /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=0c85a9ace2ad2c1be37a09a2ceea94fb786d4e163b4c181307bc991038a3b514, afterSha256=9251302d832d513ff284f5e9ee810855b71ce914a5d6e98b2254e53c04589c7b +- /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.Accessibility.plist: existed=true, beforeSha256=0c85a9ace2ad2c1be37a09a2ceea94fb786d4e163b4c181307bc991038a3b514, afterSha256=23695eb18c42e49869332f9149ad7005efd9d8e143c951e1396b8e67f2b4c179 - Changes: AccessibilityEnabled: false -> true; ApplicationAccessibilityEnabled: 0 -> true; AutomationEnabled: 0 -> true; IgnoreAXServerEntitlements: undefined -> true - /Users/thymikee/Library/Developer/CoreSimulator/Devices/F578F08D-BEA1-4A56-8A4B-C92B040FBA94/data/Library/Preferences/com.apple.UIAutomation.plist: existed=true, beforeSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c, afterSha256=db8995177327a963486dd0607260f0fad74ad10d9dec6c2f5abdbaf0dbd00b2c - Changes: none From 5d80b35a3825382aa2863ae45881626c29a610f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 17:20:36 +0200 Subject: [PATCH 28/29] fix(ios): keep AX spike out of npm package --- apple/macos-helper/Package.swift | 7 ------- package.json | 2 +- scripts/ios-ax-bridge-spike/README.md | 5 ++++- scripts/ios-ax-bridge-spike/adapter.test.ts | 12 +++++++++++- scripts/ios-ax-bridge-spike/adapter.ts | 5 +++-- .../ios-ax-bridge-spike/swift/Package.swift | 18 ++++++++++++++++++ .../ProcessMetrics.swift | 0 .../AgentDeviceIosAxBridgeSpike/Protocol.swift | 0 .../RawAccessibility.swift | 0 .../AgentDeviceIosAxBridgeSpike/main.swift | 0 10 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 scripts/ios-ax-bridge-spike/swift/Package.swift rename {apple/macos-helper => scripts/ios-ax-bridge-spike/swift}/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift (100%) rename {apple/macos-helper => scripts/ios-ax-bridge-spike/swift}/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift (100%) rename {apple/macos-helper => scripts/ios-ax-bridge-spike/swift}/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift (100%) rename {apple/macos-helper => scripts/ios-ax-bridge-spike/swift}/Sources/AgentDeviceIosAxBridgeSpike/main.swift (100%) diff --git a/apple/macos-helper/Package.swift b/apple/macos-helper/Package.swift index 9bae526423..82cd920325 100644 --- a/apple/macos-helper/Package.swift +++ b/apple/macos-helper/Package.swift @@ -9,17 +9,10 @@ let package = Package( name: "agent-device-macos-helper", targets: ["AgentDeviceMacOSHelper"] ), - .executable( - name: "agent-device-ios-ax-bridge-spike", - targets: ["AgentDeviceIosAxBridgeSpike"] - ), ], targets: [ .executableTarget( name: "AgentDeviceMacOSHelper" ), - .executableTarget( - name: "AgentDeviceIosAxBridgeSpike" - ), ] ) diff --git a/package.json b/package.json index 3ee3a178e7..c609cd6f8e 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "package:android-ime-helper": "AGENT_DEVICE_ANDROID_HELPER=ime sh ./scripts/package-android-helper.sh $(node -p \"require('./package.json').version\") .tmp/android-ime-helper", "package:android-ime-helper:npm": "rm -rf android/ime-helper/dist && AGENT_DEVICE_ANDROID_HELPER=ime sh ./scripts/package-android-helper.sh $(node -p \"require('./package.json').version\") android/ime-helper/dist", "build:macos-helper": "node --experimental-strip-types scripts/swift-toolchain-tmpdir.ts swift build -c release --package-path apple/macos-helper", - "build:ios-ax-bridge-spike": "node --experimental-strip-types scripts/swift-toolchain-tmpdir.ts swift build -c release --package-path apple/macos-helper --product agent-device-ios-ax-bridge-spike", + "build:ios-ax-bridge-spike": "node --experimental-strip-types scripts/swift-toolchain-tmpdir.ts swift build -c release --package-path scripts/ios-ax-bridge-spike/swift --product agent-device-ios-ax-bridge-spike", "build:macos-helper:clean": "node --experimental-strip-types scripts/swift-toolchain-tmpdir.ts swift package --package-path apple/macos-helper clean && pnpm build:macos-helper", "build:package": "pnpm build && pnpm build:xcuitest:ios && pnpm build:xcuitest:macos && pnpm build:xcuitest:tvos && pnpm build:xcuitest:visionos && pnpm build:macos-helper:clean && pnpm package:apple-runner:npm && pnpm build:android", "package:npm": "pnpm build:package && pnpm check:package", diff --git a/scripts/ios-ax-bridge-spike/README.md b/scripts/ios-ax-bridge-spike/README.md index d87b46706b..a5cd89bd98 100644 --- a/scripts/ios-ax-bridge-spike/README.md +++ b/scripts/ios-ax-bridge-spike/README.md @@ -2,7 +2,7 @@ This bounded harness supplies the decision evidence for [#2192](https://github.com/callstack/agent-device/issues/2192). It compares host-side public macOS AX, an explicitly configured private CoreSimulator AX tool, and the #2189 XCTest control baseline behind one framed acquisition adapter. It does not select a production backend or change daemon, runner, open, relaunch, proxy, interaction, or public CLI behavior. -Build the repository and the macOS helper first: +Build the repository and the repository-only spike helper first: ```sh pnpm install --frozen-lockfile @@ -10,6 +10,9 @@ pnpm build pnpm build:ios-ax-bridge-spike ``` +The rejected helper remains under this spike tooling package so it is reproducible without entering +the distributed `apple/macos-helper` package or npm artifact. + Use a newly created, task-owned iOS Simulator. Xcode 27 hosts should target the DeviceHub process explicitly when using the public candidate: ```sh diff --git a/scripts/ios-ax-bridge-spike/adapter.test.ts b/scripts/ios-ax-bridge-spike/adapter.test.ts index ebc6fed046..c5fc1e27c3 100644 --- a/scripts/ios-ax-bridge-spike/adapter.test.ts +++ b/scripts/ios-ax-bridge-spike/adapter.test.ts @@ -1,14 +1,24 @@ import assert from 'node:assert/strict'; +import fs from 'node:fs'; import { test } from 'vitest'; import { defaultPublicMacOsAxHelperPath, readControlSnapshot } from './adapter.ts'; test('public AX adapter resolves the SwiftPM release product', () => { assert.equal( defaultPublicMacOsAxHelperPath('/repo'), - '/repo/apple/macos-helper/.build/release/agent-device-ios-ax-bridge-spike', + '/repo/scripts/ios-ax-bridge-spike/swift/.build/release/agent-device-ios-ax-bridge-spike', ); }); +test('spike executable stays outside the distributed macOS helper package', () => { + const manifest = fs.readFileSync( + new URL('../../apple/macos-helper/Package.swift', import.meta.url), + 'utf8', + ); + + assert.doesNotMatch(manifest, /AgentDeviceIosAxBridgeSpike|agent-device-ios-ax-bridge-spike/); +}); + test('control mapping preserves the producer raw node type', () => { const result = readControlSnapshot({ data: { diff --git a/scripts/ios-ax-bridge-spike/adapter.ts b/scripts/ios-ax-bridge-spike/adapter.ts index 2ee8dab965..d475ef1a00 100644 --- a/scripts/ios-ax-bridge-spike/adapter.ts +++ b/scripts/ios-ax-bridge-spike/adapter.ts @@ -47,8 +47,9 @@ export function createPublicMacOsAxAdapter(options: AdapterOptions): Acquisition export function defaultPublicMacOsAxHelperPath(repoRoot: string): string { return path.join( repoRoot, - 'apple', - 'macos-helper', + 'scripts', + 'ios-ax-bridge-spike', + 'swift', '.build', 'release', 'agent-device-ios-ax-bridge-spike', diff --git a/scripts/ios-ax-bridge-spike/swift/Package.swift b/scripts/ios-ax-bridge-spike/swift/Package.swift new file mode 100644 index 0000000000..7796b51ff4 --- /dev/null +++ b/scripts/ios-ax-bridge-spike/swift/Package.swift @@ -0,0 +1,18 @@ +// swift-tools-version: 5.9 +import PackageDescription + +let package = Package( + name: "agent-device-ios-ax-bridge-spike", + platforms: [.macOS(.v13)], + products: [ + .executable( + name: "agent-device-ios-ax-bridge-spike", + targets: ["AgentDeviceIosAxBridgeSpike"] + ), + ], + targets: [ + .executableTarget( + name: "AgentDeviceIosAxBridgeSpike" + ), + ] +) diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift b/scripts/ios-ax-bridge-spike/swift/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift similarity index 100% rename from apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift rename to scripts/ios-ax-bridge-spike/swift/Sources/AgentDeviceIosAxBridgeSpike/ProcessMetrics.swift diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift b/scripts/ios-ax-bridge-spike/swift/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift similarity index 100% rename from apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift rename to scripts/ios-ax-bridge-spike/swift/Sources/AgentDeviceIosAxBridgeSpike/Protocol.swift diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift b/scripts/ios-ax-bridge-spike/swift/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift similarity index 100% rename from apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift rename to scripts/ios-ax-bridge-spike/swift/Sources/AgentDeviceIosAxBridgeSpike/RawAccessibility.swift diff --git a/apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/main.swift b/scripts/ios-ax-bridge-spike/swift/Sources/AgentDeviceIosAxBridgeSpike/main.swift similarity index 100% rename from apple/macos-helper/Sources/AgentDeviceIosAxBridgeSpike/main.swift rename to scripts/ios-ax-bridge-spike/swift/Sources/AgentDeviceIosAxBridgeSpike/main.swift From ac90db94cd643debd1748f7b46943409ffb5a5f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 1 Sep 2026 18:01:09 +0200 Subject: [PATCH 29/29] docs(ios): correct AX bridge viability verdict --- .../ios-simulator-ax-bridge-2026-09-01.md | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md index 62105233f8..7976254d0e 100644 --- a/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md +++ b/docs/evidence/ios-simulator-ax-bridge-2026-09-01.md @@ -1,13 +1,19 @@ # iOS Simulator AX bridge spike -- Decision: **NO-GO** -- Status: **completed** +- Decision: **INCONCLUSIVE — public AX NO-GO; guest AX bridge requires the full corpus** +- Status: **reopened after candidate-coverage correction** - Revision: 5ad244596c73f0884a48eb6445da3262d7eecb87 (takeover/2209-valid-evidence) - Target: AgentDevice-2209-Takeover (F578F08D-BEA1-4A56-8A4B-C92B040FBA94, com.apple.CoreSimulator.SimRuntime.iOS-26-2) - Generated: 2026-09-01T14:27:51.339Z - Corpus: states=warm, screens=quiet, list, samples=20 - Corpus coverage: **decisive-early-stop** +The generated run originally reported an overall NO-GO. That verdict was too broad: the +`private-coresimulator-ax` adapter returned `private-tool-unavailable` solely because no +`--private-tool` path was supplied. It did not discover, build, or execute a private candidate. +The gzipped JSON remains the immutable original run; the correction and independent live probe +below are intentionally recorded separately. + ## Environment and limits - Node: v26.1.0 @@ -24,7 +30,7 @@ Target: arm64-apple-macosx26.0 | Candidate | Mechanism | App surface | System surface | Lifecycle | Main limitation | |---|---|---|---|---|---| | public-macos-ax | public macOS ApplicationServices AX | observed in successful cells | not exercised | framed protocol | list evidence is flatter and has different identifier coverage (depth 1 vs 4; identifiers 42 vs 11) | -| private-coresimulator-ax | external/private CoreSimulator AX tool | unsupported before corpus | unsupported before corpus | framed protocol contract only | private interface/tool compatibility | +| private-coresimulator-ax | external/private CoreSimulator AX tool | not exercised in the generated corpus | not exercised | framed protocol contract only | the run supplied no tool, so it cannot support a viability verdict | | xctest-control | #2189 XCTest runner control | observed in successful cells | not exercised | existing runner lifecycle | control, not a host-side AX bridge | ## Raw acquisition and prototype presentation results @@ -49,6 +55,36 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden - stderr public-macos-ax/protocol-probe:public-macos-ax: [ios-ax-spike] capture id=protocol-probe:public-macos-ax candidate=public-macos-ax screen=unprepared-surface - stderr private-coresimulator-ax/protocol-probe:private-coresimulator-ax: empty +`private-tool-unavailable` is setup evidence, not mechanism evidence. In the adapter at this +revision, omitting `--private-tool` or naming a path that does not exist constructs this response +without starting a process. + +## Post-run candidate audit + +An independent audit on 2026-09-01 used the official idb v1.5.2 arm64 release +(`idb-companion.macos-arm64.tar.gz`, SHA-256 +`f17b718a513931705542a7fbfa9cfc11895ee191562c9ffd2343cf7f8254bc08`), including its bundled +`Resources/SimulatorFrameworkBridge`, on macOS 27.0 (26A5421a), Xcode 27.0 (27A5252f), and a booted +iOS 27.0 iPhone 17 Pro Simulator. Settings was foregrounded; the read used +`ui describe-all --api axbridge-persistent --format complete --profile` with label, identifier, +frame, and type. No `.xctest` bundle, test runner, or agent-device runner was started. + +- Backend reported: `axbridge-exclusive` (the persistent guest bridge's held session). +- First successful read: 167 elements, not truncated, one Mach round trip, 49,313 response bytes, + 956.0 ms total including bridge startup, and 56.9 ms guest read time. +- Six subsequent reads returned the same 167-element, non-truncated tree with one Mach round trip. + Total profile time ranged from 39.9 to 53.7 ms (p50 43.6 ms); guest read time ranged from 30.9 to + 39.4 ms. +- A prior attempt against a black/unready Simulator failed with an explicit frontmost-application + resolution error. Foregrounding Settings on a healthy Simulator separated target readiness from + bridge availability. +- The companion was stopped after the audit and removed its temporary directory. + +This audit proves that a compatible, no-XCTest guest AX mechanism exists, runs on the current host, +returns a detailed batched tree, and has enough warm latency headroom to justify the full #2192 +corpus. It does not prove the remaining system-surface, lifecycle, cancellation, stale-generation, +relaunch, or multi-screen acceptance cells, so it is not a production GO by itself. + ## Independent positive-control evidence - Invalid shallow rule: exit=1; command=pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow; assertion=AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid. @@ -78,13 +114,19 @@ Every acquisition sample retains timing, resource, readiness, and failure eviden - public-macos-ax warm/quiet acquisition missed the 75/150 ms target. - public-macos-ax warm/list acquisition missed the 75/150 ms target. -- private-coresimulator-ax protocol probe returned unsupported-mechanism/private-tool-unavailable. +- The generated private candidate result only proved that no tool path was supplied. +- The post-run idb audit disproved the claim that a compatible private mechanism was unavailable + and passed the warm latency threshold on one detailed Settings screen. +- The overall verdict is therefore inconclusive. Public AX remains NO-GO; the idb-style persistent + guest bridge is GO for full-corpus evaluation, not yet GO for production. ## Next interface boundary -- Keep any future bridge behind the #2190 acquisition adapter and preserve raw facts until a separate GO evidence run proves fidelity, lifecycle, and latency. +- Adapt the idb-style persistent guest reader behind the #2190 acquisition boundary and run every + remaining #2192 state and screen cell while preserving raw facts. ## Production boundary - No production backend selection, fallback, runner-demand, open/relaunch, proxy, XCTest interaction, or public CLI changes were made. -- A production bridge should not start until this report has a GO result; this run is the #2192 boundary. +- Production routing remains blocked until the guest bridge passes the full correctness, lifecycle, + and latency corpus. The original zero-cell private result must not be used to close #2192.