85e423482a
The salvaged fix only ran the CLI in its own session on POSIX and kept plain subprocess.run on Windows — the one platform where the wedge in #106244 is actually reproducible: CPython's run() retries an unbounded communicate() after kill() there, so a grandchild holding the capture pipes blocks the worker forever. On POSIX run() wait()s the PID and returns promptly; the grandchild merely leaks (live-reproduced on Linux). One code path for both platforms: - _group_popen_kwargs: start_new_session=True on POSIX, CREATE_NEW_PROCESS_GROUP + hide flags on Windows (replaces the hide-only _windows_popen_kwargs). - _kill_cli_process_group: os.killpg SIGKILL on POSIX, taskkill /T /F on Windows (same kwarg set as the sibling taskkill sites). - The Popen decodes with encoding="utf-8", errors="replace" like every other subprocess call in this file (windows footgun rule). - Drain test patches the kill helper instead of os.killpg so it runs on every host. Windows behaviour is not live-verifiable on this Linux host.