runbook cosmic: el cuarto escritorio, escrito mientras se hace

Deja asentado por qué COSMIC no se parece a KDE ni a GNOME (no hay torre de C
debajo: la primera receta salió estática y con cero NEEDED), la tabla de lo que
se hereda gratis de mirada/GNOME, el pin en lockstep epoch-1.5.0, y los seis
gotchas medidos — entre ellos que start-cosmic es bash de verdad (mapfile, [[ ]],
${!var}) y que bash no lo pide ningún [deps], así que a la imagen no lo trae
nadie por accidente.

Y el porqué del orden de ataque, que NO es el orden de arranque: cosmic-bg antes
del panel para que «pinta el fondo pero no el panel» separe la capa de UI del
transporte.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-03 10:45:39 -04:00
co-authored by Claude Opus 5
parent bc6f664650
commit ebe63cbf92
+116
View File
@@ -0,0 +1,116 @@
# Runbook — COSMIC, el cuarto escritorio
Estado al 2026-08-03: **campaña abierta.** Tres piezas selladas (`cosmic-session`, `cosmic-icons`,
`cosmic-bg`) y el compositor en construcción. Este documento se escribe mientras se hace, no después.
COSMIC es el escritorio de System76, en Rust sobre **smithay** (compositor) e **iced/libcosmic**
(clientes). Es el cuarto de hammer, tras [mirada](mirada-usb-nvidia.md),
[KDE Plasma 6](kde-qemu-desktop.md) y [GNOME](gnome-qemu-desktop.md).
## Por qué NO se parece a los dos anteriores
KDE y GNOME costaron lo que costaron por la misma razón: una torre de C con Qt o
glib/GObject/introspección debajo, donde cada capa se paga entera antes de ver un píxel. COSMIC no
tiene esa torre. La primera receta —`cosmic-session`— salió **a la primera y sin una sola dep en C**:
ELF estático, cero `NEEDED`.
Lo que sí hereda es lo que ya está pago:
| lo que COSMIC necesita | de dónde sale | costo |
|---|---|---|
| las deps en C de smithay (drm, gbm, seat, input, udev, xkb, pixman) | `mirada-compositor`, que ya es un compositor smithay de este lab | **cero** — misma lista |
| `libdisplay-info` + `hwdata` | copiadas byte a byte de la cola GNOME | **cero** — mismo hash, artefacto ya sellado |
| `bash`, `dbus-run-session`, `hicolor-icon-theme`, mesa-llvmpipe | corpus | cero |
| el andamiaje de arranque en QEMU (`run-qemu-desktop.sh`, base rootfs, console-getty, screendump) | campañas KDE/GNOME | cero |
La deuda propia que sí trae, y que ninguna de las otras campañas tocó, es la del **unwinder de la std
de rustc** cuando el enlace no es estático — la misma que ya está documentada para las recetas Cargo
del corpus.
## El pin es de la SUITE, no de cada paquete
COSMIC versiona **todos** sus repos en lockstep con el tag `epoch-N`. Comprobado repo por repo: los
doce componentes están en `epoch-1.5.0`.
**No mezclar epochs entre piezas.** Comparten protocolos propios (`cosmic-protocols`) y el formato de
configuración (`cosmic-config`); un desajuste ahí no da error de compilación, da un escritorio que
arranca y no se entiende consigo mismo — que es mucho más caro de diagnosticar.
## La cola
`recipes/incoming-cosmic/`, aislada (otro agente comparte el repo; nunca `git add -A`).
Las deps se resuelven **hermano → padre**: desde `incoming-cosmic/` se ven las recetas de
`recipes/`, pero **no** las de `incoming-gnome/` ni `incoming-kde/`. Por eso `libdisplay-info` y
`hwdata` entran copiadas. Y copiar es gratis de verdad, no «casi»: el ArtifactHash no depende de la
ruta de la receta, así que un fichero idéntico con deps que resuelven a lo mismo da **el mismo hash**
⇒ cache hit sobre el artefacto que ya existe. Se verificó antes de copiar (`b3:260f0519`,
`b3:bdc36cf9`), no después.
## Qué levanta la sesión, y por lo tanto el orden de ataque
`cosmic-session/src/main.rs` es la lista autoritativa —el mismo método que cerró la capa JS de GNOME:
*leé el fichero donde el programa declara lo que arranca, no lo descubras de a uno*:
```
cosmic-comp → cosmic-notifications · cosmic-panel · cosmic-app-library
→ cosmic-launcher · cosmic-workspaces · cosmic-osd · cosmic-bg · cosmic-idle
```
Más `cosmic-settings-daemon` y `xdg-desktop-portal-cosmic` fuera de esa lista.
| pieza | estado | hash |
|---|---|---|
| `cosmic-session` | ✅ sellado | `b3:81f02351` |
| `cosmic-icons` | ✅ sellado (671 SVGs) | `b3:94d06f77` |
| `cosmic-bg` | ✅ sellado | `b3:1ecca9c1` |
| `cosmic-comp` | 🔨 en construcción | — |
| el resto | pendiente | — |
**El orden no es el de la lista de arranque.** `cosmic-bg` va antes que el panel a propósito: habla
Wayland con `smithay-client-toolkit` y **no toca libcosmic ni iced**, mientras que panel, launcher,
osd y workspaces son todos clientes de iced. Con el fondo sellado, «pinta el fondo pero no el panel»
separa la capa de UI del transporte; sin él, las dos preguntas llegan juntas.
## Gotchas medidos (no previstos)
1. **`cargo rustc --` exige UN target.** La fase compile del lab pasa flags tras el `--`, y cualquier
paquete con binario + lib + ejemplos corta con «extra arguments to `rustc` can only be passed to
one target». Se arregla con `flags = ["--bin", "<nombre>"]`. Le pasa a cosmic-comp y a cosmic-bg
(workspace con `config/`), y le va a pasar a casi todos: **ponelo desde el principio.**
2. **`start-cosmic` es bash de verdad, no sh.** Usa `mapfile`, `[[ ]]` y expansión indirecta
`${!var}`; con el busybox del rootfs no arranca. `bash` ya está en el corpus, pero **tiene que
entrar en la imagen** — y no lo pide ningún `[deps]`, así que no lo va a traer nadie por accidente.
Lo mismo con `dbus-run-session` (de `dbus`), que es lo que el script exec-uta al final.
3. **`rust-toolchain.toml` con `channel = "1.93"` es inerte acá** — es una perilla de rustup, y el
sandbox tiene el rustc de Alpine (1.96) pelado. Conviene saberlo antes de «arreglarlo».
4. **`cosmic.desktop` existe DOS veces** (en cosmic-session y en cosmic-comp) con contenido distinto
y en la misma ruta. El de cosmic-comp es el de la «bare session» y apunta a `/usr/bin/cosmic-service`,
que vive en la rama de systemd que acá no va. Se instala **sólo** el de cosmic-session; si entraran
los dos, quién gana depende del orden de hidratación y el que pierde es el bueno.
5. **`libsystemd` no es systemd.** La feature `default = ["systemd"]` de cosmic-comp trae el crate
`libsystemd`, que es una **reimplementación en Rust** del protocolo, no un binding a la C. Y
`logind` habla `org.freedesktop.login1`, que acá lo sirve `arje-logind-compat`. No hay que apagar
nada: el nombre de la feature es el del protocolo, no el del programa que lo contesta.
6. **Las features de smithay que asustan no cuestan deps de build**: `backend_vulkan` (crate `ash`),
`backend_x11` (`x11rb` con `dl-libxcb`) y `xwayland` cargan todo por **dlopen**. Son deuda de
RUNTIME —libxcb y vulkan-loader viven hoy sólo en la cola KDE—, no un muro de compilación.
## Cómo se construye
```sh
cd ~/hammer
./target/release/hammer --store store hash recipes/incoming-cosmic/<pieza>.toml # dry-run, ~2ms
./target/release/hammer build recipes/incoming-cosmic/<pieza>.toml --store store
```
## Lo que falta, en orden
1. Cerrar `cosmic-comp`. Es el gate: sin compositor no hay escritorio que probar.
2. El primer cliente de iced (`cosmic-panel`), que es la pregunta abierta de verdad — libcosmic con
`winit`/`wgpu` puede pedir más de lo que pide cosmic-bg.
3. `cosmic-settings-daemon`, `cosmic-launcher`, `cosmic-app-library`, `cosmic-notifications`,
`cosmic-osd`, `cosmic-workspaces-epoch`, `cosmic-idle`.
4. Imagen QEMU con `bash` + `dbus-run-session` + `hicolor-icon-theme`, y **validar CON PANTALLA**
(`DISP=gtk` + `screendump`, contar colores distintos) — regla heredada de KDE y GNOME.
5. `xdg-desktop-portal-cosmic` y `cosmic-greeter`, que son de la etapa siguiente.