gioser

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 1471Shell 173Rust 105Markdown 943545 Sutichaykuna

las fuentes git se traen por ssh — y la raíz de 5,9 G tiró la caja entera

La caja no tiene git-remote-http, así que las 36 recetas que clonan de git.tawasuyu.net y las ~90 de
GitHub no se podían construir ahí. La salida es usar SSH, y sale gratis en hashes porque la URL es un
LOCALIZADOR y no entra en hash_inputs (ADR 0013): mismo commit por otro transporte, mismo artefacto.
No se toca ninguna receta —el worker sigue por HTTPS— sino la caja, con dos `url.insteadOf`.

Tres cosas medidas: (1) cargo vendor clona aparte y con su propio cliente ssh —se plantó por la clave
del host, que la tenía con puerto y cargo la busca sin él, y después por autenticación— y se resuelve
con `net.git-fetch-with-cli = true`; (2) la huella de github.com se PINEA contra la publicada, no se
acepta a ciegas; (3) CARGO_HOME estaba en /root/.cargo, o sea en la raíz de 5,9 G: el vendor bajó
2,7 G, la raíz llegó al 100 % y la caja NO se degradó, se cayó entera —sin HTTP, sin SSH y sin
responder al ping, con Hetzner informando «running»—. Rescate otra vez.

Rastro que deja un ENOSPC y que conviene saber leer: caddy escupiendo «no space left on device», y
mis propios `>>` dejando 105 bytes NULOS al final de /root/.ssh/config —un append que falla por
ENOSPC no deja el fichero como estaba: lo deja extendido y relleno de ceros—.

Reparado en el rescate y permanente: /root/.cargo → /work/cargo-home, poda horaria de logs
(ente-gitea.log había llegado SOLO a 114 M y nadie lo rotaba) y los dos configs reescritos. Tras el
arranque: raíz al 54 %, 18 entes corriendo, los 7 dominios de la caja en 200.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

8d1e765bf7a8d419a77237e02bdc91ad488f8063 · ruwaq Sergio · (1 killa ñawpaq) · tayta f13f4f542 · kay commitpi sach'ata qhaway

Semántico sayk'uy

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

1 qillqakuna · +65 −0

diff --git a/docs/28-servidor-de-produccion.md b/docs/28-servidor-de-produccion.md
index 0fb66f29..b33e51db 100644
--- a/docs/28-servidor-de-produccion.md
+++ b/docs/28-servidor-de-produccion.md
@@ -3027,6 +3027,71 @@ Las recetas del corpus que bajan tarballs con `curl` **sí** construyen ahí (ho
 construirlas en el worker, que sí tiene git completo. Arreglar eso es re-sellar `git` con libcurl, y
 es raíz de `perfil.base`: unidad propia.
 
+### 6.50 quinquies 🔑 Las fuentes git se traen por SSH — y la raíz de 5,9 G tiró la caja entera *(2026-09-17)*
+
+El §6.50 quater dejó anotado el muro: la caja no tiene `git-remote-http`, así que las 36 recetas que
+clonan de `git.tawasuyu.net` —y las ~90 de GitHub— no se podían construir ahí. La salida es la que
+pidió el usuario: **usar SSH**. Y sale gratis en hashes, porque **la URL es un LOCALIZADOR y no entra
+en `hash_inputs`** (ADR 0013): el mismo commit por otro transporte sella el mismo artefacto.
+
+No se toca ninguna receta —el worker sigue clonando por HTTPS, que es lo que puede— sino la caja:
+
+```
+  git config --global url."ssh://gitea@git.gioser.net:2345/".insteadOf "https://git.tawasuyu.net/"
+  git config --global url."ssh://git@github.com/".insteadOf        "https://github.com/"
+```
+
+Tres cosas que costaron una vuelta cada una, las tres MEDIDAS:
+
+1. **`takana` clona bien, pero `cargo vendor` clona aparte.** cargo honra el `insteadOf`, pero usa su
+   propio cliente SSH: primero se plantó por la clave del host —la tenía como `[git.gioser.net]:2345`
+   y cargo la busca **sin puerto**, misma clave reexpresada— y después por autenticación, porque no
+   sabe leer `IdentityFile` de `~/.ssh/config`. Se resuelve delegando en el git de verdad:
+
+   ```toml
+   # ~/.cargo/config.toml
+   [net]
+   git-fetch-with-cli = true
+   ```
+
+2. **La huella de `github.com` se PINEA, no se acepta a ciegas.** `ssh-keyscan` dio
+   `SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU`, idéntica a la que GitHub publica, y **por eso**
+   entró a `known_hosts`. La clave de esta caja autentica como deploy key de otro repo y aun así lee
+   repos públicos ajenos: comprobado con `uutils/coreutils`.
+
+3. **Y la que dolió: la raíz son 5,9 G y `cargo` la llenó.** `CARGO_HOME` estaba en `/root/.cargo`, o
+   sea en `sda2`. El vendor del monorepo bajó 2,7 G, la raíz llegó al **100 %**, y la caja **no se
+   degradó: se cayó entera** — sin HTTP, sin SSH y **sin responder al ping**, con Hetzner informando
+   `running`. Hubo que entrar por rescate otra vez.
+
+   Lo que el disco lleno deja como rastro, y conviene saber leer:
+
+   ```
+     caddy   → «write error: write /var/log/caddy/requests.json: no space left on device»
+     mis     → /root/.ssh/config quedó con 105 BYTES NULOS al final: el append entró a medias
+     escrituras  (el mismo daño que el corte de luz le hizo al reglaset del cortafuegos, §6.51)
+   ```
+
+   **Un `>>` que falla por ENOSPC no deja el fichero como estaba: lo deja extendido y relleno de
+   ceros.** Es exactamente la clase de avería que el §3 de `CLAUDE.md` describe para los artefactos
+   vacíos — llega hasta el final diciendo que todo fue bien.
+
+**Reparado en el rescate, y las tres piezas son permanentes:**
+
+| qué | dónde | por qué |
+|---|---|---|
+| `/root/.cargo` → `/work/cargo-home` | symlink | 2,7 G de caché no caben en una raíz de 5,9 G |
+| poda horaria de logs | `/usr/local/sbin/poda-logs.sh` + cron `17 * * * *` | `ente-gitea.log` había llegado **solo** a 114 M y **nadie lo rotaba** |
+| `.ssh/config` y `.gitconfig` | reescritos | tenían NULs de las escrituras a medias |
+
+Tras el arranque: raíz al **54 %**, los 18 entes corriendo y **los 7 dominios de la caja en 200**
+(`terapeuta.ec` sigue en gioser a propósito — se decidió respaldar, no mudar).
+
+> **La lección, que no es sobre cargo.** La raíz de esta caja es **5,9 G** y todo lo que crece sin
+> dueño vive ahí: logs, cachés, spool. No hay margen para «ya lo limpio después», y el modo de fallo
+> no es un error: es la máquina entera apagándose en silencio. Cualquier cosa que acumule bytes en la
+> caja **se declara dónde vive antes de correrla por primera vez**.
+
 ### 6.51 🔥 Me dejé afuera de la caja — 20 minutos caída, y tres causas encadenadas *(2026-09-17)*
 
 Crear una cuenta de usuario tiró el servidor de producción. Queda escrito entero porque **ninguna de