feat(0121a): wave 2 e2e_checks proposals (8 apps) + README updated
8 fn-recopilador design-e2e paralelos: - services_api (Go service, schema custom operations.db) - registry_mcp (Go stdio MCP, JSON-RPC handshake test) - sqlite_api (Go service read-only HTTP, query_endpoint) - registry_dashboard (C++ ImGui, NO Go+React como yo supuse) - primitives_gallery (C++ build gate de toda API C++ del registry, 44 .cpp) - pipeline_launcher (Go TUI bubbletea) - docker_tui (Go TUI + go-duckdb) - fn_match (subcmd ./fn, hook helper, fuzzy match) 13/26 apps cubiertas. README documenta: - 6 bugs/drift descubiertos lateral (dag_engine x3, deploy_server, pipeline_launcher, docker_tui). - 3 correcciones de mi prompt (yo asumi stacks incorrectos). - Hallazgos arquitectonicos (primitives_gallery = build gate C++). Pendiente wave 3 (13 apps) + 0121b + 0121c. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
# Propuestas e2e_checks — issue 0121a
|
||||
|
||||
Generadas por `fn-recopilador design-e2e` en wave 1, 2026-05-19.
|
||||
Generadas por `fn-recopilador design-e2e` paralelo, 2026-05-19.
|
||||
|
||||
## Estado
|
||||
## Estado (13/26 apps cubiertas)
|
||||
|
||||
### Wave 1 (5 apps)
|
||||
|
||||
| App | YAML | Lang | Stack | Checks | Severidad mix | Estado |
|
||||
|---|---|---|---|---|---|---|
|
||||
@@ -12,27 +14,64 @@ Generadas por `fn-recopilador design-e2e` en wave 1, 2026-05-19.
|
||||
| auto_metabase | [auto_metabase.yaml](auto_metabase.yaml) | py | httpx + CLI argparse | 4 | critical | propuesta |
|
||||
| dag_engine | [dag_engine.yaml](dag_engine.yaml) | go | net/http + vite/react + CGO+FTS5 | 6 | 5 critical + 1 warning | propuesta |
|
||||
|
||||
## Advertencias detectadas (laterales al objetivo)
|
||||
### Wave 2 (8 apps)
|
||||
|
||||
| App | YAML | Lang | Stack | Checks | Severidad mix | Estado |
|
||||
|---|---|---|---|---|---|---|
|
||||
| services_api | [services_api.yaml](services_api.yaml) | go | net/http + SSH cross-PC + sqlite custom schema | 6 | 3 critical + 3 warning | propuesta |
|
||||
| registry_mcp | [registry_mcp.yaml](registry_mcp.yaml) | go | mcp-go stdio + CGO+FTS5 | 5 | 4 critical + 1 warning | propuesta |
|
||||
| sqlite_api | [sqlite_api.yaml](sqlite_api.yaml) | go | net/http read-only + CGO+FTS5 | 7 | 4 critical + 2 warning + 1 (auth WIP) | propuesta |
|
||||
| registry_dashboard | [registry_dashboard.yaml](registry_dashboard.yaml) | cpp | imgui + cpp-httplib + WS RFC6455 | 7 | 3 critical + 4 warning | propuesta |
|
||||
| primitives_gallery | [primitives_gallery.yaml](primitives_gallery.yaml) | cpp | imgui + 44 .cpp registry (build gate de toda API C++) | 6 | 2 critical + 4 warning | propuesta |
|
||||
| pipeline_launcher | [pipeline_launcher.yaml](pipeline_launcher.yaml) | go | bubbletea TUI + CGO+FTS5 | 5 | 3 critical + 2 warning | propuesta |
|
||||
| docker_tui | [docker_tui.yaml](docker_tui.yaml) | go | bubbletea TUI + go-duckdb + docker CLI | 6 | 3 critical + 3 warning | propuesta |
|
||||
| fn_match | [fn_match.yaml](fn_match.yaml) | go | subcmd de ./fn + FTS5 fuzzy match (hook helper) | 5 | 2 critical + 3 warning | propuesta |
|
||||
|
||||
## Wave 3 (13 apps restantes, pendiente)
|
||||
|
||||
apps/:
|
||||
- altsnap_jitter_test, app_gestion, app_hub_launcher, footprint_geo_stack, metabase_registry, script_navegador, services_monitor, set_exe_icon, tables_qa, text_editor_smoke
|
||||
|
||||
projects/*/apps/:
|
||||
- element_agents/apps/element_matrix_chat, element_agents/apps/agents_and_robots, online_data_recopilation/apps/odr_console
|
||||
|
||||
## Advertencias detectadas (laterales)
|
||||
|
||||
### Bugs/drift descubiertos durante design-e2e
|
||||
|
||||
- **dag_engine** — `apps/dag_engine/registry.db` (262 KB) viola `db_locations.md` (registry.db SOLO en raiz). Reaparicio tras borrado de 2026-05-16. Issue separado pendiente.
|
||||
- **dag_engine** — `pnpm build` roto por Mantine API drift (`StepTimeline.tsx:49` + `main.tsx:1`). Check `build_frontend` queda en `severity: warning` hasta arreglar.
|
||||
- **dag_engine** — falta flag `--migrate-only` en binario. Check `migrations_apply` usa `list` como proxy.
|
||||
- **deploy_server** — flag `--db` no expuesto en `cmdServe`. Check smoke usa BD por defecto del cwd hasta arreglar.
|
||||
- **pipeline_launcher** — migracion `003_logs` falta en `operations.db`. Detectada por recopilador via PRAGMA table_info.
|
||||
- **docker_tui** — `go.work` con path absoluto `/home/lucas/.local_agentes/backend` → build no portable. Check `build` queda en `severity: warning`.
|
||||
|
||||
### Correcciones de stack en mis prompts (telemetria para mi)
|
||||
|
||||
- **sqlite_api**: yo asumi Python, era Go. Recopilador corrigio.
|
||||
- **registry_dashboard**: yo asumi Go+React+Vite, era C++ ImGui puro (cliente HTTP+WS). Recopilador corrigio + adapto checks.
|
||||
- **fn_match**: yo asumi binario propio, es subcomando de `./fn`. Recopilador corrigio.
|
||||
|
||||
## Hallazgos arquitectonicos
|
||||
|
||||
- **primitives_gallery** es build gate de toda la API C++ del registry: 44 .cpp linkados (gfx + viz + core + 3d + sql + ...). Si una funcion C++ rompe su cabecera, falla aqui primero. Considerar moverlo a un job critico de CI.
|
||||
- **services_api** usa schema custom en operations.db (no fn_operations standard: `service_state` + `service_transition`). `ops_audit` debe manejar schemas custom.
|
||||
- **registry_mcp** test `mcp_handshake_stdio` arranca pipes in-process — replica el JSON-RPC que Claude Code usa al arrancar. Es el check de mayor valor por linea del wave 2.
|
||||
|
||||
## Siguiente paso
|
||||
|
||||
Wave 2 (16 apps restantes): app_gestion, app_hub_launcher, altsnap_jitter_test, docker_tui, fn_match, footprint_geo_stack, metabase_registry, pipeline_launcher, primitives_gallery, registry_mcp, script_navegador, services_api, services_monitor, set_exe_icon, tables_qa, text_editor_smoke + 5 en projects/*/apps (element_matrix_chat, agents_and_robots, sqlite_api, registry_dashboard, odr_console).
|
||||
Wave 3 (13 apps restantes) → completar coverage propuestas.
|
||||
|
||||
Tras todas las propuestas → ejecutar 0121c: `/autonomous-task` por app aplicando el bloque al `app.md` correspondiente del sub-repo.
|
||||
Despues:
|
||||
- 0121b (`fn doctor e2e-coverage` via /autonomous-task tipo feature_app_simple) — apto para `/autopilot`.
|
||||
- 0121c (aplicar propuestas: N /autonomous-task add_e2e_check) — paraleliza sub-repos.
|
||||
|
||||
## Como aplicar manualmente (sin orquestador)
|
||||
|
||||
```bash
|
||||
# Editar el app.md del target
|
||||
cd apps/<app>
|
||||
# Pegar el bloque e2e_checks: del yaml al frontmatter
|
||||
# Pegar el bloque e2e_checks: del yaml al frontmatter de app.md
|
||||
$EDITOR app.md
|
||||
# Commit en sub-repo
|
||||
git add app.md && git commit -m "feat: add e2e_checks (issue 0121)"
|
||||
git push
|
||||
```
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
# e2e_checks proposal — docker_tui
|
||||
# app_id: docker_tui
|
||||
# lang: go
|
||||
# stack: Bubble Tea (charmbracelet/bubbletea) + lipgloss + devfactory TUI framework
|
||||
# dir_path: apps/docker_tui
|
||||
# date: 2026-05-19
|
||||
# issue: 0121a wave 2
|
||||
#
|
||||
# Generado por fn-recopilador modo design-e2e.
|
||||
# NO copiar directamente al app.md — requiere revision humana (mismo flujo que proposals).
|
||||
#
|
||||
# ---------------------------------------------------------------------------
|
||||
# DIAGNOSTICO
|
||||
# ---------------------------------------------------------------------------
|
||||
# lang=go, framework=bubbletea, entry_point=main.go
|
||||
# Sin tests: no hay *_test.go en ningún paquete.
|
||||
# Sin --help ni --version: el binario es TUI pura, requiere TTY.
|
||||
# - timeout 2s ./docker-tui --help → exit 1 + "could not open a new TTY"
|
||||
# - Eso es el comportamiento esperado de CI: sin TTY el proceso sale con error.
|
||||
# CGO requerido: la dependencia devfactory (go.work local path
|
||||
# /home/lucas/.local_agentes/backend) declara go-duckdb v1.6.5 que usa CGO.
|
||||
# go vet pasa con CGO_ENABLED=1. Build sin CGO no es posible por la dep transitiva.
|
||||
# Docker CLI: toda la logica llama al binario `docker` via shell.RunWithTimeout.
|
||||
# No usa SDK de Docker ni abre /var/run/docker.sock directamente.
|
||||
# Al fallar la invocación (socket ausente, daemon parado) devuelve error que
|
||||
# la vista TUI muestra en pantalla — no hay panic ni exit(1).
|
||||
# operations.db presente: 4 migraciones aplicadas (001-004). Sin entidades ni
|
||||
# ejecuciones aun — la app es nueva (v0.1.0). Incluir ops_audit igualmente.
|
||||
# go.work: referencia path absoluto /home/lucas/.local_agentes/backend.
|
||||
# El build en CI necesita que ese path exista, o reemplazar con GOFLAGS/replace
|
||||
# en el Makefile. El check build puede fallar en CI remoto si el path no monta.
|
||||
# Se marca severity: warning para no bloquear gate mientras no hay CI remoto.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
e2e_checks_suggested:
|
||||
|
||||
- id: build
|
||||
# CGO_ENABLED=1 obligatorio — devfactory backend tiene go-duckdb (CGO).
|
||||
# go.work en la raiz del app resuelve el replace local automaticamente.
|
||||
# El binario resultante es ~42 MB con trimpath+ldflags.
|
||||
cmd: "cd apps/docker_tui && CGO_ENABLED=1 go build -trimpath -ldflags='-s -w' -o /tmp/docker_tui_e2e ."
|
||||
timeout_s: 120
|
||||
severity: warning
|
||||
# warning porque el build depende de /home/lucas/.local_agentes/backend
|
||||
# (path absoluto en go.work). En CI remoto puede no existir; pendiente
|
||||
# resolver via GOFLAGS o módulo publicado en Gitea.
|
||||
|
||||
- id: vet
|
||||
# go vet detecta errores estaticos sin necesitar TTY ni docker daemon.
|
||||
# Pasa con CGO_ENABLED=1 segun verificacion directa.
|
||||
cmd: "cd apps/docker_tui && CGO_ENABLED=1 go vet ./..."
|
||||
timeout_s: 60
|
||||
|
||||
- id: no_tty_exits_cleanly
|
||||
# TUI pura sin --help. En ausencia de TTY (CI headless), el binario debe
|
||||
# salir con exit != 0 y escribir un mensaje de error legible en stderr.
|
||||
# Verificamos que:
|
||||
# 1. Sale antes del timeout (no se queda colgado esperando input).
|
||||
# 2. El stderr contiene "TTY" (mensaje de error conocido del framework).
|
||||
# expect_exit: 1 porque tui.RunFullscreen devuelve error cuando no hay TTY.
|
||||
cmd: "timeout 5s /tmp/docker_tui_e2e 2>&1 || true"
|
||||
expect_stdout_contains: "TTY"
|
||||
expect_exit: 0
|
||||
# expect_exit 0 porque usamos '|| true' para capturar stdout/stderr y
|
||||
# verificar el mensaje. La condicion real es stdout_contains "TTY".
|
||||
timeout_s: 10
|
||||
|
||||
- id: docker_cli_present
|
||||
# Verifica que el binario docker esta en PATH antes de intentar operaciones.
|
||||
# Sin docker instalado, todas las vistas muestran error — la TUI sigue
|
||||
# funcionando (no crashea), pero el check avisa al operador en CI.
|
||||
cmd: "docker --version"
|
||||
expect_stdout_contains: "Docker version"
|
||||
timeout_s: 5
|
||||
|
||||
- id: docker_socket_optional
|
||||
# Simula socket de Docker ausente. Verifica que el CLI reporta el error
|
||||
# correctamente y sale con codigo != 0 (comportamiento esperado).
|
||||
# Este check es diagnostic: confirma que cuando el daemon no esta disponible
|
||||
# el codigo de error es coherente. La TUI lo maneja gracefully (muestra
|
||||
# el error en la lista en lugar de crashear).
|
||||
cmd: "DOCKER_HOST=unix:///tmp/nonexistent_docker_e2e.sock docker ps 2>&1"
|
||||
expect_stdout_contains: "failed to connect"
|
||||
expect_exit: 0
|
||||
# expect_exit 0 porque la shell captura el stderr via 2>&1 y el check
|
||||
# evalua stdout_contains. La condicion real es que docker reporta el error.
|
||||
severity: warning
|
||||
timeout_s: 5
|
||||
|
||||
- id: ops_audit
|
||||
# operations.db presente con 4 migraciones aplicadas.
|
||||
# Sin entidades aun (app nueva v0.1.0) — el audit valida que el schema
|
||||
# esta completo y no hay referencias rotas.
|
||||
ref: "fn-recopilador:apps/docker_tui"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# JUSTIFICACION
|
||||
# ---------------------------------------------------------------------------
|
||||
# | check | razon |
|
||||
# |------------------------|--------------------------------------------------|
|
||||
# | build | CGO requerido por devfactory/go-duckdb. Sin |
|
||||
# | | build verificado no hay binario que testear. |
|
||||
# | | severity:warning por dependencia path absoluto. |
|
||||
# | vet | Analisis estatico sin TTY ni daemon. Detecta |
|
||||
# | | bugs de tipos y contextos antes de runtime. |
|
||||
# | no_tty_exits_cleanly | CI es headless. Verificar que el binario sale |
|
||||
# | | con error legible (no se cuelga) es el unico |
|
||||
# | | gate posible para una TUI sin --self-test. |
|
||||
# | docker_cli_present | Toda la logica wrappea el CLI `docker`. Si no |
|
||||
# | | esta en PATH, las vistas muestran error pero |
|
||||
# | | la causa raiz debe detectarse en CI. |
|
||||
# | docker_socket_optional | Documenta el comportamiento cuando el daemon |
|
||||
# | | no esta. La TUI debe degradar gracefully, no |
|
||||
# | | crashear. severity:warning — ambiente dependiente.|
|
||||
# | ops_audit | operations.db existe, 4 migraciones aplicadas. |
|
||||
# | | Audita schema completo y coherencia de datos |
|
||||
# | | (aunque este vacio en v0.1.0). |
|
||||
# ---------------------------------------------------------------------------
|
||||
#
|
||||
# CHECKS OMITIDOS y razon:
|
||||
# - tests: no hay *_test.go. Proponer agregar tests unitarios para
|
||||
# views/docker.go (parseJSONLines, helpers) — candidato a issue futuro.
|
||||
# - smoke con health URL: TUI sin servidor HTTP. No aplica.
|
||||
# - --self-test flag: no implementado. Podria anadirse al main.go para
|
||||
# verificar build de modelos sin lanzar el loop de bubbletea.
|
||||
# - build_frontend: no hay frontend web. No aplica.
|
||||
#
|
||||
# NOTA CRITICA — go.work con path absoluto:
|
||||
# El replace en go.work apunta a /home/lucas/.local_agentes/backend.
|
||||
# Para que el check `build` funcione en cualquier maquina/CI, pendiente
|
||||
# publicar devfactory como modulo en Gitea o agregar GONOSUMCHECK + replace
|
||||
# via GOFLAGS. Hasta entonces build=warning, no critical.
|
||||
@@ -0,0 +1,127 @@
|
||||
# e2e_checks proposal — fn_match
|
||||
#
|
||||
# app_id: fn_match
|
||||
# lang: go
|
||||
# stack: hook helper — subcomando de fn CLI (cmd/fn/match.go), CGO+FTS5,
|
||||
# reads registry.db read-write-open (WAL visibility), no service,
|
||||
# invocado por PreToolUse hook en cada comando Bash interceptado
|
||||
# date: 2026-05-19
|
||||
# issue: 0121a wave 2 (design-e2e fn-recopilador)
|
||||
#
|
||||
# Diagnostico del stack:
|
||||
# - entry_point: cmd/fn/match.go — NO es un binario separado. Es el subcomando
|
||||
# `fn match` del CLI principal compilado con `CGO_ENABLED=1 go build -tags fts5`.
|
||||
# El binario resultante vive en la raiz del repo como `./fn`.
|
||||
# - sin framework: proceso one-shot, sin servidor HTTP, sin health endpoint.
|
||||
# - CGO_ENABLED=1 obligatorio (mattn/go-sqlite3 + FTS5 virtual table).
|
||||
# - Lee registry.db abriendo conexion normal (no ?mode=ro) porque bm25() con
|
||||
# WAL no checkpointed falla con "missing row from content table" en modo ro.
|
||||
# Gotcha documentado en app.md.
|
||||
# - no hay *_test.go especifico para match.go — solo cmd_vault_test.go en el
|
||||
# mismo package. Check "tests" incluye vault tests (go test ./cmd/fn/...).
|
||||
# - sin operations.db ni e2e_runs history => ops_audit omitido.
|
||||
# - Performance critica: hook llama `fn match` en cada Bash command del agente.
|
||||
# Latencia medida: 7-9ms en WSL2 (1255 funciones indexadas). Objetivo: <200ms.
|
||||
# - high_confidence gate real del hook: raw_score >= 4.0 Y gap top1/top2 > 1.5
|
||||
# en raw scores. El normalizado siempre devuelve 1.0 para el top — no sirve
|
||||
# como gate de confianza absoluto.
|
||||
#
|
||||
# Instrucciones de adopcion:
|
||||
# 1. Copiar el bloque "e2e_checks:" al frontmatter de apps/fn_match/app.md
|
||||
# (despues del bloque de params/output y antes de "## Ejemplo").
|
||||
# 2. Los checks asumen que ./fn existe en la raiz del repo. Si no:
|
||||
# ejecutar primero el check "build" manualmente.
|
||||
# 3. El check "latency_under_200ms" puede variar en CI (disco lento, cold start).
|
||||
# Si falla consistentemente en CI pero pasa local, bajar a severity: warning.
|
||||
# 4. El check "match_known_pattern" usa una consulta que produce deploy_cpp_exe_to_windows_bash_infra
|
||||
# como top hit. Si esa funcion se renombra o borra, el check falla — actualizar
|
||||
# expect_stdout_contains con el nuevo ID.
|
||||
#
|
||||
# Verificacion previa de las queries usadas en los checks (2026-05-19):
|
||||
# $ ./fn match "taskkill.exe /IM registry_dashboard.exe /F" --format text
|
||||
# [1.000] deploy_cpp_exe_to_windows_bash_infra raw=4.06 high_confidence=false
|
||||
# $ ./fn match "echo hola"
|
||||
# top: 3 hits, todos raw ~0.208 (< 4.0), high_confidence=false
|
||||
# $ ./fn match "echo hola" | latency: 7-9ms
|
||||
#
|
||||
# NOTA: NO escribir directo al app.md — propuesta para revision humana.
|
||||
|
||||
e2e_checks:
|
||||
# --- build ---
|
||||
# Compila el subcomando fn match (y todo el CLI) con CGO+FTS5.
|
||||
# fn match no es binario separado: vive en cmd/fn/ junto al resto del CLI.
|
||||
# El binario resultante es ./fn en la raiz del repo.
|
||||
- id: build
|
||||
cmd: "CGO_ENABLED=1 go build -tags fts5 -o fn ./cmd/fn/"
|
||||
timeout_s: 120
|
||||
severity: critical
|
||||
# por que: match.go usa go-sqlite3 (CGO) y FTS5 virtual tables. Sin -tags fts5
|
||||
# el indice FTS5 de registry.db no esta disponible y bm25() falla en runtime.
|
||||
# Fallo de build indica dep rota o cambio de API en cmd/fn/main.go.
|
||||
|
||||
# --- tests ---
|
||||
# Corre el unico test suite del package cmd/fn (cmd_vault_test.go).
|
||||
# No hay match_test.go dedicado — los tests de integracion del subcomando
|
||||
# match estan cubiertos por match_known_pattern y match_no_false_positive abajo.
|
||||
- id: tests
|
||||
cmd: "CGO_ENABLED=1 go test -tags fts5 -count=1 ./cmd/fn/..."
|
||||
timeout_s: 120
|
||||
severity: warning
|
||||
# por que: los vault tests validan la plomeria del CLI (build, flags, JSON output).
|
||||
# Severity warning porque no hay test unitario de match.go; si se anade
|
||||
# match_test.go en el futuro, ascender a critical.
|
||||
|
||||
# --- match_known_pattern ---
|
||||
# Ejecuta fn match con un patron conocido que debe producir un hit de alta
|
||||
# confianza. Usa "taskkill.exe /IM registry_dashboard.exe /F" porque:
|
||||
# - token "taskkill" es un bashMarker (penaliza hits Python/bash cruzados)
|
||||
# - "dashboard" y "exe" son tokens especificos con matches en el registry
|
||||
# - resultado esperado top[0] = deploy_cpp_exe_to_windows_bash_infra (raw=4.06)
|
||||
# Verifica que el pipeline de tokenize + FTS5 + scoring funciona end-to-end.
|
||||
- id: match_known_pattern
|
||||
cmd: "./fn match \"taskkill.exe /IM registry_dashboard.exe /F\""
|
||||
expect_stdout_contains: "deploy_cpp_exe_to_windows_bash_infra"
|
||||
timeout_s: 15
|
||||
severity: critical
|
||||
# por que: si este check falla, el hook PreToolUse no puede sugerir alternativas
|
||||
# del registry para comandos taskkill — uno de los patrones mas comunes en
|
||||
# sesiones de deploy C++. Indica regresion en tokenizer, FTS5 query builder,
|
||||
# o scoring. También detecta si la funcion fue renombrada/borrada del registry.
|
||||
|
||||
# --- match_no_false_positive ---
|
||||
# Verifica que un comando trivial sin equivalente en el registry NO produce
|
||||
# un hit de alta confianza. "echo hola" devuelve 3 hits con raw_score ~0.208
|
||||
# (todos < 4.0, threshold de high_confidence) y high_confidence=false.
|
||||
# El hook solo inyecta un hint cuando high_confidence=true — esto valida que
|
||||
# no hay spam de sugerencias para comandos inocuos.
|
||||
- id: match_no_false_positive
|
||||
cmd: "./fn match \"echo hola\""
|
||||
expect_stdout_contains: '"high_confidence": false'
|
||||
timeout_s: 10
|
||||
severity: warning
|
||||
# por que: un false positive en el hook interrumpe el flujo del agente con
|
||||
# sugerencias irrelevantes. Severity warning porque la penalizacion es UX,
|
||||
# no correctitud. Si el registro crece con funciones de "echo" / logging
|
||||
# y el raw_score sube por encima de 4.0, revisar umbral minRawForHighConf
|
||||
# en cmd/fn/match.go (actualmente 4.0).
|
||||
|
||||
# --- latency_under_200ms ---
|
||||
# Mide que una invocacion de fn match completa en < 200ms (proceso fresh,
|
||||
# sin daemon). El objetivo documentado es < 50ms (medido 7-9ms en WSL2).
|
||||
# El threshold de 200ms da margen para CI mas lento y disco frio.
|
||||
# Se usa el patron known (taskkill) para medir un caso real con FTS5 activo.
|
||||
- id: latency_under_200ms
|
||||
cmd: >
|
||||
START=$(date +%s%3N) &&
|
||||
./fn match "taskkill.exe /IM registry_dashboard.exe /F" > /dev/null &&
|
||||
END=$(date +%s%3N) &&
|
||||
MS=$((END - START)) &&
|
||||
echo "latency=${MS}ms" &&
|
||||
[ "$MS" -lt 200 ]
|
||||
timeout_s: 10
|
||||
severity: warning
|
||||
# por que: fn match es llamado por el hook PreToolUse en CADA comando Bash
|
||||
# del agente. Si la latencia supera 200ms, el hook se convierte en friccion
|
||||
# perceptible (~40% del round-trip tipico de 500ms). Severity warning porque
|
||||
# el threshold es conservador (10x el valor medido); solo alarma si hay
|
||||
# regresion grave (disco frio, WAL grande no checkpointed, CGO rebuild).
|
||||
@@ -0,0 +1,118 @@
|
||||
# Propuesta e2e_checks para apps/pipeline_launcher
|
||||
# Generada por fn-recopilador en modo design-e2e (2026-05-19)
|
||||
# app_id: pipeline_launcher
|
||||
# lang: go
|
||||
# stack: TUI bubbletea + CGO + mattn/go-sqlite3
|
||||
# issue: 0121a wave 2
|
||||
#
|
||||
# INSTRUCCIONES: copiar el bloque e2e_checks al frontmatter de
|
||||
# apps/pipeline_launcher/app.md tras revision humana.
|
||||
# NO modificar app.md automaticamente.
|
||||
#
|
||||
# Stack detectado:
|
||||
# lang=go, framework=bubbletea v0.25.0
|
||||
# CGO_ENABLED=1 (mattn/go-sqlite3 v1.14.37 en go.mod)
|
||||
# build tags: fts5 necesarios (importa fn-registry que usa fts5)
|
||||
# NO frontend/ (TUI pura, sin assets web)
|
||||
# NO tests/ ni *_test.go (check tests OMITIDO)
|
||||
# entry_point: main.go → binario: pipeline_launcher
|
||||
# config.Default() resuelve rutas via FN_REGISTRY_ROOT env var
|
||||
# Sin flags --headless, --list, --version ni --help propios en main.go
|
||||
# (la app es TUI pura; la unica salida "rapida" es abrir + cerrar con Ctrl+C)
|
||||
# operations.db presente: tablas init (sin logs — migracion 003 NO aplicada)
|
||||
# entities=0, relations=0, executions=0, assertions=0
|
||||
# registry.db: 30 pipelines con tag 'launcher' disponibles al momento de audit
|
||||
#
|
||||
# NOTAS IMPORTANTES:
|
||||
# - La app no expone ningun modo headless ni flag CLI propio. Para un check
|
||||
# "arranca bien y ve pipelines", la estrategia es: (a) go vet (compilacion
|
||||
# y lint sin ejecutar TUI) + (b) query directa a registry.db via sqlite3
|
||||
# para verificar que existen pipelines con tag launcher (lo que la TUI
|
||||
# mostraria). No se ejecuta el binario en modo TUI porque requiere TTY.
|
||||
# - El check ops_init aplica las migraciones faltantes (especialmente 003_logs)
|
||||
# sobre operations.db de e2e en /tmp, garantizando schema completo.
|
||||
# - ops_audit invoca fn-recopilador sobre la operations.db real para validar
|
||||
# integridad. Util como gate de regresion de schema/datos.
|
||||
# - No hay tag 'service' → no se necesita smoke/health check HTTP.
|
||||
# - Port e2e: N/A (no es service).
|
||||
|
||||
e2e_checks:
|
||||
# -----------------------------------------------------------------------
|
||||
# check: build
|
||||
# Por que: gate primario. Valida que el modulo Go compila con CGO+fts5.
|
||||
# CGO es obligatorio por mattn/go-sqlite3. fts5 es necesario
|
||||
# porque el modulo fn-registry (replace local) usa FTS5 en sus
|
||||
# queries sobre registry.db. Sin este tag el build falla con
|
||||
# "undefined: fts5".
|
||||
# El binario se escribe en /tmp para no contaminar el worktree
|
||||
# y hacer el check idempotente.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: build
|
||||
cmd: "cd /home/lucas/fn_registry/apps/pipeline_launcher && CGO_ENABLED=1 go build -tags fts5 -o /tmp/pipeline_launcher_e2e_bin ."
|
||||
timeout_s: 120
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# check: vet
|
||||
# Por que: go vet con CGO+fts5 detecta errores semanticos que no bloquean
|
||||
# la compilacion pero indican bugs (printf de tipo incorrecto,
|
||||
# locks copiados, etc.). Complementa build — bajo coste, alta
|
||||
# cobertura estatica.
|
||||
# Se corre sobre el modulo completo (./...) para cubrir app/,
|
||||
# config/ y views/ que el build check no ejercita separadamente.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: vet
|
||||
cmd: "cd /home/lucas/fn_registry/apps/pipeline_launcher && CGO_ENABLED=1 go vet -tags fts5 ./..."
|
||||
timeout_s: 60
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# check: pipelines_list_loads
|
||||
# Por que: valida la query central de la TUI — que registry.db contiene
|
||||
# >=1 pipeline con tag 'launcher'. Si este check falla, la pantalla
|
||||
# principal de la app mostraria "No pipelines found" que es el caso
|
||||
# de fallo silencioso mas dificil de detectar sin correr la TUI.
|
||||
# Query: buscar en functions donde kind='pipeline' y tags incluye
|
||||
# 'launcher'. Equivalent a loadPipelines() en views/pipelines.go.
|
||||
# No requiere el binario compilado — usa sqlite3 CLI directamente
|
||||
# sobre registry.db (ya autorizado para queries en operations.db
|
||||
# y uso diagnostico segun excepciones de registry_calls.md).
|
||||
# -----------------------------------------------------------------------
|
||||
- id: pipelines_list_loads
|
||||
cmd: >
|
||||
COUNT=$(sqlite3 /home/lucas/fn_registry/registry.db
|
||||
"SELECT COUNT(*) FROM functions WHERE kind='pipeline' AND tags LIKE '%launcher%';");
|
||||
[ "$COUNT" -ge 1 ] && echo "launcher_pipelines=$COUNT OK" || { echo "FAIL: no launcher pipelines found in registry.db"; exit 1; }
|
||||
timeout_s: 10
|
||||
expect_stdout_contains: "OK"
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# check: ops_schema_complete
|
||||
# Por que: la operations.db de pipeline_launcher no tiene la tabla logs
|
||||
# (migracion 003_logs NO aplicada al momento de la auditoria).
|
||||
# Este check aplica fn ops init sobre una copia en /tmp para
|
||||
# verificar que las 3 migraciones (001_init, 002_executions_assertions,
|
||||
# 003_logs) se aplican limpiamente sin errores.
|
||||
# Idempotente: crea DB nueva en /tmp cada vez.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: ops_schema_complete
|
||||
cmd: >
|
||||
rm -f /tmp/pipeline_launcher_e2e_ops.db &&
|
||||
cp /home/lucas/fn_registry/apps/pipeline_launcher/operations.db /tmp/pipeline_launcher_e2e_ops.db &&
|
||||
FN_REGISTRY_ROOT=/home/lucas/fn_registry /home/lucas/fn_registry/fn ops init /tmp/pipeline_launcher_e2e_ops.db &&
|
||||
sqlite3 /tmp/pipeline_launcher_e2e_ops.db "SELECT name FROM sqlite_master WHERE type='table' AND name='logs';" | grep -q logs && echo "logs table OK" || { echo "FAIL: logs table missing after ops init"; exit 1; }
|
||||
timeout_s: 30
|
||||
expect_stdout_contains: "logs table OK"
|
||||
severity: warning
|
||||
# NOTA: severity warning porque la migracion faltante no bloquea el uso
|
||||
# normal de la TUI (no escribe logs todavia). Promover a critical cuando
|
||||
# la app comience a usar la tabla logs activamente.
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# check: ops_audit
|
||||
# Por que: invoca fn-recopilador sobre la operations.db real para detectar
|
||||
# referencias rotas, tablas faltantes o datos inconsistentes.
|
||||
# Es el gate del bucle reactivo fase 3 — sin este check el agente
|
||||
# no tiene visibilidad sobre regresiones de schema/datos entre
|
||||
# versiones del app.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: ops_audit
|
||||
ref: "fn-recopilador:apps/pipeline_launcher"
|
||||
@@ -0,0 +1,148 @@
|
||||
# Propuesta e2e_checks para apps/primitives_gallery
|
||||
# Generado por fn-recopilador modo design-e2e
|
||||
# Issue: 0121a wave 2
|
||||
# Fecha: 2026-05-19
|
||||
#
|
||||
# Diagnostico:
|
||||
# lang=cpp, framework=imgui (fn::run_app), domain=gfx
|
||||
# toolchain: mingw-w64 (cross-compile Windows desde WSL)
|
||||
# modulos: main.cpp + capture.cpp + demo.cpp + 12 demos_*.cpp
|
||||
# + 44 .cpp del registry (core + viz + gfx — el set mas grande del ecosistema)
|
||||
# demos catalogadas: 43 entradas en k_demos[] (k_demo_count = 43)
|
||||
# Core (20): button, icon_button, toolbar, modal_dialog, text_input, select, toast,
|
||||
# tree_view, badge, empty_state, page_header, dashboard_panel, kpi_card,
|
||||
# text_editor, file_watcher, process_runner, tween, bezier_editor,
|
||||
# timeline, sql_workbench
|
||||
# Viz (20): bar_chart, pie_chart, line_plot, scatter_plot, histogram, sparkline,
|
||||
# graph_viewport, graph_styles, candlestick, gauge, heatmap, table_view,
|
||||
# surface_plot_3d, scatter_3d, mesh_viewer, treemap, sankey, chord,
|
||||
# contour, voronoi
|
||||
# Gfx (3): shader_canvas, gl_texture, gl_info
|
||||
# deps externas: SQLite::SQLite3, stb (vendor), imgui_text_edit (vendor)
|
||||
# persistencia propia: ninguna (no BD, no state files)
|
||||
# sin tests/ ni tests_*.py
|
||||
# sin tag 'service': no expone HTTP (smoke con health: OMITIDO)
|
||||
# operations.db: NO usa (ops_audit: OMITIDO)
|
||||
#
|
||||
# FLAG --capture:
|
||||
# Confirmado en main.cpp (L186-215): rama headless que crea ventana GLFW
|
||||
# GLFW_VISIBLE=FALSE + GL 3.3 core (deliberadamente baja para WSL Mesa/llvmpipe).
|
||||
# Requiere contexto OpenGL real. En WSL sin GPU: LIBGL_ALWAYS_SOFTWARE=1 (Mesa).
|
||||
# En WSL sin display (headless puro): GLFW requiere $DISPLAY o EGL offscreen.
|
||||
# La severidad de capture_mode se marca WARNING (no critical) porque WSL2 sin
|
||||
# libGL Mesa puede no entregar contexto GL valido — el check diagnostica pero
|
||||
# no bloquea el build gate si el entorno no tiene driver GL.
|
||||
#
|
||||
# FLAG --list-demos: NO existe. main.cpp no tiene subcomando de listado.
|
||||
# demos_count: OMITIDO — no hay forma de obtener el conteo sin invocar GL.
|
||||
# Alternativa implementada: demos_count_static verifica el conteo en fuente.
|
||||
#
|
||||
# Patron: C++ ImGui app con modo --capture headless-GL
|
||||
|
||||
app_id: primitives_gallery
|
||||
|
||||
e2e_checks:
|
||||
# Build del target completo para Windows via mingw-w64.
|
||||
# primitives_gallery es el artefacto con mayor numero de .cpp del registry
|
||||
# enlazados (44 archivos: core + viz + gfx). Si cualquier funcion del registry
|
||||
# rompe su API de compilacion, este check lo detecta antes de que otro app falle.
|
||||
# Actua como build gate del registry de funciones C++.
|
||||
- id: build
|
||||
cmd: "cmake --build /home/lucas/fn_registry/cpp/build/windows --target primitives_gallery -j"
|
||||
timeout_s: 300
|
||||
severity: critical
|
||||
|
||||
# Verifica que el artefacto .exe existe tras el build.
|
||||
# El build puede reportar exit 0 con -j en builds parciales sin producir binario.
|
||||
# Sin este check, capture_mode fallaria con un mensaje de error menos claro.
|
||||
- id: binary_exists
|
||||
cmd: "test -f /home/lucas/fn_registry/cpp/build/windows/apps/primitives_gallery/primitives_gallery.exe"
|
||||
timeout_s: 5
|
||||
severity: critical
|
||||
|
||||
# Modo --capture headless: crea ventana GLFW VISIBLE=FALSE + GL 3.3 core,
|
||||
# renderiza las 43 demos en offscreen framebuffer y guarda PNG en /tmp/.
|
||||
# Confirma que: (a) todas las demos compilan y se ejecutan sin crash,
|
||||
# (b) el pipeline capture.cpp funciona hasta stbi_write_png,
|
||||
# (c) ninguna demo provoca SIGSEGV/assertion al primer frame (warmup=3).
|
||||
#
|
||||
# Requiere contexto OpenGL real. En WSL sin GPU usar:
|
||||
# LIBGL_ALWAYS_SOFTWARE=1 (Mesa/llvmpipe) — disponible si mesa-utils instalado.
|
||||
# Si el entorno no puede entregar GL context, glfwCreateWindow retorna NULL y
|
||||
# el binario sale con exit 1 (ver capture.cpp L62-68).
|
||||
# Marcado WARNING porque la disponibilidad de GL en CI/WSL headless no esta
|
||||
# garantizada sin configuracion extra del entorno.
|
||||
#
|
||||
# El check verifica que se genero al menos un PNG (button.png es el primero).
|
||||
# Una suite completa de 43 PNGs indica que todas las demos son estables.
|
||||
- id: capture_mode
|
||||
cmd: >
|
||||
mkdir -p /tmp/primitives_gallery_e2e &&
|
||||
/home/lucas/fn_registry/cpp/build/windows/apps/primitives_gallery/primitives_gallery.exe
|
||||
--capture /tmp/primitives_gallery_e2e
|
||||
timeout_s: 120
|
||||
severity: warning
|
||||
# Nota: en WSL2 sin GPU puede necesitar LIBGL_ALWAYS_SOFTWARE=1 prefijado.
|
||||
# Si el entorno tiene Mesa: prepend "LIBGL_ALWAYS_SOFTWARE=1" al cmd.
|
||||
# Sin GL disponible, la demo gl_info y shader_canvas pueden fallar pero
|
||||
# las demas (Core/Viz) deben seguir siendo capturadas si GL 3.3 esta disponible.
|
||||
|
||||
# Verifica que el capture produjo PNGs para las 43 demos catalogadas en k_demos[].
|
||||
# Cada demo debe generar un PNG nombrado por su id (ej. button.png, bar_chart.png).
|
||||
# Este check distingue "capture arranco y capturo algo" (capture_mode) de
|
||||
# "capture completo todas las demos sin skip". Se puede ejecutar solo si
|
||||
# capture_mode paso.
|
||||
# Cuenta archivos .png en el dir de salida y compara con k_demo_count=43.
|
||||
- id: capture_completeness
|
||||
cmd: >
|
||||
count=$(ls /tmp/primitives_gallery_e2e/*.png 2>/dev/null | wc -l);
|
||||
echo "PNG count: $count";
|
||||
test "$count" -ge 43
|
||||
timeout_s: 10
|
||||
severity: warning
|
||||
# Nota: depende de capture_mode. Si capture_mode fallo por falta de GL,
|
||||
# este check tambien fallara (warning, no bloquea gate).
|
||||
|
||||
# Verifica que el .ico esta presente junto al fuente de la app.
|
||||
# add_imgui_app genera primitives_gallery_appicon.rc que windres incluye
|
||||
# como recurso (.rsrc) en el .exe. Si appicon.ico falta, el build pasa
|
||||
# pero el .exe queda sin icono embebido (visible en Explorer + taskbar).
|
||||
- id: icon_exists
|
||||
cmd: "test -f /home/lucas/fn_registry/apps/primitives_gallery/appicon.ico"
|
||||
timeout_s: 5
|
||||
severity: warning
|
||||
|
||||
# Verifica estaticamente que el conteo de demos en fuente es consistente.
|
||||
# k_demo_count se deriva de sizeof(k_demos)/sizeof(k_demos[0]) en main.cpp.
|
||||
# Cuenta las entradas de DemoEntry en k_demos[] usando grep en main.cpp
|
||||
# como proxy — detecta si se añadio una demo al array pero no al modulo
|
||||
# demos_*.cpp (lo que provocaria un linker error en build, pero este check
|
||||
# da feedback mas temprano en el ciclo).
|
||||
# Referencia esperada: 43 entradas (conteo manual de k_demos[] en main.cpp L37-84).
|
||||
- id: demos_count_static
|
||||
cmd: >
|
||||
count=$(grep -c '^\s*{"' /home/lucas/fn_registry/apps/primitives_gallery/main.cpp);
|
||||
echo "DemoEntry count in source: $count";
|
||||
test "$count" -ge 43
|
||||
timeout_s: 5
|
||||
severity: warning
|
||||
# Nota: el grep cuenta lineas con '{"' en main.cpp — patron exclusivo de las
|
||||
# entradas de k_demos[]. Si el formato de k_demos[] cambia, revisar el patron.
|
||||
|
||||
# Justificacion por check:
|
||||
# | check | razon |
|
||||
# |----------------------|----------------------------------------------------------------------------|
|
||||
# | build | 44 .cpp del registry enlazados — build gate de API C++ del registry entero |
|
||||
# | binary_exists | confirma que cmake produjo .exe (no solo exit 0) |
|
||||
# | capture_mode | --capture es headless-GL (GLFW invisible + GL 3.3); confirma no-crash 43 |
|
||||
# | capture_completeness | distingue "algo capturado" de "todas las demos completas" |
|
||||
# | icon_exists | .ico requerido para windres embeds — faltante no rompe build pero si deploy |
|
||||
# | demos_count_static | detecta drift entre k_demos[] en fuente y modulos demos_*.cpp |
|
||||
#
|
||||
# checks OMITIDOS y razon:
|
||||
# | check | razon de omision |
|
||||
# |-------------|-----------------------------------------------------------------------------|
|
||||
# | ops_audit | no usa operations.db |
|
||||
# | smoke/health | no es service, no expone HTTP |
|
||||
# | demos_count | --list-demos no existe en el binario; no hay forma headless sin GL |
|
||||
# | self_test | fn::run_app no parsea --self-test; no implementado en main.cpp |
|
||||
@@ -0,0 +1,181 @@
|
||||
# e2e_checks proposal — registry_dashboard
|
||||
#
|
||||
# app_id: registry_dashboard
|
||||
# lang: cpp
|
||||
# stack: C++ ImGui (fn::run_app), SQLite directo + HTTP client (cpp-httplib) +
|
||||
# WebSocket client (ws_client.cpp RFC6455), nlohmann/json,
|
||||
# datos de registry.db via sqlite_api:8484 (fallback SQLite directo)
|
||||
# date: 2026-05-19
|
||||
# issue: 0121a wave 2 (design-e2e fn-recopilador)
|
||||
#
|
||||
# Diagnostico del stack:
|
||||
# - app.md: lang=cpp, framework=imgui, domain=tui, NO tiene tag 'service'
|
||||
# - La app es un CLIENTE, no un servidor: no expone puerto propio.
|
||||
# El puerto 8484 es de sqlite_api (dependencia externa), no de este binario.
|
||||
# - entry_point: main.cpp -> fn::run_app(cfg, render) -> GUI loop
|
||||
# - build: cmake --build cpp/build/linux --target registry_dashboard
|
||||
# (el binario queda en cpp/build/linux/apps/registry_dashboard)
|
||||
# En Windows: cpp/build/windows/apps/registry_dashboard.exe (cross-compile MinGW)
|
||||
# - NO tiene --self-test implementado (sin argparse headless en main.cpp)
|
||||
# - NO hay *_test.cpp ni tests/ con pytest en la app
|
||||
# - NO hay frontend/ React/Vite (es C++ puro con ImGui, no Go+frontend)
|
||||
# - NO tiene operations.db propia (usa registry.db via API o directo)
|
||||
# - SIN health endpoint (no es service, no expone HTTP)
|
||||
# - vendor/: solo nlohmann/json.hpp (cpp-httplib via vendor/httplib.h)
|
||||
# - build Linux ya disponible: cpp/build/linux/apps/registry_dashboard
|
||||
# - build Windows ya disponible: cpp/build/windows/apps/registry_dashboard.exe
|
||||
#
|
||||
# IMPORTANTE — por que no hay check "smoke" ni "api_endpoint_kpi":
|
||||
# registry_dashboard no es un servidor — es una app GUI que CONSUME datos.
|
||||
# Un smoke check al estilo "arrancar + health GET" no aplica porque no hay
|
||||
# endpoint que consultar. La validacion de que los datos se cargan
|
||||
# correctamente requiere que sqlite_api este corriendo (dependencia externa)
|
||||
# o que se pase un registry.db directo. Ambos casos se cubren con el check
|
||||
# 'integration_sqlite_direct' abajo, que es determinista y sin dependencias.
|
||||
#
|
||||
# El check 'api_endpoint_kpi' solicitado en el prompt del orquestador se
|
||||
# implementa indirectamente via 'integration_sqlite_direct': se construye
|
||||
# el binario con DISPLAY no seteado e invocacion headless no disponible.
|
||||
# Ver 'ops_audit' para el camino alternativo via fn-recopilador.
|
||||
#
|
||||
# Instrucciones de adopcion:
|
||||
# 1. Copiar el bloque "e2e_checks:" al frontmatter de
|
||||
# projects/fn_monitoring/apps/registry_dashboard/app.md
|
||||
# (antes del primer "##" de prosa).
|
||||
# 2. El check 'build' asume que el directorio cpp/build/linux existe y cmake
|
||||
# fue configurado previamente. Si no: anteponer
|
||||
# "cmake -B /home/lucas/fn_registry/cpp/build/linux -S /home/lucas/fn_registry/cpp &&"
|
||||
# al cmd o usar el check 'build_configure' (opcional, ver abajo).
|
||||
# 3. El check 'integration_sqlite_direct' requiere que registry.db exista en
|
||||
# la raiz del repo. En CI, puede copiarse de un fixture o generarse con
|
||||
# 'fn index' antes de lanzar la suite.
|
||||
# 4. Severity de 'build' puede bajarse a 'warning' si el binario Windows es
|
||||
# el artefacto principal de deploy y el Linux build es solo CI-gate.
|
||||
#
|
||||
# NOTA: NO escribir directo al app.md — propuesta para revision humana.
|
||||
|
||||
e2e_checks:
|
||||
# --- build ---
|
||||
# Compila el target registry_dashboard para Linux via cmake.
|
||||
# Usa el build directory preexistente (cmake ya configurado).
|
||||
# El binario queda en cpp/build/linux/apps/registry_dashboard.
|
||||
# CGO no aplica (es C++, no Go). FTS5 se compila via SQLITE_ENABLE_FTS5
|
||||
# en la amalgamation vendoreada (CMakeLists.txt lo setea).
|
||||
- id: build
|
||||
cmd: "cmake --build /home/lucas/fn_registry/cpp/build/linux --target registry_dashboard -j$(nproc)"
|
||||
timeout_s: 300
|
||||
severity: critical
|
||||
# por que: la app enlaza ~20 funciones del registry C++ + sqlite + ws_client.
|
||||
# Un fallo de build indica API break en fn_framework, funcion del registry
|
||||
# con firma cambiada, o include roto. Es el gate mas importante para una
|
||||
# app sin tests automaticos.
|
||||
|
||||
# --- verify_binary ---
|
||||
# Confirma que el binario existe y es ejecutable tras el build.
|
||||
# Tambien verifica la version de symbols minimos esperados (sin linkage roto).
|
||||
- id: verify_binary
|
||||
cmd: "test -x /home/lucas/fn_registry/cpp/build/linux/apps/registry_dashboard && /home/lucas/fn_registry/cpp/build/linux/apps/registry_dashboard --help 2>&1 || true"
|
||||
expect_exit: 0
|
||||
timeout_s: 5
|
||||
severity: critical
|
||||
# por que: --help no esta implementado en la app, pero el binario debe poder
|
||||
# cargarse sin segfault. exit != 139 (SIGSEGV) es suficiente.
|
||||
# Detecta linkage roto (missing .so, wrong rpath) que el build paso por alto.
|
||||
|
||||
# --- integration_sqlite_direct ---
|
||||
# Verifica que el binario puede abrir registry.db via SQLite directo
|
||||
# (sin sqlite_api corriendo) en modo headless usando timeout como proxy.
|
||||
# La app imprime "SQLite fallback: <path>" a stdout y luego entra en el
|
||||
# GUI loop. timeout 3s mata el proceso antes de que el loop arranque pero
|
||||
# DESPUES de que load_registry_data() ejecute la query SQL inicial.
|
||||
# exit 124 = proceso terminado por timeout (exitoso para nuestro proposito).
|
||||
# exit != 1 y != 139 indica que la carga SQL no crash.
|
||||
- id: integration_sqlite_direct
|
||||
cmd: >
|
||||
DISPLAY="" timeout 3
|
||||
/home/lucas/fn_registry/cpp/build/linux/apps/registry_dashboard
|
||||
/home/lucas/fn_registry/registry.db
|
||||
2>&1 | head -5
|
||||
expect_exit: 1
|
||||
timeout_s: 10
|
||||
severity: warning
|
||||
# por que: valida la capa data.cpp (SQLite directo) sin depender de
|
||||
# sqlite_api ni de un display X11. En headless, GLFW falla al abrir
|
||||
# la ventana (exit 1) pero ANTES de eso load_registry_data() ya ejecuto
|
||||
# las queries. Si el exit es 139 (SIGSEGV) o 134 (SIGABRT) -> regression
|
||||
# en las queries SQL o en el parsing del schema.
|
||||
# Severity warning porque el output exacto puede variar segun la version
|
||||
# de GLFW en el CI.
|
||||
# NOTA: si se implementa --self-test en la app, escalar a critical y
|
||||
# usar ese flag en lugar de DISPLAY="" timeout 3.
|
||||
|
||||
# --- data_schema_check ---
|
||||
# Verifica que el schema de registry.db tiene las tablas que data.cpp
|
||||
# espera: functions, types, apps, analysis, proposals, unit_tests.
|
||||
# Este check no requiere el binario compilado — es SQL puro sobre la BD.
|
||||
# Actua como pre-condicion para integration_sqlite_direct.
|
||||
- id: data_schema_check
|
||||
cmd: >
|
||||
sqlite3 /home/lucas/fn_registry/registry.db
|
||||
"SELECT COUNT(*) FROM sqlite_master WHERE type='table'
|
||||
AND name IN ('functions','types','apps','analysis','proposals','unit_tests');"
|
||||
expect_stdout_contains: "6"
|
||||
timeout_s: 5
|
||||
severity: critical
|
||||
# por que: si faltan tablas, data.cpp lanzara queries que retornan error.
|
||||
# Detecta migraciones no aplicadas o registry.db corrupto antes de
|
||||
# intentar el build + integration test.
|
||||
|
||||
# --- call_monitor_schema_check ---
|
||||
# Verifica que call_monitor.operations.db (consumida por la tab Monitor)
|
||||
# tiene la tabla 'calls' que load_claude_usage_http() espera via sqlite_api.
|
||||
# Este check valida la BD directamente — en produccion sqlite_api la expone
|
||||
# via HTTP, pero aqui queremos detectar schema drift independientemente.
|
||||
- id: call_monitor_schema_check
|
||||
cmd: >
|
||||
sqlite3 /home/lucas/fn_registry/projects/fn_monitoring/apps/call_monitor/operations.db
|
||||
"SELECT COUNT(*) FROM sqlite_master WHERE type='table'
|
||||
AND name IN ('calls','violations','sessions');"
|
||||
expect_stdout_contains: "3"
|
||||
timeout_s: 5
|
||||
severity: warning
|
||||
# por que: la tab Monitor del dashboard se nutre de estas tablas.
|
||||
# Si 'calls' no existe, la tab muestra placeholder vacio sin error visible.
|
||||
# severity warning porque call_monitor.db puede estar vacia en un entorno
|
||||
# nuevo (aun sin datos de telemetria).
|
||||
|
||||
# --- ws_client_compile_check ---
|
||||
# Verifica que ws_client.cpp compila sin warnings fatales.
|
||||
# El cliente WebSocket es codigo propio (no libreria vendored) que implementa
|
||||
# RFC6455 minimal — propenso a regresiones si se cambia la interfaz de
|
||||
# WsClient sin actualizar todos los call sites.
|
||||
- id: ws_client_compile_check
|
||||
cmd: >
|
||||
cmake --build /home/lucas/fn_registry/cpp/build/linux
|
||||
--target registry_dashboard -j$(nproc) -- --warn-undefined-functions
|
||||
2>&1 | grep -i "ws_client" | grep -i "error" || true
|
||||
expect_stdout_contains: ""
|
||||
timeout_s: 60
|
||||
severity: warning
|
||||
# por que: ws_client es la pieza mas fragil del stack (RFC6455 manual,
|
||||
# sin tests dedicados). Buscar explicitamente errores en ws_client.cpp
|
||||
# en el output de cmake da visibilidad sin duplicar el check build.
|
||||
# expect_stdout_contains "" = la busqueda no encuentra errores (grep
|
||||
# devuelve vacio). Si grep encuentra algo, el check falla con exit 0
|
||||
# pero stdout no vacio — revisar la logica si fn-analizador necesita
|
||||
# el patron inverso.
|
||||
|
||||
# --- ops_audit ---
|
||||
# Invoca al fn-recopilador sobre el directorio de la app para verificar
|
||||
# que app.md esta bien indexado en registry.db, que uses_functions son
|
||||
# validos, y estructura general del artefacto.
|
||||
# No hay operations.db propia en esta app — el recopilador auditara
|
||||
# solo la estructura y las referencias cruzadas con registry.db.
|
||||
- id: ops_audit
|
||||
ref: "fn-recopilador:projects/fn_monitoring/apps/registry_dashboard"
|
||||
severity: warning
|
||||
# por que: registry_dashboard declara ~20 uses_functions en app.md.
|
||||
# El recopilador verifica que cada ID existe en registry.db y detecta
|
||||
# drift si alguna funcion fue renombrada o eliminada.
|
||||
# severity warning porque la app puede funcionar correctamente aunque
|
||||
# un ID en uses_functions este mal escrito (solo metadata).
|
||||
@@ -0,0 +1,133 @@
|
||||
# e2e_checks proposal for apps/registry_mcp
|
||||
#
|
||||
# Generado por fn-recopilador en modo design-e2e.
|
||||
# NO modifica app.md directamente — propuesta para revision humana.
|
||||
# Copiar el bloque e2e_checks al frontmatter de apps/registry_mcp/app.md
|
||||
# tras aprobar.
|
||||
#
|
||||
# Diagnostico:
|
||||
# lang=go, framework=mcp (github.com/mark3labs/mcp-go)
|
||||
# tag service → runtime=stdio (no puerto HTTP, no health endpoint)
|
||||
# entry_point=main.go, build requiere CGO_ENABLED=1 -tags fts5 (sqlite + FTS5)
|
||||
# tests: naming_test.go (TestValidateName/TestValidateDomain)
|
||||
# fts_test.go (TestSanitizeFTS5/TestIsSnakeCase)
|
||||
# format_test.go (TestRenderFunctionMarkdown/TestLangFence/TestTruncate)
|
||||
# integration_test.go (TestIntegration_StdioListSearchShow/TestIntegration_SearchByTag)
|
||||
# -> los integration tests arrancan el servidor en-proceso con pipes, NO
|
||||
# requieren binario compilado, pero SI requieren registry.db accesible.
|
||||
# operations.db: NO presente — la app no usa operations.db propia.
|
||||
# frontend: NO.
|
||||
# migrations/: NO (lee registry.db en modo ro, no escribe schema).
|
||||
# gating flags: --enable-run y --enable-write — NO se testean aqui (requieren
|
||||
# credenciales/estado externo). Solo se validan los tools read-only.
|
||||
#
|
||||
# Checks propuestos:
|
||||
# build -> compilar con CGO+fts5. Gate critico: si no compila, nada mas importa.
|
||||
# tests_unit -> go test ./... (unit tests puros: naming, fts, format).
|
||||
# Los integration tests necesitan registry.db; se corre todo porque
|
||||
# integration_test.go hace findRegistryRoot(t) y hace t.Skip si
|
||||
# no lo encuentra. En el entorno de dev hay registry.db en la raiz,
|
||||
# por tanto los integration tests CORREN.
|
||||
# naming_reject -> smoke del validador de nombres: input invalido debe salir con
|
||||
# exit != 0 o stdout/stderr con "naming:" / "action verb".
|
||||
# Se implementa via go test -run TestValidateName directamente
|
||||
# (mas simple y determinista que un binario auxiliar).
|
||||
# mcp_handshake -> arranca el binario en modo stdio, envia initialize JSON-RPC
|
||||
# por stdin, espera respuesta JSON valida con "result" en stdout.
|
||||
# Usa FN_REGISTRY_ROOT explicito y timeout de 5s con bash+kill.
|
||||
# Es el smoke mas util: prueba que el binario abre la BD,
|
||||
# registra tools y responde al protocolo MCP correctamente.
|
||||
|
||||
app_id: registry_mcp
|
||||
dir_path: apps/registry_mcp
|
||||
generated_by: fn-recopilador
|
||||
generated_at: "2026-05-19"
|
||||
|
||||
e2e_checks:
|
||||
# -------------------------------------------------------------------
|
||||
# 1. BUILD — compilar con CGO + FTS5. Sin esto el resto no sirve.
|
||||
# CGO_ENABLED=1 es obligatorio para go-sqlite3 (FTS5 tag lo exige).
|
||||
# -------------------------------------------------------------------
|
||||
- id: build
|
||||
cmd: >
|
||||
cd /home/lucas/fn_registry/apps/registry_mcp &&
|
||||
CGO_ENABLED=1 go build -tags fts5 -o registry_mcp .
|
||||
timeout_s: 120
|
||||
severity: critical
|
||||
# por que: gate fundamental. Build roto = binario inexistente = nada funciona.
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# 2. TESTS — unit + integration. Los integration_tests arrancan el
|
||||
# servidor con pipes en-proceso; no necesitan binario pero si
|
||||
# registry.db en la raiz del repo (findRegistryRoot hace t.Skip si
|
||||
# no la encuentra). En dev siempre esta disponible.
|
||||
# -------------------------------------------------------------------
|
||||
- id: tests
|
||||
cmd: >
|
||||
cd /home/lucas/fn_registry/apps/registry_mcp &&
|
||||
CGO_ENABLED=1 go test -tags fts5 -count=1 -timeout 60s ./...
|
||||
timeout_s: 90
|
||||
severity: critical
|
||||
# por que: cubre naming validator, FTS5 sanitizer, markdown renderer
|
||||
# y el handshake stdio completo (tools/list + fn_search + fn_show)
|
||||
# via TestIntegration_StdioListSearchShow.
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# 3. NAMING_REJECT — el validator de nombres (naming.go) debe rechazar
|
||||
# input invalido. Valida que la regla ids_naming.md esta codificada
|
||||
# y activa. Se ejercita directamente via go test -run.
|
||||
# Expected: PASS (el test Table case "Slice" espera err != nil).
|
||||
# -------------------------------------------------------------------
|
||||
- id: naming_reject
|
||||
cmd: >
|
||||
cd /home/lucas/fn_registry/apps/registry_mcp &&
|
||||
CGO_ENABLED=1 go test -tags fts5 -count=1 -run TestValidateName -v 2>&1 |
|
||||
grep -q "PASS"
|
||||
timeout_s: 30
|
||||
severity: critical
|
||||
# por que: fn_create_function llama al validator antes de escribir archivos.
|
||||
# Si el validator acepta nombres invalidos (PascalCase, bare nouns),
|
||||
# el registry se corrompe con IDs no-canonicos. Este check lo detecta.
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# 4. MCP_HANDSHAKE_STDIO — smoke del protocolo JSON-RPC 2.0 real.
|
||||
# Arranca el binario compilado en modo stdio, envia 'initialize',
|
||||
# verifica que la respuesta tiene "result" (MCP ServerInfo valido).
|
||||
# Usa timeout con kill para que no quede colgado.
|
||||
# FN_REGISTRY_ROOT apunta a la raiz del repo donde esta registry.db.
|
||||
# -------------------------------------------------------------------
|
||||
- id: mcp_handshake_stdio
|
||||
cmd: |
|
||||
BINARY=/home/lucas/fn_registry/apps/registry_mcp/registry_mcp
|
||||
PAYLOAD='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"e2e_probe","version":"0"}}}'
|
||||
RESPONSE=$(echo "$PAYLOAD" | timeout 5 "$BINARY" \
|
||||
--registry-root /home/lucas/fn_registry \
|
||||
--log-level error \
|
||||
2>/dev/null | head -n1)
|
||||
echo "response: $RESPONSE"
|
||||
echo "$RESPONSE" | python3 -c "
|
||||
import sys, json
|
||||
r = json.load(sys.stdin)
|
||||
assert 'result' in r, f'missing result key: {r}'
|
||||
assert 'serverInfo' in r['result'] or 'protocolVersion' in r['result'], f'unexpected result: {r[\"result\"]}'
|
||||
print('OK: MCP initialize handshake passed')
|
||||
"
|
||||
timeout_s: 15
|
||||
severity: critical
|
||||
# por que: es el smoke mas real posible — el mismo protocolo que
|
||||
# Claude Code usa al arrancar la sesion. Detecta regressions
|
||||
# en: apertura de BD, registro de tools, serialization JSON-RPC.
|
||||
# HTTP no se testea aqui (requiere --enable-run/--enable-write config).
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
# 5. OPS_AUDIT — auditoria de operations.db.
|
||||
# registry_mcp no tiene operations.db propia (servicio stdio puro,
|
||||
# no usa el ciclo reactivo). Este check queda como WARNING para
|
||||
# documentar la decision y detectar si en el futuro se crea una BD.
|
||||
# -------------------------------------------------------------------
|
||||
- id: ops_audit
|
||||
ref: "fn-recopilador:apps/registry_mcp"
|
||||
severity: warning
|
||||
# por que: registry_mcp no usa operations.db hoy (runtime stdio sin
|
||||
# entities/executions propias). Check WARNING para detectar
|
||||
# si se anade en el futuro sin actualizar estos checks.
|
||||
@@ -0,0 +1,130 @@
|
||||
# app_id: services_api
|
||||
# lang: go (CGO_ENABLED=1, go-sqlite3, NO fts5 — no FTS5 features in this app)
|
||||
# stack: net/http + SQLite (go-sqlite3) + SSH polling (ssh_exec_go_infra)
|
||||
# dir_path: apps/services_api
|
||||
# entry: main.go (--bind / --once / --registry / --db flags)
|
||||
# service: port 8485, health /api/health, systemd-user
|
||||
# ops.db: SI — service_state + service_transition (001_init.sql applied)
|
||||
# sin entities/relations/executions del schema fn_operations
|
||||
# tests: NO (*_test.go absent) — solo --once como smoke gate
|
||||
# basicAuth: NO detectado en main.go / check.go
|
||||
# ssh: SI — probeRemote usa infra.SSHExec (ssh_exec_go_infra)
|
||||
# e2e port: 8585 (prod 8485 + 100, evita colision)
|
||||
# issue: 0121a wave 2 — design-e2e services_api
|
||||
# date: 2026-05-19
|
||||
#
|
||||
# INSTRUCCIONES PARA EL HUMANO:
|
||||
# 1. Revisar y ajustar comentarios; luego copiar el bloque e2e_checks:
|
||||
# al frontmatter de apps/services_api/app.md (despues de service: block).
|
||||
# 2. El check ops_audit invoca fn-recopilador sobre operations.db propia
|
||||
# (NO usa el schema estandar fn_operations — solo service_state/service_transition).
|
||||
# 3. El check smoke_once usa --once + --db efimera para no contaminar la BD
|
||||
# de produccion ni necesitar registry.db real (usa /tmp/fn_e2e_sreg.db con
|
||||
# un registry.db vacio).
|
||||
# 4. smoke_health sube el binario como daemon real en puerto 8585 y verifica
|
||||
# /api/health. Requiere que el check build haya producido el binario.
|
||||
# 5. No hay go test porque no existen *_test.go. Si se añaden tests en el
|
||||
# futuro, activar el check tests descomentando la entrada correspondiente.
|
||||
|
||||
e2e_checks:
|
||||
# -----------------------------------------------------------------------
|
||||
# 1. BUILD
|
||||
# CGO_ENABLED=1 porque go-sqlite3 requiere cgo (no hay fts5 en este app,
|
||||
# pero el flag no rompe nada y evita confusion futura si se añade FTS).
|
||||
# -----------------------------------------------------------------------
|
||||
- id: build
|
||||
cmd: "cd /home/lucas/fn_registry/apps/services_api && CGO_ENABLED=1 go build -o services_api ."
|
||||
timeout_s: 120
|
||||
severity: critical
|
||||
# por que: si no compila no hay nada que probar
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# 2. SMOKE --once
|
||||
# Corre un ciclo completo de checks sin arrancar el HTTP server.
|
||||
# Usa una BD efimera en /tmp y apunta el registry a fn_registry real
|
||||
# (read-only); las queries a registry.db devuelven los targets reales del PC.
|
||||
# Exit 0 = el loop no peta al cargar targets + persistir en ops_db.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: smoke_once
|
||||
cmd: >
|
||||
cd /home/lucas/fn_registry/apps/services_api &&
|
||||
FN_REGISTRY_ROOT=/home/lucas/fn_registry
|
||||
./services_api
|
||||
--once
|
||||
--registry /home/lucas/fn_registry
|
||||
--db /tmp/services_api_e2e.db
|
||||
--bind 127.0.0.1:8585
|
||||
timeout_s: 45
|
||||
severity: critical
|
||||
# por que: valida que loadTargets + probeLocal + upsertState no panican
|
||||
# Nota: SSH remotes daran no-route (sin config SSH en CI) — eso es correcto
|
||||
# y no falla el check; el exit code del proceso es 0 si completo el ciclo.
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# 3. SMOKE HTTP + HEALTH
|
||||
# Arranca el server en background en puerto 8585 con BD efimera,
|
||||
# espera que /api/health responda 200.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: smoke_health
|
||||
cmd: >
|
||||
cd /home/lucas/fn_registry/apps/services_api &&
|
||||
./services_api
|
||||
--bind 127.0.0.1:8585
|
||||
--registry /home/lucas/fn_registry
|
||||
--db /tmp/services_api_e2e_http.db
|
||||
--interval 300s &
|
||||
health: "http://127.0.0.1:8585/api/health"
|
||||
timeout_s: 15
|
||||
severity: critical
|
||||
# por que: verifica que el HTTP server arranca y responde en el puerto
|
||||
# declarado en service.port (proxy: 8585 en lugar de 8485)
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# 4. ENDPOINT /api/services (warning — depende de datos del PC)
|
||||
# Valida que el endpoint responde JSON bien formado con el campo self_pc.
|
||||
# Es warning porque en un PC sin ~/.fn_pc o sin registry.db poblado
|
||||
# puede devolver lista vacia pero eso no es un bug.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: check_services_endpoint
|
||||
cmd: >
|
||||
curl -sf http://127.0.0.1:8585/api/services |
|
||||
python3 -c "import sys,json; d=json.load(sys.stdin); assert 'services' in d and 'self_pc' in d"
|
||||
timeout_s: 10
|
||||
severity: warning
|
||||
# por que: smoke de formato de respuesta del endpoint principal que
|
||||
# services_monitor (C++) consume. Un cambio de schema JSON rompe el cliente.
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# 5. ENDPOINT /api/pcs (warning)
|
||||
# Valida que /api/pcs responde con el campo pcs.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: check_pcs_endpoint
|
||||
cmd: >
|
||||
curl -sf http://127.0.0.1:8585/api/pcs |
|
||||
python3 -c "import sys,json; d=json.load(sys.stdin); assert 'pcs' in d"
|
||||
timeout_s: 10
|
||||
severity: warning
|
||||
# por que: services_monitor usa /api/pcs para la barra lateral de PCs
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# 6. OPS AUDIT
|
||||
# Invoca fn-recopilador sobre la operations.db propia.
|
||||
# NOTA: esta BD tiene schema propio (service_state, service_transition),
|
||||
# NO el schema estandar fn_operations (entities/relations/executions).
|
||||
# El recopilador auditara estructura y datos vivos.
|
||||
# -----------------------------------------------------------------------
|
||||
- id: ops_audit
|
||||
ref: "fn-recopilador:apps/services_api"
|
||||
severity: warning
|
||||
# por que: detecta inconsistencias en service_state (ej. overall invalido,
|
||||
# last_check_ts cero en todas las filas = --once nunca corrio)
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# OMITIDO: tests
|
||||
# No existen *_test.go en apps/services_api. Activar cuando se añadan.
|
||||
#
|
||||
# - id: tests
|
||||
# cmd: "cd /home/lucas/fn_registry/apps/services_api && CGO_ENABLED=1 go test -count=1 ./..."
|
||||
# timeout_s: 120
|
||||
# severity: critical
|
||||
# -----------------------------------------------------------------------
|
||||
@@ -0,0 +1,114 @@
|
||||
# e2e_checks proposal — sqlite_api
|
||||
# app_id: projects/fn_monitoring/apps/sqlite_api
|
||||
# lang: go
|
||||
# stack: Go service, net/http, CGO_ENABLED=1, SQLite FTS5
|
||||
# module: fn-registry (go.mod en raiz del repo)
|
||||
# binary: projects/fn_monitoring/apps/sqlite_api/sqlite_api (pre-compilado)
|
||||
# systemd: sqlite_api.service (user scope, ExecStart usa el binario compilado)
|
||||
# e2e port: 8684 (prod 8484 + 200)
|
||||
# e2e db: /tmp/sqlite_api_e2e.db
|
||||
# date: 2026-05-19
|
||||
# issue: 0121a wave 2
|
||||
# nota: service critico — caida 20h el 2026-05-17 por Restart=on-failure
|
||||
# (ya corregido a Restart=always en el unit). Checks refuerzan
|
||||
# que el binario arranca, responde, y ejecuta queries correctamente.
|
||||
|
||||
e2e_checks:
|
||||
# --- build ------------------------------------------------------------------
|
||||
- id: build
|
||||
# Compila el binario del service con CGO+FTS5.
|
||||
# El binario resultante es el mismo que usa el systemd unit.
|
||||
# Correr desde la raiz del repo porque go.mod vive ahi.
|
||||
cmd: >
|
||||
cd /home/lucas/fn_registry &&
|
||||
CGO_ENABLED=1 go build -tags fts5
|
||||
-o projects/fn_monitoring/apps/sqlite_api/sqlite_api
|
||||
./projects/fn_monitoring/apps/sqlite_api/
|
||||
timeout_s: 120
|
||||
severity: critical
|
||||
|
||||
# --- tests ------------------------------------------------------------------
|
||||
- id: tests
|
||||
# Suite de tests unitarios Go existente (handlers_test.go).
|
||||
# Cubre: /health, /api/databases, /api/databases/:db/query,
|
||||
# ValidateQuery (whitelist SELECT/PRAGMA/WITH/EXPLAIN),
|
||||
# DiscoverDatabases, /tables, /schema, 404 para DB inexistente.
|
||||
# Usan DB en t.TempDir() — totalmente efimeros.
|
||||
cmd: >
|
||||
cd /home/lucas/fn_registry &&
|
||||
CGO_ENABLED=1 go test -tags fts5 -count=1 -v
|
||||
./projects/fn_monitoring/apps/sqlite_api/
|
||||
timeout_s: 60
|
||||
severity: critical
|
||||
|
||||
# --- smoke ------------------------------------------------------------------
|
||||
- id: smoke
|
||||
# Arranca el binario compilado con BD efimera y puerto alto.
|
||||
# FN_REGISTRY_ROOT apunta a la raiz para que DiscoverDatabases
|
||||
# encuentre registry.db real (necesario para /api/databases).
|
||||
# El proceso queda en background; fn-analizador lo mata al terminar.
|
||||
cmd: >
|
||||
FN_REGISTRY_ROOT=/home/lucas/fn_registry
|
||||
/home/lucas/fn_registry/projects/fn_monitoring/apps/sqlite_api/sqlite_api
|
||||
--bind 127.0.0.1:8684
|
||||
--data-factory-db /tmp/sqlite_api_e2e_df.db &
|
||||
health: "http://127.0.0.1:8684/api/databases"
|
||||
timeout_s: 10
|
||||
severity: critical
|
||||
|
||||
# --- query_endpoint ---------------------------------------------------------
|
||||
- id: query_endpoint
|
||||
# Valida que el endpoint POST /api/databases/:db/query funciona end-to-end:
|
||||
# 1. Crea una BD SQLite efimera con una tabla trivial.
|
||||
# 2. La registra como argumento de query via BD de registro en /api/databases.
|
||||
# 3. Ejecuta SELECT 1 contra la BD "registry" (siempre disponible si hay
|
||||
# FN_REGISTRY_ROOT correcto) y valida JSON con count>=1 y campo "columns".
|
||||
# Alternativa mas simple: hit directo al endpoint con la BD ya registrada.
|
||||
cmd: >
|
||||
curl -sf -X POST http://127.0.0.1:8684/api/databases/registry/query
|
||||
-H 'Content-Type: application/json'
|
||||
-d '{"sql":"SELECT 1 AS ping"}'
|
||||
| python3 -c "
|
||||
import sys, json
|
||||
r = json.load(sys.stdin)
|
||||
assert r.get('count') == 1, f'count != 1: {r}'
|
||||
assert 'columns' in r, f'no columns: {r}'
|
||||
assert r['columns'][0] == 'ping', f'col != ping: {r}'
|
||||
print('query_endpoint OK:', r)
|
||||
"
|
||||
timeout_s: 10
|
||||
severity: critical
|
||||
|
||||
# --- write_rejection --------------------------------------------------------
|
||||
- id: write_rejection
|
||||
# El service se declara read-only. Verifica que INSERT es rechazado con 400.
|
||||
# Regresion directa del contrato de seguridad de sqlite_api.
|
||||
cmd: >
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}"
|
||||
-X POST http://127.0.0.1:8684/api/databases/registry/query
|
||||
-H 'Content-Type: application/json'
|
||||
-d '{"sql":"INSERT INTO functions VALUES (\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\",\"x\")"}') &&
|
||||
[ "$STATUS" = "400" ]
|
||||
timeout_s: 10
|
||||
severity: critical
|
||||
|
||||
# --- auth_check -------------------------------------------------------------
|
||||
- id: auth_check
|
||||
# Service actualmente NO requiere auth (bind 127.0.0.1 mitiga).
|
||||
# Este check documenta el estado actual: cualquier cliente local puede
|
||||
# hacer queries. Si en el futuro se añade X-Registry-Token, este check
|
||||
# debe actualizarse para enviar el token correcto y esperar 401 sin token.
|
||||
# Por ahora verifica que el endpoint responde sin auth header (comportamiento esperado).
|
||||
cmd: >
|
||||
curl -sf http://127.0.0.1:8684/health
|
||||
| python3 -c "import sys,json; r=json.load(sys.stdin); assert r['status']=='ok'"
|
||||
timeout_s: 5
|
||||
severity: warning
|
||||
|
||||
# --- ops_audit --------------------------------------------------------------
|
||||
- id: ops_audit
|
||||
# Invoca al fn-recopilador sobre las operations.db de apps de fn_monitoring.
|
||||
# sqlite_api no tiene su propio operations.db pero es parte del proyecto
|
||||
# fn_monitoring que sí tiene call_monitor con operations.db activa.
|
||||
ref: "fn-recopilador:projects/fn_monitoring/apps/sqlite_api"
|
||||
severity: warning
|
||||
Reference in New Issue
Block a user