Files
esh-pfi-infrastructure/services/zellij-fleet

zellij-fleet@.service — fleet zellij session server in its own cgroup (nh3-dev)

Asked for by svos-dev on 2026-09-25 for SVOS seat_up: Prime, through Miranda, assigned a way to bring agent seats up remotely. The rule it enforces is that nothing forks the zellij server except this unit.

Why

svos.service runs with KillMode=control-group. If SVOS itself ran zellij attach -b Claude to create or resurrect the fleet session, the server and every agent pane would land in svos.service's cgroup. The next systemctl --user restart svos (a routine deploy, about 100 s of vault reads) would then SIGTERM the whole fleet. Started from this unit, the server gets a cgroup of its own (app-zellij-fleet.slice/zellij-fleet@<session>.service).

Behaviour (all measured on zellij 0.45.1, 2026-09-25, with a throwaway session)

case result
session does not exist created; server in the unit's cgroup
session EXITED (serialized) resurrected with its layout; command panes HELD (start_suspended true, no process running)
session already running (e.g. Prime's ssh-started server) attach -b is a no-op; that server stays in its own scope and stopping this unit does not touch it
systemctl --user stop zellij kill-session, then the cgroup; the session stays resurrectable (EXITED)
environment zsh -lc gives the login env (PATH plus the tokens from .zshenv/.zprofile, 23 vars). Bare systemd gives 13. The ssh server's extra vars are SSH_, TERM, XDG_ and .zshrc interactive settings, which each pane's own interactive shell sets anyway

Install

cp services/zellij-fleet/zellij-fleet@.service ~/.config/systemd/user/
install -D -m 644 services/zellij-fleet/10-onfailure-althing.conf \
  ~/.config/systemd/user/zellij-fleet@.service.d/10-onfailure-althing.conf
systemctl --user daemon-reload

Installed on nh3-dev 2026-09-25. zellij-fleet@Claude is NOT enabled. Enabling it (systemctl --user enable zellij-fleet@Claude) makes the fleet session come back at boot with every pane held, instead of when Prime first logs in over ssh. That changes boot behaviour, so it waits until seat_up ships and Prime agrees. Do not start it while a Claude server is already running outside it: the start is a no-op, and a later stop would then not mean what it says.

Contract use: seat_up checks zellij list-sessions for a RUNNING (not EXITED) session and calls systemctl --user start zellij-fleet@<session> only when there is none.