--- name: new-fleet-service-checklist description: "Add a new deployable service to serverAppConfigs: the four registration touch-points (two allowlists, planner, router) whose drift breaks the first-ever deploy." --- # Adding a new service to the serverAppConfigs deployer A new `--service ` target must be registered in **four** files or the first deploy fails at a gate. Two fleet services (cadvisor, gpu-exporter) shipped with the client gate missed within a day of each other; the failure mode is `Service 'X' is not deployed on ` from `deploy.sh`, exit 2 — before SSH. ## The four touch-points (per target host) 1. `scripts/deploy.sh` → `valid_service()` case: add `:`. **Client gate** — the one people forget. 2. `scripts/deploy-remote.sh` → `service_is_allowed()` case: add `:`, **and** the dispatcher `case` branch `) deploy_ ;;`. 3. `scripts/deploy-plan.py`: the name in the target's service set (`DANKCLAW_SERVICES` / `DANKSERVER_SERVICES`) + `SERVICE_ORDER`, plus a path map so edits to the service's own files select it (for `scripts/.*` host processes, map the exact filenames like the signal-relay/gpu-exporter maps do). 4. `scripts/test-changed.sh`: route the service's files to its seam, else focused test runs skip it (full `tests/run.sh` still covers). Sanctioned exception: `dankclaw:searxng-network` is client-only (network unit, no remote handler) — the drift test exempts it. ## Enforcement + local verification `tests/deployment_flow.bats` test "the client and remote allowlists agree per target" diffs the two extracted lists. Verify before pushing: ```bash grep -oE 'dank(claw|server):[a-z0-9-]+' <(sed -n '/^valid_service()/,/^}/p' scripts/deploy.sh) \ | grep -v dankclaw:searxng-network | sort -u > /tmp/cli grep -oE 'dank(claw|server):[a-z0-9-]+' <(sed -n '/^service_is_allowed()/,/^}/p' scripts/deploy-remote.sh) \ | sort -u > /tmp/rem diff /tmp/cli /tmp/rem # must be empty ``` Also: a `# comment` after a trailing `\` inside a bash `case` pattern list **breaks line continuation** (syntax error) — annotate on its own line above. ## Gotchas - Merge ≠ deploy: `deploy.sh --service ` must still be run per host; a merged service is dead code until then (GPU stats "not showing" was exactly this). - `deploy.sh` refuses to run anywhere but a clean `main` checkout: the canonical dev checkout is `/home/blank/Projects/serverAppConfig` (not the session `~/.omp/wt/...` worktree, not the build worktree).