Los lotes del Agente no escribían last_check (v1.61.1)
Los lotes del Agente no escribían last_check (v1.61.1)
Detectado: 2026-07-17 (s229)
Corregido: 2026-07-17 (commit 6d4070d)
Versión: v1.61.1
Impacto: Equipos monitorizados exclusivamente por el Agente Local (toda la LAN) quedaban con last_check NULL, impidiendo que el Motor de Integridad usase la monitorización como evidencia fresca de vida.
Síntesis del problema
Cuando el Agente Local enviaba lotes de métricas al endpoint /api/agent/metrics/bulk:
POST /api/agent/metrics/bulk
{
"agent_id": "agent_a",
"metrics": [
{"timestamp": now, "target_id": 123, "metric_type": "ping_latency", "value": 8.0},
{"timestamp": now, "target_id": 123, "metric_type": "ping_loss", "value": 0.0}
]
}
El sistema guardaba correctamente los valores:
last_latency_ms✅last_packet_loss✅last_status(reachability) ✅last_tcp_up✅
Pero no escribía last_check — ese sello de timestamp solo lo actualizaban:
- El loop server-side (
/api/monitoring/check) - Los chequeos manuales
Consecuencia: Los targets solo-Agente (MonitoringTarget.last_check IS NULL) figuraban como “nunca chequeados” ante cualquier validación de frescura. El Motor de Integridad exige last_check reciente para dar un target por vivo (_target_is_up_fresh), así que ignoraba completamente la monitorización del Agente como evidencia de vida → ruido injusto en la calibración del gate #202.
Dato detectable: Org 1 tenía 131 targets con last_check NULL mientras el Agente reportaba lotes de 1000 métricas regularmente.
Solución
Cambio mínimo en terminal/api/sentinel_ingest.py:
t.last_check = now_dt # Una línea: un lote del Agente ES un chequeo
Dentro del loop de procesamiento de métricas, tras resolver el estado de reachability, se añadió la escritura de last_check. Se incluyó también en bulk_update():
MonitoringTarget.objects.bulk_update(
update_targets,
["last_status", "last_latency_ms", "last_packet_loss", "last_tcp_up", "last_tcp_check", "last_check"],
)
Test nuevo: TestBulkMetricsUpdatesLastCheck en tests/api/test_sentinel.py — verifica que un lote del Agente establece last_check y last_status correctamente.
Impacto
✅ Los targets monitorizados por el Agente ahora tienen last_check fresco
✅ El Motor de Integridad puede usar la monitorización como evidencia de vida
✅ Menos ruido en la calibración de drifts confirmados (gate #202)
✅ Usuarios locales: La “última comprobación” de sus equipos ya no está vacía
Contexto: Por qué pasó desapercibido
El endpoint /api/agent/metrics/bulk se introdujo hace meses sin esta lógica. No había test que forzase last_check a escribirse. Los desarrolladores assumieron que cualquier actualización de métricas “de facto” era un chequeo, pero el código no lo reflejaba. Fue descubierto al validar por qué org 1 reportaba 131 targets con last_check NULL en la auditoría s229.
Versión y Changelog
## [1.61.1] - 2026-07-17 (🩹 Sentinel: los lotes del Agente ya cuentan como chequeo)
### Fixed
- El ingest bulk del Agente (`/api/agent/metrics/bulk`) no escribía `MonitoringTarget.last_check`
Véase también
- [[entity—monitoring—model—monitoring-target]]