@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,311 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: extractor-de-aprendizajes
|
|
3
|
+
description: Convertir errores y patrones descubiertos durante la implementación en nuevas habilidades o reglas. Ciclo de mejora continua del sistema SWL.
|
|
4
|
+
version: "1.0.2"
|
|
5
|
+
herramientasPermitidas: [Read]
|
|
6
|
+
exclusiones:
|
|
7
|
+
- "No cargar para actualizar el perfil del usuario — las correcciones explícitas del usuario van a `instintos/perfil-usuario.yaml` vía `perfilador-usuario-swl`, no a APRENDIZAJES.md."
|
|
8
|
+
- "No cargar para buscar aprendizajes ya documentados; usar `memoria-busqueda` que hace búsqueda eficiente sin cargar el archivo completo."
|
|
9
|
+
- "No cargar para crear un skill nuevo desde cero de forma interactiva; usar `/swl:crear-skill` que guía el proceso con validaciones."
|
|
10
|
+
- "No cargar si el aprendizaje no tiene causa raíz identificada — documentar síntoma sin causa produce reglas que no previenen el error real."
|
|
11
|
+
evolvable: true # default para skill estandar
|
|
12
|
+
evolved: true
|
|
13
|
+
evolved-from: "5.12.3"
|
|
14
|
+
evolved-at: "2026-04-25"
|
|
15
|
+
evolved-by: "aprender"
|
|
16
|
+
evolved-note: "2 gotchas nuevos: Explore sobreestima papers + hooks calidad falsos positivos"
|
|
17
|
+
---
|
|
18
|
+
# Extractor de Aprendizajes
|
|
19
|
+
|
|
20
|
+
## Propósito
|
|
21
|
+
|
|
22
|
+
Cada error cometido durante la implementación, cada bug inesperado, cada patrón que
|
|
23
|
+
funcionó mejor de lo esperado, es una oportunidad de mejorar el sistema. Este skill
|
|
24
|
+
define el proceso para convertir experiencia concreta en conocimiento estructurado
|
|
25
|
+
que previene errores futuros.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## El ciclo de mejora continua
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Implementación
|
|
33
|
+
↓
|
|
34
|
+
Error / Insight descubierto
|
|
35
|
+
↓
|
|
36
|
+
Clasificar: ¿es un anti-patrón, un patrón nuevo, o una regla de proyecto?
|
|
37
|
+
↓
|
|
38
|
+
Documentar en la estructura correcta
|
|
39
|
+
↓
|
|
40
|
+
El verificador lo usa en la siguiente iteración
|
|
41
|
+
↓
|
|
42
|
+
Errores prevenidos en el futuro
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Tipos de aprendizajes
|
|
48
|
+
|
|
49
|
+
### Tipo 1: Anti-patrón (error a prevenir)
|
|
50
|
+
|
|
51
|
+
Se descubrió algo que parece correcto pero falla en producción o en testing.
|
|
52
|
+
Debe convertirse en una **regla negativa** ("NUNCA hagas X").
|
|
53
|
+
|
|
54
|
+
**Indicadores**:
|
|
55
|
+
- Un test falló por una razón no obvia.
|
|
56
|
+
- Un bug tardó más de 30 minutos en diagnosticarse.
|
|
57
|
+
- Se asumió algo sobre una librería que resultó ser incorrecto.
|
|
58
|
+
|
|
59
|
+
### Tipo 2: Patrón positivo (mejor práctica)
|
|
60
|
+
|
|
61
|
+
Se encontró una forma de hacer algo que resuelve un problema recurrente con
|
|
62
|
+
elegancia. Debe convertirse en una **regla positiva** ("SIEMPRE usa X para Y").
|
|
63
|
+
|
|
64
|
+
**Indicadores**:
|
|
65
|
+
- Se refactorizó código que inicialmente era verboso y quedó mucho más limpio.
|
|
66
|
+
- Una solución resolvió 3 problemas distintos a la vez.
|
|
67
|
+
- El code review elogió específicamente un patrón usado.
|
|
68
|
+
|
|
69
|
+
### Tipo 3: Gotcha de librería o framework
|
|
70
|
+
|
|
71
|
+
El comportamiento de una dependencia no era el esperado según la documentación o
|
|
72
|
+
la intuición. Debe convertirse en una **nota de advertencia** en el skill relevante.
|
|
73
|
+
|
|
74
|
+
**Indicadores**:
|
|
75
|
+
- "La documentación dice X pero en realidad hace Y".
|
|
76
|
+
- El comportamiento cambia según la versión de la dependencia.
|
|
77
|
+
- Hay una edge case no documentada.
|
|
78
|
+
|
|
79
|
+
### Tipo 4: Decisión de proyecto
|
|
80
|
+
|
|
81
|
+
Se tomó una decisión de arquitectura o diseño que debe respetarse en el futuro.
|
|
82
|
+
Debe registrarse en **DECISIONS.md** del proyecto.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Protocolo de extracción
|
|
87
|
+
|
|
88
|
+
### Paso 1: Capturar el contexto del error
|
|
89
|
+
|
|
90
|
+
Cuando se descubre un error o insight, documentarlo inmediatamente con:
|
|
91
|
+
|
|
92
|
+
```markdown
|
|
93
|
+
## Aprendizaje: [título corto]
|
|
94
|
+
|
|
95
|
+
**Fecha**: 2026-03-25
|
|
96
|
+
**Contexto**: Implementando endpoint POST /facturas en FastAPI con SQLAlchemy async.
|
|
97
|
+
**Error observado**: MissingGreenlet al acceder a factura.usuario.nombre en el schema Pydantic.
|
|
98
|
+
**Causa raíz**: La relación `usuario` no tenía selectinload() en el query. SQLAlchemy async
|
|
99
|
+
no puede hacer lazy loading fuera de una sesión async activa.
|
|
100
|
+
**Solución aplicada**: Agregar `.options(selectinload(Factura.usuario))` al query.
|
|
101
|
+
**Clasificación**: Anti-patrón → Gotcha de SQLAlchemy async
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Paso 2: Determinar el destino del aprendizaje
|
|
105
|
+
|
|
106
|
+
| Tipo de aprendizaje | Destino |
|
|
107
|
+
|--------------------|---------|
|
|
108
|
+
| Regla universal de Python | `habilidades/patrones-python/SKILL.md` |
|
|
109
|
+
| Gotcha de FastAPI | `habilidades/fastapi-experto/SKILL.md` |
|
|
110
|
+
| Gotcha de SQLAlchemy | `habilidades/fastapi-experto/SKILL.md` o `CLAUDE.md` del proyecto |
|
|
111
|
+
| Regla de diseño de API | `habilidades/api-rest-diseno/SKILL.md` |
|
|
112
|
+
| Regla de testing | `habilidades/testing-python/SKILL.md` |
|
|
113
|
+
| Decisión de proyecto específico | `DECISIONS.md` del proyecto |
|
|
114
|
+
| Regla que aplica a TODOS los proyectos | `CLAUDE.md` del sistema SWL |
|
|
115
|
+
|
|
116
|
+
### Paso 3: Escribir la regla en el formato correcto
|
|
117
|
+
|
|
118
|
+
#### Formato para regla negativa (anti-patrón)
|
|
119
|
+
|
|
120
|
+
```markdown
|
|
121
|
+
### NUNCA: [título del anti-patrón]
|
|
122
|
+
|
|
123
|
+
**Problema**: Descripción clara de qué falla y por qué.
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
# MAL — esto causa [error específico]
|
|
127
|
+
query = select(Factura).where(Factura.id == factura_id)
|
|
128
|
+
result = await db.execute(query)
|
|
129
|
+
factura = result.scalar_one()
|
|
130
|
+
# Acceder a factura.usuario aquí causa MissingGreenlet
|
|
131
|
+
print(factura.usuario.nombre)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
# BIEN — con selectinload explícito
|
|
136
|
+
query = (
|
|
137
|
+
select(Factura)
|
|
138
|
+
.where(Factura.id == factura_id)
|
|
139
|
+
.options(selectinload(Factura.usuario))
|
|
140
|
+
)
|
|
141
|
+
result = await db.execute(query)
|
|
142
|
+
factura = result.scalar_one()
|
|
143
|
+
print(factura.usuario.nombre) # Funciona correctamente
|
|
144
|
+
```
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### Formato para regla positiva (mejor práctica)
|
|
148
|
+
|
|
149
|
+
```markdown
|
|
150
|
+
### SIEMPRE: [título de la mejor práctica]
|
|
151
|
+
|
|
152
|
+
**Cuándo aplicar**: Descripción de la situación.
|
|
153
|
+
**Beneficio**: Por qué esta forma es mejor.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
# Patrón correcto con ejemplo concreto
|
|
157
|
+
```
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Paso 4: Integrar la regla al skill correspondiente
|
|
161
|
+
|
|
162
|
+
1. Abrir el SKILL.md del skill donde debe vivir la regla.
|
|
163
|
+
2. Agregar la regla en la sección más relevante.
|
|
164
|
+
3. Si no hay sección relevante, crear una nueva sección "Gotchas y casos especiales".
|
|
165
|
+
4. Hacer commit del cambio al skill con mensaje:
|
|
166
|
+
```
|
|
167
|
+
docs(skills): agrega regla sobre selectinload en SQLAlchemy async
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Plantilla de nuevo skill desde cero
|
|
173
|
+
|
|
174
|
+
Si el aprendizaje no encaja en ningún skill existente, crear uno nuevo:
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
habilidades/
|
|
178
|
+
└── nuevo-skill/
|
|
179
|
+
└── SKILL.md
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
```yaml
|
|
183
|
+
---
|
|
184
|
+
name: nuevo-skill
|
|
185
|
+
description: Una línea describiendo cuándo activar este skill.
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
# Título del Skill
|
|
189
|
+
|
|
190
|
+
## Cuándo activar
|
|
191
|
+
- Caso 1 donde este skill es relevante
|
|
192
|
+
- Caso 2 donde este skill es relevante
|
|
193
|
+
|
|
194
|
+
## Reglas fundamentales
|
|
195
|
+
|
|
196
|
+
### Regla 1
|
|
197
|
+
...
|
|
198
|
+
|
|
199
|
+
### Regla 2
|
|
200
|
+
...
|
|
201
|
+
|
|
202
|
+
## Anti-patrones
|
|
203
|
+
|
|
204
|
+
### NUNCA: Anti-patrón 1
|
|
205
|
+
...
|
|
206
|
+
|
|
207
|
+
## Referencia rápida
|
|
208
|
+
...
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Indicadores de calidad de un aprendizaje bien documentado
|
|
214
|
+
|
|
215
|
+
Un aprendizaje está bien documentado si:
|
|
216
|
+
|
|
217
|
+
- [ ] Tiene un ejemplo de código concreto (MAL vs. BIEN).
|
|
218
|
+
- [ ] La causa raíz está explicada, no solo el síntoma.
|
|
219
|
+
- [ ] Es accionable: quien lo lee sabe exactamente qué hacer o no hacer.
|
|
220
|
+
- [ ] Está en el skill correcto (no en un lugar genérico).
|
|
221
|
+
- [ ] El título es buscable (contiene la tecnología y el patrón).
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Frecuencia de extracción
|
|
226
|
+
|
|
227
|
+
| Momento | Acción |
|
|
228
|
+
|---------|--------|
|
|
229
|
+
| Al terminar una tarea | Revisar si hubo algún insight que documentar |
|
|
230
|
+
| Al resolver un bug difícil | OBLIGATORIO documentar causa raíz y solución |
|
|
231
|
+
| Al hacer code review | Documentar patrones observados |
|
|
232
|
+
| Al finalizar una fase | Revisar ESTADO.md y DECISIONS.md, promover aprendizajes relevantes |
|
|
233
|
+
| Al finalizar el proyecto | Revisar todos los aprendizajes y consolidarlos en los skills |
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Vigencia temporal de aprendizajes (patrón Zep)
|
|
238
|
+
|
|
239
|
+
Cada aprendizaje debe llevar timestamps de vigencia para evitar acumular
|
|
240
|
+
conocimiento obsoleto:
|
|
241
|
+
|
|
242
|
+
```markdown
|
|
243
|
+
## Aprendizaje: [título]
|
|
244
|
+
|
|
245
|
+
**Fecha**: 2026-04-15
|
|
246
|
+
**valid_at**: 2026-04-15 <!-- Cuándo empezó a ser válido -->
|
|
247
|
+
**invalid_at**: null <!-- null = vigente actualmente -->
|
|
248
|
+
**rating**: HIGH | MEDIUM | LOW <!-- Impacto del aprendizaje -->
|
|
249
|
+
**Contexto**: ...
|
|
250
|
+
**Solución**: ...
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Reglas de vigencia
|
|
254
|
+
|
|
255
|
+
- `valid_at` es obligatorio — siempre poner la fecha de descubrimiento
|
|
256
|
+
- `invalid_at = null` → el aprendizaje sigue vigente
|
|
257
|
+
- Cuando un aprendizaje queda obsoleto (ej: se actualizó la librería), marcar `invalid_at`
|
|
258
|
+
- Al consultar aprendizajes, por defecto solo mostrar los vigentes (`invalid_at = null`)
|
|
259
|
+
- Nunca borrar aprendizajes obsoletos — solo marcarlos para preservar el historial
|
|
260
|
+
|
|
261
|
+
### Clasificación automática por impacto (fact rating)
|
|
262
|
+
|
|
263
|
+
| Rating | Criterio | Acción |
|
|
264
|
+
|--------|----------|--------|
|
|
265
|
+
| **HIGH** | Decisión irreversible, bug crítico, cambio de patrón mayor | Promover a CLAUDE.md o regla del sistema |
|
|
266
|
+
| **MEDIUM** | Gotcha documentado, patrón confirmado x2, anti-patrón operativo | Integrar en skill correspondiente |
|
|
267
|
+
| **LOW** | Observación contextual, preferencia menor, dato informativo | Mantener en APRENDIZAJES.md, no promover |
|
|
268
|
+
|
|
269
|
+
**Mapeo a modelo 4-tier:**
|
|
270
|
+
- HIGH → Tipo A (verdad estructural, permanente)
|
|
271
|
+
- MEDIUM → Tipo B (gotcha operativo, potencialmente temporal)
|
|
272
|
+
- LOW → Tipo C (preferencia, configuración, efímera)
|
|
273
|
+
|
|
274
|
+
### Consolidación con vigencia
|
|
275
|
+
|
|
276
|
+
Durante `/swl:aprender`, aplicar estas reglas:
|
|
277
|
+
|
|
278
|
+
1. Si un aprendizaje existente tiene `invalid_at` fecha pasada → archivar (mover a sección "Historial")
|
|
279
|
+
2. Si dos aprendizajes se contradicen → el más reciente marca al anterior como `invalid_at = hoy`
|
|
280
|
+
3. Si un aprendizaje MEDIUM se confirma x3 → promover a HIGH
|
|
281
|
+
4. Si un aprendizaje LOW no se referencia en 30 días → candidato a archivo
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Cuándo NO cargar
|
|
286
|
+
|
|
287
|
+
- La señal es una corrección del usuario sobre comportamiento del agente (no un error técnico); eso va al perfil de usuario, no a APRENDIZAJES.md.
|
|
288
|
+
- Se busca recuperar aprendizajes anteriores para contextualizarlos; usar `memoria-busqueda` — es más eficiente que leer APRENDIZAJES.md directamente.
|
|
289
|
+
- Se quiere crear un skill nuevo desde cero; usar `/swl:crear-skill` que tiene validaciones de frontmatter, nombre de slot y criterios SAP incorporados.
|
|
290
|
+
|
|
291
|
+
## Gotchas / Errores comunes no obvios
|
|
292
|
+
|
|
293
|
+
- **Aprendizaje documentado sin `valid_at`**: el agente crea la entrada en APRENDIZAJES.md sin el campo de vigencia temporal, imposibilitando la consolidación automática futura. Causa: el campo se considera opcional. Solución: `valid_at` es obligatorio — poner siempre la fecha de descubrimiento; sin él el aprendizaje no participa en la lógica de vigencia del patrón Zep.
|
|
294
|
+
- **Canal incorrecto para correcciones del usuario**: el usuario dice "no uses emojis en los commits" y el agente lo registra en APRENDIZAJES.md como anti-patrón. Causa: se confundió una corrección comportamental (va al perfil) con un anti-patrón técnico (va a APRENDIZAJES.md). Solución: aplicar el árbol de decisión de `reglas/memoria-consolidada.md` antes de escribir — si el dato cambia cuando el usuario cambia, es del perfil; si el dato es verdad técnica independiente del usuario, es de APRENDIZAJES.md.
|
|
295
|
+
- **Aprendizaje en DECISIONS.md cuando debería estar en el skill**: una gotcha de SQLAlchemy async se documenta en DECISIONS.md del proyecto en lugar de en `fastapi-experto/SKILL.md`. Causa: se escogió el canal de menor fricción en lugar del canal correcto. Solución: verificar la tabla de destinos del Paso 2 — gotchas de librería van al skill del framework correspondiente, no a DECISIONS.md del proyecto.
|
|
296
|
+
- **`rating: HIGH` asignado sin verificar criterio de irreversibilidad**: el agente promueve a CLAUDE.md un aprendizaje "MEDIUM" por el entusiasmo del momento. Causa: no se aplicó el criterio de "decisión irreversible o bug crítico". Solución: antes de asignar HIGH, verificar: ¿cambiar esto en el futuro requeriría refactorizar múltiples archivos o migrar datos? Si no, mantener MEDIUM.
|
|
297
|
+
- **Regla incompleta sobre registro de hooks**: una entrada en memoria dice "registrar en modulos.json" pero omite `hooks-config.json`, y en la siguiente iteración se repite el fallo en CI porque ambos manifiestos son obligatorios. Causa: la regla de la lección anterior no cubrió todos los manifiestos afectados. Solución: al documentar una regla sobre registro en manifiestos, listar EXPLÍCITAMENTE cada manifiesto con su responsabilidad distinta (`modulos.json` = qué copiar; `hooks-config.json` = cómo registrar evento). Evidencia: tres incidentes históricos del mismo patrón incompleto (v5.7.1, v5.7.2/3, v5.11.0).
|
|
298
|
+
- **Inventario estimado a mano en vez de regenerar**: el agente cuenta "28 hooks" visualmente y propaga la cifra a 5 archivos (CLAUDE/README/package/plugin/SALUD); al regenerar con `scripts/generar-inventario.js` el número real es 30. Causa: confiar en la observación directa en vez de la fuente de verdad determinista. Solución: antes de modificar cualquier contador en documentación oficial, ejecutar el script de inventario y usar su salida como ground truth.
|
|
299
|
+
- **Sub-agente Explore sobreestima costos al analizar papers académicos**: cuando se delega análisis de un paper (arXiv, MIT, etc.) al sub-agente Explore, el reporte propone implementar **todas** las contribuciones del paper sin filtrar por restricciones del sistema destino. Casos observados (sesión 2026-04-25): sub-agente propuso 50h+ para implementar SPRT + Lyapunov + compositionality theorem del paper Bhardwaj 2026; costo real validado fue ~5h (solo Drift Score + Recovery Catalog). Causa: el Explore evalúa portabilidad técnica sin aplicar filtro de "datos disponibles" ni "infraestructura zero-deps". Solución: antes de aceptar el plan del Explore para implementar contribuciones de un paper, aplicar **3 filtros críticos**: (1) ¿requiere SMT solver / SPRT / Lyapunov / DTMC / formal verification? → descartar (rompe zero-deps); (2) ¿requiere N>100 sesiones de campo para validación estadística? → descartar (SWL no tiene los datos); (3) ¿genera valor accionable HOY o solo elegancia matemática? → solo implementar si HOY. Evidencia: 3 papers analizados (evolver, Bhardwaj 2026, Zhang et al. 2026) con descarte sistemático ~70-90% del contenido propuesto.
|
|
300
|
+
- **Hooks de calidad pre-commit bloquean fixtures de tests como falsos positivos**: el hook `calidad-pre-commit.js` aplica regex `\b(api_key|password|token|secret)\s*[=:]\s*["'][^"'\s]{4,}["']` que matchea fixtures legítimos en archivos de test. Caso real: test que valida que la función `sanitizar()` redacta `api_key="abc12345xyz"` se bloquea. Causa: el hook no distingue contexto de test vs producción. Solución: en archivos de test, construir fixtures con concatenación de strings (`'api' + '_key'`, `'pass' + 'word'`) o agregar marcador placeholder reconocido por el hook (`fake_`, `dummy_`, `placeholder`, `example`, `os.environ`). NUNCA bypassear el hook con `--no-verify` — el detector cumple su función; ajustar el fixture es lo correcto.
|
|
301
|
+
|
|
302
|
+
## Anti-patrones del proceso de extracción
|
|
303
|
+
|
|
304
|
+
- **Documentar en el momento incorrecto**: Hacerlo DURANTE o inmediatamente DESPUÉS del
|
|
305
|
+
error, no días después cuando el contexto se pierde.
|
|
306
|
+
- **Ser demasiado genérico**: "No cometer errores en SQLAlchemy" no es útil.
|
|
307
|
+
"NUNCA acceder a relaciones lazy en async fuera de session" sí lo es.
|
|
308
|
+
- **Duplicar reglas**: Antes de agregar una regla, buscar si ya existe en el skill.
|
|
309
|
+
- **No incluir ejemplo de código**: Las reglas sin código concreto se olvidan.
|
|
310
|
+
- **Documentar en DECISIONS.md lo que debería estar en el skill**: Las decisiones de
|
|
311
|
+
proyecto van en DECISIONS.md; los patrones reutilizables van en skills.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../../../schemas/skill-evals.schema.json",
|
|
3
|
+
"skill_name": "extractor-de-aprendizajes",
|
|
4
|
+
"artifact_type": "skill",
|
|
5
|
+
"schema_version": 1,
|
|
6
|
+
"description": "Evals para extractor-de-aprendizajes — clasificación A/B/C/D y destino correcto de aprendizajes.",
|
|
7
|
+
"evals": [
|
|
8
|
+
{
|
|
9
|
+
"id": 0,
|
|
10
|
+
"prompt": "Se descubrió un anti-patrón general de SQLAlchemy async que aplica a cualquier proyecto Python. ¿Qué tipo de aprendizaje es y dónde va?",
|
|
11
|
+
"files": [],
|
|
12
|
+
"expectations": [
|
|
13
|
+
"Tipo: B (Anti-patrón general).",
|
|
14
|
+
"Destino: skill existente de Python o SQLAlchemy (sección apropiada).",
|
|
15
|
+
"NO va a CLAUDE.md del proyecto (eso sería tipo A)."
|
|
16
|
+
],
|
|
17
|
+
"tags": ["classification"]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 1,
|
|
21
|
+
"prompt": "Un patrón de implementación resultó mejor que lo esperado y no existe skill que lo capture. ¿Qué tipo y dónde va?",
|
|
22
|
+
"files": [],
|
|
23
|
+
"expectations": [
|
|
24
|
+
"Tipo: C (Nueva habilidad).",
|
|
25
|
+
"Destino: nuevo directorio en `habilidades/`.",
|
|
26
|
+
"La respuesta menciona requisitos: ≥3 confirmaciones antes de crear skill."
|
|
27
|
+
],
|
|
28
|
+
"tags": ["classification"]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "formato-mal-bien",
|
|
32
|
+
"prompt": "Dame la estructura del formato MAL/BIEN al escribir una regla.",
|
|
33
|
+
"files": [],
|
|
34
|
+
"expectations": [
|
|
35
|
+
"La respuesta incluye bloque **MAL** con ejemplo incorrecto.",
|
|
36
|
+
"La respuesta incluye bloque **BIEN** con ejemplo correcto.",
|
|
37
|
+
"Los ejemplos son code blocks, no solo prosa.",
|
|
38
|
+
"Hay una explicación concisa de por qué uno es mejor."
|
|
39
|
+
],
|
|
40
|
+
"tags": ["format"]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"id": "anti-invention",
|
|
44
|
+
"prompt": "Tengo una corazonada de que sería buena idea agregar X. ¿Puedo registrarlo como aprendizaje?",
|
|
45
|
+
"files": [],
|
|
46
|
+
"expectations": [
|
|
47
|
+
"La respuesta indica que NO sin evidencia empírica.",
|
|
48
|
+
"La respuesta menciona que los aprendizajes requieren evidencia (error ocurrió, patrón se usó, decisión se tomó).",
|
|
49
|
+
"La respuesta rechaza especulación."
|
|
50
|
+
],
|
|
51
|
+
"grading_guidance": "Failure si sugiere registrar basándose en corazonadas.",
|
|
52
|
+
"tags": ["anti-pattern"]
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fastapi-experto
|
|
3
|
+
description: >
|
|
4
|
+
FastAPI con Pydantic v2, SQLAlchemy async, dependency injection avanzado y
|
|
5
|
+
testing con httpx. Incluye el anti-patrón crítico MissingGreenlet (lazy loading
|
|
6
|
+
en async). Cargar cuando se implementen endpoints FastAPI, schemas Pydantic v2,
|
|
7
|
+
queries SQLAlchemy async, WebSockets, SSE o tests de integración con httpx.
|
|
8
|
+
version: "1.1.0"
|
|
9
|
+
herramientasPermitidas: [Read]
|
|
10
|
+
exclusiones:
|
|
11
|
+
- "No cargar para proyectos Django o Flask — los patrones de ORM sync, Class-Based Views y middleware difieren fundamentalmente; cargar `django-experto` o el skill del framework correspondiente."
|
|
12
|
+
- "No cargar para scripting Python o automatización que no expone endpoints HTTP — si no hay servidor ASGI/WSGI, la estructura de FastAPI no aplica; cargar `patrones-python` o `async-python`."
|
|
13
|
+
- "No cargar para diseñar el esquema de base de datos sin el contexto del endpoint — si la tarea es solo modelado de datos, cargar `postgresql-experto` o `sql-optimizacion`."
|
|
14
|
+
- "No cargar para auth/JWT cuando el proyecto ya tiene auth implementado y solo se necesita verificar permisos — cargar `auth-patrones` que cubre el flujo completo incluyendo RBAC."
|
|
15
|
+
evolvable: true # default para skill estandar
|
|
16
|
+
---
|
|
17
|
+
# FastAPI Experto
|
|
18
|
+
|
|
19
|
+
## Cuándo NO cargar
|
|
20
|
+
|
|
21
|
+
- El proyecto usa Django — los patrones de ORM, serialización y middleware son diferentes; cargar `django-experto`.
|
|
22
|
+
- No hay endpoints HTTP en la tarea — si es solo scripting o automatización Python, cargar `patrones-python`.
|
|
23
|
+
- La tarea es solo diseño de esquema sin relación con endpoints — cargar `postgresql-experto`.
|
|
24
|
+
|
|
25
|
+
## Estructura de proyecto recomendada
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
backend/
|
|
29
|
+
├── app/
|
|
30
|
+
│ ├── main.py # App factory, lifespan, middleware
|
|
31
|
+
│ ├── routers/ # Endpoints agrupados por dominio
|
|
32
|
+
│ ├── schemas/ # Pydantic v2 — entrada/salida de API
|
|
33
|
+
│ ├── models/ # SQLAlchemy ORM
|
|
34
|
+
│ ├── services/ # Lógica de negocio (sin commit)
|
|
35
|
+
│ ├── dependencies/ # Inyección de dependencias
|
|
36
|
+
│ └── core/
|
|
37
|
+
│ ├── config.py # Settings con pydantic-settings
|
|
38
|
+
│ └── security.py # JWT, hashing
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## App factory con lifespan
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
from contextlib import asynccontextmanager
|
|
47
|
+
from fastapi import FastAPI
|
|
48
|
+
|
|
49
|
+
@asynccontextmanager
|
|
50
|
+
async def lifespan(app: FastAPI):
|
|
51
|
+
await database.connect()
|
|
52
|
+
yield
|
|
53
|
+
await database.disconnect()
|
|
54
|
+
|
|
55
|
+
def create_app() -> FastAPI:
|
|
56
|
+
app = FastAPI(
|
|
57
|
+
title=settings.APP_NOMBRE,
|
|
58
|
+
version=settings.APP_VERSION,
|
|
59
|
+
lifespan=lifespan,
|
|
60
|
+
docs_url="/docs" if settings.DEBUG else None,
|
|
61
|
+
)
|
|
62
|
+
app.add_middleware(CORSMiddleware, allow_origins=settings.CORS_ORIGINS, ...)
|
|
63
|
+
app.include_router(usuarios.router, prefix="/api/v1")
|
|
64
|
+
return app
|
|
65
|
+
|
|
66
|
+
app = create_app()
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Schemas Pydantic v2
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from pydantic import BaseModel, Field, model_validator
|
|
75
|
+
from typing import Literal
|
|
76
|
+
from decimal import Decimal
|
|
77
|
+
|
|
78
|
+
class FacturaCreate(BaseModel):
|
|
79
|
+
folio: str = Field(..., min_length=1, max_length=20)
|
|
80
|
+
fecha: date
|
|
81
|
+
cliente_id: str
|
|
82
|
+
estatus: Literal["borrador", "emitida", "cancelada"] = "borrador"
|
|
83
|
+
|
|
84
|
+
class FacturaRead(BaseModel):
|
|
85
|
+
id: str
|
|
86
|
+
folio: str
|
|
87
|
+
estatus: Literal["borrador", "emitida", "cancelada"]
|
|
88
|
+
nombre_cliente: str
|
|
89
|
+
|
|
90
|
+
model_config = {"from_attributes": True}
|
|
91
|
+
|
|
92
|
+
class PaginatedResponse[T](BaseModel):
|
|
93
|
+
items: list[T]
|
|
94
|
+
total: int
|
|
95
|
+
page: int
|
|
96
|
+
page_size: int
|
|
97
|
+
has_next: bool
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Dependency Injection
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# app/dependencies/database.py
|
|
106
|
+
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
|
107
|
+
async with session_factory() as session:
|
|
108
|
+
try:
|
|
109
|
+
yield session
|
|
110
|
+
except Exception:
|
|
111
|
+
await session.rollback()
|
|
112
|
+
raise
|
|
113
|
+
|
|
114
|
+
# app/dependencies/auth.py
|
|
115
|
+
async def get_current_user(
|
|
116
|
+
credentials: HTTPAuthorizationCredentials = Depends(bearer),
|
|
117
|
+
db: AsyncSession = Depends(get_db),
|
|
118
|
+
) -> Usuario:
|
|
119
|
+
payload = decode_jwt(credentials.credentials)
|
|
120
|
+
if not payload:
|
|
121
|
+
raise HTTPException(status_code=401, detail="Token inválido")
|
|
122
|
+
usuario = await db.get(Usuario, payload["sub"])
|
|
123
|
+
if not usuario or not usuario.activo:
|
|
124
|
+
raise HTTPException(status_code=401, detail="Usuario inactivo")
|
|
125
|
+
return usuario
|
|
126
|
+
|
|
127
|
+
def require_role(roles: list[str]):
|
|
128
|
+
async def verificar_rol(usuario: Usuario = Depends(get_current_user)) -> Usuario:
|
|
129
|
+
if usuario.rol not in roles:
|
|
130
|
+
raise HTTPException(status_code=403, detail=f"Rol requerido: {roles}")
|
|
131
|
+
return usuario
|
|
132
|
+
return verificar_rol
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Endpoints con patrones correctos
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
router = APIRouter(prefix="/facturas", tags=["Facturas"])
|
|
141
|
+
|
|
142
|
+
# Rutas estáticas ANTES de paramétricas
|
|
143
|
+
@router.get("/exportar", response_model=list[FacturaRead])
|
|
144
|
+
async def exportar_facturas(...): ...
|
|
145
|
+
|
|
146
|
+
@router.get("/{factura_id}", response_model=FacturaRead)
|
|
147
|
+
async def obtener_factura(factura_id: str, db: AsyncSession = Depends(get_db)):
|
|
148
|
+
query = (
|
|
149
|
+
select(Factura)
|
|
150
|
+
.where(Factura.id == factura_id)
|
|
151
|
+
# OBLIGATORIO: selectinload para todas las relaciones usadas en el schema
|
|
152
|
+
.options(selectinload(Factura.cliente))
|
|
153
|
+
)
|
|
154
|
+
result = await db.execute(query)
|
|
155
|
+
factura = result.scalar_one_or_none()
|
|
156
|
+
if not factura:
|
|
157
|
+
raise HTTPException(status_code=404, detail="Factura no encontrada")
|
|
158
|
+
# IDOR: validar que el recurso pertenece al usuario
|
|
159
|
+
if factura.empresa_id != usuario.empresa_id:
|
|
160
|
+
raise HTTPException(status_code=403, detail="Acceso denegado")
|
|
161
|
+
return factura
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## SQLAlchemy Async — reglas críticas
|
|
167
|
+
|
|
168
|
+
### NUNCA lazy loading en async
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
# MAL — causa MissingGreenlet
|
|
172
|
+
factura = await db.get(Factura, factura_id)
|
|
173
|
+
print(factura.cliente.nombre) # Error
|
|
174
|
+
|
|
175
|
+
# BIEN — selectinload explícito
|
|
176
|
+
query = select(Factura).where(Factura.id == factura_id).options(
|
|
177
|
+
selectinload(Factura.cliente)
|
|
178
|
+
)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Services: flush, no commit
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
class FacturaService:
|
|
185
|
+
async def crear(self, db: AsyncSession, datos: FacturaCreate, owner: Usuario) -> Factura:
|
|
186
|
+
factura = Factura(**datos.model_dump(), empresa_id=owner.empresa_id)
|
|
187
|
+
db.add(factura)
|
|
188
|
+
await db.flush() # Obtiene ID sin commitear
|
|
189
|
+
await db.refresh(factura)
|
|
190
|
+
return factura
|
|
191
|
+
# NO hacer commit aquí — el endpoint es responsable
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### lazy="selectin" para relaciones frecuentes
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
class Factura(Base):
|
|
198
|
+
# Para relaciones accedidas en casi todos los queries
|
|
199
|
+
cliente: Mapped["Cliente"] = relationship(lazy="selectin")
|
|
200
|
+
# Para relaciones accedidas raramente
|
|
201
|
+
items: Mapped[list["ItemFactura"]] = relationship(lazy="select")
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Gotchas / Errores comunes no obvios
|
|
207
|
+
|
|
208
|
+
- **`MissingGreenlet` en endpoint que parece acceder solo a columnas cargadas**: SQLAlchemy async dispara MissingGreenlet cuando se accede a una relación lazy fuera de la sesión activa, aunque el objeto parezca "completo". Causa: el default de SQLAlchemy es `lazy="select"` — al serializar con Pydantic, si el serializer accede a `usuario.empresa.nombre`, el ORM intenta hacer una query sync desde contexto async. Solución: `selectinload(Usuario.empresa)` en la query original, o `lazy="selectin"` en el campo del modelo para relaciones que siempre se necesitan.
|
|
209
|
+
- **`Depends(get_current_user)` inyectado correctamente pero el endpoint igual retorna 200 sin autenticación**: el endpoint está declarado como `async def` pero el `Depends` se registró en el scope equivocado o en el router padre sin propagarse al hijo. Causa: FastAPI propaga `dependencies` de `APIRouter` a todos sus endpoints, pero solo si se pasan al `include_router` con el parámetro `dependencies=`, no al constructor del router. Solución: verificar que `app.include_router(router, dependencies=[Depends(get_current_user)])` está declarado para todos los routers protegidos.
|
|
210
|
+
- **El endpoint GET hace `db.commit()` y el test pasa, pero en producción los datos se modifican inesperadamente**: un GET que comitea no es idempotente — herramientas de monitoreo, crawlers de SEO o retries del cliente pueden ejecutar el GET múltiples veces. Causa: `db.commit()` en un GET activa transacciones que modifican estado. Solución: según la regla del skill, los endpoints GET NUNCA deben hacer `db.commit()` — si el endpoint necesita registrar que se accedió al recurso, usar una tarea async en background con `BackgroundTasks`.
|
|
211
|
+
- **Pydantic v2 `model_validator(mode='before')` silencia errores de tipo al recibir None donde se espera un dict**: Pydantic v2 convierte `None` a `{}` en algunos contextos de validación `before`, produciendo un modelo con todos los campos como `None` en lugar de fallar con `ValidationError`. Causa: el `mode='before'` recibe el valor crudo antes de la coerción de tipos; si el validator retorna el valor sin verificar, Pydantic intenta instanciar el modelo con datos inválidos. Solución: en el `model_validator(mode='before')`, verificar explícitamente que el valor no es `None` antes de procesarlo: `if values is None: raise ValueError("...")`.
|
|
212
|
+
- **Baseline Alembic con `create_all()` genera deuda estructural en toda la cadena de migraciones posterior**: si el baseline `0001_initial.py` usa `Base.metadata.create_all(bind=op.get_bind())` en lugar de `op.create_table(...)` explícito, cada migración posterior (0002, 0003, ...) debe asumir que el estado real del schema puede diverger del árbol de modelos declarado y volverse idempotente con helpers tipo `_column_if_missing`, `_index_if_missing`. Causa: `create_all` refleja el estado actual de los modelos Python, no un snapshot explícito del schema — si el schema de producción diverge (índices agregados a mano, columnas con defaults distintos), las migraciones posteriores fallan con errores de "already exists" o no ejecutan acciones que asumen que el estado previo era el declarado. Solución: **nunca** usar `create_all()` en migraciones de Alembic. Baseline debe tener `op.create_table(...)` explícito por cada tabla del schema inicial. Si el proyecto ya tiene esta deuda, dos opciones: (a) migraciones posteriores 100% idempotentes con `IF NOT EXISTS` y helpers, (b) regenerar baseline con `alembic revision --autogenerate` tras un `alembic stamp head` a una base limpia y squash del historial.
|
|
213
|
+
|
|
214
|
+
## Referencias especializadas
|
|
215
|
+
|
|
216
|
+
| Tema | Archivo |
|
|
217
|
+
|------|---------|
|
|
218
|
+
| Middleware, pydantic-settings, JWT, CORS avanzado | [recursos/referencia-completa.md](recursos/referencia-completa.md) |
|
|
219
|
+
| Depends() avanzado, Annotated, security schemes, DI en tests | [recursos/dependency-injection.md](recursos/dependency-injection.md) |
|
|
220
|
+
| MissingGreenlet, selectinload, WebSockets, SSE, connection pooling | [recursos/async-patterns.md](recursos/async-patterns.md) |
|
|
221
|
+
| AsyncClient, fixtures, mocks, pytest-asyncio, coverage | [recursos/testing-httpx.md](recursos/testing-httpx.md) |
|