@saulwade/swl-ses 2.6.1 → 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 (268) hide show
  1. package/CLAUDE.md +14 -2
  2. package/README.md +65 -18
  3. package/agentes/_intent-spec.md +73 -73
  4. package/agentes/_propose-step.md +90 -90
  5. package/bin/swl-ses.js +10 -0
  6. package/comandos/swl/brainstorm.md +1 -0
  7. package/comandos/swl/briefing.md +119 -119
  8. package/comandos/swl/contribuir.md +233 -233
  9. package/comandos/swl/deuda-codigo.md +97 -97
  10. package/comandos/swl/mcp-status.md +1 -0
  11. package/gateway/lib/event-channel.js +191 -191
  12. package/habilidades/agent-deep-links/SKILL.md +148 -148
  13. package/habilidades/backend-async-postgres-testing/SKILL.md +216 -216
  14. package/habilidades/backend-error-design/SKILL.md +221 -221
  15. package/habilidades/backend-production-resilience/SKILL.md +288 -288
  16. package/habilidades/calidad-anti-patrones-universales/SKILL.md +105 -1
  17. package/habilidades/calidad-contract-testing/SKILL.md +165 -165
  18. package/habilidades/calidad-mutation-testing/SKILL.md +25 -1
  19. package/habilidades/checklist-seguridad/recursos/stride-cobertura.md +60 -60
  20. package/habilidades/ci-cd-pipelines/SKILL.md +5 -1
  21. package/habilidades/css-moderno/SKILL.md +7 -1
  22. package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
  23. package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
  24. package/habilidades/estructura-proyecto-claude/recursos/mcp-json-template.json +57 -57
  25. package/habilidades/extractor-de-aprendizajes/SKILL.md +5 -1
  26. package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -108
  27. package/habilidades/harness-claude-code/SKILL.md +3 -2
  28. package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
  29. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
  30. package/habilidades/perfil-usuario/SKILL.md +200 -200
  31. package/habilidades/prevencion-sobreingenieria/recursos/EXAMPLES.md +580 -580
  32. package/habilidades/prevencion-sobreingenieria/recursos/soluciones-nativas.md +166 -166
  33. package/habilidades/prevencion-sobreingenieria/recursos/variables-residuales-post-refactor.md +85 -85
  34. package/habilidades/proceso-ddia-streaming/SKILL.md +231 -231
  35. package/habilidades/proceso-discovery-machote/SKILL.md +157 -157
  36. package/habilidades/proceso-dynamic-workflows/SKILL.md +60 -0
  37. package/habilidades/proceso-dynamic-workflows/recursos/template-adversarial-verify.js +65 -65
  38. package/habilidades/proceso-dynamic-workflows/recursos/template-triage.js +65 -65
  39. package/habilidades/proceso-intent-engineering/SKILL.md +269 -269
  40. package/habilidades/proceso-modular-split/SKILL.md +256 -256
  41. package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -147
  42. package/habilidades/swl-claudemd/recursos/contrato-aprender.md +83 -83
  43. package/habilidades/swl-claudemd/recursos/duplicacion-reglas-globales.md +85 -85
  44. package/habilidades/swl-claudemd/recursos/plantillas-init.md +94 -94
  45. package/habilidades/tdd-workflow/recursos/gherkin-bdd.md +111 -111
  46. package/hooks/calidad-pre-commit.js +159 -10
  47. package/hooks/ciclo-evolucion-subagente.js +26 -26
  48. package/hooks/ciclo-evolucion.js +26 -26
  49. package/hooks/contexto-subagente.js +68 -68
  50. package/hooks/lib/auto-consolidator.js +335 -335
  51. package/hooks/lib/ciclo-evolucion.js +47 -47
  52. package/hooks/lib/deep-links.js +185 -185
  53. package/hooks/lib/error-classifier.js +308 -308
  54. package/hooks/lib/notificacion-formato.js +45 -11
  55. package/hooks/lib/provenance-tracker.js +191 -191
  56. package/hooks/lib/raiz-proyecto.js +35 -4
  57. package/hooks/lib/resource-quota.js +122 -122
  58. package/hooks/lib/retry-jitter.js +165 -165
  59. package/hooks/lib/security-net.js +201 -201
  60. package/hooks/lib/skill-auditor.js +588 -588
  61. package/hooks/lib/sync-status.js +228 -228
  62. package/hooks/lib/taint-tracker.js +107 -107
  63. package/hooks/lib/text-similarity.js +241 -241
  64. package/hooks/lib/toon-compressor.js +245 -245
  65. package/hooks/notificacion-telegram.js +5 -11
  66. package/hooks/session-briefing.js +12 -4
  67. package/instintos/autonomia.yaml +27 -27
  68. package/instintos/prompt-appendices.yaml +57 -57
  69. package/llms.txt +1 -1
  70. package/manifiestos/agent-output-schemas.json +57 -57
  71. package/manifiestos/canonical-hashes.json +662 -0
  72. package/manifiestos/harness-ir.json +47536 -0
  73. package/manifiestos/hooks-config.json +469 -469
  74. package/manifiestos/invariantes-criticos.json +30 -30
  75. package/manifiestos/policy-bundle.json +2065 -0
  76. package/manifiestos/policy-corpus-w2.json +3926 -0
  77. package/manifiestos/runtime-adapters-core3.json +208 -0
  78. package/manifiestos/runtime-conformance.json +139 -0
  79. package/manifiestos/skills-lock.json +43 -43
  80. package/package.json +2 -2
  81. package/plantillas/auditor-veto-template.md +105 -105
  82. package/plantillas/github-workflows/release-please.yml +44 -44
  83. package/plantillas/github-workflows/swl-ci.yml +107 -107
  84. package/plantillas/github-workflows/swl-security.yml +51 -51
  85. package/plugin.json +2 -2
  86. package/reglas/accesibilidad.md +10 -10
  87. package/reglas/auditorias-documentales-estructurales.md +7 -7
  88. package/reglas/cloud-infra.md +8 -8
  89. package/reglas/consultar-vault-primero.md +195 -195
  90. package/reglas/git-workflow.md +1 -0
  91. package/reglas/hooks.md +6 -6
  92. package/reglas/intent-engineering.md +218 -218
  93. package/reglas/markitdown.md +8 -8
  94. package/reglas/monitor-ci.md +12 -0
  95. package/reglas/patrones.md +6 -6
  96. package/reglas/testing.md +7 -7
  97. package/reglas/tests-cleanup.md +224 -224
  98. package/schemas/agent-message.schema.json +73 -73
  99. package/schemas/agent-output-implementacion.schema.json +114 -114
  100. package/schemas/agent-output-planificacion.schema.json +150 -150
  101. package/schemas/agent-output-review.schema.json +98 -98
  102. package/schemas/diary-entry.schema.json +112 -112
  103. package/schemas/gate-state.schema.json +76 -0
  104. package/schemas/harness-ir.schema.json +369 -0
  105. package/schemas/hook-profiles.schema.json +54 -54
  106. package/schemas/hooks-config.schema.json +89 -89
  107. package/schemas/legacy-gates.schema.json +45 -0
  108. package/schemas/modulos.schema.json +38 -38
  109. package/schemas/perfiles.schema.json +36 -36
  110. package/schemas/plugin.schema.json +77 -77
  111. package/schemas/policy-bundle.schema.json +140 -0
  112. package/schemas/policy-enforcement.schema.json +117 -0
  113. package/schemas/policy-operation.schema.json +261 -0
  114. package/schemas/runtime-adapter.schema.json +176 -0
  115. package/schemas/runtime-build-attestation.schema.json +100 -0
  116. package/schemas/runtime-conformance.schema.json +239 -0
  117. package/schemas/runtime-diagnostic.schema.json +395 -0
  118. package/schemas/skill-evals.schema.json +119 -119
  119. package/schemas/skill-frontmatter.schema.json +245 -245
  120. package/schemas/w4-certification-request.schema.json +72 -0
  121. package/schemas/w4-certification-verdict.schema.json +224 -0
  122. package/schemas/w4-corpus.schema.json +172 -0
  123. package/schemas/w4-mutation-report.schema.json +116 -0
  124. package/schemas/w4-replay-result.schema.json +164 -0
  125. package/schemas/w4-scoring-report.schema.json +89 -0
  126. package/scripts/audit-tools/audit-history.js +330 -330
  127. package/scripts/audit-tools/bundle-tracker.js +290 -290
  128. package/scripts/audit-tools/canary-monitor.js +352 -352
  129. package/scripts/audit-tools/code-profiler.js +605 -605
  130. package/scripts/audit-tools/dep-doctor.js +320 -320
  131. package/scripts/audit-tools/env-validator.js +206 -206
  132. package/scripts/audit-tools/lib/fs-walk.js +48 -48
  133. package/scripts/audit-tools/lib/output.js +23 -23
  134. package/scripts/audit-tools/migration-checker.js +392 -392
  135. package/scripts/audit-tools/pentest-scanner.js +1436 -1436
  136. package/scripts/bootstrap-instintos.js +3 -0
  137. package/scripts/cli/aprobar-plan.js +73 -73
  138. package/scripts/cli/briefing.js +23 -23
  139. package/scripts/cli/ciclo-evolucion.js +26 -26
  140. package/scripts/cli/derivar-feature-list.js +25 -25
  141. package/scripts/cli/detectar-host.js +27 -27
  142. package/scripts/cli/diary-entry.js +69 -69
  143. package/scripts/cli/execution-state.js +18 -18
  144. package/scripts/cli/gateway-notify.js +41 -41
  145. package/scripts/cli/liberar-fase.js +42 -42
  146. package/scripts/cli/mark-evolved.js +56 -56
  147. package/scripts/cli/metricas-dora.js +26 -26
  148. package/scripts/cli/near-duplicate.js +55 -55
  149. package/scripts/cli/notificaciones.js +123 -123
  150. package/scripts/cli/propose-step.js +29 -29
  151. package/scripts/cli/schedule-parse.js +19 -19
  152. package/scripts/cli/sugerir-modelo.js +20 -20
  153. package/scripts/cli/verificar-plan.js +36 -36
  154. package/scripts/cli/verificar-trazabilidad.js +35 -35
  155. package/scripts/comandos/install-asistido.js +8 -7
  156. package/scripts/configurar-branch-protection.js +418 -418
  157. package/scripts/detectar-aprendizajes-duplicados.js +151 -151
  158. package/scripts/doctor.js +61 -36
  159. package/scripts/generar-checklists-consolidados.js +273 -273
  160. package/scripts/generar-claims-runtime.js +1342 -0
  161. package/scripts/generar-harness-ir.js +257 -0
  162. package/scripts/generar-inventario.js +52 -54
  163. package/scripts/generar-policy-bundle.js +202 -0
  164. package/scripts/instalador.js +26 -7
  165. package/scripts/lib/approval-receipts.js +190 -0
  166. package/scripts/lib/artefactos-python.js +43 -43
  167. package/scripts/lib/benchmark-metrics.js +160 -160
  168. package/scripts/lib/budget-enforcer.js +252 -252
  169. package/scripts/lib/certificacion-loop-state.js +421 -0
  170. package/scripts/lib/ci-reader.js +193 -193
  171. package/scripts/lib/ciclo-autonomo/yaml-instintos.js +56 -0
  172. package/scripts/lib/clasificar-directorio.js +92 -0
  173. package/scripts/lib/contadores-inventario.js +217 -217
  174. package/scripts/lib/detectar-host-swl.js +175 -175
  175. package/scripts/lib/detectar-runtime.js +29 -20
  176. package/scripts/lib/detectar-stack-detallado.js +307 -307
  177. package/scripts/lib/detector-autoduplicacion-intra-archivo.js +234 -234
  178. package/scripts/lib/detector-reglas-duplicadas.js +220 -220
  179. package/scripts/lib/eval-metrics-store.js +218 -218
  180. package/scripts/lib/eval-quality.js +171 -171
  181. package/scripts/lib/eval-schemas.js +144 -144
  182. package/scripts/lib/eval-self-correct.js +106 -106
  183. package/scripts/lib/eval-validator.js +185 -185
  184. package/scripts/lib/evidence-verifier.js +192 -0
  185. package/scripts/lib/evidencia-release.js +322 -322
  186. package/scripts/lib/frontmatter-canonico.js +509 -0
  187. package/scripts/lib/gate-engine.js +871 -0
  188. package/scripts/lib/gate-hooks-requires.js +249 -249
  189. package/scripts/lib/gate-licencias.js +212 -212
  190. package/scripts/lib/git-config-preflight.js +48 -0
  191. package/scripts/lib/git-metricas.js +257 -257
  192. package/scripts/lib/harness-ir.js +778 -0
  193. package/scripts/lib/harness-source-snapshot.js +309 -0
  194. package/scripts/lib/integrity-ledger.js +1147 -0
  195. package/scripts/lib/jaccard-similarity.js +98 -98
  196. package/scripts/lib/legacy-gate-migration.js +324 -0
  197. package/scripts/lib/limpiar-basura-global.js +45 -2
  198. package/scripts/lib/longmemeval-runner.js +125 -125
  199. package/scripts/lib/metricas-dora.js +204 -204
  200. package/scripts/lib/notificaciones-telegram.js +1 -0
  201. package/scripts/lib/npm-version.js +1 -0
  202. package/scripts/lib/paquetes-conocidos.js +50 -50
  203. package/scripts/lib/plan-lock.js +61 -13
  204. package/scripts/lib/policy-broker.js +338 -0
  205. package/scripts/lib/policy-bundle.js +342 -0
  206. package/scripts/lib/policy-context-provider.js +310 -0
  207. package/scripts/lib/policy-contract.js +479 -0
  208. package/scripts/lib/policy-verifier-utils.js +65 -0
  209. package/scripts/lib/pr-analyzer.js +399 -399
  210. package/scripts/lib/principal-verifier.js +178 -0
  211. package/scripts/lib/prompt-builder.js +264 -264
  212. package/scripts/lib/resolver-plan-fase.js +37 -37
  213. package/scripts/lib/rrf-fusion.js +175 -175
  214. package/scripts/lib/runtime-adapter-contract.js +267 -0
  215. package/scripts/lib/runtime-artifact-verifier.js +426 -0
  216. package/scripts/lib/runtime-build-attestation.js +127 -0
  217. package/scripts/lib/runtime-bundle-installer.js +586 -0
  218. package/scripts/lib/runtime-compiler.js +327 -0
  219. package/scripts/lib/runtime-conformance.js +202 -0
  220. package/scripts/lib/runtime-doctor-core3.js +567 -0
  221. package/scripts/lib/runtime-doctor-input.js +59 -0
  222. package/scripts/lib/runtime-operation-adapter.js +267 -0
  223. package/scripts/lib/schema-version.js +164 -164
  224. package/scripts/lib/semantic-search.js +252 -252
  225. package/scripts/lib/signed-envelope.js +545 -0
  226. package/scripts/lib/single-use-store.js +359 -0
  227. package/scripts/lib/skills-externas.js +31 -0
  228. package/scripts/lib/transformadores/codex.js +15 -8
  229. package/scripts/lib/transformadores/gemini.js +79 -5
  230. package/scripts/lib/w4-attestation-adapter.js +158 -0
  231. package/scripts/lib/w4-canario.js +337 -0
  232. package/scripts/lib/w4-claims.js +182 -0
  233. package/scripts/lib/w4-corpus-generador.js +542 -0
  234. package/scripts/lib/w4-gate-c5.js +115 -0
  235. package/scripts/lib/w4-harness-bajo-prueba.js +155 -0
  236. package/scripts/lib/w4-matriz-combos.js +55 -0
  237. package/scripts/lib/w4-motor-mutacion.js +1348 -0
  238. package/scripts/lib/w4-motor-replay.js +735 -0
  239. package/scripts/lib/w4-pin-origen.js +54 -0
  240. package/scripts/lib/w4-publicar-request.js +132 -0
  241. package/scripts/lib/w4-revocacion.js +62 -0
  242. package/scripts/lib/w4-runtimes-core3.js +38 -0
  243. package/scripts/lib/w4-scorer-certificacion.js +692 -0
  244. package/scripts/lib/w4-superficie-candidato.js +49 -0
  245. package/scripts/lib/w4-veredicto.js +452 -0
  246. package/scripts/lib/w4-verificar-veredicto.js +302 -0
  247. package/scripts/limpiar-artefactos-python.js +131 -131
  248. package/scripts/migrar-csv-a-array.js +168 -168
  249. package/scripts/migrar-fase-dominio.js +200 -200
  250. package/scripts/migrar-gates-legacy.js +108 -0
  251. package/scripts/publicar-certification-request.js +115 -0
  252. package/scripts/runtime-doctor.js +107 -0
  253. package/scripts/tui/componentes/selector-multi.js +189 -189
  254. package/scripts/tui/componentes/selector-unico.js +158 -158
  255. package/scripts/tui/ejecutores.js +375 -375
  256. package/scripts/tui/lib/colores.js +129 -129
  257. package/scripts/tui/lib/render.js +264 -264
  258. package/scripts/tui/lib/teclas.js +113 -113
  259. package/scripts/tui/pantallas/install-wizard.js +12 -7
  260. package/scripts/tui/pantallas/menu-principal.js +52 -52
  261. package/scripts/tui/pantallas/progreso.js +274 -274
  262. package/scripts/tui/pantallas/resumen.js +132 -132
  263. package/scripts/validar-userland-vacio.js +110 -110
  264. package/scripts/verificar-aislamiento-swl-eval.js +87 -0
  265. package/scripts/verificar-empaquetado-downstream.js +375 -0
  266. package/scripts/verificar-loop-constructor.js +215 -0
  267. package/scripts/verificar-trazabilidad.js +13 -6
  268. package/scripts/verificar-veredicto-real.js +84 -0
@@ -0,0 +1,479 @@
1
+ 'use strict';
2
+
3
+ /** Contratos opacos de operación y bootstrap del kernel W2. */
4
+
5
+ const crypto = require('node:crypto');
6
+ const path = require('node:path');
7
+ const util = require('node:util');
8
+
9
+ const POLICY_SCHEMA = require('../../schemas/policy-bundle.schema.json');
10
+ const {
11
+ canonicalizarIJson,
12
+ esEnvelopeVerificado,
13
+ parsearIJson,
14
+ validarTimestampIso,
15
+ } = require('./signed-envelope');
16
+ const SCHEMA_VERSION = '1.0.0';
17
+ const SHA256 = /^[a-f0-9]{64}$/u;
18
+ const IDENTIFICADOR = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
19
+ const DNS_LABEL = '[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?';
20
+ const ASCII_HOST = new RegExp(`^(?:${DNS_LABEL})(?:\\.(?:${DNS_LABEL}))*$`, 'u');
21
+ const CAPABILITIES = new Set(POLICY_SCHEMA.$defs.capability.enum);
22
+ const EFFECT_KINDS = new Set(['access', 'delegate', 'execute', 'invoke', 'mutate', 'read']);
23
+ const OPERATION_KEYS = [
24
+ 'schemaVersion', 'operationId', 'capability', 'effectKind', 'payloadDigest', 'scope',
25
+ 'cwd', 'fsmVersion', 'timestamp',
26
+ ];
27
+ const OPERATION_KEYS_V11 = [...OPERATION_KEYS, 'phaseId', 'taskId', 'effect'];
28
+ const EFFECT_KINDS_CANONICAL = new Set([
29
+ 'filesystem', 'process', 'network', 'memory', 'delegation', 'skill',
30
+ ]);
31
+ const UNSAFE_TEXT = /[\u0000-\u001F\u007F\u001B\u200B-\u200F\u202A-\u202E\u2060-\u206F]/u;
32
+ const BOOTSTRAP_KEYS = [
33
+ 'kind', 'schemaVersion', 'trustEpoch', 'trustDigest', 'providers', 'trustPath',
34
+ 'signerPath', 'anchorPath', 'issuedAt', 'expiresAt', 'nonce',
35
+ ];
36
+ const PROVIDERS = Object.freeze({
37
+ clock: 'builtin:clock-v1',
38
+ randomSource: 'builtin:random-source-v1',
39
+ processInspector: 'builtin:process-inspector-v1',
40
+ integrityProvider: 'builtin:integrity-provider-v1',
41
+ stateAnchorProvider: 'builtin:state-anchor-provider-v1',
42
+ });
43
+ const VERIFIED_OPERATIONS = new WeakSet();
44
+ const VERIFIED_BOOTSTRAPS = new WeakSet();
45
+ const BOOTSTRAP_METADATA = new WeakMap();
46
+ const KERNEL_DEPENDENCIES = new WeakSet();
47
+
48
+ function crearError(codigo, mensaje) {
49
+ const error = new Error(mensaje);
50
+ error.codigo = codigo;
51
+ return error;
52
+ }
53
+
54
+ function fallar(codigo, mensaje) {
55
+ throw crearError(codigo, mensaje);
56
+ }
57
+
58
+ function validarObjeto(valor, etiqueta) {
59
+ if (!valor || typeof valor !== 'object' || Array.isArray(valor) || util.types.isProxy(valor)) {
60
+ fallar('CONTRACT_INVALID', `${etiqueta} inválido`);
61
+ }
62
+ const proto = Object.getPrototypeOf(valor);
63
+ if (proto !== Object.prototype && proto !== null) {
64
+ fallar('CONTRACT_INVALID', `${etiqueta} inválido`);
65
+ }
66
+ if (Object.getOwnPropertySymbols(valor).length > 0) {
67
+ fallar('CONTRACT_INVALID', `${etiqueta} inválido`);
68
+ }
69
+ const descriptores = Object.values(Object.getOwnPropertyDescriptors(valor));
70
+ if (descriptores.some((item) => !item.enumerable || !('value' in item))) {
71
+ fallar('CONTRACT_INVALID', `${etiqueta} inválido`);
72
+ }
73
+ }
74
+
75
+ function validarClaves(valor, esperadas, etiqueta) {
76
+ const actuales = Object.keys(valor).sort();
77
+ const objetivo = [...esperadas].sort();
78
+ if (JSON.stringify(actuales) !== JSON.stringify(objetivo)) {
79
+ fallar('CONTRACT_INVALID', `${etiqueta} inválida`);
80
+ }
81
+ }
82
+
83
+ function validarIdentificador(valor, etiqueta) {
84
+ if (typeof valor !== 'string' || !IDENTIFICADOR.test(valor)) {
85
+ fallar('CONTRACT_INVALID', `${etiqueta} inválido`);
86
+ }
87
+ }
88
+
89
+ function congelarProfundo(valor) {
90
+ if (!valor || typeof valor !== 'object' || Object.isFrozen(valor)) return valor;
91
+ Object.values(valor).forEach(congelarProfundo);
92
+ return Object.freeze(valor);
93
+ }
94
+
95
+ function validarScope(scope) {
96
+ validarObjeto(scope, 'scope');
97
+ validarClaves(scope, ['digest'], 'scope');
98
+ if (!SHA256.test(scope.digest)) fallar('CONTRACT_INVALID', 'operación con scope inválido');
99
+ }
100
+
101
+ function validarTextoCanonico(valor, etiqueta, maximo = 4096, permitirVacio = false) {
102
+ if (typeof valor !== 'string' || (!permitirVacio && valor.length === 0)
103
+ || valor.length > maximo
104
+ || valor.normalize('NFKC') !== valor || UNSAFE_TEXT.test(valor)) {
105
+ fallar('CONTRACT_INVALID', `${etiqueta} inválido`);
106
+ }
107
+ }
108
+
109
+ function validarSegmentosPosix(resto) {
110
+ const segmentos = resto.split('/');
111
+ if (segmentos.some((item) => !item || item === '.' || item === '..')) {
112
+ fallar('CONTRACT_INVALID', 'path canónico inválido');
113
+ }
114
+ }
115
+
116
+ function validarSegmentosWindows(resto) {
117
+ const segmentos = resto.split('\\');
118
+ if (segmentos.some((item) => !item || item === '.' || item === '..'
119
+ || item.includes(':') || /[. ]$/u.test(item) || /~\d+/u.test(item)
120
+ || /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/iu.test(item))) {
121
+ fallar('CONTRACT_INVALID', 'path canónico inválido');
122
+ }
123
+ }
124
+
125
+ function validarPathCanonico(style, absolutePath) {
126
+ validarTextoCanonico(absolutePath, 'path');
127
+ if (style === 'posix') {
128
+ if (!absolutePath.startsWith('/') || absolutePath.startsWith('//')
129
+ || absolutePath.includes('\\')) fallar('CONTRACT_INVALID', 'path POSIX inválido');
130
+ validarSegmentosPosix(absolutePath.slice(1));
131
+ return;
132
+ }
133
+ if (style !== 'win32' || !/^[A-Z]:\\/u.test(absolutePath)
134
+ || /^[A-Z]:\\[\\?.]/u.test(absolutePath) || absolutePath.includes('/')) {
135
+ fallar('CONTRACT_INVALID', 'path Windows inválido');
136
+ }
137
+ validarSegmentosWindows(absolutePath.slice(3));
138
+ }
139
+
140
+ function validarCwdV11(effect, cwd) {
141
+ const style = ['filesystem', 'process'].includes(effect.kind)
142
+ ? effect.pathStyle
143
+ : (cwd.startsWith('/') ? 'posix' : 'win32');
144
+ validarPathCanonico(style, cwd);
145
+ }
146
+
147
+ function validarFilesystemEffect(effect) {
148
+ validarClaves(effect, ['kind', 'pathStyle', 'absolutePath', 'access'], 'effect');
149
+ if (!['posix', 'win32'].includes(effect.pathStyle)
150
+ || !['read', 'mutate', 'delete'].includes(effect.access)) {
151
+ fallar('CONTRACT_INVALID', 'effect filesystem inválido');
152
+ }
153
+ validarPathCanonico(effect.pathStyle, effect.absolutePath);
154
+ }
155
+
156
+ function validarProcessEffect(effect) {
157
+ validarClaves(effect, ['kind', 'mode', 'pathStyle', 'executablePath', 'argv'], 'effect');
158
+ if (effect.mode !== 'direct' || !['posix', 'win32'].includes(effect.pathStyle)
159
+ || !Array.isArray(effect.argv) || effect.argv.length > 256) {
160
+ fallar('CONTRACT_INVALID', 'effect process inválido');
161
+ }
162
+ validarPathCanonico(effect.pathStyle, effect.executablePath);
163
+ effect.argv.forEach((item) => validarTextoCanonico(item, 'argv', 8192, true));
164
+ }
165
+
166
+ function validarNetworkEffect(effect) {
167
+ validarClaves(effect, ['kind', 'scheme', 'asciiHost', 'port'], 'effect');
168
+ if (!['http', 'https'].includes(effect.scheme)
169
+ || typeof effect.asciiHost !== 'string'
170
+ || !ASCII_HOST.test(effect.asciiHost)
171
+ || !Number.isInteger(effect.port) || effect.port < 1 || effect.port > 65535) {
172
+ fallar('CONTRACT_INVALID', 'effect network inválido');
173
+ }
174
+ }
175
+
176
+ function validarMemoryEffect(effect) {
177
+ validarClaves(effect, ['kind', 'namespace', 'resourceId', 'access'], 'effect');
178
+ validarIdentificador(effect.namespace, 'namespace');
179
+ validarIdentificador(effect.resourceId, 'resourceId');
180
+ if (!['read', 'write'].includes(effect.access)) {
181
+ fallar('CONTRACT_INVALID', 'effect memory inválido');
182
+ }
183
+ }
184
+
185
+ function validarDelegationEffect(effect) {
186
+ validarClaves(effect, ['kind', 'targetAgentNodeId', 'capabilities'], 'effect');
187
+ if (!/^agent:[a-f0-9]{64}$/u.test(effect.targetAgentNodeId)
188
+ || !Array.isArray(effect.capabilities) || effect.capabilities.length === 0
189
+ || effect.capabilities.some((item) => !CAPABILITIES.has(item))
190
+ || effect.capabilities.some((item, index) => (
191
+ index > 0 && effect.capabilities[index - 1] >= item
192
+ ))) {
193
+ fallar('CONTRACT_INVALID', 'effect delegation inválido');
194
+ }
195
+ }
196
+
197
+ function validarSkillEffect(effect) {
198
+ validarClaves(effect, ['kind', 'skillNodeId'], 'effect');
199
+ if (!/^skill:[a-f0-9]{64}$/u.test(effect.skillNodeId)) {
200
+ fallar('CONTRACT_INVALID', 'effect skill inválido');
201
+ }
202
+ }
203
+
204
+ function validarEffectShape(effect) {
205
+ validarObjeto(effect, 'effect');
206
+ validarTextoCanonico(effect.kind, 'effect kind', 32);
207
+ if (!EFFECT_KINDS_CANONICAL.has(effect.kind)) {
208
+ fallar('CONTRACT_INVALID', 'effect desconocido');
209
+ }
210
+ if (effect.kind === 'filesystem') validarFilesystemEffect(effect);
211
+ else if (effect.kind === 'process') validarProcessEffect(effect);
212
+ else if (effect.kind === 'network') validarNetworkEffect(effect);
213
+ else if (effect.kind === 'memory') validarMemoryEffect(effect);
214
+ else if (effect.kind === 'delegation') validarDelegationEffect(effect);
215
+ else validarSkillEffect(effect);
216
+ }
217
+
218
+ function validarEffectBinding(valor) {
219
+ const effect = valor.effect;
220
+ const expected = {
221
+ filesystem: {
222
+ capability: effect.access === 'read' ? 'filesystem.read' : 'filesystem.mutate',
223
+ effectKind: effect.access === 'read' ? 'read' : 'mutate',
224
+ },
225
+ process: { capability: 'shell.exec', effectKind: 'execute' },
226
+ network: { capability: 'network.access', effectKind: 'access' },
227
+ memory: {
228
+ capability: effect.access === 'read' ? 'memory.read' : 'memory.write',
229
+ effectKind: effect.access === 'read' ? 'read' : 'mutate',
230
+ },
231
+ delegation: { capability: 'delegate', effectKind: 'delegate' },
232
+ skill: { capability: 'skill.invoke', effectKind: 'invoke' },
233
+ }[effect.kind];
234
+ if (valor.capability !== expected.capability || valor.effectKind !== expected.effectKind) {
235
+ fallar('CONTRACT_INVALID', 'binding de effect inválido');
236
+ }
237
+ }
238
+
239
+ function validarOperationV11(valor) {
240
+ validarEffectShape(valor.effect);
241
+ validarCwdV11(valor.effect, valor.cwd);
242
+ validarEffectBinding(valor);
243
+ const digest = crypto.createHash('sha256')
244
+ .update(canonicalizarIJson(valor.effect), 'utf8').digest('hex');
245
+ if (digest !== valor.scope.digest) fallar('CONTRACT_INVALID', 'preimagen scope inválida');
246
+ }
247
+
248
+ function validarOperacion(valor) {
249
+ validarObjeto(valor, 'operación');
250
+ const esV11 = valor.schemaVersion === '1.1.0';
251
+ validarClaves(valor, esV11 ? OPERATION_KEYS_V11 : OPERATION_KEYS, 'operación');
252
+ if (![SCHEMA_VERSION, '1.1.0'].includes(valor.schemaVersion)) {
253
+ fallar('CONTRACT_INVALID', 'operación futura');
254
+ }
255
+ validarIdentificador(valor.operationId, 'operationId');
256
+ if (!CAPABILITIES.has(valor.capability)) {
257
+ fallar('CONTRACT_INVALID', 'operación capability inválida');
258
+ }
259
+ if (!EFFECT_KINDS.has(valor.effectKind)) fallar('CONTRACT_INVALID', 'operación effect inválido');
260
+ if (!SHA256.test(valor.payloadDigest)) fallar('CONTRACT_INVALID', 'operación digest inválido');
261
+ validarScope(valor.scope);
262
+ if (!esV11 && (typeof valor.cwd !== 'string'
263
+ || valor.cwd.length === 0 || valor.cwd.length > 4096)) {
264
+ fallar('CONTRACT_INVALID', 'operación cwd inválido');
265
+ }
266
+ if (!Number.isInteger(valor.fsmVersion) || valor.fsmVersion < 0) {
267
+ fallar('CONTRACT_INVALID', 'operación FSM inválida');
268
+ }
269
+ validarTimestampIso(valor.timestamp, 'operación timestamp');
270
+ if (esV11) {
271
+ validarIdentificador(valor.phaseId, 'phaseId');
272
+ if (!/^T-[0-9]{2}$/u.test(valor.taskId)) fallar('CONTRACT_INVALID', 'taskId inválido');
273
+ validarOperationV11(valor);
274
+ }
275
+ }
276
+
277
+ function verificarOperacionInterna(rawBytes) {
278
+ let valor;
279
+ try {
280
+ valor = parsearIJson(rawBytes);
281
+ validarOperacion(valor);
282
+ } catch (error) {
283
+ if (error.codigo === 'RAW_BYTES_INVALID') {
284
+ throw crearError('OPERATION_INVALID', 'raw bytes inválidos');
285
+ }
286
+ if (error.codigo === 'IJSON_DUPLICATE') {
287
+ throw crearError('OPERATION_INVALID', 'operación con clave duplicada');
288
+ }
289
+ throw crearError('OPERATION_INVALID', 'operación inválida');
290
+ }
291
+ return valor;
292
+ }
293
+
294
+ function verifyOperation(rawBytes) {
295
+ const valor = verificarOperacionInterna(rawBytes);
296
+ const operationDigest = crypto.createHash('sha256')
297
+ .update(canonicalizarIJson(valor), 'utf8')
298
+ .digest('hex');
299
+ congelarProfundo(valor);
300
+ const operation = Object.freeze({ ...valor, operationDigest });
301
+ VERIFIED_OPERATIONS.add(operation);
302
+ return operation;
303
+ }
304
+
305
+ function isVerifiedOperation(valor) {
306
+ return VERIFIED_OPERATIONS.has(valor);
307
+ }
308
+
309
+ function isKernelDependencies(valor) {
310
+ return KERNEL_DEPENDENCIES.has(valor);
311
+ }
312
+
313
+ function validarOpcionesBootstrap(opciones) {
314
+ try {
315
+ validarObjeto(opciones, 'opciones bootstrap');
316
+ validarClaves(opciones, ['workspaceRoot', 'now'], 'opciones bootstrap');
317
+ } catch {
318
+ fallar('BOOTSTRAP_INVALID', 'opciones bootstrap inválidas');
319
+ }
320
+ if (!esRutaLocalAbsoluta(opciones.workspaceRoot)) {
321
+ fallar('BOOTSTRAP_INVALID', 'workspace bootstrap inválido');
322
+ }
323
+ validarTimestampIso(opciones.now, 'bootstrap now');
324
+ }
325
+
326
+ function validarProvider(nombre, valor) {
327
+ validarObjeto(valor, 'provider bootstrap');
328
+ validarClaves(valor, ['implementation', 'fingerprint'], 'provider bootstrap');
329
+ if (valor.implementation !== PROVIDERS[nombre] || !SHA256.test(valor.fingerprint)) {
330
+ fallar('BOOTSTRAP_INVALID', 'provider bootstrap inválido');
331
+ }
332
+ }
333
+
334
+ function validarProviders(providers) {
335
+ validarObjeto(providers, 'providers bootstrap');
336
+ validarClaves(providers, Object.keys(PROVIDERS), 'providers bootstrap');
337
+ for (const nombre of Object.keys(PROVIDERS)) validarProvider(nombre, providers[nombre]);
338
+ }
339
+
340
+ function esRutaInterna(ruta, workspaceRoot) {
341
+ const workspace = path.resolve(workspaceRoot);
342
+ const destino = path.resolve(ruta);
343
+ const relativa = path.relative(workspace, destino);
344
+ return relativa === '' || (!relativa.startsWith('..') && !path.isAbsolute(relativa));
345
+ }
346
+
347
+ function esRutaLocalAbsoluta(ruta) {
348
+ if (typeof ruta !== 'string' || !path.isAbsolute(ruta) || ruta.includes('\0')) return false;
349
+ if (/^[\\/]{2}|^[A-Za-z]:[^\\/]/u.test(ruta)) return false;
350
+ if (ruta.normalize('NFKC') !== ruta) return false;
351
+ if (/[\u200B-\u200F\u202A-\u202E\u2060-\u206F]/u.test(ruta)) return false;
352
+ const resto = ruta.slice(path.parse(ruta).root.length);
353
+ if (resto.includes(':')) return false;
354
+ return resto.split(/[\\/]/u).every((segmento) => {
355
+ if (!segmento || /[. ]$/u.test(segmento) || /~\d+/u.test(segmento)) return false;
356
+ return !/^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/iu.test(segmento);
357
+ });
358
+ }
359
+
360
+ function validarRutaExterna(ruta, workspaceRoot) {
361
+ if (!esRutaLocalAbsoluta(ruta) || esRutaInterna(ruta, workspaceRoot)) {
362
+ fallar('BOOTSTRAP_INVALID', 'path bootstrap inválido');
363
+ }
364
+ }
365
+
366
+ function validarBootstrapClaims(claims, envelope, opciones) {
367
+ validarObjeto(claims, 'bootstrap claims');
368
+ validarClaves(claims, BOOTSTRAP_KEYS, 'bootstrap claims');
369
+ if (claims.kind !== 'kernel-bootstrap' || claims.schemaVersion !== SCHEMA_VERSION) {
370
+ fallar('BOOTSTRAP_INVALID', 'bootstrap futuro o inválido');
371
+ }
372
+ if (claims.trustEpoch !== envelope.trustEpoch || claims.trustDigest !== envelope.trustDigest) {
373
+ fallar('BOOTSTRAP_INVALID', 'bootstrap trust binding inválido');
374
+ }
375
+ validarProviders(claims.providers);
376
+ for (const campo of ['trustPath', 'signerPath', 'anchorPath']) {
377
+ validarRutaExterna(claims[campo], opciones.workspaceRoot);
378
+ }
379
+ validarTimestampIso(claims.issuedAt, 'bootstrap issuedAt');
380
+ validarTimestampIso(claims.expiresAt, 'bootstrap expiresAt');
381
+ validarIdentificador(claims.nonce, 'bootstrap nonce');
382
+ if (opciones.now < claims.issuedAt || opciones.now > claims.expiresAt) {
383
+ fallar('BOOTSTRAP_INVALID', 'bootstrap fuera de vigencia');
384
+ }
385
+ }
386
+
387
+ function validarEnvelopeBootstrap(envelope) {
388
+ if (
389
+ !esEnvelopeVerificado(envelope)
390
+ || envelope.type !== 'integrity'
391
+ || envelope.verifiedScope !== 'kernel:bootstrap'
392
+ ) {
393
+ fallar('BOOTSTRAP_INVALID', 'bootstrap no verificado');
394
+ }
395
+ }
396
+
397
+ function crearBootstrapReceipt(envelope, opciones) {
398
+ const receipt = Object.freeze({
399
+ kind: 'verified-kernel-bootstrap-receipt',
400
+ trustEpoch: envelope.trustEpoch, trustDigest: envelope.trustDigest,
401
+ rootKeyDigest: envelope.rootKeyDigest, providers: envelope.claims.providers,
402
+ trustPath: envelope.claims.trustPath, signerPath: envelope.claims.signerPath,
403
+ anchorPath: envelope.claims.anchorPath, issuedAt: envelope.claims.issuedAt,
404
+ expiresAt: envelope.claims.expiresAt, nonce: envelope.claims.nonce,
405
+ });
406
+ congelarProfundo(receipt);
407
+ VERIFIED_BOOTSTRAPS.add(receipt);
408
+ BOOTSTRAP_METADATA.set(receipt, Object.freeze({
409
+ workspaceRoot: opciones.workspaceRoot, signerKeyId: envelope.keyId,
410
+ signerPublicKeyDigest: envelope.signerPublicKeyDigest,
411
+ }));
412
+ return receipt;
413
+ }
414
+
415
+ function verifyKernelBootstrapReceipt(envelope, opciones) {
416
+ validarEnvelopeBootstrap(envelope);
417
+ validarOpcionesBootstrap(opciones);
418
+ try {
419
+ validarBootstrapClaims(envelope.claims, envelope, opciones);
420
+ } catch (error) {
421
+ if (error.codigo === 'BOOTSTRAP_INVALID') throw error;
422
+ throw crearError('BOOTSTRAP_INVALID', 'bootstrap inválido');
423
+ }
424
+ return crearBootstrapReceipt(envelope, opciones);
425
+ }
426
+
427
+ function isVerifiedKernelBootstrapReceipt(valor) {
428
+ return VERIFIED_BOOTSTRAPS.has(valor);
429
+ }
430
+
431
+ const { bindContractValidators } = require('./policy-verifier-utils');
432
+ bindContractValidators({ isKernelDependencies, isVerifiedOperation });
433
+
434
+ const runtimeModule = require('./integrity-ledger');
435
+ const createBuiltInKernelRuntime = runtimeModule.createBuiltInKernelRuntime;
436
+ delete runtimeModule.createBuiltInKernelRuntime;
437
+ Object.freeze(runtimeModule);
438
+
439
+ function componerRuntime(receipt, metadata) {
440
+ try {
441
+ return createBuiltInKernelRuntime({
442
+ receipt, workspaceRoot: metadata.workspaceRoot,
443
+ signerKeyId: metadata.signerKeyId,
444
+ signerPublicKeyDigest: metadata.signerPublicKeyDigest,
445
+ });
446
+ } catch (error) {
447
+ if (error.codigo) throw error;
448
+ throw crearError('KERNEL_DEPENDENCIES_INVALID', 'composición del kernel inválida');
449
+ }
450
+ }
451
+
452
+ function crearDependencies(runtime) {
453
+ const dependencies = congelarProfundo(Object.freeze({
454
+ kind: 'kernel-dependencies', providers: runtime.providers,
455
+ gateEngine: runtime.gateEngine,
456
+ integrityLedger: runtime.integrityLedger,
457
+ policyBroker: runtime.policyBroker,
458
+ policyContextProvider: runtime.policyContextProvider,
459
+ singleUseStore: runtime.singleUseStore,
460
+ }));
461
+ KERNEL_DEPENDENCIES.add(dependencies);
462
+ return dependencies;
463
+ }
464
+
465
+ function createKernelDependencies(receipt) {
466
+ const autorizado = arguments.length === 1 && VERIFIED_BOOTSTRAPS.has(receipt);
467
+ if (!autorizado) fallar('KERNEL_DEPENDENCIES_INVALID', 'bootstrap receipt no autorizado');
468
+ const metadata = BOOTSTRAP_METADATA.get(receipt);
469
+ return crearDependencies(componerRuntime(receipt, metadata));
470
+ }
471
+
472
+ module.exports = {
473
+ createKernelDependencies,
474
+ isKernelDependencies,
475
+ isVerifiedKernelBootstrapReceipt,
476
+ isVerifiedOperation,
477
+ verifyKernelBootstrapReceipt,
478
+ verifyOperation,
479
+ };
@@ -0,0 +1,65 @@
1
+ 'use strict';
2
+
3
+ /** Primitivas puras compartidas por los verificadores de capabilities W2. */
4
+
5
+ const util = require('node:util');
6
+
7
+ let contractValidators = null;
8
+
9
+ function fail(code, message) {
10
+ const error = new Error(message);
11
+ error.codigo = code;
12
+ throw error;
13
+ }
14
+
15
+ function plainObject(value, code, label) {
16
+ if (!value || typeof value !== 'object' || Array.isArray(value) || util.types.isProxy(value)) {
17
+ fail(code, `${label} inválido`);
18
+ }
19
+ const proto = Object.getPrototypeOf(value);
20
+ const descriptors = Object.values(Object.getOwnPropertyDescriptors(value));
21
+ if ((proto !== Object.prototype && proto !== null)
22
+ || Object.getOwnPropertySymbols(value).length > 0
23
+ || descriptors.some((item) => !item.enumerable || !('value' in item))) {
24
+ fail(code, `${label} inválido`);
25
+ }
26
+ }
27
+
28
+ function exactKeys(value, keys, code, label) {
29
+ if (JSON.stringify(Object.keys(value).sort()) !== JSON.stringify([...keys].sort())) {
30
+ fail(code, `${label} con propiedades inválidas`);
31
+ }
32
+ }
33
+
34
+ function freezeDeep(value) {
35
+ if (!value || typeof value !== 'object' || Object.isFrozen(value)) return value;
36
+ Object.values(value).forEach(freezeDeep);
37
+ return Object.freeze(value);
38
+ }
39
+
40
+ function bindContractValidators(validators) {
41
+ plainObject(validators, 'KERNEL_BINDING_INVALID', 'predicados del contrato');
42
+ exactKeys(
43
+ validators, ['isKernelDependencies', 'isVerifiedOperation'],
44
+ 'KERNEL_BINDING_INVALID', 'predicados del contrato'
45
+ );
46
+ if (Object.values(validators).some((validator) => typeof validator !== 'function')) {
47
+ fail('KERNEL_BINDING_INVALID', 'predicados del contrato inválidos');
48
+ }
49
+ const hasConflict = contractValidators && Object.keys(contractValidators)
50
+ .some((key) => contractValidators[key] !== validators[key]);
51
+ if (hasConflict) {
52
+ fail('KERNEL_BINDING_CONFLICT', 'predicados del contrato ya ligados');
53
+ }
54
+ contractValidators ||= Object.freeze({ ...validators });
55
+ return contractValidators;
56
+ }
57
+
58
+ function getContractValidators() {
59
+ if (!contractValidators) fail('KERNEL_BINDING_MISSING', 'predicados del contrato no ligados');
60
+ return contractValidators;
61
+ }
62
+
63
+ module.exports = {
64
+ bindContractValidators, exactKeys, fail, freezeDeep, getContractValidators, plainObject,
65
+ };