diff --git a/docs/state/targets.toml b/docs/state/targets.toml index c9e57158..497a2231 100644 --- a/docs/state/targets.toml +++ b/docs/state/targets.toml @@ -24,6 +24,12 @@ descripcion = "userland foundational C: la distro arranca y se usa (shell, VCS, # Lift verbatim de BASE_SYSTEM_PKGS (scripts/product-userland-from-repo.sh). De-Alpinizado y firmado, # tandas base-system-1..3. paquetes = [ + # `os-release` (2026-09-14): la IDENTIDAD del sistema — nombre, URL, color y **el logo oficial**. + # No existía: la caja decía «Host: vServer» y ni una palabra de takana. Va en `base` y no en `cli` + # porque toda imagen de takana debe saber decir qué es, incluida la más pelada: lo lee cualquier + # programa que no sea nuestro, y sin él la distro es anónima. «No sólo para esta máquina, para + # siempre en takana» (usuario, 2026-09-14). + "os-release", # `tar` (GNU, 2026-09-14): el `tar` de busybox **no entiende `--zstd`** ni `-p` ni # `--delay-directory-restore`. Ya costó dos veces: la caja no podía desempacar su propio LAB, y # `qorpa pull` de un rootfs ajeno moría imprimiendo la ayuda de busybox sin nombrar la causa. @@ -108,11 +114,6 @@ hereda = ["base"] # declara abajo es el subconjunto que ya estaba sellado y que un usuario de esta capa espera # encontrar — cero recetas nuevas, cero builds: sólo dejan de ser invisibles. paquetes = [ - # `os-release` (2026-09-14): la IDENTIDAD del sistema, que no existía. Se descubrió al meter - # fastfetch: la caja decía «Host: vServer» y ni una palabra de takana, porque `/etc/os-release` no - # estaba. Lo lee todo el que quiera saber en qué distro corre — sin él, la distro es anónima para - # cualquier programa que no sea suyo. - "os-release", # `fastfetch` (2026-09-14, pedido del usuario): la tarjeta de presentación del sistema. En una # distro propia es lo primero que contesta «¿qué estoy corriendo?» sin leer tres ficheros de # `/proc`, y en una caja recién instalada distingue «arrancó» de «arrancó lo que yo creía». diff --git a/recipes/os-release.toml b/recipes/os-release.toml index 640c69b5..cc4dfc8c 100644 --- a/recipes/os-release.toml +++ b/recipes/os-release.toml @@ -21,9 +21,26 @@ # y no conoce `takana`. Van juntos acá y no en la receta de fastfetch porque lo que se declara es la # identidad del sistema —nombre, URL, color, logo—, no la configuración de una herramienta: mañana # el que dibuje puede ser otro programa y el logo seguirá siendo el mismo fichero. -# · `/usr/share/takana/logo.txt` — un martillo, que es lo que significa el nombre en quechua +# · `/usr/share/takana/logo.png` — **el logo oficial**, tal cual lo entregó el usuario +# · `/usr/share/takana/logo.txt` — el mismo, en ANSI de color verdadero para la terminal # · `/etc/xdg/fastfetch/config.jsonc` — la config GLOBAL (XDG), no la de un usuario # +# ⚠ EL ASCII NO SE INVENTA: SE EXTRAE DEL PNG. La primera versión de este fichero era un martillo +# dibujado a ojo, y no era el logo — era *un* martillo. El de verdad es una cuadrícula **7×7** +# medida sobre el PNG (bbox 348×348 en un lienzo de 512, celda de 49,7 px), con cuatro colores +# exactos y nada más: +# +# #a63a25 ladrillo #df6b2a naranja #e3a63d dorado #fff6de crema +# +# ██ ██ ██ ██ ██ ██ ██ fila 0: las siete +# ██ ██ ██ ██ ██ fila 1: cinco, con el crema al centro +# ██ ██ ██ ██ ██ ██ ██ fila 2: las siete +# ██ filas 3-6: el mango, una sola columna +# +# Cada celda son DOS caracteres de bloque: un carácter de terminal es alto y angosto, así que +# `██` por celda es lo que conserva la geometría CUADRADA del original. Reconstruirlo a ojo la +# pierde, y con ella deja de ser el logo. +# # ⚠ SIN VERSIÓN NI FECHA, a propósito. Un `VERSION_ID` con la fecha del build haría que este # artefacto —y con él la clausura de toda imagen que lo lleve— cambiara de hash cada día sin que # nada haya cambiado. La versión de una distro de árbol único es el hash de su imagen, que ya existe. @@ -43,4 +60,7 @@ flags = [] [build.phases] configure = "true" compile = "true" -install = "mkdir -p /out/etc /out/usr/lib && cp -a /src/etc/. /out/etc/ && cp -a /src/usr/. /out/usr/ && ln -sf ../../etc/os-release /out/usr/lib/os-release" +# `cp -r`, NO `cp -a`: en el sandbox no hay privilegio para preservar el propietario y `-a` aborta +# con `failed to preserve ownership ... Invalid argument`. Los modos por defecto son los correctos — +# y el dueño real lo pone la proyección del artefacto, no esta copia. +install = "mkdir -p /out/etc /out/usr/lib && cp -r /src/etc/. /out/etc/ && cp -r /src/usr/. /out/usr/ && ln -sf ../../etc/os-release /out/usr/lib/os-release" diff --git a/recipes/os-release/tree/etc/xdg/fastfetch/config.jsonc b/recipes/os-release/tree/etc/xdg/fastfetch/config.jsonc index 7568f255..c11e3610 100644 --- a/recipes/os-release/tree/etc/xdg/fastfetch/config.jsonc +++ b/recipes/os-release/tree/etc/xdg/fastfetch/config.jsonc @@ -1,11 +1,13 @@ // Config global de fastfetch para takana. // // Sin esto, fastfetch dibuja el pingüino genérico de Linux: elige el logo por el `ID` de -// `/etc/os-release` y no conoce `takana`. El logo es un fichero nuestro — un martillo, que es lo -// que significa el nombre en quechua. +// `/etc/os-release` y no conoce `takana`. +// +// `file-raw` (no `file`): el logo trae sus propios escapes ANSI de color verdadero, sacados del +// PNG oficial celda por celda. Con `file` se imprimirían como texto. { "logo": { - "type": "file", + "type": "file-raw", "source": "/usr/share/takana/logo.txt", "color": { "1": "36" }, "padding": { "top": 1, "right": 3 } diff --git a/recipes/os-release/tree/usr/share/takana/logo.png b/recipes/os-release/tree/usr/share/takana/logo.png new file mode 100644 index 00000000..e72cdfc5 Binary files /dev/null and b/recipes/os-release/tree/usr/share/takana/logo.png differ diff --git a/recipes/os-release/tree/usr/share/takana/logo.txt b/recipes/os-release/tree/usr/share/takana/logo.txt index 4cbda041..5ab05e50 100644 --- a/recipes/os-release/tree/usr/share/takana/logo.txt +++ b/recipes/os-release/tree/usr/share/takana/logo.txt @@ -1,9 +1,7 @@ - ▟██████████▙ - ███████████║ - ▜████▛▀▜████▛ - ▐████▌ - ▐████▌ - ▐████▌ - ▐████▌ - ▐████▌ - ▗██████▖ +██████████████ + ██████████ +██████████████ + ██ + ██ + ██ + ██ diff --git a/recipes/rust-toolchain-bin.toml b/recipes/rust-toolchain-bin.toml new file mode 100644 index 00000000..4d01beb8 --- /dev/null +++ b/recipes/rust-toolchain-bin.toml @@ -0,0 +1,53 @@ +# rust-toolchain-bin — el compilador de Rust, PRECOMPILADO por upstream y sellado tal cual. +# +# ══ POR QUÉ ESTA RECETA EXISTE, Y POR QUÉ ES `foreign` ═════════════════════════════════════════ +# Decisión del usuario (2026-09-14): *«sin compilador de rust, takana no tiene sentido»*. Y tiene +# razón por una vía que no es de gusto: **todo el instrumental de takana es Rust** —12 crates, +# 42 555 líneas— y hasta hoy el `rustc` que los construye sale del **LAB**, un rootfs Alpine ajeno. +# Como el lab entra en el `ArtifactHash`, la distro depende de bytes de otro para poder +# reconstruirse a sí misma: eso contradice el invariante central, y no se ve porque funciona. +# +# El corpus tenía **44 recetas `cargo-*` y CERO recetas de `rustc`/`cargo`** — 44 subcomandos sin el +# programa, [[subcomando-sin-driver]] a escala de toolchain. +# +# **`foreign = true` porque son bytes ajenos, no un build nuestro.** No reproduce desde fuente: lo +# que se sella es exactamente el tarball que publica rust-lang, verificado por su `sha256` oficial. +# La marca no cambia el build en nada y sí cambia cómo lo cuenta el grafo (clase `ajeno`, fuera del +# denominador de «cuántas recetas construimos»). Sin ella, meter un prebuilt inflaría la cifra que +# todo el mundo lee como corpus — el riesgo que el ADR 0015 puso por escrito. +# +# ══ ESTO ES EL PASO 1 DE TRES, Y LOS OTROS DOS NO SON OPCIONALES ═══════════════════════════════ +# 1. **este** — desbloquea HOY que una caja takana compile Rust, y dice la verdad sobre su origen. +# 2. `rustc` desde fuente con el `llvm18` que YA está sellado en el corpus (379 M). Ahí Rust pasa +# a ser nuestro. +# 3. La cadena `mrustc → 1.90 → 1.91.0 → 1.91.1`, que ya existe documentada en el selfhost +# (`docs/10-roadmap.md`, `docs/11-bootstrap.md`) pero vive en el bootstrap, no en el corpus. +# Es la que quita la última dependencia de bytes ajenos. +# +# ⚠ El target es **musl**, no gnu: es un toolchain que CORRE sobre musl, que es lo que esta distro +# tiene. Un `x86_64-unknown-linux-gnu` traería el cargador de glibc y sería [[needed-colgante-libstdcxx]] +# otra vez — instalado, sellado y sin poder ejecutarse. +name = "rust-toolchain-bin" +version = "1.97.0" +license = "MIT OR Apache-2.0" +foreign = true + +[source] +tarball = "https://static.rust-lang.org/dist/rust-1.97.0-x86_64-unknown-linux-musl.tar.xz" +sha256 = "4cebf1c593fcdccf40adb8bc5ef187c3e0dd99f465f9dab48d1a45310ba0de63" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" +flags = [] + +[build.phases] +configure = "true" +compile = "true" +# El tarball trae su propio `install.sh` con componentes (`rustc`, `cargo`, `rust-std-*`). Se usa el +# instalador de upstream en vez de copiar a mano: sabe qué componente va dónde y mantiene el +# `manifest` que `rustup` y el propio toolchain esperan encontrar. +# `--disable-ldconfig`: no hay ldconfig acá y su ausencia haría fallar el instalador por un paso que +# en una distro de binarios estáticos no significa nada. +install = "./install.sh --prefix=/out/usr --disable-ldconfig --components=rustc,cargo,rust-std-x86_64-unknown-linux-musl" diff --git a/recipes/takana.toml b/recipes/takana.toml index f19d6bdb..3f1875df 100644 --- a/recipes/takana.toml +++ b/recipes/takana.toml @@ -35,7 +35,7 @@ license = "MIT" # El repo del propio takana: el `commit` es el identificador inmutable; la URL es sólo locator y no # entra en `hash_inputs` (ADR 0013 §1). Subirlo cuando el CLI avance. repo = "https://git.gioser.net/sergio/takana.git" -commit = "68d052136c06b74f858a8a33d1963f45cf244fa0" +commit = "0d0ab79092b282f45bfb1158694f4eaf5df58af5" [build] compiler = "zig-cc"