@saulwade/swl-ses 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/CLAUDE.md +3 -3
  2. package/README.md +561 -560
  3. package/agentes/nemesis-auditor-swl.md +161 -161
  4. package/bin/swl-mcp-server.js +49 -22
  5. package/bin/swl-ses.js +74 -0
  6. package/comandos/swl/.evolved.json +22 -22
  7. package/comandos/swl/contribuir.md +233 -233
  8. package/comandos/swl/ejecutar-fase.md +33 -4
  9. package/comandos/swl/metricas.md +72 -0
  10. package/comandos/swl/nemesis.md +122 -122
  11. package/gateway/lib/event-channel.js +191 -191
  12. package/habilidades/backend-production-resilience/SKILL.md +288 -288
  13. package/habilidades/benchmark-memoria/SKILL.md +186 -186
  14. package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
  15. package/habilidades/discutir-fase/SKILL.md +50 -2
  16. package/habilidades/doubt-driven-review/SKILL.md +171 -171
  17. package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
  18. package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -0
  19. package/habilidades/eval-framework/SKILL.md +212 -212
  20. package/habilidades/feynman-auditor-swl/SKILL.md +123 -123
  21. package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -108
  22. package/habilidades/harness-claude-code/SKILL.md +299 -299
  23. package/habilidades/infra-github-actions/SKILL.md +166 -166
  24. package/habilidades/legacy-code-rescue/SKILL.md +267 -267
  25. package/habilidades/manejo-errores/.evolved.json +8 -8
  26. package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
  27. package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -163
  28. package/habilidades/patrones-python/SKILL.md +229 -229
  29. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
  30. package/habilidades/planear-fase/SKILL.md +319 -319
  31. package/habilidades/protocolo-revision-swl/SKILL.md +276 -0
  32. package/habilidades/release-semver/.evolved.json +8 -8
  33. package/habilidades/state-inconsistency-auditor-swl/SKILL.md +166 -166
  34. package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -147
  35. package/habilidades/testing-python/SKILL.md +340 -340
  36. package/habilidades/verificar-trabajo/SKILL.md +49 -5
  37. package/habilidades/web-fetcher-routing/SKILL.md +75 -75
  38. package/hooks/claudemd-bloat-detector.js +161 -161
  39. package/hooks/lib/agent-routing.js +107 -107
  40. package/hooks/lib/auto-consolidator.js +335 -335
  41. package/hooks/lib/error-classifier.js +308 -308
  42. package/hooks/lib/merkle-audit.js +96 -96
  43. package/hooks/lib/provenance-tracker.js +191 -191
  44. package/hooks/lib/rate-limit-tracker.js +253 -253
  45. package/hooks/lib/resource-quota.js +122 -122
  46. package/hooks/lib/retry-jitter.js +165 -165
  47. package/hooks/lib/security-net.js +201 -201
  48. package/hooks/lib/skill-auditor.js +588 -588
  49. package/hooks/lib/sync-status.js +228 -228
  50. package/hooks/lib/taint-tracker.js +107 -107
  51. package/hooks/lib/text-similarity.js +241 -241
  52. package/hooks/lib/toon-compressor.js +245 -245
  53. package/hooks/registro-turnos.js +209 -209
  54. package/hooks/sugerir-regenerar-inventario.js +170 -170
  55. package/hooks/validar-formato-post-subagente.js +140 -140
  56. package/hooks/validar-memoria-hook.js +218 -218
  57. package/instintos/prompt-appendices.yaml +57 -57
  58. package/manifiestos/agent-output-schemas.json +57 -57
  59. package/manifiestos/modulos.json +1321 -1262
  60. package/manifiestos/perfiles.json +2 -1
  61. package/manifiestos/skills-lock.json +1114 -1114
  62. package/package.json +3 -3
  63. package/plantillas/auditor-veto-template.md +105 -105
  64. package/plantillas/github-workflows/README.md +47 -47
  65. package/plantillas/github-workflows/release-please.yml +44 -44
  66. package/plantillas/github-workflows/swl-ci.yml +107 -107
  67. package/plantillas/github-workflows/swl-security.yml +51 -51
  68. package/plugin.json +351 -343
  69. package/reglas/analisis-previo-tareas-grandes.md +172 -172
  70. package/reglas/arreglar-al-detectar.md +147 -147
  71. package/reglas/fragmentos-compartidos.md +152 -152
  72. package/reglas/harness-claude-code.md +213 -213
  73. package/reglas/usar-context7.md +226 -226
  74. package/schemas/diary-entry.schema.json +80 -80
  75. package/scripts/audit-tools/audit-history.js +330 -330
  76. package/scripts/audit-tools/bundle-tracker.js +290 -290
  77. package/scripts/audit-tools/canary-monitor.js +352 -352
  78. package/scripts/audit-tools/code-profiler.js +605 -605
  79. package/scripts/audit-tools/dep-doctor.js +320 -320
  80. package/scripts/audit-tools/env-validator.js +206 -206
  81. package/scripts/audit-tools/lib/fs-walk.js +48 -48
  82. package/scripts/audit-tools/lib/output.js +23 -23
  83. package/scripts/audit-tools/migration-checker.js +392 -392
  84. package/scripts/audit-tools/pentest-scanner.js +1436 -1436
  85. package/scripts/benchmark-memoria.js +167 -167
  86. package/scripts/configurar-branch-protection.js +418 -418
  87. package/scripts/derivar-feature-list.js +489 -0
  88. package/scripts/detectar-aprendizajes-duplicados.js +151 -151
  89. package/scripts/doctor.js +31 -4
  90. package/scripts/field-report.js +199 -199
  91. package/scripts/generar-checklists-consolidados.js +273 -273
  92. package/scripts/generar-inventario.js +420 -420
  93. package/scripts/generar-matriz-lenguajes.js +271 -271
  94. package/scripts/instalador.js +56 -5
  95. package/scripts/lib/artefactos-python.js +43 -43
  96. package/scripts/lib/benchmark-metrics.js +160 -160
  97. package/scripts/lib/budget-enforcer.js +252 -252
  98. package/scripts/lib/configurar-ci.js +380 -380
  99. package/scripts/lib/contadores-inventario.js +217 -217
  100. package/scripts/lib/detectar-runtime.js +75 -9
  101. package/scripts/lib/detectar-stack-detallado.js +307 -307
  102. package/scripts/lib/diary-entry.js +234 -234
  103. package/scripts/lib/estado.js +13 -1
  104. package/scripts/lib/eval-metrics-store.js +218 -218
  105. package/scripts/lib/eval-quality.js +171 -171
  106. package/scripts/lib/eval-schemas.js +144 -144
  107. package/scripts/lib/eval-self-correct.js +106 -106
  108. package/scripts/lib/eval-validator.js +185 -185
  109. package/scripts/lib/expandir-targets.js +71 -0
  110. package/scripts/lib/jaccard-similarity.js +98 -98
  111. package/scripts/lib/longmemeval-runner.js +125 -125
  112. package/scripts/lib/manifiestos.js +42 -1
  113. package/scripts/lib/npm-version.js +261 -261
  114. package/scripts/lib/paquetes-conocidos.js +50 -50
  115. package/scripts/lib/parsear-opciones.js +3 -0
  116. package/scripts/lib/prompt-builder.js +264 -264
  117. package/scripts/lib/rrf-fusion.js +175 -175
  118. package/scripts/lib/scoring-instintos.js +277 -277
  119. package/scripts/lib/semantic-search.js +252 -252
  120. package/scripts/lib/toml-merge.js +204 -0
  121. package/scripts/lib/transformadores/base.js +43 -9
  122. package/scripts/lib/transformadores/codex.js +375 -115
  123. package/scripts/lib/transformadores/cursor.js +359 -0
  124. package/scripts/lib/transformadores/index.js +2 -0
  125. package/scripts/limpiar-artefactos-python.js +131 -131
  126. package/scripts/mcp-server/README.md +122 -80
  127. package/scripts/mcp-server/auth.js +105 -0
  128. package/scripts/mcp-server/cache.js +106 -0
  129. package/scripts/mcp-server/handlers.js +386 -206
  130. package/scripts/mcp-server/telemetry.js +78 -0
  131. package/scripts/migrar-csv-a-array.js +168 -168
  132. package/scripts/migrar-fase-dominio.js +201 -201
  133. package/scripts/publicar.js +511 -511
  134. package/scripts/run-eval.js +141 -141
  135. package/scripts/validar-manifest.js +231 -195
  136. package/scripts/validar-userland-vacio.js +110 -110
@@ -1,161 +1,161 @@
1
- ---
2
- name: nemesis-auditor-swl
3
- description: >
4
- Auditor de doble paso iterativo (Feynman + State Inconsistency) que encuentra
5
- bugs en la intersección que ningún paso individual detecta. Language-agnostic
6
- (Python, TypeScript, Go, Rust, Java, C#). Invocar tras revisor-codigo-swl y
7
- revisor-seguridad-swl cuando la fase toca lógica de negocio compleja con
8
- estado acoplado.
9
- tools: [Read, Grep, Glob, Bash, Write]
10
- model: claude-sonnet-4-6
11
- version: 1.0.0
12
- nivelRiesgo: MEDIO
13
- skillsInvocables: [feynman-auditor-swl, state-inconsistency-auditor-swl]
14
- permisosRed: false
15
- permisosEscritura: true
16
- permisosComandos: true
17
- maxTurnos: 20
18
- evolvable: true
19
- exclusiones:
20
- - "No invocar para pattern-matching de CVEs conocidos — usar revisor-seguridad-swl."
21
- - "No invocar para refactor o implementación — solo audita, no modifica código."
22
- - "No invocar como sustituto de tests — Nemesis complementa, no reemplaza testing."
23
- - "No invocar para análisis de blockchain — el agente fue generalizado a Python/TS/Go/Rust/Java/C#."
24
- ---
25
-
26
- # Cuándo NO invocarme
27
-
28
- - Para búsqueda de vulnerabilidades conocidas (CVE, OWASP Top 10) — usar `revisor-seguridad-swl`.
29
- - Para refactor, limpiar deuda técnica o implementar funcionalidad nueva — Nemesis audita, no toca código.
30
- - Para reemplazar un suite de tests — la cobertura de Nemesis es profundidad, no amplitud.
31
- - Para código sin estado acoplado (scripts de utilería, transformaciones funcionales puras).
32
-
33
- ---
34
-
35
- # Nemesis Auditor
36
-
37
- Dos auditores en bucle de retroalimentación. Cada uno alimenta al siguiente con sus hallazgos. El ciclo continúa hasta que ninguno encuentre algo nuevo (convergencia) o se alcancen 6 pasadas.
38
-
39
- ```
40
- PASADA 1: Feynman Auditor (corrida completa)
41
- Cuestiona cada línea. Expone asunciones. Marca sospechosos.
42
-
43
- | feed forward |
44
-
45
- PASADA 2: State Inconsistency Auditor (corrida completa, enriquecido por Pasada 1)
46
- Mapea estado acoplado. Encuentra gaps de mutación. Usa sospechosos de Feynman como objetivos.
47
-
48
- | feed forward |
49
-
50
- PASADA 3+: Pasadas alternantes dirigidas hasta convergencia
51
- Cada pasada interroga los nuevos hallazgos de la anterior.
52
- Máximo 6 pasadas. Nada sobrevive.
53
- ```
54
-
55
- ---
56
-
57
- ## Proceso — Fase 0: Contexto
58
-
59
- Antes de la Pasada 1, establecer:
60
-
61
- 1. ¿Qué archivos o módulos están en scope? (sin scope → el auditor infiere desde el directorio de trabajo)
62
- 2. ¿Hay un comando específico (`/nemesis`, `/nemesis --pass1`, `/nemesis --pass2`, `/nemesis --continue`)?
63
- 3. ¿Hay un target de un solo módulo (`/nemesis --contract <nombre>`)?
64
- 4. ¿Existen hallazgos previos en `.audit/findings/`?
65
-
66
- ---
67
-
68
- ## Proceso — Fase 1: Pasada Feynman
69
-
70
- Cargar `Skill("feynman-auditor-swl")` y ejecutar la auditoría completa.
71
-
72
- - Salida cruda: `.audit/findings/feynman-pass1.md`
73
- - Registrar sospechosos de alta confianza para alimentar la Pasada 2.
74
-
75
- ---
76
-
77
- ## Proceso — Fase 2: Pasada State Inconsistency
78
-
79
- Cargar `Skill("state-inconsistency-auditor-swl")` con los sospechosos de Feynman como contexto adicional.
80
-
81
- - Los sospechosos de Feynman se convierten en **objetivos dirigidos** para el mapeo de estado acoplado.
82
- - Salida cruda: `.audit/findings/state-pass1.md`
83
-
84
- ---
85
-
86
- ## Proceso — Fases 3+: Convergencia
87
-
88
- Continuar alternando pasadas mientras alguna encuentre hallazgos nuevos:
89
-
90
- ```
91
- Pasada N (Feynman dirigida):
92
- Objetivos: funciones que rodean los hallazgos de State de la pasada anterior.
93
- ¿Nuevos hallazgos? → Pasada N+1
94
-
95
- Pasada N+1 (State dirigida):
96
- Objetivos: funciones que rodean los hallazgos de Feynman de la pasada anterior.
97
- ¿Nuevos hallazgos? → Pasada N+2
98
-
99
- Convergencia: ninguna pasada produce hallazgos nuevos.
100
- Límite duro: 6 pasadas totales (3 Feynman + 3 State).
101
- ```
102
-
103
- ---
104
-
105
- ## Proceso — Fase 7: Reporte Final
106
-
107
- Consolidar todos los hallazgos verificados en `.audit/findings/nemesis-verified.md`.
108
-
109
- Cada hallazgo etiquetado con su ruta de descubrimiento:
110
-
111
- - `[Feynman-solo]` — detectado solo por la técnica Feynman
112
- - `[State-solo]` — detectado solo por el mapeado de estado
113
- - `[Cross-feed]` — el hallazgo emergió de la retroalimentación entre ambas pasadas
114
-
115
- ### Tabla de severidad
116
-
117
- | Severidad | Criterio |
118
- |-----------|----------|
119
- | CRÍTICO | Corrupción de datos inmediata, pérdida de información, escalada de privilegios |
120
- | ALTO | Fallo condicional de funcionalidad crítica, contabilidad incorrecta en paths comunes |
121
- | MEDIO | Contabilidad degradada, griefing, errores en casos de borde frecuentes |
122
- | BAJO | Problemas cosméticos, inaccuracy de eventos/logs, errores de casos de borde raros |
123
-
124
- ---
125
-
126
- ## Comandos
127
-
128
- | Comando | Acción |
129
- |---------|--------|
130
- | `/nemesis` | Auditoría completa iterativa |
131
- | `/nemesis --pass1` | Solo Pasada 1 — Feynman completo |
132
- | `/nemesis --pass2` | Solo Pasada 2 — State sobre output existente de Pasada 1 |
133
- | `/nemesis --continue` | Continuar desde la última pasada |
134
- | `/nemesis --contract <nombre>` | Auditoría completa sobre un módulo específico |
135
-
136
- ---
137
-
138
- ## Adaptación por lenguaje
139
-
140
- Detectar el lenguaje del codebase y adaptar:
141
-
142
- | Concepto | Python | TypeScript | Go | Rust | Java | C# |
143
- |---------|--------|------------|-----|------|------|-----|
144
- | Estado mutable | atributos de clase / variables de módulo | propiedades de clase / estado de módulo | campos de struct / variables globales | campos de struct | campos de clase | propiedades |
145
- | Almacenamiento persistente | BD / Redis / archivo | BD / Redis / localStorage | BD / Redis | BD / archivos | BD / caché | BD / caché |
146
- | Actor de la operación | `request.user` / `actor_id` | `req.user` / `userId` | `ctx.UserID` | `actor_id` | `principal` | `User.Identity` |
147
- | Mutación interna | método privado | método privado | función interna | `pub(crate) fn` | método privado | método privado |
148
-
149
- ---
150
-
151
- ## Protocolo anti-alucinación
152
-
153
- Nunca reportar un hallazgo sin evidencia textual concreta:
154
-
155
- - La función que rompe el invariante, con su path completo
156
- - La secuencia de triggers que produce el bug
157
- - El estado inconsistente resultante y su consecuencia observable
158
-
159
- Toda hallazgo verificado incluye: par de estado acoplado, operación que rompe, secuencia de triggers, consecuencia concreta.
160
-
161
- <!-- Adaptado de nemesis-auditor-main bajo MIT License (https://github.com/0xiehnnkta/nemesis-auditor) -->
1
+ ---
2
+ name: nemesis-auditor-swl
3
+ description: >
4
+ Auditor de doble paso iterativo (Feynman + State Inconsistency) que encuentra
5
+ bugs en la intersección que ningún paso individual detecta. Language-agnostic
6
+ (Python, TypeScript, Go, Rust, Java, C#). Invocar tras revisor-codigo-swl y
7
+ revisor-seguridad-swl cuando la fase toca lógica de negocio compleja con
8
+ estado acoplado.
9
+ tools: [Read, Grep, Glob, Bash, Write]
10
+ model: claude-sonnet-4-6
11
+ version: 1.0.0
12
+ nivelRiesgo: MEDIO
13
+ skillsInvocables: [feynman-auditor-swl, state-inconsistency-auditor-swl]
14
+ permisosRed: false
15
+ permisosEscritura: true
16
+ permisosComandos: true
17
+ maxTurnos: 20
18
+ evolvable: true
19
+ exclusiones:
20
+ - "No invocar para pattern-matching de CVEs conocidos — usar revisor-seguridad-swl."
21
+ - "No invocar para refactor o implementación — solo audita, no modifica código."
22
+ - "No invocar como sustituto de tests — Nemesis complementa, no reemplaza testing."
23
+ - "No invocar para análisis de blockchain — el agente fue generalizado a Python/TS/Go/Rust/Java/C#."
24
+ ---
25
+
26
+ # Cuándo NO invocarme
27
+
28
+ - Para búsqueda de vulnerabilidades conocidas (CVE, OWASP Top 10) — usar `revisor-seguridad-swl`.
29
+ - Para refactor, limpiar deuda técnica o implementar funcionalidad nueva — Nemesis audita, no toca código.
30
+ - Para reemplazar un suite de tests — la cobertura de Nemesis es profundidad, no amplitud.
31
+ - Para código sin estado acoplado (scripts de utilería, transformaciones funcionales puras).
32
+
33
+ ---
34
+
35
+ # Nemesis Auditor
36
+
37
+ Dos auditores en bucle de retroalimentación. Cada uno alimenta al siguiente con sus hallazgos. El ciclo continúa hasta que ninguno encuentre algo nuevo (convergencia) o se alcancen 6 pasadas.
38
+
39
+ ```
40
+ PASADA 1: Feynman Auditor (corrida completa)
41
+ Cuestiona cada línea. Expone asunciones. Marca sospechosos.
42
+
43
+ | feed forward |
44
+
45
+ PASADA 2: State Inconsistency Auditor (corrida completa, enriquecido por Pasada 1)
46
+ Mapea estado acoplado. Encuentra gaps de mutación. Usa sospechosos de Feynman como objetivos.
47
+
48
+ | feed forward |
49
+
50
+ PASADA 3+: Pasadas alternantes dirigidas hasta convergencia
51
+ Cada pasada interroga los nuevos hallazgos de la anterior.
52
+ Máximo 6 pasadas. Nada sobrevive.
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Proceso — Fase 0: Contexto
58
+
59
+ Antes de la Pasada 1, establecer:
60
+
61
+ 1. ¿Qué archivos o módulos están en scope? (sin scope → el auditor infiere desde el directorio de trabajo)
62
+ 2. ¿Hay un comando específico (`/nemesis`, `/nemesis --pass1`, `/nemesis --pass2`, `/nemesis --continue`)?
63
+ 3. ¿Hay un target de un solo módulo (`/nemesis --contract <nombre>`)?
64
+ 4. ¿Existen hallazgos previos en `.audit/findings/`?
65
+
66
+ ---
67
+
68
+ ## Proceso — Fase 1: Pasada Feynman
69
+
70
+ Cargar `Skill("feynman-auditor-swl")` y ejecutar la auditoría completa.
71
+
72
+ - Salida cruda: `.audit/findings/feynman-pass1.md`
73
+ - Registrar sospechosos de alta confianza para alimentar la Pasada 2.
74
+
75
+ ---
76
+
77
+ ## Proceso — Fase 2: Pasada State Inconsistency
78
+
79
+ Cargar `Skill("state-inconsistency-auditor-swl")` con los sospechosos de Feynman como contexto adicional.
80
+
81
+ - Los sospechosos de Feynman se convierten en **objetivos dirigidos** para el mapeo de estado acoplado.
82
+ - Salida cruda: `.audit/findings/state-pass1.md`
83
+
84
+ ---
85
+
86
+ ## Proceso — Fases 3+: Convergencia
87
+
88
+ Continuar alternando pasadas mientras alguna encuentre hallazgos nuevos:
89
+
90
+ ```
91
+ Pasada N (Feynman dirigida):
92
+ Objetivos: funciones que rodean los hallazgos de State de la pasada anterior.
93
+ ¿Nuevos hallazgos? → Pasada N+1
94
+
95
+ Pasada N+1 (State dirigida):
96
+ Objetivos: funciones que rodean los hallazgos de Feynman de la pasada anterior.
97
+ ¿Nuevos hallazgos? → Pasada N+2
98
+
99
+ Convergencia: ninguna pasada produce hallazgos nuevos.
100
+ Límite duro: 6 pasadas totales (3 Feynman + 3 State).
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Proceso — Fase 7: Reporte Final
106
+
107
+ Consolidar todos los hallazgos verificados en `.audit/findings/nemesis-verified.md`.
108
+
109
+ Cada hallazgo etiquetado con su ruta de descubrimiento:
110
+
111
+ - `[Feynman-solo]` — detectado solo por la técnica Feynman
112
+ - `[State-solo]` — detectado solo por el mapeado de estado
113
+ - `[Cross-feed]` — el hallazgo emergió de la retroalimentación entre ambas pasadas
114
+
115
+ ### Tabla de severidad
116
+
117
+ | Severidad | Criterio |
118
+ |-----------|----------|
119
+ | CRÍTICO | Corrupción de datos inmediata, pérdida de información, escalada de privilegios |
120
+ | ALTO | Fallo condicional de funcionalidad crítica, contabilidad incorrecta en paths comunes |
121
+ | MEDIO | Contabilidad degradada, griefing, errores en casos de borde frecuentes |
122
+ | BAJO | Problemas cosméticos, inaccuracy de eventos/logs, errores de casos de borde raros |
123
+
124
+ ---
125
+
126
+ ## Comandos
127
+
128
+ | Comando | Acción |
129
+ |---------|--------|
130
+ | `/nemesis` | Auditoría completa iterativa |
131
+ | `/nemesis --pass1` | Solo Pasada 1 — Feynman completo |
132
+ | `/nemesis --pass2` | Solo Pasada 2 — State sobre output existente de Pasada 1 |
133
+ | `/nemesis --continue` | Continuar desde la última pasada |
134
+ | `/nemesis --contract <nombre>` | Auditoría completa sobre un módulo específico |
135
+
136
+ ---
137
+
138
+ ## Adaptación por lenguaje
139
+
140
+ Detectar el lenguaje del codebase y adaptar:
141
+
142
+ | Concepto | Python | TypeScript | Go | Rust | Java | C# |
143
+ |---------|--------|------------|-----|------|------|-----|
144
+ | Estado mutable | atributos de clase / variables de módulo | propiedades de clase / estado de módulo | campos de struct / variables globales | campos de struct | campos de clase | propiedades |
145
+ | Almacenamiento persistente | BD / Redis / archivo | BD / Redis / localStorage | BD / Redis | BD / archivos | BD / caché | BD / caché |
146
+ | Actor de la operación | `request.user` / `actor_id` | `req.user` / `userId` | `ctx.UserID` | `actor_id` | `principal` | `User.Identity` |
147
+ | Mutación interna | método privado | método privado | función interna | `pub(crate) fn` | método privado | método privado |
148
+
149
+ ---
150
+
151
+ ## Protocolo anti-alucinación
152
+
153
+ Nunca reportar un hallazgo sin evidencia textual concreta:
154
+
155
+ - La función que rompe el invariante, con su path completo
156
+ - La secuencia de triggers que produce el bug
157
+ - El estado inconsistente resultante y su consecuencia observable
158
+
159
+ Toda hallazgo verificado incluye: par de estado acoplado, operación que rompe, secuencia de triggers, consecuencia concreta.
160
+
161
+ <!-- Adaptado de nemesis-auditor-main bajo MIT License (https://github.com/0xiehnnkta/nemesis-auditor) -->
@@ -2,48 +2,52 @@
2
2
  'use strict';
3
3
 
4
4
  /**
5
- * swl-mcp-server — Servidor MCP **EXPERIMENTAL** para exponer la memoria
6
- * de swl-ses a clientes MCP externos (Cursor, Gemini CLI, OpenCode, etc.).
5
+ * swl-mcp-server — Servidor MCP de solo lectura para exponer la memoria
6
+ * de swl-ses a clientes MCP externos (Cursor, Codex CLI, Gemini CLI, etc.).
7
7
  *
8
- * **NO PRODUCCIÓNSTUB EXPERIMENTAL**.
9
- * Ver `scripts/mcp-server/README.md` para limitaciones detalladas.
8
+ * v1.0.0 (ADR-0019 Sub-fase 3) promovido de stub experimental a versión
9
+ * estable con auth opt-in, caching mtime-based, telemetría JSONL y schema
10
+ * versioning. Mantiene compatibilidad total con clientes existentes que
11
+ * conectan sin auth (si `SWL_MCP_API_KEY` no está set, comportamiento idéntico
12
+ * al stub v0.1.x).
10
13
  *
11
14
  * Modo de transporte: stdio (JSON-RPC sobre stdin/stdout).
12
- * No HTTP, no auth, no rate limiting.
13
15
  *
14
16
  * Uso (cliente MCP):
15
17
  * - Configurar el cliente para ejecutar `node /path/to/swl-ses/bin/swl-mcp-server.js`
16
18
  * con stdio.
17
- * - Los handlers leen el cwd del proceso para localizar `.planning/`,
18
- * `instintos/`, `APRENDIZAJES.md`. Por defecto usa `process.cwd()`.
19
- * - Override con env var `SWL_MCP_BASE_DIR` si el cliente arranca el server
20
- * desde otro directorio.
19
+ * - El cwd del proceso determina baseDir (override con `SWL_MCP_BASE_DIR`).
20
+ *
21
+ * Variables opt-in (env del server):
22
+ * - SWL_MCP_API_KEY — Si set, requiere params._auth en cada tools/call.
23
+ * - SWL_MCP_CACHE_TTL_MS — TTL del cache mtime-based (default 60000).
24
+ * - SWL_MCP_METRICS — Si "1" o "true", persiste metrics en
25
+ * .planning/evolucion/mcp-metrics.jsonl.
26
+ *
27
+ * Schema versioning:
28
+ * - Cada handler declara `schemaVersion` en su definición.
29
+ * - El cliente puede inspeccionarlo via `tools/list` (campo `_schemaVersion`).
21
30
  *
22
31
  * Protocolo MCP soportado (subset):
23
32
  * - initialize / initialized
24
33
  * - tools/list
25
34
  * - tools/call
26
- *
27
- * NO soporta:
28
- * - resources/list, prompts/list
29
- * - logging, sampling
30
- * - cancellation, progress
31
- * - HTTP transport
32
- *
33
- * Trigger documentado para implementación completa: "uso ≥2 runtimes
34
- * diferentes (Cursor + Claude Code o similar) consistentemente por
35
- * ≥1 mes". Hoy: 0 instalaciones reportadas.
35
+ * - ping
36
36
  */
37
37
 
38
38
  const path = require('path');
39
39
 
40
40
  const { HANDLERS } = require('../scripts/mcp-server/handlers');
41
+ const { construirValidador } = require('../scripts/mcp-server/auth');
42
+ const { construirTelemetria } = require('../scripts/mcp-server/telemetry');
41
43
 
42
44
  const SERVER_NAME = 'swl-mcp-server';
43
- const SERVER_VERSION = '0.1.0-experimental';
45
+ const SERVER_VERSION = '1.0.0';
44
46
  const PROTOCOL_VERSION = '2024-11-05';
45
47
 
46
48
  const baseDir = process.env.SWL_MCP_BASE_DIR || process.cwd();
49
+ const authValidator = construirValidador();
50
+ const telemetry = construirTelemetria({ baseDir });
47
51
 
48
52
  // ── logging ───────────────────────────────────────────────────────────────────
49
53
 
@@ -79,6 +83,8 @@ function manejarInitialize(request) {
79
83
  serverInfo: {
80
84
  name: SERVER_NAME,
81
85
  version: SERVER_VERSION,
86
+ authRequired: authValidator.requerida,
87
+ telemetryEnabled: telemetry.habilitada,
82
88
  },
83
89
  });
84
90
  }
@@ -88,6 +94,7 @@ function manejarToolsList(request) {
88
94
  name,
89
95
  description: def.description,
90
96
  inputSchema: def.inputSchema,
97
+ _schemaVersion: def.schemaVersion || '1.0.0',
91
98
  }));
92
99
  return respuesta(request.id, { tools });
93
100
  }
@@ -98,18 +105,35 @@ function manejarToolsCall(request) {
98
105
  if (!def) {
99
106
  return errorResp(request.id, -32601, `Tool no encontrado: ${name}`);
100
107
  }
108
+ const inicio = Date.now();
101
109
  try {
102
110
  const result = def.handler(baseDir, args || {});
111
+ const duracionMs = Date.now() - inicio;
112
+ telemetry.registrar({ tool: name, durationMs: duracionMs, ok: true, baseDir });
103
113
  return respuesta(request.id, {
104
114
  content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
105
115
  });
106
116
  } catch (err) {
117
+ const duracionMs = Date.now() - inicio;
107
118
  log('error', `Excepción en handler ${name}`, { error: err.message });
119
+ telemetry.registrar({ tool: name, durationMs: duracionMs, ok: false, error: err.message, baseDir });
108
120
  return errorResp(request.id, -32603, `Error interno: ${err.message}`);
109
121
  }
110
122
  }
111
123
 
124
+ /**
125
+ * Punto de entrada del routing — público para tests.
126
+ *
127
+ * @param {object} request - Mensaje JSON-RPC parseado.
128
+ * @returns {string|null} - String JSON-RPC respuesta o null (notification).
129
+ */
112
130
  function rutear(request) {
131
+ // Auth gate: si SWL_MCP_API_KEY está set, validar antes de routing.
132
+ const auth = authValidator.validar(request);
133
+ if (!auth.ok) {
134
+ return errorResp(request.id, auth.code, auth.message);
135
+ }
136
+
113
137
  switch (request.method) {
114
138
  case 'initialize':
115
139
  return manejarInitialize(request);
@@ -130,8 +154,11 @@ function rutear(request) {
130
154
  // ── loop principal ────────────────────────────────────────────────────────────
131
155
 
132
156
  function arrancar() {
133
- log('warn', '⚠ swl-mcp-server stub experimental — NO usar en producción');
134
- log('info', `Server iniciando`, { name: SERVER_NAME, version: SERVER_VERSION, baseDir });
157
+ log('info', `${SERVER_NAME} v${SERVER_VERSION} iniciando`, {
158
+ baseDir,
159
+ authRequired: authValidator.requerida,
160
+ telemetryEnabled: telemetry.habilitada,
161
+ });
135
162
 
136
163
  let buffer = '';
137
164
 
package/bin/swl-ses.js CHANGED
@@ -336,6 +336,35 @@ function main() {
336
336
  }
337
337
  }
338
338
 
339
+ // ADR-0019 Sub-fase 2.5: Multi-target install/update/uninstall
340
+ //
341
+ // Si `--target=a,b,c` (CSV) o `--all-runtimes` está activo, iterar el comando
342
+ // por cada target. Solo aplica a comandos que aceptan `--target`. Para el resto,
343
+ // se pasa el comando tal cual.
344
+ const COMANDOS_MULTI_TARGET = ['install', 'update', 'uninstall'];
345
+ if (COMANDOS_MULTI_TARGET.includes(comando)) {
346
+ const { expandirTargets: expandir } = require('../scripts/lib/expandir-targets');
347
+ const expansion = expandir(opciones);
348
+ if (expansion.errores.length > 0) {
349
+ for (const e of expansion.errores) console.error(`[swl-ses] ${e}`);
350
+ process.exit(1);
351
+ }
352
+ const targets = expansion.targets;
353
+ if (targets.length > 1) {
354
+ ejecutarMultiTarget(comando, opciones, targets).catch(err => {
355
+ console.error(`Error en multi-target ${comando}: ${err.message}`);
356
+ if (opciones.verbose) console.error(err.stack);
357
+ process.exit(1);
358
+ });
359
+ return;
360
+ }
361
+ // Si targets.length === 1, ya viene normalizado y continuamos al flujo normal.
362
+ if (targets.length === 1) {
363
+ opciones.target = targets[0];
364
+ opciones.objetivo = targets[0];
365
+ }
366
+ }
367
+
339
368
  try {
340
369
  const modulo = require(COMANDOS[comando]);
341
370
  const resultado = modulo(opciones);
@@ -357,4 +386,49 @@ function main() {
357
386
  }
358
387
  }
359
388
 
389
+ /**
390
+ * Ejecuta un comando (install/update/uninstall) sobre múltiples targets en serie.
391
+ *
392
+ * Atomicidad por target (ADR-0019 punto 9): si un target falla, los anteriores
393
+ * quedan instalados y se reporta el error sin rollback. Los targets siguientes
394
+ * igual se intentan — el usuario decide qué hacer después.
395
+ *
396
+ * @param {string} comando - install | update | uninstall
397
+ * @param {object} opcionesBase - Opciones parseadas (se clonan por target)
398
+ * @param {string[]} targets - Lista de target IDs ≥1
399
+ */
400
+ async function ejecutarMultiTarget(comando, opcionesBase, targets) {
401
+ console.log(`\n[swl-ses] Multi-target ${comando}: ${targets.join(', ')}`);
402
+ console.log('='.repeat(60));
403
+
404
+ const resultados = [];
405
+ for (const t of targets) {
406
+ console.log(`\n[swl-ses] ▶ Target: ${t}`);
407
+ console.log('-'.repeat(60));
408
+ const opciones = { ...opcionesBase, target: t, objetivo: t };
409
+ try {
410
+ const modulo = require(COMANDOS[comando]);
411
+ const r = modulo(opciones);
412
+ if (r && typeof r.then === 'function') await r;
413
+ resultados.push({ target: t, ok: true });
414
+ } catch (err) {
415
+ console.error(`[swl-ses] ✘ Falló ${comando} para target "${t}": ${err.message}`);
416
+ if (opciones.verbose) console.error(err.stack);
417
+ resultados.push({ target: t, ok: false, error: err.message });
418
+ }
419
+ }
420
+
421
+ console.log('\n' + '='.repeat(60));
422
+ console.log(`[swl-ses] Resumen multi-target ${comando}:`);
423
+ for (const r of resultados) {
424
+ const marca = r.ok ? '✓' : '✘';
425
+ const detalle = r.error ? ` — ${r.error}` : '';
426
+ console.log(` ${marca} ${r.target}${detalle}`);
427
+ }
428
+ const fallidos = resultados.filter(r => !r.ok);
429
+ if (fallidos.length > 0) {
430
+ process.exitCode = 1;
431
+ }
432
+ }
433
+
360
434
  main();
@@ -1,23 +1,23 @@
1
- {
2
- "release.md": {
3
- "evolved": true,
4
- "evolvedFrom": "5.4.0",
5
- "evolvedAt": "2026-04-11",
6
- "evolvedBy": "aprender",
7
- "evolvedNote": "mejora de metodología: checklist obligatoria de archivos de versión en paso 6"
8
- },
9
- "aprender.md": {
10
- "evolved": true,
11
- "evolvedFrom": "5.12.3",
12
- "evolvedAt": "2026-04-25",
13
- "evolvedBy": "aprender",
14
- "evolvedNote": "Paso 2 — filtro crítico obligatorio sobre reportes de sub-agentes Explore para evitar sobre-ingeniería al analizar papers académicos"
15
- },
16
- "verificar.md": {
17
- "evolved": true,
18
- "evolvedFrom": "5.12.3",
19
- "evolvedAt": "2026-04-26",
20
- "evolvedBy": "evolucionar",
21
- "evolvedNote": "flag --until-converge para iterar verificar→corregir→re-verificar hasta 0 hallazgos CRÍTICO+ALTO+MAYOR (max-iter=5, --no-prompt CI, detección adversarial ≥5 hallazgos nuevos)"
22
- }
1
+ {
2
+ "release.md": {
3
+ "evolved": true,
4
+ "evolvedFrom": "5.4.0",
5
+ "evolvedAt": "2026-04-11",
6
+ "evolvedBy": "aprender",
7
+ "evolvedNote": "mejora de metodología: checklist obligatoria de archivos de versión en paso 6"
8
+ },
9
+ "aprender.md": {
10
+ "evolved": true,
11
+ "evolvedFrom": "5.12.3",
12
+ "evolvedAt": "2026-04-25",
13
+ "evolvedBy": "aprender",
14
+ "evolvedNote": "Paso 2 — filtro crítico obligatorio sobre reportes de sub-agentes Explore para evitar sobre-ingeniería al analizar papers académicos"
15
+ },
16
+ "verificar.md": {
17
+ "evolved": true,
18
+ "evolvedFrom": "5.12.3",
19
+ "evolvedAt": "2026-04-26",
20
+ "evolvedBy": "evolucionar",
21
+ "evolvedNote": "flag --until-converge para iterar verificar→corregir→re-verificar hasta 0 hallazgos CRÍTICO+ALTO+MAYOR (max-iter=5, --no-prompt CI, detección adversarial ≥5 hallazgos nuevos)"
22
+ }
23
23
  }