User Story
Matt (MG) needs reliable OpenShell branch E2E checks while qualifying PR #4066. The Docker Python lane failed its interactive-exec TTY assertion at an unchanged SHA after an earlier successful run, and Matt requested an investigation and a focused draft fix.
Problem Statement
e2e/python/test_sandbox_api.py::test_sandbox_interactive_exec_honors_tty can fail its contiguous TTT assertion even when all three descriptors are terminals, stdin is consumed, both output sentinels arrive, and the command exits successfully. The shell writes each TTY flag separately while the request generator immediately sends stdin; terminal echo can arrive between flag writes.
Attempt 2 failed on October 1, 2026, with 1 failed, 59 passed, 81 skipped. Attempt 1 passed at the same SHA (60 passed, 81 skipped). This was a PR-branch failure. Main at 348a1fc62566892ba5530ac9f35acc983e4d9324 retains the same relevant test/runtime source.
Impact / Why This Matters
The failure prevents repeatable qualification of an unrelated Nix download-recovery change. Rerunning CI consumes time and can produce another false failure without improving coverage.
Acceptance Criteria
Reproduction Steps
- Run OpenShell's Docker Python E2E lane with
mise run e2e:python.
- Repeat the interactive-exec TTY test against the Docker-backed gateway. Its input generator immediately submits
streamed-stdin-sentinel\n after the exec start message.
- When PTY echo is scheduled between the second and third shell flag writes, the test fails despite successful terminal execution. This is intermittent; the two linked CI attempts provide the observed reproduction.
Environment
Logs
assert b'TTT' in (b'TTstreamed-stdin-sentinel\r\nT\r\nstdin:streamed-stdin-sentinel\r\nstdout-sentinel\r\nstderr-sentinel\r\n' + b'')
Proposed Fix
Wait for a complete output readiness marker before streaming stdin, preserving the actual TTY and pipe assertions. A controlled real-PTY/Python-gRPC reproduction produced the exact original failure; the proposed handshake passes the same ordering and rejects deliberate regressions. No production SDK/runtime changes are proposed.
Related testing strategy tracker: #3954. This issue covers only the interactive-exec TTY flake and should be closed independently.
User Story
Matt (MG) needs reliable OpenShell branch E2E checks while qualifying PR #4066. The Docker Python lane failed its interactive-exec TTY assertion at an unchanged SHA after an earlier successful run, and Matt requested an investigation and a focused draft fix.
Problem Statement
e2e/python/test_sandbox_api.py::test_sandbox_interactive_exec_honors_ttycan fail its contiguousTTTassertion even when all three descriptors are terminals, stdin is consumed, both output sentinels arrive, and the command exits successfully. The shell writes each TTY flag separately while the request generator immediately sends stdin; terminal echo can arrive between flag writes.Attempt 2 failed on October 1, 2026, with
1 failed, 59 passed, 81 skipped. Attempt 1 passed at the same SHA (60 passed, 81 skipped). This was a PR-branch failure. Main at348a1fc62566892ba5530ac9f35acc983e4d9324retains the same relevant test/runtime source.Impact / Why This Matters
The failure prevents repeatable qualification of an unrelated Nix download-recovery change. Rerunning CI consumes time and can produce another false failure without improving coverage.
Acceptance Criteria
Reproduction Steps
mise run e2e:python.streamed-stdin-sentinel\nafter the exec start message.Environment
6c4bb7614af2d86783e8a887b8915ef1520e94df(draft PR fix(ci): retry Nix shell and app dependency preparation #4066).Logs
Proposed Fix
Wait for a complete output readiness marker before streaming stdin, preserving the actual TTY and pipe assertions. A controlled real-PTY/Python-gRPC reproduction produced the exact original failure; the proposed handshake passes the same ordering and rejects deliberate regressions. No production SDK/runtime changes are proposed.
Related testing strategy tracker: #3954. This issue covers only the interactive-exec TTY flake and should be closed independently.