250 líneas de comentario en 151 scripts. Control verificado: el diff no toca NI UNA línea que no empiece por #, y la sintaxis de los 151 pasa. El barrido saltea heredocs y cadenas triples, y el guardián DISPARÓ 3 veces: las tres eran el MOTD que el script escribe DENTRO de la imagen construida — texto del producto, no comentario del script. Se cambiaron aparte y a propósito, que es rebranding, no limpieza. Y el hallazgo caro: casaba contra , que es el TARGET de tracing — o sea el module_path!, o sea el nombre del crate. La etapa 4 lo movió a y el script quedó casando NADA. No fallaba: imprimía cero atribuciones, indistinguible de un log sin problemas. Comprobado con el binario (RUST_LOG=info sobre zlib), no deducido. Ahora acepta las dos, y tiene que seguir aceptándolas porque los logs viejos en disco dicen la vieja. Además 14 rutas de módulo en docs, que el barrido anterior no tocó porque no es frontera de palabra.
105 lines
5.3 KiB
Bash
Executable File
105 lines
5.3 KiB
Bash
Executable File
#!/bin/sh
|
||
# juez.sh <receta> — JUEZ MECÁNICO del bucle agéntico (SDD 17 §10).
|
||
#
|
||
# agente propone receta → harkaq veredicto → granja reproduce ×2 → catálogo acepta
|
||
#
|
||
# Sin humano en el medio para la parte mecánica: el humano decide QUÉ construir; el juez decide
|
||
# si lo construido MERECE entrar al catálogo, y lo decide con evidencia, no con opinión.
|
||
#
|
||
# scripts/juez.sh recipes/zlib.toml
|
||
#
|
||
# Dos preguntas, dos veredictos, ninguno negociable:
|
||
# 1. ¿HERMÉTICO? harkaq (SDD 16): ¿usó algo que no declaró? El kernel responde.
|
||
# `denials=[]` no se cree, se GANA (el canario lo demuestra — D9).
|
||
# 2. ¿REPRODUCIBLE? consenso (SDD 17 §1): N builders independientes, ¿el mismo hash?
|
||
# Si sí, el artefacto es confiable SIN FIRMA.
|
||
#
|
||
# Si falla, el juez no dice "no" a secas: dice POR QUÉ y qué hacer.
|
||
# - Impuro → harkaq-suggest: "declarar dep: make" (arreglo mecánico)
|
||
# - Divergente → why-differs: qué fichero, qué causa (codegen/timestamp/build-id)
|
||
#
|
||
# Es el bucle que el SDD 08 §4 pide ("la IA propone, el sistema reproduce, el humano commitea")
|
||
# con la pieza que faltaba: un juez que la IA no puede convencer, sólo satisfacer.
|
||
set -eu
|
||
|
||
RECETA="${1:?uso: juez.sh <receta.toml>}"
|
||
HUB="$(cd "$(dirname "$0")/.." && pwd)"
|
||
cd "$HUB"
|
||
n=$(basename "$RECETA" .toml)
|
||
BUILDERS="${BUILDERS:-2}"
|
||
|
||
echo "══════ JUEZ MECÁNICO — $n"
|
||
echo
|
||
|
||
# ── 1. ¿HERMÉTICO? (harkaq)
|
||
echo "── 1/2 ¿usó algo que no declaró? [harkaq, SDD 16]"
|
||
if [ ! -x "${HARKAQ_BIN:-$HOME/.cache/harkaq}/harkaq-audit" ]; then
|
||
echo " ⊘ harkaq no está compilado ⇒ SIN EVIDENCIA. El juez NO afirma hermeticidad."
|
||
echo " (compilar scripts/harkaq/*.c y `setcap cap_audit_read` — ver scripts/harkaq/README.md)"
|
||
veredicto_h="sin-evidencia"
|
||
else
|
||
export HARKAQ=1 HARKAQ_BIN="${HARKAQ_BIN:-$HOME/.cache/harkaq}"
|
||
export HARKAQ_BASE="${HARKAQ_BASE:-$HARKAQ_BIN/base.policy}" HARKAQ_TIMEOUT="${HARKAQ_TIMEOUT:-200}"
|
||
# Nombre ÚNICO por corrida: con uno fijo, la 2ª vez `takana build` pega en CACHÉ, no
|
||
# construye nada, no hay veredictos y el juez dice "sin evidencia" — un falso negativo que
|
||
# parece un problema de la receta. (Gotcha conocido; me mordió al probar el juez.)
|
||
uniq="$n-juez-$$"
|
||
tmp="$(dirname "$RECETA")/.juez-$n.toml"
|
||
sed -E "s/^(name\s*=\s*)\"$n\"/\1\"$uniq\"/" "$RECETA" > "$tmp"
|
||
out=$(timeout "${POR:-600}" ./target/debug/hammer build "$tmp" --store "$PWD/store" 2>&1 || true)
|
||
rm -f "$tmp"; rm -rf store/*-"$uniq" 2>/dev/null || true
|
||
veredictos=$(echo "$out" | grep '^\[harkaq\] {' | sed 's/^\[harkaq\] //')
|
||
deuda=""
|
||
if [ -z "$veredictos" ]; then
|
||
echo " ⊘ sin veredicto (¿caché? ¿el build ni arrancó?) ⇒ SIN EVIDENCIA"
|
||
veredicto_h="sin-evidencia"
|
||
else
|
||
veredicto_h="hermetico"
|
||
i=0
|
||
echo "$veredictos" | while IFS= read -r v; do :; done
|
||
printf '%s\n' "$veredictos" > /tmp/.juez-v
|
||
while IFS= read -r v; do
|
||
i=$((i + 1)); echo "$v" > /tmp/.juez-1
|
||
est=$(scripts/harkaq/harkaq-verdict.py /tmp/.juez-1 "$HARKAQ_BASE" --human 2>/dev/null | head -1 | sed 's/^ *estado: //;s/ .*//')
|
||
echo " fase $i: ${est:-?}"
|
||
[ "$est" = "Impuro" ] && { veredicto_h="impuro"; \
|
||
scripts/harkaq/harkaq-suggest.py /tmp/.juez-1 "$HARKAQ_BASE" "$PWD/store" "$PWD/recipes" "$RECETA" 2>/dev/null | sed 's/^/ /'; }
|
||
[ "$est" = "SinEvidencia" ] && veredicto_h="sin-evidencia"
|
||
done < /tmp/.juez-v
|
||
# el while corre en subshell: recuperar el peor veredicto por marcador
|
||
grep -q '"estado":"Impuro"' /tmp/.juez-v && veredicto_h="impuro"
|
||
grep -q '"estado":"SinEvidencia"' /tmp/.juez-v && veredicto_h="sin-evidencia"
|
||
fi
|
||
fi
|
||
echo
|
||
|
||
# ── 2. ¿REPRODUCIBLE? (consenso)
|
||
echo "── 2/2 ¿N builders independientes dan el mismo hash? [consenso, SDD 17 §1]"
|
||
if consenso=$(BUILDERS="$BUILDERS" timeout "${POR_CONSENSO:-1200}" scripts/consenso.sh "$RECETA" "$BUILDERS" 2>&1); then
|
||
echo "$consenso" | grep -E '✅|builder' | sed 's/^/ /'
|
||
veredicto_r="consenso"
|
||
else
|
||
rc=$?
|
||
echo "$consenso" | grep -E '⚠️|builder|SIN CONSENSO' | sed 's/^/ /'
|
||
[ "$rc" = 1 ] && veredicto_r="divergencia" || veredicto_r="sin-consenso"
|
||
if [ "$veredicto_r" = divergencia ]; then
|
||
echo " ── why-differs (SDD 17 §2) explicaría la divergencia:"
|
||
echo " scripts/why-differs.py <hashA> <hashB> --store ./store"
|
||
fi
|
||
fi
|
||
echo
|
||
|
||
# ── VEREDICTO
|
||
echo "══════ VEREDICTO"
|
||
if [ "$veredicto_h" = hermetico ] && [ "$veredicto_r" = consenso ]; then
|
||
echo " ✅ ACEPTAR — no usó nada sin declarar Y $BUILDERS builders lo reprodujeron bit a bit."
|
||
echo " El catálogo puede confiar en este artefacto sin firma y sin revisión humana del build."
|
||
exit 0
|
||
fi
|
||
echo " ❌ NO ACEPTAR"
|
||
[ "$veredicto_h" = impuro ] && echo " · hermeticidad: usa algo sin declarar (ver la sugerencia arriba: es una línea)"
|
||
[ "$veredicto_h" = sin-evidencia ] && echo " · hermeticidad: SIN EVIDENCIA — no se afirma nada (D9: un lector ciego y un build limpio son idénticos)"
|
||
[ "$veredicto_r" = divergencia ] && echo " · reproducibilidad: los builders NO coinciden ⇒ hay un canal impuro"
|
||
[ "$veredicto_r" = sin-consenso ] && echo " · reproducibilidad: no hubo suficientes builders con hash"
|
||
exit 1
|