huskies: merge 954
This commit is contained in:
@@ -69,6 +69,7 @@ impl AgentPool {
|
||||
summary: summary.to_string(),
|
||||
gates_passed,
|
||||
gate_output,
|
||||
needs_commit_recovery: false,
|
||||
};
|
||||
|
||||
// Extract data for pipeline advance, then remove the entry so
|
||||
|
||||
@@ -95,10 +95,13 @@ pub(in crate::agents::pool) async fn run_server_owned_completion(
|
||||
}
|
||||
}
|
||||
|
||||
// Run acceptance gates.
|
||||
let (gates_passed, gate_output) = if let Some(wt_path) = worktree_path {
|
||||
// Run acceptance gates. Third element of the tuple is `needs_commit_recovery`:
|
||||
// true when the coder exited with uncommitted content but zero commits — the
|
||||
// pipeline advance will issue a commit-only recovery respawn rather than a
|
||||
// normal retry, and will NOT consume a `retry_count` slot.
|
||||
let (gates_passed, gate_output, needs_commit_recovery) = if let Some(wt_path) = worktree_path {
|
||||
let path = wt_path;
|
||||
match tokio::task::spawn_blocking(move || {
|
||||
match tokio::task::spawn_blocking(move || -> Result<(bool, String, bool), String> {
|
||||
// If the worktree is dirty, check whether committed work survived.
|
||||
// An agent crash (e.g. Claude Code CLI's `output.write(&bytes).is_ok()`
|
||||
// assertion — bug 645) can leave uncommitted files behind even though
|
||||
@@ -133,7 +136,10 @@ pub(in crate::agents::pool) async fn run_server_owned_completion(
|
||||
})
|
||||
.unwrap_or(false)
|
||||
} else {
|
||||
return Ok((false, dirty_msg));
|
||||
// Dirty worktree AND no committed work: the coder exited
|
||||
// without committing. Signal a commit-only recovery respawn
|
||||
// rather than consuming a normal retry slot.
|
||||
return Ok((false, dirty_msg, true));
|
||||
}
|
||||
} else {
|
||||
false
|
||||
@@ -152,9 +158,10 @@ pub(in crate::agents::pool) async fn run_server_owned_completion(
|
||||
"Agent exited with no commits on the feature branch. \
|
||||
The agent did not produce any code changes."
|
||||
.to_string(),
|
||||
false,
|
||||
));
|
||||
}
|
||||
let result = crate::agents::gates::run_acceptance_gates(&path);
|
||||
let (passed, output) = crate::agents::gates::run_acceptance_gates(&path)?;
|
||||
// Restore stashed uncommitted changes.
|
||||
if stashed {
|
||||
let _ = std::process::Command::new("git")
|
||||
@@ -162,18 +169,19 @@ pub(in crate::agents::pool) async fn run_server_owned_completion(
|
||||
.current_dir(&path)
|
||||
.output();
|
||||
}
|
||||
result
|
||||
Ok((passed, output, false))
|
||||
})
|
||||
.await
|
||||
{
|
||||
Ok(Ok(result)) => result,
|
||||
Ok(Err(e)) => (false, e),
|
||||
Err(e) => (false, format!("Gate check task panicked: {e}")),
|
||||
Ok(Err(e)) => (false, e, false),
|
||||
Err(e) => (false, format!("Gate check task panicked: {e}"), false),
|
||||
}
|
||||
} else {
|
||||
(
|
||||
false,
|
||||
"No worktree path available to run acceptance gates".to_string(),
|
||||
false,
|
||||
)
|
||||
};
|
||||
|
||||
@@ -192,6 +200,7 @@ pub(in crate::agents::pool) async fn run_server_owned_completion(
|
||||
summary: "Agent process exited normally".to_string(),
|
||||
gates_passed,
|
||||
gate_output,
|
||||
needs_commit_recovery,
|
||||
};
|
||||
|
||||
// Store completion report, extract data for pipeline advance, then
|
||||
|
||||
@@ -97,6 +97,7 @@ async fn server_owned_completion_skips_when_already_completed() {
|
||||
summary: "Already done".to_string(),
|
||||
gates_passed: true,
|
||||
gate_output: String::new(),
|
||||
needs_commit_recovery: false,
|
||||
};
|
||||
pool.inject_test_agent_with_completion(
|
||||
"s10",
|
||||
|
||||
Reference in New Issue
Block a user