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 1389Shell 137Markdown 80Rust 802602 Definiciones

fix(granja): un espejo caído se veía igual que una publicación fallida

El publicador empujaba a `$REMOTE` a secas. `git push <remoto>` con varias `pushurl` las empuja
TODAS y devuelve != 0 si cualquiera falla, así que un espejo caído se leía igual que no haber
publicado: el reintento volvía a traer —con el canónico YA al día—, calculaba «sin novedad» y
salía 0. El fallo del espejo quedaba tapado por un éxito.

Ahora el canónico va por su URL explícita y los espejos aparte, uno por uno, diciendo cuál quedó
atrás. Un espejo roto no cambia el código de salida —lo publicado vale— pero grita, porque el modo
de falla conocido es que DERIVE EN SILENCIO durante días (CLAUDE.md regla 2). Y si no hay ninguno
configurado también se dice: un espejo ausente y un espejo roto se ven igual desde el log.

Descubierto empujando: `/opt/takana` tiene `origin` sólo a gitea, así que el latido NUNCA espejó
—ni ahora ni antes—, y el comentario de `espejo-setup.sh` daba por hecho que sí («para que TODO
`git push origin main` que ya existe en los scripts (p.ej. cosecha-cron.sh) espeje solo»). Con 48
commits de estado al día, el espejo deriva por ese mismo número.

⚠ Configurarle la pushurl al latido NO alcanza: en el anfitrión `gh` existe pero no tiene sesión
(`gh auth login`), y el espejo va por HTTPS con ese token. Hasta que la haya, el aviso nuevo es lo
que evita que la deriva vuelva a pasar inadvertida.

Controles 7 y 8 en repo de juguete: espejo sano ⇒ lo dice; espejo ausente ⇒ grita, rc=0, y el
canónico tiene el contenido.

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

cb2013f54f20960c9eed8a6114cf840002fc0857 · por Sergio · (hace 15 d) · padre 3a97cc173 · ver el árbol en este commit

Delta semántico

Ninguna definición cambió: el cambio es de texto, documentación o datos.

1 archivos · +23 −1

diff --git a/scripts/farm/publicar-estado.sh b/scripts/farm/publicar-estado.sh
index ceca5d90..9a390be6 100755
--- a/scripts/farm/publicar-estado.sh
+++ b/scripts/farm/publicar-estado.sh
@@ -124,8 +124,30 @@ while :; do
 
   # `<sha>:refs/heads/main` con el padre siendo la cabeza recién traída ⇒ es un fast-forward para
   # el remoto. Si el remoto se movió, lo RECHAZA (no hay lease que valga: el rechazo ES la señal).
-  if git push -q "$REMOTE" "$commit:refs/heads/main" 2>/dev/null; then
+  #
+  # Se empuja a la URL CANÓNICA explícitamente, no a `$REMOTE` a secas, y los espejos van aparte en
+  # un segundo paso. `git push <remoto>` con varias `pushurl` las empuja TODAS y devuelve != 0 si
+  # cualquiera falla: con eso un espejo caído se ve igual que una publicación fallida, el reintento
+  # vuelve a traer (ya con el canónico al día), calcula «sin novedad» y SALE 0. O sea que el fallo
+  # del espejo quedaría tapado por un éxito. Separarlos es lo que permite decir qué lado quedó atrás
+  # — que es la regla de este repo: comprobar los dos lados, no la salida del push.
+  CANON="$(git config --get remote.$REMOTE.url)"
+  if git push -q "$CANON" "$commit:refs/heads/main" 2>/dev/null; then
     echo "==> estado publicado: ${commit:0:9} sobre ${base:0:9} ($puestos fichero(s))"
+    # ── ESPEJOS ───────────────────────────────────────────────────────────────────────────────
+    # Un espejo que falla NO invalida lo publicado, así que no cambia el código de salida; pero se
+    # grita, porque el modo de falla conocido es que el espejo DERIVE EN SILENCIO durante días
+    # (CLAUDE.md regla 2). Si no hay ninguno configurado se dice también: un espejo ausente y un
+    # espejo roto se ven igual desde el log, y no son lo mismo.
+    espejos=0
+    for url in $(git remote get-url --push --all "$REMOTE" 2>/dev/null); do
+      [ "$url" = "$CANON" ] && continue
+      espejos=$((espejos + 1))
+      git push -q "$url" "$commit:refs/heads/main" 2>/dev/null \
+        && echo "   espejo al día: $url" \
+        || echo "   ⚠ EL ESPEJO QUEDÓ ATRÁS: $url — lo publicado está en el canónico, el espejo no"
+    done
+    [ "$espejos" -gt 0 ] || echo "   (este clon no tiene espejo configurado — ver scripts/espejo-setup.sh)"
     # Adelantar la rama local sólo si es un fast-forward limpio y el árbol no estorba. Si no se
     # puede, NO es un fallo: lo publicado ya está, que es lo que importa. Se dice y se sigue.
     if git merge-base --is-ancestor HEAD "$commit" 2>/dev/null; then