You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The run-and-die work in PR #61 (issue #60) ships the Windows kill path and a gated end-to-end test for it, but the test has never been executed against a real Windows-container Docker daemon — only Linux/macOS-container daemons were available on the dev hardware. This issue tracks running (and keeping green) that orphaned-node.exe gate on a Windows Bench. It is the one remaining deferred item from PR #61 that needs hardware, so it is split out rather than blocking the merge.
This is verification of code that already exists, not new feature work. Nothing needs to be written unless the gate fails on Windows.
Background — why Windows is different
Windows has no POSIX signals or process groups, so signalling the node --test parent does not reap its spawned children (ADR-0021 Decision 4). The design's correctness guarantee is therefore container teardown (--rm / docker rm -f), with a best-effort Tier-1 precision path of taskkill /T /F /PID <runner> (/T = whole tree). Decision 4 makes a Windows integration test asserting zero orphaned node.exe after a reaped run a required empirical gate (there is no Windows runtime ADR yet, so the test is the contract).
What already exists (do not re-implement)
Kill path — reporter/watchdog.mjs, sendSignal() (the process.platform === 'win32' branch): spawns taskkill /PID <pid> /T, adding /F for the hard kill.
Gated test — internal/dispatch/windows_e2e_test.go, TestE2E_Windows_WatchdogReapsViaTaskkill. It builds the real Windows Tester Image, runs a leaked-timer hang under isolation:"none", asserts Outcome == reaped, and asserts the labelled --rm container left nothing behind. It skips cleanly unless docker info --format '{{.OSType}}' reports windows (requireWindowsContainers), so go test ./... stays portable everywhere else.
Windows image — dockerfiles/windows.Dockerfile (bakes the reporter, watchdog, entry script run-and-die.cmd, and leak-probe).
Acceptance criteria
On a Windows host with Docker in Windows-container mode, go test ./internal/dispatch -run TestE2E_Windows_WatchdogReapsViaTaskkill -vruns (does not skip) and passes.
After a reaped Windows run, zeronode.exe processes survive (the test asserts the --rm container is gone; spot-check tasklist / Get-Process node for belt-and-suspenders).
If the gate fails, root-cause and fix the taskkill /T path (or the teardown backstop) until it is green; update ADR-0021 Decision 4 / the Implementation-status section accordingly.
Wire this into CI on a Windows runner if/when one is available, so the gate does not silently rot back to "never executed".
Summary
The run-and-die work in PR #61 (issue #60) ships the Windows kill path and a gated end-to-end test for it, but the test has never been executed against a real Windows-container Docker daemon — only Linux/macOS-container daemons were available on the dev hardware. This issue tracks running (and keeping green) that orphaned-
node.exegate on a Windows Bench. It is the one remaining deferred item from PR #61 that needs hardware, so it is split out rather than blocking the merge.This is verification of code that already exists, not new feature work. Nothing needs to be written unless the gate fails on Windows.
Background — why Windows is different
Windows has no POSIX signals or process groups, so signalling the
node --testparent does not reap its spawned children (ADR-0021 Decision 4). The design's correctness guarantee is therefore container teardown (--rm/docker rm -f), with a best-effort Tier-1 precision path oftaskkill /T /F /PID <runner>(/T= whole tree). Decision 4 makes a Windows integration test asserting zero orphanednode.exeafter a reaped run a required empirical gate (there is no Windows runtime ADR yet, so the test is the contract).What already exists (do not re-implement)
reporter/watchdog.mjs,sendSignal()(theprocess.platform === 'win32'branch): spawnstaskkill /PID <pid> /T, adding/Ffor the hard kill.internal/dispatch/windows_e2e_test.go,TestE2E_Windows_WatchdogReapsViaTaskkill. It builds the real Windows Tester Image, runs a leaked-timer hang underisolation:"none", assertsOutcome == reaped, and asserts the labelled--rmcontainer left nothing behind. It skips cleanly unlessdocker info --format '{{.OSType}}'reportswindows(requireWindowsContainers), sogo test ./...stays portable everywhere else.dockerfiles/windows.Dockerfile(bakes the reporter, watchdog, entry scriptrun-and-die.cmd, and leak-probe).Acceptance criteria
go test ./internal/dispatch -run TestE2E_Windows_WatchdogReapsViaTaskkill -vruns (does not skip) and passes.node.exeprocesses survive (the test asserts the--rmcontainer is gone; spot-checktasklist/Get-Process nodefor belt-and-suspenders).taskkill /Tpath (or the teardown backstop) until it is green; update ADR-0021 Decision 4 / the Implementation-status section accordingly.Notes
docs/adr/0021-run-and-die-execution-and-two-tier-reaping.md— Decision 4 and the "Still deferred" section.