Documentation Index
Fetch the complete documentation index at: https://docs.signalrooms.xyz/llms.txt
Use this file to discover all available pages before exploring further.
Device lanes
Status: Current concept reference.
A device lane is one physical iPhone connected over USB to the Mac host. The lane is the unit of work in SignalRoom: every thread runs on one or more lanes, every account is published from one lane at a time, every evidence bundle is tied to a lane.
This page is the concept page. For hardware specs and the iPhone-side checklist, see iPhone lanes (setup). For the field schema, see Device state model.
One iPhone, one lane, one runner
The model is intentionally simple:
iPhone (UDID) ─USB─► Mac host (Warmr.app) ─► one assigned port ─► RodmanRunner on the iPhone
│ │
└──────────────────────── one lane ─────────────────────────────────────┘
A lane has:
- One UDID: the iPhone’s stable identifier. Display names can change, UDIDs don’t.
- One assigned port: when Warmr binds the lane, it allocates a local TCP port for the runner bridge. Per-device lane stride keeps multiple lanes’ ports from colliding.
- One owner: exactly one Warmr instance owns the lane at any moment. Running two Warmr instances against the same iPhone produces a wedged lane that requires intervention.
- One runner: RodmanRunner is the on-device test runner. The lane is “real” once the runner is installed and the developer profile is trusted.
Lane state fields
Pulled from warmrctl --json devices list:
| Field | What it tells you |
|---|
udid | Stable iPhone identifier. Always key scripts on this. |
displayName | Human-readable name (“Lane 2. Kody”). For dashboards, not for filtering. |
modelName | ”iPhone 13”, “iPhone 14 Pro Max”, etc. |
iosVersion | iOS version string. |
isConnected | Whether the device is currently visible over USB. |
assignedPort | Local port allocated for this lane. Useful when debugging port collisions. |
rodmanInstalledVersion | Runner version installed on the iPhone, or null if not installed. |
isConnected: true only means USB visibility, it does not mean ready-to-run. Readiness is a separate check (next section).
Lane readiness
Five conditions must hold for a lane to start a thread cleanly:
- Connected (
isConnected: true): the iPhone is visible over USB to Warmr.
- Trusted: the “Trust This Computer?” prompt has been confirmed on the iPhone for this Mac.
- Developer Mode on + iPhone settings configured: Light appearance, StandBy off, Auto-Lock Never, etc. See iPhone settings.
- Runner installed (
rodmanInstalledVersion non-null). RodmanRunner is signed onto the iPhone and the developer profile is trusted.
- Not owned by another Warmr instance: only one Warmr can drive a given iPhone at a time.
If any one of these fails, threads on the lane fail with predictable error classes, see Failure recovery.
There isn’t a single isReady field yet (In progress), for now, operators infer readiness from isConnected + rodmanInstalledVersion + a successful no-op test thread.
Lane ownership and collisions
Lane ownership is process-scoped, not user-scoped:
- Two Warmr.app instances on the same Mac can’t both own the same iPhone. The second instance’s
devices.list will show the device as isConnected: false even when it’s physically plugged in.
- Two Macs trying to drive the same iPhone simultaneously will both fail intermittently. Apple’s USB stack doesn’t multiplex. Don’t do this.
- Xcode, iTunes, Finder’s iPhone view, and Apple Configurator can also temporarily claim the iPhone. If a lane drops to
isConnected: false mid-session and the cable is fine, check whether one of those is open and close it.
Recovery from a wedged lane: stop the affected thread, close any competing app, replug the cable, and re-run pre-flight. As a last resort, warmrctl app restart clears the entire Warmr-side state, but that interrupts every other lane on the host. See Failure recovery.
Multi-lane fleets
The fleet sizing math from Mac host setup:
| Mac | Lanes | Notes |
|---|
| M1 / M2 / M4, 16 GB RAM | 1–3 | Direct USB; no hub needed |
| M2 Pro / M4 Pro, 24 GB RAM | 4–5 | One powered hub helps |
| M2 Pro / M4 Pro, 32 GB RAM | 6–10 | Powered hub required |
| M4 Pro / Max, 48–64 GB RAM | 10+ | Multiple powered hubs, 6–8 devices per hub |
Per-lane resource cost: roughly one CPU core’s worth of recognition + a few hundred MB of RAM during active sessions. The Neural Engine on Apple Silicon does the heavy lifting for screen recognition, which is why Apple Silicon Macs run many more lanes than Intel Macs (Intel isn’t supported).
Adding a lane to an active host
The standard flow:
- Plug the new iPhone in. Run through iPhone settings.
- Open Warmr’s Devices page. Confirm the device appears as connected.
- Install the runner (Trust and runner setup). Path A (ASC API) installs on multiple devices in parallel; Path B (Xcode) is one device at a time.
- Trust the developer profile on the iPhone.
- The new lane is now selectable in any thread configuration.
You don’t need to restart Warmr.app to add a lane. Threads that were already running stay running.
Removing a lane
- Stop any threads currently using the lane (
warmrctl thread stop --configuration-id <ID>).
- Unplug the iPhone.
isConnected flips to false.
- The lane drops out of all thread configurations that reference it on next run, but the device row stays in
devices.list (with isConnected: false) until you explicitly remove it from the Devices page.
Leaving a disconnected lane in the device list is fine if you’ll re-attach the iPhone later. Per-account state stays intact.
Common lane problems
| Symptom | Cause | Where to look |
|---|
Device shows in Devices page but isConnected: false | Cable, USB port, or competing app holding the connection | Replug, close Xcode/iTunes/Finder iPhone view |
rodmanInstalledVersion is null | Runner not installed (or install failed) | Trust and runner setup |
rodmanInstalledVersion is older than expected | Free Apple ID cert expired (7 days), or runner version bumped | Re-run install from Warmr’s Devices page |
| Lane shows ready but threads fail “device not found” | Lane was claimed by another Warmr instance, or unplugged after thread started | Check for competing instances; replug |
| Multiple lanes intermittently drop under load | Bus-powered USB hub | Switch to a powered USB hub |
New lane on the Devices page shows assignedPort: null | Warmr hasn’t bound a port to it yet (transient) | Wait 10–30 seconds; if persistent, restart Warmr.app |