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,55 @@
1
+ # iOS readiness investigation — 2026-11-04
2
+
3
+ ## Findings
4
+
5
+ Blanket iOS unsupported was not justified by the initial sandbox failure.
6
+ Running the probes outside the sandbox established an actual capability
7
+ boundary, separately from tool-access failures.
8
+
9
+ Apple's installed `devicectl` documents `device info lockState` as a read-only
10
+ lock-state query, and `device info displays` supplies structured backlight
11
+ information. Its help documents JSON output as the automation interface.
12
+ [Apple's device command-line documentation](https://developer.apple.com/documentation/xcode/interacting-with-devices-using-the-command-line)
13
+ is the upstream reference. This investigation relies on actual local command
14
+ help and output for the conclusions below.
15
+
16
+ ## Environment and results
17
+
18
+ Target: iPhone 17 Pro simulator, UDID
19
+ `F9243BAF-62A8-4990-8A99-17F527F56FDA`, listed as iOS 26.4.
20
+ CoreDevice CLI version: `651.32`; JSON version: 5.
21
+ No physical iOS device was listed by `devicectl list devices`.
22
+ No server implementation was changed or tested.
23
+
24
+ | Probe | Observed result | Meaning |
25
+ | --- | --- | --- |
26
+ | `xcrun simctl list devices booted` outside sandbox | No booted simulators initially | Initial runtime state only |
27
+ | `xcrun simctl boot <UDID>` / `bootstatus <UDID> -b` | Boot succeeded; later bootstatus confirmed booted | Runtime available |
28
+ | `xcrun devicectl device info lockState --device <UDID> --timeout 10 --json-output <path>` | CoreDevice error 1001, feature `com.apple.coredevice.feature.getlockstate`, capability not supported | Explicit lock-probe unsupported on this target/toolchain |
29
+ | `xcrun devicectl device info displays --device <UDID> --timeout 10 --json-output <path>` | Per-display backlight unknown; top-level backlight `activeOn` after boot | Does not establish lock state |
30
+ | `xcrun simctl io <UDID> enumerate` | Display ports report power On | Port-level evidence only |
31
+ | `xcrun simctl io <UDID> screenConfig --display 1 power off` followed by display probes | Command accepted; display ports still On; devicectl top-level `activeOn` | These probes did not distinguish the commanded display-off state |
32
+ | Repeat display-off experiment after bootstatus completed | Baseline and off JSON both `activeOn` | No reliable sleep inference from this experiment |
33
+ | `screenConfig --display 1 power on`, then `simctl shutdown <UDID>` | Both completed successfully | Restored original shutdown state |
34
+
35
+ The display-off command is not independently verified OS sleep or lock. The
36
+ experiment disproves treating command acknowledgement or port power as sufficient
37
+ readiness evidence; it does not establish that every iOS display API is unusable.
38
+ Transient timing and simulator-specific semantics remain limitations.
39
+
40
+ ## Proposed specification correction
41
+
42
+ - Explicit unsupported is per axis and target, established by capability evidence.
43
+ - Probe failures or uninterpretable observations yield unknown.
44
+ - On this simulator: lock state unsupported through CoreDevice; wakefulness
45
+ unknown with an unverified-signal limitation.
46
+ - Physical iOS lock detection has an Apple CLI route, but no physical iOS device
47
+ was available to validate output or locked/unlocked transitions. The repository's
48
+ current iOS discovery/lifecycle path is simulator-based; extending that is a
49
+ separate scope decision.
50
+ - No private API fallback, app instrumentation, automatic unlock, or security
51
+ changes are proposed.
52
+
53
+ This is investigation evidence, not implementation verification or proof of
54
+ all iOS runtimes. Real lock/unlock transitions and true sleep recovery remain
55
+ unrun on iOS.
@@ -0,0 +1,24 @@
1
+ {
2
+ "device": {
3
+ "platform": "ios",
4
+ "id": "F9243BAF-62A8-4990-8A99-17F527F56FDA"
5
+ },
6
+ "runtime": "v23.11.0",
7
+ "server": "dist/observe/device-readiness.js",
8
+ "result": {
9
+ "wakefulness": "unknown",
10
+ "lock_state": "unsupported",
11
+ "input_ready": null,
12
+ "blockers": [],
13
+ "evidence": [
14
+ {
15
+ "code": "DEVICE_LOCK_SIGNAL_UNSUPPORTED",
16
+ "source": "coredevice",
17
+ "captured_at_ms": 1793823876688
18
+ }
19
+ ],
20
+ "limitations": [
21
+ "DEVICE_WAKEFULNESS_UNVERIFIED"
22
+ ]
23
+ }
24
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "tool": "get_app_readiness",
3
+ "server": {
4
+ "name": "mobile-debug-mcp",
5
+ "version": "0.36.0"
6
+ },
7
+ "runtime": "v23.11.0",
8
+ "result": {
9
+ "success": true,
10
+ "device": {
11
+ "platform": "ios",
12
+ "id": "F9243BAF-62A8-4990-8A99-17F527F56FDA",
13
+ "osVersion": "iOS 26.4",
14
+ "model": "iPhone 17 Pro",
15
+ "simulator": true,
16
+ "booted": true
17
+ },
18
+ "readiness": {
19
+ "state": "settled",
20
+ "scope": "device_ui",
21
+ "basis": "observed",
22
+ "captured_at_ms": 1793823964160,
23
+ "snapshot_session_id": "cd4bc1e2-b26c-40f6-a50e-27472dc00a29",
24
+ "snapshot_revision": 1,
25
+ "sample_count": 2,
26
+ "stable_for_ms": 2846.7576670000003,
27
+ "evidence": [
28
+ {
29
+ "code": "INSUFFICIENT_SAMPLES",
30
+ "source": "ui_tree",
31
+ "captured_at_ms": 1793823961313,
32
+ "snapshot_revision": 1
33
+ },
34
+ {
35
+ "code": "SNAPSHOT_STABLE",
36
+ "source": "ui_tree",
37
+ "captured_at_ms": 1793823964160,
38
+ "snapshot_revision": 1
39
+ }
40
+ ],
41
+ "limitations": [
42
+ "NORMALIZED_UI_ONLY",
43
+ "FOREGROUND_APP_UNVERIFIED",
44
+ "UNRESPONSIVE_SIGNAL_UNSUPPORTED",
45
+ "MANAGED_DEBUGGER_ONLY"
46
+ ],
47
+ "capabilities": {
48
+ "loading": true,
49
+ "transitioning": true,
50
+ "settled": true,
51
+ "unresponsive": false,
52
+ "debugger_paused": true
53
+ }
54
+ },
55
+ "device_readiness": {
56
+ "wakefulness": "unknown",
57
+ "lock_state": "unsupported",
58
+ "input_ready": null,
59
+ "blockers": [],
60
+ "evidence": [
61
+ {
62
+ "code": "DEVICE_LOCK_SIGNAL_UNSUPPORTED",
63
+ "source": "coredevice",
64
+ "captured_at_ms": 1793823962013
65
+ }
66
+ ],
67
+ "limitations": [
68
+ "DEVICE_WAKEFULNESS_UNVERIFIED"
69
+ ]
70
+ },
71
+ "elapsed_ms": 5987.550583
72
+ }
73
+ }
@@ -0,0 +1,249 @@
1
+ # Implementation and verification plan
2
+
3
+ Scope: [intent](intent.md), [approved specification](spec.md). User approved the
4
+ revised contract with “ok, lets proceed” on 2026-11-04.
5
+
6
+ Status: implementation and supported virtual-device checks complete on
7
+ 2026-11-05, including the trace shutdown repair below. Default idb compatibility
8
+ and hardware-specific coverage remain separate limitations.
9
+
10
+ ## Implementation
11
+
12
+ - [x] Add typed, bounded device-state probes with conservative Android parsing and
13
+ capability-based iOS lock evidence; reuse subprocess and operation budgets.
14
+ - [x] Integrate evidence into readiness services, predicate waits, and shared action
15
+ responses, retaining dispatch outcomes and compact/journey evidence.
16
+ - [x] Cover parsing, partial failure, recovery, deadlines, debugger precedence,
17
+ targeting and serialization with self-running unit tests.
18
+ - [x] Update tool docs, descriptions, README and changelog. Review all changed callers.
19
+
20
+ ## Verification
21
+
22
+ Node >=22 (CI Node 22); native Android ADB and local Xcode for iOS probes.
23
+
24
+ | Criteria | Check |
25
+ | --- | --- |
26
+ | 1, 2: launch, awake/asleep/locked/recovery | Updated server against explicit Android emulator; sleep disposable emulator, launch Settings, inspect readiness, restore awake state |
27
+ | 2: transition/conflict/missing fields | Deterministic parser fixtures and failed native probes |
28
+ | 3: blocker gating and unknown compatibility | Readiness/predicate wait unit integration |
29
+ | 4: debugger, targeting, timestamps, compact/journey | Shared action and probe unit integration; existing debugger guard tests |
30
+ | 5: required checks | `npm run verify`, `npm run test:device` |
31
+ | iOS boundary | Updated probe against explicitly booted iPhone 17 Pro simulator; verify capability rejection and unknown wakefulness, then shutdown |
32
+
33
+ Device suite is Android-focused and may contain opt-in checks; record skips.
34
+ Physical iOS unavailable; do not claim physical support. CI additionally compiles
35
+ the Java worker with JDK 17 and checks package contents; the latest results below
36
+ supersede the initial unrun status.
37
+ Use existing Settings app for launch reproduction, no user app data changes.
38
+ Restore emulator wake state and shutdown any simulator booted for this task.
39
+
40
+ ## Results
41
+
42
+ Implementation and required baseline verification completed; detailed evidence
43
+ and later PR repairs follow. Remaining platform risks: vendor-specific Android output,
44
+ extra probe latency, iOS capability differences, and budget expiry during probes.
45
+ No publication, release, or protected-branch change is planned.
46
+
47
+ ## Implementation results
48
+
49
+ Implemented the separate device-readiness contract, Android power/keyguard
50
+ parsers, capability-based iOS lock query, pre-observation wait gating, and shared
51
+ launch/input response evidence. Known blockers break UI-stability continuity;
52
+ recovery requires fresh UI samples. Compact actions and journey action steps
53
+ retain the evidence; the separate adjust_control result also carries it. Dispatch success and verification controls retain their
54
+ existing meanings. Updated tool descriptions and their full compatibility
55
+ fixture, README, tool docs, and changelog.
56
+
57
+ Focused review covered resolved-device ownership, no cross-call cache, partial
58
+ probe failure, conservative parsing, response preservation on observation
59
+ failure, debugger priority, and operation-budget clipping. CoreDevice requires
60
+ its own timeout argument to be >=5 seconds; the parent process enforces the
61
+ 1,000 ms probe deadline. Android 17 repeats a numeric wakefulness enum in a later
62
+ vendor section: parsing now isolates the named current-state section. Both
63
+ runtime discoveries have deterministic regression coverage. No raw native dumps
64
+ are included in the response or retained evidence.
65
+
66
+ ## Initial device evidence — 2026-11-04
67
+
68
+ Local server version 0.36.0, modified checkout based on
69
+ `46f86bae52f09be4499867ac581f9308d3892e41`, Node v23.11.0 (supported >=22).
70
+ This is local source/built-server evidence, not a published package or hosted CI.
71
+
72
+ - **PASS — Android emulator 16, emulator-5554:** started awake/unlocked;
73
+ observed a real transitioning-to-asleep state, launched Settings with
74
+ verification disabled, and established successful dispatch alongside
75
+ DEVICE_ASLEEP. Readiness wait returned READINESS_TIMEOUT while asleep, then
76
+ passed after wake-up with fresh settled UI evidence. Restored awake/unlocked
77
+ and Home. [Evidence](android-evidence.json).
78
+ - **PASS — Pixel 9 Pro, Android 17:** passive state read established
79
+ DEVICE_LOCKED and input_ready=false. No input or state changes were sent.
80
+ The first power sample was conservatively unknown because of duplicate
81
+ vendor-debug fields; the scoped parser subsequently observed awake/unlocked
82
+ with both timestamped signals. These are separate observations of natural
83
+ device changes, not an automated lock/unlock journey.
84
+ [Lock evidence](android-physical-evidence.json),
85
+ [power evidence](android-physical-power-evidence.json).
86
+ - **PASS — iPhone 17 Pro simulator, iOS 26.4:** updated native probe and actual
87
+ get_app_readiness MCP call returned lock_state=unsupported from CoreDevice's
88
+ matching capability rejection, wakefulness=unknown, and input_ready=null.
89
+ UI readiness could still report settled without claiming input readiness.
90
+ Simulator restored to shutdown. [Probe](ios-probe-evidence.json),
91
+ [MCP result](ios-tool-evidence.json).
92
+ - **UNRUN — real locked emulator journey:** this emulator wakes unlocked;
93
+ security settings were not changed. Locked classifier evidence exists on the
94
+ physical Pixel, and locked wait gating has deterministic integration coverage.
95
+ - **UNRUN — physical iOS, live debugger-paused reproduction, true iOS sleep and
96
+ lock/unlock recovery:** no physical iOS device; opt-in debugger fixtures were
97
+ not run. Managed debugger precedence is covered by deterministic tests, not
98
+ claimed as a new live debugger journey.
99
+
100
+ ## Initial verification results — 2026-11-04
101
+
102
+ - `npm run verify`: passed, including the rerun after the Android 17 parser
103
+ refinement. Final lint/build and focused action tests also passed after review. Includes lint, size/dependency checks, TypeScript build,
104
+ complete unit suite, and agent-plugin consistency.
105
+ - Focused device-readiness parser/probe/action tests, readiness tool/wait tests,
106
+ and compact journey tests: passed. Covers partial probe failure, explicit
107
+ unknown/unsupported outcomes, targeting, timestamps, expired budgets, no raw
108
+ error leakage, blocker gating, fresh recovery, and dispatch preservation.
109
+ - `npm run test:device`: passed with a booted iOS simulator. Android/iOS
110
+ screenshots, logs, trees and correlated-evidence checks passed; Android system
111
+ tracing passed with cleanup. Optional coroutine/Kotlin/debugger/interaction
112
+ fixtures and iOS tracing were unrun. The new explicit emulator readiness
113
+ journey was run separately with MCP_READINESS_DEVICE=emulator-5554.
114
+ Initial suite invocation without a booted simulator failed at the iOS
115
+ screenshot prerequisite; booting the simulator resolved that prerequisite.
116
+ - `git diff --check` and changed documentation relative-path checks: passed.
117
+ - CI uses Node 22, plus JDK 17 worker compilation/package checks. These extra
118
+ hosted checks were not run here. No commit, push, release or publication.
119
+
120
+ The GitHub project status move remains unconfirmed; CLI project access lacks
121
+ read:project, and browser actions were interrupted by concurrent user navigation.
122
+ No ticket completion or remote publication is claimed.
123
+
124
+ ## PR #104 review repairs — 2026-11-04
125
+
126
+ Lightweight fixes restoring the approved contract, based on the four attached
127
+ unresolved review threads at head `b78268b`:
128
+
129
+ - Reset UI-change candidate, change kind and stability timestamp when a device
130
+ blocker skips sampling. A deterministic clock test proves the full change
131
+ stability window must elapse again after recovery.
132
+ - Retain last-known blocked power/keyguard axes within the same wait when a
133
+ later probe is inconclusive, including original evidence timestamps and new
134
+ failure limitations. Fresh conclusive evidence clears each axis independently.
135
+ Regression tests cover partial recovery, expired probes and READINESS_TIMEOUT.
136
+ - Preserve the native tap/swipe response's resolved device in the action result.
137
+ No new target resolution or guarded-selection change. Tested implicit,
138
+ explicit and already-resolved targeting in debug/compact responses.
139
+ - Attempt every emulator restoration command independently and always close the
140
+ client in a nested finally. Aggregate failures after all attempts; report PASS
141
+ only after successful cleanup. Injected failures cover each ADB step and close.
142
+
143
+ All three production regressions were demonstrated to fail against the original
144
+ PR head and pass with these fixes. `npm run verify`, focused regressions and
145
+ final lint passed. Device verification results are recorded below.
146
+
147
+ PR repair verification used local Node v23.11.0 and server 0.36.0. On Android 16
148
+ `emulator-5554`, the updated stdio MCP server reported DEVICE_ASLEEP alongside
149
+ successful start_app, ordinary tap and swipe dispatches. The readiness wait
150
+ returned READINESS_TIMEOUT with DEVICE_ASLEEP still present, then recovered
151
+ awake/unlocked; all restoration commands and client close completed. The first
152
+ device-suite attempt timed out at the initial readiness RPC before state
153
+ changes. A focused retry passed, as did the same journey in the serial suite
154
+ retry. No timeout or assertion was weakened. Failed-cleanup paths were verified
155
+ with injected failures rather than disconnecting a real emulator.
156
+
157
+ The serial `MCP_READINESS_DEVICE=emulator-5554 npm run test:device` run passed,
158
+ including Android/iOS screenshots, logs, UI trees, correlated evidence and
159
+ Android trace cleanup. The iPhone 17 Pro iOS 26.4 simulator was temporarily
160
+ booted and restored to shutdown. Optional coroutine/Kotlin/debugger/interaction
161
+ fixtures and iOS tracing remained unrun. Hosted CI/JDK 17 package checks remain
162
+ separate from these local results. `git diff --check` passed.
163
+
164
+ ## Additional checks without physical devices — 2026-11-05
165
+
166
+ Requested follow-up: run remaining checks on emulators/simulators and record
167
+ limits explicitly. No physical device was selected. Existing fixture tests now
168
+ also assert the new device_readiness DEBUGGER_PAUSED blocker and input_ready=false,
169
+ and immediate DEBUGGER_PAUSED from wait_for_app_ready on both platforms.
170
+
171
+ - **PASS — Android emulator debugger**, including the real 60-second pause limit,
172
+ paused readiness and wait blockers, source/locals/stepping, recovery and owned
173
+ resource cleanup. JDK 17.0.11, emulator-5554, Android API 36, extended mode.
174
+ Log: `/tmp/readiness-extra-android-debugger-retry.log`.
175
+ - **PASS — iOS simulator debugger**, including paused readiness and wait blockers,
176
+ async/cancellation, real pause expiry, disconnect and shutdown recovery, and
177
+ fixture cleanup. iPhone 17 Pro simulator, iOS 26.4, Xcode 27.2 (27B52),
178
+ Swift-enabled LLDB, extended mode. Fixture-only command-file triggers are used;
179
+ this proves debugger/readiness behaviour, not successful iOS HID tap delivery.
180
+ Log: `/tmp/readiness-extra-ios-debugger-retry.log`.
181
+
182
+ The first Android extended run failed its expiry assertion with paused state and
183
+ pending cleanup after pause_limit was selected; its unchanged-deadline retry
184
+ passed. The first iOS attempt timed out during fixture installation; the retry
185
+ passed without increasing the install timeout. These initial failures remain
186
+ recorded in `/tmp/readiness-extra-android-debugger.log` and
187
+ `/tmp/readiness-extra-ios-debugger.log`; they are not counted as passes.
188
+
189
+ - **PASS — Android interaction fixture:** clickable/visible waits, stored handles,
190
+ selector journey, enabled-state assertion and labelled SeekBar convergence.
191
+ Log: `/tmp/readiness-extra-interaction.log`.
192
+ - **PASS — Kotlin locals fixture:** known values before/after assignments,
193
+ stale-frame rejection, UI recovery and owned-forward cleanup. Kotlin/stdlib
194
+ 2.0.21 and JDK 17.0.11. Log: `/tmp/readiness-extra-kotlin.log`.
195
+ - **PASS — coroutine fixture:** source stops around suspension, dispatch-thread
196
+ locals, completion, cancellation/finally, pause guards and cleanup. Uses the
197
+ same compiler plus coroutines 1.9.0. No logical coroutine-stack claim.
198
+ Log: `/tmp/readiness-extra-coroutine.log`.
199
+ - **PASS — local CI-equivalent extras:** JDK 17 worker compilation and all 23
200
+ package inventory entries from the current CI workflow. Hosted unit checks
201
+ for PR #104 head `28d73ff` were also confirmed successful.
202
+
203
+ All Android fixtures ran sequentially on emulator-5554, and removed their own
204
+ packages, temporary builds and debugger forwards. No production source changes
205
+ were required. The default iOS trace runner verified capture/cancel/expiry/shutdown cleanup but
206
+ failed its input journey: the installed idb_companion 1.1.8 expects SimulatorKit
207
+ under Developer/Library/PrivateFrameworks, absent in Xcode 27.2. A direct input
208
+ probe confirmed that error. No production or installed Xcode files were changed.
209
+
210
+ Using the documented test-owned Xcode path alias and isolated companion, the
211
+ traced tap-to-Done journey passed with 53 exported sample rows; cancellation,
212
+ expiry, stale-ID rejection and failed-journey handling also passed. The same
213
+ run failed the final server-shutdown partial-directory assertion, so the overall
214
+ compatibility trace run remains **FAIL / partial**, not a pass. A subsequent
215
+ resource check found no recorder processes or owned trace directories left.
216
+ Logs/evidence: `/tmp/readiness-extra-ios-trace.log`,
217
+ `/tmp/readiness-extra-ios-trace.json`,
218
+ `/tmp/readiness-extra-ios-trace-compatible.log` and
219
+ `/tmp/readiness-extra-ios-trace-compatible.json`.
220
+
221
+ Remaining software follow-up: investigate the intermittent iOS trace shutdown
222
+ cleanup assertion and provide a compatible default idb HID backend. True iOS
223
+ sleep/lock recovery cannot be established by this simulator's unsupported lock
224
+ probe and unverified wakefulness signal; physical iOS remains outside this
225
+ verification run. The default emulator's secure-lock journey was not enabled by
226
+ changing security settings; locked wait gating has deterministic coverage and
227
+ prior passive Pixel evidence. No new hardware validation is claimed.
228
+
229
+ Final `npm run verify` passed with the new Android/iOS paused-readiness
230
+ assertions. Changed documentation paths and `git diff --check` passed. The
231
+ compatibility companion, alias and local JDK compilation output were removed,
232
+ and the test-owned simulator was restored to shutdown. The verification-only
233
+ test changes and this plan update remain local and uncommitted.
234
+
235
+
236
+ ### iOS trace shutdown issue repaired — 2026-11-05
237
+
238
+ The shutdown finalizer now removes discarded files after a stop error if the
239
+ owned recorder has exited; it retains the failure reason and never removes a
240
+ possibly live recorder's directory. Regression tests failed on the old code and
241
+ passed with the fix. The full simulator trace journey then passed its original
242
+ shutdown assertion, with 59 exported sample rows and complete cleanup.
243
+ `npm run verify` passed. See [trace repair record](../031-ios-system-traces/plan.md#shutdown-cleanup-repair--2026-11-05).
244
+ This supersedes the earlier failed shutdown check; the default idb compatibility
245
+ limitation and hardware-only coverage remain explicitly separate.
246
+
247
+ The shutdown repair also passed the baseline device suite. Temporary verification
248
+ resources were removed and the simulator restored to shutdown. The repair and
249
+ verification updates are local and uncommitted.
@@ -0,0 +1,134 @@
1
+ # Specification: device readiness blockers
2
+
3
+ Status: approved. User accepted the revised specification with “ok, lets proceed”
4
+ in the current chat on 2026-11-04; implementation is authorised for this scope.
5
+ Intent: [approved intent](intent.md), user response “ok”, 2026-11-04.
6
+ Source: [issue #101](https://github.com/clivejefferies/mobile-debug-tools/issues/101).
7
+
8
+ ## Behaviour
9
+
10
+ Keep launch dispatch, normalized UI stability, and device accessibility distinct.
11
+ Successful `start_app` / `restart_app` dispatch does not establish app visibility,
12
+ unlocked state, or input readiness. Existing success, verification, and
13
+ `observed_app.matchedTarget` fields retain their meanings. Device observations
14
+ must never upgrade dispatch success into proof that the app is usable.
15
+
16
+ Add `device_readiness` to launch/restart results, interaction action results,
17
+ `get_app_readiness`, `wait_for_app_ready`, and readiness-enabled
18
+ `wait_for_ui` / `wait_for_ui_change` results. Preserve it in compact and debug
19
+ responses, including failures after target resolution. Journey action steps use
20
+ the same representation. Ordinary waits without `requireReady` keep their
21
+ predicate semantics. No new tools or input parameters are introduced.
22
+
23
+ The additive object has:
24
+
25
+ - `wakefulness`: `awake | asleep | transitioning | unknown | unsupported`.
26
+ - `lock_state`: `locked | unlocked | unknown | unsupported`.
27
+ - `input_ready`: `false | null`. False means an observed device blocker; null
28
+ means readiness is not established. Awake/unlocked alone never yields true.
29
+ - `blockers`: zero or more of `DEVICE_ASLEEP`, `DEVICE_LOCKED`,
30
+ `DEVICE_TRANSITIONING`, `DEBUGGER_PAUSED`.
31
+ - `evidence`: at most eight entries containing `code`, `source`, and host
32
+ epoch `captured_at_ms`. No raw command output or UI text.
33
+ - `limitations`: bounded codes for unavailable, unsupported, conflicting, or
34
+ failed observations. Each axis has an explicit value even when unavailable.
35
+
36
+ Each successful native sample carries its own timestamp. An unknown axis has
37
+ no invented timestamp. Evidence is scoped to the explicitly resolved device
38
+ and current operation, with no cross-call cache. Observations describe their
39
+ capture time; they cannot guarantee the device remains unchanged afterward.
40
+
41
+ ## Platform evidence
42
+
43
+ Android uses bounded, explicitly targeted ADB reads of `dumpsys power` and
44
+ `dumpsys window policy`. Parse recognized current-state fields only. Awake and
45
+ asleep require explicit wakefulness evidence; a wakefulness-change flag yields
46
+ transitioning. Dozing is treated as asleep for input readiness. Keyguard showing
47
+ means locked even if occluded; explicit non-showing means unlocked. Missing,
48
+ unrecognized, contradictory, or truncated fields produce unknown for the
49
+ affected axis. Device keyguard capability alone is not lock-state evidence.
50
+ Retain independent evidence when one probe fails. Unknown Android variants must
51
+ not be classified by text labels, screenshots, or command success alone.
52
+
53
+ iOS support is determined per signal and target, not by a blanket platform
54
+ assumption. Apple's `devicectl device info lockState` provides a lock-state
55
+ probe, but the tested iOS 26.4 simulator explicitly rejects it with CoreDevice
56
+ error 1001 and feature `com.apple.coredevice.feature.getlockstate`. That explicit
57
+ capability rejection yields unsupported for the lock axis; ordinary probe errors
58
+ yield unknown. A recognized successful structured response may establish lock
59
+ state only once its semantics and compatibility have been verified. Physical
60
+ iOS integration is outside this ticket's existing simulator-only lifecycle path;
61
+ the command's existence does not establish physical-device support in this MCP.
62
+
63
+ For the tested simulator, wakefulness remains unknown: display information is
64
+ available, but neither `simctl io enumerate` port power nor devicectl backlight
65
+ state reliably distinguished an accepted display-off command in this experiment.
66
+ Return `DEVICE_WAKEFULNESS_UNVERIFIED`, not an inferred awake/asleep state.
67
+ Simulator boot status, launch PID, SpringBoard labels, and a static tree do not
68
+ prove awake/unlocked state. No private iOS APIs, helper app, or security-setting
69
+ changes are introduced. See [iOS investigation](ios-investigation.md).
70
+
71
+ ## Integration, precedence, and failure
72
+
73
+ Keep the existing `ReadinessSummary.state` enum and UI evidence unchanged for
74
+ compatibility, but a known device blocker prevents readiness-wait success even
75
+ if the UI appears settled. `get_app_readiness` may successfully report an
76
+ observed blocker; a readiness wait continues within its existing budget to allow
77
+ natural recovery. At expiry it returns `READINESS_TIMEOUT` with last evidence.
78
+ Managed debugger pause retains existing immediate `DEBUGGER_PAUSED` behaviour
79
+ and guard precedence. Combine available blockers without replacing debugger
80
+ session evidence or triggering a UI read while that guard blocks one.
81
+
82
+ Unsupported/unknown device observations do not prevent existing settled-UI wait
83
+ success; documentation must make clear that this still does not prove input
84
+ readiness. After observation failure, never reuse a previous known clear state
85
+ to claim the device is clear. A later fresh sample can establish recovery.
86
+
87
+ For actions, collect one post-action device sample within the existing action
88
+ budget, including verification mode `none`; do not add a UI-tree read for this
89
+ feature. Preserve dispatch outcomes on observation failure and expose unknown
90
+ with a limitation. A sleeping/locked result does not introduce a new input guard
91
+ or retry. Calls already blocked by the debugger retain their existing failure.
92
+ If target resolution fails, return unknown with a target-unavailable limitation.
93
+
94
+ Each native probe has a maximum 1,000 ms timeout, clipped to the remaining
95
+ operation budget. No additional timeout window, retry, detached subprocess, or
96
+ automatic device selection is allowed. Existing cancellation and child-process
97
+ cleanup apply. Do not begin a probe after budget expiry.
98
+
99
+ ## Acceptance and verification
100
+
101
+ 1. Reproduce launch while asleep/locked on a disposable Android emulator where
102
+ practical; record dispatch outcome separately from device-state evidence.
103
+ 2. Verify awake/unlocked, asleep, locked, transition/conflict, missing fields,
104
+ probe failure, expiry, and recovery. Use real-device evidence for supported
105
+ stable states and deterministic fixtures for fleeting transitions.
106
+ 3. Verify a stable lock-screen tree cannot complete a readiness-enabled wait;
107
+ unknown/unsupported remains explicit without changing ordinary predicates.
108
+ 4. Verify managed debugger precedence, targeting, timestamp freshness, compact
109
+ serialization, journey propagation, and absence of raw dumps in responses.
110
+ 5. Run `npm run verify` and applicable `npm run test:device`; report exact device,
111
+ server build, outcomes, cleanup, and unrun platforms. No claim of iOS state
112
+ detection is made without matching runtime evidence.
113
+
114
+ ## Ownership, security, and investigation evidence
115
+
116
+ Affects readiness services/contracts, action execution/serialization, lifecycle
117
+ results, tool descriptions, tools documentation, README, and changelog. Reuse
118
+ existing budgets, subprocess helpers, and resolved-device context. Raw system
119
+ dumps can include private metadata: parse locally and retain only enumerated
120
+ flags. Never unlock, wake, or alter security settings automatically. Verification
121
+ may sleep/wake a disposable emulator and must restore its starting state; do not
122
+ change the user's physical phone for reproduction.
123
+
124
+ On 2026-11-04, connected MCP discovery reported an Android 16 emulator
125
+ `emulator-5554`, a physical Android phone, and no booted iOS simulator. Read-only
126
+ ADB probes on the emulator exposed `mWakefulness=Awake`,
127
+ `mWakefulnessChanging=false`, and keyguard `showing=false` / `mIsShowing=false`.
128
+ These establish available baseline fields only; sleeping/locked reproduction
129
+ and updated-server verification remain unrun. Local sandboxed simctl access
130
+ failed to connect to CoreSimulator, so it supplies no iOS runtime evidence.
131
+
132
+ The user approved this complete revised contract, including additive fields,
133
+ known-blocker wait gating, and per-signal iOS unknown/unsupported behaviour,
134
+ with “ok, lets proceed” on 2026-11-04.
@@ -0,0 +1,41 @@
1
+ # Intent: trustworthy app installation status
2
+
3
+ Status: intent approved; specification pending.
4
+ Originator: GitHub issue #98; author identity not independently checked.
5
+ Captured: 2026-11-05.
6
+ Source: https://github.com/clivejefferies/mobile-debug-tools/issues/98
7
+
8
+ ## Problem
9
+
10
+ Agent feedback reported `appInstalled: false` while Modul8 was installed and
11
+ running. The original device, app context and query are not yet established.
12
+ Current code can represent missing app context or failed installation queries
13
+ as absence; Android system status also queries without explicit device targeting.
14
+ These findings explain possible failure paths, not a reproduction of the report.
15
+
16
+ ## Desired outcome and scope
17
+
18
+ Make installation reporting trustworthy for MCP clients using device inventory
19
+ and system status on Android and iOS. Distinguish confirmed installed, confirmed
20
+ absent and unknown/check-failed results, with explicit app and device context
21
+ and the scope of the check. Review device selection consumers so unknown status
22
+ cannot be mistaken for confirmed absence or used as unsupported targeting evidence.
23
+
24
+ Success includes meaningful coverage for installed/running and absent apps,
25
+ missing app context, multiple devices and failed queries. Reproduce the original
26
+ inconsistency where practical, otherwise document the evidence and limits.
27
+ Align tool descriptions and diagnostics with the accepted contract.
28
+
29
+ ## Constraints and open questions
30
+
31
+ Preserve existing compatibility where possible; any response-contract change
32
+ requires specification approval. Use bounded, device-specific queries and avoid
33
+ installing, removing or launching user apps merely to check installation.
34
+ Automatic installation, broader readiness changes and expanded platform support
35
+ are excluded. Investigation will establish reliable absence evidence on each
36
+ supported platform and how legacy `appInstalled` maps to unknown results.
37
+
38
+ ## Approval
39
+
40
+ The user approved the captured intent with “yes” in this chat on 2026-11-05.
41
+ This approves the problem and scope; response contracts await specification approval.