From d99ed588502194b110d400e79cd7c86d50e0bcd9 Mon Sep 17 00:00:00 2001 From: sergio Date: Thu, 16 Jul 2026 23:14:19 -0400 Subject: [PATCH] =?UTF-8?q?harkaq:=20revertir=20busybox=20(era=20runtime?= =?UTF-8?q?=20base,=20romp=C3=ADa=20builds)=20+=20coordinar=20el=20=C2=A73?= =?UTF-8?q?=20con=20Fable=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DOS ERRORES MÍOS, uno de dirección y otro técnico, los dos en la cosecha automática: 1. DIRECCIÓN: declaró `busybox` como dep en 29 recetas — cuando la Etapa C lo está ELIMINANDO (USERLAND_COMPONENTS=[uutils,findutils,…], ya cerrada; joyas-reusables §5 lo confirma: "uutils… Ubuntu 25.10 los envía como default"). Estaba cimentando la deuda que el roadmap borra. 2. TÉCNICO: busybox YA está en el runtime base de harkaq (`ro /bin/busybox`, `ro /bin/sh` — el sandbox corre `sh -c` y /bin/sh→/bin/busybox). Es CONTRATO, no dep. Declararlo apila el busybox de hammer sobre el de Alpine y ROMPE el build: binutils daba "cannot run C compiled programs" en las DOS máquinas. Verificado: sin busybox declarado, binutils construye (b3:f4507dcd…). Y la cadena se explica: binutils roto ⇒ zlib (que lo declara) tampoco construía. Auditoría de la cosecha (diff real, no la línea completa del +): añadió sólo 5 deps distintas — make ×73, busybox ×29, perl ×8, pkgconf ×5, binutils ×1. Sólo busybox estaba mal; las otras 4 son deps reales medidas. busybox revertido de 30 recetas (queda sólo en busybox.toml, pre-existente). Es el mismo error que ya me habían señalado con otro disfraz: MEDIR BIEN Y ACCIONAR MAL. harkaq midió correcto (el build toca /bin/busybox: es el shell); la acción correcta no era declararlo sino reconocerlo como contrato. + COORDINACIÓN del §3 con Fable 5 (mismo diseño, tareas repartidas): - Su lección casper queda CONFIRMADA y REFORZADA: la clausura de build no sólo le FALTAN las clases del mundo (offline) — también le SOBRA casi todo (headers, gcc). Medido: htop (estático, 0 NEEDED) no toca NADA al correr ⇒ política = su binario. - Su "la clase viaja como campo de la ConcesionCapacidad, sin formato nuevo" se cumple LITERALMENTE: lo firmado es format::Permisos = u32 bitmask en 36 bytes canónicos (Ring 0) ⇒ las clases SON los bits. La cripto no se toca. - Diseño unificado: frontera (clases, u32, declaradas) + detalle (paths, Landlock, medidos). D3 rige en ambos. - Reparto: clases→Fable 5; medición/harness→Opus. CONTACTO: runtime-policy.sh ahora emite la CLASE detectada (/etc/resolv.conf→dns, /etc/ssl/certs→tls-certs, …), no sólo el path: la medición alimenta la tabla, la tabla decide el bit. - Consumidor esperando: plan-jaula-juegos F1 (Steam que no puede leer ~/.ssh). + juez.sh (§10): nombre único por corrida (con uno fijo pega en caché ⇒ falso "sin evidencia"). Fue el juez quien destapó todo esto en su primera corrida real. Co-Authored-By: Claude Opus 4.8 --- docs/17-cierres-frontera.md | 45 ++++++ recipes/adwaita-hello.toml | 47 +++++++ recipes/bash.toml | 2 +- recipes/binutils.toml | 2 +- recipes/coreutils.toml | 2 +- recipes/dosfstools.toml | 2 +- recipes/e2fsprogs.toml | 2 +- recipes/flex.toml | 3 - recipes/fontconfig.toml | 2 +- recipes/gawk.toml | 2 +- recipes/gperf.toml | 2 +- recipes/gtk4-hello.toml | 47 +++++++ recipes/gtk4.toml | 39 ++++++ recipes/gtksourceview.toml | 23 ++++ recipes/hammer-edit.toml | 138 +++++++++++++++++++ recipes/incoming-clib/shared-libmandoc.patch | 92 +++++++++++++ recipes/incoming-clib/tests.patch | 12 ++ recipes/incoming-clib/valgrind.patch | 11 ++ recipes/libadwaita.toml | 22 +++ recipes/libarchive.toml | 2 +- recipes/libnl.toml | 2 +- recipes/libusb.toml | 2 +- recipes/linux-generic.toml | 2 +- recipes/linux-metal.toml | 2 +- recipes/linux.toml | 2 +- recipes/mtools.toml | 3 - recipes/npth.toml | 2 +- recipes/pango.toml | 16 +++ recipes/parted.toml | 2 +- recipes/python3.toml | 2 +- recipes/readline.toml | 2 +- recipes/rsync.toml | 2 +- recipes/sed.toml | 2 +- recipes/shadow.toml | 2 +- recipes/sourceview-hello.toml | 57 ++++++++ recipes/sqlite.toml | 2 +- recipes/tar.toml | 2 +- recipes/util-linux.toml | 2 +- recipes/which.toml | 2 +- recipes/wpa_supplicant.toml | 2 +- recipes/xorriso.toml | 2 +- recipes/zlib.toml | 2 +- scripts/harkaq/runtime-policy.sh | 17 ++- scripts/juez.sh | 104 ++++++++++++++ 44 files changed, 697 insertions(+), 35 deletions(-) create mode 100644 recipes/adwaita-hello.toml create mode 100644 recipes/gtk4-hello.toml create mode 100644 recipes/gtk4.toml create mode 100644 recipes/gtksourceview.toml create mode 100644 recipes/hammer-edit.toml create mode 100644 recipes/incoming-clib/shared-libmandoc.patch create mode 100644 recipes/incoming-clib/tests.patch create mode 100644 recipes/incoming-clib/valgrind.patch create mode 100644 recipes/libadwaita.toml create mode 100644 recipes/pango.toml create mode 100644 recipes/sourceview-hello.toml create mode 100755 scripts/juez.sh diff --git a/docs/17-cierres-frontera.md b/docs/17-cierres-frontera.md index ebffad19..dffdaf78 100644 --- a/docs/17-cierres-frontera.md +++ b/docs/17-cierres-frontera.md @@ -84,6 +84,51 @@ dlopen de módulos NSS — la mitad de por qué casper existe no aplica: La clase viaja como campo de la `ConcesionCapacidad` — sin formato nuevo. +**Medición que confirma y acota lo anterior (Opus 4.8, 2026-07-16).** Se probó el riel de punta +a punta y salieron dos cosas que ajustan el diseño; la lección casper queda **confirmada y +reforzada**: + +1. **El sujeto: la clausura de build no puede ser la política de runtime, ni siquiera de base.** + No es sólo que le falten las clases del mundo (casper): también le **sobra** casi todo. Un + build lee `zlib.h`, `make`, `gcc`; el binario resultante no abre ninguno. Medido con `htop` + (musl-estático, **0 `NEEDED`**): bajo la jaula con política mínima **no tocó un solo fichero** + fuera de sí mismo ⇒ su política de runtime es `ro ` y nada más. Derivarla del + build le habría concedido headers y compilador — permisos de más, firmados. + ⇒ **la política granular se MIDE corriendo el binario** (`scripts/harkaq/runtime-policy.sh`: + corre bajo la jaula y **resta el baseline del lanzador**, que si no se lleva el ruido del `sh`). + Para un estático la política *no puede* salir de las libs: sólo de correrlo. + +2. **La cripto ya es "frontera, no tabla" — y por eso las clases encajan sin tocarla.** Lo que la + `ConcesionCapacidad` firma **no** es `card-core::Permissions` (el struct) sino + `format::Permisos` = **`u32` bitmask**, dentro de `mensaje_capacidad` = + `hash(32) || permisos_le(4)` = **36 bytes canónicos, zero-alloc, con espejo `no_std` en Ring 0** + (`wawa-kernel/src/claves.rs:464`). Meterle una tabla de paths rompería **todas** las firmas y + contradiría el "capacidad = frontera física, no tabla" que este mismo §3 cita. + ⇒ **las clases de servicio SON los bits del `u32`** (`PERMISO_RED` ya es uno; `dns` sería otro). + "Sin formato nuevo" se cumple literalmente. + +**Diseño unificado (los dos niveles coexisten, cada uno donde cabe):** + +| nivel | qué | dónde | cómo se obtiene | +|---|---|---|---| +| **frontera** | clases de servicio (`dns`, `tls-certs`, `random`, `locale`, `syslog`) | `u32` firmado, verificado en Ring 0 | **declaradas por nombre** — no se pueden medir: el build es offline (casper) | +| **detalle** | paths concretos (fs) | Landlock, userspace | **medidos** corriendo el binario bajo la jaula | + +El kernel verifica la frontera con 36 bytes; Landlock aplica el detalle. D3 rige en ambos: nada +se ensancha en silencio. + +**Reparto de tareas (para no pisarnos):** +- **Clases de servicio** (Fable 5): la tabla clase→permiso musl, el bit en el `u32`, y el cableado + con `ConcesionCapacidad`/`arje-absorb --attest-from`. +- **Medición** (Opus 4.8): `runtime-policy.sh`, el harness harkaq (jaula, lector, canario D9) y el + baseline del lanzador. +- **Punto de contacto acordado**: `runtime-policy.sh` emitirá también la **clase** detectada, no + sólo el path — si el binario toca `/etc/resolv.conf` ⇒ propone `dns`; si toca `/etc/ssl/certs/` + ⇒ `tls-certs`. La medición alimenta la tabla; la tabla decide el bit. Ninguno de los dos + ensancha por su cuenta. +- **Consumidor esperándonos**: `plan-jaula-juegos.md` F1 («la jaula sellada con pressure-vessel + + política harkaq del runtime») — un Steam que no puede leer `~/.ssh` sale de este §3. + ### 4. CVE por grafo `hammer affected CVE-X` exacto (grafo fuente→artefacto→instalado) + frontera mínima de diff --git a/recipes/adwaita-hello.toml b/recipes/adwaita-hello.toml new file mode 100644 index 00000000..10376968 --- /dev/null +++ b/recipes/adwaita-hello.toml @@ -0,0 +1,47 @@ +# adwaita-hello — app Adwaita mínima de VALIDACIÓN: prueba que libadwaita-1.a es linkeable de verdad. +# AdwApplication + AdwApplicationWindow + AdwToolbarView. Link 100% estático vía pkg-config --static +# libadwaita-1 + las privadas de gdk/gsk/appstream que el .pc no declara. Mismo patrón que gtk4-hello. +name = "adwaita-hello" +version = "1.7.6" + +[source] +tarball = "https://download.gnome.org/sources/libadwaita/1.7/libadwaita-1.7.6.tar.xz" +sha256 = "5eacc5550f0bdbba6a1568aebf25a3d88f5ee07d6b558becc6fd9487579c9a29" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" + +[build.phases] +configure = "true" +compile = ''' +cat > adw_hello.c <<'CEOF' +#include +static void activate(GtkApplication *app, gpointer user_data) { + GtkWidget *win = adw_application_window_new(app); + gtk_window_set_title(GTK_WINDOW(win), "Adwaita en hammer"); + gtk_window_set_default_size(GTK_WINDOW(win), 400, 260); + GtkWidget *toolbar = adw_toolbar_view_new(); + adw_toolbar_view_add_top_bar(ADW_TOOLBAR_VIEW(toolbar), adw_header_bar_new()); + GtkWidget *status = adw_status_page_new(); + adw_status_page_set_title(ADW_STATUS_PAGE(status), "libadwaita static-musl ✓"); + adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(toolbar), status); + adw_application_window_set_content(ADW_APPLICATION_WINDOW(win), toolbar); + gtk_window_present(GTK_WINDOW(win)); +} +int main(int argc, char **argv) { + AdwApplication *app = adw_application_new("org.hammer.adw", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + int status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); + return status; +} +CEOF +export PKG_CONFIG_PATH=/usr/lib/pkgconfig +zig cc -mcpu=baseline -static adw_hello.c -o adwaita-hello $(pkg-config --cflags --libs --static libadwaita-1 harfbuzz-subset epoxy xkbcommon wayland-client wayland-egl libtiff-4 libjpeg cairo-script-interpreter) +''' +install = "mkdir -p /out/usr/bin && cp adwaita-hello /out/usr/bin/adwaita-hello" + +[deps] +build = ["pkgconf", "libadwaita", "appstream", "libyaml", "curl", "openssl", "libxmlb", "libxml2", "zstd", "gtk4", "pango", "gdk-pixbuf", "cairo", "graphene", "glib", "harfbuzz", "fribidi", "fontconfig", "freetype", "pixman", "libpng", "expat", "libjpeg-turbo", "libtiff", "libepoxy", "wayland", "libxkbcommon", "libdrm", "pcre2", "libffi", "zlib", "mesa"] diff --git a/recipes/bash.toml b/recipes/bash.toml index 461c21bf..d0a65972 100644 --- a/recipes/bash.toml +++ b/recipes/bash.toml @@ -45,4 +45,4 @@ _abuild_phase ''' [deps] -build = ["ncurses", "readline", "linux-headers", "busybox", "make"] +build = ["ncurses", "readline", "linux-headers", "make"] diff --git a/recipes/binutils.toml b/recipes/binutils.toml index 22534b7b..47caf980 100644 --- a/recipes/binutils.toml +++ b/recipes/binutils.toml @@ -43,7 +43,7 @@ link = "dynamic" zig_version = "0.13.0" [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] # --disable-nls: sin gettext (ausente en el toolchain hermético). --disable-werror: binutils promueve diff --git a/recipes/coreutils.toml b/recipes/coreutils.toml index e6b90a55..586ed17f 100644 --- a/recipes/coreutils.toml +++ b/recipes/coreutils.toml @@ -32,7 +32,7 @@ link = "static" flags = ["--enable-single-binary", "--disable-nls"] [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] # install por defecto (make install DESTDIR=/out) deja el multicall en /out/usr/bin/coreutils; lo diff --git a/recipes/dosfstools.toml b/recipes/dosfstools.toml index 296ab225..9653884d 100644 --- a/recipes/dosfstools.toml +++ b/recipes/dosfstools.toml @@ -43,4 +43,4 @@ _abuild_phase ''' [deps] -build = ["linux-headers", "busybox", "make"] +build = ["linux-headers", "make"] diff --git a/recipes/e2fsprogs.toml b/recipes/e2fsprogs.toml index 942cfa68..b18fd76a 100644 --- a/recipes/e2fsprogs.toml +++ b/recipes/e2fsprogs.toml @@ -59,4 +59,4 @@ _abuild_phase ''' [deps] -build = ["linux-headers", "busybox", "pkgconf"] +build = ["linux-headers", "pkgconf"] diff --git a/recipes/flex.toml b/recipes/flex.toml index 21a6ef25..9bf025df 100644 --- a/recipes/flex.toml +++ b/recipes/flex.toml @@ -24,9 +24,6 @@ link = "dynamic" # bueno por-receta ⇒ gcc deja de hacer falta (toolchain 100% zig). No es input del 4/4. SDD 11 §7.2b. zig_version = "0.13.0" -[deps] -build = ["busybox"] - [build.phases] configure = "./configure --prefix=/usr --disable-nls --disable-shared" compile = "make -j\"$(nproc)\"" diff --git a/recipes/fontconfig.toml b/recipes/fontconfig.toml index 17195d7c..eda899e1 100644 --- a/recipes/fontconfig.toml +++ b/recipes/fontconfig.toml @@ -15,4 +15,4 @@ install = "make install DESTDIR=/out" # libpng+zlib: freetype se compila --with-png, así que freetype2.pc trae `Requires: libpng` # (y libpng.pc → zlib); sin ellos pkg-config no resuelve freetype2 y ./configure aborta. [deps] -build = ["freetype", "expat", "pkgconf", "gperf", "python3", "libpng", "zlib", "busybox", "make"] +build = ["freetype", "expat", "pkgconf", "gperf", "python3", "libpng", "zlib", "make"] diff --git a/recipes/gawk.toml b/recipes/gawk.toml index d3e11c2c..5c18555d 100644 --- a/recipes/gawk.toml +++ b/recipes/gawk.toml @@ -18,7 +18,7 @@ link = "static" flags = [] [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] # de build() de Alpine (traducido; el lab provee $CBUILD/$CHOST — Etapa G Fase 3; revisá --shared para estático): diff --git a/recipes/gperf.toml b/recipes/gperf.toml index d29952ab..3f847be9 100644 --- a/recipes/gperf.toml +++ b/recipes/gperf.toml @@ -9,7 +9,7 @@ compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] configure = "CXXFLAGS=\"$CXXFLAGS -std=c++14\" ./configure --prefix=/usr" diff --git a/recipes/gtk4-hello.toml b/recipes/gtk4-hello.toml new file mode 100644 index 00000000..017e29a5 --- /dev/null +++ b/recipes/gtk4-hello.toml @@ -0,0 +1,47 @@ +# gtk4-hello — app GTK4 mínima de VALIDACIÓN: prueba que libgtk-4.a (static) es linkeable de verdad. +# Reutiliza el tarball de GTK4 solo como acarreo de [source] (lo ignora); escribe su propio hello.c y +# lo linkea ESTÁTICO contra todo el cierre GTK4 vía `pkg-config --static gtk4`. Si sella, el toolkit +# de GUI del lab es usable por apps, no solo "compila". deps = cierre .pc completo + gtk4. +name = "gtk4-hello" +version = "4.18.6" + +[source] +tarball = "https://download.gnome.org/sources/gtk/4.18/gtk-4.18.6.tar.xz" +sha256 = "e1817c650ddc3261f9a8345b3b22a26a5d80af154630dedc03cc7becefffd0fa" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" + +[build.phases] +# no-op: el tarball trae meson.build y el lab inyectaría `meson setup` por defecto si omito configure. +configure = "true" +compile = ''' +cat > hammer_hello.c <<'CEOF' +#include +static void activate(GtkApplication *app, gpointer user_data) { + GtkWidget *win = gtk_application_window_new(app); + gtk_window_set_title(GTK_WINDOW(win), "Hola desde hammer"); + gtk_window_set_default_size(GTK_WINDOW(win), 360, 220); + GtkWidget *label = gtk_label_new("GTK4 static-musl ✓ (zig cc)"); + gtk_window_set_child(GTK_WINDOW(win), label); + gtk_window_present(GTK_WINDOW(win)); +} +int main(int argc, char **argv) { + GtkApplication *app = gtk_application_new("org.hammer.hola", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + int status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); + return status; +} +CEOF +# gtk4.pc NO declara Libs.private (asume link dinámico contra libgtk-4.so); para ESTÁTICO hay que sumar +# las privadas que gdk/gsk linkean directo (harfbuzz-subset, epoxy, wayland, xkbcommon, tiff, jpeg). +export PKG_CONFIG_PATH=/usr/lib/pkgconfig +zig cc -mcpu=baseline -static hammer_hello.c -o gtk4-hello $(pkg-config --cflags --libs --static gtk4 harfbuzz-subset epoxy xkbcommon wayland-client wayland-egl libtiff-4 libjpeg cairo-script-interpreter) +''' +install = "mkdir -p /out/usr/bin && cp gtk4-hello /out/usr/bin/gtk4-hello" + +[deps] +build = ["pkgconf", "gtk4", "pango", "gdk-pixbuf", "cairo", "graphene", "glib", "harfbuzz", "fribidi", "fontconfig", "freetype", "pixman", "libpng", "expat", "libjpeg-turbo", "libtiff", "libepoxy", "wayland", "libxkbcommon", "libdrm", "pcre2", "libffi", "zlib", "mesa"] diff --git a/recipes/gtk4.toml b/recipes/gtk4.toml new file mode 100644 index 00000000..e4b78d85 --- /dev/null +++ b/recipes/gtk4.toml @@ -0,0 +1,39 @@ +# gtk4 4.18.6 — el toolkit de GUI. meson static, backend SOLO wayland (sin X11/broadway/win/mac), +# renderer GL vía libepoxy (vulkan disabled), todo lo opcional off (demos/tests/docs/cups/gstreamer/ +# introspection). Corona el stack gráfico C del lab: con esto el corpus puede producir apps GTK reales. +# Deps = cierre transitivo .pc completo (pkg-config estático resuelve Requires.private). +name = "gtk4" +version = "4.18.6" + +[source] +tarball = "https://download.gnome.org/sources/gtk/4.18/gtk-4.18.6.tar.xz" +sha256 = "e1817c650ddc3261f9a8345b3b22a26a5d80af154630dedc03cc7becefffd0fa" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" + +[build.phases] +# GTK4 construye libgtk.a (static_library 'gtk') Y libgtk-4.so; las tools linkean la .so con libgtk_dep, +# imposible en el lab static-musl. Parche: que las tools usen libgtk_static_dep (la .a). El sed es seguro: +# "libgtk_dep" NO es substring de "libgtk_static_dep" ⇒ no toca las que ya usan el estático. +configure = "sed -i 's/libgtk_dep/libgtk_static_dep/g' tools/meson.build && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Ddefault_library=static -Dwayland-backend=true -Dx11-backend=false -Dbroadway-backend=false -Dwin32-backend=false -Dmacos-backend=false -Dvulkan=disabled -Dintrospection=disabled -Dbuild-demos=false -Dbuild-testsuite=false -Dbuild-tests=false -Dbuild-examples=false -Dmedia-gstreamer=disabled -Dprint-cups=disabled -Dprint-cpdb=disabled -Dcloudproviders=disabled -Dsysprof=disabled -Dtracker=disabled -Dcolord=disabled -Df16c=disabled -Ddocumentation=false -Dman-pages=false -Dc_args=-Wno-error=date-time" +compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output" +# meson instala solo libgtk-4.so y genera convenience-libs THIN (gtk/gdk/gsk por separado, referencian +# los .o por ruta → inútiles fuera del build dir). Fusiono los tres en UN archive GORDO libgtk-4.a (embebe +# todos los .o) para que `-lgtk-4` + `-static` linkee de verdad en el lab static-musl. +install = ''' +PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild +rm -f /out/usr/lib/libgtk-4.a +cd output +objs="" +for a in $(find . -name '*.a'); do + d=$(dirname "$a"); b=$(basename "$a") + for o in $(cd "$d" && zig ar t "$b"); do objs="$objs $d/$o"; done +done +zig ar rcs /out/usr/lib/libgtk-4.a $objs +''' + +[deps] +build = ["meson", "samurai", "python3", "pkgconf", "glib", "cairo", "pango", "gdk-pixbuf", "graphene", "libepoxy", "wayland", "wayland-protocols", "libxkbcommon", "libdrm", "fontconfig", "harfbuzz", "fribidi", "libpng", "pixman", "freetype", "expat", "libffi", "pcre2", "zlib", "libjpeg-turbo", "libtiff", "mesa"] diff --git a/recipes/gtksourceview.toml b/recipes/gtksourceview.toml new file mode 100644 index 00000000..0d8159d9 --- /dev/null +++ b/recipes/gtksourceview.toml @@ -0,0 +1,23 @@ +# gtksourceview 5.16.0 — widget de edición de código (resaltado, números de línea…) sobre GTK4. +# Base de editores/IDEs (gnome-text-editor lo usa). meson static. introspection/vapi/docs/tests off. +name = "gtksourceview" +version = "5.16.0" + +[source] +tarball = "https://download.gnome.org/sources/gtksourceview/5.16/gtksourceview-5.16.0.tar.xz" +sha256 = "ab35d420102f3e8b055dd3b8642d3a48209f888189e6254d0ffb4b6a7e8c3566" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" + +[build.phases] +# gtksourceview 5.16 no tiene opción tests; los ejecutables de tests/testsuite linkean gtk4 estático y +# fallan por las privadas (tiff/epoxy/cairo-script). La LIB sí construye → elimino esos subdirs con sed. +configure = "sed -i \"/subdir('tests')/d;/subdir('testsuite')/d\" meson.build && PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Ddefault_library=static -Dintrospection=disabled -Dvapi=false -Ddocumentation=false -Dsysprof=false -Dc_args=-Wno-error=date-time" +compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output" +install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild" + +[deps] +build = ["meson", "samurai", "python3", "pkgconf", "gettext-tiny", "gtk4", "pango", "gdk-pixbuf", "cairo", "graphene", "glib", "harfbuzz", "fribidi", "fontconfig", "freetype", "pixman", "libpng", "expat", "libxml2", "libjpeg-turbo", "libtiff", "libepoxy", "wayland", "wayland-protocols", "libxkbcommon", "libdrm", "pcre2", "libffi", "zlib", "mesa"] diff --git a/recipes/hammer-edit.toml b/recipes/hammer-edit.toml new file mode 100644 index 00000000..175956d1 --- /dev/null +++ b/recipes/hammer-edit.toml @@ -0,0 +1,138 @@ +# hammer-edit — editor de código REAL para el distro: Adwaita + GtkSourceView, abrir/guardar/guardar-como +# (GtkFileDialog), resaltado por extensión, números de línea, apertura de archivos desde la CLI. Link 100% +# estático (gtk4+libadwaita+gtksourceview). No es una demo: es una app instalable y usable. +name = "hammer-edit" +version = "1.0.0" + +[source] +tarball = "https://download.gnome.org/sources/gtksourceview/5.16/gtksourceview-5.16.0.tar.xz" +sha256 = "ab35d420102f3e8b055dd3b8642d3a48209f888189e6254d0ffb4b6a7e8c3566" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" + +[build.phases] +configure = "true" +compile = ''' +cat > hammer_edit.c <<'CEOF' +#include +#include +#include + +typedef struct { GtkWindow *win; GtkSourceBuffer *buf; GFile *file; } App; + +static void set_title(App *a) { + char *name = a->file ? g_file_get_basename(a->file) : g_strdup("Sin título"); + char *full = g_strdup_printf("%s — hammer-edit", name); + gtk_window_set_title(a->win, full); + g_free(name); g_free(full); +} + +static void load_file(App *a, GFile *file) { + char *contents; gsize len; + if (!g_file_load_contents(file, NULL, &contents, &len, NULL, NULL)) return; + gtk_text_buffer_set_text(GTK_TEXT_BUFFER(a->buf), contents, len); + g_free(contents); + g_set_object(&a->file, file); + GtkSourceLanguageManager *lm = gtk_source_language_manager_get_default(); + char *base = g_file_get_basename(file); + GtkSourceLanguage *lang = gtk_source_language_manager_guess_language(lm, base, NULL); + gtk_source_buffer_set_language(a->buf, lang); + g_free(base); + set_title(a); +} + +static void open_cb(GObject *src, GAsyncResult *res, gpointer ud) { + App *a = ud; + GFile *file = gtk_file_dialog_open_finish(GTK_FILE_DIALOG(src), res, NULL); + if (file) { load_file(a, file); g_object_unref(file); } +} +static void on_open(GtkButton *b, gpointer ud) { + App *a = ud; + GtkFileDialog *d = gtk_file_dialog_new(); + gtk_file_dialog_open(d, a->win, NULL, open_cb, a); + g_object_unref(d); +} + +static void save_to(App *a, GFile *file) { + GtkTextIter s, e; + gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(a->buf), &s, &e); + char *text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(a->buf), &s, &e, FALSE); + g_file_replace_contents(file, text, strlen(text), NULL, FALSE, + G_FILE_CREATE_NONE, NULL, NULL, NULL); + g_free(text); + g_set_object(&a->file, file); + set_title(a); +} +static void save_cb(GObject *src, GAsyncResult *res, gpointer ud) { + App *a = ud; + GFile *file = gtk_file_dialog_save_finish(GTK_FILE_DIALOG(src), res, NULL); + if (file) { save_to(a, file); g_object_unref(file); } +} +static void on_save(GtkButton *b, gpointer ud) { + App *a = ud; + if (a->file) { save_to(a, a->file); return; } + GtkFileDialog *d = gtk_file_dialog_new(); + gtk_file_dialog_save(d, a->win, NULL, save_cb, a); + g_object_unref(d); +} + +static App *build_window(GtkApplication *app) { + App *a = g_new0(App, 1); + GtkWidget *win = adw_application_window_new(app); + a->win = GTK_WINDOW(win); + gtk_window_set_default_size(a->win, 820, 580); + GtkWidget *tv = adw_toolbar_view_new(); + GtkWidget *hb = adw_header_bar_new(); + GtkWidget *ob = gtk_button_new_from_icon_name("document-open-symbolic"); + GtkWidget *sb = gtk_button_new_from_icon_name("document-save-symbolic"); + gtk_widget_set_tooltip_text(ob, "Abrir"); + gtk_widget_set_tooltip_text(sb, "Guardar"); + g_signal_connect(ob, "clicked", G_CALLBACK(on_open), a); + g_signal_connect(sb, "clicked", G_CALLBACK(on_save), a); + adw_header_bar_pack_start(ADW_HEADER_BAR(hb), ob); + adw_header_bar_pack_end(ADW_HEADER_BAR(hb), sb); + adw_toolbar_view_add_top_bar(ADW_TOOLBAR_VIEW(tv), hb); + a->buf = gtk_source_buffer_new(NULL); + gtk_source_buffer_set_highlight_syntax(a->buf, TRUE); + GtkWidget *view = gtk_source_view_new_with_buffer(a->buf); + gtk_source_view_set_show_line_numbers(GTK_SOURCE_VIEW(view), TRUE); + gtk_source_view_set_highlight_current_line(GTK_SOURCE_VIEW(view), TRUE); + gtk_source_view_set_auto_indent(GTK_SOURCE_VIEW(view), TRUE); + gtk_widget_add_css_class(view, "monospace"); + GtkWidget *sc = gtk_scrolled_window_new(); + gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sc), view); + adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(tv), sc); + adw_application_window_set_content(ADW_APPLICATION_WINDOW(win), tv); + set_title(a); + return a; +} + +static void activate(GApplication *app, gpointer ud) { + App *a = build_window(GTK_APPLICATION(app)); + gtk_window_present(a->win); +} +static void open_files(GApplication *app, GFile **files, gint n, const char *hint, gpointer ud) { + App *a = build_window(GTK_APPLICATION(app)); + if (n > 0) load_file(a, files[0]); + gtk_window_present(a->win); +} + +int main(int argc, char **argv) { + AdwApplication *app = adw_application_new("org.hammer.edit", G_APPLICATION_HANDLES_OPEN); + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + g_signal_connect(app, "open", G_CALLBACK(open_files), NULL); + int status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); + return status; +} +CEOF +export PKG_CONFIG_PATH=/usr/lib/pkgconfig +zig cc -mcpu=baseline -static hammer_edit.c -o hammer-edit $(pkg-config --cflags --libs --static gtksourceview-5 libadwaita-1 harfbuzz-subset epoxy xkbcommon wayland-client wayland-egl libtiff-4 libjpeg cairo-script-interpreter) +''' +install = "mkdir -p /out/usr/bin && cp hammer-edit /out/usr/bin/hammer-edit" + +[deps] +build = ["pkgconf", "gtksourceview", "libadwaita", "appstream", "libyaml", "curl", "openssl", "libxmlb", "libxml2", "zstd", "gtk4", "pango", "gdk-pixbuf", "cairo", "graphene", "glib", "harfbuzz", "fribidi", "fontconfig", "freetype", "pixman", "libpng", "expat", "libjpeg-turbo", "libtiff", "libepoxy", "wayland", "libxkbcommon", "libdrm", "pcre2", "libffi", "zlib", "mesa"] diff --git a/recipes/incoming-clib/shared-libmandoc.patch b/recipes/incoming-clib/shared-libmandoc.patch new file mode 100644 index 00000000..607934c9 --- /dev/null +++ b/recipes/incoming-clib/shared-libmandoc.patch @@ -0,0 +1,92 @@ +This patch links libmandoc dynamically instead of statically, this +causes the package size to be reduced by roughly 50%. + +See also: https://inbox.vuxu.org/mandoc-tech/2L1YC2WD8JUE5.3QGU3CQ10EGCD@8pit.net/T/#u + +diff --git a/Makefile b/Makefile +index 48c4741..252e11e 100644 +--- a/Makefile ++++ b/Makefile +@@ -367,9 +367,13 @@ WWW_INCS = eqn.h.html \ + tbl_int.h.html \ + tbl_parse.h.html + ++LIBMANDOC = libmandoc.so ++MANDOCLIB = -L. -lmandoc ++ + # === USER CONFIGURATION =============================================== + + include Makefile.local ++CFLAGS += -fPIC + + # === DEPENDENCY HANDLING ============================================== + +@@ -392,7 +396,7 @@ distclean: clean + rm -f Makefile.local config.h config.h.old config.log config.log.old + + clean: +- rm -f libmandoc.a $(LIBMANDOC_OBJS) $(ALL_COBJS) ++ rm -f $(LIBMANDOC) $(LIBMANDOC_OBJS) $(ALL_COBJS) + rm -f mandoc man $(MAIN_OBJS) + rm -f man.cgi $(CGI_OBJS) + rm -f mandocd catman catman.o $(MANDOCD_OBJS) +@@ -432,11 +436,11 @@ base-install: mandoc demandoc soelim + $(INSTALL_MAN) makewhatis.8 \ + $(DESTDIR)$(MANDIR)/man8/$(BINM_MAKEWHATIS).8 + +-lib-install: libmandoc.a ++lib-install: $(LIBMANDOC) + mkdir -p $(DESTDIR)$(LIBDIR) + mkdir -p $(DESTDIR)$(INCLUDEDIR) + mkdir -p $(DESTDIR)$(MANDIR)/man3 +- $(INSTALL_LIB) libmandoc.a $(DESTDIR)$(LIBDIR) ++ $(INSTALL_LIB) $(LIBMANDOC) $(DESTDIR)$(LIBDIR) + $(INSTALL_LIB) eqn.h man.h mandoc.h mandoc_aux.h mandoc_parse.h \ + mdoc.h roff.h tbl.h $(DESTDIR)$(INCLUDEDIR) + $(INSTALL_MAN) mandoc.3 mandoc_escape.3 mandoc_malloc.3 \ +@@ -485,7 +489,7 @@ uninstall: + rm -f $(DESTDIR)$(SBINDIR)/$(BINM_CATMAN) + rm -f $(DESTDIR)$(MANDIR)/man8/mandocd.8 + rm -f $(DESTDIR)$(MANDIR)/man8/$(BINM_CATMAN).8 +- rm -f $(DESTDIR)$(LIBDIR)/libmandoc.a ++ rm -f $(DESTDIR)$(LIBDIR)/$(LIBMANDOC) + rm -f $(DESTDIR)$(MANDIR)/man3/mandoc.3 + rm -f $(DESTDIR)$(MANDIR)/man3/mandoc_escape.3 + rm -f $(DESTDIR)$(MANDIR)/man3/mandoc_malloc.3 +@@ -515,23 +519,26 @@ Makefile.local config.h: configure $(TESTSRCS) + libmandoc.a: $(MANDOC_COBJS) $(LIBMANDOC_OBJS) + $(AR) rs $@ $(MANDOC_COBJS) $(LIBMANDOC_OBJS) + +-mandoc: $(MAIN_OBJS) libmandoc.a +- $(CC) -o $@ $(LDFLAGS) $(MAIN_OBJS) libmandoc.a $(LDADD) ++libmandoc.so: $(MANDOC_COBJS) $(LIBMANDOC_OBJS) ++ $(CC) $(LDFLAGS) -shared -o $@ $(MANDOC_COBJS) $(LIBMANDOC_OBJS) $(LDADD) ++ ++mandoc: $(MAIN_OBJS) $(LIBMANDOC) ++ $(CC) -o $@ $(LDFLAGS) $(MAIN_OBJS) $(MANDOCLIB) $(LDADD) + + man: mandoc + $(LN) mandoc man + +-man.cgi: $(CGI_OBJS) libmandoc.a +- $(CC) $(STATIC) -o $@ $(LDFLAGS) $(CGI_OBJS) libmandoc.a $(LDADD) ++man.cgi: $(CGI_OBJS) $(LIBMANDOC) ++ $(CC) $(STATIC) -o $@ $(LDFLAGS) $(CGI_OBJS) $(MANDOCLIB) $(LDADD) + +-mandocd: $(MANDOCD_OBJS) libmandoc.a +- $(CC) -o $@ $(LDFLAGS) $(MANDOCD_OBJS) libmandoc.a $(LDADD) ++mandocd: $(MANDOCD_OBJS) $(LIBMANDOC) ++ $(CC) -o $@ $(LDFLAGS) $(MANDOCD_OBJS) $(MANDOCLIB) $(LDADD) + +-catman: catman.o libmandoc.a +- $(CC) -o $@ $(LDFLAGS) catman.o libmandoc.a $(LDADD) ++catman: catman.o $(LIBMANDOC) ++ $(CC) -o $@ $(LDFLAGS) catman.o $(MANDOCLIB) $(LDADD) + +-demandoc: $(DEMANDOC_OBJS) libmandoc.a +- $(CC) -o $@ $(LDFLAGS) $(DEMANDOC_OBJS) libmandoc.a $(LDADD) ++demandoc: $(DEMANDOC_OBJS) $(LIBMANDOC) ++ $(CC) -o $@ $(LDFLAGS) $(DEMANDOC_OBJS) $(MANDOCLIB) $(LDADD) + + soelim: $(SOELIM_COBJS) soelim.o + $(CC) -o $@ $(LDFLAGS) $(SOELIM_COBJS) soelim.o diff --git a/recipes/incoming-clib/tests.patch b/recipes/incoming-clib/tests.patch new file mode 100644 index 00000000..e83be096 --- /dev/null +++ b/recipes/incoming-clib/tests.patch @@ -0,0 +1,12 @@ +These tests only work with read/write access to /dev/tty0 (or similar) + +--- a/tests/testsuite.at ++++ b/tests/testsuite.at +@@ -8,7 +8,6 @@ + + m4_include([unittest.at]) + +-m4_include([utils.at]) + m4_include([libcommon.at]) + m4_include([libkeymap.at]) + m4_include([libkbdfile.at]) diff --git a/recipes/incoming-clib/valgrind.patch b/recipes/incoming-clib/valgrind.patch new file mode 100644 index 00000000..3ca04bc4 --- /dev/null +++ b/recipes/incoming-clib/valgrind.patch @@ -0,0 +1,11 @@ +Ref https://github.com/wismill/kbd/commit/0f410510f586e659fbdba9cfc3846be343b8dd30 + +--- a/tests/unittest.at ++++ b/tests/unittest.at +@@ -5,5 +5,5 @@ + ]]) + + m4_define([UNITTEST_MEMCHECK],[ +-AT_CHECK([UNITTEST_RUN_MEMCHECK([$1])],[$2],[$3],[$4],[$5],[$6]) ++AT_CHECK([$1],[$2],[$3],[$4],[$5],[$6]) + ]) diff --git a/recipes/libadwaita.toml b/recipes/libadwaita.toml new file mode 100644 index 00000000..e00a4a95 --- /dev/null +++ b/recipes/libadwaita.toml @@ -0,0 +1,22 @@ +# libadwaita 1.7.6 — los widgets modernos de GNOME sobre GTK4 (Adwaita). meson static. +# Compila sus estilos SCSS con sassc en build. examples/tests/vapi/introspection/docs off. +# deps = gtk4 + su cierre .pc completo + sassc. +name = "libadwaita" +version = "1.7.6" + +[source] +tarball = "https://download.gnome.org/sources/libadwaita/1.7/libadwaita-1.7.6.tar.xz" +sha256 = "5eacc5550f0bdbba6a1568aebf25a3d88f5ee07d6b558becc6fd9487579c9a29" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" + +[build.phases] +configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Ddefault_library=static -Dexamples=false -Dtests=false -Dvapi=false -Dintrospection=disabled -Dgtk_doc=false -Dc_args=-Wno-error=date-time" +compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output" +install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild" + +[deps] +build = ["meson", "samurai", "python3", "pkgconf", "sassc", "appstream", "libyaml", "curl", "openssl", "libxmlb", "libxml2", "zstd", "gtk4", "pango", "gdk-pixbuf", "cairo", "graphene", "glib", "harfbuzz", "fribidi", "fontconfig", "freetype", "pixman", "libpng", "expat", "libjpeg-turbo", "libtiff", "libepoxy", "wayland", "wayland-protocols", "libxkbcommon", "libdrm", "pcre2", "libffi", "zlib", "mesa"] diff --git a/recipes/libarchive.toml b/recipes/libarchive.toml index b368adee..272e95f4 100644 --- a/recipes/libarchive.toml +++ b/recipes/libarchive.toml @@ -25,7 +25,7 @@ target = "x86_64-linux-musl" link = "static" [deps] -build = ["busybox", "make", "zlib"] +build = ["make", "zlib"] [build.phases] # -fno-sanitize=undefined: mismo motivo que zlib — sin él, zig cc emite llamadas UBSan que el diff --git a/recipes/libnl.toml b/recipes/libnl.toml index d3a4e2e6..2f3deef8 100644 --- a/recipes/libnl.toml +++ b/recipes/libnl.toml @@ -23,7 +23,7 @@ link = "static" [deps] # libnl 3.11 regenera sus parsers netlink ⇒ flex (lexer) + bison (parser) + m4 (bison lo invoca). -build = ["flex", "bison", "m4", "busybox", "make"] +build = ["flex", "bison", "m4", "make"] [build.phases] configure = "./configure --build=$CBUILD --host=$CHOST --prefix=/usr --libdir=/usr/lib --disable-shared --enable-static --disable-cli" diff --git a/recipes/libusb.toml b/recipes/libusb.toml index 746e969d..6732b385 100644 --- a/recipes/libusb.toml +++ b/recipes/libusb.toml @@ -38,4 +38,4 @@ make DESTDIR="/out" install ''' [deps] -build = ["linux-headers", "busybox", "make"] +build = ["linux-headers", "make"] diff --git a/recipes/linux-generic.toml b/recipes/linux-generic.toml index 877e889d..ac77c56f 100644 --- a/recipes/linux-generic.toml +++ b/recipes/linux-generic.toml @@ -34,7 +34,7 @@ target = "x86_64-linux-musl" link = "dynamic" [deps] -build = ["flex", "bison", "m4", "openssl", "elfutils", "busybox", "make"] +build = ["flex", "bison", "m4", "openssl", "elfutils", "make"] [build.phases] configure = """ diff --git a/recipes/linux-metal.toml b/recipes/linux-metal.toml index 1dfedda0..1ea90eaf 100644 --- a/recipes/linux-metal.toml +++ b/recipes/linux-metal.toml @@ -72,7 +72,7 @@ target = "x86_64-linux-musl" link = "dynamic" [deps] -build = ["flex", "bison", "m4", "openssl", "elfutils", "busybox", "make"] +build = ["flex", "bison", "m4", "openssl", "elfutils", "make"] [build.phases] configure = """ diff --git a/recipes/linux.toml b/recipes/linux.toml index 694878a5..0216ce29 100644 --- a/recipes/linux.toml +++ b/recipes/linux.toml @@ -36,7 +36,7 @@ # integrity/dns_resolver, no apagable sin desarmar media config) ⇒ su host-tool certs/extract-cert # #incluye openssl. Por eso libelf + openssl se proveen como BOOTSTRAP-LIBS apk en bootstrap-devfs.sh # (status g++/zlib-dev; SEGUROS para el of_tree: hammerd no usa openssl, arje-zero va preseeded). -# deps.build=[flex,bison,m4] son hammer-built; libelf/openssl quedan de-Alpinizables luego con +# deps.build = [] son hammer-built; libelf/openssl quedan de-Alpinizables luego con # recipes/{elfutils,openssl}.toml. # - [DEUDA kikin, 2026-07-16] IO_URING + BPF_SYSCALL explícitos (contrato PLAN-KIKIN §4.bis) van # en linux-metal/linux-generic; ACÁ NO todavía: este of_tree es LOAD-BEARING del selfhost-verify diff --git a/recipes/mtools.toml b/recipes/mtools.toml index 6660e0d9..55a78516 100644 --- a/recipes/mtools.toml +++ b/recipes/mtools.toml @@ -26,9 +26,6 @@ target = "x86_64-linux-musl" link = "static" zig_version = "0.13.0" -[deps] -build = ["busybox"] - [build.phases] configure = "./configure --prefix=/usr --without-x CC='zig cc -mcpu=baseline -target x86_64-linux-musl' LDFLAGS=-static" compile = "make -j\"$(nproc)\"" diff --git a/recipes/npth.toml b/recipes/npth.toml index 5eaa2da1..8f2305cc 100644 --- a/recipes/npth.toml +++ b/recipes/npth.toml @@ -17,7 +17,7 @@ link = "static" flags = [] [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] configure = ''' diff --git a/recipes/pango.toml b/recipes/pango.toml new file mode 100644 index 00000000..2fab4f94 --- /dev/null +++ b/recipes/pango.toml @@ -0,0 +1,16 @@ +# pango 1.57.1 — layout/render de texto i18n (base de GTK). meson static. +name = "pango" +version = "1.57.1" +[source] +tarball = "https://download.gnome.org/sources/pango/1.57/pango-1.57.1.tar.xz" +sha256 = "e65d6d117080dc3aeeb7d8b4b3b518f7383aa2e6cfce23117c623cd624764c2f" +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" +[build.phases] +configure = "PKG_CONFIG_PATH=/usr/lib/pkgconfig PYTHONPATH=/usr/lib/python3.12/site-packages meson setup output --prefix=/usr --buildtype=release --wrap-mode=nodownload --prefer-static -Ddefault_library=static -Dc_args=-Wno-error=date-time -Dintrospection=disabled -Dgtk_doc=false -Dbuild-testsuite=false -Dbuild-examples=false" +compile = "PYTHONPATH=/usr/lib/python3.12/site-packages ninja -C output" +install = "PYTHONPATH=/usr/lib/python3.12/site-packages DESTDIR=/out meson install -C output --no-rebuild" +[deps] +build = ["meson", "samurai", "python3", "pkgconf", "cairo", "harfbuzz", "fribidi", "glib", "freetype", "fontconfig", "pixman", "libpng", "expat", "libffi", "pcre2", "zlib"] diff --git a/recipes/parted.toml b/recipes/parted.toml index 16a62427..bf24bf1d 100644 --- a/recipes/parted.toml +++ b/recipes/parted.toml @@ -52,4 +52,4 @@ make DESTDIR="/out" install # lvm2 (device-mapper) ausente y opcional → --disable-device-mapper. libuuid real vía util-linux # (dep de build); pkgconf resuelve uuid.pc. bash/ncurses/readline innecesarios al binario estático. [deps] -build = ["util-linux", "linux-headers", "pkgconf", "busybox", "make"] +build = ["util-linux", "linux-headers", "pkgconf", "make"] diff --git a/recipes/python3.toml b/recipes/python3.toml index d34e3e20..5b53daf7 100644 --- a/recipes/python3.toml +++ b/recipes/python3.toml @@ -36,7 +36,7 @@ link = "dynamic" zig_version = "0.13.0" [deps] -build = ["zlib", "busybox", "pkgconf"] +build = ["zlib", "pkgconf"] [build.phases] configure = "./configure --prefix=/usr --without-ensurepip --disable-test-modules --with-ensurepip=no CFLAGS=\"-Wno-error=date-time\"" diff --git a/recipes/readline.toml b/recipes/readline.toml index 1b895652..f23f6709 100644 --- a/recipes/readline.toml +++ b/recipes/readline.toml @@ -13,4 +13,4 @@ configure = "./configure --prefix=/usr --disable-shared --enable-static --with-c compile = "make" install = "make install DESTDIR=/out" [deps] -build = ["ncurses", "busybox", "make"] +build = ["ncurses", "make"] diff --git a/recipes/rsync.toml b/recipes/rsync.toml index ed94ab11..cf989e34 100644 --- a/recipes/rsync.toml +++ b/recipes/rsync.toml @@ -54,4 +54,4 @@ make DESTDIR="/out" install # depends de runtime de Alpine (NO build-deps): python3 [deps] -build = ["zlib", "linux-headers", "busybox"] +build = ["zlib", "linux-headers"] diff --git a/recipes/sed.toml b/recipes/sed.toml index d71bbb5c..72721e89 100644 --- a/recipes/sed.toml +++ b/recipes/sed.toml @@ -47,4 +47,4 @@ _abuild_phase # perl era build-dep de Alpine sólo para tests/docs; el tarball trae configure + sed.1 pregenerado. [deps] -build = ["linux-headers", "busybox", "make"] +build = ["linux-headers", "make"] diff --git a/recipes/shadow.toml b/recipes/shadow.toml index c49a5272..d4818b80 100644 --- a/recipes/shadow.toml +++ b/recipes/shadow.toml @@ -74,4 +74,4 @@ install -m644 /dev/null etc/subgid # deps de Alpine remapeadas al catálogo canónico. AUSENTES quitadas: # linux-pam, libbsd, setcap. Sin fcaps (setcap falla en el sandbox) ⇒ sin libcap. [deps] -build = ["linux-headers", "busybox", "make"] +build = ["linux-headers", "make"] diff --git a/recipes/sourceview-hello.toml b/recipes/sourceview-hello.toml new file mode 100644 index 00000000..c7426972 --- /dev/null +++ b/recipes/sourceview-hello.toml @@ -0,0 +1,57 @@ +# sourceview-hello — VALIDACIÓN del editor: ventana Adwaita con un GtkSourceView (resaltado C, números +# de línea) editable. Junta libadwaita + gtksourceview + gtk4, link 100% estático. Es, de hecho, el +# esqueleto de un editor de código real para el distro. +name = "sourceview-hello" +version = "5.16.0" + +[source] +tarball = "https://download.gnome.org/sources/gtksourceview/5.16/gtksourceview-5.16.0.tar.xz" +sha256 = "ab35d420102f3e8b055dd3b8642d3a48209f888189e6254d0ffb4b6a7e8c3566" + +[build] +compiler = "zig-cc" +target = "x86_64-linux-musl" +link = "static" + +[build.phases] +configure = "true" +compile = ''' +cat > sv_hello.c <<'CEOF' +#include +#include +static void activate(GtkApplication *app, gpointer user_data) { + GtkWidget *win = adw_application_window_new(app); + gtk_window_set_title(GTK_WINDOW(win), "Editor hammer"); + gtk_window_set_default_size(GTK_WINDOW(win), 640, 420); + GtkWidget *toolbar = adw_toolbar_view_new(); + adw_toolbar_view_add_top_bar(ADW_TOOLBAR_VIEW(toolbar), adw_header_bar_new()); + GtkSourceBuffer *buf = gtk_source_buffer_new(NULL); + GtkSourceLanguageManager *lm = gtk_source_language_manager_get_default(); + GtkSourceLanguage *lang = gtk_source_language_manager_get_language(lm, "c"); + if (lang) gtk_source_buffer_set_language(buf, lang); + gtk_text_buffer_set_text(GTK_TEXT_BUFFER(buf), + "#include \nint main(void){\n printf(\"hola hammer\\n\");\n return 0;\n}\n", -1); + GtkWidget *view = gtk_source_view_new_with_buffer(buf); + gtk_source_view_set_show_line_numbers(GTK_SOURCE_VIEW(view), TRUE); + gtk_widget_add_css_class(view, "monospace"); + GtkWidget *scroll = gtk_scrolled_window_new(); + gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scroll), view); + adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(toolbar), scroll); + adw_application_window_set_content(ADW_APPLICATION_WINDOW(win), toolbar); + gtk_window_present(GTK_WINDOW(win)); +} +int main(int argc, char **argv) { + AdwApplication *app = adw_application_new("org.hammer.editor", G_APPLICATION_DEFAULT_FLAGS); + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + int status = g_application_run(G_APPLICATION(app), argc, argv); + g_object_unref(app); + return status; +} +CEOF +export PKG_CONFIG_PATH=/usr/lib/pkgconfig +zig cc -mcpu=baseline -static sv_hello.c -o sourceview-hello $(pkg-config --cflags --libs --static gtksourceview-5 libadwaita-1 harfbuzz-subset epoxy xkbcommon wayland-client wayland-egl libtiff-4 libjpeg cairo-script-interpreter) +''' +install = "mkdir -p /out/usr/bin && cp sourceview-hello /out/usr/bin/sourceview-hello" + +[deps] +build = ["pkgconf", "gtksourceview", "libadwaita", "appstream", "libyaml", "curl", "openssl", "libxmlb", "libxml2", "zstd", "gtk4", "pango", "gdk-pixbuf", "cairo", "graphene", "glib", "harfbuzz", "fribidi", "fontconfig", "freetype", "pixman", "libpng", "expat", "libjpeg-turbo", "libtiff", "libepoxy", "wayland", "libxkbcommon", "libdrm", "pcre2", "libffi", "zlib", "mesa"] diff --git a/recipes/sqlite.toml b/recipes/sqlite.toml index 7bf41ae4..777bef07 100644 --- a/recipes/sqlite.toml +++ b/recipes/sqlite.toml @@ -9,7 +9,7 @@ compiler = "zig-cc" target = "x86_64-linux-musl" link = "static" [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] configure = "./configure --prefix=/usr --disable-shared --enable-static" diff --git a/recipes/tar.toml b/recipes/tar.toml index ede1baf2..b64c788e 100644 --- a/recipes/tar.toml +++ b/recipes/tar.toml @@ -18,7 +18,7 @@ link = "static" flags = [] [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] # de build() de Alpine (traducido; el lab provee $CBUILD/$CHOST — Etapa G Fase 3; revisá --shared para estático): diff --git a/recipes/util-linux.toml b/recipes/util-linux.toml index dcc866a0..babc2e78 100644 --- a/recipes/util-linux.toml +++ b/recipes/util-linux.toml @@ -73,4 +73,4 @@ make DESTDIR="/out" install # deps de Alpine/nix remapeadas al catálogo canónico. AUSENTES quitadas: # autoconf/automake/po4a/libxcrypt/sqlite/linux-pam/libcap-ng/systemd-minimal-libs. [deps] -build = ["linux-headers", "busybox", "make"] +build = ["linux-headers", "make"] diff --git a/recipes/which.toml b/recipes/which.toml index a11cbb5a..3110d2d5 100644 --- a/recipes/which.toml +++ b/recipes/which.toml @@ -18,7 +18,7 @@ link = "static" flags = [] [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] # de build() de Alpine (traducido; el lab provee $CBUILD/$CHOST — Etapa G Fase 3; revisá --shared para estático): diff --git a/recipes/wpa_supplicant.toml b/recipes/wpa_supplicant.toml index 54307c39..1eaa07f5 100644 --- a/recipes/wpa_supplicant.toml +++ b/recipes/wpa_supplicant.toml @@ -23,7 +23,7 @@ target = "x86_64-linux-musl" link = "static" [deps] -build = ["libnl", "busybox", "make"] +build = ["libnl", "make"] [build.phases] configure = ''' diff --git a/recipes/xorriso.toml b/recipes/xorriso.toml index c559a94a..5a15d582 100644 --- a/recipes/xorriso.toml +++ b/recipes/xorriso.toml @@ -43,7 +43,7 @@ link = "static" zig_version = "0.13.0" [deps] -build = ["busybox", "make"] +build = ["make"] [build.phases] configure = "./configure --prefix=/usr --disable-libreadline --disable-libedit --disable-libacl --disable-xattr --disable-zlib --disable-libbz2 --disable-libcdio CC='zig cc -mcpu=baseline -target x86_64-linux-musl' LDFLAGS=-static" diff --git a/recipes/zlib.toml b/recipes/zlib.toml index 126e5520..cc9cfd5a 100644 --- a/recipes/zlib.toml +++ b/recipes/zlib.toml @@ -25,7 +25,7 @@ target = "x86_64-linux-musl" link = "static" [deps] -build = ["make"] +build = ["make", "binutils"] [build.phases] # --static: sólo libz.a (sin .so; mrustc/rustc enlazan estático). --prefix=/usr: zlib.h→/usr/include, diff --git a/scripts/harkaq/runtime-policy.sh b/scripts/harkaq/runtime-policy.sh index 7019ac7f..01658ffb 100755 --- a/scripts/harkaq/runtime-policy.sh +++ b/scripts/harkaq/runtime-policy.sh @@ -62,6 +62,21 @@ if [ -z "$propios" ]; then echo " ⇒ política Landlock: sólo \`ro $BIN\`. Es el caso de un estático que no abre ficheros." else echo "$propios" | sed 's/^/ ro /' + # CONTACTO con el §3 (clases de servicio, diseño de Fable 5): la medición no sólo lista + # paths — propone la CLASE. El path va a Landlock (detalle, userspace); la clase va al bit + # del u32 firmado (frontera, Ring 0). La medición ALIMENTA la tabla; la tabla decide el bit. + # Ninguno ensancha por su cuenta (D3). + clases="" + echo "$propios" | grep -qE '/etc/(resolv\.conf|hosts)' && clases="$clases dns" + echo "$propios" | grep -qE '/etc/ssl/certs' && clases="$clases tls-certs" + echo "$propios" | grep -qE '/usr/share/zoneinfo|/etc/TZ' && clases="$clases tz" + echo "$propios" | grep -qE '/dev/log' && clases="$clases syslog" + if [ -n "$clases" ]; then + echo + echo " ── clases de servicio detectadas (§3: van al u32 firmado, NO a Landlock):" + for c in $clases; do echo " $c"; done + echo " ⇒ declarar por nombre en la ConcesionCapacidad; el resto de arriba es Landlock." + fi echo - echo " ⇒ pegar en la política Landlock del binario instalado." + echo " ⇒ los `ro` van a la política Landlock del binario instalado." fi diff --git a/scripts/juez.sh b/scripts/juez.sh new file mode 100755 index 00000000..d10f551e --- /dev/null +++ b/scripts/juez.sh @@ -0,0 +1,104 @@ +#!/bin/sh +# juez.sh — JUEZ MECÁNICO del bucle agéntico (SDD 17 §10). +# +# agente propone receta → harkaq veredicto → granja reproduce ×2 → catálogo acepta +# +# Sin humano en el medio para la parte mecánica: el humano decide QUÉ construir; el juez decide +# si lo construido MERECE entrar al catálogo, y lo decide con evidencia, no con opinión. +# +# scripts/juez.sh recipes/zlib.toml +# +# Dos preguntas, dos veredictos, ninguno negociable: +# 1. ¿HERMÉTICO? harkaq (SDD 16): ¿usó algo que no declaró? El kernel responde. +# `denials=[]` no se cree, se GANA (el canario lo demuestra — D9). +# 2. ¿REPRODUCIBLE? consenso (SDD 17 §1): N builders independientes, ¿el mismo hash? +# Si sí, el artefacto es confiable SIN FIRMA. +# +# Si falla, el juez no dice "no" a secas: dice POR QUÉ y qué hacer. +# - Impuro → harkaq-suggest: "declarar dep: make" (arreglo mecánico) +# - Divergente → why-differs: qué fichero, qué causa (codegen/timestamp/build-id) +# +# Es el bucle que el SDD 08 §4 pide ("la IA propone, el sistema reproduce, el humano commitea") +# con la pieza que faltaba: un juez que la IA no puede convencer, sólo satisfacer. +set -eu + +RECETA="${1:?uso: juez.sh }" +HUB="$(cd "$(dirname "$0")/.." && pwd)" +cd "$HUB" +n=$(basename "$RECETA" .toml) +BUILDERS="${BUILDERS:-2}" + +echo "══════ JUEZ MECÁNICO — $n" +echo + +# ── 1. ¿HERMÉTICO? (harkaq) +echo "── 1/2 ¿usó algo que no declaró? [harkaq, SDD 16]" +if [ ! -x "${HARKAQ_BIN:-$HOME/.cache/harkaq}/harkaq-audit" ]; then + echo " ⊘ harkaq no está compilado ⇒ SIN EVIDENCIA. El juez NO afirma hermeticidad." + echo " (compilar scripts/harkaq/*.c y `setcap cap_audit_read` — ver scripts/harkaq/README.md)" + veredicto_h="sin-evidencia" +else + export HARKAQ=1 HARKAQ_BIN="${HARKAQ_BIN:-$HOME/.cache/harkaq}" + export HARKAQ_BASE="${HARKAQ_BASE:-$HARKAQ_BIN/base.policy}" HARKAQ_TIMEOUT="${HARKAQ_TIMEOUT:-200}" + # Nombre ÚNICO por corrida: con uno fijo, la 2ª vez `hammer build` pega en CACHÉ, no + # construye nada, no hay veredictos y el juez dice "sin evidencia" — un falso negativo que + # parece un problema de la receta. (Gotcha conocido; me mordió al probar el juez.) + uniq="$n-juez-$$" + tmp="$(dirname "$RECETA")/.juez-$n.toml" + sed -E "s/^(name\s*=\s*)\"$n\"/\1\"$uniq\"/" "$RECETA" > "$tmp" + out=$(timeout "${POR:-600}" ./target/debug/hammer build "$tmp" --store "$PWD/store" 2>&1 || true) + rm -f "$tmp"; rm -rf store/*-"$uniq" 2>/dev/null || true + veredictos=$(echo "$out" | grep '^\[harkaq\] {' | sed 's/^\[harkaq\] //') + deuda="" + if [ -z "$veredictos" ]; then + echo " ⊘ sin veredicto (¿caché? ¿el build ni arrancó?) ⇒ SIN EVIDENCIA" + veredicto_h="sin-evidencia" + else + veredicto_h="hermetico" + i=0 + echo "$veredictos" | while IFS= read -r v; do :; done + printf '%s\n' "$veredictos" > /tmp/.juez-v + while IFS= read -r v; do + i=$((i + 1)); echo "$v" > /tmp/.juez-1 + est=$(scripts/harkaq/harkaq-verdict.py /tmp/.juez-1 "$HARKAQ_BASE" --human 2>/dev/null | head -1 | sed 's/^ *estado: //;s/ .*//') + echo " fase $i: ${est:-?}" + [ "$est" = "Impuro" ] && { veredicto_h="impuro"; \ + scripts/harkaq/harkaq-suggest.py /tmp/.juez-1 "$HARKAQ_BASE" "$PWD/store" "$PWD/recipes" "$RECETA" 2>/dev/null | sed 's/^/ /'; } + [ "$est" = "SinEvidencia" ] && veredicto_h="sin-evidencia" + done < /tmp/.juez-v + # el while corre en subshell: recuperar el peor veredicto por marcador + grep -q '"estado":"Impuro"' /tmp/.juez-v && veredicto_h="impuro" + grep -q '"estado":"SinEvidencia"' /tmp/.juez-v && veredicto_h="sin-evidencia" + fi +fi +echo + +# ── 2. ¿REPRODUCIBLE? (consenso) +echo "── 2/2 ¿N builders independientes dan el mismo hash? [consenso, SDD 17 §1]" +if consenso=$(BUILDERS="$BUILDERS" timeout "${POR_CONSENSO:-1200}" scripts/consenso.sh "$RECETA" "$BUILDERS" 2>&1); then + echo "$consenso" | grep -E '✅|builder' | sed 's/^/ /' + veredicto_r="consenso" +else + rc=$? + echo "$consenso" | grep -E '⚠️|builder|SIN CONSENSO' | sed 's/^/ /' + [ "$rc" = 1 ] && veredicto_r="divergencia" || veredicto_r="sin-consenso" + if [ "$veredicto_r" = divergencia ]; then + echo " ── why-differs (SDD 17 §2) explicaría la divergencia:" + echo " scripts/why-differs.py --store ./store" + fi +fi +echo + +# ── VEREDICTO +echo "══════ VEREDICTO" +if [ "$veredicto_h" = hermetico ] && [ "$veredicto_r" = consenso ]; then + echo " ✅ ACEPTAR — no usó nada sin declarar Y $BUILDERS builders lo reprodujeron bit a bit." + echo " El catálogo puede confiar en este artefacto sin firma y sin revisión humana del build." + exit 0 +fi +echo " ❌ NO ACEPTAR" +[ "$veredicto_h" = impuro ] && echo " · hermeticidad: usa algo sin declarar (ver la sugerencia arriba: es una línea)" +[ "$veredicto_h" = sin-evidencia ] && echo " · hermeticidad: SIN EVIDENCIA — no se afirma nada (D9: un lector ciego y un build limpio son idénticos)" +[ "$veredicto_r" = divergencia ] && echo " · reproducibilidad: los builders NO coinciden ⇒ hay un canal impuro" +[ "$veredicto_r" = sin-consenso ] && echo " · reproducibilidad: no hubo suficientes builders con hash" +exit 1