Commit Graph
2649 Commits
Author SHA1 Message Date
Sergio b59edab197 estado: cosecha granja 2026-09-13T07:32:17Z — avance del árbol KDE 2026-09-13 07:32:17 +00:00
Sergio 6734d3eda5 estado: cosecha granja 2026-09-13T07:02:22Z — avance del árbol KDE 2026-09-13 07:02:22 +00:00
Sergio f1402036aa estado: cosecha granja 2026-09-13T06:31:56Z — avance del árbol KDE 2026-09-13 06:31:56 +00:00
Sergio df5976baad estado: cosecha granja 2026-09-13T06:02:02Z — avance del árbol KDE 2026-09-13 06:02:02 +00:00
Sergio 00c9d5afaf estado: cosecha granja 2026-09-13T05:31:54Z — avance del árbol KDE 2026-09-13 05:31:54 +00:00
Sergio 948fa6a284 estado: cosecha granja 2026-09-13T05:02:08Z — avance del árbol KDE 2026-09-13 05:02:08 +00:00
Sergio 460c68e100 estado: cosecha granja 2026-09-13T04:32:22Z — avance del árbol KDE 2026-09-13 04:32:22 +00:00
Sergio 2b86b8d0c3 estado: cosecha granja 2026-09-13T04:02:26Z — avance del árbol KDE 2026-09-13 04:02:27 +00:00
Sergio e28140c5b0 estado: cosecha granja 2026-09-13T03:32:09Z — avance del árbol KDE 2026-09-13 03:32:09 +00:00
Sergio eab169976e estado: cosecha granja 2026-09-13T03:02:27Z — avance del árbol KDE 2026-09-13 03:02:27 +00:00
Sergio 7ecf9d1d58 estado: cosecha granja 2026-09-13T02:31:54Z — avance del árbol KDE 2026-09-13 02:31:54 +00:00
Sergio f39a2eafc3 estado: cosecha granja 2026-09-13T02:02:41Z — avance del árbol KDE 2026-09-13 02:02:41 +00:00
Sergio 4b38af8f3f networkmanager al corpus CON WiFi y con nmcli — y los perfiles que no tenían gestor de red
networkmanager  b3:c36414ece23e322ef007d0acc7ce6f65b8b822ae55c38b38c9afa4b3eb340adb  (52 MB)

Arreglo del segundo hueco del barrido: `networkmanager` figuraba SÓLO en escritorio-kde, y desde
GNOME, COSMIC o sway no se alcanza (cola hermana). Pero promover la receta de KDE tal cual habría
sido peor que no hacerlo, y sólo se vio mirando el ARTEFACTO:

  · `-Dwifi=false`  ⇒ un gestor de red que no maneja interfaces inalámbricas. Allá es correcto
    (esa receta existe para dar libnm.so a plasma-nm y nada más); acá habría puesto en tres
    imágenes un demonio que arranca, dibuja el applet y no lista una sola red.
  · sin `nmcli`     ⇒ ni una herramienta con la que manejarlo. En sway eso es la diferencia entre
    tener red y no tenerla.

La variante del corpus cambia tres cosas, y la tercera hizo falta MEDIRLA:
  1. `-Dwifi=true`. Habla nl80211 por libnl (ya era dep) y delega el handshake WPA2 en
     `wpa_supplicant`, que desde hoy está en perfil.base ⇒ va también en [deps] runtime.
  2. `readline` en [deps] build.
  3. `-Dnmcli=true -Dreadline=libreadline`. Con sólo la dep, nmcli NO se construyó: `-Dnmcli` vale
     true de fábrica pero `-Dreadline` es un COMBO que por defecto va en `auto`, y sin decirle
     dónde mirar resolvió a «none» ⇒ meson apagó el CLI EN SILENCIO. Comprobado sobre el store.

Y `readline-shared` en runtime, cazado con provee.py sobre las NEEDED del binario: nmcli sale con
`NEEDED libreadline.so.8` y la readline canónica del corpus es sólo .a. La dep de BUILD y la de
RUNTIME son artefactos distintos — tercer caso del día tras cmus y bluez. No mueve el hash.

⚠ Se queda `-Dcrypto=null`, y es una limitación real escrita en la receta: sin cripto no valida
802.1X / WPA-Enterprise (el WiFi de una oficina). WPA2-PSK funciona porque ése lo hace el
supplicant. Encender nss o gnutls arrastra dos cadenas enormes: unidad de trabajo aparte.

── targets.toml ────────────────────────────────────────────────────────────────────────────────
  escritorio-gnome, escritorio-cosmic, escritorio-sway  += networkmanager  (+ servicio)
  escritorio-kde, escritorio-sway                       += wireplumber     (+ servicio)

⚠ networkmanager NO se declara en escritorio-kde: allá plasma-nm ya arrastra la variante de la
cola, y dos NetworkManager distintos en la misma ruta es la enfermedad de las dos glib. Que la de
KDE vaya sin WiFi es deuda del frente KDE, y queda escrita donde toca.
2026-09-13 01:38:50 +00:00
Sergio 72b9f54c19 recetas: libtool y libndp al corpus — promoción GRATIS, hash idéntico desde las dos partes
libtool  b3:5c09bff565b24c0a8edb306e0d4ca4e5e8e2a8c8e4a2b8ac047c8816b6883dcb
  libndp   b3:51be8f4336084b181e94a7f4a4178b87602cd39e975c2ddbd3125e7b782b9189

Entran como escalón para promover `networkmanager` al corpus (el barrido de perfiles midió que
GNOME, COSMIC y sway no alcanzaban ningún gestor de red: la receta vivía sólo en incoming-kde, que
desde ellos es una cola hermana).

La comprobación que decide una promoción NO es `diff` de las recetas sino `takana hash`, porque la
resolución de deps es hermano→padre y dos ficheros idénticos en colas distintas PUEDEN sellar
distinto. Acá sellan IGUAL desde las dos partes ⇒ misma dirección del store ⇒ las dos entraron por
CACHE-HIT, cero builds y cero rebuilds. (networkmanager, en cambio, sí difiere: resuelve varias
deps contra el corpus en vez de contra la cola de KDE.)

Las copias de `incoming-kde` se DEJAN donde están, a propósito: sellan en la misma dirección, así
que no hay dos artefactos ni colisión de nombre, y retirar ficheros de la cola que otro agente está
moliendo ahora mismo no es algo que este barrido tenga que hacer. Jubilarlas es trabajo del frente
KDE, el día que le convenga.
2026-09-13 01:37:26 +00:00
Sergio 0cd3e62822 libglvnd: sólo despacho de GL — muere la colisión de libEGL. Y obs-studio llevaba meses sin construir
libglvnd    b3:e27d3b2833a6aa6a6b4a4caad5ef2121e7be31a3c7ae59d0db22b01d696ffc99
  obs-studio  b3:29d95ddf50ef79692b48cae493758def564202ef81eba236b6cb279757621403

── libglvnd: se apagan egl, gles1, gles2 y headers ─────────────────────────────────────────────
La receta se escribió para la campaña completa —glvnd toma libEGL y mesa pasa a ser vendor detrás—
y la campaña NO SE HIZO: las tres mesa siguen con -Dglvnd=false. El resultado, medido en
/mnt/cosecha/escritorios/kde-rootfs ya hidratado, era el cuadro que la propia receta anunciaba:

  /usr/lib/libEGL.so.1 -> libEGL.so.1.0.0   1.440.624 B   (mesa: el driver)
  /usr/lib/libEGL.so.1.1.0                    323.144 B   (glvnd: despacho, HUÉRFANO)

Dos libEGL.so.1 distintos en la MISMA ruta, más libGLESv2.so.2 y los headers GL/, EGL/ y GLES2/
duplicados y con BYTES DISTINTOS (gl.h: 79.877 vs 80.393). Quién gana depende del orden de
hidratación y nada lo guarda.

Y no hacía falta: OBS, que es la razón de que la receta exista, NO usa glvnd en runtime.
libobs-opengl.so sale con NEEDED libEGL.so.1 y nada más, y sus indefinidos son todos egl* —ni un
gl[A-Z] sin resolver— o sea que su glad resuelve por eglGetProcAddress contra la EGL de mesa. Lo
único que glvnd le da es satisfacer el OpenGL::GL de CMake AL ENLAZAR.

Ahora sella libGLdispatch.so.0 + libOpenGL.so.0 + opengl.pc y nada más: CERO ficheros en común con
mesa. Radio medido: 1 dependiente.

⚠ Esto quita el DAÑO, no cierra el muro: libOpenGL.so.0 enlaza y en runtime sigue sin haber vendor
(no hay libEGL_mesa.so.0 ni egl_vendor.d). Cerrarlo es re-sellar las TRES mesa con -Dglvnd=true en
un movimiento, y el precio está medido: `yupana radio mesa` = 148 directos, 154 transitivos, 153
sellados que caen a deuda, las CINCO imágenes. Decisión de distro, no arreglo de paso.

── obs-studio: el cache-hit tapaba una regresión ───────────────────────────────────────────────
Al forzar su rebuild, el configure murió pidiendo `qrcodegencpp`, que no es receta de ninguna cola.
La causa NO era libglvnd. La receta dice «[source] de takana NO clona submódulos ⇒ sus directorios
llegan VACÍOS» y por eso hacía `touch plugins/obs-websocket/CMakeLists.txt`. Esa premisa dejó de
ser cierta: los submódulos YA se materializan, así que `touch` no vacía nada —sólo toca la mtime de
un fichero que existe— y el CMakeLists de verdad entra pidiendo su dependencia.

Corregido a `mkdir -p` + `: >` (truncar), que funciona con submódulos y sin ellos: la receta deja
de depender de una premisa que puede cambiarle bajo los pies. Construye y sella en el hub.
2026-09-13 01:36:36 +00:00
Sergio 424363fbdc receta: wireplumber al corpus — KDE y sway tenían pipewire y no encaminaban nada
wireplumber  b3:bd5471f00f5cbd229fcb252ceced41c35547725733708426bf7a42ea3e39a7bd

Arreglo del hueco que destapó el barrido de servicios. `pipewire` está en los cuatro escritorios y
arranca, pero se construyó con `-Dsession-managers=[]`: sin gestor de sesión no hay política de qué
es entrada, qué es salida ni qué se enlaza con qué, y el sink que ve la aplicación es `auto_null`
—el nodo de descarte—. Audio que parece vivo y no suena.

wireplumber existía en `incoming-gnome` y en `incoming-cosmic`, y desde KDE o sway NO SE ALCANZA:
una receta resuelve sibling-first y después el catálogo PADRE, nunca una cola hermana. Por eso la
copia va al corpus, que es el único sitio desde el que las cuatro imágenes la ven — el mismo
argumento por el que viven acá `mpv` y `atuq`.

Medido antes de copiar, no supuesto:
- `yupana radio wireplumber` = **0 dependientes** ⇒ esta copia no fuerza un solo rebuild ajeno.
- Las tres variantes sellan DISTINTO (gnome b3:71afcef4…, cosmic b3:7ad25184…, corpus b3:bd5471f0…).
  No es la enfermedad de las dos glib: ninguna imagen hidrata dos wireplumber, cada una toma la
  suya. Es la figura de las tres `pulseaudio`, que también se quedaron a propósito.
- Consolidar las tres en una es el trabajo siguiente y NO se hace de paso: el método está probado
  (es lo que se hizo con pipewire el 2026-09-03) pero GNOME y COSMIC están validados y cambiarles
  el artefacto de audio sin probarlos sería pagar con su imagen una limpieza que no urge.
2026-09-13 01:36:36 +00:00
Sergio 47ec0d9559 estado: cosecha granja 2026-09-13T01:33:30Z — avance del árbol KDE 2026-09-13 01:33:30 +00:00
Sergio 741a5d767c receta: bluez estático de verdad — el audit del cron vuelve a verde
bluez  b3:6036ab1585ce2af12e7596edd16709d1baa906f8c0ca816aed44957a038fbd66
  11/11 ejecutables `statically linked` · `bluetoothctl: 5.87` corre · 31 ficheros (no se perdió nada)

El sello de ayer decía `static` y salía con los ONCE ejecutables dinámicos; el audit del cron lo
marcó esa misma noche (docs/state/static-audit.txt, 2026-09-12T21:04Z) y dejó el veredicto global
en rojo: 715 honestas y las dos nuevas mintiendo. Acá se puede ser estático de verdad —el artefacto
NO trae ningún plugin .so, o sea que nadie hace dlopen (a diferencia de cmus)— así que el arreglo
es el arreglo, no una re-declaración.

Dos mitades, y la segunda no se ve venir:

1. `LDFLAGS=-all-static` en compile **Y** en install: bluez enlaza con libtool, que lee el `-static`
   del lab como «preferí los .a de libtool» y además RELINKEA al instalar.
2. `LIBS=-lncursesw`. Con -all-static el enlace de bluetoothctl corta con
   `undefined symbol: tgoto ... in archive /usr/lib/libreadline.a`: readline usa termcap y su
   readline.pc lo declara en `Requires.private: ncurses`, que **sólo se expande con
   `pkg-config --static`**. El configure de bluez busca readline con AC_CHECK_LIB, no con
   pkg-config ⇒ la transitiva nunca entra. En dinámico no se nota: la resuelve el loader.

Y se QUITA el `runtime = ["readline-shared"]` que se había añadido horas antes: hacía falta
mientras bluetoothctl era dinámico, y con el estático pasó a ser la mentira simétrica —declarar una
dep que no se usa—. No mueve el hash (las deps de runtime no entran en hash_inputs).
2026-09-13 01:15:40 +00:00
Sergio 35f83748f9 receta: cmus va link = "dynamic" — carga sus formatos por dlopen
cmus  b3:9a540d4270674ec74679dffbeed11d98796c51801663bde88e87affc041213ab

La primera versión decía `static` y era MENTIRA MEDIBLE: el audit del cron
(docs/state/static-audit.txt, medido 2026-09-12T21:04Z) la marcó — «dice static, es DINÁMICO →
libncursesw.so.6 libc.so» — y dejó el veredicto global en rojo. 715 honestas y las dos nuevas de
ayer mintiendo.

Pero el arreglo NO es hacerlo estático: **cmus no puede serlo**. El artefacto trae cinco plugins
—usr/lib/cmus/ip/{wav,cue,ffmpeg}.so y usr/lib/cmus/op/{alsa,oss}.so— y los abre por dlopen. Un
binario estático no puede abrirlos: quedaría un reproductor que no reproduce nada. Es la misma
razón por la que `sway` va dinámico (dlopea los drivers DRI de mesa).

⇒ `dynamic` es la declaración CORRECTA, no una concesión. Una declaración que el build ignora es
peor que no declarar, porque las herramientas río abajo la creen.

La prueba que decide, y cuesta dos segundos:
    find store/<hash>-<nombre> -name '*.so' | wc -l
  0 plugins → se puede y se debe ser estático.   N plugins → dynamic es lo honesto.

Comprobadas las NEEDED de los plugins contra el corpus con scripts/provee.py, que es la otra mitad:
libasound.so.2 (alsa-lib), libavformat/libavcodec/libswresample .so (ffmpeg) y libncursesw.so.6
(ncurses-shared) los publica el corpus ⇒ no hay NEEDED colgante. Las tres primeras llegan por
[deps] build; ncurses-shared va declarada en runtime desde el commit anterior.
2026-09-13 01:14:18 +00:00
Sergio 584cc128a8 docs: adenda al plan de apps — el censo, el muro de GL revisado y la respuesta a «¿Electron?»
Tres preguntas del usuario, contestadas midiendo, y dos de las mediciones CORRIGEN cosas que este
mismo fichero afirmaba.

1. CENSO: de ~50 apps muy usadas el catálogo tiene 9, y CINCO de las nueve son de KDE (o sea que
   llegan a una de las cuatro imágenes).

2. ⚠ CORRECCIÓN al «tercer defecto del método». Este documento dice, con fecha 2026-09-03, que
   ninguna cola publica libGL.so ni gl.pc. Dejó de ser cierto AL DÍA SIGUIENTE: recipes/libglvnd.toml
   es del 2026-09-04 y `provee.py --desde corpus opengl` da ✓ (libOpenGL.so.0 + opengl.pc). Y la
   corrección trae su propia corrección: la campaña quedó A MEDIAS. Las tres mesa siguen con
   -Dglvnd=false, no hay libEGL_mesa.so.0 ni egl_vendor.d, y en el rootfs KDE hidratado conviven DOS
   libEGL.so.1 distintos (mesa 1.440.624 B gana el symlink; el de glvnd, 323.144 B, queda huérfano).
   OBS —la razón de escribir libglvnd— NO la usa en runtime: libobs-opengl.so sale con NEEDED
   libEGL.so.1 y ni un gl[A-Z] indefinido, o sea que su glad resuelve por eglGetProcAddress.
   ⇒ el `opengl ✓` es verdad DE ENLACE. El muro pasó de «no enlaza» a «enlaza y no corre».

   Corolario: darktable estaba MAL clasificada como caso de GL. Su UI es GTK3+cairo; su muro es la
   cola de deps (lensfun, libgphoto2, openexr, imath, libraw, osm-gps-map, portmidi + cuatro que
   sólo viven en colas). Blender sí es el caso de GL.

3. ELECTRON: `grep -rni electron docs/ recipes/` da CERO. Nunca estuvo planeado. Y no existe un
   «Electron con base Firefox» porque Gecko no tiene API de embebido desde XULRunner (SDD 26 §1) —
   pero eso es exactamente lo que es atuq, y ya está: artefacto derivado + chrome propio +
   extensiones + host de native messaging en Rust. Falta un modo SSB, que es más barato que UN port.

   GenOffice concretamente: Apache-2.0 (salvo ee/), acepta endpoints OpenAI-compatible locales ⇒ la
   mitad de IA es una línea de config contra el llama-cpp que YA viaja en los cuatro escritorios. La
   mitad de runtime es qorpa. ⚠ Y el muro real es el MODELO: Qwen2.5-1.5B no sostiene IA agéntica
   sobre un .xlsx.

4. QUÉ REHACER, con criterio escrito: sólo cuando el bloqueo es estructural Y el valor vive en un
   protocolo o formato abierto. Pasan tres: el shell de apps sobre atuq, una bóveda de contraseñas
   (la mitad cara —la integración con el navegador— ya está construida), y un cliente Matrix si
   fractal no construye. Thunderbird es el más desaprovechado de la lista de EMPAQUETAR: es Gecko.
2026-09-13 01:10:00 +00:00
Sergio cbecd0ba12 docs: el barrido de perfiles y servicios, con su método y la política que faltaba escribir
Deja escrito lo que el barrido midió y, sobre todo, CÓMO se midió, para que el recuento se pueda
repetir en vez de re-derivar.

Lo que aporta que no estaba en ningún lado:

1. **La política «catálogo ≠ imagen».** El repo ya la aplicaba de hecho y no la había escrito, y sin
   ella «620 hojas sin perfil» se lee como deuda. No lo es: 529 son volcado crudo del importador y
   355 son herramientas Go de nube. Una receta sellada y no declarada es CATÁLOGO — se instala por
   nombre. Se vuelve deuda sólo cuando lo que falta es una CAPACIDAD.

2. **El método en tres preguntas encadenadas**, y por qué el orden importa: ¿está en algún perfil?
   → ¿podría llegar por clausura ajena (`dependientes_total>0`)? → ¿fue curada alguna vez (la
   cabecera «PUNTO DE PARTIDA» del importador)? Las hojas son el hueco; las librerías no.

3. **El triaje completo de las 91 hojas trabajadas a mano**, en seis clases que suman 91 exactas.
   Incluye las que NO se declaran de oficio y por qué: `openrc` compite con arje-zero, `uutils` y
   coreutils/grep/findutils compiten con los applets de busybox, `waterfox` es un segundo Gecko,
   y valkey/opensmtpd/step-ca/qdrant definen QUÉ CLASE de servidor es el perfil `servidor`.

4. **Dos hallazgos que no eran el objetivo del barrido:**
   - `networkmanager` existe SÓLO en incoming-kde ⇒ GNOME, COSMIC y sway no lo alcanzan. Con
     wpa_supplicant la WiFi se destraba, pero se configura a mano y el indicador de red del
     escritorio no tiene con qué hablar.
   - `ia-modelo-embeddings` no está en ningún perfil: hay motor (llama-cpp) y hay chat
     (ia-modelo-chat) en los cuatro escritorios, y NO hay búsqueda por significado. La mitad
     semántica del §6.3 de atuq no viaja.

5. **Una trampa del instrumento**, que casi hace escribir mal las listas de servicios:
   `scripts/targets.py <perfil>` imprime las RAÍCES, no la clausura. Cruzar los [[service]] contra
   esa salida dejaba fuera a pipewire y colord en GNOME, que sí están en la imagen. La clausura la
   da el campo `perfiles` de los build-state*.json.
2026-09-13 01:08:17 +00:00
Sergio 9ac4e1727f targets: barrido de perfiles y servicios — la WiFi faltaba, y tres escritorios no arrancaban nada
── BARRIDO 1: las hojas selladas sin perfil ────────────────────────────────────────────────────
Método, para que se pueda repetir: cruzar el campo `perfiles` de los cinco build-state*.json con
`dependientes_total`. De 905 nodos, 631 sin perfil; de ésos, **620 son HOJAS** (nadie depende de
ellas, o sea que ninguna clausura las puede alcanzar) y 11 llegan por la clausura de otra.

Las 620 se parten en dos por una marca objetiva, la cabecera del importador:
  · **529** dicen «PUNTO DE PARTIDA, no final» — volcado crudo de import-nix/import-alpine
    (328 Go + 195 Rust + 6 C). Nadie las curó nunca para una imagen.
  · **91** están trabajadas a mano. Ésas son las que se triaron una por una.

Lo que salió de ese triaje, y lo que se declara:

**`base` += `wpa_supplicant` — la imagen NO PODÍA ASOCIARSE A UN WiFi.** dhcpcd resuelve la IP de
un cable; el handshake WPA2 de 4 vías lo hace un supplicant en userspace y busybox no lo trae. La
receta existía desde el frente de metal —su cabecera dice «para asociar el WiFi del medio live al
AP»— y estaba en CERO perfiles. Es la figura de `foot` y esta vez el precio era quedarse sin red.

**`cli` += nano, tig, patch, socat, pigz, miller, dwarves.** El criterio va escrito en el fichero
porque meter las 620 habría sido peor que no mirar: entra lo que un usuario de esta capa ESPERA
encontrar y hoy no está. El resto queda en el catálogo, que NO es lo mismo que la imagen.

**`escritorio-sway` += wlr-randr**: no había con qué cambiar la resolución ni rotar una pantalla.

── BARRIDO 2: el «enable» ──────────────────────────────────────────────────────────────────────
De los cuatro escritorios **sólo GNOME tenía lista `servicios`**. Los otros tres salían con sus
demonios instalados y NINGUNO arrancado, y la métrica de clausura daba N/N igual — `paquetes` dice
qué se instala, `servicios` dice qué se levanta, y sin la segunda la imagen está a medias sin que
nada falle.

Escritas las tres que faltaban, computando la lista (no a ojo): se cruzaron los `[[service]]` de
las 11 recetas que los declaran contra el campo `perfiles` de los cinco grafos — la CLAUSURA, no
las raíces, porque la mitad de los demonios llegan como dep. Y GNOME sumó `cupsd`+`bluetoothd`,
que nacieron ayer.

⚠ El cruce destapó tres ausencias que NO se arreglan acá y quedan escritas en el fichero:
  · KDE y sway tienen `pipewire` y **no tienen `wireplumber`**: sin gestor de sesión los nodos
    existen y nadie los conecta.
  · COSMIC **no tiene `upowerd`** y dibuja un indicador de batería.
  · KDE y sway no tienen `logind-compat`.

Comprobado: tomllib parsea, y los ocho perfiles resuelven con scripts/targets.py.
2026-09-13 01:06:01 +00:00
Sergio a9991194bc estado: cosecha granja 2026-09-13T01:02:20Z — avance del árbol KDE 2026-09-13 01:02:20 +00:00
Sergio dadd231b03 estado: cosecha granja 2026-09-13T00:32:07Z — avance del árbol KDE 2026-09-13 00:32:07 +00:00
Sergio 10213c2d0a estado: cosecha granja 2026-09-13T00:02:31Z — avance del árbol KDE 2026-09-13 00:02:31 +00:00
Sergio 535778b28f estado: cosecha granja 2026-09-12T23:31:56Z — avance del árbol KDE 2026-09-12 23:31:57 +00:00
Sergio 460aa6860a estado: cosecha granja 2026-09-12T23:01:57Z — avance del árbol KDE 2026-09-12 23:01:57 +00:00
Sergio d38b1bbe41 estado: cosecha granja 2026-09-12T22:31:56Z — avance del árbol KDE 2026-09-12 22:31:56 +00:00
Sergio 10cb6ef140 estado: cosecha granja 2026-09-12T22:01:59Z — avance del árbol KDE 2026-09-12 22:01:59 +00:00
Sergio 5881260aee estado: cosecha granja 2026-09-12T21:32:04Z — avance del árbol KDE 2026-09-12 21:32:04 +00:00
Sergio 3043abd295 estado: cosecha granja 2026-09-12T21:04:26Z — avance del árbol KDE 2026-09-12 21:04:26 +00:00
Sergio 4e807444d1 targets: mold, sccache y cliphist — las tres que habrían repetido el error del commit anterior
El grafo regenerado por el cron delató lo que faltaba: `mold` y `cliphist` salían con
`perfiles: []`. O sea que en el mismo día en que se midió que 649 recetas selladas no están en
ninguna imagen, dos de las recetas nuevas se iban a sumar a la lista. La métrica lo vio porque
existe; la intención no alcanza.

- `cli` += `mold` y `sccache`. Las dos son herramientas de quien CONSTRUYE con la distro, no de
  quien la usa. `sccache` estaba sellada hace meses y sin perfil; `mold` es de hoy.
- `escritorio-sway` y `escritorio-cosmic` += `cliphist`. SÓLO ahí: habla `wlr-data-control`, que
  KWin y mutter no implementan — mismo muro que `wf-recorder`. Declararlo en KDE o GNOME daría un
  binario que arranca y no hace nada, que es peor que no tenerlo.

Comprobado con scripts/targets.py: cli resuelve mold+sccache, y sway/cosmic los tres.
2026-09-12 21:02:31 +00:00
Sergio f0614f679e recetas: mold y wireguard-tools — link = "static" era una etiqueta, no un hecho
mold             b3:9ce9fe3194982cc2b28d0fa547b037d7d36dae773fbd033ad252d7f11cb92dd2
  wireguard-tools  b3:086d0837e30e8a7a5e05c61c2df47987c2574645c03226e0020f35635ba8ba41

Los dos sellaban, reproducían y NO CORRÍAN. Se descubrió ejecutando el binario; ni el sellado, ni
`takana hash`, ni la reproducibilidad lo veían.

mold — dos causas independientes, las dos leídas en su CMakeLists.txt:
  1. `:149` — `if(ZLIB_FOUND AND NOT MOLD_MOSTLY_STATIC)` enlaza la zlib COMPARTIDA del sistema
     (ídem zstd `:179` y blake3 `:161`). El binario salía pidiendo `libz.so.1`/`libzstd.so.1`, que
     el corpus no publica (`zlib` canónica es `.a`), y al correrlo tomaba la del anfitrión:
     `Error relocating /lib/libz.so.1: __snprintf_chk: symbol not found` — símbolo de
     _FORTIFY_SOURCE de glibc que musl no tiene. `-DMOLD_MOSTLY_STATIC=ON` usa las que trae en tree.
  2. El `LDFLAGS=-static` que el lab exporta para `link = "static"` NO llegaba a la línea de enlace
     de CMake ⇒ hace falta `-DCMAKE_EXE_LINKER_FLAGS=-static` explícito.
  Ahora: `statically linked`, y `mold --version` contesta 2.42.1.

  Y antes de eso, otro defecto que tampoco fallaba: el primer sello pesaba 629 MB, de los cuales
  628 eran UN SOLO FICHERO — /usr/bin/mold con el DWARF adentro, que CMAKE_BUILD_TYPE=Release no
  quita. Con `strip_debug = true` (SDD 23) quedó en 41 MB. Un artefacto obeso no rompe nada: entra
  en el store, en la imagen y en el respaldo, y nadie mira el tamaño.

wireguard-tools — acá el error era del razonamiento, y el artefacto lo desmintió. La receta iba
`link = "dynamic"` con [deps] build=["libmnl"] argumentando «wg enlaza libmnl y no hay libmnl.a en
el store». `readelf -d wg` da UN solo NEEDED, `libc.so`, y los `mnl_*` están definidos adentro.
La razón está en la fuente, `src/netlink.h:1`:

    /* This is a minimized version of libmnl meant to be #include'd */

Upstream embebe el subconjunto que usa para no arrastrar la dependencia. Pasa a `link = "static"`
y pierde la dep: declarar una que no se usa ata esta receta al hash de otra y haría que un rebuild
de libmnl la re-selle para nada.

REGLA, escrita en las dos recetas: `link = "static"` es una DECLARACIÓN. Lo único que la comprueba
es `readelf -d` sobre el artefacto, o correrlo.
2026-09-12 21:00:32 +00:00
Sergio 4fe5886447 recetas: cmus y bluez piden un .so que la imagen no llevaba — declarado en runtime
Se descubrió CORRIENDO los binarios, no auditando las recetas, y el hash NO se mueve (las deps de
runtime no entran en hash_inputs): los artefactos sellados siguen valiendo.

  cmus/cmus            NEEDED libncursesw.so.6   ⇒ runtime = ["ncurses-shared"]
  bluez/bluetoothctl   NEEDED libreadline.so.8   ⇒ runtime = ["readline-shared"]

Las canónicas `ncurses` y `readline` del corpus son `--without-shared`/sólo `.a`, así que sin
declarar la variante `-shared` esos `.so` no viajan en la imagen y el binario muere en el loader.
Es la MISMA fuga que el perfil de sway ya pagó con zlib/expat/libffi, y no la ve ningún auditor de
recetas: sólo `readelf -d` sobre el artefacto, o ejecutarlo.

El reparto de bluez era el peor posible: `bluetoothd` sale con `libc.so` a secas y habría
arrancado, y la herramienta con la que se emparejan los dispositivos habría sido la que no.

Comprobado con scripts/provee.py: los dos sonames SÍ los publica el corpus
(corpus/ncurses-shared, corpus/readline-shared) ⇒ no hay NEEDED colgante, faltaba la declaración.
2026-09-12 20:45:58 +00:00
Sergio e1fb4b71a7 estado: cosecha granja 2026-09-12T20:33:54Z — avance del árbol KDE 2026-09-12 20:33:54 +00:00
Sergio 66db4e4054 targets: declarar lo que ya estaba sellado y en ninguna imagen — y las dos capacidades del punto 8
MEDIDO al ir a declarar las recetas nuevas, y es más grande que ellas: de las 892 recetas selladas
del corpus, **649 no están en NINGÚN perfil**. El 73% del catálogo está compilado y no viaja en
ninguna imagen. No es deuda de build (drenaje.json dice 0) y la métrica de perfil NO lo puede ver:
mide la clausura de lo DECLARADO. Es la lección de foot a escala de catálogo.

Concreto: yazi, atuin, zellij, jujutsu, just, direnv, watchexec, mise, xh, age, rclone, restic,
lazygit, difftastic, bottom y duf estaban selladas hace meses y en cero imágenes; y `helix` estaba
declarada sólo en escritorio-gnome, que es donde menos sentido tiene.

perfil.cli += esas 16 + las nuevas de hoy (btop, ncdu, nushell, aerc, cmus, syncthing).
Cero recetas nuevas y cero builds: sólo dejan de ser invisibles. Como los CUATRO escritorios y
`servidor` heredan `cli`, una sola edición los alcanza a todos.

perfil.servidor += wireguard-tools: el kernel ya trae WireGuard (SDD 22) y no había con qué
configurarlo — misma figura que el cortafuegos y el reloj que este perfil ya declaraba.

Los cuatro escritorios += cups, bluez (punto 8 de PUBLICABLE, docs/20). Viven en el CORPUS y no en
las colas por lo mismo que mpv y atuq: se alcanzan sibling-first→padre, una copia para los cuatro.

⚠ DEUDA DECLARADA, NO OLVIDO: las dos recetas traen su [[service]] y los perfiles NO los arrancan
— de los cuatro escritorios sólo escritorio-gnome tiene lista `servicios`. Los otros tres no
arrancan NADA, y eso es más grande que cups y bluez. Va escrito en el fichero para que se vea.

El barrido de las 649 queda pendiente y es su propia unidad de trabajo: 363 son recetas Go
importadas en tanda (herramientas de desarrollo) y NO todas deben entrar en una imagen.

Comprobado con scripts/targets.py: los ocho perfiles resuelven, sin nombres desconocidos.
2026-09-12 20:31:35 +00:00
Sergio 0d93435fd8 receta: bluez — la pila Bluetooth, sellada (el otro medio punto 8 de PUBLICABLE)
bluez  b3:21bee949122f770a319b806b83d23fa2bddc958252f6de7e27fffa5a75a3315a  (28 MB, 31 ficheros)

Con esto queda cerrado el punto 8 de PUBLICABLE (docs/20): «cups y bluez».

El fallo del primer intento vale más que la receta: con [deps] build=["glib", ...] el configure
corta con «Package 'libpcre2-8', required by 'glib-2.0', not found». No falta una dep de bluez:
faltan las TRANSITIVAS del .pc de glib. Un enlace estático resuelve la cadena entera en el punto de
enlace, así que pcre2/libffi/zlib hay que materializarlas aunque bluez no las nombre — es el mismo
juego de cuatro que ya declaran cairo, appstream y adwaita-hello, y que nadie había escrito por qué.

Perillas leídas del «configure --help» del tarball pineado:
- --disable-obex: obexd pide libical, y libical existe SÓLO en incoming-gnome. Una receta del
  corpus resuelve sibling-first y después el catálogo PADRE, nunca una cola hermana ⇒ desde acá no
  se alcanza. Encenderlo exige promover libical, que es otra unidad de trabajo.
- --disable-manpages: las genera rst2man (docutils); no es receta.
- --disable-cups: el backend de impresión por Bluetooth. cups YA es receta desde hoy, o sea que
  esto se puede encender — queda anotado como lo próximo, no como olvido.

Declara [[service]] bluetoothd; el exec VERIFICADO contra el artefacto: /usr/lib/bluetooth/bluetoothd.
Y va escrito que esto no enciende el bluetooth de nadie: falta dbus vivo y que el perfil lo habilite.
2026-09-12 20:28:31 +00:00
Sergio 3f2620f6b7 recetas: nushell y cmus — shell moderna y reproductor de música, sellados
nushell  b3:742c008b462930c6ee9c2af0646fe842e9e1bad7fe35277eddabdb15aa4fdae6  (41m17s de cargo)
  cmus     b3:cae8d90b5c1c7e5864c708371b2bdefbbccaa3ef1248f165a20f2dc2ce481b8b

- nushell entra como shell INTERACTIVA y va escrito en la receta que no es ni va a ser /bin/sh: su
  lenguaje no es POSIX y un script del sistema no corre ahí. El catálogo tenía tres shells (bash,
  busybox/ash, elvish) y ninguna era una alternativa moderna. compiler="gcc" por el patrón
  zellij/gitui/delta: hay crates *-sys con build-script en C y cc-rs invoca gcc; el linker sigue
  siendo zig-cc.

- cmus cierra el hueco de audio: el catálogo había cerrado el vídeo con mpv y no tenía con qué
  escuchar música. Su configure NO es autotools — toma asignaciones clave=valor, no --flags — y
  eso importa: pasarle --prefix=/usr no da error, lo IGNORA, y el paquete acabaría en /usr/local
  sin que nada falle. CONFIG_PULSE=n a propósito: la salida ALSA desemboca en PipeWire por
  -Dpipewire-alsa, igual que hace mpv, y la libpulse del corpus es la variante con la glib
  ESTÁTICA adentro, que no se quiere en un cliente.
2026-09-12 20:26:53 +00:00
Sergio b8738c6c3f estado: cosecha granja 2026-09-12T20:03:45Z — avance del árbol KDE 2026-09-12 20:03:45 +00:00
Sergio 7c4bd40c23 estado: cosecha granja 2026-09-12T19:34:20Z — avance del árbol KDE 2026-09-12 19:34:21 +00:00
Sergio 63eab86ef7 receta: cups — el servidor de impresión, sellado (punto 8 de PUBLICABLE)
cups  b3:528b38b20d3cecf7e06fbc51f271603e3c71fbec6ef8047c86ad421edb7a1a45

No es una app más: es uno de los NUEVE pendientes de PUBLICABLE (docs/20, punto 8). Una distro de
escritorio que no imprime no es una distro de escritorio, y ese hueco no se ve contando recetas
— es de CAPACIDAD, la familia de foot y las fuentes.

El muro real fue el PIE, y el diagnóstico vale más que el arreglo: el configure detecta que el
compilador acepta -fPIE y mete «-fPIE -pie» en ALL_LDFLAGS *y sólo ahí* — los objetos de
libcups.a se compilan sin PIC — así que lld corta con «relocation R_X86_64_64 cannot be used
against local symbol». No se puede apagar con una flag: @PIEFLAGS@ se sustituye DENTRO de
Makedefs, no es una variable de make que «make PIEFLAGS=» pueda pisar. Y un ejecutable PIE con
-static exigiría -static-pie, que no es lo que esta distro construye ⇒ el sed que lo quita es lo
correcto acá, no un atajo.

Todas las perillas salen del «configure --help» del TARBALL PINEADO, no de un APKBUILD ajeno.
--with-dnssd=no y --disable-acl se apagan POR DECLARACIÓN aunque no haya avahi ni acl en el
catálogo: si el configure los busca y los encuentra en el sysroot del lab, el lab NO entra en
hash_inputs y el artefacto deja de reproducir sin que nadie toque la receta.

⚠ Queda escrito en la receta un segundo tramo que ESTA receta no paga: gtk3 del corpus está
sellada con -Dprint_backends=file, así que una app GTK3 seguirá viendo un solo destino hasta que
gtk3 se re-selle. La pieza está, el sistema la ignora, y ninguna métrica lo dice.

Declara [[service]] cupsd (SDD 30). Declararlo NO lo enciende: falta que el perfil lo habilite.
2026-09-12 19:28:46 +00:00
Sergio fad71087d8 receta: btop — monitor de recursos en TUI, sellado
btop  b3:d1e3d3111d306e158f2269ba3ecb4852d7d095f688e707db54381dbb3b26e34f

Dos cosas que valían el viaje:

- `configure = 'true'` NO es relleno. btop 1.4.x trae CMakeLists.txt *y* Makefile; el autodetector
  del lab ve el primero y generaba `cmake -S . -B _build`, que muere con `cmake: not found`
  (cmake es una receta del corpus, no una herramienta del lab). Apagar la fase de configure es lo
  que elige la vía soportada por upstream.

- C++20 (<ranges>, <format>) compila y ENLAZA ESTÁTICO con la libc++ de zig, sin gueto gcc. Se
  puede porque btop no enlaza ninguna librería C++ del corpus: todo su C++ es suyo. El binario sale
  con -D_LIBCPP_HARDENING_MODE, o sea libc++ de verdad y no libstdc++.
2026-09-12 19:22:52 +00:00
Sergio a65910298a recetas: aerc y syncthing — correo en terminal y sincronización, sellados
aerc       b3:a33dbafdcc302154888095b7b5b14278461e60a69c4c8f310e388ba85f544d0a  (43 ficheros)
  syncthing  b3:544ebf125c682c720b8555faf4259cd48bee5b4a302c4a4cc29a7311691a6e34

Las dos necesitaron salirse del driver Go genérico, y por motivos distintos:

- aerc se construye con SU GNUmakefile. El driver hace `go install` y deja el binario en
  /out/usr/bin; eso habría dado un paquete que ARRANCA Y NO SIRVE — aerc busca plantillas,
  stylesets y filtros en /usr/share/aerc, y dos filtros (colorize, wrap) son fuente C que hay que
  compilar. Con el Makefile el artefacto trae los 43 ficheros. VERSION y GOFLAGS van fijados a
  mano: el Makefile los saca de `git describe` y de contrib/goflags.sh, y el árbol llega al
  sandbox SIN .git ⇒ el binario dependería de si hay un .git al lado.

- syncthing falla con `go install` a secas y el error no dice por qué:
  `lib/api/api_statics.go:45:25: undefined: auto.Assets`. La GUI web se sirve desde un fichero Go
  GENERADO que empaqueta gui/ y el repo no lo versiona: lo produce `go run build.go assets`. No es
  una dependencia que falte, es un CODEGEN. Todo local, sin red.

commit = el tag PELADO en los dos casos (ambos son tags anotados; la trampa de foot).
2026-09-12 19:21:48 +00:00
Sergio 53520c24b4 recetas: ncdu, wireguard-tools y cliphist — tres huecos del userland, sellados
Primera tanda del barrido de huecos del catálogo moderno. Las tres SELLAN en el hub:

  ncdu             b3:455589610a4d0378299a2a428f85d77c4d1998f71dbdb68bb704bd64a4ef40c5
  wireguard-tools  b3:9283f272e7833d55ec50ac854c98a5abdee81ad5ca01ce90de4ce6f241744bac
  cliphist         b3:86597f25894ab7fce9df1af6e7a6942de5e677546fcc40d91fc087778c059343

- ncdu 1.22 y NO la 2.x: la 2 esta reescrita en Zig y exige una version concreta del compilador;
  84 recetas ya pinean zig_version=0.13.0 y el zig del lab es rodante. La 1.22 es la ultima de la
  rama C y hace lo mismo.
- wireguard-tools va link="dynamic" a proposito: libmnl canonica es --disable-static, o sea que en
  el store NO hay libmnl.a. Forzar static no daria un estatico sino un enlace contra el .a del
  sysroot Alpine DEL LAB — la misma fuga que documenta el perfil de sway con zlib/expat/libffi.
- cliphist habla wlr-data-control: sirve en sway y COSMIC, NO en KDE ni GNOME (mismo muro que
  wf-recorder). Declararlo donde no funciona seria peor que no tenerlo.

Las tres licencias VERIFICADAS contra el LICENSE/COPYING del arbol, no adivinadas.
Ninguna esta declarada todavia en targets.toml: sellado != instalado (la leccion de foot).
2026-09-12 19:20:06 +00:00
Sergio 0949c0895d estado: cosecha granja 2026-09-12T19:01:53Z — avance del árbol KDE 2026-09-12 19:01:53 +00:00
Sergio 4744951980 estado: cosecha granja 2026-09-12T18:32:19Z — avance del árbol KDE 2026-09-12 18:32:19 +00:00
Sergio 86de78c0e5 estado: cosecha granja 2026-09-12T18:02:22Z — avance del árbol KDE 2026-09-12 18:02:22 +00:00
Sergio ab048a9ed8 estado: cosecha granja 2026-09-12T17:32:27Z — avance del árbol KDE 2026-09-12 17:32:27 +00:00
Sergio dad5e14a8e estado: cosecha granja 2026-09-12T17:02:20Z — avance del árbol KDE 2026-09-12 17:02:20 +00:00
Sergio 5a2e504a44 estado: cosecha granja 2026-09-12T16:32:21Z — avance del árbol KDE 2026-09-12 16:32:21 +00:00