Running spotify_play against the real phone showed a tap can be delivered
to the app and then never acted on (the dispatcher lists the Spotify window
as the touch target, and the screen does not move). The run log also showed
step durations were printed as 0s while the recorded ones were correct.
- wait steps accept "retry N": on timeout, re-run the step above and wait
again, up to N extra times. Only a wait may use it, it needs a step above
it, and it can only press something already matched by text. spotify_play
uses it on the search box and on the playback check.
- The success log line printed the duration before the deferred assignment
ran. It now records the duration first.
- uiautomator dump starts a JVM on the phone, and the wait helpers polled
every 400ms. ui.PollInterval is now 1500ms, which cuts that load on a
phone that is already short of memory.
docs/phase-3-spotify-recipe.md logs attempts 7-10: the recipe now reaches
tap_row and picks "Honky Tonk Women" at (540,878), but the app stops acting
on input on this loaded phone, so the end-to-end run is still outstanding.
Two defects found by running spotify_play against the real phone.
- Step durations were always zero in the run log: executeStep returned a copy,
so the deferred assignment never reached the caller (FR-10). It now returns a
named value, with a regression test.
- The phone was sitting on the Android Settings app, and wait "Search" was
satisfied by Settings' own "Search Settings" entry, so the recipe tapped the
Settings search bar. New "foreground" step waits until the recipe's app really
is in front; spotify_play uses it right after launch.
docs/phase-3-spotify-recipe.md now logs all six live attempts and states
plainly that the end-to-end playback run has not completed: the phone is
showing a Settings "Verify that it's you" biometric prompt, which needs Sam and
is left untouched.
Phase 3 of AGENTS.md section 11.
Recipes file (FR-5)
- recipes/ holds one hand-editable file per task; recipes/spotify_play.recipe
is the first one.
- internal/recipe parses directives, guards, parameters and steps, and runs
them with a per-step and a whole-run timeout (FR-11).
- Steps name text ("tap the element whose text is Search"), never coordinates.
- guards name screens Artemis must never tap on, so a signed-out or
first-run Spotify fails with its own reason (FR-8).
- Every run appends task, params, steps, result and duration to
logs/runs.jsonl (FR-10).
spotify_play
- launch, search, play, then wait for the transport button to say "Pause".
- internal/ui/rows.go adds tap_row: a result row is a clickable container with
a title and a subtitle, so a one-line search suggestion is not a result, and
the tap lands on the row's centre rather than on its "More options" button.
This fixes a real wrong tap: a plain text tap hit a 126x12 pixel
"More options for song Honky Tonk Women - Live" button.
Locked screen (AGENTS.md section 13 Q2, decided)
- Artemis fails loudly on a secure keyguard and never types a PIN. No secret is
stored. A non-secure keyguard is still dismissed.
- internal/ui/keyguard.go reads the KeyguardServiceDelegate block plus
cmd lock_settings is-user-secure.
- Every acting command wakes the screen before it checks the keyguard: a dozing
phone reports showing=false, because the lock screen is not drawn yet.
- AGENTS.md records the decision and that storing a PIN for auto-unlock is
rejected for now.
Verified live: the phone locked itself mid-session, and keyguard, tap and
run spotify_play all refused with "phone is locked; unlock it and retry".
The live end-to-end playback run still needs an unlocked phone.
Add the Artemis Go CLI and its packages:
- internal/adb: timeout-bounded adb wrapper, device list, wireless-debugging
port scan and auto-connect (never hardcodes the moving port).
- internal/ui: uiautomator dump parsing, find-by-text, tap the centre of a
text match (FR-4), type, swipe, scroll, back, home, launch, wake.
- cmd/artemis: CLI for the primitives plus 'demo', the Phase 2 DoD run.
Failures are loud: a missing or disabled element errors instead of tapping a
guessed coordinate. The screen is woken before acting, and every adb call has
a deadline.
Also record the section 13 Q4 decision (adb lives in the user profile on .13,
wireless ADB needs no udev rules; service packaging still open until Phase 6),
add unit tests, and document the phase evidence.
Capture the commands, evidence and port-discovery method for the proven
wireless ADB link from .13 to the Pixel 8a over Tailscale. Includes the
copied-key rationale (no pairing code) and the moving-port scan.