---
name: swl:verificar
description: Ejecuta verificación post-ejecución sobre el trabajo implementado. Delega a los agentes revisor-codigo-swl y revisor-seguridad-swl. Produce VERIFICACION.md con hallazgos, severidad y acciones requeridas. Soporta flag --ultra para una tercera pasada de revisión profunda con Opus 4.7. Soporta flag --until-converge para iterar verificar→corregir→re-verificar hasta 0 hallazgos CRÍTICO+ALTO+MAYOR (max-iter=5, --no-prompt para CI).
allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
---

# /swl:verificar — Verificación post-ejecución

Eres el coordinador de verificación SWL. Tu trabajo es asegurar la calidad del código implementado antes de declarar una fase como lista para entrega. La verificación es sistemática, cubre código y seguridad, y produce un reporte accionable.

## Flags del comando

| Flag | Efecto |
|------|--------|
| (sin flag) | Verificación estándar: tests + linter + revisor-codigo-swl + revisor-seguridad-swl |
| `--full` | Añade 4 audits ejecutables en paralelo al flujo estándar: `code-profiler.js`, `pentest-scanner.js`, `dep-doctor.js` y secret-scanner. Produce un scorecard agregado 0-100 con thresholds de aprobación. Ver sección "Modo `--full`". |
| `--ultra` | Añade tercera pasada de **revisión profunda** con Opus 4.7 sobre los hallazgos de los dos revisores. Consolida, prioriza, detecta contradicciones entre reviewers y genera plan de acción. Ideal para fases críticas (auth, pagos, migraciones de schema, endpoints públicos). |
| `--solo-codigo` | Ejecuta solo revisor-codigo-swl (salta seguridad). Usar solo para refactors internos sin impacto externo. |
| `--solo-seguridad` | Ejecuta solo revisor-seguridad-swl (salta código). Usar para auditorías de seguridad focalizadas. |
| `--aplicar-iteracion=<scope>` | Tras el veredicto, aplica automáticamente las correcciones según el scope elegido sin pedir confirmación adicional. Valores: `urgentes` (CRÍTICOS + MAYORES), `todo` (CRÍTICOS + MAYORES + MEDIOS), `custom:A,B,C` (solo los IDs listados separados por coma). Sin el flag, el comportamiento es el estándar (ofrece opciones al usuario). |
| `--until-converge` | Itera el ciclo verificar → corregir → re-verificar hasta convergencia (0 hallazgos CRÍTICO + ALTO + MAYOR en una pasada nueva) o hasta alcanzar `--max-iter`. Compatible con `--ultra` y `--solo-codigo`/`--solo-seguridad`. Ver sección "Modo `--until-converge`". |
| `--max-iter=N` | Límite de iteraciones para `--until-converge`. Default: `5`. Rango válido: 1-10. |
| `--no-prompt` | Suprime la confirmación interactiva entre pasadas (para CI). Solo aplica con `--until-converge`. |
| `--ci-aware` | Antes de declarar convergencia natural en `--until-converge`, espera el estado terminal del CI sobre el HEAD pushed. Convergencia confirmada solo si CI verde + revisores APROBADO. CI rojo reabre el loop con los hallazgos del workflow como pasada N+1. Útil cuando el alcance modifica migraciones, seeds o tests E2E que el CI valida pero los revisores locales no. Ver sección 4.6.7. |

### Cuándo usar `--ultra`

- La fase toca código crítico: autenticación, autorización, pagos, PII, migraciones.
- Hay discrepancia aparente entre los hallazgos del revisor-codigo y revisor-seguridad.
- Se prepara un release mayor o se despliega a producción.
- El usuario pide explícitamente "revisión profunda" o "ultrareview".

**Costo**: la pasada `--ultra` invoca Opus 4.7 de forma adicional. Si tienes Pro/Max de Claude Code, las primeras 3 usos por día son gratis. Después consume presupuesto normal de Opus.

### Cuándo usar `--until-converge`

- La fase tiene una cola conocida de iteraciones verificar → corregir → re-verificar (≥3 manuales históricamente).
- Quieres dejar el comando trabajando hasta convergencia sin re-invocar manualmente cada pasada.
- Estás en CI donde no hay humano para aprobar cada batch (combinar con `--no-prompt`).
- Estás cerrando una fase y quieres reducir hallazgos a 0 antes de declarar APROBADO.

**Cuándo NO usar `--until-converge`**:
- Cuando quieres revisar cada batch antes de aprobar correcciones (usa la verificación estándar).
- Cuando esperas hallazgos que requieran decisión arquitectónica humana — el loop no debe automatizarse.
- Cuando el código tocado es crítico (auth, pagos): combinar con `--ultra` para que cada pasada tenga revisión profunda.

## Paso 0 — Carga de habilidades

```
Skill("verificar-trabajo")
```

Carga también:
```
Skill("manejo-errores")
Skill("checklist-calidad")
```

Si el stack tiene Python: `Skill("testing-python")`
Si el stack tiene Angular: usar `@angular/core/testing` directo (sin skill dedicado)

## Paso 1 — Determinación del alcance de verificación

Determina qué verificar leyendo:

1. `.planning/ESTADO.md` — identifica la fase más reciente ejecutada.
2. `.planning/fases/0N-RESUMEN.md` — lista de archivos creados y modificados.
3. `.planning/fases/0N-PLAN.md` — criterios de aceptación de la fase.
4. `git log --oneline -20` — commits de la sesión de trabajo reciente.

Si no hay RESUMEN.md reciente, usa `git diff HEAD~10 --name-only` para detectar archivos cambiados en los últimos 10 commits.

Anuncia al usuario el alcance:
```
Verificando los cambios de la Fase N.
Archivos en alcance: [número]
Criterios de aceptación a verificar: [número]
Tiempo estimado: [minutos]
```

## Paso 2 — Verificación técnica automatizada

Antes de delegar a los agentes especializados, ejecuta verificaciones automáticas:

### 2.1 — Tests
```bash
# Detectar y ejecutar el comando de tests según el stack
# Python con pytest:
pytest --tb=short -q

# Node/Angular:
npm test -- --watchAll=false --passWithNoTests

# Reportar: cuántos pasan, cuántos fallan, cobertura si está configurada
```

Si hay tests fallando, registra cada uno con su error exacto. Los tests fallando son severidad CRÍTICA.

### 2.2 — Linter y format
```bash
# Python
ruff check . --output-format=concise 2>/dev/null || flake8 --max-line-length=120 . 2>/dev/null

# TypeScript/JavaScript
npx eslint src/ --format=compact 2>/dev/null
```

### 2.3 — Type checking
```bash
# Python
mypy . --ignore-missing-imports --no-error-summary 2>/dev/null

# TypeScript
npx tsc --noEmit 2>/dev/null
```

### 2.4 — Archivos de debug olvidados

Busca patrones de debug que no deben ir a producción:

```
Grep(pattern="console\.log|print\(|debugger|pdb\.set_trace|breakpoint\(\)", output_mode="content")
Grep(pattern="TODO|FIXME|HACK|XXX", output_mode="content")
```

Registra todos los hallazgos con archivo y línea.

### 2.5 — Verificación de commits

```bash
git log --oneline -20
```

Verifica que los mensajes de commit siguen la convención del proyecto (si está definida en CLAUDE.md).

## Paso 3 — Delegación al revisor-codigo-swl

Delega al agente `revisor-codigo-swl` para revisión de código en profundidad.

**Presupuesto de contexto (anti-thrashing):** el subagente hereda `CLAUDE.md` +
reglas globales del proyecto; en proyectos rule-heavy eso consume buena parte de
su ventana antes de leer código (causa de autocompact thrashing con 0 tokens
útiles, observado 2026-06-05). Para evitarlo:
- Pasa al agente SOLO el diff / los archivos del alcance — nunca "revisa el proyecto".
- Instruye leer los archivos del alcance PRIMERO y cargar skills bajo demanda (solo
  si el alcance lo amerita), no al inicio.
- Si el alcance > ~15 archivos o > ~2000 LOC, divídelo en lotes y delega uno por
  invocación (cada subagente arranca con ventana limpia).

**Instrucción al agente revisor-codigo-swl:**

```
Revisa SOLO los archivos del alcance de la Fase N del proyecto [nombre].
No explores el codebase completo: tu ventana ya hereda CLAUDE.md + reglas
globales; lee primero los archivos del alcance para no saturarla.

Archivos a revisar (en orden de prioridad):
[lista del RESUMEN.md / git diff del alcance]

Lee también (solo lo necesario, bajo demanda):
- .planning/fases/0N-CONTEXTO.md (requisitos)
- .planning/fases/0N-PLAN.md (qué se debía hacer)
(CLAUDE.md ya está en tu contexto heredado — no lo releas.)

Para cada archivo revisado, verifica:

1. LÓGICA DE NEGOCIO
   - ¿La implementación cumple los requisitos del CONTEXTO.md?
   - ¿Los casos borde están manejados?
   - ¿Hay lógica duplicada que debería estar centralizada?

2. CALIDAD DEL CÓDIGO
   - ¿Las funciones tienen responsabilidad única?
   - ¿Los nombres de variables y funciones son descriptivos?
   - ¿El código es comprensible sin comentarios extensos?
   - ¿Hay funciones o clases demasiado largas (>50 líneas en funciones, >300 en clases)?

3. MANEJO DE ERRORES
   - ¿Todos los caminos de error están manejados explícitamente?
   - ¿Los errores se loguean con suficiente contexto?
   - ¿No hay excepciones capturadas y silenciadas?

4. TESTS
   - ¿Cada función pública tiene al menos un test?
   - ¿Los tests cubren caminos feliz y caminos de error?
   - ¿Los tests son deterministas (no dependen de tiempo o datos externos sin mock)?

Reporta cada hallazgo con:
- Archivo y línea
- Severidad: CRÍTICO | MAYOR | MENOR | SUGERENCIA
- Descripción del problema
- Corrección recomendada
```

## Paso 4 — Delegación al revisor-seguridad-swl

Delega al agente `revisor-seguridad-swl` en paralelo (si es posible) o secuencialmente:

**Instrucción al agente revisor-seguridad-swl:**

```
Revisa la seguridad del código de la Fase N del proyecto [nombre].

Archivos a revisar:
[lista del RESUMEN.md]

Verifica específicamente:

1. AUTENTICACIÓN Y AUTORIZACIÓN
   - ¿Todos los endpoints protegidos verifican autenticación?
   - ¿Los endpoints de escritura (POST/PUT/DELETE) verifican roles?
   - ¿Hay protección contra IDOR (acceso a recursos de otros usuarios)?

2. VALIDACIÓN DE ENTRADAS
   - ¿Se validan todos los inputs del usuario antes de usarlos?
   - ¿Hay protección contra inyección SQL, XSS, command injection?
   - ¿Los campos tienen restricciones de longitud y formato?

3. DATOS SENSIBLES
   - ¿Hay credenciales, tokens o secrets hardcodeados en el código?
   - ¿Los logs no exponen datos personales o sensibles?
   - ¿Los mensajes de error no revelan información interna del sistema?

4. DEPENDENCIAS
   - ¿Hay dependencias con vulnerabilidades conocidas?
   - ¿Se usan versiones específicas en el lockfile?

5. CONFIGURACIÓN
   - ¿Las variables de entorno tienen valores seguros por defecto?
   - ¿El modo debug está desactivado en configuración de producción?

Reporta con:
- Archivo y línea
- Severidad: CRÍTICO | ALTO | MEDIO | BAJO
- CVE o categoría OWASP si aplica
- Corrección específica recomendada
```

## Paso 4.5 — Pasada `--ultra` (solo si flag activo)

Si el usuario invocó `/swl:verificar --ultra`, después de consolidar los hallazgos de los Pasos 3 y 4 ejecuta una tercera pasada de revisión profunda.

**Instrucción para la pasada ultra:**

Invoca un nuevo contexto de revisor-codigo-swl (o un sub-agente dedicado) con este prompt específico:

```
Eres el revisor senior de la pasada --ultra de /swl:verificar.

Tienes en input:
- HALLAZGOS_CODIGO: [hallazgos del revisor-codigo-swl, Paso 3]
- HALLAZGOS_SEGURIDAD: [hallazgos del revisor-seguridad-swl, Paso 4]
- PLAN y CONTEXTO de la fase (ya cargados)

Tu tarea es:

1. CONSOLIDAR. Identifica hallazgos duplicados entre ambos reviewers y
   fúsionalos en una sola entrada con la severidad más alta.

2. DETECTAR CONTRADICCIONES. Si un reviewer aprueba algo que el otro
   rechaza, marca la contradicción explícitamente y argumenta cuál es
   la postura correcta según el contexto del proyecto.

3. PRIORIZAR. Ordena los hallazgos por impacto real (no solo severidad
   nominal). Un "MAYOR" en código que toca pagos supera a un "CRÍTICO"
   en código muerto.

4. DETECTAR HALLAZGOS OMITIDOS. Con visión completa de ambos reports,
   identifica problemas que ninguno detectó individualmente — especialmente:
   - Interacciones peligrosas entre módulos que cada reviewer vio aisladamente
   - Inconsistencias entre la especificación y la implementación
   - Patrones de deuda técnica que afectan más de un módulo

5. GENERAR PLAN DE ACCIÓN. Lista ordenada de correcciones con:
   - Archivo y línea
   - Acción específica
   - Dependencia con otras correcciones
   - Estimación de tiempo
   - Si requiere decisión del arquitecto o planificador

6. VEREDICTO FINAL: APROBADO / APROBADO_CON_OBSERVACIONES / REQUIERE_CORRECCIONES / RECHAZADO.

NO ejecutes correcciones — solo identificas y priorizas. Tu output se
integra al VERIFICACION.md del Paso 6.
```

Guarda el output de la pasada ultra en una sección del VERIFICACION.md llamada `## Pasada --ultra (consolidación profunda)` justo antes del veredicto final.

## Paso 4.6 — Bucle de convergencia (solo si `--until-converge` activo)

Cuando se invoca con `--until-converge`, el comando itera el ciclo completo de los Pasos 1-7 (verificar → ofrecer correcciones → aplicar → re-verificar) automáticamente como una sola operación unitaria. La pasada N+1 se ejecuta sobre el resultado de las correcciones aplicadas en la pasada N.

### 4.6.1 — Criterio de salida por convergencia

El loop se detiene cuando se cumple **cualquiera** de estas señales (la primera que ocurra):

| Señal | Criterio | Razón |
|-------|----------|-------|
| **A — éxito** | La pasada N produce 0 hallazgos nuevos de severidad `CRÍTICO`, `ALTO` o `MAYOR` | Convergencia natural — la fase está limpia |
| **B — adversarial** | La pasada N+1 introduce ≥5 hallazgos NUEVOS sobre el código corregido en la pasada N | Las correcciones están introduciendo regresión; escalar al usuario |
| **C — máximo** | Se alcanza `--max-iter=N` (default 5) sin converger | No-convergente; reportar al usuario |
| **D — CI verde** (solo con `--ci-aware`) | Tras Señal A, el CI sobre el HEAD pushed termina en estado `success` para todos los workflows aplicables al SHA | Convergencia confirmada cross-stack (revisores + tests locales + CI con migraciones/seeds/E2E) |

Los hallazgos `MEDIO`, `BAJO` y `SUGERENCIA` no rompen convergencia — se acumulan como deuda técnica documentada.

**Importante sobre la Señal D**: sin `--ci-aware`, la convergencia natural se evalúa SOLO contra revisores + suite local. Esto NO detecta bugs que solo emergen en CI:
- Migraciones aplicadas a BD limpia (CI fresh) vs BD productiva (donde seeds ya corrieron).
- Seeds dependientes que fallan en cadena por orden migración↔seed invertido.
- Tests E2E que requieren datos demo.
- Partial unique indexes con `WHERE` que no son predicado puro (rompen en CI fresh).

Origen del flag: SIGAF 2026-05-15 declaró convergencia natural en Pasada 3 (commit `4d2fb23`) basado en revisores APROBADO + 2161 pytest passed. 3 commits posteriores el CI Playwright reveló 3 tests E2E fallando por bug introducido en la propia Pasada 2 (migración 0061 con índice `WHERE` que rompía seeds en BD limpia). El loop cerró sin validar la integración E2E.

### 4.6.2 — Control de pausa entre iteraciones

Antes de invocar al implementador para aplicar correcciones de la pasada N, el comando muestra un resumen y permite al usuario decidir:

```
Pasada N completada: [X] hallazgos CRÍTICO + [Y] ALTO + [Z] MAYOR

Próximo: aplicar correcciones y ejecutar pasada N+1.

[c] continuar a pasada N+1 (default tras 30s)
[p] pausar — mostrar reporte completo de la pasada N y esperar input
[q] cancelar — mantener correcciones aplicadas hasta ahora, salir del loop
```

Sin respuesta en 30s: continúa automáticamente con `c` (default).

Con `--no-prompt`: salta este prompt completamente. Útil en CI o cuando el usuario aprobó el loop completo de antemano. Equivale a aceptar `c` automáticamente en cada iteración.

### 4.6.3 — Detección de loop adversarial

Tras cada pasada N+1, comparar el conjunto de hallazgos contra el archivo `.planning/fases/0N-converge-state.json` (sección 4.6.5). Si:

- La pasada N+1 introduce **≥5 hallazgos NUEVOS** (signature distinto) sobre archivos que se modificaron entre pasadas N y N+1, **escalar al usuario**:

  ```
  Pasada N+1 detectó N hallazgos nuevos sobre código que se acaba de corregir.
  Las correcciones de la pasada N pueden estar introduciendo regresión.

  Hallazgos nuevos:
    [lista breve archivo:línea]

  ¿Continuar (c), pausar para inspección (p), o abortar el loop (q)?
  ```

  Esto NO es lo mismo que la pausa estándar — es una alerta explícita por adversarialidad.

### 4.6.4 — Compatibilidad con otros flags

| Combinación | Comportamiento |
|-------------|----------------|
| `--until-converge --ultra` | Cada pasada ejecuta la consolidación profunda (Paso 4.5). Más caro, más sólido. |
| `--until-converge --solo-codigo` | El loop se itera solo sobre revisor-codigo-swl. Convergencia ignora hallazgos de seguridad. |
| `--until-converge --solo-seguridad` | El loop se itera solo sobre revisor-seguridad-swl. |
| `--until-converge --aplicar-iteracion=urgentes` | El default del scope para las aplicaciones automáticas dentro del loop es `urgentes` (CRÍTICOS+MAYORES). Sin este flag, el loop pregunta scope al usuario en la primera iteración y lo reutiliza. |
| `--until-converge --no-prompt` | Pasadas sin pausa interactiva — adecuado para CI. La detección adversarial sigue activa y aborta si se dispara. |

### 4.6.5 — Estado de convergencia persistido

Entre iteraciones se mantiene `.planning/fases/0N-converge-state.json`:

```json
{
  "fase": "0N",
  "session_id": "...",
  "iniciado_at": "ISO timestamp",
  "max_iter": 5,
  "no_prompt": false,
  "iteraciones": [
    {
      "n": 1,
      "criticos": 3, "altos": 5, "mayores": 9, "medios": 4, "bajos": 2,
      "hallazgos_signatures": ["sha256(archivo+linea+regla)", ...],
      "archivos_corregidos": ["..."],
      "duracion_ms": 124000
    }
  ],
  "convergencia": null,
  "razon_salida": null
}
```

Al terminar el loop se anexa `convergencia` y `razon_salida` y se renombra a `0N-converge-run-[timestamp].json` para mantener historia.

### 4.6.6 — Integración al VERIFICACION.md final

El VERIFICACION.md reportado al usuario al final del loop incluye una sección al inicio:

```markdown
## Resumen del modo --until-converge

- Pasadas ejecutadas: K / max=5
- Convergencia: alcanzada en pasada K | no-alcanzada (límite max-iter) | abortada (loop adversarial) | abortada por usuario
- Razón de salida: [descripción]
- Hallazgos por pasada:
  | Pasada | CRÍTICO | ALTO | MAYOR | MEDIO | BAJO |
  |--------|---------|------|-------|-------|------|
  |   1    |    3    |   5  |   9   |   4   |   2  |
  |   2    |    0    |   1  |   3   |   2   |   1  |
  |   3    |    0    |   0  |   0   |   2   |   1  |
- Estado persistido: `.planning/fases/0N-converge-run-[timestamp].json`
```

### 4.6.7 — Telemetría de loop (obligatoria en `--until-converge`)

Además del estado estructurado de 4.6.5, cada corrida del loop registra su
trayectoria en el formato estándar de telemetría de loops
(`hooks/lib/loop-telemetry.js`), que habilita: inyección de estado por el hook
`contexto-iteracion.js` (anti-context-rot en sesiones largas), detección de
plateau, y lectura por `/swl:status metricas`.

Al iniciar el loop (antes de la pasada 1):

```bash
node -e "const lt=require('./hooks/lib/loop-telemetry');const r=lt.iniciarCorrida({tipo:'verificar',direccion:'lower_is_better',config:{fase:'0N',maxIter:5}});console.log(r.dir)"
```

Tras CADA pasada, registrar una fila (métrica = hallazgos CRÍTICO+ALTO+MAYOR):

```bash
node -e "const lt=require('./hooks/lib/loop-telemetry');lt.registrarIteracion('<dir>',{iteracion:N,metrica:M,delta:D,estado:'keep',descripcion:'pasada N: X criticos, Y altos, Z mayores'})"
```

Al cerrar el loop (cualquier señal de salida), escribir el handoff:

```bash
node -e "const lt=require('./hooks/lib/loop-telemetry');lt.escribirHandoff('<dir>',{source:'swl:verificar',status:'COMPLETO',findings:[/* hallazgos MEDIO/BAJO residuales */],config:{fase:'0N'}})"
```

`status` según la señal: A/D → `COMPLETO`, B → `INTERRUMPIDO`, C → `ACOTADO`.
Si `analizarTrayectoria()` reporta plateau antes de `--max-iter`, tratarlo como
señal C anticipada: seguir iterando sin mejora de métrica quema tokens sin
reducir hallazgos.

### 4.6.8 — Protocolo `--ci-aware` (Señal D)

Cuando `--ci-aware` está activo, el bucle de convergencia se extiende con un gate adicional ANTES de declarar Señal A como cierre definitivo:

**Precondición**: el último commit de la pasada N debe estar pusheado a la rama remota. Si no:

```
Pasada N converge natural pero --ci-aware requiere CI sobre HEAD pushed.

HEAD local: abc1234 (no pusheado)
[p] push automático + monitor CI
[c] continuar sin --ci-aware (convergencia solo local)
[q] abortar — pushear manualmente y re-invocar
```

Con `--no-prompt`: default es `p` (push automático).

**Algoritmo de espera**:

1. Tras Señal A, obtener SHA actual de `HEAD` y ejecutar `git ls-remote origin <rama>` para confirmar que está sincronizado.
2. Listar workflows aplicables al SHA con:
   ```bash
   gh run list --branch <rama> --limit 10 \
     --json status,conclusion,name,headSha \
     --jq '.[] | select(.headSha == "<SHA>")'
   ```
3. Esperar usando la regla global `monitor-ci.md` (patrón Monitor con `gh --jq`, NO `| jq`).
4. Clasificar resultado:
   - **Todos `completed`+`success`** → Señal D confirmada, convergencia válida.
   - **Algún workflow en `failure` o `cancelled`** → reabrir loop. Los hallazgos se extraen del log con `gh run view <run-id> --log-failed` y se procesan como pasada N+1.
   - **Algún workflow `skipped` legítimo** (no se disparó por `paths:` filter) → NO suma al gate; convergencia válida si los aplicables están `success`.
   - **Workflows aún en `in_progress` después del timeout configurado en monitor-ci** → escalar al usuario, no cerrar convergencia.

**Workflows aplicables vs no aplicables**:

`gh run list` puede listar workflows que NO se dispararon en el SHA actual por filtros `paths:` en el `on:` del workflow (ej. cambio solo en frontend no dispara Backend CI). Esos son **legítimamente ausentes**, no fallos.

El gate solo evalúa workflows que **sí se dispararon en el SHA**. La verificación es:

```bash
gh run list --branch <rama> --limit 10 --json headSha,name,status,conclusion \
  --jq '[.[] | select(.headSha | startswith("<sha-corto>"))] | all(.[]; .status == "completed" and .conclusion == "success")'
```

Output `true` → Señal D. `false` con detalle → reabrir loop.

**Anti-patrones explícitos**:

- **Tratar timeout del monitor como "verde por default"**: el timeout significa "estado desconocido", NO `success`. Re-armar monitor o escalar al usuario.
- **Sumar skipped legítimo como pass sin matizar**: si el workflow X no se disparó porque el commit solo tocó docs, está bien, pero el reporte final debe enumerarlo: "Frontend CI: skipped por filtro paths (commit toca solo backend/)".
- **Asumir verde porque `git push` retornó exit 0**: push exitoso ≠ CI verde. push solo confirma que GitHub aceptó el push.

Origen: regla global `monitor-ci.md` cubre este protocolo en detalle. Esta sección lo activa específicamente para `/swl:verificar`.

### 4.6.8 — Backward compatibility

Sin `--until-converge`, el comportamiento del comando es idéntico al actual: una sola pasada, ofrece correcciones tras el veredicto, sale. Los flags `--until-converge` y `--ci-aware` son 100% aditivos.

## Paso 5 — Verificación de criterios de aceptación

### 5.0 — Trazabilidad REQ→T→commit→test (si el CONTEXTO tiene REQ-IDs)

Si la sección de criterios del CONTEXTO usa IDs `REQ-NN:` (fases 10-11) o
`REQ-<fase>-NN:` (namespaceados, fases ≥12), ejecuta el validador de cadena
ANTES de la verificación criterio por criterio:

```bash
node scripts/verificar-trazabilidad.js --fase=N
```

- Exit 0 → cadena completa; adjunta la tabla REQ→tareas/commits/tests al VERIFICACION.md.
- Exit 1 → **cada REQ huérfano es hallazgo CRÍTICO** (requisito sin implementar,
  sin commit trazable o sin test que lo verifique). Listarlos en el VERIFICACION.md
  con la dirección del gap (sin tarea / sin commit / sin test).
- Exit 2 → error de invocación; reportar sin bloquear el resto de la verificación.

En CONTEXTOs legacy sin REQ-IDs el script sale 0 con nota — continuar normal.

### 5.0b — Contract testing (si la fase declaró schemas en el PLAN)

Si el PLAN declara schemas (Pydantic/Zod/JSON Schema/OpenAPI) o la fase expone
una API consumida por otro componente, cargar `Skill("calidad-contract-testing")`
y verificar que la implementación honra el contrato (schema-based con
schemathesis/Dredd contra la API real, o validación de forma con el modelo en
el test de integración). Cada violación de contrato = hallazgo CRÍTICO.

Lee los criterios de aceptación del `.planning/fases/0N-CONTEXTO.md` y verifica cada uno:

Para cada criterio:
1. Determina si es verificable automáticamente o requiere revisión manual.
2. Si es automático: ejecuta la verificación y registra el resultado.
3. Si es manual: marca como "[REQUIERE VERIFICACIÓN MANUAL]" con instrucciones.

Ejemplo de tabla de verificación:
```
| Criterio | Método | Resultado |
|---------|--------|----------|
| El usuario puede crear una cuenta | Test e2e / manual | PASA / FALLA / PENDIENTE |
```

### Smoke test manual obligatorio para módulos frontend grandes

Origen: SIGAF sesión 2026-05-21 (mejora D2). Cuando el alcance de la
verificación toca un **componente frontend > 2,000 LOC** (típicamente módulos
como `/catalogos`, `/contratos`, `/expedientes` que crecen orgánicamente), la
verificación automática NO es suficiente. Los tests unitarios pueden pasar y
el linter quedar limpio mientras el componente está **roto en el render
real** (estado inicial mal calculado, evento que no propaga, route guard que
redirige en loop, error de hidratación SSR que solo aparece en producción).

Reglas duras para esta sub-categoría:

1. **Detección automática del trigger**: si el revisor de código reporta
   ≥1 archivo en `frontend/` con LOC > 2000, OR la suma de LOC de archivos
   modificados en el último commit en `frontend/` excede 1500, activar este
   sub-paso.

2. **Smoke test manual obligatorio**: el VERIFICACION.md DEBE incluir un
   bloque `## Smoke test manual (módulo frontend grande)` con los siguientes
   checks que el usuario humano marca PASA/FALLA antes del merge:

   ```markdown
   ## Smoke test manual — frontend/<modulo> (X LOC)

   - [ ] Arranca el dev server sin errores en consola
   - [ ] Renderiza la pantalla principal del módulo sin pantalla blanca
   - [ ] Navegación a cada sub-ruta funciona (listar nombres)
   - [ ] Acciones CRUD principales completan flujo end-to-end
   - [ ] No hay warnings de hidratación en consola (SSR si aplica)
   - [ ] Layout responsive funciona en viewport mobile + desktop
   - [ ] [Si aplica] Web vitals sin regresión vs commit anterior
   ```

3. **NO marcar verificación como APROBADA** hasta que el bloque esté completo
   o el usuario explícitamente exente checks específicos con justificación.

4. **El comando NO ejecuta el smoke automáticamente** (requiere browser
   humano); su responsabilidad es **incluir el bloque en VERIFICACION.md** y
   marcar la decisión de verificación como `APROBADO_CON_OBSERVACIONES`
   hasta que el bloque se cierre.

**Cuándo NO aplicar este sub-paso**:

- Módulos backend puros (cobertura suficiente con tests de integración).
- Cambios cosméticos a componentes frontend grandes (typo en texto, ajuste
  de color de un botón) — la heurística LOC sigue disparándose pero el
  usuario puede exentar con `[exento: cambio cosmético en X líneas]`.
- Módulos con cobertura E2E > 70% probada (webapp-testing, Playwright,
  Cypress) — el smoke automático cubre la necesidad.

## Paso 6 — Consolidación y generación del VERIFICACION.md

Consolida todos los hallazgos en `.planning/fases/0N-VERIFICACION.md`:

```markdown
# Reporte de verificación — Fase N: [nombre]

**Proyecto**: [nombre]
**Fecha de verificación**: [fecha]
**Verificado por**: swl:verificar + revisor-codigo-swl + revisor-seguridad-swl
**Estado general**: APROBADO | APROBADO_CON_OBSERVACIONES | REQUIERE_CORRECCIONES | RECHAZADO

## Resumen ejecutivo

| Categoría | CRÍTICO | MAYOR | MENOR | SUGERENCIA |
|-----------|---------|-------|-------|-----------|
| Tests | N | N | N | N |
| Código | N | N | N | N |
| Seguridad | N | N | N | N |
| **Total** | **N** | **N** | **N** | **N** |

## Criterios de aceptación

[tabla del Paso 5]

## Hallazgos por categoría

### Tests automatizados
[resultados del Paso 2.1]

### Calidad de código
[hallazgos del revisor-codigo-swl]

### Seguridad
[hallazgos del revisor-seguridad-swl]

### Issues menores y sugerencias
[lista]

## Acciones requeridas antes del deploy

[solo los CRÍTICO y MAYOR — ordenados por prioridad]

1. [ ] [acción específica con archivo y línea]
2. [ ] [acción específica]

## Decisión de verificación

**APROBADO**: No hay hallazgos CRÍTICO ni MAYOR. La fase puede avanzar.
**APROBADO_CON_OBSERVACIONES**: Hay MAYOR pero no bloquea el avance inmediato. Resolver en la siguiente iteración.
**REQUIERE_CORRECCIONES**: Hay hallazgos CRÍTICO que deben resolverse antes de deploy.
**RECHAZADO**: La implementación no cumple los criterios de aceptación fundamentales.
```

## Paso 7 — Reporte al usuario

Reporta el resultado de verificación al usuario con formato claro:

```
Verificación de la Fase N completada.

Estado: [APROBADO | REQUIERE_CORRECCIONES | etc.]

Hallazgos críticos: [N] — [descripción breve o "ninguno"]
Hallazgos mayores: [N]
Hallazgos menores: [N]
Criterios de aceptación: [N de N cumplidos]

Reporte completo en: .planning/fases/0N-VERIFICACION.md
```

Si hay hallazgos CRÍTICOS, lista cada uno explícitamente y pregunta:
```
Hay [N] hallazgos críticos que deben corregirse. ¿Deseas:
1. Corregirlos ahora (recomendado)
2. Continuar de todas formas y registrar como deuda técnica
3. Ver el detalle completo del reporte primero
```

Si el veredicto es **APROBADO_CON_OBSERVACIONES** (hay MAYORES pero ninguno CRÍTICO), ofrecer al usuario el flujo de corrección automatizado:

```
Veredicto: APROBADO_CON_OBSERVACIONES

Hay [N] hallazgos mayores no bloqueantes:
  [lista breve con archivo:línea por cada uno]

¿Deseas:
1. Aplicar todas las correcciones sugeridas ahora (delegar al implementador-swl
   con el VERIFICACION.md como spec — resuelve los N hallazgos en un solo slice)
2. Resolverlos selectivamente (te muestro uno a uno y decides)
3. Registrar como deuda técnica y continuar
4. Ver el detalle completo del reporte primero
```

**Comportamiento de la opción 1** (aplicar todas las correcciones automatizado):

1. Extraer cada hallazgo MAYOR del VERIFICACION.md como una tarea del slice.
2. Delegar a `implementador-swl` con un brief que incluye:
   - Ruta del VERIFICACION.md como spec primaria
   - Lista explícita de archivo:línea por cada hallazgo
   - Regla: aplicar solo las correcciones listadas, sin refactorings adicionales
3. Al terminar el implementador, ejecutar re-verificación automática (no bloqueante)
   sobre los mismos archivos para confirmar cierre de hallazgos.
4. Si la re-verificación reporta nuevos MAYORES en código tocado, escalar al usuario
   (no entrar en bucle infinito).
5. Commit atómico con mensaje `fix(verificar): resuelve N observaciones de
   fase X — <ticket/referencia VERIFICACION.md>`.

**Por qué este flujo es necesario**: hoy el usuario tras APROBADO_CON_OBSERVACIONES
debe pedir manualmente cada corrección. Eso genera fricción y olvido de observaciones
menores que se acumulan como deuda. El flujo automatizado preserva la autonomía
del usuario (opciones 2/3/4 siguen disponibles) pero ofrece la ruta feliz cuando
el usuario quiere cerrar todo el batch.

### Flag `--aplicar-iteracion=<scope>` (salta el prompt de opciones)

Cuando el usuario ya sabe qué scope quiere aplicar, el flag elimina la fricción
de 2 mensajes de ida/vuelta (veredicto → respuesta del usuario → ejecución).

**Sintaxis**:

```bash
/swl:verificar --aplicar-iteracion=urgentes
/swl:verificar --aplicar-iteracion=todo
/swl:verificar --aplicar-iteracion=custom:C2,M3,M5
```

**Interpretación por valor**:

| Valor | Alcance | Casos de uso |
|-------|---------|--------------|
| `urgentes` | CRÍTICOS + MAYORES | Default razonable para la mayoría de fases; resuelve bloqueantes sin tocar mejoras de calidad. |
| `todo` | CRÍTICOS + MAYORES + MEDIOS | Cierre completo antes de release o entrega. Aplica todo lo accionable. |
| `custom:IDs` | Solo los hallazgos con IDs listados (comas sin espacios) | Selección quirúrgica — por ejemplo, usuario quiere omitir `C1` por razones de scope: `custom:C2,C3,M1,M4`. |

**Comportamiento del flag**:

1. Ejecuta verificación completa (Pasos 1-6 estándar).
2. Genera VERIFICACION.md normalmente.
3. Si el veredicto es `APROBADO_CON_OBSERVACIONES` o `REQUIERE_CORRECCIONES`:
   - En lugar de presentar el menú de opciones, selecciona los hallazgos según el scope del flag.
   - Delega a `implementador-swl` con la lista filtrada como brief (mismo formato que opción 1 estándar).
   - Ejecuta re-verificación no bloqueante al terminar.
4. Si el veredicto es `APROBADO` o `RECHAZADO`:
   - `APROBADO`: el flag no tiene efecto (nada que aplicar).
   - `RECHAZADO`: el flag se ignora y se escala al usuario (fase con defectos críticos requiere decisión humana).

**Reglas del flag**:

- **SIEMPRE listar explícitamente** los IDs que se aplicarán antes de delegar (para que el log del comando refleje qué se está cerrando).
- **Si el scope incluye un ID que no existe** en el VERIFICACION.md, advertir pero continuar con los que sí existen.
- **`custom:` es case-sensitive** para los IDs (ej: `C2` ≠ `c2`).
- **El flag NO suprime el commit** — el mensaje `fix(verificar): resuelve N observaciones` registra la aplicación igual que el flujo manual.
- **No combinar con `--solo-codigo` o `--solo-seguridad` sin criterio**: si solo se corre un revisor, el scope `todo` o `urgentes` solo aplica a los hallazgos de ese lado.

**Ejemplo concreto**:

```bash
# Usuario quiere cerrar MAYORES y MEDIOS pero omitir C1 (que marcó como
# fuera de scope por discusión previa con el equipo):
/swl:verificar --aplicar-iteracion=custom:C2,C3,M1,M2,M3,Med1,Med2
```

El comando:
1. Corre verificación completa.
2. Al ver `APROBADO_CON_OBSERVACIONES` con 8 hallazgos incluyendo C1:
3. Selecciona los 7 IDs listados (omite C1).
4. Delega al implementador con brief que incluye solo esos 7.
5. Re-verifica. Commitea. Reporta `7 de 7 aplicados; C1 omitido por flag custom`.

**Origen**: esta funcionalidad se agregó tras observar en campo (proyecto EMAIA,
2026-04-23) que el patrón "veredicto → usuario pide X manualmente → ejecución" se
repetía 2+ veces por sesión con alta variación sobre el alcance exacto. Formalizar
con flag elimina los 2 mensajes de fricción y deja el scope auditable en el comando.

## Modo `--full` — Parallel Scorecard

Al pasar el flag `--full`, /swl:verificar lanza en paralelo 4 audits ejecutables además del flujo secuencial estándar (revisor-codigo-swl + revisor-seguridad-swl). Cada audit produce score 0-100 y findings JSON. El scorecard final agrega resultados con thresholds estándar.

### Audits paralelos invocados

| Tool | Detecta | Comando |
|---|---|---|
| `code-profiler.js` | N+1 queries, sync I/O en async, memory leaks, ReDoS, queries unbounded | `node scripts/audit-tools/code-profiler.js .` |
| `pentest-scanner.js` | XSS, SQLi, SSTI, CORS misconfig, JWT vulnerabilities, prototype pollution | `node scripts/audit-tools/pentest-scanner.js <target>` |
| `dep-doctor.js` | Deps no usadas, outdated, heavy deps con alternativa | `node scripts/audit-tools/dep-doctor.js .` |
| `secret-scanner` (hook existente) | Credenciales hardcodeadas | (vía hook) |

### Thresholds del scorecard

| Score | Status | Acción |
|---|---|---|
| ≥80 | READY | Listo para mergear |
| 60-79 | NEEDS WORK | Hallazgos menores; mergear bajo decisión informada |
| <60 | NOT READY | Hallazgos críticos; bloquear merge |

### Salida agregada

El comando produce un reporte tipo:

```
SCORECARD — Audits paralelos
─────────────────────────────────
code-profiler:    95 / 100  [READY]
pentest-scanner:  82 / 100  [READY]
dep-doctor:       70 / 100  [NEEDS WORK]
secret-scanner:  100 / 100  [READY]
─────────────────────────────────
Score promedio:   86.75     [READY]
Total findings:   3 (0 críticos, 2 mayores, 1 menor)
```

### Cuándo usar `--full` vs flujo estándar

- **Flujo estándar** (`/swl:verificar`): revisión cualitativa por agentes con criterio editorial. Adecuado para PRs pequeños/medianos donde la calidad arquitectónica importa más que cobertura mecánica.
- **Flag `--full`**: agrega análisis estático y dinámico ejecutable. Adecuado pre-release, audit de seguridad mensual, o features que tocan endpoints, dependencias o lógica compleja.

## Reglas de comportamiento

- NUNCA marques una fase como APROBADO si hay hallazgos CRÍTICOS de seguridad.
- NUNCA ejecutes correcciones de código directamente en este comando — solo identifica. Las correcciones son responsabilidad del implementador.
- Si los tests fallan, es siempre CRÍTICO, sin excepción.
- Las SUGERENCIAS son de largo plazo — no bloquean el avance pero deben documentarse.
- Si el RESUMEN.md no existe, usa git diff para inferir el alcance. Nunca te bloquees.

<!-- El patrón parallel scorecard adaptado de Houseofmvps/ultraship /ship bajo MIT License -->
