Etapa G: GRANJA de build paralela — drena la cola, 11/22 al corpus (71→82)
La pieza que escala a miles: scripts/build-farm.sh construye N recetas a la vez (worker pool xargs -P) sobre recipes/incoming/, y lo que CONSTRUYE+sella lo promueve incoming/->recipes/ + publica al repo firmado (en serie: el index.json es mutable compartido); lo que falla queda staged con su motivo. Idempotente (cache-hit del store). Corrida sobre las 22 del lote Rust #2, JOBS=4 en la laptop libre (8 cores/19GB): BUILD-YIELD 11/22 promovidos, los 11 corren static-musl (bandwhich/difftastic/fclones/ gping/grex/mcfly/miniserve/navi/onefetch/pastel/viu). Corpus 71->82, repo 82. Los 11 fallos, FLAGEADOS por la granja (esto es el valor: triage automatico, no adivinanza) y staged en incoming/ para revision: - crate+dep-C bajo zig-cc (frente conocido, mismo family que el gueto gcc): delta (libgit2-sys), gitui (openssl-sys), jless (libc-stdhandle). - MSRV > 1.91.1 (techo del sandbox): ouch (1.93). watchexec: feature nightly E0658. - LINK colgado con zig-cc en binarios Rust grandes (deadlock, hubo que matarlos): broot, pueue, starship. Patron a investigar (zig cc + lld en binarios pesados). - import roto (no build): xsv/zellij 'No such file' (la fuente no clasifico), dog (importo un dog.c ajeno, no el cliente DNS Rust). GOTCHA infra: builds Rust grandes pueden COLGARSE en el link final con zig-cc (broot 7min frozen, pueue/starship idem); la granja deja matar el slot (pkill -f 'build recipes/incoming/<n>.toml') y sigue con los demas.
Semántico sayk'uy
Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.
23 qillqakuna · +294 −221
- recipes/bandwhich.toml +19 −0
- recipes/difftastic.toml +22 −0
- recipes/fclones.toml +19 −0
- recipes/gping.toml +22 −0
- recipes/grex.toml +19 −0
- recipes/incoming/bandwhich.toml +0 −19
- recipes/incoming/difftastic.toml +0 −22
- recipes/incoming/fclones.toml +0 −19
- recipes/incoming/gping.toml +0 −22
- recipes/incoming/grex.toml +0 −19
- recipes/incoming/mcfly.toml +0 −19
- recipes/incoming/miniserve.toml +0 −22
- recipes/incoming/navi.toml +0 −19
- recipes/incoming/onefetch.toml +0 −22
- recipes/incoming/pastel.toml +0 −19
- recipes/incoming/viu.toml +0 −19
- recipes/mcfly.toml +19 −0
- recipes/miniserve.toml +22 −0
- recipes/navi.toml +19 −0
- recipes/onefetch.toml +22 −0
- recipes/pastel.toml +19 −0
- recipes/viu.toml +19 −0
- scripts/build-farm.sh +73 −0
diff --git a/recipes/incoming/bandwhich.toml b/recipes/bandwhich.toml
similarity index 100%
rename from recipes/incoming/bandwhich.toml
rename to recipes/bandwhich.toml
diff --git a/recipes/incoming/difftastic.toml b/recipes/difftastic.toml
similarity index 100%
rename from recipes/incoming/difftastic.toml
rename to recipes/difftastic.toml
diff --git a/recipes/incoming/fclones.toml b/recipes/fclones.toml
similarity index 100%
rename from recipes/incoming/fclones.toml
rename to recipes/fclones.toml
diff --git a/recipes/incoming/gping.toml b/recipes/gping.toml
similarity index 100%
rename from recipes/incoming/gping.toml
rename to recipes/gping.toml
diff --git a/recipes/incoming/grex.toml b/recipes/grex.toml
similarity index 100%
rename from recipes/incoming/grex.toml
rename to recipes/grex.toml
diff --git a/recipes/incoming/mcfly.toml b/recipes/mcfly.toml
similarity index 100%
rename from recipes/incoming/mcfly.toml
rename to recipes/mcfly.toml
diff --git a/recipes/incoming/miniserve.toml b/recipes/miniserve.toml
similarity index 100%
rename from recipes/incoming/miniserve.toml
rename to recipes/miniserve.toml
diff --git a/recipes/incoming/navi.toml b/recipes/navi.toml
similarity index 100%
rename from recipes/incoming/navi.toml
rename to recipes/navi.toml
diff --git a/recipes/incoming/onefetch.toml b/recipes/onefetch.toml
similarity index 100%
rename from recipes/incoming/onefetch.toml
rename to recipes/onefetch.toml
diff --git a/recipes/incoming/pastel.toml b/recipes/pastel.toml
similarity index 100%
rename from recipes/incoming/pastel.toml
rename to recipes/pastel.toml
diff --git a/recipes/incoming/viu.toml b/recipes/viu.toml
similarity index 100%
rename from recipes/incoming/viu.toml
rename to recipes/viu.toml
diff --git a/scripts/build-farm.sh b/scripts/build-farm.sh
new file mode 100755
index 00000000..8a98983e
--- /dev/null
+++ b/scripts/build-farm.sh
@@ -0,0 +1,73 @@
+#!/bin/sh
+# build-farm.sh — Etapa G: GRANJA de build paralela sobre la COLA DE STAGING (recipes/incoming/).
+# El import escala (import-batch ~95% yield, cientos en minutos); el COMPILE es el cuello de botella
+# (1-7 min c/u) pero es embarrassingly-parallel + cacheable por contenido (el store dedup global). Esta
+# es la pieza que convierte "decenas por sesión serial" en "drenar la cola en paralelo": construye N a
+# la vez, y lo que CONSTRUYE+sella lo PROMUEVE incoming/->recipes/ y lo publica al repo firmado; lo que
+# falla queda staged con su motivo (MSRV, dep faltante, …) para revisión.
+#
+# Dos fases: (1) BUILD en paralelo (lo caro, worker pool de $JOBS) — escribe status por paquete; (2)
+# PROMOTE+PUBLISH en SERIE (el index.json del repo es mutable compartido ⇒ no se paraleliza) + firma 1 vez.
+# Idempotente: una receta ya sellada sale por cache-hit; re-correr sólo reintenta lo que falta.
+#
+# Uso: JOBS=4 scripts/build-farm.sh # drena recipes/incoming/*.toml
+# JOBS=6 QUEUE=recipes/incoming scripts/build-farm.sh
+# Env: JOBS (def: nproc-2), QUEUE (def recipes/incoming), STORE (def ./store), REPO (def dist/repo),
+# KEY (clave de firma; def dist/keys/release.ed25519), DISTRO (def dev), HAMMER (cmd del cli),
+# PROMOTE (def 1; =0 sólo construye+mide, no toca recipes/ ni el repo).
+set -eu
+
+ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
+QUEUE="${QUEUE:-recipes/incoming}"
+STORE="${STORE:-./store}"
+REPO="${REPO:-$ROOT/dist/repo}"
+KEY="${KEY:-$ROOT/dist/keys/release.ed25519}"
+DISTRO="${DISTRO:-dev}"
+HAMMER="${HAMMER:-$ROOT/target/release/hammer}"
+PROMOTE="${PROMOTE:-1}"
+JOBS="${JOBS:-$(( $(nproc) - 2 ))}"; [ "$JOBS" -ge 1 ] || JOBS=1
+
+FARM="$ROOT/work/farm"
+rm -rf "$FARM"; mkdir -p "$FARM/log" "$FARM/status"
+
+queue=$(ls "$QUEUE"/*.toml 2>/dev/null || true)
+[ -n "$queue" ] || { echo "cola vacía: $QUEUE/*.toml"; exit 0; }
+n_total=$(printf '%s\n' "$queue" | wc -l | tr -d ' ')
+echo "==> GRANJA: $n_total recetas en $QUEUE, $JOBS workers en paralelo"
+
+# ── Fase 1: BUILD en paralelo. Cada worker construye una receta y deja su status (.ok con hash | .fail
+# con motivo). El store sella atómico y cada build usa sources/<name>-<sha> + out/<hash>-<name> propios
+# ⇒ sin colisión entre recetas distintas. `xargs -P` es el pool.
+printf '%s\n' "$queue" | xargs -P"$JOBS" -I '{}' sh -c '
+ f="$1"; n=$(basename "$f" .toml); log="'"$FARM"'/log/$n.log"
+ H=$("'"$HAMMER"'" --store "'"$STORE"'" build "$f" 2>"$log" | tail -1 || true)
+ if [ "${H#b3:}" != "$H" ] && [ -n "$H" ]; then
+ echo "$H" > "'"$FARM"'/status/$n.ok"; printf " ✓ %-18s %s\n" "$n" "$H"
+ else
+ r=$(grep -oiE "requires rustc [0-9.]+|cannot find -l[a-z0-9]+|could not find .[a-z0-9_-]+.|error\[E[0-9]+\]|not found|unsupported|no such file" "$log" | head -1)
+ echo "${r:-fallo (ver log)}" > "'"$FARM"'/status/$n.fail"; printf " ✗ %-18s %s\n" "$n" "${r:-fallo}"
+ fi
+' _ '{}'
+
+# ── Fase 2: PROMOTE + PUBLISH en serie (índice del repo = recurso mutable compartido).
+ok=$(ls "$FARM"/status/*.ok 2>/dev/null | wc -l | tr -d ' ')
+fail=$(ls "$FARM"/status/*.fail 2>/dev/null | wc -l | tr -d ' ')
+echo "==> BUILD-YIELD: $ok/$n_total construyen ($fail fallan)"
+
+if [ "$PROMOTE" = 1 ] && [ "$ok" -gt 0 ]; then
+ echo "==> promoviendo + publicando $ok al repo firmado…"
+ for s in "$FARM"/status/*.ok; do
+ n=$(basename "$s" .ok)
+ [ -f "$QUEUE/$n.toml" ] && mv "$QUEUE/$n.toml" recipes/
+ "$HAMMER" --store "$STORE" pack "recipes/$n.toml" --repo "$REPO" --distro-version "$DISTRO" --build >/dev/null 2>&1 \
+ && printf " + %s\n" "$n" || printf " ! %s (pack falló)\n" "$n"
+ done
+ "$HAMMER" repo sign --repo "$REPO" --key "$KEY" >/dev/null 2>&1 && echo "==> release re-firmado"
+fi
+
+# ── Reporte de fallos (motivo por paquete) para triage.
+if [ "$fail" -gt 0 ]; then
+ echo "==> FALLARON ($fail) — quedan staged en $QUEUE:"
+ for s in "$FARM"/status/*.fail; do printf " ✗ %-18s %s\n" "$(basename "$s" .fail)" "$(cat "$s")"; done
+fi
+echo "==> granja: $ok promovidos, $fail staged. logs en $FARM/log/"