# Parte 6 — Catálogo consolidado de indicadores

> 147 indicadores con fórmula concreta, fuente exacta y semáforo de factibilidad.
> 🟢 calculable hoy · 🟡 requiere transformación, universo unificado o advertencia de calidad · 🔴 requiere instrumentación nueva
>
> Convención de alias: `C` = `citas`, `CC` = `citas_canceladas`, `A` = `agendas`, `AR` = `agendas_recursos`, `AB` = `agendas_bloqueo`, `CL` = `clientes`, `AC` = `activos`, `GCH` = `guacamole_connection_history`.
> **Universo de reservas (regla transversal):** salvo indicación contraria, todo KPI de reservas debe calcularse sobre `C ∪ CC`. Usar sólo `C` subcuenta en silencio.

---

## A. Demanda y volumen (18)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| A01 | Solicitudes totales | `COUNT(C.Id) + COUNT(CC.Id)` en el periodo | 🟡 | DB-01, DB-26 |
| A02 | Franjas reservadas | `COUNT(*)` sobre `C ∪ CC` (grano nativo) | 🟢 | DB-01 |
| A03 | **Solicitudes reales (no franjas)** | requiere `C.IdSolicitud` | 🔴 | DB-01 |
| A04 | Horas solicitadas | `SUM(TIMESTAMPDIFF(MINUTE,HoraInicio,HoraFin))/60` | 🟢 | DB-02, DB-03 |
| A05 | **Personas-hora atendidas** | `SUM(C.CupoConsumido × minutos)/60` con `Estado IN (1,3)` | 🟡 | DB-01, DB-10 |
| A06 | Reservas por sede | `GROUP BY A.Sede` (excluye reservas de activo con `IdAgenda=0`) | 🟡 | DB-10 |
| A07 | Reservas por categoría de espacio | `GROUP BY A.IdCategoria` | 🟢 | DB-02, DB-03 |
| A08 | Reservas por área / facultad | `LEFT JOIN areas_universitarias` — hoy **16/16 huérfanas** | 🔴 | DB-08 |
| A09 | Reservas por programa académico | `GROUP BY CL.Programa` (texto libre, cardinalidad ≈1:1) | 🔴 | DB-09 |
| A10 | Reservas por tipo de vínculo | `GROUP BY CL.Tipo` — dato disponible, **hoy sin usar en ninguna gráfica** | 🟢 | DB-21, DB-22 |
| A11 | **Reservas por canal de origen** | requiere promover `InformacionAdicional.__origen` a columna | 🔴 | DB-20, DB-26 |
| A12 | % de demanda en autoservicio | A11 filtrado a portal / total | 🔴 | DB-20 |
| A13 | Reservas por tipo de recurso | `GROUP BY C.TipoReserva` (normalizar las 3 filas con `''`) | 🟡 | DB-04 |
| A14 | **Demanda recurrente vs. espontánea** | requiere `C.IdRecurrencia` (**tabla inexistente**) | 🔴 | DB-22, DB-27 |
| A15 | Antelación media de reserva | `AVG(TIMESTAMPDIFF(HOUR, C.FechaRegistro, TIMESTAMP(C.Fecha,C.HoraInicio)))` | 🟡 | DB-13, DB-23 |
| A16 | Distribución de antelación en buckets | `CASE` sobre A15: <24 h / 1-3 d / 4-7 d / >7 d | 🟡 | DB-23 |
| A17 | **Demanda insatisfecha** | intentos rechazados + lista de espera — **no se persiste nada** | 🔴 | DB-12 |
| A18 | Índice de presión por franja | solicitudes (incl. rechazadas) / cupos ofertados | 🔴 | DB-12, DB-17 |

## B. Conversión y aprobación (12)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| B01 | Tasa de aprobación | aprobadas / (aprobadas + negadas reales), sobre `C ∪ CC` | 🟡 | DB-14 |
| B02 | **Tasa de rechazo real** | `Estado=5 AND NegadoPorUserId IS NOT NULL` / solicitudes que requerían aprobación | 🟡 | DB-14 |
| B03 | **Tasa de expiración por no-decisión** | `Estado=5 AND NegadoPorUserId IS NULL` / `Estado=5` — mide incumplimiento del equipo | 🟡 | DB-14, DB-19 |
| B04 | Tiempo medio de decisión (h) | `AVG(TIMESTAMPDIFF(MINUTE, FechaRegistro, COALESCE(AprobadoFecha,NegadoFecha)))/60` con decisión humana | 🟢 | DB-19, DB-20 |
| B05 | p95 del tiempo de decisión | `ROW_NUMBER()` sobre la duración ordenada | 🟢 | DB-19 |
| B06 | % de cumplimiento del SLA de aprobación | decisiones dentro del umbral / total. **Umbral hardcodeado en 4 h** | 🟡 | DB-19, DB-20 |
| B07 | Backlog de aprobaciones pendientes | `COUNT(Estado=0 AND TIMESTAMP(Fecha,HoraInicio) > NOW())` | 🟢 | DB-19 |
| B08 | **Antigüedad media del backlog (h)** | `AVG(TIMESTAMPDIFF(HOUR, FechaRegistro, NOW()))` sobre `Estado=0` | 🟢 | DB-19 |
| B09 | Pendientes en riesgo (<24 h de su franja) | `Estado=0 AND TIMESTAMP(Fecha,HoraInicio) < NOW()+INTERVAL 24 HOUR` | 🟢 | DB-19 |
| B10 | Decisiones por operador | `GROUP BY AprobadoPorUserId / NegadoPorUserId` | 🟡 | DB-20 |
| B11 | Tasa de conversión del embudo del portal | reservas / sesiones de portal — **no existe registro de login de clientes** | 🔴 | DB-01 |
| B12 | Conversión de lista de espera | `Estado=2 / (2+4)` — **estructuralmente 0: falta la acción de reclamar** | 🔴 | DB-12 |

## C. Asistencia, no-show y puntualidad (12)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| C01 | **Tasa de no-show** | `SUM(Estado=4) / SUM(Estado IN (1,3,4))` — **requiere que el cron corra** | 🟡 | DB-01, DB-02 |
| C02 | No-show por espacio | C01 `GROUP BY IdAgenda` | 🟡 | DB-02, DB-03 |
| C03 | No-show por franja y día | C01 `GROUP BY DAYOFWEEK, HoraInicio` | 🟡 | DB-06, DB-17 |
| C04 | No-show por tipo de vínculo y programa | C01 `GROUP BY CL.Tipo, CL.Programa` | 🟡 | DB-21, DB-22 |
| C05 | Horas desperdiciadas por no-show | `SUM(minutos)/60` sobre `Estado=4` | 🟡 | DB-01, DB-19 |
| C06 | Reincidentes de no-show | clientes con `COUNT(Estado=4) >= 2` | 🟡 | DB-21 |
| C07 | **No-show automático vs. detectado por staff** | `ComentariosEntrega LIKE '%Auto-marcada%'` / total `Estado=4` | 🟡 | DB-19, DB-20 |
| C08 | Clientes auto-bloqueados por inasistencia | `clientes_bloqueos WHERE Tipo='no_show'` | 🔴 | DB-21 |
| C09 | **Efectividad de la sanción** | no-show del cliente antes vs. después del bloqueo | 🔴 | DB-21 |
| C10 | **Tasa de check-in** | check-ins / confirmadas — **el concepto no existe** | 🔴 | DB-19 |
| C11 | **Puntualidad de llegada (min de retraso)** | `AVG(TIMESTAMPDIFF(MINUTE,HoraInicio,HoraEntrega))` — **inválido**: en préstamo y práctica libre `HoraEntrega := HoraInicio` por construcción | 🔴 | DB-19 |
| C12 | Llegadas tardías fuera de tolerancia | requiere check-in + `A.TiempoLlegadaTarde` (**hoy nunca se evalúa**) | 🔴 | DB-19 |

## D. Ocupación y capacidad (16)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| D01 | Horas reservadas por espacio | `SUM(minutos)/60` con `Estado IN (1,3)` | 🟢 | DB-02, DB-03 |
| D02 | **Horas ofertadas** | expandir `A.Horario*` (JSON) × días operativos | 🔴 | DB-11, DB-12 |
| D03 | Horas bloqueadas | `AB` con `TIMESTAMPDIFF` sobre fecha+hora compuestas | 🟡 | DB-02 |
| D04 | **% de ocupación real** | D01 / (D02 − D03) | 🔴 | DB-02, DB-03, DB-06 |
| D05 | **Horas realmente usadas** | `SUM(TIMESTAMPDIFF(MINUTE,HoraEntrega,HoraDevolucion))/60` con `EstadoEntrega=2` — cobertura ~22 % | 🔴 | DB-02, DB-19 |
| D06 | **Ratio uso real / programado** | D05 / D01 sobre el subconjunto con devolución (sesgo de selección severo) | 🔴 | DB-01, DB-02 |
| D07 | **Horas desperdiciadas totales** | no-show + cancelación tardía + reservado-no-usado | 🔴 | DB-01 |
| D08 | Ocupación por franja de 30 min | reservas solapando el slot / cupos del slot | 🟡 | DB-06, DB-17 |
| D09 | **Concurrencia máxima** | barrido de eventos `+1`/`−1` sobre inicio/fin | 🟡 | DB-17, RM-02 |
| D10 | **% de aforo aprovechado** | asistentes reales / `A.CapacidadPersonas` — **`citas` no guarda asistentes** | 🔴 | DB-03 |
| D11 | **Índice de sobredimensión** | espacios con aforo aprovechado <30 % ponderado por capacidad | 🔴 | DB-03, DB-11 |
| D12 | Espacios activos | `A WHERE Estado=1` | 🟢 | DB-11 |
| D13 | Cupo instalado por franja | `min(A.Cupos, COUNT(AR WHERE Estado=1))` | 🟢 | DB-11 |
| D14 | Puestos totales instalados | `SUM(A.CapacidadPersonas)` | 🟢 | DB-11 |
| D15 | Capacidad por edificio y piso | **no existen las tablas** | 🔴 | DB-11 |
| D16 | Densidad puestos/m² | **no existe ningún campo de superficie** | 🔴 | DB-11 |

## E. Cancelación (12)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| E01 | **Tasa de cancelación real** | `COUNT(CC.Id) / (COUNT(C.Id)+COUNT(CC.Id))` — los KPIs actuales usan `C.Estado=2` y **reportan ~0 %** | 🟡 | DB-01, DB-13 |
| E02 | Cancelaciones por canal | `GROUP BY CC.CanceladaPorCanal` (único catálogo cerrado confiable) | 🟢 | DB-13 |
| E03 | Antelación de cancelación (h) | `TIMESTAMPDIFF(HOUR, CC.CanceladaFecha, TIMESTAMP(CC.Fecha,CC.HoraInicio))` | 🟢 | DB-13 |
| E04 | Distribución en buckets de antelación | Tardía <2 h / Mismo día <24 h / Anticipada ≥24 h | 🟢 | DB-13 |
| E05 | **Cumplimiento de la ventana de cancelación** | E03 vs. `A.DiasCancelar×24 + A.HorasCancelar` | 🟡 | DB-13, DB-19 |
| E06 | Horas liberadas por cancelación | `SUM(minutos)/60` sobre `CC` | 🟢 | DB-13 |
| E07 | **% de horas liberadas re-reservadas** | nueva reserva del mismo recurso y franja tras `CanceladaFecha` | 🟡 | DB-13 |
| E08 | Cancelación de confirmadas vs. abandono de pre-reserva | `CC.EstadoOriginal=1` / total `CC` | 🟢 | DB-13 |
| E09 | **Cancelaciones post-entrega (anomalía)** | `CC.EstadoEntrega IN (1,2)` — debería ser ~0 | 🟢 | DB-13, DB-19 |
| E10 | Cancelaciones por motivo tipificado | **`CanceladaMotivo` es texto libre autorrellenado** | 🔴 | DB-13 |
| E11 | % de cancelaciones sin motivo declarado | proporción con el literal autogenerado — **el hallazgo principal** | 🟡 | DB-13 |
| E12 | **Tasa de reagendamiento vs. cancelación neta** | el concepto de reagendar no existe | 🔴 | DB-13, DB-26 |

## F. Equipos, activos e inventario (18)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| F01 | Unidades de inventario activas | `COUNT(AR WHERE Estado=1)` = 55 de 59 | 🟢 | DB-11 |
| F02 | Tasa de indisponibilidad de inventario | `1 − SUM(Estado=1)/COUNT(*)` = 6,8 % | 🟢 | DB-16 |
| F03 | Horas **agendadas** por unidad | `getRecursosUso`: `SUM(minutos)/60 GROUP BY IdAgendaRecurso` | 🟢 | DB-15 |
| F04 | **Horas reales de uso por equipo** | requiere `datetime` en entrega/devolución y granularidad por activo | 🔴 | DB-04, DB-15 |
| F05 | Sesiones por equipo | `COUNT GROUP BY IdAgendaRecurso` | 🟢 | DB-15 |
| F06 | Frecuencia semanal de asignación | sesiones / semanas del periodo | 🟢 | DB-15 |
| F07 | Días sin uso por equipo | `DATEDIFF(CURDATE(), MAX(C.Fecha))` | 🟢 | DB-16 |
| F08 | **Equipos nunca usados en el periodo** | `LEFT JOIN ... WHERE C.Id IS NULL` | 🟢 | DB-16 |
| F09 | **Índice de Gini del uso del parque** | Lorenz sobre horas por equipo (en producción: 10 de 764 con el 80 %) | 🟡 | DB-04, IA-04 |
| F10 | Equipos con >150 % del uso medio | comparación contra la media del laboratorio | 🟢 | DB-15 |
| F11 | Parque total por tipo y sede | `activos` (**0 filas**) | 🔴 | DB-11 |
| F12 | Valor total del parque | `SUM(AC.Valor)` | 🔴 | DB-11, DB-16 |
| F13 | Valor inmovilizado | `SUM(AC.Valor)` con `Estado IN (0,3)` | 🔴 | DB-16 |
| F14 | **Valor de equipos ociosos** | F12 restringido a F08 | 🔴 | DB-16 |
| F15 | Antigüedad media del parque | requiere `FechaCompra` | 🔴 | DB-11 |
| F16 | % con vida útil vencida | requiere `VidaUtilMeses` | 🔴 | DB-11 |
| F17 | Cobertura de garantía vigente | requiere `FinGarantia` | 🔴 | DB-11 |
| F18 | **Coste por hora de uso** | (valor / vida útil) ÷ horas usadas | 🔴 | DB-04 |

## G. Préstamos, mantenimiento y disponibilidad (10)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| G01 | **Préstamos abiertos vencidos** | `Estado=1 AND EstadoEntrega=1 AND TIMESTAMP(Fecha,HoraFin) < NOW()` — 4 casos vivos, algunos de hace un mes | 🟢 | DB-04, DB-19 |
| G02 | Duración media de préstamo inmediato | `AVG(TIMESTAMPDIFF(MINUTE,HoraEntrega,HoraDevolucion))` — **sólo intra-día** y el reporte actual filtra por bandera de agenda, no por origen real | 🟡 | DB-04 |
| G03 | **Tasa de devolución tardía** | devolución real vs. compromiso — **imposible con `time` sin fecha** (en producción: 50,1 %) | 🔴 | DB-19 |
| G04 | Minutos medios de retraso en devolución | ídem (en producción: 1.985 min = 33 h) | 🔴 | DB-19 |
| G05 | **% de disponibilidad técnica (uptime)** | requiere `equipos_sondeos` + cron | 🔴 | RM-04, DB-25 |
| G06 | **MTTR** | `AVG(FechaFin − FechaInicio)` de órdenes correctivas | 🔴 | DB-25 |
| G07 | **MTBF** | tiempo operativo acumulado / nº de correctivas | 🔴 | DB-25 |
| G08 | Downtime en horas y su coste | suma de intervalos en estado no operativo | 🔴 | DB-25 |
| G09 | % de cumplimiento del preventivo | ejecutados / programados | 🔴 | DB-25 |
| G10 | Tasa de pérdida y de daño | requiere condición estructurada al recibir (en producción: 226 daños, 101 no devueltos, en texto libre) | 🔴 | DB-24, DB-25 |

## H. Escritorio remoto (22)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| H01 | Sesiones remotas totales | `COUNT(GCH)` en el rango | 🟡 | RM-01 |
| H02 | Sesiones por día | `COUNT GROUP BY DATE(start_date)` con eje denso | 🟡 | RM-01 |
| H03 | Sesiones cerradas vs. en curso | `end_date IS NULL` | 🟡 | RM-01 |
| H04 | Horas de uso remoto | `SUM(TIMESTAMPDIFF(SECOND,start,end))/3600` sólo cerradas | 🟡 | RM-01, DB-05 |
| H05 | Duración media / p50 / p95 | media y `ROW_NUMBER()` para percentiles | 🟡 | RM-01 |
| H06 | Distribución de duración en 6 buckets | ya implementado en `GuacHistorialStats` | 🟡 | RM-01 |
| H07 | **% de rebotes (<60 s)** | el mejor proxy de fallo con el esquema estándar | 🟡 | RM-01, RM-05 |
| H08 | Usuarios únicos remotos | `COUNT(DISTINCT username)` — **hoy siempre 1: `guacadmin`** | 🔴 | RM-01 |
| H09 | Nuevos vs. recurrentes | `MIN(start_date)` por usuario | 🔴 | RM-01 |
| H10 | **Concurrencia máxima y hora del pico** | barrido de eventos; **sanear `end_date` NULL primero** | 🟡 | RM-02 |
| H11 | Concurrencia por franja de 15 min | slots × solapamiento, precalculado | 🟡 | RM-02 |
| H12 | % de tiempo en tope de capacidad | H11 vs. `guacamole_connection.max_connections` | 🟡 | RM-02 |
| H13 | Sesiones y horas por equipo | `GROUP BY connection_id` (no por nombre) | 🟡 | RM-03 |
| H14 | Sesiones por laboratorio virtual | `connection.parent_id` con CTE recursivo | 🟡 | RM-03 |
| H15 | Días sin uso / conexiones nunca usadas | `MAX(start_date)` y `LEFT JOIN ... IS NULL` | 🟡 | RM-03 |
| H16 | Mix de protocolos | `connection.protocol` — dato ya cargado, **no graficado** | 🟢 | RM-03 |
| H17 | **Cobertura del mapeo equipo↔conexión** | `AR` con `CodigoGuacamole` válido / total — **hoy 6,8 %** | 🟢 | RM-03, DB-11 |
| H18 | % de sesiones fuera del campus | `remote_host` vs. rangos institucionales | 🔴 | RM-06, RM-07 |
| H19 | **Tasa de éxito de conexión** | requiere `fct_intento_conexion` | 🔴 | RM-05 |
| H20 | **Aprovechamiento de la reserva remota** | reservas remotas que terminaron en sesión real | 🔴 | RM-06, DB-05 |
| H21 | Uso remoto por programa / tipo de usuario | requiere atribución de persona | 🔴 | DB-09, RM-06 |
| H22 | **Sesiones huérfanas** | `end_date IS NULL AND start_date < NOW()−6 h` — indicador de salud del dato | 🟡 | RM-08 |

## I. Población, equidad y adopción (12)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| I01 | Clientes activos por tipo de vínculo | `GROUP BY CL.Tipo` | 🟢 | DB-21 |
| I02 | Clientes únicos atendidos | `COUNT(DISTINCT IdCliente)` — **`Documento` no es único y 12 % de reservas sin cliente** | 🟡 | DB-01, DB-21 |
| I03 | **Cobertura poblacional** | I02 / matriculados (parámetro externo inexistente) | 🔴 | DB-01, DB-08 |
| I04 | Distribución de intensidad de uso | 1 / 2-5 / 6-20 / +20 usos (en producción: **54,2 % con un solo uso**) | 🟡 | DB-21 |
| I05 | Tasa de retorno | clientes con ≥2 usos / total | 🟡 | DB-21 |
| I06 | **Retención por cohorte** | requiere fecha de vinculación (**no existe**) | 🔴 | DB-21 |
| I07 | Horas por estudiante (media/p95) | horas / clientes únicos con `CL.Tipo='Estudiante'` | 🟡 | DB-21 |
| I08 | Horas por docente | ídem con `CL.Tipo='Docente'` | 🟡 | DB-22 |
| I09 | Consumo académico vs. administrativo | requiere separar las 3 semánticas de `CL.Programa` | 🔴 | DB-23 |
| I10 | **Equidad de acceso entre facultades** | Gini de horas por facultad ponderado por población | 🔴 | DB-08 |
| I11 | Clientes sancionados vigentes | `clientes_bloqueos WHERE Activo=1 AND (Vencimiento IS NULL OR >= NOW())` — el filtro por `Activo=1` a secas está **inflado** | 🔴 | DB-21 |
| I12 | **Clientes a un no-show del bloqueo** | `countRecentNoShows` = umbral − 1 | 🟡 | IA-07, DB-21 |

## J. Comunicación y alertas (6)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| J01 | Correos encolados / enviados / fallidos | `GROUP BY alertas_email.EstadoEnvio` | 🟢 | DB-19, O2 |
| J02 | **Antigüedad del correo más viejo en cola** | `MAX(NOW() − FechaRegistro)` con `EstadoEnvio=1` — hoy revela 19 correos varados | 🟢 | O2 |
| J03 | Volumen por plantilla | `GROUP BY Plantilla` — **`varchar(15)` trunca `res_aprobada_sol`** | 🟡 | DB-19 |
| J04 | **% de reservas efectivamente notificadas** | `alertas_email` **no tiene `IdCita`** | 🔴 | DB-19 |
| J05 | Latencia de la cola de correo | no hay columna de fecha de envío | 🔴 | O2 |
| J06 | Tasa de acción sobre alertas | requiere el motor de reglas y el registro de acción | 🔴 | IA-07 |

## K. Operación, calidad de dato y gobierno (9)

| # | KPI | Fórmula / fuente | Fact. | Dashboard |
|---|---|---|---|---|
| K01 | **Adherencia al proceso** | `Estado=3 AND EstadoEntrega=0` / `Estado=3` — hoy **5 de 7 (71 %) se cierran sin trazabilidad logística** | 🟢 | DB-19 |
| K02 | % de reservas sin cliente vinculado | `IdCliente IS NULL OR =0` — hoy ~12 % | 🟢 | DB-19 |
| K03 | % de reservas sin código de reserva | `CodigoQr IS NULL` — hoy **68 %**: el código no sirve como identificador operativo | 🟢 | DB-19 |
| K04 | Registros huérfanos por dimensión | `LEFT JOIN ... IS NULL` por cada FK lógica | 🟢 | DB-19 |
| K05 | **Índice de salud del dato** | media ponderada de K01–K04 | 🟢 | DB-01 |
| K06 | Productividad: personas-hora / hora-hombre | A05 / horas de operación del equipo | 🔴 | DB-20 |
| K07 | Adopción por módulo del sistema | `log_urls.Modulo` — **0 filas** | 🔴 | O2 |
| K08 | DAU / WAU / MAU del backoffice | `log_acceso Accion=1` — 3 filas, y `CierreSesion` NULL al 100 % | 🔴 | O2 |
| K09 | **Consumo y adopción del asistente IA** | `asistente_ia_conversaciones.TokensEntrada/Salida`, `_mensajes.Herramientas`, y **tasa de confirmación** de `_acciones` | 🟢 | IA-08 |

---

## Resumen de factibilidad

| Dominio | Total | 🟢 | 🟡 | 🔴 |
|---|---|---|---|---|
| A. Demanda y volumen | 18 | 4 | 6 | 8 |
| B. Conversión y aprobación | 12 | 5 | 5 | 2 |
| C. Asistencia y no-show | 12 | 0 | 7 | 5 |
| D. Ocupación y capacidad | 16 | 4 | 3 | 9 |
| E. Cancelación | 12 | 6 | 4 | 2 |
| F. Equipos e inventario | 18 | 8 | 1 | 9 |
| G. Préstamos y mantenimiento | 10 | 1 | 1 | 8 |
| H. Escritorio remoto | 22 | 2 | 14 | 6 |
| I. Población y equidad | 12 | 1 | 6 | 5 |
| J. Comunicación | 6 | 2 | 1 | 3 |
| K. Operación y gobierno | 9 | 6 | 0 | 3 |
| **Total** | **147** | **39** | **48** | **60** |

### Lectura de estos números

**39 indicadores están disponibles hoy** y ninguno de ellos se está publicando como KPI con umbral y alerta. Entre ellos hay hallazgos incómodos y valiosos que se calculan con una consulta: el 71 % de adherencia al proceso, el 68 % de reservas sin código, los 19 correos varados, los 4 préstamos vencidos, la cobertura del 6,8 % del mapeo remoto, y el consumo real del asistente IA.

**48 están a una transformación de distancia** — casi todos dependen de tres cosas: unificar el universo de reservas, que el cron corra, y definir la dimensión de franja por rangos.

**60 requieren instrumentación**, pero no 60 desarrollos distintos: **los cinco habilitadores de la Parte 7 cubren 41 de ellos**. La concentración es la buena noticia de esta auditoría.

### Los 12 indicadores que se publicarían primero

Si sólo se pudiera instrumentar un tablero, este sería su contenido: es el conjunto con mejor relación entre valor de decisión y disponibilidad inmediata.

| Prioridad | KPI | Por qué |
|---|---|---|
| 1 | A05 Personas-hora atendidas | Es la métrica de servicio; hoy se cuentan transacciones |
| 2 | E01 Tasa de cancelación real | Corrige el defecto de reporting más grave |
| 3 | C01 Tasa de no-show | El mejor KPI del sistema; sólo necesita el cron |
| 4 | B08 Antigüedad del backlog | Anticipa el problema en lugar de describirlo |
| 5 | B03 Expiración por no-decisión | Mide a la administración, no al usuario |
| 6 | G01 Préstamos abiertos vencidos | Riesgo patrimonial inmediato, hoy sólo en un log |
| 7 | F08 Equipos nunca usados | Capital ocioso recuperable, cálculo trivial |
| 8 | F09 Gini del uso del parque | El hallazgo de producción más contundente |
| 9 | K05 Índice de salud del dato | Sin esto, todo lo demás es opinable |
| 10 | J02 Antigüedad del correo en cola | Detecta el sistema congelado |
| 11 | E09 Cancelaciones post-entrega | Detecta uso indebido del borrado administrativo |
| 12 | H17 Cobertura del mapeo remoto | Coste cero, y condiciona todo el módulo remoto |

---

*Continúa en la [Parte 7 — Brechas y habilitadores](07_BRECHAS_Y_HABILITADORES.md).*
