# 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).
