Cómo relanzar (run-qemu-desktop.sh), verificar sin ojos humanos (screendump por el
monitor QEMU + STATUS del serial), reconstruir la imagen, y la tabla de los 7 fixes
que lo hacen andar + los gotchas de operación (serial stale, pkill auto-mata, OVMF
VARS stale → TianoCore). Para relanzar/verificar, no rediagnosticar.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
El worker efímero muele KDE 24/7; este cron en el laptop recoge su store sellado
(worker->laptop, CAS merge seguro), siembra recetas nuevas (laptop->worker) y regenera
el grafo de estado, commiteando SÓLO docs/state/*.json (el avance que el humano sigue).
NO promueve incoming-kde->canónico (decisión de clasificación humana). Robusto a
worker-ausente (dead-man ya lo mató por idle). KDE: 66/206 sellado.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tanda de base libs KDE construidas en el laptop mientras qtbase compila en background. qtbase (la
raíz, ↑117) va por 400/2163 objetos. libsndfile falló por fetch de red (no código).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MOTIVO: 'estábamos haciendo kde'. La cola recipes/incoming-kde/ (206 recetas) era punto ciego del
grafo (sólo miraba recipes/ top-level). Modo --kde: build-state.py/build-state-view.py cubren la cola
KDE (sombreando canónicas homónimas sibling-first, como el sandbox) → build-state-kde.{json,html}.
CAUSA de la deriva (193/206 en deuda): fui YO — esta sesión re-sellé pkgconf y samurai (arreglos
static), y 194 recetas KDE declaran pkgconf, 142 samurai ⇒ re-hash en cascada de todo el árbol. El
sistema determinista funcionando: cambia un input base, cascan los dependientes. Deuda legítima.
DESBLOQUEO (el 'GUI rompe en el laptop' era sólo cairo/pango, NO la base): construida en el laptop
toda la base KDE guiado por el orden de ataque del grafo — extra-cmake-modules, util-macros,
xorgproto, xcb-proto, wayland, libdrm, dbus, icu4c, util-linux, fontconfig, pixman, glib, freetype,
harfbuzz, fribidi, libXau/libXdmcp, la cadena X11 (xtrans/libxcb/libX11/libXext/libXrender/libXfixes/
libXi), la familia xcb-util, libxkbcommon, wayland-protocols, mesa (24.0.9 iris-only, sin LLVM), y
los -shared. KDE 9→39 selladas. qtbase (↑117, la raíz) quedó DESBLOQUEADO y compilando.
DISCO: el build llenó el disco (100%). Liberados 82G borrando work/sources (57G, se re-extrae solo)
y .farm-harvest (26G, verificado 100% redundante en el store, CAS).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Señal fuerte para Rust: la receta copia su binario de target/release/ en las fases. Medido 225
recetas, 0 con dep go ⇒ sin falsos positivos con Go (findutils entra bien: es uutils/findutils, find
en Rust). LÍMITE: un crate BuildSys::Cargo PURO sin fase install propia (zellij) no deja rastro en el
TOML y cae a 'c' — sólo se ve bajando la fuente, que el generador no hace.
Efecto: clases c 322→141, rust 45→226 (la mayoría eran Rust auto sin fase cargo explícita). Y la
LECTURA de la deuda cambia: la deuda C REAL es sólo 8 (casi toda saldada esta sesión), no 74. Lo que
queda es Rust (15, CLI pesados → granja), GUI (29 → granja), Go (5 → worker), kernel (4).
musl sellado (base). Avance: sealed 703→704, debt 53→52.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Tres tandas más de C-base de sistema, todas verifican (MIENTEN 0): perl (background, desbloquea 8),
la cadena curl/ca-certificates/gnupg, y bwrap dosfstools e2fsprogs gzip htop iproute2 iputils jq kbd
lz4 libsodium libuv mandoc parted pciutils procps-ng rsync shadow strace usbutils dhcpcd git vim
wget openssh tmux xorriso wpa_supplicant libssh2.
Avance acumulado de la sesión: sealed 647→703 (+56), debt 109→53. La deuda C-base cayó 74→18, y de
esos 18 la mayoría son Rust CLI mal-clasificados como 'c' (amp/broot/delta/gitui/zellij…) + musl.
La deuda que queda es GUI (29, granja), Rust (5), kernel (4), go (5).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Segunda tanda de sistema-base en el laptop, todas C puras listas: libudev-zero mtdev libevdev npth
libusb libevent libassuan libksba socat less nano sed gawk doas. MIENTEN 0 en las link=static.
Avance acumulado de la sesión: sealed 647→671 (+24), debt 109→85. La deuda C-base bajó 74→50; la
GUI (29) sigue intacta para la granja, como manda el orden de ataque (glib/wayland/pixman ↑).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Construidas y selladas en el laptop (C-base, listas, no-GUI, sistema): zstd (desbloquea 10), xz,
tar, tree, tzdata, tig, scdoc, when. Todas verifican: MIENTEN 0 en las link=static. Es progreso
real visible en el grafo — el resto de la deuda de alto impacto es GUI-céntrica (glib/wayland/pixman)
y va a la granja, como muestra el orden de ataque.
Snapshot del grafo actualizado: sealed 647→655, debt 109→101, never 8.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
El grafo ahora computa, sobre las dependencias, dos campos por receta:
blocked_by — deps que están en deuda (lo que impide construirla ya)
unblocks — cuántas recetas EN DEUDA la declaran como dep (su impacto de desbloqueo)
Una receta en deuda sin blocked_by es construible YA; ordenadas por unblocks desc, dan el orden que
libera el grafo más rápido. La vista muestra la pastilla ↑N en las filas listas y ordena por ahí.
Top de impacto (todo el stack GUI concentrado, más zstd/perl de C-base):
glib ↑14 wayland ↑13 pixman ↑12 libdrm ↑11 fontconfig ↑11 zstd ↑10 libxkbcommon ↑9 perl ↑8
Es la guía para cuando se levante la granja: construir esas primero desbloquea el grueso.
De paso, diagnóstico de las 8 'never' (ninguna es cruft ni bug): dwarves BLOQUEADA-documentada
(necesita libdw, elfutils da sólo libelf a propósito — sub-proyecto elfutils-libdw); llimphi-counter
es un EJEMPLO/plantilla intencional; las otras 6 son imports Go/Rust que van al worker. Y confirmado
parseando: 0 recetas con FIXME real en el campo sha256 (el grep decía 43, todas comentarios) — otra
vez grep miente, el grafo (parsea) dice la verdad.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Dashboard self-contained (sin recursos externos, tema claro/oscuro) que rinde build-state.json para
VER y SEGUIR: barra de avance del corpus, tiles por estado, reparto de deuda por clase, y los huecos
en ORDEN DE ATAQUE. Ese último es el uso accionable del grafo: cada receta en deuda muestra sus deps
coloreadas por estado; una fila 'lista' tiene todas sus deps al día (construible ya), una 'espera N'
depende de N recetas también en deuda. Foto actual: 117 en deuda, 71 listas ahora.
Publicado como Artifact para verlo en el navegador; el HTML también queda en el repo (abrir con
file://). Regenerar ambos: scripts/build-state.py && scripts/build-state-view.py.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
El estado real del build vivía disperso —en mi cabeza, en docs que envejecen (matar-gcc decía 47,
eran 16), en el store (que guarda TODOS los sellados históricos, no el vigente)— y cada medición a
mano mentía distinto. Este generador lo deriva de la ÚNICA fuente de verdad (recetas + hammer hash
+ store) a un JSON firme. El git diff de ese fichero ES el avance entre dos corridas: qué se saldó,
qué se rompió, qué cambió de estado.
NODO = receta {name, class, link, compiler, deps[], hash, state}:
sealed — el artefacto del hash VIGENTE está en el store (al día)
debt — hay sellados históricos pero ninguno vigente (cambió, falta rebuild)
never — sin ningún sellado
unhashable — hammer hash falló (hueco real)
ARISTA = dep de build. El grafo CIERRA (0 deps huérfanas) y topo-ordena sin ciclos.
Foto inicial (764 recetas): sealed 647 | debt 109 | never 8. Deuda por clase: c=74 go=5 gui=29
kernel=4 rust=5. Clases: go 362, c 322, rust 45, gui 30, kernel 5.
Validado contra lo que sé de esta sesión: samurai/which sealed, curl/openssl debt, helix sealed
(rust/gcc), naabu sealed (dynamic/go), mesa debt (gui), linux debt (kernel). Todos correctos.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
Deps de Kconfig verificadas contra el tag v6.16.12 (kernel.org):
NTSYNC sin deps; SCHED_CLASS_EXT depende de DEBUG_INFO_BTF ⇒ tarea propia
(receta dwarves + repro de BTF). Re-sellado disparado en el worker.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
El SDD 16 dejó abierto: '¿el vector page-cache de copy.fail sobrevive a un
ruleset que deniegue escritura a nivel de inode? Investigar antes de afirmar
nada'. Investigado en un fs AISLADO (loop en un worker efímero, nunca el fs del
usuario):
escribir al artefacto sellado → EPERM
dd como ROOT → Operation not permitted (ni root)
machacar los bytes POR DEBAJO (device)+leer→ Input/output error
El tercero ES el vector de copy.fail: modificar el fichero por debajo del fs. El
kernel detecta la corrupción AL LEER (el Merkle no cuadra) y rechaza la lectura.
⇒ fs-verity mata el vector. Landlock read-only no alcanzaba; fs-verity sí.
Costo medido, y corrige al SDD 17 §5: 'hash = identidad' es FALSO — fs-verity usa
Merkle SHA-256, hammer direcciona con BLAKE3 ⇒ son DOS hashes, no uno. Y ext4
exige -O verity Y blocksize = PAGE_SIZE (con 1024 el mount falla:
'Unsupported blocksize for fs-verity'). No es gratis, pero es barato para lo que da.
NO se tocó el fs del laptop (habilitar verity pediría tune2fs sobre la partición
del usuario): el experimento corrió en un loop device de un worker descartable.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
El firmware del tester reparo el GPT dd-eado en el POST y dejo el header
primario invalido (entradas apuntadas a LBA 2016, presentes en LBA 2):
Linux sin gpt en cmdline no cae al respaldo, no vio particiones y la
telemetria MIRADALOG murio en RAM. Con gpt el kernel usa el respaldo.
Documentado: greeter por nouveau GL validado en metal; input muerto queda
abierto con el plan de evidencia para el proximo viaje.
Test real (worker + volumen + helper), no en el papel. Las 3 piezas:
1. worker midió lz4+bzip2 → volumen
2. tras 1 ciclo idle SE AUTO-ELIMINÓ (verificado: el server desapareció solo)
3. volumen SOBREVIVIÓ con los 2 verdicts; helper efímero ccx13 los recogió al
hub y se auto-destruyó
3 bugs cazados EN EL TEST (no adivinados):
- falta --exclude /work: work/=69GB colgó el rsync del up horas
- cpx11 'unsupported' en hel1 (AMD sin stock) → ccx13
- collect llamaba harvest con 'local' (rsync a un worker inexistente): ahora
sólo recoge; clasificar es paso aparte (worker mide, hub clasifica)
+ auto-delete por API REST (curl+metadata), NO hcloud CLI (la golden no lo trae).
El ID propio sale del metadata service, no del nombre.
Cierra los 2 huecos de la 1ª campaña: idle cobrando (ahora auto-delete) y
dependencia de que yo esté viva (ahora el volumen persiste). Runbook:
docs/runbooks/harkaq-granja-volumen.md. Volumen clausurado tras el test (€0).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>