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>
305 lines
13 KiB
TOML
305 lines
13 KiB
TOML
# Catálogo del armador de kernel (SDD 22) — bundles de nivel 1 y perillas de nivel 2.
|
|
#
|
|
# UN BUNDLE NO ES UNA LISTA DE SÍMBOLOS. Es una raíz y su clausura sobre el grafo de Kconfig:
|
|
# `disable = ["WIRELESS"]` son ~400 CONFIG_* que hammer calcula, no que alguien mantiene a mano.
|
|
# Por eso se auto-cura: el driver wifi que entre en 6.17 cae dentro sin que nadie lo toque.
|
|
#
|
|
# LO QUE LA CLAUSURA NO CIERRA SOLA. `select` fuerza su destino IGNORANDO los `depends on` de éste,
|
|
# así que un símbolo de fuera del bundle puede reencender lo que el bundle apagó. Cada fuga se
|
|
# declara, una vez, de una de dos formas:
|
|
# · `close_leaks` — se apaga también al que la provoca.
|
|
# · `accept_leaks` — se deja abierta A SABIENDAS, con el motivo escrito.
|
|
# `hammer kernel bundles --check` falla si aparece una fuga que no esté en ninguna de las dos: eso
|
|
# es el catálogo envejeciendo, y es la mitad barata de la curación del delta entre versiones.
|
|
#
|
|
# CONTRADICTED_BY VA EN UN SOLO SENTIDO. Sirve para decirle al usuario «marcaste "no necesito wifi"
|
|
# y tenés un AX211 activo ahora mismo». NUNCA para podar el config solo: no se puede detectar el
|
|
# dock que se enchufa el mes que viene ni el fs del USB de rescate, y un kernel podado por
|
|
# autodetección es cómo se fabrica un ladrillo.
|
|
#
|
|
# Regenerar los números / revisar las fugas:
|
|
# hammer kernel bundles --kconfig <árbol> --check
|
|
# hammer kernel closure --kconfig <árbol> WIRELESS --fixpoint
|
|
|
|
version = 1
|
|
reviewed_against = "linux-6.16.12"
|
|
|
|
# =================================================================================================
|
|
# NIVEL 1 — aserciones del dueño de la máquina. No son categorías de Kconfig: son decisiones de
|
|
# vida. «No necesito wifi», «esta máquina nunca tuvo batería».
|
|
# =================================================================================================
|
|
|
|
[[bundle]]
|
|
id = "sin-wifi"
|
|
title = "No necesito wifi"
|
|
help = """
|
|
Apaga el stack 802.11 entero: cfg80211, mac80211 y todos los drivers de tarjeta. La máquina sigue
|
|
teniendo ethernet. NO apaga el interruptor de radio (RFKILL): eso es «sin-radios», porque lo
|
|
comparten bluetooth y NFC."""
|
|
disable = ["WIRELESS"]
|
|
# WLAN no DEPENDE de WIRELESS: lo SELECCIONA. Sin cerrarlo, apagar WIRELESS es un no-op — el
|
|
# olddefconfig lo reenciende y no lo dice. Fue el hallazgo que validó el diseño (SDD 22 §9).
|
|
close_leaks = ["WLAN", "IWLEGACY", "GELIC_WIRELESS"]
|
|
notes = "406 símbolos en 6.16.12; el bundle a mano de recipes/linux.toml da 421, y los 15 de diferencia son todos de sin-radios."
|
|
[bundle.contradicted_by]
|
|
pci_class = ["0280"]
|
|
|
|
[[bundle]]
|
|
id = "sin-bluetooth"
|
|
title = "No necesito bluetooth"
|
|
disable = ["BT"]
|
|
# Tarjeta combo wifi+BT: entra por select desde el lado wifi.
|
|
close_leaks = ["RSI_91X"]
|
|
[bundle.contradicted_by]
|
|
driver = ["btusb", "btintel", "btrtl"]
|
|
|
|
[[bundle]]
|
|
id = "sin-nfc"
|
|
title = "No necesito NFC"
|
|
disable = ["NFC"]
|
|
|
|
[[bundle]]
|
|
id = "sin-radios"
|
|
title = "No necesito el interruptor de radio (rfkill)"
|
|
help = """
|
|
RFKILL es el conmutador compartido de todas las radios: wifi, bluetooth y NFC lo declaran igual.
|
|
Apagarlo sólo tiene sentido si ninguna de las tres se usa — y se lleva por delante los botones de
|
|
radio de portátil (Dell, Lenovo, MSI…), que dependen de él."""
|
|
disable = ["RFKILL"]
|
|
notes = "Es un bundle propio, no parte de sin-wifi: el config a mano de linux.toml los escribía en la misma línea y por eso parecían uno solo."
|
|
|
|
[[bundle]]
|
|
id = "sin-audio"
|
|
title = "No necesito audio"
|
|
help = "Apaga ALSA y todo el stack de sonido, incluido el códec HDMI."
|
|
disable = ["SOUND"]
|
|
notes = """
|
|
No cierra: los drivers de GPU hacen `select` de los helpers de audio HDMI. Cerrarlo obligaría a
|
|
apagar la GPU, que es un precio que un escritorio no puede pagar — así que las fugas se aceptan y
|
|
quedan escritas. En recipes/linux.toml sale gratis sólo porque ahí los gráficos TAMBIÉN están
|
|
apagados."""
|
|
[bundle.accept_leaks]
|
|
SND_HDA_COMPONENT = "lo selecciona DRM_AMD_DC / DRM_NOUVEAU / DRM_RADEON: cerrarlo = quedarse sin GPU"
|
|
SND_HDA_I915 = "lo seleccionan DRM_I915 y DRM_XE: ídem para gráficos Intel"
|
|
SND_SOC_HDMI_CODEC = "lo seleccionan diez drivers DRM (casi todos SoC ARM, inertes en x86_64)"
|
|
SND_AUDIO_GRAPH_CARD = "DRM_TEGRA, inerte en x86_64"
|
|
SND_SIMPLE_CARD = "DRM_TEGRA, inerte en x86_64"
|
|
SND_UMP = "USB_F_MIDI2, gadget USB: sólo entra si la máquina hace de dispositivo USB"
|
|
SND_UMP_LEGACY_RAWMIDI = "USB_F_MIDI2, ídem"
|
|
[bundle.contradicted_by]
|
|
pci_class = ["0403"]
|
|
driver = ["snd_hda_intel"]
|
|
|
|
[[bundle]]
|
|
id = "sin-graficos"
|
|
title = "No necesito salida gráfica"
|
|
help = """
|
|
Kernel de servidor o de consola serie: sin DRM, sin framebuffer, sin retroiluminación. Si esta
|
|
máquina tiene pantalla, este bundle la deja negra — es la aserción más peligrosa del catálogo."""
|
|
disable = ["DRM", "FB", "AGP", "BACKLIGHT_CLASS_DEVICE"]
|
|
# Framebuffers de PowerMac y de SoC ARM: no existen en x86_64, cerrarlos no cuesta nada.
|
|
close_leaks = [
|
|
"FB_CONTROL", "FB_IMSTT", "FB_MAC", "FB_PLATINUM", "FB_VALKYRIE",
|
|
"FB_VT8500", "FB_WM8505", "PMAC_BACKLIGHT",
|
|
]
|
|
[bundle.accept_leaks]
|
|
DRM_AUX_BRIDGE = "lo seleccionan los muxes USB-C (TYPEC_MUX_*): apagarlos rompería el USB-C de un portátil real"
|
|
DRM_AUX_HPD_BRIDGE = "ídem, TYPEC_QCOM_PMIC / UCSI_HUAWEI_GAOKUN"
|
|
BACKLIGHT_CLASS_DEVICE = "lo seleccionan drivers de plataforma (ACPI_CMPC, SAMSUNG_Q10, USB_APPLEDISPLAY)"
|
|
DRM_DW_HDMI_I2S_AUDIO = "SND_SOC_RK3288_HDMI_ANALOG, SoC Rockchip: inerte en x86_64"
|
|
[bundle.contradicted_by]
|
|
pci_class = ["0300", "0380"]
|
|
|
|
[[bundle]]
|
|
id = "solo-ext4"
|
|
title = "Sólo uso ext4"
|
|
help = "Apaga los demás sistemas de ficheros locales. Ojo con el USB de rescate: lo que no está no se monta."
|
|
disable = ["XFS_FS", "BTRFS_FS", "F2FS_FS", "JFS_FS", "GFS2_FS", "NTFS3_FS"]
|
|
close_leaks = ["NTFS_FS"]
|
|
notes = "REISERFS_FS NO va acá: upstream lo retiró y 6.16.12 ya no lo tiene. recipes/linux.toml todavía lo apaga, y ese `-d` es un no-op silencioso."
|
|
|
|
[[bundle]]
|
|
id = "sin-usb"
|
|
title = "No necesito USB"
|
|
help = "Kernel de VM con consola serie o de servidor sin puertos accesibles. En metal deja la máquina sin teclado."
|
|
disable = ["USB_SUPPORT"]
|
|
[bundle.contradicted_by]
|
|
driver = ["usbhid", "usb_storage", "xhci_hcd"]
|
|
|
|
[[bundle]]
|
|
id = "sin-entrada-humana"
|
|
title = "No necesito teclado ni ratón"
|
|
help = """
|
|
La aserción de un kernel de QEMU con consola serie: nadie va a tocar esta máquina. Es exactamente
|
|
lo que hace recipes/linux.toml, y por eso el gate de no-regresión tiene que ser POR OBJETIVO — un
|
|
gate global rechazaría esa receta, que está sana."""
|
|
disable = ["HID_SUPPORT", "INPUT_MOUSE", "INPUT_JOYSTICK", "INPUT_TABLET", "INPUT_TOUCHSCREEN"]
|
|
[bundle.contradicted_by]
|
|
driver = ["usbhid", "hid_generic", "i8042"]
|
|
|
|
[[bundle]]
|
|
id = "sin-camaras-tv"
|
|
title = "No necesito cámara ni sintonizador"
|
|
disable = ["MEDIA_SUPPORT"]
|
|
close_leaks = ["USB_F_UVC"]
|
|
[bundle.accept_leaks]
|
|
VIDEOBUF2_VMALLOC = "lo seleccionan pantallas táctiles (RMI4_F54, TOUCHSCREEN_ATMEL_MXT_T37) para sus modos de diagnóstico: decir «no quiero cámara» no debe matar el táctil"
|
|
[bundle.contradicted_by]
|
|
driver = ["uvcvideo"]
|
|
|
|
[[bundle]]
|
|
id = "sin-infiniband"
|
|
title = "No necesito InfiniBand / RDMA"
|
|
disable = ["INFINIBAND"]
|
|
|
|
[[bundle]]
|
|
id = "sin-bus-industrial"
|
|
title = "No necesito buses industriales (CAN)"
|
|
disable = ["CAN"]
|
|
|
|
[[bundle]]
|
|
id = "sin-thunderbolt-firewire"
|
|
title = "No necesito Thunderbolt ni FireWire"
|
|
help = "El símbolo se llama USB4 desde que upstream fundió Thunderbolt y USB4 en un solo driver."
|
|
disable = ["USB4", "FIREWIRE"]
|
|
notes = "Las CUATRO recetas de kernel apagan `THUNDERBOLT`, que 6.16.12 ya no tiene: ese `-d` es un no-op y el driver sigue entrando por el defconfig."
|
|
[bundle.contradicted_by]
|
|
driver = ["thunderbolt"]
|
|
|
|
[[bundle]]
|
|
id = "sin-lector-de-tarjetas"
|
|
title = "No necesito lector de tarjetas SD/MMC"
|
|
disable = ["MMC", "MEMSTICK"]
|
|
[bundle.contradicted_by]
|
|
driver = ["sdhci_pci", "rtsx_pci_sdmmc"]
|
|
|
|
[[bundle]]
|
|
id = "sin-virtualizacion"
|
|
title = "No voy a virtualizar en esta máquina"
|
|
help = "Apaga KVM. No afecta a correr DENTRO de una VM — sólo a hospedar una."
|
|
disable = ["VIRTUALIZATION"]
|
|
[bundle.contradicted_by]
|
|
cpu_flag = ["vmx", "svm"]
|
|
|
|
# =================================================================================================
|
|
# NIVEL 2 — política y rendimiento. El campo `side` NO es decorativo: la mitad de N2 no es Kconfig
|
|
# sino variables de receta. Las dos mitades mueven el ArtifactHash igual, pero se aplican en fases
|
|
# distintas y fallan distinto; una UI que no lo sepa prometerá diffs que no puede explicar.
|
|
# =================================================================================================
|
|
|
|
[[knob]]
|
|
id = "jaula-y-eio-moderna"
|
|
title = "Jaula (Landlock + audit) y E/S moderna (io_uring, BPF)"
|
|
help = """
|
|
El contrato de PLAN-KIKIN §4.bis. Sin SECURITY_LANDLOCK+AUDIT, harkaq (SDD 16) certifica TODO como
|
|
hermético en silencio: sin auditoría no se emite un solo registro de denegación, y la evidencia
|
|
negativa se vuelve vacía."""
|
|
side = "kconfig"
|
|
enable = ["SECURITY_LANDLOCK", "AUDIT", "IO_URING", "BPF_SYSCALL"]
|
|
notes = "linux-metal y linux-generic ya los declaran; linux (el de QEMU) deja IO_URING y BPF_SYSCALL al defconfig."
|
|
|
|
[[knob]]
|
|
id = "sin-info-de-depuracion"
|
|
title = "Kernel sin información de depuración"
|
|
help = "Baja mucho el tamaño de la imagen. DEBUG_INFO_BTF además exige pahole, que el toolchain de hammer no trae."
|
|
side = "kconfig"
|
|
disable = ["DEBUG_INFO", "DEBUG_INFO_BTF"]
|
|
|
|
[[knob]]
|
|
id = "unwinder-frame-pointer"
|
|
title = "Desenrollado por frame pointer en vez de ORC"
|
|
help = """
|
|
Reduce el trabajo de objtool, pero NO lo elimina: en x86_64 las mitigaciones (retpoline,
|
|
RETHUNK) seleccionan CONFIG_OBJTOOL igual, y objtool necesita libelf."""
|
|
side = "kconfig"
|
|
enable = ["UNWINDER_FRAME_POINTER"]
|
|
disable = ["UNWINDER_ORC"]
|
|
|
|
[[knob]]
|
|
id = "preempcion-escritorio"
|
|
title = "Preempción de escritorio (menos latencia, algo menos de rendimiento bruto)"
|
|
side = "kconfig"
|
|
enable = ["PREEMPT"]
|
|
|
|
[[knob]]
|
|
id = "tick-1000"
|
|
title = "Reloj del sistema a 1000 Hz"
|
|
side = "kconfig"
|
|
enable = ["HZ_1000"]
|
|
disable = ["HZ_250"]
|
|
|
|
[[knob]]
|
|
id = "compilador-lto"
|
|
title = "LTO (optimización al enlazar)"
|
|
help = """
|
|
EL EJEMPLO DE PERILLA MIXTA. Su mitad Kconfig (LTO_CLANG_FULL) sólo se vuelve seleccionable si el
|
|
kernel se compila con clang, que es una decisión de RECETA. Hoy recipes/linux.toml compila con gcc
|
|
por decisión formal (la capa de traducción de flags de `zig cc` choca con el kbuild de x86_64), así
|
|
que esta perilla está declarada y NO es aplicable todavía."""
|
|
side = "recipe"
|
|
recipe_field = "build.compiler + build.phases.compile (make LLVM=1)"
|
|
notes = "Ver la cabecera de recipes/linux.toml: el kernel se queda en el gueto gcc hasta que se exponga el clang que zig empaqueta."
|
|
|
|
[[knob]]
|
|
id = "march-nativo"
|
|
title = "Compilar para esta CPU exacta"
|
|
help = "Mata la reproducibilidad ENTRE máquinas distintas, no la de una misma máquina: el artefacto sigue siendo bit a bit el mismo para la misma huella."
|
|
side = "recipe"
|
|
recipe_field = "build.flags"
|
|
|
|
[[knob]]
|
|
id = "debug-aparte"
|
|
title = "Separar los símbolos de depuración del artefacto"
|
|
side = "recipe"
|
|
recipe_field = "build.strip_debug"
|
|
notes = "SDD 23. Entra en hash_inputs sólo si está fijado, así que se puede activar receta a receta."
|
|
|
|
# =================================================================================================
|
|
# OBJETIVOS — para qué es este kernel. EL GATE DE NO-REGRESIÓN NO CORRE SIN UNO.
|
|
#
|
|
# La regla del gate 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 objetivo declara qué pérdidas son legítimas para este uso; todo lo demás
|
|
# bloquea. El portón se queda — sólo que en el sitio correcto.
|
|
# =================================================================================================
|
|
|
|
[[objective]]
|
|
id = "qemu-serial"
|
|
title = "VM con consola serie"
|
|
help = """
|
|
Nadie va a tocar esta máquina: entra por ttyS0 y sale por ttyS0. Es exactamente lo que hace
|
|
recipes/linux.toml, y es una receta sana."""
|
|
allow_bundles = [
|
|
"sin-wifi", "sin-bluetooth", "sin-nfc", "sin-radios",
|
|
"sin-audio", "sin-graficos", "sin-usb", "sin-entrada-humana",
|
|
"sin-camaras-tv", "sin-infiniband", "sin-bus-industrial",
|
|
"sin-thunderbolt-firewire", "sin-lector-de-tarjetas", "solo-ext4",
|
|
]
|
|
|
|
[[objective]]
|
|
id = "servidor"
|
|
title = "Servidor sin pantalla"
|
|
help = """
|
|
Sin monitor ni sonido, pero CON teclado y USB: alguien va a enchufar un rescate el día que la red
|
|
falle. Ésa es justo la clase de pérdida que el gate existe para no dejar pasar en silencio."""
|
|
allow_bundles = [
|
|
"sin-audio", "sin-graficos", "sin-camaras-tv",
|
|
"sin-bluetooth", "sin-nfc", "sin-lector-de-tarjetas",
|
|
"sin-thunderbolt-firewire", "sin-bus-industrial",
|
|
]
|
|
|
|
[[objective]]
|
|
id = "metal-escritorio"
|
|
title = "Escritorio en metal"
|
|
help = """
|
|
El objetivo más estricto del catálogo, y a propósito: en un escritorio casi nada de lo que hoy
|
|
funciona puede desaparecer sin que el dueño se entere. Sólo se autoriza lo que un escritorio
|
|
demostrablemente no usa."""
|
|
allow_bundles = ["sin-infiniband", "sin-bus-industrial"]
|
|
|
|
[[objective]]
|
|
id = "portatil"
|
|
title = "Portátil"
|
|
help = "Como el escritorio pero además con radios y lector de tarjetas: en un portátil eso se usa."
|
|
allow_bundles = ["sin-infiniband", "sin-bus-industrial", "sin-nfc"]
|