@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,267 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kotlin-testing
|
|
3
|
+
description: >
|
|
4
|
+
Testing Kotlin con MockK, Turbine para Flow, runTest para coroutines,
|
|
5
|
+
Kover para cobertura, Robolectric y Ktor test client. Incluye testing
|
|
6
|
+
de ViewModels con StateFlow y UI testing con Compose. Cargar cuando se
|
|
7
|
+
escriban tests Kotlin, tests de ViewModel o se configure cobertura en Android.
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
herramientasPermitidas: [Read, Grep]
|
|
10
|
+
exclusiones:
|
|
11
|
+
- "No cargar para implementar el código Kotlin de producción — primero implementar con `kotlin-experto` o `kotlin-compose`, luego escribir tests."
|
|
12
|
+
- "No cargar para tests Java con JUnit/Mockito — Java tiene su propio ecosistema de testing; cargar `java-testing`."
|
|
13
|
+
- "No cargar para errores de compilación Kotlin o Gradle en los tests — cargar `build-errors-kotlin`."
|
|
14
|
+
- "No cargar para tests E2E de UI Android con Espresso — Espresso no está cubierto por este skill que se enfoca en unit/integration con MockK y Compose testing."
|
|
15
|
+
evolvable: true # default para skill estandar
|
|
16
|
+
---
|
|
17
|
+
# Kotlin Testing — MockK, Turbine y runTest
|
|
18
|
+
|
|
19
|
+
## Cuándo NO cargar
|
|
20
|
+
|
|
21
|
+
- El código Kotlin de producción aún no existe — primero implementar con `kotlin-experto` o `kotlin-compose`, luego escribir tests.
|
|
22
|
+
- Los tests son para un proyecto Java con JUnit/Mockito — Java tiene su propio ecosistema; cargar `java-testing`.
|
|
23
|
+
- Los errores son de compilación Kotlin o Gradle en los archivos de test — cargar `build-errors-kotlin`.
|
|
24
|
+
- La pregunta es sobre tests E2E de UI Android con Espresso — Espresso no está cubierto por este skill.
|
|
25
|
+
|
|
26
|
+
## runTest — Tests de Coroutines
|
|
27
|
+
|
|
28
|
+
```kotlin
|
|
29
|
+
class FacturasViewModelTest {
|
|
30
|
+
|
|
31
|
+
// TestDispatcher controla el tiempo virtual
|
|
32
|
+
private val testDispatcher = UnconfinedTestDispatcher()
|
|
33
|
+
|
|
34
|
+
@Before
|
|
35
|
+
fun setup() {
|
|
36
|
+
Dispatchers.setMain(testDispatcher)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@After
|
|
40
|
+
fun teardown() {
|
|
41
|
+
Dispatchers.resetMain()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@Test
|
|
45
|
+
fun `cargarFacturas emite Exito cuando repositorio retorna datos`() = runTest {
|
|
46
|
+
// Arrange
|
|
47
|
+
val repo = mockk<IFacturasRepository>()
|
|
48
|
+
val facturas = listOf(Factura(id = "1", folio = "F-001"))
|
|
49
|
+
every { repo.observarFacturas(any()) } returns flowOf(facturas)
|
|
50
|
+
val vm = FacturasViewModel(repo, fakeSavedStateHandle("empresaId" to "empresa-1"))
|
|
51
|
+
|
|
52
|
+
// Act + Assert con Turbine
|
|
53
|
+
vm.uiState.test {
|
|
54
|
+
skipItems(1) // saltar Cargando inicial
|
|
55
|
+
val estado = awaitItem()
|
|
56
|
+
assertIs<FacturasUiState.Exito>(estado)
|
|
57
|
+
assertEquals(1, estado.facturas.size)
|
|
58
|
+
cancelAndConsumeRemainingEvents()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Turbine — Testing de Flow
|
|
67
|
+
|
|
68
|
+
```kotlin
|
|
69
|
+
// Turbine envuelve un Flow y permite aserciones item por item
|
|
70
|
+
@Test
|
|
71
|
+
fun `observarFacturas emite lista actualizada al insertar`() = runTest {
|
|
72
|
+
val dao = FakeFacturasDao()
|
|
73
|
+
|
|
74
|
+
dao.observarTodas().test {
|
|
75
|
+
// Primera emisión — lista vacía
|
|
76
|
+
assertEquals(emptyList(), awaitItem())
|
|
77
|
+
|
|
78
|
+
// Insertar elemento
|
|
79
|
+
dao.insertar(FacturaEntity(id = "1", folio = "F-001"))
|
|
80
|
+
|
|
81
|
+
// Segunda emisión — con el elemento
|
|
82
|
+
val lista = awaitItem()
|
|
83
|
+
assertEquals(1, lista.size)
|
|
84
|
+
assertEquals("F-001", lista[0].folio)
|
|
85
|
+
|
|
86
|
+
cancelAndConsumeRemainingEvents()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Verificar que Flow completa sin errores
|
|
91
|
+
@Test
|
|
92
|
+
fun `obtenerFacturasUnica completa sin error`() = runTest {
|
|
93
|
+
val flow = repo.obtenerFacturasUnica("empresa-1")
|
|
94
|
+
flow.test {
|
|
95
|
+
val items = awaitItem()
|
|
96
|
+
assertTrue(items.isNotEmpty())
|
|
97
|
+
awaitComplete()
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Verificar error en Flow
|
|
102
|
+
@Test
|
|
103
|
+
fun `Flow emite error cuando falla la red`() = runTest {
|
|
104
|
+
every { api.obtenerFacturas(any()) } throws IOException("sin red")
|
|
105
|
+
repo.observarFacturas("empresa-1").test {
|
|
106
|
+
awaitError().also { error ->
|
|
107
|
+
assertIs<IOException>(error)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## MockK — Sintaxis completa
|
|
116
|
+
|
|
117
|
+
```kotlin
|
|
118
|
+
// Mocks básicos
|
|
119
|
+
val repo = mockk<IFacturasRepository>()
|
|
120
|
+
val repo = mockk<IFacturasRepository>(relaxed = true) // stubs automáticos para Unit
|
|
121
|
+
|
|
122
|
+
// Stubs síncronos y async
|
|
123
|
+
every { repo.obtenerPorId("1") } returns Factura(id = "1")
|
|
124
|
+
coEvery { repo.obtenerAsync("1") } returns Factura(id = "1")
|
|
125
|
+
coEvery { repo.obtenerAsync("inexistente") } returns null
|
|
126
|
+
|
|
127
|
+
// Stubs de Flow
|
|
128
|
+
every { repo.observarFacturas(any()) } returns flowOf(listaFacturas)
|
|
129
|
+
every { repo.observarFacturas("vacio") } returns emptyFlow()
|
|
130
|
+
|
|
131
|
+
// Capturar argumento
|
|
132
|
+
val slot = slot<Factura>()
|
|
133
|
+
coEvery { repo.guardar(capture(slot)) } returns Unit
|
|
134
|
+
// Después del call:
|
|
135
|
+
assertEquals("F-001", slot.captured.folio)
|
|
136
|
+
|
|
137
|
+
// Verificaciones
|
|
138
|
+
coVerify(exactly = 1) { repo.guardar(any()) }
|
|
139
|
+
coVerify(exactly = 0) { repo.eliminar(any()) }
|
|
140
|
+
|
|
141
|
+
// Verificar orden
|
|
142
|
+
coVerifyOrder {
|
|
143
|
+
repo.validar(any())
|
|
144
|
+
repo.guardar(any())
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Spy — objeto real con algunos métodos substituidos
|
|
148
|
+
val realService = FacturasService(repo)
|
|
149
|
+
val spyService = spyk(realService)
|
|
150
|
+
coEvery { spyService.validarFolio(any()) } returns true
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Kover — Cobertura
|
|
156
|
+
|
|
157
|
+
```kotlin
|
|
158
|
+
// build.gradle.kts (módulo :app)
|
|
159
|
+
plugins {
|
|
160
|
+
id("org.jetbrains.kotlinx.kover") version "0.8.3"
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
kover {
|
|
164
|
+
reports {
|
|
165
|
+
filters {
|
|
166
|
+
excludes {
|
|
167
|
+
classes(
|
|
168
|
+
"*.BuildConfig",
|
|
169
|
+
"*.databinding.*",
|
|
170
|
+
"Hilt_*",
|
|
171
|
+
"*_Factory"
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
verify {
|
|
176
|
+
rule {
|
|
177
|
+
minBound(80) // 80% cobertura mínima de líneas
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Generar reporte
|
|
186
|
+
./gradlew koverHtmlReport
|
|
187
|
+
|
|
188
|
+
# Verificar umbral (falla si < 80%)
|
|
189
|
+
./gradlew koverVerify
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Compose UI Testing
|
|
195
|
+
|
|
196
|
+
```kotlin
|
|
197
|
+
class FacturasScreenTest {
|
|
198
|
+
|
|
199
|
+
@get:Rule
|
|
200
|
+
val composeRule = createComposeRule()
|
|
201
|
+
|
|
202
|
+
@Test
|
|
203
|
+
fun `pantalla muestra lista cuando estado es Exito`() {
|
|
204
|
+
val facturas = listOf(Factura(id = "1", folio = "F-001", total = 1000.0))
|
|
205
|
+
val estado = FacturasUiState.Exito(facturas)
|
|
206
|
+
|
|
207
|
+
composeRule.setContent {
|
|
208
|
+
FacturasScreen(uiState = estado, onFacturaClick = {})
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
composeRule.onNodeWithText("F-001").assertIsDisplayed()
|
|
212
|
+
composeRule.onNodeWithText("$1,000.00").assertIsDisplayed()
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
@Test
|
|
216
|
+
fun `pantalla muestra loader cuando estado es Cargando`() {
|
|
217
|
+
composeRule.setContent {
|
|
218
|
+
FacturasScreen(uiState = FacturasUiState.Cargando, onFacturaClick = {})
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
composeRule.onNodeWithContentDescription("Cargando").assertIsDisplayed()
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
@Test
|
|
225
|
+
fun `clic en factura llama al callback`() {
|
|
226
|
+
var clickedId: String? = null
|
|
227
|
+
val facturas = listOf(Factura(id = "1", folio = "F-001", total = 0.0))
|
|
228
|
+
|
|
229
|
+
composeRule.setContent {
|
|
230
|
+
FacturasScreen(
|
|
231
|
+
uiState = FacturasUiState.Exito(facturas),
|
|
232
|
+
onFacturaClick = { clickedId = it }
|
|
233
|
+
)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
composeRule.onNodeWithText("F-001").performClick()
|
|
237
|
+
assertEquals("1", clickedId)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
Para Robolectric (tests Android sin emulador), Ktor test client y el patrón
|
|
245
|
+
Fake vs Mock con ejemplos de implementación, ver
|
|
246
|
+
[recursos/testing-avanzado.md](recursos/testing-avanzado.md).
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## Gotchas / Errores comunes no obvios
|
|
251
|
+
|
|
252
|
+
**`runBlocking` en tests Android hace que los tests fallen en el thread principal de Robolectric**: usar `runBlocking` en tests con `@RunWith(RobolectricTestRunner::class)` bloquea el hilo principal que Robolectric necesita para procesar mensajes del Looper. Fix: usar `runTest` con `UnconfinedTestDispatcher` para tests de Android que necesitan el thread principal — `runTest` gestiona el dispatcher de forma compatible con Robolectric.
|
|
253
|
+
|
|
254
|
+
**Turbine `awaitItem()` sin `cancelAndIgnoreRemainingEvents()` al final hace que el test se cuelgue**: si el Flow emite más items de los que el test consume con `awaitItem()`, Turbine espera que el test explícitamente cancele o finalice el Flow. Fix: siempre terminar los bloques `turbineScope { ... }` con `cancelAndIgnoreRemainingEvents()` o `awaitComplete()` según el caso.
|
|
255
|
+
|
|
256
|
+
**`every { mock.suspend() } returns value` sin `coEvery` causa error de compilación**: MockK distingue entre funciones suspendidas y normales — usar `every` en una función suspendida genera un error críptico de tipo. Fix: usar siempre `coEvery { mock.suspendFn() } returns value` para mockear funciones `suspend`, y `coVerify` para verificarlas.
|
|
257
|
+
|
|
258
|
+
**`Dispatchers.setMain(testDispatcher)` en `@BeforeEach` sin `resetMain()` en `@AfterEach` contamina tests subsecuentes**: el dispatcher del Main persiste entre tests porque es un estado global de coroutines. Fix: siempre parear `Dispatchers.setMain(testDispatcher)` con `Dispatchers.resetMain()` en la fase de teardown, o usar la extensión `@ExtendWith(MainDispatcherRule::class)` de Coroutines Test.
|
|
259
|
+
|
|
260
|
+
## Checklist de tests Kotlin
|
|
261
|
+
|
|
262
|
+
- [ ] runTest en todos los tests de coroutines (no runBlocking en tests de Android)
|
|
263
|
+
- [ ] Dispatchers.setMain(testDispatcher) en @Before y resetMain() en @After
|
|
264
|
+
- [ ] Turbine usado para tests de Flow (no collect + lista manual)
|
|
265
|
+
- [ ] CancellationException nunca atrapada en helpers de test
|
|
266
|
+
- [ ] Kover configurado con umbral mínimo 80%
|
|
267
|
+
- [ ] Fakes para integración, mocks (MockK) para verificación de comportamiento
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Kotlin Testing — Referencia Avanzada
|
|
2
|
+
|
|
3
|
+
## Robolectric — Tests Android sin Emulador
|
|
4
|
+
|
|
5
|
+
```kotlin
|
|
6
|
+
@RunWith(RobolectricTestRunner::class)
|
|
7
|
+
@Config(sdk = [34])
|
|
8
|
+
class FacturasNotificationTest {
|
|
9
|
+
|
|
10
|
+
@Test
|
|
11
|
+
fun `notificacion se crea con titulo correcto`() {
|
|
12
|
+
val context = ApplicationProvider.getApplicationContext<Context>()
|
|
13
|
+
val builder = FacturasNotificationBuilder(context)
|
|
14
|
+
|
|
15
|
+
val notification = builder.construir("Factura F-001 procesada")
|
|
16
|
+
|
|
17
|
+
val extras = notification.extras
|
|
18
|
+
assertEquals("Facturas", extras.getString(Notification.EXTRA_TITLE))
|
|
19
|
+
assertEquals("Factura F-001 procesada",
|
|
20
|
+
extras.getString(Notification.EXTRA_TEXT))
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Ktor Test Client
|
|
28
|
+
|
|
29
|
+
```kotlin
|
|
30
|
+
class FacturasApiTest {
|
|
31
|
+
|
|
32
|
+
@Test
|
|
33
|
+
fun `POST facturas retorna 201 con datos validos`() = testApplication {
|
|
34
|
+
application { configurarRouting() }
|
|
35
|
+
|
|
36
|
+
val client = createClient {
|
|
37
|
+
install(ContentNegotiation) { json() }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
val response = client.post("/api/v1/facturas") {
|
|
41
|
+
contentType(ContentType.Application.Json)
|
|
42
|
+
setBody(CrearFacturaRequest(folio = "F-001", empresaId = "empresa-1"))
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
assertEquals(HttpStatusCode.Created, response.status)
|
|
46
|
+
val dto = response.body<FacturaDto>()
|
|
47
|
+
assertEquals("F-001", dto.folio)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Fake vs Mock — cuándo usar cada uno
|
|
55
|
+
|
|
56
|
+
```kotlin
|
|
57
|
+
// Fake — implementación en memoria para tests de integración
|
|
58
|
+
class FakeFacturasRepository : IFacturasRepository {
|
|
59
|
+
private val facturas = mutableListOf<Factura>()
|
|
60
|
+
private val _flow = MutableStateFlow(facturas.toList())
|
|
61
|
+
|
|
62
|
+
override fun observarFacturas(empresaId: String): StateFlow<List<Factura>> =
|
|
63
|
+
_flow.map { list -> list.filter { it.empresaId == empresaId } }
|
|
64
|
+
.stateIn(CoroutineScope(UnconfinedTestDispatcher()), Eagerly, emptyList())
|
|
65
|
+
|
|
66
|
+
override suspend fun guardar(factura: Factura) {
|
|
67
|
+
facturas.add(factura)
|
|
68
|
+
_flow.value = facturas.toList()
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Mock (MockK) — cuando el test verifica interacciones específicas, no estado
|
|
73
|
+
// Usar mockk cuando importa CÓMO se llama algo, no solo el resultado
|
|
74
|
+
```
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kubernetes-orquestacion
|
|
3
|
+
description: Kubernetes en producción. Deployments, Services, Ingress, ConfigMaps, Secrets, HPA, PDB, NetworkPolicies, Helm, Kustomize. Patrones de deployment blue-green y canary. Troubleshooting común.
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
herramientasPermitidas: [Read]
|
|
6
|
+
exclusiones:
|
|
7
|
+
- "No cargar para Dockerfiles y containerización de la imagen — para Docker cargar `contenedores-docker`."
|
|
8
|
+
- "No cargar para Terraform, Pulumi o infraestructura como código — para IaC cargar `terraform-experto`."
|
|
9
|
+
- "No cargar para service mesh (Istio, Linkerd) en profundidad o GitOps (ArgoCD, Flux) — este skill cubre los objetos core de Kubernetes, no plataformas de nivel superior."
|
|
10
|
+
- "No cargar para cloud-specific Kubernetes (EKS, AKS, GKE) y sus integraciones IAM específicas — para cloud cargar `cloud-aws`, `azure-cloud` o `gcp-cloud`."
|
|
11
|
+
evolvable: true # default para skill estandar
|
|
12
|
+
---
|
|
13
|
+
# Kubernetes — Orquestación en Producción
|
|
14
|
+
|
|
15
|
+
## Cuándo NO cargar
|
|
16
|
+
|
|
17
|
+
- La tarea es construir la imagen Docker: Dockerfile, multi-stage build — cargar `contenedores-docker`.
|
|
18
|
+
- El trabajo es Terraform o Pulumi para aprovisionar el cluster — cargar `terraform-experto`.
|
|
19
|
+
- El tema es service mesh (Istio, Linkerd) o GitOps (ArgoCD, Flux) en profundidad — este skill cubre los objetos core de Kubernetes.
|
|
20
|
+
- La tarea es específica de EKS/AKS/GKE: integraciones IAM, node pools, addons — cargar `cloud-aws`, `azure-cloud` o `gcp-cloud`.
|
|
21
|
+
|
|
22
|
+
Kubernetes es la plataforma estándar de orquestación de containers. Este skill cubre
|
|
23
|
+
los objetos principales, patrones de despliegue seguro y troubleshooting efectivo.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Reglas Obligatorias
|
|
28
|
+
|
|
29
|
+
1. **NUNCA `:latest` en producción** — usar tag de versión exacta.
|
|
30
|
+
2. **`resources.requests` y `resources.limits`** en TODOS los containers.
|
|
31
|
+
3. **`livenessProbe` + `readinessProbe`** en todos los pods de producción.
|
|
32
|
+
4. **`startupProbe`** para apps con arranque lento (>30s).
|
|
33
|
+
5. **`runAsNonRoot: true`** + `readOnlyRootFilesystem: true` en securityContext.
|
|
34
|
+
6. **`maxUnavailable: 0`** en RollingUpdate para zero-downtime.
|
|
35
|
+
7. **PodDisruptionBudget** OBLIGATORIO para servicios críticos.
|
|
36
|
+
8. **NetworkPolicy default-deny** + permisos explícitos (zero-trust).
|
|
37
|
+
9. **Secrets** gestionados con External Secrets Operator o Sealed Secrets.
|
|
38
|
+
10. **NUNCA Service tipo LoadBalancer directamente** — usar Ingress.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Deployment — Configuración Clave
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
spec:
|
|
46
|
+
replicas: 3
|
|
47
|
+
strategy:
|
|
48
|
+
type: RollingUpdate
|
|
49
|
+
rollingUpdate:
|
|
50
|
+
maxSurge: 1
|
|
51
|
+
maxUnavailable: 0 # Zero downtime
|
|
52
|
+
template:
|
|
53
|
+
spec:
|
|
54
|
+
securityContext:
|
|
55
|
+
runAsNonRoot: true
|
|
56
|
+
runAsUser: 1001
|
|
57
|
+
containers:
|
|
58
|
+
- name: api
|
|
59
|
+
image: registry.com/app:1.5.2 # NUNCA :latest
|
|
60
|
+
resources:
|
|
61
|
+
requests: { cpu: "100m", memory: "256Mi" }
|
|
62
|
+
limits: { cpu: "500m", memory: "512Mi" }
|
|
63
|
+
livenessProbe:
|
|
64
|
+
httpGet: { path: /health/live, port: http }
|
|
65
|
+
readinessProbe:
|
|
66
|
+
httpGet: { path: /health/ready, port: http }
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## PodDisruptionBudget
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
apiVersion: policy/v1
|
|
75
|
+
kind: PodDisruptionBudget
|
|
76
|
+
metadata:
|
|
77
|
+
name: api-pdb
|
|
78
|
+
spec:
|
|
79
|
+
minAvailable: 2
|
|
80
|
+
selector:
|
|
81
|
+
matchLabels:
|
|
82
|
+
app: api-nomina
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Deployment Strategies
|
|
88
|
+
|
|
89
|
+
| Estrategia | Riesgo | Rollback | Complejidad |
|
|
90
|
+
|-----------|--------|----------|-------------|
|
|
91
|
+
| Rolling Update | Bajo | kubectl rollout undo | Baja |
|
|
92
|
+
| Blue-Green | Muy bajo | Cambiar selector del Service | Media |
|
|
93
|
+
| Canary | Mínimo | Eliminar canary deployment | Alta |
|
|
94
|
+
|
|
95
|
+
**Blue-Green**: dos deployments (blue=actual, green=nueva). Cambiar el Service selector
|
|
96
|
+
para switch instantáneo. Rollback = volver al selector anterior.
|
|
97
|
+
|
|
98
|
+
**Canary**: deployment pequeño (1 pod de 10 = 10% tráfico) con Ingress canary annotation
|
|
99
|
+
`nginx.ingress.kubernetes.io/canary-weight: "10"`.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Helm — Comandos Esenciales
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
helm lint ./charts/mi-app
|
|
107
|
+
helm template mi-app ./charts/mi-app -f values-prod.yaml # Preview
|
|
108
|
+
helm upgrade --install mi-app ./charts/mi-app \
|
|
109
|
+
--namespace prod --create-namespace \
|
|
110
|
+
-f values-prod.yaml --set image.tag=1.5.2 --wait --timeout 5m
|
|
111
|
+
helm rollback mi-app 3 --namespace prod # Rollback
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Troubleshooting Rápido
|
|
117
|
+
|
|
118
|
+
| Síntoma | Comando | Causa común |
|
|
119
|
+
|---------|---------|-------------|
|
|
120
|
+
| Pod Pending | `kubectl describe pod` | Recursos insuficientes |
|
|
121
|
+
| CrashLoopBackOff | `kubectl logs --previous` | Error en la app |
|
|
122
|
+
| Sin tráfico | `kubectl get endpoints` | Selector no coincide |
|
|
123
|
+
| Lento | `kubectl top pods` | Recursos limit muy bajo |
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Checklist de Deployment Productivo
|
|
128
|
+
|
|
129
|
+
- [ ] `resources.requests` y `limits` definidos
|
|
130
|
+
- [ ] `livenessProbe` y `readinessProbe` configurados
|
|
131
|
+
- [ ] `startupProbe` para apps lentas
|
|
132
|
+
- [ ] PodDisruptionBudget para servicios críticos
|
|
133
|
+
- [ ] `runAsNonRoot: true` en securityContext
|
|
134
|
+
- [ ] `readOnlyRootFilesystem: true`
|
|
135
|
+
- [ ] NetworkPolicy default-deny + permisos explícitos
|
|
136
|
+
- [ ] HPA con métricas reales
|
|
137
|
+
- [ ] `maxUnavailable: 0` en RollingUpdate
|
|
138
|
+
- [ ] `podAntiAffinity` para distribuir en nodos distintos
|
|
139
|
+
- [ ] Secrets con External Secrets Operator
|
|
140
|
+
- [ ] Imagen con tag exacto (nunca `latest`)
|
|
141
|
+
|
|
142
|
+
Para manifiestos YAML completos (Deployment, Service, Ingress, HPA, NetworkPolicy, Helm, Blue-Green, Canary, troubleshooting), ver [recursos/manifiestos-completos.md](recursos/manifiestos-completos.md).
|
|
143
|
+
|
|
144
|
+
## Gotchas / Errores comunes no obvios
|
|
145
|
+
|
|
146
|
+
**`livenessProbe` con un threshold muy bajo mata pods sanos durante GC o inicialización**: si `livenessProbe` tiene `failureThreshold: 1` y `periodSeconds: 5`, una pausa de GC de 6 segundos en la JVM o Python reinicia el pod aunque la aplicación esté sana. Causa: el liveness probe no distingue entre "proceso muerto" y "proceso temporalmente ocupado". Fix: configurar `failureThreshold: 3` con `periodSeconds: 10` como mínimo, y usar `startupProbe` para aplicaciones con arranque lento — el `startupProbe` desactiva liveness/readiness hasta que la app esté lista.
|
|
147
|
+
|
|
148
|
+
**`resources.limits.memory` demasiado bajo causa OOMKilled silencioso que se ve como crash**: un pod con `limits.memory: 128Mi` y una carga que requiere 130Mi es terminado por el kernel con OOM sin mensaje claro — `kubectl describe pod` muestra `OOMKilled` solo en el campo `lastState`. Causa: los límites de memoria en Kubernetes se implementan con cgroups — exceder el límite termina el proceso inmediatamente. Fix: establecer limits basados en mediciones reales con `kubectl top pods` en carga real, dejando al menos 20% de margen sobre el consumo máximo observado.
|
|
149
|
+
|
|
150
|
+
**HPA con CPU como métrica no escala correctamente si los `resources.requests.cpu` no están bien calibrados**: el HPA escala cuando el CPU promedio supera el `targetCPUUtilizationPercentage` relativo a `requests.cpu`. Si `requests.cpu: "10m"` y la app usa "500m", el HPA ve 5000% de uso y escala agresivamente aunque haya capacidad. Causa: el HPA calcula utilización como `uso_actual / requests`, no sobre el nodo. Fix: calibrar `requests.cpu` al uso promedio real de la aplicación en carga normal — usar `kubectl top pods` en producción para obtener los valores correctos.
|
|
151
|
+
|
|
152
|
+
**`kubectl rollout undo` revierte al deployment anterior pero no revierte ConfigMaps ni Secrets referenciados**: si el deployment v2 usa `ConfigMap v2` y se hace rollout undo al deployment v1, el pod v1 puede iniciar con el `ConfigMap v2` si los pods usan el mismo nombre de ConfigMap. Causa: el rollout undo solo cambia la especificación del Deployment, no de los recursos referenciados. Fix: versionar los ConfigMaps con el mismo tag que el deployment (`config-api-v1`, `config-api-v2`) y actualizar la referencia en el Deployment — el rollout undo revertirá a la referencia al ConfigMap correcto.
|