# `@decido/core`

> Módulo central de ejecución secuencial, orquestación de sub-grafos y máquina de estados reactiva de **Decido OS**.

`@decido/core` es el núcleo computacional (Kernel) responsable de interpretar y ejecutar blueprints modulares. Utiliza un patrón de Inversión de Control (IoC) mediante plugins extensibles, posee aislamiento de memoria local para subflujos en una pila de llamadas (Call Stack) y proporciona persistencia reactiva atómica e inmune a leaks de memoria apoyada sobre IndexedDB.

---

## 📦 Instalación y Setup

Aprovisiona este paquete dentro del monorepo o consumelo como dependencia interna:

```bash
pnpm add @decido/core
```

---

## ⚙️ Arquitectura y Modelo de Ejecución

El motor `DecidoEngine` procesa la lógica paso a paso delegando la resolución de nodos a los componentes registrados de tipo `NodePlugin`. A continuación se detalla su flujo de eventos, soporte a suspensiones reactivas y apilamiento de marcos de ejecución para subflujos:

```mermaid
sequenceDiagram
    participant Host as Aplicación Host
    participant Engine as DecidoEngine
    participant Reg as PluginRegistry
    participant Plugin as NodePlugin

    Host->>Engine: start(blueprintId, initialInputs)
    Note over Engine: Estado: RUNNING<br/>Inicia primer CallFrame
    Engine-->>Host: Evento 'graph:start'
    
    Host->>Engine: executeNode(node)
    Engine->>Reg: get(node.type)
    Reg-->>Engine: Plugin
    Engine->>Plugin: execute(node.payload, context)
    
    alt Completado Simple
        Plugin->>Engine: context.dispatchCompletion(handle, outputs)
        Note over Engine: Inyecta outputs en memory.session
        Engine-->>Host: Evento 'node:complete'
    else Suspensión Reactiva
        Plugin->>Engine: context.dispatchSuspend(reason)
        Note over Engine: Estado: SUSPENDED
        Engine-->>Host: Evento 'engine:suspend'
        Host->>Engine: resume(injectedVariables)
        Note over Engine: Estado: RUNNING
        Engine-->>Host: Evento 'engine:resume'
    else Orquestación de Subflujo (Call Stack)
        Plugin->>Engine: context.pushCallFrame(targetBlueprintId, startNodeId)
        Note over Engine: Respalda memory.local del padre<br/>Limpia memory.local del hijo
        Engine-->>Host: Evento 'engine:callframe_push'
        
        Note over Engine: Ejecución del subflujo...
        
        Plugin->>Engine: context.popCallFrame(outputs, handle)
        Note over Engine: Restaura la memory.local del padre
        Engine-->>Host: Evento 'engine:callframe_pop'
        Engine-->>Host: Evento 'node:complete' (nodo padre)
    end
```

---

## 🛠️ APIs y Contratos Clave

| Símbolo | Tipo | Descripción |
| :--- | :--- | :--- |
| `DecidoEngine` | Clase | Implementación del motor central (`DecidoKernel`) con pila de llamadas y memoria de 3 niveles. |
| `PluginRegistry` | Objeto | Catálogo único (Singleton) para registrar y recuperar plugins contractuales de nodos. |
| `DecidoKernel` | Interfaz | Contrato que define la API operacional y eventos de ciclo de vida del motor. |
| `DecidoPluginContext` | Interfaz | Contexto IoC provisto a los plugins para despachar flujos (`completion`, `suspend`, `callstack`). |
| `NodePlugin` | Interfaz | Contrato para definir e implementar la lógica ejecutable asociada a un tipo de nodo. |
| `EngineMemory` | Interfaz | Estructura de almacenamiento reactivo dividida en ámbitos: `global`, `session` y `local`. |
| `get`, `set`, `del`, `clear` | Funciones | Capa de persistencia síncrona/asíncrona atómica optimizada mediante conexión **Cached Singleton** en IndexedDB. |

---

## 🚀 Ejemplos de Consumo Práctico

### 1. Definición y Registro de un Plugin de Conversación
Los plugins permiten encapsular lógica extendida e interactuar de forma segura con la pila y memoria del motor:

```typescript
import { NodePlugin, DecidoPluginContext, PluginRegistry } from '@decido/core';

interface DialoguePayload {
  prompt: string;
  role: string;
}

// Implementación de un plugin interactivo con suspensión
export const DialoguePlugin: NodePlugin = {
  type: 'ai:dialogue',
  async execute(payload: unknown, context: DecidoPluginContext) {
    const { prompt, role } = payload as DialoguePayload;
    
    console.log(`[DialoguePlugin] Procesando prompt para rol ${role}: "${prompt}"`);
    
    // Suspendemos la ejecución esperando interacción del usuario externo
    context.dispatchSuspend('WAITING_USER');
  }
};

// Registro del plugin en el catálogo global
PluginRegistry.register(DialoguePlugin);
```

### 2. Orquestación e Invocación del Motor (`DecidoEngine`)

```typescript
import { DecidoEngine } from '@decido/core';

const engine = new DecidoEngine();

// Suscripción reactiva a eventos del ciclo de vida
engine.on('graph:start', (payload) => {
  console.log(`[Kernel] Flujo iniciado: ${payload.blueprintId}`);
});

engine.on('engine:suspend', (payload) => {
  console.log(`[Kernel] Motor en Suspensión. Razón: ${payload.reason}`);
});

engine.on('node:complete', (payload) => {
  console.log(`[Kernel] Nodo completado: ${payload.nodeId} con handle: ${payload.handle}`);
});

// Iniciamos la ejecución del blueprint
engine.start('chat-flow-root', { userId: 'user_9988' });

// Al recibir respuesta externa, reanudamos el motor con las nuevas variables
setTimeout(() => {
  if (engine.state === 'SUSPENDED') {
    engine.resume({ userResponse: '¡Hola! Quiero iniciar mi onboarding.' });
  }
}, 1000);
```

---

## 🧪 Robustez y Suite de Pruebas (Test Shield 100%)

El paquete `@decido/core` cuenta con un estricto blindaje de pruebas unitarias (**Unit Test Shield**) implementado con **Vitest** y **V8**, garantizando un **100% absoluto de cobertura** en ramas lógicas, sentencias, funciones y líneas de código.

Para correr localmente las pruebas unitarias y verificar el estricto cumplimiento del Test Shield:

```bash
# Ejecutar todas las pruebas unitarias
pnpm --filter @decido/core test

# Generar y auditar la tabla de cobertura 100%
pnpm --filter @decido/core test:coverage
```

---

## 🔐 Licencia y Privacidad

El código fuente de este paquete se encuentra protegido y auditado de forma corporativa.  
Distribuido estrictamente bajo licencia **UNLICENSED** para uso exclusivo en el ecosistema de **Decido OS**.
