Skip to content

fix(tests): force the non-TTY condition instead of inheriting it - #177

Open
MCamner wants to merge 1 commit into
mainfrom
mq/fix-gitmerge-smoke-tty-20260807-003746
Open

fix(tests): force the non-TTY condition instead of inheriting it#177
MCamner wants to merge 1 commit into
mainfrom
mq/fix-gitmerge-smoke-tty-20260807-003746

Conversation

@MCamner

@MCamner MCamner commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Symptom

mqlaunch → SELF-CHECK stops here:

SMOKE: gitmerge-safe safety contract
...
[9/10] non-interactive execution is refused

Smoke checks failed.

Step 10 never prints. Run from a pipe or CI the same suite passes.

Cause

The gate in gitmerge-safe.sh is:

[[ -t 0 ]] || die "This script needs an interactive terminal (stdin is not a TTY)."

Step 9 ran the script with stdin inherited from whatever launched the suite. That only proves something when the suite happens to run without a TTY. SELF-CHECK runs in a real terminal, so stdin is a TTY, the gate correctly passes, and the script walks on to the next check — in the step's throwaway single-branch repo that is Error: No candidate branches found to merge. The following grep -q 'interactive terminal' finds nothing, set -e aborts, and the suite reports a failure against a script that behaved exactly as designed.

Measured with a real pty on stdin, not a script wrapper:

exit: 1
refuses on TTY grounds: False
output: Error: No candidate branches found to merge.

Change

One redirect. /dev/null is never a TTY, so the condition is forced rather than inherited:

"$MERGE_SCRIPT" </dev/null >/tmp/gitmerge-safe-smoke.out 2>&1 && exit 1

Verification

$ bash tests/gitmerge-safe-smoke.sh                      # no TTY
OK: gitmerge-safe safety contract passed

$ script -q /dev/null bash tests/gitmerge-safe-smoke.sh  # TTY
[9/10] non-interactive execution is refused
[10/10] TTY gate precedes network fetch
OK: gitmerge-safe safety contract passed

$ bash tools/scripts/test-all.sh
[PASS] All selftest checks passed.

The safety contract is unchanged: the script still refuses when there genuinely is no TTY, before any network operation. Step 10 still pins that the gate precedes git fetch.

🤖 Generated with Claude Code

gitmerge-safe-smoke step 9 asserts that the safe merge refuses without an
interactive terminal. The gate is `[[ -t 0 ]]`, and the step ran the script
with stdin inherited from whatever launched the suite — so it only tested
anything when the suite happened to run without a TTY.

Run from mqlaunch's SELF-CHECK in a real terminal, stdin is a TTY, the gate
correctly passes, and the script walks on to "No candidate branches found to
merge" in the throwaway repo. The grep for 'interactive terminal' then fails
and the suite aborts before step 10 — against a script that was behaving
exactly as designed.

Verified with a real pty on stdin (python pty, not a `script` wrapper):
gitmerge-safe.sh does not refuse, exits 1 on the branch check instead. With
`</dev/null` the step passes both with and without a TTY.

The safety contract itself is unchanged and intact: the script still refuses
when there genuinely is no TTY, before any network operation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant