@@ -111,6 +111,11 @@ function mergeExecutionStopSignal(
111111 summary . signalledExecutionIds . add ( signalExecutionId )
112112}
113113
114+ /**
115+ * Commits cancellation after the caller's final abort check. Once signalling begins, the
116+ * operation must finish reconciliation because workers may already have observed the durable,
117+ * local, or queued signal; attempting to honor a later abort could revive only part of a run.
118+ */
114119async function signalExecutionStop ( args : {
115120 workflowId : string
116121 signalExecutionId : string
@@ -341,6 +346,28 @@ function cancellationAbortedResponse(abortSignal?: AbortSignal): NextResponse |
341346 : null
342347}
343348
349+ async function rollbackPausedCancellationAfterAbort ( args : {
350+ stage : PausedCancellationStage
351+ workflowId : string
352+ executionId : string
353+ abortSignal ?: AbortSignal
354+ } ) : Promise < NextResponse | null > {
355+ const abortResponse = cancellationAbortedResponse ( args . abortSignal )
356+ if ( ! abortResponse ) return null
357+
358+ if ( args . stage . kind === 'active_resume' ) {
359+ await PauseResumeManager . rollbackActiveResumeCancellation (
360+ args . executionId ,
361+ args . workflowId ,
362+ args . stage . target . resumeEntryId
363+ )
364+ } else if ( args . stage . kind === 'idle' ) {
365+ await PauseResumeManager . clearPausedCancellationIntent ( args . executionId , args . workflowId )
366+ }
367+
368+ return abortResponse
369+ }
370+
344371/** Runs the existing workflow cancellation lifecycle after surface authentication. */
345372export async function cancelWorkflowExecutionPostAuth ( {
346373 workflowId,
@@ -593,6 +620,14 @@ export async function cancelWorkflowExecutionPostAuth({
593620 executionId ,
594621 workflowId
595622 )
623+ const postStageAbort = await rollbackPausedCancellationAfterAbort ( {
624+ stage : pausedCancellationStage ,
625+ workflowId,
626+ executionId,
627+ abortSignal,
628+ } )
629+ if ( postStageAbort ) return postStageAbort
630+
596631 let effectivePausedCancellationPath = isPausedCancellationStage ( pausedCancellationStage )
597632 let activeResumeTarget =
598633 pausedCancellationStage . kind === 'active_resume' ? pausedCancellationStage . target : null
@@ -656,6 +691,17 @@ export async function cancelWorkflowExecutionPostAuth({
656691 executionId ,
657692 workflowId
658693 )
694+ const postLateStageAbort = await rollbackPausedCancellationAfterAbort ( {
695+ stage : pausedCancellationStage ,
696+ workflowId,
697+ executionId,
698+ abortSignal,
699+ } )
700+ if ( postLateStageAbort ) {
701+ await clearStopSignalMarkers ( stopSummary )
702+ return postLateStageAbort
703+ }
704+
659705 effectivePausedCancellationPath = isPausedCancellationStage ( pausedCancellationStage )
660706 activeResumeTarget =
661707 pausedCancellationStage . kind === 'active_resume' ? pausedCancellationStage . target : null
0 commit comments