//! 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` 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}"); } } } }