Linux relay supervision
On the session's machine, onboarding installs and enables a systemd user service for the selected connection. CI wake-ups in every mode require that machine's relay to be running; see GitHub CI wake-ups. A hosted connection runs its pinned served release; a local universe runs this machine's installed Yoke. Both reuse the same relay state, configuration, logs, and native harness inventory as macOS.
Before installing the relay, onboarding checks Python's venv and ensurepip
support during the existing Linux system-package setup. On Debian, Ubuntu and
WSL Ubuntu, it installs the matching pythonX.Y-venv package automatically,
using root, passwordless sudo, or the terminal's sudo prompt. The release
installer also checks the stable relay interpreter, including an existing
runtime whose Python version differs from the onboarding CLI. Missing package
authority or a failed installation stops setup with the package and recovery
named; no manual sudo command is required.
Browser setup uses the same OS authority to provision Chromium's sandbox on
hosts enforcing kernel.apparmor_restrict_unprivileged_userns (including
Ubuntu 23.10+). It installs and loads an AppArmor userns allowance attached
only to Yoke's current Chromium and headless-shell executable paths. Updates
replace those attachments when Playwright changes its browser paths.
Authorization and browser QA invoke this setup before launching Chromium.
When the profile is already loaded, or the process is root or has passwordless
sudo, the sign-in window and browser QA run with Chromium's sandbox enabled
and the host restriction stays enabled. When the sandbox is not available and
cannot be enabled without an interactive root password, setup finishes and
Chromium launches with its sandbox off. A missing AppArmor parser, a profile that cannot load, or a
sandboxed launch that still fails after the profile loads stops browser setup
with browser_apparmor_setup_failed and the recovery step. Retry
yoke qa browser setup after repairing the named cause; Yoke handles the
system command and password prompt itself.
Chromium setup, authorization, and browser QA share Yoke's cache at
~/.yoke/playwright-cache/yoke, regardless of XDG_CACHE_HOME or an inherited
PLAYWRIGHT_BROWSERS_PATH. Setup checks that it can create and write the cache
before running installation commands. browser_cache_not_writable names the
path to make writable by the current user; then retry yoke qa browser setup.
Failed npm or Chromium installs report labeled tails of both stdout and stderr
(up to 20 lines and 4000 characters each), so a warning cannot hide the download
error. Repair the reported network or permissions cause and retry the same command.
The unit lives under ~/.config/systemd/user/. Its filename is
com.upyoke.relay.<instance-id>.service for every connection. The instance id comes from the
canonical config path and environment. Setup shows the concrete filename;
yoke relay status reports the installed unit path.
It starts at login, restarts on failure, and stops after the last login session
logs out. Yoke does not enable linger. If linger is already enabled, installation
refuses with relay_linger_enabled; disable it for the user with
loginctl disable-linger, then retry yoke relay install.
Use yoke relay status to read the unit, login enablement, active state,
logout behavior, and relay health. yoke relay install repairs the unit using
the existing launcher and release installer; yoke relay uninstall disables
and removes it. Logs stay in the selected relay's state directory.
Recover a release fetch failure
For a relay stuck on an older installer, update the operator CLI to the server's exact release carrying the fix, then reinstall from that connection:
yoke update --version VERSION
yoke --env team relay install
yoke --env team relay status
Replace VERSION with that served release and team with your connection.
The update command uses the official installer for the configured distribution.
Check the pinned and served releases in relay status. In the dashboard
Machine relays view, confirm this machine reports the same relay version with
a fresh last-seen time after installation; a pin or CLI update alone does
not prove which build is running.
The four product wheels come from the environment's immutable release directory,
with URL-encoded release and filename segments (including %2B for +).
A fetch failure preserves the prior release and records its named cause and
recovery in relay status. Repair that cause before reinstalling; an HTTP 403
alone does not establish a permissions problem. Existing workers and pending
reports remain available across the release switch.
Shutdown and service recovery
TERM interrupts the current poll or maintenance call and closes job admission.
At startup the relay reads the loaded systemd user unit's TimeoutStopUSec
(or launchd's exit timeout on macOS). Active settlements use that allowance
from the signal, reserving ten percent, capped at one second, for interpreter
exit. If the deadline cannot be read, relay_stop_deadline_unavailable names
the diagnostic recovery and uses a conservative five-second allowance. Blocked network workers do
not hold Python open at exit. Existing server leases, native process custody,
and pending report files remain available for reconciliation on the next login.
Release repinning uses its longer settlement window. Yoke changes neither
linger nor the host's systemd timeouts or logout policy.
Service operations wait for shutdown and startup.
A relay_systemd_command_timeout means the command did
not settle within its bounded wait; the systemd job may still be running.
Inspect systemctl --user list-jobs and the unit's systemctl --user status
before retrying the relay operation.
SSH commands on the graphical desktop have a command-scoped supervisor with
an inner deadline. Successful command exit preserves intentionally persistent
product daemons, such as the browser daemon, after their starter completes.
On timeout or SSH loss, the supervisor terminates that command's descendants,
including nested process sessions and children that ignore TERM.
An unsuccessful command also settles its remaining descendants.
A timeout is reported as settled only after remote termination is verified.
If completion cannot be verified or interrupted descendants remain alive, the operation
returns linux_command_custody_unsettled with its private remote custody path.
Keep that recovery handle and inspect it before retrying; a local SSH timeout
alone does not prove that remote work stopped.
Doctor checks the current unit, whether it is enabled and active, the connected heartbeat, and authorization. Without systemd as PID 1 (including containers or WSL configured without systemd), it reports that the relay is not supervised and why. Enable systemd in WSL or use a systemd Linux host. If the user manager is unavailable, log in through a PAM session that starts it and retry. Doctor never waits for a heartbeat. After a fresh install, setup waits up to 30 seconds for the relay's first connected heartbeat before its readiness check, because starting the relay can pin a release and restart; a relay that never connects still reports the doctor failure and its repair.
The login lifetime follows systemd's user manager and the host's logout delay; closing one shell while other sessions remain does not stop the relay. systemd service documentation and loginctl documentation describe restart and linger behavior.
Release retention
After a new release verifies and becomes the active pin, the installer removes older release directories, retaining the current pin and its previous directory. A release used by a running process stays until a later install can remove it. The stable launcher holds its selected release for its lifetime, so imports stay available across pin changes. Direct release commands also prevent removal. A failed candidate install preserves the working pin and does not prune releases. If pruning fails, relay status records the cause and relay install reports recovery; repair the named cause and retry relay install to finish cleanup.