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,21 @@
1
+ # End-to-end latency smoke (not performance evidence)
2
+
3
+ Status: finished. Build: 8f3a9bc8f498181686362c829e7395f301e85681d8ea1667692e2b33c18d011c.
4
+
5
+ | Case | Successful/measured | p50 ms | p95 ms | Failures | Warm-up failures |
6
+ | --- | ---: | ---: | ---: | ---: | ---: |
7
+ | standalone | 1/1 | 146335.1 | 146335.1 | 0 | 0 |
8
+ | full-debug | 1/1 | 84684.9 | 84684.9 | 0 | 0 |
9
+ | full-compact | 1/1 | 85400.3 | 85400.3 | 0 | 0 |
10
+ | light-debug | 1/1 | 65161.8 | 65161.8 | 0 | 0 |
11
+ | light-compact | 1/1 | 50780.4 | 50780.4 | 0 | 0 |
12
+ | screenshot-on | 1/1 | 884.2 | 884.2 | 0 | 0 |
13
+ | screenshot-off | 1/1 | 658.8 | 658.8 | 0 | 0 |
14
+ | tree-on | 1/1 | 2611.1 | 2611.1 | 0 | 0 |
15
+ | tree-off | 1/1 | 2509.6 | 2509.6 | 0 | 0 |
16
+ | snapshot-on | 1/1 | 4575.6 | 4575.6 | 0 | 0 |
17
+ | snapshot-off | 1/1 | 4667.2 | 4667.2 | 0 | 0 |
18
+
19
+ See smoke.json for exact source/build hashes, environment, phase durations, attempt order, inclusive components and failure records. Percentiles use the successful measured count shown for each case. With 1–19 successful samples, nearest-rank p95 is the sample maximum. Zero successful samples yield no percentiles. Failed attempts are excluded from percentiles, retained in raw data, and fail the run.
20
+
21
+ Intervals can overlap; component sums are not an additive latency budget. Client-minus-handler includes scheduling, transport and uninstrumented work. Handler residual excludes the union of recorded spans. Tree acquisition/parse/retry events are separate nested diagnostics. Application work inside requests remains included. Startup, fixture builds/resets and external validation are excluded from steady-state round trips. SDK wire serialization is not isolated.
@@ -111,7 +111,9 @@ requires reviewing its exception rather than silently transferring it.
111
111
  it is not packet capture or a proxy. Results depend on the app logging requests,
112
112
  and the current implementation does not measure request duration.
113
113
  - `src/debugger/protocol.ts` validates worker messages. The session manager owns
114
- serialized transitions and cleanup; the Java worker owns JDI operations.
114
+ serialized transitions and cleanup; the Java worker owns Android JDI operations.
115
+ The optional `lldb/` Python worker owns iOS simulator LLDB operations and static
116
+ inspection; `ios.ts` verifies simulator/app/process membership before attach.
115
117
 
116
118
  The [refactoring plan](specs/026-code-structure-and-quality-gates/plan.md) records
117
119
  progress and verification. The [follow-on health cleanup](specs/026-code-structure-and-quality-gates/health-plan.md)
@@ -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,166 @@
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`.
139
+
140
+
141
+ ## Shutdown cleanup repair — 2026-11-05
142
+
143
+ A simulator run exposed a discarded trace directory left after recorder stop
144
+ failed. Finalization skipped artifact cleanup on any stop exception, including
145
+ when the owned recorder had already exited (such as after forced termination).
146
+ The fix removes discarded files only after confirmed recorder exit and preserves
147
+ the failed state/reason; a possibly live recorder still retains its directory for
148
+ retry. Storage-limit cleanup retains its existing behaviour.
149
+
150
+ Regression coverage proves both the live-writer safety case and shutdown after
151
+ stop failure with confirmed exit. The latter failed before the fix and passed
152
+ afterward. The complete simulator trace regression and `npm run verify` passed. The
153
+ original shutdown deadline and assertions were unchanged. The repaired run
154
+ established tap-to-Done via a fresh UI-tree assertion, 59 exported sample rows,
155
+ cancel/expiry/stale-ID handling, server shutdown directory removal and complete
156
+ owned trace/fixture cleanup. It used the documented test-owned compatibility
157
+ companion; the default idb/Xcode HID limitation remains separate. The baseline `MCP_READINESS_DEVICE=emulator-5554 npm run test:device` suite also
158
+ passed, with optional fixture skips reported separately. The full affected iOS
159
+ trace smoke was run explicitly above rather than inferred from the baseline
160
+ suite. The test-owned companion/alias was removed and simulator shutdown restored.
161
+
162
+ Logs: `/tmp/ios-shutdown-fixed-device.log`,
163
+ `/tmp/ios-shutdown-fixed-evidence.json`, `/tmp/ios-shutdown-verify.log`,
164
+ `/tmp/ios-shutdown-device-suite.log`.
165
+ Existing readiness verification edits in spec 033 and debugger device tests are
166
+ preserved separately; no physical-device operations are needed for this repair.
@@ -0,0 +1,22 @@
1
+ {
2
+ "source": "built dist iOS sessions/native adapter; injected monitor failures, real Instruments capture",
3
+ "device": "F9243BAF-62A8-4990-8A99-17F527F56FDA",
4
+ "runtime": "v23.11.0",
5
+ "transient_recovery": {
6
+ "status": "PASS",
7
+ "injected_command_failures": 2,
8
+ "trace_id": "a979b090-3ebb-4a95-92d0-9060c8105d45",
9
+ "pid": 90191,
10
+ "sample_rows": 7,
11
+ "artifact_bytes": 10898587
12
+ },
13
+ "repeated_timeout": {
14
+ "status": "PASS",
15
+ "reason": "ACTION_TIMEOUT",
16
+ "cleanup": "complete"
17
+ },
18
+ "status": "PASS",
19
+ "build_sha256": "e735ac25c9b0065797b748934efa5f3fc977a538fffef50e464b31ca4603c64a",
20
+ "cleanup": "Owned captures stopped; fixture and host artifacts removed; simulator shutdown restored separately",
21
+ "simulator_restored_to_shutdown": true
22
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "linked_baseline": "PASS; Ready asserted via built-server journey",
3
+ "journey": {
4
+ "status": "PASS",
5
+ "trace_id": "742664b0-c676-4fe8-9231-26cca3c41009",
6
+ "correlation_id": "5affcc93-6944-4b58-a4a9-0d6cd0a55954",
7
+ "ready_at_ms": 1793796042115,
8
+ "journey_submitted_at_ms": 1793796046237,
9
+ "outcome": "Done visible via journey UI-tree assertion",
10
+ "sample_rows": 70,
11
+ "artifact_bytes": 11961327,
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
+ "shutdown": "PASS; owned recording and partial directory removed",
21
+ "app_survived_cleanup": "PASS",
22
+ "status": "PASS",
23
+ "build_sha256": "48eee7b1f71403645ab301def8d83dd14585eec099b221f8ac4f6aaba0941282",
24
+ "runtime": "v23.11.0",
25
+ "device": "F9243BAF-62A8-4990-8A99-17F527F56FDA",
26
+ "server": {
27
+ "name": "mobile-debug-mcp",
28
+ "version": "0.35.0"
29
+ },
30
+ "physical_device": "UNRUN; unsupported initial matrix",
31
+ "native_failure_injection": "UNRUN on real target; deterministic unit tests separate",
32
+ "input_toolchain": "Explicit test companion via IDB_COMPANION; see investigation.md",
33
+ "cleanup": {
34
+ "trace_errors": [],
35
+ "fixture_removed": true,
36
+ "simulator_shutdown": false,
37
+ "host_artifacts_removed": true
38
+ },
39
+ "task_cleanup": {
40
+ "original_simulator_state": "Shutdown",
41
+ "restored_simulator_state": "Shutdown",
42
+ "fixture_absent": true,
43
+ "temporary_companion_stopped": true,
44
+ "temporary_framework_alias_removed": true,
45
+ "named_probe_artifacts_removed": true
46
+ }
47
+ }
@@ -0,0 +1,135 @@
1
+ # iOS system traces — proposed specification
2
+
3
+ 2026-11-04. **Approved** by the user's second “ok” in this chat, responding to
4
+ the complete specification and implementation approval request.
5
+ [Intent](intent.md) approved by the user's “ok” in this chat.
6
+ Source: [issue #78](https://github.com/clivejefferies/mobile-debug-tools/issues/78).
7
+ [Native investigation and limits](investigation.md).
8
+
9
+ ## Supported scope
10
+
11
+ Extend the existing five system-trace tools with an Instruments backend on macOS
12
+ with full Xcode. Initial supported combination: booted iOS simulator and Time
13
+ Profiler, attached to an already running development app. Baseline is Xcode 27.2
14
+ and iOS 26.4.1. Other versions require successful prerequisite checks and artifact
15
+ validation; installed templates alone do not establish support.
16
+
17
+ System Trace is discoverable but not enabled initially: the simulator probe did
18
+ not establish scheduling data. Animation Hitches is unsupported on the tested
19
+ simulator. Hangs is an instrument within Time Profiler here, not a selectable
20
+ standalone template; do not promise detected hangs. Physical-device capture is
21
+ explicitly unsupported in this initial release, with verification unrun because
22
+ no device is available. Report pairing, Developer Mode, signing/profiling and
23
+ symbol prerequisites as applicable setup guidance, never as completed checks.
24
+ Expanding this matrix requires evidence and a specification revision.
25
+
26
+ No host recording, all-processes mode, custom templates, app launching, automatic
27
+ diagnosis, summaries, arbitrary queries, or public export API. Android retains
28
+ its existing preset, inputs, results and verification requirements.
29
+
30
+ ## Tools and contracts
31
+
32
+ Keep existing names and strict schemas. Extend capabilities and start inputs with
33
+ optional `appId` (nonblank bundle identifier) and `template` enum
34
+ `System Trace | Time Profiler | Animation Hitches | Hangs`. These fields are
35
+ iOS-only; reject them on Android. iOS start requires explicit `deviceId` and
36
+ `appId`; omitted template defaults to Time Profiler. Capabilities require explicit
37
+ `deviceId` on iOS; `appId` optionally probes running-app readiness. Duration stays
38
+ 1,000–120,000 ms, default 30,000. Controls still accept only `traceId`.
39
+
40
+ iOS capabilities return `backend:xctrace`, resolved simulator/device metadata,
41
+ Xcode version, discovered templates, per-template support/reasons/coverage,
42
+ prerequisite states (`available`, `missing`, `unknown`), and actionable recovery.
43
+ Discovery starts no recording and grants no permissions. Distinguish unavailable
44
+ tooling/target, unsupported matrix, app not running, permission failure and checks
45
+ that only a recording can establish. Do not label unknown permissions as granted.
46
+
47
+ Reuse session state, completion reasons, IDs, host bounds, cleanup and correlation
48
+ fields. Extend result unions to iOS, `backend:xctrace`, and artifact
49
+ `format:instruments` with absolute `.trace` path, recursive `size_bytes`, and
50
+ `kind:directory|file`. Include pinned `app_id`, PID, executable identity,
51
+ selected template, target type, warnings and validation result. Never return raw
52
+ trace data. Unreached fields are null. Errors use existing MCP `isError` and
53
+ TRACE_* codes; bounded reason/recovery values distinguish setup, permission,
54
+ target disconnect, readiness, export and storage failures without raw stderr.
55
+
56
+ Resolve bundle identity to one current executable/PID on the pinned simulator;
57
+ ambiguous/missing identity fails. Always pass `--device <UDID>` and revalidate
58
+ identity before starting. Do not retry against a different process/name, template,
59
+ device or host. Exported target UUID, PID and template must match the session.
60
+
61
+ ## Lifecycle, limits and privacy
62
+
63
+ Use uniquely owned mode-0700 temporary directories and fixed argument arrays.
64
+ Spawn the recorder with `--time-limit`, unique output and unique
65
+ `--notify-tracing-started` notification. Register an owned Darwin-notification
66
+ listener before spawning; return recording only after that notification while
67
+ the recorder remains live. Console “Starting recording” alone is insufficient.
68
+ Notification helper availability is a prerequisite, never a silent fallback.
69
+
70
+ Allow 35 seconds for readiness, 30 seconds for graceful stop/finalisation and
71
+ 30 seconds for validation. Bound every child process and cap captured diagnostic
72
+ output. At requested duration, reconcile and finalise automatically. SIGINT only
73
+ the session-owned recorder; after its grace deadline terminate that owned child
74
+ and report failure/partial output. Never signal the app, by process name, or an
75
+ unrelated Instruments recording. On server shutdown cancel owned sessions under
76
+ one 10-second overall deadline; forced cleanup may leave an unreadable artifact
77
+ and must report that. Crashes provide no cleanup guarantee; no restart-wide sweep.
78
+
79
+ Share the existing one-session-per-device, four-active-session server limit across
80
+ backends. Serialise controls; retain 100 terminal metadata records for ten minutes.
81
+ Stale/other-server IDs fail. Completed controls are idempotent. Disconnect,
82
+ premature recorder exit and journey failure have explicit outcomes; journey failure
83
+ does not cancel capture. Retry validation only on an existing finalised owned
84
+ bundle, never restart recording. Cancel removes owned partial output; completed
85
+ artifacts remain user-managed.
86
+
87
+ Poll recursive output size every second; stop/discard on exceeding 256 MiB per
88
+ iOS session, reject starts with less than 1 GiB free in its output filesystem.
89
+ Finalisation can temporarily overshoot the polling threshold: report this as a
90
+ soft bound, reject oversized final output and remove it. No symlink traversal.
91
+ Apply restrictive permissions recursively before returning validated output.
92
+ Instruments may contain system-wide metadata, paths, symbols, logs and signposts
93
+ despite app attachment. Disclose this in tool/skill documentation. No upload,
94
+ telemetry or permission bypass, including `--no-prompt`. User handles any required
95
+ OS permissions outside the tool.
96
+
97
+ ## Artifact and journey evidence
98
+
99
+ Require successful recorder exit, nonempty bounded output, parseable
100
+ `xctrace export --toc`, matching target/app/template metadata, expected
101
+ `time-sample` schema and successful table export. Record row count, including zero;
102
+ zero samples means no CPU sample evidence, not diagnosed inactivity. Do not call
103
+ a failed recording valid merely because a readable partial bundle exists.
104
+ Expose warnings and unavailable instruments; do not claim symbolication unless
105
+ verified. Validation exports are private temporary data removed after validation.
106
+
107
+ Keep `run_journey.systemTraceId` explicit. Validate active same-server,
108
+ same-platform/same-UDID session before any journey input. Link journey and step
109
+ evidence through existing trace context and correlation IDs. The trace pins the
110
+ profiled app; journey actions retain their existing targeting semantics and may
111
+ leave that app. Report that limitation. Duration expiry or stop during the journey
112
+ means partial coverage. Host capture bounds and unknown device-clock alignment
113
+ establish association only; no device markers or causal inference.
114
+
115
+ ## Acceptance and verification
116
+
117
+ 1. Capability matrix and rejected inputs are side-effect-free, with exact target
118
+ and actionable prerequisite reasons; unknown permissions stay unknown.
119
+ 2. Updated-server simulator Time Profiler start → existing fixture journey tapping
120
+ Show loader and asserting Done → stop yields matching IDs, target/app metadata,
121
+ notification-before-input evidence, readable bundle and exported sample rows.
122
+ 3. Deterministic checks cover stale/mismatched IDs preventing all input, ownership,
123
+ concurrency, expiry, cancellation, partial coverage, disconnect, identity races,
124
+ notification/start/stop/export/storage failures, retries and shutdown cleanup.
125
+ 4. Real simulator checks cover explicit stop, expiry, cancellation and failed
126
+ journey; unavailable physical/failure-injection evidence is separate from mocks.
127
+ 5. Existing Android traces and untraced journeys pass regression checks. Run
128
+ `npm run verify`, applicable `npm run test:device`, and focused updated-server
129
+ calls; report actual suite coverage and unrun platforms.
130
+
131
+ Affected: trace sessions/adapters/types, schemas/registration/handlers, journey and
132
+ evidence integration, shutdown, tests/goldens, tool docs, README, changelog and
133
+ packaged usage skill. Main implementation risks remain notification readiness,
134
+ reliable app identity resolution and finalisation deadlines; feasibility probes
135
+ do not establish these acceptance criteria.