core/skills/doctor/SKILL.md
Host dependency checker and hardware detector. Use when diagnosing host setup, checking dependencies, or verifying GPU detection.
npx skillsauth add overthinkos/overthink-plugins doctorInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
ov doctor checks all host dependencies grouped by feature area, probes for GPU and device hardware, and reports a summary. Use it to diagnose missing tools, verify GPU setup, or check if a host is ready for ov operations.
ov doctor # Human-readable output
ov doctor --json # Machine-readable JSON (DoctorOutput struct)
Dependencies are organized into groups. Required groups cause a non-zero exit if all checks fail.
At least one must be installed:
dockerpodmango — required to build ov from sourcegitdocker buildx — only checked if docker is availablesystemctlpodman (for quadlet)qemu-system-x86_64 (or arch-specific variant)qemu-imgvirtiofsd — checks PATH + /usr/lib/virtiofsd + /usr/libexec/virtiofsdvirshsshgocryptfsfusermount3systemd-ask-password~/.config/ov/config.yml is not 0600.> 0 plaintext entries are in config.yml (suggests ov settings migrate-secrets).Label property on each. A broken collection is one whose org.freedesktop.DBus.Properties.Get returns NoSuchObject or a DBus I/O error — the hallmark of KeePassXC FdoSecrets stubs or a corrupt keyring. Status is CheckOK when all collections respond, CheckWarning when any are broken (ov iterates past them automatically — see /ov-automation:enc). The Detail field names the broken path(s) so the user can act on them (KeePassXC → Tools → Settings → Secret Service Integration → Exposed Databases).keyring_keys shadow index in config.yml against the live Secret Service via findItemAnyCollection. For every indexed service/key entry, looks it up through the iteration-capable read path. Status is CheckOK if N/N indexed keys resolve, CheckWarning with the stale entries listed otherwise. Remediation hint: ov secrets set <service> <key> to re-store, or prune the shadow index.tailscalecloudflaredskopeoscriptOnly shown if podman is installed:
gvproxy — checks PATH + /usr/libexec/podman/gvproxy + /usr/lib/podman/gvproxyProbes GPU and device hardware, reports what flags containers will receive:
| Device | Description | Container flag |
|--------|-------------|---------------|
| NVIDIA GPU | CUDA-capable GPU | --gpus all or CDI device |
| AMD GPU | ROCm compute | --group-add keep-groups |
| /dev/dri/renderD* | GPU render node | --device /dev/dri/renderD128 |
| /dev/kfd | AMD Kernel Fusion Driver | --device /dev/kfd |
| /dev/kvm | KVM virtualization | --device /dev/kvm |
| /dev/vhost-net | vhost network acceleration | --device /dev/vhost-net |
| /dev/vhost-vsock | VM socket communication | --device /dev/vhost-vsock |
| /dev/fuse | FUSE filesystem | --device /dev/fuse |
| /dev/net/tun | TUN/TAP network device | --device /dev/net/tun |
| /dev/hwrng | Hardware RNG | --device /dev/hwrng |
AMD GPU detection also reports the GFX version (e.g., gfx 11.0.0) from KFD topology nodes and sets HSA_OVERRIDE_GFX_VERSION accordingly.
DRINODE auto-detection: ov automatically finds the first /dev/dri/renderD* device and injects it as DRINODE and DRI_NODE environment variables into ov config, ov start, and ov shell sessions. This ensures GPU render node selection is consistent across all operations without manual configuration. The detection is centralized in ov/devices.go (DetectedDevices.RenderNode); the injection is centralized in appendAutoDetectedEnv() in the same file.
Why centralized: before commit 8f6f322, DRINODE injection was scattered across 10 separate call sites across ov's source tree — one in config_image.go, one in shell.go, one in start.go, and 7 more in various layer-authored scripts. This led to drift: a fix applied to ov config wouldn't reach ov shell, and DRINODE=/dev/dri/renderD129 hardcoded in some selkies scripts masked the auto-detection entirely. The consolidation into appendAutoDetectedEnv() means /ov-core:config, /ov-core:start, and /ov-core:shell all produce the identical env set, and /ov-distros:nvidia + /ov-distros:rocm stopped shipping hardcoded render nodes in their layer.yml.
Disabling auto-detection: Pass --no-autodetect to ov config to skip all of DRINODE, DRI_NODE, and HSA_OVERRIDE_GFX_VERSION injection. Useful when you want to set these values explicitly or test a layer without host device dependence. See /ov-core:config flag table.
Human-readable output uses symbols:
[+] — installed / detected[-] — missing[!] — warning (installed but with caveats)[ ] — not present (hardware, neutral)Each check shows the binary path and version when available, or an install hint when missing. Install hints are distro-aware (suggests pacman, dnf, apt as appropriate).
ov doctor --json emits a DoctorOutput struct with:
system — detected distro infogroups — all check groups with individual resultshardware — GPU flags, device list, container flagssummary — counts of installed, missing, warnings, devices/ov-automation:udev — install udev rules for GPU device access/ov-core:config — engine.build, engine.run, secret_backend settings, --no-autodetect flag, DRINODE injection via appendAutoDetectedEnv()/ov-automation:enc — credential lookup path behind the Secret Service collection + keyring-index checks; iteration-capable ssClient; broken-collection troubleshooting/ov-build:secrets — ov secrets set/list/prune commands referenced by the keyring-index remediation hint/ov-build:settings — keyring_collection_label, secret_backend, and other runtime config keys surfaced by the Secret Storage checks/ov-core:shell — auto-detected env vars (DRINODE, DRI_NODE, HSA_OVERRIDE_GFX_VERSION) injected via the same appendAutoDetectedEnv() path/ov-core:start — same auto-injection path at service-start time/ov-distros:nvidia — NVIDIA GPU runtime support + DRINODE Auto-Injection section/ov-distros:rocm — AMD ROCm runtime support + DRINODE/HSA_OVERRIDE_GFX_VERSION auto-detect table/ov-selkies:selkies — Primary consumer of DRINODE for VAAPI H.264 encodeov/doctor.go.
Use when the user asks about:
ov doctor commandtools
Use when authoring or modifying a charly PLUGIN — a candy with a `plugin:` block that contributes Providers (verbs/kinds/deploy-targets/steps/builders/commands), its own CUE schema, builtin (compiled-in) or external (out-of-tree git repo). Covers the unified Provider model, the per-plugin CUE-schema contract (single source → Go params for dev + schema-over-Describe RPC for runtime), the SDK, and the loader.
tools
The CUE data-validation / configuration CLI (cue), pinned to v0.16.1. Use when working with the cue candy, installing the cue binary into a box or onto a target:local dev host, or running the offline schema-vendoring pipeline that feeds charly's egress validation.
tools
CUE EGRESS validation — validating (and, where it adds value, generating) the config files charly WRITES to a system BEFORE the bytes hit disk. MUST be invoked before working on charly/egress.go, the vendored schemas under candy/plugin-egress/egress-schemas/vendor/, the ValidateEgress / registerVendoredEgressKind path, the offline `task cue:vendor` pipeline, or adding an egress schema for any written artifact (cloud-init, k8s manifests, traefik routes, runtime config, install ledger, systemd/quadlet units, ssh_config, libvirt XML).
tools
Kubernetes cluster-probe declarative check verb — the `kube:` check verb (nodes, pods, ingress, storage class, addon health, apply/delete, and arbitrary resource GETs) served out-of-process by the candy/plugin-kube plugin (vendored client-go; no external kubectl required).