# Phase 1 — Prove the ADB link Status: **proven**. Originally verified on `.13` on 2026-10-16 and re-verified on 2026-10-16 during Phase 2 work. Phase 1 is the risk phase. Its Definition of Done is: *the view tree of a real phone screen is fetched.* That is done. --- ## 1. What was proven | Item | Value | |---|---| | Host | `.13` (`nixos-desktop`, LAN `192.168.20.13`, tailnet `100.114.62.46`) | | adb | `android-tools-36.0.1`, installed with `nix profile install nixpkgs#android-tools` | | adb server | listening on `127.0.0.1:5037` | | Trusted key | `.27`'s `~/.android/adbkey` copied to `.13`; fingerprint `QAAAAOHiKYXfHo1i36gZXZqqoTErVCGXiEGc1Jv9atu+BHbi+JiNmPjQxUML` | | Device | `100.101.49.17:46689` → `device product:akita model:Pixel_8a device:akita` | | View tree | `adb shell uiautomator dump` → 14955 bytes, 42 nodes, all `com.tailscale.ipn` (first proof) | | Screenshot | `adb exec-out screencap -p` → 174977 byte PNG, 1080x2400 (first proof) | The first proof captured the Tailscale app screen. Text and bounds are both present in the dump, so FR-2 (read the screen) and FR-4 (find by text) are viable: ``` [TextView] samuelrolfe@gmail.com bounds=[221,155][798,217] [TextView] Connected bounds=[221,217][453,277] [TextView] sams-pixel-8a bounds=[89,946][431,1022] [TextView] nixos-desktop bounds=[89,1145][428,1221] ``` ## 2. Commands Run these on `.13`. Every command is bounded with `timeout` so nothing can hang. ```sh # tool and server adb version ss -ltn | grep 5037 # connect (port changes — see section 4) adb connect 100.101.49.17:46689 adb devices -l # read the screen adb shell uiautomator dump /sdcard/artemis_window_dump.xml adb exec-out cat /sdcard/artemis_window_dump.xml # screenshot adb exec-out screencap -p > shot.png ``` Expected device line: ``` 100.101.49.17:46689 device product:akita model:Pixel_8a device:akita transport_id:2 ``` ## 3. Why the copied key works, and no pairing code is needed The phone's ADB trust list is keyed by **public key**, not by host. A copy of `.27`'s private key is therefore indistinguishable from the original, so the phone already trusts `.13`. No pairing code and no re-pairing step is required. `adb mdns services` is **not** available in this build (`error: unknown host service 'mdns:services'`), and mDNS does not cross the tailnet anyway. ADB cannot auto-discover the phone, so Artemis must be told the tailnet address and must discover the port itself. ## 4. Finding the port when it changes The wireless-debugging port changes on **every phone reboot or toggle of wireless debugging**. `36291` and `38989` are dead ports from earlier sessions. Never hardcode the port. Android opens **two** TCP ports: a pairing port (which refuses `adb connect`) and the connect port (which succeeds). On 2026-10-16 the open ports were `38989` (pairing, refused) and `46689` (connect, worked). Artemis implements the scan in Go: ```sh artemis connect # scan 30000-65535 on ARTEMIS_PHONE, then adb connect artemis connect # connect directly when the port is known ``` The equivalent scan by hand: ```sh # 1. find open ports in the wireless-debugging range for p in $(seq 30000 65535); do (timeout 1 bash -c "echo > /dev/tcp/100.101.49.17/$p" 2>/dev/null && echo "$p") & done | sort -n # 2. try adb connect on each open port; the one that yields "device" wins adb connect 100.101.49.17: adb devices -l ``` Or ask Sam to read the port from **Settings → System → Developer options → Wireless debugging**. ## 5. Re-verification (2026-10-16, Phase 2 run) ``` $ adb version Android Debug Bridge version 1.0.41 Version 36.0.1-android-tools $ adb devices -l 100.101.49.17:46689 device product:akita model:Pixel_8a device:akita transport_id:2 $ adb exec-out cat /sdcard/artemis_p1.xml | wc -c 64735 ``` The byte count differs from the first proof because the phone was showing Spotify rather than Tailscale. The link, key, device and port all match. ## 6. Constraints carried forward - Never run `nixos-rebuild` on `.13`. It runs the Hub, MQTT and every service, and `/etc/nixos` has uncommitted changes. - adb lives in the **user profile** (see AGENTS.md §13, Q4), not a system module. - Bound every adb command with a timeout.