@saulwade/swl-ses 1.0.0 → 1.1.1

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 (108) hide show
  1. package/CLAUDE.md +8 -5
  2. package/README.md +2 -2
  3. package/agentes/accesibilidad-wcag-swl.md +5 -7
  4. package/agentes/arquitecto-swl.md +5 -3
  5. package/agentes/auto-evolucion-swl.md +42 -12
  6. package/agentes/backend-api-swl.md +5 -3
  7. package/agentes/backend-csharp-swl.md +5 -3
  8. package/agentes/backend-go-swl.md +5 -3
  9. package/agentes/backend-java-swl.md +5 -3
  10. package/agentes/backend-node-swl.md +5 -3
  11. package/agentes/backend-python-swl.md +5 -3
  12. package/agentes/backend-rust-swl.md +5 -3
  13. package/agentes/backend-workers-swl.md +5 -3
  14. package/agentes/cloud-infra-swl.md +5 -6
  15. package/agentes/consolidador-swl.md +5 -3
  16. package/agentes/datos-swl.md +5 -7
  17. package/agentes/depurador-swl.md +6 -3
  18. package/agentes/devops-ci-swl.md +5 -3
  19. package/agentes/disenador-ui-swl.md +5 -7
  20. package/agentes/documentador-swl.md +5 -3
  21. package/agentes/frontend-angular-swl.md +5 -11
  22. package/agentes/frontend-css-swl.md +5 -9
  23. package/agentes/frontend-react-swl.md +5 -9
  24. package/agentes/frontend-swl.md +5 -9
  25. package/agentes/frontend-tailwind-swl.md +5 -9
  26. package/agentes/implementador-swl.md +6 -3
  27. package/agentes/investigador-swl.md +5 -3
  28. package/agentes/investigador-ux-swl.md +5 -9
  29. package/agentes/llm-apps-swl.md +5 -3
  30. package/agentes/migrador-swl.md +6 -3
  31. package/agentes/mobile-android-swl.md +5 -3
  32. package/agentes/mobile-cross-swl.md +5 -3
  33. package/agentes/mobile-ios-swl.md +5 -3
  34. package/agentes/mobile-testing-swl.md +5 -3
  35. package/agentes/notificador-swl.md +5 -3
  36. package/agentes/observabilidad-swl.md +5 -3
  37. package/agentes/orquestador-swl.md +29 -8
  38. package/agentes/pagos-swl.md +5 -3
  39. package/agentes/perfilador-usuario-swl.md +4 -2
  40. package/agentes/planificador-swl.md +5 -3
  41. package/agentes/producto-prd-swl.md +5 -3
  42. package/agentes/red-team-swl.md +4 -2
  43. package/agentes/release-manager-swl.md +6 -8
  44. package/agentes/rendimiento-swl.md +5 -6
  45. package/agentes/resolutor-build-swl.md +5 -3
  46. package/agentes/revisor-angular-swl.md +5 -3
  47. package/agentes/revisor-codigo-swl.md +5 -3
  48. package/agentes/revisor-csharp-swl.md +5 -3
  49. package/agentes/revisor-go-swl.md +5 -3
  50. package/agentes/revisor-java-swl.md +5 -3
  51. package/agentes/revisor-kotlin-swl.md +5 -3
  52. package/agentes/revisor-nextjs-swl.md +5 -3
  53. package/agentes/revisor-php-swl.md +5 -3
  54. package/agentes/revisor-react-swl.md +5 -3
  55. package/agentes/revisor-rust-swl.md +5 -3
  56. package/agentes/revisor-seguridad-swl.md +5 -3
  57. package/agentes/revisor-swift-swl.md +5 -3
  58. package/agentes/revisor-typescript-swl.md +5 -3
  59. package/agentes/sre-swl.md +5 -3
  60. package/agentes/tdd-qa-swl.md +5 -3
  61. package/agentes/ux-disenador-swl.md +5 -9
  62. package/bin/swl-ses.js +27 -6
  63. package/comandos/swl/evaluar-skill.md +18 -0
  64. package/comandos/swl/evolucion-estado.md +49 -0
  65. package/comandos/swl/release.md +41 -0
  66. package/comandos/swl/salud.md +23 -0
  67. package/hooks/auto-evolucion.js +35 -1
  68. package/hooks/clasificador-mensajes.js +50 -3
  69. package/hooks/lib/agent-routing.js +107 -0
  70. package/hooks/lib/delegation-tracker.js +162 -44
  71. package/hooks/lib/evolution-tracker.js +12 -3
  72. package/hooks/lib/memory-search.js +59 -1
  73. package/hooks/lib/nudge-tracker.js +10 -1
  74. package/hooks/lib/provenance-tracker.js +11 -3
  75. package/hooks/lib/text-similarity.js +241 -0
  76. package/hooks/metricas-evolucion.js +168 -1
  77. package/hooks/monitor-contexto.js +54 -6
  78. package/hooks/preservar-estado-pre-compact.js +11 -1
  79. package/hooks/risk-scoring.js +10 -1
  80. package/hooks/tracking-costos.js +10 -1
  81. package/hooks/validar-formato-post-subagente.js +140 -0
  82. package/hooks/validar-memoria-hook.js +218 -0
  83. package/manifiestos/agent-output-schemas.json +57 -0
  84. package/manifiestos/hooks-config.json +18 -0
  85. package/manifiestos/modulos.json +5 -1
  86. package/manifiestos/skills-lock.json +1065 -0
  87. package/package.json +4 -6
  88. package/plugin.json +1 -1
  89. package/reglas/arquitectura.md +20 -0
  90. package/reglas/fragmentos-compartidos.md +152 -0
  91. package/reglas/gobernanza.md +10 -1
  92. package/reglas/seguridad-agentes.md +12 -0
  93. package/reglas/skills-estandar.md +19 -0
  94. package/reglas/usar-context7.md +226 -0
  95. package/schemas/agent-frontmatter.schema.json +18 -0
  96. package/scripts/auditar-agentes-gaps.js +9 -1
  97. package/scripts/auditar-cobertura-frameworks.js +9 -1
  98. package/scripts/auditar-skills-gaps.js +9 -1
  99. package/scripts/bootstrap-instintos.js +11 -1
  100. package/scripts/generar-inventario.js +112 -9
  101. package/scripts/generar-matriz-lenguajes.js +271 -0
  102. package/scripts/generar-skills-lock.js +190 -0
  103. package/scripts/lib/estado.js +12 -2
  104. package/scripts/lib/gitignore-manifest.js +32 -2
  105. package/scripts/lib/semantic-search.js +10 -0
  106. package/scripts/migrar-csv-a-array.js +168 -0
  107. package/scripts/migrar-fase-dominio.js +201 -0
  108. package/scripts/validar-userland-vacio.js +110 -0
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: validar-formato-post-subagente.js
6
+ * Tipo: SubagentStop (async: true — fire-and-forget)
7
+ *
8
+ * Cuando un subagente SWL termina, valida que su output cumple con el
9
+ * schema declarado en `manifiestos/agent-output-schemas.json`. Si el
10
+ * agente no tiene schema declarado, el hook no hace nada — no asume
11
+ * que todo agente debe seguir el formato compacto.
12
+ *
13
+ * Registra el resultado en `.planning/evolucion/formato-violaciones.jsonl`
14
+ * para que `metricas-evolucion.js` calcule la tasa de violación por
15
+ * agente y la incluya en el dashboard de calidad conductual.
16
+ *
17
+ * Schema simple: lista de patrones regex que DEBEN aparecer en el output.
18
+ * Si todos matchean → conforme. Si falta alguno → violación con detalle.
19
+ *
20
+ * Opt-out: SWL_FORMATO_VALIDACION=0 desactiva el hook.
21
+ *
22
+ * El hook nunca bloquea — solo registra para análisis posterior.
23
+ */
24
+
25
+ const fs = require('fs');
26
+ const path = require('path');
27
+
28
+ const CWD = process.cwd();
29
+ const SCHEMAS_PATH = path.join(CWD, 'manifiestos', 'agent-output-schemas.json');
30
+ const LOG_PATH = path.join(CWD, '.planning', 'evolucion', 'formato-violaciones.jsonl');
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // Carga del schema (una vez)
34
+ // ---------------------------------------------------------------------------
35
+
36
+ function cargarSchemas() {
37
+ try {
38
+ const raw = fs.readFileSync(SCHEMAS_PATH, 'utf8');
39
+ const parsed = JSON.parse(raw);
40
+ return parsed.schemas || {};
41
+ } catch {
42
+ return {};
43
+ }
44
+ }
45
+
46
+ // ---------------------------------------------------------------------------
47
+ // Validación
48
+ // ---------------------------------------------------------------------------
49
+
50
+ /**
51
+ * Compara el output contra el schema. Devuelve { violation, errors }.
52
+ * @param {string} output - Texto del output del subagente
53
+ * @param {object} schema - { patronesRequeridos: string[] }
54
+ */
55
+ function validarOutput(output, schema) {
56
+ const errors = [];
57
+ const patrones = Array.isArray(schema.patronesRequeridos)
58
+ ? schema.patronesRequeridos
59
+ : [];
60
+ for (const patron of patrones) {
61
+ // El schema puede declarar inline flags estilo (?im) por compatibilidad
62
+ // con regex POSIX. JavaScript no los soporta inline — los stripeamos
63
+ // y aplicamos 'im' siempre (case-insensitive + multiline).
64
+ const limpio = patron.replace(/^\(\?[imsxu]+\)/, '');
65
+ let regex;
66
+ try { regex = new RegExp(limpio, 'im'); }
67
+ catch { errors.push(`Patrón inválido en schema: ${patron}`); continue; }
68
+ if (!regex.test(output)) {
69
+ errors.push(`Falta patrón requerido: ${patron}`);
70
+ }
71
+ }
72
+ return { violation: errors.length > 0, errors };
73
+ }
74
+
75
+ /**
76
+ * Extrae el output textual del subagente del payload del hook.
77
+ * El payload del SubagentStop expone el resultado en distintos lugares
78
+ * según versión de Claude Code; intentamos varias rutas.
79
+ */
80
+ function extraerOutput(data) {
81
+ const r = data.tool_response || data.tool_result || data.response || {};
82
+ // Posibles ubicaciones del output del subagente
83
+ if (typeof r.text === 'string') return r.text;
84
+ if (typeof r.content === 'string') return r.content;
85
+ if (Array.isArray(r.messages)) {
86
+ return r.messages
87
+ .map(m => (typeof m.content === 'string' ? m.content : ''))
88
+ .filter(Boolean)
89
+ .join('\n');
90
+ }
91
+ if (typeof r.output === 'string') return r.output;
92
+ return '';
93
+ }
94
+
95
+ function ensureDir() {
96
+ try { fs.mkdirSync(path.dirname(LOG_PATH), { recursive: true }); } catch { /* ignore */ }
97
+ }
98
+
99
+ // ---------------------------------------------------------------------------
100
+ // Entrypoint
101
+ // ---------------------------------------------------------------------------
102
+
103
+ let inputRaw = '';
104
+ process.stdin.on('data', chunk => { inputRaw += chunk; });
105
+
106
+ process.stdin.on('end', () => {
107
+ try {
108
+ if (process.env.SWL_FORMATO_VALIDACION === '0') return;
109
+
110
+ const data = JSON.parse(inputRaw);
111
+ const subagentType =
112
+ data.tool_input?.subagent_type ||
113
+ data.tool?.input?.subagent_type ||
114
+ data.subagent_type ||
115
+ null;
116
+ if (!subagentType) return;
117
+
118
+ const schemas = cargarSchemas();
119
+ const schema = schemas[subagentType];
120
+ if (!schema) return; // agente sin schema → no se evalúa
121
+
122
+ const output = extraerOutput(data);
123
+ if (!output || output.length < 10) return; // output trivial — no evaluar
124
+
125
+ const { violation, errors } = validarOutput(output, schema);
126
+ const entry = {
127
+ ts: new Date().toISOString(),
128
+ sessionId: String(data.session_id || 'default'),
129
+ agente: subagentType,
130
+ violation,
131
+ errors,
132
+ outputLen: output.length,
133
+ };
134
+
135
+ ensureDir();
136
+ fs.appendFileSync(LOG_PATH, JSON.stringify(entry) + '\n', 'utf8');
137
+ } catch {
138
+ // SubagentStop hook nunca bloquea por error interno.
139
+ }
140
+ });
@@ -0,0 +1,218 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Hook: validar-memoria-hook.js
6
+ * Tipo: PostToolUse (matcher: Write|Edit|MultiEdit)
7
+ *
8
+ * Cierra el gap señalado en `reglas/memoria-consolidada.md`: el script
9
+ * `scripts/validar-memoria.js` solo se ejecuta manualmente vía CLI, así
10
+ * que la contaminación entre canales (perfil-usuario, APRENDIZAJES,
11
+ * instintos) sucedía sin que nadie se enterara hasta que un humano
12
+ * corría el validador.
13
+ *
14
+ * Este hook dispara `validar-memoria.js` en modo JSON cada vez que se
15
+ * escribe un archivo de memoria sensible:
16
+ * - `.planning/APRENDIZAJES.md`
17
+ * - `instintos/perfil-usuario.yaml`
18
+ * - `instintos/proyecto.yaml`
19
+ * - `instintos/global.yaml`
20
+ *
21
+ * Comportamiento:
22
+ * - Sin violaciones → silencioso (exit 0).
23
+ * - Violaciones menores (canal incorrecto, duplicación cross-canal) →
24
+ * emite nudge informativo via systemMessage.
25
+ * - Violaciones críticas (secretos detectados) → emite mensaje fuerte
26
+ * pero NO bloquea (siguiendo el contrato de hooks PostToolUse: ya pasó).
27
+ * El bloqueo de secretos en escritura corresponde a `escaneo-secretos`
28
+ * (PreToolUse), este hook es la red de defensa secundaria.
29
+ *
30
+ * Opt-out: SWL_VALIDAR_MEMORIA=0 desactiva el hook.
31
+ *
32
+ * El hook nunca bloquea el flujo (siempre exit 0). Los errores internos
33
+ * se ignoran silenciosamente — la regla "PostToolUse no rompe nada".
34
+ */
35
+
36
+ const fs = require('fs');
37
+ const path = require('path');
38
+ const { spawnSync } = require('child_process');
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Configuración
42
+ // ---------------------------------------------------------------------------
43
+
44
+ /** Archivos cuya modificación dispara la validación. Paths relativos al CWD. */
45
+ const ARCHIVOS_MEMORIA = [
46
+ '.planning/APRENDIZAJES.md',
47
+ 'instintos/perfil-usuario.yaml',
48
+ 'instintos/proyecto.yaml',
49
+ 'instintos/global.yaml',
50
+ ];
51
+
52
+ /** Path del validador. */
53
+ const VALIDADOR = path.join(process.cwd(), 'scripts', 'validar-memoria.js');
54
+
55
+ /** Timeout para el validador (ms). Si tarda más, se aborta sin bloquear. */
56
+ const TIMEOUT_MS = 5000;
57
+
58
+ // ---------------------------------------------------------------------------
59
+ // Utilidades
60
+ // ---------------------------------------------------------------------------
61
+
62
+ /** Normaliza un path a forma POSIX para comparar contra ARCHIVOS_MEMORIA. */
63
+ function normalizar(p) {
64
+ if (!p) return '';
65
+ return String(p).replace(/\\/g, '/').replace(/^\.\//, '');
66
+ }
67
+
68
+ /** ¿El path tocado coincide con algún archivo de memoria? */
69
+ function esArchivoMemoria(filePath) {
70
+ const norm = normalizar(filePath);
71
+ return ARCHIVOS_MEMORIA.some(target => norm.endsWith(target));
72
+ }
73
+
74
+ /**
75
+ * Extrae el(los) path(s) afectado(s) por la herramienta del payload del hook.
76
+ * @param {object} data - Payload del hook (tool_input).
77
+ * @returns {string[]} Lista de paths afectados.
78
+ */
79
+ function extraerPaths(data) {
80
+ const ti = data.tool_input || {};
81
+ const paths = [];
82
+ if (ti.file_path) paths.push(ti.file_path);
83
+ if (ti.notebook_path) paths.push(ti.notebook_path);
84
+ // MultiEdit: file_path único + edits[]; ya cubierto arriba.
85
+ return paths;
86
+ }
87
+
88
+ /**
89
+ * Ejecuta el validador y devuelve un resumen normalizado.
90
+ * Schema esperado del validador (--json):
91
+ * {
92
+ * totalNoCriticas: N,
93
+ * totalCriticas: N,
94
+ * issues: {
95
+ * usuario_en_aprendizajes: [...],
96
+ * anti_tecnico_en_perfil: [...],
97
+ * duplicados_cross_canal: [...],
98
+ * secretos: [...], // críticas
99
+ * pii: [...], // críticas
100
+ * }
101
+ * }
102
+ *
103
+ * Si el validador falla o no existe, devuelve null (silencio).
104
+ */
105
+ function ejecutarValidador() {
106
+ if (!fs.existsSync(VALIDADOR)) return null;
107
+ try {
108
+ const r = spawnSync(process.execPath, [VALIDADOR, '--json'], {
109
+ cwd: process.cwd(),
110
+ encoding: 'utf8',
111
+ timeout: TIMEOUT_MS,
112
+ windowsHide: true,
113
+ });
114
+ if (r.status === null) return null;
115
+ if (!r.stdout) return null;
116
+ const parsed = JSON.parse(r.stdout);
117
+ const issues = parsed.issues || {};
118
+ return {
119
+ totalNoCriticas: Number.isInteger(parsed.totalNoCriticas) ? parsed.totalNoCriticas : 0,
120
+ totalCriticas: Number.isInteger(parsed.totalCriticas) ? parsed.totalCriticas : 0,
121
+ criticas: [
122
+ ...(issues.secretos || []).map(x => ({ tipo: 'secreto', detalle: x })),
123
+ ...(issues.pii || []).map(x => ({ tipo: 'pii', detalle: x })),
124
+ ],
125
+ menores: [
126
+ ...(issues.usuario_en_aprendizajes || []).map(x => ({ tipo: 'canal: usuario en aprendizajes', detalle: x })),
127
+ ...(issues.anti_tecnico_en_perfil || []).map(x => ({ tipo: 'canal: anti-patrón técnico en perfil', detalle: x })),
128
+ ...(issues.duplicados_cross_canal || []).map(x => ({ tipo: 'duplicación cross-canal', detalle: x })),
129
+ ],
130
+ };
131
+ } catch (_) {
132
+ return null;
133
+ }
134
+ }
135
+
136
+ /** Trunca y limpia un detalle para mostrarlo en una línea. */
137
+ function describir(item) {
138
+ if (typeof item === 'string') return item.slice(0, 120);
139
+ if (item && typeof item === 'object') {
140
+ const partes = [];
141
+ if (item.titulo) partes.push(item.titulo);
142
+ if (item.canal) partes.push(`canal=${item.canal}`);
143
+ if (item.linea) partes.push(`L${item.linea}`);
144
+ if (item.muestra) partes.push(item.muestra);
145
+ if (partes.length === 0) return JSON.stringify(item).slice(0, 120);
146
+ return partes.join(' | ').slice(0, 120);
147
+ }
148
+ return String(item).slice(0, 120);
149
+ }
150
+
151
+ /**
152
+ * Construye el mensaje de nudge según el resultado.
153
+ */
154
+ function construirMensaje(resultado, archivo) {
155
+ const { criticas, menores } = resultado;
156
+ if (criticas.length > 0) {
157
+ const lineas = [
158
+ '',
159
+ '╔══════════════════════════════════════════════════════╗',
160
+ '║ MEMORIA: VIOLACIÓN CRÍTICA DETECTADA ║',
161
+ '╚══════════════════════════════════════════════════════╝',
162
+ ` Archivo modificado: ${archivo}`,
163
+ ` Críticas: ${criticas.length}`,
164
+ ];
165
+ for (const c of criticas.slice(0, 3)) {
166
+ lineas.push(` • ${c.tipo}: ${describir(c.detalle)}`);
167
+ }
168
+ lineas.push(' Acción recomendada: revertir el cambio o sanitizar antes de commit.');
169
+ lineas.push(' Ver: reglas/memoria-consolidada.md');
170
+ lineas.push('');
171
+ return lineas.join('\n');
172
+ }
173
+ if (menores.length > 0) {
174
+ const lineas = [
175
+ '',
176
+ '⚠ Memoria: posibles violaciones de canal',
177
+ ` Archivo: ${archivo} | ${menores.length} hallazgo(s)`,
178
+ ];
179
+ for (const v of menores.slice(0, 3)) {
180
+ lineas.push(` • ${v.tipo}: ${describir(v.detalle)}`);
181
+ }
182
+ if (menores.length > 3) {
183
+ lineas.push(` • (y ${menores.length - 3} más — ejecutar: node scripts/validar-memoria.js)`);
184
+ }
185
+ lineas.push(' Ver: reglas/memoria-consolidada.md (canal correcto por tipo de dato)');
186
+ lineas.push('');
187
+ return lineas.join('\n');
188
+ }
189
+ return '';
190
+ }
191
+
192
+ // ---------------------------------------------------------------------------
193
+ // Entrypoint
194
+ // ---------------------------------------------------------------------------
195
+
196
+ let inputRaw = '';
197
+ process.stdin.on('data', chunk => { inputRaw += chunk; });
198
+
199
+ process.stdin.on('end', () => {
200
+ try {
201
+ if (process.env.SWL_VALIDAR_MEMORIA === '0') return;
202
+
203
+ const data = JSON.parse(inputRaw);
204
+ const paths = extraerPaths(data);
205
+ const archivoTocado = paths.find(esArchivoMemoria);
206
+ if (!archivoTocado) return;
207
+
208
+ const resultado = ejecutarValidador();
209
+ if (!resultado) return;
210
+
211
+ const mensaje = construirMensaje(resultado, normalizar(archivoTocado));
212
+ if (mensaje) {
213
+ process.stdout.write(JSON.stringify({ systemMessage: mensaje }));
214
+ }
215
+ } catch (_) {
216
+ // PostToolUse no bloquea por errores internos.
217
+ }
218
+ });
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "descripcion": "Schemas de output esperado por agente — formato compacto declarado en reglas/brevedad-output.md. El hook validar-formato-post-subagente.js usa estos patrones para detectar cuándo un agente devuelve output fuera de contrato.",
4
+ "version": "1.0.0",
5
+ "schemas": {
6
+ "revisor-codigo-swl": {
7
+ "descripcion": "Revisión de calidad — formato compacto",
8
+ "patronesRequeridos": [
9
+ "(?im)VEREDICTO\\s*:\\s*(APROBADO|APROBADO_CON_OBSERVACIONES|RECHAZADO|REQUIERE_CORRECCIONES|CUMPLE|PARCIAL|NO\\s+CUMPLE)",
10
+ "(?im)CR[IÍ]TICOS\\s*:\\s*\\d+",
11
+ "(?im)MAYORES\\s*:\\s*\\d+",
12
+ "(?im)MENORES\\s*:\\s*\\d+",
13
+ "(?im)HALLAZGOS\\s*:"
14
+ ]
15
+ },
16
+ "revisor-seguridad-swl": {
17
+ "descripcion": "Revisión de seguridad OWASP — formato compacto",
18
+ "patronesRequeridos": [
19
+ "(?im)VEREDICTO\\s*:\\s*(APROBADO|APROBADO_CON_OBSERVACIONES|RECHAZADO|REQUIERE_CORRECCIONES)",
20
+ "(?im)CR[IÍ]TICOS\\s*:\\s*\\d+",
21
+ "(?im)MAYORES\\s*:\\s*\\d+",
22
+ "(?im)HALLAZGOS\\s*:"
23
+ ]
24
+ },
25
+ "revisor-typescript-swl": {
26
+ "descripcion": "Revisión TypeScript — formato compacto",
27
+ "patronesRequeridos": [
28
+ "(?im)VEREDICTO\\s*:\\s*\\w+",
29
+ "(?im)CR[IÍ]TICOS\\s*:\\s*\\d+",
30
+ "(?im)HALLAZGOS\\s*:"
31
+ ]
32
+ },
33
+ "revisor-react-swl": {
34
+ "descripcion": "Revisión React — formato compacto",
35
+ "patronesRequeridos": [
36
+ "(?im)VEREDICTO\\s*:\\s*\\w+",
37
+ "(?im)CR[IÍ]TICOS\\s*:\\s*\\d+",
38
+ "(?im)HALLAZGOS\\s*:"
39
+ ]
40
+ },
41
+ "revisor-angular-swl": {
42
+ "descripcion": "Revisión Angular — formato compacto",
43
+ "patronesRequeridos": [
44
+ "(?im)VEREDICTO\\s*:\\s*\\w+",
45
+ "(?im)CR[IÍ]TICOS\\s*:\\s*\\d+",
46
+ "(?im)HALLAZGOS\\s*:"
47
+ ]
48
+ },
49
+ "tdd-qa-swl": {
50
+ "descripcion": "QA con TDD — reporte de implementación",
51
+ "patronesRequeridos": [
52
+ "(?im)ESTADO\\s*:\\s*(COMPLETADO|PARCIAL|BLOQUEADO)",
53
+ "(?im)(SLICES|TESTS)\\s*:"
54
+ ]
55
+ }
56
+ }
57
+ }
@@ -81,6 +81,15 @@
81
81
  "maxConsecutiveFailures": 3,
82
82
  "degradeOnFailure": "skip"
83
83
  },
84
+ "validar-memoria-hook.js": {
85
+ "event": "PostToolUse",
86
+ "matcher": "Write|Edit|MultiEdit",
87
+ "description": "Ejecuta scripts/validar-memoria.js cuando se modifica APRENDIZAJES.md, perfil-usuario.yaml o instintos/{proyecto,global}.yaml. Emite nudge si detecta canal incorrecto, duplicación cross-canal, secretos o PII. Opt-out con SWL_VALIDAR_MEMORIA=0.",
88
+ "blocking": false,
89
+ "async": true,
90
+ "maxConsecutiveFailures": 3,
91
+ "degradeOnFailure": "skip"
92
+ },
84
93
  "sugerir-regenerar-inventario.js": {
85
94
  "event": "PostToolUse",
86
95
  "matcher": "Write|Edit|MultiEdit",
@@ -186,6 +195,15 @@
186
195
  "maxConsecutiveFailures": 5,
187
196
  "degradeOnFailure": "skip"
188
197
  },
198
+ "validar-formato-post-subagente.js": {
199
+ "event": "SubagentStop",
200
+ "matcher": "",
201
+ "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.",
202
+ "blocking": false,
203
+ "async": true,
204
+ "maxConsecutiveFailures": 3,
205
+ "degradeOnFailure": "skip"
206
+ },
189
207
  "telemetria-agentes.js": {
190
208
  "event": "PostToolUse",
191
209
  "matcher": "Agent",
@@ -835,7 +835,8 @@
835
835
  "reglas/arquitectura.md",
836
836
  "reglas/brevedad-output.md",
837
837
  "reglas/seguridad-agentes.md",
838
- "reglas/memoria-consolidada.md"
838
+ "reglas/memoria-consolidada.md",
839
+ "reglas/usar-context7.md"
839
840
  ],
840
841
  "targets": [
841
842
  "claude",
@@ -856,6 +857,7 @@
856
857
  "reglas/api-diseno.md",
857
858
  "reglas/cloud-infra.md",
858
859
  "reglas/skills-estandar.md",
860
+ "reglas/fragmentos-compartidos.md",
859
861
  "reglas/gobernanza.md",
860
862
  "reglas/hooks.md",
861
863
  "reglas/patrones.md",
@@ -932,6 +934,8 @@
932
934
  "hooks/linea-estado.js",
933
935
  "hooks/monitor-contexto.js",
934
936
  "hooks/extraccion-aprendizajes.js",
937
+ "hooks/validar-memoria-hook.js",
938
+ "hooks/validar-formato-post-subagente.js",
935
939
  "hooks/inyeccion-contexto.js",
936
940
  "hooks/auto-consolidacion.js",
937
941
  "hooks/auto-background.js",