Hub
The full-stack primary node. Runs the Mac Mini host with the Ubuntu VM, all AI agents, Home Assistant, inference servers, and the complete service catalog. There is exactly one hub per Sanctum instance.
Sanctum is designed to run across multiple physical locations. A primary hub at your main home coordinates with satellite nodes at secondary properties, mobile nodes on laptops, and (in the future) sensor nodes for lightweight IoT devices. All nodes share a single instance.yaml configuration and communicate over Tailscale.
Hub
The full-stack primary node. Runs the Mac Mini host with the Ubuntu VM, all AI agents, Home Assistant, inference servers, and the complete service catalog. There is exactly one hub per Sanctum instance.
Satellite
A lighter deployment at a secondary home. Runs a subset of services (typically a gateway, Home Assistant, and a small local model). Syncs configuration and state with the hub over Tailscale.
Mobile
A MacBook Pro or similar portable device. Connects to the hub remotely via Tailscale for agent access, SSH, and API calls. Does not run persistent services.
Sensor
A future node type for dedicated IoT or monitoring hardware. Planned for low-power devices that report data to the hub without running the full Sanctum stack.
Each node knows who it is through a single-line file at ~/.sanctum/.node_id:
# On the hub:cat ~/.sanctum/.node_id# manoir
# On the satellite:cat ~/.sanctum/.node_id# chaletThe identity string must match a key in the nodes section of instance.yaml. Scripts and services use this to determine which configuration block applies to the current machine.
source ~/.sanctum/lib/config.sh
NODE=$(sanctum_whoami) # "manoir"TYPE=$(sanctum_node_get "$NODE" type) # "hub"IP=$(sanctum_node_get "$NODE" tailscale_ip) # "100.112.178.25"Every node is declared under the nodes key with its network addresses, SSH user, node type, and the list of services it runs:
nodes: manoir: type: hub host: 192.168.1.10 tailscale_ip: 100.112.178.25 ssh_user: bert services: - gateway - home_assistant - dashboard - voice_agent - lm_studio - council_mlx - firewalla_bridge - cloudflare_tunnel - watchdog
chalet: type: satellite host: null # Set during on-site install tailscale_ip: 100.112.203.32 ssh_user: bert services: - gateway - home_assistant
macbook: type: mobile host: null # DHCP, varies by network tailscale_ip: 100.120.85.55 ssh_user: bert services: [] # No persistent services| Field | Required | Description |
|---|---|---|
type | Yes | One of hub, satellite, mobile, sensor |
host | No | LAN IP address. null if not on the home network or DHCP. |
tailscale_ip | Yes | Stable Tailscale IP for cross-network access |
ssh_user | Yes | Username for SSH connections to this node |
services | Yes | List of service keys from services.* that this node runs |
The hub is the authoritative node. It runs every service, hosts the VM with the agent cluster, and is the source that satellites sync from.
instance.yamlThese services only run on the hub and are not deployed to satellites:
| Service | Reason |
|---|---|
| Council-27B MLX | Requires Apple Silicon with sufficient memory |
| LM Studio | Large model inference, hub-only hardware |
| Firewalla Bridge | Direct LAN access to the primary router |
| Cloudflare Tunnel | Single ingress point for the instance |
| Orbi Bridge | Direct LAN access to the access point |
| Voice Agent | Tied to local Sonos speakers and XTTS |
A satellite is a smaller deployment at a secondary location. It runs a gateway with a lightweight local model and its own Home Assistant instance for location-specific devices.
.node_id file to the satellite’s name (e.g., chalet).host field in instance.yaml on the hub.Satellites pull updates from the hub over Tailscale:
Hub (manoir) Satellite (chalet) | | +-- instance.yaml ---- Tailscale ----> instance.yaml (subset) +-- skills repo ---- Tailscale ----> skills repo (rsync) +-- agent config ---- Tailscale ----> agent configMobile nodes are laptops that connect to the Sanctum instance remotely. They do not run persistent services but can SSH into the hub, query agents, and access dashboards over Tailscale.
| Action | Command / URL |
|---|---|
| SSH to hub | ssh bert@100.112.178.25 |
| SSH to VM | ssh -J bert@100.112.178.25 ubuntu@10.10.10.10 |
| Dashboard | http://100.112.178.25:3001 |
| Home Assistant | https://ha.nepveu.name (via Cloudflare) |
| Agent query | Via gateway API at 100.112.178.25:18789 |
Both the shell and TypeScript libraries provide functions for working with the node topology:
source ~/.sanctum/lib/config.sh
# Who am I?sanctum_whoami # "manoir"
# Get a field from any nodesanctum_node_get chalet tailscale_ip # "100.112.203.32"sanctum_node_get macbook ssh_user # "bert"import { whoami, nodeGet, getNodesByType } from './lib/config';
const me = whoami(); // "manoir"const satellites = getNodesByType('satellite'); // ["chalet"]const chaletIp = nodeGet('chalet', 'tailscale_ip'); // "100.112.203.32" Tailscale Mesh (tail7c6d11.ts.net) _______________________________________________ / | \ Hub: manoir Satellite: chalet Mobile: macbook 100.112.178.25 100.112.203.32 100.120.85.55 | | | [Mac Mini M4 Pro] [Mac Mini M1] [MacBook Pro M4 Max] +-- Ubuntu VM +-- Gateway (no services) +-- 5 AI Agents +-- Home Assistant +-- Full service catalog +-- Local LLM (3B) +-- Home Assistant +-- Inference servers