@saulwade/swl-ses 2.5.3 → 2.6.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 (181) hide show
  1. package/CLAUDE.md +192 -192
  2. package/README.md +600 -600
  3. package/agentes/auto-evolucion-swl.md +27 -3
  4. package/bin/swl-ses.js +32 -7
  5. package/comandos/swl/actualizar.md +174 -174
  6. package/comandos/swl/adoptar-proyecto.md +265 -265
  7. package/comandos/swl/aprender.md +836 -823
  8. package/comandos/swl/aprobar-plan.md +146 -146
  9. package/comandos/swl/auditar-deps.md +134 -134
  10. package/comandos/swl/autoresearch.md +264 -264
  11. package/comandos/swl/ayuda.md +224 -224
  12. package/comandos/swl/brainstorm.md +51 -51
  13. package/comandos/swl/briefing.md +119 -119
  14. package/comandos/swl/checkpoint.md +325 -325
  15. package/comandos/swl/claudemd.md +234 -234
  16. package/comandos/swl/compactar.md +310 -310
  17. package/comandos/swl/configurar-ci.md +235 -235
  18. package/comandos/swl/contexto.md +110 -110
  19. package/comandos/swl/contribuir.md +233 -233
  20. package/comandos/swl/crear-skill.md +292 -292
  21. package/comandos/swl/cron.md +194 -194
  22. package/comandos/swl/deuda-codigo.md +97 -97
  23. package/comandos/swl/discutir-fase.md +169 -169
  24. package/comandos/swl/ejecutar-fase.md +233 -233
  25. package/comandos/swl/evaluar-skill.md +520 -505
  26. package/comandos/swl/evolucion-continua.md +73 -0
  27. package/comandos/swl/evolucionar.md +267 -254
  28. package/comandos/swl/exportar-vault.md +583 -583
  29. package/comandos/swl/fix.md +118 -118
  30. package/comandos/swl/gateway.md +158 -158
  31. package/comandos/swl/inbox.md +116 -116
  32. package/comandos/swl/instalar.md +220 -220
  33. package/comandos/swl/instintos.md +86 -86
  34. package/comandos/swl/mapear-codebase.md +312 -312
  35. package/comandos/swl/mcp-status.md +175 -175
  36. package/comandos/swl/modelo.md +100 -100
  37. package/comandos/swl/nemesis.md +433 -433
  38. package/comandos/swl/notificaciones.md +299 -299
  39. package/comandos/swl/nuevo-proyecto.md +251 -251
  40. package/comandos/swl/planear-fase.md +263 -263
  41. package/comandos/swl/plugins.md +256 -256
  42. package/comandos/swl/predecir.md +169 -169
  43. package/comandos/swl/reflect-skills.md +125 -125
  44. package/comandos/swl/release.md +450 -450
  45. package/comandos/swl/revisar-impacto.md +201 -201
  46. package/comandos/swl/revisar.md +330 -330
  47. package/comandos/swl/seguridad.md +189 -189
  48. package/comandos/swl/sesiones.md +200 -200
  49. package/comandos/swl/skill-search.md +113 -113
  50. package/comandos/swl/status.md +343 -343
  51. package/comandos/swl/verificar.md +817 -817
  52. package/comandos/swl/wiki.md +620 -620
  53. package/gateway/cron/jobs.example.json +12 -0
  54. package/habilidades/auto-evolucion-protocolo/SKILL.md +294 -276
  55. package/habilidades/autoresearch/SKILL.md +3 -2
  56. package/habilidades/benchmark-memoria/SKILL.md +7 -7
  57. package/habilidades/changelog-generator/SKILL.md +174 -174
  58. package/habilidades/changelog-generator/scripts/parse-commits.js +2 -1
  59. package/habilidades/checkpoints-verificacion/SKILL.md +6 -0
  60. package/habilidades/context-builder/SKILL.md +4 -0
  61. package/habilidades/doubt-driven-review/SKILL.md +207 -191
  62. package/habilidades/drift-detection/SKILL.md +6 -1
  63. package/habilidades/ejecutar-fase/SKILL.md +6 -6
  64. package/habilidades/eval-framework/SKILL.md +8 -3
  65. package/habilidades/harness-claude-code/SKILL.md +312 -308
  66. package/habilidades/infra-github-actions/SKILL.md +4 -3
  67. package/habilidades/instalar-sistema/SKILL.md +227 -223
  68. package/habilidades/memoria-busqueda/SKILL.md +31 -39
  69. package/habilidades/planear-fase/SKILL.md +358 -350
  70. package/habilidades/proceso-ddia-fundamentos/SKILL.md +3 -2
  71. package/habilidades/swl-claudemd/SKILL.md +6 -7
  72. package/habilidades/swl-dashboard/SKILL.md +11 -43
  73. package/habilidades/tdd-workflow/SKILL.md +749 -744
  74. package/habilidades/validacion-ci-sistema/SKILL.md +1 -1
  75. package/hooks/agente-lifecycle.js +2 -1
  76. package/hooks/aiisms-detector.js +13 -4
  77. package/hooks/audit-trail.js +2 -1
  78. package/hooks/auto-consolidacion.js +2 -1
  79. package/hooks/captura-acciones-post.js +2 -1
  80. package/hooks/captura-acciones-session.js +2 -1
  81. package/hooks/captura-feedback-usuario.js +3 -2
  82. package/hooks/claudemd-bloat-detector.js +12 -3
  83. package/hooks/claudemd-duplicacion-detector.js +13 -3
  84. package/hooks/contexto-iteracion.js +2 -1
  85. package/hooks/degradacion-instintos.js +2 -1
  86. package/hooks/extraccion-aprendizajes.js +109 -15
  87. package/hooks/grafo-contexto.js +2 -1
  88. package/hooks/guardrail-modelo.js +2 -1
  89. package/hooks/inbox-aviso.js +2 -1
  90. package/hooks/inyeccion-contexto.js +2 -1
  91. package/hooks/lib/agent-matcher.js +2 -1
  92. package/hooks/lib/agent-routing.js +2 -1
  93. package/hooks/lib/autonomia.js +5 -3
  94. package/hooks/lib/captura-acciones.js +2 -1
  95. package/hooks/lib/consolidation-lock.js +21 -10
  96. package/hooks/lib/etapa-auto-evolucion.js +10 -4
  97. package/hooks/lib/etapa-metricas.js +2 -1
  98. package/hooks/lib/etapa-perfil-usuario.js +20 -4
  99. package/hooks/lib/evolution-tracker.js +2 -1
  100. package/hooks/lib/gateway-notify.js +193 -179
  101. package/hooks/lib/loop-telemetry.js +5 -4
  102. package/hooks/lib/mcp-health.js +2 -1
  103. package/hooks/lib/memory-search.js +4 -0
  104. package/hooks/lib/merkle-audit.js +58 -6
  105. package/hooks/lib/nudge-tracker.js +2 -1
  106. package/hooks/lib/otlp-exporter.js +2 -1
  107. package/hooks/lib/propose-step.js +3 -2
  108. package/hooks/lib/raiz-proyecto.js +102 -0
  109. package/hooks/lib/run-log.js +2 -1
  110. package/hooks/lib/singleton-guard.js +218 -27
  111. package/hooks/lib/telegram-cliente.js +17 -8
  112. package/hooks/preservar-estado-pre-compact.js +2 -1
  113. package/hooks/proteccion-rutas.js +59 -3
  114. package/hooks/registro-turnos.js +2 -1
  115. package/hooks/resumen-sesion.js +2 -1
  116. package/hooks/risk-scoring.js +2 -1
  117. package/hooks/rotar-audit-auto.js +46 -20
  118. package/hooks/session-briefing.js +127 -1
  119. package/hooks/spec-gate.js +2 -1
  120. package/hooks/sugerir-contribuir.js +6 -3
  121. package/hooks/sugerir-regenerar-inventario.js +3 -2
  122. package/hooks/tdd-gate.js +2 -1
  123. package/hooks/telemetria-agentes.js +2 -1
  124. package/hooks/telemetria-skill-routing.js +2 -1
  125. package/hooks/tracking-costos.js +4 -3
  126. package/hooks/validar-formato-post-subagente.js +2 -1
  127. package/hooks/validar-intent-spec.js +2 -1
  128. package/hooks/validar-memoria-hook.js +13 -3
  129. package/hooks/validar-planning-paths.js +2 -1
  130. package/instintos/.backups/perfil-usuario.yaml.2026-07-10-165128.bak +53 -0
  131. package/instintos/.backups/proyecto.yaml.2026-07-10-165128.bak +372 -0
  132. package/instintos/perfil-usuario.yaml +506 -3
  133. package/instintos/proyecto.yaml +78 -0
  134. package/llms.txt +2 -2
  135. package/manifiestos/canonical-hashes.json +335 -3
  136. package/manifiestos/modulos.json +19 -14
  137. package/manifiestos/planning-paths.json +1 -0
  138. package/manifiestos/skills-lock.json +50 -50
  139. package/package.json +2 -3
  140. package/plugin.json +2 -2
  141. package/scripts/actualizar.js +3 -0
  142. package/scripts/auditar-clases-conocidas.js +32 -4
  143. package/scripts/benchmark-memoria.js +1 -0
  144. package/scripts/cli/autonomia.js +23 -0
  145. package/scripts/cli/benchmark-memoria.js +37 -0
  146. package/scripts/cli/ciclo-autonomo.js +73 -0
  147. package/scripts/cli/ciclo-fase-b.js +102 -0
  148. package/scripts/cli/guardrail-metrics.js +39 -0
  149. package/scripts/cli/loop-telemetry.js +4 -2
  150. package/scripts/cli/memoria-search.js +69 -0
  151. package/scripts/cli/nudge-accionar.js +39 -0
  152. package/scripts/cli/run-eval.js +38 -0
  153. package/scripts/cli/run-skill-evals.js +13 -2
  154. package/scripts/derivar-feature-list.js +15 -14
  155. package/scripts/desinstalar.js +11 -0
  156. package/scripts/doctor.js +24 -10
  157. package/scripts/instalador.js +85 -7
  158. package/scripts/lib/activar-hooks-proyecto.js +12 -0
  159. package/scripts/lib/auditar-invocaciones-comandos.js +96 -6
  160. package/scripts/lib/ciclo-autonomo/candidatos.js +174 -0
  161. package/scripts/lib/ciclo-autonomo/config.js +165 -0
  162. package/scripts/lib/ciclo-autonomo/drenador-feedback.js +174 -0
  163. package/scripts/lib/ciclo-autonomo/fallback.js +77 -0
  164. package/scripts/lib/ciclo-autonomo/guard-convivencia.js +139 -0
  165. package/scripts/lib/ciclo-autonomo/higiene-nudges.js +112 -0
  166. package/scripts/lib/ciclo-autonomo/index.js +301 -0
  167. package/scripts/lib/ciclo-autonomo/lock.js +124 -0
  168. package/scripts/lib/ciclo-autonomo/presupuesto.js +122 -0
  169. package/scripts/lib/ciclo-autonomo/puente-degradacion.js +240 -0
  170. package/scripts/lib/ciclo-autonomo/runner-fase-b.js +248 -0
  171. package/scripts/lib/ciclo-autonomo/writer-instintos.js +190 -0
  172. package/scripts/lib/ciclo-autonomo/yaml-instintos.js +535 -0
  173. package/scripts/lib/estado.js +9 -0
  174. package/scripts/lib/gitignore-manifest.js +8 -1
  175. package/scripts/lib/hooks-settings.js +45 -0
  176. package/scripts/rotar-audit-logs.js +48 -2
  177. package/scripts/run-eval.js +1 -0
  178. package/scripts/run-skill-evals.js +287 -8
  179. package/scripts/smoke-test.js +16 -8
  180. package/scripts/tui/pantallas/install-wizard.js +403 -347
  181. package/scripts/validar.js +40 -1
@@ -1,450 +1,450 @@
1
- ---
2
- name: swl:release
3
- description: Gestión del ciclo de release del proyecto. Genera versión siguiendo SemVer, crea changelog automático desde commits con Conventional Commits, valida que los tests pasan, crea tag de git y genera release notes. Flags: --tipo=patch|minor|major, --dry-run, --skip-tests.
4
- allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
5
- ---
6
-
7
- # /swl:release — Gestión del ciclo de release
8
-
9
- Eres el gestor de releases del proyecto. Orquestas el proceso completo de crear una nueva versión: calcular el número de versión, recopilar cambios, validar estado publicable y crear artefactos de release.
10
-
11
- **Carga**: `Skill("release-semver")` — contiene las reglas de SemVer, Conventional Commits, estrategia de tags y proceso detallado de release. Delega toda lógica de versionado al skill.
12
-
13
- ## Cuándo usar este comando
14
-
15
- - Al completar un conjunto de features o fixes listos para producción
16
- - Al final de un sprint cuando hay cambios acumulados
17
- - Para hotfixes críticos (patch release)
18
- - Antes de una demo o entrega a cliente
19
-
20
- ## Flags soportados
21
-
22
- ```
23
- --tipo=patch Incrementa PATCH (0.0.X) — bugs y correcciones menores
24
- --tipo=minor Incrementa MINOR (0.X.0) — features nuevas sin breaking changes
25
- --tipo=major Incrementa MAJOR (X.0.0) — breaking changes
26
- --dry-run Muestra qué haría sin ejecutar nada
27
- --skip-tests Omite tests. Requiere justificación y confirmación explícita.
28
- ```
29
-
30
- Si no se pasa `--tipo`, se determina automáticamente según los commits (ver skill).
31
-
32
- ## Paso 0 — Verificación de prerrequisitos
33
-
34
- ```bash
35
- git rev-parse --is-inside-work-tree 2>&1
36
- git branch --show-current
37
- git status --porcelain
38
- git remote -v
39
- ```
40
-
41
- - Si hay cambios sin commitear, DETENER y listar archivos pendientes.
42
- - Si la rama no es la principal, advertir y pedir confirmación.
43
-
44
- ## Paso 1 — Leer versión actual
45
-
46
- ```bash
47
- cat package.json 2>/dev/null | grep '"version"' | head -1
48
- cat pyproject.toml 2>/dev/null | grep "^version" | head -1
49
- cat VERSION 2>/dev/null
50
- git describe --tags --abbrev=0 2>/dev/null || echo "Sin tags previos"
51
- ```
52
-
53
- Si hay múltiples fuentes, pedir al usuario que confirme la canónica. Sin versión en ningún lugar: `0.0.0`.
54
-
55
- ## Paso 2 — Recopilar y clasificar commits
56
-
57
- ```bash
58
- LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
59
- if [ -z "$LAST_TAG" ]; then
60
- git log --oneline --format="%H %s"
61
- else
62
- git log --oneline --format="%H %s" ${LAST_TAG}..HEAD
63
- fi
64
- ```
65
-
66
- Clasifica cada commit según Conventional Commits (tipos y su impacto en versión definidos en `Skill("release-semver")`).
67
-
68
- ## Paso 3 — Calcular tipo de versión
69
-
70
- Si no se especificó `--tipo`, usar reglas del skill:
71
- - Breaking change en algún commit -> MAJOR
72
- - feat: sin breaking changes -> MINOR
73
- - Cualquier otro caso -> PATCH
74
-
75
- Si el usuario pasó `--tipo` y hay discrepancia (ej: breaking changes con --tipo=patch), advertir y pedir confirmación.
76
-
77
- ## Paso 4 — Calcular nueva versión
78
-
79
- Aplica reglas SemVer del skill: MAJOR resets MINOR y PATCH a 0, MINOR resets PATCH a 0.
80
-
81
- Si `--dry-run`, mostrar preview del changelog y terminar sin modificar nada.
82
-
83
- ## Paso 5 — Ejecutar tests
84
-
85
- Si NO se pasó `--skip-tests`, detectar runner y ejecutar:
86
-
87
- ```bash
88
- ls package.json pytest.ini setup.cfg pyproject.toml Makefile 2>/dev/null
89
- npm test 2>&1 || pytest 2>&1 || make test 2>&1
90
- ```
91
-
92
- Si fallan, DETENER. Si `--skip-tests`, pedir confirmación explícita ("confirmo").
93
-
94
- ## Paso 6 — Actualizar archivos de versión
95
-
96
- Actualiza la versión en TODOS los archivos que la contienen. Para proyectos SWL-SES, la checklist obligatoria es:
97
-
98
- ```
99
- [ ] package.json
100
- [ ] package-lock.json (2 ubicaciones: líneas 3 y 9)
101
- [ ] plugin.json
102
- [ ] CLAUDE.md
103
- [ ] README.md
104
- [ ] AGENTS.md
105
- [ ] COMANDOS.md
106
- [ ] MANUAL_USO.md
107
- [ ] INSTALACION.md
108
- [ ] SALUD.md
109
- [ ] INVENTARIO.md
110
- [ ] CHANGELOG.md (entrada nueva)
111
- [ ] .planning/COMPACTACION.md
112
- [ ] .planning/ESTADO.md
113
- [ ] .swl-install-state.json (si existe)
114
- ```
115
-
116
- Para proyectos no-SWL: actualiza los archivos detectados en Paso 1 (package.json, pyproject.toml, VERSION).
117
-
118
- ### Tres capas de versionado — NO confundir
119
-
120
- El sistema SWL versiona en tres capas independientes. El bump de versión del SISTEMA toca SOLO la capa 1:
121
-
122
- | Capa | Qué versiona | Cuándo cambia | Tocar en `/swl:release`? |
123
- |------|--------------|---------------|--------------------------|
124
- | **1. Sistema** | El paquete `@saulwade/swl-ses` como conjunto | En cada release | **SÍ — los 15 archivos del checklist arriba** |
125
- | **2. Componente individual** | Frontmatter `version:` de cada agente o skill (`agentes/*.md`, `habilidades/*/SKILL.md`) | Cuando el componente específico cambia (ver `/swl:aprender` Paso 6 acción 2) | **NO — cada componente versiona independiente** |
126
- | **3. Histórico** | Referencias a versiones pasadas en `CHANGELOG.md`, `CHANGELOG-LEGACY.md`, ADRs, RELEASE-NOTES, comentarios `Histórico: hasta vX.Y...` | Nunca (son inmutables por definición) | **NO — son registros históricos** |
127
-
128
- Verificación post-bump con `grep -rn "<versión-anterior>"` revelará decenas o cientos de matches en capas 2 y 3 — eso es esperado y correcto. Filtrar ruido para confirmar que las únicas líneas modificadas son de la capa 1:
129
-
130
- ```bash
131
- # Después del bump, validar consistencia SOLO en archivos canónicos del sistema
132
- node -e "
133
- const p=require('./package.json'),l=require('./plugin.json');
134
- const lock=require('./package-lock.json');
135
- const ok = p.version===l.version && l.version===lock.version;
136
- console.log(ok ? 'OK consistente: '+p.version : 'INCONSISTENTE');
137
- "
138
- ```
139
-
140
- Si el chequeo del nodo arriba dice OK pero `grep` aún muestra matches de la versión anterior, esos matches son **capa 2 (frontmatter)** o **capa 3 (histórico)** y son legítimos — no tocarlos.
141
-
142
- ### Republish-only entre registries (caso especial)
143
-
144
- Si el publish dual falla en uno de los 2 registries (typically npmjs o GitHub
145
- Packages) pero el otro queda publicado, **NO se puede reintentar la misma versión**
146
- — ningún registry permite sobreescribir versiones. Ejecutar inmediatamente un bump
147
- PATCH (1.X.Y → 1.X.(Y+1)) siguiendo el checklist arriba, y publicar solo al
148
- registry faltante con `node scripts/publicar.js --solo-npmjs` o `--solo-github`.
149
-
150
- Documentar el republish exclusivamente como "republish de coordinación entre
151
- registries" en CHANGELOG, sin atribuirle cambios funcionales que no existen.
152
-
153
- Ver `Skill("release-semver")` sección "Publish a múltiples registries" para detalles.
154
-
155
- ## Paso 6.5 — Regenerar skills-lock.json
156
-
157
- Antes del CHANGELOG, regenerar el lock de skills para capturar el estado de
158
- los 151 SKILL.md de la release:
159
-
160
- ```bash
161
- node scripts/generar-skills-lock.js
162
- git add manifiestos/skills-lock.json
163
- ```
164
-
165
- El lock contiene SHA256 de cada SKILL.md y permite que `/swl:status salud` detecte
166
- drift silencioso entre releases. Si el lock no cambió respecto al anterior,
167
- el commit lo refleja como no-op (idempotente). El archivo es pequeño (~37KB)
168
- y debe versionarse.
169
-
170
- ## Paso 6.6 — Regenerar canonical-hashes.json (baseline del discriminador A/B)
171
-
172
- Regenerar el manifiesto de hashes canónicos para la versión nueva. Es la baseline
173
- que el instalador usa (Fase 16) para distinguir evolución del usuario (merge) de
174
- shipped-evolved (actualizable) en cada upgrade. Debe incluir la versión que se
175
- publica para que clientes que evolucionen desde ella se clasifiquen bien.
176
-
177
- ```bash
178
- node scripts/generar-canonical-hashes.js
179
- git add manifiestos/canonical-hashes.json
180
- ```
181
-
182
- Idempotente (no-op si no cambió). El gate `node scripts/verificar-release.js`
183
- (Paso 10.1) verifica que el manifiesto esté al día y que el fuente no porte
184
- marcadores `evolved` espurios — si falla, ejecutar
185
- `node scripts/verificar-evolucion.js --gate-inverso --fix`. El test e2e
186
- `tests/scripts/release-e2e-evolved.test.js` (en `npm test`) bloquea el release
187
- si la propagación A/B regresa.
188
-
189
- ## Paso 7 — Generar CHANGELOG
190
-
191
- Desde v1.6.5 este paso usa el skill `changelog-generator` para parsear
192
- Conventional Commits y producir el bloque listo para insertar (ADR-0029).
193
-
194
- ### Paso 7.1 — Cargar skill y previsualizar
195
-
196
- ```
197
- Skill("changelog-generator")
198
- ```
199
-
200
- Ejecutar el parser determinista contra los commits del rango actual:
201
-
202
- ```bash
203
- node habilidades/changelog-generator/scripts/parse-commits.js \
204
- --from <tag-anterior> --to HEAD --version <nueva-version> --format markdown
205
- ```
206
-
207
- El script imprime el bloque markdown listo para insertar Y reporta a stderr
208
- el ratio de conformidad Conventional Commits. Categorías generadas en orden
209
- canónico: Breaking changes → Nuevas funcionalidades → Correcciones →
210
- Mejoras de rendimiento → Cambios internos → Reversiones → Evoluciones de
211
- skills/agentes → Mantenimiento → Otros.
212
-
213
- ### Paso 7.2 — Gate de conformidad
214
-
215
- Verificar la conformidad (impresa a stderr o vía `--format json`):
216
-
217
- - **>= 80% conformidad**: continuar a 7.3.
218
- - **< 80% conformidad**: detenerse y reportar al usuario los commits caídos
219
- bajo "Otros". Pedir decisión:
220
- 1. Continuar con el bloque generado (los "Otros" quedan al final del CHANGELOG).
221
- 2. Abortar release y reescribir commits no conformes (`git rebase -i`).
222
- 3. Editar manualmente la sección "Otros" antes de insertar.
223
-
224
- NO continuar automáticamente con conformidad baja — el changelog público
225
- queda confuso.
226
-
227
- ### Paso 7.3 — Insertar en CHANGELOG.md
228
-
229
- Leer `CHANGELOG.md` actual:
230
- - Si no existe: crear con header `# Changelog\n\n` y luego el bloque nuevo.
231
- - Si existe: insertar el bloque nuevo inmediatamente después del header
232
- `# Changelog` (antes de la entrada anterior).
233
-
234
- Escritura atómica obligatoria (regla CLAUDE.md). Usar `atomicWriteSync` desde
235
- `hooks/lib/atomic-write.js` cuando se llame programáticamente.
236
-
237
- ### Paso 7.4 — Verificar entrada generada
238
-
239
- ```bash
240
- head -40 CHANGELOG.md
241
- ```
242
-
243
- Confirmar:
244
- - Header `## [<nueva-version>] - YYYY-MM-DD` presente.
245
- - Categorías generadas tienen contenido coherente con los commits del rango.
246
- - Breaking changes (si los hay) aparecen al inicio.
247
-
248
- ### Fallback manual (legacy v1.6.4 y anterior)
249
-
250
- Si el parser falla o el skill no está disponible, mantener el flujo manual
251
- de versiones previas:
252
- - Secciones: Funcionalidades nuevas, Correcciones, Mejoras de rendimiento,
253
- Cambios internos, Breaking Changes, Estadísticas.
254
- - Descripciones legibles por humanos (sin prefijo feat:/fix:).
255
- - Omitir commits style: y test: del changelog público.
256
-
257
- ## Paso 8 — Commit de release y tag
258
-
259
- ```bash
260
- git add package.json pyproject.toml setup.py VERSION CHANGELOG.md 2>/dev/null
261
- git commit -m "chore(release): versión [nueva-versión]"
262
- git tag -a "v[nueva-versión]" -m "Release v[nueva-versión]"
263
- ```
264
-
265
- Usar tags anotados siempre (regla del skill).
266
-
267
- ## Paso 9 — Generar RELEASE-NOTES
268
-
269
- Crea `releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md` con: resumen,
270
- cambios, instrucciones de actualización y guía de migración si hay breaking changes.
271
-
272
- ```bash
273
- mkdir -p releases/v[nueva-versión]
274
- # escribir releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md
275
- ```
276
-
277
- **NUNCA crear las RELEASE-NOTES en la raíz del repo.** La convención (todos los
278
- releases previos en `releases/`) es que las RELEASE-NOTES viven SOLO en
279
- `releases/vX.Y.Z/` — no se versiona ninguna copia en raíz. El directorio
280
- `releases/v[nueva-versión]/` también lo crea `evidencia-release.js` (Paso 9.5);
281
- si ese paso corre primero, el `mkdir -p` es no-op.
282
-
283
- ## Paso 9.5 — Evidencia de procedencia (cadena de suministro, ADR-0038)
284
-
285
- Genera la evidencia de cadena de suministro del release: SBOM CycloneDX del
286
- árbol runtime + SHA256SUMS del tarball. No publica nada; produce artefactos
287
- versionados en `releases/v[nueva-versión]/`.
288
-
289
- ```bash
290
- node scripts/lib/evidencia-release.js --version [nueva-versión]
291
- ```
292
-
293
- Esto escribe (vía `scripts/lib/evidencia-release.js`):
294
- - `releases/v[nueva-versión]/sbom-v[nueva-versión].cdx.json` — SBOM CycloneDX
295
- runtime-only (`npm sbom --sbom-format cyclonedx --omit dev`).
296
- - `releases/v[nueva-versión]/SHA256SUMS` — checksum del tarball de `npm pack`.
297
-
298
- Luego:
299
-
300
- 1. **Insertar la sección "Integridad y verificación"** en
301
- `releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md`, justo después de
302
- la sección de correcciones. La genera `seccionVerificacionNotas` de la lib:
303
-
304
- ```bash
305
- node -e "const {seccionVerificacionNotas}=require('./scripts/lib/evidencia-release');const fs=require('fs');const v='[nueva-versión]';const sums=fs.readFileSync('releases/v'+v+'/SHA256SUMS','utf8').trim().split(/\s+/);const md=seccionVerificacionNotas({version:v,hash:sums[0],tarball:sums[1]});console.log(md)"
306
- ```
307
-
308
- Anexar ese markdown a `releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md`
309
- (tras "Correcciones").
310
-
311
- 2. **Versionar la evidencia** del release. Las RELEASE-NOTES ya viven en
312
- `releases/v[nueva-versión]/` (Paso 9) — NO hacer `cp` desde la raíz (no debe
313
- existir copia en raíz):
314
-
315
- ```bash
316
- git add releases/v[nueva-versión]/
317
- ```
318
-
319
- `releases/` NO viaja en el tarball npm (`package.json#files` es allowlist y no
320
- lo incluye) — es evidencia del repo, no del paquete. Verificar con
321
- `npm pack --dry-run | grep -c "releases/"` → debe ser `0`.
322
-
323
- **Provenance (opt-in)**: el publish default sigue siendo local
324
- (`scripts/publicar.js`). Para publicar a npmjs con `npm publish --provenance`
325
- (que exige OIDC desde CI) usar el workflow opt-in
326
- `.github/workflows/publish-npm.yml` (trigger `workflow_dispatch`, `dry_run`
327
- default true). GitHub Packages permanece local. Runbook de verificación para
328
- el consumidor: `docs/verificacion-consumidor.md`.
329
-
330
- ## Paso 10 — Verificación final
331
-
332
- ### 10.1 Gate automática anti-gap (OBLIGATORIA antes del push)
333
-
334
- Ejecutar `scripts/verificar-release.js` que valida que la versión nueva esté reflejada en las 14 ubicaciones canónicas de la checklist (y avisa sobre MANUAL_USO opcional):
335
-
336
- ```bash
337
- node scripts/verificar-release.js
338
- ```
339
-
340
- Exit codes:
341
- - `0` — todas las ubicaciones obligatorias con la versión correcta, puedes continuar al push
342
- - `1` — al menos un archivo quedó en versión anterior. **NO hacer push hasta corregir**. El reporte indica el archivo y el problema específico
343
- - `2` — error de invocación (package.json ausente, versión inválida)
344
-
345
- Ejemplo de output en éxito:
346
- ```
347
- [OK] package.json: version=5.10.5
348
- [OK] plugin.json: version=5.10.5
349
- [OK] package-lock.json: version=5.10.5, packages[""].version=5.10.5
350
- ...
351
- [OK] CHANGELOG.md: seccion [5.10.5] presente con fecha
352
- Resultado: 14/15 OK, 1 WARN opcional(es)
353
- ```
354
-
355
- Ejemplo de output en fallo que obliga a corregir:
356
- ```
357
- [FALLA] .planning/MAPEO_SKILLS_AGENTES.md: solo 0 ocurrencia(s) de 5.10.5 (minimo 1)
358
- [FALLA] README.md: primera linea no menciona 5.10.5 — actual: "# swl-software-engineering-system v5.10.4"
359
- Resultado: 13/15 OK, 2 FALLA(S) obligatoria(s)
360
- ```
361
-
362
- Esta gate existe porque el agente `release-manager-swl` ha omitido archivos en 3 releases consecutivos (5.10.3, 5.10.4, 5.10.5 — ver APRENDIZAJES.md) pese a tener la checklist documentada en su frontmatter. Un checklist textual no basta: se necesita ejecución.
363
-
364
- ### 10.1.1 Gate de cobertura por lenguaje (regeneración obligatoria)
365
-
366
- Tras el verificar-release.js, regenerar la matriz lenguaje × cobertura SWL:
367
-
368
- ```bash
369
- node scripts/generar-matriz-lenguajes.js
370
- ```
371
-
372
- El script reescribe `.planning/cobertura-lenguajes.md` con el estado actual.
373
- Comparar contra el commit anterior:
374
-
375
- ```bash
376
- git diff .planning/cobertura-lenguajes.md
377
- ```
378
-
379
- Si algún lenguaje **bajó de status** (completo → parcial, parcial → faltante)
380
- sin ADR documentado en `.planning/adrs/` justificando la regresión, **NO hacer
381
- release**. La regresión silenciosa de cobertura erosiona la promesa "polyglot"
382
- del repo.
383
-
384
- Si el cambio es esperado (eliminación deliberada de un componente), el ADR
385
- debe existir con número y fecha y referenciarse en el commit del release.
386
-
387
- Lo mismo aplica para releases con incremento de cobertura: la nueva matriz se
388
- commitea junto al release y se menciona en RELEASE-NOTES.
389
-
390
- ### 10.2 Verificación manual post-gate
391
-
392
- ```bash
393
- git tag -l "v[nueva-versión]"
394
- git log --oneline -3
395
- head -30 CHANGELOG.md
396
- ```
397
-
398
- ## Paso 11 — Reporte final
399
-
400
- ```
401
- === Release v[nueva-versión] completado ===
402
-
403
- Versión anterior: v[versión-anterior]
404
- Nueva versión: v[nueva-versión]
405
- Tipo: [PATCH | MINOR | MAJOR]
406
-
407
- Archivos actualizados: [lista]
408
- Git: Commit [hash], Tag v[nueva-versión]
409
- Commits incluidos: [N] (feat: [N], fix: [N], otros: [N])
410
- Tests: [ejecutados OK | omitidos (--skip-tests)]
411
-
412
- Próximos pasos:
413
- 1. Revisar releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md
414
- 2. git push origin v[nueva-versión]
415
- 3. Publicar release en GitHub/GitLab si aplica
416
- 4. Notificar al equipo
417
- ```
418
-
419
- ## Reglas de comportamiento
420
-
421
- - NUNCA crear release con repositorio dirty.
422
- - NUNCA omitir actualización de archivos de versión — inconsistencias causan errores de build.
423
- - NUNCA usar `--skip-tests` sin documentarlo en CHANGELOG y sin confirmación.
424
- - Si tipo calculado es MAJOR pero usuario pidió --tipo=patch, reportar discrepancia y esperar confirmación.
425
- - CHANGELOG legible por alguien que no conoce el código.
426
- - Si es monorepo, reportar que no se soporta y sugerir lerna/changesets.
427
- - **Crear el tag anotado AL FINAL del proceso, cuando el contenido está congelado
428
- y verificado** (tras evidencia + RELEASE-NOTES). Commitear ENCIMA de un tag de
429
- release ya creado pero aún-no-publicado obliga a mover el tag + regenerar la
430
- evidencia (el SHA del tarball cambia si el commit toca archivos de
431
- `package.json#files`) — churn evitable. Si hay que iterar, hacerlo antes de taggear.
432
- - **Si el usuario alimenta archivos de forma incremental para la MISMA versión
433
- ("faltan N archivos que agregar a esta versión, espera"), NO finalizar el
434
- release** (no congelar tag, no regenerar evidencia final, no proponer push)
435
- hasta que el usuario confirme que ya están TODOS los archivos. Mantener el
436
- commit de release como HEAD entre tandas para que cada incorporación sea un
437
- `amend` limpio + mover tag; regenerar la evidencia (SBOM/SHA256SUMS) SOLO en la
438
- última tanda, porque el SHA del tarball cambia con cada archivo nuevo que entre
439
- en `package.json#files`. Cerrar el release antes de tiempo obliga a rehacer
440
- evidencia y tag por cada archivo tardío.
441
- - **El agente NUNCA corre `npm` (test/pack/build/publish) en paralelo a un
442
- `npm run publish:*` que está ejecutando el usuario.** `test:release` incluye
443
- `test:smoke` (install/uninstall a temp + lectura de estado global); dos suites
444
- simultáneas colisionan y rompen `prepublishOnly` con fallos espurios que parecen
445
- bugs de test pero son concurrencia. La preparación del release (bump, manifests,
446
- evidencia, push, GitHub release) termina ANTES de que el usuario publique; durante
447
- el publish del usuario, el agente no ejecuta `npm`.
448
- - Si `prepublishOnly` falla y no se ve la causa: npm v10 NO guarda el stdout del
449
- script fallido en su debug log. Capturar con el log síncrono de `publicar.js`
450
- (`.planning/logs/publish-<v>-<ts>.log`) o `... *>&1 | Tee-Object`. No diagnosticar a ciegas.
1
+ ---
2
+ name: swl:release
3
+ description: Gestión del ciclo de release del proyecto. Genera versión siguiendo SemVer, crea changelog automático desde commits con Conventional Commits, valida que los tests pasan, crea tag de git y genera release notes. Flags: --tipo=patch|minor|major, --dry-run, --skip-tests.
4
+ allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
5
+ ---
6
+
7
+ # /swl:release — Gestión del ciclo de release
8
+
9
+ Eres el gestor de releases del proyecto. Orquestas el proceso completo de crear una nueva versión: calcular el número de versión, recopilar cambios, validar estado publicable y crear artefactos de release.
10
+
11
+ **Carga**: `Skill("release-semver")` — contiene las reglas de SemVer, Conventional Commits, estrategia de tags y proceso detallado de release. Delega toda lógica de versionado al skill.
12
+
13
+ ## Cuándo usar este comando
14
+
15
+ - Al completar un conjunto de features o fixes listos para producción
16
+ - Al final de un sprint cuando hay cambios acumulados
17
+ - Para hotfixes críticos (patch release)
18
+ - Antes de una demo o entrega a cliente
19
+
20
+ ## Flags soportados
21
+
22
+ ```
23
+ --tipo=patch Incrementa PATCH (0.0.X) — bugs y correcciones menores
24
+ --tipo=minor Incrementa MINOR (0.X.0) — features nuevas sin breaking changes
25
+ --tipo=major Incrementa MAJOR (X.0.0) — breaking changes
26
+ --dry-run Muestra qué haría sin ejecutar nada
27
+ --skip-tests Omite tests. Requiere justificación y confirmación explícita.
28
+ ```
29
+
30
+ Si no se pasa `--tipo`, se determina automáticamente según los commits (ver skill).
31
+
32
+ ## Paso 0 — Verificación de prerrequisitos
33
+
34
+ ```bash
35
+ git rev-parse --is-inside-work-tree 2>&1
36
+ git branch --show-current
37
+ git status --porcelain
38
+ git remote -v
39
+ ```
40
+
41
+ - Si hay cambios sin commitear, DETENER y listar archivos pendientes.
42
+ - Si la rama no es la principal, advertir y pedir confirmación.
43
+
44
+ ## Paso 1 — Leer versión actual
45
+
46
+ ```bash
47
+ cat package.json 2>/dev/null | grep '"version"' | head -1
48
+ cat pyproject.toml 2>/dev/null | grep "^version" | head -1
49
+ cat VERSION 2>/dev/null
50
+ git describe --tags --abbrev=0 2>/dev/null || echo "Sin tags previos"
51
+ ```
52
+
53
+ Si hay múltiples fuentes, pedir al usuario que confirme la canónica. Sin versión en ningún lugar: `0.0.0`.
54
+
55
+ ## Paso 2 — Recopilar y clasificar commits
56
+
57
+ ```bash
58
+ LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null)
59
+ if [ -z "$LAST_TAG" ]; then
60
+ git log --oneline --format="%H %s"
61
+ else
62
+ git log --oneline --format="%H %s" ${LAST_TAG}..HEAD
63
+ fi
64
+ ```
65
+
66
+ Clasifica cada commit según Conventional Commits (tipos y su impacto en versión definidos en `Skill("release-semver")`).
67
+
68
+ ## Paso 3 — Calcular tipo de versión
69
+
70
+ Si no se especificó `--tipo`, usar reglas del skill:
71
+ - Breaking change en algún commit -> MAJOR
72
+ - feat: sin breaking changes -> MINOR
73
+ - Cualquier otro caso -> PATCH
74
+
75
+ Si el usuario pasó `--tipo` y hay discrepancia (ej: breaking changes con --tipo=patch), advertir y pedir confirmación.
76
+
77
+ ## Paso 4 — Calcular nueva versión
78
+
79
+ Aplica reglas SemVer del skill: MAJOR resets MINOR y PATCH a 0, MINOR resets PATCH a 0.
80
+
81
+ Si `--dry-run`, mostrar preview del changelog y terminar sin modificar nada.
82
+
83
+ ## Paso 5 — Ejecutar tests
84
+
85
+ Si NO se pasó `--skip-tests`, detectar runner y ejecutar:
86
+
87
+ ```bash
88
+ ls package.json pytest.ini setup.cfg pyproject.toml Makefile 2>/dev/null
89
+ npm test 2>&1 || pytest 2>&1 || make test 2>&1
90
+ ```
91
+
92
+ Si fallan, DETENER. Si `--skip-tests`, pedir confirmación explícita ("confirmo").
93
+
94
+ ## Paso 6 — Actualizar archivos de versión
95
+
96
+ Actualiza la versión en TODOS los archivos que la contienen. Para proyectos SWL-SES, la checklist obligatoria es:
97
+
98
+ ```
99
+ [ ] package.json
100
+ [ ] package-lock.json (2 ubicaciones: líneas 3 y 9)
101
+ [ ] plugin.json
102
+ [ ] CLAUDE.md
103
+ [ ] README.md
104
+ [ ] AGENTS.md
105
+ [ ] COMANDOS.md
106
+ [ ] MANUAL_USO.md
107
+ [ ] INSTALACION.md
108
+ [ ] SALUD.md
109
+ [ ] INVENTARIO.md
110
+ [ ] CHANGELOG.md (entrada nueva)
111
+ [ ] .planning/COMPACTACION.md
112
+ [ ] .planning/ESTADO.md
113
+ [ ] .swl-install-state.json (si existe)
114
+ ```
115
+
116
+ Para proyectos no-SWL: actualiza los archivos detectados en Paso 1 (package.json, pyproject.toml, VERSION).
117
+
118
+ ### Tres capas de versionado — NO confundir
119
+
120
+ El sistema SWL versiona en tres capas independientes. El bump de versión del SISTEMA toca SOLO la capa 1:
121
+
122
+ | Capa | Qué versiona | Cuándo cambia | Tocar en `/swl:release`? |
123
+ |------|--------------|---------------|--------------------------|
124
+ | **1. Sistema** | El paquete `@saulwade/swl-ses` como conjunto | En cada release | **SÍ — los 15 archivos del checklist arriba** |
125
+ | **2. Componente individual** | Frontmatter `version:` de cada agente o skill (`agentes/*.md`, `habilidades/*/SKILL.md`) | Cuando el componente específico cambia (ver `/swl:aprender` Paso 6 acción 2) | **NO — cada componente versiona independiente** |
126
+ | **3. Histórico** | Referencias a versiones pasadas en `CHANGELOG.md`, `CHANGELOG-LEGACY.md`, ADRs, RELEASE-NOTES, comentarios `Histórico: hasta vX.Y...` | Nunca (son inmutables por definición) | **NO — son registros históricos** |
127
+
128
+ Verificación post-bump con `grep -rn "<versión-anterior>"` revelará decenas o cientos de matches en capas 2 y 3 — eso es esperado y correcto. Filtrar ruido para confirmar que las únicas líneas modificadas son de la capa 1:
129
+
130
+ ```bash
131
+ # Después del bump, validar consistencia SOLO en archivos canónicos del sistema
132
+ node -e "
133
+ const p=require('./package.json'),l=require('./plugin.json');
134
+ const lock=require('./package-lock.json');
135
+ const ok = p.version===l.version && l.version===lock.version;
136
+ console.log(ok ? 'OK consistente: '+p.version : 'INCONSISTENTE');
137
+ "
138
+ ```
139
+
140
+ Si el chequeo del nodo arriba dice OK pero `grep` aún muestra matches de la versión anterior, esos matches son **capa 2 (frontmatter)** o **capa 3 (histórico)** y son legítimos — no tocarlos.
141
+
142
+ ### Republish-only entre registries (caso especial)
143
+
144
+ Si el publish dual falla en uno de los 2 registries (typically npmjs o GitHub
145
+ Packages) pero el otro queda publicado, **NO se puede reintentar la misma versión**
146
+ — ningún registry permite sobreescribir versiones. Ejecutar inmediatamente un bump
147
+ PATCH (1.X.Y → 1.X.(Y+1)) siguiendo el checklist arriba, y publicar solo al
148
+ registry faltante con `node scripts/publicar.js --solo-npmjs` o `--solo-github`.
149
+
150
+ Documentar el republish exclusivamente como "republish de coordinación entre
151
+ registries" en CHANGELOG, sin atribuirle cambios funcionales que no existen.
152
+
153
+ Ver `Skill("release-semver")` sección "Publish a múltiples registries" para detalles.
154
+
155
+ ## Paso 6.5 — Regenerar skills-lock.json
156
+
157
+ Antes del CHANGELOG, regenerar el lock de skills para capturar el estado de
158
+ los 151 SKILL.md de la release:
159
+
160
+ ```bash
161
+ node scripts/generar-skills-lock.js
162
+ git add manifiestos/skills-lock.json
163
+ ```
164
+
165
+ El lock contiene SHA256 de cada SKILL.md y permite que `/swl:status salud` detecte
166
+ drift silencioso entre releases. Si el lock no cambió respecto al anterior,
167
+ el commit lo refleja como no-op (idempotente). El archivo es pequeño (~37KB)
168
+ y debe versionarse.
169
+
170
+ ## Paso 6.6 — Regenerar canonical-hashes.json (baseline del discriminador A/B)
171
+
172
+ Regenerar el manifiesto de hashes canónicos para la versión nueva. Es la baseline
173
+ que el instalador usa (Fase 16) para distinguir evolución del usuario (merge) de
174
+ shipped-evolved (actualizable) en cada upgrade. Debe incluir la versión que se
175
+ publica para que clientes que evolucionen desde ella se clasifiquen bien.
176
+
177
+ ```bash
178
+ node scripts/generar-canonical-hashes.js
179
+ git add manifiestos/canonical-hashes.json
180
+ ```
181
+
182
+ Idempotente (no-op si no cambió). El gate `node scripts/verificar-release.js`
183
+ (Paso 10.1) verifica que el manifiesto esté al día y que el fuente no porte
184
+ marcadores `evolved` espurios — si falla, ejecutar
185
+ `node scripts/verificar-evolucion.js --gate-inverso --fix`. El test e2e
186
+ `tests/scripts/release-e2e-evolved.test.js` (en `npm test`) bloquea el release
187
+ si la propagación A/B regresa.
188
+
189
+ ## Paso 7 — Generar CHANGELOG
190
+
191
+ Desde v1.6.5 este paso usa el skill `changelog-generator` para parsear
192
+ Conventional Commits y producir el bloque listo para insertar (ADR-0029).
193
+
194
+ ### Paso 7.1 — Cargar skill y previsualizar
195
+
196
+ ```
197
+ Skill("changelog-generator")
198
+ ```
199
+
200
+ Ejecutar el parser determinista contra los commits del rango actual:
201
+
202
+ ```bash
203
+ node habilidades/changelog-generator/scripts/parse-commits.js \
204
+ --from <tag-anterior> --to HEAD --version <nueva-version> --format markdown
205
+ ```
206
+
207
+ El script imprime el bloque markdown listo para insertar Y reporta a stderr
208
+ el ratio de conformidad Conventional Commits. Categorías generadas en orden
209
+ canónico: Breaking changes → Nuevas funcionalidades → Correcciones →
210
+ Mejoras de rendimiento → Cambios internos → Reversiones → Evoluciones de
211
+ skills/agentes → Mantenimiento → Otros.
212
+
213
+ ### Paso 7.2 — Gate de conformidad
214
+
215
+ Verificar la conformidad (impresa a stderr o vía `--format json`):
216
+
217
+ - **>= 80% conformidad**: continuar a 7.3.
218
+ - **< 80% conformidad**: detenerse y reportar al usuario los commits caídos
219
+ bajo "Otros". Pedir decisión:
220
+ 1. Continuar con el bloque generado (los "Otros" quedan al final del CHANGELOG).
221
+ 2. Abortar release y reescribir commits no conformes (`git rebase -i`).
222
+ 3. Editar manualmente la sección "Otros" antes de insertar.
223
+
224
+ NO continuar automáticamente con conformidad baja — el changelog público
225
+ queda confuso.
226
+
227
+ ### Paso 7.3 — Insertar en CHANGELOG.md
228
+
229
+ Leer `CHANGELOG.md` actual:
230
+ - Si no existe: crear con header `# Changelog\n\n` y luego el bloque nuevo.
231
+ - Si existe: insertar el bloque nuevo inmediatamente después del header
232
+ `# Changelog` (antes de la entrada anterior).
233
+
234
+ Escritura atómica obligatoria (regla CLAUDE.md). Usar `atomicWriteSync` desde
235
+ `hooks/lib/atomic-write.js` cuando se llame programáticamente.
236
+
237
+ ### Paso 7.4 — Verificar entrada generada
238
+
239
+ ```bash
240
+ head -40 CHANGELOG.md
241
+ ```
242
+
243
+ Confirmar:
244
+ - Header `## [<nueva-version>] - YYYY-MM-DD` presente.
245
+ - Categorías generadas tienen contenido coherente con los commits del rango.
246
+ - Breaking changes (si los hay) aparecen al inicio.
247
+
248
+ ### Fallback manual (legacy v1.6.4 y anterior)
249
+
250
+ Si el parser falla o el skill no está disponible, mantener el flujo manual
251
+ de versiones previas:
252
+ - Secciones: Funcionalidades nuevas, Correcciones, Mejoras de rendimiento,
253
+ Cambios internos, Breaking Changes, Estadísticas.
254
+ - Descripciones legibles por humanos (sin prefijo feat:/fix:).
255
+ - Omitir commits style: y test: del changelog público.
256
+
257
+ ## Paso 8 — Commit de release y tag
258
+
259
+ ```bash
260
+ git add package.json pyproject.toml setup.py VERSION CHANGELOG.md 2>/dev/null
261
+ git commit -m "chore(release): versión [nueva-versión]"
262
+ git tag -a "v[nueva-versión]" -m "Release v[nueva-versión]"
263
+ ```
264
+
265
+ Usar tags anotados siempre (regla del skill).
266
+
267
+ ## Paso 9 — Generar RELEASE-NOTES
268
+
269
+ Crea `releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md` con: resumen,
270
+ cambios, instrucciones de actualización y guía de migración si hay breaking changes.
271
+
272
+ ```bash
273
+ mkdir -p releases/v[nueva-versión]
274
+ # escribir releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md
275
+ ```
276
+
277
+ **NUNCA crear las RELEASE-NOTES en la raíz del repo.** La convención (todos los
278
+ releases previos en `releases/`) es que las RELEASE-NOTES viven SOLO en
279
+ `releases/vX.Y.Z/` — no se versiona ninguna copia en raíz. El directorio
280
+ `releases/v[nueva-versión]/` también lo crea `evidencia-release.js` (Paso 9.5);
281
+ si ese paso corre primero, el `mkdir -p` es no-op.
282
+
283
+ ## Paso 9.5 — Evidencia de procedencia (cadena de suministro, ADR-0038)
284
+
285
+ Genera la evidencia de cadena de suministro del release: SBOM CycloneDX del
286
+ árbol runtime + SHA256SUMS del tarball. No publica nada; produce artefactos
287
+ versionados en `releases/v[nueva-versión]/`.
288
+
289
+ ```bash
290
+ node scripts/lib/evidencia-release.js --version [nueva-versión]
291
+ ```
292
+
293
+ Esto escribe (vía `scripts/lib/evidencia-release.js`):
294
+ - `releases/v[nueva-versión]/sbom-v[nueva-versión].cdx.json` — SBOM CycloneDX
295
+ runtime-only (`npm sbom --sbom-format cyclonedx --omit dev`).
296
+ - `releases/v[nueva-versión]/SHA256SUMS` — checksum del tarball de `npm pack`.
297
+
298
+ Luego:
299
+
300
+ 1. **Insertar la sección "Integridad y verificación"** en
301
+ `releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md`, justo después de
302
+ la sección de correcciones. La genera `seccionVerificacionNotas` de la lib:
303
+
304
+ ```bash
305
+ node -e "const {seccionVerificacionNotas}=require('./scripts/lib/evidencia-release');const fs=require('fs');const v='[nueva-versión]';const sums=fs.readFileSync('releases/v'+v+'/SHA256SUMS','utf8').trim().split(/\s+/);const md=seccionVerificacionNotas({version:v,hash:sums[0],tarball:sums[1]});console.log(md)"
306
+ ```
307
+
308
+ Anexar ese markdown a `releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md`
309
+ (tras "Correcciones").
310
+
311
+ 2. **Versionar la evidencia** del release. Las RELEASE-NOTES ya viven en
312
+ `releases/v[nueva-versión]/` (Paso 9) — NO hacer `cp` desde la raíz (no debe
313
+ existir copia en raíz):
314
+
315
+ ```bash
316
+ git add releases/v[nueva-versión]/
317
+ ```
318
+
319
+ `releases/` NO viaja en el tarball npm (`package.json#files` es allowlist y no
320
+ lo incluye) — es evidencia del repo, no del paquete. Verificar con
321
+ `npm pack --dry-run | grep -c "releases/"` → debe ser `0`.
322
+
323
+ **Provenance (opt-in)**: el publish default sigue siendo local
324
+ (`scripts/publicar.js`). Para publicar a npmjs con `npm publish --provenance`
325
+ (que exige OIDC desde CI) usar el workflow opt-in
326
+ `.github/workflows/publish-npm.yml` (trigger `workflow_dispatch`, `dry_run`
327
+ default true). GitHub Packages permanece local. Runbook de verificación para
328
+ el consumidor: `docs/verificacion-consumidor.md`.
329
+
330
+ ## Paso 10 — Verificación final
331
+
332
+ ### 10.1 Gate automática anti-gap (OBLIGATORIA antes del push)
333
+
334
+ Ejecutar `scripts/verificar-release.js` que valida que la versión nueva esté reflejada en las 14 ubicaciones canónicas de la checklist (y avisa sobre MANUAL_USO opcional):
335
+
336
+ ```bash
337
+ node scripts/verificar-release.js
338
+ ```
339
+
340
+ Exit codes:
341
+ - `0` — todas las ubicaciones obligatorias con la versión correcta, puedes continuar al push
342
+ - `1` — al menos un archivo quedó en versión anterior. **NO hacer push hasta corregir**. El reporte indica el archivo y el problema específico
343
+ - `2` — error de invocación (package.json ausente, versión inválida)
344
+
345
+ Ejemplo de output en éxito:
346
+ ```
347
+ [OK] package.json: version=5.10.5
348
+ [OK] plugin.json: version=5.10.5
349
+ [OK] package-lock.json: version=5.10.5, packages[""].version=5.10.5
350
+ ...
351
+ [OK] CHANGELOG.md: seccion [5.10.5] presente con fecha
352
+ Resultado: 14/15 OK, 1 WARN opcional(es)
353
+ ```
354
+
355
+ Ejemplo de output en fallo que obliga a corregir:
356
+ ```
357
+ [FALLA] .planning/MAPEO_SKILLS_AGENTES.md: solo 0 ocurrencia(s) de 5.10.5 (minimo 1)
358
+ [FALLA] README.md: primera linea no menciona 5.10.5 — actual: "# swl-software-engineering-system v5.10.4"
359
+ Resultado: 13/15 OK, 2 FALLA(S) obligatoria(s)
360
+ ```
361
+
362
+ Esta gate existe porque el agente `release-manager-swl` ha omitido archivos en 3 releases consecutivos (5.10.3, 5.10.4, 5.10.5 — ver APRENDIZAJES.md) pese a tener la checklist documentada en su frontmatter. Un checklist textual no basta: se necesita ejecución.
363
+
364
+ ### 10.1.1 Gate de cobertura por lenguaje (regeneración obligatoria)
365
+
366
+ Tras el verificar-release.js, regenerar la matriz lenguaje × cobertura SWL:
367
+
368
+ ```bash
369
+ node scripts/generar-matriz-lenguajes.js
370
+ ```
371
+
372
+ El script reescribe `.planning/cobertura-lenguajes.md` con el estado actual.
373
+ Comparar contra el commit anterior:
374
+
375
+ ```bash
376
+ git diff .planning/cobertura-lenguajes.md
377
+ ```
378
+
379
+ Si algún lenguaje **bajó de status** (completo → parcial, parcial → faltante)
380
+ sin ADR documentado en `.planning/adrs/` justificando la regresión, **NO hacer
381
+ release**. La regresión silenciosa de cobertura erosiona la promesa "polyglot"
382
+ del repo.
383
+
384
+ Si el cambio es esperado (eliminación deliberada de un componente), el ADR
385
+ debe existir con número y fecha y referenciarse en el commit del release.
386
+
387
+ Lo mismo aplica para releases con incremento de cobertura: la nueva matriz se
388
+ commitea junto al release y se menciona en RELEASE-NOTES.
389
+
390
+ ### 10.2 Verificación manual post-gate
391
+
392
+ ```bash
393
+ git tag -l "v[nueva-versión]"
394
+ git log --oneline -3
395
+ head -30 CHANGELOG.md
396
+ ```
397
+
398
+ ## Paso 11 — Reporte final
399
+
400
+ ```
401
+ === Release v[nueva-versión] completado ===
402
+
403
+ Versión anterior: v[versión-anterior]
404
+ Nueva versión: v[nueva-versión]
405
+ Tipo: [PATCH | MINOR | MAJOR]
406
+
407
+ Archivos actualizados: [lista]
408
+ Git: Commit [hash], Tag v[nueva-versión]
409
+ Commits incluidos: [N] (feat: [N], fix: [N], otros: [N])
410
+ Tests: [ejecutados OK | omitidos (--skip-tests)]
411
+
412
+ Próximos pasos:
413
+ 1. Revisar releases/v[nueva-versión]/RELEASE-NOTES-v[nueva-versión].md
414
+ 2. git push origin v[nueva-versión]
415
+ 3. Publicar release en GitHub/GitLab si aplica
416
+ 4. Notificar al equipo
417
+ ```
418
+
419
+ ## Reglas de comportamiento
420
+
421
+ - NUNCA crear release con repositorio dirty.
422
+ - NUNCA omitir actualización de archivos de versión — inconsistencias causan errores de build.
423
+ - NUNCA usar `--skip-tests` sin documentarlo en CHANGELOG y sin confirmación.
424
+ - Si tipo calculado es MAJOR pero usuario pidió --tipo=patch, reportar discrepancia y esperar confirmación.
425
+ - CHANGELOG legible por alguien que no conoce el código.
426
+ - Si es monorepo, reportar que no se soporta y sugerir lerna/changesets.
427
+ - **Crear el tag anotado AL FINAL del proceso, cuando el contenido está congelado
428
+ y verificado** (tras evidencia + RELEASE-NOTES). Commitear ENCIMA de un tag de
429
+ release ya creado pero aún-no-publicado obliga a mover el tag + regenerar la
430
+ evidencia (el SHA del tarball cambia si el commit toca archivos de
431
+ `package.json#files`) — churn evitable. Si hay que iterar, hacerlo antes de taggear.
432
+ - **Si el usuario alimenta archivos de forma incremental para la MISMA versión
433
+ ("faltan N archivos que agregar a esta versión, espera"), NO finalizar el
434
+ release** (no congelar tag, no regenerar evidencia final, no proponer push)
435
+ hasta que el usuario confirme que ya están TODOS los archivos. Mantener el
436
+ commit de release como HEAD entre tandas para que cada incorporación sea un
437
+ `amend` limpio + mover tag; regenerar la evidencia (SBOM/SHA256SUMS) SOLO en la
438
+ última tanda, porque el SHA del tarball cambia con cada archivo nuevo que entre
439
+ en `package.json#files`. Cerrar el release antes de tiempo obliga a rehacer
440
+ evidencia y tag por cada archivo tardío.
441
+ - **El agente NUNCA corre `npm` (test/pack/build/publish) en paralelo a un
442
+ `npm run publish:*` que está ejecutando el usuario.** `test:release` incluye
443
+ `test:smoke` (install/uninstall a temp + lectura de estado global); dos suites
444
+ simultáneas colisionan y rompen `prepublishOnly` con fallos espurios que parecen
445
+ bugs de test pero son concurrencia. La preparación del release (bump, manifests,
446
+ evidencia, push, GitHub release) termina ANTES de que el usuario publique; durante
447
+ el publish del usuario, el agente no ejecuta `npm`.
448
+ - Si `prepublishOnly` falla y no se ve la causa: npm v10 NO guarda el stdout del
449
+ script fallido en su debug log. Capturar con el log síncrono de `publicar.js`
450
+ (`.planning/logs/publish-<v>-<ts>.log`) o `... *>&1 | Tee-Object`. No diagnosticar a ciegas.