static-audit: auditaba SÓLO recipes/ y remataba con «toda receta lo cumple» — las 5 colas nunca se miraron

El audit del enlace estático globeaba `recipes/*.toml` y nada más, y cerraba con
« toda receta que declara link=static lo cumple»: una frase verdadera de una PARTE del corpus,
presentada como si fuera de todo él. Las cinco colas (`incoming{,-kde,-gnome,-cosmic,-wlr}`) son
~305 recetas que **nunca se auditaron**.

Lo destapé por accidente: al promover `libseccomp` de `incoming-gnome/` a `recipes/`, **el artefacto
no cambió ni un byte** y el audit pasó de MIENTEN:0 a MIENTEN:1. La mentira estaba ahí desde siempre
y lo único que la tapaba era el glob de una línea. Un guardián que mide menos de lo que su resumen
afirma es peor que no tenerlo: da por cubierto lo que no mira.

Ampliado el barrido a las colas, aparecen **3** que llevaban invisibles:

    libseccomp    scmp_sys_resolver     6 rebuilds  (corpus 1 + incoming-gnome 5)
    libgcrypt     dumpsexp y 2 más     41 rebuilds  (corpus 1 + incoming-kde 40)
    libgpg-error  gpg-error            45 rebuilds  (corpus 4 + incoming-kde 41)

Radios medidos con `yupana radio`, que cruza colas — no con `grep recipes/*.toml`, que es justo el
error que este commit arregla.

En las tres, lo dinámico es un **binario auxiliar de diagnóstico**, no la librería: los consumidores
enlazan el `.a`, así que el impacto funcional hoy es NULO. Lo que está mal es la declaración, y
arreglarla cuesta ~92 rebuilds casi todos de KDE. Van con el próximo bump de cada una, cuando el
re-hash ya esté pagado — mismo criterio que la deuda de `perl`. Decisión con el número delante, no
olvido.

Por eso entran en `DEUDA_DECIDIDA` y se imprimen como `•` sin hacer fallar: si el audit fallara
siempre por tres viejas, un ofensor NUEVO se perdería entre el ruido. El resumen ahora distingue
«MIENTEN (nuevos)» de «deuda decidida».

Probado con los dos controles y no sólo con el que da verde: quitándole a propósito el
`LDFLAGS=-all-static` a `crun` y reconstruyéndola, el audit sale **1** y la nombra; restaurada, sale
**0**. O sea que la tabla de deuda no se traga a un ofensor nuevo. El artefacto de la prueba se
borró del store.
This commit is contained in:
Sergio
2026-09-11 23:04:02 +00:00
parent 196c056834
commit 43a7ef0bd1
+39 -4
View File
@@ -43,10 +43,39 @@ if [ $# -gt 0 ]; then
recetas=""
for n in "$@"; do recetas="$recetas recipes/$n.toml"; done
else
recetas="$(grep -lE '^[[:space:]]*link[[:space:]]*=[[:space:]]*"static"' recipes/*.toml)"
# ⚠ **LAS COLAS TAMBIÉN.** Esto globeaba SÓLO `recipes/*.toml` y remataba con «✅ toda receta que
# declara link=static lo cumple» — una frase verdadera de una PARTE del corpus presentada como si
# fuera de todo él. Las cinco colas (`incoming{,-kde,-gnome,-cosmic,-wlr}`) son ~305 recetas que
# NUNCA se auditaron. Se destapó promoviendo `libseccomp` de `incoming-gnome/` al corpus el
# 2026-09-11: el artefacto no cambió ni un byte y el audit pasó de MIENTEN:0 a MIENTEN:1. O sea
# que la mentira estaba ahí desde siempre y lo único que la tapaba era el glob de esta línea.
# Un guardián que mide menos de lo que su resumen afirma es peor que no tenerlo: da por
# cubierto lo que no mira. Ver [[guardian-que-nunca-fallo]].
recetas="$(grep -lE '^[[:space:]]*link[[:space:]]*=[[:space:]]*"static"' \
recipes/*.toml recipes/incoming*/*.toml 2>/dev/null)"
fi
mienten=0; honestos=0; sin=0
# ── DEUDA MEDIDA Y DECIDIDA ────────────────────────────────────────────────────────────────────
# Mentiras REALES cuyo arreglo está decidido EN CONTRA por ahora. Se imprimen como `•` con el número
# delante y NO hacen fallar. El motivo de separarlas no es cosmético: si el audit falla siempre por
# tres viejas, un ofensor NUEVO se pierde entre el ruido y el guardián deja de servir — que es
# exactamente cómo se muere uno.
#
# Las tres salieron a la luz el 2026-09-11 al ampliar el barrido a las colas (antes sólo miraba
# `recipes/*.toml`). En las tres, lo dinámico es un BINARIO AUXILIAR de diagnóstico, no la librería:
# los consumidores enlazan el `.a`, así que el impacto funcional hoy es NULO. Lo que está mal es la
# DECLARACIÓN, y arreglarla se paga en rebuilds (radio medido con `yupana radio`, que cruza colas):
#
# libseccomp scmp_sys_resolver 6 rebuilds (corpus 1 + incoming-gnome 5)
# libgcrypt dumpsexp y 2 más 41 rebuilds (corpus 1 + incoming-kde 40)
# libgpg-error gpg-error 45 rebuilds (corpus 4 + incoming-kde 41)
#
# ~92 rebuilds, casi todos KDE, para que tres binarios que nadie invoca dejen de ser dinámicos. Va
# con el próximo bump de cada una, cuando el re-hash ya esté pagado y la línea cueste cero — el mismo
# criterio que la deuda de `perl`. Esto no es un olvido: es una decisión con el número delante.
DEUDA_DECIDIDA=" libseccomp libgcrypt libgpg-error "
mienten=0; honestos=0; sin=0; deuda=0
for f in $recetas; do
n=$(basename "$f" .toml)
grep -qE '^[[:space:]]*link[[:space:]]*=[[:space:]]*"static"' "$f" || continue
@@ -94,6 +123,12 @@ for f in $recetas; do
[ "$vistos" -eq 0 ] && { sin=$((sin + 1)); continue; }
if [ -n "$needed" ]; then
case "$DEUDA_DECIDIDA" in
*" $n "*)
printf ' • %-18s DEUDA DECIDIDA: %d/%d ejecutable(s) dinámico(s) (%s) — auxiliar, no la librería\n' \
"$n" "$malos" "$vistos" "$primer_malo"
deuda=$((deuda + 1)); continue ;;
esac
if [ "$malos" -gt 1 ]; then
printf ' ✗ %-18s dice static, %d de %d ejecutables DINÁMICOS (p.ej. %s) → %s\n' \
"$n" "$malos" "$vistos" "$primer_malo" "$needed"
@@ -109,10 +144,10 @@ for f in $recetas; do
done
echo
echo "══ estáticos de verdad: $honestos | MIENTEN: $mienten | sin artefacto o sin ELF: $sin"
echo "══ estáticos de verdad: $honestos | MIENTEN (nuevos): $mienten | deuda decidida: $deuda | sin artefacto o sin ELF: $sin"
[ "$mienten" -gt 0 ] && {
echo " fix: LDFLAGS=\"-all-static -no-pie\" en compile Y en install (libtool relinkea al instalar)"
exit 1
}
echo " ✅ toda receta que declara link=static lo cumple"
echo "ninguna receta NUEVA miente (corpus + las 5 colas). Las $deuda de deuda decidida están arriba, con su radio."
exit 0