castellan doctor
Staged runtime diagnostics: multiplexer, governance, config layers, LLM provider, plugins, evolve archive, latest episode vitals. Verified against DoctorReport::run in crates/castellan-cli/src/doctor_cmd.rs — 12 stages, always run in this order.
Usage
castellan doctor [--workspace .] [--json]
--json does not change exit behavior — doctor always exits non-zero if any stage’s pass is false. Not every stage can fail: config/preset stages (permissions_preset, plan_verify, model_tiers, mux_default) always report informational detail with pass: true. llm_provider fails when provider = "openrouter" and no API key env is set. memory_sync fails when sync is configured without a token env. Only multiplexer_socket, governance_manifest, live_session, plugin_registry, evolve_archive, and episode_vitals can fail for other reasons.
Stages
Order matches DoctorReport::run in doctor_cmd.rs:
| Stage | Can fail | Checks |
|---|---|---|
multiplexer_socket | yes | Default socket exists / accepts connections |
mux_default | no (informational) | Whether mux-by-default is on given socket health + env vars |
governance_manifest | yes | castellan drift-check violations against the verification manifest |
permissions_preset | no (informational) | Active [permissions] preset and tool-override count |
plan_verify | no (informational) | Guardians-shaped [governance.plan_verify] enabled state |
model_tiers | no (informational) | [models] tier config (default/verify/act/plan — scheduler never uses LLM) |
llm_provider | yes (openrouter without key) | Provider, base_url, key_present (never the value), optional headers, TCP reachability |
memory_sync | yes (configured, no token) | [memory.sync] Turso remote-sync health |
live_session | yes | Active live-field session snapshot / idle + instrument corpus note |
plugin_registry | yes | Registry has at least one plugin, matches plugins.toml |
evolve_archive | yes | .castellan/topology_archive.json under --workspace is readable |
episode_vitals | yes | Latest episode under .castellan/episodes has circulation_vitals or wake_stats |
Recipes
Local workspace check:
castellan doctor --workspace .
CI-friendly JSON:
castellan doctor --json | jq '.stages[] | select(.pass == false)'
Human table (default):
STAGE STATUS DETAIL
------------------------------------------------------------------------
multiplexer_socket PASS socket present at /Users/you/.config/castellan/castellan.sock
mux_default PASS mux default on (socket_healthy=true); rollback: --no-mux, ...
governance_manifest PASS verification manifest OK
...
Failure paths
| Stage failing | Detail message pattern | Fix |
|---|---|---|
multiplexer_socket | socket missing at ... (run castellan multiplexer ensure) | castellan multiplexer ensure |
governance_manifest | N drift violation(s) | castellan drift-check for the full list; fix castellan.toml |
llm_provider | provider=openrouter ... key_present=false | export OPENROUTER_API_KEY=... (never commit the key) |
memory_sync | configured without token env | Set the documented Turso token env |
plugin_registry | empty plugin list | Check plugins.toml; castellan plugin list |
evolve_archive | archive missing or invalid | Run castellan evolve at least once, or pass --workspace to the right root |
episode_vitals | no episode JSON in ... | castellan run --goal "..." --plugin gridworld at least once |