feat(arje-link): transporte arje-bus → bus de agente, cierra B.2 end-to-end

hammerd::arje_link se suscribe al bus del init (ENTE_BUS_SOCK), relee el frame
postcard de arje-bus con un mirror mínimo de suscriptor (sin arrastrar el
crate-graph de arje ⇒ hammer sigue standalone) y reenvía cada BusEvent →
crashes → Event::Crashed → agent.sock. Wire verificado byte-a-byte contra
arje-bus real (ulid string, frame Subscribe=[00,01,00,0d]); 2 tests de round-trip
local + frame. Se lanza en thread si ENTE_BUS_SOCK está definido (no-op si no).
Roadmap B.2 marcado  (resta sólo el smoke contra init vivo).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-06-14 03:30:04 +00:00
co-authored by Claude Opus 4.8
parent f6b337f6cb
commit a23630c50d
6 changed files with 584 additions and 13 deletions
+12 -11
View File
@@ -287,17 +287,18 @@ Diseño completo en [SDD 11 — Bootstrap from-scratch](11-bootstrap.md). Resume
`SWAP_BWRAP=1`. **Pendiente:** correr in-VM acumulando los swaps
(`KVM=1 MEM=24576 SWAP_MAKE=1 SWAP_BUSYBOX=1 SWAP_LINUX_HEADERS=1 SWAP_BWRAP=1 ./scripts/selfhost-verify.sh`)
para el `✓ REPRODUCIBLE`, y seguir con la última pieza: rust/llvm (la grande — ya hay infra de deps).
- 🔨 **B.2 — `CRASHED` real a la capa de IA (en progreso):** el `Event::Crashed` del bus de
agente ya no es sólo declarativo. **Fuente (lado arje, ✅):** `arje-bus` ganó
`BusRequest::Subscribe` + `BusPayload::Event(BusEvent)`; arje-zero difunde en `on_death`
`EnteCrashed{id,label,status}` / `EnteRestarting{delay_ms}` / `EnteExited` a las conexiones
suscritas, purgando las muertas (4 tests). **Sink (lado hammer, ✅):** `hammerd::crashes`
traduce la señal normalizada → `Event::Crashed` y la bombea al `EventBus`
`/run/agent.sock` (3 tests). **Falta el último tramo:** el *adaptador de transporte* —un
thread que conecte a `$ARJE_BUS_SOCK`, mande `Subscribe` y reenvíe cada `BusEvent` a
`crashes::pump` (vía `BusClient::{subscribe,next_event}`)— y la decisión de cómo los dos
repos comparten el wire (dep directa a `arje-bus` vs. proto compartido vs. relectura del
frame postcard). Es el único paso que necesita un init vivo para validarse end-to-end.
- **B.2 — `CRASHED` real a la capa de IA (cableado end-to-end):** el `Event::Crashed` del
bus de agente ya tiene fuente real. **Fuente (arje):** `arje-bus` ganó `BusRequest::Subscribe`
+ `BusPayload::Event(BusEvent)`; arje-zero difunde en `on_death` `EnteCrashed{id,label,status}`
/ `EnteRestarting{delay_ms}` / `EnteExited` a las conexiones suscritas, purgando las muertas
(4 tests). **Sink (hammer):** `hammerd::crashes` traduce la señal normalizada → `Event::Crashed`
`EventBus``/run/agent.sock` (3 tests). **Transporte (hammer):** `hammerd::arje_link` se
suscribe al bus de arje (`$ENTE_BUS_SOCK`) y reenvía cada `BusEvent`. Decisión de wire =
**relectura del frame postcard** (mirror mínimo del subconjunto de suscriptor; no arrastra el
crate-graph de arje ⇒ hammer sigue standalone). El layout está **verificado byte-a-byte contra
`arje-bus` real** (mismas versiones ulid 1.2 / postcard 1.1; frame Subscribe = `[00,01,00,0d]`)
y cubierto por un round-trip local (2 tests). Resta sólo el smoke end-to-end contra un init
vivo (no reproducible sin arje corriendo).
- ⏭️ **También pendiente (Stage 1):** atestación arje (A1/A2 — ya cableada en el repo arje,
resta sólo enchufar su veredicto de boot a este roadmap).