| Filename | Latest commit message | Latest commit date |
|---|---|---|
hive-subagent-daemon and hive-bash-daemon are now delegated their cgroup (Delegate=memory pids, DelegateSubgroup=daemon). At start each daemon enables memory+pids below its unit and creates runs/ (subagent) or tasks/ (bash). Each subagent run gets runs/<name>-<n>/ and each bash task tasks/<id>/, both with memory.oom.group=1, and the daemon removes the directory when the run ends. An OOM kill now takes one whole run instead of one process out of the daemon's shared cgroup, and never the daemon itself. Subagent runs get oom_score_adj +1000; bash tasks and both daemons stay at 0; the harness stays at -500. The unit-level OOMScoreAdjust=500 on the subagent daemon goes: it was both the daemon's own score and a floor no run below it could be lowered past. Bash tasks enter their cgroup from the existing pre_exec hook, writing to a cgroup.procs fd opened by the parent. hive-claude builds its Command itself and exposes neither a pre_exec hook nor the child's pid, so a subagent's claude (and an ACP agent's process) is started as the daemon's own binary with the run's cgroup in its environment; main() enters the cgroup, raises oom_score_adj and execs the real program, the trampoline swarm-review-classifier already uses. Both enter before the program executes, so nothing it forks starts outside the run's cgroup. Without a delegated `daemon` leaf (tests, a dev shell) each daemon logs one warning and runs everything in its own cgroup, as before. The shared helper is hive-agent-sock's run_cgroup module, the crate both daemons already use for what in-container plugins share. Closes #5007 |
||
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
hive-bash-mcp
Per-agent background bash-task runner: a long-running daemon
(hive-bash-daemon) plus the thin stdio MCP bridge
(hive-bash-mcp) claude spawns each turn to talk to it. This is what
backs the bash_run / bash_status tools agents use to kick off
long-lived shell commands (builds, test suites, anything that
shouldn't block a turn) and check on them later.
When to use it
Look here when changing how background bash tasks are spawned,
tracked, or surfaced. The daemon owns all subprocess lifecycle
(sh -c spawn, completion monitoring, task state files under
harness/bash-tasks/) and pushes task-completion todos onto the
harness's in-agent socket so they show up in get_loose_ends. The
bridge binary is deliberately dumb: no subprocess management, just a
unix-socket round-trip per tool call, so it cold-starts in
milliseconds every turn.
Shape
Two bins from one shared lib (src/lib.rs):
hive-bash-daemon(src/main.rs) — the long-running daemon.runner.rsis the spawn/monitor loop and pushes todos on task transitions;socket.rsserves the daemon's own unix socket for tool-call requests from the bridge.hive-bash-mcp(src/bin/mcp.rs) — the stdio MCP server claude spawns per turn. Forwards every tool call to the daemon over the socket viaprotocol.rs'sDaemonRequest/DaemonResponseand returns the result.
Supporting modules: paths.rs (daemon socket + agent-socket
resolution), stats.rs (the bash_commands favorite-tool stat
recorded into turn-stats.sqlite).