La primera instalación real de un paquete en la caja (`takana install zsh`, sin --prefix) dejó el
sistema A MEDIAS: `commit` desmontó 5 de 7 targets y murió con `target is busy` en /bin, con dos
overlays montados y el estado sin promocionar. La causa no es un fd abierto: los procesos tienen su
EJECUTABLE mapeado desde /bin y /usr/bin —empezando por PID 1, /usr/bin/arje-zero— y un ejecutable
mapeado pin-ea el montaje. En un FHS vivo eso no se puede evitar esperando.
El comentario de `do_umount_lenient` prometía el desmontaje perezoso «desde la Fase 2» y el código
NUNCA pasaba `-l`. Ahora, ante `busy`, reintenta perezoso: desengancha el montaje ya mismo (las
rutas vuelven a resolver al directorio real, que es lo que el promote necesita) y libera cuando el
último proceso que lo miraba se muere; los vivos ven el mismo contenido porque el commit copia el
upper al lower justo después.
Probado en la caja con un paquete nuevo: install tree ⇒ overlay; commit ⇒ WARN del perezoso sobre
/usr/bin y «commit OK — 1 archivo(s) promocionados»; 0 overlays, /usr/bin/tree real, tree v2.3.2.
El SDD 28 §5.10 anota las otras cuatro cosas que ese `sudo takana install zsh` destapó: el repo por
defecto que no existía, el lab que no se encontraba desde /root, el binario del sistema incapaz de
leer los .tkn nuevos, y —la peor— que la instalación queda PARTIDA porque el overlay cubre siete
directorios y /usr/share no es uno: 1296 de los 1331 ficheros fueron directos al FHS real mientras
2 binarios esperaban el commit, y el mensaje decía `apply OK` igual.
205 lineas en 73 ficheros de crates, mas la prosa de CLAUDE.md y del skill,
que se me habian quedado afuera de los barridos anteriores (no eran ni recetas
ni docs/ ni scripts/).
EL BARRIDO ANCHO ESTUVO A UN COMMIT DE ROMPER EL CORPUS ENTERO.
El primer intento reescribia los .rs completos, no solo los comentarios. Entre
las lineas de codigo que tocaba estaban SIETE etiquetas de separacion de
dominio, que son ENTRADA DE HASH:
b"hammer-tree-v1" <- el prefijo de ArtifactHash::of_tree (hash.rs:60)
b"hammer-seed-v1" la funcion que hashea TODOS los artefactos:
b"hammer-stage1-rootfs-v2" cambiarla mueve los 4750 hashes del store
b"hammer-product-rootfs-v3"
b"hammer-product-attested-v2"
b"hammer-builder-rootfs-v1"
b"hammer-attest-dev-rootkey-0001!!" <- clave raiz de atestacion, [u8;32]
Revertido y rehecho solo sobre comentarios, esquivando ademas las cadenas
crudas de Rust (r#"..."#) porque el SYSTEM_PROMPT del traductor tiene lineas
que empiezan como comentario.
Controles: las 7 etiquetas siguen ahi, el diff toca CERO lineas de codigo,
605 tests en verde y el hash de zlib sigue en b3:dc363f26.
La leccion es la misma de toda esta etapa: un literal que parece prosa puede
ser entrada de hash, y la unica forma de saberlo es mirar donde se usa.
hammer-{core,build,bootstrap,overlay,journal,mirror,upgrade,agent,recover,cli}
→ takana-*, con sus deps de workspace, sus identificadores en el fuente y las
referencias -p de los scripts.
VERIFICADO que no mueve nada del corpus: `takana hash recipes/zlib.toml`
devuelve b3:dc363f26… , idéntico a antes del renombre. Los nombres de crate no
entran en hash_inputs, pero eso se comprueba, no se supone. 600 tests en verde.
DOS BINARIOS SE CONGELAN, y no por prolijidad:
- `hammerd` — paquete Y binario. Es componente de Stage 1 de la distro (musl,
busybox, hammerd, arje-zero), lo supervisa arje-zero en el sistema arrancado,
`PRESEED=hammerd` lo nombra en selfhost-verify y sus bytes anclan el baseline
of_tree. El nombre del crate va en los símbolos ⇒ renombrarlo mueve los bytes.
- `hammer-recover` — el PAQUETE se renombra a takana-recover, el BINARIO no.
hammer-live-install.sh lo copia a /usr/sbin/hammer-recover en sistemas ya
instalados y hornea un hook de arranque que lo invoca por ese nombre:
renombrarlo rompe máquinas instaladas, no el repo.
Consecuencia que hay que anotar igual: al renombrar hammer-core, los bytes de
hammerd cambian de todos modos porque linkea contra un crate con otro nombre.
El baseline of_tree del selfhost hay que rehacerlo — es efecto de la etapa 4,
no de un cambio de hammerd.
Las referencias en comentarios de recetas y docs (rutas hammer-core/src/…)
quedan para la etapa 5: son texto, no mueven hash.