@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.
- package/CLAUDE.md +192 -192
- package/README.md +600 -600
- package/agentes/auto-evolucion-swl.md +27 -3
- package/bin/swl-ses.js +32 -7
- package/comandos/swl/actualizar.md +174 -174
- package/comandos/swl/adoptar-proyecto.md +265 -265
- package/comandos/swl/aprender.md +836 -823
- package/comandos/swl/aprobar-plan.md +146 -146
- package/comandos/swl/auditar-deps.md +134 -134
- package/comandos/swl/autoresearch.md +264 -264
- package/comandos/swl/ayuda.md +224 -224
- package/comandos/swl/brainstorm.md +51 -51
- package/comandos/swl/briefing.md +119 -119
- package/comandos/swl/checkpoint.md +325 -325
- package/comandos/swl/claudemd.md +234 -234
- package/comandos/swl/compactar.md +310 -310
- package/comandos/swl/configurar-ci.md +235 -235
- package/comandos/swl/contexto.md +110 -110
- package/comandos/swl/contribuir.md +233 -233
- package/comandos/swl/crear-skill.md +292 -292
- package/comandos/swl/cron.md +194 -194
- package/comandos/swl/deuda-codigo.md +97 -97
- package/comandos/swl/discutir-fase.md +169 -169
- package/comandos/swl/ejecutar-fase.md +233 -233
- package/comandos/swl/evaluar-skill.md +520 -505
- package/comandos/swl/evolucion-continua.md +73 -0
- package/comandos/swl/evolucionar.md +267 -254
- package/comandos/swl/exportar-vault.md +583 -583
- package/comandos/swl/fix.md +118 -118
- package/comandos/swl/gateway.md +158 -158
- package/comandos/swl/inbox.md +116 -116
- package/comandos/swl/instalar.md +220 -220
- package/comandos/swl/instintos.md +86 -86
- package/comandos/swl/mapear-codebase.md +312 -312
- package/comandos/swl/mcp-status.md +175 -175
- package/comandos/swl/modelo.md +100 -100
- package/comandos/swl/nemesis.md +433 -433
- package/comandos/swl/notificaciones.md +299 -299
- package/comandos/swl/nuevo-proyecto.md +251 -251
- package/comandos/swl/planear-fase.md +263 -263
- package/comandos/swl/plugins.md +256 -256
- package/comandos/swl/predecir.md +169 -169
- package/comandos/swl/reflect-skills.md +125 -125
- package/comandos/swl/release.md +450 -450
- package/comandos/swl/revisar-impacto.md +201 -201
- package/comandos/swl/revisar.md +330 -330
- package/comandos/swl/seguridad.md +189 -189
- package/comandos/swl/sesiones.md +200 -200
- package/comandos/swl/skill-search.md +113 -113
- package/comandos/swl/status.md +343 -343
- package/comandos/swl/verificar.md +817 -817
- package/comandos/swl/wiki.md +620 -620
- package/gateway/cron/jobs.example.json +12 -0
- package/habilidades/auto-evolucion-protocolo/SKILL.md +294 -276
- package/habilidades/autoresearch/SKILL.md +3 -2
- package/habilidades/benchmark-memoria/SKILL.md +7 -7
- package/habilidades/changelog-generator/SKILL.md +174 -174
- package/habilidades/changelog-generator/scripts/parse-commits.js +2 -1
- package/habilidades/checkpoints-verificacion/SKILL.md +6 -0
- package/habilidades/context-builder/SKILL.md +4 -0
- package/habilidades/doubt-driven-review/SKILL.md +207 -191
- package/habilidades/drift-detection/SKILL.md +6 -1
- package/habilidades/ejecutar-fase/SKILL.md +6 -6
- package/habilidades/eval-framework/SKILL.md +8 -3
- package/habilidades/harness-claude-code/SKILL.md +312 -308
- package/habilidades/infra-github-actions/SKILL.md +4 -3
- package/habilidades/instalar-sistema/SKILL.md +227 -223
- package/habilidades/memoria-busqueda/SKILL.md +31 -39
- package/habilidades/planear-fase/SKILL.md +358 -350
- package/habilidades/proceso-ddia-fundamentos/SKILL.md +3 -2
- package/habilidades/swl-claudemd/SKILL.md +6 -7
- package/habilidades/swl-dashboard/SKILL.md +11 -43
- package/habilidades/tdd-workflow/SKILL.md +749 -744
- package/habilidades/validacion-ci-sistema/SKILL.md +1 -1
- package/hooks/agente-lifecycle.js +2 -1
- package/hooks/aiisms-detector.js +13 -4
- package/hooks/audit-trail.js +2 -1
- package/hooks/auto-consolidacion.js +2 -1
- package/hooks/captura-acciones-post.js +2 -1
- package/hooks/captura-acciones-session.js +2 -1
- package/hooks/captura-feedback-usuario.js +3 -2
- package/hooks/claudemd-bloat-detector.js +12 -3
- package/hooks/claudemd-duplicacion-detector.js +13 -3
- package/hooks/contexto-iteracion.js +2 -1
- package/hooks/degradacion-instintos.js +2 -1
- package/hooks/extraccion-aprendizajes.js +109 -15
- package/hooks/grafo-contexto.js +2 -1
- package/hooks/guardrail-modelo.js +2 -1
- package/hooks/inbox-aviso.js +2 -1
- package/hooks/inyeccion-contexto.js +2 -1
- package/hooks/lib/agent-matcher.js +2 -1
- package/hooks/lib/agent-routing.js +2 -1
- package/hooks/lib/autonomia.js +5 -3
- package/hooks/lib/captura-acciones.js +2 -1
- package/hooks/lib/consolidation-lock.js +21 -10
- package/hooks/lib/etapa-auto-evolucion.js +10 -4
- package/hooks/lib/etapa-metricas.js +2 -1
- package/hooks/lib/etapa-perfil-usuario.js +20 -4
- package/hooks/lib/evolution-tracker.js +2 -1
- package/hooks/lib/gateway-notify.js +193 -179
- package/hooks/lib/loop-telemetry.js +5 -4
- package/hooks/lib/mcp-health.js +2 -1
- package/hooks/lib/memory-search.js +4 -0
- package/hooks/lib/merkle-audit.js +58 -6
- package/hooks/lib/nudge-tracker.js +2 -1
- package/hooks/lib/otlp-exporter.js +2 -1
- package/hooks/lib/propose-step.js +3 -2
- package/hooks/lib/raiz-proyecto.js +102 -0
- package/hooks/lib/run-log.js +2 -1
- package/hooks/lib/singleton-guard.js +218 -27
- package/hooks/lib/telegram-cliente.js +17 -8
- package/hooks/preservar-estado-pre-compact.js +2 -1
- package/hooks/proteccion-rutas.js +59 -3
- package/hooks/registro-turnos.js +2 -1
- package/hooks/resumen-sesion.js +2 -1
- package/hooks/risk-scoring.js +2 -1
- package/hooks/rotar-audit-auto.js +46 -20
- package/hooks/session-briefing.js +127 -1
- package/hooks/spec-gate.js +2 -1
- package/hooks/sugerir-contribuir.js +6 -3
- package/hooks/sugerir-regenerar-inventario.js +3 -2
- package/hooks/tdd-gate.js +2 -1
- package/hooks/telemetria-agentes.js +2 -1
- package/hooks/telemetria-skill-routing.js +2 -1
- package/hooks/tracking-costos.js +4 -3
- package/hooks/validar-formato-post-subagente.js +2 -1
- package/hooks/validar-intent-spec.js +2 -1
- package/hooks/validar-memoria-hook.js +13 -3
- package/hooks/validar-planning-paths.js +2 -1
- package/instintos/.backups/perfil-usuario.yaml.2026-07-10-165128.bak +53 -0
- package/instintos/.backups/proyecto.yaml.2026-07-10-165128.bak +372 -0
- package/instintos/perfil-usuario.yaml +506 -3
- package/instintos/proyecto.yaml +78 -0
- package/llms.txt +2 -2
- package/manifiestos/canonical-hashes.json +335 -3
- package/manifiestos/modulos.json +19 -14
- package/manifiestos/planning-paths.json +1 -0
- package/manifiestos/skills-lock.json +50 -50
- package/package.json +2 -3
- package/plugin.json +2 -2
- package/scripts/actualizar.js +3 -0
- package/scripts/auditar-clases-conocidas.js +32 -4
- package/scripts/benchmark-memoria.js +1 -0
- package/scripts/cli/autonomia.js +23 -0
- package/scripts/cli/benchmark-memoria.js +37 -0
- package/scripts/cli/ciclo-autonomo.js +73 -0
- package/scripts/cli/ciclo-fase-b.js +102 -0
- package/scripts/cli/guardrail-metrics.js +39 -0
- package/scripts/cli/loop-telemetry.js +4 -2
- package/scripts/cli/memoria-search.js +69 -0
- package/scripts/cli/nudge-accionar.js +39 -0
- package/scripts/cli/run-eval.js +38 -0
- package/scripts/cli/run-skill-evals.js +13 -2
- package/scripts/derivar-feature-list.js +15 -14
- package/scripts/desinstalar.js +11 -0
- package/scripts/doctor.js +24 -10
- package/scripts/instalador.js +85 -7
- package/scripts/lib/activar-hooks-proyecto.js +12 -0
- package/scripts/lib/auditar-invocaciones-comandos.js +96 -6
- package/scripts/lib/ciclo-autonomo/candidatos.js +174 -0
- package/scripts/lib/ciclo-autonomo/config.js +165 -0
- package/scripts/lib/ciclo-autonomo/drenador-feedback.js +174 -0
- package/scripts/lib/ciclo-autonomo/fallback.js +77 -0
- package/scripts/lib/ciclo-autonomo/guard-convivencia.js +139 -0
- package/scripts/lib/ciclo-autonomo/higiene-nudges.js +112 -0
- package/scripts/lib/ciclo-autonomo/index.js +301 -0
- package/scripts/lib/ciclo-autonomo/lock.js +124 -0
- package/scripts/lib/ciclo-autonomo/presupuesto.js +122 -0
- package/scripts/lib/ciclo-autonomo/puente-degradacion.js +240 -0
- package/scripts/lib/ciclo-autonomo/runner-fase-b.js +248 -0
- package/scripts/lib/ciclo-autonomo/writer-instintos.js +190 -0
- package/scripts/lib/ciclo-autonomo/yaml-instintos.js +535 -0
- package/scripts/lib/estado.js +9 -0
- package/scripts/lib/gitignore-manifest.js +8 -1
- package/scripts/lib/hooks-settings.js +45 -0
- package/scripts/rotar-audit-logs.js +48 -2
- package/scripts/run-eval.js +1 -0
- package/scripts/run-skill-evals.js +287 -8
- package/scripts/smoke-test.js +16 -8
- package/scripts/tui/pantallas/install-wizard.js +403 -347
- package/scripts/validar.js +40 -1
package/comandos/swl/release.md
CHANGED
|
@@ -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.
|