#!/bin/sh # Fase 2 — barrer el catálogo y medir la tasa de excepciones (SDD 16 §6). # # fase2-barrido.sh [...] # # El criterio de viabilidad del SDD (§7): "si el 30% de los builds necesita excepción manual, # harkaq se desactiva y queda como decoración". Métrica: <5%. # # Pero "excepción" no es "denegación" (§4.5). Una deuda que el store YA PROVEE no es una # excepción: es una línea en `[deps]` que falta, y el arreglo es mecánico. Sólo la deuda # IRREDUCIBLE —nadie la provee— cuenta contra el <5%. Sin esa distinción la métrica mide # ansiedad, no viabilidad. # # `takana build` pega en la caché si el artefacto ya está sellado (no correría nada y el # veredicto saldría vacío sin que sea un fallo). Se fuerza un build real copiando la receta con # otro `name` — cambia hash_inputs sin tocar el store real ni la receta del repo. set -eu cd "$(dirname "$0")/../.." BIN="${HARKAQ_BIN:-$HOME/.cache/harkaq}" BASE="${HARKAQ_BASE:-$BIN/base.policy}" OUT="${OUT:-work/harkaq-fase2}" mkdir -p "$OUT" export HARKAQ=1 HARKAQ_BIN="$BIN" HARKAQ_BASE="$BASE" export HARKAQ_TIMEOUT="${HARKAQ_TIMEOUT:-120}" total=0; limpias=0; solo_declarable=0; con_irreducible=0 : > "$OUT/deuda-cruda.txt" for receta in "$@"; do n=$(basename "$receta" .toml) total=$((total + 1)) # La copia va AL LADO del original: las `deps.build` se resuelven relativas al directorio # de la receta, así que copiarla a otro sitio rompe `cmake.toml` y compañía — y descartaba # en silencio justo las recetas CON deps, que son las interesantes. Se limpia al salir. tmp="$(dirname "$receta")/.harkaq-$n.toml" sed "s/^name *= *\"$n\"/name = \"$n-hk\"/" "$receta" > "$tmp" trap 'rm -f "$tmp"' EXIT log="$OUT/$n.log" timeout "${POR_RECETA:-300}" ./target/debug/hammer build "$tmp" --store "$PWD/store" \ > "$log" 2>&1 || true # Un veredicto por fase (configure/compile/install son bwraps distintos ⇒ dominios distintos). rm -f "$tmp" grep '^\[harkaq\] {' "$log" | sed 's/^\[harkaq\] //' > "$OUT/$n.verdicts" || true if [ ! -s "$OUT/$n.verdicts" ]; then echo "?? $n — sin veredicto (¿caché? ¿fetch falló? ver $log)" continue fi irr=0; dec=0 while IFS= read -r v; do echo "$v" > "$OUT/.v.json" s=$(scripts/harkaq/harkaq-suggest.py "$OUT/.v.json" "$BASE" "$PWD/store" 2>/dev/null || true) echo "$s" | grep -q 'IRREDUCIBLE' && irr=1 echo "$s" | grep -q 'DECLARABLE' && dec=1 echo "$s" | sed -n 's/^ \(\/[^ ]*\)$/\1/p' >> "$OUT/deuda-cruda.txt" done < "$OUT/$n.verdicts" if [ "$irr" = 1 ]; then con_irreducible=$((con_irreducible + 1)); echo "!! $n — deuda IRREDUCIBLE" elif [ "$dec" = 1 ]; then solo_declarable=$((solo_declarable + 1)); echo "~~ $n — sólo deuda declarable (falta [deps])" else limpias=$((limpias + 1)); echo "ok $n — Hermetico" fi done echo echo "════ FASE 2 — $total receta(s)" echo " Hermetico ................... $limpias" echo " sólo deuda DECLARABLE ....... $solo_declarable (arreglo mecánico: una línea en [deps])" echo " con deuda IRREDUCIBLE ....... $con_irreducible ← lo que cuenta contra el <5%" echo echo " paths de deuda más frecuentes:" sort "$OUT/deuda-cruda.txt" | uniq -c | sort -rn | head -12 | sed 's/^/ /'