@saulwade/swl-ses 2.0.0 → 2.1.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 (59) hide show
  1. package/CLAUDE.md +196 -196
  2. package/README.md +579 -579
  3. package/agentes/_propose-step.md +90 -0
  4. package/agentes/implementador-swl.md +2 -0
  5. package/agentes/orquestador-swl.md +2 -0
  6. package/agentes/perfilador-usuario-swl.md +14 -1
  7. package/bin/swl-ses.js +1 -1
  8. package/comandos/swl/aprobar-plan.md +3 -2
  9. package/comandos/swl/briefing.md +122 -0
  10. package/comandos/swl/compactar.md +29 -2
  11. package/comandos/swl/discutir-fase.md +8 -5
  12. package/comandos/swl/ejecutar-fase.md +6 -0
  13. package/comandos/swl/planear-fase.md +5 -3
  14. package/comandos/swl/release.md +46 -0
  15. package/comandos/swl/status.md +69 -0
  16. package/comandos/swl/verificar.md +3 -2
  17. package/habilidades/changelog-generator/scripts/parse-commits.js +6 -4
  18. package/habilidades/ejecutar-fase/SKILL.md +541 -518
  19. package/habilidades/planear-fase/SKILL.md +3 -2
  20. package/habilidades/tdd-workflow/SKILL.md +715 -713
  21. package/habilidades/validacion-ci-sistema/SKILL.md +17 -1
  22. package/hooks/calidad-pre-commit.js +5 -1
  23. package/hooks/check-update.js +39 -1
  24. package/hooks/lib/autonomia.js +208 -0
  25. package/hooks/lib/briefing.js +474 -0
  26. package/hooks/lib/propose-step.js +357 -0
  27. package/hooks/session-briefing.js +98 -0
  28. package/hooks/telemetria-skill-routing.js +100 -0
  29. package/instintos/autonomia.yaml +27 -0
  30. package/llms.txt +4 -4
  31. package/manifiestos/hooks-config.json +18 -0
  32. package/manifiestos/modulos.json +25 -3
  33. package/manifiestos/skills-lock.json +14 -14
  34. package/package.json +93 -93
  35. package/plugin.json +371 -371
  36. package/reglas/analizar-directorios-antes-de-escribir.md +228 -0
  37. package/reglas/consultar-vault-primero.md +195 -0
  38. package/reglas/debatir-antes-de-aceptar.md +158 -0
  39. package/reglas/git-coauthor.md +100 -0
  40. package/reglas/monitor-ci.md +309 -0
  41. package/reglas/registro-componentes-nuevos.md +38 -10
  42. package/reglas/sesiones-paralelas.md +180 -0
  43. package/reglas/usar-code-review-graph.md +155 -0
  44. package/reglas/verificar-citas-normativas.md +548 -0
  45. package/scripts/instalador.js +52 -6
  46. package/scripts/lib/ci-reader.js +193 -0
  47. package/scripts/lib/detectar-host-swl.js +175 -0
  48. package/scripts/lib/evidencia-release.js +322 -0
  49. package/scripts/lib/gate-hooks-requires.js +249 -0
  50. package/scripts/lib/gate-licencias.js +212 -0
  51. package/scripts/lib/git-metricas.js +257 -0
  52. package/scripts/lib/metricas-dora.js +204 -0
  53. package/scripts/tui/ejecutores.js +1 -1
  54. package/scripts/validar-manifest.js +92 -1
  55. package/scripts/verificar-evolucion.js +54 -4
  56. package/scripts/verificar-release.js +102 -0
  57. package/scripts/verificar-trazabilidad.js +11 -5
  58. package/reglas/arquitectura.evolved.json +0 -7
  59. package/reglas/seguridad.evolved.json +0 -7
@@ -0,0 +1,309 @@
1
+ ---
2
+ paths:
3
+ - "**/.github/workflows/**"
4
+ ---
5
+ # Regla: Monitor de CI tras push
6
+
7
+ Esta regla es OBLIGATORIA para todo proyecto del usuario que use GitHub
8
+ Actions (presencia de `.github/workflows/`). Aplica tras cada `git push` a la
9
+ rama principal o a una rama con CI activo.
10
+
11
+ ---
12
+
13
+ ## Principio
14
+
15
+ > Tras cualquier push que dispare workflows de CI, **arma un Monitor que
16
+ > emita una notificación cuando cada workflow termine** (success o failure)
17
+ > en lugar de pollear con `sleep` o esperar que el usuario pregunte.
18
+
19
+ El Monitor de Claude Code permite reaccionar inmediatamente a fallos sin
20
+ bloquear la conversación: si un workflow falla, el monitor lo emite como
21
+ evento y Claude diagnostica/arregla sin esperar input. Si todo pasa, Claude
22
+ puede continuar trabajando en paralelo.
23
+
24
+ ---
25
+
26
+ ## Cuándo armar el Monitor
27
+
28
+ OBLIGATORIO armarlo:
29
+
30
+ - Tras `git push` a rama con workflows activos.
31
+ - Tras crear un PR con CI requerido (cuando GitHub corre los checks).
32
+ - Tras `gh workflow run` manual.
33
+ - Cuando el usuario pide "verifica el CI" sin más detalle.
34
+
35
+ NO armarlo cuando:
36
+
37
+ - El push fue a una rama sin workflows activos para esa rama.
38
+ - Es un push de solo documentación que no dispara workflows (verificar el
39
+ filtro `paths:` del workflow primero).
40
+ - El usuario explícitamente dijo "no monitorees" o "termina aquí".
41
+
42
+ ---
43
+
44
+ ## Patrón estándar del comando
45
+
46
+ Plantilla para la herramienta `Monitor` de Claude Code. **Usa el `--jq`
47
+ integrado de `gh` (NO `| jq`)** para evitar dependencia externa — `jq` no
48
+ viene preinstalado en Windows + Git Bash, y `gh --jq` funciona idéntico
49
+ sin requerir instalación adicional. Tampoco usa `2>/dev/null` para que
50
+ errores reales del shell (PATH, `cd` fallido) se vean en stdout y aborten
51
+ el monitor en lugar de hacerlo expirar silenciosamente.
52
+
53
+ ```bash
54
+ prev=""
55
+ while true; do
56
+ cur=$(cd PROJECT_PATH && gh run list --branch BRANCH --limit N \
57
+ --json status,conclusion,name,headSha \
58
+ --jq '.[] | "\(.headSha[0:7]) | \(.name): \(.status)/\(.conclusion // "pending")"' \
59
+ | sort)
60
+ comm -13 <(echo "$prev") <(echo "$cur")
61
+ prev=$cur
62
+ if cd PROJECT_PATH && gh run list --branch BRANCH --limit N \
63
+ --json status \
64
+ --jq 'all(.[]; .status == "completed")' | grep -q true; then
65
+ break
66
+ fi
67
+ sleep 25
68
+ done
69
+ ```
70
+
71
+ **Variables a sustituir:**
72
+
73
+ | Variable | Valor |
74
+ |----------|-------|
75
+ | `PROJECT_PATH` | Working directory del proyecto (ej: `D:/Python/sigm`) |
76
+ | `BRANCH` | Rama del push (`main`, feature branch, etc.) |
77
+ | `N` | Cantidad de workflows que dispara ese push (3 si son frontend+backend+security; 4 si incluye database; etc.) |
78
+
79
+ **Argumentos típicos para `Monitor`:**
80
+
81
+ ```jsonc
82
+ {
83
+ "description": "CI commit <hash-corto> (<contexto>) — sale cuando los N workflows finalizan",
84
+ "timeout_ms": 600000, // 10 min — suficiente para la mayoría de CIs
85
+ "persistent": false, // false = sale al completar todos
86
+ "command": "<plantilla arriba>"
87
+ }
88
+ ```
89
+
90
+ Para CIs largos (>10 min), subir `timeout_ms` a 1200000 (20 min) o
91
+ 1800000 (30 min). Máximo soportado: 3600000 (60 min).
92
+
93
+ ---
94
+
95
+ ## Cómo funciona
96
+
97
+ - `gh run list --branch BRANCH --limit N` devuelve los N runs más recientes
98
+ de esa rama (los recién disparados por tu push aparecen en orden).
99
+ - `--jq '...'` (integrado en `gh`, NO el binario `jq` externo) formatea
100
+ `sha-corto | name: status/conclusion` por línea. Equivalente a `| jq`
101
+ pero sin dependencia externa.
102
+ - `comm -13` emite solo las líneas NUEVAS respecto a la iteración anterior
103
+ (cada vez que un workflow cambia de estado, sale como notificación).
104
+ - El segundo bloque verifica con `--jq 'all(.[]; .status == "completed")'`
105
+ + `grep -q true` si todos los workflows terminaron — sale del loop.
106
+ - El loop sale cuando todos los workflows están en estado `completed`.
107
+
108
+ Cada cambio de estado genera **una notificación al chat**, así que recibes
109
+ eventos como:
110
+
111
+ ```
112
+ ee6e03e | Frontend CI: in_progress/pending
113
+ ee6e03e | Backend CI: completed/success
114
+ ee6e03e | Security: completed/success
115
+ ```
116
+
117
+ cuando el primer workflow se mueve de `pending` a `in_progress`, otro a
118
+ `success`, etc.
119
+
120
+ ### Por qué `gh --jq` y no `jq` externo
121
+
122
+ El comando original usaba `| jq` y expiraba silenciosamente en sistemas
123
+ Windows sin `jq` instalado: el pipe a `jq` (que no existe) hacía que `$cur`
124
+ quedara vacío, `comm -13` no emitía deltas y el check de "todos completed"
125
+ siempre fallaba → loop dormía hasta timeout sin notificar nada. Caso real
126
+ (SIGM, 2026-05-12): dos monitores consecutivos expiraron sin un solo evento;
127
+ diagnóstico reveló `jq: command not found` en Git Bash de Windows.
128
+
129
+ `gh --jq` está embebido en el binario de `gh` (que ya es requisito), aplica
130
+ la misma sintaxis y funciona idéntico en Windows, macOS y Linux sin
131
+ instalaciones adicionales. **Esta es la forma recomendada — usa el flag
132
+ integrado siempre, salvo que tengas razón fuerte para depender de `jq`
133
+ externo (filtros muy complejos que solo cubre el binario completo).**
134
+
135
+ ---
136
+
137
+ ## Acciones tras evento del Monitor
138
+
139
+ 1. **Si todos terminan en `success`**: continuar con el siguiente paso del
140
+ plan (commit nuevo, fase nueva, etc.). No pedir confirmación al usuario
141
+ para cosas obvias.
142
+ 2. **Si alguno termina en `failure`**: descargar log con
143
+ `gh run view <run-id> --log-failed` y diagnosticar inmediatamente.
144
+ Aplicar la regla `arreglar-al-detectar.md`: detectar → informar →
145
+ arreglar en mismo turno.
146
+
147
+ En proyectos con swl-ses instalado (presencia de `agentes/gh-fix-ci-swl.md`),
148
+ el camino canónico para cerrar el ciclo failure → fix → re-push → green
149
+ es invocar el agente **`gh-fix-ci-swl`** (HITL approval obligatorio antes
150
+ de aplicar el fix; max 3 iteraciones; `maxTurnos: 12`). El agente carga
151
+ el `Skill("build-errors-<lang>")` correspondiente automáticamente. Si el
152
+ error es del workflow YAML mismo (secret, action, syntax), delega a
153
+ `devops-ci-swl`. Si el error es local (no específico de CI), prefiere
154
+ `resolutor-build-swl`. Origen: ADR-0029 (swl-ses).
155
+
156
+ 3. **Si el monitor expira (`timeout_ms`)**: re-armar con timeout mayor o
157
+ verificar manualmente con `gh run list`.
158
+
159
+ ---
160
+
161
+ ## Anti-patrones a evitar
162
+
163
+ - `sleep N && gh run list` — bloquea la conversación, no recibe eventos.
164
+ - Polling manual con múltiples `Bash` calls separadas.
165
+ - Arrancar el siguiente trabajo sin saber si el CI pasó (riesgo de
166
+ acumular commits sobre código roto).
167
+ - Olvidar el monitor tras un push y que el usuario tenga que recordártelo.
168
+
169
+ ---
170
+
171
+ ## Antes de declarar "CI verde" — verificación obligatoria por SHA
172
+
173
+ Esta sección formaliza la regla post-mortem (L-124, SIGM Sub-fase 5c, 2026-05-11):
174
+ reportar al usuario "CI verde" sin verificar cada workflow individualmente es
175
+ **falsificación de estado**. Un monitor expirado, un commit donde un workflow
176
+ no se disparó, o asumir "verde por default" llevan a declarar saludable un
177
+ sistema que está roto.
178
+
179
+ ### Checklist obligatorio antes de afirmar "CI verde"
180
+
181
+ 1. **Listar todos los workflows del SHA específico**:
182
+ ```bash
183
+ # Forma recomendada — gh --jq integrado, sin jq ni python externos:
184
+ gh run list --branch main --limit 8 \
185
+ --json status,conclusion,name,headSha \
186
+ --jq '.[] | "\(.headSha[0:7]) | \(.name): \(.status)/\(.conclusion // "pending")"'
187
+
188
+ # Fallback con Python si necesitas filtrar/agrupar por SHA en cliente:
189
+ gh run list --branch main --limit 20 --json status,conclusion,name,headSha \
190
+ | python -c "import sys,json; runs=json.load(sys.stdin); sha='ee6e03e'; \
191
+ [print(f'{r[\"name\"]}: {r[\"status\"]}/{r.get(\"conclusion\") or \"pending\"}') \
192
+ for r in runs if r['headSha'].startswith(sha)]"
193
+ ```
194
+
195
+ 2. **Confirmar `conclusion=success` para cada workflow aplicable**:
196
+ - Cada workflow tiene `paths:` distintos en `on:`. Si el commit solo toca
197
+ `frontend/`, **NO** se dispara Backend CI — eso es comportamiento correcto,
198
+ no fallo. Pero un workflow que SÍ debió dispararse y NO aparece en la
199
+ lista por el SHA es señal de mala configuración: investigar.
200
+ - **NUNCA** asumir verde por ausencia. La ausencia significa "no se ejecutó",
201
+ no "pasó".
202
+
203
+ 3. **NO interpretar Monitor expirado como verde**:
204
+ - El Monitor de Claude Code emite `[Monitor timed out — re-arm if needed.]`
205
+ cuando el timeout vence antes de que todos los workflows finalicen.
206
+ - **Timeout ≠ success**. Equivale a "estado desconocido al momento del corte".
207
+ - Re-armar el Monitor con timeout mayor, O verificar manualmente con
208
+ `gh run list --commit <sha>`.
209
+
210
+ 4. **Si algún workflow está en `failure` o `cancelled`**:
211
+ - Bajar el log con `gh run view <run-id> --log-failed` y diagnosticar.
212
+ - NO declarar verde hasta que el workflow fallido tenga su propio
213
+ `conclusion=success` en un commit posterior que lo arregle.
214
+
215
+ 5. **Reportar al usuario el estado exacto por workflow**:
216
+
217
+ ```
218
+ CI verde confirmado para commit <sha-corto>:
219
+ - Backend CI: success ✓
220
+ - Frontend CI: success ✓
221
+ - Security: success ✓
222
+ - E2E Smoke: success ✓
223
+ (Database CI no se disparó — el commit solo modificó frontend/, comportamiento correcto)
224
+ ```
225
+
226
+ NO usar afirmaciones genéricas como "todo verde" sin enumerar.
227
+
228
+ ### Anti-patrones explícitos
229
+
230
+ - **Reportar "CI verde" tras `git push` sin esperar finalización**: push retorna
231
+ exit 0 cuando GitHub aceptó el push, NO cuando los workflows pasaron.
232
+ Push exitoso ≠ CI verde.
233
+
234
+ - **Reportar "CI verde" porque el Monitor anterior dijo `success`**: si el
235
+ Monitor cubre commits A-B pero el último push es C, los workflows de C aún
236
+ no se evaluaron. Re-armar Monitor o verificar.
237
+
238
+ - **Reportar "CI verde" para un workflow NUEVO en su primer push**: un workflow
239
+ nuevo (ej: `e2e.yml`) tiene alta probabilidad de fallar en el primer run
240
+ porque no se validó localmente. Probar localmente Docker + servicios + tests
241
+ antes de reportar verde.
242
+
243
+ - **Asumir Frontend CI siempre verde porque "solo cambié docs"**: si modificas
244
+ un `.md` dentro de `frontend/`, Frontend CI se dispara igual por el matcher
245
+ `paths: ['frontend/**']`. Verificar.
246
+
247
+ - **"CI verde formal" (0 failed) ≠ "tests ejecutaron"**. Un run con 94 passed +
248
+ 5 skipped + 0 failed es verde formal pero zero cobertura de los 5 saltados.
249
+ Tests con `if (!precondicion) test.skip()` aumentan silenciosamente el conteo
250
+ de skipped cuando la precondición falla. Comparar el conteo `skipped` entre
251
+ commits: si aumenta sin causa documentada (tests intencionalmente skipped en
252
+ el spec), es **regresión silenciosa**, no éxito. Reportar al usuario con cifras:
253
+ *"verde con N skipped (antes M)"*, no solo "verde". Origen: sesión SIGAF
254
+ 2026-05-13, 7 commits con TC036-TC041 saltando por `actoId=null` antes de
255
+ detectar el patrón.
256
+
257
+ - **Fix de seed/fixture roto puede destapar tests "verde por suerte"**. Tests
258
+ que dependen de datos seedeados saltan por null check cuando el seed falla;
259
+ el CI los marca skipped y queda verde formal. Al arreglar el seed, los tests
260
+ vuelven a ejecutar y exponen fallas latentes que estaban camufladas. **Al
261
+ publicar un fix de seed/fixture, comparar el delta de skipped antes/después**
262
+ y revisar cada test que pase de SKIPPED a EJECUTANDO — pueden fallar por
263
+ otras razones acumuladas. Patrón observado en SIGAF 2026-05-13: fix
264
+ `e6d3f63` (seed grupo20 con `hallazgo.tipo_id`) destapó TC036-TC041 que
265
+ llevaban meses skipped por falta de actos en BD.
266
+
267
+ ### Origen
268
+
269
+ Aprendizaje L-124 documentado en SIGM (`.planning/APRENDIZAJES.md`) tras
270
+ Sub-fase 5c (2026-05-11): se reportó "CI verde en cada push" en 7 commits
271
+ seguidos cuando Frontend CI estaba en `failure` desde el commit 4. El usuario
272
+ detectó la inconsistencia al pedir validación adicional ("no podemos avanzar
273
+ de fase hasta no probar que todo esté perfecto"). El Monitor que expiró fue
274
+ interpretado como verde por defecto — equivocadamente.
275
+
276
+ ---
277
+
278
+ ## Excepciones documentadas
279
+
280
+ - **Repos sin GitHub Actions**: usar el sistema de CI nativo del repo
281
+ (GitLab CI, CircleCI). Adaptar el comando.
282
+ - **Workflows en forks**: los workflows desde fork PRs no reciben secrets
283
+ por diseño de GitHub. El monitor sirve igual, pero algunos jobs pueden
284
+ saltarse.
285
+ - **Rama protegida con auto-merge**: si el repo tiene auto-merge tras CI,
286
+ el monitor sale al `success` y el merge ocurre automáticamente — no es
287
+ necesario push adicional.
288
+
289
+ ---
290
+
291
+ ## Origen de esta regla
292
+
293
+ Promovida a regla global el 2026-05-09 a petición del usuario tras observar
294
+ que el patrón Monitor con `gh run list` + `jq` + `comm -13` se repetía
295
+ con éxito en cada push del proyecto SIGM (~10 invocaciones en sesión 2026-05-09)
296
+ y que ahorraba 5-10 minutos por iteración vs polling manual.
297
+
298
+ Reemplaza el patrón anterior de "esperar que el usuario reporte el log
299
+ fallido y reaccionar reactivamente" por proactividad.
300
+
301
+ **Revisión 2026-05-12** (SIGM): migrado de `| jq` a `gh --jq` integrado
302
+ para eliminar dependencia de binario externo. Causa: dos monitores
303
+ consecutivos expiraron silenciosamente en Windows + Git Bash por
304
+ `jq: command not found`, sin emitir un solo evento. Lección: las
305
+ herramientas del Monitor tool corren en sub-shell sin `2>&1` visible —
306
+ cualquier comando faltante hace que el monitor dure hasta timeout sin
307
+ señal de fallo. Diagnóstico: `which jq` antes de armar (debería
308
+ devolver path, no exit 1). `gh --jq` no tiene esta dependencia porque
309
+ está embebido en `gh` (ya requisito previo).
@@ -1,12 +1,12 @@
1
- ---
2
- paths:
3
- - "**/manifiestos/**"
4
- - "**/agentes/**"
5
- - "**/habilidades/**"
6
- - "**/comandos/**"
7
- - "**/hooks/**"
8
- - "**/plugin.json"
9
- ---
1
+ ---
2
+ paths:
3
+ - "**/manifiestos/**"
4
+ - "**/agentes/**"
5
+ - "**/habilidades/**"
6
+ - "**/comandos/**"
7
+ - "**/hooks/**"
8
+ - "**/plugin.json"
9
+ ---
10
10
  # Regla: Registro obligatorio de componentes nuevos en manifiestos
11
11
 
12
12
  Esta regla es OBLIGATORIA para el proyecto **@saulwade/swl-ses**. Aplica
@@ -50,7 +50,7 @@ listados según el tipo:
50
50
  | **Agente** (`agentes/X-swl.md`) | `plugin.json` (array `agents`), `manifiestos/modulos.json` (módulo del dominio), `AGENTS.md` (catálogo), `INVENTARIO.md` (regenerar), `SALUD.md` (regenerar) | `node scripts/generar-inventario.js` |
51
51
  | **Skill** (`habilidades/X/SKILL.md`) | `plugin.json` (array `skills`), `manifiestos/modulos.json` (módulo del dominio), `INVENTARIO.md` (regenerar), `CLAUDE.md` § "Sistema de habilidades" si aplica al dominio | `node scripts/generar-inventario.js` |
52
52
  | **Comando** (`comandos/swl/X.md`) | `plugin.json` (array `commands` si existe), `manifiestos/modulos.json`, `COMANDOS.md` (descripción), `CLAUDE.md` § tabla de comandos `/swl:*`, `INVENTARIO.md` (regenerar) | `node scripts/generar-inventario.js` |
53
- | **Hook** (`hooks/X.js`) | `plugin.json` (array `hooks` si existe), `.claude/settings.json` (event+matcher), `manifiestos/hooks-config.json` (event+matcher+blocking), `manifiestos/modulos.json` (ruta del archivo), `INVENTARIO.md`, `SALUD.md` | `node scripts/generar-inventario.js` |
53
+ | **Hook** (`hooks/X.js`) | `plugin.json` (array `hooks` si existe), `.claude/settings.json` (event+matcher), `manifiestos/hooks-config.json` (event+matcher+blocking), `manifiestos/modulos.json` (ruta del archivo **+ toda lib de `scripts/lib/` que el hook requiera, incluidas transitivas** — `grep require` de cada lib antes de registrar), `INVENTARIO.md`, `SALUD.md` | `node scripts/generar-inventario.js` |
54
54
  | **Regla** (`reglas/X.md`) | `CLAUDE.md` § tabla de reglas (matcher), `INVENTARIO.md`, `SALUD.md` | `node scripts/generar-inventario.js` |
55
55
  | **Schema** (`schemas/X.schema.json`) | `INVENTARIO.md`, `SALUD.md`. Si valida frontmatter de algún componente, actualizar `scripts/validar.js` para que lo use | `node scripts/generar-inventario.js` |
56
56
  | **Plantilla** (`plantillas/X.md`) | `manifiestos/modulos.json` si la copia el instalador, `INVENTARIO.md` | `node scripts/generar-inventario.js` |
@@ -124,6 +124,34 @@ invisible para el instalador. Bug histórico v1.4.1 → v1.4.2: el módulo
124
124
  `auditoria-profunda` estaba en `modulos.json` pero NO en perfiles → 16
125
125
  archivos no llegaban al destino. Mismo patrón.
126
126
 
127
+ ### La lib `scripts/lib/` del hook viaja sola (no viaja)
128
+
129
+ Falso y silencioso. Un hook que hace `require('../scripts/lib/X')` necesita que
130
+ `scripts/lib/X.js` esté registrada en el MISMO módulo de `modulos.json` que el
131
+ hook — **incluyendo sus dependencias transitivas** (`grep require` de cada lib
132
+ antes de registrar). Sin eso, en el destino el require lanza `MODULE_NOT_FOUND`
133
+ y el wrapper con que se registran los hooks en settings.json
134
+ (`node -e "try{require(...)}catch(e){if(e.code!=='MODULE_NOT_FOUND')throw e}"`)
135
+ **traga el error**: el hook muere en silencio en TODA instalación destino, sin
136
+ dejar rastro, mientras funciona perfecto en el repo madre.
137
+
138
+ Caso real (2026-06-12): `check-update.js` requería `scripts/lib/npm-version.js`
139
+ (no distribuida) que a su vez requería `paquetes-conocidos.js` (transitiva,
140
+ tampoco distribuida) — el aviso de nuevas versiones nunca llegó a ningún equipo
141
+ del usuario desde la creación del hook. Fix en commit `12b2a31`.
142
+
143
+ Tres defensas obligatorias:
144
+
145
+ 1. **Registrar la lib + transitivas** en el módulo del hook (precedente: 16 libs
146
+ de `scripts/lib/` ya viajan en `hooks-inteligencia` y otros módulos).
147
+ 2. **Require tolerante en el hook** (`../scripts/lib/X` → `./lib/X` → null) con
148
+ **diagnóstico visible throttled** cuando la lib falta — nunca silencio
149
+ (regla anti-fallback-silencioso de `seguridad-agentes.md`).
150
+ 3. **Diagnóstico de "hook que nunca hace nada"**: ejecutar
151
+ `node -e "require('<ruta-al-hook>')"` SIN el wrapper — el wrapper es un
152
+ silenciador de `MODULE_NOT_FOUND` por diseño y oculta exactamente esta clase
153
+ de fallo.
154
+
127
155
  ### "Solo lo uso localmente, no necesito propagarlo"
128
156
 
129
157
  Falso. swl-ses se distribuye como paquete npm público. Cualquier componente
@@ -0,0 +1,180 @@
1
+ # Regla: Coordinación obligatoria al detectar sesión paralela
2
+
3
+ Esta regla es OBLIGATORIA y aplica cuando Claude detecta — o el usuario
4
+ informa — que **otra sesión de IA** (Claude Code, Codex CLI, Cursor, otro
5
+ agente) está trabajando **simultáneamente** sobre el mismo repositorio /
6
+ proyecto.
7
+
8
+ ---
9
+
10
+ ## Principio
11
+
12
+ > Cuando detectes que otra sesión está activa sobre el mismo repo y los
13
+ > cambios pueden colisionar en archivos compartidos, **DETÉN tu flujo
14
+ > actual y presenta 4 opciones explícitas de coordinación al usuario antes
15
+ > de proceder con cualquier escritura**. NUNCA decidas unilateralmente
16
+ > continuar.
17
+
18
+ El patrón opuesto (continuar y resolver conflictos al final) es costoso:
19
+ resolución manual de merge conflicts en archivos canónicos del sistema
20
+ (`package.json`, `plugin.json`, `CHANGELOG.md`, manifiestos) toma 30+
21
+ minutos vs 2 minutos de coordinación previa.
22
+
23
+ ---
24
+
25
+ ## Cómo detectar sesión paralela
26
+
27
+ Señales que disparan la regla:
28
+
29
+ - El usuario lo informa explícitamente: *"hay otra sesión trabajando en
30
+ esto agregando X"*.
31
+ - `git status` muestra archivos modificados que tú no modificaste en esta
32
+ sesión.
33
+ - Commits aparecen en `git log --oneline` con timestamps muy recientes
34
+ cuyo autor o mensaje no coinciden con tu trabajo.
35
+ - ADRs o PLAN.md aparecen en `.planning/` con números cercanos pero
36
+ contenido que no escribiste (`0019-X-completa.md` cuando tu trabajo era
37
+ ADR-0020).
38
+ - Archivos `.swl-install-state.json` o lockfiles con mtime posterior al
39
+ inicio de tu sesión.
40
+
41
+ Tras detectar cualquier señal: **pausar inmediatamente** antes de la
42
+ siguiente escritura.
43
+
44
+ ---
45
+
46
+ ## Las 4 opciones obligatorias
47
+
48
+ Presentar al usuario **literalmente** estas 4 opciones (sin inventar
49
+ variantes hasta que el usuario las pida):
50
+
51
+ | Opción | Estrategia | Cuándo conviene |
52
+ |--------|-----------|-----------------|
53
+ | **A — Ceder prioridad** | Pausar tu trabajo. Revertir cambios no commiteados. Esperar a que la otra sesión termine. Retomar después con `git pull` y rebase. | La otra sesión está cerca de terminar y tu trabajo es ortogonal o no urgente. |
54
+ | **B — Avance no-conflictivo** | Continuar trabajando, pero SOLO en archivos que la otra sesión NO toca. Identificar y enumerar el subconjunto seguro. Diferir cambios en archivos compartidos hasta que la otra sesión cierre. | Tu trabajo cabe en archivos disjuntos (skills nuevos, scripts nuevos, tests). |
55
+ | **C — Release combinada** | Coordinar con la otra sesión un cierre conjunto: mismo release, mismo PR, ambos trabajos integrados. Implica sincronización explícita en docs canónicas, CHANGELOG, versión. | Ambas líneas de trabajo apuntan al mismo bump de versión y los cambios son complementarios. |
56
+ | **D — Continuar conflictivo** | Continuar todo tu plan. Resolver merge conflicts al final manualmente. **NO RECOMENDADO** salvo bloqueador urgente. | Solo si la coordinación es imposible (otra sesión inalcanzable) y el trabajo es bloqueante. |
57
+
58
+ Tras presentar las opciones, **esperar la decisión del usuario** antes de
59
+ escribir cualquier archivo. La excepción son lecturas (`Read`, `Grep`,
60
+ `Glob`) que no modifican estado.
61
+
62
+ ---
63
+
64
+ ## Cómo presentar el reporte al usuario
65
+
66
+ Formato mínimo del mensaje de detección:
67
+
68
+ ```markdown
69
+ Pauso inmediatamente. Hay riesgo de conflicto crítico entre las dos sesiones.
70
+
71
+ ## Estado actual de las dos sesiones
72
+
73
+ ### Sesión actual (esta) — <descripción breve>
74
+ **Cambios en disco**: <lista de archivos modificados por mí>
75
+ **Pendiente**: <sub-fases restantes>
76
+
77
+ ### Sesión paralela — <descripción de qué hace>
78
+ **Cambios detectados**: <archivos modificados por la otra sesión>
79
+
80
+ ## Archivos en colisión potencial al avanzar
81
+
82
+ | Archivo | Mi necesidad | Otra sesión | Riesgo |
83
+ |---------|-------------|-------------|--------|
84
+ | package.json (versión) | bump vX → vY | bump probablemente también | ALTO |
85
+ | plugin.json | +N skills | posiblemente +runtimes | Medio |
86
+ | CHANGELOG.md | sección nueva | sección nueva | ALTO — conflict garantizado |
87
+ | docs canónicas | docs feature X | docs feature Y | Medio |
88
+
89
+ ## Opciones
90
+
91
+ [A/B/C/D con descripciones]
92
+
93
+ ## Recomendación
94
+
95
+ [Opción recomendada con justificación en 1 párrafo]
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Reglas duras
101
+
102
+ - **NUNCA decidir unilateralmente** continuar tras detectar sesión paralela.
103
+ - **NUNCA hacer commits** en archivos compartidos hasta que el usuario
104
+ confirme la estrategia de coordinación.
105
+ - **NUNCA pushear** cambios sin saber el estado de la otra sesión.
106
+ - Tras decidir Opción B (avance no-conflictivo): **mantener una lista
107
+ explícita** de archivos seguros vs archivos diferidos. Verificar antes
108
+ de cada `Write`/`Edit` que el archivo no está en la zona diferida.
109
+ - Si durante el trabajo aparece un nuevo conflicto no anticipado, **pausar
110
+ de nuevo y reportar** — no resolver en silencio.
111
+ - Tras decidir Opción C (release combinada): coordinar **versión y
112
+ ubicaciones canónicas** explícitamente (¿quién bumpea? ¿en qué orden se
113
+ mergean los PRs? ¿quién regenera INVENTARIO.md al final?).
114
+ - **NUNCA revertir cambios pendientes en working tree de una sesión paralela
115
+ por interpretación errónea de una instrucción del usuario**. Si el usuario
116
+ dice "no cambies de versión", "no toques X", "deja Y como está" durante un
117
+ flujo del agente actual, esa instrucción **aplica al trabajo nuevo del
118
+ agente actual**, no al trabajo previo ya pendiente en working tree de
119
+ otra sesión. **Antes de revertir cualquier archivo modificado que no
120
+ modificó la sesión actual**, ejecutar:
121
+ ```bash
122
+ git diff HEAD -- <archivo> # ver el cambio pendiente
123
+ git log --oneline -3 -- <archivo> # ver historia del archivo
124
+ grep -l "<bump-keyword>" .planning/APRENDIZAJES.md # buscar trazabilidad
125
+ ```
126
+ Si el cambio pendiente está documentado como trabajo de sesión previa
127
+ (entry en APRENDIZAJES.md, mensaje del usuario citándolo, evidencia en
128
+ `.planning/sessions/diary/`), **NO revertirlo**. Reportar al usuario:
129
+ *"Detecté cambio pendiente en X de sesión paralela (evidencia: Y). Mi
130
+ instrucción de no-cambiar-versión aplica solo a mi trabajo nuevo — ¿confirmas
131
+ que preserve los bumps previos?"*. La instrucción del usuario sobre
132
+ versiones se interpreta **a partir del momento en que se emite**, no
133
+ retroactivamente sobre el working tree.
134
+
135
+ ---
136
+
137
+ ## Excepciones legítimas
138
+
139
+ NO aplicar la regla cuando:
140
+
141
+ 1. **La otra sesión es de lectura pura** (consulta, exploración) y no
142
+ modifica archivos del repo.
143
+ 2. **Las sesiones trabajan en branches distintas** y el merge a main será
144
+ por PR independiente (no hay riesgo de colisión hasta el merge final).
145
+ 3. **El usuario explícitamente autorizó** continuar sin coordinación.
146
+
147
+ ---
148
+
149
+ ## Origen de esta regla
150
+
151
+ Sesión 2026-05-15 en swl-ses. Mientras una sesión analizaba `temp/cc-sdd-main`
152
+ para absorber patrones SDD (Opción B aprobada por el usuario), otra sesión
153
+ paralela trabajaba en agregar Codex y Cursor como targets de primera clase
154
+ (ADR-0019). Ambas sesiones modificaban `scripts/instalador.js`,
155
+ `manifiestos/modulos.json`, docs canónicas y planeaban bumpear a v1.5.0.
156
+
157
+ El usuario informó la situación con: *"hay otra sesion trabajando en el mismo
158
+ proyecto: 'Extension CLI' que esta agregando a swl-ses a codex y cursor como
159
+ targets"*. La sesión actual pausó, reportó 4 opciones, esperó decisión. El
160
+ usuario eligió Opción B (avance no-conflictivo en skills nuevos y scripts
161
+ disjuntos; deferir docs y release a "modo D" cuando la otra sesión
162
+ terminara). Resultado: **cero conflictos al cerrar v1.5.0** vía PR #25
163
+ unificado.
164
+
165
+ Sin esta regla, el patrón habitual hubiera sido continuar y resolver
166
+ conflictos en cada `git pull` — costo estimado ~30 min de merge resolution
167
+ en `CHANGELOG.md`, `plugin.json`, `package.json`, `manifiestos/modulos.json`
168
+ y `INVENTARIO.md`.
169
+
170
+ ---
171
+
172
+ ## Checklist al detectar sesión paralela
173
+
174
+ - [ ] Pausé mi escritura actual antes de la siguiente `Write`/`Edit`
175
+ - [ ] Ejecuté `git status` y `git log --since="1 hour ago"` para mapear cambios
176
+ - [ ] Identifiqué los archivos potencialmente compartidos
177
+ - [ ] Presenté al usuario un reporte con las 4 opciones (A/B/C/D) y mi recomendación
178
+ - [ ] Esperé decisión explícita antes de la siguiente escritura
179
+ - [ ] Si elegimos B: mantengo lista de archivos diferidos visible
180
+ - [ ] Si elegimos C: confirmé versión objetivo y orden de PRs