tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1506Shell 186Rust 107Markdown 983639 Sutichaykuna

SDD 28 §6.7: PUERTA 3 EN VERDE — los dos grafos idénticos byte a byte

    gioser: 7435d33d62577e8ce154e8c5e354e0465139cfbc632afe710076ea2223cea605
    caja:   7435d33d62577e8ce154e8c5e354e0465139cfbc632afe710076ea2223cea605

`base 61/61 · cli 84/84 · mirada 41/41 · servidor 96/96 · falta 0`, `wanted 3` (chrony, cronie,
logrotate: la deuda declarada), grafo CIERRA, topo-sort OK, en las dos máquinas. Es la prueba de que
un segundo hub está bien montado — no que "funcione".

Costó tres intentos y los dos fallos son la parte que vale:

1. **`unhashable 875`**, todas, con el lab bien y `takana hash` andando a mano. Los scripts asumen un
   árbol de DESARROLLO (`HAMMER = ROOT/target/release/takana`); en una caja instalada el binario es
   `/usr/bin/takana` y `target/` ni existe. No falla ruidosamente: sale el corpus entero como
   `unhashable`, que se lee como "este corpus no se puede hashear".
2. **Dos nodos divergentes** (`aichat`, `zola`): `sealed` en gioser, `never` en la caja. No era deriva
   ni pérdida — **tampoco están en disco en gioser**: son los 2 sellados avalados por los MANIFIESTOS
   (`work/farm-sellados.txt`, `work/respaldo-sellados.txt`). Y `work/` está gitignored, así que un hub
   recién sembrado no los tiene y degrada esos nodos en silencio.

Misma familia que `.fleet`: un fichero fuera de git del que depende una medición compartida.
**Sembrar un hub no es clonar el repo: es repo + store + lab + manifiestos.**

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RomoxEGZUhaT4pob1QSX5x

9a62f452d31c812d73cb841ec71dde623122a607 · ruwaq Sergio · (1 killa ñawpaq) · tayta 0fd87745c · kay commitpi sach'ata qhaway

Semántico sayk'uy

Mana ima sutichaypas t'ikrakurqanchu: qillqalla, yachachiylla utaq willaylla t'ikrakurqan.

1 qillqakuna · +45 −2

diff --git a/docs/28-servidor-de-produccion.md b/docs/28-servidor-de-produccion.md
index 0b305e1a..78897e37 100644
--- a/docs/28-servidor-de-produccion.md
+++ b/docs/28-servidor-de-produccion.md
@@ -517,8 +517,8 @@ diferencia es «cuánto de esto tengo en disco» y no «qué existe».
 |---|---|---|
 | 1 | arranca takana puro y se entra por SSH | ✅ §3.8 |
 | 2 | el store está entero | ✅ **1362 artefactos reales, 0 vacíos** |
-| 3 | los cuatro grafos idénticos | 🚧 **bloqueada** — ver §6.4 |
-| 4 | la granja late en la caja nueva | 🚧 bloqueada por lo mismo |
+| 3 | los cuatro grafos idénticos | ✅ **byte a byte** — §6.7 |
+| 4 | la granja late en la caja nueva | pendiente (ya no bloqueada: §6.5) |
 | 5 | el repo se sirve y el host se actualiza de sí mismo | ⬖ mitad: sirve (§5.1), no consume (§5.4) |
 | 6–8 | dominios vivos · respaldo · fósiles decididos | pendientes |
 
@@ -669,6 +669,49 @@ La copia correcta es **`rsync -aH --exclude='.dmerge'`**: `-H` preserva los enla
 **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.
 
+#### Y el instrumental apunta al binario de DESARROLLO, no al instalado
+
+La primera corrida de `build-state.py` en la caja devolvió **875 recetas `unhashable`** — todas —
+con el lab bien sembrado y `takana hash` funcionando a mano. La causa:
+
+```python
+HAMMER = os.environ.get("HAMMER", str(ROOT / "target/release/takana"))
+```
+
+Los scripts asumen un **árbol de desarrollo**: `target/release/takana`. En una caja **instalada** el
+binario es `/usr/bin/takana` y `target/` ni existe (la siembra lo excluye a propósito). No falla
+ruidosamente: cada `hash` falla y el grafo sale entero como `unhashable`, que se lee como «este
+corpus no se puede hashear» y no como «no encontré el binario».
+
+Se destraba con `HAMMER=/usr/bin/takana STORE=/store`, que la propia cabecera del script documenta.
+Pero la deuda queda anotada: **el instrumental debería caer a `command -v takana`** antes de rendirse,
+porque el caso «hub instalado» es justamente el que esta mudanza quiere que exista.
+
+### 6.7 ✅ PUERTA 3 EN VERDE: los dos grafos, idénticos byte a byte
+
+```
+gioser: 7435d33d62577e8ce154e8c5e354e0465139cfbc632afe710076ea2223cea605
+caja:   7435d33d62577e8ce154e8c5e354e0465139cfbc632afe710076ea2223cea605
+```
+
+`base 61/61 · cli 84/84 · escritorio-mirada 41/41 · servidor 96/96 · falta 0`, `wanted 3`
+(`chrony`, `cronie`, `logrotate` — la deuda declarada), grafo CIERRA, topo-sort OK. Las dos máquinas.
+
+**Costó tres intentos, y los dos fallos son la parte que vale.**
+
+**Intento 1 — `unhashable 875`**, todas. Ver arriba: los scripts apuntan a `target/release/takana`.
+
+**Intento 2 — dos nodos divergentes**: `aichat` y `zola`, `sealed` en gioser y `never` en la caja. No
+era deriva ni pérdida: **ninguno de los dos está en disco en gioser tampoco**. Son los «2 sellados
+que no están en esta máquina, avalados por los manifiestos» que el propio resumen imprime.
+`build-state.py` lee `work/farm-sellados.txt` y `work/respaldo-sellados.txt` — y **`work/` está
+gitignored**, así que un hub recién sembrado no los tiene y degrada esos nodos a `never` sin que nada
+falle.
+
+Es la misma familia que `scripts/farm/.fleet`: **un fichero fuera de git del que depende una medición
+compartida**. La regla que sale: *sembrar un hub no es clonar el repo — es repo + store + lab +
+los manifiestos*. Copiados los dos ficheros, los grafos coinciden exactamente.
+
 ### 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