Skip to content

Commit d92634f

Browse files
docs(adr): describe Maestro endpoint-hold internal seam in ADR 0013/0015
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent 8203a05 commit d92634f

2 files changed

Lines changed: 30 additions & 13 deletions

File tree

docs/adr/0013-unified-gesture-plans.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,31 @@ the Android planned-touch executor.
2222
## Decision
2323

2424
Public gesture inputs normalize once in `src/contracts/gesture-normalization.ts`. This is the
25-
explicit compatibility boundary: convenience APIs and deprecated arguments become canonical
26-
semantic intent before entering the runtime. The private daemon wire is free to evolve with that
27-
model; compatibility is owed at CLI, Node.js, and MCP.
25+
explicit public compatibility boundary: canonical semantic intent is produced before entering the
26+
runtime. Deprecated arguments that have been removed (timed `swipe`, timed `gesture fling`,
27+
`gesture rotate` `velocity`) are rejected with actionable `INVALID_ARGS` messages rather than
28+
silently reinterpreted. The private daemon wire remains free to carry compatibility-only hints
29+
that do not appear on public surfaces; Maestro timed swipes use
30+
`internal.gestureExecutionProfile: 'endpoint-hold'` to preserve iOS fast-swipe-then-hold behavior
31+
while still routing through the canonical `pan` input.
2832

2933
The runtime plans canonical intent in `src/contracts/gesture-plan.ts`. Contact topology is separate
3034
from motion:
3135

3236
- one contact: pan or fling with a complete pointer trajectory and an explicit execution profile;
3337
- two contacts: pan, pinch, rotate, or transform with two complete, synchronized trajectories.
3438

35-
`swipe` without a duration is public sugar for a fixed-duration fling. Its historical optional
36-
duration normalizes to pan intent with an endpoint-hold execution profile and reports a deprecation
37-
toward explicit pan. Maestro-authored swipes follow the same normalization and materialize
38-
Maestro's 400 ms default when duration is omitted. A genuine pan uses the timed-pan profile, so
39-
compatibility aliases retain their release behavior without becoming a new semantic intent. The
40-
same deprecation-to-pan rule applies to the historical fling duration. Pinch fixes translation and rotation at zero; rotate fixes
39+
`swipe` without a duration remains public sugar for a fixed-duration fling. Timed public forms
40+
(`swipe x1 y1 x2 y2 durationMs`, `gesture fling direction x y distance durationMs`,
41+
`gesture swipe preset durationMs`, and `gesture rotate degrees x y velocity`) are rejected; callers
42+
must use `gesture pan` for deliberate timed translation and `gesture rotate` without `velocity`.
43+
Maestro-authored swipes normalize to the canonical `pan` input (origin, delta, durationMs) and carry
44+
the `endpoint-hold` execution profile through a daemon-internal compatibility seam
45+
(`internal.gestureExecutionProfile`). This preserves the iOS fast-swipe-then-hold behavior that
46+
matches Maestro's XCTest driver, without exposing the profile on the public command surface. Maestro
47+
materializes its 400 ms default when duration is omitted. A genuine public `pan` uses the `timed-pan`
48+
profile, so compatibility-only paths retain their release behavior without becoming a new semantic
49+
intent. Pinch fixes translation and rotation at zero; rotate fixes
4150
translation at zero and scale at one; two-finger pan fixes scale at one and rotation at zero;
4251
transform can apply all three
4352
components atomically. Intent remains on the plan even when aliases share an executor.

docs/adr/0015-direct-maestro-engine.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ Android compatibility is materially faster than native Maestro in the pager and
2121
that advantage is a product constraint, not expendable migration headroom.
2222

2323
ADR 0013 separately owns public gesture normalization, contact topology, trajectory planning, and
24-
native injection. Maestro's supported gesture surface is single-pointer swipe only.
24+
native injection. Maestro's supported gesture surface is single-pointer swipe only. Maestro swipes
25+
normalize to ADR 0013's canonical `pan` input (origin, delta, durationMs) and carry the
26+
`endpoint-hold` execution profile through a daemon-internal compatibility seam
27+
(`internal.gestureExecutionProfile`), preserving iOS fast-swipe-then-hold behavior without exposing
28+
the profile on the public command surface.
2529

2630
## Decision
2731

@@ -55,13 +59,17 @@ The engine does not implement platform input. Absolute and percentage swipes pre
5559
endpoints without a hierarchy capture. Directional horizontal swipes reuse ADR 0013's shared in-page
5660
preset geometry so an iOS right swipe does not become an interactive-back gesture; vertical presets
5761
retain Maestro's platform geometry. All viewport-relative swipes resolve the cheapest fresh interaction
58-
viewport available so ADR 0013 can validate every planned sample.
62+
viewport available so ADR 0013 can validate every planned sample. Maestro swipes pair that resolved
63+
viewport with `internal.gestureExecutionProfile: 'endpoint-hold'` on the nested public `gesture` request
64+
so ADR 0013 produces the iOS fast-swipe-then-hold profile without a public `executionProfile` field.
5965
When normalization already resolves a viewport, the adapter pairs it with the nested public gesture
6066
request as daemon-internal metadata. ADR 0013 planning consumes that exact frame instead of probing
6167
the platform a second time.
68+
6269
Target-relative swipes reuse the target-resolution observation. The resulting typed single-pointer
63-
motion enters ADR 0013 after public compatibility normalization. Maestro code cannot construct or
64-
execute two-pointer pan, pinch, rotate, transform, or physical pointer trajectories.
70+
motion enters ADR 0013 as the canonical `pan` input, with the `endpoint-hold` execution profile carried
71+
as daemon-internal metadata. Maestro code cannot construct or execute two-pointer pan, pinch, rotate,
72+
transform, or physical pointer trajectories.
6573

6674
Simple successful target queries return their match, visibility decision, candidate count, and
6775
observation generation in one response. The daemon may retain the provider snapshot behind that

0 commit comments

Comments
 (0)