@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,291 @@
1
+ ---
2
+ name: go-testing
3
+ description: >
4
+ Testing Go con table-driven tests, testify, httptest y benchmarks. Cubre
5
+ subtests con t.Run, mocks con interfaces, tests concurrentes y profiling
6
+ básico. Cargar cuando se escriban tests en Go o se configure cobertura.
7
+ version: "1.0.0"
8
+ herramientasPermitidas: [Read, Grep]
9
+ exclusiones:
10
+ - "No cargar para implementar el código de producción que se va a testear — primero implementar con `go-experto`, luego escribir tests."
11
+ - "No cargar para diseñar la arquitectura de paquetes Go — para eso cargar `go-patrones`."
12
+ - "No cargar para errores de compilación Go en los tests — si el test no compila, cargar `build-errors-go`."
13
+ - "No cargar para benchmarking de base de datos o SQL — los benchmarks de BD tienen patrones de teardown que requieren el skill específico de BD."
14
+ evolvable: true # default para skill estandar
15
+ ---
16
+ # Go Testing — Table-Driven Tests y Ecosystem de Testing
17
+
18
+ Cubre las prácticas de testing Go idiomático: table-driven tests, subtests,
19
+ testify para assertions, httptest para handlers HTTP, t.Parallel() y benchmarks.
20
+
21
+ ## Cuándo cargar este skill
22
+
23
+ Invoca `Skill("go-testing")` cuando:
24
+
25
+ - Se escriban tests unitarios o de integración en Go
26
+ - Se testeen HTTP handlers con httptest
27
+ - Se configuren benchmarks o profiling con testing.B
28
+ - Se implementen mocks mediante interfaces
29
+ - Se use t.Parallel() para acelerar la suite
30
+
31
+ ## Cuándo NO cargar
32
+
33
+ - El código de producción aún no está implementado — primero implementar con `go-experto`, luego escribir los tests.
34
+ - La pregunta es sobre diseñar la arquitectura de paquetes Go — para eso cargar `go-patrones`.
35
+ - El test no compila por un error de Go — cargar `build-errors-go` para diagnosticar el error de compilación.
36
+ - Los tests son de otro lenguaje — este skill cubre el ecosistema de testing de Go (table-driven, testify, httptest).
37
+
38
+ ## Conceptos clave
39
+
40
+ ### Table-Driven Tests
41
+
42
+ El patrón estándar Go: una slice de structs donde cada elemento es un caso de
43
+ prueba con nombre, inputs y resultado esperado. Cada caso se ejecuta con t.Run
44
+ como subtest independiente y paralelo.
45
+
46
+ ### Interfaces como mecanismo de mock
47
+
48
+ Go no tiene reflection-based mocking por defecto. El patrón idiomático es
49
+ definir interfaces pequeñas y proporcionar implementaciones falsas en el package
50
+ de test.
51
+
52
+ ### httptest para handlers HTTP
53
+
54
+ `httptest.NewRecorder()` captura la respuesta; `httptest.NewServer()` levanta
55
+ un servidor real para tests de integración HTTP.
56
+
57
+ ## Reglas obligatorias
58
+
59
+ ### Nombres de tabla descriptivos — usar campo "name" o "desc"
60
+
61
+ Cada caso en la tabla tiene un campo string que lo describe. El t.Run usa ese
62
+ campo como nombre del subtest, haciendo el output legible.
63
+
64
+ ### t.Parallel() en tests independientes
65
+
66
+ Los tests sin estado compartido deben llamar `t.Parallel()` al inicio para
67
+ habilitar ejecución concurrente y reducir el tiempo total de la suite.
68
+
69
+ ### Usar testify/assert — no comparacion manual con if
70
+
71
+ `assert.Equal` y `require.Equal` producen mensajes con diff; una comparación
72
+ manual con `if got != want { t.Errorf(...) }` omite el contexto.
73
+ `require` detiene el test en el primer fallo; `assert` acumula todos los fallos.
74
+
75
+ ### Cerrar el body en tests de integracion HTTP
76
+
77
+ ```go
78
+ resp, err := http.Get(ts.URL + "/v1/pedidos")
79
+ require.NoError(t, err)
80
+ defer resp.Body.Close() // SIEMPRE defer antes de leer
81
+ ```
82
+
83
+ ## Patrones recomendados
84
+
85
+ ### Table-driven test completo
86
+
87
+ ```go
88
+ func TestCalcularDescuento(t *testing.T) {
89
+ t.Parallel()
90
+
91
+ casos := []struct {
92
+ name string
93
+ precio float64
94
+ categoria string
95
+ esperado float64
96
+ }{
97
+ {name: "sin descuento para electronico", precio: 100, categoria: "electronico", esperado: 100},
98
+ {name: "10% descuento para ropa", precio: 200, categoria: "ropa", esperado: 180},
99
+ {name: "precio cero retorna cero", precio: 0, categoria: "ropa", esperado: 0},
100
+ }
101
+
102
+ for _, tc := range casos {
103
+ tc := tc // captura de variable para t.Parallel() en subtests
104
+ t.Run(tc.name, func(t *testing.T) {
105
+ t.Parallel()
106
+ got := calcularDescuento(tc.precio, tc.categoria)
107
+ assert.InDelta(t, tc.esperado, got, 0.001)
108
+ })
109
+ }
110
+ }
111
+ ```
112
+
113
+ ### Mock con interfaz
114
+
115
+ ```go
116
+ // Interfaz en el package de producción
117
+ type PedidoRepository interface {
118
+ Obtener(ctx context.Context, id uuid.UUID) (*Pedido, error)
119
+ Guardar(ctx context.Context, p *Pedido) error
120
+ }
121
+
122
+ // Implementación falsa en el package de test
123
+ type repoFalso struct {
124
+ pedidos map[uuid.UUID]*Pedido
125
+ err error
126
+ }
127
+ func (r *repoFalso) Obtener(_ context.Context, id uuid.UUID) (*Pedido, error) {
128
+ if r.err != nil { return nil, r.err }
129
+ return r.pedidos[id], nil
130
+ }
131
+ func (r *repoFalso) Guardar(_ context.Context, p *Pedido) error {
132
+ r.pedidos[p.ID] = p
133
+ return r.err
134
+ }
135
+
136
+ // Uso en test
137
+ func TestPedidoService_Confirmar(t *testing.T) {
138
+ repo := &repoFalso{pedidos: make(map[uuid.UUID]*Pedido)}
139
+ svc := NewPedidoService(repo)
140
+ // ...
141
+ }
142
+ ```
143
+
144
+ ### httptest con servidor real
145
+
146
+ ```go
147
+ func TestPedidoHandler_Crear(t *testing.T) {
148
+ t.Parallel()
149
+
150
+ handler := NuevoRouter(pedidoHandlerFalso())
151
+ ts := httptest.NewServer(handler)
152
+ defer ts.Close()
153
+
154
+ body := strings.NewReader(`{"clienteId":"uuid-123","items":[]}`)
155
+ resp, err := http.Post(ts.URL+"/v1/pedidos", "application/json", body)
156
+ require.NoError(t, err)
157
+ defer resp.Body.Close()
158
+
159
+ assert.Equal(t, http.StatusCreated, resp.StatusCode)
160
+
161
+ var resultado map[string]interface{}
162
+ require.NoError(t, json.NewDecoder(resp.Body).Decode(&resultado))
163
+ assert.NotEmpty(t, resultado["id"])
164
+ }
165
+ ```
166
+
167
+ ### httptest.NewRecorder para tests unitarios de handler
168
+
169
+ ```go
170
+ func TestPedidoHandler_Obtener_NotFound(t *testing.T) {
171
+ repo := &repoFalso{err: ErrNotFound}
172
+ handler := NuevoPedidoHandler(NewPedidoService(repo))
173
+
174
+ req := httptest.NewRequest(http.MethodGet, "/v1/pedidos/uuid-404", nil)
175
+ rec := httptest.NewRecorder()
176
+
177
+ handler.Obtener(rec, req)
178
+
179
+ assert.Equal(t, http.StatusNotFound, rec.Code)
180
+ }
181
+ ```
182
+
183
+ ### Benchmark
184
+
185
+ ```go
186
+ func BenchmarkCalcularDescuento(b *testing.B) {
187
+ b.ReportAllocs()
188
+ for i := 0; i < b.N; i++ {
189
+ calcularDescuento(100.0, "ropa")
190
+ }
191
+ }
192
+ ```
193
+
194
+ Correr con: `go test -bench=. -benchmem ./...`
195
+
196
+ ### Golden files para outputs complejos
197
+
198
+ ```go
199
+ func TestGenerarReporte(t *testing.T) {
200
+ got := generarReporte(pedidosDePrueba())
201
+ golden := filepath.Join("testdata", "reporte_esperado.json")
202
+
203
+ if *update { // flag: go test -update
204
+ os.WriteFile(golden, got, 0644)
205
+ }
206
+
207
+ esperado, err := os.ReadFile(golden)
208
+ require.NoError(t, err)
209
+ assert.JSONEq(t, string(esperado), string(got))
210
+ }
211
+ ```
212
+
213
+ ## Anti-patrones conocidos
214
+
215
+ ### Test sin nombre en tabla — output ilegible
216
+
217
+ ```go
218
+ // MAL — falla como "--- FAIL: TestCalc/#02"
219
+ casos := []struct{ input, want float64 }{
220
+ {100, 80},
221
+ {0, 0},
222
+ }
223
+
224
+ // BIEN — falla como "--- FAIL: TestCalc/precio_cero"
225
+ casos := []struct {
226
+ name string
227
+ input float64
228
+ want float64
229
+ }{
230
+ {name: "descuento estandar", input: 100, want: 80},
231
+ {name: "precio cero", input: 0, want: 0},
232
+ }
233
+ ```
234
+
235
+ ### Captura de variable de loop sin tc := tc
236
+
237
+ ```go
238
+ // MAL — todos los subtests paralelos leen el mismo tc (el ultimo)
239
+ for _, tc := range casos {
240
+ t.Run(tc.name, func(t *testing.T) {
241
+ t.Parallel()
242
+ // tc.input es siempre el ultimo caso
243
+ })
244
+ }
245
+
246
+ // BIEN — captura local
247
+ for _, tc := range casos {
248
+ tc := tc
249
+ t.Run(tc.name, func(t *testing.T) {
250
+ t.Parallel()
251
+ // tc.input es el caso correcto
252
+ })
253
+ }
254
+ ```
255
+
256
+ ### io.Discard en lugar de leer el body en tests de integración
257
+
258
+ ```go
259
+ // MAL — el body queda abierto y la conexión no se libera
260
+ resp, _ := http.Get(url)
261
+ // sin defer resp.Body.Close()
262
+
263
+ // BIEN
264
+ resp, err := http.Get(url)
265
+ require.NoError(t, err)
266
+ defer resp.Body.Close()
267
+ io.Copy(io.Discard, resp.Body) // drenar si no se necesita el contenido
268
+ ```
269
+
270
+ ## Checklist de verificación
271
+
272
+ - [ ] Todos los casos de tabla tienen campo "name" descriptivo
273
+ - [ ] tc := tc antes de t.Parallel() en subtests con tabla
274
+ - [ ] defer resp.Body.Close() en todo test que hace request HTTP
275
+ - [ ] Mocks implementan interfaces pequeñas, no structs completos
276
+ - [ ] require para fallos que invalidan el resto del test; assert para los demás
277
+ - [ ] Benchmarks con b.ReportAllocs() para detectar allocaciones innecesarias
278
+ - [ ] t.Parallel() en tests sin estado compartido
279
+
280
+ ## Gotchas / Errores comunes no obvios
281
+
282
+ **`tc := tc` antes de `t.Parallel()` en table-driven tests con closures**: sin esta captura, todos los goroutines del subtest comparten la variable de loop y leen el último valor al ejecutarse. Go 1.22+ corrigió el comportamiento de loop variables, pero en proyectos con `go 1.21` o menor en `go.mod` sigue siendo necesario. Fix: verificar la versión de Go en `go.mod`; si es < 1.22, agregar `tc := tc` antes de `t.Parallel()` en todos los table-driven tests.
283
+
284
+ **`httptest.NewRecorder()` no replica el comportamiento de flujo de `http.ResponseWriter`**: `ResponseRecorder` no llama `WriteHeader(200)` implícitamente hasta que se llama `Write()`, mientras que un cliente real sí recibe el status code. Un handler que usa `w.WriteHeader()` seguido de `w.Write()` funciona diferente si se inspecciona el recorder antes de que el handler termine. Fix: siempre inspeccionar `recorder.Result()` después de que el handler ha terminado, no durante.
285
+
286
+ **`t.Cleanup()` registrado dentro de un `t.Run()` solo aplica al subtest, no al test padre**: si un helper registra `t.Cleanup(...)` con el `t` del padre pero el recurso se crea en un subtest, el cleanup puede ejecutarse antes de que el subtest termine. Fix: pasar el `t` correcto (del subtest) al helper que registra el cleanup, no el `t` del test padre.
287
+
288
+ **Benchmarks con `b.StopTimer()`/`b.StartTimer()` que no incluyen el setup inicial miden erróneamente**: si el setup costoso está fuera de la función de benchmark (en `b.ResetTimer()` al inicio), las primeras iteraciones incluyen tiempo de calentamiento. Fix: usar `b.ResetTimer()` inmediatamente después del setup costoso para que las `b.N` iteraciones empiecen desde cero.
289
+
290
+ ---
291
+ *Skill creado con swl:crear-skill el 2026-03-31. Versión 1.0.0.*
@@ -0,0 +1,323 @@
1
+ ---
2
+ name: graphql-experto
3
+ description: >
4
+ GraphQL: schema design, resolvers, DataLoader para N+1, subscriptions,
5
+ paginación Relay, federation y Apollo Server/Client. Cargar cuando se diseñe
6
+ un schema GraphQL, se implementen resolvers o se configure Apollo.
7
+ version: "1.0.0"
8
+ herramientasPermitidas: [Read, Grep]
9
+ exclusiones:
10
+ - "No cargar para APIs REST — GraphQL y REST son paradigmas de diseño de API distintos; si el proyecto usa REST cargar `api-rest-diseno` o el skill del framework backend."
11
+ - "No cargar para configurar Apollo Client en el frontend React/Next.js sin contexto del schema — si la pregunta es solo sobre configuración del cliente, no del schema o resolvers del servidor."
12
+ - "No cargar para diseñar el esquema relacional de la base de datos que subyace al schema GraphQL — el schema GraphQL y el esquema SQL son capas distintas; para el esquema SQL cargar `postgresql-experto` o `dbml-experto`."
13
+ - "No cargar para errores de TypeScript en tipos generados por GraphQL Codegen — esos son errores de generación de código; revisar el schema GraphQL fuente y la configuración de codegen."
14
+ evolvable: true # default para skill estandar
15
+ ---
16
+ # GraphQL Experto — Schema Design y Resolvers
17
+
18
+ GraphQL es un contrato entre cliente y servidor. Un schema bien diseñado permite
19
+ evolucionar la API sin versionar. Este skill cubre schema-first vs code-first,
20
+ patrones de resolvers, DataLoader para el problema N+1, paginación con cursor
21
+ y autenticación en el contexto de Apollo Server.
22
+
23
+ ## Cuándo cargar este skill
24
+
25
+ Invoca `Skill("graphql-experto")` cuando:
26
+
27
+ - Se diseñe un schema GraphQL nuevo (tipos, queries, mutations, subscriptions)
28
+ - Se implementen resolvers con acceso a BD
29
+ - Se configure Apollo Server o un servidor GraphQL similar
30
+ - Se solucione el problema N+1 en resolvers
31
+ - Se implemente paginación cursor-based o Relay spec
32
+ - Se configure Apollo Client en el frontend
33
+
34
+ ## Cuándo NO cargar
35
+
36
+ - El proyecto usa REST — GraphQL y REST son paradigmas distintos; si el proyecto usa endpoints REST cargar `api-rest-diseno` o el skill del framework backend.
37
+ - La pregunta es solo sobre configurar Apollo Client en el frontend sin contexto del schema — si no hay diseño de schema o resolvers del servidor, este skill aporta poco.
38
+ - La pregunta es sobre diseñar el esquema relacional de la BD que subyace al schema GraphQL — el schema GraphQL y el esquema SQL son capas distintas; para el esquema SQL cargar `postgresql-experto`.
39
+ - Los errores son de tipos generados por GraphQL Codegen — esos son errores de generación de código; revisar el schema GraphQL fuente y la configuración de codegen.
40
+
41
+ ## Conceptos clave
42
+
43
+ ### Schema-first vs Code-first
44
+
45
+ Schema-first: se escribe el SDL (Schema Definition Language) primero, los resolvers
46
+ lo implementan. Ventaja: el contrato es claro desde el inicio. Code-first
47
+ (ej: TypeGraphQL, Pothos): el schema se genera desde las clases/funciones.
48
+ Ventaja: un solo source of truth en TypeScript.
49
+
50
+ ### DataLoader — solución al N+1
51
+
52
+ Cada campo resuelto en GraphQL puede generar queries independientes. DataLoader
53
+ agrupa múltiples resoluciones del mismo tipo en una sola query batch, ejecutada
54
+ al final del tick de evento. Es la solución estándar al N+1 en GraphQL.
55
+
56
+ ### Contexto de Apollo Server
57
+
58
+ El contexto se crea por request y se pasa a todos los resolvers. Es el lugar
59
+ correcto para poner: el usuario autenticado, instancias de DataLoader, y el
60
+ cliente de BD. Los DataLoaders DEBEN crearse en el contexto (nuevo por request),
61
+ no como singletons globales.
62
+
63
+ ## Reglas obligatorias
64
+
65
+ ### DataLoader OBLIGATORIO para resolver relaciones en listas
66
+
67
+ ```typescript
68
+ // MAL — N+1: por cada post se hace una query para el autor
69
+ const resolvers = {
70
+ Post: {
71
+ autor: async (post) => {
72
+ return db.usuario.findUnique({ where: { id: post.autorId } });
73
+ },
74
+ },
75
+ };
76
+
77
+ // BIEN — DataLoader agrupa los IDs en una sola query batch
78
+ // En el contexto:
79
+ const context = async ({ req }) => ({
80
+ usuarioLoader: new DataLoader(async (ids: readonly string[]) => {
81
+ const usuarios = await db.usuario.findMany({
82
+ where: { id: { in: [...ids] } },
83
+ });
84
+ const mapa = new Map(usuarios.map(u => [u.id, u]));
85
+ return ids.map(id => mapa.get(id) ?? null);
86
+ }),
87
+ });
88
+
89
+ // En el resolver:
90
+ Post: {
91
+ autor: (post, _, { usuarioLoader }) => usuarioLoader.load(post.autorId),
92
+ },
93
+ ```
94
+
95
+ ### Autenticación en el contexto — nunca en cada resolver individualmente
96
+
97
+ ```typescript
98
+ // MAL — verificar auth en cada resolver
99
+ const resolvers = {
100
+ Query: {
101
+ miPerfil: async (_, __, { req }) => {
102
+ const token = req.headers.authorization;
103
+ const usuario = verificarToken(token); // duplicado en cada resolver
104
+ if (!usuario) throw new GraphQLError('No autenticado');
105
+ },
106
+ },
107
+ };
108
+
109
+ // BIEN — una vez en el contexto
110
+ const context = async ({ req }) => {
111
+ const token = req.headers.authorization?.split(' ')[1];
112
+ const usuario = token ? verificarToken(token) : null;
113
+ return { usuario, db, usuarioLoader: crearUsuarioLoader() };
114
+ };
115
+
116
+ // Resolver usa el usuario del contexto
117
+ Query: {
118
+ miPerfil: (_, __, { usuario }) => {
119
+ if (!usuario) throw new GraphQLError('No autenticado',
120
+ { extensions: { code: 'UNAUTHENTICATED' } });
121
+ return usuario;
122
+ },
123
+ },
124
+ ```
125
+
126
+ ### Validación de inputs con tipos estrictos en el schema
127
+
128
+ ```graphql
129
+ # MAL — input sin restricciones
130
+ input CrearProductoInput {
131
+ nombre: String # permite null, string vacio, etc.
132
+ precio: Float
133
+ }
134
+
135
+ # BIEN — tipos no-nullable donde aplica, scalares custom para restricciones
136
+ scalar PositiveFloat
137
+ scalar NonEmptyString
138
+
139
+ input CrearProductoInput {
140
+ nombre: NonEmptyString!
141
+ precio: PositiveFloat!
142
+ categoriaId: ID!
143
+ }
144
+ ```
145
+
146
+ ### Paginación cursor-based (Relay spec) para listas grandes
147
+
148
+ ```graphql
149
+ type ProductoConnection {
150
+ edges: [ProductoEdge!]!
151
+ pageInfo: PageInfo!
152
+ }
153
+
154
+ type ProductoEdge {
155
+ node: Producto!
156
+ cursor: String!
157
+ }
158
+
159
+ type PageInfo {
160
+ hasNextPage: Boolean!
161
+ hasPreviousPage: Boolean!
162
+ startCursor: String
163
+ endCursor: String
164
+ }
165
+
166
+ type Query {
167
+ productos(first: Int, after: String, last: Int, before: String): ProductoConnection!
168
+ }
169
+ ```
170
+
171
+ ## Patrones recomendados
172
+
173
+ ### Schema SDL con organización por dominio
174
+
175
+ ```graphql
176
+ # schema/producto.graphql
177
+ type Producto {
178
+ id: ID!
179
+ nombre: String!
180
+ precio: Float!
181
+ stock: Int!
182
+ categoria: Categoria!
183
+ resenas: [Resena!]!
184
+ creadoEn: DateTime!
185
+ }
186
+
187
+ type Query {
188
+ producto(id: ID!): Producto
189
+ productos(filtros: FiltrosProductoInput, paginacion: PaginacionInput): ProductoConnection!
190
+ }
191
+
192
+ type Mutation {
193
+ crearProducto(input: CrearProductoInput!): CrearProductoPayload!
194
+ actualizarProducto(id: ID!, input: ActualizarProductoInput!): ActualizarProductoPayload!
195
+ }
196
+ ```
197
+
198
+ ### Error handling con union types
199
+
200
+ ```graphql
201
+ # En lugar de lanzar excepciones, modelar errores como tipos
202
+ union CrearProductoPayload = ProductoCreado | ErrorValidacion | ErrorAutorizacion
203
+
204
+ type ProductoCreado { producto: Producto! }
205
+ type ErrorValidacion { campo: String!, mensaje: String! }
206
+ type ErrorAutorizacion { mensaje: String! }
207
+ ```
208
+
209
+ ```typescript
210
+ // Resolver retorna el tipo correcto segun el caso
211
+ Mutation: {
212
+ crearProducto: async (_, { input }, { usuario }) => {
213
+ if (!usuario?.esAdmin) return { __typename: 'ErrorAutorizacion', mensaje: 'Sin permiso' };
214
+ const validacion = validarInput(input);
215
+ if (!validacion.ok) return { __typename: 'ErrorValidacion', ...validacion };
216
+ const producto = await db.producto.create({ data: input });
217
+ return { __typename: 'ProductoCreado', producto };
218
+ },
219
+ },
220
+ ```
221
+
222
+ ### Subscriptions con filtrado por usuario
223
+
224
+ ```typescript
225
+ const resolvers = {
226
+ Subscription: {
227
+ pedidoActualizado: {
228
+ subscribe: withFilter(
229
+ () => pubsub.asyncIterator(['PEDIDO_ACTUALIZADO']),
230
+ (payload, variables, context) =>
231
+ payload.pedidoActualizado.usuarioId === context.usuario?.id
232
+ ),
233
+ },
234
+ },
235
+ };
236
+ ```
237
+
238
+ ### Depth limiting y complexity limits
239
+
240
+ ```typescript
241
+ import depthLimit from 'graphql-depth-limit';
242
+ import { createComplexityLimitRule } from 'graphql-validation-complexity';
243
+
244
+ const server = new ApolloServer({
245
+ typeDefs,
246
+ resolvers,
247
+ validationRules: [
248
+ depthLimit(7), // Maximo 7 niveles de anidamiento
249
+ createComplexityLimitRule(1000), // Score de complejidad maximo
250
+ ],
251
+ });
252
+ ```
253
+
254
+ ## Anti-patrones conocidos
255
+
256
+ ### Resolver con lógica de negocio — usar services
257
+
258
+ ```typescript
259
+ // MAL — logica de negocio en el resolver
260
+ Mutation: {
261
+ crearPedido: async (_, { items }, { usuario, db }) => {
262
+ // 40 lineas de calculo de descuentos, validacion de stock, etc.
263
+ },
264
+ },
265
+
266
+ // BIEN — resolver delega a un service
267
+ Mutation: {
268
+ crearPedido: async (_, { items }, { usuario, pedidoService }) => {
269
+ return pedidoService.crear({ usuario, items });
270
+ },
271
+ },
272
+ ```
273
+
274
+ ### Mutations sin payload tipado
275
+
276
+ ```graphql
277
+ # MAL — mutation que solo retorna Boolean o el objeto
278
+ type Mutation {
279
+ eliminarProducto(id: ID!): Boolean
280
+ }
281
+
282
+ # BIEN — payload con información útil y manejo de errores
283
+ type Mutation {
284
+ eliminarProducto(id: ID!): EliminarProductoPayload!
285
+ }
286
+ union EliminarProductoPayload = ProductoEliminado | ErrorNotFound
287
+ ```
288
+
289
+ ### DataLoader como singleton global
290
+
291
+ ```typescript
292
+ // MAL — comparte cache entre requests de distintos usuarios
293
+ const usuarioLoader = new DataLoader(batchFn); // modulo global
294
+
295
+ // BIEN — nuevo por request en el contexto
296
+ const context = async ({ req }) => ({
297
+ usuarioLoader: new DataLoader(batchFn),
298
+ });
299
+ ```
300
+
301
+ ## Gotchas / Errores comunes no obvios
302
+
303
+ **DataLoader retorna `null` para IDs no encontrados pero el resolver espera el objeto**: si la función batch de DataLoader retorna `ids.map(id => mapa.get(id) ?? null)` y el resolver tipado espera `User` (no nullable), GraphQL lanza un error de tipo en runtime aunque el campo del schema sea `User` (no `User!`). Causa: un `null` en DataLoader se propaga como valor del campo aunque no se haya declarado como nullable en el schema. Fix: si el campo es non-nullable en el schema (`User!`), la función batch debe lanzar un error para IDs no encontrados en lugar de retornar `null`, o usar `notFound: true` si la librería lo soporta.
304
+
305
+ **`context` del Apollo Server no se re-crea entre operaciones en subscriptions**: en queries y mutations, la función `context()` se llama una vez por request. En subscriptions WebSocket, el contexto se crea cuando el cliente conecta y persiste mientras dura la conexión — no por cada mensaje. Causa: WebSocket es una conexión persistente, no un request/response. Fix: si el contexto necesita datos frescos por operación (ej: validar token en cada mensaje), usar el hook `onOperation` del transporte WebSocket para re-validar.
306
+
307
+ **Mutations con `__typename` en union types no funciona si el resolver no lo retorna explícitamente**: `{ __typename: 'ErrorValidacion', campo: 'email', mensaje: '...' }` puede fallar si Apollo no puede resolver el `__typename` automáticamente del objeto retornado sin `resolveType`. Causa: para union types, Apollo necesita saber a qué tipo mapear el objeto — lo detecta por `__typename` en el objeto o por la función `__resolveType` en el resolver. Fix: siempre incluir `__typename` explícitamente en el objeto retornado o definir `__resolveType` en el resolver de la union.
308
+
309
+ **`depthLimit(N)` cuenta fragmentos anidados una vez, no por uso**: si un fragmento `F` se usa 3 veces en una query pero el fragmento en sí tiene profundidad 3, `depthLimit` cuenta la profundidad del fragmento una vez, no multiplica. Pero inline fragments y `... on Tipo` sí cuentan en la profundidad. Causa: la librería `graphql-depth-limit` analiza el documento AST con reglas específicas. Fix: complementar depth limit con complexity limit para capturar queries que abusan de fragmentos reutilizados para multiplicar la carga sin exceder la profundidad.
310
+
311
+ ## Checklist de verificación
312
+
313
+ - [ ] DataLoader para cada relación que se resuelve en listas
314
+ - [ ] DataLoaders creados en el contexto (uno por request, no globales)
315
+ - [ ] Autenticación verificada en el contexto, no en cada resolver
316
+ - [ ] Inputs con tipos no-nullable donde el campo es requerido
317
+ - [ ] Paginación cursor-based para colecciones grandes
318
+ - [ ] Depth limit y complexity limit configurados
319
+ - [ ] Error handling con union types, no solo excepciones
320
+
321
+ ## Referencias
322
+
323
+ - [GraphQL Spec](https://spec.graphql.org) | [Apollo Server](https://www.apollographql.com/docs/apollo-server) | [DataLoader](https://github.com/graphql/dataloader)