@@ -388,6 +388,53 @@ describe('orchestrator modes', () => {
388388 expect ( orchestrator . clearCheckpoint ( 'pre_pr' ) ) . rejects . toThrow ( 'Checkpoint mismatch' ) ;
389389 } ) ;
390390
391+ it ( 'does not re-checkpoint after pre_merge approval' , async ( ) => {
392+ planState = makePlan ( {
393+ mode : 'supervisor' ,
394+ status : 'running' ,
395+ jobs : [
396+ makeJob ( 'merge-me' , { status : 'completed' , mergeOrder : 0 , branch : 'mc/merge-me' } ) ,
397+ ] ,
398+ } ) ;
399+
400+ const fakeTrain = {
401+ queue : [ ] as JobSpec [ ] ,
402+ enqueue ( job : JobSpec ) {
403+ this . queue . push ( job ) ;
404+ } ,
405+ getQueue ( ) {
406+ return [ ...this . queue ] ;
407+ } ,
408+ async processNext ( ) {
409+ this . queue . shift ( ) ;
410+ return { success : true , mergedAt : '2026-01-02T00:00:00.000Z' } ;
411+ } ,
412+ } ;
413+
414+ const orchestrator = new Orchestrator ( monitor as any , DEFAULT_CONFIG as any , toastCallback ) ;
415+
416+ // First reconcile: job transitions completed -> ready_to_merge, then supervisor checkpoints
417+ await ( orchestrator as any ) . reconcile ( ) ;
418+ expect ( orchestrator . getCheckpoint ( ) ) . toBe ( 'pre_merge' ) ;
419+ expect ( planState ?. status ) . toBe ( 'paused' ) ;
420+
421+ // Inject fake merge train before clearing so the auto-reconcile uses it
422+ ( orchestrator as any ) . mergeTrain = fakeTrain ;
423+
424+ // Simulate mc_plan_approve clearing the checkpoint
425+ await orchestrator . clearCheckpoint ( 'pre_merge' ) ;
426+ expect ( orchestrator . getCheckpoint ( ) ) . toBeNull ( ) ;
427+ expect ( planState ?. status ) . toBe ( 'running' ) ;
428+
429+ // Wait for the auto-reconcile triggered by clearCheckpoint/startReconciler
430+ await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) ) ;
431+
432+ // Job should have moved to merging (enqueued in merge train) and then merged
433+ expect ( orchestrator . getCheckpoint ( ) ) . not . toBe ( 'pre_merge' ) ;
434+ const mergeJob = planState ?. jobs . find ( j => j . name === 'merge-me' ) ;
435+ expect ( mergeJob ?. status ) . toBe ( 'merged' ) ;
436+ } ) ;
437+
391438 it ( 'sends checkpoint toast notifications' , async ( ) => {
392439 planState = makePlan ( {
393440 mode : 'supervisor' ,
0 commit comments