harkaq: revertir busybox (era runtime base, rompía builds) + coordinar el §3 con Fable 5
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 <noreply@anthropic.com>
This commit is contained in:
@@ -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 <su binario>` 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
|
||||
|
||||
@@ -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 <adwaita.h>
|
||||
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"]
|
||||
+1
-1
@@ -45,4 +45,4 @@ _abuild_phase
|
||||
'''
|
||||
|
||||
[deps]
|
||||
build = ["ncurses", "readline", "linux-headers", "busybox", "make"]
|
||||
build = ["ncurses", "readline", "linux-headers", "make"]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -43,4 +43,4 @@ _abuild_phase
|
||||
'''
|
||||
|
||||
[deps]
|
||||
build = ["linux-headers", "busybox", "make"]
|
||||
build = ["linux-headers", "make"]
|
||||
|
||||
@@ -59,4 +59,4 @@ _abuild_phase
|
||||
'''
|
||||
|
||||
[deps]
|
||||
build = ["linux-headers", "busybox", "pkgconf"]
|
||||
build = ["linux-headers", "pkgconf"]
|
||||
|
||||
@@ -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)\""
|
||||
|
||||
@@ -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"]
|
||||
|
||||
+1
-1
@@ -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):
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
@@ -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 <gtk/gtk.h>
|
||||
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"]
|
||||
@@ -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"]
|
||||
@@ -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"]
|
||||
@@ -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 <adwaita.h>
|
||||
#include <gtksourceview/gtksource.h>
|
||||
#include <string.h>
|
||||
|
||||
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"]
|
||||
@@ -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
|
||||
@@ -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])
|
||||
@@ -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])
|
||||
])
|
||||
@@ -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"]
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+1
-1
@@ -38,4 +38,4 @@ make DESTDIR="/out" install
|
||||
'''
|
||||
|
||||
[deps]
|
||||
build = ["linux-headers", "busybox", "make"]
|
||||
build = ["linux-headers", "make"]
|
||||
|
||||
@@ -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 = """
|
||||
|
||||
@@ -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 = """
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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)\""
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ link = "static"
|
||||
flags = []
|
||||
|
||||
[deps]
|
||||
build = ["busybox", "make"]
|
||||
build = ["make"]
|
||||
|
||||
[build.phases]
|
||||
configure = '''
|
||||
|
||||
@@ -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"]
|
||||
+1
-1
@@ -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"]
|
||||
|
||||
@@ -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\""
|
||||
|
||||
@@ -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"]
|
||||
|
||||
+1
-1
@@ -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"]
|
||||
|
||||
+1
-1
@@ -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"]
|
||||
|
||||
+1
-1
@@ -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"]
|
||||
|
||||
@@ -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 <adwaita.h>
|
||||
#include <gtksourceview/gtksource.h>
|
||||
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 <stdio.h>\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"]
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+1
-1
@@ -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):
|
||||
|
||||
@@ -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"]
|
||||
|
||||
+1
-1
@@ -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):
|
||||
|
||||
@@ -23,7 +23,7 @@ target = "x86_64-linux-musl"
|
||||
link = "static"
|
||||
|
||||
[deps]
|
||||
build = ["libnl", "busybox", "make"]
|
||||
build = ["libnl", "make"]
|
||||
|
||||
[build.phases]
|
||||
configure = '''
|
||||
|
||||
@@ -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"
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
#!/bin/sh
|
||||
# juez.sh <receta> — 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 <receta.toml>}"
|
||||
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 <hashA> <hashB> --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
|
||||
Reference in New Issue
Block a user