corpus: SHARD=i/N para repartir la reconstruccion entre workers
Con un worker el corpus son ~7 dias (medido: ~9 min/receta sobre 1161). Repartirlo es la unica forma de bajarlo, y no hace falta planificador central: cada worker construye SU parte y las deps que le falten se las construye `hammer build` solo. Al cosechar todo converge en el mismo store porque las direcciones coinciden — eso lo PRUEBA el paso 4 de farm-lab-sync.sh, no se supone. El reparto es por INDICE (i-1, i-1+N, ...) y no por bloques contiguos: el orden ya esta por objetivo, asi que bloques contiguos le darian a un worker todo el tramo GUI —el mas lento— y a otro solo hojas rapidas. Intercalando, todos avanzan por el mismo terreno a la vez. ⚠ Hay trabajo DUPLICADO y es deliberado: dos workers con recetas que cuelgan de qtbase lo construyen los dos. Sale a cuenta frente a serializar, pero con 4 workers no son 4x, son ~3x. Un log por shard, o se pisan. Verificado: los 4 shards suman 1161 exactas y rechaza 5/4 y `abc`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
1 archivos · +28 −0
diff --git a/scripts/reconstruir-corpus.sh b/scripts/reconstruir-corpus.sh
index 9622f9cf..eaa2ae48 100755
--- a/scripts/reconstruir-corpus.sh
+++ b/scripts/reconstruir-corpus.sh
@@ -96,6 +96,34 @@ with open(sys.argv[1], "w") as fh:
print(f" orden: {len(pri)} de perfil primero, {len(resto)} de catálogo después")
PY
mapfile -t RECETAS < "$ORDEN"
+
+# ── PARTICIÓN ENTRE WORKERS: SHARD=i/N ──────────────────────────────────────────────────────────
+# Con un worker el corpus son ~7 días (medido: ~9 min/receta sobre 1161). Repartirlo es la única
+# forma de bajarlo, y no hace falta planificador central: cada worker construye SU parte y las deps
+# que le falten se las construye `hammer build` solo. Al cosechar, todo converge en el mismo store
+# porque las direcciones coinciden — eso está PROBADO por el paso 4 de `farm-lab-sync.sh`, no
+# supuesto.
+#
+# El reparto es por ÍNDICE (i-1, i-1+N, i-1+2N…), no por bloques contiguos: el orden ya está por
+# objetivo, así que bloques contiguos le darían a un worker todo el tramo GUI —el más lento— y a
+# otro sólo hojas rápidas. Intercalando, los cuatro avanzan por el mismo terreno a la vez.
+#
+# ⚠ HAY TRABAJO DUPLICADO y es deliberado: si a dos workers les tocan recetas que cuelgan de
+# `qtbase`, los dos lo construyen. Sale a cuenta igual frente a serializar, pero no esperes
+# aceleración lineal — con 4 workers no son 4×, son ~3×.
+if [ -n "${SHARD:-}" ]; then
+ SH_I="${SHARD%%/*}"; SH_N="${SHARD##*/}"
+ case "$SH_I$SH_N" in *[!0-9]*|"") echo "SHARD debe ser i/N (ej. 2/4)" >&2; exit 1;; esac
+ [ "$SH_I" -ge 1 ] && [ "$SH_I" -le "$SH_N" ] || { echo "SHARD fuera de rango: $SHARD" >&2; exit 1; }
+ SUB=(); k=0
+ for f in "${RECETAS[@]}"; do
+ [ $(( k % SH_N )) -eq $(( SH_I - 1 )) ] && SUB+=("$f")
+ k=$((k + 1))
+ done
+ RECETAS=("${SUB[@]}")
+ LOG="${LOG%.log}-$SH_I-de-$SH_N.log" # un log por shard, o se pisan entre workers
+ echo "== SHARD $SH_I/$SH_N ⇒ ${#RECETAS[@]} recetas de este worker" | tee -a "$LOG"
+fi
echo "== $(ts) reconstrucción: ${#RECETAS[@]} recetas · libre $(libre_gb) G" | tee -a "$LOG"
if [ "$SECO" = "1" ]; then