@saulwade/swl-ses 1.3.8 → 1.4.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 (128) hide show
  1. package/CLAUDE.md +12 -4
  2. package/README.md +1 -1
  3. package/bin/swl-mcp-server.js +187 -187
  4. package/bin/swl-webhook-server.js +198 -0
  5. package/comandos/swl/.evolved.json +22 -22
  6. package/comandos/swl/adoptar-proyecto.md +21 -1
  7. package/comandos/swl/claudemd.md +14 -1
  8. package/comandos/swl/contribuir.md +233 -233
  9. package/comandos/swl/exportar-vault.md +108 -0
  10. package/comandos/swl/nuevo-proyecto.md +24 -2
  11. package/gateway/adapters/base.js +109 -0
  12. package/gateway/adapters/discord.js +167 -0
  13. package/gateway/adapters/email.js +221 -0
  14. package/gateway/adapters/slack.js +192 -0
  15. package/gateway/adapters/telegram.js +183 -0
  16. package/gateway/adapters/webhook.js +113 -0
  17. package/gateway/adapters/whatsapp.js +214 -0
  18. package/gateway/agent-executor.js +322 -0
  19. package/gateway/command-relay.js +271 -0
  20. package/gateway/cron/jobs.js +263 -0
  21. package/gateway/cron/scheduler.js +322 -0
  22. package/gateway/cron/store.js +335 -0
  23. package/gateway/index.js +320 -0
  24. package/gateway/lib/event-channel.js +191 -0
  25. package/gateway/session.js +131 -0
  26. package/gateway/webhook-server.js +324 -0
  27. package/habilidades/backend-production-resilience/SKILL.md +288 -288
  28. package/habilidades/benchmark-memoria/SKILL.md +186 -186
  29. package/habilidades/build-errors-nextjs/SKILL.md +55 -1
  30. package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
  31. package/habilidades/doubt-driven-review/SKILL.md +171 -171
  32. package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
  33. package/habilidades/eval-framework/SKILL.md +212 -212
  34. package/habilidades/extractor-de-aprendizajes/SKILL.md +20 -10
  35. package/habilidades/harness-claude-code/SKILL.md +299 -299
  36. package/habilidades/infra-github-actions/SKILL.md +166 -166
  37. package/habilidades/legacy-code-rescue/SKILL.md +267 -267
  38. package/habilidades/manejo-errores/.evolved.json +8 -8
  39. package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
  40. package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -163
  41. package/habilidades/nextjs-testing/SKILL.md +89 -5
  42. package/habilidades/node-experto/SKILL.md +37 -1
  43. package/habilidades/patrones-python/SKILL.md +229 -229
  44. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
  45. package/habilidades/planear-fase/SKILL.md +319 -319
  46. package/habilidades/react-experto/SKILL.md +45 -4
  47. package/habilidades/release-semver/.evolved.json +8 -8
  48. package/habilidades/tdd-workflow/SKILL.md +36 -4
  49. package/habilidades/testing-python/SKILL.md +340 -340
  50. package/hooks/claudemd-bloat-detector.js +161 -161
  51. package/hooks/inyeccion-contexto.js +8 -3
  52. package/hooks/lib/agent-routing.js +107 -107
  53. package/hooks/lib/auto-consolidator.js +335 -335
  54. package/hooks/lib/error-classifier.js +308 -308
  55. package/hooks/lib/merkle-audit.js +96 -96
  56. package/hooks/lib/provenance-tracker.js +191 -191
  57. package/hooks/lib/rate-limit-ip.js +177 -0
  58. package/hooks/lib/rate-limit-tracker.js +253 -253
  59. package/hooks/lib/resource-quota.js +122 -122
  60. package/hooks/lib/retry-jitter.js +165 -165
  61. package/hooks/lib/skill-auditor.js +588 -588
  62. package/hooks/lib/sync-status.js +228 -228
  63. package/hooks/lib/taint-tracker.js +107 -107
  64. package/hooks/lib/text-similarity.js +241 -241
  65. package/hooks/lib/toon-compressor.js +245 -245
  66. package/hooks/lib/webhook-dedup.js +184 -0
  67. package/hooks/lib/webhook-verify.js +123 -0
  68. package/hooks/proteccion-rutas.js +120 -15
  69. package/hooks/registro-turnos.js +209 -209
  70. package/hooks/sugerir-regenerar-inventario.js +170 -170
  71. package/hooks/validar-formato-post-subagente.js +140 -140
  72. package/hooks/validar-memoria-hook.js +218 -218
  73. package/instintos/prompt-appendices.yaml +57 -57
  74. package/manifiestos/agent-output-schemas.json +57 -57
  75. package/manifiestos/modulos.json +1 -0
  76. package/manifiestos/skills-lock.json +34 -34
  77. package/package.json +5 -3
  78. package/plantillas/auditor-veto-template.md +105 -105
  79. package/plantillas/github-workflows/README.md +47 -47
  80. package/plantillas/github-workflows/release-please.yml +44 -44
  81. package/plantillas/github-workflows/swl-ci.yml +107 -107
  82. package/plantillas/github-workflows/swl-security.yml +51 -51
  83. package/plugin.json +1 -1
  84. package/reglas/analisis-previo-tareas-grandes.md +172 -172
  85. package/reglas/arreglar-al-detectar.md +147 -147
  86. package/reglas/fragmentos-compartidos.md +152 -152
  87. package/reglas/harness-claude-code.md +213 -213
  88. package/reglas/usar-context7.md +226 -226
  89. package/reglas/usar-sistema-swl.md +251 -0
  90. package/schemas/diary-entry.schema.json +80 -80
  91. package/scripts/benchmark-memoria.js +167 -167
  92. package/scripts/comandos/skills.js +251 -2
  93. package/scripts/configurar-branch-protection.js +418 -418
  94. package/scripts/detectar-aprendizajes-duplicados.js +151 -151
  95. package/scripts/field-report.js +199 -199
  96. package/scripts/generar-checklists-consolidados.js +273 -273
  97. package/scripts/generar-inventario.js +420 -420
  98. package/scripts/generar-matriz-lenguajes.js +271 -271
  99. package/scripts/lib/artefactos-python.js +43 -43
  100. package/scripts/lib/benchmark-metrics.js +160 -160
  101. package/scripts/lib/budget-enforcer.js +252 -252
  102. package/scripts/lib/configurar-ci.js +380 -380
  103. package/scripts/lib/contadores-inventario.js +217 -217
  104. package/scripts/lib/detectar-stack-detallado.js +307 -307
  105. package/scripts/lib/diary-entry.js +234 -234
  106. package/scripts/lib/eval-metrics-store.js +218 -218
  107. package/scripts/lib/eval-quality.js +171 -171
  108. package/scripts/lib/eval-schemas.js +144 -144
  109. package/scripts/lib/eval-self-correct.js +106 -106
  110. package/scripts/lib/eval-validator.js +185 -185
  111. package/scripts/lib/jaccard-similarity.js +98 -98
  112. package/scripts/lib/longmemeval-runner.js +125 -125
  113. package/scripts/lib/npm-version.js +261 -261
  114. package/scripts/lib/paquetes-conocidos.js +50 -50
  115. package/scripts/lib/prompt-builder.js +264 -264
  116. package/scripts/lib/rrf-fusion.js +175 -175
  117. package/scripts/lib/scoring-instintos.js +277 -277
  118. package/scripts/lib/semantic-search.js +252 -252
  119. package/scripts/limpiar-artefactos-python.js +131 -131
  120. package/scripts/mcp-server/README.md +128 -128
  121. package/scripts/mcp-server/handlers.js +206 -206
  122. package/scripts/migrar-csv-a-array.js +168 -168
  123. package/scripts/migrar-fase-dominio.js +201 -201
  124. package/scripts/publicar.js +511 -511
  125. package/scripts/run-eval.js +141 -141
  126. package/scripts/validar-manifest.js +195 -195
  127. package/scripts/validar-userland-vacio.js +110 -110
  128. package/scripts/verificar-release.js +110 -0
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: react-experto
3
3
  description: React + Next.js mejores prácticas modernas. Cubre Server Components vs Client Components, data fetching patterns (RSC, React Query, SWR, Server Actions), state management (useState, Zustand, Jotai), performance (memo, lazy, Suspense, streaming) y Next.js App Router patterns.
4
- version: "1.1.1"
4
+ version: "1.2.0"
5
5
  evolved: true
6
- evolved-from: "1.1.0"
7
- evolved-at: "2026-05-11"
6
+ evolved-from: "1.1.1"
7
+ evolved-at: "2026-05-12"
8
8
  evolved-by: "aprender"
9
- evolved-note: "L-105 SIGM: setState dentro de useEffect bloqueado por react-hooks/set-state-in-effect (eslint-plugin-react-hooks v7+) - 3 patrones de reemplazo (lazy init, useMemo, useSyncExternalStore) confirmados x3 en F1.2/F1.3/F3"
9
+ evolved-note: "Backport L-138 SIGM: Sidebar/menu con RBAC debe ocultar secciones cuyos items quedan todos filtrados; previo L-105 setState in useEffect"
10
10
  herramientasPermitidas: [Read]
11
11
  exclusiones:
12
12
  - "No cargar para optimización de rendimiento React (memo, useMemo, useCallback, virtualización, code splitting) — para rendimiento cargar `react-optimizacion`."
@@ -158,6 +158,47 @@ useEffect(() => {
158
158
  const filtrados = useMemo(() => usuarios.filter(u => u.activo), [usuarios]);
159
159
  ```
160
160
 
161
+ ### Sidebar/menu con RBAC: ocultar secciones cuyos items quedan todos filtrados
162
+
163
+ **Problema** (L-138 SIGM 2026-05-12): un sidebar con secciones colapsables filtra items por permiso del usuario. Si un usuario sin el permiso requerido ve la sección con su header y chevron pero al expandirla aparece un `<ul>` vacío, el bug confunde — el usuario reporta "el menú no despliega nada", sin saber si es bug del sistema o falta data. Caso SIGM: sección "Ventanilla" tenía 1 item con permiso `CAJA:cobrar`; cuando ningún usuario tenía ese string literal (era `RECAUDACION:CAJA:cobrar`), todos los usuarios veían la sección vacía.
164
+
165
+ ```tsx
166
+ // MAL — header se renderiza aunque el <ul> quede vacío
167
+ {NAV_SECTIONS.map((section) => (
168
+ <Section key={section.title}>
169
+ <SectionHeader title={section.title} />
170
+ <ul>
171
+ {section.items
172
+ .filter((item) => !item.permiso || tienePermiso(item.permiso))
173
+ .map((item) => <NavItem key={item.href} {...item} />)}
174
+ </ul>
175
+ </Section>
176
+ ))}
177
+ ```
178
+
179
+ ```tsx
180
+ // BIEN — filtrar items ANTES de decidir si renderizar la sección
181
+ {NAV_SECTIONS.map((section) => {
182
+ const itemsVisibles = section.items.filter(
183
+ (item) => !item.permiso || tienePermiso(item.permiso),
184
+ )
185
+ if (itemsVisibles.length === 0) return null // ← omitir sección entera
186
+
187
+ return (
188
+ <Section key={section.title}>
189
+ <SectionHeader title={section.title} />
190
+ <ul>
191
+ {itemsVisibles.map((item) => <NavItem key={item.href} {...item} />)}
192
+ </ul>
193
+ </Section>
194
+ )
195
+ })}
196
+ ```
197
+
198
+ **Aplica también a**: tabs, breadcrumbs, dropdowns de filtros, paneles de configuración con secciones por permiso. Patrón: cualquier UI que agrupa items en secciones donde los items pueden filtrarse por RBAC.
199
+
200
+ **Test obligatorio**: cuando el mock de `useAuth` NO incluye los permisos de una sección, esa sección NO debe renderizarse en el DOM (`expect(queryByText('NombreSección')).not.toBeInTheDocument()`).
201
+
161
202
  ```tsx
162
203
  // MAL: fetch en Client Component cuando podria ser RSC
163
204
  useEffect(() => {
@@ -1,9 +1,9 @@
1
- {
2
- "SKILL.md": {
3
- "evolved": true,
4
- "evolvedFrom": "1.0.1",
5
- "evolvedAt": "2026-05-02",
6
- "evolvedBy": "aprender",
7
- "evolvedNote": "Sección nueva: publish a múltiples registries (republish-only + auth GitHub Packages)"
8
- }
1
+ {
2
+ "SKILL.md": {
3
+ "evolved": true,
4
+ "evolvedFrom": "1.0.1",
5
+ "evolvedAt": "2026-05-02",
6
+ "evolvedBy": "aprender",
7
+ "evolvedNote": "Sección nueva: publish a múltiples registries (republish-only + auth GitHub Packages)"
8
+ }
9
9
  }
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: tdd-workflow
3
3
  description: Flujo completo de Test-Driven Development. Ciclo RED (el test falla) → GREEN (implementación mínima) → REFACTOR (limpieza). Incluye cobertura mínima obligatoria, tests de frontera, factories, fixtures y estrategias para diferentes tipos de código (APIs, services, componentes Angular).
4
- version: "1.0.1"
4
+ version: "1.0.2"
5
5
  evolved: true
6
- evolved-from: "1.0.0"
7
- evolved-at: "2026-05-11"
6
+ evolved-from: "1.0.1"
7
+ evolved-at: "2026-05-14"
8
8
  evolved-by: "aprender"
9
- evolved-note: "L-109 SIGM: nombrar tests por causa raíz (no por feature) test_repository_no_usa_columna_inexistente_p_monto detectó bug en F1.4 sin necesidad de reproducción manual"
9
+ evolved-note: "Patrón reloj inyectable (parámetro `ahora` con default Date.now()) para tests deterministas sin freezegun/jest.useFakeTimers validado en 3 módulos sesión webhook Opción C"
10
10
  herramientasPermitidas: [Read, Bash]
11
11
  evolvable: true # default para skill estandar
12
12
  exclusiones:
@@ -297,4 +297,36 @@ pytest --cov=src/services --cov-fail-under=90
297
297
 
298
298
  **`db_session.rollback()` en el fixture de pytest-asyncio no deshace los datos insertados por `db.flush()` dentro de la función testeada cuando la sesión usa `autocommit=True` implícito por configuración del engine**: algunos proyectos configuran `AsyncEngine` con `isolation_level="AUTOCOMMIT"` para compatibilidad con operaciones DDL; en ese contexto, cada `flush()` hace commit inmediatamente y el `rollback()` del fixture no puede deshacer esos cambios. Causa: `AUTOCOMMIT` en PostgreSQL significa que no hay transacción activa que se pueda revertir. Fix: verificar que el engine de tests NO use `isolation_level="AUTOCOMMIT"` (la configuración debe ser solo para el engine de migraciones Alembic, no para el de la app). Para tests que necesitan AUTOCOMMIT por alguna razón, usar una BD de test separada que se trunca con `TRUNCATE ... RESTART IDENTITY CASCADE` en el teardown del fixture.
299
299
 
300
+ **Reloj inyectable como parámetro `ahora` habilita tests deterministas sin `freezegun`, `jest.useFakeTimers()` ni `sinon.useFakeTimers()`** [PATRÓN VALIDADO en SWL Opción C webhook]: cuando una API depende del tiempo (rate-limit con bucket que se rellena, dedup con ventana de retención, cache con TTL, schedulers), recibir el timestamp por parámetro en lugar de llamar `Date.now()` internamente permite que los tests pasen 1000 segundos en 0 ms reales. Diseño: `metodo(arg1, arg2, ahora = Date.now())` — producción no cambia (llamadas siguen siendo `obj.consumir(1)`), tests pasan `ahora` explícito (`obj.consumir(1, T0 + 5000)`). Validado en 3 módulos esta sesión: `rate-limit-ip.js` (40+ tests bucket refill, capacidad, cleanup), `webhook-dedup.js` (ventana de retención, rotación idempotente), helpers internos de `webhook-server.js`. Ningún test usa `sleep`, ningún test es flaky, ningún test mockea `Date`. Aplicable a JS/TS y a Python (`def consumir(self, tokens, ahora=None)` con `ahora = ahora or datetime.now(UTC)` al inicio).
301
+
302
+ ```js
303
+ // MAL — test no-determinista, requiere sleep o mock global
304
+ class Bucket {
305
+ consumir(n) {
306
+ const ahora = Date.now(); // ← imposible de controlar desde el test
307
+ this._rellenar(ahora);
308
+ if (this.tokens >= n) { this.tokens -= n; return true; }
309
+ return false;
310
+ }
311
+ }
312
+
313
+ // BIEN — reloj inyectable, test determinista
314
+ class Bucket {
315
+ consumir(n, ahora = Date.now()) { // ← default en producción, inyectable en test
316
+ this._rellenar(ahora);
317
+ if (this.tokens >= n) { this.tokens -= n; return true; }
318
+ return false;
319
+ }
320
+ }
321
+
322
+ // En el test:
323
+ const T0 = 1700000000000;
324
+ const b = new Bucket(10, 1, T0);
325
+ for (let i = 0; i < 10; i++) b.consumir(1, T0); // saturar
326
+ assert.equal(b.consumir(1, T0), false); // sin refill aún
327
+ assert.equal(b.consumir(5, T0 + 5000), true); // 5 seg después: 5 tokens
328
+ ```
329
+
330
+ Aplica también a tests de clock skew (tiempo retrocede por NTP): pasar `T0 - 1000` y validar que la lógica no rompe. Origen: rate-limit-ip.js + webhook-dedup.js sesión 2026-05-13.
331
+
300
332
  **Tests nombrados por feature (`test_emitir_factura_exitosa`) pierden poder regresivo; nombrados por causa raíz (`test_repository_no_usa_columna_inexistente_p_monto`) detectan regresiones específicas sin reproducción manual** [CONFIRMADO en SIGM Opción C F1.4]: cuando se descubre un bug por una causa raíz concreta (typo en nombre de columna SQL, omisión de `selectinload`, mock que devuelve dict en vez de objeto, schema obsoleto), el test de regresión que se escribe debe llevar el nombre de la causa, no del feature afectado. Caso real: durante F1.4 de SIGM, el repository de pagos referenciaba `p.monto` cuando la columna se llamaba `p.monto_pagado`; el test escrito como `test_repository_no_usa_columna_inexistente_p_monto` falló inmediatamente en la siguiente sesión cuando otro agente reintrodujo el typo, sin necesidad de reproducir el escenario de negocio (emitir cobro real, verificar respuesta). Causa: los nombres orientados a feature (`test_pago_exitoso`) son ambiguos sobre QUÉ falla — si el test falla, el desarrollador debe diagnosticar; los nombres orientados a causa raíz (`test_X_no_usa_Y`, `test_query_incluye_selectinload_Z`, `test_service_devuelve_dict_no_objeto`) son auto-diagnósticos. Fix: para cada bug que cueste >30 min diagnosticar, escribir UN test adicional cuyo nombre describa la condición técnica violada, no el escenario de negocio. Convención: `test_<componente>_<condicion_tecnica>` o `test_<componente>_no_<anti_patron>`. Estos tests son tu segunda línea de defensa contra regresiones de la misma causa raíz, complementarios a los tests de comportamiento.