@saulwade/swl-ses 1.7.3 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CLAUDE.md +196 -196
  2. package/README.md +578 -578
  3. package/agentes/auto-evolucion-swl.md +7 -7
  4. package/agentes/disenador-ui-swl.md +12 -0
  5. package/agentes/investigador-ux-swl.md +9 -0
  6. package/agentes/perfilador-usuario-swl.md +2 -2
  7. package/agentes/ux-disenador-swl.md +6 -0
  8. package/comandos/swl/evaluar-skill.md +1 -1
  9. package/comandos/swl/evolucion-estado.md +5 -5
  10. package/comandos/swl/evolucionar.md +2 -2
  11. package/comandos/swl/inbox.md +1 -1
  12. package/comandos/swl/reflect-skills.md +2 -2
  13. package/comandos/swl/salud.md +1 -1
  14. package/habilidades/ai-runtime-security/SKILL.md +2 -2
  15. package/habilidades/auto-evolucion-protocolo/SKILL.md +2 -2
  16. package/habilidades/benchmark-memoria/SKILL.md +2 -2
  17. package/habilidades/drift-detection/SKILL.md +3 -3
  18. package/habilidades/eval-framework/SKILL.md +1 -1
  19. package/habilidades/guardrail-semantico/SKILL.md +4 -4
  20. package/habilidades/proceso-ddia-streaming/SKILL.md +4 -4
  21. package/habilidades/swl-claudemd/SKILL.md +2 -2
  22. package/habilidades/testing-python/SKILL.md +1 -1
  23. package/habilidades/tracing-processor/SKILL.md +1 -1
  24. package/hooks/actualizar-perfil-usuario.js +2 -2
  25. package/hooks/aiisms-detector.js +2 -2
  26. package/hooks/auto-evolucion.js +1 -1
  27. package/hooks/captura-feedback-usuario.js +2 -2
  28. package/hooks/claudemd-bloat-detector.js +2 -2
  29. package/hooks/claudemd-duplicacion-detector.js +1 -1
  30. package/hooks/guardrail-modelo.js +2 -2
  31. package/hooks/lib/memory-search.js +1 -1
  32. package/hooks/lib/nudge-tracker.js +1 -1
  33. package/hooks/metricas-evolucion.js +3 -3
  34. package/hooks/rotar-audit-auto.js +2 -2
  35. package/hooks/validar-formato-post-subagente.js +2 -2
  36. package/hooks/validar-intent-spec.js +1 -1
  37. package/hooks/validar-planning-paths.js +134 -0
  38. package/manifiestos/hooks-config.json +20 -11
  39. package/manifiestos/modulos.json +1352 -1351
  40. package/manifiestos/planning-paths.json +44 -0
  41. package/manifiestos/skills-lock.json +13 -13
  42. package/package.json +92 -92
  43. package/plugin.json +372 -372
  44. package/reglas/gobernanza.md +1 -1
  45. package/reglas/harness-claude-code.md +39 -0
  46. package/reglas/memoria-consolidada.md +7 -7
  47. package/reglas/sin-duplicacion-reglas-globales.md +1 -1
  48. package/scripts/auditar-agentes-gaps.js +1 -1
  49. package/scripts/auditar-cobertura-frameworks.js +2 -2
  50. package/scripts/auditar-skills-gaps.js +2 -2
  51. package/scripts/benchmark-memoria.js +3 -3
  52. package/scripts/inferir-herramientas-permitidas.js +1 -1
  53. package/scripts/instalador.js +48 -0
  54. package/scripts/lib/dashboard-widgets.js +3 -3
  55. package/scripts/lib/drift-detector.js +3 -3
  56. package/scripts/lib/eval-metrics-store.js +3 -3
  57. package/scripts/lib/gitignore-manifest.js +3 -3
  58. package/scripts/mcp-server/README.md +1 -1
  59. package/scripts/mcp-server/telemetry.js +2 -2
  60. package/scripts/reflect-skills.js +4 -4
  61. package/scripts/rotar-audit-logs.js +2 -2
  62. package/scripts/run-skill-evals.js +2 -2
@@ -10,7 +10,7 @@
10
10
  * agente no tiene schema declarado, el hook no hace nada — no asume
11
11
  * que todo agente debe seguir el formato compacto.
12
12
  *
13
- * Registra el resultado en `.planning/evolucion/formato-violaciones.jsonl`
13
+ * Registra el resultado en `.planning/evolution/formato-violaciones.jsonl`
14
14
  * para que `metricas-evolucion.js` calcule la tasa de violación por
15
15
  * agente y la incluya en el dashboard de calidad conductual.
16
16
  *
@@ -27,7 +27,7 @@ const path = require('path');
27
27
 
28
28
  const CWD = process.cwd();
29
29
  const SCHEMAS_PATH = path.join(CWD, 'manifiestos', 'agent-output-schemas.json');
30
- const LOG_PATH = path.join(CWD, '.planning', 'evolucion', 'formato-violaciones.jsonl');
30
+ const LOG_PATH = path.join(CWD, '.planning', 'evolution', 'formato-violaciones.jsonl');
31
31
 
32
32
  // ---------------------------------------------------------------------------
33
33
  // Carga del schema (una vez)
@@ -207,7 +207,7 @@ const nudge = {
207
207
  accionado: false,
208
208
  };
209
209
 
210
- const nudgesDir = path.join(CWD, '.planning', 'evolucion');
210
+ const nudgesDir = path.join(CWD, '.planning', 'evolution');
211
211
  const nudgesFile = path.join(nudgesDir, 'nudges.jsonl');
212
212
 
213
213
  try {
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: validar-planning-paths.js
6
+ * Tipo: PostToolUse (aplica a: Write, Edit, MultiEdit)
7
+ *
8
+ * Advierte cuando una sesion crea un directorio top-level NUEVO en .planning/
9
+ * que NO esta en la allowlist canonica (manifiestos/planning-paths.json).
10
+ * Atrapa divergencias es/en (auditoria/ vs audit/, ux/ vs design/) ANTES de
11
+ * que proliferen.
12
+ *
13
+ * Aplica reglas/analizar-directorios-antes-de-escribir.md y cierra
14
+ * DT-PLANNING-OUTPUT-PATHS. No bloquea (modo warn-only). ADR-0031.
15
+ *
16
+ * Opt-out: SWL_PLANNING_PATHS=0 desactiva el hook.
17
+ *
18
+ * Formato del nudge: kind "planning-path-divergente" -> documentador-swl.
19
+ */
20
+
21
+ const fs = require('fs');
22
+ const path = require('path');
23
+ const crypto = require('crypto');
24
+
25
+ if (process.env.SWL_PLANNING_PATHS === '0') process.exit(0);
26
+
27
+ let evento;
28
+ try {
29
+ evento = JSON.parse(fs.readFileSync(0, 'utf-8'));
30
+ } catch (_) {
31
+ process.exit(0);
32
+ }
33
+
34
+ const toolName = evento?.tool_name;
35
+ const toolInput = evento?.tool_input;
36
+ if (!toolName || !['Write', 'Edit', 'MultiEdit'].includes(toolName)) process.exit(0);
37
+
38
+ const filePath = toolInput?.file_path;
39
+ if (!filePath) process.exit(0);
40
+
41
+ const norm = filePath.replace(/\\/g, '/');
42
+
43
+ // Solo nos interesa lo que cae dentro de .planning/. Soporta path absoluto
44
+ // (con '/.planning/' embebido, lo que Claude Code envia en produccion) y path
45
+ // relativo ('.planning/...'). `resto` es todo lo que sigue a '.planning/'.
46
+ const marcador = '/.planning/';
47
+ let resto;
48
+ const idx = norm.indexOf(marcador);
49
+ if (idx >= 0) {
50
+ resto = norm.slice(idx + marcador.length); // path absoluto / embebido
51
+ } else if (norm.startsWith('.planning/')) {
52
+ resto = norm.slice('.planning/'.length); // path relativo
53
+ } else {
54
+ process.exit(0); // fuera de .planning/
55
+ }
56
+
57
+ // resto = "<segmento>/..." o "<archivo>"
58
+ const partes = resto.split('/').filter(Boolean);
59
+ if (partes.length === 0) process.exit(0);
60
+
61
+ // Si es un archivo directo en .planning/ (sin subdirectorio), es archivo
62
+ // top-level: lo permitimos (ESTADO.md, nudges.jsonl, etc.).
63
+ if (partes.length === 1) process.exit(0);
64
+
65
+ const topDir = partes[0];
66
+
67
+ // ─── Allowlist embebida (fallback portable) ────────────────────────────────
68
+ // manifiestos/ NO se propaga a proyectos consumidores; el hook debe ser
69
+ // autosuficiente. En el repo swl-ses se prefiere el manifest (fuente de
70
+ // verdad); en consumidores se usa esta lista. Mantener ambas en sync.
71
+ const DIRS_CANONICOS = [
72
+ 'adrs', 'analysis', 'archive', 'audit', 'auto-evolution', 'backups',
73
+ 'benchmark', 'comms', 'cron', 'design', 'evolution', 'fases', 'gateway',
74
+ 'inbox', 'knowledge', 'locks', 'red-team', 'research', 'runs', 'sessions',
75
+ 'traces', 'user-profile', 'wiki',
76
+ ];
77
+
78
+ // ─── Cargar allowlist (manifest si existe, embebida si no) ──────────────────
79
+ const CWD = process.cwd();
80
+ const allowlistPath = path.join(CWD, 'manifiestos', 'planning-paths.json');
81
+ let permitidos;
82
+ try {
83
+ const allow = JSON.parse(fs.readFileSync(allowlistPath, 'utf-8'));
84
+ permitidos = new Set((allow.directorios || []).map((d) => d.nombre));
85
+ } catch (_) {
86
+ permitidos = new Set(DIRS_CANONICOS);
87
+ }
88
+ if (permitidos.has(topDir)) process.exit(0);
89
+
90
+ // Directorio top-level NO canonico -> divergencia potencial.
91
+ // Detectar variante es/en conocida para sugerir el canonico correcto.
92
+ const VARIANTES = {
93
+ auditoria: 'audit', auditorias: 'audit',
94
+ ux: 'design', ui: 'design', diseno: 'design', 'diseno-visual': 'design',
95
+ investigacion: 'research', conocimiento: 'knowledge',
96
+ evolucion: 'evolution', 'auto-evolucion': 'auto-evolution',
97
+ 'perfil-usuario': 'user-profile', archivo: 'archive',
98
+ sesiones: 'sessions', decisiones: 'adrs',
99
+ };
100
+ const sugerido = VARIANTES[topDir] || null;
101
+
102
+ // Ruta de display relativa a .planning/, independiente de si el path era
103
+ // absoluto o relativo (resto ya es todo lo que sigue a '.planning/').
104
+ const rutaRelativa = '.planning/' + resto;
105
+ const nudge = {
106
+ id: crypto.randomBytes(8).toString('hex'),
107
+ kind: 'planning-path-divergente',
108
+ target: 'documentador-swl',
109
+ source: 'hooks/validar-planning-paths.js',
110
+ message:
111
+ `[planning-path] Se escribio en \`.planning/${topDir}/\`, un directorio top-level ` +
112
+ `NO canonico (${rutaRelativa}).\n` +
113
+ (sugerido
114
+ ? ` Probable divergencia es/en: usa el canonico \`.planning/${sugerido}/\` en su lugar.\n`
115
+ : ` Si es un dominio nuevo legitimo, agregalo a \`manifiestos/planning-paths.json\`.\n`) +
116
+ ` Ver \`reglas/analizar-directorios-antes-de-escribir.md\` y la allowlist canonica.`,
117
+ data: {
118
+ dir_detectado: topDir,
119
+ canonico_sugerido: sugerido,
120
+ archivo: rutaRelativa,
121
+ },
122
+ ts: new Date().toISOString(),
123
+ accionado: false,
124
+ accionado_ts: null,
125
+ accionado_por: null,
126
+ };
127
+
128
+ try {
129
+ const nudgesPath = path.join(CWD, '.planning', 'evolution', 'nudges.jsonl');
130
+ fs.mkdirSync(path.dirname(nudgesPath), { recursive: true });
131
+ fs.appendFileSync(nudgesPath, JSON.stringify(nudge) + '\n', 'utf-8');
132
+ } catch (_) { /* no fallar el hook */ }
133
+
134
+ process.exit(0);
@@ -17,13 +17,13 @@
17
17
  },
18
18
  "riskThresholds": {
19
19
  "allow": 0.35,
20
- "review": 0.60,
20
+ "review": 0.6,
21
21
  "confirm": 0.85
22
22
  },
23
23
  "costBudget": {
24
24
  "maxUsd": 10.0,
25
25
  "maxTokens": 500000,
26
- "alertAt": 0.80
26
+ "alertAt": 0.8
27
27
  },
28
28
  "circuitBreaker": {
29
29
  "maxConsecutiveFailures": 3,
@@ -171,7 +171,7 @@
171
171
  "actualizar-perfil-usuario.js": {
172
172
  "event": "Stop",
173
173
  "matcher": "",
174
- "description": "Detecta señales de corrección/preferencia del usuario y acumula un dirty-bit en .planning/perfil-usuario/. Emite nudge a perfilador-usuario-swl cuando cruza el umbral (default 3 señales).",
174
+ "description": "Detecta señales de corrección/preferencia del usuario y acumula un dirty-bit en .planning/user-profile/. Emite nudge a perfilador-usuario-swl cuando cruza el umbral (default 3 señales).",
175
175
  "blocking": false,
176
176
  "async": true,
177
177
  "maxConsecutiveFailures": 5,
@@ -180,7 +180,7 @@
180
180
  "metricas-evolucion.js": {
181
181
  "event": "Stop",
182
182
  "matcher": "",
183
- "description": "Consolida métricas del ciclo de evolución (nudges accionados/pendientes, instintos, fallos de agentes, evoluciones aplicadas/revertidas) y actualiza .planning/evolucion/metricas.json con health_score compuesto. Dispara escalamiento a alertas persistentes si >=5 nudges del mismo tipo ignorados en 14d.",
183
+ "description": "Consolida métricas del ciclo de evolución (nudges accionados/pendientes, instintos, fallos de agentes, evoluciones aplicadas/revertidas) y actualiza .planning/evolution/metricas.json con health_score compuesto. Dispara escalamiento a alertas persistentes si >=5 nudges del mismo tipo ignorados en 14d.",
184
184
  "blocking": false,
185
185
  "async": true,
186
186
  "maxConsecutiveFailures": 5,
@@ -198,7 +198,7 @@
198
198
  "auto-evolucion.js": {
199
199
  "event": "SubagentStop",
200
200
  "matcher": "",
201
- "description": "Registra cada terminación de subagente SWL en .planning/auto-evolucion/agentes.jsonl y emite nudge a /swl:evolucionar cuando un agente acumula fallos o volumen de runs (ventana 14 días, throttle 24h).",
201
+ "description": "Registra cada terminación de subagente SWL en .planning/auto-evolution/agentes.jsonl y emite nudge a /swl:evolucionar cuando un agente acumula fallos o volumen de runs (ventana 14 días, throttle 24h).",
202
202
  "blocking": false,
203
203
  "async": true,
204
204
  "maxConsecutiveFailures": 5,
@@ -207,7 +207,7 @@
207
207
  "validar-formato-post-subagente.js": {
208
208
  "event": "SubagentStop",
209
209
  "matcher": "",
210
- "description": "Valida output de subagentes con schema declarado en manifiestos/agent-output-schemas.json (revisor-* y tdd-qa). Registra violaciones en .planning/evolucion/formato-violaciones.jsonl. Opt-out: SWL_FORMATO_VALIDACION=0.",
210
+ "description": "Valida output de subagentes con schema declarado en manifiestos/agent-output-schemas.json (revisor-* y tdd-qa). Registra violaciones en .planning/evolution/formato-violaciones.jsonl. Opt-out: SWL_FORMATO_VALIDACION=0.",
211
211
  "blocking": false,
212
212
  "async": true,
213
213
  "maxConsecutiveFailures": 3,
@@ -323,7 +323,7 @@
323
323
  "captura-feedback-usuario.js": {
324
324
  "event": "UserPromptSubmit",
325
325
  "matcher": "",
326
- "description": "Detecta correcciones explícitas del usuario (no hagas X, prefiero Y, recuerda Z, nunca W) y las encola en .planning/evolucion/feedback-queue.jsonl para consumo por perfilador-usuario-swl y el ciclo AGP. Patrones regex en español e inglés. Opt-out: SWL_CAPTURAR_FEEDBACK=0.",
326
+ "description": "Detecta correcciones explícitas del usuario (no hagas X, prefiero Y, recuerda Z, nunca W) y las encola en .planning/evolution/feedback-queue.jsonl para consumo por perfilador-usuario-swl y el ciclo AGP. Patrones regex en español e inglés. Opt-out: SWL_CAPTURAR_FEEDBACK=0.",
327
327
  "blocking": false,
328
328
  "async": true,
329
329
  "maxConsecutiveFailures": 5,
@@ -341,7 +341,7 @@
341
341
  "aiisms-detector.js": {
342
342
  "event": "PostToolUse",
343
343
  "matcher": "Write|Edit|MultiEdit",
344
- "description": "Ejecuta detector portable Python contra archivos .md recién modificados y emite nudge a .planning/evolucion/nudges.jsonl si encuentra al menos un AI-ism P0. No bloquea. Requiere Python 3.10+. Respeta auto-referencia (habilidades/estilo-sin-ai-isms/), .planning/, temp/, node_modules/. Opt-out: SWL_AIISMS_HOOK=0.",
344
+ "description": "Ejecuta detector portable Python contra archivos .md recién modificados y emite nudge a .planning/evolution/nudges.jsonl si encuentra al menos un AI-ism P0. No bloquea. Requiere Python 3.10+. Respeta auto-referencia (habilidades/estilo-sin-ai-isms/), .planning/, temp/, node_modules/. Opt-out: SWL_AIISMS_HOOK=0.",
345
345
  "blocking": false,
346
346
  "async": true,
347
347
  "maxConsecutiveFailures": 5,
@@ -350,7 +350,7 @@
350
350
  "claudemd-bloat-detector.js": {
351
351
  "event": "PostToolUse",
352
352
  "matcher": "Write|Edit|MultiEdit",
353
- "description": "Ejecuta scripts/auditar-claudemd.js contra archivos CLAUDE.md recién modificados (basename exacto, no cualquier .md). Emite nudge a .planning/evolucion/nudges.jsonl si veredicto != OK (líneas excesivas, bullets gigantes, secciones canónicas ausentes, sin @references, placeholders). Aplica ADR-0016 (best practices Anthropic 'The CLAUDE.md file'). No bloquea. Excluye temp/, node_modules/, respositorios-git/, .planning/. Opt-out: SWL_CLAUDEMD_BLOAT=0.",
353
+ "description": "Ejecuta scripts/auditar-claudemd.js contra archivos CLAUDE.md recién modificados (basename exacto, no cualquier .md). Emite nudge a .planning/evolution/nudges.jsonl si veredicto != OK (líneas excesivas, bullets gigantes, secciones canónicas ausentes, sin @references, placeholders). Aplica ADR-0016 (best practices Anthropic 'The CLAUDE.md file'). No bloquea. Excluye temp/, node_modules/, respositorios-git/, .planning/. Opt-out: SWL_CLAUDEMD_BLOAT=0.",
354
354
  "blocking": false,
355
355
  "async": true,
356
356
  "maxConsecutiveFailures": 5,
@@ -359,7 +359,7 @@
359
359
  "claudemd-duplicacion-detector.js": {
360
360
  "event": "PostToolUse",
361
361
  "matcher": "Write|Edit|MultiEdit",
362
- "description": "Detecta duplicación de reglas globales (~/.claude/rules/) inline en CLAUDE.md de proyecto. Consume scripts/lib/detector-reglas-duplicadas.js + catálogo scripts/lib/reglas-globales-conocidas.json. Aplica regla reglas/sin-duplicacion-reglas-globales.md. Emite nudge a .planning/evolucion/nudges.jsonl si hay duplicaciones detectadas. No bloquea — kind: claudemd-duplicacion-reglas. Excluye temp/, node_modules/, respositorios-git/, .planning/, ~/.claude/ (user-level). Opt-out: SWL_CLAUDEMD_DUPLICACION=0.",
362
+ "description": "Detecta duplicación de reglas globales (~/.claude/rules/) inline en CLAUDE.md de proyecto. Consume scripts/lib/detector-reglas-duplicadas.js + catálogo scripts/lib/reglas-globales-conocidas.json. Aplica regla reglas/sin-duplicacion-reglas-globales.md. Emite nudge a .planning/evolution/nudges.jsonl si hay duplicaciones detectadas. No bloquea — kind: claudemd-duplicacion-reglas. Excluye temp/, node_modules/, respositorios-git/, .planning/, ~/.claude/ (user-level). Opt-out: SWL_CLAUDEMD_DUPLICACION=0.",
363
363
  "blocking": false,
364
364
  "async": true,
365
365
  "maxConsecutiveFailures": 5,
@@ -368,7 +368,7 @@
368
368
  "validar-intent-spec.js": {
369
369
  "event": "PostToolUse",
370
370
  "matcher": "Write|Edit|MultiEdit",
371
- "description": "Verifica que agentes nivelRiesgo:ALTO declaren las 6 partes del framework Intent Engineering (strategy, healthMetrics, steering, hardGuardrails, maxTurnos, fragmentos:[_intent-spec]) segun reglas/intent-engineering.md. Solo aplica a agentes/*.md no fragmentos. Emite nudge a .planning/evolucion/nudges.jsonl si faltan campos. No bloquea (modo warn-only inicial; promocion a blocking:true tras 2 semanas estables). Excluye temp/, node_modules/, respositorios-git/, _userland/, .planning/. Opt-out: SWL_INTENT_SPEC=0. ADR-0027.",
371
+ "description": "Verifica que agentes nivelRiesgo:ALTO declaren las 6 partes del framework Intent Engineering (strategy, healthMetrics, steering, hardGuardrails, maxTurnos, fragmentos:[_intent-spec]) segun reglas/intent-engineering.md. Solo aplica a agentes/*.md no fragmentos. Emite nudge a .planning/evolution/nudges.jsonl si faltan campos. No bloquea (modo warn-only inicial; promocion a blocking:true tras 2 semanas estables). Excluye temp/, node_modules/, respositorios-git/, _userland/, .planning/. Opt-out: SWL_INTENT_SPEC=0. ADR-0027.",
372
372
  "blocking": false,
373
373
  "async": true,
374
374
  "maxConsecutiveFailures": 5,
@@ -409,6 +409,15 @@
409
409
  "async": false,
410
410
  "maxConsecutiveFailures": 5,
411
411
  "degradeOnFailure": "skip"
412
+ },
413
+ "validar-planning-paths.js": {
414
+ "event": "PostToolUse",
415
+ "matcher": "Write|Edit|MultiEdit",
416
+ "description": "Advierte cuando una sesion crea un directorio top-level NUEVO en .planning/ fuera de la allowlist canonica (manifiestos/planning-paths.json). Atrapa divergencias es/en (auditoria/ vs audit/, ux/ vs design/) antes de que proliferen. Aplica reglas/analizar-directorios-antes-de-escribir.md, cierra DT-PLANNING-OUTPUT-PATHS (ADR-0031). Emite nudge kind: planning-path-divergente a .planning/evolution/nudges.jsonl. No bloquea (warn-only). Opt-out: SWL_PLANNING_PATHS=0.",
417
+ "blocking": false,
418
+ "async": true,
419
+ "maxConsecutiveFailures": 5,
420
+ "degradeOnFailure": "skip"
412
421
  }
413
422
  }
414
423
  }