diff --git a/recipes/aichat.toml b/recipes/aichat.toml index 00017165..5da12e2b 100644 --- a/recipes/aichat.toml +++ b/recipes/aichat.toml @@ -17,4 +17,33 @@ link = "static" flags = ["--bin", "aichat"] [build.phases] +# ── ⚠ SIN ESTO, aichat NO ES REPRODUCIBLE ────────────────────────────────────────────────────── +# Medido el 2026-09-05 con `scripts/verificar-repro.sh`: dos reconstrucciones seguidas, misma +# máquina y mismo lab, dan `usr/bin/aichat` distintos en `.rodata`. El primer byte que cambia cae +# dentro de un JSON de *stopwords* por idioma embebido en el binario, y lo que difiere es el ORDEN +# de los idiomas — una build empieza por `"sl"`, la otra por `"fi"`. +# +# La causa está en el `build.rs` del crate `stop-words` 0.8.1 (transitivo, vía bm25): arma un +# `HashMap>` y lo serializa con `serde_json::to_string`. El `HashMap` de Rust +# usa `RandomState`, o sea una semilla ALEATORIA POR PROCESO ⇒ el orden de serialización cambia en +# cada compilación, y ese JSON se hornea en el binario. `BTreeMap` serializa en orden de clave y es +# determinista; es un arreglo de una palabra que upstream no hizo. +# +# El `.cargo-checksum.json` se vacía por la misma razón que en `recipes/firefox.toml`: cargo +# verifica el sha de CADA fichero vendorizado y no ofrece forma de recalcularlo, así que se deja el +# checksum del paquete y se vacía la lista de ficheros (lo mismo hace el APKBUILD de Alpine). +# +# Los `[ -f ]` fallan RUIDOSO a propósito: si mañana la cadena de deps deja de traer stop-words, lo +# que no queremos es que el parche se salte en silencio y el binario vuelva a ser aleatorio sin que +# nadie se entere — que es exactamente cómo esto llegó hasta acá. +configure = ''' +set -e +f=vendor/stop-words/build.rs +[ -f "$f" ] || { echo "FALTA $f — ¿cambió la cadena de deps? Ver la nota de arriba." >&2; exit 1; } +sed -i 's/HashMap/BTreeMap/g' "$f" +grep -q 'BTreeMap>' "$f" || { echo "el sed no agarró en $f" >&2; exit 1; } +c=vendor/stop-words/.cargo-checksum.json +[ -f "$c" ] || { echo "FALTA $c" >&2; exit 1; } +sed -i 's/\("files":{\)[^}]*/\1/' "$c" +''' install = "mkdir -p /out/usr/bin && cp target/release/aichat /out/usr/bin/aichat"