Runbook¶
Estado real vs. plan
Esta página describía el cron del sistema completo (post Fase 5). El código hoy solo
tiene Fase 0 y parte de Fase 1: ejecutar_ingesta, renormalizar, seed_fuentes,
generar_reporte. diff_proyectos, extraer_documentos, puntuar y check_debarment
son ítems sin marcar en fases.md — no existen como comandos todavía.
Verificado contra inteligencia/management/commands/ el 2026-09-18.
Operación normal (hoy)¶
| Cuándo | Qué corre |
|---|---|
| Diario 06:00 UTC | ejecutar_ingesta para fuentes de cadencia diaria (carril A) |
| Lunes 06:00 UTC | ejecutar_ingesta semanales (carril B, ingesta silenciosa) |
| Lunes 08:00 UTC | generar_reporte |
| Jueves 08:00 UTC | generar_reporte |
Operación objetivo (Fase 4-5, no construido)¶
| Cuándo | Qué correría |
|---|---|
| Diario 07:00 UTC | extraer_documentos, puntuar |
| Diario 07:30 UTC | Evaluación de alertas por ventana corta |
| Lunes 06:00 UTC | diff_proyectos |
Por qué la ingesta es diaria y el reporte no
Si solo buscamos cuando reportamos, ampliamos la ventana y perdemos avisos cortos. Ingesta diaria, reporte dos veces por semana, alerta por evento.
El reporte salió vacío¶
Diagnóstico en orden:
- Revisar la tabla
ingestas: ¿alguna fuente falló o devolvió cero? - Si una fuente devolvió cero varias corridas seguidas → probablemente cambió su contrato. Correr los tests de normalizador contra un payload fresco
- Si todas devolvieron datos pero el reporte está vacío → los filtros duros están descartando de más. Revisar el panel de calibración
Silencio ≠ no hubo avisos
Es el modo de fallo más peligroso del sistema. Una fuente que devuelve cero
silenciosamente parece funcionar. Por eso existe la alerta de ultimo_ok.
Una fuente cambió su contrato¶
- Capturar un payload fresco y guardarlo como fixture nuevo en
tests/fixtures/<fuente>/<fecha>.json - No borrar el fixture viejo. El histórico guardado en
crudotiene la forma antigua y el normalizador debe seguir manejándola - Actualizar el normalizador para manejar ambas formas
- Correr
renormalizar --fuente=<x>sobre el histórico - Verificar que el conteo de registros no cambió inesperadamente
Ingesta manual / re-ingesta¶
python manage.py ejecutar_ingesta --fuente-id=<id>
Idempotente por fuente_id + id_nativo. Sin --fuente-id corre todas las fuentes activas.
No hay backfill por ventana de fechas todavía
ejecutar_ingesta no acepta --desde/--hasta. Descarga lo que el endpoint devuelva
con los params fijos guardados en el registro Fuente (ver seed_fuentes.py). Un
backfill real requiere editar esos params a mano o ampliarlos en código.
Ojo con las cuotas: SAM.gov e IATI tienen límites duros (fuentes aún no dadas de alta,
ver fases.md Fase 6). Revisar la página de la fuente antes de ampliar rows.
Reprocesar tras mejorar un normalizador¶
python manage.py renormalizar
Sin argumentos: reprocesa todos los avisos con crudo guardado, no admite filtrar por
--fuente. No vuelve a descargar.
puntuar (scoring LLM) es Fase 5, no existe todavía.
Antes de firmar con un socio o prime¶
Comando pendiente de construir (Fase 3)
check_debarment no existe como comando de gestión. Hoy es una consulta SQL manual
contra el dataset de sancionados del BID — ver
docs/inteligencia/fuentes/bid.md. Un socio inhabilitado
nos contamina en todo el sistema multilateral (inhabilitación cruzada Banco Mundial,
BAD, BAfD y BERD). No saltarse este paso solo porque el comando no esté listo.
Revisión trimestral¶
- Muestra manual de descartes automáticos: ¿los filtros duros se están equivocando en silencio?
- Auditoría de recall: consultar adjudicaciones AR IV y contar cuántas de nuestro nicho el sistema nunca vio
- Medir la mediana de días entre primera detección y fecha límite. Debe crecer
- Revisar Pendientes de verificación: ¿qué se confirmó, qué sigue abierto?