SDD 26 §3.quinquies: el PGO encendido y los tres muros que el plan no tenía

El §3.ter daba dos muros —el display y el no-determinismo del perfil— y los dos
eran ciertos. Aparecieron tres más, ninguno visible sin construir:

  1. libclang_rt.profile.a no existía: el lab trae clang pero NINGUNA runtime de
     compiler-rt. El instrumentado murió en el minuto 38:56.
  2. Los sandboxes de Firefox matan la corrida de perfilado con signal 11: el
     proceso que renderiza no nace, 0 GET, y el .profraw que queda es el del
     padre arrancando. Un perfil de nada, con todo en verde.
  3. El worker no puede bajar del mirror: tiene mirror-env.sh pero no la clave.

Y queda escrito cómo se verificó que el PGO llegó, que NO pudo ser como RLBox.
Ahí el artefacto delata la jaula (símbolos w2c_*, cero -> 634). Acá el
discriminante análogo —las secciones .text.hot que clang emite al particionar
por temperatura— NO SIRVE: con lld y ThinLTO el enlazador las fusiona y dan cero
con PGO y sin él. La evidencia válida está un nivel bajo el configure: 189
invocaciones del compilador con -fprofile-use, llvm-profdata encontrado, cero
avisos de perfil que no cuadra, y libxul creciendo 1,7 MB.

Es evidencia de BUILD y no de ARTEFACTO, y conviene decirlo así en vez de
presentarla como si fuera lo mismo.
This commit is contained in:
Sergio
2026-09-07 11:16:13 +00:00
parent bf6e5ce5cb
commit 024ebc52d2
+31 -1
View File
@@ -197,6 +197,36 @@ bit-repro; a nosotros nos rompe el invariante. La salida: **generar el perfil UN
artefacto propio, consumido por hash** desde `firefox`. El build optimizado vuelve a ser determinista
aunque su insumo no lo sea, y el perfil se regenera a propósito, no por accidente.
### 3.quinquies El PGO, y los tres muros que el plan no tenía escritos (2026-09-07)
El §3.ter daba dos muros: el display (X11 que no tenemos) y el no-determinismo del perfil. Los dos
eran ciertos. Aparecieron **tres más**, y ninguno se ve sin construir:
1. **`libclang_rt.profile.a` no existía.** El lab trae clang 22.1.8 pero **ninguna runtime de
compiler-rt** — su `lib/` del resource dir ni existe, exactamente como ya documentaba
`wasi-compiler-rt` para el caso wasm. El build instrumentado murió en el minuto 38:56 con
`ld.lld: cannot open …/libclang_rt.profile.a`. De ahí sale `recipes/compiler-rt-profile.toml`.
2. **Los sandboxes de Firefox matan la corrida de perfilado.** Con ellos puestos los procesos hijo
mueren con **signal 11**, el que renderiza no llega a nacer, el servidor local registra **0 GET**
y el único `.profraw` que queda es el del padre arrancando — un perfil de nada, con todo en
verde. Es lo mismo que hace el `profileserver.py` de Mozilla. Sólo aplica a la corrida de
entrenamiento: el firefox que se distribuye lleva sus sandboxes intactos.
3. **El worker no puede bajar del mirror de fuentes.** Tiene `scripts/fuentes/mirror-env.sh` desde
el 2026-09-01 pero no la clave del Storage Box, así que una receta pineada al mirror —y el perfil
es la primera— no se construye allá. Se sembró el artefacto sellado, que es content-addressed:
consigue lo mismo sin mover una credencial de máquina.
**Cómo se verificó que el PGO llegó, y por qué NO como RLBox.** Con RLBox el artefacto delata la
jaula (símbolos `w2c_*`, cero → 634). Acá el discriminante análogo serían las secciones
`.text.hot`/`.text.unlikely` que clang emite al particionar por temperatura — y **no sirve**: con
lld y ThinLTO el enlazador las fusiona, así que dan cero en el binario con PGO y sin él. La
evidencia que sí vale está un nivel por debajo del `configure`: **189 invocaciones del compilador
llevan `-fprofile-use`**, el configure encontró `llvm-profdata`, y no hay ni un aviso de perfil que
no cuadre. `libxul.so` pasa de 226.078.752 a 227.802.816 bytes, consistente con inlining de caminos
calientes. Es evidencia de build, no de artefacto, y conviene decirlo así.
### 3.quater La cadena wasm, y las tres cosas que costó (2026-09-06)
`--without-wasm-sandboxed-libraries` se cambió por `--with-wasi-sysroot=/usr/share/wasi-sysroot`,
@@ -667,7 +697,7 @@ siguiente.
| 1 | **`waterfox` SELLA** ✅ 2026-09-06 — `b3:88b5a762`, 377 M, BuildID determinista **y REPRODUCE bit a bit**. Cuatro muros, **ninguno de la receta**: hammer viejo en el worker, el watchdog barriendo el post-mortem, deps estáticas vs. el cairo bundleado, y una rotura de upstream sólo-Linux | valida la tesis del reúso | — |
| 2 | ~~`llvm-toolchain`~~**`apk add lld` + `compiler="clang"`** ✅ 2026-09-05 | LTO **y** el muro 3 | — |
| 3 | Construir el `firefox` con LTO (hash `b3:6f2a3b2f`) | el eje de velocidad **y** las extensiones de `atuq` | 2 ✅ |
| 3.a | PGO: perfil bajo sway headless, **sellado como artefacto propio** y consumido por hash | la otra mitad de la ganancia | 3 |
| 3.a | **PGO ENCENDIDO** ✅ 2026-09-07 — perfil de 501.521 funciones recogido bajo headless, publicado en el mirror y pineado por sha256; 189 compilaciones con `-fprofile-use`. Sin `jarlog` todavía | la otra mitad de la ganancia | 3 |
| 3.b | **RLBox ENCENDIDO** ✅ 2026-09-06 — cadena wasm de CINCO recetas selladas + guardián que la exige en el binario; firefox sellado **y REPRODUCE bit a bit** (`verificar-repro.sh`: 0 no-determinismos) | cierra el hueco de seguridad del §3.bis | 2 ✅ |
| 4 | **`atuq`: receta derivada + overlay de chrome** ✅ v0.1 escrita | el andamio de todo lo demás | 3 |
| 4.b | Branding + re-empaque de `omni.ja` ✅ v0.2 | el chrome de verdad | — |