From ba3ed16169612bc35129a4fc1b5396c3beec591a Mon Sep 17 00:00:00 2001 From: Sergio Date: Thu, 17 Sep 2026 15:14:06 +0000 Subject: [PATCH] =?UTF-8?q?la=20caja=20ya=20es=20un=20HUB:=20el=20lab=20vi?= =?UTF-8?q?aj=C3=B3=20pineado,=20hashea=20igual,=20y=20el=20latido=20late?= =?UTF-8?q?=20desde=20all=C3=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit El §6.42 dijo qué faltaba y el usuario eligió darle el lab a la caja. Hecho. EL LAB NO SE COPIA, SE PINEA Y SE TRAE. `lab-image.sh` lo empaqueta determinista (--sort=name --mtime=@1 --owner=0, excluyendo var/log/apk.log), lo publica al Storage Box con el sha en el nombre, y `--traer` VERIFICA EL SHA ANTES DE EXTRAER. El empaquetado de hoy devolvió exactamente el sha que el repo ya pineaba (d1e341d5…): o sea que el lab de gioser nunca derivó Y que el empaquetado es reproducible de verdad, no una promesa del comentario. LA PRUEBA QUE DECIDE no es que arranque: la caja calcula los MISMOS ArtifactHash que gioser en las cuatro recetas de control (zlib, busybox, caddy, shuma-daemon). Con otro lab serían otros números y el store no lo notaría. ⚠ Y UNA TRAMPA QUE ME TENDÍ SOLO: al copiar los 24 artefactos que le faltaban al store de la caja, `rsync -a --files-from=` mandó 2.281 bytes y «total size is 0» — pero creó los 24 DIRECTORIOS VACÍOS. `--files-from` no recursa sin `-r`, y un directorio vacío en el store ES UN CACHE-HIT (§3 de CLAUDE.md): `build` lo habría dado por sellado sin construir. Detectado contando, borrados los 24, repetido con `-r`: 3,18 GB y 0 vacíos de 1655. Stores convergidos (copiados también obs-studio y spectacle, justo los dos que el worker no logra construir). La caja no empata, gana por uno: corpus 930 selladas / 1 deuda contra 929 / 2; KDE 1106 / 1 contra 1105 / 2. Latido mudado: cron apagado en gioser, encendido en la caja, y un ciclo corrido a mano mirando lo que publica — `repo al día (ff)` → `estado commiteado+pusheado` con los números buenos. ⚠ Lo que queda apretado es el disco: /store de la caja al 91%, 8,2 G libres. Un hub sella y cosecha: ése es el próximo muro, y `store-gc.sh` no se corrió nunca allá. ⇒ PUERTA 4 EN VERDE. De las ocho quedan dos a medias (5 y 7) y ninguna en rojo. Co-Authored-By: Claude Opus 5 (1M context) --- docs/28-servidor-de-produccion.md | 73 +++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/docs/28-servidor-de-produccion.md b/docs/28-servidor-de-produccion.md index 33cb855f..b594053c 100644 --- a/docs/28-servidor-de-produccion.md +++ b/docs/28-servidor-de-produccion.md @@ -2543,6 +2543,79 @@ tiene el lab— y vuelve a publicar los números buenos. No rompe nada, pero un `EPIPE` sin manejar en una herramienta de operación aparece justo cuando alguien la encadena. +### 6.43 🧪 La caja ya es un HUB: el lab viajó, y con él la puerta 4 *(2026-09-17)* + +El §6.42 dejó dicho qué faltaba y el usuario eligió: **darle el lab a la caja**. Hecho, y el latido +ya late desde allá. + +#### El lab no se copia: se PINEA y se trae + +`scripts/lab-image.sh` empaqueta `.dev-fs/alpine` de forma **determinista** (`--sort=name +--mtime=@1 --owner=0 --group=0 --numeric-owner`, excluyendo `var/log/apk.log`, que es lo único que +difiere entre dos labs por lo demás iguales), lo publica al Storage Box con el sha en el nombre, y +del otro lado `--traer` **verifica el sha antes de extraer**. Eso es lo que hace que las dos máquinas +hasheen igual, y es un contrato, no una copia. + +**Y el empaquetado de hoy devolvió el sha que el repo ya pineaba:** + +``` + empaquetado hoy en gioser : d1e341d5dd434a11e2290b0340069ce4a83563eac8e4481f379b4951b1162045 + pineado en bootstrap-devfs.sh: d1e341d5dd434a11e2290b0340069ce4a83563eac8e4481f379b4951b1162045 +``` + +O sea dos cosas de una: **el lab de gioser nunca derivó** desde que se publicó esa imagen, y **el +empaquetado es reproducible de verdad** — no era una promesa del comentario. + +#### La prueba que decide, y no es que arranque + +Con el lab instalado, la caja calcula los MISMOS `ArtifactHash` que gioser: + +``` + zlib b3:dc363f26… busybox b3:2a2b1280… + caddy b3:c915987d… shuma-daemon b3:f9b92acc… +``` + +Cuatro de cuatro. Si el lab fuera otro, estos números serían otros y el store no lo notaría — es el +agujero que `hash_inputs` cerró (§lab en el hash) y la razón por la que esto se verifica con hashes +y no con un «arrancó bien». + +#### Los stores, convergidos — y una trampa que me tendí solo + +El grafo seguía discrepando porque el store de la caja no tenía 24 artefactos vigentes de gioser +(3,0 G). Al copiarlos con `rsync -a --files-from=` pasó lo peor posible: + +``` + sent 2,281 bytes … total size is 0 ← no copió NADA + artefactos en la caja: 1631 → 1655 ← pero creó los 24 DIRECTORIOS +``` + +**`--files-from` no recursa sin `-r`**: creó 24 directorios vacíos en el store. Y un directorio vacío +en el store **es un cache-hit** (§3 de CLAUDE.md, [[artefacto-vacio-envenena-cache]]): `build` lo +habría dado por sellado y habría salido OK sin construir. Se detectó al contar, se borraron los 24 y +se repitió con `-r`: 3,18 GB transferidos, **0 vacíos de 1655**. + +Después faltaban dos más (`obs-studio` y `spectacle`, justo los que el worker no logra construir), +copiados también. Resultado: + +| | gioser | caja | +|---|---|---| +| corpus | sealed 929 · debt 2 | **sealed 930 · debt 1** | +| KDE | sealed 1105 · debt 2 | **sealed 1106 · debt 1** | + +La caja no empata: **gana por uno** en los dos grafos. + +#### El latido, mudado + +Cron apagado en gioser, encendido en la caja, y un ciclo completo corrido a mano para mirar lo que +publica: `==> repo al día (ff)` → `==> estado commiteado+pusheado`, con los números buenos. El +`build-state` que hay en `main` ahora lo escribió la caja. + +⚠ **Lo que queda apretado es el disco**: `/store` de la caja está al **91 %, 8,2 G libres**. Un hub +sella y cosecha, así que ése es el próximo muro — `scripts/store-gc.sh` es la herramienta y todavía +no se corrió allá. + +⇒ **puerta 4 en verde.** Con eso, de las ocho quedan sólo las dos a medias (5 y 7) y ninguna en rojo. + ## 7. Reusar los scripts que ya existen, y no escribir de nuevo Pedido explícito del usuario. El inventario de lo que ya hace el trabajo: