Decide la frontera antes de escribir código. Sale de una medición incómoda: el
corpus tiene cuatro escritorios que cierran y CERO navegador, ofimática,
reproductor o editor de imagen. Al partir el «qué falta» por causa, la
intersección de «sólo X11» con «compilable desde fuente en musl» es casi vacía:
casi todo lo que se pierde por Wayland ya estaba perdido por la libc. El montón
que duele son binarios ajenos que nadie va a recompilar.
Las siete decisiones:
D1 — Una imagen ajena NO es un artefacto y no vive en el store. El store promete
reconstrucción bit a bit desde fuente; un rootfs de Fedora no. Meterlo ahí
sería la misma clase de error que el artefacto vacío: algo que se lee como
garantía y no lo es. Namespace paralelo, por digest, fuera de hash_inputs.
D2 — Se cruza el borde con protocolos y nodos de dispositivo, NUNCA con
librerías. Wayland/PipeWire son protocolos; /dev/dri y /dev/ntsync son ABI
de kernel. Mesa va adentro de la imagen. Corolario: la jaula no sabe qué
libc hay adentro, y por eso resuelve el montón entero de una vez.
D3 — El manifiesto es la verdad; el `upper` del overlay es CACHÉ. Misma relación
que receta↔artefacto. De ahí se caen solas la actualización de base (se
recrea, no se rebasea), el respaldo (KB, no GB) y la poda.
D4 — Cuatro granularidades, no una. El runtime curado inmutable (tipo 2) sigue
siendo el preferido cuando alcanza: se sella. El rootfs con dnf existe
porque es justo lo que el tipo 2 no permite.
D5 — Transparencia por shims GENERADOS, no por un FUSE global. Es el poder de
Bedrock sin sus formas: cero costo en runtime, inspeccionable, revocable, y
se exporta lo declarado (Bedrock arbitra en tiempo de exec, con heurísticas).
Los nodos exportados entran al grafo con clase `ajeno` ⇒ no se pueden contar
como corpus. Bedrock no puede decirte qué tenés.
D6 — Steam ya ES un contenedor: se anida pressure-vessel adentro, que es la
configuración que Valve prueba. El bwrap anidado hay que VERIFICARLO.
D7 — Es el único lugar del sistema donde la política se escribe en vez de
derivarse. harkaq deriva `política = clausura(deps)`; una imagen ajena no
tiene clausura declarada. Excepción nombrada y acotada, por defecto vacía.
Y lo que el ADR admite que NO resuelve, escrito para no descubrirlo en producción:
el socket de Wayland es un borde de privilegio y lo pasamos crudo (screencopy y
virtual-keyboard incluidos — Flatpak pasa un proxy filtrante, nosotros no lo
tenemos); el UID mapping va a fallar primero y las piezas ya están en el corpus
(shadow instala newuidmap/newgidmap y crea /etc/subuid vacío, falta
provisionarlo); es una segunda cadena de suministro sin garantías; y hay que
acotar por escrito el claim de bit-repro o la cultura de números honestos se
erosiona sola.
Se cae gratis: `xwayland` deja de ser deuda del corpus (va DENTRO de la imagen,
que ya lo trae, y se cuelga de kwin por el socket) ⇒ el wanted de KDE se
disolvería sin escribir la receta y sin tocar Wayland-only. GIMP e Inkscape dejan
de reabrir la deuda GTK3. Y del plan de juegos: F2 (glibc+multilib desde fuente,
«una campaña entera») queda CANCELADA y F0 (flatpak+ostree al catálogo)
innecesaria.
Lo nativo no se afloja: el montón A se sigue construyendo, en orden mpv → OBS →
Firefox.
Toca sólo documentación: el ADR nuevo, la nota de generalización en
plan-jaula-juegos.md §Capa 3, y el comentario en targets.toml que evita que
alguien escriba la receta de xwayland sin ver la decisión pendiente. Cero recetas
tocadas, cero re-hasheo: --kde sigue en 978 sealed / 1 wanted / 171-171, CIERRA.
7.0 KiB
Plan — juegos en hammer (kernel, nativos, y la jaula glibc)
Fecha: 2026-07-16 · Contexto: hammer es musl + estático + fuente; el mundo del juego en Linux es glibc + 32-bit + binarios ajenos (Steam/Proton). Este plan separa lo que hammer puede hacer nativo y barato (capas 1–2) de lo que exige un runtime ajeno contenido y sellado (capa 3), en vez de fingir que musl va a correr Steam.
Capa 1 — kernel propio: casi gratis, ganancia real
Los kernels ya fijan config por contrato explícito (scripts/config -e/-d en
recipes/linux-metal.toml:67, mismo patrón que LANDLOCK/IO_URING/BPF de 2b7c701). Se extiende
la misma línea:
- T1.1 —
CONFIG_NTSYNC=y(driver de primitivas de sincronización NT, kernel ≥6.14; el 6.16.12 propio lo trae). Es EL salto para Wine/Proton moderno — reemplaza los hacks esync/fsync por un char device (/dev/ntsync). Built-in, compatible con el-d MODULESdel kernel metal. - T1.2 — sched-ext: DIFERIDO (verificado 2026-07-16).
SCHED_CLASS_EXTen 6.16.12 depende deBPF_SYSCALL && BPF_JIT && DEBUG_INFO_BTF(kernel/Kconfig.preempt del tag) — y la receta apaga BTF/DEBUG_INFO a propósito, más BTF exige pahole/dwarves en las deps de build. Es tarea propia: recetadwarves+ análisis de repro de BTF (pahole-skew) + medir el costo en tamaño del bzImage. T2.1 (schedulers scx) queda gated por esto. - T1.3 —
HZ_1000+ preempt en linux-metal (el perfil de latencia de escritorio/juego; linux-generic puede quedarse como está — son perfiles distintos y por eso hay dos recetas). - T1.4 —
split_lock_detect=offen el CMDLINE embebido (CONFIG_CMDLINE, linux-metal.toml:99). Juegos con locks mal alineados (los hay, famosos) reciben una penalización brutal del detector; en una máquina de juego se apaga. OJO: el cmdline viaja DENTRO del bzImage (EFI-stub, ADR 0010) ⇒ esto re-sella el kernel, no es un toggle de GRUB. - T1.5 — sysctls de perfil juego:
vm.max_map_count=1048576(lo pide Valve; los defaults de kernel siguen en 65530), THP enmadvise. Dónde viven: perfil de arje/base-system, no hardcodeado en kernel.
Re-sellar linux-metal re-hashea el kernel ⇒ pasa por la granja y el ciclo QEMU-boot de
verificación existente, como el 2b7c701.
Capa 2 — userspace nativo (sí compila en hammer)
- T2.1 — schedulers scx (
scx_lavd,scx_bpfland): los schedulers de juego de CachyOS. Son programas BPF con userspace en Rust/C — pero compilar la parte BPF exige clang+libbpf ⇒ worker. Entrega: receta + regla de arranque en el init (SDD 07) para activarlos por perfil. - T2.2 —
gamescope: el micro-compositor de Valve (frame limiting, VRR, HDR, upscaling). C++ + Vulkan + cadena wayland ⇒ worker, frontera GUI (gotcha zig-skew: jamás rebuildear la cadena en el laptop). Es la pieza con más valor: da una "sesión de juego" contenida que además le queda bien a mirada como sesión alternativa. - T2.3 —
MangoHud(C++ ⇒ worker) ygamemode(C): overlay de métricas y gobernador de perfil. gamemoded habla D-Bus — la cadena KDE ya lo trajo, la dep existe. - T2.4 — mesa con RADV: el driver Vulkan serio es AMD (RADV/ACO). Revisar features de
recipes/mesa.tomly activar RADV si no está. nouveau NO es para jugar (sabido por mirada); NVK madura pero no este trimestre. El perfil de juego de hammer es honesto: AMD primero. - T2.5 — variantes v3 de mesa/wine: donde el truco CachyOS paga de verdad para juegos.
Depende del piloto de
plan-variantes-cpu.md(T5→T1–T4 de ese plan); no se duplica aquí.
Capa 3 — la jaula glibc (el elefante, por fases)
⚠ GENERALIZADO por ADR 0015 — Imágenes ajenas (2026-09-03, PROPUESTO). Esta capa razonaba sobre un runtime concreto de Valve; el ADR razona sobre cualquier rootfs ajeno y decide la frontera con el store. Si el ADR se acepta: F1 queda como caso particular (imagen «de tipo 2»: curada, inmutable, sellable por
file_drop), F0 (flatpak+ostree al catálogo) queda innecesaria, y F2 (glibc + multilib 32-bit desde fuente) queda cancelada — las libs de 32 bits las trae la imagen ajena. El resto de este plan (capas 1 y 2, todo lo nativo) no cambia.
Steam, Proton y el catálogo de juegos son binarios glibc, parte 32-bit. musl no los va a correr y perseguir eso es un pozo. La respuesta con ADN hammer: el runtime ajeno se trae entero, pineado por hash, y corre enjaulado — verificar, no confiar, aplicado a un rootfs que no construimos.
- F0 — pragmático (hoy): Steam por Flatpak. El runtime freedesktop trae su mundo glibc completo. Costo: entra flatpak al catálogo (cadena ostree/bwrap — bwrap ya es dep del build lab). Es la validación de demanda antes de construir nada propio.
- F1 — la jaula propia: importar el Steam Linux Runtime (sniper/pressure-vessel — el
contenedor que Valve ya usa para Proton) como artefacto
file_dropcontent-addressed: tarball pineado por sha256 en receta, sellado en el store, hidratable como cualquier artefacto. Unhammer-juego(script primero) lo monta con bwrap +/dev/dri+ ntsync + sockets wayland/pipewire y lanza Steam adentro. Diferencia con F0: la cadena de custodia es de hammer (hash en el índice firmado, no un remote de flathub). - F2 — (sólo si F1 duele) glibc propio: construir glibc + multilib 32-bit desde fuente es una campaña entera (toolchain dual, loader, locales). El mundo se mueve además hacia WoW64 (wine ≥9 corre 32-bit sobre wine 64-bit sin multilib), que puede volver F2 innecesario antes de que se justifique. No arrancar F2 sin una razón que F1 no cubra.
Cruce harkaq/arje (la parte que nadie más tiene): la jaula de juego es un usuario más
del cierre §3 — política Landlock declarada para el runtime ajeno (GPU, audio, input, red de
Steam, y NADA más). El binario es ajeno pero la jaula es nuestra y sus permisos son una
ConcesionCapacidad atestada como cualquier otra. Un Steam que no puede leer ~/.ssh es un
argumento de venta que ninguna distro gamer ofrece.
Lo que NO se hace
- Perseguir Steam nativo sobre musl — pozo sin fondo, y Valve ya resolvió el contenedor.
- Soporte NVIDIA propietario como frente — fuera del modelo (driver no libre, no sellable desde fuente); nouveau/NVK cuando maduren. AMD es el camino soportado.
- Fork del kernel "gaming" — no hay kernel aparte: son flags de perfil en linux-metal, bajo el mismo contrato explícito y el mismo ciclo de verificación.
Orden propuesto
- T1.1–T1.5 — re-sellar linux-metal con NTSYNC/sched-ext/HZ/cmdline (worker + QEMU-boot).
- F0 — flatpak+Steam: valida demanda con costo mínimo y da juegos YA.
- T2.2–T2.3 — gamescope/MangoHud/gamemode a la cola del worker (cadena GUI).
- T2.1 — schedulers scx + regla de init.
- F1 — la jaula sellada con pressure-vessel + política harkaq del runtime.
- T2.4–T2.5 — RADV confirmado + variantes v3 de mesa (tras el piloto de variantes).