lab: lock del toolchain, porque edge es rodante y la deriva no se veia
Los repos del rootfs apuntan a Alpine edge (bump deliberado por el techo MSRV). Es RODANTE: el mismo script en dos fechas da compiladores distintos. Medido el 2026-08-10 al bootstrapear gioser — el laptop tenia rust 1.96 y aqui edge resolvio 1.97.0-r0. Para un proyecto cuyo invariante es reproducir eso es deriva del LAB, y no aparece en build-state.json. No es un pin y no puede serlo: edge sirve solo la ultima version (`apk policy rust` lista unicamente 1.97.0-r0), asi que `apk add rust=1.96.0-r0` rompe en cuanto edge avanza, y Alpine no publica snapshots datados de edge. Anclar de verdad pide espejar APKINDEX + los .apk, que es un frente aparte. Lo que si se puede hoy: registrar los 92 paquetes resueltos en docs/state/lab-toolchain.lock —que viaja por git, que es como los dos hubs lo comparan— y AVISAR con el diff delante cuando la maquina difiere. Aceptar el cambio es deliberado: --relock. Un lock que no se puede imponer sigue valiendo si al menos nombra lo que cambio. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
2 qillqakuna · +138 −0
- docs/state/lab-toolchain.lock +95 −0
- scripts/bootstrap-devfs.sh +43 −0
diff --git a/docs/state/lab-toolchain.lock b/docs/state/lab-toolchain.lock
new file mode 100644
index 00000000..cda331c7
--- /dev/null
+++ b/docs/state/lab-toolchain.lock
@@ -0,0 +1,95 @@
+# Toolchain del lab (.dev-fs/alpine) resuelto desde Alpine edge — RODANTE.
+# Regenerar deliberadamente con: scripts/bootstrap-devfs.sh --relock
+# No es un pin: edge sólo sirve la última versión. Esto DETECTA la deriva, no la evita.
+acl-libs-2.3.2-r1
+alpine-baselayout-3.7.2-r0
+alpine-baselayout-data-3.7.2-r0
+alpine-keys-2.6-r0
+alpine-release-3.23.4-r0
+apk-tools-3.0.6-r0
+autoconf-2.72-r1
+automake-1.18.1-r0
+bash-5.3.3-r1
+binutils-2.45.1-r0
+brotli-libs-1.2.0-r1
+bubblewrap-0.11.2-r0
+busybox-1.37.0-r30
+busybox-binsh-1.37.0-r30
+c-ares-1.34.8-r0
+ca-certificates-bundle-20260413-r0
+cargo-1.97.0-r0
+clang22-22.1.8-r0
+clang22-dev-22.1.8-r0
+clang22-extra-tools-22.1.8-r0
+clang22-headers-22.1.8-r0
+clang22-libclang-22.1.8-r0
+clang22-libs-22.1.8-r0
+coreutils-9.8-r1
+coreutils-env-9.8-r1
+coreutils-fmt-9.8-r1
+coreutils-sha512sum-9.8-r1
+curl-8.21.0-r0
+fortify-headers-3.0.2-r0
+g++-15.2.0-r8
+gcc-15.2.0-r8
+git-2.55.0-r1
+git-init-template-2.55.0-r1
+git-perl-2.55.0-r1
+gmp-6.3.0-r4
+isl26-0.26-r2
+jansson-2.14.1-r0
+kmod-34.2-r1
+libapk-3.0.6-r0
+libatomic-15.2.0-r8
+libattr-2.5.2-r2
+libbz2-1.0.8-r6
+libcap2-2.78-r0
+libcrypto3-3.5.6-r0
+libcurl-8.21.0-r0
+libexpat-2.8.2-r0
+libffi-3.5.2-r1
+libgcc-15.2.0-r2
+libgcc-static-15.2.0-r8
+libgomp-15.2.0-r8
+libidn2-2.3.8-r0
+libltdl-2.5.4-r2
+libncursesw-6.5_p20251123-r0
+libpsl-0.21.5-r3
+libssh2-1.11.1-r3
+libssl3-3.5.6-r0
+libstdc++-15.2.0-r8
+libstdc++-dev-15.2.0-r8
+libtool-2.5.4-r2
+libunistring-1.4.2-r0
+libxml2-2.13.9-r2
+linux-headers-7.1.5-r0
+llvm22-22.1.8-r1
+llvm22-libs-22.1.8-r1
+llvm22-linker-tools-22.1.8-r1
+m4-1.4.20-r0
+make-4.4.1-r3
+mpc1-1.3.1-r1
+mpfr4-4.2.2-r0
+musl-1.2.6-r2
+musl-dev-1.2.6-r2
+musl-utils-1.2.5-r23
+ncurses-terminfo-base-6.5_p20251123-r0
+nghttp2-libs-1.70.0-r0
+patch-2.8-r0
+pcre2-10.47-r1
+perl-5.42.2-r0
+perl-error-0.17030-r0
+perl-git-2.55.0-r1
+pkgconf-2.5.1-r0
+readline-8.3.1-r0
+rust-1.97.0-r0
+scanelf-1.3.8-r2
+scudo-malloc-22.1.8-r0
+skalibs-libs-2.14.4.0-r0
+sqlite-libs-3.53.4-r0
+ssl_client-1.37.0-r30
+utmps-libs-0.1.3.1-r0
+xz-libs-5.8.3-r0
+zlib-1.3.2-r0
+zlib-dev-1.3.2-r0
+zstd-libs-1.5.7-r2
diff --git a/scripts/bootstrap-devfs.sh b/scripts/bootstrap-devfs.sh
index 942e5dce..73cbf5b5 100755
--- a/scripts/bootstrap-devfs.sh
+++ b/scripts/bootstrap-devfs.sh
@@ -20,6 +20,7 @@
# ./scripts/bootstrap-devfs.sh # bootstrap completo
# ./scripts/bootstrap-devfs.sh --skip-apk # sólo rootfs + zig
# ./scripts/bootstrap-devfs.sh --force-zig # re-descarga zig
+# ./scripts/bootstrap-devfs.sh --relock # acepta el toolchain actual como lock
set -euo pipefail
@@ -35,11 +36,13 @@ GO_SHA256="${GO_SHA256:-1153d3d50e0ac764b447adfe05c2bcf08e889d42a02e0fe0259bd47f
SKIP_APK=0
FORCE_ZIG=0
FORCE_ROOTFS=0
+RELOCK=0
for arg in "$@"; do
case "$arg" in
--skip-apk) SKIP_APK=1 ;;
--force-zig) FORCE_ZIG=1 ;;
--force-rootfs) FORCE_ROOTFS=1 ;;
+ --relock) RELOCK=1 ;;
-h|--help)
sed -n '2,/^$/p' "$0" | sed 's/^# \?//'
exit 0 ;;
@@ -214,6 +217,46 @@ else
ok "build tools presentes en el rootfs ($NEEDED)"
fi
+# --- 3a-quater. Lock del toolchain: NOMBRAR la deriva de edge ------------------
+# Los repos de arriba apuntan a Alpine **edge**, que es RODANTE. Dos hubs bootstrapeados en fechas
+# distintas obtienen compiladores distintos con el mismo script: medido el 2026-08-10, el laptop
+# tenía rust 1.96 y gioser resolvió **1.97.0-r0**. Para un proyecto cuyo invariante es reproducir,
+# eso es deriva del LAB, y no se ve en `build-state.json`.
+#
+# POR QUÉ UN LOCK Y NO UN PIN DE VERDAD. Un pin exacto (`apk add rust=1.96.0-r0`) NO funciona: edge
+# sólo publica la última versión — `apk policy rust` lista únicamente 1.97.0-r0 —, así que el pin
+# rompe en cuanto edge avanza. Un snapshot datado tampoco existe: Alpine no los publica para edge.
+# Anclar de verdad exigiría espejar APKINDEX + los .apk nosotros, que es un frente aparte.
+# Mientras tanto esto hace lo segundo mejor y lo hace RUIDOSO: registra el toolchain resuelto y
+# AVISA cuando el de esta máquina difiere del registrado, con el diff delante.
+# Un lock que no se puede imponer sigue valiendo si al menos nombra lo que cambió.
+LOCK="$REPO_ROOT/docs/state/lab-toolchain.lock"
+if [[ -f "$ROOTFS/lib/apk/db/installed" ]]; then
+ ACTUAL="$WORK/.lab-toolchain.actual"
+ bwrap --bind "$ROOTFS" / --proc /proc --dev /dev --unshare-all \
+ --setenv PATH /usr/bin:/usr/sbin:/bin:/sbin \
+ /sbin/apk info -v 2>/dev/null | sort > "$ACTUAL"
+ if [[ $RELOCK -eq 1 ]] || [[ ! -f "$LOCK" ]]; then
+ mkdir -p "$(dirname "$LOCK")"
+ { echo "# Toolchain del lab (.dev-fs/alpine) resuelto desde Alpine edge — RODANTE."
+ echo "# Regenerar deliberadamente con: scripts/bootstrap-devfs.sh --relock"
+ echo "# No es un pin: edge sólo sirve la última versión. Esto DETECTA la deriva, no la evita."
+ cat "$ACTUAL"
+ } > "$LOCK"
+ ok "lock del toolchain escrito ($(wc -l < "$ACTUAL") paquetes) → docs/state/lab-toolchain.lock"
+ else
+ if diff -q <(grep -v '^#' "$LOCK") "$ACTUAL" >/dev/null 2>&1; then
+ ok "toolchain del lab idéntico al lock ($(wc -l < "$ACTUAL") paquetes)"
+ else
+ printf '\033[1;33m⚠\033[0m el toolchain de esta máquina DIFIERE del lock:\n'
+ diff <(grep -v '^#' "$LOCK") "$ACTUAL" | grep -E '^[<>]' | sed 's/^/ /'
+ printf ' ⇒ un artefacto Cargo sellado aquí puede no reproducir el del otro hub.\n'
+ printf ' Aceptarlo: scripts/bootstrap-devfs.sh --relock (y commitear el lock).\n'
+ fi
+ fi
+ rm -f "$ACTUAL"
+fi
+
# --- 3a-ter. Exponer la suite llvm-* en /usr/bin -----------------------------
# Alpine instala los binutils de LLVM en /usr/lib/llvm22/bin (versionado) sin symlink a /usr/bin,
# para permitir varias versiones. El PATH del sandbox es fijo (/opt/zig:/usr/local/bin:/usr/bin:...)