8ad055414b
`cargo build 2>&1 | tail -20` exits with tail's 0 even when the build failed — bash without pipefail reports the last pipeline command's status, and `cmd || echo failed` swallows the status the same way. The model reads exit_code: 0 as a strong success signal and can conclude a build passed while the visible output says it failed (community report, Windows Rust builds; not platform-specific). Two-part fix, mirroring OpenCode's prompt-side approach plus a result-side backstop they don't have: - Tool description now forbids piping builds/tests through tail/head/cat (output is already auto-truncated + spilled to a file) and warns that pipes/|| fallbacks mask exit codes. - New annotate_masked_success() in tools/terminal_hints.py: when exit_code == 0, the command shape can mask an upstream status (top-level pipe into a passthrough consumer, or || echo/true), AND the output carries strong tool-specific failure shapes (rustc, cargo, pytest, gcc, npm, make, ninja), attach an advisory 'hint' telling the model to treat the run as failed and re-run bare. exit_code itself is never modified. Search/content heads (grep/rg/echo/printf/...) are excluded to avoid false positives on pipelines whose output legitimately contains error text. E2E-verified through the real terminal tool path: hint fires on masked cargo-style failures, silent on bare commands, clean pipes, and grep/printf pipelines. 42 targeted tests pass.