Pedido: «crea mi cuenta sergio con la clave tawasuyu, desde ahí abrir los claudes como lo estoy
haciendo acá con shuma sobre los proyectos».
· cuenta `sergio` uid 1001 (el mismo que en gioser), home /home/sergio, clave verificada
· su propia jaula `claude-sergio`, que concede SU home —su `.claude`: credenciales y memoria— y
NO el de root. Con la instancia de root, sergio moría en «bwrap: Can't mkdir /root/.claude»
· `claude` elige instancia por usuario; `PROY=/otra/ruta claude` abre el agente sobre otro proyecto
· shuma-daemon y shuma-gateway pasan a correr como `sergio`, no como la cuenta de servicio `shuma`:
shuma es su CONSOLA, y cada pestaña que abre tiene que ser una sesión suya — si no, `claude`
buscaría una jaula `claude-shuma` que no existe
⚠ NO se eleva con doas/sudo: en esta caja el setuid NO TOMA («doas: Operation not permitted», con
NoNewPrivs 0 y `/` sin nosuid — queda como deuda entender por qué). No hace falta: `qorpa run`
levanta la jaula con user namespaces y anda sin privilegio, siempre que el directorio de la
instancia sea del usuario.
⚠ Y un detalle que costó una vuelta: sin `shift 2`, el HOME y el proyecto que el lanzador pasa como
posicionales se cuelan COMO ARGUMENTOS del agente — la primera sesión se abrió con el prompt
«/home/sergio», y el agente contestó, con razón, que eso es una ruta y no un comando.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
63 lines
4.8 KiB
TOML
63 lines
4.8 KiB
TOML
# shuma-gateway — el puente HTTP/JSON + WebSocket de shuma: lo que `sergio.gioser.net/shuma/*`
|
|
# atraviesa para hablarle al daemon. Traduce JSON ↔ postcard y empalma WS ↔ ExecPty.
|
|
#
|
|
# ── POR QUÉ EXISTE ESTA RECETA (2026-09-16) ─────────────────────────────────────────────────────
|
|
# Es el ÚLTIMO vhost atado a gioser (SDD 28 §6.34): de los 29 dominios del Caddyfile, `sergio` es el
|
|
# único que todavía resuelve a la máquina que se borra, y lo que lo ata no es el sitio —su frontend
|
|
# ya está copiado en la caja— sino esta consola. El binario que corre allá hoy es **glibc, puesto a
|
|
# mano, y su inodo está BORRADO del disco**: vive sólo mientras el proceso no muera. Un servicio así
|
|
# no se muda copiándolo; se DECLARA y se reconstruye, que es lo que decidió el usuario cuando se le
|
|
# ofrecieron las tres salidas (jaula glibc / construirlo desde tawasuyu / que muera).
|
|
#
|
|
# ── EL PIN ──────────────────────────────────────────────────────────────────────────────────────
|
|
# `23a292863` es el MISMO commit que ya usa `puriy-costura` (subido hoy). Compartir el pin no es
|
|
# cosmético: el árbol de fuentes de una dep se comparte entre recetas (`work/sources/<dep>-<sha>`),
|
|
# así que dos pines distintos del monorepo son dos árboles de 2,4 G vendoreados en vez de uno.
|
|
name = "shuma-gateway"
|
|
version = "0.1.0"
|
|
license = "MIT OR Apache-2.0"
|
|
|
|
[source]
|
|
repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git"
|
|
commit = "23a292863f53b355c5c02d6185904f2c33d8ab42"
|
|
# tawasuyu COMMITEA su propio `vendor/` (smithay parcheado, enchufado por `[patch.crates-io]` POR
|
|
# RUTA) y el `cargo vendor` de takana lo pisaría, con un error que habla de `taffy` y no de esto.
|
|
# Ver [[takana-cargo-vendor-clobbers-project-vendor]] y el cabezal de `puriy-costura`.
|
|
cargo_vendor_dir = ".hammer-cargo-vendor"
|
|
|
|
[build]
|
|
compiler = "zig-cc"
|
|
target = "x86_64-linux-musl"
|
|
# Estático musl: lo arranca el init de la caja y no puede depender de encontrar un cargador. Es
|
|
# exactamente lo que le falta hoy al binario de gioser, que es ELF dinámico contra glibc.
|
|
link = "static"
|
|
flags = ["-p", "shuma-gateway", "--bin", "shuma-gateway"]
|
|
|
|
# ── EL SERVICIO (SDD 30) ────────────────────────────────────────────────────────────────────────
|
|
# Fuera de `hash_inputs`: declarar esto NO re-hashea el gateway.
|
|
#
|
|
# La cuenta la declara `shuma-daemon` —es la misma— y por eso acá no va otro `[[user]]`: dos recetas
|
|
# declarando la misma cuenta con distinto uid abortan la imagen a propósito (`takana users --merge`).
|
|
#
|
|
# ⚠ DOS GUARDAS, Y LAS DOS SALEN 78 DICIENDO EL ARREGLO:
|
|
# 1. sin el usuario, esto correría de root — y es el puente HTTP hacia un demonio que abre shells;
|
|
# 2. sin `gateway-token` no autentica a nadie. El fichero son 32 bytes que en gioser viven en
|
|
# `~/.config/shuma/gateway-token`; si se genera uno nuevo, los clientes ya emparejados dejan de
|
|
# entrar. Por eso la guarda no lo crea: lo EXIGE y nombra de dónde sale.
|
|
[[service]]
|
|
label = "shuma-gateway"
|
|
id = "01M2EKDA00SH0MAGATEWAY4K21"
|
|
exec = "/bin/busybox"
|
|
argv = ["sh", "-c", "/bin/grep -q '^sergio:' /etc/passwd || { echo 'shuma-gateway: falta el usuario `sergio` — lo declara recipes/shuma-daemon.toml' >&2; exit 78; }; test -s /home/sergio/.config/shuma/gateway-token || { echo 'shuma-gateway: falta /home/sergio/.config/shuma/gateway-token (32 B) — viene de ~/.config/shuma/gateway-token del origen; si generás uno nuevo, los clientes emparejados dejan de entrar' >&2; exit 78; }; cd /home/sergio || exit 78; exec /usr/bin/setuidgid sergio /usr/bin/shuma-gateway"]
|
|
envp = [["PATH", "/usr/bin:/bin"], ["HOME", "/home/sergio"], ["USER", "sergio"], ["XDG_RUNTIME_DIR", "/run/shuma"]]
|
|
networking = "full"
|
|
cgroup = "arje.slice/shuma-gateway"
|
|
restart = { initial_ms = 1000, max_ms = 30000 }
|
|
|
|
# ── ⚠ CORRE COMO `sergio`, NO COMO `shuma` (2026-09-17) ─────────────────────────────────────────
|
|
# La cuenta `shuma` se creó cuando la caja no tenía usuario de la persona. Ahora sí, y shuma es su
|
|
# CONSOLA: las pestañas que abre son sesiones suyas, y desde ahí lanza `claude`, que entra a la
|
|
# jaula `claude-sergio` con SU memoria y SUS credenciales. Con el daemon corriendo como `shuma`,
|
|
# cada terminal de la web habría sido de otro usuario que no es nadie — y `claude` habría buscado
|
|
# una jaula `claude-shuma` que no existe.
|