@saulwade/swl-ses 1.5.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/CLAUDE.md +225 -209
  2. package/README.md +578 -561
  3. package/agentes/arquitecto-swl.md +33 -1
  4. package/agentes/nemesis-auditor-swl.md +59 -19
  5. package/bin/swl-mcp-server.js +214 -214
  6. package/bin/swl-ses.js +49 -7
  7. package/comandos/swl/.evolved.json +22 -22
  8. package/comandos/swl/contribuir.md +233 -233
  9. package/comandos/swl/nemesis.md +230 -56
  10. package/gateway/lib/event-channel.js +191 -191
  11. package/habilidades/backend-production-resilience/SKILL.md +288 -288
  12. package/habilidades/benchmark-memoria/SKILL.md +186 -186
  13. package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
  14. package/habilidades/doubt-driven-review/SKILL.md +171 -171
  15. package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
  16. package/habilidades/ejecutar-task-iterativo/SKILL.md +278 -278
  17. package/habilidades/eval-framework/SKILL.md +212 -212
  18. package/habilidades/feynman-auditor-swl/SKILL.md +123 -123
  19. package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -108
  20. package/habilidades/harness-claude-code/SKILL.md +299 -299
  21. package/habilidades/infra-github-actions/SKILL.md +166 -166
  22. package/habilidades/legacy-code-rescue/SKILL.md +267 -267
  23. package/habilidades/manejo-errores/.evolved.json +8 -8
  24. package/habilidades/meta-skills-estandar/SKILL.md +207 -4
  25. package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
  26. package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -163
  27. package/habilidades/nemesis-evaluacion-json/SKILL.md +266 -0
  28. package/habilidades/nemesis-redistribuir/SKILL.md +341 -0
  29. package/habilidades/node-experto/SKILL.md +94 -4
  30. package/habilidades/patrones-python/SKILL.md +229 -229
  31. package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
  32. package/habilidades/planear-fase/SKILL.md +319 -319
  33. package/habilidades/protocolo-revision-swl/SKILL.md +350 -276
  34. package/habilidades/release-semver/.evolved.json +8 -8
  35. package/habilidades/state-inconsistency-auditor-swl/SKILL.md +166 -166
  36. package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -147
  37. package/habilidades/tdd-workflow/SKILL.md +121 -4
  38. package/habilidades/testing-python/SKILL.md +340 -340
  39. package/habilidades/web-fetcher-routing/SKILL.md +75 -75
  40. package/hooks/check-update.js +31 -3
  41. package/hooks/claudemd-bloat-detector.js +161 -161
  42. package/hooks/extraccion-aprendizajes.js +11 -0
  43. package/hooks/lib/agent-routing.js +107 -107
  44. package/hooks/lib/auto-consolidator.js +335 -335
  45. package/hooks/lib/error-classifier.js +308 -308
  46. package/hooks/lib/merkle-audit.js +96 -96
  47. package/hooks/lib/provenance-tracker.js +191 -191
  48. package/hooks/lib/rate-limit-tracker.js +253 -253
  49. package/hooks/lib/resource-quota.js +122 -122
  50. package/hooks/lib/retry-jitter.js +165 -165
  51. package/hooks/lib/security-net.js +201 -201
  52. package/hooks/lib/skill-auditor.js +588 -588
  53. package/hooks/lib/sync-status.js +228 -228
  54. package/hooks/lib/taint-tracker.js +107 -107
  55. package/hooks/lib/text-similarity.js +241 -241
  56. package/hooks/lib/toon-compressor.js +245 -245
  57. package/hooks/registro-turnos.js +209 -209
  58. package/hooks/sugerir-regenerar-inventario.js +170 -170
  59. package/hooks/validar-formato-post-subagente.js +140 -140
  60. package/hooks/validar-memoria-hook.js +218 -218
  61. package/instintos/prompt-appendices.yaml +57 -57
  62. package/manifiestos/agent-output-schemas.json +57 -57
  63. package/manifiestos/modulos.json +1324 -1321
  64. package/manifiestos/skills-lock.json +1142 -1114
  65. package/package.json +5 -4
  66. package/plantillas/auditor-veto-template.md +105 -105
  67. package/plantillas/github-workflows/README.md +47 -47
  68. package/plantillas/github-workflows/release-please.yml +44 -44
  69. package/plantillas/github-workflows/swl-ci.yml +107 -107
  70. package/plantillas/github-workflows/swl-security.yml +51 -51
  71. package/plugin.json +355 -351
  72. package/reglas/analisis-previo-tareas-grandes.md +172 -172
  73. package/reglas/arreglar-al-detectar.md +147 -147
  74. package/reglas/fragmentos-compartidos.md +152 -152
  75. package/reglas/harness-claude-code.md +213 -213
  76. package/reglas/registro-componentes-nuevos.md +192 -0
  77. package/reglas/usar-context7.md +226 -226
  78. package/schemas/diary-entry.schema.json +80 -80
  79. package/scripts/actualizar.js +110 -1
  80. package/scripts/audit-tools/audit-history.js +330 -330
  81. package/scripts/audit-tools/bundle-tracker.js +290 -290
  82. package/scripts/audit-tools/canary-monitor.js +352 -352
  83. package/scripts/audit-tools/code-profiler.js +605 -605
  84. package/scripts/audit-tools/dep-doctor.js +320 -320
  85. package/scripts/audit-tools/env-validator.js +206 -206
  86. package/scripts/audit-tools/lib/fs-walk.js +48 -48
  87. package/scripts/audit-tools/lib/output.js +23 -23
  88. package/scripts/audit-tools/migration-checker.js +392 -392
  89. package/scripts/audit-tools/pentest-scanner.js +1436 -1436
  90. package/scripts/benchmark-memoria.js +167 -167
  91. package/scripts/configurar-branch-protection.js +418 -418
  92. package/scripts/derivar-feature-list.js +489 -489
  93. package/scripts/desinstalar.js +105 -24
  94. package/scripts/detectar-aprendizajes-duplicados.js +151 -151
  95. package/scripts/doctor.js +27 -0
  96. package/scripts/field-report.js +199 -199
  97. package/scripts/generar-checklists-consolidados.js +273 -273
  98. package/scripts/generar-inventario.js +420 -420
  99. package/scripts/generar-matriz-lenguajes.js +271 -271
  100. package/scripts/instalador.js +55 -4
  101. package/scripts/lib/artefactos-python.js +43 -43
  102. package/scripts/lib/benchmark-metrics.js +160 -160
  103. package/scripts/lib/budget-enforcer.js +252 -252
  104. package/scripts/lib/configurar-ci.js +380 -380
  105. package/scripts/lib/contadores-inventario.js +217 -217
  106. package/scripts/lib/detectar-stack-detallado.js +307 -307
  107. package/scripts/lib/diary-entry.js +234 -234
  108. package/scripts/lib/eval-metrics-store.js +218 -218
  109. package/scripts/lib/eval-quality.js +171 -171
  110. package/scripts/lib/eval-schemas.js +144 -144
  111. package/scripts/lib/eval-self-correct.js +106 -106
  112. package/scripts/lib/eval-validator.js +185 -185
  113. package/scripts/lib/expandir-targets.js +71 -71
  114. package/scripts/lib/jaccard-similarity.js +98 -98
  115. package/scripts/lib/longmemeval-runner.js +125 -125
  116. package/scripts/lib/mcp_config.py +127 -0
  117. package/scripts/lib/npm-version.js +261 -261
  118. package/scripts/lib/paquetes-conocidos.js +50 -50
  119. package/scripts/lib/parsear-opciones.js +3 -0
  120. package/scripts/lib/prompt-builder.js +264 -264
  121. package/scripts/lib/rrf-fusion.js +175 -175
  122. package/scripts/lib/scoring-instintos.js +277 -277
  123. package/scripts/lib/semantic-search.js +252 -252
  124. package/scripts/lib/toml-merge.js +204 -204
  125. package/scripts/lib/transformadores/codex.js +375 -375
  126. package/scripts/lib/transformadores/cursor.js +359 -359
  127. package/scripts/lib/ui.js +148 -22
  128. package/scripts/limpiar-artefactos-python.js +131 -131
  129. package/scripts/mcp-orchestrator.py +8 -18
  130. package/scripts/mcp-pool-manager.py +12 -23
  131. package/scripts/mcp-server/README.md +170 -170
  132. package/scripts/mcp-server/auth.js +105 -105
  133. package/scripts/mcp-server/cache.js +106 -106
  134. package/scripts/mcp-server/telemetry.js +78 -78
  135. package/scripts/migrar-csv-a-array.js +168 -168
  136. package/scripts/migrar-fase-dominio.js +201 -201
  137. package/scripts/publicar.js +511 -511
  138. package/scripts/run-eval.js +141 -141
  139. package/scripts/tui/componentes/selector-multi.js +189 -0
  140. package/scripts/tui/componentes/selector-unico.js +158 -0
  141. package/scripts/tui/ejecutores.js +375 -0
  142. package/scripts/tui/index.js +162 -0
  143. package/scripts/tui/lib/colores.js +129 -0
  144. package/scripts/tui/lib/render.js +264 -0
  145. package/scripts/tui/lib/teclas.js +113 -0
  146. package/scripts/tui/pantallas/inspect.js +173 -0
  147. package/scripts/tui/pantallas/install-wizard.js +334 -0
  148. package/scripts/tui/pantallas/menu-principal.js +52 -0
  149. package/scripts/tui/pantallas/progreso.js +274 -0
  150. package/scripts/tui/pantallas/resumen.js +132 -0
  151. package/scripts/tui/pantallas/uninstall-wizard.js +208 -0
  152. package/scripts/tui/pantallas/update-wizard.js +232 -0
  153. package/scripts/tui/pantallas/welcome.js +187 -0
  154. package/scripts/validar-userland-vacio.js +110 -110
  155. package/scripts/verificar-docs-vs-codigo.js +425 -0
@@ -1,212 +1,212 @@
1
- ---
2
- name: eval-framework
3
- description: >
4
- Eval framework para validar y puntuar outputs estructurados de SWL
5
- (aprendizajes, instintos, observaciones, resúmenes, contextos). Cargar
6
- cuando un agente produzca un output estructurado y se quiera medir su
7
- calidad antes de persistir, o cuando se audite la calidad histórica de
8
- funciones críticas (extractor-de-aprendizajes, perfilador-usuario,
9
- consolidador, planificador).
10
- version: "1.0.0"
11
- herramientasPermitidas: [Read, Bash]
12
- exclusiones:
13
- - "No cargar para validación de input de usuario o request HTTP — eso es validación de boundary, usar Pydantic/Zod en el endpoint."
14
- - "No cargar para auditoría de seguridad — usar `revisor-seguridad-swl` y `escaneo-secretos`."
15
- - "No cargar para tests unitarios de código — usar `tdd-workflow` y Vitest."
16
- - "No cargar cuando el output no tiene estructura definida (texto libre): el eval framework requiere schemas declarados o quality scorers específicos."
17
- evolvable: true # default para skill estandar
18
- ---
19
- # Eval Framework — Validación + Calidad de Outputs SWL
20
-
21
- ## Cuándo cargar
22
-
23
- - Tras producir un output estructurado (observación, aprendizaje, resumen,
24
- resultado de búsqueda) cuando se quiera puntuar su calidad antes de
25
- persistir.
26
- - Para auditar histórico de calidad de una función crítica (ver métricas
27
- agregadas en `.planning/evolucion/eval-metrics.json`).
28
- - En tests/CI cuando el contrato del output tenga campos obligatorios y
29
- quality thresholds.
30
- - En loops de auto-corrección donde un output inválido debe regenerarse
31
- con un prompt más estricto.
32
-
33
- ---
34
-
35
- ## Componentes del framework
36
-
37
- | Módulo | Propósito |
38
- |---|---|
39
- | `scripts/lib/eval-schemas.js` | Schemas JSON-lite para outputs (observación, resumen, search input, etc.). |
40
- | `scripts/lib/eval-validator.js` | Validador zero-deps de schemas (sin Zod). |
41
- | `scripts/lib/eval-quality.js` | Funciones de scoring: `scoreObservacion`, `scoreResumen`, `scoreAprendizaje`, `scoreInstinto`, `scoreRelevanciaContexto`. |
42
- | `scripts/lib/eval-self-correct.js` | Loop de retry con sufijo estricto cuando validador falla. |
43
- | `scripts/lib/eval-metrics-store.js` | Persistencia: JSONL append-only (`eval-results.jsonl`) + agregado JSON (`eval-metrics.json`). |
44
- | `scripts/run-eval.js` | CLI para evaluar un output desde archivo JSON. |
45
-
46
- ---
47
-
48
- ## Uso típico desde agente o test
49
-
50
- ### Validar output contra schema
51
-
52
- ```js
53
- const { validar } = require('./scripts/lib/eval-validator');
54
- const { COMPRESS_OUTPUT_SCHEMA } = require('./scripts/lib/eval-schemas');
55
-
56
- const observacion = {
57
- type: 'discovery',
58
- title: 'Detalle relevante',
59
- facts: ['fact 1', 'fact 2'],
60
- narrative: 'Narrativa con suficiente detalle para evaluar',
61
- concepts: ['c1'],
62
- files: ['ruta/al/archivo.js'],
63
- importance: 7,
64
- };
65
-
66
- const r = validar(observacion, COMPRESS_OUTPUT_SCHEMA);
67
- if (!r.valid) {
68
- console.error('Output inválido:', r.errors);
69
- } else {
70
- // Persistir
71
- }
72
- ```
73
-
74
- ### Puntuar calidad (independiente de validez)
75
-
76
- ```js
77
- const { scoreObservacion, scoreAprendizaje, scoreInstinto } = require('./scripts/lib/eval-quality');
78
-
79
- const score = scoreObservacion(observacion);
80
- // score ∈ [0, 100]. 100 = todos los campos óptimos.
81
- ```
82
-
83
- ### Loop de auto-corrección
84
-
85
- ```js
86
- const { compresseConReintento } = require('./scripts/lib/eval-self-correct');
87
-
88
- const productor = async (sysPrompt, userPrompt) => {
89
- // Llamar al LLM o ejecutar Skill que produzca el output
90
- return await llamarClaude(sysPrompt, userPrompt);
91
- };
92
-
93
- const validador = (output) => {
94
- const parsed = JSON.parse(output);
95
- return validar(parsed, COMPRESS_OUTPUT_SCHEMA);
96
- };
97
-
98
- const r = await compresseConReintento({
99
- productor, validador,
100
- sysPrompt: '...', userPrompt: '...',
101
- maxRetries: 2,
102
- });
103
-
104
- if (r.valid) {
105
- // r.output es válido (puede haber requerido r.intentos retries)
106
- }
107
- ```
108
-
109
- ### Persistir métricas para auditoría histórica
110
-
111
- ```js
112
- const ms = require('./scripts/lib/eval-metrics-store');
113
-
114
- ms.registrar(process.cwd(), {
115
- functionId: 'extractor-de-aprendizajes::scorer',
116
- latencyMs: 42,
117
- success: true,
118
- qualityScore: 85,
119
- });
120
-
121
- // Lectura agregada
122
- const m = ms.obtener(process.cwd(), 'extractor-de-aprendizajes::scorer');
123
- // → { totalCalls, successCount, failureCount, avgLatencyMs, avgQualityScore, ... }
124
- ```
125
-
126
- ### CLI desde Bash (para CI o manual)
127
-
128
- ```bash
129
- # Crear archivo de eval
130
- cat > /tmp/eval.json << 'EOF'
131
- {
132
- "functionId": "memoria-busqueda::search",
133
- "schemaName": "MEMORY_SEARCH_RESULT_SCHEMA",
134
- "qualityScorer": null,
135
- "expectedKeys": ["id", "tipo", "titulo", "fecha", "relevancia"],
136
- "output": { ... }
137
- }
138
- EOF
139
-
140
- # Ejecutar
141
- node scripts/run-eval.js /tmp/eval.json
142
- # Exit 0 si valid, 1 si inválido. Persiste métricas automáticamente.
143
-
144
- # Reconstruir agregado desde JSONL si se corrompe
145
- node scripts/run-eval.js --rebuild-aggregate
146
- ```
147
-
148
- ---
149
-
150
- ## Schemas disponibles
151
-
152
- - `COMPRESS_OUTPUT_SCHEMA` — observación comprimida con type, title, facts,
153
- narrative, concepts, files, importance.
154
- - `SUMMARY_OUTPUT_SCHEMA` — resumen de sesión con title, narrative,
155
- keyDecisions, filesModified, concepts.
156
- - `SEARCH_INPUT_SCHEMA` — input de búsqueda { query, limit? }.
157
- - `REMEMBER_INPUT_SCHEMA` — input de "remember" { content, type?,
158
- concepts?, files? }.
159
- - `EVAL_RESULT_SCHEMA` — resultado de evaluación { valid, errors?,
160
- qualityScore, latencyMs, functionId, metadata? }.
161
- - `MEMORY_SEARCH_RESULT_SCHEMA` — resultado de `hooks/lib/memory-search`
162
- con id, tipo, titulo, fecha, relevancia, combinedScore?, confidence?.
163
-
164
- Agregar más schemas en `scripts/lib/eval-schemas.js` siguiendo el formato
165
- JSON Schema-lite (subset documentado en `eval-validator.js`).
166
-
167
- ---
168
-
169
- ## Quality scorers disponibles
170
-
171
- - `scoreObservacion(obs)` — observación con type/title/facts/narrative/concepts/importance.
172
- - `scoreResumen(summary)` — resumen con title/narrative/keyDecisions/filesModified/concepts.
173
- - `scoreAprendizaje(aprendizaje)` — aprendizaje SWL con titulo/contenido/tipo (específico de SWL).
174
- - `scoreInstinto(instinto)` — instinto con pattern/confidence/status/source_*/evidence_count (específico de SWL).
175
- - `scoreRelevanciaContexto(context, project)` — contexto inyectado en sesión.
176
-
177
- Cada scorer devuelve un número en [0, 100]. Los criterios están documentados
178
- en cada función en `scripts/lib/eval-quality.js`.
179
-
180
- ---
181
-
182
- ## Diferencias con tests unitarios
183
-
184
- | Eval framework | Tests unitarios |
185
- |---|---|
186
- | Mide calidad subjetiva sobre estructura | Mide correctitud lógica |
187
- | Score graduado [0, 100] | Pass/fail binario |
188
- | Persiste histórico para auditoría | No persiste (corre en CI) |
189
- | Para outputs estructurados de agentes | Para funciones puras / API |
190
- | Permite retry con prompt estricto | No aplicable |
191
-
192
- Los dos son complementarios: tests unitarios para `scoring-instintos.js`,
193
- eval framework para "¿el aprendizaje que extrajo el hook es de calidad?".
194
-
195
- ---
196
-
197
- ## Gotchas / Errores comunes no obvios
198
-
199
- - **Validez estructural ≠ calidad**: un aprendizaje con `titulo: "X"` y
200
- `contenido: "trivial"` puede pasar `expectedKeys` pero tener
201
- `qualityScore: 0`. El framework los distingue. En CI gates, considerar
202
- ambos: `valid && qualityScore >= 60`.
203
- - **Métricas agregadas se reescriben atómicamente**: si dos procesos
204
- llaman `registrar()` en paralelo sobre el mismo `functionId`, el último
205
- gana (race condition en agregado). Para alta concurrencia usar
206
- `reconstruirAgregado()` periódicamente desde el JSONL append-only.
207
- - **`run-eval.js` exit code**: 0 = valid, 1 = inválido o error de I/O,
208
- 2 = error de uso. No confundir con quality threshold — el CLI no
209
- bloquea por quality bajo, solo por validez.
210
- - **`compresseConReintento` no reintenta indefinidamente**: respeta
211
- `maxRetries`. Tras agotar reintentos devuelve el último output con
212
- `valid: false`. El caller decide qué hacer.
1
+ ---
2
+ name: eval-framework
3
+ description: >
4
+ Eval framework para validar y puntuar outputs estructurados de SWL
5
+ (aprendizajes, instintos, observaciones, resúmenes, contextos). Cargar
6
+ cuando un agente produzca un output estructurado y se quiera medir su
7
+ calidad antes de persistir, o cuando se audite la calidad histórica de
8
+ funciones críticas (extractor-de-aprendizajes, perfilador-usuario,
9
+ consolidador, planificador).
10
+ version: "1.0.0"
11
+ herramientasPermitidas: [Read, Bash]
12
+ exclusiones:
13
+ - "No cargar para validación de input de usuario o request HTTP — eso es validación de boundary, usar Pydantic/Zod en el endpoint."
14
+ - "No cargar para auditoría de seguridad — usar `revisor-seguridad-swl` y `escaneo-secretos`."
15
+ - "No cargar para tests unitarios de código — usar `tdd-workflow` y Vitest."
16
+ - "No cargar cuando el output no tiene estructura definida (texto libre): el eval framework requiere schemas declarados o quality scorers específicos."
17
+ evolvable: true # default para skill estandar
18
+ ---
19
+ # Eval Framework — Validación + Calidad de Outputs SWL
20
+
21
+ ## Cuándo cargar
22
+
23
+ - Tras producir un output estructurado (observación, aprendizaje, resumen,
24
+ resultado de búsqueda) cuando se quiera puntuar su calidad antes de
25
+ persistir.
26
+ - Para auditar histórico de calidad de una función crítica (ver métricas
27
+ agregadas en `.planning/evolucion/eval-metrics.json`).
28
+ - En tests/CI cuando el contrato del output tenga campos obligatorios y
29
+ quality thresholds.
30
+ - En loops de auto-corrección donde un output inválido debe regenerarse
31
+ con un prompt más estricto.
32
+
33
+ ---
34
+
35
+ ## Componentes del framework
36
+
37
+ | Módulo | Propósito |
38
+ |---|---|
39
+ | `scripts/lib/eval-schemas.js` | Schemas JSON-lite para outputs (observación, resumen, search input, etc.). |
40
+ | `scripts/lib/eval-validator.js` | Validador zero-deps de schemas (sin Zod). |
41
+ | `scripts/lib/eval-quality.js` | Funciones de scoring: `scoreObservacion`, `scoreResumen`, `scoreAprendizaje`, `scoreInstinto`, `scoreRelevanciaContexto`. |
42
+ | `scripts/lib/eval-self-correct.js` | Loop de retry con sufijo estricto cuando validador falla. |
43
+ | `scripts/lib/eval-metrics-store.js` | Persistencia: JSONL append-only (`eval-results.jsonl`) + agregado JSON (`eval-metrics.json`). |
44
+ | `scripts/run-eval.js` | CLI para evaluar un output desde archivo JSON. |
45
+
46
+ ---
47
+
48
+ ## Uso típico desde agente o test
49
+
50
+ ### Validar output contra schema
51
+
52
+ ```js
53
+ const { validar } = require('./scripts/lib/eval-validator');
54
+ const { COMPRESS_OUTPUT_SCHEMA } = require('./scripts/lib/eval-schemas');
55
+
56
+ const observacion = {
57
+ type: 'discovery',
58
+ title: 'Detalle relevante',
59
+ facts: ['fact 1', 'fact 2'],
60
+ narrative: 'Narrativa con suficiente detalle para evaluar',
61
+ concepts: ['c1'],
62
+ files: ['ruta/al/archivo.js'],
63
+ importance: 7,
64
+ };
65
+
66
+ const r = validar(observacion, COMPRESS_OUTPUT_SCHEMA);
67
+ if (!r.valid) {
68
+ console.error('Output inválido:', r.errors);
69
+ } else {
70
+ // Persistir
71
+ }
72
+ ```
73
+
74
+ ### Puntuar calidad (independiente de validez)
75
+
76
+ ```js
77
+ const { scoreObservacion, scoreAprendizaje, scoreInstinto } = require('./scripts/lib/eval-quality');
78
+
79
+ const score = scoreObservacion(observacion);
80
+ // score ∈ [0, 100]. 100 = todos los campos óptimos.
81
+ ```
82
+
83
+ ### Loop de auto-corrección
84
+
85
+ ```js
86
+ const { compresseConReintento } = require('./scripts/lib/eval-self-correct');
87
+
88
+ const productor = async (sysPrompt, userPrompt) => {
89
+ // Llamar al LLM o ejecutar Skill que produzca el output
90
+ return await llamarClaude(sysPrompt, userPrompt);
91
+ };
92
+
93
+ const validador = (output) => {
94
+ const parsed = JSON.parse(output);
95
+ return validar(parsed, COMPRESS_OUTPUT_SCHEMA);
96
+ };
97
+
98
+ const r = await compresseConReintento({
99
+ productor, validador,
100
+ sysPrompt: '...', userPrompt: '...',
101
+ maxRetries: 2,
102
+ });
103
+
104
+ if (r.valid) {
105
+ // r.output es válido (puede haber requerido r.intentos retries)
106
+ }
107
+ ```
108
+
109
+ ### Persistir métricas para auditoría histórica
110
+
111
+ ```js
112
+ const ms = require('./scripts/lib/eval-metrics-store');
113
+
114
+ ms.registrar(process.cwd(), {
115
+ functionId: 'extractor-de-aprendizajes::scorer',
116
+ latencyMs: 42,
117
+ success: true,
118
+ qualityScore: 85,
119
+ });
120
+
121
+ // Lectura agregada
122
+ const m = ms.obtener(process.cwd(), 'extractor-de-aprendizajes::scorer');
123
+ // → { totalCalls, successCount, failureCount, avgLatencyMs, avgQualityScore, ... }
124
+ ```
125
+
126
+ ### CLI desde Bash (para CI o manual)
127
+
128
+ ```bash
129
+ # Crear archivo de eval
130
+ cat > /tmp/eval.json << 'EOF'
131
+ {
132
+ "functionId": "memoria-busqueda::search",
133
+ "schemaName": "MEMORY_SEARCH_RESULT_SCHEMA",
134
+ "qualityScorer": null,
135
+ "expectedKeys": ["id", "tipo", "titulo", "fecha", "relevancia"],
136
+ "output": { ... }
137
+ }
138
+ EOF
139
+
140
+ # Ejecutar
141
+ node scripts/run-eval.js /tmp/eval.json
142
+ # Exit 0 si valid, 1 si inválido. Persiste métricas automáticamente.
143
+
144
+ # Reconstruir agregado desde JSONL si se corrompe
145
+ node scripts/run-eval.js --rebuild-aggregate
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Schemas disponibles
151
+
152
+ - `COMPRESS_OUTPUT_SCHEMA` — observación comprimida con type, title, facts,
153
+ narrative, concepts, files, importance.
154
+ - `SUMMARY_OUTPUT_SCHEMA` — resumen de sesión con title, narrative,
155
+ keyDecisions, filesModified, concepts.
156
+ - `SEARCH_INPUT_SCHEMA` — input de búsqueda { query, limit? }.
157
+ - `REMEMBER_INPUT_SCHEMA` — input de "remember" { content, type?,
158
+ concepts?, files? }.
159
+ - `EVAL_RESULT_SCHEMA` — resultado de evaluación { valid, errors?,
160
+ qualityScore, latencyMs, functionId, metadata? }.
161
+ - `MEMORY_SEARCH_RESULT_SCHEMA` — resultado de `hooks/lib/memory-search`
162
+ con id, tipo, titulo, fecha, relevancia, combinedScore?, confidence?.
163
+
164
+ Agregar más schemas en `scripts/lib/eval-schemas.js` siguiendo el formato
165
+ JSON Schema-lite (subset documentado en `eval-validator.js`).
166
+
167
+ ---
168
+
169
+ ## Quality scorers disponibles
170
+
171
+ - `scoreObservacion(obs)` — observación con type/title/facts/narrative/concepts/importance.
172
+ - `scoreResumen(summary)` — resumen con title/narrative/keyDecisions/filesModified/concepts.
173
+ - `scoreAprendizaje(aprendizaje)` — aprendizaje SWL con titulo/contenido/tipo (específico de SWL).
174
+ - `scoreInstinto(instinto)` — instinto con pattern/confidence/status/source_*/evidence_count (específico de SWL).
175
+ - `scoreRelevanciaContexto(context, project)` — contexto inyectado en sesión.
176
+
177
+ Cada scorer devuelve un número en [0, 100]. Los criterios están documentados
178
+ en cada función en `scripts/lib/eval-quality.js`.
179
+
180
+ ---
181
+
182
+ ## Diferencias con tests unitarios
183
+
184
+ | Eval framework | Tests unitarios |
185
+ |---|---|
186
+ | Mide calidad subjetiva sobre estructura | Mide correctitud lógica |
187
+ | Score graduado [0, 100] | Pass/fail binario |
188
+ | Persiste histórico para auditoría | No persiste (corre en CI) |
189
+ | Para outputs estructurados de agentes | Para funciones puras / API |
190
+ | Permite retry con prompt estricto | No aplicable |
191
+
192
+ Los dos son complementarios: tests unitarios para `scoring-instintos.js`,
193
+ eval framework para "¿el aprendizaje que extrajo el hook es de calidad?".
194
+
195
+ ---
196
+
197
+ ## Gotchas / Errores comunes no obvios
198
+
199
+ - **Validez estructural ≠ calidad**: un aprendizaje con `titulo: "X"` y
200
+ `contenido: "trivial"` puede pasar `expectedKeys` pero tener
201
+ `qualityScore: 0`. El framework los distingue. En CI gates, considerar
202
+ ambos: `valid && qualityScore >= 60`.
203
+ - **Métricas agregadas se reescriben atómicamente**: si dos procesos
204
+ llaman `registrar()` en paralelo sobre el mismo `functionId`, el último
205
+ gana (race condition en agregado). Para alta concurrencia usar
206
+ `reconstruirAgregado()` periódicamente desde el JSONL append-only.
207
+ - **`run-eval.js` exit code**: 0 = valid, 1 = inválido o error de I/O,
208
+ 2 = error de uso. No confundir con quality threshold — el CLI no
209
+ bloquea por quality bajo, solo por validez.
210
+ - **`compresseConReintento` no reintenta indefinidamente**: respeta
211
+ `maxRetries`. Tras agotar reintentos devuelve el último output con
212
+ `valid: false`. El caller decide qué hacer.