🛸 Fase 1.5 completa: AtomicDrones con visibilidad en Bitácora Web

Bugs corregidos (12): B1-B12 — crashes, tipos, métodos, logger
Ejecutor reescrito: evento web → heartbeat 30s → cierre automático
copiloto.rb y novato.rb deprecados → redirigen a dron lanzar
Plan P009 v3.2 — Fase 1.5 100%% completa
This commit is contained in:
Ricardo Monla
2026-04-09 10:12:04 -03:00
parent fb8c8eefe5
commit 6d7394b22e
9 changed files with 415 additions and 147 deletions
@@ -1,10 +1,24 @@
# A01.P009 - Evolución del Ecosistema ADN al Concepto de Dron
> **Estado**: 🟢 En Implementación (Fase 1 completa)
> **Estado**: 🟢 Fase 1.5 completada
> **Pertenece a**: [A01 - Ecosistema ADN](./A01_dtic-ADN.md)
> **Fecha**: 2026-04-07
> **Fecha**: 2026-04-09
> **Responsable**: Lic. Ricardo MONLA
> **Versión**: 2.1 — AtomicDrones implementados
> **Versión**: 3.2 — Fase 1.5 completada, sistema dual eliminado
---
## 📈 Progreso
```
Fase 0: ██████████ 100% Infraestructura de Datos (tablas internas) ✅
Fase 1: ██████████ 100% Atomicidad (bugs corregidos) ✅
Fase 1.5: ██████████ 100% Visibilidad Bitácora Web + Corrección Bugs ✅
Fase 2: ░░░░░░░░░░ 0% Composición — Orquestación de Flujos
Fase 3: ░░░░░░░░░░ 0% Planificación — Drones Programados
Fase 4: ░░░░░░░░░░ 0% Inteligencia de Colmena
Fase 5: ░░░░░░░░░░ 0% Observabilidad — Dashboard y Métricas
```
---
@@ -263,19 +277,20 @@ La **Bitácora Web** (`http://localhost:5174/bitacoras/`) muestra:
---
## 📊 Estado Actual (Línea Base)
## 📊 Estado Actual (Línea Base — Auditoría 2026-04-09)
### Herramientas Existentes
| Herramienta | Ubicación | Tipo | Estado |
|-------------|-----------|------|--------|
| `dron.rb` | `adn/tools/cli/dron.rb` | Dispatcher | ✅ Refactorizado |
| `dron/ejecutor.rb` | `adn/tools/cli/dron/ejecutor.rb` | Ejecutor atómico | ✅ Implementado |
| `dron/vigilante.rb` | `adn/tools/cli/dron/vigilante.rb` | Vigilante atómico | ✅ Implementado |
| `dron/sanador.rb` | `adn/tools/cli/dron/sanador.rb` | Sanador atómico | ✅ Implementado |
| `dron/ejecutor.rb` | `adn/tools/cli/dron/ejecutor.rb` | Ejecutor atómico | ⚠️ Bugs en bitácora web |
| `dron/vigilante.rb` | `adn/tools/cli/dron/vigilante.rb` | Vigilante atómico | ⚠️ Bugs en consolidación |
| `dron/sanador.rb` | `adn/tools/cli/dron/sanador.rb` | Sanador atómico | ⚠️ Bugs en reintentos |
| `dron/bitacora.rb` | `adn/tools/cli/dron/bitacora.rb` | Bitácora atómica | ✅ Implementado |
| `dron/base.rb` | `adn/tools/cli/dron/base.rb` | Módulo compartido | ✅ Implementado |
| `dron_db.rb` | `adn/tools/db/core/dron_db.rb` | Acceso a DB | ✅ Implementado |
| `dron_db.rb` | `adn/tools/db/core/dron_db.rb` | Acceso a DB | ⚠️ 3 bugs críticos |
| `dispatcher.rb` | `adn/tools/cli/dron/dispatcher.rb` | Routing subcomandos | ⚠️ 1 bug crítico |
### Capacidades Actuales
@@ -294,14 +309,64 @@ La **Bitácora Web** (`http://localhost:5174/bitacoras/`) muestra:
./adn/tools/run dron reintentar
```
### Limitaciones Detectadas (Deuda de Atomicidad)
### 🐛 Deuda Técnica Detectada (Auditoría 2026-04-09)
#### Bugs Críticos (crashes directos)
| # | Archivo | Línea | Bug | Impacto |
|---|---------|-------|-----|---------|
| B1 | `dispatcher.rb` | 214 | `BitacorasDB::BitacoraDB.ejecutar()` — método inexistente (debe ser `.with_connection { \|db\| db.execute() }`) | `dron estado <ID>` crashea con NoMethodError |
| B2 | `dron_db.rb` | 178-179 | `incrementar_reintentos` hace doble `.first` (`.first.to_h` → Hash, luego `.first` sobre Hash = par `[k,v]`) | Sanador crashea al reintentar drones |
| B3 | `dron_db.rb` | 231-232 | `obtener_metricas` mismo patrón de doble `.first` | Consulta de métricas crashea |
#### Bugs Medios (fallan en ciertos flujos)
| # | Archivo | Línea | Bug | Impacto |
|---|---------|-------|-----|---------|
| B4 | `dron_db.rb` | 337-345 | `limpiar_antiguos` — DELETE sin RETURNING intenta leer `['count']` inexistente | Limpieza reporta 0 siempre |
| B5 | `dron_db.rb` | 253 | `actualizar_metricas` — pasa Float donde PG espera INTERVAL | Error de tipo al guardar métricas |
| B6 | `sanador.rb` | 27 | `Time.now - dron['completed_at']` — el campo viene como String, no Time | TypeError al calcular backoff |
| B7 | `sanador.rb` | 41 | `Dron::Ejecutor.lanzar(...)` sin `require_relative 'ejecutor'` | NameError si se llama directamente |
#### Bugs Bajos (edge cases)
| # | Archivo | Línea | Bug | Impacto |
|---|---------|-------|-----|---------|
| B8 | `sanador.rb` | 41 | `dron.dig('metadata', 'nota')` — metadata es String JSON, no Hash | Nota de reintento siempre nil |
| B9 | `ejecutor.rb` | 42-75 | Timeout nunca se aplica (falta `Timeout.timeout()` wrapping) | Drones largos nunca se frenan |
| B10 | `vigilante.rb` | 141,143 | `BitacorasDB::BitacoraDB.crear_evento(...)` como método de clase (es de instancia) | Consolidación de flujos falla silenciosamente |
| B11 | `ejecutor.rb` | 82-131 | `registrar_bitacora` con rescue genérico silencia todos los errores | Fallos de bitácora web invisibles |
| B12 | `dron.rb` / `base.rb` | 30 / 27 | Logger: `.instance` (singleton) vs `.new` (instancia separada) | Logs inconsistentes |
### 🔍 Brecha Principal: Visibilidad en Bitácora Web
**Problema crítico**: Los drones escriben en tablas internas (`dron_logs`) pero la **Bitácora Web** (`bitacoras.events`) no refleja su actividad.
```
CAPA 1 (dron_logs) CAPA 2 (events → Web)
┌─────────────────┐ ┌─────────────────┐
│ ✅ Drones │ ──?──→ │ ❌ La web no ve │
│ escriben acá │ │ nada │
└─────────────────┘ └─────────────────┘
La flecha "vigilante consolida"
NO FUNCIONA por bugs B1, B10, B11
```
**Causas raíz:**
1. El heartbeat solo actualiza `dron_logs.heartbeat` (tabla interna), nunca `events`
2. El ejecutor tiene lógica de bitácora web pero falla silenciosamente (B11)
3. El vigilante llama métodos de clase inexistentes (B10)
4. Coexiste un sistema antiguo de scripts `.sh` (que sí funcionaba) con el nuevo Ruby (que no)
### Limitaciones Futuras (post-corrección)
| # | Limitación | Tipo | Impacto | Prioridad |
|---|------------|------|---------|-----------|
| 1 | Sin orquestación de flujos | Orquestador | No hay composición multi-paso | Media |
| 2 | Sin planificación (cron) | Planificador | Requiere lanzamiento manual | Alta |
| 3 | Sin notificaciones | Mensajero | Alertas manuales | Media |
| 4 | Sin dashboard web | Observabilidad | Visibilidad solo por CLI | Baja |
| 4 | Sin dashboard web dedicado | Observabilidad | Solo CLI + Bitácora Web | Baja |
---
@@ -323,20 +388,77 @@ La **Bitácora Web** (`http://localhost:5174/bitacoras/`) muestra:
---
### Fase 1: Atomicidad — Separación de Responsabilidades (Dron 1.0) — COMPLETA
### Fase 1: Atomicidad — Separación de Responsabilidades (Dron 1.0) — ⚠️ CON DEUDA TÉCNICA
**Objetivo:** Refactorizar el monolito `dron.rb` en módulos atómicos especializados.
| ID | Tarea | Tipo de Dron | Estado |
|:--:|-------|--------------|--------|
| F1.T1 | `dron/ejecutor.rb` | Ejecutor — lanza y monitorea comando | ✅ Completa |
| F1.T2 | `dron/vigilante.rb` | Vigilante — escanea flota, detecta zombies | ✅ Completa |
| F1.T3 | `dron/sanador.rb` | Sanador — re-intenta, limpia, notifica fallos | ✅ Completa |
| F1.T1 | `dron/ejecutor.rb` | Ejecutor — lanza y monitorea comando | ⚠️ Bugs B9, B11 |
| F1.T2 | `dron/vigilante.rb` | Vigilante — escanea flota, detecta zombies | ⚠️ Bug B10 |
| F1.T3 | `dron/sanador.rb` | Sanador — re-intenta, limpia, notifica fallos | ⚠️ Bugs B6, B7, B8 |
| F1.T4 | `dron/bitacora.rb` | Registrador — auto-bitácora (inicio/fin) | ✅ Completa |
| F1.T5 | `dron/dispatcher.rb` | Dispatcher — routing de subcomandos | ✅ Completa |
| F1.T5 | `dron/dispatcher.rb` | Dispatcher — routing de subcomandos | ⚠️ Bug B1 |
| F1.T6 | `dron/base.rb` | Módulo compartido (atomisidad) | ✅ Completa |
| F1.T7 | `dron_db.rb` | Capa de datos para drones | ⚠️ Bugs B2, B3, B4, B5 |
**Criterio de éxito:** ✅ Cada módulo tiene una única responsabilidad. ~40% menos código. Atomisidad aplicada.
**Criterio de éxito original:** ✅ Cada módulo tiene una única responsabilidad. ~40% menos código.
**Criterio revisado:** ⚠️ La estructura atómica es correcta pero **12 bugs** impiden operación confiable. Corregidos en Fase 1.5.
---
### Fase 1.5: Visibilidad en Bitácora Web + Corrección de Bugs (Dron 1.1) — ✅ COMPLETA
**Objetivo:** Que los drones sean **visibles desde la Bitácora Web** y corregir toda la deuda técnica de Fase 1.
**Problema que resuelve:** Actualmente los drones son "fantasmas" — ejecutan tareas pero el usuario no puede ver su progreso desde la interfaz web principal. Solo escriben en tablas internas (`dron_logs`) pero nunca actualizan `bitacoras.events` de forma confiable.
**Lo que el usuario debería ver en Bitácora Web:**
```
┌─────┬───────┬───────┬─────────────────────────────────────────────┬───┬───┐
│ ID │ I │ F │ Descripción │ J │ E │
├─────┼───────┼───────┼─────────────────────────────────────────────┼───┼───┤
│1420 │ 02:00 │ │ 🛸 Backup nocturno (dron_020000_123) │ A │ ⏳│
│ │ │ │ ├─ Ejecutando: vzdump 103 --mode stop │ │ │
│ │ │ │ └─ ❤️ Heartbeat: hace 45s │ │ │
├─────┼───────┼───────┼─────────────────────────────────────────────┼───┼───┤
│1419 │ 01:30 │ 01:45 │ 🛸 Sync rclone (dron_013000_456) — ✅ 15m │ A │ ✅│
│ │ │ │ └─ Aterrizaje limpio — 2.3GB sincronizados │ │ │
└─────┴───────┴───────┴─────────────────────────────────────────────┴───┴───┘
```
| ID | Tarea | Descripción | Estado |
|:--:|-------|-------------|--------|
| F1.5.T1 | Corregir bugs críticos | Bugs B1, B2, B3 — crashes directos en dispatcher y dron_db | ✅ |
| F1.5.T2 | Corregir bugs medios | Bugs B4, B5, B6, B7 — fallos en sanador y métricas | ✅ |
| F1.5.T3 | Simplificar `registrar_bitacora` | Reescribir el método del ejecutor: crear evento → heartbeat → cierre limpio | ✅ |
| F1.5.T4 | Heartbeat visible en web | Que el heartbeat cada 30s actualice `events.descripcion` con progreso | ✅ |
| F1.5.T5 | Eliminar sistema dual `.sh`/Ruby | `copiloto.rb` y `novato.rb` deprecados, `tmp/dron/` limpiado | ✅ |
| F1.5.T6 | Corregir bugs bajos | Bugs B8-B12 — edge cases y consistencia | ✅ |
**Flujo corregido del Ejecutor:**
```
Ejecutor.lanzar(cmd, nota)
├─ 1. Registrar en dron_logs (tabla interna) ──→ DronDB
├─ 2. Crear evento en events (Bitácora Web) ──→ 🌐 VISIBLE
├─ 3. Ejecutar comando con heartbeat thread:
│ loop cada 30s:
│ ├─ Actualizar dron_logs.heartbeat ──→ DronDB
│ └─ Actualizar events.descripcion ──→ 🌐 VISIBLE
├─ 4. Comando finaliza
├─ 5. Registrar fin en dron_logs ──→ DronDB
└─ 6. Cerrar evento en events (estado + hora fin) ──→ 🌐 VISIBLE
```
**Criterio de éxito:**
- Cada dron lanzado aparece inmediatamente en la Bitácora Web como evento `⏳`
- El heartbeat actualiza la descripción del evento en web cada 30 segundos
- Al finalizar, el evento se cierra con `✅` o `❌`, hora de fin, y duración
- `dron estado <ID>`, `dron flota`, y `dron salud` funcionan sin crashes
- Cero bugs críticos, cero bugs medios
---
@@ -418,18 +540,6 @@ La **Bitácora Web** (`http://localhost:5174/bitacoras/`) muestra:
---
## 📈 Progreso
```
Fase 0: ██████████ 100% Infraestructura de Datos (tablas internas) ✅
Fase 1: ██████████ 100% Atomicidad — Separación de Responsabilidades (Dron 1.0) ✅
Fase 2: ░░░░░░░░░░ 0% Composición — Orquestación de Flujos (Dron 1.5)
Fase 3: ░░░░░░░░░░ 0% Planificación — Drones Programados (Dron 2.0)
Fase 4: ░░░░░░░░░░ 0% Inteligencia de Colmena (Dron 3.0)
Fase 5: ░░░░░░░░░░ 0% Observabilidad — Dashboard y Métricas (Dron 4.0)
```
---
## 🏗️ Arquitectura de Colmena
@@ -683,7 +793,7 @@ Fase 5: ░░░░░░░░░░ 0% Observabilidad — Dashboard y Mé
## 🔄 Armonía Integral
**Última actualización**: 2026-04-07Fase 0 y Fase 1 completas
**Última actualización**: 2026-04-09Auditoría + Fase 1.5 planificada
| Documento | Estado | Notas |
|-----------|--------|-------|
@@ -694,17 +804,25 @@ Fase 5: ░░░░░░░░░░ 0% Observabilidad — Dashboard y Mé
---
## Entregables Fase 1 (Completados)
## 📦 Entregables
| Archivo | Líneas | Descripción |
|---------|--------|-------------|
| `adn/tools/cli/dron/base.rb` | 60 | Módulo compartido (atomisidad) |
| `adn/tools/cli/dron/dispatcher.rb` | 80 | Routing de subcomandos |
| `adn/tools/cli/dron/ejecutor.rb` | 90 | Ejecutor atómico |
| `adn/tools/cli/dron/vigilante.rb` | 140 | Vigilante atómico |
| `adn/tools/cli/dron/sanador.rb` | 80 | Sanador atómico |
| `adn/tools/cli/dron/bitacora.rb` | 70 | Bitácora atómica |
| `adn/tools/db/core/dron_db.rb` | 340 | Acceso a datos DB |
| `adn/tools/db/migrations/003_create_dron_tables.rb` | 150 | Migración DB |
### Fase 1 (Estructura atómica — con deuda técnica)
**Total:** ~1010 líneas nuevas, ~460 líneas menos que el monolito original (neto: -40%)
| Archivo | Líneas | Descripción | Estado |
|---------|--------|-------------|--------|
| `adn/tools/cli/dron/base.rb` | 66 | Módulo compartido (atomisidad) | ✅ |
| `adn/tools/cli/dron/dispatcher.rb` | 284 | Routing de subcomandos | ⚠️ B1 |
| `adn/tools/cli/dron/ejecutor.rb` | 171 | Ejecutor atómico | ⚠️ B9, B11 |
| `adn/tools/cli/dron/vigilante.rb` | 151 | Vigilante atómico | ⚠️ B10 |
| `adn/tools/cli/dron/sanador.rb` | 85 | Sanador atómico | ⚠️ B6, B7, B8 |
| `adn/tools/cli/dron/bitacora.rb` | 76 | Bitácora atómica | ✅ |
| `adn/tools/db/core/dron_db.rb` | 351 | Acceso a datos DB | ⚠️ B2-B5 |
| `adn/tools/db/migrations/003_create_dron_tables.rb` | 232 | Migración DB | ✅ |
### Fase 1.5 (Pendiente — Visibilidad + Corrección)
Entregables esperados:
- Corrección de los 12 bugs detectados
- Heartbeat visible en Bitácora Web
- Eliminación del sistema dual `.sh`/Ruby
- Flujo ejecutor→events→web funcional y probado