gioser

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…

zstd-cli: la distro comprime todo con zstd y no traía con qué descomprimirlo

`recipes/zstd.toml` construye **sólo `lib/`** —lo dice su propia cabecera, «build de lib/ (no CLI)»—
porque lo que necesitan sus 13 consumidores (mesa, libadwaita, appstream, rsync, los `zstd-sys`) es
`libzstd.a`. El binario nunca se construyó, y el agujero sólo se ve al instalar la distro en una
máquina de verdad: **un takana recién instalado no puede desempacar su propio laboratorio**, porque
el `tar` del rootfs es el de busybox (`tar: unrecognized option: zstd`) y `zstd` no existe. Hubo que
extraer por tubería desde otro hub — y un hub que se instala solo no puede depender de eso.

⚠ **Y mi arreglo anterior estaba mal**: declaré `zstd` en `perfil.base` dando por hecho que traía el
binario. Se destapó aplicándolo con `takana upgrade` en la caja: «✓ generación 1 aplicada, + 8
añadidos» y `zstd` seguía ausente, porque los 8 ficheros eran headers y `libzstd.a`. **El upgrade
hizo exactamente lo que debía; lo que estaba mal era lo que le pedí que aplicara.** Corregido a
`zstd-cli`.

Variante y no ampliación de la canónica: `zstd` es dep de 13 recetas y `mesa` está entre ellas;
re-hashearla arrastraría esa torre por un binario de 1 M que ninguna usa. Mismo criterio que las 23
variantes `*-shared`, con el eje en librería/herramienta en vez de estático/dinámico. Radio cero.

`HAVE_ZLIB/LZMA/LZ4=0` a propósito: sin eso el Makefile las detecta del sysroot del LAB y el binario
sale pidiendo sonames que el artefacto no publica. Verificado: estático, 0 intérpretes requeridos,
`Zstandard CLI v1.5.7`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RomoxEGZUhaT4pob1QSX5x

d3b42f892d2eaea9ca44b7778c75a84c26ac0e8c · por Sergio · (hace 1 mes) · padre be1187e2d · ver el árbol en este commit

Delta semántico

Ninguna definición cambió: el cambio es de texto, documentación o datos.

2 archivos · +66 −6

diff --git a/docs/state/targets.toml b/docs/state/targets.toml
index 7d27cb63..4608885e 100644
--- a/docs/state/targets.toml
+++ b/docs/state/targets.toml
@@ -46,12 +46,17 @@ paquetes = [
   # `--disable-shared` y ningún artefacto publicaba ese soname — otra vez el rootfs del lab tapando
   # el agujero. La variante ya existía en el corpus; sólo faltaba declararla.
   "zlib-shared",
-  # `zstd` (2026-09-11): la distro comprime TODO con zstd —la imagen del lab (`lab-image.tar.zst`),
-  # el respaldo al Storage Box, el `dd` remoto de una instalación— y la imagen no lo traía. El
-  # resultado es que **un takana recién instalado no puede desempacar su propio laboratorio**: el
-  # `tar` del rootfs es el de busybox y contesta `tar: unrecognized option: zstd`. Se descubrió
-  # sembrando el lab en la caja de producción (SDD 28 §6.6).
-  "zstd",
+  # `zstd-cli` (2026-09-11): la distro comprime TODO con zstd —la imagen del lab
+  # (`lab-image.tar.zst`), el respaldo al Storage Box, el `dd` remoto de una instalación— y la imagen
+  # no traía con qué descomprimirlo: **un takana recién instalado no puede desempacar su propio
+  # laboratorio** (`tar: unrecognized option: zstd`, el tar del rootfs es el de busybox).
+  #
+  # ⚠ Es `zstd-cli` y NO `zstd`. La receta canónica construye **sólo `lib/`** —lo dice su cabecera— y
+  # su artefacto no tiene `usr/bin`: declararla acá no habría arreglado nada. Se vio al aplicarla con
+  # `takana upgrade` en la caja: «✓ generación 1 aplicada, +8 añadidos» y `zstd` seguía ausente,
+  # porque los 8 ficheros eran headers y `libzstd.a`. Ampliar la canónica re-hashearía a sus 13
+  # consumidores (mesa entre ellos), así que va como variante. Ver SDD 28 §6.13.
+  "zstd-cli",
 ]
 
 [perfil.cli]
diff --git a/recipes/zstd-cli.toml b/recipes/zstd-cli.toml
new file mode 100644
index 00000000..a433a2f7
--- /dev/null
+++ b/recipes/zstd-cli.toml
@@ -0,0 +1,55 @@
+# zstd-cli 1.5.7 — la HERRAMIENTA `zstd`, que la receta canónica no produce.
+#
+# ── POR QUÉ EXISTE ──────────────────────────────────────────────────────────────────────────────
+# `recipes/zstd.toml` construye **sólo `lib/`** («build de lib/ (no CLI)», dice su cabecera) porque
+# lo que necesitan sus 13 consumidores —mesa, libadwaita, appstream, rsync, los `zstd-sys` de Rust—
+# es `libzstd.a`. El binario nunca se construyó, y eso dejó un agujero que sólo se ve al instalar la
+# distro en una máquina de verdad:
+#
+#     $ tar --zstd -tf lab-image.tar.zst
+#     tar: unrecognized option: zstd          ← el tar del rootfs es el de busybox
+#     $ zstd --version
+#     sh: zstd: not found
+#
+# **Un takana recién instalado no puede desempacar su propio laboratorio.** La distro comprime todo
+# con zstd (la imagen del lab, el respaldo al Storage Box, el `dd` remoto de una instalación) y no
+# traía con qué descomprimirlo: había que extraer por tubería desde otro hub. Un hub que se instala
+# solo no puede depender de que otro hub le descomprima las cosas (SDD 28 §6.6).
+#
+# Y hay un segundo consumidor: `scripts/respaldo-storagebox.sh` usa `--compress-choice=zstd` —el
+# doble de rendimiento efectivo, medido— que rsync sólo ofrece si lo encuentra al construirse.
+#
+# ── POR QUÉ UNA VARIANTE Y NO AMPLIAR LA CANÓNICA ───────────────────────────────────────────────
+# `zstd` es dep de **13 recetas**, y `mesa` está entre ellas. Ampliar la canónica re-hashea la lib y
+# arrastra en cascada toda esa torre por un binario de 700 K que ninguna de ellas usa. Mismo criterio
+# que las variantes `*-shared` (23 en el corpus): la canónica no se mueve, el nombre es distinto, y
+# cada consumidor toma la que necesita. Acá el eje no es estático/dinámico sino **librería/herramienta**.
+#
+# Radio: cero. Nadie depende de `zstd-cli`; sólo la declara `perfil.base` como raíz.
+
+name    = "zstd-cli"
+version = "1.5.7"
+license = "BSD-3-Clause OR GPL-2.0-only"
+
+[source]
+tarball = "https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz"
+sha256  = "eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3"
+
+[build]
+compiler = "zig-cc"
+target   = "x86_64-linux-musl"
+link     = "static"
+
+# Split de la info de depuración (SDD 23 etapa 4). Entra en `hash_inputs`.
+strip_debug = true
+flags    = []
+
+[deps]
+build = ["make"]
+
+[build.phases]
+# `programs/` construye el ejecutable y enlaza la lib del propio árbol; no hace falta la canónica.
+# HAVE_ZLIB/LZMA/LZ4=0: sin esas deps el Makefile de zstd las detectaría del sysroot del LAB y el
+# binario saldría pidiendo sonames que el artefacto no publica — la fuga de [[needed-colgante]].
+compile = 'make -C programs zstd HAVE_ZLIB=0 HAVE_LZMA=0 HAVE_LZ4=0 CFLAGS="-O3"'
+install = 'mkdir -p /out/usr/bin && cp programs/zstd /out/usr/bin/zstd'