750b7abcd5
- .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>
136 lines
4.5 KiB
Markdown
136 lines
4.5 KiB
Markdown
# /validate-app — Validar end-to-end una app del registry
|
|
|
|
Orquesta la cadena `fn-executor → fn-recopilador → fn-analizador → fn-mejorador` (fases 2-5 del bucle reactivo) sobre una app concreta. Devuelve veredicto pass/fail + IDs de proposals creadas si hay fallos.
|
|
|
|
## Argumento
|
|
|
|
`$ARGUMENTS` — `<app_id>` o `<dir_path>`. Ejemplos:
|
|
- `kanban_go_tools`
|
|
- `apps/kanban`
|
|
- `graph_explorer_cpp_viz`
|
|
- `projects/osint_graph/apps/graph_explorer`
|
|
|
|
Si vacio: detectar app desde `pwd` (si estas dentro de `apps/<X>/` o `projects/*/apps/<X>/`); si no, listar apps con `e2e_checks` declarado y pedir.
|
|
|
|
## Pasos
|
|
|
|
### 1. Resolver app objetivo
|
|
|
|
```bash
|
|
ROOT=/home/lucas/fn_registry
|
|
ARG="$ARGUMENTS"
|
|
|
|
if [ -z "$ARG" ]; then
|
|
CWD="$(pwd)"
|
|
case "$CWD" in
|
|
"$ROOT"/apps/*|"$ROOT"/projects/*/apps/*)
|
|
ARG="$(realpath --relative-to="$ROOT" "$CWD")"
|
|
;;
|
|
*)
|
|
sqlite3 "$ROOT/registry.db" "SELECT id, dir_path FROM apps ORDER BY id;"
|
|
echo "Especifica app_id o dir_path"
|
|
exit 1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
# Resolver a (id, dir_path)
|
|
if echo "$ARG" | grep -q "^apps/\|^projects/"; then
|
|
APP_DIR="$ARG"
|
|
APP_ID=$(sqlite3 "$ROOT/registry.db" "SELECT id FROM apps WHERE dir_path = '$ARG';")
|
|
else
|
|
APP_ID="$ARG"
|
|
APP_DIR=$(sqlite3 "$ROOT/registry.db" "SELECT dir_path FROM apps WHERE id = '$ARG';")
|
|
fi
|
|
|
|
[ -z "$APP_ID" ] || [ -z "$APP_DIR" ] && { echo "App no encontrada: $ARG"; exit 1; }
|
|
```
|
|
|
|
### 2. Verificar contrato `e2e_checks`
|
|
|
|
```bash
|
|
HAS_CHECKS=$(awk '/^e2e_checks:/,/^[a-z_]+:|^---$/' "$ROOT/$APP_DIR/app.md" | grep -c "^ - id:")
|
|
|
|
if [ "$HAS_CHECKS" -eq 0 ]; then
|
|
echo "App $APP_ID no tiene e2e_checks declarados."
|
|
echo "Invocar fn-recopilador design-e2e para generar contrato:"
|
|
echo ""
|
|
echo " Agent(subagent_type=fn-recopilador, prompt=\"design-e2e $APP_DIR\")"
|
|
exit 0
|
|
fi
|
|
```
|
|
|
|
### 3. Fase 3 — RECOPILAR (auditar operations.db)
|
|
|
|
Invocar `fn-recopilador` para confirmar que los datos operativos estan integros antes de validar. Si recopilador reporta FAIL critical, NO continuar.
|
|
|
|
```
|
|
Agent(subagent_type=fn-recopilador,
|
|
prompt="Auditar app $APP_DIR. Reportar OK/WARN/FAIL en formato corto.
|
|
Si hay FAIL critical, advertirlo claramente. Solo lectura.")
|
|
```
|
|
|
|
Si reporta FAIL critical → abortar con mensaje y no llegar a fn-analizador.
|
|
|
|
### 4. Fase 4 — ANALIZAR (correr e2e_checks)
|
|
|
|
```
|
|
Agent(subagent_type=fn-analizador,
|
|
prompt="Validar end-to-end la app $APP_ID (dir_path: $APP_DIR).
|
|
Leer e2e_checks del app.md, ejecutar via e2e_run_checks_go_infra,
|
|
evaluar assertions, calcular drift, persistir en e2e_runs.
|
|
triggered_by: manual.
|
|
git_sha: $(git rev-parse --short HEAD 2>/dev/null || echo '')
|
|
|
|
Devolver veredicto caveman + run_id.")
|
|
```
|
|
|
|
Capturar `RUN_ID` del output. Capturar `STATUS` (`pass`|`partial`|`fail`).
|
|
|
|
### 5. Fase 5 — MEJORAR (proposals si hay fallos)
|
|
|
|
Solo si `STATUS != pass`:
|
|
|
|
```
|
|
Agent(subagent_type=fn-mejorador,
|
|
prompt="App $APP_ID tuvo fallos en run_id $RUN_ID.
|
|
Leer e2e_runs y summary_json de $APP_DIR/operations.db.
|
|
Por cada fail critical: crear proposal kind=new_function|improve_function
|
|
en registry.db con created_by=reactive_loop, evidence con run_id+check_id.
|
|
Sugerir fix concreto en description.
|
|
Devolver lista de proposal_ids creados.")
|
|
```
|
|
|
|
Capturar `PROPOSAL_IDS`.
|
|
|
|
### 6. Reporte final al usuario
|
|
|
|
Tabla resumen:
|
|
|
|
```
|
|
=== /validate-app: $APP_ID ===
|
|
|
|
Fase 3 RECOPILAR: ✓ datos operativos integros
|
|
Fase 4 ANALIZAR: <STATUS> (run_id: <RUN_ID>)
|
|
<P>/<T> checks pass, <W> warn, <F> fail
|
|
Fase 5 MEJORAR: <N> proposals creadas: <PROPOSAL_IDS>
|
|
|
|
Detalle por check:
|
|
build_frontend ✓ 42s
|
|
build_backend ✓ 18s
|
|
smoke_api ✓ 1.2s
|
|
tests_go ✗ 12s — 3/45 fails
|
|
|
|
Siguientes pasos:
|
|
- Revisar proposals: fn proposal list -s pending
|
|
- Ver run completo: sqlite3 $APP_DIR/operations.db "SELECT * FROM e2e_runs WHERE id='<RUN_ID>'"
|
|
```
|
|
|
|
## Notas
|
|
|
|
- **fn-mejorador no existe todavia** (paso 6 del issue 0068). Mientras tanto, si STATUS != pass, solo imprime el detalle del fallo y sugerir crear proposal manual.
|
|
- Si un agente subagente devuelve respuesta ambigua (no extrae RUN_ID claramente), pedir clarificacion al usuario antes de continuar.
|
|
- Para apps sin `operations.db` (ej. kanban usa `kanban.db`), `e2e_runs` se persiste en `/tmp/<app>_e2e_runs.db` con la misma migracion 005.
|
|
- Caveman OK en stdout salvo en mensajes de error donde claridad supera brevedad.
|
|
- Tras correr la cadena, NO commitear nada automaticamente. La decision de mergear es del humano.
|