test(cli): capture process state when the interrupt test hangs - #1430
Merged
Conversation
TestGoCodeScriptStopsHarnessdOnInterrupt fails only in CI, and only as an opaque timeout. It has now resisted five reproduction attempts: macOS idle and loaded, Linux, Linux under -race with constrained CPU, and Linux with SIGINT ignored by the parent process. The 30s failure on a docs-only PR also showed it is a hang rather than a thin timing margin — widening the budget in #1423 did not buy headroom, it just made the failure take three times longer to report. Rather than guess a sixth time, dump the process tree with parent, state and wchan when the wrapper does not exit, so the next CI failure carries evidence about what is actually stuck. Refs #1422 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WJGxhoFhA8JjkwZFcLGdS5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refs #1422 — diagnostic, not a fix. Deliberately not
Closes.Why
TestGoCodeScriptStopsHarnessdOnInterruptfails only in CI, and only as an opaque timeout. It just failed on #1429, a docs-only PR touchingCLAUDE.mdand the engineering log — so it reproduces againstmainon a diff containing no code, and every PR is exposed to it.That failure also corrected the diagnosis. The subtest took 30.11s — the full budget I widened it to in #1423. It is a hang, not a thin margin. Widening the budget bought no headroom; it just made the failure take three times longer to report. Treating a 10s timeout as "slow" rather than "hung" was my error.
Five reproduction attempts, all negative
-race-racegolang:1.26): passes-racewith--cpus=2, 3 iterations: passesSIGINTignored by the parent shell — testing whether the wrapper's bash inherits an ignored disposition, since POSIX inherits that across exec: passesThe
Process.Waitdefect fixed in #1423 was real and worth removing, but it was not the cause.What this changes
Nothing about the product, and nothing about what the test asserts. When the wrapper fails to exit, the failure message now includes the process tree with parent, state and
wchan, filtered to the wrapper,harnessd,harnesscliandsleep:So the next CI failure says what is stuck and in which wait state, instead of only how long it took.
Why not just skip it, or widen the budget again
Skipping would hide a hang that may be a real defect in the wrapper's interrupt path — if the wrapper can hang after SIGINT in some environments, users in those environments get orphaned daemons holding the workspace lock, which is exactly the #1416 symptom this test exists to prevent.
Widening the budget again is what I already did once, on a story the evidence has since disproven. Guessing a sixth time without data would repeat that mistake.
The helper is best-effort and runs only on an already-failing path, so it cannot mask the original failure.
Verification
go test ./cmd/harnesscli -run TestGoCodeScriptStopsHarnessdOnInterruptpasses locally, as it always has — which is the problem. The diagnostic path is exercised only on failure, and its value will be visible the next time CI trips.🤖 Generated with Claude Code
https://claude.ai/code/session_01WJGxhoFhA8JjkwZFcLGdS5