@saulwade/swl-ses 1.0.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 (702) hide show
  1. package/CLAUDE.md +238 -0
  2. package/README.md +560 -0
  3. package/_userland/agentes/.gitkeep +0 -0
  4. package/_userland/habilidades/.gitkeep +0 -0
  5. package/agentes/.evolved.json +9 -0
  6. package/agentes/accesibilidad-wcag-swl.md +692 -0
  7. package/agentes/arquitecto-swl.md +238 -0
  8. package/agentes/auto-evolucion-swl.md +854 -0
  9. package/agentes/backend-api-swl.md +470 -0
  10. package/agentes/backend-csharp-swl.md +418 -0
  11. package/agentes/backend-go-swl.md +388 -0
  12. package/agentes/backend-java-swl.md +279 -0
  13. package/agentes/backend-node-swl.md +477 -0
  14. package/agentes/backend-python-swl.md +608 -0
  15. package/agentes/backend-rust-swl.md +362 -0
  16. package/agentes/backend-workers-swl.md +480 -0
  17. package/agentes/cloud-infra-swl.md +485 -0
  18. package/agentes/consolidador-swl.md +539 -0
  19. package/agentes/datos-swl.md +584 -0
  20. package/agentes/depurador-swl.md +349 -0
  21. package/agentes/devops-ci-swl.md +374 -0
  22. package/agentes/disenador-ui-swl.md +558 -0
  23. package/agentes/documentador-swl.md +343 -0
  24. package/agentes/evals/arquitecto-swl.evals.json +56 -0
  25. package/agentes/evals/auto-evolucion-swl.evals.json +68 -0
  26. package/agentes/evals/implementador-swl.evals.json +56 -0
  27. package/agentes/evals/orquestador-swl.evals.json +60 -0
  28. package/agentes/evals/perfilador-usuario-swl.evals.json +60 -0
  29. package/agentes/evals/red-team-swl.evals.json +59 -0
  30. package/agentes/evals/revisor-codigo-swl.evals.json +59 -0
  31. package/agentes/frontend-angular-swl.md +627 -0
  32. package/agentes/frontend-css-swl.md +720 -0
  33. package/agentes/frontend-react-swl.md +696 -0
  34. package/agentes/frontend-swl.md +500 -0
  35. package/agentes/frontend-tailwind-swl.md +830 -0
  36. package/agentes/implementador-swl.md +328 -0
  37. package/agentes/investigador-swl.md +430 -0
  38. package/agentes/investigador-ux-swl.md +500 -0
  39. package/agentes/llm-apps-swl.md +276 -0
  40. package/agentes/migrador-swl.md +417 -0
  41. package/agentes/mobile-android-swl.md +509 -0
  42. package/agentes/mobile-cross-swl.md +539 -0
  43. package/agentes/mobile-ios-swl.md +500 -0
  44. package/agentes/mobile-testing-swl.md +300 -0
  45. package/agentes/notificador-swl.md +916 -0
  46. package/agentes/observabilidad-swl.md +436 -0
  47. package/agentes/orquestador-swl.md +884 -0
  48. package/agentes/pagos-swl.md +283 -0
  49. package/agentes/perfilador-usuario-swl.md +306 -0
  50. package/agentes/planificador-swl.md +402 -0
  51. package/agentes/producto-prd-swl.md +587 -0
  52. package/agentes/red-team-swl.md +216 -0
  53. package/agentes/release-manager-swl.md +568 -0
  54. package/agentes/rendimiento-swl.md +714 -0
  55. package/agentes/resolutor-build-swl.md +243 -0
  56. package/agentes/revisor-angular-swl.md +276 -0
  57. package/agentes/revisor-codigo-swl.md +348 -0
  58. package/agentes/revisor-csharp-swl.md +262 -0
  59. package/agentes/revisor-go-swl.md +257 -0
  60. package/agentes/revisor-java-swl.md +255 -0
  61. package/agentes/revisor-kotlin-swl.md +271 -0
  62. package/agentes/revisor-nextjs-swl.md +279 -0
  63. package/agentes/revisor-php-swl.md +269 -0
  64. package/agentes/revisor-react-swl.md +276 -0
  65. package/agentes/revisor-rust-swl.md +344 -0
  66. package/agentes/revisor-seguridad-swl.md +390 -0
  67. package/agentes/revisor-swift-swl.md +266 -0
  68. package/agentes/revisor-typescript-swl.md +344 -0
  69. package/agentes/sre-swl.md +265 -0
  70. package/agentes/tdd-qa-swl.md +354 -0
  71. package/agentes/ux-disenador-swl.md +501 -0
  72. package/bin/lib/bot-comandos.js +1030 -0
  73. package/bin/lib/bot-discovery.js +182 -0
  74. package/bin/lib/bot-git.js +142 -0
  75. package/bin/swl-ses.js +325 -0
  76. package/bin/swl-telegram-bot.js +442 -0
  77. package/bin/swl-telegram-bot.plist +21 -0
  78. package/bin/swl-telegram-bot.service +14 -0
  79. package/comandos/swl/.evolved.json +23 -0
  80. package/comandos/swl/actualizar.md +174 -0
  81. package/comandos/swl/adoptar-proyecto.md +207 -0
  82. package/comandos/swl/aprender.md +701 -0
  83. package/comandos/swl/auditar-deps.md +134 -0
  84. package/comandos/swl/autoresearch.md +170 -0
  85. package/comandos/swl/ayuda.md +224 -0
  86. package/comandos/swl/brainstorm.md +50 -0
  87. package/comandos/swl/checkpoint.md +330 -0
  88. package/comandos/swl/compactar.md +283 -0
  89. package/comandos/swl/configurar-ci.md +227 -0
  90. package/comandos/swl/contexto.md +112 -0
  91. package/comandos/swl/contribuir.md +233 -0
  92. package/comandos/swl/crear-skill.md +292 -0
  93. package/comandos/swl/cron.md +196 -0
  94. package/comandos/swl/dashboard.md +146 -0
  95. package/comandos/swl/discutir-fase.md +230 -0
  96. package/comandos/swl/ejecutar-fase.md +135 -0
  97. package/comandos/swl/evaluar-skill.md +487 -0
  98. package/comandos/swl/evolucion-estado.md +142 -0
  99. package/comandos/swl/evolucionar.md +259 -0
  100. package/comandos/swl/exportar-vault.md +189 -0
  101. package/comandos/swl/gateway.md +158 -0
  102. package/comandos/swl/inbox.md +116 -0
  103. package/comandos/swl/instalar.md +220 -0
  104. package/comandos/swl/instintos.md +86 -0
  105. package/comandos/swl/mapear-codebase.md +312 -0
  106. package/comandos/swl/mcp-status.md +175 -0
  107. package/comandos/swl/metricas.md +270 -0
  108. package/comandos/swl/modelo.md +102 -0
  109. package/comandos/swl/notificaciones.md +396 -0
  110. package/comandos/swl/nuevo-proyecto.md +154 -0
  111. package/comandos/swl/planear-fase.md +221 -0
  112. package/comandos/swl/plugins.md +256 -0
  113. package/comandos/swl/reflect-skills.md +125 -0
  114. package/comandos/swl/release.md +217 -0
  115. package/comandos/swl/revisar-impacto.md +206 -0
  116. package/comandos/swl/revisar.md +330 -0
  117. package/comandos/swl/salud.md +363 -0
  118. package/comandos/swl/sesiones.md +200 -0
  119. package/comandos/swl/skill-search.md +113 -0
  120. package/comandos/swl/verificar.md +585 -0
  121. package/comandos/swl/wiki.md +620 -0
  122. package/contextos/dev.md +32 -0
  123. package/contextos/research.md +30 -0
  124. package/contextos/review.md +31 -0
  125. package/habilidades/accesibilidad-a11y/SKILL.md +201 -0
  126. package/habilidades/accesibilidad-a11y/evals/evals.json +56 -0
  127. package/habilidades/accesibilidad-a11y/recursos/ejemplos-y-checklist-completo.md +441 -0
  128. package/habilidades/agent-browser/SKILL.md +218 -0
  129. package/habilidades/agentes-como-servicio/SKILL.md +218 -0
  130. package/habilidades/ai-runtime-security/SKILL.md +273 -0
  131. package/habilidades/angular-avanzado/SKILL.md +164 -0
  132. package/habilidades/angular-avanzado/recursos/ejemplos-avanzados.md +219 -0
  133. package/habilidades/angular-moderno/SKILL.md +186 -0
  134. package/habilidades/angular-moderno/evals/evals.json +45 -0
  135. package/habilidades/angular-moderno/recursos/ejemplos-avanzados.md +106 -0
  136. package/habilidades/api-rest-diseno/SKILL.md +191 -0
  137. package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
  138. package/habilidades/api-rest-diseno/recursos/referencia-api.md +140 -0
  139. package/habilidades/aprendizaje-continuo/SKILL.md +151 -0
  140. package/habilidades/aprendizaje-continuo/evals/evals.json +53 -0
  141. package/habilidades/aprendizaje-continuo/recursos/referencia-instintos.md +290 -0
  142. package/habilidades/async-python/SKILL.md +149 -0
  143. package/habilidades/async-python/evals/evals.json +47 -0
  144. package/habilidades/async-python/recursos/patrones-y-ejemplos-completos.md +292 -0
  145. package/habilidades/auth-patrones/.evolved.json +9 -0
  146. package/habilidades/auth-patrones/SKILL.md +413 -0
  147. package/habilidades/auth-patrones/recursos/implementaciones-completas.md +229 -0
  148. package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -0
  149. package/habilidades/auto-evolucion-protocolo/evals/evals.json +55 -0
  150. package/habilidades/auto-evolucion-protocolo/recursos/referencia-completa.md +145 -0
  151. package/habilidades/autoresearch/SKILL.md +268 -0
  152. package/habilidades/autoresearch/evals/evals.json +41 -0
  153. package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
  154. package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
  155. package/habilidades/azure-cloud/SKILL.md +308 -0
  156. package/habilidades/azure-cloud/recursos/aks.md +327 -0
  157. package/habilidades/backend-mcp-servidor/SKILL.md +270 -0
  158. package/habilidades/backend-production-resilience/SKILL.md +288 -0
  159. package/habilidades/brainstorming/SKILL.md +295 -0
  160. package/habilidades/brainstorming/recursos/componentes-html.md +247 -0
  161. package/habilidades/build-errors-cpp/SKILL.md +270 -0
  162. package/habilidades/build-errors-csharp/SKILL.md +265 -0
  163. package/habilidades/build-errors-go/SKILL.md +306 -0
  164. package/habilidades/build-errors-java/SKILL.md +278 -0
  165. package/habilidades/build-errors-kotlin/SKILL.md +303 -0
  166. package/habilidades/build-errors-nextjs/SKILL.md +312 -0
  167. package/habilidades/build-errors-php/SKILL.md +270 -0
  168. package/habilidades/build-errors-python/SKILL.md +292 -0
  169. package/habilidades/build-errors-rust/SKILL.md +284 -0
  170. package/habilidades/build-errors-swift/SKILL.md +272 -0
  171. package/habilidades/build-errors-typescript/SKILL.md +369 -0
  172. package/habilidades/checklist-calidad/SKILL.md +271 -0
  173. package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
  174. package/habilidades/checklist-seguridad/SKILL.md +285 -0
  175. package/habilidades/checkpoints-verificacion/SKILL.md +298 -0
  176. package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
  177. package/habilidades/ci-cd-pipelines/SKILL.md +157 -0
  178. package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
  179. package/habilidades/ci-cd-pipelines/recursos/pipelines-completos.md +487 -0
  180. package/habilidades/cloud-aws/SKILL.md +142 -0
  181. package/habilidades/cloud-aws/recursos/servicios-aws-referencia.md +321 -0
  182. package/habilidades/compactacion-contexto/SKILL.md +247 -0
  183. package/habilidades/contenedores-docker/SKILL.md +137 -0
  184. package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
  185. package/habilidades/contenedores-docker/recursos/ejemplos-y-configuraciones.md +327 -0
  186. package/habilidades/context-builder/SKILL.md +170 -0
  187. package/habilidades/control-profundidad/SKILL.md +128 -0
  188. package/habilidades/csharp-experto/SKILL.md +322 -0
  189. package/habilidades/csharp-patrones/SKILL.md +316 -0
  190. package/habilidades/csharp-testing/SKILL.md +286 -0
  191. package/habilidades/css-moderno/SKILL.md +166 -0
  192. package/habilidades/css-moderno/evals/evals.json +43 -0
  193. package/habilidades/css-moderno/recursos/ejemplos-y-patrones-completos.md +337 -0
  194. package/habilidades/datos-etl/SKILL.md +129 -0
  195. package/habilidades/datos-etl/recursos/implementaciones-completas.md +322 -0
  196. package/habilidades/dbml-experto/SKILL.md +339 -0
  197. package/habilidades/dbml-experto/evals/evals.json +56 -0
  198. package/habilidades/dependencias-auditoria/SKILL.md +320 -0
  199. package/habilidades/deprecacion-migracion/SKILL.md +169 -0
  200. package/habilidades/deprecacion-migracion/recursos/implementaciones-completas.md +220 -0
  201. package/habilidades/design-tokens/SKILL.md +158 -0
  202. package/habilidades/design-tokens/recursos/tokens-y-configuracion.md +363 -0
  203. package/habilidades/devsecops-pipeline-security/SKILL.md +309 -0
  204. package/habilidades/diagrama-arquitectura/SKILL.md +165 -0
  205. package/habilidades/diagrama-arquitectura/assets/template.html +276 -0
  206. package/habilidades/discutir-fase/SKILL.md +188 -0
  207. package/habilidades/diseno-herramientas-agente/SKILL.md +199 -0
  208. package/habilidades/diseno-responsivo/SKILL.md +186 -0
  209. package/habilidades/diseno-responsivo/recursos/ejemplos-layouts.md +156 -0
  210. package/habilidades/django-experto/SKILL.md +205 -0
  211. package/habilidades/django-experto/recursos/async-django.md +390 -0
  212. package/habilidades/django-experto/recursos/drf-patrones.md +438 -0
  213. package/habilidades/django-experto/recursos/orm-avanzado.md +382 -0
  214. package/habilidades/django-experto/recursos/referencia-completa.md +188 -0
  215. package/habilidades/django-experto/recursos/testing-django.md +415 -0
  216. package/habilidades/doc-sync/SKILL.md +280 -0
  217. package/habilidades/drift-detection/SKILL.md +179 -0
  218. package/habilidades/ejecutar-fase/SKILL.md +468 -0
  219. package/habilidades/estilo-sin-ai-isms/SKILL.md +775 -0
  220. package/habilidades/estilo-sin-ai-isms/evals/evals.json +63 -0
  221. package/habilidades/estilo-sin-ai-isms/scripts/detectar_aiisms.py +500 -0
  222. package/habilidades/estructura-proyecto-claude/SKILL.md +215 -0
  223. package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
  224. package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +176 -0
  225. package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +289 -0
  226. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +77 -0
  227. package/habilidades/estructura-proyecto-claude/recursos/variantes-por-stack.md +177 -0
  228. package/habilidades/evaluacion-agentes/SKILL.md +314 -0
  229. package/habilidades/event-driven/SKILL.md +153 -0
  230. package/habilidades/event-driven/recursos/implementaciones-completas.md +423 -0
  231. package/habilidades/extraccion-documentos/SKILL.md +221 -0
  232. package/habilidades/extractor-de-aprendizajes/.evolved.json +9 -0
  233. package/habilidades/extractor-de-aprendizajes/SKILL.md +311 -0
  234. package/habilidades/extractor-de-aprendizajes/evals/evals.json +55 -0
  235. package/habilidades/fastapi-experto/SKILL.md +221 -0
  236. package/habilidades/fastapi-experto/recursos/async-patterns.md +438 -0
  237. package/habilidades/fastapi-experto/recursos/dependency-injection.md +330 -0
  238. package/habilidades/fastapi-experto/recursos/referencia-completa.md +79 -0
  239. package/habilidades/fastapi-experto/recursos/testing-httpx.md +420 -0
  240. package/habilidades/filament-admin/SKILL.md +290 -0
  241. package/habilidades/frontend-avanzado/SKILL.md +257 -0
  242. package/habilidades/frontend-avanzado/recursos/apis-nativas-ejemplos.md +341 -0
  243. package/habilidades/gcp-cloud/SKILL.md +260 -0
  244. package/habilidades/gcp-cloud/recursos/gke.md +234 -0
  245. package/habilidades/gcp-cloud/recursos/terraform-gcp.md +307 -0
  246. package/habilidades/generacion-mermaid/SKILL.md +229 -0
  247. package/habilidades/git-worktrees-paralelo/SKILL.md +270 -0
  248. package/habilidades/go-experto/SKILL.md +305 -0
  249. package/habilidades/go-patrones/SKILL.md +299 -0
  250. package/habilidades/go-testing/SKILL.md +291 -0
  251. package/habilidades/graphql-experto/SKILL.md +323 -0
  252. package/habilidades/guardrail-semantico/SKILL.md +282 -0
  253. package/habilidades/harness-claude-code/SKILL.md +299 -0
  254. package/habilidades/iam-secretos/SKILL.md +265 -0
  255. package/habilidades/iam-secretos/recursos/implementaciones-completas.md +356 -0
  256. package/habilidades/infra-github-actions/SKILL.md +166 -0
  257. package/habilidades/instalar-sistema/.evolved.json +9 -0
  258. package/habilidades/instalar-sistema/SKILL.md +221 -0
  259. package/habilidades/java-experto/SKILL.md +290 -0
  260. package/habilidades/java-patrones/SKILL.md +275 -0
  261. package/habilidades/java-testing/SKILL.md +288 -0
  262. package/habilidades/kotlin-compose/SKILL.md +278 -0
  263. package/habilidades/kotlin-compose/recursos/animaciones-performance.md +93 -0
  264. package/habilidades/kotlin-experto/SKILL.md +318 -0
  265. package/habilidades/kotlin-testing/SKILL.md +267 -0
  266. package/habilidades/kotlin-testing/recursos/testing-avanzado.md +74 -0
  267. package/habilidades/kubernetes-orquestacion/SKILL.md +152 -0
  268. package/habilidades/kubernetes-orquestacion/recursos/manifiestos-completos.md +452 -0
  269. package/habilidades/langchain-langraph/SKILL.md +386 -0
  270. package/habilidades/langchain-langraph/recursos/evaluacion-rag.md +321 -0
  271. package/habilidades/langchain-langraph/recursos/rag-maturity-model.md +225 -0
  272. package/habilidades/langchain-langraph/recursos/vectorstores.md +306 -0
  273. package/habilidades/legacy-code-rescue/SKILL.md +267 -0
  274. package/habilidades/likec4-experto/SKILL.md +412 -0
  275. package/habilidades/likec4-experto/evals/evals.json +69 -0
  276. package/habilidades/manejo-errores/.evolved.json +9 -0
  277. package/habilidades/manejo-errores/SKILL.md +407 -0
  278. package/habilidades/manejo-errores/recursos/implementaciones-completas.md +248 -0
  279. package/habilidades/mapear-codebase/SKILL.md +275 -0
  280. package/habilidades/memoria-busqueda/SKILL.md +194 -0
  281. package/habilidades/memoria-busqueda/evals/evals.json +44 -0
  282. package/habilidades/meta-skills-estandar/SKILL.md +298 -0
  283. package/habilidades/meta-skills-estandar/recursos/anti-patrones-y-leyes.md +205 -0
  284. package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +107 -0
  285. package/habilidades/meta-skills-estandar/recursos/idiomas-framework.md +60 -0
  286. package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -0
  287. package/habilidades/microservicios/SKILL.md +155 -0
  288. package/habilidades/microservicios/recursos/patrones-y-ejemplos-completos.md +325 -0
  289. package/habilidades/mobile-flutter/SKILL.md +199 -0
  290. package/habilidades/mobile-flutter/recursos/ejemplos-completos.md +319 -0
  291. package/habilidades/mobile-react-native/SKILL.md +176 -0
  292. package/habilidades/mobile-react-native/recursos/ejemplos-completos.md +216 -0
  293. package/habilidades/mongodb-experto/SKILL.md +302 -0
  294. package/habilidades/monitoring-alertas/SKILL.md +201 -0
  295. package/habilidades/monitoring-alertas/recursos/instrumentacion-y-alertas.md +301 -0
  296. package/habilidades/nestjs-experto/SKILL.md +307 -0
  297. package/habilidades/nestjs-experto/recursos/guards-interceptors.md +339 -0
  298. package/habilidades/nestjs-experto/recursos/modulos-di.md +287 -0
  299. package/habilidades/nestjs-experto/recursos/testing-nestjs.md +354 -0
  300. package/habilidades/nextjs-experto/SKILL.md +335 -0
  301. package/habilidades/nextjs-patrones/SKILL.md +303 -0
  302. package/habilidades/nextjs-testing/SKILL.md +331 -0
  303. package/habilidades/node-experto/.evolved.json +9 -0
  304. package/habilidades/node-experto/SKILL.md +266 -0
  305. package/habilidades/node-experto/recursos/patrones-completos.md +283 -0
  306. package/habilidades/notificaciones-multicanal/SKILL.md +159 -0
  307. package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
  308. package/habilidades/notificaciones-multicanal/recursos/configuracion-y-templates.md +303 -0
  309. package/habilidades/nuevo-proyecto/SKILL.md +204 -0
  310. package/habilidades/orquestacion-async/SKILL.md +303 -0
  311. package/habilidades/paid-media-tracking/SKILL.md +269 -0
  312. package/habilidades/paid-media-tracking/recursos/auditoria-tracking.md +220 -0
  313. package/habilidades/paid-media-tracking/recursos/google-ads-api.md +215 -0
  314. package/habilidades/patrones-python/SKILL.md +228 -0
  315. package/habilidades/patrones-python/evals/evals.json +56 -0
  316. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -0
  317. package/habilidades/patrones-python/recursos/referencia-completa.md +202 -0
  318. package/habilidades/perfil-usuario/SKILL.md +200 -0
  319. package/habilidades/perfil-usuario/evals/evals.json +55 -0
  320. package/habilidades/performance-baseline/SKILL.md +297 -0
  321. package/habilidades/php-experto/SKILL.md +291 -0
  322. package/habilidades/php-patrones/SKILL.md +306 -0
  323. package/habilidades/php-testing/SKILL.md +280 -0
  324. package/habilidades/planear-fase/SKILL.md +269 -0
  325. package/habilidades/postgresql-experto/SKILL.md +151 -0
  326. package/habilidades/postgresql-experto/evals/evals.json +53 -0
  327. package/habilidades/postgresql-experto/recursos/referencia-completa.md +215 -0
  328. package/habilidades/prevencion-racionalizacion/SKILL.md +175 -0
  329. package/habilidades/prevencion-sobreingenieria/SKILL.md +323 -0
  330. package/habilidades/privacy-memoria/SKILL.md +141 -0
  331. package/habilidades/privacy-memoria/evals/evals.json +43 -0
  332. package/habilidades/prompt-engineering/SKILL.md +518 -0
  333. package/habilidades/prompt-engineering/recursos/patrones-avanzados.md +467 -0
  334. package/habilidades/rag-arquitectura/SKILL.md +338 -0
  335. package/habilidades/rails-experto/SKILL.md +237 -0
  336. package/habilidades/rails-experto/recursos/active-record.md +260 -0
  337. package/habilidades/rails-experto/recursos/hotwire-turbo.md +293 -0
  338. package/habilidades/rails-experto/recursos/testing-rspec.md +362 -0
  339. package/habilidades/react-experto/SKILL.md +209 -0
  340. package/habilidades/react-experto/evals/evals.json +55 -0
  341. package/habilidades/react-experto/recursos/patrones-y-ejemplos-completos.md +240 -0
  342. package/habilidades/react-optimizacion/SKILL.md +174 -0
  343. package/habilidades/react-optimizacion/recursos/patrones-avanzados.md +138 -0
  344. package/habilidades/redis-experto/SKILL.md +305 -0
  345. package/habilidades/release-semver/.evolved.json +9 -0
  346. package/habilidades/release-semver/SKILL.md +248 -0
  347. package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
  348. package/habilidades/rust-experto/SKILL.md +400 -0
  349. package/habilidades/rust-patrones/SKILL.md +296 -0
  350. package/habilidades/rust-testing/SKILL.md +311 -0
  351. package/habilidades/seguridad-skills-ia/SKILL.md +262 -0
  352. package/habilidades/sql-optimizacion/SKILL.md +200 -0
  353. package/habilidades/sql-optimizacion/evals/evals.json +54 -0
  354. package/habilidades/sql-optimizacion/recursos/patrones-sql-avanzados.md +131 -0
  355. package/habilidades/sre-patrones/SKILL.md +333 -0
  356. package/habilidades/sre-patrones/recursos/chaos-engineering.md +241 -0
  357. package/habilidades/sre-patrones/recursos/oncall-design.md +236 -0
  358. package/habilidades/stripe-pagos/SKILL.md +550 -0
  359. package/habilidades/stripe-pagos/recursos/errores-reintentos.md +390 -0
  360. package/habilidades/stripe-pagos/recursos/stripe-connect.md +290 -0
  361. package/habilidades/structured-outputs/SKILL.md +343 -0
  362. package/habilidades/swift-experto/SKILL.md +320 -0
  363. package/habilidades/swift-experto/recursos/keychain-y-wrappers.md +110 -0
  364. package/habilidades/swift-patrones/SKILL.md +313 -0
  365. package/habilidades/swift-patrones/recursos/tca-ejemplo-completo.md +113 -0
  366. package/habilidades/swift-testing/SKILL.md +254 -0
  367. package/habilidades/swift-testing/recursos/xcuitest-planes.md +143 -0
  368. package/habilidades/swl-dashboard/SKILL.md +370 -0
  369. package/habilidades/swl-markitdown/SKILL.md +285 -0
  370. package/habilidades/swl-markitdown/evals/evals.json +52 -0
  371. package/habilidades/swl-revisar-impacto/SKILL.md +233 -0
  372. package/habilidades/tailwind-experto/SKILL.md +240 -0
  373. package/habilidades/tailwind-experto/recursos/referencia-completa.md +184 -0
  374. package/habilidades/tdd-workflow/SKILL.md +293 -0
  375. package/habilidades/terraform-experto/SKILL.md +321 -0
  376. package/habilidades/testing-python/SKILL.md +340 -0
  377. package/habilidades/testing-python/recursos/ejemplos-completos.md +167 -0
  378. package/habilidades/threat-model-lite/SKILL.md +246 -0
  379. package/habilidades/tracing-processor/SKILL.md +212 -0
  380. package/habilidades/tracking-measurement/SKILL.md +239 -0
  381. package/habilidades/tracking-measurement/recursos/consent-mode.md +231 -0
  382. package/habilidades/tracking-measurement/recursos/gtm-datalayer.md +216 -0
  383. package/habilidades/tracking-measurement/recursos/meta-capi.md +262 -0
  384. package/habilidades/typescript-avanzado/SKILL.md +144 -0
  385. package/habilidades/typescript-avanzado/evals/evals.json +55 -0
  386. package/habilidades/typescript-avanzado/recursos/patrones-y-ejemplos-completos.md +298 -0
  387. package/habilidades/typescript-diagnosticos/SKILL.md +513 -0
  388. package/habilidades/ux-diseno/SKILL.md +116 -0
  389. package/habilidades/ux-diseno/evals/evals.json +43 -0
  390. package/habilidades/ux-diseno/recursos/patrones-ux-referencia.md +214 -0
  391. package/habilidades/validacion-ci-sistema/SKILL.md +136 -0
  392. package/habilidades/validacion-ci-sistema/recursos/validadores-completos.md +369 -0
  393. package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
  394. package/habilidades/verificacion-evidencia/SKILL.md +160 -0
  395. package/habilidades/verificar-trabajo/SKILL.md +303 -0
  396. package/habilidades/verificar-trabajo/recursos/plantilla-verificacion.md +60 -0
  397. package/habilidades/wiki-conocimiento/SKILL.md +276 -0
  398. package/habilidades/wireframes-flujos/SKILL.md +212 -0
  399. package/habilidades/wireframes-flujos/recursos/referencia-completa.md +192 -0
  400. package/habilidades/workflow-claude-code/SKILL.md +260 -0
  401. package/habilidades/workflow-claude-code/recursos/referencia-completa.md +109 -0
  402. package/hooks/_run-hook.sh +57 -0
  403. package/hooks/actualizar-perfil-usuario.js +364 -0
  404. package/hooks/agente-lifecycle.js +71 -0
  405. package/hooks/aiisms-detector.js +173 -0
  406. package/hooks/audit-trail.js +204 -0
  407. package/hooks/auto-background.js +97 -0
  408. package/hooks/auto-consolidacion.js +178 -0
  409. package/hooks/auto-evolucion.js +666 -0
  410. package/hooks/auto-restaurar-settings.js +360 -0
  411. package/hooks/calidad-pre-commit.js +929 -0
  412. package/hooks/calidad-typescript.js +511 -0
  413. package/hooks/captura-feedback-usuario.js +148 -0
  414. package/hooks/check-update.js +211 -0
  415. package/hooks/clasificador-mensajes.js +271 -0
  416. package/hooks/degradacion-instintos.js +272 -0
  417. package/hooks/escaneo-secretos.js +389 -0
  418. package/hooks/extraccion-aprendizajes.js +763 -0
  419. package/hooks/grafo-contexto.js +129 -0
  420. package/hooks/graph-update.js +67 -0
  421. package/hooks/guardrail-modelo.js +247 -0
  422. package/hooks/inbox-aviso.js +75 -0
  423. package/hooks/inyeccion-contexto.js +246 -0
  424. package/hooks/lib/abort-registry.js +214 -0
  425. package/hooks/lib/agent-backend.js +210 -0
  426. package/hooks/lib/agent-comms.js +263 -0
  427. package/hooks/lib/agent-issue-codes.js +284 -0
  428. package/hooks/lib/agent-matcher.js +189 -0
  429. package/hooks/lib/async-hook-registry.js +252 -0
  430. package/hooks/lib/atomic-write.js +130 -0
  431. package/hooks/lib/auto-consolidator.js +335 -0
  432. package/hooks/lib/canary-skills.js +187 -0
  433. package/hooks/lib/consolidation-lock.js +291 -0
  434. package/hooks/lib/context-builder.js +430 -0
  435. package/hooks/lib/context-compressor.js +657 -0
  436. package/hooks/lib/convergence-detector.js +105 -0
  437. package/hooks/lib/delegation-tracker.js +198 -0
  438. package/hooks/lib/detectar-package-manager.js +423 -0
  439. package/hooks/lib/edit-accumulator.js +171 -0
  440. package/hooks/lib/error-classifier.js +308 -0
  441. package/hooks/lib/event-bus.js +112 -0
  442. package/hooks/lib/evolution-tracker.js +442 -0
  443. package/hooks/lib/execution-state.js +316 -0
  444. package/hooks/lib/fingerprint-id.js +135 -0
  445. package/hooks/lib/gateway-notify.js +116 -0
  446. package/hooks/lib/graph-security.js +75 -0
  447. package/hooks/lib/guardrail-metrics.js +202 -0
  448. package/hooks/lib/hook-circuit-breaker.js +206 -0
  449. package/hooks/lib/loop-detector.js +267 -0
  450. package/hooks/lib/mcp-health.js +184 -0
  451. package/hooks/lib/mcp-pool.js +436 -0
  452. package/hooks/lib/memory-search.js +506 -0
  453. package/hooks/lib/merkle-audit.js +96 -0
  454. package/hooks/lib/model-router.js +222 -0
  455. package/hooks/lib/normalize-error.js +324 -0
  456. package/hooks/lib/normalize-input.js +65 -0
  457. package/hooks/lib/nudge-tracker.js +306 -0
  458. package/hooks/lib/otlp-exporter.js +365 -0
  459. package/hooks/lib/performance-marks.js +239 -0
  460. package/hooks/lib/privacy-filter.js +128 -0
  461. package/hooks/lib/prompt-injection-scanner.js +209 -0
  462. package/hooks/lib/provenance-tracker.js +183 -0
  463. package/hooks/lib/rate-limit-tracker.js +253 -0
  464. package/hooks/lib/reflect-classifier.js +164 -0
  465. package/hooks/lib/resource-quota.js +122 -0
  466. package/hooks/lib/retry-jitter.js +165 -0
  467. package/hooks/lib/risk-engine.js +368 -0
  468. package/hooks/lib/run-log.js +408 -0
  469. package/hooks/lib/session-fts.js +379 -0
  470. package/hooks/lib/session-store.js +293 -0
  471. package/hooks/lib/singleton-guard.js +159 -0
  472. package/hooks/lib/skill-auditor.js +588 -0
  473. package/hooks/lib/sync-status.js +228 -0
  474. package/hooks/lib/taint-tracker.js +107 -0
  475. package/hooks/lib/task-service.js +295 -0
  476. package/hooks/lib/tech-skills-map.js +146 -0
  477. package/hooks/lib/telegram-cliente.js +159 -0
  478. package/hooks/lib/telegram-config.js +170 -0
  479. package/hooks/lib/token-budget.js +156 -0
  480. package/hooks/lib/token-estimator.js +420 -0
  481. package/hooks/lib/toon-compressor.js +245 -0
  482. package/hooks/lib/usage-model.js +183 -0
  483. package/hooks/lib/variable-resolver.js +230 -0
  484. package/hooks/linea-estado.js +324 -0
  485. package/hooks/metricas-evolucion.js +209 -0
  486. package/hooks/monitor-contexto.js +325 -0
  487. package/hooks/notificacion-sesion-stop.js +198 -0
  488. package/hooks/notificacion-telegram-notification.js +4 -0
  489. package/hooks/notificacion-telegram-subagent.js +4 -0
  490. package/hooks/notificacion-telegram.js +267 -0
  491. package/hooks/preservar-estado-pre-compact.js +150 -0
  492. package/hooks/proteccion-rutas.js +366 -0
  493. package/hooks/registro-turnos.js +209 -0
  494. package/hooks/resumen-sesion.js +249 -0
  495. package/hooks/risk-scoring.js +323 -0
  496. package/hooks/rotar-audit-auto.js +122 -0
  497. package/hooks/sugerir-regenerar-inventario.js +170 -0
  498. package/hooks/telemetria-agentes.js +167 -0
  499. package/hooks/tracking-costos.js +688 -0
  500. package/instintos/global.yaml +8 -0
  501. package/instintos/perfil-usuario.yaml +53 -0
  502. package/instintos/prompt-appendices.yaml +57 -0
  503. package/instintos/proyecto.yaml +372 -0
  504. package/manifiestos/gateway-config.json +77 -0
  505. package/manifiestos/handoff-context.json +223 -0
  506. package/manifiestos/hook-profiles.json +44 -0
  507. package/manifiestos/hooks-config.json +360 -0
  508. package/manifiestos/modulos.json +1173 -0
  509. package/manifiestos/perfiles.json +404 -0
  510. package/package.json +86 -0
  511. package/plantillas/ESTADO.md +109 -0
  512. package/plantillas/HOJA-RUTA.md +143 -0
  513. package/plantillas/PROYECTO.md +122 -0
  514. package/plantillas/REQUISITOS.md +132 -0
  515. package/plantillas/auditor-veto-template.md +105 -0
  516. package/plantillas/github-workflows/README.md +47 -0
  517. package/plantillas/github-workflows/release-please.yml +44 -0
  518. package/plantillas/github-workflows/swl-ci.yml +107 -0
  519. package/plantillas/github-workflows/swl-security.yml +51 -0
  520. package/plantillas/mcp-mineru.json +13 -0
  521. package/plantillas/research/ARQUITECTURA.md +220 -0
  522. package/plantillas/research/FUNCIONALIDADES.md +175 -0
  523. package/plantillas/research/RESUMEN.md +165 -0
  524. package/plantillas/research/STACK.md +233 -0
  525. package/plantillas/research/TRAMPAS.md +299 -0
  526. package/plantillas/skill-evals-template.json +44 -0
  527. package/plugin.json +343 -0
  528. package/reglas/accesibilidad.md +269 -0
  529. package/reglas/api-diseno.md +400 -0
  530. package/reglas/arquitectura.md +352 -0
  531. package/reglas/brevedad-output.md +124 -0
  532. package/reglas/cloud-infra.md +247 -0
  533. package/reglas/docs.md +245 -0
  534. package/reglas/estilo-codigo.md +201 -0
  535. package/reglas/git-workflow.md +245 -0
  536. package/reglas/gobernanza.md +271 -0
  537. package/reglas/harness-claude-code.md +213 -0
  538. package/reglas/hooks.md +186 -0
  539. package/reglas/lenguajes/csharp/estilo-codigo.md +231 -0
  540. package/reglas/lenguajes/csharp/hooks.md +281 -0
  541. package/reglas/lenguajes/csharp/patrones.md +226 -0
  542. package/reglas/lenguajes/csharp/seguridad.md +258 -0
  543. package/reglas/lenguajes/csharp/testing.md +176 -0
  544. package/reglas/lenguajes/go/estilo-codigo.md +195 -0
  545. package/reglas/lenguajes/go/hooks.md +249 -0
  546. package/reglas/lenguajes/go/patrones.md +249 -0
  547. package/reglas/lenguajes/go/seguridad.md +225 -0
  548. package/reglas/lenguajes/go/testing.md +272 -0
  549. package/reglas/lenguajes/java/estilo-codigo.md +217 -0
  550. package/reglas/lenguajes/java/hooks.md +251 -0
  551. package/reglas/lenguajes/java/patrones.md +226 -0
  552. package/reglas/lenguajes/java/seguridad.md +233 -0
  553. package/reglas/lenguajes/java/testing.md +238 -0
  554. package/reglas/lenguajes/kotlin/estilo-codigo.md +208 -0
  555. package/reglas/lenguajes/kotlin/hooks.md +245 -0
  556. package/reglas/lenguajes/kotlin/patrones.md +201 -0
  557. package/reglas/lenguajes/kotlin/seguridad.md +202 -0
  558. package/reglas/lenguajes/kotlin/testing.md +236 -0
  559. package/reglas/lenguajes/nextjs/estilo-codigo.md +175 -0
  560. package/reglas/lenguajes/nextjs/hooks.md +186 -0
  561. package/reglas/lenguajes/nextjs/patrones.md +225 -0
  562. package/reglas/lenguajes/nextjs/seguridad.md +216 -0
  563. package/reglas/lenguajes/nextjs/testing.md +193 -0
  564. package/reglas/lenguajes/php/estilo-codigo.md +228 -0
  565. package/reglas/lenguajes/php/hooks.md +165 -0
  566. package/reglas/lenguajes/php/patrones.md +233 -0
  567. package/reglas/lenguajes/php/seguridad.md +186 -0
  568. package/reglas/lenguajes/php/testing.md +205 -0
  569. package/reglas/lenguajes/rust/estilo-codigo.md +207 -0
  570. package/reglas/lenguajes/rust/hooks.md +240 -0
  571. package/reglas/lenguajes/rust/patrones.md +250 -0
  572. package/reglas/lenguajes/rust/seguridad.md +221 -0
  573. package/reglas/lenguajes/rust/testing.md +194 -0
  574. package/reglas/lenguajes/swift/estilo-codigo.md +238 -0
  575. package/reglas/lenguajes/swift/hooks.md +257 -0
  576. package/reglas/lenguajes/swift/patrones.md +235 -0
  577. package/reglas/lenguajes/swift/seguridad.md +248 -0
  578. package/reglas/lenguajes/swift/testing.md +242 -0
  579. package/reglas/markitdown.md +60 -0
  580. package/reglas/memoria-consolidada.md +209 -0
  581. package/reglas/patrones.md +225 -0
  582. package/reglas/performance.md +195 -0
  583. package/reglas/pruebas.md +159 -0
  584. package/reglas/seguridad-agentes.md +351 -0
  585. package/reglas/seguridad.md +151 -0
  586. package/reglas/skills-estandar.md +373 -0
  587. package/reglas/testing.md +193 -0
  588. package/schemas/agent-contract.json +176 -0
  589. package/schemas/agent-frontmatter.schema.json +149 -0
  590. package/schemas/agent-message.schema.json +53 -0
  591. package/schemas/agent-output-implementacion.schema.json +85 -0
  592. package/schemas/agent-output-planificacion.schema.json +113 -0
  593. package/schemas/agent-output-review.schema.json +78 -0
  594. package/schemas/diary-entry.schema.json +80 -0
  595. package/schemas/hook-profiles.schema.json +39 -0
  596. package/schemas/hooks-config.schema.json +74 -0
  597. package/schemas/instinct.schema.json +115 -0
  598. package/schemas/modulos.schema.json +29 -0
  599. package/schemas/perfiles.schema.json +28 -0
  600. package/schemas/plugin.schema.json +64 -0
  601. package/schemas/skill-evals.schema.json +95 -0
  602. package/schemas/skill-frontmatter.schema.json +170 -0
  603. package/scripts/actualizar.js +145 -0
  604. package/scripts/audit-skills.sh +78 -0
  605. package/scripts/auditar-agentes-gaps.js +149 -0
  606. package/scripts/auditar-cobertura-frameworks.js +241 -0
  607. package/scripts/auditar-skills-gaps.js +206 -0
  608. package/scripts/bootstrap-instintos.js +259 -0
  609. package/scripts/check-update.js +109 -0
  610. package/scripts/comandos/agents.js +105 -0
  611. package/scripts/comandos/info.js +108 -0
  612. package/scripts/comandos/install-asistido.js +186 -0
  613. package/scripts/comandos/skills.js +211 -0
  614. package/scripts/configurar-branch-protection.js +418 -0
  615. package/scripts/daemon-swl.py +388 -0
  616. package/scripts/desinstalar.js +130 -0
  617. package/scripts/doctor.js +559 -0
  618. package/scripts/field-report.js +199 -0
  619. package/scripts/generar-inventario.js +317 -0
  620. package/scripts/inbox-tmux-inject.js +161 -0
  621. package/scripts/inferir-herramientas-permitidas.js +586 -0
  622. package/scripts/inicializar.js +133 -0
  623. package/scripts/instalador.js +1031 -0
  624. package/scripts/instalar-git-hook.js +122 -0
  625. package/scripts/lib/agp-frontmatter.js +222 -0
  626. package/scripts/lib/append-con-marcadores.js +199 -0
  627. package/scripts/lib/artefactos-python.js +43 -0
  628. package/scripts/lib/audit-query.js +221 -0
  629. package/scripts/lib/autostart-linux.js +347 -0
  630. package/scripts/lib/autostart-macos.js +360 -0
  631. package/scripts/lib/autostart-windows.js +307 -0
  632. package/scripts/lib/budget-enforcer.js +252 -0
  633. package/scripts/lib/claude-sessions.js +285 -0
  634. package/scripts/lib/configurar-ci.js +380 -0
  635. package/scripts/lib/console-span-exporter.js +92 -0
  636. package/scripts/lib/contadores-inventario.js +217 -0
  637. package/scripts/lib/dashboard-widgets.js +290 -0
  638. package/scripts/lib/detectar-runtime.js +279 -0
  639. package/scripts/lib/detectar-stack.js +187 -0
  640. package/scripts/lib/diary-entry.js +234 -0
  641. package/scripts/lib/drift-detector.js +545 -0
  642. package/scripts/lib/estado.js +124 -0
  643. package/scripts/lib/gestor-componentes.js +243 -0
  644. package/scripts/lib/gitignore-manifest.js +305 -0
  645. package/scripts/lib/graph-analyze.py +556 -0
  646. package/scripts/lib/graph-builder.py +485 -0
  647. package/scripts/lib/graph-cluster.py +259 -0
  648. package/scripts/lib/health-row.js +168 -0
  649. package/scripts/lib/hooks-settings.js +789 -0
  650. package/scripts/lib/manifiestos.js +138 -0
  651. package/scripts/lib/mc-client.js +137 -0
  652. package/scripts/lib/notificaciones-telegram.js +1107 -0
  653. package/scripts/lib/npm-version.js +261 -0
  654. package/scripts/lib/paquetes-conocidos.js +50 -0
  655. package/scripts/lib/preservar-usuario.js +586 -0
  656. package/scripts/lib/prompt-builder.js +264 -0
  657. package/scripts/lib/resolver-externo.js +332 -0
  658. package/scripts/lib/schedule-parser.js +305 -0
  659. package/scripts/lib/scoring-instintos.js +240 -0
  660. package/scripts/lib/seguridad.js +160 -0
  661. package/scripts/lib/selector-interactivo.js +152 -0
  662. package/scripts/lib/semantic-search.js +242 -0
  663. package/scripts/lib/skill-discovery.js +234 -0
  664. package/scripts/lib/skill-metrics.js +246 -0
  665. package/scripts/lib/skill-normalizer.js +112 -0
  666. package/scripts/lib/skills-hub.js +340 -0
  667. package/scripts/lib/span-schema.js +134 -0
  668. package/scripts/lib/tool-cost-analyzer.js +255 -0
  669. package/scripts/lib/tracing-processor-interface.js +286 -0
  670. package/scripts/lib/transformadores/base.js +80 -0
  671. package/scripts/lib/transformadores/claude.js +124 -0
  672. package/scripts/lib/transformadores/codex.js +115 -0
  673. package/scripts/lib/transformadores/copilot.js +106 -0
  674. package/scripts/lib/transformadores/gemini.js +74 -0
  675. package/scripts/lib/transformadores/index.js +35 -0
  676. package/scripts/lib/transformadores/opencode.js +75 -0
  677. package/scripts/lib/ui.js +259 -0
  678. package/scripts/limpiar-artefactos-python.js +131 -0
  679. package/scripts/mcp-orchestrator.py +386 -0
  680. package/scripts/mcp-pool-manager.py +352 -0
  681. package/scripts/mcp-telemetry.py +378 -0
  682. package/scripts/poblar-evolvable.js +226 -0
  683. package/scripts/publicar.js +287 -0
  684. package/scripts/reflect-skills.js +403 -0
  685. package/scripts/rotar-audit-logs.js +185 -0
  686. package/scripts/run-skill-evals.js +242 -0
  687. package/scripts/smoke-test.js +374 -0
  688. package/scripts/token-analysis.py +471 -0
  689. package/scripts/validar-manifest.js +195 -0
  690. package/scripts/validar-memoria.js +321 -0
  691. package/scripts/validar-tests-aislamiento.js +184 -0
  692. package/scripts/validar-tokens-test.js +208 -0
  693. package/scripts/validar.js +147 -0
  694. package/scripts/validate-markdown.py +339 -0
  695. package/scripts/validate-skills.py +385 -0
  696. package/scripts/vendor/claude-usage/README.md +116 -0
  697. package/scripts/vendor/claude-usage/cli.py +334 -0
  698. package/scripts/vendor/claude-usage/dashboard.py +795 -0
  699. package/scripts/vendor/claude-usage/scanner.py +467 -0
  700. package/scripts/vendor/markitdown/cli.py +194 -0
  701. package/scripts/verificar-evolucion.js +289 -0
  702. package/scripts/verificar-release.js +494 -0
@@ -0,0 +1,167 @@
1
+ # Testing Python — Ejemplos completos y referencia
2
+
3
+ ## Mocking con unittest.mock y pytest-mock
4
+
5
+ ```python
6
+ from unittest.mock import MagicMock, AsyncMock, patch
7
+ import pytest
8
+
9
+ # Mock de una función de módulo
10
+ def test_crear_factura_llama_servicio_timbre(factura_service, mock_timbre):
11
+ with patch("app.services.factura_service.timbre_service") as mock_timbre:
12
+ mock_timbre.timbrar = MagicMock(return_value={"uuid": "abc-123"})
13
+
14
+ factura = factura_service.crear(datos_validos)
15
+
16
+ mock_timbre.timbrar.assert_called_once_with(factura)
17
+ assert factura.uuid_timbre == "abc-123"
18
+
19
+ # Con pytest-mock (más limpio)
20
+ def test_notificacion_enviada(mocker, factura_service):
21
+ mock_email = mocker.patch("app.services.email_service.enviar")
22
+
23
+ factura_service.emitir(factura_id="fac-123")
24
+
25
+ mock_email.assert_called_once()
26
+ llamada = mock_email.call_args
27
+ assert llamada.kwargs["destinatario"] == "cliente@empresa.com"
28
+
29
+ # Mock de async
30
+ async def test_obtener_usuario_llama_api_externa(mocker):
31
+ mock_get = mocker.patch("httpx.AsyncClient.get", new_callable=AsyncMock)
32
+ mock_get.return_value.json.return_value = {"id": "u1", "nombre": "Ana"}
33
+ mock_get.return_value.status_code = 200
34
+
35
+ usuario = await servicio.obtener_usuario("u1")
36
+
37
+ assert usuario.nombre == "Ana"
38
+ mock_get.assert_awaited_once()
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Testing async con pytest-asyncio
44
+
45
+ ```python
46
+ # pyproject.toml
47
+ # [tool.pytest.ini_options]
48
+ # asyncio_mode = "auto" # Marcar todos los tests async automáticamente
49
+
50
+ import pytest
51
+ from httpx import AsyncClient, ASGITransport
52
+
53
+ @pytest.mark.asyncio
54
+ async def test_crear_factura_endpoint(async_client: AsyncClient):
55
+ respuesta = await async_client.post(
56
+ "/api/v1/facturas/",
57
+ json={
58
+ "folio": "F-001",
59
+ "fecha": "2026-03-25",
60
+ "subtotal": "1000.00",
61
+ "cliente_id": "cliente-123",
62
+ },
63
+ headers={"Authorization": "Bearer token-test"},
64
+ )
65
+ assert respuesta.status_code == 201
66
+ data = respuesta.json()
67
+ assert data["estatus"] == "borrador"
68
+ assert "id" in data
69
+
70
+ @pytest.fixture
71
+ async def async_client(app, async_db):
72
+ async with AsyncClient(
73
+ transport=ASGITransport(app=app),
74
+ base_url="http://test",
75
+ ) as client:
76
+ yield client
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Factories con factory_boy
82
+
83
+ ```python
84
+ # tests/factories.py
85
+ import factory
86
+ from decimal import Decimal
87
+ from datetime import date
88
+ from app.models import Factura, Cliente, Item
89
+
90
+ class ClienteFactory(factory.Factory):
91
+ class Meta:
92
+ model = Cliente
93
+
94
+ id = factory.Sequence(lambda n: f"cliente-{n:05d}")
95
+ nombre = factory.Faker("company", locale="es_MX")
96
+ rfc = factory.LazyFunction(lambda: f"RFC{factory.Faker('numerify', text='######')}")
97
+ activo = True
98
+
99
+ class ItemFactory(factory.Factory):
100
+ class Meta:
101
+ model = Item
102
+
103
+ descripcion = factory.Faker("sentence", nb_words=4, locale="es_MX")
104
+ cantidad = factory.Faker("pyint", min_value=1, max_value=10)
105
+ precio_unitario = factory.Faker("pydecimal", min_value=10, max_value=1000,
106
+ right_digits=2)
107
+
108
+ class FacturaFactory(factory.Factory):
109
+ class Meta:
110
+ model = Factura
111
+
112
+ id = factory.Sequence(lambda n: f"fac-{n:05d}")
113
+ folio = factory.Sequence(lambda n: f"F-{n:05d}")
114
+ fecha = factory.LazyFunction(date.today)
115
+ estatus = "borrador"
116
+ cliente = factory.SubFactory(ClienteFactory)
117
+ items = factory.List([factory.SubFactory(ItemFactory)])
118
+
119
+ # Uso en tests
120
+ def test_calcular_total():
121
+ items = [ItemFactory(cantidad=2, precio_unitario=Decimal("100.00"))]
122
+ factura = FacturaFactory(items=items)
123
+ assert factura.calcular_total() == Decimal("200.00")
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Anti-patrones en tests
129
+
130
+ ```python
131
+ # MAL: test que verifica demasiado
132
+ def test_factura():
133
+ f = Factura(...)
134
+ assert f.folio == "F-001"
135
+ assert f.estatus == "borrador"
136
+ assert f.total == 1160
137
+ assert f.cliente.nombre == "Acme"
138
+ assert f.puede_cancelar() == True
139
+ # ... 10 asserts más
140
+
141
+ # BIEN: un comportamiento por test
142
+ def test_factura_nueva_tiene_estatus_borrador():
143
+ factura = FacturaFactory()
144
+ assert factura.estatus == "borrador"
145
+
146
+ def test_factura_calcula_total_con_iva():
147
+ factura = FacturaFactory(subtotal=Decimal("1000.00"), tasa_iva=0.16)
148
+ assert factura.total == Decimal("1160.00")
149
+
150
+ # MAL: lógica de negocio en los tests
151
+ def test_calcular_descuento():
152
+ if monto > 1000: # lógica duplicada del código de producción
153
+ esperado = monto * 0.1
154
+ else:
155
+ esperado = 0
156
+ assert calcular_descuento(monto) == esperado
157
+
158
+ # BIEN: valores concretos y explícitos
159
+ @pytest.mark.parametrize("monto,descuento_esperado", [
160
+ (500, Decimal("0.00")),
161
+ (1000, Decimal("0.00")),
162
+ (1001, Decimal("100.10")),
163
+ (2000, Decimal("200.00")),
164
+ ])
165
+ def test_calcular_descuento(monto, descuento_esperado):
166
+ assert calcular_descuento(monto) == descuento_esperado
167
+ ```
@@ -0,0 +1,246 @@
1
+ ---
2
+ name: threat-model-lite
3
+ description: Modelado de amenazas ligero basado en STRIDE simplificado. Identifica la superficie de ataque del sistema, los activos críticos, los flujos de datos sensibles y genera mitigaciones priorizadas. Diseñado para completarse en una sesión de trabajo, no en semanas.
4
+ version: "1.0.0"
5
+ herramientasPermitidas: [Read, Grep]
6
+ evolvable: true # default para skill estandar
7
+ nist_csf: [ID.RA-01, ID.RA-03, ID.RA-04]
8
+ nist_ai_rmf: [MAP-1.1, MAP-5.1, MAP-5.2]
9
+ exclusiones:
10
+ - "No cargar para implementar las mitigaciones técnicas identificadas (RBAC, rate limiting, TLS) — threat model produce el diagnóstico; para implementación cargar el skill del stack correspondiente."
11
+ - "No cargar para auditoría de código buscando vulnerabilidades específicas (SQL injection, XSS en código) — para revisión de código de seguridad cargar `checklist-seguridad` o el skill de revisión del lenguaje."
12
+ - "No cargar para análisis de cumplimiento normativo (PCI-DSS, SOC 2, ISO 27001) — el threat model es una entrada para el compliance, no el análisis de cumplimiento completo."
13
+ - "No cargar para red-teaming o pruebas de penetración activas — threat model es análisis estático; para pentest activo usar herramientas especializadas con autorización explícita."
14
+ ---
15
+ # Habilidad: Threat Model Lite
16
+
17
+ ## Cuándo NO cargar
18
+
19
+ - La tarea es implementar las mitigaciones identificadas (RBAC, rate limiting, TLS): usar el skill del stack correspondiente para la implementación.
20
+ - La tarea es revisión de código buscando vulnerabilidades: cargar `checklist-seguridad`.
21
+ - La tarea es análisis de cumplimiento normativo (PCI-DSS, SOC 2): el threat model es una entrada, no el análisis completo.
22
+ - La tarea es pentest activo o red-teaming: usar herramientas especializadas con autorización explícita.
23
+
24
+ ## Propósito
25
+
26
+ Un threat model completo toma semanas. Esta versión toma entre 2 y 4 horas y
27
+ cubre el 80% de los riesgos reales. El objetivo no es ser exhaustivo — es
28
+ identificar las amenazas de mayor impacto antes de que lleguen a producción.
29
+
30
+ ## Cuándo activar
31
+
32
+ - Al diseñar un nuevo sistema o módulo crítico
33
+ - Antes del primer deploy a producción de una aplicación nueva
34
+ - Cuando el sistema maneja datos PII, financieros o de salud
35
+ - Cuando se añade una nueva integración con sistemas externos
36
+ - Como parte de la revisión de seguridad trimestral
37
+
38
+ ---
39
+
40
+ ## Paso 1 — Definir el alcance en 15 minutos
41
+
42
+ Responder estas 4 preguntas antes de proceder:
43
+
44
+ 1. **¿Qué estamos protegiendo?** (activos: datos, dinero, reputación, disponibilidad)
45
+ 2. **¿De quién lo protegemos?** (actores: usuarios maliciosos, atacantes externos,
46
+ empleados deshonestos, errores accidentales)
47
+ 3. **¿Cuál sería el peor escenario?** (impacto: pérdida de datos, fraude, downtime)
48
+ 4. **¿Cuál es el perímetro del análisis?** (módulo específico, sistema completo,
49
+ integración puntual)
50
+
51
+ Si no puedes responder estas preguntas, detente y habla con el stakeholder antes
52
+ de continuar.
53
+
54
+ ---
55
+
56
+ ## Paso 2 — Mapear la superficie de ataque
57
+
58
+ ### Diagrama de flujo de datos (DFD simplificado)
59
+
60
+ Identificar y documentar:
61
+
62
+ **Puntos de entrada** (donde datos externos entran al sistema):
63
+ - [ ] Endpoints HTTP/REST públicos
64
+ - [ ] Endpoints autenticados
65
+ - [ ] Webhooks recibidos de sistemas externos
66
+ - [ ] Archivos cargados por usuarios
67
+ - [ ] Variables de entorno y configuración
68
+ - [ ] Mensajes de colas (Kafka, RabbitMQ, SQS)
69
+ - [ ] Interfaces de línea de comandos (CLI)
70
+
71
+ **Flujos de datos sensibles** (donde los datos críticos viajan):
72
+ - [ ] Datos de usuario en tránsito (login, sesión)
73
+ - [ ] Datos financieros (pagos, montos, cuentas)
74
+ - [ ] PII en requests/responses
75
+ - [ ] Tokens y credenciales en headers
76
+ - [ ] Datos en logs
77
+ - [ ] Datos exportados (CSV, PDF, reportes)
78
+
79
+ **Límites de confianza** (dónde cambia el nivel de confianza):
80
+ - [ ] Internet → API Gateway / Load Balancer
81
+ - [ ] API → Base de datos
82
+ - [ ] Microservicio A → Microservicio B
83
+ - [ ] Sistema interno → Sistema externo
84
+
85
+ ---
86
+
87
+ ## Paso 3 — STRIDE simplificado
88
+
89
+ Para cada punto de entrada y flujo de datos, evaluar las 6 categorías STRIDE:
90
+
91
+ ### S — Spoofing (Suplantación de identidad)
92
+ **Pregunta**: ¿Puede un atacante hacerse pasar por un usuario legítimo?
93
+ - Autenticación débil o ausente en algún endpoint
94
+ - Tokens sin expiración o sin firma válida
95
+ - No verificación de origen en webhooks
96
+ - Reset de contraseña sin validación de identidad
97
+
98
+ ### T — Tampering (Manipulación de datos)
99
+ **Pregunta**: ¿Puede un atacante modificar datos en tránsito o en reposo?
100
+ - Comunicación HTTP (no HTTPS) entre componentes internos
101
+ - HMAC ausente en mensajes de colas
102
+ - Validación insuficiente de inputs antes de persistir
103
+ - Archivos subidos sin verificación de integridad
104
+
105
+ ### R — Repudiation (Repudio)
106
+ **Pregunta**: ¿Puede un actor negar haber realizado una acción?
107
+ - Acciones críticas sin audit log
108
+ - Logs sin timestamp confiable o sin integridad garantizada
109
+ - Sin registro de IP/agente en acciones de alto riesgo
110
+
111
+ ### I — Information Disclosure (Divulgación de información)
112
+ **Pregunta**: ¿Puede un atacante acceder a información que no debería ver?
113
+ - Stack traces expuestos en respuestas de error
114
+ - Datos sensibles en logs
115
+ - Respuestas de API que revelan más de lo necesario
116
+ - Endpoints de debug accesibles en producción
117
+ - IDOR: acceso a recursos de otros usuarios
118
+
119
+ ### D — Denial of Service (Denegación de servicio)
120
+ **Pregunta**: ¿Puede un atacante degradar o eliminar el servicio?
121
+ - Sin rate limiting en endpoints públicos
122
+ - Queries sin límite de resultados (full table scan por input del usuario)
123
+ - Archivos de tamaño ilimitado aceptados
124
+ - Operaciones costosas sin throttling
125
+
126
+ ### E — Elevation of Privilege (Escalación de privilegios)
127
+ **Pregunta**: ¿Puede un usuario normal obtener permisos de administrador?
128
+ - RBAC incompleto o con brechas
129
+ - Endpoints de admin sin verificación de rol
130
+ - Parámetros de rol aceptados del cliente sin validación del servidor
131
+ - Tokens JWT con claims manipulables
132
+
133
+ ---
134
+
135
+ ## Paso 4 — Identificar activos críticos
136
+
137
+ Clasificar los activos del sistema por impacto si se comprometen:
138
+
139
+ | Activo | Tipo | Impacto si comprometido | Nivel |
140
+ |--------|------|------------------------|-------|
141
+ | Contraseñas de usuarios | PII + Auth | Acceso no autorizado a cuentas | CRÍTICO |
142
+ | Datos financieros | Financiero | Pérdida monetaria / fraude | CRÍTICO |
143
+ | PII (nombre, email, RFC) | PII | Violación de privacidad / LFPDPPP | ALTO |
144
+ | Tokens JWT | Auth | Suplantación de identidad | ALTO |
145
+ | Logs de acceso | Operacional | Pérdida de auditoría | MEDIO |
146
+ | Datos de configuración | Operacional | Exposición de infraestructura | MEDIO |
147
+
148
+ ---
149
+
150
+ ## Paso 5 — Generar mitigaciones priorizadas
151
+
152
+ Usar la matriz de riesgo para priorizar:
153
+
154
+ ```
155
+ Riesgo = Probabilidad × Impacto
156
+
157
+ Probabilidad: 1 (baja) → 5 (casi seguro)
158
+ Impacto: 1 (insignificante) → 5 (crítico)
159
+ Prioridad: [1-5] Baja | [6-14] Media | [15-25] Alta
160
+ ```
161
+
162
+ Para cada amenaza STRIDE encontrada, generar:
163
+
164
+ ```markdown
165
+ ### [ID-001] [Nombre de la amenaza]
166
+ - **Categoría STRIDE**: [S/T/R/I/D/E]
167
+ - **Activo afectado**: [nombre del activo]
168
+ - **Flujo de datos**: [de dónde a dónde]
169
+ - **Descripción del ataque**: [cómo un atacante lo exploraría]
170
+ - **Probabilidad**: [1-5] | **Impacto**: [1-5] | **Riesgo**: [producto]
171
+ - **Mitigación propuesta**: [solución técnica específica]
172
+ - **Costo de mitigación**: [Bajo/Medio/Alto]
173
+ - **Estado**: Pendiente / En progreso / Mitigado / Aceptado
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Plantilla de salida: `THREAT-MODEL.md`
179
+
180
+ ```markdown
181
+ # THREAT-MODEL.md — [Nombre del Sistema]
182
+ **Fecha**: [fecha] **Versión**: [N] **Autor**: [agente/persona]
183
+
184
+ ## Alcance
185
+ [Descripción del sistema y qué está dentro/fuera del análisis]
186
+
187
+ ## Activos críticos
188
+ | Activo | Nivel | Propietario |
189
+ |--------|-------|------------|
190
+ | | | |
191
+
192
+ ## Superficie de ataque
193
+ ### Puntos de entrada
194
+ - [lista]
195
+
196
+ ### Flujos de datos sensibles
197
+ - [lista]
198
+
199
+ ### Límites de confianza
200
+ - [lista]
201
+
202
+ ## Amenazas identificadas
203
+ [Para cada amenaza, la ficha del formato anterior]
204
+
205
+ ## Resumen de riesgos
206
+ | ID | Amenaza | Riesgo | Estado |
207
+ |----|---------|--------|--------|
208
+ | | | | |
209
+
210
+ ## Plan de mitigación (priorizado)
211
+ | Prioridad | ID | Acción | Responsable | Fecha límite |
212
+ |-----------|---|--------|-------------|-------------|
213
+ | 1 (ALTO) | | | | |
214
+ | 2 (MEDIO) | | | | |
215
+
216
+ ## Amenazas aceptadas (con justificación)
217
+ | ID | Amenaza | Justificación | Quién aceptó |
218
+ |----|---------|--------------|-------------|
219
+ | | | | |
220
+
221
+ ## Próxima revisión
222
+ **Fecha**: [fecha de revisión] o cuando ocurra: [evento trigger]
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Triggers para actualizar el modelo
228
+
229
+ El threat model debe revisarse cuando:
230
+ - Se añade un nuevo punto de entrada al sistema
231
+ - Se integra un servicio externo nuevo
232
+ - Se cambia el mecanismo de autenticación
233
+ - Los datos que maneja el sistema cambian de clasificación
234
+ - Se detecta una vulnerabilidad en producción
235
+
236
+ ---
237
+
238
+ ## Gotchas / Errores comunes no obvios
239
+
240
+ **El STRIDE simplificado de este skill omite sistemáticamente amenazas de "confused deputy" donde un servicio interno con privilegios elevados ejecuta acciones en nombre de un actor de menor privilegio sin verificar la identidad original**: en un microservicio de reportes que llama al microservicio de pagos usando credenciales de servicio (no del usuario), un atacante que compromete el microservicio de reportes puede consultar pagos de cualquier usuario. Causa: STRIDE evalúa cada componente aisladamente; las amenazas confused deputy emergen en la interacción entre dos límites de confianza. Fix: al mapear límites de confianza en el Paso 2, agregar explícitamente la pregunta: "¿Este servicio actúa en nombre de un actor? ¿Verifica que la acción solicitada está autorizada para ese actor específico?" Documentar la identidad que fluye entre servicios en el DFD.
241
+
242
+ **Las mitigaciones de prioridad calculadas con `Probabilidad × Impacto` son inconsistentes entre revisores porque la escala 1-5 es subjetiva y dos ingenieros pueden asignar probabilidad 2 vs 4 a la misma amenaza según su experiencia personal**: un equipo que usa el threat model sin calibración previa genera matrices de riesgo donde "SQL injection en el endpoint de búsqueda" tiene riesgo 6 para un revisor (Prob=2, Imp=3) y riesgo 20 para otro (Prob=4, Imp=5). Causa: las escalas ordinales sin anclas concretas son inherentemente subjetivas. Fix: antes de la sesión, calibrar la escala con 2-3 amenazas históricas conocidas del sector: "CVE-XXXX-YYYY tuvo Probabilidad=4 porque fue explotado activamente en los 6 meses anteriores al parche". Las anclas históricas reducen la varianza entre revisores.
243
+
244
+ **El THREAT-MODEL.md marcado como "Mitigado" para una amenaza de IDOR queda obsoleto en 3 meses cuando se agrega un nuevo endpoint de API que expone el mismo recurso sin la verificación de autorización implementada en los endpoints originales**: el threat model registra que "IDOR en `/api/v1/pedidos/{id}`" fue mitigado, pero el endpoint nuevo `/api/v2/orders/{id}` (agregado en sprint 14) no fue evaluado y tiene el mismo vector. Causa: el threat model es un documento puntual; los cambios incrementales al sistema no lo actualizan automáticamente. Fix: en el mapa de propagación de cambios del proyecto, agregar una regla: "nuevo endpoint en `api/` → verificar si el THREAT-MODEL.md cubre el nuevo recurso expuesto". Revisar las amenazas de tipo I (Information Disclosure) y E (Elevation of Privilege) del modelo cada vez que se añade un endpoint.
245
+
246
+ **La categoría S (Spoofing) suele generar mitigaciones de "agregar autenticación" que quedan como ítems en el backlog indefinidamente porque no tienen criterio de aceptación técnico medible**: la mitigación "implementar autenticación JWT en el endpoint" sin especificar qué claims verificar, qué algoritmo usar, qué TTL del token, ni cómo manejar revocación es inaccionable. El ticket se cierra cuando se agrega "cualquier autenticación" aunque sea trivialmente bypasseable. Causa: las mitigaciones STRIDE son descripciones de objetivo, no especificaciones técnicas. Fix: para cada mitigación en el plan de acción, agregar los criterios de aceptación mínimos: "Verificar firma RS256, audience claim = 'api.mi-sistema.com', exp < now() + 1h, validar contra JWKS endpoint del IdP. Test: request sin token retorna 401, request con token expirado retorna 401, request con audience incorrecta retorna 401."
@@ -0,0 +1,212 @@
1
+ ---
2
+ name: tracing-processor
3
+ description: Documenta el patrón TracingProcessor para el sistema de trazabilidad SWL. Cómo crear exportadores de trazas (Langfuse, Jaeger, consola) sin modificar el núcleo, usando la interfaz formal en scripts/lib/tracing-processor-interface.js. Cargar cuando se implementa un exportador de trazas nuevo, se integra observabilidad externa, o se usa MultiProcessor.
4
+ version: "1.0.0"
5
+ herramientasPermitidas: [Read, Write]
6
+ exclusiones:
7
+ - "No cargar para leer trazas ya generadas en `.planning/traces/` — eso es lectura directa de JSONL con el Read tool o con `drift-detection`; este skill documenta cómo implementar nuevos exportadores, no cómo consumir trazas."
8
+ - "No cargar para agregar observabilidad a hooks que no son parte del pipeline de trazabilidad — los hooks que registran eventos en `nudges.jsonl`, `alertas-persistentes.json` o archivos de estado no son TracingProcessors; este skill es exclusivo para exportadores de spans del ciclo de vida de agentes."
9
+ - "No cargar para depurar por qué un agente falla — las trazas son observabilidad, no diagnóstico de bugs; para bugs usar `depurador-swl` o revisar los logs del hook directamente."
10
+ - "No cargar si el exportador objetivo ya está implementado en `hooks/lib/otlp-exporter.js` y solo necesita configuración vía variable de entorno — los exportadores existentes se activan con variables opt-in, no requieren código nuevo."
11
+ evolvable: true
12
+ evolvable_scope:
13
+ - content
14
+ - examples
15
+ - anti-patterns
16
+ ---
17
+ # Habilidad: TracingProcessor — Exportadores de Trazas
18
+
19
+ ## Propósito del patrón
20
+
21
+ El sistema SWL ya registra spans en `.planning/traces/YYYY-MM-DD.jsonl` vía
22
+ `hooks/lib/otlp-exporter.js`. Sin la interfaz formal, agregar un segundo
23
+ destino de exportación (Langfuse, Jaeger, consola) requeriría modificar ese
24
+ archivo — violando el principio Open/Closed.
25
+
26
+ **TracingProcessor** resuelve esto: define un contrato que cualquier exportador
27
+ debe cumplir. El núcleo (`hooks/telemetria-agentes.js`) solo conoce la interfaz;
28
+ los destinos concretos son plugins intercambiables.
29
+
30
+ Beneficios:
31
+ - Agregar destinos sin tocar código existente.
32
+ - Combinar múltiples destinos con `MultiProcessor` (patrón Composite).
33
+ - Testear exportadores de forma aislada.
34
+
35
+ ---
36
+
37
+ ## Contrato de la interfaz
38
+
39
+ Archivo: `scripts/lib/tracing-processor-interface.js`
40
+
41
+ | Método | Cuándo se invoca | Responsabilidad |
42
+ |--------|-----------------|----------------|
43
+ | `onTraceStart(traza)` | Al iniciar una traza de alto nivel | Registrar inicio, crear buffer si aplica |
44
+ | `onTraceEnd(traza)` | Al finalizar una traza completa | Exportar la traza completa, liberar buffer |
45
+ | `onSpanStart(span)` | Al iniciar un span individual | Registrar inicio del span |
46
+ | `onSpanEnd(span)` | Al finalizar un span (datos completos disponibles) | Punto principal de exportación |
47
+ | `shutdown()` | Al detener la aplicación | Vaciar buffers, cerrar archivos/conexiones |
48
+ | `forceFlush()` | Antes de shutdown o cuando se necesita garantía | Forzar volcado de colas internas |
49
+
50
+ Reglas del contrato:
51
+ - Los métodos deben retornar rápidamente. Usar colas internas para I/O lento.
52
+ - Los errores internos no deben propagarse al caller.
53
+ - Todos los métodos son síncronos por contrato; las subclases usan colas async internamente.
54
+
55
+ ---
56
+
57
+ ## Cómo crear un exportador alterno
58
+
59
+ ### Paso 1 — Extender la clase abstracta
60
+
61
+ ```js
62
+ 'use strict';
63
+ const { TracingProcessor } = require('../../scripts/lib/tracing-processor-interface');
64
+
65
+ class MiExportador extends TracingProcessor {
66
+ constructor(opciones = {}) {
67
+ super();
68
+ this._buffer = [];
69
+ this._destino = opciones.destino || 'https://mi-backend.example.com/traces';
70
+ }
71
+
72
+ onTraceStart(traza) { /* opcional: registrar inicio */ }
73
+ onTraceEnd(traza) { this._enviarBatch(); }
74
+ onSpanStart(span) { /* opcional */ }
75
+
76
+ onSpanEnd(span) {
77
+ this._buffer.push(span);
78
+ if (this._buffer.length >= 50) this._enviarBatch();
79
+ }
80
+
81
+ shutdown() { this._enviarBatch(); }
82
+ forceFlush() { this._enviarBatch(); }
83
+
84
+ _enviarBatch() {
85
+ const lote = this._buffer.splice(0);
86
+ if (!lote.length) return;
87
+ // Envío HTTP fire-and-forget
88
+ try {
89
+ const https = require('https');
90
+ const body = JSON.stringify(lote);
91
+ const req = https.request(this._destino, { method: 'POST',
92
+ headers: { 'Content-Type': 'application/json' } });
93
+ req.on('error', () => {});
94
+ req.write(body);
95
+ req.end();
96
+ } catch (_) {}
97
+ }
98
+ }
99
+
100
+ module.exports = { MiExportador };
101
+ ```
102
+
103
+ ### Paso 2 — Verificar la implementación
104
+
105
+ ```js
106
+ const { TracingProcessor } = require('../../scripts/lib/tracing-processor-interface');
107
+ const { MiExportador } = require('./mi-exportador');
108
+
109
+ console.log(TracingProcessor.esProcesadorValido(new MiExportador())); // → true
110
+ ```
111
+
112
+ ### Paso 3 — Registrar en el pipeline (opcional)
113
+
114
+ ```js
115
+ const { MultiProcessor } = require('../../scripts/lib/tracing-processor-interface');
116
+ const { OtlpLocalProcessor } = require('../../hooks/lib/otlp-exporter');
117
+ const { MiExportador } = require('./mi-exportador');
118
+
119
+ const pipeline = new MultiProcessor([
120
+ new OtlpLocalProcessor(process.cwd()), // siempre activo
121
+ new MiExportador({ destino: process.env.TRACES_ENDPOINT }),
122
+ ]);
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Patrón Composite con MultiProcessor
128
+
129
+ `MultiProcessor` implementa `TracingProcessor` y propaga cada evento a N hijos.
130
+
131
+ **Cuándo usarlo:**
132
+ - Necesitas enviar spans a más de un destino simultáneamente.
133
+ - Quieres activar un exportador de consola durante debugging sin modificar el pipeline.
134
+ - Construyes un pipeline configurable donde los destinos se leen de variables de entorno.
135
+
136
+ **Comportamiento ante errores:** si un hijo lanza en `onSpanEnd`, `MultiProcessor`
137
+ captura la excepción y continúa con los demás hijos. Ningún fallo individual
138
+ interrumpe el pipeline completo.
139
+
140
+ ```js
141
+ const multi = new MultiProcessor([exportadorA, exportadorB]);
142
+ multi.addProcessor(exportadorC); // agregar en tiempo de ejecución
143
+ multi.removeProcessor(exportadorB); // eliminar por referencia
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Casos de uso reales
149
+
150
+ ### Exportador a Langfuse (mediano plazo)
151
+
152
+ Langfuse acepta trazas vía HTTP. Crear `scripts/lib/langfuse-processor.js`
153
+ extendiendo `TracingProcessor`. En `onSpanEnd`, formatear el span al schema
154
+ de Langfuse y encolarlo. En `shutdown`, vaciar la cola con `forceFlush`.
155
+
156
+ Variables de entorno necesarias: `LANGFUSE_PUBLIC_KEY`, `LANGFUSE_SECRET_KEY`,
157
+ `LANGFUSE_HOST`. El procesador solo se activa si `LANGFUSE_PUBLIC_KEY` está
158
+ definida (patrón opt-in de `CLAUDE.md`).
159
+
160
+ ### Exportador a Jaeger
161
+
162
+ Jaeger acepta spans en formato OpenTelemetry JSON. Los spans de swl-ses ya
163
+ tienen la estructura correcta (`traceId`, `spanId`, `nombre`, `duracionMs`).
164
+ El exportador debe mapear `estado: 'ERROR'` al código de status OTLP `2`.
165
+
166
+ Endpoint: `JAEGER_OTLP_ENDPOINT` (por defecto `http://localhost:4318/v1/traces`).
167
+
168
+ ### Exportador para métricas agregadas
169
+
170
+ En lugar de persistir spans crudos, un exportador puede agregar en memoria:
171
+ contar spans por tipo, sumar duraciones, detectar anomalías. En `onTraceEnd`
172
+ emite las métricas agregadas a `.planning/evolucion/metricas.json` usando
173
+ `atomicWriteJSON` de `hooks/lib/atomic-write.js`.
174
+
175
+ ---
176
+
177
+ ## Anti-patrones
178
+
179
+ | Anti-patrón | Problema | Solución |
180
+ |-------------|----------|---------|
181
+ | Exportador que bloquea `onSpanEnd` con I/O síncrono lento | Ralentiza todos los agentes | Usar cola interna y enviar en batch desde `onTraceEnd` o un setInterval |
182
+ | Exportador que relanza excepciones de red | Interrumpe el pipeline completo | Capturar con try/catch, registrar el error internamente |
183
+ | Exportador sin `shutdown` / `forceFlush` implementados | Spans en buffer se pierden al cerrar el proceso | Implementar ambos métodos; `shutdown` debe vaciar el buffer |
184
+ | Exportador que modifica el span recibido | Efectos secundarios para otros procesadores en el pipeline | Clonar el span antes de mutarlo: `const s = { ...span }` |
185
+ | Exportador activado incondicionalmente en producción | Agrega latencia sin config del usuario | Patrón opt-in: `if (!process.env.MI_ENDPOINT) return` al inicio |
186
+
187
+ ---
188
+
189
+ ## Relación con el resto del sistema
190
+
191
+ | Componente | Relación |
192
+ |-----------|----------|
193
+ | `scripts/lib/tracing-processor-interface.js` | Define las clases abstractas `TracingProcessor`, `TracingExporter` y `MultiProcessor` |
194
+ | `hooks/lib/otlp-exporter.js` | Implementación concreta `OtlpLocalProcessor` + funciones sueltas (compatibilidad) |
195
+ | `scripts/lib/span-schema.js` | Taxonomía de 13 tipos de span; los spans que llegan a `onSpanEnd` siguen este schema |
196
+ | `hooks/telemetria-agentes.js` | Produce los spans del ciclo de vida de agentes; es el emisor principal |
197
+ | `.planning/traces/YYYY-MM-DD.jsonl` | Destino por defecto del `OtlpLocalProcessor` |
198
+ | `hooks/lib/atomic-write.js` | Para exportadores que persisten estado (métricas, índices) — no usar para JSONL |
199
+
200
+ ## Cuándo NO cargar
201
+
202
+ - Se leen o analizan trazas ya generadas en `.planning/traces/` — usar Read tool o `drift-detection`; este skill describe cómo construir exportadores nuevos, no cómo consumir el JSONL existente.
203
+ - Se agrega observabilidad a hooks que no emiten spans del ciclo de vida de agentes (hooks de perfilado, guardrails, auditoría) — esos hooks registran en sus propios archivos JSONL; `TracingProcessor` es para el pipeline de spans de `telemetria-agentes.js`.
204
+ - El exportador objetivo ya existe en `hooks/lib/otlp-exporter.js` y solo necesita activarse — los exportadores implementados se activan con la variable de entorno correspondiente (patrón opt-in); no requieren código nuevo.
205
+ - Se diagnostica por qué un agente produjo un resultado incorrecto — las trazas miden ciclo de vida y duración, no lógica; para bugs usar `depurador-swl` o los logs del hook directamente.
206
+
207
+ ## Gotchas / Errores comunes no obvios
208
+
209
+ - **`onSpanEnd` con I/O síncrono bloquea el pipeline completo**: el exportador llama a `fetch()` o `fs.writeFileSync()` directamente en `onSpanEnd` y ralentiza todos los agentes porque cada span espera al I/O antes de continuar. Causa: `onSpanEnd` se ejecuta síncronamente en el mismo event loop. Solución: encolar los spans en un buffer interno y vaciar el buffer en `onTraceEnd` o con un `setInterval` — el anti-patrón está documentado explícitamente en la tabla del skill.
210
+ - **Exportador que mutua el span recibido afecta a otros procesadores en el pipeline**: un exportador agrega un campo `exportado: true` al span y el siguiente procesador en el `MultiProcessor` recibe el span modificado. Causa: los procesadores comparten el mismo objeto span por referencia. Solución: clonar el span antes de mutarlo (`const s = { ...span }`) — regla documentada en los anti-patrones del skill.
211
+ - **`shutdown()` no implementado provoca pérdida de spans en buffer al cerrar el proceso**: el proceso del hook termina y los spans acumulados en la cola interna se descartan. Causa: implementar solo `onSpanEnd` y `onTraceEnd` sin `shutdown`. Solución: `shutdown` debe vaciar el buffer síncronamente (o retornar una Promise que resuelve al vaciar); Claude Code llama a `shutdown` en el proceso de cierre del hook.
212
+ - **Exportador activado sin variable de entorno opt-in en todos los entornos**: el exportador a Langfuse se activa incluso en proyectos que no configuraron `LANGFUSE_PUBLIC_KEY`, añadiendo latencia de red sin beneficio. Causa: no implementar el guard de opt-in al inicio de `onSpanEnd`. Solución: todo exportador externo debe comenzar con `if (!process.env.MI_ENDPOINT) return` — el patrón opt-in de CLAUDE.md es obligatorio para integraciones enterprise.