From 7e18de16749b3a5338d57f7c4dc4d6d9e7a0dbbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20=C5=A0=C4=87eki=C4=87?= Date: Tue, 28 Jul 2026 15:43:07 +0200 Subject: [PATCH 1/4] fix(mobile): unwedge Android E2E emulator claims and preflight MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three defects made Android E2E rounds fail for reasons agents could not diagnose or recover from: - Android device claims treated an ADB serial as a device identity, but serials are recycled emulator ports. A claim was only reclaimable once its owning worktree was deleted, and worktrees outlive runs by days, so a claim left behind by a dead emulator wedged that serial permanently. emulator-5554 and emulator-5556 were both wedged this way on the shared machine — the first two serials any emulator boot takes. Claims now record the guest kernel boot id, so a foreign claim holds a serial only while it names the instance currently answering on it. - The shared E2E preflight accepted only `iOS Bundled` as Metro readiness evidence. On Android the alternative `Starting Metro Bundler` line scrolls out of the captured window on a long-lived stack, so preflight started failing with "Metro has not reached a usable state" the longer a session ran — exactly when mid-test recovery reruns login.sh. It also probed the Metro manifest as iOS regardless of the target platform. - dispatch-role.sh resolved its target with an untargeted `tmux display-message -p '#S'`, which answers with the server's current session rather than the caller's. A dispatcher outside tmux silently dropped role windows into an unrelated session; freshly created kilo-e2e-android-* emulator sessions were the usual victim, and device cleanup then killed those foreign agents. The session is now resolved through $TMUX_PANE, falling back to an own session instead of a guess. Also documents the one-time `expo prebuild --platform android` that `build` needs in a fresh worktree, since apps/mobile/android/ is git-ignored and `build` cannot generate it itself. --- .kilo_workflow/WORKFLOW.md | 2 +- .kilo_workflow/dispatch-role.sh | 17 +++++-- apps/mobile/e2e/AGENTS.md | 2 + apps/mobile/e2e/preflight.sh | 6 ++- dev/local/mobile-android.test.ts | 87 +++++++++++++++++++++++++++++--- dev/local/mobile-android.ts | 50 ++++++++++++++---- 6 files changed, 142 insertions(+), 22 deletions(-) diff --git a/.kilo_workflow/WORKFLOW.md b/.kilo_workflow/WORKFLOW.md index 713d0e8dad..06202ef4cb 100644 --- a/.kilo_workflow/WORKFLOW.md +++ b/.kilo_workflow/WORKFLOW.md @@ -55,7 +55,7 @@ The cwd/worktree is always the **cloud** worktree, even when the slice edits a s What the script encodes (details in `learnings/`): -- tmux wrapping — harness command timeouts kill bare long runs. The `e2e-verifier` gets its **own tmux session** (E2E slots are owned and auto-reclaimed by session name; a window-named owner leaks or shares slots); other roles run as windows in the dispatcher's session. Names are `
--