Commit Graph
1029 Commits
Author SHA1 Message Date
Sergio f1b758b77c estado: cosecha granja 2026-09-10T08:02:15Z — avance del árbol KDE 2026-09-10 08:02:15 +00:00
Sergio 7727fa0172 estado: cosecha granja 2026-09-10T07:31:55Z — avance del árbol KDE 2026-09-10 07:31:55 +00:00
Sergio cbfa60a7f0 estado: cosecha granja 2026-09-10T07:01:53Z — avance del árbol KDE 2026-09-10 07:01:53 +00:00
Sergio 97c0e62062 estado: cosecha granja 2026-09-10T06:31:54Z — avance del árbol KDE 2026-09-10 06:31:54 +00:00
Sergio 7e137edde3 estado: cosecha granja 2026-09-10T06:02:22Z — avance del árbol KDE 2026-09-10 06:02:22 +00:00
Sergio 6a1d1ac239 estado: cosecha granja 2026-09-10T05:33:22Z — avance del árbol KDE 2026-09-10 05:33:22 +00:00
Sergio b1a1f92592 estado: cosecha granja 2026-09-10T05:03:25Z — avance del árbol KDE 2026-09-10 05:03:25 +00:00
Sergio 476fb74a5a estado: cosecha granja 2026-09-10T04:33:31Z — avance del árbol KDE 2026-09-10 04:33:31 +00:00
Sergio b32c80eb5d estado: cosecha granja 2026-09-10T04:03:46Z — avance del árbol KDE 2026-09-10 04:03:46 +00:00
Sergio a00debe182 estado: cosecha granja 2026-09-10T03:32:07Z — avance del árbol KDE 2026-09-10 03:32:07 +00:00
Sergio 3441a6129f estado: cosecha granja 2026-09-10T02:02:17Z — avance del árbol KDE 2026-09-10 02:02:17 +00:00
Sergio e3d984475a estado: cosecha granja 2026-09-10T01:32:00Z — avance del árbol KDE 2026-09-10 01:32:00 +00:00
Sergio 1d2d636bba estado: cosecha granja 2026-09-10T00:32:07Z — avance del árbol KDE 2026-09-10 00:32:08 +00:00
Sergio fb748370e1 estado: cosecha granja 2026-09-10T00:02:52Z — avance del árbol KDE 2026-09-10 00:02:53 +00:00
Sergio cf574c5bc4 estado: cosecha granja 2026-09-09T23:32:00Z — avance del árbol KDE 2026-09-09 23:32:00 +00:00
SergioandClaude Opus 5 7b38e2ef16 kde: los portales — segundo hueco cerrado, y OBS ya tiene con quién hablar
Medido recorriendo los `.service` de D-Bus de TODO el store: los únicos backends de portal sellados
eran los de COSMIC y GNOME. Ninguno de KDE, y la cola `incoming-kde` no tenía ni el frontend.
Consecuencia concreta: la imagen KDE trae `obs-studio` con su plugin linux-pipewire, que captura
pantalla POR EL PORTAL — o sea que en Plasma no tenía con quién hablar mientras en los otros dos
escritorios ese frente estaba cerrado. Sin portal tampoco hay diálogo de fichero ni compartir
pantalla para nada que los use.

Van los DOS paquetes porque la cadena es de tres:
  cliente → org.freedesktop.portal.Desktop [frontend] → org.freedesktop.impl.portal.* [backend]
El frontend se copia de la cola de COSMIC y **comparte artefacto**: hash idéntico (ecbe13f68eca6)
desde las dos colas ⇒ un solo directorio en el store, cero builds.

El backend es receta NUEVA, 6.7.2 — la MISMA versión que plasma-workspace, kwin y kscreenlocker de
esta cola, porque habla interfaces privadas de kwin para el ScreenCast y desalinear ahí es pedir que
dos mitades del mismo release se entiendan por casualidad. **Cero frontera nueva**: sus 22
dependencias (Qt6, KF6, KWayland, protocolos de Wayland, xkbcommon) ya estaban todas, verificadas
una por una antes de escribir la receta.

⚠ SIN EL PORTAL DE IMPRESIÓN, y la causa es más honda que el error. El build moría en
`src/print.cpp:27` con `'QtPrintSupport/private/qcups_p.h' file not found`, y la cadena está medida
entera: no hay NINGUNA receta de cups en el catálogo ⇒ qtbase 6.11.1 se construyó sin CUPS ⇒ su
`QtPrintSupport/private/` trae qpaintengine_alpha_p.h y qprintengine_pdf_p.h pero NO qcups_p.h.
No falta una cabecera: falta el subsistema. Un portal de impresión sin con qué imprimir no es
funcionalidad que se pierde, es código muerto que no enlaza.

Upstream no expone `option()` para portales —se compilan todos—, así que el parche va en TRES
sitios y no en uno: la fuente, la instanciación (desktopportal.cpp/.h) y **la lista de interfaces
que el backend ANUNCIA**. El tercero es el que se olvidaría y el que importa: anunciar
`impl.portal.Print` sin implementarlo hace que el frontend enrute a un portal que no contesta, que
es peor que no tenerlo. Cada `sed` lleva su `grep` de verificación al lado, para que el día que
upstream mueva esas líneas el parche falle RUIDOSO en vez de volverse inerte.

VERIFICADO sobre el artefacto sellado: publica `org.freedesktop.impl.portal.desktop.kde.service`,
y su `kde.portal` anuncia 17 interfaces con **0 apariciones de Print** e incluyendo ScreenCast,
Screenshot y RemoteDesktop, que es exactamente lo que OBS necesita. Y sobre el rootfs hidratado:
están el frontend (`org.freedesktop.portal.Desktop.service`), el backend y el `kde.portal`.

⚠ Y la licencia casi la firmo mal: leí la cabecera de UN fichero y generalicé. Contadas las
etiquetas SPDX del árbol entero: 88 `LGPL-2.0-or-later`, 23 de la fórmula de KDE e.V. y 1
`GPL-2.0-or-later`. El binario las enlaza a todas ⇒ la expresión es la CONJUNCIÓN.

El perfil pasa a 98 raíces, 361/361 listo, deuda 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 23:17:42 +00:00
Sergio 894bfaf0f5 estado: cosecha granja 2026-09-09T23:02:09Z — avance del árbol KDE 2026-09-09 23:02:09 +00:00
SergioandClaude Opus 5 c599daa346 SDD 28: el servidor de producción — y perfil.servidor declarando la deuda que no se ve
El frente arranca con el inventario MEDIDO de gioser, no con un plan: PID 1 es `arje-zero` (nuestro
init ya gobierna un servidor real, aunque sobre userland Artix), Hetzner Cloud arranca por **BIOS**
—que es justo el layout que `takana-install.sh` ya escribe— y el kernel propio trae VIRTIO/EXT4 `=y`
con `netup` haciendo DHCPv4, que es exactamente el caso de una caja hcloud.

Dos hallazgos que cambian el trabajo:

- **La secuencia de arranque de gioser no está escrita en ningún lado.** `rc-status` dice `stopped`
  para caddy, gitea, sshd, cronie y act-runner y los cinco están VIVOS colgando de PID 1. Un
  `arje-absorb --from openrc` produciría una Semilla perfecta que no levanta el servidor.
- **La mitad del Caddyfile describe un servidor que ya no existe**: 4 de 19 dominios sin DNS y sin
  ficheros en `/var/www`, uno en 502. Una mudanza fiel copia también la basura ⇒ la regla queda
  escrita: no se muda lo que no responde.

`[perfil.servidor]` hereda `cli` (SDD 27 §7.1) y declara 5 raíces que existen (openssh, caddy, curl,
wget, tmux) y **5 que NO** (takana, chrony, nftables, cronie, logrotate). Quedan `wanted`, y `wanted`
no es `debt` ⇒ `drenaje.json` seguirá diciendo `deuda=0`. Se declaran igual: sin ellas el perfil
saldría N/N —completo y verde— describiendo un servidor sin hora, sin cortafuegos y sin latido. Es
la lección de `foot` en escritorio-sway, pagada por adelantado. Cuenta esperada: 5, verificada
resolviendo cada nombre contra el campo `name` de las 869 recetas.

La peor de esas cinco: **takana no tiene receta**. El corpus construye 869 y no la suya, así que el
host no puede instalar takana desde el repo de takana — el bloqueante de que el servidor se sirva a
sí mismo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RomoxEGZUhaT4pob1QSX5x
2026-09-09 22:53:55 +00:00
Sergio 96c7d2dfc9 estado: cosecha granja 2026-09-09T22:31:57Z — avance del árbol KDE 2026-09-09 22:31:57 +00:00
SergioandClaude Opus 5 c20372597a targets: kde/gnome/cosmic heredan cli — las imágenes ya no salen sin shell ni red
Paso 1 del SDD 27. Resultó ser UNA LÍNEA POR PERFIL: el mecanismo `hereda` ya existía en
`scripts/targets.py` —transitivo, con detección de ciclos y orden preservado— y `escritorio-sway`
ya lo usaba desde el 2026-08-07. Los otros tres nunca lo declararon, y eso no era una decisión: era
composición no declarada.

LO QUE ARREGLA, medido antes: de los 27 paquetes del perfil `base`, la clausura de escritorio-kde
alcanzaba DOS. Contra el rootfs real: sin `bash`, sin `sudo`/`doas`, sin `git`, sin `useradd`, sin
`gpg` y **sin `dhcpcd`** —o sea sin con qué pedir una IP—; y lo que parecía estar (`ip`, `mount`,
`fsck`) eran applets de busybox (`/sbin/ip → ../bin/busybox`).

DESPUÉS, verificado hidratando de verdad y no leyendo el grafo: en el rootfs aparecen `bash`,
`sudo`, `doas`, `git`, `dhcpcd`, `useradd`, `gpg`, `rg`, `fd`, `bat`, y `/sbin/ip` pasa a ser el
BINARIO de iproute2 en vez del applet.

  raíces  kde 49→96 · gnome 39→86 · cosmic 43→88
  nodos   kde 301→356 · gnome 204→256 · cosmic 162→216
  deuda   0 en los tres — no hubo que construir NADA, ya estaba todo sellado
  colisiones nuevas al hidratar: CERO (los 28 .hammer-tmp son los de gmp/mpfr de antes)

⚠ `escritorio-mirada` NO hereda a propósito: es el rootfs *slim* del USB y sumarle 47 raíces
contradice su razón de ser. Si algún día se quiere, es la misma línea.

`kde-rootfs` en el volumen se rehidrató con la herencia (11 G) para que el nombre canónico no quede
viejo — que es el error que este mismo día costó encontrar en GNOME y COSMIC. El rootfs FUNDIDO y la
imagen siguen siendo los de antes: rehacerlos es un paso aparte.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 22:31:12 +00:00
Sergio c4ebb9f5c7 estado: cosecha granja 2026-09-09T22:03:08Z — avance del árbol KDE 2026-09-09 22:03:08 +00:00
SergioandClaude Opus 5 542d9875fb kde: upower — la imagen declaraba powerdevil y no tenía batería
Primero de los dos huecos que dejaban a KDE POR DEBAJO de una instalación estándar. El perfil
declaraba `powerdevil` —el gestor de energía de Plasma— pero no a `upower`, que es con quien
powerdevil habla para leer la batería y aplicar perfiles. Medido: upower sólo existía en la cola de
GNOME, y las colas no se ven entre sí (HERMANO→corpus, nunca de reojo). En un portátil eso es un
escritorio sin indicador de batería, y el arranque no falla ⇒ no se ve hasta usarlo.

Cuesta TRES recetas y no siete, y la diferencia es una perilla: `-Dintrospection=disabled`.
GNOME la necesita ENCENDIDA porque su shell hace `imports.gi.UPowerGlib` desde JavaScript, o sea que
carga el typelib. powerdevil NO: habla D-Bus con `org.freedesktop.UPower`. Apagarla saca de la
frontera gobject-introspection, gi-foreign-girs, glib-introspected y py3-setuptools, que sólo viven
en la cola de GNOME.

⚠ Y NO SE PROMUEVEN AL CORPUS, aunque era lo primero que intenté. Al mover `libgudev` allá su
ArtifactHash CAMBIÓ (7404bc8d → 87ca5e73) y eso no es una mudanza: `glib` existe en las DOS colas y
son recetas distintas, así que desde `incoming-gnome/` se construye contra la glib de GNOME y desde
el corpus contra la del corpus. Promoverla habría arrastrado a GNOME a la glib del corpus — el
cuadro de las «dos glib» que este repo ya pagó caro. Revertido y verificado que vuelve al hash de
antes (7404bc8d), o sea GNOME intacto. Se COPIAN a la cola de KDE.
`udev-pc` sí comparte artefacto (sus deps son sólo pkgconf ⇒ mismo hash desde las dos colas, un
solo directorio en el store). `libgudev` es otro a propósito, por la glib.

VERIFICADO sobre el artefacto sellado, no supuesto: trae `usr/libexec/upowerd`, el
`org.freedesktop.UPower.service` de system-services y su política en `system.d` — que es exactamente
lo que powerdevil necesita para que el demonio arranque por activación D-Bus.

El perfil pasa a 49 raíces, 301/301 listo, deuda 0.

Queda el segundo hueco: KDE no tiene backend de portal (ni `xdg-desktop-portal` en su cola), o sea
que no hay compartir pantalla — y en particular la captura de obs-studio, que la imagen ya trae, no
tiene con quién hablar en Plasma. Eso es más caro: pide traer el portal a la cola y ESCRIBIR
`xdg-desktop-portal-kde`, que no existe como receta en ninguna cola.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 22:02:49 +00:00
Sergio d57bbaabae estado: cosecha granja 2026-09-09T21:02:12Z — avance del árbol KDE 2026-09-09 21:02:12 +00:00
SergioandClaude Opus 5 e1d58cc583 cosmic: hidratar desde el perfil — su lista a mano se saltaba 17 declarados
Misma divergencia que se encontró ayer en GNOME, medida igual: `hydrate-cosmic.sh` nombra 25 raíces
escritas a mano dentro del script, el perfil `escritorio-cosmic` declara 43, y **17 paquetes
declarados no llegaban al rootfs**:

  adwaita-cursors · xkeyboard-config · bash · atuq (el navegador) · mpv · swayimg
  zathura + zathura-pdf-poppler · dejavu-fonts y dejavu-fonts-nerd · libnotify
  desktop-file-utils · hicolor-icon-theme · y las cinco *-shared de runtime

⚠ EL PRIMERO NO ES UNA COINCIDENCIA: `adwaita-cursors` es EXACTAMENTE el ejemplo con el que la
cabecera de `scripts/hydrate-profile.py` advirtió de esto el 2026-09-04 — «se añadió a las raíces de
cosmic y sway, y los scripts de hidratación, que no la conocen, habrían seguido armando un rootfs
sin cursores». No era hipotético: seguía pasando hoy, cinco días después. Y `xkeyboard-config` es la
cicatriz de sway repitiéndose: sin él el compositor arranca sin mapa de teclado.

Y AL REVÉS NO SE PIERDE NADA, que es lo que hace el cambio barato y lo separa del caso GNOME (donde
primero hubo que mover 11 raíces de runtime al perfil): de las 25 del script, la única que el perfil
no declara es `zlib-shared`, y la clausura del perfil la alcanza igual. O sea que el motivo que
justificaba la lista a mano —los componentes que `cosmic-session` lanza por PATH, que ningún grafo
de build ve— YA ESTÁ RESUELTO en el perfil, que los declara todos como raíces. La lista quedó
redundante sin que nadie lo notara.

VERIFICADO HIDRATANDO, no leyendo: `hydrate-profile.py escritorio-cosmic` proyecta 162/162 nodos
(24166 ficheros, 4,8 G) y ahí están los 17. (Ojo con la sonda: `bash` instala en `/bin/bash`, no en
`/usr/bin` — mi primer chequeo lo dio por ausente y era el chequeo el que miraba mal.)

⚠ Y UN DATO QUE MATIZA EL DIAGNÓSTICO Y LO EMPEORA. El rootfs que hay en disco
(`escritorios/cosmic-rootfs`, 3,9 G) SÍ tiene cursores, xkb y mpv — o sea que no se armó con la
lista por defecto, alguien le pasó raíces a mano. Y aun así le falta `atuq`. El problema real no es
que la lista esté mal: es que **lo que llega a la imagen depende de lo que alguien se acuerde de
teclear**. Derivarlo del perfil quita esa variable.

El script se deja porque su cabecera documenta por qué COSMIC necesita raíces de runtime explícitas
—sigue siendo cierto sobre la naturaleza de cosmic-session—; lo que ya no es cierto es que su lista
sea la verdad. Los dos armadores de imagen (qemu y metal) ahora apuntan a `hydrate-profile.py`.

── Y de paso, una nota vieja de targets.toml corregida ────────────────────────────────────────────
Decía que el perfil de KDE «son 13 raíces de ARRANQUE EN METAL, no la imagen completa», con
konsole/kate/dolphin y otras 19 apps selladas y sin declarar. Ya no: hoy son 48 raíces, con esas
apps, las fuentes y las *-shared declaradas — el frente KDE lo reordenó y la nota quedó atrás.
De su cola quedan 8 recetas fuera del perfil y son las que corresponde: libICE, libSM, libXtst y los
cinco eslabones huérfanos de xwayland desde que se retiró su receta.
Lo que a KDE le queda es OTRO problema, también medido hoy: su imagen no se hidrata del perfil sino
de un rootfs YA ARMADO (8,4 G) que nadie re-deriva. De las 18 hojas del perfil están 15 — faltan
`obs-studio` y `atuq`, justo las dos añadidas después de esa hidratación. Re-hidratarlo es decisión
del frente KDE.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 20:54:51 +00:00
Sergio 604255949b estado: cosecha granja 2026-09-09T20:32:20Z — avance del árbol KDE 2026-09-09 20:32:20 +00:00
Sergio c423abadea estado: cosecha granja 2026-09-09T20:19:14Z — avance del árbol KDE 2026-09-09 20:19:14 +00:00
Sergio 63df96e204 estado: cosecha granja 2026-09-09T20:01:51Z — avance del árbol KDE 2026-09-09 20:01:51 +00:00
SergioandClaude Opus 5 eb8f217245 gnome: el perfil y el hidratador decían cosas distintas — 21 paquetes no llegaban a la imagen
Verificando que las extensiones de la tanda anterior llegaran al rootfs apareció algo bastante peor
que lo que fui a buscar: **`scripts/gnome/hydrate-gnome.sh` no lee `targets.toml`**. Arma el rootfs
desde una lista de 14 raíces escrita a mano dentro del propio script, y de las 28 raíces que el
perfil declaraba sólo DOS coincidían.

MEDIDO recorriendo la clausura de esa lista (123 recetas) contra la membresía del perfil: **21
paquetes declarados en `escritorio-gnome` no llegaban al rootfs hidratado**. No son accesorios —
son las hojas, que es justo lo que un perfil declara porque no es dep de build de nadie:

  atuq (el navegador) · foot (la terminal) · helix (el editor) · mpv · swayimg (el visor)
  zathura + zathura-pdf-poppler (el lector de PDF) · dejavu-fonts y dejavu-fonts-nerd (las FUENTES)
  xdg-desktop-portal-gnome · libnotify · desktop-file-utils
  bzip2-shared, expat-shared, libffi-shared, ncurses-shared, xz-shared (las .so que se cazaron el
  2026-09-03 recorriendo NEEDED, justamente para que el rootfs no resolviera contra el lab)
  y las cuatro de ayer: las tres extensiones y gnome-tweaks

O sea que el trabajo de descubrir que la imagen no tenía terminal, ni editor, ni una sola fuente
—con su análisis largo escrito en este mismo fichero— estaba DECLARADO y no llegaba.

Y la divergencia iba en los dos sentidos: 11 raíces de RUNTIME vivían sólo dentro del script y el
perfil no las conocía (accountsservice, geoclue, libgdm, libgweather, upower, librsvg, ibus, los dos
gi-*-typelibs, gsd-schemas y wireplumber). Sin ellas el shell no arranca: las carga por
`imports.gi.*`, que es invisible para la clausura de deps.

ARREGLO: las 11 se mueven a `targets.toml` con la justificación que el script ya traía bien escrita,
y el script queda marcado como SUPERADO por `scripts/hydrate-profile.py`, que hidrata desde el
perfil — la única declaración que existe. Su propia cabecera ya advertía de este modo de fallo
(«DOS fuentes de verdad para lo mismo, y divergen sin que nada lo diga»); esto es esa advertencia
cumpliéndose. El perfil pasa de 28 a 39 raíces y de 190 a 204 nodos, deuda 0.

VERIFICADO HIDRATANDO DE VERDAD, no leyendo: `hydrate-profile.py escritorio-gnome` proyecta
210/210 nodos (27993 ficheros, 3,5 G) y ahí están las tres extensiones, `gnome-tweaks` con su
módulo `gtweak`, y los tres gschemas en el directorio GLOBAL. Después se corrió el bloque nuevo del
lanzador contra ESE árbol: enumeró las tres, escribió el override y `glib-compile-schemas` salió 0
con stderr vacío.

⚠ DOS COSAS QUE APRENDÍ MIDIENDO Y CONVIENE QUE ESTÉN DICHAS:

1. **El hub NO puede hidratar GNOME hoy.** `gjs`, `gnome-shell` y `spidermonkey` salen «no sellado»
   localmente. No es deriva ni un grafo mintiendo: sus hashes vigentes SÍ están en
   `work/farm-sellados.txt` — o sea sellados EN EL WORKER — y la cosecha baja el manifiesto y no el
   store, a propósito (bajarlo deshacía la poda). `build-state` los cuenta bien porque mira también
   el manifiesto; `hydrate-profile.py` mira sólo el disco local. Los dos tienen razón.
2. **EXDEV entre bind-mounts, otra vez.** Hidratar a `work/` o a `work/out` falla con «Invalid
   cross-device link» AUNQUE `work/out` esté en el mismo /dev/sdb que el store: son bind-mounts
   distintos y `linkat()` no cruza montajes. Hay que hidratar accediendo al store por su montaje
   raíz (`--store /mnt/cosecha/store --into /mnt/cosecha/escritorios/…`). El mensaje de error del
   script lo dice y aun así me costó dos intentos.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 19:56:19 +00:00
SergioandClaude Opus 5 70a1593f57 triaje: corrijo pygobject — no era «opcional», ya la teníamos como py3-gobject
Lo destapó empaquetar gnome-tweaks: su meson pide `pygobject-3.0 >= 3.46` y resolvió sin receta
nueva, porque `recipes/incoming-gnome/py3-gobject.toml` ES PyGObject 3.50.0 —la escribió el frente
GNOME para el build de libgweather— y publica `pygobject-3.0.pc`.

Esta mañana la firmé `opcional` razonando que sólo la usan los tests de libsecret y modemmanager.
Eso sigue siendo cierto para esas dos recetas, pero el veredicto estaba mal de CATEGORÍA: `opcional`
dice «no la queremos» y el hecho es «ya la tenemos». La diferencia no es cosmética — un `provisto`
realimenta el sembrador como alias y la saca de la frontera; un `opcional` la deja saliendo en cada
barrido.

OCTAVO alias, y estrena la sexta forma de fallar el cruce por nombre: el prefijo `py3-` de nuestro
catálogo contra el nombre de upstream. Las anteriores eran puntuación (nlohmann_json), mayúsculas
(libxfont_2), prefijo lib (gusb), versión en el nombre (glad2) y homonimia cruzada (libmpc/mpc).

Y la lección de método, que es la que vale: el veredicto de esta mañana lo saqué mirando SÓLO a
quién la pedía y por qué. No miré si el catálogo ya la tenía bajo otro nombre — que es justo la
comprobación que la categoría `provisto` existe para hacer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 19:42:51 +00:00
SergioandClaude Opus 5 4e4a2c8d2a gnome: dash-to-panel, appindicator y gnome-tweaks — y la lista de activas sale de las recetas
GNOME deja de ser la cáscara: tres extensiones y la app que el proyecto no instala y todo el mundo
termina instalando. El perfil queda 190/190 con 28 raíces, deuda 0.

  dash-to-panel v73   junta dash, ventanas y bandeja en una sola barra (lo que más cambia el uso)
  appindicator v64    devuelve los ICONOS DE BANDEJA que GNOME quitó; sin ella las apps que usan
                      StatusNotifierItem corren y no tienen dónde mostrarse
  blur-my-shell v72   (ya estaba; se le saca el override, ver abajo)
  gnome-tweaks 46.1   tema, iconos, cursor, tipografías, los botones de minimizar/maximizar que
                      GNOME esconde, y el interruptor de las extensiones

⚠ LA LISTA DE ACTIVAS SE MUEVE A UN SOLO SITIO, y esto era una bomba de relojería. `enabled-extensions`
es un ARRAY: un override de GSettings lo escribe ENTERO. Con la primera extensión el override vivía
en su receta y funcionaba; con la segunda NO se habrían sumado — ganaría la que compile última
(orden alfabético) y las otras quedarían instaladas y MUERTAS, sin un solo error. Ahora la arma
`scripts/gnome/gnome-start-qemu.sh`, que ya compilaba los esquemas al arrancar, enumerando los uuid
presentes en /usr/share/gnome-shell/extensions. La política es «lo que la imagen instala, se
activa»; el dconf del usuario gana sobre el default.
Una receta NO puede ser ese sitio: hammer exige `[source]` en toda receta («missing field `source`»),
así que no hay forma de escribir una receta de pura política. Se probó el bloque contra un árbol de
juguete: lista las dos extensiones, salta un directorio sin metadata.json, el override compila con
stderr vacío y `gsettings get` devuelve las dos. Y si la lista cambia borra `gschemas.compiled` para
forzar recompilación — sin eso, una imagen ya arrancada ignoraría la extensión nueva en silencio.

⚠ EL HALLAZGO CARO: `msgfmt` de gettext-tiny REVIENTA con las formas plurales del árabe. SIGILL,
exit 132, «index 6 out of bounds for type 'size_t[6]'», y deja un .mo de 0 bytes. Reproducido FUERA
de la receta con el binario sellado. No es el idioma sino el mensaje: blur-my-shell compila su
ar.po sin problema porque no tiene NINGÚN plural (msgstr[5] = 0); el de tweaks tiene exactamente
uno. Acá se saca `ar` del LINGUAS y se pierde la traducción de UNA app, con el diagnóstico escrito
en la receta. ARREGLARLO ES OTRA UNIDAD DE TRABAJO: gettext-tiny la usan 108 recetas.

Cada receta usa el mecanismo de SU upstream, que no es el mismo en las tres:
  blur-my-shell   `make build` llama a `gnome-extensions pack` —el CLI que nuestro shell apaga— así
                  que se copia el árbol a mano, con el layout LEÍDO del zip de EGO y comparado
                  contra él (idéntico, sin sobras ni faltantes)
  dash-to-panel   su Makefile tiene un `install` que honra DESTDIR y hace lo de un paquete de
                  distro: gschema y locale a los directorios GLOBALES. ⚠ `VERSION=73` se pasa a
                  mano porque sin ella el Makefile hace `git describe` y el árbol viene por
                  `git archive`, sin `.git` ⇒ metadata quedaría con el marcador "version": 9999
  appindicator    meson. ⚠ `-Dlocal_install=disabled` explícito: en `auto` decide mirando si el uid
                  es 0, o sea que hoy acierta POR ACCIDENTE — y si el lab dejara de correr como
                  root instalaría en $HOME/.local y el artefacto sellaría vacío. Y `jq` va en deps
                  aunque sea JavaScript puro: su meson saca el uuid del metadata.json con jq

⚠ gnome-tweaks NO costó ninguna receta nueva, y eso hubo que medirlo: su meson declara siete deps
mínimas de runtime y las siete ya estaban selladas. La que parecía traer una cadena de Python
entera —`pygobject-3.0`— la provee `py3-gobject`, que YA ESTABA en el corpus con otro nombre y
publica `pygobject-3.0.pc`. El nombre no es el hecho, otra vez.
Sí costó dos deps que el configure reclamó y que son el patrón `.pc Requires` → `[deps].build`:
`appstream` (la pide `libadwaita-1.pc` y el error culpa a libadwaita, que está bien instalada) y
`desktop-file-utils` (meson la busca como PROGRAMA para `update-desktop-database`).
Sus deps de RUNTIME —python3 y py3-gobject— van declaradas: es una app de Python, si no están en la
imagen se instala y no arranca, y ningún build lo delata.

Las cuatro licencias, verificadas en la fuente pineada y NINGUNA leída del COPYING —cuyo apéndice
«How to Apply» trae siempre la frase «or any later version»—: blur-my-shell del README del commit,
dash-to-panel y appindicator de la cabecera de sus fuentes, gnome-tweaks de su etiqueta SPDX.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 19:41:52 +00:00
Sergio 1b7e6f947b estado: cosecha granja 2026-09-09T19:31:49Z — avance del árbol KDE 2026-09-09 19:31:49 +00:00
SergioandClaude Opus 5 8c2cb10414 gnome: la primera extensión del catálogo — blur-my-shell v72, instalada Y activa
La imagen de GNOME traía la CÁSCARA: el shell sabe cargar extensiones —`ui/extensionSystem.js` va
en el gresource sin opción que lo apague y su gschema sellado trae `enabled-extensions`— pero no
había ninguna que cargar. Esta es la primera, y fija el patrón para las otras ~1400.

⚠ NO HIZO FALTA TLS, que era la conclusión fácil del análisis de ayer. glib-networking sólo lo pide
BAJARLAS desde extensions.gnome.org con el descargador del shell. Empaquetada, una extensión se
instala como cualquier receta y no toca la red.

LA FUENTE ES EL REPO DEL AUTOR, NO EL ZIP DE EGO, por dos razones y las dos medidas:
  1. hammer no sabe abrir un zip: el fetch extrae con `tar -x` y GNU tar contesta «This does not
     look like a tar archive». Ninguna receta del corpus usa .zip.
  2. Y aunque lo abriera, el zip de EGO es un ARTEFACTO que construye EGO desde este mismo repo.
     Pinear el zip es pinear el binario de un tercero; pinear el commit es pinear el código.
El tag v72 es el que EGO sirve para shell 48 —preguntado a su API, no supuesto— y el metadata.json
declara ['46','47','48','49','50']. ⚠ Eso hay que preguntarlo por extensión: nixpkgs va por GNOME
50 y hay extensiones que ya sólo declaran el major nuevo.

SIN `gnome-extensions pack`, que es lo que usa el Makefile de upstream y es el CLI que nuestra
receta del shell apaga (-Dextensions_tool=false; encenderlo costaría gnome-autoar y re-hashear
gnome-shell entero). No hace falta: `pack` sólo arma un zip que después alguien descomprime, y lo
que el shell lee es un DIRECTORIO. El layout no se inventó — se leyó del zip de EGO v72, que es la
salida de ese mismo `pack`, y el artefacto sellado se comparó contra él: **entradas idénticas, ni
sobras ni faltantes**, 45 .mo compilados.

⚠ INSTALADA ≠ ACTIVA, y esto es lo que hace que la receta sirva. El shell sólo carga lo que esté en
`org.gnome.shell enabled-extensions`: sin eso el artefacto sella, el fichero está en la imagen y NO
PASA NADA al arrancar — el mismo cuadro de «sellado ≠ instalado» que este repo ya se comió con
foot, mpv y libnotify, un escalón más abajo. Se resuelve con un override de GSettings, que cambia
el DEFAULT y deja ganar al dconf del usuario que no la quiera.
PROBADO DE VERDAD, no deducido: se compiló el directorio de esquemas del shell con el override
puesto (`glib-compile-schemas`, exit 0 y stderr vacío — que hay que mirar, porque sale 0 aunque
RECHACE un esquema) y después `gsettings get org.gnome.shell enabled-extensions` devolvió
['blur-my-shell@aunetx'].

⚠ TRAMPA ANOTADA PARA LA SEGUNDA: `enabled-extensions` es un ARRAY y el override lo escribe ENTERO.
Dos recetas con su propio override no se suman — gana la que compile última y la otra queda
instalada y muerta, sin error. Cuando llegue la segunda, la lista pasa a un solo sitio.

Y una corrección sobre la licencia, que casi firmo mal: el LICENSE es el texto del GPLv3, y su
apéndice «How to Apply» CONTIENE la frase «either version 3 … or any later version» siempre, así
que grepearla ahí no distingue -only de -or-later (la trampa que la memoria del repo ya tenía
escrita). La evidencia buena es el README del commit pineado: «This program is distributed under
the terms of the GNU General Public License, version 3 or later». El árbol JS no lleva cabecera de
licencia en ningún fichero.

Va de RAÍZ en escritorio-gnome por la lección de `foot` que targets.toml ya aprendió tres veces.
El perfil queda 183/183 listo con 25 raíces, deuda 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 19:14:08 +00:00
Sergio 49e65d147c estado: cosecha granja 2026-09-09T19:01:53Z — avance del árbol KDE 2026-09-09 19:01:53 +00:00
SergioandClaude Opus 5 71904ebbde xwayland: retirar la receta — la decisión ya estaba escrita y decía que no
Decisión del usuario (2026-09-09): X11 se erradica, y eso incluye no construir el servidor que lo
mantiene vivo. La receta se retira; `xwayland` VUELVE a ser lo que sus propios documentos decían.

⚠ LO QUE APARECIÓ AL MIRAR: esto ya estaba decidido, por escrito y DOS VECES, el 2026-09-03
(commit f64859ba):
  docs/state/targets.toml:143   «`xwayland` sigue acá como RAÍZ pero su receta NO se va a escribir:
                                 lo provee una imagen ajena enjaulada … el hueco se disuelve sin
                                 receta y sin tocar la postura Wayland-only»
  docs/state/qorpa-ajenos.toml  «X11 está fuera de alcance para toda la distro … el Xwayland vive
                                 DENTRO de la imagen —Arch y Fedora ya lo traen— y se cuelga de
                                 nuestro kwin por el socket. La receta no se escribe.»
El 2026-09-08 se escribió igual (3d8c6fc6, «cerrar los 3 huecos que quedaban»), y los dos
documentos siguieron diciendo lo contrario durante toda la jornada de hoy. No hubo que cambiar
ninguno de los dos: alcanzó con borrar la receta para que el repo volviera a coincidir con ellos.

MEDIDO ANTES DE SACARLA, no supuesto:
  · Sólo kwin podía lanzarlo. mutter va con -Dxwayland=false y wlroots con -Dxwayland=disabled ⇒
    GNOME, sway y COSMIC no podían usarlo aunque el binario existiera. Nunca sirvió a más de un
    perfil de los cuatro.
  · NINGUNA app del catálogo necesita servidor X: todo lo gráfico es Wayland nativo (Qt6 con
    qtwayland, GTK3 Wayland-only, mpv, OBS con ENABLE_WAYLAND=ON, foot, fuzzel, swayimg). El
    consumidor que lo justificaba está nombrado en qorpa-ajenos.toml y es Steam, que corre
    enjaulado y TRAE EL SUYO ADENTRO.
  · Y la imagen KDE ya arrancaba sin él: la propia receta contaba que KDE sellaba 1037/1037 con las
    apps X11 muertas. Esto no estrena una configuración, vuelve a una ya probada.

EFECTO EN EL GRAFO, verificado regenerando: `xwayland` deja de ser una receta y pasa a clase
`ajeno` —que es como targets.toml decía que había que contarlo— y el perfil escritorio-kde baja de
304 a 299 nodos con deuda 0. Los cinco que se van son la cadena que sólo él usaba.

⚠ QUEDAN CINCO RECETAS HUÉRFANAS, y no las borro de paso: `libfontenc`, `libXfont2`, `libxkbfile`,
`libxshmfence` y `xkbcomp`. Medido: NADA más en el catálogo las declara, y ninguna es raíz de
ningún perfil ⇒ siguen selladas pero no entran en ninguna imagen. Sacarlas es su propia unidad de
trabajo y su propia decisión.

El triaje pasa de `provisto` a `opcional` con la historia entera en su `porque`, y con eso se cae
el alias `xwayland xwayland` de alias-triaje.txt, que habría afirmado que tenemos una receta con
ese nombre.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 18:55:20 +00:00
Sergio 1d0d50cc95 estado: cosecha granja 2026-09-09T18:31:54Z — avance del árbol KDE 2026-09-09 18:31:54 +00:00
Sergio f08d729d8c estado: cosecha granja 2026-09-09T18:01:48Z — avance del árbol KDE 2026-09-09 18:01:48 +00:00
SergioandClaude Opus 5 d8f1280ae9 frontera: rebarrida con el triaje puesto — 334 → 319 candidatos, y CERO nuevos
El triaje sirve para algo o no sirve, y eso se mide corriendo el sembrador otra vez. Regenerados
los SIETE perfiles de `seed-frontera.json` (1,3 s cada uno: el eval de nix estaba cacheado).

  perfil               antes  ahora
  base                    41     41    +0
  cli                     44     44    +0
  escritorio-cosmic      148    143    -5
  escritorio-gnome       191    181   -10
  escritorio-kde         276    266   -10
  escritorio-mirada       39     38    -1
  escritorio-sway        175    171    -4
  UNIÓN                  334    319   -15

Los 15 que se fueron son EXACTAMENTE los que el lazo cerrado puede sacar: los siete alias
(bubblewrap, mesa-gl-headers, nlohmann_json, libxfont_2, gusb, glad2, libmpc), los nix-ismos
(CUnit, ffmpeg-headless, lzip, validate-pkg-config, python3-3.14.7-env) y tres que dejaron de ser
candidatos porque ahora TIENEN receta (bash-completion, desktop-file-utils, purpose).

Y **cero candidatos nuevos**, que era la otra mitad de la pregunta: el barrido no se movió por
debajo mientras lo triábamos.

⚠ LO QUE ESTE NÚMERO NO DICE. Los 327 veredictos `opcional` NO encogen la salida del sembrador —
sólo `nix-ismo` y `provisto` realimentan. Es correcto que así sea (un `opcional` es una decisión
nuestra, no un error de nixpkgs), pero significa que la frontera va a seguir saliendo con ~319
candidatos de los que 316 ya están contestados. Quien la lea tiene que cruzarla con
`frontera-triaje.toml`, no leerla sola: `scripts/triaje.py` sin argumentos ya lo hace y dice
«0 nuevos».

De paso: 46 candidatos quedaron marcados `ausente = true` (estaban en barridos viejos y ya no
salen). El fichero de triaje los conserva con su veredicto en vez de borrarlos, que es lo correcto
— si alguno vuelve, vuelve ya contestado.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 17:34:07 +00:00
SergioandClaude Opus 5 893b126c31 triaje: de 365 candidatos quedan TRES pendientes — y ninguno es «opcional»
Cierran las 24 que quedaban de una vuelta. El barrido de la frontera queda así: 327 opcional,
25 provisto, 10 nix-ismo, 3 pendientes. Arrancó la jornada en 152 pendientes.

⚠ SÉPTIMO ALIAS, y resuelve el enigma que dejé abierto esta mañana. libmpc → mpc: nixpkgs llama
`libmpc` a GNU MPC y `mpc` al cliente de MPD; acá GNU MPC se llama `mpc`. O sea que el «lo piden
mpc y yambar» de libmpdclient no era un error del sembrador cruzando mal: es que los dos catálogos
usan el MISMO nombre para paquetes DISTINTOS. Las dos puntas de esa confusión quedan cerradas.
Van siete alias y cinco formas: puntuación, mayúsculas, prefijo `lib`, versión en el nombre, y
ahora homonimia cruzada.

Lo demás, cada uno con su prueba en la receta o en el fuente: libev cae por el mismo
--enable-lib-only de nghttp2 que c-ares (configure.ac:230); graphite2 por -Dgraphite=disabled;
libliftoff por -Dlibliftoff=disabled; libtasn1 por -Dtrust_module=disabled; libasyncns por
-Dasyncns=disabled; inih por -DEXIV2_ENABLE_INIH=OFF contra un default ON; rdma-core por
--disable-rdma. nanosvg y resvg caen juntas porque fuzzel VENDORIZA nanosvg (su receta ya lo
decía) y fcft va con -Dsvg-backend=none. boost-build no hace falta porque la receta de boost es
sólo cabeceras. validate-pkg-config no es una librería sino un setup hook de nixpkgs → nix-ismo.

CAPACIDADES AUSENTES que quedan dichas: sin polkitd no corren las reglas .rules de JavaScript
(duktape); no se regula el brillo de un monitor EXTERNO por DDC/CI (ddcutil); los PDF con
tipografías CJK no incrustadas se ven mal (poppler-data); dolphin navega sin panel de metadatos
ni etiquetas (baloo-widgets).

⚠ LOS TRES QUE NO FIRMO, y por qué. No son «opcional»: son huecos de RUNTIME que ninguna receta
delata al construir, y decidirlos es elegir alcance de la distro, no triaje. Los tres con la
medición hecha y escrita en su `porque`:

  gnome-keyring   NINGÚN artefacto del store declara org.freedesktop.secrets (grep sobre el store
                  entero), y el artefacto de kwallet trae sólo libKF6Wallet.so, sin kwalletd6. Los
                  dos escritorios tienen el PROMPTER sellado y ninguno tiene el ALMACÉN
  glib-networking los usr/lib/gio/modules/ de los cuatro artefactos de glib están VACÍOS ⇒ GIO no
                  tiene TLS, y libsoup 3 delega el TLS en GIO ⇒ HTTPS mudo en el stack GNOME
  xdg-desktop-portal-kde  los únicos backends de portal sellados son el de cosmic y el de gnome; la
                  cola kde no tiene ni receta de xdg-desktop-portal ⇒ en Plasma la captura de
                  pantalla de obs-studio (linux-pipewire → portal ScreenCast) no tiene con quién
                  hablar, mientras que en GNOME y COSMIC sí

Los tres son el mismo patrón que ya nos costó una noche con las fuentes: una raíz que no resuelve
queda `wanted` y NINGUNA métrica lo dice. Marcarlos `hueco` los mete como raíz en targets.toml y
al drenaje; eso lo decide el usuario.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 17:04:16 +00:00
SergioandClaude Opus 5 f09927cc53 triaje: 26 más — quedan 27, y un Chromium entero colgaba de una VPN
De 53 pendientes a 27. Cierran okular, libsndfile, libpsl, libtiff, colord, libplacebo, zxing-cpp,
glib, modemmanager, plasma-nm y evolution-data-server.

⚠ EL HALLAZGO QUE ABARATA MÁS: qtwebengine. En plasma-nm, Qt6WebEngineWidgets se pide REQUIRED —
pero SÓLO dentro de `if(BUILD_OPENCONNECT)` (CMakeLists.txt:54-56). O sea que un Chromium entero
colgaba de la vista web de SSO de una VPN, y el -DBUILD_OPENCONNECT=OFF que la receta ya pasaba lo
saca del grafo. Vale la pena mirar dónde MÁS aparece qtwebengine antes de darlo por deuda.

⚠ DOS ALIAS MÁS, y cada uno estrena una FORMA nueva de fallar el cruce por nombre:
  gusb  → libgusb   el prefijo `lib` (libgusb 0.4.9, ya en el [deps].build de colord)
  glad2 → glad      la VERSIÓN metida en el nombre: recipes/glad.toml pinea la 2.0.8, que ES glad2.
                    nixpkgs parte glad(v1) y glad2(v2) en dos paquetes; acá hay uno solo
Van seis alias y cuatro formas distintas: puntuación, mayúsculas, prefijo y versión. Ya no es
casualidad — cuando el sembrador vuelva a tocarse, normalizar por ahí.

DOS BUNDLEOS que parecían deps y no lo son, los dos verificados en el fuente:
  zint  zxing-cpp lo trae adentro (CMakeLists.txt:7, ZXING_USE_BUNDLED_ZINT ON por defecto, y
        core/CMakeLists.txt:532 compila core/src/libzint)
  publicsuffix-list  la lista VIENE en el tarball de libpsl y --enable-builtin la hornea en el .so.
        Traerla aparte sería meter un dato mutable en un store direccionable por contenido

Y autogen es andamiaje, no dep: configure.ac:68 busca el PROGRAMA y si falta sólo hace
`touch tests/*.c`; el Makefile.am:414 dice que los ficheros generados vienen en el tarball
«to prevent stale files from calling autogen in tarball releases».

CAPACIDADES AUSENTES que quedan dichas: okular abre PDF pero no PostScript (libspectre), ni DjVu,
ni previsualiza Markdown; no hay cliente VPN AnyConnect (openconnect); no hay calibración de
pantalla por colorímetro (argyllcms) ni stack de escáner (sane-backends).

Quedan 27 pendientes, todos de 1×. Dos de ellos NO son «opcional» y no los firmo de paso —
gnome-keyring y glib-networking, los dos con la medición hecha y escrita.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 17:00:16 +00:00
SergioandClaude Opus 5 133e1dd802 triaje: 25 más — y una corrección: las opciones 'auto' NO son una escotilla del catálogo
De 78 pendientes a 53. Caen enteras opencv, swayimg, networkmanager, gwenview, appstream y
plasma-desktop.

⚠ CORRECCIÓN, y es de las que cambian lo que uno haría. En dos commits de hoy avisé que cairo
(lzo) y xwayland (libdecor) piden esas libs con `auto`/`required:false` y que «si entran al
catálogo, el ArtifactHash cambia sin que nadie lo pida». El mecanismo está mal: el sandbox de
hammer monta SÓLO las deps declaradas (docs/02-build-lab.md §3.4 — raíz tmpfs y bind read-only de
las deps del store), así que meterla en [deps] mueve hash_inputs y SE VE. La vía por la que un
`auto` sí muerde en silencio es otra y ya está documentada: que la lib aparezca en el LAB, que no
entra en hash_inputs. Los dos `porque` quedan corregidos en el fichero; el aviso sigue valiendo,
pero apunta al lab y no al catálogo.

Lo demás, cada uno con su prueba:
  opencv           -DBUILD_LIST=core,imgproc ⇒ de todo OpenCV se construyen DOS módulos: gflags y
                   glog son del dnn y hdf5-cpp del hdf, ninguno en la lista. eigen y openblas caen
                   por -DWITH_EIGEN=OFF y -DWITH_LAPACK=OFF, explícitos
  swayimg          -Davif/-Dheif/-Draw/-Dsixel=disabled, los cuatro escritos en la receta
  networkmanager   newt es la dep de nmtui y el propio meson lo dice en su assert (meson.build:806:
                   «Use -Dnmtui=false to disable it»), que es justo lo que pasamos; slang es su
                   back-end. bpftools cae por -Debpf=false
  gwenview         cfitsio (FITS de astronomía), libkdcraw (RAW) y kimageannotator son TYPE OPTIONAL
                   en su CMakeLists; qtimageformats no aparece ahí — son plugins de Qt de runtime
  appstream        -Dstemming=false para libstemmer
  plasma-desktop   kaccounts-integration es TYPE OPTIONAL y su PURPOSE lo dice («OpenDesktop
                   integration plugin»); xf86-input-evdev y xf86-input-libinput son drivers del
                   SERVIDOR X y la distro no corre uno; plasma-sdk no aparece en su CMakeLists

⚠ QUINTO, SEXTO Y SÉPTIMO DESFASE DE VERSIÓN: xapian, libfyaml y libblake3 no aparecen en NINGÚN
meson de AppStream 1.0.5, que es la que pineamos. Ya van siete candidatos que salen de expresiones
de nixpkgs más nuevas que nuestros pines (openapv, libebur128, spandsp, libglycin y estos tres).
Es un patrón, no una casualidad: cuando el `porque` heurístico dice «lo pide una sola receta»,
mirar primero si la versión pineada la nombra sale más barato que razonar sobre la feature.

⚠ dnsmasq no es una librería: NM la declara `type: 'string'` (meson_options.txt:10), una RUTA a un
binario que ejecuta. Capacidad ausente —compartir la conexión y el DNS con caché— no dep rota.

Y gnome-keyring sigue pendiente, ahora con la medición terminada escrita en su `porque`: el grep
sobre el store ENTERO dice que NINGÚN artefacto declara org.freedesktop.secrets, y del lado KDE el
artefacto de kwallet trae sólo libKF6Wallet.so — la librería cliente— sin kwalletd6. Los dos
escritorios tienen el prompter sellado y ninguno tiene el almacén.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 16:57:23 +00:00
SergioandClaude Opus 5 ed55f5bdfc triaje: mutter y gnome-shell — 9 más, y aparece el primer candidato que huele a HUECO
De 87 pendientes a 78. Las 4 de mutter y 5 de las 6 de gnome-shell. La sexta —gnome-keyring—
queda PENDIENTE a propósito y con motivo, abajo.

Las de mutter caen contra su meson leído, no contra su comentario:
  argcomplete   tools/meson.build:17 lo usa como PROGRAMA para generar el completado de bash de
                `gdctl`, dentro del bloque `if bash_completion` ⇒ -Dbash_completion=false lo mata.
                No se enlaza: no es una librería, es un generador
  sysprof       meson.build:453, `if have_profiler` ⇒ -Dprofiler=false
  libstartup-notification   default TRUE en meson.options:114 y la receta lo apaga a mano. Es el
                cursor «ocupado» de X11; en Wayland lo reemplaza xdg-activation, que mutter
                implementa nativamente ⇒ no se pierde la función, cambia de dónde sale
  libglycin     ⚠ CUARTO DESFASE DE VERSIÓN del barrido: mutter 48.8 no nombra glycin en ningún
                fichero. El cargador de imágenes enjaulado entra en la serie 49 de GNOME

Y las de gnome-shell:
  gdm            aparcado POR DISEÑO, targets.toml:263. La sesión la lanza arje
  gnome-autoar   sólo la pide extensions-tool (su meson.build:32) y va -Dextensions_tool=false:
                 desempaqueta el .zip de una extensión, no pinta escritorio
  gnome-clocks   cero referencias en los meson: es una APP que el panel consulta en runtime para
                 los relojes del mundo
  gnome-bluetooth  cero referencias, y el hueco de fondo es el mismo de ayer: no hay bluez
  libnma         ⚠ otra vez la etiqueta y el hecho: gnome-shell 48.8 NO la nombra. Su camino de red
                 es libnm + libsecret-1 (meson.build:106-108), apagado con -Dnetworkmanager=false

⚠ POR QUÉ gnome-keyring SIGUE PENDIENTE. Es el primero del barrido que no parece «opcional» sino
falta de verdad, y decidirlo cambia el trabajo de la granja (un `hueco` nace como raíz en
targets.toml y entra al drenaje), así que no lo firmo de paso. Lo medido hasta acá:
js/ui/components/keyring.js:221 hace `own_name('org.gnome.keyring.SystemPrompter')` ⇒ el shell es
el que PREGUNTA la contraseña, no el que guarda el secreto. El almacén es el demonio, y no hay
receta de gnome-keyring en el catálogo. libsecret está sellada, pero libsecret es el CLIENTE.
Del lado KDE hay kwallet y plasma-workspace publica org.kde.secretprompter.service, o sea que ese
perfil sí parece tener con qué. Queda una medición corriendo sobre el store entero (quién declara
org.freedesktop.secrets) y con eso se decide; si nadie lo declara, es hueco y hay que decirlo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 16:52:50 +00:00
SergioandClaude Opus 5 153725bf82 triaje: nodejs y pipewire enteros — 18 más, y la distro no tiene Bluetooth
De 105 pendientes a 87. Cuatro de las cinco recetas que más candidatos arrastraban ya están
cerradas (ffmpeg, obs-studio, xwayland, nodejs, pipewire).

Las 8 de nodejs son todas BUNDLEADAS, y no se dio por bueno el comentario de la receta: se listó
el propio node-v24.18.1.tar.gz y ahí están, deps/googletest, deps/histogram, deps/llhttp,
deps/merve, deps/nbytes, deps/simdjson, deps/uvwasi. simdutf es la excepción que confirma que
mirar sirve — NO está en deps/ de primer nivel sino en deps/v8/third_party/simdutf, que es
exactamente el fichero que la receta parchea para apagar el kernel AVX-512.

⚠ CAPACIDAD AUSENTE, y más honda que la perilla: ldacbt, libfreeaptx y liblc3 son los codecs de
audio Bluetooth (LDAC de Sony, aptX de Qualcomm, LC3 de LE Audio). Caen por -Dbluez5=disabled,
pero el hecho de fondo es que NO HAY receta de bluez en todo el catálogo: la distro no tiene
Bluetooth, ni de audio ni de nada. Eso conviene que esté dicho acá y no descubierto por alguien
que enchufa unos auriculares.

⚠ SEGUNDO Y TERCER DESFASE DE VERSIÓN del barrido (el primero fue openapv/ffmpeg): libebur128 y
spandsp no aparecen en NINGÚN fichero de pipewire 1.2.7, que es la que la receta pinea. Salen de
una expresión de nixpkgs para una pipewire más nueva. Van como 'opcional' y no 'nix-ismo' a
propósito, igual que openapv: mandarlas al descarte del sembrador las haría invisibles el día que
subamos de versión, que es justo cuando vuelven a ser una pregunta legítima.

El resto de pipewire son perillas apagadas a mano y verificadas contra su meson_options.txt:
libffado:350 (audio FireWire), libcamera:180, libmysofa:229 (HRTF de audio espacial), lv2:261
(lilv, el host de plugins) y roc:237 (audio en tiempo real por red).

Nota sobre el commit anterior: dije que convenía normalizar guiones y mayúsculas en seed-graph.py.
Medido después — normalizando nombre de candidato contra el campo `name` de las 1141 recetas, de
los 105 pendientes CERO son ese caso. nlohmann_json y libxfont_2 eran los únicos. Sigue siendo
buena profilaxis, pero no hay backlog que la pague: no se toca el sembrador por ahora.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 16:48:22 +00:00
SergioandClaude Opus 5 1ef1bea605 triaje: obs-studio y xwayland enteros — 20 más, y dos alias por PUNTUACIÓN
De 125 pendientes a 105. Las dos recetas más pedidas del ranking quedan sin un solo candidato
pendiente. Las de obs ya estaban medio contestadas en los comentarios de su propia receta; lo que
faltaba era mirar el ARTEFACTO y no sólo la línea de cmake.

⚠ DOS ALIAS MÁS, y los dos son el mismo defecto del sembrador: cruza por nombre literal.
  nlohmann_json → nlohmann-json   guion bajo vs guion
  libxfont_2    → libXfont2       minúsculas vs mayúsculas (primero de esta forma)
Las dos recetas existen, están selladas y ya figuran en el [deps].build de quien «las pedía».
Van tres alias por puntuación o caso (con mesa-gl-headers, cuatro en total): conviene normalizar
en seed-graph.py antes que seguir triándolos de a uno.

MEDIDO, NO DEDUCIDO — el artefacto sellado de obs-studio:
  · usr/lib/obs-plugins NO tiene obs-websocket.so ⇒ asio, websocket++ y qrcodegencpp no tienen a
    quién servir. El `touch plugins/obs-websocket/CMakeLists.txt` de la receta funciona.
  · readelf sobre los 13 plugins: CERO NEEDED a libcjson. El JSON que OBS enlaza es jansson.
  · obs-x264.so está y enlaza libx264.so.165 ⇒ la codificación H.264 del escritorio existe y no
    pasa por ffmpeg. Es lo que hace que -DENABLE_QSV11=OFF (libvpl) no cueste capacidad.

⚠ libxres es «la etiqueta no es el hecho» otra vez: lo que xwayland usa es `resourceproto`
(meson.build:90), las CABECERAS del protocolo XRes, que vienen en xorgproto y ya están en [deps].
libXres es la librería CLIENTE — el servidor IMPLEMENTA la extensión, no la consume.

⚠ Y libxaw/libxmu/libxpm/libxt no aparecen en NINGÚN meson del árbol: sólo en .appveyor.yml y
.gitlab-ci/debian-install.sh, que instalan las deps de todos los servidores del repo xserver
(Xorg, Xnest, Xvfb). El sembrador leyó la expresión de nixpkgs, que hereda esa lista entera.

⚠ SEGUNDA ESCOTILLA 'auto' de la jornada (la primera fue cairo/lzo): xwayland pide libdecor con
`required: false` y la opción en 'auto' (meson.build:210). Si libdecor entra al catálogo y cae en
su clausura, xwayland cambia de ArtifactHash sin que nadie lo haya pedido. Sólo decoraría la
ventana en modo ROOTFUL, que no es como lo lanza el compositor.

dri-pkgconfig-stub cierra limpio: include/meson.build:9 lo pide como
`dependency('dri', required: build_glx)` ⇒ obligatorio SÓLO con glx, y la receta va -Dglx=false
porque ninguna cola publica gl.pc. font-util aparece una vez y es el default de `fontrootdir`, la
raíz de las fuentes de mapa de bits legacy que la distro no publica.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 16:46:26 +00:00
SergioandClaude Opus 5 a43beeb352 triaje: las 15 de ffmpeg, medidas sobre el artefacto sellado
De 140 pendientes a 125. Todas caen por el mismo criterio ya establecido (--disable-autodetect ⇒
sólo entra lo que se pide, y no se pide nada), pero el veredicto NO se firmó de memoria: se midió
con nm/strings sobre store/…-ffmpeg/usr/lib/libavcodec.so.61.19.100, que es el artefacto que la
distro publica hoy.

LO QUE LA MEDICIÓN CAMBIA. La lectura fácil era «sin libaom/libvpx/x265 la distro no reproduce
AV1/VP9/HEVC», y es FALSA: los decoders nativos están compilados (aparecen «AV1 decoder», los bsf
vp9_*, hevc y theora). Lo que falta es CODIFICAR. El artefacto trae 34 encoders y ninguno de vídeo
moderno: AAC, FLAC, Opus, MPEG4, mjpeg, ffv1, prores, H.263, jpeg2000. O sea: la distro decodifica
lo de hoy y codifica lo de ayer.

Y esa frase tampoco alcanza sola, porque la codificación H.264 del escritorio NO pasa por ffmpeg:
obs-studio enlaza x264 —que SÍ está en el catálogo, recipes/x264.toml— por su propio plugin
obs-x264. Antes de anunciar «no se puede grabar vídeo» convenía mirar quién codifica de verdad.

⚠ openapv NO es una perilla que no encendimos: es DESFASE DE VERSIÓN. Sale de la expresión de
nixpkgs para ffmpeg 8.x y nuestra receta pinea 7.1, cuyo `configure` no nombra apv en ningún sitio
(verificado en el tarball). Queda 'opcional' y no 'nix-ismo' a propósito: el día que ffmpeg suba de
major vuelve a ser una pregunta legítima, y mandarla al descarte del sembrador la haría invisible.

⚠ ocl-icd y opencl-headers tienen el hueco una capa MÁS ABAJO: mesa va con -Dllvm=disabled
-Dgallium-rusticl=false ⇒ la distro no publica NINGÚN runtime de OpenCL. Un ICD loader sin ICD no
filtra nada; encender --enable-opencl en ffmpeg no compraría capacidad.

CAPACIDADES AUSENTES, dichas en voz alta y no descubiertas después:
  libbluray    no se navegan discos Blu-ray (menús, títulos, BD-J); los ficheros sueltos se leen
  libopenmpt   no suena música de módulos (MOD/XM/S3M/IT)
  amf-headers / libvdpau   codificación y decodificación por hardware de AMD y NVIDIA: piden driver
               propietario, que la distro no trae ⇒ discutible sólo si eso cambia
El resto no cuesta nada: libtheora es el encoder de un formato de 2004 (su decoder es nativo),
xvidcore es REDUNDANTE con el «MPEG4 encoder» nativo que ya está, vid.stab agrega dos filtros de
estabilización y zimg sólo el filtro zscale (el escalado lo hace libswscale, compilada).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 16:43:12 +00:00
SergioandClaude Opus 5 c15d4e15e2 triaje: caen los 10 que pedían 2 recetas — y un segundo alias
De 152 pendientes a 140. Con esto el ranking del triaje queda entero en 1×: ninguna candidata
la piden ya dos recetas. Cada veredicto con la prueba en el fuente o en la receta, no de memoria.

⚠ mesa-gl-headers NO faltaba — SEGUNDO alias del barrido (el primero fue bubblewrap→bwrap). Es
el split de cabeceras de nixpkgs: el artefacto de mesa instala usr/include/{GL,GLES2,GLES3,KHR,
EGL}, verificado en el store y no deducido. El único hueco es GLES1, apagado a propósito en la
receta (-Dgles1=disabled).

⚠ libmpdclient destapa una FALSA ATRIBUCIÓN del sembrador: dice que la piden mpc y yambar, y
recipes/mpc.toml es GNU MPC (aritmética compleja, --with-gmp --with-mpfr), no el cliente de MPD.
Homónimo. El sembrador cruza por NOMBRE, así que este no va a ser el único; conviene mirar el
`piden` antes de creerle cuando el nombre es corto y genérico.

⚠ lzo deja una escotilla abierta que conviene que esté dicha: libarchive pasa --without-lzo2
explícito, pero cairo NO la apaga — meson.options:19 la declara feature 'auto' y meson.build:203
la tomaría si apareciera en el sandbox (sólo la usa util/cairo-script). Si algún día lzo entra al
catálogo y cae en la clausura de cairo, cairo cambia de ArtifactHash sin que nadie lo pida.

El resto, con su prueba:
  c-ares         configure.ac:225 de nghttp2 la fuerza a `no` DENTRO de --enable-lib-only, que es
                 lo que la receta pasa ⇒ ni presente se usaría; nodejs bundlea la suya
  ada            nodejs la bundlea a propósito y la receta lo dice con nombre y apellido
  CUnit          → nix-ismo: nghttp2 1.64.0 no la nombra en ningún fichero, sus tests usan munit
                 VENDORIZADO en tests/munit/. Dep rancia de nixpkgs; no vuelve ni con tests ON
  egl-wayland    EGLStream de NVIDIA: mutter meson.options:84 la trae en false y no la pedimos, y
                 xwayland 24.1.13 ya no la soporta (hw/xwayland/meson.build:171 have_eglstream=false)
  glu            CERO referencias en phonon 4.12.0 y xwayland 24.1.13, grep sobre el árbol entero
  libssh         ffmpeg --disable-autodetect sin --enable-libssh; konsole no la nombra: su plugin
                 SSHManager (ON, y lo construimos) lanza el binario ssh, que el corpus SÍ tiene
  libxcb-errors  wlroots -Dxcb-errors=disabled y yambar -Dbackend-x11=disabled, las dos escritas
  dbus-python
  pygobject      sólo tests: mock-service*.py de libsecret; modemmanager -Dtests=false

Granja: las cinco colas selladas y deuda 0 (corpus 868, kde 1046, gnome 920, cosmic 894, wlr 879);
el worker está idle. Esto es trabajo de hub, que es lo que queda cuando no hay cola que drenar.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LCt3ettR4Z7b6wPCBmbvEV
2026-09-09 16:40:31 +00:00
Sergio f0f49c9e15 estado: cosecha granja 2026-09-09T16:31:49Z — avance del árbol KDE 2026-09-09 16:31:49 +00:00
Sergio db31cfd988 estado: cosecha granja 2026-09-09T16:02:25Z — avance del árbol KDE 2026-09-09 16:02:25 +00:00
Sergio a1f897ea2d estado: cosecha granja 2026-09-09T15:31:39Z — avance del árbol KDE 2026-09-09 15:31:39 +00:00
SergioandClaude Opus 5 7261e02157 triaje: 14 más — un alias verificado y otra capacidad ausente
De 166 pendientes a 152.

⚠ bubblewrap NO faltaba: es el MISMO paquete con otro nombre. nixpkgs lo llama 'bubblewrap',
acá es 'bwrap' (recipes/bwrap.toml) y su artefacto instala /usr/bin/bwrap. Verificado —receta,
artefacto y binario— y marcado 'provisto' con su alias, que es justo para lo que existe esa
categoría. Es el primer alias real que aparece en todo el barrido.

ffmpeg-headless → nix-ismo: variante de empaquetado, ya tenemos ffmpeg. Mismo criterio que
git-minimal.

gnome-settings-daemon → aparcado POR DISEÑO y ya documentado en targets.toml:263: 'SIN
gnome-session / gnome-settings-daemon / gdm'. El camino vivo de GNOME es mutter → gnome-shell.

⚠ SEXTA capacidad ausente: mobile-broadband-provider-info destapa que la distro NO TIENE BANDA
ANCHA MÓVIL — networkmanager con modem_manager=false y ppp=false, modemmanager con mbim=false
qmi=false. De ahí caen también ppp y sbc (éste por el bluez ya apagado).

El resto son el cubo de ffmpeg --disable-autodetect (nv-codec-headers, librist, lame, fdk-aac,
zvbi) más openexr (opencv WITH_OPENEXR=OFF), libjxl (swayimg jxl=disabled) y libjack2
(jack=disabled en las tres que lo piden).

⚠ Y una corrección de método: mi primera búsqueda de alias fue por subcadena y produjo basura
—'nv-codec-headers' casaba con 'unconvert.toml'—. Sólo se marcó el que se verificó de verdad.
libssh tampoco se tocó: tenemos libssh2, que es OTRA librería, y konsole no lo menciona.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 14:43:25 +00:00
Sergio f49f001760 estado: cosecha granja 2026-09-09T14:31:54Z — avance del árbol KDE 2026-09-09 14:31:54 +00:00