# Colibri ISO Service Layout ## Service identity | Field | Value | | ------------ | ---------------------------------------------- | | Service name | `colibri_daemon` | | Binary | `/usr/local/bin/colibri-daemon` | | User | `colibri` (unprivileged, `/usr/sbin/nologin`) | | Group | `colibri` | | Supervisor | `daemon(8)` — restart on crash, privilege drop | ## Filesystem layout ``` /usr/local/bin/colibri-daemon ← daemon binary (foreground, no self-daemonize) /usr/local/bin/colibri ← CLI client (status, create-task, etc.) /usr/local/bin/colibri-test-agent ← test agent (sample Pi JSONL) /usr/local/etc/rc.d/colibri_daemon ← rc.d service script /usr/local/etc/colibri/ rc.conf.sample ← service config template provider.env ← optional API keys (mode 0600, root-owned) /usr/local/etc/newsyslog.conf.d/ colibri.conf ← log rotation (1MB, 7 archives) /var/db/colibri/ ← persistent data (750 colibri:colibri) colibri.sqlite ← coordination store sessions/ ← JSONL session files /var/run/colibri/ ← tmpfs (recreated each boot) colibri.sock ← Unix socket (770 colibri:colibri, set by daemon) colibri-daemon.pid ← child pidfile (daemon(8) -p) colibri-daemon-supervisor.pid ← supervisor pidfile (daemon(8) -P) /var/log/colibri/ ← persistent logs daemon.log ← stdout/stderr from colibri-daemon ``` ## Boot-time behavior 1. `rc.d` starts `colibri_daemon` after LOGIN + cleanvar 2. `prestart`: creates `/var/run/colibri/`, `/var/db/colibri/`, `/var/log/colibri/` 3. `daemon(8)` forks `colibri-daemon` as user `colibri`, redirects logs 4. `poststart`: waits up to 10s for `/var/run/colibri/colibri.sock` to appear 5. Daemon binds socket, opens SQLite, starts scheduler loop 6. CLI clients connect via `colibri` binary → Unix socket ## Shutdown behavior 1. `rc.d` sends SIGTERM to daemon(8) supervisor (via custom `stop_cmd`) 2. Supervisor forwards signal to colibri-daemon child and exits (no restart) 3. Colibri closes socket, flushes SQLite, stops scheduler 4. `poststop`: removes stale socket from tmpfs ## Startup validation ```sh # Check service status service colibri_daemon status # Socket health (nc must be available) service colibri_daemon health # CLI check colibri status colibri create-task --title "iso-check" colibri list-tasks --status queued ``` ## Config knobs (set in /etc/rc.conf or /etc/rc.conf.d/colibri_daemon) | Variable | Default | Purpose | | -------------------------- | --------------------------- | ----------------------- | | `colibri_daemon_enable` | NO | Enable at boot (YES/NO) | | `colibri_daemon_user` | colibri | Runtime user | | `colibri_daemon_group` | colibri | Runtime group | | `colibri_daemon_cost_mode` | smart | fast/smart/max | | `colibri_daemon_data_dir` | /var/db/colibri | Persistent data | | `colibri_daemon_run_dir` | /var/run/colibri | tmpfs runtime | | `colibri_daemon_socket` | $run_dir/colibri.sock | Unix socket path | | `colibri_daemon_db_path` | $data_dir/colibri.sqlite | SQLite path | | `colibri_daemon_logfile` | /var/log/colibri/daemon.log | Log output | ## Log rotation `/usr/local/etc/newsyslog.conf.d/colibri.conf`: ``` /var/log/colibri/daemon.log colibri:colibri 640 7 1024 * JC ``` Rotates at 1MB, keeps 7 compressed archives, bzip2 compression. ## Secrets policy - No API keys in rc.conf or service environment files. - `DEEPSEEK_API_KEY` and other provider keys are set via a separate, mode-0600 env file sourced by the daemon (e.g. `/usr/local/etc/colibri/provider.env`). - The rc.d script does NOT read or expose secrets. - Logs go to `/var/log/colibri/` which is mode 0750 colibri:colibri — only the colibri user and root can read them.