Skip to content

feat: end the processes a crashed daemon left (macOS, hand-started Linux) - #98

Merged
httpsphl merged 1 commit into
mainfrom
feat/unix-orphans
Oct 1, 2026
Merged

httpsphl merged 1 commit into
mainfrom
feat/unix-orphans

Conversation

@httpsphl

@httpsphl httpsphl commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Closes the last gap of slice 3 (spec 14.1). On Windows, a bot's Job Object dies with the daemon. On Linux under systemd, the cgroup does. On macOS, launchd ends only the daemon's own process group, so a bot's browser, and anything claude started, outlived a crashed daemon. A daemon started by hand had the same gap on Linux.

How

  • Writing groups down: ProcessJob::track(&command) records each bot and browser group in <home>/run/groups (0600), one JSON line with the group id and the arguments. The runtime and the browser call it right after assign. On Windows it does nothing.
  • Ending what was left: platform::track_groups(<home>/run) runs at daemon start, right after the instance lock and before any bot starts. It kills (SIGKILL to the group) every recorded group whose leader still runs all of its recorded arguments (ps -ww -o command= -p), then starts the list over.
  • Why another program is never hit: the arguments carry paths and ids unique to the bot (browser profile, mcp.json, session id), so a reused pid that belongs to someone else never matches.
  • Logging: only the count of ended groups is logged.

Tests

  • Unit test: a group written down and left running is ended. An entry naming this test's own pid with arguments it never had is left alone. The list starts over.
  • Platforms: Windows (fmt, clippy, lib) and Linux (Docker: clippy, lib, supervisor and browser tests) are green. macOS runs only in CI.

Manual test (macOS)

  1. With a bot's browser open, kill -9 the daemon.
  2. launchd brings it back within about 10 s.
  3. pgrep -fl "user-data-dir=.*browsers" shows nothing left over.

… one left

On macOS launchd ends only the daemon's own process group, and a daemon
started by hand has nobody to end anything. Each bot and browser group is
written down in <home>/run/groups with its arguments; the next daemon of
the same data folder kills every group whose leader still runs all of
them, before any bot starts. Windows keeps its Job Objects and writes
nothing down.
@httpsphl
httpsphl merged commit c30eee1 into main Oct 1, 2026
4 checks passed
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