Skip to content

Reduce routine device-selection ceremony with a deterministic resolver #1777

Description

@thymikee

Problem

Starting a routine local automation session often requires an agent to list devices, infer a target,
then repeat platform/device selectors on open. The explicit path is predictable, but it adds tool
calls and decision points even when exactly one healthy local target is available or the user already
named an unambiguous platform.

The goal is to reduce this bootstrap ceremony without making target choice implicit in ambiguous or
concurrent environments.

Desired outcome

Design one deterministic device-selection policy shared by CLI, Node, MCP, and daemon dispatch so a
routine open can select the only sensible local target while ambiguous selection still fails with a
bounded, actionable candidate list.

Examples of the intended experience:

  • One booted iOS simulator and an iOS app target: open <app> --platform ios uses it.
  • One available Android emulator and no active Android target: the command may boot/select it if the
    command contract explicitly permits that lifecycle transition.
  • Multiple eligible devices: fail before app mutation and return ranked candidates plus the exact
    selectors needed to retry.
  • An existing healthy session: preserve current session ownership and device binding; never silently
    migrate the session to a different device.
  • Physical devices, remote providers, simulator-set overrides, macOS desktop, TV, web, and concurrent
    worktrees keep their current isolation/ownership guarantees.

Constraints and source-of-truth seams

  • Start from the device/session vocabulary in CONTEXT.md and accepted decisions in
    docs/adr/README.md.
  • Selection and support checks must remain derived from the command descriptor registry and
    src/core/capabilities.ts; do not create a new command-name or capability allowlist.
  • Keep simulator-set scoping iOS-specific so it cannot hide the host macOS desktop target.
  • Respect daemon lease/device ownership and DEVICE_IN_USE; convenience must not bypass a live owner
    or make two worktrees select the same device.
  • Prefer explicit device/UDID/serial and an existing session binding over inference.
  • Provider/cloud selection must stay explicit unless a provider already guarantees a single leased
    target. Do not turn local convenience into remote allocation.
  • Any fallback/default must be represented as a named policy with typed reason codes and diagnostics,
    not error-message sniffing.
  • Keep CLI flags and MCP/Node structured inputs aligned if public selection inputs change; follow
    docs/agents/cli-flags.md.

Investigation / design questions

  1. Inventory every current selection path (open, sessionless inventory/state commands, existing
    session reuse, provider targets, default-device helpers) and identify where their precedence rules
    differ.
  2. Define an ordered candidate policy. A starting hypothesis is: explicit selector -> existing session
    binding -> exactly one already-booted compatible local target -> exactly one compatible local target
    whose lifecycle may be prepared -> typed ambiguity/no-candidate result.
  3. Decide whether app identity can contribute to target selection (for example, exactly one device has
    the app installed) without making selection expensive or creating success-path parity differences.
  4. Decide whether selection should be an open behavior only or a reusable resolver for every
    sessionless command that permits a default device.
  5. Specify the result metadata agents need: selected-by reason, candidate count, whether boot occurred,
    and retry selectors. Keep it response-level; do not add bytes per snapshot node.
  6. Prototype ambiguous and concurrent cases before changing defaults. Measure tool-call reduction and
    wrong-target rate, not only happy-path latency.

Verification

  • Unit tests pin candidate precedence and typed reason codes, including explicit selector dominance,
    existing session reuse, one booted target, one bootable target, no target, and multiple targets.
  • Contract/integration coverage proves the same outcome through CLI, Node, and MCP projections.
  • A planted pre-change failure demonstrates that the new single-target case was not already passing
    through another fallback.
  • iOS tests cover simulator-set scoping and physical-device coexistence; Android tests cover emulator
    versus physical serial selection. Add TV/macOS/web/provider cases only where the shared resolver can
    actually fire.
  • Two concurrent worktrees/daemons targeting the same inventory cannot both acquire the device; the
    loser receives DEVICE_IN_USE with the owning session and recovery hint.
  • Ambiguity performs no app/device mutation and returns a bounded deterministic candidate list.
  • Existing explicit command lines remain behaviorally unchanged.
  • Update versioned CLI help, MCP/Node metadata, user docs, and a help-conformance scenario if command
    planning guidance changes.

Acceptance criteria

  • A documented deterministic resolver owns selection precedence across applicable surfaces.
  • The routine exactly-one-compatible-local-target path needs no preliminary devices call.
  • Ambiguous, remote, and concurrent cases remain explicit and safe.
  • Selection reason and retry guidance are structured and test-covered.
  • No parallel hand-maintained device-selection allowlist is introduced.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions