`wai channel verify ... | head` exited 7 with "failed printing to stdout: Broken pipe". Rust's runtime ignores SIGPIPE, so a write to a pipe whose reader has gone returns EPIPE, and print!/println! panic on it; the door's catch_unwind turned the panic into an internal error. Every command of the binary did the same (an operation's text, its JSON envelope, the help the door prints itself), and so did wai-pack (exit 101) and wai-quantum (101). The fix is at the write sites, not in SIGPIPE's disposition at start. Restoring SIG_DFL at start would end the process on a write to any pipe whose reader has gone, a child's standard input among them: `wai key` writes a secret to a helper's input and `wai mcp`'s dev room writes to its child's, and there the command should say what failed rather than vanish. It would also leave Windows, which has no SIGPIPE, as it was. So each binary declares one module first, with #[macro_use], whose print!, println!, eprint! and eprintln! write through one function: a failure of kind BrokenPipe on the process's own standard output or error ends the process as a Unix tool's ends, by restoring SIGPIPE's default action and raising it (the shell reports 141, and pipefail sees what it sees for cat), and on Windows with status 141; any other failure panics with std's own message, as before. The handful of direct writes to stdout (prior-set's listing, the log follower's lines, wai-pack's listing and fixture bytes, wai-quantum's convert output) go through the same check. wai-quantum's completions are generated into a buffer first, since clap_complete panics on a failed write of its own. The unit-test builds keep std's macros, whose output the harness captures. The log follower of `wai logs` and `wai session list` ended with success on any write error; a real one is now an internal error. Tests, each through the binary with a pipe whose reader is closed before it starts (so its first write finds the reader gone): tests/cli_dx.rs (wai channel verify, wai ops list --json, wai --help), wai-pack tests/stdout_pipe.rs (fixture list, fixture gen) and wai-quantum-cli tests/stdout_pipe.rs (methods, methods --json, completions bash) require SIGPIPE on Unix, 141 on Windows, and nothing on standard error. A real write error still fails, on Linux to /dev/full (and on Windows, in cli_dx, to a handle open for reading alone): wai exits 7 saying "failed printing to stdout: No space left on device", wai-pack and wai-quantum fail as before. On the Framework (Linux): with main's wiring every new reader-gone test fails (wai exit 7 with the panic's message, wai-pack and wai-quantum 101), and with this change all pass; with the BrokenPipe arm planted out of each binary's check, each reader-gone test fails again. Clippy on the wai binary reports the same findings before and after (all in the library, none new); wai-pack's and wai-quantum-cli's clippy -D warnings, as their workflows run it, pass. On the old prod Mac Studio (macOS arm64), cli_dx's tests that run there and both crates' reader-gone tests pass. On cbio-device-0000 (Windows x86_64), cli_dx's two new tests pass: status 141 with nothing on standard error, and exit 7 for a write to a handle open for reading alone. Stacked on main, the floor, cli_dx, fleet, studio, doctor, mcp, setup-agent, ops, key, toolchain, target, folds and channel-lineup tests pass on the Framework, and wai breaking finds no break. Co-Authored-By: Claude Opus 5.5 <[email protected]>
1,003 B
1,003 B
wai, wai-pack and wai-quantum end quietly when their reader stops reading
- A reader gone (
wai channel verify ... | head) endswaiwithout a word, as it ends a Unix tool: on Unix bySIGPIPE, which a shell reports as 141, and on Windows with status 141. Neither is one of the toolchain's exit codes. Until now the next write panicked ("failed printing to stdout: Broken pipe") andwaiexited 7, an internal error. Any other failure to write standard output is still the error it was. Only a write to the process's own standard output or error ends it so: a write to a child's input that has gone is still reported by the command that made it. wai-packandwai-quantumdo the same.wai-quantum completionswrites its script whole, so a failed write is its error (exit 1) rather than a panic.wai logsandwai session list, following a log, ended with success on any failed write; one other than a reader gone is now an internal error (exit 7).