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 1407Shell 141Markdown 84Rust 802745 Definiciones

granja: la cosecha llenaba el disco — rsync sin -H y bajando .dmerge

La bajada del store murio con "No space left on device" con 95 G libres y un
store remoto de 25 G. Dos causas que se multiplican:

- `rsync -a` NO preserva hardlinks (eso es `-H`). El store es CAS y .dmerge
  hardlinkea los artefactos, asi que los 25 G que mide `du` en el origen -que
  deduplica por inodo- se escriben en destino como copias enteras, una por enlace.
- `.dmerge` es cache pura: hammer la reconstruye sola, no aporta un artefacto y
  es la parte mas pesada del arbol (132 G en el hub, 111,7 GiB exclusivos).

Ademas el fallo a mitad deja directorios creados sin ficheros, que es un
cache-hit envenenado: `mise` se cosecho asi, como nombre vacio. Se anade un
guardian que barre los vacios al terminar la bajada y avisa de re-correr.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LykB7vw38b4Ck1Zij15RQ4

6558b7c8dea60df7b7d704dca8a0675adf4b8359 · por Sergio · (hace 1 mes) · padre 95679adb6 · ver el árbol en este commit

Delta semántico

Ninguna definición cambió: el cambio es de texto, documentación o datos.

1 archivos · +33 −2

diff --git a/scripts/farm/farm-sync.sh b/scripts/farm/farm-sync.sh
index c88ae4a0..a6ff3f1d 100755
--- a/scripts/farm/farm-sync.sh
+++ b/scripts/farm/farm-sync.sh
@@ -75,13 +75,44 @@ echo "==> 2. bajando artefactos sellados del worker"
 # son inmutables y un artefacto superado no vuelve a ser vigente salvo que una receta retroceda—
 # excluirlos es seguro; y si una receta retrocediera, su artefacto se reconstruye, que es barato.
 LEDGER="work/store-gc-superados.txt"
+# ── ⚠ `-H` Y EXCLUIR `.dmerge`: SIN ESTO LA COSECHA LLENA EL DISCO ─────────────────────────────
+# Medido el 2026-09-01: esta bajada murió con `No space left on device (28)` escribiendo
+# `store/.dmerge/b8bc5ecc…/usr/share/locale/az/LC_MESSAGES/kio6.mo`, con 95 G libres y un store
+# remoto de 25 G. Dos causas que se multiplican:
+#
+#   1. **`rsync -a` NO preserva hardlinks** (eso es `-H`, y no está incluido en `-a`). El store es
+#      CAS y `.dmerge` hardlinkea los artefactos: en el worker, 25 G medidos con `du` —que deduplica
+#      por inodo— son MUCHOS más en el cable, porque cada enlace se transfiere y se escribe como una
+#      copia entera. El tamaño que informa `du` del origen NO es el que hace falta en el destino.
+#   2. **`.dmerge` es CACHÉ PURA y no tiene por qué viajar.** Es la capa de merge que hammer
+#      reconstruye sola; copiarla no aporta un solo artefacto y es la parte más pesada del árbol
+#      (en el hub llegó a 132 G con 111,7 GiB exclusivos). Cosechar es traerse ARTEFACTOS.
+#
+# El fallo además es a mitad de camino: rsync limpia sus temporales al abortar, pero los directorios
+# que ya creó quedan — y un directorio de artefacto sin ficheros es EXACTAMENTE un cache-hit
+# envenenado (`mise` llegó así en esa pasada). Ver la regla 3 del CLAUDE.md.
+RSOPTS=(-azH --exclude '/.dmerge')
 if [ -s "$LEDGER" ]; then
   echo "    (excluyendo $(wc -l < "$LEDGER") artefactos ya podados — ver la nota del bucle de churn)"
-  rsync -az -e "$SSH" --exclude-from="$LEDGER" "$VPS:$REMOTE/store/" ./store/
+  rsync "${RSOPTS[@]}" -e "$SSH" --exclude-from="$LEDGER" "$VPS:$REMOTE/store/" ./store/
 else
-  rsync -az -e "$SSH" "$VPS:$REMOTE/store/" ./store/
+  rsync "${RSOPTS[@]}" -e "$SSH" "$VPS:$REMOTE/store/" ./store/
 fi
 
+# ── GUARDIÁN: ningún artefacto cosechado puede llegar VACÍO ────────────────────────────────────
+# Un directorio sin ficheros no es un artefacto, es un nombre — y `hammer build` lo lee como
+# presencia y sella sin construir. Barrerlos acá es barato; detectarlos tres eslabones más abajo
+# (manifiesto → grafo → build) cuesta una campaña.
+VACIOS=0
+for d in ./store/*/; do
+  case "$d" in ./store/.dmerge/) continue ;; esac
+  [ -d "$d" ] || continue
+  if [ -z "$(find "$d" -mindepth 1 -print -quit 2>/dev/null)" ]; then
+    echo "    ⚠ artefacto VACÍO cosechado, lo quito: $d"; rmdir "$d" 2>/dev/null; VACIOS=$((VACIOS+1))
+  fi
+done
+[ "$VACIOS" -gt 0 ] && echo "    ($VACIOS vacíos barridos — la bajada quedó a medias, re-corré el sync)"
+
 if [ "${2:-}" = "--no-promote" ]; then
   echo "✓ store sincronizado (sin promote)"; exit 0
 fi