Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 |
|
multi-app | alta |
|
2026-05-09 | 2026-05-17 |
Cierre 2026-05-14
Toda infra implementada y operativa:
- Migration
fn_operations/migrations/005_e2e_runs.sqlaplicada. - Funcion
e2e_run_checks_go_infra(Cmd/Health/Ref con expect_exit/stdout_contains, background via&). TiposE2ECheck_go_infra+CheckResult_go_infra. - Subagentes
fn-analizador(Fase 4) yfn-mejorador(Fase 5) en.claude/agents/. fn-recopiladorextendido con mododesign-e2e <app_id>.- Skill
/validate-app <app_id>orquesta cadena completa. - Regla
.claude/rules/e2e_validation.mddocumenta contrato + patrones por stack. - Pilotos:
apps/kanban/app.mdyprojects/osint_graph/apps/graph_explorer/app.mddeclarane2e_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— esperacmden 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:
- Lee
e2e_checksdelapp.md. - Ejecuta cada check en orden, captura stdout/stderr/exit/duration.
- Eval assertions activas via
fn ops assertion eval --react. - Compara
executions.metricsactual vs ventana historica (drift > umbral = warning). - Diff golden outputs si app declara
tests/golden/. - Persiste resultado en nueva tabla
e2e_runsdeoperations.db. - 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:
- Filtra fallos:
critical→kind=bug,warning→kind=optimization. - Por cada fallo, busca contexto en registry: funciones tocadas, ultimas N proposals.
- Crea proposal con
created_by=reactive_loop,evidence=[assertion_id, execution_id, e2e_run_id]. - Sugiere fix concreto (parametro, funcion a partir, refactor) — texto, NO codigo.
- 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-executor → fn-recopilador → fn-analizador → fn-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-testo lanzar y matar tras N segundos). - Python pipeline → propone run con args dummy y verificar exit 0.
- Audita
operations.dby derivaops_auditautomatico. - Escribe propuesta en
app.mdcomo bloquee2e_checks_suggested:para que humano apruebe → renombre ae2e_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.mdcon seccione2e_checksdocumentada. apps/kanban/app.mddeclarae2e_checks(build_frontend + build_backend + smoke + tests + ops_audit).projects/osint_graph/apps/graph_explorer/app.mddeclarae2e_checks(build + self_test + pytest + enricher smoke).fn-recopiladorpuede sugerire2e_checkspara una app dada (mododesign-e2e).fn-analizadorcorre los checks y devuelve veredicto caveman.fn-mejoradorcrea 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.dbpropia, nooperations.db). El checkops_auditdebe aceptar BD alternativa o saltarse. - Smoke tests con puertos en uso. Los pilotos deben usar puertos efimeros (
--port 0o range alto) y BDs en/tmp/. - Adopcion gradual. Apps sin
e2e_checksno se validan (y no bloquean merge). Visible enfn 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_driftson aproximacion, no benchmark).