gioser

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 604Rust 56Shell 36Markdown 281227 Definitions

⎇ b0085e7cf6978a7f9e27aa863f756a463fc1407e scripts/juez.sh Shell · 104 lines · 5.3 KB History raw

takana etapa 5c: comentarios de scripts, MOTD, y un BUG que introdujo la etapa 4 476168bb0 · Sergio ·

1#!/bin/sh
2# juez.sh <receta> — JUEZ MECÁNICO del bucle agéntico (SDD 17 §10).
3#
4#   agente propone receta → harkaq veredicto → granja reproduce ×2 → catálogo acepta
5#
6# Sin humano en el medio para la parte mecánica: el humano decide QUÉ construir; el juez decide
7# si lo construido MERECE entrar al catálogo, y lo decide con evidencia, no con opinión.
8#
9#   scripts/juez.sh recipes/zlib.toml
10#
11# Dos preguntas, dos veredictos, ninguno negociable:
12#   1. ¿HERMÉTICO?     harkaq (SDD 16): ¿usó algo que no declaró? El kernel responde.
13#                      `denials=[]` no se cree, se GANA (el canario lo demuestra — D9).
14#   2. ¿REPRODUCIBLE?  consenso (SDD 17 §1): N builders independientes, ¿el mismo hash?
15#                      Si sí, el artefacto es confiable SIN FIRMA.
16#
17# Si falla, el juez no dice "no" a secas: dice POR QUÉ y qué hacer.
18#   - Impuro     → harkaq-suggest: "declarar dep: make" (arreglo mecánico)
19#   - Divergente → why-differs: qué fichero, qué causa (codegen/timestamp/build-id)
20#
21# Es el bucle que el SDD 08 §4 pide ("la IA propone, el sistema reproduce, el humano commitea")
22# con la pieza que faltaba: un juez que la IA no puede convencer, sólo satisfacer.
23set -eu
24
25RECETA="${1:?uso: juez.sh <receta.toml>}"
26HUB="$(cd "$(dirname "$0")/.." && pwd)"
27cd "$HUB"
28n=$(basename "$RECETA" .toml)
29BUILDERS="${BUILDERS:-2}"
30
31echo "══════ JUEZ MECÁNICO — $n"
32echo
33
34# ── 1. ¿HERMÉTICO? (harkaq)
35echo "── 1/2 ¿usó algo que no declaró?  [harkaq, SDD 16]"
36if [ ! -x "${HARKAQ_BIN:-$HOME/.cache/harkaq}/harkaq-audit" ]; then
37    echo "   ⊘ harkaq no está compilado ⇒ SIN EVIDENCIA. El juez NO afirma hermeticidad."
38    echo "     (compilar scripts/harkaq/*.c y `setcap cap_audit_read` — ver scripts/harkaq/README.md)"
39    veredicto_h="sin-evidencia"
40else
41    export HARKAQ=1 HARKAQ_BIN="${HARKAQ_BIN:-$HOME/.cache/harkaq}"
42    export HARKAQ_BASE="${HARKAQ_BASE:-$HARKAQ_BIN/base.policy}" HARKAQ_TIMEOUT="${HARKAQ_TIMEOUT:-200}"
43    # Nombre ÚNICO por corrida: con uno fijo, la 2ª vez `takana build` pega en CACHÉ, no
44    # construye nada, no hay veredictos y el juez dice "sin evidencia" — un falso negativo que
45    # parece un problema de la receta. (Gotcha conocido; me mordió al probar el juez.)
46    uniq="$n-juez-$$"
47    tmp="$(dirname "$RECETA")/.juez-$n.toml"
48    sed -E "s/^(name\s*=\s*)\"$n\"/\1\"$uniq\"/" "$RECETA" > "$tmp"
49    out=$(timeout "${POR:-600}" ./target/debug/hammer build "$tmp" --store "$PWD/store" 2>&1 || true)
50    rm -f "$tmp"; rm -rf store/*-"$uniq" 2>/dev/null || true
51    veredictos=$(echo "$out" | grep '^\[harkaq\] {' | sed 's/^\[harkaq\] //')
52    deuda=""
53    if [ -z "$veredictos" ]; then
54        echo "   ⊘ sin veredicto (¿caché? ¿el build ni arrancó?) ⇒ SIN EVIDENCIA"
55        veredicto_h="sin-evidencia"
56    else
57        veredicto_h="hermetico"
58        i=0
59        echo "$veredictos" | while IFS= read -r v; do :; done
60        printf '%s\n' "$veredictos" > /tmp/.juez-v
61        while IFS= read -r v; do
62            i=$((i + 1)); echo "$v" > /tmp/.juez-1
63            est=$(scripts/harkaq/harkaq-verdict.py /tmp/.juez-1 "$HARKAQ_BASE" --human 2>/dev/null | head -1 | sed 's/^ *estado: //;s/ .*//')
64            echo "      fase $i: ${est:-?}"
65            [ "$est" = "Impuro" ] && { veredicto_h="impuro"; \
66                scripts/harkaq/harkaq-suggest.py /tmp/.juez-1 "$HARKAQ_BASE" "$PWD/store" "$PWD/recipes" "$RECETA" 2>/dev/null | sed 's/^/         /'; }
67            [ "$est" = "SinEvidencia" ] && veredicto_h="sin-evidencia"
68        done < /tmp/.juez-v
69        # el while corre en subshell: recuperar el peor veredicto por marcador
70        grep -q '"estado":"Impuro"' /tmp/.juez-v && veredicto_h="impuro"
71        grep -q '"estado":"SinEvidencia"' /tmp/.juez-v && veredicto_h="sin-evidencia"
72    fi
73fi
74echo
75
76# ── 2. ¿REPRODUCIBLE? (consenso)
77echo "── 2/2 ¿N builders independientes dan el mismo hash?  [consenso, SDD 17 §1]"
78if consenso=$(BUILDERS="$BUILDERS" timeout "${POR_CONSENSO:-1200}" scripts/consenso.sh "$RECETA" "$BUILDERS" 2>&1); then
79    echo "$consenso" | grep -E '✅|builder' | sed 's/^/   /'
80    veredicto_r="consenso"
81else
82    rc=$?
83    echo "$consenso" | grep -E '⚠️|builder|SIN CONSENSO' | sed 's/^/   /'
84    [ "$rc" = 1 ] && veredicto_r="divergencia" || veredicto_r="sin-consenso"
85    if [ "$veredicto_r" = divergencia ]; then
86        echo "   ── why-differs (SDD 17 §2) explicaría la divergencia:"
87        echo "      scripts/why-differs.py <hashA> <hashB> --store ./store"
88    fi
89fi
90echo
91
92# ── VEREDICTO
93echo "══════ VEREDICTO"
94if [ "$veredicto_h" = hermetico ] && [ "$veredicto_r" = consenso ]; then
95    echo "   ✅ ACEPTAR — no usó nada sin declarar Y $BUILDERS builders lo reprodujeron bit a bit."
96    echo "      El catálogo puede confiar en este artefacto sin firma y sin revisión humana del build."
97    exit 0
98fi
99echo "   ❌ NO ACEPTAR"
100[ "$veredicto_h" = impuro ]        && echo "      · hermeticidad: usa algo sin declarar (ver la sugerencia arriba: es una línea)"
101[ "$veredicto_h" = sin-evidencia ] && echo "      · hermeticidad: SIN EVIDENCIA — no se afirma nada (D9: un lector ciego y un build limpio son idénticos)"
102[ "$veredicto_r" = divergencia ]   && echo "      · reproducibilidad: los builders NO coinciden ⇒ hay un canal impuro"
103[ "$veredicto_r" = sin-consenso ]  && echo "      · reproducibilidad: no hubo suficientes builders con hash"
104exit 1