huskies: merge 1198 bug Failed agents are never reaped — a dead pool entry blocks respawn indefinitely

This commit is contained in:
Huskies Agent
2026-07-17 18:31:36 +00:00
parent 2335fc0bbb
commit db27d0dbf3
4 changed files with 353 additions and 1 deletions
@@ -4,9 +4,11 @@
mod budget;
mod limits;
mod orphan;
mod reap;
#[cfg(test)]
mod tests;
use std::collections::HashSet;
use std::path::Path;
use crate::agents::AgentStatus;
@@ -18,6 +20,7 @@ use crate::slog_warn;
use super::super::AgentPool;
use limits::check_agent_limits;
use orphan::check_orphaned_agents;
use reap::reap_failed_agents;
pub(crate) use budget::{compute_budget_from_logs, compute_budget_from_single_log};
pub(crate) use limits::{count_turns_in_log, resolve_session_log};
@@ -45,7 +48,9 @@ impl AgentPool {
if let Some(root) = project_root {
let terminated = check_agent_limits(&self.agents, root).await;
let config = ProjectConfig::load(root).unwrap_or_default();
let mut just_terminated: HashSet<String> = HashSet::new();
for (key, reason) in &terminated {
just_terminated.insert(key.clone());
// Step 1: snapshot the agent's worktree path so we can find every
// process running in it (claude + any subprocesses). This must
// happen BEFORE we mutate the agent record so we can read the
@@ -132,7 +137,16 @@ impl AgentPool {
if !terminated.is_empty() {
Self::notify_agent_state_changed(&self.watcher_tx);
}
return orphaned + terminated.len();
// Bug 1198: reap any other Failed pool entry with no live process
// — orphan-detected above, or left behind by a spawn error
// (inactivity-watchdog kill, worktree timeout, runtime error)
// that never routed through the retry/respawn path. Entries the
// limits loop above just processed are excluded so their retry
// count isn't bumped twice.
let reaped = reap_failed_agents(self, root, &config, &just_terminated).await;
return orphaned + terminated.len() + reaped;
}
orphaned