Descripción General
Motor de Integridad F1 es la primera fase de la Barra de Integridad (Integrity Bar): un sistema que computa automáticamente la clasificación de cada equipo documentado en los racks contra la realidad observada en la LAN del cliente, a través de dos señales independientes:
- DeviceProfile del discovery (qué ve el sensor de red)
- MonitoringTarget del monitoreo (qué dice el agente local)
El motor NUNCA usa solo una métrica de confianza. En su lugar, separa deliberadamente:
fidelity_pct— de lo observable, cuánto cuadra con el plano (máx relevancia para el usuario, mín ruido)coverage_pct— cuánto del plano puede ver el sensor (metadato, importante para detectar puntos ciegos)
Un equipo no observable (sin IP de gestión, sin perfil, sin monitorización) jamás baja la fidelidad: se va a cuarentena (unobservable).
Cronología y Contexto
- Decisión: 2026-07-17 · Converge storm (18 citas verificadas) → roast (RESHAPE de confianza alta)
- Informes: workspace.crearack.com/informes/{storm,roast}/barra-integridad-rack-2026-07-17.html
- Gate de activación: task #202 del Gestor (umbral ≥80% de drifts reales)
- Impacto usuario: NINGUNO todavía — F1 es motor + datos internos
- Próximas fases:
- F2: reconciliación (cola + ITSM)
- F3: UI (radar interno del MSP)
- F4: informe de diligencia
Clasificación por Equipo
Cada dispositivo del plano se clasifica en uno de estos montones:
| Clase | Criterio | Acción |
|---|---|---|
matched_alive | Identidad conocida + evidencia fresca de vida (perfil ≤7d O monitorización up) | OK |
matched_stale | Identidad conocida pero sin evidencia fresca (drift candidato: retirado/apagado/desconectado) | Revisar |
ip_conflict | La identidad no cuadra: perfil en otra IP O IP del plano vinculada a otro equipo | Revisar |
unobservable | Plano sin identidad de red (sin IP, sin perfil, sin monitorización) | Cuarentena (NO baja fidelity) |
A nivel organización, se añade:
| Clase | Criterio | Acción |
|---|---|---|
undocumented | Perfil vivo en la LAN que no está en ningún plano (drift candidato: equipo montado sin documentar) | Revisar |
Componentes del Motor
Servicio racks.services.integrity
Función pública: compute_integrity(organization, fresh_days=7, target_fresh_minutes=30)
- Itera TODOS los racks + dispositivos de la org
- Cruza con DeviceProfile (discovery) + MonitoringTarget (monitoreo)
- Classifica cada equipo con evidencia (IP, hostname, serial, MAC, timestamps)
- Retorna JSON-serializable con racks/summary/undocumented
Función de persistencia: persist_snapshots(organization, result, snapshot_date=None)
- Escribe fotos diarias (una fila/rack + resumen de org con rack=NULL)
- Idempotente por (org, rack, fecha) — update_or_create
- Sin UI → no se expone en API todavía
Modelo RackIntegritySnapshot
class RackIntegritySnapshot(models.Model):
organization = ForeignKey(Organization, CASCADE)
rack = ForeignKey(Rack, CASCADE, null=True, blank=True) # NULL = org-summary
date = DateField()
fidelity_pct = FloatField(null=True, blank=True)
coverage_pct = FloatField(null=True, blank=True)
counts = JSONField(default=dict) # {matched_alive, matched_stale, ...}
findings = JSONField(default=list) # [{device_id, classification, reason, evidence}, ...]
# RLS: patrón core-0029, migraciones 0014+0015
Comando rack_integrity_probe
python manage.py rack_integrity_probe --org 1
python manage.py rack_integrity_probe --org 1 --save # guarda snapshot
python manage.py rack_integrity_probe --org 1 --json # JSON para logs
Salida human-readable con tabla de racks + avisos a revisar (stale/conflict) + vivos sin documentar.
Task Diaria compute_integrity_snapshots
@db_periodic_task(crontab(hour="4", minute="15")) # 04:15 UTC, tras backups
@lock_task("rack-integrity-snapshots")
def compute_integrity_snapshots():
# Itera org.all() con bypass GUC ('0')
# Persiste snapshot para cada org
# Logger: info al terminar
Decisiones de Diseño Clave
1. Dos Métricas Separadas (NO Una Única Confianza)
Problema: Un equipo sin perfil de discovery pero con monitorización “up” parecía 100% confiable. Pero el sensor tal vez nunca lo vió → fidelidad falsa.
Solución RESHAPE (roast 17-07):
fidelity_pct = matched_alive / observable— solo de lo que vemos, cuánto cuadracoverage_pct = observable / total— cuánto del plano podemos ver
Un equipo unobservable contribuye al denominador de coverage, pero NUNCA al numerador de fidelity.
2. Sin Impacto de Usuario (Gate Antes de Exponer)
F1 es puro motor + datos. La UI llega en F2-F4 tras validar que el detector acierta ≥80% (task #202, design partner en sept).
Si exponemos ahora, confundimos al usuario con un beta que no sabemos si funciona → pérdida de confianza.
3. RLS Patrón core-0029
Migraciones 0014 (tabla) + 0015 (política). El scoping manual en Huey (GUC ‘0’ con bypass admin) es idéntico al del resto de tasks de background.
4. Umbrales Ajustables, Pré-Declarados
Los defaults (DEFAULT_FRESH_DAYS=7, DEFAULT_TARGET_FRESH_MINUTES=30) son ajustables por flag de comando. El gate de calibración decide los definitivos, no hardcodeamos.
Límites Honestos
- QUÉ sabe el motor: existencia, vida (up/down), identidad (IP/MAC/serial)
- QUÉ NO sabe: posición física (rack/U) — requiere cruce con plano + auditoría humana
- Punto ciego documentado: una mudanza dentro de la misma red (mismo rack/modelo/IP reasignada) puede NO detectarse; la solución es el asset inventory manual (out-of-scope F1)
Véase también
- [[entity—racks—service—integrity]]
- [[entity—racks—model—rack-integrity-snapshot]]
- [[entity—racks—command—rack-integrity-probe]]
- [[entity—racks—task—compute-integrity-snapshots]]
- [[concept—saas—multi-tenancy]]
- [[decision—20260403—multi-tenancy-rls]]
Referenciado desde
- Barra de Integridad F2: el radar interno plano↔realidad
- Comando rack_integrity_probe — calibración del Motor de Integridad
- Modelo RackIntegritySnapshot — foto diaria de integridad plano↔realidad
- Servicio de Integridad — Motor de clasificación plano↔realidad
- Task Huey compute_integrity_snapshots — automatización diaria del Motor de Integridad