tawasuyu

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 1572Shell 203Rust 109Markdown 993728 Sutichaykuna

⎇ 7c794568a963b18b68d747959e6bbd07cf2ebff7 scripts/harkaq/harkaq-trace-build.sh Shell · 87 siq'ikuna · 4.5 KB Ñawpa willay ch'uya

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

1#!/usr/bin/env bash
2# harkaq-trace-build.sh — orquestador del PILOTO de traza positiva (plan-freebsd T1.1+T1.3).
3#
4# Envuelve UN `takana build` con harkaq-trace enganchado al overlay de CADA fase: un bwrap
5# por fase ⇒ una traza por fase — la misma granularidad que el veredicto de harkaq. El
6# tracer marca `/proc/<pid-bwrap>/root`: el magic-link cae en el SB del OVERLAY, que es el
7# único lugar desde donde los reads del build se ven (la marca sobre el fs del host NO los
8# ve — ceguera-overlay, medida en el piloto; ver plan-freebsd-aprovechables.md §1). Bonus:
9# los paths salen en el namespace de la jaula (/usr/include/zlib.h) — el idioma de la
10# política, sin traducción host↔jaula.
11#
12# PILOTO, no framework: el enganche por polling tiene una ventana ciega (~decenas de ms al
13# arrancar cada fase) y bwrap puede aparecer como varios pids (helpers) — trazas duplicadas
14# que el normalizador colapsa, pero el conteo de "fases" puede inflarse. La integración
15# real (lanzar el tracer ANTES del exec del build, sin carrera) va en el harness — carril
16# de Opus, se coordina allá. Este script existe para medir HOY la señal declaradas-vs-usadas.
17#
18# uso:  harkaq-trace-build.sh <receta.toml> [store] [outdir]
19# env:  HAMMER (def ./target/release/takana), TRACE (def /tmp/harkaq-trace), NORM (def
20#       scripts/harkaq/harkaq-trace-norm.py)
21# deja en outdir: traza-fase-N.txt (crudas), canonica.txt, sello.txt, resumen.txt
22set -euo pipefail
23RECETA="${1:?uso: harkaq-trace-build.sh <receta.toml> [store] [outdir]}"
24STORE="${2:-./store}"
25OUT="${3:-/tmp/harkaq-trace-pilot}"
26HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
27TRACE="${TRACE:-/tmp/harkaq-trace}"
28NORM="${NORM:-scripts/harkaq/harkaq-trace-norm.py}"
29mkdir -p "$OUT"; rm -f "$OUT"/traza-fase-*.txt "$OUT"/canonica.txt "$OUT"/resumen.txt
30
31# bwraps que YA vivían (builds ajenos): fuera del piloto. El `|| true` importa: sin bwraps
32# pgrep sale 1 y, bajo pipefail, mataría el script en el arranque (medido, no teórico).
33YA=" $(pgrep -x bwrap 2>/dev/null | tr '\n' ' ' || true) "
34
35"$HAMMER" --store "$STORE" build "$RECETA" > "$OUT/build.out" 2> "$OUT/build.log" &
36BPID=$!
37
38fase=0
39declare -A TRAZADO
40while kill -0 "$BPID" 2>/dev/null; do
41  for p in $(pgrep -x bwrap 2>/dev/null || true); do
42    case "$YA" in *" $p "*) continue ;; esac
43    [ -n "${TRAZADO[$p]:-}" ] && continue
44    TRAZADO[$p]=1; fase=$((fase + 1))
45    # El tracer vive lo que viva SU bwrap: el cmd interno es un latido sobre el pid.
46    "$TRACE" --fs "/proc/$p/root" -o "$OUT/traza-fase-$fase.txt" -- \
47      sh -c "while kill -0 $p 2>/dev/null; do sleep 0.1; done" 2>> "$OUT/tracer.log" &
48  done
49  sleep 0.05
50done
51RC=0; wait "$BPID" || RC=$?
52wait || true # los tracers mueren con su bwrap y drenan la cola
53
54cat "$OUT"/traza-fase-*.txt > "$OUT/cruda-total.txt" 2>/dev/null || : > "$OUT/cruda-total.txt"
55python3 "$NORM" "$OUT/cruda-total.txt" > "$OUT/canonica.txt"
56
57# T1.3 (sello): b3 si hay b3sum; si no, sha256 MARCADO provisional — el sello que viaja
58# junto al of_tree debe ser b3 (mismo espacio de nombres del store), esto es el piloto.
59if command -v b3sum >/dev/null 2>&1; then
60  echo "b3:$(b3sum --no-names "$OUT/canonica.txt")" > "$OUT/sello.txt"
61else
62  echo "sha256(PROVISIONAL):$(sha256sum "$OUT/canonica.txt" | cut -d' ' -f1)" > "$OUT/sello.txt"
63fi
64
65# Declaradas vs USADAS — la señal de poda (T1.4) y el uso del runtime base (Q2 positivo).
66# Cada dep aporta un árbol al overlay fundido en /: sus paths de artefacto SON los paths
67# de jaula. `usadas/total` por dep; lo tocado que ninguna dep aporta = base Alpine.
68deps=$(sed -n '/^\[deps\]/,/^\[.*\]/p' "$RECETA" | grep -oE '"[a-zA-Z0-9_-]+"' | tr -d '"' || true)
69: > "$OUT/atribuidas.txt"
70{
71  echo "== declaradas vs usadas ($RECETA) =="
72  for d in $deps; do
73    art=$(ls -d "$STORE"/*-"$d" 2>/dev/null | head -1) || true
74    if [ -z "$art" ]; then echo "     ?/?     $d (sin artefacto en el store)"; continue; fi
75    cd "$art"; find . -type f | sed 's|^\.||' | sort > /tmp/.dep-files.$$; cd - >/dev/null
76    n=$(comm -12 /tmp/.dep-files.$$ <(sort "$OUT/canonica.txt") | wc -l)
77    comm -12 /tmp/.dep-files.$$ <(sort "$OUT/canonica.txt") >> "$OUT/atribuidas.txt"
78    tot=$(wc -l < /tmp/.dep-files.$$)
79    printf "%6d/%-6d %s\n" "$n" "$tot" "$d"
80    rm -f /tmp/.dep-files.$$
81  done
82  base=$(comm -23 <(sort "$OUT/canonica.txt") <(sort -u "$OUT/atribuidas.txt") | wc -l)
83  echo "   base (sin dep que lo aporte): $base paths — el runtime base de Q2, medido POSITIVO"
84  echo "   sello: $(cat "$OUT/sello.txt")"
85  echo "   build rc=$RC — $(tail -1 "$OUT/build.out" 2>/dev/null || echo '(sin hash)')"
86} | tee "$OUT/resumen.txt"
87exit "$RC"