@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.
- package/CLAUDE.md +238 -0
- package/README.md +560 -0
- package/_userland/agentes/.gitkeep +0 -0
- package/_userland/habilidades/.gitkeep +0 -0
- package/agentes/.evolved.json +9 -0
- package/agentes/accesibilidad-wcag-swl.md +692 -0
- package/agentes/arquitecto-swl.md +238 -0
- package/agentes/auto-evolucion-swl.md +854 -0
- package/agentes/backend-api-swl.md +470 -0
- package/agentes/backend-csharp-swl.md +418 -0
- package/agentes/backend-go-swl.md +388 -0
- package/agentes/backend-java-swl.md +279 -0
- package/agentes/backend-node-swl.md +477 -0
- package/agentes/backend-python-swl.md +608 -0
- package/agentes/backend-rust-swl.md +362 -0
- package/agentes/backend-workers-swl.md +480 -0
- package/agentes/cloud-infra-swl.md +485 -0
- package/agentes/consolidador-swl.md +539 -0
- package/agentes/datos-swl.md +584 -0
- package/agentes/depurador-swl.md +349 -0
- package/agentes/devops-ci-swl.md +374 -0
- package/agentes/disenador-ui-swl.md +558 -0
- package/agentes/documentador-swl.md +343 -0
- package/agentes/evals/arquitecto-swl.evals.json +56 -0
- package/agentes/evals/auto-evolucion-swl.evals.json +68 -0
- package/agentes/evals/implementador-swl.evals.json +56 -0
- package/agentes/evals/orquestador-swl.evals.json +60 -0
- package/agentes/evals/perfilador-usuario-swl.evals.json +60 -0
- package/agentes/evals/red-team-swl.evals.json +59 -0
- package/agentes/evals/revisor-codigo-swl.evals.json +59 -0
- package/agentes/frontend-angular-swl.md +627 -0
- package/agentes/frontend-css-swl.md +720 -0
- package/agentes/frontend-react-swl.md +696 -0
- package/agentes/frontend-swl.md +500 -0
- package/agentes/frontend-tailwind-swl.md +830 -0
- package/agentes/implementador-swl.md +328 -0
- package/agentes/investigador-swl.md +430 -0
- package/agentes/investigador-ux-swl.md +500 -0
- package/agentes/llm-apps-swl.md +276 -0
- package/agentes/migrador-swl.md +417 -0
- package/agentes/mobile-android-swl.md +509 -0
- package/agentes/mobile-cross-swl.md +539 -0
- package/agentes/mobile-ios-swl.md +500 -0
- package/agentes/mobile-testing-swl.md +300 -0
- package/agentes/notificador-swl.md +916 -0
- package/agentes/observabilidad-swl.md +436 -0
- package/agentes/orquestador-swl.md +884 -0
- package/agentes/pagos-swl.md +283 -0
- package/agentes/perfilador-usuario-swl.md +306 -0
- package/agentes/planificador-swl.md +402 -0
- package/agentes/producto-prd-swl.md +587 -0
- package/agentes/red-team-swl.md +216 -0
- package/agentes/release-manager-swl.md +568 -0
- package/agentes/rendimiento-swl.md +714 -0
- package/agentes/resolutor-build-swl.md +243 -0
- package/agentes/revisor-angular-swl.md +276 -0
- package/agentes/revisor-codigo-swl.md +348 -0
- package/agentes/revisor-csharp-swl.md +262 -0
- package/agentes/revisor-go-swl.md +257 -0
- package/agentes/revisor-java-swl.md +255 -0
- package/agentes/revisor-kotlin-swl.md +271 -0
- package/agentes/revisor-nextjs-swl.md +279 -0
- package/agentes/revisor-php-swl.md +269 -0
- package/agentes/revisor-react-swl.md +276 -0
- package/agentes/revisor-rust-swl.md +344 -0
- package/agentes/revisor-seguridad-swl.md +390 -0
- package/agentes/revisor-swift-swl.md +266 -0
- package/agentes/revisor-typescript-swl.md +344 -0
- package/agentes/sre-swl.md +265 -0
- package/agentes/tdd-qa-swl.md +354 -0
- package/agentes/ux-disenador-swl.md +501 -0
- package/bin/lib/bot-comandos.js +1030 -0
- package/bin/lib/bot-discovery.js +182 -0
- package/bin/lib/bot-git.js +142 -0
- package/bin/swl-ses.js +325 -0
- package/bin/swl-telegram-bot.js +442 -0
- package/bin/swl-telegram-bot.plist +21 -0
- package/bin/swl-telegram-bot.service +14 -0
- package/comandos/swl/.evolved.json +23 -0
- package/comandos/swl/actualizar.md +174 -0
- package/comandos/swl/adoptar-proyecto.md +207 -0
- package/comandos/swl/aprender.md +701 -0
- package/comandos/swl/auditar-deps.md +134 -0
- package/comandos/swl/autoresearch.md +170 -0
- package/comandos/swl/ayuda.md +224 -0
- package/comandos/swl/brainstorm.md +50 -0
- package/comandos/swl/checkpoint.md +330 -0
- package/comandos/swl/compactar.md +283 -0
- package/comandos/swl/configurar-ci.md +227 -0
- package/comandos/swl/contexto.md +112 -0
- package/comandos/swl/contribuir.md +233 -0
- package/comandos/swl/crear-skill.md +292 -0
- package/comandos/swl/cron.md +196 -0
- package/comandos/swl/dashboard.md +146 -0
- package/comandos/swl/discutir-fase.md +230 -0
- package/comandos/swl/ejecutar-fase.md +135 -0
- package/comandos/swl/evaluar-skill.md +487 -0
- package/comandos/swl/evolucion-estado.md +142 -0
- package/comandos/swl/evolucionar.md +259 -0
- package/comandos/swl/exportar-vault.md +189 -0
- package/comandos/swl/gateway.md +158 -0
- package/comandos/swl/inbox.md +116 -0
- package/comandos/swl/instalar.md +220 -0
- package/comandos/swl/instintos.md +86 -0
- package/comandos/swl/mapear-codebase.md +312 -0
- package/comandos/swl/mcp-status.md +175 -0
- package/comandos/swl/metricas.md +270 -0
- package/comandos/swl/modelo.md +102 -0
- package/comandos/swl/notificaciones.md +396 -0
- package/comandos/swl/nuevo-proyecto.md +154 -0
- package/comandos/swl/planear-fase.md +221 -0
- package/comandos/swl/plugins.md +256 -0
- package/comandos/swl/reflect-skills.md +125 -0
- package/comandos/swl/release.md +217 -0
- package/comandos/swl/revisar-impacto.md +206 -0
- package/comandos/swl/revisar.md +330 -0
- package/comandos/swl/salud.md +363 -0
- package/comandos/swl/sesiones.md +200 -0
- package/comandos/swl/skill-search.md +113 -0
- package/comandos/swl/verificar.md +585 -0
- package/comandos/swl/wiki.md +620 -0
- package/contextos/dev.md +32 -0
- package/contextos/research.md +30 -0
- package/contextos/review.md +31 -0
- package/habilidades/accesibilidad-a11y/SKILL.md +201 -0
- package/habilidades/accesibilidad-a11y/evals/evals.json +56 -0
- package/habilidades/accesibilidad-a11y/recursos/ejemplos-y-checklist-completo.md +441 -0
- package/habilidades/agent-browser/SKILL.md +218 -0
- package/habilidades/agentes-como-servicio/SKILL.md +218 -0
- package/habilidades/ai-runtime-security/SKILL.md +273 -0
- package/habilidades/angular-avanzado/SKILL.md +164 -0
- package/habilidades/angular-avanzado/recursos/ejemplos-avanzados.md +219 -0
- package/habilidades/angular-moderno/SKILL.md +186 -0
- package/habilidades/angular-moderno/evals/evals.json +45 -0
- package/habilidades/angular-moderno/recursos/ejemplos-avanzados.md +106 -0
- package/habilidades/api-rest-diseno/SKILL.md +191 -0
- package/habilidades/api-rest-diseno/recursos/openapi-template.yaml +506 -0
- package/habilidades/api-rest-diseno/recursos/referencia-api.md +140 -0
- package/habilidades/aprendizaje-continuo/SKILL.md +151 -0
- package/habilidades/aprendizaje-continuo/evals/evals.json +53 -0
- package/habilidades/aprendizaje-continuo/recursos/referencia-instintos.md +290 -0
- package/habilidades/async-python/SKILL.md +149 -0
- package/habilidades/async-python/evals/evals.json +47 -0
- package/habilidades/async-python/recursos/patrones-y-ejemplos-completos.md +292 -0
- package/habilidades/auth-patrones/.evolved.json +9 -0
- package/habilidades/auth-patrones/SKILL.md +413 -0
- package/habilidades/auth-patrones/recursos/implementaciones-completas.md +229 -0
- package/habilidades/auto-evolucion-protocolo/SKILL.md +276 -0
- package/habilidades/auto-evolucion-protocolo/evals/evals.json +55 -0
- package/habilidades/auto-evolucion-protocolo/recursos/referencia-completa.md +145 -0
- package/habilidades/autoresearch/SKILL.md +268 -0
- package/habilidades/autoresearch/evals/evals.json +41 -0
- package/habilidades/autoresearch/recursos/checklist-template.md +191 -0
- package/habilidades/autoresearch/scripts/calcular-score.js +88 -0
- package/habilidades/azure-cloud/SKILL.md +308 -0
- package/habilidades/azure-cloud/recursos/aks.md +327 -0
- package/habilidades/backend-mcp-servidor/SKILL.md +270 -0
- package/habilidades/backend-production-resilience/SKILL.md +288 -0
- package/habilidades/brainstorming/SKILL.md +295 -0
- package/habilidades/brainstorming/recursos/componentes-html.md +247 -0
- package/habilidades/build-errors-cpp/SKILL.md +270 -0
- package/habilidades/build-errors-csharp/SKILL.md +265 -0
- package/habilidades/build-errors-go/SKILL.md +306 -0
- package/habilidades/build-errors-java/SKILL.md +278 -0
- package/habilidades/build-errors-kotlin/SKILL.md +303 -0
- package/habilidades/build-errors-nextjs/SKILL.md +312 -0
- package/habilidades/build-errors-php/SKILL.md +270 -0
- package/habilidades/build-errors-python/SKILL.md +292 -0
- package/habilidades/build-errors-rust/SKILL.md +284 -0
- package/habilidades/build-errors-swift/SKILL.md +272 -0
- package/habilidades/build-errors-typescript/SKILL.md +369 -0
- package/habilidades/checklist-calidad/SKILL.md +271 -0
- package/habilidades/checklist-calidad/recursos/quality-report-template.md +148 -0
- package/habilidades/checklist-seguridad/SKILL.md +285 -0
- package/habilidades/checkpoints-verificacion/SKILL.md +298 -0
- package/habilidades/checkpoints-verificacion/recursos/checkpoint-templates.md +360 -0
- package/habilidades/ci-cd-pipelines/SKILL.md +157 -0
- package/habilidades/ci-cd-pipelines/recursos/github-actions-template.yaml +403 -0
- package/habilidades/ci-cd-pipelines/recursos/pipelines-completos.md +487 -0
- package/habilidades/cloud-aws/SKILL.md +142 -0
- package/habilidades/cloud-aws/recursos/servicios-aws-referencia.md +321 -0
- package/habilidades/compactacion-contexto/SKILL.md +247 -0
- package/habilidades/contenedores-docker/SKILL.md +137 -0
- package/habilidades/contenedores-docker/recursos/dockerfile-template.dockerfile +160 -0
- package/habilidades/contenedores-docker/recursos/ejemplos-y-configuraciones.md +327 -0
- package/habilidades/context-builder/SKILL.md +170 -0
- package/habilidades/control-profundidad/SKILL.md +128 -0
- package/habilidades/csharp-experto/SKILL.md +322 -0
- package/habilidades/csharp-patrones/SKILL.md +316 -0
- package/habilidades/csharp-testing/SKILL.md +286 -0
- package/habilidades/css-moderno/SKILL.md +166 -0
- package/habilidades/css-moderno/evals/evals.json +43 -0
- package/habilidades/css-moderno/recursos/ejemplos-y-patrones-completos.md +337 -0
- package/habilidades/datos-etl/SKILL.md +129 -0
- package/habilidades/datos-etl/recursos/implementaciones-completas.md +322 -0
- package/habilidades/dbml-experto/SKILL.md +339 -0
- package/habilidades/dbml-experto/evals/evals.json +56 -0
- package/habilidades/dependencias-auditoria/SKILL.md +320 -0
- package/habilidades/deprecacion-migracion/SKILL.md +169 -0
- package/habilidades/deprecacion-migracion/recursos/implementaciones-completas.md +220 -0
- package/habilidades/design-tokens/SKILL.md +158 -0
- package/habilidades/design-tokens/recursos/tokens-y-configuracion.md +363 -0
- package/habilidades/devsecops-pipeline-security/SKILL.md +309 -0
- package/habilidades/diagrama-arquitectura/SKILL.md +165 -0
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -0
- package/habilidades/discutir-fase/SKILL.md +188 -0
- package/habilidades/diseno-herramientas-agente/SKILL.md +199 -0
- package/habilidades/diseno-responsivo/SKILL.md +186 -0
- package/habilidades/diseno-responsivo/recursos/ejemplos-layouts.md +156 -0
- package/habilidades/django-experto/SKILL.md +205 -0
- package/habilidades/django-experto/recursos/async-django.md +390 -0
- package/habilidades/django-experto/recursos/drf-patrones.md +438 -0
- package/habilidades/django-experto/recursos/orm-avanzado.md +382 -0
- package/habilidades/django-experto/recursos/referencia-completa.md +188 -0
- package/habilidades/django-experto/recursos/testing-django.md +415 -0
- package/habilidades/doc-sync/SKILL.md +280 -0
- package/habilidades/drift-detection/SKILL.md +179 -0
- package/habilidades/ejecutar-fase/SKILL.md +468 -0
- package/habilidades/estilo-sin-ai-isms/SKILL.md +775 -0
- package/habilidades/estilo-sin-ai-isms/evals/evals.json +63 -0
- package/habilidades/estilo-sin-ai-isms/scripts/detectar_aiisms.py +500 -0
- package/habilidades/estructura-proyecto-claude/SKILL.md +215 -0
- package/habilidades/estructura-proyecto-claude/recursos/claude-md-template.md +261 -0
- package/habilidades/estructura-proyecto-claude/recursos/configuracion-y-extensiones.md +176 -0
- package/habilidades/estructura-proyecto-claude/recursos/frontmatter-y-hooks-referencia.md +289 -0
- package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +77 -0
- package/habilidades/estructura-proyecto-claude/recursos/variantes-por-stack.md +177 -0
- package/habilidades/evaluacion-agentes/SKILL.md +314 -0
- package/habilidades/event-driven/SKILL.md +153 -0
- package/habilidades/event-driven/recursos/implementaciones-completas.md +423 -0
- package/habilidades/extraccion-documentos/SKILL.md +221 -0
- package/habilidades/extractor-de-aprendizajes/.evolved.json +9 -0
- package/habilidades/extractor-de-aprendizajes/SKILL.md +311 -0
- package/habilidades/extractor-de-aprendizajes/evals/evals.json +55 -0
- package/habilidades/fastapi-experto/SKILL.md +221 -0
- package/habilidades/fastapi-experto/recursos/async-patterns.md +438 -0
- package/habilidades/fastapi-experto/recursos/dependency-injection.md +330 -0
- package/habilidades/fastapi-experto/recursos/referencia-completa.md +79 -0
- package/habilidades/fastapi-experto/recursos/testing-httpx.md +420 -0
- package/habilidades/filament-admin/SKILL.md +290 -0
- package/habilidades/frontend-avanzado/SKILL.md +257 -0
- package/habilidades/frontend-avanzado/recursos/apis-nativas-ejemplos.md +341 -0
- package/habilidades/gcp-cloud/SKILL.md +260 -0
- package/habilidades/gcp-cloud/recursos/gke.md +234 -0
- package/habilidades/gcp-cloud/recursos/terraform-gcp.md +307 -0
- package/habilidades/generacion-mermaid/SKILL.md +229 -0
- package/habilidades/git-worktrees-paralelo/SKILL.md +270 -0
- package/habilidades/go-experto/SKILL.md +305 -0
- package/habilidades/go-patrones/SKILL.md +299 -0
- package/habilidades/go-testing/SKILL.md +291 -0
- package/habilidades/graphql-experto/SKILL.md +323 -0
- package/habilidades/guardrail-semantico/SKILL.md +282 -0
- package/habilidades/harness-claude-code/SKILL.md +299 -0
- package/habilidades/iam-secretos/SKILL.md +265 -0
- package/habilidades/iam-secretos/recursos/implementaciones-completas.md +356 -0
- package/habilidades/infra-github-actions/SKILL.md +166 -0
- package/habilidades/instalar-sistema/.evolved.json +9 -0
- package/habilidades/instalar-sistema/SKILL.md +221 -0
- package/habilidades/java-experto/SKILL.md +290 -0
- package/habilidades/java-patrones/SKILL.md +275 -0
- package/habilidades/java-testing/SKILL.md +288 -0
- package/habilidades/kotlin-compose/SKILL.md +278 -0
- package/habilidades/kotlin-compose/recursos/animaciones-performance.md +93 -0
- package/habilidades/kotlin-experto/SKILL.md +318 -0
- package/habilidades/kotlin-testing/SKILL.md +267 -0
- package/habilidades/kotlin-testing/recursos/testing-avanzado.md +74 -0
- package/habilidades/kubernetes-orquestacion/SKILL.md +152 -0
- package/habilidades/kubernetes-orquestacion/recursos/manifiestos-completos.md +452 -0
- package/habilidades/langchain-langraph/SKILL.md +386 -0
- package/habilidades/langchain-langraph/recursos/evaluacion-rag.md +321 -0
- package/habilidades/langchain-langraph/recursos/rag-maturity-model.md +225 -0
- package/habilidades/langchain-langraph/recursos/vectorstores.md +306 -0
- package/habilidades/legacy-code-rescue/SKILL.md +267 -0
- package/habilidades/likec4-experto/SKILL.md +412 -0
- package/habilidades/likec4-experto/evals/evals.json +69 -0
- package/habilidades/manejo-errores/.evolved.json +9 -0
- package/habilidades/manejo-errores/SKILL.md +407 -0
- package/habilidades/manejo-errores/recursos/implementaciones-completas.md +248 -0
- package/habilidades/mapear-codebase/SKILL.md +275 -0
- package/habilidades/memoria-busqueda/SKILL.md +194 -0
- package/habilidades/memoria-busqueda/evals/evals.json +44 -0
- package/habilidades/meta-skills-estandar/SKILL.md +298 -0
- package/habilidades/meta-skills-estandar/recursos/anti-patrones-y-leyes.md +205 -0
- package/habilidades/meta-skills-estandar/recursos/frameworks-seguridad.md +107 -0
- package/habilidades/meta-skills-estandar/recursos/idiomas-framework.md +60 -0
- package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -0
- package/habilidades/microservicios/SKILL.md +155 -0
- package/habilidades/microservicios/recursos/patrones-y-ejemplos-completos.md +325 -0
- package/habilidades/mobile-flutter/SKILL.md +199 -0
- package/habilidades/mobile-flutter/recursos/ejemplos-completos.md +319 -0
- package/habilidades/mobile-react-native/SKILL.md +176 -0
- package/habilidades/mobile-react-native/recursos/ejemplos-completos.md +216 -0
- package/habilidades/mongodb-experto/SKILL.md +302 -0
- package/habilidades/monitoring-alertas/SKILL.md +201 -0
- package/habilidades/monitoring-alertas/recursos/instrumentacion-y-alertas.md +301 -0
- package/habilidades/nestjs-experto/SKILL.md +307 -0
- package/habilidades/nestjs-experto/recursos/guards-interceptors.md +339 -0
- package/habilidades/nestjs-experto/recursos/modulos-di.md +287 -0
- package/habilidades/nestjs-experto/recursos/testing-nestjs.md +354 -0
- package/habilidades/nextjs-experto/SKILL.md +335 -0
- package/habilidades/nextjs-patrones/SKILL.md +303 -0
- package/habilidades/nextjs-testing/SKILL.md +331 -0
- package/habilidades/node-experto/.evolved.json +9 -0
- package/habilidades/node-experto/SKILL.md +266 -0
- package/habilidades/node-experto/recursos/patrones-completos.md +283 -0
- package/habilidades/notificaciones-multicanal/SKILL.md +159 -0
- package/habilidades/notificaciones-multicanal/recursos/config-template.json +115 -0
- package/habilidades/notificaciones-multicanal/recursos/configuracion-y-templates.md +303 -0
- package/habilidades/nuevo-proyecto/SKILL.md +204 -0
- package/habilidades/orquestacion-async/SKILL.md +303 -0
- package/habilidades/paid-media-tracking/SKILL.md +269 -0
- package/habilidades/paid-media-tracking/recursos/auditoria-tracking.md +220 -0
- package/habilidades/paid-media-tracking/recursos/google-ads-api.md +215 -0
- package/habilidades/patrones-python/SKILL.md +228 -0
- package/habilidades/patrones-python/evals/evals.json +56 -0
- package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -0
- package/habilidades/patrones-python/recursos/referencia-completa.md +202 -0
- package/habilidades/perfil-usuario/SKILL.md +200 -0
- package/habilidades/perfil-usuario/evals/evals.json +55 -0
- package/habilidades/performance-baseline/SKILL.md +297 -0
- package/habilidades/php-experto/SKILL.md +291 -0
- package/habilidades/php-patrones/SKILL.md +306 -0
- package/habilidades/php-testing/SKILL.md +280 -0
- package/habilidades/planear-fase/SKILL.md +269 -0
- package/habilidades/postgresql-experto/SKILL.md +151 -0
- package/habilidades/postgresql-experto/evals/evals.json +53 -0
- package/habilidades/postgresql-experto/recursos/referencia-completa.md +215 -0
- package/habilidades/prevencion-racionalizacion/SKILL.md +175 -0
- package/habilidades/prevencion-sobreingenieria/SKILL.md +323 -0
- package/habilidades/privacy-memoria/SKILL.md +141 -0
- package/habilidades/privacy-memoria/evals/evals.json +43 -0
- package/habilidades/prompt-engineering/SKILL.md +518 -0
- package/habilidades/prompt-engineering/recursos/patrones-avanzados.md +467 -0
- package/habilidades/rag-arquitectura/SKILL.md +338 -0
- package/habilidades/rails-experto/SKILL.md +237 -0
- package/habilidades/rails-experto/recursos/active-record.md +260 -0
- package/habilidades/rails-experto/recursos/hotwire-turbo.md +293 -0
- package/habilidades/rails-experto/recursos/testing-rspec.md +362 -0
- package/habilidades/react-experto/SKILL.md +209 -0
- package/habilidades/react-experto/evals/evals.json +55 -0
- package/habilidades/react-experto/recursos/patrones-y-ejemplos-completos.md +240 -0
- package/habilidades/react-optimizacion/SKILL.md +174 -0
- package/habilidades/react-optimizacion/recursos/patrones-avanzados.md +138 -0
- package/habilidades/redis-experto/SKILL.md +305 -0
- package/habilidades/release-semver/.evolved.json +9 -0
- package/habilidades/release-semver/SKILL.md +248 -0
- package/habilidades/release-semver/scripts/generar-changelog.sh +238 -0
- package/habilidades/rust-experto/SKILL.md +400 -0
- package/habilidades/rust-patrones/SKILL.md +296 -0
- package/habilidades/rust-testing/SKILL.md +311 -0
- package/habilidades/seguridad-skills-ia/SKILL.md +262 -0
- package/habilidades/sql-optimizacion/SKILL.md +200 -0
- package/habilidades/sql-optimizacion/evals/evals.json +54 -0
- package/habilidades/sql-optimizacion/recursos/patrones-sql-avanzados.md +131 -0
- package/habilidades/sre-patrones/SKILL.md +333 -0
- package/habilidades/sre-patrones/recursos/chaos-engineering.md +241 -0
- package/habilidades/sre-patrones/recursos/oncall-design.md +236 -0
- package/habilidades/stripe-pagos/SKILL.md +550 -0
- package/habilidades/stripe-pagos/recursos/errores-reintentos.md +390 -0
- package/habilidades/stripe-pagos/recursos/stripe-connect.md +290 -0
- package/habilidades/structured-outputs/SKILL.md +343 -0
- package/habilidades/swift-experto/SKILL.md +320 -0
- package/habilidades/swift-experto/recursos/keychain-y-wrappers.md +110 -0
- package/habilidades/swift-patrones/SKILL.md +313 -0
- package/habilidades/swift-patrones/recursos/tca-ejemplo-completo.md +113 -0
- package/habilidades/swift-testing/SKILL.md +254 -0
- package/habilidades/swift-testing/recursos/xcuitest-planes.md +143 -0
- package/habilidades/swl-dashboard/SKILL.md +370 -0
- package/habilidades/swl-markitdown/SKILL.md +285 -0
- package/habilidades/swl-markitdown/evals/evals.json +52 -0
- package/habilidades/swl-revisar-impacto/SKILL.md +233 -0
- package/habilidades/tailwind-experto/SKILL.md +240 -0
- package/habilidades/tailwind-experto/recursos/referencia-completa.md +184 -0
- package/habilidades/tdd-workflow/SKILL.md +293 -0
- package/habilidades/terraform-experto/SKILL.md +321 -0
- package/habilidades/testing-python/SKILL.md +340 -0
- package/habilidades/testing-python/recursos/ejemplos-completos.md +167 -0
- package/habilidades/threat-model-lite/SKILL.md +246 -0
- package/habilidades/tracing-processor/SKILL.md +212 -0
- package/habilidades/tracking-measurement/SKILL.md +239 -0
- package/habilidades/tracking-measurement/recursos/consent-mode.md +231 -0
- package/habilidades/tracking-measurement/recursos/gtm-datalayer.md +216 -0
- package/habilidades/tracking-measurement/recursos/meta-capi.md +262 -0
- package/habilidades/typescript-avanzado/SKILL.md +144 -0
- package/habilidades/typescript-avanzado/evals/evals.json +55 -0
- package/habilidades/typescript-avanzado/recursos/patrones-y-ejemplos-completos.md +298 -0
- package/habilidades/typescript-diagnosticos/SKILL.md +513 -0
- package/habilidades/ux-diseno/SKILL.md +116 -0
- package/habilidades/ux-diseno/evals/evals.json +43 -0
- package/habilidades/ux-diseno/recursos/patrones-ux-referencia.md +214 -0
- package/habilidades/validacion-ci-sistema/SKILL.md +136 -0
- package/habilidades/validacion-ci-sistema/recursos/validadores-completos.md +369 -0
- package/habilidades/validacion-ci-sistema/scripts/validar-sistema.sh +286 -0
- package/habilidades/verificacion-evidencia/SKILL.md +160 -0
- package/habilidades/verificar-trabajo/SKILL.md +303 -0
- package/habilidades/verificar-trabajo/recursos/plantilla-verificacion.md +60 -0
- package/habilidades/wiki-conocimiento/SKILL.md +276 -0
- package/habilidades/wireframes-flujos/SKILL.md +212 -0
- package/habilidades/wireframes-flujos/recursos/referencia-completa.md +192 -0
- package/habilidades/workflow-claude-code/SKILL.md +260 -0
- package/habilidades/workflow-claude-code/recursos/referencia-completa.md +109 -0
- package/hooks/_run-hook.sh +57 -0
- package/hooks/actualizar-perfil-usuario.js +364 -0
- package/hooks/agente-lifecycle.js +71 -0
- package/hooks/aiisms-detector.js +173 -0
- package/hooks/audit-trail.js +204 -0
- package/hooks/auto-background.js +97 -0
- package/hooks/auto-consolidacion.js +178 -0
- package/hooks/auto-evolucion.js +666 -0
- package/hooks/auto-restaurar-settings.js +360 -0
- package/hooks/calidad-pre-commit.js +929 -0
- package/hooks/calidad-typescript.js +511 -0
- package/hooks/captura-feedback-usuario.js +148 -0
- package/hooks/check-update.js +211 -0
- package/hooks/clasificador-mensajes.js +271 -0
- package/hooks/degradacion-instintos.js +272 -0
- package/hooks/escaneo-secretos.js +389 -0
- package/hooks/extraccion-aprendizajes.js +763 -0
- package/hooks/grafo-contexto.js +129 -0
- package/hooks/graph-update.js +67 -0
- package/hooks/guardrail-modelo.js +247 -0
- package/hooks/inbox-aviso.js +75 -0
- package/hooks/inyeccion-contexto.js +246 -0
- package/hooks/lib/abort-registry.js +214 -0
- package/hooks/lib/agent-backend.js +210 -0
- package/hooks/lib/agent-comms.js +263 -0
- package/hooks/lib/agent-issue-codes.js +284 -0
- package/hooks/lib/agent-matcher.js +189 -0
- package/hooks/lib/async-hook-registry.js +252 -0
- package/hooks/lib/atomic-write.js +130 -0
- package/hooks/lib/auto-consolidator.js +335 -0
- package/hooks/lib/canary-skills.js +187 -0
- package/hooks/lib/consolidation-lock.js +291 -0
- package/hooks/lib/context-builder.js +430 -0
- package/hooks/lib/context-compressor.js +657 -0
- package/hooks/lib/convergence-detector.js +105 -0
- package/hooks/lib/delegation-tracker.js +198 -0
- package/hooks/lib/detectar-package-manager.js +423 -0
- package/hooks/lib/edit-accumulator.js +171 -0
- package/hooks/lib/error-classifier.js +308 -0
- package/hooks/lib/event-bus.js +112 -0
- package/hooks/lib/evolution-tracker.js +442 -0
- package/hooks/lib/execution-state.js +316 -0
- package/hooks/lib/fingerprint-id.js +135 -0
- package/hooks/lib/gateway-notify.js +116 -0
- package/hooks/lib/graph-security.js +75 -0
- package/hooks/lib/guardrail-metrics.js +202 -0
- package/hooks/lib/hook-circuit-breaker.js +206 -0
- package/hooks/lib/loop-detector.js +267 -0
- package/hooks/lib/mcp-health.js +184 -0
- package/hooks/lib/mcp-pool.js +436 -0
- package/hooks/lib/memory-search.js +506 -0
- package/hooks/lib/merkle-audit.js +96 -0
- package/hooks/lib/model-router.js +222 -0
- package/hooks/lib/normalize-error.js +324 -0
- package/hooks/lib/normalize-input.js +65 -0
- package/hooks/lib/nudge-tracker.js +306 -0
- package/hooks/lib/otlp-exporter.js +365 -0
- package/hooks/lib/performance-marks.js +239 -0
- package/hooks/lib/privacy-filter.js +128 -0
- package/hooks/lib/prompt-injection-scanner.js +209 -0
- package/hooks/lib/provenance-tracker.js +183 -0
- package/hooks/lib/rate-limit-tracker.js +253 -0
- package/hooks/lib/reflect-classifier.js +164 -0
- package/hooks/lib/resource-quota.js +122 -0
- package/hooks/lib/retry-jitter.js +165 -0
- package/hooks/lib/risk-engine.js +368 -0
- package/hooks/lib/run-log.js +408 -0
- package/hooks/lib/session-fts.js +379 -0
- package/hooks/lib/session-store.js +293 -0
- package/hooks/lib/singleton-guard.js +159 -0
- package/hooks/lib/skill-auditor.js +588 -0
- package/hooks/lib/sync-status.js +228 -0
- package/hooks/lib/taint-tracker.js +107 -0
- package/hooks/lib/task-service.js +295 -0
- package/hooks/lib/tech-skills-map.js +146 -0
- package/hooks/lib/telegram-cliente.js +159 -0
- package/hooks/lib/telegram-config.js +170 -0
- package/hooks/lib/token-budget.js +156 -0
- package/hooks/lib/token-estimator.js +420 -0
- package/hooks/lib/toon-compressor.js +245 -0
- package/hooks/lib/usage-model.js +183 -0
- package/hooks/lib/variable-resolver.js +230 -0
- package/hooks/linea-estado.js +324 -0
- package/hooks/metricas-evolucion.js +209 -0
- package/hooks/monitor-contexto.js +325 -0
- package/hooks/notificacion-sesion-stop.js +198 -0
- package/hooks/notificacion-telegram-notification.js +4 -0
- package/hooks/notificacion-telegram-subagent.js +4 -0
- package/hooks/notificacion-telegram.js +267 -0
- package/hooks/preservar-estado-pre-compact.js +150 -0
- package/hooks/proteccion-rutas.js +366 -0
- package/hooks/registro-turnos.js +209 -0
- package/hooks/resumen-sesion.js +249 -0
- package/hooks/risk-scoring.js +323 -0
- package/hooks/rotar-audit-auto.js +122 -0
- package/hooks/sugerir-regenerar-inventario.js +170 -0
- package/hooks/telemetria-agentes.js +167 -0
- package/hooks/tracking-costos.js +688 -0
- package/instintos/global.yaml +8 -0
- package/instintos/perfil-usuario.yaml +53 -0
- package/instintos/prompt-appendices.yaml +57 -0
- package/instintos/proyecto.yaml +372 -0
- package/manifiestos/gateway-config.json +77 -0
- package/manifiestos/handoff-context.json +223 -0
- package/manifiestos/hook-profiles.json +44 -0
- package/manifiestos/hooks-config.json +360 -0
- package/manifiestos/modulos.json +1173 -0
- package/manifiestos/perfiles.json +404 -0
- package/package.json +86 -0
- package/plantillas/ESTADO.md +109 -0
- package/plantillas/HOJA-RUTA.md +143 -0
- package/plantillas/PROYECTO.md +122 -0
- package/plantillas/REQUISITOS.md +132 -0
- package/plantillas/auditor-veto-template.md +105 -0
- package/plantillas/github-workflows/README.md +47 -0
- package/plantillas/github-workflows/release-please.yml +44 -0
- package/plantillas/github-workflows/swl-ci.yml +107 -0
- package/plantillas/github-workflows/swl-security.yml +51 -0
- package/plantillas/mcp-mineru.json +13 -0
- package/plantillas/research/ARQUITECTURA.md +220 -0
- package/plantillas/research/FUNCIONALIDADES.md +175 -0
- package/plantillas/research/RESUMEN.md +165 -0
- package/plantillas/research/STACK.md +233 -0
- package/plantillas/research/TRAMPAS.md +299 -0
- package/plantillas/skill-evals-template.json +44 -0
- package/plugin.json +343 -0
- package/reglas/accesibilidad.md +269 -0
- package/reglas/api-diseno.md +400 -0
- package/reglas/arquitectura.md +352 -0
- package/reglas/brevedad-output.md +124 -0
- package/reglas/cloud-infra.md +247 -0
- package/reglas/docs.md +245 -0
- package/reglas/estilo-codigo.md +201 -0
- package/reglas/git-workflow.md +245 -0
- package/reglas/gobernanza.md +271 -0
- package/reglas/harness-claude-code.md +213 -0
- package/reglas/hooks.md +186 -0
- package/reglas/lenguajes/csharp/estilo-codigo.md +231 -0
- package/reglas/lenguajes/csharp/hooks.md +281 -0
- package/reglas/lenguajes/csharp/patrones.md +226 -0
- package/reglas/lenguajes/csharp/seguridad.md +258 -0
- package/reglas/lenguajes/csharp/testing.md +176 -0
- package/reglas/lenguajes/go/estilo-codigo.md +195 -0
- package/reglas/lenguajes/go/hooks.md +249 -0
- package/reglas/lenguajes/go/patrones.md +249 -0
- package/reglas/lenguajes/go/seguridad.md +225 -0
- package/reglas/lenguajes/go/testing.md +272 -0
- package/reglas/lenguajes/java/estilo-codigo.md +217 -0
- package/reglas/lenguajes/java/hooks.md +251 -0
- package/reglas/lenguajes/java/patrones.md +226 -0
- package/reglas/lenguajes/java/seguridad.md +233 -0
- package/reglas/lenguajes/java/testing.md +238 -0
- package/reglas/lenguajes/kotlin/estilo-codigo.md +208 -0
- package/reglas/lenguajes/kotlin/hooks.md +245 -0
- package/reglas/lenguajes/kotlin/patrones.md +201 -0
- package/reglas/lenguajes/kotlin/seguridad.md +202 -0
- package/reglas/lenguajes/kotlin/testing.md +236 -0
- package/reglas/lenguajes/nextjs/estilo-codigo.md +175 -0
- package/reglas/lenguajes/nextjs/hooks.md +186 -0
- package/reglas/lenguajes/nextjs/patrones.md +225 -0
- package/reglas/lenguajes/nextjs/seguridad.md +216 -0
- package/reglas/lenguajes/nextjs/testing.md +193 -0
- package/reglas/lenguajes/php/estilo-codigo.md +228 -0
- package/reglas/lenguajes/php/hooks.md +165 -0
- package/reglas/lenguajes/php/patrones.md +233 -0
- package/reglas/lenguajes/php/seguridad.md +186 -0
- package/reglas/lenguajes/php/testing.md +205 -0
- package/reglas/lenguajes/rust/estilo-codigo.md +207 -0
- package/reglas/lenguajes/rust/hooks.md +240 -0
- package/reglas/lenguajes/rust/patrones.md +250 -0
- package/reglas/lenguajes/rust/seguridad.md +221 -0
- package/reglas/lenguajes/rust/testing.md +194 -0
- package/reglas/lenguajes/swift/estilo-codigo.md +238 -0
- package/reglas/lenguajes/swift/hooks.md +257 -0
- package/reglas/lenguajes/swift/patrones.md +235 -0
- package/reglas/lenguajes/swift/seguridad.md +248 -0
- package/reglas/lenguajes/swift/testing.md +242 -0
- package/reglas/markitdown.md +60 -0
- package/reglas/memoria-consolidada.md +209 -0
- package/reglas/patrones.md +225 -0
- package/reglas/performance.md +195 -0
- package/reglas/pruebas.md +159 -0
- package/reglas/seguridad-agentes.md +351 -0
- package/reglas/seguridad.md +151 -0
- package/reglas/skills-estandar.md +373 -0
- package/reglas/testing.md +193 -0
- package/schemas/agent-contract.json +176 -0
- package/schemas/agent-frontmatter.schema.json +149 -0
- package/schemas/agent-message.schema.json +53 -0
- package/schemas/agent-output-implementacion.schema.json +85 -0
- package/schemas/agent-output-planificacion.schema.json +113 -0
- package/schemas/agent-output-review.schema.json +78 -0
- package/schemas/diary-entry.schema.json +80 -0
- package/schemas/hook-profiles.schema.json +39 -0
- package/schemas/hooks-config.schema.json +74 -0
- package/schemas/instinct.schema.json +115 -0
- package/schemas/modulos.schema.json +29 -0
- package/schemas/perfiles.schema.json +28 -0
- package/schemas/plugin.schema.json +64 -0
- package/schemas/skill-evals.schema.json +95 -0
- package/schemas/skill-frontmatter.schema.json +170 -0
- package/scripts/actualizar.js +145 -0
- package/scripts/audit-skills.sh +78 -0
- package/scripts/auditar-agentes-gaps.js +149 -0
- package/scripts/auditar-cobertura-frameworks.js +241 -0
- package/scripts/auditar-skills-gaps.js +206 -0
- package/scripts/bootstrap-instintos.js +259 -0
- package/scripts/check-update.js +109 -0
- package/scripts/comandos/agents.js +105 -0
- package/scripts/comandos/info.js +108 -0
- package/scripts/comandos/install-asistido.js +186 -0
- package/scripts/comandos/skills.js +211 -0
- package/scripts/configurar-branch-protection.js +418 -0
- package/scripts/daemon-swl.py +388 -0
- package/scripts/desinstalar.js +130 -0
- package/scripts/doctor.js +559 -0
- package/scripts/field-report.js +199 -0
- package/scripts/generar-inventario.js +317 -0
- package/scripts/inbox-tmux-inject.js +161 -0
- package/scripts/inferir-herramientas-permitidas.js +586 -0
- package/scripts/inicializar.js +133 -0
- package/scripts/instalador.js +1031 -0
- package/scripts/instalar-git-hook.js +122 -0
- package/scripts/lib/agp-frontmatter.js +222 -0
- package/scripts/lib/append-con-marcadores.js +199 -0
- package/scripts/lib/artefactos-python.js +43 -0
- package/scripts/lib/audit-query.js +221 -0
- package/scripts/lib/autostart-linux.js +347 -0
- package/scripts/lib/autostart-macos.js +360 -0
- package/scripts/lib/autostart-windows.js +307 -0
- package/scripts/lib/budget-enforcer.js +252 -0
- package/scripts/lib/claude-sessions.js +285 -0
- package/scripts/lib/configurar-ci.js +380 -0
- package/scripts/lib/console-span-exporter.js +92 -0
- package/scripts/lib/contadores-inventario.js +217 -0
- package/scripts/lib/dashboard-widgets.js +290 -0
- package/scripts/lib/detectar-runtime.js +279 -0
- package/scripts/lib/detectar-stack.js +187 -0
- package/scripts/lib/diary-entry.js +234 -0
- package/scripts/lib/drift-detector.js +545 -0
- package/scripts/lib/estado.js +124 -0
- package/scripts/lib/gestor-componentes.js +243 -0
- package/scripts/lib/gitignore-manifest.js +305 -0
- package/scripts/lib/graph-analyze.py +556 -0
- package/scripts/lib/graph-builder.py +485 -0
- package/scripts/lib/graph-cluster.py +259 -0
- package/scripts/lib/health-row.js +168 -0
- package/scripts/lib/hooks-settings.js +789 -0
- package/scripts/lib/manifiestos.js +138 -0
- package/scripts/lib/mc-client.js +137 -0
- package/scripts/lib/notificaciones-telegram.js +1107 -0
- package/scripts/lib/npm-version.js +261 -0
- package/scripts/lib/paquetes-conocidos.js +50 -0
- package/scripts/lib/preservar-usuario.js +586 -0
- package/scripts/lib/prompt-builder.js +264 -0
- package/scripts/lib/resolver-externo.js +332 -0
- package/scripts/lib/schedule-parser.js +305 -0
- package/scripts/lib/scoring-instintos.js +240 -0
- package/scripts/lib/seguridad.js +160 -0
- package/scripts/lib/selector-interactivo.js +152 -0
- package/scripts/lib/semantic-search.js +242 -0
- package/scripts/lib/skill-discovery.js +234 -0
- package/scripts/lib/skill-metrics.js +246 -0
- package/scripts/lib/skill-normalizer.js +112 -0
- package/scripts/lib/skills-hub.js +340 -0
- package/scripts/lib/span-schema.js +134 -0
- package/scripts/lib/tool-cost-analyzer.js +255 -0
- package/scripts/lib/tracing-processor-interface.js +286 -0
- package/scripts/lib/transformadores/base.js +80 -0
- package/scripts/lib/transformadores/claude.js +124 -0
- package/scripts/lib/transformadores/codex.js +115 -0
- package/scripts/lib/transformadores/copilot.js +106 -0
- package/scripts/lib/transformadores/gemini.js +74 -0
- package/scripts/lib/transformadores/index.js +35 -0
- package/scripts/lib/transformadores/opencode.js +75 -0
- package/scripts/lib/ui.js +259 -0
- package/scripts/limpiar-artefactos-python.js +131 -0
- package/scripts/mcp-orchestrator.py +386 -0
- package/scripts/mcp-pool-manager.py +352 -0
- package/scripts/mcp-telemetry.py +378 -0
- package/scripts/poblar-evolvable.js +226 -0
- package/scripts/publicar.js +287 -0
- package/scripts/reflect-skills.js +403 -0
- package/scripts/rotar-audit-logs.js +185 -0
- package/scripts/run-skill-evals.js +242 -0
- package/scripts/smoke-test.js +374 -0
- package/scripts/token-analysis.py +471 -0
- package/scripts/validar-manifest.js +195 -0
- package/scripts/validar-memoria.js +321 -0
- package/scripts/validar-tests-aislamiento.js +184 -0
- package/scripts/validar-tokens-test.js +208 -0
- package/scripts/validar.js +147 -0
- package/scripts/validate-markdown.py +339 -0
- package/scripts/validate-skills.py +385 -0
- package/scripts/vendor/claude-usage/README.md +116 -0
- package/scripts/vendor/claude-usage/cli.py +334 -0
- package/scripts/vendor/claude-usage/dashboard.py +795 -0
- package/scripts/vendor/claude-usage/scanner.py +467 -0
- package/scripts/vendor/markitdown/cli.py +194 -0
- package/scripts/verificar-evolucion.js +289 -0
- package/scripts/verificar-release.js +494 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Regla: Hooks de Desarrollo Go
|
|
2
|
+
|
|
3
|
+
Go tiene excelentes herramientas de análisis estático integradas o de la comunidad.
|
|
4
|
+
Automatizarlas como hooks garantiza que el código que llega al repositorio ya
|
|
5
|
+
superó las verificaciones básicas, reduciendo el ruido en code review.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## go vet obligatorio antes de commit
|
|
10
|
+
|
|
11
|
+
`go vet` examina el código fuente e identifica construcciones sospechosas que
|
|
12
|
+
el compilador no reporta como errores pero que probablemente son bugs.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Verificación básica — debe pasar siempre
|
|
16
|
+
go vet ./...
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Casos que `go vet` detecta:
|
|
20
|
+
- `Printf`-like calls con formato incorrecto (`fmt.Sprintf("%d", "string")`)
|
|
21
|
+
- Variables de loop capturadas incorrectamente en goroutines
|
|
22
|
+
- Llamadas a `sync.Mutex` después de copiar el struct
|
|
23
|
+
- `unreachable code` después de return/break/continue
|
|
24
|
+
|
|
25
|
+
Pre-commit hook:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
#!/bin/sh
|
|
29
|
+
# .git/hooks/pre-commit
|
|
30
|
+
echo "Ejecutando go vet..."
|
|
31
|
+
if ! go vet ./...; then
|
|
32
|
+
echo "ERROR: go vet encontró problemas. Corregir antes de hacer commit."
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
echo "go vet: OK"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## staticcheck como linter principal
|
|
41
|
+
|
|
42
|
+
`staticcheck` es el analizador estático más completo para Go. Detecta bugs,
|
|
43
|
+
código ineficiente, código simplificable y APIs deprecadas.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Instalar
|
|
47
|
+
go install honnef.co/go/tools/cmd/staticcheck@latest
|
|
48
|
+
|
|
49
|
+
# Ejecutar
|
|
50
|
+
staticcheck ./...
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Verificaciones clave de staticcheck:
|
|
54
|
+
- SA: Análisis estático (bugs reales como nil dereference, locks mal usados)
|
|
55
|
+
- S: Código simplificable
|
|
56
|
+
- ST: Violaciones de estilo
|
|
57
|
+
- QF: Sugerencias de quickfix (código mejorable)
|
|
58
|
+
- Deprecations: uso de APIs deprecadas de la stdlib
|
|
59
|
+
|
|
60
|
+
Configuración en `staticcheck.conf` en la raíz del proyecto:
|
|
61
|
+
|
|
62
|
+
```ini
|
|
63
|
+
# staticcheck.conf
|
|
64
|
+
checks = ["all", "-ST1000", "-ST1003"]
|
|
65
|
+
# ST1000: comentario de paquete (puede ser ruidoso en paquetes internos)
|
|
66
|
+
# ST1003: naming de identificadores (demasiado estricto para nombres en español)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## golangci-lint con configuración del proyecto
|
|
72
|
+
|
|
73
|
+
`golangci-lint` agrega una capa de verificación coordinando múltiples linters.
|
|
74
|
+
La configuración en `.golangci.yml` garantiza que todos en el equipo usan los mismos checks.
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
# .golangci.yml — configuración del proyecto
|
|
78
|
+
run:
|
|
79
|
+
timeout: 5m
|
|
80
|
+
go: "1.21"
|
|
81
|
+
|
|
82
|
+
linters:
|
|
83
|
+
enable:
|
|
84
|
+
- errcheck # errores no verificados
|
|
85
|
+
- gosimple # simplificaciones de código
|
|
86
|
+
- govet # vet checks
|
|
87
|
+
- ineffassign # asignaciones sin uso
|
|
88
|
+
- staticcheck # análisis estático completo
|
|
89
|
+
- unused # código sin usar
|
|
90
|
+
- goimports # imports no organizados
|
|
91
|
+
- misspell # typos en comentarios
|
|
92
|
+
- godot # punto final en comentarios
|
|
93
|
+
- gosec # seguridad
|
|
94
|
+
- bodyclose # response body no cerrado
|
|
95
|
+
- noctx # HTTP requests sin context
|
|
96
|
+
|
|
97
|
+
linters-settings:
|
|
98
|
+
errcheck:
|
|
99
|
+
check-type-assertions: true
|
|
100
|
+
govet:
|
|
101
|
+
enable:
|
|
102
|
+
- shadow # detección de variable shadowing
|
|
103
|
+
|
|
104
|
+
issues:
|
|
105
|
+
exclude-rules:
|
|
106
|
+
# En archivos de test, errcheck es menos estricto
|
|
107
|
+
- path: "_test\\.go"
|
|
108
|
+
linters:
|
|
109
|
+
- errcheck
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Ejecutar
|
|
114
|
+
golangci-lint run ./...
|
|
115
|
+
|
|
116
|
+
# En CI con reporte
|
|
117
|
+
golangci-lint run --out-format github-actions ./...
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Detección de fmt.Println en código no-test
|
|
123
|
+
|
|
124
|
+
`fmt.Println` y `fmt.Printf` en código de producción son logs no estructurados
|
|
125
|
+
que no se pueden filtrar, enrutar ni analizar. Usar `zap`, `slog` o el logger
|
|
126
|
+
del proyecto.
|
|
127
|
+
|
|
128
|
+
Hook de detección:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
#!/bin/sh
|
|
132
|
+
# Detectar fmt.Println/Printf en src que no son test
|
|
133
|
+
ARCHIVOS=$(grep -r "fmt\.Print" --include="*.go" \
|
|
134
|
+
--exclude="*_test.go" \
|
|
135
|
+
--exclude-dir=vendor \
|
|
136
|
+
-l . 2>/dev/null)
|
|
137
|
+
|
|
138
|
+
if [ -n "$ARCHIVOS" ]; then
|
|
139
|
+
echo "ERROR: fmt.Print* detectado en código de producción."
|
|
140
|
+
echo "Usar el logger del proyecto (zap/slog) en su lugar."
|
|
141
|
+
echo "Archivos afectados:"
|
|
142
|
+
echo "$ARCHIVOS"
|
|
143
|
+
exit 1
|
|
144
|
+
fi
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Con golangci-lint, agregar el linter `forbidigo`:
|
|
148
|
+
|
|
149
|
+
```yaml
|
|
150
|
+
# En .golangci.yml
|
|
151
|
+
linters:
|
|
152
|
+
enable:
|
|
153
|
+
- forbidigo
|
|
154
|
+
|
|
155
|
+
linters-settings:
|
|
156
|
+
forbidigo:
|
|
157
|
+
forbid:
|
|
158
|
+
- pattern: "^fmt\\.Print"
|
|
159
|
+
msg: "Usar el logger del proyecto en lugar de fmt.Print*"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## go mod tidy antes de commit
|
|
165
|
+
|
|
166
|
+
`go mod tidy` asegura que `go.mod` y `go.sum` están sincronizados con las
|
|
167
|
+
importaciones reales del proyecto. Sin esto, el CI puede fallar con módulos
|
|
168
|
+
que no están en el go.sum.
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
#!/bin/sh
|
|
172
|
+
# Verificar que go.mod y go.sum están actualizados
|
|
173
|
+
go mod tidy
|
|
174
|
+
|
|
175
|
+
# Si go mod tidy modificó archivos, el commit no debe proceder
|
|
176
|
+
if ! git diff --quiet go.mod go.sum; then
|
|
177
|
+
echo "ERROR: go.mod o go.sum están desactualizados."
|
|
178
|
+
echo "Ejecutar 'go mod tidy' y agregar los cambios al commit."
|
|
179
|
+
exit 1
|
|
180
|
+
fi
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## errcheck: verificación de errores no manejados
|
|
186
|
+
|
|
187
|
+
`errcheck` como parte de golangci-lint detecta errores ignorados sin el
|
|
188
|
+
`_ =` explícito, y también con él si `check-type-assertions: true`.
|
|
189
|
+
|
|
190
|
+
```go
|
|
191
|
+
// MAL — estos casos son detectados por errcheck
|
|
192
|
+
repositorio.Guardar(ctx, factura) // error retornado e ignorado
|
|
193
|
+
archivo, _ := os.Open(ruta) // error ignorado con blank identifier
|
|
194
|
+
|
|
195
|
+
// BIEN — error manejado explícitamente
|
|
196
|
+
if err := repositorio.Guardar(ctx, factura); err != nil {
|
|
197
|
+
return fmt.Errorf("guardar factura: %w", err)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
archivo, err := os.Open(ruta)
|
|
201
|
+
if err != nil {
|
|
202
|
+
return fmt.Errorf("abrir archivo %s: %w", ruta, err)
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Pipeline CI completa de calidad Go
|
|
209
|
+
|
|
210
|
+
Orden de ejecución (cada fase bloquea las siguientes):
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# 1. Formato
|
|
214
|
+
gofmt -l . && test -z "$(gofmt -l .)"
|
|
215
|
+
|
|
216
|
+
# 2. Imports
|
|
217
|
+
goimports -l . && test -z "$(goimports -l .)"
|
|
218
|
+
|
|
219
|
+
# 3. Módulos actualizados
|
|
220
|
+
go mod tidy && git diff --exit-code go.mod go.sum
|
|
221
|
+
|
|
222
|
+
# 4. Compilación
|
|
223
|
+
go build ./...
|
|
224
|
+
|
|
225
|
+
# 5. Tests con race detection
|
|
226
|
+
go test -race ./...
|
|
227
|
+
|
|
228
|
+
# 6. Análisis estático
|
|
229
|
+
golangci-lint run ./...
|
|
230
|
+
|
|
231
|
+
# 7. Seguridad
|
|
232
|
+
gosec -severity medium ./...
|
|
233
|
+
|
|
234
|
+
# 8. Cobertura
|
|
235
|
+
go test -coverprofile=coverage.out ./...
|
|
236
|
+
go tool cover -func=coverage.out | grep total
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Checklist de hooks Go antes de hacer commit
|
|
242
|
+
|
|
243
|
+
- [ ] `go vet ./...` pasa sin errores
|
|
244
|
+
- [ ] `gofmt -l .` retorna vacío
|
|
245
|
+
- [ ] `go mod tidy` no modifica go.mod ni go.sum
|
|
246
|
+
- [ ] Sin `fmt.Println`/`fmt.Printf` en código fuera de tests
|
|
247
|
+
- [ ] `golangci-lint run ./...` pasa
|
|
248
|
+
- [ ] `gosec ./...` sin severidad media o alta
|
|
249
|
+
- [ ] `go test -race ./...` pasa sin data races
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Regla: Patrones Go Idiomáticos
|
|
2
|
+
|
|
3
|
+
Los patrones aquí listados son soluciones probadas para problemas recurrentes
|
|
4
|
+
en Go de producción. El lenguaje tiene sus propios modismos — aplicar patrones
|
|
5
|
+
de otros lenguajes sin adaptarlos genera código que "funciona pero no es Go".
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Functional options para configuración
|
|
10
|
+
|
|
11
|
+
El patrón de opciones funcionales permite API de construcción extensible sin
|
|
12
|
+
romper compatibilidad al agregar nuevas opciones.
|
|
13
|
+
|
|
14
|
+
```go
|
|
15
|
+
// MAL — constructor con muchos parámetros booleanos/opcionales
|
|
16
|
+
func NuevoCliente(host string, port int, timeout time.Duration, tls bool, maxConn int) *Cliente { ... }
|
|
17
|
+
|
|
18
|
+
// BIEN — functional options: cada opción es explícita y opcional
|
|
19
|
+
type ClienteOption func(*cliente)
|
|
20
|
+
|
|
21
|
+
func ConTimeout(d time.Duration) ClienteOption {
|
|
22
|
+
return func(c *cliente) { c.timeout = d }
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
func ConTLS(certPath string) ClienteOption {
|
|
26
|
+
return func(c *cliente) {
|
|
27
|
+
c.tls = true
|
|
28
|
+
c.certPath = certPath
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func NuevoCliente(host string, opts ...ClienteOption) *Cliente {
|
|
33
|
+
c := &cliente{
|
|
34
|
+
host: host,
|
|
35
|
+
timeout: 30 * time.Second, // valores por defecto razonables
|
|
36
|
+
maxConn: 10,
|
|
37
|
+
}
|
|
38
|
+
for _, opt := range opts {
|
|
39
|
+
opt(c)
|
|
40
|
+
}
|
|
41
|
+
return c
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Consumo — solo las opciones necesarias
|
|
45
|
+
cliente := NuevoCliente("api.ejemplo.com",
|
|
46
|
+
ConTimeout(5*time.Second),
|
|
47
|
+
ConTLS("/certs/client.pem"),
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Interface satisfaction implícita
|
|
54
|
+
|
|
55
|
+
Go no usa `implements`. Un tipo satisface una interfaz automáticamente si tiene
|
|
56
|
+
los métodos requeridos. Verificar en compile time con asignación a blank identifier.
|
|
57
|
+
|
|
58
|
+
```go
|
|
59
|
+
// Verificación en compile time — falla si *FacturaService no implementa la interfaz
|
|
60
|
+
var _ FacturaRepository = (*FacturaRepositoryPostgres)(nil)
|
|
61
|
+
|
|
62
|
+
// Inyección de dependencias: el servicio depende de la interfaz, no del concreto
|
|
63
|
+
type FacturaService struct {
|
|
64
|
+
repo FacturaRepository // interface
|
|
65
|
+
logger *zap.Logger
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
func NuevoFacturaService(repo FacturaRepository, logger *zap.Logger) *FacturaService {
|
|
69
|
+
return &FacturaService{repo: repo, logger: logger}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Context propagation: context.Context como primer parámetro
|
|
76
|
+
|
|
77
|
+
`context.Context` es el primer parámetro de toda función que hace I/O, llama
|
|
78
|
+
a servicios externos o puede cancelarse/timeout.
|
|
79
|
+
|
|
80
|
+
```go
|
|
81
|
+
// MAL — sin context: no hay forma de cancelar ni hacer timeout
|
|
82
|
+
func (s *FacturaService) Crear(req CrearRequest) (*Factura, error) { ... }
|
|
83
|
+
|
|
84
|
+
// MAL — context en el struct (compartido entre llamadas)
|
|
85
|
+
type FacturaService struct {
|
|
86
|
+
ctx context.Context // NUNCA almacenar context en struct
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// BIEN — context como primer parámetro
|
|
90
|
+
func (s *FacturaService) Crear(ctx context.Context, req CrearRequest) (*Factura, error) {
|
|
91
|
+
// Propagar el context a llamadas downstream
|
|
92
|
+
if err := s.validar(ctx, req); err != nil {
|
|
93
|
+
return nil, err
|
|
94
|
+
}
|
|
95
|
+
factura, err := s.repo.Guardar(ctx, req.toFactura())
|
|
96
|
+
if err != nil {
|
|
97
|
+
return nil, fmt.Errorf("guardar factura: %w", err)
|
|
98
|
+
}
|
|
99
|
+
return factura, nil
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Error wrapping con fmt.Errorf y %w
|
|
106
|
+
|
|
107
|
+
Envolver errores agrega contexto sin perder el tipo original para `errors.Is`/`errors.As`.
|
|
108
|
+
|
|
109
|
+
```go
|
|
110
|
+
// MAL — error devuelto sin contexto
|
|
111
|
+
if err != nil {
|
|
112
|
+
return err // el llamador no sabe en qué operación falló
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// MAL — error formateado como string (pierde el tipo)
|
|
116
|
+
if err != nil {
|
|
117
|
+
return fmt.Errorf("error al guardar: " + err.Error())
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// BIEN — wrapping con %w preserva el tipo para unwrapping
|
|
121
|
+
if err != nil {
|
|
122
|
+
return fmt.Errorf("guardar factura %s: %w", factura.ID, err)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Errores sentinel para tipos conocidos
|
|
126
|
+
var (
|
|
127
|
+
ErrFacturaNoEncontrada = errors.New("factura no encontrada")
|
|
128
|
+
ErrClienteInactivo = errors.New("cliente inactivo")
|
|
129
|
+
ErrSaldoInsuficiente = errors.New("saldo insuficiente")
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
// Verificación con errors.Is (funciona aunque el error esté envuelto)
|
|
133
|
+
if errors.Is(err, ErrFacturaNoEncontrada) {
|
|
134
|
+
return c.JSON(http.StatusNotFound, errorResponse(err))
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Goroutines con errgroup
|
|
141
|
+
|
|
142
|
+
Usar `golang.org/x/sync/errgroup` para goroutines coordinadas. Propaga errores
|
|
143
|
+
y cancelación correctamente.
|
|
144
|
+
|
|
145
|
+
```go
|
|
146
|
+
// MAL — goroutines sin manejo de errores ni cancelación
|
|
147
|
+
var wg sync.WaitGroup
|
|
148
|
+
for _, id := range ids {
|
|
149
|
+
wg.Add(1)
|
|
150
|
+
go func(id uuid.UUID) {
|
|
151
|
+
defer wg.Done()
|
|
152
|
+
procesarFactura(id) // ¿cómo se maneja el error?
|
|
153
|
+
}(id)
|
|
154
|
+
}
|
|
155
|
+
wg.Wait()
|
|
156
|
+
|
|
157
|
+
// BIEN — errgroup maneja errores y cancela el resto si uno falla
|
|
158
|
+
g, ctx := errgroup.WithContext(ctx)
|
|
159
|
+
for _, id := range ids {
|
|
160
|
+
id := id // capturar para la goroutine (Go < 1.22)
|
|
161
|
+
g.Go(func() error {
|
|
162
|
+
return procesarFactura(ctx, id)
|
|
163
|
+
})
|
|
164
|
+
}
|
|
165
|
+
if err := g.Wait(); err != nil {
|
|
166
|
+
return fmt.Errorf("procesar facturas: %w", err)
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Table-driven tests como patrón por defecto
|
|
173
|
+
|
|
174
|
+
Ver la regla de testing para el ejemplo completo. Los table-driven tests son
|
|
175
|
+
el patrón idiomatic en Go para múltiples casos de prueba del mismo comportamiento.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Middleware pattern para HTTP
|
|
180
|
+
|
|
181
|
+
```go
|
|
182
|
+
// Tipo de middleware
|
|
183
|
+
type Middleware func(http.Handler) http.Handler
|
|
184
|
+
|
|
185
|
+
// Implementación de middleware de autenticación
|
|
186
|
+
func RequiereAutenticacion(validador TokenValidador) Middleware {
|
|
187
|
+
return func(next http.Handler) http.Handler {
|
|
188
|
+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
189
|
+
token := r.Header.Get("Authorization")
|
|
190
|
+
claims, err := validador.Validar(token)
|
|
191
|
+
if err != nil {
|
|
192
|
+
http.Error(w, "No autorizado", http.StatusUnauthorized)
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
// Propagar claims via context
|
|
196
|
+
ctx := context.WithValue(r.Context(), claimsKey, claims)
|
|
197
|
+
next.ServeHTTP(w, r.WithContext(ctx))
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Composición de middlewares
|
|
203
|
+
handler := RequiereAutenticacion(validador)(
|
|
204
|
+
RequiereRol("ADMIN")(
|
|
205
|
+
manejadorFacturas,
|
|
206
|
+
),
|
|
207
|
+
)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Preferir comunicación sobre mutex
|
|
213
|
+
|
|
214
|
+
```go
|
|
215
|
+
// MAL — mutex para estado compartido (propenso a deadlocks)
|
|
216
|
+
type Contador struct {
|
|
217
|
+
mu sync.Mutex
|
|
218
|
+
valor int
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
func (c *Contador) Incrementar() {
|
|
222
|
+
c.mu.Lock()
|
|
223
|
+
defer c.mu.Unlock()
|
|
224
|
+
c.valor++
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// BIEN — channel para comunicación entre goroutines (cuando aplica)
|
|
228
|
+
func NuevoContador() *Contador {
|
|
229
|
+
c := &Contador{ch: make(chan int, 1)}
|
|
230
|
+
c.ch <- 0 // valor inicial
|
|
231
|
+
go c.ejecutar()
|
|
232
|
+
return c
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Nota: mutex es apropiado para estado simple; channels para orquestación
|
|
236
|
+
// La regla es: "do not communicate by sharing memory; share memory by communicating"
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Checklist de patrones Go antes de abrir PR
|
|
242
|
+
|
|
243
|
+
- [ ] Funciones con múltiples parámetros opcionales usan functional options
|
|
244
|
+
- [ ] context.Context es el primer parámetro en toda función con I/O
|
|
245
|
+
- [ ] Errores envueltos con fmt.Errorf y %w (no descartados ni concatenados)
|
|
246
|
+
- [ ] Goroutines coordinadas usan errgroup, no WaitGroup manual
|
|
247
|
+
- [ ] Interfaces verificadas en compile time con `var _ Interface = (*Tipo)(nil)`
|
|
248
|
+
- [ ] Sin context.Context almacenado en structs
|
|
249
|
+
- [ ] Errores sentinel definidos para tipos de error conocidos
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# Regla: Seguridad Go
|
|
2
|
+
|
|
3
|
+
Esta regla es OBLIGATORIA para todo código Go de producción. Go tiene defaults
|
|
4
|
+
seguros en muchas áreas, pero no en todas. Las vulnerabilidades documentadas
|
|
5
|
+
aquí son evitables con los patrones correctos desde el inicio.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## gosec como scanner de seguridad en CI
|
|
10
|
+
|
|
11
|
+
`gosec` analiza el AST de Go buscando patrones de código inseguro. Es el primer
|
|
12
|
+
mecanismo de defensa automática.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Instalar
|
|
16
|
+
go install github.com/securego/gosec/v2/cmd/gosec@latest
|
|
17
|
+
|
|
18
|
+
# Ejecutar sobre todo el proyecto
|
|
19
|
+
gosec ./...
|
|
20
|
+
|
|
21
|
+
# En CI — falla si hay issues de severidad alta o media
|
|
22
|
+
gosec -severity medium -confidence medium -fmt json -out gosec-report.json ./...
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Reglas críticas que gosec verifica:
|
|
26
|
+
- G101: Credenciales hardcodeadas
|
|
27
|
+
- G201/G202: SQL injection
|
|
28
|
+
- G304: Path traversal en lectura de archivos
|
|
29
|
+
- G401/G501: Uso de algoritmos criptográficos débiles (MD5, SHA1)
|
|
30
|
+
- G501: Import de `math/rand` para uso criptográfico
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## No usar unsafe sin justificación en ADR
|
|
35
|
+
|
|
36
|
+
El paquete `unsafe` rompe las garantías de tipo y memoria de Go. Es legítimo
|
|
37
|
+
en casos muy específicos (interop con C, serialización de alto rendimiento),
|
|
38
|
+
pero nunca sin documentación explícita.
|
|
39
|
+
|
|
40
|
+
```go
|
|
41
|
+
// MAL — unsafe sin justificación
|
|
42
|
+
import "unsafe"
|
|
43
|
+
func convertirBytes(b []byte) string {
|
|
44
|
+
return *(*string)(unsafe.Pointer(&b))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// BIEN — conversión segura (copia, pero es lo correcto)
|
|
48
|
+
func convertirBytes(b []byte) string {
|
|
49
|
+
return string(b)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Excepción documentada — si se requiere unsafe por rendimiento crítico:
|
|
53
|
+
// 1. Crear ADR documentando la justificación
|
|
54
|
+
// 2. Aislar en archivo con nombre: unsafe_*.go
|
|
55
|
+
// 3. Comentario inline explicando por qué es seguro en este caso específico
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## crypto/rand para secretos — nunca math/rand
|
|
61
|
+
|
|
62
|
+
`math/rand` es un PRNG determinista. Predecible. Jamás para tokens, IDs de sesión,
|
|
63
|
+
claves criptográficas ni cualquier valor que deba ser impredecible.
|
|
64
|
+
|
|
65
|
+
```go
|
|
66
|
+
// MAL — math/rand: predecible, no apto para seguridad
|
|
67
|
+
import "math/rand"
|
|
68
|
+
token := fmt.Sprintf("%d", rand.Int63()) // VULNERABLE
|
|
69
|
+
|
|
70
|
+
// BIEN — crypto/rand: criptográficamente seguro
|
|
71
|
+
import (
|
|
72
|
+
"crypto/rand"
|
|
73
|
+
"encoding/base64"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
func GenerarToken(n int) (string, error) {
|
|
77
|
+
bytes := make([]byte, n)
|
|
78
|
+
if _, err := rand.Read(bytes); err != nil {
|
|
79
|
+
return "", fmt.Errorf("generar token: %w", err)
|
|
80
|
+
}
|
|
81
|
+
return base64.URLEncoding.EncodeToString(bytes), nil
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## html/template para HTML — no text/template
|
|
88
|
+
|
|
89
|
+
`text/template` NO escapa HTML automáticamente. Usar `html/template` siempre
|
|
90
|
+
que se genere HTML para evitar XSS.
|
|
91
|
+
|
|
92
|
+
```go
|
|
93
|
+
// MAL — text/template: sin escape automático de HTML
|
|
94
|
+
import "text/template"
|
|
95
|
+
tmpl := template.Must(template.New("").Parse("<h1>{{.Nombre}}</h1>"))
|
|
96
|
+
|
|
97
|
+
// BIEN — html/template: escapa automáticamente contenido potencialmente peligroso
|
|
98
|
+
import "html/template"
|
|
99
|
+
tmpl := template.Must(html_template.New("").Parse("<h1>{{.Nombre}}</h1>"))
|
|
100
|
+
// Si .Nombre = "<script>alert('xss')</script>", se renderiza como texto seguro
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## SQL con placeholders — nunca fmt.Sprintf
|
|
106
|
+
|
|
107
|
+
La inyección SQL es tan simple de evitar como usar placeholders. No hay excusa.
|
|
108
|
+
|
|
109
|
+
```go
|
|
110
|
+
// MAL — SQL injection garantizada
|
|
111
|
+
query := fmt.Sprintf("SELECT * FROM facturas WHERE cliente_id = '%s'", clienteID)
|
|
112
|
+
rows, err := db.QueryContext(ctx, query)
|
|
113
|
+
|
|
114
|
+
// MAL — strings.Builder no ayuda
|
|
115
|
+
var sb strings.Builder
|
|
116
|
+
sb.WriteString("SELECT * FROM facturas WHERE cliente_id = '")
|
|
117
|
+
sb.WriteString(clienteID)
|
|
118
|
+
|
|
119
|
+
// BIEN — placeholders: la BD separa código de datos
|
|
120
|
+
rows, err := db.QueryContext(ctx,
|
|
121
|
+
"SELECT id, total, estatus FROM facturas WHERE cliente_id = $1 AND estatus = $2",
|
|
122
|
+
clienteID, estatus,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
// BIEN — con sqlx o GORM (internamente usan placeholders)
|
|
126
|
+
var facturas []Factura
|
|
127
|
+
err := db.SelectContext(ctx, &facturas,
|
|
128
|
+
"SELECT * FROM facturas WHERE cliente_id = $1", clienteID)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## TLS 1.2+ en clientes HTTP
|
|
134
|
+
|
|
135
|
+
El cliente HTTP por defecto de Go es seguro en versiones recientes, pero
|
|
136
|
+
es mejor ser explícito con la configuración mínima de TLS.
|
|
137
|
+
|
|
138
|
+
```go
|
|
139
|
+
// MAL — skip de verificación de certificado (nunca en producción)
|
|
140
|
+
cliente := &http.Client{
|
|
141
|
+
Transport: &http.Transport{
|
|
142
|
+
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // PROHIBIDO
|
|
143
|
+
},
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// BIEN — TLS mínimo explícito
|
|
147
|
+
cliente := &http.Client{
|
|
148
|
+
Timeout: 30 * time.Second,
|
|
149
|
+
Transport: &http.Transport{
|
|
150
|
+
TLSClientConfig: &tls.Config{
|
|
151
|
+
MinVersion: tls.VersionTLS12,
|
|
152
|
+
},
|
|
153
|
+
DialContext: (&net.Dialer{
|
|
154
|
+
Timeout: 10 * time.Second,
|
|
155
|
+
KeepAlive: 30 * time.Second,
|
|
156
|
+
}).DialContext,
|
|
157
|
+
},
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## No almacenar secretos en structs serializables
|
|
164
|
+
|
|
165
|
+
Los structs con tags `json:` o `yaml:` pueden serializarse accidentalmente
|
|
166
|
+
en logs, respuestas de API o archivos de configuración.
|
|
167
|
+
|
|
168
|
+
```go
|
|
169
|
+
// MAL — el campo Password aparece en JSON si se serializa Config
|
|
170
|
+
type Config struct {
|
|
171
|
+
Host string `json:"host"`
|
|
172
|
+
Password string `json:"password"` // PELIGROSO: aparece en logs/respuestas
|
|
173
|
+
APIKey string `json:"api_key"`
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// BIEN — secretos sin tag json, o con "-" para excluirlos siempre
|
|
177
|
+
type Config struct {
|
|
178
|
+
Host string `json:"host"`
|
|
179
|
+
Password string `json:"-"` // nunca serializado
|
|
180
|
+
APIKey string `json:"-"`
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// BIEN — tipo opaco que no serializa su contenido
|
|
184
|
+
type SecretString string
|
|
185
|
+
func (s SecretString) MarshalJSON() ([]byte, error) {
|
|
186
|
+
return []byte(`"[REDACTED]"`), nil
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Rate limiting con golang.org/x/time/rate
|
|
193
|
+
|
|
194
|
+
```go
|
|
195
|
+
import "golang.org/x/time/rate"
|
|
196
|
+
|
|
197
|
+
// Limiter: 10 requests por segundo, burst de 20
|
|
198
|
+
limiter := rate.NewLimiter(rate.Limit(10), 20)
|
|
199
|
+
|
|
200
|
+
// Middleware de rate limiting
|
|
201
|
+
func RateLimitMiddleware(limiter *rate.Limiter) func(http.Handler) http.Handler {
|
|
202
|
+
return func(next http.Handler) http.Handler {
|
|
203
|
+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
204
|
+
if !limiter.Allow() {
|
|
205
|
+
http.Error(w, "Demasiadas solicitudes", http.StatusTooManyRequests)
|
|
206
|
+
return
|
|
207
|
+
}
|
|
208
|
+
next.ServeHTTP(w, r)
|
|
209
|
+
})
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Checklist de seguridad Go antes de abrir PR
|
|
217
|
+
|
|
218
|
+
- [ ] `gosec ./...` pasa sin issues de severidad media o alta
|
|
219
|
+
- [ ] Sin importación de `math/rand` para valores de seguridad — usar `crypto/rand`
|
|
220
|
+
- [ ] Sin `InsecureSkipVerify: true` en ningún cliente TLS
|
|
221
|
+
- [ ] SQL usa placeholders (`$1`, `?`) — sin fmt.Sprintf en queries
|
|
222
|
+
- [ ] HTML renderizado con `html/template`, no `text/template`
|
|
223
|
+
- [ ] Sin `unsafe` sin ADR documentado y comentario de justificación
|
|
224
|
+
- [ ] Secretos en structs marcados con `json:"-"` o tipo opaco
|
|
225
|
+
- [ ] Rate limiting configurado en endpoints públicos
|