La semana en la que paramos a mirar lo que ya teníamos
Semana de instrumentación, hardening y limpiar la casa: Observio empieza a recibir señales reales de Ganga24, Sofi pasa por una auditoría de clasificadores que destapa 10 cosas, Chordna deja de inventarse álbumes y sixsevenapps prepara el salto de Beehiiv a Loops.
Hay semanas de construir cosas nuevas y semanas de pararte a mirar lo que ya tienes funcionando. Esta fue claramente de las segundas, y se nota en el tipo de commits: menos features brillantes, más instrumentación, más "esto que dimos por bueno hace un mes, ¿de verdad lo era?". Que es, probablemente, donde se cuece el 80% del producto real.
Ganga24: Observio deja de ser una promesa
La noticia gorda es que Observio P1 está LIVE en Ganga24. Durante meses Observio fue un dashboard medio vacío esperando a que alguien le mandase eventos de verdad. Esta semana cerramos FEAT-032 y FEAT-032b, y ahora el scraper emite cuatro señales clave (offer_scraped, offer_published, digest_sent, click_recorded) hacia el wrapper packaged. Por dentro es bastante poco glamuroso: un wrapper que centraliza el emit(), configuración alineada con la realidad de Observio (no con la que nos habíamos inventado en la spec original), y un scope reduction explícito a Phase A — porque la versión completa requería tocar más sitios de los que tenía sentido en una sola PR. Decir "hacemos menos" en mitad de una FEAT cuesta, pero ahorra dos semanas de bugs por contagio.
En paralelo, FEAT-035 hardening de newsletter cerró sus tres waves: schema + token helpers, Turnstile + cookies + lookups por hash, y el script de rotación con su CORS y su header de webhook bien puestos. Y como toda semana que se precie, hubo sus dos hotfixes de manual: la cookie g24_prefs estaba en SameSite=Strict y se moría en cuanto el usuario venía desde el email (clásico — el cambio a Lax debería haber sido la versión por defecto desde el día uno), y el link de rotación del email se invalidaba de forma inmediata al llegar el siguiente digest. Bug bonito porque solo aparece si abres el correo "tarde". Esos son los que más duelen: no rompen para ti porque tú estás siempre dentro del producto.
También hubo limpieza de specs — renombrado de _archive/ a archive/, purga de metadocs pre-SDD en completed/ — el tipo de tarea que nadie celebra pero que evita que dentro de seis meses no sepas qué carpeta es la fuente de verdad.
Sofi: auditoría de clasificadores con resultado incómodo
Sofi tuvo la semana más densa. FEAT-027 fue una auditoría completa de los clasificadores — los modelos que deciden si un mensaje del cole es "reunión", "deberes", "actividad extraescolar" o ruido. Salieron diez findings. Algunos eran el típico edge case que asumes que pasa al 0.5% de los casos pero pasa al 8%; otros eran reglas que parecían razonables sobre el papel y no aguantan dos semanas de mensajes reales. Se aplicaron seis fixes directos, más uno extra (FEAT-025 Fix E) para clasificar correctamente emails de clubs deportivos por remitente — porque resulta que el contenido del mail engaña mucho menos que el dominio desde el que sale.
En observabilidad, FEAT-024 persiste los outputs de los agentes (Telegram + WhatsApp) en una tabla propia. Suena aburrido hasta que recuerdas que sin eso, debuggear por qué un usuario recibió un resumen raro es ir a ciegas — tienes el input, tienes la respuesta final, pero todo el razonamiento intermedio se evaporaba. Ahora queda. Esto además desbloquea D-007 en Observio, que es lo siguiente que viene.
Dos fixes de scraper que merece la pena mencionar porque son el tipo de detalle que sólo aparece operando: el early-stop del scraper se cambió de "para cuando encuentres uno conocido" a "para cuando encuentres tres consecutivos sin guardar". El primero ahorra requests pero te corta a la primera coincidencia falsa; el segundo es más caro pero infinitamente más robusto. Es la diferencia entre optimizar prematuramente y optimizar con un mes de logs detrás.
Y un hotfix de domingo: los auto-reminders se estaban creando para mensajes de hace meses cada vez que el scraper rescaneaba. Filtro de 30 días y a otra cosa.
Chordna: el resolver de álbumes ya no alucina
FEAT-025 cerró en Chordna tras dos PRs adicionales de pulido. El problema era jugoso: el resolver de álbumes, cuando no encontraba un match limpio, se conformaba con cualquier release que contuviera el track — y eso significaba que canciones populares acababan asignadas a recopilatorios random de "100 Hits del Verano 2003". Ahora hay un tight track match, los Soundtracks se supersedan correctamente (porque un BSO casi nunca es el álbum canónico de la canción) y se subió el límite de SOLR para que el resolver tenga más candidatos donde elegir. También se amplió la allow-list del genre-cleaner con un rescate de abreviaturas — los géneros venían a veces como "alt rock" en lugar de "alternative rock" y el cleaner los tiraba.
FEAT-011 entró en draft: artículos de blog optimizados para SEO y GEO. La parte interesante no es el SEO clásico sino el GEO — generative engine optimization, escribir contenido pensando en que lo va a citar un LLM, no sólo en que lo rankee Google. Veremos si la tesis aguanta.
sixsevenapps: cron arreglado y Beehiiv en la rampa de salida
La propia web tuvo dos cosas. Primero, el journal cron estaba roto porque dependía de nvm.sh y el cron no tiene shell interactivo — se derivó el binario de node desde el symlink directamente y resucitó. Segundo, el script de newsletter generaba la semana ISO actual en lugar de la anterior, así que cada lunes publicaba un resumen vacío. Bug pequeño, consecuencia ridícula. Después del fix se hizo backfill de 22 dailies y 7 weeklies para no dejar agujero en el journal.
Y entró en active la FEAT-007: migración de newsletter de Beehiiv a Loops.so. Beehiiv cumplió su función pero Loops encaja mejor con el resto del stack y nos quita una integración que pedía constantemente atención manual. La FEAT-006 (tracking de CTAs outbound) también se promovió a active — necesitamos saber cuánta gente del journal acaba clickando a las apps reales, porque ahora mismo es fe.
Semana de hacer la cama antes de invitar gente a dormir.