@saulwade/swl-ses 2.6.0 → 2.6.1

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 (207) hide show
  1. package/CLAUDE.md +197 -197
  2. package/README.md +600 -600
  3. package/agentes/_intent-spec.md +73 -73
  4. package/agentes/_propose-step.md +90 -90
  5. package/agentes/accesibilidad-wcag-swl.md +690 -690
  6. package/agentes/arquitecto-swl.md +267 -267
  7. package/agentes/auto-evolucion-swl.md +932 -932
  8. package/agentes/backend-csharp-swl.md +420 -420
  9. package/agentes/backend-go-swl.md +390 -390
  10. package/agentes/backend-java-swl.md +281 -281
  11. package/agentes/backend-rust-swl.md +364 -364
  12. package/agentes/backend-workers-swl.md +482 -482
  13. package/agentes/cloud-infra-swl.md +509 -509
  14. package/agentes/consolidador-swl.md +541 -541
  15. package/agentes/depurador-swl.md +352 -352
  16. package/agentes/devops-ci-swl.md +400 -400
  17. package/agentes/disenador-ui-swl.md +569 -569
  18. package/agentes/documentador-swl.md +345 -345
  19. package/agentes/frontend-angular-swl.md +621 -621
  20. package/agentes/frontend-css-swl.md +716 -716
  21. package/agentes/frontend-react-swl.md +692 -692
  22. package/agentes/frontend-swl.md +496 -496
  23. package/agentes/frontend-tailwind-swl.md +826 -826
  24. package/agentes/investigador-swl.md +432 -432
  25. package/agentes/investigador-ux-swl.md +505 -505
  26. package/agentes/migrador-swl.md +442 -442
  27. package/agentes/mobile-android-swl.md +511 -511
  28. package/agentes/mobile-cross-swl.md +541 -541
  29. package/agentes/mobile-ios-swl.md +502 -502
  30. package/agentes/mobile-testing-swl.md +302 -302
  31. package/agentes/nemesis-auditor-swl.md +285 -285
  32. package/agentes/observabilidad-swl.md +438 -438
  33. package/agentes/pagos-swl.md +310 -310
  34. package/agentes/perfilador-usuario-swl.md +321 -321
  35. package/agentes/planificador-swl.md +399 -399
  36. package/agentes/producto-prd-swl.md +589 -589
  37. package/agentes/red-team-swl.md +218 -218
  38. package/agentes/release-manager-swl.md +590 -590
  39. package/agentes/rendimiento-swl.md +713 -713
  40. package/agentes/revisor-angular-swl.md +278 -278
  41. package/agentes/revisor-csharp-swl.md +264 -264
  42. package/agentes/revisor-go-swl.md +259 -259
  43. package/agentes/revisor-java-swl.md +257 -257
  44. package/agentes/revisor-kotlin-swl.md +273 -273
  45. package/agentes/revisor-nextjs-swl.md +281 -281
  46. package/agentes/revisor-php-swl.md +271 -271
  47. package/agentes/revisor-react-swl.md +278 -278
  48. package/agentes/revisor-rust-swl.md +346 -346
  49. package/agentes/revisor-seguridad-swl.md +399 -399
  50. package/agentes/revisor-swift-swl.md +268 -268
  51. package/agentes/revisor-typescript-swl.md +346 -346
  52. package/agentes/tdd-qa-swl.md +393 -393
  53. package/comandos/swl/actualizar.md +174 -174
  54. package/comandos/swl/adoptar-proyecto.md +265 -265
  55. package/comandos/swl/aprender.md +836 -836
  56. package/comandos/swl/aprobar-plan.md +146 -146
  57. package/comandos/swl/auditar-deps.md +134 -134
  58. package/comandos/swl/autoresearch.md +264 -264
  59. package/comandos/swl/ayuda.md +224 -224
  60. package/comandos/swl/brainstorm.md +51 -51
  61. package/comandos/swl/briefing.md +119 -119
  62. package/comandos/swl/checkpoint.md +325 -325
  63. package/comandos/swl/claudemd.md +234 -234
  64. package/comandos/swl/compactar.md +310 -310
  65. package/comandos/swl/configurar-ci.md +235 -235
  66. package/comandos/swl/contexto.md +110 -110
  67. package/comandos/swl/contribuir.md +233 -233
  68. package/comandos/swl/crear-skill.md +292 -292
  69. package/comandos/swl/cron.md +194 -194
  70. package/comandos/swl/discutir-fase.md +169 -169
  71. package/comandos/swl/ejecutar-fase.md +233 -233
  72. package/comandos/swl/evaluar-skill.md +520 -520
  73. package/comandos/swl/evolucion-continua.md +73 -73
  74. package/comandos/swl/evolucionar.md +267 -267
  75. package/comandos/swl/exportar-vault.md +583 -583
  76. package/comandos/swl/fix.md +118 -118
  77. package/comandos/swl/gateway.md +158 -158
  78. package/comandos/swl/inbox.md +116 -116
  79. package/comandos/swl/instalar.md +220 -220
  80. package/comandos/swl/instintos.md +86 -86
  81. package/comandos/swl/mapear-codebase.md +312 -312
  82. package/comandos/swl/mcp-status.md +175 -175
  83. package/comandos/swl/modelo.md +100 -100
  84. package/comandos/swl/nemesis.md +433 -433
  85. package/comandos/swl/notificaciones.md +299 -299
  86. package/comandos/swl/nuevo-proyecto.md +251 -251
  87. package/comandos/swl/planear-fase.md +263 -263
  88. package/comandos/swl/plugins.md +256 -256
  89. package/comandos/swl/predecir.md +169 -169
  90. package/comandos/swl/reflect-skills.md +125 -125
  91. package/comandos/swl/release.md +450 -450
  92. package/comandos/swl/revisar-impacto.md +201 -201
  93. package/comandos/swl/revisar.md +330 -330
  94. package/comandos/swl/seguridad.md +189 -189
  95. package/comandos/swl/sesiones.md +200 -200
  96. package/comandos/swl/skill-search.md +113 -113
  97. package/comandos/swl/status.md +345 -345
  98. package/comandos/swl/verificar.md +817 -817
  99. package/comandos/swl/wiki.md +620 -620
  100. package/gateway/cron/jobs.example.json +12 -12
  101. package/habilidades/auto-evolucion-protocolo/SKILL.md +294 -294
  102. package/habilidades/backend-async-postgres-testing/SKILL.md +2 -1
  103. package/habilidades/changelog-generator/SKILL.md +174 -174
  104. package/habilidades/compactacion-contexto/SKILL.md +2 -1
  105. package/habilidades/contenedores-docker/SKILL.md +4 -2
  106. package/habilidades/doubt-driven-review/SKILL.md +207 -207
  107. package/habilidades/drift-detection/SKILL.md +1 -1
  108. package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -278
  109. package/habilidades/extractor-de-aprendizajes/SKILL.md +8 -2
  110. package/habilidades/git-worktrees-paralelo/SKILL.md +19 -1
  111. package/habilidades/harness-claude-code/SKILL.md +314 -314
  112. package/habilidades/instalar-sistema/SKILL.md +227 -227
  113. package/habilidades/planear-fase/SKILL.md +358 -358
  114. package/habilidades/prevencion-sobreingenieria/recursos/soluciones-nativas.md +166 -166
  115. package/habilidades/prevencion-sobreingenieria/recursos/variables-residuales-post-refactor.md +85 -85
  116. package/habilidades/proceso-ingenieria-requerimientos/SKILL.md +147 -147
  117. package/habilidades/release-semver/SKILL.md +2 -2
  118. package/habilidades/tdd-workflow/SKILL.md +749 -749
  119. package/hooks/agente-lifecycle.js +1 -1
  120. package/hooks/audit-trail.js +1 -1
  121. package/hooks/auto-consolidacion.js +1 -1
  122. package/hooks/captura-acciones-post.js +1 -1
  123. package/hooks/captura-acciones-session.js +1 -1
  124. package/hooks/captura-feedback-usuario.js +1 -1
  125. package/hooks/contexto-iteracion.js +1 -1
  126. package/hooks/contexto-subagente.js +68 -68
  127. package/hooks/degradacion-instintos.js +1 -1
  128. package/hooks/grafo-contexto.js +1 -1
  129. package/hooks/guardrail-modelo.js +1 -1
  130. package/hooks/inbox-aviso.js +1 -1
  131. package/hooks/inyeccion-contexto.js +1 -1
  132. package/hooks/lib/agent-matcher.js +1 -1
  133. package/hooks/lib/agent-routing.js +1 -1
  134. package/hooks/lib/captura-acciones.js +1 -1
  135. package/hooks/lib/etapa-metricas.js +1 -1
  136. package/hooks/lib/evolution-tracker.js +1 -1
  137. package/hooks/lib/gateway-notify.js +193 -193
  138. package/hooks/lib/mcp-health.js +1 -1
  139. package/hooks/lib/notificacion-formato.js +58 -0
  140. package/hooks/lib/nudge-tracker.js +1 -1
  141. package/hooks/lib/otlp-exporter.js +1 -1
  142. package/hooks/lib/propose-step.js +1 -1
  143. package/hooks/lib/raiz-proyecto.js +127 -102
  144. package/hooks/lib/run-log.js +1 -1
  145. package/hooks/lib/singleton-guard.js +20 -13
  146. package/hooks/lib/telegram-cliente.js +11 -3
  147. package/hooks/notificacion-telegram.js +13 -3
  148. package/hooks/preservar-estado-pre-compact.js +1 -1
  149. package/hooks/registro-turnos.js +1 -1
  150. package/hooks/resumen-sesion.js +1 -1
  151. package/hooks/risk-scoring.js +1 -1
  152. package/hooks/session-briefing.js +1 -1
  153. package/hooks/spec-gate.js +1 -1
  154. package/hooks/sugerir-regenerar-inventario.js +1 -1
  155. package/hooks/tdd-gate.js +1 -1
  156. package/hooks/telemetria-agentes.js +1 -1
  157. package/hooks/telemetria-skill-routing.js +1 -1
  158. package/hooks/tracking-costos.js +1 -1
  159. package/hooks/validar-formato-post-subagente.js +1 -1
  160. package/hooks/validar-intent-spec.js +1 -1
  161. package/hooks/validar-planning-paths.js +1 -1
  162. package/llms.txt +29 -29
  163. package/manifiestos/canonical-hashes.json +5588 -5257
  164. package/manifiestos/hooks-config.json +469 -469
  165. package/manifiestos/invariantes-criticos.json +30 -30
  166. package/manifiestos/modulos.json +1429 -1428
  167. package/manifiestos/skills-lock.json +1275 -1275
  168. package/package.json +94 -94
  169. package/plugin.json +369 -369
  170. package/scripts/auditar-clases-conocidas.js +134 -134
  171. package/scripts/bootstrap-instintos.js +85 -14
  172. package/scripts/canario-hooks.js +166 -166
  173. package/scripts/cli/autonomia.js +23 -23
  174. package/scripts/cli/benchmark-memoria.js +37 -37
  175. package/scripts/cli/ciclo-autonomo.js +73 -73
  176. package/scripts/cli/ciclo-fase-b.js +102 -102
  177. package/scripts/cli/guardrail-metrics.js +39 -39
  178. package/scripts/cli/memoria-search.js +69 -69
  179. package/scripts/cli/nudge-accionar.js +39 -39
  180. package/scripts/cli/run-eval.js +38 -38
  181. package/scripts/doctor.js +26 -3
  182. package/scripts/evidencia-valor.js +101 -101
  183. package/scripts/field-report.js +16 -16
  184. package/scripts/instalador.js +13 -0
  185. package/scripts/lib/activar-hooks-proyecto.js +116 -116
  186. package/scripts/lib/ciclo-autonomo/candidatos.js +174 -174
  187. package/scripts/lib/ciclo-autonomo/config.js +165 -165
  188. package/scripts/lib/ciclo-autonomo/drenador-feedback.js +174 -174
  189. package/scripts/lib/ciclo-autonomo/fallback.js +77 -77
  190. package/scripts/lib/ciclo-autonomo/guard-convivencia.js +139 -139
  191. package/scripts/lib/ciclo-autonomo/higiene-nudges.js +112 -112
  192. package/scripts/lib/ciclo-autonomo/index.js +301 -301
  193. package/scripts/lib/ciclo-autonomo/lock.js +124 -124
  194. package/scripts/lib/ciclo-autonomo/presupuesto.js +122 -122
  195. package/scripts/lib/ciclo-autonomo/puente-degradacion.js +240 -240
  196. package/scripts/lib/ciclo-autonomo/runner-fase-b.js +248 -248
  197. package/scripts/lib/ciclo-autonomo/writer-instintos.js +190 -190
  198. package/scripts/lib/ciclo-autonomo/yaml-instintos.js +535 -535
  199. package/scripts/lib/evidencia-valor.js +228 -228
  200. package/scripts/lib/expandir-targets.js +71 -71
  201. package/scripts/lib/limpiar-basura-global.js +161 -0
  202. package/scripts/lib/toml-merge.js +204 -204
  203. package/scripts/mcp-server/auth.js +105 -105
  204. package/scripts/mcp-server/cache.js +106 -106
  205. package/scripts/tui/pantallas/install-wizard.js +403 -403
  206. package/instintos/.backups/perfil-usuario.yaml.2026-07-10-165128.bak +0 -53
  207. package/instintos/.backups/proyecto.yaml.2026-07-10-165128.bak +0 -372
@@ -1,433 +1,433 @@
1
- ---
2
- name: swl:nemesis
3
- description: >
4
- Auditoría iterativa Feynman + State Inconsistency con loop evaluator-optimizer
5
- opcional. Sin flag --remediar: solo audita (comportamiento clásico de
6
- v1.5.x). Con --remediar: ciclo audit→fix→re-audit hasta convergencia
7
- (max 3 iteraciones, Recovery Catalog si no converge). Modo redistribuido
8
- automático para scope > 1500 LOC o > 5 archivos en módulos distintos.
9
- Persiste hallazgos en .planning/audit/findings/iter-N/.
10
- allowed-tools: [Read, Grep, Glob, Bash, Write, Agent, Skill]
11
- argument-hint: "[--remediar] [--pass1 | --pass2 | --continue] [--modulo <ruta>] [--redistribuir] [--reset-plan] [--cross-model]"
12
- ---
13
-
14
- # /swl:nemesis — Auditoría iterativa con remediación opt-in
15
-
16
- Dos auditores en loop interno (Feynman + State Inconsistency) detectan bugs de
17
- profundidad que el código superficialmente correcto esconde. Con el flag
18
- `--remediar` el comando entra en modo **evaluator-optimizer** (patrón oficial
19
- de Anthropic, ADR-0021): el agente nemesis evalúa, el orquestador-swl remedia,
20
- y el ciclo continúa hasta convergencia o agotar el guardrail de 3 iteraciones.
21
-
22
- ## Cuándo invocar
23
-
24
- - El módulo pasó `/swl:revisar` con score ≥ 9.0 pero hay sospechas de bugs
25
- de lógica profunda que el revisor de código no captura (suposiciones
26
- incorrectas, invariantes rotos, condiciones de carrera sutiles).
27
- - Antes de un release de componente crítico: auth, pagos, contratos, permisos.
28
- - Cuando un bug en producción se atribuye a lógica aparentemente correcta —
29
- usar Nemesis para encontrar el patrón de fallo subyacente.
30
- - Para módulos legacy con alta deuda técnica donde los tests no cubren los
31
- caminos de estado.
32
- - **Para cerrar el loop audit→fix→re-audit en una sola invocación**: usar
33
- `/swl:nemesis --remediar`. La autonomía es opt-in.
34
-
35
- ## Cuándo NO invocar
36
-
37
- - El módulo tiene menos de 200 LOC y es CRUD simple sin lógica de negocio.
38
- - Se necesita revisión de estilo, naming o cobertura de tests — usar
39
- `/swl:revisar` en su lugar.
40
- - El proyecto no tiene `agentes/nemesis-auditor-swl.md` instalado — verificar
41
- con `ls agentes/ | grep nemesis` antes de invocar.
42
- - La tarea urgente es un hotfix en producción — Nemesis con `--remediar` es
43
- deliberado (8-30 turnos); en incidente activo, usar `/swl:verificar` acotado.
44
-
45
- ## Modos disponibles
46
-
47
- | Modo | Flag | Descripción |
48
- |---|---|---|
49
- | **Solo auditar** (default) | (sin flag) | Pasada 1 (Feynman) + Pasada 2 (State) + N alternadas hasta convergencia interna, máximo 6 pasadas. Entrega reporte. NO remedia. Retrocompatible con v1.5.x. |
50
- | **Loop completo** | `--remediar` | Evaluator-optimizer: audita → invoca `orquestador-swl` con hallazgos → re-audita. Max 3 iteraciones. Convergencia cuando status=PASS. Recovery Catalog si no converge. |
51
- | Solo Feynman | `--pass1` | Una pasada Feynman exhaustiva; no ejecuta State. Ortogonal a `--remediar`. |
52
- | Solo State | `--pass2` | Una pasada State Inconsistency; puede alimentarse con findings previos. |
53
- | Retomar | `--continue` | Continúa desde la última iteración registrada en `.planning/audit/findings/`. |
54
- | Acotar módulo | `--modulo <ruta>` | Limita el scope a un archivo o subdirectorio específico. Se combina con cualquier otro flag. |
55
- | Forzar redistribución | `--redistribuir` | Activa `Skill("nemesis-redistribuir")` aunque scope sea menor al umbral. |
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`.
80
-
81
- ## Flujo completo con `--remediar`
82
-
83
- ```
84
- # iter usa indexing 1-based para alinear con el agente y los output paths
85
- # (.planning/audit/findings/iter-1/, iter-2/, iter-3/). Max 3 iteraciones.
86
- iter = 1
87
- MAX_ITER = 3
88
- evaluacion = null
89
-
90
- # Fase 0 del comando: análisis del scope
91
- loc_total, modulos = analizar_scope(modulo_arg or "directorio actual")
92
-
93
- # Decisión de redistribuir:
94
- # 1. --redistribuir explícito siempre activa redistribución (override del usuario).
95
- # 2. --modulo respeta el scope acotado por el usuario y NO redistribuye, aunque
96
- # excede umbrales. El usuario ya delimitó intencionalmente.
97
- # 3. Sin --modulo: umbrales automáticos (> 1500 LOC ó > 5 módulos distintos).
98
- redistribuir = flag_redistribuir or (
99
- not flag_modulo and (loc_total > 1500 or modulos > 5)
100
- )
101
-
102
- if redistribuir:
103
- cargar Skill("nemesis-redistribuir")
104
- plan = generar_plan_redistribuido(scope)
105
- persistir plan en .planning/audit/nemesis-plan.json
106
- sub_scopes = plan.sub_scopes
107
- else:
108
- sub_scopes = [scope_unico]
109
-
110
- # Fase 1+: loop evaluator-optimizer (iter ∈ {1, 2, 3})
111
- while iter <= MAX_ITER:
112
- # Evaluator: invocar nemesis-auditor-swl una vez por sub-scope.
113
- # En modo redistribuido cada sub_scope tiene un `id` (declarado en
114
- # nemesis-plan.json) que el agente USA para construir la ruta de output
115
- # `.planning/audit/findings/iter-N/<sub_id>/`. Sin sub_id, los reportes
116
- # se sobrescribirían entre sub-scopes. En modo monolítico sub_id queda
117
- # `null` y el agente escribe a `iter-N/` (sin subdirectorio).
118
- for sub_scope in sub_scopes:
119
- sub_id = sub_scope.id if redistribuir else null
120
- invocar(nemesis-auditor-swl, sub_scope, iter=iter, sub_id=sub_id)
121
- # Produce:
122
- # redistribuido → .planning/audit/findings/iter-N/<sub_id>/evaluacion.json + .md
123
- # monolítico → .planning/audit/findings/iter-N/evaluacion.json + .md
124
-
125
- # Consolidar (si modo redistribuido)
126
- evaluacion = consolidar_evaluaciones(iter)
127
- # Produce: .planning/audit/findings/iter-N/evaluacion.json consolidado
128
- # (en modo monolítico no hay consolidación: el archivo ya está en iter-N/)
129
-
130
- # Decisión sobre el JSON consolidado
131
- if evaluacion.veredicto.status == "PASS":
132
- emitir_reporte_final(evaluacion)
133
- return { exito: True, iters: iter, evaluacion } # convergencia
134
-
135
- if not flag_remediar:
136
- emitir_reporte(evaluacion)
137
- return { exito: False, iters: iter, evaluacion } # solo audita
138
-
139
- if evaluacion.veredicto.status == "FAIL":
140
- return activar_recovery_catalog("escalate", evaluacion.veredicto.razon_si_fail)
141
-
142
- if not evaluacion.veredicto.puede_remediar_automaticamente:
143
- return activar_recovery_catalog("escalate", "Hallazgos no auto-remediables")
144
-
145
- # Generator: invocar orquestador-swl con hallazgos como input
146
- invocar(
147
- orquestador-swl,
148
- hallazgos=evaluacion.hallazgos,
149
- feedback=evaluacion,
150
- intentos_previos=hallazgos_de_iters_anteriores(iter),
151
- iter=iter,
152
- )
153
- iter += 1
154
-
155
- # max-iter agotado sin PASS
156
- return activar_recovery_catalog_secuencial(evaluacion)
157
- # orden: reprompt(1ª) → reduce-autonomy(2ª) → escalate(3ª)
158
- ```
159
-
160
- Los `return` son explícitos. Sin `--remediar`, el `return` del bloque
161
- `if not flag_remediar` impide que el flujo alcance la invocación del
162
- orquestador. La retrocompatibilidad es por construcción.
163
-
164
- ## Activación de redistribución (Fase 0)
165
-
166
- | Condición | Acción |
167
- |---|---|
168
- | `loc_total > 1500` | Cargar `Skill("nemesis-redistribuir")` |
169
- | `archivos_modulos_distintos > 5` | Cargar `Skill("nemesis-redistribuir")` |
170
- | `--redistribuir` explícito | Cargar `Skill("nemesis-redistribuir")` |
171
- | `--modulo <ruta>` con scope acotado | NO redistribuir (respetar decisión explícita del usuario) |
172
-
173
- Cuando se activa, el comando registra un nudge en `.planning/nudges.jsonl`:
174
-
175
- ```json
176
- {
177
- "timestamp": "<ISO 8601>",
178
- "tipo": "nemesis-redistribuido",
179
- "mutation_category": "scope-adaptation",
180
- "risk_level": "low",
181
- "razon": "loc_total=3170 (>1500)",
182
- "sub_scopes": 3,
183
- "archivo_plan": ".planning/audit/nemesis-plan.json"
184
- }
185
- ```
186
-
187
- ## Recovery Catalog cuando max-iter sin PASS
188
-
189
- Tras 3 iteraciones del loop sin alcanzar `status=PASS`, el comando aplica en
190
- orden estricto el catálogo de `reglas/seguridad-agentes.md § Recovery Catalog`:
191
-
192
- 1. **reprompt** (excedencia 1): re-invoca al orquestador con feedback reforzado
193
- (qué hallazgos quedaron sin resolver, constraints adicionales). Una sola vez.
194
- 2. **reduce-autonomy** (excedencia 2 consecutiva): baja `nivelRiesgo` efectivo,
195
- pide confirmación al usuario antes de cada acción del generator.
196
- 3. **escalate** (excedencia 3): pausa la cadena, invoca `notificador-swl`,
197
- espera decisión humana del usuario.
198
- 4. **terminate**: solo si el evaluator detecta violación de regla de seguridad
199
- explícita (no por simple no-convergencia).
200
-
201
- Cada activación se registra en `.planning/nudges.jsonl` con
202
- `mutation_category: repair` y `risk_level` proporcional.
203
-
204
- ## Qué produce
205
-
206
- Estructura de salida bajo `.planning/audit/findings/`:
207
-
208
- ```
209
- .planning/audit/findings/
210
- ├── nemesis-plan.json # solo si modo redistribuido
211
- ├── iter-1/
212
- │ ├── feynman-pass1.md # output crudo Feynman
213
- │ ├── feynman-pass2.md # si hubo segunda pasada Feynman
214
- │ ├── state-pass1.md # output crudo State
215
- │ ├── state-pass2.md # si hubo segunda pasada State
216
- │ ├── nemesis-verified.md # reporte legible consolidado
217
- │ ├── evaluacion.json # veredicto estructurado
218
- │ ├── sub-1/ # solo en modo redistribuido
219
- │ │ ├── feynman-pass1.md
220
- │ │ ├── state-pass1.md
221
- │ │ ├── nemesis-verified.md
222
- │ │ └── evaluacion.json
223
- │ ├── sub-2/
224
- │ └── sub-3/
225
- ├── iter-2/ # solo si --remediar y no convergió en iter 1
226
- │ └── (mismo formato)
227
- └── iter-3/ # último intento si --remediar y no convergió
228
- └── (mismo formato)
229
- ```
230
-
231
- Cada `evaluacion.json` sigue el schema `nemesis-evaluacion-json` v1.0.0.
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:status 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
-
251
- ## Cómo interpretar el reporte
252
-
253
- ### Severidades
254
-
255
- | Nivel | Criterio |
256
- |---|---|
257
- | CRÍTICO | Explotable sin precondiciones; pérdida de datos o control total |
258
- | ALTO | Explotable bajo condiciones razonables; impacto severo |
259
- | MEDIO | Requiere condiciones específicas; impacto moderado |
260
- | BAJO | Impacto menor o difícil de explotar; documentar para trazabilidad |
261
-
262
- ### Discovery path
263
-
264
- - `Feynman-only`: Feynman lo detectó; State no lo confirmó ni refutó.
265
- - `State-only`: State Inconsistency lo encontró analizando mutaciones.
266
- - `Cross-feed Pass N → Pass M`: Feynman marcó un sospechoso en la pasada N;
267
- State lo confirmó como bug real en la pasada M (o viceversa). Estos
268
- hallazgos son los más confiables.
269
-
270
- ### Veredicto JSON
271
-
272
- Los tres status del JSON estructurado del evaluator (definidos canónicamente
273
- en `agentes/nemesis-auditor-swl.md § Veredicto status`):
274
-
275
- - **`status: "PASS"`** — convergencia. 0 críticos + 0 altos. Pueden quedar
276
- hallazgos MEDIOS/BAJOS/informativos. El loop termina con éxito.
277
-
278
- - **`status: "NEEDS_IMPROVEMENT"`** — hay críticos o altos pero **todos** tienen
279
- `accion_sugerida` concreta + `agente_recomendado` válido. El comando con
280
- `--remediar` invoca al `orquestador-swl` automáticamente. Sin `--remediar`,
281
- el reporte queda como acción pendiente para el usuario.
282
-
283
- - **`status: "FAIL"`** — hay al menos un hallazgo que cumple cualquiera de:
284
- - Veto items según `reglas/gobernanza.md § Veto items`.
285
- - Cambio arquitectural ambiguo (requiere ADR / decisión del usuario).
286
- - Decisión de producto (comportamiento esperado no definido).
287
- - Datos de entrada inválidos en el alcance auditado.
288
-
289
- El loop se detiene de inmediato y escala a Recovery Catalog. Origen del
290
- refuerzo: SIGAF sesión 2026-05-21 (alineación L2 — el comando y el agente
291
- deben tener idéntico criterio de FAIL para evitar loops vacíos).
292
-
293
- **Regla de consistencia**: si esta sección del comando y la del agente
294
- diverge en wording, el agente es la fuente de verdad operacional (lo
295
- implementa). Actualizar el comando para alinear, NO al revés.
296
-
297
- ## Costo estimado
298
-
299
- | Modo | Turnos aproximados |
300
- |---|---|
301
- | Solo auditar, módulo pequeño (< 500 LOC) | 8-12 |
302
- | Solo auditar, módulo mediano (500-1500 LOC) | 12-18 |
303
- | Solo auditar, módulo grande (> 1500 LOC, modo redistribuido) | 18-30 |
304
- | `--remediar`, módulo pequeño, converge en 1 iter | 12-18 |
305
- | `--remediar`, módulo mediano, 2-3 iters | 20-40 |
306
- | `--remediar`, módulo grande con redistribución, 3 iters | 40-70 |
307
- | Solo `--pass1` o `--pass2` | 4-8 |
308
-
309
- El costo del modo `--remediar` es 3-5× el del modo solo auditar. Es opt-in
310
- deliberado del usuario, no default.
311
-
312
- ### Calibración para módulos pequeños con alta densidad de control de flujo
313
-
314
- Aunque la tabla estima 12-18 turnos para `--remediar` sobre módulo pequeño
315
- (< 500 LOC), el valor agregado es desproporcionadamente alto cuando el
316
- módulo concentra **lógica de control de flujo** (event handlers,
317
- callbacks, `setTimeout`/`setInterval`, readline, promises, race conditions).
318
- La densidad de bugs latentes en este tipo de código es alta, y nemesis los
319
- detecta donde la revisión one-shot no.
320
-
321
- **Patrón confirmado en swl-ses v1.6.0** (sesión 2026-05-16): `--remediar`
322
- sobre `scripts/lib/ui.js` (~300 LOC con spinner + readline + prompts)
323
- convergió en iter-2 con 15 turnos totales. Iter-1 detectó dos hallazgos
324
- adicionales que el fix manual no había detectado:
325
-
326
- - **F-1 (ALTO)**: listener leak de `process.once('exit')` acumulándose
327
- en loops que crean N spinners secuenciales → MaxListenersExceededWarning.
328
- - **F-2 (MEDIO)**: `preguntarOpcion` llamaba `_pausarSpinnersActivos()`
329
- DESPUÉS del primer `console.log` del menú, dejando una ventana donde
330
- el tick del spinner sobrescribía la primera línea.
331
-
332
- Iter-2 confirmó PASS tras aplicar ambos fixes. Ninguno habría sido
333
- detectado por `/swl:revisar` o `revisor-codigo-swl` solos — ambos
334
- requirieron el reasoning iterativo Feynman+State.
335
-
336
- **Regla operativa**: tras commits de fix-only en módulos con alta densidad
337
- de control de flujo (no en módulos CRUD puros), correr `--remediar`
338
- acotado al módulo. La inversión de 15 turnos típicamente detecta 1-2
339
- bugs adyacentes que el fix original no cubrió.
340
-
341
- ## Ejemplos de invocación
342
-
343
- ```bash
344
- # Modo clásico (retrocompatibilidad v1.5.x): solo audita
345
- /swl:nemesis
346
- /swl:nemesis --modulo backend/app/auth
347
-
348
- # Solo una pasada específica
349
- /swl:nemesis --pass1 --modulo backend/app/auth
350
- /swl:nemesis --pass2
351
-
352
- # Retomar auditoría interrumpida
353
- /swl:nemesis --continue
354
-
355
- # Modo evaluator-optimizer completo (nuevo en v1.5.2)
356
- /swl:nemesis --remediar --modulo backend/app/auth
357
- /swl:nemesis --remediar # scope = directorio actual
358
- /swl:nemesis --remediar --modulo database/schemas # módulo grande → activa redistribución
359
-
360
- # Forzar redistribución aunque scope sea pequeño
361
- /swl:nemesis --redistribuir --modulo backend/app/auth
362
- ```
363
-
364
- ## Inyectar foco adicional durante el loop con `SendMessage`
365
-
366
- Durante una ejecución `--remediar` larga (8-30 turnos en módulos grandes), el
367
- usuario humano puede observar que el evaluator está siguiendo una pista débil
368
- o ignorando una sospecha concreta. **No es necesario abortar el comando** —
369
- usar `SendMessage` para inyectar foco adicional al agente en curso sin perder
370
- el progreso del loop.
371
-
372
- Patrón validado (origen: SIGAF sesión 2026-05-21, mejora D1):
373
-
374
- ```
375
- # El usuario ve en el chat que la iteración 2 está auditando solo
376
- # permisos y olvida revisar el invariante de auditoría.
377
- # SendMessage al agente activo:
378
-
379
- SendMessage({
380
- to: "nemesis-auditor-swl", // o el nombre asignado del agente activo
381
- message: "Antes de cerrar iteración 2: revisa también el invariante de
382
- auditoría inmutable en module/audit/handlers.py. Sospecho que
383
- handle_revoke() escribe a la tabla aprobaciones_historial sin
384
- verificar que el VBO original siga vigente."
385
- });
386
- ```
387
-
388
- El agente recibe el mensaje en su próximo turno y lo trata como instrucción
389
- adicional sin reiniciar el loop. El registro `audit/findings/iter-N/` queda
390
- intacto.
391
-
392
- **Cuándo aplicar**:
393
-
394
- - El loop lleva ≥2 iteraciones y el reporte sugiere que olvida un patrón obvio
395
- para el contexto del módulo.
396
- - Se detecta que el evaluator está dando vueltas sobre el mismo hallazgo de
397
- baja severidad y conviene priorizar otra zona del código.
398
- - El usuario tiene contexto adicional (incidente reciente, decisión de ADR
399
- no documentado en CLAUDE.md) que el agente no puede inferir solo.
400
-
401
- **Cuándo NO aplicar**:
402
-
403
- - La iteración actual está progresando bien — no interrumpir loops que
404
- convergen.
405
- - El cambio que se quiere inyectar es de scope (cambiar `--modulo`): ahí sí
406
- abortar con Ctrl+C, reset con `--reset-plan` y re-invocar.
407
- - Inyectar instrucciones contradictorias con el plan congelado del loop —
408
- viola regla `seguridad-agentes.md § Anti-proxy-goal-drift`.
409
-
410
- ## Regla obligatoria sobre las citas archivo:línea del reporte
411
-
412
- Cuando se actúe sobre un hallazgo `archivo:linea` reportado por el evaluator,
413
- **verificar la cita** con `Read` antes de aplicar el fix. Esto es directiva de
414
- la regla global `verificar-citas-normativas.md` Familia 2 — citas
415
- archivo:línea en reportes de auditoría DEBEN re-verificarse contra el código
416
- actual antes de tomar acción. El loop de remediación NO sustituye esta
417
- verificación — el generator (orquestador-swl + agentes de stack) debe leer el
418
- archivo en su HEAD actual antes de modificar.
419
-
420
- ## Referencias
421
-
422
- - ADR-0021: `nemesis-evaluator-optimizer` — diseño completo del patrón.
423
- - ADR-0018: introducción del agente nemesis-auditor-swl.
424
- - `agentes/nemesis-auditor-swl.md`: agente evaluator.
425
- - `agentes/orquestador-swl.md`: agente generator (delega a depurador, backend-*, frontend-*, etc.).
426
- - `habilidades/nemesis-evaluacion-json/SKILL.md`: schema del JSON estructurado.
427
- - `habilidades/nemesis-redistribuir/SKILL.md`: modo redistribuido para scope grande.
428
- - `reglas/seguridad-agentes.md § Recovery Catalog`: manejo de no-convergencia.
429
- - Cookbook Anthropic, patrón evaluator-optimizer:
430
- https://github.com/anthropics/anthropic-cookbook/blob/main/patterns/agents/evaluator_optimizer.ipynb
431
-
432
- <!-- Adaptado de nemesis-auditor-main bajo MIT License (transmissions11/nemesis-auditor) -->
433
- <!-- Loop evaluator-optimizer agregado en v1.6.0 (ADR-0021), 2026-05-16 -->
1
+ ---
2
+ name: swl:nemesis
3
+ description: >
4
+ Auditoría iterativa Feynman + State Inconsistency con loop evaluator-optimizer
5
+ opcional. Sin flag --remediar: solo audita (comportamiento clásico de
6
+ v1.5.x). Con --remediar: ciclo audit→fix→re-audit hasta convergencia
7
+ (max 3 iteraciones, Recovery Catalog si no converge). Modo redistribuido
8
+ automático para scope > 1500 LOC o > 5 archivos en módulos distintos.
9
+ Persiste hallazgos en .planning/audit/findings/iter-N/.
10
+ allowed-tools: [Read, Grep, Glob, Bash, Write, Agent, Skill]
11
+ argument-hint: "[--remediar] [--pass1 | --pass2 | --continue] [--modulo <ruta>] [--redistribuir] [--reset-plan] [--cross-model]"
12
+ ---
13
+
14
+ # /swl:nemesis — Auditoría iterativa con remediación opt-in
15
+
16
+ Dos auditores en loop interno (Feynman + State Inconsistency) detectan bugs de
17
+ profundidad que el código superficialmente correcto esconde. Con el flag
18
+ `--remediar` el comando entra en modo **evaluator-optimizer** (patrón oficial
19
+ de Anthropic, ADR-0021): el agente nemesis evalúa, el orquestador-swl remedia,
20
+ y el ciclo continúa hasta convergencia o agotar el guardrail de 3 iteraciones.
21
+
22
+ ## Cuándo invocar
23
+
24
+ - El módulo pasó `/swl:revisar` con score ≥ 9.0 pero hay sospechas de bugs
25
+ de lógica profunda que el revisor de código no captura (suposiciones
26
+ incorrectas, invariantes rotos, condiciones de carrera sutiles).
27
+ - Antes de un release de componente crítico: auth, pagos, contratos, permisos.
28
+ - Cuando un bug en producción se atribuye a lógica aparentemente correcta —
29
+ usar Nemesis para encontrar el patrón de fallo subyacente.
30
+ - Para módulos legacy con alta deuda técnica donde los tests no cubren los
31
+ caminos de estado.
32
+ - **Para cerrar el loop audit→fix→re-audit en una sola invocación**: usar
33
+ `/swl:nemesis --remediar`. La autonomía es opt-in.
34
+
35
+ ## Cuándo NO invocar
36
+
37
+ - El módulo tiene menos de 200 LOC y es CRUD simple sin lógica de negocio.
38
+ - Se necesita revisión de estilo, naming o cobertura de tests — usar
39
+ `/swl:revisar` en su lugar.
40
+ - El proyecto no tiene `agentes/nemesis-auditor-swl.md` instalado — verificar
41
+ con `ls agentes/ | grep nemesis` antes de invocar.
42
+ - La tarea urgente es un hotfix en producción — Nemesis con `--remediar` es
43
+ deliberado (8-30 turnos); en incidente activo, usar `/swl:verificar` acotado.
44
+
45
+ ## Modos disponibles
46
+
47
+ | Modo | Flag | Descripción |
48
+ |---|---|---|
49
+ | **Solo auditar** (default) | (sin flag) | Pasada 1 (Feynman) + Pasada 2 (State) + N alternadas hasta convergencia interna, máximo 6 pasadas. Entrega reporte. NO remedia. Retrocompatible con v1.5.x. |
50
+ | **Loop completo** | `--remediar` | Evaluator-optimizer: audita → invoca `orquestador-swl` con hallazgos → re-audita. Max 3 iteraciones. Convergencia cuando status=PASS. Recovery Catalog si no converge. |
51
+ | Solo Feynman | `--pass1` | Una pasada Feynman exhaustiva; no ejecuta State. Ortogonal a `--remediar`. |
52
+ | Solo State | `--pass2` | Una pasada State Inconsistency; puede alimentarse con findings previos. |
53
+ | Retomar | `--continue` | Continúa desde la última iteración registrada en `.planning/audit/findings/`. |
54
+ | Acotar módulo | `--modulo <ruta>` | Limita el scope a un archivo o subdirectorio específico. Se combina con cualquier otro flag. |
55
+ | Forzar redistribución | `--redistribuir` | Activa `Skill("nemesis-redistribuir")` aunque scope sea menor al umbral. |
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`.
80
+
81
+ ## Flujo completo con `--remediar`
82
+
83
+ ```
84
+ # iter usa indexing 1-based para alinear con el agente y los output paths
85
+ # (.planning/audit/findings/iter-1/, iter-2/, iter-3/). Max 3 iteraciones.
86
+ iter = 1
87
+ MAX_ITER = 3
88
+ evaluacion = null
89
+
90
+ # Fase 0 del comando: análisis del scope
91
+ loc_total, modulos = analizar_scope(modulo_arg or "directorio actual")
92
+
93
+ # Decisión de redistribuir:
94
+ # 1. --redistribuir explícito siempre activa redistribución (override del usuario).
95
+ # 2. --modulo respeta el scope acotado por el usuario y NO redistribuye, aunque
96
+ # excede umbrales. El usuario ya delimitó intencionalmente.
97
+ # 3. Sin --modulo: umbrales automáticos (> 1500 LOC ó > 5 módulos distintos).
98
+ redistribuir = flag_redistribuir or (
99
+ not flag_modulo and (loc_total > 1500 or modulos > 5)
100
+ )
101
+
102
+ if redistribuir:
103
+ cargar Skill("nemesis-redistribuir")
104
+ plan = generar_plan_redistribuido(scope)
105
+ persistir plan en .planning/audit/nemesis-plan.json
106
+ sub_scopes = plan.sub_scopes
107
+ else:
108
+ sub_scopes = [scope_unico]
109
+
110
+ # Fase 1+: loop evaluator-optimizer (iter ∈ {1, 2, 3})
111
+ while iter <= MAX_ITER:
112
+ # Evaluator: invocar nemesis-auditor-swl una vez por sub-scope.
113
+ # En modo redistribuido cada sub_scope tiene un `id` (declarado en
114
+ # nemesis-plan.json) que el agente USA para construir la ruta de output
115
+ # `.planning/audit/findings/iter-N/<sub_id>/`. Sin sub_id, los reportes
116
+ # se sobrescribirían entre sub-scopes. En modo monolítico sub_id queda
117
+ # `null` y el agente escribe a `iter-N/` (sin subdirectorio).
118
+ for sub_scope in sub_scopes:
119
+ sub_id = sub_scope.id if redistribuir else null
120
+ invocar(nemesis-auditor-swl, sub_scope, iter=iter, sub_id=sub_id)
121
+ # Produce:
122
+ # redistribuido → .planning/audit/findings/iter-N/<sub_id>/evaluacion.json + .md
123
+ # monolítico → .planning/audit/findings/iter-N/evaluacion.json + .md
124
+
125
+ # Consolidar (si modo redistribuido)
126
+ evaluacion = consolidar_evaluaciones(iter)
127
+ # Produce: .planning/audit/findings/iter-N/evaluacion.json consolidado
128
+ # (en modo monolítico no hay consolidación: el archivo ya está en iter-N/)
129
+
130
+ # Decisión sobre el JSON consolidado
131
+ if evaluacion.veredicto.status == "PASS":
132
+ emitir_reporte_final(evaluacion)
133
+ return { exito: True, iters: iter, evaluacion } # convergencia
134
+
135
+ if not flag_remediar:
136
+ emitir_reporte(evaluacion)
137
+ return { exito: False, iters: iter, evaluacion } # solo audita
138
+
139
+ if evaluacion.veredicto.status == "FAIL":
140
+ return activar_recovery_catalog("escalate", evaluacion.veredicto.razon_si_fail)
141
+
142
+ if not evaluacion.veredicto.puede_remediar_automaticamente:
143
+ return activar_recovery_catalog("escalate", "Hallazgos no auto-remediables")
144
+
145
+ # Generator: invocar orquestador-swl con hallazgos como input
146
+ invocar(
147
+ orquestador-swl,
148
+ hallazgos=evaluacion.hallazgos,
149
+ feedback=evaluacion,
150
+ intentos_previos=hallazgos_de_iters_anteriores(iter),
151
+ iter=iter,
152
+ )
153
+ iter += 1
154
+
155
+ # max-iter agotado sin PASS
156
+ return activar_recovery_catalog_secuencial(evaluacion)
157
+ # orden: reprompt(1ª) → reduce-autonomy(2ª) → escalate(3ª)
158
+ ```
159
+
160
+ Los `return` son explícitos. Sin `--remediar`, el `return` del bloque
161
+ `if not flag_remediar` impide que el flujo alcance la invocación del
162
+ orquestador. La retrocompatibilidad es por construcción.
163
+
164
+ ## Activación de redistribución (Fase 0)
165
+
166
+ | Condición | Acción |
167
+ |---|---|
168
+ | `loc_total > 1500` | Cargar `Skill("nemesis-redistribuir")` |
169
+ | `archivos_modulos_distintos > 5` | Cargar `Skill("nemesis-redistribuir")` |
170
+ | `--redistribuir` explícito | Cargar `Skill("nemesis-redistribuir")` |
171
+ | `--modulo <ruta>` con scope acotado | NO redistribuir (respetar decisión explícita del usuario) |
172
+
173
+ Cuando se activa, el comando registra un nudge en `.planning/nudges.jsonl`:
174
+
175
+ ```json
176
+ {
177
+ "timestamp": "<ISO 8601>",
178
+ "tipo": "nemesis-redistribuido",
179
+ "mutation_category": "scope-adaptation",
180
+ "risk_level": "low",
181
+ "razon": "loc_total=3170 (>1500)",
182
+ "sub_scopes": 3,
183
+ "archivo_plan": ".planning/audit/nemesis-plan.json"
184
+ }
185
+ ```
186
+
187
+ ## Recovery Catalog cuando max-iter sin PASS
188
+
189
+ Tras 3 iteraciones del loop sin alcanzar `status=PASS`, el comando aplica en
190
+ orden estricto el catálogo de `reglas/seguridad-agentes.md § Recovery Catalog`:
191
+
192
+ 1. **reprompt** (excedencia 1): re-invoca al orquestador con feedback reforzado
193
+ (qué hallazgos quedaron sin resolver, constraints adicionales). Una sola vez.
194
+ 2. **reduce-autonomy** (excedencia 2 consecutiva): baja `nivelRiesgo` efectivo,
195
+ pide confirmación al usuario antes de cada acción del generator.
196
+ 3. **escalate** (excedencia 3): pausa la cadena, invoca `notificador-swl`,
197
+ espera decisión humana del usuario.
198
+ 4. **terminate**: solo si el evaluator detecta violación de regla de seguridad
199
+ explícita (no por simple no-convergencia).
200
+
201
+ Cada activación se registra en `.planning/nudges.jsonl` con
202
+ `mutation_category: repair` y `risk_level` proporcional.
203
+
204
+ ## Qué produce
205
+
206
+ Estructura de salida bajo `.planning/audit/findings/`:
207
+
208
+ ```
209
+ .planning/audit/findings/
210
+ ├── nemesis-plan.json # solo si modo redistribuido
211
+ ├── iter-1/
212
+ │ ├── feynman-pass1.md # output crudo Feynman
213
+ │ ├── feynman-pass2.md # si hubo segunda pasada Feynman
214
+ │ ├── state-pass1.md # output crudo State
215
+ │ ├── state-pass2.md # si hubo segunda pasada State
216
+ │ ├── nemesis-verified.md # reporte legible consolidado
217
+ │ ├── evaluacion.json # veredicto estructurado
218
+ │ ├── sub-1/ # solo en modo redistribuido
219
+ │ │ ├── feynman-pass1.md
220
+ │ │ ├── state-pass1.md
221
+ │ │ ├── nemesis-verified.md
222
+ │ │ └── evaluacion.json
223
+ │ ├── sub-2/
224
+ │ └── sub-3/
225
+ ├── iter-2/ # solo si --remediar y no convergió en iter 1
226
+ │ └── (mismo formato)
227
+ └── iter-3/ # último intento si --remediar y no convergió
228
+ └── (mismo formato)
229
+ ```
230
+
231
+ Cada `evaluacion.json` sigue el schema `nemesis-evaluacion-json` v1.0.0.
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:status 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
+
251
+ ## Cómo interpretar el reporte
252
+
253
+ ### Severidades
254
+
255
+ | Nivel | Criterio |
256
+ |---|---|
257
+ | CRÍTICO | Explotable sin precondiciones; pérdida de datos o control total |
258
+ | ALTO | Explotable bajo condiciones razonables; impacto severo |
259
+ | MEDIO | Requiere condiciones específicas; impacto moderado |
260
+ | BAJO | Impacto menor o difícil de explotar; documentar para trazabilidad |
261
+
262
+ ### Discovery path
263
+
264
+ - `Feynman-only`: Feynman lo detectó; State no lo confirmó ni refutó.
265
+ - `State-only`: State Inconsistency lo encontró analizando mutaciones.
266
+ - `Cross-feed Pass N → Pass M`: Feynman marcó un sospechoso en la pasada N;
267
+ State lo confirmó como bug real en la pasada M (o viceversa). Estos
268
+ hallazgos son los más confiables.
269
+
270
+ ### Veredicto JSON
271
+
272
+ Los tres status del JSON estructurado del evaluator (definidos canónicamente
273
+ en `agentes/nemesis-auditor-swl.md § Veredicto status`):
274
+
275
+ - **`status: "PASS"`** — convergencia. 0 críticos + 0 altos. Pueden quedar
276
+ hallazgos MEDIOS/BAJOS/informativos. El loop termina con éxito.
277
+
278
+ - **`status: "NEEDS_IMPROVEMENT"`** — hay críticos o altos pero **todos** tienen
279
+ `accion_sugerida` concreta + `agente_recomendado` válido. El comando con
280
+ `--remediar` invoca al `orquestador-swl` automáticamente. Sin `--remediar`,
281
+ el reporte queda como acción pendiente para el usuario.
282
+
283
+ - **`status: "FAIL"`** — hay al menos un hallazgo que cumple cualquiera de:
284
+ - Veto items según `reglas/gobernanza.md § Veto items`.
285
+ - Cambio arquitectural ambiguo (requiere ADR / decisión del usuario).
286
+ - Decisión de producto (comportamiento esperado no definido).
287
+ - Datos de entrada inválidos en el alcance auditado.
288
+
289
+ El loop se detiene de inmediato y escala a Recovery Catalog. Origen del
290
+ refuerzo: SIGAF sesión 2026-05-21 (alineación L2 — el comando y el agente
291
+ deben tener idéntico criterio de FAIL para evitar loops vacíos).
292
+
293
+ **Regla de consistencia**: si esta sección del comando y la del agente
294
+ diverge en wording, el agente es la fuente de verdad operacional (lo
295
+ implementa). Actualizar el comando para alinear, NO al revés.
296
+
297
+ ## Costo estimado
298
+
299
+ | Modo | Turnos aproximados |
300
+ |---|---|
301
+ | Solo auditar, módulo pequeño (< 500 LOC) | 8-12 |
302
+ | Solo auditar, módulo mediano (500-1500 LOC) | 12-18 |
303
+ | Solo auditar, módulo grande (> 1500 LOC, modo redistribuido) | 18-30 |
304
+ | `--remediar`, módulo pequeño, converge en 1 iter | 12-18 |
305
+ | `--remediar`, módulo mediano, 2-3 iters | 20-40 |
306
+ | `--remediar`, módulo grande con redistribución, 3 iters | 40-70 |
307
+ | Solo `--pass1` o `--pass2` | 4-8 |
308
+
309
+ El costo del modo `--remediar` es 3-5× el del modo solo auditar. Es opt-in
310
+ deliberado del usuario, no default.
311
+
312
+ ### Calibración para módulos pequeños con alta densidad de control de flujo
313
+
314
+ Aunque la tabla estima 12-18 turnos para `--remediar` sobre módulo pequeño
315
+ (< 500 LOC), el valor agregado es desproporcionadamente alto cuando el
316
+ módulo concentra **lógica de control de flujo** (event handlers,
317
+ callbacks, `setTimeout`/`setInterval`, readline, promises, race conditions).
318
+ La densidad de bugs latentes en este tipo de código es alta, y nemesis los
319
+ detecta donde la revisión one-shot no.
320
+
321
+ **Patrón confirmado en swl-ses v1.6.0** (sesión 2026-05-16): `--remediar`
322
+ sobre `scripts/lib/ui.js` (~300 LOC con spinner + readline + prompts)
323
+ convergió en iter-2 con 15 turnos totales. Iter-1 detectó dos hallazgos
324
+ adicionales que el fix manual no había detectado:
325
+
326
+ - **F-1 (ALTO)**: listener leak de `process.once('exit')` acumulándose
327
+ en loops que crean N spinners secuenciales → MaxListenersExceededWarning.
328
+ - **F-2 (MEDIO)**: `preguntarOpcion` llamaba `_pausarSpinnersActivos()`
329
+ DESPUÉS del primer `console.log` del menú, dejando una ventana donde
330
+ el tick del spinner sobrescribía la primera línea.
331
+
332
+ Iter-2 confirmó PASS tras aplicar ambos fixes. Ninguno habría sido
333
+ detectado por `/swl:revisar` o `revisor-codigo-swl` solos — ambos
334
+ requirieron el reasoning iterativo Feynman+State.
335
+
336
+ **Regla operativa**: tras commits de fix-only en módulos con alta densidad
337
+ de control de flujo (no en módulos CRUD puros), correr `--remediar`
338
+ acotado al módulo. La inversión de 15 turnos típicamente detecta 1-2
339
+ bugs adyacentes que el fix original no cubrió.
340
+
341
+ ## Ejemplos de invocación
342
+
343
+ ```bash
344
+ # Modo clásico (retrocompatibilidad v1.5.x): solo audita
345
+ /swl:nemesis
346
+ /swl:nemesis --modulo backend/app/auth
347
+
348
+ # Solo una pasada específica
349
+ /swl:nemesis --pass1 --modulo backend/app/auth
350
+ /swl:nemesis --pass2
351
+
352
+ # Retomar auditoría interrumpida
353
+ /swl:nemesis --continue
354
+
355
+ # Modo evaluator-optimizer completo (nuevo en v1.5.2)
356
+ /swl:nemesis --remediar --modulo backend/app/auth
357
+ /swl:nemesis --remediar # scope = directorio actual
358
+ /swl:nemesis --remediar --modulo database/schemas # módulo grande → activa redistribución
359
+
360
+ # Forzar redistribución aunque scope sea pequeño
361
+ /swl:nemesis --redistribuir --modulo backend/app/auth
362
+ ```
363
+
364
+ ## Inyectar foco adicional durante el loop con `SendMessage`
365
+
366
+ Durante una ejecución `--remediar` larga (8-30 turnos en módulos grandes), el
367
+ usuario humano puede observar que el evaluator está siguiendo una pista débil
368
+ o ignorando una sospecha concreta. **No es necesario abortar el comando** —
369
+ usar `SendMessage` para inyectar foco adicional al agente en curso sin perder
370
+ el progreso del loop.
371
+
372
+ Patrón validado (origen: SIGAF sesión 2026-05-21, mejora D1):
373
+
374
+ ```
375
+ # El usuario ve en el chat que la iteración 2 está auditando solo
376
+ # permisos y olvida revisar el invariante de auditoría.
377
+ # SendMessage al agente activo:
378
+
379
+ SendMessage({
380
+ to: "nemesis-auditor-swl", // o el nombre asignado del agente activo
381
+ message: "Antes de cerrar iteración 2: revisa también el invariante de
382
+ auditoría inmutable en module/audit/handlers.py. Sospecho que
383
+ handle_revoke() escribe a la tabla aprobaciones_historial sin
384
+ verificar que el VBO original siga vigente."
385
+ });
386
+ ```
387
+
388
+ El agente recibe el mensaje en su próximo turno y lo trata como instrucción
389
+ adicional sin reiniciar el loop. El registro `audit/findings/iter-N/` queda
390
+ intacto.
391
+
392
+ **Cuándo aplicar**:
393
+
394
+ - El loop lleva ≥2 iteraciones y el reporte sugiere que olvida un patrón obvio
395
+ para el contexto del módulo.
396
+ - Se detecta que el evaluator está dando vueltas sobre el mismo hallazgo de
397
+ baja severidad y conviene priorizar otra zona del código.
398
+ - El usuario tiene contexto adicional (incidente reciente, decisión de ADR
399
+ no documentado en CLAUDE.md) que el agente no puede inferir solo.
400
+
401
+ **Cuándo NO aplicar**:
402
+
403
+ - La iteración actual está progresando bien — no interrumpir loops que
404
+ convergen.
405
+ - El cambio que se quiere inyectar es de scope (cambiar `--modulo`): ahí sí
406
+ abortar con Ctrl+C, reset con `--reset-plan` y re-invocar.
407
+ - Inyectar instrucciones contradictorias con el plan congelado del loop —
408
+ viola regla `seguridad-agentes.md § Anti-proxy-goal-drift`.
409
+
410
+ ## Regla obligatoria sobre las citas archivo:línea del reporte
411
+
412
+ Cuando se actúe sobre un hallazgo `archivo:linea` reportado por el evaluator,
413
+ **verificar la cita** con `Read` antes de aplicar el fix. Esto es directiva de
414
+ la regla global `verificar-citas-normativas.md` Familia 2 — citas
415
+ archivo:línea en reportes de auditoría DEBEN re-verificarse contra el código
416
+ actual antes de tomar acción. El loop de remediación NO sustituye esta
417
+ verificación — el generator (orquestador-swl + agentes de stack) debe leer el
418
+ archivo en su HEAD actual antes de modificar.
419
+
420
+ ## Referencias
421
+
422
+ - ADR-0021: `nemesis-evaluator-optimizer` — diseño completo del patrón.
423
+ - ADR-0018: introducción del agente nemesis-auditor-swl.
424
+ - `agentes/nemesis-auditor-swl.md`: agente evaluator.
425
+ - `agentes/orquestador-swl.md`: agente generator (delega a depurador, backend-*, frontend-*, etc.).
426
+ - `habilidades/nemesis-evaluacion-json/SKILL.md`: schema del JSON estructurado.
427
+ - `habilidades/nemesis-redistribuir/SKILL.md`: modo redistribuido para scope grande.
428
+ - `reglas/seguridad-agentes.md § Recovery Catalog`: manejo de no-convergencia.
429
+ - Cookbook Anthropic, patrón evaluator-optimizer:
430
+ https://github.com/anthropics/anthropic-cookbook/blob/main/patterns/agents/evaluator_optimizer.ipynb
431
+
432
+ <!-- Adaptado de nemesis-auditor-main bajo MIT License (transmissions11/nemesis-auditor) -->
433
+ <!-- Loop evaluator-optimizer agregado en v1.6.0 (ADR-0021), 2026-05-16 -->