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:
@@ -0,0 +1,74 @@
|
||||
package infra
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestClassifyFleetTermination(t *testing.T) {
|
||||
const stall = 600
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
status string
|
||||
phase string
|
||||
dodC string
|
||||
dodS string
|
||||
idle int
|
||||
thresh int
|
||||
want string
|
||||
}{
|
||||
// --- RECLAMA (precedencia 1) ---
|
||||
{"waiting reclama input", "waiting", "haciendo", "criterio", "pending", 10, stall, TerminationReclama},
|
||||
{"phase preguntando reclama", "busy", "preguntando", "criterio", "pending", 10, stall, TerminationReclama},
|
||||
{"phase bloqueado reclama", "idle", "bloqueado", "criterio", "pending", 9999, stall, TerminationReclama},
|
||||
{"waiting manda aunque sin dodContract", "waiting", "haciendo", "", "", 10, stall, TerminationReclama},
|
||||
{"preguntando manda aunque sin dodContract", "idle", "preguntando", "", "", 10, stall, TerminationReclama},
|
||||
{"bloqueado manda aunque idle estancado", "idle", "bloqueado", "criterio", "pending", 10000, stall, TerminationReclama},
|
||||
|
||||
// --- MAL_LANZADO (precedencia 2) ---
|
||||
{"sin dodContract busy", "busy", "haciendo", "", "pending", 10, stall, TerminationMalLanzado},
|
||||
{"sin dodContract idle reciente", "idle", "haciendo", "", "", 5, stall, TerminationMalLanzado},
|
||||
{"sin dodContract idle estancado", "idle", "haciendo", "", "pending", 10000, stall, TerminationMalLanzado},
|
||||
{"sin dodContract phase hecho", "idle", "hecho", "", "met", 10, stall, TerminationMalLanzado},
|
||||
{"sin dodContract dodStatus met", "idle", "testeando", "", "met", 10, stall, TerminationMalLanzado},
|
||||
|
||||
// --- DICE_TERMINADO (precedencia 3) ---
|
||||
{"idle phase hecho", "idle", "hecho", "criterio", "pending", 10, stall, TerminationDiceTerminado},
|
||||
{"idle dodStatus met", "idle", "testeando", "criterio", "met", 10, stall, TerminationDiceTerminado},
|
||||
{"idle hecho y met", "idle", "hecho", "criterio", "met", 10, stall, TerminationDiceTerminado},
|
||||
{"idle met aunque estancado por tiempo", "idle", "puliendo", "criterio", "met", 10000, stall, TerminationDiceTerminado},
|
||||
{"idle hecho aunque estancado por tiempo", "idle", "hecho", "criterio", "pending", 10000, stall, TerminationDiceTerminado},
|
||||
|
||||
// --- ESTANCADO (precedencia 4) ---
|
||||
{"idle no hecho en umbral exacto", "idle", "haciendo", "criterio", "pending", stall, stall, TerminationEstancado},
|
||||
{"idle no hecho por encima del umbral", "idle", "investigando", "criterio", "pending", stall + 1, stall, TerminationEstancado},
|
||||
{"idle iterando estancado", "idle", "iterando", "criterio", "failed", 5000, stall, TerminationEstancado},
|
||||
{"idle dodStatus failed estancado", "idle", "testeando", "criterio", "failed", 700, stall, TerminationEstancado},
|
||||
{"idle en_pausa estancado", "idle", "en_pausa", "criterio", "pending", 601, stall, TerminationEstancado},
|
||||
|
||||
// --- TRABAJANDO (precedencia 5, todo lo demas) ---
|
||||
{"busy trabajando", "busy", "haciendo", "criterio", "pending", 0, stall, TerminationTrabajando},
|
||||
{"busy aunque idleSeconds alto", "busy", "investigando", "criterio", "pending", 99999, stall, TerminationTrabajando},
|
||||
{"idle reciente bajo umbral", "idle", "haciendo", "criterio", "pending", stall - 1, stall, TerminationTrabajando},
|
||||
{"idle reciente cero segundos", "idle", "planificando", "criterio", "pending", 0, stall, TerminationTrabajando},
|
||||
{"idle no hecho justo bajo umbral", "idle", "testeando", "criterio", "failed", 599, stall, TerminationTrabajando},
|
||||
{"busy phase vacia con dodContract", "busy", "", "criterio", "", 10, stall, TerminationTrabajando},
|
||||
|
||||
// --- Bordes y combinaciones ---
|
||||
{"umbral cero idle no hecho => estancado", "idle", "haciendo", "criterio", "pending", 0, 0, TerminationEstancado},
|
||||
{"idle hecho con umbral cero => dice terminado", "idle", "hecho", "criterio", "pending", 0, 0, TerminationDiceTerminado},
|
||||
{"dodStatus met con status busy NO termina", "busy", "haciendo", "criterio", "met", 10, stall, TerminationTrabajando},
|
||||
{"phase hecho con status busy NO termina", "busy", "hecho", "criterio", "pending", 10, stall, TerminationTrabajando},
|
||||
{"idle pendiente_revision bajo umbral trabajando", "idle", "pendiente_revision", "criterio", "pending", 100, stall, TerminationTrabajando},
|
||||
{"idle pendiente_revision sobre umbral estancado", "idle", "pendiente_revision", "criterio", "pending", 1000, stall, TerminationEstancado},
|
||||
{"waiting con dodStatus met sigue reclamando", "waiting", "hecho", "criterio", "met", 10, stall, TerminationReclama},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
got := ClassifyFleetTermination(c.status, c.phase, c.dodC, c.dodS, c.idle, c.thresh)
|
||||
if got != c.want {
|
||||
t.Errorf("ClassifyFleetTermination(%q,%q,%q,%q,%d,%d) = %q, want %q",
|
||||
c.status, c.phase, c.dodC, c.dodS, c.idle, c.thresh, got, c.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user