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…
feat(servidor): el latido ya espeja a GitHub — con el token pedido en el momento, no guardado
1#!/bin/sh
2# credencial-espejo-github.sh — da a git el token de GitHub del espejo, sin guardarlo en ningún sitio.
3#
4# ══ POR QUÉ EXISTE ════════════════════════════════════════════════════════════════════════════
5# El latido (`cosecha-cron.sh`, crontab de ROOT con `HOME=/root`) publica el estado y debe espejarlo
6# a GitHub. El espejo va por HTTPS con el token de `gh` —las claves SSH disponibles no llegan: se
7# comprobó el 2026-10-07 que ninguna de `/root/.ssh` abre el repo del espejo— y `gh` está logueado
8# como **sergio**, en `/home/sergio/.config/gh/hosts.yml`. Root no lo ve.
9#
10# Las alternativas se descartaron por lo que dejan a la intemperie:
11# - meter el token en `.git/config` o en un `~/.git-credentials` ⇒ secreto EN REPOSO, en claro,
12# en una caja que ya tiene root compartido.
13# - poner la URL con el token adentro (`https://x:TOKEN@github.com/…`) ⇒ lo mismo, y además sale
14# en cada mensaje de error de git.
15# - loguear `gh` como root ⇒ dos sesiones que caducan por separado, y la de root nadie la mira.
16#
17# Esto lo pide EN EL MOMENTO y no lo escribe: si `gh` pierde la sesión, el push falla ruidosamente
18# en vez de empujar con un token muerto.
19#
20# ⚠ El token NO se imprime en ninguna traza: `gh auth token` escribe sólo a stdout, que git consume.
21# No añadir `set -x` acá ni redirigir esta salida a un log.
22#
23# Uso: no se invoca a mano. Se declara como ayudante de credencial del clon del latido:
24# git -C /opt/takana config credential.https://github.com.helper /usr/local/bin/credencial-espejo-github
25#
26# git llama al ayudante con la operación en $1 (`get`/`store`/`erase`). Sólo `get` tiene respuesta:
27# no se guarda ni se borra nada, porque no hay nada guardado.
28[ "${1:-}" = "get" ] || exit 0
29
30DUENO="${DUENO_GH:-sergio}"
31USUARIO="${USUARIO_GH:-sergiovelasquezzeballos}"
32
33# `su - <dueño>` y no `sudo`: en esta caja `sudo` reenvía al anfitrión por ssh (ver CLAUDE.md) y acá
34# ya estamos en el anfitrión. El login shell es necesario para que `gh` encuentre su HOME.
35token="$(su - "$DUENO" -c 'gh auth token' 2>/dev/null)"
36if [ -z "$token" ]; then
37 # A stderr, que git muestra: un ayudante que calla deja a git pidiendo usuario y contraseña por
38 # teclado, y en un cron eso es un cuelgue sin mensaje.
39 echo "credencial-espejo-github: $DUENO no tiene sesión de gh (corré: gh auth login)" >&2
40 exit 1
41fi
42
43echo "username=$USUARIO"
44echo "password=$token"