Architecture Review
Review document that records findings, observations, and validation notes for the architecture package.
Translation layer status: English review layer prepared for public reading. The Spanish source remains attached below as the audit source until final human translation replaces this page.
sha256: 8D8F2344D7AAD4E732369CABA92679305B01D5C546E7562EFF1604239E60FA7C
Original Spanish Source
# Revisión técnica — ::::bastion::unicorn:::: / nueva arquitectura de intranet ## Veredicto directo El archivo sirve. No es basura. Es una propuesta fuerte, ambiciosa y técnicamente superior al esquema de seis puertos + seis túneles. Pero no debe ejecutarse como reemplazo inmediato del sistema real, porque mezcla tres niveles distintos: 1. **Corrección inmediata realista:** gateway único, Caddy/Cloudflare/Tailscale, un solo punto público. 2. **Arquitectura objetivo:** capability-based runtime, control plane local, observabilidad y estado unificado. 3. **Especificación de producto nuevo:** `unicornd` en Go/Rust, WASI, WebRTC, ConnectRPC, SPFx, NATS, SQLite, OTEL, GitOps. La parte valiosa es la dirección: dejar de administrar puertos y empezar a administrar capacidades. La parte peligrosa es pretender saltar directo a `unicornd` sin estabilizar primero el runtime actual de Mini + bastion-grp + 8011 + 8766 + 8767 + 8788. ## Qué sí debe quedarse - La idea de **un solo gateway público**. - La lectura de que los puertos internos no son producto; son infraestructura privada. - El enfoque de **capabilities**: `codex`, `voice`, `messages`, `grp-midi2`, `mayanmidi`, `legacy`. - El rechazo a seis iframes permanentes en SharePoint. - La separación entre Mini como nodo edge/local y Azure/SharePoint como capa institucional. - La idea de que Streamlit no debe ser el corazón permanente del sistema. - El uso de observabilidad real: `/healthz`, `/metrics`, logs JSONL y estado verificable. ## Qué corregir antes de convertirlo en norma ### 1. No afirmar que Dev Tunnels “matan” WebSockets de forma absoluta La pantalla negra de Streamlit puede venir de WebSockets, headers, baseUrlPath, CORS, CSP, iframe, `server.address`, browser mixed context o proceso Streamlit mal levantado. El archivo tiene razón en sospechar de WebSockets + iframe, pero lo formula demasiado absoluto. Debe quedar como hipótesis técnica prioritaria, no como hecho cerrado. ### 2. No vender `Scheduled Tasks` como anti-patrón absoluto En Windows, un servicio formal es más limpio, pero Scheduled Tasks sirven como puente operativo real. La norma debe decir: **Tasks son puente de operación; servicios Windows son objetivo estable**. ### 3. Cloudflare no debe sustituir automáticamente a Dev Tunnels sin decisión de dominio Cloudflare Tunnel exige dominio controlado y configuración DNS. Puede ser mejor, pero no es “gratis sin costo operativo”. Si no hay dominio listo, Dev Tunnels siguen siendo válidos para arranque. Arquitectura recomendada: - Fase puente: Dev Tunnel único a 8800. - Fase dominio: Cloudflare/Tailscale Funnel. - Fase producción: Azure Container Apps/App Service para piezas públicas críticas. ### 4. `unicornd` es producto nuevo, no refactor menor Un runtime en Go/Rust con WASI, ConnectRPC, WebRTC, NATS y SPFx es un proyecto completo. Debe tratarse como `bastion-unicorn` dentro de `bastion-grp`, no como tarea pequeña de parche. ### 5. No eliminar Python/Streamlit de golpe MayanMIDI y redeco ya tienen valor operativo. La ruta sana es: - conservar Streamlit como capability legacy; - estabilizar 8502 o encapsularlo; - extraer core MIDI a librería/servicio; - solo después migrar a WASM/Go/Rust. ## Arquitectura recomendada por fases ### Fase A — Gateway operativo inmediato Objetivo: una entrada pública sin romper lo que ya funciona. - Mantener 8766, 8767, 8788 y 8011. - Encapsularlos detrás de `gateway:8800`. - Dejar 8501/8502 como `legacy/debug` hasta resolver pantalla negra. - Registrar `/healthz`, `/status`, `/routes` y `/version`. ### Fase B — Bastion Shell Objetivo: SharePoint deja de depender de seis iframes. - Un iframe temporal al gateway. - Después un SPFx/Web Component. - Menú interno: Codex, Voice, Messages, GRP-MIDI2, MayanMIDI. - Auth con Entra ID cuando se pase de demo a operación institucional. ### Fase C — Capabilities Objetivo: dejar de pensar en puertos. Cada módulo debe tener: - `capability_id` - `route` - `owner_node` - `healthcheck` - `runtime` - `state_path` - `logs_path` - `restart_policy` - `public_exposure` ### Fase D — Unicorn Runtime Objetivo: producto nuevo. - Crear paquete `unicornd` dentro del repo. - Primero supervisor + router + config. - Después observabilidad. - Después sidecars. - Después WASI. - Después WebRTC. ## Decisión arquitectónica recomendada No mover todo a `UNICORN` hoy. Primero crear el repositorio/folder técnico y usarlo como cápsula de diseño controlado. La prioridad real es: 1. **consolidar gateway 8800**; 2. **documentar rutas actuales y futuras**; 3. **crear manifiesto de capabilities**; 4. **crear scripts de arranque/validación**; 5. **convertir `UNICORN` en rama/proyecto, no en parche inmediato**. ## Lo que yo añadiría al documento ### Sección nueva: `::::bastion::unicorn::migration::guardrails::::` Reglas: - No apagar ningún servicio real hasta que su capability tenga healthcheck equivalente. - No borrar Dev Tunnels actuales hasta validar gateway único durante al menos una sesión completa. - No migrar 8502 hasta tener diagnóstico de pantalla negra por logs y WebSocket test. - No reemplazar `bastion-grp` por `unicornd`; `unicornd` debe envolverlo primero. - Todo endpoint debe tener ruta pública, ruta interna, healthcheck y owner. ### Sección nueva: `::::bastion::unicorn::capability::registry::::` Tabla mínima: | capability_id | ruta pública | destino actual | estado | prioridad | |---|---|---|---|---| | `bastion.ui.codex` | `/` / `/codex` | 8766 | arriba | alta | | `bastion.voice.ingest` | `/voice` | 8767 | arriba | alta | | `bastion.msg.bus` | `/messages` | 8788 | arriba | alta | | `bastion.api.grp_midi2` | `/grp-midi2/status` | 8011 | arriba | alta | | `bastion.midi.mapper` | `/mayanmidi` | 8502 | pantalla negra | media | | `bastion.midi.legacy` | `/legacy` | 8501 | pantalla negra | baja | ### Sección nueva: `::::bastion::unicorn::definition::of::done::::` Un módulo está migrado cuando: - responde en ruta gateway; - responde healthcheck; - tiene logs persistentes; - tiene restart policy; - no depende de terminal abierta; - está documentado en manifest; - está registrado bajo nodo terrauniversalis. ## Nodo terrauniversalis Nodo principal: `tu-11-tec @systemauniversalis`. Nodos vinculados: - `tu-08-arc @acervouniversalis` por archivo, bitácora, documentación y preservación. - `tu-15-edu @educareuniversalis` por aprendizaje técnico, patrones y formación interna. - `tu-06-com @mediauniversalis` por consola visual, SharePoint shell, voice ingestion y capa comunicacional. ## Conclusión El documento sirve como visión de arquitectura. No debe entrar como instrucción operativa directa sin faseado. Su valor principal es convertir el caos de puertos en un modelo de capacidades. Su riesgo principal es querer reescribir todo antes de estabilizar el gateway. La línea correcta es esta: **Primero gateway 8800. Después capability registry. Después shell único. Después unicorn runtime.** ::::terra::sls:::: 🌐♾