docs(mirada): SDD — arquitectura Cerebro↔Cuerpo y los 6 crates
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
1 archivos · +81 −26
- crates/modules/mirada/SDD.md +81 −26
diff --git a/crates/modules/mirada/SDD.md b/crates/modules/mirada/SDD.md
index 8d02352..96be630 100644
--- a/crates/modules/mirada/SDD.md
+++ b/crates/modules/mirada/SDD.md
@@ -1,40 +1,95 @@
-# modules/mirada/ — Compositor Wayland
+# modules/mirada/ — Compositor Wayland (carmen)
-**Propósito.** Un compositor Wayland teselante con aislamiento de
-clientes (sobre `arje-incarnate`) y delegación de regiones. El cerebro
-espacial —cómo se reparte la pantalla— se mantiene puro y aislado de
-Wayland para poder probarlo sin un servidor gráfico.
+**Propósito.** Un compositor Wayland teselante. La decisión de diseño
+central es partirlo en dos procesos, el **Cerebro** y el **Cuerpo**:
+
+- **El Cuerpo** (`mirada-compositor`, sobre `smithay`) habla Wayland con
+ los clientes, posee el hardware (DRM/GPU/libinput) y compone las
+ superficies reales. Los píxeles nunca salen de él — composición
+ *zero-copy*.
+- **El Cerebro** (la app `mirada`, GPUI) decide *dónde* va cada ventana
+ —pura aritmética de rectángulos— y orquesta el escritorio: layouts,
+ atajos, focos, escritorios virtuales.
+
+Los dos hablan por un socket Unix con un contrato mínimo de enums. Así,
+toda la lógica espacial es agnóstica de Wayland y se prueba sin un
+servidor gráfico; el Cuerpo queda reducido a "habla el protocolo y
+ejecuta operaciones de geometría".
## Crates
-| crate | tipo | rol |
-| --------------- | ---- | ------------------------------------------------------------ |
-| `mirada-layout` | lib | Motor de teselado: `Rect`, modos de layout, `Workspace` (ventanas, foco) |
+| crate | tipo | rol |
+| ------------------ | -------- | ---------------------------------------------------------------------- |
+| `mirada-layout` | lib | Motor de teselado: `Rect`, modos de layout, `Workspace` (ventanas, foco) |
+| `mirada-protocol` | lib | Contrato Cerebro↔Cuerpo: `BrainCommand`/`BodyEvent` + marco de cable |
+| `mirada-brain` | lib | Orquestador del escritorio: `Desktop`, eventos→comandos, atajos |
+| `mirada-link` | lib | Transporte: el socket Unix con hilo lector + canal |
+| `mirada-body` | lib | Contabilidad del Cuerpo: `BodyState`, traduce comandos a `BodyOp` |
+| `mirada` (app) | bin/GPUI | El Cerebro: ventana que tesela el escritorio y manda geometría |
+
+## Flujo
-## mirada-layout
+```text
+ mirada-layout ─► mirada-protocol ─► mirada-brain ─► [app mirada · Cerebro]
+ │ │
+ │ mirada-link
+ │ │
+ └────► mirada-body ─► [mirada-compositor · Cuerpo]
+```
-- `Rect` + `split` — reparto exacto de píxeles (sin pérdidas).
-- `LayoutMode` — `MasterStack`, `Monocle`, `Grid`, `Columns`; `tile`
- calcula el rectángulo de cada ventana.
-- `Workspace` — ventanas en orden de teselado, foco cíclico, reordenado
- (`move_focused_forward/backward`) y `layout` que resuelve la geometría.
-- Determinista: misma pantalla + mismas ventanas → misma distribución.
+- El Cuerpo reporta hardware/clientes con `BodyEvent` (salida conectada,
+ ventana abierta, atajo pulsado…).
+- El Cerebro (`Desktop::on_event`) recalcula y emite `BrainCommand`
+ (`Place` con la geometría completa, `Close`, `GrabKeys`…).
+- El Cuerpo (`BodyState::apply`) traduce cada comando a `BodyOp`
+ concretas y sólo emite lo que de verdad cambia.
+
+## Detalle por crate
+
+- **`mirada-layout`** — `Rect` + `split` (reparto exacto de píxeles),
+ `LayoutMode` (`MasterStack`/`Monocle`/`Grid`/`Columns`), `Workspace`
+ con foco cíclico y reordenado. Determinista.
+- **`mirada-protocol`** — `WindowPlacement`, los enums `BrainCommand` y
+ `BodyEvent`, el marco `postcard` con prefijo `u32` LE
+ (`write_frame`/`read_frame`, guard `MAX_FRAME`) y el puente
+ `placements(&Workspace, Rect)`.
+- **`mirada-brain`** — `Desktop`: salidas, 9 escritorios virtuales,
+ registro de ventanas. `on_event(BodyEvent) -> Vec<BrainCommand>`;
+ `DesktopAction` + mapa de teclas estilo *tiling WM* (`Super`).
+- **`mirada-link`** — `Link<Out,In>` sobre socket Unix; hilo lector de
+ fondo + canal `mpsc` para sondeo no bloqueante. `BrainLink`/`BodyLink`,
+ `connected_pair` (socketpair), `connect`/`listen` por ruta.
+- **`mirada-body`** — `BodyState`: salidas + superficies; `apply` traduce
+ `BrainCommand`→`BodyOp` (idempotente), los mutadores del backend
+ devuelven los `BodyEvent` a mandar. Ejemplo `headless`: un Cuerpo sin
+ gráficos guiado por stdin para ejercitar el bucle entero.
+- **`mirada` (app)** — envuelve `Desktop` y lo pinta (barra de
+ escritorios + modo + foco, lienzo teselado). Con `MIRADA_SOCKET`
+ conecta a un Cuerpo; sin él corre en **simulación** (ventanas
+ sintéticas, teclado de la propia ventana).
## Dependencias
-- `mirada-layout` ← sólo `serde`. `#![forbid(unsafe_code)]`.
-- Cero Wayland, cero `smithay` — ese acoplamiento vive en los crates de
- integración pendientes.
+- Todos los `lib` con `#![forbid(unsafe_code)]`. Cero Wayland, cero
+ `smithay` en los seis crates de arriba.
+- El acoplamiento a hardware vive sólo en `mirada-compositor`
+ (pendiente).
## Estado
-`mirada-layout` implementado y verde (22 tests). **Pendiente** (la capa
-que toca hardware/protocolo, no verificable en modo desatendido):
+Implementado y verde: `mirada-layout` (22 tests), `mirada-protocol`
+(9), `mirada-brain` (17), `mirada-link` (7), `mirada-body` (13), y la
+app `mirada` (compila; verificación visual manual).
+
+**Pendiente** — la capa que toca hardware/protocolo, no verificable en
+modo desatendido:
-| crate pendiente | rol |
-| ------------------ | ---------------------------------------------------- |
-| `mirada-compositor`| integración `smithay`: superficies, buffers, salidas |
-| `mirada-input` | teclado/ratón, atajos, asignación de foco |
-| `mirada-sandbox` | aislamiento de clientes sobre `arje-incarnate` |
+| crate pendiente | rol |
+| ------------------- | --------------------------------------------------------- |
+| `mirada-compositor` | el Cuerpo: `smithay` — superficies, buffers, salidas, DRM |
+| `mirada-input` | libinput → teclado/ratón, intercepción de atajos |
+| `mirada-sandbox` | aislamiento de clientes sobre `arje-incarnate` |
-CRIU (congelar/restaurar ventanas) queda anotado como futuro.
+El Cuerpo reusará `mirada-body` para su contabilidad y `mirada-link`
+para el cable; sólo le falta el *backend* `smithay`. CRIU
+(congelar/restaurar ventanas) queda anotado como futuro.