the phone walk refuses one, because a real device's orientation is not the harness's to set. The device turns itself over instead, in a block of the phone walk's own, after `background` and before the network — because a step list cannot do either of the two things this needs. It reads `settings get system accelerometer_rotation` and `user_rotation` FIRST and latches the pair; only then does it put auto-rotate off and `user_rotation` to 1 (a retry at 3 for a device whose natural orientation is landscape), and it polls for the turn rather than waiting a fixed time. Then it asserts what only a device can answer: `screen.orientation.angle` is 90 or 270 — an `Emulation.setDeviceMetricsOverride` without `screenOrientation` leaves the angle at 0, so the mock physically cannot fake this, and it is the one clean "a real phone did this" clause — that the WebView RESIZED as well (a separate clause, because a WebView that never got the configuration change looks identical to a display that never rotated), that `--nav-h` computed to 48px so the phone-sized landscape query really fired, that the activity was NOT recreated (the same window token and the same `performance.timeOrigin`, the same pid, no `AndroidRuntime` fatal — the manifest declares `orientation` and `screenSize` handled, so a recreation here would be the bug), that the tab and every stack are where they were, that the track is still playing and past where it was, that nothing is clipped, and that the glass bar, the mini bar and the screen spend whatever `env()` says. Then the player sheet sideways: two columns, every control on screen, its own side padding. Then back. The four safe-area insets are printed, not asserted. Nobody had ever measured them on this phone: `MainActivity` calls androidx's `enableEdgeToEdge()`, `themes.xml` sets no cutout attribute and nothing in the generated Kotlin touches insets, so `env()` comes straight out of Chromium's own window-inset mapping and whether the hole-punch shows up as a non-zero side inset depends on the cutout mode that picks. The run records the numbers — `insets` as top/right/bottom/left, `insetsReal`, the app's own `--inset-left/right` beside them, and `chromePct` — and a later round can assert them once they are known. Asserting a number nobody has measured is how a round fails on a correct build. Putting the phone back is the part that is written carefully, because the phone is Kyle's. The saved pair is a module-level latch, and the restore is reached from four places: the rotation block's own `finally`, main's `finally`, `process.on("exit")` and SIGINT/SIGTERM/SIGBREAK. It has to be all four — a failed clause only pushes a problem and walks on, but `still()` and the probe call are wrapped in nothing, so a WebView that stops answering rejects after 45 s and throws clean out of the loop, and Ctrl-C runs no `exit` handler at all. The latch clears itself before it writes, so only the first caller acts and a restore that fails hands the latch back for the next one. The rotation goes back before auto-rotate does, so a phone that had the sensor in charge gets it back last. A device whose two settings will not read is skipped with a line rather than forced — `rotation skipped: the phone's rotation settings would not read` — as is one that is already sideways, and `--no-rotate` skips the block outright for a run where he is holding the phone. Nothing else on the device is touched: no download, no room, no message, no sign-in, nothing written to the config or the library. The one case no handler covers is a hard kill of the machine, after which auto-rotate is a Quick Settings tile away. The stills are `phone-turned.png`, `phone-turned-sheet.png` and `phone-turned-back.png`.