From 0e93258974c8ec4220f1d8ba45746ea10cb17d38 Mon Sep 17 00:00:00 2001 From: agent Date: Sat, 20 Jun 2026 20:02:01 +0200 Subject: [PATCH] =?UTF-8?q?docs(flows):=200012=20fase=201=20hecha=20?= =?UTF-8?q?=E2=80=94=20watcher=20dentro=20de=20fleetview=20+=20cola=20JSON?= =?UTF-8?q?L?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refleja la decisión real: el watcher no es un daemon aparte sino que se embebe en fleetview (reutiliza su polling); la cola es JSONL en ~/.claude/fleet/events.jsonl (sin SQLite/CGO). Co-Authored-By: Claude Opus 4.8 (1M context) --- dev/flows/0012-fleet-orchestrator-dod.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/dev/flows/0012-fleet-orchestrator-dod.md b/dev/flows/0012-fleet-orchestrator-dod.md index e222d02c..1307d35d 100644 --- a/dev/flows/0012-fleet-orchestrator-dod.md +++ b/dev/flows/0012-fleet-orchestrator-dod.md @@ -21,7 +21,7 @@ tags: [orchestration, fleet, dod, multi-agent, watcher] dod_evidence_schema: - id: watcher_events kind: cmd - expected: "sqlite3 apps/fleet_watcher/operations.db 'SELECT count(*) FROM fleet_events WHERE created_at > date(now,-1 day)' > 0; cada fila es una TRANSICION de estado, no un nivel repetido" + expected: "wc -l ~/.claude/fleet/events.jsonl > 0; cada linea es una TRANSICION de estado (edge), no un nivel repetido" required: true - id: dod_contract_on_spawn kind: cmd @@ -97,14 +97,16 @@ El hook GOAL-TRACKER debe respetar `dod_contract`/`dod_status` (solo reescribe ` ## Fases de construcción -### Fase 1 — fleet_watcher (cerebro barato, sin LLM) +### Fase 1 — watcher (cerebro barato, sin LLM) — DENTRO de fleetview [HECHO 2026-06-20] -Service liviano (Go o bash) que corre como step de dag_engine o systemd-user. Cada N segundos: -1. Snapshot del fleet (`fleetview list --json`, extendido con `dod_contract`/`dod_status`/`phase`). -2. Diff contra el snapshot anterior -> transiciones (edge-triggered, no nivel). -3. Clasifica cada transición según la máquina de terminación. -4. Escribe un evento por transición en `apps/fleet_watcher/operations.db` (tabla `fleet_events`). -5. Push inmediato (PushNotification) para clasificación RECLAMA. +Decisión: NO es un daemon aparte. fleetview ya es un proceso vivo que pollea la flota cada segundo y vive mientras la sesión tmux fleet (y por tanto la flota) exista. El watcher se embebe ahí (KISS). En cada refresco de la TUI: +1. Snapshot del fleet (`list_claude_fleet`, con `dod_contract`/`dod_status`/`role`). +2. Clasifica cada agente con `classify_fleet_termination` (función pura del registry). +3. Diff contra el snapshot anterior (en memoria) -> transiciones (edge-triggered, no nivel). +4. Escribe un evento por transición en la cola JSONL `~/.claude/fleet/events.jsonl` (sin SQLite/CGO — KISS). Línea: `{ts, session_id, pid, from, to, goal, phase, urgent}`. +5. Marca `urgent=true` en transición a RECLAMA. El push real al móvil lo hace el orquestador (Fase 2) leyendo la cola; el watcher solo marca. + +Estado: modelo de datos (`DodContract`/`DodStatus`/`Role` en `ClaudeFleet`) + `classify_fleet_termination` + watcher embebido (`watcher.go`) — construidos y testeados (7 tests del watcher + 34 del clasificador). Pendiente: validación en vivo (relanzar fleetview con el binario nuevo y observar la cola con agentes reales cambiando de estado). DoD Fase 1: - Golden: un agente pasa busy->idle -> aparece 1 evento `DICE-TERMINADO` o `ESTANCADO` en `fleet_events`.