@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,90 @@
1
+ <!--
2
+ Fragmento compartido — Propose-step de adyacencias (Fase 13, ADR-0037)
3
+ Importable desde frontmatter de agente: `fragmentos: [_propose-step]`
4
+ Usar en orquestador-swl e implementador-swl. NO routable, NO invocable con Skill.
5
+ Ver reglas/seguridad-agentes.md y .planning/adrs/0037-propose-step-presupuesto-autonomia.md
6
+ -->
7
+
8
+ ## Propose-step — proponer adyacencias, nunca actuar
9
+
10
+ Separa PROPONER de ACTUAR. Al **cerrar una tarea o fase** (no en cada turno),
11
+ evalúas las adyacencias de riesgo del cambio y las emites como **anexo
12
+ propositivo**. El anexo NUNCA bloquea ni ejecuta nada: es texto que el usuario
13
+ lee y decide si actúa.
14
+
15
+ ### Cuándo correr
16
+
17
+ - Solo al cerrar una tarea o una fase, sobre el diff de ese cierre.
18
+ - Nunca en mitad de la implementación (evita ruido por turno).
19
+ - Si `SWL_PROPOSE=0`, el propose-step queda desactivado: silencio total.
20
+
21
+ ### Cómo evaluar (mecanizado)
22
+
23
+ Ejecuta la lib sobre el diff de la tarea/fase:
24
+
25
+ ```bash
26
+ node hooks/lib/propose-step.js --rango=HEAD~1..HEAD
27
+ ```
28
+
29
+ Imprime el anexo solo si detecta ≥1 señal; silencio si no hay nada. Si la lib
30
+ no está disponible en el destino, evalúa a mano las 2 señales v1:
31
+
32
+ - **auth/PII/pagos**: el diff toca autenticación, datos personales o pagos
33
+ (paths `auth/`, `login`, `session`; patrones `password`, `token`, `secret`,
34
+ `jwt`, `stripe`, `pago`, `curp`, `rfc`). → Sugerir revisión de seguridad y
35
+ tests de autorización.
36
+ - **migración de schema**: el diff toca `models/`, `migrations/`, `*.sql`, o
37
+ contiene `ALTER/CREATE/DROP TABLE`. → Sugerir plan de rollback /
38
+ expand-contract y verificar reversibilidad.
39
+
40
+ ### Formato del anexo
41
+
42
+ Solo cuando hay señal. Una sección al final del entregable:
43
+
44
+ ```
45
+ ## Anexo propositivo — adyacencias de riesgo
46
+
47
+ Sugerencias, no acciones: nada se ejecuta ni se bloquea automáticamente.
48
+
49
+ - [auth-pii-pagos] <título> (<evidencia>) → <acción sugerida>
50
+ ```
51
+
52
+ Las categorías que la telemetría de aceptación silenció (el usuario las ignora
53
+ de forma sostenida) no copan el anexo. La lib lo maneja con
54
+ `categoriasSilenciadasPropose`.
55
+
56
+ ## Presupuesto de autonomía — proponer libre, actuar con presupuesto
57
+
58
+ Antes de **actuar** de forma autónoma, consulta el dial de autonomía en
59
+ `instintos/autonomia.yaml` (defaults = `reglas/seguridad-agentes.md`; este
60
+ fragmento NO relaja ningún control). Niveles por clase de riesgo:
61
+
62
+ | Clase | Nivel default | Qué significa |
63
+ |-------|---------------|---------------|
64
+ | lectura/análisis | `total` | Autónomo sin checkpoint. |
65
+ | cambio reversible | `con_auto_checkpoint` | Autónomo, pero registra un auto-checkpoint ANTES de actuar. |
66
+ | migración / auth / push / publish | `hitl` | Confirmación humana siempre. |
67
+
68
+ El dial sube **solo por decisión explícita del usuario**, nunca por tu
69
+ conveniencia. Un valor desconocido en el dial degrada a `hitl`.
70
+
71
+ ### Auto-checkpoint (precondición de cambio reversible)
72
+
73
+ Antes de la primera acción autónoma de clase **cambio reversible** de una tarea,
74
+ registra el checkpoint mecánico:
75
+
76
+ ```bash
77
+ node hooks/lib/autonomia.js --accion "<descripción corta de la acción>"
78
+ ```
79
+
80
+ Registra HEAD + archivos modificados en
81
+ `.planning/user-profile/auto-checkpoints.jsonl` como evidencia de rollback (los
82
+ commits atómicos son el mecanismo real de reversibilidad). Es best-effort: no
83
+ bloquea la acción que protege.
84
+
85
+ ### Reglas duras
86
+
87
+ - Proponer es siempre permitido; actuar se gobierna por el dial.
88
+ - Para clases `hitl` (migración, auth, push, publish): pausa y pide confirmación.
89
+ - Nunca degradar silenciosamente: si una adyacencia es de alto impacto, repórtala
90
+ en el anexo aunque el dial permita actuar.
@@ -44,6 +44,8 @@ exclusiones:
44
44
  - "No invocar para backend Node.js puro — usar backend-node-swl para mayor profundidad en NestJS, Prisma y ecosistema Node."
45
45
  - "No invocar sin PLAN.md aprobado para features complejas — primero pasar por planificador-swl."
46
46
  - "No invocar para decisiones de arquitectura — esas decisiones corresponden a arquitecto-swl; este agente ejecuta planes, no los diseña."
47
+ fragmentos:
48
+ - _propose-step
47
49
  ---
48
50
  ## Cuándo NO invocarme
49
51
 
@@ -40,6 +40,8 @@ exclusiones:
40
40
  - "No invocar para tareas de un solo agente o preguntas técnicas puntuales: el usuario puede invocar el agente especializado directamente sin pasar por el orquestador."
41
41
  - "No invocar para tomar decisiones de arquitectura — esas decisiones corresponden a arquitecto-swl; el orquestador solo coordina, no decide."
42
42
  - "No invocar cuando ya existe un PLAN.md aprobado y en ejecución activa: en ese caso invocar directamente a implementador-swl con el plan existente."
43
+ fragmentos:
44
+ - _propose-step
43
45
  ---
44
46
  Eres el orquestador central del sistema SWL.
45
47
 
@@ -17,7 +17,7 @@ modeloAlterno: claude-opus-4-7
17
17
  ventanaContexto: 200k
18
18
  permissionMode: acceptEdits
19
19
  color: indigo
20
- version: 1.0.0
20
+ version: 1.1.0
21
21
  nivelRiesgo: MEDIO
22
22
  skillsInvocables: [perfil-usuario, aprendizaje-continuo, memoria-busqueda, privacy-memoria]
23
23
  permisosRed: false
@@ -109,10 +109,23 @@ tercero (perfil del usuario). **No cruces los carriles:**
109
109
  | Sesiones con commits aceptados | 0.6 | Trabajo validado implícitamente |
110
110
  | Sesiones con correcciones frecuentes | 0.4 | Señal de fricción, no de preferencia firme |
111
111
  | `instintos/proyecto.yaml` con evidence_count ≥3 | 0.7 | Patrón observado en proyecto |
112
+ | `.planning/user-profile/briefing-telemetria.json` categoría `silenciada:true` | 0.6 | El usuario ignora consistentemente esa categoría de señal proactiva |
112
113
 
113
114
  **Nunca** uses tool outputs crudos ni logs de errores como evidencia directa
114
115
  de preferencia — el ruido es alto.
115
116
 
117
+ ### Telemetría de aceptación del briefing (Fase 12, ADR-0036)
118
+
119
+ El hook `session-briefing.js` mantiene `.planning/user-profile/briefing-telemetria.json`
120
+ con, por categoría de señal (`adr-vencido`, `deuda-trigger`, `nudges-pendientes`,
121
+ `gate-calibracion`, `continue-here`), los contadores `{mostrado, actuado, ignorado,
122
+ silenciada}`. Al consolidar el perfil, leer este archivo como señal de **preferencias
123
+ de proactividad**: una categoría con `silenciada:true` (ratio ignorado/mostrado ≥0.8
124
+ con ≥5 muestras) indica que el usuario no quiere ese tipo de aviso — registrarlo en
125
+ el perfil como preferencia de comunicación, no como anti-patrón técnico (canal A de
126
+ `memoria-consolidada.md`, no APRENDIZAJES). NO inferir más de lo que los contadores
127
+ dicen: actuado≠preferencia positiva fuerte, solo "resolvió la señal".
128
+
116
129
  ## Estructura del perfil (`instintos/perfil-usuario.yaml`)
117
130
 
118
131
  ```yaml
package/bin/swl-ses.js CHANGED
@@ -192,7 +192,7 @@ GESTIÓN DE COMPONENTES:
192
192
  OPCIONES DE INSTALL:
193
193
  --target <runtime> Runtime destino: claude|openclaude|copilot|opencode|codex|gemini|cursor (default: claude)
194
194
  --profile <perfil> Perfil: core|backend-python|backend-node|frontend-react|frontend-angular|
195
- fullstack-python-angular|fullstack-node-react|mobile|devops|completo (default: core)
195
+ fullstack-python-angular|fullstack-node-react|mobile|devops|completo (default: completo)
196
196
  --with <componentes> Incluir componentes adicionales (separados por coma)
197
197
  --without <comps> Excluir componentes (separados por coma)
198
198
  --global Instalar en directorio global del runtime (~/.claude, etc.)
@@ -51,8 +51,9 @@ Lee el campo `estado:` del frontmatter:
51
51
 
52
52
  ## Paso 2.5 — Validar la matriz REQ×T (trazabilidad G4)
53
53
 
54
- Lee `.planning/fases/0N-CONTEXTO.md` y extrae los IDs `REQ-NN:` de la sección de
55
- criterios de aceptación.
54
+ Lee `.planning/fases/0N-CONTEXTO.md` y extrae los IDs `REQ-NN:` (fases 01-11) o
55
+ `REQ-<fase>-NN:` (namespaceados, fases ≥12) de la sección de criterios de
56
+ aceptación. `verificar-trazabilidad.js` reconoce ambos formatos.
56
57
 
57
58
  - **CONTEXTO sin REQ-IDs** (fases legacy 01-09): advertencia informativa
58
59
  ("CONTEXTO sin REQ-IDs — trazabilidad no exigible, gracia legacy") y continúa.
@@ -0,0 +1,122 @@
1
+ ---
2
+ name: swl:briefing
3
+ description: Briefing proactivo del proyecto bajo demanda. Re-presenta las señales baratas del hook SessionStart (ADRs Propuestos con reevaluación vencida, deuda con trigger por fecha cumplido, nudges sin accionar, gates en calibración, retoma pendiente) y agrega el análisis profundo opt-in que el hook no puede pagar: audit de dependencias del proyecto destino, cobertura vs umbral, hubs del grafo tocados sin revisión, drift de feature-list, y triggers de deuda en prosa libre. Cargar cuando el usuario pide "¿qué hay pendiente?", "¿qué riesgos hay?", "ponme al día", o cuando el digest de sesión sugiere el análisis completo por volumen de señales.
4
+ allowed_tools: ["Read", "Bash", "Glob", "Grep"]
5
+ ---
6
+
7
+ # /swl:briefing — Briefing proactivo bajo demanda
8
+
9
+ Análisis no solicitado del estado del proyecto destino (Fase 12, ADR-0036). El
10
+ hook `session-briefing.js` da el digest barato al abrir sesión; este comando es
11
+ el nivel profundo: re-presenta esas señales Y agrega las que cuestan (deps, grafo,
12
+ cobertura) con degradación funcional si la herramienta no está instalada.
13
+
14
+ Principio rector: **proponer es barato y siempre permitido; actuar requiere
15
+ autorización del usuario**. Este comando solo propone y analiza — nunca aplica
16
+ cambios sin que el usuario los pida.
17
+
18
+ ## Uso
19
+
20
+ ```
21
+ /swl:briefing # señales baratas + análisis profundo completo
22
+ /swl:briefing rapido # solo las 5 señales del hook (sin deps/grafo/cobertura)
23
+ ```
24
+
25
+ ## Paso 1 — Señales baratas (mismas del hook)
26
+
27
+ Ejecuta los recolectores de filesystem y presenta el digest sin tope de 5 (aquí
28
+ sí caben todas, no hay presupuesto de latencia de arranque):
29
+
30
+ ```bash
31
+ node -e "
32
+ const b = require('./hooks/lib/briefing.js');
33
+ const items = b.recolectarTodo(process.cwd(), new Date());
34
+ for (const it of items) console.log('— [' + it.categoria + '] ' + it.titulo + ' → ' + it.accion);
35
+ if (items.length === 0) console.log('(sin señales baratas)');
36
+ "
37
+ ```
38
+
39
+ Las 5 categorías: `adr-vencido`, `deuda-trigger`, `nudges-pendientes`,
40
+ `gate-calibracion`, `continue-here`. Si `rapido`, terminar aquí.
41
+
42
+ ## Paso 2 — Análisis profundo (opt-in, con degradación)
43
+
44
+ Para cada herramienta, **validar antes de invocar** (patrón "validar antes de
45
+ invocar"): si no está disponible, reportar "no disponible, omitido" y continuar —
46
+ nunca fallar el briefing por una herramienta ausente.
47
+
48
+ ### 2.1 — Audit de dependencias del proyecto destino
49
+
50
+ Detectar el ecosistema y correr el audit nativo:
51
+
52
+ ```bash
53
+ # Node
54
+ [ -f package.json ] && npm audit --omit=dev 2>/dev/null | tail -5
55
+ # Python
56
+ [ -f requirements.txt -o -f pyproject.toml ] && (command -v pip-audit >/dev/null && pip-audit 2>/dev/null | tail -5 || echo "pip-audit no instalado — omitido")
57
+ ```
58
+
59
+ Reportar CVEs HIGH/CRITICAL con la acción concreta (`npm audit fix`, bump de
60
+ versión). Sin lockfile o sin gestor → omitir.
61
+
62
+ ### 2.2 — Cobertura vs umbral
63
+
64
+ Si el proyecto define cobertura, comparar contra el umbral del proyecto (80% por
65
+ defecto). Si no hay reporte reciente, indicar el comando para generarlo en vez de
66
+ correrlo (puede ser caro):
67
+
68
+ ```
69
+ Para medir cobertura: <runner del proyecto> --coverage
70
+ ```
71
+
72
+ ### 2.3 — Hubs del grafo tocados sin revisión
73
+
74
+ Si el MCP `code-review-graph` está disponible (tools `mcp__code-review-graph__*`
75
+ registradas o deferred), consultar los nodos hub modificados en los últimos N
76
+ commits sin revisión asociada. Si no está disponible → omitir con nota.
77
+
78
+ ### 2.4 — Drift de feature-list
79
+
80
+ ```bash
81
+ node scripts/derivar-feature-list.js --check 2>/dev/null; echo "exit: $?"
82
+ ```
83
+
84
+ Exit 2 → reportar que `HOJA-RUTA.md` y `feature-list.json` divergieron, con la
85
+ acción `node scripts/derivar-feature-list.js` para regenerar.
86
+
87
+ ### 2.5 — Deuda con trigger en prosa libre
88
+
89
+ El hook solo evalúa triggers verificables por fecha (D-16). Aquí, leer
90
+ `.planning/DEUDA-TECNICA.md` y evaluar con criterio los triggers en prosa
91
+ ("≥2 clientes reportan", "p95 > 60s documentado") contra el estado real del
92
+ proyecto. Reportar los que parezcan cumplidos para revisión del usuario.
93
+
94
+ ## Paso 3 — Presentación y telemetría
95
+
96
+ Presenta el briefing agrupado por prioridad (continue-here → gates → deuda →
97
+ ADRs → nudges → hallazgos profundos). Cada ítem con su acción ejecutable.
98
+
99
+ Tras presentar, el usuario decide qué accionar. NO ejecutar acciones de mutación
100
+ (cerrar deuda, promover gates, aplicar fixes) sin que el usuario lo pida — este
101
+ comando es propositivo (separación PROPONER/ACTUAR, ADR-0037 pendiente).
102
+
103
+ Si el usuario acciona una señal en esta sesión (ejecuta el comando sugerido), esa
104
+ resolución la captura la telemetría de aceptación del hook en la siguiente sesión
105
+ (la señal desaparece del recolector → cuenta como "actuada", D-18).
106
+
107
+ ## Cuándo NO usar este comando
108
+
109
+ - En cada turno de una sesión: el briefing es por sesión, no por mensaje. El hook
110
+ ya cubre el inicio; este comando es para cuando el usuario pide el detalle.
111
+ - Para aplicar las acciones propuestas: este comando propone, no ejecuta. Usar el
112
+ comando concreto de cada señal (`/swl:evolucion-estado`, `/swl:verificar`, etc.).
113
+ - En proyectos sin `.planning/`: no hay señales que recolectar.
114
+
115
+ ## Gotchas
116
+
117
+ - **Herramienta ausente ≠ error**: si `npm audit`, `pip-audit` o el grafo no están,
118
+ el briefing los omite con nota y sigue. Nunca abortar por una dependencia opt-in.
119
+ - **No re-listar lo que el hook ya mostró hoy**: el hook aplica dedupe diario; este
120
+ comando ignora el dedupe a propósito (lo invoca el usuario, quiere ver todo).
121
+ - **`code-review-graph` deferred ≠ ausente**: si las tools aparecen como deferred,
122
+ cargar su schema con `ToolSearch` antes de concluir que no está disponible.
@@ -269,10 +269,37 @@ Archivos actualizados:
269
269
  - .planning/COMPACTACION.md (creado/actualizado)
270
270
  - .planning/ESTADO.md (referencia agregada)
271
271
 
272
- El contexto está listo para continuar con sesión fresca.
273
- Próximo comando: [comando exacto]
272
+ El estado está a salvo en disco. IMPORTANTE: este comando NO compacta la
273
+ ventana de contexto — eso es una operación del harness que el agente no
274
+ puede ejecutar. Para compactar de verdad, AHORA ejecuta TÚ una de estas:
275
+
276
+ /compact ← built-in de Claude Code: trunca la ventana usando
277
+ el estado ya persistido (recomendado para seguir
278
+ en la misma sesión)
279
+ /clear o sesión nueva ← arranque limpio; pega la instrucción de arranque
280
+ del Paso 7
281
+
282
+ Próximo comando de trabajo (tras compactar): [comando exacto]
274
283
  ```
275
284
 
285
+ ## Paso 9 — Por qué este comando NO compacta la ventana (límite del harness)
286
+
287
+ La compactación REAL del contexto (truncar la conversación) es una operación
288
+ exclusiva del harness de Claude Code: el `/compact` built-in o el auto-compact.
289
+ Un comando `/swl:*` corre DENTRO de la conversación y el modelo no tiene
290
+ ninguna herramienta para truncar su propia ventana — por diseño.
291
+
292
+ División de responsabilidades:
293
+
294
+ | Mitad | Quién | Qué hace |
295
+ |-------|-------|----------|
296
+ | `/swl:compactar` | el agente | Persiste el estado a disco (COMPACTACION.md + ESTADO.md) para que NADA se pierda al truncar |
297
+ | `/compact` | el usuario (harness) | Trunca la ventana de verdad. Sin la mitad anterior, perdería las decisiones no escritas |
298
+
299
+ El error a prevenir: ejecutar `/compact` SIN haber corrido `/swl:compactar`
300
+ antes (estado solo en la memoria de la conversación → se pierde). El orden
301
+ correcto siempre es: `/swl:compactar` → `/compact`.
302
+
276
303
  ## Reglas de comportamiento
277
304
 
278
305
  - El COMPACTACION.md debe reemplazar la necesidad de releer toda la conversación. Si alguien lo lee, debe poder continuar el trabajo.
@@ -218,16 +218,19 @@ Estructura del archivo:
218
218
  [descripción de pantallas]
219
219
 
220
220
  ## Criterios de aceptación (REQ)
221
- [criterios binarios y verificables con ID estable REQ-NN trazabilidad G4:
222
- - **REQ-01**: [criterio binario verificable]
223
- - **REQ-02**: [criterio binario verificable]
221
+ [criterios binarios y verificables con ID estable namespaceado por fase
222
+ `REQ-<fase>-NN` (DT-IDS-NAMESPACE, fases ≥12) — trazabilidad G4:
223
+ - **REQ-12-01**: [criterio binario verificable]
224
+ - **REQ-12-02**: [criterio binario verificable]
225
+ Las fases 01-11 conservan el formato plano `REQ-NN` (gracia legacy permanente,
226
+ no se renumeran). `verificar-trazabilidad.js` acepta ambos formatos.
224
227
  Un REQ emitido NUNCA se renumera ni se reusa: si un criterio se descarta, marcarlo
225
228
  "RETIRADO — razón" conservando el número. planear-fase exige que cada tarea T-NN
226
229
  declare qué REQ verifica (matriz REQ×T) y aprobar-plan rechaza planes con REQ
227
230
  huérfanos. verificar-trazabilidad.js valida la cadena REQ→T→commit→test al cierre.
228
231
  Método de verificación: por default cada REQ exige un test con marker
229
- `verifica: REQ-NN`; los REQ satisfechos por prosa/docs/configuración llevan la
230
- anotación `(verificación: inspección)` en el criterio — exigen tarea y commit
232
+ `verifica: REQ-<fase>-NN`; los REQ satisfechos por prosa/docs/configuración llevan
233
+ la anotación `(verificación: inspección)` en el criterio — exigen tarea y commit
231
234
  pero no test automatizado.]
232
235
 
233
236
  ## Riesgos identificados
@@ -167,6 +167,12 @@ Según tipo de error:
167
167
 
168
168
  Al completar todos los slices, genera `.planning/fases/0N-RESUMEN.md` con: slices implementados (commits, archivos), resultados de tests, desviaciones del plan, decisiones técnicas, deuda técnica, estado final, criterios de aceptación verificados, próximos pasos.
169
169
 
170
+ **Anexo propositivo (Fase 13, ADR-0037)**: antes de cerrar, ejecuta el propose-step
171
+ sobre el diff de la fase (`node hooks/lib/propose-step.js --rango=<base>..HEAD`) e
172
+ incluye una sección "Anexo propositivo" en el RESUMEN.md **solo si hay ≥1 señal** de
173
+ adyacencia (auth/PII/pagos, migración de schema). Si no hay señal, omite la sección
174
+ (silencio, no sección vacía). El anexo propone, nunca bloquea. Opt-out `SWL_PROPOSE=0`.
175
+
170
176
  ## Paso 7 — Actualización de HOJA-RUTA.md y ESTADO.md
171
177
 
172
178
  Marca fase completada en HOJA-RUTA.md con fecha. Actualiza ESTADO.md con estado general.
@@ -181,9 +181,11 @@ fases técnicas puras — Gherkin sin lector de negocio es ceremonia.]
181
181
  ## Matriz REQ×T (obligatoria si el CONTEXTO tiene criterios REQ-NN)
182
182
  [tabla REQ → tareas que lo verifican. Cada tarea declara `**Verifica REQ**: REQ-XX`.
183
183
  Todo REQ sin tarea = plan NO apto para aprobación (aprobar-plan lo rechaza).
184
- La convención de cierre de cadena: commits con footer `Refs: REQ-NN` y tests con
185
- marker `# verifica: REQ-NN` (Python) / `// verifica: REQ-NN` (JS/TS) validada
186
- por `scripts/verificar-trazabilidad.js`. Omitir solo en CONTEXTOs legacy sin REQ-IDs.]
184
+ La convención de cierre de cadena (fases ≥12, IDs namespaceados por fase): commits
185
+ con prefijo `[F<fase>·T-NN]` y footer `Refs: REQ-<fase>-NN`, tests con marker
186
+ `# verifica: REQ-<fase>-NN` (Python) / `// verifica: REQ-<fase>-NN` (JS/TS)
187
+ validada por `scripts/verificar-trazabilidad.js` (acepta también el formato plano
188
+ `REQ-NN`/`[T-NN]` de fases 01-11). Omitir solo en CONTEXTOs legacy sin REQ-IDs.]
187
189
 
188
190
  | REQ | Tareas que lo verifican |
189
191
  |-----|------------------------|
@@ -254,6 +254,52 @@ Usar tags anotados siempre (regla del skill).
254
254
 
255
255
  Crea `RELEASE-NOTES-v[nueva-versión].md` con: resumen, cambios, instrucciones de actualización y guía de migración si hay breaking changes.
256
256
 
257
+ ## Paso 9.5 — Evidencia de procedencia (cadena de suministro, ADR-0038)
258
+
259
+ Genera la evidencia de cadena de suministro del release: SBOM CycloneDX del
260
+ árbol runtime + SHA256SUMS del tarball. No publica nada; produce artefactos
261
+ versionados en `releases/v[nueva-versión]/`.
262
+
263
+ ```bash
264
+ node scripts/lib/evidencia-release.js --version [nueva-versión]
265
+ ```
266
+
267
+ Esto escribe (vía `scripts/lib/evidencia-release.js`):
268
+ - `releases/v[nueva-versión]/sbom-v[nueva-versión].cdx.json` — SBOM CycloneDX
269
+ runtime-only (`npm sbom --sbom-format cyclonedx --omit dev`).
270
+ - `releases/v[nueva-versión]/SHA256SUMS` — checksum del tarball de `npm pack`.
271
+
272
+ Luego:
273
+
274
+ 1. **Insertar la sección "Integridad y verificación"** en
275
+ `RELEASE-NOTES-v[nueva-versión].md`, justo después de la sección de
276
+ correcciones. La genera `seccionVerificacionNotas` de la lib:
277
+
278
+ ```bash
279
+ 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)"
280
+ ```
281
+
282
+ Copiar ese markdown a RELEASE-NOTES (tras "Correcciones").
283
+
284
+ 2. **Copiar las RELEASE-NOTES** a la carpeta del release como evidencia
285
+ versionada:
286
+
287
+ ```bash
288
+ cp RELEASE-NOTES-v[nueva-versión].md releases/v[nueva-versión]/
289
+ git add releases/v[nueva-versión]/
290
+ ```
291
+
292
+ `releases/` NO viaja en el tarball npm (`package.json#files` es allowlist y no
293
+ lo incluye) — es evidencia del repo, no del paquete. Verificar con
294
+ `npm pack --dry-run | grep -c "releases/"` → debe ser `0`.
295
+
296
+ **Provenance (opt-in)**: el publish default sigue siendo local
297
+ (`scripts/publicar.js`). Para publicar a npmjs con `npm publish --provenance`
298
+ (que exige OIDC desde CI) usar el workflow opt-in
299
+ `.github/workflows/publish-npm.yml` (trigger `workflow_dispatch`, `dry_run`
300
+ default true). GitHub Packages permanece local. Runbook de verificación para
301
+ el consumidor: `docs/verificacion-consumidor.md`.
302
+
257
303
  ## Paso 10 — Verificación final
258
304
 
259
305
  ### 10.1 Gate automática anti-gap (OBLIGATORIA antes del push)
@@ -23,6 +23,8 @@ funcionalidad ni de flags.
23
23
  /swl:status evolucion --json — JSON crudo de metricas.json (para pipes)
24
24
  /swl:status evolucion --dias=N — Regenera métricas con ventana de N días (default 14)
25
25
  /swl:status evolucion --regenerar — Fuerza recomputo del hook ciclo-evolucion.js (etapa métricas)
26
+ /swl:status dora — Métricas DORA del proyecto destino (deploy freq, lead time, CFR, MTTR)
27
+ /swl:status dora --dias=N — Ventana de medición de N días (default 30)
26
28
  /swl:status historico — Dashboard histórico multi-sesión (web, auto-puerto)
27
29
  /swl:status dashboard — Alias de historico
28
30
  /swl:status dashboard --port 9090 — Fuerza puerto específico del dashboard
@@ -42,6 +44,7 @@ como vista por defecto si el contexto lo sugiere.
42
44
  | `metricas` (+ `detalle`, `fases`) | scripts de métricas de sesión + `derivar-feature-list.js` | `/swl:metricas` |
43
45
  | `loops` | `hooks/lib/loop-telemetry.js` | `/swl:metricas loops` |
44
46
  | `evolucion` | `hooks/ciclo-evolucion.js` (etapa métricas) + `.planning/evolution/metricas.json` | `/swl:evolucion-estado` |
47
+ | `dora` | `scripts/lib/metricas-dora.js` + `.planning/evolution/metricas-dora.json` | nuevo (Fase 15, ADR-0039) |
45
48
  | `historico` / `dashboard` | `Skill("swl-dashboard")` | `/swl:dashboard` |
46
49
 
47
50
  ---
@@ -53,6 +56,25 @@ Diagnóstico de salud del sistema SWL con **verificaciones deterministas**
53
56
  **Solo lectura** — no modifica nada salvo `SALUD.md`. Para corregir problemas,
54
57
  usar `/swl:evolucionar`.
55
58
 
59
+ **Paso 0 — Detección host vs consumidor (gate determinista, OBLIGATORIO)**:
60
+
61
+ `salud` audita los componentes del sistema SWL con un score ponderado. Ese score
62
+ solo tiene sentido en el repo que **hospeda** los componentes (swl-ses o un fork).
63
+ En un proyecto **consumidor** (usa las convenciones SWL vía `~/.claude/` pero no
64
+ aloja `agentes/`, `habilidades/`, `comandos/swl/`, `reglas/`, `hooks/`), el
65
+ inventario daría 0 y un score `0/100` sería señal falsa. Esta distinción es
66
+ **determinista**, NO juicio del agente:
67
+
68
+ ```bash
69
+ node scripts/lib/detectar-host-swl.js --json
70
+ ```
71
+
72
+ - Si `esHost: true` → continuar con el diagnóstico normal (Carga + pasos siguientes).
73
+ - Si `esHost: false` → **NO** calcular score de componentes ni generar `SALUD.md`
74
+ con `0/100`. Reportar el campo `razon` y la lista `sugerencias` (subcomandos de
75
+ `/swl:status` que sí aplican aquí: `metricas`, `loops`, `evolucion`, `dashboard`).
76
+ Ofrecer ejecutar uno de ellos. Terminar sin penalizar el score.
77
+
56
78
  **Carga**: `Skill("validacion-ci-sistema")` — contiene las reglas de validación
57
79
  por componente (agentes, skills, hooks, comandos, reglas), la tabla de exit codes
58
80
  y el checklist de integridad. Toda la lógica de verificación vive en el skill.
@@ -225,6 +247,53 @@ archivo, sin prosa.
225
247
 
226
248
  ---
227
249
 
250
+ ## Subcomando: `dora`
251
+
252
+ Métricas DORA (DevOps Research and Assessment) del **proyecto destino** donde SWL
253
+ está instalado: deployment frequency, lead time for changes, change failure rate
254
+ y MTTR, cada una clasificada en elite/high/medium/low (umbrales DORA Report 2023).
255
+ Mide **velocidad de entrega**, ortogonal a la reliability en runtime de
256
+ `observabilidad-swl`/`sre-swl`. Solo lectura salvo el JSON de storage.
257
+
258
+ **Portabilidad** (D-15-01): deployment frequency + lead time se derivan de git
259
+ (tags de release + commits) y están **siempre** disponibles. Change failure rate
260
+ + MTTR requieren `gh` (GitHub CLI) autenticado; si `gh` falta, no está autenticado,
261
+ o el repo no tiene remoto GitHub, esas dos reportan "no disponible" **sin fallar**.
262
+
263
+ **Paso 0 — calcular/regenerar**:
264
+ ```bash
265
+ node scripts/lib/metricas-dora.js --json [--dias=N]
266
+ ```
267
+ Regenera siempre que se invoque el subcomando (la medición es barata) o cuando se
268
+ pase `--dias=N` (ventana en días, default 30). El script persiste el informe en
269
+ `.planning/evolution/metricas-dora.json` (runtime, gitignored).
270
+
271
+ **Paso 1 — render**: presentar las 4 métricas con su valor y clasificación:
272
+
273
+ ```
274
+ Métricas DORA — ventana de 30 días
275
+
276
+ Deployment frequency: 2.30 deploys/semana [high]
277
+ Lead time (p50): 18.4 h [high]
278
+ Change failure rate: no disponible (gh ausente)
279
+ MTTR: no disponible (gh ausente)
280
+ ```
281
+
282
+ Reglas de render:
283
+ - Si una métrica git reporta `sinDatos: true` (proyecto sin tags de release),
284
+ mostrar "sin datos" — distinto de "frecuencia baja". El informe NO penaliza:
285
+ un proyecto sin releases no es "low", es "sin datos".
286
+ - Si `changeFailureRate`/`mttr` traen `disponible: false`, mostrar
287
+ "no disponible (gh ausente)" con la `razon` si ayuda — nunca como error.
288
+ - Tras el render, si CFR/MTTR no están disponibles, sugerir (1 línea) instalar y
289
+ autenticar `gh` para habilitarlas; no es obligatorio.
290
+
291
+ **Anti-substitution**: el archivo de storage es **siempre**
292
+ `.planning/evolution/metricas-dora.json` (nunca `metricas.json`, que es del ciclo
293
+ de evolución); el script es **siempre** `scripts/lib/metricas-dora.js`.
294
+
295
+ ---
296
+
228
297
  ## Subcomando: `historico` / `dashboard`
229
298
 
230
299
  Dashboard histórico multi-sesión vía `claude-usage` (vendored). Complementa
@@ -496,8 +496,9 @@ Sin `--until-converge`, el comportamiento del comando es idéntico al actual: un
496
496
 
497
497
  ### 5.0 — Trazabilidad REQ→T→commit→test (si el CONTEXTO tiene REQ-IDs)
498
498
 
499
- Si la sección de criterios del CONTEXTO usa IDs `REQ-NN:` (formato Fase 10+),
500
- ejecuta el validador de cadena ANTES de la verificación criterio por criterio:
499
+ Si la sección de criterios del CONTEXTO usa IDs `REQ-NN:` (fases 10-11) o
500
+ `REQ-<fase>-NN:` (namespaceados, fases ≥12), ejecuta el validador de cadena
501
+ ANTES de la verificación criterio por criterio:
501
502
 
502
503
  ```bash
503
504
  node scripts/verificar-trazabilidad.js --fase=N
@@ -53,15 +53,17 @@ const { execSync } = require('node:child_process');
53
53
  * [T-01] feat(hooks): prefijo de trazabilidad de tarea (ejecutar-fase)
54
54
  * [T-07][T-08] refactor(hooks): varios prefijos consecutivos
55
55
  * [REQ-08] feat(scripts): prefijo de requisito
56
+ * [F12·T-01] feat(hooks): prefijo namespaceado por fase (DT-IDS-NAMESPACE)
56
57
  *
57
- * El prefijo opcional `[T-NN]` / `[REQ-NN]` (uno o más, consecutivos) proviene
58
- * de la convención de commits de `habilidades/ejecutar-fase/SKILL.md`
59
- * (trazabilidad de tarea/requisito). No altera la semántica CC: el
58
+ * El prefijo opcional `[T-NN]` / `[REQ-NN]` / `[F<fase>·T-NN]` (uno o más,
59
+ * consecutivos) proviene de la convención de commits de
60
+ * `habilidades/ejecutar-fase/SKILL.md` (trazabilidad de tarea/requisito; desde
61
+ * la Fase 12 los IDs se namespacean por fase). No altera la semántica CC: el
60
62
  * tipo+scope+descripción siguen presentes después del/los prefijo(s), por lo
61
63
  * que el commit cuenta como conforme. Grupo non-capturing para no desplazar
62
64
  * los índices [1]=tipo [2]=scope [3]=! [4]=descripcion.
63
65
  */
64
- const RE_CONVENTIONAL = /^(?:\[(?:T|REQ)-\d+\]\s*)*(feat|fix|perf|refactor|docs|style|test|ci|build|chore|revert|evolucion|evolve)(?:\(([^)]+)\))?(!)?:\s*(.+)$/;
66
+ const RE_CONVENTIONAL = /^(?:\[(?:F\d+·)?(?:T|REQ)-\d+(?:-\d+)?\]\s*)*(feat|fix|perf|refactor|docs|style|test|ci|build|chore|revert|evolucion|evolve)(?:\(([^)]+)\))?(!)?:\s*(.+)$/;
65
67
 
66
68
  /** Mapa tipo CC → categoría Keep a Changelog en es-MX. */
67
69
  const CATEGORIAS = Object.freeze({