[P2] Job framing injects a synthetic newline into stderr and transcripts

#23 · closed · 1 comments

View on GitHub ↗

Azathothas

Tested the published **wsl-toolkit-v1.3.0 Windows amd64** binary on Windows 11/WSL2 on 2026-09-10. SHA-256: `71b2ef9b0cf50da0acda45e7cc9293185a2b18d8aa403812e20ed29222d54424`, matching the release manifest. Related: #10. ## Summary Every successful job injects one newline into stderr even when the payload writes none. JSON, byte counts, and complete transcripts all present that synthetic byte as command output. ## Reproduction ```powershell & $wtk run --image alpine --json -c 'printf ONLY-STDOUT' & $wtk run --image alpine --json -c 'printf ERR-LIVE >&2' ``` Observed on both direct and helper paths: - A no-stderr command returned `"stderr":"\n"` and `stderr_bytes: 1`; `stderr.log` contained a blank line. - The real-stderr command returned `"stderr":"\nERR-LIVE"` (with its terminator) and counted one byte more than the payload wrote. ## Cause The container wrapper prints the completion token to stderr as `printf '\n%s\n' ...`. `markerStripper.Write` removes the marker but deliberately writes the leading newline back to the destination. That newline is synthetic when the payload had no unterminated stderr text, and it also precedes genuine stderr. ## Impact JSON consumers cannot distinguish “no stderr” from output, exact byte accounting is wrong, and transcript comparison/golden tests see data the Linux command never produced. ## Expected Protocol framing must not alter the payload streams. Preserve an unterminated final payload line without manufacturing a byte for empty or newline-terminated stderr. Test empty stderr, terminated stderr, unterminated stderr, marker-like payload text, direct and helper paths, and exact byte counts/transcripts.

Comments

Azathothas

Fixed in `wsl-toolkit-v2.0.0`, by `WSL-46` in `TODO/wsl-toolkit-go.md`. The container wrapper writes a framing marker to stderr so an image that never ran can be told from a program that exited 125. The stripper removed the marker and wrote the newline in front of it **back** into the payload's stream, so a job writing nothing to stderr reported one byte. Re-derived against the published v2.0.0 binary, 2026-09-10: ```text $ wsl-toolkit run --image alpine --json -c 'echo only-stdout' stderr_bytes=0 stdout_bytes=12 stderr=<> ``` Worth recording: `WSL-39` closed and shipped saying the marker was stripped before any sink saw it, and this issue was filed against a release cut believing that sentence. A sixth review pass found the citation, following it found this, and the entry is amended in place rather than corrected, because a test named for a property the code does not have is the more useful half of that record. `stderr_bytes` being one smaller is a break and `docs/consumers.md` carries the row.