mobile-debug-mcp 0.34.0 → 0.36.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 (500) hide show
  1. package/.agents/skills/mcp-builder/SKILL.md +44 -64
  2. package/.agents/skills/mcp-builder/references/build-flags.md +44 -43
  3. package/.agents/skills/mcp-builder/references/diagnostics-schema.md +4 -1
  4. package/.agents/skills/mcp-builder/references/toolchain-details.md +49 -62
  5. package/.agents/skills/spec-review/references/spec-review-checklist.md +7 -0
  6. package/.agents/skills/test-authoring/SKILL.md +7 -6
  7. package/.agents/skills/test-authoring/references/repo-test-layout.md +3 -1
  8. package/.agents/skills/test-authoring/references/test-authoring-workflow.md +16 -7
  9. package/.agents/skills/test-authoring/references/test-quality-checklist.md +2 -1
  10. package/.cursor-plugin/marketplace.json +1 -1
  11. package/.github/copilot-instructions.md +14 -36
  12. package/.github/workflows/ci.yml +4 -4
  13. package/AGENTS.md +12 -3
  14. package/CONTRIBUTING.md +79 -0
  15. package/README.md +218 -129
  16. package/agent-plugin/.antigravity-plugin/README.md +48 -0
  17. package/agent-plugin/.antigravity-plugin/plugin.json +18 -0
  18. package/agent-plugin/.claude-plugin/plugin.json +2 -2
  19. package/agent-plugin/.codex-plugin/plugin.json +1 -1
  20. package/agent-plugin/.cursor-plugin/plugin.json +2 -2
  21. package/agent-plugin/.mcp.json +1 -1
  22. package/agent-plugin/README.md +50 -11
  23. package/agent-plugin/cursor/.cursor-plugin/plugin.json +23 -0
  24. package/agent-plugin/cursor/LICENSE +201 -0
  25. package/agent-plugin/cursor/README.md +9 -0
  26. package/agent-plugin/cursor/skills/mobile-debug-mcp/SKILL.md +253 -0
  27. package/agent-plugin/mcp.json +1 -1
  28. package/agent-plugin/mcp_config.json +13 -0
  29. package/agent-plugin/plugin.json +1 -1
  30. package/agent-plugin/skills/mobile-debug-mcp/SKILL.md +62 -17
  31. package/dist/contracts/execution-controls.js +24 -0
  32. package/dist/contracts/selector.js +8 -0
  33. package/dist/contracts/target.js +15 -0
  34. package/dist/contracts/ui.js +1 -0
  35. package/dist/debugger/android.js +2 -1
  36. package/dist/debugger/diagnostics.js +54 -0
  37. package/dist/debugger/guard.js +4 -4
  38. package/dist/debugger/ios-worker.js +62 -0
  39. package/dist/debugger/ios.js +57 -0
  40. package/dist/debugger/protocol.js +33 -0
  41. package/dist/debugger/sessions.js +133 -74
  42. package/dist/debugger/worker.js +59 -46
  43. package/dist/interact/adjustment/adjustment-context.js +41 -0
  44. package/dist/interact/adjustment/adjustment-gestures.js +55 -0
  45. package/dist/interact/adjustment/adjustment-plan.js +18 -0
  46. package/dist/interact/adjustment/adjustment-resolution.js +127 -0
  47. package/dist/interact/adjustment/adjustment-result.js +19 -0
  48. package/dist/interact/adjustment/adjustment-semantic.js +64 -0
  49. package/dist/interact/adjustment/adjustment-verification.js +35 -0
  50. package/dist/interact/adjustment/adjustment.js +52 -0
  51. package/dist/interact/adjustment/control-geometry.js +87 -0
  52. package/dist/interact/adjustment/control-values.js +136 -0
  53. package/dist/interact/adjustment/slider-labels.js +84 -0
  54. package/dist/interact/assertions/screen-assertion.js +37 -0
  55. package/dist/interact/assertions/state-assertion-context.js +35 -0
  56. package/dist/interact/assertions/state-assertion.js +76 -0
  57. package/dist/interact/assertions/state-comparison.js +141 -0
  58. package/dist/interact/assertions/visibility-assertion.js +34 -0
  59. package/dist/interact/conditional-action.js +12 -7
  60. package/dist/interact/index.js +77 -3092
  61. package/dist/interact/input-service.js +1 -0
  62. package/dist/interact/interaction-trace.js +21 -0
  63. package/dist/interact/model.js +1 -0
  64. package/dist/interact/observation.js +1 -0
  65. package/dist/interact/targeting/candidate-ancestor.js +58 -0
  66. package/dist/interact/targeting/candidate-result.js +23 -0
  67. package/dist/interact/targeting/candidate-scoring.js +50 -0
  68. package/dist/interact/targeting/element-helpers.js +216 -0
  69. package/dist/interact/targeting/find-element.js +65 -0
  70. package/dist/interact/targeting/nearby-control.js +56 -0
  71. package/dist/interact/targeting/resolved-elements.js +21 -0
  72. package/dist/interact/targeting/tap-target.js +17 -0
  73. package/dist/interact/targeting/target-scope.js +104 -0
  74. package/dist/interact/waits/legacy-log-wait.js +38 -0
  75. package/dist/interact/waits/legacy-wait-observations.js +103 -0
  76. package/dist/interact/waits/legacy-wait-state.js +34 -0
  77. package/dist/interact/waits/legacy-wait.js +48 -0
  78. package/dist/interact/waits/screen-wait.js +49 -0
  79. package/dist/interact/waits/ui-change-helpers.js +157 -0
  80. package/dist/interact/waits/ui-change-state.js +18 -0
  81. package/dist/interact/waits/ui-change-wait.js +77 -0
  82. package/dist/interact/waits/ui-wait-condition.js +56 -0
  83. package/dist/interact/waits/ui-wait-state.js +38 -0
  84. package/dist/interact/waits/ui-wait.js +106 -0
  85. package/dist/manage/android.js +55 -51
  86. package/dist/manage/index.js +38 -75
  87. package/dist/manage/ios/build-types.js +1 -0
  88. package/dist/manage/ios/build.js +210 -0
  89. package/dist/manage/ios/project-discovery.js +29 -0
  90. package/dist/manage/ios/scheme.js +18 -0
  91. package/dist/manage/ios.js +44 -256
  92. package/dist/observe/android/context.js +1 -0
  93. package/dist/observe/android/current-screen.js +55 -0
  94. package/dist/observe/android/fingerprint.js +13 -0
  95. package/dist/observe/android/log-stream.js +132 -0
  96. package/dist/observe/android/logs.js +107 -0
  97. package/dist/observe/android/screenshot.js +70 -0
  98. package/dist/observe/android/ui-tree.js +107 -0
  99. package/dist/observe/android.js +16 -520
  100. package/dist/observe/evidence.js +114 -75
  101. package/dist/observe/index.js +16 -263
  102. package/dist/observe/ios/context.js +16 -0
  103. package/dist/observe/ios/fingerprint.js +12 -0
  104. package/dist/observe/ios/log-stream.js +105 -0
  105. package/dist/observe/ios/logs.js +168 -0
  106. package/dist/observe/ios/screenshot.js +22 -0
  107. package/dist/observe/ios/ui-elements.js +241 -0
  108. package/dist/observe/ios/ui-tree.js +137 -0
  109. package/dist/observe/ios-trace/artifact.js +63 -0
  110. package/dist/observe/ios-trace/capabilities.js +86 -0
  111. package/dist/observe/ios-trace/native.js +93 -0
  112. package/dist/observe/ios-trace/notification.js +35 -0
  113. package/dist/observe/ios-trace/process.js +98 -0
  114. package/dist/observe/ios-trace/sessions.js +244 -0
  115. package/dist/observe/ios.js +17 -715
  116. package/dist/observe/logs/model.js +1 -0
  117. package/dist/{network → observe/network}/index.js +2 -2
  118. package/dist/observe/readiness-service.js +5 -3
  119. package/dist/observe/readiness.js +33 -14
  120. package/dist/observe/screenshot-encoding.js +41 -0
  121. package/dist/observe/snapshot-collection.js +79 -0
  122. package/dist/observe/snapshot-logs.js +30 -0
  123. package/dist/observe/snapshot-metadata.js +43 -31
  124. package/dist/observe/snapshot-semantic.js +115 -0
  125. package/dist/observe/system-trace-error.js +7 -0
  126. package/dist/observe/system-trace-router.js +81 -0
  127. package/dist/observe/system-trace.js +26 -21
  128. package/dist/runtime/action-results.js +270 -0
  129. package/dist/runtime/clock.js +4 -0
  130. package/dist/server/common.js +1 -256
  131. package/dist/server/definitions/assert.js +162 -0
  132. package/dist/server/definitions/diagnostic.js +118 -0
  133. package/dist/server/definitions/input.js +274 -0
  134. package/dist/server/definitions/manage.js +194 -0
  135. package/dist/server/definitions/observe.js +149 -0
  136. package/dist/server/definitions/target.js +138 -0
  137. package/dist/server/definitions/wait.js +105 -0
  138. package/dist/server/handlers/action-execution.js +163 -0
  139. package/dist/server/handlers/correlation.js +23 -0
  140. package/dist/server/handlers/debugger-handlers.js +67 -0
  141. package/dist/server/handlers/debugger-response.js +9 -0
  142. package/dist/server/handlers/diagnostic.js +77 -0
  143. package/dist/server/handlers/handler-types.js +1 -0
  144. package/dist/server/handlers/input.js +154 -0
  145. package/dist/server/handlers/interact.js +113 -0
  146. package/dist/server/handlers/journey-assertions.js +35 -0
  147. package/dist/server/handlers/journey.js +147 -0
  148. package/dist/server/handlers/manage.js +119 -0
  149. package/dist/server/handlers/observe.js +95 -0
  150. package/dist/server/handlers/payload.js +4 -0
  151. package/dist/server/handlers/tool-handlers.js +170 -0
  152. package/dist/server/schemas/condition-schema.js +2 -0
  153. package/dist/server/{debugger-schema.js → schemas/debugger-schema.js} +20 -12
  154. package/dist/server/{journey-schema.js → schemas/journey-schema.js} +7 -22
  155. package/dist/server/schemas/system-trace-schema.js +22 -0
  156. package/dist/server/tool-definitions.js +58 -1135
  157. package/dist/server-core.js +2 -2
  158. package/dist/server.js +4 -4
  159. package/dist/system/android-status.js +101 -0
  160. package/dist/system/android.js +37 -27
  161. package/dist/system/index.js +13 -439
  162. package/dist/system/ios-status.js +132 -0
  163. package/dist/system/ios.js +11 -8
  164. package/dist/system/model.js +1 -0
  165. package/dist/system/probes.js +105 -0
  166. package/dist/system/status-summary.js +43 -0
  167. package/dist/system/unsupported-status.js +52 -0
  168. package/dist/utils/android/commands.js +89 -0
  169. package/dist/utils/android/gradle.js +139 -0
  170. package/dist/utils/android/logs.js +103 -0
  171. package/dist/utils/android/ui-tree.js +233 -0
  172. package/dist/utils/android/utils.js +6 -564
  173. package/dist/utils/cli/idb/idb-helper.js +4 -6
  174. package/dist/utils/cli/idb/install-idb.js +13 -9
  175. package/dist/utils/cli/ios/preflight-ios.js +42 -38
  176. package/dist/utils/ios/utils.js +48 -46
  177. package/dist/utils/java.js +65 -49
  178. package/dist/utils/resolve-device.js +4 -2
  179. package/dist/utils/ui/index.js +26 -26
  180. package/docs/CHANGELOG.md +67 -1
  181. package/docs/README.md +38 -0
  182. package/docs/agent-plugin-installation-verification.md +39 -0
  183. package/docs/benchmarks/README.md +18 -0
  184. package/docs/benchmarks/interaction-latency/README.md +14 -0
  185. package/docs/benchmarks/interaction-latency/final.md +4 -1
  186. package/docs/benchmarks/interaction-latency/ios-validation.md +2 -0
  187. package/docs/benchmarks/ui-tree-performance/README.md +24 -16
  188. package/docs/benchmarks/ui-tree-performance/comparison.md +11 -10
  189. package/docs/code-structure.md +120 -0
  190. package/docs/specs/001-state-verification/spec.md +16 -14
  191. package/docs/specs/002-richer-element-identity/spec.md +12 -10
  192. package/docs/specs/003-wait-and-synchronization-reliability/spec.md +12 -10
  193. package/docs/specs/004-action-verification-routing/spec.md +3 -3
  194. package/docs/specs/005-unified-action-execution-and-verification-model/spec.md +2 -0
  195. package/docs/specs/006-runtime-action-instrumentation-and-binding-layer/spec.md +2 -0
  196. package/docs/specs/007-actionability-resolution-and-executable-target-selection/spec.md +3 -1
  197. package/docs/specs/008-adjustable-control-support-and-semantic-value-manipulation/spec.md +3 -4
  198. package/docs/specs/009-semantic-control-modeling-for-custom-and-composite-controls/spec.md +2 -0
  199. package/docs/specs/010-verification-stabilization-and-temporal-convergence/spec.md +2 -2
  200. package/docs/specs/011-recovery-and-replanning-for-failed-or-ambiguous-interaction-flows/spec.md +2 -2
  201. package/docs/specs/011.1-recovery-contract-types-and-runtime-wiring-spec/spec.md +2 -0
  202. package/docs/specs/012-action-trace-and-xecution-observability/spec.md +2 -3
  203. package/docs/specs/013-wait-and-synchronization-reliability/spec.md +19 -19
  204. package/docs/specs/014-actionability-resolution/spec.md +20 -18
  205. package/docs/specs/015-adjustable-control-support/spec.md +17 -15
  206. package/docs/specs/016-environment-tools/spec.md +20 -20
  207. package/docs/specs/018-interaction-latency-and-batched-journeys/spec.md +2 -0
  208. package/docs/specs/019-ui-tree-observation-performance/spec.md +3 -1
  209. package/docs/specs/020-conditional-actions/intent.md +5 -3
  210. package/docs/specs/020-conditional-actions/plan.md +8 -9
  211. package/docs/specs/020-conditional-actions/spec.md +4 -2
  212. package/docs/specs/021-app-readiness-signals/intent.md +4 -2
  213. package/docs/specs/021-app-readiness-signals/plan.md +7 -6
  214. package/docs/specs/021-app-readiness-signals/spec.md +3 -1
  215. package/docs/specs/022-correlated-evidence/intent.md +4 -4
  216. package/docs/specs/022-correlated-evidence/plan.md +10 -11
  217. package/docs/specs/022-correlated-evidence/spec.md +3 -1
  218. package/docs/specs/023-android-system-traces/intent.md +3 -2
  219. package/docs/specs/023-android-system-traces/plan.md +5 -7
  220. package/docs/specs/023-android-system-traces/spec.md +3 -1
  221. package/docs/specs/024-android-heap-dump-capture/intent.md +3 -1
  222. package/docs/specs/025-android-runtime-debugger/intent.md +4 -3
  223. package/docs/specs/025-android-runtime-debugger/plan.md +3 -1
  224. package/docs/specs/025-android-runtime-debugger/spec.md +4 -3
  225. package/docs/specs/026-code-structure-and-quality-gates/health-plan.md +88 -0
  226. package/docs/specs/026-code-structure-and-quality-gates/intent.md +47 -0
  227. package/docs/specs/026-code-structure-and-quality-gates/plan.md +191 -0
  228. package/docs/specs/026-code-structure-and-quality-gates/spec.md +138 -0
  229. package/docs/specs/026-code-structure-and-quality-gates/verification-final.json +200 -0
  230. package/docs/specs/026-code-structure-and-quality-gates/verification-thin-facade.json +154 -0
  231. package/docs/specs/026-code-structure-and-quality-gates/verification.json +136 -0
  232. package/docs/specs/027-debugger-failure-diagnostics/intent.md +43 -0
  233. package/docs/specs/027-debugger-failure-diagnostics/plan.md +86 -0
  234. package/docs/specs/027-debugger-failure-diagnostics/spec.md +133 -0
  235. package/docs/specs/028-compact-debugger-responses/intent.md +41 -0
  236. package/docs/specs/028-compact-debugger-responses/plan.md +112 -0
  237. package/docs/specs/028-compact-debugger-responses/spec.md +108 -0
  238. package/docs/specs/029-kotlin-locals-validation/report.md +119 -0
  239. package/docs/specs/030-android-coroutine-validation/evidence.json +475 -0
  240. package/docs/specs/030-android-coroutine-validation/intent.md +47 -0
  241. package/docs/specs/030-android-coroutine-validation/plan.md +147 -0
  242. package/docs/specs/030-android-coroutine-validation/report.md +240 -0
  243. package/docs/specs/030-android-coroutine-validation/spec.md +107 -0
  244. package/docs/specs/031-ios-system-traces/intent.md +38 -0
  245. package/docs/specs/031-ios-system-traces/investigation.md +92 -0
  246. package/docs/specs/031-ios-system-traces/late-run-failure-evidence.json +32 -0
  247. package/docs/specs/031-ios-system-traces/plan.md +138 -0
  248. package/docs/specs/031-ios-system-traces/pr102-monitor-evidence.json +22 -0
  249. package/docs/specs/031-ios-system-traces/simulator-evidence.json +47 -0
  250. package/docs/specs/031-ios-system-traces/spec.md +135 -0
  251. package/docs/specs/032-ios-runtime-debugger/evidence.json +176 -0
  252. package/docs/specs/032-ios-runtime-debugger/intent.md +38 -0
  253. package/docs/specs/032-ios-runtime-debugger/plan.md +95 -0
  254. package/docs/specs/032-ios-runtime-debugger/report.md +205 -0
  255. package/docs/specs/032-ios-runtime-debugger/spec.md +153 -0
  256. package/docs/tools/TOOLS.md +31 -18
  257. package/docs/tools/{evidence.md → correlated-evidence.md} +9 -1
  258. package/docs/tools/debugger.md +120 -4
  259. package/docs/tools/interact.md +42 -20
  260. package/docs/tools/manage.md +25 -44
  261. package/docs/tools/observe.md +55 -23
  262. package/docs/tools/system-traces.md +89 -14
  263. package/docs/tools/system.md +12 -5
  264. package/package.json +12 -8
  265. package/scripts/agent-plugin.mjs +55 -5
  266. package/scripts/architecture-graph.mjs +69 -0
  267. package/scripts/check-architecture.mjs +47 -0
  268. package/scripts/code-quality-baseline.json +1 -0
  269. package/scripts/code-quality.mjs +161 -0
  270. package/src/contracts/execution-controls.ts +26 -0
  271. package/src/contracts/selector.ts +17 -0
  272. package/src/contracts/target.ts +19 -0
  273. package/src/contracts/ui.ts +94 -0
  274. package/src/debugger/android.ts +3 -2
  275. package/src/debugger/diagnostics.ts +43 -0
  276. package/src/debugger/guard.ts +10 -5
  277. package/src/debugger/ios-worker.ts +49 -0
  278. package/src/debugger/ios.ts +45 -0
  279. package/{worker → src/debugger/java}/DebuggerWorker.java +9 -3
  280. package/src/debugger/lldb/breakpoints.py +51 -0
  281. package/src/debugger/lldb/inspection.py +109 -0
  282. package/src/debugger/lldb/worker.py +203 -0
  283. package/src/debugger/protocol.ts +37 -0
  284. package/src/debugger/sessions.ts +326 -155
  285. package/src/debugger/worker.ts +57 -41
  286. package/src/interact/adjustment/adjustment-context.ts +83 -0
  287. package/src/interact/adjustment/adjustment-gestures.ts +48 -0
  288. package/src/interact/adjustment/adjustment-plan.ts +23 -0
  289. package/src/interact/adjustment/adjustment-resolution.ts +104 -0
  290. package/src/interact/adjustment/adjustment-result.ts +34 -0
  291. package/src/interact/adjustment/adjustment-semantic.ts +53 -0
  292. package/src/interact/adjustment/adjustment-verification.ts +60 -0
  293. package/src/interact/adjustment/adjustment.ts +49 -0
  294. package/src/interact/adjustment/control-geometry.ts +120 -0
  295. package/src/interact/adjustment/control-values.ts +141 -0
  296. package/src/interact/adjustment/slider-labels.ts +84 -0
  297. package/src/interact/assertions/screen-assertion.ts +39 -0
  298. package/src/interact/assertions/state-assertion-context.ts +48 -0
  299. package/src/interact/assertions/state-assertion.ts +64 -0
  300. package/src/interact/assertions/state-comparison.ts +168 -0
  301. package/src/interact/assertions/visibility-assertion.ts +41 -0
  302. package/src/interact/conditional-action.ts +18 -12
  303. package/src/interact/index.ts +89 -3494
  304. package/src/interact/input-service.ts +11 -0
  305. package/src/interact/interaction-trace.ts +36 -0
  306. package/src/interact/model.ts +109 -0
  307. package/src/interact/observation.ts +7 -0
  308. package/src/interact/targeting/candidate-ancestor.ts +49 -0
  309. package/src/interact/targeting/candidate-result.ts +24 -0
  310. package/src/interact/targeting/candidate-scoring.ts +42 -0
  311. package/src/interact/targeting/element-helpers.ts +243 -0
  312. package/src/interact/targeting/find-element.ts +47 -0
  313. package/src/interact/targeting/nearby-control.ts +46 -0
  314. package/src/interact/targeting/resolved-elements.ts +20 -0
  315. package/src/interact/targeting/tap-target.ts +22 -0
  316. package/src/interact/targeting/target-scope.ts +121 -0
  317. package/src/interact/waits/legacy-log-wait.ts +30 -0
  318. package/src/interact/waits/legacy-wait-observations.ts +55 -0
  319. package/src/interact/waits/legacy-wait-state.ts +48 -0
  320. package/src/interact/waits/legacy-wait.ts +34 -0
  321. package/src/interact/waits/screen-wait.ts +37 -0
  322. package/src/interact/waits/ui-change-helpers.ts +184 -0
  323. package/src/interact/waits/ui-change-state.ts +26 -0
  324. package/src/interact/waits/ui-change-wait.ts +59 -0
  325. package/src/interact/waits/ui-wait-condition.ts +52 -0
  326. package/src/interact/waits/ui-wait-state.ts +55 -0
  327. package/src/interact/waits/ui-wait.ts +84 -0
  328. package/src/manage/android.ts +56 -50
  329. package/src/manage/index.ts +63 -93
  330. package/src/manage/ios/build-types.ts +14 -0
  331. package/src/manage/ios/build.ts +230 -0
  332. package/src/manage/ios/project-discovery.ts +26 -0
  333. package/src/manage/ios/scheme.ts +16 -0
  334. package/src/manage/ios.ts +67 -298
  335. package/src/observe/android/context.ts +1 -0
  336. package/src/observe/android/current-screen.ts +63 -0
  337. package/src/observe/android/fingerprint.ts +13 -0
  338. package/src/observe/android/log-stream.ts +127 -0
  339. package/src/observe/android/logs.ts +110 -0
  340. package/src/observe/android/screenshot.ts +79 -0
  341. package/src/observe/android/ui-tree.ts +113 -0
  342. package/src/observe/android.ts +17 -531
  343. package/src/observe/evidence.ts +122 -70
  344. package/src/observe/index.ts +24 -286
  345. package/src/observe/ios/context.ts +22 -0
  346. package/src/observe/ios/fingerprint.ts +12 -0
  347. package/src/observe/ios/log-stream.ts +103 -0
  348. package/src/observe/ios/logs.ts +179 -0
  349. package/src/observe/ios/screenshot.ts +26 -0
  350. package/src/observe/ios/ui-elements.ts +266 -0
  351. package/src/observe/ios/ui-tree.ts +143 -0
  352. package/src/observe/ios-trace/artifact.ts +55 -0
  353. package/src/observe/ios-trace/capabilities.ts +74 -0
  354. package/src/observe/ios-trace/native.ts +72 -0
  355. package/src/observe/ios-trace/notification.ts +30 -0
  356. package/src/observe/ios-trace/process.ts +82 -0
  357. package/src/observe/ios-trace/sessions.ts +204 -0
  358. package/src/observe/ios.ts +18 -749
  359. package/src/observe/logs/model.ts +11 -0
  360. package/src/{network → observe/network}/index.ts +2 -2
  361. package/src/observe/readiness-service.ts +6 -4
  362. package/src/observe/readiness.ts +42 -21
  363. package/src/observe/screenshot-encoding.ts +32 -0
  364. package/src/observe/snapshot-collection.ts +69 -0
  365. package/src/observe/snapshot-logs.ts +26 -0
  366. package/src/observe/snapshot-metadata.ts +51 -31
  367. package/src/observe/snapshot-semantic.ts +153 -0
  368. package/src/observe/system-trace-error.ts +3 -0
  369. package/src/observe/system-trace-router.ts +61 -0
  370. package/src/observe/system-trace.ts +28 -19
  371. package/src/runtime/action-results.ts +376 -0
  372. package/src/runtime/clock.ts +9 -0
  373. package/src/server/common.ts +9 -359
  374. package/src/server/definitions/assert.ts +164 -0
  375. package/src/server/definitions/diagnostic.ts +120 -0
  376. package/src/server/definitions/input.ts +276 -0
  377. package/src/server/definitions/manage.ts +196 -0
  378. package/src/server/definitions/observe.ts +151 -0
  379. package/src/server/definitions/target.ts +140 -0
  380. package/src/server/definitions/wait.ts +107 -0
  381. package/src/server/handlers/action-execution.ts +164 -0
  382. package/src/server/handlers/correlation.ts +20 -0
  383. package/src/server/handlers/debugger-handlers.ts +58 -0
  384. package/src/server/handlers/debugger-response.ts +7 -0
  385. package/src/server/handlers/diagnostic.ts +86 -0
  386. package/src/server/handlers/handler-types.ts +7 -0
  387. package/src/server/handlers/input.ts +173 -0
  388. package/src/server/handlers/interact.ts +135 -0
  389. package/src/server/handlers/journey-assertions.ts +39 -0
  390. package/src/server/handlers/journey.ts +132 -0
  391. package/src/server/handlers/manage.ts +141 -0
  392. package/src/server/handlers/observe.ts +116 -0
  393. package/src/server/handlers/payload.ts +36 -0
  394. package/src/server/handlers/tool-handlers.ts +170 -0
  395. package/src/server/schemas/condition-schema.ts +2 -0
  396. package/src/server/schemas/debugger-schema.ts +46 -0
  397. package/src/server/{journey-schema.ts → schemas/journey-schema.ts} +7 -22
  398. package/src/server/schemas/system-trace-schema.ts +23 -0
  399. package/src/server/tool-definitions.ts +67 -1143
  400. package/src/server-core.ts +2 -2
  401. package/src/server.ts +4 -4
  402. package/src/system/android-status.ts +124 -0
  403. package/src/system/android.ts +33 -21
  404. package/src/system/index.ts +21 -525
  405. package/src/system/ios-status.ts +147 -0
  406. package/src/system/ios.ts +14 -10
  407. package/src/system/model.ts +41 -0
  408. package/src/system/probes.ts +114 -0
  409. package/src/system/status-summary.ts +47 -0
  410. package/src/system/unsupported-status.ts +55 -0
  411. package/src/types.ts +16 -106
  412. package/src/utils/android/commands.ts +81 -0
  413. package/src/utils/android/gradle.ts +132 -0
  414. package/src/utils/android/logs.ts +103 -0
  415. package/src/utils/android/ui-tree.ts +239 -0
  416. package/src/utils/android/utils.ts +16 -556
  417. package/src/utils/cli/idb/check-idb.ts +4 -4
  418. package/src/utils/cli/idb/idb-helper.ts +6 -8
  419. package/src/utils/cli/idb/install-idb.ts +15 -9
  420. package/src/utils/cli/ios/preflight-ios.ts +39 -31
  421. package/src/utils/cli/ios/run-ios-ui-tree-tap.ts +4 -4
  422. package/src/utils/ios/utils.ts +60 -61
  423. package/src/utils/java.ts +62 -43
  424. package/src/utils/resolve-device.ts +9 -6
  425. package/src/utils/ui/index.ts +28 -28
  426. package/test/device/automated/debugger/coroutine-lifecycle.ts +27 -0
  427. package/test/device/automated/debugger/coroutine-support.ts +140 -0
  428. package/test/device/automated/debugger/coroutine.android.test.ts +169 -0
  429. package/test/device/automated/debugger/kotlin.android.test.ts +127 -0
  430. package/test/device/automated/debugger/runtime.android.test.ts +19 -3
  431. package/test/device/automated/debugger/runtime.ios.test.ts +221 -0
  432. package/test/device/automated/interact/interaction.android.test.ts +56 -0
  433. package/test/device/automated/observe/ios-system-trace.smoke.ts +119 -0
  434. package/test/device/automated/observe/system-trace.smoke.ts +1 -1
  435. package/test/device/manual/interact/modul8_selector_tap.manual.ts +1 -1
  436. package/test/fixtures/contracts/tool-definitions.json +3696 -0
  437. package/test/fixtures/coroutine-app/MainActivity.kt +100 -0
  438. package/test/fixtures/coroutine-app/README.md +48 -0
  439. package/test/fixtures/coroutine-app/build.ts +35 -0
  440. package/test/fixtures/debugger-app/MainActivity.java +21 -0
  441. package/test/fixtures/debugger-app/MainActivity.kt +32 -0
  442. package/test/fixtures/debugger-app/README.md +52 -0
  443. package/test/fixtures/debugger-app/build.ts +25 -15
  444. package/test/fixtures/ios-debugger-app/Main.swift +95 -0
  445. package/test/fixtures/ios-debugger-app/README.md +27 -0
  446. package/test/fixtures/ios-debugger-app/build.ts +21 -0
  447. package/test/fixtures/latency-journey-app/README.md +2 -0
  448. package/test/fixtures/readiness-app/README.md +2 -0
  449. package/test/helpers/ios-trace-shutdown.ts +29 -0
  450. package/test/unit/debugger/coroutine-lifecycle.test.ts +43 -0
  451. package/test/unit/debugger/diagnostic-sessions.test.ts +67 -0
  452. package/test/unit/debugger/diagnostics.test.ts +80 -0
  453. package/test/unit/debugger/guards.test.ts +4 -0
  454. package/test/unit/debugger/handle-guards.test.ts +88 -0
  455. package/test/unit/debugger/ios-preparation.test.ts +57 -0
  456. package/test/unit/debugger/ios.test.ts +104 -0
  457. package/test/unit/debugger/lldb-worker.py +166 -0
  458. package/test/unit/debugger/lldb-worker.test.ts +10 -0
  459. package/test/unit/debugger/preparation.test.ts +32 -0
  460. package/test/unit/debugger/protocol.test.ts +15 -0
  461. package/test/unit/debugger/sessions.test.ts +1 -1
  462. package/test/unit/interact/adjustment_service.test.ts +42 -0
  463. package/test/unit/interact/adjustment_verification.test.ts +35 -0
  464. package/test/unit/interact/clock_dependencies.test.ts +63 -0
  465. package/test/unit/interact/element_helpers.test.ts +19 -0
  466. package/test/unit/interact/legacy_wait_service.test.ts +17 -0
  467. package/test/unit/interact/state_comparison.test.ts +20 -0
  468. package/test/unit/interact/target_scope.test.ts +35 -0
  469. package/test/unit/network/get_network_activity.test.ts +1 -1
  470. package/test/unit/observe/ios-trace-native.test.ts +90 -0
  471. package/test/unit/observe/ios-trace-sessions.test.ts +131 -0
  472. package/test/unit/observe/readiness.test.ts +1 -1
  473. package/test/unit/observe/screenshot-encoding.test.ts +30 -0
  474. package/test/unit/observe/snapshot-logs.test.ts +14 -0
  475. package/test/unit/observe/system-trace-router.test.ts +49 -0
  476. package/test/unit/quality/agent-plugin-export.test.ts +38 -0
  477. package/test/unit/quality/architecture.test.ts +60 -0
  478. package/test/unit/quality/code-quality.test.ts +58 -0
  479. package/test/unit/quality/interaction_boundaries.test.ts +24 -0
  480. package/test/unit/server/conditional_actions.test.ts +1 -1
  481. package/test/unit/server/conditional_schema.test.ts +2 -2
  482. package/test/unit/server/debugger-response.test.ts +63 -0
  483. package/test/unit/server/system-trace.test.ts +12 -3
  484. package/test/unit/server/tool_definitions_parity.test.ts +8 -0
  485. package/dist/server/debugger-handlers.js +0 -38
  486. package/dist/server/system-trace-schema.js +0 -17
  487. package/dist/server/tool-handlers.js +0 -1000
  488. package/docs/ROADMAP.md +0 -646
  489. package/docs/benchmarks/ui-tree-performance/bridge-probe.json +0 -29
  490. package/docs/benchmarks/ui-tree-performance/initial-baseline.json +0 -59560
  491. package/docs/specs/baseline-spec-v0.md +0 -312
  492. package/docs/specs/mcp-tooling-spec-v1.md +0 -446
  493. package/src/server/debugger-handlers.ts +0 -29
  494. package/src/server/debugger-schema.ts +0 -37
  495. package/src/server/system-trace-schema.ts +0 -17
  496. package/src/server/tool-handlers.ts +0 -1008
  497. /package/dist/{server/condition-schema.js → contracts/condition.js} +0 -0
  498. /package/dist/server/{readiness-schema.js → schemas/readiness-schema.js} +0 -0
  499. /package/src/{server/condition-schema.ts → contracts/condition.ts} +0 -0
  500. /package/src/server/{readiness-schema.ts → schemas/readiness-schema.ts} +0 -0
@@ -0,0 +1,240 @@
1
+ # Android coroutine debugger assessment — issue #93
2
+
3
+ Date: 2026-11-02. Source: [issue #93](https://github.com/clivejefferies/mobile-debug-tools/issues/93).
4
+ Scope: [accepted specification](spec.md); [fixture/reproduction](../../../test/fixtures/coroutine-app/README.md).
5
+
6
+ ## Method and evidence boundaries
7
+
8
+ The fixture uses explicit CompletableDeferred gates, two named single-thread
9
+ executor dispatchers, a nested async child and a cancellation/finally path.
10
+ It uses no debug probes or app instrumentation. The runner uses the existing
11
+ MCP stdio server and records source/APK/server/worker/dependency fingerprints,
12
+ compiler line/local tables and actual stops, stacks and locals. Fresh UI-tree
13
+ assertions independently establish completion and cancellation recovery.
14
+ Opaque MCP thread IDs are scoped to each stop; different ID strings alone do
15
+ not establish a dispatcher change. Live synthetic thread-name locals and fixture
16
+ checks establish the named dispatcher execution instead.
17
+
18
+ Environment selected: emulator-5554, Android 16/API 36; Node 22.23.4;
19
+ Kotlin compiler/stdlib 2.0.21; kotlinx-coroutines-core-jvm 1.9.0;
20
+ fixture compiler JDK 17.0.11; Android SDK/build-tools 36. The debugger's existing
21
+ Java discovery selects Android Studio JBR, which reports 25.0.3 on this host;
22
+ setting fixture JAVA_HOME does not override that debugger discovery order.
23
+ The local run used a temporary wrapper around the cached Kotlin embeddable
24
+ compiler; the fixture README documents a standard Kotlin CLI installation.
25
+ No result is inferred for other compiler/runtime versions.
26
+
27
+ ## Results
28
+
29
+ Focused emulator journey: **PASS**. Full local output:
30
+ `/tmp/mobile-debug-93-emulator.log`; compact checked-in [evidence](evidence.json).
31
+
32
+ | Check | Observed result |
33
+ | --- | --- |
34
+ | Before/after gate suspension | PASS: source stops; `known=42` readable on both sides |
35
+ | Dispatcher change | PASS: live locals `fixture-first` then `fixture-second` |
36
+ | Nested child work | PASS: helper argument `43`; final `answer=44` |
37
+ | Into/over/out | PASS inside the synchronous helper/increment calls |
38
+ | Suspension-boundary step | Observed stop at `completeWork` entry, line 50; no logical-coroutine-following claim |
39
+ | Safety and recovery | PASS: pause guard, stale-frame rejection, cancelled event wait with usable session |
40
+ | Job cancellation | PASS: child finally source stop, joined cancellation, fresh `Coroutine cancelled` UI |
41
+ | Completion/recovery | PASS: fresh `Coroutine result 44` UI after detach |
42
+ | Owned cleanup | PASS: complete detach, forwards preserved, package/build directory removed |
43
+ | Physical-device journey | UNRUN; explicit serial selection is required |
44
+
45
+ Source SHA-256: `5978b835673876642c256b1c688975e78018addc1f68219371bc47c8cc29a92b`.
46
+ Built server/dist SHA-256: `4f7bf452fc0022c8feb492f11a25c34ac5e360baff9f77d752dd0d248105d581`.
47
+ Worker source SHA-256: `fb15e7add65fb3682d86153818d02378084a46fcd49b2c23c0eafdba290f8323`.
48
+ Compiler/APK/dependency metadata and hashes are in the evidence file. APK signing
49
+ is ephemeral, so subsequent APK hashes can differ.
50
+
51
+ Initial cancellation recovery failed to reach its expected UI state while
52
+ retaining the prior completion text. The test now starts cancellation from a
53
+ fresh fixture process after detaching the boundary-step assessment. This is
54
+ fixture-owned lifecycle isolation, not a debugger cleanup operation.
55
+ An initial thread-name assertion also exposed compiler elimination of unused
56
+ locals; the fixture now uses those values after the breakpoint so their emitted
57
+ scope covers inspection. Assertions were not weakened to treat absent values
58
+ as a dispatcher proof.
59
+
60
+ ## Interpretation and follow-up recommendation
61
+
62
+ Existing source breakpoints can be a useful way to inspect separately executing
63
+ parts of a coroutine. Source bindings must include generated binary class names
64
+ from the actual compiler output. A shallow locals result and current-thread stack
65
+ are execution evidence; they do not enumerate suspended coroutines, establish a
66
+ parent/child job identity or recover an asynchronous logical stack. A local spilled
67
+ into a continuation field need not appear in the current frame's local table.
68
+
69
+ **No-go for implementing generic coroutine reconstruction in this ticket.** A
70
+ separate feasibility design should first prove Android-compatible discovery of
71
+ active and suspended continuations, stable job identity and ownership/parent-child
72
+ relationships, and a versioned mapping from DebugMetadata/state labels to logical
73
+ source frames. This would require inspection beyond the existing shallow locals
74
+ API, or explicitly agreed app instrumentation, with privacy and compatibility
75
+ limits. No such mechanism has been validated here.
76
+
77
+ The upstream [kotlinx-coroutines-debug documentation](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-debug/)
78
+ describes JVM agent-based coroutine tracking and explicitly identifies Android
79
+ instrumentation limitations. It is not evidence that installing that JVM agent
80
+ would supply an Android solution. The [DebugProbes API](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-debug/kotlinx.coroutines.debug/-debug-probes/)
81
+ describes tracking creation, suspension and resumption with instrumentation and
82
+ overhead; this fixture does not enable it. Android-specific alternatives and
83
+ metadata compatibility remain design questions. Defer that capability design
84
+ until after the bounded assessment and iOS parity, as the issue requires.
85
+
86
+ ## Limits
87
+
88
+ Physical-device verification, other Kotlin/coroutine versions, optimized or
89
+ obfuscated apps, inline suspend functions, process/device disconnect and forced
90
+ host termination are unrun unless separately recorded below. Signal handling
91
+ requests MCP cancellation then finally attempts owned cleanup; SIGKILL/host loss
92
+ cannot run finally. No iOS runtime-debugger support is claimed. Hosted CI has not
93
+ run; it separately compiles the worker with JDK 17 and checks package contents,
94
+ and its ordinary device workflow does not provision this opt-in Kotlin compiler.
95
+ Local build/test evidence is not an installed or published-package check.
96
+
97
+ ## Repository verification
98
+
99
+ `npm run verify` **PASS** on Node 22.23.4: lint, structural/architecture checks,
100
+ TypeScript build, all 89 unit files and plugin consistency. Final log:
101
+ `/tmp/mobile-debug-93-final-verify.log`. The sandbox blocked tsx IPC creation;
102
+ verification passed in the authorized run outside the sandbox without changing
103
+ checks. Changed relative links, new-file whitespace and `git diff --check` passed.
104
+
105
+ The focused review found no required production-code or schema change. Fixture
106
+ subprocesses/polls are bounded; package targeting is explicit; the runner refuses
107
+ pre-existing fixture installations and keeps normal debugger cleanup separate
108
+ from resetting its own app between independent cases. At the original verification,
109
+ changes were local, uncommitted and unpushed.
110
+
111
+ Full `npm run test:device` **PASS**, all 12 files, with
112
+ `MCP_COROUTINE_DEVICE=emulator-5554 MCP_KOTLIN_DEVICE=emulator-5554 MCP_DEBUGGER_DEVICE=emulator-5554`
113
+ and the documented local compiler/stdlib/coroutine paths set. Log:
114
+ `/tmp/mobile-debug-93-device.log`. The coroutine assessment passed again on the
115
+ same source/server/worker fingerprints (ephemeral APK signing produced SHA-256
116
+ `6cc95ae8ad9d254444e9704a7526d62a0ab1c8354a5624d6695789eedd429f82`).
117
+ Existing Kotlin/Java debugger, interaction, Android/iOS observation smoke,
118
+ correlated-evidence and Android system-trace checks passed. These iOS checks do
119
+ not verify iOS runtime debugging. The new fixture's package, temporary outputs
120
+ and owned forwards were removed; no physical-device coroutine check ran.
121
+
122
+ ## PR #96 repair evidence
123
+
124
+ The original results above predate the readiness-race fix: they establish the
125
+ recorded locations/values, but the original UI readiness alone did not prove
126
+ that the gate wait had suspended before release/cancellation. New readiness
127
+ runs as queued work behind the coroutine on its own single-thread executor,
128
+ which cannot execute until that coroutine yields. The repaired dispatcher
129
+ breakpoint class is `MainActivity$completeWork$3`.
130
+
131
+ Overall JSON PASS now follows cleanup, and cleanup failures are reported as FAIL.
132
+ Forward comparisons select only the target serial and sort entries. The new
133
+ unit regressions and repository verification passed (90 unit files, Node 22.23.3;
134
+ `/tmp/pr96-verify.log`). The first attempt on a restored emulator
135
+ snapshot hit install/uninstall timeouts; that real cleanup failure emitted JSON FAIL
136
+ without an overall PASS (`/tmp/pr96-device.log`). The task-owned leftover package
137
+ was removed after a cold start. Final device-rerun evidence is recorded below;
138
+ the original suspension-readiness evidence is superseded.
139
+
140
+ Final repair verification: `npm run verify` **PASS**, all 90 unit files, Node
141
+ 22.23.3 (`/tmp/pr96-final-verify.log`). Unit checks cover successful cleanup before
142
+ PASS, work failure, cleanup failure, simultaneous failures without losing either
143
+ error, exact serial filtering, other-device churn and order normalization.
144
+
145
+ Full device-suite attempts **FAIL** during installation/cleanup on the restored
146
+ and cold-started emulator (`/tmp/pr96-device.log`, `/tmp/pr96-device-cold.log`).
147
+ Incremental installation continued after host-side timeout, leaving a differently
148
+ signed package; the task-owned package was removed. A focused streamed-install
149
+ run used an external temporary ADB_PATH wrapper adding `--no-incremental` only
150
+ for install, without changing repository timeouts or assertions.
151
+
152
+ That focused run **passed** completion, verified the queued readiness and updated
153
+ `completeWork$3` breakpoints, named dispatchers, known values, synchronous steps,
154
+ stale/pause guards, cancelled wait recovery and the bounded suspension-step
155
+ observation. It then **failed** at `am start -W` restarting the fixture before
156
+ cancellation, followed by an uninstall timeout. Its overall JSON FAIL preserves
157
+ both errors (`/tmp/pr96-focused-streamed.log`). Repaired cancellation readiness
158
+ is compiler-checked but its device journey is **UNRUN**; remaining suite checks
159
+ were not reached. No full native pass is claimed for this repair.
160
+
161
+ Current fixture source SHA-256:
162
+ `d4656e3736cc245230bc000c6574288b145df47957dd7ee511ea98717afde4df`.
163
+ Final independent package query returned no owned fixture package; no ADB forwards
164
+ remained and temporary build output was removed. The review fixes introduce no
165
+ production server behaviour or contract change. Physical-device checks and hosted
166
+ CI are unrun for this revision.
167
+
168
+ ## Successful retry on the maintainer's running emulator
169
+
170
+ The repaired coroutine assessment **PASS**ed in full on emulator-5554, Android
171
+ 16/API 36, commit `1497693`, Node 22.23.3. This supersedes the earlier incomplete
172
+ cancellation verification: queued readiness, cancellation/finally, cancelAndJoin,
173
+ fresh `Coroutine cancelled` UI, completion, stepping, guards, cancelled event wait
174
+ and owned cleanup all passed. The overall JSON PASS followed successful cleanup.
175
+ Log: `/tmp/pr96-user-emulator.log`.
176
+
177
+ Fixture source SHA-256 remains
178
+ `d4656e3736cc245230bc000c6574288b145df47957dd7ee511ea98717afde4df`;
179
+ server/dist remains `4f7bf452fc0022c8feb492f11a25c34ac5e360baff9f77d752dd0d248105d581`.
180
+ APK SHA-256: `3ec87db96cd87f9bd7ca27472dde8c1b57d2789d9f808714362ca4ba2ee95c83`.
181
+ Kotlin/stdlib 2.0.21, coroutines 1.9.0 and fixture JDK 17.0.11 were unchanged.
182
+ Local setup used the temporary ADB_PATH wrapper for streamed installation and
183
+ `JAVA_TOOL_OPTIONS='-Xmx512m -XX:TieredStopAtLevel=1'` for host JVM startup.
184
+ No assertions or deadlines changed. The user-started emulator remains running;
185
+ only fixture-owned resources were removed. Physical-device coroutine validation
186
+ remains unrun.
187
+
188
+ The full device-suite retry passed coroutine, Kotlin/Java debugger, interaction
189
+ and Android screenshot checks before failing the iOS screenshot test's ambiguous
190
+ target selection (`/tmp/pr96-user-device-suite.log`). Separate Android logs,
191
+ UI-tree and correlated-evidence checks passed; the correlation script then failed
192
+ its iOS prerequisite because no iOS simulator was running
193
+ (`/tmp/pr96-user-android-remaining.log`). Full-suite status remains **FAIL** for
194
+ those iOS setup requirements, while the repaired Android coroutine journey is
195
+ verified **PASS**, including cancellation and cleanup.
196
+
197
+ A separate Android system-trace check failed its cancellation-state assertion
198
+ (`failed` / `ACTION_TIMEOUT`, expected `cancelled`); its finally cleanup retry
199
+ completed. Log: `/tmp/pr96-user-trace.log`. This is an additional observed
200
+ limitation in the broader smoke checks; it does not invalidate the coroutine
201
+ journey's successful cancellation and cleanup. No trace code or assertions were
202
+ changed, and no complete device-suite pass is claimed.
203
+
204
+ ## Perfetto timeout investigation — 2026-11-02
205
+
206
+ The earlier `cancel_system_trace` failure reported ACTION_TIMEOUT in the bounded
207
+ stop/termination phase. Its original log does not identify which ADB command or
208
+ process-exit wait exhausted the budget, so the root cause remains undetermined.
209
+ No tracing source or smoke-test changes appear in PR #96.
210
+
211
+ On the same running Android 16/API 36 emulator-5554 and server build
212
+ `e90ed0831de4059f1e2b213ed0c050298cf2e55c0cc0aef9ff4ea2a38b6062a0`:
213
+
214
+ - Three direct native/session start-cancel probes **PASS**ed with complete cleanup;
215
+ cancellation took 372, 373 and 390 ms. Log: `/tmp/pr96-perfetto-probe.log`.
216
+ - Three full MCP smoke journeys **PASS**ed: Settings journey assertion, readable
217
+ trace content, explicit stop, cancellation, automatic duration completion,
218
+ stale-trace rejection and active shutdown cleanup. Logs:
219
+ `/tmp/pr96-perfetto-retest.log`, `/tmp/pr96-perfetto-instrumented-1.log`,
220
+ `/tmp/pr96-perfetto-instrumented-2.log`.
221
+ - The final run used an assertion-identical temporary test copy with a server
222
+ preloader recording native-command timing. Across 71 commands, the only
223
+ nonzero exits were five expected Perfetto help probes (exit 1 is supported).
224
+ Maximum process lookup was 111 ms; maximum signal command 63 ms; maximum start
225
+ 247 ms. No command timed out. Log: `/tmp/pr96-perfetto-mcp-timings.log`.
226
+ - The first attempted instrumentation relied on NODE_OPTIONS, which the SDK's
227
+ default subprocess environment did not forward to the server. That smoke pass
228
+ remains valid but supplies no server timing evidence. The final run explicitly
229
+ preloaded the diagnostic module in both server subprocesses.
230
+ - Final independent checks found no MCP trace files and no forwards on the
231
+ emulator. Host test artifacts were removed by each smoke journey. The emulator
232
+ remains running; no settings or user-app data were changed.
233
+
234
+ Classification: the previously observed timeout is **not reproduced**, with an
235
+ intermittent timing failure still possible. Passing reruns do not establish its
236
+ cause or prove it fixed. No production change, timeout increase, assertion change
237
+ or test suppression was made. Current Perfetto verification passes; the earlier
238
+ failed observation is retained rather than reclassified as a pass. Any recurrence
239
+ needs command timings at the failing invocation to distinguish ADB transport,
240
+ process identity lookup, signalling and process-exit delay.
@@ -0,0 +1,107 @@
1
+ # Android coroutine validation specification — issue #93
2
+
3
+ Status: accepted by the maintainer’s second “ok” in this chat on 2026-11-02. Implements the
4
+ [accepted intent](intent.md), approved by “ok” in this chat on 2026-11-02.
5
+
6
+ ## Outcome and compatibility
7
+
8
+ Establish what the existing Android JDI tools actually expose for an isolated
9
+ Kotlin coroutine, and publish a reproducible assessment. No server capability,
10
+ schema, response shape, error code or default changes. Android only; iOS runtime
11
+ debugging remains unsupported. Java and synchronous Kotlin fixture journeys
12
+ retain their current behaviour. Any reproduced production defect is reported
13
+ with evidence and handled separately through the shared process.
14
+
15
+ ## Fixture and prerequisites
16
+
17
+ Add an opt-in coroutine variant of the disposable debugger fixture, built from
18
+ checked-in source using the existing direct Kotlin/D8/aapt2 pipeline. Initially
19
+ target Kotlin compiler/stdlib 2.0.21, kotlinx-coroutines-core-jvm 1.9.0, JDK 17,
20
+ Android SDK/build-tools 36 and Node 22+. Require explicit local dependency paths;
21
+ do not download dependencies at test runtime, add server dependencies, enable
22
+ debug probes or instrument user apps. Record actual versions and dependency
23
+ hashes. Missing or incompatible prerequisites produce an actionable blocked
24
+ result, not a pass.
25
+
26
+ Use a separate fixture package so the coroutine journey cannot replace the
27
+ existing Java/Kotlin fixture. Refuse installation if that package is already
28
+ present; remove only the package installed by this run. Run sequentially on an
29
+ explicit device serial. Initial target is emulator-5554; an attached Pixel 9 Pro
30
+ is a separate optional verification target, never selected automatically.
31
+
32
+ The fixture owns two named single-thread executor dispatchers. This makes a
33
+ thread change observable without relying on scheduler chance. A run exposes a
34
+ known local, suspends on a controllable gate, continues on the other dispatcher,
35
+ performs nested child work, then completes with a fixed visible result. A
36
+ separate cancellation run suspends a child, cancels and joins it, executes its
37
+ finally block and shows a cancellation result. Gates and UI state establish
38
+ ordering; arbitrary sleeps do not establish suspension. Close jobs/executors
39
+ on activity destruction. Use compiler-emitted line/class metadata to identify
40
+ generated continuation classes; do not assume every source line belongs to
41
+ MainActivity or has a usable breakpoint.
42
+
43
+ ## Existing MCP workflow
44
+
45
+ Use `get_debugger_capabilities`, `attach_debugger`,
46
+ `set_debugger_breakpoint`, `wait_for_debugger_event`, `get_debugger_stack`,
47
+ `get_debugger_locals`, `step_debugger`, `resume_debugger`,
48
+ `remove_debugger_breakpoint`, `get_debugger_state` and `detach_debugger` with
49
+ their current inputs and response contracts in the [debugger guide](../../tools/debugger.md).
50
+ Keep session IDs, stop/thread/frame IDs and event cursors scoped to that run;
51
+ reject overflow as incomplete evidence. Inspect thread-based frames and shallow
52
+ locals without evaluating expressions or traversing continuation objects.
53
+
54
+ Verify source stops before and after suspension and across the dispatcher
55
+ change; compare known values with compiler scope tables. Report missing or
56
+ unavailable locals honestly. Compiler spilling into continuation fields does
57
+ not imply the locals API exposes those fields. Compare observed thread IDs and
58
+ stack locations, without calling a thread stack a logical coroutine stack.
59
+
60
+ Exercise into/over/out on a deterministic synchronous helper inside the coroutine.
61
+ Separately attempt a bounded step across a suspension boundary and record where
62
+ the event actually stops, including generated/runtime code or absence of a stop.
63
+ Do not require that step to follow the coroutine; remove the step request through
64
+ normal detach if it cannot make useful progress. A fresh session can then verify
65
+ the before/after source-breakpoint workaround independently.
66
+
67
+ ## Safety, failure and cleanup
68
+
69
+ All stops suspend the app. Verify an MCP interaction is rejected with the existing
70
+ `DEBUGGER_PAUSED` result; no UI action is needed to release a gate while paused.
71
+ Resume before further input. Old stop/frame references must return
72
+ `DEBUGGER_STALE_REFERENCE` after execution resumes. Cancel an event wait and
73
+ confirm the session remains usable; distinguish MCP request cancellation from
74
+ fixture job cancellation.
75
+
76
+ Bound subprocesses and polls with explicit deadlines. Keep normal inspection
77
+ below the existing 60-second pause limit. On timeout, failure or interruption,
78
+ attempt bounded detach, close the client, remove only owned forwards/package
79
+ and temporary build output, and report unresolved cleanup. Never kill ADB,
80
+ unrelated debugger sessions or user apps, nor automatically retry uncertain
81
+ attach/step/resume operations. Preserve unrelated forwards. After normal detach,
82
+ use a fresh UI-tree assertion of the expected completion/cancellation text to
83
+ prove app recovery; detach acknowledgement alone is insufficient.
84
+
85
+ ## Acceptance and assessment
86
+
87
+ 1. A reproducible opt-in runner records source/APK/server fingerprints, dependency
88
+ versions, Android target and per-journey pass/fail/blocked/unrun results.
89
+ 2. Completion, cancellation, breakpoint workaround, stepping observations,
90
+ stale references, pause guards, cancelled wait recovery and owned cleanup
91
+ have explicit evidence. An unsupported debugging observation is an assessment
92
+ finding; a failed safety or cleanup assertion remains a failure.
93
+ 3. Emulator and physical-device evidence are separate. No physical run or
94
+ version compatibility is inferred from emulator success.
95
+ 4. Tool docs, usage skill and fixture README explain verified behaviour,
96
+ limitations and reproduction. Existing journeys and `npm run verify` pass;
97
+ applicable `npm run test:device` coverage and skips are reported.
98
+ 5. A report recommends go/no-go for separately scoped inspection of active and
99
+ suspended coroutine state, parent/child identity and logical stacks. Describe
100
+ metadata/probe requirements and setup friction as evidence or open questions.
101
+ No follow-up capability is implemented or approved by this specification.
102
+
103
+ Only synthetic fixture values are collected. Retain local evidence intentionally;
104
+ do not upload app data. Principal risks are compiler source mapping, ART variable
105
+ metadata and scheduler/debugger interaction. No live coroutine behaviour has been
106
+ verified yet. Prerequisite discovery found the proposed compiler/coroutine jars,
107
+ JDK 17 and an authorized emulator; this is availability evidence only.
@@ -0,0 +1,38 @@
1
+ # iOS system traces — intent
2
+
3
+ - Source: [GitHub issue #78](https://github.com/clivejefferies/mobile-debug-tools/issues/78), authored by clivejefferies.
4
+ - Captured: 2026-11-04.
5
+ - Status: intent approved by the user's “ok” on 2026-11-04, responding to the
6
+ complete scope and approval request in this chat. Specification approval pending.
7
+
8
+ ## Problem and outcome
9
+
10
+ MCP clients need optional iOS performance evidence around an existing journey
11
+ to investigate slow interactions, hangs and rendering hitches. Add bounded
12
+ Apple Instruments capture through `xcrun xctrace` on macOS with Xcode, returning
13
+ a readable local `.trace` artifact with explicit iOS target/app metadata and
14
+ journey/evidence correlation identifiers.
15
+
16
+ ## Scope and constraints
17
+
18
+ Investigate System Trace, Time Profiler, Hangs and Animation Hitches availability
19
+ and distinct coverage, then propose an initial supported target/template matrix.
20
+ Assess simulators and physical devices independently. Require explicit target
21
+ UDIDs, recording readiness before journey input, artifact validation, bounded
22
+ resource use, and cleanup of session-owned processes. Keep trace contents local,
23
+ explain sensitive-data and retention implications, and report setup/permission
24
+ failures without bypassing them. Reuse Android tracing conventions where suitable
25
+ and preserve existing Android and untraced-journey behaviour.
26
+
27
+ Success requires at least one development fixture completing start → asserted
28
+ journey → stop with a readable artifact and matching correlation metadata.
29
+ Report unsupported, blocked and unrun coverage separately.
30
+
31
+ Automatic diagnosis, performance summaries, arbitrary queries, general export
32
+ APIs and runtime debugging are excluded.
33
+
34
+ ## Questions for investigation
35
+
36
+ Which target/template combinations are usable, how is recording readiness
37
+ established, and which fixture and export tables can prove useful capture?
38
+ These choices require specification approval after intent acceptance.
@@ -0,0 +1,92 @@
1
+ # iOS tracing investigation
2
+
3
+ 2026-11-04. Native CLI feasibility only; no new MCP behaviour implemented.
4
+ Xcode 27.2 (27B52), Instruments 27.2; iPhone 17 Pro simulator, iOS 26.4.1,
5
+ UDID `F9243BAF-62A8-4990-8A99-17F527F56FDA`.
6
+
7
+ `xcrun xctrace help record`, `help export`, `list templates`, `list devices`,
8
+ and `record --template 'Time Profiler' --device <UDID>
9
+ --show-recording-options` were inspected. Listing required execution outside
10
+ the workspace sandbox because Instruments writes its normal cache. No physical
11
+ iOS device was listed. No permission bypass or `--no-prompt` was used.
12
+
13
+ The existing `test/fixtures/readiness-app` was built, installed and launched on
14
+ the explicitly selected simulator. It was previously shut down. Three-second
15
+ recordings used `record --template <name> --device <UDID> --attach Readiness
16
+ --time-limit 3s --output <unique local path>`. Initial PID attachment failed
17
+ with “Cannot find process”; later name attachment resolved fixture PID 22313.
18
+ This argues for exact app identity resolution and fail-closed readiness, not
19
+ blind PID/name retries. No journey or UI assertion ran during these probes.
20
+
21
+ | Template | Result | Artifact validation |
22
+ | --- | --- | --- |
23
+ | Time Profiler | exit 0 | TOC confirms simulator UDID, fixture PID and template; `time-sample` export contains 5 rows |
24
+ | System Trace | exit 0 | TOC confirms target/template, but `context-switch` export has 0 rows; scheduling coverage unproven |
25
+ | Animation Hitches | exit 2 | explicit “Hitches is not supported on this platform”; saved failed artifact is not success |
26
+ | Hangs | no standalone template | Time Profiler recording options and TOC include Hangs; hang detection itself unverified |
27
+
28
+ Successful recordings warned that one table lacked a known input source.
29
+ Preserve such warnings; readable output does not establish every instrument works.
30
+ `--notify-tracing-started` is documented by the installed CLI; notification-based
31
+ readiness and graceful interruption remain unverified implementation checks.
32
+
33
+ Artifacts are local temporary investigation data under `/private/tmp/`:
34
+ `mcp-ios-time-profiler-name-01a1a646.trace`,
35
+ `mcp-ios-system-trace-01a1a646.trace`, `mcp-ios-animation-01a1a646.trace`.
36
+ Exports: `mcp-ios-time-samples-01a1a646.xml`,
37
+ `mcp-ios-system-toc-01a1a646.xml`, `mcp-ios-context-switch-01a1a646.xml`.
38
+ These were temporary investigation artifacts, subsequently removed during task cleanup; they are not tracked repository artifacts.
39
+ Fixture uninstall and simulator shutdown both passed; no recording remained active.
40
+
41
+ Owning code inspected: `src/observe/system-trace.ts`,
42
+ `src/server/handlers/diagnostic.ts`, `src/server/handlers/journey.ts`,
43
+ `src/server/schemas/system-trace-schema.ts`, and `src/utils/resolve-device.ts`.
44
+ Current session metadata and journey validation hardcode Android; existing APIs
45
+ must be extended consistently rather than routing iOS into the Perfetto adapter.
46
+
47
+ ## Updated-server verification and input tooling
48
+
49
+ The default Homebrew `idb_companion` 1.1.8 (built 2022-08-12) can read this
50
+ simulator hierarchy but its HID input fails because it loads SimulatorKit from
51
+ `Contents/Developer/Library/PrivateFrameworks/SimulatorKit.framework`. Xcode 27.2
52
+ ships it under `Contents/SharedFrameworks/SimulatorKit.framework` instead.
53
+ A direct tap on the offline fixture reproduced that failure without tracing.
54
+ The early full smoke runs therefore failed; their assertions were not weakened.
55
+
56
+ For the successful input verification, a **test-owned** companion used a private
57
+ layout alias under `/private/tmp/mcp-idb-xcode-o6ks8j9h/Contents/Developer`:
58
+ other Xcode contents were symlinks to the installed Xcode, with an additional
59
+ `Developer/Library/PrivateFrameworks/SimulatorKit.framework` link to the actual
60
+ SharedFrameworks location. `DEVELOPER_DIR` was set only for that companion.
61
+ The installed Xcode and existing companion were not modified or replaced.
62
+
63
+ The isolated companion command was:
64
+
65
+ ```sh
66
+ DEVELOPER_DIR=<private-alias>/Contents/Developer idb_companion \
67
+ --udid F9243BAF-62A8-4990-8A99-17F527F56FDA \
68
+ --grpc-domain-sock /private/tmp/mcp-ios-trace-idb.sock --log-level info
69
+ ```
70
+
71
+ The smoke passes `IDB_COMPANION=/private/tmp/mcp-ios-trace-idb.sock` explicitly
72
+ into the built server, using the installed idb client's supported companion
73
+ option. Instruments uses the real selected Xcode. This is verification-specific
74
+ tooling setup, not a new shipped input backend or proof that default idb HID works
75
+ with Xcode 27.2. Environments need a compatible idb companion for input journeys.
76
+ Capture-only use does not require idb input. See [plan](plan.md) and the final
77
+ [simulator evidence](simulator-evidence.json) for exactly what passed and cleanup.
78
+
79
+ A later long smoke run passed tap → Done (66 exported sample rows), cancellation,
80
+ expiry and failed-journey handling, then returned `TRACE_UNSUPPORTED` starting an
81
+ independent shutdown probe. Its exact prerequisite cause was not established;
82
+ a subsequent standalone capability read found all capture prerequisites available.
83
+ The original smoke then incorrectly reported expired completed metadata as failed
84
+ cleanup after ten minutes. [That failed report](late-run-failure-evidence.json)
85
+ is retained. The harness now tracks only sessions that still require cleanup and
86
+ queries explicit capabilities before the separate shutdown probe. The prerequisite
87
+ failure is not attributed to CPU load or a particular permission without evidence.
88
+
89
+ Final cleanup verified the simulator returned to Shutdown and no Readiness.app
90
+ fixture remained. The test-owned companion, layout alias, socket and private log
91
+ were removed. The final standalone combined smoke passed; its exact build and
92
+ outcomes are recorded in plan.md and simulator-evidence.json.
@@ -0,0 +1,32 @@
1
+ {
2
+ "linked_baseline": "PASS; Ready asserted via built-server journey",
3
+ "journey": {
4
+ "status": "PASS",
5
+ "trace_id": "ec906d78-08bf-495b-a824-2cdaf84536ba",
6
+ "correlation_id": "78d5c21f-435e-4b9c-822a-1cdfb23a1d63",
7
+ "ready_at_ms": 1793794165955,
8
+ "journey_submitted_at_ms": 1793794170369,
9
+ "outcome": "Done visible via journey UI-tree assertion",
10
+ "sample_rows": 66,
11
+ "artifact_bytes": 12304469,
12
+ "warnings": [
13
+ "INSTRUMENTS_RUN_WARNING: one or more Instruments warnings; coverage may be incomplete."
14
+ ]
15
+ },
16
+ "stale_id": "PASS; rejected tap left prior fixture label visible",
17
+ "cancel": "PASS",
18
+ "expiry": "PASS",
19
+ "failed_journey": "PASS; failure retained capture for explicit stop",
20
+ "status": "FAIL",
21
+ "error": "AssertionError [ERR_ASSERTION]: {\"error\":{\"tool\":\"start_system_trace\",\"code\":\"TRACE_UNSUPPORTED\",\"message\":\"TRACE_UNSUPPORTED\"}}\n+ actual - expected\n\n+ undefined\n- 'recording'\n",
22
+ "cleanup": {
23
+ "trace_errors": [
24
+ "ec906d78-08bf-495b-a824-2cdaf84536ba",
25
+ "7f89df16-af5c-4c1f-a21d-bb1f5b702dc5",
26
+ "379e63fc-d780-4a80-96d3-1eca3cda1c28"
27
+ ],
28
+ "fixture_removed": true,
29
+ "simulator_shutdown": false,
30
+ "host_artifacts_removed": true
31
+ }
32
+ }
@@ -0,0 +1,138 @@
1
+ # iOS system traces implementation plan
2
+
3
+ [Intent](intent.md) and [specification](spec.md) approved in this chat on
4
+ 2026-11-04. Implementation is local on `feature/ios-system-traces`; no publication
5
+ or push requested. Preserve Android contracts and unrelated work.
6
+
7
+ ## Implementation
8
+
9
+ - [x] Add bounded owned subprocess and Darwin-notification helper support.
10
+ - [x] Add simulator/app capability discovery and validated Instruments artifacts.
11
+ - [x] Add iOS sessions and shared platform routing, limits and journey linkage.
12
+ - [x] Extend schemas, public definitions, fixtures and documentation/usage skill.
13
+ - [x] Add deterministic lifecycle/native/contract tests and explicit simulator smoke.
14
+ - [x] Review resource ownership, failure/retry paths, schemas and Android callers.
15
+
16
+ ## Verification
17
+
18
+ Node >=22 (use installed Node 22 where needed), Xcode 27.2 and iOS 26.4.1
19
+ simulator `F9243BAF-62A8-4990-8A99-17F527F56FDA`. Boot only that simulator,
20
+ install the existing offline readiness fixture, launch, start Time Profiler,
21
+ run a journey tapping Show loader and asserting Done, stop and validate target,
22
+ IDs, readiness ordering, TOC and sample rows. Also exercise expiry, cancel and
23
+ failed journey. Remove fixture and restore simulator shutdown afterward.
24
+
25
+ | Criteria | Checks |
26
+ | --- | --- |
27
+ | 1 capability/input safety | injected native probes, handler/schema and definition goldens |
28
+ | 2 validated linked capture | updated-server simulator smoke with outcome assertion and artifact exports |
29
+ | 3 lifecycle and ownership | deterministic native/session failure, concurrency, stale/mismatch, retry tests |
30
+ | 4 real lifecycle evidence | simulator explicit stop, expiry, cancellation and journey failure |
31
+ | 5 compatibility | Android session tests, existing device suite, full maintainer verification |
32
+
33
+ Commands: focused `node --import tsx test/unit/...` checks, `npm run verify`,
34
+ `npm run test:device`, opt-in iOS trace smoke with an explicit simulator UDID.
35
+ CI workflows will be checked for coverage differences. Physical-device capture
36
+ is outside the initial matrix and unrun; none is connected. Notification helper
37
+ compilation/readiness, PID identity resolution and finalisation deadlines require
38
+ early native checks. No test result is implied by the prior feasibility probes.
39
+
40
+ ## Results
41
+
42
+ Implementation and focused review complete locally. No commit, push or release.
43
+
44
+ | Check | Result and scope |
45
+ | --- | --- |
46
+ | Focused native/session/router/tool contracts | PASS: identity/executable matching, notification-before-readiness, stale and mismatched links, shared pending reservations, expiry, cancellation, export retry without restart, storage and subprocess deadlines |
47
+ | `npm run verify` | PASS on Node 23.11.0: lint, structural gates, architecture, TypeScript, 94 unit files, agent-plugin consistency. Final post-fix run also passed, including the corrected smoke cleanup harness. |
48
+ | `npm run test:device` | PASS on the local emulator/simulator: Android Perfetto capture/readability, explicit stop/cancel/expiry/shutdown plus Android+iOS observation/evidence smoke. 13 files visited; opt-in debugger/coroutine/Kotlin/interaction and iOS trace files report UNRUN without their explicit environment. |
49
+ | Focused built-server iOS trace smoke | Full fixture tap → Done UI-tree assertion and sample export passed using the isolated input companion documented in investigation.md. Final standalone combined lifecycle/shutdown run PASS; see simulator-evidence.json. |
50
+ | Real iOS shutdown recheck | PASS after allowing recorder finalisation up to eight seconds inside the ten-second server budget. Earlier one-second forced-stop run failed cleanup; that failure was investigated and fixed. |
51
+ | Physical device / real native failure injection | UNRUN. Physical capture is outside the accepted initial matrix; disconnect/permission/start/export/storage failure branches have deterministic coverage, not real-device proof. |
52
+
53
+ Logs: `/private/tmp/mobile-debug-ios-trace-verify-final.log` and
54
+ `/private/tmp/mobile-debug-ios-trace-device.log`. CI uses Ubuntu/Node 22/JDK 17;
55
+ local validation used macOS/Node 23.11.0 and installed toolchains. Hosted CI is
56
+ unrun. No hosted-CI or installed/published-package compatibility claim is made.
57
+
58
+ Review: schemas, registration goldens, dispatch, response serialization and callers
59
+ were checked together. Android adapter/session logic remains intact behind routing.
60
+ Recorder handles are owned, process identity is revalidated, artifacts validate
61
+ UUID/PID/executable/template/table data, and temporary exports/helpers are removed.
62
+ Forced-stop deadlines, incomplete shutdown reporting and oversized-output disposal
63
+ were reviewed. No remaining actionable code review finding is recorded.
64
+
65
+ Local limitations: default idb 1.1.8 HID is incompatible with the Xcode 27.2
66
+ framework layout. Successful input evidence uses a test-owned companion with a
67
+ private path alias; capture itself uses the actual selected Xcode. Instruments
68
+ reported a bounded run warning; successful CPU sample export does not verify all
69
+ bundled instruments, scheduling data, symbolication or hang detection.
70
+
71
+
72
+ ## Final device result and cleanup
73
+
74
+ The final standalone built-server smoke passed with build SHA-256
75
+ `48eee7b1f71403645ab301def8d83dd14585eec099b221f8ac4f6aaba0941282`.
76
+ The UI-tree assertion established Done after tapping Show loader, with readiness
77
+ before journey submission, matching correlation identifiers and 70 exported CPU
78
+ sample rows in an 11,961,327-byte readable Instruments bundle. Explicit stop,
79
+ stale rejection, cancel, duration expiry, failed-journey retention, real server
80
+ shutdown and target-app survival passed. The generated report is
81
+ [simulator-evidence.json](simulator-evidence.json).
82
+
83
+ The earlier long-run failure is retained as
84
+ [late-run-failure-evidence.json](late-run-failure-evidence.json); it is not called
85
+ a pass. The final run used corrected active-session cleanup tracking and explicit
86
+ shutdown capability checks, after maintainer verification had finished.
87
+
88
+ Final `npm run verify`: PASS, 94 unit files, on Node 23.11.0. The native forced-stop
89
+ nonclosure case has a bounded deterministic test. The existing device suite's
90
+ passed checks and opt-in UNRUN entries are scoped above. Hosted CI remains unrun.
91
+
92
+ All task-owned fixture installations and trace/probe artifacts were removed. The
93
+ test-owned companion was stopped only after verifying its exact command/PID;
94
+ its path alias, socket and private diagnostic log were removed. The simulator's
95
+ original Shutdown state and fixture absence were verified with simctl and the
96
+ filesystem. The original companion and installed Xcode were unchanged. No active
97
+ task recording remains. Changes are uncommitted and unpushed.
98
+
99
+ ## PR #102 review repair — 2026-11-04
100
+
101
+ The three review findings were checked against the current branch. Clarified
102
+ artifact retention wording in the canonical and generated Cursor skills, and
103
+ separated Android/iOS capability and session fields in the tool guide.
104
+
105
+ Monitoring now tolerates two consecutive non-definitive failures, resets the
106
+ counter on success, and preserves COMMAND_FAILED/ACTION_TIMEOUT classifications.
107
+ Unknown failures use bounded TRACE_MONITOR_FAILED rather than claiming a target
108
+ disconnect. Storage, changed identity and missing-app failures remain immediate.
109
+ Tolerated failures still reconcile expiry and recorder exit; retries retain the
110
+ same device/app/recording and never restart capture.
111
+
112
+ Deterministic tests cover reset, third-failure cleanup, immediate failures,
113
+ reason privacy, pinned recording identity and deadline/recorder fall-through.
114
+ Fresh maintainer/device results and focused simulator evidence are recorded
115
+ below after validation; previous feature evidence remains scoped to its build.
116
+
117
+ PR repair validation:
118
+
119
+ - `npm run verify`: PASS on Node 23.11.0, including 94 unit files and plugin sync.
120
+ - `npm run test:device`: Android+iOS observation/evidence checks passed; the
121
+ Android system-trace shutdown assertion failed in the full run. Its uniquely
122
+ owned leftover trace was removed. The unchanged Android trace smoke passed
123
+ independently afterward, including active shutdown. The initial suite failure
124
+ remains recorded; its exact cause was not established.
125
+ - Focused iPhone 17 Pro / iOS 26.4 simulator check: PASS using built iOS adapters,
126
+ real Time Profiler recording, and explicitly injected monitor failures. Two
127
+ COMMAND_FAILED polls preserved capture and yielded seven exported sample rows;
128
+ three ACTION_TIMEOUT polls failed with that reason and complete cleanup.
129
+ See [pr102-monitor-evidence.json](pr102-monitor-evidence.json) for its build hash.
130
+ This checks monitoring and native capture, not a new UI-input journey or real
131
+ device disconnection. Deterministic tests establish expiry/reset/identity cases.
132
+ - Fixture and test host artifacts removed; simulator returned to Shutdown.
133
+ Physical devices and hosted CI are not established by these local checks.
134
+
135
+ Logs: `/private/tmp/mobile-debug-pr102-verify.log`,
136
+ `/private/tmp/mobile-debug-pr102-device.log`,
137
+ `/private/tmp/mobile-debug-pr102-android-rerun.log` and
138
+ `/private/tmp/mobile-debug-pr102-monitor.log`.