# Granja harkaq con volumen persistente + auto-shutdown La arquitectura que la 1ª campaña pidió (quedó idle ~4h cobrando). El worker no depende de que yo esté viva y no se queda idle. **Validado end-to-end 2026-07-16** (worker se auto-eliminó, volumen sobrevivió con las cosechas, helper efímero las recogió). ## Ciclo ```sh scripts/farm/harkaq-vol.sh up 2 # 2 workers midiendo → volumen; se auto-eliminan al agotar cola # ... (muelen la noche, se destruyen solos) ... scripts/farm/harkaq-vol.sh collect # (cuando esté viva) helper efímero baja las cosechas al hub scripts/farm/harkaq-vol.sh close # clausura el volumen (deja de cobrar) scripts/farm/harkaq-vol.sh status ``` ## Cómo funciona (y por qué así) - **Volumen `harkaq-cosecha`**: los workers escriben verdicts a `/mnt/cosecha`, que **sobrevive a su destrucción**. No dependo de estar viva para no perder el trabajo. - **Auto-shutdown**: tras `IDLE_CICLOS` ciclos con 0 mediciones nuevas, el worker **se auto-elimina vía API REST** (`curl` + metadata service; NO hcloud CLI, que la golden no trae). En Hetzner un server apagado **sigue cobrando** ⇒ apagar de verdad es `delete`. - **collect**: monta el volumen en un helper efímero barato (o un worker vivo), rsync al hub, lo destruye. Clasificar los verdicts es un paso aparte (el worker MIDE, el hub CLASIFICA con el store completo). ## Rastrillos que ya se pagaron (todos verificados en vivo) - **`--exclude /work` es crítico**: `work/` son 69GB; sin excluirlo el rsync del `up` cuelga horas. - **Tipo de server**: en hel1 los AMD `cpx*` dan "unsupported/stock"; `ccx13`/`ccx23` sí van. - **El token va al worker** (para auto-delete): riesgo acotado — efímero, sin servicios entrantes. - **`${1:?...}` sin llaves** en el mensaje: una `}` interna cierra la expansión. - El bucle **borra el artefacto `-hkm` tras medir** (envenenaba la caché en la 1ª campaña) y gatea por ABI≥7 + binario-con-jaula (no medir ciego). ## Un volumen se adjunta a UN server (2026-08-22, costó 21 G) `farm-up.sh N` crea N workers en un bucle y **todos apuntan al mismo `VOL_NAME`**. Como un volumen de Hetzner se adjunta a un único server, del segundo en adelante no queda nada que adjuntar. La campaña de reconstrucción corrió sharded (`SHARD=i/N`) en dos workers: hworker-1 tomó `harkaq-cosecha` y hworker-2 nació sin volumen, construyó el shard 1/2 entero en su disco raíz y el dead-man se lo llevó a las 03:27Z. **397 artefactos sellados, 584 sin copia en ningún otro sitio** (la lista quedó en `work/perdidos-hworker2.txt`). Lo caro no fue la falta de detección: `farm-up` **ya imprimía** `⚠ el store NO quedó en el volumen ⇒ lo que construya se PIERDE`. Lo imprimió esa noche, con esas palabras, y siguió adelante armando el dead-man y sembrando la cola. Un aviso que no detiene el pipeline no es un guardián cuando no hay nadie leyendo el log. Desde entonces `farm-up` **corta** (`sin_volumen()`): pregunta antes quién tiene el volumen tomado, ya no se traga el error del `attach`, y si el store no queda anclado borra el server recién creado (vacío, para no dejar un idle facturando) y sale 1. Para correr sharded hace falta **un volumen por worker**: ```sh VOL_NAME=harkaq-cosecha-1 scripts/farm/farm-up.sh 1 VOL_NAME=harkaq-cosecha-2 scripts/farm/farm-up.sh 1 SIN_VOLUMEN_OK=1 scripts/farm/farm-up.sh 1 # worker deliberadamente desechable ``` ## El latido en gioser va por cron, no por sesión `latido.sh` cuelga el bucle de **tu sesión de shell**, y eso es lo correcto *en el laptop*: no hay systemd y cronie sólo existe en uno de los dos arranques. En gioser la premisa se invierte — es un server, no hay sesión permanente, y crond sí corre. El mismo 2026-08-22 el rescate de hworker-2 dependía de que un agente estuviera despierto mirando, y la respuesta llegó después del auto-borrado. ```crontab */30 * * * * HOME=/home/sergio PATH=/usr/local/bin:/usr/bin:/bin /mnt/vvv/takana/scripts/farm/cosecha-cron.sh >>/mnt/vvv/takana/work/cosecha-cron.log 2>&1 ``` Rutas **absolutas** las dos: cron arranca en `$HOME`, así que una ruta relativa al script no resuelve y —peor— la redirección del log se abre en el directorio equivocado. El script hace su propio `cd "$ROOT"`, trae su `flock`, tolera workers ausentes y **no baja el store** (sólo el manifiesto de nombres) ⇒ no puede llenar el disco. Parar = borrar la línea. Lo que el latido **no** cubre: los artefactos siguen viviendo sólo en el volumen hasta que alguien haga una pasada de respaldo. El volumen tiene borrado protegido, pero es UNA copia. ## Parar de emergencia ```sh hcloud server list | grep hkw # ver workers hcloud server delete hkw-N # matar uno scripts/farm/harkaq-vol.sh close # y el volumen ```