@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,54 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * `pinOrigen` — identidad OIDC ESPERADA del workflow protegido de `swl-eval`
5
+ * que firma los `CertificationVerdict` (T-09, REQ-32-09, ADR-0053 pieza 5,
6
+ * ADR-0056 § pinOrigen bajo gobernanza).
7
+ *
8
+ * ES UNA CONSTANTE COMMITEADA, NUNCA UN INPUT DE RUNTIME. La revisión
9
+ * adversarial de T-09 mostró que si el candidato pudiera fijar `pinOrigen` en
10
+ * ejecución, la raíz de confianza criptográfica colapsaría a una auto-aserción
11
+ * del evaluado (`seguridad-agentes.md § Anti-gaming`). Por eso vive aquí,
12
+ * congelado; cambiarlo es un CAMBIO DE SEGURIDAD que exige PR revisado
13
+ * (gobernanza.md § alto riesgo), no una edición silenciosa.
14
+ *
15
+ * FORMAS DE STRING — PENDIENTES DE GOLDEN BUNDLE: `repo`/`workflow`/`ref`
16
+ * usan las formas de las extensiones del certificado Sigstore de GitHub
17
+ * Actions (`sourceRepositoryURI`, `buildSignerURI`, `sourceRepositoryRef`),
18
+ * que `w4-attestation-adapter.js#mapearIdentidad` extrae. Las formas EXACTAS
19
+ * se anclan contra un bundle real en el tramo real (ver
20
+ * DT-T06-BINDING-C1-DELEGADO-A-ADAPTADOR-T09). El test viviente
21
+ * `tests/lib/w4-pin-origen.test.js` asevera que el pin y el mapeo del
22
+ * adaptador coinciden en forma — cuando exista el golden bundle, ese test se
23
+ * ancla además contra la identidad OIDC real.
24
+ */
25
+
26
+ // Config del adaptador (`--owner`, `--signer-workflow`). El owner canónico es
27
+ // la ORG `saul-wade` (donde vive swl-eval); difiere de CODEOWNERS
28
+ // `@saulwadeleon` (el usuario) — resuelto por escrito en ADR-0056.
29
+ const OWNER = 'saul-wade';
30
+ const REPO = 'saul-wade/swl-eval';
31
+ const RUTA_WORKFLOW = '.github/workflows/certificacion.yml';
32
+ const REF = 'refs/heads/main';
33
+
34
+ // Valor para `gh attestation verify --signer-workflow`, que EXIGE el formato
35
+ // completo `[host/]<owner>/<repo>/<path>/<to>/<workflow>` (verificado en gh
36
+ // v2.89.0) — no basta la ruta del workflow. Sin el prefijo owner/repo, gh no
37
+ // casa la identidad y TODO veredicto real caería en VERDICT_SIGNATURE_INVALID.
38
+ const SIGNER_WORKFLOW = `${REPO}/${RUTA_WORKFLOW}`;
39
+
40
+ // Identidad OIDC esperada, en las formas que produce mapearIdentidad().
41
+ const PIN_ORIGEN = Object.freeze({
42
+ repo: `https://github.com/${REPO}`,
43
+ workflow: `https://github.com/${REPO}/${RUTA_WORKFLOW}@${REF}`,
44
+ ref: REF,
45
+ });
46
+
47
+ module.exports = {
48
+ PIN_ORIGEN,
49
+ OWNER,
50
+ REPO,
51
+ RUTA_WORKFLOW,
52
+ SIGNER_WORKFLOW,
53
+ REF,
54
+ };
@@ -0,0 +1,132 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Builder PURO del `CertificationRequest` que `swl-ses` (candidato) publica
5
+ * hacia `swl-eval` (juez) — T-09, REQ-32-09, ADR-0053 § Contrato. Sin efectos:
6
+ * no lee disco, no hace red, no consulta el reloj. Los efectos (derivar el
7
+ * commit de git, el `tarballDigest` de `npm pack`, escribir el JSON) viven en
8
+ * el CLI `scripts/publicar-certification-request.js`.
9
+ *
10
+ * `entryPoint` por defecto apunta a la superficie del CANDIDATO
11
+ * (`runHarnessBajoPrueba`), que el juez instancia DESDE EL TARBALL bajo prueba
12
+ * (nunca desde una copia pineada — ADR-0056 § vendor sin superficie del
13
+ * candidato). La validación es la autoritativa de `validateCertificationRequest`
14
+ * (incluye unicidad de matrix y NFKC, no expresables en JSON Schema puro).
15
+ */
16
+
17
+ const { validateCertificationRequest } = require('./w4-harness-bajo-prueba');
18
+
19
+ const SCHEMA_VERSION = '1.0.0';
20
+ const KIND = 'swl-certification-request';
21
+ const GIT_SHA = /^[a-f0-9]{40}$/u;
22
+ const SHA256 = /^[a-f0-9]{64}$/u;
23
+
24
+ const ENTRYPOINT_DEFECTO = Object.freeze({
25
+ module: 'scripts/lib/w4-superficie-candidato.js',
26
+ function: 'runHarnessBajoPrueba',
27
+ });
28
+
29
+ function crearError(codigo, mensaje) {
30
+ const error = new Error(mensaje);
31
+ error.codigo = codigo;
32
+ return error;
33
+ }
34
+
35
+ function fallar(codigo, mensaje) {
36
+ throw crearError(codigo, mensaje);
37
+ }
38
+
39
+ /**
40
+ * Arma y valida el `CertificationRequest`. Lanza `CERTIFICATION_REQUEST_INVALID`
41
+ * si cualquier campo no cumple el contrato. Retorna el request deeply frozen.
42
+ *
43
+ * @param {{commit:string, tarballDigest:string, matrix:Array<{runtime,os,model}>,
44
+ * entryPoint?:{module:string, function:string}}} opciones
45
+ */
46
+ function construirRequest(opciones = {}) {
47
+ const { commit, tarballDigest, matrix, entryPoint = ENTRYPOINT_DEFECTO } = opciones;
48
+ return validateCertificationRequest({
49
+ kind: KIND,
50
+ schemaVersion: SCHEMA_VERSION,
51
+ candidate: { commit, tarballDigest },
52
+ matrix,
53
+ entryPoint,
54
+ });
55
+ }
56
+
57
+ /**
58
+ * Deriva el `requestEsperado` de anti-replay (C2) que consume
59
+ * `verificarVeredicto`: exactamente `{commit, tarballDigest, matrix}` con cada
60
+ * entrada `{runtime, os, model}`. Re-valida el request por robustez.
61
+ */
62
+ function construirRequestEsperado(request) {
63
+ const validado = validateCertificationRequest(request);
64
+ return {
65
+ commit: validado.candidate.commit,
66
+ tarballDigest: validado.candidate.tarballDigest,
67
+ matrix: validado.matrix.map((entrada) => ({
68
+ runtime: entrada.runtime, os: entrada.os, model: entrada.model,
69
+ })),
70
+ };
71
+ }
72
+
73
+ /**
74
+ * Provee el mecanismo que cierra el Hueco A de la revisión adversarial de T-09
75
+ * (C-3): verifica el binding commit↔tarballDigest re-empaquetando el tarball
76
+ * DESDE el commit certificado (efecto inyectado `reempaquetar`) y aseverando que
77
+ * su sha256 coincide con el `tarballDigest` del request. El cierre extremo-a-
78
+ * extremo requiere que el workflow del juez en `swl-eval` invoque esta primitiva
79
+ * contra el tarball descargado (fuera de este repo, gateado); aquí sólo vive la
80
+ * primitiva reusable, fail-closed. Sin ella, un dispatcher podría atar un
81
+ * `tarballDigest` benigno a un `commit` malicioso y el veredicto lo firmaría
82
+ * igual (el schema valida ambos campos por separado, nunca su correspondencia).
83
+ * Fail-closed: cualquier error de `reempaquetar` o cualquier mismatch lanza;
84
+ * nunca aprueba por omisión.
85
+ *
86
+ * @param {string} commit git HEAD (40 hex) del candidato certificado.
87
+ * @param {string} tarballDigestEsperado sha256 (64 hex) declarado en el request.
88
+ * @param {(commit:string)=>string} reempaquetar puerto de efecto: reconstruye el
89
+ * tarball desde el commit y devuelve su sha256 hex. Reproducible por diseño —
90
+ * npm >=7 normaliza mtimes, así que el mismo commit con la misma versión de npm
91
+ * produce el mismo digest; la costura de reproducibilidad se ancla en el tramo
92
+ * real (misma imagen de runner) igual que el golden bundle de DT-T06-BINDING.
93
+ * @returns {true} si el binding es válido; de lo contrario lanza.
94
+ */
95
+ function verificarBindingCommitTarball(commit, tarballDigestEsperado, reempaquetar) {
96
+ if (typeof commit !== 'string' || !GIT_SHA.test(commit)) {
97
+ fallar('TARBALL_COMMIT_BINDING_INVALID', 'commit inválido');
98
+ }
99
+ if (typeof tarballDigestEsperado !== 'string' || !SHA256.test(tarballDigestEsperado)) {
100
+ fallar('TARBALL_COMMIT_BINDING_INVALID', 'tarballDigest inválido');
101
+ }
102
+ if (typeof reempaquetar !== 'function') {
103
+ fallar('TARBALL_COMMIT_BINDING_INVALID', 'reempaquetar debe ser una función');
104
+ }
105
+ let digestReal;
106
+ try {
107
+ digestReal = reempaquetar(commit);
108
+ } catch (error) {
109
+ // Fail-closed: si el tarball no se puede reconstruir desde el commit, el
110
+ // binding NO está probado — nunca se acepta por omisión.
111
+ throw crearError(
112
+ 'TARBALL_COMMIT_BINDING_UNVERIFIABLE',
113
+ `no se pudo re-empaquetar desde ${commit}: ${error.message}`
114
+ );
115
+ }
116
+ if (typeof digestReal !== 'string' || !SHA256.test(digestReal)) {
117
+ fallar('TARBALL_COMMIT_BINDING_UNVERIFIABLE', 'reempaquetar no devolvió un sha256 válido');
118
+ }
119
+ if (digestReal !== tarballDigestEsperado) {
120
+ fallar('TARBALL_COMMIT_BINDING_MISMATCH', `el tarball del request no proviene de ${commit}`);
121
+ }
122
+ return true;
123
+ }
124
+
125
+ module.exports = {
126
+ construirRequest,
127
+ construirRequestEsperado,
128
+ verificarBindingCommitTarball,
129
+ ENTRYPOINT_DEFECTO,
130
+ SCHEMA_VERSION,
131
+ KIND,
132
+ };
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Revocación automática de la certificación (F32/T-12, REQ-32-12, ADR-0050).
5
+ * La etiqueta EXPIRA ante cualquier drift respecto a la matriz certificada
6
+ * (runtime/modelo/OS, commit del candidato, dataset/`tarballDigest`, o `seed`
7
+ * del corpus) o ante un canario fallido. Puro: sin `fs`/red/reloj; el efecto
8
+ * (leer el estado actual) vive en el caller.
9
+ *
10
+ * Reusa `evaluarGateCanario` (T-11) para la condición de canario — no
11
+ * reimplementa el gate. `evaluarRevocacion` NUNCA lanza: retorna
12
+ * `{revocado, motivos}` (motivos vacío ⇒ no revocado).
13
+ */
14
+
15
+ const { evaluarGateCanario } = require('./w4-canario');
16
+
17
+ function normalizarMatrix(matrix) {
18
+ return (Array.isArray(matrix) ? matrix : [])
19
+ .map((entrada) => `${entrada && entrada.runtime}|${entrada && entrada.os}|${entrada && entrada.model}`)
20
+ .sort();
21
+ }
22
+
23
+ function matrixDifiere(certificada, actual) {
24
+ return JSON.stringify(normalizarMatrix(certificada)) !== JSON.stringify(normalizarMatrix(actual));
25
+ }
26
+
27
+ /**
28
+ * @param {object} verdict - CertificationVerdict certificado (usa `.request`:
29
+ * commit, tarballDigest, matrix — la matriz certificada).
30
+ * @param {{commit?:string, tarballDigest?:string, matrix?:Array,
31
+ * seedFingerprintCertificado?:string, seedFingerprintActual?:string,
32
+ * canario?:unknown}} estadoActual - estado observado hoy. Cada campo es
33
+ * opcional: sólo se evalúa el drift de los campos provistos (un campo
34
+ * ausente no revoca por sí mismo — el caller decide qué observa).
35
+ * @returns {{revocado:boolean, motivos:string[]}}
36
+ */
37
+ function evaluarRevocacion(verdict, estadoActual = {}) {
38
+ const motivos = [];
39
+ const req = (verdict && typeof verdict === 'object' && verdict.request) || {};
40
+ const estado = (estadoActual && typeof estadoActual === 'object') ? estadoActual : {};
41
+
42
+ if (estado.commit !== undefined && estado.commit !== req.commit) {
43
+ motivos.push('commit-drift');
44
+ }
45
+ if (estado.tarballDigest !== undefined && estado.tarballDigest !== req.tarballDigest) {
46
+ motivos.push('dataset-drift');
47
+ }
48
+ if (estado.matrix !== undefined && matrixDifiere(req.matrix, estado.matrix)) {
49
+ motivos.push('matrix-drift');
50
+ }
51
+ if (estado.seedFingerprintCertificado !== undefined && estado.seedFingerprintActual !== undefined
52
+ && estado.seedFingerprintCertificado !== estado.seedFingerprintActual) {
53
+ motivos.push('seed-drift');
54
+ }
55
+ if (estado.canario !== undefined && evaluarGateCanario(estado.canario).certifica !== true) {
56
+ motivos.push('canario-fallido');
57
+ }
58
+
59
+ return { revocado: motivos.length > 0, motivos };
60
+ }
61
+
62
+ module.exports = { evaluarRevocacion };
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Constantes compartidas del corpus Core-3 (F32/W4): la lista canónica de
5
+ * runtimes soportados por certificación (ADR-0050) y los umbrales mínimos
6
+ * del gate de canario (T-11, REQ-32-11) que también consume el sub-check
7
+ * meta-SLO `canaryInput` (T-05, `scripts/lib/w4-scorer-certificacion.js`).
8
+ *
9
+ * Única fuente de estos literales — NUNCA replicarlos en otro módulo
10
+ * (`~/.claude/rules/arquitectura.md § DRY`). Antes de F32/T-11,
11
+ * `RUNTIMES_CORE3` vivía privado en `w4-scorer-certificacion.js` y los
12
+ * umbrales 1000/7 estaban inline en su sub-check `canaryInput`; ambos
13
+ * módulos ahora importan de aquí para que un cambio de umbral o de la
14
+ * lista de runtimes se propague en un solo lugar.
15
+ *
16
+ * Puro: cero `fs`/`net`/reloj/aleatoriedad.
17
+ */
18
+
19
+ const RUNTIMES_CORE3 = Object.freeze(['claude-code', 'codex-cli', 'gemini-cli']);
20
+
21
+ // Identificadores de OS (forma `process.platform`) de la matriz Core-3, en
22
+ // orden estable para la generación de combos del CertificationRequest (T-09).
23
+ // Los validadores que sólo checan pertenencia usan un `Set` derivado de esta
24
+ // lista en su propio módulo; esta es la fuente ordenada canónica.
25
+ const OS_CORE3 = Object.freeze(['win32', 'linux', 'darwin']);
26
+
27
+ // ADR-0050 § meta-SLO (párrafo tras la tabla de 6 dimensiones): "canary de
28
+ // al menos siete días y 1,000 sesiones de campo por runtime antes de
29
+ // certificar un release mayor del harness". Umbrales inclusivos (>=).
30
+ const SESIONES_MIN_CANARIO = 1000;
31
+ const DIAS_MIN_CANARIO = 7;
32
+
33
+ module.exports = Object.freeze({
34
+ RUNTIMES_CORE3,
35
+ OS_CORE3,
36
+ SESIONES_MIN_CANARIO,
37
+ DIAS_MIN_CANARIO,
38
+ });