|
| 1 | +# s6-rc Service Topology |
| 2 | + |
| 3 | +34 services managed by s6-rc. Dependencies resolved in parallel with readiness gating. |
| 4 | + |
| 5 | +## Dependency Graph |
| 6 | + |
| 7 | +```mermaid |
| 8 | +graph TD |
| 9 | + classDef oneshot fill:#dae8fc,stroke:#6c8ebf,color:#333 |
| 10 | + classDef longrun fill:#d5e8d4,stroke:#82b366,color:#333,font-weight:bold |
| 11 | + classDef readiness fill:#d5e8d4,stroke:#82b366,color:#333,font-weight:bold,stroke-width:3px |
| 12 | + classDef bundle fill:#e1d5e7,stroke:#9673a6,color:#333 |
| 13 | +
|
| 14 | + user["user (bundle)"]:::bundle |
| 15 | + base_init["base-init"]:::oneshot |
| 16 | +
|
| 17 | + env_setup["env-setup"]:::oneshot |
| 18 | + secrets["secrets"]:::oneshot |
| 19 | + postgres_init["postgres-init"]:::oneshot |
| 20 | + system_fixups["system-fixups"]:::oneshot |
| 21 | + pulseaudio["pulseaudio"]:::longrun |
| 22 | + tor["tor"]:::oneshot |
| 23 | + wireguard["wireguard"]:::oneshot |
| 24 | +
|
| 25 | + shell_rc["shell-rc"]:::oneshot |
| 26 | + postgres["postgres"]:::longrun |
| 27 | + gcroot["gcroot"]:::oneshot |
| 28 | + nix_daemon["nix-daemon ★"]:::readiness |
| 29 | +
|
| 30 | + homedir["homedir"]:::oneshot |
| 31 | + gui_config["gui-config"]:::oneshot |
| 32 | + claude_config["claude-config"]:::oneshot |
| 33 | + codex_config["codex-config"]:::oneshot |
| 34 | + opencode_config["opencode-config"]:::oneshot |
| 35 | + gemini_config["gemini-config"]:::oneshot |
| 36 | + antigravity["antigravity"]:::oneshot |
| 37 | + mise["mise"]:::oneshot |
| 38 | + project_flake["project-flake"]:::oneshot |
| 39 | +
|
| 40 | + chromium_cleanup["chromium-cleanup"]:::oneshot |
| 41 | + mcp_toggle["mcp-toggle"]:::oneshot |
| 42 | + mise_packages["mise-packages"]:::oneshot |
| 43 | + nix_packages["nix-packages"]:::oneshot |
| 44 | +
|
| 45 | + xvfb["xvfb ★"]:::readiness |
| 46 | + dbus_session["dbus-session"]:::longrun |
| 47 | + snixembed["snixembed"]:::longrun |
| 48 | + window_manager["window-manager ★"]:::readiness |
| 49 | + wallpaper["wallpaper"]:::oneshot |
| 50 | + x11vnc["x11vnc"]:::longrun |
| 51 | + xrdp["xrdp"]:::longrun |
| 52 | + xrdp_chansrv["xrdp-chansrv"]:::longrun |
| 53 | +
|
| 54 | + user --> base_init |
| 55 | +
|
| 56 | + base_init --> env_setup |
| 57 | + base_init --> secrets |
| 58 | + base_init --> postgres_init |
| 59 | + base_init --> system_fixups |
| 60 | + base_init --> pulseaudio |
| 61 | + base_init --> tor |
| 62 | + base_init --> wireguard |
| 63 | + base_init --> dbus_session |
| 64 | +
|
| 65 | + env_setup --> shell_rc |
| 66 | + system_fixups --> gcroot |
| 67 | + system_fixups --> nix_daemon |
| 68 | + postgres_init --> postgres |
| 69 | +
|
| 70 | + shell_rc --> homedir |
| 71 | + shell_rc --> gui_config |
| 72 | + shell_rc --> claude_config |
| 73 | + shell_rc --> codex_config |
| 74 | + shell_rc --> opencode_config |
| 75 | + shell_rc --> gemini_config |
| 76 | + shell_rc --> antigravity |
| 77 | + shell_rc --> mise |
| 78 | + nix_daemon --> project_flake |
| 79 | +
|
| 80 | + homedir --> chromium_cleanup |
| 81 | + gui_config --> xvfb |
| 82 | + claude_config --> mcp_toggle |
| 83 | + codex_config --> mcp_toggle |
| 84 | + opencode_config --> mcp_toggle |
| 85 | + mise --> mise_packages |
| 86 | + project_flake --> nix_packages |
| 87 | +
|
| 88 | + xvfb --> dbus_session |
| 89 | + xvfb --> window_manager |
| 90 | + xvfb --> x11vnc |
| 91 | + xvfb --> xrdp |
| 92 | +
|
| 93 | + xrdp --> xrdp_chansrv |
| 94 | + dbus_session --> snixembed |
| 95 | + window_manager --> wallpaper |
| 96 | +
|
| 97 | + subgraph gui ["GUI Stack (DEVCELL_GUI_ENABLED=true)"] |
| 98 | + xvfb |
| 99 | + dbus_session |
| 100 | + snixembed |
| 101 | + window_manager |
| 102 | + wallpaper |
| 103 | + x11vnc |
| 104 | + xrdp |
| 105 | + xrdp_chansrv |
| 106 | + end |
| 107 | +
|
| 108 | + style gui fill:none,stroke:#82b366,stroke-dasharray:8 8,color:#333 |
| 109 | +``` |
| 110 | + |
| 111 | +> Blue = oneshot, green = longrun, purple = bundle, **★** = notification-fd=3 (readiness-gated). |
| 112 | +
|
| 113 | +## Services |
| 114 | + |
| 115 | +| Service | Type | Platform | Readiness | Notes | |
| 116 | +|---------|------|----------|-----------|-------| |
| 117 | +| **base-init** | oneshot | all | | `linux/up`, `darwin/up` variants | |
| 118 | +| **env-setup** | oneshot | Linux, WinKit | | writes `/etc/s6/env/` | |
| 119 | +| **secrets** | oneshot | all | | | |
| 120 | +| **postgres-init** | oneshot | all | | | |
| 121 | +| **system-fixups** | oneshot | all | | `linux/up`, `darwin/up` variants | |
| 122 | +| **pulseaudio** | longrun | Linux, WinKit | | | |
| 123 | +| **tor** | oneshot | all | | | |
| 124 | +| **wireguard** | oneshot | all | | | |
| 125 | +| **shell-rc** | oneshot | all | | | |
| 126 | +| **postgres** | longrun | all | | | |
| 127 | +| **gcroot** | oneshot | all | | | |
| 128 | +| **nix-daemon** | longrun | all | notification-fd=3 | | |
| 129 | +| **homedir** | oneshot | all | | | |
| 130 | +| **gui-config** | oneshot | all | | | |
| 131 | +| **claude-config** | oneshot | all | | | |
| 132 | +| **codex-config** | oneshot | all | | | |
| 133 | +| **opencode-config** | oneshot | all | | | |
| 134 | +| **gemini-config** | oneshot | all | | | |
| 135 | +| **antigravity** | oneshot | all | | | |
| 136 | +| **mise** | oneshot | all | | | |
| 137 | +| **project-flake** | oneshot | all | | | |
| 138 | +| **chromium-cleanup** | oneshot | all | | | |
| 139 | +| **mcp-toggle** | oneshot | all | | | |
| 140 | +| **mise-packages** | oneshot | all | | | |
| 141 | +| **nix-packages** | oneshot | all | | | |
| 142 | +| **xvfb** | longrun | Linux, WinKit | notification-fd=3 | `:99` | |
| 143 | +| **dbus-session** | longrun | Linux, WinKit | | writes `DBUS_SESSION_BUS_ADDRESS` to envdir | |
| 144 | +| **window-manager** | longrun | Linux, WinKit | notification-fd=3 | check: `xdotool search --class` | |
| 145 | +| **snixembed** | longrun | Linux, WinKit | | reads envdir for `DBUS_SESSION_BUS_ADDRESS` | |
| 146 | +| **x11vnc** | longrun | Linux, WinKit | | `:5900` | |
| 147 | +| **xrdp** | longrun | Linux, WinKit | | `:3389` | |
| 148 | +| **xrdp-chansrv** | longrun | Linux, WinKit | | | |
| 149 | +| **wallpaper** | oneshot | Linux, WinKit | | | |
| 150 | +| **user** | bundle | all | | `contents.d/` lists all services | |
| 151 | + |
| 152 | +## How It Works |
| 153 | + |
| 154 | +- **Build time**: `s6-rc-compile` (via `s6-linux-renderer.nix`) compiles source definitions from `modules/s6/` into `/etc/s6-rc/compiled/`. |
| 155 | +- **Boot time**: entrypoint starts `s6-svscan`, runs `s6-rc-init` to link the compiled DB, then `s6-rc -u change user` brings up all services in parallel dependency order. |
| 156 | +- **Privilege model**: s6-svscan runs as root. Services drop to session user via `gosu` in their run scripts. `chmod 0711` on supervise directories lets the session user query status with `s6-svstat`. |
| 157 | +- **Envdir** (`/etc/s6/env/`): oneshots write env vars (e.g. `DBUS_SESSION_BUS_ADDRESS`), longruns read them via `s6-envdir`. |
| 158 | +- **Dependencies**: declared via `dependencies.d/` directories containing empty files named after deps. |
| 159 | + |
| 160 | +## Known Issues |
| 161 | + |
| 162 | +1. **Compiled DB missing log pipelines** (MEDIUM): per-service s6-log definitions exist in source but aren't in the compiled output. Service stdout goes to the svscan catchall log. |
| 163 | +2. **Oneshot up scripts use shell** (LOW): s6-rc-compile expects execline. The community-home compiler wraps them, but pure s6-rc-compile would reject. |
| 164 | +3. **xrdp.log root-only** (LOW): session user can't read connection logs. Fixed by #1. |
0 commit comments