@saulwade/swl-ses 1.8.0 → 1.9.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 (44) hide show
  1. package/CLAUDE.md +3 -3
  2. package/README.md +5 -5
  3. package/agentes/orquestador-swl.md +89 -1
  4. package/agentes/revisor-codigo-swl.md +34 -10
  5. package/agentes/revisor-seguridad-swl.md +7 -0
  6. package/agentes/tdd-qa-swl.md +23 -2
  7. package/comandos/swl/autoresearch.md +102 -6
  8. package/comandos/swl/metricas.md +34 -0
  9. package/comandos/swl/nemesis.md +42 -1
  10. package/comandos/swl/planear-fase.md +8 -0
  11. package/comandos/swl/predecir.md +139 -0
  12. package/comandos/swl/verificar.md +50 -7
  13. package/habilidades/angular-moderno/SKILL.md +44 -1
  14. package/habilidades/autoresearch/SKILL.md +15 -1
  15. package/habilidades/calidad-mutation-testing/SKILL.md +170 -0
  16. package/habilidades/changelog-generator/scripts/parse-commits.js +2 -1
  17. package/habilidades/checklist-seguridad/SKILL.md +29 -1
  18. package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -0
  19. package/habilidades/css-moderno/SKILL.md +3 -1
  20. package/habilidades/fastapi-experto/SKILL.md +56 -5
  21. package/habilidades/patrones-python/SKILL.md +8 -5
  22. package/habilidades/proceso-debate-adversarial/SKILL.md +164 -0
  23. package/habilidades/proceso-debate-adversarial/recursos/personas.md +105 -0
  24. package/habilidades/proceso-dynamic-workflows/SKILL.md +138 -0
  25. package/habilidades/proceso-dynamic-workflows/recursos/template-adversarial-verify.js +65 -0
  26. package/habilidades/proceso-dynamic-workflows/recursos/template-triage.js +65 -0
  27. package/habilidades/tdd-workflow/SKILL.md +14 -1
  28. package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -0
  29. package/hooks/contexto-iteracion.js +144 -0
  30. package/hooks/lib/loop-telemetry.js +321 -0
  31. package/hooks/notificacion-telegram.js +11 -3
  32. package/llms.txt +29 -0
  33. package/manifiestos/hooks-config.json +10 -1
  34. package/manifiestos/modulos.json +7 -1
  35. package/manifiestos/skills-lock.json +45 -24
  36. package/package.json +4 -3
  37. package/plugin.json +5 -2
  38. package/reglas/arquitectura.evolved.json +7 -0
  39. package/reglas/arquitectura.md +65 -0
  40. package/reglas/seguridad.evolved.json +7 -0
  41. package/reglas/seguridad.md +144 -0
  42. package/scripts/generar-inventario.js +64 -1
  43. package/scripts/instalador.js +32 -2
  44. package/scripts/smoke-test.js +24 -2
package/CLAUDE.md CHANGED
@@ -1,4 +1,4 @@
1
- # CLAUDE.md — @saulwade/swl-ses v1.8.0
1
+ # CLAUDE.md — @saulwade/swl-ses v1.9.0
2
2
 
3
3
  ## Reglas de máxima prioridad (aplican SIEMPRE, sin excepción)
4
4
 
@@ -95,7 +95,7 @@ NUNCA asumir, sugerir como hecho consumado, ni escribir en ADRs/manifiestos/CHAN
95
95
  ## Qué es este repositorio
96
96
 
97
97
  Sistema de ingeniería de software auto-evolutivo multi-runtime polyglot (SDLC completo).
98
- 11 lenguajes, 7 runtimes (Claude, OpenClaude, OpenCode, Gemini, Cursor, Codex, Copilot), 61 agentes, 178 skills, 44 comandos, 71 reglas, 44 hooks.
98
+ 11 lenguajes, 7 runtimes (Claude, OpenClaude, OpenCode, Gemini, Cursor, Codex, Copilot), 61 agentes, 181 skills, 45 comandos, 71 reglas, 45 hooks.
99
99
 
100
100
  ## Estructura del repositorio
101
101
 
@@ -115,7 +115,7 @@ scripts/ bin/ _userland/ .claude/ .planning/
115
115
 
116
116
  ## Comandos del sistema (/swl:*)
117
117
 
118
- Catálogo completo de 44 comandos `/swl:*` en `@COMANDOS.md`. Atajos mentales por categoría:
118
+ Catálogo completo de 45 comandos `/swl:*` en `@COMANDOS.md`. Atajos mentales por categoría:
119
119
 
120
120
  - **Ciclo GSD por fase**: `discutir-fase` → `planear-fase` → `ejecutar-fase` → `verificar` (con discovery routing, modo iterativo `--iterative` y `--until-converge`).
121
121
  - **Anti-context-rot**: `checkpoint`, `compactar`.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # swl-ses v1.8.0
1
+ # swl-ses v1.9.0
2
2
 
3
3
  > El paquete anterior `@saulwadeleon/swl-software-engineering-system` está deprecado. Migrar a `@saulwade/swl-ses` (npmjs.org canónico) o `@saul-wade/swl-ses` (mirror en GitHub Packages) — el CLI `swl-ses` no cambia.
4
4
 
@@ -195,7 +195,7 @@ claude
195
195
  | `mobile` | Android + iOS + React Native/Flutter + UX |
196
196
  | `devops` | CI/CD + cloud + observabilidad + releases + seguridad |
197
197
  | `polyglot` | Todos los lenguajes: 11 lenguajes + revisores + build resolvers |
198
- | `completo` | Todo: 61 agentes + 178 habilidades + 44 comandos + 71 reglas + 44 hooks |
198
+ | `completo` | Todo: 61 agentes + 181 habilidades + 45 comandos + 71 reglas + 45 hooks |
199
199
 
200
200
  ### Targets soportados
201
201
 
@@ -498,9 +498,9 @@ swl-ses/
498
498
  manifiestos/ # Perfiles y módulos de instalación
499
499
  agentes/ # 60 agentes especializados
500
500
  habilidades/ # 160 habilidades modulares
501
- comandos/swl/ # 44 comandos slash
501
+ comandos/swl/ # 45 comandos slash
502
502
  reglas/ # 28 reglas base + 40 por lenguaje
503
- hooks/ # 44 hooks + 66 librerías en hooks/lib/
503
+ hooks/ # 45 hooks + 69 librerías en hooks/lib/
504
504
  schemas/ # 15 JSON Schemas
505
505
  contextos/ # 3 modos de desarrollo
506
506
  instintos/ # Instintos YAML con confianza
@@ -576,4 +576,4 @@ npm run field-report # Reporte de uso real de skills y agentes
576
576
 
577
577
  ## Licencia
578
578
 
579
- MIT
579
+ MIT
@@ -15,7 +15,12 @@ modeloAlterno: claude-haiku-4-5-20251001
15
15
  ventanaContexto: 200k
16
16
  permissionMode: plan
17
17
  color: white
18
- version: 1.2.0
18
+ version: 1.3.0
19
+ evolved: true
20
+ evolved-from: "1.2.0"
21
+ evolved-at: "2026-06-04"
22
+ evolved-by: "evolucionar"
23
+ evolved-note: "PE-005 sección 5 'Sub-agente background falla con API Error: Usage credits required for 1M context — verificar filesystem antes de re-intentar' + PE-006 sección 6 'Cuándo NO delegar a sub-agentes Opus 4.7 1M context'. Aprobación humana explícita pese a evolvable=false (función sistémica) — patrones de recovery operativos validados en OIC v1.5 2026-06-04 (2 sub-agentes background fallaron al cerrar pero dejaron ~700 LOC en disco)."
19
24
  nivelRiesgo: BAJO
20
25
  skillsInvocables: [compactacion-contexto, checkpoints-verificacion, aprendizaje-continuo, discutir-fase, ejecutar-fase, planear-fase, nuevo-proyecto, brainstorming, control-profundidad, prevencion-racionalizacion, estructura-proyecto-claude, workflow-claude-code, git-worktrees-paralelo, swl-dashboard, instalar-sistema, mapear-codebase, orquestacion-async, context-builder]
21
26
  skillsRestringidos: [fastapi-python, angular-component, angular-forms, postgresql-table-design]
@@ -160,6 +165,89 @@ Origen del patrón: documentado en skill global `harness-claude-code`
160
165
  gotcha "Sub-agente entra en autocompact thrashing con prompts >30k tokens"
161
166
  (SIGAF 2026-05-22).
162
167
 
168
+ ### 5. Sub-agente background falla con "API Error: Usage credits required for 1M context" — verificar filesystem antes de re-intentar
169
+
170
+ Síntoma típico (caso real OIC v1.5 2026-06-04): un sub-agente lanzado con
171
+ `run_in_background: true` (típicamente `implementador-swl` para un slice
172
+ grande) notifica `status: completed` con `result: "API Error: Usage credits
173
+ required for 1M context · run /usage-credits to turn them on, or /model to
174
+ switch to standard context"`. El `total_tokens` del result es muy bajo
175
+ (1k-2k) pese a `tool_uses` alto (29-35).
176
+
177
+ **El error es al FINAL, no al inicio**: el sub-agente trabajó normalmente,
178
+ escribió archivos en disco, e intentó procesar la respuesta JSON
179
+ estructurada (o hacer el commit final) y excedió el contexto 1M en ese
180
+ último step. Todo el trabajo real quedó en disco.
181
+
182
+ **Protocolo OBLIGATORIO de recuperación** antes de re-implementar:
183
+
184
+ ```bash
185
+ # 1. Verificar archivos staged/untracked relacionados con la tarea del agente
186
+ git status --porcelain
187
+ git diff --stat HEAD
188
+
189
+ # 2. Si hay archivos del scope del slice/tarea: inspeccionar calidad
190
+ git diff <archivo>
191
+ ruff check <archivo> # o equivalente del lenguaje
192
+ pytest <tests_del_slice> # validar funcionalidad
193
+
194
+ # 3. Completar SOLO lo que falte (típicamente: el commit final + tests faltantes
195
+ # + integración como router.py, __init__.py, etc.)
196
+ git add <archivos_validados>
197
+ git commit -m "feat(...): retomado tras fallo de billing del sub-agente"
198
+ ```
199
+
200
+ **NUNCA** asumir "fallo total" y re-implementar desde cero. Eso descarta
201
+ horas de trabajo que está completo en disco.
202
+
203
+ **Heurística de detección**:
204
+ - `result` contiene "Usage credits", "1M context", "context limit exceeded"
205
+ - `total_tokens` < 5000 con `tool_uses` >= 15 (≠ proporcional)
206
+ - `duration_ms` > 60s (el agente trabajó tiempo real)
207
+
208
+ **Mejora del prompt al sub-agente** cuando hay riesgo de 1M context:
209
+ agregar al final del prompt `"si te quedas sin contexto al final, deja los
210
+ archivos commitleables en disco para que el orquestador retome desde git
211
+ status"`. Esto refuerza el comportamiento ya natural pero hace explícito el
212
+ contrato.
213
+
214
+ **Origen**: OIC Milestone v1.5 Slices 1 y 5 (2026-06-04). Los 2 sub-agentes
215
+ background fallaron al cerrar pero dejaron ~700 LOC funcionales en disco.
216
+ Detectado por `git status` antes de re-implementar.
217
+
218
+ ### 6. Cuándo NO delegar a sub-agentes Opus 4.7 [1M context]
219
+
220
+ El modelo Opus 4.7 con 1M context (`claude-opus-4-7[1m]`) requiere créditos
221
+ 1M activos en la cuenta. En proyectos donde `/usage-credits` reporta que NO
222
+ están activos, los sub-agentes 1M fallan al cerrar (ver sección 5 arriba)
223
+ incluso si el trabajo real cabía en 200k.
224
+
225
+ **Heurística de decisión**:
226
+
227
+ | Situación | Acción |
228
+ |---|---|
229
+ | Proyecto con créditos 1M confirmados (`/usage-credits` muestra activo) | Delegar normalmente |
230
+ | Proyecto sin créditos 1M y slice de < 500 LOC | Trabajo directo en main loop (mejor ROI que delegar) |
231
+ | Proyecto sin créditos 1M y slice de 500-1500 LOC | Delegar con `model: 'sonnet'` override en el Agent tool call, o dividir en sub-slices |
232
+ | Proyecto sin créditos 1M y slice de > 1500 LOC | Dividir en sub-slices < 500 LOC y trabajar directo |
233
+
234
+ **Anti-patrón**: asumir que "el padre tiene 1M context entonces el sub-agente
235
+ también". El sub-agente hereda el modelo, no los créditos. Los créditos son
236
+ por-cuenta, no por-sesión.
237
+
238
+ **Override seguro** cuando se delega y no hay créditos 1M:
239
+
240
+ ```typescript
241
+ Agent({
242
+ subagent_type: "implementador-swl",
243
+ model: "sonnet", // ← override explícito
244
+ prompt: "...",
245
+ })
246
+ ```
247
+
248
+ **Origen**: OIC Milestone v1.5 2026-06-04. 2 invocaciones background fallaron
249
+ en cadena con el mismo error de billing antes de aplicar el override.
250
+
163
251
  ## Routing por fase + dominio (lookup tabular determinístico)
164
252
 
165
253
  Antes de delegar, **clasifica la petición** por dos ejes mecánicos en lugar de
@@ -15,12 +15,12 @@ model: claude-sonnet-4-6
15
15
  modeloAlterno: claude-haiku-4-5-20251001
16
16
  ventanaContexto: 200k
17
17
  color: orange
18
- version: 1.2.0
18
+ version: 1.2.2
19
19
  evolved: true
20
- evolved-from: "1.1.2"
21
- evolved-at: "2026-05-09"
22
- evolved-by: "aprender"
23
- evolved-note: "Reorganización de scoring con vocabulario 5-axis Addy Osmani sin duplicar capacidades existentes. Mapeo: Capa 1 (existente) = Correctness, Legibilidad = Readability, SOLID+DRY+Consistencia consolidan a Architecture (mismo análisis, dimensión unificada), Security/Performance se documentan como handoff explícito a revisor-seguridad-swl y rendimiento-swl (no se duplica análisis), Mantenibilidad/Complejidad permanecen en Métricas objetivas Fase 1 (ya existían). Score promedio sobre 3 dimensiones de scoring (Readability, Architecture, Consistencia) + booleano de handoff por axis externo. Veto items y formato de reporte preservados, retrocompatible. Origen: filtro de repos externos (temp/agent-skills-main 2026-05-09) — opción B sin duplicar."
20
+ evolved-from: "1.2.1"
21
+ evolved-at: "2026-06-05"
22
+ evolved-by: "evolucionar"
23
+ evolved-note: "+gating por versión de lenguaje antes de marcar sintaxis como SyntaxError CRÍTICO: leer requires-python/target-version/tsconfig/edition y refutar con import+linter del stack (aplicación de verificar-citas Familia 2 a claims de sintaxis). Generalizable a cualquier lenguaje version-dependent. Origen: falso positivo PEP 758 (except A,B: en Python 3.14) en sistema-verificacion-oic."
24
24
  nivelRiesgo: BAJO
25
25
  skillsInvocables: [checklist-calidad, patrones-python, api-rest-diseno, tdd-workflow, verificar-trabajo, verificacion-evidencia, swl-revisar-impacto, prevencion-sobreingenieria]
26
26
  skillsRestringidos: []
@@ -68,13 +68,22 @@ Responsabilidades concretas:
68
68
 
69
69
  ## Protocolo obligatorio al iniciar
70
70
 
71
+ **Presupuesto de contexto (anti-thrashing):** tu ventana hereda el `CLAUDE.md`
72
+ del proyecto + las reglas globales del usuario. En proyectos rule-heavy eso
73
+ consume buena parte de la ventana antes de leer código — si además exploras el
74
+ codebase completo, saturas y entras en autocompact thrashing (0 tokens útiles,
75
+ observado 2026-06-05). Por eso: NO releas `CLAUDE.md` (ya está en tu contexto),
76
+ lee SOLO los archivos del alcance recibido, y carga `skillsInvocables` bajo
77
+ demanda — solo cuando el alcance concreto lo amerite, nunca al inicio "por si acaso".
78
+
71
79
  Antes de revisar cualquier código:
72
80
 
73
- 1. **Leer CLAUDE.md** del proyecto convenciones, anti-patrones conocidos.
74
- 2. **Obtener el diff** del cambio a revisar: `git diff main..HEAD` o leer
75
- los archivos indicados.
76
- 3. **Leer el contexto** archivos relacionados para entender el módulo completo,
77
- no solo el cambio aislado.
81
+ 1. **Obtener el diff / alcance**: usar los archivos indicados por quien delega;
82
+ si no se indicaron, `git diff main..HEAD --name-only`. NO releer CLAUDE.md
83
+ (ya está en tu contexto heredado).
84
+ 2. **Leer los archivos del alcance PRIMERO**, antes de cargar cualquier skill.
85
+ 3. **Leer contexto adicional solo si es necesario** para entender el cambio
86
+ acotado; no el módulo completo si el alcance es pequeño.
78
87
  4. **Verificar métricas base** con herramientas estáticas antes de hacer juicios.
79
88
 
80
89
  ## Revision en dos capas (obligatorio)
@@ -370,6 +379,19 @@ Solo los problemas CRÍTICOS bloquean el avance. MAYOR debe documentarse como de
370
379
  - Si el código es bueno, dilo explícitamente — los reportes vacíos de problemas
371
380
  son tan valiosos como los reportes con 10 problemas
372
381
  - No revises código que no puedes ejecutar ni compilar — pide el contexto necesario
382
+ - NUNCA marques una construcción sintáctica como SyntaxError CRÍTICO sin verificar
383
+ primero la **versión objetivo del lenguaje** del proyecto. Mucha sintaxis es
384
+ válida solo a partir de cierta versión (Python: `requires-python` /
385
+ `tool.ruff.target-version` en `pyproject.toml`; TypeScript: `target`/`lib` en
386
+ `tsconfig.json`; Java: `--release`; C#: `<LangVersion>`; Rust: edition). Antes
387
+ de emitir el veredicto bloqueante, lee la versión objetivo y **refuta el presunto
388
+ error con evidencia ejecutable** del stack (`python -c "import <módulo>"`,
389
+ `ruff check`, `tsc --noEmit`, el compilador correspondiente). Evidencia >
390
+ afirmación: si la construcción importa/compila bajo la versión objetivo, NO es
391
+ un hallazgo — degrádalo o elimínalo. Esta es la aplicación de
392
+ `verificar-citas Familia 2` a claims de sintaxis: un revisor que afirma
393
+ "SyntaxError" sin verificar contra el target propaga un falso positivo
394
+ bloqueante.
373
395
 
374
396
  ## Gotchas / Errores comunes no obvios
375
397
 
@@ -381,6 +403,8 @@ Solo los problemas CRÍTICOS bloquean el avance. MAYOR debe documentarse como de
381
403
 
382
404
  **Hallazgos sin ejemplo de corrección**: un hallazgo que solo señala el problema sin mostrar cómo arreglarlo no es accionable. Causa: el revisor describe el anti-patrón pero no la alternativa correcta. Solución: todo hallazgo CRÍTICO o MAYOR incluye el código incorrecto y el código correcto esperado.
383
405
 
406
+ **Marcar sintaxis version-dependent como SyntaxError sin verificar el target**: una construcción válida en la versión objetivo del proyecto se lee como error de sintaxis cuando el revisor la juzga contra su conocimiento general del lenguaje en vez de leer la versión objetivo. Causa: la validez sintáctica depende de la versión (`requires-python`/`target-version`, `tsconfig target`, `--release`, edition) y no es absoluta. Caso real (2026-06-05, `sistema-verificacion-oic`): `except A, B:` sin paréntesis — válido en Python ≥3.14 por PEP 758 — fue marcado como SyntaxError CRÍTICO/RECHAZADO en un proyecto con `requires-python >=3.14`; refutado con `python -c "import …"` + `ruff check` + CI verde. Solución: antes de un veredicto bloqueante por sintaxis, leer la versión objetivo del proyecto y refutar el presunto error con import/compilación real del stack (ver Reglas estrictas).
407
+
384
408
  ## Veto items — cap enforcement a 60/100
385
409
 
386
410
  Ciertos hallazgos son **no negociables** y violan reglas globales del sistema.
@@ -63,6 +63,13 @@ Antes de comenzar la auditoría:
63
63
  de archivos, autenticación, autorización, dependencias externas.
64
64
  3. **Obtener el diff** o la lista de archivos a auditar.
65
65
  4. **Mapear el flujo de datos**: de dónde viene el input, cómo se procesa, dónde se almacena.
66
+ 5. **Elegir el modo**: revisión de PR/diff (flujo estándar de abajo) o
67
+ **auditoría en profundidad** — en ese caso cargar
68
+ `Skill("checklist-seguridad")` y aplicar su *modo cobertura* (STRIDE +
69
+ OWASP con score compuesto, iterando con rotación de personas red-team y
70
+ registro en `hooks/lib/loop-telemetry.js`). Cada hallazgo se etiqueta con
71
+ ambas taxonomías y el reporte incluye la línea de cobertura
72
+ `OWASP: N/10 | STRIDE: M/6 | Score: X`.
66
73
 
67
74
  ## Flujo de trabajo paso a paso
68
75
 
@@ -11,9 +11,9 @@ model: claude-sonnet-4-6
11
11
  modeloAlterno: claude-haiku-4-5-20251001
12
12
  ventanaContexto: 200k
13
13
  color: purple
14
- version: 1.0.0
14
+ version: 1.1.0
15
15
  nivelRiesgo: BAJO
16
- skillsInvocables: [tdd-workflow, testing-python, checklist-calidad, manejo-errores, webapp-testing, php-testing, nextjs-testing]
16
+ skillsInvocables: [tdd-workflow, testing-python, checklist-calidad, manejo-errores, webapp-testing, php-testing, nextjs-testing, calidad-mutation-testing]
17
17
  skillsRestringidos: []
18
18
  permisosRed: false
19
19
  permisosEscritura: true
@@ -213,6 +213,27 @@ diff /tmp/baseline.txt /tmp/current.txt
213
213
  Toda regresión (test que antes pasaba y ahora falla) es un bloqueante.
214
214
  Reporta: qué test, qué falló, qué cambio lo causó.
215
215
 
216
+ ### Fase 6 — Gate de mutación (opt-in, módulos críticos)
217
+
218
+ La cobertura mide ejecución, no calidad de asserts. Cuando el módulo es
219
+ crítico (dinero, auth, cálculo regulatorio) Y hay runner de mutación
220
+ instalado Y la suite corre en <2 min, cerrar la auditoría con mutación
221
+ incremental sobre el diff:
222
+
223
+ 1. Cargar `Skill("calidad-mutation-testing")` — herramientas por stack,
224
+ modo incremental, umbrales por contexto.
225
+ 2. Correr la mutación SOLO sobre los archivos del diff de la fase
226
+ (`--since` / `--in-diff`), nunca el repo completo.
227
+ 3. Diagnosticar cada mutante sobreviviente: assert débil → endurecer el
228
+ assert; test faltante → escribir test de frontera dirigido; mutante
229
+ equivalente → excluir con anotación (NUNCA test artificial para matarlo).
230
+ 4. Reportar el mutation score junto a la cobertura. Umbral de referencia:
231
+ ≥85% en módulo crítico, ≥70% en lógica de negocio estándar.
232
+
233
+ Si las precondiciones no se cumplen (sin runner, suite lenta, suite roja),
234
+ omitir la fase y decirlo en el reporte — no es deuda silenciosa, es opt-in
235
+ documentado.
236
+
216
237
  ## Convenciones de escritura de tests
217
238
 
218
239
  ### Python (pytest)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: swl:autoresearch
3
- description: Ejecuta el loop de auto-mejora iterativa Autoresearch sobre un skill o agente. Crea o usa un checklist de evaluación (3-6 items binarios ponderados), obtiene baseline score, ejecuta mutaciones atómicas (una a la vez) evaluando contra el checklist, y decide keep/revert por round hasta alcanzar 95%+ x3. Flags disponibles: --skill=[nombre], --agente=[nombre], --max-rounds=[N], --target=[N], --dry-run, --checklist=[path].
3
+ description: Ejecuta el loop de auto-mejora iterativa Autoresearch sobre un skill, un agente, o (modo --codigo) sobre código del proyecto contra una métrica arbitraria. Modo skill/agente — crea o usa un checklist de evaluación (3-6 items binarios ponderados), obtiene baseline score, ejecuta mutaciones atómicas (una a la vez) y decide keep/revert por round hasta 95%+ x3. Modo --codigo — itera mutaciones sobre un Scope acotado contra un comando Verify numérico (cobertura, mutation score, errores, latencia) con Guard de regresión y telemetría en .planning/loops/. Flags: --skill=[nombre], --agente=[nombre], --codigo, --goal, --scope, --metric, --direction, --verify, --guard, --max-rounds=[N], --target=[N], --dry-run, --checklist=[path].
4
4
  allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
5
5
  ---
6
6
 
@@ -22,13 +22,20 @@ Este comando es distinto a `/swl:evolucionar`: donde evolucionar analiza evidenc
22
22
  ```
23
23
  --skill=[nombre] Skill a mejorar (busca en habilidades/[nombre]/SKILL.md)
24
24
  --agente=[nombre] Agente a mejorar (busca en agentes/[nombre].md)
25
- --max-rounds=[N] Máximo de iteraciones del loop (default: 10)
26
- --target=[N] Score objetivo en % (default: 95)
27
- --dry-run Analizar y crear checklist sin ejecutar mutaciones
28
- --checklist=[path] Ruta a checklist existente
25
+ --codigo Modo código: itera sobre código del proyecto contra una métrica (ver sección "Modo --codigo")
26
+ --goal="..." (--codigo) Meta textual del loop
27
+ --scope="glob" (--codigo) Archivos que el loop PUEDE modificar (glob acotado)
28
+ --metric="..." (--codigo) Qué mide la métrica (ej: "mutation score de src/pagos")
29
+ --direction=[dir] (--codigo) higher_is_better | lower_is_better
30
+ --verify="cmd" (--codigo) Comando shell cuya salida contiene el número de la métrica
31
+ --guard="cmd" (--codigo) Comando que debe pasar (exit 0) para aceptar una mutación
32
+ --max-rounds=[N] Máximo de iteraciones del loop (default: 10 skill/agente, 15 código)
33
+ --target=[N] Score objetivo (default: 95% en skills; en código lo define el usuario)
34
+ --dry-run Analizar y derivar configuración sin ejecutar mutaciones
35
+ --checklist=[path] Ruta a checklist existente (solo modo skill/agente)
29
36
  ```
30
37
 
31
- **Nota**: Se debe pasar `--skill` o `--agente`, no ambos. Si no se pasa ninguno, preguntar al usuario.
38
+ **Nota**: Se debe pasar `--skill`, `--agente` o `--codigo` (excluyentes). Si no se pasa ninguno, preguntar al usuario.
32
39
 
33
40
  ## Paso 0 — Parseo de flags y carga de habilidades
34
41
 
@@ -168,3 +175,92 @@ Si el score mejoró respecto al baseline:
168
175
  - Si después de 3 rounds sin mejora, preguntar al usuario si continuar o parar
169
176
  - El caso de prueba NO cambia durante el loop
170
177
  - Mantener log completo del loop para auditoría
178
+
179
+ ---
180
+
181
+ ## Modo `--codigo` — Loop métrico sobre código del proyecto
182
+
183
+ Generaliza el loop a **código del usuario**: la misma disciplina (mutación
184
+ atómica → medir → keep/revert) pero la evaluación es un **comando Verify
185
+ numérico** en lugar de un checklist. Patrón adoptado del análisis de
186
+ autoresearch v2.1 (loop core), adaptado a las reglas SWL (HITL, git-workflow,
187
+ telemetría en `.planning/loops/`).
188
+
189
+ Métricas típicas: mutation score (cargar `Skill("calidad-mutation-testing")`),
190
+ cobertura de tests, conteo de errores de tsc/lint (lower_is_better), latencia
191
+ p95 de un benchmark, bundle size, tiempo de suite.
192
+
193
+ ### Paso C0 — Derivar y aprobar la configuración (HITL obligatorio)
194
+
195
+ Completar con el usuario los campos faltantes y presentar el bloque para
196
+ aprobación explícita ANTES de la primera mutación:
197
+
198
+ ```
199
+ === Autoresearch --codigo — Configuración ===
200
+ Goal: [meta textual]
201
+ Scope: [glob de archivos que el loop PUEDE tocar]
202
+ Metric: [qué mide] | Direction: [higher|lower]_is_better
203
+ Verify: [comando shell]
204
+ Guard: [comando shell o "(ninguno)"]
205
+ Target: [valor objetivo o "(mejora máxima en N rounds)"]
206
+ Rounds: [N, default 15]
207
+ ```
208
+
209
+ **Safety screen del Verify/Guard (bloqueante)**: rechazar comandos que
210
+ contengan `rm -rf`, `curl|sh`/`wget|sh`, `sudo`, `git push`, `--force`,
211
+ redirecciones a archivos fuera del repo, o credenciales inline. El Verify se
212
+ ejecuta una vez en dry-run para confirmar que produce un número parseable —
213
+ si no, corregir el comando antes de iterar.
214
+
215
+ **Guard por default**: si el proyecto tiene suite de tests, el Guard es la
216
+ suite (`npm test` / `pytest`). Iterar sin Guard solo si el usuario lo aprueba
217
+ explícitamente — una métrica que sube con la suite rota no es mejora.
218
+
219
+ Si `--dry-run`: terminar aquí mostrando la configuración derivada.
220
+
221
+ ### Paso C1 — Baseline y telemetría
222
+
223
+ ```bash
224
+ node -e "const lt=require('./hooks/lib/loop-telemetry');const r=lt.iniciarCorrida({tipo:'autoresearch',direccion:'[direction]',config:{goal:'[goal]',scope:'[scope]',verify:'[verify]',guard:'[guard]'}});console.log(r.dir)"
225
+ ```
226
+
227
+ Correr Verify, extraer la métrica, registrar la iteración 0 (`estado:
228
+ baseline`). Si el baseline ya cumple el target, terminar: no hay loop que correr.
229
+
230
+ ### Paso C2 — El loop
231
+
232
+ Por cada round (hasta `--max-rounds`, default 15):
233
+
234
+ 1. **Revisar memoria**: últimas filas del TSV + `git log --oneline -10` — qué
235
+ funcionó, qué se revirtió. No repetir mutaciones ya revertidas.
236
+ 2. **UNA mutación atómica** dentro del Scope. Archivos fuera del Scope son
237
+ intocables — si la mejora "necesita" tocar otro archivo, pausar y
238
+ preguntar al usuario (anti-proxy-goal-drift).
239
+ 3. **Medir**: correr Verify → métrica nueva; correr Guard.
240
+ 4. **Decidir**:
241
+ - Métrica mejora Y Guard pasa → **keep**: commit `experiment(autoresearch): [descripción]`.
242
+ - Métrica no mejora O Guard falla → **revert**: descartar los cambios del
243
+ working tree (`git checkout -- [archivos tocados]`). NUNCA reescribir
244
+ historia para revertir — solo se commitea lo que se conserva.
245
+ - Verify truena → estado `crash`: descartar cambios, registrar, continuar.
246
+ 5. **Registrar** la iteración con `registrarIteracion` (métrica, delta, estado, descripción).
247
+ 6. **Condiciones de salida**: target alcanzado → ÉXITO; `detectarPlateau`
248
+ sobre las últimas 3 filas → PLATEAU (parar, no quemar rounds sin mejora);
249
+ 3 reverts consecutivos → ESTANCAMIENTO (preguntar al usuario);
250
+ max rounds → ACOTADO.
251
+
252
+ ### Paso C3 — Cierre
253
+
254
+ 1. Escribir handoff: `escribirHandoff(dir, {source: 'swl:autoresearch', status: [COMPLETO|PLATEAU|ACOTADO|INTERRUMPIDO], config})`.
255
+ 2. Reporte final con trayectoria (`analizarTrayectoria`): rounds, keep/revert,
256
+ métrica inicial → final, mayor salto, y los commits `experiment(...)` generados.
257
+ 3. Ofrecer al usuario squash de los commits experimentales en un commit
258
+ semántico final (`git-workflow.md § Squash antes de merge`).
259
+
260
+ ### Reglas adicionales del modo `--codigo`
261
+
262
+ - NUNCA `git push` desde el loop — los commits experimentales son locales.
263
+ - NUNCA tocar archivos fuera del Scope aprobado.
264
+ - NUNCA continuar tras plateau "por si acaso" — el plateau ES la señal de salida.
265
+ - El hook `contexto-iteracion.js` inyecta el estado del loop en sesiones
266
+ largas; no releer el TSV completo en cada round (las últimas 3 filas bastan).
@@ -22,6 +22,7 @@ costo estimado, herramientas más usadas y estado del presupuesto configurado.
22
22
  /swl:metricas — Resumen de métricas de la sesión
23
23
  /swl:metricas detalle — Desglose completo por herramienta y timeline
24
24
  /swl:metricas fases — Progreso de fases del proyecto desde feature-list.json
25
+ /swl:metricas loops — Trayectorias de loops iterativos desde .planning/loops/
25
26
  /swl:metricas historico — Abre el dashboard histórico multi-sesión (alias de /swl:dashboard)
26
27
  ```
27
28
 
@@ -318,6 +319,39 @@ node scripts/derivar-feature-list.js --check
318
319
 
319
320
  ---
320
321
 
322
+ ## Subcomando: `loops` — Trayectorias de loops iterativos
323
+
324
+ Si el usuario invoca `/swl:metricas loops`, leer las corridas registradas por
325
+ `hooks/lib/loop-telemetry.js` en `.planning/loops/`:
326
+
327
+ ```bash
328
+ node -e "
329
+ const fs = require('fs'), path = require('path');
330
+ const lt = require('./hooks/lib/loop-telemetry');
331
+ const base = path.join(process.cwd(), lt.DIR_LOOPS);
332
+ let dirs = [];
333
+ try { dirs = fs.readdirSync(base).map(d => path.join(base, d)).filter(d => fs.statSync(d).isDirectory()); } catch {}
334
+ if (dirs.length === 0) { console.log('(sin corridas de loops registradas)'); process.exit(0); }
335
+ for (const dir of dirs.sort().slice(-10)) {
336
+ try {
337
+ const t = lt.analizarTrayectoria(dir);
338
+ const h = lt.leerHandoff(dir);
339
+ console.log(path.basename(dir) + ' | iters: ' + t.totalIteraciones +
340
+ ' | keep/revert: ' + t.keeps + '/' + t.reverts +
341
+ ' | métrica: ' + t.metricaInicial + ' → ' + t.metricaFinal +
342
+ ' | plateau: ' + (t.plateau ? 'SÍ' : 'no') +
343
+ ' | status: ' + (h ? h.status : 'en curso'));
344
+ } catch (e) { console.log(path.basename(dir) + ' | (ilegible: ' + e.message + ')'); }
345
+ }
346
+ "
347
+ ```
348
+
349
+ Reportar al usuario en tabla: corrida, iteraciones, keep/revert rate, métrica
350
+ inicial → final, plateau y status del handoff. Si alguna corrida activa muestra
351
+ plateau, sugerir cerrarla — seguir iterando sin mejora quema tokens.
352
+
353
+ ---
354
+
321
355
  ## Subcomando: `historico`
322
356
 
323
357
  Si el usuario invoca `/swl:metricas historico`, redirigir inmediatamente a:
@@ -8,7 +8,7 @@ description: >
8
8
  automático para scope > 1500 LOC o > 5 archivos en módulos distintos.
9
9
  Persiste hallazgos en .planning/audit/findings/iter-N/.
10
10
  allowed-tools: [Read, Grep, Glob, Bash, Write, Agent, Skill]
11
- argument-hint: "[--remediar] [--pass1 | --pass2 | --continue] [--modulo <ruta>] [--redistribuir] [--reset-plan]"
11
+ argument-hint: "[--remediar] [--pass1 | --pass2 | --continue] [--modulo <ruta>] [--redistribuir] [--reset-plan] [--cross-model]"
12
12
  ---
13
13
 
14
14
  # /swl:nemesis — Auditoría iterativa con remediación opt-in
@@ -54,6 +54,29 @@ y el ciclo continúa hasta convergencia o agotar el guardrail de 3 iteraciones.
54
54
  | Acotar módulo | `--modulo <ruta>` | Limita el scope a un archivo o subdirectorio específico. Se combina con cualquier otro flag. |
55
55
  | Forzar redistribución | `--redistribuir` | Activa `Skill("nemesis-redistribuir")` aunque scope sea menor al umbral. |
56
56
  | Reset del plan | `--reset-plan` | Regenera `nemesis-plan.json` desde cero (descarta plan previo). |
57
+ | **Revisión cross-modelo** | `--cross-model` | Opt-in: rutea la evaluación a un reviewer en OTRO modelo (vía MCP, p.ej. `gemini-review`/`codex-review`) para combatir *self-preferential bias*. Degrada al reviewer same-model si no hay MCP configurado (anuncia la degradación). Combina con `--remediar`. Ver `Skill("proceso-dynamic-workflows") § Revisión cross-modelo`. |
58
+
59
+ ## Revisión cross-modelo (`--cross-model`)
60
+
61
+ El reviewer adversarial en el MISMO modelo aún arrastra *self-preferential bias*
62
+ (uno de los 3 modos de falla nombrados en el blog oficial de dynamic workflows).
63
+ `--cross-model` hace que la evaluación la emita un modelo DISTINTO al ejecutor:
64
+
65
+ - **Wiring (opt-in, ligero)**: si hay un MCP reviewer configurado (patrón ARIS
66
+ `gemini-review`/`codex-review`: expone `review`/`review_reply`, devuelve JSON con
67
+ `threadId` + `response`), el paso de evaluación se rutea a ese MCP. swl-ses NO
68
+ embebe el servidor — lo provee el usuario con su API key del otro modelo.
69
+ - **Degradación explícita** (regla `arreglar-al-detectar.md` / no-fallback-silencioso):
70
+ si el MCP no está disponible, NO falla — usa el reviewer same-model y **anuncia**
71
+ "cross-model solicitado pero MCP ausente → degradado a same-model".
72
+ - **Reviewer memory + debate** (de ARIS `auto-review-loop`): el reviewer externo
73
+ arrastra sospechas entre iteraciones (un `threadId`); el ejecutor puede rebatir,
74
+ el reviewer falla el veredicto final — *"it can drive, never acquit"*.
75
+ - **Trazabilidad**: el JSON del reviewer (`threadId`, `response`, score) se persiste
76
+ junto a `evaluacion.json` en `.planning/audit/findings/iter-N/` → veredicto
77
+ independiente auditable.
78
+
79
+ Detalle del patrón: `Skill("proceso-dynamic-workflows") § Revisión cross-modelo`.
57
80
 
58
81
  ## Flujo completo con `--remediar`
59
82
 
@@ -207,6 +230,24 @@ Estructura de salida bajo `.planning/audit/findings/`:
207
230
 
208
231
  Cada `evaluacion.json` sigue el schema `nemesis-evaluacion-json` v1.0.0.
209
232
 
233
+ ### Telemetría de loop (obligatoria con `--remediar`)
234
+
235
+ En modo `--remediar`, además de los `iter-N/` el comando registra la
236
+ trayectoria en el formato estándar de telemetría de loops
237
+ (`hooks/lib/loop-telemetry.js`). Esto habilita: inyección de estado por el
238
+ hook `contexto-iteracion.js` durante las ejecuciones largas (8-30 turnos),
239
+ detección de plateau, y lectura de la corrida por `/swl:metricas`.
240
+
241
+ - Al iniciar iter-1: `iniciarCorrida({tipo: 'nemesis', direccion: 'lower_is_better', config: {modulo, maxIter: 3}})`.
242
+ - Tras cada iteración: `registrarIteracion(dir, {iteracion: N, metrica: criticos+altos, delta, estado: 'keep', descripcion: 'iter N: status=<status>, X criticos, Y altos'})`.
243
+ - Al cerrar (PASS, FAIL o Recovery Catalog): `escribirHandoff(dir, {source: 'swl:nemesis', status, findings: <hallazgos residuales con archivo_linea>, config})`.
244
+ Mapeo de status: PASS → `COMPLETO`, max iteraciones → `ACOTADO`, Recovery
245
+ Catalog/escalada → `INTERRUMPIDO`.
246
+
247
+ El `handoff.json` resultante es consumible por una corrida posterior de
248
+ `/swl:verificar --until-converge` o por el orquestador (los `findings`
249
+ traen `archivo_linea` verificable según `verificar-citas-normativas.md § Familia 2`).
250
+
210
251
  ## Cómo interpretar el reporte
211
252
 
212
253
  ### Severidades
@@ -161,6 +161,14 @@ El agente planificador-swl debe generar el plan con esta estructura exacta:
161
161
  ## Tests requeridos
162
162
  [lista de tests que deben existir al finalizar la fase]
163
163
 
164
+ ## Escenarios Gherkin (opt-in — solo si la fase tiene criterios de aceptación de negocio)
165
+ [Si el CONTEXTO.md/PRD trae criterios de aceptación con reglas de negocio
166
+ distinguibles, convertirlos en escenarios Given–When–Then siguiendo
167
+ `habilidades/tdd-workflow/recursos/gherkin-bdd.md` y presentarlos al usuario
168
+ para validación ANTES de aprobar el plan. Cada escenario validado se referencia
169
+ desde la tarea que lo implementa (será su test RED). Omitir esta sección en
170
+ fases técnicas puras — Gherkin sin lector de negocio es ceremonia.]
171
+
164
172
  ## Riesgos y mitigaciones
165
173
  | Riesgo | Impacto | Probabilidad | Mitigación |
166
174
  |--------|---------|-------------|-----------|