Commit Graph
2121 Commits
Author SHA1 Message Date
Sergio f9d4572077 compiler-rt-profile: la runtime de perfilado que el lab no trae (b3:32dff740)
libclang_rt.profile.a, 129.178 bytes — la que implementa los __llvm_profile_* y
escribe los .profraw. Hermana nativa de wasi-compiler-rt: mismo tarball de LLVM
22.1.8, mismo patrón, mismo sitio de aterrizaje; cambia el target (x86_64 en vez
de wasm32) y el componente (profile en vez de builtins).

Lo destapó el build del firefox instrumentado, en el minuto 38:56:

    ld.lld: error: cannot open
      /usr/lib/llvm22/lib/clang/22/lib/x86_64-alpine-linux-musl/libclang_rt.profile.a

El lab trae clang 22.1.8 con su include/ pero el lib/ del resource dir NO EXISTE
— que es exactamente lo que wasi-compiler-rt ya documentaba para el caso wasm.
O sea: el PGO no estaba bloqueado por el display (eso se despejó ayer) sino por
una pieza de toolchain que nunca hizo falta hasta ahora.

Se apaga todo menos profile: compiler-rt trae sanitizers, xray, memprof, orc y
ninguno tiene destinatario acá.

La primera corrida murió en el configure con «CMAKE_C_COMPILER_TARGET must also
be set when COMPILER_RT_DEFAULT_TARGET_ONLY is ON» — un error de cmake que dice
exactamente qué falta, cosa que no se puede dar por supuesta esta noche.

Dos guardianes. El primero exige la RUTA LITERAL del error y no «alguna
libclang_rt»: el layout per-target es una opción de cmake y equivocarla deja la
librería donde clang no mira, que es el mismo fallo que la libstdc++ en
/usr/lib64 de hace unas horas. El segundo es la prueba del consumidor: que
DEFINA __llvm_profile_write_file y compañía, para que un .a vacío no se descubra
al final de una corrida de perfilado.
2026-09-06 23:58:53 +00:00
SergioandClaude Opus 5 26a0dd31c7 SDD 26: restauradas §2.ter–§2.sexies, que mi commit anterior borró sin querer
Al reescribir el §6.8 corté el texto entre «lo que NO está probado» y `## 7`, y
entre medio no había sólo eso: vivían ahí §2.ter (el modo `[source] dir`),
§2.quater (los tres fallos que destapó abrirlo en pantalla), §2.quinquies (los
tres mecanismos de la v0.3) y §2.sexies (lo que quedó probado y con qué). Ciento
veinte líneas de método pagado con horas.

Recuperadas de HEAD~1 y comprobadas byte a byte con `diff` contra el original, no
a ojo.

La causa, que es la de siempre en este repo: usé un ANCLA («hasta el próximo
`## 7`») dando por hecho que el documento estaba en el orden en que yo lo
imaginaba. El §6.8 lo había insertado yo mismo antes del §2.ter hace unas horas,
así que el ancla saltaba por encima de cuatro secciones. Un ancla es una
etiqueta, no una propiedad del documento — la misma familia que la cabecera de
hunk que nombra la función anterior.

Lo que lo hizo visible en el mismo minuto fue mirar el `git show --stat`: 210
líneas cambiadas en un fichero donde yo había escrito 45. La regla 2 del
CLAUDE.md manda mirarlo para el ALCANCE del commit, pero sirve igual para el
tamaño del cambio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UgNtJEFetMYbXax5dVUjZZ
2026-09-06 23:48:19 +00:00
SergioandClaude Opus 5 2e093f9cab atuq §6.8: probado que el paquete sale por el proxy del contenedor — y con control negativo
Era lo único que la v0.5 dejó sin probar, y las tres puertas que había
encontrado siguen cerradas: no hay flag de línea de comandos para el
userContextId, Marionette no toma `-remote-allow-system-access` en la jaula, y
`tabs.create({cookieStoreId})` exige el permiso `cookies` — que no se le da a la
extensión del proxy sólo para que pueda probarse a sí misma.

La cuarta puerta estaba abierta: el fichero de SESIÓN guarda el userContextId de
cada pestaña y Gecko lo restaura. Se fabrica a mano — `mozLz40\0` + tamaño + un
bloque LZ4, y un bloque de sólo literales es LZ4 válido: veinte líneas, sin
librería.

Y la medición no le pregunta nada al navegador: le pone dos oídos en la red y
mira a cuál llama. Dos pestañas piden la MISMA url, una sin contenedor y otra en
«Banco»:

    al destino (8099)  GET /directo   <- la de sin contenedor, directa
    al proxy   (9099)  \x05\x01\x00   <- saludo SOCKS5 de la de «Banco»

Ese saludo sólo aparece si Gecko decidió hablar con un proxy para esa petición, y
el único que se lo pudo indicar es proxy.onRequest mirando el cookieStoreId. La
pestaña sin contenedor no es decorativa: sin ella, «todo fue por el proxy» y «el
ruteo anda» se verían iguales.

CONTROL NEGATIVO, que es lo que este repo se exige desde hoy: con
`--negative-control` no se configura el proxy y se exige lo contrario — las dos
pestañas directas y nadie llamando al proxy. Corrido: pasa. La única diferencia
entre las dos corridas es una línea de configuración y el observable se da vuelta
entero. Sin ese modo, una prueba que se hubiera vuelto ciega se vería idéntica a
una que funciona.

Tres detalles sin los cuales la prueba mide un silencio y se lee como fallo:
restore_on_demand=false, allow_hijacking_localhost=true, y el
triggeringPrincipal_base64 en cada entrada de sesión.

El artefacto se resuelve por `hammer hash` y no por glob, que es la lección de
hammer-03 de esta madrugada: con dos artefactos de la misma receta en el store,
`ls | head -1` es una ruleta.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UgNtJEFetMYbXax5dVUjZZ
2026-09-06 23:47:08 +00:00
Sergio 7f912c1e22 estado: cosecha granja 2026-09-06T23:33:11Z — avance del árbol KDE 2026-09-06 23:33:11 +00:00
Sergio 391d60eb90 estado: cosecha granja 2026-09-06T23:03:02Z — avance del árbol KDE 2026-09-06 23:03:02 +00:00
Sergio 44b6032522 vigia-sonames: dos falsos positivos menos — los cinco perfiles en CERO
NO hacía falta una receta de perl. `libperl.so` está en el artefacto, son 9,6 MB
en usr/lib/perl5/5.40.2/x86_64-linux/CORE/, y el binario la encuentra por su
RUNPATH, que apunta justo ahí. El vigía no la veía porque perl la construye con
-Duseshrplib y NO le pone SONAME: el código sólo registraba el nombre del fichero
`if son:`. Un ELF compartido sin SONAME se resuelve POR NOMBRE DE FICHERO, y eso
es exactamente lo que había que indexar.

El otro falso positivo era el último «hueco» del informe:
usr/lib/go/src/debug/elf/testdata/libtiffxx.so_ — un ELF de MUESTRA que Go
shipea para los tests de su propio paquete debug/elf, pidiendo libc.so.6 (glibc)
en una distro musl. Un binario que nadie ejecuta. `testdata/` no es cierre.

Importa arreglar un falso positivo aunque «sólo» sea ruido: un vigía que grita
en falso enseña a ignorarlo, y así es como libstdc++.so.6 —que SÍ rompía el
navegador en los cuatro escritorios— estuvo en esta misma salida sin que nadie
la mirara.

    escritorio-mirada    41 nodos ·  231 sonames ·  0 sin proveedor
    escritorio-kde      306 nodos · 2083 sonames ·  0 sin proveedor
    escritorio-gnome    190 nodos ·  657 sonames ·  0 sin proveedor
    escritorio-cosmic   161 nodos ·  498 sonames ·  0 sin proveedor
    escritorio-sway     201 nodos ·  509 sonames ·  0 sin proveedor

PROBADO CON UNA ROTURA A PROPÓSITO, porque un vigía todo-verde se ve igual que
uno roto. Quitando `runtime = ["gcc-libs"]` de firefox SOLO no pasa nada —atuq
lo declara también y es raíz de los mismos perfiles, así que la librería entra
igual; el primer control estaba mal montado—. Quitándolo de las DOS, kde y
cosmic vuelven a reportar libstdc++.so.6 y libgcc_s.so.1 exactamente. Restaurado
después.
2026-09-06 23:00:59 +00:00
Sergio 841abef25f estado: cosecha granja 2026-09-06T22:32:57Z — avance del árbol KDE 2026-09-06 22:32:57 +00:00
Sergio 02facebe28 deps.runtime: que ALGUIEN las lea — de 29 huecos de soname a 6
Tres arreglos que son el mismo: un campo que nadie lee es un campo que miente.

1. yupana._deps() leía SÓLO `deps.build`. Como yupana es la base de todas las
   herramientas de grafo, una dep de EJECUCIÓN no existía para ninguna: ni el
   vigía de sonames, ni la membresía de perfiles, ni el rootfs hidratado.
   Medido: firefox declaraba `runtime = ["gcc-libs"]` y el cierre de las cuatro
   imágenes seguía sin libstdc++.so.6, así que el navegador no arrancaba y el
   vigía lo seguía reportando como hueco DESPUÉS de haberlo arreglado.
   `deps.runtime` está en el esquema de hammer desde siempre. La unión es la
   definición de cierre: para CORRER hacen falta las dos.

2. build-state.py, lo mismo y por lo mismo.

3. El vigía entra en el LATIDO y deja docs/state/sonames.txt. Existía desde
   antes y contesta la pregunta que el grafo no contesta —no «¿está sellado?»
   sino «¿arranca?»— pero NADIE LO CORRÍA: no estaba en cosecha-cron y no dejaba
   fichero de estado. Por eso libstdc++.so.6, que rompía el navegador en los
   CUATRO perfiles, estuvo en su salida sin que nadie lo leyera, y se
   redescubrió arrancando atuq a mano. Un vigía que hay que acordarse de invocar
   no se distingue de no tenerlo.

Y se BORRA scripts/audit-needed.sh, que escribí ayer sin ver que vigia-sonames.py
ya hacía exactamente esto, con la misma frase en la cabecera. Dos herramientas
que miden lo mismo divergen y la que nadie mira es la que miente; la que se
queda es la que ya existía, que además reporta POR PERFIL y encontró más cosas.

python3 declara sus cuatro deps de ejecución (readline/sqlite/lzma/bz2): son
módulos de la stdlib que se cargan por dlopen, así que no rompen el arranque
sino un `import` — un fallo que aparece lejos y no menciona a python.

Resultado, con todo aplicado: 29 huecos -> 6, y los que quedan son otra clase.
`libperl.so` es empaquetado de la receta perl; `libc.so.6` lo pide el `go`
prebuilt y es un soname de GLIBC en una distro musl, que es un síntoma distinto.
Los dos quedan anotados en docs/state/sonames.txt, que ahora se regenera solo.
2026-09-06 22:28:17 +00:00
Sergio b2ff678301 readline-shared: la .so que python3 y sqlite piden (b3:79355aad)
libreadline.so.8, 970.144 bytes. Hermana de ncurses-shared y por la misma fuga:
python3 y sqlite-shared salen con NEEDED libreadline.so.8 y la readline del
catálogo es --disable-shared, así que sólo produce libreadline.a. En el rootfs
hidratado eso se resolvía contra el sysroot Alpine DEL LAB.

Versión 8.2 y no la 8.3.3 de Alpine, a propósito: es la que ya usa
recipes/readline.toml y tener las dos variantes en versiones distintas es pedir
que diverjan sin que nadie lo note.

TRES GUARDIANES, y el segundo es de Alpine casi literal. readline sale MAL
ENLAZADA por diseño de upstream —libreadline.so no enlaza contra ncurses salvo
que se lo fuerces, y queda con tgetent y compañía sin resolver—; Alpine lo
arregla con un parche y con un check que falla si el NEEDED de ncurses no
aparece. Acá se consigue sin parche con SHLIB_LIBS=-lncursesw, que es la perilla
que el propio Makefile expone. El guardián verifica que quedó enlazada, porque
si no el fallo reaparece en el consumidor, a un eslabón de distancia y sin
nombrar a esta receta.

La dep es ncurses-shared y no ncurses: con la estática, libreadline.so.8 se
llevaría los objetos de libncursesw.a dentro en vez de declarar el NEEDED — la
misma lección que el cairo estático de waterfox.

Se promueve además sqlite-shared de incoming-gnome al catálogo canónico: python3
la necesita como dep de ejecución y una receta de recipes/ no ve las de una
cola. Sin variantes en conflicto y ya sellada, así que la promoción no cuesta un
build.
2026-09-06 22:27:59 +00:00
Sergio 54729e01e8 estado: cosecha granja 2026-09-06T22:02:09Z — avance del árbol KDE 2026-09-06 22:02:09 +00:00
Sergio 15639dd9a6 estado: cosecha granja 2026-09-06T21:31:39Z — avance del árbol KDE 2026-09-06 21:31:39 +00:00
Sergio 1ac1ed81bd estado: cosecha granja 2026-09-06T21:02:07Z — avance del árbol KDE 2026-09-06 21:02:08 +00:00
Sergio 387f4e9256 estado: cosecha granja 2026-09-06T20:33:04Z — avance del árbol KDE 2026-09-06 20:33:04 +00:00
Sergio 5b9777bdbd declarar gcc-libs como dep de EJECUCIÓN en las seis — y el navegador arranca
Las seis recetas que el audit daba por colgantes declaran ahora
`runtime = ["gcc-libs"]`. `deps.runtime` NO entra en el ArtifactHash —medido:
firefox sigue en b3:8116bdec, atuq en b3:f2960991, waterfox en b3:88b5a762—
así que esto NO reconstruye nada. Lo que cambia es la CLAUSURA, que es lo que se
hidrata en la imagen.

EVIDENCIA DE QUE ARREGLA EL FALLO REAL, no de que compila: `atuq` bajo sway
headless, sin GPU, renderizando about:buildconfig con sus tablas y la barra de
contenedores de la v0.5. Antes moría con decenas de «Error relocating:
_ZNKSt5ctypeIcE13_M_widen_initEv: symbol not found».
docs/evidencia/atuq-arranca-con-gcc-libs-2026-09-06.png

Y el audit se corrige, porque SUB-REPORTABA en dos formas:

  · Miraba sólo ejecutables y `head -12` por artefacto. El siguiente NEEDED que
    faltaba estaba en una LIBRERÍA (libmozsandbox.so pedía libnspr4.so), así que
    daba «6 recetas» cuando el artefacto de firefox declara 30 sonames. Ahora
    recorre TODOS los ELF.
  · No contaba lo que el propio artefacto TRAE. Firefox bundlea su nspr/nss y
    las encuentra por el LD_LIBRARY_PATH que fija su lanzador; contarlas como
    colgantes era un falso positivo.

Con las dos correcciones y gcc-libs en el store, el corpus baja de 25 artefactos
colgantes a TRES, y son otra cosa:

    sqlite-shared   libreadline.so.8
    python3         libreadline.so.8
    naabu           libdl.so.2 libpthread.so.0 libc.so.6

Los dos primeros piden una receta que falta (readline). El tercero pide sonames
de GLIBC, que en una distro musl es un síntoma distinto y merece su propia
mirada. Quedan anotados, no arreglados.
2026-09-06 20:09:10 +00:00
Sergio 22bf487b1a gcc-libs: las librerías de ejecución que faltaban (b3:aa605af4)
libstdc++.so.6 (20.850.968 bytes) y libgcc_s.so.1 (824.776), construidas desde
el tarball de GCC 15.2.0 — la MISMA versión del lab, porque firefox se enlaza
contra la libstdc++ compartida de ese gcc y otra versión traería de vuelta el
mismo fallo disfrazado. sha512 del tarball verificado byte a byte contra el
APKBUILD de Alpine.

Tres decisiones que no son de estilo:

  --disable-symvers   Alpine lo pasa. El versionado cambia la tabla de símbolos;
                      nuestros binarios se enlazaron contra la libstdc++ SIN
                      versionar del lab.
  link = "dynamic"    hammer inyecta LDFLAGS=-static por defecto y acá el
                      producto ES una librería compartida: con el default no
                      saldría ni un .so. Misma perilla que apagaba los threads
                      de openssl, vista desde el otro lado.
  --disable-bootstrap Sólo `all-target-libgcc all-target-libstdc++-v3`. GCC
                      entero multiplica el tiempo por cinco para tirar el
                      compilador a la basura.

Los guardianes se ganaron el sueldo en las dos primeras corridas:

  1ª  «!! falta libstdc++.so.6» — y las librerías estaban perfectas: GCC instala
      en /usr/lib64 porque su t-linux64 fija MULTILIB_OSDIRNAMES=../lib64, y
      --disable-multilib NO lo apaga. Un .so impecable en el directorio que el
      loader no mira es EXACTAMENTE el fallo que esta receta viene a arreglar,
      un directorio más allá. Se normaliza a lib en el install.
  2ª  «!! no definen los símbolos» — y sí los definían. --disable-symvers apaga
      el versionado de libstdc++, pero libgcc tiene su PROPIO libgcc.map y
      versiona igual: nm los imprime como _Unwind_Backtrace@@GCC_3.3 y el grep
      anclado al fin de línea no los veía. El fallo era del guardián. Verificado
      contra el libgcc_s.so.1 DEL LAB —el que satisface a firefox hoy— y
      coinciden hasta en la etiqueta de versión.

gmp/mpfr/mpc ya existían pero sólo en recipes/incoming-*, con DOS variantes cada
una. Promovidas las de incoming-kde y no las de cosmic: la terna tiene que ser
internamente coherente porque mpc enlaza su .so contra las otras dos, y con las
de cosmic (estáticas sin PIC) muere en «relocation R_X86_64_32 ... recompile
with -fPIC». La de kde va con link=dynamic las tres y además ya estaba SELLADA
entera, así que la promoción no costó ni un build.
2026-09-06 20:08:53 +00:00
Sergio c5df480b36 estado: cosecha granja 2026-09-06T20:03:27Z — avance del árbol KDE 2026-09-06 20:03:27 +00:00
Sergio 4219d412ee estado: cosecha granja 2026-09-06T19:32:17Z — avance del árbol KDE 2026-09-06 19:32:17 +00:00
Sergio 2be672415c audit-needed: cazar deps de ejecución colgantes — firefox no arranca en la distro
Encontrado corriendo el navegador, no leyendo. Lancé `atuq` bajo el sway
headless y murió con decenas de «Error relocating: _ZNKSt5ctypeIcE...: symbol
not found». El binario SELLADO de firefox declara:

    NEEDED libstdc++.so.6      NEEDED libgcc_s.so.1      NEEDED libc.so

y las dos primeras NO EXISTEN en el store ni en ningún cierre hidratado: sólo en
.dev-fs/alpine, o sea en el LAB. Es exactamente la lección que la memoria
`quitar-dep-no-apaga-funcion` describe: el proyecto la encuentra en el sysroot
del lab y el artefacto sella con un NEEDED que nadie provee.

LO QUE LO HACE CARO ES QUE NINGUNA MÉTRICA LO VE. build-state.json dice
`sealed`; verificar-repro.sh dice que REPRODUCE bit a bit; los tres guardianes de
la receta pasan (RLBox en el binario, MOZ_REQUIRE_SIGNING, BuildID determinista)
— y el binario no arranca fuera del lab. El verde responde «¿construye?», nunca
«¿corre?».

El audit recorre el store, indexa qué sonames PROVEE el corpus y resta los NEEDED
de cada ELF. No mira el lab a propósito: mirarlo diría que todo está bien, que es
justo la ilusión que causó el problema.

Resultado de hoy: 25 artefactos colgantes, 6 recetas distintas —atuq, firefox,
waterfox, librsvg, spidermonkey, mesa-llvmpipe— y sólo DOS sonames faltan en todo
el corpus. O sea que falta UNA receta que provea las libs de runtime de gcc.

Gravedad: firefox y atuq son raíces de los CUATRO perfiles de escritorio
(cosmic, gnome, kde, sway), así que hoy las cuatro imágenes llevan un navegador
que no puede arrancar. La receta de firefox razona sobre esto en su comentario
—«clang++ de Alpine usa la libstdc++ COMPARTIDA ⇒ el NEEDED existe»— pero cierra
el requisito de BUILD y deja abierto el de EJECUCIÓN. hammer tiene
`[deps] runtime` y ninguna de las seis lo declara.
2026-09-06 19:23:02 +00:00
Sergio 04a5ff4be9 estado: cosecha granja 2026-09-06T19:03:28Z — avance del árbol KDE 2026-09-06 19:03:29 +00:00
Sergio c13410428e estado: cosecha granja 2026-09-06T18:32:26Z — avance del árbol KDE 2026-09-06 18:32:26 +00:00
Sergio 98d0ad49cc estado: cosecha granja 2026-09-06T18:02:12Z — avance del árbol KDE 2026-09-06 18:02:12 +00:00
Sergio 0aa0ab6e48 estado: cosecha granja 2026-09-06T17:02:08Z — avance del árbol KDE 2026-09-06 17:02:08 +00:00
Sergio b2df1fbac2 estado: cosecha granja 2026-09-06T16:32:26Z — avance del árbol KDE 2026-09-06 16:32:26 +00:00
Sergio e88e4ab3d7 SDD 26 §3.ter: el muro del display del PGO está despejado, con evidencia
El PGO necesita correr el navegador para juntar el perfil, y las distros lo
hacen bajo xvfb-run. Nosotros no tenemos X11 (Wayland-only), así que el plan
decía «la salida es un sway headless». Ya no es plan: se corrió.

sway con WLR_BACKENDS=headless y WLR_RENDERER=pixman arranca en gioser —un LXC
SIN /dev/dri, o sea sin GPU ninguna— y dibuja píxeles reales. La captura va como
evidencia: sway 1.10 / wlroots 0.18.2 / foot 1.27.0, los tres binarios nuestros,
salida HEADLESS-1 a 1280x720. Ciclo completo ~2 min.

Dos cosas que costó y quedan escritas para no repetirlas:

· Hidratar BAJO el montaje del store. hydrate-profile.py enlaza, y un hardlink
  no cruza montajes: con --into work/... sale EXDEV porque el store está en otro
  disco. Con --into store/.rootfs/sway son 193/193 nodos y 4,9 G que no ocupan.

· Inyectar el loader de musl. sway salió DINÁMICO y pide
  /lib/ld-musl-x86_64.so.1, que el cierre no trae. El error es
  «exec: /usr/bin/sway: not found», que se lee como «falta el binario» cuando lo
  que falta es su INTÉRPRETE. En musl el libc.so ES el loader, así que se
  resuelve con un --ro-bind. Misma familia que el resto de la noche: el mensaje
  nombra lo que buscó, no lo que falta.

Queda el segundo muro del PGO, que es de diseño y no de infra: el profdata no es
determinista, así que hay que generarlo UNA vez y sellarlo como artefacto propio
consumido por hash.
2026-09-06 16:09:24 +00:00
Sergio ff9dffaff6 estado: cosecha granja 2026-09-06T16:02:19Z — avance del árbol KDE 2026-09-06 16:02:19 +00:00
Sergio 1d2f7b7686 SDD 26: waterfox también reproduce bit a bit
`scripts/verificar-repro.sh recipes/waterfox.toml`: REPRODUCEN 1, DERIVA 0,
NO-DETERMINISMO 0.

Con esto el guardián del BuildID queda probado en las DOS direcciones que exige
la doctrina del repo, y no por diseño sino porque los hechos cayeron así: cazó
una rotura real —el artefacto anterior selló en verde con BuildID=20260906062042,
la hora del build— y pasa un control positivo, que es el arreglado reproduciendo
de verdad. Un guardián con sólo la primera mitad no se distingue de uno que mata
siempre; con sólo la segunda, de uno que no mira nada.

Los dos Gecko del corpus (firefox con RLBox y waterfox) reproducen.
2026-09-06 16:00:36 +00:00
Sergio 349da65086 SDD 26: el firefox con RLBox REPRODUCE bit a bit
`scripts/verificar-repro.sh recipes/firefox.toml`: reconstruido y comparado
contra el sellado da REPRODUCEN 1, DERIVA 0, NO-DETERMINISMO 0.

No es un trámite. Encender RLBox mete una cadena de compilación ENTERA nueva
—wasi-libc, libc++ a wasm32, los builtins, wasm2c traduciendo a C— dentro del
build de firefox, y la duda razonable era si algo de eso metía una fecha, un
orden de tabla hash o una ruta absoluta. No lo hace.

Es además la distinción que esta misma noche costó cara en la receta de al lado:
waterfox SELLÓ EN VERDE sin reproducir, porque el ArtifactHash es
input-addressed y no se mueve por un BuildID que sea la hora del build. «Selló»
y «está bien» son dos preguntas distintas, y la segunda cuesta un comando.
2026-09-06 15:24:20 +00:00
Sergio 100ecc9211 estado: cosecha granja 2026-09-06T15:02:24Z — avance del árbol KDE 2026-09-06 15:02:24 +00:00
Sergio 96c71de490 estado: cosecha granja 2026-09-06T14:32:06Z — avance del árbol KDE 2026-09-06 14:32:06 +00:00
Sergio 00d305de2f estado: cosecha granja 2026-09-06T14:02:14Z — avance del árbol KDE 2026-09-06 14:02:14 +00:00
Sergio f0b8d9025e estado: cosecha granja 2026-09-06T13:32:11Z — avance del árbol KDE 2026-09-06 13:32:11 +00:00
Sergio 757f4fb26d estado: cosecha granja 2026-09-06T13:02:08Z — avance del árbol KDE 2026-09-06 13:02:08 +00:00
Sergio 8dc8bb3a3e estado: cosecha granja 2026-09-06T12:32:22Z — avance del árbol KDE 2026-09-06 12:32:22 +00:00
Sergio b086382c44 estado: cosecha granja 2026-09-06T11:31:54Z — avance del árbol KDE 2026-09-06 11:31:54 +00:00
Sergio 384d9fe793 estado: cosecha granja 2026-09-06T11:02:18Z — avance del árbol KDE 2026-09-06 11:02:18 +00:00
Sergio 624745ed5f estado: cosecha granja 2026-09-06T10:31:54Z — avance del árbol KDE 2026-09-06 10:31:54 +00:00
Sergio 5755c6c401 estado: cosecha granja 2026-09-06T10:02:22Z — avance del árbol KDE 2026-09-06 10:02:22 +00:00
Sergio 70ca353653 estado: cosecha granja 2026-09-06T09:02:08Z — avance del árbol KDE 2026-09-06 09:02:08 +00:00
Sergio 8149036e2a estado: cosecha granja 2026-09-06T08:31:56Z — avance del árbol KDE 2026-09-06 08:31:56 +00:00
Sergio 00bee2645c estado: cosecha granja 2026-09-06T08:01:54Z — avance del árbol KDE 2026-09-06 08:01:54 +00:00
Sergio 7e9c43975e estado: cosecha granja 2026-09-06T07:31:52Z — avance del árbol KDE 2026-09-06 07:31:52 +00:00
Sergio 25934f52f3 SDD 26: waterfox sella — unidad 1 cerrada, y el corpus con cero deuda
b3:88b5a762, 377 M, 43 ficheros, BuildID=19700101000001 (determinista, con
guardián). Con esto el grafo queda 850/852 sellados y los dos que faltan son
`ajeno` (steam-runtime-sniper, xwayland), que son frontera y no deuda.

Los cuatro muros que costó, y ninguno era de la receta:

  1. Moría en 4 s por un submódulo git — era el binario de hammer del worker,
     13 h más viejo que el arreglo que los materializa.
  2. El linker moría sin mensaje — era el watchdog del worker-loop barriendo el
     objdir a los 2 minutos, antes de que nadie pudiera mirarlo.
  3. `multiple definition` de cairo — la receta traía la lista de deps anterior
     a la migración de firefox a las variantes -shared.
  4. Iconos faltantes al empaquetar — inconsistencia interna de Waterfox: el
     manifiesto pide ocho tamaños y branding-common.mozbuild instala cinco.
     Rotura sólo de Linux.

Y una quinta que el sello NO habría delatado: selló primero con
BuildID=20260906062042, o sea sin reproducir, y en VERDE.
2026-09-06 07:02:58 +00:00
Sergio 87a86c1e45 estado: cosecha granja 2026-09-06T06:32:04Z — avance del árbol KDE 2026-09-06 06:32:04 +00:00
Sergio 699bbe8475 waterfox: BuildID determinista — SELLÓ EN VERDE sin reproducir
waterfox selló (b3:e65c0221, 377 M, 43 ficheros) y el artefacto NO reproduce:

    BuildID=20260906062042

o sea la hora del build. Y selló en VERDE, que es lo peor: el ArtifactHash es
input-addressed y no se mueve por esto, así que build-state.json lo contaba como
bueno. Es EXACTAMENTE el modo de fallo que el comentario de firefox.toml
describe desde ayer —«el artefacto deja de reproducir SIN QUE NADA LO DIGA»—
ocurriendo en la receta de al lado por no haber copiado cuatro líneas.

Se exporta MOZ_BUILD_DATE en las TRES fases (son shells distintos y mach
re-ejecuta configure) y se pone el mismo guardián que firefox: si el BuildID no
es el que obliga SOURCE_DATE_EPOCH, el build muere.

Quedan escritas en la receta otras dos cosas medidas en el application.ini del
sellado, que son decisión y no bug, y por eso se documentan en vez de cambiarse:

  1. El branding «oficial» de ESTE commit es el de MOZILLA, no el de Waterfox.
     El comentario de la receta afirmaba lo contrario. Comprobado en el árbol:
     branding/official/configure.sh pone MOZ_APP_DISPLAYNAME=Firefox, brand.ftl
     da -brand-full-name = Mozilla Firefox, y el ID es el canónico de Firefox.
     Hoy esto sella un binario parcheado que se presenta como «Mozilla Firefox»,
     justo lo que firefox.toml evita yendo sin marca. La salida probable es
     `unofficial`, pero es política de marcas, no una perilla.

  2. Colisiona de ruta con firefox: instala en usr/lib/firefox/ y
     usr/bin/firefox porque no se fija MOZ_APP_NAME. Hoy no rompe nada porque
     ninguna imagen incluye las dos; el día que una lo haga, las dos capas
     overlay se pelean el mismo fichero y gana una en silencio.
2026-09-06 06:23:47 +00:00
Sergio c6e5a0b803 estado: cosecha granja 2026-09-06T06:02:13Z — avance del árbol KDE 2026-09-06 06:02:13 +00:00
Sergio cabb106c93 waterfox: instalar los tres iconos que su propio empaquetador exige
Con las deps -shared el enlace de libxul.so YA PASA (el choque de cairo se
acabó) y el build avanza hasta el empaquetado, donde muere así:

    error: browser/installer/package-manifest.in:239: Missing file(s):
           bin/browser/chrome/icons/default/default22.png
                                        :240: default24.png
                                        :245: default256.png

No falta arte y no es culpa nuestra: es una inconsistencia INTERNA del árbol de
Waterfox 6.7.1.1. Bajo `#ifdef MOZ_GTK` el manifiesto pide ocho tamaños (16, 22,
24, 32, 48, 64, 128, 256) y la rama gtk de branding-common.mozbuild lista sólo
cinco. Los tres ficheros existen en los CUATRO brandings del árbol
(official/aurora/nightly/unofficial); lo que falta es la línea que los instala.

Es una rotura sólo de Linux, que es la razón plausible de que upstream no la
note: la rama de Windows del mismo fichero está completa.

El hunk está GENERADO con `diff -u` sobre el fichero real, no escrito a mano: la
primera versión aplicaba «with fuzz 2» y la segunda «with fuzz 1». Un parche con
fuzz es uno que puede agarrar donde no debe, y verificar que aplica limpio cuesta
un `patch --dry-run`.

Va en recipes/waterfox-patches/ y no en firefox-patches/ porque es de waterfox:
firefox no lo necesita.
2026-09-06 05:44:09 +00:00
Sergio 800c80a8f7 estado: cosecha granja 2026-09-06T05:32:13Z — avance del árbol KDE 2026-09-06 05:32:14 +00:00
Sergio 0ef8320c6c waterfox: las variantes -shared de la cadena GUI, que es lo que mataba el enlace
El build llegaba al minuto 36 y moría enlazando libxul.so con un `collect2:
error: ld returned 1 exit status` y NADA delante — ni undefined reference, ni
cannot find -l, ni DSO missing. No era OOM ni disco. El filtro de salida de mach
clasificaba y descartaba justo el diagnóstico.

Rehecho el mismo objetivo llamando a gmake directo, el linker habló:

    ld: /usr/lib/libcairo.a(cairo-ft-font.c.o): in function `_cairo_ft_to_cairo_error':
        multiple definition of `_cairo_ft_to_cairo_error';
        gfx/cairo/cairo/src/cairo-ft-font.o: first defined here

…y así decenas de símbolos de cairo-ft-font, cairo-pdf-surface y
cairo-toy-font-face. O sea: el libcairo.a ESTÁTICO de la dep entra al enlace por
el -lcairo que arrastra el .pc de gtk3, y sus objetos chocan con el cairo
BUNDLEADO del propio árbol de Gecko.

La receta traía la lista de deps ANTERIOR a la migración de firefox: cairo,
pango, gdk-pixbuf y harfbuzz estáticas donde firefox ya usa las -shared. Y el
propio firefox.toml lo tiene escrito desde el 2026-09-05: declarar las estáticas
junto a un gtk3 que trae las compartidas son dos artefactos peleando por el
mismo .pc, «van las dos listas al mismo sitio o ninguna». Waterfox se quedó a
mitad de camino.

Con la variante compartida, -lcairo resuelve a libcairo.so y los símbolos
bundleados se quedan donde tienen que quedarse.

NO se tocan clang18/llvm18: firefox los quitó porque tapaban el LLVM 22 del lab
y con ThinLTO el bitcode no es compatible hacia atrás; acá el compilador es gcc,
así que ese razonamiento no aplica y cambiarlo sería otra unidad de trabajo.

Se deja puesta la rama de diagnóstico del compile: si mach falla, rehace el
enlace con gmake directo para que el linker hable. No cuesta nada en el camino
bueno (`&& exit 0`) y convirtió un fallo indiagnosticable en uno diagnosticado
en una sola corrida.
2026-09-06 05:03:57 +00:00
Sergio 96bfa8fe5d estado: cosecha granja 2026-09-06T05:02:07Z — avance del árbol KDE 2026-09-06 05:02:07 +00:00
Sergio 409eab1ffe estado: cosecha granja 2026-09-06T04:33:26Z — avance del árbol KDE 2026-09-06 04:33:26 +00:00