SDD 28 §6.5: el muro derribado — de 23 binarios inertes a 1, y sin mover un ArtifactHash
Elegidas las salidas 1 y 2 del §6.4; hecha la 1, que resultó más barata de lo que parecía y desbloquea la 2 en vez de competir con ella. `musl-shared` publica `/usr/lib/libc.so` + `/lib/ld-musl-x86_64.so.1`. Como variante y no tocando la canónica: `musl` es Stage 1 y su `of_tree` es el baseline del selfhost. Control: `takana hash recipes/musl.toml` sigue en `b3:ce952f72…`. Y `musl` no es dep de nadie ⇒ cero re-hasheo del corpus. En la caja: `sh: python3: not found` → `Python 3.12.10`. De 23 inertes quedó **1**, `sqlite3`, que pedía `libz.so.1`; `zlib-shared` ya estaba sellado y sólo faltaba declararla en `base`. La salida 2 (python/perl estáticos) sigue viva pero deja de ser urgente: con el cargador publicado el sistema ya no cuelga del rootfs del lab. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RomoxEGZUhaT4pob1QSX5x
This commit is contained in:
@@ -582,6 +582,51 @@ Es decisión de ADR, y de las que conviene tomar mirando también el [SDD 27 §4
|
||||
las dos preguntas —«¿el cliente reproduce o hidrata?» y «¿el cliente puede correr lo que le
|
||||
mandamos?»— son la misma pregunta sobre qué es un sistema takana **sin laboratorio**.
|
||||
|
||||
### 6.5 ✅ El muro, derribado: el corpus publica su propio cargador *(2026-09-11)*
|
||||
|
||||
De las tres salidas del §6.4 el usuario eligió la 1 y la 2. Hecha la **1**, que resultó ser más barata
|
||||
de lo que parecía y desbloquea la 2 en vez de competir con ella.
|
||||
|
||||
**`recipes/musl-shared.toml`** — variante dinámica de musl que publica `/usr/lib/libc.so` (4,2 M) y
|
||||
`/lib/ld-musl-x86_64.so.1`. En musl el cargador Y la libc son el mismo objeto.
|
||||
|
||||
**Por qué una variante y no `--enable-shared` en la canónica**, con su control: `musl` es componente
|
||||
de **Stage 1** y su `of_tree` es el baseline de `selfhost-verify`. Tocarla obliga a rehacer ese
|
||||
baseline a propósito. Con el patrón `*-shared` —que el corpus ya usa 23 veces— la canónica no se
|
||||
mueve: `takana hash recipes/musl.toml` sigue dando `b3:ce952f72…`, el mismo sellado de Stage 1. Y
|
||||
además **`musl` no es dep de nadie** (medido: sólo de sí misma; el enlace estático lo resuelve el
|
||||
musl que trae zig), así que esto **suma sin mover un solo ArtifactHash del corpus**.
|
||||
|
||||
#### ⚠ Y hubo que cambiar de compilador, medido
|
||||
|
||||
Con `zig-cc` el `libc.so` sale con **1586 símbolos dinámicos** contra los **1654** del musl de Alpine,
|
||||
y los **68 que faltan son exactamente** los que musl implementa en ensamblador x86_64 — `memset`,
|
||||
`memcpy`, `memmove`, `memcmp`, `strlen` y toda la familia matemática (`ceil floor sqrt fmod exp log
|
||||
sin cos tan fma round trunc`) — más los `__stack_chk_*`.
|
||||
|
||||
No es que no se compilen: en el `libc.a` del musl canónico **están**. Lo que pasa es que **zig los
|
||||
resuelve con su propio musl y los deja `FUNC LOCAL HIDDEN` de tamaño 0**, fuera de la tabla dinámica.
|
||||
El síntoma es un cargador que arranca, reloca y muere con `memset: symbol not found` — que se lee
|
||||
como «el binario está roto», no como «a la libc le faltan símbolos».
|
||||
|
||||
Con `compiler = "gcc"`: **1651 símbolos**, `memset` y `ceil` presentes.
|
||||
|
||||
#### El resultado, en la caja
|
||||
|
||||
| antes | después |
|
||||
|---|---|
|
||||
| `sh: python3: not found` (con `command -v` contestando `/usr/bin/python3`) | `Python 3.12.10` |
|
||||
| 23 binarios inertes de 726 | **1** |
|
||||
|
||||
`perl 5.040002`, `readelf`/`objdump`/`nm` (GNU Binutils 2.45.1) y el resto corren. El único que
|
||||
quedaba era **`sqlite3`**, con `Error loading shared library libz.so.1`: la zlib canónica también es
|
||||
`--disable-shared` y nadie publicaba ese soname. `zlib-shared` ya existía sellado en el corpus —
|
||||
sólo faltaba declararla en `base`.
|
||||
|
||||
**La salida 2 (python/perl estáticos) sigue viva y ahora es opcional, no urgente**: con el cargador
|
||||
publicado el sistema ya no depende del rootfs del lab. Estático seguiría siendo mejor (un binario
|
||||
menos que puede quedar colgado de un soname), pero es un frente propio y ya no bloquea la mudanza.
|
||||
|
||||
### 6.2 Lo que la mudanza tiene que producir, además de la mudanza
|
||||
|
||||
El usuario lo pidió explícito: **que este experimento saque recetas y las pruebe**. La caja vieja es
|
||||
|
||||
@@ -40,6 +40,12 @@ paquetes = [
|
||||
# instrumental del proyecto. El síntoma era `sh: python3: not found` con `command -v python3`
|
||||
# contestando `/usr/bin/python3`: no falta, no arranca. Ver SDD 28 §6.4.
|
||||
"musl-shared",
|
||||
# `zlib-shared` (2026-09-11): el único hueco que quedó tras publicar el cargador. Con
|
||||
# `musl-shared`, 22 de los 23 binarios inertes de la imagen del servidor pasaron a correr; el 23º
|
||||
# era `sqlite3`, que muere con `Error loading shared library libz.so.1`. La zlib canónica es
|
||||
# `--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",
|
||||
]
|
||||
|
||||
[perfil.cli]
|
||||
|
||||
Reference in New Issue
Block a user