`colibri doctor` — self-diagnosis & self-upgrade
← index
Status: Shipped (v0.12.0+). 10 checks, two auto-fixable targets, client-side
colibri upgrade. Cross-platform (Linux + FreeBSD, one #[cfg] for service restart).
What it is
Razdelek z naslovom „What it is”status is a passive snapshot (counts). doctor is a battery of active
checks — each verifies one thing that has to be true for the control plane to
work, and reports PASS/WARN/FAIL. It’s the task-dispatch-flow
“why won’t my task run?” checklist, executable. Scope is concrete — check
only what we actually have, never claim a check we can’t back with a data source.
Check result shape
Razdelek z naslovom „Check result shape”struct CheckResult { check: String, // e.g. "database", "registration_linkage" status: String, // "pass" | "warn" | "fail" detail: String, // human-readable one-liner hint: Option<String>, // optional operator-facing tip (→ displayed) fixable: bool, // can `colibri doctor --fix` act on it?}hint is always displayed as a → tip in table output. fixable is the hinge
between diagnosis and action: only fixable: true checks are acted on by
--fix. Today two checks are fixable: binary_vs_git_version → colibri upgrade,
registration_linkage → colibri agents prune.
Check catalog — all shipped
Razdelek z naslovom „Check catalog — all shipped”| Check | What it verifies | fixable |
|---|---|---|
| database | Store opens and queries cleanly | no |
| providers | At least one cloud provider key set | no |
| agents | At least one live agent handle | no |
| dispatch_readiness | Agents are in RPC mode (can receive tasks) | no |
| registration_linkage | Store agents map to live handles (stale if not) | yes → colibri agents prune |
| model_selection | Phase 3 model selection enabled/disabled | no |
| local_eval | ollama available for local-llm eval | no |
| disk_free | df -k on data_dir — <100MiB FAIL, <1GiB WARN | no |
| binary_vs_git_version | Binary version matches git tag at build time | yes → colibri upgrade |
| doas_nopasswd (FreeBSD) / sudo_nopasswd (Linux) | Passwordless escalation configured for daemon control | no |
| git_behind | Client-side: commits behind origin/main | no (shown by client, not daemon) |
The daemon emits 10 checks. git_behind is client-side only — the client runs
git rev-list --count HEAD..origin/main after fetching. The escalation check
(doas_nopasswd on FreeBSD, sudo_nopasswd on Linux) was added after
real-world testing showed colibri upgrade failing mid-flight when the
escalation tool required a password.
Explicitly out of scope (no data source)
Razdelek z naslovom „Explicitly out of scope (no data source)”- DNS resolution — daemon has no DNS config; would need a
/etc/resolv.conforhostprobe. - TLS/ACME cert expiry — no cert knowledge in the daemon; an nginx concern.
- PostgreSQL health — not in the colibri installer scope.
- Mother reachable —
ssh colibri@motherrequires key setup that isn’t guaranteed on every node.
The doctor never prints a check it can’t back. Adding one of these means adding its data source first.
colibri upgrade — client-side self-rebuild
Razdelek z naslovom „colibri upgrade — client-side self-rebuild”The upgrade flow is entirely client-side. The daemon never touches its own binary.
colibri upgrade --check # just the git-behind count, no buildcolibri upgrade --yes # git pull → cargo build --release → stop → install → startcolibri upgrade # interactive (prompts before build)Platform restart: service colibri_daemon restart (FreeBSD rc.d) vs
systemctl restart colibri-daemon (Linux) — one #[cfg] block.
Binary install uses install(1) (not cp) to avoid ETXTBSY (“Text file
busy”) when overwriting the running client binary on FreeBSD.
Passwordless escalation requirement (doas on FreeBSD, sudo on Linux)
Razdelek z naslovom „Passwordless escalation requirement (doas on FreeBSD, sudo on Linux)”colibri upgrade needs passwordless escalation for the daemon stop/install/start
cycle. The doas_nopasswd (FreeBSD) / sudo_nopasswd (Linux) check detects this.
The check (and the upgrade pre-flight) probe the scoped service-status
command — doas -n service colibri_daemon status (FreeBSD) /
sudo -n systemctl status colibri-daemon (Linux) — not esc -n true. The
installer writes command-limited rules, so a blanket true probe would fail
even on a correctly-configured host.
Preferred provisioning — the clawdie installer writes the scoped rules for
you. Run it with the operator account that should control upgrades:
clawdie apply --operator-user YOUR_ACCOUNT --yesFreeBSD (rc.d + doas) — the installer appends permit nopass rules to
/usr/local/etc/doas.conf for the operator account:
permit nopass YOUR_ACCOUNT cmd servicepermit nopass YOUR_ACCOUNT cmd installLinux (systemd + sudo) — the installer writes a NOPASSWD drop-in for the operator account:
YOUR_ACCOUNT ALL=(root) NOPASSWD: /usr/bin/systemctl * colibri-daemonYOUR_ACCOUNT ALL=(root) NOPASSWD: /usr/bin/install *The rules are scoped by command, not blanket — doas matches by command name
(service covers any service invocation), while sudoers uses arg wildcards.
colibri doctor --fix — two auto-fixable targets
Razdelek z naslovom „colibri doctor --fix — two auto-fixable targets”colibri doctor --fixRuns all checks, then acts on fixable: true ones:
binary_vs_git_version→colibri upgrade(pull + build + restart). Forces rebuild even when git is at origin/main — the binary can be stale from a pre-tag build.registration_linkage→colibri agents prune— removes store agents that have no live daemon handle. Stale agents accumulate on every daemon restart because agent IDs are ephemeral.
After fixes, re-runs doctor to show the new state.
Command surface
Razdelek z naslovom „Command surface”colibri doctor # run all checks, print table with → hintscolibri doctor --json # machine-readable (MCP / dashboard)colibri doctor --fix # run checks + act on fixable onescolibri upgrade # interactive self-rebuildcolibri upgrade --check # git-behind count onlycolibri upgrade --yes # non-interactive self-rebuildArchitecture
Razdelek z naslovom „Architecture”| Piece | Where | Platform |
|---|---|---|
| Checks engine | crates/colibri-daemon/src/doctor.rs | cross-platform |
| Client display | colibri-client (colibri doctor) | cross-platform |
| Self-upgrade | colibri-client (colibri upgrade) | one #[cfg] block |
| Stale-agent prune | crates/colibri-daemon/src/daemon.rs | cross-platform |
The daemon gets exactly one command: Doctor → Vec<CheckResult>. The client
formats it and runs fixes. Upgrade and prune are separate — they compose through
--fix, not through a shared daemon API.
Hive composition
Razdelek z naslovom „Hive composition”Each node runs colibri doctor locally. Mother queries all nodes with
ssh <node> colibri doctor --json — the SSH keychain + MCP-over-SSH already
carry arbitrary socket commands.
See also
Razdelek z naslovom „See also”- task-dispatch-flow — the stall checklist doctor automates
- factory-model — the harness architecture doctor verifies
- hive-routing — per-node identity + capability probes
- mother-hive — the MCP-over-SSH path the hive
--jsonquery rides