selfhost-verify: pieza 5 (coreutils swap) — SWAP_COREUTILS=1, musl+busybox byte-idénticos en host
Quinta pieza del toolchain hammer-from-source (variante b, SDD 11 §7.2b): GNU coreutils 9.8 (cp/mkdir/ln/chmod/mv/install…), que el `make install` de musl y busybox invocan. - recipes/coreutils.toml: empaquetada multicall (--enable-single-binary), mismo layout que el paquete de Alpine (un /bin/coreutils + ~100 symlinks que despachan por argv[0]). Estática musl con zig cc, vainilla sin patches (es tool del toolchain, no input compilado del 4/4). - scripts/selfhost-verify.sh: SWAP_COREUTILS=1 construye la receta y monta el único binario sobre /toolchain/bin/coreutils — los symlinks del toolchain (cp/mkdir/install/…) lo siguen, un solo --swap. Bisección host fuerte: con hammer-coreutils pisando el de Alpine (trap-restore en .dev-fs), musl Y busybox rebuildearon BYTE-IDÉNTICO (57b66a2e, 56664d70). Pendiente: corrida in-VM acumulando swaps. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
3 qillqakuna · +60 −2
- docs/10-roadmap.md +8 −2
- recipes/coreutils.toml +39 −0
- scripts/selfhost-verify.sh +13 −0
diff --git a/docs/10-roadmap.md b/docs/10-roadmap.md
index d79e4066..bddd1e83 100644
--- a/docs/10-roadmap.md
+++ b/docs/10-roadmap.md
@@ -284,8 +284,14 @@ Diseño completo en [SDD 11 — Bootstrap from-scratch](11-bootstrap.md). Resume
`usr/{include,lib,lib/pkgconfig}` en `/usr` — pkgconf y zig cc los hallan sin plumbing de flags (recetas
sin deps quedan byte-iguales, baseline intacto). Validación host fuerte: hammer-bwrap es estático, corre
`--version`/sandboxea, y **musl rebuildeó byte-idéntico** usándolo de sandbox (bisección). Expuesto con
- `SWAP_BWRAP=1`. **Pendiente:** correr in-VM acumulando los swaps
- (`KVM=1 MEM=24576 SWAP_MAKE=1 SWAP_BUSYBOX=1 SWAP_LINUX_HEADERS=1 SWAP_BWRAP=1 ./scripts/selfhost-verify.sh`)
+ `SWAP_BWRAP=1`; falta sólo correrla in-VM.
+ **Pieza 5 — coreutils (`recipes/coreutils.toml`, GNU 9.8, validada en host):** cp/mkdir/ln/chmod/mv/
+ install que el `make install` de musl/busybox usa. Empaquetada multicall (`--enable-single-binary`,
+ igual layout que Alpine: un `/bin/coreutils` + ~100 symlinks), así **un solo swap del binario** rutea
+ todos los applets. Tool, no input ⇒ build vainilla sin patches. Bisección host fuerte: **musl Y busybox
+ rebuildearon byte-idéntico** (`57b66a2e`, `56664d70`) con hammer-coreutils pisando el de Alpine.
+ Expuesto con `SWAP_COREUTILS=1`. **Pendiente:** correr in-VM acumulando los swaps
+ (`KVM=1 MEM=24576 SWAP_MAKE=1 SWAP_BUSYBOX=1 SWAP_LINUX_HEADERS=1 SWAP_BWRAP=1 SWAP_COREUTILS=1 ./scripts/selfhost-verify.sh`)
para el `✓ REPRODUCIBLE`, y seguir con la última pieza: rust/llvm (la grande — ya hay infra de deps).
- ✅ **B.2 — `CRASHED` real a la capa de IA (cableado end-to-end):** el `Event::Crashed` del
bus de agente ya tiene fuente real. **Fuente (arje):** `arje-bus` ganó `BusRequest::Subscribe`
diff --git a/recipes/coreutils.toml b/recipes/coreutils.toml
new file mode 100644
index 00000000..972507ee
--- /dev/null
+++ b/recipes/coreutils.toml
@@ -0,0 +1,39 @@
+# GNU coreutils 9.8 — pieza 5 del toolchain hammer-from-source (SDD 11 §7.2b).
+#
+# cp/mkdir/ln/chmod/mv/rm/install… del builder. El `make install` de musl y busybox los invoca (vía
+# tools/install.sh y el install de busybox), así que están en el camino real del 4/4. Hoy vienen del
+# paquete `coreutils` de Alpine.
+#
+# Como make/busybox/bwrap, coreutils es una HERRAMIENTA del toolchain (no input compilado del 4/4): no
+# necesita casar byte-a-byte con la de Alpine, sólo producir los mismos árboles instalados (cp copia los
+# mismos bytes con cualquier versión; of_tree ignora timestamps). Por eso build vainilla, sin patches.
+#
+# Alpine empaqueta coreutils como **multicall** (`/bin/coreutils` + ~100 symlinks cp→coreutils, …, igual
+# que busybox). `--enable-single-binary` reproduce ese layout: un único binario que despacha por argv[0].
+# El swap del builder reemplaza ese único `/toolchain/bin/coreutils` (swap de archivo) y los symlinks que
+# Alpine ya dejó en el toolchain (cp, mkdir, install, …) pasan a usar el de hammer — un solo --swap cubre
+# todos los applets.
+#
+# Tarball release (configure ya generado ⇒ AutoconfReady, como grep/make). Estático musl con zig cc.
+
+name = "coreutils"
+version = "9.8"
+
+[source]
+tarball = "https://ftp.gnu.org/gnu/coreutils/coreutils-9.8.tar.gz"
+sha256 = "1be88d53f694671cf7fb85e7723dbd1de9131d031880161b452a0685b986296e"
+
+[build]
+compiler = "zig-cc"
+target = "x86_64-linux-musl"
+link = "static"
+# --enable-single-binary: un solo binario multicall + symlinks (layout Alpine). --disable-nls: sin
+# gettext (ausente). Las flags van al ./configure (AutoconfReady).
+flags = ["--enable-single-binary", "--disable-nls"]
+
+[build.phases]
+# install por defecto (make install DESTDIR=/out) deja el multicall en /out/usr/bin/coreutils; lo
+# relocamos a /out/bin/coreutils, que es donde apuntan los symlinks del toolchain Alpine (/bin/cp →
+# coreutils, etc.) y el rel_path del swap. Mantenemos también el de /usr/bin por si algún consumidor
+# lo busca ahí; sólo bin/coreutils es lo que el swap monta.
+install = "make install DESTDIR=/out PREFIX=/usr && mkdir -p /out/bin && cp /out/usr/bin/coreutils /out/bin/coreutils"
diff --git a/scripts/selfhost-verify.sh b/scripts/selfhost-verify.sh
index c6bbabd9..6bf24f91 100755
--- a/scripts/selfhost-verify.sh
+++ b/scripts/selfhost-verify.sh
@@ -121,6 +121,8 @@ done
# kernel-owned de /toolchain/usr/include (linux/asm/…); musl bits/sys intactos.
# SWAP_BWRAP=1 → construye recipes/bwrap.toml (+libcap, su dep, vía deps.build) y lo monta
# sobre /toolchain/usr/bin/bwrap (el sandbox del propio lab).
+# SWAP_COREUTILS=1 → construye recipes/coreutils.toml (multicall) y monta el binario sobre
+# /toolchain/bin/coreutils; los ~100 symlinks (cp/mkdir/install/…) lo siguen.
# SWAPS="name=hash[:rel] …" → swaps explícitos extra (formato del flag --swap).
# Por defecto, off ⇒ corrida pura-Alpine (variante a), idéntica a la baseline conocida-buena.
# Piezas validadas en host: make+busybox reproducen of_tree=9adefb82 in-VM; linux-headers da un
@@ -168,6 +170,17 @@ if [[ "${SWAP_BWRAP:-0}" == 1 ]]; then
say "bwrap hammer: $BW_HASH"
SWAP_ARGS+=(--swap "bwrap=${BW_HASH}:usr/bin/bwrap")
fi
+if [[ "${SWAP_COREUTILS:-0}" == 1 ]]; then
+ # Pieza 5: GNU coreutils (cp/mkdir/ln/chmod/mv/install…). Multicall (--enable-single-binary), igual
+ # layout que Alpine: un binario /bin/coreutils + ~100 symlinks. UN swap del binario rutea todos los
+ # applets (los symlinks del toolchain ya apuntan a coreutils). Tool, no input: validado en host —
+ # musl Y busybox rebuildearon byte-idéntico bajo hammer-coreutils.
+ say "variante b — construir coreutils desde fuente y swapearlo en /toolchain/bin/coreutils"
+ CU_HASH="$("$HAMMER" --store "$STORE" build recipes/coreutils.toml | grep -oE 'b3:[0-9a-f]{64}' | tail -1)"
+ [[ "$CU_HASH" == b3:* ]] || die "no obtuve el hash sellado de coreutils"
+ say "coreutils hammer: $CU_HASH"
+ SWAP_ARGS+=(--swap "coreutils=${CU_HASH}:bin/coreutils")
+fi
for s in ${SWAPS:-}; do SWAP_ARGS+=(--swap "$s"); done
# 4) Ensamblar el builder con la referencia embebida.