@overdeck/core 0.45.10 → 0.45.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-state-KVbJEG5f.js → agent-state-RLhS7ckO.js} +1 -1
- package/dist/{agents-pp8FO7Uj.js → agents-By3u_fQ8.js} +1 -1
- package/dist/{agents-CQHK0CSA.js → agents-CgVr77Qq.js} +12 -12
- package/dist/{agents-CQHK0CSA.js.map → agents-CgVr77Qq.js.map} +1 -1
- package/dist/{backlog-auto-trigger-CyuoS0nl.js → backlog-auto-trigger-B_-1tk4e.js} +5 -5
- package/dist/{backlog-auto-trigger-CyuoS0nl.js.map → backlog-auto-trigger-B_-1tk4e.js.map} +1 -1
- package/dist/cli/index.js +45 -45
- package/dist/{cli-Cewlu3yU.js → cli-DGeSW85B.js} +2 -2
- package/dist/{cli-Cewlu3yU.js.map → cli-DGeSW85B.js.map} +1 -1
- package/dist/cli-MTB9IOoR.js +3 -0
- package/dist/{close-issue-BJGX9_z7.js → close-issue-Djajb6Sv.js} +2 -2
- package/dist/{close-issue-BJGX9_z7.js.map → close-issue-Djajb6Sv.js.map} +1 -1
- package/dist/{concurrency-Ca-fC7tA.js → concurrency-4rzjHAQA.js} +1 -1
- package/dist/{conversation-compaction-B_6s9EvM.js → conversation-compaction-BQvZh09I.js} +4 -4
- package/dist/{conversation-compaction-B_6s9EvM.js.map → conversation-compaction-BQvZh09I.js.map} +1 -1
- package/dist/dashboard/{advancing-selfheal-CMlGznKv.js → advancing-selfheal-BezNfM3P.js} +3 -3
- package/dist/dashboard/{advancing-selfheal-CMlGznKv.js.map → advancing-selfheal-BezNfM3P.js.map} +1 -1
- package/dist/dashboard/{agent-state-xk_G8t90.js → agent-state-BUANcaA7.js} +1 -1
- package/dist/dashboard/{agent-state-service-C1iUF9Ft.js → agent-state-service-DmFpIMbP.js} +1 -1
- package/dist/dashboard/{agent-state-service-5ge9xxhx.js → agent-state-service-tXUdp6UF.js} +2 -2
- package/dist/dashboard/{agent-state-service-5ge9xxhx.js.map → agent-state-service-tXUdp6UF.js.map} +1 -1
- package/dist/dashboard/{agents-BIggLvi_.js → agents-C-vqmKDi.js} +1 -1
- package/dist/dashboard/{agents-DHvsjsuP.js → agents-C7V4odQ6.js} +11 -11
- package/dist/dashboard/{agents-DHvsjsuP.js.map → agents-C7V4odQ6.js.map} +1 -1
- package/dist/dashboard/{backlog-auto-trigger-COm_R96V.js → backlog-auto-trigger-Cb8PR-5w.js} +2 -2
- package/dist/dashboard/{backlog-auto-trigger-COm_R96V.js.map → backlog-auto-trigger-Cb8PR-5w.js.map} +1 -1
- package/dist/dashboard/{cli-CvK9xuSS.js → cli-BgzbB6h3.js} +2 -2
- package/dist/dashboard/{cli-CvK9xuSS.js.map → cli-BgzbB6h3.js.map} +1 -1
- package/dist/dashboard/cli-DCqy_wFa.js +3 -0
- package/dist/dashboard/{close-issue-BnpErnD1.js → close-issue-BWf3pxn4.js} +2 -2
- package/dist/dashboard/{close-issue-BnpErnD1.js.map → close-issue-BWf3pxn4.js.map} +1 -1
- package/dist/dashboard/{closed-issue-reaper-DRqK5k39.js → closed-issue-reaper-D7XPq5pY.js} +4 -4
- package/dist/dashboard/{closed-issue-reaper-DRqK5k39.js.map → closed-issue-reaper-D7XPq5pY.js.map} +1 -1
- package/dist/dashboard/{closed-issue-reaper-BLCQwTpF.js → closed-issue-reaper-VSTSTROK.js} +1 -1
- package/dist/dashboard/{conflict-gate-JdFuhKuF.js → conflict-gate-DwOslTij.js} +1 -1
- package/dist/dashboard/{conflict-gate-BhKvrPxn.js → conflict-gate-FFEvTDVA.js} +3 -3
- package/dist/dashboard/{conflict-gate-BhKvrPxn.js.map → conflict-gate-FFEvTDVA.js.map} +1 -1
- package/dist/dashboard/{conversation-compaction-C5o_eKEm.js → conversation-compaction-CCqN4hWk.js} +4 -4
- package/dist/dashboard/{conversation-compaction-C5o_eKEm.js.map → conversation-compaction-CCqN4hWk.js.map} +1 -1
- package/dist/dashboard/{conversation-compaction-Ba5aZdrb.js → conversation-compaction-CL5Ti4j4.js} +1 -1
- package/dist/dashboard/{deacon-j3qSZ7--.js → deacon-CGHl90eC.js} +107 -50
- package/dist/dashboard/{deacon-j3qSZ7--.js.map → deacon-CGHl90eC.js.map} +1 -1
- package/dist/dashboard/{deacon-Cv2RMfHs.js → deacon-DMPh40Im.js} +2 -2
- package/dist/dashboard/deacon-swarm-CVTiNL0N.js +2 -0
- package/dist/dashboard/{deacon-swarm-DadWNi5J.js → deacon-swarm-aMMJTq6t.js} +4 -4
- package/dist/dashboard/{deacon-swarm-DadWNi5J.js.map → deacon-swarm-aMMJTq6t.js.map} +1 -1
- package/dist/dashboard/deacon.js +4 -4
- package/dist/dashboard/{feedback-target-oE4-Esxl.js → feedback-target-dJjFfITP.js} +4 -4
- package/dist/dashboard/{feedback-target-oE4-Esxl.js.map → feedback-target-dJjFfITP.js.map} +1 -1
- package/dist/dashboard/{feedback-target-C4DaDSZ8.js → feedback-target-nQSM6ygL.js} +1 -1
- package/dist/dashboard/{flywheel-ClMjGW_u.js → flywheel-BLoVNtJV.js} +6 -6
- package/dist/dashboard/{flywheel-ClMjGW_u.js.map → flywheel-BLoVNtJV.js.map} +1 -1
- package/dist/dashboard/{flywheel-DefHRzY4.js → flywheel-Cqf8vu7N.js} +6 -6
- package/dist/dashboard/{flywheel-DefHRzY4.js.map → flywheel-Cqf8vu7N.js.map} +1 -1
- package/dist/dashboard/{flywheel-BqDdGvrQ.js → flywheel-PJsbrXNY.js} +1 -1
- package/dist/dashboard/{flywheel-merge-order-CuDcqTRJ.js → flywheel-merge-order-B7BH8mZ3.js} +2 -2
- package/dist/dashboard/{flywheel-merge-order-CuDcqTRJ.js.map → flywheel-merge-order-B7BH8mZ3.js.map} +1 -1
- package/dist/dashboard/{flywheel-merge-order-B6YDSElh.js → flywheel-merge-order-CCwF60b-.js} +1 -1
- package/dist/dashboard/{harness-resolve-DKeSVsJL.js → harness-resolve-B3f9G1Kp.js} +2 -2
- package/dist/dashboard/{harness-resolve-DKeSVsJL.js.map → harness-resolve-B3f9G1Kp.js.map} +1 -1
- package/dist/dashboard/{inspect-agent-BKKc0XnB.js → inspect-agent-CKF5-SJr.js} +3 -3
- package/dist/dashboard/{inspect-agent-BKKc0XnB.js.map → inspect-agent-CKF5-SJr.js.map} +1 -1
- package/dist/dashboard/inspect-agent-CqpEWGWy.js +2 -0
- package/dist/dashboard/{issue-lifecycle-DnhQgddB.js → issue-lifecycle-5LbOcATP.js} +7 -7
- package/dist/dashboard/{issue-lifecycle-DnhQgddB.js.map → issue-lifecycle-5LbOcATP.js.map} +1 -1
- package/dist/dashboard/{issue-lifecycle-nY4esZn8.js → issue-lifecycle-CjYqQ669.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-Bnqv1uaa.js → issue-service-singleton-B8iu_TKV.js} +1 -1
- package/dist/dashboard/{issue-service-singleton-_AquSBTl.js → issue-service-singleton-CDGt__oQ.js} +2 -2
- package/dist/dashboard/{issue-service-singleton-_AquSBTl.js.map → issue-service-singleton-CDGt__oQ.js.map} +1 -1
- package/dist/dashboard/{lifecycle-CGKm7doE.js → lifecycle-CEg4sHZH.js} +4 -4
- package/dist/dashboard/{lifecycle-CGKm7doE.js.map → lifecycle-CEg4sHZH.js.map} +1 -1
- package/dist/dashboard/{merge-agent-Dh8Y9PDO.js → merge-agent-7nBiCytp.js} +1 -1
- package/dist/dashboard/{merge-agent-BcgAYStl.js → merge-agent-C81xPIGd.js} +6 -6
- package/dist/dashboard/{merge-agent-BcgAYStl.js.map → merge-agent-C81xPIGd.js.map} +1 -1
- package/dist/dashboard/merge-ops-DE_6CnmZ.js +2 -0
- package/dist/dashboard/{merge-train-DmxlYbEo.js → merge-train-D3qzRccL.js} +2 -2
- package/dist/dashboard/{merge-train-DmxlYbEo.js.map → merge-train-D3qzRccL.js.map} +1 -1
- package/dist/dashboard/{merge-train-deps-DBHsOWt9.js → merge-train-deps-Be5ElC_P.js} +2 -2
- package/dist/dashboard/{merge-train-deps-DBHsOWt9.js.map → merge-train-deps-Be5ElC_P.js.map} +1 -1
- package/dist/dashboard/{orphan-proposed-reconciler-Db8tUhce.js → orphan-proposed-reconciler-Boq_XaRe.js} +3 -3
- package/dist/dashboard/{orphan-proposed-reconciler-Db8tUhce.js.map → orphan-proposed-reconciler-Boq_XaRe.js.map} +1 -1
- package/dist/dashboard/{orphan-proposed-reconciler-mXV--tcB.js → orphan-proposed-reconciler-C0sPnDq_.js} +1 -1
- package/dist/dashboard/{reconstruct-cache-_tDZ2D72.js → reconstruct-cache-C2pCltOq.js} +3 -3
- package/dist/dashboard/{reconstruct-cache-_tDZ2D72.js.map → reconstruct-cache-C2pCltOq.js.map} +1 -1
- package/dist/dashboard/{remote-completion-Bklh6loJ.js → remote-completion-BmxD5UMQ.js} +3 -3
- package/dist/dashboard/{remote-completion-Bklh6loJ.js.map → remote-completion-BmxD5UMQ.js.map} +1 -1
- package/dist/dashboard/resume-C-nxu9Y4.js +3 -0
- package/dist/dashboard/{review-agent-phzqNqIs.js → review-agent-D6P6d3pz.js} +26 -17
- package/dist/dashboard/review-agent-D6P6d3pz.js.map +1 -0
- package/dist/dashboard/review-agent-DTINEffB.js +3 -0
- package/dist/dashboard/{review-context-CCq56O_Y.js → review-context-Dyo0tsBa.js} +2 -2
- package/dist/dashboard/{review-context-CCq56O_Y.js.map → review-context-Dyo0tsBa.js.map} +1 -1
- package/dist/dashboard/{review-status-BQjqQXZG.js → review-status-B5ZASOo4.js} +18 -5
- package/dist/dashboard/review-status-B5ZASOo4.js.map +1 -0
- package/dist/dashboard/{review-status-bBkqUj5i.js → review-status-h7BXIA4z.js} +1 -1
- package/dist/dashboard/{review-verdict-feedback-wqnikhMK.js → review-verdict-feedback-B70VbfRL.js} +4 -4
- package/dist/dashboard/{review-verdict-feedback-wqnikhMK.js.map → review-verdict-feedback-B70VbfRL.js.map} +1 -1
- package/dist/dashboard/{review-verdict-feedback-cZh9Wi9G.js → review-verdict-feedback-CorgH49f.js} +1 -1
- package/dist/dashboard/{sequence-io-B2GmilSI.js → sequence-io-6YP8fVpH.js} +2 -2
- package/dist/dashboard/{sequence-io-B2GmilSI.js.map → sequence-io-6YP8fVpH.js.map} +1 -1
- package/dist/dashboard/{sequencer-agent-D8pW2aU_.js → sequencer-agent-ja-nkEc1.js} +5 -5
- package/dist/dashboard/{sequencer-agent-D8pW2aU_.js.map → sequencer-agent-ja-nkEc1.js.map} +1 -1
- package/dist/dashboard/server.js +66 -55
- package/dist/dashboard/server.js.map +1 -1
- package/dist/dashboard/{service-CILd-uOt.js → service-HKDrIy0h.js} +24 -24
- package/dist/dashboard/{service-CILd-uOt.js.map → service-HKDrIy0h.js.map} +1 -1
- package/dist/dashboard/{smart-compaction-Bgp_gwcA.js → smart-compaction-L0LSnF0_.js} +1 -1
- package/dist/dashboard/{smart-compaction-CrP90OFE.js → smart-compaction-uke1npUz.js} +2 -2
- package/dist/dashboard/{smart-compaction-CrP90OFE.js.map → smart-compaction-uke1npUz.js.map} +1 -1
- package/dist/dashboard/{spawn-planning-session-D15KbPOy.js → spawn-planning-session-CSMWco8B.js} +1 -1
- package/dist/dashboard/{spawn-planning-session-BmJWHSCu.js → spawn-planning-session-CXc0NkwV.js} +3 -3
- package/dist/dashboard/{spawn-planning-session-BmJWHSCu.js.map → spawn-planning-session-CXc0NkwV.js.map} +1 -1
- package/dist/dashboard/{specialist-context-CwKkcXL9.js → specialist-context-BGCJ24LH.js} +3 -3
- package/dist/dashboard/{specialist-context-CwKkcXL9.js.map → specialist-context-BGCJ24LH.js.map} +1 -1
- package/dist/dashboard/{specialist-logs-CvDxquV_.js → specialist-logs--Uz-r8ia.js} +2 -2
- package/dist/dashboard/{specialist-logs-CvDxquV_.js.map → specialist-logs--Uz-r8ia.js.map} +1 -1
- package/dist/dashboard/{specialists-BCjcG4uE.js → specialists-Ca9XSBCS.js} +1 -1
- package/dist/dashboard/{specialists-D07ybnam.js → specialists-DEfrAbWs.js} +36 -36
- package/dist/dashboard/{specialists-D07ybnam.js.map → specialists-DEfrAbWs.js.map} +1 -1
- package/dist/dashboard/{specialists-F2uMO4QS.js → specialists-DeZx9xom.js} +1 -1
- package/dist/dashboard/{specialists-BYi0k8CZ.js → specialists-nZ0mRwpZ.js} +12 -12
- package/dist/dashboard/{specialists-BYi0k8CZ.js.map → specialists-nZ0mRwpZ.js.map} +1 -1
- package/dist/dashboard/{summary-fork-DedqguZb.js → summary-fork-2a1L2DIU.js} +2 -2
- package/dist/dashboard/{summary-fork-EjvOkEPl.js → summary-fork-Xn0QUNmb.js} +3 -3
- package/dist/dashboard/{summary-fork-EjvOkEPl.js.map → summary-fork-Xn0QUNmb.js.map} +1 -1
- package/dist/dashboard/{teardown-workspace-5LCVbjfq.js → teardown-workspace-DhA6oAIK.js} +2 -2
- package/dist/dashboard/{teardown-workspace-5LCVbjfq.js.map → teardown-workspace-DhA6oAIK.js.map} +1 -1
- package/dist/dashboard/{test-agent-queue-qfsq6uaC.js → test-agent-queue-B_ukPyIK.js} +3 -3
- package/dist/dashboard/{test-agent-queue-qfsq6uaC.js.map → test-agent-queue-B_ukPyIK.js.map} +1 -1
- package/dist/dashboard/{uat-train-CtNGgXxj.js → uat-train-BLBAbJ8Y.js} +10 -10
- package/dist/dashboard/{uat-train-CtNGgXxj.js.map → uat-train-BLBAbJ8Y.js.map} +1 -1
- package/dist/dashboard/{uat-train-C3hWXtip.js → uat-train-DPfGR9_I.js} +1 -1
- package/dist/dashboard/{verification-runner-DuZRHjPU.js → verification-runner-KTGTNugM.js} +1 -1
- package/dist/dashboard/{verification-runner-BPAhPWR7.js → verification-runner-R2-4XgMO.js} +4 -4
- package/dist/dashboard/{verification-runner-BPAhPWR7.js.map → verification-runner-R2-4XgMO.js.map} +1 -1
- package/dist/dashboard/{workflows-H-COJ84X.js → workflows-CSKX5MhC.js} +7 -7
- package/dist/dashboard/{workflows-H-COJ84X.js.map → workflows-CSKX5MhC.js.map} +1 -1
- package/dist/dashboard/workflows-DVwXauef.js +2 -0
- package/dist/dashboard/{workspaces-CRU9_vRn.js → workspaces-DXLDgXo2.js} +32 -32
- package/dist/dashboard/{workspaces-CRU9_vRn.js.map → workspaces-DXLDgXo2.js.map} +1 -1
- package/dist/docs-index.sqlite +0 -0
- package/dist/{feedback-target-DTGAhFkM.js → feedback-target-BsKN4Tr_.js} +4 -4
- package/dist/{feedback-target-DTGAhFkM.js.map → feedback-target-BsKN4Tr_.js.map} +1 -1
- package/dist/{feedback-target-DutF088V.js → feedback-target-DM1WzOKy.js} +1 -1
- package/dist/{harness-resolve-Bz1prk6B.js → harness-resolve-B-YDNwNW.js} +2 -2
- package/dist/{harness-resolve-Bz1prk6B.js.map → harness-resolve-B-YDNwNW.js.map} +1 -1
- package/dist/{issue-lifecycle-fVqvCdKM.js → issue-lifecycle-Bc1l3U9f.js} +7 -7
- package/dist/{issue-lifecycle-fVqvCdKM.js.map → issue-lifecycle-Bc1l3U9f.js.map} +1 -1
- package/dist/{issue-service-singleton-CZm8p6Rj.js → issue-service-singleton-D-8Q6tdT.js} +1 -1
- package/dist/{issue-service-singleton-Cr73JAaR.js → issue-service-singleton-D1433I7n.js} +2 -2
- package/dist/{issue-service-singleton-Cr73JAaR.js.map → issue-service-singleton-D1433I7n.js.map} +1 -1
- package/dist/{lifecycle-CR6tZfl1.js → lifecycle-SmrqysDf.js} +7 -7
- package/dist/{lifecycle-CR6tZfl1.js.map → lifecycle-SmrqysDf.js.map} +1 -1
- package/dist/{lifecycle-D_EWiUjk.js → lifecycle-mRMyiIXs.js} +2 -2
- package/dist/{merge-agent-LM4avOtA.js → merge-agent-B9hIZ6Z0.js} +6 -6
- package/dist/{merge-agent-LM4avOtA.js.map → merge-agent-B9hIZ6Z0.js.map} +1 -1
- package/dist/{merge-agent-Bj046HE1.js → merge-agent-DUj22cXL.js} +1 -1
- package/dist/{merge-fulfillment-DrnC1Kmg.js → merge-fulfillment-__P4WE-T.js} +3 -3
- package/dist/{merge-fulfillment-DrnC1Kmg.js.map → merge-fulfillment-__P4WE-T.js.map} +1 -1
- package/dist/{reconstruct-cache-NPqoAUg-.js → reconstruct-cache-9SWp82SQ.js} +3 -3
- package/dist/{reconstruct-cache-NPqoAUg-.js.map → reconstruct-cache-9SWp82SQ.js.map} +1 -1
- package/dist/{records-BIkN1LQ4.js → records-CTmvuRzz.js} +14 -1
- package/dist/{records-BIkN1LQ4.js.map → records-CTmvuRzz.js.map} +1 -1
- package/dist/records-backfill-BQcmTmwF.js +2 -0
- package/dist/{records-backfill-HM0Pln6N.js → records-backfill-BrNsv_zT.js} +2 -2
- package/dist/{records-backfill-HM0Pln6N.js.map → records-backfill-BrNsv_zT.js.map} +1 -1
- package/dist/resume-Bn4kDk9x.js +3 -0
- package/dist/{review-agent-DFosQzCG.js → review-agent-PhqOhpx3.js} +24 -16
- package/dist/{review-agent-DFosQzCG.js.map → review-agent-PhqOhpx3.js.map} +1 -1
- package/dist/review-agent-hLbRRxZF.js +3 -0
- package/dist/{review-status-iJwfEoNX.js → review-status-B_XXomV0.js} +6 -6
- package/dist/{review-status-iJwfEoNX.js.map → review-status-B_XXomV0.js.map} +1 -1
- package/dist/{review-status-BbNVlXh1.js → review-status-Bo-EFVKh.js} +1 -1
- package/dist/{review-verdict-feedback-BGPw3z1X.js → review-verdict-feedback-CXHkoiKZ.js} +1 -1
- package/dist/{review-verdict-feedback-CCZ05atV.js → review-verdict-feedback-DGV13LDb.js} +4 -4
- package/dist/{review-verdict-feedback-CCZ05atV.js.map → review-verdict-feedback-DGV13LDb.js.map} +1 -1
- package/dist/{sequence-io-CcxZNHcD.js → sequence-io-Cg4NHAco.js} +1 -1
- package/dist/{sequence-io-Cx1usxG3.js → sequence-io-CyxvNHfA.js} +2 -2
- package/dist/{sequence-io-Cx1usxG3.js.map → sequence-io-CyxvNHfA.js.map} +1 -1
- package/dist/{smart-compaction-ByUEgQkF.js → smart-compaction-ByKXTQNy.js} +2 -2
- package/dist/{smart-compaction-ByUEgQkF.js.map → smart-compaction-ByKXTQNy.js.map} +1 -1
- package/dist/{smart-compaction-DfLe_CtH.js → smart-compaction-U6e_uB1E.js} +1 -1
- package/dist/{specialist-context-McuGkaeR.js → specialist-context-BUTadO-U.js} +3 -3
- package/dist/{specialist-context-McuGkaeR.js.map → specialist-context-BUTadO-U.js.map} +1 -1
- package/dist/{specialist-logs-CUUJ4eiB.js → specialist-logs-pEMCTtGZ.js} +2 -2
- package/dist/{specialist-logs-CUUJ4eiB.js.map → specialist-logs-pEMCTtGZ.js.map} +1 -1
- package/dist/{specialists-BSrylD1S.js → specialists-BGFnrQ8n.js} +1 -1
- package/dist/{specialists-B0elgInc.js → specialists-DeTkkp8b.js} +12 -12
- package/dist/{specialists-B0elgInc.js.map → specialists-DeTkkp8b.js.map} +1 -1
- package/dist/{summary-fork-DskMRnyb.js → summary-fork-CgzThE2-.js} +2 -2
- package/dist/{summary-fork-CPUTKcAT.js → summary-fork-Dx1RMuvU.js} +3 -3
- package/dist/{summary-fork-CPUTKcAT.js.map → summary-fork-Dx1RMuvU.js.map} +1 -1
- package/dist/{sync-BiNVQHBf.js → sync-Bsww9tuj.js} +2 -2
- package/dist/{sync-BiNVQHBf.js.map → sync-Bsww9tuj.js.map} +1 -1
- package/dist/sync-CylE_SjB.js +2 -0
- package/dist/{verdict-restore-DQiV7_fe.js → verdict-restore-DGpX0ZOJ.js} +5 -5
- package/dist/{verdict-restore-DQiV7_fe.js.map → verdict-restore-DGpX0ZOJ.js.map} +1 -1
- package/dist/{webhook-handlers-DHBSEDEm.js → webhook-handlers-BjsfIL7u.js} +3 -3
- package/dist/{webhook-handlers-DHBSEDEm.js.map → webhook-handlers-BjsfIL7u.js.map} +1 -1
- package/dist/{workspace-migrate-duUsWNpd.js → workspace-migrate-BBQ8nAnP.js} +2 -2
- package/dist/{workspace-migrate-duUsWNpd.js.map → workspace-migrate-BBQ8nAnP.js.map} +1 -1
- package/dist/{workspace-reap-DLCIoJmn.js → workspace-reap-12O9354k.js} +2 -2
- package/dist/{workspace-reap-DLCIoJmn.js.map → workspace-reap-12O9354k.js.map} +1 -1
- package/package.json +1 -1
- package/scripts/file-size-baseline.txt +1 -1
- package/dist/cli-DBWG12XK.js +0 -3
- package/dist/dashboard/cli-CJDWXE_Y.js +0 -3
- package/dist/dashboard/deacon-swarm-D1iAUX-P.js +0 -2
- package/dist/dashboard/inspect-agent-vm88mLYr.js +0 -2
- package/dist/dashboard/merge-ops-QdBiQ8XB.js +0 -2
- package/dist/dashboard/resume-DnIsmIgC.js +0 -3
- package/dist/dashboard/review-agent-DgySDb-G.js +0 -3
- package/dist/dashboard/review-agent-phzqNqIs.js.map +0 -1
- package/dist/dashboard/review-status-BQjqQXZG.js.map +0 -1
- package/dist/dashboard/workflows-Cz8OtiB4.js +0 -2
- package/dist/records-backfill-DEgtRyKL.js +0 -2
- package/dist/resume-DGymuXZM.js +0 -3
- package/dist/review-agent-DjVadURa.js +0 -3
- package/dist/sync-4jqukkxz.js +0 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as postUatGenerationStackPayload, c as startUatTrainReconciler, i as postUatGenerationPromotePayload, l as stopUatTrainReconciler, n as getUatCandidatePayload, o as resolveUatProjectRoot, r as getUatGenerationsPayload, s as runUatTrainReconcile, t as canStartUatTrainReconciler } from "./uat-train-
|
|
1
|
+
import { a as postUatGenerationStackPayload, c as startUatTrainReconciler, i as postUatGenerationPromotePayload, l as stopUatTrainReconciler, n as getUatCandidatePayload, o as resolveUatProjectRoot, r as getUatGenerationsPayload, s as runUatTrainReconcile, t as canStartUatTrainReconciler } from "./uat-train-BLBAbJ8Y.js";
|
|
2
2
|
export { canStartUatTrainReconciler, getUatCandidatePayload, getUatGenerationsPayload, postUatGenerationPromotePayload, postUatGenerationStackPayload, resolveUatProjectRoot, runUatTrainReconcile, startUatTrainReconciler, stopUatTrainReconciler };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as runVerificationForIssue } from "./verification-runner-
|
|
1
|
+
import { n as runVerificationForIssue } from "./verification-runner-R2-4XgMO.js";
|
|
2
2
|
export { runVerificationForIssue };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Nn as init_projects, bn as findProjectByPathSync } from "./config-yaml-DPAieL_G.js";
|
|
2
|
-
import { c as init_review_status, f as markWorkspaceStuck, s as getReviewStatusSync, y as setReviewStatusSync } from "./review-status-
|
|
3
|
-
import { K as stopAgent, Yn as setAgentPaused, j as messageAgent, t as init_agents } from "./agents-
|
|
2
|
+
import { c as init_review_status, f as markWorkspaceStuck, s as getReviewStatusSync, y as setReviewStatusSync } from "./review-status-B5ZASOo4.js";
|
|
3
|
+
import { K as stopAgent, Yn as setAgentPaused, j as messageAgent, t as init_agents } from "./agents-C7V4odQ6.js";
|
|
4
4
|
import { o as init_io, t as VBriefMergeConflictError } from "./io-Wy8YpFeP.js";
|
|
5
5
|
import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-DMaO0XXa.js";
|
|
6
|
-
import { n as resolveIssueFeedbackTarget, r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-
|
|
6
|
+
import { n as resolveIssueFeedbackTarget, r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-dJjFfITP.js";
|
|
7
7
|
import { n as init_validation, r as runQualityGates, t as DEFAULT_GATES } from "./validation-BmUB-26g.js";
|
|
8
8
|
import { a as getVBriefACStatusSync } from "./beads-DlZm-vrG.js";
|
|
9
9
|
import { Effect } from "effect";
|
|
@@ -552,4 +552,4 @@ function runVerificationForIssue(issueId, workspacePath, workspaceInfo, logPrefi
|
|
|
552
552
|
//#endregion
|
|
553
553
|
export { runVerificationForIssue as n, changesetHasNoContent as t };
|
|
554
554
|
|
|
555
|
-
//# sourceMappingURL=verification-runner-
|
|
555
|
+
//# sourceMappingURL=verification-runner-R2-4XgMO.js.map
|
package/dist/dashboard/{verification-runner-BPAhPWR7.js.map → verification-runner-R2-4XgMO.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-runner-BPAhPWR7.js","names":[],"sources":["../../src/lib/cloister/verification-runner.ts"],"sourcesContent":["/**\n * Verification Runner — orchestrates the full verification gate lifecycle.\n *\n * Runs quality gates (typecheck → lint → test by default, or project-specific\n * gates from projects.yaml), updates review status, writes feedback files,\n * and notifies the work agent on failure.\n *\n * Extracted from dashboard/server to be independently testable.\n */\n\nimport { basename, dirname, join } from 'path';\nimport { homedir } from 'os';\nimport { exec } from 'child_process';\nimport { existsSync } from 'fs';\nimport { readdir } from 'fs/promises';\nimport { promisify } from 'util';\nimport { Effect } from 'effect';\nimport { getReviewStatusSync, markWorkspaceStuck, setReviewStatusSync } from '../review-status.js';\nimport { runQualityGates, DEFAULT_GATES } from './validation.js';\nimport { writeFeedbackFile } from './feedback-writer.js';\nimport { resolveIssueFeedbackTarget, surfaceIssueFeedbackNeedsYou } from './feedback-target.js';\nimport { messageAgent, setAgentPaused, stopAgent } from '../agents.js';\nimport { findProjectByPathSync } from '../projects.js';\nimport { getVBriefACStatusSync } from '../vbrief/beads.js';\nimport { VBriefMergeConflictError } from '../vbrief/io.js';\nimport type { TemplatePlaceholders } from '../workspace-config.js';\n\nconst execAsync = promisify(exec);\n\nexport const VERIFICATION_MAX_CYCLES = 3;\nconst NO_PROGRESS_REPEAT_THRESHOLD = 2;\n\nexport type VerificationRunnerOutcome =\n | { outcome: 'passed' }\n | { outcome: 'skipped'; reason: string }\n | { outcome: 'failed'; failedCheck: string; cycleCount: number; maxCycles: number }\n | { outcome: 'error'; message: string };\n\nexport interface WorkspaceInfo {\n isRemote: boolean;\n vmName?: string;\n}\n\nexport interface VerificationRunnerOptions {\n syncTargetBranch?: boolean;\n /** PAN-2487: receives human-readable gate progress lines (ship-log mirror). */\n onGateLog?: (line: string) => void;\n}\n\ninterface SyncResult {\n repoDir: string;\n repoName: string;\n targetBranch: string;\n success: boolean;\n alreadyUpToDate?: boolean;\n hasConflicts?: boolean;\n conflictLines?: string;\n errorOutput?: string;\n}\n\nfunction isFinalVerificationAttempt(cycleCount: number): boolean {\n return cycleCount >= VERIFICATION_MAX_CYCLES;\n}\n\nfunction isRepeatFailedCheck(\n status: ReturnType<typeof getReviewStatusSync> | null | undefined,\n failedCheck: string,\n): boolean {\n return (\n status?.verificationStatus === 'failed' &&\n status.verificationNotes?.startsWith(`Verification FAILED at ${failedCheck} `) === true\n );\n}\n\nfunction shouldEscalateVerificationFailure(\n status: ReturnType<typeof getReviewStatusSync> | null | undefined,\n failedCheck: string,\n cycleCount: number,\n): boolean {\n if (isFinalVerificationAttempt(cycleCount)) return true;\n return cycleCount >= NO_PROGRESS_REPEAT_THRESHOLD && isRepeatFailedCheck(status, failedCheck);\n}\n\nfunction buildFinalFailureInstructions(issueId: string): string {\n return `## NEEDS-YOU: Verification stuck\n\nThis was the final allowed verification attempt. The work agent is paused so it does not keep spending cycles on the same failing gate.\n\nAn operator needs to inspect ${issueId}, decide whether to fix-forward manually, restart the agent with new instructions, or move the issue through the normal pipeline. Do not re-request review automatically.`;\n}\n\nfunction setStateDerivedVerificationFailure(\n issueId: string,\n failedCheck: string,\n summary: string,\n cycleCount: number,\n currentStatus: ReturnType<typeof getReviewStatusSync> | null | undefined,\n): void {\n setReviewStatusSync(issueId, {\n verificationStatus: 'failed',\n verificationNotes: summary,\n verificationCycleCount: cycleCount,\n verificationMaxCycles: VERIFICATION_MAX_CYCLES,\n });\n\n if (currentStatus?.reviewStatus !== 'passed') return;\n\n markWorkspaceStuck(issueId, 'state_derived_verification_hold', {\n failedCheck,\n summary,\n reviewStatus: currentStatus.reviewStatus,\n });\n console.warn(`[verification-runner] ${issueId} review is passed but held by state-derived gate ${failedCheck}: ${summary}`);\n}\n\nasync function escalateVerificationStuck(\n issueId: string,\n failedCheck: string,\n cycleCount: number,\n summary: string,\n logPrefix: string,\n): Promise<void> {\n const agentId = `agent-${issueId.toLowerCase()}`;\n const reason = `needs-you: verification stuck after ${cycleCount}/${VERIFICATION_MAX_CYCLES} attempts (${failedCheck})`;\n\n markWorkspaceStuck(issueId, 'verification_stuck', {\n failedCheck,\n cycleCount,\n maxCycles: VERIFICATION_MAX_CYCLES,\n summary,\n });\n\n try {\n await Effect.runPromise(setAgentPaused(agentId, reason, true));\n await Effect.runPromise(stopAgent(agentId));\n console.log(`[${logPrefix}] Verification stuck for ${issueId} — paused ${agentId} and marked workspace stuck`);\n } catch (err: any) {\n console.error(`[${logPrefix}] Failed to pause ${agentId} after verification stuck:`, err);\n }\n}\n\nasync function deliverVerificationFeedback(\n issueId: string,\n message: string,\n details: Record<string, unknown>,\n logPrefix: string,\n): Promise<void> {\n const target = await resolveIssueFeedbackTarget(issueId);\n if ('agentId' in target) {\n await messageAgent(target.agentId, message);\n console.log(`[${logPrefix}] Sent verification feedback for ${issueId} to ${target.agentId}`);\n return;\n }\n\n await surfaceIssueFeedbackNeedsYou(issueId, target.reason, {\n specialist: 'verification-gate',\n ...details,\n });\n}\n\nasync function resolveGitDirs(\n workspacePath: string,\n projectConfig: ReturnType<typeof findProjectByPathSync>,\n): Promise<{ gitDirs: string[]; isPolyrepo: boolean }> {\n const isPolyrepoConfig = projectConfig?.workspace?.type === 'polyrepo';\n\n if (!isPolyrepoConfig && existsSync(join(workspacePath, '.git'))) {\n return { gitDirs: [workspacePath], isPolyrepo: false };\n }\n\n const gitDirs: string[] = [];\n try {\n const entries = await readdir(workspacePath, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && existsSync(join(workspacePath, entry.name, '.git'))) {\n gitDirs.push(join(workspacePath, entry.name));\n }\n }\n } catch {}\n\n if (gitDirs.length > 0) {\n return { gitDirs, isPolyrepo: true };\n }\n\n if (existsSync(join(workspacePath, '.git'))) {\n return { gitDirs: [workspacePath], isPolyrepo: false };\n }\n\n return { gitDirs: [], isPolyrepo: false };\n}\n\nasync function syncSingleRepo(gitDir: string, targetBranch: string): Promise<SyncResult> {\n const repoName = basename(gitDir);\n try {\n await execAsync(`git fetch origin ${targetBranch}`, { cwd: gitDir, encoding: 'utf-8', timeout: 30000 });\n const mergeResult = await execAsync(`git merge origin/${targetBranch} --no-edit`, {\n cwd: gitDir,\n encoding: 'utf-8',\n timeout: 60000,\n });\n const mergeOut = (mergeResult.stdout || '') + (mergeResult.stderr || '');\n const alreadyUpToDate = mergeOut.includes('Already up to date') || mergeOut.includes('Already up-to-date');\n return { repoDir: gitDir, repoName, targetBranch, success: true, alreadyUpToDate };\n } catch (mergeErr: any) {\n const mergeOut = (mergeErr.stdout || '') + (mergeErr.stderr || '');\n const hasConflicts = mergeOut.includes('CONFLICT') || mergeOut.includes('Merge conflict');\n\n if (hasConflicts) {\n try { await execAsync('git merge --abort', { cwd: gitDir, encoding: 'utf-8' }); } catch {}\n const conflictLines = mergeOut\n .split('\\n')\n .filter((line: string) => line.startsWith('CONFLICT'))\n .map((line: string) => line.replace(/^CONFLICT \\([^)]+\\): /, '').replace(/Merge conflict in /, ''))\n .join('\\n - ');\n return { repoDir: gitDir, repoName, targetBranch, success: false, hasConflicts: true, conflictLines };\n }\n\n const rawOutput = mergeOut || mergeErr.message || '(no output)';\n const errorOutput = rawOutput.length > 3000 ? rawOutput.slice(0, 3000) + '\\n...(truncated)' : rawOutput;\n return { repoDir: gitDir, repoName, targetBranch, success: false, errorOutput };\n }\n}\n\nfunction buildSyncFailureFeedback(\n issueId: string,\n failures: SyncResult[],\n isPolyrepo: boolean,\n cycleCount: number,\n): { summary: string; feedbackBody: string } {\n const hasConflicts = failures.some(f => f.hasConflicts);\n\n const summaryParts = failures.map(f => {\n const prefix = isPolyrepo ? `[${f.repoName}] ` : '';\n if (f.hasConflicts) {\n return `${prefix}Merge conflicts with ${f.targetBranch}:\\n - ${f.conflictLines}`;\n }\n return `${prefix}Sync with ${f.targetBranch} FAILED:\\n${f.errorOutput}`;\n });\n const summary = isPolyrepo\n ? `Sync FAILED in ${failures.length} repo(s):\\n\\n${summaryParts.join('\\n\\n')}`\n : `Sync with ${failures[0].targetBranch} FAILED${hasConflicts ? ' — merge conflicts detected' : ''}:\\n\\n${summaryParts.join('\\n\\n')}`;\n\n const repoInstructions = isPolyrepo\n ? failures.map(f => {\n if (f.hasConflicts) {\n return `### ${f.repoName}/\\n1. \\`cd ${f.repoName}\\`\\n2. \\`git fetch origin ${f.targetBranch} && git merge origin/${f.targetBranch}\\`\\n3. Resolve all conflicts and commit`;\n }\n return `### ${f.repoName}/\\n1. \\`cd ${f.repoName}\\`\\n2. Investigate and fix the sync failure\\n3. Commit changes`;\n }).join('\\n\\n')\n : hasConflicts\n ? `1. Run: \\`git fetch origin ${failures[0].targetBranch} && git merge origin/${failures[0].targetBranch}\\`\\n2. Resolve all conflicts in the listed files\\n3. Run the project's build and tests to verify nothing broke\\n4. Commit and push ALL changes`\n : `1. Run: \\`git fetch origin ${failures[0].targetBranch}\\`\\n2. Run: \\`git merge origin/${failures[0].targetBranch}\\`\\n3. If git reports conflicts, resolve them and verify the merge succeeds cleanly\\n4. Run the project's build and tests to verify nothing broke\\n5. Commit and push ALL changes`;\n\n const feedbackBody = isFinalVerificationAttempt(cycleCount)\n ? `VERIFICATION STUCK for ${issueId} (attempt ${cycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: sync-target-branch\\n\\n${summary}\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId} (attempt ${cycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: sync-target-branch\\n\\n${summary}\\n\\n## REQUIRED: ${hasConflicts ? 'Resolve merge conflicts' : 'Fix the sync failure'} BEFORE resubmitting\\n\\n${isPolyrepo ? 'This is a polyrepo workspace. Fix each failing repo individually:\\n\\n' : ''}${repoInstructions}\\n\\nAfter fixing:\\n1. Run the project's build and tests\\n2. Commit and push ALL changes\\n3. ONLY THEN resubmit: pan review request ${issueId} -m \"Fixed sync-target-branch\"\\n\\nDo NOT resubmit until all repos sync cleanly and tests pass.`;\n\n return { summary, feedbackBody };\n}\n\nfunction getSyncTargetBranch(\n workspacePath: string,\n projectConfig: ReturnType<typeof findProjectByPathSync>,\n repoName?: string,\n): string {\n if (!projectConfig) return 'main';\n\n if (repoName) {\n const matchingRepo = projectConfig.workspace?.repos?.find(repo => repo.name === repoName);\n return (\n matchingRepo?.pr_target ||\n projectConfig.workspace?.pr_target ||\n matchingRepo?.default_branch ||\n projectConfig.workspace?.default_branch ||\n 'main'\n );\n }\n\n const wsName = basename(workspacePath);\n const matchingRepo = projectConfig.workspace?.repos?.find(repo =>\n repo.name === wsName || basename(repo.path) === wsName\n );\n\n return (\n matchingRepo?.pr_target ||\n projectConfig.workspace?.pr_target ||\n matchingRepo?.default_branch ||\n projectConfig.workspace?.default_branch ||\n 'main'\n );\n}\n\n/**\n * PAN-2179: detect a \"plan-only\" / zombie changeset — one whose only changes are\n * pipeline artifacts (.pan/, beads, vbrief) with no actual implementation. A work\n * agent that never received its kickoff produces exactly this. The verification\n * gate uses it to bounce the branch back instead of letting an empty \"completion\"\n * advance to review/merge. A legit non-code change (docs, rules under\n * sync-sources/, config) counts as content and is NOT flagged.\n */\nexport function changesetHasNoContent(changedFiles: readonly string[]): boolean {\n const content = changedFiles\n .map((f) => f.trim())\n .filter(Boolean)\n .filter((f) => !f.startsWith('.pan/') && !f.startsWith('.beads/') && !f.endsWith('.vbrief.json'));\n return content.length === 0;\n}\n\nasync function runVerificationForIssuePromise(\n issueId: string,\n workspacePath: string,\n workspaceInfo: WorkspaceInfo,\n logPrefix: string,\n options: VerificationRunnerOptions = {},\n): Promise<VerificationRunnerOutcome> {\n const currentStatus = getReviewStatusSync(issueId);\n const currentCycles = currentStatus?.verificationCycleCount ?? 0;\n\n if (currentCycles >= VERIFICATION_MAX_CYCLES) {\n const reason = `Circuit breaker: ${currentCycles}/${VERIFICATION_MAX_CYCLES} cycles exceeded — skipping verification`;\n console.log(`[${logPrefix}] ${reason} for ${issueId}`);\n setReviewStatusSync(issueId, { verificationStatus: 'skipped' });\n return { outcome: 'skipped', reason };\n }\n\n setReviewStatusSync(issueId, { verificationStatus: 'running' });\n console.log(`[${logPrefix}] Running verification gate for ${issueId} (attempt ${currentCycles + 1}/${VERIFICATION_MAX_CYCLES})`);\n\n try {\n const projectConfig = findProjectByPathSync(workspacePath);\n const { gitDirs, isPolyrepo } = await resolveGitDirs(workspacePath, projectConfig);\n\n // === Sync target branch ===\n if (options.syncTargetBranch !== false) {\n if (gitDirs.length === 0) {\n console.log(`[${logPrefix}] No git directories found in workspace ${workspacePath} — skipping sync`);\n } else {\n const syncResults: SyncResult[] = [];\n for (const gitDir of gitDirs) {\n const repoName = isPolyrepo ? basename(gitDir) : undefined;\n const targetBranch = getSyncTargetBranch(workspacePath, projectConfig, repoName);\n const displayName = repoName || basename(workspacePath);\n console.log(`[${logPrefix}] Syncing ${targetBranch} into ${displayName} for ${issueId}...`);\n syncResults.push(await syncSingleRepo(gitDir, targetBranch));\n }\n\n const failures = syncResults.filter(r => !r.success);\n\n if (failures.length > 0) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'sync-target-branch';\n const { summary, feedbackBody } = buildSyncFailureFeedback(issueId, failures, isPolyrepo, newCycleCount);\n\n setReviewStatusSync(issueId, {\n reviewStatus: 'pending',\n verificationStatus: 'failed',\n verificationNotes: summary,\n verificationCycleCount: newCycleCount,\n verificationMaxCycles: VERIFICATION_MAX_CYCLES,\n });\n\n if (shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `Sync FAILED${isPolyrepo ? ` in ${failures.length} repo(s)` : ''} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES})`,\n markdownBody: feedbackBody,\n }));\n if (fileResult.success) {\n const hasConflicts = failures.some(f => f.hasConflicts);\n const repoList = isPolyrepo ? failures.map(f => f.repoName).join(', ') : basename(workspacePath);\n const msg = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck}${hasConflicts ? ' — merge conflicts' : ''} in ${repoList} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nYou are paused for operator intervention. Do not re-request review automatically.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck}${hasConflicts ? ' — merge conflicts' : ''} in ${repoList}.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nUse your Read tool to open this file, read every line, fix the sync issues, commit and push every change, then request a new review with pan review request. Do NOT stop at the prompt — keep working until pan review request completes successfully.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n feedbackPath: fileResult.filePath,\n }, logPrefix);\n }\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to write sync-target feedback for ${issueId}:`, feedbackErr);\n }\n\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n\n for (const result of syncResults) {\n const displayName = isPolyrepo ? result.repoName : basename(workspacePath);\n if (result.alreadyUpToDate) {\n console.log(`[${logPrefix}] ${displayName}: Already up to date with ${result.targetBranch}`);\n } else {\n console.log(`[${logPrefix}] ${displayName}: Merged latest ${result.targetBranch}`);\n }\n }\n }\n } else {\n console.log(`[${logPrefix}] Skipping target-branch sync for ${issueId}; verifying current workspace state`);\n }\n\n // Load project-specific gates or fall back to defaults\n const gates =\n projectConfig?.quality_gates && Object.keys(projectConfig.quality_gates).length > 0\n ? projectConfig.quality_gates\n : DEFAULT_GATES;\n console.log(`[${logPrefix}] Project: ${projectConfig?.name || 'NOT FOUND'}, gates: [${Object.keys(gates).join(', ')}], workspace: ${workspacePath}`);\n\n // Build template placeholders for container name resolution\n const featureFolder = basename(workspacePath); // e.g., 'feature-min-574'\n const featureName = featureFolder.replace(/^feature-/, ''); // e.g., 'min-574'\n const projectPath = projectConfig?.path || dirname(dirname(workspacePath));\n const domain = projectConfig?.workspace?.dns?.domain || 'localhost';\n // PAN-666: the ref a changed-file-scoped gate diffs against. The gate already\n // merged this branch into the workspace above, so `origin/<target>` is the\n // pre-PR baseline; `vitest run --changed {{CHANGED_BASE}}` then runs only the\n // tests affected by the PR and ignores pre-existing failures elsewhere.\n const changedBase = `origin/${getSyncTargetBranch(workspacePath, projectConfig, undefined)}`;\n const placeholders: TemplatePlaceholders = {\n FEATURE_NAME: featureName,\n FEATURE_FOLDER: featureFolder,\n BRANCH_NAME: `feature/${featureName}`,\n COMPOSE_PROJECT: `${basename(projectPath)}-${featureFolder}`,\n DOMAIN: domain,\n PROJECT_NAME: basename(projectPath),\n PROJECT_PATH: projectPath,\n PROJECTS_DIR: dirname(projectPath),\n WORKSPACE_PATH: workspacePath,\n HOME: homedir(),\n CHANGED_BASE: changedBase,\n };\n\n // PAN-666 (AC#3): make changed-file scoping visible so humans know pre-existing\n // failures in unmodified files were not run and may be accumulating.\n if (Object.values(gates).some(g => g.command?.includes('CHANGED_BASE'))) {\n console.log(\n `[${logPrefix}] Test gate is scoped to files changed since ${changedBase} ` +\n `(PAN-666). Pre-existing failures in files this PR did not touch are NOT run — ` +\n `they may be accumulating as tech debt on the target branch.`,\n );\n }\n\n // Install dependencies for monorepo workspaces.\n // Polyrepo workspaces manage deps per-repo via quality gate commands or containers.\n if (!isPolyrepo) {\n const packageManager = projectConfig?.package_manager || 'npm';\n const installCmd = packageManager === 'bun' ? 'bun install' : `${packageManager} install`;\n try {\n console.log(`[${logPrefix}] Installing dependencies: ${installCmd}`);\n await execAsync(installCmd, { cwd: workspacePath, encoding: 'utf-8', timeout: 60000 });\n } catch (installErr: any) {\n console.warn(`[${logPrefix}] Dependency install warning: ${installErr.message}`);\n }\n\n // Build workspace packages (e.g., @overdeck/contracts) before running gates\n const workspacePackages = (projectConfig as any)?.workspace_packages as Array<{ path: string; build_command: string }> | undefined;\n if (workspacePackages) {\n for (const pkg of workspacePackages) {\n const pkgPath = join(workspacePath, pkg.path);\n try {\n console.log(`[${logPrefix}] Building workspace package: ${pkg.path}`);\n await execAsync(pkg.build_command, { cwd: pkgPath, encoding: 'utf-8', timeout: 30000 });\n } catch (buildErr: any) {\n console.warn(`[${logPrefix}] Workspace package build warning (${pkg.path}): ${buildErr.message}`);\n }\n }\n }\n } else {\n console.log(`[${logPrefix}] Polyrepo workspace — per-repo dependencies managed by quality gates`);\n }\n\n const gateResults = await Effect.runPromise(runQualityGates(gates, workspacePath, 'pre_push', {\n isRemote: workspaceInfo.isRemote,\n vmName: workspaceInfo.vmName,\n placeholders,\n ...(options.onGateLog ? { onLog: options.onGateLog } : {}),\n }));\n\n const failedGate = gateResults.find(r => !r.passed && r.required !== false);\n\n // PAN-2461: an infra-unavailable gate (container/docker missing) is NOT a code\n // failure — it must not consume a verification attempt or pause the agent.\n // Trigger stack recovery and leave verification pending for the next cycle.\n if (failedGate?.infraUnavailable) {\n console.warn(`[${logPrefix}] Gate \"${failedGate.name}\" could not run for ${issueId}: ${failedGate.error} — triggering workspace stack rebuild, attempt NOT counted (${currentCycles}/${VERIFICATION_MAX_CYCLES} used)`);\n setReviewStatusSync(issueId, {\n verificationStatus: 'pending',\n verificationNotes: `Verification deferred: ${failedGate.error}. Workspace stack rebuild triggered; verification re-runs on the next cycle.`,\n });\n try {\n const { rebuildWorkspaceStack } = await import('../workspace/rebuild-stack.js');\n void Effect.runPromise(rebuildWorkspaceStack(issueId, {\n onProgress: (m) => console.log(`[${logPrefix}] ${issueId} stack rebuild: ${m}`),\n })).then((r) => {\n if (!r.success) console.warn(`[${logPrefix}] Stack rebuild for ${issueId} failed: ${r.error}`);\n });\n } catch (err) {\n console.warn(`[${logPrefix}] Could not trigger stack rebuild for ${issueId}: ${err instanceof Error ? err.message : String(err)}`);\n }\n return { outcome: 'failed', failedCheck: failedGate.name, cycleCount: currentCycles, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n\n if (failedGate) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = failedGate.name;\n const rawOutput = failedGate.output || failedGate.error || '(no output)';\n const truncatedOutput =\n rawOutput.length > 3000 ? rawOutput.slice(0, 3000) + '\\n...(truncated)' : rawOutput;\n const summary = `Verification FAILED at ${failedCheck} (${failedGate.durationMs}ms):\\n\\n${truncatedOutput}`;\n\n setReviewStatusSync(issueId, {\n reviewStatus: 'pending',\n verificationStatus: 'failed',\n verificationNotes: summary,\n verificationCycleCount: newCycleCount,\n verificationMaxCycles: VERIFICATION_MAX_CYCLES,\n });\n\n const shouldEscalate = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount);\n\n if (shouldEscalate) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n\n const feedbackBody = shouldEscalate\n ? `VERIFICATION STUCK for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n## REQUIRED: Fix the failing check, push, and request a new review\\n\\n1. Read the error output above carefully\\n2. Fix the code causing the failure\\n3. Run the failing check locally to verify it passes\\n4. Commit every change\\n5. Invoke the /rebase-and-submit skill for ${issueId} — this is an atomic task. Because verification already ran once (a PR exists), the skill will push your branch and run \\`pan review request ${issueId} -m \"Fixed ${failedCheck}\"\\` for you. NEVER curl \\`/api/review/...\\` or any dashboard endpoint — \\`pan review request\\` is the only supported re-entry point.\\n\\nDo NOT stop between steps. Do NOT stop after pushing. Do NOT stop until \\`pan review request\\` has completed successfully.`;\n\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `Verification FAILED at ${failedCheck} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES})`,\n markdownBody: feedbackBody,\n }));\n if (fileResult.success) {\n const msg = shouldEscalate\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nYou are paused for operator intervention. Do not re-request review automatically.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck}.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nUse your Read tool to open this file, read every line, fix the failing check, commit every change, and invoke /rebase-and-submit. The skill will push and request a new review with pan review request. Do NOT stop at the prompt — keep working until pan review request completes successfully.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n feedbackPath: fileResult.filePath,\n }, logPrefix);\n }\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to write verification feedback for ${issueId}:`, feedbackErr);\n }\n\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n\n // vBRIEF AC gate: check all acceptance criteria are completed (runs after quality gates)\n // Wrap in try-catch to detect merge conflict markers in plan.vbrief.json and send\n // actionable feedback rather than falling through to a generic infrastructure error.\n let acStatus: ReturnType<typeof getVBriefACStatusSync>;\n try {\n acStatus = getVBriefACStatusSync(workspacePath);\n } catch (vbriefErr: any) {\n if (vbriefErr instanceof VBriefMergeConflictError) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'vbrief-conflicts';\n const summary = `vBRIEF spec has unresolved git merge conflict markers. Resolve all conflict markers in the spec file and commit before resubmitting.`;\n setStateDerivedVerificationFailure(issueId, failedCheck, summary, newCycleCount, currentStatus);\n if (shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n const feedbackBody = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n## REQUIRED: Fix merge conflicts in vBRIEF spec BEFORE resubmitting\\n\\n1. Open the vBRIEF spec (on main in .pan/specs/)\\n2. Find and resolve all <<<<<<< HEAD / ======= / >>>>>>> conflict markers\\n3. Ensure the file is valid JSON (only keep ONE version of each conflicted block)\\n4. Commit the fixed file on main\\n5. ONLY THEN resubmit: pan review request ${issueId} -m \"Resolved spec merge conflict\"\\n\\nDo NOT resubmit until the spec parses cleanly.`;\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `vBRIEF plan has merge conflicts (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES})`,\n markdownBody: feedbackBody,\n }));\n if (fileResult.success) {\n const msg = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nYou are paused for operator intervention. Do not re-request review automatically.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — plan.vbrief.json has merge conflict markers.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nUse your Read tool to open this file, read every line, resolve the merge conflict markers, commit and push the fix, then request a new review with pan review request. Do NOT stop at the prompt — keep working until pan review request completes successfully.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n feedbackPath: fileResult.filePath,\n }, logPrefix);\n }\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to write vBRIEF conflict feedback for ${issueId}:`, feedbackErr);\n }\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n throw vbriefErr;\n }\n if (acStatus && !acStatus.allCompleted) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'vbrief-ac';\n const incompleteList = acStatus.items\n .filter(i => i.pending > 0)\n .map(i => {\n const pendingAC = i.criteria\n .filter(ac => ac.status !== 'completed' && ac.status !== 'cancelled')\n .map(ac => ` - [ ] ${ac.title}`)\n .join('\\n');\n return `### ${i.itemTitle} (${i.pending}/${i.total} incomplete)\\n${pendingAC}`;\n })\n .join('\\n\\n');\n const summary = `Acceptance criteria check FAILED — ${acStatus.totalPending}/${acStatus.totalCount} AC incomplete:\\n\\n${incompleteList}`;\n\n setStateDerivedVerificationFailure(issueId, failedCheck, summary, newCycleCount, currentStatus);\n if (shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n\n const feedbackBody = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n## REQUIRED: Complete all acceptance criteria BEFORE resubmitting\\n\\n1. Review the incomplete AC above\\n2. Implement the missing requirements and write tests\\n3. Close every completed bead with \\`bd close\\` — AC statuses sync from closed beads automatically; never hand-edit spec files\\n4. Commit and push ALL changes\\n5. ONLY THEN resubmit: pan review request ${issueId} -m \"Completed acceptance criteria\"\\n\\nDo NOT resubmit until all AC are completed.`;\n\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `AC check FAILED — ${acStatus.totalPending}/${acStatus.totalCount} incomplete (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES})`,\n markdownBody: feedbackBody,\n }));\n if (fileResult.success) {\n const msg = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nYou are paused for operator intervention. Do not re-request review automatically.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — ${acStatus.totalPending} AC incomplete.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nUse your Read tool to open this file, read every line, complete all pending acceptance criteria, commit and push every change, then request a new review with pan review request. Do NOT stop at the prompt — keep working until pan review request completes successfully.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n feedbackPath: fileResult.filePath,\n }, logPrefix);\n }\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to write AC verification feedback for ${issueId}:`, feedbackErr);\n }\n\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n\n // PAN-2179: reject a plan-only / zombie changeset before it can reach\n // review/merge. A work agent that never got its kickoff (or did nothing)\n // leaves a branch whose only changes are pipeline artifacts (.pan/vbrief/beads);\n // lint/test/build and the AC gate all pass trivially on no code, so without\n // this guard the empty \"completion\" silently advances. Bounce it back.\n try {\n const { stdout: changedOut } = await execAsync(\n `git diff --name-only ${changedBase}...HEAD`,\n { cwd: workspacePath, encoding: 'utf-8', timeout: 15000 },\n );\n if (changesetHasNoContent(changedOut.split('\\n'))) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'empty-changeset';\n const summary = `Branch has no implementation — only pipeline artifacts (.pan/vbrief/beads) changed vs ${changedBase}. The work agent produced no code (likely a kickoff-delivery zombie — PAN-2179).`;\n setReviewStatusSync(issueId, {\n reviewStatus: 'pending',\n verificationStatus: 'failed',\n verificationNotes: summary,\n verificationCycleCount: newCycleCount,\n verificationMaxCycles: VERIFICATION_MAX_CYCLES,\n });\n if (shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n try {\n const msg = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts — branch still has no implementation.\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — your branch contains NO code (only .pan/vbrief/beads changed vs ${changedBase}).\\n\\nYou must actually implement the issue: read the plan (.pan/spec.vbrief.json + the issue body), write and commit the code, push, then run pan review request. Do NOT stop at the prompt — keep working until pan review request completes.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n changedBase,\n }, logPrefix);\n console.error(`[${logPrefix}] VERIFICATION FAILED for ${issueId}: empty-changeset (no content files vs ${changedBase})`);\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to send empty-changeset feedback for ${issueId}:`, feedbackErr);\n }\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n } catch (diffErr: any) {\n // Non-fatal: if the diff can't be computed, don't block — log and proceed.\n console.warn(`[${logPrefix}] empty-changeset guard skipped (diff failed): ${diffErr.message}`);\n }\n\n // Snapshot HEAD at verification pass time — compared with reviewedAtCommit\n // after review to skip redundant test-agent when no code changed.\n let lastVerifiedCommit: string | undefined;\n try {\n const { stdout } = await execAsync('git rev-parse HEAD', { cwd: workspacePath, encoding: 'utf-8', timeout: 5000 });\n lastVerifiedCommit = stdout.trim();\n } catch { /* non-fatal — skip optimization if we can't get HEAD */ }\n\n setReviewStatusSync(issueId, {\n verificationStatus: 'passed',\n verificationNotes: undefined,\n ...(lastVerifiedCommit ? { lastVerifiedCommit } : {}),\n });\n console.log(`[${logPrefix}] Verification passed for ${issueId}${lastVerifiedCommit ? ` (HEAD=${lastVerifiedCommit.slice(0, 8)})` : ''} — proceeding to review-agent`);\n\n // Post overdeck/tests=success so the GitHub CI test job can self-skip\n // its redundant vitest run on this exact commit. Non-fatal on failure.\n void (async () => {\n try {\n const project = findProjectByPathSync(workspacePath);\n const repo = project?.github_repo;\n if (!repo || !repo.includes('/')) return;\n const [owner, name] = repo.split('/');\n const { postOverdeckTestsStatus } = await import('../github-app.js');\n await postOverdeckTestsStatus(workspacePath, owner!, name!, 'success', 'Verification gate passed');\n } catch (err: any) {\n console.warn(`[${logPrefix}] Failed to post overdeck/tests status: ${err.message}`);\n }\n })();\n return { outcome: 'passed' };\n\n } catch (verifyErr: any) {\n setReviewStatusSync(issueId, {\n reviewStatus: 'pending',\n verificationStatus: 'failed',\n verificationNotes: `Verification infrastructure error: ${verifyErr.message}`,\n });\n console.error(`[${logPrefix}] Verification infrastructure error for ${issueId}:`, verifyErr);\n return { outcome: 'error', message: verifyErr.message };\n }\n}\n\n// ─── PAN-1249: additive Effect variant ────────────────────────────────────────\n\n/**\n * Effect-typed variant of {@link runVerificationForIssue}.\n *\n * Always succeeds — the legacy Promise already collapses every failure mode\n * into a discriminated `VerificationRunnerOutcome` union (`{ outcome: 'error' }`),\n * so the Effect error channel stays empty.\n */\nexport function runVerificationForIssue(\n issueId: string,\n workspacePath: string,\n workspaceInfo: WorkspaceInfo,\n logPrefix: string,\n options: VerificationRunnerOptions = {},\n): Effect.Effect<VerificationRunnerOutcome> {\n return Effect.promise(() => runVerificationForIssuePromise(issueId, workspacePath, workspaceInfo, logPrefix, options));\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"verification-runner-R2-4XgMO.js","names":[],"sources":["../../src/lib/cloister/verification-runner.ts"],"sourcesContent":["/**\n * Verification Runner — orchestrates the full verification gate lifecycle.\n *\n * Runs quality gates (typecheck → lint → test by default, or project-specific\n * gates from projects.yaml), updates review status, writes feedback files,\n * and notifies the work agent on failure.\n *\n * Extracted from dashboard/server to be independently testable.\n */\n\nimport { basename, dirname, join } from 'path';\nimport { homedir } from 'os';\nimport { exec } from 'child_process';\nimport { existsSync } from 'fs';\nimport { readdir } from 'fs/promises';\nimport { promisify } from 'util';\nimport { Effect } from 'effect';\nimport { getReviewStatusSync, markWorkspaceStuck, setReviewStatusSync } from '../review-status.js';\nimport { runQualityGates, DEFAULT_GATES } from './validation.js';\nimport { writeFeedbackFile } from './feedback-writer.js';\nimport { resolveIssueFeedbackTarget, surfaceIssueFeedbackNeedsYou } from './feedback-target.js';\nimport { messageAgent, setAgentPaused, stopAgent } from '../agents.js';\nimport { findProjectByPathSync } from '../projects.js';\nimport { getVBriefACStatusSync } from '../vbrief/beads.js';\nimport { VBriefMergeConflictError } from '../vbrief/io.js';\nimport type { TemplatePlaceholders } from '../workspace-config.js';\n\nconst execAsync = promisify(exec);\n\nexport const VERIFICATION_MAX_CYCLES = 3;\nconst NO_PROGRESS_REPEAT_THRESHOLD = 2;\n\nexport type VerificationRunnerOutcome =\n | { outcome: 'passed' }\n | { outcome: 'skipped'; reason: string }\n | { outcome: 'failed'; failedCheck: string; cycleCount: number; maxCycles: number }\n | { outcome: 'error'; message: string };\n\nexport interface WorkspaceInfo {\n isRemote: boolean;\n vmName?: string;\n}\n\nexport interface VerificationRunnerOptions {\n syncTargetBranch?: boolean;\n /** PAN-2487: receives human-readable gate progress lines (ship-log mirror). */\n onGateLog?: (line: string) => void;\n}\n\ninterface SyncResult {\n repoDir: string;\n repoName: string;\n targetBranch: string;\n success: boolean;\n alreadyUpToDate?: boolean;\n hasConflicts?: boolean;\n conflictLines?: string;\n errorOutput?: string;\n}\n\nfunction isFinalVerificationAttempt(cycleCount: number): boolean {\n return cycleCount >= VERIFICATION_MAX_CYCLES;\n}\n\nfunction isRepeatFailedCheck(\n status: ReturnType<typeof getReviewStatusSync> | null | undefined,\n failedCheck: string,\n): boolean {\n return (\n status?.verificationStatus === 'failed' &&\n status.verificationNotes?.startsWith(`Verification FAILED at ${failedCheck} `) === true\n );\n}\n\nfunction shouldEscalateVerificationFailure(\n status: ReturnType<typeof getReviewStatusSync> | null | undefined,\n failedCheck: string,\n cycleCount: number,\n): boolean {\n if (isFinalVerificationAttempt(cycleCount)) return true;\n return cycleCount >= NO_PROGRESS_REPEAT_THRESHOLD && isRepeatFailedCheck(status, failedCheck);\n}\n\nfunction buildFinalFailureInstructions(issueId: string): string {\n return `## NEEDS-YOU: Verification stuck\n\nThis was the final allowed verification attempt. The work agent is paused so it does not keep spending cycles on the same failing gate.\n\nAn operator needs to inspect ${issueId}, decide whether to fix-forward manually, restart the agent with new instructions, or move the issue through the normal pipeline. Do not re-request review automatically.`;\n}\n\nfunction setStateDerivedVerificationFailure(\n issueId: string,\n failedCheck: string,\n summary: string,\n cycleCount: number,\n currentStatus: ReturnType<typeof getReviewStatusSync> | null | undefined,\n): void {\n setReviewStatusSync(issueId, {\n verificationStatus: 'failed',\n verificationNotes: summary,\n verificationCycleCount: cycleCount,\n verificationMaxCycles: VERIFICATION_MAX_CYCLES,\n });\n\n if (currentStatus?.reviewStatus !== 'passed') return;\n\n markWorkspaceStuck(issueId, 'state_derived_verification_hold', {\n failedCheck,\n summary,\n reviewStatus: currentStatus.reviewStatus,\n });\n console.warn(`[verification-runner] ${issueId} review is passed but held by state-derived gate ${failedCheck}: ${summary}`);\n}\n\nasync function escalateVerificationStuck(\n issueId: string,\n failedCheck: string,\n cycleCount: number,\n summary: string,\n logPrefix: string,\n): Promise<void> {\n const agentId = `agent-${issueId.toLowerCase()}`;\n const reason = `needs-you: verification stuck after ${cycleCount}/${VERIFICATION_MAX_CYCLES} attempts (${failedCheck})`;\n\n markWorkspaceStuck(issueId, 'verification_stuck', {\n failedCheck,\n cycleCount,\n maxCycles: VERIFICATION_MAX_CYCLES,\n summary,\n });\n\n try {\n await Effect.runPromise(setAgentPaused(agentId, reason, true));\n await Effect.runPromise(stopAgent(agentId));\n console.log(`[${logPrefix}] Verification stuck for ${issueId} — paused ${agentId} and marked workspace stuck`);\n } catch (err: any) {\n console.error(`[${logPrefix}] Failed to pause ${agentId} after verification stuck:`, err);\n }\n}\n\nasync function deliverVerificationFeedback(\n issueId: string,\n message: string,\n details: Record<string, unknown>,\n logPrefix: string,\n): Promise<void> {\n const target = await resolveIssueFeedbackTarget(issueId);\n if ('agentId' in target) {\n await messageAgent(target.agentId, message);\n console.log(`[${logPrefix}] Sent verification feedback for ${issueId} to ${target.agentId}`);\n return;\n }\n\n await surfaceIssueFeedbackNeedsYou(issueId, target.reason, {\n specialist: 'verification-gate',\n ...details,\n });\n}\n\nasync function resolveGitDirs(\n workspacePath: string,\n projectConfig: ReturnType<typeof findProjectByPathSync>,\n): Promise<{ gitDirs: string[]; isPolyrepo: boolean }> {\n const isPolyrepoConfig = projectConfig?.workspace?.type === 'polyrepo';\n\n if (!isPolyrepoConfig && existsSync(join(workspacePath, '.git'))) {\n return { gitDirs: [workspacePath], isPolyrepo: false };\n }\n\n const gitDirs: string[] = [];\n try {\n const entries = await readdir(workspacePath, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory() && !entry.name.startsWith('.') && existsSync(join(workspacePath, entry.name, '.git'))) {\n gitDirs.push(join(workspacePath, entry.name));\n }\n }\n } catch {}\n\n if (gitDirs.length > 0) {\n return { gitDirs, isPolyrepo: true };\n }\n\n if (existsSync(join(workspacePath, '.git'))) {\n return { gitDirs: [workspacePath], isPolyrepo: false };\n }\n\n return { gitDirs: [], isPolyrepo: false };\n}\n\nasync function syncSingleRepo(gitDir: string, targetBranch: string): Promise<SyncResult> {\n const repoName = basename(gitDir);\n try {\n await execAsync(`git fetch origin ${targetBranch}`, { cwd: gitDir, encoding: 'utf-8', timeout: 30000 });\n const mergeResult = await execAsync(`git merge origin/${targetBranch} --no-edit`, {\n cwd: gitDir,\n encoding: 'utf-8',\n timeout: 60000,\n });\n const mergeOut = (mergeResult.stdout || '') + (mergeResult.stderr || '');\n const alreadyUpToDate = mergeOut.includes('Already up to date') || mergeOut.includes('Already up-to-date');\n return { repoDir: gitDir, repoName, targetBranch, success: true, alreadyUpToDate };\n } catch (mergeErr: any) {\n const mergeOut = (mergeErr.stdout || '') + (mergeErr.stderr || '');\n const hasConflicts = mergeOut.includes('CONFLICT') || mergeOut.includes('Merge conflict');\n\n if (hasConflicts) {\n try { await execAsync('git merge --abort', { cwd: gitDir, encoding: 'utf-8' }); } catch {}\n const conflictLines = mergeOut\n .split('\\n')\n .filter((line: string) => line.startsWith('CONFLICT'))\n .map((line: string) => line.replace(/^CONFLICT \\([^)]+\\): /, '').replace(/Merge conflict in /, ''))\n .join('\\n - ');\n return { repoDir: gitDir, repoName, targetBranch, success: false, hasConflicts: true, conflictLines };\n }\n\n const rawOutput = mergeOut || mergeErr.message || '(no output)';\n const errorOutput = rawOutput.length > 3000 ? rawOutput.slice(0, 3000) + '\\n...(truncated)' : rawOutput;\n return { repoDir: gitDir, repoName, targetBranch, success: false, errorOutput };\n }\n}\n\nfunction buildSyncFailureFeedback(\n issueId: string,\n failures: SyncResult[],\n isPolyrepo: boolean,\n cycleCount: number,\n): { summary: string; feedbackBody: string } {\n const hasConflicts = failures.some(f => f.hasConflicts);\n\n const summaryParts = failures.map(f => {\n const prefix = isPolyrepo ? `[${f.repoName}] ` : '';\n if (f.hasConflicts) {\n return `${prefix}Merge conflicts with ${f.targetBranch}:\\n - ${f.conflictLines}`;\n }\n return `${prefix}Sync with ${f.targetBranch} FAILED:\\n${f.errorOutput}`;\n });\n const summary = isPolyrepo\n ? `Sync FAILED in ${failures.length} repo(s):\\n\\n${summaryParts.join('\\n\\n')}`\n : `Sync with ${failures[0].targetBranch} FAILED${hasConflicts ? ' — merge conflicts detected' : ''}:\\n\\n${summaryParts.join('\\n\\n')}`;\n\n const repoInstructions = isPolyrepo\n ? failures.map(f => {\n if (f.hasConflicts) {\n return `### ${f.repoName}/\\n1. \\`cd ${f.repoName}\\`\\n2. \\`git fetch origin ${f.targetBranch} && git merge origin/${f.targetBranch}\\`\\n3. Resolve all conflicts and commit`;\n }\n return `### ${f.repoName}/\\n1. \\`cd ${f.repoName}\\`\\n2. Investigate and fix the sync failure\\n3. Commit changes`;\n }).join('\\n\\n')\n : hasConflicts\n ? `1. Run: \\`git fetch origin ${failures[0].targetBranch} && git merge origin/${failures[0].targetBranch}\\`\\n2. Resolve all conflicts in the listed files\\n3. Run the project's build and tests to verify nothing broke\\n4. Commit and push ALL changes`\n : `1. Run: \\`git fetch origin ${failures[0].targetBranch}\\`\\n2. Run: \\`git merge origin/${failures[0].targetBranch}\\`\\n3. If git reports conflicts, resolve them and verify the merge succeeds cleanly\\n4. Run the project's build and tests to verify nothing broke\\n5. Commit and push ALL changes`;\n\n const feedbackBody = isFinalVerificationAttempt(cycleCount)\n ? `VERIFICATION STUCK for ${issueId} (attempt ${cycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: sync-target-branch\\n\\n${summary}\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId} (attempt ${cycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: sync-target-branch\\n\\n${summary}\\n\\n## REQUIRED: ${hasConflicts ? 'Resolve merge conflicts' : 'Fix the sync failure'} BEFORE resubmitting\\n\\n${isPolyrepo ? 'This is a polyrepo workspace. Fix each failing repo individually:\\n\\n' : ''}${repoInstructions}\\n\\nAfter fixing:\\n1. Run the project's build and tests\\n2. Commit and push ALL changes\\n3. ONLY THEN resubmit: pan review request ${issueId} -m \"Fixed sync-target-branch\"\\n\\nDo NOT resubmit until all repos sync cleanly and tests pass.`;\n\n return { summary, feedbackBody };\n}\n\nfunction getSyncTargetBranch(\n workspacePath: string,\n projectConfig: ReturnType<typeof findProjectByPathSync>,\n repoName?: string,\n): string {\n if (!projectConfig) return 'main';\n\n if (repoName) {\n const matchingRepo = projectConfig.workspace?.repos?.find(repo => repo.name === repoName);\n return (\n matchingRepo?.pr_target ||\n projectConfig.workspace?.pr_target ||\n matchingRepo?.default_branch ||\n projectConfig.workspace?.default_branch ||\n 'main'\n );\n }\n\n const wsName = basename(workspacePath);\n const matchingRepo = projectConfig.workspace?.repos?.find(repo =>\n repo.name === wsName || basename(repo.path) === wsName\n );\n\n return (\n matchingRepo?.pr_target ||\n projectConfig.workspace?.pr_target ||\n matchingRepo?.default_branch ||\n projectConfig.workspace?.default_branch ||\n 'main'\n );\n}\n\n/**\n * PAN-2179: detect a \"plan-only\" / zombie changeset — one whose only changes are\n * pipeline artifacts (.pan/, beads, vbrief) with no actual implementation. A work\n * agent that never received its kickoff produces exactly this. The verification\n * gate uses it to bounce the branch back instead of letting an empty \"completion\"\n * advance to review/merge. A legit non-code change (docs, rules under\n * sync-sources/, config) counts as content and is NOT flagged.\n */\nexport function changesetHasNoContent(changedFiles: readonly string[]): boolean {\n const content = changedFiles\n .map((f) => f.trim())\n .filter(Boolean)\n .filter((f) => !f.startsWith('.pan/') && !f.startsWith('.beads/') && !f.endsWith('.vbrief.json'));\n return content.length === 0;\n}\n\nasync function runVerificationForIssuePromise(\n issueId: string,\n workspacePath: string,\n workspaceInfo: WorkspaceInfo,\n logPrefix: string,\n options: VerificationRunnerOptions = {},\n): Promise<VerificationRunnerOutcome> {\n const currentStatus = getReviewStatusSync(issueId);\n const currentCycles = currentStatus?.verificationCycleCount ?? 0;\n\n if (currentCycles >= VERIFICATION_MAX_CYCLES) {\n const reason = `Circuit breaker: ${currentCycles}/${VERIFICATION_MAX_CYCLES} cycles exceeded — skipping verification`;\n console.log(`[${logPrefix}] ${reason} for ${issueId}`);\n setReviewStatusSync(issueId, { verificationStatus: 'skipped' });\n return { outcome: 'skipped', reason };\n }\n\n setReviewStatusSync(issueId, { verificationStatus: 'running' });\n console.log(`[${logPrefix}] Running verification gate for ${issueId} (attempt ${currentCycles + 1}/${VERIFICATION_MAX_CYCLES})`);\n\n try {\n const projectConfig = findProjectByPathSync(workspacePath);\n const { gitDirs, isPolyrepo } = await resolveGitDirs(workspacePath, projectConfig);\n\n // === Sync target branch ===\n if (options.syncTargetBranch !== false) {\n if (gitDirs.length === 0) {\n console.log(`[${logPrefix}] No git directories found in workspace ${workspacePath} — skipping sync`);\n } else {\n const syncResults: SyncResult[] = [];\n for (const gitDir of gitDirs) {\n const repoName = isPolyrepo ? basename(gitDir) : undefined;\n const targetBranch = getSyncTargetBranch(workspacePath, projectConfig, repoName);\n const displayName = repoName || basename(workspacePath);\n console.log(`[${logPrefix}] Syncing ${targetBranch} into ${displayName} for ${issueId}...`);\n syncResults.push(await syncSingleRepo(gitDir, targetBranch));\n }\n\n const failures = syncResults.filter(r => !r.success);\n\n if (failures.length > 0) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'sync-target-branch';\n const { summary, feedbackBody } = buildSyncFailureFeedback(issueId, failures, isPolyrepo, newCycleCount);\n\n setReviewStatusSync(issueId, {\n reviewStatus: 'pending',\n verificationStatus: 'failed',\n verificationNotes: summary,\n verificationCycleCount: newCycleCount,\n verificationMaxCycles: VERIFICATION_MAX_CYCLES,\n });\n\n if (shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `Sync FAILED${isPolyrepo ? ` in ${failures.length} repo(s)` : ''} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES})`,\n markdownBody: feedbackBody,\n }));\n if (fileResult.success) {\n const hasConflicts = failures.some(f => f.hasConflicts);\n const repoList = isPolyrepo ? failures.map(f => f.repoName).join(', ') : basename(workspacePath);\n const msg = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck}${hasConflicts ? ' — merge conflicts' : ''} in ${repoList} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nYou are paused for operator intervention. Do not re-request review automatically.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck}${hasConflicts ? ' — merge conflicts' : ''} in ${repoList}.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nUse your Read tool to open this file, read every line, fix the sync issues, commit and push every change, then request a new review with pan review request. Do NOT stop at the prompt — keep working until pan review request completes successfully.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n feedbackPath: fileResult.filePath,\n }, logPrefix);\n }\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to write sync-target feedback for ${issueId}:`, feedbackErr);\n }\n\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n\n for (const result of syncResults) {\n const displayName = isPolyrepo ? result.repoName : basename(workspacePath);\n if (result.alreadyUpToDate) {\n console.log(`[${logPrefix}] ${displayName}: Already up to date with ${result.targetBranch}`);\n } else {\n console.log(`[${logPrefix}] ${displayName}: Merged latest ${result.targetBranch}`);\n }\n }\n }\n } else {\n console.log(`[${logPrefix}] Skipping target-branch sync for ${issueId}; verifying current workspace state`);\n }\n\n // Load project-specific gates or fall back to defaults\n const gates =\n projectConfig?.quality_gates && Object.keys(projectConfig.quality_gates).length > 0\n ? projectConfig.quality_gates\n : DEFAULT_GATES;\n console.log(`[${logPrefix}] Project: ${projectConfig?.name || 'NOT FOUND'}, gates: [${Object.keys(gates).join(', ')}], workspace: ${workspacePath}`);\n\n // Build template placeholders for container name resolution\n const featureFolder = basename(workspacePath); // e.g., 'feature-min-574'\n const featureName = featureFolder.replace(/^feature-/, ''); // e.g., 'min-574'\n const projectPath = projectConfig?.path || dirname(dirname(workspacePath));\n const domain = projectConfig?.workspace?.dns?.domain || 'localhost';\n // PAN-666: the ref a changed-file-scoped gate diffs against. The gate already\n // merged this branch into the workspace above, so `origin/<target>` is the\n // pre-PR baseline; `vitest run --changed {{CHANGED_BASE}}` then runs only the\n // tests affected by the PR and ignores pre-existing failures elsewhere.\n const changedBase = `origin/${getSyncTargetBranch(workspacePath, projectConfig, undefined)}`;\n const placeholders: TemplatePlaceholders = {\n FEATURE_NAME: featureName,\n FEATURE_FOLDER: featureFolder,\n BRANCH_NAME: `feature/${featureName}`,\n COMPOSE_PROJECT: `${basename(projectPath)}-${featureFolder}`,\n DOMAIN: domain,\n PROJECT_NAME: basename(projectPath),\n PROJECT_PATH: projectPath,\n PROJECTS_DIR: dirname(projectPath),\n WORKSPACE_PATH: workspacePath,\n HOME: homedir(),\n CHANGED_BASE: changedBase,\n };\n\n // PAN-666 (AC#3): make changed-file scoping visible so humans know pre-existing\n // failures in unmodified files were not run and may be accumulating.\n if (Object.values(gates).some(g => g.command?.includes('CHANGED_BASE'))) {\n console.log(\n `[${logPrefix}] Test gate is scoped to files changed since ${changedBase} ` +\n `(PAN-666). Pre-existing failures in files this PR did not touch are NOT run — ` +\n `they may be accumulating as tech debt on the target branch.`,\n );\n }\n\n // Install dependencies for monorepo workspaces.\n // Polyrepo workspaces manage deps per-repo via quality gate commands or containers.\n if (!isPolyrepo) {\n const packageManager = projectConfig?.package_manager || 'npm';\n const installCmd = packageManager === 'bun' ? 'bun install' : `${packageManager} install`;\n try {\n console.log(`[${logPrefix}] Installing dependencies: ${installCmd}`);\n await execAsync(installCmd, { cwd: workspacePath, encoding: 'utf-8', timeout: 60000 });\n } catch (installErr: any) {\n console.warn(`[${logPrefix}] Dependency install warning: ${installErr.message}`);\n }\n\n // Build workspace packages (e.g., @overdeck/contracts) before running gates\n const workspacePackages = (projectConfig as any)?.workspace_packages as Array<{ path: string; build_command: string }> | undefined;\n if (workspacePackages) {\n for (const pkg of workspacePackages) {\n const pkgPath = join(workspacePath, pkg.path);\n try {\n console.log(`[${logPrefix}] Building workspace package: ${pkg.path}`);\n await execAsync(pkg.build_command, { cwd: pkgPath, encoding: 'utf-8', timeout: 30000 });\n } catch (buildErr: any) {\n console.warn(`[${logPrefix}] Workspace package build warning (${pkg.path}): ${buildErr.message}`);\n }\n }\n }\n } else {\n console.log(`[${logPrefix}] Polyrepo workspace — per-repo dependencies managed by quality gates`);\n }\n\n const gateResults = await Effect.runPromise(runQualityGates(gates, workspacePath, 'pre_push', {\n isRemote: workspaceInfo.isRemote,\n vmName: workspaceInfo.vmName,\n placeholders,\n ...(options.onGateLog ? { onLog: options.onGateLog } : {}),\n }));\n\n const failedGate = gateResults.find(r => !r.passed && r.required !== false);\n\n // PAN-2461: an infra-unavailable gate (container/docker missing) is NOT a code\n // failure — it must not consume a verification attempt or pause the agent.\n // Trigger stack recovery and leave verification pending for the next cycle.\n if (failedGate?.infraUnavailable) {\n console.warn(`[${logPrefix}] Gate \"${failedGate.name}\" could not run for ${issueId}: ${failedGate.error} — triggering workspace stack rebuild, attempt NOT counted (${currentCycles}/${VERIFICATION_MAX_CYCLES} used)`);\n setReviewStatusSync(issueId, {\n verificationStatus: 'pending',\n verificationNotes: `Verification deferred: ${failedGate.error}. Workspace stack rebuild triggered; verification re-runs on the next cycle.`,\n });\n try {\n const { rebuildWorkspaceStack } = await import('../workspace/rebuild-stack.js');\n void Effect.runPromise(rebuildWorkspaceStack(issueId, {\n onProgress: (m) => console.log(`[${logPrefix}] ${issueId} stack rebuild: ${m}`),\n })).then((r) => {\n if (!r.success) console.warn(`[${logPrefix}] Stack rebuild for ${issueId} failed: ${r.error}`);\n });\n } catch (err) {\n console.warn(`[${logPrefix}] Could not trigger stack rebuild for ${issueId}: ${err instanceof Error ? err.message : String(err)}`);\n }\n return { outcome: 'failed', failedCheck: failedGate.name, cycleCount: currentCycles, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n\n if (failedGate) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = failedGate.name;\n const rawOutput = failedGate.output || failedGate.error || '(no output)';\n const truncatedOutput =\n rawOutput.length > 3000 ? rawOutput.slice(0, 3000) + '\\n...(truncated)' : rawOutput;\n const summary = `Verification FAILED at ${failedCheck} (${failedGate.durationMs}ms):\\n\\n${truncatedOutput}`;\n\n setReviewStatusSync(issueId, {\n reviewStatus: 'pending',\n verificationStatus: 'failed',\n verificationNotes: summary,\n verificationCycleCount: newCycleCount,\n verificationMaxCycles: VERIFICATION_MAX_CYCLES,\n });\n\n const shouldEscalate = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount);\n\n if (shouldEscalate) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n\n const feedbackBody = shouldEscalate\n ? `VERIFICATION STUCK for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n## REQUIRED: Fix the failing check, push, and request a new review\\n\\n1. Read the error output above carefully\\n2. Fix the code causing the failure\\n3. Run the failing check locally to verify it passes\\n4. Commit every change\\n5. Invoke the /rebase-and-submit skill for ${issueId} — this is an atomic task. Because verification already ran once (a PR exists), the skill will push your branch and run \\`pan review request ${issueId} -m \"Fixed ${failedCheck}\"\\` for you. NEVER curl \\`/api/review/...\\` or any dashboard endpoint — \\`pan review request\\` is the only supported re-entry point.\\n\\nDo NOT stop between steps. Do NOT stop after pushing. Do NOT stop until \\`pan review request\\` has completed successfully.`;\n\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `Verification FAILED at ${failedCheck} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES})`,\n markdownBody: feedbackBody,\n }));\n if (fileResult.success) {\n const msg = shouldEscalate\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nYou are paused for operator intervention. Do not re-request review automatically.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck}.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nUse your Read tool to open this file, read every line, fix the failing check, commit every change, and invoke /rebase-and-submit. The skill will push and request a new review with pan review request. Do NOT stop at the prompt — keep working until pan review request completes successfully.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n feedbackPath: fileResult.filePath,\n }, logPrefix);\n }\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to write verification feedback for ${issueId}:`, feedbackErr);\n }\n\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n\n // vBRIEF AC gate: check all acceptance criteria are completed (runs after quality gates)\n // Wrap in try-catch to detect merge conflict markers in plan.vbrief.json and send\n // actionable feedback rather than falling through to a generic infrastructure error.\n let acStatus: ReturnType<typeof getVBriefACStatusSync>;\n try {\n acStatus = getVBriefACStatusSync(workspacePath);\n } catch (vbriefErr: any) {\n if (vbriefErr instanceof VBriefMergeConflictError) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'vbrief-conflicts';\n const summary = `vBRIEF spec has unresolved git merge conflict markers. Resolve all conflict markers in the spec file and commit before resubmitting.`;\n setStateDerivedVerificationFailure(issueId, failedCheck, summary, newCycleCount, currentStatus);\n if (shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n const feedbackBody = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n## REQUIRED: Fix merge conflicts in vBRIEF spec BEFORE resubmitting\\n\\n1. Open the vBRIEF spec (on main in .pan/specs/)\\n2. Find and resolve all <<<<<<< HEAD / ======= / >>>>>>> conflict markers\\n3. Ensure the file is valid JSON (only keep ONE version of each conflicted block)\\n4. Commit the fixed file on main\\n5. ONLY THEN resubmit: pan review request ${issueId} -m \"Resolved spec merge conflict\"\\n\\nDo NOT resubmit until the spec parses cleanly.`;\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `vBRIEF plan has merge conflicts (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES})`,\n markdownBody: feedbackBody,\n }));\n if (fileResult.success) {\n const msg = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nYou are paused for operator intervention. Do not re-request review automatically.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — plan.vbrief.json has merge conflict markers.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nUse your Read tool to open this file, read every line, resolve the merge conflict markers, commit and push the fix, then request a new review with pan review request. Do NOT stop at the prompt — keep working until pan review request completes successfully.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n feedbackPath: fileResult.filePath,\n }, logPrefix);\n }\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to write vBRIEF conflict feedback for ${issueId}:`, feedbackErr);\n }\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n throw vbriefErr;\n }\n if (acStatus && !acStatus.allCompleted) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'vbrief-ac';\n const incompleteList = acStatus.items\n .filter(i => i.pending > 0)\n .map(i => {\n const pendingAC = i.criteria\n .filter(ac => ac.status !== 'completed' && ac.status !== 'cancelled')\n .map(ac => ` - [ ] ${ac.title}`)\n .join('\\n');\n return `### ${i.itemTitle} (${i.pending}/${i.total} incomplete)\\n${pendingAC}`;\n })\n .join('\\n\\n');\n const summary = `Acceptance criteria check FAILED — ${acStatus.totalPending}/${acStatus.totalCount} AC incomplete:\\n\\n${incompleteList}`;\n\n setStateDerivedVerificationFailure(issueId, failedCheck, summary, newCycleCount, currentStatus);\n if (shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n\n const feedbackBody = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId} (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES}):\\n\\nFailed check: ${failedCheck}\\n\\n${summary}\\n\\n## REQUIRED: Complete all acceptance criteria BEFORE resubmitting\\n\\n1. Review the incomplete AC above\\n2. Implement the missing requirements and write tests\\n3. Close every completed bead with \\`bd close\\` — AC statuses sync from closed beads automatically; never hand-edit spec files\\n4. Commit and push ALL changes\\n5. ONLY THEN resubmit: pan review request ${issueId} -m \"Completed acceptance criteria\"\\n\\nDo NOT resubmit until all AC are completed.`;\n\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `AC check FAILED — ${acStatus.totalPending}/${acStatus.totalCount} incomplete (attempt ${newCycleCount}/${VERIFICATION_MAX_CYCLES})`,\n markdownBody: feedbackBody,\n }));\n if (fileResult.success) {\n const msg = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nYou are paused for operator intervention. Do not re-request review automatically.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — ${acStatus.totalPending} AC incomplete.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nUse your Read tool to open this file, read every line, complete all pending acceptance criteria, commit and push every change, then request a new review with pan review request. Do NOT stop at the prompt — keep working until pan review request completes successfully.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n feedbackPath: fileResult.filePath,\n }, logPrefix);\n }\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to write AC verification feedback for ${issueId}:`, feedbackErr);\n }\n\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n\n // PAN-2179: reject a plan-only / zombie changeset before it can reach\n // review/merge. A work agent that never got its kickoff (or did nothing)\n // leaves a branch whose only changes are pipeline artifacts (.pan/vbrief/beads);\n // lint/test/build and the AC gate all pass trivially on no code, so without\n // this guard the empty \"completion\" silently advances. Bounce it back.\n try {\n const { stdout: changedOut } = await execAsync(\n `git diff --name-only ${changedBase}...HEAD`,\n { cwd: workspacePath, encoding: 'utf-8', timeout: 15000 },\n );\n if (changesetHasNoContent(changedOut.split('\\n'))) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'empty-changeset';\n const summary = `Branch has no implementation — only pipeline artifacts (.pan/vbrief/beads) changed vs ${changedBase}. The work agent produced no code (likely a kickoff-delivery zombie — PAN-2179).`;\n setReviewStatusSync(issueId, {\n reviewStatus: 'pending',\n verificationStatus: 'failed',\n verificationNotes: summary,\n verificationCycleCount: newCycleCount,\n verificationMaxCycles: VERIFICATION_MAX_CYCLES,\n });\n if (shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)) {\n await escalateVerificationStuck(issueId, failedCheck, newCycleCount, summary, logPrefix);\n }\n try {\n const msg = shouldEscalateVerificationFailure(currentStatus, failedCheck, newCycleCount)\n ? `VERIFICATION STUCK for ${issueId}.\\nFailed check: ${failedCheck} after ${newCycleCount}/${VERIFICATION_MAX_CYCLES} attempts — branch still has no implementation.\\n\\n${buildFinalFailureInstructions(issueId)}`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — your branch contains NO code (only .pan/vbrief/beads changed vs ${changedBase}).\\n\\nYou must actually implement the issue: read the plan (.pan/spec.vbrief.json + the issue body), write and commit the code, push, then run pan review request. Do NOT stop at the prompt — keep working until pan review request completes.`;\n await deliverVerificationFeedback(issueId, msg, {\n failedCheck,\n changedBase,\n }, logPrefix);\n console.error(`[${logPrefix}] VERIFICATION FAILED for ${issueId}: empty-changeset (no content files vs ${changedBase})`);\n } catch (feedbackErr: any) {\n console.error(`[${logPrefix}] Failed to send empty-changeset feedback for ${issueId}:`, feedbackErr);\n }\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n } catch (diffErr: any) {\n // Non-fatal: if the diff can't be computed, don't block — log and proceed.\n console.warn(`[${logPrefix}] empty-changeset guard skipped (diff failed): ${diffErr.message}`);\n }\n\n // Snapshot HEAD at verification pass time — compared with reviewedAtCommit\n // after review to skip redundant test-agent when no code changed.\n let lastVerifiedCommit: string | undefined;\n try {\n const { stdout } = await execAsync('git rev-parse HEAD', { cwd: workspacePath, encoding: 'utf-8', timeout: 5000 });\n lastVerifiedCommit = stdout.trim();\n } catch { /* non-fatal — skip optimization if we can't get HEAD */ }\n\n setReviewStatusSync(issueId, {\n verificationStatus: 'passed',\n verificationNotes: undefined,\n ...(lastVerifiedCommit ? { lastVerifiedCommit } : {}),\n });\n console.log(`[${logPrefix}] Verification passed for ${issueId}${lastVerifiedCommit ? ` (HEAD=${lastVerifiedCommit.slice(0, 8)})` : ''} — proceeding to review-agent`);\n\n // Post overdeck/tests=success so the GitHub CI test job can self-skip\n // its redundant vitest run on this exact commit. Non-fatal on failure.\n void (async () => {\n try {\n const project = findProjectByPathSync(workspacePath);\n const repo = project?.github_repo;\n if (!repo || !repo.includes('/')) return;\n const [owner, name] = repo.split('/');\n const { postOverdeckTestsStatus } = await import('../github-app.js');\n await postOverdeckTestsStatus(workspacePath, owner!, name!, 'success', 'Verification gate passed');\n } catch (err: any) {\n console.warn(`[${logPrefix}] Failed to post overdeck/tests status: ${err.message}`);\n }\n })();\n return { outcome: 'passed' };\n\n } catch (verifyErr: any) {\n setReviewStatusSync(issueId, {\n reviewStatus: 'pending',\n verificationStatus: 'failed',\n verificationNotes: `Verification infrastructure error: ${verifyErr.message}`,\n });\n console.error(`[${logPrefix}] Verification infrastructure error for ${issueId}:`, verifyErr);\n return { outcome: 'error', message: verifyErr.message };\n }\n}\n\n// ─── PAN-1249: additive Effect variant ────────────────────────────────────────\n\n/**\n * Effect-typed variant of {@link runVerificationForIssue}.\n *\n * Always succeeds — the legacy Promise already collapses every failure mode\n * into a discriminated `VerificationRunnerOutcome` union (`{ outcome: 'error' }`),\n * so the Effect error channel stays empty.\n */\nexport function runVerificationForIssue(\n issueId: string,\n workspacePath: string,\n workspaceInfo: WorkspaceInfo,\n logPrefix: string,\n options: VerificationRunnerOptions = {},\n): Effect.Effect<VerificationRunnerOutcome> {\n return Effect.promise(() => runVerificationForIssuePromise(issueId, workspacePath, workspaceInfo, logPrefix, options));\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { $n as extractPrefixSync, Dt as getProjectConfigFromWorkspacePath, Or as OVERDECK_HOME, Ot as init_record, Qn as extractNumberSync, Vr as init_paths, er as init_issue_id, kt as markRecordPipelineClosedOutSync } from "./config-yaml-DPAieL_G.js";
|
|
2
|
-
import { _t as init_config, vt as loadCloisterConfig } from "./agents-
|
|
2
|
+
import { _t as init_config, vt as loadCloisterConfig } from "./agents-C7V4odQ6.js";
|
|
3
3
|
import { n as recordFeatureRegistryLifecycle, t as init_feature_registry_population } from "./feature-registry-population-Dwyj9gEM.js";
|
|
4
4
|
import { i as findWorkspacePath, o as init_archive_planning, t as archivePlanning } from "./archive-planning-zTvWWHG_.js";
|
|
5
5
|
import { a as stepSkipped, i as stepOk, n as init_types, r as stepFailed, t as getLinearApiKey } from "./types-B5u3NxMl.js";
|
|
6
|
-
import { t as closeIssue } from "./close-issue-
|
|
6
|
+
import { t as closeIssue } from "./close-issue-BWf3pxn4.js";
|
|
7
7
|
import { t as pruneStoppedAgentsForIssue } from "./agent-gc-BtAzj8QN.js";
|
|
8
|
-
import { t as teardownWorkspace } from "./teardown-workspace-
|
|
8
|
+
import { t as teardownWorkspace } from "./teardown-workspace-DhA6oAIK.js";
|
|
9
9
|
import { n as init_compact_beads, t as compactBeads } from "./compact-beads-RFwdZFPA.js";
|
|
10
10
|
import { Effect } from "effect";
|
|
11
11
|
import { existsSync } from "fs";
|
|
@@ -285,7 +285,7 @@ async function verifyBranchMergedImpl(ctx) {
|
|
|
285
285
|
const branchName = `feature/${ctx.issueId.toLowerCase()}`;
|
|
286
286
|
try {
|
|
287
287
|
try {
|
|
288
|
-
const { loadReviewStatuses } = await import("./review-status-
|
|
288
|
+
const { loadReviewStatuses } = await import("./review-status-h7BXIA4z.js");
|
|
289
289
|
if (loadReviewStatuses()[ctx.issueId.toUpperCase()]?.mergeStatus === "merged") return stepOk(step, ["Merge specialist confirmed merge completed"]);
|
|
290
290
|
} catch {}
|
|
291
291
|
const { stdout: branchExists } = await execAsync(`git branch --list "${branchName}" 2>/dev/null || true`, {
|
|
@@ -488,7 +488,7 @@ async function resetIssueToTodoImpl(ctx) {
|
|
|
488
488
|
*/
|
|
489
489
|
async function resetPostMergeStateForIssue(issueId) {
|
|
490
490
|
try {
|
|
491
|
-
const { resetPostMergeState } = await import("./merge-agent-
|
|
491
|
+
const { resetPostMergeState } = await import("./merge-agent-7nBiCytp.js");
|
|
492
492
|
resetPostMergeState(issueId);
|
|
493
493
|
resetPostMergeState(issueId.toUpperCase());
|
|
494
494
|
} catch {
|
|
@@ -504,7 +504,7 @@ function clearReviewStatusStep(issueId) {
|
|
|
504
504
|
async function clearReviewStatusStepImpl(issueId) {
|
|
505
505
|
const step = "clear-review-status";
|
|
506
506
|
try {
|
|
507
|
-
const { clearReviewStatus } = await import("./review-status-
|
|
507
|
+
const { clearReviewStatus } = await import("./review-status-h7BXIA4z.js");
|
|
508
508
|
clearReviewStatus(issueId.toUpperCase());
|
|
509
509
|
return stepOk(step, ["Review status cleared"]);
|
|
510
510
|
} catch {
|
|
@@ -571,4 +571,4 @@ async function resetIssueToCanceledImpl(ctx) {
|
|
|
571
571
|
//#endregion
|
|
572
572
|
export { deepWipe as a, closeOut as i, cancelIssueWorkflow as n, resetToTodo as o, close as r, approve as t };
|
|
573
573
|
|
|
574
|
-
//# sourceMappingURL=workflows-
|
|
574
|
+
//# sourceMappingURL=workflows-CSKX5MhC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflows-H-COJ84X.js","names":[],"sources":["../../src/lib/lifecycle/workflows.ts"],"sourcesContent":["/**\n * Lifecycle workflows — Compose atomic operations into complete workflows.\n *\n * approve() — Post-merge: archive + close + teardown + compact-beads\n * close() — Simple close: close-issue + teardown\n * closeOut() — Full ceremony: verify-merged + archive + teardown + close + label + clear-status\n * deepWipe() — Destructive: teardown(deleteBranches) + delete agent state + reset issue\n */\n\nimport { existsSync } from 'fs';\nimport { copyFile, readFile, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { Effect } from 'effect';\nimport { OVERDECK_HOME } from '../paths.js';\nimport type {\n LifecycleContext,\n WorkflowResult,\n StepResult,\n ApproveOptions,\n DeepWipeOptions,\n ArchiveOptions,\n} from './types.js';\nimport { stepOk, stepSkipped, stepFailed, getLinearApiKey } from './types.js';\nimport { archivePlanning, findWorkspacePath } from './archive-planning.js';\nimport { closeIssue, type CloseIssueOptions } from './close-issue.js';\nimport { teardownWorkspace } from './teardown-workspace.js';\nimport { compactBeads } from './compact-beads.js';\nimport { loadCloisterConfig } from '../cloister/config.js';\nimport { extractNumberSync, extractPrefixSync } from '../issue-id.js';\nimport { recordFeatureRegistryLifecycle } from '../registry/feature-registry-population.js';\nimport { getProjectConfigFromWorkspacePath, markRecordPipelineClosedOutSync } from '../pan-dir/record.js';\nimport { pruneStoppedAgentsForIssue } from '../cloister/agent-gc.js';\n\nconst execAsync = promisify(exec);\n\nfunction trackerName(ctx: LifecycleContext, fallback: string): string {\n const name = ctx.tracker?.name ?? fallback;\n return name.charAt(0).toUpperCase() + name.slice(1);\n}\n\n/**\n * Build a WorkflowResult from collected steps.\n */\nfunction buildResult(\n workflow: WorkflowResult['workflow'],\n issueId: string,\n steps: StepResult[],\n startTime: number,\n): WorkflowResult {\n return {\n workflow,\n issueId,\n success: steps.every(s => s.success),\n steps,\n duration: Date.now() - startTime,\n };\n}\n\nfunction hasBlockingFailure(steps: StepResult[]): boolean {\n return steps.some(s => !s.success && !s.skipped);\n}\n\n/**\n * approve() — Post-merge lifecycle.\n */\nexport function approve(\n ctx: LifecycleContext,\n opts: ApproveOptions & CloseIssueOptions & ArchiveOptions = {},\n): Effect.Effect<WorkflowResult> {\n return Effect.gen(function* () {\n const start = Date.now();\n const allSteps: StepResult[] = [];\n\n // 1. Archive planning\n const archiveSteps = yield* archivePlanning(ctx, opts);\n allSteps.push(...archiveSteps);\n\n // If archive failed, stop — don't destroy unarchived artifacts\n const archiveFailed = archiveSteps.some(s => !s.success && !s.skipped);\n if (archiveFailed) {\n allSteps.push(stepFailed('approve:abort', 'Stopped — archiving failed, workspace preserved'));\n return buildResult('approve', ctx.issueId, allSteps, start);\n }\n\n // 2. Close issue\n const closeSteps = yield* closeIssue(ctx, {\n tracker: opts.tracker,\n comment: 'Merged to main via Overdeck lifecycle',\n applyLabel: true,\n });\n allSteps.push(...closeSteps);\n\n // 3. Teardown workspace (delete branches — merge is complete)\n const teardownSteps = yield* teardownWorkspace(ctx, { deleteBranches: true });\n allSteps.push(...teardownSteps);\n\n // 4. Compact beads (non-blocking — failure doesn't affect workflow success)\n if (!opts.skipBeadsCompaction) {\n const beadsResult = yield* compactBeads(ctx);\n allSteps.push(beadsResult);\n }\n\n // 5. Clear review status\n const clearResult = yield* clearReviewStatusStep(ctx.issueId);\n allSteps.push(clearResult);\n\n return buildResult('approve', ctx.issueId, allSteps, start);\n });\n}\n\n/**\n * close() — Simple issue close with teardown.\n */\nexport function close(\n ctx: LifecycleContext,\n opts: CloseIssueOptions = {},\n): Effect.Effect<WorkflowResult> {\n return Effect.gen(function* () {\n const start = Date.now();\n const allSteps: StepResult[] = [];\n\n // 1. Close issue\n const closeSteps = yield* closeIssue(ctx, {\n tracker: opts.tracker,\n reason: opts.reason,\n applyLabel: false,\n });\n allSteps.push(...closeSteps);\n\n // 2. Teardown workspace\n const teardownSteps = yield* teardownWorkspace(ctx);\n allSteps.push(...teardownSteps);\n\n // 3. Clear review status\n const clearResult = yield* clearReviewStatusStep(ctx.issueId);\n allSteps.push(clearResult);\n\n return buildResult('close', ctx.issueId, allSteps, start);\n });\n}\n\n/**\n * closeOut() — Full close-out ceremony.\n *\n * This is the human-gated verification and cleanup workflow.\n * Replaces the monolithic executeCloseOut() function.\n *\n * 1. Verify branch merged (hard fail if not — must pass before any cleanup)\n * 2. Move PRD + archive workspace artifacts (hard fail if archiving fails)\n * 3. Mark vBRIEF completed\n * 4. Clean up workspace (tmux, TLDR, Docker, worktree)\n * 5. Clean up agent state\n * 6. Close issue on tracker\n * 7. Apply closed-out label\n * 8. Clear review status\n */\nexport function closeOut(\n ctx: LifecycleContext,\n opts: CloseIssueOptions & ArchiveOptions = {},\n): Effect.Effect<WorkflowResult> {\n return Effect.gen(function* () {\n const start = Date.now();\n const allSteps: StepResult[] = [];\n\n // 1. Verify branch merged (hard fail — must pass before we archive or clean up)\n const mergeVerify = yield* verifyBranchMerged(ctx);\n allSteps.push(mergeVerify);\n if (!mergeVerify.success && !mergeVerify.skipped) {\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 2. Move PRD + archive workspace artifacts\n const archiveSteps = yield* archivePlanning(ctx, opts);\n allSteps.push(...archiveSteps);\n\n // Hard fail on archive failure — don't destroy unarchived artifacts\n const archiveFailed = archiveSteps.some(s => !s.success && !s.skipped);\n if (archiveFailed) {\n allSteps.push(stepFailed('close-out:abort', 'Stopped — archiving failed, workspace preserved'));\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 3. Mark the vBRIEF completed on main before teardown removes local state.\n const vbriefStep = yield* Effect.promise(() => completeVBriefStep(ctx));\n allSteps.push(vbriefStep);\n if (!vbriefStep.success && !vbriefStep.skipped) {\n allSteps.push(stepFailed('close-out:abort', 'Stopped — vBRIEF completion failed, workspace preserved'));\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 4+5. Teardown workspace + agent state\n const closeOutConfig = (yield* Effect.promise(() => Effect.runPromise(loadCloisterConfig()))).close_out;\n const teardownSteps = yield* teardownWorkspace(ctx, {\n deleteWorkspace: closeOutConfig?.remove_workspace ?? false,\n deleteBranches: closeOutConfig?.delete_feature_branch ?? false,\n });\n allSteps.push(...teardownSteps);\n if (hasBlockingFailure(teardownSteps)) {\n allSteps.push(stepFailed('close-out:abort', 'Stopped — teardown failed, tracker issue and review status preserved'));\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 6+7. Close issue + apply label\n const closeSteps = yield* closeIssue(ctx, {\n tracker: opts.tracker,\n comment: ctx.auto ? 'Closed via automatic close-out ceremony' : 'Closed via close-out ceremony',\n applyLabel: true,\n });\n allSteps.push(...closeSteps);\n if (hasBlockingFailure(closeSteps)) {\n allSteps.push(stepFailed('close-out:abort', 'Stopped — issue close failed, review status preserved'));\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 8. Mark durable pipeline terminal before clearing the DB cache.\n const markTerminal = yield* markPipelineClosedOutStep(ctx);\n allSteps.push(markTerminal);\n if (markTerminal.success) {\n const pruned = pruneStoppedAgentsForIssue(ctx.issueId);\n allSteps.push(pruned.preserved.length > 0\n ? stepSkipped('close-out:prune-agent-rows', [`WARNING: preserved live/non-stopped agents: ${pruned.preserved.join(', ')}`])\n : stepOk('close-out:prune-agent-rows', [`Pruned ${pruned.removed.length} stopped agent row(s)`]));\n }\n\n // 9. Clear review status\n const clearResult = yield* clearReviewStatusStep(ctx.issueId);\n allSteps.push(clearResult);\n\n yield* Effect.promise(() => resetPostMergeStateForIssue(ctx.issueId));\n yield* Effect.promise(() => recordFeatureRegistryLifecycle({ issueId: ctx.issueId, status: 'archived' }));\n\n return buildResult('close-out', ctx.issueId, allSteps, start);\n });\n}\n\nfunction markPipelineClosedOutStep(ctx: LifecycleContext): Effect.Effect<StepResult> {\n const step = 'close-out:mark-pipeline-terminal';\n return Effect.try({\n try: () => {\n const project = getProjectConfigFromWorkspacePath(ctx.projectPath);\n markRecordPipelineClosedOutSync(project, ctx.issueId.toUpperCase());\n return stepOk(step, ['Marked durable pipeline journal closed-out']);\n },\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepSkipped(step, [`Pipeline terminal marker failed (non-fatal): ${(err as Error).message ?? String(err)}`])),\n ),\n );\n}\n\n/**\n * deepWipe() — Destructive cleanup for abandoned workspaces.\n */\nfunction destructiveResetWorkflow(\n workflow: 'deep-wipe' | 'reset' | 'cancel',\n ctx: LifecycleContext,\n opts: DeepWipeOptions,\n resetStep: (ctx: LifecycleContext) => Effect.Effect<StepResult>,\n progressLabel: string,\n progressSuccessDetail: string,\n): Effect.Effect<WorkflowResult> {\n return Effect.gen(function* () {\n const start = Date.now();\n const allSteps: StepResult[] = [];\n const { deleteWorkspace = true, deleteBranches = true, resetIssue = true, onProgress } = opts;\n const resetContext = opts.tracker ? { ...ctx, tracker: opts.tracker } : ctx;\n\n const TOTAL_STEPS = 3 + (resetIssue ? 1 : 0);\n let stepNum = 0;\n\n const progress = (label: string, detail: string, status: 'active' | 'complete' | 'error' = 'active') => {\n onProgress?.({ step: stepNum, total: TOTAL_STEPS, label, detail, status });\n };\n\n stepNum = 1;\n\n // Preserve PRD before workspace teardown so it survives reset/cancel.\n const issueLower = ctx.issueId.toLowerCase();\n const workspacePath = findWorkspacePath(ctx.projectPath, issueLower);\n if (workspacePath && existsSync(workspacePath)) {\n const prdPath = join(workspacePath, '.pan', 'prd.md');\n if (existsSync(prdPath)) {\n yield* Effect.tryPromise({\n try: async () => {\n const activeDir = join(ctx.projectPath, 'docs', 'prds', 'active', issueLower);\n const { mkdir } = await import('fs/promises');\n await mkdir(activeDir, { recursive: true });\n await copyFile(prdPath, join(activeDir, 'prd.md'));\n },\n catch: () => null,\n }).pipe(Effect.catch(() => Effect.void));\n }\n }\n\n progress('Tearing down workspace', 'Killing agents, stopping services, removing files');\n const teardownSteps = yield* teardownWorkspace(ctx, {\n deleteWorkspace,\n deleteBranches,\n clearBeads: true,\n workspaceConfig: opts.workspaceConfig,\n projectName: opts.projectName,\n });\n allSteps.push(...teardownSteps);\n const teardownFailed = teardownSteps.some(s => !s.success && !s.skipped);\n progress('Tearing down workspace', teardownFailed ? 'Some steps failed' : 'Workspace torn down', teardownFailed ? 'error' : 'complete');\n\n stepNum = 2;\n progress('Deleting git branches', `feature/${ctx.issueId.toLowerCase()}`);\n progress('Deleting git branches', deleteBranches ? 'Branches removed' : 'Skipped', 'complete');\n\n if (resetIssue) {\n stepNum = 3;\n progress(progressLabel, `${ctx.issueId}`);\n const resetResult = yield* resetStep(resetContext);\n allSteps.push(resetResult);\n progress(progressLabel, resetResult.success ? progressSuccessDetail : (resetResult.error || 'Failed'), resetResult.success ? 'complete' : 'error');\n }\n\n stepNum = resetIssue ? 4 : 3;\n progress('Clearing review status', 'Removing specialist state');\n const clearResult = yield* clearReviewStatusStep(ctx.issueId);\n allSteps.push(clearResult);\n progress('Clearing review status', 'Review status cleared', 'complete');\n\n return buildResult(workflow, ctx.issueId, allSteps, start);\n });\n}\n\nexport function deepWipe(\n ctx: LifecycleContext,\n opts: DeepWipeOptions = {},\n): Effect.Effect<WorkflowResult> {\n return destructiveResetWorkflow(\n 'deep-wipe',\n ctx,\n opts,\n resetIssueToTodo,\n 'Resetting issue status',\n 'Issue reset to Todo',\n );\n}\n\nexport function resetToTodo(\n ctx: LifecycleContext,\n opts: DeepWipeOptions = {},\n): Effect.Effect<WorkflowResult> {\n return destructiveResetWorkflow(\n 'reset',\n ctx,\n opts,\n resetIssueToTodo,\n 'Resetting issue status',\n 'Issue reset to Todo',\n );\n}\n\nexport function cancelIssueWorkflow(\n ctx: LifecycleContext,\n opts: DeepWipeOptions = {},\n): Effect.Effect<WorkflowResult> {\n return destructiveResetWorkflow(\n 'cancel',\n ctx,\n opts,\n resetIssueToCanceled,\n 'Canceling issue',\n 'Issue moved to Canceled',\n );\n}\n\n// --- Internal helpers ---\n\nasync function completeVBriefStep(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'close-out:vbrief-completed';\n try {\n const { transitionVBriefOnMain } = await import('../vbrief/lifecycle-io.js');\n const result = await Effect.runPromise(transitionVBriefOnMain(\n ctx.projectPath,\n ctx.issueId,\n 'completed',\n 'completed',\n `scope: complete ${ctx.issueId.toUpperCase()} vBRIEF`,\n ));\n const details = [\n result.moved ? 'Updated vBRIEF lifecycle to completed' : 'vBRIEF lifecycle already completed',\n result.statusUpdated ? 'Updated plan.status to completed' : 'plan.status already completed',\n ];\n if (result.committed) details.push('Committed vBRIEF completion on main');\n return stepOk(step, details);\n } catch (err) {\n const cause = (err as { cause?: unknown }).cause ?? err;\n const message = cause instanceof Error ? cause.message : String(cause);\n if (message.includes('No vBRIEF found')) {\n return stepSkipped(step, [`No vBRIEF found for ${ctx.issueId}`]);\n }\n return stepFailed(step, `vBRIEF completion failed: ${message}`);\n }\n}\n\n/**\n * Verify feature branch is merged into main.\n */\nfunction verifyBranchMerged(ctx: LifecycleContext): Effect.Effect<StepResult> {\n return Effect.tryPromise({\n try: () => verifyBranchMergedImpl(ctx),\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepFailed('close-out:verify-merged', `Could not verify merge: ${(err as Error).message}`)),\n ),\n );\n}\n\nasync function verifyBranchMergedImpl(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'close-out:verify-merged';\n const issueLower = ctx.issueId.toLowerCase();\n const branchName = `feature/${issueLower}`;\n\n try {\n // Check review-status first — the merge specialist validates before marking merged\n try {\n const { loadReviewStatuses } = await import('../review-status.js');\n const statuses = loadReviewStatuses();\n const issueKey = ctx.issueId.toUpperCase();\n if (statuses[issueKey]?.mergeStatus === 'merged') {\n return stepOk(step, ['Merge specialist confirmed merge completed']);\n }\n } catch {\n // review-status.json may not exist, continue with git checks\n }\n\n\n // Check if branch exists locally\n const { stdout: branchExists } = await execAsync(\n `git branch --list \"${branchName}\" 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n\n if (branchExists.trim()) {\n // Use merge-base --is-ancestor: checks if the branch tip is reachable from main\n try {\n await execAsync(\n `git merge-base --is-ancestor ${branchName} main`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const remoteCheck = await verifyRemoteBranchIfPresent(ctx, branchName);\n if (remoteCheck && !remoteCheck.success) return remoteCheck;\n return stepOk(step, [\n 'All commits merged to main',\n ...(remoteCheck?.details ?? []),\n ]);\n } catch {\n // --is-ancestor fails for squash merges where the branch still exists.\n try {\n const { stdout: codeDiff } = await execAsync(\n `git diff main...${branchName} -- ':!.planning' ':!docs/prds' ':!.overdeck/prompts' 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (!codeDiff.trim()) {\n const remoteCheck = await verifyRemoteBranchIfPresent(ctx, branchName);\n if (remoteCheck && !remoteCheck.success) return remoteCheck;\n return stepOk(step, [\n 'Code changes squash-merged to main (only planning artifacts remain on branch)',\n ...(remoteCheck?.details ?? []),\n ]);\n }\n } catch {\n // diff failed — fall through to unmerged report\n }\n\n const githubMerged = await verifySquashMergedPrByBranch(ctx, branchName, branchName);\n if (githubMerged?.success) {\n const remoteCheck = await verifyRemoteBranchIfPresent(ctx, branchName);\n if (remoteCheck && !remoteCheck.success) return remoteCheck;\n return stepOk(step, [\n ...(githubMerged.details ?? []),\n ...(remoteCheck?.details ?? []),\n ]);\n }\n if (githubMerged) return githubMerged;\n\n const { stdout: unmerged } = await execAsync(\n `git log main..${branchName} --oneline 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const count = unmerged.trim() ? unmerged.trim().split('\\n').length : 0;\n\n if (ctx.github) {\n try {\n const { stdout: issueState } = await execAsync(\n `gh issue view ${ctx.github.number} --repo ${ctx.github.owner}/${ctx.github.repo} --json state --jq '.state'`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (issueState.trim().toUpperCase() === 'CLOSED') {\n return stepSkipped(step, [`Issue already closed on GitHub; ${count} unmerged commit(s) remain on ${branchName}`]);\n }\n } catch {\n // gh check failed — fall through to hard fail\n }\n }\n\n return stepFailed(step, `${count} unmerged commit(s) on ${branchName}. Merge before closing out.`);\n }\n }\n\n // Check remote\n const { stdout: remoteBranch } = await execAsync(\n `git ls-remote --heads origin \"${branchName}\" 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n\n if (remoteBranch.trim()) {\n await execAsync(`git fetch origin ${branchName}`, { cwd: ctx.projectPath }).catch(() => {});\n const remoteCheck = await verifyRemoteBranchIfPresent(ctx, branchName);\n if (remoteCheck) return remoteCheck;\n }\n\n // No branch at all — assume squash-merged and branch deleted\n return stepOk(step, ['Branch already cleaned up (squash-merged)']);\n } catch (err) {\n return stepFailed(step, `Could not verify merge: ${(err as Error).message}`);\n }\n}\n\ntype GitHubMergedPr = {\n number?: number;\n mergedAt?: string | null;\n headRefOid?: string | null;\n url?: string | null;\n};\n\nasync function verifyRemoteBranchIfPresent(\n ctx: LifecycleContext,\n branchName: string,\n): Promise<StepResult | null> {\n const step = 'close-out:verify-merged';\n const remoteRef = `origin/${branchName}`;\n\n const { stdout: remoteBranch } = await execAsync(\n `git ls-remote --heads origin \"${branchName}\" 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (!remoteBranch.trim()) return null;\n\n await execAsync(`git fetch origin ${branchName}`, { cwd: ctx.projectPath }).catch(() => {});\n\n try {\n await execAsync(\n `git merge-base --is-ancestor ${remoteRef} main`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n return stepOk(step, ['Remote branch fully merged']);\n } catch {\n // Squash-merge detection for remote branch\n try {\n const { stdout: codeDiff } = await execAsync(\n `git diff main...${remoteRef} -- ':!.planning' ':!docs/prds' ':!.overdeck/prompts' 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (!codeDiff.trim()) {\n return stepOk(step, ['Remote code changes squash-merged to main (only planning artifacts remain on branch)']);\n }\n } catch {\n // diff failed — fall through\n }\n\n const githubMerged = await verifySquashMergedPrByBranch(ctx, branchName, remoteRef);\n if (githubMerged) return githubMerged;\n\n const { stdout: remoteUnmerged } = await execAsync(\n `git log main..${remoteRef} --oneline 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const count = remoteUnmerged.trim() ? remoteUnmerged.trim().split('\\n').length : 0;\n\n if (ctx.github) {\n try {\n const { stdout: issueState } = await execAsync(\n `gh issue view ${ctx.github.number} --repo ${ctx.github.owner}/${ctx.github.repo} --json state --jq '.state'`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (issueState.trim().toUpperCase() === 'CLOSED') {\n return stepSkipped(step, [`Issue already closed on GitHub; ${count} unmerged commit(s) remain on remote ${branchName}`]);\n }\n } catch {\n // gh check failed — fall through to hard fail\n }\n }\n\n return stepFailed(step, `${count} unmerged commit(s) on remote ${branchName}.`);\n }\n}\n\nasync function verifySquashMergedPrByBranch(\n ctx: LifecycleContext,\n branchName: string,\n branchRef: string,\n): Promise<StepResult | null> {\n if (!ctx.github) return null;\n\n const step = 'close-out:verify-merged';\n const { owner, repo } = ctx.github;\n\n try {\n const { stdout: prJson } = await execAsync(\n `gh pr list --repo ${owner}/${repo} --state merged --head ${JSON.stringify(branchName)} --json number,mergedAt,headRefOid,url`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const prs = JSON.parse(prJson) as GitHubMergedPr[];\n const mergedPr = prs\n .filter((pr) => (\n typeof pr.mergedAt === 'string'\n && pr.mergedAt.length > 0\n && typeof pr.headRefOid === 'string'\n && pr.headRefOid.length > 0\n ))\n .sort((a, b) => Date.parse(String(b.mergedAt)) - Date.parse(String(a.mergedAt)))[0];\n if (!mergedPr?.headRefOid) return null;\n\n const { stdout: tipShaRaw } = await execAsync(\n `git rev-parse ${branchRef} 2>/dev/null`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const tipSha = tipShaRaw.trim();\n if (!tipSha) return null;\n\n if (tipSha === mergedPr.headRefOid) {\n const prLabel = typeof mergedPr.number === 'number' ? `PR #${mergedPr.number}` : 'GitHub PR';\n return stepOk(step, [`${prLabel} is squash-merged and ${branchRef} matches the merged PR head`]);\n }\n\n // PAN-2406 / state-plane policy rule 3: commits after the merged head that\n // touch ONLY state-plane paths (.pan/, .beads/) are pipeline exhaust —\n // e.g. 'chore: record merge status' — and must not block close-out.\n try {\n const { stdout: deltaRaw } = await execAsync(\n `git diff --name-only ${mergedPr.headRefOid}..${tipSha}`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n let deltaFiles = deltaRaw.split('\\n').map((f) => f.trim()).filter(Boolean);\n let statePlaneOnly = deltaFiles.length > 0 && deltaFiles.every((f) =>\n f.startsWith('.pan/') || f.startsWith('.beads/'));\n if (!statePlaneOnly) {\n // Branch may have merged main INTO itself after the PR merged — the\n // two-dot delta then contains main's own files. Judge only changes\n // UNIQUE to the branch (three-dot vs origin/main): if those are\n // state-plane-only, everything real is already on main.\n const { stdout: uniqueRaw } = await execAsync(\n `git diff --name-only origin/main...${tipSha}`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n deltaFiles = uniqueRaw.split('\\n').map((f) => f.trim()).filter(Boolean);\n statePlaneOnly = deltaFiles.every((f) =>\n f.startsWith('.pan/') || f.startsWith('.beads/'));\n }\n if (statePlaneOnly) {\n const prLabel = typeof mergedPr.number === 'number' ? `PR #${mergedPr.number}` : 'GitHub PR';\n return stepOk(step, [\n `${prLabel} is squash-merged; ${branchRef} is ahead only by state-plane commits (${deltaFiles.length} file(s): .pan/.beads) — accepted per state-plane policy`,\n ]);\n }\n } catch { /* diff failure falls through to the strict rejection below */ }\n\n const prLabel = typeof mergedPr.number === 'number' ? `PR #${mergedPr.number}` : 'merged GitHub PR';\n return stepFailed(step, `${branchRef} does not match the head commit of merged ${prLabel}; inspect before closing out.`);\n } catch {\n return null;\n }\n}\n\n/**\n * Reset issue back to open/backlog state (for destructive reset).\n */\nfunction resetIssueToTodo(ctx: LifecycleContext): Effect.Effect<StepResult> {\n return Effect.tryPromise({\n try: () => resetIssueToTodoImpl(ctx),\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepFailed('reset:reset-issue', `Failed to reset issue: ${(err as Error).message}`)),\n ),\n );\n}\n\nasync function resetIssueToTodoImpl(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'reset:reset-issue';\n try {\n if (ctx.github) {\n const { owner, repo, number } = ctx.github;\n // Reopen the issue\n await execAsync(\n `gh issue reopen ${number} --repo ${owner}/${repo}`,\n { encoding: 'utf-8' },\n ).catch(() => {}); // May already be open\n // Remove lifecycle labels\n const labelsToRemove = ['in-review', 'in-progress', 'planned', 'planning', 'Review: Approved', 'Review: Failed', 'ready-for-merge'];\n for (const label of labelsToRemove) {\n await execAsync(\n `gh issue edit ${number} --repo ${owner}/${repo} --remove-label \"${label}\"`,\n { encoding: 'utf-8' },\n ).catch(() => {}); // Label may not exist\n }\n return stepOk(step, [`Reset GitHub issue #${number}: reopened and cleared labels`]);\n }\n\n // Linear: reopen to Todo\n const linearApiKey = await getLinearApiKey();\n if (linearApiKey) {\n const { LinearClient } = await import('@linear/sdk');\n const client = new LinearClient({ apiKey: linearApiKey });\n const issueNum = extractNumberSync(ctx.issueId);\n const teamKey = extractPrefixSync(ctx.issueId);\n if (issueNum === null || teamKey === null) {\n return stepFailed(step, `Could not parse issue ID: ${ctx.issueId}`);\n }\n const results = await client.issues({\n filter: {\n number: { eq: issueNum },\n team: { key: { eq: teamKey } },\n },\n first: 1,\n });\n if (results.nodes.length > 0) {\n const issue = results.nodes[0];\n const team = await issue.team;\n if (team) {\n const states = await team.states();\n const todoState = states.nodes.find(s => s.type === 'unstarted' && s.name === 'Todo') ||\n states.nodes.find(s => s.type === 'unstarted');\n if (todoState) {\n await issue.update({ stateId: todoState.id });\n }\n }\n }\n return stepOk(step, [`Reset ${trackerName(ctx, 'linear')} issue ${ctx.issueId} to Todo`]);\n }\n\n return stepSkipped(step, ['No tracker available to reset issue']);\n } catch (err) {\n return stepFailed(step, `Failed to reset issue: ${(err as Error).message}`);\n }\n}\n\n/**\n * Clear review status for an issue.\n */\nasync function resetPostMergeStateForIssue(issueId: string): Promise<void> {\n try {\n const { resetPostMergeState } = await import('../cloister/merge-agent.js');\n resetPostMergeState(issueId);\n resetPostMergeState(issueId.toUpperCase());\n } catch {\n return;\n }\n}\n\nfunction clearReviewStatusStep(issueId: string): Effect.Effect<StepResult> {\n return Effect.tryPromise({\n try: () => clearReviewStatusStepImpl(issueId),\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepSkipped('clear-review-status', [`Failed to clear review status (non-fatal): ${(err as Error).message}`])),\n ),\n );\n}\n\nasync function clearReviewStatusStepImpl(issueId: string): Promise<StepResult> {\n const step = 'clear-review-status';\n try {\n const { clearReviewStatus } = await import('../review-status.js');\n clearReviewStatus(issueId.toUpperCase());\n return stepOk(step, ['Review status cleared']);\n } catch {\n // Fallback: direct file manipulation\n try {\n const statusFile = join(OVERDECK_HOME, 'review-status.json');\n if (existsSync(statusFile)) {\n const data = JSON.parse(await readFile(statusFile, 'utf-8'));\n const upperKey = issueId.toUpperCase();\n if (data[upperKey]) {\n delete data[upperKey];\n await writeFile(statusFile, JSON.stringify(data, null, 2));\n }\n }\n return stepOk(step, ['Review status cleared (direct)']);\n } catch (innerErr) {\n return stepSkipped(step, [`Failed to clear review status (non-fatal): ${(innerErr as Error).message}`]);\n }\n }\n}\n\nexport const __testInternals = {\n completeVBriefStep,\n verifyBranchMerged,\n};\n\nfunction resetIssueToCanceled(ctx: LifecycleContext): Effect.Effect<StepResult> {\n return Effect.tryPromise({\n try: () => resetIssueToCanceledImpl(ctx),\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepFailed('cancel:reset-issue', `Failed to cancel issue: ${(err as Error).message}`)),\n ),\n );\n}\n\nasync function resetIssueToCanceledImpl(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'cancel:reset-issue';\n try {\n if (ctx.github) {\n const { owner, repo, number } = ctx.github;\n await execAsync(\n `gh issue edit ${number} --repo ${owner}/${repo} --add-label \"wontfix\"`,\n { encoding: 'utf-8' },\n ).catch(() => {});\n return stepOk(step, [`Marked GitHub issue #${number} as canceled/wontfix`]);\n }\n\n const linearApiKey = await getLinearApiKey();\n if (linearApiKey) {\n const { LinearClient } = await import('@linear/sdk');\n const client = new LinearClient({ apiKey: linearApiKey });\n const issueNum = extractNumberSync(ctx.issueId);\n const teamKey = extractPrefixSync(ctx.issueId);\n if (issueNum === null || teamKey === null) {\n return stepFailed(step, `Could not parse issue ID: ${ctx.issueId}`);\n }\n const results = await client.issues({\n filter: {\n number: { eq: issueNum },\n team: { key: { eq: teamKey } },\n },\n first: 1,\n });\n if (results.nodes.length > 0) {\n const issue = results.nodes[0];\n const team = await issue.team;\n if (team) {\n const states = await team.states();\n const canceledState = states.nodes.find(s => s.type === 'canceled') ||\n states.nodes.find(s => s.name.toLowerCase() === 'canceled');\n if (canceledState) {\n await issue.update({ stateId: canceledState.id });\n }\n }\n }\n return stepOk(step, [`Reset ${trackerName(ctx, 'linear')} issue ${ctx.issueId} to Canceled`]);\n }\n\n return stepSkipped(step, ['No tracker available to cancel issue']);\n } catch (err) {\n return stepFailed(step, `Failed to cancel issue: ${(err as Error).message}`);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"workflows-CSKX5MhC.js","names":[],"sources":["../../src/lib/lifecycle/workflows.ts"],"sourcesContent":["/**\n * Lifecycle workflows — Compose atomic operations into complete workflows.\n *\n * approve() — Post-merge: archive + close + teardown + compact-beads\n * close() — Simple close: close-issue + teardown\n * closeOut() — Full ceremony: verify-merged + archive + teardown + close + label + clear-status\n * deepWipe() — Destructive: teardown(deleteBranches) + delete agent state + reset issue\n */\n\nimport { existsSync } from 'fs';\nimport { copyFile, readFile, writeFile } from 'fs/promises';\nimport { join } from 'path';\nimport { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { Effect } from 'effect';\nimport { OVERDECK_HOME } from '../paths.js';\nimport type {\n LifecycleContext,\n WorkflowResult,\n StepResult,\n ApproveOptions,\n DeepWipeOptions,\n ArchiveOptions,\n} from './types.js';\nimport { stepOk, stepSkipped, stepFailed, getLinearApiKey } from './types.js';\nimport { archivePlanning, findWorkspacePath } from './archive-planning.js';\nimport { closeIssue, type CloseIssueOptions } from './close-issue.js';\nimport { teardownWorkspace } from './teardown-workspace.js';\nimport { compactBeads } from './compact-beads.js';\nimport { loadCloisterConfig } from '../cloister/config.js';\nimport { extractNumberSync, extractPrefixSync } from '../issue-id.js';\nimport { recordFeatureRegistryLifecycle } from '../registry/feature-registry-population.js';\nimport { getProjectConfigFromWorkspacePath, markRecordPipelineClosedOutSync } from '../pan-dir/record.js';\nimport { pruneStoppedAgentsForIssue } from '../cloister/agent-gc.js';\n\nconst execAsync = promisify(exec);\n\nfunction trackerName(ctx: LifecycleContext, fallback: string): string {\n const name = ctx.tracker?.name ?? fallback;\n return name.charAt(0).toUpperCase() + name.slice(1);\n}\n\n/**\n * Build a WorkflowResult from collected steps.\n */\nfunction buildResult(\n workflow: WorkflowResult['workflow'],\n issueId: string,\n steps: StepResult[],\n startTime: number,\n): WorkflowResult {\n return {\n workflow,\n issueId,\n success: steps.every(s => s.success),\n steps,\n duration: Date.now() - startTime,\n };\n}\n\nfunction hasBlockingFailure(steps: StepResult[]): boolean {\n return steps.some(s => !s.success && !s.skipped);\n}\n\n/**\n * approve() — Post-merge lifecycle.\n */\nexport function approve(\n ctx: LifecycleContext,\n opts: ApproveOptions & CloseIssueOptions & ArchiveOptions = {},\n): Effect.Effect<WorkflowResult> {\n return Effect.gen(function* () {\n const start = Date.now();\n const allSteps: StepResult[] = [];\n\n // 1. Archive planning\n const archiveSteps = yield* archivePlanning(ctx, opts);\n allSteps.push(...archiveSteps);\n\n // If archive failed, stop — don't destroy unarchived artifacts\n const archiveFailed = archiveSteps.some(s => !s.success && !s.skipped);\n if (archiveFailed) {\n allSteps.push(stepFailed('approve:abort', 'Stopped — archiving failed, workspace preserved'));\n return buildResult('approve', ctx.issueId, allSteps, start);\n }\n\n // 2. Close issue\n const closeSteps = yield* closeIssue(ctx, {\n tracker: opts.tracker,\n comment: 'Merged to main via Overdeck lifecycle',\n applyLabel: true,\n });\n allSteps.push(...closeSteps);\n\n // 3. Teardown workspace (delete branches — merge is complete)\n const teardownSteps = yield* teardownWorkspace(ctx, { deleteBranches: true });\n allSteps.push(...teardownSteps);\n\n // 4. Compact beads (non-blocking — failure doesn't affect workflow success)\n if (!opts.skipBeadsCompaction) {\n const beadsResult = yield* compactBeads(ctx);\n allSteps.push(beadsResult);\n }\n\n // 5. Clear review status\n const clearResult = yield* clearReviewStatusStep(ctx.issueId);\n allSteps.push(clearResult);\n\n return buildResult('approve', ctx.issueId, allSteps, start);\n });\n}\n\n/**\n * close() — Simple issue close with teardown.\n */\nexport function close(\n ctx: LifecycleContext,\n opts: CloseIssueOptions = {},\n): Effect.Effect<WorkflowResult> {\n return Effect.gen(function* () {\n const start = Date.now();\n const allSteps: StepResult[] = [];\n\n // 1. Close issue\n const closeSteps = yield* closeIssue(ctx, {\n tracker: opts.tracker,\n reason: opts.reason,\n applyLabel: false,\n });\n allSteps.push(...closeSteps);\n\n // 2. Teardown workspace\n const teardownSteps = yield* teardownWorkspace(ctx);\n allSteps.push(...teardownSteps);\n\n // 3. Clear review status\n const clearResult = yield* clearReviewStatusStep(ctx.issueId);\n allSteps.push(clearResult);\n\n return buildResult('close', ctx.issueId, allSteps, start);\n });\n}\n\n/**\n * closeOut() — Full close-out ceremony.\n *\n * This is the human-gated verification and cleanup workflow.\n * Replaces the monolithic executeCloseOut() function.\n *\n * 1. Verify branch merged (hard fail if not — must pass before any cleanup)\n * 2. Move PRD + archive workspace artifacts (hard fail if archiving fails)\n * 3. Mark vBRIEF completed\n * 4. Clean up workspace (tmux, TLDR, Docker, worktree)\n * 5. Clean up agent state\n * 6. Close issue on tracker\n * 7. Apply closed-out label\n * 8. Clear review status\n */\nexport function closeOut(\n ctx: LifecycleContext,\n opts: CloseIssueOptions & ArchiveOptions = {},\n): Effect.Effect<WorkflowResult> {\n return Effect.gen(function* () {\n const start = Date.now();\n const allSteps: StepResult[] = [];\n\n // 1. Verify branch merged (hard fail — must pass before we archive or clean up)\n const mergeVerify = yield* verifyBranchMerged(ctx);\n allSteps.push(mergeVerify);\n if (!mergeVerify.success && !mergeVerify.skipped) {\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 2. Move PRD + archive workspace artifacts\n const archiveSteps = yield* archivePlanning(ctx, opts);\n allSteps.push(...archiveSteps);\n\n // Hard fail on archive failure — don't destroy unarchived artifacts\n const archiveFailed = archiveSteps.some(s => !s.success && !s.skipped);\n if (archiveFailed) {\n allSteps.push(stepFailed('close-out:abort', 'Stopped — archiving failed, workspace preserved'));\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 3. Mark the vBRIEF completed on main before teardown removes local state.\n const vbriefStep = yield* Effect.promise(() => completeVBriefStep(ctx));\n allSteps.push(vbriefStep);\n if (!vbriefStep.success && !vbriefStep.skipped) {\n allSteps.push(stepFailed('close-out:abort', 'Stopped — vBRIEF completion failed, workspace preserved'));\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 4+5. Teardown workspace + agent state\n const closeOutConfig = (yield* Effect.promise(() => Effect.runPromise(loadCloisterConfig()))).close_out;\n const teardownSteps = yield* teardownWorkspace(ctx, {\n deleteWorkspace: closeOutConfig?.remove_workspace ?? false,\n deleteBranches: closeOutConfig?.delete_feature_branch ?? false,\n });\n allSteps.push(...teardownSteps);\n if (hasBlockingFailure(teardownSteps)) {\n allSteps.push(stepFailed('close-out:abort', 'Stopped — teardown failed, tracker issue and review status preserved'));\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 6+7. Close issue + apply label\n const closeSteps = yield* closeIssue(ctx, {\n tracker: opts.tracker,\n comment: ctx.auto ? 'Closed via automatic close-out ceremony' : 'Closed via close-out ceremony',\n applyLabel: true,\n });\n allSteps.push(...closeSteps);\n if (hasBlockingFailure(closeSteps)) {\n allSteps.push(stepFailed('close-out:abort', 'Stopped — issue close failed, review status preserved'));\n return buildResult('close-out', ctx.issueId, allSteps, start);\n }\n\n // 8. Mark durable pipeline terminal before clearing the DB cache.\n const markTerminal = yield* markPipelineClosedOutStep(ctx);\n allSteps.push(markTerminal);\n if (markTerminal.success) {\n const pruned = pruneStoppedAgentsForIssue(ctx.issueId);\n allSteps.push(pruned.preserved.length > 0\n ? stepSkipped('close-out:prune-agent-rows', [`WARNING: preserved live/non-stopped agents: ${pruned.preserved.join(', ')}`])\n : stepOk('close-out:prune-agent-rows', [`Pruned ${pruned.removed.length} stopped agent row(s)`]));\n }\n\n // 9. Clear review status\n const clearResult = yield* clearReviewStatusStep(ctx.issueId);\n allSteps.push(clearResult);\n\n yield* Effect.promise(() => resetPostMergeStateForIssue(ctx.issueId));\n yield* Effect.promise(() => recordFeatureRegistryLifecycle({ issueId: ctx.issueId, status: 'archived' }));\n\n return buildResult('close-out', ctx.issueId, allSteps, start);\n });\n}\n\nfunction markPipelineClosedOutStep(ctx: LifecycleContext): Effect.Effect<StepResult> {\n const step = 'close-out:mark-pipeline-terminal';\n return Effect.try({\n try: () => {\n const project = getProjectConfigFromWorkspacePath(ctx.projectPath);\n markRecordPipelineClosedOutSync(project, ctx.issueId.toUpperCase());\n return stepOk(step, ['Marked durable pipeline journal closed-out']);\n },\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepSkipped(step, [`Pipeline terminal marker failed (non-fatal): ${(err as Error).message ?? String(err)}`])),\n ),\n );\n}\n\n/**\n * deepWipe() — Destructive cleanup for abandoned workspaces.\n */\nfunction destructiveResetWorkflow(\n workflow: 'deep-wipe' | 'reset' | 'cancel',\n ctx: LifecycleContext,\n opts: DeepWipeOptions,\n resetStep: (ctx: LifecycleContext) => Effect.Effect<StepResult>,\n progressLabel: string,\n progressSuccessDetail: string,\n): Effect.Effect<WorkflowResult> {\n return Effect.gen(function* () {\n const start = Date.now();\n const allSteps: StepResult[] = [];\n const { deleteWorkspace = true, deleteBranches = true, resetIssue = true, onProgress } = opts;\n const resetContext = opts.tracker ? { ...ctx, tracker: opts.tracker } : ctx;\n\n const TOTAL_STEPS = 3 + (resetIssue ? 1 : 0);\n let stepNum = 0;\n\n const progress = (label: string, detail: string, status: 'active' | 'complete' | 'error' = 'active') => {\n onProgress?.({ step: stepNum, total: TOTAL_STEPS, label, detail, status });\n };\n\n stepNum = 1;\n\n // Preserve PRD before workspace teardown so it survives reset/cancel.\n const issueLower = ctx.issueId.toLowerCase();\n const workspacePath = findWorkspacePath(ctx.projectPath, issueLower);\n if (workspacePath && existsSync(workspacePath)) {\n const prdPath = join(workspacePath, '.pan', 'prd.md');\n if (existsSync(prdPath)) {\n yield* Effect.tryPromise({\n try: async () => {\n const activeDir = join(ctx.projectPath, 'docs', 'prds', 'active', issueLower);\n const { mkdir } = await import('fs/promises');\n await mkdir(activeDir, { recursive: true });\n await copyFile(prdPath, join(activeDir, 'prd.md'));\n },\n catch: () => null,\n }).pipe(Effect.catch(() => Effect.void));\n }\n }\n\n progress('Tearing down workspace', 'Killing agents, stopping services, removing files');\n const teardownSteps = yield* teardownWorkspace(ctx, {\n deleteWorkspace,\n deleteBranches,\n clearBeads: true,\n workspaceConfig: opts.workspaceConfig,\n projectName: opts.projectName,\n });\n allSteps.push(...teardownSteps);\n const teardownFailed = teardownSteps.some(s => !s.success && !s.skipped);\n progress('Tearing down workspace', teardownFailed ? 'Some steps failed' : 'Workspace torn down', teardownFailed ? 'error' : 'complete');\n\n stepNum = 2;\n progress('Deleting git branches', `feature/${ctx.issueId.toLowerCase()}`);\n progress('Deleting git branches', deleteBranches ? 'Branches removed' : 'Skipped', 'complete');\n\n if (resetIssue) {\n stepNum = 3;\n progress(progressLabel, `${ctx.issueId}`);\n const resetResult = yield* resetStep(resetContext);\n allSteps.push(resetResult);\n progress(progressLabel, resetResult.success ? progressSuccessDetail : (resetResult.error || 'Failed'), resetResult.success ? 'complete' : 'error');\n }\n\n stepNum = resetIssue ? 4 : 3;\n progress('Clearing review status', 'Removing specialist state');\n const clearResult = yield* clearReviewStatusStep(ctx.issueId);\n allSteps.push(clearResult);\n progress('Clearing review status', 'Review status cleared', 'complete');\n\n return buildResult(workflow, ctx.issueId, allSteps, start);\n });\n}\n\nexport function deepWipe(\n ctx: LifecycleContext,\n opts: DeepWipeOptions = {},\n): Effect.Effect<WorkflowResult> {\n return destructiveResetWorkflow(\n 'deep-wipe',\n ctx,\n opts,\n resetIssueToTodo,\n 'Resetting issue status',\n 'Issue reset to Todo',\n );\n}\n\nexport function resetToTodo(\n ctx: LifecycleContext,\n opts: DeepWipeOptions = {},\n): Effect.Effect<WorkflowResult> {\n return destructiveResetWorkflow(\n 'reset',\n ctx,\n opts,\n resetIssueToTodo,\n 'Resetting issue status',\n 'Issue reset to Todo',\n );\n}\n\nexport function cancelIssueWorkflow(\n ctx: LifecycleContext,\n opts: DeepWipeOptions = {},\n): Effect.Effect<WorkflowResult> {\n return destructiveResetWorkflow(\n 'cancel',\n ctx,\n opts,\n resetIssueToCanceled,\n 'Canceling issue',\n 'Issue moved to Canceled',\n );\n}\n\n// --- Internal helpers ---\n\nasync function completeVBriefStep(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'close-out:vbrief-completed';\n try {\n const { transitionVBriefOnMain } = await import('../vbrief/lifecycle-io.js');\n const result = await Effect.runPromise(transitionVBriefOnMain(\n ctx.projectPath,\n ctx.issueId,\n 'completed',\n 'completed',\n `scope: complete ${ctx.issueId.toUpperCase()} vBRIEF`,\n ));\n const details = [\n result.moved ? 'Updated vBRIEF lifecycle to completed' : 'vBRIEF lifecycle already completed',\n result.statusUpdated ? 'Updated plan.status to completed' : 'plan.status already completed',\n ];\n if (result.committed) details.push('Committed vBRIEF completion on main');\n return stepOk(step, details);\n } catch (err) {\n const cause = (err as { cause?: unknown }).cause ?? err;\n const message = cause instanceof Error ? cause.message : String(cause);\n if (message.includes('No vBRIEF found')) {\n return stepSkipped(step, [`No vBRIEF found for ${ctx.issueId}`]);\n }\n return stepFailed(step, `vBRIEF completion failed: ${message}`);\n }\n}\n\n/**\n * Verify feature branch is merged into main.\n */\nfunction verifyBranchMerged(ctx: LifecycleContext): Effect.Effect<StepResult> {\n return Effect.tryPromise({\n try: () => verifyBranchMergedImpl(ctx),\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepFailed('close-out:verify-merged', `Could not verify merge: ${(err as Error).message}`)),\n ),\n );\n}\n\nasync function verifyBranchMergedImpl(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'close-out:verify-merged';\n const issueLower = ctx.issueId.toLowerCase();\n const branchName = `feature/${issueLower}`;\n\n try {\n // Check review-status first — the merge specialist validates before marking merged\n try {\n const { loadReviewStatuses } = await import('../review-status.js');\n const statuses = loadReviewStatuses();\n const issueKey = ctx.issueId.toUpperCase();\n if (statuses[issueKey]?.mergeStatus === 'merged') {\n return stepOk(step, ['Merge specialist confirmed merge completed']);\n }\n } catch {\n // review-status.json may not exist, continue with git checks\n }\n\n\n // Check if branch exists locally\n const { stdout: branchExists } = await execAsync(\n `git branch --list \"${branchName}\" 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n\n if (branchExists.trim()) {\n // Use merge-base --is-ancestor: checks if the branch tip is reachable from main\n try {\n await execAsync(\n `git merge-base --is-ancestor ${branchName} main`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const remoteCheck = await verifyRemoteBranchIfPresent(ctx, branchName);\n if (remoteCheck && !remoteCheck.success) return remoteCheck;\n return stepOk(step, [\n 'All commits merged to main',\n ...(remoteCheck?.details ?? []),\n ]);\n } catch {\n // --is-ancestor fails for squash merges where the branch still exists.\n try {\n const { stdout: codeDiff } = await execAsync(\n `git diff main...${branchName} -- ':!.planning' ':!docs/prds' ':!.overdeck/prompts' 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (!codeDiff.trim()) {\n const remoteCheck = await verifyRemoteBranchIfPresent(ctx, branchName);\n if (remoteCheck && !remoteCheck.success) return remoteCheck;\n return stepOk(step, [\n 'Code changes squash-merged to main (only planning artifacts remain on branch)',\n ...(remoteCheck?.details ?? []),\n ]);\n }\n } catch {\n // diff failed — fall through to unmerged report\n }\n\n const githubMerged = await verifySquashMergedPrByBranch(ctx, branchName, branchName);\n if (githubMerged?.success) {\n const remoteCheck = await verifyRemoteBranchIfPresent(ctx, branchName);\n if (remoteCheck && !remoteCheck.success) return remoteCheck;\n return stepOk(step, [\n ...(githubMerged.details ?? []),\n ...(remoteCheck?.details ?? []),\n ]);\n }\n if (githubMerged) return githubMerged;\n\n const { stdout: unmerged } = await execAsync(\n `git log main..${branchName} --oneline 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const count = unmerged.trim() ? unmerged.trim().split('\\n').length : 0;\n\n if (ctx.github) {\n try {\n const { stdout: issueState } = await execAsync(\n `gh issue view ${ctx.github.number} --repo ${ctx.github.owner}/${ctx.github.repo} --json state --jq '.state'`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (issueState.trim().toUpperCase() === 'CLOSED') {\n return stepSkipped(step, [`Issue already closed on GitHub; ${count} unmerged commit(s) remain on ${branchName}`]);\n }\n } catch {\n // gh check failed — fall through to hard fail\n }\n }\n\n return stepFailed(step, `${count} unmerged commit(s) on ${branchName}. Merge before closing out.`);\n }\n }\n\n // Check remote\n const { stdout: remoteBranch } = await execAsync(\n `git ls-remote --heads origin \"${branchName}\" 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n\n if (remoteBranch.trim()) {\n await execAsync(`git fetch origin ${branchName}`, { cwd: ctx.projectPath }).catch(() => {});\n const remoteCheck = await verifyRemoteBranchIfPresent(ctx, branchName);\n if (remoteCheck) return remoteCheck;\n }\n\n // No branch at all — assume squash-merged and branch deleted\n return stepOk(step, ['Branch already cleaned up (squash-merged)']);\n } catch (err) {\n return stepFailed(step, `Could not verify merge: ${(err as Error).message}`);\n }\n}\n\ntype GitHubMergedPr = {\n number?: number;\n mergedAt?: string | null;\n headRefOid?: string | null;\n url?: string | null;\n};\n\nasync function verifyRemoteBranchIfPresent(\n ctx: LifecycleContext,\n branchName: string,\n): Promise<StepResult | null> {\n const step = 'close-out:verify-merged';\n const remoteRef = `origin/${branchName}`;\n\n const { stdout: remoteBranch } = await execAsync(\n `git ls-remote --heads origin \"${branchName}\" 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (!remoteBranch.trim()) return null;\n\n await execAsync(`git fetch origin ${branchName}`, { cwd: ctx.projectPath }).catch(() => {});\n\n try {\n await execAsync(\n `git merge-base --is-ancestor ${remoteRef} main`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n return stepOk(step, ['Remote branch fully merged']);\n } catch {\n // Squash-merge detection for remote branch\n try {\n const { stdout: codeDiff } = await execAsync(\n `git diff main...${remoteRef} -- ':!.planning' ':!docs/prds' ':!.overdeck/prompts' 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (!codeDiff.trim()) {\n return stepOk(step, ['Remote code changes squash-merged to main (only planning artifacts remain on branch)']);\n }\n } catch {\n // diff failed — fall through\n }\n\n const githubMerged = await verifySquashMergedPrByBranch(ctx, branchName, remoteRef);\n if (githubMerged) return githubMerged;\n\n const { stdout: remoteUnmerged } = await execAsync(\n `git log main..${remoteRef} --oneline 2>/dev/null || true`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const count = remoteUnmerged.trim() ? remoteUnmerged.trim().split('\\n').length : 0;\n\n if (ctx.github) {\n try {\n const { stdout: issueState } = await execAsync(\n `gh issue view ${ctx.github.number} --repo ${ctx.github.owner}/${ctx.github.repo} --json state --jq '.state'`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n if (issueState.trim().toUpperCase() === 'CLOSED') {\n return stepSkipped(step, [`Issue already closed on GitHub; ${count} unmerged commit(s) remain on remote ${branchName}`]);\n }\n } catch {\n // gh check failed — fall through to hard fail\n }\n }\n\n return stepFailed(step, `${count} unmerged commit(s) on remote ${branchName}.`);\n }\n}\n\nasync function verifySquashMergedPrByBranch(\n ctx: LifecycleContext,\n branchName: string,\n branchRef: string,\n): Promise<StepResult | null> {\n if (!ctx.github) return null;\n\n const step = 'close-out:verify-merged';\n const { owner, repo } = ctx.github;\n\n try {\n const { stdout: prJson } = await execAsync(\n `gh pr list --repo ${owner}/${repo} --state merged --head ${JSON.stringify(branchName)} --json number,mergedAt,headRefOid,url`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const prs = JSON.parse(prJson) as GitHubMergedPr[];\n const mergedPr = prs\n .filter((pr) => (\n typeof pr.mergedAt === 'string'\n && pr.mergedAt.length > 0\n && typeof pr.headRefOid === 'string'\n && pr.headRefOid.length > 0\n ))\n .sort((a, b) => Date.parse(String(b.mergedAt)) - Date.parse(String(a.mergedAt)))[0];\n if (!mergedPr?.headRefOid) return null;\n\n const { stdout: tipShaRaw } = await execAsync(\n `git rev-parse ${branchRef} 2>/dev/null`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n const tipSha = tipShaRaw.trim();\n if (!tipSha) return null;\n\n if (tipSha === mergedPr.headRefOid) {\n const prLabel = typeof mergedPr.number === 'number' ? `PR #${mergedPr.number}` : 'GitHub PR';\n return stepOk(step, [`${prLabel} is squash-merged and ${branchRef} matches the merged PR head`]);\n }\n\n // PAN-2406 / state-plane policy rule 3: commits after the merged head that\n // touch ONLY state-plane paths (.pan/, .beads/) are pipeline exhaust —\n // e.g. 'chore: record merge status' — and must not block close-out.\n try {\n const { stdout: deltaRaw } = await execAsync(\n `git diff --name-only ${mergedPr.headRefOid}..${tipSha}`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n let deltaFiles = deltaRaw.split('\\n').map((f) => f.trim()).filter(Boolean);\n let statePlaneOnly = deltaFiles.length > 0 && deltaFiles.every((f) =>\n f.startsWith('.pan/') || f.startsWith('.beads/'));\n if (!statePlaneOnly) {\n // Branch may have merged main INTO itself after the PR merged — the\n // two-dot delta then contains main's own files. Judge only changes\n // UNIQUE to the branch (three-dot vs origin/main): if those are\n // state-plane-only, everything real is already on main.\n const { stdout: uniqueRaw } = await execAsync(\n `git diff --name-only origin/main...${tipSha}`,\n { cwd: ctx.projectPath, encoding: 'utf-8' },\n );\n deltaFiles = uniqueRaw.split('\\n').map((f) => f.trim()).filter(Boolean);\n statePlaneOnly = deltaFiles.every((f) =>\n f.startsWith('.pan/') || f.startsWith('.beads/'));\n }\n if (statePlaneOnly) {\n const prLabel = typeof mergedPr.number === 'number' ? `PR #${mergedPr.number}` : 'GitHub PR';\n return stepOk(step, [\n `${prLabel} is squash-merged; ${branchRef} is ahead only by state-plane commits (${deltaFiles.length} file(s): .pan/.beads) — accepted per state-plane policy`,\n ]);\n }\n } catch { /* diff failure falls through to the strict rejection below */ }\n\n const prLabel = typeof mergedPr.number === 'number' ? `PR #${mergedPr.number}` : 'merged GitHub PR';\n return stepFailed(step, `${branchRef} does not match the head commit of merged ${prLabel}; inspect before closing out.`);\n } catch {\n return null;\n }\n}\n\n/**\n * Reset issue back to open/backlog state (for destructive reset).\n */\nfunction resetIssueToTodo(ctx: LifecycleContext): Effect.Effect<StepResult> {\n return Effect.tryPromise({\n try: () => resetIssueToTodoImpl(ctx),\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepFailed('reset:reset-issue', `Failed to reset issue: ${(err as Error).message}`)),\n ),\n );\n}\n\nasync function resetIssueToTodoImpl(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'reset:reset-issue';\n try {\n if (ctx.github) {\n const { owner, repo, number } = ctx.github;\n // Reopen the issue\n await execAsync(\n `gh issue reopen ${number} --repo ${owner}/${repo}`,\n { encoding: 'utf-8' },\n ).catch(() => {}); // May already be open\n // Remove lifecycle labels\n const labelsToRemove = ['in-review', 'in-progress', 'planned', 'planning', 'Review: Approved', 'Review: Failed', 'ready-for-merge'];\n for (const label of labelsToRemove) {\n await execAsync(\n `gh issue edit ${number} --repo ${owner}/${repo} --remove-label \"${label}\"`,\n { encoding: 'utf-8' },\n ).catch(() => {}); // Label may not exist\n }\n return stepOk(step, [`Reset GitHub issue #${number}: reopened and cleared labels`]);\n }\n\n // Linear: reopen to Todo\n const linearApiKey = await getLinearApiKey();\n if (linearApiKey) {\n const { LinearClient } = await import('@linear/sdk');\n const client = new LinearClient({ apiKey: linearApiKey });\n const issueNum = extractNumberSync(ctx.issueId);\n const teamKey = extractPrefixSync(ctx.issueId);\n if (issueNum === null || teamKey === null) {\n return stepFailed(step, `Could not parse issue ID: ${ctx.issueId}`);\n }\n const results = await client.issues({\n filter: {\n number: { eq: issueNum },\n team: { key: { eq: teamKey } },\n },\n first: 1,\n });\n if (results.nodes.length > 0) {\n const issue = results.nodes[0];\n const team = await issue.team;\n if (team) {\n const states = await team.states();\n const todoState = states.nodes.find(s => s.type === 'unstarted' && s.name === 'Todo') ||\n states.nodes.find(s => s.type === 'unstarted');\n if (todoState) {\n await issue.update({ stateId: todoState.id });\n }\n }\n }\n return stepOk(step, [`Reset ${trackerName(ctx, 'linear')} issue ${ctx.issueId} to Todo`]);\n }\n\n return stepSkipped(step, ['No tracker available to reset issue']);\n } catch (err) {\n return stepFailed(step, `Failed to reset issue: ${(err as Error).message}`);\n }\n}\n\n/**\n * Clear review status for an issue.\n */\nasync function resetPostMergeStateForIssue(issueId: string): Promise<void> {\n try {\n const { resetPostMergeState } = await import('../cloister/merge-agent.js');\n resetPostMergeState(issueId);\n resetPostMergeState(issueId.toUpperCase());\n } catch {\n return;\n }\n}\n\nfunction clearReviewStatusStep(issueId: string): Effect.Effect<StepResult> {\n return Effect.tryPromise({\n try: () => clearReviewStatusStepImpl(issueId),\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepSkipped('clear-review-status', [`Failed to clear review status (non-fatal): ${(err as Error).message}`])),\n ),\n );\n}\n\nasync function clearReviewStatusStepImpl(issueId: string): Promise<StepResult> {\n const step = 'clear-review-status';\n try {\n const { clearReviewStatus } = await import('../review-status.js');\n clearReviewStatus(issueId.toUpperCase());\n return stepOk(step, ['Review status cleared']);\n } catch {\n // Fallback: direct file manipulation\n try {\n const statusFile = join(OVERDECK_HOME, 'review-status.json');\n if (existsSync(statusFile)) {\n const data = JSON.parse(await readFile(statusFile, 'utf-8'));\n const upperKey = issueId.toUpperCase();\n if (data[upperKey]) {\n delete data[upperKey];\n await writeFile(statusFile, JSON.stringify(data, null, 2));\n }\n }\n return stepOk(step, ['Review status cleared (direct)']);\n } catch (innerErr) {\n return stepSkipped(step, [`Failed to clear review status (non-fatal): ${(innerErr as Error).message}`]);\n }\n }\n}\n\nexport const __testInternals = {\n completeVBriefStep,\n verifyBranchMerged,\n};\n\nfunction resetIssueToCanceled(ctx: LifecycleContext): Effect.Effect<StepResult> {\n return Effect.tryPromise({\n try: () => resetIssueToCanceledImpl(ctx),\n catch: (err) => err,\n }).pipe(\n Effect.catch((err) =>\n Effect.succeed(stepFailed('cancel:reset-issue', `Failed to cancel issue: ${(err as Error).message}`)),\n ),\n );\n}\n\nasync function resetIssueToCanceledImpl(ctx: LifecycleContext): Promise<StepResult> {\n const step = 'cancel:reset-issue';\n try {\n if (ctx.github) {\n const { owner, repo, number } = ctx.github;\n await execAsync(\n `gh issue edit ${number} --repo ${owner}/${repo} --add-label \"wontfix\"`,\n { encoding: 'utf-8' },\n ).catch(() => {});\n return stepOk(step, [`Marked GitHub issue #${number} as canceled/wontfix`]);\n }\n\n const linearApiKey = await getLinearApiKey();\n if (linearApiKey) {\n const { LinearClient } = await import('@linear/sdk');\n const client = new LinearClient({ apiKey: linearApiKey });\n const issueNum = extractNumberSync(ctx.issueId);\n const teamKey = extractPrefixSync(ctx.issueId);\n if (issueNum === null || teamKey === null) {\n return stepFailed(step, `Could not parse issue ID: ${ctx.issueId}`);\n }\n const results = await client.issues({\n filter: {\n number: { eq: issueNum },\n team: { key: { eq: teamKey } },\n },\n first: 1,\n });\n if (results.nodes.length > 0) {\n const issue = results.nodes[0];\n const team = await issue.team;\n if (team) {\n const states = await team.states();\n const canceledState = states.nodes.find(s => s.type === 'canceled') ||\n states.nodes.find(s => s.name.toLowerCase() === 'canceled');\n if (canceledState) {\n await issue.update({ stateId: canceledState.id });\n }\n }\n }\n return stepOk(step, [`Reset ${trackerName(ctx, 'linear')} issue ${ctx.issueId} to Canceled`]);\n }\n\n return stepSkipped(step, ['No tracker available to cancel issue']);\n } catch (err) {\n return stepFailed(step, `Failed to cancel issue: ${(err as Error).message}`);\n }\n}\n"],"mappings":"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"}
|