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:
- Bootstrap (arranque):
load_pluginsdescubre plugins →create_plugin+ hooksregister_*→ registries → rutas/panels,/ui,/forms. - Runtime: el panel React consume esas rutas; los plugins sirven dominio en
/api/v1/{namespace}; tenant y auth aplican en cada petición. - 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.
- Estado — Implementado (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:
salesscaffold;storescaffold; 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:
- Instancia:
create_plugin()→PluginProtocol(api_router,resource_paths) — lógica REST de dominio. - 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 | FormDefinition → GET /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+ abstraccionesregistrar(PanelRegistrar,DashboardRegistrar,FormRegistrar) — plugins no importancortex_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,controlvíacortex.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; flagsshellOwnsPageTitleyshowPanelSubtitle. - [x]
@cortex/web: shell comúncreatePanelShellApp()— rutas, provider, API client. - [x] Demo:
framework/web-shadcn(:5175). - [x] Fix
resolveApiUrl: paths CUS con/api/v1/...no duplican prefijo enfetchPath.
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¶
- Usuario navega a p. ej.
/panel/booking/home. AppPanelRoutesresolvió rutas desdeGET /api/v1/panels/routes.PanelShellcargaGET /api/v1/panels/panel→ módulos,navGroups,navigation.ModuleScreencarga manifest del módulo →dashboardIdde la pantalla.GET /api/v1/ui/dashboards/{dashboardId}→ layout + widgets.- 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, hookregister_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¶
- Doble
/api/v1: los dashboards declaran paths completos; el cliente usaresolveApiUrl— no volver a prefijar en widgets. - Vite + monorepo: en
vite.config.tsde cada demo,optimizeDeps.excludepara@cortex/web,@cortex/panel-corey la skin;dedupe: ['@cortex/panel-core']— evita dos copias de React context (usePanel must be used within PanelProvider). - Plugins scaffold: existen en repo pero no cargan hasta activarlos en
CORTEX_ENABLED_PLUGINS. - Sin MongoDB: documentación y código activo solo PostgreSQL.
- 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:
- Implementar ADRs 005–009 — OIDC, MCP, PG por plugin, booking genérico, Redis NFR.
- Pip packaging (ADR 002) — publicar
cortex-plugin-*y validar sideload. - Endurecer plugins de dominio restantes (clients, payments, …).
- Widgets CUS v2 — sparklines en stats, polling; contrato JSON estable para
chartystats-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) |