Skip to content

Credential runner signal test: write with os.write so a signal cannot re-enter the buffered stdout - #601

Merged
seathatflowsinourveins merged 1 commit into
mainfrom
claude/credential-run-signal-fixture-20261002
Oct 2, 2026
Merged

seathatflowsinourveins merged 1 commit into
mainfrom
claude/credential-run-signal-fixture-20261002

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator

Scope

One test fixture in tests/test_credential_run.py (ProcessTests.test_exit_code_and_signal_propagate). The fixture's readiness line and its signal handler now write with os.write instead of print. The seven signals, their expected exit codes, the exact stdout assertion and the runner (scripts/credential_run.py) are unchanged. Lane: foundation.

Why: the hosted macOS suite of #592 failed once on this test (run 36946376402, job 110649337077: SIGQUIT subtest, 1 != 9; 9,483 tests, 1 failure). The Codex lane's source diagnosis on #592 named buffered-stream reentrancy as the lead. A handler that prints while the interrupted print still holds the buffered stdout raises RuntimeError: reentrant call inside <_io.BufferedWriter name='<stdout>'>, so the command exits 1 instead of its code. CPython runs signal handlers inside the buffered writer's flush loop (PyErr_CheckSignals after a raw write), which is where the window opens.

SOTA sources

Evidence-class table

Claim Class Where
A printing handler that interrupts a print exits 1 with the reentrancy error; an os.write handler exits with its code local demonstration, timing forced with a full pipe (Python 3.13.15, Linux) commands below
The repaired test passes repeatedly on this host local integration check, 40 of 40 runs commands below
The repaired test passes on the hosted macOS runner not observed yet this pull request's validate-macos check is the observation

The local demonstration forces the window with a blocked write; the hosted failure reached the same window through scheduling. It shows the mechanism, not that it was the cause of that run.

Local commands run

  • Mechanism, old handler against new handler in a child process blocked on a full pipe: print: exit 1 | RuntimeError: reentrant call inside <_io.BufferedWriter name='<stdout>'>; os.write: exit 9.
  • python3 -B -m unittest tests.test_credential_run.ProcessTests.test_exit_code_and_signal_propagate, 40 runs: 40 passed.
  • python3 -B -m unittest tests.test_credential_run: 92 tests, OK.
  • python3 -B scripts/validate.py: passed, 8,976 hashed files.

Both suites ran with the temporary directory outside /tmp: while Codex sandboxes run on this host, an empty /tmp/.git mount target appears and the runner correctly refuses a store inside a git work tree (9 of 150 runs of the unmodified test on main exited 1 with unsafe: inside_git_worktree for that reason). That is a property of this host under load, not of the test.

Decision record

None; a test-fixture repair.

Host evidence

None changed.

Checklist

  • No workflow or action changes.
  • No secrets are printed, logged or committed; no new required secret was introduced.
  • No new paid hosting, subscription or billing surface was introduced.
  • Peer-owned untracked files and worktrees were preserved.

🤖 Generated with Claude Code

…print

The hosted macOS suite failed once on test_exit_code_and_signal_propagate (SIGQUIT subtest, 1 != 9).
The fixture printed its readiness line and printed again from its signal handler. When the signal
arrives while the interrupted print still holds the buffered stdout, the handler's print raises
RuntimeError (reentrant call inside BufferedWriter) and the command exits 1 instead of its code.
Both writes now use os.write, which takes no buffer lock. The seven signals, their exit codes and the
exact stdout assertion are unchanged; the runner is unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@seathatflowsinourveins seathatflowsinourveins added the lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers label Oct 2, 2026
@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator Author

Bounded static reconciliation at d3fdc3974136664dd65aa4e66b12d7a908d2499a: the fixture repair preserves its existing contract.

Both buffered prints become os.write, retaining ready <PID>\n and got <SIGNAL>\n. The readiness read, signal send/wait, and exact stdout assertion remain unchanged. All seven exit codes remain TERM→5, INT→6, HUP→8, QUIT→9, USR1→11, USR2→12, ALRM→13; normal exit and unhandled-signal assertions are also retained. Exact-head fixture.

The only executable-code delta is this test fixture; the second file changes its evidence digest/size. Runner implementation, workflows and runtime configuration are unchanged in the exact comparison.

Acceptance is source-only from the existing Astra/max reviewer. No tests, reruns, source changes or host/service operations by this lane. Owner-reported Linux demonstrations are separate evidence; the required actual macOS CI result must bind to this head. Root has no competing repair unit.

@seathatflowsinourveins
seathatflowsinourveins merged commit 231eed4 into main Oct 2, 2026
25 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/credential-run-signal-fixture-20261002 branch October 2, 2026 05:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant