@saulwade/swl-ses 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CLAUDE.md +1 -1
  2. package/README.md +1 -1
  3. package/bin/swl-ses.js +63 -0
  4. package/comandos/swl/adoptar-proyecto.md +258 -255
  5. package/comandos/swl/aprender.md +828 -840
  6. package/comandos/swl/aprobar-plan.md +23 -35
  7. package/comandos/swl/autoresearch.md +12 -14
  8. package/comandos/swl/briefing.md +5 -8
  9. package/comandos/swl/checkpoint.md +10 -15
  10. package/comandos/swl/claudemd.md +239 -234
  11. package/comandos/swl/configurar-ci.md +20 -19
  12. package/comandos/swl/cron.md +10 -12
  13. package/comandos/swl/ejecutar-fase.md +10 -3
  14. package/comandos/swl/evolucionar.md +6 -11
  15. package/comandos/swl/inbox.md +10 -10
  16. package/comandos/swl/modelo.md +7 -9
  17. package/comandos/swl/notificaciones.md +19 -116
  18. package/comandos/swl/nuevo-proyecto.md +205 -205
  19. package/comandos/swl/status.md +333 -348
  20. package/comandos/swl/verificar.md +817 -813
  21. package/habilidades/swl-claudemd/SKILL.md +10 -6
  22. package/hooks/lib/propose-step.js +1 -0
  23. package/llms.txt +1 -1
  24. package/manifiestos/skills-lock.json +5 -5
  25. package/package.json +1 -1
  26. package/plugin.json +1 -1
  27. package/scripts/auditar-claudemd.js +38 -0
  28. package/scripts/cli/aprobar-plan.js +73 -0
  29. package/scripts/cli/briefing.js +23 -0
  30. package/scripts/cli/ciclo-evolucion.js +26 -0
  31. package/scripts/cli/configurar-ci.js +40 -0
  32. package/scripts/cli/derivar-feature-list.js +25 -0
  33. package/scripts/cli/detectar-host.js +27 -0
  34. package/scripts/cli/diary-entry.js +69 -0
  35. package/scripts/cli/execution-state.js +18 -0
  36. package/scripts/cli/gateway-notify.js +41 -0
  37. package/scripts/cli/liberar-fase.js +42 -0
  38. package/scripts/cli/loop-telemetry.js +125 -0
  39. package/scripts/cli/mark-evolved.js +56 -0
  40. package/scripts/cli/metricas-dora.js +26 -0
  41. package/scripts/cli/near-duplicate.js +55 -0
  42. package/scripts/cli/notificaciones.js +123 -0
  43. package/scripts/cli/propose-step.js +29 -0
  44. package/scripts/cli/schedule-parse.js +19 -0
  45. package/scripts/cli/sugerir-modelo.js +20 -0
  46. package/scripts/cli/verificar-plan.js +36 -0
  47. package/scripts/cli/verificar-trazabilidad.js +35 -0
  48. package/scripts/derivar-feature-list.js +1 -0
  49. package/scripts/lib/auditar-invocaciones-comandos.js +104 -0
  50. package/scripts/lib/resolver-plan-fase.js +37 -0
  51. package/scripts/validar.js +13 -0
  52. package/scripts/verificar-trazabilidad.js +1 -1
@@ -1,813 +1,817 @@
1
- ---
2
- name: swl:verificar
3
- 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).
4
- allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
5
- ---
6
-
7
- # /swl:verificar — Verificación post-ejecución
8
-
9
- 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.
10
-
11
- ## Flags del comando
12
-
13
- | Flag | Efecto |
14
- |------|--------|
15
- | (sin flag) | Verificación estándar: tests + linter + revisor-codigo-swl + revisor-seguridad-swl |
16
- | `--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`". |
17
- | `--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). |
18
- | `--solo-codigo` | Ejecuta solo revisor-codigo-swl (salta seguridad). Usar solo para refactors internos sin impacto externo. |
19
- | `--solo-seguridad` | Ejecuta solo revisor-seguridad-swl (salta código). Usar para auditorías de seguridad focalizadas. |
20
- | `--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). |
21
- | `--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`". |
22
- | `--max-iter=N` | Límite de iteraciones para `--until-converge`. Default: `5`. Rango válido: 1-10. |
23
- | `--no-prompt` | Suprime la confirmación interactiva entre pasadas (para CI). Solo aplica con `--until-converge`. |
24
- | `--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. |
25
-
26
- ### Cuándo usar `--ultra`
27
-
28
- - La fase toca código crítico: autenticación, autorización, pagos, PII, migraciones.
29
- - Hay discrepancia aparente entre los hallazgos del revisor-codigo y revisor-seguridad.
30
- - Se prepara un release mayor o se despliega a producción.
31
- - El usuario pide explícitamente "revisión profunda" o "ultrareview".
32
-
33
- **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.
34
-
35
- ### Cuándo usar `--until-converge`
36
-
37
- - La fase tiene una cola conocida de iteraciones verificar → corregir → re-verificar (≥3 manuales históricamente).
38
- - Quieres dejar el comando trabajando hasta convergencia sin re-invocar manualmente cada pasada.
39
- - Estás en CI donde no hay humano para aprobar cada batch (combinar con `--no-prompt`).
40
- - Estás cerrando una fase y quieres reducir hallazgos a 0 antes de declarar APROBADO.
41
-
42
- **Cuándo NO usar `--until-converge`**:
43
- - Cuando quieres revisar cada batch antes de aprobar correcciones (usa la verificación estándar).
44
- - Cuando esperas hallazgos que requieran decisión arquitectónica humana — el loop no debe automatizarse.
45
- - Cuando el código tocado es crítico (auth, pagos): combinar con `--ultra` para que cada pasada tenga revisión profunda.
46
-
47
- ## Paso 0 — Carga de habilidades
48
-
49
- ```
50
- Skill("verificar-trabajo")
51
- ```
52
-
53
- Carga también:
54
- ```
55
- Skill("manejo-errores")
56
- Skill("checklist-calidad")
57
- ```
58
-
59
- Si el stack tiene Python: `Skill("testing-python")`
60
- Si el stack tiene Angular: usar `@angular/core/testing` directo (sin skill dedicado)
61
-
62
- ## Paso 1 — Determinación del alcance de verificación
63
-
64
- Determina qué verificar leyendo:
65
-
66
- 1. `.planning/ESTADO.md` — identifica la fase más reciente ejecutada.
67
- 2. `.planning/fases/0N-RESUMEN.md` — lista de archivos creados y modificados.
68
- 3. `.planning/fases/0N-PLAN.md` — criterios de aceptación de la fase.
69
- 4. `git log --oneline -20` — commits de la sesión de trabajo reciente.
70
-
71
- Si no hay RESUMEN.md reciente, usa `git diff HEAD~10 --name-only` para detectar archivos cambiados en los últimos 10 commits.
72
-
73
- Anuncia al usuario el alcance:
74
- ```
75
- Verificando los cambios de la Fase N.
76
- Archivos en alcance: [número]
77
- Criterios de aceptación a verificar: [número]
78
- Tiempo estimado: [minutos]
79
- ```
80
-
81
- ## Paso 2 — Verificación técnica automatizada
82
-
83
- Antes de delegar a los agentes especializados, ejecuta verificaciones automáticas:
84
-
85
- ### 2.1 — Tests
86
- ```bash
87
- # Detectar y ejecutar el comando de tests según el stack
88
- # Python con pytest:
89
- pytest --tb=short -q
90
-
91
- # Node/Angular:
92
- npm test -- --watchAll=false --passWithNoTests
93
-
94
- # Reportar: cuántos pasan, cuántos fallan, cobertura si está configurada
95
- ```
96
-
97
- Si hay tests fallando, registra cada uno con su error exacto. Los tests fallando son severidad CRÍTICA.
98
-
99
- ### 2.2 — Linter y format
100
- ```bash
101
- # Python
102
- ruff check . --output-format=concise 2>/dev/null || flake8 --max-line-length=120 . 2>/dev/null
103
-
104
- # TypeScript/JavaScript
105
- npx eslint src/ --format=compact 2>/dev/null
106
- ```
107
-
108
- ### 2.3 — Type checking
109
- ```bash
110
- # Python
111
- mypy . --ignore-missing-imports --no-error-summary 2>/dev/null
112
-
113
- # TypeScript
114
- npx tsc --noEmit 2>/dev/null
115
- ```
116
-
117
- ### 2.4 — Archivos de debug olvidados
118
-
119
- Busca patrones de debug que no deben ir a producción:
120
-
121
- ```
122
- Grep(pattern="console\.log|print\(|debugger|pdb\.set_trace|breakpoint\(\)", output_mode="content")
123
- Grep(pattern="TODO|FIXME|HACK|XXX", output_mode="content")
124
- ```
125
-
126
- Registra todos los hallazgos con archivo y línea.
127
-
128
- ### 2.5 — Verificación de commits
129
-
130
- ```bash
131
- git log --oneline -20
132
- ```
133
-
134
- Verifica que los mensajes de commit siguen la convención del proyecto (si está definida en CLAUDE.md).
135
-
136
- ## Paso 3 — Delegación al revisor-codigo-swl
137
-
138
- Delega al agente `revisor-codigo-swl` para revisión de código en profundidad.
139
-
140
- **Presupuesto de contexto (anti-thrashing):** el subagente hereda `CLAUDE.md` +
141
- reglas globales del proyecto; en proyectos rule-heavy eso consume buena parte de
142
- su ventana antes de leer código (causa de autocompact thrashing con 0 tokens
143
- útiles, observado 2026-06-05). Para evitarlo:
144
- - Pasa al agente SOLO el diff / los archivos del alcance — nunca "revisa el proyecto".
145
- - Instruye leer los archivos del alcance PRIMERO y cargar skills bajo demanda (solo
146
- si el alcance lo amerita), no al inicio.
147
- - Si el alcance > ~15 archivos o > ~2000 LOC, divídelo en lotes y delega uno por
148
- invocación (cada subagente arranca con ventana limpia).
149
-
150
- **Instrucción al agente revisor-codigo-swl:**
151
-
152
- ```
153
- Revisa SOLO los archivos del alcance de la Fase N del proyecto [nombre].
154
- No explores el codebase completo: tu ventana ya hereda CLAUDE.md + reglas
155
- globales; lee primero los archivos del alcance para no saturarla.
156
-
157
- Archivos a revisar (en orden de prioridad):
158
- [lista del RESUMEN.md / git diff del alcance]
159
-
160
- Lee también (solo lo necesario, bajo demanda):
161
- - .planning/fases/0N-CONTEXTO.md (requisitos)
162
- - .planning/fases/0N-PLAN.md (qué se debía hacer)
163
- (CLAUDE.md ya está en tu contexto heredado — no lo releas.)
164
-
165
- Para cada archivo revisado, verifica:
166
-
167
- 1. LÓGICA DE NEGOCIO
168
- - ¿La implementación cumple los requisitos del CONTEXTO.md?
169
- - ¿Los casos borde están manejados?
170
- - ¿Hay lógica duplicada que debería estar centralizada?
171
-
172
- 2. CALIDAD DEL CÓDIGO
173
- - ¿Las funciones tienen responsabilidad única?
174
- - ¿Los nombres de variables y funciones son descriptivos?
175
- - ¿El código es comprensible sin comentarios extensos?
176
- - ¿Hay funciones o clases demasiado largas (>50 líneas en funciones, >300 en clases)?
177
-
178
- 3. MANEJO DE ERRORES
179
- - ¿Todos los caminos de error están manejados explícitamente?
180
- - ¿Los errores se loguean con suficiente contexto?
181
- - ¿No hay excepciones capturadas y silenciadas?
182
-
183
- 4. TESTS
184
- - ¿Cada función pública tiene al menos un test?
185
- - ¿Los tests cubren caminos feliz y caminos de error?
186
- - ¿Los tests son deterministas (no dependen de tiempo o datos externos sin mock)?
187
-
188
- Reporta cada hallazgo con:
189
- - Archivo y línea
190
- - Severidad: CRÍTICO | MAYOR | MENOR | SUGERENCIA
191
- - Descripción del problema
192
- - Corrección recomendada
193
- ```
194
-
195
- ## Paso 4 — Delegación al revisor-seguridad-swl
196
-
197
- Delega al agente `revisor-seguridad-swl` en paralelo (si es posible) o secuencialmente:
198
-
199
- **Instrucción al agente revisor-seguridad-swl:**
200
-
201
- ```
202
- Revisa la seguridad del código de la Fase N del proyecto [nombre].
203
-
204
- Archivos a revisar:
205
- [lista del RESUMEN.md]
206
-
207
- Verifica específicamente:
208
-
209
- 1. AUTENTICACIÓN Y AUTORIZACIÓN
210
- - ¿Todos los endpoints protegidos verifican autenticación?
211
- - ¿Los endpoints de escritura (POST/PUT/DELETE) verifican roles?
212
- - ¿Hay protección contra IDOR (acceso a recursos de otros usuarios)?
213
-
214
- 2. VALIDACIÓN DE ENTRADAS
215
- - ¿Se validan todos los inputs del usuario antes de usarlos?
216
- - ¿Hay protección contra inyección SQL, XSS, command injection?
217
- - ¿Los campos tienen restricciones de longitud y formato?
218
-
219
- 3. DATOS SENSIBLES
220
- - ¿Hay credenciales, tokens o secrets hardcodeados en el código?
221
- - ¿Los logs no exponen datos personales o sensibles?
222
- - ¿Los mensajes de error no revelan información interna del sistema?
223
-
224
- 4. DEPENDENCIAS
225
- - ¿Hay dependencias con vulnerabilidades conocidas?
226
- - ¿Se usan versiones específicas en el lockfile?
227
-
228
- 5. CONFIGURACIÓN
229
- - ¿Las variables de entorno tienen valores seguros por defecto?
230
- - ¿El modo debug está desactivado en configuración de producción?
231
-
232
- Reporta con:
233
- - Archivo y línea
234
- - Severidad: CRÍTICO | ALTO | MEDIO | BAJO
235
- - CVE o categoría OWASP si aplica
236
- - Corrección específica recomendada
237
- ```
238
-
239
- ## Paso 4.5 — Pasada `--ultra` (solo si flag activo)
240
-
241
- 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.
242
-
243
- **Instrucción para la pasada ultra:**
244
-
245
- Invoca un nuevo contexto de revisor-codigo-swl (o un sub-agente dedicado) con este prompt específico:
246
-
247
- ```
248
- Eres el revisor senior de la pasada --ultra de /swl:verificar.
249
-
250
- Tienes en input:
251
- - HALLAZGOS_CODIGO: [hallazgos del revisor-codigo-swl, Paso 3]
252
- - HALLAZGOS_SEGURIDAD: [hallazgos del revisor-seguridad-swl, Paso 4]
253
- - PLAN y CONTEXTO de la fase (ya cargados)
254
-
255
- Tu tarea es:
256
-
257
- 1. CONSOLIDAR. Identifica hallazgos duplicados entre ambos reviewers y
258
- fúsionalos en una sola entrada con la severidad más alta.
259
-
260
- 2. DETECTAR CONTRADICCIONES. Si un reviewer aprueba algo que el otro
261
- rechaza, marca la contradicción explícitamente y argumenta cuál es
262
- la postura correcta según el contexto del proyecto.
263
-
264
- 3. PRIORIZAR. Ordena los hallazgos por impacto real (no solo severidad
265
- nominal). Un "MAYOR" en código que toca pagos supera a un "CRÍTICO"
266
- en código muerto.
267
-
268
- 4. DETECTAR HALLAZGOS OMITIDOS. Con visión completa de ambos reports,
269
- identifica problemas que ninguno detectó individualmente — especialmente:
270
- - Interacciones peligrosas entre módulos que cada reviewer vio aisladamente
271
- - Inconsistencias entre la especificación y la implementación
272
- - Patrones de deuda técnica que afectan más de un módulo
273
-
274
- 5. GENERAR PLAN DE ACCIÓN. Lista ordenada de correcciones con:
275
- - Archivo y línea
276
- - Acción específica
277
- - Dependencia con otras correcciones
278
- - Estimación de tiempo
279
- - Si requiere decisión del arquitecto o planificador
280
-
281
- 6. VEREDICTO FINAL: APROBADO / APROBADO_CON_OBSERVACIONES / REQUIERE_CORRECCIONES / RECHAZADO.
282
-
283
- NO ejecutes correcciones — solo identificas y priorizas. Tu output se
284
- integra al VERIFICACION.md del Paso 6.
285
- ```
286
-
287
- 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.
288
-
289
- ## Paso 4.6 — Bucle de convergencia (solo si `--until-converge` activo)
290
-
291
- 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.
292
-
293
- ### 4.6.1 — Criterio de salida por convergencia
294
-
295
- El loop se detiene cuando se cumple **cualquiera** de estas señales (la primera que ocurra):
296
-
297
- | Señal | Criterio | Razón |
298
- |-------|----------|-------|
299
- | **A — éxito** | La pasada N produce 0 hallazgos nuevos de severidad `CRÍTICO`, `ALTO` o `MAYOR` | Convergencia natural — la fase está limpia |
300
- | **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 |
301
- | **C — máximo** | Se alcanza `--max-iter=N` (default 5) sin converger | No-convergente; reportar al usuario |
302
- | **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) |
303
-
304
- Los hallazgos `MEDIO`, `BAJO` y `SUGERENCIA` no rompen convergencia — se acumulan como deuda técnica documentada.
305
-
306
- **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:
307
- - Migraciones aplicadas a BD limpia (CI fresh) vs BD productiva (donde seeds ya corrieron).
308
- - Seeds dependientes que fallan en cadena por orden migración↔seed invertido.
309
- - Tests E2E que requieren datos demo.
310
- - Partial unique indexes con `WHERE` que no son predicado puro (rompen en CI fresh).
311
-
312
- 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.
313
-
314
- ### 4.6.2 — Control de pausa entre iteraciones
315
-
316
- Antes de invocar al implementador para aplicar correcciones de la pasada N, el comando muestra un resumen y permite al usuario decidir:
317
-
318
- ```
319
- Pasada N completada: [X] hallazgos CRÍTICO + [Y] ALTO + [Z] MAYOR
320
-
321
- Próximo: aplicar correcciones y ejecutar pasada N+1.
322
-
323
- [c] continuar a pasada N+1 (default tras 30s)
324
- [p] pausar — mostrar reporte completo de la pasada N y esperar input
325
- [q] cancelar — mantener correcciones aplicadas hasta ahora, salir del loop
326
- ```
327
-
328
- Sin respuesta en 30s: continúa automáticamente con `c` (default).
329
-
330
- 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.
331
-
332
- ### 4.6.3 — Detección de loop adversarial
333
-
334
- 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:
335
-
336
- - La pasada N+1 introduce **≥5 hallazgos NUEVOS** (signature distinto) sobre archivos que se modificaron entre pasadas N y N+1, **escalar al usuario**:
337
-
338
- ```
339
- Pasada N+1 detectó N hallazgos nuevos sobre código que se acaba de corregir.
340
- Las correcciones de la pasada N pueden estar introduciendo regresión.
341
-
342
- Hallazgos nuevos:
343
- [lista breve archivo:línea]
344
-
345
- ¿Continuar (c), pausar para inspección (p), o abortar el loop (q)?
346
- ```
347
-
348
- Esto NO es lo mismo que la pausa estándar — es una alerta explícita por adversarialidad.
349
-
350
- ### 4.6.4 — Compatibilidad con otros flags
351
-
352
- | Combinación | Comportamiento |
353
- |-------------|----------------|
354
- | `--until-converge --ultra` | Cada pasada ejecuta la consolidación profunda (Paso 4.5). Más caro, más sólido. |
355
- | `--until-converge --solo-codigo` | El loop se itera solo sobre revisor-codigo-swl. Convergencia ignora hallazgos de seguridad. |
356
- | `--until-converge --solo-seguridad` | El loop se itera solo sobre revisor-seguridad-swl. |
357
- | `--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. |
358
- | `--until-converge --no-prompt` | Pasadas sin pausa interactiva — adecuado para CI. La detección adversarial sigue activa y aborta si se dispara. |
359
-
360
- ### 4.6.5 — Estado de convergencia persistido
361
-
362
- Entre iteraciones se mantiene `.planning/fases/0N-converge-state.json`:
363
-
364
- ```json
365
- {
366
- "fase": "0N",
367
- "session_id": "...",
368
- "iniciado_at": "ISO timestamp",
369
- "max_iter": 5,
370
- "no_prompt": false,
371
- "iteraciones": [
372
- {
373
- "n": 1,
374
- "criticos": 3, "altos": 5, "mayores": 9, "medios": 4, "bajos": 2,
375
- "hallazgos_signatures": ["sha256(archivo+linea+regla)", ...],
376
- "archivos_corregidos": ["..."],
377
- "duracion_ms": 124000
378
- }
379
- ],
380
- "convergencia": null,
381
- "razon_salida": null
382
- }
383
- ```
384
-
385
- Al terminar el loop se anexa `convergencia` y `razon_salida` y se renombra a `0N-converge-run-[timestamp].json` para mantener historia.
386
-
387
- ### 4.6.6 — Integración al VERIFICACION.md final
388
-
389
- El VERIFICACION.md reportado al usuario al final del loop incluye una sección al inicio:
390
-
391
- ```markdown
392
- ## Resumen del modo --until-converge
393
-
394
- - Pasadas ejecutadas: K / max=5
395
- - Convergencia: alcanzada en pasada K | no-alcanzada (límite max-iter) | abortada (loop adversarial) | abortada por usuario
396
- - Razón de salida: [descripción]
397
- - Hallazgos por pasada:
398
- | Pasada | CRÍTICO | ALTO | MAYOR | MEDIO | BAJO |
399
- |--------|---------|------|-------|-------|------|
400
- | 1 | 3 | 5 | 9 | 4 | 2 |
401
- | 2 | 0 | 1 | 3 | 2 | 1 |
402
- | 3 | 0 | 0 | 0 | 2 | 1 |
403
- - Estado persistido: `.planning/fases/0N-converge-run-[timestamp].json`
404
- ```
405
-
406
- ### 4.6.7 — Telemetría de loop (obligatoria en `--until-converge`)
407
-
408
- Además del estado estructurado de 4.6.5, cada corrida del loop registra su
409
- trayectoria en el formato estándar de telemetría de loops
410
- (`hooks/lib/loop-telemetry.js`), que habilita: inyección de estado por el hook
411
- `contexto-iteracion.js` (anti-context-rot en sesiones largas), detección de
412
- plateau, y lectura por `/swl:status metricas`.
413
-
414
- Al iniciar el loop (antes de la pasada 1):
415
-
416
- ```bash
417
- 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)"
418
- ```
419
-
420
- Tras CADA pasada, registrar una fila (métrica = hallazgos CRÍTICO+ALTO+MAYOR):
421
-
422
- ```bash
423
- 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'})"
424
- ```
425
-
426
- Al cerrar el loop (cualquier señal de salida), escribir el handoff:
427
-
428
- ```bash
429
- 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'}})"
430
- ```
431
-
432
- `status` según la señal: A/D → `COMPLETO`, B → `INTERRUMPIDO`, C → `ACOTADO`.
433
- Si `analizarTrayectoria()` reporta plateau antes de `--max-iter`, tratarlo como
434
- señal C anticipada: seguir iterando sin mejora de métrica quema tokens sin
435
- reducir hallazgos.
436
-
437
- ### 4.6.8 Protocolo `--ci-aware` (Señal D)
438
-
439
- Cuando `--ci-aware` está activo, el bucle de convergencia se extiende con un gate adicional ANTES de declarar Señal A como cierre definitivo:
440
-
441
- **Precondición**: el último commit de la pasada N debe estar pusheado a la rama remota. Si no:
442
-
443
- ```
444
- Pasada N converge natural pero --ci-aware requiere CI sobre HEAD pushed.
445
-
446
- HEAD local: abc1234 (no pusheado)
447
- [p] push automático + monitor CI
448
- [c] continuar sin --ci-aware (convergencia solo local)
449
- [q] abortar — pushear manualmente y re-invocar
450
- ```
451
-
452
- Con `--no-prompt`: default es `p` (push automático).
453
-
454
- **Algoritmo de espera**:
455
-
456
- 1. Tras Señal A, obtener SHA actual de `HEAD` y ejecutar `git ls-remote origin <rama>` para confirmar que está sincronizado.
457
- 2. Listar workflows aplicables al SHA con:
458
- ```bash
459
- gh run list --branch <rama> --limit 10 \
460
- --json status,conclusion,name,headSha \
461
- --jq '.[] | select(.headSha == "<SHA>")'
462
- ```
463
- 3. Esperar usando la regla global `monitor-ci.md` (patrón Monitor con `gh --jq`, NO `| jq`).
464
- 4. Clasificar resultado:
465
- - **Todos `completed`+`success`** Señal D confirmada, convergencia válida.
466
- - **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.
467
- - **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`.
468
- - **Workflows aún en `in_progress` después del timeout configurado en monitor-ci** → escalar al usuario, no cerrar convergencia.
469
-
470
- **Workflows aplicables vs no aplicables**:
471
-
472
- `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.
473
-
474
- El gate solo evalúa workflows que ** se dispararon en el SHA**. La verificación es:
475
-
476
- ```bash
477
- gh run list --branch <rama> --limit 10 --json headSha,name,status,conclusion \
478
- --jq '[.[] | select(.headSha | startswith("<sha-corto>"))] | all(.[]; .status == "completed" and .conclusion == "success")'
479
- ```
480
-
481
- Output `true` Señal D. `false` con detalle reabrir loop.
482
-
483
- **Anti-patrones explícitos**:
484
-
485
- - **Tratar timeout del monitor como "verde por default"**: el timeout significa "estado desconocido", NO `success`. Re-armar monitor o escalar al usuario.
486
- - **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/)".
487
- - **Asumir verde porque `git push` retornó exit 0**: push exitoso ≠ CI verde. push solo confirma que GitHub aceptó el push.
488
-
489
- Origen: regla global `monitor-ci.md` cubre este protocolo en detalle. Esta sección lo activa específicamente para `/swl:verificar`.
490
-
491
- ### 4.6.8 Backward compatibility
492
-
493
- 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.
494
-
495
- ## Paso 5 Verificación de criterios de aceptación
496
-
497
- ### 5.0 Trazabilidad REQ→T→commit→test (si el CONTEXTO tiene REQ-IDs)
498
-
499
- Si la sección de criterios del CONTEXTO usa IDs `REQ-NN:` (fases 10-11) o
500
- `REQ-<fase>-NN:` (namespaceados, fases ≥12), ejecuta el validador de cadena
501
- ANTES de la verificación criterio por criterio:
502
-
503
- ```bash
504
- node scripts/verificar-trazabilidad.js --fase=N
505
- ```
506
-
507
- - Exit 0 → cadena completa; adjunta la tabla REQ→tareas/commits/tests al VERIFICACION.md.
508
- - Exit 1 → **cada REQ huérfano es hallazgo CRÍTICO** (requisito sin implementar,
509
- sin commit trazable o sin test que lo verifique). Listarlos en el VERIFICACION.md
510
- con la dirección del gap (sin tarea / sin commit / sin test).
511
- - Exit 2error de invocación; reportar sin bloquear el resto de la verificación.
512
-
513
- En CONTEXTOs legacy sin REQ-IDs el script sale 0 con nota — continuar normal.
514
-
515
- ### 5.0b Contract testing (si la fase declaró schemas en el PLAN)
516
-
517
- Si el PLAN declara schemas (Pydantic/Zod/JSON Schema/OpenAPI) o la fase expone
518
- una API consumida por otro componente, cargar `Skill("calidad-contract-testing")`
519
- y verificar que la implementación honra el contrato (schema-based con
520
- schemathesis/Dredd contra la API real, o validación de forma con el modelo en
521
- el test de integración). Cada violación de contrato = hallazgo CRÍTICO.
522
-
523
- Lee los criterios de aceptación del `.planning/fases/0N-CONTEXTO.md` y verifica cada uno:
524
-
525
- Para cada criterio:
526
- 1. Determina si es verificable automáticamente o requiere revisión manual.
527
- 2. Si es automático: ejecuta la verificación y registra el resultado.
528
- 3. Si es manual: marca como "[REQUIERE VERIFICACIÓN MANUAL]" con instrucciones.
529
-
530
- Ejemplo de tabla de verificación:
531
- ```
532
- | Criterio | Método | Resultado |
533
- |---------|--------|----------|
534
- | El usuario puede crear una cuenta | Test e2e / manual | PASA / FALLA / PENDIENTE |
535
- ```
536
-
537
- ### Smoke test manual obligatorio para módulos frontend grandes
538
-
539
- Origen: SIGAF sesión 2026-05-21 (mejora D2). Cuando el alcance de la
540
- verificación toca un **componente frontend > 2,000 LOC** (típicamente módulos
541
- como `/catalogos`, `/contratos`, `/expedientes` que crecen orgánicamente), la
542
- verificación automática NO es suficiente. Los tests unitarios pueden pasar y
543
- el linter quedar limpio mientras el componente está **roto en el render
544
- real** (estado inicial mal calculado, evento que no propaga, route guard que
545
- redirige en loop, error de hidratación SSR que solo aparece en producción).
546
-
547
- Reglas duras para esta sub-categoría:
548
-
549
- 1. **Detección automática del trigger**: si el revisor de código reporta
550
- ≥1 archivo en `frontend/` con LOC > 2000, OR la suma de LOC de archivos
551
- modificados en el último commit en `frontend/` excede 1500, activar este
552
- sub-paso.
553
-
554
- 2. **Smoke test manual obligatorio**: el VERIFICACION.md DEBE incluir un
555
- bloque `## Smoke test manual (módulo frontend grande)` con los siguientes
556
- checks que el usuario humano marca PASA/FALLA antes del merge:
557
-
558
- ```markdown
559
- ## Smoke test manual frontend/<modulo> (X LOC)
560
-
561
- - [ ] Arranca el dev server sin errores en consola
562
- - [ ] Renderiza la pantalla principal del módulo sin pantalla blanca
563
- - [ ] Navegación a cada sub-ruta funciona (listar nombres)
564
- - [ ] Acciones CRUD principales completan flujo end-to-end
565
- - [ ] No hay warnings de hidratación en consola (SSR si aplica)
566
- - [ ] Layout responsive funciona en viewport mobile + desktop
567
- - [ ] [Si aplica] Web vitals sin regresión vs commit anterior
568
- ```
569
-
570
- 3. **NO marcar verificación como APROBADA** hasta que el bloque esté completo
571
- o el usuario explícitamente exente checks específicos con justificación.
572
-
573
- 4. **El comando NO ejecuta el smoke automáticamente** (requiere browser
574
- humano); su responsabilidad es **incluir el bloque en VERIFICACION.md** y
575
- marcar la decisión de verificación como `APROBADO_CON_OBSERVACIONES`
576
- hasta que el bloque se cierre.
577
-
578
- **Cuándo NO aplicar este sub-paso**:
579
-
580
- - Módulos backend puros (cobertura suficiente con tests de integración).
581
- - Cambios cosméticos a componentes frontend grandes (typo en texto, ajuste
582
- de color de un botón) — la heurística LOC sigue disparándose pero el
583
- usuario puede exentar con `[exento: cambio cosmético en X líneas]`.
584
- - Módulos con cobertura E2E > 70% probada (webapp-testing, Playwright,
585
- Cypress) el smoke automático cubre la necesidad.
586
-
587
- ## Paso 6 Consolidación y generación del VERIFICACION.md
588
-
589
- Consolida todos los hallazgos en `.planning/fases/0N-VERIFICACION.md`:
590
-
591
- ```markdown
592
- # Reporte de verificación — Fase N: [nombre]
593
-
594
- **Proyecto**: [nombre]
595
- **Fecha de verificación**: [fecha]
596
- **Verificado por**: swl:verificar + revisor-codigo-swl + revisor-seguridad-swl
597
- **Estado general**: APROBADO | APROBADO_CON_OBSERVACIONES | REQUIERE_CORRECCIONES | RECHAZADO
598
-
599
- ## Resumen ejecutivo
600
-
601
- | Categoría | CRÍTICO | MAYOR | MENOR | SUGERENCIA |
602
- |-----------|---------|-------|-------|-----------|
603
- | Tests | N | N | N | N |
604
- | Código | N | N | N | N |
605
- | Seguridad | N | N | N | N |
606
- | **Total** | **N** | **N** | **N** | **N** |
607
-
608
- ## Criterios de aceptación
609
-
610
- [tabla del Paso 5]
611
-
612
- ## Hallazgos por categoría
613
-
614
- ### Tests automatizados
615
- [resultados del Paso 2.1]
616
-
617
- ### Calidad de código
618
- [hallazgos del revisor-codigo-swl]
619
-
620
- ### Seguridad
621
- [hallazgos del revisor-seguridad-swl]
622
-
623
- ### Issues menores y sugerencias
624
- [lista]
625
-
626
- ## Acciones requeridas antes del deploy
627
-
628
- [solo los CRÍTICO y MAYOR — ordenados por prioridad]
629
-
630
- 1. [ ] [acción específica con archivo y línea]
631
- 2. [ ] [acción específica]
632
-
633
- ## Decisión de verificación
634
-
635
- **APROBADO**: No hay hallazgos CRÍTICO ni MAYOR. La fase puede avanzar.
636
- **APROBADO_CON_OBSERVACIONES**: Hay MAYOR pero no bloquea el avance inmediato. Resolver en la siguiente iteración.
637
- **REQUIERE_CORRECCIONES**: Hay hallazgos CRÍTICO que deben resolverse antes de deploy.
638
- **RECHAZADO**: La implementación no cumple los criterios de aceptación fundamentales.
639
- ```
640
-
641
- ## Paso 7 Reporte al usuario
642
-
643
- Reporta el resultado de verificación al usuario con formato claro:
644
-
645
- ```
646
- Verificación de la Fase N completada.
647
-
648
- Estado: [APROBADO | REQUIERE_CORRECCIONES | etc.]
649
-
650
- Hallazgos críticos: [N] [descripción breve o "ninguno"]
651
- Hallazgos mayores: [N]
652
- Hallazgos menores: [N]
653
- Criterios de aceptación: [N de N cumplidos]
654
-
655
- Reporte completo en: .planning/fases/0N-VERIFICACION.md
656
- ```
657
-
658
- Si hay hallazgos CRÍTICOS, lista cada uno explícitamente y pregunta:
659
- ```
660
- Hay [N] hallazgos críticos que deben corregirse. ¿Deseas:
661
- 1. Corregirlos ahora (recomendado)
662
- 2. Continuar de todas formas y registrar como deuda técnica
663
- 3. Ver el detalle completo del reporte primero
664
- ```
665
-
666
- Si el veredicto es **APROBADO_CON_OBSERVACIONES** (hay MAYORES pero ninguno CRÍTICO), ofrecer al usuario el flujo de corrección automatizado:
667
-
668
- ```
669
- Veredicto: APROBADO_CON_OBSERVACIONES
670
-
671
- Hay [N] hallazgos mayores no bloqueantes:
672
- [lista breve con archivo:línea por cada uno]
673
-
674
- ¿Deseas:
675
- 1. Aplicar todas las correcciones sugeridas ahora (delegar al implementador-swl
676
- con el VERIFICACION.md como spec resuelve los N hallazgos en un solo slice)
677
- 2. Resolverlos selectivamente (te muestro uno a uno y decides)
678
- 3. Registrar como deuda técnica y continuar
679
- 4. Ver el detalle completo del reporte primero
680
- ```
681
-
682
- **Comportamiento de la opción 1** (aplicar todas las correcciones automatizado):
683
-
684
- 1. Extraer cada hallazgo MAYOR del VERIFICACION.md como una tarea del slice.
685
- 2. Delegar a `implementador-swl` con un brief que incluye:
686
- - Ruta del VERIFICACION.md como spec primaria
687
- - Lista explícita de archivo:línea por cada hallazgo
688
- - Regla: aplicar solo las correcciones listadas, sin refactorings adicionales
689
- 3. Al terminar el implementador, ejecutar re-verificación automática (no bloqueante)
690
- sobre los mismos archivos para confirmar cierre de hallazgos.
691
- 4. Si la re-verificación reporta nuevos MAYORES en código tocado, escalar al usuario
692
- (no entrar en bucle infinito).
693
- 5. Commit atómico con mensaje `fix(verificar): resuelve N observaciones de
694
- fase X <ticket/referencia VERIFICACION.md>`.
695
-
696
- **Por qué este flujo es necesario**: hoy el usuario tras APROBADO_CON_OBSERVACIONES
697
- debe pedir manualmente cada corrección. Eso genera fricción y olvido de observaciones
698
- menores que se acumulan como deuda. El flujo automatizado preserva la autonomía
699
- del usuario (opciones 2/3/4 siguen disponibles) pero ofrece la ruta feliz cuando
700
- el usuario quiere cerrar todo el batch.
701
-
702
- ### Flag `--aplicar-iteracion=<scope>` (salta el prompt de opciones)
703
-
704
- Cuando el usuario ya sabe qué scope quiere aplicar, el flag elimina la fricción
705
- de 2 mensajes de ida/vuelta (veredicto → respuesta del usuario → ejecución).
706
-
707
- **Sintaxis**:
708
-
709
- ```bash
710
- /swl:verificar --aplicar-iteracion=urgentes
711
- /swl:verificar --aplicar-iteracion=todo
712
- /swl:verificar --aplicar-iteracion=custom:C2,M3,M5
713
- ```
714
-
715
- **Interpretación por valor**:
716
-
717
- | Valor | Alcance | Casos de uso |
718
- |-------|---------|--------------|
719
- | `urgentes` | CRÍTICOS + MAYORES | Default razonable para la mayoría de fases; resuelve bloqueantes sin tocar mejoras de calidad. |
720
- | `todo` | CRÍTICOS + MAYORES + MEDIOS | Cierre completo antes de release o entrega. Aplica todo lo accionable. |
721
- | `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`. |
722
-
723
- **Comportamiento del flag**:
724
-
725
- 1. Ejecuta verificación completa (Pasos 1-6 estándar).
726
- 2. Genera VERIFICACION.md normalmente.
727
- 3. Si el veredicto es `APROBADO_CON_OBSERVACIONES` o `REQUIERE_CORRECCIONES`:
728
- - En lugar de presentar el menú de opciones, selecciona los hallazgos según el scope del flag.
729
- - Delega a `implementador-swl` con la lista filtrada como brief (mismo formato que opción 1 estándar).
730
- - Ejecuta re-verificación no bloqueante al terminar.
731
- 4. Si el veredicto es `APROBADO` o `RECHAZADO`:
732
- - `APROBADO`: el flag no tiene efecto (nada que aplicar).
733
- - `RECHAZADO`: el flag se ignora y se escala al usuario (fase con defectos críticos requiere decisión humana).
734
-
735
- **Reglas del flag**:
736
-
737
- - **SIEMPRE listar explícitamente** los IDs que se aplicarán antes de delegar (para que el log del comando refleje qué se está cerrando).
738
- - **Si el scope incluye un ID que no existe** en el VERIFICACION.md, advertir pero continuar con los que sí existen.
739
- - **`custom:` es case-sensitive** para los IDs (ej: `C2` ≠ `c2`).
740
- - **El flag NO suprime el commit** — el mensaje `fix(verificar): resuelve N observaciones` registra la aplicación igual que el flujo manual.
741
- - **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.
742
-
743
- **Ejemplo concreto**:
744
-
745
- ```bash
746
- # Usuario quiere cerrar MAYORES y MEDIOS pero omitir C1 (que marcó como
747
- # fuera de scope por discusión previa con el equipo):
748
- /swl:verificar --aplicar-iteracion=custom:C2,C3,M1,M2,M3,Med1,Med2
749
- ```
750
-
751
- El comando:
752
- 1. Corre verificación completa.
753
- 2. Al ver `APROBADO_CON_OBSERVACIONES` con 8 hallazgos incluyendo C1:
754
- 3. Selecciona los 7 IDs listados (omite C1).
755
- 4. Delega al implementador con brief que incluye solo esos 7.
756
- 5. Re-verifica. Commitea. Reporta `7 de 7 aplicados; C1 omitido por flag custom`.
757
-
758
- **Origen**: esta funcionalidad se agregó tras observar en campo (proyecto EMAIA,
759
- 2026-04-23) que el patrón "veredicto usuario pide X manualmente → ejecución" se
760
- repetía 2+ veces por sesión con alta variación sobre el alcance exacto. Formalizar
761
- con flag elimina los 2 mensajes de fricción y deja el scope auditable en el comando.
762
-
763
- ## Modo `--full` Parallel Scorecard
764
-
765
- 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.
766
-
767
- ### Audits paralelos invocados
768
-
769
- | Tool | Detecta | Comando |
770
- |---|---|---|
771
- | `code-profiler.js` | N+1 queries, sync I/O en async, memory leaks, ReDoS, queries unbounded | `node scripts/audit-tools/code-profiler.js .` |
772
- | `pentest-scanner.js` | XSS, SQLi, SSTI, CORS misconfig, JWT vulnerabilities, prototype pollution | `node scripts/audit-tools/pentest-scanner.js <target>` |
773
- | `dep-doctor.js` | Deps no usadas, outdated, heavy deps con alternativa | `node scripts/audit-tools/dep-doctor.js .` |
774
- | `secret-scanner` (hook existente) | Credenciales hardcodeadas | (vía hook) |
775
-
776
- ### Thresholds del scorecard
777
-
778
- | Score | Status | Acción |
779
- |---|---|---|
780
- | ≥80 | READY | Listo para mergear |
781
- | 60-79 | NEEDS WORK | Hallazgos menores; mergear bajo decisión informada |
782
- | <60 | NOT READY | Hallazgos críticos; bloquear merge |
783
-
784
- ### Salida agregada
785
-
786
- El comando produce un reporte tipo:
787
-
788
- ```
789
- SCORECARD — Audits paralelos
790
- ─────────────────────────────────
791
- code-profiler: 95 / 100 [READY]
792
- pentest-scanner: 82 / 100 [READY]
793
- dep-doctor: 70 / 100 [NEEDS WORK]
794
- secret-scanner: 100 / 100 [READY]
795
- ─────────────────────────────────
796
- Score promedio: 86.75 [READY]
797
- Total findings: 3 (0 críticos, 2 mayores, 1 menor)
798
- ```
799
-
800
- ### Cuándo usar `--full` vs flujo estándar
801
-
802
- - **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.
803
- - **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.
804
-
805
- ## Reglas de comportamiento
806
-
807
- - NUNCA marques una fase como APROBADO si hay hallazgos CRÍTICOS de seguridad.
808
- - NUNCA ejecutes correcciones de código directamente en este comando — solo identifica. Las correcciones son responsabilidad del implementador.
809
- - Si los tests fallan, es siempre CRÍTICO, sin excepción.
810
- - Las SUGERENCIAS son de largo plazo — no bloquean el avance pero deben documentarse.
811
- - Si el RESUMEN.md no existe, usa git diff para inferir el alcance. Nunca te bloquees.
812
-
813
- <!-- El patrón parallel scorecard adaptado de Houseofmvps/ultraship /ship bajo MIT License -->
1
+ ---
2
+ name: swl:verificar
3
+ 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).
4
+ allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
5
+ ---
6
+
7
+ # /swl:verificar — Verificación post-ejecución
8
+
9
+ 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.
10
+
11
+ ## Flags del comando
12
+
13
+ | Flag | Efecto |
14
+ |------|--------|
15
+ | (sin flag) | Verificación estándar: tests + linter + revisor-codigo-swl + revisor-seguridad-swl |
16
+ | `--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`". |
17
+ | `--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). |
18
+ | `--solo-codigo` | Ejecuta solo revisor-codigo-swl (salta seguridad). Usar solo para refactors internos sin impacto externo. |
19
+ | `--solo-seguridad` | Ejecuta solo revisor-seguridad-swl (salta código). Usar para auditorías de seguridad focalizadas. |
20
+ | `--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). |
21
+ | `--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`". |
22
+ | `--max-iter=N` | Límite de iteraciones para `--until-converge`. Default: `5`. Rango válido: 1-10. |
23
+ | `--no-prompt` | Suprime la confirmación interactiva entre pasadas (para CI). Solo aplica con `--until-converge`. |
24
+ | `--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. |
25
+
26
+ ### Cuándo usar `--ultra`
27
+
28
+ - La fase toca código crítico: autenticación, autorización, pagos, PII, migraciones.
29
+ - Hay discrepancia aparente entre los hallazgos del revisor-codigo y revisor-seguridad.
30
+ - Se prepara un release mayor o se despliega a producción.
31
+ - El usuario pide explícitamente "revisión profunda" o "ultrareview".
32
+
33
+ **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.
34
+
35
+ ### Cuándo usar `--until-converge`
36
+
37
+ - La fase tiene una cola conocida de iteraciones verificar → corregir → re-verificar (≥3 manuales históricamente).
38
+ - Quieres dejar el comando trabajando hasta convergencia sin re-invocar manualmente cada pasada.
39
+ - Estás en CI donde no hay humano para aprobar cada batch (combinar con `--no-prompt`).
40
+ - Estás cerrando una fase y quieres reducir hallazgos a 0 antes de declarar APROBADO.
41
+
42
+ **Cuándo NO usar `--until-converge`**:
43
+ - Cuando quieres revisar cada batch antes de aprobar correcciones (usa la verificación estándar).
44
+ - Cuando esperas hallazgos que requieran decisión arquitectónica humana — el loop no debe automatizarse.
45
+ - Cuando el código tocado es crítico (auth, pagos): combinar con `--ultra` para que cada pasada tenga revisión profunda.
46
+
47
+ ## Paso 0 — Carga de habilidades
48
+
49
+ ```
50
+ Skill("verificar-trabajo")
51
+ ```
52
+
53
+ Carga también:
54
+ ```
55
+ Skill("manejo-errores")
56
+ Skill("checklist-calidad")
57
+ ```
58
+
59
+ Si el stack tiene Python: `Skill("testing-python")`
60
+ Si el stack tiene Angular: usar `@angular/core/testing` directo (sin skill dedicado)
61
+
62
+ ## Paso 1 — Determinación del alcance de verificación
63
+
64
+ Determina qué verificar leyendo:
65
+
66
+ 1. `.planning/ESTADO.md` — identifica la fase más reciente ejecutada.
67
+ 2. `.planning/fases/0N-RESUMEN.md` — lista de archivos creados y modificados.
68
+ 3. `.planning/fases/0N-PLAN.md` — criterios de aceptación de la fase.
69
+ 4. `git log --oneline -20` — commits de la sesión de trabajo reciente.
70
+
71
+ Si no hay RESUMEN.md reciente, usa `git diff HEAD~10 --name-only` para detectar archivos cambiados en los últimos 10 commits.
72
+
73
+ Anuncia al usuario el alcance:
74
+ ```
75
+ Verificando los cambios de la Fase N.
76
+ Archivos en alcance: [número]
77
+ Criterios de aceptación a verificar: [número]
78
+ Tiempo estimado: [minutos]
79
+ ```
80
+
81
+ ## Paso 2 — Verificación técnica automatizada
82
+
83
+ Antes de delegar a los agentes especializados, ejecuta verificaciones automáticas:
84
+
85
+ ### 2.1 — Tests
86
+ ```bash
87
+ # Detectar y ejecutar el comando de tests según el stack
88
+ # Python con pytest:
89
+ pytest --tb=short -q
90
+
91
+ # Node/Angular:
92
+ npm test -- --watchAll=false --passWithNoTests
93
+
94
+ # Reportar: cuántos pasan, cuántos fallan, cobertura si está configurada
95
+ ```
96
+
97
+ Si hay tests fallando, registra cada uno con su error exacto. Los tests fallando son severidad CRÍTICA.
98
+
99
+ ### 2.2 — Linter y format
100
+ ```bash
101
+ # Python
102
+ ruff check . --output-format=concise 2>/dev/null || flake8 --max-line-length=120 . 2>/dev/null
103
+
104
+ # TypeScript/JavaScript
105
+ npx eslint src/ --format=compact 2>/dev/null
106
+ ```
107
+
108
+ ### 2.3 — Type checking
109
+ ```bash
110
+ # Python
111
+ mypy . --ignore-missing-imports --no-error-summary 2>/dev/null
112
+
113
+ # TypeScript
114
+ npx tsc --noEmit 2>/dev/null
115
+ ```
116
+
117
+ ### 2.4 — Archivos de debug olvidados
118
+
119
+ Busca patrones de debug que no deben ir a producción:
120
+
121
+ ```
122
+ Grep(pattern="console\.log|print\(|debugger|pdb\.set_trace|breakpoint\(\)", output_mode="content")
123
+ Grep(pattern="TODO|FIXME|HACK|XXX", output_mode="content")
124
+ ```
125
+
126
+ Registra todos los hallazgos con archivo y línea.
127
+
128
+ ### 2.5 — Verificación de commits
129
+
130
+ ```bash
131
+ git log --oneline -20
132
+ ```
133
+
134
+ Verifica que los mensajes de commit siguen la convención del proyecto (si está definida en CLAUDE.md).
135
+
136
+ ## Paso 3 — Delegación al revisor-codigo-swl
137
+
138
+ Delega al agente `revisor-codigo-swl` para revisión de código en profundidad.
139
+
140
+ **Presupuesto de contexto (anti-thrashing):** el subagente hereda `CLAUDE.md` +
141
+ reglas globales del proyecto; en proyectos rule-heavy eso consume buena parte de
142
+ su ventana antes de leer código (causa de autocompact thrashing con 0 tokens
143
+ útiles, observado 2026-06-05). Para evitarlo:
144
+ - Pasa al agente SOLO el diff / los archivos del alcance — nunca "revisa el proyecto".
145
+ - Instruye leer los archivos del alcance PRIMERO y cargar skills bajo demanda (solo
146
+ si el alcance lo amerita), no al inicio.
147
+ - Si el alcance > ~15 archivos o > ~2000 LOC, divídelo en lotes y delega uno por
148
+ invocación (cada subagente arranca con ventana limpia).
149
+
150
+ **Instrucción al agente revisor-codigo-swl:**
151
+
152
+ ```
153
+ Revisa SOLO los archivos del alcance de la Fase N del proyecto [nombre].
154
+ No explores el codebase completo: tu ventana ya hereda CLAUDE.md + reglas
155
+ globales; lee primero los archivos del alcance para no saturarla.
156
+
157
+ Archivos a revisar (en orden de prioridad):
158
+ [lista del RESUMEN.md / git diff del alcance]
159
+
160
+ Lee también (solo lo necesario, bajo demanda):
161
+ - .planning/fases/0N-CONTEXTO.md (requisitos)
162
+ - .planning/fases/0N-PLAN.md (qué se debía hacer)
163
+ (CLAUDE.md ya está en tu contexto heredado — no lo releas.)
164
+
165
+ Para cada archivo revisado, verifica:
166
+
167
+ 1. LÓGICA DE NEGOCIO
168
+ - ¿La implementación cumple los requisitos del CONTEXTO.md?
169
+ - ¿Los casos borde están manejados?
170
+ - ¿Hay lógica duplicada que debería estar centralizada?
171
+
172
+ 2. CALIDAD DEL CÓDIGO
173
+ - ¿Las funciones tienen responsabilidad única?
174
+ - ¿Los nombres de variables y funciones son descriptivos?
175
+ - ¿El código es comprensible sin comentarios extensos?
176
+ - ¿Hay funciones o clases demasiado largas (>50 líneas en funciones, >300 en clases)?
177
+
178
+ 3. MANEJO DE ERRORES
179
+ - ¿Todos los caminos de error están manejados explícitamente?
180
+ - ¿Los errores se loguean con suficiente contexto?
181
+ - ¿No hay excepciones capturadas y silenciadas?
182
+
183
+ 4. TESTS
184
+ - ¿Cada función pública tiene al menos un test?
185
+ - ¿Los tests cubren caminos feliz y caminos de error?
186
+ - ¿Los tests son deterministas (no dependen de tiempo o datos externos sin mock)?
187
+
188
+ Reporta cada hallazgo con:
189
+ - Archivo y línea
190
+ - Severidad: CRÍTICO | MAYOR | MENOR | SUGERENCIA
191
+ - Descripción del problema
192
+ - Corrección recomendada
193
+ ```
194
+
195
+ ## Paso 4 — Delegación al revisor-seguridad-swl
196
+
197
+ Delega al agente `revisor-seguridad-swl` en paralelo (si es posible) o secuencialmente:
198
+
199
+ **Instrucción al agente revisor-seguridad-swl:**
200
+
201
+ ```
202
+ Revisa la seguridad del código de la Fase N del proyecto [nombre].
203
+
204
+ Archivos a revisar:
205
+ [lista del RESUMEN.md]
206
+
207
+ Verifica específicamente:
208
+
209
+ 1. AUTENTICACIÓN Y AUTORIZACIÓN
210
+ - ¿Todos los endpoints protegidos verifican autenticación?
211
+ - ¿Los endpoints de escritura (POST/PUT/DELETE) verifican roles?
212
+ - ¿Hay protección contra IDOR (acceso a recursos de otros usuarios)?
213
+
214
+ 2. VALIDACIÓN DE ENTRADAS
215
+ - ¿Se validan todos los inputs del usuario antes de usarlos?
216
+ - ¿Hay protección contra inyección SQL, XSS, command injection?
217
+ - ¿Los campos tienen restricciones de longitud y formato?
218
+
219
+ 3. DATOS SENSIBLES
220
+ - ¿Hay credenciales, tokens o secrets hardcodeados en el código?
221
+ - ¿Los logs no exponen datos personales o sensibles?
222
+ - ¿Los mensajes de error no revelan información interna del sistema?
223
+
224
+ 4. DEPENDENCIAS
225
+ - ¿Hay dependencias con vulnerabilidades conocidas?
226
+ - ¿Se usan versiones específicas en el lockfile?
227
+
228
+ 5. CONFIGURACIÓN
229
+ - ¿Las variables de entorno tienen valores seguros por defecto?
230
+ - ¿El modo debug está desactivado en configuración de producción?
231
+
232
+ Reporta con:
233
+ - Archivo y línea
234
+ - Severidad: CRÍTICO | ALTO | MEDIO | BAJO
235
+ - CVE o categoría OWASP si aplica
236
+ - Corrección específica recomendada
237
+ ```
238
+
239
+ ## Paso 4.5 — Pasada `--ultra` (solo si flag activo)
240
+
241
+ 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.
242
+
243
+ **Instrucción para la pasada ultra:**
244
+
245
+ Invoca un nuevo contexto de revisor-codigo-swl (o un sub-agente dedicado) con este prompt específico:
246
+
247
+ ```
248
+ Eres el revisor senior de la pasada --ultra de /swl:verificar.
249
+
250
+ Tienes en input:
251
+ - HALLAZGOS_CODIGO: [hallazgos del revisor-codigo-swl, Paso 3]
252
+ - HALLAZGOS_SEGURIDAD: [hallazgos del revisor-seguridad-swl, Paso 4]
253
+ - PLAN y CONTEXTO de la fase (ya cargados)
254
+
255
+ Tu tarea es:
256
+
257
+ 1. CONSOLIDAR. Identifica hallazgos duplicados entre ambos reviewers y
258
+ fúsionalos en una sola entrada con la severidad más alta.
259
+
260
+ 2. DETECTAR CONTRADICCIONES. Si un reviewer aprueba algo que el otro
261
+ rechaza, marca la contradicción explícitamente y argumenta cuál es
262
+ la postura correcta según el contexto del proyecto.
263
+
264
+ 3. PRIORIZAR. Ordena los hallazgos por impacto real (no solo severidad
265
+ nominal). Un "MAYOR" en código que toca pagos supera a un "CRÍTICO"
266
+ en código muerto.
267
+
268
+ 4. DETECTAR HALLAZGOS OMITIDOS. Con visión completa de ambos reports,
269
+ identifica problemas que ninguno detectó individualmente — especialmente:
270
+ - Interacciones peligrosas entre módulos que cada reviewer vio aisladamente
271
+ - Inconsistencias entre la especificación y la implementación
272
+ - Patrones de deuda técnica que afectan más de un módulo
273
+
274
+ 5. GENERAR PLAN DE ACCIÓN. Lista ordenada de correcciones con:
275
+ - Archivo y línea
276
+ - Acción específica
277
+ - Dependencia con otras correcciones
278
+ - Estimación de tiempo
279
+ - Si requiere decisión del arquitecto o planificador
280
+
281
+ 6. VEREDICTO FINAL: APROBADO / APROBADO_CON_OBSERVACIONES / REQUIERE_CORRECCIONES / RECHAZADO.
282
+
283
+ NO ejecutes correcciones — solo identificas y priorizas. Tu output se
284
+ integra al VERIFICACION.md del Paso 6.
285
+ ```
286
+
287
+ 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.
288
+
289
+ ## Paso 4.6 — Bucle de convergencia (solo si `--until-converge` activo)
290
+
291
+ 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.
292
+
293
+ ### 4.6.1 — Criterio de salida por convergencia
294
+
295
+ El loop se detiene cuando se cumple **cualquiera** de estas señales (la primera que ocurra):
296
+
297
+ | Señal | Criterio | Razón |
298
+ |-------|----------|-------|
299
+ | **A — éxito** | La pasada N produce 0 hallazgos nuevos de severidad `CRÍTICO`, `ALTO` o `MAYOR` | Convergencia natural — la fase está limpia |
300
+ | **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 |
301
+ | **C — máximo** | Se alcanza `--max-iter=N` (default 5) sin converger | No-convergente; reportar al usuario |
302
+ | **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) |
303
+
304
+ Los hallazgos `MEDIO`, `BAJO` y `SUGERENCIA` no rompen convergencia — se acumulan como deuda técnica documentada.
305
+
306
+ **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:
307
+ - Migraciones aplicadas a BD limpia (CI fresh) vs BD productiva (donde seeds ya corrieron).
308
+ - Seeds dependientes que fallan en cadena por orden migración↔seed invertido.
309
+ - Tests E2E que requieren datos demo.
310
+ - Partial unique indexes con `WHERE` que no son predicado puro (rompen en CI fresh).
311
+
312
+ 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.
313
+
314
+ ### 4.6.2 — Control de pausa entre iteraciones
315
+
316
+ Antes de invocar al implementador para aplicar correcciones de la pasada N, el comando muestra un resumen y permite al usuario decidir:
317
+
318
+ ```
319
+ Pasada N completada: [X] hallazgos CRÍTICO + [Y] ALTO + [Z] MAYOR
320
+
321
+ Próximo: aplicar correcciones y ejecutar pasada N+1.
322
+
323
+ [c] continuar a pasada N+1 (default tras 30s)
324
+ [p] pausar — mostrar reporte completo de la pasada N y esperar input
325
+ [q] cancelar — mantener correcciones aplicadas hasta ahora, salir del loop
326
+ ```
327
+
328
+ Sin respuesta en 30s: continúa automáticamente con `c` (default).
329
+
330
+ 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.
331
+
332
+ ### 4.6.3 — Detección de loop adversarial
333
+
334
+ 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:
335
+
336
+ - La pasada N+1 introduce **≥5 hallazgos NUEVOS** (signature distinto) sobre archivos que se modificaron entre pasadas N y N+1, **escalar al usuario**:
337
+
338
+ ```
339
+ Pasada N+1 detectó N hallazgos nuevos sobre código que se acaba de corregir.
340
+ Las correcciones de la pasada N pueden estar introduciendo regresión.
341
+
342
+ Hallazgos nuevos:
343
+ [lista breve archivo:línea]
344
+
345
+ ¿Continuar (c), pausar para inspección (p), o abortar el loop (q)?
346
+ ```
347
+
348
+ Esto NO es lo mismo que la pausa estándar — es una alerta explícita por adversarialidad.
349
+
350
+ ### 4.6.4 — Compatibilidad con otros flags
351
+
352
+ | Combinación | Comportamiento |
353
+ |-------------|----------------|
354
+ | `--until-converge --ultra` | Cada pasada ejecuta la consolidación profunda (Paso 4.5). Más caro, más sólido. |
355
+ | `--until-converge --solo-codigo` | El loop se itera solo sobre revisor-codigo-swl. Convergencia ignora hallazgos de seguridad. |
356
+ | `--until-converge --solo-seguridad` | El loop se itera solo sobre revisor-seguridad-swl. |
357
+ | `--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. |
358
+ | `--until-converge --no-prompt` | Pasadas sin pausa interactiva — adecuado para CI. La detección adversarial sigue activa y aborta si se dispara. |
359
+
360
+ ### 4.6.5 — Estado de convergencia persistido
361
+
362
+ Entre iteraciones se mantiene `.planning/fases/0N-converge-state.json`:
363
+
364
+ ```json
365
+ {
366
+ "fase": "0N",
367
+ "session_id": "...",
368
+ "iniciado_at": "ISO timestamp",
369
+ "max_iter": 5,
370
+ "no_prompt": false,
371
+ "iteraciones": [
372
+ {
373
+ "n": 1,
374
+ "criticos": 3, "altos": 5, "mayores": 9, "medios": 4, "bajos": 2,
375
+ "hallazgos_signatures": ["sha256(archivo+linea+regla)", ...],
376
+ "archivos_corregidos": ["..."],
377
+ "duracion_ms": 124000
378
+ }
379
+ ],
380
+ "convergencia": null,
381
+ "razon_salida": null
382
+ }
383
+ ```
384
+
385
+ Al terminar el loop se anexa `convergencia` y `razon_salida` y se renombra a `0N-converge-run-[timestamp].json` para mantener historia.
386
+
387
+ ### 4.6.6 — Integración al VERIFICACION.md final
388
+
389
+ El VERIFICACION.md reportado al usuario al final del loop incluye una sección al inicio:
390
+
391
+ ```markdown
392
+ ## Resumen del modo --until-converge
393
+
394
+ - Pasadas ejecutadas: K / max=5
395
+ - Convergencia: alcanzada en pasada K | no-alcanzada (límite max-iter) | abortada (loop adversarial) | abortada por usuario
396
+ - Razón de salida: [descripción]
397
+ - Hallazgos por pasada:
398
+ | Pasada | CRÍTICO | ALTO | MAYOR | MEDIO | BAJO |
399
+ |--------|---------|------|-------|-------|------|
400
+ | 1 | 3 | 5 | 9 | 4 | 2 |
401
+ | 2 | 0 | 1 | 3 | 2 | 1 |
402
+ | 3 | 0 | 0 | 0 | 2 | 1 |
403
+ - Estado persistido: `.planning/fases/0N-converge-run-[timestamp].json`
404
+ ```
405
+
406
+ ### 4.6.7 — Telemetría de loop (obligatoria en `--until-converge`)
407
+
408
+ Además del estado estructurado de 4.6.5, cada corrida del loop registra su
409
+ trayectoria en el formato estándar de telemetría de loops
410
+ (`hooks/lib/loop-telemetry.js`), que habilita: inyección de estado por el hook
411
+ `contexto-iteracion.js` (anti-context-rot en sesiones largas), detección de
412
+ plateau, y lectura por `/swl:status metricas`.
413
+
414
+ Usar el subcomando del CLI (resuelve cross-scope; ver
415
+ `docs/invocacion-cli-cross-scope.md`).
416
+
417
+ Al iniciar el loop (antes de la pasada 1) — imprime el `<dir>` de la corrida:
418
+
419
+ ```bash
420
+ swl-ses loop-telemetry iniciar --tipo=verificar --direccion=lower_is_better --config='{"fase":"0N","maxIter":5}'
421
+ ```
422
+
423
+ Tras CADA pasada, registrar una fila (métrica = hallazgos CRÍTICO+ALTO+MAYOR):
424
+
425
+ ```bash
426
+ swl-ses loop-telemetry registrar --dir="<dir>" --iteracion=N --metrica=M --delta=D --estado=keep --descripcion="pasada N: X criticos, Y altos, Z mayores"
427
+ ```
428
+
429
+ Al cerrar el loop (cualquier señal de salida), escribir el handoff (los
430
+ hallazgos MEDIO/BAJO residuales van como array JSON en `--findings`):
431
+
432
+ ```bash
433
+ swl-ses loop-telemetry handoff --dir="<dir>" --source=swl:verificar --status=COMPLETO --config='{"fase":"0N"}' --findings='[]'
434
+ ```
435
+
436
+ `status` según la señal: A/D → `COMPLETO`, B → `INTERRUMPIDO`, C → `ACOTADO`.
437
+ Si `analizarTrayectoria()` reporta plateau antes de `--max-iter`, tratarlo como
438
+ señal C anticipada: seguir iterando sin mejora de métrica quema tokens sin
439
+ reducir hallazgos.
440
+
441
+ ### 4.6.8 Protocolo `--ci-aware` (Señal D)
442
+
443
+ Cuando `--ci-aware` está activo, el bucle de convergencia se extiende con un gate adicional ANTES de declarar Señal A como cierre definitivo:
444
+
445
+ **Precondición**: el último commit de la pasada N debe estar pusheado a la rama remota. Si no:
446
+
447
+ ```
448
+ Pasada N converge natural pero --ci-aware requiere CI sobre HEAD pushed.
449
+
450
+ HEAD local: abc1234 (no pusheado)
451
+ [p] push automático + monitor CI
452
+ [c] continuar sin --ci-aware (convergencia solo local)
453
+ [q] abortar — pushear manualmente y re-invocar
454
+ ```
455
+
456
+ Con `--no-prompt`: default es `p` (push automático).
457
+
458
+ **Algoritmo de espera**:
459
+
460
+ 1. Tras Señal A, obtener SHA actual de `HEAD` y ejecutar `git ls-remote origin <rama>` para confirmar que está sincronizado.
461
+ 2. Listar workflows aplicables al SHA con:
462
+ ```bash
463
+ gh run list --branch <rama> --limit 10 \
464
+ --json status,conclusion,name,headSha \
465
+ --jq '.[] | select(.headSha == "<SHA>")'
466
+ ```
467
+ 3. Esperar usando la regla global `monitor-ci.md` (patrón Monitor con `gh --jq`, NO `| jq`).
468
+ 4. Clasificar resultado:
469
+ - **Todos `completed`+`success`** → Señal D confirmada, convergencia válida.
470
+ - **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.
471
+ - **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`.
472
+ - **Workflows aún en `in_progress` después del timeout configurado en monitor-ci** escalar al usuario, no cerrar convergencia.
473
+
474
+ **Workflows aplicables vs no aplicables**:
475
+
476
+ `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.
477
+
478
+ El gate solo evalúa workflows que **sí se dispararon en el SHA**. La verificación es:
479
+
480
+ ```bash
481
+ gh run list --branch <rama> --limit 10 --json headSha,name,status,conclusion \
482
+ --jq '[.[] | select(.headSha | startswith("<sha-corto>"))] | all(.[]; .status == "completed" and .conclusion == "success")'
483
+ ```
484
+
485
+ Output `true` Señal D. `false` con detalle reabrir loop.
486
+
487
+ **Anti-patrones explícitos**:
488
+
489
+ - **Tratar timeout del monitor como "verde por default"**: el timeout significa "estado desconocido", NO `success`. Re-armar monitor o escalar al usuario.
490
+ - **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/)".
491
+ - **Asumir verde porque `git push` retornó exit 0**: push exitoso ≠ CI verde. push solo confirma que GitHub aceptó el push.
492
+
493
+ Origen: regla global `monitor-ci.md` cubre este protocolo en detalle. Esta sección lo activa específicamente para `/swl:verificar`.
494
+
495
+ ### 4.6.8Backward compatibility
496
+
497
+ 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.
498
+
499
+ ## Paso 5 — Verificación de criterios de aceptación
500
+
501
+ ### 5.0 Trazabilidad REQ→T→commit→test (si el CONTEXTO tiene REQ-IDs)
502
+
503
+ Si la sección de criterios del CONTEXTO usa IDs `REQ-NN:` (fases 10-11) o
504
+ `REQ-<fase>-NN:` (namespaceados, fases ≥12), ejecuta el validador de cadena
505
+ ANTES de la verificación criterio por criterio:
506
+
507
+ ```bash
508
+ swl-ses verificar-trazabilidad --fase=N
509
+ ```
510
+
511
+ - Exit 0cadena completa; adjunta la tabla REQ→tareas/commits/tests al VERIFICACION.md.
512
+ - Exit 1 → **cada REQ huérfano es hallazgo CRÍTICO** (requisito sin implementar,
513
+ sin commit trazable o sin test que lo verifique). Listarlos en el VERIFICACION.md
514
+ con la dirección del gap (sin tarea / sin commit / sin test).
515
+ - Exit 2 error de invocación; reportar sin bloquear el resto de la verificación.
516
+
517
+ En CONTEXTOs legacy sin REQ-IDs el script sale 0 con nota continuar normal.
518
+
519
+ ### 5.0b Contract testing (si la fase declaró schemas en el PLAN)
520
+
521
+ Si el PLAN declara schemas (Pydantic/Zod/JSON Schema/OpenAPI) o la fase expone
522
+ una API consumida por otro componente, cargar `Skill("calidad-contract-testing")`
523
+ y verificar que la implementación honra el contrato (schema-based con
524
+ schemathesis/Dredd contra la API real, o validación de forma con el modelo en
525
+ el test de integración). Cada violación de contrato = hallazgo CRÍTICO.
526
+
527
+ Lee los criterios de aceptación del `.planning/fases/0N-CONTEXTO.md` y verifica cada uno:
528
+
529
+ Para cada criterio:
530
+ 1. Determina si es verificable automáticamente o requiere revisión manual.
531
+ 2. Si es automático: ejecuta la verificación y registra el resultado.
532
+ 3. Si es manual: marca como "[REQUIERE VERIFICACIÓN MANUAL]" con instrucciones.
533
+
534
+ Ejemplo de tabla de verificación:
535
+ ```
536
+ | Criterio | Método | Resultado |
537
+ |---------|--------|----------|
538
+ | El usuario puede crear una cuenta | Test e2e / manual | PASA / FALLA / PENDIENTE |
539
+ ```
540
+
541
+ ### Smoke test manual obligatorio para módulos frontend grandes
542
+
543
+ Origen: SIGAF sesión 2026-05-21 (mejora D2). Cuando el alcance de la
544
+ verificación toca un **componente frontend > 2,000 LOC** (típicamente módulos
545
+ como `/catalogos`, `/contratos`, `/expedientes` que crecen orgánicamente), la
546
+ verificación automática NO es suficiente. Los tests unitarios pueden pasar y
547
+ el linter quedar limpio mientras el componente está **roto en el render
548
+ real** (estado inicial mal calculado, evento que no propaga, route guard que
549
+ redirige en loop, error de hidratación SSR que solo aparece en producción).
550
+
551
+ Reglas duras para esta sub-categoría:
552
+
553
+ 1. **Detección automática del trigger**: si el revisor de código reporta
554
+ ≥1 archivo en `frontend/` con LOC > 2000, OR la suma de LOC de archivos
555
+ modificados en el último commit en `frontend/` excede 1500, activar este
556
+ sub-paso.
557
+
558
+ 2. **Smoke test manual obligatorio**: el VERIFICACION.md DEBE incluir un
559
+ bloque `## Smoke test manual (módulo frontend grande)` con los siguientes
560
+ checks que el usuario humano marca PASA/FALLA antes del merge:
561
+
562
+ ```markdown
563
+ ## Smoke test manual frontend/<modulo> (X LOC)
564
+
565
+ - [ ] Arranca el dev server sin errores en consola
566
+ - [ ] Renderiza la pantalla principal del módulo sin pantalla blanca
567
+ - [ ] Navegación a cada sub-ruta funciona (listar nombres)
568
+ - [ ] Acciones CRUD principales completan flujo end-to-end
569
+ - [ ] No hay warnings de hidratación en consola (SSR si aplica)
570
+ - [ ] Layout responsive funciona en viewport mobile + desktop
571
+ - [ ] [Si aplica] Web vitals sin regresión vs commit anterior
572
+ ```
573
+
574
+ 3. **NO marcar verificación como APROBADA** hasta que el bloque esté completo
575
+ o el usuario explícitamente exente checks específicos con justificación.
576
+
577
+ 4. **El comando NO ejecuta el smoke automáticamente** (requiere browser
578
+ humano); su responsabilidad es **incluir el bloque en VERIFICACION.md** y
579
+ marcar la decisión de verificación como `APROBADO_CON_OBSERVACIONES`
580
+ hasta que el bloque se cierre.
581
+
582
+ **Cuándo NO aplicar este sub-paso**:
583
+
584
+ - Módulos backend puros (cobertura suficiente con tests de integración).
585
+ - Cambios cosméticos a componentes frontend grandes (typo en texto, ajuste
586
+ de color de un botón) — la heurística LOC sigue disparándose pero el
587
+ usuario puede exentar con `[exento: cambio cosmético en X líneas]`.
588
+ - Módulos con cobertura E2E > 70% probada (webapp-testing, Playwright,
589
+ Cypress) el smoke automático cubre la necesidad.
590
+
591
+ ## Paso 6 — Consolidación y generación del VERIFICACION.md
592
+
593
+ Consolida todos los hallazgos en `.planning/fases/0N-VERIFICACION.md`:
594
+
595
+ ```markdown
596
+ # Reporte de verificación Fase N: [nombre]
597
+
598
+ **Proyecto**: [nombre]
599
+ **Fecha de verificación**: [fecha]
600
+ **Verificado por**: swl:verificar + revisor-codigo-swl + revisor-seguridad-swl
601
+ **Estado general**: APROBADO | APROBADO_CON_OBSERVACIONES | REQUIERE_CORRECCIONES | RECHAZADO
602
+
603
+ ## Resumen ejecutivo
604
+
605
+ | Categoría | CRÍTICO | MAYOR | MENOR | SUGERENCIA |
606
+ |-----------|---------|-------|-------|-----------|
607
+ | Tests | N | N | N | N |
608
+ | Código | N | N | N | N |
609
+ | Seguridad | N | N | N | N |
610
+ | **Total** | **N** | **N** | **N** | **N** |
611
+
612
+ ## Criterios de aceptación
613
+
614
+ [tabla del Paso 5]
615
+
616
+ ## Hallazgos por categoría
617
+
618
+ ### Tests automatizados
619
+ [resultados del Paso 2.1]
620
+
621
+ ### Calidad de código
622
+ [hallazgos del revisor-codigo-swl]
623
+
624
+ ### Seguridad
625
+ [hallazgos del revisor-seguridad-swl]
626
+
627
+ ### Issues menores y sugerencias
628
+ [lista]
629
+
630
+ ## Acciones requeridas antes del deploy
631
+
632
+ [solo los CRÍTICO y MAYOR — ordenados por prioridad]
633
+
634
+ 1. [ ] [acción específica con archivo y línea]
635
+ 2. [ ] [acción específica]
636
+
637
+ ## Decisión de verificación
638
+
639
+ **APROBADO**: No hay hallazgos CRÍTICO ni MAYOR. La fase puede avanzar.
640
+ **APROBADO_CON_OBSERVACIONES**: Hay MAYOR pero no bloquea el avance inmediato. Resolver en la siguiente iteración.
641
+ **REQUIERE_CORRECCIONES**: Hay hallazgos CRÍTICO que deben resolverse antes de deploy.
642
+ **RECHAZADO**: La implementación no cumple los criterios de aceptación fundamentales.
643
+ ```
644
+
645
+ ## Paso 7 — Reporte al usuario
646
+
647
+ Reporta el resultado de verificación al usuario con formato claro:
648
+
649
+ ```
650
+ Verificación de la Fase N completada.
651
+
652
+ Estado: [APROBADO | REQUIERE_CORRECCIONES | etc.]
653
+
654
+ Hallazgos críticos: [N] — [descripción breve o "ninguno"]
655
+ Hallazgos mayores: [N]
656
+ Hallazgos menores: [N]
657
+ Criterios de aceptación: [N de N cumplidos]
658
+
659
+ Reporte completo en: .planning/fases/0N-VERIFICACION.md
660
+ ```
661
+
662
+ Si hay hallazgos CRÍTICOS, lista cada uno explícitamente y pregunta:
663
+ ```
664
+ Hay [N] hallazgos críticos que deben corregirse. ¿Deseas:
665
+ 1. Corregirlos ahora (recomendado)
666
+ 2. Continuar de todas formas y registrar como deuda técnica
667
+ 3. Ver el detalle completo del reporte primero
668
+ ```
669
+
670
+ Si el veredicto es **APROBADO_CON_OBSERVACIONES** (hay MAYORES pero ninguno CRÍTICO), ofrecer al usuario el flujo de corrección automatizado:
671
+
672
+ ```
673
+ Veredicto: APROBADO_CON_OBSERVACIONES
674
+
675
+ Hay [N] hallazgos mayores no bloqueantes:
676
+ [lista breve con archivo:línea por cada uno]
677
+
678
+ ¿Deseas:
679
+ 1. Aplicar todas las correcciones sugeridas ahora (delegar al implementador-swl
680
+ con el VERIFICACION.md como spec — resuelve los N hallazgos en un solo slice)
681
+ 2. Resolverlos selectivamente (te muestro uno a uno y decides)
682
+ 3. Registrar como deuda técnica y continuar
683
+ 4. Ver el detalle completo del reporte primero
684
+ ```
685
+
686
+ **Comportamiento de la opción 1** (aplicar todas las correcciones automatizado):
687
+
688
+ 1. Extraer cada hallazgo MAYOR del VERIFICACION.md como una tarea del slice.
689
+ 2. Delegar a `implementador-swl` con un brief que incluye:
690
+ - Ruta del VERIFICACION.md como spec primaria
691
+ - Lista explícita de archivo:línea por cada hallazgo
692
+ - Regla: aplicar solo las correcciones listadas, sin refactorings adicionales
693
+ 3. Al terminar el implementador, ejecutar re-verificación automática (no bloqueante)
694
+ sobre los mismos archivos para confirmar cierre de hallazgos.
695
+ 4. Si la re-verificación reporta nuevos MAYORES en código tocado, escalar al usuario
696
+ (no entrar en bucle infinito).
697
+ 5. Commit atómico con mensaje `fix(verificar): resuelve N observaciones de
698
+ fase X <ticket/referencia VERIFICACION.md>`.
699
+
700
+ **Por qué este flujo es necesario**: hoy el usuario tras APROBADO_CON_OBSERVACIONES
701
+ debe pedir manualmente cada corrección. Eso genera fricción y olvido de observaciones
702
+ menores que se acumulan como deuda. El flujo automatizado preserva la autonomía
703
+ del usuario (opciones 2/3/4 siguen disponibles) pero ofrece la ruta feliz cuando
704
+ el usuario quiere cerrar todo el batch.
705
+
706
+ ### Flag `--aplicar-iteracion=<scope>` (salta el prompt de opciones)
707
+
708
+ Cuando el usuario ya sabe qué scope quiere aplicar, el flag elimina la fricción
709
+ de 2 mensajes de ida/vuelta (veredicto → respuesta del usuario → ejecución).
710
+
711
+ **Sintaxis**:
712
+
713
+ ```bash
714
+ /swl:verificar --aplicar-iteracion=urgentes
715
+ /swl:verificar --aplicar-iteracion=todo
716
+ /swl:verificar --aplicar-iteracion=custom:C2,M3,M5
717
+ ```
718
+
719
+ **Interpretación por valor**:
720
+
721
+ | Valor | Alcance | Casos de uso |
722
+ |-------|---------|--------------|
723
+ | `urgentes` | CRÍTICOS + MAYORES | Default razonable para la mayoría de fases; resuelve bloqueantes sin tocar mejoras de calidad. |
724
+ | `todo` | CRÍTICOS + MAYORES + MEDIOS | Cierre completo antes de release o entrega. Aplica todo lo accionable. |
725
+ | `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`. |
726
+
727
+ **Comportamiento del flag**:
728
+
729
+ 1. Ejecuta verificación completa (Pasos 1-6 estándar).
730
+ 2. Genera VERIFICACION.md normalmente.
731
+ 3. Si el veredicto es `APROBADO_CON_OBSERVACIONES` o `REQUIERE_CORRECCIONES`:
732
+ - En lugar de presentar el menú de opciones, selecciona los hallazgos según el scope del flag.
733
+ - Delega a `implementador-swl` con la lista filtrada como brief (mismo formato que opción 1 estándar).
734
+ - Ejecuta re-verificación no bloqueante al terminar.
735
+ 4. Si el veredicto es `APROBADO` o `RECHAZADO`:
736
+ - `APROBADO`: el flag no tiene efecto (nada que aplicar).
737
+ - `RECHAZADO`: el flag se ignora y se escala al usuario (fase con defectos críticos requiere decisión humana).
738
+
739
+ **Reglas del flag**:
740
+
741
+ - **SIEMPRE listar explícitamente** los IDs que se aplicarán antes de delegar (para que el log del comando refleje qué se está cerrando).
742
+ - **Si el scope incluye un ID que no existe** en el VERIFICACION.md, advertir pero continuar con los que sí existen.
743
+ - **`custom:` es case-sensitive** para los IDs (ej: `C2` ≠ `c2`).
744
+ - **El flag NO suprime el commit** — el mensaje `fix(verificar): resuelve N observaciones` registra la aplicación igual que el flujo manual.
745
+ - **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.
746
+
747
+ **Ejemplo concreto**:
748
+
749
+ ```bash
750
+ # Usuario quiere cerrar MAYORES y MEDIOS pero omitir C1 (que marcó como
751
+ # fuera de scope por discusión previa con el equipo):
752
+ /swl:verificar --aplicar-iteracion=custom:C2,C3,M1,M2,M3,Med1,Med2
753
+ ```
754
+
755
+ El comando:
756
+ 1. Corre verificación completa.
757
+ 2. Al ver `APROBADO_CON_OBSERVACIONES` con 8 hallazgos incluyendo C1:
758
+ 3. Selecciona los 7 IDs listados (omite C1).
759
+ 4. Delega al implementador con brief que incluye solo esos 7.
760
+ 5. Re-verifica. Commitea. Reporta `7 de 7 aplicados; C1 omitido por flag custom`.
761
+
762
+ **Origen**: esta funcionalidad se agregó tras observar en campo (proyecto EMAIA,
763
+ 2026-04-23) que el patrón "veredicto → usuario pide X manualmente → ejecución" se
764
+ repetía 2+ veces por sesión con alta variación sobre el alcance exacto. Formalizar
765
+ con flag elimina los 2 mensajes de fricción y deja el scope auditable en el comando.
766
+
767
+ ## Modo `--full` — Parallel Scorecard
768
+
769
+ 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.
770
+
771
+ ### Audits paralelos invocados
772
+
773
+ | Tool | Detecta | Comando |
774
+ |---|---|---|
775
+ | `code-profiler.js` | N+1 queries, sync I/O en async, memory leaks, ReDoS, queries unbounded | `node scripts/audit-tools/code-profiler.js .` |
776
+ | `pentest-scanner.js` | XSS, SQLi, SSTI, CORS misconfig, JWT vulnerabilities, prototype pollution | `node scripts/audit-tools/pentest-scanner.js <target>` |
777
+ | `dep-doctor.js` | Deps no usadas, outdated, heavy deps con alternativa | `node scripts/audit-tools/dep-doctor.js .` |
778
+ | `secret-scanner` (hook existente) | Credenciales hardcodeadas | (vía hook) |
779
+
780
+ ### Thresholds del scorecard
781
+
782
+ | Score | Status | Acción |
783
+ |---|---|---|
784
+ | ≥80 | READY | Listo para mergear |
785
+ | 60-79 | NEEDS WORK | Hallazgos menores; mergear bajo decisión informada |
786
+ | <60 | NOT READY | Hallazgos críticos; bloquear merge |
787
+
788
+ ### Salida agregada
789
+
790
+ El comando produce un reporte tipo:
791
+
792
+ ```
793
+ SCORECARD Audits paralelos
794
+ ─────────────────────────────────
795
+ code-profiler: 95 / 100 [READY]
796
+ pentest-scanner: 82 / 100 [READY]
797
+ dep-doctor: 70 / 100 [NEEDS WORK]
798
+ secret-scanner: 100 / 100 [READY]
799
+ ─────────────────────────────────
800
+ Score promedio: 86.75 [READY]
801
+ Total findings: 3 (0 críticos, 2 mayores, 1 menor)
802
+ ```
803
+
804
+ ### Cuándo usar `--full` vs flujo estándar
805
+
806
+ - **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.
807
+ - **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.
808
+
809
+ ## Reglas de comportamiento
810
+
811
+ - NUNCA marques una fase como APROBADO si hay hallazgos CRÍTICOS de seguridad.
812
+ - NUNCA ejecutes correcciones de código directamente en este comando — solo identifica. Las correcciones son responsabilidad del implementador.
813
+ - Si los tests fallan, es siempre CRÍTICO, sin excepción.
814
+ - Las SUGERENCIAS son de largo plazo — no bloquean el avance pero deben documentarse.
815
+ - Si el RESUMEN.md no existe, usa git diff para inferir el alcance. Nunca te bloquees.
816
+
817
+ <!-- El patrón parallel scorecard adaptado de Houseofmvps/ultraship /ship bajo MIT License -->