## fn doctor: diagnostico del registry y artefactos

`fn doctor` es el entrypoint unico para auditar la salud del sistema de forma read-only. Compone funciones del registry (`functions/infra/`) y formatea su salida. No modifica nada.

### Cuando usar

- Despues de un deploy: confirmar que servicios siguen vivos y artefactos intactos.
- Despues de `git pull` o `fn sync`: detectar drift entre BD y disco.
- Antes de `fn index` masivo: confirmar que apps Go/Py siguen declarando bien sus deps.
- Periodicamente (cron): listar funciones del registry sin consumidores para limpiar.
- Como gate antes de crear proposals: si `fn doctor` esta verde, las metricas del bucle reactivo son fiables.

### Comandos

```bash
fn doctor                  # Corre TODOS los checks (artefacts + services + sync + uses-functions + unused)
fn doctor artefacts        # Solo artefactos: git/venv/app.md/upstream
fn doctor services         # Solo apps con tag 'service' + systemctl + puerto
fn doctor sync             # Solo drift pc_locations BD vs disco local
fn doctor uses-functions   # Solo audit imports reales vs uses_functions
fn doctor unused           # Solo funciones huerfanas del registry

fn doctor --json           # Salida JSON (cualquier subcomando) — para agentes/scripts
```

### Mapeo subcomando → funcion del registry

| Subcomando | Funcion |
|---|---|
| `artefacts` | `artefact_doctor_go_infra` |
| `services` | `services_status_go_infra` |
| `sync` | `pc_locations_drift_go_infra` |
| `uses-functions` | `audit_uses_functions_go_infra` |
| `unused` | `find_unused_functions_go_infra` |

Cada subcomando es un wrapper fino. Toda la logica vive en la funcion. Si quieres usar la salida en otro programa Go, importa la funcion directamente.

### Salida

Texto humano por defecto (tabwriter). `--json` produce array/objeto serializable para `jq`, agentes o pipes.

### Idempotente y seguro

- Read-only: ningun subcomando escribe, mata procesos ni cambia estado.
- `services` abre conexiones TCP a `127.0.0.1:<port>` con timeout 500ms — no genera trafico saliente.
- `artefacts` ejecuta `git rev-parse @{u}` con timeout 3s por artefacto.

### Acciones complementarias (NO son `fn doctor`)

`fn doctor` solo diagnostica. Las acciones derivadas son verbos separados:

| Si `fn doctor` reporta... | Accion |
|---|---|
| `directory_missing` | Marcar `pc_locations.status='missing'` o re-clonar via `/full-git-pull` |
| `git_not_initialized` | `gitea_create_repo_bash_infra` + `ensure_repo_synced_bash_infra` |
| `venv_broken_path` | `cd <analysis_dir> && rm -rf .venv && uv sync` |
| `service active=inactive` | `systemctl --user start <unit>` o investigar logs |
| `port not listening` | `port_kill_bash_infra <port>` (si zombie) y relanzar |
| `missing_in_app_md` | Editar `app.md` y añadir el ID a `uses_functions` |
| `unused` (funcion huerfana) | Decidir: usar, deprecar (tag), o borrar |
| Backup viejo | `backup_all_bash_pipelines ~/backups/fn_registry` |

### Para agentes

Patron recomendado tras una accion no trivial (deploy, sync, mass edit):

```bash
fn doctor --json > /tmp/doctor.json
# Agente parsea JSON, decide si crear proposals o avisar al humano
```

Si el agente quiere actuar sobre los hallazgos, abre proposals con `fn proposal add` referenciando los IDs afectados — NO toca artefactos directamente sin aprobacion humana.
