From 7dcbef1a3679e0b1636e8e7ad8e71f03d8cbb764 Mon Sep 17 00:00:00 2001 From: Armando Fernandez Date: Fri, 4 Sep 2026 17:49:17 -0700 Subject: [PATCH] Add verification-only retries and resumable pauses to plan execution --- MandoCode | 2 +- .../ViewModels/ChatController.Plans.cs | 2 ++ .../ViewModels/ChatController.cs | 35 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/MandoCode b/MandoCode index 29c745c..1f7a7ec 160000 --- a/MandoCode +++ b/MandoCode @@ -1 +1 @@ -Subproject commit 29c745c1147216153200f0aa512e55a61c46ed0c +Subproject commit 1f7a7ec89aa8a12f276e906e330ec398332146dc diff --git a/src/MandoCode.Desktop/ViewModels/ChatController.Plans.cs b/src/MandoCode.Desktop/ViewModels/ChatController.Plans.cs index 799333e..01487b3 100644 --- a/src/MandoCode.Desktop/ViewModels/ChatController.Plans.cs +++ b/src/MandoCode.Desktop/ViewModels/ChatController.Plans.cs @@ -192,6 +192,8 @@ private async Task ResumePlanAsync(PlanRunState saved) _transcript.Append(_html.Warn("Resumed plan completed with skipped or failed steps.")); else if (plan.Status == TaskPlanStatus.Cancelled) _transcript.Append(_html.Warn("Resumed plan was cancelled; its checkpoint remains available.")); + else if (plan.Status == TaskPlanStatus.Paused) + _transcript.Append(_html.Warn("Plan paused; outstanding work and verification evidence remain saved.")); else _transcript.Append(_html.Error("Resumed plan finished with unresolved failures.")); diff --git a/src/MandoCode.Desktop/ViewModels/ChatController.cs b/src/MandoCode.Desktop/ViewModels/ChatController.cs index dc96d61..909e3ca 100644 --- a/src/MandoCode.Desktop/ViewModels/ChatController.cs +++ b/src/MandoCode.Desktop/ViewModels/ChatController.cs @@ -816,6 +816,7 @@ private async Task HandleProposedPlanAsync(TaskPlan plan, CancellationTo TaskPlanStatus.Completed => ("Plan completed", plan.ExecutionSummary ?? "All steps completed successfully.", "success"), TaskPlanStatus.CompletedWithIssues => ("Plan completed with issues", plan.ExecutionSummary ?? "Some steps were skipped or failed.", "warning"), TaskPlanStatus.Cancelled => ("Plan cancelled", plan.ExecutionSummary ?? "No more plan steps will run.", "warning"), + TaskPlanStatus.Paused => ("Plan paused", plan.ExecutionSummary ?? "Outstanding work is saved. Use /plan-resume to continue.", "warning"), _ => ("Plan completed with errors", plan.ExecutionSummary ?? "One or more steps could not be completed.", "error"), }; _transcript.Append(_html.PlanFinished(outcomeTitle, outcomeDetail, outcomeState)); @@ -937,6 +938,40 @@ private async Task HandleProgressEventAsync( { switch (progressEvent.ProgressType) { + case TaskProgressType.StepActivity: + _busy.Update(progressEvent.Message ?? "Checking step..."); + _transcript.Append(_html.Dim(progressEvent.Message ?? "Checking step...")); + break; + + case TaskProgressType.StepVerificationUnavailable: + _busy.Stop(); + _transcript.Append(_html.Warn(progressEvent.Message ?? "Verification unavailable; execution evidence is saved.")); + if (ct.IsCancellationRequested) break; + var verificationChoice = await ui.ShowApprovalAsync(new ApprovalRequest + { + Title = $"Step {progressEvent.CurrentStep}: verification unavailable", + Subtitle = "The implementation will not run again. Check the saved evidence or pause.", + Options = [new ApprovalOption("Retry verification", ApprovalOptionKind.Proceed), + new ApprovalOption("Pause plan", ApprovalOptionKind.Redirect)] + }, ct); + if (verificationChoice == "Retry verification") + { + plan.Steps.First(s => s.StepNumber == progressEvent.CurrentStep).Status = TaskStepStatus.Pending; + _busy.Start("Retrying verification..."); + } + else plan.Status = TaskPlanStatus.Paused; + break; + + case TaskProgressType.PlanPaused: + _busy.Stop(); + _transcript.Append(_html.Warn(progressEvent.Message ?? "Plan paused.")); + _transcript.Append(_html.Dim("Use /plan-resume to continue from the saved step, or revise its instruction before retrying.")); + break; + + case TaskProgressType.PersistenceWarning: + _transcript.Append(_html.Warn(progressEvent.Message ?? "Plan progress could not be saved.")); + break; + case TaskProgressType.StepStarted: _recentReadCount = 0; _recentReadFiles.Clear();