# Conformance stage descendant cleanup

The conformance runner now stops a POSIX stage's process group on timeout,
cancellation and normal completion. Previously a timeout killed only the direct
child; build/test grandchildren could continue consuming CPUs after the stage
was reported failed. This is a harness correction, not an engine latency change.

## Reproduction and correction

The baseline is `599f9667b`, with new tests but unchanged runner code. Thirteen
tests reported six failures. Real three-process fixtures demonstrated surviving
children after timeout, interruption, and successful parent exit. Every fixture
has individual PID files and test cleanup; reproduction killed only its own
processes. The separate conformance sweep was neither changed nor stopped.

Each POSIX command now starts in an owned process group. Cleanup sends TERM,
allows up to 0.5 seconds for cooperative termination, then sends KILL to that
same group even if its leader exited or its captured pipes closed. Closing the
capture pipes and a bounded parent wait prevent cleanup from waiting indefinitely
on a detached pipe holder. Temporary signal handlers clean the owned group before
exiting with the signal's conventional status, and restore prior handlers. A
signal received inside process startup waits for the owned PID before unwinding;
repeated signals during cleanup do not bypass it.

The runner registers `conformance-process-cleanup-self-test`. Tests cover stubborn
grandchildren, a parent which exits while descendants retain capture pipes,
background children with closed pipes, cooperative TERM cleanup, INT/TERM/HUP/QUIT,
repeated cancellation, interruption during startup, handler restoration, unrelated
process-group survival, and the outer CPU-slot deadline. Existing success, failure,
explicit-skip, environment, prerequisite and start-error report contracts remain
tested.

## Verification

On hp, wrapped in isolated functional-test leases while the other session's
shared sweep continued:

- The final runner/report/manifest/reference pass: 198 tests, no failures or skips.
- The cleanup and CPU-slot pass: 37 tests, no failures, one expected skip. The
  skipped CPU-slot case requires a host without isolated CPUs; hp has them.
- The CPU-slot regression returned 124 for its own two-second deadline and left
  no running fixture descendants. Its lease state was separate from live jobs.

Raw baseline, fixed and final logs, the baseline runner, and gate report are under
`~/archive/libhft/conformance-process-cleanup-20261003/`. These runs do not claim
a new all-flavour sweep or a NIC latency measurement.

## Scope

The live process tests use Linux `/proc`; they explicitly skip elsewhere.
Non-POSIX runner behavior remains direct-child cleanup. Explicitly detached
daemons are outside a stage's group. An abrupt runner crash or SIGKILL cannot
execute signal cleanup; the CPU-slot TERM-before-KILL grace path is tested.
Neither a Windows process-tree guarantee nor a crash-proof job container is
claimed by this change.
