@saulwade/swl-ses 1.4.0 → 1.4.2
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.
- package/CLAUDE.md +4 -3
- package/README.md +15 -14
- package/agentes/nemesis-auditor-swl.md +161 -0
- package/bin/swl-mcp-server.js +187 -187
- package/comandos/swl/.evolved.json +22 -22
- package/comandos/swl/contribuir.md +233 -233
- package/comandos/swl/nemesis.md +122 -0
- package/comandos/swl/salud.md +34 -0
- package/comandos/swl/verificar.md +45 -0
- package/gateway/lib/event-channel.js +191 -191
- package/habilidades/backend-production-resilience/SKILL.md +288 -288
- package/habilidades/benchmark-memoria/SKILL.md +186 -186
- package/habilidades/diagrama-arquitectura/assets/template.html +276 -276
- package/habilidades/doubt-driven-review/SKILL.md +171 -171
- package/habilidades/doubt-driven-review/recursos/EXAMPLES.md +130 -130
- package/habilidades/eval-framework/SKILL.md +212 -212
- package/habilidades/feynman-auditor-swl/SKILL.md +123 -0
- package/habilidades/feynman-auditor-swl/recursos/preguntas-language-agnostic.md +108 -0
- package/habilidades/harness-claude-code/SKILL.md +299 -299
- package/habilidades/infra-github-actions/SKILL.md +166 -166
- package/habilidades/legacy-code-rescue/SKILL.md +267 -267
- package/habilidades/manejo-errores/.evolved.json +8 -8
- package/habilidades/meta-skills-estandar/recursos/convencion-examples.md +93 -93
- package/habilidades/meta-skills-estandar/recursos/skills-as-agents.md +163 -163
- package/habilidades/patrones-python/SKILL.md +229 -229
- package/habilidades/patrones-python/recursos/patrones-avanzados.md +469 -469
- package/habilidades/planear-fase/SKILL.md +319 -319
- package/habilidades/release-semver/.evolved.json +8 -8
- package/habilidades/state-inconsistency-auditor-swl/SKILL.md +166 -0
- package/habilidades/state-inconsistency-auditor-swl/recursos/coupled-state-patterns.md +147 -0
- package/habilidades/testing-python/SKILL.md +340 -340
- package/habilidades/web-fetcher-routing/SKILL.md +75 -0
- package/hooks/claudemd-bloat-detector.js +161 -161
- package/hooks/lib/agent-routing.js +107 -107
- package/hooks/lib/auto-consolidator.js +335 -335
- package/hooks/lib/error-classifier.js +308 -308
- package/hooks/lib/merkle-audit.js +96 -96
- package/hooks/lib/provenance-tracker.js +191 -191
- package/hooks/lib/rate-limit-tracker.js +253 -253
- package/hooks/lib/resource-quota.js +122 -122
- package/hooks/lib/retry-jitter.js +165 -165
- package/hooks/lib/security-net.js +201 -0
- package/hooks/lib/skill-auditor.js +588 -588
- package/hooks/lib/sync-status.js +228 -228
- package/hooks/lib/taint-tracker.js +107 -107
- package/hooks/lib/text-similarity.js +241 -241
- package/hooks/lib/toon-compressor.js +245 -245
- package/hooks/registro-turnos.js +209 -209
- package/hooks/sugerir-regenerar-inventario.js +170 -170
- package/hooks/validar-formato-post-subagente.js +140 -140
- package/hooks/validar-memoria-hook.js +218 -218
- package/instintos/prompt-appendices.yaml +57 -57
- package/manifiestos/agent-output-schemas.json +57 -57
- package/manifiestos/modulos.json +41 -6
- package/manifiestos/perfiles.json +2 -1
- package/manifiestos/skills-lock.json +30 -9
- package/package.json +2 -2
- package/plantillas/auditor-veto-template.md +105 -105
- package/plantillas/github-workflows/README.md +47 -47
- package/plantillas/github-workflows/release-please.yml +44 -44
- package/plantillas/github-workflows/swl-ci.yml +107 -107
- package/plantillas/github-workflows/swl-security.yml +51 -51
- package/plugin.json +10 -2
- package/reglas/analisis-previo-tareas-grandes.md +172 -172
- package/reglas/arreglar-al-detectar.md +147 -147
- package/reglas/fragmentos-compartidos.md +152 -152
- package/reglas/harness-claude-code.md +213 -213
- package/reglas/usar-context7.md +226 -226
- package/schemas/diary-entry.schema.json +80 -80
- package/scripts/audit-tools/audit-history.js +330 -0
- package/scripts/audit-tools/bundle-tracker.js +290 -0
- package/scripts/audit-tools/canary-monitor.js +352 -0
- package/scripts/audit-tools/code-profiler.js +605 -0
- package/scripts/audit-tools/dep-doctor.js +320 -0
- package/scripts/audit-tools/env-validator.js +206 -0
- package/scripts/audit-tools/lib/fs-walk.js +48 -0
- package/scripts/audit-tools/lib/output.js +23 -0
- package/scripts/audit-tools/migration-checker.js +392 -0
- package/scripts/audit-tools/pentest-scanner.js +1436 -0
- package/scripts/benchmark-memoria.js +167 -167
- package/scripts/configurar-branch-protection.js +418 -418
- package/scripts/detectar-aprendizajes-duplicados.js +151 -151
- package/scripts/field-report.js +199 -199
- package/scripts/generar-checklists-consolidados.js +273 -273
- package/scripts/generar-inventario.js +420 -420
- package/scripts/generar-matriz-lenguajes.js +271 -271
- package/scripts/lib/artefactos-python.js +43 -43
- package/scripts/lib/benchmark-metrics.js +160 -160
- package/scripts/lib/budget-enforcer.js +252 -252
- package/scripts/lib/configurar-ci.js +380 -380
- package/scripts/lib/contadores-inventario.js +217 -217
- package/scripts/lib/detectar-stack-detallado.js +307 -307
- package/scripts/lib/diary-entry.js +234 -234
- package/scripts/lib/eval-metrics-store.js +218 -218
- package/scripts/lib/eval-quality.js +171 -171
- package/scripts/lib/eval-schemas.js +144 -144
- package/scripts/lib/eval-self-correct.js +106 -106
- package/scripts/lib/eval-validator.js +185 -185
- package/scripts/lib/jaccard-similarity.js +98 -98
- package/scripts/lib/longmemeval-runner.js +125 -125
- package/scripts/lib/manifiestos.js +42 -1
- package/scripts/lib/npm-version.js +261 -261
- package/scripts/lib/paquetes-conocidos.js +50 -50
- package/scripts/lib/prompt-builder.js +264 -264
- package/scripts/lib/rrf-fusion.js +175 -175
- package/scripts/lib/scoring-instintos.js +277 -277
- package/scripts/lib/semantic-search.js +252 -252
- package/scripts/limpiar-artefactos-python.js +131 -131
- package/scripts/mcp-server/README.md +128 -128
- package/scripts/mcp-server/handlers.js +206 -206
- package/scripts/migrar-csv-a-array.js +168 -168
- package/scripts/migrar-fase-dominio.js +201 -201
- package/scripts/publicar.js +511 -511
- package/scripts/run-eval.js +141 -141
- package/scripts/validar-manifest.js +231 -195
- package/scripts/validar-userland-vacio.js +110 -110
|
@@ -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.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: feynman-auditor-swl
|
|
3
|
+
description: >
|
|
4
|
+
Auditor de bugs de lógica de negocio mediante la técnica Feynman: cuestiona
|
|
5
|
+
cada línea, cada orden de operaciones, cada presencia/ausencia de guard, y
|
|
6
|
+
cada asunción implícita. Language-agnostic (Python, TS, Go, Rust, Java, C#).
|
|
7
|
+
Cargar cuando se necesite revisión profunda de funciones individuales en
|
|
8
|
+
módulos críticos, especialmente tras un revisor-codigo-swl que pasó pero
|
|
9
|
+
donde sospechas que algo no está bien.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Cuándo cargar
|
|
13
|
+
|
|
14
|
+
- El módulo maneja dinero, inventario, permisos, o datos críticos irreversibles.
|
|
15
|
+
- `revisor-codigo-swl` pasó pero hay sospecha de bug de lógica de negocio.
|
|
16
|
+
- Nemesis está corriendo su Pasada 1.
|
|
17
|
+
- Se necesita revisión profunda de una función específica antes de merge.
|
|
18
|
+
|
|
19
|
+
# Cuándo NO cargar
|
|
20
|
+
|
|
21
|
+
- Para escaneo de vulnerabilidades conocidas (CVE, inyecciones) — usar `revisor-seguridad-swl`.
|
|
22
|
+
- Para revisión de estilo o cobertura de tests — usar `revisor-codigo-swl`.
|
|
23
|
+
- Para funciones de utilería sin estado (formateo, parsing puro).
|
|
24
|
+
- Como sustituto de tests de regresión.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
# Feynman Auditor
|
|
29
|
+
|
|
30
|
+
Encuentra bugs de lógica de negocio cuestionando cada línea como si tuvieras que explicarle el código a alguien que no asume nada.
|
|
31
|
+
|
|
32
|
+
Las preguntas detalladas están en [recursos/preguntas-language-agnostic.md](recursos/preguntas-language-agnostic.md).
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Mentalidad de base
|
|
37
|
+
|
|
38
|
+
Antes de leer el primer archivo, adoptar esta perspectiva:
|
|
39
|
+
|
|
40
|
+
> "Este código tiene un bug. Mi trabajo es encontrarlo.
|
|
41
|
+
> No estoy aquí para confirmar que el código es correcto.
|
|
42
|
+
> Cada línea que no entiendo completamente es un sospechoso."
|
|
43
|
+
|
|
44
|
+
Dos fuentes principales de bugs de lógica:
|
|
45
|
+
|
|
46
|
+
1. **Bugs de guard ausente**: la condición correcta existe en función A pero falta en función B que hace lo mismo por un path diferente.
|
|
47
|
+
2. **Bugs de orden de operaciones**: el cálculo es correcto, pero se ejecuta antes o después del momento en que los datos son válidos.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Fase 0: Inventario de scope
|
|
52
|
+
|
|
53
|
+
Antes de auditar, mapear:
|
|
54
|
+
|
|
55
|
+
- ¿Qué módulos/archivos están en scope?
|
|
56
|
+
- ¿Cuáles son las funciones de punto de entrada (endpoints, handlers, métodos públicos)?
|
|
57
|
+
- ¿Qué datos persisten (BD, caché, archivos, estado en memoria)?
|
|
58
|
+
- ¿Qué actores pueden llamar qué funciones?
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Fase 1: Auditoría de funciones individuales
|
|
63
|
+
|
|
64
|
+
Para cada función no trivial, hacer las preguntas Q1–Q7 del archivo de recursos.
|
|
65
|
+
|
|
66
|
+
Categorías de preguntas:
|
|
67
|
+
- **Q1** — Propósito: ¿qué hace exactamente esta función y solo esta función?
|
|
68
|
+
- **Q2** — Orden: ¿importa el orden de estas operaciones?
|
|
69
|
+
- **Q3** — Consistencia cross-función: ¿qué tienen en común dos funciones que parecen similares?
|
|
70
|
+
- **Q4** — Asunciones implícitas: ¿qué asume este código sin verificarlo?
|
|
71
|
+
- **Q5** — Límites: ¿qué pasa en los extremos (cero, máximo, vacío, ya-existe)?
|
|
72
|
+
- **Q6** — Returns y errores: ¿qué devuelve esta función cuando algo falla?
|
|
73
|
+
- **Q7** — Interacciones externas: ¿qué puede pasar mal cuando se llama a otro sistema?
|
|
74
|
+
|
|
75
|
+
Registrar como sospechoso cualquier función donde una pregunta no tenga respuesta clara en el código.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Fase 2: Auditoría cross-función
|
|
80
|
+
|
|
81
|
+
Buscar divergencias entre funciones que deberían comportarse igual:
|
|
82
|
+
|
|
83
|
+
- ¿Función A y B hacen lo mismo pero una tiene un guard que la otra no tiene?
|
|
84
|
+
- ¿La función de creación inicializa todos los campos que la función de lectura usa?
|
|
85
|
+
- ¿El path de happy path y el path de error manejan el estado de la misma manera?
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Fase 3: Síntesis de hallazgos
|
|
90
|
+
|
|
91
|
+
Convertir sospechosos en hallazgos concretos:
|
|
92
|
+
|
|
93
|
+
Para cada sospechoso, construir:
|
|
94
|
+
1. La pregunta Feynman que lo identificó
|
|
95
|
+
2. La asunción que el código hace implícitamente
|
|
96
|
+
3. El contraejemplo concreto que rompe esa asunción
|
|
97
|
+
4. La consecuencia observable del bug
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Fase 4: Verificación
|
|
102
|
+
|
|
103
|
+
Todo hallazgo CRÍTICO, ALTO y MEDIO debe verificarse antes del reporte final.
|
|
104
|
+
|
|
105
|
+
**Patrón de falsos positivos frecuentes:**
|
|
106
|
+
- El guard existe pero en un nivel superior (middleware, decorator, caller).
|
|
107
|
+
- El orden parece incorrecto pero hay un comentario que explica el diseño intencional.
|
|
108
|
+
- La función parece no validar, pero el tipo de dato ya garantiza el invariante.
|
|
109
|
+
|
|
110
|
+
**Formato de salida**: `.audit/findings/feynman-passN.md`
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Adaptación por lenguaje
|
|
115
|
+
|
|
116
|
+
| Concepto | Python | TypeScript | Go | Rust | Java | C# |
|
|
117
|
+
|---------|--------|------------|-----|------|------|-----|
|
|
118
|
+
| Actor | `request.user` | `req.user` / `userId` | `ctx.UserID` | `actor_id` | `principal` | `User.Identity` |
|
|
119
|
+
| Guard | decorador / `if not user:` | middleware / `if (!user)` | `if ctx.UserID == ""` | `if actor_id.is_none()` | `@PreAuthorize` | `[Authorize]` |
|
|
120
|
+
| Mutación interna | método privado `_fn` | método privado | función local | `pub(crate) fn` | método `private` | método `private` |
|
|
121
|
+
| Transacción | `with db.begin():` | `await trx.begin()` | `tx, _ := db.Begin()` | `conn.execute("BEGIN")` | `@Transactional` | `using var tx =` |
|
|
122
|
+
|
|
123
|
+
<!-- Adaptado de nemesis-auditor-main bajo MIT License (https://github.com/0xiehnnkta/nemesis-auditor) -->
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Preguntas Feynman — Language-Agnostic
|
|
2
|
+
|
|
3
|
+
28 preguntas organizadas en 7 categorías. Aplicar a cada función no trivial del módulo bajo auditoría.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Q1 — Propósito
|
|
8
|
+
|
|
9
|
+
**Q1.1** ¿Qué hace exactamente esta función y solo esta función? Si no puedo describirla en una oración sin usar "y", ¿tiene demasiadas responsabilidades?
|
|
10
|
+
|
|
11
|
+
**Q1.2** ¿Cuál es el invariante que esta función garantiza al terminar? ¿El código lo garantiza de verdad o solo en el camino feliz?
|
|
12
|
+
|
|
13
|
+
**Q1.3** ¿Hay alguna condición en que esta función debería rechazar la operación pero no lo hace? ¿Qué pasa si se la llama dos veces seguidas con los mismos argumentos?
|
|
14
|
+
|
|
15
|
+
**Q1.4** ¿Esta función asume que el estado del sistema está en alguna condición particular antes de ejecutarse? ¿Dónde se verifica esa condición?
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Q2 — Orden de operaciones
|
|
20
|
+
|
|
21
|
+
**Q2.1** ¿Importa el orden en que estas líneas se ejecutan? Si cambio el orden de dos líneas adyacentes, ¿el resultado es el mismo?
|
|
22
|
+
|
|
23
|
+
**Q2.2** ¿Esta función lee un valor y luego lo modifica? Si algo cambia el valor entre la lectura y la escritura, ¿qué pasa?
|
|
24
|
+
|
|
25
|
+
**Q2.3** ¿El cálculo de recompensa, crédito, o resultado se hace ANTES o DESPUÉS de actualizar el estado base? ¿Debería ser al revés?
|
|
26
|
+
|
|
27
|
+
**Q2.4** ¿Si esta función llama a un sistema externo (BD, API, caché), el estado local ya está actualizado en ese momento? ¿El sistema externo puede ver un estado inconsistente?
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Q3 — Consistencia cross-función
|
|
32
|
+
|
|
33
|
+
**Q3.1** ¿Qué tienen en común esta función y otra que hace algo similar? ¿Una tiene un guard o una actualización que la otra no tiene?
|
|
34
|
+
|
|
35
|
+
**Q3.2** ¿Existe una función de "camino normal" y una de "camino de emergencia/admin"? ¿Ambas actualizan exactamente el mismo conjunto de estado?
|
|
36
|
+
|
|
37
|
+
**Q3.3** ¿Esta función inicializa todos los campos que otras funciones esperan encontrar inicializados? ¿Hay algún campo que se lee antes de ser escrito?
|
|
38
|
+
|
|
39
|
+
**Q3.4** ¿El path que crea un recurso y el path que lo elimina dejan el sistema en un estado simétrico? ¿O el delete deja huérfanos?
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Q4 — Asunciones implícitas
|
|
44
|
+
|
|
45
|
+
**Q4.1** ¿Qué asume este código sobre el tipo o el rango del argumento que recibe? ¿Hay alguna validación que debería existir pero no existe?
|
|
46
|
+
|
|
47
|
+
**Q4.2** ¿El código asume que el actor que llama esta función tiene permiso para hacerlo? ¿Dónde se verifica ese permiso exactamente?
|
|
48
|
+
|
|
49
|
+
**Q4.3** ¿El código asume que algún recurso externo (BD, archivo, servicio) está disponible y en un estado consistente? ¿Qué pasa si no lo está?
|
|
50
|
+
|
|
51
|
+
**Q4.4** ¿El código asume que nunca se llamará con valor cero, lista vacía, o string vacío? ¿Se validó eso?
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Q5 — Límites y casos de borde
|
|
56
|
+
|
|
57
|
+
**Q5.1** ¿Qué pasa si el valor es exactamente cero? ¿Y si es el máximo representable? ¿Y si es negativo?
|
|
58
|
+
|
|
59
|
+
**Q5.2** ¿Qué pasa si la lista o colección está vacía? ¿Y si tiene exactamente un elemento? ¿Y si tiene millones?
|
|
60
|
+
|
|
61
|
+
**Q5.3** ¿Qué pasa si el recurso ya existe cuando se intenta crear? ¿Y si no existe cuando se intenta modificar o eliminar?
|
|
62
|
+
|
|
63
|
+
**Q5.4** ¿Qué pasa si dos actores ejecutan esta función al mismo tiempo? ¿Hay condición de carrera? ¿El resultado es determinista?
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Q6 — Returns y manejo de errores
|
|
68
|
+
|
|
69
|
+
**Q6.1** ¿Qué devuelve esta función cuando el input es inválido? ¿Lanza excepción, devuelve null, devuelve un error tipado, o silencia el problema?
|
|
70
|
+
|
|
71
|
+
**Q6.2** ¿Si una operación parcial falla a mitad de camino, el estado queda consistente? ¿Hay rollback? ¿O el sistema queda a medias?
|
|
72
|
+
|
|
73
|
+
**Q6.3** ¿El caller de esta función verifica el valor de retorno? ¿Un error no verificado puede causar daño silencioso más adelante?
|
|
74
|
+
|
|
75
|
+
**Q6.4** ¿El código captura excepciones de forma demasiado amplia (`except Exception`, `catch (e)` vacío)? ¿Qué errores legítimos podría estar silenciando?
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Q7 — Interacciones externas
|
|
80
|
+
|
|
81
|
+
**Q7.1** ¿Esta función llama a un sistema externo (BD, API, caché, cola)? ¿La llamada puede fallar? ¿Qué pasa con el estado local si falla?
|
|
82
|
+
|
|
83
|
+
**Q7.2** ¿Esta función persiste datos en más de un lugar (ej: BD + caché + índice)? ¿Qué pasa si la segunda escritura falla después de que la primera tuvo éxito?
|
|
84
|
+
|
|
85
|
+
**Q7.3** ¿El acumulador o índice que esta función usa se actualiza ANTES de modificar el valor base, o DESPUÉS? ¿El orden importa para la correctitud del cálculo?
|
|
86
|
+
|
|
87
|
+
**Q7.4** ¿Esta función envía una notificación, evento, o mensaje a otro sistema? ¿Lo hace antes o después de confirmar la operación? ¿El receptor puede actuar sobre un estado que aún no se confirmó?
|
|
88
|
+
|
|
89
|
+
**Q7.5** ¿Esta función lee un valor de caché y lo trata como fresco? ¿Hay algún path donde la caché puede estar desactualizada respecto a la fuente de verdad?
|
|
90
|
+
|
|
91
|
+
**Q7.6** ¿Esta función modifica datos de otro actor además de los del actor que la llama? ¿Tiene permiso para hacerlo en todos los casos?
|
|
92
|
+
|
|
93
|
+
**Q7.7** ¿Existe un patrón de acumulador donde el total acumulado se calcula con base en el estado anterior? Si el estado base cambia (insert/update/delete de otro registro), ¿el acumulador refleja el cambio correctamente?
|
|
94
|
+
|
|
95
|
+
**Q7.8** ¿Esta función delega a otra función que tiene sus propios efectos secundarios? ¿El caller sabe qué estado modifica el callee internamente?
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Cómo usar estas preguntas
|
|
100
|
+
|
|
101
|
+
1. Leer la función completa una vez para entender el propósito.
|
|
102
|
+
2. Para cada pregunta de las categorías Q1–Q7, marcar:
|
|
103
|
+
- ✓ Respondida claramente por el código
|
|
104
|
+
- ? Requiere rastrear el caller o el sistema externo para responder
|
|
105
|
+
- ✗ El código no la responde — sospechoso de bug
|
|
106
|
+
3. Todo `✗` o `?` sin resolver es un **sospechoso** para Fase 3 de síntesis.
|
|
107
|
+
|
|
108
|
+
<!-- Adaptado de nemesis-auditor-main bajo MIT License (https://github.com/0xiehnnkta/nemesis-auditor) -->
|