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 1569Shell 203Rust 109Markdown 993728 Definiciones

imágenes: PID1 sale del artefacto sellado, no del directorio base congelado

Las 4 imágenes de escritorio (GNOME + los 3 de KDE: qemu, metal, dual) fundían `work/metal-rootfs`
por hardlinks y se llevaban SU arje-zero, que era del 2026-06-19: ese directorio se armó a mano en
la campaña de metal y nadie lo regeneraba al re-sellar la receta. Resultado: todas arrancaban con un
PID1 de hace mes y medio, en silencio.

No es hipotético — se comió un fix real. El `identity mismatch` del bus del fractal estaba arreglado
río arriba y la VM seguía imprimiendo el mensaje viejo porque el binario de la imagen no venía de la
receta (ver el comentario de recipes/arje-zero.toml).

El síntoma engaña porque el directorio base es LEGÍTIMO para todo lo demás —busybox, firmware, el
kernel EFI-stub, la estructura de /etc—: sólo la pieza que TAMBIÉN es receta se queda atrás, y justo
esa es PID1. La regla que queda escrita en el helper: si algo del rootfs tiene receta, la imagen lo
toma del artefacto sellado, no de la copia congelada.

El helper va en scripts/lib/ y no inline ×4 a propósito: el porqué es largo y vale una sola copia.
Elige el artefacto por `hammer hash` (el de la receta de HOY, no el más nuevo por fecha, que miente
en cuanto conviven dos) y ABORTA si falta, porque seguir con el PID1 congelado es exactamente el
modo de falla que cierra.

Probado: las 4 pasan `bash -n` y la imagen GNOME lo ejecuta bien sourceado (`✓ e570c1482432 (el de
work/metal-rootfs era de 2026-06-19)`), con la VM ya validada booteando ese PID1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

84e088fd130d0421d35ffa2b108a59c4cbb19e62 · por sergio · (hace 2 meses) · padre e4b6c0f12 · ver el árbol en este commit

Delta semántico

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

5 archivos · +55 −22

diff --git a/scripts/gnome/qemu-desktop-image.sh b/scripts/gnome/qemu-desktop-image.sh
index 2e9a936c..9e482248 100755
--- a/scripts/gnome/qemu-desktop-image.sh
+++ b/scripts/gnome/qemu-desktop-image.sh
@@ -31,28 +31,8 @@ rm -rf "$MERGED"
 cp -al "$BASE" "$MERGED"
 cp -al --remove-destination "$GNOME"/. "$MERGED"/
 
-# ── PID1 DESDE EL STORE, no desde el directorio base ────────────────────────────────────────────
-# `work/metal-rootfs` se armó a mano en la campaña de metal y quedó CONGELADO: su `arje-zero` era de
-# 2026-06-19. Nadie lo re-generaba al re-sellar la receta, así que cada imagen de escritorio arrancaba
-# con un PID1 de hace mes y medio sin que nada lo dijera. Así se comió el fix del `identity mismatch`:
-# arje-zero se había arreglado río arriba y la VM seguía imprimiendo el mensaje viejo.
-#
-# El síntoma es engañoso porque el directorio base es LEGÍTIMO para todo lo demás (busybox, firmware,
-# el kernel EFI-stub): sólo la pieza que también es receta se queda atrás. Regla: **si algo del rootfs
-# tiene receta, la imagen lo toma del artefacto sellado, no de la copia congelada.**
-#
-# Se elige por `hammer hash` —el artefacto que corresponde a la receta de HOY—, mismo criterio que los
-# dos compat daemons de más abajo; el más reciente por fecha miente en cuanto conviven dos.
-echo "==> PID1: arje-zero desde el store (no desde $BASE)"
-AZ="${AZ:-store/$(./target/release/hammer --store store hash recipes/arje-zero.toml 2>/dev/null | tail -1 | sed 's/^b3://')-arje-zero}"
-if [ -d "$AZ" ] && [ -x "$AZ/usr/bin/arje-zero" ]; then
-  install -Dm755 "$AZ"/usr/bin/arje-zero "$MERGED"/usr/bin/arje-zero
-  echo "   ✓ $(basename "$AZ" | cut -c1-12)  (el de $BASE era de $(stat -c '%y' "$BASE"/usr/bin/arje-zero 2>/dev/null | cut -d' ' -f1))"
-else
-  echo "   ✗ falta arje-zero sellado en store/ — la imagen usaría el PID1 CONGELADO de $BASE" >&2
-  echo "     construílo:  ./target/release/hammer build recipes/arje-zero.toml --store store" >&2
-  exit 1
-fi
+. "$ROOT/scripts/lib/pid1-desde-store.sh"
+inyectar_pid1 "$MERGED" "$BASE"
 
 echo "==> parcheando mesa software desde $MESA"
 # El cierre GNOME trae mesa con SÓLO iris_dri.so (Intel real). En QEMU no hay GPU: hace falta
diff --git a/scripts/kde/metal-desktop-image-dual.sh b/scripts/kde/metal-desktop-image-dual.sh
index e8aff569..b9cf2cdd 100755
--- a/scripts/kde/metal-desktop-image-dual.sh
+++ b/scripts/kde/metal-desktop-image-dual.sh
@@ -38,6 +38,9 @@ rm -rf "$MERGED"
 cp -al "$BASE" "$MERGED"
 cp -al --remove-destination "$KDE"/. "$MERGED"/
 
+. "$ROOT/scripts/lib/pid1-desde-store.sh"
+inyectar_pid1 "$MERGED" "$BASE"
+
 echo "==> inyectando mesa-llvmpipe (software GL) desde $MESA"
 cp -a "$MESA"/usr/lib/dri/. "$MERGED"/usr/lib/dri/ 2>/dev/null || true
 for so in libglapi libgbm libEGL libGLESv2 libgallium; do
diff --git a/scripts/kde/metal-desktop-image.sh b/scripts/kde/metal-desktop-image.sh
index bd3b0836..f5ae075d 100755
--- a/scripts/kde/metal-desktop-image.sh
+++ b/scripts/kde/metal-desktop-image.sh
@@ -33,6 +33,9 @@ rm -rf "$MERGED"
 cp -al "$BASE" "$MERGED"
 cp -al --remove-destination "$KDE"/. "$MERGED"/
 
+. "$ROOT/scripts/lib/pid1-desde-store.sh"
+inyectar_pid1 "$MERGED" "$BASE"
+
 echo "==> instalando /usr/bin/plasma-start"
 install -Dm755 scripts/kde/plasma-start-metal.sh "$MERGED/usr/bin/plasma-start"
 
diff --git a/scripts/kde/qemu-desktop-image.sh b/scripts/kde/qemu-desktop-image.sh
index 7687227f..98c5dd94 100755
--- a/scripts/kde/qemu-desktop-image.sh
+++ b/scripts/kde/qemu-desktop-image.sh
@@ -34,6 +34,9 @@ rm -rf "$MERGED"
 cp -al "$BASE" "$MERGED"
 cp -al --remove-destination "$KDE"/. "$MERGED"/
 
+. "$ROOT/scripts/lib/pid1-desde-store.sh"
+inyectar_pid1 "$MERGED" "$BASE"
+
 echo "==> parcheando mesa (software GL) desde $MESA  (llvmpipe=$LLVMPIPE)"
 # el artefacto trae usr/lib/{dri/*swrast*,libEGL,libgbm,libglapi,libGLESv2}; copiamos SIN --remove para
 # no pisar sonames del metal salvo lo que falte, pero swrast_dri debe entrar sí o sí.
diff --git a/scripts/lib/pid1-desde-store.sh b/scripts/lib/pid1-desde-store.sh
new file mode 100644
index 00000000..a838a97a
--- /dev/null
+++ b/scripts/lib/pid1-desde-store.sh
@@ -0,0 +1,44 @@
+# pid1-desde-store.sh — helper compartido por los scripts de imagen: poner en el rootfs fundido el
+# arje-zero SELLADO, no el que venga arrastrado del directorio base.
+#
+# ── POR QUÉ EXISTE ──────────────────────────────────────────────────────────────────────────────
+# `work/metal-rootfs` se armó a mano en la campaña de metal y quedó CONGELADO: su `arje-zero` era del
+# 2026-06-19. Nadie lo regeneraba al re-sellar la receta, así que cada imagen de escritorio —GNOME,
+# KDE, metal, dual— arrancaba con un PID1 de hace mes y medio **sin que nada lo dijera**.
+#
+# Así se comió un fix real: el `identity mismatch` del bus del fractal estaba arreglado río arriba
+# (tawasuyu ce96cfa8d) y la VM seguía imprimiendo el mensaje viejo, porque el binario de la imagen no
+# venía de la receta. Se pasaron sesiones creyendo que era un bug nuestro por arreglar.
+#
+# El síntoma es engañoso porque el directorio base es LEGÍTIMO para todo lo demás —busybox, firmware,
+# el kernel EFI-stub, la estructura de /etc—: sólo la pieza que TAMBIÉN es receta se queda atrás, y
+# justo esa es PID1. De ahí la regla:
+#
+#   **si algo del rootfs tiene receta, la imagen lo toma del artefacto sellado, no de la copia
+#   congelada.**
+#
+# El artefacto se elige por `hammer hash` sobre la receta —el que corresponde a la receta de HOY—, no
+# por el más reciente del store: con dos artefactos del mismo paquete conviviendo, la fecha miente.
+# Mismo criterio que ya usaban los inyectores de arje-logind-compat y arje-polkit-compat.
+#
+# ABORTA si no hay artefacto. Es deliberado: seguir con el PID1 congelado es exactamente el modo de
+# falla que este helper existe para cerrar, y un aviso que no corta se lee como ruido.
+#
+# Uso:  . scripts/lib/pid1-desde-store.sh ; inyectar_pid1 "$MERGED" "$BASE"
+# Var:  AZ=<dir del store>  fuerza un artefacto concreto (diagnóstico).
+
+inyectar_pid1() {
+  local merged="$1" base="${2:-}" az
+  echo "==> PID1: arje-zero desde el store${base:+ (no desde $base)}"
+  az="${AZ:-store/$(./target/release/hammer --store store hash recipes/arje-zero.toml 2>/dev/null | tail -1 | sed 's/^b3://')-arje-zero}"
+  if [ -d "$az" ] && [ -x "$az/usr/bin/arje-zero" ]; then
+    install -Dm755 "$az"/usr/bin/arje-zero "$merged"/usr/bin/arje-zero
+    local viejo=""
+    [ -n "$base" ] && viejo=$(stat -c '%y' "$base"/usr/bin/arje-zero 2>/dev/null | cut -d' ' -f1)
+    echo "   ✓ $(basename "$az" | cut -c1-12)${viejo:+  (el de $base era de $viejo)}"
+  else
+    echo "   ✗ falta arje-zero sellado en store/ — la imagen usaría el PID1 CONGELADO${base:+ de $base}" >&2
+    echo "     construílo:  ./target/release/hammer build recipes/arje-zero.toml --store store" >&2
+    return 1
+  fi
+}