huskies: merge 671_refactor_migrate_pipeline_state_consumers_from_string_comparisons_to_typed_pipelinestage_enum

This commit is contained in:
dave
2026-04-27 16:35:25 +00:00
parent 39a9766d7d
commit 4a0f57478c
15 changed files with 161 additions and 103 deletions
@@ -3,6 +3,7 @@
use std::path::Path;
use tokio::sync::broadcast;
use crate::pipeline_state::Stage;
use crate::worktree;
use super::super::super::ReconciliationEvent;
@@ -52,20 +53,20 @@ impl AgentPool {
let wt_path = wt_entry.path.clone();
// Determine which active stage the story is in.
let stage_dir = match find_active_story_stage(project_root, story_id) {
let stage = match find_active_story_stage(project_root, story_id) {
Some(s) => s,
None => continue, // Not in any active stage (backlog/archived or unknown).
};
// 4_merge/ is left for auto_assign to handle with a fresh mergemaster.
if stage_dir == "4_merge" {
if matches!(stage, Stage::Merge { .. }) {
continue;
}
let _ = progress_tx.send(ReconciliationEvent {
story_id: story_id.clone(),
status: "checking".to_string(),
message: format!("Checking for committed work in {stage_dir}/"),
message: format!("Checking for committed work in {}/", stage.dir_name()),
});
// Check whether the worktree has commits ahead of the base branch.
@@ -78,7 +79,8 @@ impl AgentPool {
if !has_work {
eprintln!(
"[startup:reconcile] No committed work for '{story_id}' in {stage_dir}/; skipping."
"[startup:reconcile] No committed work for '{story_id}' in {}/; skipping.",
stage.dir_name()
);
let _ = progress_tx.send(ReconciliationEvent {
story_id: story_id.clone(),
@@ -89,7 +91,8 @@ impl AgentPool {
}
eprintln!(
"[startup:reconcile] Found committed work for '{story_id}' in {stage_dir}/. Running acceptance gates."
"[startup:reconcile] Found committed work for '{story_id}' in {}/. Running acceptance gates.",
stage.dir_name()
);
let _ = progress_tx.send(ReconciliationEvent {
story_id: story_id.clone(),
@@ -130,7 +133,8 @@ impl AgentPool {
if !gates_passed {
eprintln!(
"[startup:reconcile] Gates failed for '{story_id}': {gate_output}\n\
Leaving in {stage_dir}/ for auto-assign to restart the agent."
Leaving in {}/ for auto-assign to restart the agent.",
stage.dir_name()
);
let _ = progress_tx.send(ReconciliationEvent {
story_id: story_id.clone(),
@@ -140,9 +144,12 @@ impl AgentPool {
continue;
}
eprintln!("[startup:reconcile] Gates passed for '{story_id}' (stage: {stage_dir}/).");
eprintln!(
"[startup:reconcile] Gates passed for '{story_id}' (stage: {}/).",
stage.dir_name()
);
if stage_dir == "2_current" {
if matches!(stage, Stage::Coding) {
// Coder stage — determine qa mode to decide next step.
let qa_mode = {
let item_type = crate::agents::lifecycle::item_type_from_id(story_id);
@@ -232,7 +239,7 @@ impl AgentPool {
}
}
}
} else if stage_dir == "3_qa" {
} else if matches!(stage, Stage::Qa) {
// QA stage → run coverage gate before advancing to merge.
let wt_path_for_cov = wt_path.clone();
let coverage_result = tokio::task::spawn_blocking(move || {