tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1572Shell 203Rust 109Markdown 993728 Sutichaykuna

paso 8 bis: pigz sobre zlib-rs, sellado — el swap en un consumidor real no costó una línea de su fuente

La lib andando contra un programa de prueba propio no decide una campaña de 122 recetas. pigz sí, y se
eligió por duro: no usa compress2 sino los rincones de zlib —inflateBack, inflateBackInit_,
inflateBackEnd, deflatePending, deflatePrime, crc32_combine, deflateSetHeader—, los siete comprobados
en los símbolos de zlib-rs ANTES de intentar el build. Y viaja en 6 perfiles.

b3:3a485edc… sellada. Lo único distinto de recipes/pigz.toml: la dep y `LIBS="… -lz -lunwind"`. El
-lunwind va en LIBS y no en LDFLAGS porque el Makefile pone $(LDFLAGS) antes de los objetos y $(LIBS)
al final: en enlace estático el orden decide.

MEDIDO (Silesia 15,7 MB, un hilo):
  comprimir -6   canónico 6.410.662 B / 0,726 s  ·  zlib-rs 6.455.201 B / 0,326 s   (+0,69 %, 2,23×)
  descomprimir   canónico 0,065 s               ·  zlib-rs 0,059 s
  binario        1.062.672 B                    ·  3.971.304 B                      (+2,9 MB, ×3,7)

INTEROPERABILIDAD en las tres direcciones: el canónico lee el .gz de zlib-rs, zlib-rs lee el del
canónico, y el gzip del corpus —tercera implementación— lee los dos, recuperando el sha256 original.

De las tres reservas del paso 8 quedan dos (no es byte-idéntica; gzprintf no existe) y aparece una
tercera: +2,9 MB por binario no es gratis en una imagen con muchos consumidores de zlib.

yupana gana el sufijo `-zlibrs` en SUFIJOS_VARIANTE: sin eso el invariante (c) marcaría
pigz/pigz-zlibrs como colisión-fuente ACCIONABLE, un falso positivo. Comprobado: duplicados sigue en
«ninguna».

8836ce70622e30c6525be879078fa957a416b122 · ruwaq Sergio · (29 p'unchaw ñawpaq) · tayta 227869462 · kay commitpi sach'ata qhaway

Semántico sayk'uy

Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.

3 qillqakuna · +103 −1

diff --git a/docs/plan-que-sigue-tras-busybox.md b/docs/plan-que-sigue-tras-busybox.md
index 9737b880..7c2812f3 100644
--- a/docs/plan-que-sigue-tras-busybox.md
+++ b/docs/plan-que-sigue-tras-busybox.md
@@ -1002,3 +1002,54 @@ usa, pero el store lo paga.
 que el plan suponía. La receta queda sellada en el catálogo con 0 consumidores y en ningún perfil: el
 siguiente paso natural es swapear UN consumidor real (`lld21` pide `libz.so.1`; `pigz` ejercita
 deflate a fondo) y correr su prueba, ahora que el artefacto existe y el enlace está caracterizado.
+
+## Paso 8 bis — el swap en un consumidor REAL: `pigz` sobre `zlib-rs`, sellado y verificado
+
+La lib andando contra un programa de prueba propio no decide una campaña de 122 recetas. Lo que
+decide es si un consumidor **de verdad**, con su Makefile y su uso de la API, compila y corre **sin
+tocar su fuente**. `recipes/pigz-zlibrs.toml`: `b3:3a485edc…`, sellada.
+
+**pigz es el consumidor duro, y por eso se eligió**: no usa el `compress2` de manual sino los rincones
+de zlib — `inflateBack`, `inflateBackInit_`, `inflateBackEnd`, `deflatePending`, `deflatePrime`,
+`crc32_combine`, `deflateSetHeader`. Comprobado que zlib-rs exporta **los siete** antes de intentar el
+build. Y viaja en 6 perfiles.
+
+**Lo único que cambió respecto de `recipes/pigz.toml`:** la dep (`zlib-rs` en vez de `zlib`) y
+`LIBS="… -lz -lunwind"`. El `-lunwind` va en `LIBS` y NO en `LDFLAGS` porque el Makefile de pigz pone
+`$(LDFLAGS)` antes de los objetos y `$(LIBS)` al final (línea 15): en enlace estático el orden decide
+y el unwinder tiene que ir DESPUÉS de quien lo pide. Fuente, banderas y fases, idénticas — la
+comparación vale porque lo único distinto es la lib.
+
+### Medido, con el corpus Silesia (15,7 MB) y un solo hilo para que el tiempo sea comparable
+
+| | `pigz` (zlib 1.3.1) | `pigz-zlibrs` |
+|---|---|---|
+| comprimir `-6` | 6.410.662 B · **0,726 s** | 6.455.201 B · **0,326 s** |
+| descomprimir (ejercita `inflateBack`) | 0,065 s | **0,059 s** |
+| tamaño del binario | 1.062.672 B | **3.971.304 B** |
+
+⇒ **+0,69 % de tamaño comprimido, 2,23× más rápido comprimiendo**, y descompresión un pelo más
+rápida. El precio está en el binario: **+2,9 MB** (×3,7), que es el mundo de Rust que el `staticlib`
+arrastra.
+
+### Interoperabilidad, en las tres direcciones que importan
+
+```
+canónico lee el .gz de zlib-rs   ⇒ OK      (sha256 del original recuperado)
+zlib-rs  lee el .gz del canónico ⇒ OK
+el `gzip` del corpus lee los dos ⇒ OK      ← tercera implementación, independiente
+```
+
+O sea: el formato es el mismo y el CRC cierra. Lo que difiere es **qué bytes elige el compresor**, que
+es la reserva nº 1 del paso 8 y sigue en pie.
+
+### Lo que esto cambia en el veredicto
+
+El swap en un consumidor real **no costó ni una línea de su fuente**, sólo la bandera del unwinder. Con
+eso, de las tres reservas del paso 8 quedan dos: la salida no es byte-idéntica (decisión de contenido)
+y `gzprintf` no existe (hay que mirar receta por receta). El tamaño del binario se suma como tercera:
+para una imagen con muchos consumidores de zlib, +2,9 MB por binario no es gratis.
+
+⚠ `scripts/yupana.py` gana el sufijo `-zlibrs` en `SUFIJOS_VARIANTE`: sin eso el invariante (c) marca
+`pigz`/`pigz-zlibrs` como «colisión-fuente ACCIONABLE», que es un falso positivo — y un guardián con
+falsos positivos se empieza a ignorar. Comprobado: `yupana duplicados` sigue en «ninguna».
diff --git a/recipes/pigz-zlibrs.toml b/recipes/pigz-zlibrs.toml
new file mode 100644
index 00000000..4caf1d04
--- /dev/null
+++ b/recipes/pigz-zlibrs.toml
@@ -0,0 +1,46 @@
+# pigz 2.8 sobre zlib-rs — la PRUEBA DE CONSUMIDOR del paso 8 del plan, sellada.
+#
+# ── POR QUÉ ESTA VARIANTE EXISTE ────────────────────────────────────────────────────────────────
+# `recipes/zlib-rs.toml` demostró que la lib anda contra un programa de prueba propio. Eso no alcanza
+# para decidir la campaña de las 122 recetas: lo que hay que saber es si un **consumidor de verdad**,
+# con su propio Makefile y su propio uso de la API, compila y CORRE sin tocar su fuente.
+#
+# pigz es el mejor candidato del corpus para eso, y no por ser chico:
+#   · usa los RINCONES de zlib, no el `compress2` de manual — `inflateBack`, `inflateBackInit_`,
+#     `inflateBackEnd`, `deflatePending`, `deflatePrime`, `crc32_combine`, `deflateSetHeader`.
+#     Comprobado que zlib-rs exporta los siete antes de intentar el build.
+#   · su producto es un fichero .gz que se puede verificar contra el `pigz` canónico: mismo formato,
+#     descomprimible por el otro, y con el CRC que el formato lleva adentro.
+#   · viaja en 6 perfiles, así que si el swap anda acá, anda donde importa.
+#
+# ── LO ÚNICO QUE CAMBIA RESPECTO DE `recipes/pigz.toml` ─────────────────────────────────────────
+#   1. `deps.build`: `zlib-rs` en vez de `zlib`. Publica `libz.a` con el mismo nombre, así que el
+#      `-lz` del Makefile lo encuentra sin tocar nada.
+#   2. `LIBS` gana `-lunwind`. Es la reserva nº 3 del paso 8: un `staticlib` de Rust arrastra el
+#      backtrace de std y sin el unwinder el enlace muere con `undefined symbol: _Unwind_Resume`.
+#      Va en `LIBS` y NO en `LDFLAGS` porque el Makefile de pigz pone `$(LDFLAGS)` ANTES de los
+#      objetos y `$(LIBS)` al final (línea 15) — en enlace estático el orden decide, y `-lunwind`
+#      tiene que ir DESPUÉS de `-lz`, que es quien lo necesita.
+#
+# La fuente, las banderas y el resto de las fases son idénticas a la receta canónica: la comparación
+# vale porque lo único distinto es la lib.
+name    = "pigz-zlibrs"
+version = "2.8"
+license = "Zlib"
+
+[source]
+tarball = "https://zlib.net/pigz/pigz-2.8.tar.gz"
+sha256  = "eb872b4f0e1f0ebe59c9f7bd8c506c4204893ba6a8492de31df416f0d5170fd0"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "static"
+flags    = []
+
+[build.phases]
+compile = 'make pigz CC="$CC" CFLAGS="-O2 -I/usr/include" LDFLAGS="-static -no-pie -L/usr/lib" LIBS="-lm -lpthread -lz -lunwind"'
+install = 'mkdir -p /out/usr/bin && cp pigz /out/usr/bin/pigz && ln -sf pigz /out/usr/bin/unpigz'
+
+[deps]
+build = ["zlib-rs", "make"]
diff --git a/scripts/yupana.py b/scripts/yupana.py
index 8bcb2deb..d4f5725c 100755
--- a/scripts/yupana.py
+++ b/scripts/yupana.py
@@ -127,7 +127,12 @@ def _deps_build(f):
 # duplicado a fundir — es la diversificación coherente [[etapa-g-gui-chain-boundary]]. `-hello`/`-hola`
 # son demos que vendorean la fuente de otro a propósito.
 SUFIJOS_VARIANTE = ("-shared", "-static", "-libs", "-tiny", "-dev", "-headers", "-minimal",
-                    "-generic", "-metal-dual", "-metal", "-swrast", "-llvmpipe", "-hello", "-hola")
+                    "-generic", "-metal-dual", "-metal", "-swrast", "-llvmpipe", "-hello", "-hola",
+                    # `-zlibrs` (2026-09-22): el MISMO paquete construido contra `zlib-rs` en vez de
+                    # `zlib`. Es la prueba de consumidor del paso 8; sin este sufijo el invariante (c)
+                    # lo reportaría como «colisión-fuente ACCIONABLE», que es un falso positivo — y un
+                    # guardián con falsos positivos se empieza a ignorar.
+                    "-zlibrs")
 
 
 def _base(n):