docs(SDD 23): §10 — la misma herida reabierta por el renombre, y el gocryptfs sin causa
Deja escrito lo de hoy donde ya vivía el diagnóstico de esta clase de fallo (§9): el aprovisionamiento de `go` en el worker SE HIZO el 2026-08-28 y el renombre lo deshizo el 2026-09-09 sin que nada fallara. Con el método de detección (varias muriendo en segundos = sistémico; leer el error de UNA antes de contar deuda), la comprobación en los dos sentidos, y las cuatro sondas de `pgrep` que el mismo renombre dejó ciegas. Incluye el no-determinismo de `gocryptfs` con la hipótesis REFUTADA anotada como tal: no es el `cgo` (sq y usql también lo usan y reproducen) ni la ruta aleatoria del temporal (las cadenas son idénticas y difieren 1.874.136 bytes, desde .rodata). Queda abierto y sin causa; no está en ningún perfil, así que no bloquea imágenes.
This commit is contained in:
@@ -351,3 +351,70 @@ habla del rootfs DEL SANDBOX.
|
||||
|
||||
⇒ **Es una decisión de aprovisionamiento, no de arquitectura**, y desbloquea tres cuartas partes del
|
||||
catálogo para la granja.
|
||||
|
||||
## 10. 🔁 La misma herida, reabierta por el renombre (2026-09-14)
|
||||
|
||||
El §9 cerró con «es una decisión de aprovisionamiento, no de arquitectura». **Se tomó**: el
|
||||
2026-08-28 `bootstrap-devfs.sh` enlazó `go` en `~/.cargo/bin` del worker, que es lo que el fetch
|
||||
mira. Funcionó.
|
||||
|
||||
Y volvió a romperse **sin que nada fallara**. El enlace guardaba una ruta ABSOLUTA
|
||||
—`/opt/hammer/.dev-fs/tools/go/bin/go`— y el renombre hammer→takana (ADR 0016, 2026-09-09) movió el
|
||||
directorio. `ln -sfn` había dejado un enlace colgado, y el script imprimía «go enlazado ✓» sin
|
||||
comprobar nada. **Del 2026-09-09 al 2026-09-14 el worker no pudo construir ninguna receta Go.**
|
||||
|
||||
### Cómo se encontró, que es la parte reutilizable
|
||||
|
||||
Por casualidad, verificando reproducibilidad: **16 de 25 recetas Go murieron en SEGUNDOS**. Esa es
|
||||
la firma de un fallo SISTÉMICO, nunca la de 16 recetas rotas — es la misma pista que el disco lleno.
|
||||
El error lo decía entero:
|
||||
|
||||
Error: spawn go mod vendor: No such file or directory (¿está `go` en el PATH del host?)
|
||||
|
||||
pero `verificar-repro.sh` manda la salida del build a `/dev/null`, así que el informe sólo decía
|
||||
«no construyó». ⇒ **Ante un «no construyó», reproducir UNA a mano y leer el error** antes de
|
||||
escribir un número de deuda.
|
||||
|
||||
### Comprobado en los dos sentidos
|
||||
|
||||
Repuesto el enlace, `gron` pasó de no construir a construir **y reproducir bit a bit**
|
||||
(`why-differs`: 5 entradas idénticas, 0 divergen), y `checkmake` —que la tanda anterior había dado
|
||||
por «no construyó»— reproduce. No estaban rotas: faltaba el binario.
|
||||
|
||||
`cargo`, `git`, `patch`, `tar` y `curl` del worker se revisaron a la vez y están sanos: `cargo` es
|
||||
una instalación de rustup de verdad, no un enlace al repo, y por eso el renombre no lo tocó.
|
||||
|
||||
### Lo que se cambió para que no se repita
|
||||
|
||||
`bootstrap-devfs.sh` ya no da el enlace por bueno: repone el que esté colgado (avisando de a dónde
|
||||
apuntaba) y **comprueba que RESUELVE ejecutando `go version` a través de él**; si no ejecuta, sale 1
|
||||
con el síntoma escrito. Probado con un control que tiene que pasar y con dos roturas a propósito
|
||||
(enlace colgado a `/opt/hammer` ⇒ lo repone; destino inexistente ⇒ falla ruidoso).
|
||||
|
||||
Y de paso, el mismo renombre había dejado **ciegas cuatro sondas de proceso** que buscaban
|
||||
`release/hammer`: `estado-granja.sh` informaba «moliendo: (nada — idle)» con el worker compilando
|
||||
`centrifugo`, y el `hay_trabajo` del dead-man tampoco veía el build — en una caja hcloud eso es un
|
||||
worker borrado a mitad de un build. Las cuatro aceptan ahora los dos nombres.
|
||||
|
||||
> **La lección, que es nueva respecto de las tres del §7:** un renombre no rompe sólo lo que
|
||||
> compila. Rompe las cadenas que alguien escribió a mano —enlaces absolutos, patrones de `pgrep`,
|
||||
> rutas en scripts— y ésas no las mira ningún compilador. Lo que las encuentra es un guardián que
|
||||
> comprueba el EFECTO (¿corre `go`?, ¿veo el build?) en vez del gesto (¿creé el enlace?).
|
||||
|
||||
### Rendimiento de la campaña ese día
|
||||
|
||||
Con el worker devuelto al frente Go y el hub en la familia KDE Frameworks:
|
||||
|
||||
| frente | familia | reproducen | deriva | no-determinismo | no construyeron |
|
||||
|---|---|---|---|---|---|
|
||||
| hub | KF6 tier 1–3 (CMake) | 36 | 0 | 0 | 0 |
|
||||
| worker | Go | 17 | 2 | 1 | 0 |
|
||||
|
||||
El único no-determinismo real es `gocryptfs`, con los dos ejemplares guardados en
|
||||
`store/.divergen/`. **La hipótesis obvia se midió y salió FALSA**: se atribuyó al `cgo = true`
|
||||
—porque el temporal `go-build<aleatorio>` queda en el DWARF— pero las otras dos recetas con cgo del
|
||||
corpus, `sq` y `usql`, **reproducen**. Y mirado de cerca, la ruta aleatoria tampoco es la causa: los
|
||||
dos binarios tienen cadenas IDÉNTICAS salvo esas dos rutas, y sin embargo difieren en **1.874.136
|
||||
bytes** empezando dentro de `.rodata`. O sea que hay algo de orden/direcciones debajo, no una cadena
|
||||
horneada. Queda ABIERTO y sin causa; `gocryptfs` no está en ningún perfil y no tiene dependientes,
|
||||
así que no bloquea ninguna imagen.
|
||||
|
||||
Reference in New Issue
Block a user