Files
fn_registry/functions/infra/classify_fleet_termination.md
T
egutierrez e4a36f1133 chore(tags): anadir tag 'orchestration' a las 6 funciones del grupo que faltaban
capability_groups.md exige que toda funcion de un grupo lleve su tag plano para
ser descubrible via fn_search tag='orchestration'. 6 de las funciones del grupo
(reboot_all_claudes, classify_fleet_termination, list_claude_fleet,
drain_fleet_events, mark_claude_role, set_dod_contract) no lo llevaban. Se anade
sin borrar los tags existentes.

notify_desktop_go_infra ya llevaba el tag pero no figuraba en la tabla del grupo:
se decide que SI pertenece (la usa el orquestador/watcher para avisar de un
RECLAMA u otro evento urgente) y se anade a la tabla en orchestration.md (commit
anterior), en lugar de quitarle el tag. Resultado: 13 funciones con tag
orchestration, identicas a las 13 filas de la tabla del grupo (sin drift).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 18:03:14 +02:00

5.4 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
classify_fleet_termination function go infra 1.0.0 pure func ClassifyFleetTermination(status, phase, dodContract, dodStatus string, idleSeconds, stallThresholdSeconds int) string Clasifica MECANICAMENTE el estado de terminacion de un agente Claude de la flota para que un watcher barato sin LLM decida que hacer. Pura y determinista. Devuelve una de RECLAMA, MAL_LANZADO, DICE_TERMINADO, ESTANCADO o TRABAJANDO segun precedencia fija: RECLAMA (pide input humano) manda sobre todo, luego MAL_LANZADO (sin DoD-contrato), luego DICE_TERMINADO, ESTANCADO y TRABAJANDO.
fleet
claude-fleet
classification
watcher
termination
orchestrator
pure
infra
orchestration
false
name desc
status estado del proceso Claude leido de sessions.json: idle | busy | waiting
name desc
phase fase de trabajo del goal.json: investigando | planificando | haciendo | testeando | puliendo | pendiente_revision | preguntando | bloqueado | en_pausa | hecho | iterando | (vacio)
name desc
dodContract criterio de aceptacion fijo del agente; cadena vacia significa que no se definio DoD-contrato (agente mal lanzado)
name desc
dodStatus estado de cumplimiento del DoD: pending | met | failed | (vacio)
name desc
idleSeconds segundos transcurridos desde la ultima actividad de la sesion
name desc
stallThresholdSeconds umbral en segundos a partir del cual un agente idle no terminado se considera ESTANCADO (comparacion >=, inclusiva)
una etiqueta string: RECLAMA | MAL_LANZADO | DICE_TERMINADO | ESTANCADO | TRABAJANDO (constantes exportadas TerminationReclama, TerminationMalLanzado, TerminationDiceTerminado, TerminationEstancado, TerminationTrabajando) true
waiting reclama input
phase preguntando reclama
phase bloqueado reclama
waiting manda aunque sin dodContract
preguntando manda aunque sin dodContract
bloqueado manda aunque idle estancado
sin dodContract busy
sin dodContract idle reciente
sin dodContract idle estancado
sin dodContract phase hecho
sin dodContract dodStatus met
idle phase hecho
idle dodStatus met
idle hecho y met
idle met aunque estancado por tiempo
idle hecho aunque estancado por tiempo
idle no hecho en umbral exacto
idle no hecho por encima del umbral
idle iterando estancado
idle dodStatus failed estancado
idle en_pausa estancado
busy trabajando
busy aunque idleSeconds alto
idle reciente bajo umbral
idle reciente cero segundos
idle no hecho justo bajo umbral
busy phase vacia con dodContract
umbral cero idle no hecho => estancado
idle hecho con umbral cero => dice terminado
dodStatus met con status busy NO termina
phase hecho con status busy NO termina
idle pendiente_revision bajo umbral trabajando
idle pendiente_revision sobre umbral estancado
waiting con dodStatus met sigue reclamando
functions/infra/classify_fleet_termination_test.go functions/infra/classify_fleet_termination.go

Ejemplo

// Agente idle que dice estar terminado.
label := ClassifyFleetTermination("idle", "hecho", "tests verdes + indexado", "met", 30, 600)
// label == "DICE_TERMINADO"  (== TerminationDiceTerminado)

// Agente idle, no terminado, parado 12 minutos con umbral de 10 minutos.
label = ClassifyFleetTermination("idle", "haciendo", "tests verdes", "pending", 720, 600)
// label == "ESTANCADO"

// Agente que reclama input humano: manda sobre todo, aunque le falte DoD.
label = ClassifyFleetTermination("waiting", "haciendo", "", "", 5, 600)
// label == "RECLAMA"

switch label {
case TerminationReclama:
    // notificar al humano
case TerminationMalLanzado:
    // matar y relanzar con DoD-contrato
case TerminationDiceTerminado:
    // pasar a verificacion de DoD
case TerminationEstancado:
    // empujar / reiniciar / escalar
case TerminationTrabajando:
    // dejar trabajar
}

Cuando usarla

Usala en el watcher del meta-orquestador de flota (dev/flows/0012-fleet-orchestrator-dod.md) cuando barras cada agente Claude y necesites decidir mecanicamente, sin gastar LLM, en que cubo cae (reclama input / mal lanzado / dice terminado / estancado / trabajando) a partir de sessions.json + goal.json. Es el paso de triaje barato antes de cualquier accion costosa.

Gotchas

  • Precedencia estricta de arriba a abajo. RECLAMA gana siempre, incluso si el agente no tiene dodContract o ya esta idle y estancado. Si tu logica espera que MAL_LANZADO domine, esta funcion no hace eso a proposito: un agente que pide input se atiende primero.
  • El umbral es inclusivo (>=). idleSeconds == stallThresholdSeconds ya cuenta como ESTANCADO. Con stallThresholdSeconds == 0 cualquier agente idle no terminado es ESTANCADO al instante.
  • status == "busy" nunca termina ni se estanca. Aunque dodStatus == "met" o phase == "hecho", si el proceso esta busy se clasifica como TRABAJANDO (la condicion de terminacion/estancamiento exige idle).
  • Strings exactos, case-sensitive. Valores fuera de los esperados (ej. "Idle", "WAITING", una phase desconocida) caen a TRABAJANDO salvo que disparen otra rama. Normaliza las entradas antes de llamar si tus fuentes no garantizan el casing.