arranque-grafo: paso 3 del ADR 0010 — grafo de estados + hammer boot

El menú de arranque como navegación del grafo content-addressed de estados
(no una lista de kernels). Sube el modelo de generaciones in-place a un grafo
navegable y define el contrato de datos con mirada.

- hammer_upgrade::boot_graph: BootGraph/BootNode (formato exacto del contrato),
  build() arma el DAG desde las generaciones (id = of_tree sin b3:, parents =
  of_tree del padre, Base para la raíz del linaje), nodo Recovery sintético
  colgando de la viva, emit() atómico a /run/hammer/boot-graph.json.
- activate(): resuelve el id content-addressed a una generación y deja el
  sistema en ese nodo — no-op si ya viva, rollback paso a paso a un ancestro
  (reusa el rollback E4), recovery = un rollback, error honesto ante un "redo"
  hacia una generación huérfana (pide re-aplicar el árbol).
- CLI `hammer boot graph [--out|--stdout]` y `hammer boot activate <id>
  [--from-select]` (lee el id que mirada deja en /run/hammer/boot-select).
- Tests: DAG + activate a ancestro + recovery + redo-falla; rfc3339 sin deps.
  Validado e2e por el binario (3 generaciones → grafo → activar → recovery).

Cierra el lado `proceso` de SDD 15 §H4 (arrancar = activar un nodo del DAG).
mirada ya puede maquetar contra el grafo real (HANDOFF-arranque-grafo.md).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-06 20:36:04 -04:00
co-authored by Claude Opus 4.8
parent 7e21b0184b
commit 3c343bee9a
4 changed files with 464 additions and 2 deletions
+7 -2
View File
@@ -96,8 +96,13 @@ muerto antes del takeover).
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`.
3. **Contrato de generaciones-grafo** ✅ (módulo `hammer_upgrade::boot_graph` + subcomando `hammer
boot`): el modelo in-place de generaciones se lee como un **grafo de estados** navegable (id =
`of_tree`, DAG por `parent`), `hammer boot graph` emite `/run/hammer/boot-graph.json` con el
formato del contrato, y `hammer boot activate <id>` (o `--from-select`) deja el sistema en un nodo
(no-op si ya vivo · rollback paso a paso a un ancestro · nodo `recovery` sintético · error honesto
ante un "redo" hacia una generación huérfana). Validado e2e por el CLI. **mirada ya puede maquetar
contra el grafo real.**
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