@saulwade/swl-ses 2.6.0 → 2.8.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 +209 -197
- package/README.md +647 -600
- package/agentes/accesibilidad-wcag-swl.md +690 -690
- package/agentes/arquitecto-swl.md +267 -267
- package/agentes/auto-evolucion-swl.md +932 -932
- package/agentes/backend-csharp-swl.md +420 -420
- package/agentes/backend-go-swl.md +390 -390
- package/agentes/backend-java-swl.md +281 -281
- package/agentes/backend-rust-swl.md +364 -364
- package/agentes/backend-workers-swl.md +482 -482
- package/agentes/cloud-infra-swl.md +509 -509
- package/agentes/consolidador-swl.md +541 -541
- package/agentes/depurador-swl.md +352 -352
- package/agentes/devops-ci-swl.md +400 -400
- package/agentes/disenador-ui-swl.md +569 -569
- package/agentes/documentador-swl.md +345 -345
- package/agentes/frontend-angular-swl.md +621 -621
- package/agentes/frontend-css-swl.md +716 -716
- package/agentes/frontend-react-swl.md +692 -692
- package/agentes/frontend-swl.md +496 -496
- package/agentes/frontend-tailwind-swl.md +826 -826
- package/agentes/investigador-swl.md +432 -432
- package/agentes/investigador-ux-swl.md +505 -505
- package/agentes/migrador-swl.md +442 -442
- package/agentes/mobile-android-swl.md +511 -511
- package/agentes/mobile-cross-swl.md +541 -541
- package/agentes/mobile-ios-swl.md +502 -502
- package/agentes/mobile-testing-swl.md +302 -302
- package/agentes/nemesis-auditor-swl.md +285 -285
- package/agentes/observabilidad-swl.md +438 -438
- package/agentes/pagos-swl.md +310 -310
- package/agentes/perfilador-usuario-swl.md +321 -321
- package/agentes/planificador-swl.md +399 -399
- package/agentes/producto-prd-swl.md +589 -589
- package/agentes/red-team-swl.md +218 -218
- package/agentes/release-manager-swl.md +590 -590
- package/agentes/rendimiento-swl.md +713 -713
- package/agentes/revisor-angular-swl.md +278 -278
- package/agentes/revisor-csharp-swl.md +264 -264
- package/agentes/revisor-go-swl.md +259 -259
- package/agentes/revisor-java-swl.md +257 -257
- package/agentes/revisor-kotlin-swl.md +273 -273
- package/agentes/revisor-nextjs-swl.md +281 -281
- package/agentes/revisor-php-swl.md +271 -271
- package/agentes/revisor-react-swl.md +278 -278
- package/agentes/revisor-rust-swl.md +346 -346
- package/agentes/revisor-seguridad-swl.md +399 -399
- package/agentes/revisor-swift-swl.md +268 -268
- package/agentes/revisor-typescript-swl.md +346 -346
- package/agentes/tdd-qa-swl.md +393 -393
- package/bin/swl-ses.js +10 -0
- package/comandos/swl/actualizar.md +174 -174
- package/comandos/swl/adoptar-proyecto.md +265 -265
- package/comandos/swl/aprender.md +836 -836
- package/comandos/swl/aprobar-plan.md +146 -146
- package/comandos/swl/auditar-deps.md +134 -134
- package/comandos/swl/autoresearch.md +264 -264
- package/comandos/swl/ayuda.md +224 -224
- package/comandos/swl/brainstorm.md +52 -51
- package/comandos/swl/checkpoint.md +325 -325
- package/comandos/swl/claudemd.md +234 -234
- package/comandos/swl/compactar.md +310 -310
- package/comandos/swl/configurar-ci.md +235 -235
- package/comandos/swl/contexto.md +110 -110
- package/comandos/swl/crear-skill.md +292 -292
- package/comandos/swl/cron.md +194 -194
- package/comandos/swl/deuda-codigo.md +97 -97
- package/comandos/swl/discutir-fase.md +169 -169
- package/comandos/swl/ejecutar-fase.md +233 -233
- package/comandos/swl/evaluar-skill.md +520 -520
- package/comandos/swl/evolucion-continua.md +73 -73
- package/comandos/swl/evolucionar.md +267 -267
- package/comandos/swl/exportar-vault.md +583 -583
- package/comandos/swl/fix.md +118 -118
- package/comandos/swl/gateway.md +158 -158
- package/comandos/swl/inbox.md +116 -116
- package/comandos/swl/instalar.md +220 -220
- package/comandos/swl/instintos.md +86 -86
- package/comandos/swl/mapear-codebase.md +312 -312
- package/comandos/swl/mcp-status.md +176 -175
- package/comandos/swl/modelo.md +100 -100
- package/comandos/swl/nemesis.md +433 -433
- package/comandos/swl/notificaciones.md +299 -299
- package/comandos/swl/nuevo-proyecto.md +251 -251
- package/comandos/swl/planear-fase.md +263 -263
- package/comandos/swl/plugins.md +256 -256
- package/comandos/swl/predecir.md +169 -169
- package/comandos/swl/reflect-skills.md +125 -125
- package/comandos/swl/release.md +450 -450
- package/comandos/swl/revisar-impacto.md +201 -201
- package/comandos/swl/revisar.md +330 -330
- package/comandos/swl/seguridad.md +189 -189
- package/comandos/swl/sesiones.md +200 -200
- package/comandos/swl/skill-search.md +113 -113
- package/comandos/swl/status.md +345 -345
- package/comandos/swl/verificar.md +817 -817
- package/comandos/swl/wiki.md +620 -620
- package/gateway/cron/jobs.example.json +12 -12
- package/gateway/lib/event-channel.js +191 -191
- package/habilidades/agent-deep-links/SKILL.md +148 -148
- package/habilidades/auto-evolucion-protocolo/SKILL.md +294 -294
- package/habilidades/backend-async-postgres-testing/SKILL.md +216 -215
- package/habilidades/backend-error-design/SKILL.md +221 -221
- package/habilidades/backend-production-resilience/SKILL.md +288 -288
- package/habilidades/calidad-anti-patrones-universales/SKILL.md +105 -1
- package/habilidades/calidad-contract-testing/SKILL.md +165 -165
- package/habilidades/calidad-mutation-testing/SKILL.md +25 -1
- package/habilidades/changelog-generator/SKILL.md +174 -174
- package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -60
- package/habilidades/ci-cd-pipelines/SKILL.md +5 -1
- package/habilidades/compactacion-contexto/SKILL.md +2 -1
- package/habilidades/contenedores-docker/SKILL.md +4 -2
- package/habilidades/css-moderno/SKILL.md +7 -1
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
- package/habilidades/doubt-driven-review/SKILL.md +207 -207
- package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
- package/habilidades/drift-detection/SKILL.md +1 -1
- package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -278
- package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -57
- package/habilidades/extractor-de-aprendizajes/SKILL.md +12 -2
- package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -108
- package/habilidades/git-worktrees-paralelo/SKILL.md +19 -1
- package/habilidades/harness-claude-code/SKILL.md +315 -314
- package/habilidades/instalar-sistema/SKILL.md +227 -227
- package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
- package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
- package/habilidades/perfil-usuario/SKILL.md +200 -200
- package/habilidades/planear-fase/SKILL.md +358 -358
- package/habilidades/prevencion-sobreingenieria/recursos/EXAMPLES.md +580 -580
- package/habilidades/proceso-ddia-streaming/SKILL.md +231 -231
- package/habilidades/proceso-discovery-machote/SKILL.md +157 -157
- package/habilidades/proceso-dynamic-workflows/SKILL.md +60 -0
- package/habilidades/proceso-dynamic-workflows/recursos/template-adversarial-verify.js +65 -65
- package/habilidades/proceso-dynamic-workflows/recursos/template-triage.js +65 -65
- package/habilidades/proceso-ingenieria-requerimientos/SKILL.md +147 -147
- package/habilidades/proceso-intent-engineering/SKILL.md +269 -269
- package/habilidades/proceso-modular-split/SKILL.md +256 -256
- package/habilidades/release-semver/SKILL.md +2 -2
- package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -147
- package/habilidades/swl-claudemd/recursos/contrato-aprender.md +83 -83
- package/habilidades/swl-claudemd/recursos/duplicacion-reglas-globales.md +85 -85
- package/habilidades/swl-claudemd/recursos/plantillas-init.md +94 -94
- package/habilidades/tdd-workflow/SKILL.md +749 -749
- package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -111
- package/hooks/agente-lifecycle.js +1 -1
- package/hooks/audit-trail.js +1 -1
- package/hooks/auto-consolidacion.js +1 -1
- package/hooks/calidad-pre-commit.js +159 -10
- package/hooks/captura-acciones-post.js +1 -1
- package/hooks/captura-acciones-session.js +1 -1
- package/hooks/captura-feedback-usuario.js +1 -1
- package/hooks/ciclo-evolucion-subagente.js +26 -26
- package/hooks/ciclo-evolucion.js +26 -26
- package/hooks/contexto-iteracion.js +1 -1
- package/hooks/degradacion-instintos.js +1 -1
- package/hooks/grafo-contexto.js +1 -1
- package/hooks/guardrail-modelo.js +1 -1
- package/hooks/inbox-aviso.js +1 -1
- package/hooks/inyeccion-contexto.js +1 -1
- package/hooks/lib/agent-matcher.js +1 -1
- package/hooks/lib/agent-routing.js +1 -1
- package/hooks/lib/auto-consolidator.js +335 -335
- package/hooks/lib/captura-acciones.js +1 -1
- package/hooks/lib/ciclo-evolucion.js +47 -47
- package/hooks/lib/deep-links.js +185 -185
- package/hooks/lib/error-classifier.js +308 -308
- package/hooks/lib/etapa-metricas.js +1 -1
- package/hooks/lib/evolution-tracker.js +1 -1
- package/hooks/lib/gateway-notify.js +193 -193
- package/hooks/lib/mcp-health.js +1 -1
- package/hooks/lib/notificacion-formato.js +92 -0
- package/hooks/lib/nudge-tracker.js +1 -1
- package/hooks/lib/otlp-exporter.js +1 -1
- package/hooks/lib/propose-step.js +1 -1
- package/hooks/lib/provenance-tracker.js +191 -191
- package/hooks/lib/raiz-proyecto.js +158 -102
- package/hooks/lib/resource-quota.js +122 -122
- package/hooks/lib/retry-jitter.js +165 -165
- package/hooks/lib/run-log.js +1 -1
- package/hooks/lib/security-net.js +201 -201
- package/hooks/lib/singleton-guard.js +20 -13
- package/hooks/lib/skill-auditor.js +588 -588
- package/hooks/lib/sync-status.js +228 -228
- package/hooks/lib/taint-tracker.js +107 -107
- package/hooks/lib/telegram-cliente.js +11 -3
- package/hooks/lib/text-similarity.js +241 -241
- package/hooks/lib/toon-compressor.js +245 -245
- package/hooks/notificacion-telegram.js +17 -13
- package/hooks/preservar-estado-pre-compact.js +1 -1
- package/hooks/registro-turnos.js +1 -1
- package/hooks/resumen-sesion.js +1 -1
- package/hooks/risk-scoring.js +1 -1
- package/hooks/session-briefing.js +13 -5
- package/hooks/spec-gate.js +1 -1
- package/hooks/sugerir-regenerar-inventario.js +1 -1
- package/hooks/tdd-gate.js +1 -1
- package/hooks/telemetria-agentes.js +1 -1
- package/hooks/telemetria-skill-routing.js +1 -1
- package/hooks/tracking-costos.js +1 -1
- package/hooks/validar-formato-post-subagente.js +1 -1
- package/hooks/validar-intent-spec.js +1 -1
- package/hooks/validar-planning-paths.js +1 -1
- package/instintos/autonomia.yaml +27 -27
- package/instintos/prompt-appendices.yaml +57 -57
- package/llms.txt +29 -29
- package/manifiestos/agent-output-schemas.json +57 -57
- package/manifiestos/canonical-hashes.json +6250 -5257
- package/manifiestos/harness-ir.json +47536 -0
- package/manifiestos/modulos.json +1429 -1428
- package/manifiestos/policy-bundle.json +2065 -0
- package/manifiestos/policy-corpus-w2.json +3926 -0
- package/manifiestos/runtime-adapters-core3.json +208 -0
- package/manifiestos/runtime-conformance.json +139 -0
- package/manifiestos/skills-lock.json +1275 -1275
- package/package.json +94 -94
- package/plantillas/auditor-veto-template.md +105 -105
- package/plantillas/github-workflows/release-please.yml +44 -44
- package/plantillas/github-workflows/swl-ci.yml +107 -107
- package/plantillas/github-workflows/swl-security.yml +51 -51
- package/plugin.json +369 -369
- package/reglas/accesibilidad.md +10 -10
- package/reglas/auditorias-documentales-estructurales.md +7 -7
- package/reglas/cloud-infra.md +8 -8
- package/reglas/consultar-vault-primero.md +195 -195
- package/reglas/git-workflow.md +1 -0
- package/reglas/hooks.md +6 -6
- package/reglas/intent-engineering.md +218 -218
- package/reglas/markitdown.md +8 -8
- package/reglas/monitor-ci.md +12 -0
- package/reglas/patrones.md +6 -6
- package/reglas/testing.md +7 -7
- package/reglas/tests-cleanup.md +224 -224
- package/schemas/agent-message.schema.json +73 -73
- package/schemas/agent-output-implementacion.schema.json +114 -114
- package/schemas/agent-output-planificacion.schema.json +150 -150
- package/schemas/agent-output-review.schema.json +98 -98
- package/schemas/diary-entry.schema.json +112 -112
- package/schemas/gate-state.schema.json +76 -0
- package/schemas/harness-ir.schema.json +369 -0
- package/schemas/hook-profiles.schema.json +54 -54
- package/schemas/hooks-config.schema.json +89 -89
- package/schemas/legacy-gates.schema.json +45 -0
- package/schemas/modulos.schema.json +38 -38
- package/schemas/perfiles.schema.json +36 -36
- package/schemas/plugin.schema.json +77 -77
- package/schemas/policy-bundle.schema.json +140 -0
- package/schemas/policy-enforcement.schema.json +117 -0
- package/schemas/policy-operation.schema.json +261 -0
- package/schemas/runtime-adapter.schema.json +176 -0
- package/schemas/runtime-build-attestation.schema.json +100 -0
- package/schemas/runtime-conformance.schema.json +239 -0
- package/schemas/runtime-diagnostic.schema.json +395 -0
- package/schemas/skill-evals.schema.json +119 -119
- package/schemas/skill-frontmatter.schema.json +245 -245
- package/schemas/w4-certification-request.schema.json +72 -0
- package/schemas/w4-certification-verdict.schema.json +224 -0
- package/schemas/w4-corpus.schema.json +172 -0
- package/schemas/w4-mutation-report.schema.json +116 -0
- package/schemas/w4-replay-result.schema.json +164 -0
- package/schemas/w4-scoring-report.schema.json +89 -0
- package/scripts/audit-tools/audit-history.js +330 -330
- package/scripts/audit-tools/bundle-tracker.js +290 -290
- package/scripts/audit-tools/canary-monitor.js +352 -352
- package/scripts/audit-tools/code-profiler.js +605 -605
- package/scripts/audit-tools/dep-doctor.js +320 -320
- package/scripts/audit-tools/env-validator.js +206 -206
- package/scripts/audit-tools/lib/fs-walk.js +48 -48
- package/scripts/audit-tools/lib/output.js +23 -23
- package/scripts/audit-tools/migration-checker.js +392 -392
- package/scripts/audit-tools/pentest-scanner.js +1436 -1436
- package/scripts/auditar-clases-conocidas.js +134 -134
- package/scripts/bootstrap-instintos.js +88 -14
- package/scripts/canario-hooks.js +166 -166
- package/scripts/cli/aprobar-plan.js +73 -73
- package/scripts/cli/autonomia.js +23 -23
- package/scripts/cli/benchmark-memoria.js +37 -37
- package/scripts/cli/briefing.js +23 -23
- package/scripts/cli/ciclo-autonomo.js +73 -73
- package/scripts/cli/ciclo-evolucion.js +26 -26
- package/scripts/cli/ciclo-fase-b.js +102 -102
- package/scripts/cli/derivar-feature-list.js +25 -25
- package/scripts/cli/detectar-host.js +27 -27
- package/scripts/cli/diary-entry.js +69 -69
- package/scripts/cli/execution-state.js +18 -18
- package/scripts/cli/gateway-notify.js +41 -41
- package/scripts/cli/guardrail-metrics.js +39 -39
- package/scripts/cli/liberar-fase.js +42 -42
- package/scripts/cli/mark-evolved.js +56 -56
- package/scripts/cli/memoria-search.js +69 -69
- package/scripts/cli/metricas-dora.js +26 -26
- package/scripts/cli/near-duplicate.js +55 -55
- package/scripts/cli/notificaciones.js +123 -123
- package/scripts/cli/nudge-accionar.js +39 -39
- package/scripts/cli/propose-step.js +29 -29
- package/scripts/cli/run-eval.js +38 -38
- package/scripts/cli/schedule-parse.js +19 -19
- package/scripts/cli/sugerir-modelo.js +20 -20
- package/scripts/cli/verificar-plan.js +36 -36
- package/scripts/cli/verificar-trazabilidad.js +35 -35
- package/scripts/comandos/install-asistido.js +8 -7
- package/scripts/configurar-branch-protection.js +418 -418
- package/scripts/detectar-aprendizajes-duplicados.js +151 -151
- package/scripts/doctor.js +61 -13
- package/scripts/evidencia-valor.js +101 -101
- package/scripts/field-report.js +16 -16
- package/scripts/generar-checklists-consolidados.js +273 -273
- package/scripts/generar-claims-runtime.js +1342 -0
- package/scripts/generar-harness-ir.js +257 -0
- package/scripts/generar-inventario.js +52 -54
- package/scripts/generar-policy-bundle.js +202 -0
- package/scripts/instalador.js +39 -7
- package/scripts/lib/activar-hooks-proyecto.js +116 -116
- package/scripts/lib/approval-receipts.js +190 -0
- package/scripts/lib/artefactos-python.js +43 -43
- package/scripts/lib/benchmark-metrics.js +160 -160
- package/scripts/lib/budget-enforcer.js +252 -252
- package/scripts/lib/certificacion-loop-state.js +421 -0
- package/scripts/lib/ci-reader.js +193 -193
- package/scripts/lib/ciclo-autonomo/candidatos.js +174 -174
- package/scripts/lib/ciclo-autonomo/config.js +165 -165
- package/scripts/lib/ciclo-autonomo/drenador-feedback.js +174 -174
- package/scripts/lib/ciclo-autonomo/fallback.js +77 -77
- package/scripts/lib/ciclo-autonomo/guard-convivencia.js +139 -139
- package/scripts/lib/ciclo-autonomo/higiene-nudges.js +112 -112
- package/scripts/lib/ciclo-autonomo/index.js +301 -301
- package/scripts/lib/ciclo-autonomo/lock.js +124 -124
- package/scripts/lib/ciclo-autonomo/presupuesto.js +122 -122
- package/scripts/lib/ciclo-autonomo/puente-degradacion.js +240 -240
- package/scripts/lib/ciclo-autonomo/runner-fase-b.js +248 -248
- package/scripts/lib/ciclo-autonomo/writer-instintos.js +190 -190
- package/scripts/lib/ciclo-autonomo/yaml-instintos.js +591 -535
- package/scripts/lib/clasificar-directorio.js +92 -0
- package/scripts/lib/contadores-inventario.js +217 -217
- package/scripts/lib/detectar-host-swl.js +175 -175
- package/scripts/lib/detectar-runtime.js +29 -20
- package/scripts/lib/detectar-stack-detallado.js +307 -307
- package/scripts/lib/detector-autoduplicacion-intra-archivo.js +234 -234
- package/scripts/lib/detector-reglas-duplicadas.js +220 -220
- package/scripts/lib/eval-metrics-store.js +218 -218
- package/scripts/lib/eval-quality.js +171 -171
- package/scripts/lib/eval-schemas.js +144 -144
- package/scripts/lib/eval-self-correct.js +106 -106
- package/scripts/lib/eval-validator.js +185 -185
- package/scripts/lib/evidence-verifier.js +192 -0
- package/scripts/lib/evidencia-release.js +322 -322
- package/scripts/lib/evidencia-valor.js +228 -228
- package/scripts/lib/expandir-targets.js +71 -71
- package/scripts/lib/frontmatter-canonico.js +509 -0
- package/scripts/lib/gate-engine.js +871 -0
- package/scripts/lib/gate-hooks-requires.js +249 -249
- package/scripts/lib/gate-licencias.js +212 -212
- package/scripts/lib/git-config-preflight.js +48 -0
- package/scripts/lib/git-metricas.js +257 -257
- package/scripts/lib/harness-ir.js +778 -0
- package/scripts/lib/harness-source-snapshot.js +309 -0
- package/scripts/lib/integrity-ledger.js +1147 -0
- package/scripts/lib/jaccard-similarity.js +98 -98
- package/scripts/lib/legacy-gate-migration.js +324 -0
- package/scripts/lib/limpiar-basura-global.js +204 -0
- package/scripts/lib/longmemeval-runner.js +125 -125
- package/scripts/lib/metricas-dora.js +204 -204
- package/scripts/lib/notificaciones-telegram.js +1 -0
- package/scripts/lib/npm-version.js +1 -0
- package/scripts/lib/paquetes-conocidos.js +50 -50
- package/scripts/lib/plan-lock.js +61 -13
- package/scripts/lib/policy-broker.js +338 -0
- package/scripts/lib/policy-bundle.js +342 -0
- package/scripts/lib/policy-context-provider.js +310 -0
- package/scripts/lib/policy-contract.js +479 -0
- package/scripts/lib/policy-verifier-utils.js +65 -0
- package/scripts/lib/pr-analyzer.js +399 -399
- package/scripts/lib/principal-verifier.js +178 -0
- package/scripts/lib/prompt-builder.js +264 -264
- package/scripts/lib/resolver-plan-fase.js +37 -37
- package/scripts/lib/rrf-fusion.js +175 -175
- package/scripts/lib/runtime-adapter-contract.js +267 -0
- package/scripts/lib/runtime-artifact-verifier.js +426 -0
- package/scripts/lib/runtime-build-attestation.js +127 -0
- package/scripts/lib/runtime-bundle-installer.js +586 -0
- package/scripts/lib/runtime-compiler.js +327 -0
- package/scripts/lib/runtime-conformance.js +202 -0
- package/scripts/lib/runtime-doctor-core3.js +567 -0
- package/scripts/lib/runtime-doctor-input.js +59 -0
- package/scripts/lib/runtime-operation-adapter.js +267 -0
- package/scripts/lib/schema-version.js +164 -164
- package/scripts/lib/semantic-search.js +252 -252
- package/scripts/lib/signed-envelope.js +545 -0
- package/scripts/lib/single-use-store.js +359 -0
- package/scripts/lib/skills-externas.js +31 -0
- package/scripts/lib/toml-merge.js +204 -204
- package/scripts/lib/transformadores/codex.js +15 -8
- package/scripts/lib/transformadores/gemini.js +79 -5
- package/scripts/lib/w4-attestation-adapter.js +158 -0
- package/scripts/lib/w4-canario.js +337 -0
- package/scripts/lib/w4-claims.js +182 -0
- package/scripts/lib/w4-corpus-generador.js +542 -0
- package/scripts/lib/w4-gate-c5.js +115 -0
- package/scripts/lib/w4-harness-bajo-prueba.js +155 -0
- package/scripts/lib/w4-matriz-combos.js +55 -0
- package/scripts/lib/w4-motor-mutacion.js +1348 -0
- package/scripts/lib/w4-motor-replay.js +735 -0
- package/scripts/lib/w4-pin-origen.js +54 -0
- package/scripts/lib/w4-publicar-request.js +132 -0
- package/scripts/lib/w4-revocacion.js +62 -0
- package/scripts/lib/w4-runtimes-core3.js +38 -0
- package/scripts/lib/w4-scorer-certificacion.js +692 -0
- package/scripts/lib/w4-superficie-candidato.js +49 -0
- package/scripts/lib/w4-veredicto.js +452 -0
- package/scripts/lib/w4-verificar-veredicto.js +302 -0
- package/scripts/limpiar-artefactos-python.js +131 -131
- package/scripts/mcp-server/auth.js +105 -105
- package/scripts/mcp-server/cache.js +106 -106
- package/scripts/migrar-csv-a-array.js +168 -168
- package/scripts/migrar-fase-dominio.js +200 -200
- package/scripts/migrar-gates-legacy.js +108 -0
- package/scripts/publicar-certification-request.js +115 -0
- package/scripts/runtime-doctor.js +107 -0
- package/scripts/tui/componentes/selector-multi.js +189 -189
- package/scripts/tui/componentes/selector-unico.js +158 -158
- package/scripts/tui/ejecutores.js +375 -375
- package/scripts/tui/lib/colores.js +129 -129
- package/scripts/tui/lib/render.js +264 -264
- package/scripts/tui/lib/teclas.js +113 -113
- package/scripts/tui/pantallas/install-wizard.js +408 -403
- package/scripts/tui/pantallas/menu-principal.js +52 -52
- package/scripts/tui/pantallas/progreso.js +274 -274
- package/scripts/tui/pantallas/resumen.js +132 -132
- package/scripts/validar-userland-vacio.js +110 -110
- package/scripts/verificar-aislamiento-swl-eval.js +87 -0
- package/scripts/verificar-empaquetado-downstream.js +375 -0
- package/scripts/verificar-loop-constructor.js +215 -0
- package/scripts/verificar-trazabilidad.js +13 -6
- package/scripts/verificar-veredicto-real.js +84 -0
- package/instintos/.backups/perfil-usuario.yaml.2026-07-10-165128.bak +0 -53
- package/instintos/.backups/proyecto.yaml.2026-07-10-165128.bak +0 -372
|
@@ -1,204 +1,204 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* metricas-dora.js
|
|
5
|
-
*
|
|
6
|
-
* Compone las 4 métricas DORA del proyecto destino y las clasifica en
|
|
7
|
-
* elite/high/medium/low según los umbrales del DORA Report 2023:
|
|
8
|
-
* - deployment frequency + lead time desde git (siempre, git-metricas.js).
|
|
9
|
-
* - change failure rate + MTTR desde gh (degrada si ausente, ci-reader.js).
|
|
10
|
-
*
|
|
11
|
-
* Persiste el informe en `.planning/evolution/metricas-dora.json` (runtime).
|
|
12
|
-
* Entrypoint CLI `--json`. Parte de la Fase 15 (ADR-0039).
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const fs = require('node:fs');
|
|
16
|
-
const path = require('node:path');
|
|
17
|
-
|
|
18
|
-
const gitMetricas = require('./git-metricas');
|
|
19
|
-
const ciReader = require('./ci-reader');
|
|
20
|
-
|
|
21
|
-
let atomicWriteJSON;
|
|
22
|
-
try {
|
|
23
|
-
({ atomicWriteJSON } = require('../../hooks/lib/atomic-write'));
|
|
24
|
-
} catch (err) {
|
|
25
|
-
if (err.code !== 'MODULE_NOT_FOUND') throw err;
|
|
26
|
-
atomicWriteJSON = (p, obj) => {
|
|
27
|
-
const dir = path.dirname(p);
|
|
28
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
29
|
-
fs.writeFileSync(p, JSON.stringify(obj, null, 2), 'utf8');
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const STORAGE_REL = path.join('.planning', 'evolution', 'metricas-dora.json');
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Umbrales DORA Report 2023 (Accelerate State of DevOps). Boundaries expresados
|
|
37
|
-
* en las unidades internas de cada métrica. Ajustar aquí si el reporte cambia.
|
|
38
|
-
*
|
|
39
|
-
* - deploymentFrequency (deploys/semana, mayor es mejor):
|
|
40
|
-
* elite ≥1/día (7/sem) · high ≥1/mes (0.23/sem) · medium ≥1/semestre (0.038/sem) · low <semestral.
|
|
41
|
-
* - leadTimeHoras (commit→tag, menor es mejor): elite <1día · high <1sem · medium <1mes · low ≥1mes.
|
|
42
|
-
* - changeFailureRate (0..1, menor es mejor): elite ≤0.15 · high ≤0.30 · medium ≤0.45 · low >0.45.
|
|
43
|
-
* - mttrHoras (menor es mejor): elite <1h · high <1día · medium <1sem · low ≥1sem.
|
|
44
|
-
*/
|
|
45
|
-
const UMBRALES_DORA_2023 = {
|
|
46
|
-
deploymentFrequency: { elite: 7, high: 0.23, medium: 0.038 }, // deploys/semana, mayor mejor
|
|
47
|
-
leadTimeHoras: { elite: 24, high: 168, medium: 730 }, // menor mejor
|
|
48
|
-
changeFailureRate: { elite: 0.15, high: 0.3, medium: 0.45 }, // menor mejor
|
|
49
|
-
mttrHoras: { elite: 1, high: 24, medium: 168 }, // menor mejor
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const NIVELES = ['elite', 'high', 'medium', 'low'];
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Clasifica un valor de una métrica en elite/high/medium/low.
|
|
56
|
-
* @param {string} metrica - clave de UMBRALES_DORA_2023.
|
|
57
|
-
* @param {number|null|undefined} valor
|
|
58
|
-
* @returns {'elite'|'high'|'medium'|'low'|'sin-datos'}
|
|
59
|
-
*/
|
|
60
|
-
function clasificar(metrica, valor) {
|
|
61
|
-
const u = UMBRALES_DORA_2023[metrica];
|
|
62
|
-
if (!u || valor === null || valor === undefined || !Number.isFinite(valor)) return 'sin-datos';
|
|
63
|
-
|
|
64
|
-
if (metrica === 'deploymentFrequency') {
|
|
65
|
-
// mayor es mejor
|
|
66
|
-
if (valor >= u.elite) return 'elite';
|
|
67
|
-
if (valor >= u.high) return 'high';
|
|
68
|
-
if (valor >= u.medium) return 'medium';
|
|
69
|
-
return 'low';
|
|
70
|
-
}
|
|
71
|
-
// menor es mejor (leadTime, cfr, mttr)
|
|
72
|
-
if (valor < u.elite) return 'elite';
|
|
73
|
-
if (valor < u.high) return 'high';
|
|
74
|
-
if (valor < u.medium) return 'medium';
|
|
75
|
-
return 'low';
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Calcula las 4 métricas DORA del proyecto en baseDir.
|
|
80
|
-
* @returns objeto serializable con generado, ventana_dias y las 4 métricas.
|
|
81
|
-
*/
|
|
82
|
-
function calcularDora(baseDir = process.cwd(), opts = {}) {
|
|
83
|
-
const { ventanaDias = 30, hoy = new Date(), ejecutorGh } = opts;
|
|
84
|
-
|
|
85
|
-
// Git (siempre)
|
|
86
|
-
const df = gitMetricas.deploymentFrequency(baseDir, { ventanaDias, hoy });
|
|
87
|
-
const lt = gitMetricas.leadTimeForChanges(baseDir, { ventanaDias, hoy });
|
|
88
|
-
|
|
89
|
-
// CI (degrada): una sola llamada a gh. Si no está disponible, NO se re-intenta
|
|
90
|
-
// — se propaga la razón directamente (evita 3 invocaciones del mismo fallo).
|
|
91
|
-
const runsBase = ciReader.obtenerRuns({ ejecutorGh, rama: 'main' });
|
|
92
|
-
const cfr = runsBase.disponible
|
|
93
|
-
? ciReader.changeFailureRate({ ventanaDias, hoy, runs: runsBase.runs })
|
|
94
|
-
: { disponible: false, razon: runsBase.razon };
|
|
95
|
-
const mttr = runsBase.disponible
|
|
96
|
-
? ciReader.meanTimeToRestore({ ventanaDias, hoy, runs: runsBase.runs })
|
|
97
|
-
: { disponible: false, razon: runsBase.razon };
|
|
98
|
-
|
|
99
|
-
const deploymentFrequency = df.disponible
|
|
100
|
-
? {
|
|
101
|
-
disponible: true,
|
|
102
|
-
valor: df.sinDatos ? null : df.deploysPorSemana,
|
|
103
|
-
unidad: 'deploys/semana',
|
|
104
|
-
clasificacion: df.sinDatos ? 'sin-datos' : clasificar('deploymentFrequency', df.deploysPorSemana),
|
|
105
|
-
sinDatos: !!df.sinDatos,
|
|
106
|
-
}
|
|
107
|
-
: { disponible: false, razon: df.razon };
|
|
108
|
-
|
|
109
|
-
const leadTime = lt.disponible
|
|
110
|
-
? {
|
|
111
|
-
disponible: true,
|
|
112
|
-
p50Horas: lt.sinDatos ? null : lt.p50Horas,
|
|
113
|
-
p95Horas: lt.sinDatos ? null : lt.p95Horas,
|
|
114
|
-
clasificacion: lt.sinDatos ? 'sin-datos' : clasificar('leadTimeHoras', lt.p50Horas),
|
|
115
|
-
sinDatos: !!lt.sinDatos,
|
|
116
|
-
}
|
|
117
|
-
: { disponible: false, razon: lt.razon };
|
|
118
|
-
|
|
119
|
-
const changeFailureRate = cfr.disponible
|
|
120
|
-
? {
|
|
121
|
-
disponible: true,
|
|
122
|
-
valor: cfr.sinDatos ? null : cfr.cfr,
|
|
123
|
-
clasificacion: cfr.sinDatos ? 'sin-datos' : clasificar('changeFailureRate', cfr.cfr),
|
|
124
|
-
sinDatos: !!cfr.sinDatos,
|
|
125
|
-
totalRuns: cfr.totalRuns,
|
|
126
|
-
fallidos: cfr.fallidos,
|
|
127
|
-
}
|
|
128
|
-
: { disponible: false, razon: cfr.razon };
|
|
129
|
-
|
|
130
|
-
const mttrOut = mttr.disponible
|
|
131
|
-
? {
|
|
132
|
-
disponible: true,
|
|
133
|
-
mttrHoras: mttr.sinDatos ? null : mttr.mttrHoras,
|
|
134
|
-
clasificacion: mttr.sinDatos ? 'sin-datos' : clasificar('mttrHoras', mttr.mttrHoras),
|
|
135
|
-
sinDatos: !!mttr.sinDatos,
|
|
136
|
-
recuperaciones: mttr.recuperaciones,
|
|
137
|
-
}
|
|
138
|
-
: { disponible: false, razon: mttr.razon };
|
|
139
|
-
|
|
140
|
-
return {
|
|
141
|
-
generado: hoy.toISOString(),
|
|
142
|
-
ventana_dias: ventanaDias,
|
|
143
|
-
deploymentFrequency,
|
|
144
|
-
leadTime,
|
|
145
|
-
changeFailureRate,
|
|
146
|
-
mttr: mttrOut,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Persiste el informe DORA en `<baseDir>/.planning/evolution/metricas-dora.json`.
|
|
152
|
-
* `baseDir` se trata como ruta CONFIABLE del invocador (CLI local / cwd); NUNCA
|
|
153
|
-
* debe propagarse desde input web/HTTP/PR. Aun así se valida contención bajo
|
|
154
|
-
* baseDir para evitar write-anywhere si el path subiera de nivel (H-01).
|
|
155
|
-
*/
|
|
156
|
-
function persistir(baseDir, dora) {
|
|
157
|
-
const base = path.resolve(baseDir);
|
|
158
|
-
const destino = path.resolve(base, STORAGE_REL);
|
|
159
|
-
if (destino !== base && !destino.startsWith(base + path.sep)) {
|
|
160
|
-
throw new Error('destino de métricas DORA fuera de baseDir');
|
|
161
|
-
}
|
|
162
|
-
atomicWriteJSON(destino, dora);
|
|
163
|
-
return destino;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
module.exports = {
|
|
167
|
-
clasificar,
|
|
168
|
-
calcularDora,
|
|
169
|
-
persistir,
|
|
170
|
-
UMBRALES_DORA_2023,
|
|
171
|
-
NIVELES,
|
|
172
|
-
STORAGE_REL,
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
// Entrypoint CLI: node scripts/lib/metricas-dora.js [--json] [--dias=N] [baseDir]
|
|
176
|
-
if (!require.main || require.main === module) {
|
|
177
|
-
const args = process.argv.slice(2);
|
|
178
|
-
const json = args.includes('--json');
|
|
179
|
-
const diasArg = args.find((a) => a.startsWith('--dias='));
|
|
180
|
-
const ventanaDias = Math.max(1, Math.min(365, (diasArg ? parseInt(diasArg.slice('--dias='.length), 10) : 30) || 30));
|
|
181
|
-
const baseDir = args.find((a) => !a.startsWith('--')) || process.cwd();
|
|
182
|
-
|
|
183
|
-
const dora = calcularDora(baseDir, { ventanaDias });
|
|
184
|
-
try {
|
|
185
|
-
persistir(baseDir, dora);
|
|
186
|
-
} catch {
|
|
187
|
-
/* persistencia best-effort: no romper el informe si el disco falla */
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if (json) {
|
|
191
|
-
process.stdout.write(JSON.stringify(dora, null, 2) + '\n');
|
|
192
|
-
} else {
|
|
193
|
-
const fmt = (txt) => process.stdout.write(`${txt}\n`);
|
|
194
|
-
const df = dora.deploymentFrequency;
|
|
195
|
-
const lt = dora.leadTime;
|
|
196
|
-
const cfr = dora.changeFailureRate;
|
|
197
|
-
const mt = dora.mttr;
|
|
198
|
-
fmt(`Deployment frequency: ${df.disponible ? (df.sinDatos ? 'sin datos' : `${df.valor.toFixed(2)}/sem [${df.clasificacion}]`) : 'no disponible'}`);
|
|
199
|
-
fmt(`Lead time (p50): ${lt.disponible ? (lt.sinDatos ? 'sin datos' : `${lt.p50Horas.toFixed(1)}h [${lt.clasificacion}]`) : 'no disponible'}`);
|
|
200
|
-
fmt(`Change failure rate: ${cfr.disponible ? (cfr.sinDatos ? 'sin datos' : `${(cfr.valor * 100).toFixed(1)}% [${cfr.clasificacion}]`) : 'no disponible (gh ausente)'}`);
|
|
201
|
-
fmt(`MTTR: ${mt.disponible ? (mt.sinDatos ? 'sin datos' : `${mt.mttrHoras.toFixed(1)}h [${mt.clasificacion}]`) : 'no disponible (gh ausente)'}`);
|
|
202
|
-
}
|
|
203
|
-
process.exit(0);
|
|
204
|
-
}
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* metricas-dora.js
|
|
5
|
+
*
|
|
6
|
+
* Compone las 4 métricas DORA del proyecto destino y las clasifica en
|
|
7
|
+
* elite/high/medium/low según los umbrales del DORA Report 2023:
|
|
8
|
+
* - deployment frequency + lead time desde git (siempre, git-metricas.js).
|
|
9
|
+
* - change failure rate + MTTR desde gh (degrada si ausente, ci-reader.js).
|
|
10
|
+
*
|
|
11
|
+
* Persiste el informe en `.planning/evolution/metricas-dora.json` (runtime).
|
|
12
|
+
* Entrypoint CLI `--json`. Parte de la Fase 15 (ADR-0039).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const fs = require('node:fs');
|
|
16
|
+
const path = require('node:path');
|
|
17
|
+
|
|
18
|
+
const gitMetricas = require('./git-metricas');
|
|
19
|
+
const ciReader = require('./ci-reader');
|
|
20
|
+
|
|
21
|
+
let atomicWriteJSON;
|
|
22
|
+
try {
|
|
23
|
+
({ atomicWriteJSON } = require('../../hooks/lib/atomic-write'));
|
|
24
|
+
} catch (err) {
|
|
25
|
+
if (err.code !== 'MODULE_NOT_FOUND') throw err;
|
|
26
|
+
atomicWriteJSON = (p, obj) => {
|
|
27
|
+
const dir = path.dirname(p);
|
|
28
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
29
|
+
fs.writeFileSync(p, JSON.stringify(obj, null, 2), 'utf8');
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const STORAGE_REL = path.join('.planning', 'evolution', 'metricas-dora.json');
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Umbrales DORA Report 2023 (Accelerate State of DevOps). Boundaries expresados
|
|
37
|
+
* en las unidades internas de cada métrica. Ajustar aquí si el reporte cambia.
|
|
38
|
+
*
|
|
39
|
+
* - deploymentFrequency (deploys/semana, mayor es mejor):
|
|
40
|
+
* elite ≥1/día (7/sem) · high ≥1/mes (0.23/sem) · medium ≥1/semestre (0.038/sem) · low <semestral.
|
|
41
|
+
* - leadTimeHoras (commit→tag, menor es mejor): elite <1día · high <1sem · medium <1mes · low ≥1mes.
|
|
42
|
+
* - changeFailureRate (0..1, menor es mejor): elite ≤0.15 · high ≤0.30 · medium ≤0.45 · low >0.45.
|
|
43
|
+
* - mttrHoras (menor es mejor): elite <1h · high <1día · medium <1sem · low ≥1sem.
|
|
44
|
+
*/
|
|
45
|
+
const UMBRALES_DORA_2023 = {
|
|
46
|
+
deploymentFrequency: { elite: 7, high: 0.23, medium: 0.038 }, // deploys/semana, mayor mejor
|
|
47
|
+
leadTimeHoras: { elite: 24, high: 168, medium: 730 }, // menor mejor
|
|
48
|
+
changeFailureRate: { elite: 0.15, high: 0.3, medium: 0.45 }, // menor mejor
|
|
49
|
+
mttrHoras: { elite: 1, high: 24, medium: 168 }, // menor mejor
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const NIVELES = ['elite', 'high', 'medium', 'low'];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Clasifica un valor de una métrica en elite/high/medium/low.
|
|
56
|
+
* @param {string} metrica - clave de UMBRALES_DORA_2023.
|
|
57
|
+
* @param {number|null|undefined} valor
|
|
58
|
+
* @returns {'elite'|'high'|'medium'|'low'|'sin-datos'}
|
|
59
|
+
*/
|
|
60
|
+
function clasificar(metrica, valor) {
|
|
61
|
+
const u = UMBRALES_DORA_2023[metrica];
|
|
62
|
+
if (!u || valor === null || valor === undefined || !Number.isFinite(valor)) return 'sin-datos';
|
|
63
|
+
|
|
64
|
+
if (metrica === 'deploymentFrequency') {
|
|
65
|
+
// mayor es mejor
|
|
66
|
+
if (valor >= u.elite) return 'elite';
|
|
67
|
+
if (valor >= u.high) return 'high';
|
|
68
|
+
if (valor >= u.medium) return 'medium';
|
|
69
|
+
return 'low';
|
|
70
|
+
}
|
|
71
|
+
// menor es mejor (leadTime, cfr, mttr)
|
|
72
|
+
if (valor < u.elite) return 'elite';
|
|
73
|
+
if (valor < u.high) return 'high';
|
|
74
|
+
if (valor < u.medium) return 'medium';
|
|
75
|
+
return 'low';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Calcula las 4 métricas DORA del proyecto en baseDir.
|
|
80
|
+
* @returns objeto serializable con generado, ventana_dias y las 4 métricas.
|
|
81
|
+
*/
|
|
82
|
+
function calcularDora(baseDir = process.cwd(), opts = {}) {
|
|
83
|
+
const { ventanaDias = 30, hoy = new Date(), ejecutorGh } = opts;
|
|
84
|
+
|
|
85
|
+
// Git (siempre)
|
|
86
|
+
const df = gitMetricas.deploymentFrequency(baseDir, { ventanaDias, hoy });
|
|
87
|
+
const lt = gitMetricas.leadTimeForChanges(baseDir, { ventanaDias, hoy });
|
|
88
|
+
|
|
89
|
+
// CI (degrada): una sola llamada a gh. Si no está disponible, NO se re-intenta
|
|
90
|
+
// — se propaga la razón directamente (evita 3 invocaciones del mismo fallo).
|
|
91
|
+
const runsBase = ciReader.obtenerRuns({ ejecutorGh, rama: 'main' });
|
|
92
|
+
const cfr = runsBase.disponible
|
|
93
|
+
? ciReader.changeFailureRate({ ventanaDias, hoy, runs: runsBase.runs })
|
|
94
|
+
: { disponible: false, razon: runsBase.razon };
|
|
95
|
+
const mttr = runsBase.disponible
|
|
96
|
+
? ciReader.meanTimeToRestore({ ventanaDias, hoy, runs: runsBase.runs })
|
|
97
|
+
: { disponible: false, razon: runsBase.razon };
|
|
98
|
+
|
|
99
|
+
const deploymentFrequency = df.disponible
|
|
100
|
+
? {
|
|
101
|
+
disponible: true,
|
|
102
|
+
valor: df.sinDatos ? null : df.deploysPorSemana,
|
|
103
|
+
unidad: 'deploys/semana',
|
|
104
|
+
clasificacion: df.sinDatos ? 'sin-datos' : clasificar('deploymentFrequency', df.deploysPorSemana),
|
|
105
|
+
sinDatos: !!df.sinDatos,
|
|
106
|
+
}
|
|
107
|
+
: { disponible: false, razon: df.razon };
|
|
108
|
+
|
|
109
|
+
const leadTime = lt.disponible
|
|
110
|
+
? {
|
|
111
|
+
disponible: true,
|
|
112
|
+
p50Horas: lt.sinDatos ? null : lt.p50Horas,
|
|
113
|
+
p95Horas: lt.sinDatos ? null : lt.p95Horas,
|
|
114
|
+
clasificacion: lt.sinDatos ? 'sin-datos' : clasificar('leadTimeHoras', lt.p50Horas),
|
|
115
|
+
sinDatos: !!lt.sinDatos,
|
|
116
|
+
}
|
|
117
|
+
: { disponible: false, razon: lt.razon };
|
|
118
|
+
|
|
119
|
+
const changeFailureRate = cfr.disponible
|
|
120
|
+
? {
|
|
121
|
+
disponible: true,
|
|
122
|
+
valor: cfr.sinDatos ? null : cfr.cfr,
|
|
123
|
+
clasificacion: cfr.sinDatos ? 'sin-datos' : clasificar('changeFailureRate', cfr.cfr),
|
|
124
|
+
sinDatos: !!cfr.sinDatos,
|
|
125
|
+
totalRuns: cfr.totalRuns,
|
|
126
|
+
fallidos: cfr.fallidos,
|
|
127
|
+
}
|
|
128
|
+
: { disponible: false, razon: cfr.razon };
|
|
129
|
+
|
|
130
|
+
const mttrOut = mttr.disponible
|
|
131
|
+
? {
|
|
132
|
+
disponible: true,
|
|
133
|
+
mttrHoras: mttr.sinDatos ? null : mttr.mttrHoras,
|
|
134
|
+
clasificacion: mttr.sinDatos ? 'sin-datos' : clasificar('mttrHoras', mttr.mttrHoras),
|
|
135
|
+
sinDatos: !!mttr.sinDatos,
|
|
136
|
+
recuperaciones: mttr.recuperaciones,
|
|
137
|
+
}
|
|
138
|
+
: { disponible: false, razon: mttr.razon };
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
generado: hoy.toISOString(),
|
|
142
|
+
ventana_dias: ventanaDias,
|
|
143
|
+
deploymentFrequency,
|
|
144
|
+
leadTime,
|
|
145
|
+
changeFailureRate,
|
|
146
|
+
mttr: mttrOut,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Persiste el informe DORA en `<baseDir>/.planning/evolution/metricas-dora.json`.
|
|
152
|
+
* `baseDir` se trata como ruta CONFIABLE del invocador (CLI local / cwd); NUNCA
|
|
153
|
+
* debe propagarse desde input web/HTTP/PR. Aun así se valida contención bajo
|
|
154
|
+
* baseDir para evitar write-anywhere si el path subiera de nivel (H-01).
|
|
155
|
+
*/
|
|
156
|
+
function persistir(baseDir, dora) {
|
|
157
|
+
const base = path.resolve(baseDir);
|
|
158
|
+
const destino = path.resolve(base, STORAGE_REL);
|
|
159
|
+
if (destino !== base && !destino.startsWith(base + path.sep)) {
|
|
160
|
+
throw new Error('destino de métricas DORA fuera de baseDir');
|
|
161
|
+
}
|
|
162
|
+
atomicWriteJSON(destino, dora);
|
|
163
|
+
return destino;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
module.exports = {
|
|
167
|
+
clasificar,
|
|
168
|
+
calcularDora,
|
|
169
|
+
persistir,
|
|
170
|
+
UMBRALES_DORA_2023,
|
|
171
|
+
NIVELES,
|
|
172
|
+
STORAGE_REL,
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
// Entrypoint CLI: node scripts/lib/metricas-dora.js [--json] [--dias=N] [baseDir]
|
|
176
|
+
if (!require.main || require.main === module) {
|
|
177
|
+
const args = process.argv.slice(2);
|
|
178
|
+
const json = args.includes('--json');
|
|
179
|
+
const diasArg = args.find((a) => a.startsWith('--dias='));
|
|
180
|
+
const ventanaDias = Math.max(1, Math.min(365, (diasArg ? parseInt(diasArg.slice('--dias='.length), 10) : 30) || 30));
|
|
181
|
+
const baseDir = args.find((a) => !a.startsWith('--')) || process.cwd();
|
|
182
|
+
|
|
183
|
+
const dora = calcularDora(baseDir, { ventanaDias });
|
|
184
|
+
try {
|
|
185
|
+
persistir(baseDir, dora);
|
|
186
|
+
} catch {
|
|
187
|
+
/* persistencia best-effort: no romper el informe si el disco falla */
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (json) {
|
|
191
|
+
process.stdout.write(JSON.stringify(dora, null, 2) + '\n');
|
|
192
|
+
} else {
|
|
193
|
+
const fmt = (txt) => process.stdout.write(`${txt}\n`);
|
|
194
|
+
const df = dora.deploymentFrequency;
|
|
195
|
+
const lt = dora.leadTime;
|
|
196
|
+
const cfr = dora.changeFailureRate;
|
|
197
|
+
const mt = dora.mttr;
|
|
198
|
+
fmt(`Deployment frequency: ${df.disponible ? (df.sinDatos ? 'sin datos' : `${df.valor.toFixed(2)}/sem [${df.clasificacion}]`) : 'no disponible'}`);
|
|
199
|
+
fmt(`Lead time (p50): ${lt.disponible ? (lt.sinDatos ? 'sin datos' : `${lt.p50Horas.toFixed(1)}h [${lt.clasificacion}]`) : 'no disponible'}`);
|
|
200
|
+
fmt(`Change failure rate: ${cfr.disponible ? (cfr.sinDatos ? 'sin datos' : `${(cfr.valor * 100).toFixed(1)}% [${cfr.clasificacion}]`) : 'no disponible (gh ausente)'}`);
|
|
201
|
+
fmt(`MTTR: ${mt.disponible ? (mt.sinDatos ? 'sin datos' : `${mt.mttrHoras.toFixed(1)}h [${mt.clasificacion}]`) : 'no disponible (gh ausente)'}`);
|
|
202
|
+
}
|
|
203
|
+
process.exit(0);
|
|
204
|
+
}
|
|
@@ -63,6 +63,7 @@ const HOOKS_A_COPIAR = [
|
|
|
63
63
|
'lib/atomic-write.js', // dependencia de auto-restaurar y notificacion
|
|
64
64
|
'lib/telegram-cliente.js',
|
|
65
65
|
'lib/telegram-config.js',
|
|
66
|
+
'lib/notificacion-formato.js', // resumirParaNotificacion — requerido por notificacion-telegram.js (v2.6.2)
|
|
66
67
|
'notificacion-telegram.js',
|
|
67
68
|
'notificacion-telegram-notification.js',
|
|
68
69
|
'notificacion-telegram-subagent.js',
|
|
@@ -1,50 +1,50 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* paquetes-conocidos.js — fuente única de verdad para los nombres de
|
|
5
|
-
* paquete del rebrand swl-ses.
|
|
6
|
-
*
|
|
7
|
-
* Por qué existe:
|
|
8
|
-
* La asimetría intencional de scopes (npmjs `@saulwade/swl-ses` vs
|
|
9
|
-
* GitHub Packages `@saul-wade/swl-ses`) requiere que múltiples scripts
|
|
10
|
-
* reconozcan ambos nombres más el legacy. Tener la lista hardcodeada
|
|
11
|
-
* en cada archivo es violación DRY de conocimiento — un cambio futuro
|
|
12
|
-
* (deprecar el nombre desnudo, agregar otro mirror) requeriría editar
|
|
13
|
-
* varios archivos.
|
|
14
|
-
*
|
|
15
|
-
* Convenciones:
|
|
16
|
-
* - NOMBRE_NPMJS_CANONICO: canónico publicado en registry.npmjs.org.
|
|
17
|
-
* - NOMBRE_GITHUB_MIRROR: mirror publicado en npm.pkg.github.com.
|
|
18
|
-
* - NOMBRES_DETECCION: orden de prioridad para consultas remotas
|
|
19
|
-
* (canónico npmjs primero porque no requiere auth).
|
|
20
|
-
* - NOMBRES_VALIDOS: nombres aceptables para `package.json#name`.
|
|
21
|
-
* NO incluye 'swl-ses' sin scope (deprecated, eliminado en v1.0.0).
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
const NOMBRE_NPMJS_CANONICO = '@saulwade/swl-ses';
|
|
25
|
-
const NOMBRE_GITHUB_MIRROR = '@saul-wade/swl-ses';
|
|
26
|
-
const NOMBRE_LEGACY_DESNUDO = 'swl-ses';
|
|
27
|
-
|
|
28
|
-
const NOMBRES_DETECCION = Object.freeze([
|
|
29
|
-
NOMBRE_NPMJS_CANONICO,
|
|
30
|
-
NOMBRE_GITHUB_MIRROR,
|
|
31
|
-
NOMBRE_LEGACY_DESNUDO,
|
|
32
|
-
]);
|
|
33
|
-
|
|
34
|
-
const NOMBRES_VALIDOS = Object.freeze([
|
|
35
|
-
NOMBRE_NPMJS_CANONICO,
|
|
36
|
-
NOMBRE_GITHUB_MIRROR,
|
|
37
|
-
]);
|
|
38
|
-
|
|
39
|
-
const REGISTRY_NPMJS = 'https://registry.npmjs.org/';
|
|
40
|
-
const REGISTRY_GITHUB = 'https://npm.pkg.github.com';
|
|
41
|
-
|
|
42
|
-
module.exports = {
|
|
43
|
-
NOMBRE_NPMJS_CANONICO,
|
|
44
|
-
NOMBRE_GITHUB_MIRROR,
|
|
45
|
-
NOMBRE_LEGACY_DESNUDO,
|
|
46
|
-
NOMBRES_DETECCION,
|
|
47
|
-
NOMBRES_VALIDOS,
|
|
48
|
-
REGISTRY_NPMJS,
|
|
49
|
-
REGISTRY_GITHUB,
|
|
50
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* paquetes-conocidos.js — fuente única de verdad para los nombres de
|
|
5
|
+
* paquete del rebrand swl-ses.
|
|
6
|
+
*
|
|
7
|
+
* Por qué existe:
|
|
8
|
+
* La asimetría intencional de scopes (npmjs `@saulwade/swl-ses` vs
|
|
9
|
+
* GitHub Packages `@saul-wade/swl-ses`) requiere que múltiples scripts
|
|
10
|
+
* reconozcan ambos nombres más el legacy. Tener la lista hardcodeada
|
|
11
|
+
* en cada archivo es violación DRY de conocimiento — un cambio futuro
|
|
12
|
+
* (deprecar el nombre desnudo, agregar otro mirror) requeriría editar
|
|
13
|
+
* varios archivos.
|
|
14
|
+
*
|
|
15
|
+
* Convenciones:
|
|
16
|
+
* - NOMBRE_NPMJS_CANONICO: canónico publicado en registry.npmjs.org.
|
|
17
|
+
* - NOMBRE_GITHUB_MIRROR: mirror publicado en npm.pkg.github.com.
|
|
18
|
+
* - NOMBRES_DETECCION: orden de prioridad para consultas remotas
|
|
19
|
+
* (canónico npmjs primero porque no requiere auth).
|
|
20
|
+
* - NOMBRES_VALIDOS: nombres aceptables para `package.json#name`.
|
|
21
|
+
* NO incluye 'swl-ses' sin scope (deprecated, eliminado en v1.0.0).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const NOMBRE_NPMJS_CANONICO = '@saulwade/swl-ses';
|
|
25
|
+
const NOMBRE_GITHUB_MIRROR = '@saul-wade/swl-ses';
|
|
26
|
+
const NOMBRE_LEGACY_DESNUDO = 'swl-ses';
|
|
27
|
+
|
|
28
|
+
const NOMBRES_DETECCION = Object.freeze([
|
|
29
|
+
NOMBRE_NPMJS_CANONICO,
|
|
30
|
+
NOMBRE_GITHUB_MIRROR,
|
|
31
|
+
NOMBRE_LEGACY_DESNUDO,
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
const NOMBRES_VALIDOS = Object.freeze([
|
|
35
|
+
NOMBRE_NPMJS_CANONICO,
|
|
36
|
+
NOMBRE_GITHUB_MIRROR,
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
const REGISTRY_NPMJS = 'https://registry.npmjs.org/';
|
|
40
|
+
const REGISTRY_GITHUB = 'https://npm.pkg.github.com';
|
|
41
|
+
|
|
42
|
+
module.exports = {
|
|
43
|
+
NOMBRE_NPMJS_CANONICO,
|
|
44
|
+
NOMBRE_GITHUB_MIRROR,
|
|
45
|
+
NOMBRE_LEGACY_DESNUDO,
|
|
46
|
+
NOMBRES_DETECCION,
|
|
47
|
+
NOMBRES_VALIDOS,
|
|
48
|
+
REGISTRY_NPMJS,
|
|
49
|
+
REGISTRY_GITHUB,
|
|
50
|
+
};
|