Repository navigation
Description
Motivation
User feedback from a client project:
I had tons of issues with agent-device always trying to open iPhone simulator (default) when I really wanted the session to be scoped to a particular iPad only when I was working with real client's project. Solved it by wrapping every agent-device command with my custom bash script. I think simlock might be a good tool to enforce that.
Project config already provides overridable device defaults. A project also needs an opt-in constraint that prevents explicit selectors, nested commands, or selection heuristics from targeting a different device.
Accepted configuration
{
"devicePin": {
"platform": "ios",
"device": "iPad Pro"
}
}devicePinis a non-empty object containingplatform,device,udid, and/orserial. Boolean values are not supported.- Without
devicePin, top-level selector defaults retain their existing overridable behavior. - A pin supplies its own selector defaults. Ordinary config and environment defaults cannot change its values.
- Keep the pin and its source config file together. No provenance map is needed for unrelated flags.
- A project pin replaces the entire user-config pin. Selector fields are not merged between pins. An explicit
--config/AGENT_DEVICE_CONFIGfile replaces both implicit config files. - Pinning is configured through these files. Do not add a
--device-pinflag or pin environment variable.
Required behavior
- Selector-less commands use the pin or fail if it is unavailable. They never fall back to an unpinned device.
- Conflicting CLI selectors, MCP inputs, remote connection defaults, and batch steps fail with
INVALID_ARGSanddetails.reason: "device_pin_conflict". The error identifies the pin, its config source, and how to edit or remove it. - Compatible refinements pass. Use the existing device-name and platform matching semantics. A supplied UDID or serial must resolve to a device that satisfies every pinned value.
- Check the actual device before granting runtime access. Preserve the constraint through batch and replay child requests, including existing sessions and sessionless device operations.
- Tool input cannot replace or disable operator-configured pinning.
- Surface the active pin in
devices/doctorso agents can discover the constraint.
Non-goals
Device ownership and cross-worktree exclusion belong to #1320. Holding a claim while a child process runs belongs to #3263. A workspace pin is a selection constraint, not a competing claim or provider lease.
Implementation
PR #4384 implements configuration and enforcement. Active-pin visibility in devices / doctor remains follow-up work before this issue is complete.
Activity
thymikee commentedon Aug 31, 2026
Valid feature request, but not AFK-ready yet. Please decide the workspace/root/config authority (environment-only v1 versus project config), selector grammar and precedence, covered command families, daemon/proxy/provider semantics, and how the active pin is surfaced. Keep this distinct from #1320’s host-global device claims: a workspace preference may guide selection, but it must not become a competing ownership authority. Marking .
thymikee commentedon Aug 31, 2026
Correction with exact wording: Valid feature request, but not AFK-ready yet. Please decide the workspace, root, and config authority; selector grammar and precedence; covered command families; daemon, proxy, and provider semantics; and how the active pin is surfaced. Keep this distinct from issue 1320 host-global device claims: a workspace preference may guide selection, but it must not become a competing ownership authority. Label applied: needs-triage.
thymikee commentedon Oct 9, 2026
Decision: accepted as an explicit, opt-in pin policy, separate from #3263.
agent-device.jsonalready providesplatform/device/udid/serialdefaults (merged incli-config.ts), and defaults must stay overridable: making them mandatory would change existing behavior. Scope:#3263 (holding a claim while a child process runs) is a different feature and stays separate.
thymikee commentedon Nov 11, 2026
Decision: device pin configuration: use an explicit selector object, not a Boolean that freezes ordinary defaults:
{ "devicePin": { "platform": "ios", "device": "iPad Pro" } }Keep the pin and the config file that supplied it together. A project pin replaces the entire user pin;
--config/AGENT_DEVICE_CONFIGreplaces both implicit config files. Ordinary defaults and environment variables do not change pinned values. Do not add a--device-pinflag or Boolean environment switch.Validate explicit selectors with the existing matching semantics and reject contradictions with
INVALID_ARGS,details.reason: "device_pin_conflict", the source, and the pinned selector. Also validate the actual selected device before runtime access, so an otherwise unpinned UDID or serial cannot escape a name pin. CLI, MCP, batch, and replay must retain this constraint. General provenance for unrelated flags is not required.PR #4384 is being updated to this design. Showing the active pin in
devices/doctorremains follow-up work on this issue.apex-sentinel-staging commentedon Nov 11, 2026
Apex Sentinel · Issue review
Suggested label:
featureThe issue requests a new opt-in devicePin configuration that constrains device selection across commands, MCP inputs, sessions, and tools, with detailed config schema and required failure behavior.
feat(cli): opt-in workspace device pin via devicePin (callstack#2161)
feat(cli): opt-in workspace device pin via devicePin (callstack#2161)
feat(config): pin workspace devices with explicit selectors (callstac…