@saulwade/swl-ses 1.6.3 → 1.6.6
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.
- package/CLAUDE.md +3 -3
- package/README.md +2 -2
- package/agentes/gh-fix-ci-swl.md +275 -0
- package/agentes/nemesis-auditor-swl.md +90 -1
- package/comandos/swl/exportar-vault.md +106 -14
- package/comandos/swl/nemesis.md +70 -3
- package/comandos/swl/release.md +62 -2
- package/comandos/swl/salud.md +32 -0
- package/comandos/swl/verificar.md +116 -2
- package/habilidades/agent-browser/SKILL.md +111 -4
- package/habilidades/agent-deep-links/SKILL.md +148 -0
- package/habilidades/backend-async-postgres-testing/SKILL.md +215 -0
- package/habilidades/backend-error-design/SKILL.md +221 -0
- package/habilidades/browser-interaction-patterns/SKILL.md +514 -0
- package/habilidades/browser-research-domains/SKILL.md +635 -0
- package/habilidades/changelog-generator/SKILL.md +172 -0
- package/habilidades/changelog-generator/scripts/parse-commits.js +354 -0
- package/habilidades/devsecops-pipeline-security/SKILL.md +3 -0
- package/habilidades/fastapi-experto/SKILL.md +49 -4
- package/habilidades/harness-claude-code/SKILL.md +4 -1
- package/habilidades/postgresql-experto/SKILL.md +80 -4
- package/habilidades/proceso-discovery-machote/SKILL.md +157 -0
- package/habilidades/proceso-modular-split/SKILL.md +256 -0
- package/habilidades/tdd-workflow/SKILL.md +12 -5
- package/hooks/extraccion-aprendizajes.js +8 -0
- package/hooks/lib/deep-links.js +185 -0
- package/hooks/lib/evolution-tracker.js +148 -20
- package/hooks/lib/gateway-notify.js +70 -7
- package/manifiestos/modulos.json +13 -3
- package/manifiestos/skills-lock.json +1247 -1191
- package/package.json +92 -92
- package/plugin.json +371 -362
- package/reglas/arquitectura.md +38 -0
- package/reglas/arreglar-al-detectar.md +93 -0
- package/reglas/auditorias-documentales-estructurales.md +38 -0
- package/reglas/registro-componentes-nuevos.md +14 -0
- package/reglas/tests-cleanup.md +220 -0
- package/scripts/instalador.js +72 -4
- package/scripts/lib/mcp_config.py +29 -14
- package/scripts/lib/notificaciones-telegram.js +14 -0
- package/scripts/lib/transformadores/codex.js +4 -0
- package/scripts/lib/transformadores/cursor.js +5 -0
- package/scripts/mcp-orchestrator.py +153 -131
- package/scripts/mcp-pool-manager.py +132 -107
- package/scripts/mcp-telemetry.py +139 -120
- package/scripts/verificar-release.js +199 -1
|
@@ -105,6 +105,7 @@ Si tras `ToolSearch` el MCP carga sus tools pero la primera llamada (ej.
|
|
|
105
105
|
el síntoma es claro: apiKey desincronizada.
|
|
106
106
|
|
|
107
107
|
Acción:
|
|
108
|
+
|
|
108
109
|
1. Leer la apiKey actual del plugin con
|
|
109
110
|
`grep '"apiKey"' "F:/Google Drive/Developer/Obsidian/Vault/SWL/.obsidian/plugins/obsidian-local-rest-api/data.json"`
|
|
110
111
|
2. Reportar al usuario que actualice en **claude.ai → Settings → Connectors
|
|
@@ -152,6 +153,7 @@ META - SWL Software Engineering System.md
|
|
|
152
153
|
Algoritmo de match (en cascada — cada pasada solo se ejecuta si la anterior no resolvió match único):
|
|
153
154
|
|
|
154
155
|
**Normaliza ambos lados** a comparación robusta antes de cualquier pasada:
|
|
156
|
+
|
|
155
157
|
- Strip extensión `.md`.
|
|
156
158
|
- Strip prefijo `DEV - ` o `META - ` (cualquier prefijo seguido de ` - `).
|
|
157
159
|
- Lowercase.
|
|
@@ -161,17 +163,21 @@ Algoritmo de match (en cascada — cada pasada solo se ejecuta si la anterior no
|
|
|
161
163
|
Aplica el mismo procesamiento al slug del proyecto local.
|
|
162
164
|
|
|
163
165
|
**Pasada 1 — Match exacto**:
|
|
166
|
+
|
|
164
167
|
- Si la cadena normalizada del slug local coincide carácter a carácter con la de algún canónico, ese es el match. Caso típico: `sigaf` ↔ `DEV - SIGAF`.
|
|
165
168
|
|
|
166
169
|
**Pasada 2 — Match por prefijo bidireccional**:
|
|
170
|
+
|
|
167
171
|
- Si la cadena del slug local es **prefijo** de la cadena de algún canónico, ese canónico matchea. Ej: `ecosistemamultiagenteia` es prefijo de `ecosistemamultiagenteiaoicine` → match con `DEV - Ecosistema Multi-Agente IA OIC-INE`.
|
|
168
172
|
- Inversamente: si la cadena de algún canónico es prefijo de la del slug local, también matchea (cubre el caso opuesto: vault con nombre más corto que el slug del proyecto).
|
|
169
173
|
- Solo se acepta el match si la pasada produce **exactamente 1** candidato. Si hay 2+ ambiguos, NO usar — pasar a siguiente pasada con el alias o fallback final, listando los candidatos en el WARNING del Paso 5.
|
|
170
174
|
|
|
171
175
|
**Pasada 3 — Aliases conocidos**:
|
|
176
|
+
|
|
172
177
|
- Si ninguna pasada anterior resolvió, intenta con sinónimos del slug local antes del fallback (ver lista de aliases más abajo). Para cada alias, repite Pasada 1 y Pasada 2.
|
|
173
178
|
|
|
174
179
|
**Pasada 4 — Fallback**:
|
|
180
|
+
|
|
175
181
|
- Si todo lo anterior es vacío:
|
|
176
182
|
- Usar como `related_vault_project` el valor `[[DEV - {Nombre-Title-Case}]]` (fallback antiguo).
|
|
177
183
|
- **Reportar warning explícito al usuario** en el paso 5 indicando que no se encontró nodo canónico y sugerir crear `02-Projects/DEV - {Nombre}.md` en el vault.
|
|
@@ -180,13 +186,13 @@ Resultado del algoritmo: el nombre canónico es el basename del archivo sin `.md
|
|
|
180
186
|
|
|
181
187
|
Ejemplos de match esperado (con la pasada que lo resuelve):
|
|
182
188
|
|
|
183
|
-
| Slug local
|
|
184
|
-
|
|
185
|
-
| `sigaf`
|
|
186
|
-
| `sigm`
|
|
187
|
-
| `swl-software-engineering-system` | `swlsoftwareengineeringsystem` | `swlsoftwareengineeringsystem`
|
|
188
|
-
| `ecosistema-multi-agente-ia`
|
|
189
|
-
| `swl-ses`
|
|
189
|
+
| Slug local | Normalizado local | Canónico que matchea | Pasada | Nombre canónico resuelto |
|
|
190
|
+
| --------------------------------- | ------------------------------ | ------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------ |
|
|
191
|
+
| `sigaf` | `sigaf` | `sigaf` | 1 (exacto) | `DEV - SIGAF` |
|
|
192
|
+
| `sigm` | `sigm` | `sigm` | 1 (exacto) | `DEV - SIGM` |
|
|
193
|
+
| `swl-software-engineering-system` | `swlsoftwareengineeringsystem` | `swlsoftwareengineeringsystem` | 1 (exacto) | `META - SWL Software Engineering System` |
|
|
194
|
+
| `ecosistema-multi-agente-ia` | `ecosistemamultiagenteia` | `ecosistemamultiagenteiaoicine` | 2 (prefijo del slug en canónico) | `DEV - Ecosistema Multi-Agente IA OIC-INE` |
|
|
195
|
+
| `swl-ses` | `swlses` | ninguno (ver nota) | 3 (alias → reemplaza slug por `swlsoftwareengineeringsystem` y repite 1) | `META - SWL Software Engineering System` |
|
|
190
196
|
|
|
191
197
|
**Nota sobre el caso `swl-ses`** — un lector cuidadoso puede preguntarse por qué Pasada 2 (prefijo) no captura este caso, dado que `swlses` y `swlsoftwareengineeringsystem` comparten el inicio `swls`. La verificación carácter a carácter:
|
|
192
198
|
|
|
@@ -263,11 +269,11 @@ reviewed: false
|
|
|
263
269
|
|
|
264
270
|
## Métricas que cambiaron
|
|
265
271
|
|
|
266
|
-
| Métrica
|
|
267
|
-
|
|
268
|
-
| LOC
|
|
269
|
-
| Endpoints |
|
|
270
|
-
| Tests
|
|
272
|
+
| Métrica | Antes | Después |
|
|
273
|
+
| --------- | ----- | ------- |
|
|
274
|
+
| LOC | | |
|
|
275
|
+
| Endpoints | | |
|
|
276
|
+
| Tests | | |
|
|
271
277
|
|
|
272
278
|
## Bloqueantes o deuda detectada
|
|
273
279
|
|
|
@@ -280,11 +286,13 @@ Ejecutar `/sync-projects {proyecto-slug}` en el vault para integrar los cambios
|
|
|
280
286
|
---
|
|
281
287
|
|
|
282
288
|
**Archivos fuente consultados:**
|
|
289
|
+
|
|
283
290
|
- `.planning/COMPACTACION.md` (última)
|
|
284
291
|
- `.planning/APRENDIZAJES.md` (últimas entradas)
|
|
285
292
|
- Git log del día
|
|
286
293
|
|
|
287
294
|
**Notas:**
|
|
295
|
+
|
|
288
296
|
- Este archivo vive en 00-Inbox/ del vault. Saul lo procesa manualmente o con `/sync-projects`.
|
|
289
297
|
- No sobreescribe nada en `02-Projects/`, `04-Resources/` ni `07-Decisions/` del vault.
|
|
290
298
|
```
|
|
@@ -313,6 +321,7 @@ mcp__obsidian__obsidian_append_content({
|
|
|
313
321
|
```
|
|
314
322
|
|
|
315
323
|
Ventajas frente al filesystem:
|
|
324
|
+
|
|
316
325
|
- **No pasa por `proteccion-rutas.js`** — el MCP opera vía HTTPS al puerto
|
|
317
326
|
27124, fuera del flujo de Bash/Write/Edit.
|
|
318
327
|
- **Sin staging intermedio**: escribe directamente al archivo final del vault.
|
|
@@ -321,6 +330,7 @@ Ventajas frente al filesystem:
|
|
|
321
330
|
manejar separators de path.
|
|
322
331
|
|
|
323
332
|
Notas operativas:
|
|
333
|
+
|
|
324
334
|
- Si el archivo ya existe con ese timestamp (raro), agregar sufijo `_b`
|
|
325
335
|
al nombre antes de invocar `append_content`. El MCP de obsidian no
|
|
326
336
|
sobreescribe si el archivo existe — `append` agrega al final.
|
|
@@ -354,6 +364,7 @@ escribe a `_userland/staging/<timestamp>.md` dentro del CWD, luego mueve con
|
|
|
354
364
|
`Bash` (`mv` o PowerShell `Move-Item`).
|
|
355
365
|
|
|
356
366
|
Reportar al usuario qué canal se usó:
|
|
367
|
+
|
|
357
368
|
- Canal A → `[OK] Vía: MCP Obsidian (puerto 27124)`
|
|
358
369
|
- Canal B → `[OK] Vía: filesystem directo (MCP no disponible)`
|
|
359
370
|
- Canal Híbrido → `[OK] Vía: filesystem para Inbox, MCP para promociones`
|
|
@@ -391,11 +402,78 @@ Reportar al usuario el desglose final del modo híbrido:
|
|
|
391
402
|
[OK] Revisión aprobada (reviewed: true) en el Inbox
|
|
392
403
|
```
|
|
393
404
|
|
|
405
|
+
## Paso 4b — Verificación post-escritura (obligatorio)
|
|
406
|
+
|
|
407
|
+
**Inmediatamente después** de cada escritura del Paso 4 (Inbox, promociones en
|
|
408
|
+
`02-Projects/`, `07-Decisions/`, `04-Resources/`, `10-Archive/`), confirma que el
|
|
409
|
+
archivo en disco **existe y tiene contenido sustantivo**. Sin este paso, Obsidian
|
|
410
|
+
puede mostrar nodos fantasma (pestaña con título pero cuerpo vacío) cuando el MCP
|
|
411
|
+
falló con `40101`, timeout o `append_content` sobre ruta incorrecta.
|
|
412
|
+
|
|
413
|
+
### Cuándo verificar
|
|
414
|
+
|
|
415
|
+
| Escritura | Verificar |
|
|
416
|
+
| ------------------------------------------------------------- | ------------------------------------------------------------- |
|
|
417
|
+
| Export en `00-Inbox/` | **Siempre** |
|
|
418
|
+
| Append a `02-Projects/DEV - *.md` | **Siempre** (leer tramo final o archivo completo si es corto) |
|
|
419
|
+
| Nota nueva en `07-Decisions/`, `04-Resources/`, `10-Archive/` | **Siempre** |
|
|
420
|
+
| Solo `reviewed: true` en Inbox existente | Opcional (el archivo ya existía) |
|
|
421
|
+
|
|
422
|
+
### Cómo verificar (orden de preferencia)
|
|
423
|
+
|
|
424
|
+
1. **MCP** — `obsidian_get_file_contents` con path **relativo al vault SWL**
|
|
425
|
+
(sin prefijo `F:\...`):
|
|
426
|
+
```json
|
|
427
|
+
{ "filepath": "00-Inbox/2026-05-18_1530_export-swl-ses.md" }
|
|
428
|
+
```
|
|
429
|
+
2. **Filesystem** — si el Paso 4 usó canal B, leer el mismo path absoluto con
|
|
430
|
+
`Read` o `Get-Content` y comparar longitud.
|
|
431
|
+
|
|
432
|
+
### Criterios de aprobación (todos deben cumplirse)
|
|
433
|
+
|
|
434
|
+
| # | Criterio | Umbral |
|
|
435
|
+
| --- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
436
|
+
| 1 | El archivo existe | Sin error 404 / `ENOENT` |
|
|
437
|
+
| 2 | Longitud del cuerpo | ≥ **500 caracteres** (sin contar solo frontmatter vacío) |
|
|
438
|
+
| 3 | Marcador de export | Contiene `type: export-swl` en frontmatter **o** al menos una sección `## Logros de la sesión` / `## Sesión` / `## Decisiones` con texto bajo el heading |
|
|
439
|
+
| 4 | No es fantasma | El cuerpo **no** es solo el título del archivo, una línea en blanco, o el nombre del nodo sin párrafos |
|
|
440
|
+
|
|
441
|
+
Si el export es deliberadamente corto (<500 caracteres), bajar el umbral a
|
|
442
|
+
≥ **200 caracteres** solo si el frontmatter incluye `type: export-swl` y al
|
|
443
|
+
menos un bullet bajo `## Logros` o `## Sesión`; en caso contrario, tratar como
|
|
444
|
+
fallo.
|
|
445
|
+
|
|
446
|
+
### Si la verificación falla
|
|
447
|
+
|
|
448
|
+
1. **No** reportar `[OK] Export creado` al usuario.
|
|
449
|
+
2. Registrar en la salida: `[FAIL] Verificación post-escritura: <motivo>`.
|
|
450
|
+
3. **Un reintento** con el canal alternativo (MCP ↔ filesystem del Paso 4).
|
|
451
|
+
4. Si sigue fallando: reconstruir el Markdown desde `.planning/COMPACTACION.md`
|
|
452
|
+
- artefactos de sesión y escribir de nuevo; si aún falla, abortar y pedir
|
|
453
|
+
al usuario revisar Obsidian (vault activo Paso 0c, apiKey Paso 0d).
|
|
454
|
+
5. Si Obsidian ya abrió una pestaña fantasma: cerrar la pestaña en el IDE de
|
|
455
|
+
Obsidian; **no** dejar el tab apuntando a un path que no pasó verificación.
|
|
456
|
+
|
|
457
|
+
### Salida interna (para el Paso 5)
|
|
458
|
+
|
|
459
|
+
Guardar mentalmente (o en el reporte):
|
|
460
|
+
|
|
461
|
+
```
|
|
462
|
+
[OK] Verificación: 00-Inbox/2026-05-18_1530_export-swl-ses.md — 2847 chars, secciones OK
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
o
|
|
466
|
+
|
|
467
|
+
```
|
|
468
|
+
[FAIL] Verificación: cuerpo 42 chars — reintento vía filesystem
|
|
469
|
+
```
|
|
470
|
+
|
|
394
471
|
## Paso 5 — Confirmación
|
|
395
472
|
|
|
396
|
-
Reporta al usuario:
|
|
473
|
+
Reporta al usuario **solo si el Paso 4b aprobó** el Inbox (y cada promoción, si aplica):
|
|
397
474
|
|
|
398
475
|
- Ruta exacta del archivo creado.
|
|
476
|
+
- Resultado del Paso 4b (caracteres verificados o `[FAIL]` si abortaste).
|
|
399
477
|
- Conteo de palabras.
|
|
400
478
|
- **Nombre canónico resuelto**: indicar qué nodo de `02-Projects/` enlazó el export. Si no hubo match, marcar el warning explícito.
|
|
401
479
|
- Recordatorio: "Al abrir el vault en tu próxima sesión, ejecuta `/sync-projects {proyecto-slug}` para integrar formalmente estos cambios."
|
|
@@ -404,6 +482,7 @@ Formato esperado cuando hay match:
|
|
|
404
482
|
|
|
405
483
|
```
|
|
406
484
|
[OK] Export creado: F:\...\2026-05-04_1748_export-swl-ses.md (487 palabras)
|
|
485
|
+
[OK] Verificación post-escritura: 3124 chars, type: export-swl, secciones OK
|
|
407
486
|
[OK] Enlace canónico: [[META - SWL Software Engineering System]]
|
|
408
487
|
|
|
409
488
|
Próximo paso: al abrir el vault, ejecuta:
|
|
@@ -440,6 +519,9 @@ Próximo paso: al abrir el vault, ejecuta:
|
|
|
440
519
|
- **Recurrir al workaround del filesystem antes de cargar el schema del
|
|
441
520
|
MCP con `ToolSearch`**. Tools deferred ≠ tools ausentes — el MCP server
|
|
442
521
|
está corriendo, solo falta cargar el schema. Cargar antes de defaultear.
|
|
522
|
+
- **Declarar éxito sin Paso 4b**. Un `append_content` o `Write` que no lanza
|
|
523
|
+
error no garantiza contenido en disco ni en el índice de Obsidian — genera
|
|
524
|
+
nodos fantasma en el grafo. Siempre leer de vuelta antes del `[OK]`.
|
|
443
525
|
|
|
444
526
|
## Relación con otros comandos SWL
|
|
445
527
|
|
|
@@ -458,6 +540,7 @@ Produce:
|
|
|
458
540
|
|
|
459
541
|
```
|
|
460
542
|
[OK] Export creado: F:\Google Drive\Developer\Obsidian\Vault\SWL\00-Inbox\2026-04-16_2130_export-sigaf.md (487 palabras)
|
|
543
|
+
[OK] Verificación post-escritura: 2980 chars, secciones OK
|
|
461
544
|
[OK] Vía: MCP Obsidian (puerto 27124)
|
|
462
545
|
[OK] Enlace canónico: [[DEV - SIGAF]]
|
|
463
546
|
|
|
@@ -467,6 +550,15 @@ Próximo paso: al abrir el vault, ejecuta:
|
|
|
467
550
|
|
|
468
551
|
## Historial de cambios del comando
|
|
469
552
|
|
|
553
|
+
- **v1.4.1** (2026-05-18) — **Paso 4b — Verificación post-escritura**
|
|
554
|
+
obligatoria tras cada escritura MCP o filesystem. Origen: exports MCP fallidos
|
|
555
|
+
(40101 / vault activo incorrecto) dejaron pestañas y nodos en el grafo sin
|
|
556
|
+
archivo en disco o con cuerpo vacío; reconstrucción manual desde
|
|
557
|
+
`COMPACTACION.md`. Criterios: existencia, ≥500 chars (o ≥200 con frontmatter
|
|
558
|
+
completo), secciones de export, anti-fantasma; un reintento con canal alternativo;
|
|
559
|
+
no reportar `[OK]` sin verificación. Anti-patrón y ejemplos del Paso 5
|
|
560
|
+
actualizados.
|
|
561
|
+
|
|
470
562
|
- **v1.4.0** (2026-05-13) — Agregados Pasos 0c y 0d con verificación previa
|
|
471
563
|
del vault activo de Obsidian y de la apiKey del MCP. Origen: sesión
|
|
472
564
|
2026-05-13 con autorización ampliada del usuario para promover docs;
|
|
@@ -488,4 +580,4 @@ Próximo paso: al abrir el vault, ejecuta:
|
|
|
488
580
|
el orden de preferencia (MCP primero, filesystem como fallback explícito)
|
|
489
581
|
y agrega la nota de "tools deferred ≠ tools ausentes" en anti-patrones.
|
|
490
582
|
Aplicación de la regla `consultar-vault-primero.md § Workflow forzoso
|
|
491
|
-
|
|
583
|
+
para escritura al vault`.
|
package/comandos/swl/nemesis.md
CHANGED
|
@@ -228,9 +228,30 @@ Cada `evaluacion.json` sigue el schema `nemesis-evaluacion-json` v1.0.0.
|
|
|
228
228
|
|
|
229
229
|
### Veredicto JSON
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
Los tres status del JSON estructurado del evaluator (definidos canónicamente
|
|
232
|
+
en `agentes/nemesis-auditor-swl.md § Veredicto status`):
|
|
233
|
+
|
|
234
|
+
- **`status: "PASS"`** — convergencia. 0 críticos + 0 altos. Pueden quedar
|
|
235
|
+
hallazgos MEDIOS/BAJOS/informativos. El loop termina con éxito.
|
|
236
|
+
|
|
237
|
+
- **`status: "NEEDS_IMPROVEMENT"`** — hay críticos o altos pero **todos** tienen
|
|
238
|
+
`accion_sugerida` concreta + `agente_recomendado` válido. El comando con
|
|
239
|
+
`--remediar` invoca al `orquestador-swl` automáticamente. Sin `--remediar`,
|
|
240
|
+
el reporte queda como acción pendiente para el usuario.
|
|
241
|
+
|
|
242
|
+
- **`status: "FAIL"`** — hay al menos un hallazgo que cumple cualquiera de:
|
|
243
|
+
- Veto items según `reglas/gobernanza.md § Veto items`.
|
|
244
|
+
- Cambio arquitectural ambiguo (requiere ADR / decisión del usuario).
|
|
245
|
+
- Decisión de producto (comportamiento esperado no definido).
|
|
246
|
+
- Datos de entrada inválidos en el alcance auditado.
|
|
247
|
+
|
|
248
|
+
El loop se detiene de inmediato y escala a Recovery Catalog. Origen del
|
|
249
|
+
refuerzo: SIGAF sesión 2026-05-21 (alineación L2 — el comando y el agente
|
|
250
|
+
deben tener idéntico criterio de FAIL para evitar loops vacíos).
|
|
251
|
+
|
|
252
|
+
**Regla de consistencia**: si esta sección del comando y la del agente
|
|
253
|
+
diverge en wording, el agente es la fuente de verdad operacional (lo
|
|
254
|
+
implementa). Actualizar el comando para alinear, NO al revés.
|
|
234
255
|
|
|
235
256
|
## Costo estimado
|
|
236
257
|
|
|
@@ -299,6 +320,52 @@ bugs adyacentes que el fix original no cubrió.
|
|
|
299
320
|
/swl:nemesis --redistribuir --modulo backend/app/auth
|
|
300
321
|
```
|
|
301
322
|
|
|
323
|
+
## Inyectar foco adicional durante el loop con `SendMessage`
|
|
324
|
+
|
|
325
|
+
Durante una ejecución `--remediar` larga (8-30 turnos en módulos grandes), el
|
|
326
|
+
usuario humano puede observar que el evaluator está siguiendo una pista débil
|
|
327
|
+
o ignorando una sospecha concreta. **No es necesario abortar el comando** —
|
|
328
|
+
usar `SendMessage` para inyectar foco adicional al agente en curso sin perder
|
|
329
|
+
el progreso del loop.
|
|
330
|
+
|
|
331
|
+
Patrón validado (origen: SIGAF sesión 2026-05-21, mejora D1):
|
|
332
|
+
|
|
333
|
+
```
|
|
334
|
+
# El usuario ve en el chat que la iteración 2 está auditando solo
|
|
335
|
+
# permisos y olvida revisar el invariante de auditoría.
|
|
336
|
+
# SendMessage al agente activo:
|
|
337
|
+
|
|
338
|
+
SendMessage({
|
|
339
|
+
to: "nemesis-auditor-swl", // o el nombre asignado del agente activo
|
|
340
|
+
message: "Antes de cerrar iteración 2: revisa también el invariante de
|
|
341
|
+
auditoría inmutable en module/audit/handlers.py. Sospecho que
|
|
342
|
+
handle_revoke() escribe a la tabla aprobaciones_historial sin
|
|
343
|
+
verificar que el VBO original siga vigente."
|
|
344
|
+
});
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
El agente recibe el mensaje en su próximo turno y lo trata como instrucción
|
|
348
|
+
adicional sin reiniciar el loop. El registro `audit/findings/iter-N/` queda
|
|
349
|
+
intacto.
|
|
350
|
+
|
|
351
|
+
**Cuándo aplicar**:
|
|
352
|
+
|
|
353
|
+
- El loop lleva ≥2 iteraciones y el reporte sugiere que olvida un patrón obvio
|
|
354
|
+
para el contexto del módulo.
|
|
355
|
+
- Se detecta que el evaluator está dando vueltas sobre el mismo hallazgo de
|
|
356
|
+
baja severidad y conviene priorizar otra zona del código.
|
|
357
|
+
- El usuario tiene contexto adicional (incidente reciente, decisión de ADR
|
|
358
|
+
no documentado en CLAUDE.md) que el agente no puede inferir solo.
|
|
359
|
+
|
|
360
|
+
**Cuándo NO aplicar**:
|
|
361
|
+
|
|
362
|
+
- La iteración actual está progresando bien — no interrumpir loops que
|
|
363
|
+
convergen.
|
|
364
|
+
- El cambio que se quiere inyectar es de scope (cambiar `--modulo`): ahí sí
|
|
365
|
+
abortar con Ctrl+C, reset con `--reset-plan` y re-invocar.
|
|
366
|
+
- Inyectar instrucciones contradictorias con el plan congelado del loop —
|
|
367
|
+
viola regla `seguridad-agentes.md § Anti-proxy-goal-drift`.
|
|
368
|
+
|
|
302
369
|
## Regla obligatoria sobre las citas archivo:línea del reporte
|
|
303
370
|
|
|
304
371
|
Cuando se actúe sobre un hallazgo `archivo:linea` reportado por el evaluator,
|
package/comandos/swl/release.md
CHANGED
|
@@ -174,9 +174,69 @@ y debe versionarse.
|
|
|
174
174
|
|
|
175
175
|
## Paso 7 — Generar CHANGELOG
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
Desde v1.6.5 este paso usa el skill `changelog-generator` para parsear
|
|
178
|
+
Conventional Commits y producir el bloque listo para insertar (ADR-0029).
|
|
178
179
|
|
|
179
|
-
|
|
180
|
+
### Paso 7.1 — Cargar skill y previsualizar
|
|
181
|
+
|
|
182
|
+
```
|
|
183
|
+
Skill("changelog-generator")
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Ejecutar el parser determinista contra los commits del rango actual:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
node habilidades/changelog-generator/scripts/parse-commits.js \
|
|
190
|
+
--from <tag-anterior> --to HEAD --version <nueva-version> --format markdown
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
El script imprime el bloque markdown listo para insertar Y reporta a stderr
|
|
194
|
+
el ratio de conformidad Conventional Commits. Categorías generadas en orden
|
|
195
|
+
canónico: Breaking changes → Nuevas funcionalidades → Correcciones →
|
|
196
|
+
Mejoras de rendimiento → Cambios internos → Reversiones → Evoluciones de
|
|
197
|
+
skills/agentes → Mantenimiento → Otros.
|
|
198
|
+
|
|
199
|
+
### Paso 7.2 — Gate de conformidad
|
|
200
|
+
|
|
201
|
+
Verificar la conformidad (impresa a stderr o vía `--format json`):
|
|
202
|
+
|
|
203
|
+
- **>= 80% conformidad**: continuar a 7.3.
|
|
204
|
+
- **< 80% conformidad**: detenerse y reportar al usuario los commits caídos
|
|
205
|
+
bajo "Otros". Pedir decisión:
|
|
206
|
+
1. Continuar con el bloque generado (los "Otros" quedan al final del CHANGELOG).
|
|
207
|
+
2. Abortar release y reescribir commits no conformes (`git rebase -i`).
|
|
208
|
+
3. Editar manualmente la sección "Otros" antes de insertar.
|
|
209
|
+
|
|
210
|
+
NO continuar automáticamente con conformidad baja — el changelog público
|
|
211
|
+
queda confuso.
|
|
212
|
+
|
|
213
|
+
### Paso 7.3 — Insertar en CHANGELOG.md
|
|
214
|
+
|
|
215
|
+
Leer `CHANGELOG.md` actual:
|
|
216
|
+
- Si no existe: crear con header `# Changelog\n\n` y luego el bloque nuevo.
|
|
217
|
+
- Si existe: insertar el bloque nuevo inmediatamente después del header
|
|
218
|
+
`# Changelog` (antes de la entrada anterior).
|
|
219
|
+
|
|
220
|
+
Escritura atómica obligatoria (regla CLAUDE.md). Usar `atomicWriteSync` desde
|
|
221
|
+
`hooks/lib/atomic-write.js` cuando se llame programáticamente.
|
|
222
|
+
|
|
223
|
+
### Paso 7.4 — Verificar entrada generada
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
head -40 CHANGELOG.md
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Confirmar:
|
|
230
|
+
- Header `## [<nueva-version>] - YYYY-MM-DD` presente.
|
|
231
|
+
- Categorías generadas tienen contenido coherente con los commits del rango.
|
|
232
|
+
- Breaking changes (si los hay) aparecen al inicio.
|
|
233
|
+
|
|
234
|
+
### Fallback manual (legacy v1.6.4 y anterior)
|
|
235
|
+
|
|
236
|
+
Si el parser falla o el skill no está disponible, mantener el flujo manual
|
|
237
|
+
de versiones previas:
|
|
238
|
+
- Secciones: Funcionalidades nuevas, Correcciones, Mejoras de rendimiento,
|
|
239
|
+
Cambios internos, Breaking Changes, Estadísticas.
|
|
180
240
|
- Descripciones legibles por humanos (sin prefijo feat:/fix:).
|
|
181
241
|
- Omitir commits style: y test: del changelog público.
|
|
182
242
|
|
package/comandos/swl/salud.md
CHANGED
|
@@ -347,6 +347,38 @@ Documentación completa en `@docs/variables-entorno.md`.
|
|
|
347
347
|
Este paso siempre se ejecuta (no es opt-in) — la calidad de CLAUDE.md
|
|
348
348
|
es métrica continua del sistema.
|
|
349
349
|
|
|
350
|
+
## Paso 5g — Smoke test de servidores MCP (opt-in)
|
|
351
|
+
|
|
352
|
+
Si el proyecto declara servidores MCP en `.claude/settings.json` o en
|
|
353
|
+
`~/.cursor/mcp.json` o `~/.claude/settings.json` (global), ejecutar un smoke
|
|
354
|
+
test rápido para detectar configuraciones rotas antes de que fallen en uso
|
|
355
|
+
interactivo:
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
python scripts/mcp-orchestrator.py status --json 2>/dev/null
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
El orchestrator levanta un proceso MCP fresh por cada server configurado y
|
|
362
|
+
reporta:
|
|
363
|
+
|
|
364
|
+
- `status: "OK"` — handshake completo + lista de tools devuelta correctamente
|
|
365
|
+
- `status: "ERROR"` — fallo de handshake, autenticación o spawn
|
|
366
|
+
|
|
367
|
+
Casos detectables que `/swl:salud` debe reportar:
|
|
368
|
+
|
|
369
|
+
| Síntoma | Causa probable | Acción sugerida |
|
|
370
|
+
|---|---|---|
|
|
371
|
+
| `40101 Authorization required` | apiKey desincronizada entre cliente y plugin | Verificar `HKCU\Environment` (Windows) o variable de entorno del shell coincide con apiKey del plugin |
|
|
372
|
+
| `Server failed to start` | Binario no encontrado en `command` | Verificar path absoluto del binario |
|
|
373
|
+
| `Connection refused` | Plugin/servicio destino no corriendo | Iniciar plugin (ej. Obsidian con Local REST API activo) |
|
|
374
|
+
| `env=None passed` | Config tiene `"env": {}` literal — rompe herencia | Omitir clave `env` por completo en JSON (no dejar vacía) |
|
|
375
|
+
|
|
376
|
+
Si no hay servers configurados, este paso se omite silenciosamente.
|
|
377
|
+
|
|
378
|
+
Este smoke test detecta drift de apiKeys ANTES de que el usuario interactivo
|
|
379
|
+
encuentre 40101 en una invocación crítica. Recomendado ejecutar como parte del
|
|
380
|
+
flujo `/swl:salud` periódico mensual.
|
|
381
|
+
|
|
350
382
|
## Paso 5e — Verificación de drift de skills (skills-lock)
|
|
351
383
|
|
|
352
384
|
Si existe `manifiestos/skills-lock.json`, comparar el hash actual de cada
|
|
@@ -21,6 +21,7 @@ Eres el coordinador de verificación SWL. Tu trabajo es asegurar la calidad del
|
|
|
21
21
|
| `--until-converge` | Itera el ciclo verificar → corregir → re-verificar hasta convergencia (0 hallazgos CRÍTICO + ALTO + MAYOR en una pasada nueva) o hasta alcanzar `--max-iter`. Compatible con `--ultra` y `--solo-codigo`/`--solo-seguridad`. Ver sección "Modo `--until-converge`". |
|
|
22
22
|
| `--max-iter=N` | Límite de iteraciones para `--until-converge`. Default: `5`. Rango válido: 1-10. |
|
|
23
23
|
| `--no-prompt` | Suprime la confirmación interactiva entre pasadas (para CI). Solo aplica con `--until-converge`. |
|
|
24
|
+
| `--ci-aware` | Antes de declarar convergencia natural en `--until-converge`, espera el estado terminal del CI sobre el HEAD pushed. Convergencia confirmada solo si CI verde + revisores APROBADO. CI rojo reabre el loop con los hallazgos del workflow como pasada N+1. Útil cuando el alcance modifica migraciones, seeds o tests E2E que el CI valida pero los revisores locales no. Ver sección 4.6.7. |
|
|
24
25
|
|
|
25
26
|
### Cuándo usar `--ultra`
|
|
26
27
|
|
|
@@ -286,9 +287,18 @@ El loop se detiene cuando se cumple **cualquiera** de estas señales (la primera
|
|
|
286
287
|
| **A — éxito** | La pasada N produce 0 hallazgos nuevos de severidad `CRÍTICO`, `ALTO` o `MAYOR` | Convergencia natural — la fase está limpia |
|
|
287
288
|
| **B — adversarial** | La pasada N+1 introduce ≥5 hallazgos NUEVOS sobre el código corregido en la pasada N | Las correcciones están introduciendo regresión; escalar al usuario |
|
|
288
289
|
| **C — máximo** | Se alcanza `--max-iter=N` (default 5) sin converger | No-convergente; reportar al usuario |
|
|
290
|
+
| **D — CI verde** (solo con `--ci-aware`) | Tras Señal A, el CI sobre el HEAD pushed termina en estado `success` para todos los workflows aplicables al SHA | Convergencia confirmada cross-stack (revisores + tests locales + CI con migraciones/seeds/E2E) |
|
|
289
291
|
|
|
290
292
|
Los hallazgos `MEDIO`, `BAJO` y `SUGERENCIA` no rompen convergencia — se acumulan como deuda técnica documentada.
|
|
291
293
|
|
|
294
|
+
**Importante sobre la Señal D**: sin `--ci-aware`, la convergencia natural se evalúa SOLO contra revisores + suite local. Esto NO detecta bugs que solo emergen en CI:
|
|
295
|
+
- Migraciones aplicadas a BD limpia (CI fresh) vs BD productiva (donde seeds ya corrieron).
|
|
296
|
+
- Seeds dependientes que fallan en cadena por orden migración↔seed invertido.
|
|
297
|
+
- Tests E2E que requieren datos demo.
|
|
298
|
+
- Partial unique indexes con `WHERE` que no son predicado puro (rompen en CI fresh).
|
|
299
|
+
|
|
300
|
+
Origen del flag: SIGAF 2026-05-15 declaró convergencia natural en Pasada 3 (commit `4d2fb23`) basado en revisores APROBADO + 2161 pytest passed. 3 commits posteriores el CI Playwright reveló 3 tests E2E fallando por bug introducido en la propia Pasada 2 (migración 0061 con índice `WHERE` que rompía seeds en BD limpia). El loop cerró sin validar la integración E2E.
|
|
301
|
+
|
|
292
302
|
### 4.6.2 — Control de pausa entre iteraciones
|
|
293
303
|
|
|
294
304
|
Antes de invocar al implementador para aplicar correcciones de la pasada N, el comando muestra un resumen y permite al usuario decidir:
|
|
@@ -381,9 +391,63 @@ El VERIFICACION.md reportado al usuario al final del loop incluye una sección a
|
|
|
381
391
|
- Estado persistido: `.planning/fases/0N-converge-run-[timestamp].json`
|
|
382
392
|
```
|
|
383
393
|
|
|
384
|
-
### 4.6.7 —
|
|
394
|
+
### 4.6.7 — Protocolo `--ci-aware` (Señal D)
|
|
395
|
+
|
|
396
|
+
Cuando `--ci-aware` está activo, el bucle de convergencia se extiende con un gate adicional ANTES de declarar Señal A como cierre definitivo:
|
|
397
|
+
|
|
398
|
+
**Precondición**: el último commit de la pasada N debe estar pusheado a la rama remota. Si no:
|
|
399
|
+
|
|
400
|
+
```
|
|
401
|
+
Pasada N converge natural pero --ci-aware requiere CI sobre HEAD pushed.
|
|
402
|
+
|
|
403
|
+
HEAD local: abc1234 (no pusheado)
|
|
404
|
+
[p] push automático + monitor CI
|
|
405
|
+
[c] continuar sin --ci-aware (convergencia solo local)
|
|
406
|
+
[q] abortar — pushear manualmente y re-invocar
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Con `--no-prompt`: default es `p` (push automático).
|
|
410
|
+
|
|
411
|
+
**Algoritmo de espera**:
|
|
412
|
+
|
|
413
|
+
1. Tras Señal A, obtener SHA actual de `HEAD` y ejecutar `git ls-remote origin <rama>` para confirmar que está sincronizado.
|
|
414
|
+
2. Listar workflows aplicables al SHA con:
|
|
415
|
+
```bash
|
|
416
|
+
gh run list --branch <rama> --limit 10 \
|
|
417
|
+
--json status,conclusion,name,headSha \
|
|
418
|
+
--jq '.[] | select(.headSha == "<SHA>")'
|
|
419
|
+
```
|
|
420
|
+
3. Esperar usando la regla global `monitor-ci.md` (patrón Monitor con `gh --jq`, NO `| jq`).
|
|
421
|
+
4. Clasificar resultado:
|
|
422
|
+
- **Todos `completed`+`success`** → Señal D confirmada, convergencia válida.
|
|
423
|
+
- **Algún workflow en `failure` o `cancelled`** → reabrir loop. Los hallazgos se extraen del log con `gh run view <run-id> --log-failed` y se procesan como pasada N+1.
|
|
424
|
+
- **Algún workflow `skipped` legítimo** (no se disparó por `paths:` filter) → NO suma al gate; convergencia válida si los aplicables están `success`.
|
|
425
|
+
- **Workflows aún en `in_progress` después del timeout configurado en monitor-ci** → escalar al usuario, no cerrar convergencia.
|
|
426
|
+
|
|
427
|
+
**Workflows aplicables vs no aplicables**:
|
|
428
|
+
|
|
429
|
+
`gh run list` puede listar workflows que NO se dispararon en el SHA actual por filtros `paths:` en el `on:` del workflow (ej. cambio solo en frontend no dispara Backend CI). Esos son **legítimamente ausentes**, no fallos.
|
|
430
|
+
|
|
431
|
+
El gate solo evalúa workflows que **sí se dispararon en el SHA**. La verificación es:
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
gh run list --branch <rama> --limit 10 --json headSha,name,status,conclusion \
|
|
435
|
+
--jq '[.[] | select(.headSha | startswith("<sha-corto>"))] | all(.[]; .status == "completed" and .conclusion == "success")'
|
|
436
|
+
```
|
|
385
437
|
|
|
386
|
-
|
|
438
|
+
Output `true` → Señal D. `false` con detalle → reabrir loop.
|
|
439
|
+
|
|
440
|
+
**Anti-patrones explícitos**:
|
|
441
|
+
|
|
442
|
+
- **Tratar timeout del monitor como "verde por default"**: el timeout significa "estado desconocido", NO `success`. Re-armar monitor o escalar al usuario.
|
|
443
|
+
- **Sumar skipped legítimo como pass sin matizar**: si el workflow X no se disparó porque el commit solo tocó docs, está bien, pero el reporte final debe enumerarlo: "Frontend CI: skipped por filtro paths (commit toca solo backend/)".
|
|
444
|
+
- **Asumir verde porque `git push` retornó exit 0**: push exitoso ≠ CI verde. push solo confirma que GitHub aceptó el push.
|
|
445
|
+
|
|
446
|
+
Origen: regla global `monitor-ci.md` cubre este protocolo en detalle. Esta sección lo activa específicamente para `/swl:verificar`.
|
|
447
|
+
|
|
448
|
+
### 4.6.8 — Backward compatibility
|
|
449
|
+
|
|
450
|
+
Sin `--until-converge`, el comportamiento del comando es idéntico al actual: una sola pasada, ofrece correcciones tras el veredicto, sale. Los flags `--until-converge` y `--ci-aware` son 100% aditivos.
|
|
387
451
|
|
|
388
452
|
## Paso 5 — Verificación de criterios de aceptación
|
|
389
453
|
|
|
@@ -401,6 +465,56 @@ Ejemplo de tabla de verificación:
|
|
|
401
465
|
| El usuario puede crear una cuenta | Test e2e / manual | PASA / FALLA / PENDIENTE |
|
|
402
466
|
```
|
|
403
467
|
|
|
468
|
+
### Smoke test manual obligatorio para módulos frontend grandes
|
|
469
|
+
|
|
470
|
+
Origen: SIGAF sesión 2026-05-21 (mejora D2). Cuando el alcance de la
|
|
471
|
+
verificación toca un **componente frontend > 2,000 LOC** (típicamente módulos
|
|
472
|
+
como `/catalogos`, `/contratos`, `/expedientes` que crecen orgánicamente), la
|
|
473
|
+
verificación automática NO es suficiente. Los tests unitarios pueden pasar y
|
|
474
|
+
el linter quedar limpio mientras el componente está **roto en el render
|
|
475
|
+
real** (estado inicial mal calculado, evento que no propaga, route guard que
|
|
476
|
+
redirige en loop, error de hidratación SSR que solo aparece en producción).
|
|
477
|
+
|
|
478
|
+
Reglas duras para esta sub-categoría:
|
|
479
|
+
|
|
480
|
+
1. **Detección automática del trigger**: si el revisor de código reporta
|
|
481
|
+
≥1 archivo en `frontend/` con LOC > 2000, OR la suma de LOC de archivos
|
|
482
|
+
modificados en el último commit en `frontend/` excede 1500, activar este
|
|
483
|
+
sub-paso.
|
|
484
|
+
|
|
485
|
+
2. **Smoke test manual obligatorio**: el VERIFICACION.md DEBE incluir un
|
|
486
|
+
bloque `## Smoke test manual (módulo frontend grande)` con los siguientes
|
|
487
|
+
checks que el usuario humano marca PASA/FALLA antes del merge:
|
|
488
|
+
|
|
489
|
+
```markdown
|
|
490
|
+
## Smoke test manual — frontend/<modulo> (X LOC)
|
|
491
|
+
|
|
492
|
+
- [ ] Arranca el dev server sin errores en consola
|
|
493
|
+
- [ ] Renderiza la pantalla principal del módulo sin pantalla blanca
|
|
494
|
+
- [ ] Navegación a cada sub-ruta funciona (listar nombres)
|
|
495
|
+
- [ ] Acciones CRUD principales completan flujo end-to-end
|
|
496
|
+
- [ ] No hay warnings de hidratación en consola (SSR si aplica)
|
|
497
|
+
- [ ] Layout responsive funciona en viewport mobile + desktop
|
|
498
|
+
- [ ] [Si aplica] Web vitals sin regresión vs commit anterior
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
3. **NO marcar verificación como APROBADA** hasta que el bloque esté completo
|
|
502
|
+
o el usuario explícitamente exente checks específicos con justificación.
|
|
503
|
+
|
|
504
|
+
4. **El comando NO ejecuta el smoke automáticamente** (requiere browser
|
|
505
|
+
humano); su responsabilidad es **incluir el bloque en VERIFICACION.md** y
|
|
506
|
+
marcar la decisión de verificación como `APROBADO_CON_OBSERVACIONES`
|
|
507
|
+
hasta que el bloque se cierre.
|
|
508
|
+
|
|
509
|
+
**Cuándo NO aplicar este sub-paso**:
|
|
510
|
+
|
|
511
|
+
- Módulos backend puros (cobertura suficiente con tests de integración).
|
|
512
|
+
- Cambios cosméticos a componentes frontend grandes (typo en texto, ajuste
|
|
513
|
+
de color de un botón) — la heurística LOC sigue disparándose pero el
|
|
514
|
+
usuario puede exentar con `[exento: cambio cosmético en X líneas]`.
|
|
515
|
+
- Módulos con cobertura E2E > 70% probada (webapp-testing, Playwright,
|
|
516
|
+
Cypress) — el smoke automático cubre la necesidad.
|
|
517
|
+
|
|
404
518
|
## Paso 6 — Consolidación y generación del VERIFICACION.md
|
|
405
519
|
|
|
406
520
|
Consolida todos los hallazgos en `.planning/fases/0N-VERIFICACION.md`:
|