# steam-runtime-sniper — el runtime en el que Valve corre los juegos, SELLADO al store. # ADR 0015 (qorpa) D8: es la única imagen ajena de la terna que puede entrar acá, y esta receta # es lo que hace cierto ese renglón. # # ══ ESTO NO ES UNA RECETA NORMAL, Y LA DIFERENCIA IMPORTA ══════════════════════════════════════ # No construye nada: **sella bytes ajenos ya compilados**. Por eso lleva `foreign = true`, que no # cambia el build en nada y sí cambia cómo la cuenta el grafo — pasa a clase `ajeno`, se resta del # denominador de las imágenes y NO engorda «cuántas recetas construimos». Sin esa marca, sellar un # prebuilt inflaría la cifra que todo el mundo lee como corpus, que es exactamente el riesgo que el # ADR 0015 se puso por escrito para no cometer. # # ══ POR QUÉ ESTA SÍ Y LAS OTRAS DOS NO ═════════════════════════════════════════════════════════ # La invariante D1 dice que las imágenes ajenas NO entran al store, y el motivo es que un rootfs # mutable —Arch, Ubuntu, al que le instalás cosas— no reproduce: meterlo haría que el store mienta. # Sniper es distinto por una propiedad, no por simpatía: **no muta**. Nadie le instala nada adentro; # pressure-vessel lo monta de sólo lectura. Así que el mismo tarball pineado produce siempre el # mismo árbol, y sellarlo es una afirmación verdadera. # # ══ QUÉ SE GANA SELLÁNDOLO ═════════════════════════════════════════════════════════════════════ # Cadena de custodia NUESTRA: el artefacto se replica con `takana mirror push`, su digest puede ir # al índice firmado (ADR 0014) y una instancia se arma sin depender de que la CDN de Valve siga # viva. Se consume con: # # takana qorpa import --from-store # ⇒ images//{image.toml,rootfs} # # La identidad de la imagen sigue siendo **el sha256 del ARCHIVO de Valve**, no el ArtifactHash: es # lo que hace que dos máquinas coincidan aunque una lo traiga del store y la otra de upstream. Por # eso el `image.toml` viaja DENTRO del artefacto, escrito acá y no adivinado por el importador. # # ══ POR QUÉ EL ÁRBOL VA A /usr/share/qorpa Y NO A LA RAÍZ ══════════════════════════════════════ # Un rootfs glibc entero volcado en `/` pisaría el sistema; y aunque la tentación sea dejarlo en la # raíz del artefacto para que `hydrate` lo escupa con la forma exacta de una imagen qorpa, un # artefacto tiene que ser inofensivo si alguien lo compone en un rootfs por error. Namespaceado no # colisiona con nada. **Esta receta NO va en ningún perfil de `targets.toml`**: no es parte de # ninguna imagen nuestra, es carga para qorpa. # # ══ LICENCIA ══════════════════════════════════════════════════════════════════════════════════ # `LicenseRef-…-no-enumerable` a propósito: adentro hay cientos de paquetes Debian con sus términos # y no podemos enumerarlos. Poner "MIT" o dejarlo vacío sería peor — vacío se lee como «todavía no # la poblamos». SDD 20 ya dice que las ajenas no entran al reporte de licencias; esto lo hace # visible desde la receta. name = "steam-runtime-sniper" version = "3.0.20260805.254768" license = "LicenseRef-qorpa-ajena-no-enumerable" foreign = true [source] # El snapshot NO es «el último»: es el que `latest-container-runtime-depot.txt` dice que despliega # el cliente de Steam. Pinear otro sería pinear algo que nadie corre. Digest verificado contra el # SHA256SUMS del propio snapshot el 2026-09-03 (ver docs/state/qorpa-imagenes.toml). tarball = "https://repo.steampowered.com/steamrt-images-sniper/snapshots/3.0.20260805.254768/com.valvesoftware.SteamRuntime.Platform-amd64%2Ci386-sniper-runtime.tar.gz" sha256 = "1a293c312215c59e4e5348ce210594cd7967d1a1fcaec6248a024e0878776f2b" # CERO, no el 1 de siempre: el archivo trae DOS entradas arriba —`files/` (el rootfs) y `metadata` # (la ficha de build de Valve)—. Con strip 1 el rootfs se fundiría con su hermano y el árbol # quedaría mal anclado, que es el fallo que no rompe al traerlo sino después, cuando la instancia # no encuentra su loader. strip_components = 0 [build] compiler = "zig-cc" target = "x86_64-linux-musl" link = "dynamic" [build.phases] configure = "true" compile = "true" # `cp -a` y no `cp -r`: hay que preservar symlinks, modos y tiempos o el rootfs deja de ser un # rootfs. `metadata` se deja fuera igual que hace `takana qorpa pull`, para que el árbol sellado y # el traído de upstream sean el MISMO árbol y no dos primos. install = ''' set -e D=/out/usr/share/qorpa/images/steam-runtime-sniper mkdir -p "$D" cp -a files "$D/rootfs" test -x "$D/rootfs/usr/bin/env" || { echo "el árbol no parece un rootfs" >&2; exit 1; } cat > "$D/image.toml" <<'EOF' # Lo sella `recipes/steam-runtime-sniper.toml` (ADR 0015 D8) y lo consume `hammer qorpa import`. # La identidad de la imagen es el sha256 del ARCHIVO de Valve, no el ArtifactHash de este # artefacto: es lo que hace que coincida con la que otra máquina traiga de upstream. sha256 = "1a293c312215c59e4e5348ce210594cd7967d1a1fcaec6248a024e0878776f2b" url = "https://repo.steampowered.com/steamrt-images-sniper/snapshots/3.0.20260805.254768/com.valvesoftware.SteamRuntime.Platform-amd64%2Ci386-sniper-runtime.tar.gz" label = "sniper-platform-3.0.20260805.254768" archive_bytes = 302423522 rootfs_subdir = "files" dropped_siblings = ["metadata"] EOF ''' [deps] build = []