# SDD 20 — El catálogo de lo que falta: hasta PUBLICABLE y hasta COMPLETA Escrito 2026-08-07, a pedido del usuario: «el catálogo de todo lo que falta hasta decir *la distro está publicable*, y lo de más hasta *la distro está completa*». Este documento es el **inventario**. El [SDD 21](21-manual-del-piloto.md) es el **manual de a pie**: qué tiene que hacer el usuario, en qué orden, en cada una de las tres etapas. Todo lo de acá está **medido contra el repo el 2026-08-07**, no estimado de memoria. Donde hay un número, hay un comando que lo produjo. --- ## Los dos codos, y por qué están donde están - **PUBLICABLE** = un extraño puede descargarla, instalarla, usarla y actualizarla, y nosotros estamos en regla al dársela. **No** significa que tenga todo lo que uno querría. - **COMPLETA** = tiene lo que una persona espera de un sistema de escritorio para su día a día, sin tener que salir a buscar nada fuera. La distancia entre los dos codos es enorme y **el orden importa**: casi todo lo caro (navegador, ofimática) está DESPUÉS del primer codo, y casi todo lo bloqueante (legal, claves, actualización) está ANTES. La trampa clásica es invertirlos — pasarse meses con el navegador y descubrir el día del anuncio que no se puede publicar. --- # PARTE I — Hasta «la distro está PUBLICABLE» ## I.1 Estado de construcción: esto ya está casi cerrado Medido con `docs/state/build-state*.json` (el grafo, no recuento a mano): | frente | nodos | sellados | en deuda | |---|---:|---:|---:| | corpus | 771 | 759 | **12** | | KDE | 968 | 952 | 12 | | GNOME | 853 | 840 | 13 | | COSMIC | 818 | 806 | 12 | Los perfiles `base` (51 nodos) y `cli` (74 nodos) están **al 100%, deuda 0**. KDE cierra 162/162. **La deuda real es una sola lista de 12 recetas, compartida por todos los frentes** (por eso el número se repite: es el mismo agujero visto desde cuatro grafos): ``` gtk4 libadwaita gtksourceview gtk4-hello adwaita-hello sourceview-hello hammer-edit mirada-compositor mirada-greeter dwarves llimphi-counter wlr-randr ``` > ### ⚠️ CORREGIDO EL MISMO DÍA, MIDIENDO CONTRA EL WORKER > La primera versión de esta sección decía que las 12 «fallan en el worker por su rootfs: `python > OSError` en meson, `find_package` en cmake» y que el arreglo era declarar las herramientas en > `[deps]`. **Se probó y es falso.** cmake y meson corren perfectamente en el worker. Las causas son > **cuatro, distintas**, y ninguna es el rootfs. Se descubrió al construirlas de verdad en vez de > heredar el diagnóstico. **(a) Seis están bloqueadas por el muro del PIC — y el frente GNOME ya lo venció por otro camino.** `gtk4` del corpus es `link = "static"` y enlaza `libfontconfig.a`, que tiene **1122 reubicaciones no-PIC**: el enlace produce **13 032 errores** `relocation R_X86_64_64 cannot be used against local symbol`. No es una receta rota, es una imposibilidad estructural. Mientras tanto `recipes/incoming-gnome/gtk4.toml` —`link = "dynamic"` con las deps `-shared`— **está sellada**, y con ella `libadwaita` y `fontconfig-shared`. ⇒ La cadena del corpus (`gtk4`, `libadwaita`, `gtksourceview`, `gtk4-hello`, `adwaita-hello`, `sourceview-hello`, `hammer-edit`) es un **duplicado superado** de la cadena dinámica de GNOME. Cerrarla no es «construirla»: es decidir si se **promueven las sombras `-shared` al corpus**, porque la resolución de deps es hermano→padre y una receta del corpus no ve a las de `incoming-gnome`. **Es una decisión de arquitectura, no una tarea** — y hay un aviso registrado de que promover a ciegas hace que variantes homónimas pisen recetas canónicas. **(b) `wlr-randr` — ✅ CERRADA HOY.** Le faltaban dos deps: `python3` (porque **meson es un script de Python**; sin intérprete la fase muere con exit 127, que se lee como «meson no está») y `libffi` (que la receta no usa: lo exige `wayland-client.pc` en su `Requires`). Auditadas las 1141 recetas, era **la única** con meson y sin python3. **(c) `dwarves` — frente propio, no deuda.** Falla porque nuestro `elfutils` entrega **sólo libelf**, deliberadamente: libdw arrastra argp/obstack/fts, «lo verdaderamente difícil en musl». Y no se arregla ampliando `elfutils`, porque de él cuelga **el kernel que ya reproduce bit a bit**; el camino correcto es una receta aparte `elfutils-libdw`. Sin urgencia: ningún perfil lo pide y el kernel desactiva `DEBUG_INFO_BTF` explícitamente por su ausencia. Se desbloquea cuando se quiera sched-ext. **(d) `mirada-compositor`, `mirada-greeter`, `llimphi-counter` — HUB-ONLY estructural.** Su `source` es `gitea@git.tawasuyu.net:...` por SSH y **el worker es sin secretos por diseño**. No es un fallo. `llimphi-counter` ni siquiera llega a construir: su `commit` es literalmente ceros, con el comentario «fijar al commit real» — es una receta sin terminar, y es de tawasuyu. ### Y el hallazgo de fondo: nadie las estaba intentando El bucle del worker recorre `QUEUES="recipes/incoming recipes/incoming-go recipes/incoming-clib recipes/incoming-gnome-onda1 recipes/incoming-gnome-onda2 recipes/incoming-gnome recipes/incoming-kde"` — **el corpus (`recipes/`) no está en la lista**. Las 12 nunca se habían intentado en el worker. Buena parte de «la deuda» era de encolado, no técnica. ## I.2 🚨 Lo legal — bloqueante ### Licencias: de 0 a 228 de 1141 hoy, faltan 913 El 2026-08-07 se midió: **0 de 1141 recetas** declaraban licencia. (El informe previo decía «5 de 771»; los dos números estaban mal — los «5» eran falsos positivos de `grep license`: el paquete `addlicense`, el paquete `cargo-bundle-licenses`, una línea de `install` y un comentario.) Ese mismo día se hizo lo estructural: - Campo `license` en la receta, **fuera de `hash_inputs`** ⇒ se puebla sobre recetas ya selladas sin mover un solo `ArtifactHash`. Verificado en 40 recetas: 40 hashes idénticos, 0 cambiados. - `scripts/licencias.sh` mide de verdad (cuenta el campo, no la palabra) y siembra desde una tabla curada. - 228 sembradas: todo el toolchain, la base C, las gráficas, GNOME/GTK, Qt, KDE Frameworks y Plasma. **Falta**: las 913 restantes, casi todas CLIs Go/Rust importados en masa. Buena noticia: **ésas sí se automatizan con evidencia real y sin red** — `Cargo.toml` trae el campo `license` y los módulos Go traen su `LICENSE` en el árbol. El cierre definitivo es capturarlo en la **fase de fetch**, que ya descarga y extrae cada tarball. ⚠️ **La regla que no se rompe**: no se rellena a ojo. Declarar mal una licencia es peor que dejarla vacía — convierte un hueco visible en una afirmación falsa. Concretamente se descartó el atajo «`k*` = KDE ⇒ LGPL»: en este catálogo `kail`, `kind`, `ko`, `kopia`, `krew`, `kustomize`, `kyverno` y toda la familia `kube*` son herramientas Go sin relación con KDE. ### El texto de la licencia dentro del paquete La GPL obliga a acompañar el binario del texto. **Dónde se inyecta decide el precio**: en la fase `install` de la receta re-hashearía las 1141 (las fases SÍ entran al hash); en **`hammer pack`** es gratis, porque pack es aguas abajo del `ArtifactHash`. Va en pack. ### Espejo de fuentes — la obligación que más se malentiende La GPL no pide «que el código exista en internet»: pide que **quien recibe el binario pueda obtener de nosotros la fuente correspondiente**. Hoy las recetas apuntan a URLs de terceros que se caen. Acá estamos inusualmente bien parados: cada receta pinea `tarball` + `sha256`, así que el espejo es mecánico **y encima verificable**. Pero tiene que existir **antes de la primera descarga**. ### Marcas Redistribuir Firefox con su nombre y logo exige cumplir la política de marca de Mozilla (por eso Debian tuvo Iceweasel). Decidir por adelantado: cumplir o rebrandear. **No bloquea el primer lanzamiento** si se sale sin navegador propio. ### La licencia de hammer — ✅ ya está `LICENSE` en la raíz y `license = "MIT"` en `Cargo.toml`. *(El SDD 19 decía que faltaba; era falso.)* ## I.3 Infraestructura pública 1. **Espejo de paquetes e imágenes.** Dimensionado real: el store son 128 G, pero **el 79% es información de depuración** ⇒ separando `-debug` en paquetes aparte el espejo baja a **~30 G**. 2. **Cadena de firma de release.** Hoy hay firma de índice. Falta el nivel de arriba: **clave raíz fuera de línea**, claves de firma rotables y un procedimiento escrito para cuando se filtre una. Firma sin gestión de claves es teatro. 3. **Evidencia de reproducibilidad publicada.** Es *el* diferenciador: publicar junto a cada imagen los `ArtifactHash` de toda su clausura, para que un tercero reconstruya y compare. Es lo que convierte «somos reproducibles» en un hecho comprobable por un extraño. 4. **Respuesta a seguridad**: un canal para reportes y —lo importante— la capacidad **demostrada** de empujar una actualización y que llegue. Ensayar el ciclo completo con un CVE de mentira. ## I.4 Que se pueda instalar y usar 1. **Imagen instalable validada en METAL**, no sólo en QEMU. Está a medio camino: el USB de KDE en metal está **en curso** y falta re-quemarlo. Reglas ya pagadas caro: validar imágenes de escritorio **con pantalla**, nunca sólo `-nographic`; `/dev/console` es el serial, así que cada capa debe escribir a `/dev/tty0`; y **nunca quemar a un NVMe**. 2. **Matriz de hardware honesta**: en qué se probó y en qué no. Vale más «probado en estas 3 máquinas» que «debería funcionar». 3. **Actualización en sitio probada de verdad**: instalar N, actualizar a N+1, y que arranque. Y **rollback**, que con un store direccionado por contenido debería ser barato — es la ventaja natural de esta arquitectura y conviene que sea función de primera clase. 4. **Documentación mínima**: instalar, gestionar paquetes, reportar un fallo. 5. **Sitio de descarga** con sumas y firmas, y las instrucciones para verificarlas. ## I.5 Lo que falta de sistema para que no se note pobre Presente ya: `networkmanager`, `pipewire`, `wireplumber`, `polkit`, `seatd`, `upower`, `tzdata`, `fontconfig`. **Falta**: `cups` (impresión), `bluez` (bluetooth), y tipografías/locales revisados. --- # PARTE II — De PUBLICABLE a «la distro está COMPLETA» Acá está el trabajo grande, y conviene decir los tamaños en voz alta. ## II.1 WMs Wayland ligeros — barato, alto retorno **Medido: no hay ninguno.** De toda la familia sólo existen `foot` (terminal) y `mako` (notificaciones). Falta la base entera: - **`wlroots`** primero: es la biblioteca de la que cuelgan casi todos. - **Compositores**: `sway`, `labwc`, `river`, `niri`. - **La barra y los accesorios, sin los cuales un WM no se usa**: `waybar`, `fuzzel`/`wofi`, `swaybg`, `swayidle`, `swaylock`, `grim`, `slurp`, `wl-clipboard`. Son **baratos comparados con los escritorios completos**: no hay una torre de C debajo. Es la mejor relación esfuerzo/resultado que queda en el proyecto. ## II.2 Aplicaciones gráficas de terceros — **medido: cero** No hay ni una. Por coste creciente: - **Barato** (y es lo que hace que la distro se sienta usable): visor de imágenes (`imv`), lector PDF (`zathura`), reproductor (`mpv`), gestor de archivos, editor de texto gráfico, emulador de terminal adicional (`alacritty`, `kitty`). - **Caro**: **LibreOffice**. - **El más caro de todo el catálogo**: **un navegador**. Firefox es Rust + C++ + su propio sistema de build, y arrastra cbindgen, nasm, nodejs y una cadena de `*-sys` con C++ — que es **justo la frontera que el techo MSRV del sandbox (1.96) no cruza todavía**. Presupuestarlo como un frente propio, no como «una receta más». ## II.3 Deuda técnica de fondo que conviene cerrar antes de crecer - **Las 16 recetas con `compiler = "gcc"`** (contadas parseando TOML; `grep` cuenta comentarios). Las 12 de Rust son **un solo problema**: falta el unwinder de libgcc. - **No-determinismo en 92 paquetes**, todos por rutas `/src` incrustadas en secciones `.debug_*`. El arreglo (`-ffile-prefix-map` global) re-hashea ~720 recetas: decisión de arquitectura, no remiendo. - **La carrera del árbol de fuentes (ADR 0012)**, pendiente y **sin decidir**: dos builds de la misma dependencia se pisan. Aviso registrado: *un lock sólo en la extracción parece correcto y NO lo es.* - **El multi-init**: los inits del catálogo **compiten** con arje-zero, no se apilan. ## II.4 Sostenibilidad — lo que decide si sobrevive al primer mes Versionado y cadencia escritos; **reconstrucción desde cero en una máquina limpia, cronometrada** — la prueba de que el proyecto no depende de un laptop concreto, que es exactamente la preocupación que originó el respaldo del 2026-08-07. --- # PARTE III — El resumen ejecutivo **Para PUBLICABLE falta, en una línea cada uno:** 1. Arreglar el entorno del worker → caen las 12 recetas en deuda. 2. Terminar las licencias (913) e inyectar el texto en `hammer pack`. 3. Montar el espejo de fuentes. 4. Clave raíz fuera de línea y procedimiento de rotación. 5. Imagen validada en metal (re-quemar el USB). 6. Actualización N→N+1 probada, con rollback. 7. Espejo de paquetes (~30 G separando `-debug`), sitio, sumas y firmas. 8. `cups` y `bluez`. 9. Documentación mínima y un canal de reportes. **Se puede publicar SIN**: navegador propio, ofimática, y el reconstructor independiente. Son objetivos, no requisitos. **Para COMPLETA falta, además**: wlroots + los WMs ligeros y sus accesorios, el juego de aplicaciones gráficas, LibreOffice, el navegador, y cerrar la deuda de fondo (gcc, determinismo `.debug_`, ADR 0012).