SDD 28 §6.6: el lab es parte de la IDENTIDAD, y copiar un store con rsync -a lo revienta

**Un hub no es repo+store: es repo+store+LAB.** Con python3 ya vivo, `takana hash` en la caja seguía
fallando por el apk db del lab: el toolchain entra en el ArtifactHash, así que una máquina sin lab no
puede ni preguntar cuál es el hash vigente de una receta — no puede computar el grafo. Sembrado el
lab, el hash testigo coincide byte a byte en las dos máquinas (`zlib` → `b3:dc363f26…`).

**Y la primera copia del store murió con el disco lleno, dejando 1367 de 1368 artefactos VACÍOS.**
La puerta 2 corrida EN EL DESTINO lo cazó en el acto — para eso está.

La causa, medida sobre el store de gioser:

    du -sh                  60 G   (hardlinks contados UNA vez)
    du -sh --count-links    85 G   (hardlinks EXPANDIDOS)
    .dmerge                 11 G   (la caché que hardlinkea al store)

`rsync` sin `-H` NO preserva hardlinks: los expande en copias enteras. O sea que «el store son 60 G»
—lo que dice `du` y lo que uno planifica— son 85 G al copiarlo, más lo que `.dmerge` expanda. La
partición de 68,7 G no tenía ninguna chance.

La copia correcta es `rsync -aH --exclude='.dmerge'`. Y la lección general: **`du -sh` sobre un árbol
con hardlinks no dice cuánto ocupa COPIARLO**; para dimensionar hay que medir con `--count-links`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RomoxEGZUhaT4pob1QSX5x
This commit is contained in:
Sergio
2026-09-11 02:17:29 +00:00
co-authored by Claude Opus 5
parent 9a31857eaa
commit 0fd87745c6
+42
View File
@@ -627,6 +627,48 @@ sólo faltaba declararla en `base`.
publicado el sistema ya no depende del rootfs del lab. Estático seguiría siendo mejor (un binario
menos que puede quedar colgado de un soname), pero es un frente propio y ya no bloquea la mudanza.
### 6.6 Sembrar el hub: un hub no es repo+store, es repo+store+LAB
Con `python3` vivo, `takana hash` en la caja **seguía fallando**:
```
Error: no pude leer el apk db del lab en /.dev-fs/alpine/lib/apk/db/installed.
El toolchain entra en el ArtifactHash ⇒ sin rootfs no hay hash comparable.
```
**El lab es parte de la IDENTIDAD, no del entorno.** Una máquina sin él no puede ni preguntar «¿cuál
es el hash vigente de esta receta?», así que no puede computar el grafo ni decidir qué falta. Sembrado
el lab (tarball pineado + `tools/`, bajo `/store/dev-fs` porque la raíz son 6 G), el **hash testigo
coincide byte a byte**: `takana hash recipes/zlib.toml` da `b3:dc363f26…` en las dos máquinas.
**Y la caja no podía desempacar su propio lab**: el `tar` del rootfs es el de busybox y contesta
`tar: unrecognized option: zstd`. La distro comprime todo con zstd —la imagen del lab, el respaldo,
el `dd` remoto— y la imagen no traía el binario. `zstd` ya tenía receta sellada; declarado en `base`.
#### ⚠⚠ Copiar un store con `rsync -a` es una fábrica de vacíos, y ahora se sabe POR QUÉ
La primera copia murió con `No space left on device` en un `.so` de Qt, dejando el destino al 100 %
y **1367 de 1368 artefactos VACÍOS**. La puerta 2 corrida EN EL DESTINO lo cazó en el acto.
La causa, medida:
| medición sobre el store de gioser | |
|---|---:|
| `du -sh` (hardlinks contados UNA vez) | **60 G** |
| `du -sh --count-links` (hardlinks EXPANDIDOS) | **85 G** |
| `.dmerge` (la caché que hardlinkea al store) | **11 G** |
**`rsync` sin `-H` no preserva hardlinks: los expande en copias enteras.** Así que «el store son 60 G»
—que es lo que dice `du` y lo que uno planifica— se convierte en 85 G + lo que `.dmerge` expanda al
otro lado. La partición de 68,7 G no tenía ninguna chance, y el modo de fallar es el peor: el disco se
llena a mitad y quedan cientos de nombres de artefacto sin contenido, que el store da por presentes.
La copia correcta es **`rsync -aH --exclude='.dmerge'`**: `-H` preserva los enlaces (60 G reales) y
`.dmerge` no se copia porque es caché regenerable — la misma que ya llenó un disco en el worker.
**La lección de método**: `du -sh` sobre un árbol con hardlinks **no** dice cuánto ocupa copiarlo.
Para dimensionar una copia hay que medir con `--count-links`, o preservar los enlaces.
### 6.2 Lo que la mudanza tiene que producir, además de la mudanza
El usuario lo pidió explícito: **que este experimento saque recetas y las pruebe**. La caja vieja es