MOB-169: mob.deploy freezes explicit targets before doing work - #77
Merged
Merged
Conversation
Discovery used to fan out to every reachable device during compatibility checks, native installs, and the final BEAM push independently. A bare `mix mob.deploy --native` installed on every Android device from `adb devices` and tried every connected iPhone, ignoring ANDROID_SERIAL. The set could change during a long native build, so even reading the initial output did not define which devices the command would later modify — a phone plugged in for unrelated work would receive the deploy. The task now discovers once and resolves an immutable target list before compile / build / install / push begins. Every downstream stage consumes that list. See `decisions/2026-09-11-deploy-freezes-explicit-targets.md`. New shared `MobDev.TaskTargets` policy: - `--device <id>` selects one named device, including a physical device. - `--all-devices` selects every emulator and simulator. - `--all-physical` selects every physical device. - Combined broad flags select every connected device. - No flag = exactly one emulator or simulator, auto-selected. Physical devices are never implicit; multiple development devices are an error demanding an explicit selection. - On Android-only runs, a non-empty `ANDROID_SERIAL` is a named target when no CLI scope was supplied. Explicit CLI wins. `MobDev.Uninstaller` delegates through the same selector so device- changing tasks cannot drift. ## Reviews before commit Adopted this branch from a prior agent's session (they left the work uncommitted, no PR, ticket sitting In Progress with no comment). Rebased onto current master (which now carries the 0.7.1 release), verified the design against the decision record, ran gates: - 2447 mix tests pass (2 new, added while addressing review findings). Every changed test flips when the corresponding fix is reverted. - `mix format --check-formatted`, `mix credo --strict`, `mix compile --warnings-as-errors --force`, `mix mob.security_scan` all clean. Adversarial subagent review of the ~1000-line diff (verdict SOUND WITH FIXES) caught: - **F1 blocker**: `ANDROID_SERIAL` hijacked mixed-platform default runs. On macOS `mix mob.deploy` runs on [:android, :ios], and a stale ANDROID_SERIAL from another tool would turn a bare deploy into `--device xyz` and raise :no_matching_devices against any connected iOS simulator. Fixed by narrowing the ANDROID_SERIAL rule to Android-only runs (matches the decision record's exact wording), plus a `String.trim/1` so a whitespace-only value is treated as unset. Two revert-verified tests added. - **F2 should-fix**: CHANGELOG did not name the multi-emulator break as a behaviour change. Added a paragraph. - **Also caught by me**: the prior agent had added the MOB-169 CHANGELOG entry inside the [0.7.0] block, which shipped to Hex a week ago without any of this work. Moved to a fresh [Unreleased] block at the top. Not device-verified (mob_dev is host-side tooling, no device to verify against). Ready for release when a next mob_dev version warrants one. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- CHANGELOG: name the actual iOS refactor (extracted finalize_ios_override_result/2 so :skipped can no longer inherit the incomplete-override wording) instead of implying a mid-copy fix that the diff does not make. - TaskTargets moduledoc: spell out that combining --all-devices and --all-physical selects every connected device, and that multiple development devices with no scope flag is an ambiguity error. Behaviour unchanged; docs only. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MOB-169 —
mix mob.deployfreezes an explicit target set before compile, build, install, or push, so a device appearing during a long native build cannot join the operation and physical phones plugged in for unrelated work are never implicitly targeted.Adopted this branch from a prior agent's session — they left the work uncommitted, no PR, ticket sitting In Progress with no comment. Rebased onto current master (which now carries the 0.7.1 release), verified the design against the decision record, applied review findings, squashed into one coherent commit.
Design
See
decisions/2026-09-11-deploy-freezes-explicit-targets.md. New sharedMobDev.TaskTargetsmodule implements the policy:--device <id>— one named device, physical allowed--all-devices— every emulator and simulator--all-physical— every physical deviceANDROID_SERIALis a named target when no CLI scope was supplied; explicit CLI winsMobDev.Uninstallerdelegates through the same selector so device-changing tasks cannot drift.Behaviour change users will hit
A bare
mix mob.deploywith two or more emulators or simulators running for parallel testing used to fan out to both, and now refuses with an ambiguity error demanding an explicit selection (--device <id>or--all-devices). Physical devices also no longer receive an implicit deploy. The CHANGELOG under[Unreleased]names this explicitly.Adversarial pre-commit review (SOUND WITH FIXES)
Two real issues, both fixed with revert-verified tests:
ANDROID_SERIALhijacked mixed-platform default runs. On macOSmix mob.deployruns on[:android, :ios], and a staleANDROID_SERIALfrom another tool would turn a bare deploy into--device xyz, raising:no_matching_devicesagainst any connected iOS simulator. Fixed by narrowing theANDROID_SERIALrule to Android-only runs (matches the decision record's exact wording) and adding aString.trim/1so a whitespace-only value is treated as unset. Two new tests, both flip on revert.[0.7.0]block, which shipped to Hex last week without any of this work. Moved to a fresh[Unreleased]block at the top.Gates
mix test: 2447 pass, 0 fail (2 new tests)mix credo --strict: 0 issues (3750 mods/funs)mix format --check-formatted: cleanmix compile --warnings-as-errors --force: cleanmix mob.security_scan: 0 findings across 57 hex deps + 4 bundled OTP tarballsNot device-verified
mob_dev is host-side tooling — no device to verify against. Ready for release when a next mob_dev version warrants one.
Closes MOB-169.