Skip to content

test(cli): capture process state when the interrupt test hangs - #1430

Merged
dennisonbertram merged 1 commit into
mainfrom
fix/1422-diagnose-interrupt-hang
Sep 8, 2026
Merged

test(cli): capture process state when the interrupt test hangs#1430
dennisonbertram merged 1 commit into
mainfrom
fix/1422-diagnose-interrupt-hang

Conversation

@dennisonbertram

Copy link
Copy Markdown
Owner

Refs #1422 — diagnostic, not a fix. Deliberately not Closes.

Why

TestGoCodeScriptStopsHarnessdOnInterrupt fails only in CI, and only as an opaque timeout. It just failed on #1429, a docs-only PR touching CLAUDE.md and the engineering log — so it reproduces against main on 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

  • macOS, idle: 3/3 pass under -race
  • macOS, four CPU hogs running: 8/8 pass under -race
  • Linux (Docker, golang:1.26): passes
  • Linux under -race with --cpus=2, 3 iterations: passes
  • Linux with SIGINT ignored by the parent shell — testing whether the wrapper's bash inherits an ignored disposition, since POSIX inherits that across exec: passes

The Process.Wait defect 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, harnesscli and sleep:

wrapper did not exit within 30s of SIGINT
wrapper pid: 1234
relevant processes:
  <pid ppid stat wchan args>

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 TestGoCodeScriptStopsHarnessdOnInterrupt passes 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

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
@dennisonbertram
dennisonbertram merged commit 119b401 into main Sep 8, 2026
2 checks passed
@dennisonbertram
dennisonbertram deleted the fix/1422-diagnose-interrupt-hang branch September 8, 2026 14:15
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