| name | doctor |
| description | Audits the orchestration setup without changes for model drift, stale pins, and environment overrides. Use when routing behaves oddly, after a CLI upgrade, or when model drift is suspected. |
| allowed-tools | Read, Glob, Bash(rg:*), Bash(node:*), Bash(codex --version:*), Bash(grok --version:*), Bash(grok models:*), Bash(grok inspect:*), Bash(grok --help:*), Bash(grok agent --help:*) |
Audit the orchestration setup and report findings as a short checklist with a clear verdict per item.
Environment overrides captured at invocation:
- CLAUDE_CODE_SUBAGENT_MODEL: !
sh -c 'printenv CLAUDE_CODE_SUBAGENT_MODEL || echo "(unset)"'
- ANTHROPIC_MODEL: !
sh -c 'printenv ANTHROPIC_MODEL || echo "(unset)"'
- ANTHROPIC_DEFAULT_HAIKU_MODEL: !
sh -c 'printenv ANTHROPIC_DEFAULT_HAIKU_MODEL || echo "(unset)"'
- ANTHROPIC_DEFAULT_FABLE_MODEL: !
sh -c 'printenv ANTHROPIC_DEFAULT_FABLE_MODEL || echo "(unset)"'
Checks to perform:
- A set CLAUDE_CODE_SUBAGENT_MODEL can silently override every agent model pin (Claude Code behavior as observed on 2.1.x); flag it as a problem unless the user says it is deliberate.
- Read ~/.claude/settings.json and report the
model key. It should be an alias, preferably best[1m] (Fable when available, latest Opus otherwise, floats to future releases). Flag any dated full model ID as a rot risk. Also confirm codex@claude-code-fusion, grok@claude-code-fusion, and fusion@claude-code-fusion appear in enabledPlugins. Treat codex@openai-codex and codex@claude-code-fusion being enabled together as an error because both register the codex namespace. If only codex@openai-codex is enabled, report a migration warning: use the old /codex:status --all to collect or cancel every authoritative running job, exit that session, disable and uninstall the old plugin with --keep-data, install codex@claude-code-fusion, then open a new session. When Codex is missing, report that ordinary implementation has lost its primary lane. Bounded isolated work may use Grok under burst; work that needs Claude tools, privacy, or falls outside Grok's safety boundary uses fusion:fast-worker. Recommend installing codex@claude-code-fusion.
- Read the frontmatter of every file in ${CLAUDE_PLUGIN_ROOT}/agents/ and report each
model, effort, and maxTurns value. Alias pins (opus, sonnet, haiku) float to new releases automatically and are healthy. Full model ID pins are rot risks; fusion:trivial-worker's claude-haiku-4-5 pin is deliberate because the haiku alias can be remapped by ANTHROPIC_DEFAULT_HAIKU_MODEL, so a full ID pins the tier to the intended model regardless of that override, but it must be bumped by hand when a newer cheap tier ships.
- List ~/.claude/agents/ if it exists. A file whose name matches a plugin agent (deep-reasoner, fast-worker, trivial-worker) registers as a duplicate agent alongside the fusion: namespaced one and confuses auto delegation; flag it as a stale leftover to delete unless the user says it is a deliberate local override.
- Compare the template hash of ~/.claude/rules/orchestration.md against the template hash of ${CLAUDE_PLUGIN_ROOT}/rules/orchestration.md, using the same normalization as rules-sync: replace everything between the
<!-- fusion:model-table:start --> and <!-- fusion:model-table:end --> sentinel lines with the fixed normalized marker before computing SHA-256. Prefer node --input-type=module with hashRulesTemplate exported by ${CLAUDE_PLUGIN_ROOT}/scripts/lib/rules-template.mjs; a sed or similar comparison that strips only the sentinel region is also acceptable. Missing live rules or a mismatched template hash means the static routing policy is stale; point at /fusion:setup to install or update it. A user selected live model table may differ from the scored canonical table and is healthy when the template hashes match.
- Remind the user of the role model: the main Claude session is the only control plane and final judge. Claude workers are native specialists rather than an independent model family, Codex owns ordinary implementation and default deep external review, and Grok keeps the protected
burst, independence, live-web, large-context, and best-of-n roles. The orchestrator, deep reasoning, mechanical, and trivial Claude tiers are roles bound to alias tiers, not to specific models, so same tier releases (for example Sonnet 5 under the sonnet alias) adopt their role with no configuration change. Only a genuinely new tier above or between the existing rungs requires a decision.
- Note the recovery moves: if the main session fell back from Fable (safety classifier or availability), /model best restores the strongest available orchestrator. Peer engine models are owned by their own CLIs (~/.grok/config.toml, ~/.codex/config.toml); this setup never pins them.
- Point at /codex:setup and /grok:setup for peer runtime health checks beyond config defaults; peer config defaults themselves are covered in the next step.
- Peer engine defaults: extract the model related keys from ~/.grok/config.toml and the model and model_reasoning_effort keys from ~/.codex/config.toml (never read or print the full files; they sit next to credentials; use a scoped rg query rather than Read on those two files). Report each peer's configured default and flag grok drift when the grok CLI default is absent from the capability table or when that table's recorded lane or scores disagree with the default shown by the CLI. Run
node "${CLAUDE_PLUGIN_ROOT}/scripts/fusion-config.mjs" audit and report its Codex listing section as one checklist item. It reads only ~/.codex/models_cache.json (or FUSION_CODEX_MODELS_CACHE) and never refreshes it or invokes the Codex binary. Flag the configured-but-absent IDs and unconfigured gpt-* newcomers it reports, including the listing mtime. Treat listing unavailable as a warning without aborting the doctor run. /fusion:config is the write path for changing these scores; this audit never changes model-routing.json. When the capability table has no scored models at all, recommend /fusion:config propose so routing stops relying on the qualitative lane descriptions alone.
- Audit the installed Codex surface against the foreground invariant. Glob
~/.claude/plugins/cache/claude-code-fusion/codex/*/commands/ and ~/.claude/plugins/cache/claude-code-fusion/codex/*/agents/, then inspect the task, rescue, review, adversarial-review, and codex-rescue instructions. Task and review calls must stay foreground regardless of complexity, expected duration, review size, or model unless the incoming user request explicitly supplied --background; the rescue agent's companion Bash call must use the 10 minute tool timeout. A package that cannot fit the cap must be split or routed elsewhere. Fusion orchestration gives every detached job it creates one same turn collection attempt capped at 540000ms; a timeout must remain explicitly uncollected with the job id and result command. Direct Codex slash command instructions inspect through status and collect through result; Fusion's monitor is notification only. Confirm that task and rescue expose opt in --web, require --write --network for sandbox network access, and leave both settings disabled when absent. Flag any instruction that can detach implicitly or accepts a foreground receipt as a result.
- Check both ~/.claude/plugins/data/codex-claude-code-fusion/state and the read only compatibility root ~/.claude/plugins/data/codex-openai-codex/state. The first root is canonical for new jobs; Fusion stats and the breaker may read the second after migration but never copy or mutate it. If neither exists, report no recorded Codex job history yet or an uninitialized Codex state path, not necessarily an error.
- In the live ~/.claude/rules/orchestration.md, collect every concrete model ID named in routing prose outside the
<!-- fusion:model-table:start --> and <!-- fusion:model-table:end --> sentinel region, then compare them with the model IDs in the live capability table. Flag every prose ID without a table row as an orphan.
- Probe the installed Codex plugin cache by globbing
~/.claude/plugins/cache/claude-code-fusion/codex/*/commands/ for the /codex:task, /codex:rescue, /codex:review, /codex:adversarial-review, /codex:status, /codex:result, /codex:cancel, and /codex:setup command files and ~/.claude/plugins/cache/claude-code-fusion/codex/*/agents/ for the codex-rescue agent. Report any absent surface as a degraded-capability warning, not an error.
- Audit the installed Grok runtime and instructions against the actual headless surface, not version assumptions. Consult, write, review, and best-of-n must all use
--sandbox strict; a workspace downgrade is an error. Every managed run requires --prompt-file, --output-format, --sandbox, --tools, --disallowed-tools, --deny, --max-turns, and --no-auto-update; consult also requires --permission-mode and --allow, no-web requires --disable-web-search, write requires --always-approve, review requires --json-schema, best-of-n requires --best-of-n and --background-wait-timeout, and ordinary calls require --no-wait-for-background or the bounded wait flag. Missing installation, version, or applicable capability readiness is failure kind setup; recommend upgrading or repairing the CLI and rerunning /grok:setup, never retrying the unchanged task. Consult tools are read, grep, and list plus optional direct web tools. Write tools are read_file, grep, list_dir, search_replace, and run_terminal_cmd, with Agent only for best-of-n; Grok has no write tool id, and search_replace creates files. Every mode denies search_tool, use_tool, ask_user_question, and MCP tools, while ordinary calls also deny Agent. Treat command-pattern denies for common direct grok, claude, and codex invocations as best effort because absolute paths, aliases or functions, and indirect scripts can bypass them. A hard nested-execution boundary requires removing run_terminal_cmd or an OS-level executable or network policy. Builder tracing starts only after stdin is consumed, so it cannot prove policy before prompt delivery or every side effect; fallback or unmatched warnings must terminate early, and a successful close without positive tools allowlist applied evidence is an error. Confirm the following behavior. The child sets all eighteen GROK_CLAUDE_*_ENABLED, GROK_CURSOR_*_ENABLED, and GROK_CODEX_*_ENABLED bridge variables to false; upstream currently consumes the six Claude and six Cursor cells plus the Codex sessions cell and reserves the other five Codex cells, and the child also pins GROK_MANAGED_MCPS_ENABLED=false because that variable has highest precedence over [managed_mcps] in ~/.grok/config.toml and remote settings. Confirm that it removes inherited CLAUDE_CODE_*, CLAUDE_PLUGIN_*, GROK_COMPANION_*, and _GROK_CLAUDE_MARKER_OVERRIDE, broadly scrubs unrelated secrets while preserving xAI authentication, and passes --no-auto-update. Confirm GROK_MEMORY=0 is forced by default, only a direct ordinary task with explicit --memory receives GROK_MEMORY=1, and Fusion routed briefs, review, stop gate, and best-of-n cannot enable it. Report upstream minimum-version forced update as a residual execution and network boundary.
- Audit native Grok configuration as a user-controlled trust boundary. The
search_tool, use_tool, and MCP denies block model invocation but do not prove that native MCP servers, plugins, or hooks under ~/.grok were not started during agent construction or had no side effects; those bridge variables disable Codex compatibility imports, not native Grok configuration. Run grok inspect --json and review the reported permissions, hooks, plugins, agents, mcpServers, and externalCompat surfaces as the native configuration exposure check that the SECURITY threat model otherwise cannot verify. Use scoped rg queries that report configured surface names without printing credentials or full configuration, and label any native startup surface as an explicit trust-boundary notice rather than claiming MCP side effects are disabled. The entire Grok home is read-write under strict, and the sandbox permits consult read_file to reach ~/.grok/auth.json, config, and sessions while write terminal commands may receive preserved xAI authentication variables. Confirm the companion's best-effort Read denies cover auth.json, mcp_credentials.json, config.toml, sessions, memory, logs, and debug with both absolute paths and standard **/.grok patterns. Report that raw path variants, symbolic links, and shell or indirect scripts can bypass those tool-level rules, so environment scrubbing and pattern denies do not isolate filesystem credentials. When memory is explicitly enabled, upstream's internal first-turn memory injection is not a model read_file call and can place selected memory in the model context sent to xAI despite those Read denies. Narrower exposure requires a dedicated sandbox profile, an isolated Grok home, an authentication broker, or upstream path-level authorization.
- Audit Grok sandbox, transport, output, metrics, session, worktree, collection, continuity, history, and ACP evidence. Strict's upstream
system_read roots include /var and /tmp on Linux, and /private plus the entire ~/Library on macOS, so shared temporary content and substantial user application configuration and caches may be readable. Its write roots include the workspace and entire Grok home, always include /tmp and /var/tmp, and on macOS also include /private/tmp, /private/var/tmp, and all of /private/var/folders; the unique private TMPDIR is preferred and handshake-verified, not the only writable temporary surface. Before prompt delivery, the adapter must validate a new ProfileApplied event from the incremental shared sandbox-events.jsonl delta that contains this run's private path and matches the canonical workspace, strict profile, enforced state, and requested restrict_network: true configuration. Upstream events have no run id or pid, so unrelated ProfileApplied and ApplyFailed records are not attributable to this run; failure events are auxiliary only. A matching owned-stderr warning, handshake timeout, missing or malformed matching evidence, shared-log rotation or disappearance, or matching field mismatch fails closed. The matching event proves configuration application, not actual network isolation: Linux uses seccomp, while macOS network blocking is a no-op and write shells may reach the network. Every prompt uses --prompt-file /dev/stdin. Stdout uses a 0600 file unlinked immediately after open and parsed through its descriptor under the total limit. An upstream model_usage row contains only input, output, cache-read, and model-call counts plus optional cost, never synthetic reasoning or total tokens. usage_is_incomplete makes reported values observed lower bounds and both job-total token and cost coverage incomplete. Exact cost otherwise requires a positive complete USD and tick pair, with ticks authoritative at 10000000000 per USD. Short-cwd metadata uses only the exact encoded path; long-cwd lookup requires an exact decoded or .cwd match and never selects a sole cross-cwd candidate. Review requires one --json-schema call; an error or explicit null structured result fails, and only a completely absent field permits local text parsing. Continuity must default to manual; optional claude-session affinity may select only a completed ordinary task from the same Claude session, exact resolved cwd, mode, strict profile, and memory boundary. Fusion routed briefs must not receive automatic affinity, while explicit resume remains limited to compatible terminal task records. /grok:history must expose only the safe companion metadata projection, default to the current workspace, and never read native session contents, briefs, results, or logs. Treat native sessions, companion history, and cross-session memory as three separate stores. Native session cleanup defaults to 30 days and accepts only a positive [storage] cleanup_ttl_days, with 0 falling back to 30; the companion ledger has no promised automatic garbage collection. Fusion creates real worktrees. Upstream ships ACP today, but the companion has not adopted it and continues per-call invocation; any future companion adoption must pool by canonical cwd plus sandbox profile with grok --cwd <canonical> --sandbox <profile> agent --no-leader stdio. A collector timeout, dead job, or status error reports the Fusion task id, peer job id, uncollected, and exact result command. Successful Grok collection remains unverified until /fusion:stats --record-worker-acceptance <fusion-task-id> <accepted|rejected> --source main-loop records the main-loop judgment.
- Run
codex --version and grok --version and compare them against the verified contract versions in ${CLAUDE_PLUGIN_ROOT}/verified-versions.json. An installed version older than the verified one is a compatibility warning. A newer one is an informational drift notice that the companion contracts were verified against the older release and behavior may have moved. Neither is an error by itself because a companion call failing with failure kind setup is the enforcement signal. Multiple Codex generations sharing one CODEX_HOME (for example an IDE or desktop app bundling a newer Codex) are worth flagging when the versions straddle the verified release.
Report the findings compactly. Do not change any file; this command is read only.