@saulwade/swl-ses 1.3.4 → 1.3.7

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 (110) hide show
  1. package/CLAUDE.md +2 -2
  2. package/README.md +34 -34
  3. package/bin/swl-mcp-server.js +187 -187
  4. package/bin/swl-ses.js +4 -62
  5. package/comandos/swl/.evolved.json +22 -22
  6. package/comandos/swl/adoptar-proyecto.md +207 -207
  7. package/comandos/swl/contribuir.md +233 -233
  8. package/habilidades/backend-production-resilience/SKILL.md +288 -288
  9. package/habilidades/benchmark-memoria/SKILL.md +186 -186
  10. package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
  11. package/habilidades/doubt-driven-review/SKILL.md +171 -171
  12. package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
  13. package/habilidades/eval-framework/SKILL.md +212 -212
  14. package/habilidades/extractor-de-aprendizajes/SKILL.md +321 -321
  15. package/habilidades/harness-claude-code/SKILL.md +299 -299
  16. package/habilidades/infra-github-actions/SKILL.md +166 -166
  17. package/habilidades/legacy-code-rescue/SKILL.md +267 -267
  18. package/habilidades/manejo-errores/.evolved.json +8 -8
  19. package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
  20. package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -163
  21. package/habilidades/patrones-python/SKILL.md +229 -229
  22. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
  23. package/habilidades/planear-fase/SKILL.md +319 -319
  24. package/habilidades/release-semver/.evolved.json +8 -8
  25. package/habilidades/swl-claudemd/SKILL.md +220 -220
  26. package/habilidades/testing-python/SKILL.md +340 -340
  27. package/hooks/claudemd-bloat-detector.js +161 -161
  28. package/hooks/extraccion-aprendizajes.js +19 -12
  29. package/hooks/lib/agent-routing.js +107 -107
  30. package/hooks/lib/auto-consolidator.js +335 -335
  31. package/hooks/lib/error-classifier.js +308 -308
  32. package/hooks/lib/merkle-audit.js +96 -96
  33. package/hooks/lib/provenance-tracker.js +191 -191
  34. package/hooks/lib/rate-limit-tracker.js +253 -253
  35. package/hooks/lib/resource-quota.js +122 -122
  36. package/hooks/lib/retry-jitter.js +165 -165
  37. package/hooks/lib/skill-auditor.js +588 -588
  38. package/hooks/lib/sync-status.js +228 -228
  39. package/hooks/lib/taint-tracker.js +107 -107
  40. package/hooks/lib/text-similarity.js +241 -241
  41. package/hooks/lib/toon-compressor.js +245 -245
  42. package/hooks/registro-turnos.js +209 -209
  43. package/hooks/sugerir-regenerar-inventario.js +170 -170
  44. package/hooks/validar-formato-post-subagente.js +140 -140
  45. package/hooks/validar-memoria-hook.js +218 -218
  46. package/instintos/prompt-appendices.yaml +57 -57
  47. package/manifiestos/agent-output-schemas.json +57 -57
  48. package/manifiestos/skills-lock.json +1093 -1093
  49. package/package.json +1 -1
  50. package/plantillas/auditor-veto-template.md +105 -105
  51. package/plantillas/github-workflows/README.md +47 -47
  52. package/plantillas/github-workflows/release-please.yml +44 -44
  53. package/plantillas/github-workflows/swl-ci.yml +107 -107
  54. package/plantillas/github-workflows/swl-security.yml +51 -51
  55. package/plugin.json +1 -1
  56. package/reglas/analisis-previo-tareas-grandes.md +172 -172
  57. package/reglas/arreglar-al-detectar.md +147 -147
  58. package/reglas/fragmentos-compartidos.md +152 -152
  59. package/reglas/harness-claude-code.md +213 -213
  60. package/reglas/usar-context7.md +226 -226
  61. package/schemas/diary-entry.schema.json +80 -80
  62. package/scripts/benchmark-memoria.js +167 -167
  63. package/scripts/comandos/info.js +1 -1
  64. package/scripts/configurar-branch-protection.js +418 -418
  65. package/scripts/detectar-aprendizajes-duplicados.js +151 -151
  66. package/scripts/doctor.js +77 -3
  67. package/scripts/field-report.js +199 -199
  68. package/scripts/generar-checklists-consolidados.js +273 -273
  69. package/scripts/generar-inventario.js +420 -420
  70. package/scripts/generar-matriz-lenguajes.js +271 -271
  71. package/scripts/inicializar.js +2 -2
  72. package/scripts/instalador.js +40 -3
  73. package/scripts/instalar-git-hook.js +2 -2
  74. package/scripts/lib/artefactos-python.js +43 -43
  75. package/scripts/lib/benchmark-metrics.js +160 -160
  76. package/scripts/lib/budget-enforcer.js +252 -252
  77. package/scripts/lib/configurar-ci.js +380 -380
  78. package/scripts/lib/contadores-inventario.js +217 -217
  79. package/scripts/lib/detectar-stack-detallado.js +307 -307
  80. package/scripts/lib/diary-entry.js +234 -234
  81. package/scripts/lib/eval-metrics-store.js +218 -218
  82. package/scripts/lib/eval-quality.js +171 -171
  83. package/scripts/lib/eval-schemas.js +144 -144
  84. package/scripts/lib/eval-self-correct.js +106 -106
  85. package/scripts/lib/eval-validator.js +185 -185
  86. package/scripts/lib/gitignore-manifest.js +1 -1
  87. package/scripts/lib/jaccard-similarity.js +98 -98
  88. package/scripts/lib/longmemeval-runner.js +125 -125
  89. package/scripts/lib/npm-version.js +261 -261
  90. package/scripts/lib/paquetes-conocidos.js +50 -50
  91. package/scripts/lib/parsear-opciones.js +136 -0
  92. package/scripts/lib/prompt-builder.js +264 -264
  93. package/scripts/lib/rrf-fusion.js +175 -175
  94. package/scripts/lib/scoring-instintos.js +277 -277
  95. package/scripts/lib/semantic-search.js +252 -252
  96. package/scripts/lib/transformadores/claude.js +200 -200
  97. package/scripts/lib/transformadores/codex.js +1 -1
  98. package/scripts/lib/transformadores/copilot.js +1 -1
  99. package/scripts/lib/transformadores/gemini.js +1 -1
  100. package/scripts/lib/transformadores/opencode.js +1 -1
  101. package/scripts/limpiar-artefactos-python.js +131 -131
  102. package/scripts/mcp-server/README.md +128 -128
  103. package/scripts/mcp-server/handlers.js +206 -206
  104. package/scripts/migrar-csv-a-array.js +168 -168
  105. package/scripts/migrar-fase-dominio.js +201 -201
  106. package/scripts/publicar.js +511 -511
  107. package/scripts/run-eval.js +141 -141
  108. package/scripts/validar-manifest.js +195 -195
  109. package/scripts/validar-userland-vacio.js +110 -110
  110. package/scripts/verificar-release.js +5 -1
@@ -1,321 +1,321 @@
1
- ---
2
- name: extractor-de-aprendizajes
3
- description: Convertir errores y patrones descubiertos durante la implementación en nuevas habilidades o reglas. Ciclo de mejora continua del sistema SWL.
4
- version: "1.0.3"
5
- herramientasPermitidas: [Read]
6
- exclusiones:
7
- - "No cargar para actualizar el perfil del usuario — las correcciones explícitas del usuario van a `instintos/perfil-usuario.yaml` vía `perfilador-usuario-swl`, no a APRENDIZAJES.md."
8
- - "No cargar para buscar aprendizajes ya documentados; usar `memoria-busqueda` que hace búsqueda eficiente sin cargar el archivo completo."
9
- - "No cargar para crear un skill nuevo desde cero de forma interactiva; usar `/swl:crear-skill` que guía el proceso con validaciones."
10
- - "No cargar si el aprendizaje no tiene causa raíz identificada — documentar síntoma sin causa produce reglas que no previenen el error real."
11
- evolvable: true # default para skill estandar
12
- evolved: true
13
- evolved-from: "1.1.1"
14
- evolved-at: "2026-05-02"
15
- evolved-by: "aprender"
16
- evolved-note: "Extender gotcha Explore (papers → papers+repos) tras confirmación x4 — sync desde skill global"
17
- ---
18
- # Extractor de Aprendizajes
19
-
20
- ## Propósito
21
-
22
- Cada error cometido durante la implementación, cada bug inesperado, cada patrón que
23
- funcionó mejor de lo esperado, es una oportunidad de mejorar el sistema. Este skill
24
- define el proceso para convertir experiencia concreta en conocimiento estructurado
25
- que previene errores futuros.
26
-
27
- ---
28
-
29
- ## El ciclo de mejora continua
30
-
31
- ```
32
- Implementación
33
-
34
- Error / Insight descubierto
35
-
36
- Clasificar: ¿es un anti-patrón, un patrón nuevo, o una regla de proyecto?
37
-
38
- Documentar en la estructura correcta
39
-
40
- El verificador lo usa en la siguiente iteración
41
-
42
- Errores prevenidos en el futuro
43
- ```
44
-
45
- ---
46
-
47
- ## Tipos de aprendizajes
48
-
49
- ### Tipo 1: Anti-patrón (error a prevenir)
50
-
51
- Se descubrió algo que parece correcto pero falla en producción o en testing.
52
- Debe convertirse en una **regla negativa** ("NUNCA hagas X").
53
-
54
- **Indicadores**:
55
- - Un test falló por una razón no obvia.
56
- - Un bug tardó más de 30 minutos en diagnosticarse.
57
- - Se asumió algo sobre una librería que resultó ser incorrecto.
58
-
59
- ### Tipo 2: Patrón positivo (mejor práctica)
60
-
61
- Se encontró una forma de hacer algo que resuelve un problema recurrente con
62
- elegancia. Debe convertirse en una **regla positiva** ("SIEMPRE usa X para Y").
63
-
64
- **Indicadores**:
65
- - Se refactorizó código que inicialmente era verboso y quedó mucho más limpio.
66
- - Una solución resolvió 3 problemas distintos a la vez.
67
- - El code review elogió específicamente un patrón usado.
68
-
69
- ### Tipo 3: Gotcha de librería o framework
70
-
71
- El comportamiento de una dependencia no era el esperado según la documentación o
72
- la intuición. Debe convertirse en una **nota de advertencia** en el skill relevante.
73
-
74
- **Indicadores**:
75
- - "La documentación dice X pero en realidad hace Y".
76
- - El comportamiento cambia según la versión de la dependencia.
77
- - Hay una edge case no documentada.
78
-
79
- ### Tipo 4: Decisión de proyecto
80
-
81
- Se tomó una decisión de arquitectura o diseño que debe respetarse en el futuro.
82
- Debe registrarse en **DECISIONS.md** del proyecto.
83
-
84
- ---
85
-
86
- ## Protocolo de extracción
87
-
88
- ### Paso 1: Capturar el contexto del error
89
-
90
- Cuando se descubre un error o insight, documentarlo inmediatamente con:
91
-
92
- ```markdown
93
- ## Aprendizaje: [título corto]
94
-
95
- **Fecha**: 2026-03-25
96
- **Contexto**: Implementando endpoint POST /facturas en FastAPI con SQLAlchemy async.
97
- **Error observado**: MissingGreenlet al acceder a factura.usuario.nombre en el schema Pydantic.
98
- **Causa raíz**: La relación `usuario` no tenía selectinload() en el query. SQLAlchemy async
99
- no puede hacer lazy loading fuera de una sesión async activa.
100
- **Solución aplicada**: Agregar `.options(selectinload(Factura.usuario))` al query.
101
- **Clasificación**: Anti-patrón → Gotcha de SQLAlchemy async
102
- ```
103
-
104
- ### Paso 2: Determinar el destino del aprendizaje
105
-
106
- | Tipo de aprendizaje | Destino |
107
- |--------------------|---------|
108
- | Regla universal de Python | `habilidades/patrones-python/SKILL.md` |
109
- | Gotcha de FastAPI | `habilidades/fastapi-experto/SKILL.md` |
110
- | Gotcha de SQLAlchemy | `habilidades/fastapi-experto/SKILL.md` o `CLAUDE.md` del proyecto |
111
- | Regla de diseño de API | `habilidades/api-rest-diseno/SKILL.md` |
112
- | Regla de testing | `habilidades/testing-python/SKILL.md` |
113
- | Decisión de proyecto específico | `DECISIONS.md` del proyecto |
114
- | Regla que aplica a TODOS los proyectos | `CLAUDE.md` del sistema SWL |
115
-
116
- ### Paso 3: Escribir la regla en el formato correcto
117
-
118
- #### Formato para regla negativa (anti-patrón)
119
-
120
- ```markdown
121
- ### NUNCA: [título del anti-patrón]
122
-
123
- **Problema**: Descripción clara de qué falla y por qué.
124
-
125
- ```python
126
- # MAL — esto causa [error específico]
127
- query = select(Factura).where(Factura.id == factura_id)
128
- result = await db.execute(query)
129
- factura = result.scalar_one()
130
- # Acceder a factura.usuario aquí causa MissingGreenlet
131
- print(factura.usuario.nombre)
132
- ```
133
-
134
- ```python
135
- # BIEN — con selectinload explícito
136
- query = (
137
- select(Factura)
138
- .where(Factura.id == factura_id)
139
- .options(selectinload(Factura.usuario))
140
- )
141
- result = await db.execute(query)
142
- factura = result.scalar_one()
143
- print(factura.usuario.nombre) # Funciona correctamente
144
- ```
145
- ```
146
-
147
- #### Formato para regla positiva (mejor práctica)
148
-
149
- ```markdown
150
- ### SIEMPRE: [título de la mejor práctica]
151
-
152
- **Cuándo aplicar**: Descripción de la situación.
153
- **Beneficio**: Por qué esta forma es mejor.
154
-
155
- ```python
156
- # Patrón correcto con ejemplo concreto
157
- ```
158
- ```
159
-
160
- ### Paso 4: Integrar la regla al skill correspondiente
161
-
162
- 1. Abrir el SKILL.md del skill donde debe vivir la regla.
163
- 2. Agregar la regla en la sección más relevante.
164
- 3. Si no hay sección relevante, crear una nueva sección "Gotchas y casos especiales".
165
- 4. Hacer commit del cambio al skill con mensaje:
166
- ```
167
- docs(skills): agrega regla sobre selectinload en SQLAlchemy async
168
- ```
169
-
170
- ---
171
-
172
- ## Plantilla de nuevo skill desde cero
173
-
174
- Si el aprendizaje no encaja en ningún skill existente, crear uno nuevo:
175
-
176
- ```
177
- habilidades/
178
- └── nuevo-skill/
179
- └── SKILL.md
180
- ```
181
-
182
- ```yaml
183
- ---
184
- name: nuevo-skill
185
- description: Una línea describiendo cuándo activar este skill.
186
- ---
187
-
188
- # Título del Skill
189
-
190
- ## Cuándo activar
191
- - Caso 1 donde este skill es relevante
192
- - Caso 2 donde este skill es relevante
193
-
194
- ## Reglas fundamentales
195
-
196
- ### Regla 1
197
- ...
198
-
199
- ### Regla 2
200
- ...
201
-
202
- ## Anti-patrones
203
-
204
- ### NUNCA: Anti-patrón 1
205
- ...
206
-
207
- ## Referencia rápida
208
- ...
209
- ```
210
-
211
- ---
212
-
213
- ## Indicadores de calidad de un aprendizaje bien documentado
214
-
215
- Un aprendizaje está bien documentado si:
216
-
217
- - [ ] Tiene un ejemplo de código concreto (MAL vs. BIEN).
218
- - [ ] La causa raíz está explicada, no solo el síntoma.
219
- - [ ] Es accionable: quien lo lee sabe exactamente qué hacer o no hacer.
220
- - [ ] Está en el skill correcto (no en un lugar genérico).
221
- - [ ] El título es buscable (contiene la tecnología y el patrón).
222
-
223
- ---
224
-
225
- ## Frecuencia de extracción
226
-
227
- | Momento | Acción |
228
- |---------|--------|
229
- | Al terminar una tarea | Revisar si hubo algún insight que documentar |
230
- | Al resolver un bug difícil | OBLIGATORIO documentar causa raíz y solución |
231
- | Al hacer code review | Documentar patrones observados |
232
- | Al finalizar una fase | Revisar ESTADO.md y DECISIONS.md, promover aprendizajes relevantes |
233
- | Al finalizar el proyecto | Revisar todos los aprendizajes y consolidarlos en los skills |
234
-
235
- ---
236
-
237
- ## Vigencia temporal de aprendizajes (patrón Zep)
238
-
239
- Cada aprendizaje debe llevar timestamps de vigencia para evitar acumular
240
- conocimiento obsoleto:
241
-
242
- ```markdown
243
- ## Aprendizaje: [título]
244
-
245
- **Fecha**: 2026-04-15
246
- **valid_at**: 2026-04-15 <!-- Cuándo empezó a ser válido -->
247
- **invalid_at**: null <!-- null = vigente actualmente -->
248
- **rating**: HIGH | MEDIUM | LOW <!-- Impacto del aprendizaje -->
249
- **Contexto**: ...
250
- **Solución**: ...
251
- ```
252
-
253
- ### Reglas de vigencia
254
-
255
- - `valid_at` es obligatorio — siempre poner la fecha de descubrimiento
256
- - `invalid_at = null` → el aprendizaje sigue vigente
257
- - Cuando un aprendizaje queda obsoleto (ej: se actualizó la librería), marcar `invalid_at`
258
- - Al consultar aprendizajes, por defecto solo mostrar los vigentes (`invalid_at = null`)
259
- - Nunca borrar aprendizajes obsoletos — solo marcarlos para preservar el historial
260
-
261
- ### Clasificación automática por impacto (fact rating)
262
-
263
- | Rating | Criterio | Acción |
264
- |--------|----------|--------|
265
- | **HIGH** | Decisión irreversible, bug crítico, cambio de patrón mayor | Promover a CLAUDE.md o regla del sistema |
266
- | **MEDIUM** | Gotcha documentado, patrón confirmado x2, anti-patrón operativo | Integrar en skill correspondiente |
267
- | **LOW** | Observación contextual, preferencia menor, dato informativo | Mantener en APRENDIZAJES.md, no promover |
268
-
269
- **Mapeo a modelo 4-tier:**
270
- - HIGH → Tipo A (verdad estructural, permanente)
271
- - MEDIUM → Tipo B (gotcha operativo, potencialmente temporal)
272
- - LOW → Tipo C (preferencia, configuración, efímera)
273
-
274
- ### Consolidación con vigencia
275
-
276
- Durante `/swl:aprender`, aplicar estas reglas:
277
-
278
- 1. Si un aprendizaje existente tiene `invalid_at` fecha pasada → archivar (mover a sección "Historial")
279
- 2. Si dos aprendizajes se contradicen → el más reciente marca al anterior como `invalid_at = hoy`
280
- 3. Si un aprendizaje MEDIUM se confirma x3 → promover a HIGH
281
- 4. Si un aprendizaje LOW no se referencia en 30 días → candidato a archivo
282
-
283
- ---
284
-
285
- ## Cuándo NO cargar
286
-
287
- - La señal es una corrección del usuario sobre comportamiento del agente (no un error técnico); eso va al perfil de usuario, no a APRENDIZAJES.md.
288
- - Se busca recuperar aprendizajes anteriores para contextualizarlos; usar `memoria-busqueda` — es más eficiente que leer APRENDIZAJES.md directamente.
289
- - Se quiere crear un skill nuevo desde cero; usar `/swl:crear-skill` que tiene validaciones de frontmatter, nombre de slot y criterios SAP incorporados.
290
-
291
- ## Gotchas / Errores comunes no obvios
292
-
293
- - **Aprendizaje documentado sin `valid_at`**: el agente crea la entrada en APRENDIZAJES.md sin el campo de vigencia temporal, imposibilitando la consolidación automática futura. Causa: el campo se considera opcional. Solución: `valid_at` es obligatorio — poner siempre la fecha de descubrimiento; sin él el aprendizaje no participa en la lógica de vigencia del patrón Zep.
294
- - **Canal incorrecto para correcciones del usuario**: el usuario dice "no uses emojis en los commits" y el agente lo registra en APRENDIZAJES.md como anti-patrón. Causa: se confundió una corrección comportamental (va al perfil) con un anti-patrón técnico (va a APRENDIZAJES.md). Solución: aplicar el árbol de decisión de `reglas/memoria-consolidada.md` antes de escribir — si el dato cambia cuando el usuario cambia, es del perfil; si el dato es verdad técnica independiente del usuario, es de APRENDIZAJES.md.
295
- - **Aprendizaje en DECISIONS.md cuando debería estar en el skill**: una gotcha de SQLAlchemy async se documenta en DECISIONS.md del proyecto en lugar de en `fastapi-experto/SKILL.md`. Causa: se escogió el canal de menor fricción en lugar del canal correcto. Solución: verificar la tabla de destinos del Paso 2 — gotchas de librería van al skill del framework correspondiente, no a DECISIONS.md del proyecto.
296
- - **`rating: HIGH` asignado sin verificar criterio de irreversibilidad**: el agente promueve a CLAUDE.md un aprendizaje "MEDIUM" por el entusiasmo del momento. Causa: no se aplicó el criterio de "decisión irreversible o bug crítico". Solución: antes de asignar HIGH, verificar: ¿cambiar esto en el futuro requeriría refactorizar múltiples archivos o migrar datos? Si no, mantener MEDIUM.
297
- - **Regla incompleta sobre registro de hooks**: una entrada en memoria dice "registrar en modulos.json" pero omite `hooks-config.json`, y en la siguiente iteración se repite el fallo en CI porque ambos manifiestos son obligatorios. Causa: la regla de la lección anterior no cubrió todos los manifiestos afectados. Solución: al documentar una regla sobre registro en manifiestos, listar EXPLÍCITAMENTE cada manifiesto con su responsabilidad distinta (`modulos.json` = qué copiar; `hooks-config.json` = cómo registrar evento). Evidencia: tres incidentes históricos del mismo patrón incompleto (v5.7.1, v5.7.2/3, v5.11.0).
298
- - **Inventario estimado a mano en vez de regenerar**: el agente cuenta "28 hooks" visualmente y propaga la cifra a 5 archivos (CLAUDE/README/package/plugin/SALUD); al regenerar con `scripts/generar-inventario.js` el número real es 30. Causa: confiar en la observación directa en vez de la fuente de verdad determinista. Solución: antes de modificar cualquier contador en documentación oficial, ejecutar el script de inventario y usar su salida como ground truth.
299
- - **Sub-agente Explore sobreestima al analizar fuentes externas (papers + repos)** [CONFIRMADO x4]: cuando se delega análisis de una fuente externa (paper arXiv, repositorio GitHub, documentación de framework) al sub-agente Explore, el reporte propone implementar contribuciones sin filtrar por restricciones del sistema destino Y, peor, sin verificar qué de eso ya existe en el proyecto. **Dos modos de falla observados**:
300
-
301
- **Modo A — papers académicos** (sesión 2026-04-25): sub-agente propuso 50h+ para implementar SPRT + Lyapunov + compositionality theorem del paper Bhardwaj 2026; costo real validado fue ~5h (solo Drift Score + Recovery Catalog). Causa: el Explore evalúa portabilidad técnica sin aplicar filtro de "datos disponibles" ni "infraestructura zero-deps". Evidencia: 3 papers analizados (evolver, Bhardwaj 2026, Zhang et al. 2026) con descarte sistemático ~70-90% del contenido propuesto.
302
-
303
- **Modo B — repositorios externos** (sesión 2026-05-02 cosecha-temp/ EMAIA): sub-agente analizando `temp/docetl-main` (UC Berkeley, arXiv:2410.12189) afirmó dos cosas FALSAS verificables contra el código del proyecto destino: (1) "EMAIA ya usa LiteLLM" — verificación contra `pyproject.toml` + `grep -r litellm core/` mostró que EMAIA tiene clientes propios (`OllamaClient`/`NIMClient`/`vLLMClient`) y NO usa LiteLLM en absoluto; (2) recomendó portar Gleaning como patrón nuevo, cuando `core/learning/evaluator_optimizer.py` y `core/llm/quality_judge.py` YA implementan Anthropic Evaluator-Optimizer + LLM-as-judge. El fix real era WIRING (~30 LOC), no porting. Costo "MEDIO" del agente quedó como BAJO real. Causa: el Explore evalúa el repo externo en aislamiento, sin leer paths del proyecto destino para verificar qué mecanismos ya existen.
304
-
305
- **Solución unificada — aplicar filtros antes de aceptar propuesta del Explore**:
306
-
307
- *Para papers académicos (Modo A)*: 3 filtros críticos: (1) ¿requiere SMT solver / SPRT / Lyapunov / DTMC / formal verification? → descartar (rompe zero-deps); (2) ¿requiere N>100 sesiones de campo para validación estadística? → descartar; (3) ¿genera valor accionable HOY o solo elegancia matemática? → solo implementar si HOY.
308
-
309
- *Para repos externos (Modo B)*: 4 filtros críticos: (1) ¿qué % es teoría/código no-portable vs portable? — si >70% no-portable, recortar; (2) **¿la propuesta reescribe mecanismos existentes en el proyecto destino?** — VERIFICAR con `Grep`/`Read` 2-3 afirmaciones concretas del agente contra el código real ANTES de aceptar (ej: agente dice "X usa Y" → `grep -l Y` para confirmar); (3) ¿LOC nuevas estimadas vs reutilizar lo existente? — si la propuesta supera 500 LOC para un solo patrón, hay sobre-ingeniería; (4) ¿el alcance reducido cubre 80% del valor? — Pareto: identificar el patrón mínimo que captura la mayor parte del beneficio. **Patrón de validación obligatorio**: extraer 2-3 afirmaciones factuales del reporte del Explore (ej: "X usa LiteLLM", "no existe Gleaning en el proyecto") y verificar cada una con `Grep`/`Read` antes de aceptar el plan.
310
- - **Hooks de calidad pre-commit bloquean fixtures de tests como falsos positivos**: el hook `calidad-pre-commit.js` aplica regex `\b(api_key|password|token|secret)\s*[=:]\s*["'][^"'\s]{4,}["']` que matchea fixtures legítimos en archivos de test. Caso real: test que valida que la función `sanitizar()` redacta `api_key="abc12345xyz"` se bloquea. Causa: el hook no distingue contexto de test vs producción. Solución: en archivos de test, construir fixtures con concatenación de strings (`'api' + '_key'`, `'pass' + 'word'`) o agregar marcador placeholder reconocido por el hook (`fake_`, `dummy_`, `placeholder`, `example`, `os.environ`). NUNCA bypassear el hook con `--no-verify` — el detector cumple su función; ajustar el fixture es lo correcto.
311
-
312
- ## Anti-patrones del proceso de extracción
313
-
314
- - **Documentar en el momento incorrecto**: Hacerlo DURANTE o inmediatamente DESPUÉS del
315
- error, no días después cuando el contexto se pierde.
316
- - **Ser demasiado genérico**: "No cometer errores en SQLAlchemy" no es útil.
317
- "NUNCA acceder a relaciones lazy en async fuera de session" sí lo es.
318
- - **Duplicar reglas**: Antes de agregar una regla, buscar si ya existe en el skill.
319
- - **No incluir ejemplo de código**: Las reglas sin código concreto se olvidan.
320
- - **Documentar en DECISIONS.md lo que debería estar en el skill**: Las decisiones de
321
- proyecto van en DECISIONS.md; los patrones reutilizables van en skills.
1
+ ---
2
+ name: extractor-de-aprendizajes
3
+ description: Convertir errores y patrones descubiertos durante la implementación en nuevas habilidades o reglas. Ciclo de mejora continua del sistema SWL.
4
+ version: "1.0.3"
5
+ herramientasPermitidas: [Read]
6
+ exclusiones:
7
+ - "No cargar para actualizar el perfil del usuario — las correcciones explícitas del usuario van a `instintos/perfil-usuario.yaml` vía `perfilador-usuario-swl`, no a APRENDIZAJES.md."
8
+ - "No cargar para buscar aprendizajes ya documentados; usar `memoria-busqueda` que hace búsqueda eficiente sin cargar el archivo completo."
9
+ - "No cargar para crear un skill nuevo desde cero de forma interactiva; usar `/swl:crear-skill` que guía el proceso con validaciones."
10
+ - "No cargar si el aprendizaje no tiene causa raíz identificada — documentar síntoma sin causa produce reglas que no previenen el error real."
11
+ evolvable: true # default para skill estandar
12
+ evolved: true
13
+ evolved-from: "1.1.1"
14
+ evolved-at: "2026-05-02"
15
+ evolved-by: "aprender"
16
+ evolved-note: "Extender gotcha Explore (papers → papers+repos) tras confirmación x4 — sync desde skill global"
17
+ ---
18
+ # Extractor de Aprendizajes
19
+
20
+ ## Propósito
21
+
22
+ Cada error cometido durante la implementación, cada bug inesperado, cada patrón que
23
+ funcionó mejor de lo esperado, es una oportunidad de mejorar el sistema. Este skill
24
+ define el proceso para convertir experiencia concreta en conocimiento estructurado
25
+ que previene errores futuros.
26
+
27
+ ---
28
+
29
+ ## El ciclo de mejora continua
30
+
31
+ ```
32
+ Implementación
33
+
34
+ Error / Insight descubierto
35
+
36
+ Clasificar: ¿es un anti-patrón, un patrón nuevo, o una regla de proyecto?
37
+
38
+ Documentar en la estructura correcta
39
+
40
+ El verificador lo usa en la siguiente iteración
41
+
42
+ Errores prevenidos en el futuro
43
+ ```
44
+
45
+ ---
46
+
47
+ ## Tipos de aprendizajes
48
+
49
+ ### Tipo 1: Anti-patrón (error a prevenir)
50
+
51
+ Se descubrió algo que parece correcto pero falla en producción o en testing.
52
+ Debe convertirse en una **regla negativa** ("NUNCA hagas X").
53
+
54
+ **Indicadores**:
55
+ - Un test falló por una razón no obvia.
56
+ - Un bug tardó más de 30 minutos en diagnosticarse.
57
+ - Se asumió algo sobre una librería que resultó ser incorrecto.
58
+
59
+ ### Tipo 2: Patrón positivo (mejor práctica)
60
+
61
+ Se encontró una forma de hacer algo que resuelve un problema recurrente con
62
+ elegancia. Debe convertirse en una **regla positiva** ("SIEMPRE usa X para Y").
63
+
64
+ **Indicadores**:
65
+ - Se refactorizó código que inicialmente era verboso y quedó mucho más limpio.
66
+ - Una solución resolvió 3 problemas distintos a la vez.
67
+ - El code review elogió específicamente un patrón usado.
68
+
69
+ ### Tipo 3: Gotcha de librería o framework
70
+
71
+ El comportamiento de una dependencia no era el esperado según la documentación o
72
+ la intuición. Debe convertirse en una **nota de advertencia** en el skill relevante.
73
+
74
+ **Indicadores**:
75
+ - "La documentación dice X pero en realidad hace Y".
76
+ - El comportamiento cambia según la versión de la dependencia.
77
+ - Hay una edge case no documentada.
78
+
79
+ ### Tipo 4: Decisión de proyecto
80
+
81
+ Se tomó una decisión de arquitectura o diseño que debe respetarse en el futuro.
82
+ Debe registrarse en **DECISIONS.md** del proyecto.
83
+
84
+ ---
85
+
86
+ ## Protocolo de extracción
87
+
88
+ ### Paso 1: Capturar el contexto del error
89
+
90
+ Cuando se descubre un error o insight, documentarlo inmediatamente con:
91
+
92
+ ```markdown
93
+ ## Aprendizaje: [título corto]
94
+
95
+ **Fecha**: 2026-03-25
96
+ **Contexto**: Implementando endpoint POST /facturas en FastAPI con SQLAlchemy async.
97
+ **Error observado**: MissingGreenlet al acceder a factura.usuario.nombre en el schema Pydantic.
98
+ **Causa raíz**: La relación `usuario` no tenía selectinload() en el query. SQLAlchemy async
99
+ no puede hacer lazy loading fuera de una sesión async activa.
100
+ **Solución aplicada**: Agregar `.options(selectinload(Factura.usuario))` al query.
101
+ **Clasificación**: Anti-patrón → Gotcha de SQLAlchemy async
102
+ ```
103
+
104
+ ### Paso 2: Determinar el destino del aprendizaje
105
+
106
+ | Tipo de aprendizaje | Destino |
107
+ |--------------------|---------|
108
+ | Regla universal de Python | `habilidades/patrones-python/SKILL.md` |
109
+ | Gotcha de FastAPI | `habilidades/fastapi-experto/SKILL.md` |
110
+ | Gotcha de SQLAlchemy | `habilidades/fastapi-experto/SKILL.md` o `CLAUDE.md` del proyecto |
111
+ | Regla de diseño de API | `habilidades/api-rest-diseno/SKILL.md` |
112
+ | Regla de testing | `habilidades/testing-python/SKILL.md` |
113
+ | Decisión de proyecto específico | `DECISIONS.md` del proyecto |
114
+ | Regla que aplica a TODOS los proyectos | `CLAUDE.md` del sistema SWL |
115
+
116
+ ### Paso 3: Escribir la regla en el formato correcto
117
+
118
+ #### Formato para regla negativa (anti-patrón)
119
+
120
+ ```markdown
121
+ ### NUNCA: [título del anti-patrón]
122
+
123
+ **Problema**: Descripción clara de qué falla y por qué.
124
+
125
+ ```python
126
+ # MAL — esto causa [error específico]
127
+ query = select(Factura).where(Factura.id == factura_id)
128
+ result = await db.execute(query)
129
+ factura = result.scalar_one()
130
+ # Acceder a factura.usuario aquí causa MissingGreenlet
131
+ print(factura.usuario.nombre)
132
+ ```
133
+
134
+ ```python
135
+ # BIEN — con selectinload explícito
136
+ query = (
137
+ select(Factura)
138
+ .where(Factura.id == factura_id)
139
+ .options(selectinload(Factura.usuario))
140
+ )
141
+ result = await db.execute(query)
142
+ factura = result.scalar_one()
143
+ print(factura.usuario.nombre) # Funciona correctamente
144
+ ```
145
+ ```
146
+
147
+ #### Formato para regla positiva (mejor práctica)
148
+
149
+ ```markdown
150
+ ### SIEMPRE: [título de la mejor práctica]
151
+
152
+ **Cuándo aplicar**: Descripción de la situación.
153
+ **Beneficio**: Por qué esta forma es mejor.
154
+
155
+ ```python
156
+ # Patrón correcto con ejemplo concreto
157
+ ```
158
+ ```
159
+
160
+ ### Paso 4: Integrar la regla al skill correspondiente
161
+
162
+ 1. Abrir el SKILL.md del skill donde debe vivir la regla.
163
+ 2. Agregar la regla en la sección más relevante.
164
+ 3. Si no hay sección relevante, crear una nueva sección "Gotchas y casos especiales".
165
+ 4. Hacer commit del cambio al skill con mensaje:
166
+ ```
167
+ docs(skills): agrega regla sobre selectinload en SQLAlchemy async
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Plantilla de nuevo skill desde cero
173
+
174
+ Si el aprendizaje no encaja en ningún skill existente, crear uno nuevo:
175
+
176
+ ```
177
+ habilidades/
178
+ └── nuevo-skill/
179
+ └── SKILL.md
180
+ ```
181
+
182
+ ```yaml
183
+ ---
184
+ name: nuevo-skill
185
+ description: Una línea describiendo cuándo activar este skill.
186
+ ---
187
+
188
+ # Título del Skill
189
+
190
+ ## Cuándo activar
191
+ - Caso 1 donde este skill es relevante
192
+ - Caso 2 donde este skill es relevante
193
+
194
+ ## Reglas fundamentales
195
+
196
+ ### Regla 1
197
+ ...
198
+
199
+ ### Regla 2
200
+ ...
201
+
202
+ ## Anti-patrones
203
+
204
+ ### NUNCA: Anti-patrón 1
205
+ ...
206
+
207
+ ## Referencia rápida
208
+ ...
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Indicadores de calidad de un aprendizaje bien documentado
214
+
215
+ Un aprendizaje está bien documentado si:
216
+
217
+ - [ ] Tiene un ejemplo de código concreto (MAL vs. BIEN).
218
+ - [ ] La causa raíz está explicada, no solo el síntoma.
219
+ - [ ] Es accionable: quien lo lee sabe exactamente qué hacer o no hacer.
220
+ - [ ] Está en el skill correcto (no en un lugar genérico).
221
+ - [ ] El título es buscable (contiene la tecnología y el patrón).
222
+
223
+ ---
224
+
225
+ ## Frecuencia de extracción
226
+
227
+ | Momento | Acción |
228
+ |---------|--------|
229
+ | Al terminar una tarea | Revisar si hubo algún insight que documentar |
230
+ | Al resolver un bug difícil | OBLIGATORIO documentar causa raíz y solución |
231
+ | Al hacer code review | Documentar patrones observados |
232
+ | Al finalizar una fase | Revisar ESTADO.md y DECISIONS.md, promover aprendizajes relevantes |
233
+ | Al finalizar el proyecto | Revisar todos los aprendizajes y consolidarlos en los skills |
234
+
235
+ ---
236
+
237
+ ## Vigencia temporal de aprendizajes (patrón Zep)
238
+
239
+ Cada aprendizaje debe llevar timestamps de vigencia para evitar acumular
240
+ conocimiento obsoleto:
241
+
242
+ ```markdown
243
+ ## Aprendizaje: [título]
244
+
245
+ **Fecha**: 2026-04-15
246
+ **valid_at**: 2026-04-15 <!-- Cuándo empezó a ser válido -->
247
+ **invalid_at**: null <!-- null = vigente actualmente -->
248
+ **rating**: HIGH | MEDIUM | LOW <!-- Impacto del aprendizaje -->
249
+ **Contexto**: ...
250
+ **Solución**: ...
251
+ ```
252
+
253
+ ### Reglas de vigencia
254
+
255
+ - `valid_at` es obligatorio — siempre poner la fecha de descubrimiento
256
+ - `invalid_at = null` → el aprendizaje sigue vigente
257
+ - Cuando un aprendizaje queda obsoleto (ej: se actualizó la librería), marcar `invalid_at`
258
+ - Al consultar aprendizajes, por defecto solo mostrar los vigentes (`invalid_at = null`)
259
+ - Nunca borrar aprendizajes obsoletos — solo marcarlos para preservar el historial
260
+
261
+ ### Clasificación automática por impacto (fact rating)
262
+
263
+ | Rating | Criterio | Acción |
264
+ |--------|----------|--------|
265
+ | **HIGH** | Decisión irreversible, bug crítico, cambio de patrón mayor | Promover a CLAUDE.md o regla del sistema |
266
+ | **MEDIUM** | Gotcha documentado, patrón confirmado x2, anti-patrón operativo | Integrar en skill correspondiente |
267
+ | **LOW** | Observación contextual, preferencia menor, dato informativo | Mantener en APRENDIZAJES.md, no promover |
268
+
269
+ **Mapeo a modelo 4-tier:**
270
+ - HIGH → Tipo A (verdad estructural, permanente)
271
+ - MEDIUM → Tipo B (gotcha operativo, potencialmente temporal)
272
+ - LOW → Tipo C (preferencia, configuración, efímera)
273
+
274
+ ### Consolidación con vigencia
275
+
276
+ Durante `/swl:aprender`, aplicar estas reglas:
277
+
278
+ 1. Si un aprendizaje existente tiene `invalid_at` fecha pasada → archivar (mover a sección "Historial")
279
+ 2. Si dos aprendizajes se contradicen → el más reciente marca al anterior como `invalid_at = hoy`
280
+ 3. Si un aprendizaje MEDIUM se confirma x3 → promover a HIGH
281
+ 4. Si un aprendizaje LOW no se referencia en 30 días → candidato a archivo
282
+
283
+ ---
284
+
285
+ ## Cuándo NO cargar
286
+
287
+ - La señal es una corrección del usuario sobre comportamiento del agente (no un error técnico); eso va al perfil de usuario, no a APRENDIZAJES.md.
288
+ - Se busca recuperar aprendizajes anteriores para contextualizarlos; usar `memoria-busqueda` — es más eficiente que leer APRENDIZAJES.md directamente.
289
+ - Se quiere crear un skill nuevo desde cero; usar `/swl:crear-skill` que tiene validaciones de frontmatter, nombre de slot y criterios SAP incorporados.
290
+
291
+ ## Gotchas / Errores comunes no obvios
292
+
293
+ - **Aprendizaje documentado sin `valid_at`**: el agente crea la entrada en APRENDIZAJES.md sin el campo de vigencia temporal, imposibilitando la consolidación automática futura. Causa: el campo se considera opcional. Solución: `valid_at` es obligatorio — poner siempre la fecha de descubrimiento; sin él el aprendizaje no participa en la lógica de vigencia del patrón Zep.
294
+ - **Canal incorrecto para correcciones del usuario**: el usuario dice "no uses emojis en los commits" y el agente lo registra en APRENDIZAJES.md como anti-patrón. Causa: se confundió una corrección comportamental (va al perfil) con un anti-patrón técnico (va a APRENDIZAJES.md). Solución: aplicar el árbol de decisión de `reglas/memoria-consolidada.md` antes de escribir — si el dato cambia cuando el usuario cambia, es del perfil; si el dato es verdad técnica independiente del usuario, es de APRENDIZAJES.md.
295
+ - **Aprendizaje en DECISIONS.md cuando debería estar en el skill**: una gotcha de SQLAlchemy async se documenta en DECISIONS.md del proyecto en lugar de en `fastapi-experto/SKILL.md`. Causa: se escogió el canal de menor fricción en lugar del canal correcto. Solución: verificar la tabla de destinos del Paso 2 — gotchas de librería van al skill del framework correspondiente, no a DECISIONS.md del proyecto.
296
+ - **`rating: HIGH` asignado sin verificar criterio de irreversibilidad**: el agente promueve a CLAUDE.md un aprendizaje "MEDIUM" por el entusiasmo del momento. Causa: no se aplicó el criterio de "decisión irreversible o bug crítico". Solución: antes de asignar HIGH, verificar: ¿cambiar esto en el futuro requeriría refactorizar múltiples archivos o migrar datos? Si no, mantener MEDIUM.
297
+ - **Regla incompleta sobre registro de hooks**: una entrada en memoria dice "registrar en modulos.json" pero omite `hooks-config.json`, y en la siguiente iteración se repite el fallo en CI porque ambos manifiestos son obligatorios. Causa: la regla de la lección anterior no cubrió todos los manifiestos afectados. Solución: al documentar una regla sobre registro en manifiestos, listar EXPLÍCITAMENTE cada manifiesto con su responsabilidad distinta (`modulos.json` = qué copiar; `hooks-config.json` = cómo registrar evento). Evidencia: tres incidentes históricos del mismo patrón incompleto (v5.7.1, v5.7.2/3, v5.11.0).
298
+ - **Inventario estimado a mano en vez de regenerar**: el agente cuenta "28 hooks" visualmente y propaga la cifra a 5 archivos (CLAUDE/README/package/plugin/SALUD); al regenerar con `scripts/generar-inventario.js` el número real es 30. Causa: confiar en la observación directa en vez de la fuente de verdad determinista. Solución: antes de modificar cualquier contador en documentación oficial, ejecutar el script de inventario y usar su salida como ground truth.
299
+ - **Sub-agente Explore sobreestima al analizar fuentes externas (papers + repos)** [CONFIRMADO x4]: cuando se delega análisis de una fuente externa (paper arXiv, repositorio GitHub, documentación de framework) al sub-agente Explore, el reporte propone implementar contribuciones sin filtrar por restricciones del sistema destino Y, peor, sin verificar qué de eso ya existe en el proyecto. **Dos modos de falla observados**:
300
+
301
+ **Modo A — papers académicos** (sesión 2026-04-25): sub-agente propuso 50h+ para implementar SPRT + Lyapunov + compositionality theorem del paper Bhardwaj 2026; costo real validado fue ~5h (solo Drift Score + Recovery Catalog). Causa: el Explore evalúa portabilidad técnica sin aplicar filtro de "datos disponibles" ni "infraestructura zero-deps". Evidencia: 3 papers analizados (evolver, Bhardwaj 2026, Zhang et al. 2026) con descarte sistemático ~70-90% del contenido propuesto.
302
+
303
+ **Modo B — repositorios externos** (sesión 2026-05-02 cosecha-temp/ EMAIA): sub-agente analizando `temp/docetl-main` (UC Berkeley, arXiv:2410.12189) afirmó dos cosas FALSAS verificables contra el código del proyecto destino: (1) "EMAIA ya usa LiteLLM" — verificación contra `pyproject.toml` + `grep -r litellm core/` mostró que EMAIA tiene clientes propios (`OllamaClient`/`NIMClient`/`vLLMClient`) y NO usa LiteLLM en absoluto; (2) recomendó portar Gleaning como patrón nuevo, cuando `core/learning/evaluator_optimizer.py` y `core/llm/quality_judge.py` YA implementan Anthropic Evaluator-Optimizer + LLM-as-judge. El fix real era WIRING (~30 LOC), no porting. Costo "MEDIO" del agente quedó como BAJO real. Causa: el Explore evalúa el repo externo en aislamiento, sin leer paths del proyecto destino para verificar qué mecanismos ya existen.
304
+
305
+ **Solución unificada — aplicar filtros antes de aceptar propuesta del Explore**:
306
+
307
+ *Para papers académicos (Modo A)*: 3 filtros críticos: (1) ¿requiere SMT solver / SPRT / Lyapunov / DTMC / formal verification? → descartar (rompe zero-deps); (2) ¿requiere N>100 sesiones de campo para validación estadística? → descartar; (3) ¿genera valor accionable HOY o solo elegancia matemática? → solo implementar si HOY.
308
+
309
+ *Para repos externos (Modo B)*: 4 filtros críticos: (1) ¿qué % es teoría/código no-portable vs portable? — si >70% no-portable, recortar; (2) **¿la propuesta reescribe mecanismos existentes en el proyecto destino?** — VERIFICAR con `Grep`/`Read` 2-3 afirmaciones concretas del agente contra el código real ANTES de aceptar (ej: agente dice "X usa Y" → `grep -l Y` para confirmar); (3) ¿LOC nuevas estimadas vs reutilizar lo existente? — si la propuesta supera 500 LOC para un solo patrón, hay sobre-ingeniería; (4) ¿el alcance reducido cubre 80% del valor? — Pareto: identificar el patrón mínimo que captura la mayor parte del beneficio. **Patrón de validación obligatorio**: extraer 2-3 afirmaciones factuales del reporte del Explore (ej: "X usa LiteLLM", "no existe Gleaning en el proyecto") y verificar cada una con `Grep`/`Read` antes de aceptar el plan.
310
+ - **Hooks de calidad pre-commit bloquean fixtures de tests como falsos positivos**: el hook `calidad-pre-commit.js` aplica regex `\b(api_key|password|token|secret)\s*[=:]\s*["'][^"'\s]{4,}["']` que matchea fixtures legítimos en archivos de test. Caso real: test que valida que la función `sanitizar()` redacta `api_key="abc12345xyz"` se bloquea. Causa: el hook no distingue contexto de test vs producción. Solución: en archivos de test, construir fixtures con concatenación de strings (`'api' + '_key'`, `'pass' + 'word'`) o agregar marcador placeholder reconocido por el hook (`fake_`, `dummy_`, `placeholder`, `example`, `os.environ`). NUNCA bypassear el hook con `--no-verify` — el detector cumple su función; ajustar el fixture es lo correcto.
311
+
312
+ ## Anti-patrones del proceso de extracción
313
+
314
+ - **Documentar en el momento incorrecto**: Hacerlo DURANTE o inmediatamente DESPUÉS del
315
+ error, no días después cuando el contexto se pierde.
316
+ - **Ser demasiado genérico**: "No cometer errores en SQLAlchemy" no es útil.
317
+ "NUNCA acceder a relaciones lazy en async fuera de session" sí lo es.
318
+ - **Duplicar reglas**: Antes de agregar una regla, buscar si ya existe en el skill.
319
+ - **No incluir ejemplo de código**: Las reglas sin código concreto se olvidan.
320
+ - **Documentar en DECISIONS.md lo que debería estar en el skill**: Las decisiones de
321
+ proyecto van en DECISIONS.md; los patrones reutilizables van en skills.