mobile-debug-mcp 0.29.0 → 0.30.1

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.
@@ -0,0 +1,394 @@
1
+ # RFC 014 — Actionability Resolution
2
+
3
+ ## Status
4
+
5
+ Draft
6
+
7
+ ---
8
+
9
+ # 1. Summary
10
+
11
+ This RFC defines a deterministic model for resolving whether a UI element is actionable within mobile-debug-mcp.
12
+
13
+ Actionability Resolution ensures that interactions (tap, input, scroll targets, gestures) are only executed against elements that are in a valid and stable state for interaction.
14
+
15
+ It builds directly on:
16
+
17
+ - RFC 013 (Wait and Synchronization Reliability)
18
+ - Stronger State Verification primitives
19
+ - Richer Element Identity model
20
+
21
+ ---
22
+
23
+ # 2. Relationship to Existing Resolution System (RFC 005 / RFC 007)
24
+
25
+ This RFC refines, but does not replace, the existing resolution pipeline defined in RFC 005 (Resolved Stage) and RFC 007 (Executable Target Selection).
26
+
27
+ Specifically:
28
+
29
+ - RFC 005 defines when an element is considered a valid resolved target
30
+ - RFC 007 defines how executable targets are selected from candidate elements
31
+ - RFC 014 defines a **pre-execution predicate gate**: whether a resolved target is safe to interact with at dispatch time
32
+
33
+ RFC 014 MUST be applied AFTER RFC 005/007 resolution and BEFORE any interaction dispatch occurs.
34
+
35
+ ---
36
+
37
+ # 3. Problem Statement
38
+
39
+ Current interaction failures arise when actions are attempted on elements that are:
40
+
41
+ - not yet fully rendered
42
+ - temporarily disabled during recomposition
43
+ - visually present but not interactable due to transient platform state (composition, layout, or interaction eligibility changes)
44
+ - stale due to snapshot timing issues
45
+
46
+ This leads to:
47
+
48
+ - missed taps
49
+ - retry loops
50
+ - inconsistent automation outcomes
51
+ - non-deterministic test behavior
52
+
53
+ There is currently no single authoritative model defining when an element is safe to interact with.
54
+
55
+ ---
56
+
57
+ # 4. Goals
58
+
59
+ The system should:
60
+
61
+ - Provide a deterministic definition of "actionable"
62
+ - Prevent interactions on unstable UI states
63
+ - Reduce retries caused by transient UI conditions
64
+ - Integrate with stabilization semantics from RFC 013
65
+ - Support both Android and iOS UI models
66
+
67
+ ---
68
+
69
+ # 5. Non-Goals
70
+
71
+ This RFC does NOT:
72
+
73
+ - define gesture recognition internals
74
+ - implement visual computer vision occlusion detection
75
+ - guarantee backend readiness
76
+ - replace synchronization primitives from RFC 013
77
+ - define visual occlusion detection; interaction eligibility is derived from platform clickable/interactable semantics, not vision-based inference
78
+
79
+ ---
80
+
81
+ # 6. Definition: Actionability
82
+
83
+ An element is considered **actionable** if ALL of the following conditions are satisfied:
84
+
85
+ ## 6.1 Structural Validity
86
+
87
+ - Element exists in the current UI hierarchy snapshot
88
+ - Element identity is stable (per Richer Element Identity model)
89
+
90
+ ### Identity Source of Truth
91
+
92
+ Element identity MUST be derived using the following priority order:
93
+
94
+ 1. `stable_id` (primary source from runtime)
95
+ 2. `elementId` deterministic hash (fallback)
96
+ 3. recomputed semantic node signature (last resort)
97
+
98
+ If identity cannot be resolved consistently across snapshots, the element MUST be treated as non-actionable due to instability.
99
+
100
+ ## 6.2 Visibility
101
+
102
+ - Element is visible within the current viewport OR scrollable container
103
+ - Element is not explicitly hidden (e.g. visibility = gone / hidden)
104
+
105
+ ## 6.3 Enabled State
106
+
107
+ - Element is not disabled
108
+ - Element accepts interaction for the requested action type
109
+ - Must be interpreted relative to action_type (see Section 7.4)
110
+
111
+ ## 6.4 Stability Requirement
112
+
113
+ - UI must be in a "stable" state per RFC 013 stabilization rules
114
+ - No synchronization-relevant mutation is currently active
115
+
116
+ ## 6.5 Interaction Eligibility
117
+
118
+ - Element is not in a transitional animation state that blocks interaction
119
+ - Element is not temporarily detached or reparenting in the hierarchy
120
+ - Element MUST satisfy runtime proxy interactability derived only from visible, enabled, and clickable fields
121
+ - No hit-test, overlay, or occlusion guarantees are assumed
122
+
123
+ ---
124
+
125
+ # 7. Actionability Evaluation Model (Runtime Contract)
126
+
127
+ Actionability is evaluated using runtime-provided fields from the resolved element and snapshot system.
128
+
129
+ ## 7.1 Predicate Definition
130
+
131
+ ```text
132
+ is_actionable(element, snapshot, normalized_action_type) =
133
+ exists(element)
134
+ AND snapshot.stable == true
135
+ AND element.visible == true
136
+ AND element.enabled == true
137
+ AND normalized_action_type IS NOT NULL
138
+ AND actionability_by_type(normalized_action_type, element)
139
+ AND identity_is_stable(element)
140
+ ```
141
+
142
+ ## 7.2 Field Mapping
143
+
144
+ | Predicate Component | Source Field |
145
+ |--------------------|-------------|
146
+ | exists(element) | element presence in resolved tree |
147
+ | snapshot.stable | RFC 013 stabilization state |
148
+ | element.visible | visible / computed visibility flag |
149
+ | element.enabled | enabled / interactable flag |
150
+ | actionability_by_type(action_type, element) | derived runtime interaction capability from visible, enabled, clickable proxy signals (no hit-test dependency) |
151
+ | identity_is_stable | stable_id or fallback identity resolution |
152
+
153
+ ## 7.3 Identity Stability Rule
154
+
155
+ Identity is considered stable if `stable_id` remains unchanged across the latest two snapshots.
156
+
157
+ If identity changes, the element MUST be re-resolved before actionability can be evaluated.
158
+
159
+ ## 7.4 Action Type Applicability (Core Contract)
160
+
161
+ Action type is a PRIMARY dimension of actionability and MUST be evaluated explicitly for every interaction.
162
+
163
+ The predicate `actionability_by_type(action_type, element)` is not optional and defines interaction correctness.
164
+
165
+ If the caller omits `action_type`, implementations MUST evaluate Tap / Click semantics.
166
+ Before evaluation, implementations MUST normalize the effective action type to a concrete value.
167
+
168
+ Each action type defines strict eligibility constraints:
169
+
170
+ ### Tap / Click (Default Interaction Model)
171
+ - Requires: element.clickable == true
172
+ - Requires: element.visible == true
173
+ - Requires: element.enabled == true
174
+ - This is the DEFAULT action model when action_type is unspecified
175
+
176
+ ### Input / Text Entry
177
+ - Requires: element.enabled == true
178
+ - Requires: element.focusable == true OR platform equivalent input capability
179
+ - Clickable is NOT required
180
+
181
+ ### Scroll Targeting
182
+ - Requires: element is within a scrollable container
183
+ - Requires: element.visible == true OR can be brought into viewport
184
+ - Enabled state is NOT required
185
+
186
+ ### Gesture (Swipe / Drag)
187
+ - Requires: element exists in stable snapshot
188
+ - Requires: element.visible == true
189
+ - Requires: no active animation or transition state that blocks interaction
190
+
191
+ ### Contract Rule
192
+
193
+ Implementations MUST treat the effective action type as a required discriminator in all actionability evaluations.
194
+
195
+ ### Determinism Rule
196
+
197
+ Action type evaluation is fully deterministic.
198
+
199
+ All constraints for a given action type MUST be evaluated as a single conjunctive predicate.
200
+
201
+ No constraint MAY override another constraint. No priority ordering between fields is permitted.
202
+
203
+ Evaluation MUST produce identical results for identical inputs (element, snapshot, action_type).
204
+
205
+ ## 7.5 Deterministic Evaluation Guarantees
206
+
207
+ Actionability evaluation is a pure function of:
208
+
209
+ - element
210
+ - snapshot
211
+ - action_type
212
+
213
+ The evaluation MUST NOT depend on external or hidden state.
214
+
215
+ The system MUST guarantee:
216
+
217
+ - identical inputs produce identical outputs
218
+ - no temporal or execution-order dependency affects results
219
+ - all predicates are evaluated in a single logical context
220
+
221
+ Short-circuit evaluation is permitted for performance but MUST NOT change final outcome semantics.
222
+
223
+ ---
224
+
225
+ # 8. Resolution Lifecycle
226
+
227
+ Actionability MUST be evaluated in the following sequence:
228
+
229
+ 1. Retrieve latest UI snapshot
230
+ 2. Verify snapshot is stable (RFC 013)
231
+ 3. Resolve element identity
232
+ 4. Evaluate visibility constraints
233
+ 5. Evaluate enabled state
234
+ 6. Evaluate interaction readiness
235
+ 7. Return final boolean result
236
+
237
+ If any step fails, the element MUST be considered non-actionable.
238
+
239
+ ---
240
+
241
+ # 9. Interaction Guardrail
242
+
243
+ Actions MUST NOT be executed unless actionability resolution returns true.
244
+
245
+ If actionability is false:
246
+
247
+ - system MAY retry after waiting for stabilization
248
+ - system MUST NOT force interaction
249
+ - system MAY re-resolve snapshot
250
+
251
+ ---
252
+
253
+ # 10. Failure Modes
254
+
255
+ ## 10.1 Transient Non-Actionability
256
+
257
+ Caused by:
258
+
259
+ - recomposition
260
+ - animation transitions
261
+ - delayed rendering
262
+
263
+ Mitigation:
264
+
265
+ - rely on RFC 013 stabilization
266
+ - re-evaluate after wait cycle
267
+
268
+ ---
269
+
270
+ ## 10.2 Stale Snapshot
271
+
272
+ Caused by:
273
+
274
+ - outdated hierarchy
275
+ - missed mutation events
276
+
277
+ Mitigation:
278
+
279
+ - require fresh snapshot before evaluation
280
+
281
+ ---
282
+
283
+ ## 10.3 False Positives (appears actionable but is not)
284
+
285
+ Caused by:
286
+
287
+ - proxy signal mismatch (e.g. element reports clickable/visible but runtime rejects interaction via proxy constraints)
288
+
289
+ Mitigation:
290
+
291
+ - stricter validation of visible/enabled/clickable proxy consistency
292
+ - re-resolution of element state before evaluation
293
+
294
+ ---
295
+
296
+ # 11. Platform Considerations
297
+
298
+ ## Android
299
+
300
+ - View visibility and enabled-state are primary signals
301
+ - Touch target bounds SHOULD be respected
302
+
303
+ ## iOS
304
+
305
+ - UIKit and SwiftUI state transitions may delay interaction readiness
306
+ - Accessibility tree is primary signal for actionability
307
+
308
+ ---
309
+
310
+ # 12. Integration with RFC 013
311
+
312
+ Actionability Resolution depends on:
313
+
314
+ - Stable snapshot guarantee
315
+ - Synchronization-relevant mutation rules
316
+
317
+ It MUST NOT evaluate elements from unstable snapshots.
318
+
319
+ ---
320
+
321
+ # 13. Telemetry
322
+
323
+ Systems SHOULD track:
324
+
325
+ - actionability rejection rate
326
+ - retry frequency after failed actionability
327
+ - time-to-actionable per element
328
+ - false-positive interaction attempts
329
+
330
+ ---
331
+
332
+ # 14. Rollout Strategy
333
+
334
+ ## Phase 1
335
+
336
+ - Basic structural + visibility checks
337
+
338
+ ## Phase 2
339
+
340
+ - Stability integration (RFC 013)
341
+
342
+ ## Phase 3
343
+
344
+ - Platform-specific interaction heuristics
345
+
346
+ The shipped interaction layer now applies iOS semantic tap eligibility in addition to proxy clickability checks.
347
+
348
+ ---
349
+
350
+ # 15. Dependencies
351
+
352
+ ## Depends On
353
+
354
+ - RFC 013 — Wait and Synchronization Reliability
355
+ - Stronger State Verification
356
+ - Richer Element Identity
357
+
358
+ ---
359
+
360
+ # 15.1 Acceptance Criteria
361
+
362
+ An implementation of RFC 014 is considered correct if:
363
+
364
+ - Disabled elements never pass actionability checks
365
+ - Elements in unstable snapshots are never actionable
366
+ - Identity changes force re-resolution before interaction
367
+ - Proxy interaction eligibility blocked elements are rejected
368
+ - All failures produce a defined failure code
369
+ - Actionability is only evaluated AFTER RFC 005/007 resolution
370
+
371
+ # 16. Failure Codes (Actionability Gate)
372
+
373
+ ## Failure Code Derivation Matrix
374
+
375
+ Failure codes MUST be derived directly from predicate evaluation results:
376
+
377
+ | Predicate Failure Condition | Failure Code |
378
+ |----------------------------|-------------|
379
+ | element does not exist in snapshot | NOT_FOUND |
380
+ | element.visible == false | NOT_VISIBLE |
381
+ | element.enabled == false | NOT_ENABLED |
382
+ | snapshot.stable == false | NOT_STABLE |
383
+ | identity_is_stable == false | IDENTITY_UNSTABLE |
384
+ | actionability_by_type(...) == false | NOT_ELIGIBLE |
385
+
386
+ These are the only supported actionability failure codes.
387
+
388
+ Implementations SHOULD return the structured code together with a human-readable reason.
389
+
390
+ # 17. Conclusion
391
+
392
+ Actionability Resolution provides the final gate before UI interaction execution.
393
+
394
+ It ensures that all interactions are performed only on elements that are structurally valid, stable, visible, and interaction-ready, significantly reducing non-deterministic automation behavior.
@@ -194,6 +194,34 @@ Examples:
194
194
  - `success` indicates condition met or resolution succeeded
195
195
  - `success` does NOT indicate outcome correctness
196
196
 
197
+ ### 6.4 `wait_for_ui_change`
198
+
199
+ `wait_for_ui_change` synchronizes on observable in-place UI mutation.
200
+
201
+ Inputs:
202
+
203
+ - `platform?: "android" | "ios"`
204
+ - `deviceId?: string`
205
+ - `timeout_ms?: number`
206
+ - `stability_window_ms?: number` (default: `300`)
207
+ - `expected_change?: "hierarchy_diff" | "text_change" | "state_change"`
208
+
209
+ Required semantics:
210
+
211
+ - success means a qualifying UI mutation was observed and remained stable for a full `stability_window_ms`
212
+ - stabilization MUST reset whenever a synchronization-relevant mutation is observed
213
+ - the stabilization window MUST be measured from the most recent qualifying mutation
214
+ - the implementation MUST treat as synchronization-relevant: element addition or removal, visibility changes, enabled-state changes, navigation transitions, text or content-description changes, subtree structure mutation, and semantic accessibility tree mutation
215
+ - the implementation MUST NOT treat as synchronization-relevant: animation frame updates, layout-only jitter, opacity-only visual transitions, and non-semantic rendering updates
216
+ - partial convergence MUST NOT be reported as success
217
+ - timeout MAY return the last observed state, but MUST NOT report stable convergence
218
+
219
+ Guidance:
220
+
221
+ - prefer `wait_for_screen_change` for navigation transitions
222
+ - prefer `wait_for_ui_change` for in-place updates and recomposition-style changes
223
+ - follow with `expect_*` when the expected final state is known
224
+
197
225
  ## 7. Failure Semantics
198
226
 
199
227
  ### 7.1 Canonical Codes
@@ -182,6 +182,12 @@ Capabilities:
182
182
  - waits for hierarchy, text, or state deltas
183
183
  - uses snapshot revision metadata when available
184
184
  - confirms the change remains stable before returning success
185
+ - defaults `stability_window_ms` to `300`
186
+
187
+ Mutation rules:
188
+
189
+ - synchronization-relevant: element addition or removal, visibility changes, enabled-state changes, navigation transitions, text or content-description changes, subtree structure mutation, semantic accessibility tree mutation
190
+ - not synchronization-relevant: animation frame updates, layout-only jitter, opacity-only visual transitions, non-semantic rendering updates
185
191
 
186
192
  Guidance:
187
193
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mobile-debug-mcp",
3
- "version": "0.29.0",
3
+ "version": "0.30.1",
4
4
  "description": "MCP server for mobile app debugging (Android + iOS), with focus on security and reliability",
5
5
  "type": "module",
6
6
  "bin": {