feat(infra): modelo de datos del meta-orquestador de flota (flow 0012)

Fase 1, piezas 1+2:
- ClaudeFleet + list_claude_fleet ganan DodContract/DodStatus/Role,
  leidos de goals/<sessionId>.json (.dod_contract/.dod_status/.role).
  Aditivo: fleetview sigue compilando.
- classify_fleet_termination (pura): clasifica el estado de terminacion
  de un agente (RECLAMA/MAL_LANZADO/DICE_TERMINADO/ESTANCADO/TRABAJANDO)
  con precedencia fija, para que un watcher sin LLM decida. 34 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
agent
2026-06-20 19:51:11 +02:00
parent b569561115
commit 28a53ee357
7 changed files with 315 additions and 40 deletions
+18 -15
View File
@@ -10,19 +10,22 @@ package infra
// from a single ~/.claude/sessions/<PID>.json entry plus its optional
// ~/.claude/goals/<sessionId>.json sidecar and the process' own /proc entry.
type ClaudeFleet struct {
PID int `json:"pid"`
KittyPID int `json:"kitty_pid"` // KITTY_PID from the process environ; 0 if not applicable (e.g. remote tmux)
SessionID string `json:"session_id"` // Claude Code sessionId (UUID)
Rename string `json:"rename"` // display name: short goal if present, else basename(cwd)
Target string `json:"target"` // sessionId[:8] + "@" + basename(cwd)
Goal string `json:"goal"` // from goals/<sessionId>.json .goal ("" if absent)
Phase string `json:"phase"` // from goals/<sessionId>.json .phase ("" if absent)
Emojis string `json:"emojis"` // 3 emojis representing the task (from goals .emojis; "" if absent)
Name string `json:"name"` // manual rename of the terminal (from goals .rename; "" if none)
Status string `json:"status"` // idle|busy|waiting (from sessions/<pid>.json)
Cwd string `json:"cwd"` // working directory of the session
TmuxWindow string `json:"tmux_window"` // "" for now (populated in a later phase)
Alive bool `json:"alive"` // process alive AND procStart matches (guards against PID recycling)
UpdatedAt int64 `json:"updated_at"` // from sessions/<pid>.json .updatedAt (epoch millis)
CtxPct int `json:"ctx_pct"` // context window used %, from runtime/<sessionId>.json; -1 if unknown
PID int `json:"pid"`
KittyPID int `json:"kitty_pid"` // KITTY_PID from the process environ; 0 if not applicable (e.g. remote tmux)
SessionID string `json:"session_id"` // Claude Code sessionId (UUID)
Rename string `json:"rename"` // display name: short goal if present, else basename(cwd)
Target string `json:"target"` // sessionId[:8] + "@" + basename(cwd)
Goal string `json:"goal"` // from goals/<sessionId>.json .goal ("" if absent)
Phase string `json:"phase"` // from goals/<sessionId>.json .phase ("" if absent)
DodContract string `json:"dod_contract"` // from goals .dod_contract: fixed acceptance criterion ("" if absent)
DodStatus string `json:"dod_status"` // from goals .dod_status: pending|met|failed ("" if absent)
Role string `json:"role"` // from goals .role: orchestrator|executor ("" if absent; defaults to executor in consumers)
Emojis string `json:"emojis"` // 3 emojis representing the task (from goals .emojis; "" if absent)
Name string `json:"name"` // manual rename of the terminal (from goals .rename; "" if none)
Status string `json:"status"` // idle|busy|waiting (from sessions/<pid>.json)
Cwd string `json:"cwd"` // working directory of the session
TmuxWindow string `json:"tmux_window"` // "" for now (populated in a later phase)
Alive bool `json:"alive"` // process alive AND procStart matches (guards against PID recycling)
UpdatedAt int64 `json:"updated_at"` // from sessions/<pid>.json .updatedAt (epoch millis)
CtxPct int `json:"ctx_pct"` // context window used %, from runtime/<sessionId>.json; -1 if unknown
}