gioser

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 815Rust 56Shell 37Markdown 291229 Sutichaykuna

tres arreglos que pidió el agente de adentro, y uno era mío

1) `publicar-webs.sh` corría como root y hacía el `git pull` igual: git dejó 24 entradas de root
dentro del .git de /work/sergio/tawasuyu —refs, logs, config, directorios de objetos— y el dueño se
quedó sin poder ni hacer `fetch` («unable to append to .git/logs/refs/remotes/origin/main»). El clon
quedó congelado 21 commits atrás sin que nada fallara del lado de root. Ahora el pull va COMO EL
DUEÑO, y los cuatro clones quedaron con sus permisos.

2) `cc-por-zig.sh` elegía el rust con `ls -d …/*-rust | tail -1`, que es el último ALFABÉTICO:
certificaba `fe277b32…` mientras la jaula usaba el vigente `6441302d…`. Dos artefactos distintos, uno
certificado y otro en uso. Ahora pregunta por el hash vigente de la receta y sólo cae al más reciente
—con el nombre exacto— si no puede. Lo detectó el agente comparando los dos guiones.

3) `rustdoc` entra en `tools`: el artefacto salía con cargo y rustc y SIN rustdoc, o sea que en una
caja takana `cargo doc` no existe. `docs = false` se queda —la documentación de la std es otra
decisión, cientos de MB—. Radio medido: 0 dependientes de build.

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

2f9253886ff843d9701ac61a9c3ff4f2cd43ef33 · ruwaq Sergio · (1 killa ñawpaq) · tayta 67f601305 · kay commitpi sach'ata qhaway

Semántico sayk'uy

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

3 qillqakuna · +30 −3

diff --git a/recipes/rust.toml b/recipes/rust.toml
index 664a78ea..b11a8a1b 100644
--- a/recipes/rust.toml
+++ b/recipes/rust.toml
@@ -96,7 +96,16 @@ change-id = "ignore"
 build = "x86_64-alpine-linux-musl"
 docs = false
 extended = true
-tools = ["cargo"]
+# ⚠ `rustdoc` ENTRA (2026-09-18). Antes iba sólo `cargo`, y el artefacto salía con
+# `cargo rustc rust-gdb rust-gdbgui rust-lldb` y **sin rustdoc**: o sea que en una caja takana
+# `cargo doc` no existe. Para una distro que ENVÍA un toolchain de Rust es un hueco de la misma
+# familia que las proc-macros que no enlazaban: todo presente, y una cosa que la gente hace a
+# diario, imposible. Lo levantó el agente que trabaja enjaulado.
+# `docs = false` se QUEDA: eso construye la documentación de la `std` —cientos de MB y mucho rato— y
+# es otra decisión. Esto agrega sólo la HERRAMIENTA, para documentar el código de uno.
+# Radio medido antes de tocar: `yupana radio rust` da 0 dependientes de build; toca la imagen
+# `servidor`, que es re-ensamblar, no reconstruir.
+tools = ["cargo", "rustdoc"]
 local-rebuild = true
 # Hay que NOMBRAR el stage0 aunque ya esté en el PATH: sin estas dos líneas, x.py se salta el
 # compilador local y va a DESCARGAR el toolchain de `static.rust-lang.org` — que en un sandbox sin
diff --git a/scripts/servidor/cc-por-zig.sh b/scripts/servidor/cc-por-zig.sh
index cccf0900..391ef101 100755
--- a/scripts/servidor/cc-por-zig.sh
+++ b/scripts/servidor/cc-por-zig.sh
@@ -97,7 +97,18 @@ cc --target=x86_64-unknown-linux-musl -o "$T/h2" "$T/h.c" 2>"$T/errcc" || {
 "$T/h2" >/dev/null || { echo "✗ compiló con el triple de cc-rs y no corre" >&2; exit 1; }
 echo "  ✓ C: con el --target= de cc-rs"
 
-R=$(ls -d "$STORE"/*-rust 2>/dev/null | tail -1)
+# ⚠ EL RUST QUE SE CERTIFICA TIENE QUE SER EL VIGENTE (2026-09-18). Esto decía
+# `ls -d …/*-rust | tail -1`, que es el ÚLTIMO ALFABÉTICO: elegía `fe277b32…` mientras el vigente
+# —y el que usa la jaula— es `6441302d…`. La caja certificaba un rust y el agente usaba otro; lo
+# detectó el agente de adentro comparando los dos guiones.
+# Se pregunta por el hash vigente de la receta; si no se puede, se cae al más RECIENTE con el
+# nombre EXACTO — `*-rust` también casa con `…-rust-toolchain-bin`.
+R=""
+if [ -x ./target/release/takana ] && [ -f recipes/rust.toml ]; then
+  h=$(./target/release/takana --store "$STORE" hash recipes/rust.toml 2>/dev/null | grep -o "b3:[0-9a-f]*" | head -1)
+  [ -n "$h" ] && [ -d "$STORE/${h#b3:}-rust" ] && R="$STORE/${h#b3:}-rust"
+fi
+[ -n "$R" ] || R=$(ls -dt "$STORE"/*-rust 2>/dev/null | while read -r d; do nn=${d##*/}; [ "${nn#*-}" = "rust" ] && { echo "$d"; break; }; done)
 if [ -n "$R" ] && [ -x "$R/usr/bin/rustc" ]; then
   printf 'extern crate proc_macro;\nuse proc_macro::TokenStream;\n#[proc_macro]\npub fn m(_i: TokenStream) -> TokenStream { "fn v() -> u32 { 42 }".parse().unwrap() }\n' > "$T/pm.rs"
   # shellcheck disable=SC2086
diff --git a/scripts/servidor/publicar-webs.sh b/scripts/servidor/publicar-webs.sh
index efde0607..5ddc7ada 100755
--- a/scripts/servidor/publicar-webs.sh
+++ b/scripts/servidor/publicar-webs.sh
@@ -31,7 +31,14 @@ tirar() {  # $1 = clon
   # ⚠ Sólo avance rápido: si alguien dejó cambios locales en el clon que sirve la web, esto NO los
   # pisa — se queja y sigue. Un `git pull` que rebasa sobre un árbol servido es cómo se rompe un
   # sitio en producción sin enterarse.
-  if git -C "$1" pull -q --ff-only 2>/dev/null; then
+  # ⚠ COMO EL DUEÑO, NO COMO ROOT (2026-09-18). Este guion corre como root y hacía el `pull` igual:
+  # git dejó 24 entradas de root dentro del `.git` de /work/sergio/tawasuyu —refs, logs, config,
+  # directorios de objetos— y el dueño se quedó sin poder ni hacer `fetch`: «unable to append to
+  # .git/logs/refs/remotes/origin/main». El clon quedó congelado 21 commits atrás sin que nada
+  # fallara del lado de root. Lo reportó el agente que trabaja ahí.
+  duenio=$(stat -c %U "$1" 2>/dev/null || echo root)
+  if [ "$duenio" != "root" ] && [ "$(id -u)" = "0" ]; then tira="su $duenio -s /bin/sh -c"; else tira="sh -c"; fi
+  if $tira "git -C '$1' pull -q --ff-only" 2>/dev/null; then
     ahora=$(git -C "$1" rev-parse --short HEAD)
     [ "$antes" = "$ahora" ] && echo "  = $1 ya estaba al día ($ahora)" || echo "  ↑ $1 $antes → $ahora"
   else