Saltar a contenido

Contexto del proyecto Cortex (HIVE)

Documento de referencia para desarrolladores y agentes: dónde estamos, cómo encaja todo y hacia dónde apunta el monorepo. Actualizar cuando cambie arquitectura o hitos relevantes.

Última revisión: 2026-06 (post-refactor frontend multi-skin).


Visión

Cortex/HIVE es una plataforma multi-tenant ensamblada por plugins Python. La experiencia administrativa ofrece varios panels independientes, UI declarativa y API REST bajo /api/v1:

  • Varios panels independientes (panel, admin, client, trainer, accounting, …).
  • Cada panel tiene path UI, namespace API y módulos CUS (manifests + dashboards JSON).
  • Los plugins no aportan páginas React; declaran JSON y REST.
  • Distribución futura vía pip (ADR 002); sideload con CORTEX_PLUGIN_DIRS.

Los prototipos históricos validaron la arquitectura multi-panel y UI declarativa; no definen el dominio genérico de los módulos de negocio (p. ej. reservas → ADR 008).


Mapa general del sistema

Diagrama de un vistazo: actores, capas Dependiente, plugins Independiente, datos e integraciones. El detalle de cada bloque está en las secciones siguientes y en los ADRs.

Leyenda: Visión holística de Cortex/HIVE. Actores: administrador (panel), apps externas (REST), agentes (MCP). Estado: Parcial — UI, registries y apirest implementados; oauth2-server, io completo y persistencia real en diseño.

flowchart TB
  subgraph actores [Actores]
    Admin[Administrador panel]
    Apps[Apps y clientes REST]
    IA[Agentes IA MCP]
  end

  subgraph frontend [Frontend Dependiente]
    Shell["@cortex/web + skins"]
    CUS[Panel CUS widgets]
  end

  subgraph plataforma [Plataforma HIVE Dependiente]
    REST["FastAPI /api/v1"]
    Auth[oauth2-server JWT ACL]
    Tenant[tenant multi-tenant]
    IO[io apirest webhooks mcp]
    UIreg[forms panel registries]
  end

  subgraph nucleo [Nucleo ensamblador]
    SPI[cortex_core SPI hooks]
    FW[cortex_framework loader]
  end

  subgraph plugins [Plugins Independiente]
    Dom["cortex_plugin_* booking clients payments sales store accounting ..."]
  end

  subgraph datos [Infraestructura]
    PG[(PostgreSQL por tenant)]
    Redis[(Redis cache NFR)]
  end

  subgraph externos [Externos opcionales]
    IdP[IdP OAuth externo]
    WH[Suscriptores webhooks]
  end

  Admin --> Shell
  Shell --> CUS
  CUS -->|HTTP| REST
  Apps --> REST
  IA --> IO
  REST --> Auth
  REST --> Tenant
  REST --> IO
  REST --> UIreg
  Auth --> IdP
  FW --> SPI
  SPI -->|discovery bootstrap| Dom
  Dom -->|api_router runtime| IO
  Tenant --> PG
  Dom --> PG
  IO --> Redis
  IO --> WH

Flujo resumido:

  1. Bootstrap (arranque): load_plugins descubre plugins → create_plugin + hooks register_* → registries → rutas /panels, /ui, /forms.
  2. Runtime: el panel React consume esas rutas; los plugins sirven dominio en /api/v1/{namespace}; tenant y auth aplican en cada petición.
  3. Integración: plugins de negocio se hablan entre sí solo por REST (sin imports cruzados).

Arquitectura Dependiente vs Independiente

La pizarra de producto define dónde vive el código, no solo “core vs plugins”.

Columna Qué es Dónde vive
Dependiente Módulos internos del framework — la plataforma no funciona sin ellos framework/cortex_framework/*, packages/cortex-panel-*, packages/cortex-web
Independiente Dominios de negocio en plugins pip/sideload plugins/*/cortex_plugin_*

Los plugins consumen módulos Dependiente (auth, IO, UI, tenant); no reimplementan OAuth, panel shell, widgets base ni capa REST/MCP.

Convención de leyendas en diagramas

Cada diagrama del repo incluye un bloque Leyenda con:

  • Propósito — qué muestra el diagrama.
  • Actores — quién inicia cada interacción.
  • EstadoImplementado (código en repo) o Diseño (ADR / pendiente).

Módulos Dependiente

Módulo Responsabilidad Ubicación actual / objetivo
oauth2-server OAuth2, ACL, permisos, JWT (Keycloak-like interno; IdP externo opcional — ADR 005) Objetivo: cortex_framework.oauth2_server
tenant Multi-tenant, X-Tenant-Id, PG por tenant cortex_framework/tenant/
io apirest, webhooks, mcp, apirest2mcp (ADR 010) Parcial: cortex_framework/api/
ui / panel Forms, componentes, dashboards, skins, multi-panel CUS cortex_framework/forms/, panel/, dashboard/, packages/cortex-panel-*
observability Logs, trazas, métricas Diseño
cms Contenido gestionado (páginas, bloques) para apps host Diseño — módulo Dependiente
reportes Motor de informes transversal sobre datos de plugins Diseño — módulo Dependiente
integraciones Conectores salida/entrada (ERP, pasarelas) vía io Diseño — submódulo de io
configuración Settings tenant, panel Control settings.py, control/

Panel hosts: entry point cortex.panels + configure_panel(PanelBuilder); cada host declara módulo home con dashboard propio. Los plugins contribuyen con register_resources, register_widgets, register_settings en uno o varios panel_id. Panel Control embebido en framework.

Operación vs parametrización (ADR 019)

Panel Ruta Rol Módulos típicos
panel /panel/ Operación diaria booking, clients, resources
admin /admin/ Parametrización y finanzas sales, billing, payments, pricing, configuración
flowchart TB
  subgraph hosts [Panel hosts]
    P[panel /panel]
    A[admin /admin]
  end

  subgraph opMods [Modulos operacion]
    BK[booking]
    CL[clients]
    RS[resources]
  end

  subgraph admMods [Modulos parametrizacion]
    SL[sales]
    BL[billing]
    PY[payments]
    PR[pricing]
  end

  subgraph cross [Contribucion transversal]
    W[register_widgets KPI]
    S[register_settings]
    F[reservation-flow widgets]
  end

  P --> opMods
  A --> admMods
  SL --> W
  PY --> W
  BK --> F
  F --> CL
  F --> PY
  F --> PR
  SL --> S
  BL --> S
  PY --> S
  PR --> S
  BK --> S

Leyenda: Separación operación / parametrización. Un plugin puede registrar en varios panels (módulos, widgets o settings). Estado: Implementado en demo (panel + admin).

Plugins Independiente (dominio)

Dominio Plugin Notas
Reserva (calendario, agenda, recursos) cortex_plugin_booking ADR 008
Pagos cortex_plugin_payments
Facturación cortex_plugin_billing
Contabilidad cortex_plugin_accounting PoC más completo
Descuentos / cupones cortex_plugin_discounts
Tarifas cortex_plugin_pricing
Clientes cortex_plugin_clients
Ventas (POS) cortex_plugin_sales Cajeros, apertura/cierre, mostrador
Tienda (e-commerce) cortex_plugin_store Catálogo, carrito, checkout
Eventos cortex_plugin_events
Suscripciones cortex_plugin_subscriptions
Bot / IA Consumen io.mcp + dominio No duplican reglas de negocio; tools por plugin (ADR 006)

Ventas ≠ Tienda: dos plugins separados; comparten integraciones (pagos, clientes, tarifas) vía REST, sin código compartido de dominio.

flowchart TB
  subgraph dependiente [Dependiente - modulos framework]
    Auth[oauth2-server ACL JWT]
    Tenant[multi-tenant logs config]
    UI[forms components dashboard skins panel]
    IO[io apirest webhooks mcp apirest2mcp]
  end
  subgraph independiente [Independiente - plugins]
    BK[cortex_plugin_booking]
    SL[cortex_plugin_sales POS]
    ST[cortex_plugin_store e-commerce]
    AC[cortex_plugin_accounting]
  end
  Auth --> IO
  UI -->|HTTP PanelApiClient| IO
  IO --> BK
  IO --> SL
  IO --> ST
  IO --> AC

Leyenda: Taxonomía Dependiente vs Independiente. Actores: módulos de plataforma habilitan plugins de negocio; la UI solo habla HTTP con io.apirest. Estado: Parcial — registries y apirest implementados; oauth2-server, io completo y persistencia real en diseño.

flowchart LR
  subgraph sales [cortex_plugin_sales]
    CR[cajeros]
    OP[apertura cierre]
    TK[ticket mostrador]
  end
  subgraph store [cortex_plugin_store]
    CAT[catalogo]
    CART[carrito]
    CHK[checkout]
  end
  subgraph shared [integracion REST]
    PAY[cortex_plugin_payments]
    CLI[cortex_plugin_clients]
    PRC[cortex_plugin_pricing]
  end
  sales --> PAY
  store --> PAY
  sales --> CLI
  store --> CLI
  store --> PRC

Leyenda: Ventas (POS) y Tienda (e-commerce) como plugins distintos. Actores: cada dominio llama a otros plugins solo por API. Estado: sales scaffold; store scaffold; integraciones reales pendientes.


Ciclo de vida del plugin

Principio: HIVE no conoce las reglas de negocio ni el código React de un plugin. Solo conoce contratos SPI, hooks de registro y rutas HTTP genéricas de plataforma. Al descubrir un plugin, este se coloca en la aplicación: panels, módulos CUS, formularios y API REST — usando herramientas Dependientes (forms, UI/panel, widgets, io.apirest).

El arranque en framework/cortex_framework/plugins/loader.py tiene dos fases:

  1. Instancia: create_plugin()PluginProtocol (api_router, resource_paths) — lógica REST de dominio.
  2. Bootstrap: hooks opcionales → el framework inyecta implementaciones concretas de los registradores definidos en core/cortex_core/registrar.py (DIP).

Bootstrap vs runtime

Fase Mecanismo Responsabilidad del plugin
Bootstrap register_resources, register_dashboards (legacy), register_settings, … Dónde aparece en panels, pantallas CUS, formularios
Runtime api_router(), resource_paths() Endpoints y lógica de dominio bajo /api/v1

Hooks disponibles

Hook Tipo inyectado (core) Qué publica
configure_panel (cortex.panels) PanelBuilder Identidad del panel host (path, brand, theme)
register_resources(registry) ResourceRegistry Manifest + dashboards + forms vía ResourceBuilder (recomendado)
register_widgets(registry) WidgetRegistryApi Widgets en dashboard del panel host (panel_id)
register_settings(registry) SettingsRegistry Secciones de configuración por panel
register_dashboards(registry) DashboardRegistrar Manifest + dashboards JSON (legacy)
register_forms(registry) FormRegistrar FormDefinitionGET /api/v1/forms/{formId}

Catálogo de campos v1 (FormBuilder, emisión en forms/emit.py, renderers shadcn): ver ADR 020. | register_mcp_tools(registry) (diseño) | McpToolRegistrar | Tools MCP sobre REST existente (ADR 006) |

El plugin compone pantallas con widgets del UI Kit (data-table, form, section, …); no aporta componentes React propios.

Límite del desacoplamiento: HIVE sí conoce los tipos de widget y las rutas HTTP de plataforma; lo desconocido es el dominio de negocio y el JSON concreto de cada módulo.

Leyenda: Ciclo completo discovery → bootstrap → ensamblado HTTP → shell React. Actores: discovery, hosts, plugins, registries, API, shell. Estado: Implementado.

flowchart TB
  subgraph discovery [Discovery]
    EP[entry_points cortex.panels + cortex.plugins]
    Load[load_plugins]
  end
  subgraph hosts [Panel hosts]
    PH[configure_panel PanelBuilder]
  end
  subgraph plugin [Plugin Independiente]
    CP[create_plugin api_router]
    HR[register_resources]
    HD[register_dashboards legacy]
    JSON[ui manifest dashboards]
  end
  subgraph framework [Framework Dependiente]
    PREG[PanelRegistry]
    RREG[ResourceRegistry DashboardRegistry FormRegistry]
    HTTP["GET /api/v1/panels /ui /forms"]
    IO[io.apirest guards tenant]
  end
  subgraph frontend [Shell React]
    Shell["@cortex/web + panel-shadcn"]
    Widgets[widgets CUS]
  end
  EP --> Load
  Load --> PH --> PREG
  Load --> CP
  Load --> HR
  Load --> HD
  JSON --> HD
  HR --> RREG
  HD --> RREG
  CP --> IO
  PREG --> HTTP
  RREG --> HTTP
  HTTP --> Shell --> Widgets
  Widgets -->|fetchPath| IO

Leyenda: Secuencia de invocación de hooks en bootstrap. Actores: loader, módulo del plugin, registries etiquetados, rutas FastAPI. Estado: Implementado.

sequenceDiagram
  participant Loader as loader.py
  participant Host as cortex.panels
  participant Mod as cortex_plugin_*
  participant Reg as TaggedRegistries
  participant API as FastAPI routes

  Loader->>Host: load_panel_hosts configure_panel
  Host->>Reg: PanelRegistry
  Loader->>Mod: import_plugin_module
  Loader->>Mod: create_plugin
  Loader->>Mod: register_resources registry
  Mod->>Reg: manifest dashboards forms
  Reg->>API: assemble GET /panels /ui /forms
  Loader->>Loader: validate_panels

Diseño de ingeniería (ADRs 005–010)

Documentación de diseño acordada; implementación pendiente.

PDF consolidado: ingenieria-hive.pdf — regenerar con docs/build-ingenieria-pdf.sh (autor: Neftali Yagua; incluye arquitectura Dependiente/Independiente y ADRs seleccionados 001–011, 018–019). Diagramas fuente: docs/diagrams/.

ADR Tema
005 oauth2-server híbrido (interno por defecto), JWT, PanelAuthPolicy
006 Servidor MCP + SPI register_mcp_tools
007 PostgreSQL por tenant, Alembic por plugin
008 Dominio genérico Resource/Slot/Booking
009 Rate limit Redis, /ready, idempotencia
010 Módulo IO: apirest, webhooks, mcp, apirest2mcp

Leyenda: ADRs transversales (Dependiente) y de dominio (Independiente) que afectan al ecosistema. Estado: Diseño de ingeniería; implementación parcial según ADR.

flowchart TB
  subgraph transversal [Capas transversales]
    OIDC[ADR 005 OIDC]
    Redis[ADR 009 Redis NFR]
    PG[ADR 007 Persistencia]
    IOM[ADR 010 Modulo IO]
  end
  subgraph dominio [Dominio]
    Booking[ADR 008 booking]
    MCP[ADR 006 MCP tools]
  end
  OIDC --> Booking
  PG --> Booking
  Redis --> Booking
  IOM --> MCP
  MCP --> Booking

Leyenda: Dependencias entre ADRs transversales y dominio booking/MCP. Actores: capas de plataforma habilitan el módulo booking. Estado: Diseño.

Estado actual (hitos completados)

Backend

  • [x] Stack HIVE: FastAPI, PostgreSQL por tenant, Redis, uv workspace (ADR 001).
  • [x] SPI en core/cortex_core + abstracciones registrar (PanelRegistrar, DashboardRegistrar, FormRegistrar) — plugins no importan cortex_framework.
  • [x] Multi-panel registry + GET /api/v1/panels, /panels/routes, /panels/{id} (ADR 004).
  • [x] CUS: manifests/dashboards JSON, validación ligera en cortex_framework/panel/.
  • [x] Panel Control embebido (/control/, toggles de plugins en caliente).
  • [x] Plugin accounting como PoC de dominio completo (API + UI).
  • [x] Plugin reference (samples / To-Do) como ejemplo mínimo.
  • [x] Panel hosts: panel, client, trainer, accounting, control vía cortex.panels.
  • [x] Scaffolds de dominio: booking, billing, clients, discounts, events, payments, pricing, sales, store, subscriptions (fixtures + UI; persistencia real — ADR 007/008).

Frontend

  • [x] @cortex/panel-core: headless (types, PanelProvider, nav agrupada, routing, PanelApiClient).
  • [x] @cortex/panel-shadcn: skin shadcn/ui + Tailwind v4 (shell, widgets, DashboardRenderer).
  • [x] Routing por especificidad: matchModuleScreen / scoreScreenPath — rutas literales (create) antes que :id (ADR 018).
  • [x] Jerarquía de títulos: shell → dashboard (hideTitle) → widgets; flags shellOwnsPageTitle y showPanelSubtitle.
  • [x] @cortex/web: shell común createPanelShellApp() — rutas, provider, API client.
  • [x] Demo: framework/web-shadcn (:5175).
  • [x] Fix resolveApiUrl: paths CUS con /api/v1/... no duplican prefijo en fetchPath.

Tooling / CI

  • [x] npm workspaces en raíz (packages/*, framework/web, framework/web-shadcn).
  • [x] Tests Vitest en @cortex/panel-core (nav, routing, API URL).

Arquitectura en capas

Leyenda: Stack frontend (demos → shell → skin → core) y backend (API ensambla framework y plugins). Actores: navegador, paquetes npm, FastAPI. Estado: Implementado.

flowchart TB
  subgraph demos [Demo Vite]
    SH[web-shadcn :5175]
  end
  subgraph shell ["@cortex/web"]
    CPS[createPanelShellApp]
  end
  subgraph skin ["@cortex/panel-shadcn"]
    Skin[PanelShell widgets]
  end
  subgraph headless ["@cortex/panel-core"]
    Core["PanelProvider navUtils PanelApiClient"]
  end
  subgraph backend [Backend Python]
    API[FastAPI /api/v1]
    FW[cortex_framework]
    PLG[cortex_plugin_*]
    SPI[cortex_core SPI]
  end
  demos --> CPS --> Skin --> Core
  Core -->|HTTP| API
  FW --> PLG --> SPI
  API --> FW

Flujos clave

Arranque de una pantalla del panel

  1. Usuario navega a p. ej. /panel/booking/home.
  2. AppPanelRoutes resolvió rutas desde GET /api/v1/panels/routes.
  3. PanelShell carga GET /api/v1/panels/panel → módulos, navGroups, navigation.
  4. ModuleScreen carga manifest del módulo → dashboardId de la pantalla.
  5. GET /api/v1/ui/dashboards/{dashboardId} → layout + widgets.
  6. Widgets llaman API vía api.fetchPath(config.path) — paths CUS son absolutos /api/v1/....

Leyenda: Secuencia de carga de una pantalla del panel. Actores: usuario, rutas React, shell, ModuleScreen, widgets, FastAPI. Estado: Implementado.

sequenceDiagram
  participant U as Usuario
  participant R as AppPanelRoutes
  participant S as PanelShell
  participant M as ModuleScreen
  participant W as Widgets
  participant API as FastAPI

  U->>R: GET /panel/booking/home
  R->>API: GET /api/v1/panels/routes
  S->>API: GET /api/v1/panels/panel
  M->>API: GET /api/v1/panels/panel/modules/booking/manifest
  M->>API: GET /api/v1/ui/dashboards/{dashboardId}
  W->>API: PanelApiClient.fetchPath

Registro de UI en un plugin

Leyenda: Cómo un plugin Independiente publica UI declarativa sin React propio. Actores: ResourceBuilder, hook register_resources, registry del framework. Estado: Implementado.

flowchart LR
  RB[ResourceBuilder register_resources]
  JSON["ui/ legacy JSON"]
  Reg[ResourceRegistry PanelRegistry]
  API["GET /api/v1/panels /ui /forms"]
  RB --> Reg --> API
  JSON -->|register_dashboards legacy| Reg
# plugins/foo/cortex_plugin_foo/resources.py
from cortex_framework.ui import ResourceBuilder, register_resource
from cortex_framework.ui.registry import ResourceRegistry

def register_resources(registry: ResourceRegistry) -> None:
    def configure(builder: ResourceBuilder) -> None:
        builder.id("foo").title("Foo").api_base("/api/v1/foo")
    register_resource(registry, "panel", "foo", configure)

Bootstrap de una demo frontend

// framework/web-shadcn/src/panel/bootstrap.tsx (patrón)
import { createPanelShellApp } from '@cortex/web';
import { PanelShell, createDefaultRegistry } from '@cortex/panel-shadcn';

export const { AppPanelProvider, AppPanelRoutes, panelApiClient } =
  createPanelShellApp({ PanelShell, createDefaultRegistry, renderLoading, renderError });

Mapa de archivos importantes

Ruta Rol
core/cortex_core/spi.py Contrato base del plugin
core/cortex_core/registrar.py Interfaces register_* (DIP)
framework/cortex_framework/api/routes.py Rutas REST plataforma
framework/cortex_framework/panels/registry.py Ensamblado multi-panel
framework/cortex_framework/plugins/loader.py Discovery + CORTEX_ENABLED_PLUGINS
framework/cortex_framework/control/ Panel control embebido
packages/cortex-panel-core/src/panelApiClient.ts Cliente HTTP + resolveApiUrl
packages/cortex-panel-core/src/navUtils.ts Nav agrupada por navGroup
framework/web/src/createPanelShellApp.tsx Factory del shell React
plugins/panel/ Panel host operación
plugins/admin/ Panel host parametrización
plugins/clients/ Módulo de negocio clientes (CRUD, no panel host)
plugins/reference/ Ejemplo To-Do (samples)
plugins/accounting/ PoC contabilidad completa
scripts/scaffold_domain_plugins.py Generador de plugins dominio

Configuración habitual

Variable Default Notas
CORTEX_ENABLED_PLUGINS shells,reference,accounting * = todos descubiertos
CORTEX_PLUGIN_DIRS Sideload externo
CORTEX_DATABASE_URL_TEMPLATE PG por tenant
Header X-Tenant-Id default Obligatorio en API

Widgets CUS

Implementados en @cortex/panel-shadcn (tipos preferidos data-table, form; alias api-table, json-form):

type Uso
form JSON Forms + submit REST
data-table Tabla sobre GET config.path
api-card Resumen/card
plugin-list Lista plugins control (toggle)
settings Configuración mergeable por panel
stat-card KPI sobre endpoint REST (una métrica)
stats-overview Bloque de KPIs con un fetch (varias métricas)
chart Gráfico Recharts (bar, line, area, pie) sobre GET
reservation-flow Wizard composable de reserva
client-picker Selección de cliente (wizard)
payment-checkout Cobro y tarifa (wizard)
booking-slot-picker FullCalendar + overlay de slot (wizard)
section Contenedor con hijos

Extensión: createDefaultRegistry() + registry.register('tipo', Component).


Pitfalls conocidos

  1. Doble /api/v1: los dashboards declaran paths completos; el cliente usa resolveApiUrl — no volver a prefijar en widgets.
  2. Vite + monorepo: en vite.config.ts de cada demo, optimizeDeps.exclude para @cortex/web, @cortex/panel-core y la skin; dedupe: ['@cortex/panel-core'] — evita dos copias de React context (usePanel must be used within PanelProvider).
  3. Plugins scaffold: existen en repo pero no cargan hasta activarlos en CORTEX_ENABLED_PLUGINS.
  4. Sin MongoDB: documentación y código activo solo PostgreSQL.
  5. Legacy: no editar legacy/ salvo migración puntual.

Verificación antes de merge

uv run pytest
uv run ruff check core framework plugins/<tocados>
npm run test:panel-core
npm run build:web-shadcn   # si hay cambios UI

Dirección probable (no comprometida)

Orden sugerido para iteraciones futuras:

  1. Implementar ADRs 005–009 — OIDC, MCP, PG por plugin, booking genérico, Redis NFR.
  2. Pip packaging (ADR 002) — publicar cortex-plugin-* y validar sideload.
  3. Endurecer plugins de dominio restantes (clients, payments, …).
  4. Widgets CUS v2 — sparklines en stats, polling; contrato JSON estable para chart y stats-overview.

Referencias cruzadas

Doc Tema
ADR 001 Stack Python/FastAPI/PG
ADR 002 Distribución pip
ADR 003 CUS + widgets
ADR 004 Multi-panel
ADR 005 oauth2-server híbrido
ADR 006 Plugin MCP interno
ADR 007 Persistencia multi-tenant
ADR 008 Módulo booking genérico
ADR 009 Redis y NFRs
ADR 010 Módulo IO (apirest, webhooks, MCP)
ADR 019 Panel admin y parametrización
cortex-panel.md Guía runtime panel
Plugins Construcción de plugins
README del repositorio Arranque rápido
.cursor/rules/cortex-project.mdc Reglas arquitectura (Cursor)
.cursor/rules/hive-python.mdc Convenciones Python

Changelog de este documento

Fecha Cambio
2026-06 Creación post-refactor: panel-core, panel-shadcn, @cortex/web, demo web-shadcn, registrar SPI
2026-06 Retiro skins MUI/PatternFly; documentación alineada a shadcn único
2026-06 Diagramas Mermaid en arquitectura y flujos clave
2026-06 ADRs 005–009: ingeniería OIDC, MCP, persistencia, booking, Redis
2026-06 Taxonomía Dependiente/Independiente, ADR 010 IO, ADR 005 oauth2-server híbrido, leyendas en diagramas
2026-06 Sección ciclo de vida del plugin: discovery, hooks DIP, bootstrap vs runtime, diagramas
2026-06 Panel admin, separación operación/parametrización, widgets wizard y dashboard por host (ADR 019)