#6308·CodeWhale

tui: bind Ctrl+Z (byte 0x1A) to the suspend handshake + add the cucumber PTY test (#6169 follow-ups)

Author: HmbownCreated Sep 17, 2026Updated Sep 17, 2026

Two follow-ups from the #6169 landing (95bc5c008), both deliberately deferred there:

  1. Ctrl+Z binding. Raw mode means the keyboard Ctrl+Z arrives as byte 0x1A, never SIGTSTP (lib.rs:2145-2150 documents the same for Ctrl+C/0x03). The signal handshake now covers externally delivered SIGTSTP/SIGTTIN only; the vim-like Ctrl+Z needs a key handler that runs the full crossterm teardown (legal in normal context) and ends with libc::raise(libc::SIGSTOP) as the last statement. Entry points: composer/key routing in crates/tui/src/tui/ui/handlers/, pause_terminal(...) (terminal.rs:432).

  2. Cucumber PTY test. Add signal() / wait_until_stopped() to crates/tui/tests/support/qa_harness/pty.rs and a job_control_suspend_pty.rs precedent per screen_mode_inline_pty.rs: deliver SIGTSTP, assert WUNTRACED stop + restore bytes on the control stream, SIGCONT -> repaint. The standalone smoke artifacts/agent-reports/plans/6169-pty-smoke.py proves the shape today; this asks for it in-repo under CI.

Also noted from the #6169 review: the background-SIGTTIN path is covered structurally (one shared handler + SIGTTOU ignored at install) but was not driven live end-to-end — the cucumber test above is where that gets proven.