Files
huskies/server/src/agents/pool/pipeline/merge/control.rs
T

70 lines
2.9 KiB
Rust
Raw Normal View History

2026-04-29 00:11:52 +00:00
//! Merge control — server-side trigger and failure reporting.
use crate::slog;
use crate::slog_error;
use crate::slog_warn;
use std::sync::Arc;
use super::super::super::AgentPool;
use crate::agents::{PipelineStage, pipeline_stage};
impl AgentPool {
/// Trigger a deterministic server-side merge for `story_id` without spawning
/// an LLM agent.
///
/// Constructs an `Arc<Self>` from the pool's shared fields and delegates to
/// [`start_merge_agent_work`]. The merge runs in a background task; this
/// function returns immediately.
pub(crate) fn trigger_server_side_merge(&self, project_root: &std::path::Path, story_id: &str) {
let pool = Arc::new(Self {
agents: Arc::clone(&self.agents),
port: self.port,
child_killers: Arc::clone(&self.child_killers),
watcher_tx: self.watcher_tx.clone(),
status_broadcaster: Arc::clone(&self.status_broadcaster),
});
if let Err(e) = pool.start_merge_agent_work(project_root, story_id) {
slog_error!("[merge] Failed to trigger server-side merge for '{story_id}': {e}");
}
}
/// Record that the mergemaster agent for `story_id` explicitly reported a
/// merge failure via the `report_merge_failure` MCP tool.
///
/// Sets `merge_failure_reported = true` on the active mergemaster agent so
/// that `run_pipeline_advance` can block advancement to `5_done/` even when
/// the server-owned gate check returns `gates_passed=true` (those gates run
/// in the feature-branch worktree, not on master).
pub fn set_merge_failure_reported(&self, story_id: &str) {
match self.agents.lock() {
Ok(mut lock) => {
let found = lock.iter_mut().find(|(key, agent)| {
let key_story_id = key
.rsplit_once(':')
.map(|(sid, _)| sid)
.unwrap_or(key.as_str());
key_story_id == story_id
&& pipeline_stage(&agent.agent_name) == PipelineStage::Mergemaster
});
match found {
Some((_, agent)) => {
agent.merge_failure_reported = true;
slog!(
"[pipeline] Merge failure flag set for '{story_id}:{}'",
agent.agent_name
);
}
None => {
slog_warn!(
"[pipeline] set_merge_failure_reported: no running mergemaster found \
for story '{story_id}' — flag not set"
);
}
}
}
Err(e) => {
slog_error!("[pipeline] set_merge_failure_reported: could not lock agents: {e}");
}
}
}
}