diff --git a/scripts/farm/farm-worker-loop.sh b/scripts/farm/farm-worker-loop.sh index 60d5d200..27e77310 100755 --- a/scripts/farm/farm-worker-loop.sh +++ b/scripts/farm/farm-worker-loop.sh @@ -36,6 +36,9 @@ mkdir -p "$HAMMER_DIR/work" # pisa un vendor en curso, esa receta reintenta el próximo ciclo (cache-hit el resto). Sin esto, una # tanda Go grande llena el disco de 80G y el I/O-wait dispara el load (cuello real, no CPU/RAM). DISK_HIGH="${DISK_HIGH:-82}" +# Cuántos minutos se le respetan a un árbol EN FRÍO cuando el disco NO está apretado. Es la ventana +# de post-mortem: por debajo de esto, un fallo se lleva su propia evidencia (ver protección 4). +SUELO_FRIO_MIN="${SUELO_FRIO_MIN:-120}" ( while :; do sleep 180 @@ -56,7 +59,23 @@ DISK_HIGH="${DISK_HIGH:-82}" # que NO coincide con la receta en vuelo ⇒ protecciones 1 y 2 no la cubren. Sin esto, el rm -rf # compite con el tar y deja el árbol a medias ("Cannot mkdir" / luego "Directory not empty" para # siempre). Un árbol en frío (extracción ya fallida/terminada) queda purgable ⇒ se re-extrae limpio. - [ -n "$(find "$dd" -mmin -2 -print -quit 2>/dev/null)" ] && continue + # Protección 4: EL POST-MORTEM (2026-09-06). Con el suelo en 2 min, el árbol de una receta que + # ACABA DE FALLAR se barre antes de que nadie lo mire: `waterfox` murió a las 03:20:15 tras 36 + # min y 23.980 pasos, enlazando `libxul.so`, y a las 03:22 `work/sources/` estaba VACÍO. El + # objdir con la evidencia se fue con él y reproducirlo cuesta otros 36 min. + # + # El repo ya tiene la doctrina escrita en otros dos sitios y este watchdog la contradecía: + # `campana-deuda.sh` dice «NO se poda tras un ✗: el árbol de una receta que falló es el + # post-mortem», y `poda-fuentes.sh` usa un suelo de 24 h justamente para «dejar el post-mortem + # del día». + # + # No se arregla subiendo el suelo a secas: este watchdog existe para que una tanda Go no llene + # el disco vendoreando, y ahí los minutos importan. Se arregla siendo agresivo SÓLO cuando el + # recurso escasea de verdad — con disco holgado, un árbol frío no le hace daño a nadie. + usado=$(df --output=pcent "$HAMMER_DIR" 2>/dev/null | tr -dc '0-9') # pcent = USADO, no libre + suelo=$SUELO_FRIO_MIN + [ -n "$usado" ] && [ "$usado" -ge "$DISK_HIGH" ] && suelo=2 # disco apretado ⇒ como antes + [ -n "$(find "$dd" -mmin -"$suelo" -print -quit 2>/dev/null)" ] && continue rm -rf "$dd" done use=$(df --output=pcent "$HAMMER_DIR" 2>/dev/null | tr -dc '0-9')