---
name: fathom-doctor
description: >
  Run and interpret `fathom doctor`, the deterministic wiring-diagnosis
  checklist for a fathom-adopting repo — MCP registration, daemon
  reachability, binary freshness, the hook stack (installed AND firing),
  the AGENTS.md stanza and whether Claude Code loads it, shipped skills, config validity,
  obligations serving, and surface traffic. Use when asked "is fathom
  actually wired here", when troubleshooting missing or silent fathom
  behavior, right after `fathom init`, or before trusting a fresh
  session's tool access.
---

<!-- fathom:owned — generated by `fathom init --skills`; safe to delete this line to adopt the file as your own -->

## 1. Run the checklist

```sh
fathom doctor [--harness=claude|codex|auto|<registry id>] [--path <dir>] [--service <id>] [--url <base>] [--json]
```

- `--harness` defaults to `auto`: the first harness whose config markers
  exist (`fathom harness list` shows the registry), else `claude`. Pass it
  explicitly when you know which harness you are diagnosing.
- `--path` defaults to the current directory. `--service` defaults to the
  identities the hooks probe (the directory's basename, then the git
  toplevel's), checked against the daemon's service list, so a repository
  indexed under another name is named rather than guessed.
- `--url` defaults to `http://localhost:7575` (or `$FATHOM_HTTP`); doctor
  only reads from the daemon.
- `--json` for machine output; otherwise a table.

Exit codes: `0` no row failed; `1` at least one row failed; `2` doctor
itself could not run (bad flags, an unresolvable `--path`).

## 2. Read the report honestly

Every row is `{name, status, reason, remedy}`. Keep the four statuses apart
when you summarize:

- **PASS**: verified true; the evidence is in `reason`.
- **FAIL**: an observable problem; `remedy` is one command.
- **WARN**: worth attention, never fails the exit code (a dead guard, a
  leftover scratch daemon).
- **SKIP**: doctor could not check it (daemon down, no call log, a feature
  not configured). It is neither a failure nor a pass. Report it as "could
  not verify: <reason>".

**A fresh install, read correctly.** In v0.11.0 a correct `fathom init
--skills` usually prints about 60 rows with three FAIL rows that are not
wiring faults:

| Row | Why it fails on day one | What to do |
|---|---|---|
| `lefthook_gates` | The repository has no `lefthook.yml` with a `fathom verify` pre-push step | Nothing, unless you want the gate (`fathom-verify` skill) |
| `obligations_served` | The obligations layer has never been compiled | Optional, and it spends LLM tokens: `fathom compile --service <svc> --dry-run=false` |
| `surface_traffic` | No MCP tool call has reached the daemon yet | Make one call (`find_symbol`) after restarting the session |

Rows that SKIP on day one and need nothing: `mcp_registration` (until the
harness config is readable), `binary_fresh` outside fathom's own checkout,
`hooks_firing` and `stanza_loaded` (no session has run yet), the provider
rows (`providers`, `compile_layer`, `decision_provider`) with the default
provider `none`, and the module-binding rows when no module is bound.

The rows that decide whether fathom works:

| Row | What it proves |
|---|---|
| `daemon_reachable` | `GET /healthz` answers |
| `mcp_registration` | The harness's MCP config points at `/rpc/agent` (or `/rpc/extended`) |
| `hooks_installed` | The hook stack is wired in some settings scope (project, local or user) |
| `hooks_firing` | The call log has seen hook traffic: configured is not the same as firing |
| `stanza_present` | `AGENTS.md` has a well-formed fathom region; it WARNs when Claude Code will not load `AGENTS.md` (a root `CLAUDE.md` without `@AGENTS.md`, a parent CLAUDE file, the agents-md plugin's `instructionFiles` setting at `claude-md` or `managed-only`, or Claude Code older than 2.1.277). The plugin is `cc-plugin-agents-md@builtin` from Claude Code 2.1.285 and `agents-md@builtin` in 2.1.277 through 2.1.284; its setting is user-global, so fathom never writes it |
| `skills_installed` | Every shipped skill is present, fathom-owned and current; each missing one is named |
| `wiring_drift` | Hooks, stanza and skills match the shipped template; `fathom fleet reconcile --repo .` shows the diff |
| `config_valid` | `.fathom/config.toml` (user and project) validates |
| `concerns` | Every registered config concern holds (`fathom config audit` has the evidence) |

## 3. Apply remedies with the operator's approval, one at a time

Never run a remedy without saying what it does and getting the operator's
go-ahead:

- `fathom init [--harness <id>] [--skills] [--path <dir>]` is idempotent
  (stanza, hooks, skills; `--json` lists every write); still confirm before
  writing to the operator's repository.
- **Daemon down** (`daemon_reachable`): on macOS the remedy names this
  machine's launchd label, or `fathom daemon install` when none exists;
  elsewhere it is `fathom serve-http` under the operator's own supervisor.
  Never restart a daemon from an agent's own sandboxed shell: hand the
  operator the exact command.
- **A new binary** (`binary_fresh`): the daemon must be restarted on the new
  build. Never copy over a running daemon's binary, which truncates it.
- **A recompile** (`obligations_served`) spends real tokens with a
  configured LLM provider. `--dry-run` (the default) prints the estimate.

Re-run `fathom doctor` after each remedy instead of assuming it worked.

## 4. Prove the session sees it

A clean report proves configuration, not that this session loaded it. A
session started before registration or before a daemon restart never sees
the tools. Make one real call (`find_symbol` on a symbol you know exists);
a connection error despite a clean report means "restart this session".

To check the edit hook's cost, time one call (the hook's own timeout is
5 s; its payload is capped at about 150 tokens and is empty on a clean
file):

```sh
time fathom edit-hook <<< '{"tool_input":{"file_path":"<a real file in the repo>"}}'
```

Well under a second is healthy. A hook that nears 5 s is dropped by Claude
Code on slow runs: file it with `fathom observe` (the `fathom-feedback`
skill).

## 5. Report back

Give a short PASS/FAIL/WARN/SKIP tally and the remedy for each failure,
ready to copy. Never a bare "N checks failed".
