Supervisor
Apple's container runtime supervises nothing. There is no --restart flag, no policy that brings a
crashed service back, and nothing that keeps the engine itself alive. If a container dies, it stays
dead until you notice.
The Supervisor is Runbay's app-side answer. It has three parts — and one honest limitation you should understand up front.
Daemon watchdog
The watchdog polls the engine every 30 seconds with a real round-trip (a container ls --format json
call, not just a process check). On failure it attempts one automatic container system start, then
backs off on a 5s → 15s → 60s schedule so it never hammers the daemon.
Keep-alive and launch-at-login
- Start at App Launch — mark a container (context menu, or the Supervisor settings tab) and it comes up automatically when the app starts. The list self-prunes if the container is removed.
- Launch at login — the app itself can start at login via
SMAppService, so your supervised containers are there when you sit down.
Keep Running (per-container restart policy)
Opt in per container. When enabled:
- Crash detection on the 30-second poll.
- Per-container backoff of 5s → 15s → 60s, with park-after-3: after three failed restarts it stops trying and offers a Try Again button, so a hard-broken container never starves the loop.
- Health-driven restart for containers that declare a health check — three consecutive unhealthy checks trigger a stop→start. Each container's restart work runs as its own task, so one container's backoff never delays daemon monitoring or another container's recovery.
This is the --restart policy Apple's CLI doesn't have, implemented in the app.
The honest limitation (decision D017)
The app cannot restart a fully-dead engine by itself.
Runbay runs under the macOS App Sandbox. Starting the engine (container system start)
submits a launchd job via launchctl bootstrap, and launchd refuses domain-management submissions
from sandboxed processes. The daemon-reachability entitlements the app carries let it talk to an
already-running daemon; they do not let it register one. The exact same command from a
non-sandboxed shell works instantly.
So when the engine is fully down, the watchdog:
- Attempts
system startonce (auto-recovery still works in non-sandboxed dev builds). - Recognizes the sandbox failure signature (
failed to get a response from apiserver) and parks immediately inrecoveryUnavailableinstead of burning retries. - Posts a notification and shows a "Restart in Terminal" button in Settings ▸ Supervisor (which launches the command in your terminal — a path proven safe under the sandbox).
- Keeps polling, so the moment you restart the daemon manually, the state self-heals to
running.
This was verified end-to-end: engine down → one attempt → parked with "user action required" →
manual system start → next poll → "daemon healthy."
The real fix — a bundled non-sandboxed SMAppService launch-agent helper that performs the start
over XPC (launch agents don't inherit the app sandbox) — is planned. Until then, in-app engine
restart is a guided one-click Terminal action, not silent magic. We'd rather tell you that than fake
it.
See also
- Getting started — install the engine and run the first-run doctor.
- Stacks — health checks come from stack definitions; health-driven restart uses them.