@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
package/scripts/instalador.js
CHANGED
|
@@ -16,7 +16,13 @@
|
|
|
16
16
|
const fs = require('fs');
|
|
17
17
|
const path = require('path');
|
|
18
18
|
|
|
19
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
calcularRutas,
|
|
21
|
+
detectarInstalacionesDuales,
|
|
22
|
+
obtenerEtiquetaConformidad,
|
|
23
|
+
obtenerRuntime,
|
|
24
|
+
resumenDeteccion,
|
|
25
|
+
} = require('./lib/detectar-runtime');
|
|
20
26
|
const { preguntarSiNo, ES_TTY } = require('./lib/ui');
|
|
21
27
|
const { resolverPerfil, generarPlan } = require('./lib/manifiestos');
|
|
22
28
|
const { crearEstado, registrarArchivo, registrarComponente, guardarEstado, cargarEstado } = require('./lib/estado');
|
|
@@ -41,6 +47,7 @@ const { canonicalHash } = require('./lib/canonical-hash');
|
|
|
41
47
|
const { auditarEscritura } = require('./lib/audit-evolved');
|
|
42
48
|
const { detectarStack, filtrarReglasPorStack } = require('./lib/detectar-stack');
|
|
43
49
|
const { actualizarGitignore, entradasParaRuntime, limpiarTracked, leerManifest, escribirManifest } = require('./lib/gitignore-manifest');
|
|
50
|
+
const { limpiarBasuraGlobal } = require('./lib/limpiar-basura-global');
|
|
44
51
|
|
|
45
52
|
const RAIZ_PKG = path.resolve(__dirname, '..');
|
|
46
53
|
const VERSION = require('../package.json').version;
|
|
@@ -199,9 +206,11 @@ async function install(opciones) {
|
|
|
199
206
|
process.exit(1);
|
|
200
207
|
}
|
|
201
208
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
209
|
+
const etiquetaConformidad = obtenerEtiquetaConformidad(target);
|
|
210
|
+
console.log(
|
|
211
|
+
`Conformidad: ${runtime.nombre} (${target}) = ${etiquetaConformidad}. ` +
|
|
212
|
+
'La disponibilidad del instalador no equivale a certificación del harness.\n'
|
|
213
|
+
);
|
|
205
214
|
|
|
206
215
|
// 1b. Detectar conflicto dual-scope: instalar en un scope cuando el opuesto
|
|
207
216
|
// ya tiene SWL instalado causa duplicación visible de comandos en la UI.
|
|
@@ -352,6 +361,18 @@ async function install(opciones) {
|
|
|
352
361
|
}
|
|
353
362
|
}
|
|
354
363
|
|
|
364
|
+
// Scope global: purgar directorios basura sembrados en el HOME por versiones
|
|
365
|
+
// previas: ~/.planning/ scaffold (doctor confundía el HOME con un proyecto por
|
|
366
|
+
// ~/_userland) y ~/_userland/ vacío. Conservador: solo el .planning con la
|
|
367
|
+
// huella del scaffold y el _userland sin plugins reales, nunca contenido del
|
|
368
|
+
// usuario. Ver scripts/lib/limpiar-basura-global.js.
|
|
369
|
+
if (esGlobal) {
|
|
370
|
+
const basura = limpiarBasuraGlobal();
|
|
371
|
+
if (basura.eliminados.length > 0) {
|
|
372
|
+
console.log(`\n[global] Basura purgada del HOME: ${basura.eliminados.join(', ')}.`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
355
376
|
// 4. Detectar _userland/
|
|
356
377
|
const userlandAgentes = path.join(process.cwd(), '_userland', 'agentes');
|
|
357
378
|
const userlandHabilidades = path.join(process.cwd(), '_userland', 'habilidades');
|
|
@@ -1132,6 +1153,17 @@ function instalarArchivo(archivo, rutas, runtime, opciones = {}) {
|
|
|
1132
1153
|
return { instalado: false, razon: `Target "${runtime.id}" no soporta "${archivo.tipo}"` };
|
|
1133
1154
|
}
|
|
1134
1155
|
|
|
1156
|
+
// Base de los backups de actualización. En install GLOBAL no se ancla a
|
|
1157
|
+
// process.cwd(): si el usuario corre `install --global` desde su HOME, cwd es
|
|
1158
|
+
// el HOME y los backups aterrizaban en ~/.planning/backups (bug 2026-07-15,
|
|
1159
|
+
// sembraba un ~/.planning espurio). Se co-ubican con el scope global
|
|
1160
|
+
// (~/.claude/.planning/backups) — el restore usa la rutaBackup absoluta
|
|
1161
|
+
// guardada en el estado, así que reubicar la base es seguro. En install de
|
|
1162
|
+
// proyecto, los backups viven en el proyecto (comportamiento correcto).
|
|
1163
|
+
const rutaBackupBase = opciones.esGlobal
|
|
1164
|
+
? path.join(require('os').homedir(), '.claude')
|
|
1165
|
+
: process.cwd();
|
|
1166
|
+
|
|
1135
1167
|
let dirDestino;
|
|
1136
1168
|
|
|
1137
1169
|
switch (archivo.tipo) {
|
|
@@ -1317,7 +1349,7 @@ function instalarArchivo(archivo, rutas, runtime, opciones = {}) {
|
|
|
1317
1349
|
|
|
1318
1350
|
if (strategy.strategy === 'conflict') {
|
|
1319
1351
|
// Población A — evolución del usuario. NUNCA overwrite: backup + merge (diff).
|
|
1320
|
-
const backup = crearBackup(
|
|
1352
|
+
const backup = crearBackup(rutaBackupBase, cmpDestino, versionBackup);
|
|
1321
1353
|
if (!backup.respaldado) {
|
|
1322
1354
|
console.log(` ⚠ Backup falló (${backup.error || 'desconocido'}) para ${nombreArchivo} — merge abortado, original preservado`);
|
|
1323
1355
|
auditEvolved({ archivo: path.relative(process.cwd(), cmpDestino), clasificacion: 'A', accion: 'preserve', hashAntes, evidencia: `backup falló: ${backup.error || 'desconocido'}` });
|
|
@@ -1377,7 +1409,7 @@ function instalarArchivo(archivo, rutas, runtime, opciones = {}) {
|
|
|
1377
1409
|
}
|
|
1378
1410
|
|
|
1379
1411
|
// Componente-archivo (agentes/comandos/reglas): backup del archivo + fall-through.
|
|
1380
|
-
const backup = crearBackup(
|
|
1412
|
+
const backup = crearBackup(rutaBackupBase, cmpDestino, versionBackup);
|
|
1381
1413
|
// H1 (nemesis O5): si el backup falla, NO sobrescribir — preservar original.
|
|
1382
1414
|
if (!backup.respaldado) {
|
|
1383
1415
|
console.log(` ⚠ Backup falló (${backup.error || 'desconocido'}) para ${nombreArchivo} — overwrite abortado, original preservado`);
|
|
@@ -1415,7 +1447,7 @@ function instalarArchivo(archivo, rutas, runtime, opciones = {}) {
|
|
|
1415
1447
|
// Nivel 2: Backup antes de sobreescribir con --force (el caso B shipped-evolved
|
|
1416
1448
|
// ya hizo su propio backup arriba; no duplicar).
|
|
1417
1449
|
if (fs.existsSync(destino) && opciones.force && opciones.versionAnterior && !forzarEscrituraEvolved) {
|
|
1418
|
-
const backup = crearBackup(
|
|
1450
|
+
const backup = crearBackup(rutaBackupBase, destino, opciones.versionAnterior);
|
|
1419
1451
|
if (backup.respaldado) {
|
|
1420
1452
|
if (typeof opciones.onProgress === 'function') {
|
|
1421
1453
|
opciones.onProgress({
|
|
@@ -1,116 +1,116 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* activar-hooks-proyecto.js — Camino "solo hooks" (DT-HOOKS-SOLO-PROYECTO).
|
|
5
|
-
*
|
|
6
|
-
* Registra en el `.claude/settings.json` del PROYECTO los hooks del scope
|
|
7
|
-
* GLOBAL ya instalado, sin copiar ningún componente. Cierra el dilema del
|
|
8
|
-
* install local: los hooks solo funcionan registrados a nivel proyecto
|
|
9
|
-
* (ADR-0009), pero el install local completo duplica agentes/comandos en la
|
|
10
|
-
* UI de Claude Code (lee ambos scopes). Con este camino:
|
|
11
|
-
*
|
|
12
|
-
* - Los comandos del settings apuntan con ruta ABSOLUTA al hooks/ global
|
|
13
|
-
* (esGlobal: true en registrarHooks) → cero archivos copiados.
|
|
14
|
-
* - `swl-ses update` del global refresca los hooks de TODOS los proyectos
|
|
15
|
-
* activados así, gratis (apuntan a los mismos archivos).
|
|
16
|
-
* - Hooks externos (no-SWL) del settings del proyecto se preservan
|
|
17
|
-
* (garantía de registrarHooks).
|
|
18
|
-
*
|
|
19
|
-
* Uso: `swl-ses install --target claude --solo-hooks` (en la raíz del
|
|
20
|
-
* proyecto). Requiere instalación global previa del runtime.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
const fs = require('fs');
|
|
24
|
-
const path = require('path');
|
|
25
|
-
|
|
26
|
-
const RUNTIMES_SOPORTADOS = new Set(['claude', 'openclaude']);
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @param {object} opciones
|
|
30
|
-
* @param {string} [opciones.target='claude'] Runtime (claude|openclaude — formato de settings de Claude Code)
|
|
31
|
-
* @param {string} [opciones.dirProyecto=cwd] Raíz del proyecto destino
|
|
32
|
-
* @param {string} [opciones.hooksDirGlobal] Override del hooks/ global (tests)
|
|
33
|
-
* @param {object} [opciones.deps] Inyección para tests: { registrarHooks, registrarOptimizaciones, cargarHooksConfig, scopesReales, obtenerRuntime }
|
|
34
|
-
* @returns {{ok: boolean, error?: string, settingsPath?: string, hooksDirGlobal?: string, registrados?: number, preservados?: number}}
|
|
35
|
-
*/
|
|
36
|
-
function activarHooksProyecto(opciones = {}) {
|
|
37
|
-
const target = opciones.target || 'claude';
|
|
38
|
-
if (!RUNTIMES_SOPORTADOS.has(target)) {
|
|
39
|
-
return { ok: false, error: `--solo-hooks soporta por ahora targets con settings formato Claude Code (claude, openclaude); recibido: "${target}".` };
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const deps = opciones.deps || {};
|
|
43
|
-
const hs = require('./hooks-settings');
|
|
44
|
-
const registrarHooks = deps.registrarHooks || hs.registrarHooks;
|
|
45
|
-
const registrarOptimizaciones = deps.registrarOptimizaciones || hs.registrarOptimizaciones;
|
|
46
|
-
const cargarHooksConfig = deps.cargarHooksConfig || hs.cargarHooksConfig;
|
|
47
|
-
|
|
48
|
-
// 1. Localizar el hooks/ del scope GLOBAL del runtime.
|
|
49
|
-
let hooksDirGlobal = opciones.hooksDirGlobal;
|
|
50
|
-
if (!hooksDirGlobal) {
|
|
51
|
-
try {
|
|
52
|
-
const dr = require('./detectar-runtime');
|
|
53
|
-
const obtenerRuntime = deps.obtenerRuntime || dr.obtenerRuntime;
|
|
54
|
-
const scopesReales = deps.scopesReales || dr.scopesReales;
|
|
55
|
-
const runtime = obtenerRuntime(target);
|
|
56
|
-
const global = scopesReales(runtime).find(s => s.esGlobal);
|
|
57
|
-
if (!global) return { ok: false, error: `No se pudo resolver el scope global del runtime "${target}".` };
|
|
58
|
-
hooksDirGlobal = path.join(global.dir, 'hooks');
|
|
59
|
-
} catch (err) {
|
|
60
|
-
return { ok: false, error: `No se pudo detectar el runtime "${target}": ${err.message}` };
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (!fs.existsSync(hooksDirGlobal)) {
|
|
64
|
-
return { ok: false, error: `No hay instalación global con hooks en ${hooksDirGlobal}. Instala primero el global: npx -y @saulwade/swl-ses@latest install --target ${target} --global --perfil completo` };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// 2. Hooks disponibles = archivos del global ∩ hooks-config del paquete.
|
|
68
|
-
const hooksConfig = cargarHooksConfig();
|
|
69
|
-
const hookFiles = fs.readdirSync(hooksDirGlobal)
|
|
70
|
-
.filter(f => f.endsWith('.js') && hooksConfig[f]);
|
|
71
|
-
if (hookFiles.length === 0) {
|
|
72
|
-
return { ok: false, error: `El hooks/ global (${hooksDirGlobal}) no contiene hooks reconocidos por hooks-config.json — instalación global corrupta o muy antigua; corre update primero.` };
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 3. Registrar en el settings.json del PROYECTO, apuntando al global.
|
|
76
|
-
const dirProyecto = opciones.dirProyecto || process.cwd();
|
|
77
|
-
const dirClaude = path.join(dirProyecto, '.claude');
|
|
78
|
-
fs.mkdirSync(dirClaude, { recursive: true });
|
|
79
|
-
const settingsPath = path.join(dirClaude, 'settings.json');
|
|
80
|
-
|
|
81
|
-
const r = registrarHooks({
|
|
82
|
-
settingsPath,
|
|
83
|
-
hooksDir: hooksDirGlobal,
|
|
84
|
-
esGlobal: true, // semántica: comandos con ruta ABSOLUTA al hooksDir (que es el global)
|
|
85
|
-
hookFiles,
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
let optimizaciones = 0;
|
|
89
|
-
try {
|
|
90
|
-
const opt = registrarOptimizaciones(settingsPath);
|
|
91
|
-
optimizaciones = (opt && opt.registradas) || 0;
|
|
92
|
-
} catch { /* opcional — no bloquea la activación */ }
|
|
93
|
-
|
|
94
|
-
// 4. Sembrar el .gitignore del proyecto: encender la telemetría hace que
|
|
95
|
-
// los hooks ESCRIBAN (.planning/METRICAS.md, audit*.jsonl, evolution/...)
|
|
96
|
-
// — sin la sección swl-ses esos archivos runtime aparecen como cambios
|
|
97
|
-
// pendientes en el editor del usuario (caso real sistema-verificacion-oic,
|
|
98
|
-
// 2026-07-10: 19 archivos sin trackear tras activar hooks).
|
|
99
|
-
let gitignorePath = null;
|
|
100
|
-
try {
|
|
101
|
-
const { actualizarGitignore } = deps.gitignoreManifest || require('./gitignore-manifest');
|
|
102
|
-
gitignorePath = actualizarGitignore(dirProyecto);
|
|
103
|
-
} catch { /* no bloquea la activación — se reporta null */ }
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
ok: true,
|
|
107
|
-
settingsPath,
|
|
108
|
-
hooksDirGlobal,
|
|
109
|
-
registrados: r.registrados,
|
|
110
|
-
preservados: r.preservados,
|
|
111
|
-
optimizaciones,
|
|
112
|
-
gitignorePath,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
module.exports = { activarHooksProyecto, RUNTIMES_SOPORTADOS };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* activar-hooks-proyecto.js — Camino "solo hooks" (DT-HOOKS-SOLO-PROYECTO).
|
|
5
|
+
*
|
|
6
|
+
* Registra en el `.claude/settings.json` del PROYECTO los hooks del scope
|
|
7
|
+
* GLOBAL ya instalado, sin copiar ningún componente. Cierra el dilema del
|
|
8
|
+
* install local: los hooks solo funcionan registrados a nivel proyecto
|
|
9
|
+
* (ADR-0009), pero el install local completo duplica agentes/comandos en la
|
|
10
|
+
* UI de Claude Code (lee ambos scopes). Con este camino:
|
|
11
|
+
*
|
|
12
|
+
* - Los comandos del settings apuntan con ruta ABSOLUTA al hooks/ global
|
|
13
|
+
* (esGlobal: true en registrarHooks) → cero archivos copiados.
|
|
14
|
+
* - `swl-ses update` del global refresca los hooks de TODOS los proyectos
|
|
15
|
+
* activados así, gratis (apuntan a los mismos archivos).
|
|
16
|
+
* - Hooks externos (no-SWL) del settings del proyecto se preservan
|
|
17
|
+
* (garantía de registrarHooks).
|
|
18
|
+
*
|
|
19
|
+
* Uso: `swl-ses install --target claude --solo-hooks` (en la raíz del
|
|
20
|
+
* proyecto). Requiere instalación global previa del runtime.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const fs = require('fs');
|
|
24
|
+
const path = require('path');
|
|
25
|
+
|
|
26
|
+
const RUNTIMES_SOPORTADOS = new Set(['claude', 'openclaude']);
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @param {object} opciones
|
|
30
|
+
* @param {string} [opciones.target='claude'] Runtime (claude|openclaude — formato de settings de Claude Code)
|
|
31
|
+
* @param {string} [opciones.dirProyecto=cwd] Raíz del proyecto destino
|
|
32
|
+
* @param {string} [opciones.hooksDirGlobal] Override del hooks/ global (tests)
|
|
33
|
+
* @param {object} [opciones.deps] Inyección para tests: { registrarHooks, registrarOptimizaciones, cargarHooksConfig, scopesReales, obtenerRuntime }
|
|
34
|
+
* @returns {{ok: boolean, error?: string, settingsPath?: string, hooksDirGlobal?: string, registrados?: number, preservados?: number}}
|
|
35
|
+
*/
|
|
36
|
+
function activarHooksProyecto(opciones = {}) {
|
|
37
|
+
const target = opciones.target || 'claude';
|
|
38
|
+
if (!RUNTIMES_SOPORTADOS.has(target)) {
|
|
39
|
+
return { ok: false, error: `--solo-hooks soporta por ahora targets con settings formato Claude Code (claude, openclaude); recibido: "${target}".` };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const deps = opciones.deps || {};
|
|
43
|
+
const hs = require('./hooks-settings');
|
|
44
|
+
const registrarHooks = deps.registrarHooks || hs.registrarHooks;
|
|
45
|
+
const registrarOptimizaciones = deps.registrarOptimizaciones || hs.registrarOptimizaciones;
|
|
46
|
+
const cargarHooksConfig = deps.cargarHooksConfig || hs.cargarHooksConfig;
|
|
47
|
+
|
|
48
|
+
// 1. Localizar el hooks/ del scope GLOBAL del runtime.
|
|
49
|
+
let hooksDirGlobal = opciones.hooksDirGlobal;
|
|
50
|
+
if (!hooksDirGlobal) {
|
|
51
|
+
try {
|
|
52
|
+
const dr = require('./detectar-runtime');
|
|
53
|
+
const obtenerRuntime = deps.obtenerRuntime || dr.obtenerRuntime;
|
|
54
|
+
const scopesReales = deps.scopesReales || dr.scopesReales;
|
|
55
|
+
const runtime = obtenerRuntime(target);
|
|
56
|
+
const global = scopesReales(runtime).find(s => s.esGlobal);
|
|
57
|
+
if (!global) return { ok: false, error: `No se pudo resolver el scope global del runtime "${target}".` };
|
|
58
|
+
hooksDirGlobal = path.join(global.dir, 'hooks');
|
|
59
|
+
} catch (err) {
|
|
60
|
+
return { ok: false, error: `No se pudo detectar el runtime "${target}": ${err.message}` };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!fs.existsSync(hooksDirGlobal)) {
|
|
64
|
+
return { ok: false, error: `No hay instalación global con hooks en ${hooksDirGlobal}. Instala primero el global: npx -y @saulwade/swl-ses@latest install --target ${target} --global --perfil completo` };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 2. Hooks disponibles = archivos del global ∩ hooks-config del paquete.
|
|
68
|
+
const hooksConfig = cargarHooksConfig();
|
|
69
|
+
const hookFiles = fs.readdirSync(hooksDirGlobal)
|
|
70
|
+
.filter(f => f.endsWith('.js') && hooksConfig[f]);
|
|
71
|
+
if (hookFiles.length === 0) {
|
|
72
|
+
return { ok: false, error: `El hooks/ global (${hooksDirGlobal}) no contiene hooks reconocidos por hooks-config.json — instalación global corrupta o muy antigua; corre update primero.` };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 3. Registrar en el settings.json del PROYECTO, apuntando al global.
|
|
76
|
+
const dirProyecto = opciones.dirProyecto || process.cwd();
|
|
77
|
+
const dirClaude = path.join(dirProyecto, '.claude');
|
|
78
|
+
fs.mkdirSync(dirClaude, { recursive: true });
|
|
79
|
+
const settingsPath = path.join(dirClaude, 'settings.json');
|
|
80
|
+
|
|
81
|
+
const r = registrarHooks({
|
|
82
|
+
settingsPath,
|
|
83
|
+
hooksDir: hooksDirGlobal,
|
|
84
|
+
esGlobal: true, // semántica: comandos con ruta ABSOLUTA al hooksDir (que es el global)
|
|
85
|
+
hookFiles,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
let optimizaciones = 0;
|
|
89
|
+
try {
|
|
90
|
+
const opt = registrarOptimizaciones(settingsPath);
|
|
91
|
+
optimizaciones = (opt && opt.registradas) || 0;
|
|
92
|
+
} catch { /* opcional — no bloquea la activación */ }
|
|
93
|
+
|
|
94
|
+
// 4. Sembrar el .gitignore del proyecto: encender la telemetría hace que
|
|
95
|
+
// los hooks ESCRIBAN (.planning/METRICAS.md, audit*.jsonl, evolution/...)
|
|
96
|
+
// — sin la sección swl-ses esos archivos runtime aparecen como cambios
|
|
97
|
+
// pendientes en el editor del usuario (caso real sistema-verificacion-oic,
|
|
98
|
+
// 2026-07-10: 19 archivos sin trackear tras activar hooks).
|
|
99
|
+
let gitignorePath = null;
|
|
100
|
+
try {
|
|
101
|
+
const { actualizarGitignore } = deps.gitignoreManifest || require('./gitignore-manifest');
|
|
102
|
+
gitignorePath = actualizarGitignore(dirProyecto);
|
|
103
|
+
} catch { /* no bloquea la activación — se reporta null */ }
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
ok: true,
|
|
107
|
+
settingsPath,
|
|
108
|
+
hooksDirGlobal,
|
|
109
|
+
registrados: r.registrados,
|
|
110
|
+
preservados: r.preservados,
|
|
111
|
+
optimizaciones,
|
|
112
|
+
gitignorePath,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = { activarHooksProyecto, RUNTIMES_SOPORTADOS };
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/** Verifica approvals Ed25519 ligadas a principal, operación, PLAN y FSM. */
|
|
4
|
+
|
|
5
|
+
const crypto = require('node:crypto');
|
|
6
|
+
|
|
7
|
+
const { assertPrincipalCurrent, isVerifiedPrincipal } = require('./principal-verifier');
|
|
8
|
+
const {
|
|
9
|
+
exactKeys, fail, freezeDeep, getContractValidators, plainObject,
|
|
10
|
+
} = require('./policy-verifier-utils');
|
|
11
|
+
const signed = require('./signed-envelope');
|
|
12
|
+
|
|
13
|
+
const APPROVALS = new WeakSet();
|
|
14
|
+
const APPROVAL_META = new WeakMap();
|
|
15
|
+
const SHA256 = /^[a-f0-9]{64}$/u;
|
|
16
|
+
const IDENTIFIER = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
|
|
17
|
+
const CLAIM_KEYS = [
|
|
18
|
+
'kind', 'schemaVersion', 'approvalId', 'principalDigest', 'operationDigest',
|
|
19
|
+
'sessionId', 'runtimeId', 'projectId', 'worktreeDigest', 'capability', 'effectKind',
|
|
20
|
+
'scopeDigest', 'planDigest', 'fsmVersion', 'issuedAt', 'expiresAt', 'nonce',
|
|
21
|
+
];
|
|
22
|
+
const SCOPED_CLAIM_KEYS = [...CLAIM_KEYS, 'phaseId', 'taskId'];
|
|
23
|
+
const EPOCH_CLAIM_KEYS = [...SCOPED_CLAIM_KEYS, 'g1ApprovalDigest'];
|
|
24
|
+
const OPTION_KEYS = [
|
|
25
|
+
'trustContext', 'dependencies', 'principal', 'operation', 'planDigest', 'fsmVersion',
|
|
26
|
+
];
|
|
27
|
+
const SCOPED_OPTION_KEYS = [...OPTION_KEYS, 'phaseId', 'taskId'];
|
|
28
|
+
const EPOCH_OPTION_KEYS = [...SCOPED_OPTION_KEYS, 'g1ApprovalDigest'];
|
|
29
|
+
const TASK = /^T-[0-9]{2}$/u;
|
|
30
|
+
|
|
31
|
+
function validateOptions(options) {
|
|
32
|
+
const contract = getContractValidators();
|
|
33
|
+
plainObject(options, 'APPROVAL_OPTIONS_INVALID', 'opciones approval');
|
|
34
|
+
const isScoped = Object.hasOwn(options, 'phaseId') || Object.hasOwn(options, 'taskId');
|
|
35
|
+
const hasEpoch = Object.hasOwn(options, 'g1ApprovalDigest');
|
|
36
|
+
exactKeys(
|
|
37
|
+
options, hasEpoch ? EPOCH_OPTION_KEYS : (isScoped ? SCOPED_OPTION_KEYS : OPTION_KEYS),
|
|
38
|
+
'APPROVAL_OPTIONS_INVALID', 'opciones approval'
|
|
39
|
+
);
|
|
40
|
+
if (!contract.isKernelDependencies(options.dependencies)) {
|
|
41
|
+
fail('APPROVAL_OPTIONS_INVALID', 'dependencies inválidas');
|
|
42
|
+
}
|
|
43
|
+
if (!isVerifiedPrincipal(options.principal)) {
|
|
44
|
+
fail('APPROVAL_PRINCIPAL_INVALID', 'principal inválido');
|
|
45
|
+
}
|
|
46
|
+
if (!contract.isVerifiedOperation(options.operation)) {
|
|
47
|
+
fail('APPROVAL_OPERATION_INVALID', 'operación inválida');
|
|
48
|
+
}
|
|
49
|
+
if (!SHA256.test(options.planDigest) || !Number.isInteger(options.fsmVersion)
|
|
50
|
+
|| options.fsmVersion < 0) {
|
|
51
|
+
fail('APPROVAL_OPTIONS_INVALID', 'PLAN o FSM inválido');
|
|
52
|
+
}
|
|
53
|
+
if (isScoped && (!IDENTIFIER.test(options.phaseId) || !TASK.test(options.taskId))) {
|
|
54
|
+
fail('APPROVAL_OPTIONS_INVALID', 'alcance de gate inválido');
|
|
55
|
+
}
|
|
56
|
+
if (hasEpoch && !SHA256.test(options.g1ApprovalDigest)) {
|
|
57
|
+
fail('APPROVAL_OPTIONS_INVALID', 'época G1 inválida');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function validateShape(claims) {
|
|
62
|
+
plainObject(claims, 'APPROVAL_INVALID', 'claims approval');
|
|
63
|
+
const isScoped = ['1.1.0', '1.2.0'].includes(claims.schemaVersion);
|
|
64
|
+
const keys = claims.schemaVersion === '1.2.0' ? EPOCH_CLAIM_KEYS
|
|
65
|
+
: (isScoped ? SCOPED_CLAIM_KEYS : CLAIM_KEYS);
|
|
66
|
+
exactKeys(claims, keys,
|
|
67
|
+
'APPROVAL_INVALID', 'claims approval');
|
|
68
|
+
if (claims.kind !== 'authorization-approval'
|
|
69
|
+
|| !['1.0.0', '1.1.0', '1.2.0'].includes(claims.schemaVersion)) {
|
|
70
|
+
fail('APPROVAL_INVALID', 'approval futura o inválida');
|
|
71
|
+
}
|
|
72
|
+
for (const field of ['approvalId', 'sessionId', 'runtimeId', 'projectId', 'nonce']) {
|
|
73
|
+
if (!IDENTIFIER.test(claims[field])) fail('APPROVAL_INVALID', `${field} inválido`);
|
|
74
|
+
}
|
|
75
|
+
for (const field of ['principalDigest', 'operationDigest', 'worktreeDigest',
|
|
76
|
+
'scopeDigest', 'planDigest']) {
|
|
77
|
+
if (!SHA256.test(claims[field])) fail('APPROVAL_INVALID', `${field} inválido`);
|
|
78
|
+
}
|
|
79
|
+
if (!IDENTIFIER.test(claims.capability) || !IDENTIFIER.test(claims.effectKind)
|
|
80
|
+
|| !Number.isInteger(claims.fsmVersion) || claims.fsmVersion < 0) {
|
|
81
|
+
fail('APPROVAL_INVALID', 'capability, effect o FSM inválido');
|
|
82
|
+
}
|
|
83
|
+
if (isScoped && (!IDENTIFIER.test(claims.phaseId) || !TASK.test(claims.taskId))) {
|
|
84
|
+
fail('APPROVAL_INVALID', 'alcance de gate inválido');
|
|
85
|
+
}
|
|
86
|
+
if (claims.schemaVersion === '1.2.0' && !SHA256.test(claims.g1ApprovalDigest)) {
|
|
87
|
+
fail('APPROVAL_INVALID', 'época G1 inválida');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function validateBindings(claims, options) {
|
|
92
|
+
const requestedSchema = Object.hasOwn(options, 'g1ApprovalDigest') ? '1.2.0'
|
|
93
|
+
: (Object.hasOwn(options, 'phaseId') ? '1.1.0' : '1.0.0');
|
|
94
|
+
if (claims.schemaVersion !== requestedSchema) {
|
|
95
|
+
fail('APPROVAL_BINDING_INVALID', 'schema no satisface las garantías solicitadas');
|
|
96
|
+
}
|
|
97
|
+
const expected = {
|
|
98
|
+
principalDigest: options.principal.principalDigest,
|
|
99
|
+
operationDigest: options.operation.operationDigest,
|
|
100
|
+
sessionId: options.principal.sessionId, runtimeId: options.principal.runtimeId,
|
|
101
|
+
projectId: options.principal.projectId, worktreeDigest: options.principal.worktreeDigest,
|
|
102
|
+
capability: options.operation.capability, effectKind: options.operation.effectKind,
|
|
103
|
+
scopeDigest: options.operation.scope.digest, planDigest: options.planDigest,
|
|
104
|
+
fsmVersion: options.fsmVersion,
|
|
105
|
+
};
|
|
106
|
+
if (['1.1.0', '1.2.0'].includes(requestedSchema)) {
|
|
107
|
+
expected.phaseId = options.phaseId;
|
|
108
|
+
expected.taskId = options.taskId;
|
|
109
|
+
}
|
|
110
|
+
if (requestedSchema === '1.2.0') {
|
|
111
|
+
expected.g1ApprovalDigest = options.g1ApprovalDigest;
|
|
112
|
+
}
|
|
113
|
+
if (Object.entries(expected).some(([key, value]) => claims[key] !== value)) {
|
|
114
|
+
fail('APPROVAL_BINDING_INVALID', 'approval ligada a otro contexto');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function validateTime(claims, now) {
|
|
119
|
+
signed.validarTimestampIso(claims.issuedAt, 'approval issuedAt');
|
|
120
|
+
signed.validarTimestampIso(claims.expiresAt, 'approval expiresAt');
|
|
121
|
+
if (claims.issuedAt > now || claims.expiresAt < now || claims.issuedAt >= claims.expiresAt) {
|
|
122
|
+
fail('APPROVAL_EXPIRED', 'approval fuera de vigencia');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function createReceipt(envelope, options) {
|
|
127
|
+
const digestInput = {
|
|
128
|
+
issuer: envelope.issuer, subject: envelope.subject,
|
|
129
|
+
signerPublicKeyDigest: envelope.signerPublicKeyDigest,
|
|
130
|
+
trustEpoch: envelope.trustEpoch, trustDigest: envelope.trustDigest,
|
|
131
|
+
claims: envelope.claims,
|
|
132
|
+
};
|
|
133
|
+
const approvalDigest = crypto.createHash('sha256')
|
|
134
|
+
.update(signed.canonicalizarIJson(digestInput), 'utf8').digest('hex');
|
|
135
|
+
const receipt = freezeDeep({
|
|
136
|
+
kind: 'verified-approval', ...structuredClone(envelope.claims),
|
|
137
|
+
approverId: envelope.subject, issuer: envelope.issuer,
|
|
138
|
+
keyId: envelope.keyId, rootKeyDigest: envelope.rootKeyDigest,
|
|
139
|
+
signerPublicKeyDigest: envelope.signerPublicKeyDigest,
|
|
140
|
+
trustEpoch: envelope.trustEpoch, trustDigest: envelope.trustDigest,
|
|
141
|
+
approvalDigest,
|
|
142
|
+
});
|
|
143
|
+
APPROVALS.add(receipt);
|
|
144
|
+
APPROVAL_META.set(receipt, Object.freeze({
|
|
145
|
+
envelope, principal: options.principal,
|
|
146
|
+
integrityLedger: options.dependencies.integrityLedger,
|
|
147
|
+
}));
|
|
148
|
+
return receipt;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function assertApprovalCurrent(approval, authority) {
|
|
152
|
+
if (!APPROVALS.has(approval)) fail('APPROVAL_INVALID', 'approval no verificada');
|
|
153
|
+
const metadata = APPROVAL_META.get(approval);
|
|
154
|
+
if (!metadata.integrityLedger.isAuthorityReceipt(authority)) {
|
|
155
|
+
fail('APPROVAL_AUTHORITY_INVALID', 'autoridad no verificada');
|
|
156
|
+
}
|
|
157
|
+
assertPrincipalCurrent(metadata.principal, authority);
|
|
158
|
+
signed.revalidarEnvelopeVerificado(metadata.envelope, authority.observedAt);
|
|
159
|
+
validateTime(approval, authority.observedAt);
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function verifyApproval(rawBytes, options) {
|
|
164
|
+
validateOptions(options);
|
|
165
|
+
const authority = options.dependencies.integrityLedger.readAuthority();
|
|
166
|
+
const envelope = signed.verificarEnvelope(rawBytes, {
|
|
167
|
+
trustContext: options.trustContext, expectedType: 'approval',
|
|
168
|
+
requiredScope: `approve:${options.operation.capability}`, now: authority.observedAt,
|
|
169
|
+
});
|
|
170
|
+
if (envelope.trustEpoch !== authority.trustEpoch
|
|
171
|
+
|| envelope.trustDigest !== authority.trustDigest
|
|
172
|
+
|| envelope.rootKeyDigest !== authority.rootKeyDigest) {
|
|
173
|
+
fail('APPROVAL_TRUST_INVALID', 'approval ligada a trust distinto');
|
|
174
|
+
}
|
|
175
|
+
assertPrincipalCurrent(options.principal, authority);
|
|
176
|
+
validateShape(envelope.claims);
|
|
177
|
+
validateBindings(envelope.claims, options);
|
|
178
|
+
validateTime(envelope.claims, authority.observedAt);
|
|
179
|
+
return createReceipt(envelope, options);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function isVerifiedApproval(value) {
|
|
183
|
+
return APPROVALS.has(value);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
module.exports = {
|
|
187
|
+
assertApprovalCurrent,
|
|
188
|
+
isVerifiedApproval,
|
|
189
|
+
verifyApproval,
|
|
190
|
+
};
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* artefactos-python.js — fuente única de verdad para los artefactos
|
|
5
|
-
* Python que NO deben distribuirse en el paquete npm.
|
|
6
|
-
*
|
|
7
|
-
* Por qué existe:
|
|
8
|
-
* Tanto `scripts/limpiar-artefactos-python.js` (prepack) como
|
|
9
|
-
* `scripts/publicar.js` (copiarDir hacia tmpDir del mirror GH)
|
|
10
|
-
* necesitan saber qué directorios y extensiones excluir. Tener la
|
|
11
|
-
* lista hardcodeada en cada archivo es violación DRY de conocimiento
|
|
12
|
-
* — agregar `.pyd` o `.mypy_cache_v2` exigiría editar dos archivos
|
|
13
|
-
* y mantenerlos sincronizados.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const DIRS_ARTEFACTOS_PYTHON = Object.freeze(new Set([
|
|
17
|
-
'__pycache__',
|
|
18
|
-
'.pytest_cache',
|
|
19
|
-
'.mypy_cache',
|
|
20
|
-
'.ruff_cache',
|
|
21
|
-
]));
|
|
22
|
-
|
|
23
|
-
const EXTS_ARTEFACTOS_PYTHON = Object.freeze(new Set([
|
|
24
|
-
'.pyc',
|
|
25
|
-
'.pyo',
|
|
26
|
-
]));
|
|
27
|
-
|
|
28
|
-
function esDirArtefacto(nombre) {
|
|
29
|
-
return DIRS_ARTEFACTOS_PYTHON.has(nombre);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function esArchivoArtefacto(nombre) {
|
|
33
|
-
const dot = nombre.lastIndexOf('.');
|
|
34
|
-
if (dot < 0) return false;
|
|
35
|
-
return EXTS_ARTEFACTOS_PYTHON.has(nombre.slice(dot).toLowerCase());
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
module.exports = {
|
|
39
|
-
DIRS_ARTEFACTOS_PYTHON,
|
|
40
|
-
EXTS_ARTEFACTOS_PYTHON,
|
|
41
|
-
esDirArtefacto,
|
|
42
|
-
esArchivoArtefacto,
|
|
43
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* artefactos-python.js — fuente única de verdad para los artefactos
|
|
5
|
+
* Python que NO deben distribuirse en el paquete npm.
|
|
6
|
+
*
|
|
7
|
+
* Por qué existe:
|
|
8
|
+
* Tanto `scripts/limpiar-artefactos-python.js` (prepack) como
|
|
9
|
+
* `scripts/publicar.js` (copiarDir hacia tmpDir del mirror GH)
|
|
10
|
+
* necesitan saber qué directorios y extensiones excluir. Tener la
|
|
11
|
+
* lista hardcodeada en cada archivo es violación DRY de conocimiento
|
|
12
|
+
* — agregar `.pyd` o `.mypy_cache_v2` exigiría editar dos archivos
|
|
13
|
+
* y mantenerlos sincronizados.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const DIRS_ARTEFACTOS_PYTHON = Object.freeze(new Set([
|
|
17
|
+
'__pycache__',
|
|
18
|
+
'.pytest_cache',
|
|
19
|
+
'.mypy_cache',
|
|
20
|
+
'.ruff_cache',
|
|
21
|
+
]));
|
|
22
|
+
|
|
23
|
+
const EXTS_ARTEFACTOS_PYTHON = Object.freeze(new Set([
|
|
24
|
+
'.pyc',
|
|
25
|
+
'.pyo',
|
|
26
|
+
]));
|
|
27
|
+
|
|
28
|
+
function esDirArtefacto(nombre) {
|
|
29
|
+
return DIRS_ARTEFACTOS_PYTHON.has(nombre);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function esArchivoArtefacto(nombre) {
|
|
33
|
+
const dot = nombre.lastIndexOf('.');
|
|
34
|
+
if (dot < 0) return false;
|
|
35
|
+
return EXTS_ARTEFACTOS_PYTHON.has(nombre.slice(dot).toLowerCase());
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
DIRS_ARTEFACTOS_PYTHON,
|
|
40
|
+
EXTS_ARTEFACTOS_PYTHON,
|
|
41
|
+
esDirArtefacto,
|
|
42
|
+
esArchivoArtefacto,
|
|
43
|
+
};
|