feat(android): hand rotation back to the sensor with orientation auto
Summary
orientation <rotation> on Android turns auto-rotate off and nothing turns it back on, so one rotation locks the device for every later check. orientation auto writes accelerometer_rotation=1, leaves user_rotation alone, and reports that the sensor owns rotation. Only ADB-backed Android (local and Limrun) declares the unlockOrientation operation. Every other owner refuses auto with UNSUPPORTED_OPERATION before binding. There is no display settle: the sensor decides the next rotation, so there is no target to wait for. The mode stays out of DeviceRotation. It is its own argument vocabulary (OrientationRequest) and its own admission cell, so rotation readers keep their one-to-one mapping.
agent-device orientation landscape-left # locks: accelerometer_rotation=0
agent-device orientation auto # unlocks: "Rotation follows the device sensor"
client.command.orientation({ orientation: 'auto' })
41 files changed. Three review commits follow: unlockOrientation is classified runner-free in Apple plan demand, the daemon auto branch shares the rotation path's intent builder, and the refusal matrix now drives the auto positional plus per-platform assertions.
Validation
Head 042fd5ed6, base 112d29160.
pnpm check:affected --run --head HEAD: lint, typecheck, layering, di-seams, fallow, mcp-metadata, build, package, integration-node, macos-coverage, and 9673 unit tests passed. Three runner-artifact-manifest.test.ts symlink cases fail; they reproduce identically on the unchanged base, so they are base-blocked.
Device evidence at head. Android emulator: landscape-left leaves accelerometer_rotation=0 user_rotation=1, then auto leaves accelerometer_rotation=1 with user_rotation unchanged. iOS Simulator (iPhone 17): auto is refused with the ADB-only hint before any binding, portrait still rotates.
CI owns coverage, device lanes, provider integration.