Silo de noticias + /lecturas — decisión (2026-09-11)
Contexto: plan aprobado para extraer sitios destino de X, unificar timelines DS/ML/AI y cruzar con second-brain; esta decisión incorpora los descubrimientos de la revisión de ~/nef/decisions/.
# Silo de noticias y /lecturas — plan y constraints (2026-09-11)
## Visión
Unificar timelines: (1) X → sitios destino (no tuits), (2) HN + Telegram
hn_best_comments + outsiders MX (izquierda independiente, anti-extractivista,
anti-feudalista, crítica de la tecnología con perspectiva social), (3)
Lobste.rs, (4) medios US/MX con énfasis en análisis (no titulares), (5)
lectura DS/ML/AI, y (6) cruce transversal con second-brain (escuela, libros,
papers). Clave: feed y retrieval.
## Decisiones cerradas
1. Sin planes de pago: extracción local vía RSSHub (:1200). Apify/Twillot
descartados por ahora (se pueden añadir como capa aparte si el volumen
lo exige).
2. NYT + WaPo + Washington Sun solo RSS público + NewsAPI (100 req/día free;
NEWSAPI_KEY ya en .env.local). El módulo de sesión subscrita
(`prensa_sesion.py`) NO se implementa: queda apagado como opción futura
(usuario se conecta desde MX; acceso "extremadamente cauteloso" solo si
se decide explícitamente).
3. `/lecturas` es local-first: se genera, el usuario revisa en local y se
sube "como está". El commit + deploy ES la aprobación (sin gate en código).
4. Términos/conceptos se derivan del second-brain COMPLETO (360 nodos + tags)
+ rama DVS (499 recursos). No se inventan.
5. Silo X = sitios destino; cubre TECH_X (7) + HERMANAS_X (12) = campo
semántico completo.
## Descubrimientos de /decisions (constraints que aplican)
- `2026-09-06-surtido-no-divulgar-receta.md`: el HTML público de /lecturas no
menciona jerga interna (scripts, rutas, nombres de archivos, instrucciones);
estados vacíos neutros; el resumen de aprobación es interno; grep pre-deploy.
- `2026-09-09-capa-recursos-dvs-local.md`: DVS es local-only, nunca a nodo.ws;
sus TÉRMINOS alimentan el catálogo, su CONTENIDO no se publica ni se
convierte en nodos del grafo ("no inventar memoria").
- `2026-09-08-second-brain-twitter-logica.md` + `2026-09-10-...-operacion.md`
+ `2026-09-09-...-observar-atención.md`: el corpus propio (5,911 tweets +
130,626 likes, SQLite FTS5 / D1 con búsqueda local-only) es la otra mitad
de "unificar timelines": el silo es lo entrante, el corpus es el historial
de atención. Cruce futuro natural: "¿ya me importó esto?" contra likes.
La señal técnica está en los likes, no en los tweets.
- `[CREDENCIAL].md`: paquete semántico
(fuente, prioridad, caducidad, versión) y frescura visible. Los JSON del
silo llevan `fuente`, `fecha`, `generado`; /lecturas muestra frescura.
- `2026-09-06-surtido-auditoria-anti-bots.md`: /lecturas se renderiza estático
desde JSON; cero fetch/LLM en request; cero endpoints nuevos; sin exponer
tokens. El hardening ya deployado se respeta.
- `[CREDENCIAL].md`: para el cruce futuro
noticia→grafo, patrón de revisión humana (stubs, evidencia/inferencia/
confianza separadas); nada entra directo a content/nodes.
- `2026-09-07-surtido-mesh-cauces.md`: guion.json como semilla semántica;
contexto para el formato de paquete, no bloqueante.
## Plan por fases
F4 → F1 → F2 → F3 → verificación → commit/push → revisión local → deploy.
- F4 Términos: `scripts/terminos_desde_second_brain.py` extrae de
`~/nef/second-brain`: nodos (360: 243 concept, 38 tool, 28 paper, 27
algorithm, 18 model; tags ml, dl, ai-systems, nlp, retrieval, dataeng,
stats, cybersec, snn, responsible-ai…) + DVS (`content/resources/`: 499;
categorías Websites & Tools 128, Media 125, Style Guides 69, Publications
63, Education 47, Data Sources 45…; temas visualizacion, narrativa,
diseno-ux, datos-geo) → `terminos_dsml.txt` editable (~700–900 términos).
- F1 Silo X: `feed.py` `_urls_destino()` / `_dominio_basura()` / `_silo_x()`
sobre TECH_X + HERMANAS_X vía RSSHub; dedupe por URL destino; detecta
medios nuevos sin RSS; CLI `feed.py --silo` → `reporte/x-silos.json`
(`post_partida, url_destino, dominio, medio, publicado, terminos[]`).
- F2 Fuentes: `HERMANAS_RSS` += NYT (HomePage/Technology/Science), WaPo
(world/national https), Washington Sun; flags `analisis`, `paywall`;
NewsAPI vía `sentimiento.collect_newsapi` con
`domains=nytimes.com,washingtonpost.com`.
- F3 `/lecturas`: `lecturas.py` → `reporte/lecturas.json` (merge X+TG+RSS+
NewsAPI; categorías DS/ML/AI/PROG/CHINA-RD; dedupe por URL destino);
`GET /lecturas` en asgi (patrón /fuentes).
- F5 Verificación: `py_compile` + `git diff --check`; curl local de `--silo`
y `/lecturas`; commit por fase; push; deploy CLI solo tras revisión local.
## Estado
Plan aprobado y persistido. Nada toca S76 (fuera de servicio) ni Linode
(radio); todo local y gratis.
## Addendum (misma fecha, ejecución)
- Env real: los secretos viven en `.vercel/.env` (ignorado por git), no en
`.env.local`. `feed.py`/`lecturas.py` ahora cargan `.env.local` +
`.vercel/.env`. La llave es `NEWS_API_KEY`; `sentimiento.collect_newsapi`
acepta ambos nombres (`NEWSAPI_KEY` o `NEWS_API_KEY`).
- Volumen: China y tech ampliados (21 fuentes nuevas: Solidot, V2EX, 少数派,
爱范儿, OSChina, InfoQ 中国, 钛媒体, 极客公园, Lobsters, Ars Technica,
TechCrunch, The Verge, 404 Media, Simon Willison, Import AI, The Gradient,
Alignment Forum, MIT Tech Review, Krebs, The Record, BleepingComputer).
Topes: 12/fuente y 12/medio. `/lecturas` pasó de 265 a ~810 items.
- Diseño: 9 fuentes dataviz/diseño (FlowingData, Nightingale DVS, The Pudding,
Visual Capitalist, Information is Beautiful, Storytelling with Data,
Creative Review, Smashing, A List Apart) con categoría DISEÑO.
- Archivo: `archivo.py` acumula diseño + ML desde `/lecturas` y data/prensa/ a
`reporte/archivo-diseno-ml.json/.html` (solo metadatos y enlace).
- Acceso cauteloso: `prensa_sesion.py` NO automatiza login con password; usa
cookies exportadas a mano (`data/prensa-cookies.json`), cola en
`data/prensa-cola.txt`, máx 2/día/sitio, espera 45–90 s, aborta 401/403/429.
Texto completo solo en `data/prensa/` (local, ignorado por git); nunca a
reporte/ ni publicado. `--status` para ver si hay cookies.
- Variante Selenium: `prensa_selenium.py` usa Brave con perfil dedicado
(`data/prensa-perfil/`): login manual UNA vez (`--login`), cookies persisten
en el perfil; luego visita la cola con los mismos límites y registro
compartido con prensa_sesion. Ventana visible, una pestaña, sin headless en
producción. `--check` verifica driver (Brave 152 verificado).
- Referencias (brecha informativa): `referencias.py` busca sin Google (ddgs;
SerpAPI si hay llave) por perfil ML/Data/DataViz/Programmer/AI en NYT, WaPo
y web; filtra relevancia por palabras; consulta Wayback (CDX) y archive.today
por resultado y acumula en `reporte/referencias.json/.html`. `--preciada URL`
marca joyas y las respalda (ej. "Twelve Million Phones, One Dataset, Zero
Privacy", NYT 2019). Límites: 2–4 s entre búsquedas, 1.5–3 s entre archivos.
- Título de NYT/WaPo puede venir basura (403 con <title>dominio): se rechaza
y se toma del snapshot de Wayback.
- SerpAPI: `SERPAPI_KEY` en `.vercel/.env` (250 consultas/mes). Motor
`duckduckgo` (sin Google; `SERPAPI_ENGINE` configurable). Contador
`serpapi_uso` en `reporte/referencias.json`; corte en 240 (`SERPAPI_BUDGET`),
al agotarse cae a ddgs. `--news` usa ddgs news (gratis, sin gastar).
- Rotación: `cursor` en referencias.json avanza por la matriz perfiles×sitios
para que cada corrida traiga consultas nuevas.
- Runner local: `scripts/local_news.sh` (lecturas → archivo → referencias;
`--queries N`, `--archivo N`, `--news`).