Skip to content

docs: estructura del repositorio y validación E2E previa a v0.3.0 - #110

Merged
g-garciac2022 merged 1 commit into
devfrom
docs/estructura-y-validacion-e2e
Aug 15, 2026
Merged

docs: estructura del repositorio y validación E2E previa a v0.3.0#110
g-garciac2022 merged 1 commit into
devfrom
docs/estructura-y-validacion-e2e

Conversation

@g-garciac2022

Copy link
Copy Markdown
Collaborator

Estructura del repositorio y validación E2E previa a v0.3.0

Sin issue asociado: es documentación de trabajo ya hecho, no una unidad de
trabajo. Los hallazgos que sí requieren acción salieron de aquí y tienen su
propio sitio — #107, #108 y #109.

Cierra los dos huecos que quedaban antes de tagear H2: el sistema nunca se había
ejercitado de punta a punta desde que existe la API REST, y no había ningún
documento que dijera dónde debe vivir cada cosa.

Qué incluye

  • docs/estructura.md (nuevo): qué contiene cada carpeta y, sobre todo, qué
    cualifica a una pieza para vivir en ella. Tabla por fichero dentro de
    backend/.
  • README.md: la validación E2E con sus tres hallazgos y el caso estrella.
  • backend/config/settings.py: el comentario de mcp_execute_timeout, que
    afirmaba «~20 s» cuando lo medido son 51,6. Único cambio en código, y no
    altera comportamiento
    .

Criterios de pertenencia, no descripciones

La distinción no es retórica. Una descripción se escribe mirando lo que ya hay
dentro, así que por construcción lo legitima: «api/ contiene endpoints,
esquemas y la orquestación del análisis» es cierta, y habría dado por bueno que
la lógica de veredictos viviera ahí.

Un criterio es una pregunta que se contesta sí o no sobre una pieza concreta, y
puede delatar a algo que ya está dentro:

Carpeta Criterio
api/ ¿existiría si no hubiera HTTP?
core/ ¿lo usa más de una capa y no sabe nada del dominio del clickbait?
integrations/ ¿envuelve algo externo al proyecto?
config/ ¿cambia entre entornos sin tocar código?
evaluation/ ¿se ejecuta a mano para producir una medición?

Aplicarlos destapó cuatro tensiones y dos bugs sin ejecutar una línea. La
primera —la orquestación en api/— resultó tener consecuencia de diseño y se
analiza en #107: el servidor MCP no expone ninguna herramienta que contraste
señales, así que el agente conversacional no puede reproducir el veredicto del
formulario.

También se borró backend/tools/, resto de la estructura anterior al patrón
integrations/*/tool.py: contenía sólo un __pycache__ y git no rastreaba nada.

La validación E2E

Los 175 tests mockean la red y el protocolo, así que nada había probado la cadena
real con el servidor MCP levantado por HTTP. Se corrió con los dos backends
NLP
y con el historial apuntado a un fichero temporal.

Paso Resultado En frío En caliente
GET /health ok, tres integraciones 0,43 s
GET /tools 11 herramientas, degraded: false 0,068 s
execute válido / 404 / 422 los tres exactos 0,66 s
POST /analyze local veredicto correcto 105,6 s 0,363 s
POST /analyze remoto mismo veredicto 38,9 s 0,610 s
GET /history + 10 filtros todos correctos 0,033 s

Todo funcionó. Y aun así salieron tres cosas.

1 · El timeout de ejecución no tiene arreglo por número. detect_clickbait
contra un servidor MCP en frío tardó 51,6 s con un corte de 60, y con el
modelo ya descargado. Subirlo no lo arregla: con caché fría el tiempo depende del
ancho de banda y no está acotado. La solución es que cargar no ocurra dentro de
una petición — calentamiento al arrancar, que es tarea de H4.

2 · NLP_BACKEND=remote no hace remoto el sistema. Sólo conmuta dos de las
cinco señales; incoherencia, léxico y lineal son siempre locales. Por eso el
«remoto en frío» tardó 38,9 s: era MiniLM cargándose en local, no la red.
Consecuencia para H4: la imagen Docker necesita torch aunque se despliegue en
modo remoto.

3 · Los ~20 s del arranque en frío son ~105 s con el backend local y las
cinco señales.

El caso estrella, en vivo

El primer análisis reprodujo el listicle de ejemplo:

forma    -> None   (detect_clickbait=False · lexical=True · linear=True)
engano   -> True   (incoherence)
VEREDICTO: enganoso

La dimensión forma tenía 2 contra 1 y el sistema se negó a resolverlo:
declaró la discrepancia en vez de votar. El tono no votó. Y la jerarquía hizo el
resto.

Pero los dos que coincidieron son justo los que comparten extracción de
rasgos
, y el que discrepó es el único independiente. Ese «2 contra 1» es un
par acoplado contra una vista independiente
: con agregación por mayoría se
habría dictaminado forma = clickbait apoyándose en dos señales que ven lo
mismo.

El diseño resultó más robusto de lo que sabía ser — y por eso el caso observado
tranquiliza más de lo que debería: protege cuando las señales acopladas
discrepan, y es vulnerable cuando coinciden, que es lo que hacen casi
siempre. Abierto como #109.

Notas

  • Ningún hallazgo rompe funcionalidad: los tres son de configuración y
    documentación, y quedan declarados como límites conocidos de v0.3.0.
  • La carga perezosa se queda. Es lo que evita que importar un módulo arrastre
    1,6 GB y lo que permite que el CI corra sin torch. No se sustituye: se
    complementa con un disparo deliberado en el arranque.
  • Las tensiones 2, 3 y 4 quedan documentadas sin resolver. Convertir el
    documento en un refactor encubierto es cómo se queda a medias.
  • Sin medir todavía: si parte de esos 51,6 s son consultas evitables al hub de
    HuggingFace (HF_HUB_OFFLINE=1). Es barato y va con H4.

@g-garciac2022
g-garciac2022 merged commit ee3fd32 into dev Aug 15, 2026
1 check passed
@g-garciac2022
g-garciac2022 deleted the docs/estructura-y-validacion-e2e branch August 15, 2026 11:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant