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.
Semantic delta
No definition changed: this change is text, documentation or data.
1 files · +34 −1
- scripts/poda-fuentes.sh +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