@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,296 @@
1
+ ---
2
+ name: rust-patrones
3
+ description: >
4
+ Patrones idiomaticos de Rust: newtype, builder con typestate, From/Into,
5
+ RAII con Drop, iteradores custom, smart pointers y interior mutability.
6
+ Cargar cuando se diseñe arquitectura Rust o se refactorice código existente.
7
+ version: "1.0.0"
8
+ herramientasPermitidas: [Read, Glob, Grep]
9
+ exclusiones:
10
+ - "No cargar para implementar servicios Rust, APIs HTTP o lógica concurrente — para implementación cargar `rust-experto`."
11
+ - "No cargar para escribir tests Rust — para testing cargar `rust-testing`."
12
+ - "No cargar para errores de compilación Rust — para build errors cargar `build-errors-rust`."
13
+ - "No cargar para patrones de diseño en otros lenguajes — newtype y typestate son patrones idiomáticos de Rust no directamente aplicables en lenguajes con GC."
14
+ evolvable: true # default para skill estandar
15
+ ---
16
+ # Rust Patrones — Diseño Idiomático Rust
17
+
18
+ Cubre los patrones que producen código Rust seguro, expresivo y mantenible:
19
+ newtype para tipos fuertes, builder con typestate, conversiones con From/Into,
20
+ RAII con Drop, iteradores custom y uso correcto de smart pointers.
21
+
22
+ ## Cuándo cargar este skill
23
+
24
+ Invoca `Skill("rust-patrones")` cuando:
25
+
26
+ - Se diseñen tipos de dominio en Rust (IDs, cantidades, valores monetarios)
27
+ - Se implemente el patrón builder para structs con muchos campos opcionales
28
+ - Se revise código con clonaciones excesivas o unsafe innecesario
29
+ - Se diseñen iteradores custom o adaptadores de iterador
30
+ - Se elija entre Box, Rc, Arc, Cell y RefCell
31
+
32
+ ## Cuándo NO cargar
33
+
34
+ - La pregunta es sobre implementar servicios Rust, APIs HTTP o async con Tokio — para implementación cargar `rust-experto`.
35
+ - La tarea es escribir tests Rust — cargar `rust-testing`.
36
+ - Los errores son de compilación Rust (borrow checker, lifetime errors) — cargar `build-errors-rust`.
37
+ - Los patrones buscados son de otro lenguaje — newtype y typestate son específicos de Rust; en lenguajes con GC los patrones equivalentes son distintos.
38
+
39
+ ## Conceptos clave
40
+
41
+ ### Newtype Pattern
42
+
43
+ Envuelve un tipo primitivo en un struct de un campo (`struct UserId(Uuid)`).
44
+ Aporta type safety en compilación sin costo en runtime. El compilador rechaza
45
+ pasar un `UserId` donde se espera un `OrderId`, aunque ambos sean `Uuid` internamente.
46
+
47
+ ### Typestate Pattern
48
+
49
+ Codifica el estado válido de un objeto en el tipo, no en campos de estado.
50
+ Las transiciones inválidas son errores de compilación, no de runtime.
51
+
52
+ ### RAII (Resource Acquisition Is Initialization)
53
+
54
+ El trait `Drop` garantiza que los recursos se liberan cuando el dueño sale de
55
+ scope, incluso en presencia de panic. Conexiones, archivos y locks se cierran
56
+ automáticamente.
57
+
58
+ ## Reglas obligatorias
59
+
60
+ ### Newtype para todo ID de dominio — nunca Uuid crudo como parámetro
61
+
62
+ Pasar `Uuid` directamente permite confundir IDs de distintas entidades. Un
63
+ newtype con `#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]` y conversión
64
+ desde Uuid cuesta cero en runtime.
65
+
66
+ ```rust
67
+ // MAL — nada impide pasar client_id donde se espera order_id
68
+ fn transferir(desde: Uuid, hacia: Uuid, monto: Decimal) { ... }
69
+
70
+ // BIEN — el compilador rechaza el orden equivocado
71
+ fn transferir(desde: CuentaId, hacia: CuentaId, monto: Dinero) { ... }
72
+ ```
73
+
74
+ ### Implementar From — NUNCA conversiones con unwrap en el sitio de uso
75
+
76
+ `impl From<A> for B` permite `B::from(a)` y habilita el operador `?` para
77
+ `Into`. Centraliza la lógica de conversión y elimina conversiones repetidas.
78
+
79
+ ### Cow<str> para funciones que a veces alocan y a veces no
80
+
81
+ `Cow<'a, str>` retorna una referencia cuando el input no necesita modificarse
82
+ y un String cuando sí. Evita alocar siempre o cambiar la firma según el caso.
83
+
84
+ ### RefCell solo en contextos single-thread — Mutex en multi-thread
85
+
86
+ `RefCell` paniquea en runtime si hay más de un borrow mutable simultáneo.
87
+ Solo es correcto en código single-thread (sin `Send`). En multi-thread usar `Mutex`.
88
+
89
+ ## Patrones recomendados
90
+
91
+ ### Newtype con conversiones
92
+
93
+ ```rust
94
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
95
+ pub struct PedidoId(Uuid);
96
+
97
+ impl PedidoId {
98
+ pub fn nuevo() -> Self { Self(Uuid::new_v4()) }
99
+ pub fn inner(self) -> Uuid { self.0 }
100
+ }
101
+
102
+ impl From<Uuid> for PedidoId {
103
+ fn from(id: Uuid) -> Self { Self(id) }
104
+ }
105
+
106
+ impl fmt::Display for PedidoId {
107
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108
+ write!(f, "{}", self.0)
109
+ }
110
+ }
111
+ ```
112
+
113
+ ### Builder con typestate
114
+
115
+ ```rust
116
+ pub struct Borrador;
117
+ pub struct Listo;
118
+
119
+ pub struct PedidoBuilder<Estado> {
120
+ cliente_id: Option<ClienteId>,
121
+ items: Vec<ItemPedido>,
122
+ _estado: PhantomData<Estado>,
123
+ }
124
+
125
+ impl PedidoBuilder<Borrador> {
126
+ pub fn nuevo() -> Self {
127
+ Self { cliente_id: None, items: vec![], _estado: PhantomData }
128
+ }
129
+
130
+ pub fn cliente(mut self, id: ClienteId) -> Self {
131
+ self.cliente_id = Some(id);
132
+ self
133
+ }
134
+
135
+ pub fn item(mut self, item: ItemPedido) -> Self {
136
+ self.items.push(item);
137
+ self
138
+ }
139
+
140
+ // Solo disponible cuando hay cliente Y al menos un item
141
+ pub fn listo(self) -> Result<PedidoBuilder<Listo>, BuildError> {
142
+ if self.cliente_id.is_none() { return Err(BuildError::SinCliente); }
143
+ if self.items.is_empty() { return Err(BuildError::SinItems); }
144
+ Ok(PedidoBuilder { cliente_id: self.cliente_id, items: self.items, _estado: PhantomData })
145
+ }
146
+ }
147
+
148
+ impl PedidoBuilder<Listo> {
149
+ pub fn construir(self) -> Pedido {
150
+ Pedido::new(self.cliente_id.unwrap(), self.items) // safe: typestate garantiza que existe
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### From/Into para conversiones de dominio
156
+
157
+ ```rust
158
+ impl From<PedidoRow> for Pedido {
159
+ fn from(row: PedidoRow) -> Self {
160
+ Pedido {
161
+ id: PedidoId::from(row.id),
162
+ cliente_id: ClienteId::from(row.cliente_id),
163
+ total: row.total,
164
+ estado: Estado::from(row.estado_str.as_str()),
165
+ }
166
+ }
167
+ }
168
+
169
+ // Uso con operador ? en contextos que retornan Result<_, ConversionError>
170
+ impl TryFrom<&str> for Estado {
171
+ type Error = ParseEstadoError;
172
+ fn try_from(s: &str) -> Result<Self, Self::Error> {
173
+ match s {
174
+ "borrador" => Ok(Estado::Borrador),
175
+ "confirmado" => Ok(Estado::Confirmado),
176
+ "cancelado" => Ok(Estado::Cancelado),
177
+ other => Err(ParseEstadoError(other.to_string())),
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ ### RAII con Drop para recursos
184
+
185
+ ```rust
186
+ pub struct ConexionBD {
187
+ conn: Option<PgConnection>,
188
+ pool: Arc<Pool>,
189
+ }
190
+
191
+ impl Drop for ConexionBD {
192
+ fn drop(&mut self) {
193
+ if let Some(conn) = self.conn.take() {
194
+ self.pool.devolver(conn); // se ejecuta incluso en panic
195
+ }
196
+ }
197
+ }
198
+ ```
199
+
200
+ ### Iterador custom
201
+
202
+ ```rust
203
+ pub struct PaginaIter<'a> {
204
+ items: &'a [Pedido],
205
+ pos: usize,
206
+ tamano_pagina: usize,
207
+ }
208
+
209
+ impl<'a> Iterator for PaginaIter<'a> {
210
+ type Item = &'a [Pedido];
211
+
212
+ fn next(&mut self) -> Option<Self::Item> {
213
+ if self.pos >= self.items.len() { return None; }
214
+ let fin = (self.pos + self.tamano_pagina).min(self.items.len());
215
+ let pagina = &self.items[self.pos..fin];
216
+ self.pos = fin;
217
+ Some(pagina)
218
+ }
219
+ }
220
+ ```
221
+
222
+ ### Cow para funciones mixtas
223
+
224
+ ```rust
225
+ use std::borrow::Cow;
226
+
227
+ fn normalizar_email(email: &str) -> Cow<str> {
228
+ if email.chars().any(|c| c.is_uppercase()) {
229
+ Cow::Owned(email.to_lowercase()) // aloca solo cuando es necesario
230
+ } else {
231
+ Cow::Borrowed(email) // referencia directa sin aloca
232
+ }
233
+ }
234
+ ```
235
+
236
+ ## Anti-patrones conocidos
237
+
238
+ ### Stringly-typed — strings para conceptos con dominio cerrado
239
+
240
+ ```rust
241
+ // MAL — cualquier string es valido en compilacion
242
+ fn cambiar_estado(pedido: &mut Pedido, estado: &str) {
243
+ pedido.estado = estado.to_string(); // "activo", "Activo", "ACTIVO"... todos pasan
244
+ }
245
+
246
+ // BIEN — enum exhaustivo
247
+ fn cambiar_estado(pedido: &mut Pedido, estado: EstadoPedido) { ... }
248
+ ```
249
+
250
+ ### Clone excesivo para satisfacer al borrow checker
251
+
252
+ ```rust
253
+ // MAL — clonar solo para evitar mover
254
+ let nombre = usuario.nombre.clone();
255
+ let respuesta = construir_respuesta(nombre);
256
+ enviar_log(usuario.nombre.clone()); // ya podria haber usado &usuario.nombre
257
+
258
+ // BIEN — restructurar para minimizar clones
259
+ enviar_log(&usuario.nombre);
260
+ let respuesta = construir_respuesta(&usuario.nombre);
261
+ ```
262
+
263
+ ### Ignorar Drop al usar ManuallyDrop
264
+
265
+ ```rust
266
+ // MAL — ManuallyDrop sin plan de liberacion
267
+ let valor = ManuallyDrop::new(recurso_importante);
268
+ // recurso_importante nunca se libera si no se llama ManuallyDrop::drop
269
+
270
+ // BIEN — Solo ManuallyDrop cuando se transfiere ownership a FFI con
271
+ // documentacion explicita de quien es responsable de liberar
272
+ ```
273
+
274
+ ## Checklist de verificación
275
+
276
+ - [ ] Cada ID de dominio es un newtype, no un Uuid/u64 crudo
277
+ - [ ] Builder pattern con typestate cuando hay precondiciones de construcción
278
+ - [ ] From/Into implementado para conversiones entre capas (row -> domain)
279
+ - [ ] TryFrom para conversiones que pueden fallar, no unwrap en el sitio
280
+ - [ ] Drop implementado para structs que manejan recursos externos
281
+ - [ ] Cow<str> en funciones que a veces modifican y a veces no
282
+ - [ ] RefCell solo en single-thread; Mutex en multi-thread
283
+ - [ ] Sin unsafe sin comentario explicando invariante que lo justifica
284
+
285
+ ## Gotchas / Errores comunes no obvios
286
+
287
+ **Newtype que implementa `Deref<Target=T>` puede confundirse con `T` en inferencia de tipos**: si `struct UserId(Uuid)` implementa `Deref<Target=Uuid>`, el compilador puede inferir el tipo `Uuid` en contextos donde se espera `UserId`, anulando la protección del newtype. Fix: no implementar `Deref` en newtypes de dominio cuyo propósito es distinguir tipos; si se necesita acceso al inner, exponer un método `fn inner(&self) -> &Uuid`.
288
+
289
+ **Builder con typestate no compila con `Box<dyn Builder<State>>` para builders almacenados dinámicamente**: el typestate usa tipos genéricos como phantom data, lo que hace que diferentes estados del builder sean tipos distintos que no tienen un ancestro común en el type system. Fix: si se necesita almacenar builders dinámicamente, usar un enum en lugar de typestate, o aceptar que el builder con typestate solo funciona en contextos donde el tipo completo es conocido en compile time.
290
+
291
+ **`From<T> for U` no implementa automáticamente `TryFrom<T> for U`**: si se define `From<RawRow> for Entidad`, esto da `Into<Entidad>` automáticamente, pero `TryFrom` no se infiere — hay que implementarlo por separado si la conversión puede fallar. Causa: `From` es infallible por definición. Fix: implementar `TryFrom<RawRow> for Entidad` con error tipado cuando la conversión puede fallar, y usar `From` solo cuando la conversión es garantizada.
292
+
293
+ **`impl Iterator for MiTipo` con `type Item = &'a T` requiere lifetime explícito en la implementación**: si el iterador retorna referencias a datos que viven en la colección que itera, el lifetime debe ser explícito tanto en la struct del iterador como en el `impl`. El compilador puede sugerir lifetimes incorrectos en mensajes de error. Fix: anotar el lifetime de la referencia al dato origen en la struct del iterador: `struct Iter<'a, T> { inner: &'a [T], pos: usize }`.
294
+
295
+ ---
296
+ *Skill creado con swl:crear-skill el 2026-03-31. Versión 1.0.0.*
@@ -0,0 +1,311 @@
1
+ ---
2
+ name: rust-testing
3
+ description: >
4
+ Testing Rust con rstest, proptest, mockall y cargo-llvm-cov. Cubre tests
5
+ inline con #[cfg(test)], async tests con tokio::test, integration tests
6
+ y doc tests. Cargar cuando se escriban tests Rust o se configure cobertura.
7
+ version: "1.0.0"
8
+ herramientasPermitidas: [Read, Grep]
9
+ exclusiones:
10
+ - "No cargar para implementar el código Rust de producción — primero implementar con `rust-experto`, luego escribir tests."
11
+ - "No cargar para errores de compilación Rust en los tests — para build errors cargar `build-errors-rust`."
12
+ - "No cargar para benchmarks avanzados con criterion o divan — esas herramientas requieren configuración específica no cubierta en este skill de testing estándar."
13
+ - "No cargar para tests de otros lenguajes — este skill cubre el ecosistema de testing de Rust específicamente."
14
+ evolvable: true # default para skill estandar
15
+ ---
16
+ # Rust Testing — rstest, proptest y Cobertura
17
+
18
+ Cubre el ecosistema de testing Rust: tests inline, rstest para fixtures y
19
+ parametrizados, proptest para property-based testing, mockall para mocks de
20
+ traits, async tests con tokio::test y cargo-llvm-cov para cobertura.
21
+
22
+ ## Cuándo cargar este skill
23
+
24
+ Invoca `Skill("rust-testing")` cuando:
25
+
26
+ - Se escriban tests unitarios o de integración en Rust
27
+ - Se use rstest para fixtures compartidos o tests parametrizados
28
+ - Se implemente property-based testing con proptest
29
+ - Se mocken traits con mockall
30
+ - Se configure cobertura con cargo-llvm-cov
31
+
32
+ ## Cuándo NO cargar
33
+
34
+ - El código Rust de producción aún no está implementado — primero implementar con `rust-experto`, luego escribir tests.
35
+ - Los errores son de compilación Rust en los archivos de test — cargar `build-errors-rust`.
36
+ - La pregunta es sobre benchmarks avanzados con criterion o divan — esas herramientas tienen su propio flujo de configuración no cubierto en este skill.
37
+ - Los tests son de otro lenguaje — este skill cubre el ecosistema de testing específico de Rust.
38
+
39
+ ## Conceptos clave
40
+
41
+ ### Tests inline con #[cfg(test)]
42
+
43
+ El módulo `#[cfg(test)]` en el mismo archivo que el código bajo prueba tiene
44
+ acceso a items privados. Es el lugar correcto para tests unitarios de implementación.
45
+ Los integration tests en `tests/` prueban solo la API pública del crate.
46
+
47
+ ### rstest
48
+
49
+ `rstest` permite fixtures inyectados automáticamente y casos de prueba declarativos
50
+ con `#[rstest]` y `#[case(...)]`. Reduce el boilerplate de setup compartido.
51
+
52
+ ### proptest
53
+
54
+ Genera inputs aleatorios que satisfacen una estrategia y ejecuta el test cientos
55
+ de veces. Encoge (shrinks) el input fallido al caso más pequeño que reproduce el fallo.
56
+
57
+ ## Reglas obligatorias
58
+
59
+ ### assert_eq! con mensaje — facilita debugging
60
+
61
+ Siempre agregar un mensaje de contexto en assertions no triviales:
62
+ `assert_eq!(got, want, "al calcular descuento con precio={}", precio)`
63
+
64
+ ### #[tokio::test] para tests async — no block_on manual
65
+
66
+ ```rust
67
+ // MAL
68
+ #[test]
69
+ fn test_crear_pedido() {
70
+ let result = tokio::runtime::Runtime::new()
71
+ .unwrap()
72
+ .block_on(crear_pedido(req));
73
+ }
74
+
75
+ // BIEN
76
+ #[tokio::test]
77
+ async fn test_crear_pedido() {
78
+ let result = crear_pedido(req).await;
79
+ assert!(result.is_ok());
80
+ }
81
+ ```
82
+
83
+ ### Integration tests usan solo API pública del crate
84
+
85
+ Los tests en `tests/` no importan módulos internos con `use mi_crate::internal::`.
86
+ Si necesitas acceder a internos, el test debe estar en un módulo `#[cfg(test)]`.
87
+
88
+ ### mockall solo en el módulo de test — no en producción
89
+
90
+ Los mocks generados por `#[automock]` aumentan el binario. El atributo
91
+ `#[cfg_attr(test, automock)]` aplica la macro solo al compilar tests.
92
+
93
+ ## Patrones recomendados
94
+
95
+ ### Test unitario inline con acceso a privados
96
+
97
+ ```rust
98
+ // src/pedido.rs
99
+ pub struct Pedido {
100
+ id: Uuid,
101
+ estado: Estado,
102
+ items: Vec<Item>,
103
+ }
104
+
105
+ impl Pedido {
106
+ fn calcular_subtotal(&self) -> Decimal { /* ... */ }
107
+ }
108
+
109
+ #[cfg(test)]
110
+ mod tests {
111
+ use super::*; // accede a calcular_subtotal aunque sea privada
112
+
113
+ #[test]
114
+ fn subtotal_suma_precio_por_cantidad() {
115
+ let pedido = Pedido {
116
+ id: Uuid::new_v4(),
117
+ estado: Estado::Borrador,
118
+ items: vec![
119
+ Item::new(Decimal::new(100, 0), 2),
120
+ Item::new(Decimal::new(50, 0), 1),
121
+ ],
122
+ };
123
+ assert_eq!(
124
+ pedido.calcular_subtotal(),
125
+ Decimal::new(250, 0),
126
+ "subtotal debe ser suma de precio*cantidad"
127
+ );
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### rstest con fixtures y casos parametrizados
133
+
134
+ ```rust
135
+ use rstest::*;
136
+
137
+ #[fixture]
138
+ fn pedido_borrador() -> Pedido {
139
+ Pedido::nuevo(ClienteId::new_v4())
140
+ }
141
+
142
+ #[fixture]
143
+ fn pedido_confirmado(pedido_borrador: Pedido) -> Pedido {
144
+ pedido_borrador.confirmar().unwrap()
145
+ }
146
+
147
+ #[rstest]
148
+ #[case(Estado::Borrador, true)]
149
+ #[case(Estado::Confirmado, false)]
150
+ #[case(Estado::Cancelado, false)]
151
+ fn puede_cancelar_solo_en_estado_borrador(
152
+ #[case] estado: Estado,
153
+ #[case] esperado: bool,
154
+ pedido_borrador: Pedido,
155
+ ) {
156
+ let pedido = pedido_borrador.con_estado(estado);
157
+ assert_eq!(pedido.puede_cancelar(), esperado);
158
+ }
159
+ ```
160
+
161
+ ### proptest para invariantes de dominio
162
+
163
+ ```rust
164
+ use proptest::prelude::*;
165
+
166
+ proptest! {
167
+ #[test]
168
+ fn descuento_nunca_supera_precio(
169
+ precio in 0.01f64..10_000.0,
170
+ porcentaje in 0u8..=100,
171
+ ) {
172
+ let descuento = calcular_descuento(precio, porcentaje);
173
+ prop_assert!(
174
+ descuento <= precio,
175
+ "descuento {} supero precio {}", descuento, precio
176
+ );
177
+ prop_assert!(descuento >= 0.0);
178
+ }
179
+ }
180
+ ```
181
+
182
+ ### mockall para traits
183
+
184
+ ```rust
185
+ use mockall::automock;
186
+
187
+ #[cfg_attr(test, automock)]
188
+ pub trait PedidoRepository: Send + Sync {
189
+ async fn obtener(&self, id: Uuid) -> Result<Pedido, AppError>;
190
+ async fn guardar(&self, pedido: &Pedido) -> Result<(), AppError>;
191
+ }
192
+
193
+ #[cfg(test)]
194
+ mod tests {
195
+ use super::*;
196
+ use mockall::predicate::*;
197
+
198
+ #[tokio::test]
199
+ async fn service_retorna_error_cuando_repo_falla() {
200
+ let mut mock = MockPedidoRepository::new();
201
+ mock.expect_obtener()
202
+ .with(eq(id_prueba()))
203
+ .returning(|_| Err(AppError::NotFound("no existe".into())));
204
+
205
+ let service = PedidoService::new(Arc::new(mock));
206
+ let resultado = service.obtener(id_prueba()).await;
207
+
208
+ assert!(matches!(resultado, Err(AppError::NotFound(_))));
209
+ }
210
+ }
211
+ ```
212
+
213
+ ### assert_matches! para pattern matching en assertions
214
+
215
+ ```rust
216
+ use std::assert_matches::assert_matches;
217
+
218
+ let resultado = service.crear(req_invalido).await;
219
+ assert_matches!(
220
+ resultado,
221
+ Err(AppError::Validation(msg)) if msg.contains("cliente_id")
222
+ );
223
+ ```
224
+
225
+ ### Configurar cargo-llvm-cov
226
+
227
+ ```toml
228
+ # .cargo/config.toml
229
+ [alias]
230
+ cov = "llvm-cov --lcov --output-path lcov.info"
231
+ cov-html = "llvm-cov --html"
232
+ ```
233
+
234
+ ```bash
235
+ cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
236
+ # Verificar cobertura mínima del 80%
237
+ cargo llvm-cov --all-features --workspace --fail-under-lines 80
238
+ ```
239
+
240
+ ## Anti-patrones conocidos
241
+
242
+ ### unwrap() en tests sin mensaje de contexto
243
+
244
+ ```rust
245
+ // MAL — panic con mensaje generico "called unwrap on None"
246
+ let pedido = repo.obtener(id).await.unwrap();
247
+
248
+ // BIEN — mensaje que indica que estaba probando
249
+ let pedido = repo.obtener(id).await
250
+ .expect("deberia encontrar el pedido insertado en el fixture");
251
+ ```
252
+
253
+ ### Tests que dependen de orden de ejecución
254
+
255
+ ```rust
256
+ // MAL — modifica estado global, falla si otro test corre primero
257
+ static CONTADOR: AtomicU32 = AtomicU32::new(0);
258
+ #[test]
259
+ fn test_a() { CONTADOR.fetch_add(1, Ordering::SeqCst); }
260
+ #[test]
261
+ fn test_b() { assert_eq!(CONTADOR.load(Ordering::SeqCst), 1); } // fragil
262
+
263
+ // BIEN — cada test es autocontenido
264
+ #[test]
265
+ fn test_b() {
266
+ let mut contador = 0u32;
267
+ incrementar(&mut contador);
268
+ assert_eq!(contador, 1);
269
+ }
270
+ ```
271
+
272
+ ### Doc tests para ejemplos no compilables
273
+
274
+ ```rust
275
+ /// Calcula el descuento.
276
+ ///
277
+ /// # Examples
278
+ /// ```no_run
279
+ /// // MAL — no_run significa que nunca se verifica que compile
280
+ /// let d = calcular_descuento(100.0, 10);
281
+ /// ```
282
+ ///
283
+ /// ```
284
+ /// // BIEN — el ejemplo compila y se ejecuta en cargo test
285
+ /// use mi_crate::calcular_descuento;
286
+ /// assert_eq!(calcular_descuento(100.0, 10), 90.0);
287
+ /// ```
288
+ ```
289
+
290
+ ## Checklist de verificación
291
+
292
+ - [ ] Tests unitarios en módulo #[cfg(test)] en el mismo archivo
293
+ - [ ] Tests async usan #[tokio::test], no block_on manual
294
+ - [ ] rstest para fixtures compartidos y casos parametrizados
295
+ - [ ] proptest para invariantes de dominio con inputs generados
296
+ - [ ] mockall con #[cfg_attr(test, automock)], no en código de producción
297
+ - [ ] assert_eq! con mensaje descriptivo en assertions no triviales
298
+ - [ ] cargo-llvm-cov configurado con umbral mínimo del 80%
299
+
300
+ ## Gotchas / Errores comunes no obvios
301
+
302
+ **`#[tokio::test]` sin `flavor = "multi_thread"` limita el paralelismo en tests async**: por defecto `#[tokio::test]` usa el runtime current-thread — si un test lanza múltiples tareas que esperan entre sí, puede producir un deadlock en el runtime single-thread que no ocurre en producción. Fix: usar `#[tokio::test(flavor = "multi_thread", worker_threads = 2)]` para tests que simulan concurrencia real.
303
+
304
+ **`mockall::automock` en un trait con métodos de retorno de tipo genérico requiere declarar el tipo concreto al configurar la expectativa**: `mock.expect_obtener().returning(|| vec![...])` puede fallar si el compilador no infiere el tipo de retorno genérico. Fix: especificar el tipo explícitamente en el `returning` con turbofish si es necesario, o definir un tipo concreto de retorno en el trait en lugar de genérico.
305
+
306
+ **Tests de integración en `tests/` no tienen acceso a funciones privadas o internas del crate**: si el test necesita inspeccionar estado interno que no es `pub`, el test de integración no puede hacerlo directamente. Causa: `tests/` es un crate separado que solo ve la API pública. Fix: mover el test a un módulo `#[cfg(test)]` inline en el módulo que necesita inspeccionar, o exponer una función de test pública con `#[doc(hidden)] pub fn __test_only_estado(&self)`.
307
+
308
+ **`proptest!` genera casos aleatorios que pueden no reproducirse sin la semilla**: cuando proptest encuentra un contraejemplo, lo imprime y lo guarda en `.proptest-regressions/`. Si el archivo no se commitea, el CI puede pasar sin el contraejemplo pero el bug persiste. Fix: committear el directorio `.proptest-regressions/` al repositorio para que el CI reproduzca los casos que fallaron en desarrollo.
309
+
310
+ ---
311
+ *Skill creado con swl:crear-skill el 2026-03-31. Versión 1.0.0.*