From ce23f64dc32fa35a2c5cdd5cb8d804eefbf6f848 Mon Sep 17 00:00:00 2001 From: mika kuns Date: Fri, 24 Apr 2026 18:32:52 +0200 Subject: [PATCH] fix(worker): emit PlanningMergeAborted (not Conflict) on non-conflict merge failures Co-Authored-By: Claude Sonnet 4.6 --- .../Planning/PlanningMergeOrchestrator.cs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/ClaudeDo.Worker/Planning/PlanningMergeOrchestrator.cs b/src/ClaudeDo.Worker/Planning/PlanningMergeOrchestrator.cs index 643b9a5..6c46750 100644 --- a/src/ClaudeDo.Worker/Planning/PlanningMergeOrchestrator.cs +++ b/src/ClaudeDo.Worker/Planning/PlanningMergeOrchestrator.cs @@ -96,11 +96,23 @@ public sealed class PlanningMergeOrchestrator var current = state.CurrentSubtaskId; var result = await _merge.ContinueMergeAsync(current, ct); - if (result.Status != TaskMergeService.StatusMerged) + + if (result.Status == TaskMergeService.StatusConflict) { await _broadcaster.PlanningMergeConflict(planningTaskId, current, result.ConflictFiles); return; } + + if (result.Status != TaskMergeService.StatusMerged) + { + _logger.LogWarning( + "Planning continue blocked on subtask {Subtask}: {Msg}", + current, result.ErrorMessage); + _states.TryRemove(planningTaskId, out _); + await _broadcaster.PlanningMergeAborted(planningTaskId); + return; + } + await _broadcaster.PlanningSubtaskMerged(planningTaskId, current); state.CurrentSubtaskId = null; @@ -144,11 +156,11 @@ public sealed class PlanningMergeOrchestrator if (result.Status != TaskMergeService.StatusMerged) { - await _broadcaster.PlanningMergeConflict( - planningTaskId, subtaskId, - new[] { result.ErrorMessage ?? "merge blocked" }); - keepState = true; - return; + _logger.LogWarning( + "Planning merge blocked on subtask {Subtask}: {Msg}", + subtaskId, result.ErrorMessage); + await _broadcaster.PlanningMergeAborted(planningTaskId); + return; // keepState stays false → finally removes the state entry } await _broadcaster.PlanningSubtaskMerged(planningTaskId, subtaskId);