Commit Graph
2300 Commits
Author SHA1 Message Date
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
SergioandClaude Opus 5 b3fde53938 triaje: 12 más — y aparecen las capacidades que la distro NO tiene
De 178 pendientes a 166. Todos opcionales, todos con la prueba en la receta. Un hallazgo
transversal: ffmpeg lleva '--disable-autodetect', o sea que sólo entra lo que se pide
explícitamente y no se pide nada. Eso explica de golpe srt, speex, soxr y sdl2-compat.

  xorg-server   mutter x11=false xwayland=false, plasma-desktop X11=OFF
  unzip         sólo desempaqueta datos de test, y los tests están apagados
  umockdev      simula dispositivos en tests; sin tests no hay nada que simular
  tinysparql    gtk4 tracker=disabled ⇒ el selector de ficheros sin búsqueda por contenido
  sphinx        libtiff docs=OFF
  srt/speex/soxr/sdl2-compat   ffmpeg --disable-autodetect, obs ENABLE_NEW_MPEGTS_OUTPUT=OFF,
                pulseaudio soxr=disabled

⚠ TRES CON COSTE que conviene que estén dichos, no descubiertos:
  webrtc-audio-processing  pipewire echo-cancel-webrtc=disabled y pulseaudio webrtc-aec=disabled
                           ⇒ SIN CANCELACIÓN DE ECO. Se nota en videollamadas con altavoz.
  webkitgtk                ya estaba decidido: la cabecera de evolution-data-server dice que
                           apagar GTK4 'también borra ENABLE_OAUTH2_WEBKITGTK, que arrastraba
                           WebKitGTK — el paquete más caro'. Y gnome-shell portal_helper=false
                           ⇒ sin login OAuth2 en Evolution y sin ventana de portal cautivo.
  shaderc                  ⇒ ESTA DISTRO NO TIENE VULKAN. gtk4 vulkan=disabled, libplacebo
                           shaderc=disabled vulkan=disabled. Todo va por GL/EGL sobre mesa.

⚠ Y un detalle que el barrido destapó: mutter lleva 'xwayland=false'. KDE tiene Xwayland desde
ayer (receta propia) pero GNOME no ⇒ las apps X11 correrán en KDE y no en GNOME. Asimetría entre
imágenes que nadie había mirado.

Con bluez (sin audio Bluetooth) y la ausencia de OpenGL de escritorio ya anotadas, son cinco
capacidades que la distro no tiene. Todas por decisiones de construcción anteriores, ninguna
por olvido de esta frontera — pero ahora están escritas en un solo sitio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 14:30:26 +00:00
SergioandClaude Opus 5 3c628deeb6 purpose: el último hueco de la frontera, y enganchado a las tres apps
purpose 6.27.0 — el marco de «compartir» de KDE. 23 plugins (código de barras, bluetooth,
portapapeles, correo, imgur…) más sharefileitemaction.so, que añade «Compartir» al menú de
Dolphin.

Era el último hueco. La receta de okular lo degradaba con el flag oficial
FORCE_NOT_REQUIRED_DEPENDENCIES y su cabecera decía «los que no tenemos sellados» — un ESTADO,
no una preferencia. Ahora sale de esa lista.

⚠ Y va ENGANCHADO, no sólo autorado: una receta que nadie alcanza no arregla nada. okular sale
de la lista de degradados; gwenview y spectacle lo declaran (ninguna lo mencionaba: construían
sin él y el CMake se lo saltaba en silencio). Coste medido antes de tocar: las tres son hojas
con 0 dependientes transitivos ⇒ 3 builds, sin cascada.

La prueba es el enlace, no la intención: las tres referencian libKF6Purpose (2 cada una).

Un tropiezo con su lección: el CMake abortó pidiendo tres MÓDULOS QML —org.kde.prison,
org.kde.kitemmodels, org.kde.kcmutils— que no salen de ningún find_package. Los pide con
ecm_find_qmlmodule, o sea que comprueba que el IMPORT exista, no que la librería esté enlazada.
Las tres recetas ya existían y publicaban su qmldir; sólo faltaba pedirlas. Un requisito que no
se ve leyendo los find_package.

KAccounts6 NO se pide: su find_package va sin REQUIRED y arrastraría toda la torre de
kaccounts/signond que esta distro no tiene.

Verificado: REPRODUCE bit a bit · tarball en el mirror · escritorio-kde 304/304 sellado, deuda 0.

FRONTERA: 0 HUECOS.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 14:21:02 +00:00
Sergio ee8162fcf3 estado: cosecha granja 2026-09-09T14:03:18Z — avance del árbol KDE 2026-09-09 14:03:18 +00:00
SergioandClaude Opus 5 248fa8e991 desktop-file-utils: cerrar el «abrir con»
update-desktop-database construye la caché MIME→APLICACIÓN (mimeinfo.cache). Comprobado antes
de escribir la receta: NINGÚN artefacto del store lo traía, así que esa caché no se construía
nunca. Con shared-mime-info (cerrado ayer) el escritorio sabe QUÉ TIPO es un fichero; sin ésta
seguía sin saber CON QUÉ abrirlo — el menú «abrir con» vacío y sin aplicación por defecto.

Misma familia que aquel hueco: falla en RUNTIME, no en build. gnome-shell, libadwaita y mutter
lo piden en nixpkgs y acá construyen tan contentos sin él, así que ninguna métrica de deuda
puede verlo.

Prueba del consumidor con 14 .desktop REALES de okular/dolphin/kate/konsole/spectacle:
  mimeinfo.cache de 2.368 bytes · 47 asociaciones
  application/pdf=okularApplication_pdf.desktop
  text/plain=okularApplication_txt.desktop;org.kde.kate.desktop;org.kde.kwrite.desktop
Los 4 binarios estáticos con 0 NEEDED (--prefer-static desde el principio, no tras el error).
REPRODUCE bit a bit · tarball en el mirror.

Va como RAÍZ en los CUATRO escritorios y no en , y la razón importa: escritorio-kde y
escritorio-gnome comparten CERO raíces con base y bash NO está en su clausura. escritorio-mirada
documenta que no hereda «a propósito, es slim»; esos dos no dicen nada, y sway sí hereda cli.
Declararla en los cuatro funciona con cualquiera de las dos lecturas. La asimetría en sí queda
para decidir aparte: hoy «KDE 302/302» significa «la capa de escritorio está completa», no «la
imagen está completa».

Triaje: huecos 2 → 1 (queda ). Clausuras 303/182/160/205, todas selladas.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 13:40:46 +00:00
Sergio d6a43465c9 estado: cosecha granja 2026-09-09T13:31:51Z — avance del árbol KDE 2026-09-09 13:31:51 +00:00
Sergio 5fc2b0357b estado: cosecha granja 2026-09-09T13:01:38Z — avance del árbol KDE 2026-09-09 13:01:38 +00:00
Sergio 1512ae9762 estado: cosecha granja 2026-09-09T12:31:42Z — avance del árbol KDE 2026-09-09 12:31:42 +00:00
Sergio 70c1e72cc3 estado: cosecha granja 2026-09-09T12:02:28Z — avance del árbol KDE 2026-09-09 12:02:28 +00:00
Sergio 3479eade2c estado: cosecha granja 2026-09-09T07:01:32Z — avance del árbol KDE 2026-09-09 07:01:32 +00:00
Sergio ad299ba85c estado: cosecha granja 2026-09-09T05:01:40Z — avance del árbol KDE 2026-09-09 05:01:40 +00:00
Sergio ccf35904ad estado: cosecha granja 2026-09-09T04:31:31Z — avance del árbol KDE 2026-09-09 04:31:31 +00:00
SergioandClaude Opus 5 66abf69ebf triaje: 8 candidatos más, con dos huecos reales y dos costes que hay que decir
De 186 pendientes a 178. Cada veredicto con la prueba en la receta:

  libxdamage          opcional  gtk3/gtk4/mutter con el backend X11 apagado
  libsysprof-capture  opcional  gjs profiler=disabled, mutter profiler=false
  protobuf            opcional  opencv -DWITH_PROTOBUF=OFF (módulo DNN)
  fftw-single         opcional  pulseaudio fftw=disabled (ecualizador)

⚠ DOS OPCIONALES CON COSTE, que no es lo mismo que gratis:
  libopus   pipewire opus=disabled ⇒ el servidor de audio no codifica Opus. NO afecta a
            reproducirlo en el navegador (atuq trae su propio códec, medido en su día).
  bluez     pipewire Y pulseaudio con -Dbluez5=disabled ⇒ LA DISTRO NO TIENE AUDIO POR
            BLUETOOTH. No es un olvido de esta frontera: viene de cómo se construyeron esas dos
            recetas. Habilitarlo exige traer bluez y RE-HASHEAR las dos, que no es gratis.
            Queda escrito para que sea una decisión explícita y no un descubrimiento.

⚠ DOS HUECOS REALES:
  desktop-file-utils  provee update-desktop-database, que construye la caché MIME→APLICACIÓN.
                      Comprobado que NINGÚN artefacto del store lo trae. Con shared-mime-info ya
                      dentro, el escritorio sabe qué TIPO es un fichero y sigue sin saber CON QUÉ
                      abrirlo: el «abrir con» no funciona. Compañero natural del hueco de ayer.
  purpose             el marco de «compartir» de KDE (gwenview, okular, spectacle). La receta de
                      okular lo degrada con el flag oficial FORCE_NOT_REQUIRED_DEPENDENCIES y su
                      cabecera dice «los que no tenemos sellados»: un estado, no una preferencia.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 03:42:16 +00:00
Sergio c03a971144 estado: cosecha granja 2026-09-09T03:31:49Z — avance del árbol KDE 2026-09-09 03:31:49 +00:00
Sergio fe24285c4b estado: cosecha granja 2026-09-09T03:01:54Z — avance del árbol KDE 2026-09-09 03:01:54 +00:00
SergioandClaude Opus 5 1da6851775 bash-completion: cerrar el hueco del tabulador
bash es RAÍZ del perfil base —el shell de la distro— y cinco recetas repartidas en cuatro colas
(appstream, colord, gnome-shell, modemmanager, swayimg) instalan completados en el directorio
que este paquete define. Sin él NO los instalan y siguen adelante: nada falla, nadie se entera,
y el usuario se queda sin tabulador en las herramientas del sistema. Hueco de RUNTIME puro, de
los que ninguna métrica de deuda puede ver — por eso hizo falta la frontera para encontrarlo.

Va al CORPUS y como raíz de , no a una cola: lo alcanzan las cuatro imágenes de escritorio
y la CLI, y una receta resuelve sibling-first y después el catálogo padre, nunca una cola
hermana. Y entra como RAÍZ porque nadie lo alcanza por deps de build: los consumidores sólo
preguntan por su .pc.

Verificado como consumidor, las dos mitades:
  pkgconf --variable=completionsdir bash-completion → /usr/share/bash-completion/completions
  el marco carga 131 completados y complete  devuelve regla · 522 ficheros instalados
  REPRODUCE bit a bit · tarball en el mirror

Triaje: los huecos vuelven a CERO. base pasa de 26 a 27 raíces, clausura 58/58 sellada.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 02:48:20 +00:00
SergioandClaude Opus 5 854b839ae8 triaje: clasificar los 7 candidatos con más consumidores, con evidencia
Los 193 pendientes que destapó el barrido de sway y cosmic empiezan a bajar. Cada veredicto va
con la prueba en la receta, no con una corazonada:

  vala                 opcional  las 5 que lo piden llevan vapi=false explícito
  gi-docgen            opcional  gtk4 documentation=false, pango/libadwaita gtk_doc=false
  shiboken6-generator  opcional  las 8 recetas KF6 llevan -DBUILD_PYTHON_BINDINGS=OFF
  xvfb-run             opcional  sólo envuelve tests, y los tests no se corren
  libxinerama          opcional  gtk3/gtk4/mutter con el backend X11 apagado; es Wayland-only
  openjpeg             opcional  ⚠ CON COSTE: poppler -DENABLE_LIBOPENJPEG=none y swayimg
                                 jp2=disabled ⇒ un PDF con imágenes JPEG 2000 abre pero esas
                                 imágenes NO SE VEN. Decisión tomada, no olvido — pero queda
                                 escrito para que el día que alguien reporte 'este PDF sale con
                                 huecos' la respuesta esté acá.
  bash-completion      HUECO     bash es RAÍZ del perfil base, o sea el shell de la distro. Las 5
                                 que lo piden instalan sus completados en el directorio que ese
                                 paquete define y sin él no los instalan: nada se rompe y el
                                 usuario se queda sin tabulador. Barato: datos + un script.

De 193 pendientes a 186. Quedan los de 3 consumidores hacia abajo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 02:02:27 +00:00
Sergio cc7cbf6836 estado: cosecha granja 2026-09-09T01:01:33Z — avance del árbol KDE 2026-09-09 01:01:33 +00:00
SergioandClaude Opus 5 f984cbf9e7 frontera: derivar el grafo de la COLA — sway y cosmic eran invisibles
La lista de grafos que consulta 'frontera' estaba escrita a mano y sólo tenía corpus, kde y
gnome. Consecuencia: 'yupana frontera escritorio-sway' y '... escritorio-cosmic' fallaban con
'perfil sin nodos en ningún grafo de estado (¿regeneraste con build-state.py?)' — culpando a un
grafo viejo con los cinco frescos de hacía minutos. Dos escritorios enteros sin poder responder
'¿qué me falta?'.

⚠ QUINTA vez que cae el mismo cable en este repo: GNOME (2026-07-27), COSMIC (2026-08-03) y
wlr/sway (2026-08-26) en cosecha-cron.sh, keystones y duplicados (2026-09-08) en el mismo sitio,
y ahora acá. Las cuatro anteriores se arreglaron AGREGANDO una línea, que arregla el caso y deja
la trampa puesta. Esta vez el fichero se DERIVA de la cola que el perfil declara: corpus →
build-state.json, incoming-<x> → build-state-<x>.json. Una cola nueva trae su grafo sola.

Verificado con control: 'base' sigue usando build-state.json y dando los mismos 41 candidatos.
Y lo que estaba tapado aparece — sway 175, cosmic 148, gnome 191, kde 276.

El triaje pasa de 172 a 365 candidatos (193 nuevos). No es deuda nueva: es deuda que no se
podía ver. Los que más recetas piden encabezan la cola — gi-docgen y vala con 9 cada uno.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-09 00:20:35 +00:00
Sergio b14e766b5e estado: cosecha granja 2026-09-09T00:01:58Z — avance del árbol KDE 2026-09-09 00:01:58 +00:00
Sergio 8491c28155 estado: cosecha granja 2026-09-08T23:31:54Z — avance del árbol KDE 2026-09-08 23:31:54 +00:00
Sergio 9b1445ceac estado: cosecha granja 2026-09-08T23:01:50Z — avance del árbol KDE 2026-09-08 23:01:50 +00:00
Sergio 7d5e57841f estado: cosecha granja 2026-09-08T22:31:52Z — avance del árbol KDE 2026-09-08 22:31:52 +00:00
SergioandClaude Opus 5 3d8c6fc6c7 KDE: cerrar los 3 huecos que quedaban — polkit-qt-1, qqc2-breeze-style y xwayland
La frontera queda en CERO huecos y cero pendientes, y el perfil escritorio-kde en 302/302
sellados. Los tres eran huecos de RUNTIME: KDE sellaba 1037/1037 con la autorización muerta,
los controles QML en estilo genérico y ninguna app X11 capaz de arrancar.

polkit-qt-1 0.201.1 — al conectarlo se vio lo que ninguna métrica decía: kauth NO traía plugin
de backend, ni siquiera el directorio. Ahora trae kf6/kauth/backend/kauth_backend_plugin.so con
el símbolo KAuth::Polkit1Backend. Cascada de 26 dependientes reconstruida, 26/26 sin fallos.
Añadirlo cambió la rama del CMake y pidió kwindowsystem y tras él las X11 — cada cosa dicha por
el configure al fallar, no supuesta.

qqc2-breeze-style 6.7.2 (la del stack Plasma, NO la 6.7.4 de nixpkgs: mezclar versiones de un
mismo release es pedir desajuste de ABI en los plugins QML, que se ve en runtime y no al
construir). Enganchado a plasma-workspace como deps.runtime, no build: es un plugin que Qt carga
por la ruta de imports. Verificado que runtime no re-hashea ⇒ cero rebuilds.

xwayland 24.1.13 — resultó ser una CADENA de seis: libfontenc, libXfont2, libxkbfile,
libxshmfence, xkbcomp y el servidor. Ninguna existía. Tres tropiezos con su lección:

  · libxkbfile 1.2.0 ya no trae ./configure: es sólo meson. El resto de las libs X11 de la cola
    son autotools, así que copiar su plantilla era lo natural y estaba mal.
  · «checking for freetype2... no» culpaba a freetype, que estaba perfecta: freetype2.pc declara
    Requires: zlib, libpng y pkg-config resuelve transitivamente. El mensaje señala al paquete
    equivocado.
  · libXfont2 construye una .so y moría en «recompile with -fPIC» contra la libfreetype.a
    estática. Van las variantes -shared.

  Y xkbcomp es el eslabón que NINGÚN build habría delatado: xwayland lo lanza como subproceso en
  runtime (xkb/ddxLoad.c) y su meson lo pide con required:false, así que la receta compila igual
  y el servidor arranca sin teclado. Se encontró leyendo la fuente.

⚠ Sin GLX, y no por preferencia: glx/meson.build:43 pide dependency('gl') y ninguna cola publica
gl.pc — las tres recetas de mesa van con glx y glvnd apagados por decisión anterior. Las apps
X11 corren en 2D. ⚠ Y el meson.build RAÍZ engaña: ahí build_glx sólo enciende una tabla hash y
parece gratis; yo mismo di la preocupación por infundada mirando el fichero equivocado.

Verificado: Xwayland arranca y se identifica («The X.Org Foundation Xwayland Version 24.1.13»),
las 6 REPRODUCEN bit a bit, los 5 grafos con deuda 0, y los 6 tarballs en el mirror.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 22:26:17 +00:00
Sergio a939ff0a3a estado: cosecha granja 2026-09-08T22:03:10Z — avance del árbol KDE 2026-09-08 22:03:10 +00:00
Sergio c4779c8545 estado: cosecha granja 2026-09-08T21:33:15Z — avance del árbol KDE 2026-09-08 21:33:15 +00:00
Sergio 13ee11826f estado: cosecha granja 2026-09-08T21:03:09Z — avance del árbol KDE 2026-09-08 21:03:09 +00:00
Sergio 3ab947102c estado: cosecha granja 2026-09-08T20:32:24Z — avance del árbol KDE 2026-09-08 20:32:24 +00:00
SergioandClaude Opus 5 71bdb5ec5b shared-mime-info: cerrar el primer hueco de la frontera
Salió de 'yupana frontera' en cuanto nix volvió a correr: kcoreaddons la pide y no había receta.
Es un hueco de RUNTIME, no de build — KDE sella 1037/1037 sin ella, y por eso NINGUNA métrica de
deuda la veía. Sin la base MIME el escritorio no resuelve asociaciones, iconos por tipo ni
'abrir con', y GIO cae a adivinar por extensión.

Va al CORPUS, no a incoming-kde: la necesitan las cuatro imágenes de escritorio, y una receta
resuelve sibling-first y después el catálogo padre, nunca una cola hermana.

Dos cosas que se comprobaron ANTES de construir, no después de que fallaran:

  · El tarball de GitLab no trae el submódulo 'xdgmime' — .gitmodules lo declara y el directorio
    llega vacío. Leyendo meson.build:26-47 se ve que sólo lo usa la suite de tests y con
    required:false, así que con build-tests=false lo único que pasa es un warning.
  · 'i18n.merge_file' corre SIEMPRE, no lo gobierna build-translations: no traduce UI, arma el
    fichero de datos desde el .in. De ahí el msgfmt, que gettext-tiny sí provee.

'--prefer-static' desde el principio, que es la lección de json-glib de hace un rato: el binario
sale ESTÁTICO con 0 NEEDED y corre en el host.

Y el artefacto trae la mime.cache ya compilada (update-mimedb=true, que upstream trae en false):
sin ella el paquete son datos crudos y alguien tendría que acordarse de correr
update-mime-database al armar cada imagen.

Verificado:
  prueba del consumidor  update-mime-database genera 157.560 bytes de cache y 26 media-types
  binario                estático, 0 NEEDED, corre fuera del sandbox
  repro                  REPRODUCE bit a bit (la caché se genera en el build: era candidata)
  mirror                 el tarball subido al Storage Box (ADR 0013)
  frontera               huecos 4 → 3

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 20:15:06 +00:00
Sergio 50c1a55a2a estado: cosecha granja 2026-09-08T20:04:11Z — avance del árbol KDE 2026-09-08 20:04:11 +00:00
SergioandClaude Opus 5 bdb5f7df9a nix instalado en gioser: la cadena frontera→triaje vuelve a correr
'yupana frontera' llevaba desde el 2026-08-10 sin poder correr acá porque el hub no tenía nix.
Instalado desde el repo de Artix (extra/nix 2.35.2). Dos cosas que costaron medirse:

  · El paquete quedó ROTO al instalarse: le faltaban libboost_{context,iostreams,url}.so.1.92.0
    porque el sistema tiene boost 1.91 y 280 paquetes sin actualizar. NO se hizo 'pacman -Syu':
    280 paquetes en un server protegido, sin backup, que hospeda la granja, gitea y el runner de
    CI no es una decisión que tome un arreglo de tooling. El ensayo en seco mostró que la
    reparación acotada eran TRES paquetes exactos (boost-libs, source-highlight, gdb) sin
    cascada, y eso sí se hizo. Control después: gdb 17.2 sigue arrancando.

  · El store por defecto iba a ~/.nixstore, o sea a '/', que tiene 21 G libres frente a los 126
    del volumen. Llenar '/' no rompe una tanda, rompe la máquina. NIX_ROOT pasa a apuntar a
    work/nixstore, que además ya es el sitio de lo pesado-y-regenerable. La caché git de nixpkgs
    (~69 M) NO la gobierna esa variable —nix la pone en XDG_CACHE_HOME— así que en gioser está
    mudada al volumen con un enlace: ~/.cache/nix -> /mnt/vvv/nix-cache.

Con eso, la frontera vuelve a dar respuesta, y es pequeña como corresponde a un corpus cerrado:
172 candidatos → 150 opcionales, 11 provistos, 5 nix-ismos, 4 HUECOS reales (polkit-qt-1,
qqc2-breeze-style, shared-mime-info, xwayland) y 2 pendientes de clasificar (mesa-libclc,
python3-3.14.7-env).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 20:01:49 +00:00
SergioandClaude Opus 5 a19fc8bcf0 seed-graph: decir que falta nix, en vez de reventar con un traceback
'yupana frontera <perfil>' —el verbo que responde qué pide upstream y no tenemos— moría con
veinte líneas de traceback terminadas en FileNotFoundError: 'nix'. Eso tiene la cara de un bug
de código y manda a depurar el script, cuando lo único que falta es una herramienta que en esta
máquina nunca se instaló: el hub gioser no trae nix, y los docs/state/seed-*.json del repo se
generaron en otra máquina el 2026-08-10. El coste no es el susto, es el desvío.

Ahora es una precondición explícita que dice qué falta y qué hacer, y sale 2.

⚠ Dos errores míos que los controles cazaron en el acto, y por eso van escritos:
  · Eximí a --calibrar de la comprobación 'porque no usa nix'. Lo usa: el control lo mostró
    imprimiendo 'nix eval lote 1 (3 nombres)…' y muriendo igual. La exención era una suposición
    con forma de hecho.
  · Con la precondición delante del uso, 'seed-graph.py' a secas pasó a quejarse de nix en vez
    de explicarse. Un fallo de entorno va DESPUÉS del uso.

Verificado en los tres caminos: sin args → uso; --frontera → mensaje de entorno; --calibrar →
mensaje de entorno.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:54:19 +00:00
SergioandClaude Opus 5 ca2c164512 sombras: CERO — promover las 6 compartidas al corpus y barrer sus 16 copias
Las 6 que quedaban (fuse3, hwdata, icu4c, libdisplay-info, libelogind, lua) no tenían copia en
el corpus, así que borrar una habría roto su cola: la resolución es sibling-first y después el
catálogo PADRE, nunca una cola hermana. Se promueve una y se barren las 16.

Las 16 eran byte a byte IDÉNTICAS entre sí, con el mismo ArtifactHash — medido con 'hammer hash',
no deducido del nombre. Cada una la comparten entre 2 y 4 imágenes, que es exactamente el
criterio que dejó escrito xkeyboard-config al promoverse: lo que comparten varias imágenes tiene
que vivir en el corpus o no lo alcanzan.

A diferencia de aquella, acá las copias SÍ se barren en el mismo movimiento: sin copia en el
corpus no había dónde caer, y dejarlas sería mantener hasta 4 ficheros que son el mismo hash.

Verificado con la huella de las 1167 recetas antes y después:
  ficheros de receta   1167 → 1157   (16 borradas, 6 promovidas)
  hashes supervivientes  ninguno se movió ⇒ CERO rebuilds
  los cinco grafos       deuda 0, huérfanas [], sellados == recetas
  static-audit           MIENTEN 0 de 690
  duplicados             SOMBRAS REDUNDANTES: 0   ← de 14

⚠ Y una lectura que casi publico mal: mi primera comparación de hashes dijo 'CAMBIÓ ✗' en las
seis. Era el grep de la comparación, que no casaba y dejaba el valor 'antes' vacío — los hashes
nuevos eran idénticos a los medidos minutos antes. Un instrumento roto que grita es tan malo
como uno mudo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:47:55 +00:00
SergioandClaude Opus 5 a4a462b751 sombras: barrer 14 recetas redundantes que ya tenían copia en el corpus
Las 14 sombras marcadas 'redundante' dan el MISMO ArtifactHash en todas sus colas — no son
variantes, son el mismo artefacto declarado dos, tres, cuatro y hasta cinco veces. Medido con
'hammer hash' receta por receta, no deducido del nombre.

Se barren sólo las que YA tenían copia en el corpus, porque la resolución es sibling-first: una
dep desde incoming-kde busca incoming-kde/x y, si no está, CAE al corpus/x. Son 8 nombres, 14
ficheros: bzip2-shared, glib-shared, lcms2, mpc, pcre2-shared, sqlite-shared, xkeyboard-config
y xz-shared.

13 de los 14 eran byte a byte idénticos al del corpus. El decimocuarto, xkeyboard-config,
difiere en 14 líneas de COMENTARIO (mismo hash), y ese comentario es el permiso explícito para
esto: quien la promovió el 2026-09-05 escribió que dejaba las copias a propósito y que
'barrerlas es otra unidad de trabajo, no un efecto colateral de ésta'. Ésta es esa unidad.

Verificado con la huella de las 1181 recetas antes y después: NINGÚN hash superviviente se
movió ⇒ cero rebuilds. Y tras regenerar los cinco grafos: deuda 0, huérfanas [], y todas las
clausuras de perfil siguen completas.

⚠ Nota sobre una lectura que casi me confunde: los conteos de 'recipes' NO bajan (kde sigue en
1034) y eso es lo correcto — cuentan nodos alcanzables, no ficheros. Antes incoming-kde/x tapaba
a corpus/x; ahora el del corpus ocupa su lugar. Un nodo por otro.

Quedan 6 nombres (fuse3, hwdata, icu4c, libdisplay-info, libelogind, lua) sin copia en el
corpus: ésos exigen promover una primero, y van aparte.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:44:28 +00:00
SergioandClaude Opus 5 29b0d99e9d latido: regenerar keystones y duplicados — llevaban TRES DÍAS congelados
Cuarta vez que cae el mismo cable. Los comentarios del propio fichero ya lo cuentan para GNOME
(2026-07-27), COSMIC (2026-08-03) y wlr/sway (2026-08-26): un frente que el latido no regenera
envejece en silencio, y un grafo viejo miente con la misma cara que uno fresco.

keystones.json y duplicados.json estaban parados en 2026-09-05. Con un agravante que los otros
tres no tenían: keystones es el fichero que responde '¿qué construyo después?', así que rancio
no se limita a envejecer — DESINFORMA. Medido: decía '1 nudo en deuda, camino crítico
corpus/firefox → corpus/atuq' con los dos sellados hacía horas. Regenerado dice 0 nudos en
deuda, que es la verdad.

Van también al 'git add' Y al commit acotado por pathspec: regenerar sin publicar deja el
fichero fresco en el hub y viejo para todos los demás.

Probado con un ciclo real: 'keystones.json ✓  duplicados.json ✓  estado commiteado+pusheado'.

⚠ De paso, dos cosas que este rato dejó claras sobre mis propias comprobaciones: 'pgrep' y
'grep [c]osecha-cron' se autodetectan cuando MI comando menciona el fichero, así que la guarda
'¿está corriendo?' dio dos falsos positivos. La comprobación fiable mira /proc/*/cmdline y pide
que argv[0] sea un shell y argv[1] el script.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:31:52 +00:00
Sergio 29cf7cc69c estado: cosecha granja 2026-09-08T19:31:11Z — avance del árbol KDE 2026-09-08 19:31:11 +00:00
SergioandClaude Opus 5 7892d50842 json-glib: --prefer-static — declaraba static y sus binarios no corrían fuera del sandbox
'-Ddefault_library=static' gobierna cómo se construye la librería PROPIA, y eso funcionaba: el
artefacto trae libjson-glib-1.0.a. Pero no dice nada de con qué se enlazan los EJECUTABLES, así
que json-glib-format y json-glib-validate salían dinámicos contra libffi.so.8, libz.so.1 y
libc.so — y ese libc.so es la musl de zig, 255 bytes de linker script en el host. O sea binarios
que NO CORREN fuera del sandbox, en una receta que declara link=static. Mismo remedio que
appstream, que ya llevaba --prefer-static.

Medido antes y después:
  json-glib-format    dinámico, 3 NEEDED  →  ESTÁTICO, 0 NEEDED
  json-glib-validate  dinámico, 3 NEEDED  →  ESTÁTICO, 0 NEEDED
  libjson-glib-1.0.a  igual (los consumidores no cambian de forma)

Y la prueba del consumidor, que es la que vale: json-glib-format sobre un JSON real corre EN EL
HOST y devuelve {"a":1}. (El ruido de libgvfsdbus.so en stderr es glib intentando dlopen
módulos GIO desde un binario estático: inocuo, la salida sale bien.)

Cascada reconstruida en orden de onda, con el cierre transitivo sacado de yupana y no de un grep
—que no veía a zathura ni a zathura-pdf-poppler por tener el array de deps multilínea, y la regla
del repo es justamente ésa—: zathura, incoming-cosmic/xdg-desktop-portal, zathura-pdf-poppler.

Verificado después, no antes:
  static-audit   MIENTEN 0 de 690    toda receta que declara link=static lo cumple
  los 5 grafos   deuda 0
  repro          REPRODUCEN 3 · DERIVA 0 · NO-DETERMINISMO 0

⚠ incoming-gnome/json-glib NO se toca: declara link="dynamic" a propósito porque el shell de
GNOME dlopea .so reales para introspección. No miente — es honesta, y su radio de 10 no se paga.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:26:12 +00:00
SergioandClaude Opus 5 381780aab4 fuentes: tapar el agujero de libtool y que el vigía distinga noticia de emergencia
El vigía decía 5 fuentes muertas y sólo UNA estaba en riesgo de verdad: busybox y freetype
tenían el tarball en la caché local Y en el mirror, y firefox-pgo-profile apunta a .invalid a
propósito. La que no tenía copia en ningún lado era libtool (incoming-kde), con ftpmirror.gnu.org
devolviendo 502 — o sea una receta que ya no se podía reconstruir y nadie lo sabía.

Arreglado: el tarball se bajó de ftp.gnu.org, se verificó contra el sha256 PINEADO (coincide
byte a byte), y está en la caché local y en el mirror. La URL de la receta pasa al espejo que
responde, y se midió que eso no re-hashea nada — ANTES y DESPUÉS dan el mismo
b3:5c09bff5..., que es el ADR 0013 comprobado en vez de citado.

Y el vigía ahora cruza cada fuente muerta con la caché local y el mirror, porque mezclar
'upstream caído con el blob guardado' (noticia) con 'caído y sin copia' (emergencia) hace que
el número suba, nadie lo mire, y el día que uno importe esté enterrado entre cuatro que no. A
un guardián lo mata el ruido. Ahora informa EN RIESGO aparte:

  == vivas 1175 / 1179   muertas arriba 4   EN RIESGO 0

⚠ Y si el mirror no se puede consultar —el worker no tiene la clave del Storage Box— dice
'indeterminado', NUNCA 'EN RIESGO': un instrumento que no pudo correr no puede parecer un
hallazgo.

Probado con rotura a propósito y con los dos controles, que es lo que separa un guardián que
sirve de uno que nunca saltó:
  sha inexistente + upstream muerto → EN RIESGO        ✓ salta
  blob en caché + upstream muerto   → cache-local      ✓ no salta
  mirror inalcanzable               → indeterminado    ✓ no alarma en falso

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 19:14:21 +00:00
Sergio 45a6ce547d estado: cosecha granja 2026-09-08T19:01:35Z — avance del árbol KDE 2026-09-08 19:01:35 +00:00
SergioandClaude Opus 5 f1d69f4f99 granja: la siembra de la flota fallaba justo en el caso que existe para arreglar
Con '.fleet' ausente —el hub recién clonado, o sea el único caso que importa— el 'cat' de un
fichero inexistente devuelve 1, y como el script corre con 'set -o pipefail' la tubería hereda
ese estado y el '&& mv' no dispara: el fichero se generaba correctamente y se quedaba sin
mover. Se añaden los '|| true' que faltaban.

⚠ Y por qué mi prueba no lo vio, que es lo que vale anotar: extraje el bloque real del script
para probarlo, pero le puse 'set -u' en vez del 'set -uo pipefail' que el script trae. Copié
el código y no el ENTORNO en que corre, y sin pipefail el caso pasaba. El extractor ahora lee
la línea 'set -' del propio script en vez de que yo la escriba de memoria.

Verificado con un ciclo REAL tras borrar .fleet a mano:
  ── cosecha-cron arranca
  ==> dev.gioser.net (154.197.1.13)
     siembra ✓
     manifiesto ✓ (worker: 764 · total: 4743)
  .fleet quedó: dev.gioser.net 154.197.1.13

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 18:52:51 +00:00
Sergio 0eb353b572 estado: cosecha granja 2026-09-08T18:52:12Z — avance del árbol KDE 2026-09-08 18:52:12 +00:00
Sergio cb06a37ffa estado: cosecha granja 2026-09-08T18:48:37Z — avance del árbol KDE 2026-09-08 18:48:37 +00:00
SergioandClaude Opus 5 4db7d1e7ce granja: versionar la flota permanente, y acotar el commit del cron
'.fleet' está gitignored con razón —los workers efímeros entran y salen, y el reaper lo
reescribe en cada ciclo— pero eso tenía un coste que nadie había pagado: un hub recién
clonado nacía con la flota VACÍA y la granja quedaba desconectada EN SILENCIO. La cosecha
decía 'flota vacía' cada 30 min, los artefactos del worker no volvían, estado-granja.sh
reportaba 'no hay worker vivo' con el worker compilando, y nada fallaba. Así se descubrió
esto hoy, por casualidad.

Se separa lo que debe sobrevivir a un clon (scripts/farm/flota-permanente, versionado) de lo
que es estado de ejecución (.fleet). cosecha-cron siembra .fleet desde el fichero fijo al
empezar cada ciclo, uniendo por nombre. Probado con la siembra extraída del script real:

  hub recién clonado (.fleet ausente)  → queda dev.gioser.net          ← el caso que rompía
  con un hworker-3 efímero ya dentro   → conviven los dos, sin duplicar
  ejecutada dos veces más              → idempotente, sigue 1 línea por worker
  comentarios del fichero versionado   → 0 se cuelan

Y de paso el commit del propio cron pasa a ir acotado por pathspec. Hacía 'git add <rutas>' +
'git commit' a secas, que es justo lo que la regla 2 de CLAUDE.md declara insuficiente: el
índice es compartido y el commit se lleva el índice entero. Pesa más acá que en ningún sitio
porque corre desatendido cada 30 min mientras hay agentes trabajando.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 18:45:54 +00:00
SergioandClaude Opus 5 d45c0688e7 granja: el worker es el LXC PRESTADO (€0) — que no se vuelva a perder
El dato ya estaba en memoria y aun así se perdió dos veces, así que ahora vive en los sitios
que se leen sin buscarlos: regla 1 bis de CLAUDE.md (que carga todo agente en cada sesión) y
la skill 'granja' del repo. Se compila en dev.gioser.net PARA NO GASTAR HETZNER; no se
levantan cajas hcloud salvo petición explícita.

Y se arregla la fragilidad que salió al mirar: el reaper de cosecha-cron expulsa de .fleet
todo lo que no esté en hcloud, y el LXC se salvaba SÓLO porque su nombre contiene la subcadena
'gioser' y caía en una lista negra que existe para proteger al hub de Hetzner — no tiene nada
que ver con él. Medido con el bloque real del reaper contra un .fleet de juguete:

  nombre CON 'gioser'                    → 'en LISTA NEGRA ⇒ intocable'      sobrevive
  el MISMO host como 'pruebasia-lxc'     → 'ya no existe en hcloud'          .fleet VACÍO

O sea que la granja se mantenía conectada por una casualidad de nombre, y con otro nombre
volvía a 'flota vacía' en el primer ciclo sin que nada fallara. Ahora el reaper pregunta por
SSH si el host responde, que es preguntarle a la máquina en vez de al nombre. Verificado en
las dos direcciones, con control:

  host vivo, nombre sin 'gioser'  → 'no es de hcloud pero RESPONDE ⇒ se queda (€0)'
  host que no responde            → 'no responde ⇒ lo saco de .fleet'   (intención original)

Queda anotado también que .fleet está gitignored: un hub recién clonado nace con la flota
vacía y la granja queda desconectada en silencio — la cosecha dice 'flota vacía', los
artefactos no vuelven, y estado-granja.sh reporta 'no hay worker vivo' con el worker
compilando. Es como se descubrió esto hoy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014QPJteswQvP1L7zSBrQQe2
2026-09-08 18:41:16 +00:00
Sergio c1d80ff8af estado: cosecha granja 2026-09-08T18:32:27Z — avance del árbol KDE 2026-09-08 18:32:27 +00:00