# fleet — one-shot homelab health snapshot Replaces the hand-rolled `ssh pi5-claude sudo claude-docker ps …` loops from every runbook with a single command that checks **all hosts**: container states, disk fill and failed systemd units. Read-only by construction — it only runs `ps`/`df`/`systemctl` through the read-only claude-docker wrapper, so it needs no new permissions. From [`doc/tool-parity.md`](../doc/tool-parity.md) §4.2. ## Usage ``` fleet status [--host NAME] # all hosts, or one ``` ``` == pi5 == containers: 54/58 healthy disk / 81% used, 82G free disk /srv/storage1 58% used, 1.2T free failed units: 0 system, 0 user ... 19 finding(s): pi5: container dozzle: exited (Exited (0) 5 months ago) brasse-linux01: failed unit: cpupower-gui.service ``` | Exit | Meaning | |------|---------| | 0 | everything healthy | | 2 | findings printed (unhealthy/exited containers, disk ≥ warn %, failed units) | | 1 | error (unknown host, config problem) | Output is a stable text table — an agent can diff it between runs. Unreachable hosts become findings, not crashes. Gitea Actions' transient job containers are skipped. ## Config `~/.config/fleet/config.json`, created on first run (`FLEET_CONFIG` overrides): ```json { "disk_warn_pct": 85, "hosts": [ {"name": "pi5", "ssh": "pi5-claude", "docker_cmd": "sudo claude-docker", "df_targets": "/ /srv/storage1", "user_units": false}, {"name": "brasse-linux01", "ssh": "", "docker_cmd": "docker", "df_targets": "/ /home", "user_units": true} ] } ``` `ssh: ""` means run locally. Add hosts by appending entries. ## Build & test ```bash go test ./... go build -o build/fleet . ```