// public/docs-app/v1/doc/lru_destilado_modelo_unificado_senales_s183.md
// 2026-06-03T00:00:00Z

# LRU · Destilado · Modelo unificado de señales · fuente/sumidero · multi-tiempo · bidireccional · s183

**Ubicación canónica**: `public/docs-app/v1/doc/lru_destilado_modelo_unificado_senales_s183.md`
**Sesión origen**: s183 · 2026-06-03 · Manuel & Claude Opus 4.8
**Naturaleza**: destilado anillo 2 · diseño antes de materialización (Patrón 7) · **NO canónico · regla de disputa activa** hasta que el núcleo lo absorba
**Relación con el corpus**: **eleva** el alfiler `lru_alfiler_unificacion_arbitraje_senales_s165.md` (T-S165) de "unificar el arbitraje per-sensor" a "modelo unificado de señales" completo, recogiendo las piezas canónicas dispersas. Es **reconocimiento + materialización**, no diseño desde cero.
**Tensión**: `T-S183-MODELO-UNIFICADO-SENALES` · umbrella estructural · NO bloqueante · **absorbe la cola de T-S165** (R3/R4/R5 dejan de ser "lo que queda" y pasan a ser las primeras rebanadas de este norte)
**Propósito**: fijar la brújula del frente — el mundo de señales unificado, uniforme y simple que Manuel pide — con los tres ejes (espacio/tiempo/dirección) cableados en el contrato desde el día uno, aunque su materialización sea por rebanadas y mucha esté en horizonte.
**No-propósito**: NO toca código · NO arbitra el orden fino de ejecución · NO construye el grabador/viewer ni la actuación real ahora · NO cierra dónde vive físicamente el árbitro.

---

## §0 · Voz fundacional · Manuel s183 (Patrón 3, verbatim)

**El problema de fondo** (turno):

> *"tenemos varios mundos paralelos que no estan sincronizados y hay muchas inconsistencias, debemos tender a hacer un mundo de señales mas unificado uniforme y simple, donde la complejidad sea menor y la flexibilidad mayor"*

**La libertad por-señal**:

> *"el tema es que en cada señal tengamos libertad de aplicar cualquier fuente presente y futura, las señales pueden provenir de multiples fuentes de la app o externas, desde multiples dispositivos via comunicaciones ... una infinidad de fuentes ... otras maquinas reales o virtuales externas que queremos incorporarlas a la simulacion, la flexibilidad y simplicidad y agnosticismo por diseño"*

**La apuesta de generalizar**:

> *"ahora son tres generadores en conflicto ... si unificamos a costa de hacerlas mas genericas y universales creo que puede ser mas util"*

**Los actuadores como manos** (la mitad que falta):

> *"los actuadores son nuestras manos para interactuar con el mundo fisico no solo lo leemos sino que deberemos mas adelante de interactuar con el, sin eso solo somos un gran cerebro con mucha inteligencia pero encerrado en un mundo virtual"*

**La grabación/reproducción como objetivo**:

> *"la grabacion y reproduccion de señales tambien es un objetivo, por ejemplo imagina que queremos reproducir una secuencia de sensores de una caja negra del avion o del fallo de un sistema para aprender o la grabacion de una clase magistral"*

Eco fundacional (s67, ya en `LRU_FUNDAMENTOS §7`):

> *"el mundo virtual es idilico: el concepto actuador es ideal y no realista. En el mundo fisico pueden ocurrir muchas cosas imprevistas y mediante realimentacion de los sentidos o los sensores hacemos los cambios o la reingenieria que sea necesaria."* — Manuel, s67

---

## §1 · El problema de fondo — mundos paralelos sin coordinación

El diagnóstico no es nuevo: lo nombró `lru_geografia_desconexion_uso_real_s157.md`. La complejidad se acumuló por capas (M2 SimService · M3 DataPlane · M4 CommsAdapters · M5 ControlBus + RouterService), y **cada capa preservó retrocompatibilidad pero añadió un sitio nuevo donde el dato puede vivir y bifurcarse**. Síntoma empírico (s157 §4): dos universos internamente coherentes pero divergentes entre sí —

- **Universo A**: 7 consumidores (Mixer, Chart, Signals, Systems, Fallos, SignalLab, SignalTree) que leen el mismo `valuesRef` de SimService. Cero divergencia interna.
- **Universo B**: 4 consumidores (ComponenteLru/LruBar, EnlacesPanel, HwObjPopup, Hw1AdminPanel) que leen el ORC. Cero divergencia interna.
- **Pero A y B no ven necesariamente el mismo dato.** Esa es la desincronización.

El "volver" de s157 **no es regresión**: es reinstalar deliberadamente, sobre la arquitectura actual, la coordinación intrínseca que se perdió. Coherente con P10 (estructura sobre composición) y P11 (la complejidad debe ganarse).

Los **tres generadores en conflicto** son síntoma, no causa. Hallazgo empírico de s183 (auditoría de `SimService`):

1. **El motor está fuera de la taxonomía de modos.** El RAF tick escribe `'sim1'` (ungated, todos los sensores sim) solo con Play; entró por la puerta de atrás.
2. **`demoTick` (Rnd) escribe `'registry'`** solo con el motor parado, por-hwObj (`rs.getMode==='Rnd'`). **Motor y demoTick son excluyentes por run-state** — nunca a la vez.
3. **SignalLab no tiene fuente propia**: escribe vía `startOverride`/`setOverride`, una **capa de override sobre el camino del crucero**, efectiva solo con Play.
4. **`Gen` está sobrecargado**: una familia (`'sim1'` + `'registry'`) en vez de una fuente. El alfiler s165 §8 lo aparcó "aguas arriba en la composición del `valuesRef`".

La salida no es añadir un caso especial más. Es **hacer todas las fuentes uniformes** — la apuesta de Manuel: generalizar a costa de hacerlas universales.

---

## §2 · El modelo unificado — tres ejes, una abstracción

Una sola abstracción gobierna espacio, tiempo y dirección. La **señal** es el ladrillo (su slot en el DataPlane es el punto de encuentro). Todo lo demás son medios flexibles (coherente con `T-S176-SEÑAL-EJE`).

### §2.1 · Eje ESPACIO — registro abierto de fuentes/sumideros

El modo de una señal **no es un enum fijo** (ni 4 ni 6): es un **puntero a una entrada de un registro abierto** de adaptadores. Cada adaptador es uniforme y declara su **dirección**:

- **Cara ingress (fuente)** — escribe el valor en el slot. Familias: sensor/hardware (`mqtt-hw`), generador interno (motor/random/lab), grabación reproducida, transporte externo entrante (WSS de teléfono, WebRTC, AMQP, máquina externa…).
- **Cara egress (sumidero)** — consume el valor comandado del slot y lo lleva *al mundo*: actuador (con su dinámica), transporte saliente.

**Añadir una fuente o sumidero presente o futuro = registrar un adaptador. Cero cambio en el gate ni en el core.** Eso es el agnosticismo por diseño llevado al final. Los "tres generadores en conflicto" pasan a ser tres entradas del registro, gateadas igual que `mqtt-hw` o el slider; el conflicto desaparece porque desaparece la no-uniformidad.

### §2.2 · Eje TIEMPO — continuo vivo / grabado / programado

Bisagra canónica (`LRU_FUNDAMENTOS §5.4`):

> *"El vivo y el replay no son modos distintos del sistema — son dos puntos sobre un continuo temporal donde el sistema puede estar leyendo. Lo que cambia es el origen de las pistas (buffer vivo vs log persistente)."*

Por tanto **grabación/reproducción no es un subsistema aparte: es el registro de fuentes extendido en el tiempo.** Una pista grabada que se reproduce (REPLAY_SIM) **es otra fuente** que escribe el slot. Los **tres tiempos** del núcleo son tres familias de fuente sobre el mismo eje:

- **Vivo** — transporte/generador en tiempo real.
- **Grabado** — reproductor de log (caja negra, FDR, clase magistral).
- **Programado** — escenario/partitura (eventos con tolerancias temporales).

`REPLAY_MIXED` deja de ser un modo especial: es **arbitraje per-señal con una grabación como una de las fuentes** (unas señales del FDR grabado, otras del alumno en vivo).

### §2.3 · Eje DIRECCIÓN — bidireccionalidad (la mitad que falta)

Canónico: dimensión 2 de la señal (`observable / actuable / bidireccional`, `LRU_FUNDAMENTOS §2.1`); bucle P1 *perceptor → inteligencia → efector → percibir el efecto → iterar* (`§7`). OBSERVAR = lado sensor; INTERVENIR = lado actuador.

**Decisión registrada (Patrón 6, autocorrección s183):** el actuador **NO es "un sensor con dirección inversa"**. El `lru_actuator_model_s79.md §1.3` rechazó ese aplanamiento por cuatro razones: (1) semántica opuesta (valor medido vs comandado), (2) taxonomías de fallo distintas (16 kinds sensor vs 6 actuador), (3) el actuador tiene **dinámica de planta** (inercia, respuesta, saturación) que un sensor no, (4) gobierno: la inteligencia *escribe* a actuadores y *lee* de sensores.

**Pero el bus es compartido** (`§3.2`): el actuador escribe su valor ejecutado al slot del `feedbackSensorId` y los instrumentos lo leen como cualquier señal — **sin segundo bus**. Reconciliación: el sustrato es uniforme; la dirección no. El actuador es un **sumidero** (egress) + opcionalmente su feedback es una **fuente** (ingress) sobre el slot pareado. La tripla comandado → (dinámica) → ejecutado → feedback es estructura propia del lado actuador.

Estado material: el `SimService` **ya tiene** `sendActuatorCommand`, `ActuatorDef`, `feedbackSensorId`, `applyActuatorFault`, `updateActuators` (vía `activeRealm`). Falta declararlos en catálogo y exponerlos en UI.

### §2.4 · SEMÁNTICA — el Realm como partitura

El Realm declara los **papeles** (qué significa cada señal, su dirección, contrato de unidades y transporte, dinámica declarada) — las cinco dimensiones intrínsecas. Las fuentes/sumideros son **músicos** que ejecutan papeles. La sustitución es transparente porque el papel está en la partitura, no en el músico ("Realm como lector de partituras", s103). El escenario/procedimiento es **partitura temporal** (eventos esperados con tolerancias) = una fuente programada.

### §2.5 · SUPERFICIE — mesa de parcheo + mesa de mezcla

- **Mesa de parcheo** (EnlacesPanel, `LRU_ARQUITECTURA §3.2`): **exclusividad atómica por canal — un canal solo puede tener una fuente activa.** Es el árbitro per-señal. En el lado actuador, *"una sola mano en la palanca"* deja de ser regla de UX y pasa a ser **invariante de seguridad**.
- **Mesa de mezcla** (sesión multipista DAW, `LRU_FUNDAMENTOS §5`): el grabador (captura la línea multipista — 8 tipos de pista), el reproductor (alimenta canales desde grabación · es una fuente más), los overlays no destructivos y las DerivedTrack (pistas calculadas).

---

## §3 · Anclaje canónico — esto está reconocido, no inventado

| Pieza del modelo | Anclaje canónico | Paternidad |
|---|---|---|
| Modo per-señal = "quién produce el valor ahora" | Dimensión 6 · Origen contingente (runtime) | s53 / `LRU_ARQUITECTURA §5` |
| Una fuente activa por canal | Mesa de parcheo · exclusividad atómica | s53 / `LRU_ARQUITECTURA §3.2` |
| Fuentes externas agnósticas al transporte | CommsManager · 7 adaptadores uniformes | s24-s32 / `LRU_ARQUITECTURA §3` |
| Slot único como punto de encuentro | DataPlane "dónde viven los valores ahora" | fase 4 / capa 1 |
| Árbitro per-señal | ControlBus `SignalMode` (per-señal, s166+) | s166 |
| Bidireccionalidad sensor↔actuador | Dimensión 2 + P1 + actuator model | s67 / s79 / `§7` |
| Continuo vivo/grabado/programado | Sesión multipista · 3 tiempos · REPLAY_* | s22 / `LRU_FUNDAMENTOS §5` |
| Generalizar la trinidad de generadores | Alfiler s165 §4-§5 (familia Generador) | s165 |

El trabajo es **materializar** lo disperso bajo un modelo único, no fundar nada nuevo.

---

## §4 · El núcleo duro a diseñar — el contrato del adaptador

1. **Interfaz uniforme con dirección declarada.** Un adaptador declara: id de fuente, dirección (ingress/egress/bidi), y produce/consume valores para signalIds. Internas (generador, grabación) y externas (transporte) bajo el mismo contrato.
2. **Dos naturalezas que el contrato debe abrazar:** *push/subscribe* (transportes CommsManager, sensores) y *pull/tick* (generadores). El contrato uniforme no puede asumir solo una.
3. **Dos caras:** ingress escribe el slot; egress consume del slot hacia el mundo (con dinámica en actuadores). El recorder es ingress-desde-vivo→log; el player es ingress-desde-log→slot.
4. **Exclusividad como invariante.** Un escritor/comandante autoritativo por señal. En egress es propiedad de seguridad, no de UX.
5. **Desacoplar del run-state.** Motor y demoTick dependen hoy de Play/Stop global. Como fuentes uniformes, cada una produce cuando es autoritativa de ≥1 señal, sin interruptor global.
6. **Convergencia de los dos universos** sobre el DataPlane como única verdad (curar s157 sin regresión).

---

## §5 · Lo que se reconcilia y se retira

- **`Gen` desaparece** → sustituido por fuentes 1:1 contra el registro (`Real / Local / HwSim / Sim / Rnd / Lab / …` y las externas/grabadas/programadas). El gate per-señal pierde el escape permisivo `!== 'Gen'`: pasa a ser "modo → exactamente una fuente", uniforme.
- **Revertir la fusión de fuentes de s28** — cada generador recupera su `source` propio (`sim1` / `rnd` reintroducido / `lab`), para que el gate distinga.
- **El override de SignalLab** se reinterpreta como **una fuente** (`Lab`/`Gen·SignalLab`), no un mecanismo paralelo. La composición (un pipeline que lee otra señal) vive *dentro* de la fuente, no como capa global.
- **El motor se gatea** — deja de escribir `'sim1'` incondicionalmente; sujeto al árbitro como cualquier fuente (cierra la co-escritura, conecta T-S163/T-S164).
- **`demoTick` → fuente Rnd per-señal**, fundido en la familia de generadores; se desacopla del run-state.
- **RouterService (per-hwObj) se retira** — el árbitro per-señal (ControlBus generalizado de enum a `sourceId`) lo sustituye.
- **El default permisivo desaparece** — cada señal sim nace en una fuente concreta (`Sim`), no en `Gen`.

---

## §6 · Hilo de materialización — rebanadas reversibles (P11)

El frente de unificación en curso (T-S165) **se reencuadra como las primeras rebanadas de este norte**:

- **R3** (era Rnd→Gen + cabecera) → primer paso de la familia Generador per-señal + retirar el eje per-hwObj de la cabecera. Reabsorbe el debate del disparador Rnd: Rnd pasa a ser una fuente per-señal (no un modo per-hwObj), disolviendo la pregunta RouterService-vs-SimService.
- **R4** → inhibición de firmware (D-s182-FW) en el lado HwSim/actuador.
- **R5** → retirada total del eje per-hwObj (RouterService/RouterMode/HW_PERMISSIONS).

Orden y rebanadas finas se arbitran al materializar (D-s111-1: empírico antes de cada paso). Cada rebanada con dryRun + build verde, como hasta ahora.

**Horizonte explícito (contemplado, NO construido ahora):**
- El **grabador/reproductor completo** = el "viewer externo de Debug1", el gap mayor del proyecto. Se *cablea en el contrato* (un player es una fuente) pero no se construye.
- La **actuación sobre el mundo real** — con guardas de seguridad; reproducir comandos grabados sobre un actuador real es el rincón más peligroso.
- **Nuevos transportes** (WSS/WebRTC/AMQP/máquina externa) — adaptadores que se añaden sin tocar core.

---

## §7 · Tensiones y preguntas abiertas

- **Seguridad del egress.** Actuar sobre el mundo es otra clase de riesgo que leerlo. La exclusividad como invariante de seguridad; replay→actuador real con guardas. (Nueva, estructural, horizonte.)
- **Contrato push/pull.** Cómo abraza el contrato ambas naturalezas sin caso especial. (Núcleo del diseño.)
- **Dónde vive el árbitro.** ControlBus generalizado (enum→sourceId) vs nuevo `SourceArbiter`. Lean: ControlBus, ya es el hub per-señal.
- **Desacople del run-state.** Cómo cada generador produce sin el interruptor global Play/Stop.
- **Convergencia de universos.** El camino para que A y B lean la misma verdad (DataPlane) sin regresión.
- **`T-S174-VERTIDO-SIN-ESCALA`** (heredada) — escalado raw→unidades; entra cuando una fuente externa cruda alimente una señal con rango propio.
- **Granularidad sim/hw del id.** `${hwObjKey}/${puerto}` coincide con `sensor.id` en hw pero no en sim (`'N1_L'` vs `'sim1_engine/N1_L'`); el modelo per-señal debe usar el `sensor.id` canónico.

---

## §8 · Disciplina — brújula, no big-bang

Este documento es **brújula**, no plan de reescritura. El riesgo real del frente no es la arquitectura (sólida y reconocida) sino la **disciplina**: que un modelo tan grande se vuelva excusa para no enviar rebanadas pequeñas o para un big-bang. Por eso:

- **Reconocimiento + materialización** — se recogen piezas canónicas dispersas, no se funda.
- **Alfiler / P11** — se avanza por rebanadas reversibles, cada una con disparador concreto y build verde; nada anticipado sin trigger material.
- **Como un solo hilo** — no se forkea un segundo esfuerzo de unificación en paralelo (eso recrearía, a nivel meta, el problema de mundos paralelos que curamos).
- **Disputa activa** — anillo 2, no canónico; el núcleo lo absorbe cuando Manuel lo arbitre.

**Destilado propone, núcleo dispone, Manuel arbitra.**
