Files
hammer/scripts/farm/harvest-harkaq.sh
T
sergioandClaude Opus 4.8 21ac060c4b harkaq: declarar deps medidas por el kernel (cosecha automática)
Cosecha desatendida de la campaña harkaq. Cada dep de acá la denunció el audit de
Landlock en un build real: el kernel vio al build usarla sin declararla, y el
store del hub confirma qué artefacto la provee (deuda DECLARABLE, §4.5).

Recetas:gettext-tiny giflib git gnupg gperf gzip htop iproute2 jq kbd libassuan libcap libevent libffi libgcrypt libgpg-error libksba libnl libpng libsass libsodium libssh2 libudev-zero libusb libwebp libxml2 libyaml linux-generic linux-headers linux-metal linux-pam linux lz4 mandoc mtools musl nano npth openssh openssl parted pciutils pcre2 pigz procps-ng python3 readline rsync samurai ca-certificates curl doas dosfstools e2fsprogs fontconfig freetype

No se tocó ninguna receta con deuda IRREDUCIBLE: declarar algo que el store no
provee rompería el build en vez de arreglarlo. Esas van a tandas/needs-review-harkaq.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:27:57 -04:00

113 lines
5.5 KiB
Bash
Executable File

#!/bin/sh
# harvest-harkaq.sh — COSECHA-ONLY de la campaña harkaq (modo desatendido, para cron en el hub).
# Determinista, sin IA. Hermano de harvest-go.sh y con la misma disciplina: no elige, no diagnostica,
# no compila en el hub; sólo convierte en commit lo que el worker YA midió.
#
# Uso (cron): cd /home/sergio/hammer && scripts/farm/harvest-harkaq.sh root@<ip> >>work/harvest-harkaq.log 2>&1
#
# POR QUÉ EXISTE ASÍ: la lista de "recetas a las que les falta declarar make" NO se puede sacar de
# un regex. Se intentó y falló dos veces en la misma tarde: `\bmake\b` colaba `cargo-make` (el guión
# es límite de palabra) y la versión estrecha perdía LAS CINCO recetas donde harkaq había medido la
# deuda de verdad (`compile = "make …"`: el carácter previo es una comilla). El número bailó 69→45→99
# según el retoque. La fuente de verdad es la MEDICIÓN, no la conjetura — que es exactamente para lo
# que existe harkaq. Este script sólo aplica lo que el kernel denunció.
#
# Ciclo (idempotente, seguro de re-correr):
# 1. git pull --rebase (otro agente pushea al mismo main)
# 2. baja los veredictos del worker
# 3. por cada veredicto: harkaq-suggest contra el store COMPLETO del hub (el del worker es parcial
# y marcaría como irreducible lo que sí es declarable — el worker MIDE, el hub CLASIFICA)
# 4. si la deuda es DECLARABLE ⇒ añade la dep a la receta. Si es IRREDUCIBLE ⇒ NO la toca: va a
# tandas/needs-review-harkaq/ con el motivo. Declarar algo que el store no provee rompería el
# build en vez de arreglarlo.
# 5. commit + push con `git add` EXPLÍCITO (nunca -A: respeta al otro agente)
set -u
HUB="$(cd "$(dirname "$0")/../.." && pwd)"
cd "$HUB"
WORKER="${1:?uso: harvest-harkaq.sh root@<ip>}"
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
REMOTE="${REMOTE:-/opt/hammer}"
SSH="ssh -i $SSH_KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes"
REVIEW="tandas/needs-review-harkaq"
mkdir -p "$REVIEW" work
echo "═══ $(date -u +%FT%TZ) cosecha harkaq desde $WORKER"
git pull --rebase -q 2>/dev/null || echo " (pull falló; sigo con lo local)"
VERD=work/harkaq-verdicts
rm -rf "$VERD"; mkdir -p "$VERD"
rsync -az -e "$SSH" "$WORKER:$REMOTE/work/harkaq-campana/" "$VERD/" 2>/dev/null || {
echo " sin veredictos que cosechar (¿el worker sigue midiendo?)"; exit 0; }
tocadas=""
for v in "$VERD"/*.verdicts; do
[ -f "$v" ] || continue
n=$(basename "$v" .verdicts)
[ -f "recipes/$n.toml" ] || continue
deps=""; irr=0
while IFS= read -r j; do
[ -n "$j" ] || continue
echo "$j" > /tmp/.hkv.json
s=$(scripts/harkaq/harkaq-suggest.py /tmp/.hkv.json "$HOME/.cache/harkaq/base.policy" \
"$HUB/store" "$HUB/recipes" 2>/dev/null) || true
echo "$s" | grep -q IRREDUCIBLE && irr=1
# "→ declarar dep: X" (el store lo provee y sabe cuál artefacto es).
d=$(echo "$s" | sed -n 's/.*→ declarar dep: \([a-zA-Z0-9._-]*\).*/\1/p')
deps="$deps $d"
done < "$v"
deps=$(echo "$deps" | tr ' ' '\n' | grep -v '^$' | sort -u | tr '\n' ' ')
[ -n "$deps" ] || continue
if [ "$irr" = 1 ]; then
# NO se toca: declarar algo que el store no provee rompe el build en vez de arreglarlo.
cp "$v" "$REVIEW/$n.verdicts"
echo " ?? $n — deuda irreducible ⇒ a needs-review (deps declarables vistas:$deps)"
continue
fi
if python3 scripts/farm/harkaq-add-deps.py "recipes/$n.toml" $deps; then
echo " ++ $n — declaradas:$deps"
tocadas="$tocadas recipes/$n.toml"
fi
done
# Recoger también las recetas editadas por un ciclo ANTERIOR que no llegó a commitear (el proceso
# murió, SIGPIPE, la máquina se apagó). Sin esto quedan huérfanas para siempre: al re-correr,
# add-deps dice "ya estaban declaradas", `tocadas` sale vacío y nadie las commitea nunca. Pasó en
# el primer ciclo real: 13 recetas editadas y sin committear. Se filtra por `recipes/*.toml` y por
# que el diff SÓLO toque la línea `build = [...]`, para no arrastrar trabajo de otro agente.
for f in $(git diff --name-only -- 'recipes/*.toml' 2>/dev/null); do
case " $tocadas " in *" $f "*) continue ;; esac
if git diff -U0 -- "$f" | grep -E '^[-+]' | grep -vE '^(---|\+\+\+)' | grep -qvE '^[-+]\s*(build\s*=|\[deps\])'; then
echo " ·· $f — modificado con algo que no es `[deps].build`: NO lo toco (¿otro agente?)"
else
tocadas="$tocadas $f"
echo " ↻ $f — pendiente de un ciclo anterior, se commitea ahora"
fi
done
if [ -n "$tocadas" ]; then
# `git add` EXPLÍCITO por rutas: el repo lo comparte otro agente (cola gráfica/Go).
# shellcheck disable=SC2086
git add $tocadas
git commit -q -m "harkaq: declarar deps medidas por el kernel (cosecha automática)
Cosecha desatendida de la campaña harkaq. Cada dep de acá la denunció el audit de
Landlock en un build real: el kernel vio al build usarla sin declararla, y el
store del hub confirma qué artefacto la provee (deuda DECLARABLE, §4.5).
Recetas:$(echo "$tocadas" | tr ' ' '\n' | grep -v '^$' | sed 's|recipes/||;s|\.toml||' | tr '\n' ' ')
No se tocó ninguna receta con deuda IRREDUCIBLE: declarar algo que el store no
provee rompería el build en vez de arreglarlo. Esas van a $REVIEW.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>" && git push -q 2>/dev/null || {
git pull --rebase -q && git push -q; }
echo " ✓ commit+push de $(echo "$tocadas" | wc -w) receta(s)"
else
echo " nada que declarar en este ciclo"
fi