PR #18172 review r1 (Opus 5.5), read-only
Scope: origin/main(ab6be13d43)...HEAD(2edca79db5), 5 files +194/-38. Full diff read; callers of remoteDeviceCommand/quoteRemoteArg/remoteDeviceEnvironment, runSshCommand stdin handling, DeviceActions/DeviceService ready.run callers, and historical PR feedback checked.

VERDICT: no blocking source defects found. Native Windows acceptance is still missing (BLOCKED, as stated in the handoff). That is missing proof, not a source defect.

Checked and OK:
- Transport: the remote command is always `sh -s`. The script and payload go over stdin (runSshCommand uses endOnDone, so EOF reaches sh). With no input, the command gets `</dev/null`, so the exec'd command can't read sh's remaining script. With input, `printf %b '<quoted>' | { script; }`. remoteDeviceEnvironment runs before the payload line, and none of its commands read stdin, so it can't consume script bytes.
- Escaping: the order in printfEscaped is correct (backslash first, then CR->\0015, NUL->\0000). The payload is a %b argument, not a format, so `%` is inert. I checked by hand on dash and bash --posix: `a\\0015\0015b\0000c` -> `a \ 0 0 1 5 \r b \0 c`. quoteRemoteArg's CR splice (`'"$(printf '\015')"'`) is correct, and $() strips only trailing LF. Quotes in payloads are escaped through the same quoteRemoteArg. I found no injection path.
- Bootstrap: `node -e ... || export PATH=fallback` inside the brace group doesn't read stdin. The pipeline exit status is node's, because the group exec's node.
- Windows npm: runNpm looks for npm-cli.js beside process.execPath first, then on PATH entries (quotes stripped), and runs it with the same Node without a shell. The child PATH starts with the Node directory, and duplicate path keys are collapsed. A missing CLI throws a clear message (probe surfaces it; install's finally still cleans staging). POSIX still runs `npm` from PATH as before.
- Callers: only SshDeviceHost imports sshDeviceScript, and remoteDeviceEnvironment becoming a function has no other consumers. localSshDeviceHost and packages/ssh tunnel callers are unaffected.
- Docs: the claims match behavior (Node + bundled npm, Git `bin` sh on the SSH service PATH, restart, Test connection) and stay in user voice.

Low / non-blocking (no change required to merge):
1. [Low, behavior change] remoteDeviceEnvironment now appends `$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin` instead of prepending them. This applies to every ready.run command, not just node. Trigger: a host with the same tool both on the SSH PATH and in one of those dirs, e.g. Homebrew-linked java vs the macOS /usr/bin/java stub, or a newer ~/.local/bin node when the system node is already 22+. That host now gets the SSH-PATH copy. This looks intentional (configured PATH wins; node < 22 still falls back to the prepend). Smallest fix if unwanted: keep the prepend and gate only the Windows case. Otherwise just mention it in the PR body.
2. [Low, test cost] The modeled-Windows npm test copies the whole node binary into tmp on every run. It's needed so execPath resolves to the fixture path, so it's acceptable; noting the I/O cost only.
3. [Info] On a real Windows host, DeviceActions passes the probed nodePath (e.g. `C:\Program Files\nodejs\node.exe`) to `exec '<backslash path>'` under Git sh. MSYS accepts Win32 paths, but the host test normalizes to forward slashes, so this path isn't exercised. Add it to the native acceptance checklist; no code change proposed.

Tests: the existing public-host lifecycle test now sends ready.run through a real `sh -s` with stdin and checks CR/NUL/backslash/quotes, an input without a trailing newline, and empty-stdin. That is high value. The modeled-Windows npm dispatch test checks real behavior (selected Node runs npm, and lifecycle children resolve the same Node), not wiring. I found no source-text or static-markup assertions. The skipIf conversions are equivalent to the old early returns.

Still unproven (BLOCKED, not defects): real PowerShell/cmd OpenSSH stdin byte transport, Windows registry install, hub/agent start/stop, interruption/cancellation recovery.
