Fase 5 — bus de agente (/run/agent.sock) + FIFO de control humano

- proto: tipos Command/Event con serde tag "t", Hello/Welcome handshake, RecipeInline
  reducida para COMPILE, Cap enum (Query/Compile/Inject/InjectReal/Init) y
  required_for() para gating por comando.
- bus: serve_agent_bus listens en UnixListener, autenticación SO_PEERCRED por
  conexión via nix::sys::socket::PeerCredentials, una conexión = reader thread +
  writer thread + bus-forwarder thread + worker spawn por COMPILE. Dispatch a
  hammer-build (Compile), find_by_hash+run_hydrate (Inject), stat (Query/file),
  store.find_by_hash (Query/artifact) y send_to_fifo (Init).
- events: EventBus in-process (Arc<Mutex<Vec<Sender>>>), suscripción por conexión
  y purga perezosa de subs muertos en publish.
- control: ensure_fifo (mkfifo idempotente, rechaza non-FIFO), run_reader (relog
  por línea, reabre al EOF), send_to_fifo (bloqueante si no hay reader).
- watcher: nuevo start_with_events que clona el EventBus; cada MutationEvent
  registrado se re-emite como Event::Modified a las conexiones abiertas.
- hammerd::main: orquesta FIFO + watcher + bus en threads; --no-watcher para
  dev sin CAP_SYS_ADMIN.
- hammer-cli: hammer ctl <line> [--fifo PATH] escribe al FIFO con error claro si
  no existe; reemplaza el stub "[fase 5 pendiente]".
- Tests:
  * 14 unit tests nuevos en hammerd (proto/bus/events/control).
  * 5 e2e en crates/hammerd/tests/bus_e2e.rs: handshake con peer creds, gating
    no_cap, Query/file, Modified fan-out vía bus, Init -> FIFO end-to-end.
- Docs: docs/10-roadmap.md actualizado con lo cerrado y lo pendiente (policy
  declarativa, CRASHED real con supervisor, log_tail en BuildFailed).
This commit is contained in:
Sergio
2026-06-09 15:29:42 +00:00
parent 09d50f9e60
commit f41022d81f
11 changed files with 1426 additions and 32 deletions
+22 -4
View File
@@ -76,10 +76,28 @@ pre-requisito de validación.
`config_edit` + `file_drop`. `source_patch` reusa el camino de Fase 0/1 (gated en
`HAMMER_NETWORK_TESTS`).
### Fase 5 — Bus de agente
- [ ] `/run/init.control` (FIFO humano) + `/run/agent.sock` (JSON-líneas, `SO_PEERCRED`).
- [ ] Comandos `COMPILE`/`INJECT`/`QUERY`/`INIT`; eventos `BUILD_*`/`CRASHED`/`MODIFIED`.
- **Hecho cuando:** un cliente externo dispara un build y recibe el evento de fin por el socket.
### Fase 5 — Bus de agente ▶ *en progreso*
- [x] `/run/init.control` (FIFO humano): `mkfifo`, reader que loguea cada línea, y
`hammer ctl <line>` que escribe al FIFO con error claro si no existe.
- [x] `/run/agent.sock` (JSON-líneas) con handshake `Hello/Welcome`, auth via
`SO_PEERCRED` y `CapsPolicy` por UID.
- [x] Comandos `Compile`/`Inject`/`Query`/`Init`; eventos
`Welcome`/`BuildReady`/`BuildFailed`/`Injected`/`QueryResult`/`InitAck`/
`Modified`/`Crashed`/`Error`.
- [x] EventBus in-process: el watcher publica `Modified` y todas las conexiones lo reciben.
- [x] Subsistemas independientes en `hammerd::main` (FIFO/watcher/bus en threads); si uno
falla en init, los demás siguen.
- [ ] Política expresiva: hoy es código (`default_policy`), pendiente leerla de
`/etc/hammer/agent-caps.toml`.
- [ ] `CRASHED` real (requiere supervisión de servicios, que llega con el init propio del
track posterior).
- [ ] `BuildFailed.log_tail` con cola real del lab (hoy es `None`; el `reason` viene del
`Error` de Rust pero no se conserva el log textual del sandbox).
- **Hecho cuando:** un cliente externo dispara un build y recibe el evento de fin por el
socket. ✅ Camino implementado (`Compile``BuildReady`/`BuildFailed`) y la maquinaria
alrededor cubierta por `crates/hammerd/tests/bus_e2e.rs`: handshake con peer creds,
gating `no_cap`, `Query`, `Modified` fan-out, `Init`→FIFO. Un `Compile` real reusa el
camino de Fase 0/1 (gated en `HAMMER_NETWORK_TESTS`).
### Fase 6 — Integración de la IA
- [ ] Cliente de agente; traductor intención NL → `.swm`; bucle plan→build→try→verify→propose.