From 755dcc5c39c930a576e40ccafae31b90ac683f72 Mon Sep 17 00:00:00 2001 From: Sergio Date: Wed, 9 Sep 2026 22:10:59 +0000 Subject: [PATCH] =?UTF-8?q?SDD=2027:=20perfiles=20instalables=20=E2=80=94?= =?UTF-8?q?=20y=20la=20medici=C3=B3n=20de=20que=20los=20escritorios=20no?= =?UTF-8?q?=20traen=20base?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PROPUESTA, nada implementado. Escrito a pedido del usuario mientras se tapaba el hueco de upower. ⚠ EL HALLAZGO QUE LO MOTIVA, y es peor de lo que parecía: `targets.toml` ya avisaba que «kde/gnome/cosmic NO heredan base», pero la consecuencia no estaba escrita en ningún lado. Medida: **de los 27 paquetes del perfil `base`, la clausura de escritorio-kde alcanza 2**. Y comprobado contra el rootfs real de la imagen: NO hay `bash`, ni `sudo`/`doas`, ni `git`, ni `useradd`, ni `gpg`, **ni `dhcpcd`** — o sea que la imagen no sabe pedir una IP. Lo que sí hay (`ip`, `mount`, `fsck`) son APPLETS DE BUSYBOX: `/sbin/ip → ../bin/busybox`. O sea que la respuesta a «¿abrir un escritorio es como si base no existiera?» es **sí**. Y la causa es que hay DOS cosas llamadas base que nadie había distinguido por escrito: · base de ARRANQUE (`metal-rootfs`): arje-zero + busybox. La imagen la funde. Existe. · base de USERLAND (`[perfil.base]`): las 27. No la funde nadie. El documento separa las cuatro capas (piso / escritorio / extras / toolbox CLI), explica que un «metapaquete» YA EXISTE y se llama perfil, y nombra las tres cosas que le faltan para ser instalable: herencia entre perfiles, publicación al repo firmado, y un verbo que resuelva una LISTA y no un paquete. Y plantea la única decisión que no es de implementación: instalar un escritorio REPRODUCIENDO (coherente con que el canal no distribuya binarios, pero son horas en la máquina del usuario) o HIDRATANDO artefactos firmados (segundos, pero es entregar binarios y activa entera la obligación de licencias que se cerró hoy). La salida propuesta es la del ADR 0014: que existan las dos y que reproducir sea lo que hace verificable a hidratar. Nota de nomenclatura, porque el usuario preguntó: `.swm` NO es residuo del renombre — significa «Software Mutación» y describe lo que el fichero ES. El verbo ya es el correcto, `takana install`. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV --- ...27-perfiles-instalables-y-el-instalador.md | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 docs/27-perfiles-instalables-y-el-instalador.md diff --git a/docs/27-perfiles-instalables-y-el-instalador.md b/docs/27-perfiles-instalables-y-el-instalador.md new file mode 100644 index 00000000..53bd995c --- /dev/null +++ b/docs/27-perfiles-instalables-y-el-instalador.md @@ -0,0 +1,129 @@ +# SDD 27 — Perfiles instalables: del rootfs hidratado al `takana install escritorio-kde` + +> **Estado: PROPUESTA.** Nada de lo de acá está implementado. Lo que sí está medido es el punto de +> partida, y las mediciones llevan fecha 2026-09-09. Escrito a pedido del usuario mientras se +> cerraban los huecos de la imagen KDE. + +## 0. La pregunta + +Hoy sabemos construir. Sabemos hidratar un rootfs y meterlo en una imagen que arranca. Lo que no +existe es **instalar un escritorio como una unidad**: hoy «KDE» es una lista dentro de un fichero +del repo, no algo que un usuario pueda pedir. + +Y hay una pregunta previa que el usuario formuló mejor de lo que estaba escrito en ningún lado: + +> *el toolbox CLI es general, que sea piso userland del sistema siempre. los extras son igual +> instalaciones, depende de quién instale qué.* + +Eso son **tres capas distintas**, y hoy el repo las mezcla en una sola lista por escritorio. + +## 1. Lo medido: hoy los escritorios NO heredan la base + +`docs/state/targets.toml` declara un perfil `base` de **27 paquetes**: `bash`, `git`, `sudo`, `doas`, +`util-linux`, `shadow`, `kbd`, `procps-ng`, `iproute2`, `iputils`, `dhcpcd`, `e2fsprogs`, +`dosfstools`, `gnupg`, `ca-certificates`… El fichero ya avisa que «kde/gnome/cosmic **NO** heredan +base», pero la consecuencia no estaba escrita. Medida: + +> **De los 27 paquetes de `base`, la clausura de `escritorio-kde` alcanza 2.** + +Y comprobado contra el rootfs real de la imagen KDE (`kde-qemu-rootfs`): + +| se busca | está | +|---|---| +| `bash`, `git`, `sudo`, `doas`, `dhcpcd`, `useradd`, `gpg` | **NO** | +| `ip`, `mount`, `fsck` | sí, pero **son applets de busybox** (`/sbin/ip → ../bin/busybox`) | +| `ssh`, `curl` | sí, de rebote: entran por la clausura de KDE, no por `base` | + +⇒ **Sí: abrís el escritorio y es como si `base` no existiera.** No hay shell de verdad (busybox `sh`, +no bash), no hay `sudo` ni `doas`, no hay `git`, y **no hay `dhcpcd`** — o sea que la imagen no sabe +pedir una IP salvo lo que haga busybox. Lo que sí hay es el **otro** base: `arje-zero` como PID1 más +busybox, que es lo mínimo para arrancar. Son dos cosas distintas con el mismo nombre coloquial: + +- **base de arranque** (`metal-rootfs`): arje-zero + busybox + kernel. La imagen la funde por + hardlinks. Existe. +- **base de userland** (`[perfil.base]`): las 27. **No la funde nadie.** + +Esto no es un bug de una imagen: es que la composición entre perfiles **no está definida**. + +## 2. Las tres capas que hay que separar + +| capa | qué es | quién decide | hoy | +|---|---|---|---| +| **piso** | userland siempre presente: shell, red, usuarios, paquetes, `git` | la distro | existe como `[perfil.base]`, no lo hereda nadie | +| **escritorio** | KDE / GNOME / COSMIC / sway y lo que los hace ser ellos | la distro | existe como perfil, es lo único que se materializa | +| **extras** | lo que cada quien instala encima | el usuario | no existe como operación | + +Y hay una cuarta que el usuario nombró y conviene no perder: **el toolbox CLI**. Hoy hay +**652 recetas selladas que ninguna imagen alcanza** — 361 Go, 214 Rust, 67 C — y son casi todas +herramientas de línea de comandos. Ya construidas, ya reproducibles: **coste de build cero, sólo +declararlas**. Si el toolbox es piso, va en la capa 1 y no en cada escritorio. + +## 3. Un «metapaquete» ya existe, y se llama perfil + +`[perfil.escritorio-kde]` con sus 49 raíces **es** el metapaquete: una lista de nombres cuya +clausura define qué entra. Lo que le falta para ser instalable son tres cosas concretas: + +1. **Herencia.** Un perfil tiene que poder decir `hereda = ["base"]` en vez de repetir la lista. Hoy + los cuatro escritorios repiten `dejavu-fonts`, `desktop-file-utils` y las `*-shared` de runtime, + y ya se vio lo que pasa: se añade a uno y se olvida en los otros. +2. **Publicación.** `targets.toml` vive en el repo y es de tiempo de build. Para que el instalador + lo use tiene que salir al repositorio firmado como un objeto más, igual que un `.swm`. +3. **Un verbo.** `takana install escritorio-kde` no existe: `install` resuelve **un paquete** por + nombre en el índice. Instalar un perfil es resolver una LISTA y aplicar su clausura. + +## 4. La decisión de fondo del instalador: reproducir o hidratar + +Ésta es la única pregunta que no es de implementación, y conviene decidirla antes de escribir código. + +**Hoy el canal de paquetes NO distribuye binarios.** `pack` produce un `.swm` —una receta de +transformación sobre fuente pública— e `install` **reproduce construyendo**, con cache-hit del +corpus. Es coherente con todo el diseño: lo que viaja es la receta, no el binario. + +- **Reproducir** un escritorio entero en la máquina del usuario son **horas** de compilación (KDE son + 301 nodos; Qt y Firefox solos ya son la mayor parte de una tarde). Coherente y honesto, pero + inaceptable como experiencia de instalación. +- **Hidratar desde artefactos firmados** es lo que ya hace `hydrate-profile.py`: segundos, porque + son hardlinks contra el store. Pero eso **es entregar binarios**, y activa entera la obligación de + licencias que se cerró el 2026-09-09 (`scripts/licencias-rootfs.sh`, que veta si un paquete no + declara licencia). También activa la pregunta de confianza: el ADR 0014 ya dice que el cuerpo es + inmutable y direccionado por contenido, así que **el origen no necesita confianza** — lo que se + firma es la raíz, no el servidor. + +**La salida no es elegir una: es que las dos existan y el usuario elija**, igual que el ADR 0014 hizo +con los orígenes. Instalar por hidratación es el camino normal; reproducir es el camino auditable, y +que exista es lo que hace verificable al primero. Lo que hay que definir es el **default** — y ahí la +respuesta razonable es hidratar, porque el que quiere auditar puede reproducir cuando quiera y +comparar hashes, que es exactamente lo que `selfhost-verify` ya hace. + +## 5. La imagen y el instalador son el mismo problema con dos salidas + +Hoy hay dos caminos que hacen casi lo mismo y no se hablan: + +- **Imagen**: perfil → `hydrate-profile.py` → rootfs → `install-image-efi.sh` → `.img` que arranca. +- **Instalador**: TUI + `base-system`, que instala sobre un disco. + +Si un perfil es publicable e instalable, los dos son **el mismo verbo con distinto destino**: uno +escribe a una imagen, el otro a una partición. Vale la pena unificarlos antes de que diverjan más: +hoy ya divergieron una vez —los `hydrate-*.sh` por escritorio contra `targets.toml`, con 21 paquetes +declarados que no llegaban a la imagen de GNOME y 17 a la de COSMIC— y costó encontrarlo. + +## 6. Sobre el nombre del paquete (`.swm` vs `.tkn`) + +`.swm` **no es residuo del renombre**: significa «Software Mutación» y describe lo que el fichero +es —una mutación reproducible sobre una fuente—, no la marca. Renombrarlo a `.tkn` sería alinear +marca y formato, y es defendible, pero **no lo pide ninguna inconsistencia técnica**. Si se hace, +es una decisión de ADR y con la misma disciplina que el renombre de hoy: hay que mirar si la +extensión entra en algún hash o en el índice del repo antes de tocarla. + +El verbo, en cambio, ya es el correcto: **`takana install`**. + +## 7. Orden propuesto + +1. **Herencia entre perfiles** (`hereda = [...]`) y hacer que los cuatro escritorios hereden `base`. + Es lo más barato y arregla un fallo real: hoy los escritorios no traen shell ni red. +2. **Decidir el piso**: qué del toolbox CLI de 652 entra en `base`. Coste de build cero. +3. **Publicar perfiles** al repositorio firmado. +4. **`takana install `**, hidratando por defecto y con `--reproduce` como camino auditable. +5. **Unificar imagen e instalador** sobre ese verbo. + +Los pasos 1 y 2 se pueden hacer ya y no dependen de ninguna decisión de arquitectura.