huskies: merge 570_bug_merge_agent_work_should_check_if_story_is_already_done_before_attempting_merge

This commit is contained in:
dave
2026-04-14 16:11:34 +00:00
parent 327163eb60
commit 8482df2f4e
+71
View File
@@ -15,6 +15,23 @@ pub(super) async fn tool_merge_agent_work(
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.ok_or("Missing required argument: story_id")?; .ok_or("Missing required argument: story_id")?;
// Check CRDT stage before attempting merge — if already done or archived,
// return success immediately to avoid spurious error notifications.
if let Some(item) = crate::crdt_state::read_item(story_id)
&& (item.stage == "5_done" || item.stage == "6_archived")
{
return serde_json::to_string_pretty(&json!({
"story_id": story_id,
"status": "completed",
"success": true,
"message": format!(
"Story '{}' is already in '{}' — no merge needed.",
story_id, item.stage
),
}))
.map_err(|e| format!("Serialization error: {e}"));
}
let project_root = ctx.agents.get_project_root(&ctx.state)?; let project_root = ctx.agents.get_project_root(&ctx.state)?;
ctx.agents.start_merge_agent_work(&project_root, story_id)?; ctx.agents.start_merge_agent_work(&project_root, story_id)?;
@@ -258,6 +275,60 @@ mod tests {
assert!(result.unwrap_err().contains("story_id")); assert!(result.unwrap_err().contains("story_id"));
} }
#[tokio::test]
async fn tool_merge_agent_work_already_done_returns_success() {
crate::crdt_state::init_for_test();
crate::crdt_state::write_item(
"99_story_already_done",
"5_done",
Some("Already done story"),
None,
None,
None,
None,
None,
None,
None,
);
let tmp = tempfile::tempdir().unwrap();
let ctx = test_ctx(tmp.path());
let result =
tool_merge_agent_work(&json!({"story_id": "99_story_already_done"}), &ctx).await;
assert!(result.is_ok(), "expected Ok, got: {result:?}");
let body = result.unwrap();
let v: serde_json::Value = serde_json::from_str(&body).unwrap();
assert_eq!(v["status"], "completed");
assert_eq!(v["success"], true);
assert!(v["message"].as_str().unwrap().contains("5_done"));
}
#[tokio::test]
async fn tool_merge_agent_work_already_archived_returns_success() {
crate::crdt_state::init_for_test();
crate::crdt_state::write_item(
"98_story_already_archived",
"6_archived",
Some("Already archived story"),
None,
None,
None,
None,
None,
None,
None,
);
let tmp = tempfile::tempdir().unwrap();
let ctx = test_ctx(tmp.path());
let result =
tool_merge_agent_work(&json!({"story_id": "98_story_already_archived"}), &ctx).await;
assert!(result.is_ok(), "expected Ok, got: {result:?}");
let body = result.unwrap();
let v: serde_json::Value = serde_json::from_str(&body).unwrap();
assert_eq!(v["status"], "completed");
assert_eq!(v["success"], true);
assert!(v["message"].as_str().unwrap().contains("6_archived"));
}
#[tokio::test] #[tokio::test]
async fn tool_move_story_to_merge_missing_story_id() { async fn tool_move_story_to_merge_missing_story_id() {
let tmp = tempfile::tempdir().unwrap(); let tmp = tempfile::tempdir().unwrap();