plugin-doctor
| Placement | compiled-in (in-process) |
| Source | github.com/opencharly/charly/candy/plugin-doctor |
| Version | 2026.181.0001 |
| Candy | plugin-doctor |
This plugin is listed in charly/charly.yml’s compiled_plugins:, so its providers are compiled into the charly binary and register in-process.
Providers
Section titled “Providers”The reserved words this plugin serves:
doctor— command class
What it does
Section titled “What it does”COMPILED-IN charly COMMAND-class plugin that OWNS the externalized charly doctor
CLI — the host-dependency-status surface. The plugin owns the command end to end: the
flag grammar (–json), the ENTIRE check list + group orchestration (container engine /
build infra / service management / VMs / VFIO / encrypted storage / secret storage /
tunnels / merge & registry / shell & TTY / podman machine), the pass/warn/fail verdicts,
the human + JSON report formatting, the exit code, AND the pure host ops it runs itself
(binary probes via exec.LookPath / exec.Command, file reads via os.Stat / os.ReadFile).
No plugin-specific report LOGIC is left in core.
The ONE thing the plugin cannot compute itself is the genuine host-HARDWARE subsystem + core-owned data: the GPU/VFIO/device detection primitives (DetectGPU / DetectAMDGPU / detectAMDGFXVersion / GPURunArgs / DetectVFIO / MemlockLimitBytes / VfioGroupAccessible / vfioPciAvailable / the devicePatterns glob), the credential-store health (credentialHealth → verb:credential, which lazy-connects host-side), and the core install-hint / distro-family / device-description tables. Those STAY core (charly/host_build_hostprobe.go) because they are the genuine host-hardware subsystem the plugin cannot hold + are MULTI-CALLER (the GPU/VFIO shims serve vm/deploy too) — so duplicating them into the plugin would violate R3. The plugin reaches them via the generic “hostprobe” HostBuild seam (spec.HostProbeRequest → spec.HostProbeReply), which runs the detection primitives host-side ONCE and returns RAW FACTS ONLY — zero formatting or verdict logic crosses into core. “hostprobe” is a class-generic action noun, not a provider word (F11). This is the same “plugin owns the report + a generic seam for the genuine host-coupled facts” doctrine the clean + settings command plugins established.
doctor is COMPILED-IN (listed in charly/charly.yml compiled_plugins) BECAUSE its Invoke(OpRun) needs the in-proc reverse channel — threaded by dispatchInProcCommand (“Seam A”) — to call HostBuild(“hostprobe”). The out-of-process CliMain path has no reverse channel, so it errors: doctor cannot run out-of-process, it needs the hostprobe host seam. There is NO hidden core-command forward — the plugin does the report directly, calling back only for the raw host-hardware facts; no core symbol crosses the boundary, no ad-hoc podman.
command:doctor dispatches through the COMPILED-IN registry path (registerCompiledPlugin →
resolve(ClassCommand,“doctor”) → dispatchInProcCommand → Invoke(OpRun) with the threaded
in-proc reverse channel), so NewMeta advertises command:doctor while the served CUE schema
carries no plugin_input (the args are plain CLI tokens). The R10 witness is the disposable
check-doctor-local bed: charly doctor exits 0 and prints the host-dependency report,
proving the externalized command + the in-proc HostBuild hostprobe dispatch end-to-end.
See also the candy reference for this candy’s install surface.