# Plan: Story 919 ## ACs → implementation locations - AC 1 (`MergeFailure + Unblock → Merge`): `server/src/pipeline_state/transition.rs:295` — change `Ok(Coding)` to `Ok(Merge { feature_branch, commits_ahead })`. Also requires adding `feature_branch: BranchName` and `commits_ahead: NonZeroU32` to `Stage::MergeFailure` in `server/src/pipeline_state/types.rs:113`, and carrying those fields through the `Merge → MergeFailure` transition at `transition.rs:200`. - AC 2 (`Coding (blocked) + Unblock → Coding` unchanged): `server/src/pipeline_state/transition.rs:289` — `(Blocked { .. }, Unblock) => Ok(Coding)` already correct; no change needed. - AC 3 (regression test): `server/src/pipeline_state/tests.rs` — add `merge_failure_unblock_returns_to_merge` CRDT-based test. ## Decisions - Add `feature_branch` and `commits_ahead` to `MergeFailure` (rather than use synthetic defaults in the transition): allows the exact merge state to be restored on Unblock. Rejected: synthetic values at transition time (would require story_id not available in the transition function, or use a placeholder that loses the real branch name). - Update all `Stage::MergeFailure { reason }` construction sites to include the new fields with synthetic defaults where real values are unavailable (CRDT read, `from_dir`, migration). ## Current state Not started — fresh session. ## What's left - [ ] Add `feature_branch: BranchName` and `commits_ahead: NonZeroU32` to `Stage::MergeFailure` in `types.rs` - [ ] Update `types.rs` `from_dir` construction of `MergeFailure` - [ ] Update `transition.rs`: carry fields in `Merge → MergeFailure`, self-loop, fix `MergeFailure + Unblock → Merge` - [ ] Update `crdt_state/read.rs` `MergeFailure` construction - [ ] Update `crdt_state/write/migrations.rs` `MergeFailure` construction - [ ] Update `tests.rs`: all `Stage::MergeFailure { .. }` constructions, rename+fix unblock test - [ ] Add CRDT-based regression test (AC3) - [ ] Run run_check, fix any clippy/fmt issues - [ ] Run run_tests, commit