# The tmux execution runtime, owned separately from the worker. # # The worker used to spawn this server implicitly on its first tmux command, # which put the server and every agent pane inside the worker unit's cgroup. # Restarting the worker then destroyed the sessions it was restarting to # manage: a deploy killed the run it was deploying for, and F16's missing-pane # branch fired on deployment rather than on real execution-runtime loss. # # KillMode does not fix that. Under `mixed` systemd still sends the final # SIGKILL to whatever remains in the cgroup, and `process` only encodes # accidental orphaning. The runtime has to be a service of its own. # # Lifecycle this gives you: # systemctl restart orchestra-worker -> panes survive, worker reconciles # systemctl stop orchestra-tmux -> panes die, deliberately # # User MUST match orchestra-worker.service. The socket lives under # /tmp/tmux-$UID, so a mismatch leaves the worker talking to a different # server, or to none. [Unit] Description=Orchestra tmux execution runtime After=network.target [Service] Type=forking User=orchestra # The socket name is the worker's tmux_socket for this harness (-L, not -S). # Keep the two in step; the worker does not create the server any more. # # The idle session exists so the server outlives its last agent pane. Without # it the runtime exits whenever a task completes, and the next launch spawns a # fresh server back inside whichever cgroup asked for it. ExecStart=/usr/bin/tmux -L orchestra new-session -d -s orchestra-runtime ExecStop=/usr/bin/tmux -L orchestra kill-server # The runtime coming back empty is honest: the panes are gone either way, and # F16 observes that as real execution loss. Refusing to restart would instead # block every later launch until an operator noticed. Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target