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>
86 lines
5.9 KiB
TOML
86 lines
5.9 KiB
TOML
# shuma-daemon — el dueño de los Workspaces de shuma: sesiones PTY, paneles y el socket de admin
|
|
# que consultan el gateway, el TUI y el shell. Es el que hace que `/shuma/*` sirva de algo.
|
|
#
|
|
# ── POR QUÉ ESTA RECETA (2026-09-16) ────────────────────────────────────────────────────────────
|
|
# Va en par con `shuma-gateway`: el gateway sin daemon es un puente a ninguna parte. Los dos corren
|
|
# hoy en gioser desde binarios puestos a mano —el del daemon, además, desde un **inodo borrado**— y
|
|
# la mudanza los reconstruye en vez de copiarlos (SDD 28 §6.34).
|
|
#
|
|
# ⚠ **Lo que esta receta NO resuelve, y hay que decirlo acá**: en gioser el daemon corre como
|
|
# `sergio`, no como root, y el payload `Native` de una tarjeta de arje **no tiene campo de usuario**
|
|
# (SDD 29 §4.0 quinquies). Declararlo sin más lo pondría a correr como root, que no es «perder una
|
|
# opción» sino cambiar el sistema. La bajada de privilegio se decide al escribir la tarjeta, no acá.
|
|
name = "shuma-daemon"
|
|
version = "0.1.0"
|
|
license = "MIT OR Apache-2.0"
|
|
|
|
[source]
|
|
repo = "https://git.tawasuyu.net/tawasuyu/tawasuyu.git"
|
|
commit = "23a292863f53b355c5c02d6185904f2c33d8ab42"
|
|
cargo_vendor_dir = ".hammer-cargo-vendor"
|
|
|
|
[build]
|
|
compiler = "zig-cc"
|
|
target = "x86_64-linux-musl"
|
|
link = "static"
|
|
flags = ["-p", "shuma-daemon", "--bin", "shuma-daemon"]
|
|
|
|
# ── LA CUENTA (SDD 30) ──────────────────────────────────────────────────────────────────────────
|
|
# Fuera de `hash_inputs`: declarar esto NO re-hashea shuma-daemon (control corrido, el hash no se
|
|
# movió).
|
|
#
|
|
# ⚠ EN GIOSER CORRE COMO `sergio`, Y ESO NO SE PUEDE TRADUCIR SOLO. El payload `Native` de arje no
|
|
# tiene campo de usuario (SDD 29 §4.0 quinquies), así que una tarjeta escrita «como estaba» lo
|
|
# pondría de ROOT — y esto es un demonio que abre PTYs y ejecuta shells: correrlo de root no es
|
|
# perder una opción, es entregar la máquina. La cuenta es propia y sin privilegio, y el descenso se
|
|
# hace en el comando con `setuidgid`, igual que gitea.
|
|
[[user]]
|
|
name = "shuma"
|
|
uid = 967
|
|
home = "/var/lib/shuma"
|
|
# ⚠ Y LA SHELL NO ES UN DETALLE ACÁ. El default de `[[user]]` es `/bin/false`, que es lo correcto
|
|
# para un demonio (gitea, squid) y **lo exactamente contrario** para éste: shuma-daemon existe para
|
|
# abrir PTYs y lanzar shells. Con `/bin/false` el servicio arranca, se supervisa, contesta… y cada
|
|
# pestaña que alguien abra muere al instante. Un fallo que no se ve al desplegar: se ve al usarlo.
|
|
shell = "/bin/sh"
|
|
|
|
# ── EL SERVICIO ─────────────────────────────────────────────────────────────────────────────────
|
|
# Las guardas salen 78 NOMBRANDO EL ARREGLO. Es lo que hace la diferencia entre un servicio que
|
|
# reintenta para siempre con «unknown user» y uno que dice qué falta: medido con gitea, cuya imagen
|
|
# arrancaba perfecta y sin el servicio por el que existe.
|
|
#
|
|
# `XDG_RUNTIME_DIR` no es decoración: es donde el daemon pone su socket, y es por ese socket que el
|
|
# gateway le habla. En gioser vale `/run/shuma`, medido en el entorno del proceso vivo.
|
|
[[service]]
|
|
label = "shuma-daemon"
|
|
id = "01M2EKDA00SH0MADAEM0N7X4K2"
|
|
exec = "/bin/busybox"
|
|
argv = ["sh", "-c", "/bin/grep -q '^sergio:' /etc/passwd || { echo 'shuma-daemon: no existe el usuario `sergio` en /etc/passwd — la receta lo declara con [[user]]; la imagen lo compone con `takana users`' >&2; exit 78; }; mkdir -p /run/shuma /var/lib/shuma || exit 78; chown shuma:shuma /run/shuma /var/lib/shuma || exit 78; cd /home/sergio || exit 78; exec /usr/bin/setuidgid sergio /usr/bin/shuma-daemon"]
|
|
envp = [["PATH", "/usr/bin:/bin"], ["HOME", "/home/sergio"], ["USER", "sergio"], ["XDG_RUNTIME_DIR", "/run/shuma"]]
|
|
networking = "full"
|
|
cgroup = "arje.slice/shuma-daemon"
|
|
restart = { initial_ms = 1000, max_ms = 30000 }
|
|
|
|
# ── ⚠ `shuma-askpass` NO VA EN ESTA CAJA, y conviene decirlo acá porque el daemon lo PIDE ────────
|
|
# Al arrancar, shuma-daemon avisa: «askpass: no encontré `shuma-askpass` … sudo/ssh pedirán la clave
|
|
# por el TTY». Se intentó darle la receta (2026-09-16) y el resultado fue mejor que construirla:
|
|
#
|
|
# 1. **No construye**: su dependencia `atspi-common` muere con `custom attribute panicked —
|
|
# message: File has no extension.` en el proc-macro `#[validate(signal: …)]`, que lee un
|
|
# fichero en tiempo de compilación y no resuelve la ruta dentro del sandbox (`/src/...`).
|
|
# 292 errores en cascada, todos hijos de ese pánico.
|
|
# 2. **Y no hace falta**: su propio `Cargo.toml` la describe como «Mini-ventana Llimphi compatible
|
|
# con SUDO_ASKPASS» — es una VENTANA (llimphi-ui, theme, widget-text-input, clipboard). En un
|
|
# servidor sin pantalla no tiene dónde dibujarse, y las sesiones de shuma son PTYs: ahí el
|
|
# prompt por TTY es el camino correcto, no una degradación.
|
|
#
|
|
# ⇒ el aviso del daemon es para el escritorio, no para el servidor. Si algún día hace falta acá,
|
|
# primero hay que resolver el proc-macro de atspi, no reponer la receta.
|
|
|
|
# ── ⚠ 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.
|