diff --git a/docs/evidencia/atuq-arranca-con-gcc-libs-2026-09-06.png b/docs/evidencia/atuq-arranca-con-gcc-libs-2026-09-06.png new file mode 100644 index 00000000..522177c0 Binary files /dev/null and b/docs/evidencia/atuq-arranca-con-gcc-libs-2026-09-06.png differ diff --git a/recipes/atuq.toml b/recipes/atuq.toml index dcceb1da..2c3aa36e 100644 --- a/recipes/atuq.toml +++ b/recipes/atuq.toml @@ -142,6 +142,15 @@ grep -q '^Name=atuq' "$DST/application.ini" || { echo "atuq: application.ini no ''' [deps] +# ⚠ DEP DE EJECUCIÓN, NO DE BUILD — Y NO ES DECORACIÓN (2026-09-06). +# Este artefacto declara `NEEDED libstdc++.so.6` / `libgcc_s.so.1`, y hasta hoy NADIE en el corpus +# las proveía: sólo existían en `.dev-fs/alpine`, o sea en el LAB. El binario sellaba, REPRODUCÍA +# bit a bit, pasaba todos los guardianes… y no arrancaba fuera del lab. Se descubrió corriendo +# `atuq` bajo un sway headless, no leyendo el grafo. +# `runtime` NO entra en el ArtifactHash (igual que `license`), así que declararlo NO re-hashea: +# lo que cambia es la CLAUSURA, que es lo que se hidrata en la imagen. Lo vigila +# `scripts/audit-needed.sh`. +runtime = ["gcc-libs"] # `firefox` como dep de BUILD y no de runtime: su árbol se materializa en el sandbox, se copia # dentro del artefacto de atuq y a partir de ahí atuq no lo necesita más. El precio es que el # artefacto pesa lo que pesa Firefox otra vez; la salida barata (una granja de symlinks) rompe la diff --git a/recipes/firefox.toml b/recipes/firefox.toml index ab0e84af..9d8b213b 100644 --- a/recipes/firefox.toml +++ b/recipes/firefox.toml @@ -366,6 +366,15 @@ echo "guardián: RLBox en el binario (w2c_=$n_w2c rlbox=$n_rlb wasm2c=$n_w2n; co ''' [deps] +# ⚠ DEP DE EJECUCIÓN, NO DE BUILD — Y NO ES DECORACIÓN (2026-09-06). +# Este artefacto declara `NEEDED libstdc++.so.6` / `libgcc_s.so.1`, y hasta hoy NADIE en el corpus +# las proveía: sólo existían en `.dev-fs/alpine`, o sea en el LAB. El binario sellaba, REPRODUCÍA +# bit a bit, pasaba todos los guardianes… y no arrancaba fuera del lab. Se descubrió corriendo +# `atuq` bajo un sway headless, no leyendo el grafo. +# `runtime` NO entra en el ArtifactHash (igual que `license`), así que declararlo NO re-hashea: +# lo que cambia es la CLAUSURA, que es lo que se hidrata en la imagen. Lo vigila +# `scripts/audit-needed.sh`. +runtime = ["gcc-libs"] build = [ "python3", "pkgconf", "nasm", "make", "cmake", # la plataforma Gecko, compartida con los forks (SDD 26) diff --git a/recipes/incoming-gnome/librsvg.toml b/recipes/incoming-gnome/librsvg.toml index 83b14ead..982ab9d9 100644 --- a/recipes/incoming-gnome/librsvg.toml +++ b/recipes/incoming-gnome/librsvg.toml @@ -76,4 +76,13 @@ compile = "CARGO_NET_OFFLINE=true make" install = "CARGO_NET_OFFLINE=true DESTDIR=/out make install" [deps] +# ⚠ DEP DE EJECUCIÓN, NO DE BUILD — Y NO ES DECORACIÓN (2026-09-06). +# Este artefacto declara `NEEDED libstdc++.so.6` / `libgcc_s.so.1`, y hasta hoy NADIE en el corpus +# las proveía: sólo existían en `.dev-fs/alpine`, o sea en el LAB. El binario sellaba, REPRODUCÍA +# bit a bit, pasaba todos los guardianes… y no arrancaba fuera del lab. Se descubrió corriendo +# `atuq` bajo un sway headless, no leyendo el grafo. +# `runtime` NO entra en el ArtifactHash (igual que `license`), así que declararlo NO re-hashea: +# lo que cambia es la CLAUSURA, que es lo que se hidrata en la imagen. Lo vigila +# `scripts/audit-needed.sh`. +runtime = ["gcc-libs"] build = ["make", "pkgconf", "python3", "py3-setuptools", "gobject-introspection", "gi-foreign-girs", "glib", "glib-introspected", "gdk-pixbuf", "cairo-shared", "pango", "harfbuzz", "fribidi", "freetype-shared", "fontconfig-shared", "libxml2-shared", "libpng-shared", "pixman", "expat", "libffi", "pcre2", "zlib-shared"] diff --git a/recipes/incoming-gnome/spidermonkey.toml b/recipes/incoming-gnome/spidermonkey.toml index 093ea678..420a00da 100644 --- a/recipes/incoming-gnome/spidermonkey.toml +++ b/recipes/incoming-gnome/spidermonkey.toml @@ -45,4 +45,13 @@ compile = "export MOZBUILD_STATE_PATH=/src/.mozbuild MOZ_NOSPAM=1 && cd js/src install = "export MOZBUILD_STATE_PATH=/src/.mozbuild MOZ_NOSPAM=1 && cd js/src/obj && make DESTDIR=/out install" [deps] +# ⚠ DEP DE EJECUCIÓN, NO DE BUILD — Y NO ES DECORACIÓN (2026-09-06). +# Este artefacto declara `NEEDED libstdc++.so.6` / `libgcc_s.so.1`, y hasta hoy NADIE en el corpus +# las proveía: sólo existían en `.dev-fs/alpine`, o sea en el LAB. El binario sellaba, REPRODUCÍA +# bit a bit, pasaba todos los guardianes… y no arrancaba fuera del lab. Se descubrió corriendo +# `atuq` bajo un sway headless, no leyendo el grafo. +# `runtime` NO entra en el ArtifactHash (igual que `license`), así que declararlo NO re-hashea: +# lo que cambia es la CLAUSURA, que es lo que se hidrata en la imagen. Lo vigila +# `scripts/audit-needed.sh`. +runtime = ["gcc-libs"] build = ["nspr", "nasm", "cbindgen", "python3", "make", "zlib", "pkgconf"] diff --git a/recipes/mesa-llvmpipe.toml b/recipes/mesa-llvmpipe.toml index 90cfe9fa..a9ae5d2f 100644 --- a/recipes/mesa-llvmpipe.toml +++ b/recipes/mesa-llvmpipe.toml @@ -27,6 +27,15 @@ compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output" install = "DESTDIR=/out ninja -C output install" [deps] +# ⚠ DEP DE EJECUCIÓN, NO DE BUILD — Y NO ES DECORACIÓN (2026-09-06). +# Este artefacto declara `NEEDED libstdc++.so.6` / `libgcc_s.so.1`, y hasta hoy NADIE en el corpus +# las proveía: sólo existían en `.dev-fs/alpine`, o sea en el LAB. El binario sellaba, REPRODUCÍA +# bit a bit, pasaba todos los guardianes… y no arrancaba fuera del lab. Se descubrió corriendo +# `atuq` bajo un sway headless, no leyendo el grafo. +# `runtime` NO entra en el ArtifactHash (igual que `license`), así que declararlo NO re-hashea: +# lo que cambia es la CLAUSURA, que es lo que se hidrata en la imagen. Lo vigila +# `scripts/audit-needed.sh`. +runtime = ["gcc-libs"] # llvm18: el libLLVM hammer-built (soberano) que llvmpipe JIT-linkea. hammer lo materializa en el # sandbox en /usr ⇒ /usr/bin/llvm-config es el de LLVM 18 (no el LLVM 22 de Alpine, que mesa 24.0.9 # no traga). Runtime: libLLVM.so.18 se inyecta a la imagen QEMU (NEEDED sólo libc por -static-libstdc++). diff --git a/recipes/waterfox.toml b/recipes/waterfox.toml index 6c188625..bd51b52c 100644 --- a/recipes/waterfox.toml +++ b/recipes/waterfox.toml @@ -256,6 +256,15 @@ echo "guardián: BuildID = $real (determinista, de SOURCE_DATE_EPOCH)" ''' [deps] +# ⚠ DEP DE EJECUCIÓN, NO DE BUILD — Y NO ES DECORACIÓN (2026-09-06). +# Este artefacto declara `NEEDED libstdc++.so.6` / `libgcc_s.so.1`, y hasta hoy NADIE en el corpus +# las proveía: sólo existían en `.dev-fs/alpine`, o sea en el LAB. El binario sellaba, REPRODUCÍA +# bit a bit, pasaba todos los guardianes… y no arrancaba fuera del lab. Se descubrió corriendo +# `atuq` bajo un sway headless, no leyendo el grafo. +# `runtime` NO entra en el ArtifactHash (igual que `license`), así que declararlo NO re-hashea: +# lo que cambia es la CLAUSURA, que es lo que se hidrata en la imagen. Lo vigila +# `scripts/audit-needed.sh`. +runtime = ["gcc-libs"] build = [ "python3", "pkgconf", "nasm", "make", "cmake", # la plataforma Gecko, compartida con Waterfox y Zen diff --git a/scripts/audit-needed.sh b/scripts/audit-needed.sh index e053c7dc..0cbb5193 100755 --- a/scripts/audit-needed.sh +++ b/scripts/audit-needed.sh @@ -38,18 +38,28 @@ find "$STORE" -maxdepth 5 -name '*.so' -o -maxdepth 5 -name '*.so.*' 2>/dev/null echo "== sonames provistos por el store: $(wc -l < "$tmp/provisto")" # 2. Qué pide cada artefacto. +# +# ⚠ DOS CORRECCIONES SOBRE LA PRIMERA VERSIÓN, las dos por sub-reportar (2026-09-06): +# · Miraba sólo ejecutables y `head -12` por artefacto. El `NEEDED` que faltaba de verdad estaba +# en una LIBRERÍA (`libmozsandbox.so` pedía `libnspr4.so`), así que el audit daba «6 recetas» +# cuando el artefacto de firefox solo declara 30 sonames. Ahora mira 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 sería un falso positivo. colgantes=0 for d in "$STORE"/*/; do d=${d%/}; nombre=$(basename "$d"); receta=${nombre#*-} + # lo que este artefacto se provee a sí mismo + find "$d" \( -name '*.so' -o -name '*.so.*' \) 2>/dev/null | sed 's|.*/||' | sort -u > "$tmp/propio" falta="" while IFS= read -r f; do n=$(readelf -d "$f" 2>/dev/null | sed -n 's/.*Shared library: \[\(.*\)\]/\1/p') for so in $n; do grep -qxF "$so" "$tmp/provisto" && continue + grep -qxF "$so" "$tmp/propio" && continue case "$so" in libc.so|ld-musl*) continue ;; esac # la libc la pone el sistema base case " $falta " in *" $so "*) ;; *) falta="$falta $so" ;; esac done - done < <(find "$d" -maxdepth 4 -type f -perm -u+x 2>/dev/null | head -12) + done < <(find "$d" -type f \( -name '*.so' -o -name '*.so.*' -o -perm -u+x \) 2>/dev/null) [ -n "$falta" ] && { printf ' ✗ %-24s pide y nadie provee:%s\n' "$receta" "$falta"; colgantes=$((colgantes+1)); } done