mobile-debug-mcp 0.35.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/.cursor-plugin/marketplace.json +1 -1
  2. package/.github/workflows/ci.yml +1 -1
  3. package/README.md +96 -24
  4. package/agent-plugin/.antigravity-plugin/README.md +48 -0
  5. package/agent-plugin/.antigravity-plugin/plugin.json +18 -0
  6. package/agent-plugin/.claude-plugin/plugin.json +2 -2
  7. package/agent-plugin/.codex-plugin/plugin.json +1 -1
  8. package/agent-plugin/.cursor-plugin/plugin.json +2 -2
  9. package/agent-plugin/.mcp.json +1 -1
  10. package/agent-plugin/README.md +37 -8
  11. package/agent-plugin/cursor/.cursor-plugin/plugin.json +23 -0
  12. package/agent-plugin/cursor/LICENSE +201 -0
  13. package/agent-plugin/cursor/README.md +9 -0
  14. package/agent-plugin/cursor/skills/mobile-debug-mcp/SKILL.md +261 -0
  15. package/agent-plugin/mcp.json +1 -1
  16. package/agent-plugin/mcp_config.json +13 -0
  17. package/agent-plugin/plugin.json +1 -1
  18. package/agent-plugin/skills/mobile-debug-mcp/SKILL.md +46 -18
  19. package/dist/contracts/device-readiness.js +1 -0
  20. package/dist/debugger/guard.js +4 -4
  21. package/dist/debugger/ios-worker.js +62 -0
  22. package/dist/debugger/ios.js +57 -0
  23. package/dist/debugger/sessions.js +33 -16
  24. package/dist/debugger/worker.js +6 -4
  25. package/dist/interact/index.js +12 -2
  26. package/dist/interact/waits/ui-change-wait.js +9 -2
  27. package/dist/interact/waits/ui-wait.js +7 -3
  28. package/dist/manage/index.js +3 -0
  29. package/dist/manage/ios.js +2 -0
  30. package/dist/observe/device-readiness.js +116 -0
  31. package/dist/observe/evidence.js +31 -0
  32. package/dist/observe/ios-trace/artifact.js +63 -0
  33. package/dist/observe/ios-trace/capabilities.js +86 -0
  34. package/dist/observe/ios-trace/native.js +93 -0
  35. package/dist/observe/ios-trace/notification.js +35 -0
  36. package/dist/observe/ios-trace/process.js +98 -0
  37. package/dist/observe/ios-trace/sessions.js +246 -0
  38. package/dist/observe/readiness-service.js +22 -10
  39. package/dist/observe/readiness.js +34 -4
  40. package/dist/observe/screenshot-encoding.js +4 -0
  41. package/dist/observe/snapshot-collection.js +7 -2
  42. package/dist/observe/system-trace-error.js +7 -0
  43. package/dist/observe/system-trace-router.js +81 -0
  44. package/dist/observe/system-trace.js +4 -8
  45. package/dist/server/definitions/manage.js +3 -2
  46. package/dist/server/handlers/action-execution.js +23 -14
  47. package/dist/server/handlers/compact-interaction.js +106 -0
  48. package/dist/server/handlers/compact-state.js +47 -0
  49. package/dist/server/handlers/debugger-handlers.js +27 -8
  50. package/dist/server/handlers/diagnostic.js +12 -4
  51. package/dist/server/handlers/input.js +2 -0
  52. package/dist/server/handlers/interact.js +2 -0
  53. package/dist/server/handlers/interaction-diagnostics.js +62 -0
  54. package/dist/server/handlers/journey.js +18 -20
  55. package/dist/server/handlers/observe.js +2 -1
  56. package/dist/server/handlers/tool-handlers.js +28 -14
  57. package/dist/server/schemas/debugger-schema.js +10 -7
  58. package/dist/server/schemas/interaction-diagnostics.js +9 -0
  59. package/dist/server/schemas/system-trace-schema.js +14 -9
  60. package/dist/server/tool-definitions.js +9 -4
  61. package/dist/server-core.js +5 -2
  62. package/dist/server.js +5 -5
  63. package/dist/system/android.js +19 -15
  64. package/dist/system/index.js +2 -1
  65. package/dist/utils/android/utils.js +7 -16
  66. package/dist/utils/app-installation.js +77 -0
  67. package/dist/utils/benchmark-metrics.js +43 -0
  68. package/dist/utils/exec.js +4 -0
  69. package/dist/utils/ios/utils.js +7 -11
  70. package/dist/utils/resolve-device.js +3 -2
  71. package/dist/utils/timing.js +3 -3
  72. package/docs/CHANGELOG.md +48 -1
  73. package/docs/agent-plugin-installation-verification.md +39 -0
  74. package/docs/benchmarks/README.md +1 -0
  75. package/docs/benchmarks/end-to-end-latency/README.md +98 -0
  76. package/docs/benchmarks/end-to-end-latency/android-snapshot-pair.json +6532 -0
  77. package/docs/benchmarks/end-to-end-latency/android-snapshot-pair.md +30 -0
  78. package/docs/benchmarks/end-to-end-latency/baseline-attempt-1.json +15901 -0
  79. package/docs/benchmarks/end-to-end-latency/baseline-attempt-1.md +14 -0
  80. package/docs/benchmarks/end-to-end-latency/baseline.json +233843 -0
  81. package/docs/benchmarks/end-to-end-latency/baseline.md +21 -0
  82. package/docs/benchmarks/end-to-end-latency/investigation.md +128 -0
  83. package/docs/benchmarks/end-to-end-latency/ios-smoke.json +84 -0
  84. package/docs/benchmarks/end-to-end-latency/ios-smoke.md +9 -0
  85. package/docs/benchmarks/end-to-end-latency/smoke.json +19601 -0
  86. package/docs/benchmarks/end-to-end-latency/smoke.md +21 -0
  87. package/docs/code-structure.md +3 -1
  88. package/docs/specs/031-ios-system-traces/intent.md +38 -0
  89. package/docs/specs/031-ios-system-traces/investigation.md +92 -0
  90. package/docs/specs/031-ios-system-traces/late-run-failure-evidence.json +32 -0
  91. package/docs/specs/031-ios-system-traces/plan.md +166 -0
  92. package/docs/specs/031-ios-system-traces/pr102-monitor-evidence.json +22 -0
  93. package/docs/specs/031-ios-system-traces/simulator-evidence.json +47 -0
  94. package/docs/specs/031-ios-system-traces/spec.md +135 -0
  95. package/docs/specs/032-ios-runtime-debugger/evidence.json +176 -0
  96. package/docs/specs/032-ios-runtime-debugger/intent.md +38 -0
  97. package/docs/specs/032-ios-runtime-debugger/plan.md +95 -0
  98. package/docs/specs/032-ios-runtime-debugger/report.md +205 -0
  99. package/docs/specs/032-ios-runtime-debugger/spec.md +153 -0
  100. package/docs/specs/033-device-readiness-blockers/android-evidence.json +437 -0
  101. package/docs/specs/033-device-readiness-blockers/android-physical-evidence.json +28 -0
  102. package/docs/specs/033-device-readiness-blockers/android-physical-power-evidence.json +29 -0
  103. package/docs/specs/033-device-readiness-blockers/intent.md +41 -0
  104. package/docs/specs/033-device-readiness-blockers/ios-investigation.md +55 -0
  105. package/docs/specs/033-device-readiness-blockers/ios-probe-evidence.json +24 -0
  106. package/docs/specs/033-device-readiness-blockers/ios-tool-evidence.json +73 -0
  107. package/docs/specs/033-device-readiness-blockers/plan.md +249 -0
  108. package/docs/specs/033-device-readiness-blockers/spec.md +134 -0
  109. package/docs/specs/034-app-installation-status/intent.md +41 -0
  110. package/docs/specs/034-app-installation-status/native-evidence.json +654 -0
  111. package/docs/specs/034-app-installation-status/plan.md +73 -0
  112. package/docs/specs/034-app-installation-status/spec.md +114 -0
  113. package/docs/specs/035-compact-interaction-results/baseline.md +45 -0
  114. package/docs/specs/035-compact-interaction-results/intent.md +38 -0
  115. package/docs/specs/035-compact-interaction-results/plan.md +43 -0
  116. package/docs/specs/035-compact-interaction-results/spec.md +118 -0
  117. package/docs/specs/035-compact-interaction-results/verification.md +111 -0
  118. package/docs/specs/036-end-to-end-interaction-latency/android-snapshot-amendment.md +60 -0
  119. package/docs/specs/036-end-to-end-interaction-latency/android-snapshot-plan.md +32 -0
  120. package/docs/specs/036-end-to-end-interaction-latency/intent.md +37 -0
  121. package/docs/specs/036-end-to-end-interaction-latency/plan.md +59 -0
  122. package/docs/specs/036-end-to-end-interaction-latency/spec.md +126 -0
  123. package/docs/specs/036-end-to-end-interaction-latency/verification.md +87 -0
  124. package/docs/tools/TOOLS.md +3 -2
  125. package/docs/tools/compact-interactions.md +56 -0
  126. package/docs/tools/correlated-evidence.md +6 -0
  127. package/docs/tools/debugger.md +45 -5
  128. package/docs/tools/interact.md +17 -8
  129. package/docs/tools/manage.md +10 -2
  130. package/docs/tools/observe.md +42 -2
  131. package/docs/tools/system-traces.md +81 -14
  132. package/docs/tools/system.md +6 -0
  133. package/package.json +2 -1
  134. package/scripts/agent-plugin.mjs +55 -5
  135. package/src/contracts/device-readiness.ts +8 -0
  136. package/src/debugger/android.ts +1 -1
  137. package/src/debugger/guard.ts +5 -5
  138. package/src/debugger/ios-worker.ts +49 -0
  139. package/src/debugger/ios.ts +45 -0
  140. package/src/debugger/lldb/breakpoints.py +51 -0
  141. package/src/debugger/lldb/inspection.py +109 -0
  142. package/src/debugger/lldb/worker.py +203 -0
  143. package/src/debugger/sessions.ts +24 -12
  144. package/src/debugger/worker.ts +7 -4
  145. package/src/interact/index.ts +13 -2
  146. package/src/interact/waits/ui-change-wait.ts +7 -2
  147. package/src/interact/waits/ui-wait.ts +6 -3
  148. package/src/manage/index.ts +2 -0
  149. package/src/manage/ios.ts +2 -0
  150. package/src/observe/device-readiness.ts +96 -0
  151. package/src/observe/evidence.ts +30 -1
  152. package/src/observe/ios-trace/artifact.ts +55 -0
  153. package/src/observe/ios-trace/capabilities.ts +74 -0
  154. package/src/observe/ios-trace/native.ts +72 -0
  155. package/src/observe/ios-trace/notification.ts +30 -0
  156. package/src/observe/ios-trace/process.ts +82 -0
  157. package/src/observe/ios-trace/sessions.ts +206 -0
  158. package/src/observe/readiness-service.ts +22 -10
  159. package/src/observe/readiness.ts +37 -4
  160. package/src/observe/screenshot-encoding.ts +4 -0
  161. package/src/observe/snapshot-collection.ts +7 -2
  162. package/src/observe/system-trace-error.ts +3 -0
  163. package/src/observe/system-trace-router.ts +61 -0
  164. package/src/observe/system-trace.ts +4 -4
  165. package/src/server/common.ts +2 -2
  166. package/src/server/definitions/manage.ts +3 -2
  167. package/src/server/handlers/action-execution.ts +22 -14
  168. package/src/server/handlers/compact-interaction.ts +91 -0
  169. package/src/server/handlers/compact-state.ts +43 -0
  170. package/src/server/handlers/debugger-handlers.ts +28 -9
  171. package/src/server/handlers/diagnostic.ts +11 -4
  172. package/src/server/handlers/input.ts +2 -0
  173. package/src/server/handlers/interact.ts +2 -0
  174. package/src/server/handlers/interaction-diagnostics.ts +50 -0
  175. package/src/server/handlers/journey.ts +15 -17
  176. package/src/server/handlers/observe.ts +2 -1
  177. package/src/server/handlers/payload.ts +2 -1
  178. package/src/server/handlers/tool-handlers.ts +29 -14
  179. package/src/server/schemas/debugger-schema.ts +10 -7
  180. package/src/server/schemas/interaction-diagnostics.ts +10 -0
  181. package/src/server/schemas/system-trace-schema.ts +15 -9
  182. package/src/server/tool-definitions.ts +8 -4
  183. package/src/server-core.ts +5 -2
  184. package/src/server.ts +4 -4
  185. package/src/system/android.ts +18 -11
  186. package/src/system/index.ts +2 -1
  187. package/src/types.ts +2 -0
  188. package/src/utils/android/utils.ts +8 -10
  189. package/src/utils/app-installation.ts +73 -0
  190. package/src/utils/benchmark-metrics.ts +42 -0
  191. package/src/utils/exec.ts +5 -0
  192. package/src/utils/ios/utils.ts +7 -10
  193. package/src/utils/resolve-device.ts +4 -2
  194. package/src/utils/timing.ts +3 -2
  195. package/test/device/automated/debugger/runtime.android.test.ts +5 -0
  196. package/test/device/automated/debugger/runtime.ios.test.ts +227 -0
  197. package/test/device/automated/interact/compact-results.smoke.ts +58 -0
  198. package/test/device/automated/latency/end-to-end-environment.ts +61 -0
  199. package/test/device/automated/latency/end-to-end-report.ts +90 -0
  200. package/test/device/automated/latency/end-to-end-session.ts +98 -0
  201. package/test/device/automated/latency/end-to-end.ts +149 -0
  202. package/test/device/automated/latency/owned-transport.ts +81 -0
  203. package/test/device/automated/latency/snapshot-pair.ts +143 -0
  204. package/test/device/automated/latency-ios/benchmark.ts +126 -0
  205. package/test/device/automated/observe/correlated-evidence.smoke.ts +7 -5
  206. package/test/device/automated/observe/device-readiness-cleanup.ts +14 -0
  207. package/test/device/automated/observe/device-readiness.android.smoke.ts +78 -0
  208. package/test/device/automated/observe/ios-system-trace.smoke.ts +119 -0
  209. package/test/device/automated/observe/system-trace.smoke.ts +2 -2
  210. package/test/fixtures/contracts/tool-definitions.json +243 -47
  211. package/test/fixtures/ios-debugger-app/Main.swift +95 -0
  212. package/test/fixtures/ios-debugger-app/README.md +27 -0
  213. package/test/fixtures/ios-debugger-app/build.ts +21 -0
  214. package/test/fixtures/latency-journey-app/build.ts +3 -3
  215. package/test/helpers/ios-trace-shutdown.ts +29 -0
  216. package/test/unit/debugger/handle-guards.test.ts +89 -0
  217. package/test/unit/debugger/ios-preparation.test.ts +57 -0
  218. package/test/unit/debugger/ios.test.ts +104 -0
  219. package/test/unit/debugger/lldb-worker.py +166 -0
  220. package/test/unit/debugger/lldb-worker.test.ts +10 -0
  221. package/test/unit/interact/ui-change-readiness-interruption.test.ts +37 -0
  222. package/test/unit/observe/capture_debug_snapshot.test.ts +66 -12
  223. package/test/unit/observe/device-readiness-cleanup.test.ts +24 -0
  224. package/test/unit/observe/device-readiness.test.ts +97 -0
  225. package/test/unit/observe/ios-trace-native.test.ts +90 -0
  226. package/test/unit/observe/ios-trace-sessions.test.ts +154 -0
  227. package/test/unit/observe/readiness-retained-blockers.test.ts +40 -0
  228. package/test/unit/observe/readiness.test.ts +1 -1
  229. package/test/unit/observe/system-trace-router.test.ts +49 -0
  230. package/test/unit/quality/agent-plugin-export.test.ts +38 -0
  231. package/test/unit/server/compact-interaction.test.ts +87 -0
  232. package/test/unit/server/compact-journey-evidence.test.ts +40 -0
  233. package/test/unit/server/compact-review-regressions.test.ts +78 -0
  234. package/test/unit/server/conditional_actions.test.ts +7 -3
  235. package/test/unit/server/correlated-evidence.test.ts +18 -6
  236. package/test/unit/server/end-to-end-report.test.ts +46 -0
  237. package/test/unit/server/input-device-readiness.test.ts +55 -0
  238. package/test/unit/server/interaction-diagnostics.test.ts +45 -0
  239. package/test/unit/server/owned-benchmark-transport.test.ts +32 -0
  240. package/test/unit/server/readiness-retained-deadline.test.ts +32 -0
  241. package/test/unit/server/readiness.test.ts +24 -1
  242. package/test/unit/server/run_journey.test.ts +2 -1
  243. package/test/unit/server/selector_tap_target.test.ts +2 -1
  244. package/test/unit/server/system-trace.test.ts +18 -7
  245. package/test/unit/utils/app-installation.test.ts +78 -0
  246. package/test/unit/utils/benchmark-metrics.test.ts +36 -0
  247. package/test/unit/utils/resolve_device.test.ts +11 -0
@@ -0,0 +1,37 @@
1
+ # End-to-end interaction latency — intent
2
+
3
+ Status: accepted on 2026-11-06. The user replied “ok” to the proposed intent
4
+ and its scope in this chat. This approves investigation and specification;
5
+ specification acceptance is still required before implementation.
6
+ Originator: Clive Jefferies, GitHub issue #100; picked up at the user's request on 2026-11-06.
7
+ Source: https://github.com/clivejefferies/mobile-debug-tools/issues/100
8
+
9
+ ## Problem and outcome
10
+
11
+ Agent feedback reports observations taking several seconds during small UI
12
+ refinements. Establish reproducible measurements of complete MCP action and
13
+ observation round trips, separating MCP overhead from Gradle builds, application
14
+ work, and external test-suite time. Optimize only bottlenecks supported by those
15
+ measurements; a documented negative finding is a valid outcome.
16
+
17
+ ## Scope and success
18
+
19
+ Reuse the existing interaction-latency benchmark and coordinate iOS UI-tree
20
+ measurements with issue #89 and its existing fixture. Measure Android and iOS
21
+ separately and compare relevant response and verification modes. Report repeated
22
+ runs, p50/p95, failed attempts, device/platform, server build, tool versions, and
23
+ component costs: targeting/readiness, subprocess acquisition, screenshots, UI
24
+ trees, waits, verification, and serialization. Identify attribution limits.
25
+
26
+ Any proposed optimization must improve the same baseline while preserving fresh,
27
+ device-scoped evidence, assertions, required verification, deadlines,
28
+ cancellation, and child-process cleanup. Report unavailable platform coverage
29
+ explicitly. Existing MCP clients must retain their agreed contracts.
30
+
31
+ ## Constraints and open questions
32
+
33
+ No speculative caching, hidden failures, reduced verification, or duplicated iOS
34
+ tree fixture. Runtime or contract changes require an accepted specification.
35
+ Investigation will establish available devices, reproducible workloads, useful
36
+ sample counts, and existing timing coverage before specification. No performance
37
+ target or optimization is assumed in advance.
@@ -0,0 +1,59 @@
1
+ # Implementation and verification plan
2
+
3
+ [Intent](intent.md) and [specification](spec.md) accepted by the user in this
4
+ chat, each with “ok” on 2026-11-06. No runtime optimization is authorized.
5
+
6
+ ## Work
7
+
8
+ - Add opt-in request timing events using existing AsyncLocalStorage timing and
9
+ tree metrics. Include subprocess intervals, preserve normal responses/output.
10
+ - Add a dedicated end-to-end benchmark alongside the historical Spec 018
11
+ benchmark. Reuse its fixture and journey, alternate modes, retain failed
12
+ attempts, record build identity and separate setup phases, write new reports.
13
+ - Add deterministic tests for accounting, privacy, disabled instrumentation,
14
+ nested/concurrent timing and owned process cleanup. Bound fixture builds.
15
+ - Run validation, then device measurement. Review reports and document
16
+ bottlenecks, negative findings and coverage limitations. No speculative fixes.
17
+
18
+ ## Verification mapping
19
+
20
+ | Acceptance | Check |
21
+ | --- | --- |
22
+ | Reproducible attempts and percentiles | Unit report checks; repeated Android run (3 warm-ups + 10 attempts/case) with environment/build hashes |
23
+ | Separate phases/components/overhead | Setup ledger; request/tree spans; instrumented/uninstrumented observation comparison |
24
+ | Assertions and platform coverage | Six-transition fixture journey in all modes; report explicit iOS blocker and #89 ownership |
25
+ | Contracts and cleanup | Opt-in instrumentation unit tests; timeout/interrupt owned-process checks; `npm run verify`; `npm run test:device` |
26
+ | Optimization discipline | Report measured findings; no optimization in this stage |
27
+
28
+ Commands: `npm run verify`, `npm run test:device`, and
29
+ `LATENCY_DEVICE_ID=emulator-5554 MCP_ADB_TIMEOUT=30000 npx tsx test/device/automated/latency/end-to-end.ts`.
30
+ Requires Node >=22, installed npm dependencies, Java capable of `--release 8`,
31
+ Android platform/build-tools 36/36.0.0, adb and a running emulator. Fixture build
32
+ uses existing offline SDK tools; no Gradle or network dependency.
33
+
34
+ Device starting state: explicitly named Android emulator, dedicated fixture
35
+ installed/reset by harness; no display/settings changes. Each attempt starts
36
+ with reset fixture and stopped process. Journey asserts every destination;
37
+ observations use its known final screen. Evidence: timing-only JSON/Markdown,
38
+ fixture/build hashes, attempt outcomes, cleanup status. Remove run-owned remote
39
+ temporary files, force-stop fixture and close server on completion/interruption;
40
+ preserve pre-existing apps/settings.
41
+
42
+ iOS: no simulator was booted during specification. No shared #89 static/network
43
+ fixture exists in this checkout; fixture journey remains blocked pending that
44
+ work. Record simulator availability again during execution. Physical iOS is
45
+ excluded. Existing suite may skip optional fixture checks; report actual scope.
46
+
47
+ Risks: instrumentation perturbation, nested intervals, emulator contention,
48
+ long full-verification runs. Keep transport residual unlabelled, document gaps,
49
+ stop measurement after unsafe timeout/cleanup failure, preserve partial reports.
50
+ No commit/push/release is included.
51
+
52
+ ## Results
53
+
54
+ Benchmark code, request instrumentation and timing reports are implemented.
55
+ Android produced nine successful measured samples per case, two additional
56
+ measured failures, three warm-up failures and nine unrun attempts before an
57
+ emulator crash. The iOS smoke reached its readiness check and produced zero
58
+ timing samples. See [findings](../../benchmarks/end-to-end-latency/investigation.md)
59
+ and [verification](verification.md) for evidence, cleanup and remaining gates.
@@ -0,0 +1,126 @@
1
+ # End-to-end interaction latency — specification
2
+
3
+ Status: accepted on 2026-11-06 by the user's “ok” in response to the complete
4
+ specification in this chat. The [intent](intent.md) was
5
+ accepted by the user's “ok” on 2026-11-06. Source: [issue #100](https://github.com/clivejefferies/mobile-debug-tools/issues/100).
6
+
7
+ ## Outcome and boundaries
8
+
9
+ Publish reproducible current-build round-trip measurements and identify where
10
+ time is spent. Reuse Spec 018's Android fixture and stdio MCP harness, Spec 019's
11
+ tree metrics, and existing timing helpers. This stage authorizes benchmark and
12
+ opt-in instrumentation changes, not runtime optimizations. A measured candidate
13
+ requires a specification amendment identifying its path, correctness risks,
14
+ and comparison criteria before implementation. A negative finding is valid.
15
+
16
+ No new MCP tools, arguments, response fields, errors, defaults, verification
17
+ semantics, or caching are introduced. Instrumentation is disabled by default
18
+ and emits only benchmark diagnostics to stderr, preserving stdio protocol output.
19
+
20
+ ## Measurement protocol
21
+
22
+ Measure a locally built server over a real SDK stdio client. Record commit,
23
+ working-tree state and source/build hashes, package and Node versions, host,
24
+ platform/OS, device model, emulator configuration, fixture hash, and applicable
25
+ adb/Xcode/idb versions. Dirty source is explicitly identified; generated reports
26
+ are distinguished from changes to measured source. Capture exact commands,
27
+ timeouts, instrumentation settings, starting state, and run order.
28
+
29
+ Reuse the six-transition Android fixture journey with explicit destination
30
+ assertions. Retain the standalone handle-based comparison. Compare journey
31
+ full/debug, full/compact, light/debug and light/compact to separate response-mode
32
+ cost from verification cost. All comparisons retain destination assertions.
33
+ Do not use verification `none` as evidence of equivalent verification.
34
+
35
+ Each case receives three warm-ups and ten measured attempts. Alternate mode
36
+ order across rounds to reduce ordering bias. Preserve warm-up failures separately
37
+ from measured failures. Report raw per-attempt durations, success/failure and
38
+ stage, sample counts, nearest-rank p50/p95, minimum and maximum. Percentiles
39
+ describe successful attempts only; failures remain visible and prevent a claim
40
+ that the entire run passed. Missing samples produce unavailable statistics,
41
+ never zero latency. Ten samples provide a preliminary p95, not a robust tail
42
+ estimate; state that limitation.
43
+
44
+ Measure `capture_screenshot`, `get_ui_tree`, and screenshot/log-free
45
+ `capture_debug_snapshot` separately on the same known fixture screen. Record
46
+ response byte counts without retaining response contents. Fixture build,
47
+ installation/reset, server startup, and any Gradle or validation-suite execution
48
+ are separate phases excluded from steady-state MCP round trips. Device-side
49
+ application work within a round trip remains included unless independently
50
+ measured; do not mislabel it as pure MCP overhead.
51
+
52
+ ## Attribution
53
+
54
+ Use monotonic clocks for client request-to-response and server intervals.
55
+ Attribute device resolution/readiness, subprocess/tool acquisition, screenshot
56
+ capture/encoding, physical tree acquisition/retries/parsing, waits, dispatch,
57
+ verification/assertions, and response construction/JSON serialization where
58
+ observable. Reuse existing timing and observation events before adding probes.
59
+ Correlate events using generated request/acquisition IDs and serialize requests
60
+ within a run. Document inclusive/nested intervals; do not sum overlapping spans.
61
+
62
+ Report unattributed residual time explicitly. Client round-trip minus server
63
+ timing includes transport, scheduling and uninstrumented work; it is not an
64
+ exact transport or serialization measurement. SDK wire serialization and device
65
+ application execution may remain unattributed. Instrumentation failures or
66
+ missing events are diagnostic gaps, never invented component timings. Compare
67
+ instrumented and uninstrumented observation runs to disclose probe overhead.
68
+
69
+ ## Platform ownership and safety
70
+
71
+ Pin every request to an explicit device; never fall back to a physical phone.
72
+ Run one fixture workload at a time. Reset/install only the dedicated Android
73
+ fixture, restore changed settings, and remove run-owned temporary files and
74
+ processes. Do not change display configuration silently. No real user app data
75
+ is reset. Reports omit device serials, screenshots, UI trees, logs, credentials,
76
+ raw command arguments and unrestricted subprocess output; use fixture aliases
77
+ and sanitized failure classifications.
78
+
79
+ [Issue #89](https://github.com/clivejefferies/mobile-debug-tools/issues/89) owns
80
+ the iOS static/network fixture and paired tree protocol. Reuse it when available;
81
+ do not create a competing fixture here. Standalone iOS observation measurements
82
+ may use an explicitly identified stable simulator screen, separately labelled
83
+ from fixture journeys. If no simulator or shared fixture is available, report
84
+ those cases blocked with prerequisites and runnable next steps. Physical iOS
85
+ coverage is excluded from this simulator investigation.
86
+
87
+ ## Failures and verification
88
+
89
+ Preserve existing action, wait and verification deadlines. Bound harness calls
90
+ and setup operations; on timeout, cancellation or interrupt, record the failed
91
+ attempt and close the owned client/server. Verify owned subprocess exit and
92
+ cleanup; do not kill unrelated processes or leave a timed-out request running
93
+ while measuring another. If safe recovery cannot be established, stop that case
94
+ and report remaining attempts unrun. Never retry invisibly.
95
+
96
+ Use unit checks for percentile/failure accounting, redaction, correlation and
97
+ instrumentation enabled/disabled behavior where changed. Run `npm run verify`
98
+ and applicable `npm run test:device`, plus the repeated benchmark. Runtime
99
+ changes later require focused deadline, cancellation, cleanup, freshness,
100
+ device-isolation and stabilization regression checks and paired results on the
101
+ same fixture, settings and instrumented baseline. Existing Spec 018/019 gates
102
+ remain applicable to their original comparisons; new mode measurements must
103
+ not be forced through unrelated speedup gates.
104
+
105
+ ## Acceptance and reporting
106
+
107
+ 1. Reports reproduce each measured case with environment/build identifiers,
108
+ commands, run order, p50/p95, raw attempts and visible failures.
109
+ 2. Phase and component attribution separate setup/build/test-suite time, expose
110
+ overlap and gaps, and quantify instrumentation overhead.
111
+ 3. Mode comparisons retain assertions; platform coverage and #89 dependencies
112
+ are explicit. Report observed bottlenecks or a justified negative finding.
113
+ 4. No public contract or normal diagnostic-output change occurs. Cleanup,
114
+ timeout and interrupt checks pass for changed harness paths.
115
+ 5. Any later optimization has separately accepted scope and improves its paired
116
+ baseline without correctness or verification regressions.
117
+
118
+ Expected modules: existing latency benchmark/report helpers, shared benchmark
119
+ support where useful, opt-in timing hooks near server/observation/subprocess
120
+ boundaries, focused unit tests, and benchmark documentation. Main risks are
121
+ probe overhead, nested-span double counting, emulator variance, and unavailable
122
+ iOS prerequisites; reports must expose each rather than hide it.
123
+
124
+ Investigation on 2026-11-06 found an attached Android emulator and no booted iOS
125
+ simulator. The existing latency and tree harnesses are Android-only. These are
126
+ prerequisite observations, not current-build performance or correctness results.
@@ -0,0 +1,87 @@
1
+ # Verification evidence
2
+
3
+ ## Local checks
4
+
5
+ - `npm run verify`: **pass** on the final checkout with device workloads stopped. Lint,
6
+ structural/architecture gates, TypeScript build, 112 automated unit files and
7
+ agent-plugin consistency checks completed. Local Node is 23.11.0; CI uses 22.
8
+ - The run overlapping iOS startup and smoke execution failed the existing
9
+ `server/conditional_actions.test.ts` 150 ms action-budget assertion. The
10
+ assertion was preserved and passed on the final run.
11
+ - New deterministic checks cover failed/empty sample accounting, overlapping
12
+ spans, observation validity/device identity, metric redaction, instrumented and
13
+ uninstrumented return behavior, concurrent request isolation, and exception
14
+ recording. The real process test verifies timeout/interrupt cleanup including
15
+ a child that ignores SIGTERM. Darwin's transient post-kill EPERM is treated as
16
+ unconfirmed existence until ESRCH; it never counts as successful cleanup.
17
+ - `git diff --check`: **pass** during implementation; repeat at final review.
18
+
19
+ The final CI workflow also compiles the optional Java debugger worker and checks
20
+ package contents; those additional checks are not part of `npm run verify` and
21
+ were not separately executed for this instrumentation-only change. Android
22
+ integration CI is manually triggered. No hosted CI run or installed-package
23
+ compatibility result is claimed.
24
+
25
+ ## Native evidence
26
+
27
+ All executed Android actions target the named Android 16/API 36 emulator.
28
+ The connected physical Android phone was not selected for actions. For the
29
+ existing device suite, a temporary ADB_PATH forwarding script exposed only the
30
+ emulator in discovery, rejected different explicit serials, and forwarded real
31
+ commands to the installed adb; no tool output or assertions were mocked. The
32
+ benchmark itself uses the real adb and explicit device IDs, and records discovery
33
+ topology because existing device resolution can enumerate other attached devices.
34
+
35
+ - `ADB_PATH=/private/tmp/ticket100-adb MCP_ADB_TIMEOUT=30000 npm run test:device`:
36
+ **blocked / exit 1**. Android compact-result smoke passed dispatch-only,
37
+ post-observation, absent-target, journey, and diagnostics checks. The next
38
+ iOS branch asserted that a booted simulator was required and stopped the suite.
39
+ Optional coroutine, Kotlin and runtime debugger fixture checks reported unrun.
40
+ - Individually executed `capture_screenshot.android.smoke.ts`,
41
+ `get_ui_tree.android.smoke.ts`, and `get_logs.android.smoke.ts` using the same
42
+ forwarding configuration: **pass**. These are real emulator observation
43
+ checks, separate from benchmark timing and iOS coverage.
44
+ - Development `end-to-end.ts --smoke`: **pass**, 11/11 cases, both owned servers
45
+ and fixture cleanup confirmed. This was a harness-development run; later
46
+ attribution/validation additions mean its source/build is not the final
47
+ repeated-run baseline. It is explicitly not performance evidence.
48
+
49
+ The default device smoke leaves Android Settings foreground; it changes no
50
+ settings or user app data. Benchmark attempts reset only the dedicated latency
51
+ fixture, change no display settings and force-stop the fixture on exit. Existing
52
+ fixture installations are retained; run-created installations are removed.
53
+
54
+ ## Platform prerequisites
55
+
56
+ `xcrun simctl list devices booted` initially found no booted simulator. A PATH-only
57
+ check missed idb, but subsequent inspection of the owning `getIdbCmd()` resolver
58
+ found a working common-location fallback; its Python package is fb-idb 1.1.7.
59
+ The original PATH-based unavailable assessment was incorrect. Android raw
60
+ metadata retains that initial PATH probe; it does not establish iOS tool absence.
61
+
62
+ The isolated iPhone 17 Pro booted iOS 27.2 runtime build 24B8117. The local
63
+ stdio smoke failed the Settings readiness assertion after 32.6 seconds and
64
+ recorded zero performance samples. A subsequent Mobile Debug MCP screenshot
65
+ showed a blank app content area. Its UI tree reported the idb prerequisite
66
+ unavailable. Direct `idb list-targets --json` failed with a companion listing
67
+ error, though a later direct `idb_companion --list 1` succeeded. Root cause
68
+ remains unresolved. Both owned servers exited. The temporary simulator was
69
+ shut down and removed, and its remaining idb companion was stopped by matching
70
+ the temporary simulator ID. The full native suite remains incomplete.
71
+
72
+ The shared #89 static/network fixture remains absent. Equivalent fixture
73
+ journeys remain blocked and physical iOS is excluded.
74
+
75
+ ## Original broad performance investigation
76
+
77
+ Android measurement is partial. Nine successful samples per case precede the
78
+ emulator's exit 139. Two measured and three warm-up failures are preserved, with
79
+ nine planned attempts unrun. Both server groups exited. The crashed emulator
80
+ prevented fixture force-stop confirmation. See the
81
+ [investigation report](../../benchmarks/end-to-end-latency/investigation.md).
82
+ Fixture compilation uses offline SDK tools, not Gradle. Validation-suite runtime
83
+ is outside the benchmark; it is not included in request percentiles. Device-side
84
+ application work remains included in request timings and is not separately
85
+ profiled. The later Android tree-reuse candidate is covered by the
86
+ [snapshot verification](android-snapshot-plan.md) and
87
+ [paired comparison](../../benchmarks/end-to-end-latency/android-snapshot-pair.md).
@@ -10,9 +10,10 @@ Use the guides below when you need a tool contract or a specific workflow.
10
10
  - [Observation](observe.md) — screenshots, logs, UI trees, fingerprints, debug snapshots, and app readiness.
11
11
  - [Interaction](interact.md) — UI resolution, actions, waits, and deterministic verification.
12
12
  - [Environment diagnostics](system.md) — toolchain discovery and health checks.
13
+ - [Compact interaction results](compact-interactions.md) — output budgets and read-only diagnostics lookup.
13
14
  - [Evidence correlation](correlated-evidence.md) — action references, capture timing, and freshness.
14
- - [Android system traces](system-traces.md) — performance capture and local Perfetto artifacts.
15
- - [Android runtime debugger](debugger.md) — process attachment, breakpoints, and bounded runtime inspection.
15
+ - [System traces](system-traces.md) — Android Perfetto and iOS simulator Time Profiler capture with local artifacts.
16
+ - [Android and iOS simulator runtime debugger](debugger.md) — process attachment, breakpoints, and bounded runtime inspection.
16
17
 
17
18
  ## Interaction principles
18
19
 
@@ -0,0 +1,56 @@
1
+ # Compact interaction results
2
+
3
+ [Tool reference](TOOLS.md)
4
+
5
+ Use `responseMode: "compact"` on tap, tap_element, swipe, scroll_to_element,
6
+ type_text, press_back, start_app, restart_app and run_journey. Individual actions
7
+ still default to debug; journeys still default to compact. Other tools retain
8
+ their existing response contracts.
9
+
10
+ Compact results preserve action outcomes, delivery/verification status, failure
11
+ codes and retryability, device-readiness blockers/limitations and correlation IDs.
12
+ They summarize condition observations and state-delta counts instead of returning
13
+ full trees or changed elements. `observed_state.status` is `observed` only for
14
+ fresh same-device evidence acquired after dispatch; otherwise it is `unknown`
15
+ with a reason. A precondition tree never establishes the resulting UI. A fingerprint
16
+ observation does not identify a screen or prove the intended outcome. Existing
17
+ `verification` semantics are unchanged and separate from observation freshness.
18
+
19
+ ## Read the original result without replay
20
+
21
+ Every executed compact action/journey step and journey supplies `diagnostics`:
22
+
23
+ ```json
24
+ {"session_id":"UUID","result_id":"UUID","available":true}
25
+ ```
26
+
27
+ Call `get_interaction_diagnostics({"sessionId":"UUID","resultId":"UUID"})`.
28
+ It returns `{"success":true,"result":{...}}` with the retained original payload,
29
+ including full evidence and internally available failure details. This tool performs
30
+ no device action or observation. It does not acquire additional debug snapshots
31
+ that were not requested originally; use debug mode at execution time for those.
32
+
33
+ Retention is in process memory, at most ten minutes, 100 results, 16 MiB total,
34
+ and 1 MiB per entry. Oldest completed entries are evicted first; reads do not extend
35
+ expiry. Oversized originals report `available:false, reason:"RESULT_TOO_LARGE"`.
36
+ Lookup failure returns `success:false, error:{code,message}`. Codes are
37
+ `INVALID_ARGUMENT`, `SESSION_MISMATCH`, and `RESULT_UNAVAILABLE` (expired, evicted,
38
+ unknown or restarted). Do not automatically replay input when diagnostics expire.
39
+ Payloads may include private UI text and errors; compact mode is not redaction.
40
+ Nothing is persisted to disk by this cache.
41
+
42
+ ## Output bounds and compatibility
43
+
44
+ The final compact action text is at most 1,280 UTF-8 bytes plus device-ID bytes.
45
+ Journeys have a base budget of 1,280 bytes plus 1,280 per supplied step and caller
46
+ step-ID/device-ID occurrences (their UTF-8 JSON wire encoding, including necessary
47
+ escapes). Optional summaries may be omitted with
48
+ `truncated:true`; resulting state becomes unknown if its summary must be removed.
49
+ Caller IDs, outcomes, blockers and diagnostics references are preserved. Token
50
+ estimates in development reports use ceil(bytes/4), not tokenizer measurements.
51
+
52
+ Compact clients that inspected full evidence timestamps/observations, condition
53
+ UI trees or state-delta elements must use the diagnostics lookup instead. Evidence
54
+ session/action IDs still work with observation tools' `actionRef`. Debug output
55
+ remains available with its original detailed shape. Journey child diagnostics are
56
+ retained after shared verification and final evidence refresh.
@@ -6,6 +6,12 @@ Use evidence correlation to connect an action with later screenshots, UI trees,
6
6
  and logs, and to understand when those observations were captured. Association
7
7
  does not prove that the action caused an observed change.
8
8
 
9
+ Compact interaction/journey output keeps the correlation IDs and device while
10
+ summarizing observation metadata. Use the returned `diagnostics` reference with
11
+ [`get_interaction_diagnostics`](compact-interactions.md) for original timestamps,
12
+ observation arrays and trace context without replaying input. Debug output retains
13
+ the full evidence envelope described below. `adjust_control` output is unchanged.
14
+
9
15
  ## Associate an observation with an action
10
16
 
11
17
  Covered actions (`start_app`, `restart_app`, `tap`, `tap_element`, `swipe`,
@@ -1,4 +1,4 @@
1
- # Android runtime debugger
1
+ # Runtime debugger
2
2
 
3
3
  [Documentation](../README.md) · [Tool reference](TOOLS.md)
4
4
 
@@ -98,7 +98,7 @@ state-changing command. Timeout or cancellation does not prove nondelivery.
98
98
  Retry incomplete cleanup with `detach_debugger`; never automatically retry
99
99
  attach, step or resume, or kill the app/ADB server. Diagnostics improve failure
100
100
  classification and do not establish the cause of a previously intermittent error.
101
- This contract applies to the Android backend; iOS debugging remains unsupported.
101
+ These details describe Android; see the iOS simulator backend below for its prerequisites and recovery guidance.
102
102
 
103
103
  ## Suspension, limits and cleanup
104
104
 
@@ -108,8 +108,8 @@ racing input submission preserves delivery uncertainty and blocks verification.
108
108
  Journeys preserve completed steps. Other devices are unaffected.
109
109
 
110
110
  `get_app_readiness` returns evidence-backed `debugger_paused` without reading the
111
- UI; readiness waits fail with `DEBUGGER_PAUSED`. This signal covers managed Android
112
- sessions only and does not establish foreground app identity. Raw trees, screenshots
111
+ UI; readiness waits fail with `DEBUGGER_PAUSED`. This signal covers managed Android and iOS simulator
112
+ sessions and does not establish foreground app identity. Raw trees, screenshots
113
113
  and logs remain available within their own timeouts; snapshot/log acquisition may
114
114
  still fail while the app is suspended. Known pauses are annotated on observations.
115
115
 
@@ -134,7 +134,7 @@ step, resume or attach.
134
134
  ## Limits, privacy and evidence
135
135
 
136
136
  There is no expression evaluation, object traversal, method invocation, mutation,
137
- coroutine reconstruction, native debugger, iOS debugger or heap capture. Kotlin
137
+ coroutine reconstruction, native-specific inspection or heap capture. The optional iOS simulator backend is described below. Kotlin
138
138
  results follow emitted bytecode/debug metadata; optimized/obfuscated apps may lack
139
139
  useful source lines or locals. Locals may contain private data: values are returned
140
140
  only on request, without protocol/value logging, persistent dumps or upload.
@@ -178,3 +178,43 @@ is selected. Fixture compilation requires SDK platform/build-tools 36 and `javac
178
178
  - [App management](manage.md): build, install, and launch the app before attaching.
179
179
  - [App readiness](observe.md#app-readiness): understand known debugger-pause evidence.
180
180
  - [Android system traces](system-traces.md): investigate performance without paused-state inspection.
181
+
182
+ ## iOS simulator backend
183
+
184
+ The same eleven tools accept `platform: "ios"` for target capability probes and
185
+ attach. Supply an explicit booted simulator UDID and bundle `appId`; an optional
186
+ `processId` must belong to that simulator's installed app. Requires macOS and full
187
+ Xcode with its Swift-enabled LLDB and Python bindings. Physical iOS devices remain
188
+ unsupported. Attach never launches an app, chooses a host process by name alone,
189
+ replaces another debugger, or changes security settings.
190
+
191
+ For `set_debugger_breakpoint`, supply `sourceFile` (absolute local source path)
192
+ and 1-based `line` for iOS; continue using binary `className` for Android. Exactly
193
+ one selector is required. iOS reports `resolved`, `pending` or `rejected` with
194
+ actual locations; LLDB line relocation is disabled. Pending breakpoints may bind
195
+ when their image loads. Other tool arguments, stop-scoped references, stack/locals
196
+ limits, event cursors, response modes and expiry durations follow the flow above.
197
+
198
+ iOS returns backend-specific capabilities and limitations; `target.uid` may be
199
+ null and `target.executable_path` identifies the verified simulator executable.
200
+ `async_execution_inspection` and `async_stepping` are independent capability flags.
201
+ False means the capability is not established for the backend's supported matrix;
202
+ inspect the limitations. A source breakpoint after await and a shallow local do
203
+ not enumerate suspended tasks or establish logical task identity. Step requests
204
+ acknowledge delivery; inspect the subsequent actual stop. Object locals expose
205
+ only bounded type/opaque identity; Swift standard numeric/bool wrappers are read
206
+ from static storage; Swift strings and other aggregates retain type summaries. No expressions, descriptions, dynamic getters or arbitrary
207
+ LLDB commands execute through this API.
208
+
209
+ Known iOS pauses guard lifecycle actions, input, waits and assertions on that
210
+ platform/device and supply `debugger_paused` readiness. Raw observations remain
211
+ available within their own deadlines. Detach removes owned breakpoints and worker
212
+ resources and releases owned suspension; it never kills the app or simulator.
213
+ A worker exit without confirmed detach/process exit cannot prove cleanup; retry
214
+ `detach_debugger` and inspect `cleanup.remaining_resources`. Failure diagnostics
215
+ provide static Xcode/LLDB-specific recovery guidance without raw worker text.
216
+
217
+ Use the [isolated simulator fixture](../../test/fixtures/ios-debugger-app/README.md)
218
+ for real MCP runtime and async checks. The [implementation plan](../specs/032-ios-runtime-debugger/plan.md)
219
+ records exact verification and unavailable coverage. An installed/published package,
220
+ physical device, or other Xcode version requires separate evidence.
@@ -78,11 +78,11 @@ Reasons are `BASELINE_UNAVAILABLE`, `SESSION_MISMATCH`, `DEVICE_MISMATCH`,
78
78
  there is no valid fresh observation. Error trees cannot authorise input merely
79
79
  because they contain an old revision.
80
80
 
81
- Debug responses retain the full condition tree. Compact responses retain full
82
- fresh evidence on mismatch/unavailable results; this is an exception to their
83
- usual omission of device identifiers and tree contents. Successful compact
84
- conditions contain only observed session/revision and capture time. UI trees may
85
- contain private text; avoid copying them into logs unnecessarily.
81
+ Debug responses retain the full condition tree. Compact responses retain condition
82
+ status/reason and observed session/revision/capture time when they fit the budget.
83
+ Use the returned diagnostics reference with `get_interaction_diagnostics` to read
84
+ the retained original condition tree without replaying input. UI trees may contain
85
+ private text; compact mode is not redaction. See [compact results](compact-interactions.md).
86
86
 
87
87
  The baseline must still be in this process's same-device history: up to eight
88
88
  revisions, retained for ten minutes since a successful observation of that
@@ -714,7 +714,10 @@ and `responseMode` (`compact`, `debug`). Omitted controls retain `full`/`debug`.
714
714
  `none` reports dispatch without post-action accessibility reads. `light` requests
715
715
  one fresh tree; an unavailable observation does not turn successful delivery into
716
716
  a failed action. Use an explicit assertion to establish the intended outcome.
717
- Compact responses retain delivery, retry, lifecycle, and timing fields.
717
+ Compact responses retain delivery, retry, lifecycle and verification fields, with
718
+ bounded observation summaries and a read-only diagnostics reference. Optional
719
+ timing/summaries may be omitted with `truncated:true` to fit the output budget.
720
+ See [compact results](compact-interactions.md) for bounds and migration.
718
721
 
719
722
  `actionTimeoutMs` and `verificationTimeoutMs` are integer budgets, clamped to
720
723
  100–30,000 and 100–60,000 ms respectively. An action timeout after dispatch starts
@@ -789,5 +792,11 @@ for supported states and limits.
789
792
 
790
793
  ## Correlated evidence
791
794
 
792
- Actions and journeys expose identifiers and phase timestamps for linking later
793
- observations. See [evidence correlation](correlated-evidence.md) for scope and limitations.
795
+ Actions and journeys expose identifiers for linking later observations. Debug
796
+ results and retained diagnostics include phase timestamps. See [evidence correlation](correlated-evidence.md) for scope and limitations.
797
+
798
+ Interaction action responses preserve `device_readiness` in compact/debug modes
799
+ and journey action steps, including when verification is disabled. This evidence
800
+ adds no input guard or automatic retry. Readiness-enabled waits reject known
801
+ device blockers; ordinary predicate waits keep their existing semantics.
802
+ See [device readiness evidence](observe.md#device-readiness-evidence).
@@ -23,16 +23,18 @@ Enumerate connected Android devices and iOS simulators.
23
23
  Input (optional):
24
24
 
25
25
  ```json
26
- { "platform": "android" }
26
+ { "platform": "android", "appId": "com.example.app" }
27
27
  ```
28
28
 
29
29
  Response:
30
30
 
31
31
  ```json
32
- { "devices": [ { "id": "emulator-5554", "platform": "android", "osVersion": "11", "model": "sdk_gphone64_arm64", "simulator": true, "appInstalled": false } ] }
32
+ { "devices": [ { "id": "emulator-5554", "platform": "android", "osVersion": "11", "model": "sdk_gphone64_arm64", "simulator": true, "appInstalled": false, "appInstallation": { "status": "absent", "appId": "com.example.app", "deviceId": "emulator-5554", "scope": "android-current-user", "checkedAt": "2026-11-05T20:00:00.000Z" } } ] }
33
33
  ```
34
34
 
35
35
  Notes:
36
+ - Supply `appId` for an installation check. `appInstallation.status` is `installed`, `absent`, or `unknown`; unknown includes a reason and omits legacy `appInstalled`. Missing app context never means absent.
37
+ - Checks identify device/app, scope, and completion time (`checkedAt: null` when no check ran). Android checks cover the current user; iOS covers booted simulators. Unavailable devices and failed checks remain unknown. Installation does not establish running or ready state.
36
38
  - When multiple devices are attached, pass `deviceId` to other tools to target a specific device.
37
39
 
38
40
  ---
@@ -137,3 +139,9 @@ Notes:
137
139
  `appId`, with optional `deviceId`. Resetting app data removes application state;
138
140
  use it only when a clean app state is intended. Execution controls apply to
139
141
  `start_app` and `restart_app`; see [verification modes](interact.md#interaction-execution-controls-rfc-018).
142
+
143
+ Launch/restart action responses include `device_readiness` in compact and debug
144
+ modes, even when verification is disabled. `success` retains dispatch semantics;
145
+ a sleeping/locked observation does not erase successful dispatch or prove that
146
+ the target app is visible. Device-probe failure is reported as unknown without
147
+ changing the dispatch result. See [device readiness evidence](observe.md#device-readiness-evidence).
@@ -146,6 +146,8 @@ Input:
146
146
 
147
147
  Behavior:
148
148
  - Captures screenshot (base64), current activity (Android), screen fingerprint, full UI tree, and recent logs.
149
+ - On Android, the fingerprint uses the fresh tree returned in the same snapshot.
150
+ A failed tree acquisition makes both components unavailable.
149
151
  - Prefers active log stream entries (read_log_stream) and falls back to get_logs when no active stream is available.
150
152
  - Returns partial data when components fail and includes per-part error fields (e.g. `screenshot_error`, `ui_tree_error`).
151
153
  - Caps logs to `logLines` entries and prefers recent entries.
@@ -290,8 +292,9 @@ latest successful capture time and snapshot session/revision, sample
290
292
  count, `stable_for_ms`, up to eight signal-code evidence records, limitations,
291
293
  and capability flags. Evidence excludes UI text and full trees. Managed Android
292
294
  [debugger pauses](debugger.md) are reported from session evidence without acquiring
293
- a UI tree; readiness waits fail with `DEBUGGER_PAUSED`. External-debugger and iOS
294
- pause detection remain unsupported. Unresponsive detection is unsupported; neither
295
+ a UI tree; readiness waits fail with `DEBUGGER_PAUSED`. Supported managed iOS
296
+ simulator debugger sessions also report pauses. External-debugger pause
297
+ detection remains unsupported. Unresponsive detection is unsupported; neither
295
298
  slow hierarchy retrieval nor a deadline expiry proves a pause or unresponsiveness.
296
299
 
297
300
  Tree responses (including compact and nested trees) add a single-sample readiness
@@ -312,3 +315,40 @@ reads remain bounded by their operation deadlines.
312
315
 
313
316
  See [readiness-aware waits](interact.md#readiness-aware-waits) to combine this
314
317
  signal with a specific UI predicate.
318
+
319
+ ### Device readiness evidence
320
+
321
+ `get_app_readiness`, `wait_for_app_ready`, readiness-enabled UI waits and shared
322
+ interaction action results include a separate `device_readiness` object:
323
+
324
+ - `wakefulness`: awake, asleep, transitioning, unknown or unsupported.
325
+ - `lock_state`: locked, unlocked, unknown or unsupported.
326
+ - `blockers`: DEVICE_ASLEEP, DEVICE_LOCKED, DEVICE_TRANSITIONING or DEBUGGER_PAUSED.
327
+ - `input_ready`: false for an observed blocker; otherwise null (not established).
328
+ - `evidence`: bounded signal codes, sources and host epoch `captured_at_ms` values.
329
+ - `limitations`: explicit unavailable/unverified signal codes.
330
+
331
+ Android reads explicitly targeted power/keyguard flags; missing or contradictory
332
+ flags yield unknown. Known device blockers prevent readiness-wait success even
333
+ when a lock-screen tree is stable. Waits allow natural recovery within the same
334
+ budget; expiry retains READINESS_TIMEOUT and the last device observation.
335
+ Within one wait, an inconclusive device probe retains any last-known blocker
336
+ for that axis, including its original evidence timestamp and the new probe-failure
337
+ limitation. `DEVICE_BLOCKER_EVIDENCE_RETAINED` distinguishes that historical
338
+ evidence; only a fresh conclusive state clears the corresponding blocker.
339
+ Unknown/unsupported signals without an earlier blocker retain existing
340
+ UI-stability semantics and cannot prove input readiness. Managed debugger pause
341
+ keeps its existing guard priority.
342
+
343
+ On iOS, the CoreDevice lock query reports unsupported only for an explicit
344
+ matching capability rejection; other failures yield unknown. Successful lock
345
+ response semantics remain unverified. The tested iOS 26.4 simulator rejected
346
+ lock-state queries, and wakefulness remains unknown: display/backlight output
347
+ was not a reliable sleep signal. Physical iOS support was not established.
348
+
349
+ No probe wakes, unlocks or changes security settings. Probe timeouts are at most
350
+ 1,000 ms each, clipped to the existing operation budget, with no retries or
351
+ cross-call cache. Device evidence describes capture time, not an atomic promise
352
+ about later input. Known blockers are checked before readiness UI acquisition.
353
+ Tree-only observations retain their existing single-sample UI summary and do
354
+ not perform these additional device probes.