tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1572Shell 203Rust 109Markdown 993728 Definiciones

⎇ 435b63eae7543e71145064b7854fa99096531ae2 docs/20-catalogo-publicable-y-completa.md Markdown · 413 líneas · 25.7 KB Historia crudo

takana etapa 5b: los 59 docs de diseño, runbooks y ADR 97ceb7241 · Sergio ·

1# SDD 20 — El catálogo de lo que falta: hasta PUBLICABLE y hasta COMPLETA
2
3Escrito 2026-08-07, a pedido del usuario: «el catálogo de todo lo que falta hasta decir *la distro
4está publicable*, y lo de más hasta *la distro está completa*».
5
6Este documento es el **inventario**. El [SDD 21](21-manual-del-piloto.md) es el **manual de a pie**:
7qué tiene que hacer el usuario, en qué orden, en cada una de las tres etapas.
8
9Todo lo de acá está **medido contra el repo el 2026-08-07**, no estimado de memoria. Donde hay un
10número, hay un comando que lo produjo.
11
12---
13
14## Los dos codos, y por qué están donde están
15
16- **PUBLICABLE** = un extraño puede descargarla, instalarla, usarla y actualizarla, y nosotros
17  estamos en regla al dársela. **No** significa que tenga todo lo que uno querría.
18- **COMPLETA** = tiene lo que una persona espera de un sistema de escritorio para su día a día, sin
19  tener que salir a buscar nada fuera.
20
21La distancia entre los dos codos es enorme y **el orden importa**: casi todo lo caro (navegador,
22ofimática) está DESPUÉS del primer codo, y casi todo lo bloqueante (legal, claves, actualización)
23está ANTES. La trampa clásica es invertirlos — pasarse meses con el navegador y descubrir el día del
24anuncio que no se puede publicar.
25
26---
27
28# PARTE I — Hasta «la distro está PUBLICABLE»
29
30## I.1 Estado de construcción: esto ya está casi cerrado
31
32Medido con `docs/state/build-state*.json` (el grafo, no recuento a mano):
33
34| frente | nodos | sellados | en deuda |
35|---|---:|---:|---:|
36| corpus | 771 | 759 | **12** |
37| KDE | 968 | 952 | 12 |
38| GNOME | 853 | 840 | 13 |
39| COSMIC | 818 | 806 | 12 |
40
41Los perfiles `base` (51 nodos) y `cli` (74 nodos) están **al 100%, deuda 0**.
42
43> ⚠️ **CORREGIDO 2026-08-08.** Este párrafo decía «KDE cierra 162/162». **Falso**: regenerado el
44> grafo, `escritorio-kde` está en **76/162**, y lo está en todos los commits recientes — o sea que ya
45> lo estaba cuando se escribió esta frase. El error fue leer `docs/state/build-state-kde.json` **sin
46> regenerarlo**: es un fichero GENERADO, y un generado que no se regenera es una foto vieja con
47> aspecto de dato fresco. En total hay **198 recetas de las colas de escritorio** (KDE 133, GNOME 37,
48> COSMIC 24) sin artefacto en su hash vigente.
49>
50> Se verificó que **NO lo causó la campaña del split** (SDD 23): se revirtieron una por una todas las
51> recetas tocadas —las 3 bibliotecas base, las 30 hojas, `dbus`, las 38 de la 2ª tanda— y el número
52> **no se movió de 198** en ningún caso.
53
54**La deuda real es una sola lista de 12 recetas, compartida por todos los frentes** (por eso el
55número se repite: es el mismo agujero visto desde cuatro grafos):
56
57```
58gtk4  libadwaita  gtksourceview  gtk4-hello  adwaita-hello  sourceview-hello
59takana-edit  mirada-compositor  mirada-greeter  dwarves  llimphi-counter  wlr-randr
60```
61
62> ### ⚠️ CORREGIDO EL MISMO DÍA, MIDIENDO CONTRA EL WORKER
63> La primera versión de esta sección decía que las 12 «fallan en el worker por su rootfs: `python
64> OSError` en meson, `find_package` en cmake» y que el arreglo era declarar las herramientas en
65> `[deps]`. **Se probó y es falso.** cmake y meson corren perfectamente en el worker. Las causas son
66> **cuatro, distintas**, y ninguna es el rootfs. Se descubrió al construirlas de verdad en vez de
67> heredar el diagnóstico.
68
69**(a) Seis están bloqueadas por el muro del PIC — y el frente GNOME ya lo venció por otro camino.**
70`gtk4` del corpus es `link = "static"` y enlaza `libfontconfig.a`, que tiene **1122 reubicaciones
71no-PIC**: el enlace produce **13 032 errores** `relocation R_X86_64_64 cannot be used against local
72symbol`. No es una receta rota, es una imposibilidad estructural. Mientras tanto
73`recipes/incoming-gnome/gtk4.toml` —`link = "dynamic"` con las deps `-shared`— **está sellada**, y
74con ella `libadwaita` y `fontconfig-shared`.
75⇒ La cadena del corpus (`gtk4`, `libadwaita`, `gtksourceview`, `gtk4-hello`, `adwaita-hello`,
76`sourceview-hello`, `takana-edit`) es un **duplicado superado** de la cadena dinámica de GNOME.
77Cerrarla no es «construirla»: es decidir si se **promueven las sombras `-shared` al corpus**, porque
78la resolución de deps es hermano→padre y una receta del corpus no ve a las de `incoming-gnome`.
79**Es una decisión de arquitectura, no una tarea** — y hay un aviso registrado de que promover a
80ciegas hace que variantes homónimas pisen recetas canónicas.
81
82**(b) `wlr-randr` — ✅ CERRADA HOY.** Le faltaban dos deps: `python3` (porque **meson es un script de
83Python**; sin intérprete la fase muere con exit 127, que se lee como «meson no está») y `libffi`
84(que la receta no usa: lo exige `wayland-client.pc` en su `Requires`). Auditadas las 1141 recetas,
85era **la única** con meson y sin python3.
86
87**(c) `dwarves` — frente propio, no deuda.** Falla porque nuestro `elfutils` entrega **sólo libelf**,
88deliberadamente: libdw arrastra argp/obstack/fts, «lo verdaderamente difícil en musl». Y no se
89arregla ampliando `elfutils`, porque de él cuelga **el kernel que ya reproduce bit a bit**; el camino
90correcto es una receta aparte `elfutils-libdw`. Sin urgencia: ningún perfil lo pide y el kernel
91desactiva `DEBUG_INFO_BTF` explícitamente por su ausencia. Se desbloquea cuando se quiera sched-ext.
92
93**(d) `mirada-compositor`, `mirada-greeter`, `llimphi-counter` — HUB-ONLY estructural.** Su `source`
94es `gitea@git.tawasuyu.net:...` por SSH y **el worker es sin secretos por diseño**. No es un fallo.
95`llimphi-counter` ni siquiera llega a construir: su `commit` es literalmente ceros, con el comentario
96«fijar al commit real» — es una receta sin terminar, y es de tawasuyu.
97
98### Y el hallazgo de fondo: nadie las estaba intentando
99El bucle del worker recorre `QUEUES="recipes/incoming recipes/incoming-go recipes/incoming-clib
100recipes/incoming-gnome-onda1 recipes/incoming-gnome-onda2 recipes/incoming-gnome recipes/incoming-kde"`
101— **el corpus (`recipes/`) no está en la lista**. Las 12 nunca se habían intentado en el worker. Buena
102parte de «la deuda» era de encolado, no técnica.
103
104## I.2 🚨 Lo legal — bloqueante
105
106### Licencias: de 0 a 1063 de 1141 en un día
107El 2026-08-07 se midió: **0 de 1141 recetas** declaraban licencia. (El informe previo decía «5 de
108771»; los dos números estaban mal — los «5» eran falsos positivos de `grep license`: el paquete
109`addlicense`, el paquete `cargo-bundle-licenses`, una línea de `install` y un comentario.)
110
111Ese mismo día se hizo lo estructural:
112- Campo `license` en la receta, **fuera de `hash_inputs`** ⇒ se puebla sobre recetas ya selladas sin
113  mover un solo `ArtifactHash`. Verificado en 40 recetas: 40 hashes idénticos, 0 cambiados.
114- `scripts/licencias.sh` mide de verdad (cuenta el campo, no la palabra) y siembra desde una tabla
115  curada.
116- Tabla curada por familias (toolchain, base C, gráficas, GNOME/GTK, Qt, KDE, X.Org, GnuPG,
117  freedesktop, kernel.org, PyPI) + el código propio de tawasuyu, que el usuario puso en **MIT**.
118
119**Estado al cierre del día: 1063 de 1141 (93%).** Cuatro escalones de evidencia, de peor a mejor:
120nombre (prohibido) → URL de fuente (familias) → API de licencias de GitHub → `Cargo.toml` del autor
121al tag exacto. Faltan 78. **Falta también** desambiguar ~55 SPDX obsoletos (`GPL-3.0` no dice si es
122`-only` u `-or-later`), que es trabajo humano: hay que leer cabeceras de fuentes.
123
124El cierre definitivo, para que la deuda no vuelva a abrirse con cada receta nueva, es capturar la
125licencia en la **fase de fetch**, que ya descarga y extrae cada tarball: ahí el dato pasa gratis.
126
127⚠️ **La regla que no se rompe**: no se rellena a ojo. Declarar mal una licencia es peor que dejarla
128vacía — convierte un hueco visible en una afirmación falsa. Concretamente se descartó el atajo
129«`k*` = KDE ⇒ LGPL»: en este catálogo `kail`, `kind`, `ko`, `kopia`, `krew`, `kustomize`, `kyverno`
130y toda la familia `kube*` son herramientas Go sin relación con KDE.
131
132### El texto de la licencia dentro del paquete — ✅ HECHO (y no donde yo dije)
133> **CORRECCIÓN.** Esto decía «va en `takana pack`». El razonamiento del coste era correcto —las
134> fases SÍ entran al hash, así que hacerlo en la receta re-hashearía las 1141— pero **el sitio
135> estaba mal**: `pack` produce un `.swm`, una receta de transformación sobre fuente pública que por
136> diseño «NUNCA transporta binarios cocidos», e `install` REPRODUCE construyendo. **El canal de
137> paquetes de takana no distribuye binarios.** Donde sí se entrega un binario es en la **imagen
138> instalable**, y ahí se hace ahora: `scripts/licencias-rootfs.sh` escribe
139> `/usr/share/licenses/<pkg>/` con el texto canónico de cada licencia de la expresión, más un
140> `MANIFEST.tsv` (1,0 MB para el perfil `cli`). Los 44 textos SPDX viven en `licenses/`.
141>
142> **Y VETA**: sale ≠0 si un paquete del rootfs no declara licencia. Al estrenarlo reveló que `base`
143> y `cli` llevaban 10 y 12 paquetes con binarios y licencia desconocida; después bajaron a 2 cada
144> uno (`lsof` y `tzdata`, que necesitaban la vía `LicenseRef-`).
145
146### Cerrado el 2026-09-09: 1166/1166, y el guardián contaba mal
147**Las 26 que faltaban están hechas**, ninguna adivinada: cada una sale del fichero de licencia de
148su fuente PINEADA —el tarball del `sha256` de la receta, o el commit exacto en la forja— y la cita
149queda como comentario en la propia receta. `lsof` y `tzdata` ya no vetan: llevan
150`LicenseRef-lsof` y `LicenseRef-tz-public-domain` con su texto real en `licenses/`.
151
152> ⚠ **Y el guardián tenía un fallo que valía más que las 26.** `licencias-rootfs.sh` resolvía la
153> receta por **nombre de fichero** (`ls recipes/$pkg.toml`), y el paquete se llama por su campo
154> `name`, que en **34 recetas no coincide** (`nu.toml`→`nushell`, `dust.toml`→`du-dust`,
155> `incoming-kde/qtbase.toml`→`qt6-qtbase`…). Medido: **14 paquetes que SÍ declaraban licencia
156> salían como «desconocida»** y el guardián vetaba una imagen publicable. El falso veto se nota; el
157> hermano silencioso no —un `<pkg>.toml` que pertenece a otro paquete daba la licencia EQUIVOCADA
158> sin decir nada—, y aunque hoy eso no ocurre (0 casos; de los 34 duplicados, ninguno declara
159> licencias distintas), el índice por `name` lo hace imposible en vez de improbable.
160>
161> El arreglo va por **los dos lados**, y el primer intento rompió el otro: el grafo de estado nombra
162> sus nodos por el FICHERO (`dust`) y el artefacto del store por `name` (`du-dust`). Ahora busca por
163> `name` y cae al fichero. Medido en los dos sentidos: corpus 1128/1128 y perfil `base`+`cli` 81/81.
164> Y probado con **rotura a propósito** además del control: paquete inexistente → exit 1; control →
165> exit 0 con los textos escritos.
166
167**Dos paquetes del catálogo NO se pueden redistribuir**, y ahora el veto los ve en vez de dejarlos
168pasar con el campo vacío: `duplicacy` no es software libre (su `LICENSE.md` cobra licencias por
169equipo para uso comercial) y `waybackurls` **no declara licencia ninguna** en el commit pineado, lo
170que por defecto reserva todos los derechos. Ninguno está hoy en un perfil de imagen.
171
172Hueco anotado: `XFree86-1.0` —una de las dos ramas del `OR` de `hwdata`— se queda sin texto porque
173SPDX no publica ese identificador (sólo `XFree86-1.1`, que es otra licencia) y el tarball lo nombra
174sin incluirlo. El guardián avisa y no veta, que es lo correcto: la otra rama es la GPL y su texto sí
175se entrega.
176
177### Espejo de fuentes — la obligación que más se malentiende
178La GPL no pide «que el código exista en internet»: pide que **quien recibe el binario pueda obtener
179de nosotros la fuente correspondiente**. Hoy las recetas apuntan a URLs de terceros que se caen.
180
181Acá estamos inusualmente bien parados: cada receta pinea `tarball` + `sha256`, así que el espejo es
182mecánico **y encima verificable**. Pero tiene que existir **antes de la primera descarga**.
183
184### Imágenes ajenas (qorpa): fuera del catálogo, y por escrito
185Desde el [ADR 0015](adr/0015-imagenes-ajenas.md) hay una segunda cadena de suministro: rootfs de
186otras distros que corren enjaulados. **No entran en el catálogo publicable ni en el reporte de
187licencias, y la razón no es pereza: no podemos enumerarlas.** Un `dnf install` o un `pacman -S`
188dentro de una instancia trae paquetes que nadie declaró acá, y afirmar una licencia sobre eso sería
189inventarla.
190
191Lo que sí se hace, y alcanza:
192- **Se cuentan aparte, en clase `ajeno`** (`docs/state/qorpa-ajenos.toml` → `build-state.json` →
193  «187/188 listo … + 1 ajenas»). El riesgo real de todo el ADR es que en seis meses alguien las
194  cuente como corpus; en otra clase no se pueden contar mal.
195- **La licencia la pone quien las publica**, que no somos nosotros: el usuario trae la imagen por
196  URL + sha256 y la relación es con esa distro.
197- **Si algún día se espejan** —el mecanismo lo permite gratis, porque son cuerpo inmutable
198  direccionado por contenido (ADR 0014)— ahí sí hay que mirar licencia **y marca** antes, igual que
199  con Firefox: redistribuir un rootfs de Ubuntu sin modificar suele estar permitido, pero la
200  política de marca es cosa aparte y **no es una pregunta técnica**.
201
202**Novedad 2026-09-04, y no rompe nada de lo anterior: una de ellas YA está sellada al store.** El
203runtime *sniper* de Valve entra por `recipes/steam-runtime-sniper.toml` porque **no muta** —nadie le
204instala nada adentro—, así que el mismo tarball pineado da siempre el mismo árbol. Sigue **fuera**
205del catálogo publicable y del reporte de licencias: su receta lleva `foreign = true`, el grafo la
206clasifica `ajeno` y su `license` es un `LicenseRef-…-no-enumerable` explícito, que dice lo que hay
207—cientos de paquetes Debian que no podemos enumerar— en vez de dejar el campo vacío, que se leería
208como «todavía no la poblamos». Y la distinción del punto anterior sigue en pie con más filo:
209**replicarla a nuestras propias máquinas** con `takana mirror push` es lo mismo que ya hace el ADR
2100013 con las fuentes; **publicarla a terceros** sigue pidiendo mirar licencia y marca antes, y eso
211no es una pregunta técnica.
212
213⚠️ Y el corolario que hay que escribir donde se lea: **el claim «takana reproduce bit a bit» hay que
214acotarlo** desde el día que exista una instancia — *el sistema base reproduce; las instancias ajenas
215no, y se declaran como tales*. Sin eso, la cultura de números honestos se erosiona sola.
216
217### Marcas
218Redistribuir Firefox con su nombre y logo exige cumplir la política de marca de Mozilla (por eso
219Debian tuvo Iceweasel). Decidir por adelantado: cumplir o rebrandear. **No bloquea el primer
220lanzamiento** si se sale sin navegador propio.
221
222### La licencia de takana — ✅ ya está
223`LICENSE` en la raíz y `license = "MIT"` en `Cargo.toml`. *(El SDD 19 decía que faltaba; era falso.)*
224
225## I.3 Infraestructura pública
226
2271. **Espejo de paquetes e imágenes.** Dimensionado real: el store son 128 G, pero **~60% es información de depuración** ⇒ separando `-debug` en paquetes aparte el espejo baja a **~51 G** (medido en la etapa 3 del SDD 23; el «79%» que se citaba era sobre el CONTENIDO BINARIO, no sobre el tamaño de artefacto).
2282. **Cadena de firma de release.** Hoy hay firma de índice. Falta el nivel de arriba: **clave raíz
229   fuera de línea**, claves de firma rotables y un procedimiento escrito para cuando se filtre una.
230   Firma sin gestión de claves es teatro.
2313. **Evidencia de reproducibilidad publicada.** Es *el* diferenciador: publicar junto a cada imagen
232   los `ArtifactHash` de toda su clausura, para que un tercero reconstruya y compare. Es lo que
233   convierte «somos reproducibles» en un hecho comprobable por un extraño.
2344. **Respuesta a seguridad**: un canal para reportes y —lo importante— la capacidad **demostrada** de
235   empujar una actualización y que llegue. Ensayar el ciclo completo con un CVE de mentira.
236
237## I.4 Que se pueda instalar y usar
238
2391. **Imagen instalable validada en METAL**, no sólo en QEMU. Está a medio camino: el USB de KDE en
240   metal está **en curso** y falta re-quemarlo. Reglas ya pagadas caro: validar imágenes de
241   escritorio **con pantalla**, nunca sólo `-nographic`; `/dev/console` es el serial, así que cada
242   capa debe escribir a `/dev/tty0`; y **nunca quemar a un NVMe**.
2432. **Matriz de hardware honesta**: en qué se probó y en qué no. Vale más «probado en estas 3
244   máquinas» que «debería funcionar».
2453. **Actualización en sitio probada de verdad**: instalar N, actualizar a N+1, y que arranque. Y
246   **rollback**, que con un store direccionado por contenido debería ser barato — es la ventaja
247   natural de esta arquitectura y conviene que sea función de primera clase.
2484. **Documentación mínima**: instalar, gestionar paquetes, reportar un fallo.
2495. **Sitio de descarga** con sumas y firmas, y las instrucciones para verificarlas.
250
251## I.5 Lo que falta de sistema para que no se note pobre
252
253Presente ya: `networkmanager`, `pipewire`, `wireplumber`, `polkit`, `seatd`, `upower`, `tzdata`,
254`fontconfig`. **Falta**: `cups` (impresión), `bluez` (bluetooth), y tipografías/locales revisados.
255
256---
257
258# PARTE II — De PUBLICABLE a «la distro está COMPLETA»
259
260Acá está el trabajo grande, y conviene decir los tamaños en voz alta.
261
262## II.1 WMs Wayland ligeros — ✅ HECHO EN UNA NOCHE (2026-08-07/08)
263> **Actualizado.** Esta sección decía «medido: no hay ninguno — de toda la familia sólo existen
264> `foot` y `mako`». Ya no. La hipótesis que traía —«son baratos comparados con los escritorios
265> completos: no hay una torre de C debajo»— **se cumplió y ahora está medida**: KDE y GNOME fueron
266> campañas de semanas; esto salió en una noche.
267
268**10 recetas selladas** en la cola `recipes/incoming-wlr/`, 12 binarios:
269
270| pieza | qué aporta |
271|---|---|
272| `wlroots` 0.18.2 | la biblioteca de la que cuelga todo lo demás |
273| `sway` 1.10 | el compositor (+ swaybar, swaymsg, swaynag) |
274| `yambar` | la barra de estado |
275| `fuzzel` | el lanzador de aplicaciones |
276| `swaybg` · `swaylock` · `swayidle` | fondo, bloqueo (con PAM) e inactividad |
277| `grim` · `slurp` | captura de pantalla y selección de región |
278| `wl-clipboard` | `wl-copy` / `wl-paste` |
279
280Con `foot` (ya en el corpus) como terminal, el perfil **`escritorio-sway` cierra 121/121** y
281**arranca en QEMU**: ver `docs/evidencia/sway-qemu-2026-08-08.png`.
282
283**`waybar` queda fuera POR MEDICIÓN**, no por gusto: pide `gtkmm-3.0` —GTK**3** *y* sus bindings de
284C++— más gtk-layer-shell, jsoncpp, fmt, spdlog, sigc++, date y libnl. Es el muro de GTK3 aparcado
285por diseño, con ocho recetas nuevas encima. `yambar` es C puro, del mismo autor que foot/fcft/fuzzel,
286y sus dependencias ya estaban selladas. Si algún día entra GTK3, waybar vuelve a la mesa.
287
288Faltan otros compositores (`labwc`, `river`, `niri`), que ahora son baratos porque wlroots ya está.
289
290### ⚠️ LA LECCIÓN QUE VALE PARA TODO ESTE DOCUMENTO: **sellado ≠ arranca**
291El grafo decía **121/121, falta 0** — y entre eso y una pantalla con algo dibujado hubo **seis muros
292y ocho ciclos de imagen**. Ninguno era visible en un grafo de dependencias, porque ninguno es una
293dependencia de build:
294
2951. **`PATH` vacío** — el `console-getty` no lo exporta; ni `mkdir` se encontraba.
2962. **`libz.so.1` ausente del rootfs** — el `zlib` del corpus es sólo estático y la compartida vive
297   en otra cola. Se cazó comparando los `NEEDED` del ELF contra el rootfs.
2983. **`LIBSEAT_BACKEND=builtin` no existe en NUESTRO libseat** — la receta lo construye con un solo
299   backend. *La receta manda sobre lo que uno cree recordar del proyecto.*
3004. **`/run` de sólo lectura** — la raíz es inmutable por diseño; el error («check permissions»)
301   sonaba a permisos y era un filesystem read-only.
3025. **`xkeyboard-config` ausente** — sin los datos XKB, xkbcommon aborta.
3036. **Sin tipografías no hay terminal** — `fcft: failed to load primary fonts`.
304
305Y el método: **el veredicto es contar colores del PPM, no leer el log.** Hubo un arranque con TODO
306verde —salida activada, modo correcto, «Commit of 1 outputs succeeded», workspace creado— y la
307captura **100% negra**. Un compositor puede estar vivo y no pintar nada.
308
309⇒ **Corolario para §4.1 y para cualquier estimación de este documento**: que un perfil cierre en el
310grafo prueba que la imagen SE ARMA, no que ARRANQUE. Los otros perfiles no validados en metal
311cargan esa misma distancia, y conviene no prometer fechas contra el número del grafo.
312
313## II.2 Aplicaciones gráficas de terceros — **medido: cero**
314No hay ni una. Por coste creciente:
315
316- **Barato** (y es lo que hace que la distro se sienta usable): visor de imágenes (`imv`), lector PDF
317  (`zathura`), reproductor (`mpv`), gestor de archivos, editor de texto gráfico, emulador de terminal
318  adicional (`alacritty`, `kitty`).
319- **Caro**: **LibreOffice**.
320- **El más caro de todo el catálogo**: **un navegador**. Firefox es Rust + C++ + su propio sistema de
321  build, y arrastra cbindgen, nasm, nodejs y una cadena de `*-sys` con C++ — que es **justo la
322  frontera que el techo MSRV del sandbox (1.96) no cruza todavía**. Presupuestarlo como un frente
323  propio, no como «una receta más».
324
325## II.3 Deuda técnica de fondo que conviene cerrar antes de crecer
326
327- **Las 16 recetas con `compiler = "gcc"`** (contadas parseando TOML; `grep` cuenta comentarios).
328  Las 12 de Rust son **un solo problema**: falta el unwinder de libgcc.
329- **No-determinismo en 92 paquetes**, todos por rutas `/src` incrustadas en secciones `.debug_*`. El
330  arreglo (`-ffile-prefix-map` global) re-hashea ~720 recetas: decisión de arquitectura, no remiendo.
331- **La carrera del árbol de fuentes (ADR 0012)**, pendiente y **sin decidir**: dos builds de la misma
332  dependencia se pisan. Aviso registrado: *un lock sólo en la extracción parece correcto y NO lo es.*
333- **El multi-init**: los inits del catálogo **compiten** con arje-zero, no se apilan.
334
335## II.4 Sostenibilidad — lo que decide si sobrevive al primer mes
336Versionado y cadencia escritos; **reconstrucción desde cero en una máquina limpia, cronometrada** —
337la prueba de que el proyecto no depende de un laptop concreto, que es exactamente la preocupación que
338originó el respaldo del 2026-08-07.
339
340---
341
342# PARTE III — El resumen ejecutivo
343
344**Para PUBLICABLE falta, en una línea cada uno:**
345
3461. Arreglar el entorno del worker → caen las 12 recetas en deuda.
3472. Terminar las licencias (913) e inyectar el texto en `takana pack`.
3483. Montar el espejo de fuentes.
3494. Clave raíz fuera de línea y procedimiento de rotación.
3505. Imagen validada en metal (re-quemar el USB).
3516. Actualización N→N+1 probada, con rollback.
3527. Espejo de paquetes (~30 G separando `-debug`), sitio, sumas y firmas.
3538. `cups` y `bluez`.
3549. Documentación mínima y un canal de reportes.
355
356**Se puede publicar SIN**: navegador propio, ofimática, y el reconstructor independiente. Son
357objetivos, no requisitos.
358
359**Para COMPLETA falta, además**: el juego de aplicaciones gráficas, LibreOffice, el navegador, y
360cerrar la deuda de fondo (gcc, determinismo `.debug_`, ADR 0012).
361*(Los WMs ligeros ya NO están en esta lista: wlroots + sway + accesorios se cerraron el 2026-08-07/08
362y el perfil arranca en QEMU — ver §II.1. También faltan otros compositores, pero ahora son baratos.)*
363
364---
365
366## 7. Lo que este documento NO puede decirte
367
368Todos los números de acá salen del grafo, y el grafo tiene un límite que conviene tener presente
369antes de leerlo como un plan: **prueba que una imagen SE ARMA, no que ARRANQUE.**
370
371Está medido, no supuesto. El perfil `escritorio-sway` cerró **121/121, falta 0** — y entre eso y una
372pantalla con algo dibujado hubo **seis muros y ocho ciclos de imagen**: PATH vacío, un `.so`
373ausente del rootfs, un backend de libseat que nuestra receta no construye, `/run` de sólo lectura,
374los datos XKB, y la falta de tipografías. Ninguno era una dependencia de build, así que ninguno podía
375aparecer en el grafo.
376
377⇒ Cuando este documento diga que algo «cierra», leelo como *se puede intentar*, no como *funciona*.
378La distancia se paga una vez por perfil y se paga entera. Los tres escritorios que aún no se
379validaron con pantalla la deben.
380
381---
382
383## 8. Por qué `escritorio-kde` está en 76/162 — diagnóstico (2026-08-08)
384
385**No es daño de la campaña del split**, y tampoco es un fallo de `store-gc`. Es más simple y más
386incómodo: **esos artefactos no existen en ninguna parte**.
387
388### Lo que se midió, en orden
3891. **86 nodos del perfil sin artefacto en su hash vigente.**
3902. **No lo causó el split**: se revirtieron una por una todas las recetas tocadas hoy —las 3
391   bibliotecas base, las 30 hojas, `dbus`, las 38 de la 2ª tanda— y el número **no se movió**.
3923. **La FRONTERA de la deriva son 7 recetas** (las únicas cuyas deps sí están al día):
393   `dbus`, `libnl`, `libpcap`, `libxkbcommon`, `lm-sensors`, `perl-xml-parser`, `vulkan-loader`.
394   Las otras 79 cuelgan de ellas.
3954. **Las 7 son SOMBRAS de `incoming-kde`**, no las canónicas. Las del corpus están perfectamente al
396   día — por eso el problema es invisible desde el grafo del corpus.
3975. **No fue `store-gc`**: sus hashes vigentes no figuran en ningún manifiesto de borrado, y tres de
398   ellas (`libpcap`, `lm-sensors`, `vulkan-loader`) nunca se podaron.
3996. **Ni el hub ni el worker los tienen.** No están «en otro sitio»: no están.
400
401### La causa de fondo, y por qué importa más que KDE
402La cola KDE se construyó en workers EFÍMEROS. El sync del store es **unidireccional** (worker→hub) y
403esos workers ya no existen. Cuando algo del sustrato compartido cambió después de aquella campaña,
404las sombras de KDE se re-hashearon y **nadie las reconstruyó**, porque el hub nunca fue la máquina
405donde vivía ese escritorio.
406
407⇒ **Con flota efímera y sync unidireccional, un escritorio puede dejar de ser reconstruible-desde-el-
408store sin que ningún indicador lo diga.** El grafo seguía reportando 162/162 en un JSON generado
409semanas antes, y sólo se vio al regenerarlo.
410
411### Qué cuesta arreglarlo
412**86 reconstrucciones en la granja**, empezando por las 7 de la frontera. No hay muro técnico
413conocido: son recetas que ya construyeron alguna vez. Es tiempo de cómputo, no investigación.

20-catalogo-publicable-y-completa.md

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 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

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):

frentenodosselladosen deuda
corpus77175912
KDE96895212
GNOME85384013
COSMIC81880612

Los perfiles base (51 nodos) y cli (74 nodos) están al 100%, deuda 0.

⚠️ CORREGIDO 2026-08-08. Este párrafo decía «KDE cierra 162/162». Falso: regenerado el grafo, escritorio-kde está en 76/162, y lo está en todos los commits recientes — o sea que ya lo estaba cuando se escribió esta frase. El error fue leer docs/state/build-state-kde.json sin regenerarlo: es un fichero GENERADO, y un generado que no se regenera es una foto vieja con aspecto de dato fresco. En total hay 198 recetas de las colas de escritorio (KDE 133, GNOME 37, COSMIC 24) sin artefacto en su hash vigente.

Se verificó que NO lo causó la campaña del split (SDD 23): se revirtieron una por una todas las recetas tocadas —las 3 bibliotecas base, las 30 hojas, dbus, las 38 de la 2ª tanda— y el número no se movió de 198 en ningún caso.

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
takana-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, takana-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 1063 de 1141 en un día

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:

Estado al cierre del día: 1063 de 1141 (93%). Cuatro escalones de evidencia, de peor a mejor: nombre (prohibido) → URL de fuente (familias) → API de licencias de GitHub → Cargo.toml del autor al tag exacto. Faltan 78. Falta también desambiguar ~55 SPDX obsoletos (GPL-3.0 no dice si es -only u -or-later), que es trabajo humano: hay que leer cabeceras de fuentes.

El cierre definitivo, para que la deuda no vuelva a abrirse con cada receta nueva, es capturar la licencia en la fase de fetch, que ya descarga y extrae cada tarball: ahí el dato pasa gratis.

⚠️ 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 — ✅ HECHO (y no donde yo dije)

CORRECCIÓN. Esto decía «va en takana pack». El razonamiento del coste era correcto —las fases SÍ entran al hash, así que hacerlo en la receta re-hashearía las 1141— pero el sitio estaba mal: pack produce un .swm, una receta de transformación sobre fuente pública que por diseño «NUNCA transporta binarios cocidos», e install REPRODUCE construyendo. El canal de paquetes de takana no distribuye binarios. Donde sí se entrega un binario es en la imagen instalable, y ahí se hace ahora: scripts/licencias-rootfs.sh escribe /usr/share/licenses/<pkg>/ con el texto canónico de cada licencia de la expresión, más un MANIFEST.tsv (1,0 MB para el perfil cli). Los 44 textos SPDX viven en licenses/.

Y VETA: sale ≠0 si un paquete del rootfs no declara licencia. Al estrenarlo reveló que base y cli llevaban 10 y 12 paquetes con binarios y licencia desconocida; después bajaron a 2 cada uno (lsof y tzdata, que necesitaban la vía LicenseRef-).

Cerrado el 2026-09-09: 1166/1166, y el guardián contaba mal

Las 26 que faltaban están hechas, ninguna adivinada: cada una sale del fichero de licencia de su fuente PINEADA —el tarball del sha256 de la receta, o el commit exacto en la forja— y la cita queda como comentario en la propia receta. lsof y tzdata ya no vetan: llevan LicenseRef-lsof y LicenseRef-tz-public-domain con su texto real en licenses/.

⚠ Y el guardián tenía un fallo que valía más que las 26. licencias-rootfs.sh resolvía la receta por nombre de fichero (ls recipes/$pkg.toml), y el paquete se llama por su campo name, que en 34 recetas no coincide (nu.toml→nushell, dust.toml→du-dust, incoming-kde/qtbase.toml→qt6-qtbase…). Medido: 14 paquetes que SÍ declaraban licencia salían como «desconocida» y el guardián vetaba una imagen publicable. El falso veto se nota; el hermano silencioso no —un <pkg>.toml que pertenece a otro paquete daba la licencia EQUIVOCADA sin decir nada—, y aunque hoy eso no ocurre (0 casos; de los 34 duplicados, ninguno declara licencias distintas), el índice por name lo hace imposible en vez de improbable.

El arreglo va por los dos lados, y el primer intento rompió el otro: el grafo de estado nombra sus nodos por el FICHERO (dust) y el artefacto del store por name (du-dust). Ahora busca por name y cae al fichero. Medido en los dos sentidos: corpus 1128/1128 y perfil base+cli 81/81. Y probado con rotura a propósito además del control: paquete inexistente → exit 1; control → exit 0 con los textos escritos.

Dos paquetes del catálogo NO se pueden redistribuir, y ahora el veto los ve en vez de dejarlos pasar con el campo vacío: duplicacy no es software libre (su LICENSE.md cobra licencias por equipo para uso comercial) y waybackurls no declara licencia ninguna en el commit pineado, lo que por defecto reserva todos los derechos. Ninguno está hoy en un perfil de imagen.

Hueco anotado: XFree86-1.0 —una de las dos ramas del OR de hwdata— se queda sin texto porque SPDX no publica ese identificador (sólo XFree86-1.1, que es otra licencia) y el tarball lo nombra sin incluirlo. El guardián avisa y no veta, que es lo correcto: la otra rama es la GPL y su texto sí se entrega.

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.

Imágenes ajenas (qorpa): fuera del catálogo, y por escrito

Desde el ADR 0015 hay una segunda cadena de suministro: rootfs de otras distros que corren enjaulados. No entran en el catálogo publicable ni en el reporte de licencias, y la razón no es pereza: no podemos enumerarlas. Un dnf install o un pacman -S dentro de una instancia trae paquetes que nadie declaró acá, y afirmar una licencia sobre eso sería inventarla.

Lo que sí se hace, y alcanza:

Novedad 2026-09-04, y no rompe nada de lo anterior: una de ellas YA está sellada al store. El runtime sniper de Valve entra por recipes/steam-runtime-sniper.toml porque no muta —nadie le instala nada adentro—, así que el mismo tarball pineado da siempre el mismo árbol. Sigue fuera del catálogo publicable y del reporte de licencias: su receta lleva foreign = true, el grafo la clasifica ajeno y su license es un LicenseRef-…-no-enumerable explícito, que dice lo que hay —cientos de paquetes Debian que no podemos enumerar— en vez de dejar el campo vacío, que se leería como «todavía no la poblamos». Y la distinción del punto anterior sigue en pie con más filo: replicarla a nuestras propias máquinas con takana mirror push es lo mismo que ya hace el ADR 0013 con las fuentes; publicarla a terceros sigue pidiendo mirar licencia y marca antes, y eso no es una pregunta técnica.

⚠️ Y el corolario que hay que escribir donde se lea: el claim «takana reproduce bit a bit» hay que acotarlo desde el día que exista una instancia — el sistema base reproduce; las instancias ajenas no, y se declaran como tales. Sin eso, la cultura de números honestos se erosiona sola.

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 takana — ✅ 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 ~60% es información de depuración ⇒ separando -debug en paquetes aparte el espejo baja a ~51 G (medido en la etapa 3 del SDD 23; el «79%» que se citaba era sobre el CONTENIDO BINARIO, no sobre el tamaño de artefacto).
  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 — ✅ HECHO EN UNA NOCHE (2026-08-07/08)

Actualizado. Esta sección decía «medido: no hay ninguno — de toda la familia sólo existen foot y mako». Ya no. La hipótesis que traía —«son baratos comparados con los escritorios completos: no hay una torre de C debajo»— se cumplió y ahora está medida: KDE y GNOME fueron campañas de semanas; esto salió en una noche.

10 recetas selladas en la cola recipes/incoming-wlr/, 12 binarios:

piezaqué aporta
wlroots 0.18.2la biblioteca de la que cuelga todo lo demás
sway 1.10el compositor (+ swaybar, swaymsg, swaynag)
yambarla barra de estado
fuzzelel lanzador de aplicaciones
swaybg · swaylock · swayidlefondo, bloqueo (con PAM) e inactividad
grim · slurpcaptura de pantalla y selección de región
wl-clipboardwl-copy / wl-paste

Con foot (ya en el corpus) como terminal, el perfil escritorio-sway cierra 121/121 y arranca en QEMU: ver docs/evidencia/sway-qemu-2026-08-08.png.

waybar queda fuera POR MEDICIÓN, no por gusto: pide gtkmm-3.0 —GTK3 y sus bindings de C++— más gtk-layer-shell, jsoncpp, fmt, spdlog, sigc++, date y libnl. Es el muro de GTK3 aparcado por diseño, con ocho recetas nuevas encima. yambar es C puro, del mismo autor que foot/fcft/fuzzel, y sus dependencias ya estaban selladas. Si algún día entra GTK3, waybar vuelve a la mesa.

Faltan otros compositores (labwc, river, niri), que ahora son baratos porque wlroots ya está.

⚠️ LA LECCIÓN QUE VALE PARA TODO ESTE DOCUMENTO: sellado ≠ arranca

El grafo decía 121/121, falta 0 — y entre eso y una pantalla con algo dibujado hubo seis muros y ocho ciclos de imagen. Ninguno era visible en un grafo de dependencias, porque ninguno es una dependencia de build:

  1. PATH vacío — el console-getty no lo exporta; ni mkdir se encontraba.
  2. libz.so.1 ausente del rootfs — el zlib del corpus es sólo estático y la compartida vive en otra cola. Se cazó comparando los NEEDED del ELF contra el rootfs.
  3. LIBSEAT_BACKEND=builtin no existe en NUESTRO libseat — la receta lo construye con un solo backend. La receta manda sobre lo que uno cree recordar del proyecto.
  4. /run de sólo lectura — la raíz es inmutable por diseño; el error («check permissions») sonaba a permisos y era un filesystem read-only.
  5. xkeyboard-config ausente — sin los datos XKB, xkbcommon aborta.
  6. Sin tipografías no hay terminal — fcft: failed to load primary fonts.

Y el método: el veredicto es contar colores del PPM, no leer el log. Hubo un arranque con TODO verde —salida activada, modo correcto, «Commit of 1 outputs succeeded», workspace creado— y la captura 100% negra. Un compositor puede estar vivo y no pintar nada.

⇒ Corolario para §4.1 y para cualquier estimación de este documento: que un perfil cierre en el grafo prueba que la imagen SE ARMA, no que ARRANQUE. Los otros perfiles no validados en metal cargan esa misma distancia, y conviene no prometer fechas contra el número del grafo.

II.2 Aplicaciones gráficas de terceros — medido: cero

No hay ni una. Por coste creciente:

II.3 Deuda técnica de fondo que conviene cerrar antes de crecer

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 takana 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: el juego de aplicaciones gráficas, LibreOffice, el navegador, y cerrar la deuda de fondo (gcc, determinismo .debug_, ADR 0012). (Los WMs ligeros ya NO están en esta lista: wlroots + sway + accesorios se cerraron el 2026-08-07/08 y el perfil arranca en QEMU — ver §II.1. También faltan otros compositores, pero ahora son baratos.)


7. Lo que este documento NO puede decirte

Todos los números de acá salen del grafo, y el grafo tiene un límite que conviene tener presente antes de leerlo como un plan: prueba que una imagen SE ARMA, no que ARRANQUE.

Está medido, no supuesto. El perfil escritorio-sway cerró 121/121, falta 0 — y entre eso y una pantalla con algo dibujado hubo seis muros y ocho ciclos de imagen: PATH vacío, un .so ausente del rootfs, un backend de libseat que nuestra receta no construye, /run de sólo lectura, los datos XKB, y la falta de tipografías. Ninguno era una dependencia de build, así que ninguno podía aparecer en el grafo.

⇒ Cuando este documento diga que algo «cierra», leelo como se puede intentar, no como funciona. La distancia se paga una vez por perfil y se paga entera. Los tres escritorios que aún no se validaron con pantalla la deben.


8. Por qué escritorio-kde está en 76/162 — diagnóstico (2026-08-08)

No es daño de la campaña del split, y tampoco es un fallo de store-gc. Es más simple y más incómodo: esos artefactos no existen en ninguna parte.

Lo que se midió, en orden

  1. 86 nodos del perfil sin artefacto en su hash vigente.
  2. No lo causó el split: se revirtieron una por una todas las recetas tocadas hoy —las 3 bibliotecas base, las 30 hojas, dbus, las 38 de la 2ª tanda— y el número no se movió.
  3. La FRONTERA de la deriva son 7 recetas (las únicas cuyas deps sí están al día): dbus, libnl, libpcap, libxkbcommon, lm-sensors, perl-xml-parser, vulkan-loader. Las otras 79 cuelgan de ellas.
  4. Las 7 son SOMBRAS de incoming-kde, no las canónicas. Las del corpus están perfectamente al día — por eso el problema es invisible desde el grafo del corpus.
  5. No fue store-gc: sus hashes vigentes no figuran en ningún manifiesto de borrado, y tres de ellas (libpcap, lm-sensors, vulkan-loader) nunca se podaron.
  6. Ni el hub ni el worker los tienen. No están «en otro sitio»: no están.

La causa de fondo, y por qué importa más que KDE

La cola KDE se construyó en workers EFÍMEROS. El sync del store es unidireccional (worker→hub) y esos workers ya no existen. Cuando algo del sustrato compartido cambió después de aquella campaña, las sombras de KDE se re-hashearon y nadie las reconstruyó, porque el hub nunca fue la máquina donde vivía ese escritorio.

⇒ Con flota efímera y sync unidireccional, un escritorio puede dejar de ser reconstruible-desde-el- store sin que ningún indicador lo diga. El grafo seguía reportando 162/162 en un JSON generado semanas antes, y sólo se vio al regenerarlo.

Qué cuesta arreglarlo

86 reconstrucciones en la granja, empezando por las 7 de la frontera. No hay muro técnico conocido: son recetas que ya construyeron alguna vez. Es tiempo de cómputo, no investigación.