media_monitor es un backend editorial semiautónomo orientado a una ruta operativa simple:
news in → brief → draft → human last mile.
Hoy el foco no es agregar capas, sino mantener viva la ruta útil y reducir ambigüedad operacional.
La ejecución recomendada es por lanes independientes vía bin/run_minimal_loop_once.sh:
- sensing (obligatoria, cada 60m)
make s01make s02make s03make export-pr3amake build-news-access-indexes
- editorial (recomendada, cada 6h)
make s04make s06make s05make build-editorial-access-indexes
- enrich (opcional, queue/on-demand)
python scripts/06_scrape_enrich.py
Entrypoint único por lane:
bin/run_minimal_loop_once.sh --lane sensing
bin/run_minimal_loop_once.sh --lane editorial
bin/run_minimal_loop_once.sh --lane enrichUn sprint se considera cerrado solo si se cumple este mínimo:
homeviva (ruta principal visible y utilizable sin arqueología documental).storyviva (al menos una historia recorre la ruta completa y queda accionable).- handoff panel simple vivo (
storage/indexes/editorial_latest.jsoncomo superficie de decisión). - README canónico corto actualizado (este archivo como golden path).
Criterio de rechazo explícito:
- Si para entender el flujo básico hacen falta múltiples runbooks/scripts en paralelo, el sprint no se cierra.
Evidencia obligatoria por PR:
- Comandos ejecutados (copiables) y resultado observable.
- Capturas de la superficie afectada cuando el cambio sea visual/operativo.
- Validación de no duplicación de mapping entre frontend/API/scripts (o
N/Ajustificado si una capa no existe en el repo).
Generar snapshot público hardened para la web:
make build-editorial-access-indexes DIGEST_AT=$(date -u +%Y%m%dT%H)
make publish-last-mile-snapshotAbrir vista local:
python -m http.server 8000
# abrir http://localhost:8000/web/Deploy en Vercel (online):
vercel --prodHardening aplicado:
- La UI consume
web/data/editorial_latest.json(snapshot público hardened para publicación estática). - Snapshot generado por
scripts/publish_last_mile_snapshot.pycon shape mínima y sanitizada para evitar exponer campos no necesarios. vercel.jsonaplica headers de seguridad (CSP,X-Frame-Options,nosniff) yno-storepara JSON de estado.
Source of truth (news_site): runtime truth = storage/indexes → deploy truth = refreshed snapshot in apps/news_site/public/data.
# 1) generar/actualizar índices runtime
make build-news-access-indexes DIGEST_AT=$(date -u +%Y%m%dT%H)
make build-editorial-access-indexes DIGEST_AT=$(date -u +%Y%m%dT%H)
# 2) refrescar snapshot público (copia + validación)
npm --prefix apps/news_site run refresh-data
# 3) build deployable (incluye refresh-data)
npm --prefix apps/news_site run build:deployable
# 4) deploy
vercel --prodNotas del refresh:
- Falla con error si faltan
news_recent_refs_latest.jsonlonews_recent_groups_latest.jsonl, si están vacíos o si no parsean como JSONL. - Si falta
storage/indexes/editorial_latest.json, escribe un fallback determinístico enapps/news_site/public/data/editorial_latest.json.
- Verificar runtime:
make preflight-runtime- Ejecutar una corrida de sensing (dry run):
make s01 DRY_RUN=1
make s02 DRY_RUN=1
make s03 DRY_RUN=1- Levantar heartbeat de sensing:
make heartbeat-start INTERVAL_SEC=3600
make heartbeat-statusbin/→ entrypoints de operación.Makefile→ wiring de stages.apps/news_acquire|news_editorial|news_enrich→ ownership por dominio.legacy/y algunosscripts/→ compat wrappers aún activos.contracts/schemas/→ contratos interoperables.storage/buses/ystorage/indexes/→ superficies exportables.docs/runbooks/→ runbooks de operación, migración y pruning.
- Evitar nuevas capas/orquestadores sin consumidor real.
- Priorizar claridad de entrypoints sobre expansión de superficies.
- Tratar artefactos intermedios (
data/pf_out,data/drafts,data/quarantine) como internos, no contratos públicos.
Para más detalle operativo: ver docs/runbooks/pr5-minimal-autonomous-loop.md.