selfhost-verify: pieza 3 (linux-headers swap) — SWAP_LINUX_HEADERS=1, byte-idéntico a Alpine en host

Tercera pieza del toolchain hammer-from-source (variante b, SDD 11 §7.2b): los headers
UAPI del kernel 6.16.12 que musl/busybox #include, hoy tomados del paquete linux-headers
de Alpine.

- recipes/linux-headers.toml: `make headers` (no `headers_install` — su rsync final falta
  en el toolchain hermético) + unifdef vía HOSTCC=zig cc; .tar.gz (busybox-tar lo
  descomprime sin xz). Sella los 13 subdirs kernel-owned de usr/include.
- assemble_builder: el swap ahora soporta rel_path de DIRECTORIO (reemplaza el árbol
  entero: remove + copy), no sólo binarios. Cubierto por test nuevo
  (builder_rootfs_swaps_toolchain_header_tree_from_source, incl. borrado de huérfanos).
- recipes/linux-headers-alpine-compat.patch: el paquete de Alpine no es el `make headers`
  crudo. Aporta content-pinned 5 archivos que difieren de la salida vainilla; 3 son
  REQUERIDOS (scsi/{scsi,scsi_ioctl,sg}.h — legacy userspace, NO UAPI) porque el applet
  `eject` de busybox los incluye y sin ellos no compila. install los pisa sobre /out y
  limpia el junk (.cmd/Makefile/headers_check.pl/drm) que `cp -a` arrastra.
- scripts/selfhost-verify.sh: SWAP_LINUX_HEADERS=1 construye la receta y emite un --swap
  por subdir kernel-owned (auto-derivado del artefacto sellado).

Criterio de éxito fuerte: `diff -r` del header-tree de hammer contra el de Alpine = VACÍO
⇒ el toolchain swapeado es byte-idéntico al baseline ⇒ reproducibilidad por construcción.
Ensamblado end-to-end en host OK (13 swaps, musl bits/sys intactos). 133 tests verdes.
Pendiente: corrida in-VM para el sello ✓ REPRODUCIBLE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 19:35:01 -04:00
co-authored by Claude Opus 4.8
parent 26b10bd757
commit b05badee23
5 changed files with 693 additions and 16 deletions
+16 -2
View File
@@ -256,8 +256,22 @@ Diseño completo en [SDD 11 — Bootstrap from-scratch](11-bootstrap.md). Resume
reconstruyó los 4/4 dentro de la VM con el `/toolchain` hammerizado (make `fbad44ac…` + busybox
`56664d70…` pisando los de Alpine) y el `of_tree(stage1')` **igualó** la referencia `9adefb82…`
`✓ REPRODUCIBLE: stage1' == stage1`, `DRIVER_RC=0` (~54 min, arje-zero cu=1 in-VM). **La procedencia
del builder ya no es "todo Alpine" y el auto-alojamiento sigue bit-a-bit.** **Pendiente:** seguir
reemplazando piezas — linux-headers → bwrap → rust/llvm (cada una swapeada y re-verificada igual).
del builder ya no es "todo Alpine" y el auto-alojamiento sigue bit-a-bit.** **Pieza 3 — linux-headers
(`recipes/linux-headers.toml`, kernel 6.16.12, validada en host):** los headers UAPI que musl/busybox
`#include`. Construidos con `make headers` (NO `headers_install`: su `rsync` final falta en el toolchain
hermético) + `unifdef` vía HOSTCC=zig cc. El swap es de **directorio**, no de binario: se extendió
`assemble_builder` para reemplazar árboles enteros (los 13 subdirs kernel-owned `usr/include/{linux,asm,
asm-generic,cxl,fwctl,misc,mtd,rdma,regulator,scsi,sound,video,xen}`), dejando intactos los de musl
(bits/sys/net…). Hallazgo clave: el paquete de Alpine NO es el `make headers` crudo — trae 5 archivos
distintos a la salida vainilla; 3 de ellos (`scsi/{scsi,scsi_ioctl,sg}.h`, legacy userspace, NO UAPI)
son **requeridos** porque el applet `eject` de busybox los incluye y sin ellos no compila. Se aportan
content-pinned vía `recipes/linux-headers-alpine-compat.patch` (+ 2 cosméticos: kernel.h/if_tunnel.h) y
se pisan sobre la salida. Criterio de éxito fuerte alcanzado: **`diff -r` del header-tree hammer contra
el de Alpine = vacío** ⇒ el toolchain swapeado es byte-idéntico al baseline ⇒ todo lo que compile abajo
reproduce de por sí (garantía por construcción, más fuerte que un rebuild). Expuesto con
`SWAP_LINUX_HEADERS=1`; ensamblado end-to-end en host OK. **Pendiente:** la corrida in-VM
(`KVM=1 MEM=24576 SWAP_LINUX_HEADERS=1 ./scripts/selfhost-verify.sh`) para el sello `✓ REPRODUCIBLE`,
y seguir con bwrap → rust/llvm (cada una swapeada y re-verificada igual).
- ⏭️ **También pendiente (Stage 1):** bus único (B.2: exponer el `CRASHED` a la capa de IA) y
atestación arje (A1/A2).