huskies: merge 893

This commit is contained in:
dave
2026-05-12 22:42:04 +00:00
parent 8e9112066f
commit 541433d96e
4 changed files with 98 additions and 4 deletions
+57 -1
View File
@@ -334,7 +334,9 @@ fn map_stage_move_to_event(
}),
(Stage::Coding | Stage::Qa | Stage::Backlog, "done") => Ok(PipelineEvent::Close),
(Stage::Blocked { .. }, "current") => Ok(PipelineEvent::Unblock),
(Stage::MergeFailure { .. }, "backlog") => Ok(PipelineEvent::Unblock),
// Story 893: MergeFailure + Unblock now goes to Coding (retry), so
// manual demotion to backlog uses Demote instead.
(Stage::MergeFailure { .. }, "backlog") => Ok(PipelineEvent::Demote),
(
Stage::Archived {
reason: ArchiveReason::Blocked { .. },
@@ -592,6 +594,60 @@ mod tests {
);
}
// ── Story 893: MergeFailure unblock → Coding regression ─────────────────
/// Regression test (story 893): unblocking a story in `MergeFailure` via
/// `transition_to_unblocked` transitions it to `Stage::Coding`, not `Backlog`.
/// After the unblock, the auto-assigner can pick it up normally (it looks for
/// stories in `Coding` / active stages).
#[test]
fn unblock_merge_failure_story_lands_in_coding() {
crate::db::ensure_content_store();
crate::db::write_item_with_content(
"99893_story_merge_failure_unblock",
"merge_failure",
"---\nname: MergeFailure Unblock Test\n---\n# Story\n",
crate::db::ItemMeta::named("MergeFailure Unblock Test"),
);
// Verify starting state is MergeFailure.
let item = crate::pipeline_state::read_typed("99893_story_merge_failure_unblock")
.expect("CRDT read should succeed")
.expect("item should exist");
assert!(
matches!(item.stage, Stage::MergeFailure { .. }),
"should start in MergeFailure: {:?}",
item.stage
);
// Unblock routes through transition_to_unblocked (same path as unblock_story MCP).
transition_to_unblocked("99893_story_merge_failure_unblock")
.expect("transition_to_unblocked should succeed for MergeFailure story");
// Story must land in Coding, not Backlog — the auto-assigner picks up
// Coding-stage stories without an extra DepsMet promotion step.
let item = crate::pipeline_state::read_typed("99893_story_merge_failure_unblock")
.expect("CRDT read should succeed")
.expect("item should exist after unblock");
assert_eq!(
item.stage.dir_name(),
"coding",
"MergeFailure story should land in Coding after unblock for immediate retry: {:?}",
item.stage
);
assert!(
matches!(item.stage, Stage::Coding),
"stage should be Stage::Coding after unblock, got: {:?}",
item.stage
);
// auto_assign checks is_active() — Coding satisfies it.
assert!(
item.stage.is_active(),
"Coding satisfies is_active() so auto_assign can pick it up: {:?}",
item.stage
);
}
// ── feature_branch_has_unmerged_changes tests ────────────────────────────
fn init_git_repo(repo: &std::path::Path) {