Files
egutierrez 750b7abcd5 chore: auto-commit (97 archivos)
- .claude/CLAUDE.md
- .claude/agents/fn-recopilador/SKILL.md
- .claude/rules/INDEX.md
- .claude/rules/cpp_apps.md
- bash/functions/infra/build_cpp_windows.sh
- cpp/CMakeLists.txt
- cpp/PATTERNS.md
- cpp/framework/app_base.cpp
- cpp/framework/app_base.h
- dev/issues/README.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 18:11:24 +02:00

6.3 KiB

Validacion end-to-end de apps (bucle reactivo, fase 4)

Contrato obligatorio para apps que vayan a master con gate automatico: declarar e2e_checks en su app.md. Sin contrato, fn-analizador no puede validar y la app cae al modo "manual": el humano sigue iterando.

Ver tambien: apps_tbd.md, feature_flags.md, issue 0068.

Por que

El bucle reactivo del registry tiene 5 fases. Las 3 primeras (fn-constructor, fn-executor, fn-recopilador) cubren CONSTRUIR/EJECUTAR/RECOPILAR. La fase 4 (ANALIZAR) y la 5 (MEJORAR) no funcionan sin un contrato explicito de "como sabe el agente que esta app esta sana". Ese contrato es e2e_checks.

Donde vive

En el frontmatter de cada app.md, lista e2e_checks. Convencion: id unico por check, ejecucion en orden declarado, falla = stop o continue segun severidad (TBD por implementar).

Tipos de check

Campo Que hace
id Identificador unico del check dentro de la app (build, smoke, tests_unit, ...)
cmd Comando shell. Exit 0 = pass salvo override de expect_exit.
health URL HTTP. Hace GET, espera 200, util tras un cmd que arranca un servicio en background (con &).
ref Referencia a otro agente / funcion del registry (ej. fn-recopilador:apps/X, fn-doctor:artefacts).
timeout_s Timeout en segundos. Default 60.
expect_exit Codigo de salida esperado (default 0).
expect_stdout_contains Substring que debe aparecer en stdout.
expect_stdout_json JSONPath o key=value que debe satisfacer la salida.
severity critical (default) o warning. Critical = bloquea merge; warning = registra y sigue.

Patrones por stack

Go service con frontend embebido

e2e_checks:
  - id: build_frontend
    cmd: "cd frontend && pnpm install --frozen-lockfile && pnpm build"
    timeout_s: 180
  - id: build_backend
    cmd: "CGO_ENABLED=1 go build -tags fts5 -o myapp ."
  - id: smoke
    cmd: "./myapp --port 8200 --db /tmp/myapp_e2e.db &"
    health: "http://127.0.0.1:8200/api/health"
  - id: tests
    cmd: "go test -tags fts5 -count=1 ./..."

C++ ImGui app

e2e_checks:
  - id: build
    cmd: "cmake --build build --target myapp -j"
    timeout_s: 300
  - id: self_test
    cmd: "./build/myapp --self-test"
    timeout_s: 30
  - id: pytest
    cmd: "cd tests && python3 -m pytest -x -q"

Apps C++ deben implementar --self-test que arranca, verifica subsistemas (GL loader, fonts, DBs locales), y sale con codigo 0/1.

Python pipeline / CLI

e2e_checks:
  - id: import
    cmd: "python3 -c 'import myapp'"
  - id: cli_help
    cmd: "python3 -m myapp --help"
    expect_stdout_contains: "usage:"
  - id: dry_run
    cmd: "python3 -m myapp --dry-run --input examples/sample.json"

App con operations.db

Anadir siempre:

  - id: ops_audit
    ref: "fn-recopilador:apps/myapp"

Esto invoca al recopilador en modo audit sobre apps/myapp/operations.db.

Reglas

  1. Idempotente: cada check debe poderse correr N veces sin efectos secundarios. Usar BDs en /tmp/, puertos altos, --port 0 cuando se pueda.
  2. Sin credenciales reales: ningun check toca produccion ni servicios externos sensibles. Si necesita HTTP de prueba, usar httpbin.org o un mock local.
  3. Tiempo acotado: cada check declara timeout_s. Suma total de la app < 10 min como objetivo razonable.
  4. Determinista: si el check depende de red flaky, marcalo severity: warning o usalo solo como diagnostico, no como gate.
  5. Cleanup implicito: si el check arranca un proceso en background (&), debe morir al final. fn-analizador mata el grupo de procesos al terminar la suite.

Como diseñar e2e_checks para una app existente

fn-recopilador tiene un modo design-e2e <app_id> que:

  1. Inspecciona app.md (lang, framework, entry_point, uses_functions).
  2. Revisa estructura del directorio (presencia de tests/, frontend/, Makefile, CMakeLists.txt, etc.).
  3. Audita operations.db (si existe) para sugerir ops_audit.
  4. Devuelve bloque e2e_checks_suggested: listo para copiar al app.md tras revision humana.

Comando indicativo:

Agent(subagent_type="fn-recopilador",
      prompt="design-e2e apps/<app>")

El recopilador NO escribe directo al app.md; deja la propuesta para que el humano apruebe (similar a proposals).

Adopcion gradual

  • Apps SIN e2e_checks declarado: fn doctor muestra warning, no bloquea nada.
  • Apps CON e2e_checks: fn-analizador corre la suite. Si critical falla → fn-mejorador crea proposal. Gate opcional en /git-push.
  • Pilotos iniciales: apps/kanban, projects/osint_graph/apps/graph_explorer. Resto de apps van migrando segun necesidad.

Anti-patrones

Anti-patron Por que es malo
cmd: "make test" con make-target opaco Ilegible. El check debe ser ejecutable directo y auditable.
Check que tarda > 5 min sin razon (smoke pesado) Bloquea iteracion. Mover a CI nocturno con tag slow.
Smoke que toca produccion Riesgo. Smoke usa BD efimera, puertos altos, mocks.
expect_stdout_contains: "" Vacio = siempre pass. No es un check.
Anidar checks (uno depende de side-effects de otro sin declararlo) Frigil. Cada check arranca lo que necesita.
Usar e2e_checks como sustituto de tests unitarios Son cosas distintas. Unit tests viven en *_test.go/pytest. e2e valida que el sistema arranque y haga su trabajo.

Tabla e2e_runs en operations.db

Cada corrida de fn-analizador se persiste:

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
);

Migracion: fn_operations/migrations/006_e2e_runs.sql (issue 0068, paso 3).

Output canonico de fn-analizador

Tabla caveman, una linea por check:

build           ✓ 42s
smoke           ✓ 0.8s
ops_audit       ✓
tests           ✗ 12s   exit 1, 3/45 failures
assertion:R1    ✗       warning  duration drift +47% vs p50
golden:home     ✓

Rojo cuando severity: critical y status fail. Esto es lo que el agente principal lee y reenvia al humano.