@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.
Files changed (435) hide show
  1. package/CLAUDE.md +209 -197
  2. package/README.md +647 -600
  3. package/agentes/accesibilidad-wcag-swl.md +690 -690
  4. package/agentes/arquitecto-swl.md +267 -267
  5. package/agentes/auto-evolucion-swl.md +932 -932
  6. package/agentes/backend-csharp-swl.md +420 -420
  7. package/agentes/backend-go-swl.md +390 -390
  8. package/agentes/backend-java-swl.md +281 -281
  9. package/agentes/backend-rust-swl.md +364 -364
  10. package/agentes/backend-workers-swl.md +482 -482
  11. package/agentes/cloud-infra-swl.md +509 -509
  12. package/agentes/consolidador-swl.md +541 -541
  13. package/agentes/depurador-swl.md +352 -352
  14. package/agentes/devops-ci-swl.md +400 -400
  15. package/agentes/disenador-ui-swl.md +569 -569
  16. package/agentes/documentador-swl.md +345 -345
  17. package/agentes/frontend-angular-swl.md +621 -621
  18. package/agentes/frontend-css-swl.md +716 -716
  19. package/agentes/frontend-react-swl.md +692 -692
  20. package/agentes/frontend-swl.md +496 -496
  21. package/agentes/frontend-tailwind-swl.md +826 -826
  22. package/agentes/investigador-swl.md +432 -432
  23. package/agentes/investigador-ux-swl.md +505 -505
  24. package/agentes/migrador-swl.md +442 -442
  25. package/agentes/mobile-android-swl.md +511 -511
  26. package/agentes/mobile-cross-swl.md +541 -541
  27. package/agentes/mobile-ios-swl.md +502 -502
  28. package/agentes/mobile-testing-swl.md +302 -302
  29. package/agentes/nemesis-auditor-swl.md +285 -285
  30. package/agentes/observabilidad-swl.md +438 -438
  31. package/agentes/pagos-swl.md +310 -310
  32. package/agentes/perfilador-usuario-swl.md +321 -321
  33. package/agentes/planificador-swl.md +399 -399
  34. package/agentes/producto-prd-swl.md +589 -589
  35. package/agentes/red-team-swl.md +218 -218
  36. package/agentes/release-manager-swl.md +590 -590
  37. package/agentes/rendimiento-swl.md +713 -713
  38. package/agentes/revisor-angular-swl.md +278 -278
  39. package/agentes/revisor-csharp-swl.md +264 -264
  40. package/agentes/revisor-go-swl.md +259 -259
  41. package/agentes/revisor-java-swl.md +257 -257
  42. package/agentes/revisor-kotlin-swl.md +273 -273
  43. package/agentes/revisor-nextjs-swl.md +281 -281
  44. package/agentes/revisor-php-swl.md +271 -271
  45. package/agentes/revisor-react-swl.md +278 -278
  46. package/agentes/revisor-rust-swl.md +346 -346
  47. package/agentes/revisor-seguridad-swl.md +399 -399
  48. package/agentes/revisor-swift-swl.md +268 -268
  49. package/agentes/revisor-typescript-swl.md +346 -346
  50. package/agentes/tdd-qa-swl.md +393 -393
  51. package/bin/swl-ses.js +10 -0
  52. package/comandos/swl/actualizar.md +174 -174
  53. package/comandos/swl/adoptar-proyecto.md +265 -265
  54. package/comandos/swl/aprender.md +836 -836
  55. package/comandos/swl/aprobar-plan.md +146 -146
  56. package/comandos/swl/auditar-deps.md +134 -134
  57. package/comandos/swl/autoresearch.md +264 -264
  58. package/comandos/swl/ayuda.md +224 -224
  59. package/comandos/swl/brainstorm.md +52 -51
  60. package/comandos/swl/checkpoint.md +325 -325
  61. package/comandos/swl/claudemd.md +234 -234
  62. package/comandos/swl/compactar.md +310 -310
  63. package/comandos/swl/configurar-ci.md +235 -235
  64. package/comandos/swl/contexto.md +110 -110
  65. package/comandos/swl/crear-skill.md +292 -292
  66. package/comandos/swl/cron.md +194 -194
  67. package/comandos/swl/deuda-codigo.md +97 -97
  68. package/comandos/swl/discutir-fase.md +169 -169
  69. package/comandos/swl/ejecutar-fase.md +233 -233
  70. package/comandos/swl/evaluar-skill.md +520 -520
  71. package/comandos/swl/evolucion-continua.md +73 -73
  72. package/comandos/swl/evolucionar.md +267 -267
  73. package/comandos/swl/exportar-vault.md +583 -583
  74. package/comandos/swl/fix.md +118 -118
  75. package/comandos/swl/gateway.md +158 -158
  76. package/comandos/swl/inbox.md +116 -116
  77. package/comandos/swl/instalar.md +220 -220
  78. package/comandos/swl/instintos.md +86 -86
  79. package/comandos/swl/mapear-codebase.md +312 -312
  80. package/comandos/swl/mcp-status.md +176 -175
  81. package/comandos/swl/modelo.md +100 -100
  82. package/comandos/swl/nemesis.md +433 -433
  83. package/comandos/swl/notificaciones.md +299 -299
  84. package/comandos/swl/nuevo-proyecto.md +251 -251
  85. package/comandos/swl/planear-fase.md +263 -263
  86. package/comandos/swl/plugins.md +256 -256
  87. package/comandos/swl/predecir.md +169 -169
  88. package/comandos/swl/reflect-skills.md +125 -125
  89. package/comandos/swl/release.md +450 -450
  90. package/comandos/swl/revisar-impacto.md +201 -201
  91. package/comandos/swl/revisar.md +330 -330
  92. package/comandos/swl/seguridad.md +189 -189
  93. package/comandos/swl/sesiones.md +200 -200
  94. package/comandos/swl/skill-search.md +113 -113
  95. package/comandos/swl/status.md +345 -345
  96. package/comandos/swl/verificar.md +817 -817
  97. package/comandos/swl/wiki.md +620 -620
  98. package/gateway/cron/jobs.example.json +12 -12
  99. package/gateway/lib/event-channel.js +191 -191
  100. package/habilidades/agent-deep-links/SKILL.md +148 -148
  101. package/habilidades/auto-evolucion-protocolo/SKILL.md +294 -294
  102. package/habilidades/backend-async-postgres-testing/SKILL.md +216 -215
  103. package/habilidades/backend-error-design/SKILL.md +221 -221
  104. package/habilidades/backend-production-resilience/SKILL.md +288 -288
  105. package/habilidades/calidad-anti-patrones-universales/SKILL.md +105 -1
  106. package/habilidades/calidad-contract-testing/SKILL.md +165 -165
  107. package/habilidades/calidad-mutation-testing/SKILL.md +25 -1
  108. package/habilidades/changelog-generator/SKILL.md +174 -174
  109. package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -60
  110. package/habilidades/ci-cd-pipelines/SKILL.md +5 -1
  111. package/habilidades/compactacion-contexto/SKILL.md +2 -1
  112. package/habilidades/contenedores-docker/SKILL.md +4 -2
  113. package/habilidades/css-moderno/SKILL.md +7 -1
  114. package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
  115. package/habilidades/doubt-driven-review/SKILL.md +207 -207
  116. package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
  117. package/habilidades/drift-detection/SKILL.md +1 -1
  118. package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -278
  119. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -57
  120. package/habilidades/extractor-de-aprendizajes/SKILL.md +12 -2
  121. package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -108
  122. package/habilidades/git-worktrees-paralelo/SKILL.md +19 -1
  123. package/habilidades/harness-claude-code/SKILL.md +315 -314
  124. package/habilidades/instalar-sistema/SKILL.md +227 -227
  125. package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
  126. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
  127. package/habilidades/perfil-usuario/SKILL.md +200 -200
  128. package/habilidades/planear-fase/SKILL.md +358 -358
  129. package/habilidades/prevencion-sobreingenieria/recursos/EXAMPLES.md +580 -580
  130. package/habilidades/proceso-ddia-streaming/SKILL.md +231 -231
  131. package/habilidades/proceso-discovery-machote/SKILL.md +157 -157
  132. package/habilidades/proceso-dynamic-workflows/SKILL.md +60 -0
  133. package/habilidades/proceso-dynamic-workflows/recursos/template-adversarial-verify.js +65 -65
  134. package/habilidades/proceso-dynamic-workflows/recursos/template-triage.js +65 -65
  135. package/habilidades/proceso-ingenieria-requerimientos/SKILL.md +147 -147
  136. package/habilidades/proceso-intent-engineering/SKILL.md +269 -269
  137. package/habilidades/proceso-modular-split/SKILL.md +256 -256
  138. package/habilidades/release-semver/SKILL.md +2 -2
  139. package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -147
  140. package/habilidades/swl-claudemd/recursos/contrato-aprender.md +83 -83
  141. package/habilidades/swl-claudemd/recursos/duplicacion-reglas-globales.md +85 -85
  142. package/habilidades/swl-claudemd/recursos/plantillas-init.md +94 -94
  143. package/habilidades/tdd-workflow/SKILL.md +749 -749
  144. package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -111
  145. package/hooks/agente-lifecycle.js +1 -1
  146. package/hooks/audit-trail.js +1 -1
  147. package/hooks/auto-consolidacion.js +1 -1
  148. package/hooks/calidad-pre-commit.js +159 -10
  149. package/hooks/captura-acciones-post.js +1 -1
  150. package/hooks/captura-acciones-session.js +1 -1
  151. package/hooks/captura-feedback-usuario.js +1 -1
  152. package/hooks/ciclo-evolucion-subagente.js +26 -26
  153. package/hooks/ciclo-evolucion.js +26 -26
  154. package/hooks/contexto-iteracion.js +1 -1
  155. package/hooks/degradacion-instintos.js +1 -1
  156. package/hooks/grafo-contexto.js +1 -1
  157. package/hooks/guardrail-modelo.js +1 -1
  158. package/hooks/inbox-aviso.js +1 -1
  159. package/hooks/inyeccion-contexto.js +1 -1
  160. package/hooks/lib/agent-matcher.js +1 -1
  161. package/hooks/lib/agent-routing.js +1 -1
  162. package/hooks/lib/auto-consolidator.js +335 -335
  163. package/hooks/lib/captura-acciones.js +1 -1
  164. package/hooks/lib/ciclo-evolucion.js +47 -47
  165. package/hooks/lib/deep-links.js +185 -185
  166. package/hooks/lib/error-classifier.js +308 -308
  167. package/hooks/lib/etapa-metricas.js +1 -1
  168. package/hooks/lib/evolution-tracker.js +1 -1
  169. package/hooks/lib/gateway-notify.js +193 -193
  170. package/hooks/lib/mcp-health.js +1 -1
  171. package/hooks/lib/notificacion-formato.js +92 -0
  172. package/hooks/lib/nudge-tracker.js +1 -1
  173. package/hooks/lib/otlp-exporter.js +1 -1
  174. package/hooks/lib/propose-step.js +1 -1
  175. package/hooks/lib/provenance-tracker.js +191 -191
  176. package/hooks/lib/raiz-proyecto.js +158 -102
  177. package/hooks/lib/resource-quota.js +122 -122
  178. package/hooks/lib/retry-jitter.js +165 -165
  179. package/hooks/lib/run-log.js +1 -1
  180. package/hooks/lib/security-net.js +201 -201
  181. package/hooks/lib/singleton-guard.js +20 -13
  182. package/hooks/lib/skill-auditor.js +588 -588
  183. package/hooks/lib/sync-status.js +228 -228
  184. package/hooks/lib/taint-tracker.js +107 -107
  185. package/hooks/lib/telegram-cliente.js +11 -3
  186. package/hooks/lib/text-similarity.js +241 -241
  187. package/hooks/lib/toon-compressor.js +245 -245
  188. package/hooks/notificacion-telegram.js +17 -13
  189. package/hooks/preservar-estado-pre-compact.js +1 -1
  190. package/hooks/registro-turnos.js +1 -1
  191. package/hooks/resumen-sesion.js +1 -1
  192. package/hooks/risk-scoring.js +1 -1
  193. package/hooks/session-briefing.js +13 -5
  194. package/hooks/spec-gate.js +1 -1
  195. package/hooks/sugerir-regenerar-inventario.js +1 -1
  196. package/hooks/tdd-gate.js +1 -1
  197. package/hooks/telemetria-agentes.js +1 -1
  198. package/hooks/telemetria-skill-routing.js +1 -1
  199. package/hooks/tracking-costos.js +1 -1
  200. package/hooks/validar-formato-post-subagente.js +1 -1
  201. package/hooks/validar-intent-spec.js +1 -1
  202. package/hooks/validar-planning-paths.js +1 -1
  203. package/instintos/autonomia.yaml +27 -27
  204. package/instintos/prompt-appendices.yaml +57 -57
  205. package/llms.txt +29 -29
  206. package/manifiestos/agent-output-schemas.json +57 -57
  207. package/manifiestos/canonical-hashes.json +6250 -5257
  208. package/manifiestos/harness-ir.json +47536 -0
  209. package/manifiestos/modulos.json +1429 -1428
  210. package/manifiestos/policy-bundle.json +2065 -0
  211. package/manifiestos/policy-corpus-w2.json +3926 -0
  212. package/manifiestos/runtime-adapters-core3.json +208 -0
  213. package/manifiestos/runtime-conformance.json +139 -0
  214. package/manifiestos/skills-lock.json +1275 -1275
  215. package/package.json +94 -94
  216. package/plantillas/auditor-veto-template.md +105 -105
  217. package/plantillas/github-workflows/release-please.yml +44 -44
  218. package/plantillas/github-workflows/swl-ci.yml +107 -107
  219. package/plantillas/github-workflows/swl-security.yml +51 -51
  220. package/plugin.json +369 -369
  221. package/reglas/accesibilidad.md +10 -10
  222. package/reglas/auditorias-documentales-estructurales.md +7 -7
  223. package/reglas/cloud-infra.md +8 -8
  224. package/reglas/consultar-vault-primero.md +195 -195
  225. package/reglas/git-workflow.md +1 -0
  226. package/reglas/hooks.md +6 -6
  227. package/reglas/intent-engineering.md +218 -218
  228. package/reglas/markitdown.md +8 -8
  229. package/reglas/monitor-ci.md +12 -0
  230. package/reglas/patrones.md +6 -6
  231. package/reglas/testing.md +7 -7
  232. package/reglas/tests-cleanup.md +224 -224
  233. package/schemas/agent-message.schema.json +73 -73
  234. package/schemas/agent-output-implementacion.schema.json +114 -114
  235. package/schemas/agent-output-planificacion.schema.json +150 -150
  236. package/schemas/agent-output-review.schema.json +98 -98
  237. package/schemas/diary-entry.schema.json +112 -112
  238. package/schemas/gate-state.schema.json +76 -0
  239. package/schemas/harness-ir.schema.json +369 -0
  240. package/schemas/hook-profiles.schema.json +54 -54
  241. package/schemas/hooks-config.schema.json +89 -89
  242. package/schemas/legacy-gates.schema.json +45 -0
  243. package/schemas/modulos.schema.json +38 -38
  244. package/schemas/perfiles.schema.json +36 -36
  245. package/schemas/plugin.schema.json +77 -77
  246. package/schemas/policy-bundle.schema.json +140 -0
  247. package/schemas/policy-enforcement.schema.json +117 -0
  248. package/schemas/policy-operation.schema.json +261 -0
  249. package/schemas/runtime-adapter.schema.json +176 -0
  250. package/schemas/runtime-build-attestation.schema.json +100 -0
  251. package/schemas/runtime-conformance.schema.json +239 -0
  252. package/schemas/runtime-diagnostic.schema.json +395 -0
  253. package/schemas/skill-evals.schema.json +119 -119
  254. package/schemas/skill-frontmatter.schema.json +245 -245
  255. package/schemas/w4-certification-request.schema.json +72 -0
  256. package/schemas/w4-certification-verdict.schema.json +224 -0
  257. package/schemas/w4-corpus.schema.json +172 -0
  258. package/schemas/w4-mutation-report.schema.json +116 -0
  259. package/schemas/w4-replay-result.schema.json +164 -0
  260. package/schemas/w4-scoring-report.schema.json +89 -0
  261. package/scripts/audit-tools/audit-history.js +330 -330
  262. package/scripts/audit-tools/bundle-tracker.js +290 -290
  263. package/scripts/audit-tools/canary-monitor.js +352 -352
  264. package/scripts/audit-tools/code-profiler.js +605 -605
  265. package/scripts/audit-tools/dep-doctor.js +320 -320
  266. package/scripts/audit-tools/env-validator.js +206 -206
  267. package/scripts/audit-tools/lib/fs-walk.js +48 -48
  268. package/scripts/audit-tools/lib/output.js +23 -23
  269. package/scripts/audit-tools/migration-checker.js +392 -392
  270. package/scripts/audit-tools/pentest-scanner.js +1436 -1436
  271. package/scripts/auditar-clases-conocidas.js +134 -134
  272. package/scripts/bootstrap-instintos.js +88 -14
  273. package/scripts/canario-hooks.js +166 -166
  274. package/scripts/cli/aprobar-plan.js +73 -73
  275. package/scripts/cli/autonomia.js +23 -23
  276. package/scripts/cli/benchmark-memoria.js +37 -37
  277. package/scripts/cli/briefing.js +23 -23
  278. package/scripts/cli/ciclo-autonomo.js +73 -73
  279. package/scripts/cli/ciclo-evolucion.js +26 -26
  280. package/scripts/cli/ciclo-fase-b.js +102 -102
  281. package/scripts/cli/derivar-feature-list.js +25 -25
  282. package/scripts/cli/detectar-host.js +27 -27
  283. package/scripts/cli/diary-entry.js +69 -69
  284. package/scripts/cli/execution-state.js +18 -18
  285. package/scripts/cli/gateway-notify.js +41 -41
  286. package/scripts/cli/guardrail-metrics.js +39 -39
  287. package/scripts/cli/liberar-fase.js +42 -42
  288. package/scripts/cli/mark-evolved.js +56 -56
  289. package/scripts/cli/memoria-search.js +69 -69
  290. package/scripts/cli/metricas-dora.js +26 -26
  291. package/scripts/cli/near-duplicate.js +55 -55
  292. package/scripts/cli/notificaciones.js +123 -123
  293. package/scripts/cli/nudge-accionar.js +39 -39
  294. package/scripts/cli/propose-step.js +29 -29
  295. package/scripts/cli/run-eval.js +38 -38
  296. package/scripts/cli/schedule-parse.js +19 -19
  297. package/scripts/cli/sugerir-modelo.js +20 -20
  298. package/scripts/cli/verificar-plan.js +36 -36
  299. package/scripts/cli/verificar-trazabilidad.js +35 -35
  300. package/scripts/comandos/install-asistido.js +8 -7
  301. package/scripts/configurar-branch-protection.js +418 -418
  302. package/scripts/detectar-aprendizajes-duplicados.js +151 -151
  303. package/scripts/doctor.js +61 -13
  304. package/scripts/evidencia-valor.js +101 -101
  305. package/scripts/field-report.js +16 -16
  306. package/scripts/generar-checklists-consolidados.js +273 -273
  307. package/scripts/generar-claims-runtime.js +1342 -0
  308. package/scripts/generar-harness-ir.js +257 -0
  309. package/scripts/generar-inventario.js +52 -54
  310. package/scripts/generar-policy-bundle.js +202 -0
  311. package/scripts/instalador.js +39 -7
  312. package/scripts/lib/activar-hooks-proyecto.js +116 -116
  313. package/scripts/lib/approval-receipts.js +190 -0
  314. package/scripts/lib/artefactos-python.js +43 -43
  315. package/scripts/lib/benchmark-metrics.js +160 -160
  316. package/scripts/lib/budget-enforcer.js +252 -252
  317. package/scripts/lib/certificacion-loop-state.js +421 -0
  318. package/scripts/lib/ci-reader.js +193 -193
  319. package/scripts/lib/ciclo-autonomo/candidatos.js +174 -174
  320. package/scripts/lib/ciclo-autonomo/config.js +165 -165
  321. package/scripts/lib/ciclo-autonomo/drenador-feedback.js +174 -174
  322. package/scripts/lib/ciclo-autonomo/fallback.js +77 -77
  323. package/scripts/lib/ciclo-autonomo/guard-convivencia.js +139 -139
  324. package/scripts/lib/ciclo-autonomo/higiene-nudges.js +112 -112
  325. package/scripts/lib/ciclo-autonomo/index.js +301 -301
  326. package/scripts/lib/ciclo-autonomo/lock.js +124 -124
  327. package/scripts/lib/ciclo-autonomo/presupuesto.js +122 -122
  328. package/scripts/lib/ciclo-autonomo/puente-degradacion.js +240 -240
  329. package/scripts/lib/ciclo-autonomo/runner-fase-b.js +248 -248
  330. package/scripts/lib/ciclo-autonomo/writer-instintos.js +190 -190
  331. package/scripts/lib/ciclo-autonomo/yaml-instintos.js +591 -535
  332. package/scripts/lib/clasificar-directorio.js +92 -0
  333. package/scripts/lib/contadores-inventario.js +217 -217
  334. package/scripts/lib/detectar-host-swl.js +175 -175
  335. package/scripts/lib/detectar-runtime.js +29 -20
  336. package/scripts/lib/detectar-stack-detallado.js +307 -307
  337. package/scripts/lib/detector-autoduplicacion-intra-archivo.js +234 -234
  338. package/scripts/lib/detector-reglas-duplicadas.js +220 -220
  339. package/scripts/lib/eval-metrics-store.js +218 -218
  340. package/scripts/lib/eval-quality.js +171 -171
  341. package/scripts/lib/eval-schemas.js +144 -144
  342. package/scripts/lib/eval-self-correct.js +106 -106
  343. package/scripts/lib/eval-validator.js +185 -185
  344. package/scripts/lib/evidence-verifier.js +192 -0
  345. package/scripts/lib/evidencia-release.js +322 -322
  346. package/scripts/lib/evidencia-valor.js +228 -228
  347. package/scripts/lib/expandir-targets.js +71 -71
  348. package/scripts/lib/frontmatter-canonico.js +509 -0
  349. package/scripts/lib/gate-engine.js +871 -0
  350. package/scripts/lib/gate-hooks-requires.js +249 -249
  351. package/scripts/lib/gate-licencias.js +212 -212
  352. package/scripts/lib/git-config-preflight.js +48 -0
  353. package/scripts/lib/git-metricas.js +257 -257
  354. package/scripts/lib/harness-ir.js +778 -0
  355. package/scripts/lib/harness-source-snapshot.js +309 -0
  356. package/scripts/lib/integrity-ledger.js +1147 -0
  357. package/scripts/lib/jaccard-similarity.js +98 -98
  358. package/scripts/lib/legacy-gate-migration.js +324 -0
  359. package/scripts/lib/limpiar-basura-global.js +204 -0
  360. package/scripts/lib/longmemeval-runner.js +125 -125
  361. package/scripts/lib/metricas-dora.js +204 -204
  362. package/scripts/lib/notificaciones-telegram.js +1 -0
  363. package/scripts/lib/npm-version.js +1 -0
  364. package/scripts/lib/paquetes-conocidos.js +50 -50
  365. package/scripts/lib/plan-lock.js +61 -13
  366. package/scripts/lib/policy-broker.js +338 -0
  367. package/scripts/lib/policy-bundle.js +342 -0
  368. package/scripts/lib/policy-context-provider.js +310 -0
  369. package/scripts/lib/policy-contract.js +479 -0
  370. package/scripts/lib/policy-verifier-utils.js +65 -0
  371. package/scripts/lib/pr-analyzer.js +399 -399
  372. package/scripts/lib/principal-verifier.js +178 -0
  373. package/scripts/lib/prompt-builder.js +264 -264
  374. package/scripts/lib/resolver-plan-fase.js +37 -37
  375. package/scripts/lib/rrf-fusion.js +175 -175
  376. package/scripts/lib/runtime-adapter-contract.js +267 -0
  377. package/scripts/lib/runtime-artifact-verifier.js +426 -0
  378. package/scripts/lib/runtime-build-attestation.js +127 -0
  379. package/scripts/lib/runtime-bundle-installer.js +586 -0
  380. package/scripts/lib/runtime-compiler.js +327 -0
  381. package/scripts/lib/runtime-conformance.js +202 -0
  382. package/scripts/lib/runtime-doctor-core3.js +567 -0
  383. package/scripts/lib/runtime-doctor-input.js +59 -0
  384. package/scripts/lib/runtime-operation-adapter.js +267 -0
  385. package/scripts/lib/schema-version.js +164 -164
  386. package/scripts/lib/semantic-search.js +252 -252
  387. package/scripts/lib/signed-envelope.js +545 -0
  388. package/scripts/lib/single-use-store.js +359 -0
  389. package/scripts/lib/skills-externas.js +31 -0
  390. package/scripts/lib/toml-merge.js +204 -204
  391. package/scripts/lib/transformadores/codex.js +15 -8
  392. package/scripts/lib/transformadores/gemini.js +79 -5
  393. package/scripts/lib/w4-attestation-adapter.js +158 -0
  394. package/scripts/lib/w4-canario.js +337 -0
  395. package/scripts/lib/w4-claims.js +182 -0
  396. package/scripts/lib/w4-corpus-generador.js +542 -0
  397. package/scripts/lib/w4-gate-c5.js +115 -0
  398. package/scripts/lib/w4-harness-bajo-prueba.js +155 -0
  399. package/scripts/lib/w4-matriz-combos.js +55 -0
  400. package/scripts/lib/w4-motor-mutacion.js +1348 -0
  401. package/scripts/lib/w4-motor-replay.js +735 -0
  402. package/scripts/lib/w4-pin-origen.js +54 -0
  403. package/scripts/lib/w4-publicar-request.js +132 -0
  404. package/scripts/lib/w4-revocacion.js +62 -0
  405. package/scripts/lib/w4-runtimes-core3.js +38 -0
  406. package/scripts/lib/w4-scorer-certificacion.js +692 -0
  407. package/scripts/lib/w4-superficie-candidato.js +49 -0
  408. package/scripts/lib/w4-veredicto.js +452 -0
  409. package/scripts/lib/w4-verificar-veredicto.js +302 -0
  410. package/scripts/limpiar-artefactos-python.js +131 -131
  411. package/scripts/mcp-server/auth.js +105 -105
  412. package/scripts/mcp-server/cache.js +106 -106
  413. package/scripts/migrar-csv-a-array.js +168 -168
  414. package/scripts/migrar-fase-dominio.js +200 -200
  415. package/scripts/migrar-gates-legacy.js +108 -0
  416. package/scripts/publicar-certification-request.js +115 -0
  417. package/scripts/runtime-doctor.js +107 -0
  418. package/scripts/tui/componentes/selector-multi.js +189 -189
  419. package/scripts/tui/componentes/selector-unico.js +158 -158
  420. package/scripts/tui/ejecutores.js +375 -375
  421. package/scripts/tui/lib/colores.js +129 -129
  422. package/scripts/tui/lib/render.js +264 -264
  423. package/scripts/tui/lib/teclas.js +113 -113
  424. package/scripts/tui/pantallas/install-wizard.js +408 -403
  425. package/scripts/tui/pantallas/menu-principal.js +52 -52
  426. package/scripts/tui/pantallas/progreso.js +274 -274
  427. package/scripts/tui/pantallas/resumen.js +132 -132
  428. package/scripts/validar-userland-vacio.js +110 -110
  429. package/scripts/verificar-aislamiento-swl-eval.js +87 -0
  430. package/scripts/verificar-empaquetado-downstream.js +375 -0
  431. package/scripts/verificar-loop-constructor.js +215 -0
  432. package/scripts/verificar-trazabilidad.js +13 -6
  433. package/scripts/verificar-veredicto-real.js +84 -0
  434. package/instintos/.backups/perfil-usuario.yaml.2026-07-10-165128.bak +0 -53
  435. package/instintos/.backups/proyecto.yaml.2026-07-10-165128.bak +0 -372
@@ -0,0 +1,426 @@
1
+ 'use strict';
2
+
3
+ /** Verificación fail-closed de artefactos y locators runtime C10/W3. */
4
+
5
+ const crypto = require('node:crypto');
6
+ const fs = require('node:fs');
7
+ const path = require('node:path');
8
+ const util = require('node:util');
9
+
10
+ const MAX_ARTIFACTS = 256;
11
+ const MAX_ARTIFACT_BYTES = 16 * 1024 * 1024;
12
+ const MAX_TOTAL_BYTES = 64 * 1024 * 1024;
13
+ const MAX_RELATIVE_PATH = 512;
14
+ const MAX_PATH_SEGMENT = 128;
15
+ const SHA256 = /^[a-f0-9]{64}$/u;
16
+ const SAFE_RELATIVE_PATH = /^[A-Za-z0-9._/-]+$/u;
17
+ const WINDOWS_RESERVED = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/iu;
18
+ const OPEN_FLAGS = fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0);
19
+ const VERIFIED_SETS = new WeakMap();
20
+
21
+ function crearError(code, mensaje) {
22
+ const error = new Error(`${code}: ${mensaje}`);
23
+ error.code = code;
24
+ error.esErrorArtefactoSWL = true;
25
+ return error;
26
+ }
27
+
28
+ function esObjetoPlano(valor) {
29
+ if (valor === null || typeof valor !== 'object' || Array.isArray(valor)
30
+ || util.types.isProxy(valor)) return false;
31
+ const prototipo = Object.getPrototypeOf(valor);
32
+ return prototipo === Object.prototype || prototipo === null;
33
+ }
34
+
35
+ function esMaterialDatos(valor) {
36
+ if (Object.getOwnPropertySymbols(valor).length > 0) return false;
37
+ return Object.values(Object.getOwnPropertyDescriptors(valor))
38
+ .every((descriptor) => descriptor.enumerable && 'value' in descriptor);
39
+ }
40
+
41
+ function esArrayDatos(valor) {
42
+ if (!Array.isArray(valor) || util.types.isProxy(valor)
43
+ || Object.getOwnPropertySymbols(valor).length > 0) return false;
44
+ const descriptores = Object.getOwnPropertyDescriptors(valor);
45
+ const indices = Object.entries(descriptores).filter(([clave]) => clave !== 'length');
46
+ return indices.length === valor.length && indices.every(([clave, descriptor]) => (
47
+ /^(?:0|[1-9]\d*)$/u.test(clave) && descriptor.enumerable && 'value' in descriptor
48
+ ));
49
+ }
50
+
51
+ function assertShape(valor, campos, nombre) {
52
+ if (!esObjetoPlano(valor)) throw crearError('LOCATOR_INVALID', `${nombre} no es objeto plano`);
53
+ if (!esMaterialDatos(valor)) {
54
+ throw crearError('LOCATOR_INVALID', `${nombre} contiene material hostil`);
55
+ }
56
+ const faltante = campos.find((campo) => !Object.hasOwn(valor, campo));
57
+ if (faltante) throw crearError('LOCATOR_INVALID', `${nombre} omite ${faltante}`);
58
+ const extra = Object.keys(valor).find((campo) => !campos.includes(campo));
59
+ if (extra) throw crearError('LOCATOR_INVALID', `${nombre} contiene campo ${extra}`);
60
+ }
61
+
62
+ function rutasIguales(izquierda, derecha) {
63
+ return path.relative(izquierda, derecha) === '';
64
+ }
65
+
66
+ function mismaIdentidad(izquierda, derecha) {
67
+ return izquierda.dev === derecha.dev && izquierda.ino === derecha.ino;
68
+ }
69
+
70
+ function validarDirectorio(stats, code, nombre) {
71
+ if (stats.isSymbolicLink() || !stats.isDirectory()) {
72
+ throw crearError(code, `${nombre} debe ser directorio real`);
73
+ }
74
+ }
75
+
76
+ function cerrarDescriptores(descriptores) {
77
+ const unicos = [...new Set(descriptores.filter(Number.isInteger))];
78
+ const errores = [];
79
+ for (const descriptor of unicos) {
80
+ try { fs.closeSync(descriptor); } catch (error) { errores.push(error); }
81
+ }
82
+ return errores;
83
+ }
84
+
85
+ function cerrarRecursos(descriptores, errorOperacion) {
86
+ const erroresCierre = cerrarDescriptores(descriptores);
87
+ if (erroresCierre.length > 0) {
88
+ const error = crearError('CLOSE_FAILED', 'no se pudieron cerrar todos los descriptores');
89
+ error.cause = errorOperacion || erroresCierre[0];
90
+ throw error;
91
+ }
92
+ if (errorOperacion) throw errorOperacion;
93
+ }
94
+
95
+ function resolverRaiz(bundleRoot) {
96
+ if (typeof bundleRoot !== 'string' || !path.isAbsolute(bundleRoot)) {
97
+ throw crearError('ROOT_INVALID', 'la raíz absoluta es requerida');
98
+ }
99
+ const ruta = path.resolve(bundleRoot);
100
+ try {
101
+ const stats = fs.lstatSync(ruta, { bigint: true });
102
+ validarDirectorio(stats, 'ROOT_INVALID', 'la raíz');
103
+ if (!rutasIguales(ruta, fs.realpathSync(ruta))) {
104
+ throw crearError('ROOT_INVALID', 'la raíz contiene resolución por link');
105
+ }
106
+ return { ruta, stats };
107
+ } catch (error) {
108
+ if (error.code === 'ROOT_INVALID') throw error;
109
+ throw crearError('ROOT_INVALID', 'la raíz no existe o no es accesible');
110
+ }
111
+ }
112
+
113
+ function abrirRaiz(bundleRoot) {
114
+ const { ruta, stats: antes } = resolverRaiz(bundleRoot);
115
+ let descriptor;
116
+ try {
117
+ descriptor = fs.openSync(ruta, OPEN_FLAGS);
118
+ const handle = fs.fstatSync(descriptor, { bigint: true });
119
+ const despues = fs.lstatSync(ruta, { bigint: true });
120
+ validarDirectorio(handle, 'ROOT_CHANGED', 'la raíz abierta');
121
+ validarDirectorio(despues, 'ROOT_CHANGED', 'la raíz actual');
122
+ if (!mismaIdentidad(antes, handle) || !mismaIdentidad(handle, despues)) {
123
+ throw crearError('ROOT_CHANGED', 'la raíz cambió entre lstat y open');
124
+ }
125
+ return { ruta, descriptor, dev: handle.dev, ino: handle.ino, code: 'ROOT_CHANGED' };
126
+ } catch (error) {
127
+ const fallo = error.code === 'ROOT_CHANGED'
128
+ ? error
129
+ : crearError('OPEN_FAILED', 'no se pudo fijar la raíz');
130
+ cerrarRecursos([descriptor], fallo);
131
+ }
132
+ }
133
+
134
+ function validarDirectorioActual(handle) {
135
+ try {
136
+ const abierto = fs.fstatSync(handle.descriptor, { bigint: true });
137
+ const actual = fs.lstatSync(handle.ruta, { bigint: true });
138
+ validarDirectorio(abierto, handle.code, 'directorio abierto');
139
+ validarDirectorio(actual, handle.code, 'directorio actual');
140
+ if (!mismaIdentidad(handle, abierto) || !mismaIdentidad(handle, actual)) {
141
+ throw crearError(handle.code, 'directorio cambió de identidad');
142
+ }
143
+ } catch (error) {
144
+ if (error.code === handle.code) throw error;
145
+ throw crearError(handle.code, 'directorio desapareció o dejó de ser verificable');
146
+ }
147
+ }
148
+
149
+ function validarDirectorios(handles) {
150
+ handles.forEach(validarDirectorioActual);
151
+ }
152
+
153
+ function abrirDirectorio(ruta, padres) {
154
+ let descriptor;
155
+ let antes;
156
+ try {
157
+ antes = fs.lstatSync(ruta, { bigint: true });
158
+ } catch {
159
+ throw crearError('PATH_INVALID', 'ancestro ausente');
160
+ }
161
+ if (antes.isSymbolicLink()) throw crearError('LINK_REJECTED', 'symlink en path');
162
+ if (!antes.isDirectory()) throw crearError('PATH_INVALID', 'ancestro no es directorio');
163
+ try {
164
+ validarDirectorios(padres);
165
+ descriptor = fs.openSync(ruta, OPEN_FLAGS);
166
+ const abierto = fs.fstatSync(descriptor, { bigint: true });
167
+ const despues = fs.lstatSync(ruta, { bigint: true });
168
+ validarDirectorio(abierto, 'DIRECTORY_CHANGED', 'ancestro abierto');
169
+ validarDirectorio(despues, 'DIRECTORY_CHANGED', 'ancestro actual');
170
+ if (!mismaIdentidad(antes, abierto) || !mismaIdentidad(abierto, despues)) {
171
+ throw crearError('DIRECTORY_CHANGED', 'ancestro cambió entre lstat y open');
172
+ }
173
+ return { ruta, descriptor, dev: abierto.dev, ino: abierto.ino, code: 'DIRECTORY_CHANGED' };
174
+ } catch (error) {
175
+ const fallo = error.code === 'DIRECTORY_CHANGED'
176
+ ? error
177
+ : crearError('OPEN_FAILED', 'no se pudo fijar un ancestro');
178
+ cerrarRecursos([descriptor], fallo);
179
+ }
180
+ }
181
+
182
+ function validarSegmentoPortable(segmento) {
183
+ if (segmento.length > MAX_PATH_SEGMENT || /[. ]$/u.test(segmento)) {
184
+ throw crearError('PATH_INVALID', 'segmento excede longitud o termina en punto/espacio');
185
+ }
186
+ if (WINDOWS_RESERVED.test(segmento)) {
187
+ throw crearError('PATH_INVALID', 'nombre reservado no portable');
188
+ }
189
+ }
190
+
191
+ function validarPathRelativo(relativo) {
192
+ if (typeof relativo !== 'string' || relativo.length > MAX_RELATIVE_PATH
193
+ || !SAFE_RELATIVE_PATH.test(relativo)) {
194
+ throw crearError('PATH_INVALID', 'path relativo no canónico o excede longitud');
195
+ }
196
+ const partes = relativo.split('/');
197
+ if (path.posix.isAbsolute(relativo) || relativo.includes(':') || relativo.includes('\\')
198
+ || partes.some((parte) => parte === '' || parte === '.' || parte === '..')) {
199
+ throw crearError('PATH_INVALID', 'path absoluto, traversal, ADS o segmento inválido');
200
+ }
201
+ partes.forEach(validarSegmentoPortable);
202
+ return partes;
203
+ }
204
+
205
+ function validarListaRutas(rutas) {
206
+ if (!esArrayDatos(rutas) || rutas.length === 0) {
207
+ throw crearError('PATH_INVALID', 'la lista de paths debe ser datos no vacíos');
208
+ }
209
+ if (rutas.length > MAX_ARTIFACTS) throw crearError('LIMIT_EXCEEDED', 'cantidad de artefactos');
210
+ rutas.forEach(validarPathRelativo);
211
+ const ordenadas = [...rutas].sort();
212
+ const caseFold = rutas.map((ruta) => ruta.toLowerCase());
213
+ if (new Set(rutas).size !== rutas.length || new Set(caseFold).size !== rutas.length
214
+ || JSON.stringify(rutas) !== JSON.stringify(ordenadas)) {
215
+ throw crearError('PATH_INVALID', 'paths duplicados, con colisión case-fold o fuera de orden');
216
+ }
217
+ }
218
+
219
+ function abrirAncestros(raiz, partes) {
220
+ const handles = [raiz];
221
+ let actual = raiz.ruta;
222
+ try {
223
+ for (const parte of partes.slice(0, -1)) {
224
+ actual = path.join(actual, parte);
225
+ handles.push(abrirDirectorio(actual, handles));
226
+ }
227
+ return handles;
228
+ } catch (error) {
229
+ const abiertos = handles.slice(1).reverse().map(({ descriptor }) => descriptor);
230
+ cerrarRecursos(abiertos, error);
231
+ }
232
+ }
233
+
234
+ function identidadArchivo(stats) {
235
+ return [stats.dev, stats.ino, stats.size, stats.mtimeNs, stats.ctimeNs]
236
+ .map((valor) => String(valor)).join(':');
237
+ }
238
+
239
+ function validarStatsArchivo(stats) {
240
+ if (!stats.isFile()) throw crearError('TYPE_REJECTED', 'artefacto no es archivo regular');
241
+ if (stats.nlink !== 1n) throw crearError('LINK_REJECTED', 'hardlink detectado');
242
+ if (stats.size > BigInt(MAX_ARTIFACT_BYTES)) {
243
+ throw crearError('LIMIT_EXCEEDED', 'artefacto demasiado grande');
244
+ }
245
+ }
246
+
247
+ function leerBytes(descriptor, longitud) {
248
+ const bytes = Buffer.alloc(longitud);
249
+ let offset = 0;
250
+ while (offset < longitud) {
251
+ const leidos = fs.readSync(descriptor, bytes, offset, longitud - offset, offset);
252
+ if (leidos === 0) throw crearError('ARTIFACT_CHANGED', 'EOF antes del tamaño verificado');
253
+ offset += leidos;
254
+ }
255
+ return bytes;
256
+ }
257
+
258
+ function estaConfinado(raiz, destino) {
259
+ const relativo = path.relative(raiz, destino);
260
+ const primerSegmento = relativo.split(path.sep)[0];
261
+ return relativo !== '' && primerSegmento !== '..' && !path.isAbsolute(relativo);
262
+ }
263
+
264
+ function validarPathFinal(raiz, destino, statsHandle) {
265
+ try {
266
+ const real = fs.realpathSync(destino);
267
+ const statsPath = fs.lstatSync(destino, { bigint: true });
268
+ if (!estaConfinado(raiz, real) || statsPath.isSymbolicLink()) {
269
+ throw crearError('PATH_ESCAPE', 'path final fuera de la raíz o symlink');
270
+ }
271
+ if (!mismaIdentidad(statsPath, statsHandle)) {
272
+ throw crearError('ARTIFACT_CHANGED', 'path cambió de identidad durante lectura');
273
+ }
274
+ } catch (error) {
275
+ if (['PATH_ESCAPE', 'ARTIFACT_CHANGED'].includes(error.code)) throw error;
276
+ throw crearError('ARTIFACT_CHANGED', 'path desapareció durante lectura');
277
+ }
278
+ }
279
+
280
+ function abrirArchivo(ruta) {
281
+ try {
282
+ return fs.openSync(ruta, OPEN_FLAGS);
283
+ } catch {
284
+ throw crearError('OPEN_FAILED', 'no se pudo abrir el artefacto');
285
+ }
286
+ }
287
+
288
+ function leerArchivoEstable(raiz, relativo) {
289
+ const partes = validarPathRelativo(relativo);
290
+ const handles = abrirAncestros(raiz, partes);
291
+ const destino = path.join(raiz.ruta, ...partes);
292
+ let descriptor;
293
+ let bytes;
294
+ let errorOperacion;
295
+ try {
296
+ validarDirectorios(handles);
297
+ descriptor = abrirArchivo(destino);
298
+ const antes = fs.fstatSync(descriptor, { bigint: true });
299
+ validarStatsArchivo(antes);
300
+ validarDirectorios(handles);
301
+ bytes = leerBytes(descriptor, Number(antes.size));
302
+ const despues = fs.fstatSync(descriptor, { bigint: true });
303
+ validarDirectorios(handles);
304
+ if (identidadArchivo(antes) !== identidadArchivo(despues)
305
+ || antes.nlink !== despues.nlink) {
306
+ throw crearError('ARTIFACT_CHANGED', 'archivo cambió durante lectura');
307
+ }
308
+ validarStatsArchivo(despues);
309
+ validarPathFinal(raiz.ruta, destino, despues);
310
+ validarDirectorios(handles);
311
+ } catch (error) {
312
+ errorOperacion = error.esErrorArtefactoSWL
313
+ ? error
314
+ : crearError('OPEN_FAILED', 'falló la lectura por descriptor');
315
+ }
316
+ const ancestros = handles.slice(1).reverse().map((handle) => handle.descriptor);
317
+ cerrarRecursos([descriptor, ...ancestros], errorOperacion);
318
+ return bytes;
319
+ }
320
+
321
+ function metadataDe(ruta, bytes) {
322
+ return Object.freeze({
323
+ path: ruta,
324
+ bytes: bytes.length,
325
+ sha256: crypto.createHash('sha256').update(bytes).digest('hex'),
326
+ });
327
+ }
328
+
329
+ function registrarConjunto(entradas) {
330
+ const metadata = Object.freeze(entradas.map(({ path: ruta, bytes }) => metadataDe(ruta, bytes)));
331
+ const token = Object.freeze({ kind: 'verified-runtime-artifacts', entries: metadata });
332
+ const bytesPorRuta = entradas.map(({ path: ruta, bytes }) => [ruta, Buffer.from(bytes)]);
333
+ VERIFIED_SETS.set(token, new Map(bytesPorRuta));
334
+ return token;
335
+ }
336
+
337
+ function cargarArtefactosVerificados(bundleRoot, rutas) {
338
+ validarListaRutas(rutas);
339
+ const raiz = abrirRaiz(bundleRoot);
340
+ let total = 0;
341
+ let conjunto;
342
+ let errorOperacion;
343
+ try {
344
+ const entradas = rutas.map((ruta) => {
345
+ const bytes = leerArchivoEstable(raiz, ruta);
346
+ total += bytes.length;
347
+ if (total > MAX_TOTAL_BYTES) throw crearError('LIMIT_EXCEEDED', 'tamaño total excedido');
348
+ return { path: ruta, bytes };
349
+ });
350
+ validarDirectorioActual(raiz);
351
+ conjunto = registrarConjunto(entradas);
352
+ } catch (error) {
353
+ errorOperacion = error;
354
+ }
355
+ cerrarRecursos([raiz.descriptor], errorOperacion);
356
+ return conjunto;
357
+ }
358
+
359
+ function exigirConjunto(conjunto) {
360
+ const interno = VERIFIED_SETS.get(conjunto);
361
+ if (!interno) throw crearError('UNVERIFIED_SET', 'se requiere conjunto verificado');
362
+ return interno;
363
+ }
364
+
365
+ function esConjuntoArtefactosVerificado(valor) {
366
+ return VERIFIED_SETS.has(valor);
367
+ }
368
+
369
+ function crearLocator(conjunto) {
370
+ exigirConjunto(conjunto);
371
+ const entries = Object.freeze(conjunto.entries.map((entry) => Object.freeze({ ...entry })));
372
+ return Object.freeze({ schemaVersion: '1.0.0', kind: 'swl-runtime-locator', entries });
373
+ }
374
+
375
+ function validarEntradaLocator(entry, indice) {
376
+ assertShape(entry, ['path', 'bytes', 'sha256'], `locator entry ${indice}`);
377
+ validarPathRelativo(entry.path);
378
+ if (!Number.isSafeInteger(entry.bytes) || entry.bytes < 0 || entry.bytes > MAX_ARTIFACT_BYTES) {
379
+ throw crearError('LOCATOR_INVALID', 'bytes de locator inválidos');
380
+ }
381
+ if (typeof entry.sha256 !== 'string' || !SHA256.test(entry.sha256)) {
382
+ throw crearError('LOCATOR_INVALID', 'digest de locator inválido');
383
+ }
384
+ }
385
+
386
+ function validarLocator(locator) {
387
+ assertShape(locator, ['schemaVersion', 'kind', 'entries'], 'locator');
388
+ if (locator.schemaVersion !== '1.0.0' || locator.kind !== 'swl-runtime-locator') {
389
+ throw crearError('LOCATOR_INVALID', 'versión o kind de locator inválido');
390
+ }
391
+ if (!esArrayDatos(locator.entries) || locator.entries.length === 0) {
392
+ throw crearError('LOCATOR_INVALID', 'locator sin entradas de datos');
393
+ }
394
+ if (locator.entries.length > MAX_ARTIFACTS) {
395
+ throw crearError('LIMIT_EXCEEDED', 'cantidad de entradas del locator');
396
+ }
397
+ locator.entries.forEach(validarEntradaLocator);
398
+ validarListaRutas(locator.entries.map(({ path: ruta }) => ruta));
399
+ }
400
+
401
+ function verificarLocator(bundleRoot, locator) {
402
+ validarLocator(locator);
403
+ const conjunto = cargarArtefactosVerificados(
404
+ bundleRoot, locator.entries.map(({ path: ruta }) => ruta)
405
+ );
406
+ if (JSON.stringify(conjunto.entries) !== JSON.stringify(locator.entries)) {
407
+ throw crearError('ARTIFACT_MISMATCH', 'bytes o digest no coinciden con locator');
408
+ }
409
+ return conjunto;
410
+ }
411
+
412
+ function leerArtefactoVerificado(conjunto, relativo) {
413
+ const interno = exigirConjunto(conjunto);
414
+ const bytes = interno.get(relativo);
415
+ if (!bytes) throw crearError('PATH_INVALID', 'artefacto no pertenece al conjunto');
416
+ return Buffer.from(bytes);
417
+ }
418
+
419
+ module.exports = {
420
+ cargarArtefactosVerificados,
421
+ crearLocator,
422
+ esConjuntoArtefactosVerificado,
423
+ leerArtefactoVerificado,
424
+ validarListaRutasPortables: validarListaRutas,
425
+ verificarLocator,
426
+ };
@@ -0,0 +1,127 @@
1
+ 'use strict';
2
+
3
+ /** Registra una construcción Core-3 sin producir autoridad conductual. */
4
+
5
+ const util = require('node:util');
6
+
7
+ const { isKernelDependencies } = require('./policy-contract');
8
+ const { validarListaRutasPortables } = require('./runtime-artifact-verifier');
9
+ const { parsearIJson, validarTimestampIso } = require('./signed-envelope');
10
+
11
+ const MAX_RAW_BYTES = 256 * 1024;
12
+ const SHA256 = /^[a-f0-9]{64}$/u;
13
+ const PAYLOAD_KEYS = Object.freeze([
14
+ 'schemaVersion', 'kind', 'purpose', 'runtimeId', 'installerTarget', 'adapterId',
15
+ 'adapterSchemaVersion', 'contractVersion', 'manifestDigest', 'locatorDigest',
16
+ 'outputs', 'builtAt', 'effectiveMode',
17
+ ]);
18
+ const RUNTIMES = Object.freeze({
19
+ 'claude-code': 'claude',
20
+ 'codex-cli': 'codex',
21
+ 'gemini-cli': 'gemini',
22
+ });
23
+
24
+ function fail(codigo, mensaje) {
25
+ const error = new TypeError(mensaje);
26
+ error.codigo = codigo;
27
+ throw error;
28
+ }
29
+
30
+ function exactKeys(value, keys) {
31
+ return value !== null && typeof value === 'object' && !Array.isArray(value)
32
+ && JSON.stringify(Object.keys(value).sort()) === JSON.stringify([...keys].sort());
33
+ }
34
+
35
+ function validateRawBytes(rawBytes) {
36
+ if (!rawBytes || typeof rawBytes !== 'object' || util.types.isProxy(rawBytes)) {
37
+ fail('BUILD_ATTESTATION_INVALID', 'bytes de atestación inválidos');
38
+ }
39
+ const prototype = Object.getPrototypeOf(rawBytes);
40
+ const validPrototype = prototype === Buffer.prototype || prototype === Uint8Array.prototype;
41
+ const intrusive = ['buffer', 'byteOffset', 'byteLength'].some(
42
+ (property) => Object.hasOwn(rawBytes, property)
43
+ );
44
+ if (!validPrototype || intrusive
45
+ || rawBytes.byteLength === 0 || rawBytes.byteLength > MAX_RAW_BYTES) {
46
+ fail('BUILD_ATTESTATION_INVALID', 'bytes de atestación inválidos');
47
+ }
48
+ }
49
+
50
+ function parsePayload(rawBytes) {
51
+ validateRawBytes(rawBytes);
52
+ try {
53
+ return parsearIJson(rawBytes);
54
+ } catch {
55
+ fail('BUILD_ATTESTATION_INVALID', 'atestación no es I-JSON canónico');
56
+ }
57
+ }
58
+
59
+ function validateOutputs(outputs) {
60
+ if (!Array.isArray(outputs) || !outputs.every((output) => (
61
+ exactKeys(output, ['path', 'sha256'])
62
+ && typeof output.path === 'string' && output.path.startsWith('outputs/')
63
+ && typeof output.sha256 === 'string' && SHA256.test(output.sha256)
64
+ ))) return false;
65
+ try {
66
+ validarListaRutasPortables(outputs.map((output) => output.path));
67
+ return true;
68
+ } catch {
69
+ return false;
70
+ }
71
+ }
72
+
73
+ function validateBindings(payload) {
74
+ if (!Object.hasOwn(RUNTIMES, payload.runtimeId)) return false;
75
+ return payload.installerTarget === RUNTIMES[payload.runtimeId]
76
+ && payload.adapterId === `runtime-adapter:${payload.runtimeId}`;
77
+ }
78
+
79
+ function validateConstants(payload) {
80
+ return payload.schemaVersion === '1.0.0'
81
+ && payload.kind === 'swl-runtime-build-attestation'
82
+ && payload.purpose === 'runtime-build'
83
+ && payload.adapterSchemaVersion === '1.0.0'
84
+ && payload.contractVersion === '1.0.0'
85
+ && payload.effectiveMode === 'proposal_only';
86
+ }
87
+
88
+ function validatePayload(payload) {
89
+ try {
90
+ validarTimestampIso(payload.builtAt, 'build timestamp');
91
+ } catch {
92
+ return false;
93
+ }
94
+ return exactKeys(payload, PAYLOAD_KEYS)
95
+ && validateConstants(payload)
96
+ && validateBindings(payload)
97
+ && SHA256.test(payload.manifestDigest)
98
+ && SHA256.test(payload.locatorDigest)
99
+ && validateOutputs(payload.outputs);
100
+ }
101
+
102
+ function validateCas(expectedSequence, expectedHeadHash) {
103
+ if (!Number.isSafeInteger(expectedSequence) || expectedSequence < 0
104
+ || Object.is(expectedSequence, -0) || typeof expectedHeadHash !== 'string'
105
+ || !SHA256.test(expectedHeadHash)) {
106
+ fail('BUILD_CAS_INVALID', 'precondición CAS inválida');
107
+ }
108
+ }
109
+
110
+ function registrarBuildAttestation(rawBytes, expectedSequence, expectedHeadHash, dependencies) {
111
+ if (arguments.length !== 4 || !isKernelDependencies(dependencies)) {
112
+ fail('BUILD_AUTHORITY_INVALID', 'dependencias W2 no verificadas');
113
+ }
114
+ validateCas(expectedSequence, expectedHeadHash);
115
+ const payload = parsePayload(rawBytes);
116
+ if (!validatePayload(payload)) {
117
+ fail('BUILD_ATTESTATION_INVALID', 'contrato de atestación inválido');
118
+ }
119
+ return dependencies.integrityLedger.append({
120
+ expectedSequence,
121
+ expectedHeadHash,
122
+ eventType: 'runtime-build',
123
+ payload,
124
+ });
125
+ }
126
+
127
+ module.exports = { registrarBuildAttestation };