Test 705 — bridge survives a broken stdout tee
source_commit=71c08a2cc3f0728d1002adda775497b2eb6e3805

Layer 1: process + tee behavior
bun test v1.3.14 (0d9b296a)

src/process-survival-log.test.ts:
(pass) agent-node process survival log > the production logger switches to file-only output after EPIPE [3.94ms]
(pass) agent-node process survival log > closed stdout records EPIPE and the process stays alive [440.10ms]
(pass) agent-node process survival log > repeated broken-stream notifications record EPIPE only once [88.37ms]
(pass) agent-node process survival log > uncaught exception preserves its stack on stderr and in the synchronous log [93.27ms]
(pass) agent-node process survival log > unhandled rejection exits 1 with a synchronous reason [95.96ms]
(pass) agent-node process survival log > Grok CLI survival diagnostics use the hardened private-log writer [3.44ms]

 6 pass
 0 fail
 18 expect() calls
Ran 6 tests across 1 file. [800.00ms]
bun test v1.3.14 (0d9b296a)

src/codex-copresence-bridge-log.test.ts:
(pass) #535 codex bridge launch log > tee keeps the writer alive when a secondary sink closes [41.06ms]
(pass) #535 codex bridge launch log > a non-GNU tee falls back to portable tee without losing pane or file output [68.92ms]
(pass) #535 codex bridge launch log > a dead bridge: tail + path, and no tmux attach to a session that is gone [1.27ms]
(pass) #535 codex bridge launch log > a live but silent bridge keeps the attach hint and says the log is empty [0.25ms]
(pass) #535 codex bridge launch log > tailLines drops trailing blanks and CRs [0.13ms]
(pass) #535 codex bridge launch log > the tee statement copies stdout+stderr to the log, whole lines up to the cap, without breaking the writer [68.62ms]
(pass) #535 codex bridge launch log > a line reaches the log while the writer is still running (a live bridge that never attached) [60.29ms]

 7 pass
 0 fail
 24 expect() calls
Ran 7 tests across 1 file. [351.00ms]

Layer 2: typecheck and production builds
$ bun build src/cli.ts --outdir dist --entry-naming cli.js --target node --minify --external @anthropic-ai/claude-agent-sdk --external '@anthropic-ai/claude-agent-sdk-*' --external @openai/codex-sdk --external node-pty && bun build src/upload-file-mcp-stdio.ts --outdir dist --entry-naming upload-file-mcp-stdio.js --target node --minify
Bundled 372 modules in 310ms

  cli.js  1.48 MB  (entry point)

Bundled 221 modules in 185ms

  upload-file-mcp-stdio.js  0.27 MB  (entry point)

$ tsc --noEmit

Layer 3: witnessed-red mutations
WITNESSED_RED: no-stdout-epipe-listener (closed stdout records EPIPE)
WITNESSED_RED: cli-does-not-switch-to-file-only (the production logger switches to file-only output after EPIPE)
WITNESSED_RED: no-uncaught-diagnostic (uncaught exception preserves its stack)
WITNESSED_RED: no-fatal-stderr-stack (uncaught exception preserves its stack)
WITNESSED_RED: tee-without-p (tee keeps the writer alive)
WITNESSED_RED: tee-without-portable-fallback (a non-GNU tee falls back)

RESULT: PASS

Board #714 follow-up (2026-10-08)
- Docker: tests/test705-bridge-epipe/Dockerfile, --cpus=2, rc=0.
- The GNU tee case now executes codexBridgeTeeCommand instead of a hand-written
  approximation and closes its generated secondary sink before the writer's
  next burst.
- Witnessed-red mutation removes `$tee_arg` from the production tee invocation:
  rc=1 at "tee keeps the writer alive" (not an environment failure).
