huskies: merge 954

This commit is contained in:
dave
2026-05-13 09:30:44 +00:00
parent c228ae1640
commit 765d54fc4b
8 changed files with 290 additions and 9 deletions
+55 -1
View File
@@ -74,7 +74,58 @@ impl AgentPool {
// Supervisors and unknown agents do not advance the pipeline.
}
PipelineStage::Coder => {
if completion.gates_passed {
if completion.needs_commit_recovery {
// The coder exited with uncommitted content but no commits.
// Check if this is already a second recovery attempt (the
// first recovery respawn also produced no commits).
let recovery_key = format!("{story_id}:commit_recovery_pending");
if crate::db::read_content(&recovery_key).is_some() {
// Second attempt still produced no commits → block.
crate::db::delete_content(&recovery_key);
slog!(
"[pipeline] Coder '{agent_name}' (commit-recovery respawn) \
still produced no commits for '{story_id}'. Blocking story."
);
let reason = "agent declined to commit recoverable work".to_string();
if let Err(e) =
crate::agents::lifecycle::transition_to_blocked(story_id, &reason)
{
slog_error!("[pipeline] Failed to block '{story_id}': {e}");
}
let _ = self.watcher_tx.send(WatcherEvent::StoryBlocked {
story_id: story_id.to_string(),
reason,
});
} else {
// First occurrence: issue a commit-only recovery respawn.
// This does NOT consume a retry_count slot.
crate::db::write_content(&recovery_key, "1");
slog!(
"[pipeline] Coder '{agent_name}' exited with uncommitted work \
for '{story_id}'. Issuing commit-only recovery respawn."
);
let addendum = "\n\nYou have uncommitted work in this worktree. \
Your only task this session is run_tests → git_add → git_commit. \
Do not explore further.";
if let Err(e) = self
.start_agent(
&project_root,
story_id,
Some(agent_name),
Some(addendum),
previous_session_id,
)
.await
{
slog_error!(
"[pipeline] Failed to start commit-recovery respawn \
for '{story_id}': {e}"
);
}
}
} else if completion.gates_passed {
// Clear any stale recovery key when the coder succeeds normally.
crate::db::delete_content(&format!("{story_id}:commit_recovery_pending"));
// Determine effective QA mode for this story.
let qa_mode = {
let item_type = crate::agents::lifecycle::item_type_from_id(story_id);
@@ -130,6 +181,9 @@ impl AgentPool {
}
}
} else {
// Clear any stale recovery key when gates fail normally (agent committed
// but the build is broken — treat as a standard retry, not a recovery).
crate::db::delete_content(&format!("{story_id}:commit_recovery_pending"));
// Bug 645 / 668: Before retry/block, check if the agent left committed
// work AND the agent had a passing run_tests result captured during its
// session. An agent may crash mid-output (e.g. Claude Code CLI PTY write