From 642c170b6ac6d3db6c7173791d8e123202ed5b40 Mon Sep 17 00:00:00 2001 From: Sergio Date: Mon, 14 Sep 2026 14:32:04 +0000 Subject: [PATCH] =?UTF-8?q?docs(SDD=2023):=20=C2=A710=20=E2=80=94=20la=20m?= =?UTF-8?q?isma=20herida=20reabierta=20por=20el=20renombre,=20y=20el=20goc?= =?UTF-8?q?ryptfs=20sin=20causa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- docs/23-plan-rehasheo.md | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/docs/23-plan-rehasheo.md b/docs/23-plan-rehasheo.md index ed695760..592e202a 100644 --- a/docs/23-plan-rehasheo.md +++ b/docs/23-plan-rehasheo.md @@ -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` 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.