@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,250 @@
1
+ # Regla: Patrones de Diseño — Rust
2
+
3
+ Patrones idiomáticos de Rust para código de producción. El objetivo es aprovechar
4
+ el sistema de tipos y el ownership model para escribir código correcto por
5
+ construcción, no solo por convención.
6
+
7
+ ---
8
+
9
+ ## Error handling: thiserror y anyhow
10
+
11
+ **thiserror** para librerías (errores tipados que el llamador puede inspeccionar):
12
+
13
+ ```rust
14
+ use thiserror::Error;
15
+
16
+ #[derive(Debug, Error)]
17
+ pub enum FacturaError {
18
+ #[error("Factura no encontrada: {id}")]
19
+ NoEncontrada { id: u64 },
20
+
21
+ #[error("Total inválido: {total} (debe ser > 0)")]
22
+ TotalInvalido { total: f64 },
23
+
24
+ #[error("Error de base de datos")]
25
+ BaseDatos(#[from] sqlx::Error),
26
+ }
27
+ ```
28
+
29
+ **anyhow** para aplicaciones (propagación de errores con contexto):
30
+
31
+ ```rust
32
+ use anyhow::{Context, Result};
33
+
34
+ async fn cargar_config() -> Result<Config> {
35
+ let ruta = env::var("CONFIG_PATH")
36
+ .context("Variable CONFIG_PATH no definida")?;
37
+
38
+ let contenido = fs::read_to_string(&ruta)
39
+ .with_context(|| format!("No se pudo leer el archivo: {ruta}"))?;
40
+
41
+ toml::from_str(&contenido)
42
+ .context("Formato de configuración inválido")
43
+ }
44
+ ```
45
+
46
+ - NUNCA mezclar: `thiserror` en librerías, `anyhow` en binarios/aplicaciones.
47
+ - NUNCA retornar `Box<dyn Error>` — usar `anyhow::Error` o un tipo específico.
48
+
49
+ ---
50
+
51
+ ## Builder pattern para structs complejos
52
+
53
+ Cuando un struct tiene más de 4 campos o campos opcionales, usar builder:
54
+
55
+ ```rust
56
+ // MAL — constructor con muchos parámetros, difícil de leer
57
+ let factura = Factura::new(123, "cliente@email.com", 1500.0, None, true, "MXN");
58
+
59
+ // BIEN — builder con nombres explícitos
60
+ let factura = Factura::builder()
61
+ .id(123)
62
+ .cliente("cliente@email.com")
63
+ .total(1500.0)
64
+ .moneda("MXN")
65
+ .build()?;
66
+ ```
67
+
68
+ - El método `build()` retorna `Result<T, Error>` para validar invariantes.
69
+ - Usar el crate `derive_builder` para casos simples.
70
+ - Para builders complejos con validación, implementar manualmente.
71
+
72
+ ---
73
+
74
+ ## Newtype pattern para type safety
75
+
76
+ Envolver tipos primitivos para que el compilador detecte usos incorrectos:
77
+
78
+ ```rust
79
+ // MAL — dos u64 intercambiables, el compilador no detecta el error
80
+ fn transferir(origen: u64, destino: u64, monto: f64) { ... }
81
+ transferir(cuenta_destino, cuenta_origen, 100.0); // invertidos, sin error
82
+
83
+ // BIEN — tipos distintos que el compilador distingue
84
+ struct CuentaId(u64);
85
+ struct Monto(f64);
86
+
87
+ fn transferir(origen: CuentaId, destino: CuentaId, monto: Monto) { ... }
88
+ // transferir(cuenta_destino, cuenta_origen, monto); // ERROR DE COMPILACIÓN
89
+ ```
90
+
91
+ - Implementar `Display`, `Debug`, `From<u64>` y `Into<u64>` según necesidad.
92
+ - Implementar `Deref` solo cuando el newtype ES el tipo interno (no solo lo contiene).
93
+
94
+ ---
95
+
96
+ ## Trait objects vs generics
97
+
98
+ | Situación | Usar | Razón |
99
+ |-----------|------|-------|
100
+ | Tipo conocido en compilación, performance crítica | `impl Trait` / genéricos | Monomorphization, sin overhead |
101
+ | Colección heterogénea de implementadores | `Box<dyn Trait>` | Dispatch dinámico necesario |
102
+ | Trait object en función | `&dyn Trait` | Sin heap allocation |
103
+ | Tamaño del binario importa | Genéricos con cuidado | Monomorphization puede inflarlo |
104
+
105
+ ```rust
106
+ // Genéricos — dispatch estático, cero overhead
107
+ fn procesar<T: Pagable>(item: &T) -> Resultado { ... }
108
+
109
+ // Trait object — dispatch dinámico, cuando el tipo varía en runtime
110
+ fn registrar_handler(handler: Box<dyn EventHandler>) { ... }
111
+ ```
112
+
113
+ ---
114
+
115
+ ## From/Into para conversiones idiomáticas
116
+
117
+ Implementar `From<T>` automáticamente proporciona `Into<T>`:
118
+
119
+ ```rust
120
+ impl From<FacturaDb> for Factura {
121
+ fn from(db: FacturaDb) -> Self {
122
+ Factura {
123
+ id: FacturaId(db.id),
124
+ total: Monto(db.total),
125
+ estatus: db.estatus.parse().unwrap_or_default(),
126
+ }
127
+ }
128
+ }
129
+
130
+ // El llamador puede usar From o Into indistintamente
131
+ let factura = Factura::from(fila_db);
132
+ let factura: Factura = fila_db.into();
133
+ ```
134
+
135
+ - NUNCA implementar `Into<T>` directamente — implementar `From<T>` y dejar que
136
+ el compilador derive `Into<T>` automáticamente.
137
+ - Implementar `TryFrom<T>` cuando la conversión puede fallar.
138
+
139
+ ---
140
+
141
+ ## Option combinators
142
+
143
+ ```rust
144
+ // MAL — if-let verboso para transformaciones simples
145
+ let nombre_upper = if let Some(n) = usuario.nombre {
146
+ Some(n.to_uppercase())
147
+ } else {
148
+ None
149
+ };
150
+
151
+ // BIEN — combinators
152
+ let nombre_upper = usuario.nombre.map(|n| n.to_uppercase());
153
+
154
+ // MAL — unwrap con default innecesariamente verboso
155
+ let total = factura.total.unwrap_or(0.0);
156
+
157
+ // BIEN — unwrap_or_default cuando el default del tipo es correcto
158
+ let total = factura.total.unwrap_or_default(); // 0.0 para f64
159
+
160
+ // Cadena de operaciones con Option
161
+ let descuento = usuario
162
+ .membresia
163
+ .filter(|m| m.esta_activa())
164
+ .map(|m| m.porcentaje_descuento())
165
+ .unwrap_or(0.0);
166
+ ```
167
+
168
+ - `map` para transformar el valor interno.
169
+ - `and_then` para operaciones que pueden retornar `None`.
170
+ - `or_else` para proveer un alternativo si el valor es `None`.
171
+ - `unwrap_or_default` cuando el default del tipo es el valor correcto.
172
+ - `ok_or_else` para convertir `Option<T>` en `Result<T, E>`.
173
+
174
+ ---
175
+
176
+ ## Async con Tokio
177
+
178
+ ```rust
179
+ use tokio::{join, select, spawn};
180
+
181
+ // Ejecutar tareas independientes en paralelo
182
+ async fn cargar_datos(id: u64) -> Result<DatoCompleto> {
183
+ let (usuario, facturas) = join!(
184
+ repo.obtener_usuario(id),
185
+ repo.listar_facturas(id)
186
+ )?;
187
+ Ok(DatoCompleto { usuario, facturas })
188
+ }
189
+
190
+ // Spawn para background tasks
191
+ spawn(async move {
192
+ if let Err(e) = enviar_notificacion(evento).await {
193
+ tracing::error!("Error enviando notificación: {e}");
194
+ }
195
+ });
196
+
197
+ // Select para timeout o cancelación
198
+ select! {
199
+ resultado = operacion_lenta() => manejar(resultado),
200
+ _ = tokio::time::sleep(Duration::from_secs(30)) => {
201
+ return Err(Error::Timeout);
202
+ }
203
+ }
204
+ ```
205
+
206
+ - NUNCA usar `std::thread::sleep` en código async — usar `tokio::time::sleep`.
207
+ - NUNCA bloquear el thread de Tokio con operaciones sincrónicas largas.
208
+ Usar `tokio::task::spawn_blocking` para código CPU-intensivo o IO síncrono.
209
+ - `#[tokio::main]` solo en `main()`. El resto son funciones `async fn` normales.
210
+
211
+ ---
212
+
213
+ ## RAII: Drop trait para cleanup
214
+
215
+ ```rust
216
+ struct ConexionBd {
217
+ inner: pg::Connection,
218
+ }
219
+
220
+ impl Drop for ConexionBd {
221
+ fn drop(&mut self) {
222
+ // Se ejecuta automáticamente al salir del scope
223
+ if let Err(e) = self.inner.cerrar() {
224
+ tracing::warn!("Error cerrando conexión: {e}");
225
+ }
226
+ }
227
+ }
228
+
229
+ // El cleanup es automático — no hay finally ni try/catch necesario
230
+ {
231
+ let conn = ConexionBd::conectar(&url)?;
232
+ conn.ejecutar(query)?;
233
+ } // conn.drop() se llama aquí automáticamente
234
+ ```
235
+
236
+ - Usar RAII para recursos que necesiten cleanup garantizado.
237
+ - Los guardas de Mutex (`MutexGuard`) son RAII — liberan el lock al salir del scope.
238
+
239
+ ---
240
+
241
+ ## Checklist de patrones antes de hacer merge
242
+
243
+ - [ ] Errores de librería usan `thiserror`, errores de aplicación usan `anyhow`
244
+ - [ ] Sin `Box<dyn Error>` como tipo de retorno
245
+ - [ ] Structs complejos (>4 campos opcionales) usan builder pattern
246
+ - [ ] IDs y valores de dominio usan newtype pattern
247
+ - [ ] Sin `unwrap()` en `src/` fuera de tests (ver regla de estilo)
248
+ - [ ] Option manejado con combinators, no con if-let cuando es una transformación
249
+ - [ ] Tareas async independientes usand `join!` para ejecución paralela
250
+ - [ ] Sin bloqueo del runtime async con operaciones síncronas largas
@@ -0,0 +1,221 @@
1
+ # Regla: Seguridad — Rust
2
+
3
+ Rust elimina por diseño clases enteras de vulnerabilidades (buffer overflows,
4
+ use-after-free, data races). Sin embargo, existen vectores de ataque específicos
5
+ de Rust que requieren disciplina explícita. Esta regla cubre lo que el compilador
6
+ no puede garantizar por sí solo.
7
+
8
+ ---
9
+
10
+ ## cargo-audit para CVEs en dependencias
11
+
12
+ ```bash
13
+ # Instalar
14
+ cargo install cargo-audit
15
+
16
+ # Ejecutar auditoría
17
+ cargo audit
18
+
19
+ # Con política estricta — falla si hay cualquier vulnerabilidad
20
+ cargo audit --deny warnings
21
+ ```
22
+
23
+ - `cargo audit` debe ejecutarse en CI **semanalmente** como job independiente.
24
+ - También ejecutar en el pipeline de PR si `Cargo.lock` cambia.
25
+ - Si un CVE no tiene fix disponible:
26
+ 1. Documentar en `Cargo.toml` como una excepción justificada con ticket.
27
+ 2. Evaluar si el vector de ataque aplica al uso real de la dependencia.
28
+ 3. Definir fecha límite para migrar o reemplazar la dependencia.
29
+ - NUNCA ignorar un CVE HIGH o CRITICAL sin aprobación explícita del equipo.
30
+
31
+ ---
32
+
33
+ ## cargo-deny para licencias y vulnerabilidades
34
+
35
+ ```bash
36
+ cargo install cargo-deny
37
+ cargo deny check
38
+ ```
39
+
40
+ `deny.toml` en la raíz del proyecto:
41
+
42
+ ```toml
43
+ [advisories]
44
+ vulnerability = "deny"
45
+ unmaintained = "warn"
46
+ unsound = "deny"
47
+
48
+ [licenses]
49
+ # Solo licencias compatibles con el proyecto
50
+ allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC"]
51
+ deny = ["GPL-2.0", "AGPL-3.0"]
52
+
53
+ [bans]
54
+ # Prohibir crates con historial de problemas de seguridad
55
+ deny = [
56
+ { name = "openssl", reason = "Usar rustls o native-tls verificados" },
57
+ ]
58
+ ```
59
+
60
+ - `cargo-deny` en CI detecta tanto vulnerabilidades como conflictos de licencia.
61
+ - Revisar y actualizar `deny.toml` cuando se agregan dependencias nuevas.
62
+
63
+ ---
64
+
65
+ ## unsafe: prohibido sin justificación en ADR
66
+
67
+ - `unsafe` desactiva las garantías del compilador. Todo bloque `unsafe` es
68
+ responsabilidad explícita del desarrollador — el compilador ya no verifica.
69
+ - **Regla**: todo uso de `unsafe` en el código del proyecto (no en dependencias)
70
+ requiere:
71
+ 1. Un comentario inmediatamente antes del bloque explicando POR QUÉ es seguro.
72
+ 2. Un ADR documentando la decisión si el `unsafe` es en código de librería.
73
+ 3. Revisión de seguridad explícita en el PR.
74
+
75
+ ```rust
76
+ // MAL — unsafe sin justificación
77
+ unsafe {
78
+ *ptr = valor;
79
+ }
80
+
81
+ // BIEN — unsafe con safety comment obligatorio
82
+ // SAFETY: ptr apunta a memoria válida y alineada porque
83
+ // fue obtenido de Box::into_raw() en la misma función y
84
+ // no ha sido liberado ni aliasado desde entonces.
85
+ unsafe {
86
+ *ptr = valor;
87
+ }
88
+ ```
89
+
90
+ - `#![forbid(unsafe_code)]` en crates que no necesitan `unsafe` — el compilador
91
+ rechaza cualquier bloque `unsafe` y protege contra PRs accidentales.
92
+ - Si se necesita `unsafe` en un módulo específico, aislar en un módulo dedicado
93
+ con interfaz safe hacia afuera.
94
+
95
+ ---
96
+
97
+ ## Miri para detectar undefined behavior
98
+
99
+ ```bash
100
+ # Instalar (requiere toolchain nightly)
101
+ rustup +nightly component add miri
102
+
103
+ # Ejecutar tests bajo Miri
104
+ cargo +nightly miri test
105
+ ```
106
+
107
+ - Miri ejecuta el código en un intérprete que detecta UB, accesos inválidos
108
+ a memoria y data races que ocurren en runtime.
109
+ - Ejecutar Miri en todo código que contiene `unsafe`.
110
+ - Miri puede ser lento — ejecutarlo como job separado en CI, no en cada PR.
111
+ - Si Miri reporta un error: es un bug real que debe corregirse, no ignorarse.
112
+
113
+ ---
114
+
115
+ ## No transmute sin revisión de seguridad
116
+
117
+ - `std::mem::transmute` reinterpreta los bits de un valor como otro tipo.
118
+ Es el operador más peligroso de Rust — puede violar todas las garantías del sistema de tipos.
119
+ - **Regla**: `transmute` está prohibido sin revisión explícita de seguridad
120
+ documentada en el PR y en el código.
121
+ - Alternativas que no requieren `transmute`:
122
+ - Conversión de números: `as` cast o `From`/`Into`
123
+ - Conversión de punteros: `pointer::cast()`
124
+ - Conversión de referencias: `pointer::cast()` con `unsafe` justificado
125
+ - Cambio de lifetime: rediseñar la API para que el compilador la acepte
126
+
127
+ ---
128
+
129
+ ## Secretos: no en const/static
130
+
131
+ ```rust
132
+ // MAL — la API key queda en el binario compilado y en el historial de git
133
+ const API_KEY: &str = "sk-prod-abc123xyz789";
134
+
135
+ // MAL — static mutable tampoco es seguro
136
+ static mut TOKEN: String = String::new();
137
+
138
+ // BIEN — leer de variable de entorno en runtime
139
+ fn cargar_config() -> Result<Config> {
140
+ Ok(Config {
141
+ api_key: env::var("API_KEY")
142
+ .context("Variable API_KEY no definida")?,
143
+ })
144
+ }
145
+ ```
146
+
147
+ - Las constantes en Rust se embeben en el binario. Un secreto en `const` puede
148
+ extraerse del ejecutable con herramientas básicas de análisis binario.
149
+ - Usar variables de entorno para secretos, inyectadas por el sistema de deployment.
150
+ - En desarrollo local: archivo `.env` (en `.gitignore`) con `dotenvy` crate.
151
+
152
+ ---
153
+
154
+ ## Validar inputs en boundaries del sistema
155
+
156
+ ```rust
157
+ use garde::Validate;
158
+
159
+ #[derive(Validate)]
160
+ pub struct NuevaFactura {
161
+ #[garde(length(min = 1, max = 255))]
162
+ pub descripcion: String,
163
+
164
+ #[garde(range(min = 0.01, max = 1_000_000.0))]
165
+ pub total: f64,
166
+
167
+ #[garde(email)]
168
+ pub cliente_email: String,
169
+ }
170
+
171
+ pub async fn crear_factura(
172
+ State(repo): State<Arc<FacturaRepo>>,
173
+ Json(input): Json<NuevaFactura>,
174
+ ) -> Result<Json<Factura>, AppError> {
175
+ input.validate(&())?; // Retorna error si algún campo es inválido
176
+ let factura = repo.crear(input).await?;
177
+ Ok(Json(factura))
178
+ }
179
+ ```
180
+
181
+ - Validar toda entrada externa (HTTP, archivos, CLI) en el boundary de entrada.
182
+ - No asumir que los datos de la base de datos son válidos si pueden haber sido
183
+ escritos por otros sistemas.
184
+ - Usar el crate `garde` o `validator` para validación declarativa.
185
+
186
+ ---
187
+
188
+ ## Pin para futures auto-referenciales
189
+
190
+ ```rust
191
+ use std::pin::Pin;
192
+ use futures::Future;
193
+
194
+ // Cuando un future contiene referencias a sí mismo, Pin garantiza
195
+ // que no se moverá en memoria mientras está pendiente.
196
+ type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
197
+
198
+ // En traits async con objetos (trait objects de futures)
199
+ trait Procesador: Send {
200
+ fn procesar<'a>(&'a self, item: &'a Item) -> BoxFuture<'a, Result<()>>;
201
+ }
202
+ ```
203
+
204
+ - Usar `Pin<Box<dyn Future>>` para almacenar futures en structs o como parámetros.
205
+ - No implementar `Unpin` manualmente en futures a menos que se pueda demostrar
206
+ que son seguros de mover.
207
+ - El compilador detectará la mayoría de los errores relacionados con Pin —
208
+ si hay que combatir al compilador para que acepte el código, revisar el diseño.
209
+
210
+ ---
211
+
212
+ ## Checklist de seguridad antes de hacer merge
213
+
214
+ - [ ] `cargo audit` pasa sin vulnerabilidades HIGH o CRITICAL
215
+ - [ ] `cargo deny check` pasa (licencias y vulnerabilidades)
216
+ - [ ] Todo bloque `unsafe` tiene safety comment explicando por qué es seguro
217
+ - [ ] Sin `transmute` sin revisión de seguridad documentada
218
+ - [ ] Sin secretos en `const`, `static` o en código fuente
219
+ - [ ] Inputs externos validados con esquemas (garde/validator)
220
+ - [ ] `#![forbid(unsafe_code)]` en crates que no lo necesitan
221
+ - [ ] Miri ejecutado en todo código nuevo con `unsafe`
@@ -0,0 +1,194 @@
1
+ # Regla: Pruebas — Rust
2
+
3
+ Las pruebas en Rust son ciudadanos de primera clase: viven junto al código que
4
+ prueban y el compilador las verifica. El sistema de tipos ya elimina clases
5
+ enteras de bugs — los tests cubren la lógica de negocio y los contratos públicos.
6
+
7
+ ---
8
+
9
+ ## cargo test como runner principal
10
+
11
+ - `cargo test` ejecuta todos los tests: unitarios, de integración y doctests.
12
+ - `cargo test nombre` para ejecutar un test específico.
13
+ - `cargo test -- --nocapture` para ver salida en tests que pasan.
14
+ - CI siempre ejecuta `cargo test --all-targets --all-features` antes del merge.
15
+ - Los benchmarks no corren con `cargo test` — usar `cargo bench`.
16
+
17
+ ---
18
+
19
+ ## rstest para tests parametrizados y fixtures
20
+
21
+ ```rust
22
+ use rstest::{fixture, rstest};
23
+
24
+ #[fixture]
25
+ fn factura_valida() -> Factura {
26
+ Factura::builder().id(FacturaId(1)).total(Monto(1500.0)).build().unwrap()
27
+ }
28
+
29
+ // Test parametrizado — evita duplicar el mismo test con distintos valores
30
+ #[rstest]
31
+ #[case(0.16, 240.0)]
32
+ #[case(0.08, 120.0)]
33
+ #[case(0.0, 0.0)]
34
+ fn test_calcular_iva_por_tasa(factura_valida: Factura, #[case] tasa: f64, #[case] esperado: f64) {
35
+ assert_eq!(factura_valida.calcular_iva(tasa).0, esperado);
36
+ }
37
+ ```
38
+
39
+ - Usar `#[fixture]` para objetos complejos reutilizados entre tests.
40
+ - Usar `#[rstest]` con `#[case]` en lugar de duplicar tests con distintos inputs.
41
+
42
+ ---
43
+
44
+ ## proptest para property-based testing
45
+
46
+ ```rust
47
+ use proptest::prelude::*;
48
+
49
+ proptest! {
50
+ #[test]
51
+ fn iva_nunca_supera_el_total(total in 0.01f64..1_000_000.0) {
52
+ let factura = FacturaFactory::con_total(total);
53
+ prop_assert!(factura.calcular_iva(0.16).0 <= total);
54
+ }
55
+ }
56
+ ```
57
+
58
+ - Usar proptest para invariantes que deben cumplirse para cualquier input válido.
59
+ - Especialmente útil para: serialización/deserialización, algoritmos matemáticos y parsers.
60
+ - Complementa los tests unitarios — no los reemplaza.
61
+
62
+ ---
63
+
64
+ ## mockall para mocks de traits
65
+
66
+ ```rust
67
+ use mockall::mock;
68
+
69
+ mock! {
70
+ RepoMock {}
71
+ impl FacturaRepo for RepoMock {
72
+ async fn obtener(&self, id: FacturaId) -> Result<Factura, FacturaError>;
73
+ }
74
+ }
75
+
76
+ #[tokio::test]
77
+ async fn test_servicio_propaga_error_de_repo() {
78
+ // Arrange
79
+ let mut repo = MockRepoMock::new();
80
+ repo.expect_obtener()
81
+ .returning(|_| Err(FacturaError::NoEncontrada { id: 99 }));
82
+
83
+ // Act
84
+ let resultado = FacturaServicio::new(Arc::new(repo))
85
+ .obtener(FacturaId(99)).await;
86
+
87
+ // Assert
88
+ assert!(matches!(resultado, Err(FacturaError::NoEncontrada { .. })));
89
+ }
90
+ ```
91
+
92
+ - Mockear solo dependencias externas (BD, APIs, filesystem) — nunca código propio del dominio.
93
+ - Verificar el número de llamadas con `.times(N)` para side effects esperados.
94
+
95
+ ---
96
+
97
+ ## cargo-llvm-cov para cobertura
98
+
99
+ ```bash
100
+ cargo install cargo-llvm-cov
101
+ cargo llvm-cov --fail-under-lines 80
102
+ ```
103
+
104
+ - Cobertura mínima: **80%** de líneas en módulos de lógica de negocio.
105
+ - CI debe fallar si la cobertura cae por debajo del umbral.
106
+ - Excluir código de arranque y configuración con `#[cfg(not(tarpaulin_include))]`.
107
+
108
+ ---
109
+
110
+ ## Tests unitarios en el mismo archivo (#[cfg(test)] mod tests)
111
+
112
+ ```rust
113
+ // src/facturacion/calculo.rs
114
+ pub fn calcular_iva(base: f64, tasa: f64) -> f64 { base * tasa }
115
+
116
+ #[cfg(test)]
117
+ mod tests {
118
+ use super::*; // accede también a funciones privadas
119
+
120
+ #[test]
121
+ fn iva_con_tasa_estandar() {
122
+ // Arrange
123
+ let (base, tasa) = (1000.0, 0.16);
124
+ // Act
125
+ let resultado = calcular_iva(base, tasa);
126
+ // Assert
127
+ assert_eq!(resultado, 160.0);
128
+ }
129
+ }
130
+ ```
131
+
132
+ - `use super::*` permite probar funciones privadas del módulo.
133
+ - `#[cfg(test)]` garantiza que el código de test no se incluye en el binario.
134
+
135
+ ---
136
+
137
+ ## Tests de integración en tests/
138
+
139
+ Los tests de integración viven en `tests/` en la raíz del crate y solo acceden
140
+ a la API pública:
141
+
142
+ ```
143
+ mi-crate/
144
+ ├── src/
145
+ └── tests/
146
+ └── facturacion_integration.rs
147
+ ```
148
+
149
+ - Usar una BD aislada por test (transacción que se revierte, o BD en memoria).
150
+ - Los tests de integración son más lentos — ejecutar en job CI separado si es necesario.
151
+
152
+ ---
153
+
154
+ ## Benchmarks con criterion
155
+
156
+ ```rust
157
+ // benches/calculo_bench.rs
158
+ use criterion::{black_box, criterion_group, criterion_main, Criterion};
159
+
160
+ fn benchmark_calcular_totales(c: &mut Criterion) {
161
+ let facturas: Vec<Factura> = (0..1000).map(FacturaFactory::nueva).collect();
162
+ c.bench_function("calcular_totales_1000", |b| {
163
+ b.iter(|| calcular_totales(black_box(&facturas)))
164
+ });
165
+ }
166
+
167
+ criterion_group!(benchmarks, benchmark_calcular_totales);
168
+ criterion_main!(benchmarks);
169
+ ```
170
+
171
+ - Los benchmarks van en `benches/` — no en `src/` ni `tests/`.
172
+ - `black_box` previene que el compilador optimice el código de benchmark.
173
+ - No corren en CI normal — solo al investigar regresiones de performance.
174
+
175
+ ---
176
+
177
+ ## Patrón Arrange-Act-Assert
178
+
179
+ - Los tres bloques siempre separados con comentario o línea en blanco.
180
+ - Nombre del test: `test_[unidad]_[condicion]_[resultado_esperado]`.
181
+ - Un solo concepto por test. Si el Arrange es extenso, extraer a fixture de rstest.
182
+
183
+ ---
184
+
185
+ ## Checklist de pruebas antes de hacer merge
186
+
187
+ - [ ] `cargo test --all-targets` pasa completamente
188
+ - [ ] Tests nuevos para toda lógica de negocio nueva
189
+ - [ ] Test de regresión escrito antes del fix para todo bug
190
+ - [ ] `cargo llvm-cov --fail-under-lines 80` pasa
191
+ - [ ] Tests unitarios en `#[cfg(test)] mod tests` del mismo archivo
192
+ - [ ] Tests de integración en `tests/`
193
+ - [ ] Sin `time::sleep` en tests — usar mocks del reloj
194
+ - [ ] Tests parametrizados con `rstest` en lugar de tests duplicados