Commit Graph
1939 Commits
Author SHA1 Message Date
Sergio 61143203f9 firefox: wrappers de ar/nm/ranlib — zig los trae como subcomandos
Segundo fallo de configure: «ERROR: Cannot find ar». moz.configure hace
check_prog("AR", …) y en el sandbox no existe un ejecutable llamado `ar`: existe
`zig ar`. Un AR="zig ar" con espacio tampoco sirve, se ejecutaría como un binario
único llamado «zig ar» — el mismo gotcha que ya documentan la receta de ffmpeg y
el de los crates cc en las recetas Rust.

Wrapper de UN SOLO TOKEN por herramienta (ar, ranlib, nm, objcopy), que es el
patrón ya establecido en el corpus, exportados en configure Y en compile porque
las dos fases los necesitan.

El linker ya pasó: este fallo es posterior, lo que confirma que quitar
--enable-linker fue correcto.
2026-09-04 21:55:45 +00:00
Sergio 2fd738bf82 firefox: quitar --enable-linker=lld — el sondeo de Mozilla no reconoce a zig
Primer intento de build: configure murió con «Could not use lld as linker».
NO era que faltara lld. toolchain.configure sondea con
`$CC -fuse-ld=lld -Wl,--version` y clasifica por la SALIDA, buscando «mold»,
«GNU ld», «GNU gold» o «LLD». zig se identifica como `zig ld 0.16.0`, que no casa
con ninguno ⇒ kind = "unknown".

«unknown» por sí solo NO rompe: el código lo acepta explícitamente. Lo que rompe
es PEDIR el linker por nombre, porque eso vuelve fatal cualquier fallo del sondeo:
  if linker: result = try_linker(linker)
             if result is None: die("Could not use %s as linker")
Sin el flag, unas líneas más abajo Firefox prueba lld igual —c_compiler.type es
clang y la versión 21.1.0 pasa el umbral de 15.0— y si el sondeo falla sigue a
gold y al linker por defecto, que es exactamente el lld que zig trae adentro.
Mismo linker, sin el die.

Diagnóstico hecho leyendo toolchain.configure en el árbol del worker, no
suponiendo: el comando sondeado devuelve rc=0 y sí imprime la versión cuando se
corre a mano.
2026-09-04 21:53:59 +00:00
Sergio 5776f63aed estado: cosecha granja 2026-09-04T21:31:52Z — avance del árbol KDE 2026-09-04 21:31:52 +00:00
Sergio 90364fabbf nodejs y firefox: strip_debug — medido, no supuesto
El nodejs que selló en el LXC sin strip pesa 984 MB, de los cuales .debug_info son
497 MB y .debug_line otros 43: MÁS DE LA MITAD del artefacto es información de
depuración, para una herramienta que nadie va a depurar y que ni siquiera se
publica.

Se aplica también a firefox ANTES de construirlo, que es donde importa: Firefox es
varias veces V8 y sin strip su artefacto entraría en varios GB. El store no es
sólo disco — se sincroniza hub↔worker y se respalda.

Es el hallazgo del SDD 23: el 79% del contenido binario del store era .debug_*, y
quitarlo hace que artefactos que no reproducían PASEN a reproducir, porque lo que
difería eran las rutas del árbol de build embebidas en esas secciones.

El campo entra en hash_inputs a propósito (cambia el contenido) y usa zig objcopy,
que siempre está en el sandbox ⇒ no agrega dep de build. Node se reconstruye.
2026-09-04 21:24:47 +00:00
Sergio 428be5e8d1 firefox 154.0 — la cabeza de la familia Gecko (receta, sin construir todavía)
154 y no 155 pese a que Zen sigue 155.0.1 y Waterfox también va por release: los
parches de musl de Alpine son para 154.0, y son ONCE. Ese es el trabajo de
portabilidad que un import de nix pierde y sin el cual Firefox no compila contra
musl. Un Firefox que compila con el set probado vale más que uno con el número
correcto que no compila; y como Firefox se mueve cada 4 semanas, la paridad exacta
con Zen es una cinta de correr. Lo que se reutiliza entre los tres es la
PLATAFORMA (gtk3/nodejs/clang18/cbindgen, ya en el corpus) y este set de parches.
Subir a 155 después es un rebase, no un port.

Se traen los 11 de musl y NO los de ppc64le, loongarch ni Android: cada parche que
no hace falta es una forma más de que un rebase falle sin motivo.

TODO BUNDLEADO salvo GTK3. Alpine usa --with-system-{icu,nspr,nss,av1,libvpx,
webp,libevent} y de ésas el corpus tiene cero; Firefox las trae en el árbol.
Menos piezas móviles para el primer build, que es cuando conviene minimizar
variables.

SIN BRANDING OFICIAL, y no es descuido: el binario lleva once parches, y poner el
nombre y el logo de Firefox sobre un build modificado entra en la política de
marcas de Mozilla — es la historia de Iceweasel en Debian. Misma cautela que
dejavu-fonts-nerd con la licencia de Bitstream Vera: una fuente modificada no
puede llamarse como la original, y un navegador parcheado tampoco.

HERMÉTICO: --disable-bootstrap (su trabajo es descargar toolchains),
MACH_BUILD_PYTHON_NATIVE_PACKAGE_SOURCE=system (si no, mach arma un virtualenv con
pip y sale a la red) y MOZBUILD_STATE_PATH al árbol (por defecto escribe en $HOME,
que en el sandbox no es suyo). Los crates vienen vendorizados en el tarball.

Wayland-only heredado de gtk3 (-Dx11_backend=false) ⇒ este Firefox NO correrá como
cliente X11 ni bajo Xwayland. Escrito en las dos recetas.
2026-09-04 21:02:51 +00:00
Sergio 9c657efe61 plataforma Gecko: nodejs 24.18.1 — ./mach configure lo exige
Firefox aborta con «Could not find a Node.js executable»: lo usa para empaquetar
los bundles de JS. Waterfox y Zen lo necesitan igual ⇒ al corpus con el resto de
la plataforma.

TODO BUNDLEADO, a diferencia de Alpine, que lo construye contra diez deps del
sistema de las cuales el corpus tiene dos. La decisión de fondo: acá Node es un
COMPILADOR, no software que la distro publique — entra al sandbox de Firefox y
desaparece, así que el cierre chico gana al cierre puro y el precio (binario
gordo, openssl bundleado que nadie expone) no lo paga ningún usuario. Si algún
día se quiere PUBLICAR Node, esa es otra receta; queda avisado en la cabecera.

Dos AVX-512 apagados, y los dos por la perilla que upstream mismo deja:
 · simdjson  → SIMDJSON_AVX512_ALLOWED=0. ⚠ EN EL .h Y EN EL .cpp: la librería se
   distribuye AMALGAMADA y el .cpp lleva su propia copia (línea 2493), así que
   tocar sólo el header no sirve — y engaña, porque ninja sigue con otros objetos
   y el log parece avanzar.
 · simdutf (dentro de V8) → se antepone SIMDUTF_IMPLEMENTATION_ICELAKE 0, que es
   el override que habilita su #ifndef.
No se pierde nada: todo el corpus va -mcpu=baseline y ambas eligen implementación
en RUNTIME. CXXFLAGS NO sirve acá — GYP no lo propaga a la línea de compilación
(verificado buscando el -D en el comando que ninja reportó al fallar).

EL PARALELISMO SE CAPA POR RAM Y SIN ESCRIBIR UN NÚMERO. Sin cap, ninja lanza
nproc+2 y muere con `job terminated due to signal 9` en el objeto 2936/4414
compilando lo que genera Torque (~2 G por job). Un `-j2` fijo ataría el
ArtifactHash a la RAM de quien escribió la receta; la cuenta es un job cada 3 GiB
de MemTotal, mínimo 1, tope nproc. Da 2 en momento (7,6 GiB) y 5 en el LXC
(16 GiB, 6 cores) con el MISMO texto y el mismo hash.
2026-09-04 20:55:57 +00:00
Sergio e1f081b06b estado: cosecha granja 2026-09-04T20:32:59Z — avance del árbol KDE 2026-09-04 20:32:59 +00:00
Sergio e7e008e126 estado: cosecha granja 2026-09-04T20:03:06Z — avance del árbol KDE 2026-09-04 20:03:06 +00:00
Sergio 4ec49e9962 estado: cosecha granja 2026-09-04T19:33:12Z — avance del árbol KDE 2026-09-04 19:33:12 +00:00
Sergio 9f908090d5 estado: cosecha granja 2026-09-04T19:03:00Z — avance del árbol KDE 2026-09-04 19:03:00 +00:00
Sergio 8c15c2eaf4 estado: cosecha granja 2026-09-04T18:32:49Z — avance del árbol KDE 2026-09-04 18:32:49 +00:00
Sergio 188a45b1d5 estado: cosecha granja 2026-09-04T18:05:16Z — avance del árbol KDE 2026-09-04 18:05:16 +00:00
Sergio dc8aa7367e plataforma Gecko: cbindgen sube al corpus
Genera las cabeceras C++ de los componentes Rust de Gecko (Stylo, WebRender) y el
build de Firefox la exige. Mudanza gratis: [deps] vacío ⇒ no hay cierre que
cambiar, mismo ArtifactHash (b3:bd2e6ca6) en las dos rutas, radio 0.
2026-09-04 17:54:17 +00:00
Sergio 027d3a25ef plataforma Gecko: clang18 sube al corpus — bindgen necesita libclang
El build de Firefox corre bindgen sobre los headers de C++ y bindgen carga
libclang.so en RUNTIME. La receta ya existía —nació en incoming-cosmic por un
crate *-sys del portal, y su commit de origen dice «sólo libclang.so»— pero desde
el corpus no se alcanza una cola hermana. Sin esto no hay Firefox, ni Waterfox,
ni Zen.

Mudanza medida ANTES, no después: sus cinco deps (cmake, samurai, python3,
pkgconf, llvm18) viven sólo en el corpus, así que incoming-cosmic ya las resolvía
por caída al padre y el cierre no cambia. hammer hash dio el MISMO ArtifactHash
(b3:25d95279) en las dos rutas.
Verificado que xdg-desktop-portal-cosmic —su único dependiente— sigue SELLADO y
que la cola cosmic queda en 36/36 sin deuda: cero rebuilds.

Se MUEVE y no se copia: dos ficheros para un artefacto es el cuadro de las dos
glib esperando a que uno de los dos derive.
2026-09-04 17:53:03 +00:00
Sergio 7c58f6b62e plataforma Gecko: atk + GTK3 Wayland-only — la base que comparten Firefox, Waterfox y Zen
GTK3 no existía en NINGUNA cola y es el único toolkit de Gecko en Linux. Como
Waterfox y Zen son forks de Gecko, los tres navegadores consumen exactamente esta
misma pieza: una receta sostiene a los tres. Por eso va al CORPUS y no a una cola
—una receta resuelve sibling-first y después el catálogo padre, nunca una cola
hermana—, que es la lección de mpv y justo lo que OBS no pudo cumplir al quedar
atado a incoming-kde por Qt6. La plataforma nace bien puesta para que los tres
navegadores no repitan ese error.

Al medir el cierre antes de escribir, TODO estaba ya en el corpus salvo `atk`. Un
ladrillo chico destrabando una pieza grande: por eso atk fue primero.

WAYLAND-ONLY de verdad, no de intención: -Dx11_backend=false. A diferencia de OBS
—que exigía find_package(X11) incondicional— GTK3 sí deja apagarlo, y eso saca
libX11/libXext/libXi/libXrandr/… del cierre. Esa cadena vive sólo en incoming-kde
y meterla en el corpus la pondría en las CINCO imágenes.
Verificado en el artefacto: los .pc son gdk-wayland-3.0 y gtk+-wayland-3.0 (no hay
gdk-x11-3.0), libgtk-3.so.0 no enlaza X11 ni xcb, y libgdk-3.so trae NEEDED
libwayland-client/cursor/egl + libxkbcommon.

⚠ Consecuencia escrita en la receta: un Firefox contra este GTK3 no correrá como
cliente X11 ni bajo Xwayland. Bajo Wayland nativo sí. Es la postura de la distro
aplicada al navegador, no un accidente.

Las deps van a las variantes -shared EN LUGAR DE las estáticas, nunca junto a
ellas: libgtk-3.so es un objeto compartido y un .a sin PIC adentro da
`relocation R_X86_64_32 against png_default_write_data`. Se sustituye y no se suma
porque ambas variantes instalan los MISMOS .pc y cabeceras — declarar las dos
serían dos artefactos peleando por lib/pkgconfig/glib-2.0.pc.
2026-09-04 17:51:08 +00:00
Sergio e684c26e52 targets: obs-studio entra al perfil escritorio-kde (274/274)
Una receta sellada que ningún perfil declara NO ESTÁ EN NINGUNA IMAGEN, y la
métrica de clausura no lo puede ver porque mide lo declarado — la lección que este
fichero ya aprendió con foot en sway y con las 22 apps KDE. OBS estaba sellado y
en ninguna imagen.

Entra SÓLO en escritorio-kde, y no por preferencia: su frontend es Qt6 y las 13
recetas Qt viven sólo en esa cola. Verificado con `yupana perfiles obs-studio`.
El perfil pasa de 263/263 a 274/274 — arrastra 11 nodos a la clausura, todos ya
sellados, y el grafo sigue cerrando.

De paso: el aviso de los «tres huecos de mpv» estaba repetido en los CUATRO
perfiles de escritorio y hoy quedó vencido en los cuatro (ALSA/PipeWire, Lua/OSC
y vaapi están cerrados). Corregidos los cuatro; el assert de count==1 fue lo que
destapó que no era uno solo.
2026-09-04 17:42:47 +00:00
Sergio 461f677368 estado: cosecha granja 2026-09-04T17:32:11Z — avance del árbol KDE 2026-09-04 17:32:11 +00:00
Sergio 554c59b1b5 estado: corpus 831/831 y KDE 1010/1010 tras OBS y sus 7 deps nuevas
Entran libglvnd, uthash, nlohmann-json, jansson, x264, simde, pciutils-shared y
mbedtls al corpus, y obs-studio a incoming-kde. Cero en deuda en los 7 perfiles.
2026-09-04 17:18:18 +00:00
Sergio 670a5b6b49 OBS Studio 32.2.2 — segunda app gráfica de usuario final, con el renderer portado a EGL
13 plugins sellados, entre ellos los que importan: linux-pipewire (captura de
pantalla en Wayland), obs-ffmpeg, obs-x264, obs-outputs (RTMP RTMP),
linux-pulseaudio/alsa y text-freetype2.

EL PORT. El glad de OBS hacía dlopen("libGL.so.1") + dlsym("glXGetProcAddressARB")
y devolvía 0 si no lo hallaba, o sea que el renderer no arrancaba: OBS estaba
atado a GLX —y por tanto a X11— aun corriendo en Wayland puro. Acá nadie publica
libGL.so.1 y el libglvnd del corpus va sin GLX a propósito. El parche carga por
libEGL.so.1 + eglGetProcAddress, que es lo que OBS ya usa para las extensiones.
Verificado en el artefacto, no en el log: libobs-opengl.so.30 tiene CERO
ocurrencias de glXGetProcAddressARB, sus NEEDED son libEGL.so.1 +
libwayland-egl.so.1, y el binario no filtra a glibc.

DÓNDE VIVE. En incoming-kde y no en el corpus porque su frontend es Qt6 y las 13
recetas Qt viven sólo en esa cola. Se midió antes de descartar el corpus: qtbase
sin X11 cierra en 26 nodos que YA están en el corpus, pero el qtbase de la cola va
xcb=ON, así que un qtbase de corpus tendría otro hash con el MISMO nombre de
artefacto ⇒ dos Qt peleando por /usr/lib/libQt6Core.so. Unificar obligaría a
apagarle xcb a KDE: radio 119.

Los símbolos indefinidos salieron por CAPAS y ninguno nombraba al culpable:
freetype (.a no PIC) → fontconfig (idem) → i2d_SSL_SESSION → inflateInit_. Las dos
primeras se arreglaron usando las variantes -shared que YA existían en el corpus;
las dos últimas con -lssl -lcrypto -lz, porque OBS resuelve curl con el FindCURL
de CMake, que toma libcurl.a por fichero y no lee su Libs.private. Un símbolo
indefinido nombra a la librería que lo USA, no a la que falta.

Huecos escritos en la receta para que no se descubran en la mano del usuario:
sin webcam (ENABLE_V4L2=OFF, libv4l2 no está en ninguna cola), sin salida MPEG-TS
(SRT/RIST ausentes) y sin scripting (falta swig). Grabar, capturar pantalla y
publicar por RTMP no pasan por ninguno de los tres.
2026-09-04 17:17:17 +00:00
Sergio 3f84cd761b estado: cosecha granja 2026-09-04T17:02:11Z — avance del árbol KDE 2026-09-04 17:02:11 +00:00
Sergio f3767f6361 corpus: pciutils-shared y mbedtls — dos deps duras de OBS
pciutils-shared: obs-ffmpeg (el plugin de codificación, sin perilla para
apagarlo) hace find_package(Libpci) para identificar la GPU por su ID. La
pciutils canónica va SHARED=no e instala SÓLO bin/sbin/share — provee.py
confirmaba que libpci.so no lo publicaba NINGUNA cola. Patrón zlib-shared: una
variante, sin mover el hash de la canónica.
Verificado que NO colisionan listando los dos artefactos: la variante sólo pone
usr/lib y usr/include; la canónica no pone nada en usr/lib. Rutas disjuntas
conviven; rutas pisadas son el cuadro de las dos glib. Por eso el install usa el
target `install-lib` y no `install`, que traería los binarios.

mbedtls: obs-outputs (streaming RTMP) hace find_package(MbedTLS REQUIRED) y NO
acepta OpenSSL — no hay opción en su CMake, está cableado.
Va por TARBALL DE RELEASE y no por commit, que es excepción consciente al ADR
0006: mbedtls 3.6 tiene framework/ como submódulo y [source] de hammer no clona
submódulos, así que el árbol llegaría incompleto. Un fichero de
/releases/download/ lo sube upstream y su sha256 es estable; lo inestable es
/archive/<tag>, que la forja genera al vuelo. La propiedad que el ADR exige —que
la fuente sea la misma mañana— se cumple igual.
PIC ON porque quien la consume es obs-outputs.so, un módulo dlopen.
2026-09-04 16:49:57 +00:00
Sergio 99eb0071f6 corpus: simde 0.8.2 — libobs la exige REQUIRED
libobs/CMakeLists.txt:10 hace find_package(SIMDe REQUIRED) y linkea SIMDe::SIMDe,
así que no es opcional para OBS. Sólo cabeceras, pero se instala por meson y no
copiando a mano porque genera simde.pc, que es por donde el FindSIMDe de OBS lo
encuentra: dejar las cabeceras sin su fichero de descubrimiento da el «está pero
no lo encuentra», peor de diagnosticar que una ausencia.
2026-09-04 16:33:22 +00:00
Sergio 684c1b0a24 estado: cosecha granja 2026-09-04T16:31:58Z — avance del árbol KDE 2026-09-04 16:31:58 +00:00
Sergio c2feb3eab6 corpus: uthash, nlohmann-json, jansson y x264 — las 4 deps que a OBS le faltaban
Las cuatro no existían en NINGUNA cola (medido cruzando el grafo, no con grep).
Van al corpus y no a una cola porque OBS es una app que quieren las cuatro
imágenes, y una receta resuelve sibling-first y después el catálogo PADRE, nunca
una cola hermana.

Verificadas por CONTENIDO del artefacto, no por exit 0 (regla 3 del repo):
 · uthash          5 cabeceras; no compila nada y la fase `compile` dice `true`
                   explícito, porque que una librería sea sólo cabeceras es un
                   hecho suyo, no un descuido de la receta.
 · nlohmann-json   pasa por CMake y no por un `cp` para que instale sus
                   nlohmann_jsonConfig/Targets.cmake: OBS hace find_package, y
                   copiar los .hpp a mano dejaría «está pero no lo encuentra».
 · jansson         libjansson.so.4.
 · x264            libx264.so.165 + x264.pc, y `asm: yes` — con SIMD, que es la
                   lección que ffmpeg acaba de costar hoy.

⚠ jansson trajo su propia trampa: la perilla es JANSSON_BUILD_SHARED_LIBS, NO la
estándar BUILD_SHARED_LIBS de CMake (CMakeLists.txt:5, default OFF). Con la
estándar el build sale exit 0 y sella un artefacto con SÓLO libjansson.a — la
receta diciendo link="dynamic" y el artefacto estático. Se vio mirando usr/lib/
del artefacto, no el código de salida.
2026-09-04 16:27:24 +00:00
Sergio 323a675ed0 estado: cosecha granja 2026-09-04T16:01:58Z — avance del árbol KDE 2026-09-04 16:01:58 +00:00
Sergio 666a681812 libglvnd 1.7.0: el GL de escritorio que a la distro le faltaba
Hasta hoy NINGUNA cola publicaba libGL.so, libGL.so.1 ni gl.pc (medido con
provee.py): mesa va -Dglx=disabled -Dglvnd=false, así que sólo había libEGL y
libGLESv2. Toda app de GL fijo compilaba —mesa SÍ instala GL/gl.h— y moría al
LIGAR. Lo destapó OBS: deps/glad linkea PUBLIC OpenGL::GL, que ES libGL.so, y eso
es un link, no un gate de configure que se pueda apagar.

SIN GLX Y SIN X11, que es lo que hace esto coherente con la distro: glvnd parte el
libGL.so.1 histórico en libGL.so.1 (GL+GLX ⇒ implica X11) y libOpenGL.so.0 (GL
pelado ⇒ no implica nada). Vamos por la segunda. Encender glx metería
libX11/libxcb/xorgproto —hoy sólo en incoming-kde— en el CORPUS, o sea en las
cinco imágenes, para servir a una sola app.

Entrega verificada en el artefacto: libOpenGL.so.0, libGLdispatch.so.0,
libEGL.so.1, libGLESv{1_CM,2}, y opengl.pc. Cero GLX.

El wrapper: meson emite `-Wl,--version-script <ruta>` con ESPACIO. Con gcc anda de
casualidad (reenvía al linker el argumento suelto que no entiende); zig-cc lo
rechaza con «unrecognized file extension». El wrapper une el par con `=`. No se
parchea upstream: el defecto es del contrato meson↔driver, no de glvnd.

⚠ Instala libEGL.so.1, que HOY la pone mesa. Mismo soname, otro dueño ⇒ mesa se
reconstruye con -Dglvnd=true en esta misma campaña, no después.
2026-09-04 15:35:32 +00:00
Sergio 8ddafc15e6 estado: cosecha granja 2026-09-04T15:32:15Z — avance del árbol KDE 2026-09-04 15:32:15 +00:00
Sergio 8d48f1869f vaapi: mpv cierra su último hueco — decodificación por hardware
libva sube al corpus y la copia de incoming-kde se JUBILA (git mv, no copia: dos
ficheros para un artefacto es el cuadro de las dos glib esperando a derivar). La
mudanza fue gratis y medida antes: las cinco deps de libva viven sólo en el
corpus, así que incoming-kde ya las resolvía por caída al padre y hammer hash dio
el MISMO ArtifactHash en las dos rutas (b3:405c6211).

libva pasa a -Dwith_wayland=yes, que eso SÍ cambia el hash. La razón está en
mpv/meson.build:1464: el feature `vaapi` se requiere contra
`vaapi-drm or vaapi-wayland or vaapi-x11 or vaapi-win32` ⇒ -Dvaapi=enabled a
secas no habilita NADA. De los cuatro backends, x11/win32 están fuera por
Wayland-only y vaapi-drm exige features[drm] de mpv, apagado porque vo=drm pide
libdisplay-info. Queda vaapi-wayland, que pide libva-wayland.pc.

Evidencia, no sólo sello: meson lista «vaapi vaapi-wayland» entre los features
habilitados, y el binario sellado trae NEEDED libva.so.2 + libva-wayland.so.2.

Radio medido antes de tocar: 2 dependientes (kpipewire, spectacle), los dos
reconstruidos. Las 7 imágenes siguen en 0 en deuda.

⚠ El driver es RUNTIME (intel-media-driver / gallium VA por dlopen): que esto
selle y que --hwdec=vaapi funcione en una máquina son cosas distintas.
2026-09-04 15:06:14 +00:00
Sergio 269e8410fd estado: cosecha granja 2026-09-04T15:02:12Z — avance del árbol KDE 2026-09-04 15:02:12 +00:00
Sergio 814676ad26 ffmpeg: x86asm encendida — mpv decodificaba sin SIMD por una prohibición vencida
La receta llevaba --disable-x86asm heredado de cuando ffmpeg entró SÓLO para
kpipewire (codificar un stream de escritorio, donde da igual). Para el
reproductor era decodificar sin SIMD.

Dos recetas —ffmpeg.toml y mpv.toml— prohibían tocarlo con la misma razón: un
hash distinto dejaría DOS ffmpeg peleando por las mismas rutas en una imagen KDE,
y el arreglo correcto sería «promover una sola y jubilar la de la cola». Eso ya
había pasado: incoming-kde/ffmpeg.toml no existe y hay UNA sola receta ffmpeg en
todo el disco. La prohibición sobrevivió a la condición que la justificaba.

--x86asmexe=nasm explícito y nasm (2.16.03) a [deps].build: sin ensamblador
declarado configure apagaría x86asm en SILENCIO, sellando un artefacto con otro
hash y sin la SIMD que dice traer.

Evidencia, no sólo sello: configure imprime «x86 assembler nasm», compila los
objetos X86ASM, y libavcodec.so pasa de 12.685.744 a 14.454.288 bytes (+1,77 MB).

Radio medido antes de tocar (yupana radio ffmpeg): 4 dependientes, ninguno
transitivo de más — mpv, wf-recorder, kpipewire, spectacle. Los 4 reconstruidos y
sellados; las 7 imágenes siguen en 0 en deuda.
2026-09-04 14:37:52 +00:00
Sergio 99a3ad5a30 estado: cosecha granja 2026-09-04T14:33:11Z — avance del árbol KDE 2026-09-04 14:33:11 +00:00
Sergio 9834f57052 yupana: --help imprimía literalmente None
Todo el encabezado del fichero era comentario `#`, así que __doc__ era None y
`main()` hace `print(__doc__)` en dos caminos: `--help` y verbo desconocido. La
puerta única de la metodología no sabía explicarse, y el error de verbo tampoco
decía cuáles son los verbos válidos.

La ayuda operativa pasa a docstring; el diseño y el porqué se quedan arriba como
comentario. Cotejada contra el despacho real: los 11 verbos de la ayuda existen y
los 11 que existen están en la ayuda (faltaba `sembrar`).
2026-09-04 14:27:34 +00:00
Sergio 28d98dc5f9 drenaje: medía 5 de 7 imágenes y las otras 2 desaparecían en silencio
targets.toml declara 7 perfiles; drenaje.json listaba 5. escritorio-cosmic (cola
incoming-cosmic) y escritorio-sway (cola incoming-wlr) declaraban una cola que
ningún grafo de GRAFOS contenía, así que cargar() devolvía None y --todos hacía
`continue` pelado. Dos imágenes enteras fuera del artefacto sin dejar rastro, y
los dos números —5 medidos, 7 declarados— no se cruzaban en ningún lado.

Mismo olvido que ya costó 17 días de build-state-wlr.json congelado: la lista de
grafos crece a mano y se queda atrás cuando se abre una cola.

Tres cambios:
- GRAFOS suma los grafos de cosmic y wlr.
- Un perfil sin medir se anota en el artefacto (`sin_medir`), se grita por stdout
  y drenar.py sale 1. Regla 3 del repo: un ausente falla ruidosamente.
- cosecha-cron deja de tragarse la salida; filtra las líneas ⚠ al log, que si no
  llegaban como un "falló" mudo que no dice cuál imagen falta.

Medido: las 2 imágenes que nadie miraba estaban limpias, 0 en deuda. Ahora son
7/7 verificadas en vez de 5 verificadas y 2 supuestas.
2026-09-04 14:26:04 +00:00
Sergio e8ca740119 estado: cosecha granja 2026-09-04T14:02:09Z — avance del árbol KDE 2026-09-04 14:02:09 +00:00
Sergio 2db76cfb32 estado: cosecha granja 2026-09-04T13:32:00Z — avance del árbol KDE 2026-09-04 13:32:00 +00:00
Sergio c52b2737bd estado: KDE cierra 1001/1001 — saldadas las 8 que mató el disco lleno
dolphin filelight kate kinfocenter konsole kscreen plasma-integration
plasma-desktop. Ninguna era fallo de receta: las 8 murieron el 2026-09-03 con
«No space left on device» y el bucle las anotó ✗ igual que a una que no compila.
Reintentadas tal cual, sin tocar una sola receta, sellaron las 8 a la primera.

escritorio-kde pasa a 263/263 y drenaje.json queda en 0 en deuda en los cinco
perfiles: base, cli, escritorio-{gnome,kde,mirada}.
2026-09-04 13:21:12 +00:00
Sergio 97023c3306 granja: PODA_FUENTES nace encendida y respeta el árbol de la receta que falló
Causa raíz de la deuda KDE de hoy: la cascada del 2026-09-03 corrió campana-deuda
SIN PODA_FUENTES=1 (cero menciones en su log). Los 71 árboles de fuentes se
acumularon en /dev/sdc a ~300 MB cada uno y lo llenaron en la receta 52; las 8
últimas murieron por disco, no por receta. Un default que hay que acordarse de
encender no es una defensa.

No poda tras un ✗: el árbol de la receta fallida es el post-mortem, y es justo el
caso en que alguien va a mirarlo. Mismo criterio que el suelo de 24 h de
poda-fuentes.sh, aplicado por resultado en vez de por edad.

Probado: sobrevive tras ✗, poda tras ✓, y PODA_FUENTES=0 sigue apagándola.
2026-09-04 13:11:47 +00:00
Sergio 3f26d37d17 granja: guardián de disco en campana-deuda — corta en vez de anotar ✗ falsos
La cascada KDE del 2026-09-03 llenó el disco en la receta 52 de 71 y siguió
moliendo: las 8 últimas murieron en 1-20 s con «No space left on device» y el
bucle las anotó ✗, el mismo símbolo que una receta que no compila. El grafo del
día siguiente decía «8 en deuda, clase c» y mandó a buscar un bug inexistente.

Mide el MÍNIMO de dos filesystems, no uno: en gioser store/ (/dev/sdb, 109 G) y
work/ (/dev/sdc, 53 G) son discos distintos y el que se llenó fue el de work/,
donde vive el árbol de fuentes. Mirando sólo el store el vigía habría leído
109 G y dejado moler igual.

Al cruzar el suelo corta con exit 3 y lista las recetas SIN INTENTAR, que no es
lo mismo que fallidas.
2026-09-04 13:09:17 +00:00
Sergio 6f145abe58 estado: cosecha granja 2026-09-04T13:01:50Z — avance del árbol KDE 2026-09-04 13:01:50 +00:00
Sergio cb7462249c estado: cosecha granja 2026-09-04T12:32:07Z — avance del árbol KDE 2026-09-04 12:32:07 +00:00
Sergio 728cbec07d estado: cosecha granja 2026-09-04T12:01:54Z — avance del árbol KDE 2026-09-04 12:01:54 +00:00
Sergio 3be39111c6 estado: cosecha granja 2026-09-04T11:31:54Z — avance del árbol KDE 2026-09-04 11:31:54 +00:00
Sergio bbbaf7141a estado: cosecha granja 2026-09-04T11:01:57Z — avance del árbol KDE 2026-09-04 11:01:57 +00:00
Sergio f41569beb1 estado: cosecha granja 2026-09-04T10:31:53Z — avance del árbol KDE 2026-09-04 10:31:53 +00:00
Sergio dbaf8d9a43 estado: cosecha granja 2026-09-04T10:01:53Z — avance del árbol KDE 2026-09-04 10:01:53 +00:00
Sergio a36124f38d estado: cosecha granja 2026-09-04T07:31:54Z — avance del árbol KDE 2026-09-04 07:31:54 +00:00
Sergio b2b261dd98 estado: cosecha granja 2026-09-04T07:01:52Z — avance del árbol KDE 2026-09-04 07:01:52 +00:00
Sergio 7db1522c14 estado: cosecha granja 2026-09-04T06:01:53Z — avance del árbol KDE 2026-09-04 06:01:53 +00:00
Sergio d67a7fa038 estado: cosecha granja 2026-09-04T05:01:49Z — avance del árbol KDE 2026-09-04 05:01:49 +00:00
Sergio 99f7f46c47 estado: cosecha granja 2026-09-04T04:31:42Z — avance del árbol KDE 2026-09-04 04:31:42 +00:00