@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,316 @@
1
+ ---
2
+ name: csharp-patrones
3
+ description: >
4
+ Patrones C# modernos: records para CQRS, MediatR, Result<T> pattern,
5
+ Specification pattern, Unit of Work, Channel<T>, Polly y discriminated
6
+ unions con OneOf. Cargar cuando se diseñe arquitectura .NET, se implemente
7
+ CQRS/Mediator, o se necesite manejo robusto de errores sin excepciones.
8
+ version: "1.0.0"
9
+ herramientasPermitidas: [Read, Glob, Grep]
10
+ exclusiones:
11
+ - "No cargar para implementar endpoints ASP.NET Core, EF Core o Background Services — para implementación cargar `csharp-experto`."
12
+ - "No cargar para escribir tests C# — para testing cargar `csharp-testing`."
13
+ - "No cargar para errores de compilación C# — para build errors cargar `build-errors-csharp`."
14
+ - "No cargar para patrones de diseño GoF genéricos sin contexto C# — este skill cubre patrones idiomáticos de C# moderno como CQRS con records, Result<T> y MediatR."
15
+ evolvable: true # default para skill estandar
16
+ ---
17
+ # C# Patrones — CQRS, Result, MediatR y Más
18
+
19
+ ## Cuándo NO cargar
20
+
21
+ - La pregunta es sobre implementar endpoints ASP.NET Core, EF Core o Background Services — para implementación concreta cargar `csharp-experto`.
22
+ - La tarea es escribir tests C# — cargar `csharp-testing`.
23
+ - Los errores son de compilación C# — cargar `build-errors-csharp`.
24
+ - La discusión es sobre patrones GoF genéricos (Singleton, Observer) sin contexto C# — este skill cubre patrones idiomáticos de C# moderno como CQRS con records, Result<T> y MediatR.
25
+
26
+ ## CQRS con Records y MediatR
27
+
28
+ ```csharp
29
+ // Command — estado mutable del sistema
30
+ public record CrearFacturaCommand(
31
+ Guid EmpresaId,
32
+ string Folio,
33
+ List<ItemCommand> Items) : IRequest<Result<FacturaDto>>;
34
+
35
+ // Query — solo lectura, sin efectos secundarios
36
+ public record ObtenerFacturasQuery(
37
+ Guid EmpresaId,
38
+ int Pagina = 1,
39
+ int TamanoPagina = 20) : IRequest<Result<PaginaDto<FacturaDto>>>;
40
+
41
+ // Handler de Command
42
+ public class CrearFacturaHandler(
43
+ IFacturasRepository repo,
44
+ IUnitOfWork uow,
45
+ ILogger<CrearFacturaHandler> logger)
46
+ : IRequestHandler<CrearFacturaCommand, Result<FacturaDto>>
47
+ {
48
+ public async Task<Result<FacturaDto>> Handle(
49
+ CrearFacturaCommand req, CancellationToken ct)
50
+ {
51
+ if (await repo.ExisteFolioAsync(req.EmpresaId, req.Folio, ct))
52
+ return Result.Failure<FacturaDto>(
53
+ Error.Conflicto("Facturas.FolioDuplicado", $"El folio {req.Folio} ya existe"));
54
+
55
+ var factura = Factura.Crear(req.EmpresaId, req.Folio, req.Items);
56
+ await repo.AgregarAsync(factura, ct);
57
+ await uow.GuardarCambiosAsync(ct);
58
+
59
+ logger.LogInformation("Factura {Folio} creada para empresa {EmpresaId}",
60
+ req.Folio, req.EmpresaId);
61
+ return Result.Success(FacturaDto.Desde(factura));
62
+ }
63
+ }
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Result<T> Pattern — Sin excepciones para flujo de control
69
+
70
+ ```csharp
71
+ public class Result<T>
72
+ {
73
+ private Result(T? valor, bool exitoso, Error error)
74
+ {
75
+ Valor = valor;
76
+ EsExitoso = exitoso;
77
+ Error = error;
78
+ }
79
+
80
+ public T? Valor { get; }
81
+ public bool EsExitoso { get; }
82
+ public bool EsFallido => !EsExitoso;
83
+ public Error Error { get; }
84
+
85
+ public static Result<T> Success(T valor) =>
86
+ new(valor, true, Error.Ninguno);
87
+
88
+ public static Result<T> Failure(Error error) =>
89
+ new(default, false, error);
90
+ }
91
+
92
+ public static class Result
93
+ {
94
+ public static Result<T> Success<T>(T valor) => Result<T>.Success(valor);
95
+ public static Result<T> Failure<T>(Error error) => Result<T>.Failure(error);
96
+ }
97
+
98
+ public record Error(string Codigo, string Descripcion)
99
+ {
100
+ public static readonly Error Ninguno = new("", "");
101
+ public static Error NoEncontrado(string entidad, Guid id) =>
102
+ new($"{entidad}.NoEncontrado", $"{entidad} con id {id} no existe");
103
+ public static Error Conflicto(string codigo, string desc) => new(codigo, desc);
104
+ public static Error Validacion(string campo, string mensaje) =>
105
+ new($"Validacion.{campo}", mensaje);
106
+ }
107
+
108
+ // Uso en endpoint — mapear Result a HTTP
109
+ static async Task<IResult> Crear(
110
+ CrearFacturaCommand cmd,
111
+ ISender mediator,
112
+ CancellationToken ct)
113
+ {
114
+ var resultado = await mediator.Send(cmd, ct);
115
+ return resultado switch
116
+ {
117
+ { EsExitoso: true } => TypedResults.Created($"/facturas/{resultado.Valor!.Id}", resultado.Valor),
118
+ { Error.Codigo: var c } when c.StartsWith("Validacion") => TypedResults.BadRequest(resultado.Error),
119
+ { Error.Codigo: var c } when c.EndsWith("Duplicado") => TypedResults.Conflict(resultado.Error),
120
+ _ => TypedResults.Problem("Error interno")
121
+ };
122
+ }
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Specification Pattern
128
+
129
+ ```csharp
130
+ public abstract class Specification<T>
131
+ {
132
+ public abstract Expression<Func<T, bool>> Criterio { get; }
133
+
134
+ public Specification<T> And(Specification<T> otra) =>
135
+ new SpecificacionAnd<T>(this, otra);
136
+
137
+ public Specification<T> Or(Specification<T> otra) =>
138
+ new SpecificacionOr<T>(this, otra);
139
+ }
140
+
141
+ public class FacturasPorEmpresaSpec : Specification<Factura>
142
+ {
143
+ private readonly Guid _empresaId;
144
+ public FacturasPorEmpresaSpec(Guid empresaId) => _empresaId = empresaId;
145
+
146
+ public override Expression<Func<Factura, bool>> Criterio =>
147
+ f => f.EmpresaId == _empresaId;
148
+ }
149
+
150
+ public class FacturasPendientesSpec : Specification<Factura>
151
+ {
152
+ public override Expression<Func<Factura, bool>> Criterio =>
153
+ f => f.Estatus == "pendiente";
154
+ }
155
+
156
+ // Uso compuesto
157
+ var spec = new FacturasPorEmpresaSpec(empresaId)
158
+ .And(new FacturasPendientesSpec());
159
+
160
+ var facturas = await _db.Facturas
161
+ .Where(spec.Criterio)
162
+ .ToListAsync(ct);
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Unit of Work con EF Core
168
+
169
+ ```csharp
170
+ public interface IUnitOfWork
171
+ {
172
+ Task<int> GuardarCambiosAsync(CancellationToken ct = default);
173
+ }
174
+
175
+ // AppDbContext implementa IUnitOfWork directamente
176
+ public class AppDbContext : DbContext, IUnitOfWork
177
+ {
178
+ public Task<int> GuardarCambiosAsync(CancellationToken ct = default) =>
179
+ SaveChangesAsync(ct);
180
+ }
181
+
182
+ // Registro — mismo DbContext resuelve ambas interfaces
183
+ builder.Services.AddDbContext<AppDbContext>(...);
184
+ builder.Services.AddScoped<IUnitOfWork>(sp =>
185
+ sp.GetRequiredService<AppDbContext>());
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Channel<T> — Pipelines async
191
+
192
+ ```csharp
193
+ // Productor/consumidor sin bloqueo de thread
194
+ public class ColaProcesamiento<T>
195
+ {
196
+ private readonly Channel<T> _canal = Channel.CreateBounded<T>(
197
+ new BoundedChannelOptions(1000)
198
+ {
199
+ FullMode = BoundedChannelFullMode.Wait,
200
+ SingleReader = false,
201
+ SingleWriter = false
202
+ });
203
+
204
+ public ChannelWriter<T> Escritor => _canal.Writer;
205
+ public ChannelReader<T> Lector => _canal.Reader;
206
+ }
207
+
208
+ // Productor
209
+ await _cola.Escritor.WriteAsync(nuevoElemento, ct);
210
+
211
+ // Consumidor en BackgroundService
212
+ await foreach (var elemento in _cola.Lector.ReadAllAsync(stoppingToken))
213
+ {
214
+ await ProcesarAsync(elemento, stoppingToken);
215
+ }
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Polly — Resiliencia
221
+
222
+ ```csharp
223
+ // Pipeline de resiliencia para llamadas HTTP externas
224
+ var pipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
225
+ .AddRetry(new RetryStrategyOptions<HttpResponseMessage>
226
+ {
227
+ MaxRetryAttempts = 3,
228
+ Delay = TimeSpan.FromSeconds(1),
229
+ BackoffType = DelayBackoffType.Exponential,
230
+ ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
231
+ .Handle<HttpRequestException>()
232
+ .HandleResult(r => r.StatusCode >= HttpStatusCode.InternalServerError)
233
+ })
234
+ .AddCircuitBreaker(new CircuitBreakerStrategyOptions<HttpResponseMessage>
235
+ {
236
+ FailureRatio = 0.5,
237
+ MinimumThroughput = 10,
238
+ BreakDuration = TimeSpan.FromSeconds(30)
239
+ })
240
+ .AddTimeout(TimeSpan.FromSeconds(10))
241
+ .Build();
242
+
243
+ // Registro con HttpClient
244
+ builder.Services.AddHttpClient<ISatClient, SatClient>()
245
+ .AddResilienceHandler("sat-pipeline", b => b.AddPipeline(pipeline));
246
+ ```
247
+
248
+ ---
249
+
250
+ ## OneOf — Discriminated Unions
251
+
252
+ ```csharp
253
+ // dotnet add package OneOf
254
+ public class FacturasService
255
+ {
256
+ public async Task<OneOf<FacturaDto, NotFound, ValidationError>> ObtenerAsync(
257
+ Guid id, CancellationToken ct)
258
+ {
259
+ var factura = await _repo.ObtenerAsync(id, ct);
260
+ if (factura is null) return new NotFound();
261
+ return FacturaDto.Desde(factura);
262
+ }
263
+ }
264
+
265
+ // Uso exhaustivo en endpoint
266
+ var resultado = await svc.ObtenerAsync(id, ct);
267
+ return resultado.Match(
268
+ dto => TypedResults.Ok(dto),
269
+ _ => TypedResults.NotFound(),
270
+ error => TypedResults.BadRequest(error.Mensajes)
271
+ );
272
+ ```
273
+
274
+ ---
275
+
276
+ ## Anti-patrones
277
+
278
+ ### Excepciones para flujo de control — NUNCA
279
+
280
+ ```csharp
281
+ // MAL — las excepciones son costosas y ocultan la intención
282
+ throw new NotFoundException($"Factura {id} no encontrada");
283
+
284
+ // BIEN — Result o OneOf expresan el caso esperado
285
+ return Result.Failure<FacturaDto>(Error.NoEncontrado("Factura", id));
286
+ ```
287
+
288
+ ### Service Locator — NUNCA
289
+
290
+ ```csharp
291
+ // MAL — oculta dependencias, imposible de testear
292
+ var svc = _serviceProvider.GetService<IFacturasService>();
293
+
294
+ // BIEN — inyectar en el constructor
295
+ public class Handler(IFacturasService svc) { }
296
+ ```
297
+
298
+ ---
299
+
300
+ ## Gotchas / Errores comunes no obvios
301
+
302
+ **MediatR con `IPipelineBehavior` registrado después del handler no se ejecuta en el orden correcto**: el orden de registro de behaviors en el DI container determina el orden de ejecución de la pipeline. Un behavior de validación registrado después del behavior de logging ejecuta después, no antes. Fix: registrar los behaviors en orden explícito: primero logging, luego validación, luego el handler — o usar `OrderedPipelineBehavior` si el orden debe ser determinístico independiente del registro.
303
+
304
+ **`Result<T>` implementado con un `bool Success` y un `T Value` permite acceder a `Value` cuando `Success = false`**: si el tipo `Result<T>` no protege el acceso al valor cuando el resultado es error, el código que consume el resultado puede usar `result.Value` sin verificar `result.Success`. Fix: hacer que `Value` lance una excepción si se accede cuando `IsError` es true, o usar un patrón match que fuerce el manejo de ambos casos.
305
+
306
+ **`Channel<T>` sin capacidad fija (`Channel.CreateUnbounded()`) puede crecer sin límite bajo presión**: si el productor es más rápido que el consumidor, el canal acumula mensajes en memoria hasta agotar RAM. Fix: usar `Channel.CreateBounded(capacity)` con una capacidad razonable y manejar `ChannelWriter.TryWrite()` retornando `false` (canal lleno) con backpressure.
307
+
308
+ **Polly `WaitAndRetry` con la misma instancia de `HttpClient` no reintenta si el HttpMessageHandler tiene su propio timeout**: si el `HttpClient` tiene `Timeout = TimeSpan.FromSeconds(5)` y Polly tiene 3 reintentos, el `TaskCanceledException` del timeout interno del cliente se lanza antes del segundo intento y no es capturado por Polly. Fix: deshabilitar el timeout del `HttpClient` (`Timeout = InfiniteTimeSpan`) y configurar el timeout a través de Polly con `TimeoutPolicy`.
309
+
310
+ ## Checklist de arquitectura
311
+
312
+ - [ ] Commands y Queries son records inmutables
313
+ - [ ] Handlers retornan Result<T>, no lanzan excepciones para casos esperados
314
+ - [ ] Unit of Work hace SaveChanges, no los repositorios
315
+ - [ ] Polly configurado para todas las llamadas HTTP externas
316
+ - [ ] Sin Service Locator (IServiceProvider en código de negocio)
@@ -0,0 +1,286 @@
1
+ ---
2
+ name: csharp-testing
3
+ description: >
4
+ Testing C# con xUnit, NSubstitute, FluentAssertions y WebApplicationFactory.
5
+ Cubre IAsyncLifetime, TestContainers, Bogus para datos falsos, coverlet y
6
+ snapshot testing con Verify. Cargar cuando se escriban tests en .NET o se
7
+ configure el pipeline de testing para proyectos C#.
8
+ version: "1.0.0"
9
+ herramientasPermitidas: [Read, Grep]
10
+ exclusiones:
11
+ - "No cargar para implementar el código C# de producción — primero implementar con `csharp-experto`, luego escribir tests."
12
+ - "No cargar para diseñar patrones C# (CQRS, MediatR, Result<T>) — para diseño cargar `csharp-patrones`."
13
+ - "No cargar para errores de compilación C# en los tests — para build errors cargar `build-errors-csharp`."
14
+ - "No cargar para tests de carga o rendimiento — NUnit/xUnit con Benchmark.NET requieren configuración distinta no cubierta en este skill."
15
+ evolvable: true # default para skill estandar
16
+ ---
17
+ # C# Testing — xUnit, NSubstitute, FluentAssertions
18
+
19
+ ## Cuándo NO cargar
20
+
21
+ - El código C# de producción aún no existe — primero implementar con `csharp-experto`, luego escribir tests.
22
+ - La pregunta es sobre diseñar patrones C# (CQRS, MediatR) — cargar `csharp-patrones`.
23
+ - Los errores son de compilación C# en los archivos de test — cargar `build-errors-csharp`.
24
+ - La pregunta es sobre tests de carga o rendimiento con BenchmarkDotNet — no está cubierto en este skill.
25
+
26
+ ## Lifecycle de xUnit
27
+
28
+ ```csharp
29
+ // IAsyncLifetime para setup/teardown async
30
+ public class FacturasServiceTests : IAsyncLifetime
31
+ {
32
+ private AppDbContext _db = null!;
33
+
34
+ public async Task InitializeAsync()
35
+ {
36
+ // Se ejecuta antes del primer test de la clase
37
+ _db = await TestDbContextFactory.CreateAsync();
38
+ }
39
+
40
+ public async Task DisposeAsync()
41
+ {
42
+ await _db.DisposeAsync();
43
+ }
44
+ }
45
+
46
+ // IClassFixture<T> — fixture compartido entre todos los tests de la clase
47
+ // Solo para recursos costosos de inicializar (contenedor de BD, servidor HTTP)
48
+ public class IntegrationTests(WebAppFixture fixture)
49
+ : IClassFixture<WebAppFixture>
50
+ {
51
+ private readonly HttpClient _client = fixture.Client;
52
+ }
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Naming — Should_When
58
+
59
+ ```
60
+ NombreMetodo_Debe_ResultadoEsperado_CuandoCondicion
61
+ Ej: Crear_DebeRetornarFactura_CuandoDatosValidos
62
+ Crear_DebeLanzarValidacion_CuandoFolioVacio
63
+ ObtenerTodas_DebeRetornarVacia_CuandoNoHayFacturas
64
+ ```
65
+
66
+ ---
67
+
68
+ ## NSubstitute — Mocks
69
+
70
+ ```csharp
71
+ // Crear sustituto
72
+ var repo = Substitute.For<IFacturasRepository>();
73
+
74
+ // Configurar respuesta
75
+ repo.ObtenerAsync(Arg.Any<Guid>(), Arg.Any<CancellationToken>())
76
+ .Returns(new Factura { Id = Guid.NewGuid(), Folio = "F-001" });
77
+
78
+ // Configurar respuesta async con Task
79
+ repo.CrearAsync(Arg.Any<Factura>())
80
+ .Returns(Task.FromResult(new Factura()));
81
+
82
+ // Verificar llamada
83
+ await repo.Received(1).ObtenerAsync(
84
+ Arg.Is<Guid>(id => id == facturaId),
85
+ Arg.Any<CancellationToken>());
86
+
87
+ // Verificar que NO se llamó
88
+ repo.DidNotReceive().EliminarAsync(Arg.Any<Guid>());
89
+
90
+ // Capturar argumento
91
+ Factura? facturaCapturada = null;
92
+ await repo.CrearAsync(Arg.Do<Factura>(f => facturaCapturada = f));
93
+ ```
94
+
95
+ ---
96
+
97
+ ## FluentAssertions
98
+
99
+ ```csharp
100
+ // Objetos
101
+ resultado.Should().NotBeNull();
102
+ resultado.Should().BeOfType<FacturaDto>();
103
+ resultado.Id.Should().Be(esperadoId);
104
+
105
+ // Colecciones
106
+ facturas.Should().HaveCount(3);
107
+ facturas.Should().Contain(f => f.Folio == "F-001");
108
+ facturas.Should().BeInAscendingOrder(f => f.FechaEmision);
109
+ facturas.Should().AllSatisfy(f => f.EmpresaId.Should().Be(empresaId));
110
+
111
+ // Excepciones
112
+ var act = async () => await svc.CrearAsync(null!);
113
+ await act.Should().ThrowAsync<ArgumentNullException>()
114
+ .WithMessage("*factura*");
115
+
116
+ // Strings
117
+ mensaje.Should().StartWith("Error").And.Contain("validación");
118
+
119
+ // Fechas
120
+ factura.FechaEmision.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(5));
121
+ ```
122
+
123
+ ---
124
+
125
+ ## WebApplicationFactory — Tests de integración
126
+
127
+ ```csharp
128
+ public class WebAppFixture : WebApplicationFactory<Program>, IAsyncLifetime
129
+ {
130
+ private readonly PostgreSqlContainer _pg = new PostgreSqlBuilder()
131
+ .WithImage("postgres:16-alpine")
132
+ .Build();
133
+
134
+ protected override void ConfigureWebHost(IWebHostBuilder builder)
135
+ {
136
+ builder.ConfigureTestServices(services =>
137
+ {
138
+ // Reemplazar DbContext con la BD del contenedor
139
+ services.RemoveAll<DbContextOptions<AppDbContext>>();
140
+ services.AddDbContext<AppDbContext>(o =>
141
+ o.UseNpgsql(_pg.GetConnectionString()));
142
+ });
143
+ }
144
+
145
+ public async Task InitializeAsync()
146
+ {
147
+ await _pg.StartAsync();
148
+ // Aplicar migraciones a la BD de test
149
+ using var scope = Services.CreateScope();
150
+ var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
151
+ await db.Database.MigrateAsync();
152
+ }
153
+
154
+ public new async Task DisposeAsync()
155
+ {
156
+ await _pg.StopAsync();
157
+ }
158
+ }
159
+
160
+ // Uso en test
161
+ public class FacturasApiTests(WebAppFixture fixture)
162
+ : IClassFixture<WebAppFixture>
163
+ {
164
+ [Fact]
165
+ public async Task PostFactura_Debe201_CuandoDatosValidos()
166
+ {
167
+ var client = fixture.CreateClient();
168
+ var body = new { Folio = "F-001", EmpresaId = Guid.NewGuid() };
169
+
170
+ var response = await client.PostAsJsonAsync("/api/v1/facturas", body);
171
+
172
+ response.StatusCode.Should().Be(HttpStatusCode.Created);
173
+ var dto = await response.Content.ReadFromJsonAsync<FacturaDto>();
174
+ dto!.Folio.Should().Be("F-001");
175
+ }
176
+ }
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Bogus — Datos falsos
182
+
183
+ ```csharp
184
+ // Centralizar factories en Tests/Factories/
185
+ public static class FacturaFaker
186
+ {
187
+ private static readonly Faker<Factura> _faker = new Faker<Factura>("es")
188
+ .RuleFor(f => f.Id, f => f.Random.Guid())
189
+ .RuleFor(f => f.Folio, f => $"F-{f.Random.Int(1, 999):D3}")
190
+ .RuleFor(f => f.Total, f => f.Finance.Amount(100, 50000))
191
+ .RuleFor(f => f.FechaEmision, f => f.Date.Recent(30))
192
+ .RuleFor(f => f.Estatus, f => f.PickRandom("borrador", "emitida"));
193
+
194
+ public static Factura Generar() => _faker.Generate();
195
+ public static List<Factura> GenerarLista(int n = 5) => _faker.Generate(n);
196
+ }
197
+ ```
198
+
199
+ ---
200
+
201
+ ## Coverlet — Configuración
202
+
203
+ ```xml
204
+ <!-- MiApi.Tests.csproj -->
205
+ <PackageReference Include="coverlet.collector" Version="6.*" />
206
+ <PackageReference Include="coverlet.msbuild" Version="6.*" />
207
+ ```
208
+
209
+ ```bash
210
+ # Ejecutar con cobertura mínima 80%
211
+ dotnet test --collect:"XPlat Code Coverage" \
212
+ /p:Threshold=80 \
213
+ /p:ThresholdType=line \
214
+ /p:ExcludeByAttribute="GeneratedCodeAttribute"
215
+
216
+ # Generar reporte HTML
217
+ reportgenerator -reports:"**/coverage.cobertura.xml" \
218
+ -targetdir:"coveragereport" -reporttypes:Html
219
+ ```
220
+
221
+ ---
222
+
223
+ ## Verify — Snapshot Testing
224
+
225
+ ```csharp
226
+ // Útil para DTOs complejos, HTML generado, respuestas de API
227
+ [Fact]
228
+ public async Task ObtenerReporte_DebeMatchSnapshot()
229
+ {
230
+ var reporte = await _svc.GenerarReporteAsync(empresaId);
231
+
232
+ // Primera ejecución: crea el archivo .verified.txt
233
+ // Siguientes: compara contra el snapshot
234
+ await Verify(reporte)
235
+ .ScrubMember<ReporteDto>(r => r.FechaGeneracion); // excluir campos volátiles
236
+ }
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Anti-patrones
242
+
243
+ ### Sleep en tests — NUNCA
244
+
245
+ ```csharp
246
+ // MAL — flaky e innecesario
247
+ await Task.Delay(1000);
248
+ Assert.True(resultado.Procesado);
249
+
250
+ // BIEN — usar Polly o un mecanismo de espera explícito
251
+ await Policy.Handle<AssertionException>()
252
+ .WaitAndRetryAsync(5, _ => TimeSpan.FromMilliseconds(200))
253
+ .ExecuteAsync(async () =>
254
+ {
255
+ var r = await _svc.ObtenerAsync(id);
256
+ r.Procesado.Should().BeTrue();
257
+ });
258
+ ```
259
+
260
+ ### Tests que dependen del orden — NUNCA
261
+
262
+ ```csharp
263
+ // MAL — test 2 asume que test 1 ya insertó datos
264
+ // BIEN — cada test crea sus propios datos con Bogus/factories
265
+ ```
266
+
267
+ ---
268
+
269
+ ## Gotchas / Errores comunes no obvios
270
+
271
+ **`WebApplicationFactory` con `IClassFixture<T>` comparte el servidor entre todos los tests de la clase — los datos de un test contaminan el siguiente**: el servidor y la BD del `WebApplicationFactory` son compartidos dentro de un `IClassFixture`. Si un test crea una entidad, el siguiente test la puede encontrar. Fix: usar `IAsyncLifetime` en la clase de test para truncar tablas en `InitializeAsync`, o envolver cada test en una transacción con rollback.
272
+
273
+ **NSubstitute `.Returns()` en un método que retorna `Task` sin `await` no suspende realmente el test**: `sub.ObtenerAsync().Returns(Task.FromResult(entidad))` funciona, pero `sub.ObtenerAsync().Returns(entidad)` puede no compilar o retornar un `Task` ya completado que nunca se awaita. Fix: siempre usar `.Returns(Task.FromResult(valor))` o `.Returns(x => Task.FromResult(entidad))` para métodos async en NSubstitute.
274
+
275
+ **`Bogus.Faker<T>` genera los mismos valores si se crea sin semilla diferente por test**: por defecto `new Faker<T>()` usa una semilla aleatoria diferente en cada ejecución — esto hace que los tests sean no reproducibles cuando fallan. Fix: en tests que requieren reproducibilidad, usar `new Faker<T>().UseSeed(42)` con semilla fija, o guardar la semilla en el output del test fallido.
276
+
277
+ **FluentAssertions `BeEquivalentTo` compara propiedades por nombre y no detecta diferencias en tipos distintos con mismos nombres**: `expected.Should().BeEquivalentTo(actual)` puede pasar aunque `expected` sea un DTO y `actual` sea la entidad, porque las propiedades homónimas coinciden. Fix: usar `.BeOfType<T>()` antes de `BeEquivalentTo` cuando se quiere verificar que el tipo exacto también coincide.
278
+
279
+ ## Checklist de tests
280
+
281
+ - [ ] Naming sigue Should_When (o Debe_Cuando en español)
282
+ - [ ] Sin Task.Delay/Thread.Sleep en tests
283
+ - [ ] Cada test crea sus datos (no depende de otro test)
284
+ - [ ] WebApplicationFactory usa TestContainers para BD real
285
+ - [ ] Cobertura >= 80% verificada con coverlet en CI
286
+ - [ ] Factories de datos en Tests/Factories/, no inline