Commit Graph
761 Commits
Author SHA1 Message Date
sergioandClaude Fable 5 7fa12ed7ce piloto harkaq-trace MEDIDO en builds reales: ceguera-overlay confirmada (0 eventos de store, 206 de binds) y salida validada — marcar /proc/<pid-bwrap>/root cae en el SB del overlay y los paths salen en el idioma de la política; zlib-ng SELLADA b3:93d1da8a al 1er intento; dwarves BLOQUEADA (elfutils sellado sin libdw ⇒ pide variante elfutils-libdw)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 00:05:54 -04:00
sergioandClaude Opus 4.8 dac5bbb1f7 matar-gcc: wget migrada a zig-cc — era la única receta C con gcc sin justificación
Sin parches ni flags: el config.sub de wget 1.25.0 ya conoce -musl* y el
configure no se atraganta con AR="zig ar". Bit-repro verificado (2 builds
desde cero, mismo hash) y la ruta openssl viva (descarga HTTPS real, exit 0).

Como link=static, el ELF no tiene sección dinámica: cero NEEDED ⇒ no arrastra
libgcc_s/libstdc++ de Alpine. El comentario viejo listaba gcc como parte de la
de-Alpinización, que era justo al revés; corregido.

30 migradas. Quedan 17: 12 Rust con sys-crate C (cc-rs invoca el compilador del
sistema desde los build-scripts), 4 matraca dura, procps-ng en vuelo.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 00:04:38 -04:00
sergioandClaude Fable 5 d48f9be636 zlib-ng 2.2.4 + dwarves 1.30 al catálogo (tanda planes-freebsd-2, sha256 verificados)
zlib-ng: el veredicto T5 hecho receta — dispatch SIMD en runtime en vez de
variantes v3; modo ZLIB_COMPAT, zlib.toml intocada (dep del frente rust).
dwarves: pahole para destrabar sched-ext; el kernel NO lo declara aún (el
análisis de repro BTF/pahole-skew va primero). Ambas al worker.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 23:52:24 -04:00
sergioandClaude Fable 5 91496007ca harkaq-trace: la traza POSITIVA de la clausura (plan-freebsd T1.1-T1.2, prior art filemon/META MODE)
- harkaq-trace.c: fanotify FAN_MARK_FILESYSTEM — agnóstico de mount-ns, el
  tracer en el HOST ve los open() de dentro del bwrap (ptrace lo deniega el
  seccomp D4; audit sólo emite denegaciones). Crudo y tonto a propósito
  (reparto Q1c); D9: sin fanotify ⇒ exit 3 SinEvidencia, jamás traza vacía.
- harkaq-trace-norm.py: canoniza (drop /proc /sys /dev /tmp /out /src, dedupe,
  orden estable — la lección nº1 de META MODE) + atribución por dep con
  --resumen = la señal de PODA (T1.4): dep declarada con 0 toques = grasa.
- VALIDADO: modo --fs como root (worker, 5s, sin tocar colas): capturó
  exactamente zlib.h + 3×libz.a de un cat/head; laptop sin privilegio ⇒
  SinEvidencia honesto. Piloto completo (traza de un hammer build real +
  resumen de poda) pendiente de un rebuild natural en el worker.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 23:51:17 -04:00
sergioandClaude Fable 5 a1b3b8642a cierre §3: carril Fable 5 HECHO — clases de servicio en tawasuyu 6eba521c6 (bits 8..12 + detalle musl + nombres de alambre); el cable attest-from las lleva gratis
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 23:38:39 -04:00
sergioandClaude Opus 4.8 83d40af35c harkaq: el clasificador nunca propone runtime base como declarable (fix de raíz de busybox)
El bug que declaró `busybox` en 29 recetas y rompió binutils: harkaq-suggest veía
`/bin/busybox` denegado, encontraba `recipes/busybox.toml` en el store y decía
"declarar dep: busybox" — sin mirar que la política YA lo concede (`ro /bin/busybox`:
el sandbox corre `sh -c` y /bin/sh→busybox ⇒ es CONTRATO, no dep).

Fix: harkaq-suggest ahora lee los paths CONCEDIDOS de la política (`ro`/`rw`/`list`),
no sólo los `# expect`. Si un path está concedido ⇒ categoría RUNTIME BASE: no se
declara, aunque el store lo provea.

Las 4 clasificaciones verificadas tras el cambio:
  /bin/busybox              → RUNTIME BASE (ya concedido; NO declarar)   ← el fix
  /usr/bin/make             → DECLARABLE (declarar dep: make)
  /usr/lib/libstdc++.so     → IRREDUCIBLE (nadie lo provee)
  /usr/bin/gcc en broot     → DEUDA DE COMPILADOR (compiler=gcc)
  /usr/bin/gcc en zlib      → sin deuda (sonda esperada; zlib compila con zig)

Con esto puesto, busybox JAMÁS se habría declarado. Cierra el TODO que dejó el
revert: la campaña automática ya no puede cimentar contrato como dependencia.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 23:27:57 -04:00
sergioandClaude Opus 4.8 d99ed58850 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>
2026-07-16 23:14:19 -04:00
sergioandClaude Fable 5 2e85dfc8a3 joyas #1 composefs: prototipo medido — hydrate 28ms vs mkcomposefs 507ms (métrica equivocada: lo que compra es verity por lectura + RO real + manifiesto 136KB firmable); hallazgo: objects/ por sha256-verity ⇒ mapa b3→verity al sellar
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 23:12:55 -04:00
sergioandClaude Fable 5 7f310005ea variantes-cpu T5 MEDIDO: zstd cortado (dispatch runtime, v3/v4=ruido con i7); zlib inconcluso pero la respuesta es zlib-ng; la lista caliente se concentra en mesa/códecs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 23:09:50 -04:00
sergioandClaude Fable 5 9c4ef8561c linux-metal: perfil escritorio/juego — NTSYNC, PREEMPT full+HZ_1000 explícitos, MGLRU, ZRAM, EROFS+FS_VERITY (sustrato composefs), split_lock_detect=off; sched-ext DIFERIDO (exige BTF que la receta apaga a propósito)
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>
2026-07-16 22:26:46 -04:00
sergioandClaude Opus 4.8 ec7ceb0915 harkaq: Q1-copy.fail RESPONDIDA — fs-verity mata el vector page-cache
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>
2026-07-16 22:17:01 -04:00
sergioandClaude Fable 5 272125b93a joyas reusables: composefs, PGO/BOLT con perfil sellado, mimalloc, MGLRU, uutils, corpus Clear Linux, reglas ananicy — cada una con su pieza receptora
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:16:02 -04:00
sergioandClaude Fable 5 4aa436ceb8 libarchive 3.8.1: receta mínima (bsdtar estático, sólo zlib) + tanda para el worker — plan-freebsd T3.1, sha256 verificado
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:16:02 -04:00
sergioandClaude Fable 5 6ef9f2b4a8 cierre §3: lección casper aterrizada — clases de servicio declaradas + mapa clase→permiso musl (plan-freebsd T2.1-T2.2 HECHAS)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:16:02 -04:00
sergioandClaude Fable 5 6e1ebfd001 plan jaula-juegos: kernel (NTSYNC/sched-ext/cmdline), nativos (gamescope/scx/mesa-RADV), jaula glibc por fases (flatpak → SLR sellado) con política harkaq
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:10:35 -04:00
sergioandClaude Fable 5 ed99fcf1ee plan variantes-cpu: x86-64-v3 sobre el CAS — selección en hydrate (musl sin hwcaps), lista caliente estilo Solus, piloto zlib/zstd
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:10:35 -04:00
sergioandClaude Opus 4.8 4374d2b591 cierres §4: CVE por grafo — frontera mínima de rebuild (dirty_cone + topo_order)
`scripts/affected.py <pkg> [--agenda] [--sellados]`. Un CVE no obliga a
reconstruir el catálogo: obliga a reconstruir el CONO de lo que depende del
paquete, y nada más. El grafo declarado ya lo sabe.

  CVE en zlib  → 65 de 761 recetas (8%) — el resto NO se toca
  CVE en expat → 20 de 761 (2%), las 20 selladas = el trabajo real
                 agenda: fontconfig → fcft → cairo → pango → dbus → wayland…

Es el `dirty_cone` de `dataflow` (crate no_std de tawasuyu) + `topo_order` como
agenda (una dep antes que su consumidor), calculados sobre las deps declaradas.
`--sellados` separa lo que hay que reconstruir de verdad (tiene artefacto) de lo
que no existe aún.

CAE SOLO DEL INVARIANTE: las deps están declaradas por hash ⇒ el cono es
computable y EXACTO. Una distro sin clausura declarada tiene que adivinar o
reconstruir todo por las dudas. Ésa es la tesis del SDD 17.

Honestidad grabada en el propio output: la frontera es exacta respecto de lo
DECLARADO. Lo que una receta usa sin declarar queda FUERA del cono — y ese es el
agujero que harkaq cierra (SDD 16). La campaña de esta semana declaró ~84 deps
que el kernel midió y nadie había escrito: sin eso, este cono habría sido
optimista. **El cono es tan bueno como la clausura**, y por eso los dos frentes
se necesitan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:09:59 -04:00
sergioandClaude Fable 5 8ff8c1b820 plan freebsd: traza positiva (filemon/META MODE) + taxonomía casper para cierre §3 + libarchive al catálogo
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:03:24 -04:00
sergioandClaude Opus 4.8 be52e735ab cierres §3: política de runtime derivada por medición (sin tocar la cripto)
El #3 decía "la clausura medida por harkaq en build = permisos del binario
instalado". MEDIDO: es falso en dos ejes, y por eso NO se implementó así.

1. SUJETO: la clausura de BUILD (zlib.h, make, gcc) no es la de RUNTIME. Un build
   lee headers; el binario resultante no. Dos clausuras, dos sujetos.
2. GRANULARIDAD/CRIPTO: lo que la ConcesionCapacidad firma NO es card-core::
   Permissions (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 wawa-kernel (Ring 0). Meterle paths rompería TODAS las
   firmas y contradice el "capacidad = frontera física, no tabla" que el propio
   plan cita como referencia.

⇒ Camino elegido: la concesión firmada QUEDA INTACTA (frontera gruesa, Ring 0) y
la clausura granular se deriva por MEDICIÓN como política Landlock en userspace,
donde Vec<String> sí cabe. Coexisten: el kernel verifica la frontera, Landlock
aplica el detalle.

runtime-policy.sh: corre el binario bajo la jaula con política mínima DERIVADA
(harkaq-base-closure, no a mano) y resta el BASELINE del lanzador (el sh deniega
locale/ld.so.cache; sin restarlo, la política del binario se lleva esa basura).

Demo real — htop (musl-estático): baseline 3 paths del sh; htop --version no tocó
NADA propio ⇒ su política de runtime es sólo `ro <su binario>`. Medido, no supuesto.
htop tiene 0 NEEDED: para un estático la política NO sale de las libs, sólo de
correrlo — lo que confirma que la técnica de harkaq es la única vía para el #3.

+ FIX del lector (lo cazó el chequeo anti-pérdida `nº ACCESS == denials`): descartaba
los ACCESS previos al canario porque hasta verlo no sabe su domain= — pero el sh
deniega ANTES del probe y esas son suyas. El kernel contaba 4 y el lector recibía 1.
Ahora se bufferizan con su domain y se rescatan retroactivamente al ver el canario.
Sin ese chequeo habría emitido una política con 1 de 4 accesos, perfectamente creíble.
(Primer intento de fix —drenar el socket al ver el deallocated— era plausible y NO
era la causa: el contador siguió en 4 vs 1.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:02:05 -04:00
sergioandClaude Opus 4.8 e9b6283722 cierres §2: why-differs — explica POR QUÉ dos artefactos no reproducen
El #2 de SDD 17, y encadena con el #1: cuando  da DIVERGENCIA, esto
dice qué difiere y por qué. Hoy debuggear una no-reproducción es artesanal; esto
la vuelve mecánica y legible por máquina (lo que el bucle agéntico necesita).

Algoritmo (cruce con  de tawasuyu): árbol = grafo blob+árbol hasheado ⇒
dos subárboles idénticos colapsan al mismo hash ⇒ descender SÓLO donde difiere.
O(diferencia), no O(tamaño).

Clasifica la causa, que es lo que decide la acción: solo-en-A/B (no-determinismo
de estructura) · tamaño · build-id · timestamp · path-embebido · codegen ·
contenido.

Probado: control (A vs A) → 'árboles IDÉNTICOS' ✓. Caso real (bzip2 gcc vs zig):
de 21 ficheros sólo difieren los 4 binarios → causa .

DOS VECES tuve que arreglar el diagnóstico por confundir SÍNTOMA con causa:
  1. Chequeaba build-id PRIMERO ⇒ reportaba 'build-id' cuando la causa era el
     codegen. El build-id es un HASH DEL CONTENIDO: difiere siempre que difiera
     el código.
  2. El umbral era '<1% del binario' — sonaba bien y clasificaba 1196 bytes como
     build-id. Un build-id son 20 bytes (sha1). Atado al TAMAÑO REAL (<=64).
Un diagnóstico plausible no es un diagnóstico correcto.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 20:33:51 -04:00
sergioandClaude Opus 4.8 8b1eea8911 cierres §1: consenso de reconstrucción — funcionando (2/2 builders, mismo hash)
El top-1 de SDD 17 (mayor ventaja competitiva por esfuerzo). N builders
INDEPENDIENTES reproducen el mismo hash ⇒ el binario es confiable SIN FIRMA.
Convierte la repro de QA en primitiva de distribución: cualquiera puede ser
mirror, nadie puede envenenar el repo.

  scripts/consenso.sh recipes/bzip2.toml 2
    builder 1: hub local (Artix)     → b3:86a33b76…
    builder 2: worker efímero (Ubuntu) → b3:86a33b76…
     CONSENSO (2/2, bit a bit)

Dos máquinas físicas, dos distros, mismo hash byte a byte. Nix/Debian no pueden
ofrecerlo (repro incompleta). Cae SOLO del invariante que hammer ya paga — que es
la tesis del SDD 17: buscar qué cae del invariante, no qué frontera agregar.

Lo originó una observación accidental: al hacer el rollout de cmake noté que el
laptop y el worker daban el MISMO hash sin que nadie lo buscara. Eso ya era
consenso ocurriendo; esto sólo lo formaliza.

Divergencia ⇒ exit 1 y apunta a why-differs (§2): una divergencia YA es
información (un canal impuro encontrado). NO firma ni publica: sólo el veredicto.
El log de transparencia (fork-proof: hash-encadenado + detección de equivocation)
ya está escrito en tawasuyu — no hay que construir un rekor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 20:26:03 -04:00
sergioandClaude Opus 4.8 2d8514555c matar-gcc: riesgo GUI VERIFICADO — el ABI de las libs migradas es idéntico
Debí evaluar esto ANTES de migrar, no después: las 29 tienen 36 consumidores,
incl. toda la cadena GUI (cairo/gtk4/pango/harfbuzz/fontconfig/libadwaita) +
mesa/mirada. 6 migradas son deps de ese stack, que por regla no se rebuildea en
el laptop.

No se pudo construir la GUI completa en ninguna máquina (laptop: python3 no
construye — gotcha conocido, verificado que es PREEXISTENTE revirtiendo mis deps;
worker golden: busybox no construye — store parcial). Así que se verificó lo que
decide el link: el ABI.

  freetype 90 · expat 12 · libpng/libpng16 385 · libffi 68 símbolos globales
  → IDÉNTICOS entre gcc y zig ⇒ la GUI linkea igual.

Dos falsos positivos cazados al medir: . comparaba libpng.a contra
libpng16.a (libs distintas), y  cuenta símbolos INTERNOS de los
.o que difieren entre compiladores sin tocar el ABI (294 'diferencias' espurias).
Lo correcto: mismo fichero + --extern-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 20:03:35 -04:00
sergioandClaude Fable 5 2b7c7015eb kernels: LANDLOCK+AUDIT+IO_URING+BPF_SYSCALL explícitos en linux-metal/linux-generic (contrato kikin)
PLAN-KIKIN §4.bis + HANDOFF-KIKIN-DESDE-HAMMER: el sustrato que kikin asume
(J4 = io_uring, J4b = Landlock/seccomp del anfitrión, eBPF = observabilidad)
tiene que venir COMPILADO en los kernels que hammer distribuye — «al azar del
defconfig» no es un contrato.

- linux-generic 7.1.2: re-sellado en el worker (5c5ef06c) y VALIDADO en QEMU:
  config =y los cuatro, landlock_create_ruleset/io_uring_setup/bpf_prog_load
  en kallsyms, y el re-test de input de mirada pasa (5 dispositivos, salida de
  emergencia procesada). Imagen mirada-usb re-empaquetada con este kernel.
- linux-metal: mismos flags; se re-sella en el próximo build de imagen metal.
- linux.toml (soberano): NO tocado — su of_tree es load-bearing del
  selfhost-verify; deuda anotada en la receta para el próximo re-ancle.
- SECURITYFS queda fuera (introspección opcional; harkaq usa el probe
  landlock_create_ruleset(VERSION), que no lo necesita).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 18:45:48 -04:00
sergioandClaude Fable 5 e8e25fb88e boot: activate --from-select idempotente — el hook de apagado de arje-zero lo invoca incondicional
Contrato PLAN-KIKIN §9 (respondido en HANDOFF-KIKIN-DESDE-HAMMER.md): mirada
escribe /run/hammer/boot-select y dispara el reboot SIN salir; /run es tmpfs,
así que la selección se aplica en el apagado o nunca. arje-zero corre esto en
toda secuencia de apagado:
- sin fichero o vacío → no-op limpio (exit 0)
- con selección → activa (rollback E4) y CONSUME el canal; si falla, el fichero
  queda para diagnóstico
- --select parametrizable (testeable); 3 tests nuevos (d/e/f)
- 'boot menu' documentado como HARNESS de dev/VM: en producción mirada no sale

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 17:12:35 -04:00
sergioandClaude Opus 4.8 6c864dcee3 matar-gcc: balance final — 29 migradas, 4 matraca dura diagnosticada
Cerré el frente C-puras. Las 4 que no migran son matraca DURA con gcc
justificado (no inercia):
  file      → el binario zig SEGFAULTEA generando magic.mgc (persiste con -O0
              ⇒ codegen, no optimización)
  linux-pam → 'cannot run C compiled programs' (binario zig no corre)
  libgcrypt/libsodium → no construyen (asm criptográfico)

De 47 compiler=gcc: 29 migradas + 4 matraca dura (gueto gcc legítimo) + 11 Rust
diferidas + 3 no medidas. compiler=gcc: 47 → 18.

harkaq hizo el ciclo completo: reveló las 47 (invisibles bajo 'gcc esperada'),
midió cuáles migran, y el residuo quedó JUSTIFICADO con diagnóstico, no supuesto.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 15:40:48 -04:00
sergio 49fd38d53b arje-link: resync del espejo con arje-bus (Subscribe 13→14 + Parked/Refloored
arje inserto StopCardFromDisk en el medio de BusRequest el 2026-06-26 y
corrio Subscribe a indice 14 — el puente estaba suscribiendose con el byte
viejo desde entonces (roto en silencio; lo delato el golden test de arje-bus
el 2026-07-16, lado tawasuyu 41f4accc7). Ademas el espejo de BusEvent no
conocia EnteParked/EnteRefloored: se agregan como consumo-sin-senal
(to_lifecycle -> Option). Tests unit+e2e actualizados y verdes.
2026-07-16 15:39:58 -04:00
sergioandClaude Opus 4.8 87634f3196 matar-gcc: libevdev + mtdev migradas a zig-cc (generan la lib con zig)
Las 2 'sin confirmar' del balance: el smoke-test no las verificaba por ser libs
sin binario, pero generan la lib con zig (libevdev.so, libmtdev.a). Migradas.

mtdev queda COMPLETAMENTE de-Alpinizado: config.sub soberano (patch de esta
sesión) + zig compiler ⇒ cero dependencia de Alpine. Era la única deuda de
soberanía del barrido harkaq y ahora está cerrada por entero.

Total matar-gcc: 29 recetas C migradas. Quedan 18 compiler=gcc (4 matraca-C
dura + 11 Rust + 3 no medidas).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 15:33:50 -04:00
sergioandClaude Opus 4.8 c6ff858f23 harkaq: cpp/getent en las sondas del provisioning (coherente con base.policy)
Faltaba persistir en harkaq-farm-setup.sh las 2 sondas que añadí a base.policy
al revisar needs-review (cpp=frontend gcc, getent=NSS musl). Sin esto, un worker
nuevo derivaría una base.policy sin ellas y volvería a marcar irreducibles
falsos (dhcpcd/strace).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 15:22:39 -04:00
sergioandClaude Opus 4.8 bf840915f7 matar-gcc: curl+libevent migradas + BALANCE final (27 recetas C a zig)
curl (dep de muchos) y libevent verificadas en laptop: construyen+corren con zig.
Total sesión: 27 recetas C migradas gcc→zig-cc.

BALANCE de las 47 que harkaq nombró:
  27 MIGRADAS  (deuda histórica: zig 0.13/0.16 segfaultaba, zig mejoró)
   4 matraca real: libgcrypt/libsodium (crypto asm), file (magic), linux-pam
   2 sin confirmar: libevdev, mtdev (libs, smoke-test no verifica)
  11 Rust diferidas (gcc para el C embebido de sys-crates, otra evaluación)

matar-gcc pasó de '47 invisibles' (harkaq las reveló al leer el compiler=) a
27 cerradas + cola nombrada. Reporte: tandas/needs-review-harkaq/migracion-zig.md

OJO: re-hashea las 27 del índice firmado 748 ⇒ re-firma en próximo packaging.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 13:42:06 -04:00
sergioandClaude Opus 4.8 322d528888 matar-gcc: 14 recetas C más migradas gcc→zig-cc (verificadas en laptop, store completo)
Segunda tanda. Candidatas que el VPS marcó migrable; re-verificadas en el LAPTOP
(store completo, fiable) build+corre — 14/14, cero matraca:

  freetype jq libassuan libgpg-error libssh2 libuv libxml2 nano pcre2 pigz socat
  tig tmux vim

pcre2 tuvo una discrepancia transitoria (falló en una prueba local temprana con
"linker version script", migró en el VPS); re-verificado limpio en el laptop:
construye Y corre. Era estado transitorio, no incompatibilidad.

Confirma el patrón: el VPS acierta en las MIGRABLES (build+corre son evidencia
real); sólo erraba en las matraca (build-falla espurio por store parcial). La
medición fiable es el laptop.

Total matar-gcc esta sesión: 25 recetas C migradas (11+14). El frente pasa de 47
compiler=gcc a ~22 (las 25 migradas + las que faltan medir + las 11 Rust). OJO:
re-hashea, índice firmado 748 necesita re-firma en el próximo packaging.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 13:30:05 -04:00
sergioandClaude Opus 4.8 c671ae840d matar-gcc: 11 recetas C migradas gcc→zig-cc (medido: construyen y corren)
Primera tanda del rollout aprobado. harkaq nombró 47 recetas compiler=gcc;
migra-zig.sh midió que las C-puras migran a zig (~85%). Estas 11 se verificaron
en el LAPTOP (store completo, fiable): construyen con zig-cc Y —las que tienen
binario— corren limpio.

  bzip2 expat json-c gzip htop less libpng libyaml zstd libffi xz

El compiler=gcc era deuda histórica: se marcaron con zig 0.13/0.16 (que
segfaultaban C clásicos), zig mejoró, el gcc quedó por inercia. Verificado
in-place: bzip2→b3:86a33b76, json-c→b3:9cbe76e3.

11 dependencias menos del gcc de Alpine. Quedan ~25 C-puras candidatas del VPS
por verificar en el laptop (el store parcial del VPS daba build-falla espurios
por deps faltantes — la medición fiable es la del laptop) + las 11 Rust
(sys-crate C, otra evaluación).

OJO: re-hashea estas 11 (estaban en el índice firmado 748); el índice necesita
re-firma en el próximo packaging.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 13:11:18 -04:00
sergioandClaude Fable 5 81a5d8d746 mirada-usb: el overlay de mesa pisaba libudev-zero con el libudev de eudev — input muerto en el tester NVIDIA
Causa raíz del viaje 2026-07-16 (pantalla viva, teclado/mouse muertos): el apk
de mesa arrastra eudev-libs y el 'cp *.so*' del overlay pisaba el libudev.so.1
de libudev-zero. Sin udevd, el libudev de eudev no expone ID_INPUT y libinput
ignora TODOS los dispositivos en silencio; la GPU no lo delata porque smithay
la encuentra por syspath. Reproducido y verificado A/B en QEMU (usb-kbd):
eudev = 0 dispositivos; libudev-zero = 5 y Ctrl+Alt+BackSpace corta el
compositor al instante.

- 5c-bis: restaurar libudev-zero tras el overlay + aserción cmp (regresión = build roto)
- MIRADA_DEBUG_DIR → run-NNNN del pendrive (eventos.log y panics ya no mueren en RAM)
- imagen re-empaquetada con el fix + gpt en la cmdline

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 13:02:17 -04:00
sergioandClaude Opus 4.8 2d1d40a6f1 matar-gcc: migra-zig.sh + veredicto medido — las C-puras SON granjeables (~85%)
¿Las 47 compiler=gcc que harkaq nombró son factibles de migrar a zig, o hay que
matracar? MEDIDO, no adivinado.

migra-zig.sh: para cada receta, build con zig-cc + SMOKE-TEST del binario —
porque el motivo del gcc era segfault en RUNTIME, no fallo de build; un artefacto
que sella pero segfaultea es peor que gcc. Idempotente, acumula por lotes (probar
47 no cabe en un timeout).

Muestra de 13 C-puras: 11 MIGRAN (bzip2 expat json-c gzip htop less libpng
libyaml zstd libffi xz), 2 MATRACA (pcre2: linker version script que zig ld no
soporta; file: subdir magic). ≈85% yield.

VEREDICTO: es GRANJEADA para las ~36 C-puras. El compiler=gcc era deuda histórica
— marcadas con zig 0.13/0.16 (que segfaultaban C clásicos), zig mejoró, el gcc
quedó por inercia. ~85% migran solas; el residuo (~15%) es matraca individual por
causas concretas del build-system.

Las 11 Rust con sys-crate C son otra evaluación (gcc para el C embebido de
libgit2-sys, no el Rust) — se deja para después.

Rollout = decisión del usuario (re-hashea recetas del índice firmado 748). Correr
migra-zig.sh sobre las 47 en la granja VPS da la lista final; promover las
migrables re-firma el índice. Reporte: tandas/needs-review-harkaq/migracion-zig.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 12:31:53 -04:00
sergio 0f6c841782 mirada-usb: force_gpt en la cmdline + post-mortem del viaje NVIDIA
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.
2026-07-16 12:16:04 -04:00
sergioandClaude Opus 4.8 71ec92345f harkaq: el clasificador distingue gcc-compilador de gcc-sonda — matar-gcc son 47 recetas
El límite del modelo que mtdev destapó, cerrado. harkaq clasificaba /usr/bin/gcc
como "sonda esperada" SIEMPRE, así que marcaba `Hermetico` a las recetas que
compilan CON el gcc de Alpine (compiler=gcc = CC=gcc, musl+GNU ld). Estuvo ciego
a la deuda de compilador todo el barrido.

Fix en harkaq-suggest: 5º arg = la receta medida. Si usa compiler=gcc, los
frontends de gcc (gcc/cpp/c89/c99/g++/cc/ld/as) dejan de ser "esperada" y pasan a
DEUDA DE COMPILADOR (matar-gcc). Para compiler=zig-cc (default, 714 recetas) gcc
sigue siendo sonda de configure — esperada, como antes. Verificado: mtdev(gcc) →
deuda de compilador; zlib(zig) → sin deuda.

EL HALLAZGO: matar-gcc no es "{kernel, cmake}" como creía la memoria del proyecto.
Son 47 recetas (36 C puro + 11 Rust con sys-crate C) que dependen del gcc de
Alpine. harkaq lo reveló sólo cuando aprendió a leer el compiler= de la receta —
antes gcc-como-sonda-esperada ocultaba una deuda mayor que toda la que sí detectó.
Reporte: tandas/needs-review-harkaq/deuda-compilador-matar-gcc.md.

Cada una usa gcc porque zig-cc la miscompila (documentado en su receta). Acción
por receta: migrar a zig cuando zig mejore, o aceptar el escape como deuda
conocida. Ahora es una deuda NOMBRADA y contada, no invisible.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 09:43:06 -04:00
sergioandClaude Opus 4.8 a1ab8774c5 harkaq: mtdev — deuda de config.sub CERRADA con patch soberano (+ límite del modelo descubierto)
El único caso de deuda de soberanía del barrido: mtdev copiaba el config.sub/guess
del autoconf de ALPINE (/usr/share/autoconf/build-aux/) porque el suyo (1.1.6) no
conoce *-musl. harkaq lo cazó como lectura no declarada del rootfs.

CERRADO con recipes/mtdev-config-sub-musl.patch: 11 líneas, +`-musl*` a la
whitelist de OS del config.sub DEL PROPIO TARBALL. Ahora es input soberano
(hasheado con la receta), sin leer Alpine. Se quitó el `cp /usr/share/autoconf/...`
del configure. Verificado: mtdev construye (b3:47708e40) sin tocar /usr/share/autoconf.

Método (con un tropiezo honesto): casi afirmo que el `cp` era espurio porque el
config.sub en work/sources/mtdev daba exit 0 con musl — pero ese source estaba
MUTADO por un build previo (el cp lo había reemplazado por el de Alpine). El
tarball ORIGINAL fresco NO conoce musl (exit 1). Casi valido sobre un source
contaminado; me salvó chequear el exit code, no el output.

DESCUBIERTO AL CERRARLO: mtdev tenía DOS deudas de Alpine, no una. También usa
`compiler = "gcc"` (gcc de Alpine, no zig). Bajo la jaula la política deniega
/usr/bin/gcc (sonda esperada) y el configure da "C compiler cannot create
executables". Es parte de matar-gcc (kernel, cmake, mtdev), frente aparte.

LÍMITE DEL MODELO (nuevo, documentado en needs-review): harkaq clasifica gcc como
"sonda esperada" SIEMPRE, así que marca la fase Hermetico — pero para una receta
compiler=gcc, gcc es ESENCIAL y el build no compila sin él. harkaq no distingue
"gcc sondeado (ignorable)" de "gcc = el compilador". Caso límite real del
clasificador; no invalida el cierre de config.sub (producción no usa la jaula).

make declarado en mtdev (deuda declarable restante). config.sub fuera de
needs-review; queda anotado el gcc-compilador.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 08:04:03 -04:00
sergioandClaude Opus 4.8 35f58aa75b harkaq: granja con volumen + auto-shutdown VALIDADA end-to-end
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>
2026-07-16 07:47:36 -04:00
sergioandClaude Opus 4.8 f7916b5ee9 harkaq: granja con volumen persistente + workers auto-terminantes
La arquitectura que la 1ª campaña pidió a gritos (el worker quedó idle ~4h
cobrando). Tres piezas en harkaq-vol.sh {up|collect|close|status}:

1. VOLUMEN persistente (harkaq-cosecha): los workers escriben verdicts a
   /mnt/cosecha, que sobrevive a su destrucción ⇒ NO dependo de estar viva para
   no perder el trabajo.
2. AUTO-SHUTDOWN (harkaq-campana-vol.sh): tras IDLE_CICLOS ciclos con 0
   mediciones nuevas, el worker SE AUTO-ELIMINA. En Hetzner un server apagado
   sigue cobrando ⇒ apagar de verdad es delete. Vía API REST + curl + metadata
   service (NO hcloud CLI: la golden Ubuntu no lo trae; curl siempre está). El
   ID propio sale del metadata, no del nombre.
3. collect: monta el volumen en un helper barato efímero (o un worker vivo),
   rsync al hub, corre el harvest, destruye el helper. close: detach+delete del
   volumen (deja de cobrar, ~€0.44/mes mientras exista).

+ dos fixes de la 1ª campaña horneados en el bucle: borra el artefacto -hkm tras
medir (envenenaba la caché) y los dos gates (ABI>=7 + binario-con-jaula).

El token va al worker (para auto-delete): riesgo acotado — worker efímero, sin
servicios entrantes salvo SSH-por-clave, destruido al terminar.

Bug cazado antes de gastar: las llaves {..} dentro del mensaje de ${1:?...}
cerraban la expansión (CMD salía 'status}').

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 07:23:02 -04:00
sergioandClaude Opus 4.8 7d760f274e harkaq: declarar deps medidas por el kernel (cosecha automática)
Cosecha desatendida de la campaña harkaq. Cada dep de acá la denunció el audit de
Landlock en un build real: el kernel vio al build usarla sin declararla, y el
store del hub confirma qué artefacto la provee (deuda DECLARABLE, §4.5).

Recetas:bash binutils busybox bzip2

No se tocó ninguna receta con deuda IRREDUCIBLE: declarar algo que el store no
provee rompería el build en vez de arreglarlo. Esas van a tandas/needs-review-harkaq.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 07:12:47 -04:00
sergioandClaude Opus 4.8 fecdeab8f1 harkaq: declarar deps medidas por el kernel (cosecha automática)
Cosecha desatendida de la campaña harkaq. Cada dep de acá la denunció el audit de
Landlock en un build real: el kernel vio al build usarla sin declararla, y el
store del hub confirma qué artefacto la provee (deuda DECLARABLE, §4.5).

Recetas:dhcpcd strace

No se tocó ninguna receta con deuda IRREDUCIBLE: declarar algo que el store no
provee rompería el build en vez de arreglarlo. Esas van a tandas/needs-review-harkaq.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 07:04:58 -04:00
sergioandClaude Opus 4.8 895e8202fa harkaq: revisadas las 5 irreducibles — 2 recuperadas, 3 casos genuinos diagnosticados
Ninguna de las 5 necesitaba una receta nueva. Eran falsos irreducibles por
política incompleta + un caso real de de-Alpinización.

FALTABAN 2 SONDAS EN LA POLÍTICA: /usr/bin/cpp (frontend del preprocesador de
gcc, mismo grupo que gcc/c89/c99) y /usr/bin/getent (utilidad NSS de musl).
hammer NO las construye ⇒ se deniegan y clasifican (D3), como gcc. Sin ellas en
`# expect`, arrastraban la receta entera a irreducible. Añadidas a base.policy y
a harkaq-farm-setup.sh (para los próximos workers). Re-clasifiqué SIN re-medir
(la clasificación lee la política; los veredictos crudos no cambian).

nm/ranlib NO se añadieron como sondas: los provee binutils ⇒ son DECLARABLES.
Ponerlos como esperadas dejaría a una receta usar el ranlib de Alpine en vez de
decir "declará binutils" — lo contrario de lo que se busca.

RECUPERADAS (declaradas y fuera de needs-review):
  dhcpcd → make, pkgconf     strace → make

QUEDAN 3, cada una una historia distinta (README en needs-review):
  ncurses  fs.make_dir /usr/lib — ESCRITURA en install, no lectura de Alpine
           (DESTDIR de la receta), NO de-Alpinización.
  mtdev    config.guess/sub del autoconf de Alpine — LA ÚNICA deuda de soberanía
           genuina del barrido (parchar mtdev o escribir recipes/autoconf.toml).
  perl     /etc/hosts,/etc/resolv.conf — config de sistema para tests de red; el
           build completa igual. Runtime base o denegación benigna, no Alpine.

Resultado del barrido completo: de 83 recetas, la deuda de soberanía REAL es UN
caso (mtdev/autoconf). Todo lo demás era declarable o sondas.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 06:44:20 -04:00
sergioandClaude Opus 4.8 7206626e25 harkaq: el disparo de cosecha es loop nohup, NO cron (arje-zero es PID1)
El laptop corre arje-zero como init (no systemd, systemctl no existe) y no tiene
crond activo. El crontab que instalé anoche corrió 0 veces: validé que la LÍNEA
corría a mano, nunca que un daemon fuera a dispararla. Mismo patrón que me mordió
toda la sesión — validar la pieza, no el sistema.

Disparo real: scripts/farm/harvest-loop.sh con setsid nohup. Sobrevive el fin de
sesión, no un reboot (eso pediría un servicio /etc/init.d, con root).

+ 2 bugs del harvest arreglados: flock anti-solape (dos ciclos editando+commiteando
a la vez = árbol corrupto) y el rescate rechazaba recetas legítimas por la línea
en blanco que add-deps añade (el + vacío no matcheaba [deps].build).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 06:31:34 -04:00
sergioandClaude Opus 4.8 7ec2e86b7b harkaq: declarar deps medidas por el kernel (cosecha automática)
Cosecha desatendida de la campaña harkaq. Cada dep de acá la denunció el audit de
Landlock en un build real: el kernel vio al build usarla sin declararla, y el
store del hub confirma qué artefacto la provee (deuda DECLARABLE, §4.5).

Recetas:coreutils elfutils expat file flex gawk

No se tocó ninguna receta con deuda IRREDUCIBLE: declarar algo que el store no
provee rompería el build en vez de arreglarlo. Esas van a tandas/needs-review-harkaq.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 06:30:36 -04:00
sergioandClaude Opus 4.8 8f94b8a251 harkaq: declarar deps medidas por el kernel (cosecha automática)
Cosecha desatendida de la campaña harkaq. Cada dep de acá la denunció el audit de
Landlock en un build real: el kernel vio al build usarla sin declararla, y el
store del hub confirma qué artefacto la provee (deuda DECLARABLE, §4.5).

Recetas:sassc scdoc sed shadow socat sqlite tar tmux tree tzdata util-linux vim wget when which wpa_supplicant xorriso xz zlib

No se tocó ninguna receta con deuda IRREDUCIBLE: declarar algo que el store no
provee rompería el build en vez de arreglarlo. Esas van a tandas/needs-review-harkaq.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 06:21:14 -04:00
sergioandClaude Opus 4.8 21ac060c4b harkaq: declarar deps medidas por el kernel (cosecha automática)
Cosecha desatendida de la campaña harkaq. Cada dep de acá la denunció el audit de
Landlock en un build real: el kernel vio al build usarla sin declararla, y el
store del hub confirma qué artefacto la provee (deuda DECLARABLE, §4.5).

Recetas:gettext-tiny giflib git gnupg gperf gzip htop iproute2 jq kbd libassuan libcap libevent libffi libgcrypt libgpg-error libksba libnl libpng libsass libsodium libssh2 libudev-zero libusb libwebp libxml2 libyaml linux-generic linux-headers linux-metal linux-pam linux lz4 mandoc mtools musl nano npth openssh openssl parted pciutils pcre2 pigz procps-ng python3 readline rsync samurai ca-certificates curl doas dosfstools e2fsprogs fontconfig freetype

No se tocó ninguna receta con deuda IRREDUCIBLE: declarar algo que el store no
provee rompería el build en vez de arreglarlo. Esas van a tandas/needs-review-harkaq.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:27:57 -04:00
sergioandClaude Opus 4.8 593a11c034 harkaq: gate 2 de la campaña — ¿el binario TIENE la jaula dentro?
La golden hornea un target/release/hammer viejo y el rsync excluye /target ⇒ si
el cargo build del provisioning no corre, el worker construye alegremente SIN
JAULA y produce cero veredictos.

PASÓ: la primera corrida molió 2 recetas con un binario del 29/06 (0 ocurrencias
de 'harkaq' en strings) y las marcó 'sin veredicto' como si fuera culpa de las
recetas. Ocho horas así son la noche entera perdida, y el log habría dicho
'salteada' — nunca 'estoy ciego'. Es el falso Hermetico de D9 mudado al
orquestador: la ausencia como respuesta tranquilizadora.

Ahora aborta si strings no encuentra harkaq en el binario. Mismo criterio que el
gate del ABI: no medir es mejor que creer que se mide.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:24:58 -04:00
sergioandClaude Opus 4.8 32e8ac557d harkaq: runbook de la campaña desatendida (worker + cron, para retomar sin mí)
Estado escrito en el repo y no en mi cabeza: la campaña tiene que sobrevivir a
que yo desaparezca al final del turno. Qué corre, dónde, cómo revisarlo por la
mañana, cómo pararlo, y los rastrillos que ya se pagaron (el cd del cron, el
pull sucio, cargo fuera del PATH).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:09:32 -04:00
sergioandClaude Opus 4.8 052f4f765e harkaq: Cargo.lock — libc en hammer-build (SIGTERM para el lector)
Sin esto el `git pull --rebase` del cron de cosecha falla con 'unstaged changes'
y la cosecha nunca sincroniza con el otro agente: idle silencioso de noche, que
es justo lo que la campaña existe para no tener.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 23:07:25 -04:00
sergioandClaude Opus 4.8 f783f0107d harkaq: campaña desatendida — medir→declarar→verificar, sin regex y sin preguntas
El problema real no es el coste de la tanda: es que una pregunta a las 3am son 8
horas de idle. Estas 3 piezas están hechas para que la noche no se desperdicie.

  harkaq-campana.sh   (worker) bucle autónomo: construye cada receta bajo la
                      jaula y guarda los veredictos crudos. Idempotente, saltea
                      lo medido, duerme y re-escanea. NUNCA bloquea esperando: un
                      build que falla no detiene la cola (y su veredicto interesa
                      igual — es cuando más importa saber qué tocó fuera). Gatea
                      por ABI>=7: moler la noche para producir "no sabemos" es
                      peor que no moler.
  harvest-harkaq.sh   (hub, cron) hermano de harvest-go.sh: baja veredictos,
                      clasifica contra el store COMPLETO, aplica las deps
                      DECLARABLES y commitea con `git add` explícito. La deuda
                      IRREDUCIBLE NO se toca (declarar algo que el store no
                      provee rompe el build en vez de arreglarlo) → needs-review.
  harkaq-add-deps.py  editor de recetas conservador: idempotente, preserva las
                      deps existentes, y ANTE LA DUDA NO TOCA (valida que el
                      resultado siga parseando como TOML y no encoja). Corre de
                      noche sobre la fuente de verdad del catálogo: un fichero mal
                      editado a las 3am no da un error, da una receta corrupta que
                      nadie mira hasta el lunes.

POR QUÉ NO HAY REGEX EN EL CAMINO CRÍTICO: intenté sacar la lista de "a quién le
falta declarar make" con uno y falló dos veces en la misma tarde. `\bmake\b`
colaba `cargo-make` (el guión ES límite de palabra). La versión estrecha perdía
LAS CINCO recetas donde harkaq había medido la deuda de verdad (`compile = "make
…"`: el carácter previo es una comilla). El número bailó 69→45→99 según el
retoque. Construí una herramienta de medición y después intenté adivinar con un
regex — la lista buena la da el kernel. El regex queda sólo para ORDENAR la cola.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 22:53:57 -04:00
sergioandClaude Opus 4.8 1e0bc98ad4 matar gcc: rollout de cmake HECHO en la granja — y los consumidores no hacían falta
cmake reconstruido en un worker efímero (regla: la cadena GUI no se rebuildea en
el laptop, el zig-skew rompe cairo) y cosechado al hub:
    b3:834132e7…-cmake   NEEDED = sólo libc.musl-x86_64.so.1
El viejo (99864dcc…, con libstdc++.so.6 + libgcc_s.so.1) queda en el store por si
algo lo referencia.

LOS 10 CONSUMIDORES NO SE RECONSTRUYERON, Y NO HACE FALTA. El fix quita la
dependencia de RUNTIME del artefacto DE CMAKE. Los consumidores sólo lo usaron
como HERRAMIENTA DE BUILD — sus artefactos no linkean libstdc++. Rebuildearlos
sólo daría frescura de hash, y eso pasa solo en su próximo build. Confundir "usó
la herramienta" con "linkea la librería" habría costado un rebuild de gtk4 para
nada. (Yo mismo había propuesto los 11; el radio real es 1.)

REGALO DEL ROLLOUT: el worker (Ubuntu 24.04, ccx23) y el laptop (CachyOS)
produjeron cmake con el MISMO HASH, bit a bit — el invariante central de hammer
confirmándose entre dos máquinas distintas sin que nadie lo buscara. Y como los
bytes son idénticos, el NEEDED del worker queda verificado por transitividad: no
hizo falta readelf allá (que además no está instalado en la golden).

Limpieza: removido store/834132e7…-cmake-nogcc (mi artefacto experimental).
harkaq-suggest INDEXA el store, así que un artefacto huérfano aparecería como
"proveedor" de paths y ensuciaría los diagnósticos.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 20:53:11 -04:00