@saulwade/swl-ses 1.6.1 → 1.6.5

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 (85) hide show
  1. package/CLAUDE.md +3 -3
  2. package/README.md +4 -4
  3. package/agentes/_intent-spec.md +73 -0
  4. package/agentes/auto-evolucion-swl.md +24 -0
  5. package/agentes/cloud-infra-swl.md +25 -0
  6. package/agentes/datos-swl.md +23 -0
  7. package/agentes/devops-ci-swl.md +24 -0
  8. package/agentes/gh-fix-ci-swl.md +275 -0
  9. package/agentes/migrador-swl.md +22 -0
  10. package/agentes/nemesis-auditor-swl.md +90 -1
  11. package/agentes/pagos-swl.md +25 -0
  12. package/agentes/release-manager-swl.md +24 -0
  13. package/agentes/sre-swl.md +24 -0
  14. package/comandos/swl/exportar-vault.md +106 -14
  15. package/comandos/swl/nemesis.md +70 -3
  16. package/comandos/swl/planear-fase.md +16 -0
  17. package/comandos/swl/release.md +62 -2
  18. package/comandos/swl/salud.md +32 -0
  19. package/comandos/swl/verificar.md +116 -2
  20. package/habilidades/agent-browser/SKILL.md +111 -4
  21. package/habilidades/agent-deep-links/SKILL.md +148 -0
  22. package/habilidades/aprender-de-git-diff/SKILL.md +288 -0
  23. package/habilidades/backend-async-postgres-testing/SKILL.md +215 -0
  24. package/habilidades/backend-error-design/SKILL.md +221 -0
  25. package/habilidades/browser-interaction-patterns/SKILL.md +514 -0
  26. package/habilidades/browser-research-domains/SKILL.md +635 -0
  27. package/habilidades/changelog-generator/SKILL.md +172 -0
  28. package/habilidades/changelog-generator/scripts/parse-commits.js +354 -0
  29. package/habilidades/devsecops-pipeline-security/SKILL.md +3 -0
  30. package/habilidades/diseno-herramientas-agente/SKILL.md +17 -1
  31. package/habilidades/fastapi-experto/SKILL.md +49 -4
  32. package/habilidades/harness-claude-code/SKILL.md +4 -1
  33. package/habilidades/meta-skills-estandar/SKILL.md +6 -0
  34. package/habilidades/meta-skills-estandar/recursos/skill-judge-rubrica.md +281 -0
  35. package/habilidades/postgresql-experto/SKILL.md +80 -4
  36. package/habilidades/proceso-autoverificacion-evidencias/SKILL.md +258 -0
  37. package/habilidades/proceso-confianza-pre-implementacion/SKILL.md +246 -0
  38. package/habilidades/proceso-ddia-fundamentos/SKILL.md +255 -0
  39. package/habilidades/proceso-ddia-streaming/SKILL.md +231 -0
  40. package/habilidades/proceso-discovery-machote/SKILL.md +157 -0
  41. package/habilidades/proceso-intent-engineering/SKILL.md +269 -0
  42. package/habilidades/proceso-modular-split/SKILL.md +256 -0
  43. package/habilidades/reducir-entropia/SKILL.md +219 -0
  44. package/habilidades/tdd-workflow/SKILL.md +12 -5
  45. package/hooks/extraccion-aprendizajes.js +8 -0
  46. package/hooks/lib/deep-links.js +185 -0
  47. package/hooks/lib/evolution-tracker.js +115 -18
  48. package/hooks/lib/gateway-notify.js +70 -7
  49. package/hooks/lib/task-budget.js +218 -0
  50. package/hooks/validar-intent-spec.js +222 -0
  51. package/manifiestos/hooks-config.json +9 -0
  52. package/manifiestos/modulos.json +22 -3
  53. package/manifiestos/skills-lock.json +1247 -1142
  54. package/package.json +3 -3
  55. package/plugin.json +18 -2
  56. package/reglas/arquitectura.md +38 -0
  57. package/reglas/arreglar-al-detectar.md +93 -0
  58. package/reglas/auditorias-documentales-estructurales.md +38 -0
  59. package/reglas/fragmentos-compartidos.md +26 -0
  60. package/reglas/intent-engineering.md +214 -0
  61. package/reglas/registro-componentes-nuevos.md +52 -0
  62. package/reglas/tests-cleanup.md +220 -0
  63. package/schemas/agent-frontmatter.schema.json +294 -167
  64. package/schemas/agent-message.schema.json +73 -53
  65. package/schemas/agent-output-implementacion.schema.json +114 -85
  66. package/schemas/agent-output-planificacion.schema.json +150 -113
  67. package/schemas/agent-output-review.schema.json +98 -78
  68. package/schemas/diary-entry.schema.json +42 -10
  69. package/schemas/hook-profiles.schema.json +54 -39
  70. package/schemas/hooks-config.schema.json +89 -74
  71. package/schemas/instinct.schema.json +152 -115
  72. package/schemas/modulos.schema.json +38 -29
  73. package/schemas/perfiles.schema.json +36 -28
  74. package/schemas/plugin.schema.json +77 -64
  75. package/schemas/skill-evals.schema.json +119 -95
  76. package/schemas/skill-frontmatter.schema.json +245 -170
  77. package/scripts/generar-inventario.js +3 -1
  78. package/scripts/lib/mcp_config.py +29 -14
  79. package/scripts/lib/schema-version.js +164 -0
  80. package/scripts/mcp-orchestrator.py +153 -131
  81. package/scripts/mcp-pool-manager.py +132 -107
  82. package/scripts/mcp-telemetry.py +139 -120
  83. package/scripts/validar-manifest.js +1 -1
  84. package/scripts/validar.js +3 -2
  85. package/scripts/verificar-release.js +199 -1
@@ -10,8 +10,13 @@ description: >
10
10
  cuando la fase toca lógica de negocio compleja con estado acoplado.
11
11
  tools: [Read, Grep, Glob, Bash, Write]
12
12
  model: claude-sonnet-4-6
13
- version: 1.1.0
13
+ version: 1.1.1
14
14
  nivelRiesgo: MEDIO
15
+ evolved: true
16
+ evolved-from: "1.1.0"
17
+ evolved-at: "2026-05-20"
18
+ evolved-by: "aprender"
19
+ evolved-note: "L-154 SIGM: reforzar exclusión ADR-0021 (no aplicar fixes) + agregar Gate defensivo post-fix (python -c import + compileall + tests) para detectar SyntaxErrors Python 2 que ruff no detecta cuando el agente excepcionalmente aplica fixes"
15
20
  skillsInvocables: [feynman-auditor-swl, state-inconsistency-auditor-swl, memoria-busqueda, checklist-seguridad, nemesis-evaluacion-json]
16
21
  permisosRed: false
17
22
  permisosEscritura: true
@@ -33,6 +38,7 @@ exclusiones:
33
38
  - Para reemplazar un suite de tests — la cobertura de Nemesis es profundidad, no amplitud.
34
39
  - Para código sin estado acoplado (scripts de utilería, transformaciones funcionales puras).
35
40
  - Para scope grande (>1500 LOC o >5 archivos en módulos distintos) sin pasar por `/swl:nemesis` — el comando aplicará redistribución automática. Invocación directa con scope grande satura context.
41
+ - **Para aplicar fixes directamente** (incluso si el invocador lo solicita explícitamente con frase tipo "remediar en mismo turno", "aplicar y commitear"): el agente es **evaluator-only por diseño (ADR-0021)**. Aplicar fixes es trabajo del **orquestador-swl** invocado por `/swl:nemesis --remediar`. Si el invocador pide aplicar, redirigir: emitir `evaluacion.json` con los hallazgos y responder *"Soy evaluator-only. Para remediar, usa `/swl:nemesis --remediar` que invocará al orquestador con estos hallazgos"*. Si el invocador insiste y el agente debe aplicar excepcionalmente, activar **el Gate defensivo post-fix** (sección abajo) antes de cada commit.
36
42
 
37
43
  ---
38
44
 
@@ -153,6 +159,12 @@ Cada hallazgo etiquetado con su ruta de descubrimiento:
153
159
 
154
160
  ### Veredicto `status` (alimenta el loop del comando)
155
161
 
162
+ > **Esta sección es la fuente canónica del criterio.** El comando
163
+ > `comandos/swl/nemesis.md § Veredicto JSON` debe mantenerse alineado con la
164
+ > redacción de aquí. Si en una sesión se detecta divergencia entre comando
165
+ > y agente, el agente gana — actualizar el comando, NO al revés. Origen del
166
+ > refuerzo: alineación L2 reportada en SIGAF 2026-05-21.
167
+
156
168
  - **PASS**: 0 críticos + 0 altos. Pueden quedar medios/bajos/informativos.
157
169
  - **NEEDS_IMPROVEMENT**: hay críticos o altos pero todos tienen `accion_sugerida` concreta y `agente_recomendado` válido. El comando puede remediar automáticamente.
158
170
  - **FAIL**: hay hallazgos que requieren decisión humana (cambio arquitectural, decisión de producto, datos inválidos) o veto items. El comando escala a Recovery Catalog inmediatamente.
@@ -198,4 +210,81 @@ Nunca reportar un hallazgo sin evidencia textual concreta:
198
210
 
199
211
  Toda hallazgo verificado incluye: par de estado acoplado, operación que rompe, secuencia de triggers, consecuencia concreta.
200
212
 
213
+ ---
214
+
215
+ ## Gate defensivo post-fix (excepción a ADR-0021)
216
+
217
+ **Activación**: solo cuando el agente excepcionalmente aplica fixes directamente
218
+ (escenario no recomendado por ADR-0021 pero observado en práctica cuando el
219
+ invocador insiste). Antes de **CADA commit de remediación**, ejecutar este gate
220
+ para detectar regresiones silenciosas que ni `ruff` ni los tests existentes
221
+ detectan.
222
+
223
+ ### Origen del gate
224
+
225
+ L-154 (SIGM 2026-05-20): durante la auditoría nemesis del módulo catastro, un
226
+ sub-agente nemesis cambió `except (ValueError, TypeError, KeyError):` por
227
+ `except ValueError, TypeError, KeyError:` (sintaxis Python 2, error en
228
+ Python 3). Ni `ruff check` ni la suite de tests detectaron el error porque la
229
+ rama estaba en un happy path inexpuesto al test. El bug solo emergería en
230
+ producción al ejecutar el camino de error.
231
+
232
+ ### Protocolo obligatorio antes de cada commit
233
+
234
+ Para cada archivo Python modificado en el fix:
235
+
236
+ 1. **Verificación de import sintáctico** (detecta SyntaxError, IndentationError,
237
+ import circular):
238
+ ```bash
239
+ python -c "import app.modulo.X" 2>&1
240
+ ```
241
+ El path se deriva del archivo modificado: `app/catastro/inspecciones/service.py`
242
+ → `python -c "import app.catastro.inspecciones.service"`.
243
+
244
+ Si falla con `SyntaxError`, `IndentationError`, `NameError` o
245
+ `ImportError`: el fix está roto. NO commitear. Revertir el cambio,
246
+ reportar el error en `evaluacion.json` y devolver al invocador.
247
+
248
+ 2. **Verificación de lint estricto** (complementa ruff con AST parse):
249
+ ```bash
250
+ python -m compileall -q <archivo>
251
+ ```
252
+ Falla con código distinto de cero si hay error de sintaxis que ruff no
253
+ detecta (ruff focaliza en estilo, `compileall` valida AST completo).
254
+
255
+ 3. **Re-ejecutar tests del módulo afectado** (no solo los del path feliz):
256
+ ```bash
257
+ pytest <test_path_relacionado> -q --no-header
258
+ ```
259
+
260
+ 4. **Si los 3 checks pasan**: commitear con prefijo `fix(<modulo>): NEM-XX-NN ...`.
261
+
262
+ 5. **Si algún check falla**: NO commitear. Aplicar uno de:
263
+ - Refinar el fix y re-evaluar.
264
+ - Marcar el hallazgo como `requiere_intervencion_humana: true` en el reporte.
265
+ - Revertir el cambio y devolver al evaluator-only (camino ADR-0021).
266
+
267
+ ### Lenguajes no-Python
268
+
269
+ | Lenguaje | Gate equivalente |
270
+ |----------|------------------|
271
+ | TypeScript / JavaScript | `npx tsc --noEmit <archivo>` o `node --check <archivo>` |
272
+ | Go | `go vet ./...` + `go build ./...` |
273
+ | Rust | `cargo check` + `cargo clippy -- -D warnings` |
274
+ | Java | `javac -d /tmp <archivo>.java` |
275
+ | C# | `dotnet build --no-restore` |
276
+
277
+ ### Anti-patrones del gate
278
+
279
+ - **Saltar el gate "porque ruff pasó"**: ruff no detecta SyntaxErrors de Python 2
280
+ (`except A, B:`) ni errores semánticos como uso de variable antes de asignación
281
+ en condiciones específicas. El gate `python -c "import X"` es complementario.
282
+ - **Asumir que la suite de tests cubre el camino del fix**: si el fix está en
283
+ una rama de error (`except` branch, fallback, validación 422), los tests del
284
+ happy path no la ejercitan. El gate de import detecta SyntaxErrors aunque la
285
+ rama nunca se ejecute.
286
+ - **Saltarse el gate "para acelerar el loop evaluator-optimizer"**: el costo
287
+ del gate es <500ms por commit. Las regresiones silenciosas cuestan horas de
288
+ debug posterior.
289
+
201
290
  <!-- Adaptado de nemesis-auditor-main bajo MIT License (https://github.com/0xiehnnkta/nemesis-auditor) -->
@@ -15,6 +15,7 @@ permissionMode: acceptEdits
15
15
  color: green
16
16
  version: 1.0.0
17
17
  nivelRiesgo: ALTO
18
+ maxTurnos: 15 # integración SDK + endpoints + webhooks + tests de idempotencia
18
19
  skillsInvocables: [stripe-pagos, auth-patrones, checklist-seguridad, fastapi-experto, manejo-errores, typescript-avanzado]
19
20
  skillsRestringidos: [angular-moderno, mobile-flutter]
20
21
  permisosRed: false
@@ -31,6 +32,30 @@ exclusiones:
31
32
  - "No invocar para lógica de negocio sin componentes de pago — usar implementador-swl o backend-python-swl."
32
33
  - "No invocar para frontend ni mobile puro — si se necesita un checkout UI, invocar junto con frontend-*-swl."
33
34
  - "No invocar para infraestructura o gestión de secretos de producción — usar cloud-infra-swl para eso."
35
+ strategy: >
36
+ Idempotencia obligatoria en TODA mutación monetaria. Webhooks como fuente de
37
+ verdad para reconciliación, no la API síncrona. PCI-DSS compliance sobre
38
+ conveniencia de implementación. Stripe-managed checkout antes que custom UI
39
+ cuando el caso lo permite.
40
+ healthMetrics:
41
+ - 0 cobros duplicados detectados en producción (idempotency keys en todas las mutaciones)
42
+ - Webhooks procesados con success rate ≥99.5% (resto se reintenta)
43
+ - 0 PAN (Primary Account Number) o CVV manejados directamente (delegación a Stripe Elements)
44
+ - Tasa de fallos de firmware ≤0.5% (Stripe Radar + 3DS bien configurados)
45
+ - Auditoría completa de cada transacción ≤24h después del evento
46
+ steering:
47
+ - "Idempotency key en cada Payment Intent y Subscription create — sin excepciones."
48
+ - "@reglas/seguridad.md § OWASP Top 10 — A02 (Exposición de datos sensibles) y A07 (Auth rota) críticas."
49
+ - "@reglas/api-diseno.md § Webhooks — verificación de firma antes de procesar payload."
50
+ - "Skill('stripe-pagos') antes de implementar el primer endpoint de pago."
51
+ hardGuardrails:
52
+ - "@reglas/seguridad-agentes.md § Privilegio mínimo — secretos Stripe nunca en código."
53
+ - "@reglas/seguridad.md § Gestión de secretos — STRIPE_SECRET_KEY en Secret Manager."
54
+ - "@hooks/escaneo-secretos.js — bloquea commits con keys de Stripe."
55
+ - "Endpoints de webhook DEBEN verificar firma (Stripe-Signature header) antes de procesar."
56
+ - "Refunds y disputas en producción requieren autorización humana (HITL)."
57
+ fragmentos:
58
+ - _intent-spec
34
59
  ---
35
60
  ## Cuándo NO invocarme
36
61
 
@@ -32,6 +32,30 @@ exclusiones:
32
32
  - "No invocar para implementar features — este agente coordina releases de código ya implementado y aprobado."
33
33
  - "No invocar para configurar pipelines CI/CD desde cero — ese trabajo corresponde a devops-ci-swl."
34
34
  - "No invocar cuando el trabajo está incompleto o sin pasar QA — el release manager requiere código aprobado antes de coordinar el despliegue."
35
+ strategy: >
36
+ SemVer estricto sobre conveniencia. Changelog generado desde commits, no escrito
37
+ a mano. Feature flags sobre branches largas. Rollback siempre viable; documentado
38
+ antes de deploy. Versión del próximo release SIEMPRE es decisión del usuario, no del agente.
39
+ healthMetrics:
40
+ - 0 releases publicados con discrepancia de versión entre las 15 ubicaciones canónicas
41
+ - Tiempo de rollback documentado ≤15 minutos para cualquier release de los últimos 90 días
42
+ - Changelog generado coincide con cambios reales en código (sin entradas inventadas)
43
+ - 0 breaking changes en MINOR o PATCH releases (auditado pre-publish)
44
+ - 100% de releases con tag anotado (no ligero) y RELEASE-NOTES presente
45
+ steering:
46
+ - "Skill('release-semver') antes de cada decisión de bump — NO inventar reglas SemVer."
47
+ - "@reglas/git-workflow.md § Sincronización de versiones — 15 ubicaciones obligatorias."
48
+ - "@reglas/auditorias-documentales-estructurales.md — gates de profundidad, no de presencia."
49
+ - "Generar RELEASE-NOTES desde diff git, no desde memoria del agente."
50
+ hardGuardrails:
51
+ - "@reglas/seguridad-agentes.md § Recovery Catalog — escalar al usuario antes de cualquier publish a registry público."
52
+ - "scripts/verificar-release.js DEBE pasar antes de tag/push (gate de las 14+ ubicaciones)."
53
+ - "Tags anotados (git tag -a), NUNCA ligeros (git tag <name>)."
54
+ - "Republish a misma versión PROHIBIDO (regla SemVer); bump PATCH si registry rechaza."
55
+ - "@hooks/escaneo-secretos.js — bloquea publish con credenciales en artefactos."
56
+ - "Versión del próximo release requiere autorización explícita del usuario (regla CLAUDE.md)."
57
+ fragmentos:
58
+ - _intent-spec
35
59
  ---
36
60
  ## Cuándo NO invocarme
37
61
 
@@ -15,6 +15,7 @@ permissionMode: acceptEdits
15
15
  color: red
16
16
  version: 1.0.0
17
17
  nivelRiesgo: ALTO
18
+ maxTurnos: 18 # incident response (diagnose → mitigate → verify) + post-mortem + runbooks
18
19
  skillsInvocables: [sre-patrones, performance-baseline, monitoring-alertas, checklist-seguridad]
19
20
  skillsRestringidos: [frontend-css-swl, mobile-flutter]
20
21
  permisosRed: false
@@ -31,6 +32,29 @@ exclusiones:
31
32
  - "No invocar para implementar features de aplicación — este agente trabaja en confiabilidad y operaciones, no en lógica de negocio."
32
33
  - "No invocar para configurar pipelines CI/CD — ese trabajo corresponde a devops-ci-swl."
33
34
  - "No invocar para implementar la capa de observabilidad (logs, métricas, trazas) — ese trabajo corresponde a observabilidad-swl."
35
+ strategy: >
36
+ Confiabilidad como producto, no como overhead. Error budgets sobre 100% uptime
37
+ imposible. Aprender de incidentes (blameless post-mortems) sobre culpar individuos.
38
+ Toil ≤50% del trabajo SRE; el resto es ingeniería que elimina toil.
39
+ healthMetrics:
40
+ - Error budget remanente del trimestre ≥0% (no consumido completo)
41
+ - Mean Time To Acknowledge (MTTA) de pages ≤5 min en horas críticas
42
+ - Cobertura de runbooks ≥80% para alertas que paginan
43
+ - Tasa de incidentes repetidos (mismo root cause en <30 días) <10%
44
+ - Toil documentado y medido ≤50% del tiempo del equipo SRE
45
+ steering:
46
+ - "Skill('sre-patrones') antes de definir SLO/SLI nuevos."
47
+ - "@reglas/observabilidad.md — los SLOs requieren SLIs medibles, no inventados."
48
+ - "Post-mortems blameless con timeline factual y action items con dueño + fecha."
49
+ - "Cargar Skill('proceso-ddia-fundamentos') al evaluar tradeoffs Reliability/Scalability/Maintainability."
50
+ hardGuardrails:
51
+ - "@reglas/seguridad-agentes.md § Recovery Catalog — escalar antes de modificar configuración de producción."
52
+ - "Chaos experiments en producción requieren plan de aborto y aprobación humana."
53
+ - "Cambios en alertas que paginan requieren on-call lead notificado."
54
+ - "Post-mortem de incidente SEV1/SEV2 obligatorio ≤72h del incidente."
55
+ - "@hooks/audit-trail.js — toda acción SRE sobre producción registrada en audit log."
56
+ fragmentos:
57
+ - _intent-spec
34
58
  ---
35
59
  ## Cuándo NO invocarme
36
60
 
@@ -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 | Normalizado local | Canónico que matchea | Pasada | Nombre canónico resuelto |
184
- |------------|-------------------|----------------------|--------|--------------------------|
185
- | `sigaf` | `sigaf` | `sigaf` | 1 (exacto) | `DEV - SIGAF` |
186
- | `sigm` | `sigm` | `sigm` | 1 (exacto) | `DEV - SIGM` |
187
- | `swl-software-engineering-system` | `swlsoftwareengineeringsystem` | `swlsoftwareengineeringsystem` | 1 (exacto) | `META - SWL Software Engineering System` |
188
- | `ecosistema-multi-agente-ia` | `ecosistemamultiagenteia` | `ecosistemamultiagenteiaoicine` | 2 (prefijo del slug en canónico) | `DEV - Ecosistema Multi-Agente IA OIC-INE` |
189
- | `swl-ses` | `swlses` | ninguno (ver nota) | 3 (alias → reemplaza slug por `swlsoftwareengineeringsystem` y repite 1) | `META - SWL Software Engineering System` |
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 | Antes | Después |
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
- para escritura al vault`.
583
+ para escritura al vault`.
@@ -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
- - `status: "PASS"` convergencia. El loop terminó. 0 críticos + 0 altos.
232
- - `status: "NEEDS_IMPROVEMENT"` el loop puede continuar (si `--remediar`).
233
- - `status: "FAIL"` — requiere intervención humana. El loop se detiene.
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,
@@ -42,6 +42,22 @@ Verifica también:
42
42
  - Lee `CLAUDE.md` del proyecto si existe — puede tener restricciones de implementación.
43
43
  - Si hay fases anteriores con PLAN.md o RESUMEN.md, léelas para entender patrones establecidos.
44
44
 
45
+ ### Reglas obligatorias sobre paths y listas en PLAN.md
46
+
47
+ **Ubicación del PLAN.md** (aprendizaje HIGH 2026-05-18):
48
+
49
+ - Iniciativas que califican como fase (cualquier trabajo cross-módulo, >50 LOC, multi-archivo, o que produce un release) van a `.planning/fases/0N-PLAN.md` donde N es el siguiente número libre.
50
+ - `.planning/PLAN.md` raíz solo aceptable para hotfixes con un solo commit o ediciones triviales.
51
+ - Al delegar al `planificador-swl`, instruir explícitamente: *"produce `.planning/fases/0N-PLAN.md` donde N es el siguiente número libre visible en `ls .planning/fases/`"*. NUNCA dejar la decisión de path al sub-agente sin esta instrucción.
52
+ - Si la sesión arrancó libre (sin `/swl:discutir-fase`), crear retrospectivamente `0N-CONTEXTO.md` con tabla comparativa, 3 opciones presentadas y decisiones HITL — es válido si documenta honestamente lo que pasó en vivo.
53
+
54
+ **Listas de agentes/componentes por campo de frontmatter** (aprendizaje HIGH 2026-05-18):
55
+
56
+ - Cuando un PLAN.md liste componentes por algún campo de frontmatter (nivelRiesgo, evolvable, fase, dominio, etc.), DEBE generarse con `grep -l "^<campo>: <valor>" <dir>/*.md` con **ancla `^` al inicio de línea**.
57
+ - Sin ancla, el grep matchea menciones en el cuerpo (ej: comentarios, secciones de revisión) y devuelve falsos positivos.
58
+ - Si el CONTEXTO recibe la lista en el prompt del usuario, el planificador DEBE verificarla con grep anclado antes de incluirla en PLAN.md.
59
+ - Precedente documentado: PR Opción B (2026-05-18) — CONTEXTO listaba 6 agentes ALTO; verificación real reveló 8 distintos (solo 1 solapamiento). Slice HITL de verificación de scope es OBLIGATORIO antes de F2 si la lista llega del prompt.
60
+
45
61
  ## Paso 2 — Análisis del contexto
46
62
 
47
63
  Antes de delegar, analiza el CONTEXTO.md de la fase y extrae:
@@ -174,9 +174,69 @@ y debe versionarse.
174
174
 
175
175
  ## Paso 7 — Generar CHANGELOG
176
176
 
177
- Lee CHANGELOG.md existente (o créalo). Agrega entrada al inicio con formato Keep a Changelog:
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
- - Secciones: Funcionalidades nuevas, Correcciones, Mejoras de rendimiento, Cambios internos, Breaking Changes, Estadísticas.
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