Skip to content

LaunchAgents & LaunchDaemons

Sanctum manages a set of macOS LaunchAgents (user-level) and LaunchDaemons (root-level) that form the boot chain for the home intelligence platform. Each plist is rendered from templates at ~/.sanctum/templates/launchagents/ by the generate-plists.sh script, which pulls values from instance.yaml and tokens from the macOS Keychain.

LaunchAgents are loaded at user login. The ordering below reflects the logical dependency chain — launchd does not guarantee ordering, but RunAtLoad: true ensures all agents start promptly after login.

PropertyValue
Labelcom.user.utm-autostart
PurposeLaunch UTM, start the VM, and set the bridge100 IP to the configured mac_bridge_ip
Required Servicevm
KeepAliveNo
RunAtLoadYes

Runs a startup script that launches UTM.app, waits for the VM to boot, and configures the bridge interface IP via sudo ifconfig. Requires the vmnet-bridge sudoers entry at /etc/sudoers.d/vmnet-bridge.


PropertyValue
Labelai.openclaw.gateway
PurposeOpenClaw/DenchClaw agent gateway on the Mac side
Required Servicegateway
KeepAliveNo
RunAtLoadYes
Port18789

The Mac-side agent gateway. Uses /opt/homebrew/bin/node (stable Homebrew symlink, not a versioned Cellar path) to avoid breakage on Node.js upgrades.


PropertyValue
Labelcom.openclaw.firewalla-bridge
PurposeBridge between the Sanctum stack and the Firewalla Purple router via the P2P API
Required Servicefirewalla
KeepAliveYes
RunAtLoadYes
Port18094
Bind0.0.0.0 (accessible from VM)

Runs firewalla-bridge.js which authenticates to Firewalla’s cloud endpoint and then communicates locally over port 8833. The bridge binds to all interfaces so the VM can reach it at 10.10.10.1:18094.


PropertyValue
Labelcom.yoda.xtts-server
PurposeXTTS-v2 text-to-speech server using Mac GPU (MPS)
Required Servicextts
KeepAliveNo
RunAtLoadYes

Provides TTS capability for the voice agent. Runs on the Mac to leverage Metal Performance Shaders for faster inference compared to the legacy CPU-based VM server.


PropertyValue
Labelcom.yoda.voice-agent
PurposeYoda voice interaction agent
Required Servicevoice_agent
KeepAliveNo
RunAtLoadYes

Manages voice capture, wake-word detection, and Yoda personality interactions.


PropertyValue
Labelcom.user.ha-ssh-tunnel
PurposeSSH tunnel from the HA Docker container to the VM’s Network Control API on port 18092
Required Servicehome_assistant
KeepAliveNo
RunAtLoadYes

Allows the Home Assistant container (running in Docker bridge networking) to reach the VM’s Network Control API via host.docker.internal.


PropertyValue
Labelcom.sanctum.council-mlx
PurposeCouncil-27B MLX model server for local agent inference
Required Servicemlx_server
KeepAliveYes
RunAtLoadYes
Port8899

Serves the Qwen3.5-27B-4bit model with a LoRA adapter supporting 6 agent personalities. KeepAlive ensures the model stays loaded in memory.


PropertyValue
Labelcom.cloudflare.tunnel
PurposeCloudflare Zero Trust tunnel for external access
Required Servicecloudflare
KeepAliveYes
RunAtLoadYes

Runs the cloudflared tunnel daemon for the configured tunnel name (e.g., manoir-nepveu). Routes external traffic to internal services like Home Assistant and the health ingester.


PropertyValue
Labelcom.user.health-ssh-tunnel
PurposeSSH tunnel for the health ingester to reach the VM on port 18095
Required Servicehealth_center
KeepAliveYes
RunAtLoadYes

PropertyValue
Labelcom.manoir.icloud-filer
PurposeAutomatic filing daemon for iCloud Drive documents
Required Serviceicloud_filer
KeepAliveYes
RunAtLoadYes

Watches iCloud Drive directories and automatically files documents into organized folder structures.


PropertyValue
Labelcom.sanctum.litellm-proxy
PurposeLiteLLM fallback proxy for LLM API routing
Required Servicelitellm
KeepAliveYes
RunAtLoadYes
Ports4000 (proxy), 4001 (admin)

Provides automatic fallback routing from primary LLM providers to OpenRouter alternatives when billing errors or rate limits occur.


PropertyValue
Labelcom.sanctum.orbi-bridge
Purposesocat bridge allowing the VM to reach the Orbi router
Required Servicevm
KeepAliveYes
RunAtLoadYes
Ports18080 (HTTP), 18085 (API)

Forwards VM traffic from 10.10.10.1:18080 to the Orbi router at 192.168.1.2:80 and 10.10.10.1:18085 to 192.168.1.2:5000. Required because the VM has no direct LAN access.


PropertyValue
Labelcom.sanctum.signal-bridge
PurposeSignal messaging bridge for agent communication
Required Servicesignal_bridge
KeepAliveYes
RunAtLoadYes

PropertyValue
Labelcom.sanctum.watchdog
PurposeHealth monitoring watchdog that runs every 600 seconds
Required Servicewatchdog
KeepAliveNo
RunAtLoadYes
StartInterval600

Periodically checks the health of all enabled services and auto-heals failures via service-doctor. Not KeepAlive — uses launchd’s StartInterval for periodic execution.


PropertyValue
Labelcom.sanctum.rotate-secrets
PurposeMonthly secret rotation (gateway tokens, API keys)
Required Service
KeepAliveNo
RunAtLoadNo
StartCalendarInterval1st of each month at 03:30

Runs on a calendar schedule, not at boot. Rotates secrets stored in 1Password and the macOS Keychain.


PropertyValue
Labelcom.manoir.command-center
PurposeCommand center dashboard web server
Required Servicedashboard
KeepAliveNo
RunAtLoadYes
Port3001

PropertyValue
Labelcom.manoir.kiwix-serve
PurposeKiwix offline library server (Wikipedia, etc.)
Required Servicekiwix
KeepAliveYes
RunAtLoadYes
Port8888
ThrottleInterval30

Requires an external T9 drive to be mounted. KeepAlive with ThrottleInterval prevents rapid restart loops if the drive is disconnected.


LaunchDaemons run as root and load at system boot (before user login).

PropertyValue
Labelcom.manoir.dench-proxy
PurposeReverse proxy from port 80 to port 19001 for the Holocron chat interface
Required Servicegateway
KeepAliveYes
RunAtLoadYes
Runs asroot

This is a LaunchDaemon (not a LaunchAgent) because binding to port 80 requires root privileges. It enables http://holocron/ access from the LAN without specifying a port.

Plist location: /Library/LaunchDaemons/com.manoir.dench-proxy.plist


All plists are rendered from Mustache-style templates using values from instance.yaml and tokens from the macOS Keychain:

Terminal window
# Preview what would be generated (dry run)
~/.sanctum/generate-plists.sh --dry-run
# Generate and install all plists for enabled services
~/.sanctum/generate-plists.sh

The generator:

  1. Reads each template from ~/.sanctum/templates/launchagents/
  2. Checks if the corresponding service is enabled in instance.yaml
  3. Expands {{PLACEHOLDER}} tokens with config values
  4. Pulls secrets from the macOS Keychain using the configured keychain_account
  5. Writes the rendered plist to ~/Library/LaunchAgents/ (or /Library/LaunchDaemons/ for daemons)

Load or unload agents using launchctl:

Terminal window
# Load an agent
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.sanctum.watchdog.plist
# Unload an agent
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.sanctum.watchdog.plist
# Check if an agent is running
launchctl print gui/$(id -u)/com.sanctum.watchdog