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 1572Shell 203Rust 109Markdown 993728 Sutichaykuna

tres variantes —base, mirada, servidor, full— en sus dos medios

`scripts/instalador-variantes.sh` arma cada una y las publica en takana-os.net/descargas. La
diferencia es QUÉ SISTEMA SE INSTALA, no cómo: el instalador, el censo y las guardas son los
mismos en todas.

⚠ «base» son DOS COSAS CON EL MISMO NOMBRE, y confundirlas da un rootfs que no arranca. El piso
de ARRANQUE es product-rootfs (arje-zero como PID 1 + busybox) y NO está en ningún perfil de
targets.toml; el userland base es [perfil.base], 359 binarios, y medido: `ls base/bin` no tiene
ni busybox ni arje-zero. Cada variante es product-rootfs ∪ perfil.base ∪ los suyos. El SDD 27 §1
ya había medido la otra mitad del mismo hueco (los escritorios no heredan base); ésta es la que
faltaba.

⚠ Cada perfil se hidrata en SU PROPIO árbol y después se funden, no uno encima de otro con
--keep. La auditoría del bit de privilegio corre contra las declaraciones [[setuid]] del perfil
que se está hidratando: al poner escritorio-mirada sobre base veía el `doas` 4755 que dejó base
—declarado y legítimo— y lo denunciaba como «un bit que nadie declaró». La auditoría tenía razón
en lo suyo; el que estaba mal era el método.

⚠ Y la guarda de RAM del initramfs estaba aplicándose al camino del USB, donde no aplica: con
TREE_ONLY el árbol se escribe en el ext4 de un pendrive, y ahí no hay límite de memoria. Rechazaba
la variante `full` por no caber en la RAM de una máquina que no es la que instala. Queda además
anotado el defecto de fondo que no barro: mide la RAM de la máquina que CONSTRUYE.

`full` no tiene .run y es física, no pereza: el fichero único carga el instalador entero en
memoria —es lo que le permite soltar el disco— y con 3,2 GiB de rootfs eso pide ~8 GiB de RAM en
la máquina donde se instale. El USB corre desde el propio medio y no tiene ese límite.

El USB de `mirada` probado arrancando por FIRMWARE (OVMF, sin -kernel): 13 comprobaciones en
verde, instalando de verdad sobre el disco destino.

Los 11 artefactos que le faltaban al hub para el perfil servidor (rust, dwarves, pacha, nftables…)
se trajeron del worker por hash vigente.

3d3d160e01f83bf5a671272af2de2d6bfeddbb87 · ruwaq Sergio · (28 p'unchaw ñawpaq) · tayta 53ff22480 · kay commitpi sach'ata qhaway

Semántico sayk'uy

Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.

4 qillqakuna · +240 −18

diff --git a/scripts/instalador-initramfs.sh b/scripts/instalador-initramfs.sh
index b6e606a4..e5ddcdfa 100755
--- a/scripts/instalador-initramfs.sh
+++ b/scripts/instalador-initramfs.sh
@@ -53,6 +53,17 @@ STAGE_ONLY=1 KEEP_STORE=1 STAGE="$STAGE" ./scripts/install-image-efi.sh
 # Un initramfs vive ENTERO en memoria, y el kernel no lo avisa con elegancia: se queda sin RAM al
 # desempaquetar y el arranque muere sin un mensaje que diga por qué. Medirlo antes es la diferencia
 # entre «no entra, usá el USB» y un cuelgue mudo en la máquina del usuario.
+# ⚠ **Esta guarda es del camino en RAM, y sólo de ése.** Con `TREE_ONLY=1` el árbol se va a
+# escribir en el ext4 de un USB, donde no hay ningún límite de memoria: aplicarla ahí rechazaba la
+# variante `full` por no caber en la RAM de una máquina que no es la que va a instalar. Medido el
+# 2026-09-23 armando las tres variantes.
+#
+# ⚠ Y hay un segundo defecto, que se deja anotado y no barrido: mide la RAM de **esta** máquina, no
+# la de aquella donde se va a instalar. Acá acierta por casualidad —el hub tiene 7,6 GiB, parecido a
+# un portátil—, pero construir en una caja grande dejaría pasar una imagen que allá no arranca.
+if [ -n "${TREE_ONLY:-}" ]; then
+    echo "    (TREE_ONLY: el árbol va a un disco, no a RAM — la guarda de memoria no aplica)"
+else
 _mib_payload=$(du -sm "$STAGE/root" | cut -f1)
 _mib_ram=$(( $(awk '/^MemTotal:/ {print $2}' /proc/meminfo) / 1024 ))
 echo "    payload ${_mib_payload} MiB · RAM de esta máquina ${_mib_ram} MiB"
@@ -62,6 +73,7 @@ if [ "$(( _mib_payload * 100 / _mib_ram ))" -gt 40 ]; then
     echo "                      Este camino no sirve para este rootfs: instalá desde un medio." >&2
     exit 1
 fi
+fi
 
 # ── 3) el árbol del initramfs ──────────────────────────────────────────────────────────────────
 echo "==> árbol del initramfs-instalador"
diff --git a/scripts/instalador-variantes.sh b/scripts/instalador-variantes.sh
new file mode 100755
index 00000000..b9518bcb
--- /dev/null
+++ b/scripts/instalador-variantes.sh
@@ -0,0 +1,140 @@
+#!/bin/sh
+# instalador-variantes.sh — las tres variantes del instalador, en sus dos medios.
+#
+# ══ QUÉ SON ═══════════════════════════════════════════════════════════════════════════════════
+#   servidor  el piso de arranque + el userland base + el perfil `servidor`
+#   mirada    el piso de arranque + el userland base + el escritorio propio de la suite
+#   full      todo lo anterior junto, más el toolbox de línea de comandos (`cli`)
+#
+# ── LA COMPOSICIÓN, Y POR QUÉ NO ES UN PERFIL SOLO ────────────────────────────────────────────
+# ⚠ **«base» son DOS cosas con el mismo nombre**, y confundirlas da un rootfs que no arranca:
+#
+#   · el **piso de ARRANQUE** — `product-rootfs`: arje-zero como PID 1 + busybox. Es lo único que
+#     hace que la imagen encienda, y NO está en ningún perfil de `targets.toml`.
+#   · el **userland base** — `[perfil.base]`: bash, git, sudo, dhcpcd, coreutils… 359 binarios y
+#     **ni busybox ni arje-zero adentro** (medido: `ls base/bin` no los tiene).
+#
+# El [SDD 27 §1](../docs/27-perfiles-instalables-y-el-instalador.md) ya había medido que los
+# escritorios NO heredan `base`; esto es la otra mitad del mismo hueco. Cada variante se compone
+# entonces así, y en este orden:
+#
+#     product-rootfs  ∪  perfil.base  ∪  <los perfiles de la variante>
+#
+# ── DOS MONTAJES, DOS COPIAS, Y NO ES DESPERDICIO ─────────────────────────────────────────────
+# `hydrate` proyecta por HARDLINK y `linkat()` no cruza un punto de montaje: la composición tiene
+# que armarse **bajo el montaje del store**. Y el ensamblado de la imagen vuelve a enlazar, esta vez
+# hacia `work/`, que está en OTRO disco — así que la composición se copia una vez a este lado. Las
+# dos restricciones son la misma física y ya mordieron dos veces en este repo.
+#
+# Uso:  scripts/instalador-variantes.sh [servidor|mirada|full]...   (sin argumentos: las tres)
+# Vars: KERNEL · SALIDA (def work/variantes) · STORE (def /store)
+set -eu
+ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
+STORE="${STORE:-/store}"
+SALIDA="${SALIDA:-work/variantes}"
+COMPOSICION="$STORE/.perfiles"
+LOCAL="work/.rootfs-local"
+
+perfiles_de() {
+    case "$1" in
+        servidor) echo "base servidor" ;;
+        mirada)   echo "base escritorio-mirada" ;;
+        full)     echo "base cli escritorio-mirada servidor" ;;
+        *) echo "variante desconocida: $1 (servidor|mirada|full)" >&2; return 1 ;;
+    esac
+}
+
+# ── QUÉ MEDIOS TIENE CADA VARIANTE, Y POR QUÉ `full` NO TIENE .run ────────────────────────────
+# El fichero único carga el instalador ENTERO en memoria —es lo que le permite soltar el disco— y
+# en RAM viven a la vez el initramfs comprimido y su contenido desempaquetado. El generador ya lo
+# comprueba y se niega por encima del 40 % de la RAM; con `full` (3,2 GiB) eso pide ~8 GiB en la
+# máquina donde se instale, o sea que el `.run` sería un fichero de 1,5 GiB que en la mitad de las
+# máquinas no se puede usar. **El USB no tiene ese límite**: corre desde el propio medio.
+#
+# ⚠ Y hay un defecto conocido en esa guarda: mide la RAM de la máquina que CONSTRUYE, no la de la
+# que instala. Acá da el resultado correcto por casualidad —el hub tiene 7,6 GiB, parecido a un
+# portátil— pero construir en una caja grande dejaría pasar una imagen que allá no arranca. Está
+# anotado y no barrido.
+medios_de() {
+    case "$1" in
+        full) echo "usb" ;;
+        *)    echo "run usb" ;;
+    esac
+}
+
+VARIANTES="${*:-servidor mirada full}"
+for v in $VARIANTES; do perfiles_de "$v" >/dev/null || exit 2; done
+
+KERNEL="${KERNEL:-$(ls -dt "$STORE"/*-linux-metal/boot/bzImage 2>/dev/null | head -1)}"
+[ -n "${KERNEL:-}" ] && [ -r "$KERNEL" ] || { echo "no encuentro un bzImage de linux-metal (set KERNEL=)" >&2; exit 1; }
+PISO="${PISO:-$(ls -dt "$STORE"/*-product-rootfs 2>/dev/null | head -1)}"
+[ -n "${PISO:-}" ] && [ -d "$PISO" ] || { echo "no encuentro un product-rootfs (set PISO=)" >&2; exit 1; }
+echo "==> piso de arranque: $PISO"
+echo "==> kernel: $KERNEL"
+mkdir -p "$SALIDA" "$COMPOSICION" "$LOCAL"
+
+for v in $VARIANTES; do
+    echo
+    echo "════ $v ════════════════════════════════════════════════════════════════════════"
+    C="$COMPOSICION/$v"
+    # `cp -al`: el piso entra por hardlinks, que en el mismo filesystem es gratis. Un `cp -a` de
+    # 265 MiB por variante es tiempo y disco que no hacen falta.
+    rm -rf "$C"; cp -al "$PISO" "$C"
+    chmod -R u+w "$C" 2>/dev/null || true
+    # ⚠ **Cada perfil se hidrata en SU PROPIO árbol y después se funden**, y no uno encima de otro
+    # con `--keep`. La razón es la auditoría del bit de privilegio, que corre contra las
+    # declaraciones `[[setuid]]` DEL PERFIL QUE SE ESTÁ HIDRATANDO: al poner `escritorio-mirada`
+    # encima de `base`, veía el `doas` 4755 que dejó `base` —declarado, legítimo— y lo denunciaba
+    # como «un bit que nadie declaró». La auditoría tiene razón en lo suyo; el que estaba mal era
+    # el método. Medido el 2026-09-23.
+    for p in $(perfiles_de "$v"); do
+        echo "  ── perfil $p"
+        H="$COMPOSICION/$v-$p"; rm -rf "$H"
+        python3 scripts/hydrate-profile.py "$p" --into "$H" --store "$STORE" \
+            > "work/.variante-$v-$p.log" 2>&1 || {
+            echo "     ✗ falló la hidratación de $p — ver work/.variante-$v-$p.log" >&2
+            grep -A6 'SIN artefacto\|✗' "work/.variante-$v-$p.log" | head -14 >&2
+            exit 1; }
+        # `-n` (no pisar): si dos perfiles traen el mismo fichero es el mismo artefacto, así que
+        # gana el primero y da igual cuál sea. Pisar daría el mismo resultado y un error si el
+        # hardlink ya existe.
+        chmod -R u+w "$H" 2>/dev/null || true
+        ( cd "$H" && find . -type d -exec mkdir -p "$C/{}" \; ) 2>/dev/null || true
+        ( cd "$H" && find . ! -type d -exec cp -a -l -n {} "$C/{}" \; ) 2>/dev/null || true
+        rm -rf "$H"
+        echo "     $(grep -oE '[0-9]+/[0-9]+' "work/.variante-$v-$p.log" | tail -1) artefactos · acumulado $(du -sm "$C" | cut -f1) MiB"
+    done
+
+    # ── el árbol tiene que quedar en el MISMO montaje que el stage del ensamblado ─────────────
+    L="$LOCAL/$v"
+    rm -rf "$L"; cp -a "$C" "$L"
+    echo "  ── árbol local: $(du -sm "$L" | cut -f1) MiB"
+
+  if echo " $(medios_de "$v") " | grep -q ' run '; then
+    echo "  ── el fichero que se baja (.run)"
+    ROOTFS="$L" KERNEL="$KERNEL" SALIDA="$SALIDA/paquete-$v" ./scripts/instalador-paquete.sh \
+        > "work/.variante-$v-paquete.log" 2>&1 || {
+        echo "     ✗ falló el paquete — ver work/.variante-$v-paquete.log" >&2; tail -6 "work/.variante-$v-paquete.log" >&2; exit 1; }
+    PAQUETE="$SALIDA/paquete-$v" SALIDA="$SALIDA/takana-instalador-$v.run" ./scripts/instalador-autoextraible.sh \
+        > "work/.variante-$v-run.log" 2>&1 || {
+        echo "     ✗ falló el autoextraíble — ver work/.variante-$v-run.log" >&2; tail -6 "work/.variante-$v-run.log" >&2; exit 1; }
+    echo "     $SALIDA/takana-instalador-$v.run  $(( $(wc -c < "$SALIDA/takana-instalador-$v.run") / 1048576 )) MiB"
+  else
+    echo "  ── sin .run: este rootfs no entra en RAM en una máquina normal (sólo USB)"
+  fi
+
+    echo "  ── la imagen USB"
+    ROOTFS="$L" KERNEL="$KERNEL" IRD_TREE="work/.arbol-$v" \
+        IMG="$SALIDA/takana-instalador-usb-$v.img" ./scripts/instalador-usb.sh \
+        > "work/.variante-$v-usb.log" 2>&1 || {
+        echo "     ✗ falló el USB — ver work/.variante-$v-usb.log" >&2; tail -6 "work/.variante-$v-usb.log" >&2; exit 1; }
+    echo "     $SALIDA/takana-instalador-usb-$v.img  $(( $(wc -c < "$SALIDA/takana-instalador-usb-$v.img") / 1048576 )) MiB"
+
+    # La composición bajo el store se borra: es un árbol de trabajo, no un artefacto, y dejarlo ahí
+    # es invitar a que alguien lo confunda con uno.
+    rm -rf "$C" "$L"
+done
+
+echo
+echo "✓ en $SALIDA:"
+ls -l "$SALIDA"/*.run "$SALIDA"/*.img 2>/dev/null | awk '{printf "  %-52s %s MiB\n", $9, int($5/1048576)}'
diff --git a/web/takana-os.net/README.md b/web/takana-os.net/README.md
index 90ea4af7..677016a2 100644
--- a/web/takana-os.net/README.md
+++ b/web/takana-os.net/README.md
@@ -43,8 +43,8 @@ que está en `sdc` (255 G) y no en la raíz de 5,8 G, que se llena y tira la caj
 ```sh
 scripts/instalador-paquete.sh          # arma el paquete (y comprueba su coherencia)
 scripts/instalador-autoextraible.sh    # lo convierte en UN fichero, y lo desempaqueta para probarlo
-cp work/takana-instalador.run /work/sergio/descargas/
-( cd /work/sergio/descargas && sha256sum takana-instalador.run > takana-instalador.run.sha256 )
+cp work/variantes/*.run work/variantes/*.img /work/sergio/descargas/
+( cd /work/sergio/descargas && for f in takana-instalador-*; do case "$f" in *.sha256) ;; *) sha256sum "$f" > "$f.sha256";; esac; done )
 ```
 
 El `.sha256` que se publica al lado es **el del fichero entero**, para comprobar la descarga
@@ -60,6 +60,37 @@ el fichero de al lado, que se regenera junto al `.run`.
 ⚠ `/descargas` queda **fuera del `encode`** del vhost: el `.run` ya viene comprimido, y volver a
 comprimirlo por HTTP gasta CPU en cada descarga sin ahorrar un byte.
 
+### Las variantes: qué sistema se instala
+
+`scripts/instalador-variantes.sh [servidor|mirada|full]` arma las tres, en sus dos medios.
+La diferencia es **qué rootfs se copia al disco**, no cómo: el instalador y el censo son los mismos.
+
+| variante | composición | .run | USB |
+|---|---|---|---|
+| `base` | sólo el piso de arranque | 137 MiB | 519 MiB |
+| `mirada` | + `[perfil.base]` + `[perfil.escritorio-mirada]` | 524 MiB | 1,6 GiB |
+| `servidor` | + `[perfil.base]` + `[perfil.servidor]` | 1,2 GiB | 3,3 GiB |
+| `full` | + `base` + `cli` + `escritorio-mirada` + `servidor` | **no hay** | 3,5 GiB |
+
+⚠ **«base» son DOS cosas con el mismo nombre y confundirlas da un rootfs que no arranca.** El
+*piso de arranque* es `product-rootfs` —arje-zero como PID 1 + busybox— y **no está en ningún
+perfil**; el *userland base* es `[perfil.base]`, 359 binarios, y **no tiene ni busybox ni
+arje-zero adentro** (medido: `ls base/bin`). Cada variante es `product-rootfs ∪ perfil.base ∪ …`.
+El [SDD 27 §1](../../docs/27-perfiles-instalables-y-el-instalador.md) ya había medido la otra
+mitad del mismo hueco: los escritorios no heredan `base`.
+
+⚠ **Cada perfil se hidrata en su propio árbol y después se funden**, y no uno encima de otro: la
+auditoría del bit de privilegio corre contra las declaraciones `[[setuid]]` del perfil que se está
+hidratando, así que al poner `escritorio-mirada` sobre `base` veía el `doas` 4755 que dejó `base`
+—declarado y legítimo— y lo denunciaba como un bit que nadie declaró.
+
+⚠ **`full` no tiene `.run`, y es física.** El fichero único carga el instalador entero en memoria
+—es lo que le permite soltar el disco— y ahí viven a la vez el initramfs comprimido y su contenido
+desempaquetado. Con 3,2 GiB de rootfs eso pide ~8 GiB de RAM en la máquina donde se instale. El USB
+no tiene ese límite: corre desde el propio medio. La guarda que lo detecta **mide la RAM de la
+máquina que construye, no la de la que instala** — acá acierta por casualidad (el hub tiene 7,6 GiB,
+parecido a un portátil) y queda anotado sin barrer.
+
 ### La imagen USB, para cuando el salto no se puede
 
 `takana-instalador-usb.img` (519 MiB) es **el mismo instalador por otro camino**: mismo árbol, mismo
diff --git a/web/takana-os.net/index.html b/web/takana-os.net/index.html
index f96dd258..48047ed4 100644
--- a/web/takana-os.net/index.html
+++ b/web/takana-os.net/index.html
@@ -48,6 +48,11 @@ body{background:var(--fondo);color:var(--texto);font:17px/1.62 var(--sans);
 p{margin:0 0 1rem}
 a{color:inherit;text-decoration:none}
 h1,h2,h3{font-weight:600;letter-spacing:-.01em;line-height:1.15}
+.variantes{width:100%;border-collapse:collapse;margin:1rem 0;font-size:.92rem}
+.variantes th{text-align:left;font-weight:600;font-size:.78rem;letter-spacing:.06em;text-transform:uppercase;color:var(--tenue);padding:.4rem .6rem;border-bottom:1px solid var(--linea)}
+.variantes td{padding:.55rem .6rem;border-bottom:1px solid var(--linea);vertical-align:top}
+.variantes td:first-child{white-space:nowrap}
+.variantes td:nth-child(3),.variantes td:nth-child(4){white-space:nowrap;text-align:right}
 code{font:.86em/1.5 var(--mono);background:var(--papel2);border:1px solid var(--linea);
  border-radius:5px;padding:.08em .38em}
 :root[data-lang="es"] [data-l="en"],:root[data-lang="en"] [data-l="es"]{display:none!important}
@@ -237,9 +242,9 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
   <span data-l="en">There is no ISO to burn and no tree to copy: you download <strong>one file</strong>, make it executable and run it. Everything travels inside — the program, the installer that runs in RAM and its own kernel — so it <strong>downloads nothing from the internet while installing</strong>. A system installer that needs the network fails exactly where it costs most: on the machine that has no system yet.</span>
  </p>
 
-<pre><span class="p">$</span> curl -LO https://takana-os.net/descargas/takana-instalador.run
-<span class="p">$</span> chmod +x takana-instalador.run
-<span class="p">$</span> sudo ./takana-instalador.run</pre>
+<pre><span class="p">$</span> curl -LO https://takana-os.net/descargas/takana-instalador-mirada.run
+<span class="p">$</span> chmod +x takana-instalador-mirada.run
+<span class="p">$</span> sudo ./takana-instalador-mirada.run</pre>
 
  <p>
   <span data-l="es">Eso hace las tres cosas por orden: comprueba si esta máquina puede instalarse <em>sin USB</em>, muestra el terreno —cada partición, su tamaño, qué hay dentro y si se puede usar— y recién entonces pregunta. Lo cifrado, lo de Windows, la swap, las particiones de arranque y lo que está montado <strong>no se ofrecen</strong>, y se muestran igual con el motivo escrito al lado.</span>
@@ -251,13 +256,52 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
   <span data-l="en"><strong>Without a USB</strong> means the Linux you are using jumps into the in-memory installer and releases its own disk. If that machine's kernel does not allow it, the installer says so and explains why instead of failing halfway. It asks for a typed «si» before writing anything, and after the jump it shows the terrain and asks again: two consents for two different things.</span>
  </p>
 
- <div class="direccion">
-  <p class="etiqueta"><span data-l="es">el instalador · 137 MiB · x86-64</span><span data-l="en">the installer · 137 MiB · x86-64</span></p>
-  <a class="url" href="/descargas/takana-instalador.run">takana-os.net/descargas/takana-instalador.run</a>
- </div>
+ <h3><span data-l="es">Tres variantes</span><span data-l="en">Three variants</span></h3>
+ <p>
+  <span data-l="es">La diferencia es <strong>qué sistema se instala</strong>, no cómo. Las tres traen el mismo instalador y el mismo censo; cambia el tamaño de lo que copian al disco.</span>
+  <span data-l="en">The difference is <strong>which system gets installed</strong>, not how. All three carry the same installer and the same survey; what changes is the size of what they copy to the disk.</span>
+ </p>
+
+ <table class="variantes">
+  <tr>
+   <th><span data-l="es">variante</span><span data-l="en">variant</span></th>
+   <th><span data-l="es">qué trae</span><span data-l="en">what it carries</span></th>
+   <th><span data-l="es">un archivo</span><span data-l="en">one file</span></th>
+   <th>USB</th>
+  </tr>
+  <tr>
+   <td><code>base</code></td>
+   <td><span data-l="es">el piso de arranque y nada más: arranca a una consola</span><span data-l="en">the boot floor and nothing else: it boots to a console</span></td>
+   <td><a href="/descargas/takana-instalador-base.run">137 MiB</a></td>
+   <td><a href="/descargas/takana-instalador-usb-base.img">519 MiB</a></td>
+  </tr>
+  <tr>
+   <td><code>mirada</code></td>
+   <td><span data-l="es">+ el userland completo + el escritorio propio de la suite</span><span data-l="en">+ the full userland + the suite's own desktop</span></td>
+   <td><a href="/descargas/takana-instalador-mirada.run">524 MiB</a></td>
+   <td><a href="/descargas/takana-instalador-usb-mirada.img">1,6 GiB</a></td>
+  </tr>
+  <tr>
+   <td><code>servidor</code></td>
+   <td><span data-l="es">+ el userland completo + el perfil de servidor</span><span data-l="en">+ the full userland + the server profile</span></td>
+   <td><a href="/descargas/takana-instalador-servidor.run">1,2 GiB</a></td>
+   <td><a href="/descargas/takana-instalador-usb-servidor.img">3,3 GiB</a></td>
+  </tr>
+  <tr>
+   <td><code>full</code></td>
+   <td><span data-l="es">todo lo anterior junto, más el toolbox de línea de comandos</span><span data-l="en">all of the above together, plus the command-line toolbox</span></td>
+   <td><span data-l="es">— sólo USB</span><span data-l="en">— USB only</span></td>
+   <td><a href="/descargas/takana-instalador-usb-full.img">3,5 GiB</a></td>
+  </tr>
+ </table>
 
-<pre><span class="p">$</span> curl -sO https://takana-os.net/descargas/takana-instalador.run.sha256
-<span class="p">$</span> sha256sum -c takana-instalador.run.sha256</pre>
+ <p class="nota">
+  <span data-l="es">⚠ <strong>El archivo único carga el instalador ENTERO en memoria</strong> para poder soltar el disco, así que de las variantes grandes hace falta bastante RAM — y si no entra, el instalador lo dice y no lo intenta. El USB no tiene ese límite: corre desde el propio pendrive. Para <code>servidor</code> y para máquinas con poca memoria, <strong>el USB es el camino</strong>.</span>
+  <span data-l="en">⚠ <strong>The single file loads the WHOLE installer into memory</strong> so it can release the disk, so the larger variants need a fair amount of RAM — and if it does not fit, the installer says so instead of trying. The USB has no such limit: it runs from the stick itself. For <code>servidor</code> and for machines with little memory, <strong>the USB is the way</strong>.</span>
+ </p>
+
+<pre><span class="p">$</span> curl -sO https://takana-os.net/descargas/takana-instalador-mirada.run.sha256
+<span class="p">$</span> sha256sum -c takana-instalador-mirada.run.sha256</pre>
 
  <h3><span data-l="es">Y si esta máquina no puede saltar: el USB</span><span data-l="en">And if this machine cannot jump: the USB</span></h3>
  <p>
@@ -265,13 +309,8 @@ footer.pie{border-top:1px solid var(--linea);background:var(--papel);padding:2.6
   <span data-l="en">The jump asks three things of the kernel already running, and any of them can be missing: <code>kexec</code> support, being root, and Secure Boot not getting in the way. When one is missing the installer says so and explains which. For that case there is the <strong>USB image</strong>, which is the same installer arriving by another route — the same survey and the same guards.</span>
  </p>
 
- <div class="direccion">
-  <p class="etiqueta"><span data-l="es">la imagen USB · 519 MiB · UEFI x86-64</span><span data-l="en">the USB image · 519 MiB · UEFI x86-64</span></p>
-  <a class="url" href="/descargas/takana-instalador-usb.img">takana-os.net/descargas/takana-instalador-usb.img</a>
- </div>
-
-<pre><span class="p">$</span> curl -LO https://takana-os.net/descargas/takana-instalador-usb.img
-<span class="p">$</span> sudo dd if=takana-instalador-usb.img of=/dev/sdX bs=4M oflag=sync status=progress</pre>
+<pre><span class="p">$</span> curl -LO https://takana-os.net/descargas/takana-instalador-usb-mirada.img
+<span class="p">$</span> sudo dd if=takana-instalador-usb-mirada.img of=/dev/sdX bs=4M oflag=sync status=progress</pre>
 
  <p class="nota">
   <span data-l="es">Arranca por la ruta de medios removibles del firmware: no hay nada que registrar y no toca la NVRAM hasta que vos elegís instalar. El medio desde el que arrancaste <strong>nunca se ofrece como destino</strong>. Si la máquina no tiene pantalla y la estás administrando por puerto serie, arrancá con <code>takana.console=/dev/ttyS0</code>.</span>