Responde: para cada objetivo comprometido, ¿qué lo implementa, qué decisión lo respalda y qué
lo verifica?
Es el artefacto que busca un tribunal: la cadena que conecta lo que se prometió con lo que se
puede mostrar. Cada fila es rastreable hasta un archivo de un repositorio, fijado por commit.
La cadena de trazabilidad está completa desde el 2026-10-14
La forma ideal de esta matriz es objetivo → caso de uso o historia → requisito → decisión →
PR o release → prueba. Hasta el 2026-10-14 faltaban dos eslabones. Los dos se cerraron ese
día:
Eslabón
Cómo se cerró
Historias de usuario (US-0xx)
El enunciado completo de las veinte apareció en el anexo del Informe de Avance 1, entregado el 2025-08-20. No son reconstrucciones derivadas del código: son el texto original con sus criterios de aceptación. Ver historias de usuario
Release
Los cinco repositorios no tenían tags —no cuatro, como decía esta página—. Se fijó v1.0.0-rc1 sobre los commits que estaban efectivamente desplegados en producción. Ver releases
La matriz se construye entonces sobre la cadena completa. Donde una verificación no existe se
dice, en lugar de inventarla: esa severidad no cambia.
Parcial: hay implementación, con una limitación declarada
✗
No implementado
La columna Verificación es la más severa a propósito: dice qué prueba automatizada cubre el
objetivo, no qué se probó a mano alguna vez. Lo que se prueba fuera del CI, con fecha y
versión, se registra en evidencias de pruebas integrales.
✅ La mejor del sistema: el CI del historian levanta una InfluxDB real, corre el componente contra ella y verifica por consulta que los puntos llegaron. El CI del Edge compila para arm64 y corre sus tests unitarios
Limitación
Nunca corrió en una Raspberry Pi real: el stack se verificó en amd64
Existe el modelo de datos de reglas y notificaciones, su API y su interfaz. No existe código que evalúe las reglas
Evidencia
internal/api/handler/alarm_rules/ e internal/app/alarm_rules/ del Cloud: son CRUD. No hay módulo de evaluación
Decisión
FE-ADR-014 (2026-10-04, cátedra y equipo): el módulo no se expone en el MVP y el objetivo se declara no alcanzado. SYS-ADR-007 acota qué puede hacer una alarma —notificar, nunca actuar sobre la máquina—; FE-ADR-014 explica su ausencia
Verificación
—
Limitación
Es el único de los diez objetivos sin cumplir, y ahora está declarado como tal, no pendiente de decisión. La interfaz lo marca: ítem «Alertas» deshabilitado con cartel «Pendiente», campana oculta. Ver bitácora de alcance
Objetivo 6 — Estructurar los datos para análisis e inteligencia de negocio¶
Estado
✅
Implementación
Semántica del estándar AAS de punta a punta: el aasPath identifica cada variable en los cuatro repositorios y se persiste con cada medición
⚠️ El aislamiento entre clientes no tiene prueba automatizada contra una base real. Lo impone el código: el backend conecta con un rol que bypassea el control por fila
⚠️ El índice único que sostiene toda la idempotencia no se verifica en CI
Limitación
La calidad del dato no viaja: una lectura fallida es indistinguible de una máquina detenida. Y los logs de la Pi rotan, así que un incidente de ayer no se puede investigar
Identidad delegada con verificación de firma contra claves públicas; patrón BFF; claves de dispositivo hasheadas con comparación en tiempo constante; permisos por rol desde la base
Evidencia
Seguridad — el modelo completo y sus cinco debilidades verificadas
Decisión
SYS-ADR-005 · CLOUD-ADR-002 y -015 · FE-ADR-002 a -004, -008
Verificación
⚠️ Tests unitarios. Nada verifica el aislamiento ni los controles contra una base real
Limitación
Cinco debilidades sin corregir, de las cuales la más seria es que el aislamiento entre clientes depende del código. El cifrado en tránsito depende del despliegue, no del código
Objetivo 10 — Entorno visual interactivo de análisis y seguimiento¶
Estado
✅
Implementación
Dashboard con disposiciones configurables y persistidas por cliente, catálogo de widgets y alta desde la interfaz
Evidencia
src/lib/widget-registry.ts y la API de disposiciones del Cloud
Decisión
FE-ADR-001
Verificación
⚠️ E2E con Playwright que no bloquean el despliegue
Limitación
Los informes que el anteproyecto lista como componente del alcance no existen: no hay servicio de reportes
1 · Nueve de diez objetivos tienen implementación; casi ninguno tiene verificación automatizada¶
De los diez objetivos, uno solo tiene una prueba de integración real que lo respalde: el
objetivo 2, gracias al CI del componente externo. Los demás se apoyan en tests unitarios, en
pruebas que no bloquean el despliegue, o en nada.
Es la brecha más importante del proyecto desde el punto de vista de la defensa: "está
implementado" y "está verificado" no son lo mismo, y la matriz lo hace visible.
2 · El control que debía proteger el objetivo 6 no detecta el defecto que existe¶
!!! danger "La validación de aasPath del frontend pasó una semana en verde sobre 3 literales
rotos"
Corregido el 2026-10-07 — el cierre está al final de esta admonición. El hallazgo se
conserva porque es uno de los resultados del trabajo de reconciliación, y porque la forma
del error es más instructiva que el error.
`FE-ADR-010` decidió, el 2026-09-30, validar cada `aasPath` del dashboard contra el catálogo
canónico del historian, fijado a un tag. El script existe y corre en el CI.
**Verificado ejecutándolo**: devuelve
`aaspath-check OK — 14 aasPath (10 distintos) existen en el catálogo canónico` y sale con
código 0.
Pero 3 de esos 14 literales **nunca van a devolver datos**, porque el Edge escribe
`Alarmas//paradaEmergencia` —con el segmento de colección vacío— y el dashboard pide
`Alarmas/paradaEmergencia`.
La causa está en cómo el script compone las rutas del catálogo: omite el segmento vacío,
que es la convención del **frontend**, no la del **Edge**. Su propio comentario lo dice:
*"la misma forma que usa widget-registry"*. Así que el control **compara el frontend contra
sí mismo**, y confirma que es internamente coherente — mientras que lo único que importa es
lo que el Edge efectivamente escribe, porque el Cloud compara por igualdad exacta.
No es un reproche al control: su diseño es correcto y su ADR descarta bien las
alternativas. Es un **error de un carácter en la composición**, y es justamente el tipo de
cosa que solo se ve mirando los dos repositorios a la vez.
**Cómo se cerró, el 2026-10-07.** Primero la decisión de sistema
([`SYS-ADR-009`](../arquitectura/decisiones/sys-adr-009.md)), que eligió colapsar el
segmento vacío; después el Edge, que lo aplicó (`EDGE-ADR-012`); después el frontend, que
dejó de implementar la regla por su cuenta y pasó a derivarla de un único módulo con test
propio, leyendo el YAML canónico (`FE-ADR-015`, que reemplaza a `FE-ADR-010`). El control
se volvió a ejecutar y pasa —ahora por la razón correcta—. Queda el paso 3: dejarlo
bloqueante en PR.
La decisión que fijó la forma canónica, con los dos caminos analizados y su costo, es
[`SYS-ADR-009`](../arquitectura/decisiones/sys-adr-009.md). Cambia el identificador de los
eventos de alarma ya almacenados, que quedan fuera del alcance de una consulta por la forma
nueva: ver [catálogo de variables](../integraciones/catalogo-variables.md).
3 · Los objetivos cumplidos lo están con una limitación declarada¶
Ninguna fila dice "✅" a secas. Seis tienen limitación explícita, y eso es deliberado: una matriz
donde todo está verde no es creíble y no resiste una pregunta del tribunal. Cada limitación está
documentada en la página que la analiza, no inventada acá.