takana: el worker pasa a /opt/takana y takana-farm.service
Renombrado el directorio del worker y la unit, con las tres units del repo (farm, deadman service y timer). Todas las rutas /opt/hammer del hub pasan a /opt/takana: eran defaults REMOTE= y HAMMER_DIR=, mas los systemctl/journalctl que nombraban la unit sin el sufijo .service, que el primer sed no casaba. Orden, para que no quedara partido: el hub siembra por rsync a una ruta fija, asi que se saco el cron ANTES de mover. Si se movia el worker con el hub apuntando a la ruta vieja, la siguiente cosecha recreaba /opt/hammer y quedaban dos arboles. Verificado de punta a punta: - el worker cerro un ciclo de build REAL desde /opt/takana (dunst sellado, 1/1) - una cosecha completa del hub contra la ruta nueva: siembra, manifiesto, los nueve grafos, static-audit (691 estaticos, MIENTEN 0) y estado pusheado - la unit vieja quedo deshabilitada y borrada; /opt tiene una sola entrada NO se tocan dos referencias a /opt/hammer que siguen siendo CORRECTAS: docs/23-plan-rehasheo.md describe rutas EMBEBIDAS en artefactos ya construidos —que literalmente dicen /opt/hammer/work en sus secciones .debug— y el HANDOFF de la noche de KDE es registro. Cambiarlas haria que los documentos mientan.
Delta semántico
Ninguna definición cambió: el cambio es de texto, documentación o datos.
28 archivos · +132 −132
- docs/adr/0016-renombre-takana.md +4 −4
- scripts/consenso.sh +2 −2
- scripts/farm/campana-deuda.sh +3 −3
- scripts/farm/cosecha-cron.sh +3 −3
- scripts/farm/deadman.sh +7 −7
- scripts/farm/estado-granja.sh +1 −1
- scripts/farm/farm-down.sh +2 −2
- scripts/farm/farm-lab-sync.sh +1 −1
- scripts/farm/farm-run.sh +1 −1
- scripts/farm/farm-sync.sh +2 −2
- scripts/farm/farm-up.sh +10 −10
- scripts/farm/farm-worker-loop.sh +2 −2
- scripts/farm/hammer-deadman.service +0 −10
- scripts/farm/hammer-deadman.timer +0 −18
- scripts/farm/hammer-farm.service +0 −46
- scripts/farm/harkaq-campana-vol.sh +1 −1
- scripts/farm/harkaq-campana.sh +1 −1
- scripts/farm/harkaq-vol.sh +1 −1
- scripts/farm/harvest-go.sh +2 −2
- scripts/farm/harvest-harkaq.sh +1 −1
- scripts/farm/takana-deadman.service +10 −0
- scripts/farm/takana-deadman.timer +18 −0
- scripts/farm/takana-farm.service +46 −0
- scripts/farm/tandas.sh +3 −3
- scripts/farm/vps-setup.sh +7 −7
- scripts/farm/worker-depositar.sh +1 −1
- scripts/harkaq/harkaq-farm-setup.sh +1 −1
- scripts/yupana.py +2 −2
diff --git a/docs/adr/0016-renombre-takana.md b/docs/adr/0016-renombre-takana.md
index 8543f8ff..2133bd1f 100644
--- a/docs/adr/0016-renombre-takana.md
+++ b/docs/adr/0016-renombre-takana.md
@@ -93,7 +93,7 @@ simplemente deja de cosechar. El directorio es lo **último** que se toca, y con
- ADRs y docs de diseño: texto, y `hammer` sigue funcionando. Van con la etapa 5.
**Cómo converge el worker** (medido el 2026-09-09, no supuesto). Su checkout vive en
- `/opt/hammer`, **no es un clon git** —lo pone el rsync de la siembra— y `hammer-farm.service`
+ `/opt/hammer`, **no es un clon git** —lo pone el rsync de la siembra— y `takana-farm.service`
está `enabled` allá, corriendo `farm-worker-loop.sh` como servicio largo. En el momento del
cambio el worker tenía scripts viejos y binario del 6-sep: **coherente**. Los dos estados
intermedios también lo son, y por eso la 3a iba primero:
@@ -105,7 +105,7 @@ simplemente deja de cosechar. El directorio es lo **último** que se toca, y con
La unit apunta a la RUTA DEL SCRIPT, no al binario, así que nada de la etapa 3 la toca. El
nombre del fichero de unit y `/opt/hammer` son etapa 6.
- **Convergido y comprobado (2026-09-09 18:40–18:45Z).** Reiniciado `hammer-farm.service`, el
+ **Convergido y comprobado (2026-09-09 18:40–18:45Z).** Reiniciado `takana-farm.service`, el
worker compiló los dos binarios y **cerró un ciclo de build real con el nombre nuevo**:
`✓ dunst b3:29a79859…`, BUILD-YIELD 1/1, 1 promovido. No es que «no se rompió nada visible»: el
camino de construir y sellar se ejercitó entero.
@@ -197,7 +197,7 @@ simplemente deja de cosechar. El directorio es lo **último** que se toca, y con
reescribir historia es peor que un mensaje incompleto. El detalle vive acá.)*
**Congelados y verificados con controles:** `/opt/hammer`, `/var/lib/hammer`, `/usr/bin/hammer`,
- `/mnt/vvv/hammer`, la URL de gitea, `hammer-farm.service`, `hammer-live-install.sh`,
+ `/mnt/vvv/hammer`, la URL de gitea, `takana-farm.service`, `hammer-live-install.sh`,
`BRIEFING-hammer.md`, `hammerd`, `hammer-recover`, `HAMMER_LIVE`, `.hammer-zig-cc`,
`.hammer-cargo-vendor` y dos identificadores más que aparecieron al barrer:
- `hammer-build-state/1` — el `schema` del estado generado. Nadie lo valida, pero el valor de un
@@ -236,7 +236,7 @@ simplemente deja de cosechar. El directorio es lo **último** que se toca, y con
- 🔒 **`/usr/bin/hammer` dentro del rootfs del producto** — está **dentro de un árbol que se
hashea**. Moverlo cambia el hash del producto y obliga a rehacer el baseline del selfhost.
Va junto con esa deuda, no antes.
- - ⚠ **`hammer-farm.service` y `/opt/hammer`** — despliegue coordinado en el worker: parar,
+ - ⚠ **`takana-farm.service` y `/opt/hammer`** — despliegue coordinado en el worker: parar,
renombrar, `daemon-reload`, arrancar. Reversible, pero es hacia afuera.
- ✅ **`/mnt/vvv/hammer` → `/mnt/vvv/takana`, y el repo renombrado en gitea a `sergio/takana`**
(2026-09-09 ~20:00Z). Se coordinó primero: se avisó a las dos sesiones `hammer-*` y `hammer-9f`
diff --git a/scripts/consenso.sh b/scripts/consenso.sh
index 564f7a55..d741d159 100755
--- a/scripts/consenso.sh
+++ b/scripts/consenso.sh
@@ -54,8 +54,8 @@ while [ "$i" -le "$N" ]; do
for _ in $(seq 1 30); do $SSH "root@$ip" true 2>/dev/null && break; sleep 6; done
rsync -az -e "$SSH" --exclude /work --exclude /store --exclude '/store-*' --exclude /target \
--exclude /dist --exclude /tandas --exclude /.dev-fs --exclude /.git --exclude /.scratch \
- --exclude '*.png' --exclude '/content*' ./ "root@$ip:/opt/hammer/" >/dev/null 2>&1
- hN=$($SSH "root@$ip" "export PATH=\$HOME/.cargo/bin:\$PATH; cd /opt/hammer && \
+ --exclude '*.png' --exclude '/content*' ./ "root@$ip:/opt/takana/" >/dev/null 2>&1
+ hN=$($SSH "root@$ip" "export PATH=\$HOME/.cargo/bin:\$PATH; cd /opt/takana && \
cargo build --release -q -p takana-cli 2>/dev/null; \
timeout ${POR:-900} ./target/release/takana build $RECETA --store \$PWD/store 2>/dev/null \
| grep -oE '^b3:[a-f0-9]{64}' | head -1" 2>/dev/null | tr -d '\r')
diff --git a/scripts/farm/campana-deuda.sh b/scripts/farm/campana-deuda.sh
index 97fcf899..2dfc8319 100755
--- a/scripts/farm/campana-deuda.sh
+++ b/scripts/farm/campana-deuda.sh
@@ -21,11 +21,11 @@
# Uso (en el worker): scripts/farm/campana-deuda.sh <receta> [receta…]
# DEUDA="glib cairo" scripts/farm/campana-deuda.sh
# Lanzarlo desde el hub para que sobreviva al cierre del SSH:
-# ssh root@<ip> 'systemd-run --unit=campana-deuda --working-directory=/opt/hammer \
-# /opt/hammer/scripts/farm/campana-deuda.sh <recetas…>'
+# ssh root@<ip> 'systemd-run --unit=campana-deuda --working-directory=/opt/takana \
+# /opt/takana/scripts/farm/campana-deuda.sh <recetas…>'
# ssh root@<ip> 'journalctl -u campana-deuda -f'
set -u
-HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
+HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/takana}}"
# Ruta absoluta a MÍ MISMO antes del `cd`: acá el `cd` va a HAMMER_DIR, que ni siquiera tiene por
# qué contener a este script, así que un `$0` relativo se pierde seguro.
YO="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")"
diff --git a/scripts/farm/cosecha-cron.sh b/scripts/farm/cosecha-cron.sh
index 3621708f..d776c095 100755
--- a/scripts/farm/cosecha-cron.sh
+++ b/scripts/farm/cosecha-cron.sh
@@ -21,7 +21,7 @@
#
# Uso: scripts/farm/cosecha-cron.sh # un ciclo (lo que dispara el cron)
# */30 * * * * cd /home/sergio/takana && scripts/farm/cosecha-cron.sh >>work/cosecha-cron.log 2>&1
-# Env: SSH_KEY (def ~/.ssh/github5), REMOTE (def /opt/hammer), NO_COMMIT=1 (regenera pero no commitea)
+# Env: SSH_KEY (def ~/.ssh/github5), REMOTE (def /opt/takana), NO_COMMIT=1 (regenera pero no commitea)
set -uo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
@@ -62,7 +62,7 @@ if [ -z "${COSECHA_CRON_CON_LOCK:-}" ]; then
fi
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
FLEET="$ROOT/scripts/farm/.fleet"
# ── SIEMBRA DE LA FLOTA FIJA ────────────────────────────────────────────────────────────────────
# `.fleet` es estado de EJECUCIÓN (gitignored, lo reescribe el reaper cada ciclo); `flota-permanente`
@@ -156,7 +156,7 @@ else
fi
# 2.5 REAPER HUB-SIDE (2026-07-23). El dead-man DEL WORKER probó FRÁGIL: un worker quedó 3.5h idle
-# quemando € porque su `/etc/hammer-deadman.env` no tenía token válido ⇒ el dead-man llegaba a
+# quemando € porque su `/etc/takana-deadman.env` no tenía token válido ⇒ el dead-man llegaba a
# matarse pero salía 1 "sin HCLOUD_TOKEN" cada tick. La garantía "un vps idle es inadmisible" NO
# puede depender de que cada worker se auto-provisione bien un token (falla en silencio). El HUB sí
# tiene un token que funciona, y este latido corre cada 30 min aunque no haya sesión (setsid) ⇒ el
diff --git a/scripts/farm/deadman.sh b/scripts/farm/deadman.sh
index 2e5206a3..fd3cb092 100644
--- a/scripts/farm/deadman.sh
+++ b/scripts/farm/deadman.sh
@@ -47,15 +47,15 @@
set -eu
IDLE_MAX_TICKS="${IDLE_MAX_TICKS:-6}" # 6 ticks × 10 min = 1 h sin trabajo → borrar
-ESTADO="/var/lib/hammer-deadman.ticks"
+ESTADO="/var/lib/takana-deadman.ticks"
HEARTBEAT="/run/hammer-heartbeat"
HEARTBEAT_MAX_AGE=1800 # 30 min: más viejo que esto no cuenta como vivo
-LOG="/var/log/hammer-deadman.log"
+LOG="/var/log/takana-deadman.log"
log() { echo "$(date -u +%FT%TZ) deadman: $*" >> "$LOG"; }
# TOKEN ROBUSTO A CADA CAMINO DE CREACIÓN (incidente 2026-07-23). Hay DOS caminos que crean workers y
-# ponen el token en ficheros DISTINTOS: `farm-up` → /etc/hammer-deadman.env (EnvironmentFile de la
+# ponen el token en ficheros DISTINTOS: `farm-up` → /etc/takana-deadman.env (EnvironmentFile de la
# service); `harkaq-vol.sh` → /root/.hcloud-token (cloud-init). La service del snapshot lee sólo el
# primero ⇒ un worker nacido por el OTRO camino quedaba SIN token en su env, disparaba pero salía 1
# "sin HCLOUD_TOKEN" y NUNCA se borraba (3.5h idle quemando €). El dead-man NO puede depender del hub
@@ -65,8 +65,8 @@ log() { echo "$(date -u +%FT%TZ) deadman: $*" >> "$LOG"; }
# La service lo recibe vía EnvironmentFile, pero corrido A MANO (farm-up --puede-borrar) ese fichero
# NO se carga solo ⇒ hay que sourcearlo, o la verificación da falso-negativo y destruye un worker que
# SÍ puede matarse (lo cazó el 1er worker real, 2026-07-23). Es formato KEY=value.
-if [ -z "$HCLOUD_TOKEN" ] && [ -r /etc/hammer-deadman.env ]; then
- . /etc/hammer-deadman.env 2>/dev/null || true
+if [ -z "$HCLOUD_TOKEN" ] && [ -r /etc/takana-deadman.env ]; then
+ . /etc/takana-deadman.env 2>/dev/null || true
: "${HCLOUD_TOKEN:=}"
fi
# Y ficheros de token DESNUDO (otros caminos de creación): el volumen primero, que es lo persistente.
@@ -92,8 +92,8 @@ fi
if [ "${1:-}" = "--verificar" ]; then
echo "══ ¿el dead-man switch está REALMENTE armado?"
- echo "── timer:"; systemctl is-active hammer-deadman.timer 2>/dev/null || echo " INACTIVO ⚠"
- systemctl list-timers hammer-deadman.timer --no-pager 2>/dev/null | head -3
+ echo "── timer:"; systemctl is-active takana-deadman.timer 2>/dev/null || echo " INACTIVO ⚠"
+ systemctl list-timers takana-deadman.timer --no-pager 2>/dev/null | head -3
echo "── ticks idle acumulados: $(cat "$ESTADO" 2>/dev/null || echo 0) / $IDLE_MAX_TICKS"
echo "── últimas líneas del log (evidencia de que DISPARA):"
tail -5 "$LOG" 2>/dev/null | sed 's/^/ /' || echo " (sin log todavía ⇒ NUNCA disparó)"
diff --git a/scripts/farm/estado-granja.sh b/scripts/farm/estado-granja.sh
index a7299690..f4a3040f 100755
--- a/scripts/farm/estado-granja.sh
+++ b/scripts/farm/estado-granja.sh
@@ -15,7 +15,7 @@ if [ -s "$FLEET" ]; then
echo "▶ $name ($ip)"
$SSH "root@$ip" '
echo " $(uptime | sed "s/.*load average/load/")"
- n=$(ls /opt/hammer/store 2>/dev/null | wc -l); echo " store: $n artefactos"
+ n=$(ls /opt/takana/store 2>/dev/null | wc -l); echo " store: $n artefactos"
b=$(pgrep -af "release/hammer" | grep -E "release/hammer (build|--store|hash)" | grep -oE "[^ /]+\.toml" | sort -u | tr "\n" " ")
echo " moliendo: ${b:-(nada — idle o entre colas)}"
' 2>/dev/null || echo " ⚠ sin respuesta (¿dead-man lo mató? ¿aún arrancando?)"
diff --git a/scripts/farm/farm-down.sh b/scripts/farm/farm-down.sh
index 5dba6231..916571ae 100755
--- a/scripts/farm/farm-down.sh
+++ b/scripts/farm/farm-down.sh
@@ -9,11 +9,11 @@
#
# Uso: scripts/farm/farm-down.sh # cosecha + destruye toda la flota
# scripts/farm/farm-down.sh hworker-2 # sólo ese
-# Env: SSH_KEY (def ~/.ssh/github5), REMOTE (def /opt/hammer), NO_PROMOTE=1 (sólo cosecha+destruye)
+# Env: SSH_KEY (def ~/.ssh/github5), REMOTE (def /opt/takana), NO_PROMOTE=1 (sólo cosecha+destruye)
set -uo pipefail
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
FLEET="$ROOT/scripts/farm/.fleet"
# Ver nota en farm-up.sh: workers efímeros reciclan IPs ⇒ known_hosts a /dev/null (hub-and-spoke,
diff --git a/scripts/farm/farm-lab-sync.sh b/scripts/farm/farm-lab-sync.sh
index 42219306..24a1428c 100755
--- a/scripts/farm/farm-lab-sync.sh
+++ b/scripts/farm/farm-lab-sync.sh
@@ -26,7 +26,7 @@ set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
IP="${1:?falta la IP del worker}"
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
SSH="ssh -i $SSH_KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
IMG="$ROOT/.dev-fs/lab-image.tar.zst"
TESTIGO="${TESTIGO:-recipes/zlib.toml}"
diff --git a/scripts/farm/farm-run.sh b/scripts/farm/farm-run.sh
index 0f7f0a65..0c491998 100755
--- a/scripts/farm/farm-run.sh
+++ b/scripts/farm/farm-run.sh
@@ -31,7 +31,7 @@ FLEET="$ROOT/scripts/farm/.fleet"
SSH="ssh -i $SSH_KEY -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR -o ConnectTimeout=10"
cd "$ROOT"
-cycles() { $SSH "root@$1" 'journalctl -u hammer-farm -o cat --no-pager 2>/dev/null | grep -c "ciclo terminado"' 2>/dev/null || echo 0; }
+cycles() { $SSH "root@$1" 'journalctl -u takana-farm -o cat --no-pager 2>/dev/null | grep -c "ciclo terminado"' 2>/dev/null || echo 0; }
echo "==> [farm-run] levantando $N worker(s) y alineando la cola…"
scripts/farm/farm-up.sh "$N"
diff --git a/scripts/farm/farm-sync.sh b/scripts/farm/farm-sync.sh
index 63a79de0..a45ae42d 100755
--- a/scripts/farm/farm-sync.sh
+++ b/scripts/farm/farm-sync.sh
@@ -9,12 +9,12 @@
#
# Uso: scripts/farm/farm-sync.sh root@1.2.3.4
# scripts/farm/farm-sync.sh root@1.2.3.4 --no-promote # sólo sincroniza, no firma
-# Env: SSH_KEY (def ~/.ssh/github5), REMOTE (def /opt/hammer)
+# Env: SSH_KEY (def ~/.ssh/github5), REMOTE (def /opt/takana)
set -euo pipefail
VPS="${1:?uso: farm-sync.sh user@host [--no-promote]}"
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
cd "$ROOT"
SSH="ssh -i $SSH_KEY -o StrictHostKeyChecking=accept-new"
diff --git a/scripts/farm/farm-up.sh b/scripts/farm/farm-up.sh
index f645ad86..f5a55586 100755
--- a/scripts/farm/farm-up.sh
+++ b/scripts/farm/farm-up.sh
@@ -15,7 +15,7 @@
# Env: IMAGE (snapshot, def 417847948=takana-golden-rust-go-2026-08-08), TYPE (def ccx23),
# LOCATION
# (def hel1), SSHKEY (llave del proyecto Hetzner, def desarrollo@jlsoltech.com), SSH_KEY
-# (privada local p/ SSH, def ~/.ssh/github5), REMOTE (def /opt/hammer).
+# (privada local p/ SSH, def ~/.ssh/github5), REMOTE (def /opt/takana).
set -euo pipefail
N="${1:-1}"
@@ -40,7 +40,7 @@ TYPE="${TYPE:-ccx23}"
LOCATION="${LOCATION:-hel1}"
SSHKEY="${SSHKEY:-desarrollo@jlsoltech.com}"
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
# MISMO volumen que harkaq-vol.sh, a propósito: eran DOS caminos de crear workers y sólo uno tenía
# volumen+automuerte. hworker-4 nació por ÉSTE (farm-up) y por eso quedó 5 días idle con 37G que
# nadie salvó — la protección existía y este camino la esquivaba. Compartir el volumen hace que
@@ -141,7 +141,7 @@ for k in $(seq 1 "$N"); do
# mientras eso no se reordene, esto garantiza al menos que se llegue a armarlo.
[ "$rc" -ne 0 ] && echo " ⚠ rsync de código salió $rc — el worker puede tener la cola incompleta; sigo para ARMAR EL DEAD-MAN"
# el servicio ya arrancó en el boot (baked/enabled); reiniciar fuerza rescan inmediato de la cola
- $SSH root@"$ip" 'systemctl restart hammer-farm' 2>/dev/null || true
+ $SSH root@"$ip" 'systemctl restart takana-farm' 2>/dev/null || true
# VOLUMEN PERSISTENTE + STORE DENTRO. Sin esto la automuerte perdería lo construido: hworker-4
# tenía 438 artefactos (37G) SÓLO en su disco local. El store vive en /mnt/cosecha/store ⇒ cada
@@ -188,9 +188,9 @@ for k in $(seq 1 "$N"); do
# fusionar es seguro por construcción: \`mv -n\` no pisa lo que el volumen ya tiene.
# ⚠ mountpoint -q NO ES OPCIONAL — sin él este bloque BORRA EL VOLUMEN.
# La guarda original sólo comprobaba «es directorio y no es symlink». Eso basta en un server
- # recién creado desde la golden ORIGINAL, donde /opt/hammer/store es un directorio normal.
+ # recién creado desde la golden ORIGINAL, donde /opt/takana/store es un directorio normal.
# Pero al re-snapshotear un worker (2026-08-08) la imagen se llevó también la CONFIGURACIÓN DE
- # MONTAJE: el server nuevo monta el volumen en /opt/hammer/store al arrancar, ANTES de que
+ # MONTAJE: el server nuevo monta el volumen en /opt/takana/store al arrancar, ANTES de que
# corra este rescate. Entonces rm -rf $REMOTE/store borra A TRAVÉS DEL MONTAJE y se lleva el
# store del volumen entero — que es justo lo que el volumen existe para proteger.
# Medido: el volumen pasó de ~900 artefactos a 2. No se perdió el filesystem (lost+found es de
@@ -210,7 +210,7 @@ for k in $(seq 1 "$N"); do
# el store resuelve a /mnt/cosecha/store ⇒ busca /mnt/cosecha/.dev-fs, que no existe, y muere
# con 'no encuentro el ejecutable zig en …' apuntando al lugar equivocado. Un bind-mount deja
# los datos en el volumen igual, pero \$REMOTE/store sigue siendo una ruta REAL bajo
- # \$REMOTE ⇒ el padre vuelve a ser /opt/hammer y .dev-fs se encuentra. Mantiene las dos
+ # \$REMOTE ⇒ el padre vuelve a ser /opt/takana y .dev-fs se encuentra. Mantiene las dos
# invariantes a la vez: sellar = persistir, y el lab donde takana lo espera.
if [ -L $REMOTE/store ]; then rm -f $REMOTE/store; fi
mkdir -p $REMOTE/store
@@ -239,11 +239,11 @@ for k in $(seq 1 "$N"); do
scp -q -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
scripts/farm/deadman.sh "root@$ip:/usr/local/bin/deadman.sh" 2>/dev/null
scp -q -i "$SSH_KEY" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
- scripts/farm/hammer-deadman.service scripts/farm/hammer-deadman.timer \
+ scripts/farm/takana-deadman.service scripts/farm/takana-deadman.timer \
"root@$ip:/etc/systemd/system/" 2>/dev/null
$SSH root@"$ip" "chmod +x /usr/local/bin/deadman.sh
- printf 'HCLOUD_TOKEN=%s\n' '$tok' > /etc/hammer-deadman.env; chmod 600 /etc/hammer-deadman.env
- systemctl daemon-reload && systemctl enable --now hammer-deadman.timer" >/dev/null 2>&1
+ printf 'HCLOUD_TOKEN=%s\n' '$tok' > /etc/takana-deadman.env; chmod 600 /etc/takana-deadman.env
+ systemctl daemon-reload && systemctl enable --now takana-deadman.timer" >/dev/null 2>&1
# EVIDENCIA, no fe: que el timer esté ARMADO se comprueba, no se asume (el cron de aquella vez
# estaba "validado" y nunca disparó porque el PID 1 no tenía crond).
# FIRING ≠ CAN-DELETE (2026-07-23): un worker quedó idle 3.5h quemando € porque su token no
@@ -252,7 +252,7 @@ for k in $(seq 1 "$N"); do
# SOLO, sin el hub — así que si NO PUEDE, no lo dejamos vivo: lo DESTRUIMOS acá mismo. Un worker
# que no se puede autodestruir es exactamente lo que el usuario prohíbe. `deadman.sh --puede-borrar`
# busca el token en cadena (env, volumen, /root) y prueba que ve su id en la API.
- timer_ok=$($SSH root@"$ip" 'systemctl is-active hammer-deadman.timer' 2>/dev/null | grep -q active && echo 1)
+ timer_ok=$($SSH root@"$ip" 'systemctl is-active takana-deadman.timer' 2>/dev/null | grep -q active && echo 1)
puede=$($SSH root@"$ip" '/usr/local/bin/deadman.sh --puede-borrar' 2>/dev/null)
if [ -n "$timer_ok" ] && printf '%s' "$puede" | grep -q '^SÍ'; then
echo " ✓ dead-man ARMADO y PUEDE borrarse solo ($puede) — no depende del hub"
diff --git a/scripts/farm/farm-worker-loop.sh b/scripts/farm/farm-worker-loop.sh
index 96f5940a..d72b25fd 100755
--- a/scripts/farm/farm-worker-loop.sh
+++ b/scripts/farm/farm-worker-loop.sh
@@ -7,9 +7,9 @@
# Idempotente: cada ciclo re-escanea incoming/; lo ya-sellado sale por cache-hit (instantáneo),
# sólo construye lo nuevo. Cuando la cola está toda construida, duerme IDLE_SLEEP y reintenta.
#
-# Lo lanza systemd (hammer-farm.service). Manual: JOBS=2 ./scripts/farm/farm-worker-loop.sh
+# Lo lanza systemd (takana-farm.service). Manual: JOBS=2 ./scripts/farm/farm-worker-loop.sh
set -uo pipefail
-HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
+HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/takana}}"
cd "$HAMMER_DIR"
. "$HOME/.cargo/env" 2>/dev/null || true
# JOBS=1 MIENTRAS EL ADR 0012 ESTÉ SIN DECIDIR (2026-07-22). `build-farm.sh` usa `xargs -P$JOBS`, y
diff --git a/scripts/farm/harkaq-campana-vol.sh b/scripts/farm/harkaq-campana-vol.sh
index 8a08633a..1527169f 100755
--- a/scripts/farm/harkaq-campana-vol.sh
+++ b/scripts/farm/harkaq-campana-vol.sh
@@ -10,7 +10,7 @@
set -u
MI_NOMBRE="${1:?uso: harkaq-campana-vol.sh <mi-nombre>}"
-HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
+HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/takana}}"
cd "$HAMMER_DIR"
LISTA="${LISTA:-work/harkaq-cola.txt}"
VOL_OUT="/mnt/cosecha"
diff --git a/scripts/farm/harkaq-campana.sh b/scripts/farm/harkaq-campana.sh
index fea6c1dd..c54a8aea 100755
--- a/scripts/farm/harkaq-campana.sh
+++ b/scripts/farm/harkaq-campana.sh
@@ -18,7 +18,7 @@
# script existe para no tener.
set -u
-HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
+HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/takana}}"
cd "$HAMMER_DIR"
LISTA="${1:-work/harkaq-cola.txt}"
OUT="work/harkaq-campana"
diff --git a/scripts/farm/harkaq-vol.sh b/scripts/farm/harkaq-vol.sh
index 9a6a9497..c35c740e 100755
--- a/scripts/farm/harkaq-vol.sh
+++ b/scripts/farm/harkaq-vol.sh
@@ -30,7 +30,7 @@ HELPER_TYPE="${HELPER_TYPE:-ccx13}" # para collect: el más barato que
LOCATION="${LOCATION:-hel1}"
SSHKEY="${SSHKEY:-desarrollo@jlsoltech.com}"
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
IDLE_CICLOS="${IDLE_CICLOS:-3}" # ciclos idle antes de auto-eliminarse
SSH="ssh -i $SSH_KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes"
diff --git a/scripts/farm/harvest-go.sh b/scripts/farm/harvest-go.sh
index e86b4e9f..0168e0ec 100755
--- a/scripts/farm/harvest-go.sh
+++ b/scripts/farm/harvest-go.sh
@@ -16,7 +16,7 @@
# Todo se loguea a work/harvest-go.log para revisar el lunes.
#
# Uso (cron): */DohubVPS cd /home/sergio/takana && scripts/farm/harvest-go.sh root@1.2.3.4 >>work/harvest-go.log 2>&1
-# Env: SSH_KEY (def ~/.ssh/github5), REMOTE (def /opt/hammer), STORE (def ./store), REPO (def dist/repo),
+# Env: SSH_KEY (def ~/.ssh/github5), REMOTE (def /opt/takana), STORE (def ./store), REPO (def dist/repo),
# KEY (def dist/keys/release.ed25519), DISTRO (def dev), HAMMER (def target/release/takana),
# SEAL_TIMEOUT (def 60s: techo del cache-hit; más = sería build local ⇒ skip).
set -u
@@ -24,7 +24,7 @@ set -u
VPS="${1:?uso: harvest-go.sh user@host}"
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
STORE="${STORE:-$ROOT/store}"
REPO="${REPO:-$ROOT/dist/repo}"
KEY="${KEY:-$ROOT/dist/keys/release.ed25519}"
diff --git a/scripts/farm/harvest-harkaq.sh b/scripts/farm/harvest-harkaq.sh
index 93bba4a0..fc10f445 100755
--- a/scripts/farm/harvest-harkaq.sh
+++ b/scripts/farm/harvest-harkaq.sh
@@ -49,7 +49,7 @@ if [ -z "${HARVEST_HARKAQ_CON_LOCK:-}" ]; then
exit "$rc"
fi
SSH_KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
SSH="ssh -i $SSH_KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes"
REVIEW="tandas/needs-review-harkaq"
mkdir -p "$REVIEW" work
diff --git a/scripts/farm/hammer-deadman.service b/scripts/farm/takana-deadman.service
similarity index 76%
rename from scripts/farm/hammer-deadman.service
rename to scripts/farm/takana-deadman.service
index 371acdd2..4b2bee2f 100644
--- a/scripts/farm/hammer-deadman.service
+++ b/scripts/farm/takana-deadman.service
@@ -1,10 +1,10 @@
[Unit]
Description=hammer: tick del dead-man switch (borra el worker tras 1h idle)
-# El token se lee de /etc/hammer-deadman.env (0600, lo escribe farm-up al provisionar). Sin él el
+# El token se lee de /etc/takana-deadman.env (0600, lo escribe farm-up al provisionar). Sin él el
# script LOGUEA EL ERROR y sale 1: no hace un poweroff "por si acaso", porque un server apagado en
# Hetzner SIGUE COBRANDO y daría una falsa sensación de ahorro.
[Service]
Type=oneshot
-EnvironmentFile=-/etc/hammer-deadman.env
+EnvironmentFile=-/etc/takana-deadman.env
ExecStart=/usr/local/bin/deadman.sh
diff --git a/scripts/farm/hammer-deadman.timer b/scripts/farm/takana-deadman.timer
similarity index 100%
rename from scripts/farm/hammer-deadman.timer
rename to scripts/farm/takana-deadman.timer
diff --git a/scripts/farm/hammer-farm.service b/scripts/farm/takana-farm.service
similarity index 92%
rename from scripts/farm/hammer-farm.service
rename to scripts/farm/takana-farm.service
index 0ae939a5..7a522188 100644
--- a/scripts/farm/hammer-farm.service
+++ b/scripts/farm/takana-farm.service
@@ -1,5 +1,5 @@
[Unit]
-Description=hammer build farm worker (loop autónomo)
+Description=takana build farm worker (loop autónomo)
After=network-online.target
Wants=network-online.target
# ── FRENO AL CRASHLOOP (2026-08-31) ──────────────────────────────────────────────────────────────
@@ -18,7 +18,7 @@ StartLimitBurst=3
[Service]
Type=simple
-WorkingDirectory=/opt/hammer
+WorkingDirectory=/opt/takana
Environment=HOME=/root
# ADR 0016: se fijan LAS DOS mientras dure el renombre. Los scripts leen
# ${TAKANA_DIR:-${HAMMER_DIR:-…}}, pero un script VIEJO —o una copia del repo
@@ -27,12 +27,12 @@ Environment=HOME=/root
# es lo que hoy impide retirar la caída. Cuando el worker corra con TAKANA_DIR
# y el resto de la flota también, se borra la segunda línea y recién ahí se
# puede retirar la caída del código (etapa 6).
-Environment=TAKANA_DIR=/opt/hammer
-Environment=HAMMER_DIR=/opt/hammer
+Environment=TAKANA_DIR=/opt/takana
+Environment=HAMMER_DIR=/opt/takana
# JOBS no se fija: el loop usa nproc por defecto (cada build usa 1 core por codegen-units=1).
# Así, al REPOTENCIAR la caja (CCX13→CCX23/33), el worker auto-escala los slots sin tocar config.
# La línea CCX da ~4GB RAM/core ⇒ nproc slots quedan con margen para builds Rust + swap.
-ExecStart=/opt/hammer/scripts/farm/farm-worker-loop.sh
+ExecStart=/opt/takana/scripts/farm/farm-worker-loop.sh
Restart=always
RestartSec=30
# El OOM del worker NO se reintenta como si fuera un fallo transitorio: si la receta no entra en la
diff --git a/scripts/farm/tandas.sh b/scripts/farm/tandas.sh
index abbbd6c4..3f7602ac 100755
--- a/scripts/farm/tandas.sh
+++ b/scripts/farm/tandas.sh
@@ -17,11 +17,11 @@
# Uso (en el worker):
# scripts/farm/tandas.sh "gui:pixman,cairo,pango" "kernels:linux,linux-generic"
# Desde el hub:
-# ssh root@<ip> 'systemd-run --unit=tandas --working-directory=/opt/hammer \
-# /opt/hammer/scripts/farm/tandas.sh "gui:pixman,cairo" …'
+# ssh root@<ip> 'systemd-run --unit=tandas --working-directory=/opt/takana \
+# /opt/takana/scripts/farm/tandas.sh "gui:pixman,cairo" …'
# ssh root@<ip> 'tail -f /var/log/tandas.log'
set -u
-HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
+HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/takana}}"
cd "$HAMMER_DIR"
LOG="${LOG:-/var/log/tandas.log}"
ESPERA="${ESPERA:-30}"
diff --git a/scripts/farm/vps-setup.sh b/scripts/farm/vps-setup.sh
index 302894b7..c5c9f02c 100755
--- a/scripts/farm/vps-setup.sh
+++ b/scripts/farm/vps-setup.sh
@@ -23,7 +23,7 @@
# falla se avisa RUIDOSO, porque sin swap un build Rust grande no se pone lento:
# lo mata el OOM killer.
#
-# Uso (en el VPS, como root): HAMMER_DIR=/opt/hammer ./scripts/farm/vps-setup.sh
+# Uso (en el VPS, como root): HAMMER_DIR=/opt/takana ./scripts/farm/vps-setup.sh
#
# ── CAJA FRESCA (no golden): DOS PASOS DEL HUB ANTES DE ESTO ────────────────────────────────
# La imagen golden de Hetzner ya trae rsync y el lab horneados. Una caja virgen, no:
@@ -35,13 +35,13 @@
# tira del Storage Box y eso exige credenciales — que el worker NO debe tener (modelo
# hub-and-spoke: compute puro, sin secretos). El hub le manda el tarball ya verificado
# y el worker lo re-verifica por sha256 al extraerlo:
-# rsync -a .dev-fs/lab-image.tar.zst caja:/opt/hammer/.dev-fs/lab-<SHA>.tar.zst
-# rsync -a .dev-fs/tools/ caja:/opt/hammer/.dev-fs/tools/
+# rsync -a .dev-fs/lab-image.tar.zst caja:/opt/takana/.dev-fs/lab-<SHA>.tar.zst
+# rsync -a .dev-fs/tools/ caja:/opt/takana/.dev-fs/tools/
# Mandar `tools/` entero (zig 0.13.0 + 0.16.0 + go) y no dejar que se descarguen solos
# evita el zig-skew: el worker usa EXACTAMENTE las versiones del hub.
set -euo pipefail
-HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
+HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/takana}}"
cd "$HAMMER_DIR"
# ── detección de familia ────────────────────────────────────────────────────────────────────
@@ -144,9 +144,9 @@ echo "==> 6. rootfs Alpine edge + zig (bootstrap reproducible; varios min la 1ra
./scripts/bootstrap-devfs.sh
echo "==> 7. systemd unit del loop"
-cp scripts/farm/hammer-farm.service /etc/systemd/system/hammer-farm.service
+cp scripts/farm/takana-farm.service /etc/systemd/system/takana-farm.service
systemctl daemon-reload
echo "✓ worker provisionado."
-echo " arrancar: systemctl enable --now hammer-farm"
-echo " logs: journalctl -u hammer-farm -f"
+echo " arrancar: systemctl enable --now takana-farm"
+echo " logs: journalctl -u takana-farm -f"
diff --git a/scripts/farm/worker-depositar.sh b/scripts/farm/worker-depositar.sh
index 87bdd538..80d5f1e5 100755
--- a/scripts/farm/worker-depositar.sh
+++ b/scripts/farm/worker-depositar.sh
@@ -18,7 +18,7 @@
# DENTRO de una misma corrida: con un rsync por directorio, cada artefacto viaja como si fuera único
# y el buzón llega inflado. Una sola invocación con la lista completa los ve todos.
set -uo pipefail
-STORE="${STORE:-/opt/hammer/store}"
+STORE="${STORE:-/opt/takana/store}"
KEY="${KEY:-/root/.ssh/sb_sub}"
RO_HOST="${RO_HOST:-u647150-sub1.your-storagebox.de}"; RO_USER="${RO_USER:-u647150-sub1}"
BZ_HOST="${BZ_HOST:-u647150-sub2.your-storagebox.de}"; BZ_USER="${BZ_USER:-u647150-sub2}"
diff --git a/scripts/harkaq/harkaq-farm-setup.sh b/scripts/harkaq/harkaq-farm-setup.sh
index 05fa59e5..33d8ad85 100755
--- a/scripts/harkaq/harkaq-farm-setup.sh
+++ b/scripts/harkaq/harkaq-farm-setup.sh
@@ -11,7 +11,7 @@ set -eu
IP="${1:?uso: harkaq-farm-setup.sh <ip>}"
KEY="${SSH_KEY:-$HOME/.ssh/github5}"
-REMOTE="${REMOTE:-/opt/hammer}"
+REMOTE="${REMOTE:-/opt/takana}"
SSH="ssh -i $KEY -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes"
HERE="$(cd "$(dirname "$0")" && pwd)"
diff --git a/scripts/yupana.py b/scripts/yupana.py
index 46fd1ef9..4136fea1 100755
--- a/scripts/yupana.py
+++ b/scripts/yupana.py
@@ -153,9 +153,9 @@ def _base(n):
# El primer predictor "obvio" (prefijo del hub) mentía con confianza — la lección de siempre.
PAGINA_OVERLAY = 4096 # tope del string de opciones de un mount overlayfs = PAGE_SIZE
# Prefijo que bwrap ve en runtime (bajo /oldroot, ruta del worker). Ajustable por host.
-_PREF_SANDBOX = os.environ.get("PREF_STORE_SANDBOX", "/oldroot/opt/hammer/store/")
+_PREF_SANDBOX = os.environ.get("PREF_STORE_SANDBOX", "/oldroot/opt/takana/store/")
_OVERHEAD_OVERLAY = len("upperdir=/tmp-overlay-upper-0,workdir=/tmp-overlay-work-0,") \
- + len("/oldroot/opt/hammer/.dev-fs/alpine") + len(",userxattr")
+ + len("/oldroot/opt/takana/.dev-fs/alpine") + len(",userxattr")
def _lowerdir_estimado(deps):