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…

poda-fuentes: miraba donde el scratch ya no está — por eso /store llegó al 100%

El disco se llenó durante la cascada de bluez5 y nueve recetas fallaron con
«No space left on device». La causa no era el volumen de la cascada: era que
el podador llevaba SEIS DÍAS sin encontrar su montón.

`FUENTES` tenía el default `work/sources`, pero el 2026-10-15 `work_root` dejó
de ser `dirname(store)/work` cuando el store es punto de montaje y pasó a ser
`<store>/.work` (config.rs, `work_root_para`). Acá eso es
`/store/.work/sources`. El podador salía con «no existe work/sources — nada
que podar» mientras al lado se acumulaban 14,9 G.

⚠ Y lo llama el CRON cada 30 minutos (cosecha-cron.sh:358). O sea que el
latido venía informando éxito mientras el disco se llenaba. **Un podador que
no encuentra su montón informa éxito**, que es la peor forma de fallar y la
misma familia que el guardián que nunca falló porque nunca miró donde debía.

Ahora deriva la ruta con la MISMA regla que el build, en orden:
  1. $FUENTES explícito
  2. $TAKANA_WORK/sources (el override que takana respeta)
  3. store es punto de montaje ⇒ <store>/.work/sources
  4. si no ⇒ dirname(store)/work/sources
El punto de montaje se detecta comparando el número de dispositivo con el del
padre —lo mismo que `store_es_punto_de_montaje`— porque `mountpoint(8)` no
está en esta caja.

Y si la ruta derivada no existe pero la vieja sí, cae a la vieja y AVISA: una
caja sin migrar se sigue podando en vez de quedarse muda.

Probado: sin pasarle nada encuentra /store/.work/sources. Apuntado a mano
liberó 5,7 G de 33 árboles (de 264 K libres a 5,7 G).

La lección que vale: **cuando una ruta se deriva en el código, los scripts que
la asumen caducan en silencio.** El arreglo del 15-oct era correcto y dejó
atrás a un podador que nadie volvió a mirar.

0f5f53259f607efa1d43a651f478b4ea2b16553c · by Sergio · (21 h ago) · parent 1951f7140 · browse the tree at this commit

Semantic delta

No definition changed: this change is text, documentation or data.

1 files · +34 −1

diff --git a/scripts/poda-fuentes.sh b/scripts/poda-fuentes.sh
index a456bd49..02cc0ea3 100755
--- a/scripts/poda-fuentes.sh
+++ b/scripts/poda-fuentes.sh
@@ -47,7 +47,40 @@
 #        (sin --aplicar es DRY-RUN: mide y no borra)
 set -uo pipefail
 ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
-FUENTES="${FUENTES:-work/sources}"
+# ── ⚠ DÓNDE ESTÁ `sources` SE DERIVA, NO SE SUPONE (arreglado 2026-10-21) ──────────────────────
+# Esto decía `FUENTES="${FUENTES:-work/sources}"` a secas, y **por eso el disco llegó al 100 %**:
+# el 2026-10-15 `work_root` dejó de ser `dirname(store)/work` cuando el store es un punto de
+# montaje, y pasó a ser `<store>/.work` (`crates/takana-build/src/config.rs`, `work_root_para`).
+# En esta caja eso son `/store/.work/sources` — y el podador seguía mirando `work/sources`, que no
+# existe. Salía «no existe work/sources — nada que podar», con 14,9 G acumulados al lado y
+# `/store` con 264 K libres. Un podador que no encuentra su montón **informa éxito**, que es la
+# peor forma de fallar.
+#
+# ⇒ Se replica la MISMA regla que el build, en este orden:
+#     1. `$FUENTES` explícito, si alguien lo pasa
+#     2. `$TAKANA_WORK/sources`, el override deliberado que takana respeta
+#     3. si el store es punto de montaje ⇒ `<store>/.work/sources`
+#     4. si no ⇒ `dirname(store)/work/sources`
+# El punto de montaje se detecta comparando el número de dispositivo con el del padre, que es lo
+# que hace `store_es_punto_de_montaje` y no necesita `mountpoint(8)` (que acá no está).
+STORE_POD="${HAMMER_STORE:-${TAKANA_STORE:-${STORE:-/store}}}"
+derivar_fuentes() {
+  [ -n "${TAKANA_WORK:-}" ] && { echo "$TAKANA_WORK/sources"; return; }
+  if [ -d "$STORE_POD" ]; then
+    d_store=$(stat -c %d "$STORE_POD" 2>/dev/null || echo x)
+    d_padre=$(stat -c %d "$(dirname "$STORE_POD")" 2>/dev/null || echo y)
+    if [ "$d_store" != "$d_padre" ]; then echo "$STORE_POD/.work/sources"; return; fi
+    echo "$(dirname "$STORE_POD")/work/sources"; return
+  fi
+  echo "work/sources"
+}
+FUENTES="${FUENTES:-$(derivar_fuentes)}"
+# Y si la ruta derivada no existe pero la VIEJA sí, se usa la vieja y se avisa: así una caja que
+# todavía no haya migrado se sigue podando en vez de quedarse muda.
+if [ ! -d "$FUENTES" ] && [ -d work/sources ]; then
+  echo "⚠ $FUENTES no existe; cayendo a work/sources (¿caja sin migrar?)" >&2
+  FUENTES=work/sources
+fi
 HORAS="${HORAS:-24}"; APLICAR=0; ESPERA="${ESPERA:-60}"
 while [ $# -gt 0 ]; do
   case "$1" in