fix(426): verify cherry-pick landed on master before marking story done

After the cherry-pick step in run_squash_merge, verify:
1. project_root is on the base branch (not a merge-queue branch)
2. HEAD commit has actual code changes (not an empty/story-only diff)

If either check fails, return success=false so the story stays in merge
stage for retry instead of being phantom-advanced to done.

Also rename move_story_to_archived → move_story_to_done.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dave
2026-03-28 12:37:03 +00:00
parent 5035b84de5
commit 953fce2ca6
7 changed files with 79 additions and 14 deletions
+6 -6
View File
@@ -102,7 +102,7 @@ pub fn feature_branch_has_unmerged_changes(project_root: &Path, story_id: &str)
/// * If the story is in `4_merge/`, it is moved to `5_done/` and committed.
/// * If the story is already in `5_done/` or `6_archived/`, this is a no-op (idempotent).
/// * If the story is not found in `2_current/`, `4_merge/`, `5_done/`, or `6_archived/`, an error is returned.
pub fn move_story_to_archived(project_root: &Path, story_id: &str) -> Result<(), String> {
pub fn move_story_to_done(project_root: &Path, story_id: &str) -> Result<(), String> {
let sk = project_root.join(".storkit").join("work");
let current_path = sk.join("2_current").join(format!("{story_id}.md"));
let merge_path = sk.join("4_merge").join(format!("{story_id}.md"));
@@ -584,10 +584,10 @@ mod tests {
assert!(result.unwrap_err().contains("not found in work/2_current/"));
}
// ── move_story_to_archived tests ──────────────────────────────────────────
// ── move_story_to_done tests ──────────────────────────────────────────
#[test]
fn move_story_to_archived_finds_in_merge_dir() {
fn move_story_to_done_finds_in_merge_dir() {
use std::fs;
let tmp = tempfile::tempdir().unwrap();
let root = tmp.path();
@@ -595,16 +595,16 @@ mod tests {
fs::create_dir_all(&merge_dir).unwrap();
fs::write(merge_dir.join("22_story_test.md"), "test").unwrap();
move_story_to_archived(root, "22_story_test").unwrap();
move_story_to_done(root, "22_story_test").unwrap();
assert!(!merge_dir.join("22_story_test.md").exists());
assert!(root.join(".storkit/work/5_done/22_story_test.md").exists());
}
#[test]
fn move_story_to_archived_error_when_not_in_current_or_merge() {
fn move_story_to_done_error_when_not_in_current_or_merge() {
let tmp = tempfile::tempdir().unwrap();
let result = move_story_to_archived(tmp.path(), "99_nonexistent");
let result = move_story_to_done(tmp.path(), "99_nonexistent");
assert!(result.unwrap_err().contains("4_merge"));
}