diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml index 019f2c9ec..aa7be0077 100644 --- a/.github/workflows/size.yml +++ b/.github/workflows/size.yml @@ -44,6 +44,21 @@ jobs: run: | mkdir -p /tmp/agent-device-size-report cp scripts/size-report*.mjs /tmp/agent-device-size-report/ + cp scripts/prepare-publish-assets.mjs /tmp/agent-device-size-report/ + + - name: Install Android helper toolchain + run: | + SDK_ROOT="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-/usr/local/lib/android/sdk}}" + SDKMANAGER="$SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" + if [ ! -x "$SDKMANAGER" ]; then + SDKMANAGER="$SDK_ROOT/cmdline-tools/bin/sdkmanager" + fi + if [ ! -x "$SDKMANAGER" ]; then + echo "sdkmanager not found under $SDK_ROOT" >&2 + exit 1 + fi + yes | "$SDKMANAGER" --licenses >/dev/null || true + "$SDKMANAGER" "platforms;android-36" "build-tools;36.0.0" # dist is fully determined by the base commit, so reuse it across PR runs # against the same base. Startup medians are still measured fresh on this diff --git a/package.json b/package.json index e4018d526..17b4ded73 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,8 @@ "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: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", + "prepare:publish-assets": "node scripts/prepare-publish-assets.mjs", + "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 prepare:publish-assets", "package:npm": "pnpm build:package && pnpm check:package", "release:prepare": "node scripts/release-mark-dev.mjs --check-release-version && rm -rf .tmp/release && pnpm check:mcp-metadata && pnpm build:package && pnpm check:package -- --pack-destination .tmp/release", "release:publish": "pnpm release:prepare && npm publish --ignore-scripts .tmp/release/*.tgz && pnpm release:mark-dev", @@ -120,6 +121,8 @@ "test:ios-snapshot-differential": "node --experimental-strip-types scripts/swift-toolchain-tmpdir.ts swift test --package-path apple/snapshot-presentation && node --experimental-strip-types scripts/node-test-tmpdir.ts --experimental-strip-types --test scripts/ios-snapshot-differential.test.ts", "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-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", "mutation:affected": "node --experimental-strip-types scripts/mutation/run.ts --affected", diff --git a/src/__tests__/eager-closure-budgets.test.ts b/scripts/__tests__/eager-closure-budgets.test.ts similarity index 98% rename from src/__tests__/eager-closure-budgets.test.ts rename to scripts/__tests__/eager-closure-budgets.test.ts index e0e243c74..ddcb54d80 100644 --- a/src/__tests__/eager-closure-budgets.test.ts +++ b/scripts/__tests__/eager-closure-budgets.test.ts @@ -3,7 +3,7 @@ import { execFileSync } from 'node:child_process'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { eagerClosureGraphOf } from './eager-import-closure.fixtures.ts'; +import { eagerClosureGraphOf } from '../../src/__tests__/eager-import-closure.fixtures.ts'; import { classifyBudget, describeClosurePressure, @@ -22,7 +22,8 @@ import { * ADR-0019 requires platform-package façades to stay implementation-lazy and is explicit that a * startup threshold alone is not a substitute for preserving the loading shape: "the tracking * issue owns the exact probe and planted-red procedure." #1950 built the walker this file reuses - * (`eager-import-closure.fixtures.ts`, AST-level: static value edges plus top-level dynamic + * (`src/__tests__/eager-import-closure.fixtures.ts`, AST-level: static value edges plus top-level + * dynamic * imports, type-only erased) and proved the planted-red procedure on one file. This is that * probe, generalized to every workspace-package entry surface plus designated hub modules. * diff --git a/src/__tests__/eager-closure-budgets.ts b/scripts/__tests__/eager-closure-budgets.ts similarity index 99% rename from src/__tests__/eager-closure-budgets.ts rename to scripts/__tests__/eager-closure-budgets.ts index 682dd723b..6417e2aac 100644 --- a/src/__tests__/eager-closure-budgets.ts +++ b/scripts/__tests__/eager-closure-budgets.ts @@ -4,7 +4,8 @@ // implementation-lazy and is explicit that a startup-time threshold alone is not a substitute for // preserving the loading shape (`docs/adr/0019-request-bound-platform-runtime.md`): "the tracking // issue owns the exact probe and planted-red procedure." #1950 built the AST-level walker -// (`eager-import-closure.fixtures.ts`); #1959/#1969 fixed two more instances of the regression +// (`src/__tests__/eager-import-closure.fixtures.ts`); #1959/#1969 fixed two more instances of the +// regression // class by hand. This table generalizes the proof: every package entry surface gets an exact pin // on how many repo modules importing it evaluates, plus a standing assertion that the closure // never reaches a concrete platform implementation before discovery/binding selects one. @@ -22,7 +23,7 @@ // enforced by the compiler instead of by a runtime check that a `Set` conversion would hide. import path from 'node:path'; -import { facadeEntryFiles } from '../../scripts/layering/package-boundaries.ts'; +import { facadeEntryFiles } from '../layering/package-boundaries.ts'; export type EagerClosureBudget = { /** Stable label for test names and failure messages -- the entry's repo-relative path. */ diff --git a/scripts/__tests__/fixtures/size-report-npm-pack.json b/scripts/__tests__/fixtures/size-report-npm-pack.json index 1a94d8903..3bac3f782 100644 --- a/scripts/__tests__/fixtures/size-report-npm-pack.json +++ b/scripts/__tests__/fixtures/size-report-npm-pack.json @@ -1,5 +1,5 @@ { - "unpackedSize": 1814, + "unpackedSize": 2319, "files": [ { "path": "dist/src/index.js", "size": 401 }, { "path": "dist/src/index.d.ts", "size": 102 }, @@ -7,6 +7,9 @@ { "path": "dist/apple/snapshot-presentation/Package.swift", "size": 113 }, { "path": "apple/macos-helper/Sources/main.swift", "size": 211 }, { "path": "android/snapshot-helper/dist/helper.apk", "size": 307 }, + { "path": "android/snapshot-helper/dist/helper.manifest.json", "size": 99 }, + { "path": "android/ime-helper/dist/helper.apk", "size": 307 }, + { "path": "android/ime-helper/dist/helper.manifest.json", "size": 99 }, { "path": "package.json", "size": 99 }, { "path": "vendor/unknown.bin", "size": 78 } ] diff --git a/scripts/__tests__/prepare-publish-assets.test.ts b/scripts/__tests__/prepare-publish-assets.test.ts new file mode 100644 index 000000000..1846b3810 --- /dev/null +++ b/scripts/__tests__/prepare-publish-assets.test.ts @@ -0,0 +1,47 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { test } from 'vitest'; +import { mkdtempForTestSync } from '../../src/__tests__/test-utils/tmp-dir.ts'; +import { preparePublishAssets } from '../prepare-publish-assets.mjs'; + +test('prepares both Android runtime helpers through the shared publish owner', () => { + const root = mkdtempForTestSync('agent-device-publish-assets-'); + const scriptsDirectory = path.join(root, 'scripts'); + fs.mkdirSync(scriptsDirectory, { recursive: true }); + fs.writeFileSync(path.join(root, 'package.json'), '{"version":"1.2.3"}\n'); + fs.writeFileSync(path.join(scriptsDirectory, 'package-apple-runner-source.mjs'), ''); + fs.writeFileSync( + path.join(scriptsDirectory, 'package-android-helper.sh'), + `#!/bin/sh +set -eu +if [ "$AGENT_DEVICE_ANDROID_HELPER" = "snapshot" ]; then + output="$3" +else + output="$2" +fi +mkdir -p "$output" +prefix="agent-device-android-$AGENT_DEVICE_ANDROID_HELPER-helper-$1" +printf apk > "$output/$prefix.apk" +printf manifest > "$output/$prefix.manifest.json" +printf checksum > "$output/$prefix.apk.sha256" +`, + ); + + const stalePath = path.join(root, 'android', 'ime-helper', 'dist', 'stale.apk'); + fs.mkdirSync(path.dirname(stalePath), { recursive: true }); + fs.writeFileSync(stalePath, 'stale'); + + preparePublishAssets({ root }); + + assert.equal(fs.existsSync(stalePath), false); + for (const helper of ['snapshot', 'ime']) { + const prefix = `agent-device-android-${helper}-helper-1.2.3`; + const directory = path.join(root, 'android', `${helper}-helper`, 'dist'); + assert.deepEqual(fs.readdirSync(directory).sort(), [ + `${prefix}.apk`, + `${prefix}.apk.sha256`, + `${prefix}.manifest.json`, + ]); + } +}); diff --git a/scripts/__tests__/size-report-package.test.ts b/scripts/__tests__/size-report-package.test.ts index e149254f5..b5db3c066 100644 --- a/scripts/__tests__/size-report-package.test.ts +++ b/scripts/__tests__/size-report-package.test.ts @@ -3,7 +3,11 @@ import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; import { test } from 'vitest'; import { formatMarkdown } from '../size-report.mjs'; -import { classifyNpmPackEntry, summarizeNpmPackComponents } from '../size-report-package.mjs'; +import { + assertPublishPackageContents, + classifyNpmPackEntry, + summarizeNpmPackComponents, +} from '../size-report-package.mjs'; const fixturePack = JSON.parse( await readFile(join(import.meta.dirname, 'fixtures', 'size-report-npm-pack.json'), 'utf8'), @@ -21,6 +25,9 @@ test('classifies every shipped entry into one named component', () => { ['dist/apple/snapshot-presentation/Package.swift', 'apple-snapshot-presentation'], ['apple/macos-helper/Sources/main.swift', 'macos-helper'], ['android/snapshot-helper/dist/helper.apk', 'android-helpers'], + ['android/snapshot-helper/dist/helper.manifest.json', 'android-helpers'], + ['android/ime-helper/dist/helper.apk', 'android-helpers'], + ['android/ime-helper/dist/helper.manifest.json', 'android-helpers'], ['package.json', 'other'], ['vendor/unknown.bin', 'other'], ], @@ -34,6 +41,25 @@ test('unknown package paths fall into other', () => { ); }); +test('publish package requires both Android helpers and excludes benchmark scripts', () => { + assert.doesNotThrow(() => assertPublishPackageContents(fixturePack.files)); + assert.throws( + () => + assertPublishPackageContents( + fixturePack.files.filter((entry) => !entry.path.startsWith('android/ime-helper/')), + ), + /android\/ime-helper/, + ); + assert.throws( + () => + assertPublishPackageContents([ + ...fixturePack.files, + { path: 'scripts/ios-snapshot-benchmark/run.ts', size: 1 }, + ]), + /benchmark or build scripts/, + ); +}); + test('component bytes sum exactly to npm pack unpackedSize', () => { const components = summarizeNpmPackComponents(fixturePack); @@ -48,12 +74,12 @@ test('component bytes sum exactly to npm pack unpackedSize', () => { 'apple-runner': 503, 'apple-snapshot-presentation': 113, 'macos-helper': 211, - 'android-helpers': 307, + 'android-helpers': 812, other: 177, }, ); assert.throws( - () => summarizeNpmPackComponents({ ...fixturePack, unpackedSize: 1800 }), + () => summarizeNpmPackComponents({ ...fixturePack, unpackedSize: 2318 }), /does not match npm pack unpackedSize/, ); }); @@ -63,7 +89,7 @@ test('Markdown reports component diffs and changed packed files', () => { js: { rawBytes: 10, gzipBytes: 8 }, npmPack: { tarballBytes: 100, - unpackedBytes: 1814, + unpackedBytes: 2319, components: summarizeNpmPackComponents(fixturePack), entries: fixturePack.files, }, @@ -76,10 +102,10 @@ test('Markdown reports component diffs and changed packed files', () => { js: { rawBytes: 10, gzipBytes: 8 }, npmPack: { tarballBytes: 100, - unpackedBytes: 1713, + unpackedBytes: 2218, components: summarizeNpmPackComponents({ ...fixturePack, - unpackedSize: 1713, + unpackedSize: 2218, files: baseEntries, }), entries: baseEntries, diff --git a/scripts/ios-snapshot-benchmark/README.md b/scripts/ios-snapshot-benchmark/README.md new file mode 100644 index 000000000..e6550ea14 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/README.md @@ -0,0 +1,98 @@ +# iOS snapshot convergence evidence + +This harness owns the reproducible evidence contract for [#2189](https://github.com/callstack/agent-device/issues/2189), which supplies measurements to [#2188](https://github.com/callstack/agent-device/issues/2188). It does not change daemon, runner, snapshot, or package runtime behavior. + +## Prepare a real target + +Use a dedicated iOS Simulator and the checked-in test app. Build the CLI and app before measuring: + +```sh +pnpm install --frozen-lockfile +pnpm build +pnpm test-app:install +pnpm test-app:ios -- --device "bench-golden-v1" +``` + +The app build must succeed on the host. If signing, Xcode, XCTest, simulator, runner, or daemon setup cannot be made deterministic, stop and attach the exact command, target, toolchain, and diagnostic; do not report fixture-only timings. + +## Local state matrix + +Replace `SIMULATOR_UDID` with the dedicated simulator UDID. The default screen set is quiet, list, nested-scroll, alert, system-surface, and xctest-stress. Cold cells require at least 10 samples; warm and relaunch cells require at least 20. + +```sh +pnpm bench:ios-snapshot -- \ + --mode local \ + --udid SIMULATOR_UDID \ + --state cold-cold,cold,warm,relaunch \ + --screen quiet,list,nested-scroll,alert,system-surface,xctest-stress \ + --samples 20 \ + --out .tmp/ios-snapshot-convergence.v1.json +``` + +The cells mean: + +- `cold-cold`: simulator off, daemon off, derived runner data cleared before each sample. +- `cold`: simulator booted, daemon stopped, and app terminated before each sample. +- `warm`: app, daemon, runner, and target are prepared once; each sample is a fresh CLI snapshot. +- `relaunch`: the same prepared tooling is retained while each sample launches a new app process. + +Every sample keeps daemon duration and fresh-process wall time separately, the first-tree status, response bytes, target generation, and typed failure details. Each raw result also records the typed host model, model identifier, CPU, and core count needed to compare performance baselines. The raw JSON is validated against `raw-result.schema.v1.json`; the adjacent Markdown is a human-readable summary. + +Each local cell is admitted only after the simulator state, verified daemon identity, app process generation, and exact fixture anchor are checked. A mismatch stops the run with a typed cell-state or fixture-anchor reason. Derived data is cleared only below the benchmark-owned state directory. + +When `--state-dir` is omitted, the harness allocates a fresh marker-owned root under the host temporary directory. A caller-supplied state directory must already be a real, marker-owned directory; the CLI never initializes ownership for an existing path. Any explicit `--derived-path` must remain below that root. + +## Proxy matrix + +The proxy mode starts the repository proxy, then inserts a local deterministic conditioner in front of it. It runs both a persistent Node client and a fresh-process CLI at RTT 0, 20, and 80 ms. Request and response body bytes, failures, bandwidth, packet-loss rate, and seed are retained in the raw result. + +```sh +pnpm bench:ios-snapshot -- \ + --mode proxy \ + --udid SIMULATOR_UDID \ + --screen quiet \ + --rtt 0,20,80 \ + --samples 20 \ + --bandwidth-kbps unlimited \ + --packet-loss 0 \ + --out .tmp/ios-snapshot-proxy.v1.json +``` + +The conditioner is semantics-preserving at zero packet loss. Non-zero loss is an explicit failure experiment, not a successful baseline. + +The complete exact-head corpus from `bench-golden-v2` (iPhone 17 Pro, iOS 27.0) is retained under +[`evidence/`](./evidence/) from revision `71fb2483f30d90e615e949601c836aeebbf450c5`: + +- [`ios-snapshot-cold-local-71fb2483f.json`](./evidence/ios-snapshot-cold-local-71fb2483f.json) + covers cold-cold and cold lifecycle cells across all six screens with 10 samples per cell. +- [`ios-snapshot-warm-relaunch-local-71fb2483f.json`](./evidence/ios-snapshot-warm-relaunch-local-71fb2483f.json) + covers warm and relaunch lifecycle cells across all six screens with 20 samples per cell and + includes package-size measurements. +- [`ios-snapshot-proxy-71fb2483f.json`](./evidence/ios-snapshot-proxy-71fb2483f.json) covers + persistent-client and fresh-process CLI cells at RTT 0, 20, and 80 ms with 20 samples per cell. + +Each JSON file is the schema-validated raw result from the commit named in its `revision` field; +each has an adjacent Markdown summary. Superseded pre-admission captures are not part of the +published corpus. + +## Package-size evidence + +`pnpm size --json .tmp/size.json --markdown .tmp/size.md` prepares the same Apple and Android +publish assets used by `pnpm build:package`, then measures bundled JavaScript, packed tarball, +packed unpacked tree, and the package tree after a clean `npm install` into an isolated consumer. +The report rejects packages missing either Android helper or containing benchmark/build scripts. +The iOS harness includes those three package measurements unless `--skip-package-size` is supplied. + +## Permanent deep-button control + +This is an implementation-independent control for [#1626](https://github.com/callstack/agent-device/issues/1626): the checked-in `deep-button-fixture.v1.json` artifact contains a 72-level ancestor chain and independently recorded shallow/full outputs. The changed leaf is intentionally omitted by the shallow observation, so a no-effect assertion must fail. The full observation includes the leaf and passes. + +```sh +pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow +# expected exit 1: +# AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid. +pnpm bench:ios-snapshot:deep-button -- --rule safe-full +# expected exit 0 +``` + +The schema links [#1571](https://github.com/callstack/agent-device/issues/1571) so an unreadable or empty first tree remains distinct from bridge, runner, timeout, stale-generation, packet-loss, and upstream failures. This harness does not modify either issue’s runtime behavior. diff --git a/scripts/ios-snapshot-benchmark/benchmark-config.test.ts b/scripts/ios-snapshot-benchmark/benchmark-config.test.ts new file mode 100644 index 000000000..fc3f72d42 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/benchmark-config.test.ts @@ -0,0 +1,66 @@ +import assert from 'node:assert/strict'; +import path from 'node:path'; +import { test } from 'vitest'; +import { mkdtempForTest } from '../../src/__tests__/test-utils/tmp-dir.ts'; +import { parseConfig } from './benchmark-config.ts'; +import { createBenchmarkStateRoot } from './state-ownership.ts'; + +test('proxy measurements retain the warm sample minimum', async () => { + const stateDir = createBenchmarkStateRoot(); + const args = [ + '--mode', + 'proxy', + '--udid', + 'simulator', + '--state', + 'cold', + '--state-dir', + stateDir, + ]; + assert.throws(() => parseConfig([...args, '--samples', '10']), /at least 20/); + assert.equal(parseConfig([...args, '--samples', '20']).samples, 20); +}); + +test('unknown benchmark flags fail closed', async () => { + const stateDir = createBenchmarkStateRoot(); + assert.throws( + () => parseConfig(['--udid', 'simulator', '--state-dir', stateDir, '--unknown']), + /Unknown option: --unknown/, + ); +}); + +test('derived data is confined to the owned benchmark state directory', async () => { + const stateDir = createBenchmarkStateRoot(); + assert.doesNotThrow(() => + parseConfig([ + '--udid', + 'simulator', + '--state-dir', + stateDir, + '--derived-path', + path.join(stateDir, 'derived-data', 'cell'), + ]), + ); + assert.throws( + () => + parseConfig([ + '--udid', + 'simulator', + '--state-dir', + stateDir, + '--derived-path', + path.join(stateDir, '..', 'unowned-derived-data'), + ]), + /descendant of the benchmark state directory/, + ); +}); + +test('caller-supplied state directories must already be benchmark-owned', async () => { + const unmarked = await mkdtempForTest('agent-device-ios-benchmark-unmarked-'); + assert.throws( + () => parseConfig(['--udid', 'simulator', '--state-dir', unmarked]), + /not benchmark-owned/, + ); + const stateDir = createBenchmarkStateRoot(); + assert.equal(parseConfig(['--udid', 'simulator', '--state-dir', stateDir]).stateDir, stateDir); +}); diff --git a/scripts/ios-snapshot-benchmark/benchmark-config.ts b/scripts/ios-snapshot-benchmark/benchmark-config.ts new file mode 100644 index 000000000..777beb2c3 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/benchmark-config.ts @@ -0,0 +1,250 @@ +import path from 'node:path'; +import { parseLocalStates, parseRtt, parseSampleCount, parseScreenIds } from './definitions.ts'; +import { resolveRepoRoot } from './host.ts'; +import { + assertBenchmarkOwner, + assertOwnedDerivedPath, + createBenchmarkStateRoot, +} from './state-ownership.ts'; +import type { LocalState, ScreenId } from './types.ts'; + +export class BenchmarkConfigurationError extends Error {} + +export type BenchmarkConfig = { + repoRoot: string; + mode: 'local' | 'proxy' | 'all'; + udid: string; + appId: string; + appPath?: string; + stateDir: string; + outputPath: string; + derivedPath: string; + screens: ScreenId[]; + states: LocalState[]; + samples: number; + rtts: readonly number[]; + bandwidthKbps: number | null; + packetLossPercent: number; + seed: number; + skipPackageSize: boolean; + keepDevice: boolean; +}; + +type ParsedArguments = { values: Map; booleans: Set }; +type ParsedOption = { flag: string; value?: string; boolean: boolean }; + +const DEFAULT_APP_ID = 'com.callstack.agentdevicelab'; +const MODES: ReadonlySet = new Set(['local', 'proxy', 'all']); +const BOOLEAN_FLAGS = new Set(['--skip-package-size', '--keep-device']); +const VALUE_FLAGS = new Set([ + '--mode', + '--udid', + '--app-id', + '--app-path', + '--state-dir', + '--derived-path', + '--out', + '--screen', + '--state', + '--samples', + '--rtt', + '--bandwidth-kbps', + '--packet-loss', + '--seed', +]); + +export function parseConfig(argv: string[]): BenchmarkConfig { + const arguments_ = parseArguments(argv); + const mode = readMode(arguments_.values.get('--mode')); + const udid = requireValue(arguments_.values, '--udid'); + const cells = readCells(arguments_.values, mode); + const paths = readPaths(arguments_.values); + const network = readNetwork(arguments_.values); + return { + repoRoot: resolveRepoRoot(), + mode, + udid, + appId: arguments_.values.get('--app-id') ?? DEFAULT_APP_ID, + ...paths, + ...cells, + ...network, + skipPackageSize: arguments_.booleans.has('--skip-package-size'), + keepDevice: arguments_.booleans.has('--keep-device'), + }; +} + +function parseArguments(argv: string[]): ParsedArguments { + const normalized = argv[0] === '--' ? argv.slice(1) : argv; + exitForHelp(normalized); + const values = new Map(); + const booleans = new Set(); + for (let index = 0; index < normalized.length; index += 1) { + const option = readOption(normalized[index]!, normalized[index + 1]); + addOption(option, values, booleans); + if (!option.boolean) index += 1; + } + return { values, booleans }; +} + +function exitForHelp(argv: string[]): void { + if (!argv.includes('--help') && !argv.includes('-h')) return; + printHelp(); + process.exit(0); +} + +function addOption(option: ParsedOption, values: Map, booleans: Set): void { + if (option.boolean) { + booleans.add(option.flag); + return; + } + values.set(option.flag, option.value!); +} + +function readOption(arg: string, next: string | undefined): ParsedOption { + if (BOOLEAN_FLAGS.has(arg)) return { flag: arg, boolean: true }; + if (!arg.startsWith('--')) throw new BenchmarkConfigurationError(`Unexpected argument: ${arg}`); + if (!VALUE_FLAGS.has(arg)) throw new BenchmarkConfigurationError(`Unknown option: ${arg}`); + return { flag: arg, value: requireNextValue(arg, next), boolean: false }; +} + +function requireNextValue(flag: string, value: string | undefined): string { + if (!value || value.startsWith('--')) { + throw new BenchmarkConfigurationError(`${flag} requires a value.`); + } + return value; +} + +function readMode(value: string | undefined): BenchmarkConfig['mode'] { + const mode = value ?? 'local'; + if (!MODES.has(mode as BenchmarkConfig['mode'])) { + throw new BenchmarkConfigurationError(`--mode must be local, proxy, or all (got ${mode}).`); + } + return mode as BenchmarkConfig['mode']; +} + +function requireValue(values: Map, flag: string): string { + const value = values.get(flag); + if (!value) throw new BenchmarkConfigurationError(`${flag} is required for a reproducible run.`); + return value; +} + +function readCells( + values: Map, + mode: BenchmarkConfig['mode'], +): { + states: LocalState[]; + screens: ScreenId[]; + samples: number; +} { + try { + const states = parseLocalStates(values.get('--state')); + return { + states, + screens: parseScreenIds(values.get('--screen')), + samples: parseSampleCount(values.get('--samples'), sampleMinimumStates(states, mode)), + }; + } catch (error) { + throw new BenchmarkConfigurationError(error instanceof Error ? error.message : String(error)); + } +} + +function sampleMinimumStates(states: LocalState[], mode: BenchmarkConfig['mode']): LocalState[] { + return mode === 'local' ? states : [...states, 'warm']; +} + +function readPaths( + values: Map, +): Pick { + const stateDir = values.has('--state-dir') + ? resolvePath(values.get('--state-dir'), '') + : createBenchmarkStateRoot(); + const appPath = values.get('--app-path'); + const derivedPath = resolvePath( + values.get('--derived-path'), + path.join(stateDir, 'derived-data'), + ); + try { + assertBenchmarkOwner(stateDir); + assertOwnedDerivedPath(derivedPath, stateDir); + } catch (error) { + throw new BenchmarkConfigurationError(error instanceof Error ? error.message : String(error)); + } + return { + stateDir, + outputPath: resolvePath( + values.get('--out'), + path.join(stateDir, 'ios-snapshot-convergence.v1.json'), + ), + derivedPath, + ...optionalAppPath(appPath), + }; +} + +function resolvePath(value: string | undefined, fallback: string): string { + return path.resolve(value ?? fallback); +} + +function optionalAppPath(appPath: string | undefined): Pick { + return appPath === undefined ? {} : { appPath }; +} + +function readNetwork( + values: Map, +): Pick { + const packetLoss = values.get('--packet-loss') ?? '0'; + const seed = values.get('--seed') ?? '2189'; + return { + rtts: parseRtt(values.get('--rtt')), + bandwidthKbps: readBandwidth(values.get('--bandwidth-kbps')), + packetLossPercent: parseNumber(packetLoss, '--packet-loss', 0, 100), + seed: parsePositiveInteger(seed, '--seed'), + }; +} + +function readBandwidth(value: string | undefined): number | null { + if (value === undefined || value === 'unlimited') return null; + return parsePositiveInteger(value, '--bandwidth-kbps'); +} + +function parsePositiveInteger(value: string, flag: string): number { + const parsed = Number(value); + if (!Number.isInteger(parsed) || parsed < 1) { + throw new BenchmarkConfigurationError(`${flag} must be an integer >= 1.`); + } + return parsed; +} + +function parseNumber(value: string, flag: string, minimum: number, maximum: number): number { + const parsed = Number(value); + if (!Number.isFinite(parsed) || parsed < minimum || parsed > maximum) { + throw new BenchmarkConfigurationError(`${flag} must be between ${minimum} and ${maximum}.`); + } + return parsed; +} + +function printHelp(): void { + process.stdout.write(`Usage: pnpm bench:ios-snapshot -- [options] + +Capture runner-backed iOS Simulator snapshot convergence evidence and raw JSON. + +Required: + --udid + +Options: + --mode local|proxy|all Measurement transport (default local). + --app-id Target bundle identifier (default fixture app). + --app-path Optional target artifact path recorded in metadata. + --screen quiet,list,nested-scroll,alert,system-surface,xctest-stress. + --state cold-cold,cold,warm,relaunch. + --samples At least 10 cold or 20 warm/relaunch samples. + --rtt Proxy RTT cells: 0,20,80 (default all). + --bandwidth-kbps + --packet-loss Deterministic loss rate for proxy requests. + --seed Deterministic proxy loss seed. + --state-dir Existing pre-marked benchmark state directory; omit for a fresh root. + --derived-path Isolated iOS XCTest derived-data path. + --out Raw JSON output path. + --skip-package-size Omit packed/clean-installed/bundled measurement. + --keep-device Leave the selected simulator booted. +`); +} diff --git a/scripts/ios-snapshot-benchmark/cell-admission.ts b/scripts/ios-snapshot-benchmark/cell-admission.ts new file mode 100644 index 000000000..7733a26b6 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/cell-admission.ts @@ -0,0 +1,236 @@ +import fs from 'node:fs'; +import { resolveDaemonPaths } from '../../src/daemon/config.ts'; +import { readDaemonInfo } from '../../src/daemon/client/daemon-client-metadata.ts'; +import { isAgentDeviceDaemonProcess } from '../../src/daemon/daemon-process.ts'; +import { + openFixture, + pressFixtureTarget, + scrollFixtureSetup, + snapshotFixture, + type CliContext, + type CliResult, +} from './command.ts'; +import { + fixtureOperationFromCli, + prepareFixture, + requireFixtureAnchor, + requireFixtureOperationSuccess, +} from './fixture-admission.ts'; +import { + BenchmarkCellAdmissionError, + bootSimulator, + readRunningAppPids, + readSimulatorState, + shutdownSimulator, + stopDaemon, + terminateApp, +} from './lifecycle.ts'; +import { clearDerivedData } from './state-ownership.ts'; +import type { LocalState, ScreenFixture } from './types.ts'; + +export type CellAdmissionOptions = { + repoRoot: string; + stateDir: string; + derivedPath: string; + udid: string; + samples: number; + state: LocalState; + fixture: ScreenFixture; +}; + +export function prepareCellState(options: CellAdmissionOptions): void { + if (options.state === 'cold-cold') { + prepareColdColdState(options); + return; + } + stopDaemon(options.repoRoot, options.stateDir); + assertDaemonStopped(options.stateDir); + bootSimulator(options.udid); + assertSimulatorState(options.udid, 'Booted'); + if (options.state === 'cold') { + terminateApp(options.udid, options.fixture.app); + assertAppStopped(options.udid, options.fixture.app); + } +} + +export function prepareSampleState(options: CellAdmissionOptions): void { + if (options.state === 'cold-cold') { + prepareColdColdState(options); + return; + } + if (options.state === 'cold') { + stopDaemon(options.repoRoot, options.stateDir); + assertDaemonStopped(options.stateDir); + terminateApp(options.udid, options.fixture.app); + assertAppStopped(options.udid, options.fixture.app); + return; + } + assertReadyState(options); +} + +export async function admitReadyCell( + context: CliContext, + options: CellAdmissionOptions, +): Promise { + if (options.state !== 'warm' && options.state !== 'relaunch') return undefined; + const opened = openFixture(context, options.fixture, { relaunch: true }); + requireFixtureOperationSuccess( + fixtureOperationFromCli(opened, `${options.state} ${options.fixture.id} setup`), + `${options.state} ${options.fixture.id} setup`, + 'cell-state', + ); + return await admitOpenedFixture(context, options); +} + +export async function admitSuccessfulSample( + context: CliContext, + options: CellAdmissionOptions, + result: CliResult, + previousAppPid: number | undefined, +): Promise { + if (!result.ok) return previousAppPid; + if (options.state === 'warm') { + return admitWarmSample(options, result, previousAppPid); + } + return await admitNonWarmSample(context, options, previousAppPid); +} + +export function cleanupSuccessfulSample(context: CliContext, options: CellAdmissionOptions): void { + if (options.state !== 'relaunch' || options.fixture.setupAction !== 'open-alert') return; + const dismissed = pressFixtureTarget(context, 'label="Cancel"'); + requireFixtureOperationSuccess( + fixtureOperationFromCli(dismissed, 'agent-device click label="Cancel"'), + `${options.fixture.id} sample cleanup`, + 'cell-state', + ); +} + +async function admitNonWarmSample( + context: CliContext, + options: CellAdmissionOptions, + previousAppPid: number | undefined, +): Promise { + const appPid = await admitOpenedFixture(context, options); + if (options.state !== 'relaunch') return appPid; + if (previousAppPid === appPid) { + throw new BenchmarkCellAdmissionError( + 'cell-state', + `Relaunch cell ${options.fixture.id} reused app PID ${String(appPid)}.`, + 'agent-device open --relaunch', + ); + } + return appPid; +} + +function prepareColdColdState(options: CellAdmissionOptions): void { + stopDaemon(options.repoRoot, options.stateDir); + assertDaemonStopped(options.stateDir); + shutdownSimulator(options.udid); + assertSimulatorState(options.udid, 'Shutdown'); + clearDerivedData(options.derivedPath, options.stateDir); + bootSimulator(options.udid); + assertSimulatorState(options.udid, 'Booted'); + assertAppStopped(options.udid, options.fixture.app); +} + +function admitWarmSample( + options: CellAdmissionOptions, + result: CliResult, + previousAppPid: number | undefined, +): number { + assertReadyState(options); + requireFixtureAnchor(result.payload, options.fixture, 'sample'); + const appPid = assertAppRunning(options.udid, options.fixture.app); + if (previousAppPid !== undefined && 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; +} + +async function admitOpenedFixture( + context: CliContext, + options: CellAdmissionOptions, +): Promise { + assertSimulatorState(options.udid, 'Booted'); + assertDaemonRunning(options.stateDir); + assertAppRunning(options.udid, options.fixture.app); + await prepareFixture(options.fixture, { + observe: () => + fixtureOperationFromCli(snapshotFixture(context), 'agent-device batch --steps snapshot'), + scrollToBottom: () => + fixtureOperationFromCli(scrollFixtureSetup(context), 'agent-device scroll bottom'), + openAlert: () => + fixtureOperationFromCli( + pressFixtureTarget(context, 'id="automation-open-alert"'), + 'agent-device click id="automation-open-alert"', + ), + }); + const appPid = assertAppRunning(options.udid, options.fixture.app); + return appPid; +} + +function assertReadyState(options: CellAdmissionOptions): void { + assertSimulatorState(options.udid, 'Booted'); + assertDaemonRunning(options.stateDir); + assertAppRunning(options.udid, options.fixture.app); +} + +function assertSimulatorState(udid: string, expected: string): void { + const actual = readSimulatorState(udid); + if (actual !== expected) { + throw new BenchmarkCellAdmissionError( + 'cell-state', + `Simulator ${udid} was ${actual}, expected ${expected}.`, + `xcrun simctl list devices available --json`, + ); + } +} + +function assertDaemonStopped(stateDir: string): void { + const paths = resolveDaemonPaths(stateDir); + if (fs.existsSync(paths.infoPath) || fs.existsSync(paths.lockPath)) { + throw new BenchmarkCellAdmissionError( + 'cell-state', + `Daemon state remained active in ${stateDir}.`, + 'agent-device daemon stop --clean', + ); + } +} + +function assertDaemonRunning(stateDir: string): void { + const info = readDaemonInfo(resolveDaemonPaths(stateDir).infoPath); + if (!info?.processStartTime || !isAgentDeviceDaemonProcess(info.pid, info.processStartTime)) { + throw new BenchmarkCellAdmissionError( + 'cell-state', + `Daemon admission failed for ${stateDir}; no verified daemon identity is running.`, + 'agent-device daemon status', + ); + } +} + +function assertAppStopped(udid: string, appId: string): void { + const pids = readRunningAppPids(udid, appId); + if (pids.length > 0) { + throw new BenchmarkCellAdmissionError( + 'cell-state', + `App ${appId} remained running on simulator ${udid}: ${pids.join(', ')}.`, + `xcrun simctl spawn ${udid} launchctl list`, + ); + } +} + +function assertAppRunning(udid: string, appId: string): number { + const pids = readRunningAppPids(udid, appId); + if (pids.length !== 1) { + throw new BenchmarkCellAdmissionError( + 'cell-state', + `Expected one running ${appId} process on ${udid}; observed ${pids.length}.`, + `xcrun simctl spawn ${udid} launchctl list`, + ); + } + return pids[0]!; +} diff --git a/scripts/ios-snapshot-benchmark/cli-process.test.ts b/scripts/ios-snapshot-benchmark/cli-process.test.ts new file mode 100644 index 000000000..fd314ac9d --- /dev/null +++ b/scripts/ios-snapshot-benchmark/cli-process.test.ts @@ -0,0 +1,32 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { test } from 'vitest'; +import { mkdtempForTest } from '../../src/__tests__/test-utils/tmp-dir.ts'; +import { classifyFailure } from './command.ts'; +import { runCliAsync } from './cli-process.ts'; + +test('preserves timeout classification when execFile reports no string error code', async () => { + const repoRoot = await mkdtempForTest('agent-device-ios-benchmark-timeout-'); + fs.mkdirSync(path.join(repoRoot, 'bin'), { recursive: true }); + fs.writeFileSync( + path.join(repoRoot, 'bin/agent-device.mjs'), + 'setTimeout(() => undefined, 1000);\n', + ); + + const result = await runCliAsync( + { + repoRoot, + stateDir: path.join(repoRoot, 'state'), + session: 'timeout-test', + udid: 'timeout-test', + derivedPath: path.join(repoRoot, 'derived'), + }, + ['noop'], + 100, + ); + + assert.equal(result.ok, false); + assert.equal(result.spawnErrorCode, 'ETIMEDOUT'); + assert.equal(classifyFailure(result.payload, result).category, 'timeout'); +}); diff --git a/scripts/ios-snapshot-benchmark/cli-process.ts b/scripts/ios-snapshot-benchmark/cli-process.ts new file mode 100644 index 000000000..55b70b3dc --- /dev/null +++ b/scripts/ios-snapshot-benchmark/cli-process.ts @@ -0,0 +1,169 @@ +import { execFile, spawnSync } from 'node:child_process'; +import { performance } from 'node:perf_hooks'; +import { asRecord, readString } from './result-values.ts'; + +const MAX_BUFFER = 64 * 1024 * 1024; + +export type CliResult = { + exitCode: number; + startedAt: string; + finishedAt: string; + wallClockMs: number; + stdout: string; + stderr: string; + payload: unknown; + ok: boolean; + spawnErrorCode?: string; +}; + +export type CliContext = { + repoRoot: string; + stateDir: string; + session: string; + udid: string; + derivedPath: string; + extraFlags?: string[]; +}; + +export function runCli(context: CliContext, args: string[], timeoutMs = 300_000): CliResult { + const argv = buildArgv(context, args); + const startedAt = new Date().toISOString(); + const started = performance.now(); + const result = spawnSync(process.execPath, argv, { + cwd: context.repoRoot, + env: { ...process.env, AGENT_DEVICE_NO_UPDATE_NOTIFIER: '1' }, + encoding: 'utf8', + maxBuffer: MAX_BUFFER, + timeout: timeoutMs, + }); + return buildResult({ + startedAt, + started, + exitCode: typeof result.status === 'number' ? result.status : -1, + stdout: result.stdout, + stderr: result.stderr, + error: result.error, + }); +} + +export async function runCliAsync( + context: CliContext, + args: string[], + timeoutMs = 300_000, +): Promise { + const argv = buildArgv(context, args); + const startedAt = new Date().toISOString(); + const started = performance.now(); + return await new Promise((resolve) => { + execFile( + process.execPath, + argv, + { + cwd: context.repoRoot, + env: { ...process.env, AGENT_DEVICE_NO_UPDATE_NOTIFIER: '1' }, + encoding: 'utf8', + maxBuffer: MAX_BUFFER, + timeout: timeoutMs, + }, + (error, stdout, stderr) => { + resolve( + buildResult({ + startedAt, + started, + exitCode: typeof error?.code === 'number' ? error.code : error ? -1 : 0, + stdout, + stderr, + error, + }), + ); + }, + ); + }); +} + +function buildArgv(context: CliContext, args: string[]): string[] { + return ['bin/agent-device.mjs', ...args, ...baseFlags(context), '--json']; +} + +function buildResult(options: { + startedAt: string; + started: number; + exitCode: number; + stdout: string | Buffer | null; + stderr: string | Buffer | null; + error?: Error | null; +}): CliResult { + const stdout = readOutput(options.stdout); + const stderr = readOutput(options.stderr); + const spawnErrorCode = readAsyncErrorCode(options.error); + const spawnError = options.error ? `${options.error.name}: ${options.error.message}` : ''; + const payload = parseJson(stdout); + return { + exitCode: options.exitCode, + startedAt: options.startedAt, + finishedAt: new Date().toISOString(), + wallClockMs: performance.now() - options.started, + stdout, + stderr: [stderr, spawnError].filter(Boolean).join('\n'), + payload, + ok: options.exitCode === 0 && !isExplicitFailure(payload) && !isBatchStepFailure(payload), + ...(spawnErrorCode ? { spawnErrorCode } : {}), + }; +} + +function readAsyncErrorCode(error: Error | null | undefined): string | undefined { + const processError = error as + | (NodeJS.ErrnoException & { killed?: boolean; signal?: NodeJS.Signals | null }) + | null + | undefined; + if (processError?.killed && processError.signal === 'SIGTERM') return 'ETIMEDOUT'; + return readString(processError?.code); +} + +function baseFlags(context: CliContext): string[] { + return [ + '--state-dir', + context.stateDir, + '--session', + context.session, + '--platform', + 'ios', + '--udid', + context.udid, + '--ios-xctest-derived-data-path', + context.derivedPath, + ...(context.extraFlags ?? []), + ]; +} + +function readOutput(value: string | Buffer | null): string { + return typeof value === 'string' ? value : (value?.toString('utf8') ?? ''); +} + +function parseJson(value: string): unknown { + const trimmed = value.trim(); + if (!trimmed) return undefined; + try { + return JSON.parse(trimmed); + } catch { + const start = trimmed.indexOf('{'); + const end = trimmed.lastIndexOf('}'); + if (start < 0 || end <= start) return undefined; + try { + return JSON.parse(trimmed.slice(start, end + 1)); + } catch { + return undefined; + } + } +} + +function isExplicitFailure(value: unknown): boolean { + const record = asRecord(value); + return record?.ok === false || Boolean(asRecord(record?.data)?.initialSnapshotError); +} + +function isBatchStepFailure(value: unknown): boolean { + const results = asRecord(asRecord(value)?.data)?.results; + const first = Array.isArray(results) ? asRecord(results[0]) : undefined; + return first?.ok === false; +} diff --git a/scripts/ios-snapshot-benchmark/command.test.ts b/scripts/ios-snapshot-benchmark/command.test.ts new file mode 100644 index 000000000..3a3845092 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/command.test.ts @@ -0,0 +1,97 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { + classifyFailure, + firstTreeStatus, + hasDeepLinkConfirmation, + snapshotHasAnchor, +} from './command.ts'; + +test('classifies typed reasons without using error message text', () => { + assert.equal( + classifyFailure({ error: { code: 'COMMAND_FAILED', message: 'timeout-looking text' } }) + .category, + 'other', + ); + assert.equal( + classifyFailure({ + error: { + code: 'COMMAND_FAILED', + message: 'unrelated text', + details: { reason: 'stale_generation' }, + }, + }).category, + 'stale-generation', + ); + assert.equal( + classifyFailure({ + error: { code: 'COMMAND_FAILED', details: { reason: 'first_tree_unreadable' } }, + }).category, + 'app-mount', + ); +}); + +test('keeps empty, readable, unreadable, and unobserved first trees distinct', () => { + assert.equal(firstTreeStatus({ data: { nodes: [] } }), 'empty'); + assert.equal(firstTreeStatus({ data: { nodes: [{ ref: '@e1' }] } }), 'readable'); + assert.equal(firstTreeStatus({ error: { details: { reason: 'first_tree_empty' } } }), 'empty'); + assert.equal( + firstTreeStatus({ error: { details: { reason: 'first_tree_unreadable' } } }), + 'unreadable', + ); + assert.equal( + firstTreeStatus({ error: { details: { reason: 'bridge_unavailable' } } }), + 'not-observed', + ); +}); + +test('admits only an exact semantic anchor from snapshot node fields', () => { + const payload = { + data: { + results: [ + { + data: { + snapshot: { + nodes: [{ label: 'Automation lab' }, { value: 'secondary value' }], + }, + }, + }, + ], + }, + }; + assert.equal(snapshotHasAnchor(payload, 'Automation lab'), true); + assert.equal(snapshotHasAnchor(payload, 'secondary value'), true); + assert.equal(snapshotHasAnchor(payload, 'Automation'), false); + assert.equal( + snapshotHasAnchor( + { results: [{ data: { snapshot: { nodes: [{ label: 'Automation lab' }] } } }] }, + 'Automation lab', + ), + true, + ); +}); + +test('recognizes the first-install deep-link confirmation as a setup prompt', () => { + assert.equal( + hasDeepLinkConfirmation({ + data: { + results: [ + { + data: { + snapshot: { + nodes: [{ role: 'alert', label: 'Open in “Agent Device Tester”?' }], + }, + }, + }, + ], + }, + }), + true, + ); + assert.equal( + hasDeepLinkConfirmation({ + data: { results: [{ data: { snapshot: { nodes: [{ role: 'application' }] } } }] }, + }), + false, + ); +}); diff --git a/scripts/ios-snapshot-benchmark/command.ts b/scripts/ios-snapshot-benchmark/command.ts new file mode 100644 index 000000000..043351b94 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/command.ts @@ -0,0 +1,304 @@ +import { asRecord, readString } from './result-values.ts'; +import { runCli, runCliAsync, type CliContext, type CliResult } from './cli-process.ts'; +import type { Failure, FirstTreeStatus, RawSample, ScreenFixture } from './types.ts'; + +const APP_MOUNT_REASONS = new Set([ + 'app_mount_race', + 'app_not_mounted', + 'active_ax_application_missing', + 'first_tree_empty', + 'first_tree_unreadable', +]); +const BRIDGE_REASONS = new Set([ + 'bridge_unavailable', + 'bridge_request_failed', + 'metro_bridge_failed', +]); +const STALE_REASONS = new Set(['ref_frame_expired', 'stale_generation', 'stale_snapshot']); +const TIMEOUT_REASONS = new Set([ + 'request_timeout', + 'command_timeout', + 'prepare_deadline_expired', + 'runner_main_thread_execution_timeout', +]); +const RUNNER_REASONS = new Set([ + 'runner_health_failed', + 'runner_connect_failed_before_command_send', + 'runner_readiness_preflight_failed_before_command_send', + 'runner_reported_failure', + 'command_still_in_flight', +]); +const REASON_CATEGORIES: ReadonlyArray<[Set, Failure['category']]> = [ + [STALE_REASONS, 'stale-generation'], + [APP_MOUNT_REASONS, 'app-mount'], + [BRIDGE_REASONS, 'bridge'], + [TIMEOUT_REASONS, 'timeout'], + [RUNNER_REASONS, 'runner'], +]; +const TIMEOUT_CODES = new Set(['TIMEOUT', 'REQUEST_TIMEOUT', 'ETIMEDOUT']); + +export type { CliContext, CliResult } from './cli-process.ts'; + +export function openFixture( + context: CliContext, + fixture: ScreenFixture, + options: { relaunch?: boolean } = {}, +): CliResult { + const opened = runCli(context, [ + 'open', + fixture.app, + ...(options.relaunch ? ['--relaunch'] : []), + ...(fixture.launchUrl ? ['--launch-url', fixture.launchUrl] : []), + '--foreground', + ]); + if (!fixture.launchUrl || !hasDeepLinkConfirmation(opened.payload)) return opened; + const accepted = pressFixtureTarget(context, 'label="Open"'); + if (accepted.ok) return opened; + return { + ...opened, + ok: false, + stderr: [opened.stderr, accepted.stderr].filter(Boolean).join('\n'), + payload: accepted.payload, + }; +} + +export async function openFixtureAsync( + context: CliContext, + fixture: ScreenFixture, + options: { relaunch?: boolean } = {}, +): Promise { + const opened = await runCliAsync(context, [ + 'open', + fixture.app, + ...(options.relaunch ? ['--relaunch'] : []), + ...(fixture.launchUrl ? ['--launch-url', fixture.launchUrl] : []), + '--foreground', + ]); + if (!fixture.launchUrl || !hasDeepLinkConfirmation(opened.payload)) return opened; + const accepted = await pressFixtureTargetAsync(context, 'label="Open"'); + if (accepted.ok) return opened; + return { + ...opened, + ok: false, + stderr: [opened.stderr, accepted.stderr].filter(Boolean).join('\n'), + payload: accepted.payload, + }; +} + +export function snapshotFixture(context: CliContext): CliResult { + return runCli(context, [ + 'batch', + '--steps', + JSON.stringify([{ command: 'snapshot', input: { interactiveOnly: true } }]), + ]); +} + +export async function snapshotFixtureAsync(context: CliContext): Promise { + return await runCliAsync(context, [ + 'batch', + '--steps', + JSON.stringify([{ command: 'snapshot', input: { interactiveOnly: true } }]), + ]); +} + +export function pressFixtureTarget(context: CliContext, selector: string): CliResult { + return runCli(context, ['click', selector]); +} + +export function scrollFixtureSetup(context: CliContext): CliResult { + return runCli(context, ['scroll', 'bottom']); +} + +export async function pressFixtureTargetAsync( + context: CliContext, + selector: string, +): Promise { + return await runCliAsync(context, ['click', selector]); +} + +export async function scrollFixtureSetupAsync(context: CliContext): Promise { + return await runCliAsync(context, ['scroll', 'bottom']); +} + +export async function closeSessionAsync(context: CliContext): Promise { + await runCliAsync(context, ['close']); +} + +export function snapshotHasAnchor(payload: unknown, anchorText: string): boolean { + return snapshotNodes(payload).some((record) => { + return record.label === anchorText || record.value === anchorText; + }); +} + +export function hasDeepLinkConfirmation(payload: unknown): boolean { + return snapshotNodes(payload).some((record) => { + const role = readString(record.role); + const label = readString(record.label); + return role === 'alert' && label?.startsWith('Open in ') === true; + }); +} + +function snapshotNodes(payload: unknown): Record[] { + const snapshot = readSnapshotRecord(payload); + if (!snapshot || !Array.isArray(snapshot.nodes)) return []; + return snapshot.nodes.flatMap((node) => { + const record = asRecord(node); + return record ? [record] : []; + }); +} + +export function sampleFromCli( + result: CliResult, + operation: RawSample['operation'], + index: number, + responseBytes = Buffer.byteLength(result.stdout), +): RawSample { + const snapshot = readSnapshot(result.payload); + const failure = result.ok ? undefined : classifyFailure(result.payload, result); + const daemonDurationMs = readDaemonDuration(result.payload, operation); + return { + index: index + 1, + startedAt: result.startedAt, + finishedAt: result.finishedAt, + operation, + wallClockMs: result.wallClockMs, + ...(daemonDurationMs === undefined ? {} : { daemonDurationMs }), + responseBytes, + ...snapshotFields(snapshot), + targetGeneration: snapshot?.targetGeneration ?? null, + firstTree: firstTreeStatusForSample(snapshot, failure), + ok: result.ok, + outlier: false, + ...(failure ? { failure } : {}), + }; +} + +function snapshotFields(snapshot: { nodeCount: number } | undefined): { nodeCount?: number } { + return snapshot ? { nodeCount: snapshot.nodeCount } : {}; +} + +function firstTreeStatusForSample( + snapshot: { nodeCount: number } | undefined, + failure: Failure | undefined, +): FirstTreeStatus { + if (snapshot) return snapshot.nodeCount === 0 ? 'empty' : 'readable'; + if (failure?.reason === 'first_tree_empty') return 'empty'; + return failure?.category === 'app-mount' ? 'unreadable' : 'not-observed'; +} + +export function classifyFailure( + payload: unknown, + result?: Pick, +): Failure { + const error = readError(payload); + const code = readString(error?.code) ?? result?.spawnErrorCode; + const details = asRecord(error?.details); + const reason = readString(details?.reason); + const category = failureCategory(code, reason); + const message = readString(error?.message) ?? readString(result?.stderr); + return { + category, + ...(code ? { code } : {}), + ...(reason ? { reason } : {}), + ...(message ? { message: message.slice(0, 240) } : {}), + }; +} + +export function formatCliFailure( + operation: string, + failure: Failure, + result: Pick, +): string { + return `${operation} failed [${failureLabel(failure)}]: ${failureMessage(failure, result)}`; +} + +function failureLabel(failure: Failure): string { + return failure.code ? `${failure.category}/${failure.code}` : failure.category; +} + +function failureMessage(failure: Failure, result: Pick): string { + if (failure.message) return failure.message; + if (result.stderr.trim()) return result.stderr.trim(); + return `exit ${result.exitCode}`; +} + +export function firstTreeStatus(payload: unknown): FirstTreeStatus { + const snapshot = readSnapshot(payload); + if (snapshot) return snapshot.nodeCount === 0 ? 'empty' : 'readable'; + const error = readError(payload); + const reason = readString(asRecord(error?.details)?.reason); + return firstTreeStatusFromReason(reason); +} + +function firstTreeStatusFromReason(reason: string | undefined): FirstTreeStatus { + if (reason === 'first_tree_empty') return 'empty'; + return APP_MOUNT_REASONS.has(reason ?? '') ? 'unreadable' : 'not-observed'; +} + +function readDaemonDuration( + payload: unknown, + operation: RawSample['operation'], +): number | undefined { + const record = asRecord(payload); + const data = asRecord(record?.data); + if (operation === 'snapshot') { + const results = Array.isArray(data?.results) ? data.results : []; + const first = asRecord(results[0]); + return readFiniteNumber(first?.durationMs); + } + return readFiniteNumber(asRecord(data?.startup)?.durationMs); +} + +function readSnapshot( + payload: unknown, +): { nodeCount: number; targetGeneration: number | null } | undefined { + const snapshot = readSnapshotRecord(payload); + if (!snapshot) return undefined; + const nodeCount = readSnapshotNodeCount(snapshot); + if (nodeCount === undefined) return undefined; + const generation = readFiniteNumber(snapshot.refsGeneration ?? snapshot.targetGeneration); + return { nodeCount, targetGeneration: generation ?? null }; +} + +function readSnapshotRecord(payload: unknown): Record | undefined { + const record = asRecord(payload); + const data = asRecord(record?.data) ?? record; + const batchResults = Array.isArray(data?.results) ? data.results : []; + const firstResult = asRecord(batchResults[0]); + const stepData = asRecord(firstResult?.data) ?? data; + return asRecord(stepData?.snapshot) ?? stepData; +} + +function readSnapshotNodeCount(snapshot: Record): number | undefined { + const nodes = snapshot.nodes; + return Array.isArray(nodes) ? nodes.length : readFiniteNumber(snapshot.nodeCount); +} + +function failureCategory( + code: string | undefined, + reason: string | undefined, +): Failure['category'] { + const category = REASON_CATEGORIES.find( + ([reasons]) => reason !== undefined && reasons.has(reason), + ); + return category?.[1] ?? (code && TIMEOUT_CODES.has(code) ? 'timeout' : 'other'); +} + +function readError( + payload: unknown, +): { code?: unknown; message?: string; details?: unknown } | undefined { + const record = asRecord(payload); + const direct = asRecord(record?.error); + if (direct) { + return { code: direct.code, message: readString(direct.message), details: direct.details }; + } + const initial = asRecord(asRecord(record?.data)?.initialSnapshotError); + if (initial) { + return { code: initial.code, message: readString(initial.message), details: initial.details }; + } + return undefined; +} + +function readFiniteNumber(value: unknown): number | undefined { + return typeof value === 'number' && Number.isFinite(value) ? value : undefined; +} diff --git a/scripts/ios-snapshot-benchmark/deep-button-artifact.ts b/scripts/ios-snapshot-benchmark/deep-button-artifact.ts new file mode 100644 index 000000000..adc533546 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/deep-button-artifact.ts @@ -0,0 +1,288 @@ +import crypto from 'node:crypto'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +export const ARTIFACT_FILENAME = 'deep-button-fixture.v1.json' as const; +const ARTIFACT_PATH = path.join(path.dirname(fileURLToPath(import.meta.url)), ARTIFACT_FILENAME); + +export type FixtureNode = { + id: string; + parentId: string | null; + depth: number; + role: string; + label: string; + value?: string; + state?: 'off' | 'on'; +}; + +export type ArtifactObservation = { + state: 'off' | 'on'; + shallowNodeIds: string[]; + fullNodeIds: string[]; + changedNode: FixtureNode; + shallowDigest: string; + fullDigest: string; +}; + +export type DeepButtonArtifact = { + version: 1; + fixture: 'deep-button-v1'; + depth: 72; + changedDescendant: 'deep-button-state'; + nodes: FixtureNode[]; + before: ArtifactObservation; + after: ArtifactObservation; +}; + +export function readDeepButtonFixtureArtifact(): DeepButtonArtifact { + let value: unknown; + try { + value = JSON.parse(fs.readFileSync(ARTIFACT_PATH, 'utf8')); + } catch (error) { + throw new Error( + `Could not read ${ARTIFACT_FILENAME}: ${error instanceof Error ? error.message : String(error)}`, + ); + } + if (!isRecord(value)) throw new Error(`${ARTIFACT_FILENAME} must contain an object.`); + if (value.version !== 1 || value.fixture !== 'deep-button-v1') { + throw new Error(`${ARTIFACT_FILENAME} has an unsupported fixture identity.`); + } + if (value.depth !== 72 || value.changedDescendant !== 'deep-button-state') { + throw new Error(`${ARTIFACT_FILENAME} has an unsupported depth or changed descendant.`); + } + const artifact: DeepButtonArtifact = { + version: 1, + fixture: 'deep-button-v1', + depth: 72, + changedDescendant: 'deep-button-state', + nodes: readNodes(value.nodes), + before: readObservation(value.before), + after: readObservation(value.after), + }; + validateArtifact(artifact); + return artifact; +} + +export function materializeNodes( + nodes: FixtureNode[], + ids: string[], + changedNode: FixtureNode, +): FixtureNode[] { + const nodeById = new Map(nodes.map((node) => [node.id, node])); + return ids.map((id) => (id === changedNode.id ? changedNode : nodeById.get(id)!)); +} + +function validateArtifact(artifact: DeepButtonArtifact): void { + if (artifact.nodes.length !== artifact.depth + 1) { + throw new Error(`${ARTIFACT_FILENAME} must contain one root-to-leaf node per depth.`); + } + const nodeIds = artifact.nodes.map((node) => node.id); + if (new Set(nodeIds).size !== nodeIds.length) { + throw new Error(`${ARTIFACT_FILENAME} contains duplicate node ids.`); + } + const nodeById = new Map(artifact.nodes.map((node) => [node.id, node])); + for (const [index, node] of artifact.nodes.entries()) { + const expectedParent = index === 0 ? null : artifact.nodes[index - 1]!.id; + if (node.depth !== index || node.parentId !== expectedParent) { + throw new Error(`${ARTIFACT_FILENAME} contains a broken ancestor chain at depth ${index}.`); + } + } + validateObservation(artifact.before, nodeIds, nodeById, artifact); + validateObservation(artifact.after, nodeIds, nodeById, artifact); + if (artifact.before.shallowDigest !== artifact.after.shallowDigest) { + throw new Error(`${ARTIFACT_FILENAME} changed its shallow output between states.`); + } + if (JSON.stringify(artifact.before.changedNode) === JSON.stringify(artifact.after.changedNode)) { + throw new Error(`${ARTIFACT_FILENAME} did not change the deep button state.`); + } +} + +function validateObservation( + source: ArtifactObservation, + nodeIds: string[], + nodeById: ReadonlyMap, + artifact: DeepButtonArtifact, +): void { + validateFullOutput(source, nodeIds); + validateShallowOutput(source, nodeIds, nodeById); + validateChangedNodeIdentity(source, artifact); + validateChangedNodeDepth(source, artifact); + validateChangedNodeParent(source, artifact); + validateChangedNodeRole(source); + validateChangedNodeState(source); + validateChangedNodePresence(source, artifact); + validateOutputDigests(source, artifact); +} + +function validateFullOutput(source: ArtifactObservation, nodeIds: string[]): void { + if (source.fullNodeIds.length !== nodeIds.length || !sameItems(source.fullNodeIds, nodeIds)) { + throw new Error(`${ARTIFACT_FILENAME} full output does not contain the complete fixture.`); + } +} + +function validateShallowOutput( + source: ArtifactObservation, + nodeIds: string[], + nodeById: ReadonlyMap, +): void { + if (source.shallowNodeIds.length === 0) { + throw new Error(`${ARTIFACT_FILENAME} shallow output is not a root prefix.`); + } + if (source.shallowNodeIds.some((id) => !nodeById.has(id))) { + throw new Error(`${ARTIFACT_FILENAME} shallow output contains an unknown node.`); + } + if (source.shallowNodeIds.some((id, index) => id !== nodeIds[index])) { + throw new Error(`${ARTIFACT_FILENAME} shallow output is not a root prefix.`); + } +} + +function validateChangedNodeIdentity( + source: ArtifactObservation, + artifact: DeepButtonArtifact, +): void { + if (source.changedNode.id !== artifact.changedDescendant) { + throw new Error(`${ARTIFACT_FILENAME} changed node has the wrong identity.`); + } +} + +function validateChangedNodeDepth(source: ArtifactObservation, artifact: DeepButtonArtifact): void { + if (source.changedNode.depth !== artifact.depth) { + throw new Error(`${ARTIFACT_FILENAME} changed node does not reach the declared depth.`); + } +} + +function validateChangedNodeParent( + source: ArtifactObservation, + artifact: DeepButtonArtifact, +): void { + if (source.changedNode.parentId !== artifact.nodes.at(-2)?.id) { + throw new Error(`${ARTIFACT_FILENAME} changed node has the wrong parent.`); + } +} + +function validateChangedNodeRole(source: ArtifactObservation): void { + if (source.changedNode.role !== 'button') { + throw new Error(`${ARTIFACT_FILENAME} changed node is not a button.`); + } +} + +function validateChangedNodeState(source: ArtifactObservation): void { + if (source.changedNode.state !== source.state || source.changedNode.value !== source.state) { + throw new Error(`${ARTIFACT_FILENAME} changed node state does not match its observation.`); + } +} + +function validateChangedNodePresence( + source: ArtifactObservation, + artifact: DeepButtonArtifact, +): void { + if (!source.fullNodeIds.includes(artifact.changedDescendant)) { + throw new Error(`${ARTIFACT_FILENAME} full output omitted the changed node.`); + } + if (source.shallowNodeIds.includes(artifact.changedDescendant)) { + throw new Error(`${ARTIFACT_FILENAME} shallow output included the changed node.`); + } +} + +function validateOutputDigests(source: ArtifactObservation, artifact: DeepButtonArtifact): void { + const surfaceNodes = materializeNodes(artifact.nodes, source.shallowNodeIds, source.changedNode); + const fullNodes = materializeNodes(artifact.nodes, source.fullNodeIds, source.changedNode); + if (digest(surfaceNodes) !== source.shallowDigest || digest(fullNodes) !== source.fullDigest) { + throw new Error(`${ARTIFACT_FILENAME} contains a stale output digest.`); + } +} + +function readNodes(value: unknown): FixtureNode[] { + if (!Array.isArray(value)) throw new Error(`${ARTIFACT_FILENAME} nodes must be an array.`); + return value.map(readNode); +} + +function readObservation(value: unknown): ArtifactObservation { + if (!isRecord(value)) throw new Error(`${ARTIFACT_FILENAME} observation must be an object.`); + if (value.state !== 'off' && value.state !== 'on') { + throw new Error(`${ARTIFACT_FILENAME} observation has an invalid state.`); + } + return { + state: value.state, + shallowNodeIds: readStringArray(value.shallowNodeIds), + fullNodeIds: readStringArray(value.fullNodeIds), + changedNode: readNode(value.changedNode), + shallowDigest: readString(value.shallowDigest), + fullDigest: readString(value.fullDigest), + }; +} + +function readNode(value: unknown): FixtureNode { + if (!isRecord(value)) throw new Error(`${ARTIFACT_FILENAME} node must be an object.`); + const id = readRequiredString(value.id, 'node id'); + const parentId = readParentId(value.parentId); + const depth = readInteger(value.depth, 'node depth'); + const role = readRequiredString(value.role, 'node role'); + const label = readRequiredString(value.label, 'node label'); + const nodeValue = readOptionalString(value.value, 'node value'); + const state = readOptionalState(value.state); + return { + id, + parentId, + depth, + role, + label, + ...(nodeValue === undefined ? {} : { value: nodeValue }), + ...(state === undefined ? {} : { state }), + }; +} + +function readStringArray(value: unknown): string[] { + if (!Array.isArray(value) || value.some((item) => typeof item !== 'string')) { + throw new Error(`${ARTIFACT_FILENAME} node ids must be strings.`); + } + return value.map((item) => item as string); +} + +function readString(value: unknown): string { + if (typeof value !== 'string' || value.length === 0) { + throw new Error(`${ARTIFACT_FILENAME} digest must be a non-empty string.`); + } + return value; +} + +function readRequiredString(value: unknown, label: string): string { + if (typeof value !== 'string') + throw new Error(`${ARTIFACT_FILENAME} contains an invalid ${label}.`); + return value; +} + +function readParentId(value: unknown): string | null { + return value === null ? null : readRequiredString(value, 'node parent'); +} + +function readInteger(value: unknown, label: string): number { + if (typeof value !== 'number' || !Number.isInteger(value)) { + throw new Error(`${ARTIFACT_FILENAME} contains an invalid ${label}.`); + } + return value; +} + +function readOptionalString(value: unknown, label: string): string | undefined { + if (value === undefined) return undefined; + return readRequiredString(value, label); +} + +function readOptionalState(value: unknown): 'off' | 'on' | undefined { + if (value === undefined) return undefined; + if (value === 'off' || value === 'on') return value; + throw new Error(`${ARTIFACT_FILENAME} contains an invalid node state.`); +} + +function sameItems(left: string[], right: string[]): boolean { + return left.length === right.length && left.every((item, index) => item === right[index]); +} + +function digest(nodes: FixtureNode[]): string { + return crypto.createHash('sha256').update(JSON.stringify(nodes)).digest('hex'); +} + +function isRecord(value: unknown): value is Record { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} diff --git a/scripts/ios-snapshot-benchmark/deep-button-fixture.v1.json b/scripts/ios-snapshot-benchmark/deep-button-fixture.v1.json new file mode 100644 index 000000000..c9454183f --- /dev/null +++ b/scripts/ios-snapshot-benchmark/deep-button-fixture.v1.json @@ -0,0 +1,699 @@ +{ + "version": 1, + "fixture": "deep-button-v1", + "depth": 72, + "changedDescendant": "deep-button-state", + "nodes": [ + { + "id": "deep-button-root", + "parentId": null, + "depth": 0, + "role": "window", + "label": "Deep button fixture" + }, + { + "id": "deep-button-level-01", + "parentId": "deep-button-root", + "depth": 1, + "role": "group", + "label": "Descendant level 1" + }, + { + "id": "deep-button-level-02", + "parentId": "deep-button-level-01", + "depth": 2, + "role": "group", + "label": "Descendant level 2" + }, + { + "id": "deep-button-level-03", + "parentId": "deep-button-level-02", + "depth": 3, + "role": "group", + "label": "Descendant level 3" + }, + { + "id": "deep-button-level-04", + "parentId": "deep-button-level-03", + "depth": 4, + "role": "group", + "label": "Descendant level 4" + }, + { + "id": "deep-button-level-05", + "parentId": "deep-button-level-04", + "depth": 5, + "role": "group", + "label": "Descendant level 5" + }, + { + "id": "deep-button-level-06", + "parentId": "deep-button-level-05", + "depth": 6, + "role": "group", + "label": "Descendant level 6" + }, + { + "id": "deep-button-level-07", + "parentId": "deep-button-level-06", + "depth": 7, + "role": "group", + "label": "Descendant level 7" + }, + { + "id": "deep-button-level-08", + "parentId": "deep-button-level-07", + "depth": 8, + "role": "group", + "label": "Descendant level 8" + }, + { + "id": "deep-button-level-09", + "parentId": "deep-button-level-08", + "depth": 9, + "role": "group", + "label": "Descendant level 9" + }, + { + "id": "deep-button-level-10", + "parentId": "deep-button-level-09", + "depth": 10, + "role": "group", + "label": "Descendant level 10" + }, + { + "id": "deep-button-level-11", + "parentId": "deep-button-level-10", + "depth": 11, + "role": "group", + "label": "Descendant level 11" + }, + { + "id": "deep-button-level-12", + "parentId": "deep-button-level-11", + "depth": 12, + "role": "group", + "label": "Descendant level 12" + }, + { + "id": "deep-button-level-13", + "parentId": "deep-button-level-12", + "depth": 13, + "role": "group", + "label": "Descendant level 13" + }, + { + "id": "deep-button-level-14", + "parentId": "deep-button-level-13", + "depth": 14, + "role": "group", + "label": "Descendant level 14" + }, + { + "id": "deep-button-level-15", + "parentId": "deep-button-level-14", + "depth": 15, + "role": "group", + "label": "Descendant level 15" + }, + { + "id": "deep-button-level-16", + "parentId": "deep-button-level-15", + "depth": 16, + "role": "group", + "label": "Descendant level 16" + }, + { + "id": "deep-button-level-17", + "parentId": "deep-button-level-16", + "depth": 17, + "role": "group", + "label": "Descendant level 17" + }, + { + "id": "deep-button-level-18", + "parentId": "deep-button-level-17", + "depth": 18, + "role": "group", + "label": "Descendant level 18" + }, + { + "id": "deep-button-level-19", + "parentId": "deep-button-level-18", + "depth": 19, + "role": "group", + "label": "Descendant level 19" + }, + { + "id": "deep-button-level-20", + "parentId": "deep-button-level-19", + "depth": 20, + "role": "group", + "label": "Descendant level 20" + }, + { + "id": "deep-button-level-21", + "parentId": "deep-button-level-20", + "depth": 21, + "role": "group", + "label": "Descendant level 21" + }, + { + "id": "deep-button-level-22", + "parentId": "deep-button-level-21", + "depth": 22, + "role": "group", + "label": "Descendant level 22" + }, + { + "id": "deep-button-level-23", + "parentId": "deep-button-level-22", + "depth": 23, + "role": "group", + "label": "Descendant level 23" + }, + { + "id": "deep-button-level-24", + "parentId": "deep-button-level-23", + "depth": 24, + "role": "group", + "label": "Descendant level 24" + }, + { + "id": "deep-button-level-25", + "parentId": "deep-button-level-24", + "depth": 25, + "role": "group", + "label": "Descendant level 25" + }, + { + "id": "deep-button-level-26", + "parentId": "deep-button-level-25", + "depth": 26, + "role": "group", + "label": "Descendant level 26" + }, + { + "id": "deep-button-level-27", + "parentId": "deep-button-level-26", + "depth": 27, + "role": "group", + "label": "Descendant level 27" + }, + { + "id": "deep-button-level-28", + "parentId": "deep-button-level-27", + "depth": 28, + "role": "group", + "label": "Descendant level 28" + }, + { + "id": "deep-button-level-29", + "parentId": "deep-button-level-28", + "depth": 29, + "role": "group", + "label": "Descendant level 29" + }, + { + "id": "deep-button-level-30", + "parentId": "deep-button-level-29", + "depth": 30, + "role": "group", + "label": "Descendant level 30" + }, + { + "id": "deep-button-level-31", + "parentId": "deep-button-level-30", + "depth": 31, + "role": "group", + "label": "Descendant level 31" + }, + { + "id": "deep-button-level-32", + "parentId": "deep-button-level-31", + "depth": 32, + "role": "group", + "label": "Descendant level 32" + }, + { + "id": "deep-button-level-33", + "parentId": "deep-button-level-32", + "depth": 33, + "role": "group", + "label": "Descendant level 33" + }, + { + "id": "deep-button-level-34", + "parentId": "deep-button-level-33", + "depth": 34, + "role": "group", + "label": "Descendant level 34" + }, + { + "id": "deep-button-level-35", + "parentId": "deep-button-level-34", + "depth": 35, + "role": "group", + "label": "Descendant level 35" + }, + { + "id": "deep-button-level-36", + "parentId": "deep-button-level-35", + "depth": 36, + "role": "group", + "label": "Descendant level 36" + }, + { + "id": "deep-button-level-37", + "parentId": "deep-button-level-36", + "depth": 37, + "role": "group", + "label": "Descendant level 37" + }, + { + "id": "deep-button-level-38", + "parentId": "deep-button-level-37", + "depth": 38, + "role": "group", + "label": "Descendant level 38" + }, + { + "id": "deep-button-level-39", + "parentId": "deep-button-level-38", + "depth": 39, + "role": "group", + "label": "Descendant level 39" + }, + { + "id": "deep-button-level-40", + "parentId": "deep-button-level-39", + "depth": 40, + "role": "group", + "label": "Descendant level 40" + }, + { + "id": "deep-button-level-41", + "parentId": "deep-button-level-40", + "depth": 41, + "role": "group", + "label": "Descendant level 41" + }, + { + "id": "deep-button-level-42", + "parentId": "deep-button-level-41", + "depth": 42, + "role": "group", + "label": "Descendant level 42" + }, + { + "id": "deep-button-level-43", + "parentId": "deep-button-level-42", + "depth": 43, + "role": "group", + "label": "Descendant level 43" + }, + { + "id": "deep-button-level-44", + "parentId": "deep-button-level-43", + "depth": 44, + "role": "group", + "label": "Descendant level 44" + }, + { + "id": "deep-button-level-45", + "parentId": "deep-button-level-44", + "depth": 45, + "role": "group", + "label": "Descendant level 45" + }, + { + "id": "deep-button-level-46", + "parentId": "deep-button-level-45", + "depth": 46, + "role": "group", + "label": "Descendant level 46" + }, + { + "id": "deep-button-level-47", + "parentId": "deep-button-level-46", + "depth": 47, + "role": "group", + "label": "Descendant level 47" + }, + { + "id": "deep-button-level-48", + "parentId": "deep-button-level-47", + "depth": 48, + "role": "group", + "label": "Descendant level 48" + }, + { + "id": "deep-button-level-49", + "parentId": "deep-button-level-48", + "depth": 49, + "role": "group", + "label": "Descendant level 49" + }, + { + "id": "deep-button-level-50", + "parentId": "deep-button-level-49", + "depth": 50, + "role": "group", + "label": "Descendant level 50" + }, + { + "id": "deep-button-level-51", + "parentId": "deep-button-level-50", + "depth": 51, + "role": "group", + "label": "Descendant level 51" + }, + { + "id": "deep-button-level-52", + "parentId": "deep-button-level-51", + "depth": 52, + "role": "group", + "label": "Descendant level 52" + }, + { + "id": "deep-button-level-53", + "parentId": "deep-button-level-52", + "depth": 53, + "role": "group", + "label": "Descendant level 53" + }, + { + "id": "deep-button-level-54", + "parentId": "deep-button-level-53", + "depth": 54, + "role": "group", + "label": "Descendant level 54" + }, + { + "id": "deep-button-level-55", + "parentId": "deep-button-level-54", + "depth": 55, + "role": "group", + "label": "Descendant level 55" + }, + { + "id": "deep-button-level-56", + "parentId": "deep-button-level-55", + "depth": 56, + "role": "group", + "label": "Descendant level 56" + }, + { + "id": "deep-button-level-57", + "parentId": "deep-button-level-56", + "depth": 57, + "role": "group", + "label": "Descendant level 57" + }, + { + "id": "deep-button-level-58", + "parentId": "deep-button-level-57", + "depth": 58, + "role": "group", + "label": "Descendant level 58" + }, + { + "id": "deep-button-level-59", + "parentId": "deep-button-level-58", + "depth": 59, + "role": "group", + "label": "Descendant level 59" + }, + { + "id": "deep-button-level-60", + "parentId": "deep-button-level-59", + "depth": 60, + "role": "group", + "label": "Descendant level 60" + }, + { + "id": "deep-button-level-61", + "parentId": "deep-button-level-60", + "depth": 61, + "role": "group", + "label": "Descendant level 61" + }, + { + "id": "deep-button-level-62", + "parentId": "deep-button-level-61", + "depth": 62, + "role": "group", + "label": "Descendant level 62" + }, + { + "id": "deep-button-level-63", + "parentId": "deep-button-level-62", + "depth": 63, + "role": "group", + "label": "Descendant level 63" + }, + { + "id": "deep-button-level-64", + "parentId": "deep-button-level-63", + "depth": 64, + "role": "group", + "label": "Descendant level 64" + }, + { + "id": "deep-button-level-65", + "parentId": "deep-button-level-64", + "depth": 65, + "role": "group", + "label": "Descendant level 65" + }, + { + "id": "deep-button-level-66", + "parentId": "deep-button-level-65", + "depth": 66, + "role": "group", + "label": "Descendant level 66" + }, + { + "id": "deep-button-level-67", + "parentId": "deep-button-level-66", + "depth": 67, + "role": "group", + "label": "Descendant level 67" + }, + { + "id": "deep-button-level-68", + "parentId": "deep-button-level-67", + "depth": 68, + "role": "group", + "label": "Descendant level 68" + }, + { + "id": "deep-button-level-69", + "parentId": "deep-button-level-68", + "depth": 69, + "role": "group", + "label": "Descendant level 69" + }, + { + "id": "deep-button-level-70", + "parentId": "deep-button-level-69", + "depth": 70, + "role": "group", + "label": "Descendant level 70" + }, + { + "id": "deep-button-level-71", + "parentId": "deep-button-level-70", + "depth": 71, + "role": "group", + "label": "Descendant level 71" + }, + { + "id": "deep-button-state", + "parentId": "deep-button-level-71", + "depth": 72, + "role": "button", + "label": "Deep button state" + } + ], + "before": { + "state": "off", + "shallowNodeIds": ["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" + ], + "changedNode": { + "id": "deep-button-state", + "parentId": "deep-button-level-71", + "depth": 72, + "role": "button", + "label": "Deep button off", + "value": "off", + "state": "off" + }, + "shallowDigest": "bd7118623fd764b18b99394d25021372840cea98e8b3b0c0196d3e791b199062", + "fullDigest": "275f9d14720d5a02ed77b54a03a8f51830afcdc2b12577bd8014631bfbf2c81a" + }, + "after": { + "state": "on", + "shallowNodeIds": ["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" + ], + "changedNode": { + "id": "deep-button-state", + "parentId": "deep-button-level-71", + "depth": 72, + "role": "button", + "label": "Deep button on", + "value": "on", + "state": "on" + }, + "shallowDigest": "bd7118623fd764b18b99394d25021372840cea98e8b3b0c0196d3e791b199062", + "fullDigest": "8542024b5b9719f6b2ba9692915bda9011e0e5d10c4e21463257763ee765719d" + } +} diff --git a/scripts/ios-snapshot-benchmark/deep-button.test.ts b/scripts/ios-snapshot-benchmark/deep-button.test.ts new file mode 100644 index 000000000..1feb9b4b4 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/deep-button.test.ts @@ -0,0 +1,32 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { + assertInvalidShallowRuleFails, + assertSafeFullRulePasses, + deepButtonFixtureEvidence, + readDeepButtonFixtureArtifact, +} from './deep-button.ts'; + +test('the checked-in fixture has a real 72-level ancestor chain', () => { + const artifact = readDeepButtonFixtureArtifact(); + assert.equal(artifact.depth, 72); + assert.equal(artifact.nodes.length, 73); + assert.equal(artifact.before.changedNode.depth, 72); + assert.equal(artifact.after.changedNode.depth, 72); + assert.notDeepEqual(artifact.before.changedNode, artifact.after.changedNode); +}); + +test('the shallow control observes no change while the full tree changes', () => { + const evidence = deepButtonFixtureEvidence(); + assert.equal(evidence.artifact, 'deep-button-fixture.v1.json'); + assert.equal(evidence.depth, 72); + assert.equal(evidence.before.surfaceDigest, evidence.after.surfaceDigest); + assert.notEqual(evidence.before.fullDigest, evidence.after.fullDigest); + assert.ok(!evidence.after.surfaceNodeIds.includes(evidence.changedDescendant)); + assert.ok(evidence.after.fullNodeIds.includes(evidence.changedDescendant)); +}); + +test('the planted invalid rule is red and the full rule is green', () => { + assert.throws(assertInvalidShallowRuleFails, /changed descendant was omitted/); + assert.doesNotThrow(assertSafeFullRulePasses); +}); diff --git a/scripts/ios-snapshot-benchmark/deep-button.ts b/scripts/ios-snapshot-benchmark/deep-button.ts new file mode 100644 index 000000000..f1bceffb1 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/deep-button.ts @@ -0,0 +1,106 @@ +import crypto from 'node:crypto'; +import { fileURLToPath } from 'node:url'; +import { + ARTIFACT_FILENAME, + materializeNodes, + readDeepButtonFixtureArtifact, + type DeepButtonArtifact, +} from './deep-button-artifact.ts'; +import type { DeepButtonEvidence, DeepButtonObservation } from './types.ts'; + +const INVALID_SHALLOW_COMMAND = 'pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow'; +const SAFE_FULL_COMMAND = 'pnpm bench:ios-snapshot:deep-button -- --rule safe-full'; +const INVALID_ASSERTION = + 'AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid.'; + +export { readDeepButtonFixtureArtifact } from './deep-button-artifact.ts'; + +export function deepButtonFixtureEvidence(): DeepButtonEvidence { + const artifact = readDeepButtonFixtureArtifact(); + return { + issue: '#1626', + fixture: 'deep-button-v1', + artifact: ARTIFACT_FILENAME, + depth: artifact.depth, + changedDescendant: artifact.changedDescendant, + invalidShallowRule: { + command: INVALID_SHALLOW_COMMAND, + exitCode: 1, + assertion: INVALID_ASSERTION, + }, + safeFullRule: { + command: SAFE_FULL_COMMAND, + exitCode: 0, + assertion: 'full observation changed and includes the changed descendant.', + }, + before: observation(artifact, artifact.before), + after: observation(artifact, artifact.after), + }; +} + +export function assertInvalidShallowRuleFails(): never { + const evidence = deepButtonFixtureEvidence(); + if ( + evidence.before.surfaceDigest === evidence.after.surfaceDigest && + evidence.before.fullDigest !== evidence.after.fullDigest && + !evidence.after.surfaceNodeIds.includes(evidence.changedDescendant) && + evidence.after.fullNodeIds.includes(evidence.changedDescendant) + ) { + throw new Error(INVALID_ASSERTION); + } + throw new Error('AssertionError: fixture did not produce a changed omitted descendant.'); +} + +export function assertSafeFullRulePasses(): void { + const evidence = deepButtonFixtureEvidence(); + if (evidence.before.fullDigest === evidence.after.fullDigest) { + throw new Error('AssertionError: full observation did not record the changed descendant.'); + } + if (!evidence.after.fullNodeIds.includes(evidence.changedDescendant)) { + throw new Error('AssertionError: full observation omitted the changed descendant.'); + } +} + +function observation( + artifact: DeepButtonArtifact, + source: DeepButtonArtifact['before'], +): DeepButtonObservation { + const surfaceNodes = materializeNodes(artifact.nodes, source.shallowNodeIds, source.changedNode); + const fullNodes = materializeNodes(artifact.nodes, source.fullNodeIds, source.changedNode); + return { + depth: artifact.depth, + surfaceDigest: digest(surfaceNodes), + fullDigest: digest(fullNodes), + state: source.state, + surfaceNodeIds: source.shallowNodeIds, + fullNodeIds: source.fullNodeIds, + }; +} + +function digest(nodes: DeepButtonArtifact['nodes']): string { + return crypto.createHash('sha256').update(JSON.stringify(nodes)).digest('hex'); +} + +function readRule(argv: string[]): 'invalid-shallow' | 'safe-full' { + if (argv[0] === '--') argv = argv.slice(1); + const index = argv.indexOf('--rule'); + const rule = argv[index + 1]; + if (rule === 'invalid-shallow' || rule === 'safe-full') return rule; + throw new Error('Usage: pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow|safe-full'); +} + +function runDeepButtonRule(argv: string[]): void { + const rule = readRule(argv); + if (rule === 'invalid-shallow') assertInvalidShallowRuleFails(); + assertSafeFullRulePasses(); + process.stdout.write('safe-full: changed descendant observed in the full snapshot.\n'); +} + +if (process.argv[1] && fileURLToPath(import.meta.url) === process.argv[1]) { + try { + runDeepButtonRule(process.argv.slice(2)); + } catch (error) { + process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`); + process.exitCode = 1; + } +} diff --git a/scripts/ios-snapshot-benchmark/deep-control.ts b/scripts/ios-snapshot-benchmark/deep-control.ts new file mode 100644 index 000000000..45ad07ea4 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/deep-control.ts @@ -0,0 +1,58 @@ +import { spawnSync } from 'node:child_process'; +import path from 'node:path'; +import { deepButtonFixtureEvidence } from './deep-button.ts'; + +export class BenchmarkControlError extends Error { + readonly command?: string; + + constructor(message: string, command?: string) { + super(message); + this.command = command; + } +} + +export function runDeepButtonControls(repoRoot: string) { + const evidence = deepButtonFixtureEvidence(); + const script = path.join(repoRoot, 'scripts', 'ios-snapshot-benchmark', 'deep-button.ts'); + const invalid = runControl(repoRoot, script, 'invalid-shallow'); + assertInvalidControl(invalid, evidence.invalidShallowRule.assertion); + const safe = runControl(repoRoot, script, 'safe-full'); + assertSafeControl(safe); + return { + ...evidence, + invalidShallowRule: { ...evidence.invalidShallowRule, exitCode: invalid.status ?? -1 }, + safeFullRule: { ...evidence.safeFullRule, exitCode: safe.status ?? -1 }, + }; +} + +function runControl( + repoRoot: string, + script: string, + rule: 'invalid-shallow' | 'safe-full', +): { status: number | null; stderr: string } { + const result = spawnSync( + process.execPath, + ['--experimental-strip-types', script, '--rule', rule], + { cwd: repoRoot, encoding: 'utf8', timeout: 30_000 }, + ); + return { status: result.status, stderr: result.stderr ?? '' }; +} + +function assertInvalidControl( + result: { status: number | null; stderr: string }, + assertion: string, +): void { + if (result.status === 1 && result.stderr.trim() === assertion) return; + throw new BenchmarkControlError( + `Invalid-shallow control did not produce the required red assertion (exit ${String(result.status)}).`, + 'pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow', + ); +} + +function assertSafeControl(result: { status: number | null; stderr: string }): void { + if (result.status === 0) return; + throw new BenchmarkControlError( + `Safe-full control failed: ${result.stderr.trim() || `exit ${String(result.status)}`}`, + 'pnpm bench:ios-snapshot:deep-button -- --rule safe-full', + ); +} diff --git a/scripts/ios-snapshot-benchmark/definitions.test.ts b/scripts/ios-snapshot-benchmark/definitions.test.ts new file mode 100644 index 000000000..31370fa9b --- /dev/null +++ b/scripts/ios-snapshot-benchmark/definitions.test.ts @@ -0,0 +1,23 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { + parseLocalStates, + parseRtt, + parseSampleCount, + parseScreenIds, + sampleMinimumForState, +} from './definitions.ts'; + +test('parses the versioned state and screen cells', () => { + assert.deepEqual(parseLocalStates('warm,cold,warm'), ['warm', 'cold']); + assert.deepEqual(parseScreenIds('quiet,alert,quiet'), ['quiet', 'alert']); + assert.deepEqual(parseRtt('80,0,20,0'), [80, 0, 20]); + assert.equal(sampleMinimumForState('cold-cold'), 10); + assert.equal(sampleMinimumForState('relaunch'), 20); +}); + +test('enforces the warm and cold sample minima', () => { + assert.equal(parseSampleCount('10', ['cold']), 10); + assert.throws(() => parseSampleCount('10', ['warm']), /at least 20/); + assert.equal(parseSampleCount(undefined, ['cold', 'warm']), 20); +}); diff --git a/scripts/ios-snapshot-benchmark/definitions.ts b/scripts/ios-snapshot-benchmark/definitions.ts new file mode 100644 index 000000000..a96d04a2c --- /dev/null +++ b/scripts/ios-snapshot-benchmark/definitions.ts @@ -0,0 +1,127 @@ +import { + APP_MOUNT_ISSUE_ID, + COLD_SAMPLE_MINIMUM, + DEEP_BUTTON_ISSUE_ID, + ISSUE_ID, + PARENT_ISSUE_ID, + PROXY_RTT_VALUES, + WARM_SAMPLE_MINIMUM, + type LocalState, + type ScreenFixture, + type ScreenId, +} from './types.ts'; + +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[] = [ + { + id: 'quiet', + label: 'Quiet inert surface', + app: FIXTURE_APP_ID, + launchUrl: `${FIXTURE_SCHEME}/inert`, + anchorText: 'Inert surface', + }, + { + id: 'list', + label: 'Long catalog list', + app: FIXTURE_APP_ID, + launchUrl: `${FIXTURE_SCHEME}/catalog`, + anchorText: 'Catalog', + }, + { + id: 'nested-scroll', + label: 'WebView nested scroll', + app: FIXTURE_APP_ID, + launchUrl: `${FIXTURE_SCHEME}/webview`, + anchorText: 'WebView accessibility', + }, + { + id: 'alert', + label: 'Native alert', + app: FIXTURE_APP_ID, + launchUrl: `${FIXTURE_SCHEME}/automation`, + anchorText: 'Automation lab', + postSetupAnchorText: 'Automation confirmation', + setupAction: 'open-alert', + }, + { + id: 'system-surface', + label: 'iOS Settings system surface', + app: IOS_SETTINGS_APP_ID, + anchorText: 'Settings', + }, + { + id: 'xctest-stress', + label: 'Dense checkout XCTest stress surface', + app: FIXTURE_APP_ID, + launchUrl: `${FIXTURE_SCHEME}/form`, + anchorText: 'Checkout form', + }, +]; + +export function screenFixture(id: ScreenId): ScreenFixture { + const fixture = SCREEN_FIXTURES.find((candidate) => candidate.id === id); + if (!fixture) throw new Error(`Unknown screen fixture: ${id}`); + return fixture; +} + +export function parseScreenIds(value: string | undefined): ScreenId[] { + const ids = (value ?? 'quiet,list,nested-scroll,alert,system-surface,xctest-stress') + .split(',') + .map((item) => item.trim()) + .filter(Boolean) as ScreenId[]; + const valid = new Set(SCREEN_FIXTURES.map((fixture) => fixture.id)); + const unknown = ids.filter((id) => !valid.has(id)); + if (unknown.length > 0) throw new Error(`Unknown --screen value: ${unknown.join(', ')}`); + if (ids.length === 0) throw new Error('--screen requires at least one fixture.'); + return [...new Set(ids)]; +} + +export function parseLocalStates(value: string | undefined): LocalState[] { + const states = (value ?? 'cold-cold,cold,warm,relaunch') + .split(',') + .map((item) => item.trim()) + .filter(Boolean) as LocalState[]; + const valid = new Set(['cold-cold', 'cold', 'warm', 'relaunch']); + 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.'); + return [...new Set(states)]; +} + +export function sampleMinimumForState(state: LocalState): number { + return state === 'warm' || state === 'relaunch' ? WARM_SAMPLE_MINIMUM : COLD_SAMPLE_MINIMUM; +} + +export function parseSampleCount(value: string | undefined, states: LocalState[]): number { + const requested = + value === undefined ? Math.max(...states.map(sampleMinimumForState)) : Number(value); + if (!Number.isInteger(requested) || requested < 1) { + throw new Error(`--samples must be an integer >= 1 (got ${JSON.stringify(value)})`); + } + const minimum = Math.max(...states.map(sampleMinimumForState)); + if (requested < minimum) { + throw new Error(`--samples must be at least ${minimum} for the selected state cells.`); + } + return requested; +} + +export function parseRtt(value: string | undefined): (typeof PROXY_RTT_VALUES)[number][] { + const values = (value ?? '0,20,80').split(',').map((item) => Number(item.trim())); + if ( + values.some((item) => !PROXY_RTT_VALUES.includes(item as (typeof PROXY_RTT_VALUES)[number])) + ) { + throw new Error('--rtt must contain only 0, 20, or 80 milliseconds.'); + } + return [...new Set(values)] as (typeof PROXY_RTT_VALUES)[number][]; +} + +export const CONTRACT = { + issue: ISSUE_ID, + parent: PARENT_ISSUE_ID, + references: { deepButton: DEEP_BUTTON_ISSUE_ID, appMount: APP_MOUNT_ISSUE_ID }, + warmSampleMinimum: WARM_SAMPLE_MINIMUM, + coldSampleMinimum: COLD_SAMPLE_MINIMUM, +} as const; diff --git a/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-cold-local-71fb2483f.json b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-cold-local-71fb2483f.json new file mode 100644 index 000000000..5dd140f07 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-cold-local-71fb2483f.json @@ -0,0 +1,2382 @@ +{ + "schemaVersion": "ios-snapshot-convergence.v1", + "issue": "#2189", + "parent": "#2188", + "references": { + "deepButton": "#1626", + "appMount": "#1571" + }, + "runId": "ios-snapshot-1788279723256-74636", + "generatedAt": "2026-09-01T16:22:03.256Z", + "revision": { + "commit": "71fb2483f30d90e615e949601c836aeebbf450c5", + "branch": "codex/2189-ios-snapshot-baselines", + "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" + }, + "host": { + "model": "MacBook Pro", + "modelIdentifier": "Mac16,8", + "cpu": "Apple M4 Pro", + "cpuCores": 12 + }, + "target": { + "platform": "ios", + "kind": "simulator", + "udid": "7E76ECA9-D40C-4833-A711-F870F8CE9363", + "name": "bench-golden-v2", + "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-27-0", + "appId": "com.callstack.agentdevicelab", + "appPath": "/private/tmp/agent-device-2189-fixture-app-repacked/AgentDeviceTester.app" + }, + "config": { + "warmSampleMinimum": 20, + "coldSampleMinimum": 10, + "requestedSamples": 10, + "screens": ["quiet", "list", "nested-scroll", "alert", "system-surface", "xctest-stress"], + "states": ["cold-cold", "cold"] + }, + "measurements": [ + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold-cold", + "screen": "quiet", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T15:39:03.845Z", + "finishedAt": "2026-09-01T15:39:21.390Z", + "operation": "open-foreground", + "wallClockMs": 17544.868082999998, + "daemonDurationMs": 16124, + "responseBytes": 4799, + "nodeCount": 6, + "targetGeneration": 189306, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T15:39:32.703Z", + "finishedAt": "2026-09-01T15:39:48.696Z", + "operation": "open-foreground", + "wallClockMs": 15992.420542000007, + "daemonDurationMs": 14488, + "responseBytes": 4799, + "nodeCount": 6, + "targetGeneration": 196005, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T15:39:59.697Z", + "finishedAt": "2026-09-01T15:40:22.627Z", + "operation": "open-foreground", + "wallClockMs": 22929.789749999996, + "daemonDurationMs": 14079, + "responseBytes": 4802, + "nodeCount": 6, + "targetGeneration": 766327, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T15:40:34.485Z", + "finishedAt": "2026-09-01T15:40:51.008Z", + "operation": "open-foreground", + "wallClockMs": 16523.480874999994, + "daemonDurationMs": 15161, + "responseBytes": 4799, + "nodeCount": 6, + "targetGeneration": 947799, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T15:41:01.737Z", + "finishedAt": "2026-09-01T15:41:18.129Z", + "operation": "open-foreground", + "wallClockMs": 16392.18300000002, + "daemonDurationMs": 14926, + "responseBytes": 4799, + "nodeCount": 6, + "targetGeneration": 753234, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T15:41:29.122Z", + "finishedAt": "2026-09-01T15:41:46.666Z", + "operation": "open-foreground", + "wallClockMs": 17543.537209000002, + "daemonDurationMs": 15637, + "responseBytes": 4799, + "nodeCount": 6, + "targetGeneration": 343695, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T15:41:56.372Z", + "finishedAt": "2026-09-01T15:42:14.418Z", + "operation": "open-foreground", + "wallClockMs": 18045.288249999983, + "daemonDurationMs": 16442, + "responseBytes": 4798, + "nodeCount": 6, + "targetGeneration": 106821, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T15:42:25.131Z", + "finishedAt": "2026-09-01T15:42:43.044Z", + "operation": "open-foreground", + "wallClockMs": 17912.674207999982, + "daemonDurationMs": 16339, + "responseBytes": 4799, + "nodeCount": 6, + "targetGeneration": 418428, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T15:42:55.476Z", + "finishedAt": "2026-09-01T15:43:12.163Z", + "operation": "open-foreground", + "wallClockMs": 16686.876292, + "daemonDurationMs": 14849, + "responseBytes": 4800, + "nodeCount": 6, + "targetGeneration": 748657, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T15:43:26.668Z", + "finishedAt": "2026-09-01T15:43:44.641Z", + "operation": "open-foreground", + "wallClockMs": 17972.059416999982, + "daemonDurationMs": 16441, + "responseBytes": 4799, + "nodeCount": 6, + "targetGeneration": 346204, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 15992.420542000007, + "median": 17543.537209000002, + "p95": 22929.789749999996, + "max": 22929.789749999996, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 14079, + "median": 15161, + "p95": 16442, + "max": 16442, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 4798, + "median": 4799, + "p95": 4802, + "max": 4802, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold-cold", + "screen": "list", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T15:43:59.880Z", + "finishedAt": "2026-09-01T15:44:18.215Z", + "operation": "open-foreground", + "wallClockMs": 18334.765874999983, + "daemonDurationMs": 16483, + "responseBytes": 16906, + "nodeCount": 35, + "targetGeneration": 132349, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T15:44:30.366Z", + "finishedAt": "2026-09-01T15:44:54.850Z", + "operation": "open-foreground", + "wallClockMs": 24483.376374999993, + "daemonDurationMs": 18602, + "responseBytes": 16907, + "nodeCount": 35, + "targetGeneration": 119629, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 3, + "startedAt": "2026-09-01T15:45:08.517Z", + "finishedAt": "2026-09-01T15:45:27.896Z", + "operation": "open-foreground", + "wallClockMs": 19379.254124999978, + "daemonDurationMs": 17459, + "responseBytes": 16905, + "nodeCount": 35, + "targetGeneration": 635863, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T15:45:42.686Z", + "finishedAt": "2026-09-01T15:46:01.033Z", + "operation": "open-foreground", + "wallClockMs": 18346.459583000047, + "daemonDurationMs": 16658, + "responseBytes": 16905, + "nodeCount": 35, + "targetGeneration": 420034, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T15:46:10.702Z", + "finishedAt": "2026-09-01T15:46:30.437Z", + "operation": "open-foreground", + "wallClockMs": 19734.277624999988, + "daemonDurationMs": 18010, + "responseBytes": 16904, + "nodeCount": 35, + "targetGeneration": 502229, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T15:46:42.067Z", + "finishedAt": "2026-09-01T15:47:00.847Z", + "operation": "open-foreground", + "wallClockMs": 18780.024916999973, + "daemonDurationMs": 17151, + "responseBytes": 16905, + "nodeCount": 35, + "targetGeneration": 749806, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T15:47:10.498Z", + "finishedAt": "2026-09-01T15:47:31.187Z", + "operation": "open-foreground", + "wallClockMs": 20689.641333999985, + "daemonDurationMs": 19235, + "responseBytes": 16904, + "nodeCount": 35, + "targetGeneration": 827083, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T15:47:41.666Z", + "finishedAt": "2026-09-01T15:48:00.837Z", + "operation": "open-foreground", + "wallClockMs": 19170.291792000062, + "daemonDurationMs": 17191, + "responseBytes": 16905, + "nodeCount": 35, + "targetGeneration": 883461, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T15:48:14.494Z", + "finishedAt": "2026-09-01T15:48:32.167Z", + "operation": "open-foreground", + "wallClockMs": 17672.210291999974, + "daemonDurationMs": 16000, + "responseBytes": 16905, + "nodeCount": 35, + "targetGeneration": 939250, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T15:48:44.066Z", + "finishedAt": "2026-09-01T15:49:03.583Z", + "operation": "open-foreground", + "wallClockMs": 19516.302040999988, + "daemonDurationMs": 17620, + "responseBytes": 16906, + "nodeCount": 35, + "targetGeneration": 367317, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 17672.210291999974, + "median": 19170.291792000062, + "p95": 24483.376374999993, + "max": 24483.376374999993, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 16000, + "median": 17191, + "p95": 19235, + "max": 19235, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 16904, + "median": 16905, + "p95": 16907, + "max": 16907, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold-cold", + "screen": "nested-scroll", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T15:49:16.862Z", + "finishedAt": "2026-09-01T15:49:33.604Z", + "operation": "open-foreground", + "wallClockMs": 16741.77241600002, + "daemonDurationMs": 15405, + "responseBytes": 13072, + "nodeCount": 25, + "targetGeneration": 404035, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T15:49:43.688Z", + "finishedAt": "2026-09-01T15:50:04.030Z", + "operation": "open-foreground", + "wallClockMs": 20341.753041999997, + "daemonDurationMs": 18592, + "responseBytes": 13073, + "nodeCount": 25, + "targetGeneration": 776113, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T15:50:14.656Z", + "finishedAt": "2026-09-01T15:50:33.161Z", + "operation": "open-foreground", + "wallClockMs": 18504.61525000003, + "daemonDurationMs": 16948, + "responseBytes": 13072, + "nodeCount": 25, + "targetGeneration": 955661, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T15:50:43.912Z", + "finishedAt": "2026-09-01T15:51:02.455Z", + "operation": "open-foreground", + "wallClockMs": 18542.232707999996, + "daemonDurationMs": 16908, + "responseBytes": 13073, + "nodeCount": 25, + "targetGeneration": 384291, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T15:51:13.183Z", + "finishedAt": "2026-09-01T15:51:32.589Z", + "operation": "open-foreground", + "wallClockMs": 19406.50991699996, + "daemonDurationMs": 17803, + "responseBytes": 13072, + "nodeCount": 25, + "targetGeneration": 590825, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T15:51:41.712Z", + "finishedAt": "2026-09-01T15:52:00.955Z", + "operation": "open-foreground", + "wallClockMs": 19242.605040999944, + "daemonDurationMs": 17773, + "responseBytes": 13072, + "nodeCount": 25, + "targetGeneration": 977719, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T15:52:11.558Z", + "finishedAt": "2026-09-01T15:52:31.040Z", + "operation": "open-foreground", + "wallClockMs": 19481.60162500001, + "daemonDurationMs": 17724, + "responseBytes": 13073, + "nodeCount": 25, + "targetGeneration": 144177, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T15:52:41.000Z", + "finishedAt": "2026-09-01T15:53:00.517Z", + "operation": "open-foreground", + "wallClockMs": 19516.746916999924, + "daemonDurationMs": 17940, + "responseBytes": 13073, + "nodeCount": 25, + "targetGeneration": 711947, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T15:53:14.418Z", + "finishedAt": "2026-09-01T15:53:34.709Z", + "operation": "open-foreground", + "wallClockMs": 20291.17195899994, + "daemonDurationMs": 18398, + "responseBytes": 13071, + "nodeCount": 25, + "targetGeneration": 172219, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T15:53:46.502Z", + "finishedAt": "2026-09-01T15:54:10.042Z", + "operation": "open-foreground", + "wallClockMs": 23539.19962500001, + "daemonDurationMs": 20729, + "responseBytes": 13072, + "nodeCount": 25, + "targetGeneration": 771203, + "firstTree": "readable", + "ok": true, + "outlier": true + } + ], + "wallClockMs": { + "n": 10, + "min": 16741.77241600002, + "median": 19406.50991699996, + "p95": 23539.19962500001, + "max": 23539.19962500001, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 15405, + "median": 17773, + "p95": 20729, + "max": 20729, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 13071, + "median": 13072, + "p95": 13073, + "max": 13073, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold-cold", + "screen": "alert", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T15:54:24.318Z", + "finishedAt": "2026-09-01T15:54:45.859Z", + "operation": "open-foreground", + "wallClockMs": 21540.98095800006, + "daemonDurationMs": 19285, + "responseBytes": 14065, + "nodeCount": 28, + "targetGeneration": 557650, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T15:55:01.680Z", + "finishedAt": "2026-09-01T15:55:22.181Z", + "operation": "open-foreground", + "wallClockMs": 20500.040750000044, + "daemonDurationMs": 17943, + "responseBytes": 14064, + "nodeCount": 28, + "targetGeneration": 366145, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T15:55:37.611Z", + "finishedAt": "2026-09-01T15:55:58.179Z", + "operation": "open-foreground", + "wallClockMs": 20567.714916000026, + "daemonDurationMs": 18391, + "responseBytes": 14065, + "nodeCount": 28, + "targetGeneration": 179608, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T15:56:15.616Z", + "finishedAt": "2026-09-01T15:56:38.396Z", + "operation": "open-foreground", + "wallClockMs": 22780.43604199984, + "daemonDurationMs": 20112, + "responseBytes": 14065, + "nodeCount": 28, + "targetGeneration": 209078, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T15:57:00.945Z", + "finishedAt": "2026-09-01T15:57:20.393Z", + "operation": "open-foreground", + "wallClockMs": 19448.080375000136, + "daemonDurationMs": 13528, + "responseBytes": 14064, + "nodeCount": 28, + "targetGeneration": 696832, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T15:57:40.420Z", + "finishedAt": "2026-09-01T15:58:01.497Z", + "operation": "open-foreground", + "wallClockMs": 21076.482708999887, + "daemonDurationMs": 18767, + "responseBytes": 14065, + "nodeCount": 28, + "targetGeneration": 199999, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T15:58:16.367Z", + "finishedAt": "2026-09-01T15:58:35.067Z", + "operation": "open-foreground", + "wallClockMs": 18700.150917000137, + "daemonDurationMs": 16824, + "responseBytes": 14065, + "nodeCount": 28, + "targetGeneration": 994470, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T15:58:52.246Z", + "finishedAt": "2026-09-01T15:59:10.456Z", + "operation": "open-foreground", + "wallClockMs": 18210.309125000145, + "daemonDurationMs": 16548, + "responseBytes": 14063, + "nodeCount": 28, + "targetGeneration": 275496, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T15:59:25.890Z", + "finishedAt": "2026-09-01T15:59:42.802Z", + "operation": "open-foreground", + "wallClockMs": 16911.38316700002, + "daemonDurationMs": 15262, + "responseBytes": 14063, + "nodeCount": 28, + "targetGeneration": 683008, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:00:00.245Z", + "finishedAt": "2026-09-01T16:00:19.180Z", + "operation": "open-foreground", + "wallClockMs": 18934.49508399982, + "daemonDurationMs": 17436, + "responseBytes": 14064, + "nodeCount": 28, + "targetGeneration": 778333, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 16911.38316700002, + "median": 19448.080375000136, + "p95": 22780.43604199984, + "max": 22780.43604199984, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 13528, + "median": 17436, + "p95": 20112, + "max": 20112, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 14063, + "median": 14064, + "p95": 14065, + "max": 14065, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold-cold", + "screen": "system-surface", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:00:33.751Z", + "finishedAt": "2026-09-01T16:00:53.674Z", + "operation": "open-foreground", + "wallClockMs": 19922.623833000194, + "daemonDurationMs": 18290, + "responseBytes": 9889, + "nodeCount": 18, + "targetGeneration": 561620, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:01:04.091Z", + "finishedAt": "2026-09-01T16:01:23.518Z", + "operation": "open-foreground", + "wallClockMs": 19426.208166999975, + "daemonDurationMs": 17420, + "responseBytes": 9889, + "nodeCount": 18, + "targetGeneration": 313465, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:01:36.367Z", + "finishedAt": "2026-09-01T16:01:58.368Z", + "operation": "open-foreground", + "wallClockMs": 22000.16712499992, + "daemonDurationMs": 17774, + "responseBytes": 9889, + "nodeCount": 18, + "targetGeneration": 361860, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:02:14.509Z", + "finishedAt": "2026-09-01T16:02:34.744Z", + "operation": "open-foreground", + "wallClockMs": 20234.647750000004, + "daemonDurationMs": 18481, + "responseBytes": 9890, + "nodeCount": 18, + "targetGeneration": 357374, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:02:50.489Z", + "finishedAt": "2026-09-01T16:03:09.860Z", + "operation": "open-foreground", + "wallClockMs": 19371.008750000037, + "daemonDurationMs": 17266, + "responseBytes": 9889, + "nodeCount": 18, + "targetGeneration": 984822, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:03:20.453Z", + "finishedAt": "2026-09-01T16:03:42.480Z", + "operation": "open-foreground", + "wallClockMs": 22026.39633399993, + "daemonDurationMs": 19553, + "responseBytes": 9890, + "nodeCount": 18, + "targetGeneration": 828568, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:03:55.404Z", + "finishedAt": "2026-09-01T16:04:16.261Z", + "operation": "open-foreground", + "wallClockMs": 20857.034375000047, + "daemonDurationMs": 17974, + "responseBytes": 9887, + "nodeCount": 18, + "targetGeneration": 441320, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:04:27.089Z", + "finishedAt": "2026-09-01T16:04:52.892Z", + "operation": "open-foreground", + "wallClockMs": 25803.21775000007, + "daemonDurationMs": 23176, + "responseBytes": 9889, + "nodeCount": 18, + "targetGeneration": 769175, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 9, + "startedAt": "2026-09-01T16:05:08.824Z", + "finishedAt": "2026-09-01T16:05:28.588Z", + "operation": "open-foreground", + "wallClockMs": 19763.167084000073, + "daemonDurationMs": 17806, + "responseBytes": 9889, + "nodeCount": 18, + "targetGeneration": 349045, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:05:43.387Z", + "finishedAt": "2026-09-01T16:06:04.690Z", + "operation": "open-foreground", + "wallClockMs": 21302.550042000134, + "daemonDurationMs": 19100, + "responseBytes": 9889, + "nodeCount": 18, + "targetGeneration": 505727, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 19371.008750000037, + "median": 20234.647750000004, + "p95": 25803.21775000007, + "max": 25803.21775000007, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 17266, + "median": 17974, + "p95": 23176, + "max": 23176, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 9887, + "median": 9889, + "p95": 9890, + "max": 9890, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold-cold", + "screen": "xctest-stress", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:06:21.558Z", + "finishedAt": "2026-09-01T16:06:42.991Z", + "operation": "open-foreground", + "wallClockMs": 21433.26770800003, + "daemonDurationMs": 19145, + "responseBytes": 14278, + "nodeCount": 29, + "targetGeneration": 205770, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:06:58.447Z", + "finishedAt": "2026-09-01T16:07:19.258Z", + "operation": "open-foreground", + "wallClockMs": 20810.846542000072, + "daemonDurationMs": 18506, + "responseBytes": 14278, + "nodeCount": 29, + "targetGeneration": 167551, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:07:35.144Z", + "finishedAt": "2026-09-01T16:07:56.805Z", + "operation": "open-foreground", + "wallClockMs": 21660.744582999963, + "daemonDurationMs": 19756, + "responseBytes": 14276, + "nodeCount": 29, + "targetGeneration": 171223, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:08:12.353Z", + "finishedAt": "2026-09-01T16:08:32.821Z", + "operation": "open-foreground", + "wallClockMs": 20468.091665999964, + "daemonDurationMs": 18205, + "responseBytes": 14278, + "nodeCount": 29, + "targetGeneration": 805902, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:08:43.855Z", + "finishedAt": "2026-09-01T16:09:02.747Z", + "operation": "open-foreground", + "wallClockMs": 18891.889874999877, + "daemonDurationMs": 17052, + "responseBytes": 14279, + "nodeCount": 29, + "targetGeneration": 959457, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:09:17.471Z", + "finishedAt": "2026-09-01T16:09:38.752Z", + "operation": "open-foreground", + "wallClockMs": 21279.809624999994, + "daemonDurationMs": 19111, + "responseBytes": 14277, + "nodeCount": 29, + "targetGeneration": 111686, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:09:48.973Z", + "finishedAt": "2026-09-01T16:10:13.947Z", + "operation": "open-foreground", + "wallClockMs": 24972.366999999853, + "daemonDurationMs": 23160, + "responseBytes": 14277, + "nodeCount": 29, + "targetGeneration": 640406, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:10:25.466Z", + "finishedAt": "2026-09-01T16:10:44.151Z", + "operation": "open-foreground", + "wallClockMs": 18685.285667000106, + "daemonDurationMs": 16911, + "responseBytes": 14278, + "nodeCount": 29, + "targetGeneration": 392908, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:10:54.899Z", + "finishedAt": "2026-09-01T16:11:12.810Z", + "operation": "open-foreground", + "wallClockMs": 17910.658916000044, + "daemonDurationMs": 16280, + "responseBytes": 14279, + "nodeCount": 29, + "targetGeneration": 439887, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:11:23.482Z", + "finishedAt": "2026-09-01T16:11:44.576Z", + "operation": "open-foreground", + "wallClockMs": 21093.344040999888, + "daemonDurationMs": 19570, + "responseBytes": 14279, + "nodeCount": 29, + "targetGeneration": 893330, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 17910.658916000044, + "median": 20810.846542000072, + "p95": 24972.366999999853, + "max": 24972.366999999853, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 16280, + "median": 18506, + "p95": 23160, + "max": 23160, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 14276, + "median": 14278, + "p95": 14279, + "max": 14279, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold", + "screen": "quiet", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:11:48.008Z", + "finishedAt": "2026-09-01T16:12:00.058Z", + "operation": "open-foreground", + "wallClockMs": 12049.333625000203, + "daemonDurationMs": 10330, + "responseBytes": 4776, + "nodeCount": 6, + "targetGeneration": 467821, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 2, + "startedAt": "2026-09-01T16:12:08.323Z", + "finishedAt": "2026-09-01T16:12:16.811Z", + "operation": "open-foreground", + "wallClockMs": 8488.316624999978, + "daemonDurationMs": 7434, + "responseBytes": 4773, + "nodeCount": 6, + "targetGeneration": 545079, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 3, + "startedAt": "2026-09-01T16:12:19.815Z", + "finishedAt": "2026-09-01T16:12:26.640Z", + "operation": "open-foreground", + "wallClockMs": 6825.341749999905, + "daemonDurationMs": 6045, + "responseBytes": 4773, + "nodeCount": 6, + "targetGeneration": 557216, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:12:29.319Z", + "finishedAt": "2026-09-01T16:12:35.957Z", + "operation": "open-foreground", + "wallClockMs": 6637.371083999984, + "daemonDurationMs": 5853, + "responseBytes": 4773, + "nodeCount": 6, + "targetGeneration": 955928, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:12:38.481Z", + "finishedAt": "2026-09-01T16:12:45.173Z", + "operation": "open-foreground", + "wallClockMs": 6691.741334000137, + "daemonDurationMs": 5920, + "responseBytes": 4773, + "nodeCount": 6, + "targetGeneration": 165847, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:12:47.698Z", + "finishedAt": "2026-09-01T16:12:54.341Z", + "operation": "open-foreground", + "wallClockMs": 6642.739415999968, + "daemonDurationMs": 5889, + "responseBytes": 4772, + "nodeCount": 6, + "targetGeneration": 637926, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:12:56.865Z", + "finishedAt": "2026-09-01T16:13:03.543Z", + "operation": "open-foreground", + "wallClockMs": 6677.863750000019, + "daemonDurationMs": 5886, + "responseBytes": 4773, + "nodeCount": 6, + "targetGeneration": 158364, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:13:06.295Z", + "finishedAt": "2026-09-01T16:13:12.936Z", + "operation": "open-foreground", + "wallClockMs": 6641.118250000058, + "daemonDurationMs": 5863, + "responseBytes": 4772, + "nodeCount": 6, + "targetGeneration": 718632, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:13:15.463Z", + "finishedAt": "2026-09-01T16:13:21.999Z", + "operation": "open-foreground", + "wallClockMs": 6536.612916999962, + "daemonDurationMs": 5787, + "responseBytes": 4773, + "nodeCount": 6, + "targetGeneration": 508625, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:13:24.518Z", + "finishedAt": "2026-09-01T16:13:31.129Z", + "operation": "open-foreground", + "wallClockMs": 6610.848874999909, + "daemonDurationMs": 5818, + "responseBytes": 4771, + "nodeCount": 6, + "targetGeneration": 327345, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 6536.612916999962, + "median": 6642.739415999968, + "p95": 12049.333625000203, + "max": 12049.333625000203, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 5787, + "median": 5886, + "p95": 10330, + "max": 10330, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 4771, + "median": 4773, + "p95": 4776, + "max": 4776, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold", + "screen": "list", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:13:34.433Z", + "finishedAt": "2026-09-01T16:13:41.247Z", + "operation": "open-foreground", + "wallClockMs": 6814.414791000076, + "daemonDurationMs": 5878, + "responseBytes": 16879, + "nodeCount": 35, + "targetGeneration": 513215, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:13:43.985Z", + "finishedAt": "2026-09-01T16:13:50.751Z", + "operation": "open-foreground", + "wallClockMs": 6765.662709000055, + "daemonDurationMs": 5809, + "responseBytes": 16877, + "nodeCount": 35, + "targetGeneration": 123936, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:13:53.479Z", + "finishedAt": "2026-09-01T16:14:00.244Z", + "operation": "open-foreground", + "wallClockMs": 6764.85479100002, + "daemonDurationMs": 5812, + "responseBytes": 16879, + "nodeCount": 35, + "targetGeneration": 512597, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:14:03.010Z", + "finishedAt": "2026-09-01T16:14:09.917Z", + "operation": "open-foreground", + "wallClockMs": 6907.521583999973, + "daemonDurationMs": 5957, + "responseBytes": 16879, + "nodeCount": 35, + "targetGeneration": 775579, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:14:12.791Z", + "finishedAt": "2026-09-01T16:14:19.642Z", + "operation": "open-foreground", + "wallClockMs": 6850.780875000171, + "daemonDurationMs": 5887, + "responseBytes": 16879, + "nodeCount": 35, + "targetGeneration": 453509, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:14:22.320Z", + "finishedAt": "2026-09-01T16:14:29.194Z", + "operation": "open-foreground", + "wallClockMs": 6873.774582999758, + "daemonDurationMs": 5922, + "responseBytes": 16879, + "nodeCount": 35, + "targetGeneration": 815191, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:14:31.943Z", + "finishedAt": "2026-09-01T16:14:38.912Z", + "operation": "open-foreground", + "wallClockMs": 6968.823749999981, + "daemonDurationMs": 6032, + "responseBytes": 16880, + "nodeCount": 35, + "targetGeneration": 800231, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:14:41.706Z", + "finishedAt": "2026-09-01T16:14:48.981Z", + "operation": "open-foreground", + "wallClockMs": 7275.259459000081, + "daemonDurationMs": 6322, + "responseBytes": 16879, + "nodeCount": 35, + "targetGeneration": 479177, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 9, + "startedAt": "2026-09-01T16:14:51.790Z", + "finishedAt": "2026-09-01T16:14:58.716Z", + "operation": "open-foreground", + "wallClockMs": 6925.9807919999585, + "daemonDurationMs": 5995, + "responseBytes": 16878, + "nodeCount": 35, + "targetGeneration": 143480, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:15:01.428Z", + "finishedAt": "2026-09-01T16:15:08.271Z", + "operation": "open-foreground", + "wallClockMs": 6843.41079199966, + "daemonDurationMs": 5897, + "responseBytes": 16879, + "nodeCount": 35, + "targetGeneration": 214550, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 6764.85479100002, + "median": 6850.780875000171, + "p95": 7275.259459000081, + "max": 7275.259459000081, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 5809, + "median": 5897, + "p95": 6322, + "max": 6322, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 16877, + "median": 16879, + "p95": 16880, + "max": 16880, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold", + "screen": "nested-scroll", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:15:11.687Z", + "finishedAt": "2026-09-01T16:15:18.401Z", + "operation": "open-foreground", + "wallClockMs": 6714.228916000109, + "daemonDurationMs": 5887, + "responseBytes": 13046, + "nodeCount": 25, + "targetGeneration": 925235, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:15:21.022Z", + "finishedAt": "2026-09-01T16:15:27.735Z", + "operation": "open-foreground", + "wallClockMs": 6713.451041999739, + "daemonDurationMs": 5871, + "responseBytes": 13046, + "nodeCount": 25, + "targetGeneration": 954425, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:15:30.327Z", + "finishedAt": "2026-09-01T16:15:36.997Z", + "operation": "open-foreground", + "wallClockMs": 6669.889667000156, + "daemonDurationMs": 5884, + "responseBytes": 13047, + "nodeCount": 25, + "targetGeneration": 746596, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:15:39.669Z", + "finishedAt": "2026-09-01T16:15:46.332Z", + "operation": "open-foreground", + "wallClockMs": 6663.210709000006, + "daemonDurationMs": 5836, + "responseBytes": 13047, + "nodeCount": 25, + "targetGeneration": 217528, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:15:48.925Z", + "finishedAt": "2026-09-01T16:15:55.654Z", + "operation": "open-foreground", + "wallClockMs": 6728.986957999878, + "daemonDurationMs": 5895, + "responseBytes": 13046, + "nodeCount": 25, + "targetGeneration": 203575, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:15:58.336Z", + "finishedAt": "2026-09-01T16:16:05.003Z", + "operation": "open-foreground", + "wallClockMs": 6667.151583999861, + "daemonDurationMs": 5813, + "responseBytes": 13047, + "nodeCount": 25, + "targetGeneration": 431263, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:16:08.422Z", + "finishedAt": "2026-09-01T16:16:15.412Z", + "operation": "open-foreground", + "wallClockMs": 6989.646834000014, + "daemonDurationMs": 6126, + "responseBytes": 13045, + "nodeCount": 25, + "targetGeneration": 498035, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 8, + "startedAt": "2026-09-01T16:16:18.019Z", + "finishedAt": "2026-09-01T16:16:25.096Z", + "operation": "open-foreground", + "wallClockMs": 7077.055833999999, + "daemonDurationMs": 6237, + "responseBytes": 13046, + "nodeCount": 25, + "targetGeneration": 945299, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 9, + "startedAt": "2026-09-01T16:16:27.748Z", + "finishedAt": "2026-09-01T16:16:34.423Z", + "operation": "open-foreground", + "wallClockMs": 6675.096375000197, + "daemonDurationMs": 5813, + "responseBytes": 13047, + "nodeCount": 25, + "targetGeneration": 453118, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:16:37.082Z", + "finishedAt": "2026-09-01T16:16:43.804Z", + "operation": "open-foreground", + "wallClockMs": 6722.447666999884, + "daemonDurationMs": 5925, + "responseBytes": 13045, + "nodeCount": 25, + "targetGeneration": 692846, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 6663.210709000006, + "median": 6713.451041999739, + "p95": 7077.055833999999, + "max": 7077.055833999999, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 5813, + "median": 5884, + "p95": 6237, + "max": 6237, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 13045, + "median": 13046, + "p95": 13047, + "max": 13047, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold", + "screen": "alert", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:16:47.216Z", + "finishedAt": "2026-09-01T16:16:53.906Z", + "operation": "open-foreground", + "wallClockMs": 6689.316208000295, + "daemonDurationMs": 5870, + "responseBytes": 14039, + "nodeCount": 28, + "targetGeneration": 548422, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:16:59.853Z", + "finishedAt": "2026-09-01T16:17:06.487Z", + "operation": "open-foreground", + "wallClockMs": 6634.254290999845, + "daemonDurationMs": 5843, + "responseBytes": 14037, + "nodeCount": 28, + "targetGeneration": 497615, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:17:12.302Z", + "finishedAt": "2026-09-01T16:17:19.015Z", + "operation": "open-foreground", + "wallClockMs": 6712.594749999698, + "daemonDurationMs": 5899, + "responseBytes": 14039, + "nodeCount": 28, + "targetGeneration": 566190, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:17:24.861Z", + "finishedAt": "2026-09-01T16:17:31.453Z", + "operation": "open-foreground", + "wallClockMs": 6592.10566599993, + "daemonDurationMs": 5807, + "responseBytes": 14038, + "nodeCount": 28, + "targetGeneration": 806047, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:17:37.251Z", + "finishedAt": "2026-09-01T16:17:43.906Z", + "operation": "open-foreground", + "wallClockMs": 6654.485417000018, + "daemonDurationMs": 5865, + "responseBytes": 14038, + "nodeCount": 28, + "targetGeneration": 764727, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:17:49.722Z", + "finishedAt": "2026-09-01T16:17:56.397Z", + "operation": "open-foreground", + "wallClockMs": 6674.380083000287, + "daemonDurationMs": 5868, + "responseBytes": 14037, + "nodeCount": 28, + "targetGeneration": 303800, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:18:02.250Z", + "finishedAt": "2026-09-01T16:18:08.891Z", + "operation": "open-foreground", + "wallClockMs": 6641.065167000052, + "daemonDurationMs": 5831, + "responseBytes": 14039, + "nodeCount": 28, + "targetGeneration": 936737, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:18:14.705Z", + "finishedAt": "2026-09-01T16:18:21.382Z", + "operation": "open-foreground", + "wallClockMs": 6676.57412499981, + "daemonDurationMs": 5879, + "responseBytes": 14039, + "nodeCount": 28, + "targetGeneration": 311343, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:18:27.141Z", + "finishedAt": "2026-09-01T16:18:34.116Z", + "operation": "open-foreground", + "wallClockMs": 6974.543209000025, + "daemonDurationMs": 6175, + "responseBytes": 14039, + "nodeCount": 28, + "targetGeneration": 841136, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 10, + "startedAt": "2026-09-01T16:18:40.116Z", + "finishedAt": "2026-09-01T16:18:46.875Z", + "operation": "open-foreground", + "wallClockMs": 6758.907000000123, + "daemonDurationMs": 5952, + "responseBytes": 14038, + "nodeCount": 28, + "targetGeneration": 771861, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 6592.10566599993, + "median": 6674.380083000287, + "p95": 6974.543209000025, + "max": 6974.543209000025, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 5807, + "median": 5868, + "p95": 6175, + "max": 6175, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 14037, + "median": 14038, + "p95": 14039, + "max": 14039, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold", + "screen": "system-surface", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:18:52.695Z", + "finishedAt": "2026-09-01T16:18:59.579Z", + "operation": "open-foreground", + "wallClockMs": 6883.51962500019, + "daemonDurationMs": 5979, + "responseBytes": 9864, + "nodeCount": 18, + "targetGeneration": 997226, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:19:02.162Z", + "finishedAt": "2026-09-01T16:19:09.063Z", + "operation": "open-foreground", + "wallClockMs": 6900.985374999698, + "daemonDurationMs": 6034, + "responseBytes": 9863, + "nodeCount": 18, + "targetGeneration": 806797, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:19:11.693Z", + "finishedAt": "2026-09-01T16:19:20.499Z", + "operation": "open-foreground", + "wallClockMs": 8805.527749999892, + "daemonDurationMs": 7963, + "responseBytes": 9863, + "nodeCount": 18, + "targetGeneration": 330962, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T16:19:23.115Z", + "finishedAt": "2026-09-01T16:19:29.816Z", + "operation": "open-foreground", + "wallClockMs": 6700.248458000366, + "daemonDurationMs": 5838, + "responseBytes": 9863, + "nodeCount": 18, + "targetGeneration": 483745, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:19:32.412Z", + "finishedAt": "2026-09-01T16:19:39.157Z", + "operation": "open-foreground", + "wallClockMs": 6744.326874999795, + "daemonDurationMs": 5870, + "responseBytes": 9863, + "nodeCount": 18, + "targetGeneration": 328229, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:19:41.718Z", + "finishedAt": "2026-09-01T16:19:48.547Z", + "operation": "open-foreground", + "wallClockMs": 6829.058541000355, + "daemonDurationMs": 5958, + "responseBytes": 9862, + "nodeCount": 18, + "targetGeneration": 114181, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:19:51.191Z", + "finishedAt": "2026-09-01T16:19:58.071Z", + "operation": "open-foreground", + "wallClockMs": 6879.0934170000255, + "daemonDurationMs": 5966, + "responseBytes": 9863, + "nodeCount": 18, + "targetGeneration": 662440, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:20:00.781Z", + "finishedAt": "2026-09-01T16:20:07.560Z", + "operation": "open-foreground", + "wallClockMs": 6779.4877920001745, + "daemonDurationMs": 5910, + "responseBytes": 9863, + "nodeCount": 18, + "targetGeneration": 120043, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:20:10.245Z", + "finishedAt": "2026-09-01T16:20:17.023Z", + "operation": "open-foreground", + "wallClockMs": 6778.116249999963, + "daemonDurationMs": 5883, + "responseBytes": 9862, + "nodeCount": 18, + "targetGeneration": 361607, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:20:19.649Z", + "finishedAt": "2026-09-01T16:20:26.468Z", + "operation": "open-foreground", + "wallClockMs": 6819.06645799987, + "daemonDurationMs": 5957, + "responseBytes": 9863, + "nodeCount": 18, + "targetGeneration": 471762, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 6700.248458000366, + "median": 6819.06645799987, + "p95": 8805.527749999892, + "max": 8805.527749999892, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 5838, + "median": 5957, + "p95": 7963, + "max": 7963, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 9862, + "median": 9863, + "p95": 9864, + "max": 9864, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "cold", + "screen": "xctest-stress", + "sampleMinimum": 10, + "operation": "open-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:20:29.956Z", + "finishedAt": "2026-09-01T16:20:36.982Z", + "operation": "open-foreground", + "wallClockMs": 7025.7450409997255, + "daemonDurationMs": 6210, + "responseBytes": 14251, + "nodeCount": 29, + "targetGeneration": 175421, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:20:39.607Z", + "finishedAt": "2026-09-01T16:20:46.321Z", + "operation": "open-foreground", + "wallClockMs": 6714.430542000104, + "daemonDurationMs": 5860, + "responseBytes": 14252, + "nodeCount": 29, + "targetGeneration": 662586, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:20:48.938Z", + "finishedAt": "2026-09-01T16:20:55.642Z", + "operation": "open-foreground", + "wallClockMs": 6704.038375000004, + "daemonDurationMs": 5874, + "responseBytes": 14251, + "nodeCount": 29, + "targetGeneration": 487000, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:20:58.267Z", + "finishedAt": "2026-09-01T16:21:04.900Z", + "operation": "open-foreground", + "wallClockMs": 6633.436166000087, + "daemonDurationMs": 5829, + "responseBytes": 14252, + "nodeCount": 29, + "targetGeneration": 932775, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:21:07.481Z", + "finishedAt": "2026-09-01T16:21:14.089Z", + "operation": "open-foreground", + "wallClockMs": 6607.950249999762, + "daemonDurationMs": 5802, + "responseBytes": 14252, + "nodeCount": 29, + "targetGeneration": 526327, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:21:16.671Z", + "finishedAt": "2026-09-01T16:21:23.342Z", + "operation": "open-foreground", + "wallClockMs": 6671.39308300009, + "daemonDurationMs": 5835, + "responseBytes": 14253, + "nodeCount": 29, + "targetGeneration": 584499, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:21:25.924Z", + "finishedAt": "2026-09-01T16:21:32.688Z", + "operation": "open-foreground", + "wallClockMs": 6764.375, + "daemonDurationMs": 5954, + "responseBytes": 14253, + "nodeCount": 29, + "targetGeneration": 324441, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:21:35.395Z", + "finishedAt": "2026-09-01T16:21:42.388Z", + "operation": "open-foreground", + "wallClockMs": 6992.76316699991, + "daemonDurationMs": 6091, + "responseBytes": 14251, + "nodeCount": 29, + "targetGeneration": 373957, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:21:45.385Z", + "finishedAt": "2026-09-01T16:21:52.430Z", + "operation": "open-foreground", + "wallClockMs": 7044.176832999568, + "daemonDurationMs": 6183, + "responseBytes": 14253, + "nodeCount": 29, + "targetGeneration": 333859, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:21:55.043Z", + "finishedAt": "2026-09-01T16:22:01.794Z", + "operation": "open-foreground", + "wallClockMs": 6750.716917000245, + "daemonDurationMs": 5930, + "responseBytes": 14251, + "nodeCount": 29, + "targetGeneration": 957136, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 10, + "min": 6607.950249999762, + "median": 6714.430542000104, + "p95": 7044.176832999568, + "max": 7044.176832999568, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 10, + "min": 5802, + "median": 5874, + "p95": 6210, + "max": 6210, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 10, + "min": 14251, + "median": 14252, + "p95": 14253, + "max": 14253, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + } + ], + "packageSize": { + "status": "not-run", + "revision": "71fb2483f30d90e615e949601c836aeebbf450c5" + }, + "deepButtonEvidence": { + "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" +} diff --git a/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-cold-local-71fb2483f.md b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-cold-local-71fb2483f.md new file mode 100644 index 000000000..59e3a91f0 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-cold-local-71fb2483f.md @@ -0,0 +1,34 @@ +# iOS snapshot convergence benchmark + +- Status: **completed** +- Revision: 71fb2483f30d90e615e949601c836aeebbf450c5 +- Host: MacBook Pro (Mac16,8; Apple M4 Pro, 12 cores) +- Target: bench-golden-v2 (7E76ECA9-D40C-4833-A711-F870F8CE9363, com.apple.CoreSimulator.SimRuntime.iOS-27-0) +- Generated: 2026-09-01T16:22:03.256Z + +| State | Screen | Transport | Execution | N | Wall median | Wall p95 | Daemon median | Response median | Failures | +|---|---|---|---|---:|---:|---:|---:|---:|---:| +| cold-cold | quiet | local | fresh-process-cli | 10 | 17543.5 | 22929.8 | 15161.0 | 4799.0 | 0 | +| cold-cold | list | local | fresh-process-cli | 10 | 19170.3 | 24483.4 | 17191.0 | 16905.0 | 0 | +| cold-cold | nested-scroll | local | fresh-process-cli | 10 | 19406.5 | 23539.2 | 17773.0 | 13072.0 | 0 | +| cold-cold | alert | local | fresh-process-cli | 10 | 19448.1 | 22780.4 | 17436.0 | 14064.0 | 0 | +| cold-cold | system-surface | local | fresh-process-cli | 10 | 20234.6 | 25803.2 | 17974.0 | 9889.0 | 0 | +| cold-cold | xctest-stress | local | fresh-process-cli | 10 | 20810.8 | 24972.4 | 18506.0 | 14278.0 | 0 | +| cold | quiet | local | fresh-process-cli | 10 | 6642.7 | 12049.3 | 5886.0 | 4773.0 | 0 | +| cold | list | local | fresh-process-cli | 10 | 6850.8 | 7275.3 | 5897.0 | 16879.0 | 0 | +| cold | nested-scroll | local | fresh-process-cli | 10 | 6713.5 | 7077.1 | 5884.0 | 13046.0 | 0 | +| cold | alert | local | fresh-process-cli | 10 | 6674.4 | 6974.5 | 5868.0 | 14038.0 | 0 | +| cold | system-surface | local | fresh-process-cli | 10 | 6819.1 | 8805.5 | 5957.0 | 9863.0 | 0 | +| cold | xctest-stress | local | fresh-process-cli | 10 | 6714.4 | 7044.2 | 5874.0 | 14252.0 | 0 | + +## Package size + +Not measured. + +## Deep-button control + +- Fixture artifact: deep-button-fixture.v1.json (depth 72) +- Red control: pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow (exit 1) + - AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid. +- Safe control: pnpm bench:ios-snapshot:deep-button -- --rule safe-full (exit 0) + - full observation changed and includes the changed descendant. diff --git a/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-proxy-71fb2483f.json b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-proxy-71fb2483f.json new file mode 100644 index 000000000..98c5c1556 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-proxy-71fb2483f.json @@ -0,0 +1,11954 @@ +{ + "schemaVersion": "ios-snapshot-convergence.v1", + "issue": "#2189", + "parent": "#2188", + "references": { + "deepButton": "#1626", + "appMount": "#1571" + }, + "runId": "ios-snapshot-1788283204211-32355", + "generatedAt": "2026-09-01T17:20:04.211Z", + "revision": { + "commit": "71fb2483f30d90e615e949601c836aeebbf450c5", + "branch": "codex/2189-ios-snapshot-baselines", + "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" + }, + "host": { + "model": "MacBook Pro", + "modelIdentifier": "Mac16,8", + "cpu": "Apple M4 Pro", + "cpuCores": 12 + }, + "target": { + "platform": "ios", + "kind": "simulator", + "udid": "7E76ECA9-D40C-4833-A711-F870F8CE9363", + "name": "bench-golden-v2", + "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-27-0", + "appId": "com.callstack.agentdevicelab", + "appPath": "/private/tmp/agent-device-2189-fixture-app-repacked/AgentDeviceTester.app" + }, + "config": { + "warmSampleMinimum": 20, + "coldSampleMinimum": 10, + "requestedSamples": 20, + "screens": ["quiet", "list", "nested-scroll", "alert", "system-surface", "xctest-stress"], + "states": ["cold-cold", "cold", "warm", "relaunch"] + }, + "measurements": [ + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "quiet", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:04:21.222Z", + "finishedAt": "2026-09-01T17:04:22.536Z", + "operation": "snapshot", + "wallClockMs": 1313.856749999999, + "daemonDurationMs": 1178, + "responseBytes": 1924, + "nodeCount": 6, + "targetGeneration": 902045, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 2, + "startedAt": "2026-09-01T17:04:22.536Z", + "finishedAt": "2026-09-01T17:04:23.316Z", + "operation": "snapshot", + "wallClockMs": 779.8466249999983, + "daemonDurationMs": 734, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 902046, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:04:23.316Z", + "finishedAt": "2026-09-01T17:04:24.663Z", + "operation": "snapshot", + "wallClockMs": 1347.4581249999974, + "daemonDurationMs": 1295, + "responseBytes": 1926, + "nodeCount": 6, + "targetGeneration": 902047, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T17:04:24.663Z", + "finishedAt": "2026-09-01T17:04:25.168Z", + "operation": "snapshot", + "wallClockMs": 505.067833000001, + "daemonDurationMs": 461, + "responseBytes": 1923, + "nodeCount": 6, + "targetGeneration": 902048, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:04:25.168Z", + "finishedAt": "2026-09-01T17:04:25.991Z", + "operation": "snapshot", + "wallClockMs": 822.2364999999991, + "daemonDurationMs": 753, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 902049, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:04:25.991Z", + "finishedAt": "2026-09-01T17:04:26.308Z", + "operation": "snapshot", + "wallClockMs": 317.1845420000027, + "daemonDurationMs": 296, + "responseBytes": 1923, + "nodeCount": 6, + "targetGeneration": 902050, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:04:26.308Z", + "finishedAt": "2026-09-01T17:04:26.581Z", + "operation": "snapshot", + "wallClockMs": 273.30120799999713, + "daemonDurationMs": 197, + "responseBytes": 1922, + "nodeCount": 6, + "targetGeneration": 902051, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:04:26.581Z", + "finishedAt": "2026-09-01T17:04:26.809Z", + "operation": "snapshot", + "wallClockMs": 227.8805829999983, + "daemonDurationMs": 195, + "responseBytes": 1924, + "nodeCount": 6, + "targetGeneration": 902052, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:04:26.809Z", + "finishedAt": "2026-09-01T17:04:27.047Z", + "operation": "snapshot", + "wallClockMs": 238.46191700000054, + "daemonDurationMs": 210, + "responseBytes": 1924, + "nodeCount": 6, + "targetGeneration": 902053, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:04:27.048Z", + "finishedAt": "2026-09-01T17:04:27.314Z", + "operation": "snapshot", + "wallClockMs": 265.5486249999958, + "daemonDurationMs": 165, + "responseBytes": 1924, + "nodeCount": 6, + "targetGeneration": 902054, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:04:27.314Z", + "finishedAt": "2026-09-01T17:04:27.710Z", + "operation": "snapshot", + "wallClockMs": 396.4235830000034, + "daemonDurationMs": 340, + "responseBytes": 1924, + "nodeCount": 6, + "targetGeneration": 902055, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:04:27.710Z", + "finishedAt": "2026-09-01T17:04:27.916Z", + "operation": "snapshot", + "wallClockMs": 206.15350000000035, + "daemonDurationMs": 157, + "responseBytes": 1925, + "nodeCount": 6, + "targetGeneration": 902056, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:04:27.916Z", + "finishedAt": "2026-09-01T17:04:28.484Z", + "operation": "snapshot", + "wallClockMs": 567.8543329999957, + "daemonDurationMs": 537, + "responseBytes": 1925, + "nodeCount": 6, + "targetGeneration": 902057, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:04:28.484Z", + "finishedAt": "2026-09-01T17:04:28.629Z", + "operation": "snapshot", + "wallClockMs": 144.89020799999707, + "daemonDurationMs": 113, + "responseBytes": 1925, + "nodeCount": 6, + "targetGeneration": 902058, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:04:28.629Z", + "finishedAt": "2026-09-01T17:04:28.852Z", + "operation": "snapshot", + "wallClockMs": 222.57949999999983, + "daemonDurationMs": 193, + "responseBytes": 1923, + "nodeCount": 6, + "targetGeneration": 902059, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:04:28.852Z", + "finishedAt": "2026-09-01T17:04:29.313Z", + "operation": "snapshot", + "wallClockMs": 461.6324160000004, + "daemonDurationMs": 389, + "responseBytes": 1925, + "nodeCount": 6, + "targetGeneration": 902060, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:04:29.313Z", + "finishedAt": "2026-09-01T17:04:29.560Z", + "operation": "snapshot", + "wallClockMs": 247.12229200000002, + "daemonDurationMs": 211, + "responseBytes": 1924, + "nodeCount": 6, + "targetGeneration": 902061, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:04:29.560Z", + "finishedAt": "2026-09-01T17:04:29.815Z", + "operation": "snapshot", + "wallClockMs": 254.69354100000055, + "daemonDurationMs": 206, + "responseBytes": 1925, + "nodeCount": 6, + "targetGeneration": 902062, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:04:29.815Z", + "finishedAt": "2026-09-01T17:04:30.001Z", + "operation": "snapshot", + "wallClockMs": 185.68470900000102, + "daemonDurationMs": 146, + "responseBytes": 1924, + "nodeCount": 6, + "targetGeneration": 902063, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:04:30.001Z", + "finishedAt": "2026-09-01T17:04:30.361Z", + "operation": "snapshot", + "wallClockMs": 360.28887500000565, + "daemonDurationMs": 304, + "responseBytes": 1924, + "nodeCount": 6, + "targetGeneration": 902064, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 144.89020799999707, + "median": 273.30120799999713, + "p95": 1313.856749999999, + "max": 1347.4581249999974, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 113, + "median": 211, + "p95": 1178, + "max": 1295, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 1921, + "median": 1924, + "p95": 1925, + "max": 1926, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "quiet", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:04:42.894Z", + "finishedAt": "2026-09-01T17:04:43.095Z", + "operation": "snapshot", + "wallClockMs": 201.72845899999083, + "daemonDurationMs": 63, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 214428, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:04:43.096Z", + "finishedAt": "2026-09-01T17:04:43.380Z", + "operation": "snapshot", + "wallClockMs": 283.79674999999406, + "daemonDurationMs": 126, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 214429, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:04:43.380Z", + "finishedAt": "2026-09-01T17:04:43.615Z", + "operation": "snapshot", + "wallClockMs": 235.50108299999556, + "daemonDurationMs": 62, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 214430, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:04:43.615Z", + "finishedAt": "2026-09-01T17:04:43.867Z", + "operation": "snapshot", + "wallClockMs": 252.01324999998906, + "daemonDurationMs": 74, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 214431, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:04:43.867Z", + "finishedAt": "2026-09-01T17:04:44.113Z", + "operation": "snapshot", + "wallClockMs": 246.16266699999687, + "daemonDurationMs": 80, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 214432, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:04:44.113Z", + "finishedAt": "2026-09-01T17:04:44.338Z", + "operation": "snapshot", + "wallClockMs": 224.3089170000021, + "daemonDurationMs": 68, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 214433, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:04:44.338Z", + "finishedAt": "2026-09-01T17:04:44.540Z", + "operation": "snapshot", + "wallClockMs": 202.10362500000338, + "daemonDurationMs": 61, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 214434, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:04:44.540Z", + "finishedAt": "2026-09-01T17:04:44.737Z", + "operation": "snapshot", + "wallClockMs": 196.72420900000725, + "daemonDurationMs": 61, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 214435, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:04:44.737Z", + "finishedAt": "2026-09-01T17:04:44.956Z", + "operation": "snapshot", + "wallClockMs": 218.77958399998897, + "daemonDurationMs": 67, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 214436, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:04:44.956Z", + "finishedAt": "2026-09-01T17:04:45.202Z", + "operation": "snapshot", + "wallClockMs": 246.63225000000966, + "daemonDurationMs": 71, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 214437, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:04:45.203Z", + "finishedAt": "2026-09-01T17:04:45.463Z", + "operation": "snapshot", + "wallClockMs": 260.2000839999964, + "daemonDurationMs": 77, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 214438, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:04:45.463Z", + "finishedAt": "2026-09-01T17:04:45.756Z", + "operation": "snapshot", + "wallClockMs": 293.3477500000008, + "daemonDurationMs": 75, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 214439, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:04:45.756Z", + "finishedAt": "2026-09-01T17:04:45.989Z", + "operation": "snapshot", + "wallClockMs": 233.1810839999962, + "daemonDurationMs": 72, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 214440, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:04:45.989Z", + "finishedAt": "2026-09-01T17:04:46.278Z", + "operation": "snapshot", + "wallClockMs": 288.6695420000033, + "daemonDurationMs": 75, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 214441, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:04:46.278Z", + "finishedAt": "2026-09-01T17:04:46.532Z", + "operation": "snapshot", + "wallClockMs": 254.29237500000454, + "daemonDurationMs": 71, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 214442, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:04:46.532Z", + "finishedAt": "2026-09-01T17:04:46.767Z", + "operation": "snapshot", + "wallClockMs": 234.5365829999937, + "daemonDurationMs": 62, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 214443, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:04:46.767Z", + "finishedAt": "2026-09-01T17:04:46.960Z", + "operation": "snapshot", + "wallClockMs": 192.61870800000906, + "daemonDurationMs": 56, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 214444, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:04:46.960Z", + "finishedAt": "2026-09-01T17:04:47.150Z", + "operation": "snapshot", + "wallClockMs": 190.7183750000113, + "daemonDurationMs": 65, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 214445, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:04:47.151Z", + "finishedAt": "2026-09-01T17:04:47.355Z", + "operation": "snapshot", + "wallClockMs": 204.81691599999613, + "daemonDurationMs": 65, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 214446, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:04:47.355Z", + "finishedAt": "2026-09-01T17:04:47.559Z", + "operation": "snapshot", + "wallClockMs": 203.95320799999172, + "daemonDurationMs": 64, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 214447, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 190.7183750000113, + "median": 233.1810839999962, + "p95": 288.6695420000033, + "max": 293.3477500000008, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 56, + "median": 67, + "p95": 80, + "max": 126, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 1917, + "median": 1919, + "p95": 1920, + "max": 1920, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "list", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:04:56.966Z", + "finishedAt": "2026-09-01T17:04:57.241Z", + "operation": "snapshot", + "wallClockMs": 274.33550000000105, + "daemonDurationMs": 271, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 805293, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:04:57.241Z", + "finishedAt": "2026-09-01T17:04:57.497Z", + "operation": "snapshot", + "wallClockMs": 256.72458399999596, + "daemonDurationMs": 253, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 805294, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:04:57.497Z", + "finishedAt": "2026-09-01T17:04:57.755Z", + "operation": "snapshot", + "wallClockMs": 257.94679099999485, + "daemonDurationMs": 253, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 805295, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:04:57.755Z", + "finishedAt": "2026-09-01T17:04:58.007Z", + "operation": "snapshot", + "wallClockMs": 252.1197919999977, + "daemonDurationMs": 247, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 805296, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:04:58.007Z", + "finishedAt": "2026-09-01T17:04:58.260Z", + "operation": "snapshot", + "wallClockMs": 252.07891599999857, + "daemonDurationMs": 248, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 805297, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:04:58.260Z", + "finishedAt": "2026-09-01T17:04:58.514Z", + "operation": "snapshot", + "wallClockMs": 254.7177090000041, + "daemonDurationMs": 250, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 805298, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:04:58.514Z", + "finishedAt": "2026-09-01T17:04:58.768Z", + "operation": "snapshot", + "wallClockMs": 254.08812499999476, + "daemonDurationMs": 250, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 805299, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:04:58.768Z", + "finishedAt": "2026-09-01T17:04:59.023Z", + "operation": "snapshot", + "wallClockMs": 254.42879200000607, + "daemonDurationMs": 250, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 805300, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:04:59.023Z", + "finishedAt": "2026-09-01T17:04:59.276Z", + "operation": "snapshot", + "wallClockMs": 252.87541700000293, + "daemonDurationMs": 248, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 805301, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:04:59.276Z", + "finishedAt": "2026-09-01T17:04:59.538Z", + "operation": "snapshot", + "wallClockMs": 262.5444159999897, + "daemonDurationMs": 258, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 805302, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:04:59.538Z", + "finishedAt": "2026-09-01T17:04:59.795Z", + "operation": "snapshot", + "wallClockMs": 256.3797499999928, + "daemonDurationMs": 252, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 805303, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:04:59.795Z", + "finishedAt": "2026-09-01T17:05:00.053Z", + "operation": "snapshot", + "wallClockMs": 258.71208299999125, + "daemonDurationMs": 253, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 805304, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:05:00.053Z", + "finishedAt": "2026-09-01T17:05:00.309Z", + "operation": "snapshot", + "wallClockMs": 255.88899999999558, + "daemonDurationMs": 251, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 805305, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:05:00.309Z", + "finishedAt": "2026-09-01T17:05:00.554Z", + "operation": "snapshot", + "wallClockMs": 245.16766700000153, + "daemonDurationMs": 241, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 805306, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:05:00.554Z", + "finishedAt": "2026-09-01T17:05:00.798Z", + "operation": "snapshot", + "wallClockMs": 243.5387919999921, + "daemonDurationMs": 240, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 805307, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:05:00.798Z", + "finishedAt": "2026-09-01T17:05:01.039Z", + "operation": "snapshot", + "wallClockMs": 240.52241700000013, + "daemonDurationMs": 236, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 805308, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:05:01.039Z", + "finishedAt": "2026-09-01T17:05:01.280Z", + "operation": "snapshot", + "wallClockMs": 241.3674170000013, + "daemonDurationMs": 236, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 805309, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:05:01.280Z", + "finishedAt": "2026-09-01T17:05:01.524Z", + "operation": "snapshot", + "wallClockMs": 243.98658300000534, + "daemonDurationMs": 239, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 805310, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:05:01.524Z", + "finishedAt": "2026-09-01T17:05:01.768Z", + "operation": "snapshot", + "wallClockMs": 244.29612500000803, + "daemonDurationMs": 239, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 805311, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:05:01.768Z", + "finishedAt": "2026-09-01T17:05:02.025Z", + "operation": "snapshot", + "wallClockMs": 256.99812499999825, + "daemonDurationMs": 252, + "responseBytes": 8278, + "nodeCount": 35, + "targetGeneration": 805312, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 240.52241700000013, + "median": 254.08812499999476, + "p95": 262.5444159999897, + "max": 274.33550000000105, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 236, + "median": 250, + "p95": 258, + "max": 271, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 8278, + "median": 8281, + "p95": 8283, + "max": 8283, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "list", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:05:12.908Z", + "finishedAt": "2026-09-01T17:05:13.416Z", + "operation": "snapshot", + "wallClockMs": 507.6891250000044, + "daemonDurationMs": 284, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 347131, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:05:13.416Z", + "finishedAt": "2026-09-01T17:05:13.847Z", + "operation": "snapshot", + "wallClockMs": 430.5123329999915, + "daemonDurationMs": 270, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 347132, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:05:13.847Z", + "finishedAt": "2026-09-01T17:05:14.253Z", + "operation": "snapshot", + "wallClockMs": 406.1120840000076, + "daemonDurationMs": 264, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 347133, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:05:14.253Z", + "finishedAt": "2026-09-01T17:05:14.654Z", + "operation": "snapshot", + "wallClockMs": 401.6864579999965, + "daemonDurationMs": 269, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 347134, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:05:14.655Z", + "finishedAt": "2026-09-01T17:05:15.060Z", + "operation": "snapshot", + "wallClockMs": 405.1386659999989, + "daemonDurationMs": 268, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 347135, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:05:15.060Z", + "finishedAt": "2026-09-01T17:05:15.471Z", + "operation": "snapshot", + "wallClockMs": 411.46187500000815, + "daemonDurationMs": 261, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 347136, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:05:15.471Z", + "finishedAt": "2026-09-01T17:05:15.870Z", + "operation": "snapshot", + "wallClockMs": 399.0766250000015, + "daemonDurationMs": 252, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 347137, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:05:15.870Z", + "finishedAt": "2026-09-01T17:05:16.271Z", + "operation": "snapshot", + "wallClockMs": 400.9728749999922, + "daemonDurationMs": 250, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 347138, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:05:16.271Z", + "finishedAt": "2026-09-01T17:05:16.774Z", + "operation": "snapshot", + "wallClockMs": 503.0660829999979, + "daemonDurationMs": 276, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 347139, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:05:16.774Z", + "finishedAt": "2026-09-01T17:05:17.193Z", + "operation": "snapshot", + "wallClockMs": 418.50129100000777, + "daemonDurationMs": 250, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 347140, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:05:17.193Z", + "finishedAt": "2026-09-01T17:05:17.553Z", + "operation": "snapshot", + "wallClockMs": 360.3561250000057, + "daemonDurationMs": 230, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 347141, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:05:17.553Z", + "finishedAt": "2026-09-01T17:05:17.989Z", + "operation": "snapshot", + "wallClockMs": 435.3371249999909, + "daemonDurationMs": 270, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 347142, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:05:17.989Z", + "finishedAt": "2026-09-01T17:05:18.509Z", + "operation": "snapshot", + "wallClockMs": 519.945292000004, + "daemonDurationMs": 276, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 347143, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:05:18.509Z", + "finishedAt": "2026-09-01T17:05:18.935Z", + "operation": "snapshot", + "wallClockMs": 425.92387499999313, + "daemonDurationMs": 253, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 347144, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:05:18.935Z", + "finishedAt": "2026-09-01T17:05:19.459Z", + "operation": "snapshot", + "wallClockMs": 523.901291999995, + "daemonDurationMs": 276, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 347145, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:05:19.459Z", + "finishedAt": "2026-09-01T17:05:19.971Z", + "operation": "snapshot", + "wallClockMs": 512.5795409999992, + "daemonDurationMs": 274, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 347146, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:05:19.971Z", + "finishedAt": "2026-09-01T17:05:20.493Z", + "operation": "snapshot", + "wallClockMs": 521.8409580000007, + "daemonDurationMs": 261, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 347147, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:05:20.493Z", + "finishedAt": "2026-09-01T17:05:20.945Z", + "operation": "snapshot", + "wallClockMs": 451.46241700000246, + "daemonDurationMs": 285, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 347148, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:05:20.945Z", + "finishedAt": "2026-09-01T17:05:21.469Z", + "operation": "snapshot", + "wallClockMs": 524.1050000000105, + "daemonDurationMs": 287, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 347149, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:05:21.469Z", + "finishedAt": "2026-09-01T17:05:21.945Z", + "operation": "snapshot", + "wallClockMs": 476.29133300000103, + "daemonDurationMs": 286, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 347150, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 360.3561250000057, + "median": 430.5123329999915, + "p95": 523.901291999995, + "max": 524.1050000000105, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 230, + "median": 269, + "p95": 286, + "max": 287, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 8279, + "median": 8281, + "p95": 8283, + "max": 8283, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "nested-scroll", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:05:30.971Z", + "finishedAt": "2026-09-01T17:05:31.140Z", + "operation": "snapshot", + "wallClockMs": 168.93020800000522, + "daemonDurationMs": 153, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 392072, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:05:31.140Z", + "finishedAt": "2026-09-01T17:05:31.375Z", + "operation": "snapshot", + "wallClockMs": 235.37016599999333, + "daemonDurationMs": 201, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 392073, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 3, + "startedAt": "2026-09-01T17:05:31.375Z", + "finishedAt": "2026-09-01T17:05:31.604Z", + "operation": "snapshot", + "wallClockMs": 228.91841599998588, + "daemonDurationMs": 220, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 392074, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T17:05:31.604Z", + "finishedAt": "2026-09-01T17:05:31.737Z", + "operation": "snapshot", + "wallClockMs": 133.1466669999936, + "daemonDurationMs": 125, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 392075, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:05:31.737Z", + "finishedAt": "2026-09-01T17:05:31.889Z", + "operation": "snapshot", + "wallClockMs": 152.00158300000476, + "daemonDurationMs": 145, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 392076, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:05:31.889Z", + "finishedAt": "2026-09-01T17:05:32.032Z", + "operation": "snapshot", + "wallClockMs": 142.9013330000016, + "daemonDurationMs": 134, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 392077, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:05:32.032Z", + "finishedAt": "2026-09-01T17:05:32.162Z", + "operation": "snapshot", + "wallClockMs": 130.32412499999919, + "daemonDurationMs": 121, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 392078, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:05:32.162Z", + "finishedAt": "2026-09-01T17:05:32.295Z", + "operation": "snapshot", + "wallClockMs": 132.19079199999396, + "daemonDurationMs": 124, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 392079, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:05:32.295Z", + "finishedAt": "2026-09-01T17:05:32.457Z", + "operation": "snapshot", + "wallClockMs": 162.56179100000008, + "daemonDurationMs": 154, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 392080, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:05:32.457Z", + "finishedAt": "2026-09-01T17:05:32.613Z", + "operation": "snapshot", + "wallClockMs": 156.12479200000234, + "daemonDurationMs": 147, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 392081, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:05:32.613Z", + "finishedAt": "2026-09-01T17:05:32.738Z", + "operation": "snapshot", + "wallClockMs": 124.59524999999849, + "daemonDurationMs": 120, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 392082, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:05:32.738Z", + "finishedAt": "2026-09-01T17:05:32.850Z", + "operation": "snapshot", + "wallClockMs": 111.68583299999591, + "daemonDurationMs": 107, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 392083, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:05:32.850Z", + "finishedAt": "2026-09-01T17:05:33.028Z", + "operation": "snapshot", + "wallClockMs": 178.52720900000713, + "daemonDurationMs": 174, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 392084, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:05:33.028Z", + "finishedAt": "2026-09-01T17:05:33.162Z", + "operation": "snapshot", + "wallClockMs": 133.75612499999988, + "daemonDurationMs": 127, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 392085, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:05:33.162Z", + "finishedAt": "2026-09-01T17:05:33.292Z", + "operation": "snapshot", + "wallClockMs": 129.7042080000101, + "daemonDurationMs": 122, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 392086, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:05:33.292Z", + "finishedAt": "2026-09-01T17:05:33.414Z", + "operation": "snapshot", + "wallClockMs": 122.03145799999766, + "daemonDurationMs": 113, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 392087, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:05:33.414Z", + "finishedAt": "2026-09-01T17:05:33.543Z", + "operation": "snapshot", + "wallClockMs": 129.23854200000642, + "daemonDurationMs": 119, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 392088, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:05:33.543Z", + "finishedAt": "2026-09-01T17:05:33.681Z", + "operation": "snapshot", + "wallClockMs": 137.67779200000223, + "daemonDurationMs": 125, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 392089, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:05:33.681Z", + "finishedAt": "2026-09-01T17:05:33.828Z", + "operation": "snapshot", + "wallClockMs": 147.4563749999943, + "daemonDurationMs": 132, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 392090, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:05:33.828Z", + "finishedAt": "2026-09-01T17:05:34.018Z", + "operation": "snapshot", + "wallClockMs": 190.11925000000338, + "daemonDurationMs": 182, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 392091, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 111.68583299999591, + "median": 137.67779200000223, + "p95": 228.91841599998588, + "max": 235.37016599999333, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 107, + "median": 127, + "p95": 201, + "max": 220, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6273, + "median": 6275, + "p95": 6276, + "max": 6276, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "nested-scroll", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:05:45.653Z", + "finishedAt": "2026-09-01T17:05:45.848Z", + "operation": "snapshot", + "wallClockMs": 194.35379199997988, + "daemonDurationMs": 88, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 134332, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:05:45.848Z", + "finishedAt": "2026-09-01T17:05:46.036Z", + "operation": "snapshot", + "wallClockMs": 187.85779199999524, + "daemonDurationMs": 84, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 134333, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:05:46.036Z", + "finishedAt": "2026-09-01T17:05:46.216Z", + "operation": "snapshot", + "wallClockMs": 180.23191599998972, + "daemonDurationMs": 80, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 134334, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:05:46.216Z", + "finishedAt": "2026-09-01T17:05:46.395Z", + "operation": "snapshot", + "wallClockMs": 179.09579200000735, + "daemonDurationMs": 81, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 134335, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:05:46.395Z", + "finishedAt": "2026-09-01T17:05:46.575Z", + "operation": "snapshot", + "wallClockMs": 179.98549999998068, + "daemonDurationMs": 81, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 134336, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:05:46.575Z", + "finishedAt": "2026-09-01T17:05:46.754Z", + "operation": "snapshot", + "wallClockMs": 178.97916700001224, + "daemonDurationMs": 78, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 134337, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:05:46.754Z", + "finishedAt": "2026-09-01T17:05:46.937Z", + "operation": "snapshot", + "wallClockMs": 182.91287499997998, + "daemonDurationMs": 84, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 134338, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:05:46.937Z", + "finishedAt": "2026-09-01T17:05:47.117Z", + "operation": "snapshot", + "wallClockMs": 180.05179200001294, + "daemonDurationMs": 79, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 134339, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:05:47.117Z", + "finishedAt": "2026-09-01T17:05:47.309Z", + "operation": "snapshot", + "wallClockMs": 192.00775000001886, + "daemonDurationMs": 87, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 134340, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:05:47.309Z", + "finishedAt": "2026-09-01T17:05:47.530Z", + "operation": "snapshot", + "wallClockMs": 221.03445800000918, + "daemonDurationMs": 93, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 134341, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:05:47.530Z", + "finishedAt": "2026-09-01T17:05:47.881Z", + "operation": "snapshot", + "wallClockMs": 350.8609170000127, + "daemonDurationMs": 92, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 134342, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 12, + "startedAt": "2026-09-01T17:05:47.881Z", + "finishedAt": "2026-09-01T17:05:48.066Z", + "operation": "snapshot", + "wallClockMs": 185.02612500000396, + "daemonDurationMs": 81, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 134343, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:05:48.066Z", + "finishedAt": "2026-09-01T17:05:48.249Z", + "operation": "snapshot", + "wallClockMs": 182.59387499999139, + "daemonDurationMs": 81, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 134344, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:05:48.249Z", + "finishedAt": "2026-09-01T17:05:48.501Z", + "operation": "snapshot", + "wallClockMs": 252.29845800000476, + "daemonDurationMs": 96, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 134345, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:05:48.501Z", + "finishedAt": "2026-09-01T17:05:48.860Z", + "operation": "snapshot", + "wallClockMs": 358.6848750000063, + "daemonDurationMs": 87, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 134346, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 16, + "startedAt": "2026-09-01T17:05:48.860Z", + "finishedAt": "2026-09-01T17:05:49.056Z", + "operation": "snapshot", + "wallClockMs": 196.10433299999568, + "daemonDurationMs": 82, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 134347, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:05:49.056Z", + "finishedAt": "2026-09-01T17:05:49.376Z", + "operation": "snapshot", + "wallClockMs": 319.68141700001433, + "daemonDurationMs": 89, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 134348, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 18, + "startedAt": "2026-09-01T17:05:49.376Z", + "finishedAt": "2026-09-01T17:05:49.555Z", + "operation": "snapshot", + "wallClockMs": 179.74529200000688, + "daemonDurationMs": 81, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 134349, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:05:49.555Z", + "finishedAt": "2026-09-01T17:05:49.854Z", + "operation": "snapshot", + "wallClockMs": 298.52900000000955, + "daemonDurationMs": 93, + "responseBytes": 6270, + "nodeCount": 25, + "targetGeneration": 134350, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 20, + "startedAt": "2026-09-01T17:05:49.854Z", + "finishedAt": "2026-09-01T17:05:50.043Z", + "operation": "snapshot", + "wallClockMs": 188.54229199999827, + "daemonDurationMs": 79, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 134351, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 178.97916700001224, + "median": 187.85779199999524, + "p95": 350.8609170000127, + "max": 358.6848750000063, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 78, + "median": 82, + "p95": 93, + "max": 96, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6270, + "median": 6272, + "p95": 6274, + "max": 6274, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "alert", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:06:00.169Z", + "finishedAt": "2026-09-01T17:06:00.278Z", + "operation": "snapshot", + "wallClockMs": 109.31487500001094, + "daemonDurationMs": 104, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 195525, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:06:00.278Z", + "finishedAt": "2026-09-01T17:06:00.390Z", + "operation": "snapshot", + "wallClockMs": 112.13195899999118, + "daemonDurationMs": 106, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 195526, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:06:00.390Z", + "finishedAt": "2026-09-01T17:06:00.501Z", + "operation": "snapshot", + "wallClockMs": 110.27766699998756, + "daemonDurationMs": 104, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 195527, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:06:00.501Z", + "finishedAt": "2026-09-01T17:06:00.610Z", + "operation": "snapshot", + "wallClockMs": 109.16325000001234, + "daemonDurationMs": 102, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195528, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:06:00.610Z", + "finishedAt": "2026-09-01T17:06:00.718Z", + "operation": "snapshot", + "wallClockMs": 108.4163750000007, + "daemonDurationMs": 101, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195529, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:06:00.718Z", + "finishedAt": "2026-09-01T17:06:00.826Z", + "operation": "snapshot", + "wallClockMs": 108.14012500000536, + "daemonDurationMs": 102, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195530, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:06:00.826Z", + "finishedAt": "2026-09-01T17:06:00.939Z", + "operation": "snapshot", + "wallClockMs": 112.50812499999302, + "daemonDurationMs": 103, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 195531, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:06:00.939Z", + "finishedAt": "2026-09-01T17:06:01.052Z", + "operation": "snapshot", + "wallClockMs": 113.10058299999218, + "daemonDurationMs": 105, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 195532, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:06:01.052Z", + "finishedAt": "2026-09-01T17:06:01.169Z", + "operation": "snapshot", + "wallClockMs": 116.9714999999851, + "daemonDurationMs": 109, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195533, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:06:01.169Z", + "finishedAt": "2026-09-01T17:06:01.277Z", + "operation": "snapshot", + "wallClockMs": 107.59075000000303, + "daemonDurationMs": 101, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195534, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:06:01.277Z", + "finishedAt": "2026-09-01T17:06:01.383Z", + "operation": "snapshot", + "wallClockMs": 106.81849999999395, + "daemonDurationMs": 101, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 195535, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:06:01.383Z", + "finishedAt": "2026-09-01T17:06:01.489Z", + "operation": "snapshot", + "wallClockMs": 105.95987500000047, + "daemonDurationMs": 100, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195536, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:06:01.489Z", + "finishedAt": "2026-09-01T17:06:01.595Z", + "operation": "snapshot", + "wallClockMs": 105.18074999999953, + "daemonDurationMs": 100, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 195537, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:06:01.595Z", + "finishedAt": "2026-09-01T17:06:01.703Z", + "operation": "snapshot", + "wallClockMs": 108.10866700002225, + "daemonDurationMs": 102, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195538, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:06:01.703Z", + "finishedAt": "2026-09-01T17:06:01.810Z", + "operation": "snapshot", + "wallClockMs": 107.6779160000151, + "daemonDurationMs": 101, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 195539, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:06:01.810Z", + "finishedAt": "2026-09-01T17:06:01.924Z", + "operation": "snapshot", + "wallClockMs": 113.17366699999548, + "daemonDurationMs": 103, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195540, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:06:01.924Z", + "finishedAt": "2026-09-01T17:06:02.031Z", + "operation": "snapshot", + "wallClockMs": 106.97275000001537, + "daemonDurationMs": 102, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195541, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:06:02.031Z", + "finishedAt": "2026-09-01T17:06:02.144Z", + "operation": "snapshot", + "wallClockMs": 112.99870799999917, + "daemonDurationMs": 105, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195542, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:06:02.144Z", + "finishedAt": "2026-09-01T17:06:02.253Z", + "operation": "snapshot", + "wallClockMs": 108.99233400000958, + "daemonDurationMs": 103, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195543, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:06:02.253Z", + "finishedAt": "2026-09-01T17:06:02.358Z", + "operation": "snapshot", + "wallClockMs": 105.37262500001816, + "daemonDurationMs": 101, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 195544, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 105.18074999999953, + "median": 108.4163750000007, + "p95": 113.17366699999548, + "max": 116.9714999999851, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 100, + "median": 102, + "p95": 106, + "max": 109, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 7165, + "median": 7168, + "p95": 7168, + "max": 7168, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "alert", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:06:13.128Z", + "finishedAt": "2026-09-01T17:06:13.371Z", + "operation": "snapshot", + "wallClockMs": 242.59091600001557, + "daemonDurationMs": 118, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 289667, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:06:13.371Z", + "finishedAt": "2026-09-01T17:06:13.611Z", + "operation": "snapshot", + "wallClockMs": 239.78883400000632, + "daemonDurationMs": 106, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 289668, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:06:13.611Z", + "finishedAt": "2026-09-01T17:06:13.834Z", + "operation": "snapshot", + "wallClockMs": 223.39145900000585, + "daemonDurationMs": 112, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 289669, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:06:13.834Z", + "finishedAt": "2026-09-01T17:06:14.329Z", + "operation": "snapshot", + "wallClockMs": 494.35425000000396, + "daemonDurationMs": 113, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 289670, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 5, + "startedAt": "2026-09-01T17:06:14.329Z", + "finishedAt": "2026-09-01T17:06:14.577Z", + "operation": "snapshot", + "wallClockMs": 248.43341700002202, + "daemonDurationMs": 107, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289671, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:06:14.577Z", + "finishedAt": "2026-09-01T17:06:14.787Z", + "operation": "snapshot", + "wallClockMs": 210.16908399999375, + "daemonDurationMs": 106, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289672, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:06:14.787Z", + "finishedAt": "2026-09-01T17:06:14.988Z", + "operation": "snapshot", + "wallClockMs": 201.0640420000127, + "daemonDurationMs": 102, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289673, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:06:14.988Z", + "finishedAt": "2026-09-01T17:06:15.224Z", + "operation": "snapshot", + "wallClockMs": 235.83762499998556, + "daemonDurationMs": 125, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289674, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:06:15.224Z", + "finishedAt": "2026-09-01T17:06:15.437Z", + "operation": "snapshot", + "wallClockMs": 212.75795899998047, + "daemonDurationMs": 106, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 289675, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:06:15.437Z", + "finishedAt": "2026-09-01T17:06:15.688Z", + "operation": "snapshot", + "wallClockMs": 250.64937499997905, + "daemonDurationMs": 131, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289676, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:06:15.688Z", + "finishedAt": "2026-09-01T17:06:15.905Z", + "operation": "snapshot", + "wallClockMs": 217.44200000001, + "daemonDurationMs": 105, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289677, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:06:15.905Z", + "finishedAt": "2026-09-01T17:06:16.109Z", + "operation": "snapshot", + "wallClockMs": 203.6089159999974, + "daemonDurationMs": 100, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289678, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:06:16.109Z", + "finishedAt": "2026-09-01T17:06:16.313Z", + "operation": "snapshot", + "wallClockMs": 204.01062499999534, + "daemonDurationMs": 102, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 289679, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:06:16.313Z", + "finishedAt": "2026-09-01T17:06:16.520Z", + "operation": "snapshot", + "wallClockMs": 206.91679200000362, + "daemonDurationMs": 103, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 289680, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:06:16.520Z", + "finishedAt": "2026-09-01T17:06:16.719Z", + "operation": "snapshot", + "wallClockMs": 199.40300000002026, + "daemonDurationMs": 99, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 289681, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:06:16.719Z", + "finishedAt": "2026-09-01T17:06:16.922Z", + "operation": "snapshot", + "wallClockMs": 202.25162500000442, + "daemonDurationMs": 100, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289682, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:06:16.922Z", + "finishedAt": "2026-09-01T17:06:17.121Z", + "operation": "snapshot", + "wallClockMs": 199.52962500002468, + "daemonDurationMs": 101, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 289683, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:06:17.121Z", + "finishedAt": "2026-09-01T17:06:17.399Z", + "operation": "snapshot", + "wallClockMs": 278.0522500000079, + "daemonDurationMs": 102, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 289684, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:06:17.399Z", + "finishedAt": "2026-09-01T17:06:17.599Z", + "operation": "snapshot", + "wallClockMs": 199.2951250000042, + "daemonDurationMs": 102, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 289685, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:06:17.599Z", + "finishedAt": "2026-09-01T17:06:17.803Z", + "operation": "snapshot", + "wallClockMs": 204.78008399999817, + "daemonDurationMs": 103, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 289686, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 199.2951250000042, + "median": 210.16908399999375, + "p95": 278.0522500000079, + "max": 494.35425000000396, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 99, + "median": 103, + "p95": 125, + "max": 131, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 7165, + "median": 7167, + "p95": 7168, + "max": 7168, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "system-surface", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:06:27.092Z", + "finishedAt": "2026-09-01T17:06:27.198Z", + "operation": "snapshot", + "wallClockMs": 106.0126670000027, + "daemonDurationMs": 102, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 829953, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:06:27.198Z", + "finishedAt": "2026-09-01T17:06:27.307Z", + "operation": "snapshot", + "wallClockMs": 108.38020800001686, + "daemonDurationMs": 106, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 829954, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 3, + "startedAt": "2026-09-01T17:06:27.307Z", + "finishedAt": "2026-09-01T17:06:27.448Z", + "operation": "snapshot", + "wallClockMs": 141.49783400000888, + "daemonDurationMs": 138, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 829955, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T17:06:27.448Z", + "finishedAt": "2026-09-01T17:06:27.552Z", + "operation": "snapshot", + "wallClockMs": 103.71379199999501, + "daemonDurationMs": 101, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 829956, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:06:27.552Z", + "finishedAt": "2026-09-01T17:06:27.655Z", + "operation": "snapshot", + "wallClockMs": 103.54116699998849, + "daemonDurationMs": 101, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 829957, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:06:27.655Z", + "finishedAt": "2026-09-01T17:06:27.758Z", + "operation": "snapshot", + "wallClockMs": 102.63499999998021, + "daemonDurationMs": 100, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 829958, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:06:27.758Z", + "finishedAt": "2026-09-01T17:06:27.863Z", + "operation": "snapshot", + "wallClockMs": 105.35733300002175, + "daemonDurationMs": 103, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 829959, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:06:27.863Z", + "finishedAt": "2026-09-01T17:06:27.969Z", + "operation": "snapshot", + "wallClockMs": 105.2759580000129, + "daemonDurationMs": 103, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 829960, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:06:27.969Z", + "finishedAt": "2026-09-01T17:06:28.073Z", + "operation": "snapshot", + "wallClockMs": 104.59500000000116, + "daemonDurationMs": 101, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829961, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:06:28.073Z", + "finishedAt": "2026-09-01T17:06:28.178Z", + "operation": "snapshot", + "wallClockMs": 104.4855830000015, + "daemonDurationMs": 102, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 829962, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:06:28.178Z", + "finishedAt": "2026-09-01T17:06:28.284Z", + "operation": "snapshot", + "wallClockMs": 105.84899999998743, + "daemonDurationMs": 103, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829963, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:06:28.284Z", + "finishedAt": "2026-09-01T17:06:28.389Z", + "operation": "snapshot", + "wallClockMs": 104.8588340000133, + "daemonDurationMs": 102, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 829964, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:06:28.389Z", + "finishedAt": "2026-09-01T17:06:28.494Z", + "operation": "snapshot", + "wallClockMs": 105.76583400001982, + "daemonDurationMs": 102, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829965, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:06:28.494Z", + "finishedAt": "2026-09-01T17:06:28.599Z", + "operation": "snapshot", + "wallClockMs": 105.05241600002046, + "daemonDurationMs": 101, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 829966, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:06:28.599Z", + "finishedAt": "2026-09-01T17:06:28.705Z", + "operation": "snapshot", + "wallClockMs": 105.51329200001783, + "daemonDurationMs": 102, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829967, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:06:28.705Z", + "finishedAt": "2026-09-01T17:06:28.809Z", + "operation": "snapshot", + "wallClockMs": 103.81812499999069, + "daemonDurationMs": 101, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829968, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:06:28.809Z", + "finishedAt": "2026-09-01T17:06:28.913Z", + "operation": "snapshot", + "wallClockMs": 103.984375, + "daemonDurationMs": 101, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829969, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:06:28.913Z", + "finishedAt": "2026-09-01T17:06:29.018Z", + "operation": "snapshot", + "wallClockMs": 105.01729200000409, + "daemonDurationMs": 102, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829970, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:06:29.018Z", + "finishedAt": "2026-09-01T17:06:29.122Z", + "operation": "snapshot", + "wallClockMs": 104.38179200000013, + "daemonDurationMs": 101, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829971, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:06:29.122Z", + "finishedAt": "2026-09-01T17:06:29.227Z", + "operation": "snapshot", + "wallClockMs": 105.15891699999338, + "daemonDurationMs": 102, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 829972, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 102.63499999998021, + "median": 105.01729200000409, + "p95": 108.38020800001686, + "max": 141.49783400000888, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 100, + "median": 102, + "p95": 106, + "max": 138, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 4608, + "median": 4610, + "p95": 4611, + "max": 4611, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "system-surface", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:06:37.229Z", + "finishedAt": "2026-09-01T17:06:37.468Z", + "operation": "snapshot", + "wallClockMs": 238.24795799999265, + "daemonDurationMs": 130, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 694242, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:06:37.468Z", + "finishedAt": "2026-09-01T17:06:37.676Z", + "operation": "snapshot", + "wallClockMs": 208.6802500000049, + "daemonDurationMs": 106, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 694243, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:06:37.676Z", + "finishedAt": "2026-09-01T17:06:37.891Z", + "operation": "snapshot", + "wallClockMs": 214.9134999999951, + "daemonDurationMs": 111, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 694244, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:06:37.891Z", + "finishedAt": "2026-09-01T17:06:38.099Z", + "operation": "snapshot", + "wallClockMs": 208.14983300000313, + "daemonDurationMs": 107, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 694245, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:06:38.099Z", + "finishedAt": "2026-09-01T17:06:38.322Z", + "operation": "snapshot", + "wallClockMs": 222.93945899998653, + "daemonDurationMs": 110, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 694246, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:06:38.322Z", + "finishedAt": "2026-09-01T17:06:38.532Z", + "operation": "snapshot", + "wallClockMs": 209.4709579999908, + "daemonDurationMs": 106, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 694247, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:06:38.532Z", + "finishedAt": "2026-09-01T17:06:38.739Z", + "operation": "snapshot", + "wallClockMs": 206.75149999998393, + "daemonDurationMs": 106, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 694248, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:06:38.739Z", + "finishedAt": "2026-09-01T17:06:38.944Z", + "operation": "snapshot", + "wallClockMs": 204.8096249999944, + "daemonDurationMs": 106, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 694249, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:06:38.944Z", + "finishedAt": "2026-09-01T17:06:39.150Z", + "operation": "snapshot", + "wallClockMs": 206.8397910000058, + "daemonDurationMs": 108, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 694250, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:06:39.150Z", + "finishedAt": "2026-09-01T17:06:39.357Z", + "operation": "snapshot", + "wallClockMs": 206.58058300000266, + "daemonDurationMs": 106, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 694251, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:06:39.357Z", + "finishedAt": "2026-09-01T17:06:39.565Z", + "operation": "snapshot", + "wallClockMs": 208.43437500001164, + "daemonDurationMs": 105, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 694252, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:06:39.566Z", + "finishedAt": "2026-09-01T17:06:39.774Z", + "operation": "snapshot", + "wallClockMs": 208.5887090000033, + "daemonDurationMs": 106, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 694253, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:06:39.774Z", + "finishedAt": "2026-09-01T17:06:39.983Z", + "operation": "snapshot", + "wallClockMs": 208.80333299998892, + "daemonDurationMs": 110, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 694254, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:06:39.983Z", + "finishedAt": "2026-09-01T17:06:40.201Z", + "operation": "snapshot", + "wallClockMs": 217.83341600000858, + "daemonDurationMs": 114, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 694255, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:06:40.201Z", + "finishedAt": "2026-09-01T17:06:40.442Z", + "operation": "snapshot", + "wallClockMs": 240.86516700001084, + "daemonDurationMs": 113, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 694256, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:06:40.442Z", + "finishedAt": "2026-09-01T17:06:40.667Z", + "operation": "snapshot", + "wallClockMs": 225.69191599998157, + "daemonDurationMs": 110, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 694257, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:06:40.668Z", + "finishedAt": "2026-09-01T17:06:40.892Z", + "operation": "snapshot", + "wallClockMs": 224.95754100001068, + "daemonDurationMs": 112, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 694258, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:06:40.893Z", + "finishedAt": "2026-09-01T17:06:41.113Z", + "operation": "snapshot", + "wallClockMs": 220.12108299997635, + "daemonDurationMs": 111, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 694259, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:06:41.113Z", + "finishedAt": "2026-09-01T17:06:41.343Z", + "operation": "snapshot", + "wallClockMs": 230.3159169999999, + "daemonDurationMs": 114, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 694260, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:06:41.343Z", + "finishedAt": "2026-09-01T17:06:41.574Z", + "operation": "snapshot", + "wallClockMs": 231.11633399999118, + "daemonDurationMs": 110, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 694261, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 204.8096249999944, + "median": 209.4709579999908, + "p95": 238.24795799999265, + "max": 240.86516700001084, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 105, + "median": 110, + "p95": 114, + "max": 130, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 4608, + "median": 4610, + "p95": 4611, + "max": 4611, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "xctest-stress", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:06:49.213Z", + "finishedAt": "2026-09-01T17:06:49.334Z", + "operation": "snapshot", + "wallClockMs": 120.84691699998803, + "daemonDurationMs": 117, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 110574, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:06:49.334Z", + "finishedAt": "2026-09-01T17:06:49.459Z", + "operation": "snapshot", + "wallClockMs": 124.48012500000186, + "daemonDurationMs": 120, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 110575, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:06:49.459Z", + "finishedAt": "2026-09-01T17:06:49.643Z", + "operation": "snapshot", + "wallClockMs": 184.55704200000037, + "daemonDurationMs": 176, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 110576, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T17:06:49.643Z", + "finishedAt": "2026-09-01T17:06:49.770Z", + "operation": "snapshot", + "wallClockMs": 126.91783300001407, + "daemonDurationMs": 122, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 110577, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:06:49.770Z", + "finishedAt": "2026-09-01T17:06:49.897Z", + "operation": "snapshot", + "wallClockMs": 126.82641700000386, + "daemonDurationMs": 120, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 110578, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:06:49.897Z", + "finishedAt": "2026-09-01T17:06:50.025Z", + "operation": "snapshot", + "wallClockMs": 128.14308300000266, + "daemonDurationMs": 124, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 110579, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:06:50.025Z", + "finishedAt": "2026-09-01T17:06:50.160Z", + "operation": "snapshot", + "wallClockMs": 134.92920799998683, + "daemonDurationMs": 128, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 110580, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:06:50.160Z", + "finishedAt": "2026-09-01T17:06:50.329Z", + "operation": "snapshot", + "wallClockMs": 168.32962499998393, + "daemonDurationMs": 160, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 110581, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 9, + "startedAt": "2026-09-01T17:06:50.329Z", + "finishedAt": "2026-09-01T17:06:50.462Z", + "operation": "snapshot", + "wallClockMs": 133.48637499997858, + "daemonDurationMs": 127, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 110582, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:06:50.462Z", + "finishedAt": "2026-09-01T17:06:50.587Z", + "operation": "snapshot", + "wallClockMs": 125.17762500001118, + "daemonDurationMs": 118, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 110583, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:06:50.587Z", + "finishedAt": "2026-09-01T17:06:50.723Z", + "operation": "snapshot", + "wallClockMs": 135.25875000000815, + "daemonDurationMs": 129, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 110584, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:06:50.723Z", + "finishedAt": "2026-09-01T17:06:50.863Z", + "operation": "snapshot", + "wallClockMs": 140.14287500001956, + "daemonDurationMs": 129, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 110585, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:06:50.863Z", + "finishedAt": "2026-09-01T17:06:51.031Z", + "operation": "snapshot", + "wallClockMs": 168.68237500000396, + "daemonDurationMs": 148, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 110586, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 14, + "startedAt": "2026-09-01T17:06:51.031Z", + "finishedAt": "2026-09-01T17:06:51.175Z", + "operation": "snapshot", + "wallClockMs": 143.8393329999817, + "daemonDurationMs": 121, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 110587, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:06:51.175Z", + "finishedAt": "2026-09-01T17:06:51.293Z", + "operation": "snapshot", + "wallClockMs": 118.13716600000043, + "daemonDurationMs": 112, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 110588, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:06:51.293Z", + "finishedAt": "2026-09-01T17:06:51.410Z", + "operation": "snapshot", + "wallClockMs": 117.10404100001324, + "daemonDurationMs": 112, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 110589, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:06:51.410Z", + "finishedAt": "2026-09-01T17:06:51.527Z", + "operation": "snapshot", + "wallClockMs": 116.9960420000134, + "daemonDurationMs": 113, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 110590, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:06:51.528Z", + "finishedAt": "2026-09-01T17:06:51.641Z", + "operation": "snapshot", + "wallClockMs": 113.14599999997881, + "daemonDurationMs": 109, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 110591, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:06:51.641Z", + "finishedAt": "2026-09-01T17:06:51.758Z", + "operation": "snapshot", + "wallClockMs": 117.09829200000968, + "daemonDurationMs": 113, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 110592, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:06:51.758Z", + "finishedAt": "2026-09-01T17:06:51.872Z", + "operation": "snapshot", + "wallClockMs": 114.60487499998999, + "daemonDurationMs": 111, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 110593, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 113.14599999997881, + "median": 126.82641700000386, + "p95": 168.68237500000396, + "max": 184.55704200000037, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 109, + "median": 120, + "p95": 160, + "max": 176, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6840, + "median": 6842, + "p95": 6843, + "max": 6843, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "xctest-stress", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:07:00.581Z", + "finishedAt": "2026-09-01T17:07:00.834Z", + "operation": "snapshot", + "wallClockMs": 252.33937500001048, + "daemonDurationMs": 134, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 451835, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:07:00.834Z", + "finishedAt": "2026-09-01T17:07:01.054Z", + "operation": "snapshot", + "wallClockMs": 220.79850000000442, + "daemonDurationMs": 108, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 451836, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:07:01.054Z", + "finishedAt": "2026-09-01T17:07:01.294Z", + "operation": "snapshot", + "wallClockMs": 240.0444579999894, + "daemonDurationMs": 117, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 451837, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:07:01.294Z", + "finishedAt": "2026-09-01T17:07:01.515Z", + "operation": "snapshot", + "wallClockMs": 220.47841700000572, + "daemonDurationMs": 104, + "responseBytes": 6838, + "nodeCount": 29, + "targetGeneration": 451838, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:07:01.515Z", + "finishedAt": "2026-09-01T17:07:01.729Z", + "operation": "snapshot", + "wallClockMs": 213.85191599998507, + "daemonDurationMs": 110, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 451839, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:07:01.729Z", + "finishedAt": "2026-09-01T17:07:01.970Z", + "operation": "snapshot", + "wallClockMs": 240.7053329999908, + "daemonDurationMs": 108, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 451840, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:07:01.970Z", + "finishedAt": "2026-09-01T17:07:02.182Z", + "operation": "snapshot", + "wallClockMs": 212.303791000013, + "daemonDurationMs": 105, + "responseBytes": 6834, + "nodeCount": 29, + "targetGeneration": 451841, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:07:02.182Z", + "finishedAt": "2026-09-01T17:07:02.418Z", + "operation": "snapshot", + "wallClockMs": 235.79375000001164, + "daemonDurationMs": 113, + "responseBytes": 6839, + "nodeCount": 29, + "targetGeneration": 451842, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:07:02.418Z", + "finishedAt": "2026-09-01T17:07:02.625Z", + "operation": "snapshot", + "wallClockMs": 207.07354199999827, + "daemonDurationMs": 102, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 451843, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:07:02.625Z", + "finishedAt": "2026-09-01T17:07:02.848Z", + "operation": "snapshot", + "wallClockMs": 222.89616599999135, + "daemonDurationMs": 111, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 451844, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:07:02.848Z", + "finishedAt": "2026-09-01T17:07:03.058Z", + "operation": "snapshot", + "wallClockMs": 209.62329200000386, + "daemonDurationMs": 105, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 451845, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:07:03.058Z", + "finishedAt": "2026-09-01T17:07:03.295Z", + "operation": "snapshot", + "wallClockMs": 237.40454199997475, + "daemonDurationMs": 118, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 451846, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:07:03.295Z", + "finishedAt": "2026-09-01T17:07:03.607Z", + "operation": "snapshot", + "wallClockMs": 312.4269159999967, + "daemonDurationMs": 125, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 451847, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 14, + "startedAt": "2026-09-01T17:07:03.607Z", + "finishedAt": "2026-09-01T17:07:03.883Z", + "operation": "snapshot", + "wallClockMs": 275.05770900001517, + "daemonDurationMs": 117, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 451848, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 15, + "startedAt": "2026-09-01T17:07:03.883Z", + "finishedAt": "2026-09-01T17:07:04.161Z", + "operation": "snapshot", + "wallClockMs": 278.27074999999604, + "daemonDurationMs": 126, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 451849, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 16, + "startedAt": "2026-09-01T17:07:04.161Z", + "finishedAt": "2026-09-01T17:07:04.410Z", + "operation": "snapshot", + "wallClockMs": 249.48399999999674, + "daemonDurationMs": 116, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 451850, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:07:04.410Z", + "finishedAt": "2026-09-01T17:07:04.632Z", + "operation": "snapshot", + "wallClockMs": 221.61725000001024, + "daemonDurationMs": 114, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 451851, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:07:04.632Z", + "finishedAt": "2026-09-01T17:07:04.860Z", + "operation": "snapshot", + "wallClockMs": 227.65454099999624, + "daemonDurationMs": 114, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 451852, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:07:04.860Z", + "finishedAt": "2026-09-01T17:07:05.079Z", + "operation": "snapshot", + "wallClockMs": 219.6325829999987, + "daemonDurationMs": 109, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 451853, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:07:05.079Z", + "finishedAt": "2026-09-01T17:07:05.304Z", + "operation": "snapshot", + "wallClockMs": 224.8399170000048, + "daemonDurationMs": 111, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 451854, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + "wallClockMs": { + "n": 20, + "min": 207.07354199999827, + "median": 224.8399170000048, + "p95": 278.27074999999604, + "max": 312.4269159999967, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 102, + "median": 111, + "p95": 126, + "max": 134, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6834, + "median": 6841, + "p95": 6843, + "max": 6843, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "quiet", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:07:14.636Z", + "finishedAt": "2026-09-01T17:07:15.212Z", + "operation": "snapshot", + "wallClockMs": 575.2980830000015, + "daemonDurationMs": 71, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 601501, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:07:15.212Z", + "finishedAt": "2026-09-01T17:07:15.699Z", + "operation": "snapshot", + "wallClockMs": 486.7808329999971, + "daemonDurationMs": 61, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 601502, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:07:15.699Z", + "finishedAt": "2026-09-01T17:07:16.566Z", + "operation": "snapshot", + "wallClockMs": 867.5259170000209, + "daemonDurationMs": 52, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 601503, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:07:16.566Z", + "finishedAt": "2026-09-01T17:07:17.121Z", + "operation": "snapshot", + "wallClockMs": 555.408792000002, + "daemonDurationMs": 53, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 601504, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:07:17.121Z", + "finishedAt": "2026-09-01T17:07:17.694Z", + "operation": "snapshot", + "wallClockMs": 572.3494590000191, + "daemonDurationMs": 71, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 601505, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:07:17.694Z", + "finishedAt": "2026-09-01T17:07:18.097Z", + "operation": "snapshot", + "wallClockMs": 403.0825419999892, + "daemonDurationMs": 54, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 601506, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:07:18.097Z", + "finishedAt": "2026-09-01T17:07:18.253Z", + "operation": "snapshot", + "wallClockMs": 155.94075000000885, + "daemonDurationMs": 58, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 601507, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:07:18.253Z", + "finishedAt": "2026-09-01T17:07:18.812Z", + "operation": "snapshot", + "wallClockMs": 558.9902080000029, + "daemonDurationMs": 57, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 601508, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:07:18.812Z", + "finishedAt": "2026-09-01T17:07:19.311Z", + "operation": "snapshot", + "wallClockMs": 499.0495419999934, + "daemonDurationMs": 55, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 601509, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:07:19.311Z", + "finishedAt": "2026-09-01T17:07:20.073Z", + "operation": "snapshot", + "wallClockMs": 762.458249999996, + "daemonDurationMs": 60, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 601510, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:07:20.073Z", + "finishedAt": "2026-09-01T17:07:20.872Z", + "operation": "snapshot", + "wallClockMs": 798.2340420000255, + "daemonDurationMs": 58, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 601511, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:07:20.872Z", + "finishedAt": "2026-09-01T17:07:21.420Z", + "operation": "snapshot", + "wallClockMs": 547.9422919999924, + "daemonDurationMs": 96, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 601512, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:07:21.420Z", + "finishedAt": "2026-09-01T17:07:21.981Z", + "operation": "snapshot", + "wallClockMs": 561.529332999984, + "daemonDurationMs": 60, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 601513, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:07:21.981Z", + "finishedAt": "2026-09-01T17:07:22.474Z", + "operation": "snapshot", + "wallClockMs": 493.20979100000113, + "daemonDurationMs": 54, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 601514, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:07:22.474Z", + "finishedAt": "2026-09-01T17:07:23.151Z", + "operation": "snapshot", + "wallClockMs": 676.7175829999906, + "daemonDurationMs": 65, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 601515, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:07:23.151Z", + "finishedAt": "2026-09-01T17:07:24.076Z", + "operation": "snapshot", + "wallClockMs": 924.7909999999974, + "daemonDurationMs": 60, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 601516, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:07:24.076Z", + "finishedAt": "2026-09-01T17:07:24.638Z", + "operation": "snapshot", + "wallClockMs": 561.9752499999886, + "daemonDurationMs": 61, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 601517, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:07:24.638Z", + "finishedAt": "2026-09-01T17:07:25.130Z", + "operation": "snapshot", + "wallClockMs": 491.7075419999892, + "daemonDurationMs": 54, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 601518, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:07:25.130Z", + "finishedAt": "2026-09-01T17:07:26.148Z", + "operation": "snapshot", + "wallClockMs": 1018.6978749999835, + "daemonDurationMs": 60, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 601519, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:07:26.148Z", + "finishedAt": "2026-09-01T17:07:27.076Z", + "operation": "snapshot", + "wallClockMs": 927.4457920000132, + "daemonDurationMs": 61, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 601520, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 155.94075000000885, + "median": 561.529332999984, + "p95": 927.4457920000132, + "max": 1018.6978749999835, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 52, + "median": 60, + "p95": 71, + "max": 96, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 1917, + "median": 1919, + "p95": 1921, + "max": 1921, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "quiet", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:07:39.149Z", + "finishedAt": "2026-09-01T17:07:39.794Z", + "operation": "snapshot", + "wallClockMs": 645.8771249999991, + "daemonDurationMs": 74, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 337102, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 2, + "startedAt": "2026-09-01T17:07:39.794Z", + "finishedAt": "2026-09-01T17:07:41.068Z", + "operation": "snapshot", + "wallClockMs": 1273.2234579999931, + "daemonDurationMs": 52, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 337103, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:07:41.068Z", + "finishedAt": "2026-09-01T17:07:42.152Z", + "operation": "snapshot", + "wallClockMs": 1083.784249999997, + "daemonDurationMs": 76, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 337104, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:07:42.152Z", + "finishedAt": "2026-09-01T17:07:43.116Z", + "operation": "snapshot", + "wallClockMs": 964.275250000006, + "daemonDurationMs": 71, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 337105, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:07:43.116Z", + "finishedAt": "2026-09-01T17:07:45.092Z", + "operation": "snapshot", + "wallClockMs": 1975.7905000000028, + "daemonDurationMs": 72, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 337106, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 6, + "startedAt": "2026-09-01T17:07:45.092Z", + "finishedAt": "2026-09-01T17:07:46.175Z", + "operation": "snapshot", + "wallClockMs": 1083.3291660000104, + "daemonDurationMs": 75, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 337107, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:07:46.175Z", + "finishedAt": "2026-09-01T17:07:47.145Z", + "operation": "snapshot", + "wallClockMs": 969.7036659999867, + "daemonDurationMs": 71, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 337108, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:07:47.145Z", + "finishedAt": "2026-09-01T17:07:49.075Z", + "operation": "snapshot", + "wallClockMs": 1929.8247499999707, + "daemonDurationMs": 57, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 337109, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 9, + "startedAt": "2026-09-01T17:07:49.075Z", + "finishedAt": "2026-09-01T17:07:50.160Z", + "operation": "snapshot", + "wallClockMs": 1085.154749999987, + "daemonDurationMs": 76, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 337110, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:07:50.160Z", + "finishedAt": "2026-09-01T17:07:51.212Z", + "operation": "snapshot", + "wallClockMs": 1052.5097500000265, + "daemonDurationMs": 55, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 337111, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:07:51.213Z", + "finishedAt": "2026-09-01T17:07:52.295Z", + "operation": "snapshot", + "wallClockMs": 1082.9546669999836, + "daemonDurationMs": 74, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 337112, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:07:52.296Z", + "finishedAt": "2026-09-01T17:07:53.212Z", + "operation": "snapshot", + "wallClockMs": 916.6215830000001, + "daemonDurationMs": 53, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 337113, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:07:53.212Z", + "finishedAt": "2026-09-01T17:07:55.985Z", + "operation": "snapshot", + "wallClockMs": 2772.2890420000185, + "daemonDurationMs": 62, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 337114, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 14, + "startedAt": "2026-09-01T17:07:55.985Z", + "finishedAt": "2026-09-01T17:07:56.536Z", + "operation": "snapshot", + "wallClockMs": 551.5472500000033, + "daemonDurationMs": 52, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 337115, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 15, + "startedAt": "2026-09-01T17:07:56.536Z", + "finishedAt": "2026-09-01T17:07:58.574Z", + "operation": "snapshot", + "wallClockMs": 2038.0383750000037, + "daemonDurationMs": 57, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 337116, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 16, + "startedAt": "2026-09-01T17:07:58.574Z", + "finishedAt": "2026-09-01T17:07:59.627Z", + "operation": "snapshot", + "wallClockMs": 1053.2060829999973, + "daemonDurationMs": 52, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 337117, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:07:59.628Z", + "finishedAt": "2026-09-01T17:08:00.722Z", + "operation": "snapshot", + "wallClockMs": 1094.375291000004, + "daemonDurationMs": 65, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 337118, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:08:00.722Z", + "finishedAt": "2026-09-01T17:08:01.756Z", + "operation": "snapshot", + "wallClockMs": 1033.6922079999931, + "daemonDurationMs": 54, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 337119, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:08:01.756Z", + "finishedAt": "2026-09-01T17:08:02.314Z", + "operation": "snapshot", + "wallClockMs": 558.5252090000431, + "daemonDurationMs": 57, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 337120, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 20, + "startedAt": "2026-09-01T17:08:02.314Z", + "finishedAt": "2026-09-01T17:08:03.372Z", + "operation": "snapshot", + "wallClockMs": 1057.291041999997, + "daemonDurationMs": 55, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 337121, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 551.5472500000033, + "median": 1057.291041999997, + "p95": 2038.0383750000037, + "max": 2772.2890420000185, + "outlierCount": 7, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 52, + "median": 57, + "p95": 76, + "max": 76, + "outlierCount": 7, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 1917, + "median": 1919, + "p95": 1921, + "max": 1921, + "outlierCount": 7, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "list", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:08:13.228Z", + "finishedAt": "2026-09-01T17:08:13.967Z", + "operation": "snapshot", + "wallClockMs": 738.612208000035, + "daemonDurationMs": 235, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 636867, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:08:13.967Z", + "finishedAt": "2026-09-01T17:08:14.450Z", + "operation": "snapshot", + "wallClockMs": 482.94699999998556, + "daemonDurationMs": 219, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 636868, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:08:14.450Z", + "finishedAt": "2026-09-01T17:08:15.732Z", + "operation": "snapshot", + "wallClockMs": 1282.2743750000373, + "daemonDurationMs": 218, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 636869, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T17:08:15.732Z", + "finishedAt": "2026-09-01T17:08:16.448Z", + "operation": "snapshot", + "wallClockMs": 716.0277089999872, + "daemonDurationMs": 216, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 636870, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:08:16.448Z", + "finishedAt": "2026-09-01T17:08:16.946Z", + "operation": "snapshot", + "wallClockMs": 497.39783299999544, + "daemonDurationMs": 211, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 636871, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:08:16.946Z", + "finishedAt": "2026-09-01T17:08:17.726Z", + "operation": "snapshot", + "wallClockMs": 780.883582999988, + "daemonDurationMs": 214, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 636872, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:08:17.726Z", + "finishedAt": "2026-09-01T17:08:18.446Z", + "operation": "snapshot", + "wallClockMs": 719.6566250000033, + "daemonDurationMs": 217, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 636873, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:08:18.446Z", + "finishedAt": "2026-09-01T17:08:18.945Z", + "operation": "snapshot", + "wallClockMs": 498.422750000027, + "daemonDurationMs": 216, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 636874, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:08:18.945Z", + "finishedAt": "2026-09-01T17:08:19.663Z", + "operation": "snapshot", + "wallClockMs": 718.5324170000385, + "daemonDurationMs": 216, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 636875, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:08:19.663Z", + "finishedAt": "2026-09-01T17:08:20.234Z", + "operation": "snapshot", + "wallClockMs": 571.3313329999801, + "daemonDurationMs": 220, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 636876, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:08:20.234Z", + "finishedAt": "2026-09-01T17:08:20.957Z", + "operation": "snapshot", + "wallClockMs": 722.0954999999958, + "daemonDurationMs": 220, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 636877, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:08:20.957Z", + "finishedAt": "2026-09-01T17:08:21.457Z", + "operation": "snapshot", + "wallClockMs": 500.25095900002634, + "daemonDurationMs": 222, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 636878, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:08:21.457Z", + "finishedAt": "2026-09-01T17:08:22.235Z", + "operation": "snapshot", + "wallClockMs": 778.4149589999579, + "daemonDurationMs": 222, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 636879, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:08:22.235Z", + "finishedAt": "2026-09-01T17:08:22.957Z", + "operation": "snapshot", + "wallClockMs": 721.4695000000065, + "daemonDurationMs": 220, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 636880, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:08:22.957Z", + "finishedAt": "2026-09-01T17:08:23.456Z", + "operation": "snapshot", + "wallClockMs": 499.41433400003007, + "daemonDurationMs": 219, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 636881, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:08:23.456Z", + "finishedAt": "2026-09-01T17:08:24.233Z", + "operation": "snapshot", + "wallClockMs": 777.2377909999923, + "daemonDurationMs": 218, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 636882, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:08:24.233Z", + "finishedAt": "2026-09-01T17:08:24.906Z", + "operation": "snapshot", + "wallClockMs": 672.3880840000347, + "daemonDurationMs": 228, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 636883, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:08:24.906Z", + "finishedAt": "2026-09-01T17:08:25.289Z", + "operation": "snapshot", + "wallClockMs": 383.60537499998463, + "daemonDurationMs": 266, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 636884, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:08:25.289Z", + "finishedAt": "2026-09-01T17:08:26.174Z", + "operation": "snapshot", + "wallClockMs": 884.4098750000121, + "daemonDurationMs": 217, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 636885, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:08:26.174Z", + "finishedAt": "2026-09-01T17:08:26.894Z", + "operation": "snapshot", + "wallClockMs": 720.2222090000287, + "daemonDurationMs": 218, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 636886, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 383.60537499998463, + "median": 718.5324170000385, + "p95": 884.4098750000121, + "max": 1282.2743750000373, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 211, + "median": 218, + "p95": 235, + "max": 266, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 8279, + "median": 8281, + "p95": 8283, + "max": 8283, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "list", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:08:38.711Z", + "finishedAt": "2026-09-01T17:08:39.930Z", + "operation": "snapshot", + "wallClockMs": 1218.5017080000252, + "daemonDurationMs": 218, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 943632, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:08:39.930Z", + "finishedAt": "2026-09-01T17:08:41.152Z", + "operation": "snapshot", + "wallClockMs": 1222.1049169999897, + "daemonDurationMs": 222, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 943633, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:08:41.152Z", + "finishedAt": "2026-09-01T17:08:42.376Z", + "operation": "snapshot", + "wallClockMs": 1224.1245840000338, + "daemonDurationMs": 221, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 943634, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:08:42.376Z", + "finishedAt": "2026-09-01T17:08:43.599Z", + "operation": "snapshot", + "wallClockMs": 1222.725959000003, + "daemonDurationMs": 222, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 943635, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:08:43.599Z", + "finishedAt": "2026-09-01T17:08:44.345Z", + "operation": "snapshot", + "wallClockMs": 745.7620829999796, + "daemonDurationMs": 220, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 943636, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:08:44.345Z", + "finishedAt": "2026-09-01T17:08:45.323Z", + "operation": "snapshot", + "wallClockMs": 978.684041999979, + "daemonDurationMs": 223, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 943637, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:08:45.324Z", + "finishedAt": "2026-09-01T17:08:46.547Z", + "operation": "snapshot", + "wallClockMs": 1223.584582999989, + "daemonDurationMs": 219, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 943638, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:08:46.547Z", + "finishedAt": "2026-09-01T17:08:47.295Z", + "operation": "snapshot", + "wallClockMs": 747.5914590000175, + "daemonDurationMs": 223, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 943639, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:08:47.295Z", + "finishedAt": "2026-09-01T17:08:48.769Z", + "operation": "snapshot", + "wallClockMs": 1473.9659999999567, + "daemonDurationMs": 220, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 943640, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:08:48.769Z", + "finishedAt": "2026-09-01T17:08:49.765Z", + "operation": "snapshot", + "wallClockMs": 996.384875000047, + "daemonDurationMs": 217, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 943641, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:08:49.765Z", + "finishedAt": "2026-09-01T17:08:51.260Z", + "operation": "snapshot", + "wallClockMs": 1494.445791999984, + "daemonDurationMs": 220, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 943642, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:08:51.260Z", + "finishedAt": "2026-09-01T17:08:52.483Z", + "operation": "snapshot", + "wallClockMs": 1222.9700409999932, + "daemonDurationMs": 224, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 943643, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:08:52.483Z", + "finishedAt": "2026-09-01T17:08:53.234Z", + "operation": "snapshot", + "wallClockMs": 751.7016670000157, + "daemonDurationMs": 217, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 943644, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:08:53.235Z", + "finishedAt": "2026-09-01T17:08:54.261Z", + "operation": "snapshot", + "wallClockMs": 1026.1890410000342, + "daemonDurationMs": 219, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 943645, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:08:54.261Z", + "finishedAt": "2026-09-01T17:08:55.978Z", + "operation": "snapshot", + "wallClockMs": 1717.707166999986, + "daemonDurationMs": 214, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 943646, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 16, + "startedAt": "2026-09-01T17:08:55.979Z", + "finishedAt": "2026-09-01T17:08:57.200Z", + "operation": "snapshot", + "wallClockMs": 1221.0715830000117, + "daemonDurationMs": 221, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 943647, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:08:57.200Z", + "finishedAt": "2026-09-01T17:08:58.421Z", + "operation": "snapshot", + "wallClockMs": 1221.7934159999713, + "daemonDurationMs": 219, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 943648, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:08:58.421Z", + "finishedAt": "2026-09-01T17:08:59.239Z", + "operation": "snapshot", + "wallClockMs": 817.8687919999938, + "daemonDurationMs": 222, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 943649, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:08:59.239Z", + "finishedAt": "2026-09-01T17:09:00.639Z", + "operation": "snapshot", + "wallClockMs": 1399.6193329999805, + "daemonDurationMs": 216, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 943650, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:09:00.639Z", + "finishedAt": "2026-09-01T17:09:01.855Z", + "operation": "snapshot", + "wallClockMs": 1216.1371250000084, + "daemonDurationMs": 216, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 943651, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 745.7620829999796, + "median": 1221.0715830000117, + "p95": 1494.445791999984, + "max": 1717.707166999986, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 214, + "median": 220, + "p95": 223, + "max": 224, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 8279, + "median": 8281, + "p95": 8283, + "max": 8283, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "nested-scroll", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:09:11.658Z", + "finishedAt": "2026-09-01T17:09:12.158Z", + "operation": "snapshot", + "wallClockMs": 499.93329200003063, + "daemonDurationMs": 87, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 523186, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:09:12.158Z", + "finishedAt": "2026-09-01T17:09:13.102Z", + "operation": "snapshot", + "wallClockMs": 943.6435420000344, + "daemonDurationMs": 88, + "responseBytes": 6265, + "nodeCount": 25, + "targetGeneration": 523187, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:09:13.102Z", + "finishedAt": "2026-09-01T17:09:14.101Z", + "operation": "snapshot", + "wallClockMs": 999.3819999999832, + "daemonDurationMs": 89, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 523188, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:09:14.101Z", + "finishedAt": "2026-09-01T17:09:14.691Z", + "operation": "snapshot", + "wallClockMs": 589.3956250000047, + "daemonDurationMs": 88, + "responseBytes": 6270, + "nodeCount": 25, + "targetGeneration": 523189, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:09:14.691Z", + "finishedAt": "2026-09-01T17:09:15.179Z", + "operation": "snapshot", + "wallClockMs": 487.85350000002654, + "daemonDurationMs": 94, + "responseBytes": 6270, + "nodeCount": 25, + "targetGeneration": 523190, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:09:15.179Z", + "finishedAt": "2026-09-01T17:09:16.607Z", + "operation": "snapshot", + "wallClockMs": 1428.4583339999663, + "daemonDurationMs": 95, + "responseBytes": 6271, + "nodeCount": 25, + "targetGeneration": 523191, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 7, + "startedAt": "2026-09-01T17:09:16.607Z", + "finishedAt": "2026-09-01T17:09:17.100Z", + "operation": "snapshot", + "wallClockMs": 492.8355830000364, + "daemonDurationMs": 86, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 523192, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:09:17.100Z", + "finishedAt": "2026-09-01T17:09:18.603Z", + "operation": "snapshot", + "wallClockMs": 1502.6516669999692, + "daemonDurationMs": 91, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 523193, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 9, + "startedAt": "2026-09-01T17:09:18.603Z", + "finishedAt": "2026-09-01T17:09:19.195Z", + "operation": "snapshot", + "wallClockMs": 592.6792919999571, + "daemonDurationMs": 90, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 523194, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:09:19.195Z", + "finishedAt": "2026-09-01T17:09:19.786Z", + "operation": "snapshot", + "wallClockMs": 590.4403750000056, + "daemonDurationMs": 88, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 523195, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:09:19.786Z", + "finishedAt": "2026-09-01T17:09:20.191Z", + "operation": "snapshot", + "wallClockMs": 404.998041999992, + "daemonDurationMs": 89, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 523196, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:09:20.191Z", + "finishedAt": "2026-09-01T17:09:20.876Z", + "operation": "snapshot", + "wallClockMs": 685.2098750000005, + "daemonDurationMs": 88, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 523197, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:09:20.876Z", + "finishedAt": "2026-09-01T17:09:21.375Z", + "operation": "snapshot", + "wallClockMs": 499.37395899998955, + "daemonDurationMs": 88, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 523198, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:09:21.375Z", + "finishedAt": "2026-09-01T17:09:22.102Z", + "operation": "snapshot", + "wallClockMs": 726.3134999999893, + "daemonDurationMs": 89, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 523199, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:09:22.102Z", + "finishedAt": "2026-09-01T17:09:23.103Z", + "operation": "snapshot", + "wallClockMs": 1001.69412499998, + "daemonDurationMs": 88, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 523200, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:09:23.104Z", + "finishedAt": "2026-09-01T17:09:23.603Z", + "operation": "snapshot", + "wallClockMs": 499.5106670000241, + "daemonDurationMs": 87, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 523201, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:09:23.603Z", + "finishedAt": "2026-09-01T17:09:24.193Z", + "operation": "snapshot", + "wallClockMs": 589.6160840000375, + "daemonDurationMs": 89, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 523202, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:09:24.193Z", + "finishedAt": "2026-09-01T17:09:24.783Z", + "operation": "snapshot", + "wallClockMs": 590.5903330000001, + "daemonDurationMs": 91, + "responseBytes": 6270, + "nodeCount": 25, + "targetGeneration": 523203, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:09:24.783Z", + "finishedAt": "2026-09-01T17:09:25.281Z", + "operation": "snapshot", + "wallClockMs": 497.6587919999729, + "daemonDurationMs": 89, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 523204, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:09:25.281Z", + "finishedAt": "2026-09-01T17:09:26.124Z", + "operation": "snapshot", + "wallClockMs": 843.5475839999854, + "daemonDurationMs": 86, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 523205, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 404.998041999992, + "median": 590.4403750000056, + "p95": 1428.4583339999663, + "max": 1502.6516669999692, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 86, + "median": 88, + "p95": 94, + "max": 95, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6265, + "median": 6272, + "p95": 6274, + "max": 6274, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "nested-scroll", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:09:37.824Z", + "finishedAt": "2026-09-01T17:09:38.427Z", + "operation": "snapshot", + "wallClockMs": 602.7791250000009, + "daemonDurationMs": 101, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 966205, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:09:38.427Z", + "finishedAt": "2026-09-01T17:09:39.156Z", + "operation": "snapshot", + "wallClockMs": 728.6910420000204, + "daemonDurationMs": 107, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 966206, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:09:39.156Z", + "finishedAt": "2026-09-01T17:09:40.316Z", + "operation": "snapshot", + "wallClockMs": 1159.6807079999708, + "daemonDurationMs": 100, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 966207, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:09:40.316Z", + "finishedAt": "2026-09-01T17:09:41.329Z", + "operation": "snapshot", + "wallClockMs": 1012.955541000003, + "daemonDurationMs": 91, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 966208, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:09:41.329Z", + "finishedAt": "2026-09-01T17:09:42.834Z", + "operation": "snapshot", + "wallClockMs": 1505.1109590000124, + "daemonDurationMs": 109, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 966209, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:09:42.834Z", + "finishedAt": "2026-09-01T17:09:44.134Z", + "operation": "snapshot", + "wallClockMs": 1299.6142499999842, + "daemonDurationMs": 111, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 966210, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:09:44.134Z", + "finishedAt": "2026-09-01T17:09:45.136Z", + "operation": "snapshot", + "wallClockMs": 1002.7661669999943, + "daemonDurationMs": 112, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 966211, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:09:45.137Z", + "finishedAt": "2026-09-01T17:09:46.439Z", + "operation": "snapshot", + "wallClockMs": 1302.2200420000008, + "daemonDurationMs": 98, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 966212, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:09:46.439Z", + "finishedAt": "2026-09-01T17:09:47.526Z", + "operation": "snapshot", + "wallClockMs": 1087.243208000029, + "daemonDurationMs": 82, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 966213, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:09:47.526Z", + "finishedAt": "2026-09-01T17:09:48.943Z", + "operation": "snapshot", + "wallClockMs": 1416.8989590000128, + "daemonDurationMs": 96, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 966214, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:09:48.943Z", + "finishedAt": "2026-09-01T17:09:50.129Z", + "operation": "snapshot", + "wallClockMs": 1185.869458000001, + "daemonDurationMs": 108, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 966215, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:09:50.129Z", + "finishedAt": "2026-09-01T17:09:51.565Z", + "operation": "snapshot", + "wallClockMs": 1436.034708000021, + "daemonDurationMs": 112, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 966216, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:09:51.565Z", + "finishedAt": "2026-09-01T17:09:52.681Z", + "operation": "snapshot", + "wallClockMs": 1116.0537499999627, + "daemonDurationMs": 109, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 966217, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:09:52.681Z", + "finishedAt": "2026-09-01T17:09:53.793Z", + "operation": "snapshot", + "wallClockMs": 1112.1408330000122, + "daemonDurationMs": 110, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 966218, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:09:53.793Z", + "finishedAt": "2026-09-01T17:09:54.895Z", + "operation": "snapshot", + "wallClockMs": 1101.6637919999775, + "daemonDurationMs": 103, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 966219, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:09:54.895Z", + "finishedAt": "2026-09-01T17:09:56.134Z", + "operation": "snapshot", + "wallClockMs": 1238.5263750000158, + "daemonDurationMs": 110, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 966220, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:09:56.134Z", + "finishedAt": "2026-09-01T17:09:57.252Z", + "operation": "snapshot", + "wallClockMs": 1117.918250000046, + "daemonDurationMs": 111, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 966221, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:09:57.252Z", + "finishedAt": "2026-09-01T17:09:58.013Z", + "operation": "snapshot", + "wallClockMs": 761.4490419999929, + "daemonDurationMs": 110, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 966222, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:09:58.013Z", + "finishedAt": "2026-09-01T17:10:00.135Z", + "operation": "snapshot", + "wallClockMs": 2121.4736660000053, + "daemonDurationMs": 110, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 966223, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 20, + "startedAt": "2026-09-01T17:10:00.135Z", + "finishedAt": "2026-09-01T17:10:01.232Z", + "operation": "snapshot", + "wallClockMs": 1097.458500000008, + "daemonDurationMs": 94, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 966224, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 602.7791250000009, + "median": 1116.0537499999627, + "p95": 1505.1109590000124, + "max": 2121.4736660000053, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 82, + "median": 108, + "p95": 112, + "max": 112, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6272, + "median": 6275, + "p95": 6277, + "max": 6277, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "alert", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:10:14.391Z", + "finishedAt": "2026-09-01T17:10:15.145Z", + "operation": "snapshot", + "wallClockMs": 754.2980840000091, + "daemonDurationMs": 129, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 352556, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:10:15.145Z", + "finishedAt": "2026-09-01T17:10:15.787Z", + "operation": "snapshot", + "wallClockMs": 641.2340409999597, + "daemonDurationMs": 135, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 352557, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:10:15.787Z", + "finishedAt": "2026-09-01T17:10:16.276Z", + "operation": "snapshot", + "wallClockMs": 489.10262499999953, + "daemonDurationMs": 126, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 352558, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:10:16.276Z", + "finishedAt": "2026-09-01T17:10:17.201Z", + "operation": "snapshot", + "wallClockMs": 925.3289579999982, + "daemonDurationMs": 136, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 352559, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:10:17.201Z", + "finishedAt": "2026-09-01T17:10:18.122Z", + "operation": "snapshot", + "wallClockMs": 920.8739169999608, + "daemonDurationMs": 104, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 352560, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:10:18.122Z", + "finishedAt": "2026-09-01T17:10:18.636Z", + "operation": "snapshot", + "wallClockMs": 513.6625420000055, + "daemonDurationMs": 116, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 352561, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:10:18.636Z", + "finishedAt": "2026-09-01T17:10:19.265Z", + "operation": "snapshot", + "wallClockMs": 628.8471249999711, + "daemonDurationMs": 141, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 352562, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:10:19.265Z", + "finishedAt": "2026-09-01T17:10:19.893Z", + "operation": "snapshot", + "wallClockMs": 628.0960000000196, + "daemonDurationMs": 125, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 352563, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:10:19.893Z", + "finishedAt": "2026-09-01T17:10:20.341Z", + "operation": "snapshot", + "wallClockMs": 448.27808299998287, + "daemonDurationMs": 135, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 352564, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:10:20.341Z", + "finishedAt": "2026-09-01T17:10:20.547Z", + "operation": "snapshot", + "wallClockMs": 205.63691599998856, + "daemonDurationMs": 117, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 352565, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:10:20.547Z", + "finishedAt": "2026-09-01T17:10:21.151Z", + "operation": "snapshot", + "wallClockMs": 604.3979999999865, + "daemonDurationMs": 132, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 352566, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:10:21.151Z", + "finishedAt": "2026-09-01T17:10:21.873Z", + "operation": "snapshot", + "wallClockMs": 721.904749999987, + "daemonDurationMs": 134, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 352567, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:10:21.873Z", + "finishedAt": "2026-09-01T17:10:22.331Z", + "operation": "snapshot", + "wallClockMs": 457.92987500003073, + "daemonDurationMs": 116, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 352568, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:10:22.331Z", + "finishedAt": "2026-09-01T17:10:23.150Z", + "operation": "snapshot", + "wallClockMs": 818.8445000000065, + "daemonDurationMs": 133, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 352569, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:10:23.150Z", + "finishedAt": "2026-09-01T17:10:23.638Z", + "operation": "snapshot", + "wallClockMs": 488.0342079999973, + "daemonDurationMs": 121, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 352570, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:10:23.638Z", + "finishedAt": "2026-09-01T17:10:24.647Z", + "operation": "snapshot", + "wallClockMs": 1009.1064580000238, + "daemonDurationMs": 129, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 352571, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:10:24.647Z", + "finishedAt": "2026-09-01T17:10:25.261Z", + "operation": "snapshot", + "wallClockMs": 614.0780830000294, + "daemonDurationMs": 113, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 352572, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:10:25.261Z", + "finishedAt": "2026-09-01T17:10:25.883Z", + "operation": "snapshot", + "wallClockMs": 622.4954159999616, + "daemonDurationMs": 121, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 352573, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:10:25.884Z", + "finishedAt": "2026-09-01T17:10:26.302Z", + "operation": "snapshot", + "wallClockMs": 418.3780840000254, + "daemonDurationMs": 134, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 352574, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:10:26.302Z", + "finishedAt": "2026-09-01T17:10:27.009Z", + "operation": "snapshot", + "wallClockMs": 706.9315420000348, + "daemonDurationMs": 123, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 352575, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 205.63691599998856, + "median": 622.4954159999616, + "p95": 925.3289579999982, + "max": 1009.1064580000238, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 104, + "median": 126, + "p95": 136, + "max": 141, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 7165, + "median": 7167, + "p95": 7168, + "max": 7168, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "alert", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:10:43.446Z", + "finishedAt": "2026-09-01T17:10:44.556Z", + "operation": "snapshot", + "wallClockMs": 1110.0217499999562, + "daemonDurationMs": 113, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 731551, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:10:44.556Z", + "finishedAt": "2026-09-01T17:10:45.194Z", + "operation": "snapshot", + "wallClockMs": 638.0019169999869, + "daemonDurationMs": 112, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 731552, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 3, + "startedAt": "2026-09-01T17:10:45.194Z", + "finishedAt": "2026-09-01T17:10:46.554Z", + "operation": "snapshot", + "wallClockMs": 1360.5, + "daemonDurationMs": 108, + "responseBytes": 7163, + "nodeCount": 30, + "targetGeneration": 731553, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:10:46.554Z", + "finishedAt": "2026-09-01T17:10:48.644Z", + "operation": "snapshot", + "wallClockMs": 2089.8589159999974, + "daemonDurationMs": 121, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 731554, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 5, + "startedAt": "2026-09-01T17:10:48.644Z", + "finishedAt": "2026-09-01T17:10:49.694Z", + "operation": "snapshot", + "wallClockMs": 1049.9783329999773, + "daemonDurationMs": 110, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 731555, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:10:49.694Z", + "finishedAt": "2026-09-01T17:10:50.806Z", + "operation": "snapshot", + "wallClockMs": 1112.3530829999945, + "daemonDurationMs": 112, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 731556, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:10:50.807Z", + "finishedAt": "2026-09-01T17:10:51.922Z", + "operation": "snapshot", + "wallClockMs": 1115.5142499999492, + "daemonDurationMs": 114, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 731557, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:10:51.922Z", + "finishedAt": "2026-09-01T17:10:53.056Z", + "operation": "snapshot", + "wallClockMs": 1134.140625, + "daemonDurationMs": 122, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 731558, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:10:53.056Z", + "finishedAt": "2026-09-01T17:10:54.160Z", + "operation": "snapshot", + "wallClockMs": 1104.1681249999674, + "daemonDurationMs": 114, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 731559, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:10:54.161Z", + "finishedAt": "2026-09-01T17:10:55.273Z", + "operation": "snapshot", + "wallClockMs": 1112.80016600003, + "daemonDurationMs": 110, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 731560, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:10:55.273Z", + "finishedAt": "2026-09-01T17:10:56.126Z", + "operation": "snapshot", + "wallClockMs": 852.5434170000372, + "daemonDurationMs": 108, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 731561, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:10:56.126Z", + "finishedAt": "2026-09-01T17:10:57.385Z", + "operation": "snapshot", + "wallClockMs": 1258.9937919999938, + "daemonDurationMs": 109, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 731562, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:10:57.385Z", + "finishedAt": "2026-09-01T17:10:58.501Z", + "operation": "snapshot", + "wallClockMs": 1116.1513339999947, + "daemonDurationMs": 114, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 731563, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:10:58.501Z", + "finishedAt": "2026-09-01T17:11:00.116Z", + "operation": "snapshot", + "wallClockMs": 1614.4329160000198, + "daemonDurationMs": 110, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 731564, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 15, + "startedAt": "2026-09-01T17:11:00.116Z", + "finishedAt": "2026-09-01T17:11:01.230Z", + "operation": "snapshot", + "wallClockMs": 1113.825583000027, + "daemonDurationMs": 111, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 731565, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:11:01.230Z", + "finishedAt": "2026-09-01T17:11:02.130Z", + "operation": "snapshot", + "wallClockMs": 900.1142920000129, + "daemonDurationMs": 111, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 731566, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:11:02.130Z", + "finishedAt": "2026-09-01T17:11:03.353Z", + "operation": "snapshot", + "wallClockMs": 1222.9544999999925, + "daemonDurationMs": 110, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 731567, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:11:03.353Z", + "finishedAt": "2026-09-01T17:11:04.130Z", + "operation": "snapshot", + "wallClockMs": 777.1079169999575, + "daemonDurationMs": 112, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 731568, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:11:04.130Z", + "finishedAt": "2026-09-01T17:11:05.128Z", + "operation": "snapshot", + "wallClockMs": 997.6953750000102, + "daemonDurationMs": 111, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 731569, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:11:05.128Z", + "finishedAt": "2026-09-01T17:11:06.468Z", + "operation": "snapshot", + "wallClockMs": 1340.8177499999874, + "daemonDurationMs": 114, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 731570, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 638.0019169999869, + "median": 1112.80016600003, + "p95": 1614.4329160000198, + "max": 2089.8589159999974, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 108, + "median": 111, + "p95": 121, + "max": 122, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 7163, + "median": 7167, + "p95": 7168, + "max": 7168, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "system-surface", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:11:16.730Z", + "finishedAt": "2026-09-01T17:11:17.232Z", + "operation": "snapshot", + "wallClockMs": 502.3766249999753, + "daemonDurationMs": 112, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 321225, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:11:17.232Z", + "finishedAt": "2026-09-01T17:11:18.128Z", + "operation": "snapshot", + "wallClockMs": 895.1520840000012, + "daemonDurationMs": 113, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 321226, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:11:18.128Z", + "finishedAt": "2026-09-01T17:11:18.365Z", + "operation": "snapshot", + "wallClockMs": 237.78208400000585, + "daemonDurationMs": 109, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 321227, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:11:18.365Z", + "finishedAt": "2026-09-01T17:11:18.846Z", + "operation": "snapshot", + "wallClockMs": 480.2229159999988, + "daemonDurationMs": 112, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 321228, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:11:18.846Z", + "finishedAt": "2026-09-01T17:11:19.229Z", + "operation": "snapshot", + "wallClockMs": 383.0000830000499, + "daemonDurationMs": 108, + "responseBytes": 4607, + "nodeCount": 18, + "targetGeneration": 321229, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:11:19.229Z", + "finishedAt": "2026-09-01T17:11:19.963Z", + "operation": "snapshot", + "wallClockMs": 734.1152090000105, + "daemonDurationMs": 117, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 321230, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:11:19.963Z", + "finishedAt": "2026-09-01T17:11:20.245Z", + "operation": "snapshot", + "wallClockMs": 282.52183299994795, + "daemonDurationMs": 112, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 321231, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:11:20.245Z", + "finishedAt": "2026-09-01T17:11:20.580Z", + "operation": "snapshot", + "wallClockMs": 334.53545799996937, + "daemonDurationMs": 116, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 321232, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:11:20.580Z", + "finishedAt": "2026-09-01T17:11:21.131Z", + "operation": "snapshot", + "wallClockMs": 551.0803750000196, + "daemonDurationMs": 115, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 321233, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:11:21.131Z", + "finishedAt": "2026-09-01T17:11:21.748Z", + "operation": "snapshot", + "wallClockMs": 617.010958000028, + "daemonDurationMs": 116, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 321234, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:11:21.748Z", + "finishedAt": "2026-09-01T17:11:22.243Z", + "operation": "snapshot", + "wallClockMs": 494.62779200001387, + "daemonDurationMs": 111, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 321235, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:11:22.243Z", + "finishedAt": "2026-09-01T17:11:23.625Z", + "operation": "snapshot", + "wallClockMs": 1382.1392089999863, + "daemonDurationMs": 112, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 321236, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 13, + "startedAt": "2026-09-01T17:11:23.625Z", + "finishedAt": "2026-09-01T17:11:24.235Z", + "operation": "snapshot", + "wallClockMs": 609.9520839999896, + "daemonDurationMs": 109, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 321237, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:11:24.235Z", + "finishedAt": "2026-09-01T17:11:24.850Z", + "operation": "snapshot", + "wallClockMs": 615.1677500000224, + "daemonDurationMs": 113, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 321238, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:11:24.850Z", + "finishedAt": "2026-09-01T17:11:25.149Z", + "operation": "snapshot", + "wallClockMs": 299.3681669999496, + "daemonDurationMs": 111, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 321239, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:11:25.149Z", + "finishedAt": "2026-09-01T17:11:25.466Z", + "operation": "snapshot", + "wallClockMs": 316.96066600002814, + "daemonDurationMs": 114, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 321240, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:11:25.466Z", + "finishedAt": "2026-09-01T17:11:26.078Z", + "operation": "snapshot", + "wallClockMs": 612.1039999999921, + "daemonDurationMs": 111, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 321241, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:11:26.078Z", + "finishedAt": "2026-09-01T17:11:26.656Z", + "operation": "snapshot", + "wallClockMs": 577.8431249999558, + "daemonDurationMs": 112, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 321242, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:11:26.656Z", + "finishedAt": "2026-09-01T17:11:27.194Z", + "operation": "snapshot", + "wallClockMs": 537.3665419999743, + "daemonDurationMs": 113, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 321243, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:11:27.194Z", + "finishedAt": "2026-09-01T17:11:27.793Z", + "operation": "snapshot", + "wallClockMs": 599.6769999999669, + "daemonDurationMs": 113, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 321244, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 237.78208400000585, + "median": 537.3665419999743, + "p95": 895.1520840000012, + "max": 1382.1392089999863, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 108, + "median": 112, + "p95": 116, + "max": 117, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 4607, + "median": 4610, + "p95": 4611, + "max": 4611, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "system-surface", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:11:40.001Z", + "finishedAt": "2026-09-01T17:11:41.504Z", + "operation": "snapshot", + "wallClockMs": 1503.2409580000094, + "daemonDurationMs": 112, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 397087, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:11:41.504Z", + "finishedAt": "2026-09-01T17:11:43.361Z", + "operation": "snapshot", + "wallClockMs": 1856.7463330000173, + "daemonDurationMs": 111, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 397088, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:11:43.361Z", + "finishedAt": "2026-09-01T17:11:44.499Z", + "operation": "snapshot", + "wallClockMs": 1137.9282910000184, + "daemonDurationMs": 132, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 397089, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:11:44.499Z", + "finishedAt": "2026-09-01T17:11:46.130Z", + "operation": "snapshot", + "wallClockMs": 1631.313709000009, + "daemonDurationMs": 115, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 397090, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:11:46.130Z", + "finishedAt": "2026-09-01T17:11:47.242Z", + "operation": "snapshot", + "wallClockMs": 1111.8004160000128, + "daemonDurationMs": 108, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 397091, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:11:47.242Z", + "finishedAt": "2026-09-01T17:11:48.128Z", + "operation": "snapshot", + "wallClockMs": 885.5105829999666, + "daemonDurationMs": 110, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 397092, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:11:48.128Z", + "finishedAt": "2026-09-01T17:11:49.357Z", + "operation": "snapshot", + "wallClockMs": 1229.5336249999818, + "daemonDurationMs": 114, + "responseBytes": 4605, + "nodeCount": 18, + "targetGeneration": 397093, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:11:49.357Z", + "finishedAt": "2026-09-01T17:11:50.477Z", + "operation": "snapshot", + "wallClockMs": 1119.3256249999977, + "daemonDurationMs": 119, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 397094, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:11:50.477Z", + "finishedAt": "2026-09-01T17:11:51.601Z", + "operation": "snapshot", + "wallClockMs": 1124.5658330000006, + "daemonDurationMs": 122, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 397095, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:11:51.601Z", + "finishedAt": "2026-09-01T17:11:52.720Z", + "operation": "snapshot", + "wallClockMs": 1118.3162500000326, + "daemonDurationMs": 116, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 397096, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:11:52.720Z", + "finishedAt": "2026-09-01T17:11:53.594Z", + "operation": "snapshot", + "wallClockMs": 874.775500000047, + "daemonDurationMs": 115, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 397097, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:11:53.594Z", + "finishedAt": "2026-09-01T17:11:55.133Z", + "operation": "snapshot", + "wallClockMs": 1538.6015829999815, + "daemonDurationMs": 116, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 397098, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:11:55.133Z", + "finishedAt": "2026-09-01T17:11:56.249Z", + "operation": "snapshot", + "wallClockMs": 1115.5707500000135, + "daemonDurationMs": 115, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 397099, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:11:56.249Z", + "finishedAt": "2026-09-01T17:11:56.996Z", + "operation": "snapshot", + "wallClockMs": 747.0001250000205, + "daemonDurationMs": 130, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 397100, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:11:56.996Z", + "finishedAt": "2026-09-01T17:11:58.373Z", + "operation": "snapshot", + "wallClockMs": 1377.7660000000033, + "daemonDurationMs": 120, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 397101, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:11:58.374Z", + "finishedAt": "2026-09-01T17:11:59.128Z", + "operation": "snapshot", + "wallClockMs": 754.0793330000015, + "daemonDurationMs": 110, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 397102, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:11:59.128Z", + "finishedAt": "2026-09-01T17:12:00.131Z", + "operation": "snapshot", + "wallClockMs": 1003.1074580000131, + "daemonDurationMs": 114, + "responseBytes": 4607, + "nodeCount": 18, + "targetGeneration": 397103, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:12:00.131Z", + "finishedAt": "2026-09-01T17:12:01.115Z", + "operation": "snapshot", + "wallClockMs": 984.551541999972, + "daemonDurationMs": 110, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 397104, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:12:01.115Z", + "finishedAt": "2026-09-01T17:12:02.492Z", + "operation": "snapshot", + "wallClockMs": 1376.8115419999813, + "daemonDurationMs": 116, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 397105, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:12:02.492Z", + "finishedAt": "2026-09-01T17:12:04.130Z", + "operation": "snapshot", + "wallClockMs": 1637.5595830000238, + "daemonDurationMs": 115, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 397106, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 747.0001250000205, + "median": 1119.3256249999977, + "p95": 1637.5595830000238, + "max": 1856.7463330000173, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 108, + "median": 115, + "p95": 130, + "max": 132, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 4605, + "median": 4609, + "p95": 4611, + "max": 4611, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "xctest-stress", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:12:14.415Z", + "finishedAt": "2026-09-01T17:12:15.028Z", + "operation": "snapshot", + "wallClockMs": 613.6402920000255, + "daemonDurationMs": 113, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 239898, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:12:15.028Z", + "finishedAt": "2026-09-01T17:12:15.528Z", + "operation": "snapshot", + "wallClockMs": 499.65508299996145, + "daemonDurationMs": 113, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 239899, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:12:15.528Z", + "finishedAt": "2026-09-01T17:12:16.934Z", + "operation": "snapshot", + "wallClockMs": 1406.2587499999208, + "daemonDurationMs": 117, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 239900, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T17:12:16.934Z", + "finishedAt": "2026-09-01T17:12:17.426Z", + "operation": "snapshot", + "wallClockMs": 491.61295899993274, + "daemonDurationMs": 110, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 239901, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:12:17.426Z", + "finishedAt": "2026-09-01T17:12:18.126Z", + "operation": "snapshot", + "wallClockMs": 700.0402089999989, + "daemonDurationMs": 112, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 239902, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:12:18.126Z", + "finishedAt": "2026-09-01T17:12:18.938Z", + "operation": "snapshot", + "wallClockMs": 812.3194999999832, + "daemonDurationMs": 108, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 239903, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:12:18.938Z", + "finishedAt": "2026-09-01T17:12:19.436Z", + "operation": "snapshot", + "wallClockMs": 498.062957999995, + "daemonDurationMs": 107, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 239904, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:12:19.436Z", + "finishedAt": "2026-09-01T17:12:20.049Z", + "operation": "snapshot", + "wallClockMs": 612.3995000000577, + "daemonDurationMs": 113, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239905, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:12:20.049Z", + "finishedAt": "2026-09-01T17:12:20.937Z", + "operation": "snapshot", + "wallClockMs": 888.8529580000322, + "daemonDurationMs": 109, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239906, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:12:20.937Z", + "finishedAt": "2026-09-01T17:12:21.450Z", + "operation": "snapshot", + "wallClockMs": 512.4227919999976, + "daemonDurationMs": 121, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 239907, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:12:21.450Z", + "finishedAt": "2026-09-01T17:12:22.058Z", + "operation": "snapshot", + "wallClockMs": 607.7167080000509, + "daemonDurationMs": 119, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239908, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:12:22.058Z", + "finishedAt": "2026-09-01T17:12:22.680Z", + "operation": "snapshot", + "wallClockMs": 622.140625, + "daemonDurationMs": 121, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239909, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:12:22.680Z", + "finishedAt": "2026-09-01T17:12:23.165Z", + "operation": "snapshot", + "wallClockMs": 484.70625000004657, + "daemonDurationMs": 113, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239910, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:12:23.165Z", + "finishedAt": "2026-09-01T17:12:23.870Z", + "operation": "snapshot", + "wallClockMs": 705.5578749999404, + "daemonDurationMs": 119, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239911, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:12:23.870Z", + "finishedAt": "2026-09-01T17:12:24.363Z", + "operation": "snapshot", + "wallClockMs": 493.31566700001713, + "daemonDurationMs": 114, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 239912, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:12:24.363Z", + "finishedAt": "2026-09-01T17:12:25.630Z", + "operation": "snapshot", + "wallClockMs": 1266.454916000017, + "daemonDurationMs": 114, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 239913, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 17, + "startedAt": "2026-09-01T17:12:25.630Z", + "finishedAt": "2026-09-01T17:12:26.132Z", + "operation": "snapshot", + "wallClockMs": 502.5077080000192, + "daemonDurationMs": 114, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239914, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:12:26.132Z", + "finishedAt": "2026-09-01T17:12:26.770Z", + "operation": "snapshot", + "wallClockMs": 637.4685410000384, + "daemonDurationMs": 134, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239915, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:12:26.770Z", + "finishedAt": "2026-09-01T17:12:27.266Z", + "operation": "snapshot", + "wallClockMs": 496.1812500000233, + "daemonDurationMs": 131, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 239916, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:12:27.266Z", + "finishedAt": "2026-09-01T17:12:28.631Z", + "operation": "snapshot", + "wallClockMs": 1364.6765000000596, + "daemonDurationMs": 114, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 239917, + "firstTree": "readable", + "ok": true, + "outlier": true + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 484.70625000004657, + "median": 612.3995000000577, + "p95": 1364.6765000000596, + "max": 1406.2587499999208, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 107, + "median": 114, + "p95": 131, + "max": 134, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6840, + "median": 6842, + "p95": 6843, + "max": 6843, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "xctest-stress", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:12:39.332Z", + "finishedAt": "2026-09-01T17:12:40.159Z", + "operation": "snapshot", + "wallClockMs": 826.8559999999125, + "daemonDurationMs": 134, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 820307, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:12:40.159Z", + "finishedAt": "2026-09-01T17:12:41.321Z", + "operation": "snapshot", + "wallClockMs": 1162.0743340000045, + "daemonDurationMs": 103, + "responseBytes": 6839, + "nodeCount": 29, + "targetGeneration": 820308, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:12:41.321Z", + "finishedAt": "2026-09-01T17:12:44.157Z", + "operation": "snapshot", + "wallClockMs": 2835.1861670000944, + "daemonDurationMs": 132, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 820309, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T17:12:44.157Z", + "finishedAt": "2026-09-01T17:12:45.158Z", + "operation": "snapshot", + "wallClockMs": 1001.6380829999689, + "daemonDurationMs": 134, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 820310, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:12:45.158Z", + "finishedAt": "2026-09-01T17:12:47.459Z", + "operation": "snapshot", + "wallClockMs": 2300.8526670000283, + "daemonDurationMs": 130, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 820311, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:12:47.459Z", + "finishedAt": "2026-09-01T17:12:50.159Z", + "operation": "snapshot", + "wallClockMs": 2699.9416249999776, + "daemonDurationMs": 134, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 820312, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 7, + "startedAt": "2026-09-01T17:12:50.159Z", + "finishedAt": "2026-09-01T17:12:50.769Z", + "operation": "snapshot", + "wallClockMs": 610.044041999965, + "daemonDurationMs": 103, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 820313, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:12:50.770Z", + "finishedAt": "2026-09-01T17:12:51.374Z", + "operation": "snapshot", + "wallClockMs": 603.998041999992, + "daemonDurationMs": 105, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 820314, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:12:51.374Z", + "finishedAt": "2026-09-01T17:12:52.165Z", + "operation": "snapshot", + "wallClockMs": 791.4212080000434, + "daemonDurationMs": 116, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 820315, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:12:52.165Z", + "finishedAt": "2026-09-01T17:12:53.656Z", + "operation": "snapshot", + "wallClockMs": 1490.6002919999883, + "daemonDurationMs": 131, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 820316, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:12:53.656Z", + "finishedAt": "2026-09-01T17:12:55.154Z", + "operation": "snapshot", + "wallClockMs": 1498.2270000000717, + "daemonDurationMs": 130, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 820317, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:12:55.154Z", + "finishedAt": "2026-09-01T17:12:56.283Z", + "operation": "snapshot", + "wallClockMs": 1129.300500000012, + "daemonDurationMs": 128, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 820318, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:12:56.283Z", + "finishedAt": "2026-09-01T17:12:57.134Z", + "operation": "snapshot", + "wallClockMs": 850.8041250000242, + "daemonDurationMs": 118, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 820319, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:12:57.134Z", + "finishedAt": "2026-09-01T17:12:59.155Z", + "operation": "snapshot", + "wallClockMs": 2020.7625410000328, + "daemonDurationMs": 130, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 820320, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:12:59.155Z", + "finishedAt": "2026-09-01T17:13:00.134Z", + "operation": "snapshot", + "wallClockMs": 979.2273750000168, + "daemonDurationMs": 109, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 820321, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:13:00.134Z", + "finishedAt": "2026-09-01T17:13:02.601Z", + "operation": "snapshot", + "wallClockMs": 2466.1472920000087, + "daemonDurationMs": 123, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 820322, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:13:02.601Z", + "finishedAt": "2026-09-01T17:13:03.739Z", + "operation": "snapshot", + "wallClockMs": 1137.5290830000304, + "daemonDurationMs": 131, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 820323, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:13:03.739Z", + "finishedAt": "2026-09-01T17:13:04.874Z", + "operation": "snapshot", + "wallClockMs": 1135.561083000037, + "daemonDurationMs": 131, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 820324, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:13:04.874Z", + "finishedAt": "2026-09-01T17:13:05.737Z", + "operation": "snapshot", + "wallClockMs": 862.6192919999594, + "daemonDurationMs": 129, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 820325, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:13:05.737Z", + "finishedAt": "2026-09-01T17:13:06.978Z", + "operation": "snapshot", + "wallClockMs": 1240.8075839999365, + "daemonDurationMs": 106, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 820326, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + "wallClockMs": { + "n": 20, + "min": 603.998041999992, + "median": 1135.561083000037, + "p95": 2699.9416249999776, + "max": 2835.1861670000944, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 103, + "median": 129, + "p95": 134, + "max": 134, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6839, + "median": 6842, + "p95": 6843, + "max": 6843, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "quiet", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:13:17.965Z", + "finishedAt": "2026-09-01T17:13:19.098Z", + "operation": "snapshot", + "wallClockMs": 1132.7745839999989, + "daemonDurationMs": 55, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 892313, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:13:19.098Z", + "finishedAt": "2026-09-01T17:13:20.034Z", + "operation": "snapshot", + "wallClockMs": 936.3041250000242, + "daemonDurationMs": 46, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 892314, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:13:20.034Z", + "finishedAt": "2026-09-01T17:13:20.533Z", + "operation": "snapshot", + "wallClockMs": 498.934459000011, + "daemonDurationMs": 45, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 892315, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:13:20.533Z", + "finishedAt": "2026-09-01T17:13:21.490Z", + "operation": "snapshot", + "wallClockMs": 956.845042000059, + "daemonDurationMs": 44, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 892316, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:13:21.490Z", + "finishedAt": "2026-09-01T17:13:22.600Z", + "operation": "snapshot", + "wallClockMs": 1109.3952920000302, + "daemonDurationMs": 54, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 892317, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:13:22.600Z", + "finishedAt": "2026-09-01T17:13:23.500Z", + "operation": "snapshot", + "wallClockMs": 899.9435420000227, + "daemonDurationMs": 55, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 892318, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:13:23.500Z", + "finishedAt": "2026-09-01T17:13:24.127Z", + "operation": "snapshot", + "wallClockMs": 627.3984580000397, + "daemonDurationMs": 75, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 892319, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:13:24.127Z", + "finishedAt": "2026-09-01T17:13:24.682Z", + "operation": "snapshot", + "wallClockMs": 554.9822500000009, + "daemonDurationMs": 56, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 892320, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:13:24.682Z", + "finishedAt": "2026-09-01T17:13:25.238Z", + "operation": "snapshot", + "wallClockMs": 556.0343750000466, + "daemonDurationMs": 54, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 892321, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:13:25.238Z", + "finishedAt": "2026-09-01T17:13:25.782Z", + "operation": "snapshot", + "wallClockMs": 543.5002920000115, + "daemonDurationMs": 54, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 892322, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:13:25.782Z", + "finishedAt": "2026-09-01T17:13:26.295Z", + "operation": "snapshot", + "wallClockMs": 513.3553750000428, + "daemonDurationMs": 56, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 892323, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:13:26.295Z", + "finishedAt": "2026-09-01T17:13:27.101Z", + "operation": "snapshot", + "wallClockMs": 806.1901249999646, + "daemonDurationMs": 58, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 892324, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:13:27.101Z", + "finishedAt": "2026-09-01T17:13:28.101Z", + "operation": "snapshot", + "wallClockMs": 999.7744160000002, + "daemonDurationMs": 57, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 892325, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:13:28.101Z", + "finishedAt": "2026-09-01T17:13:28.599Z", + "operation": "snapshot", + "wallClockMs": 498.3619170000311, + "daemonDurationMs": 55, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 892326, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:13:28.599Z", + "finishedAt": "2026-09-01T17:13:29.188Z", + "operation": "snapshot", + "wallClockMs": 588.2873329999857, + "daemonDurationMs": 60, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 892327, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:13:29.188Z", + "finishedAt": "2026-09-01T17:13:30.097Z", + "operation": "snapshot", + "wallClockMs": 909.7293340000324, + "daemonDurationMs": 54, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 892328, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:13:30.097Z", + "finishedAt": "2026-09-01T17:13:31.101Z", + "operation": "snapshot", + "wallClockMs": 1003.157957999967, + "daemonDurationMs": 57, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 892329, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:13:31.101Z", + "finishedAt": "2026-09-01T17:13:32.103Z", + "operation": "snapshot", + "wallClockMs": 1001.8749170000665, + "daemonDurationMs": 57, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 892330, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:13:32.103Z", + "finishedAt": "2026-09-01T17:13:33.099Z", + "operation": "snapshot", + "wallClockMs": 996.2892499999143, + "daemonDurationMs": 54, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 892331, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:13:33.099Z", + "finishedAt": "2026-09-01T17:13:33.685Z", + "operation": "snapshot", + "wallClockMs": 586.5656660000095, + "daemonDurationMs": 57, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 892332, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 498.3619170000311, + "median": 806.1901249999646, + "p95": 1109.3952920000302, + "max": 1132.7745839999989, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 44, + "median": 55, + "p95": 60, + "max": 75, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 1917, + "median": 1920, + "p95": 1921, + "max": 1921, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "quiet", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:13:46.100Z", + "finishedAt": "2026-09-01T17:13:47.901Z", + "operation": "snapshot", + "wallClockMs": 1801.2974170000525, + "daemonDurationMs": 56, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 911588, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:13:47.901Z", + "finishedAt": "2026-09-01T17:13:51.817Z", + "operation": "snapshot", + "wallClockMs": 3915.635583999916, + "daemonDurationMs": 53, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 911589, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:13:51.817Z", + "finishedAt": "2026-09-01T17:13:53.557Z", + "operation": "snapshot", + "wallClockMs": 1740.4379169999156, + "daemonDurationMs": 54, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 911590, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:13:53.557Z", + "finishedAt": "2026-09-01T17:13:57.105Z", + "operation": "snapshot", + "wallClockMs": 3547.8813340000343, + "daemonDurationMs": 57, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 911591, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:13:57.105Z", + "finishedAt": "2026-09-01T17:13:59.601Z", + "operation": "snapshot", + "wallClockMs": 2495.291833000025, + "daemonDurationMs": 53, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 911592, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:13:59.601Z", + "finishedAt": "2026-09-01T17:14:02.095Z", + "operation": "snapshot", + "wallClockMs": 2494.6867090000305, + "daemonDurationMs": 48, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 911593, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:14:02.095Z", + "finishedAt": "2026-09-01T17:14:03.363Z", + "operation": "snapshot", + "wallClockMs": 1267.243291999912, + "daemonDurationMs": 51, + "responseBytes": 1917, + "nodeCount": 6, + "targetGeneration": 911594, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:14:03.363Z", + "finishedAt": "2026-09-01T17:14:05.099Z", + "operation": "snapshot", + "wallClockMs": 1736.484625000041, + "daemonDurationMs": 53, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 911595, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:14:05.099Z", + "finishedAt": "2026-09-01T17:14:07.099Z", + "operation": "snapshot", + "wallClockMs": 1999.7032500000205, + "daemonDurationMs": 54, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 911596, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:14:07.099Z", + "finishedAt": "2026-09-01T17:14:08.913Z", + "operation": "snapshot", + "wallClockMs": 1813.5310000000754, + "daemonDurationMs": 58, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 911597, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:14:08.913Z", + "finishedAt": "2026-09-01T17:14:10.264Z", + "operation": "snapshot", + "wallClockMs": 1350.9008750000503, + "daemonDurationMs": 55, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 911598, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:14:10.264Z", + "finishedAt": "2026-09-01T17:14:12.102Z", + "operation": "snapshot", + "wallClockMs": 1838.8323749999981, + "daemonDurationMs": 55, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 911599, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:14:12.102Z", + "finishedAt": "2026-09-01T17:14:13.638Z", + "operation": "snapshot", + "wallClockMs": 1535.6207079999149, + "daemonDurationMs": 79, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 911600, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:14:13.638Z", + "finishedAt": "2026-09-01T17:14:15.103Z", + "operation": "snapshot", + "wallClockMs": 1464.3981660000281, + "daemonDurationMs": 55, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 911601, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:14:15.103Z", + "finishedAt": "2026-09-01T17:14:17.103Z", + "operation": "snapshot", + "wallClockMs": 2000.16866700002, + "daemonDurationMs": 57, + "responseBytes": 1920, + "nodeCount": 6, + "targetGeneration": 911602, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:14:17.103Z", + "finishedAt": "2026-09-01T17:14:18.098Z", + "operation": "snapshot", + "wallClockMs": 995.6048749999609, + "daemonDurationMs": 52, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 911603, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:14:18.098Z", + "finishedAt": "2026-09-01T17:14:20.606Z", + "operation": "snapshot", + "wallClockMs": 2507.902250000043, + "daemonDurationMs": 55, + "responseBytes": 1921, + "nodeCount": 6, + "targetGeneration": 911604, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:14:20.606Z", + "finishedAt": "2026-09-01T17:14:22.098Z", + "operation": "snapshot", + "wallClockMs": 1491.6107909999555, + "daemonDurationMs": 51, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 911605, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:14:22.098Z", + "finishedAt": "2026-09-01T17:14:25.104Z", + "operation": "snapshot", + "wallClockMs": 3005.8642910000635, + "daemonDurationMs": 57, + "responseBytes": 1918, + "nodeCount": 6, + "targetGeneration": 911606, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:14:25.104Z", + "finishedAt": "2026-09-01T17:14:26.604Z", + "operation": "snapshot", + "wallClockMs": 1499.4797920000274, + "daemonDurationMs": 56, + "responseBytes": 1919, + "nodeCount": 6, + "targetGeneration": 911607, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 995.6048749999609, + "median": 1801.2974170000525, + "p95": 3547.8813340000343, + "max": 3915.635583999916, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 48, + "median": 55, + "p95": 58, + "max": 79, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 1917, + "median": 1919, + "p95": 1921, + "max": 1921, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "list", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:14:38.994Z", + "finishedAt": "2026-09-01T17:14:39.716Z", + "operation": "snapshot", + "wallClockMs": 722.1979999999749, + "daemonDurationMs": 220, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 289685, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:14:39.716Z", + "finishedAt": "2026-09-01T17:14:40.455Z", + "operation": "snapshot", + "wallClockMs": 738.7012080000713, + "daemonDurationMs": 237, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 289686, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:14:40.455Z", + "finishedAt": "2026-09-01T17:14:41.193Z", + "operation": "snapshot", + "wallClockMs": 737.8731660000049, + "daemonDurationMs": 235, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 289687, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:14:41.193Z", + "finishedAt": "2026-09-01T17:14:41.843Z", + "operation": "snapshot", + "wallClockMs": 650.452500000014, + "daemonDurationMs": 236, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 289688, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:14:41.843Z", + "finishedAt": "2026-09-01T17:14:42.426Z", + "operation": "snapshot", + "wallClockMs": 582.5616660000524, + "daemonDurationMs": 231, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 289689, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:14:42.426Z", + "finishedAt": "2026-09-01T17:14:43.280Z", + "operation": "snapshot", + "wallClockMs": 854.4145830000052, + "daemonDurationMs": 234, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 289690, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:14:43.280Z", + "finishedAt": "2026-09-01T17:14:44.008Z", + "operation": "snapshot", + "wallClockMs": 727.8012089999393, + "daemonDurationMs": 227, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 289691, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:14:44.008Z", + "finishedAt": "2026-09-01T17:14:44.502Z", + "operation": "snapshot", + "wallClockMs": 493.69954199995846, + "daemonDurationMs": 220, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 289692, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 9, + "startedAt": "2026-09-01T17:14:44.502Z", + "finishedAt": "2026-09-01T17:14:45.765Z", + "operation": "snapshot", + "wallClockMs": 1263.393625000026, + "daemonDurationMs": 218, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 289693, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 10, + "startedAt": "2026-09-01T17:14:45.765Z", + "finishedAt": "2026-09-01T17:14:46.486Z", + "operation": "snapshot", + "wallClockMs": 720.6966660000617, + "daemonDurationMs": 219, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 289694, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:14:46.486Z", + "finishedAt": "2026-09-01T17:14:47.215Z", + "operation": "snapshot", + "wallClockMs": 729.0294579999754, + "daemonDurationMs": 222, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 289695, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:14:47.215Z", + "finishedAt": "2026-09-01T17:14:47.955Z", + "operation": "snapshot", + "wallClockMs": 740.4338339999085, + "daemonDurationMs": 233, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 289696, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:14:47.955Z", + "finishedAt": "2026-09-01T17:14:48.453Z", + "operation": "snapshot", + "wallClockMs": 497.0921249999665, + "daemonDurationMs": 232, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 289697, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 14, + "startedAt": "2026-09-01T17:14:48.453Z", + "finishedAt": "2026-09-01T17:14:49.266Z", + "operation": "snapshot", + "wallClockMs": 813.3590839999961, + "daemonDurationMs": 219, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 289698, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:14:49.266Z", + "finishedAt": "2026-09-01T17:14:49.952Z", + "operation": "snapshot", + "wallClockMs": 685.6846249999944, + "daemonDurationMs": 237, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 289699, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:14:49.952Z", + "finishedAt": "2026-09-01T17:14:50.450Z", + "operation": "snapshot", + "wallClockMs": 498.3709159999853, + "daemonDurationMs": 235, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 289700, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 17, + "startedAt": "2026-09-01T17:14:50.450Z", + "finishedAt": "2026-09-01T17:14:51.287Z", + "operation": "snapshot", + "wallClockMs": 837.2757500000298, + "daemonDurationMs": 237, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 289701, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:14:51.287Z", + "finishedAt": "2026-09-01T17:14:52.027Z", + "operation": "snapshot", + "wallClockMs": 739.9807080000173, + "daemonDurationMs": 236, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 289702, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:14:52.027Z", + "finishedAt": "2026-09-01T17:14:52.771Z", + "operation": "snapshot", + "wallClockMs": 743.6939590000547, + "daemonDurationMs": 236, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 289703, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:14:52.771Z", + "finishedAt": "2026-09-01T17:14:53.513Z", + "operation": "snapshot", + "wallClockMs": 741.9287499999627, + "daemonDurationMs": 236, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 289704, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 493.69954199995846, + "median": 729.0294579999754, + "p95": 854.4145830000052, + "max": 1263.393625000026, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 218, + "median": 233, + "p95": 237, + "max": 237, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 8279, + "median": 8282, + "p95": 8283, + "max": 8283, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "list", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:15:09.193Z", + "finishedAt": "2026-09-01T17:15:10.270Z", + "operation": "snapshot", + "wallClockMs": 1077.3232910000952, + "daemonDurationMs": 213, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 759465, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:15:10.270Z", + "finishedAt": "2026-09-01T17:15:11.789Z", + "operation": "snapshot", + "wallClockMs": 1519.2580409999937, + "daemonDurationMs": 232, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 759466, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:15:11.789Z", + "finishedAt": "2026-09-01T17:15:13.290Z", + "operation": "snapshot", + "wallClockMs": 1500.1341249999823, + "daemonDurationMs": 233, + "responseBytes": 8279, + "nodeCount": 35, + "targetGeneration": 759467, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:15:13.290Z", + "finishedAt": "2026-09-01T17:15:15.291Z", + "operation": "snapshot", + "wallClockMs": 2001.6200420000823, + "daemonDurationMs": 232, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 759468, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:15:15.291Z", + "finishedAt": "2026-09-01T17:15:16.514Z", + "operation": "snapshot", + "wallClockMs": 1223.122374999919, + "daemonDurationMs": 218, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 759469, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:15:16.515Z", + "finishedAt": "2026-09-01T17:15:18.293Z", + "operation": "snapshot", + "wallClockMs": 1778.5399579999503, + "daemonDurationMs": 236, + "responseBytes": 8280, + "nodeCount": 35, + "targetGeneration": 759470, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:15:18.293Z", + "finishedAt": "2026-09-01T17:15:19.538Z", + "operation": "snapshot", + "wallClockMs": 1245.125250000041, + "daemonDurationMs": 234, + "responseBytes": 8278, + "nodeCount": 35, + "targetGeneration": 759471, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:15:19.538Z", + "finishedAt": "2026-09-01T17:15:21.292Z", + "operation": "snapshot", + "wallClockMs": 1754.1503749999683, + "daemonDurationMs": 234, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 759472, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:15:21.293Z", + "finishedAt": "2026-09-01T17:15:22.514Z", + "operation": "snapshot", + "wallClockMs": 1221.479209000012, + "daemonDurationMs": 216, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 759473, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:15:22.514Z", + "finishedAt": "2026-09-01T17:15:24.295Z", + "operation": "snapshot", + "wallClockMs": 1780.7448330000043, + "daemonDurationMs": 236, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 759474, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:15:24.295Z", + "finishedAt": "2026-09-01T17:15:25.536Z", + "operation": "snapshot", + "wallClockMs": 1241.22195799998, + "daemonDurationMs": 235, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 759475, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:15:25.536Z", + "finishedAt": "2026-09-01T17:15:27.298Z", + "operation": "snapshot", + "wallClockMs": 1762.1761249999981, + "daemonDurationMs": 237, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 759476, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:15:27.298Z", + "finishedAt": "2026-09-01T17:15:28.376Z", + "operation": "snapshot", + "wallClockMs": 1077.638082999969, + "daemonDurationMs": 231, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 759477, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:15:28.376Z", + "finishedAt": "2026-09-01T17:15:30.289Z", + "operation": "snapshot", + "wallClockMs": 1912.7663750000065, + "daemonDurationMs": 233, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 759478, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:15:30.289Z", + "finishedAt": "2026-09-01T17:15:31.525Z", + "operation": "snapshot", + "wallClockMs": 1236.282666999963, + "daemonDurationMs": 230, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 759479, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:15:31.525Z", + "finishedAt": "2026-09-01T17:15:32.853Z", + "operation": "snapshot", + "wallClockMs": 1328.120874999906, + "daemonDurationMs": 233, + "responseBytes": 8282, + "nodeCount": 35, + "targetGeneration": 759480, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:15:32.854Z", + "finishedAt": "2026-09-01T17:15:34.292Z", + "operation": "snapshot", + "wallClockMs": 1438.8014169998933, + "daemonDurationMs": 238, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 759481, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:15:34.292Z", + "finishedAt": "2026-09-01T17:15:36.269Z", + "operation": "snapshot", + "wallClockMs": 1976.215291999979, + "daemonDurationMs": 214, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 759482, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:15:36.269Z", + "finishedAt": "2026-09-01T17:15:37.364Z", + "operation": "snapshot", + "wallClockMs": 1094.8492090000072, + "daemonDurationMs": 223, + "responseBytes": 8283, + "nodeCount": 35, + "targetGeneration": 759483, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:15:37.364Z", + "finishedAt": "2026-09-01T17:15:38.593Z", + "operation": "snapshot", + "wallClockMs": 1229.094167000032, + "daemonDurationMs": 221, + "responseBytes": 8281, + "nodeCount": 35, + "targetGeneration": 759484, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 1077.3232910000952, + "median": 1328.120874999906, + "p95": 1976.215291999979, + "max": 2001.6200420000823, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 213, + "median": 232, + "p95": 237, + "max": 238, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 8278, + "median": 8281, + "p95": 8283, + "max": 8283, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "nested-scroll", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:15:48.779Z", + "finishedAt": "2026-09-01T17:15:49.304Z", + "operation": "snapshot", + "wallClockMs": 524.703125, + "daemonDurationMs": 115, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 107812, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:15:49.304Z", + "finishedAt": "2026-09-01T17:15:50.152Z", + "operation": "snapshot", + "wallClockMs": 847.5192090000492, + "daemonDurationMs": 104, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 107813, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:15:50.152Z", + "finishedAt": "2026-09-01T17:15:50.768Z", + "operation": "snapshot", + "wallClockMs": 616.6224999999395, + "daemonDurationMs": 112, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 107814, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:15:50.768Z", + "finishedAt": "2026-09-01T17:15:51.260Z", + "operation": "snapshot", + "wallClockMs": 491.9614999999758, + "daemonDurationMs": 104, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 107815, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:15:51.260Z", + "finishedAt": "2026-09-01T17:15:52.346Z", + "operation": "snapshot", + "wallClockMs": 1086.0202500000596, + "daemonDurationMs": 111, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 107816, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:15:52.346Z", + "finishedAt": "2026-09-01T17:15:53.147Z", + "operation": "snapshot", + "wallClockMs": 800.2948750000214, + "daemonDurationMs": 101, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 107817, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:15:53.147Z", + "finishedAt": "2026-09-01T17:15:53.753Z", + "operation": "snapshot", + "wallClockMs": 606.3805000000866, + "daemonDurationMs": 102, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 107818, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:15:53.753Z", + "finishedAt": "2026-09-01T17:15:54.228Z", + "operation": "snapshot", + "wallClockMs": 474.89824999996927, + "daemonDurationMs": 78, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 107819, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:15:54.228Z", + "finishedAt": "2026-09-01T17:15:55.644Z", + "operation": "snapshot", + "wallClockMs": 1416.562750000041, + "daemonDurationMs": 96, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 107820, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 10, + "startedAt": "2026-09-01T17:15:55.644Z", + "finishedAt": "2026-09-01T17:15:56.262Z", + "operation": "snapshot", + "wallClockMs": 617.2155839999905, + "daemonDurationMs": 110, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 107821, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:15:56.262Z", + "finishedAt": "2026-09-01T17:15:56.879Z", + "operation": "snapshot", + "wallClockMs": 617.0088329999708, + "daemonDurationMs": 109, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 107822, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:15:56.879Z", + "finishedAt": "2026-09-01T17:15:57.345Z", + "operation": "snapshot", + "wallClockMs": 465.8416669999715, + "daemonDurationMs": 111, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 107823, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:15:57.345Z", + "finishedAt": "2026-09-01T17:15:58.646Z", + "operation": "snapshot", + "wallClockMs": 1301.846750000026, + "daemonDurationMs": 100, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 107824, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 14, + "startedAt": "2026-09-01T17:15:58.646Z", + "finishedAt": "2026-09-01T17:15:59.262Z", + "operation": "snapshot", + "wallClockMs": 615.422332999995, + "daemonDurationMs": 110, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 107825, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:15:59.262Z", + "finishedAt": "2026-09-01T17:15:59.879Z", + "operation": "snapshot", + "wallClockMs": 616.9436659999192, + "daemonDurationMs": 111, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 107826, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:15:59.879Z", + "finishedAt": "2026-09-01T17:16:00.372Z", + "operation": "snapshot", + "wallClockMs": 493.08104100008495, + "daemonDurationMs": 105, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 107827, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:16:00.372Z", + "finishedAt": "2026-09-01T17:16:01.661Z", + "operation": "snapshot", + "wallClockMs": 1289.2781660000328, + "daemonDurationMs": 111, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 107828, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 18, + "startedAt": "2026-09-01T17:16:01.661Z", + "finishedAt": "2026-09-01T17:16:02.277Z", + "operation": "snapshot", + "wallClockMs": 615.6862500000279, + "daemonDurationMs": 112, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 107829, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:16:02.277Z", + "finishedAt": "2026-09-01T17:16:02.892Z", + "operation": "snapshot", + "wallClockMs": 615.4347919999855, + "daemonDurationMs": 109, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 107830, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:16:02.892Z", + "finishedAt": "2026-09-01T17:16:03.392Z", + "operation": "snapshot", + "wallClockMs": 499.9194579999894, + "daemonDurationMs": 110, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 107831, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 465.8416669999715, + "median": 615.6862500000279, + "p95": 1301.846750000026, + "max": 1416.562750000041, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 78, + "median": 109, + "p95": 112, + "max": 115, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6272, + "median": 6275, + "p95": 6277, + "max": 6277, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "nested-scroll", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:16:14.750Z", + "finishedAt": "2026-09-01T17:16:16.667Z", + "operation": "snapshot", + "wallClockMs": 1916.763666999992, + "daemonDurationMs": 113, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 539438, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 2, + "startedAt": "2026-09-01T17:16:16.667Z", + "finishedAt": "2026-09-01T17:16:18.168Z", + "operation": "snapshot", + "wallClockMs": 1501.4689589999616, + "daemonDurationMs": 111, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 539439, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:16:18.169Z", + "finishedAt": "2026-09-01T17:16:19.280Z", + "operation": "snapshot", + "wallClockMs": 1111.6837090000045, + "daemonDurationMs": 105, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 539440, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:16:19.280Z", + "finishedAt": "2026-09-01T17:16:20.254Z", + "operation": "snapshot", + "wallClockMs": 973.9179580000928, + "daemonDurationMs": 113, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 539441, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:16:20.254Z", + "finishedAt": "2026-09-01T17:16:22.792Z", + "operation": "snapshot", + "wallClockMs": 2538.0927499999525, + "daemonDurationMs": 111, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 539442, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 6, + "startedAt": "2026-09-01T17:16:22.792Z", + "finishedAt": "2026-09-01T17:16:23.885Z", + "operation": "snapshot", + "wallClockMs": 1092.700708999997, + "daemonDurationMs": 95, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 539443, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:16:23.885Z", + "finishedAt": "2026-09-01T17:16:25.144Z", + "operation": "snapshot", + "wallClockMs": 1258.7937499999534, + "daemonDurationMs": 94, + "responseBytes": 6272, + "nodeCount": 25, + "targetGeneration": 539444, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:16:25.144Z", + "finishedAt": "2026-09-01T17:16:26.163Z", + "operation": "snapshot", + "wallClockMs": 1019.3842919999734, + "daemonDurationMs": 107, + "responseBytes": 6273, + "nodeCount": 25, + "targetGeneration": 539445, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:16:26.164Z", + "finishedAt": "2026-09-01T17:16:27.239Z", + "operation": "snapshot", + "wallClockMs": 1075.8032499999972, + "daemonDurationMs": 96, + "responseBytes": 6274, + "nodeCount": 25, + "targetGeneration": 539446, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:16:27.239Z", + "finishedAt": "2026-09-01T17:16:29.161Z", + "operation": "snapshot", + "wallClockMs": 1921.846583000035, + "daemonDurationMs": 105, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 539447, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 11, + "startedAt": "2026-09-01T17:16:29.161Z", + "finishedAt": "2026-09-01T17:16:30.269Z", + "operation": "snapshot", + "wallClockMs": 1107.5236250000307, + "daemonDurationMs": 100, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 539448, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:16:30.269Z", + "finishedAt": "2026-09-01T17:16:31.374Z", + "operation": "snapshot", + "wallClockMs": 1104.9392499999376, + "daemonDurationMs": 105, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 539449, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:16:31.374Z", + "finishedAt": "2026-09-01T17:16:32.495Z", + "operation": "snapshot", + "wallClockMs": 1121.5292500000214, + "daemonDurationMs": 111, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 539450, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:16:32.495Z", + "finishedAt": "2026-09-01T17:16:34.170Z", + "operation": "snapshot", + "wallClockMs": 1674.4906669999473, + "daemonDurationMs": 113, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 539451, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 15, + "startedAt": "2026-09-01T17:16:34.170Z", + "finishedAt": "2026-09-01T17:16:35.279Z", + "operation": "snapshot", + "wallClockMs": 1108.919916999992, + "daemonDurationMs": 102, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 539452, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:16:35.279Z", + "finishedAt": "2026-09-01T17:16:36.386Z", + "operation": "snapshot", + "wallClockMs": 1106.6781250000931, + "daemonDurationMs": 103, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 539453, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:16:36.386Z", + "finishedAt": "2026-09-01T17:16:37.476Z", + "operation": "snapshot", + "wallClockMs": 1090.623790999991, + "daemonDurationMs": 90, + "responseBytes": 6275, + "nodeCount": 25, + "targetGeneration": 539454, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:16:37.476Z", + "finishedAt": "2026-09-01T17:16:38.153Z", + "operation": "snapshot", + "wallClockMs": 676.440750000067, + "daemonDurationMs": 102, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 539455, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 19, + "startedAt": "2026-09-01T17:16:38.153Z", + "finishedAt": "2026-09-01T17:16:39.268Z", + "operation": "snapshot", + "wallClockMs": 1114.9806249999674, + "daemonDurationMs": 104, + "responseBytes": 6276, + "nodeCount": 25, + "targetGeneration": 539456, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:16:39.268Z", + "finishedAt": "2026-09-01T17:16:40.375Z", + "operation": "snapshot", + "wallClockMs": 1106.7991250000196, + "daemonDurationMs": 106, + "responseBytes": 6277, + "nodeCount": 25, + "targetGeneration": 539457, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 676.440750000067, + "median": 1107.5236250000307, + "p95": 1921.846583000035, + "max": 2538.0927499999525, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 90, + "median": 105, + "p95": 113, + "max": 113, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6272, + "median": 6275, + "p95": 6277, + "max": 6277, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "alert", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:16:54.551Z", + "finishedAt": "2026-09-01T17:16:55.181Z", + "operation": "snapshot", + "wallClockMs": 629.3018330000341, + "daemonDurationMs": 132, + "responseBytes": 7162, + "nodeCount": 30, + "targetGeneration": 144109, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:16:55.181Z", + "finishedAt": "2026-09-01T17:16:55.819Z", + "operation": "snapshot", + "wallClockMs": 638.5381250000792, + "daemonDurationMs": 133, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 144110, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:16:55.819Z", + "finishedAt": "2026-09-01T17:16:56.322Z", + "operation": "snapshot", + "wallClockMs": 502.8080830000108, + "daemonDurationMs": 132, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 144111, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T17:16:56.322Z", + "finishedAt": "2026-09-01T17:16:57.153Z", + "operation": "snapshot", + "wallClockMs": 830.9902500000317, + "daemonDurationMs": 105, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 144112, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 5, + "startedAt": "2026-09-01T17:16:57.153Z", + "finishedAt": "2026-09-01T17:16:57.958Z", + "operation": "snapshot", + "wallClockMs": 805.2721250000177, + "daemonDurationMs": 129, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144113, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 6, + "startedAt": "2026-09-01T17:16:57.958Z", + "finishedAt": "2026-09-01T17:16:58.365Z", + "operation": "snapshot", + "wallClockMs": 407.1600000000326, + "daemonDurationMs": 133, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144114, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 7, + "startedAt": "2026-09-01T17:16:58.365Z", + "finishedAt": "2026-09-01T17:16:59.097Z", + "operation": "snapshot", + "wallClockMs": 732.0076249999693, + "daemonDurationMs": 134, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144115, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 8, + "startedAt": "2026-09-01T17:16:59.097Z", + "finishedAt": "2026-09-01T17:16:59.738Z", + "operation": "snapshot", + "wallClockMs": 640.1228330000304, + "daemonDurationMs": 134, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144116, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:16:59.738Z", + "finishedAt": "2026-09-01T17:17:00.368Z", + "operation": "snapshot", + "wallClockMs": 630.6271249999991, + "daemonDurationMs": 129, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144117, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:17:00.368Z", + "finishedAt": "2026-09-01T17:17:01.005Z", + "operation": "snapshot", + "wallClockMs": 636.9444589999039, + "daemonDurationMs": 131, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144118, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:17:01.005Z", + "finishedAt": "2026-09-01T17:17:01.643Z", + "operation": "snapshot", + "wallClockMs": 637.7571250000037, + "daemonDurationMs": 133, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144119, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:17:01.643Z", + "finishedAt": "2026-09-01T17:17:02.272Z", + "operation": "snapshot", + "wallClockMs": 629.1487910000142, + "daemonDurationMs": 129, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144120, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:17:02.272Z", + "finishedAt": "2026-09-01T17:17:02.908Z", + "operation": "snapshot", + "wallClockMs": 635.949459000025, + "daemonDurationMs": 130, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144121, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:17:02.908Z", + "finishedAt": "2026-09-01T17:17:03.409Z", + "operation": "snapshot", + "wallClockMs": 500.41587500006426, + "daemonDurationMs": 130, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144122, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 15, + "startedAt": "2026-09-01T17:17:03.409Z", + "finishedAt": "2026-09-01T17:17:04.170Z", + "operation": "snapshot", + "wallClockMs": 761.5774159999564, + "daemonDurationMs": 121, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 144123, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 16, + "startedAt": "2026-09-01T17:17:04.170Z", + "finishedAt": "2026-09-01T17:17:05.049Z", + "operation": "snapshot", + "wallClockMs": 878.2770420000888, + "daemonDurationMs": 134, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 144124, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 17, + "startedAt": "2026-09-01T17:17:05.049Z", + "finishedAt": "2026-09-01T17:17:05.661Z", + "operation": "snapshot", + "wallClockMs": 612.3253750000149, + "daemonDurationMs": 105, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 144125, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:17:05.661Z", + "finishedAt": "2026-09-01T17:17:06.300Z", + "operation": "snapshot", + "wallClockMs": 638.6930830000201, + "daemonDurationMs": 131, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144126, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:17:06.300Z", + "finishedAt": "2026-09-01T17:17:06.938Z", + "operation": "snapshot", + "wallClockMs": 638.1423749999376, + "daemonDurationMs": 132, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144127, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:17:06.938Z", + "finishedAt": "2026-09-01T17:17:07.303Z", + "operation": "snapshot", + "wallClockMs": 365.13133300002664, + "daemonDurationMs": 129, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 144128, + "firstTree": "readable", + "ok": true, + "outlier": true + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 365.13133300002664, + "median": 636.9444589999039, + "p95": 830.9902500000317, + "max": 878.2770420000888, + "outlierCount": 9, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 105, + "median": 131, + "p95": 134, + "max": 134, + "outlierCount": 9, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 7162, + "median": 7168, + "p95": 7168, + "max": 7168, + "outlierCount": 9, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "alert", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:17:27.063Z", + "finishedAt": "2026-09-01T17:17:28.545Z", + "operation": "snapshot", + "wallClockMs": 1482.1708749999525, + "daemonDurationMs": 127, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 353047, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:17:28.545Z", + "finishedAt": "2026-09-01T17:17:30.170Z", + "operation": "snapshot", + "wallClockMs": 1625.3167089999188, + "daemonDurationMs": 120, + "responseBytes": 7166, + "nodeCount": 30, + "targetGeneration": 353048, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:17:30.170Z", + "finishedAt": "2026-09-01T17:17:31.167Z", + "operation": "snapshot", + "wallClockMs": 996.8061250000028, + "daemonDurationMs": 109, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 353049, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:17:31.167Z", + "finishedAt": "2026-09-01T17:17:32.161Z", + "operation": "snapshot", + "wallClockMs": 993.4096249999711, + "daemonDurationMs": 106, + "responseBytes": 7165, + "nodeCount": 30, + "targetGeneration": 353050, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:17:32.161Z", + "finishedAt": "2026-09-01T17:17:33.523Z", + "operation": "snapshot", + "wallClockMs": 1362.4273749999702, + "daemonDurationMs": 113, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 353051, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:17:33.523Z", + "finishedAt": "2026-09-01T17:17:35.148Z", + "operation": "snapshot", + "wallClockMs": 1624.3292909999145, + "daemonDurationMs": 119, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353052, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:17:35.148Z", + "finishedAt": "2026-09-01T17:17:36.265Z", + "operation": "snapshot", + "wallClockMs": 1117.8227500000503, + "daemonDurationMs": 107, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353053, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:17:36.266Z", + "finishedAt": "2026-09-01T17:17:37.190Z", + "operation": "snapshot", + "wallClockMs": 924.1884169999976, + "daemonDurationMs": 131, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353054, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:17:37.190Z", + "finishedAt": "2026-09-01T17:17:38.768Z", + "operation": "snapshot", + "wallClockMs": 1578.2477499999804, + "daemonDurationMs": 133, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353055, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:17:38.768Z", + "finishedAt": "2026-09-01T17:17:40.671Z", + "operation": "snapshot", + "wallClockMs": 1903.1648749999003, + "daemonDurationMs": 132, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 353056, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:17:40.671Z", + "finishedAt": "2026-09-01T17:17:42.192Z", + "operation": "snapshot", + "wallClockMs": 1520.6240830000024, + "daemonDurationMs": 132, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353057, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:17:42.192Z", + "finishedAt": "2026-09-01T17:17:43.189Z", + "operation": "snapshot", + "wallClockMs": 997.075542000006, + "daemonDurationMs": 132, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 353058, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:17:43.189Z", + "finishedAt": "2026-09-01T17:17:44.384Z", + "operation": "snapshot", + "wallClockMs": 1194.877000000095, + "daemonDurationMs": 124, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353059, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:17:44.384Z", + "finishedAt": "2026-09-01T17:17:45.821Z", + "operation": "snapshot", + "wallClockMs": 1436.8297089999542, + "daemonDurationMs": 135, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 353060, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:17:45.821Z", + "finishedAt": "2026-09-01T17:17:46.813Z", + "operation": "snapshot", + "wallClockMs": 991.640458000009, + "daemonDurationMs": 131, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 353061, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:17:46.813Z", + "finishedAt": "2026-09-01T17:17:48.707Z", + "operation": "snapshot", + "wallClockMs": 1894.1992910000263, + "daemonDurationMs": 121, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353062, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:17:48.707Z", + "finishedAt": "2026-09-01T17:17:49.956Z", + "operation": "snapshot", + "wallClockMs": 1248.4709590000566, + "daemonDurationMs": 134, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353063, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:17:49.956Z", + "finishedAt": "2026-09-01T17:17:51.337Z", + "operation": "snapshot", + "wallClockMs": 1381.0855000000447, + "daemonDurationMs": 123, + "responseBytes": 7167, + "nodeCount": 30, + "targetGeneration": 353064, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:17:51.337Z", + "finishedAt": "2026-09-01T17:17:52.475Z", + "operation": "snapshot", + "wallClockMs": 1138.0681249999907, + "daemonDurationMs": 131, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353065, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:17:52.475Z", + "finishedAt": "2026-09-01T17:17:55.176Z", + "operation": "snapshot", + "wallClockMs": 2701.3390000000363, + "daemonDurationMs": 122, + "responseBytes": 7168, + "nodeCount": 30, + "targetGeneration": 353066, + "firstTree": "readable", + "ok": true, + "outlier": true + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 924.1884169999976, + "median": 1362.4273749999702, + "p95": 1903.1648749999003, + "max": 2701.3390000000363, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 106, + "median": 124, + "p95": 134, + "max": 135, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 7165, + "median": 7167, + "p95": 7168, + "max": 7168, + "outlierCount": 1, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "system-surface", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:18:06.515Z", + "finishedAt": "2026-09-01T17:18:07.153Z", + "operation": "snapshot", + "wallClockMs": 637.8986659999937, + "daemonDurationMs": 133, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 480005, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:18:07.153Z", + "finishedAt": "2026-09-01T17:18:07.789Z", + "operation": "snapshot", + "wallClockMs": 636.2560829999857, + "daemonDurationMs": 132, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 480006, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:18:07.789Z", + "finishedAt": "2026-09-01T17:18:08.279Z", + "operation": "snapshot", + "wallClockMs": 490.2282500000438, + "daemonDurationMs": 119, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 480007, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:18:08.279Z", + "finishedAt": "2026-09-01T17:18:09.003Z", + "operation": "snapshot", + "wallClockMs": 723.7752079999773, + "daemonDurationMs": 105, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 480008, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:18:09.003Z", + "finishedAt": "2026-09-01T17:18:09.750Z", + "operation": "snapshot", + "wallClockMs": 746.7754160000477, + "daemonDurationMs": 118, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 480009, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:18:09.750Z", + "finishedAt": "2026-09-01T17:18:10.187Z", + "operation": "snapshot", + "wallClockMs": 436.8852079999633, + "daemonDurationMs": 135, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 480010, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:18:10.187Z", + "finishedAt": "2026-09-01T17:18:11.686Z", + "operation": "snapshot", + "wallClockMs": 1499.0858749999898, + "daemonDurationMs": 133, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 480011, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 8, + "startedAt": "2026-09-01T17:18:11.686Z", + "finishedAt": "2026-09-01T17:18:12.169Z", + "operation": "snapshot", + "wallClockMs": 482.8238329999149, + "daemonDurationMs": 134, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 480012, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:18:12.169Z", + "finishedAt": "2026-09-01T17:18:13.684Z", + "operation": "snapshot", + "wallClockMs": 1515.187249999959, + "daemonDurationMs": 133, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 480013, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 10, + "startedAt": "2026-09-01T17:18:13.684Z", + "finishedAt": "2026-09-01T17:18:14.322Z", + "operation": "snapshot", + "wallClockMs": 638.5414159999928, + "daemonDurationMs": 133, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 480014, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:18:14.322Z", + "finishedAt": "2026-09-01T17:18:14.960Z", + "operation": "snapshot", + "wallClockMs": 638.0137500000419, + "daemonDurationMs": 131, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 480015, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:18:14.961Z", + "finishedAt": "2026-09-01T17:18:15.576Z", + "operation": "snapshot", + "wallClockMs": 615.1440410000505, + "daemonDurationMs": 115, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 480016, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:18:15.576Z", + "finishedAt": "2026-09-01T17:18:16.185Z", + "operation": "snapshot", + "wallClockMs": 608.9797079999698, + "daemonDurationMs": 131, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 480017, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:18:16.185Z", + "finishedAt": "2026-09-01T17:18:16.818Z", + "operation": "snapshot", + "wallClockMs": 632.984541999991, + "daemonDurationMs": 127, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 480018, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:18:16.818Z", + "finishedAt": "2026-09-01T17:18:17.327Z", + "operation": "snapshot", + "wallClockMs": 509.300416000071, + "daemonDurationMs": 134, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 480019, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:18:17.327Z", + "finishedAt": "2026-09-01T17:18:18.099Z", + "operation": "snapshot", + "wallClockMs": 772.4807499999879, + "daemonDurationMs": 132, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 480020, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:18:18.100Z", + "finishedAt": "2026-09-01T17:18:18.741Z", + "operation": "snapshot", + "wallClockMs": 641.4130830001086, + "daemonDurationMs": 134, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 480021, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:18:18.741Z", + "finishedAt": "2026-09-01T17:18:19.243Z", + "operation": "snapshot", + "wallClockMs": 501.6959589999169, + "daemonDurationMs": 104, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 480022, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:18:19.243Z", + "finishedAt": "2026-09-01T17:18:20.177Z", + "operation": "snapshot", + "wallClockMs": 934.0390419999603, + "daemonDurationMs": 127, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 480023, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:18:20.177Z", + "finishedAt": "2026-09-01T17:18:21.681Z", + "operation": "snapshot", + "wallClockMs": 1503.7648340000305, + "daemonDurationMs": 128, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 480024, + "firstTree": "readable", + "ok": true, + "outlier": true + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 436.8852079999633, + "median": 637.8986659999937, + "p95": 1503.7648340000305, + "max": 1515.187249999959, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 104, + "median": 131, + "p95": 134, + "max": 135, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 4608, + "median": 4610, + "p95": 4611, + "max": 4611, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "system-surface", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:18:34.189Z", + "finishedAt": "2026-09-01T17:18:35.279Z", + "operation": "snapshot", + "wallClockMs": 1089.822499999893, + "daemonDurationMs": 130, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 870087, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:18:35.279Z", + "finishedAt": "2026-09-01T17:18:37.187Z", + "operation": "snapshot", + "wallClockMs": 1908.1487920000218, + "daemonDurationMs": 134, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 870088, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 3, + "startedAt": "2026-09-01T17:18:37.187Z", + "finishedAt": "2026-09-01T17:18:38.389Z", + "operation": "snapshot", + "wallClockMs": 1201.43658400001, + "daemonDurationMs": 112, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 870089, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:18:38.389Z", + "finishedAt": "2026-09-01T17:18:40.661Z", + "operation": "snapshot", + "wallClockMs": 2272.579582999926, + "daemonDurationMs": 112, + "responseBytes": 4609, + "nodeCount": 18, + "targetGeneration": 870090, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 5, + "startedAt": "2026-09-01T17:18:40.661Z", + "finishedAt": "2026-09-01T17:18:41.807Z", + "operation": "snapshot", + "wallClockMs": 1145.329207999981, + "daemonDurationMs": 135, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 870091, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:18:41.807Z", + "finishedAt": "2026-09-01T17:18:42.528Z", + "operation": "snapshot", + "wallClockMs": 721.2534999999916, + "daemonDurationMs": 126, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 870092, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:18:42.528Z", + "finishedAt": "2026-09-01T17:18:44.187Z", + "operation": "snapshot", + "wallClockMs": 1659.2556249999907, + "daemonDurationMs": 130, + "responseBytes": 4608, + "nodeCount": 18, + "targetGeneration": 870093, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:18:44.187Z", + "finishedAt": "2026-09-01T17:18:45.184Z", + "operation": "snapshot", + "wallClockMs": 996.8705830000108, + "daemonDurationMs": 132, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 870094, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:18:45.184Z", + "finishedAt": "2026-09-01T17:18:46.830Z", + "operation": "snapshot", + "wallClockMs": 1645.5092500000028, + "daemonDurationMs": 132, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 870095, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:18:46.830Z", + "finishedAt": "2026-09-01T17:18:47.966Z", + "operation": "snapshot", + "wallClockMs": 1136.1591659999685, + "daemonDurationMs": 132, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 870096, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:18:47.966Z", + "finishedAt": "2026-09-01T17:18:49.186Z", + "operation": "snapshot", + "wallClockMs": 1219.7354169999016, + "daemonDurationMs": 127, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 870097, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:18:49.186Z", + "finishedAt": "2026-09-01T17:18:50.580Z", + "operation": "snapshot", + "wallClockMs": 1393.65708299994, + "daemonDurationMs": 133, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 870098, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:18:50.580Z", + "finishedAt": "2026-09-01T17:18:52.188Z", + "operation": "snapshot", + "wallClockMs": 1608.3987499999348, + "daemonDurationMs": 130, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 870099, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:18:52.188Z", + "finishedAt": "2026-09-01T17:18:53.311Z", + "operation": "snapshot", + "wallClockMs": 1122.4834160000319, + "daemonDurationMs": 119, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 870100, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:18:53.311Z", + "finishedAt": "2026-09-01T17:18:54.437Z", + "operation": "snapshot", + "wallClockMs": 1126.0427500000224, + "daemonDurationMs": 122, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 870101, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:18:54.437Z", + "finishedAt": "2026-09-01T17:18:55.569Z", + "operation": "snapshot", + "wallClockMs": 1131.7228340000147, + "daemonDurationMs": 124, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 870102, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:18:55.569Z", + "finishedAt": "2026-09-01T17:18:56.765Z", + "operation": "snapshot", + "wallClockMs": 1196.1623750000726, + "daemonDurationMs": 133, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 870103, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:18:56.765Z", + "finishedAt": "2026-09-01T17:18:58.190Z", + "operation": "snapshot", + "wallClockMs": 1425.078125, + "daemonDurationMs": 134, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 870104, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:18:58.190Z", + "finishedAt": "2026-09-01T17:18:59.318Z", + "operation": "snapshot", + "wallClockMs": 1128.1483330000192, + "daemonDurationMs": 119, + "responseBytes": 4611, + "nodeCount": 18, + "targetGeneration": 870105, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:18:59.318Z", + "finishedAt": "2026-09-01T17:19:00.434Z", + "operation": "snapshot", + "wallClockMs": 1115.5170420000795, + "daemonDurationMs": 116, + "responseBytes": 4610, + "nodeCount": 18, + "targetGeneration": 870106, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 721.2534999999916, + "median": 1145.329207999981, + "p95": 1908.1487920000218, + "max": 2272.579582999926, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 112, + "median": 130, + "p95": 134, + "max": 135, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 4608, + "median": 4610, + "p95": 4611, + "max": 4611, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "persistent-client", + "state": "warm", + "screen": "xctest-stress", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:19:09.991Z", + "finishedAt": "2026-09-01T17:19:10.606Z", + "operation": "snapshot", + "wallClockMs": 615.2828339999542, + "daemonDurationMs": 108, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 709715, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:19:10.606Z", + "finishedAt": "2026-09-01T17:19:11.225Z", + "operation": "snapshot", + "wallClockMs": 618.7531250000466, + "daemonDurationMs": 117, + "responseBytes": 6839, + "nodeCount": 29, + "targetGeneration": 709716, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:19:11.225Z", + "finishedAt": "2026-09-01T17:19:11.864Z", + "operation": "snapshot", + "wallClockMs": 638.9510000000009, + "daemonDurationMs": 131, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 709717, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:19:11.864Z", + "finishedAt": "2026-09-01T17:19:12.364Z", + "operation": "snapshot", + "wallClockMs": 500.32433400000446, + "daemonDurationMs": 134, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 709718, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:19:12.364Z", + "finishedAt": "2026-09-01T17:19:13.180Z", + "operation": "snapshot", + "wallClockMs": 815.9032919999445, + "daemonDurationMs": 132, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 709719, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:19:13.180Z", + "finishedAt": "2026-09-01T17:19:13.590Z", + "operation": "snapshot", + "wallClockMs": 409.5147500000894, + "daemonDurationMs": 130, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 709720, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:19:13.590Z", + "finishedAt": "2026-09-01T17:19:14.169Z", + "operation": "snapshot", + "wallClockMs": 579.2466660001082, + "daemonDurationMs": 120, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 709721, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:19:14.169Z", + "finishedAt": "2026-09-01T17:19:15.172Z", + "operation": "snapshot", + "wallClockMs": 1003.1196670000209, + "daemonDurationMs": 124, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 709722, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 9, + "startedAt": "2026-09-01T17:19:15.172Z", + "finishedAt": "2026-09-01T17:19:15.681Z", + "operation": "snapshot", + "wallClockMs": 508.7245839999523, + "daemonDurationMs": 130, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 709723, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:19:15.681Z", + "finishedAt": "2026-09-01T17:19:16.311Z", + "operation": "snapshot", + "wallClockMs": 629.9195420000469, + "daemonDurationMs": 131, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 709724, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:19:16.311Z", + "finishedAt": "2026-09-01T17:19:16.945Z", + "operation": "snapshot", + "wallClockMs": 633.9070000000065, + "daemonDurationMs": 130, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 709725, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:19:16.945Z", + "finishedAt": "2026-09-01T17:19:17.430Z", + "operation": "snapshot", + "wallClockMs": 484.6267499999376, + "daemonDurationMs": 118, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 709726, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:19:17.430Z", + "finishedAt": "2026-09-01T17:19:18.354Z", + "operation": "snapshot", + "wallClockMs": 924.8016669999342, + "daemonDurationMs": 131, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 709727, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 14, + "startedAt": "2026-09-01T17:19:18.354Z", + "finishedAt": "2026-09-01T17:19:19.181Z", + "operation": "snapshot", + "wallClockMs": 826.6198749999749, + "daemonDurationMs": 129, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 709728, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:19:19.181Z", + "finishedAt": "2026-09-01T17:19:19.815Z", + "operation": "snapshot", + "wallClockMs": 634.3582079999615, + "daemonDurationMs": 129, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 709729, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:19:19.815Z", + "finishedAt": "2026-09-01T17:19:20.320Z", + "operation": "snapshot", + "wallClockMs": 504.59625000006054, + "daemonDurationMs": 132, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 709730, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:19:20.320Z", + "finishedAt": "2026-09-01T17:19:21.176Z", + "operation": "snapshot", + "wallClockMs": 856.064291000017, + "daemonDurationMs": 129, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 709731, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 18, + "startedAt": "2026-09-01T17:19:21.176Z", + "finishedAt": "2026-09-01T17:19:21.681Z", + "operation": "snapshot", + "wallClockMs": 504.5672499999637, + "daemonDurationMs": 130, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 709732, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:19:21.681Z", + "finishedAt": "2026-09-01T17:19:22.280Z", + "operation": "snapshot", + "wallClockMs": 599.3338330000406, + "daemonDurationMs": 132, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 709733, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:19:22.280Z", + "finishedAt": "2026-09-01T17:19:22.915Z", + "operation": "snapshot", + "wallClockMs": 635.0605409999844, + "daemonDurationMs": 128, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 709734, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 409.5147500000894, + "median": 618.7531250000466, + "p95": 924.8016669999342, + "max": 1003.1196670000209, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 108, + "median": 130, + "p95": 132, + "max": 134, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6839, + "median": 6842, + "p95": 6843, + "max": 6843, + "outlierCount": 3, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "proxy", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "xctest-stress", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:19:35.058Z", + "finishedAt": "2026-09-01T17:19:36.551Z", + "operation": "snapshot", + "wallClockMs": 1493.1155000000726, + "daemonDurationMs": 108, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 629024, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T17:19:36.552Z", + "finishedAt": "2026-09-01T17:19:38.190Z", + "operation": "snapshot", + "wallClockMs": 1638.5487089999951, + "daemonDurationMs": 133, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 629025, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:19:38.190Z", + "finishedAt": "2026-09-01T17:19:39.272Z", + "operation": "snapshot", + "wallClockMs": 1081.890167000005, + "daemonDurationMs": 130, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 629026, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:19:39.272Z", + "finishedAt": "2026-09-01T17:19:40.668Z", + "operation": "snapshot", + "wallClockMs": 1395.485457999981, + "daemonDurationMs": 118, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 629027, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:19:40.668Z", + "finishedAt": "2026-09-01T17:19:42.161Z", + "operation": "snapshot", + "wallClockMs": 1493.3981660000281, + "daemonDurationMs": 111, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 629028, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:19:42.161Z", + "finishedAt": "2026-09-01T17:19:44.123Z", + "operation": "snapshot", + "wallClockMs": 1961.4892499999842, + "daemonDurationMs": 132, + "responseBytes": 6840, + "nodeCount": 29, + "targetGeneration": 629029, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:19:44.123Z", + "finishedAt": "2026-09-01T17:19:45.624Z", + "operation": "snapshot", + "wallClockMs": 1501.0341659999685, + "daemonDurationMs": 129, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 629030, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:19:45.624Z", + "finishedAt": "2026-09-01T17:19:47.185Z", + "operation": "snapshot", + "wallClockMs": 1560.9364160000114, + "daemonDurationMs": 128, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 629031, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:19:47.185Z", + "finishedAt": "2026-09-01T17:19:48.325Z", + "operation": "snapshot", + "wallClockMs": 1140.2889999999898, + "daemonDurationMs": 130, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 629032, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:19:48.325Z", + "finishedAt": "2026-09-01T17:19:49.458Z", + "operation": "snapshot", + "wallClockMs": 1133.3041250000242, + "daemonDurationMs": 133, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 629033, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:19:49.458Z", + "finishedAt": "2026-09-01T17:19:50.686Z", + "operation": "snapshot", + "wallClockMs": 1227.0713749999413, + "daemonDurationMs": 130, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 629034, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:19:50.686Z", + "finishedAt": "2026-09-01T17:19:52.100Z", + "operation": "snapshot", + "wallClockMs": 1414.426833000034, + "daemonDurationMs": 126, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 629035, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:19:52.100Z", + "finishedAt": "2026-09-01T17:19:53.686Z", + "operation": "snapshot", + "wallClockMs": 1586.108082999941, + "daemonDurationMs": 130, + "responseBytes": 6842, + "nodeCount": 29, + "targetGeneration": 629036, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T17:19:53.686Z", + "finishedAt": "2026-09-01T17:19:55.182Z", + "operation": "snapshot", + "wallClockMs": 1495.9697079999605, + "daemonDurationMs": 131, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 629037, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:19:55.182Z", + "finishedAt": "2026-09-01T17:19:56.328Z", + "operation": "snapshot", + "wallClockMs": 1145.8230830000248, + "daemonDurationMs": 131, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 629038, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:19:56.328Z", + "finishedAt": "2026-09-01T17:19:57.466Z", + "operation": "snapshot", + "wallClockMs": 1137.4133330000332, + "daemonDurationMs": 133, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 629039, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:19:57.466Z", + "finishedAt": "2026-09-01T17:19:58.608Z", + "operation": "snapshot", + "wallClockMs": 1142.5081249999348, + "daemonDurationMs": 136, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 629040, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:19:58.608Z", + "finishedAt": "2026-09-01T17:20:00.162Z", + "operation": "snapshot", + "wallClockMs": 1553.8067499999888, + "daemonDurationMs": 113, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 629041, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:20:00.162Z", + "finishedAt": "2026-09-01T17:20:01.306Z", + "operation": "snapshot", + "wallClockMs": 1144.4245830000145, + "daemonDurationMs": 132, + "responseBytes": 6843, + "nodeCount": 29, + "targetGeneration": 629042, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:20:01.307Z", + "finishedAt": "2026-09-01T17:20:02.429Z", + "operation": "snapshot", + "wallClockMs": 1122.1651249999413, + "daemonDurationMs": 119, + "responseBytes": 6841, + "nodeCount": 29, + "targetGeneration": 629043, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "network": { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + }, + "wallClockMs": { + "n": 20, + "min": 1081.890167000005, + "median": 1395.485457999981, + "p95": 1638.5487089999951, + "max": 1961.4892499999842, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 108, + "median": 130, + "p95": 133, + "max": 136, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 6840, + "median": 6842, + "p95": 6843, + "max": 6843, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + } + ], + "packageSize": { + "status": "not-run", + "revision": "71fb2483f30d90e615e949601c836aeebbf450c5" + }, + "deepButtonEvidence": { + "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", + "proxyNetworks": [ + { + "rttMs": 0, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2189 + }, + { + "rttMs": 20, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2209 + }, + { + "rttMs": 80, + "bandwidthKbps": null, + "packetLossPercent": 0, + "seed": 2269 + } + ] +} diff --git a/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-proxy-71fb2483f.md b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-proxy-71fb2483f.md new file mode 100644 index 000000000..47bb0d2c9 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-proxy-71fb2483f.md @@ -0,0 +1,58 @@ +# iOS snapshot convergence benchmark + +- Status: **completed** +- Revision: 71fb2483f30d90e615e949601c836aeebbf450c5 +- Host: MacBook Pro (Mac16,8; Apple M4 Pro, 12 cores) +- Target: bench-golden-v2 (7E76ECA9-D40C-4833-A711-F870F8CE9363, com.apple.CoreSimulator.SimRuntime.iOS-27-0) +- Generated: 2026-09-01T17:20:04.211Z + +| State | Screen | Transport | Execution | N | Wall median | Wall p95 | Daemon median | Response median | Failures | +|---|---|---|---|---:|---:|---:|---:|---:|---:| +| warm | quiet | proxy | persistent-client | 20 | 273.3 | 1313.9 | 211.0 | 1924.0 | 0 | +| warm | quiet | proxy | fresh-process-cli | 20 | 233.2 | 288.7 | 67.0 | 1919.0 | 0 | +| warm | list | proxy | persistent-client | 20 | 254.1 | 262.5 | 250.0 | 8281.0 | 0 | +| warm | list | proxy | fresh-process-cli | 20 | 430.5 | 523.9 | 269.0 | 8281.0 | 0 | +| warm | nested-scroll | proxy | persistent-client | 20 | 137.7 | 228.9 | 127.0 | 6275.0 | 0 | +| warm | nested-scroll | proxy | fresh-process-cli | 20 | 187.9 | 350.9 | 82.0 | 6272.0 | 0 | +| warm | alert | proxy | persistent-client | 20 | 108.4 | 113.2 | 102.0 | 7168.0 | 0 | +| warm | alert | proxy | fresh-process-cli | 20 | 210.2 | 278.1 | 103.0 | 7167.0 | 0 | +| warm | system-surface | proxy | persistent-client | 20 | 105.0 | 108.4 | 102.0 | 4610.0 | 0 | +| warm | system-surface | proxy | fresh-process-cli | 20 | 209.5 | 238.2 | 110.0 | 4610.0 | 0 | +| warm | xctest-stress | proxy | persistent-client | 20 | 126.8 | 168.7 | 120.0 | 6842.0 | 0 | +| warm | xctest-stress | proxy | fresh-process-cli | 20 | 224.8 | 278.3 | 111.0 | 6841.0 | 0 | +| warm | quiet | proxy | persistent-client | 20 | 561.5 | 927.4 | 60.0 | 1919.0 | 0 | +| warm | quiet | proxy | fresh-process-cli | 20 | 1057.3 | 2038.0 | 57.0 | 1919.0 | 0 | +| warm | list | proxy | persistent-client | 20 | 718.5 | 884.4 | 218.0 | 8281.0 | 0 | +| warm | list | proxy | fresh-process-cli | 20 | 1221.1 | 1494.4 | 220.0 | 8281.0 | 0 | +| warm | nested-scroll | proxy | persistent-client | 20 | 590.4 | 1428.5 | 88.0 | 6272.0 | 0 | +| warm | nested-scroll | proxy | fresh-process-cli | 20 | 1116.1 | 1505.1 | 108.0 | 6275.0 | 0 | +| warm | alert | proxy | persistent-client | 20 | 622.5 | 925.3 | 126.0 | 7167.0 | 0 | +| warm | alert | proxy | fresh-process-cli | 20 | 1112.8 | 1614.4 | 111.0 | 7167.0 | 0 | +| warm | system-surface | proxy | persistent-client | 20 | 537.4 | 895.2 | 112.0 | 4610.0 | 0 | +| warm | system-surface | proxy | fresh-process-cli | 20 | 1119.3 | 1637.6 | 115.0 | 4609.0 | 0 | +| warm | xctest-stress | proxy | persistent-client | 20 | 612.4 | 1364.7 | 114.0 | 6842.0 | 0 | +| warm | xctest-stress | proxy | fresh-process-cli | 20 | 1135.6 | 2699.9 | 129.0 | 6842.0 | 0 | +| warm | quiet | proxy | persistent-client | 20 | 806.2 | 1109.4 | 55.0 | 1920.0 | 0 | +| warm | quiet | proxy | fresh-process-cli | 20 | 1801.3 | 3547.9 | 55.0 | 1919.0 | 0 | +| warm | list | proxy | persistent-client | 20 | 729.0 | 854.4 | 233.0 | 8282.0 | 0 | +| warm | list | proxy | fresh-process-cli | 20 | 1328.1 | 1976.2 | 232.0 | 8281.0 | 0 | +| warm | nested-scroll | proxy | persistent-client | 20 | 615.7 | 1301.8 | 109.0 | 6275.0 | 0 | +| warm | nested-scroll | proxy | fresh-process-cli | 20 | 1107.5 | 1921.8 | 105.0 | 6275.0 | 0 | +| warm | alert | proxy | persistent-client | 20 | 636.9 | 831.0 | 131.0 | 7168.0 | 0 | +| warm | alert | proxy | fresh-process-cli | 20 | 1362.4 | 1903.2 | 124.0 | 7167.0 | 0 | +| warm | system-surface | proxy | persistent-client | 20 | 637.9 | 1503.8 | 131.0 | 4610.0 | 0 | +| warm | system-surface | proxy | fresh-process-cli | 20 | 1145.3 | 1908.1 | 130.0 | 4610.0 | 0 | +| warm | xctest-stress | proxy | persistent-client | 20 | 618.8 | 924.8 | 130.0 | 6842.0 | 0 | +| warm | xctest-stress | proxy | fresh-process-cli | 20 | 1395.5 | 1638.5 | 130.0 | 6842.0 | 0 | + +## Package size + +Not measured. + +## Deep-button control + +- Fixture artifact: deep-button-fixture.v1.json (depth 72) +- Red control: pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow (exit 1) + - AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid. +- Safe control: pnpm bench:ios-snapshot:deep-button -- --rule safe-full (exit 0) + - full observation changed and includes the changed descendant. diff --git a/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-warm-relaunch-local-71fb2483f.json b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-warm-relaunch-local-71fb2483f.json new file mode 100644 index 000000000..de4c19cac --- /dev/null +++ b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-warm-relaunch-local-71fb2483f.json @@ -0,0 +1,4075 @@ +{ + "schemaVersion": "ios-snapshot-convergence.v1", + "issue": "#2189", + "parent": "#2188", + "references": { + "deepButton": "#1626", + "appMount": "#1571" + }, + "runId": "ios-snapshot-1788282170284-66287", + "generatedAt": "2026-09-01T17:02:50.284Z", + "revision": { + "commit": "71fb2483f30d90e615e949601c836aeebbf450c5", + "branch": "codex/2189-ios-snapshot-baselines", + "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" + }, + "host": { + "model": "MacBook Pro", + "modelIdentifier": "Mac16,8", + "cpu": "Apple M4 Pro", + "cpuCores": 12 + }, + "target": { + "platform": "ios", + "kind": "simulator", + "udid": "7E76ECA9-D40C-4833-A711-F870F8CE9363", + "name": "bench-golden-v2", + "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-27-0", + "appId": "com.callstack.agentdevicelab", + "appPath": "/private/tmp/agent-device-2189-fixture-app-repacked/AgentDeviceTester.app" + }, + "config": { + "warmSampleMinimum": 20, + "coldSampleMinimum": 10, + "requestedSamples": 20, + "screens": ["quiet", "list", "nested-scroll", "alert", "system-surface", "xctest-stress"], + "states": ["warm", "relaunch"] + }, + "measurements": [ + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "quiet", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:44:02.692Z", + "finishedAt": "2026-09-01T16:44:03.049Z", + "operation": "snapshot", + "wallClockMs": 356.7773750000051, + "daemonDurationMs": 149, + "responseBytes": 4004, + "nodeCount": 6, + "targetGeneration": 682762, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 2, + "startedAt": "2026-09-01T16:44:05.754Z", + "finishedAt": "2026-09-01T16:44:06.052Z", + "operation": "snapshot", + "wallClockMs": 297.28899999999703, + "daemonDurationMs": 90, + "responseBytes": 4003, + "nodeCount": 6, + "targetGeneration": 682763, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 3, + "startedAt": "2026-09-01T16:44:07.808Z", + "finishedAt": "2026-09-01T16:44:08.105Z", + "operation": "snapshot", + "wallClockMs": 296.4367920000004, + "daemonDurationMs": 116, + "responseBytes": 3998, + "nodeCount": 6, + "targetGeneration": 682764, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T16:44:10.065Z", + "finishedAt": "2026-09-01T16:44:10.249Z", + "operation": "snapshot", + "wallClockMs": 183.35933400000067, + "daemonDurationMs": 55, + "responseBytes": 4001, + "nodeCount": 6, + "targetGeneration": 682765, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:44:11.679Z", + "finishedAt": "2026-09-01T16:44:11.825Z", + "operation": "snapshot", + "wallClockMs": 146.90679100000125, + "daemonDurationMs": 49, + "responseBytes": 4003, + "nodeCount": 6, + "targetGeneration": 682766, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:44:13.177Z", + "finishedAt": "2026-09-01T16:44:13.359Z", + "operation": "snapshot", + "wallClockMs": 182.01537500000268, + "daemonDurationMs": 78, + "responseBytes": 4002, + "nodeCount": 6, + "targetGeneration": 682767, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:44:14.737Z", + "finishedAt": "2026-09-01T16:44:14.894Z", + "operation": "snapshot", + "wallClockMs": 157.0014999999985, + "daemonDurationMs": 53, + "responseBytes": 4002, + "nodeCount": 6, + "targetGeneration": 682768, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:44:16.230Z", + "finishedAt": "2026-09-01T16:44:16.387Z", + "operation": "snapshot", + "wallClockMs": 157.16137500000332, + "daemonDurationMs": 52, + "responseBytes": 4004, + "nodeCount": 6, + "targetGeneration": 682769, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:44:17.645Z", + "finishedAt": "2026-09-01T16:44:17.799Z", + "operation": "snapshot", + "wallClockMs": 154.0971669999999, + "daemonDurationMs": 50, + "responseBytes": 4004, + "nodeCount": 6, + "targetGeneration": 682770, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:44:19.086Z", + "finishedAt": "2026-09-01T16:44:19.225Z", + "operation": "snapshot", + "wallClockMs": 139.22624999999243, + "daemonDurationMs": 48, + "responseBytes": 4004, + "nodeCount": 6, + "targetGeneration": 682771, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:44:20.516Z", + "finishedAt": "2026-09-01T16:44:20.831Z", + "operation": "snapshot", + "wallClockMs": 315.26750000000175, + "daemonDurationMs": 50, + "responseBytes": 4005, + "nodeCount": 6, + "targetGeneration": 682772, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 12, + "startedAt": "2026-09-01T16:44:22.093Z", + "finishedAt": "2026-09-01T16:44:22.246Z", + "operation": "snapshot", + "wallClockMs": 152.6237919999985, + "daemonDurationMs": 50, + "responseBytes": 4004, + "nodeCount": 6, + "targetGeneration": 682773, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:44:23.686Z", + "finishedAt": "2026-09-01T16:44:23.839Z", + "operation": "snapshot", + "wallClockMs": 153.22158300000592, + "daemonDurationMs": 50, + "responseBytes": 4005, + "nodeCount": 6, + "targetGeneration": 682774, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:44:25.133Z", + "finishedAt": "2026-09-01T16:44:25.287Z", + "operation": "snapshot", + "wallClockMs": 154.2664999999979, + "daemonDurationMs": 50, + "responseBytes": 4005, + "nodeCount": 6, + "targetGeneration": 682775, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:44:26.581Z", + "finishedAt": "2026-09-01T16:44:26.715Z", + "operation": "snapshot", + "wallClockMs": 133.9898749999993, + "daemonDurationMs": 43, + "responseBytes": 4005, + "nodeCount": 6, + "targetGeneration": 682776, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:44:28.038Z", + "finishedAt": "2026-09-01T16:44:28.176Z", + "operation": "snapshot", + "wallClockMs": 138.3605419999949, + "daemonDurationMs": 46, + "responseBytes": 4004, + "nodeCount": 6, + "targetGeneration": 682777, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:44:29.415Z", + "finishedAt": "2026-09-01T16:44:29.563Z", + "operation": "snapshot", + "wallClockMs": 148.5216250000085, + "daemonDurationMs": 49, + "responseBytes": 4004, + "nodeCount": 6, + "targetGeneration": 682778, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T16:44:30.955Z", + "finishedAt": "2026-09-01T16:44:31.108Z", + "operation": "snapshot", + "wallClockMs": 153.54237499999, + "daemonDurationMs": 51, + "responseBytes": 4003, + "nodeCount": 6, + "targetGeneration": 682779, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:44:32.336Z", + "finishedAt": "2026-09-01T16:44:32.486Z", + "operation": "snapshot", + "wallClockMs": 149.85208399999829, + "daemonDurationMs": 49, + "responseBytes": 4002, + "nodeCount": 6, + "targetGeneration": 682780, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T16:44:33.781Z", + "finishedAt": "2026-09-01T16:44:33.929Z", + "operation": "snapshot", + "wallClockMs": 147.52599999999802, + "daemonDurationMs": 49, + "responseBytes": 4004, + "nodeCount": 6, + "targetGeneration": 682781, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 133.9898749999993, + "median": 153.54237499999, + "p95": 315.26750000000175, + "max": 356.7773750000051, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 43, + "median": 50, + "p95": 116, + "max": 149, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 3998, + "median": 4004, + "p95": 4005, + "max": 4005, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "list", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:44:43.840Z", + "finishedAt": "2026-09-01T16:44:44.150Z", + "operation": "snapshot", + "wallClockMs": 310.43279199999233, + "daemonDurationMs": 210, + "responseBytes": 18019, + "nodeCount": 35, + "targetGeneration": 168389, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:44:45.472Z", + "finishedAt": "2026-09-01T16:44:45.789Z", + "operation": "snapshot", + "wallClockMs": 317.37191699999676, + "daemonDurationMs": 212, + "responseBytes": 18020, + "nodeCount": 35, + "targetGeneration": 168390, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:44:47.093Z", + "finishedAt": "2026-09-01T16:44:47.385Z", + "operation": "snapshot", + "wallClockMs": 292.28341699999874, + "daemonDurationMs": 202, + "responseBytes": 18019, + "nodeCount": 35, + "targetGeneration": 168391, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 4, + "startedAt": "2026-09-01T16:44:48.847Z", + "finishedAt": "2026-09-01T16:44:49.162Z", + "operation": "snapshot", + "wallClockMs": 314.4459160000115, + "daemonDurationMs": 210, + "responseBytes": 18019, + "nodeCount": 35, + "targetGeneration": 168392, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:44:50.438Z", + "finishedAt": "2026-09-01T16:44:50.749Z", + "operation": "snapshot", + "wallClockMs": 311.7997500000056, + "daemonDurationMs": 208, + "responseBytes": 18019, + "nodeCount": 35, + "targetGeneration": 168393, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:44:52.043Z", + "finishedAt": "2026-09-01T16:44:52.360Z", + "operation": "snapshot", + "wallClockMs": 316.71050000000105, + "daemonDurationMs": 211, + "responseBytes": 18018, + "nodeCount": 35, + "targetGeneration": 168394, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:44:53.649Z", + "finishedAt": "2026-09-01T16:44:53.962Z", + "operation": "snapshot", + "wallClockMs": 313.1837919999962, + "daemonDurationMs": 212, + "responseBytes": 18018, + "nodeCount": 35, + "targetGeneration": 168395, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:44:55.241Z", + "finishedAt": "2026-09-01T16:44:55.551Z", + "operation": "snapshot", + "wallClockMs": 310.1861249999929, + "daemonDurationMs": 210, + "responseBytes": 18020, + "nodeCount": 35, + "targetGeneration": 168396, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:44:56.810Z", + "finishedAt": "2026-09-01T16:44:57.121Z", + "operation": "snapshot", + "wallClockMs": 311.3911250000092, + "daemonDurationMs": 207, + "responseBytes": 18021, + "nodeCount": 35, + "targetGeneration": 168397, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:44:58.395Z", + "finishedAt": "2026-09-01T16:44:58.702Z", + "operation": "snapshot", + "wallClockMs": 307.3497079999943, + "daemonDurationMs": 207, + "responseBytes": 18020, + "nodeCount": 35, + "targetGeneration": 168398, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:44:59.994Z", + "finishedAt": "2026-09-01T16:45:00.299Z", + "operation": "snapshot", + "wallClockMs": 304.97799999998824, + "daemonDurationMs": 208, + "responseBytes": 18020, + "nodeCount": 35, + "targetGeneration": 168399, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T16:45:01.597Z", + "finishedAt": "2026-09-01T16:45:01.892Z", + "operation": "snapshot", + "wallClockMs": 295.5289580000099, + "daemonDurationMs": 205, + "responseBytes": 18022, + "nodeCount": 35, + "targetGeneration": 168400, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 13, + "startedAt": "2026-09-01T16:45:03.166Z", + "finishedAt": "2026-09-01T16:45:03.487Z", + "operation": "snapshot", + "wallClockMs": 321.52266599998984, + "daemonDurationMs": 213, + "responseBytes": 18022, + "nodeCount": 35, + "targetGeneration": 168401, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:45:04.743Z", + "finishedAt": "2026-09-01T16:45:05.061Z", + "operation": "snapshot", + "wallClockMs": 318.26316699999734, + "daemonDurationMs": 210, + "responseBytes": 18021, + "nodeCount": 35, + "targetGeneration": 168402, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:45:06.327Z", + "finishedAt": "2026-09-01T16:45:06.644Z", + "operation": "snapshot", + "wallClockMs": 316.92829099998926, + "daemonDurationMs": 211, + "responseBytes": 18020, + "nodeCount": 35, + "targetGeneration": 168403, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:45:07.914Z", + "finishedAt": "2026-09-01T16:45:08.226Z", + "operation": "snapshot", + "wallClockMs": 312.28137500000594, + "daemonDurationMs": 208, + "responseBytes": 18020, + "nodeCount": 35, + "targetGeneration": 168404, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:45:09.555Z", + "finishedAt": "2026-09-01T16:45:09.870Z", + "operation": "snapshot", + "wallClockMs": 315.02654099999927, + "daemonDurationMs": 208, + "responseBytes": 18020, + "nodeCount": 35, + "targetGeneration": 168405, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T16:45:11.171Z", + "finishedAt": "2026-09-01T16:45:11.480Z", + "operation": "snapshot", + "wallClockMs": 308.86304100000416, + "daemonDurationMs": 206, + "responseBytes": 18021, + "nodeCount": 35, + "targetGeneration": 168406, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:45:12.784Z", + "finishedAt": "2026-09-01T16:45:13.098Z", + "operation": "snapshot", + "wallClockMs": 313.7901659999916, + "daemonDurationMs": 212, + "responseBytes": 18021, + "nodeCount": 35, + "targetGeneration": 168407, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T16:45:14.369Z", + "finishedAt": "2026-09-01T16:45:14.688Z", + "operation": "snapshot", + "wallClockMs": 318.3940419999999, + "daemonDurationMs": 209, + "responseBytes": 18022, + "nodeCount": 35, + "targetGeneration": 168408, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 292.28341699999874, + "median": 312.28137500000594, + "p95": 318.3940419999999, + "max": 321.52266599998984, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 202, + "median": 209, + "p95": 212, + "max": 213, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 18018, + "median": 18020, + "p95": 18022, + "max": 18022, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "nested-scroll", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:45:24.222Z", + "finishedAt": "2026-09-01T16:45:24.411Z", + "operation": "snapshot", + "wallClockMs": 189.47562499999185, + "daemonDurationMs": 85, + "responseBytes": 13535, + "nodeCount": 25, + "targetGeneration": 188211, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:45:25.675Z", + "finishedAt": "2026-09-01T16:45:25.849Z", + "operation": "snapshot", + "wallClockMs": 174.1943339999998, + "daemonDurationMs": 79, + "responseBytes": 13536, + "nodeCount": 25, + "targetGeneration": 188212, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:45:27.055Z", + "finishedAt": "2026-09-01T16:45:27.229Z", + "operation": "snapshot", + "wallClockMs": 174.29737500002375, + "daemonDurationMs": 80, + "responseBytes": 13536, + "nodeCount": 25, + "targetGeneration": 188213, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:45:28.572Z", + "finishedAt": "2026-09-01T16:45:28.763Z", + "operation": "snapshot", + "wallClockMs": 190.90912499997648, + "daemonDurationMs": 84, + "responseBytes": 13537, + "nodeCount": 25, + "targetGeneration": 188214, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:45:30.062Z", + "finishedAt": "2026-09-01T16:45:30.251Z", + "operation": "snapshot", + "wallClockMs": 188.85912499998813, + "daemonDurationMs": 84, + "responseBytes": 13536, + "nodeCount": 25, + "targetGeneration": 188215, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:45:31.524Z", + "finishedAt": "2026-09-01T16:45:31.706Z", + "operation": "snapshot", + "wallClockMs": 181.97308399999747, + "daemonDurationMs": 83, + "responseBytes": 13536, + "nodeCount": 25, + "targetGeneration": 188216, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:45:33.006Z", + "finishedAt": "2026-09-01T16:45:33.180Z", + "operation": "snapshot", + "wallClockMs": 173.9595000000263, + "daemonDurationMs": 80, + "responseBytes": 13536, + "nodeCount": 25, + "targetGeneration": 188217, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:45:34.474Z", + "finishedAt": "2026-09-01T16:45:34.665Z", + "operation": "snapshot", + "wallClockMs": 190.53974999999627, + "daemonDurationMs": 84, + "responseBytes": 13537, + "nodeCount": 25, + "targetGeneration": 188218, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:45:35.940Z", + "finishedAt": "2026-09-01T16:45:36.115Z", + "operation": "snapshot", + "wallClockMs": 174.5030830000178, + "daemonDurationMs": 83, + "responseBytes": 13538, + "nodeCount": 25, + "targetGeneration": 188219, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:45:37.406Z", + "finishedAt": "2026-09-01T16:45:37.594Z", + "operation": "snapshot", + "wallClockMs": 188.96408400000655, + "daemonDurationMs": 83, + "responseBytes": 13536, + "nodeCount": 25, + "targetGeneration": 188220, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:45:38.877Z", + "finishedAt": "2026-09-01T16:45:39.067Z", + "operation": "snapshot", + "wallClockMs": 189.91058400002657, + "daemonDurationMs": 83, + "responseBytes": 13538, + "nodeCount": 25, + "targetGeneration": 188221, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T16:45:40.360Z", + "finishedAt": "2026-09-01T16:45:40.547Z", + "operation": "snapshot", + "wallClockMs": 187.17712500001653, + "daemonDurationMs": 81, + "responseBytes": 13539, + "nodeCount": 25, + "targetGeneration": 188222, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:45:41.800Z", + "finishedAt": "2026-09-01T16:45:41.990Z", + "operation": "snapshot", + "wallClockMs": 189.7678329999908, + "daemonDurationMs": 83, + "responseBytes": 13539, + "nodeCount": 25, + "targetGeneration": 188223, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:45:43.255Z", + "finishedAt": "2026-09-01T16:45:43.442Z", + "operation": "snapshot", + "wallClockMs": 187.62812500001746, + "daemonDurationMs": 83, + "responseBytes": 13538, + "nodeCount": 25, + "targetGeneration": 188224, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:45:44.744Z", + "finishedAt": "2026-09-01T16:45:44.934Z", + "operation": "snapshot", + "wallClockMs": 189.81479200001922, + "daemonDurationMs": 85, + "responseBytes": 13538, + "nodeCount": 25, + "targetGeneration": 188225, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:45:46.193Z", + "finishedAt": "2026-09-01T16:45:46.380Z", + "operation": "snapshot", + "wallClockMs": 186.62495800000033, + "daemonDurationMs": 82, + "responseBytes": 13537, + "nodeCount": 25, + "targetGeneration": 188226, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:45:47.661Z", + "finishedAt": "2026-09-01T16:45:47.847Z", + "operation": "snapshot", + "wallClockMs": 186.15079099999275, + "daemonDurationMs": 82, + "responseBytes": 13537, + "nodeCount": 25, + "targetGeneration": 188227, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T16:45:49.110Z", + "finishedAt": "2026-09-01T16:45:49.295Z", + "operation": "snapshot", + "wallClockMs": 185.86479200000758, + "daemonDurationMs": 80, + "responseBytes": 13538, + "nodeCount": 25, + "targetGeneration": 188228, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:45:50.575Z", + "finishedAt": "2026-09-01T16:45:50.765Z", + "operation": "snapshot", + "wallClockMs": 190.3008339999942, + "daemonDurationMs": 83, + "responseBytes": 13536, + "nodeCount": 25, + "targetGeneration": 188229, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T16:45:52.055Z", + "finishedAt": "2026-09-01T16:45:52.242Z", + "operation": "snapshot", + "wallClockMs": 187.03200000000652, + "daemonDurationMs": 83, + "responseBytes": 13537, + "nodeCount": 25, + "targetGeneration": 188230, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 173.9595000000263, + "median": 187.17712500001653, + "p95": 190.53974999999627, + "max": 190.90912499997648, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 79, + "median": 83, + "p95": 85, + "max": 85, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 13535, + "median": 13537, + "p95": 13539, + "max": 13539, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "alert", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:46:05.018Z", + "finishedAt": "2026-09-01T16:46:05.217Z", + "operation": "snapshot", + "wallClockMs": 198.4574169999978, + "daemonDurationMs": 103, + "responseBytes": 15666, + "nodeCount": 30, + "targetGeneration": 470804, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:46:06.432Z", + "finishedAt": "2026-09-01T16:46:06.626Z", + "operation": "snapshot", + "wallClockMs": 193.6617499999993, + "daemonDurationMs": 104, + "responseBytes": 15667, + "nodeCount": 30, + "targetGeneration": 470805, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:46:07.883Z", + "finishedAt": "2026-09-01T16:46:08.083Z", + "operation": "snapshot", + "wallClockMs": 199.24816699998337, + "daemonDurationMs": 107, + "responseBytes": 15667, + "nodeCount": 30, + "targetGeneration": 470806, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:46:09.324Z", + "finishedAt": "2026-09-01T16:46:09.532Z", + "operation": "snapshot", + "wallClockMs": 207.8723750000063, + "daemonDurationMs": 106, + "responseBytes": 15668, + "nodeCount": 30, + "targetGeneration": 470807, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:46:10.804Z", + "finishedAt": "2026-09-01T16:46:11.013Z", + "operation": "snapshot", + "wallClockMs": 209.05829200000153, + "daemonDurationMs": 105, + "responseBytes": 15668, + "nodeCount": 30, + "targetGeneration": 470808, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:46:12.244Z", + "finishedAt": "2026-09-01T16:46:12.448Z", + "operation": "snapshot", + "wallClockMs": 204.34783300000709, + "daemonDurationMs": 100, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470809, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:46:13.673Z", + "finishedAt": "2026-09-01T16:46:13.866Z", + "operation": "snapshot", + "wallClockMs": 192.6979580000043, + "daemonDurationMs": 99, + "responseBytes": 15667, + "nodeCount": 30, + "targetGeneration": 470810, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:46:15.102Z", + "finishedAt": "2026-09-01T16:46:15.312Z", + "operation": "snapshot", + "wallClockMs": 209.56325000000652, + "daemonDurationMs": 107, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470811, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:46:16.727Z", + "finishedAt": "2026-09-01T16:46:16.921Z", + "operation": "snapshot", + "wallClockMs": 194.55929199999082, + "daemonDurationMs": 97, + "responseBytes": 15667, + "nodeCount": 30, + "targetGeneration": 470812, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:46:18.130Z", + "finishedAt": "2026-09-01T16:46:18.322Z", + "operation": "snapshot", + "wallClockMs": 191.3687079999945, + "daemonDurationMs": 99, + "responseBytes": 15666, + "nodeCount": 30, + "targetGeneration": 470813, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:46:19.522Z", + "finishedAt": "2026-09-01T16:46:19.711Z", + "operation": "snapshot", + "wallClockMs": 189.52933299998404, + "daemonDurationMs": 97, + "responseBytes": 15666, + "nodeCount": 30, + "targetGeneration": 470814, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T16:46:20.949Z", + "finishedAt": "2026-09-01T16:46:21.158Z", + "operation": "snapshot", + "wallClockMs": 208.3475000000035, + "daemonDurationMs": 104, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470815, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:46:22.440Z", + "finishedAt": "2026-09-01T16:46:22.648Z", + "operation": "snapshot", + "wallClockMs": 208.11237499999697, + "daemonDurationMs": 106, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470816, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:46:23.936Z", + "finishedAt": "2026-09-01T16:46:24.137Z", + "operation": "snapshot", + "wallClockMs": 200.518167000002, + "daemonDurationMs": 104, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470817, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:46:25.555Z", + "finishedAt": "2026-09-01T16:46:25.762Z", + "operation": "snapshot", + "wallClockMs": 207.60158299998147, + "daemonDurationMs": 105, + "responseBytes": 15668, + "nodeCount": 30, + "targetGeneration": 470818, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:46:27.036Z", + "finishedAt": "2026-09-01T16:46:27.243Z", + "operation": "snapshot", + "wallClockMs": 206.80187500000466, + "daemonDurationMs": 104, + "responseBytes": 15668, + "nodeCount": 30, + "targetGeneration": 470819, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:46:28.553Z", + "finishedAt": "2026-09-01T16:46:28.761Z", + "operation": "snapshot", + "wallClockMs": 208.14949999999953, + "daemonDurationMs": 107, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470820, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T16:46:30.000Z", + "finishedAt": "2026-09-01T16:46:30.397Z", + "operation": "snapshot", + "wallClockMs": 397.0127499999944, + "daemonDurationMs": 116, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470821, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 19, + "startedAt": "2026-09-01T16:46:31.820Z", + "finishedAt": "2026-09-01T16:46:32.215Z", + "operation": "snapshot", + "wallClockMs": 395.544332999998, + "daemonDurationMs": 107, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470822, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 20, + "startedAt": "2026-09-01T16:46:33.493Z", + "finishedAt": "2026-09-01T16:46:33.701Z", + "operation": "snapshot", + "wallClockMs": 208.00987499998882, + "daemonDurationMs": 106, + "responseBytes": 15669, + "nodeCount": 30, + "targetGeneration": 470823, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 189.52933299998404, + "median": 206.80187500000466, + "p95": 395.544332999998, + "max": 397.0127499999944, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 97, + "median": 104, + "p95": 107, + "max": 116, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 15666, + "median": 15668, + "p95": 15669, + "max": 15669, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "system-surface", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:46:43.219Z", + "finishedAt": "2026-09-01T16:46:43.427Z", + "operation": "snapshot", + "wallClockMs": 207.88495800000965, + "daemonDurationMs": 105, + "responseBytes": 10010, + "nodeCount": 18, + "targetGeneration": 306433, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:46:44.677Z", + "finishedAt": "2026-09-01T16:46:44.887Z", + "operation": "snapshot", + "wallClockMs": 210.24150000000373, + "daemonDurationMs": 105, + "responseBytes": 10011, + "nodeCount": 18, + "targetGeneration": 306434, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:46:46.156Z", + "finishedAt": "2026-09-01T16:46:46.371Z", + "operation": "snapshot", + "wallClockMs": 215.12016600000788, + "daemonDurationMs": 105, + "responseBytes": 10011, + "nodeCount": 18, + "targetGeneration": 306435, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:46:47.816Z", + "finishedAt": "2026-09-01T16:46:48.044Z", + "operation": "snapshot", + "wallClockMs": 227.8198749999865, + "daemonDurationMs": 102, + "responseBytes": 10011, + "nodeCount": 18, + "targetGeneration": 306436, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 5, + "startedAt": "2026-09-01T16:46:49.312Z", + "finishedAt": "2026-09-01T16:46:49.522Z", + "operation": "snapshot", + "wallClockMs": 209.72070899998653, + "daemonDurationMs": 105, + "responseBytes": 10011, + "nodeCount": 18, + "targetGeneration": 306437, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:46:50.764Z", + "finishedAt": "2026-09-01T16:46:50.974Z", + "operation": "snapshot", + "wallClockMs": 209.98754200001713, + "daemonDurationMs": 105, + "responseBytes": 10010, + "nodeCount": 18, + "targetGeneration": 306438, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:46:52.269Z", + "finishedAt": "2026-09-01T16:46:52.482Z", + "operation": "snapshot", + "wallClockMs": 213.1536250000063, + "daemonDurationMs": 106, + "responseBytes": 10011, + "nodeCount": 18, + "targetGeneration": 306439, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:46:53.771Z", + "finishedAt": "2026-09-01T16:46:53.979Z", + "operation": "snapshot", + "wallClockMs": 208.0906660000037, + "daemonDurationMs": 106, + "responseBytes": 10013, + "nodeCount": 18, + "targetGeneration": 306440, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:46:55.238Z", + "finishedAt": "2026-09-01T16:46:55.446Z", + "operation": "snapshot", + "wallClockMs": 207.82795800000895, + "daemonDurationMs": 106, + "responseBytes": 10012, + "nodeCount": 18, + "targetGeneration": 306441, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:46:56.728Z", + "finishedAt": "2026-09-01T16:46:56.937Z", + "operation": "snapshot", + "wallClockMs": 209.45108300002175, + "daemonDurationMs": 106, + "responseBytes": 10013, + "nodeCount": 18, + "targetGeneration": 306442, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:46:58.189Z", + "finishedAt": "2026-09-01T16:46:58.401Z", + "operation": "snapshot", + "wallClockMs": 212.21958299999824, + "daemonDurationMs": 105, + "responseBytes": 10012, + "nodeCount": 18, + "targetGeneration": 306443, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T16:46:59.691Z", + "finishedAt": "2026-09-01T16:46:59.899Z", + "operation": "snapshot", + "wallClockMs": 207.8581669999985, + "daemonDurationMs": 103, + "responseBytes": 10011, + "nodeCount": 18, + "targetGeneration": 306444, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:47:01.133Z", + "finishedAt": "2026-09-01T16:47:01.349Z", + "operation": "snapshot", + "wallClockMs": 216.52195799999754, + "daemonDurationMs": 109, + "responseBytes": 10013, + "nodeCount": 18, + "targetGeneration": 306445, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:47:02.649Z", + "finishedAt": "2026-09-01T16:47:02.860Z", + "operation": "snapshot", + "wallClockMs": 211.11604199997964, + "daemonDurationMs": 106, + "responseBytes": 10013, + "nodeCount": 18, + "targetGeneration": 306446, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:47:04.146Z", + "finishedAt": "2026-09-01T16:47:04.352Z", + "operation": "snapshot", + "wallClockMs": 205.1595420000085, + "daemonDurationMs": 106, + "responseBytes": 10012, + "nodeCount": 18, + "targetGeneration": 306447, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:47:05.620Z", + "finishedAt": "2026-09-01T16:47:05.810Z", + "operation": "snapshot", + "wallClockMs": 189.8878749999858, + "daemonDurationMs": 101, + "responseBytes": 10013, + "nodeCount": 18, + "targetGeneration": 306448, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 17, + "startedAt": "2026-09-01T16:47:07.055Z", + "finishedAt": "2026-09-01T16:47:07.450Z", + "operation": "snapshot", + "wallClockMs": 395.1750409999804, + "daemonDurationMs": 108, + "responseBytes": 10012, + "nodeCount": 18, + "targetGeneration": 306449, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 18, + "startedAt": "2026-09-01T16:47:08.741Z", + "finishedAt": "2026-09-01T16:47:08.957Z", + "operation": "snapshot", + "wallClockMs": 215.53125, + "daemonDurationMs": 108, + "responseBytes": 10013, + "nodeCount": 18, + "targetGeneration": 306450, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:47:10.314Z", + "finishedAt": "2026-09-01T16:47:10.505Z", + "operation": "snapshot", + "wallClockMs": 190.97750000000815, + "daemonDurationMs": 100, + "responseBytes": 10012, + "nodeCount": 18, + "targetGeneration": 306451, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 20, + "startedAt": "2026-09-01T16:47:11.788Z", + "finishedAt": "2026-09-01T16:47:11.996Z", + "operation": "snapshot", + "wallClockMs": 207.5954170000041, + "daemonDurationMs": 105, + "responseBytes": 10010, + "nodeCount": 18, + "targetGeneration": 306452, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 189.8878749999858, + "median": 209.72070899998653, + "p95": 227.8198749999865, + "max": 395.1750409999804, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 100, + "median": 105, + "p95": 108, + "max": 109, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 10010, + "median": 10012, + "p95": 10013, + "max": 10013, + "outlierCount": 4, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "warm", + "screen": "xctest-stress", + "sampleMinimum": 20, + "operation": "snapshot", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:47:21.487Z", + "finishedAt": "2026-09-01T16:47:21.695Z", + "operation": "snapshot", + "wallClockMs": 207.9488330000022, + "daemonDurationMs": 107, + "responseBytes": 14941, + "nodeCount": 29, + "targetGeneration": 603212, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:47:22.974Z", + "finishedAt": "2026-09-01T16:47:23.181Z", + "operation": "snapshot", + "wallClockMs": 206.53533300000709, + "daemonDurationMs": 106, + "responseBytes": 14942, + "nodeCount": 29, + "targetGeneration": 603213, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:47:24.426Z", + "finishedAt": "2026-09-01T16:47:24.636Z", + "operation": "snapshot", + "wallClockMs": 209.4393750000163, + "daemonDurationMs": 105, + "responseBytes": 14942, + "nodeCount": 29, + "targetGeneration": 603214, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:47:25.890Z", + "finishedAt": "2026-09-01T16:47:26.103Z", + "operation": "snapshot", + "wallClockMs": 212.64225000000442, + "daemonDurationMs": 108, + "responseBytes": 14942, + "nodeCount": 29, + "targetGeneration": 603215, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:47:27.418Z", + "finishedAt": "2026-09-01T16:47:27.630Z", + "operation": "snapshot", + "wallClockMs": 211.9524579999852, + "daemonDurationMs": 105, + "responseBytes": 14941, + "nodeCount": 29, + "targetGeneration": 603216, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:47:28.889Z", + "finishedAt": "2026-09-01T16:47:29.095Z", + "operation": "snapshot", + "wallClockMs": 206.4917500000156, + "daemonDurationMs": 105, + "responseBytes": 14942, + "nodeCount": 29, + "targetGeneration": 603217, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:47:30.391Z", + "finishedAt": "2026-09-01T16:47:30.591Z", + "operation": "snapshot", + "wallClockMs": 200.45254100000602, + "daemonDurationMs": 106, + "responseBytes": 14942, + "nodeCount": 29, + "targetGeneration": 603218, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:47:31.831Z", + "finishedAt": "2026-09-01T16:47:32.040Z", + "operation": "snapshot", + "wallClockMs": 208.9256249999744, + "daemonDurationMs": 106, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603219, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:47:33.308Z", + "finishedAt": "2026-09-01T16:47:33.519Z", + "operation": "snapshot", + "wallClockMs": 211.29370799998287, + "daemonDurationMs": 106, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603220, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:47:34.804Z", + "finishedAt": "2026-09-01T16:47:35.019Z", + "operation": "snapshot", + "wallClockMs": 214.73845800000709, + "daemonDurationMs": 106, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603221, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:47:36.268Z", + "finishedAt": "2026-09-01T16:47:36.477Z", + "operation": "snapshot", + "wallClockMs": 208.29062499996508, + "daemonDurationMs": 100, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603222, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T16:47:37.728Z", + "finishedAt": "2026-09-01T16:47:37.934Z", + "operation": "snapshot", + "wallClockMs": 205.4114169999957, + "daemonDurationMs": 104, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603223, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:47:39.186Z", + "finishedAt": "2026-09-01T16:47:39.399Z", + "operation": "snapshot", + "wallClockMs": 212.57654099998763, + "daemonDurationMs": 106, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603224, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:47:40.701Z", + "finishedAt": "2026-09-01T16:47:40.914Z", + "operation": "snapshot", + "wallClockMs": 213.3059169999906, + "daemonDurationMs": 105, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603225, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:47:42.181Z", + "finishedAt": "2026-09-01T16:47:42.389Z", + "operation": "snapshot", + "wallClockMs": 208.27820800000336, + "daemonDurationMs": 102, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603226, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:47:43.660Z", + "finishedAt": "2026-09-01T16:47:43.868Z", + "operation": "snapshot", + "wallClockMs": 207.50391600001603, + "daemonDurationMs": 103, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603227, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:47:45.136Z", + "finishedAt": "2026-09-01T16:47:45.341Z", + "operation": "snapshot", + "wallClockMs": 205.36650000000373, + "daemonDurationMs": 98, + "responseBytes": 14940, + "nodeCount": 29, + "targetGeneration": 603228, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T16:47:46.628Z", + "finishedAt": "2026-09-01T16:47:46.840Z", + "operation": "snapshot", + "wallClockMs": 211.21154200000456, + "daemonDurationMs": 107, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603229, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:47:48.136Z", + "finishedAt": "2026-09-01T16:47:48.344Z", + "operation": "snapshot", + "wallClockMs": 208.20449999999255, + "daemonDurationMs": 105, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603230, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T16:47:49.603Z", + "finishedAt": "2026-09-01T16:47:49.812Z", + "operation": "snapshot", + "wallClockMs": 208.4959160000435, + "daemonDurationMs": 106, + "responseBytes": 14944, + "nodeCount": 29, + "targetGeneration": 603231, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 200.45254100000602, + "median": 208.29062499996508, + "p95": 213.3059169999906, + "max": 214.73845800000709, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 98, + "median": 105, + "p95": 107, + "max": 108, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 14940, + "median": 14944, + "p95": 14944, + "max": 14944, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "relaunch", + "screen": "quiet", + "sampleMinimum": 20, + "operation": "relaunch-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:47:59.134Z", + "finishedAt": "2026-09-01T16:48:02.749Z", + "operation": "relaunch-foreground", + "wallClockMs": 3614.726250000007, + "daemonDurationMs": 625, + "responseBytes": 4874, + "nodeCount": 5, + "targetGeneration": 641711, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:48:04.511Z", + "finishedAt": "2026-09-01T16:48:08.116Z", + "operation": "relaunch-foreground", + "wallClockMs": 3604.8522499999963, + "daemonDurationMs": 629, + "responseBytes": 5059, + "nodeCount": 5, + "targetGeneration": 641713, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:48:09.869Z", + "finishedAt": "2026-09-01T16:48:13.446Z", + "operation": "relaunch-foreground", + "wallClockMs": 3577.466375000018, + "daemonDurationMs": 619, + "responseBytes": 5059, + "nodeCount": 5, + "targetGeneration": 641715, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:48:15.110Z", + "finishedAt": "2026-09-01T16:48:18.580Z", + "operation": "relaunch-foreground", + "wallClockMs": 3470.551416000002, + "daemonDurationMs": 619, + "responseBytes": 5059, + "nodeCount": 5, + "targetGeneration": 641717, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 5, + "startedAt": "2026-09-01T16:48:20.219Z", + "finishedAt": "2026-09-01T16:48:24.656Z", + "operation": "relaunch-foreground", + "wallClockMs": 4437.265791000042, + "daemonDurationMs": 723, + "responseBytes": 3467, + "nodeCount": 1, + "targetGeneration": 641719, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 6, + "startedAt": "2026-09-01T16:48:26.460Z", + "finishedAt": "2026-09-01T16:48:30.151Z", + "operation": "relaunch-foreground", + "wallClockMs": 3690.869249999989, + "daemonDurationMs": 644, + "responseBytes": 5062, + "nodeCount": 5, + "targetGeneration": 641721, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:48:31.951Z", + "finishedAt": "2026-09-01T16:48:36.202Z", + "operation": "relaunch-foreground", + "wallClockMs": 4251.2983330000425, + "daemonDurationMs": 625, + "responseBytes": 3467, + "nodeCount": 1, + "targetGeneration": 641723, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 8, + "startedAt": "2026-09-01T16:48:37.939Z", + "finishedAt": "2026-09-01T16:48:41.609Z", + "operation": "relaunch-foreground", + "wallClockMs": 3670.1114159999997, + "daemonDurationMs": 633, + "responseBytes": 5062, + "nodeCount": 5, + "targetGeneration": 641725, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:48:43.405Z", + "finishedAt": "2026-09-01T16:48:47.040Z", + "operation": "relaunch-foreground", + "wallClockMs": 3635.280708999955, + "daemonDurationMs": 628, + "responseBytes": 5062, + "nodeCount": 5, + "targetGeneration": 641727, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:48:48.830Z", + "finishedAt": "2026-09-01T16:48:52.502Z", + "operation": "relaunch-foreground", + "wallClockMs": 3671.8927500000573, + "daemonDurationMs": 632, + "responseBytes": 5062, + "nodeCount": 5, + "targetGeneration": 641729, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:48:54.260Z", + "finishedAt": "2026-09-01T16:48:58.063Z", + "operation": "relaunch-foreground", + "wallClockMs": 3802.5566659999895, + "daemonDurationMs": 751, + "responseBytes": 5063, + "nodeCount": 5, + "targetGeneration": 641731, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 12, + "startedAt": "2026-09-01T16:48:59.849Z", + "finishedAt": "2026-09-01T16:49:03.497Z", + "operation": "relaunch-foreground", + "wallClockMs": 3648.512041000009, + "daemonDurationMs": 627, + "responseBytes": 5063, + "nodeCount": 5, + "targetGeneration": 641733, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:49:05.284Z", + "finishedAt": "2026-09-01T16:49:08.988Z", + "operation": "relaunch-foreground", + "wallClockMs": 3703.3766659999965, + "daemonDurationMs": 625, + "responseBytes": 5063, + "nodeCount": 5, + "targetGeneration": 641735, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:49:10.759Z", + "finishedAt": "2026-09-01T16:49:14.412Z", + "operation": "relaunch-foreground", + "wallClockMs": 3653.605958, + "daemonDurationMs": 623, + "responseBytes": 5062, + "nodeCount": 5, + "targetGeneration": 641737, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:49:16.181Z", + "finishedAt": "2026-09-01T16:49:19.815Z", + "operation": "relaunch-foreground", + "wallClockMs": 3633.398166000028, + "daemonDurationMs": 625, + "responseBytes": 5062, + "nodeCount": 5, + "targetGeneration": 641739, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:49:21.537Z", + "finishedAt": "2026-09-01T16:49:25.181Z", + "operation": "relaunch-foreground", + "wallClockMs": 3643.5260409999755, + "daemonDurationMs": 631, + "responseBytes": 5063, + "nodeCount": 5, + "targetGeneration": 641741, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:49:26.974Z", + "finishedAt": "2026-09-01T16:49:31.172Z", + "operation": "relaunch-foreground", + "wallClockMs": 4197.549082999991, + "daemonDurationMs": 642, + "responseBytes": 3467, + "nodeCount": 1, + "targetGeneration": 641743, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 18, + "startedAt": "2026-09-01T16:49:32.907Z", + "finishedAt": "2026-09-01T16:49:36.552Z", + "operation": "relaunch-foreground", + "wallClockMs": 3644.8109169999952, + "daemonDurationMs": 604, + "responseBytes": 5063, + "nodeCount": 5, + "targetGeneration": 641745, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:49:38.343Z", + "finishedAt": "2026-09-01T16:49:41.979Z", + "operation": "relaunch-foreground", + "wallClockMs": 3635.5981249999604, + "daemonDurationMs": 628, + "responseBytes": 5062, + "nodeCount": 5, + "targetGeneration": 641747, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T16:49:43.763Z", + "finishedAt": "2026-09-01T16:49:47.406Z", + "operation": "relaunch-foreground", + "wallClockMs": 3642.513417000009, + "daemonDurationMs": 625, + "responseBytes": 5061, + "nodeCount": 5, + "targetGeneration": 641749, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 3470.551416000002, + "median": 3644.8109169999952, + "p95": 4251.2983330000425, + "max": 4437.265791000042, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 604, + "median": 627, + "p95": 723, + "max": 751, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 3467, + "median": 5062, + "p95": 5063, + "max": 5063, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "relaunch", + "screen": "list", + "sampleMinimum": 20, + "operation": "relaunch-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:49:57.819Z", + "finishedAt": "2026-09-01T16:50:02.179Z", + "operation": "relaunch-foreground", + "wallClockMs": 4360.55237499997, + "daemonDurationMs": 629, + "responseBytes": 16235, + "nodeCount": 32, + "targetGeneration": 121333, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:50:03.983Z", + "finishedAt": "2026-09-01T16:50:08.484Z", + "operation": "relaunch-foreground", + "wallClockMs": 4500.915084000037, + "daemonDurationMs": 638, + "responseBytes": 16419, + "nodeCount": 32, + "targetGeneration": 121335, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:50:10.286Z", + "finishedAt": "2026-09-01T16:50:14.665Z", + "operation": "relaunch-foreground", + "wallClockMs": 4379.166125000047, + "daemonDurationMs": 629, + "responseBytes": 16419, + "nodeCount": 32, + "targetGeneration": 121337, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:50:16.467Z", + "finishedAt": "2026-09-01T16:50:20.832Z", + "operation": "relaunch-foreground", + "wallClockMs": 4365.218500000017, + "daemonDurationMs": 623, + "responseBytes": 16419, + "nodeCount": 32, + "targetGeneration": 121339, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:50:22.642Z", + "finishedAt": "2026-09-01T16:50:27.843Z", + "operation": "relaunch-foreground", + "wallClockMs": 5201.354875000019, + "daemonDurationMs": 629, + "responseBytes": 3465, + "nodeCount": 1, + "targetGeneration": 121341, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 6, + "startedAt": "2026-09-01T16:50:29.587Z", + "finishedAt": "2026-09-01T16:50:34.077Z", + "operation": "relaunch-foreground", + "wallClockMs": 4490.433790999989, + "daemonDurationMs": 638, + "responseBytes": 16422, + "nodeCount": 32, + "targetGeneration": 121343, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:50:35.830Z", + "finishedAt": "2026-09-01T16:50:40.882Z", + "operation": "relaunch-foreground", + "wallClockMs": 5051.223624999984, + "daemonDurationMs": 639, + "responseBytes": 3463, + "nodeCount": 1, + "targetGeneration": 121345, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 8, + "startedAt": "2026-09-01T16:50:42.788Z", + "finishedAt": "2026-09-01T16:50:47.165Z", + "operation": "relaunch-foreground", + "wallClockMs": 4377.938833000022, + "daemonDurationMs": 632, + "responseBytes": 16962, + "nodeCount": 33, + "targetGeneration": 121347, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:50:48.901Z", + "finishedAt": "2026-09-01T16:50:53.219Z", + "operation": "relaunch-foreground", + "wallClockMs": 4317.787167000002, + "daemonDurationMs": 615, + "responseBytes": 16421, + "nodeCount": 32, + "targetGeneration": 121349, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:50:55.047Z", + "finishedAt": "2026-09-01T16:50:59.394Z", + "operation": "relaunch-foreground", + "wallClockMs": 4346.730625000026, + "daemonDurationMs": 628, + "responseBytes": 16422, + "nodeCount": 32, + "targetGeneration": 121351, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:51:01.127Z", + "finishedAt": "2026-09-01T16:51:05.485Z", + "operation": "relaunch-foreground", + "wallClockMs": 4357.641041999974, + "daemonDurationMs": 629, + "responseBytes": 16962, + "nodeCount": 33, + "targetGeneration": 121353, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T16:51:07.240Z", + "finishedAt": "2026-09-01T16:51:11.588Z", + "operation": "relaunch-foreground", + "wallClockMs": 4347.3544160000165, + "daemonDurationMs": 622, + "responseBytes": 16422, + "nodeCount": 32, + "targetGeneration": 121355, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:51:13.323Z", + "finishedAt": "2026-09-01T16:51:17.634Z", + "operation": "relaunch-foreground", + "wallClockMs": 4310.559125000029, + "daemonDurationMs": 624, + "responseBytes": 16423, + "nodeCount": 32, + "targetGeneration": 121357, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:51:19.365Z", + "finishedAt": "2026-09-01T16:51:23.691Z", + "operation": "relaunch-foreground", + "wallClockMs": 4325.83041699999, + "daemonDurationMs": 621, + "responseBytes": 16421, + "nodeCount": 32, + "targetGeneration": 121359, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:51:25.426Z", + "finishedAt": "2026-09-01T16:51:29.825Z", + "operation": "relaunch-foreground", + "wallClockMs": 4398.973209000018, + "daemonDurationMs": 611, + "responseBytes": 16423, + "nodeCount": 32, + "targetGeneration": 121361, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:51:31.583Z", + "finishedAt": "2026-09-01T16:51:36.021Z", + "operation": "relaunch-foreground", + "wallClockMs": 4438.05899999995, + "daemonDurationMs": 625, + "responseBytes": 16422, + "nodeCount": 32, + "targetGeneration": 121363, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:51:37.762Z", + "finishedAt": "2026-09-01T16:51:42.232Z", + "operation": "relaunch-foreground", + "wallClockMs": 4470.0595840000315, + "daemonDurationMs": 623, + "responseBytes": 16422, + "nodeCount": 32, + "targetGeneration": 121365, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T16:51:44.005Z", + "finishedAt": "2026-09-01T16:51:48.442Z", + "operation": "relaunch-foreground", + "wallClockMs": 4436.934583000024, + "daemonDurationMs": 640, + "responseBytes": 16423, + "nodeCount": 32, + "targetGeneration": 121367, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:51:50.157Z", + "finishedAt": "2026-09-01T16:51:54.500Z", + "operation": "relaunch-foreground", + "wallClockMs": 4342.886915999989, + "daemonDurationMs": 633, + "responseBytes": 16423, + "nodeCount": 32, + "targetGeneration": 121369, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T16:51:56.250Z", + "finishedAt": "2026-09-01T16:52:00.662Z", + "operation": "relaunch-foreground", + "wallClockMs": 4411.571040999959, + "daemonDurationMs": 608, + "responseBytes": 16422, + "nodeCount": 32, + "targetGeneration": 121371, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 4310.559125000029, + "median": 4377.938833000022, + "p95": 5051.223624999984, + "max": 5201.354875000019, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 608, + "median": 628, + "p95": 639, + "max": 640, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 3463, + "median": 16422, + "p95": 16962, + "max": 16962, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "relaunch", + "screen": "nested-scroll", + "sampleMinimum": 20, + "operation": "relaunch-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:52:10.743Z", + "finishedAt": "2026-09-01T16:52:15.027Z", + "operation": "relaunch-foreground", + "wallClockMs": 4283.656958000036, + "daemonDurationMs": 621, + "responseBytes": 10375, + "nodeCount": 18, + "targetGeneration": 963644, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:52:16.720Z", + "finishedAt": "2026-09-01T16:52:21.026Z", + "operation": "relaunch-foreground", + "wallClockMs": 4305.960667000036, + "daemonDurationMs": 615, + "responseBytes": 10558, + "nodeCount": 18, + "targetGeneration": 963646, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:52:22.733Z", + "finishedAt": "2026-09-01T16:52:27.038Z", + "operation": "relaunch-foreground", + "wallClockMs": 4305.392666999949, + "daemonDurationMs": 626, + "responseBytes": 10559, + "nodeCount": 18, + "targetGeneration": 963648, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:52:28.770Z", + "finishedAt": "2026-09-01T16:52:33.097Z", + "operation": "relaunch-foreground", + "wallClockMs": 4326.759250000003, + "daemonDurationMs": 628, + "responseBytes": 10560, + "nodeCount": 18, + "targetGeneration": 963650, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:52:34.795Z", + "finishedAt": "2026-09-01T16:52:39.135Z", + "operation": "relaunch-foreground", + "wallClockMs": 4340.049624999985, + "daemonDurationMs": 632, + "responseBytes": 10562, + "nodeCount": 18, + "targetGeneration": 963652, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:52:40.831Z", + "finishedAt": "2026-09-01T16:52:45.132Z", + "operation": "relaunch-foreground", + "wallClockMs": 4301.041874999995, + "daemonDurationMs": 632, + "responseBytes": 10562, + "nodeCount": 18, + "targetGeneration": 963654, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:52:46.824Z", + "finishedAt": "2026-09-01T16:52:51.229Z", + "operation": "relaunch-foreground", + "wallClockMs": 4405.029708000016, + "daemonDurationMs": 629, + "responseBytes": 10563, + "nodeCount": 18, + "targetGeneration": 963656, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 8, + "startedAt": "2026-09-01T16:52:52.945Z", + "finishedAt": "2026-09-01T16:52:57.262Z", + "operation": "relaunch-foreground", + "wallClockMs": 4316.823665999924, + "daemonDurationMs": 633, + "responseBytes": 10563, + "nodeCount": 18, + "targetGeneration": 963658, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:52:58.957Z", + "finishedAt": "2026-09-01T16:53:03.282Z", + "operation": "relaunch-foreground", + "wallClockMs": 4324.82108299993, + "daemonDurationMs": 632, + "responseBytes": 10563, + "nodeCount": 18, + "targetGeneration": 963660, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:53:04.966Z", + "finishedAt": "2026-09-01T16:53:10.030Z", + "operation": "relaunch-foreground", + "wallClockMs": 5064.201125000021, + "daemonDurationMs": 625, + "responseBytes": 3510, + "nodeCount": 1, + "targetGeneration": 963662, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 11, + "startedAt": "2026-09-01T16:53:11.764Z", + "finishedAt": "2026-09-01T16:53:16.048Z", + "operation": "relaunch-foreground", + "wallClockMs": 4283.705542000011, + "daemonDurationMs": 644, + "responseBytes": 10562, + "nodeCount": 18, + "targetGeneration": 963664, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T16:53:17.731Z", + "finishedAt": "2026-09-01T16:53:22.025Z", + "operation": "relaunch-foreground", + "wallClockMs": 4293.527333000093, + "daemonDurationMs": 618, + "responseBytes": 10562, + "nodeCount": 18, + "targetGeneration": 963666, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:53:23.712Z", + "finishedAt": "2026-09-01T16:53:28.025Z", + "operation": "relaunch-foreground", + "wallClockMs": 4313.179250000045, + "daemonDurationMs": 626, + "responseBytes": 10564, + "nodeCount": 18, + "targetGeneration": 963668, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:53:29.719Z", + "finishedAt": "2026-09-01T16:53:34.050Z", + "operation": "relaunch-foreground", + "wallClockMs": 4330.523791000014, + "daemonDurationMs": 632, + "responseBytes": 10563, + "nodeCount": 18, + "targetGeneration": 963670, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:53:35.785Z", + "finishedAt": "2026-09-01T16:53:40.131Z", + "operation": "relaunch-foreground", + "wallClockMs": 4346.830958999926, + "daemonDurationMs": 623, + "responseBytes": 10562, + "nodeCount": 18, + "targetGeneration": 963672, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:53:41.830Z", + "finishedAt": "2026-09-01T16:53:46.108Z", + "operation": "relaunch-foreground", + "wallClockMs": 4277.895207999973, + "daemonDurationMs": 626, + "responseBytes": 10562, + "nodeCount": 18, + "targetGeneration": 963674, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:53:47.798Z", + "finishedAt": "2026-09-01T16:53:52.150Z", + "operation": "relaunch-foreground", + "wallClockMs": 4351.8157080000965, + "daemonDurationMs": 623, + "responseBytes": 10563, + "nodeCount": 18, + "targetGeneration": 963676, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T16:53:53.860Z", + "finishedAt": "2026-09-01T16:53:58.216Z", + "operation": "relaunch-foreground", + "wallClockMs": 4355.853917, + "daemonDurationMs": 631, + "responseBytes": 10564, + "nodeCount": 18, + "targetGeneration": 963678, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:53:59.956Z", + "finishedAt": "2026-09-01T16:54:04.269Z", + "operation": "relaunch-foreground", + "wallClockMs": 4313.459583999938, + "daemonDurationMs": 640, + "responseBytes": 10562, + "nodeCount": 18, + "targetGeneration": 963680, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T16:54:05.979Z", + "finishedAt": "2026-09-01T16:54:10.288Z", + "operation": "relaunch-foreground", + "wallClockMs": 4309.355958000058, + "daemonDurationMs": 620, + "responseBytes": 10564, + "nodeCount": 18, + "targetGeneration": 963682, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 4277.895207999973, + "median": 4313.459583999938, + "p95": 4405.029708000016, + "max": 5064.201125000021, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 615, + "median": 626, + "p95": 640, + "max": 644, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 3510, + "median": 10562, + "p95": 10564, + "max": 10564, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "relaunch", + "screen": "alert", + "sampleMinimum": 20, + "operation": "relaunch-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:54:23.334Z", + "finishedAt": "2026-09-01T16:54:27.684Z", + "operation": "relaunch-foreground", + "wallClockMs": 4349.96100000001, + "daemonDurationMs": 629, + "responseBytes": 14047, + "nodeCount": 27, + "targetGeneration": 335536, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:54:34.380Z", + "finishedAt": "2026-09-01T16:54:38.724Z", + "operation": "relaunch-foreground", + "wallClockMs": 4344.461207999964, + "daemonDurationMs": 621, + "responseBytes": 14235, + "nodeCount": 27, + "targetGeneration": 335541, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:54:45.598Z", + "finishedAt": "2026-09-01T16:54:49.948Z", + "operation": "relaunch-foreground", + "wallClockMs": 4349.629665999906, + "daemonDurationMs": 624, + "responseBytes": 14234, + "nodeCount": 27, + "targetGeneration": 335546, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:54:56.657Z", + "finishedAt": "2026-09-01T16:55:01.090Z", + "operation": "relaunch-foreground", + "wallClockMs": 4432.34695799998, + "daemonDurationMs": 633, + "responseBytes": 14234, + "nodeCount": 27, + "targetGeneration": 335551, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:55:07.724Z", + "finishedAt": "2026-09-01T16:55:11.884Z", + "operation": "relaunch-foreground", + "wallClockMs": 4160.368708000053, + "daemonDurationMs": 630, + "responseBytes": 3473, + "nodeCount": 1, + "targetGeneration": 335556, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 6, + "startedAt": "2026-09-01T16:55:18.603Z", + "finishedAt": "2026-09-01T16:55:23.566Z", + "operation": "relaunch-foreground", + "wallClockMs": 4963.159040999948, + "daemonDurationMs": 632, + "responseBytes": 3473, + "nodeCount": 1, + "targetGeneration": 335561, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 7, + "startedAt": "2026-09-01T16:55:30.286Z", + "finishedAt": "2026-09-01T16:55:35.433Z", + "operation": "relaunch-foreground", + "wallClockMs": 5146.910957999993, + "daemonDurationMs": 622, + "responseBytes": 3472, + "nodeCount": 1, + "targetGeneration": 335566, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 8, + "startedAt": "2026-09-01T16:55:42.200Z", + "finishedAt": "2026-09-01T16:55:46.564Z", + "operation": "relaunch-foreground", + "wallClockMs": 4364.3134579999605, + "daemonDurationMs": 636, + "responseBytes": 14234, + "nodeCount": 27, + "targetGeneration": 335571, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:55:53.302Z", + "finishedAt": "2026-09-01T16:55:57.636Z", + "operation": "relaunch-foreground", + "wallClockMs": 4334.427040999988, + "daemonDurationMs": 612, + "responseBytes": 14233, + "nodeCount": 27, + "targetGeneration": 335576, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:56:04.414Z", + "finishedAt": "2026-09-01T16:56:08.784Z", + "operation": "relaunch-foreground", + "wallClockMs": 4369.510249999934, + "daemonDurationMs": 625, + "responseBytes": 14232, + "nodeCount": 27, + "targetGeneration": 335581, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:56:15.514Z", + "finishedAt": "2026-09-01T16:56:20.433Z", + "operation": "relaunch-foreground", + "wallClockMs": 4919.00537499995, + "daemonDurationMs": 629, + "responseBytes": 3471, + "nodeCount": 1, + "targetGeneration": 335586, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 12, + "startedAt": "2026-09-01T16:56:27.172Z", + "finishedAt": "2026-09-01T16:56:31.588Z", + "operation": "relaunch-foreground", + "wallClockMs": 4416.102541, + "daemonDurationMs": 620, + "responseBytes": 14234, + "nodeCount": 27, + "targetGeneration": 335591, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:56:38.342Z", + "finishedAt": "2026-09-01T16:56:42.719Z", + "operation": "relaunch-foreground", + "wallClockMs": 4376.866416999954, + "daemonDurationMs": 629, + "responseBytes": 14233, + "nodeCount": 27, + "targetGeneration": 335596, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:56:49.468Z", + "finishedAt": "2026-09-01T16:56:53.851Z", + "operation": "relaunch-foreground", + "wallClockMs": 4382.534375000047, + "daemonDurationMs": 616, + "responseBytes": 14233, + "nodeCount": 27, + "targetGeneration": 335601, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:57:00.640Z", + "finishedAt": "2026-09-01T16:57:04.989Z", + "operation": "relaunch-foreground", + "wallClockMs": 4349.424457999994, + "daemonDurationMs": 629, + "responseBytes": 14233, + "nodeCount": 27, + "targetGeneration": 335606, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T16:57:11.678Z", + "finishedAt": "2026-09-01T16:57:16.018Z", + "operation": "relaunch-foreground", + "wallClockMs": 4340.003917000024, + "daemonDurationMs": 620, + "responseBytes": 14235, + "nodeCount": 27, + "targetGeneration": 335611, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T16:57:22.764Z", + "finishedAt": "2026-09-01T16:57:27.153Z", + "operation": "relaunch-foreground", + "wallClockMs": 4389.687292000046, + "daemonDurationMs": 625, + "responseBytes": 14237, + "nodeCount": 27, + "targetGeneration": 335616, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T16:57:33.887Z", + "finishedAt": "2026-09-01T16:57:38.264Z", + "operation": "relaunch-foreground", + "wallClockMs": 4376.970874999999, + "daemonDurationMs": 606, + "responseBytes": 14236, + "nodeCount": 27, + "targetGeneration": 335621, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T16:57:44.916Z", + "finishedAt": "2026-09-01T16:57:49.264Z", + "operation": "relaunch-foreground", + "wallClockMs": 4348.024166000076, + "daemonDurationMs": 620, + "responseBytes": 14237, + "nodeCount": 27, + "targetGeneration": 335626, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T16:57:55.937Z", + "finishedAt": "2026-09-01T16:58:01.003Z", + "operation": "relaunch-foreground", + "wallClockMs": 5065.905708000064, + "daemonDurationMs": 621, + "responseBytes": 3475, + "nodeCount": 1, + "targetGeneration": 335631, + "firstTree": "readable", + "ok": true, + "outlier": true + } + ], + "wallClockMs": { + "n": 20, + "min": 4160.368708000053, + "median": 4369.510249999934, + "p95": 5065.905708000064, + "max": 5146.910957999993, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 606, + "median": 624, + "p95": 633, + "max": 636, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 3471, + "median": 14233, + "p95": 14237, + "max": 14237, + "outlierCount": 5, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "relaunch", + "screen": "system-surface", + "sampleMinimum": 20, + "operation": "relaunch-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T16:58:18.843Z", + "finishedAt": "2026-09-01T16:58:23.758Z", + "operation": "relaunch-foreground", + "wallClockMs": 4915.003707999946, + "daemonDurationMs": 578, + "responseBytes": 11019, + "nodeCount": 20, + "targetGeneration": 258409, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 2, + "startedAt": "2026-09-01T16:58:25.580Z", + "finishedAt": "2026-09-01T16:58:30.675Z", + "operation": "relaunch-foreground", + "wallClockMs": 5094.90395800001, + "daemonDurationMs": 545, + "responseBytes": 11204, + "nodeCount": 20, + "targetGeneration": 258411, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T16:58:32.456Z", + "finishedAt": "2026-09-01T16:58:37.295Z", + "operation": "relaunch-foreground", + "wallClockMs": 4838.924457999994, + "daemonDurationMs": 546, + "responseBytes": 11204, + "nodeCount": 20, + "targetGeneration": 258413, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T16:58:39.100Z", + "finishedAt": "2026-09-01T16:58:44.215Z", + "operation": "relaunch-foreground", + "wallClockMs": 5115.3286249999655, + "daemonDurationMs": 540, + "responseBytes": 11204, + "nodeCount": 20, + "targetGeneration": 258415, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T16:58:45.983Z", + "finishedAt": "2026-09-01T16:58:50.865Z", + "operation": "relaunch-foreground", + "wallClockMs": 4881.691499999957, + "daemonDurationMs": 542, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258417, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T16:58:53.208Z", + "finishedAt": "2026-09-01T16:58:58.083Z", + "operation": "relaunch-foreground", + "wallClockMs": 4875.4217499999795, + "daemonDurationMs": 535, + "responseBytes": 11206, + "nodeCount": 20, + "targetGeneration": 258419, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T16:58:59.911Z", + "finishedAt": "2026-09-01T16:59:04.836Z", + "operation": "relaunch-foreground", + "wallClockMs": 4924.646582999965, + "daemonDurationMs": 538, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258421, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T16:59:06.562Z", + "finishedAt": "2026-09-01T16:59:11.449Z", + "operation": "relaunch-foreground", + "wallClockMs": 4887.00083299994, + "daemonDurationMs": 536, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258423, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T16:59:13.222Z", + "finishedAt": "2026-09-01T16:59:18.150Z", + "operation": "relaunch-foreground", + "wallClockMs": 4927.389457999961, + "daemonDurationMs": 539, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258425, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T16:59:19.936Z", + "finishedAt": "2026-09-01T16:59:24.946Z", + "operation": "relaunch-foreground", + "wallClockMs": 5010.439874999924, + "daemonDurationMs": 558, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258427, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T16:59:26.730Z", + "finishedAt": "2026-09-01T16:59:31.725Z", + "operation": "relaunch-foreground", + "wallClockMs": 4995.177957999986, + "daemonDurationMs": 554, + "responseBytes": 11208, + "nodeCount": 20, + "targetGeneration": 258429, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T16:59:33.505Z", + "finishedAt": "2026-09-01T16:59:38.427Z", + "operation": "relaunch-foreground", + "wallClockMs": 4922.163457999937, + "daemonDurationMs": 540, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258431, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T16:59:40.188Z", + "finishedAt": "2026-09-01T16:59:45.055Z", + "operation": "relaunch-foreground", + "wallClockMs": 4867.245042000082, + "daemonDurationMs": 540, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258433, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 14, + "startedAt": "2026-09-01T16:59:46.878Z", + "finishedAt": "2026-09-01T16:59:51.942Z", + "operation": "relaunch-foreground", + "wallClockMs": 5063.650874999934, + "daemonDurationMs": 528, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258435, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T16:59:53.748Z", + "finishedAt": "2026-09-01T16:59:58.664Z", + "operation": "relaunch-foreground", + "wallClockMs": 4916.811332999961, + "daemonDurationMs": 541, + "responseBytes": 11208, + "nodeCount": 20, + "targetGeneration": 258437, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:00:00.485Z", + "finishedAt": "2026-09-01T17:00:05.395Z", + "operation": "relaunch-foreground", + "wallClockMs": 4909.595874999999, + "daemonDurationMs": 545, + "responseBytes": 11208, + "nodeCount": 20, + "targetGeneration": 258439, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:00:07.202Z", + "finishedAt": "2026-09-01T17:00:12.006Z", + "operation": "relaunch-foreground", + "wallClockMs": 4804.4382079999195, + "daemonDurationMs": 538, + "responseBytes": 11208, + "nodeCount": 20, + "targetGeneration": 258441, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:00:13.741Z", + "finishedAt": "2026-09-01T17:00:18.658Z", + "operation": "relaunch-foreground", + "wallClockMs": 4916.146791999927, + "daemonDurationMs": 543, + "responseBytes": 11208, + "nodeCount": 20, + "targetGeneration": 258443, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:00:20.454Z", + "finishedAt": "2026-09-01T17:00:25.467Z", + "operation": "relaunch-foreground", + "wallClockMs": 5013.690457999939, + "daemonDurationMs": 541, + "responseBytes": 11208, + "nodeCount": 20, + "targetGeneration": 258445, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:00:27.287Z", + "finishedAt": "2026-09-01T17:00:32.308Z", + "operation": "relaunch-foreground", + "wallClockMs": 5021.184166999999, + "daemonDurationMs": 541, + "responseBytes": 11207, + "nodeCount": 20, + "targetGeneration": 258447, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 4804.4382079999195, + "median": 4916.811332999961, + "p95": 5094.90395800001, + "max": 5115.3286249999655, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 528, + "median": 541, + "p95": 558, + "max": 578, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 11019, + "median": 11207, + "p95": 11208, + "max": 11208, + "outlierCount": 0, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + }, + { + "transport": "local", + "execution": "fresh-process-cli", + "state": "relaunch", + "screen": "xctest-stress", + "sampleMinimum": 20, + "operation": "relaunch-foreground", + "samples": [ + { + "index": 1, + "startedAt": "2026-09-01T17:00:43.393Z", + "finishedAt": "2026-09-01T17:00:48.782Z", + "operation": "relaunch-foreground", + "wallClockMs": 5388.2342920000665, + "daemonDurationMs": 618, + "responseBytes": 3319, + "nodeCount": 1, + "targetGeneration": 911257, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 2, + "startedAt": "2026-09-01T17:00:50.978Z", + "finishedAt": "2026-09-01T17:00:56.014Z", + "operation": "relaunch-foreground", + "wallClockMs": 5035.480250000022, + "daemonDurationMs": 648, + "responseBytes": 3504, + "nodeCount": 1, + "targetGeneration": 911259, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 3, + "startedAt": "2026-09-01T17:00:57.772Z", + "finishedAt": "2026-09-01T17:01:02.381Z", + "operation": "relaunch-foreground", + "wallClockMs": 4608.763583000051, + "daemonDurationMs": 973, + "responseBytes": 3504, + "nodeCount": 1, + "targetGeneration": 911261, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 4, + "startedAt": "2026-09-01T17:01:04.319Z", + "finishedAt": "2026-09-01T17:01:08.704Z", + "operation": "relaunch-foreground", + "wallClockMs": 4385.374166999944, + "daemonDurationMs": 732, + "responseBytes": 3503, + "nodeCount": 1, + "targetGeneration": 911263, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 5, + "startedAt": "2026-09-01T17:01:10.444Z", + "finishedAt": "2026-09-01T17:01:14.436Z", + "operation": "relaunch-foreground", + "wallClockMs": 3992.0867080001626, + "daemonDurationMs": 649, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911265, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 6, + "startedAt": "2026-09-01T17:01:16.177Z", + "finishedAt": "2026-09-01T17:01:20.186Z", + "operation": "relaunch-foreground", + "wallClockMs": 4009.622542000143, + "daemonDurationMs": 648, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911267, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 7, + "startedAt": "2026-09-01T17:01:22.031Z", + "finishedAt": "2026-09-01T17:01:26.219Z", + "operation": "relaunch-foreground", + "wallClockMs": 4187.794415999902, + "daemonDurationMs": 681, + "responseBytes": 3505, + "nodeCount": 1, + "targetGeneration": 911269, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 8, + "startedAt": "2026-09-01T17:01:28.042Z", + "finishedAt": "2026-09-01T17:01:32.138Z", + "operation": "relaunch-foreground", + "wallClockMs": 4095.747958000051, + "daemonDurationMs": 668, + "responseBytes": 3507, + "nodeCount": 1, + "targetGeneration": 911271, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 9, + "startedAt": "2026-09-01T17:01:33.970Z", + "finishedAt": "2026-09-01T17:01:38.163Z", + "operation": "relaunch-foreground", + "wallClockMs": 4192.844583000056, + "daemonDurationMs": 766, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911273, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 10, + "startedAt": "2026-09-01T17:01:39.968Z", + "finishedAt": "2026-09-01T17:01:44.228Z", + "operation": "relaunch-foreground", + "wallClockMs": 4260.054999999935, + "daemonDurationMs": 714, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911275, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 11, + "startedAt": "2026-09-01T17:01:46.502Z", + "finishedAt": "2026-09-01T17:01:50.949Z", + "operation": "relaunch-foreground", + "wallClockMs": 4447.674540999811, + "daemonDurationMs": 771, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911277, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 12, + "startedAt": "2026-09-01T17:01:53.050Z", + "finishedAt": "2026-09-01T17:01:58.298Z", + "operation": "relaunch-foreground", + "wallClockMs": 5247.331250000047, + "daemonDurationMs": 666, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911279, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 13, + "startedAt": "2026-09-01T17:02:00.137Z", + "finishedAt": "2026-09-01T17:02:05.654Z", + "operation": "relaunch-foreground", + "wallClockMs": 5516.366249999963, + "daemonDurationMs": 916, + "responseBytes": 3507, + "nodeCount": 1, + "targetGeneration": 911281, + "firstTree": "readable", + "ok": true, + "outlier": true + }, + { + "index": 14, + "startedAt": "2026-09-01T17:02:07.433Z", + "finishedAt": "2026-09-01T17:02:11.562Z", + "operation": "relaunch-foreground", + "wallClockMs": 4128.087749999948, + "daemonDurationMs": 626, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911283, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 15, + "startedAt": "2026-09-01T17:02:13.616Z", + "finishedAt": "2026-09-01T17:02:18.493Z", + "operation": "relaunch-foreground", + "wallClockMs": 4876.161665999796, + "daemonDurationMs": 623, + "responseBytes": 3508, + "nodeCount": 1, + "targetGeneration": 911285, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 16, + "startedAt": "2026-09-01T17:02:20.336Z", + "finishedAt": "2026-09-01T17:02:24.754Z", + "operation": "relaunch-foreground", + "wallClockMs": 4417.248292000033, + "daemonDurationMs": 984, + "responseBytes": 3507, + "nodeCount": 1, + "targetGeneration": 911287, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 17, + "startedAt": "2026-09-01T17:02:26.689Z", + "finishedAt": "2026-09-01T17:02:30.985Z", + "operation": "relaunch-foreground", + "wallClockMs": 4296.329499999993, + "daemonDurationMs": 697, + "responseBytes": 3505, + "nodeCount": 1, + "targetGeneration": 911289, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 18, + "startedAt": "2026-09-01T17:02:32.727Z", + "finishedAt": "2026-09-01T17:02:36.719Z", + "operation": "relaunch-foreground", + "wallClockMs": 3991.0787080000155, + "daemonDurationMs": 666, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911291, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 19, + "startedAt": "2026-09-01T17:02:38.446Z", + "finishedAt": "2026-09-01T17:02:42.509Z", + "operation": "relaunch-foreground", + "wallClockMs": 4062.674374999944, + "daemonDurationMs": 652, + "responseBytes": 3504, + "nodeCount": 1, + "targetGeneration": 911293, + "firstTree": "readable", + "ok": true, + "outlier": false + }, + { + "index": 20, + "startedAt": "2026-09-01T17:02:44.346Z", + "finishedAt": "2026-09-01T17:02:48.571Z", + "operation": "relaunch-foreground", + "wallClockMs": 4224.37716699997, + "daemonDurationMs": 748, + "responseBytes": 3506, + "nodeCount": 1, + "targetGeneration": 911295, + "firstTree": "readable", + "ok": true, + "outlier": false + } + ], + "wallClockMs": { + "n": 20, + "min": 3991.0787080000155, + "median": 4260.054999999935, + "p95": 5388.2342920000665, + "max": 5516.366249999963, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "daemonDurationMs": { + "n": 20, + "min": 618, + "median": 668, + "p95": 973, + "max": 984, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "responseBytes": { + "n": 20, + "min": 3319, + "median": 3506, + "p95": 3507, + "max": 3508, + "outlierCount": 2, + "outlierRule": "tukey-1.5-iqr" + }, + "failures": 0, + "failureCategories": {} + } + ], + "packageSize": { + "status": "measured", + "revision": "71fb2483f30d90e615e949601c836aeebbf450c5", + "packed": { + "tarballBytes": 982960, + "unpackedBytes": 3347347 + }, + "cleanInstalled": { + "packageBytes": 3347347, + "files": 436 + }, + "bundled": { + "rawBytes": 2480947, + "gzipBytes": 835279, + "files": 330 + } + }, + "deepButtonEvidence": { + "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" +} diff --git a/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-warm-relaunch-local-71fb2483f.md b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-warm-relaunch-local-71fb2483f.md new file mode 100644 index 000000000..1395736a7 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/evidence/ios-snapshot-warm-relaunch-local-71fb2483f.md @@ -0,0 +1,37 @@ +# iOS snapshot convergence benchmark + +- Status: **completed** +- Revision: 71fb2483f30d90e615e949601c836aeebbf450c5 +- Host: MacBook Pro (Mac16,8; Apple M4 Pro, 12 cores) +- Target: bench-golden-v2 (7E76ECA9-D40C-4833-A711-F870F8CE9363, com.apple.CoreSimulator.SimRuntime.iOS-27-0) +- Generated: 2026-09-01T17:02:50.284Z + +| State | Screen | Transport | Execution | N | Wall median | Wall p95 | Daemon median | Response median | Failures | +|---|---|---|---|---:|---:|---:|---:|---:|---:| +| warm | quiet | local | fresh-process-cli | 20 | 153.5 | 315.3 | 50.0 | 4004.0 | 0 | +| warm | list | local | fresh-process-cli | 20 | 312.3 | 318.4 | 209.0 | 18020.0 | 0 | +| warm | nested-scroll | local | fresh-process-cli | 20 | 187.2 | 190.5 | 83.0 | 13537.0 | 0 | +| warm | alert | local | fresh-process-cli | 20 | 206.8 | 395.5 | 104.0 | 15668.0 | 0 | +| warm | system-surface | local | fresh-process-cli | 20 | 209.7 | 227.8 | 105.0 | 10012.0 | 0 | +| warm | xctest-stress | local | fresh-process-cli | 20 | 208.3 | 213.3 | 105.0 | 14944.0 | 0 | +| relaunch | quiet | local | fresh-process-cli | 20 | 3644.8 | 4251.3 | 627.0 | 5062.0 | 0 | +| relaunch | list | local | fresh-process-cli | 20 | 4377.9 | 5051.2 | 628.0 | 16422.0 | 0 | +| relaunch | nested-scroll | local | fresh-process-cli | 20 | 4313.5 | 4405.0 | 626.0 | 10562.0 | 0 | +| relaunch | alert | local | fresh-process-cli | 20 | 4369.5 | 5065.9 | 624.0 | 14233.0 | 0 | +| relaunch | system-surface | local | fresh-process-cli | 20 | 4916.8 | 5094.9 | 541.0 | 11207.0 | 0 | +| relaunch | xctest-stress | local | fresh-process-cli | 20 | 4260.1 | 5388.2 | 668.0 | 3506.0 | 0 | + +## Package size + +- Packed tarball: 982960 bytes +- Packed unpacked tree: 3347347 bytes +- Clean-installed package tree: 3347347 bytes (436 files) +- Bundled JavaScript: 2480947 raw / 835279 gzip bytes + +## Deep-button control + +- Fixture artifact: deep-button-fixture.v1.json (depth 72) +- Red control: pnpm bench:ios-snapshot:deep-button -- --rule invalid-shallow (exit 1) + - AssertionError: changed descendant was omitted by shallow observation; no-effect claim is invalid. +- Safe control: pnpm bench:ios-snapshot:deep-button -- --rule safe-full (exit 0) + - full observation changed and includes the changed descendant. diff --git a/scripts/ios-snapshot-benchmark/fixture-admission.test.ts b/scripts/ios-snapshot-benchmark/fixture-admission.test.ts new file mode 100644 index 000000000..cc328e75f --- /dev/null +++ b/scripts/ios-snapshot-benchmark/fixture-admission.test.ts @@ -0,0 +1,76 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { BenchmarkCellAdmissionError } from './lifecycle.ts'; +import { + prepareFixture, + requireFixtureAnchor, + type FixturePreparationDriver, + type FixturePreparationResult, +} from './fixture-admission.ts'; +import type { ScreenFixture } from './types.ts'; + +const alertFixture: ScreenFixture = { + id: 'alert', + label: 'Native alert', + app: 'com.callstack.agentdevicelab', + anchorText: 'Automation lab', + postSetupAnchorText: 'Automation confirmation', + setupAction: 'open-alert', +}; + +function observed(anchor: string): FixturePreparationResult { + return { + ok: true, + payload: { + total: 1, + results: [{ data: { snapshot: { nodes: [{ label: anchor }] } } }], + }, + }; +} + +function successfulDriver(observations: string[]): FixturePreparationDriver { + const calls: FixturePreparationDriver = { + observe: () => observed(observations.shift() ?? ''), + scrollToBottom: () => ({ ok: true, payload: {} }), + openAlert: () => ({ ok: true, payload: {} }), + }; + return calls; +} + +test('shares opening, setup, and post-setup admission across fixture drivers', async () => { + const calls: string[] = []; + const driver: FixturePreparationDriver = { + observe: () => { + calls.push('observe'); + return observed(calls.length === 1 ? 'Automation lab' : 'Automation confirmation'); + }, + scrollToBottom: () => { + calls.push('scroll'); + return { ok: true, payload: {} }; + }, + openAlert: () => { + calls.push('open-alert'); + return { ok: true, payload: {} }; + }, + }; + + await prepareFixture(alertFixture, driver); + + assert.deepEqual(calls, ['observe', 'scroll', 'open-alert', 'observe']); +}); + +test('turns a wrong post-setup screen into a typed fixture-anchor stop', async () => { + await assert.rejects( + () => prepareFixture(alertFixture, successfulDriver(['Automation lab', 'Settings'])), + (error: unknown) => + error instanceof BenchmarkCellAdmissionError && error.reason === 'fixture-anchor', + ); +}); + +test('checks the expected post-setup anchor for direct client batch results', () => { + assert.throws( + () => requireFixtureAnchor(observed('Settings').payload, alertFixture, 'prepared'), + (error: unknown) => + error instanceof BenchmarkCellAdmissionError && error.reason === 'fixture-anchor', + ); +}); diff --git a/scripts/ios-snapshot-benchmark/fixture-admission.ts b/scripts/ios-snapshot-benchmark/fixture-admission.ts new file mode 100644 index 000000000..673a37ab3 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/fixture-admission.ts @@ -0,0 +1,113 @@ +import { classifyFailure, formatCliFailure, snapshotHasAnchor, type CliResult } from './command.ts'; +import { BenchmarkCellAdmissionError, BenchmarkContentionError } from './lifecycle.ts'; +import { asRecord, readString } from './result-values.ts'; +import type { Failure, ScreenFixture } from './types.ts'; + +export type FixtureAnchorPhase = 'opened' | 'prepared' | 'sample'; + +export type FixtureOperationResult = { + ok: boolean; + payload: unknown; + failure?: Failure; + message?: string; + command?: string; +}; + +export type FixturePreparationDriver = { + observe: () => FixtureOperationResult | Promise; + scrollToBottom: () => FixtureOperationResult | Promise; + openAlert: () => FixtureOperationResult | Promise; +}; + +export async function prepareFixture( + fixture: ScreenFixture, + driver: FixturePreparationDriver, +): Promise { + const opened = await driver.observe(); + requireFixtureOperationSuccess( + opened, + `${fixture.id} semantic anchor observation`, + 'fixture-anchor', + ); + requireFixtureAnchor(opened.payload, fixture, 'opened', opened.command); + if (fixture.setupAction !== 'open-alert') return; + + const scrolled = await driver.scrollToBottom(); + requireFixtureOperationSuccess(scrolled, `${fixture.id} setup scroll`, 'cell-state'); + const alert = await driver.openAlert(); + requireFixtureOperationSuccess(alert, `${fixture.id} setup action`, 'cell-state'); + const prepared = await driver.observe(); + requireFixtureOperationSuccess( + prepared, + `${fixture.id} post-setup semantic anchor observation`, + 'fixture-anchor', + ); + requireFixtureAnchor(prepared.payload, fixture, 'prepared', prepared.command); +} + +export function requireFixtureAnchor( + payload: unknown, + fixture: ScreenFixture, + phase: FixtureAnchorPhase, + command = 'agent-device snapshot', +): void { + const anchor = expectedAnchor(fixture, phase); + if (snapshotHasAnchor(payload, anchor)) return; + throw new BenchmarkCellAdmissionError( + 'fixture-anchor', + `Fixture ${fixture.id} ${phase} did not expose the exact anchor ${JSON.stringify(anchor)}.`, + command, + ); +} + +export function fixtureOperationFromCli( + result: CliResult, + command: string, +): FixtureOperationResult { + if (result.ok) return { ok: true, payload: result.payload, command }; + const failure = classifyFailure(result.payload, result); + return { + ok: false, + payload: result.payload, + failure, + message: formatCliFailure(command, failure, result), + command, + }; +} + +export function fixtureOperationFromClient( + payload: unknown, + command: string, +): FixtureOperationResult { + const record = asRecord(payload); + const first = Array.isArray(record?.results) ? asRecord(record.results[0]) : undefined; + const ok = record?.ok !== false && first?.ok !== false; + if (ok) return { ok: true, payload, command }; + const error = asRecord(record?.error); + const code = readString(error?.code); + const message = readString(error?.message) ?? `${command} failed`; + const failure: Failure = { + category: 'upstream', + ...(code ? { code } : {}), + message, + }; + return { ok: false, payload, failure, message, command }; +} + +function expectedAnchor(fixture: ScreenFixture, phase: FixtureAnchorPhase): string { + if (phase === 'opened') return fixture.anchorText; + return fixture.postSetupAnchorText ?? fixture.anchorText; +} + +export function requireFixtureOperationSuccess( + result: FixtureOperationResult, + operation: string, + reason: 'cell-state' | 'fixture-anchor', +): void { + if (result.ok) return; + const message = result.message ?? `${operation} failed`; + if (result.failure?.code === 'DEVICE_IN_USE') { + throw new BenchmarkContentionError(message, result.command ?? operation); + } + throw new BenchmarkCellAdmissionError(reason, message, result.command ?? operation); +} diff --git a/scripts/ios-snapshot-benchmark/host.test.ts b/scripts/ios-snapshot-benchmark/host.test.ts new file mode 100644 index 000000000..b2d1124d1 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/host.test.ts @@ -0,0 +1,32 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { parseHardwareProfile } from './host.ts'; + +test('parses the Mac model and CPU identity from system_profiler output', () => { + assert.deepEqual( + parseHardwareProfile( + [ + 'Hardware:', + '', + ' Hardware Overview:', + ' Model Name: MacBook Pro', + ' Model Identifier: Mac16,8', + ' Chip: Apple M4 Pro', + ' Total Number of Cores: 12 (8 performance and 4 efficiency)', + ].join('\n'), + ), + { + model: 'MacBook Pro', + modelIdentifier: 'Mac16,8', + cpu: 'Apple M4 Pro', + cpuCores: 12, + }, + ); +}); + +test('rejects incomplete host identity instead of recording an unknown machine', () => { + assert.throws( + () => parseHardwareProfile('Hardware:\n Model Name: MacBook Pro'), + /Model Identifier/, + ); +}); diff --git a/scripts/ios-snapshot-benchmark/host.ts b/scripts/ios-snapshot-benchmark/host.ts new file mode 100644 index 000000000..7df821764 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/host.ts @@ -0,0 +1,109 @@ +import { execFileSync } from 'node:child_process'; +import os from 'node:os'; +import path from 'node:path'; +import type { GitRevision, HostIdentity, Target, Toolchain } from './types.ts'; + +export function readToolchain(): Toolchain { + return { + node: process.version, + pnpm: commandVersion('pnpm', ['--version']), + xcode: commandText('xcodebuild', ['-version']), + simctl: commandText('xcrun', ['simctl', '--version']), + os: `${os.platform()} ${os.release()}`, + arch: os.arch(), + }; +} + +export function readHostIdentity(): HostIdentity { + return parseHardwareProfile(commandText('system_profiler', ['SPHardwareDataType'])); +} + +export function parseHardwareProfile(output: string): HostIdentity { + const fields = new Map(); + for (const line of output.split('\n')) { + const match = /^\s*([^:]+):\s*(.+?)\s*$/u.exec(line); + if (match) fields.set(match[1]!, match[2]!); + } + const model = requiredHardwareField(fields, 'Model Name'); + const modelIdentifier = requiredHardwareField(fields, 'Model Identifier'); + const cpu = fields.get('Chip') ?? fields.get('Processor Name'); + if (!cpu) throw new Error('system_profiler did not report a Mac CPU.'); + const coreText = requiredHardwareField(fields, 'Total Number of Cores'); + const coreMatch = /^(\d+)\b/u.exec(coreText); + const cpuCores = Number(coreMatch?.[1]); + if (!Number.isSafeInteger(cpuCores) || cpuCores < 1) { + throw new Error(`system_profiler reported an invalid core count: ${coreText}`); + } + return { model, modelIdentifier, cpu, cpuCores }; +} + +export function readGitRevision(repoRoot: string): GitRevision { + return { + commit: commandText('git', ['rev-parse', 'HEAD'], repoRoot), + branch: commandText('git', ['branch', '--show-current'], repoRoot) || 'detached', + dirty: commandText('git', ['status', '--porcelain'], repoRoot).length > 0, + }; +} + +export function readTarget(udid: string, appId: string, appPath?: string): Target { + const inventory = parseSimctlDevices( + commandText('xcrun', ['simctl', 'list', 'devices', 'available', '--json']), + ); + const device = inventory.find((candidate) => candidate.udid === udid); + if (!device) throw new Error(`Simulator ${udid} is not available in simctl inventory.`); + return { + platform: 'ios', + kind: 'simulator', + udid, + name: device.name, + runtime: device.runtime, + appId, + ...(appPath ? { appPath } : {}), + }; +} + +function commandText(command: string, args: string[], cwd?: string): string { + try { + return execFileSync(command, args, { + cwd, + encoding: 'utf8', + env: { ...process.env, AGENT_DEVICE_NO_UPDATE_NOTIFIER: '1' }, + maxBuffer: 1024 * 1024, + stdio: ['ignore', 'pipe', 'ignore'], + }).trim(); + } catch { + return 'unavailable'; + } +} + +function commandVersion(command: string, args: string[]): string { + return commandText(command, args) || 'unavailable'; +} + +function requiredHardwareField(fields: Map, name: string): string { + const value = fields.get(name); + if (!value) throw new Error(`system_profiler did not report ${name}.`); + return value; +} + +function parseSimctlDevices( + output: string, +): Array<{ udid: string; name: string; runtime: string }> { + if (output === 'unavailable') return []; + try { + const parsed = JSON.parse(output) as { + devices?: Record>; + }; + return Object.entries(parsed.devices ?? {}).flatMap(([runtime, devices]) => + devices.flatMap((device) => + device.udid && device.name ? [{ udid: device.udid, name: device.name, runtime }] : [], + ), + ); + } catch { + return []; + } +} + +export function resolveRepoRoot(): string { + return path.resolve(import.meta.dirname, '..', '..'); +} diff --git a/scripts/ios-snapshot-benchmark/lifecycle.test.ts b/scripts/ios-snapshot-benchmark/lifecycle.test.ts new file mode 100644 index 000000000..5a4eab69e --- /dev/null +++ b/scripts/ios-snapshot-benchmark/lifecycle.test.ts @@ -0,0 +1,13 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { parseRunningAppPids } from './lifecycle.ts'; + +test('parses only exact UIKit application labels', () => { + const output = [ + 'PID Status Label', + '1000\t0\tUIKitApplication:com.callstack.agentdevicelab[abc][rb-legacy]', + '1001\t0\tUIKitApplication:com.callstack.agentdevicelab-extra[def][rb-legacy]', + '1002\t0\tcom.apple.some-service', + ].join('\n'); + assert.deepEqual(parseRunningAppPids(output, 'com.callstack.agentdevicelab'), [1000]); +}); diff --git a/scripts/ios-snapshot-benchmark/lifecycle.ts b/scripts/ios-snapshot-benchmark/lifecycle.ts new file mode 100644 index 000000000..64352dd62 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/lifecycle.ts @@ -0,0 +1,220 @@ +import { spawnSync } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; +import type { BenchmarkStopReason } from './types.ts'; + +export class BenchmarkInfrastructureError extends Error { + readonly command?: string; + + constructor(message: string, command?: string) { + super(message); + this.name = 'BenchmarkInfrastructureError'; + this.command = command; + } +} + +export class BenchmarkContentionError extends Error { + readonly command?: string; + + constructor(message: string, command?: string) { + super(message); + this.name = 'BenchmarkContentionError'; + this.command = command; + } +} + +export class BenchmarkCellAdmissionError extends BenchmarkInfrastructureError { + readonly reason: BenchmarkStopReason; + + constructor(reason: BenchmarkStopReason, message: string, command?: string) { + super(message, command); + this.name = 'BenchmarkCellAdmissionError'; + this.reason = reason; + } +} + +export function bootSimulator(udid: string): void { + if (readSimulatorState(udid) !== 'Booted') { + const boot = runXcrun(['simctl', 'boot', udid], false); + if (boot.status !== 0) { + throw new BenchmarkInfrastructureError( + `xcrun simctl boot ${udid} failed: ${boot.stderr.trim() || 'no diagnostic'}`, + `xcrun simctl boot ${udid}`, + ); + } + } + const result = runXcrun(['simctl', 'bootstatus', udid, '-b'], true); + if (result.status !== 0) { + throw new BenchmarkInfrastructureError( + `Simulator ${udid} did not reach Booted: ${result.stderr.trim() || 'simctl bootstatus failed'}`, + `xcrun simctl bootstatus ${udid} -b`, + ); + } + if (readSimulatorState(udid) !== 'Booted') { + throw new BenchmarkInfrastructureError( + `Simulator ${udid} did not reach Booted after bootstatus.`, + `xcrun simctl bootstatus ${udid} -b`, + ); + } +} + +export function shutdownSimulator(udid: string): void { + if (readSimulatorState(udid) === 'Shutdown') return; + const result = runXcrun(['simctl', 'shutdown', udid], false); + if (result.status !== 0) { + throw new BenchmarkInfrastructureError( + `xcrun simctl shutdown ${udid} failed: ${result.stderr.trim() || 'no diagnostic'}`, + `xcrun simctl shutdown ${udid}`, + ); + } + if (!waitForSimulatorState(udid, 'Shutdown')) { + throw new BenchmarkInfrastructureError( + `Simulator ${udid} did not reach Shutdown after shutdown.`, + `xcrun simctl shutdown ${udid}`, + ); + } +} + +function waitForSimulatorState(udid: string, expected: string): boolean { + const deadline = Date.now() + 30_000; + while (Date.now() < deadline) { + if (readSimulatorState(udid) === expected) return true; + spawnSync('sleep', ['0.25'], { stdio: 'ignore' }); + } + return readSimulatorState(udid) === expected; +} + +export function terminateApp(udid: string, appId: string): void { + if (readSimulatorState(udid) !== 'Booted') { + throw new BenchmarkInfrastructureError( + `Simulator ${udid} must be Booted before terminating ${appId}.`, + `xcrun simctl terminate ${udid} ${appId}`, + ); + } + if (readRunningAppPids(udid, appId).length === 0) return; + const result = runXcrun(['simctl', 'terminate', udid, appId], false); + if (result.status !== 0) { + throw new BenchmarkInfrastructureError( + `xcrun simctl terminate ${udid} ${appId} failed: ${result.stderr.trim() || 'no diagnostic'}`, + `xcrun simctl terminate ${udid} ${appId}`, + ); + } + if (readRunningAppPids(udid, appId).length > 0) { + throw new BenchmarkInfrastructureError( + `App ${appId} remained running on simulator ${udid} after terminate.`, + `xcrun simctl terminate ${udid} ${appId}`, + ); + } +} + +export function stopDaemon(repoRoot: string, stateDir: string): void { + const result = spawnSync( + process.execPath, + ['bin/agent-device.mjs', 'daemon', 'stop', '--state-dir', stateDir, '--clean', '--json'], + { + cwd: repoRoot, + env: { ...process.env, AGENT_DEVICE_NO_UPDATE_NOTIFIER: '1' }, + encoding: 'utf8', + timeout: 60_000, + stdio: ['ignore', 'pipe', 'pipe'], + }, + ); + if (result.error || result.status !== 0) { + const diagnostic = processStderr(result.stderr); + throw new BenchmarkInfrastructureError( + `Daemon stop failed for ${stateDir}: ${diagnostic.trim() || result.error?.message || `exit ${String(result.status)}`}`, + 'agent-device daemon stop --clean', + ); + } + if ( + fs.existsSync(path.join(stateDir, 'daemon.json')) || + fs.existsSync(path.join(stateDir, 'daemon.lock')) + ) { + throw new BenchmarkInfrastructureError( + `Daemon metadata remained after stopping ${stateDir}.`, + 'agent-device daemon stop --clean', + ); + } +} + +export function readSimulatorState(udid: string): string { + const result = runXcrun(['simctl', 'list', 'devices', 'available', '--json'], true); + let parsed: unknown; + try { + parsed = JSON.parse(result.stdout); + } catch { + throw new BenchmarkInfrastructureError( + `simctl returned invalid device metadata for ${udid}.`, + 'xcrun simctl list devices available --json', + ); + } + if (!isRecord(parsed) || !isRecord(parsed.devices)) { + throw new BenchmarkInfrastructureError( + `simctl returned no device metadata for ${udid}.`, + 'xcrun simctl list devices available --json', + ); + } + for (const devices of Object.values(parsed.devices)) { + if (!Array.isArray(devices)) continue; + const match = devices.find((device) => isRecord(device) && device.udid === udid); + if (isRecord(match) && typeof match.state === 'string') return match.state; + } + throw new BenchmarkInfrastructureError( + `Simulator ${udid} was not found in simctl device metadata.`, + 'xcrun simctl list devices available --json', + ); +} + +export function readRunningAppPids(udid: string, appId: string): number[] { + const result = runXcrun(['simctl', 'spawn', udid, 'launchctl', 'list'], true); + return parseRunningAppPids(result.stdout, appId); +} + +export function parseRunningAppPids(output: string, appId: string): number[] { + const prefix = `UIKitApplication:${appId}[`; + const pids: number[] = []; + for (const line of output.split('\n')) { + const columns = line.trim().split(/\s+/u); + const pid = Number(columns[0]); + const label = columns.slice(2).join(' '); + if (Number.isSafeInteger(pid) && pid > 0 && label.startsWith(prefix)) pids.push(pid); + } + return [...new Set(pids)]; +} + +function runXcrun( + args: string[], + required: boolean, +): { status: number; stdout: string; stderr: string; error?: Error } { + const result = spawnSync('xcrun', args, { + encoding: 'utf8', + timeout: 5 * 60 * 1000, + stdio: ['ignore', 'pipe', 'pipe'], + }); + const status = processStatus(result.status); + const stdout = processOutput(result.stdout); + const stderr = processStderr(result.stderr); + if (required && status !== 0) { + throw new BenchmarkInfrastructureError( + `xcrun ${args.join(' ')} failed: ${stderr.trim() || result.error?.message || 'no diagnostic'}`, + `xcrun ${args.join(' ')}`, + ); + } + return { status, stdout, stderr, ...(result.error ? { error: result.error } : {}) }; +} + +function processStatus(status: number | null): number { + return typeof status === 'number' ? status : -1; +} + +function processStderr(stderr: string | Buffer | null): string { + return typeof stderr === 'string' ? stderr : ''; +} + +function processOutput(stdout: string | Buffer | null): string { + return typeof stdout === 'string' ? stdout : ''; +} + +function isRecord(value: unknown): value is Record { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} diff --git a/scripts/ios-snapshot-benchmark/local-runner.ts b/scripts/ios-snapshot-benchmark/local-runner.ts new file mode 100644 index 000000000..6dc31a8fe --- /dev/null +++ b/scripts/ios-snapshot-benchmark/local-runner.ts @@ -0,0 +1,119 @@ +import { spawnSync } from 'node:child_process'; +import path from 'node:path'; +import { + openFixture, + sampleFromCli, + snapshotFixture, + type CliContext, + type CliResult, +} from './command.ts'; +import { + admitReadyCell, + admitSuccessfulSample, + cleanupSuccessfulSample, + prepareCellState, + prepareSampleState, + type CellAdmissionOptions, +} from './cell-admission.ts'; +import { sampleMinimumForState } from './definitions.ts'; +import { stopDaemon } from './lifecycle.ts'; +import { buildMeasurement } from './statistics.ts'; +import type { LocalState, Measurement, RawSample, ScreenFixture } from './types.ts'; + +type LocalRunnerOptions = { + repoRoot: string; + stateDir: string; + derivedPath: string; + udid: string; + fixtures: ScreenFixture[]; + states: LocalState[]; + samples: number; +}; + +export async function runLocalMeasurements(options: LocalRunnerOptions): Promise { + const measurements: Measurement[] = []; + for (const state of options.states) { + for (const fixture of options.fixtures) { + measurements.push(await runCell({ ...options, state, fixture })); + } + } + return measurements; +} + +async function runCell(options: CellAdmissionOptions): Promise { + const context = contextFor(options); + let appPid: number | undefined; + try { + prepareCellState(options); + appPid = await admitReadyCell(context, options); + const samples: RawSample[] = []; + for (let index = 0; index < options.samples; index += 1) { + if (index > 0) prepareSampleState(options); + const result = runMeasuredCommand(context, options); + if (result.ok) { + appPid = await admitSuccessfulSample(context, options, result, appPid); + cleanupSuccessfulSample(context, options); + } + samples.push(sampleFromCli(result, measuredOperation(options.state), index)); + } + return buildMeasurement({ + transport: 'local', + execution: 'fresh-process-cli', + state: options.state, + screen: options.fixture.id, + sampleMinimum: sampleMinimumForState(options.state), + operation: measuredOperation(options.state), + samples, + }); + } finally { + closeSession(context); + stopDaemon(options.repoRoot, options.stateDir); + } +} + +function runMeasuredCommand(context: CliContext, options: CellAdmissionOptions): CliResult { + if (options.state === 'warm') return snapshotFixture(context); + return openFixture(context, options.fixture, { relaunch: true }); +} + +function measuredOperation( + state: LocalState, +): 'open-foreground' | 'snapshot' | 'relaunch-foreground' { + if (state === 'warm') return 'snapshot'; + if (state === 'relaunch') return 'relaunch-foreground'; + return 'open-foreground'; +} + +function contextFor(options: CellAdmissionOptions): CliContext { + return { + repoRoot: options.repoRoot, + stateDir: options.stateDir, + session: `bench-${options.state}-${options.fixture.id}`, + udid: options.udid, + derivedPath: path.join(options.derivedPath, options.state, options.fixture.id), + }; +} + +export 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, + stdio: 'ignore', + timeout: 60_000, + }, + ); +} diff --git a/scripts/ios-snapshot-benchmark/package-evidence.ts b/scripts/ios-snapshot-benchmark/package-evidence.ts new file mode 100644 index 000000000..3a0906df8 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/package-evidence.ts @@ -0,0 +1,84 @@ +import { execFileSync } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; +import { asRecord } from './result-values.ts'; +import type { PackageSize } from './types.ts'; + +export function measurePackageSize(repoRoot: string, revision: string): PackageSize { + const reportPath = path.join(repoRoot, '.tmp', `ios-size-${process.pid}-${Date.now()}.json`); + try { + runSizeReport(repoRoot, reportPath); + return readPackageSize(reportPath, revision); + } finally { + removeReport(reportPath); + } +} + +export function notRunPackageSize(revision: string): PackageSize { + return { status: 'not-run', revision }; +} + +function runSizeReport(repoRoot: string, reportPath: string): void { + execFileSync( + process.execPath, + ['scripts/size-report.mjs', '--cwd', repoRoot, '--json', reportPath], + { + cwd: repoRoot, + stdio: ['ignore', 'ignore', 'inherit'], + timeout: 10 * 60 * 1000, + }, + ); +} + +function readPackageSize(reportPath: string, revision: string): PackageSize { + const report = JSON.parse(fs.readFileSync(reportPath, 'utf8')) as Record; + const npmPack = asRecord(report.npmPack); + const cleanInstalled = asRecord(report.cleanInstalled); + const bundled = asRecord(report.bundled); + return { + status: 'measured', + revision, + packed: readPackedSize(npmPack), + cleanInstalled: readCleanInstalledSize(cleanInstalled), + bundled: readBundledSize(bundled), + }; +} + +function readPackedSize( + value: Record | undefined, +): NonNullable { + return { + tarballBytes: readInteger(value?.tarballBytes), + unpackedBytes: readInteger(value?.unpackedBytes), + }; +} + +function readCleanInstalledSize( + value: Record | undefined, +): NonNullable { + return { + packageBytes: readInteger(value?.packageBytes), + files: readInteger(value?.files), + }; +} + +function readBundledSize( + value: Record | undefined, +): NonNullable { + return { + rawBytes: readInteger(value?.rawBytes), + gzipBytes: readInteger(value?.gzipBytes), + files: readInteger(value?.files), + }; +} + +function removeReport(reportPath: string): void { + if (fs.existsSync(reportPath)) fs.rmSync(reportPath, { force: true }); +} + +function readInteger(value: unknown): number { + if (!Number.isSafeInteger(value) || (value as number) < 0) { + throw new Error(`Invalid size report value: ${String(value)}`); + } + return value as number; +} diff --git a/scripts/ios-snapshot-benchmark/proxy-client-support.test.ts b/scripts/ios-snapshot-benchmark/proxy-client-support.test.ts new file mode 100644 index 000000000..825b81a2f --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-client-support.test.ts @@ -0,0 +1,82 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { BenchmarkCellAdmissionError } from './lifecycle.ts'; +import { openClientFixture, type AgentClient } from './proxy-client-support.ts'; +import type { ScreenFixture } from './types.ts'; + +const alertFixture: ScreenFixture = { + id: 'alert', + label: 'Native alert', + app: 'com.callstack.agentdevicelab', + anchorText: 'Automation lab', + postSetupAnchorText: 'Automation confirmation', + setupAction: 'open-alert', +}; + +function clientWithSnapshots(anchors: string[], calls: string[]): AgentClient { + return { + apps: { + open: async () => { + calls.push('open'); + return {}; + }, + }, + interactions: { + scroll: async () => { + calls.push('scroll'); + return {}; + }, + click: async () => { + calls.push('click'); + return {}; + }, + }, + batch: { + run: async () => { + calls.push('snapshot'); + return { + results: [ + { + step: 1, + command: 'snapshot', + ok: true, + data: { snapshot: { nodes: [{ label: anchors.shift() ?? '' }] } }, + durationMs: 1, + }, + ], + total: 1, + executed: 1, + totalDurationMs: 1, + }; + }, + }, + sessions: { close: async () => ({}) }, + leases: { + allocate: async () => ({}), + release: async () => ({}), + }, + }; +} + +test('persistent-client fixture setup admits both opened and prepared anchors', async () => { + const calls: string[] = []; + await openClientFixture( + clientWithSnapshots(['Automation lab', 'Automation confirmation'], calls), + alertFixture, + 'simulator', + ); + assert.deepEqual(calls, ['open', 'snapshot', 'scroll', 'click', 'snapshot']); +}); + +test('persistent-client setup rejects a wrong prepared screen as fixture-anchor', async () => { + await assert.rejects( + () => + openClientFixture( + clientWithSnapshots(['Automation lab', 'Settings'], []), + alertFixture, + 'simulator', + ), + (error: unknown) => + error instanceof BenchmarkCellAdmissionError && error.reason === 'fixture-anchor', + ); +}); diff --git a/scripts/ios-snapshot-benchmark/proxy-client-support.ts b/scripts/ios-snapshot-benchmark/proxy-client-support.ts new file mode 100644 index 000000000..426dc027d --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-client-support.ts @@ -0,0 +1,432 @@ +import fs from 'node:fs'; +import { performance } from 'node:perf_hooks'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { buildDaemonHttpBaseUrl } from '../../src/daemon/http-contract.ts'; +import { + BenchmarkCellAdmissionError, + BenchmarkContentionError, + BenchmarkInfrastructureError, +} from './lifecycle.ts'; +import { + classifyFailure, + closeSessionAsync, + formatCliFailure, + type CliContext, + type CliResult, +} from './command.ts'; +import { + fixtureOperationFromClient, + prepareFixture, + requireFixtureAnchor, +} from './fixture-admission.ts'; +import { type NetworkConditioner, type ProxyRpcRecord } from './proxy-conditioner.ts'; +import type { ProxyStartup } from './proxy-process.ts'; +import { asRecord } from './result-values.ts'; +import type { Failure, ProxyNetwork, RawSample, ScreenFixture } from './types.ts'; + +export type AgentClient = { + apps: { open(options: Record): Promise }; + interactions: { + click(options: Record): Promise; + scroll(options: Record): Promise; + }; + batch: { run(options: Record): Promise> }; + sessions: { close(): Promise }; + leases: { + allocate(options: Record): Promise>; + release(options: Record): Promise; + }; +}; + +type BuiltAgentDeviceSdk = typeof import('../../src/sdk/index.ts'); + +export type ProxyClientOptions = { + repoRoot: string; + clientStateDir: string; + derivedPath: string; + udid: string; + proxy: ProxyStartup; + conditioner: NetworkConditioner; +}; + +export async function allocateLease( + options: Pick, + clientId: string, + runId: string, +): Promise> { + const createAgentDeviceClient = await loadBuiltClient(options.repoRoot); + const client = createAgentDeviceClient({ + daemonBaseUrl: buildDaemonHttpBaseUrl(options.conditioner.baseUrl), + daemonAuthToken: options.proxy.token, + daemonTransport: 'http', + session: `lease-${clientId}`, + tenant: 'bench', + runId, + leaseProvider: 'proxy', + clientId, + leaseBackend: 'ios-simulator', + }); + return client.leases.allocate({ + tenant: 'bench', + runId, + leaseProvider: 'proxy', + clientId, + leaseBackend: 'ios-simulator', + platform: 'ios', + target: 'mobile', + udid: options.udid, + deviceKey: `ios:mobile:${options.udid}`, + }); +} + +export async function createClient( + options: Pick, + lease: Record, + clientId: string, + runId: string, + suffix: string, +): Promise { + const createAgentDeviceClient = await loadBuiltClient(options.repoRoot); + return createAgentDeviceClient({ + stateDir: path.join(options.clientStateDir, suffix), + daemonBaseUrl: buildDaemonHttpBaseUrl(options.conditioner.baseUrl), + daemonAuthToken: options.proxy.token, + daemonTransport: 'http', + session: clientId, + tenant: 'bench', + runId, + leaseProvider: 'proxy', + clientId, + leaseBackend: 'ios-simulator', + leaseId: readRequiredString(lease, 'leaseId'), + deviceKey: readRequiredString(lease, 'deviceKey'), + }); +} + +export async function openClientFixture( + client: AgentClient, + fixture: ScreenFixture, + udid: string, +): Promise { + await client.apps.open({ + app: fixture.app, + ...(fixture.launchUrl ? { url: fixture.launchUrl } : {}), + platform: 'ios', + udid, + relaunch: true, + foreground: true, + }); + await prepareFixture(fixture, { + observe: async () => + fixtureOperationFromClient( + await client.batch.run(snapshotBatchOptions()), + 'agent-device client batch --steps snapshot', + ), + scrollToBottom: async () => + fixtureOperationFromClient( + await client.interactions.scroll({ + direction: 'bottom', + platform: 'ios', + udid, + }), + 'agent-device client scroll bottom', + ), + openAlert: async () => + fixtureOperationFromClient( + await client.interactions.click({ + target: { kind: 'selector', selector: 'id="automation-open-alert"' }, + platform: 'ios', + udid, + }), + 'agent-device client click id="automation-open-alert"', + ), + }); +} + +export async function captureClientSample( + client: AgentClient, + options: Pick & { + fixture: ScreenFixture; + network: ProxyNetwork; + }, + index: number, +): Promise { + const startedAt = new Date().toISOString(); + const started = performance.now(); + const mark = options.conditioner.mark(); + try { + const result = await client.batch.run({ + steps: [{ command: 'snapshot', input: { interactiveOnly: true } }], + }); + const record = lastRecord(options.conditioner.recordsSince(mark)); + return buildSuccessfulClientSample( + result, + options.fixture, + options.network, + record, + index, + startedAt, + started, + ); + } catch (error) { + if (error instanceof BenchmarkCellAdmissionError) throw error; + const record = lastRecord(options.conditioner.recordsSince(mark)); + return buildFailedClientSample(options.network, record, error, index, startedAt, started); + } +} + +function buildSuccessfulClientSample( + result: Record, + fixture: ScreenFixture, + network: ProxyNetwork, + record: ProxyRpcRecord | undefined, + index: number, + startedAt: string, + started: number, +): RawSample { + const first = firstClientResult(result); + const snapshot = snapshotFromClientResult(first); + const nodeCount = readNodeCount(snapshot); + const succeeded = clientSampleSucceeded(record); + if (succeeded) { + requireFixtureAnchor(result, fixture, 'sample', 'agent-device client batch --steps snapshot'); + } + return { + ...sampleTiming(index, startedAt, started), + ...daemonDurationFields(first), + ...responseFields(record), + ...nodeFields(nodeCount), + targetGeneration: targetGeneration(snapshot), + firstTree: firstTreeForClient(nodeCount), + ok: succeeded, + outlier: false, + ...clientFailureFields(network, record), + }; +} + +function firstClientResult(result: Record): Record | undefined { + return asRecord(result.results?.[0]); +} + +function snapshotFromClientResult( + first: Record | undefined, +): Record | undefined { + const data = asRecord(first?.data); + return snapshotFromData(data); +} + +function snapshotFromData( + data: Record | undefined, +): Record | undefined { + return asRecord(data?.snapshot) ?? data; +} + +function daemonDurationFields(first: Record | undefined): { + daemonDurationMs?: number; +} { + return typeof first?.durationMs === 'number' ? { daemonDurationMs: first.durationMs } : {}; +} + +function targetGeneration(snapshot: Record | undefined): number | null { + return readNumber(snapshot?.refsGeneration) ?? null; +} + +function clientSampleSucceeded(record: ProxyRpcRecord | undefined): boolean { + return record?.failed !== true; +} + +function buildFailedClientSample( + network: ProxyNetwork, + record: ProxyRpcRecord | undefined, + error: unknown, + index: number, + startedAt: string, + started: number, +): RawSample { + return { + ...sampleTiming(index, startedAt, started), + ...responseFields(record), + targetGeneration: null, + firstTree: 'not-observed', + ok: false, + outlier: false, + failure: { + ...networkFailure(network, record?.failed), + ...(error instanceof Error ? { message: error.message.slice(0, 240) } : {}), + }, + }; +} + +function sampleTiming( + index: number, + startedAt: string, + started: number, +): Pick { + return { + index: index + 1, + startedAt, + finishedAt: new Date().toISOString(), + operation: 'snapshot', + wallClockMs: performance.now() - started, + }; +} + +function responseFields(record: ProxyRpcRecord | undefined): { responseBytes?: number } { + return record ? { responseBytes: record.responseBytes } : {}; +} + +function nodeFields(nodeCount: number | undefined): { nodeCount?: number } { + return nodeCount === undefined ? {} : { nodeCount }; +} + +function readNodeCount(snapshot: Record | undefined): number | undefined { + const nodes = snapshot?.nodes; + return Array.isArray(nodes) ? nodes.length : undefined; +} + +function firstTreeForClient(nodeCount: number | undefined): RawSample['firstTree'] { + if (nodeCount === undefined) return 'not-observed'; + return nodeCount === 0 ? 'empty' : 'readable'; +} + +function clientFailureFields( + network: ProxyNetwork, + record: ProxyRpcRecord | undefined, +): { failure?: Failure } { + return record?.failed ? { failure: networkFailure(network) } : {}; +} + +export async function closeClient(client: AgentClient): Promise { + try { + await client.sessions.close(); + } catch { + return; + } +} + +export async function releaseLease( + options: Pick, + lease: Record, + clientId: string, + runId: string, +): Promise { + try { + const createAgentDeviceClient = await loadBuiltClient(options.repoRoot); + const client = createAgentDeviceClient({ + daemonBaseUrl: buildDaemonHttpBaseUrl(options.conditioner.baseUrl), + daemonAuthToken: options.proxy.token, + daemonTransport: 'http', + session: `release-${clientId}`, + tenant: 'bench', + runId, + leaseProvider: 'proxy', + clientId, + leaseBackend: 'ios-simulator', + leaseId: readRequiredString(lease, 'leaseId'), + deviceKey: readRequiredString(lease, 'deviceKey'), + }); + await client.leases.release({ + tenant: 'bench', + runId, + leaseId: readRequiredString(lease, 'leaseId'), + leaseProvider: 'proxy', + clientId, + leaseBackend: 'ios-simulator', + deviceKey: readRequiredString(lease, 'deviceKey'), + }); + } catch { + return; + } +} + +async function loadBuiltClient( + repoRoot: string, +): Promise { + const module = (await import( + pathToFileURL(path.resolve(repoRoot, 'dist/src/index.js')).href + )) as BuiltAgentDeviceSdk; + return module.createAgentDeviceClient; +} + +export function remoteFlags( + options: Pick, + lease: Record, + clientId: string, + runId: string, + stateDir: string, +): string[] { + const remoteConfigPath = path.join(stateDir, 'proxy-connection.json'); + fs.mkdirSync(stateDir, { recursive: true }); + fs.writeFileSync( + remoteConfigPath, + `${JSON.stringify( + { + daemonBaseUrl: buildDaemonHttpBaseUrl(options.conditioner.baseUrl), + daemonTransport: 'http', + tenant: 'bench', + sessionIsolation: 'tenant', + runId, + leaseId: readRequiredString(lease, 'leaseId'), + leaseBackend: 'ios-simulator', + leaseProvider: 'proxy', + clientId, + deviceKey: readRequiredString(lease, 'deviceKey'), + platform: 'apple', + target: 'mobile', + }, + null, + 2, + )}\n`, + 'utf8', + ); + return [ + '--daemon-base-url', + buildDaemonHttpBaseUrl(options.conditioner.baseUrl), + '--daemon-auth-token', + options.proxy.token, + '--daemon-transport', + 'http', + '--platform', + 'apple', + '--remote-config', + remoteConfigPath, + ]; +} + +export async function closeCliSession(context: CliContext): Promise { + await closeSessionAsync(context); +} + +export function setupFailure(operation: string, result: CliResult): BenchmarkInfrastructureError { + const failure = classifyFailure(result.payload, result); + const message = formatCliFailure(operation, failure, result); + if (failure.code === 'DEVICE_IN_USE') throw new BenchmarkContentionError(message, operation); + return new BenchmarkInfrastructureError(message, operation); +} + +function networkFailure(network: ProxyNetwork, failed = true): Failure { + return { + category: failed && network.packetLossPercent > 0 ? 'packet-loss' : 'upstream', + }; +} + +function lastRecord(records: ProxyRpcRecord[]): ProxyRpcRecord | undefined { + return records.at(-1); +} + +function readRequiredString(value: Record, key: string): string { + const result = value[key]; + if (typeof result !== 'string' || result.length === 0) { + throw new BenchmarkInfrastructureError(`Lease did not contain ${key}.`); + } + return result; +} + +function readNumber(value: unknown): number | undefined { + return typeof value === 'number' && Number.isFinite(value) ? value : undefined; +} + +function snapshotBatchOptions(): Record { + return { steps: [{ command: 'snapshot', input: { interactiveOnly: true } }] }; +} diff --git a/scripts/ios-snapshot-benchmark/proxy-client.ts b/scripts/ios-snapshot-benchmark/proxy-client.ts new file mode 100644 index 000000000..6983636da --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-client.ts @@ -0,0 +1,192 @@ +import path from 'node:path'; +import { + openFixtureAsync, + pressFixtureTargetAsync, + sampleFromCli, + scrollFixtureSetupAsync, + snapshotFixtureAsync, +} from './command.ts'; +import { buildMeasurement } from './statistics.ts'; +import { + fixtureOperationFromCli, + prepareFixture, + requireFixtureAnchor, +} from './fixture-admission.ts'; +import { + allocateLease, + captureClientSample, + closeCliSession, + closeClient, + createClient, + openClientFixture, + releaseLease, + remoteFlags, + setupFailure, + type AgentClient, +} from './proxy-client-support.ts'; +import type { NetworkConditioner } from './proxy-conditioner.ts'; +import type { ProxyStartup } from './proxy-process.ts'; +import type { Measurement, ProxyNetwork, RawSample, ScreenFixture } from './types.ts'; + +export type ProxyMeasurementOptions = { + repoRoot: string; + clientStateDir: string; + derivedPath: string; + udid: string; + samples: number; + fixture: ScreenFixture; + network: ProxyNetwork; + proxy: ProxyStartup; + conditioner: NetworkConditioner; +}; + +export async function runPersistentMeasurement( + options: ProxyMeasurementOptions, +): Promise { + const { clientId, runId } = measurementIdentity(options, 'persistent'); + const lease = await allocateLease(options, clientId, runId); + let client: AgentClient | undefined; + const samples: RawSample[] = []; + try { + client = await createClient(options, lease, clientId, runId, 'persistent'); + await openClientFixture(client, options.fixture, options.udid); + for (let index = 0; index < options.samples; index += 1) { + samples.push(await captureClientSample(client, options, index)); + } + } finally { + if (client) await closeClient(client); + await releaseLease(options, lease, clientId, runId); + } + return buildMeasurement({ + transport: 'proxy', + execution: 'persistent-client', + state: 'warm', + screen: options.fixture.id, + sampleMinimum: options.samples >= 20 ? 20 : 10, + operation: 'snapshot', + samples, + network: options.network, + }); +} + +export async function runFreshCliMeasurement( + options: ProxyMeasurementOptions, +): Promise { + const { clientId, runId } = measurementIdentity(options, 'cli'); + const lease = await allocateLease(options, clientId, runId); + try { + return await measureFreshCli(options, lease, clientId, runId); + } finally { + await releaseLease(options, lease, clientId, runId); + } +} + +async function measureFreshCli( + options: ProxyMeasurementOptions, + lease: Record, + clientId: string, + runId: string, +): Promise { + const context = freshCliContext(options, lease, clientId, runId); + try { + const samples = await collectFreshCliSamples(context, options); + return buildMeasurement({ + transport: 'proxy', + execution: 'fresh-process-cli', + state: 'warm', + screen: options.fixture.id, + sampleMinimum: options.samples >= 20 ? 20 : 10, + operation: 'snapshot', + samples, + network: options.network, + }); + } finally { + await closeCliSession(context); + } +} + +function freshCliContext( + options: ProxyMeasurementOptions, + lease: Record, + clientId: string, + runId: string, +) { + const stateDir = path.join( + options.clientStateDir, + `cli-${options.fixture.id}-${options.network.rttMs}`, + ); + return { + repoRoot: options.repoRoot, + stateDir, + session: `bench-cli-${options.fixture.id}-${options.network.rttMs}`, + udid: options.udid, + derivedPath: options.derivedPath, + extraFlags: remoteFlags(options, lease, clientId, runId, stateDir), + }; +} + +async function collectFreshCliSamples( + context: ReturnType, + options: ProxyMeasurementOptions, +): Promise { + const opened = await openFixtureAsync(context, options.fixture, { relaunch: true }); + if (!opened.ok) throw setupFailure('fresh CLI open', opened); + await prepareFreshCliFixture(context, options.fixture); + const samples: RawSample[] = []; + for (let index = 0; index < options.samples; index += 1) { + const mark = options.conditioner.mark(); + const result = await snapshotFixtureAsync(context); + if (result.ok) { + requireFixtureAnchor( + result.payload, + options.fixture, + 'sample', + 'agent-device batch --steps snapshot', + ); + } + samples.push(sampleFromProxyCli(result, options.conditioner, mark, index)); + } + return samples; +} + +async function prepareFreshCliFixture( + context: ReturnType, + fixture: ScreenFixture, +): Promise { + await prepareFixture(fixture, { + observe: async () => + fixtureOperationFromCli( + await snapshotFixtureAsync(context), + 'agent-device batch --steps snapshot', + ), + scrollToBottom: async () => + fixtureOperationFromCli(await scrollFixtureSetupAsync(context), 'agent-device scroll bottom'), + openAlert: async () => + fixtureOperationFromCli( + await pressFixtureTargetAsync(context, 'id="automation-open-alert"'), + 'agent-device click id="automation-open-alert"', + ), + }); +} + +function sampleFromProxyCli( + result: Awaited>, + conditioner: NetworkConditioner, + mark: number, + index: number, +): RawSample { + const record = conditioner.recordsSince(mark).at(-1); + return { + ...sampleFromCli(result, 'snapshot', index, record?.responseBytes), + }; +} + +function measurementIdentity( + options: Pick, + kind: 'persistent' | 'cli', +): { clientId: string; runId: string } { + return { + clientId: `bench-${kind}-${options.fixture.id}-${options.network.rttMs}`, + runId: `bench-${options.fixture.id}-${options.network.rttMs}-${kind}`, + }; +} diff --git a/scripts/ios-snapshot-benchmark/proxy-conditioner.test.ts b/scripts/ios-snapshot-benchmark/proxy-conditioner.test.ts new file mode 100644 index 000000000..d5ef712ab --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-conditioner.test.ts @@ -0,0 +1,73 @@ +import assert from 'node:assert/strict'; +import http from 'node:http'; +import { test } from 'vitest'; +import { createNetworkConditioner } from './proxy-conditioner.ts'; + +test('forwards an RPC response and records exact body bytes at zero loss', async () => { + const upstream = http.createServer((request, response) => { + request.resume(); + request.on('end', () => { + response.setHeader('content-type', 'application/json'); + response.end('{"result":{"ok":true}}'); + }); + }); + await new Promise((resolve) => upstream.listen(0, '127.0.0.1', resolve)); + const address = upstream.address(); + assert.ok(address && typeof address !== 'string'); + const conditioner = await createNetworkConditioner({ + upstreamBaseUrl: `http://127.0.0.1:${address.port}`, + network: { rttMs: 0, bandwidthKbps: null, packetLossPercent: 0, seed: 1 }, + }); + try { + const response = await fetch(`${conditioner.baseUrl}/agent-device/rpc`, { + method: 'POST', + body: '{"request":true}', + }); + assert.equal(await response.text(), '{"result":{"ok":true}}'); + assert.deepEqual(conditioner.recordsSince(0), [ + { + sequence: 1, + requestBytes: 16, + responseBytes: 22, + status: 200, + failed: false, + }, + ]); + } finally { + await conditioner.close(); + await new Promise((resolve, reject) => + upstream.close((error) => (error ? reject(error) : resolve())), + ); + } +}); + +test('rejects non-loopback upstreams before binding the conditioner', async () => { + await assert.rejects( + createNetworkConditioner({ + upstreamBaseUrl: 'https://example.com:443', + network: { rttMs: 0, bandwidthKbps: null, packetLossPercent: 0, seed: 1 }, + }), + /must be an HTTP 127\.0\.0\.1 URL with a port/, + ); +}); + +test('does not forward unsupported paths upstream', async () => { + const upstream = http.createServer((_request, response) => response.end('unexpected')); + await new Promise((resolve) => upstream.listen(0, '127.0.0.1', resolve)); + const address = upstream.address(); + assert.ok(address && typeof address !== 'string'); + const conditioner = await createNetworkConditioner({ + upstreamBaseUrl: `http://127.0.0.1:${address.port}`, + network: { rttMs: 0, bandwidthKbps: null, packetLossPercent: 0, seed: 1 }, + }); + try { + const response = await fetch(`${conditioner.baseUrl}/unsupported`); + assert.equal(response.status, 404); + assert.equal(await response.text(), 'Not found'); + } finally { + await conditioner.close(); + await new Promise((resolve, reject) => + upstream.close((error) => (error ? reject(error) : resolve())), + ); + } +}); diff --git a/scripts/ios-snapshot-benchmark/proxy-conditioner.ts b/scripts/ios-snapshot-benchmark/proxy-conditioner.ts new file mode 100644 index 000000000..df8ebebe8 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-conditioner.ts @@ -0,0 +1,263 @@ +import http, { type IncomingMessage, type ServerResponse } from 'node:http'; +import type { AddressInfo } from 'node:net'; +import { setTimeout as delay } from 'node:timers/promises'; +import type { ProxyNetwork } from './types.ts'; + +export type ProxyRpcRecord = { + sequence: number; + requestBytes: number; + responseBytes: number; + status: number; + failed: boolean; +}; + +export type NetworkConditioner = { + baseUrl: string; + network: ProxyNetwork; + mark(): number; + recordsSince(mark: number): ProxyRpcRecord[]; + close(): Promise; +}; + +const UPSTREAM_FAILURE_BODY = JSON.stringify({ error: 'upstream request failed' }); +const RPC_PATH = '/agent-device/rpc'; +const HEALTH_PATH = '/agent-device/health'; + +type ConditionerPath = typeof RPC_PATH | typeof HEALTH_PATH; + +type RequestContext = { + path: ConditionerPath; + method: string; + headers: IncomingMessage['headers']; + isRpc: boolean; + sequence: number; + body: Buffer; +}; + +export async function createNetworkConditioner(options: { + upstreamBaseUrl: string; + network: ProxyNetwork; +}): Promise { + const records: ProxyRpcRecord[] = []; + const upstreamPort = readLocalUpstreamPort(options.upstreamBaseUrl); + let randomState = options.network.seed >>> 0; + const server = http.createServer((request, response) => { + void forwardRequest( + request, + response, + { upstreamPort, network: options.network }, + records, + () => { + randomState = nextRandom(randomState); + return randomState / 0x1_0000_0000; + }, + ); + }); + await listen(server); + const address = server.address(); + if (!address || typeof address === 'string') { + throw new Error('Network conditioner did not bind to a TCP address.'); + } + return { + baseUrl: `http://127.0.0.1:${(address as AddressInfo).port}`, + network: options.network, + mark: () => records.length, + recordsSince: (mark) => records.slice(mark).map((record) => ({ ...record })), + close: () => closeServer(server), + }; +} + +async function forwardRequest( + request: IncomingMessage, + response: ServerResponse, + options: { upstreamPort: string; network: ProxyNetwork }, + records: ProxyRpcRecord[], + random: () => number, +): Promise { + const context = await readRequestContext(request, records); + if (!context) { + response.statusCode = 404; + response.end('Not found'); + return; + } + if (dropRequest(context, response, options.network, records, random)) return; + await waitForNetwork(options.network, context.body.byteLength); + try { + await sendRequest(context, response, options, records); + } catch { + writeUpstreamFailure(context, response, records); + } +} + +async function readRequestContext( + request: IncomingMessage, + records: ProxyRpcRecord[], +): Promise { + const requestUrl = new URL(request.url ?? '/', 'http://conditioner.invalid'); + const path = resolveConditionerPath(requestUrl); + if (!path) return null; + return { + path, + method: request.method ?? 'GET', + headers: request.headers, + isRpc: path === RPC_PATH, + sequence: path === RPC_PATH ? records.length + 1 : 0, + body: await readBody(request), + }; +} + +function dropRequest( + context: RequestContext, + response: ServerResponse, + network: ProxyNetwork, + records: ProxyRpcRecord[], + random: () => number, +): boolean { + if (!isDropped(network.packetLossPercent, random)) return false; + if (context.isRpc) recordFailure(context, records); + response.destroy(); + return true; +} + +async function sendRequest( + context: RequestContext, + response: ServerResponse, + options: { upstreamPort: string; network: ProxyNetwork }, + records: ProxyRpcRecord[], +): Promise { + const upstream = await fetch(buildTargetUrl(options.upstreamPort, context.path), { + method: context.method, + headers: forwardHeaders(context.headers), + ...(context.body.byteLength > 0 ? { body: context.body, duplex: 'half' } : {}), + }); + const body = Buffer.from(await upstream.arrayBuffer()); + await waitForNetwork(options.network, body.byteLength); + response.statusCode = upstream.status; + copyHeader(response, 'content-type', upstream); + copyHeader(response, 'x-request-id', upstream); + if (context.isRpc) { + records.push({ + sequence: context.sequence, + requestBytes: context.body.byteLength, + responseBytes: body.byteLength, + status: upstream.status, + failed: !upstream.ok, + }); + } + response.end(body); +} + +function writeUpstreamFailure( + context: RequestContext, + response: ServerResponse, + records: ProxyRpcRecord[], +): void { + if (context.isRpc) recordFailure(context, records); + response.statusCode = 502; + response.setHeader('content-type', 'application/json'); + response.end(UPSTREAM_FAILURE_BODY); +} + +function recordFailure(context: RequestContext, records: ProxyRpcRecord[]): void { + records.push({ + sequence: context.sequence, + requestBytes: context.body.byteLength, + responseBytes: 0, + status: 0, + failed: true, + }); +} + +function copyHeader(response: ServerResponse, name: string, upstream: Response): void { + const value = upstream.headers.get(name); + if (value) response.setHeader(name, value); +} + +function buildTargetUrl(upstreamPort: string, path: ConditionerPath): string { + const upstreamPath = path === RPC_PATH ? RPC_PATH : HEALTH_PATH; + return `http://127.0.0.1:${upstreamPort}${upstreamPath}`; +} + +function resolveConditionerPath(requestUrl: URL): ConditionerPath | undefined { + if (requestUrl.search.length > 0) return undefined; + if (requestUrl.pathname === RPC_PATH) return RPC_PATH; + if (requestUrl.pathname === HEALTH_PATH) return HEALTH_PATH; + return undefined; +} + +function readLocalUpstreamPort(upstreamBaseUrl: string): string { + const base = new URL(upstreamBaseUrl); + const validBase = [ + base.protocol === 'http:', + base.hostname === '127.0.0.1', + base.port.length > 0, + base.username.length === 0, + base.password.length === 0, + base.pathname === '/', + base.search.length === 0, + base.hash.length === 0, + ].every(Boolean); + if (!validBase) { + throw new Error('Network conditioner upstream must be an HTTP 127.0.0.1 URL with a port.'); + } + const port = Number(base.port); + if (!Number.isInteger(port) || port < 1 || port > 65_535) { + throw new Error('Network conditioner upstream port must be between 1 and 65535.'); + } + return String(port); +} + +function forwardHeaders(headers: IncomingMessage['headers']): Headers { + const forwarded = new Headers(); + for (const [name, value] of Object.entries(headers)) { + if ( + value === undefined || + ['connection', 'content-length', 'host', 'transfer-encoding'].includes(name) + ) { + continue; + } + forwarded.set(name, Array.isArray(value) ? value.join(', ') : value); + } + return forwarded; +} + +function readBody(request: IncomingMessage): Promise { + return new Promise((resolve, reject) => { + const chunks: Buffer[] = []; + request.on('data', (chunk: Buffer | string) => + chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)), + ); + request.on('end', () => resolve(Buffer.concat(chunks))); + request.on('error', reject); + }); +} + +async function waitForNetwork(network: ProxyNetwork, bytes: number): Promise { + const bandwidthDelay = network.bandwidthKbps ? (bytes * 8) / network.bandwidthKbps : 0; + const totalDelay = network.rttMs / 2 + bandwidthDelay; + if (totalDelay > 0) await delay(totalDelay); +} + +function isDropped(packetLossPercent: number, random: () => number): boolean { + return packetLossPercent > 0 && random() * 100 < packetLossPercent; +} + +function nextRandom(value: number): number { + return (value * 1_664_525 + 1_013_904_223) >>> 0; +} + +function listen(server: http.Server): Promise { + return new Promise((resolve, reject) => { + server.once('error', reject); + server.listen(0, '127.0.0.1', () => { + server.off('error', reject); + resolve(); + }); + }); +} + +function closeServer(server: http.Server): Promise { + return new Promise((resolve, reject) => + server.close((error) => (error ? reject(error) : resolve())), + ); +} diff --git a/scripts/ios-snapshot-benchmark/proxy-process.ts b/scripts/ios-snapshot-benchmark/proxy-process.ts new file mode 100644 index 000000000..c76653bfc --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-process.ts @@ -0,0 +1,112 @@ +import { spawn } from 'node:child_process'; +import { BenchmarkInfrastructureError, stopDaemon } from './lifecycle.ts'; +import { findProxyStartup, type ProxyStartup } from './proxy-startup.ts'; + +export type ProxyProcess = ProxyStartup & { stop(): Promise }; + +export async function startProxy(repoRoot: string, stateDir: string): Promise { + const token = `bench-${process.pid}-${Date.now()}`; + const child = spawn( + process.execPath, + [ + 'bin/agent-device.mjs', + 'proxy', + '--state-dir', + stateDir, + '--daemon-auth-token', + token, + '--json', + ], + { + cwd: repoRoot, + env: { ...process.env, AGENT_DEVICE_NO_UPDATE_NOTIFIER: '1' }, + stdio: ['ignore', 'pipe', 'pipe'], + }, + ); + let stderr = ''; + child.stderr?.on('data', (chunk: Buffer) => { + stderr += chunk.toString(); + }); + try { + const startup = await readProxyStartup(child, () => stderr); + let stopPromise: Promise | undefined; + return { + ...startup, + stop: () => (stopPromise ??= stopProxyProcess(child, repoRoot, stateDir)), + }; + } catch (error) { + await terminateChild(child); + throw error; + } +} + +function readProxyStartup( + child: ReturnType, + getStderr: () => string, +): Promise { + return new Promise((resolve, reject) => { + let output = ''; + const timer = setTimeout(() => { + reject( + new BenchmarkInfrastructureError( + `Proxy did not publish startup metadata: ${getStderr().trim() || output.trim()}`, + 'agent-device proxy --json', + ), + ); + child.kill('SIGTERM'); + }, 60_000); + child.stdout?.on('data', (chunk: Buffer) => { + output += chunk.toString(); + const startup = findProxyStartup(output); + if (!startup) return; + clearTimeout(timer); + resolve(startup); + }); + child.once('error', (error) => { + clearTimeout(timer); + reject(error); + }); + child.once('exit', (code, signal) => { + if (isCleanExit(code, signal)) return; + clearTimeout(timer); + reject( + new BenchmarkInfrastructureError( + `Proxy exited before startup: ${getStderr().trim() || `exit ${String(code)}`}`, + 'agent-device proxy --json', + ), + ); + }); + }); +} + +async function stopProxyProcess( + child: ReturnType, + repoRoot: string, + stateDir: string, +): Promise { + await terminateChild(child); + stopDaemon(repoRoot, stateDir); +} + +async function terminateChild(child: ReturnType): Promise { + if (child.exitCode === null) child.kill('SIGTERM'); + await waitForExit(child); +} + +function isCleanExit(code: number | null, signal: NodeJS.Signals | null): boolean { + return code === 0 && signal === null; +} + +function waitForExit(child: ReturnType): Promise { + if (child.exitCode !== null) return Promise.resolve(); + return new Promise((resolve) => { + const timer = setTimeout(() => { + child.kill('SIGKILL'); + resolve(); + }, 10_000); + child.once('exit', () => { + clearTimeout(timer); + resolve(); + }); + }); +} diff --git a/scripts/ios-snapshot-benchmark/proxy-runner.ts b/scripts/ios-snapshot-benchmark/proxy-runner.ts new file mode 100644 index 000000000..01d4b8521 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-runner.ts @@ -0,0 +1,52 @@ +import { createNetworkConditioner } from './proxy-conditioner.ts'; +import { runFreshCliMeasurement, runPersistentMeasurement } from './proxy-client.ts'; +import { startProxy } from './proxy-process.ts'; +import type { Measurement, ProxyNetwork, ScreenFixture } from './types.ts'; + +export async function runProxyMeasurements(options: { + repoRoot: string; + stateDir: string; + clientStateDir: string; + derivedPath: string; + udid: string; + fixtures: ScreenFixture[]; + samples: number; + rtts: readonly number[]; + bandwidthKbps: number | null; + packetLossPercent: number; + seed: number; +}): Promise<{ measurements: Measurement[]; networks: ProxyNetwork[] }> { + const proxy = await startProxy(options.repoRoot, options.stateDir); + const measurements: Measurement[] = []; + const networks: ProxyNetwork[] = []; + try { + for (const rttMs of options.rtts) { + const network: ProxyNetwork = { + rttMs: rttMs as ProxyNetwork['rttMs'], + bandwidthKbps: options.bandwidthKbps, + packetLossPercent: options.packetLossPercent, + seed: options.seed + rttMs, + }; + networks.push(network); + const conditioner = await createNetworkConditioner({ + upstreamBaseUrl: proxy.proxyBaseUrl, + network, + }); + try { + for (const fixture of options.fixtures) { + measurements.push( + await runPersistentMeasurement({ ...options, proxy, conditioner, fixture, network }), + ); + measurements.push( + await runFreshCliMeasurement({ ...options, proxy, conditioner, fixture, network }), + ); + } + } finally { + await conditioner.close(); + } + } + return { measurements, networks }; + } finally { + await proxy.stop(); + } +} diff --git a/scripts/ios-snapshot-benchmark/proxy-startup.test.ts b/scripts/ios-snapshot-benchmark/proxy-startup.test.ts new file mode 100644 index 000000000..d9af6aef7 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-startup.test.ts @@ -0,0 +1,32 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { findProxyStartup, type ProxyStartup } from './proxy-startup.ts'; + +const startup: ProxyStartup = { + proxyBaseUrl: 'http://127.0.0.1:49152', + agentDeviceBaseUrl: 'http://127.0.0.1:49152/agent-device', + token: 'benchmark-token', + stateDir: '/tmp/agent-device-benchmark/proxy', +}; + +test('findProxyStartup accepts the CLI pretty JSON envelope', () => { + assert.deepEqual( + findProxyStartup(JSON.stringify({ success: true, data: startup }, null, 2)), + startup, + ); +}); + +test('findProxyStartup accepts a complete line-delimited envelope', () => { + assert.deepEqual( + findProxyStartup(`noise\n${JSON.stringify({ success: true, data: startup })}`), + startup, + ); +}); + +test('findProxyStartup ignores incomplete or unrelated output', () => { + assert.equal(findProxyStartup('{"success":true'), undefined); + assert.equal( + findProxyStartup(JSON.stringify({ success: true, data: { token: startup.token } })), + undefined, + ); +}); diff --git a/scripts/ios-snapshot-benchmark/proxy-startup.ts b/scripts/ios-snapshot-benchmark/proxy-startup.ts new file mode 100644 index 000000000..78d6c20d3 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/proxy-startup.ts @@ -0,0 +1,41 @@ +import { asRecord, readString } from './result-values.ts'; + +export type ProxyStartup = { + proxyBaseUrl: string; + agentDeviceBaseUrl: string; + token: string; + stateDir: string; +}; + +export function findProxyStartup(output: string): ProxyStartup | undefined { + const wholeOutput = parseProxyStartup(output); + if (wholeOutput) return wholeOutput; + for (const line of output.split('\n')) { + const startup = parseProxyStartup(line); + if (startup) return startup; + } + return undefined; +} + +function parseProxyStartup(value: string): ProxyStartup | undefined { + const record = asRecord(asRecord(parseJson(value))?.data); + if (!record) return undefined; + const values = ['proxyBaseUrl', 'agentDeviceBaseUrl', 'token', 'stateDir'].map((key) => + readString(record[key]), + ); + if (values.some((value) => value === undefined)) return undefined; + return { + proxyBaseUrl: values[0]!, + agentDeviceBaseUrl: values[1]!, + token: values[2]!, + stateDir: values[3]!, + }; +} + +function parseJson(value: string): unknown { + try { + return JSON.parse(value.trim()); + } catch { + return undefined; + } +} diff --git a/scripts/ios-snapshot-benchmark/raw-result.schema.v1.json b/scripts/ios-snapshot-benchmark/raw-result.schema.v1.json new file mode 100644 index 000000000..94c1c3df2 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/raw-result.schema.v1.json @@ -0,0 +1,367 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://github.com/callstack/agent-device/blob/main/scripts/ios-snapshot-benchmark/raw-result.schema.v1.json", + "title": "agent-device iOS snapshot convergence raw result", + "type": "object", + "additionalProperties": false, + "required": [ + "schemaVersion", + "issue", + "parent", + "references", + "runId", + "generatedAt", + "revision", + "toolchain", + "host", + "target", + "config", + "status", + "measurements", + "packageSize", + "deepButtonEvidence" + ], + "properties": { + "schemaVersion": { "const": "ios-snapshot-convergence.v1" }, + "issue": { "const": "#2189" }, + "parent": { "const": "#2188" }, + "references": { + "type": "object", + "additionalProperties": false, + "required": ["deepButton", "appMount"], + "properties": { + "deepButton": { "const": "#1626" }, + "appMount": { "const": "#1571" } + } + }, + "runId": { "type": "string", "minLength": 1 }, + "generatedAt": { "type": "string", "minLength": 1 }, + "revision": { + "type": "object", + "additionalProperties": false, + "required": ["commit", "branch", "dirty"], + "properties": { + "commit": { "type": "string", "minLength": 1 }, + "branch": { "type": "string", "minLength": 1 }, + "dirty": { "type": "boolean" } + } + }, + "toolchain": { + "type": "object", + "additionalProperties": false, + "required": ["node", "pnpm", "xcode", "simctl", "os", "arch"], + "properties": { + "node": { "type": "string", "minLength": 1 }, + "pnpm": { "type": "string", "minLength": 1 }, + "xcode": { "type": "string", "minLength": 1 }, + "simctl": { "type": "string", "minLength": 1 }, + "os": { "type": "string", "minLength": 1 }, + "arch": { "type": "string", "minLength": 1 } + } + }, + "host": { + "type": "object", + "additionalProperties": false, + "required": ["model", "modelIdentifier", "cpu", "cpuCores"], + "properties": { + "model": { "type": "string", "minLength": 1 }, + "modelIdentifier": { "type": "string", "minLength": 1 }, + "cpu": { "type": "string", "minLength": 1 }, + "cpuCores": { "type": "integer", "minimum": 1 } + } + }, + "target": { + "type": "object", + "additionalProperties": false, + "required": ["platform", "kind", "udid", "name", "runtime", "appId"], + "properties": { + "platform": { "const": "ios" }, + "kind": { "const": "simulator" }, + "udid": { "type": "string", "minLength": 1 }, + "name": { "type": "string", "minLength": 1 }, + "runtime": { "type": "string", "minLength": 1 }, + "appId": { "type": "string", "minLength": 1 }, + "appPath": { "type": "string", "minLength": 1 } + } + }, + "config": { + "type": "object", + "additionalProperties": false, + "required": [ + "warmSampleMinimum", + "coldSampleMinimum", + "requestedSamples", + "screens", + "states" + ], + "properties": { + "warmSampleMinimum": { "type": "integer", "minimum": 1 }, + "coldSampleMinimum": { "type": "integer", "minimum": 1 }, + "requestedSamples": { "type": "integer", "minimum": 1 }, + "screens": { + "type": "array", + "minItems": 1, + "items": { + "type": "string", + "enum": ["quiet", "list", "nested-scroll", "alert", "system-surface", "xctest-stress"] + } + }, + "states": { + "type": "array", + "minItems": 1, + "items": { "type": "string", "enum": ["cold-cold", "cold", "warm", "relaunch"] } + } + } + }, + "status": { "type": "string", "enum": ["completed", "stopped"] }, + "measurements": { + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "transport", + "execution", + "state", + "screen", + "sampleMinimum", + "operation", + "samples", + "wallClockMs", + "daemonDurationMs", + "responseBytes", + "failures", + "failureCategories" + ], + "properties": { + "transport": { "type": "string", "enum": ["local", "proxy"] }, + "execution": { "type": "string", "enum": ["fresh-process-cli", "persistent-client"] }, + "state": { "type": "string", "enum": ["cold-cold", "cold", "warm", "relaunch"] }, + "screen": { + "type": "string", + "enum": ["quiet", "list", "nested-scroll", "alert", "system-surface", "xctest-stress"] + }, + "sampleMinimum": { "type": "integer", "minimum": 1 }, + "operation": { + "type": "string", + "enum": ["open-foreground", "snapshot", "relaunch-foreground"] + }, + "samples": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/sample" } }, + "wallClockMs": { "$ref": "#/$defs/summaryOrNull" }, + "daemonDurationMs": { "$ref": "#/$defs/summaryOrNull" }, + "responseBytes": { "$ref": "#/$defs/summaryOrNull" }, + "network": { "$ref": "#/$defs/proxyNetwork" }, + "failures": { "type": "integer", "minimum": 0 }, + "failureCategories": { + "type": "object", + "additionalProperties": { "type": "integer", "minimum": 1 } + } + } + } + }, + "proxyNetworks": { + "type": "array", + "items": { "$ref": "#/$defs/proxyNetwork" } + }, + "stop": { + "type": "object", + "additionalProperties": false, + "required": ["category", "message"], + "properties": { + "category": { "type": "string", "enum": ["infrastructure", "contention", "configuration"] }, + "message": { "type": "string", "minLength": 1 }, + "reason": { "type": "string", "enum": ["cell-state", "fixture-anchor", "derived-path"] }, + "command": { "type": "string", "minLength": 1 } + } + }, + "packageSize": { + "type": "object", + "additionalProperties": false, + "required": ["status", "revision"], + "properties": { + "status": { "type": "string", "enum": ["measured", "not-run"] }, + "revision": { "type": "string", "minLength": 1 }, + "packed": { "$ref": "#/$defs/sizePair" }, + "cleanInstalled": { + "type": "object", + "additionalProperties": false, + "required": ["packageBytes", "files"], + "properties": { + "packageBytes": { "type": "integer", "minimum": 0 }, + "files": { "type": "integer", "minimum": 0 } + } + }, + "bundled": { + "type": "object", + "additionalProperties": false, + "required": ["rawBytes", "gzipBytes", "files"], + "properties": { + "rawBytes": { "type": "integer", "minimum": 0 }, + "gzipBytes": { "type": "integer", "minimum": 0 }, + "files": { "type": "integer", "minimum": 0 } + } + } + } + }, + "deepButtonEvidence": { "$ref": "#/$defs/deepButtonEvidence" } + }, + "$defs": { + "proxyNetwork": { + "type": "object", + "additionalProperties": false, + "required": ["rttMs", "bandwidthKbps", "packetLossPercent", "seed"], + "properties": { + "rttMs": { "type": "integer", "enum": [0, 20, 80] }, + "bandwidthKbps": { "type": ["integer", "null"], "minimum": 1 }, + "packetLossPercent": { "type": "number", "minimum": 0, "maximum": 100 }, + "seed": { "type": "integer", "minimum": 0 } + } + }, + "summaryOrNull": { + "type": ["object", "null"], + "additionalProperties": false, + "required": ["n", "min", "median", "p95", "max", "outlierCount", "outlierRule"], + "properties": { + "n": { "type": "integer", "minimum": 1 }, + "min": { "type": "number", "minimum": 0 }, + "median": { "type": "number", "minimum": 0 }, + "p95": { "type": "number", "minimum": 0 }, + "max": { "type": "number", "minimum": 0 }, + "outlierCount": { "type": "integer", "minimum": 0 }, + "outlierRule": { "const": "tukey-1.5-iqr" } + } + }, + "sample": { + "type": "object", + "additionalProperties": false, + "required": [ + "index", + "startedAt", + "finishedAt", + "operation", + "wallClockMs", + "targetGeneration", + "firstTree", + "ok", + "outlier" + ], + "properties": { + "index": { "type": "integer", "minimum": 1 }, + "startedAt": { "type": "string", "minLength": 1 }, + "finishedAt": { "type": "string", "minLength": 1 }, + "operation": { + "type": "string", + "enum": ["open-foreground", "snapshot", "relaunch-foreground"] + }, + "wallClockMs": { "type": "number", "minimum": 0 }, + "daemonDurationMs": { "type": "number", "minimum": 0 }, + "responseBytes": { "type": "integer", "minimum": 0 }, + "nodeCount": { "type": "integer", "minimum": 0 }, + "targetGeneration": { "type": ["integer", "null"], "minimum": 0 }, + "firstTree": { + "type": "string", + "enum": ["readable", "empty", "unreadable", "not-observed"] + }, + "ok": { "type": "boolean" }, + "outlier": { "type": "boolean" }, + "failure": { "$ref": "#/$defs/failure" } + } + }, + "failure": { + "type": "object", + "additionalProperties": false, + "required": ["category"], + "properties": { + "category": { + "type": "string", + "enum": [ + "app-mount", + "bridge", + "runner", + "timeout", + "stale-generation", + "packet-loss", + "upstream", + "other" + ] + }, + "code": { "type": "string", "minLength": 1 }, + "reason": { "type": "string", "minLength": 1 }, + "message": { "type": "string", "minLength": 1 } + } + }, + "sizePair": { + "type": "object", + "additionalProperties": false, + "required": ["tarballBytes", "unpackedBytes"], + "properties": { + "tarballBytes": { "type": "integer", "minimum": 0 }, + "unpackedBytes": { "type": "integer", "minimum": 0 } + } + }, + "deepButtonEvidence": { + "type": "object", + "additionalProperties": false, + "required": [ + "issue", + "fixture", + "artifact", + "depth", + "changedDescendant", + "invalidShallowRule", + "safeFullRule", + "before", + "after" + ], + "properties": { + "issue": { "const": "#1626" }, + "fixture": { "const": "deep-button-v1" }, + "artifact": { "const": "deep-button-fixture.v1.json" }, + "depth": { "type": "integer", "minimum": 1 }, + "changedDescendant": { "const": "deep-button-state" }, + "invalidShallowRule": { "$ref": "#/$defs/control" }, + "safeFullRule": { "$ref": "#/$defs/control" }, + "before": { "$ref": "#/$defs/observation" }, + "after": { "$ref": "#/$defs/observation" } + } + }, + "control": { + "type": "object", + "additionalProperties": false, + "required": ["command", "exitCode", "assertion"], + "properties": { + "command": { "type": "string", "minLength": 1 }, + "exitCode": { "type": "integer", "minimum": 0 }, + "assertion": { "type": "string", "minLength": 1 } + } + }, + "observation": { + "type": "object", + "additionalProperties": false, + "required": [ + "depth", + "surfaceDigest", + "fullDigest", + "state", + "surfaceNodeIds", + "fullNodeIds" + ], + "properties": { + "depth": { "type": "integer", "minimum": 1 }, + "surfaceDigest": { "type": "string", "minLength": 1 }, + "fullDigest": { "type": "string", "minLength": 1 }, + "state": { "type": "string", "enum": ["off", "on"] }, + "surfaceNodeIds": { + "type": "array", + "minItems": 1, + "items": { "type": "string", "minLength": 1 } + }, + "fullNodeIds": { + "type": "array", + "minItems": 1, + "items": { "type": "string", "minLength": 1 } + } + } + } + } +} diff --git a/scripts/ios-snapshot-benchmark/report.ts b/scripts/ios-snapshot-benchmark/report.ts new file mode 100644 index 000000000..11fc05e03 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/report.ts @@ -0,0 +1,110 @@ +import type { BenchmarkResult, Measurement, PackageSize, Summary } from './types.ts'; + +export function renderBenchmarkMarkdown(result: BenchmarkResult): string { + const lines = [ + '# iOS snapshot convergence benchmark', + '', + `- Status: **${result.status}**`, + `- Revision: ${result.revision.commit}`, + `- Host: ${result.host.model} (${result.host.modelIdentifier}; ${result.host.cpu}, ${result.host.cpuCores} cores)`, + `- Target: ${result.target.name} (${result.target.udid}, ${result.target.runtime})`, + `- Generated: ${result.generatedAt}`, + '', + '| State | Screen | Transport | Execution | N | Wall median | Wall p95 | Daemon median | Response median | Failures |', + '|---|---|---|---|---:|---:|---:|---:|---:|---:|', + ...result.measurements.map(measurementRow), + '', + '## Package size', + '', + packageSizeLines(result), + '', + '## Deep-button control', + '', + `- Fixture artifact: ${result.deepButtonEvidence.artifact} (depth ${result.deepButtonEvidence.depth})`, + `- Red control: ${result.deepButtonEvidence.invalidShallowRule.command} (exit ${result.deepButtonEvidence.invalidShallowRule.exitCode})`, + ` - ${result.deepButtonEvidence.invalidShallowRule.assertion}`, + `- Safe control: ${result.deepButtonEvidence.safeFullRule.command} (exit ${result.deepButtonEvidence.safeFullRule.exitCode})`, + ` - ${result.deepButtonEvidence.safeFullRule.assertion}`, + ]; + if (result.stop) { + lines.push('', '## Stop condition', '', `- ${result.stop.category}: ${result.stop.message}`); + if (result.stop.reason) lines.push(`- Reason: ${result.stop.reason}`); + if (result.stop.command) lines.push(`- Command: ${result.stop.command}`); + } + return `${lines.join('\n')}\n`; +} + +function measurementRow(measurement: Measurement): string { + return `| ${[ + measurement.state, + measurement.screen, + measurement.transport, + measurement.execution, + measurement.wallClockMs?.n ?? 0, + formatSummaryValue(measurement.wallClockMs, 'median'), + formatSummaryValue(measurement.wallClockMs, 'p95'), + formatSummaryValue(measurement.daemonDurationMs, 'median'), + formatSummaryValue(measurement.responseBytes, 'median'), + measurement.failures, + ].join(' | ')} |`; +} + +function formatSummaryValue(summary: Summary | null, key: 'median' | 'p95'): string { + return summary ? `${summary[key].toFixed(1)}` : '–'; +} + +function packageSizeLines(result: BenchmarkResult): string { + const packageSize = result.packageSize; + if (packageSize.status !== 'measured') return 'Not measured.'; + return measuredPackageSizeLines(packageSize); +} + +function measuredPackageSizeLines(packageSize: PackageSize & { status: 'measured' }): string { + return [ + ...packedSizeLines(packageSize), + cleanInstalledSizeLine(packageSize), + bundledSizeLine(packageSize), + ].join('\n'); +} + +function packedSizeLines(packageSize: PackageSize): string[] { + const packed = packageSize.packed; + return [ + packageSizeLine('Packed tarball', packed?.tarballBytes), + packageSizeLine('Packed unpacked tree', packed?.unpackedBytes), + ]; +} + +function cleanInstalledSizeLine(packageSize: PackageSize): string { + const cleanInstalled = packageSize.cleanInstalled; + return packageTreeLine( + 'Clean-installed package tree', + cleanInstalled?.packageBytes, + cleanInstalled?.files, + ); +} + +function bundledSizeLine(packageSize: PackageSize): string { + const bundled = packageSize.bundled; + return packageBundleLine('Bundled JavaScript', bundled?.rawBytes, bundled?.gzipBytes); +} + +function packageSizeLine(label: string, bytes: number | undefined): string { + return `- ${label}: ${bytes ?? '–'} bytes`; +} + +function packageTreeLine( + label: string, + bytes: number | undefined, + files: number | undefined, +): string { + return `- ${label}: ${bytes ?? '–'} bytes (${files ?? '–'} files)`; +} + +function packageBundleLine( + label: string, + raw: number | undefined, + gzip: number | undefined, +): string { + return `- ${label}: ${raw ?? '–'} raw / ${gzip ?? '–'} gzip bytes`; +} diff --git a/scripts/ios-snapshot-benchmark/result-values.ts b/scripts/ios-snapshot-benchmark/result-values.ts new file mode 100644 index 000000000..4d9f43302 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/result-values.ts @@ -0,0 +1,9 @@ +export function asRecord(value: unknown): Record | undefined { + return value && typeof value === 'object' && !Array.isArray(value) + ? (value as Record) + : undefined; +} + +export function readString(value: unknown): string | undefined { + return typeof value === 'string' && value.length > 0 ? value : undefined; +} diff --git a/scripts/ios-snapshot-benchmark/run.test.ts b/scripts/ios-snapshot-benchmark/run.test.ts new file mode 100644 index 000000000..c1b9c0597 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/run.test.ts @@ -0,0 +1,53 @@ +import assert from 'node:assert/strict'; +import { execFileSync } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; +import { test } from 'vitest'; +import { mkdtempForTest } from '../../src/__tests__/test-utils/tmp-dir.ts'; +import { resolveRepoRoot } from './host.ts'; + +test('CLI refuses an unmarked existing root before any descendant can be cleared', async () => { + const repoRoot = resolveRepoRoot(); + const stateDir = await mkdtempForTest('agent-device-ios-benchmark-cli-'); + const derivedPath = path.join(stateDir, 'derived-data', 'cell'); + const sentinel = path.join(derivedPath, 'must-survive'); + fs.mkdirSync(derivedPath, { recursive: true }); + fs.writeFileSync(sentinel, 'keep'); + + let exitCode = 0; + let stderr = ''; + try { + execFileSync( + process.execPath, + [ + '--experimental-strip-types', + path.join(repoRoot, 'scripts/ios-snapshot-benchmark/run.ts'), + '--udid', + 'unavailable-simulator', + '--state-dir', + stateDir, + '--derived-path', + derivedPath, + '--skip-package-size', + ], + { + cwd: repoRoot, + encoding: 'utf8', + maxBuffer: 64 * 1024, + timeout: 60_000, + }, + ); + } catch (error) { + const failure = error as { status?: unknown; stderr?: unknown }; + exitCode = typeof failure.status === 'number' ? failure.status : -1; + stderr = Buffer.isBuffer(failure.stderr) + ? failure.stderr.toString('utf8') + : typeof failure.stderr === 'string' + ? failure.stderr + : ''; + } + + assert.notEqual(exitCode, 0); + assert.match(stderr, /benchmark-owned/); + assert.equal(fs.readFileSync(sentinel, 'utf8'), 'keep'); +}); diff --git a/scripts/ios-snapshot-benchmark/run.ts b/scripts/ios-snapshot-benchmark/run.ts new file mode 100644 index 000000000..e312da698 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/run.ts @@ -0,0 +1,284 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { + BenchmarkConfigurationError, + parseConfig, + type BenchmarkConfig, +} from './benchmark-config.ts'; +import { classifyFailure, formatCliFailure, openFixture, type CliContext } from './command.ts'; +import { BenchmarkControlError, runDeepButtonControls } from './deep-control.ts'; +import { CONTRACT, screenFixture } from './definitions.ts'; +import { deepButtonFixtureEvidence } from './deep-button.ts'; +import { readGitRevision, readHostIdentity, readTarget, readToolchain } from './host.ts'; +import { + BenchmarkCellAdmissionError, + BenchmarkContentionError, + BenchmarkInfrastructureError, + bootSimulator, + shutdownSimulator, + stopDaemon, +} from './lifecycle.ts'; +import { closeSession, runLocalMeasurements } from './local-runner.ts'; +import { measurePackageSize, notRunPackageSize } from './package-evidence.ts'; +import { runProxyMeasurements } from './proxy-runner.ts'; +import { renderBenchmarkMarkdown } from './report.ts'; +import { assertValidRawResult } from './schema.ts'; +import { + BENCHMARK_SCHEMA_VERSION, + type BenchmarkStop, + type BenchmarkResult, + type DeepButtonEvidence, + type GitRevision, + type HostIdentity, + type Measurement, + type PackageSize, + type ProxyNetwork, + type Target, + type Toolchain, +} from './types.ts'; + +type BenchmarkMetadata = { + revision: GitRevision; + target: Target; + toolchain: Toolchain; + host: HostIdentity; +}; +type BenchmarkEvidence = { + packageSize: PackageSize; + deepButtonEvidence: DeepButtonEvidence; + measurements: Measurement[]; + proxyNetworks?: ProxyNetwork[]; +}; + +if (isMainModule()) { + try { + await main(process.argv.slice(2)); + } catch (error) { + process.stderr.write( + `${error instanceof Error ? (error.stack ?? error.message) : String(error)}\n`, + ); + process.exitCode = 1; + } +} + +async function main(argv: string[]): Promise { + const config = parseConfig(argv); + const metadata = readMetadata(config); + const result = await executeBenchmark(config, metadata); + assertValidRawResult(result); + writeResult(config.outputPath, result); + process.stdout.write(`${renderBenchmarkMarkdown(result)}\nraw: ${config.outputPath}\n`); + if (result.status === 'stopped') process.exitCode = 2; +} + +function readMetadata(config: BenchmarkConfig): BenchmarkMetadata { + return { + revision: readGitRevision(config.repoRoot), + target: readTarget(config.udid, config.appId, config.appPath), + toolchain: readToolchain(), + host: readHostIdentity(), + }; +} + +async function executeBenchmark( + config: BenchmarkConfig, + metadata: BenchmarkMetadata, +): Promise { + const evidence: BenchmarkEvidence = { + packageSize: notRunPackageSize(metadata.revision.commit), + deepButtonEvidence: deepButtonFixtureEvidence(), + measurements: [], + }; + try { + bootSimulator(config.udid); + primeDeepLink(config); + evidence.deepButtonEvidence = runDeepButtonControls(config.repoRoot); + if (!config.skipPackageSize) { + evidence.packageSize = measurePackageSize(config.repoRoot, metadata.revision.commit); + } + const measurements = await collectMeasurements(config); + evidence.measurements = measurements.measurements; + evidence.proxyNetworks = measurements.proxyNetworks; + return completedResult(config, metadata, evidence); + } catch (error) { + return stoppedResult(config, metadata, evidence, error); + } finally { + shutdownAfterRun(config); + } +} + +function primeDeepLink(config: BenchmarkConfig): void { + const fixture = config.screens.map(screenFixture).find((candidate) => candidate.launchUrl); + if (!fixture) return; + const context: CliContext = { + repoRoot: config.repoRoot, + stateDir: config.stateDir, + session: 'bench-deep-link-prime', + udid: config.udid, + derivedPath: path.join(config.derivedPath, 'deep-link-prime'), + }; + try { + const opened = openFixture(context, fixture, { relaunch: true }); + if (!opened.ok) { + throw new BenchmarkInfrastructureError( + formatCliFailure('deep-link priming', classifyFailure(opened.payload, opened), opened), + 'agent-device open --launch-url', + ); + } + } finally { + closeSession(context); + stopDaemon(config.repoRoot, config.stateDir); + } +} + +async function collectMeasurements(config: BenchmarkConfig): Promise<{ + measurements: Measurement[]; + proxyNetworks?: ProxyNetwork[]; +}> { + const measurements = shouldRunLocal(config) + ? await runLocalMeasurements({ + repoRoot: config.repoRoot, + stateDir: config.stateDir, + derivedPath: config.derivedPath, + udid: config.udid, + fixtures: config.screens.map(screenFixture), + states: config.states, + samples: config.samples, + }) + : []; + if (!shouldRunProxy(config)) return { measurements }; + const proxy = await runProxyMeasurements({ + repoRoot: config.repoRoot, + stateDir: path.join(config.stateDir, 'proxy'), + clientStateDir: path.join(config.stateDir, 'proxy-clients'), + derivedPath: config.derivedPath, + udid: config.udid, + fixtures: config.screens.map(screenFixture), + samples: config.samples, + rtts: config.rtts, + bandwidthKbps: config.bandwidthKbps, + packetLossPercent: config.packetLossPercent, + seed: config.seed, + }); + return { measurements: [...measurements, ...proxy.measurements], proxyNetworks: proxy.networks }; +} + +function shouldRunLocal(config: BenchmarkConfig): boolean { + return config.mode === 'local' || config.mode === 'all'; +} + +function shouldRunProxy(config: BenchmarkConfig): boolean { + return config.mode === 'proxy' || config.mode === 'all'; +} + +function completedResult( + config: BenchmarkConfig, + metadata: BenchmarkMetadata, + evidence: BenchmarkEvidence, +): BenchmarkResult { + return { + ...resultFields(config, metadata, evidence), + status: 'completed', + measurements: evidence.measurements, + ...(evidence.proxyNetworks ? { proxyNetworks: evidence.proxyNetworks } : {}), + }; +} + +function stoppedResult( + config: BenchmarkConfig, + metadata: BenchmarkMetadata, + evidence: BenchmarkEvidence, + error: unknown, +): BenchmarkResult { + const message = error instanceof Error ? error.message : String(error); + process.stderr.write(`[ios-benchmark] stopped: ${message}\n`); + return { + ...resultFields(config, metadata, evidence), + status: 'stopped', + measurements: evidence.measurements, + ...(evidence.proxyNetworks ? { proxyNetworks: evidence.proxyNetworks } : {}), + stop: { + category: stopCategory(error), + message: message.slice(0, 2000), + ...stopDetails(error), + }, + }; +} + +function stopDetails(error: unknown): Pick { + const reason = error instanceof BenchmarkCellAdmissionError ? error.reason : undefined; + const command = stopCommand(error); + return { + ...(reason ? { reason } : {}), + ...(command ? { command } : {}), + }; +} + +function stopCategory(error: unknown): 'infrastructure' | 'contention' | 'configuration' { + if (error instanceof BenchmarkConfigurationError) return 'configuration'; + if (error instanceof BenchmarkContentionError) return 'contention'; + return 'infrastructure'; +} + +function stopCommand(error: unknown): string | undefined { + if ( + error instanceof BenchmarkControlError || + error instanceof BenchmarkInfrastructureError || + error instanceof BenchmarkContentionError + ) { + return error.command; + } + return undefined; +} + +function shutdownAfterRun(config: BenchmarkConfig): void { + if (config.keepDevice) return; + try { + shutdownSimulator(config.udid); + } catch { + process.stderr.write(`[ios-benchmark] cleanup could not shut down ${config.udid}\n`); + } +} + +function resultFields( + config: BenchmarkConfig, + metadata: BenchmarkMetadata, + evidence: BenchmarkEvidence, +) { + return { + schemaVersion: BENCHMARK_SCHEMA_VERSION, + issue: CONTRACT.issue, + parent: CONTRACT.parent, + references: CONTRACT.references, + runId: `ios-snapshot-${Date.now()}-${process.pid}`, + generatedAt: new Date().toISOString(), + revision: metadata.revision, + toolchain: metadata.toolchain, + host: metadata.host, + target: metadata.target, + config: { + warmSampleMinimum: CONTRACT.warmSampleMinimum, + coldSampleMinimum: CONTRACT.coldSampleMinimum, + requestedSamples: config.samples, + screens: config.screens, + states: config.states, + }, + measurements: [], + packageSize: evidence.packageSize, + deepButtonEvidence: evidence.deepButtonEvidence, + } satisfies Omit; +} + +function writeResult(outputPath: string, result: BenchmarkResult): void { + fs.mkdirSync(path.dirname(outputPath), { recursive: true }); + fs.writeFileSync(outputPath, `${JSON.stringify(result, null, 2)}\n`); + fs.writeFileSync(outputPath.replace(/\.json$/u, '.md'), renderBenchmarkMarkdown(result)); +} + +function isMainModule(): boolean { + return Boolean( + process.argv[1] && + path.resolve(process.argv[1]) === path.resolve(fileURLToPath(import.meta.url)), + ); +} diff --git a/scripts/ios-snapshot-benchmark/schema.test.ts b/scripts/ios-snapshot-benchmark/schema.test.ts new file mode 100644 index 000000000..fcc1972be --- /dev/null +++ b/scripts/ios-snapshot-benchmark/schema.test.ts @@ -0,0 +1,96 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { deepButtonFixtureEvidence } from './deep-button.ts'; +import { assertValidRawResult, validateRawResult } from './schema.ts'; +import type { BenchmarkResult } from './types.ts'; + +function result(): BenchmarkResult { + return { + schemaVersion: 'ios-snapshot-convergence.v1', + issue: '#2189', + parent: '#2188', + references: { deepButton: '#1626', appMount: '#1571' }, + runId: 'schema-test', + generatedAt: '2026-01-01T00:00:00.000Z', + revision: { commit: 'abc', branch: 'test', dirty: false }, + toolchain: { node: 'v26', pnpm: '10', xcode: '27', simctl: '27', os: 'darwin', arch: 'arm64' }, + host: { + model: 'MacBook Pro', + modelIdentifier: 'Mac16,8', + cpu: 'Apple M4 Pro', + cpuCores: 12, + }, + target: { + platform: 'ios', + kind: 'simulator', + udid: 'simulator', + name: 'bench', + runtime: 'iOS 27', + appId: 'com.callstack.agentdevicelab', + }, + config: { + warmSampleMinimum: 20, + coldSampleMinimum: 10, + requestedSamples: 20, + screens: ['quiet'], + states: ['warm'], + }, + status: 'completed', + measurements: [ + { + transport: 'local', + execution: 'fresh-process-cli', + state: 'warm', + screen: 'quiet', + sampleMinimum: 20, + operation: 'snapshot', + samples: [ + { + index: 1, + startedAt: '2026-01-01T00:00:00.000Z', + finishedAt: '2026-01-01T00:00:00.001Z', + operation: 'snapshot', + wallClockMs: 1, + targetGeneration: null, + firstTree: 'readable', + ok: true, + outlier: false, + }, + ], + wallClockMs: null, + daemonDurationMs: null, + responseBytes: null, + failures: 0, + failureCategories: {}, + }, + ], + packageSize: { status: 'not-run', revision: 'abc' }, + deepButtonEvidence: deepButtonFixtureEvidence(), + }; +} + +test('validates the raw result and rejects unknown or missing fields', () => { + const value = result(); + assert.deepEqual(validateRawResult(value), []); + assert.doesNotThrow(() => assertValidRawResult(value)); + assert.match(validateRawResult({ ...value, unexpected: true }).join('\n'), /unknown property/); + assert.match( + validateRawResult({ + ...value, + measurements: [{ ...value.measurements[0], screen: 'unknown' }], + }).join('\n'), + /permitted enum/, + ); +}); + +test('accepts a stopped run before the first measurement cell', () => { + const value = result(); + value.status = 'stopped'; + value.measurements = []; + value.stop = { + category: 'infrastructure', + reason: 'fixture-anchor', + message: 'fixture build unavailable', + }; + assert.doesNotThrow(() => assertValidRawResult(value)); +}); diff --git a/scripts/ios-snapshot-benchmark/schema.ts b/scripts/ios-snapshot-benchmark/schema.ts new file mode 100644 index 000000000..ed8242ffd --- /dev/null +++ b/scripts/ios-snapshot-benchmark/schema.ts @@ -0,0 +1,179 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +type Schema = { + type?: string | string[]; + const?: unknown; + enum?: unknown[]; + required?: string[]; + properties?: Record; + items?: Schema; + additionalProperties?: boolean | Schema; + minItems?: number; + minLength?: number; + minimum?: number; + maximum?: number; + $ref?: string; + $defs?: Record; +}; + +const SCHEMA_PATH = path.join(import.meta.dirname, 'raw-result.schema.v1.json'); + +export function validateRawResult(value: unknown): string[] { + const root = readRawResultSchema(); + return collectErrors(value, root, '$', root.$defs ?? {}); +} + +export function assertValidRawResult(value: unknown): void { + const errors = validateRawResult(value); + if (errors.length > 0) throw new Error(`Raw result does not match schema:\n${errors.join('\n')}`); +} + +function readRawResultSchema(): Schema { + return JSON.parse(fs.readFileSync(SCHEMA_PATH, 'utf8')) as Schema; +} + +function collectErrors( + value: unknown, + schema: Schema, + location: string, + definitions: Record, +): string[] { + if (schema.$ref) return collectReferenceErrors(value, schema.$ref, location, definitions); + const typeErrors = validateType(value, schema, location); + if (typeErrors.length > 0) return typeErrors; + return [ + ...validateConst(value, schema, location), + ...validateEnum(value, schema, location), + ...validateString(value, schema, location), + ...validateNumber(value, schema, location), + ...validateArray(value, schema, location, definitions), + ...validateObject(value, schema, location, definitions), + ]; +} + +function collectReferenceErrors( + value: unknown, + reference: string, + location: string, + definitions: Record, +): string[] { + const definitionName = reference.replace(/^#\/\$defs\//, ''); + const definition = definitions[definitionName]; + return definition + ? collectErrors(value, definition, location, definitions) + : [`${location}: unknown schema reference ${reference}`]; +} + +function validateType(value: unknown, schema: Schema, location: string): string[] { + if (!schema.type || matchesType(value, schema.type)) return []; + return [`${location}: expected type ${JSON.stringify(schema.type)}`]; +} + +function validateConst(value: unknown, schema: Schema, location: string): string[] { + return 'const' in schema && !Object.is(value, schema.const) + ? [`${location}: expected ${JSON.stringify(schema.const)}`] + : []; +} + +function validateEnum(value: unknown, schema: Schema, location: string): string[] { + return schema.enum && !schema.enum.some((candidate) => Object.is(candidate, value)) + ? [`${location}: value is not in the permitted enum`] + : []; +} + +function validateString(value: unknown, schema: Schema, location: string): string[] { + if (typeof value !== 'string' || value.length >= (schema.minLength ?? 0)) return []; + return [`${location}: string is too short`]; +} + +function validateNumber(value: unknown, schema: Schema, location: string): string[] { + if (typeof value !== 'number') return []; + const errors = [ + ...(Number.isFinite(value) ? [] : [`${location}: number must be finite`]), + ...(schema.minimum !== undefined && value < schema.minimum + ? [`${location}: number is below minimum ${schema.minimum}`] + : []), + ...(schema.maximum !== undefined && value > schema.maximum + ? [`${location}: number is above maximum ${schema.maximum}`] + : []), + ]; + return errors; +} + +function validateArray( + value: unknown, + schema: Schema, + location: string, + definitions: Record, +): string[] { + if (!Array.isArray(value)) return []; + const lengthErrors = + value.length < (schema.minItems ?? 0) ? [`${location}: array is too short`] : []; + const itemErrors = schema.items + ? value.flatMap((item, index) => + collectErrors(item, schema.items!, `${location}[${index}]`, definitions), + ) + : []; + return [...lengthErrors, ...itemErrors]; +} + +function validateObject( + value: unknown, + schema: Schema, + location: string, + definitions: Record, +): string[] { + if (!isPlainObject(value)) return []; + const properties = schema.properties ?? {}; + const requiredErrors = (schema.required ?? []).flatMap((key) => + key in value ? [] : [`${location}.${key}: missing required property`], + ); + const propertyErrors = Object.entries(properties).flatMap(([key, child]) => + key in value ? collectErrors(value[key], child, `${location}.${key}`, definitions) : [], + ); + const additionalErrors = validateAdditionalProperties( + value, + schema.additionalProperties, + properties, + location, + definitions, + ); + return [...requiredErrors, ...propertyErrors, ...additionalErrors]; +} + +function validateAdditionalProperties( + value: Record, + additionalProperties: boolean | Schema | undefined, + properties: Record, + location: string, + definitions: Record, +): string[] { + const unknownKeys = Object.keys(value).filter((key) => !(key in properties)); + if (additionalProperties === false) { + return unknownKeys.map((key) => `${location}.${key}: unknown property`); + } + if (!isSchema(additionalProperties)) return []; + return unknownKeys.flatMap((key) => + collectErrors(value[key], additionalProperties, `${location}.${key}`, definitions), + ); +} + +function matchesType(value: unknown, type: string | string[]): boolean { + return (Array.isArray(type) ? type : [type]).some((candidate) => { + if (candidate === 'integer') return typeof value === 'number' && Number.isInteger(value); + if (candidate === 'number') return typeof value === 'number'; + if (candidate === 'object') return isPlainObject(value); + if (candidate === 'array') return Array.isArray(value); + if (candidate === 'null') return value === null; + return typeof value === candidate; + }); +} + +function isSchema(value: boolean | Schema | undefined): value is Schema { + return Boolean(value && typeof value === 'object' && !Array.isArray(value)); +} + +function isPlainObject(value: unknown): value is Record { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} diff --git a/scripts/ios-snapshot-benchmark/size-install.test.ts b/scripts/ios-snapshot-benchmark/size-install.test.ts new file mode 100644 index 000000000..1e4471746 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/size-install.test.ts @@ -0,0 +1,14 @@ +import assert from 'node:assert/strict'; +import { mkdir, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { test } from 'vitest'; +import { mkdtempForTest } from '../../src/__tests__/test-utils/tmp-dir.ts'; +import { measureDirectory } from '../size-report-install.mjs'; + +test('measures the clean-installed package tree without counting the consumer', async () => { + const root = await mkdtempForTest('agent-device-size-tree-'); + await mkdir(join(root, 'nested')); + await writeFile(join(root, 'index.js'), '1234'); + await writeFile(join(root, 'nested', 'data.json'), '{}'); + assert.deepEqual(measureDirectory(root), { packageBytes: 6, files: 2 }); +}); diff --git a/scripts/ios-snapshot-benchmark/state-ownership.test.ts b/scripts/ios-snapshot-benchmark/state-ownership.test.ts new file mode 100644 index 000000000..1755d47d4 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/state-ownership.test.ts @@ -0,0 +1,37 @@ +import assert from 'node:assert/strict'; +import fs from 'node:fs'; +import path from 'node:path'; +import { test } from 'vitest'; +import { mkdtempForTest } from '../../src/__tests__/test-utils/tmp-dir.ts'; +import { + assertBenchmarkOwner, + assertOwnedDerivedPath, + clearDerivedData, + createBenchmarkStateRoot, +} from './state-ownership.ts'; + +test('clears only a benchmark-owned derived-data descendant', () => { + const stateDir = createBenchmarkStateRoot(); + const derivedPath = path.join(stateDir, 'derived-data', 'cold', 'quiet'); + fs.mkdirSync(derivedPath, { recursive: true }); + fs.writeFileSync(path.join(derivedPath, 'result'), 'fixture'); + clearDerivedData(derivedPath, stateDir); + assert.equal(fs.existsSync(derivedPath), false); + assert.throws( + () => assertOwnedDerivedPath(path.join(stateDir, '..', 'outside'), stateDir), + /descendant of the benchmark state directory/, + ); +}); + +test('rejects an unmarked existing root and symlinked ownership marker', async () => { + const unmarked = await mkdtempForTest('agent-device-ios-benchmark-unmarked-'); + assert.throws(() => assertBenchmarkOwner(unmarked), /not benchmark-owned/); + + const marked = createBenchmarkStateRoot(); + const marker = path.join(marked, '.agent-device-ios-snapshot-benchmark-owner'); + const replacement = path.join(marked, 'marker-target'); + fs.writeFileSync(replacement, 'agent-device-ios-snapshot-benchmark.v1\n'); + fs.rmSync(marker); + fs.symlinkSync(replacement, marker); + assert.throws(() => assertBenchmarkOwner(marked), /regular file/); +}); diff --git a/scripts/ios-snapshot-benchmark/state-ownership.ts b/scripts/ios-snapshot-benchmark/state-ownership.ts new file mode 100644 index 000000000..300e3ad85 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/state-ownership.ts @@ -0,0 +1,94 @@ +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { BenchmarkCellAdmissionError } from './lifecycle.ts'; + +const BENCHMARK_OWNER_MARKER = '.agent-device-ios-snapshot-benchmark-owner'; +const BENCHMARK_OWNER_MARKER_CONTENT = 'agent-device-ios-snapshot-benchmark.v1\n'; + +export function createBenchmarkStateRoot(): string { + const ownerRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-device-ios-benchmark-')); + fs.writeFileSync(path.join(ownerRoot, BENCHMARK_OWNER_MARKER), BENCHMARK_OWNER_MARKER_CONTENT, { + flag: 'wx', + }); + return ownerRoot; +} + +export function assertBenchmarkOwner(ownerRoot: string): void { + const resolvedOwnerRoot = path.resolve(ownerRoot); + if (!fs.existsSync(resolvedOwnerRoot)) { + throw ownershipError(`Benchmark state directory must already exist: ${resolvedOwnerRoot}`); + } + const rootStat = fs.lstatSync(resolvedOwnerRoot); + if (!rootStat.isDirectory() || rootStat.isSymbolicLink()) { + throw ownershipError( + `Benchmark state directory must be a real directory: ${resolvedOwnerRoot}`, + ); + } + const markerPath = path.join(resolvedOwnerRoot, BENCHMARK_OWNER_MARKER); + if (!fs.existsSync(markerPath)) { + throw ownershipError(`Benchmark state directory is not benchmark-owned: ${resolvedOwnerRoot}`); + } + const markerStat = fs.lstatSync(markerPath); + if (markerStat.isSymbolicLink() || !markerStat.isFile()) { + throw ownershipError(`Benchmark owner marker must be a regular file: ${markerPath}`); + } + if (fs.readFileSync(markerPath, 'utf8') !== BENCHMARK_OWNER_MARKER_CONTENT) { + throw ownershipError(`Benchmark owner marker is invalid: ${markerPath}`); + } +} + +export function assertOwnedDerivedPath(derivedPath: string, ownerRoot: string): void { + assertBenchmarkOwner(ownerRoot); + const resolvedOwnerRoot = path.resolve(ownerRoot); + const resolvedDerivedPath = path.resolve(derivedPath); + if (!isDescendant(resolvedDerivedPath, resolvedOwnerRoot)) { + throw ownershipError( + 'Derived-data path must be a descendant of the benchmark state directory.', + ); + } + if (fs.existsSync(resolvedDerivedPath) && fs.lstatSync(resolvedDerivedPath).isSymbolicLink()) { + throw ownershipError(`Derived-data path must not be a symbolic link: ${resolvedDerivedPath}`); + } + const realOwnerRoot = fs.realpathSync.native(resolvedOwnerRoot); + const realExistingParent = fs.realpathSync.native(findExistingPath(resolvedDerivedPath)); + if (!isDescendantOrSame(realExistingParent, realOwnerRoot)) { + throw ownershipError('Derived-data path resolves outside the benchmark state directory.'); + } +} + +export function clearDerivedData(derivedPath: string, ownerRoot: string): void { + assertOwnedDerivedPath(derivedPath, ownerRoot); + if (fs.existsSync(derivedPath)) fs.rmSync(derivedPath, { recursive: true, force: true }); + fs.mkdirSync(path.dirname(derivedPath), { recursive: true }); +} + +function ownershipError(message: string): BenchmarkCellAdmissionError { + return new BenchmarkCellAdmissionError('derived-path', message); +} + +function isDescendant(candidate: string, root: string): boolean { + const relative = path.relative(root, candidate); + return ( + relative !== '' && + relative !== '..' && + !relative.startsWith(`..${path.sep}`) && + !path.isAbsolute(relative) + ); +} + +function isDescendantOrSame(candidate: string, root: string): boolean { + return candidate === root || isDescendant(candidate, root); +} + +function findExistingPath(target: string): string { + let current = target; + while (!fs.existsSync(current)) { + const parent = path.dirname(current); + if (parent === current) { + throw ownershipError(`Could not resolve derived-data parent: ${target}`); + } + current = parent; + } + return current; +} diff --git a/scripts/ios-snapshot-benchmark/statistics.test.ts b/scripts/ios-snapshot-benchmark/statistics.test.ts new file mode 100644 index 000000000..38f6a1913 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/statistics.test.ts @@ -0,0 +1,51 @@ +import assert from 'node:assert/strict'; +import { test } from 'vitest'; +import { buildMeasurement, markOutliers, summarize } from './statistics.ts'; +import type { RawSample } from './types.ts'; + +function sample(index: number, wallClockMs: number, ok = true): RawSample { + return { + index, + startedAt: '2026-01-01T00:00:00.000Z', + finishedAt: '2026-01-01T00:00:00.001Z', + operation: 'snapshot', + wallClockMs, + targetGeneration: 1, + firstTree: ok ? 'readable' : 'not-observed', + ok, + outlier: false, + ...(ok ? {} : { failure: { category: 'timeout' as const } }), + }; +} + +test('summarizes successful values and uses the Tukey outlier rule', () => { + const values = [10, 11, 12, 13, 100]; + assert.deepEqual(summarize(values, 1), { + n: 5, + min: 10, + median: 12, + p95: 100, + max: 100, + outlierCount: 1, + outlierRule: 'tukey-1.5-iqr', + }); + assert.equal( + markOutliers(values.map((value, index) => sample(index + 1, value))).at(-1)?.outlier, + true, + ); +}); + +test('keeps failures out of timing summaries and counts typed categories', () => { + const measurement = buildMeasurement({ + transport: 'local', + execution: 'fresh-process-cli', + state: 'cold', + screen: 'quiet', + sampleMinimum: 10, + operation: 'open-foreground', + samples: [sample(1, 10), sample(2, 20, false)], + }); + assert.equal(measurement.failures, 1); + assert.deepEqual(measurement.failureCategories, { timeout: 1 }); + assert.equal(measurement.wallClockMs?.n, 1); +}); diff --git a/scripts/ios-snapshot-benchmark/statistics.ts b/scripts/ios-snapshot-benchmark/statistics.ts new file mode 100644 index 000000000..35f912ff4 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/statistics.ts @@ -0,0 +1,87 @@ +import type { Measurement, RawSample, Summary } from './types.ts'; + +function percentile(values: number[], percentage: number): number { + const rank = Math.ceil((percentage / 100) * values.length); + return values[Math.min(values.length - 1, Math.max(0, rank - 1))]!; +} + +export function summarize(values: number[], outlierCount = 0): Summary | null { + const finite = values.filter(Number.isFinite).sort((left, right) => left - right); + if (finite.length === 0) return null; + return { + n: finite.length, + min: finite[0]!, + median: percentile(finite, 50), + p95: percentile(finite, 95), + max: finite.at(-1)!, + outlierCount, + outlierRule: 'tukey-1.5-iqr', + }; +} + +function outlierIndexes(values: number[]): Set { + const finite = values.filter(Number.isFinite).sort((left, right) => left - right); + if (finite.length < 4) return new Set(); + const q1 = percentile(finite, 25); + const q3 = percentile(finite, 75); + const spread = q3 - q1; + const lower = q1 - 1.5 * spread; + const upper = q3 + 1.5 * spread; + return new Set(values.flatMap((value, index) => (value < lower || value > upper ? [index] : []))); +} + +export function markOutliers(samples: RawSample[]): RawSample[] { + const indexes = outlierIndexes( + samples.filter((sample) => sample.ok).map((sample) => sample.wallClockMs), + ); + let successfulIndex = 0; + return samples.map((sample) => { + if (!sample.ok) return { ...sample, outlier: false }; + const outlier = indexes.has(successfulIndex); + successfulIndex += 1; + return { ...sample, outlier }; + }); +} + +export function buildMeasurement(options: { + transport: Measurement['transport']; + execution: Measurement['execution']; + state: Measurement['state']; + screen: Measurement['screen']; + sampleMinimum: number; + operation: Measurement['operation']; + samples: RawSample[]; + network?: Measurement['network']; +}): Measurement { + const samples = markOutliers(options.samples); + const successful = samples.filter((sample) => sample.ok); + const outlierCount = successful.filter((sample) => sample.outlier).length; + const failures = samples.length - successful.length; + const failureCategories: Measurement['failureCategories'] = {}; + for (const sample of samples) { + const category = sample.failure?.category; + if (category) failureCategories[category] = (failureCategories[category] ?? 0) + 1; + } + return { + ...options, + samples, + wallClockMs: summarize( + successful.map((sample) => sample.wallClockMs), + outlierCount, + ), + daemonDurationMs: summarize( + successful.flatMap((sample) => + typeof sample.daemonDurationMs === 'number' ? [sample.daemonDurationMs] : [], + ), + outlierCount, + ), + responseBytes: summarize( + successful.flatMap((sample) => + typeof sample.responseBytes === 'number' ? [sample.responseBytes] : [], + ), + outlierCount, + ), + failures, + failureCategories, + }; +} diff --git a/scripts/ios-snapshot-benchmark/types.ts b/scripts/ios-snapshot-benchmark/types.ts new file mode 100644 index 000000000..e8c4d1119 --- /dev/null +++ b/scripts/ios-snapshot-benchmark/types.ts @@ -0,0 +1,200 @@ +export const BENCHMARK_SCHEMA_VERSION = 'ios-snapshot-convergence.v1' as const; +export const ISSUE_ID = '#2189'; +export const PARENT_ISSUE_ID = '#2188'; +export const DEEP_BUTTON_ISSUE_ID = '#1626'; +export const APP_MOUNT_ISSUE_ID = '#1571'; + +export const WARM_SAMPLE_MINIMUM = 20; +export const COLD_SAMPLE_MINIMUM = 10; +export const PROXY_RTT_VALUES = [0, 20, 80] as const; + +export type LocalState = 'cold-cold' | 'cold' | 'warm' | 'relaunch'; +export type Transport = 'local' | 'proxy'; +export type Execution = 'fresh-process-cli' | 'persistent-client'; +export type ScreenId = + | 'quiet' + | 'list' + | 'nested-scroll' + | 'alert' + | 'system-surface' + | 'xctest-stress'; + +export type FailureCategory = + | 'app-mount' + | 'bridge' + | 'runner' + | 'timeout' + | 'stale-generation' + | 'packet-loss' + | 'upstream' + | 'other'; + +export type FirstTreeStatus = 'readable' | 'empty' | 'unreadable' | 'not-observed'; + +export type ScreenFixture = { + id: ScreenId; + label: string; + app: string; + launchUrl?: string; + anchorText: string; + postSetupAnchorText?: string; + setupAction?: 'open-alert'; +}; + +export type Failure = { + category: FailureCategory; + code?: string; + reason?: string; + message?: string; +}; + +export type RawSample = { + index: number; + startedAt: string; + finishedAt: string; + operation: 'open-foreground' | 'snapshot' | 'relaunch-foreground'; + wallClockMs: number; + daemonDurationMs?: number; + responseBytes?: number; + nodeCount?: number; + targetGeneration: number | null; + firstTree: FirstTreeStatus; + ok: boolean; + outlier: boolean; + failure?: Failure; +}; + +export type Summary = { + n: number; + min: number; + median: number; + p95: number; + max: number; + outlierCount: number; + outlierRule: 'tukey-1.5-iqr'; +}; + +export type Measurement = { + transport: Transport; + execution: Execution; + state: LocalState; + screen: ScreenId; + sampleMinimum: number; + operation: RawSample['operation']; + samples: RawSample[]; + wallClockMs: Summary | null; + daemonDurationMs: Summary | null; + responseBytes: Summary | null; + network?: ProxyNetwork; + failures: number; + failureCategories: Partial>; +}; + +export type Toolchain = { + node: string; + pnpm: string; + xcode: string; + simctl: string; + os: string; + arch: string; +}; + +export type HostIdentity = { + model: string; + modelIdentifier: string; + cpu: string; + cpuCores: number; +}; + +export type GitRevision = { + commit: string; + branch: string; + dirty: boolean; +}; + +export type Target = { + platform: 'ios'; + kind: 'simulator'; + udid: string; + name: string; + runtime: string; + appId: string; + appPath?: string; +}; + +export type PackageSize = { + status: 'measured' | 'not-run'; + revision: string; + packed?: { tarballBytes: number; unpackedBytes: number }; + cleanInstalled?: { packageBytes: number; files: number }; + bundled?: { rawBytes: number; gzipBytes: number; files: number }; +}; + +export type DeepButtonObservation = { + depth: number; + surfaceDigest: string; + fullDigest: string; + state: 'off' | 'on'; + surfaceNodeIds: string[]; + fullNodeIds: string[]; +}; + +export type DeepButtonControl = { + command: string; + exitCode: number; + assertion: string; +}; + +export type DeepButtonEvidence = { + issue: typeof DEEP_BUTTON_ISSUE_ID; + fixture: 'deep-button-v1'; + artifact: 'deep-button-fixture.v1.json'; + depth: number; + changedDescendant: 'deep-button-state'; + invalidShallowRule: DeepButtonControl; + safeFullRule: DeepButtonControl; + before: DeepButtonObservation; + after: DeepButtonObservation; +}; + +export type ProxyNetwork = { + rttMs: (typeof PROXY_RTT_VALUES)[number]; + bandwidthKbps: number | null; + packetLossPercent: number; + seed: number; +}; + +export type BenchmarkStopReason = 'cell-state' | 'fixture-anchor' | 'derived-path'; + +export type BenchmarkStop = { + category: 'infrastructure' | 'contention' | 'configuration'; + message: string; + reason?: BenchmarkStopReason; + command?: string; +}; + +export type BenchmarkResult = { + schemaVersion: typeof BENCHMARK_SCHEMA_VERSION; + issue: typeof ISSUE_ID; + parent: typeof PARENT_ISSUE_ID; + references: { deepButton: typeof DEEP_BUTTON_ISSUE_ID; appMount: typeof APP_MOUNT_ISSUE_ID }; + runId: string; + generatedAt: string; + revision: GitRevision; + toolchain: Toolchain; + host: HostIdentity; + target: Target; + config: { + warmSampleMinimum: number; + coldSampleMinimum: number; + requestedSamples: number; + screens: ScreenId[]; + states: LocalState[]; + }; + status: 'completed' | 'stopped'; + measurements: Measurement[]; + proxyNetworks?: ProxyNetwork[]; + packageSize: PackageSize; + deepButtonEvidence: DeepButtonEvidence; + stop?: BenchmarkStop; +}; diff --git a/scripts/layering/model.test.ts b/scripts/layering/model.test.ts index 41a09ed3d..6792c4fd1 100644 --- a/scripts/layering/model.test.ts +++ b/scripts/layering/model.test.ts @@ -249,7 +249,7 @@ test('classifyZone separates the ranked spine from intentionally-unranked zones' assert.equal(classifyZone('(root)'), 'unranked'); assert.equal(classifyZone('platform-runtime'), 'unranked'); assert.equal(classifyZone('platforms'), 'unclassified'); - assert.equal(classifyZone('utils'), 'ranked'); + assert.equal(classifyZone('utils'), 'unclassified'); // Every satellite zone joined the spine; only the composition root stays out, because R2 // forbids daemon/ from importing commands/ so the files that wire them cannot be ranked. assert.equal(classifyZone('mcp'), 'ranked'); diff --git a/scripts/layering/model.ts b/scripts/layering/model.ts index 8b5f4d1d6..7cb355160 100644 --- a/scripts/layering/model.ts +++ b/scripts/layering/model.ts @@ -46,7 +46,6 @@ const TARGET_DAG_RANK = new Map([ ['screenshot-diff', 1], ['selectors', 1], ['snapshot', 1], - ['utils', 1], ['core', 2], ['cli-schema', 3], ['commands', 3], @@ -78,9 +77,9 @@ export function zoneRank(zone: string): number | null { // and the no-root-back-import rule instead of their former src folder rank. // // The satellite zones used to be listed here too, on the grounds that ranking them would -// invent an order the architecture had not committed to. Once `utils` joined the spine and -// `(root)` was emptied of shared contracts, every one of them turned out to have a -// consistent rank already — so the order was there, just unasserted. +// invent an order the architecture had not committed to. Once `(root)` was emptied of shared +// contracts, every one of them turned out to have a consistent rank already — so the order was +// there, just unasserted. The former `utils` zone was retired into owning modules and packages. // Extracted workspace packages are not src/ zones: R11 owns their physical seams, and their zone // names only appear in workspace-aware graphs. The platform packages additionally carry R13's // exact-family/composition/laziness policy. diff --git a/scripts/layering/package-boundaries.ts b/scripts/layering/package-boundaries.ts index 562c5a443..4944c9d69 100644 --- a/scripts/layering/package-boundaries.ts +++ b/scripts/layering/package-boundaries.ts @@ -270,7 +270,7 @@ export function rootExternalDependencyRanges(repoRoot: string): Map { }); test('a kernel test is reachable only under root or package src', () => { - // Load-bearing for where `test-file-size-ratchet.test.ts` lives. It measures the - // repository's own files and git history, neither of which Stryker's sandbox copy can - // answer, so it sits in `scripts/__tests__/` (explicitly included by `unit-core`) and - // this predicate is what keeps it out of every mutation lane. Widening the pattern to - // scripts/ would silently pull it back in and fail every dry run. + // Load-bearing for where repository-structure gates live. They measure the repository's own + // tracked files and Git history, which Stryker's sandbox copy cannot answer, so they sit in + // `scripts/__tests__/` (explicitly included by `unit-core`) and this predicate keeps them out of + // every mutation lane. Widening the pattern to scripts/ would silently pull them back in and + // fail every dry run. assert.ok(isKernelTestFile('src/daemon/__tests__/ref-frame.test.ts')); assert.ok(isKernelTestFile('packages/selectors/src/parse.test.ts')); assert.ok(!isKernelTestFile('scripts/__tests__/test-file-size-ratchet.test.ts')); + assert.ok(!isKernelTestFile('scripts/__tests__/eager-closure-budgets.test.ts')); + assert.ok(fs.existsSync(path.join(repoRoot, 'scripts/__tests__/eager-closure-budgets.test.ts'))); + assert.ok(!fs.existsSync(path.join(repoRoot, 'src/__tests__/eager-closure-budgets.test.ts'))); assert.ok(!isKernelTestFile('test/integration/daemon.test.ts')); assert.ok(!isKernelTestFile('src/daemon/ref-frame.ts')); }); diff --git a/scripts/mutation/modules.ts b/scripts/mutation/modules.ts index 81e321e31..9b3b9c5bd 100644 --- a/scripts/mutation/modules.ts +++ b/scripts/mutation/modules.ts @@ -61,8 +61,8 @@ export const KERNEL_MODULES: readonly KernelModule[] = [ { id: 'scroll-edge-state', label: 'Scroll edge-state detection', - mutate: ['src/utils/scroll-edge-state.ts'], - owns: ['src/utils/scroll-edge-state.ts'], + mutate: ['src/snapshot/scroll-edge-state.ts', 'src/snapshot/scroll-edge-state/**/*.ts'], + owns: ['src/snapshot/scroll-edge-state.ts', 'src/snapshot/scroll-edge-state/'], }, { id: 'selectors', diff --git a/scripts/mutation/selection.test.ts b/scripts/mutation/selection.test.ts index da2766e61..0d04f1eb4 100644 --- a/scripts/mutation/selection.test.ts +++ b/scripts/mutation/selection.test.ts @@ -80,9 +80,9 @@ test('a lane-tooling diff selects real mutants', () => { // The weekly sweep is the kernel report; selecting on derived ownership would // run the full ten-shard sweep on most PRs for a report nobody gates on. test('a kernel diff selects nothing — only a harness diff spends mutants', () => { - const dir = worktreeWithCommit('kernel', ['src/utils/scroll-edge-state.ts']); + const dir = worktreeWithCommit('kernel', ['src/snapshot/scroll-edge-state.ts']); assert.deepEqual(listAffected(dir), []); - assert.deepEqual(affectedMatrixFor(['src/utils/scroll-edge-state.ts']), []); + assert.deepEqual(affectedMatrixFor(['src/snapshot/scroll-edge-state.ts']), []); }); test('a docs-only diff selects nothing', () => { diff --git a/scripts/prepare-publish-assets.mjs b/scripts/prepare-publish-assets.mjs new file mode 100644 index 000000000..8ec37d599 --- /dev/null +++ b/scripts/prepare-publish-assets.mjs @@ -0,0 +1,89 @@ +#!/usr/bin/env node +import { execFileSync } from 'node:child_process'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const HELPERS = [ + { + name: 'snapshot', + directory: path.join('android', 'snapshot-helper', 'dist'), + releaseTag: true, + }, + { + name: 'ime', + directory: path.join('android', 'ime-helper', 'dist'), + releaseTag: false, + }, +]; + +export function preparePublishAssets(options = {}) { + const root = path.resolve(options.root ?? process.cwd()); + const version = readPackageVersion(root); + const packageAppleRunnerScript = path.join(root, 'scripts', 'package-apple-runner-source.mjs'); + const packageAndroidHelperScript = path.join(root, 'scripts', 'package-android-helper.sh'); + + run(process.execPath, [packageAppleRunnerScript, '--quiet'], root); + for (const helper of HELPERS) { + const outputDirectory = path.join(root, helper.directory); + fs.rmSync(outputDirectory, { recursive: true, force: true }); + const helperArguments = [version]; + if (helper.releaseTag) helperArguments.push(`v${version}`); + helperArguments.push(outputDirectory); + run('sh', [packageAndroidHelperScript, ...helperArguments], root, { + AGENT_DEVICE_ANDROID_HELPER: helper.name, + }); + } + + assertPreparedAssets(root, version); + return { root, version }; +} + +function readPackageVersion(root) { + const packageJson = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')); + if (typeof packageJson.version !== 'string' || packageJson.version.length === 0) { + throw new Error('package.json must declare a non-empty version'); + } + return packageJson.version; +} + +function run(command, arguments_, root, environment = {}) { + execFileSync(command, arguments_, { + cwd: root, + env: { ...process.env, ...environment }, + stdio: ['ignore', 'ignore', 'inherit'], + }); +} + +function assertPreparedAssets(root, version) { + for (const helper of HELPERS) { + const directory = path.join(root, helper.directory); + for (const suffix of ['.apk', '.manifest.json', '.apk.sha256']) { + const filePath = path.join( + directory, + `agent-device-android-${helper.name}-helper-${version}${suffix}`, + ); + if (!isNonEmptyFile(filePath)) { + throw new Error(`Publish asset was not prepared: ${filePath}`); + } + } + } +} + +function isNonEmptyFile(filePath) { + try { + const stat = fs.statSync(filePath); + return stat.isFile() && stat.size > 0; + } catch { + return false; + } +} + +function isMainModule() { + return process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url); +} + +if (isMainModule()) { + const result = preparePublishAssets(); + process.stdout.write(`Prepared publish assets for ${result.version}.\n`); +} diff --git a/scripts/size-report-install.mjs b/scripts/size-report-install.mjs new file mode 100644 index 000000000..5f4482cf2 --- /dev/null +++ b/scripts/size-report-install.mjs @@ -0,0 +1,68 @@ +import { execFileSync } from 'node:child_process'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; + +export function measureCleanInstalledPackage(tarballPath, packageName) { + const workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'agent-device-size-install-')); + const consumerDir = path.join(workDir, 'consumer'); + const npmCache = path.join(workDir, 'npm-cache'); + fs.mkdirSync(consumerDir); + fs.mkdirSync(npmCache); + try { + execFileSync( + 'npm', + [ + 'install', + '--ignore-scripts', + '--no-audit', + '--no-fund', + '--package-lock=false', + '--prefix', + consumerDir, + tarballPath, + ], + { + cwd: consumerDir, + env: { ...process.env, npm_config_cache: npmCache }, + stdio: ['ignore', 'ignore', 'inherit'], + timeout: 5 * 60 * 1000, + }, + ); + const packageDir = path.join(consumerDir, 'node_modules', packageName); + if (!fs.existsSync(packageDir)) { + throw new Error(`Clean install did not create node_modules/${packageName}.`); + } + return measureDirectory(packageDir); + } finally { + fs.rmSync(workDir, { recursive: true, force: true }); + } +} + +export function measureDirectory(root) { + const entries = fs.readdirSync(root, { withFileTypes: true }); + return entries.reduce( + (total, entry) => { + const entryPath = path.join(root, entry.name); + if (entry.isDirectory()) { + const nested = measureDirectory(entryPath); + return { + packageBytes: total.packageBytes + nested.packageBytes, + files: total.files + nested.files, + }; + } + if (entry.isSymbolicLink()) { + return { + packageBytes: total.packageBytes + Buffer.byteLength(fs.readlinkSync(entryPath)), + files: total.files + 1, + }; + } + const stat = fs.statSync(entryPath); + return { + packageBytes: total.packageBytes + stat.size, + files: total.files + 1, + }; + }, + { packageBytes: 0, files: 0 }, + ); +} diff --git a/scripts/size-report-package.mjs b/scripts/size-report-package.mjs index 673158888..df231cb18 100644 --- a/scripts/size-report-package.mjs +++ b/scripts/size-report-package.mjs @@ -47,13 +47,15 @@ export function collectNpmPack(root) { fs.mkdirSync(cachePath, { recursive: true }); const stdout = execFileSync( 'npm', - ['pack', '--dry-run', '--ignore-scripts', '--json', '--cache', cachePath], + ['pack', '--ignore-scripts', '--json', '--pack-destination', cachePath, '--cache', cachePath], { cwd: root, encoding: 'utf8' }, ); const pack = parseNpmPackOutput(stdout); const entries = normalizeNpmPackEntries(pack); + assertPublishPackageContents(entries); return { filename: pack.filename, + tarballPath: path.join(cachePath, pack.filename), tarballBytes: pack.size, unpackedBytes: pack.unpackedSize, files: entries.length, @@ -62,6 +64,35 @@ export function collectNpmPack(root) { }; } +export function assertPublishPackageContents(entries) { + const paths = entries.map((entry) => entry.path); + const requiredAssets = [ + { directory: 'android/snapshot-helper/dist/', suffix: '.apk' }, + { directory: 'android/snapshot-helper/dist/', suffix: '.manifest.json' }, + { directory: 'android/ime-helper/dist/', suffix: '.apk' }, + { directory: 'android/ime-helper/dist/', suffix: '.manifest.json' }, + ]; + const missingAssets = requiredAssets.filter( + (asset) => + !paths.some( + (entryPath) => entryPath.startsWith(asset.directory) && entryPath.endsWith(asset.suffix), + ), + ); + if (missingAssets.length > 0) { + throw new Error( + `npm pack is missing publish assets: ${missingAssets + .map((asset) => `${asset.directory}*${asset.suffix}`) + .join(', ')}`, + ); + } + const forbiddenPaths = paths.filter( + (entryPath) => entryPath === 'scripts' || entryPath.startsWith('scripts/'), + ); + if (forbiddenPaths.length > 0) { + throw new Error(`npm pack includes benchmark or build scripts: ${forbiddenPaths.join(', ')}`); + } +} + function parseNpmPackOutput(stdout) { const parsed = JSON.parse(stdout); return Array.isArray(parsed) ? parsed[0] : parsed; diff --git a/scripts/size-report.mjs b/scripts/size-report.mjs index 231fc95e0..dd91c81b1 100644 --- a/scripts/size-report.mjs +++ b/scripts/size-report.mjs @@ -16,6 +16,8 @@ import { formatPackageComponents, formatPackedFiles, } from './size-report-package.mjs'; +import { measureCleanInstalledPackage } from './size-report-install.mjs'; +import { preparePublishAssets } from './prepare-publish-assets.mjs'; const COMMENT_MARKER = ''; const GITHUB_REQUEST_ATTEMPTS = 4; @@ -131,7 +133,7 @@ function collectReport(root, options) { if (jsFiles.length === 0) { throw new Error('No dist/src JavaScript files found. Run `pnpm build` before measuring size.'); } - prepareGeneratedPackageAssets(root); + preparePublishAssets({ root }); const chunks = jsFiles .map((file) => { @@ -153,12 +155,18 @@ function collectReport(root, options) { { files: 0, rawBytes: 0, gzipBytes: 0 }, ); + const npmPackWithArchive = collectNpmPack(root); + const { tarballPath, ...npmPack } = npmPackWithArchive; + const cleanInstalled = measureCleanInstalledPackage(tarballPath, packageJson.name); + return { packageName: packageJson.name, version: packageJson.version, generatedAt: new Date().toISOString(), js, - npmPack: collectNpmPack(root), + bundled: js, + npmPack, + cleanInstalled, ...(options.startupRuns > 0 ? { startup: collectStartupBenchmarks(root, options.startupRuns) } : {}), @@ -166,17 +174,6 @@ function collectReport(root, options) { }; } -function prepareGeneratedPackageAssets(root) { - const packageAppleRunnerScript = path.join(root, 'scripts', 'package-apple-runner-source.mjs'); - if (!fs.existsSync(packageAppleRunnerScript)) { - return; - } - execFileSync(process.execPath, [packageAppleRunnerScript, '--quiet'], { - cwd: root, - stdio: ['ignore', 'ignore', 'inherit'], - }); -} - function collectStartupBenchmarks(root, runs) { return { runs, @@ -236,6 +233,23 @@ function formatMarkdown(report, baseReport) { metricRow('npm tarball', baseReport?.npmPack.tarballBytes, report.npmPack.tarballBytes), metricRow('npm unpacked', baseReport?.npmPack.unpackedBytes, report.npmPack.unpackedBytes), ]; + if (report.bundled) { + rows.splice( + 2, + 0, + metricRow('npm bundled raw', baseReport?.bundled?.rawBytes, report.bundled.rawBytes), + metricRow('npm bundled gzip', baseReport?.bundled?.gzipBytes, report.bundled.gzipBytes), + ); + } + if (report.cleanInstalled) { + rows.push( + metricRow( + 'npm clean-installed', + baseReport?.cleanInstalled?.packageBytes, + report.cleanInstalled.packageBytes, + ), + ); + } const changedChunks = baseReport ? formatChangedChunks(report.chunks, baseReport.chunks ?? []) diff --git a/src/__tests__/npm-package-scripts.test.ts b/src/__tests__/npm-package-scripts.test.ts index 414e932b6..4e1aa228a 100644 --- a/src/__tests__/npm-package-scripts.test.ts +++ b/src/__tests__/npm-package-scripts.test.ts @@ -59,9 +59,9 @@ test('the npm package build covers every package-owned output before verificatio 'pnpm build:xcuitest:tvos', 'pnpm build:xcuitest:visionos', 'pnpm build:macos-helper:clean', - 'pnpm package:apple-runner:npm', - 'pnpm build:android', + 'pnpm prepare:publish-assets', ]); + assert.equal(script('prepare:publish-assets'), 'node scripts/prepare-publish-assets.mjs'); assert.equal(script('package:npm'), 'pnpm build:package && pnpm check:package'); assert.deepEqual(script('build:android').split(' && '), [ diff --git a/stryker.config.json b/stryker.config.json index 35a3443c6..1a2c7bb0b 100644 --- a/stryker.config.json +++ b/stryker.config.json @@ -34,7 +34,8 @@ "packages/kernel/src/errors.ts", "src/daemon/ref-frame.ts", "src/commands/interaction/runtime/settle.ts", - "src/utils/scroll-edge-state.ts", + "src/snapshot/scroll-edge-state.ts", + "src/snapshot/scroll-edge-state/**/*.ts", "packages/selectors/src/**/*.ts", "!packages/selectors/src/**/*.test.ts", "!packages/selectors/src/internal/__tests__/**", diff --git a/test/ci/size-workflow.test.ts b/test/ci/size-workflow.test.ts index eea13d356..11b1b6515 100644 --- a/test/ci/size-workflow.test.ts +++ b/test/ci/size-workflow.test.ts @@ -27,16 +27,20 @@ test('the preserved size reporter keeps its entrypoint and relative modules toge const measureBase = workflowStep('Measure base size').run ?? ''; expect(preserve).toContain(`mkdir -p ${preservedReportDir}`); - expect(preserve).toContain(`cp scripts/size-report*.mjs ${preservedReportDir}/`); + expect(preserve).toContain('cp scripts/size-report*.mjs'); expect(measureBase).toContain(`node ${preservedReportDir}/size-report.mjs`); const reportSource = fs.readFileSync(path.join(repoRoot, 'scripts/size-report.mjs'), 'utf8'); - const relativeModules = [...reportSource.matchAll(/from '\.\/(size-report-[^']+\.mjs)'/g)].map( + const relativeModules = [...reportSource.matchAll(/from '\.\/([^']+\.mjs)'/g)].map( (match) => match[1], ); expect(relativeModules.length).toBeGreaterThan(0); for (const moduleName of relativeModules) { if (!moduleName) throw new Error('relative size-report import has no module name'); expect(fs.existsSync(path.join(repoRoot, 'scripts', moduleName)), moduleName).toBe(true); + expect( + moduleName.startsWith('size-report-') || preserve.includes(`scripts/${moduleName}`), + `${moduleName} must be preserved for the base checkout`, + ).toBe(true); } }); diff --git a/vitest.config.ts b/vitest.config.ts index 5b0814e18..433f80f76 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -128,6 +128,7 @@ export default defineConfig({ // by a classifier that has to recognise it — see KERNEL_TEST_FILE_RE in // scripts/mutation/modules.ts. 'scripts/__tests__/test-file-size-ratchet.test.ts', + 'scripts/__tests__/eager-closure-budgets.test.ts', 'scripts/__tests__/agent-setup-startup-contract.test.ts', 'scripts/__tests__/npm-skills-exclusion.test.ts', 'scripts/__tests__/simulator-skills-contract.test.ts', @@ -147,9 +148,13 @@ 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 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. + // Package attribution models npm-pack output. Keep it in the fast lane so every new + // package path remains accounted for. 'scripts/__tests__/size-report-package.test.ts', + // Publish preparation spawns only fixture-owned scripts and proves both Android + // helper families are rebuilt through the shared release/size-report owner. + 'scripts/__tests__/prepare-publish-assets.test.ts', + 'scripts/ios-snapshot-benchmark/*.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',