Problem
os.kill(pid, 0) is used as a non-destructive process-liveness probe in three places, but on Windows os.kill(pid, sig) calls TerminateProcess for every signal except CTRL_C_EVENT / CTRL_BREAK_EVENT — signal 0 included. So on Windows these "check if the process exists" probes would attempt to terminate the target pid rather than test it.
Sites (on dev after #1000):
src/synapt/recall/registry.py:302 — os.kill(pid, 0) # Check if process exists
src/synapt/dashboard/app.py:224
src/synapt/dashboard/app.py:495
Why it wasn't caught until now
The windows-latest CI matrix only began running once the store-isolation collection fix (#1000) let the suite reach test execution on Windows. The unit suite passes, so no current test exercises these code paths on Windows — but they are latent bugs for any Windows deployment of the registry or dashboard.
Suggested fix
Route liveness through a platform-branching, non-destructive probe — exactly what src/synapt/recall/session_start.py::_pid_alive / _pid_alive_win32 already do (win32: OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION) + GetExitCodeProcess + CloseHandle; POSIX: os.kill(pid, 0)). Consider extracting that helper to a shared util and calling it from all three sites.
Separate concern, same file: dashboard/app.py:521/:528 use os.kill(pid, SIGTERM/SIGKILL) for actual termination (SIGKILL does not exist on Windows) — triage whether the dashboard is POSIX-only.
Found during #1000's windows-latest bring-up.
Premium boundary: recall is OSS (registry + dashboard are local primitives). No identity/org.
Problem
os.kill(pid, 0)is used as a non-destructive process-liveness probe in three places, but on Windowsos.kill(pid, sig)callsTerminateProcessfor every signal exceptCTRL_C_EVENT/CTRL_BREAK_EVENT— signal0included. So on Windows these "check if the process exists" probes would attempt to terminate the target pid rather than test it.Sites (on
devafter #1000):src/synapt/recall/registry.py:302—os.kill(pid, 0) # Check if process existssrc/synapt/dashboard/app.py:224src/synapt/dashboard/app.py:495Why it wasn't caught until now
The
windows-latestCI matrix only began running once the store-isolation collection fix (#1000) let the suite reach test execution on Windows. The unit suite passes, so no current test exercises these code paths on Windows — but they are latent bugs for any Windows deployment of the registry or dashboard.Suggested fix
Route liveness through a platform-branching, non-destructive probe — exactly what
src/synapt/recall/session_start.py::_pid_alive/_pid_alive_win32already do (win32:OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION)+GetExitCodeProcess+CloseHandle; POSIX:os.kill(pid, 0)). Consider extracting that helper to a shared util and calling it from all three sites.Separate concern, same file:
dashboard/app.py:521/:528useos.kill(pid, SIGTERM/SIGKILL)for actual termination (SIGKILLdoes not exist on Windows) — triage whether the dashboard is POSIX-only.Found during #1000's
windows-latestbring-up.Premium boundary: recall is OSS (registry + dashboard are local primitives). No identity/org.