ADR — Un solo engine (nef-silo · surtido · news-silo · second-brain)

Fecha: 2026-09-22. Estado: parcial (cerrado lo marcado; el resto pendiente de confirmación). Relacionados: 2026-09-22-bateria-engine-resultados.md, [CREDENCIAL].md, [CREDENCIAL].md, 2026-09-11-silo-noticias-lecturas.md.

Contexto

Búsqueda en ~/nef/decisions/ (260 docs) y ai-sessions: no existía una decisión de “un solo engine”. El rastro era fragmentado: unificar timelines (2026-09-11, varado en la rama experiments de surtido), silo-engine “componente aparte” con hook pendiente a news-silo (2026-09-19), roadmap del retriever (ejecutado en nef-silo), enrich MVP (second-brain) y extracción de exports al Linode.

Estado real: un pipeline de facto con órganos duplicados. Fetch RSS/X/TG ×2 (surtido y nef-silo), clasificador de 7 temas ×2 (home_feed.py y _REGLAS), dedup ×3, clustering ×2 (LSH vs HDBSCAN), búsqueda ×3, enriquecimiento ×3. news-silo produce silo-textos.json… que nadie consume. La rama experiments de surtido tiene lecturas/archivo/referencias sin mergear.

Decisiones cerradas (2026-09-22)

  1. Ingesta por sabores con objetivos propios. Cada sabor declara su profundidad default y su objetivo de diversidad: flash (frescura, cuota por medio), coverage (cobertura, mínimos por tema/región), depth (multi-medio por evento, privacidad local), signals, knowledge, personal.
  2. Profundidad: archivo total por tiers.
    • T0 content:encoded/summary del RSS al insertar (hoy se tira) — gratis.
    • T1 fetch + trafilatura en el Linode — público.
    • T2 paywall/anti-bot con cookies/Brave — local-only.
    • T3 transcripciones (faster-whisper) — local-only.
    • Reglas: dedup antes de extraer; texto de prensa nunca se publica; guardar texto + hash + versión de extractor (no HTML crudo).
  3. KPI: balance de perspectivas (distribución por sesgo/credibilidad/región, por item y por evento), condicionado a extender el índice de ratings: hoy solo 2.9% de items calificados.
  4. second-brain: el engine propone candidatos → _enrich/ con provenance; adopción manual (regla del repo). second-brain aporta vocabulario (terminos_desde_second_brain).
  5. Métrica clave: datos relevantes = no duplicado + match (modelo A grafo con IDF, modelo B perfil curado). Medida por tests/bateria.py.

Recomendaciones pendientes de confirmar

  • Núcleo: opción A — nef-silo evoluciona a engine (SQLite+FTS5, cron Linode, salud ya construida), con surtido como plano de publicación y news-silo/second-brain como planos local/consumidor. Descartadas: repo nuevo (re-port + doble mantenimiento) y surtido como núcleo (cron en Vercel, sin DB local).
  • Surtido: congelar la ingestión (deja de fetchear y clasificar; consume el engine), pero no el producto (radio, ediciones, mailing, /leer siguen evolucionando). Falta confirmar.
  • Clustering: C1 dos etapas — online LSH assign-or-open en el server (ya existe) + re-cluster local periódico con Qwen3-0.6B + c-TF-IDF que reescribe silos.json; spike C2 (embeddings ONNX sin torch en el Linode, medir RAM en la ventana 05:00–13:00). Falta elegir.

Evidencia (batería, 2026-09-22)

  • t0 65% · t1 83% (1.4 s/artículo) · t2 128 docs · t3 titular 50% → texto 90% (lift +40 pt; perfil 0% → 70%).
  • unfetch: solape 100% con surtido en la ventana del engine → “un fetch” es viable.
  • relevancia base sin profundidad: 20% grafo / 8.9% perfil; top-20 = 100% (el ranking funciona).
  • sabores: 57 flash / 55 coverage.
  • Bug corregido: duplicados inflado (3,243/4,416 URLs ya conocidas) → set urls_db + repetidos.

Fases

  • F0 Congelar trabajo suelto en los 4 repos + rescatar terminos_desde_second_brain.py de experiments.
  • F1 Sabores + ratings importados + KPIs de balance y relevancia en salud.
  • F2 Un fetch: engine exporta formato surtido; surtido consume (diff verificado 24 h).
  • F2.5 Archivo total por tiers + backfill de los items existentes.
  • F3 Clustering con texto (C1 + spike C2).
  • F4 Puente second-brain (candidatos → _enrich/).
  • F5 Limpieza: rama experiments, módulos muertos, doc de frontera por repo.

NO

  • Publicar texto de prensa o transcripciones. Extraer duplicados. Bajar torch al Linode. Extraer X/TG (su texto ya es el item). Auto-adoptar nodos. Monorepo.

Commits (nef-silo, locales, sin push ni deploy)

  • 5be9d4d robustez: topes, alertas, --dry-run, salud; fix repetidos/duplicados.
  • 6cc1c6e batería: 8 probes + README.