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…
etapa 4: primera tanda desplegada y verificada (3/3) + el desplegador por tandas
1#!/usr/bin/env bash
2# desplegar-strip.sh — activa `strip_debug = true` por TANDAS. Etapa 4 del SDD 23.
3#
4# ── QUÉ HACE Y POR QUÉ POR TANDAS ──────────────────────────────────────────────────────────────
5# Activar el split de debug re-hashea la receta A PROPÓSITO (cambia el contenido del artefacto), y
6# re-hashea en cascada todo lo que dependa de ella. Hacerlo de golpe sobre 1161 recetas dejaría el
7# corpus entero sin sellar a la vez: días de granja antes de poder verificar NADA, y el disco
8# aguantando artefactos viejos y nuevos al mismo tiempo.
9# Por tandas se puede medir, verificar y podar entre medias, que es lo que hace la campaña
10# reversible en vez de un salto a ciegas.
11#
12# ── LA DEP DE `binutils` VA EXPLÍCITA, NO INYECTADA POR EL LAB ──────────────────────────────────
13# El paso de strip usa `strip --strip-debug -D` de binutils. Se podría hacer que el lab lo
14# materialice solo, sin tocar las recetas — pero entonces la VERSIÓN de binutils sería un input
15# invisible: dos corridas con binutils distintos darían artefactos distintos con el mismo hash. Los
16# `deps` SÍ entran en `hash_inputs`, así que declararlo es lo único que mantiene el invariante.
17# Cuesta una edición mecánica por receta; el invariante no se negocia por comodidad.
18#
19# ── EXCLUSIONES, y por qué exactamente éstas ───────────────────────────────────────────────────
20# `binutils` y `make`: binutils provee el `strip`, y depende de make. Si se les activara el split se
21# necesitarían a sí mismos para construirse. No es una preferencia: es la circularidad.
22#
23# Uso: scripts/desplegar-strip.sh --tanda N [--aplicar]
24# (sin --aplicar sólo lista lo que haría)
25set -uo pipefail
26ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
27N="${N:-25}"; APLICAR=0
28while [ $# -gt 0 ]; do
29 case "$1" in
30 --tanda) N="$2"; shift 2 ;;
31 --aplicar) APLICAR=1; shift ;;
32 *) echo "opción desconocida: $1" >&2; exit 2 ;;
33 esac
34done
35
36EXCLUIDAS="binutils make"
37
38candidatas=""
39for f in recipes/*.toml; do
40 [ -f "$f" ] || continue
41 n=$(basename "$f" .toml)
42 case " $EXCLUIDAS " in *" $n "*) continue ;; esac
43 grep -q 'strip_debug' "$f" && continue # ya desplegada
44 grep -q 'CERRADA POR DECISIÓN' "$f" && continue # no se toca lo cerrado
45 grep -qE '^link\s*=' "$f" || continue # sin línea link no sé dónde insertar
46 candidatas="$candidatas $f"
47done
48
49total=$(echo $candidatas | wc -w)
50tanda=$(echo $candidatas | tr ' ' '\n' | head -"$N")
51echo "==> candidatas totales: $total · esta tanda: $(echo $tanda | wc -w)"
52[ "$APLICAR" = 1 ] || { echo "$tanda" | tr ' ' '\n' | head -10 | sed 's|^| |'; echo "==> DRY-RUN: nada tocado. Repetí con --aplicar."; exit 0; }
53
54hechas=0
55for f in $tanda; do
56 python3 - "$f" <<'PY'
57import re, sys
58p = sys.argv[1]; s = open(p).read()
59m = re.search(r'^(link\s*=\s*"[a-z]+")\s*$', s, re.M)
60if not m: sys.exit(0)
61s = s[:m.end(1)] + '\n\n# Split de la info de depuración (SDD 23 etapa 4). Entra en `hash_inputs`: re-hashea a propósito.\nstrip_debug = true' + s[m.end(1):]
62# binutils en deps: el paso de strip del lab usa su `strip --strip-debug -D`.
63if '"binutils"' not in s:
64 if re.search(r'^build\s*=\s*\[', s, re.M):
65 s = re.sub(r'^build\s*=\s*\[', 'build = ["binutils", ', s, count=1, flags=re.M)
66 elif '[deps]' in s:
67 s = s.replace('[deps]', '[deps]\nbuild = ["binutils"]', 1)
68 else:
69 s = s.rstrip('\n') + '\n\n[deps]\nbuild = ["binutils"]\n'
70open(p, 'w').write(s)
71PY
72 hechas=$((hechas+1))
73done
74echo "==> $hechas recetas con strip_debug=true (+ dep binutils)"
75echo "==> siguiente: construir la tanda en la granja y verificar con scripts/verificar-repro.sh"