Files
fn_registry/dev/issues/0068-e2e-validation-loop-fn4-fn5.md

8.2 KiB

id, title, status, type, domain, scope, priority, depends, blocks, related, created, updated, tags
id title status type domain scope priority depends blocks related created updated tags
0068 Cerrar bucle reactivo — fn-analizador (fase 4) y fn-mejorador (fase 5) con contrato e2e_checks completado feature
meta
multi-app alta
22
23
0028
2026-05-09 2026-05-17

Cierre 2026-05-14

Toda infra implementada y operativa:

  • Migration fn_operations/migrations/005_e2e_runs.sql aplicada.
  • Funcion e2e_run_checks_go_infra (Cmd/Health/Ref con expect_exit/stdout_contains, background via &). Tipos E2ECheck_go_infra + CheckResult_go_infra.
  • Subagentes fn-analizador (Fase 4) y fn-mejorador (Fase 5) en .claude/agents/.
  • fn-recopilador extendido con modo design-e2e <app_id>.
  • Skill /validate-app <app_id> orquesta cadena completa.
  • Regla .claude/rules/e2e_validation.md documenta contrato + patrones por stack.
  • Pilotos: apps/kanban/app.md y projects/osint_graph/apps/graph_explorer/app.md declaran e2e_checks.

Contexto

El bucle reactivo del registry (CONSTRUIR → EJECUTAR → RECOPILAR → ANALIZAR → MEJORAR) tiene agentes para fases 1-3:

  • Fase 1 — CONSTRUIR: fn-constructor (existe)
  • Fase 2 — EJECUTAR: fn-executor (existe)
  • Fase 3 — RECOPILAR: fn-recopilador (existe)
  • Fase 4 — ANALIZAR: falta agente
  • Fase 5 — MEJORAR: falta agente

Sin fases 4 y 5 el bucle no cierra. Cada app sigue requiriendo iteracion manual: el humano lanza, mira, decide si funciona, y propone fixes. Objetivo: que apps lleguen a master correctas sin esa iteracion manual.

Objetivo

Disponer de un gate automatico pre-merge que valide end-to-end cualquier app del registry, y un mejorador que proponga cambios cuando la validacion falla. Capacidad reutilizable, no especifica de un proyecto.

Diseno

Contrato e2e_checks en app.md

Cada app declara su validacion end-to-end en el frontmatter:

e2e_checks:
  - id: build
    cmd: "cd frontend && pnpm build && cd .. && CGO_ENABLED=1 go build -tags fts5 -o kanban ."
    timeout_s: 120
  - id: smoke
    cmd: "./kanban --port 8095 --db /tmp/kanban_e2e.db &"
    health: "http://127.0.0.1:8095/api/board"
    timeout_s: 10
  - id: ops_audit
    ref: "fn-recopilador:apps/kanban"
  - id: migrations
    cmd: "sqlite3 /tmp/kanban_e2e.db 'SELECT version FROM schema_migrations;'"
    expect_exit: 0

Tipos de check:

  • cmd — comando shell, exit 0 = OK.
  • health — espera cmd en background, hace GET y verifica 200.
  • ref — apunta a otro agente/funcion del registry (ej. fn-recopilador, fn-doctor).
  • expect_exit, expect_stdout_contains, expect_stdout_json — predicados sobre la salida.

fn-analizador (fase 4)

Subagente nuevo. Input: app_id. Pasos:

  1. Lee e2e_checks del app.md.
  2. Ejecuta cada check en orden, captura stdout/stderr/exit/duration.
  3. Eval assertions activas via fn ops assertion eval --react.
  4. Compara executions.metrics actual vs ventana historica (drift > umbral = warning).
  5. Diff golden outputs si app declara tests/golden/.
  6. Persiste resultado en nueva tabla e2e_runs de operations.db.
  7. Devuelve veredicto caveman:
    build           ✓ 42s
    smoke           ✓ 0.8s
    ops_audit       ✓
    assertion:R1    ✗  warning  duration drift +47% vs p50
    

Tools: Read, Bash, Grep, Glob. Escribe SOLO assertion_results, entity.status, e2e_runs. NO toca registry.db.

fn-mejorador (fase 5)

Subagente nuevo. Input: salida de fn-analizador + app_id. Pasos:

  1. Filtra fallos: criticalkind=bug, warningkind=optimization.
  2. Por cada fallo, busca contexto en registry: funciones tocadas, ultimas N proposals.
  3. Crea proposal con created_by=reactive_loop, evidence=[assertion_id, execution_id, e2e_run_id].
  4. Sugiere fix concreto (parametro, funcion a partir, refactor) — texto, NO codigo.
  5. Si fallo recurrente (>3 veces misma assertion) → priority=high.

Tools: Read, Bash, Grep. Escribe SOLO proposals en registry.db. Nunca modifica funciones.

Skill /validate-app <app_id>

Orquesta cadena: fn-executorfn-recopiladorfn-analizadorfn-mejorador. Devuelve tabla pass/fail + IDs de proposals creadas.

Migracion 006_e2e_runs.sql

CREATE TABLE IF NOT EXISTS e2e_runs (
    id            TEXT PRIMARY KEY,
    app_id        TEXT NOT NULL,
    started_at    INTEGER NOT NULL,
    finished_at   INTEGER,
    status        TEXT NOT NULL,        -- pass|fail|partial
    checks_total  INTEGER NOT NULL,
    checks_pass   INTEGER NOT NULL,
    checks_fail   INTEGER NOT NULL,
    summary_json  TEXT NOT NULL         -- detalle por check
);
CREATE INDEX IF NOT EXISTS e2e_runs_app_idx ON e2e_runs(app_id, started_at DESC);

Funciones nuevas del registry

Delegables a fn-constructor:

ID Domain Que hace
e2e_run_checks_go_infra infra Ejecuta lista de checks, devuelve []CheckResult
golden_diff_go_core core Compara archivo vs golden con umbral
metrics_drift_go_datascience datascience p50/p95 historico vs actual
proposal_from_failure_go_infra infra Formatea evidencia → proposal
health_probe_go_infra infra GET con timeout, retry, codigo esperado

Tipos:

ID Que
E2ECheck_go_infra struct check (id, cmd, ref, health, expect_*)
CheckResult_go_infra struct resultado (id, status, duration_ms, stdout, stderr, exit)

fn-recopilador como diseñador de checks

fn-recopilador se extiende para proponer e2e_checks por app (modo design):

  • Inspecciona app.md (lang, framework, entry_point, uses_functions).
  • Detecta patrones conocidos:
    • Go service con frontend Vite → propone build (pnpm + go), smoke (puerto + endpoint health).
    • C++ ImGui app → propone build (cmake), smoke (--self-test o lanzar y matar tras N segundos).
    • Python pipeline → propone run con args dummy y verificar exit 0.
  • Audita operations.db y deriva ops_audit automatico.
  • Escribe propuesta en app.md como bloque e2e_checks_suggested: para que humano apruebe → renombre a e2e_checks:.

Comando: fn-recopilador design-e2e <app_id>.

Asi fn-analizador recibe contratos completos de fabrica y solo necesita ejecutar.

Plan de ejecucion

Paso Tarea Estado
1 Contrato e2e_checks en docs/templates/app.md + 2 apps piloto (kanban, graph_explorer) en curso
2 Funciones registry: e2e_run_checks, golden_diff, metrics_drift, proposal_from_failure, health_probe pendiente
3 Migracion 006_e2e_runs.sql en fn_operations/migrations/ pendiente
4 Subagente fn-analizador + skill /validate-app pendiente
5 Extender fn-recopilador con modo design-e2e pendiente
6 Subagente fn-mejorador pendiente
7 Gate opcional en /git-push para apps con e2e_checks declarado pendiente

Criterios de aceptacion

  • Template docs/templates/app.md con seccion e2e_checks documentada.
  • apps/kanban/app.md declara e2e_checks (build_frontend + build_backend + smoke + tests + ops_audit).
  • projects/osint_graph/apps/graph_explorer/app.md declara e2e_checks (build + self_test + pytest + enricher smoke).
  • fn-recopilador puede sugerir e2e_checks para una app dada (modo design-e2e).
  • fn-analizador corre los checks y devuelve veredicto caveman.
  • fn-mejorador crea proposals con evidencia cuando hay fallos.
  • Skill /validate-app <app_id> orquesta la cadena completa.
  • Documentacion en .claude/rules/e2e_validation.md.

Riesgos

  • Golden tests para C++/UI son caros. Empezar build+smoke+assertions; goldens solo donde aporten (graph_explorer ya tiene capture system).
  • Apps sin operations.db (kanban usa kanban.db propia, no operations.db). El check ops_audit debe aceptar BD alternativa o saltarse.
  • Smoke tests con puertos en uso. Los pilotos deben usar puertos efimeros (--port 0 o range alto) y BDs en /tmp/.
  • Adopcion gradual. Apps sin e2e_checks no se validan (y no bloquean merge). Visible en fn doctor.

Out of scope

  • Reemplazar fn doctor (que sigue siendo diagnostico read-only del estado).
  • Tests unitarios de funciones (siguen en *_test.go, pytest, etc.).
  • Performance benchmarks formales (los metrics_drift son aproximacion, no benchmark).