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.
`diff-back` contesta «¿el .config honra el PLAN?»; el contrato contesta la otra
mitad, «¿el kernel trae lo que el userland usa por nombre?». Son distintas: un
kernel puede honrar su plan al pie de la letra y no tener MEMCG, que nunca
estuvo en ningún plan porque nadie lo pidió.
Queda dicho también que hoy sale ROJO a propósito (2 de 11) y por qué.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ACUcwo9mZsE5ocYVE9npih
Primera vez que el armador se usa para lo que existe, con artefacto real al final:
b3:8ffd57109a2f7102c1bbbbc91cf0e729047312eee1a4e3fdb8b178680cc94264-linux-gioser
linux-metal derivada gioser
bzImage 14,5 MB 11,1 MB (-23%)
símbolos encendidos 1805 1647
diff-back contra el artefacto ... 35 cumplidos, 0 INCUMPLIDOS
gate contra el artefacto ........ ningún dispositivo en uso sin driver
La base la eligió el probe, no la intuición: linux (el de QEMU) apaga USB, HID e INPUT a
propósito y gioser tiene xhci_hcd, usbhid e i8042 bindeados ⇒ linux-metal. 13 bundles y 3
perillas, 34 banderas, clausura de 3054.
Segunda validación de la clausura contra el olddefconfig real, ahora sobre otra base y con
13 bundles: 154 aciertos, SOBRA 0, faltan 18 (todos de la clase «apagado ahora ≠
inalcanzable» del §12).
LA PRUEBA DE 30 s PREDIJO EL BUILD DE 45 MIN. El .config del artefacto y el de la prueba en
seco difieren en 14 líneas y NI UNA es funcional: son las siete versiones del toolchain que
el kernel graba en su propio config (CC_VERSION_TEXT, GCC_VERSION, AS_VERSION, LD_VERSION,
RUSTC_VERSION, RUSTC_LLVM_VERSION, PAHOLE_VERSION). Cero símbolos de diferencia ⇒ la prueba
barata es un sustituto fiel para todo lo que el armador decide.
Y de regalo, la mecánica exacta de por qué el lab TIENE que estar en hash_inputs: el kernel
graba la versión de su compilador DENTRO del .config, y el .config va dentro del artefacto.
No es que el lab «influya» en el resultado — es que el lab está literalmente en el
contenido sellado. Se ve línea a línea: gcc 15.2.0 del lab anclado vs 16.1.1 del host.
PAHOLE_VERSION=0 confirma además lo que dice la cabecera de linux.toml.
La receta derivada NO se deja en recipes/: build-state.py y yupana barren recipes/ y
recipes/incoming-*, así que dejarla ahí la mete en el grafo compartido como deuda. Va en
docs/state/kernel-plans/ con el comando que la regenera; para construir se copia a
recipes/incoming-kernel/ temporalmente y se saca después.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Hasta acá el armador era análisis puro: la clausura decía qué debía morir y nadie lo había
contrastado con el resolvedor real. NO hace falta construir un kernel para hacerlo: lo caro
es la fase compile (35-60 min); toda la cadena del armador vive en configure y corre en
segundos.
Método: árbol 6.16.12 entero, `make defconfig` de base (el config de linux.toml NO sirve de
base: ya apaga wifi/audio/fs a mano, así que el lado disable no apagaría nada y la
predicción no se pondría a prueba — fue mi primer error), el fragmento del plan, y
olddefconfig. Verdad de campo = los símbolos que pasaron de encendidos a apagados.
sólo depends on ....... clausura 1775 aciertos 64/68 SOBRA 0 falta 4
+ huérfanos select .... clausura 1794 aciertos 65/68 SOBRA 0 falta 3
+ comparaciones ....... clausura 1795 aciertos 65/68 SOBRA 0 falta 3
SOBRA 0 en las tres: el predictor nunca dice que muere algo que sobrevive, que es la única
dirección en la que puede equivocarse sin fabricar un ladrillo.
Dos refinamientos que salieron de la medición, cada uno con su test:
· HUÉRFANOS DE SELECT. Un símbolo sin prompt no se marca a mano: sólo entra por select.
Si caen todos sus selectores, cae él, aunque nadie dependa de él (caso ACPI_NHLT). Se
exige >=1 selector: sin ninguno entra por un default, y darlo por muerto mataría media
tabla.
· `X = y` SÍ ES DEPENDENCIA DURA. Medio drivers/video/fbdev declara su dependencia de FB
como `depends on (FB = y) && ARM`. Tratar toda comparación como opaca dejaba esos
drivers fuera. `X = n` sigue fuera a propósito: con X en n es VERDADERA. De regalo, las
fugas select sin declarar de sin-graficos cayeron de 8+ a 1.
Los 3 que faltan NO son un fallo, son otra pregunta: CRYPTO_LIB_ARC4, REGMAP y
SYSTEM_DATA_VERIFICATION tienen selectores FUERA de la clausura (PPP_MPPE, 111 usuarios más
de REGMAP…). Se quedaron sin usuarios en ESE config; encendés PPP y ARC4 vuelve.
«Inalcanzable» y «apagado ahora» no son lo mismo, y la clausura contesta la primera.
Y un bug que sólo aparece corriendo el resolvedor: el diff-back contaba como promesa
incumplida todo símbolo pedido ausente del .config. Pero Kconfig NO EMITE un símbolo cuyas
dependencias no se cumplen ⇒ un `-d WLAN` cuya raíz ya cayó simplemente no sale. Con esa
cuenta un plan perfecto se reportaba roto (2 falsos incumplidos de 16). Ahora: ausente +
se pedía apagar = éxito; ausente + se pedía encender = fallo. La corrida real sale 14
cumplidos, 0 incumplidos.
GUARDIÁN NUEVO, y hacía falta: las cuatro recetas de kernel NO son el mismo kernel — linux
y linux-metal van por 6.16.12, linux-metal-dual y linux-generic por 7.1.2. Planear una
contra el árbol de la otra calcularía clausuras sobre símbolos que ahí no existen, y
saldría SIN RUIDO. KconfigTree lee ahora su versión del Makefile de arriba y `plan` FALLA
si no coincide con la de la receta (los diagnósticos sólo avisan). Aviso de la sesión de
granja/store, verificado antes de implementarlo.
Catálogo: las dos fugas que destapó la clausura más grande quedan declaradas con motivo
(FB_SYSMEM_HELPERS_DEFERRED por HID_PICOLCD_FB; DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG por
DRM_I915_DEBUG), y las notas sobre THUNDERBOLT/REISERFS_FS pasan a pasado: ya se
corrigieron en 2602218.
Runbook §4.bis: cómo probar un plan entero en 30 s en vez de 40 min.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
«no encuentro el ejecutable zig en …» no quiere decir que falte zig: falta ESA versión.
hammer lo resuelve en .dev-fs/tools/zig-x86_64-linux-<ver>/, ni el symlink tools/zig ni el
PATH cuentan.
Medido para el caso concreto del kernel: linux.toml NO pinea zig_version, pero tres de sus
deps.build sí — flex, openssl y elfutils, las tres a 0.13.0 — y la receta derivada las
hereda enteras. En gioser están 0.13.0 y 0.16.0, así que el eje está cubierto.
Aviso de la sesión de granja/store; verificado contra las recetas antes de escribirlo.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
work/.farm-build.lock, el mismo que toman farm-worker-loop.sh y campana-deuda.sh.
hammer build comparte work/sources/<dep>-<sha> entre todas las recetas: dos builds
simultáneos que compartan una dep se pisan (uno hace fetch y borra el árbol mientras el
otro lo usa) y el árbol queda roto PARA SIEMPRE — reintentar no lo arregla. Medido: al
invalidar libdrm, ~93 de 205 recetas KDE murieron por el wrapper .zwrap/cc barrido del
árbol de fuente. ADR 0012, sin decidir.
El runbook era el único sitio de este frente que mandaba a construir. El resto del armador
no toca el store: plan calcula el ArtifactHash con cómputo puro sobre las recetas, y
probe/gate/bundles/closure sólo leen.
Aviso de la sesión de granja/store, que comparte el repo.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Paso 3 del §8 del SDD 22, y cierra el orden que fijaba: reversa, clausura, gate, diff-back.
La pieza que faltaba no era el gate sino el MAPA driver → símbolo. El kernel sabe qué
driver tiene bindeado cada dispositivo, pero no de qué CONFIG_* salió: esa relación sólo
existe en los Makefiles de kbuild. modmap.rs lee 15.789 reglas obj-$(CONFIG_X) += y.o en
3182 Makefiles. Dos trampas de nombres, cada una con su test:
· el módulo cargado usa _ donde el fichero usa - (snd-hda-intel.o → snd_hda_intel)
· un módulo puede salir de VARIOS símbolos, y sobrevive si sobrevive cualquiera
Sin resolverlas el gate no encontraría nada y diría que todo está bien, que es el peor
resultado posible para un portón.
POR OBJETIVO, no global. La regla es "todo dispositivo en uso debe seguir teniendo
driver"; aplicada global rechazaría recipes/linux.toml, que apaga USB, HID e INPUT A
PROPÓSITO por ser el kernel de QEMU con consola serie. El gate NO CORRE sin --objective, y
un allow_bundles con un id mal escrito es error de CARGA del catálogo (si no, autorizaría
nada y bloquearía sin que se entienda por qué).
Medido con el mismo plan (sin-usb + sin-entrada-humana + sin-graficos + sin-wifi) y el
hardware real de gioser:
qemu-serial ........ PASA — 5 pérdidas autorizadas
metal-escritorio ... BLOQUEA — las mismas 5 como regresiones, con el bundle culpable
Ése es todo el punto del §5.
Y lo que el gate no puede comprobar, lo dice: de los 38 drivers bindeados, 15 no se
mapearon a ningún símbolo (pcieport, serial8250 — built-ins cuyo nombre de driver no
coincide con el del módulo). Quedan listados como SIN COMPROBAR, nunca como aprobados.
hammer kernel hw vuelca la huella y los drivers de la máquina DESTINO, que no tiene por
qué ser la de build — el SDD lo pedía explícitamente.
Cuatro objetivos en el catálogo (qemu-serial, servidor, metal-escritorio, portatil) y un
runbook nuevo: docs/runbooks/armador-de-kernel.md, con el ataque de punta a punta y una
lista honesta de lo que todavía NO está (sonda en VM, atestación por huella, bisección,
curación del delta con modelo, perillas side=recipe).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>