---
name: swl:status
description: Comando unificado de observabilidad del sistema y la sesión. Enruta a subcomandos [salud | metricas | loops | evolucion | historico | dashboard] que reportan salud del sistema SWL, métricas de la sesión actual, trayectorias de loops iterativos, estado del ciclo de auto-evolución y dashboard histórico multi-sesión. Reemplaza los comandos previos /swl:salud, /swl:metricas, /swl:dashboard y /swl:evolucion-estado (fusionados en este desde la Fase 09).
allowed_tools: ["Read", "Write", "Bash", "Glob", "Grep"]
---

# /swl:status <subcomando> — Observabilidad unificada

Punto único de observabilidad de swl-ses. Fusiona los cuatro comandos previos de
diagnóstico en un router con subcomandos. Cada subcomando delega exactamente en
la misma lógica (skill o script) que usaba el comando original — sin pérdida de
funcionalidad ni de flags.

## Uso

```
/swl:status salud                  — Diagnóstico de salud del sistema SWL (genera SALUD.md)
/swl:status metricas               — Métricas de la sesión actual (tokens, costo, herramientas)
/swl:status metricas detalle       — Desglose completo por herramienta, agente y timeline
/swl:status metricas fases         — Progreso de fases del proyecto (desde feature-list.json)
/swl:status loops                  — Trayectorias de loops iterativos (.planning/loops/)
/swl:status evolucion              — Estado del ciclo de auto-evolución (health_score, nudges…)
/swl:status evolucion --json       — JSON crudo de metricas.json (para pipes)
/swl:status evolucion --dias=N     — Regenera métricas con ventana de N días (default 14)
/swl:status evolucion --regenerar  — Fuerza recomputo del hook ciclo-evolucion.js (etapa métricas)
/swl:status dora                   — Métricas DORA del proyecto destino (deploy freq, lead time, CFR, MTTR)
/swl:status dora --dias=N          — Ventana de medición de N días (default 30)
/swl:status historico              — Dashboard histórico multi-sesión (web, auto-puerto)
/swl:status dashboard              — Alias de historico
/swl:status dashboard --port 9090  — Fuerza puerto específico del dashboard
/swl:status dashboard today        — Resumen de consumo del día (terminal)
/swl:status dashboard stats        — Estadísticas históricas all-time (terminal)
/swl:status dashboard scan         — Sincroniza JSONL → SQLite sin abrir el dashboard
```

Sin subcomando: pide al usuario cuál quiere, o muestra `salud` + `metricas`
como vista por defecto si el contexto lo sugiere.

## Tabla de enrutamiento (delegación 1:1)

| Subcomando | Delega en | Origen previo |
|------------|-----------|---------------|
| `salud` | `Skill("validacion-ci-sistema")` | `/swl:salud` |
| `metricas` (+ `detalle`, `fases`) | scripts de métricas de sesión + `derivar-feature-list.js` | `/swl:metricas` |
| `loops` | `hooks/lib/loop-telemetry.js` | `/swl:metricas loops` |
| `evolucion` | `hooks/ciclo-evolucion.js` (etapa métricas) + `.planning/evolution/metricas.json` | `/swl:evolucion-estado` |
| `dora` | `scripts/lib/metricas-dora.js` + `.planning/evolution/metricas-dora.json` | nuevo (Fase 15, ADR-0039) |
| `historico` / `dashboard` | `Skill("swl-dashboard")` | `/swl:dashboard` |

---

## Subcomando: `salud`

Diagnóstico de salud del sistema SWL con **verificaciones deterministas**
(conteos, existencia de campos, sintaxis). Genera `SALUD.md` con score objetivo.
**Solo lectura** — no modifica nada salvo `SALUD.md`. Para corregir problemas,
usar `/swl:evolucionar`.

**Paso 0 — Detección host vs consumidor (gate determinista, OBLIGATORIO)**:

`salud` audita los componentes del sistema SWL con un score ponderado. Ese score
solo tiene sentido en el repo que **hospeda** los componentes (swl-ses o un fork).
En un proyecto **consumidor** (usa las convenciones SWL vía `~/.claude/` pero no
aloja `agentes/`, `habilidades/`, `comandos/swl/`, `reglas/`, `hooks/`), el
inventario daría 0 y un score `0/100` sería señal falsa. Esta distinción es
**determinista**, NO juicio del agente:

```bash
node scripts/lib/detectar-host-swl.js --json
```

- Si `esHost: true` → continuar con el diagnóstico normal (Carga + pasos siguientes).
- Si `esHost: false` → **NO** calcular score de componentes ni generar `SALUD.md`
  con `0/100`. Reportar el campo `razon` y la lista `sugerencias` (subcomandos de
  `/swl:status` que sí aplican aquí: `metricas`, `loops`, `evolucion`, `dashboard`).
  Ofrecer ejecutar uno de ellos. Terminar sin penalizar el score.

**Carga**: `Skill("validacion-ci-sistema")` — contiene las reglas de validación
por componente (agentes, skills, hooks, comandos, reglas), la tabla de exit codes
y el checklist de integridad. Toda la lógica de verificación vive en el skill.

**Cuándo usar**: antes de iniciar proyecto nuevo, tras modificar agentes/skills
manualmente, tras merge/pull, o como mantenimiento mensual.

**Score global ponderado**:
```
Score = agentes×0.30 + skills×0.25 + comandos×0.20 + reglas×0.15 + hooks×0.10
90-100 Excelente · 75-89 Saludable · 60-74 Funcional · <60 Crítico
```

**Pasos siempre activos**: inventario determinista, detección de tier del proyecto
(Simple <500 / Standard 500-5000 / Complex >5000 archivos), diagnóstico de los 5
componentes, y calidad de `CLAUDE.md` (ADR-0016):
```bash
npx -y @saulwade/swl-ses@latest audit-claudemd --json
```
Umbrales ajustables: `SWL_CLAUDEMD_MAX_LINES` (default 200),
`SWL_CLAUDEMD_MAX_BULLET_CHARS` (default 1000).

**Auditorías opt-in** (cada una se activa con su variable de entorno; si no está
definida, el paso se omite sin afectar el score — diseño zero-config):

| Variable | Qué audita | Comando |
|----------|-----------|---------|
| `SWL_AUDIT_SKILLS=1` | Prompt injection, secretos, URLs sospechosas y estructura en SKILL.md | `bash scripts/audit-skills.sh` (requiere `uv`) |
| `SWL_AUDIT_FRAMEWORKS=1` | Cobertura de NIST CSF/AI RMF, MITRE ATLAS/ATT&CK, D3FEND en skills de seguridad | `npx -y @saulwade/swl-ses@latest audit-coverage-frameworks --resumen` |
| `SWL_AUDIT_AGENTES=1` | Agentes sin Exclusion Clause o Gotchas (anti agent-hijacking) | `npx -y @saulwade/swl-ses@latest audit-agents-gaps --resumen` |

**Verificación de drift de skills** (si existe `manifiestos/skills-lock.json`):
```bash
npx -y @saulwade/swl-ses@latest generate-skills-lock --check
```

**Smoke test de MCP** (si hay servers en `.claude/settings.json` o configs globales):
```bash
python scripts/mcp-orchestrator.py status --json 2>/dev/null
```
Detecta drift de apiKeys (`40101`), binarios faltantes y `"env": {}` que rompe la
herencia de variables — antes de que fallen en uso interactivo.

Formato de salida enriquecido vía `scripts/lib/health-row.js` (barras Unicode;
respeta `NO_COLOR` y `SWL_ASCII_SIMPLE=1`). Genera `SALUD.md` con los datos
exactos de los scripts — sin ajustar el score "porque parece sano".

---

## Subcomando: `metricas`

Métricas acumuladas de la **sesión actual**: tokens, costo estimado USD, tool
calls y distribución por herramienta, más el estado del presupuesto configurado.

**Fuentes de datos**:
```bash
# 1. Bridge de tracking de la sesión (generado por el hook de costos)
ls /tmp/swl-costs-*.json 2>/dev/null | sort -t- -k3 -n | tail -1
# 2. Métricas persistidas del proyecto
cat .planning/METRICAS.md 2>/dev/null || echo "(sin métricas previas)"
# 3. Presupuesto configurado
node -e "const c=require('./manifiestos/hooks-config.json').costBudget||{}; console.log('maxUsd:',c.maxUsd??'no configurado','| maxTokens:',c.maxTokens??'no configurado','| alertAt:',c.alertAt??'no configurado')"
```

Construir el resumen con: tool calls totales, tokens, costo estimado, modelo
predominante, estado de presupuesto (`OK`/`ALERTA`/`EXCEDIDO`) y top 5
herramientas por costo. Si el estado es ALERTA (≥ `alertAt`), sugerir
`/swl:compactar`. Si EXCEDIDO, recomendar revisar `manifiestos/hooks-config.json`.

### `metricas detalle`

Desglose completo: tabla por herramienta (calls, tokens entrada/salida, costo),
desglose por agente SWL desde `costePorAgente` del bridge, comparativa histórica
contra `~/.claude/usage.db` (últimos 30 días) y timeline de actividad por bloques
de 5 minutos.

### `metricas fases`

Progreso de fases del proyecto. Regenera primero el JSON derivado de
`HOJA-RUTA.md` (fuente de verdad) y lo lee:
```bash
node scripts/derivar-feature-list.js
cat .planning/feature-list.json
```
Reporta totales por estado canónico (`completado`, `en_progreso`, `pendiente`,
`bloqueado`, `spec_listo`), lista de fases con marca visual y artefactos
presentes (`[PLAN]`/`[RESUMEN]`), y timestamp de generación. Detección de drift:
`node scripts/derivar-feature-list.js --check` (exit 2 si drift).

### Notas de precisión

Los costos son estimaciones según precios publicados de la API de Anthropic. El
real varía por modelo efectivo, caché de prompt y región/plan. Para costos
exactos, el dashboard de Anthropic Console.

---

## Subcomando: `loops`

Trayectorias de loops iterativos registradas por `hooks/lib/loop-telemetry.js`
en `.planning/loops/`:
```bash
node -e "
const fs = require('fs'), path = require('path');
const lt = require('./hooks/lib/loop-telemetry');
const base = path.join(process.cwd(), lt.DIR_LOOPS);
let dirs = [];
try { dirs = fs.readdirSync(base).map(d => path.join(base, d)).filter(d => fs.statSync(d).isDirectory()); } catch {}
if (dirs.length === 0) { console.log('(sin corridas de loops registradas)'); process.exit(0); }
for (const dir of dirs.sort().slice(-10)) {
  try {
    const t = lt.analizarTrayectoria(dir);
    const h = lt.leerHandoff(dir);
    console.log(path.basename(dir) + ' | iters: ' + t.totalIteraciones +
      ' | keep/revert: ' + t.keeps + '/' + t.reverts +
      ' | métrica: ' + t.metricaInicial + ' → ' + t.metricaFinal +
      ' | plateau: ' + (t.plateau ? 'SÍ' : 'no') +
      ' | status: ' + (h ? h.status : 'en curso'));
  } catch (e) { console.log(path.basename(dir) + ' | (ilegible: ' + e.message + ')'); }
}
"
```
Reportar en tabla: corrida, iteraciones, keep/revert rate, métrica inicial →
final, plateau y status. Si una corrida activa muestra plateau, sugerir cerrarla
— iterar sin mejora quema tokens.

---

## Subcomando: `evolucion`

Estado del ciclo de auto-evolución en la ventana reciente (default 14 días).
Responde con datos a "¿el sistema está aprendiendo?".

**Flags**: `--json` (emite el JSON crudo de `metricas.json`), `--dias=N`
(ventana de N días), `--regenerar` (fuerza recomputo del hook).

**Paso 0 — métricas frescas** (si `--regenerar` o `metricas.json` > 24h):
```bash
echo '{}' | node hooks/ciclo-evolucion.js
```

**Paso 1 — cargar**:
```bash
cat .planning/evolution/metricas.json
```
Si no existe, ejecutar el regenerado; si sigue sin existir, reportar que el ciclo
no ha corrido aún.

**Dashboard** (formato humano) con secciones: health_score + badge, NUDGES
(emitidos/accionados/pendientes por tipo), INSTINTOS (proyecto/global/perfil),
AGENTES (runs/fallos/tasa), EVOLUCIONES (aplicadas/revertidas/rollback ratio),
CALIDAD CONDUCTUAL (fallos por tipo, reintentos, latencia), ALERTAS PERSISTENTES
y KERNEL (gobernanza: política evolvable, último ADR kernel, ratio
`evolvable=false`/total).

**Badges**: ≥90 🏆 Óptimo · ≥75 🥇 Saludable · ≥60 🥈 Parcial · ≥40 🥉 Esqueleto
· <40 ⚠️ Dormido.

**Recomendaciones contextuales** (máx 3, al final): bootstrap de instintos si
`instintos.proyecto==0` y `aprendizajes>10`; revisar alertas si `tasaAccion<0.3`;
candidatos a `/swl:evolucionar` si `tasaExito<70`; etc.

**Anti-substitution**: el archivo de métricas es **siempre**
`.planning/evolution/metricas.json` (nunca `.planning/metricas.json` ni variantes);
el hook que regenera es **siempre** `hooks/ciclo-evolucion.js` (etapa métricas, Fase 11); para forzar
regen usar el pipe `echo '{}' | node ...`, nunca `require()` directo.

**Response discipline**: con `--json`, la respuesta es el contenido crudo del
archivo, sin prosa.

---

## Subcomando: `dora`

Métricas DORA (DevOps Research and Assessment) del **proyecto destino** donde SWL
está instalado: deployment frequency, lead time for changes, change failure rate
y MTTR, cada una clasificada en elite/high/medium/low (umbrales DORA Report 2023).
Mide **velocidad de entrega**, ortogonal a la reliability en runtime de
`observabilidad-swl`/`sre-swl`. Solo lectura salvo el JSON de storage.

**Portabilidad** (D-15-01): deployment frequency + lead time se derivan de git
(tags de release + commits) y están **siempre** disponibles. Change failure rate
+ MTTR requieren `gh` (GitHub CLI) autenticado; si `gh` falta, no está autenticado,
o el repo no tiene remoto GitHub, esas dos reportan "no disponible" **sin fallar**.

**Paso 0 — calcular/regenerar**:
```bash
node scripts/lib/metricas-dora.js --json [--dias=N]
```
Regenera siempre que se invoque el subcomando (la medición es barata) o cuando se
pase `--dias=N` (ventana en días, default 30). El script persiste el informe en
`.planning/evolution/metricas-dora.json` (runtime, gitignored).

**Paso 1 — render**: presentar las 4 métricas con su valor y clasificación:

```
Métricas DORA — ventana de 30 días

  Deployment frequency:  2.30 deploys/semana   [high]
  Lead time (p50):       18.4 h                 [high]
  Change failure rate:   no disponible (gh ausente)
  MTTR:                  no disponible (gh ausente)
```

Reglas de render:
- Si una métrica git reporta `sinDatos: true` (proyecto sin tags de release),
  mostrar "sin datos" — distinto de "frecuencia baja". El informe NO penaliza:
  un proyecto sin releases no es "low", es "sin datos".
- Si `changeFailureRate`/`mttr` traen `disponible: false`, mostrar
  "no disponible (gh ausente)" con la `razon` si ayuda — nunca como error.
- Tras el render, si CFR/MTTR no están disponibles, sugerir (1 línea) instalar y
  autenticar `gh` para habilitarlas; no es obligatorio.

**Anti-substitution**: el archivo de storage es **siempre**
`.planning/evolution/metricas-dora.json` (nunca `metricas.json`, que es del ciclo
de evolución); el script es **siempre** `scripts/lib/metricas-dora.js`.

---

## Subcomando: `historico` / `dashboard`

Dashboard histórico multi-sesión vía `claude-usage` (vendored). Complementa
`metricas` (sesión actual) con perspectiva multi-sesión y gráficos interactivos.

**Carga**: `Skill("swl-dashboard")` con el subcomando indicado:
- (vacío) o `historico` → dashboard web (auto-detecta puerto: 8888, 9090, 9191…)
- `--port N` → fuerza un puerto
- `today` → resumen del día en terminal
- `stats` → estadísticas históricas all-time en terminal
- `scan` → solo sincroniza JSONL → SQLite sin abrir el dashboard

### Integración con Mission Control (opt-in)

Dashboard web externo para orquestación de flotas de agentes. **Completamente
opcional** — el dashboard local funciona igual sin configurarlo.

| Variable | Descripción | Ejemplo |
|----------|-------------|---------|
| `SWL_MC_URL` | URL base de la instancia de MC | `http://localhost:3000` |
| `SWL_MC_TOKEN` | API key de MC (si hay auth) | `mc-key-abc123` |

- Con `SWL_MC_URL` definida: el comando detecta MC (vía `scripts/lib/mc-client.js`)
  y ofrece redirigir al panel web. Si MC no responde en 2s, fallback graceful al
  dashboard local con mensaje informativo (sin crash ni degradación silenciosa).
- Sin `SWL_MC_URL`: dashboard local sin cambios (zero-config).

Instalar MC (opcional): `git clone https://github.com/builderzlabs/mission-control`
→ `docker compose up` (requiere Node ≥22, pnpm; genera su API key al primer
arranque). MC expone además un **servidor MCP con ~49 tools** (agentes, memoria,
soul, tareas, sesiones, tokens/costos, skills, cron, runs/evals). swl-ses **NO**
modifica `.claude/settings.json` automáticamente — el registro del MCP es manual.

**Seguridad**: el MCP de MC incluye tools de **escritura** (`mc_create_task`,
`mc_write_memory`, `mc_write_soul`…). Antes de activarlo, evaluar exposición de
red, permisos mínimos de la API key y confianza en los agentes que lo invocarán.
La regla `seguridad-agentes.md` recomienda documentarlo en
`.planning/MCP_REGISTRY.md`.

---

## Reglas de comportamiento

- `salud` y `evolucion` son **solo lectura** (salvo que `salud` genera `SALUD.md`).
  Para corregir, usar `/swl:evolucionar`.
- Las verificaciones de `salud` son scripts deterministas — no usar juicio
  subjetivo ni ajustar scores "porque parece sano".
- Los reportes opt-in de auditoría (`SWL_AUDIT_SKILLS`, `SWL_AUDIT_FRAMEWORKS`,
  `SWL_AUDIT_AGENTES`) nunca bloquean el diagnóstico: si fallan (red,
  dependencia, paquete no publicado), el flujo continúa.
- Respetar `--json` como salida cruda sin prosa donde aplique (`evolucion`).
- No reintroducir los comandos eliminados: este comando los reemplaza.
