gioser

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1576Shell 205Rust 111Markdown 993774 Definitions

⎇ 7e21b0184b9f721c5cc5c74328cf5656ef305d69 docs/adr/0010-arranque-grafo-mirada.md Markdown · 124 lines · 6.8 KB History raw

docs: ADR 0010 — arranque por grafo (menú de boot = navegación del grafo de estados, mirada+hammer) 7e21b0184 · sergio ·

1# ADR 0010 — Arranque por grafo: el menú de boot como navegación del grafo de estados (mirada + hammer)
2
3**Estado:** aceptado (plan), sin implementar.
4**Fecha:** 2026-07-06.
5**Contexto cruzado:** hammer (arranque/kernel/generaciones) + tawasuyu/mirada (render). El
6espejo de este ADR para el lado mirada vive en `tawasuyu/HANDOFF-arranque-grafo.md`.
7
8## Contexto
9
10hammer quiere instalarse en metal real con un arranque **soberano**: nada de `systemd-boot`
11(sigue siendo systemd) y GRUB-EFI está roto en este stack (GRUB 2.14 cuelga la rama UEFI, ver
12[etapa-metal-usb]). El compositor **mirada** (tawasuyu, `02_ruway/mirada`) ya es "lo que ves al
13arrancar": compositor Wayland + greeter + launcher sobre DRM/KMS. La idea del usuario: que el
14**menú de arranque sea de mirada**, no de un bootloader ajeno — "sólo falta ponerle su menú tipo
15GRUB".
16
17Al mirarlo, el menú no es un port de GRUB. En un Linux normal el menú es una **lista** de kernels.
18En hammer, donde el sistema es un **grafo content-addressed** de estados (SDD 15: config = paquete =
19función = proceso), el menú puede ser la **navegación de ese grafo**: elegir un nodo = activar un
20estado del sistema. Eso cierra el eslabón **proceso** que SDD 15 §H4 dejó abierto (las tres primeras
21lentes ya coinciden en el hash; faltaba el lado proceso = replay de un log monótono de estados).
22
23## Decisión
24
25El menú de arranque es un **selector gráfico sobre el grafo de estados del sistema**, renderizado por
26**mirada** sobre KMS, respaldado por el modelo de generaciones/DAG de **hammer**. La frontera entre
27los dos agentes es un **contrato de datos** (hammer describe el grafo; mirada lo dibuja y pide activar
28un nodo). Invariante de UX compartido: **cero parpadeo** de DRM desde la firmware hasta el escritorio.
29
30### Quién reside sobre qué
31
32| Capa | Reside en | Notas |
33|---|---|---|
34| Cargador EFI + entrada en el disco instalado | **hammer** | install-to-disk EFI; ver "loader" abajo. |
35| Kernel con KMS sin costura (simpledrm→i915) | **hammer** | `linux-generic.toml` ya trae `SIMPLEDRM+SYSFB_SIMPLEFB+FB_EFI+I915+FBDEV_EMULATION`. |
36| El grafo de estados (nodos que el menú ofrece) + activar nodo | **hammer** | generaciones (hammer-upgrade/recover), overlay, DAG de wawa-memo. |
37| Render + navegación del menú sobre KMS | **tawasuyu/mirada** | reusa Prezi espacial / Zoom-Z (árbol fractal) / constelaciones. |
38| Sostener el DRM master sin parpadeo menú→escritorio | **mirada** (con el kernel de hammer) | un solo framebuffer, abierto una vez, nunca re-modeset. |
39
40### El contrato (la frontera limpia)
41
42**hammer → mirada** — hammer escribe el grafo en un path bien conocido (propuesta:
43`/run/hammer/boot-graph.json`, regenerable, world-readable):
44
45```json
46{
47  "version": 1,
48  "current": "<blake3-del-nodo-vivo>",
49  "default": "<blake3-a-arrancar-si-no-hay-elección>",
50  "nodes": [
51    {
52      "id": "<blake3>",
53      "label": "texto corto para el usuario",
54      "kind": "generation | snapshot | base | recovery",
55      "created": "2026-07-06T12:00:00Z",
56      "parents": ["<blake3>", "..."],
57      "bootable": true,
58      "summary": "qué cambió respecto del padre (opcional)"
59    }
60  ]
61}
62```
63
64**mirada → hammer** — mirada pide activar el nodo elegido (propuesta: escribir el id en
65`/run/hammer/boot-select` **o** invocar `hammer boot activate <id>`). hammer valida el id contra el
66grafo, activa la generación (pivota overlay/root) y sigue el arranque. Un nodo `recovery` mapea al
67`hammer-recover --rollback` que ya existe.
68
69> El grafo es content-addressed: cada `id` es un hash, `parents` forma un DAG (no una lista lineal).
70> El modelo in-place actual de hammer (`hammer-recover`: "no hay menú de generaciones tipo NixOS")
71> se **sube** a un grafo navegable — es trabajo nuevo de hammer, no un refactor cosmético.
72
73### Cero parpadeo (invariante compartido)
74
75Un solo modo de video desde la firmware hasta el compositor:
76
771. Firmware GOP framebuffer → **`SYSFB_SIMPLEFB`** toma ese mismo FB → **i915 hace *seamless
78   takeover*** sin cambio de modo. (El kernel ya tiene los tres bits `=y`.)
792. Cmdline **`quiet loglevel=0`** + sin texto de fbcon ni cursor (`vt.global_cursor_default=0`), sin
80   getty en el VT gráfico durante el arranque. **Ajuste pendiente:** hoy `FRAMEBUFFER_CONSOLE=y`
81   puede pintar texto encima; afinar cmdline/config del kernel.
823. **mirada abre el DRM master directo** y lo sostiene desde el menú hasta el escritorio — nunca
83   suelta, nunca re-modeset.
84
85### El loader (cómo se lanza el kernel sin systemd-boot ni GRUB)
86
87El cuelgue del EFI-stub directo en el metal del usuario era por el **initrd de 100MB** (medición TPM
88+ quirk de LoadOptions del firmware). `linux-generic.toml` ya trae **squashfs+overlay** ⇒ el
89initramfs se vuelve **minúsculo** (sólo monta el squashfs). Con initrd chico, **EFI-stub directo
90vuelve a ser viable y soberano** — sin GRUB ni systemd. Es decir: squashfs+overlay no es un desvío,
91es lo que *destraba* el arranque EFI soberano y de paso el cero-parpadeo (initrd chico = menos tiempo
92muerto antes del takeover).
93
94## Plan (lado hammer)
95
961. **Este ADR + el handoff a tawasuyu** con el contrato (hecho en este commit).
972. **squashfs+overlay** en el medio/instalador → initrd chico → **reprobar EFI-stub directo** en
98   OVMF, dejarlo listo para el metal. (Refinamiento #2 de [post-etapa-e].)
993. **Contrato de generaciones-grafo**: subir el modelo in-place a un **grafo de estados** navegable +
100   la operación "activar nodo", y emitir `/run/hammer/boot-graph.json`.
1014. **Afinar kernel/cmdline** para el handoff sin costura (punto cero-parpadeo).
1025. **install-to-disk EFI** (`hammer-live-install` rama EFI): GPT+ESP con el bzImage como
103   `\EFI\BOOT\BOOTX64.EFI` (EFI-stub), root/store/var en particiones; validar el disco instalado en
104   OVMF hasta que mirada tome el control.
105
106## Consecuencias
107
108- La frontera es un **fichero + un comando**, no una API compartida ⇒ los dos agentes avanzan sin
109  bloquearse. hammer puede emitir el grafo y probar EFI-stub sin esperar a mirada; mirada puede
110  maquetar el menú contra un `boot-graph.json` de ejemplo sin esperar a hammer.
111- El menú-grafo es la primera **manifestación del lado proceso** de SDD 15 §H4 — arrancar = activar
112  un nodo del DAG. No colapsa todo el modelo, pero lo hace visible.
113- No mueve la frontera de confianza (ADR 0007/0009): activar un nodo es reproducir/hidratar un árbol
114  sellado del store, no ejecutar algo nuevo.
115
116## Referencias
117
118- SDD 15 §H3/§H4 (`docs/15-frontier-ai-native.md`) — config = paquete = función = proceso; el lado
119  proceso = replay del MonotonicLog.
120- ADR 0007 (arje-zero como init propio), ADR 0009 (código content-addressed).
121- Memoria de proyecto: etapa-metal-usb (GRUB 2.14 roto, EFI-stub colgó por initrd 100MB, metal
122  booteado vía systemd-boot como crutch descartable), post-etapa-e-refinamientos (squashfs+overlay,
123  rollback-al-boot).
124- `tawasuyu/HANDOFF-arranque-grafo.md` — el espejo, lado mirada.

0010-arranque-grafo-mirada.md

ADR 0010 — Arranque por grafo: el menú de boot como navegación del grafo de estados (mirada + hammer)

Estado: aceptado (plan), sin implementar. Fecha: 2026-07-06. Contexto cruzado: hammer (arranque/kernel/generaciones) + tawasuyu/mirada (render). El espejo de este ADR para el lado mirada vive en tawasuyu/HANDOFF-arranque-grafo.md.

Contexto

hammer quiere instalarse en metal real con un arranque soberano: nada de systemd-boot (sigue siendo systemd) y GRUB-EFI está roto en este stack (GRUB 2.14 cuelga la rama UEFI, ver [etapa-metal-usb]). El compositor mirada (tawasuyu, 02_ruway/mirada) ya es "lo que ves al arrancar": compositor Wayland + greeter + launcher sobre DRM/KMS. La idea del usuario: que el menú de arranque sea de mirada, no de un bootloader ajeno — "sólo falta ponerle su menú tipo GRUB".

Al mirarlo, el menú no es un port de GRUB. En un Linux normal el menú es una lista de kernels. En hammer, donde el sistema es un grafo content-addressed de estados (SDD 15: config = paquete = función = proceso), el menú puede ser la navegación de ese grafo: elegir un nodo = activar un estado del sistema. Eso cierra el eslabón proceso que SDD 15 §H4 dejó abierto (las tres primeras lentes ya coinciden en el hash; faltaba el lado proceso = replay de un log monótono de estados).

Decisión

El menú de arranque es un selector gráfico sobre el grafo de estados del sistema, renderizado por mirada sobre KMS, respaldado por el modelo de generaciones/DAG de hammer. La frontera entre los dos agentes es un contrato de datos (hammer describe el grafo; mirada lo dibuja y pide activar un nodo). Invariante de UX compartido: cero parpadeo de DRM desde la firmware hasta el escritorio.

Quién reside sobre qué

CapaReside enNotas
Cargador EFI + entrada en el disco instaladohammerinstall-to-disk EFI; ver "loader" abajo.
Kernel con KMS sin costura (simpledrm→i915)hammerlinux-generic.toml ya trae SIMPLEDRM+SYSFB_SIMPLEFB+FB_EFI+I915+FBDEV_EMULATION.
El grafo de estados (nodos que el menú ofrece) + activar nodohammergeneraciones (hammer-upgrade/recover), overlay, DAG de wawa-memo.
Render + navegación del menú sobre KMStawasuyu/miradareusa Prezi espacial / Zoom-Z (árbol fractal) / constelaciones.
Sostener el DRM master sin parpadeo menú→escritoriomirada (con el kernel de hammer)un solo framebuffer, abierto una vez, nunca re-modeset.

El contrato (la frontera limpia)

hammer → mirada — hammer escribe el grafo en un path bien conocido (propuesta: /run/hammer/boot-graph.json, regenerable, world-readable):

{
  "version": 1,
  "current": "<blake3-del-nodo-vivo>",
  "default": "<blake3-a-arrancar-si-no-hay-elección>",
  "nodes": [
    {
      "id": "<blake3>",
      "label": "texto corto para el usuario",
      "kind": "generation | snapshot | base | recovery",
      "created": "2026-07-06T12:00:00Z",
      "parents": ["<blake3>", "..."],
      "bootable": true,
      "summary": "qué cambió respecto del padre (opcional)"
    }
  ]
}

mirada → hammer — mirada pide activar el nodo elegido (propuesta: escribir el id en /run/hammer/boot-select o invocar hammer boot activate <id>). hammer valida el id contra el grafo, activa la generación (pivota overlay/root) y sigue el arranque. Un nodo recovery mapea al hammer-recover --rollback que ya existe.

El grafo es content-addressed: cada id es un hash, parents forma un DAG (no una lista lineal). El modelo in-place actual de hammer (hammer-recover: "no hay menú de generaciones tipo NixOS") se sube a un grafo navegable — es trabajo nuevo de hammer, no un refactor cosmético.

Cero parpadeo (invariante compartido)

Un solo modo de video desde la firmware hasta el compositor:

  1. Firmware GOP framebuffer → SYSFB_SIMPLEFB toma ese mismo FB → i915 hace seamless takeover sin cambio de modo. (El kernel ya tiene los tres bits =y.)
  2. Cmdline quiet loglevel=0 + sin texto de fbcon ni cursor (vt.global_cursor_default=0), sin getty en el VT gráfico durante el arranque. Ajuste pendiente: hoy FRAMEBUFFER_CONSOLE=y puede pintar texto encima; afinar cmdline/config del kernel.
  3. mirada abre el DRM master directo y lo sostiene desde el menú hasta el escritorio — nunca suelta, nunca re-modeset.

El loader (cómo se lanza el kernel sin systemd-boot ni GRUB)

El cuelgue del EFI-stub directo en el metal del usuario era por el initrd de 100MB (medición TPM

Plan (lado hammer)

  1. Este ADR + el handoff a tawasuyu con el contrato (hecho en este commit).
  2. squashfs+overlay en el medio/instalador → initrd chico → reprobar EFI-stub directo en OVMF, dejarlo listo para el metal. (Refinamiento #2 de [post-etapa-e].)
  3. Contrato de generaciones-grafo: subir el modelo in-place a un grafo de estados navegable + la operación "activar nodo", y emitir /run/hammer/boot-graph.json.
  4. Afinar kernel/cmdline para el handoff sin costura (punto cero-parpadeo).
  5. install-to-disk EFI (hammer-live-install rama EFI): GPT+ESP con el bzImage como \EFI\BOOT\BOOTX64.EFI (EFI-stub), root/store/var en particiones; validar el disco instalado en OVMF hasta que mirada tome el control.

Consecuencias

Referencias