From dff8b7c45282ed50917175ad976a0cbd7d65013d Mon Sep 17 00:00:00 2001 From: David F Glidden Date: Sun, 7 Jun 2026 18:43:37 +0200 Subject: [PATCH] [FIX] pre-commit: probe /dev/tty by opening it, not testing existence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On macOS /dev/tty always exists, so '[ -e /dev/tty ]' passed even in agent harnesses/CI with no controlling terminal — the subsequent read then died with ENXIO ('Device not configured') and blocked the commit instead of taking the hook's own non-interactive branch. Probe with '( : < /dev/tty )' — the exact operation that fails. Both prompt sites fixed; the deliberate asymmetry preserved (debug keywords warn-and-proceed; secrets fail closed). Verified both paths from a non-TTY context. Surfaced via the be a11y-gate commit bypass logged in today's ledger. Co-Authored-By: Claude Opus 4.8 (1M context) --- git/hooks/pre-commit | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/git/hooks/pre-commit b/git/hooks/pre-commit index 745b7ef..877b9ad 100755 --- a/git/hooks/pre-commit +++ b/git/hooks/pre-commit @@ -26,7 +26,10 @@ if echo "$added_lines" | grep -qE "(console\.log|debugger|binding\.pry|TODO:|FIX echo -e "${YELLOW}Warning: Found debugging keywords or TODOs in added lines:${NC}" echo "$added_lines" | grep -nE "(console\.log|debugger|binding\.pry|TODO:|FIXME:|XXX:)" || true echo - if [ -t 0 ] || [ -e /dev/tty ]; then + # Probe by OPENING /dev/tty, not testing existence — on macOS /dev/tty always + # exists ([ -e ] passes) but open() fails with ENXIO when there is no controlling + # terminal (agent harnesses, CI), which used to kill the read and block the commit. + if ( : < /dev/tty ) 2>/dev/null; then printf "Continue anyway? (y/n) " read -n 1 -r REPLY < /dev/tty echo @@ -56,7 +59,9 @@ if echo "$added_lines" | grep -qE "(password|secret|token|api_key)[[:space:]]*=[ echo "$added_lines" | grep -nE "(password|secret|token|api_key)[[:space:]]*=[[:space:]]*[\"'][^\"']+[\"']" || true echo "Please review your changes carefully." echo - if [ -t 0 ] || [ -e /dev/tty ]; then + # Same open()-probe as above. Note the deliberate asymmetry: secrets BLOCK when + # non-interactive (fail closed); debug keywords proceed with a warning. + if ( : < /dev/tty ) 2>/dev/null; then printf "Continue anyway? (y/n) " read -n 1 -r REPLY < /dev/tty echo