Commit Graph
5 Commits
Author SHA1 Message Date
Sergio 8730aad34e takana etapa 3b: las 49 invocaciones pasan a ./target/release/takana
Los llamadores EJECUTABLES: scripts/ (incluida toda la granja), los runbooks y
CLAUDE.md. Seguro porque la 3a ya garantiza que el worker emite los dos
binarios, y porque en farm-lab-sync.sh el cargo build remoto precede a la
invocación remota en el mismo script.

Verificado: sintaxis de los 49 (bash -n / py_compile — ojo que
why-differs-barrido.sh es Python con extensión .sh) y `takana hash` devuelve
hash real sobre el store.

NO se toca en esta etapa, a propósito:
- La variable de entorno HAMMER=. Es interfaz de los scripts entre sí y hay
  llamadores que la fijan; renombrarla va con la etapa 4.
- docs/evidencia/ y los HANDOFF: son REGISTRO de lo que se corrió ese día.
  Reescribir un comando dentro de una evidencia la falsifica.
- docs/state/: es generado, se regenera solo.
- Los ADR y los docs de diseño: texto, y `hammer` sigue funcionando. Van con
  la etapa 5, que es la de churn de texto.
2026-09-09 18:25:58 +00:00
SergioandClaude Opus 5 5155f90ab9 static-audit: miraba UN binario y capaba a 40 — dos pases en falso probados
Arreglando las tres hojas salio que el guardian tenia dos agujeros, y los dos
devuelven un pase en falso, que es la peor direccion posible para un gate.

1. `break` en el PRIMER ELF ejecutable. e2fsprogs: el primero que encontraba era
   `bin/lsattr` (estatico) ⇒ receta HONESTA, mientras `e2fsck` y los tres
   `fsck.ext*` eran dinamicos. 4 de 31, invisibles.

2. `find | head -40`. bash trae 42 ejecutables y CUARENTA son los modulos
   cargables `usr/lib/bash/*`, que son ELF *shared object* y no matchean
   `ELF.*executable`. El cap cortaba la lista ANTES de llegar a `bin/bash` ⇒ el
   audit concluia «sin ELF» y eso en el resumen se lee como que no hay nada que
   objetar. El shell del perfil base, dinamico, sin que nadie lo viera.

Con dwarves el `break` habia acertado de casualidad —el primero tambien era
dinamico— y por eso reportaba 1 donde habia 10.

Ahora recorre TODOS los ejecutables, sin cap, cuenta cuantos mienten sobre
cuantos hay, y nombra un ejemplo: «gtk4 dice static, 8 de 8 ejecutables
DINAMICOS (p.ej. usr/bin/gtk4-rendernode-tool)».

Barrido completo con el metodo estricto: 684 estaticos de verdad, MIENTEN 3
(gtk4, bash, e2fsprogs), 59 sin artefacto. Con el metodo viejo, sobre el mismo
store, salia 685/1/60. La diferencia son los dos que se escapaban.

Es «no comprobar no es aprobar» aplicado al propio guardian — el mismo fallo que
`hammer kernel contract` ya habia tenido que corregir en SDD 25 §4.ter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACUcwo9mZsE5ocYVE9npih
2026-08-31 15:04:26 +00:00
sergioandClaude Opus 4.8 1e823d377b hammer hash: dry-run que faltaba — cierra el sobre-reporte del static-audit de raíz
El agujero que dejé señalado 3 veces esta sesión: nada podía saber el sellado VIGENTE de una receta
sin construirla, así que static-audit.sh auditaba el más reciente por mtime (ls -dt) y acusaba a
recetas ya sanas (dbus/libnl) por un sellado anterior a sus flags.

FIX = subcomando `hammer hash <receta> [--check]`. Calcula el ArtifactHash puro sobre las recetas
(source_id + compiler/target/link + patches + flags + fases + hashes de deps recursivos) SIN bajar
fuentes ni compilar. artifact_hash() ya era pub; el CLI sólo lo expone. Cero cambios en la lógica
de hashing ⇒ NINGÚN sellado se mueve.

Verificado: `hash` da EXACTAMENTE el mismo hash que `build` (samurai, byte a byte); `--check` sobre
receta editada → NO-SELLADO en 2ms, exit 1, sin construir nada.

static-audit.sh ahora selecciona el artefacto VIGENTE por hash, no el más reciente por mtime. Con
fallback a ls -dt si hammer no está compilado. Efecto en el store completo: las ~65 recetas cuyo
sellado no es el vigente pasan de 'auditadas' (falsa cobertura) a 'sin artefacto' (deuda de rebuild
REAL, ahora visible): estáticas de verdad 615 | MIENTEN 0 | sin artefacto 123. Corre en 15s, sin
build. El '58 sin medir' de antes estaba enmascarando ~65 recetas más.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 11:08:29 -04:00
sergioandClaude Opus 4.8 372baed4f6 static-audit: el '28 mienten' estaba INFLADO por mi propio bug (ls|head -1)
El audit tomaba 'ls -d store/*-<n> | head -1' = orden ALFABÉTICO POR HASH, no el
artefacto vigente. El store guarda TODOS los sellados de una receta (expat tenía
5, de junio a hoy), así que auditaba uno de hace tres semanas. Mismo bug de
clase que comparar libpng.a con libpng16.a por find|head -1.

Con 'ls -dt' (más reciente): 28 → 11. Tres de las supuestas mentirosas
(cargo-audit, git-absorb, yazi) nunca lo fueron: su artefacto reciente ya era
estático y el audit leía el viejo.

Lo que NO cambia: el hallazgo central es real y verificado a mano. libtool
ignora el -static del lab, el curl sellado NO arrancaba en el host, y de las 14
que arreglé cada una se verificó contra sus artefactos previos (expat: los 4
viejos con NEEDED=1, el nuevo con 0). Estaban rotas de verdad.

HONESTIDAD escrita en el script: 'más reciente' ≠ 'vigente'. Lo vigente sería el
artefacto cuyo hash corresponde a la receta de HOY, y hammer no lo expone sin
construir (no hay hammer hash / dry-run). Por eso el audit va DESPUÉS del
rebuild, nunca antes.

Quedan 11: file, helix, libcap, libgcrypt, pcre2, pkgconf, samurai, tuc,
util-linux, xz + naabu (nuevo: Go con libc.so.6 de GLIBC, otro caso).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 05:01:40 -04:00
sergioandClaude Opus 4.8 c707c1e13f static-audit: link="static" era mentira en 28 recetas selladas (libtool lo ignora)
Destapado migrando procps-ng. libtool lee el -static del lab como "preferí mis
.a", NO como flag al linker: el binario sale dinámico y la receta jura que es
estático. Con gcc pasaba igual — no es regresión de zig, es un agujero que
nadie había medido.

Tres consecuencias medidas, no teóricas:

1. NO CORREN. El curl sellado en el host: "Error relocating /lib/libz.so.1:
   __snprintf_chk: symbol not found". Su NEEDED libc.so es el soname de la musl
   de zig; en el host /lib/libc.so son 255B de linker script. El artefacto sólo
   funciona dentro del sandbox.
2. ARRASTRAN GCC. helix, yazi, git-absorb, cargo-audit y tuc traen libgcc_s.so.1
   de Alpine DENTRO del binario. Deuda de matar-gcc que ningún compiler="gcc"
   declara: invisible para el frente entero hasta ahora.
3. Un NEEDED es una entrada no declarada — lo que harkaq mide en build, pero en
   RUNTIME. Rompe el cono de affected.py (SDD 17 §4): un CVE en zlib no
   alcanzaría a un curl que se declara estático.

Script, no gate duro: fallar hoy rompe 28 selladas de golpe, varias del sistema
base (curl, util-linux, sudo). Primero se arreglan con evidencia, después se
cierra la puerta. Exit 1 mientras haya mentirosos ⇒ sirve de gate en CI cuando
la lista llegue a cero.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 00:12:59 -04:00