@overdeck/core 0.50.3 → 0.50.4

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.
Files changed (208) hide show
  1. package/dist/agents-DNMRPC8n.js.map +1 -1
  2. package/dist/{build-info-BJuEVWOh.js → build-info-ioRdOmqT.js} +3 -3
  3. package/dist/{build-info-BJuEVWOh.js.map → build-info-ioRdOmqT.js.map} +1 -1
  4. package/dist/build-info-kMMitDOP.js +2 -0
  5. package/dist/cli/index.js +4 -4
  6. package/dist/conversation-compaction-GFfO5UZL.js.map +1 -1
  7. package/dist/dashboard/{advancing-selfheal-Bq8V0QUa.js → advancing-selfheal-Dp5_Gai3.js} +3 -3
  8. package/dist/dashboard/{advancing-selfheal-Bq8V0QUa.js.map → advancing-selfheal-Dp5_Gai3.js.map} +1 -1
  9. package/dist/dashboard/{agent-gc-Coz8zQt_.js → agent-gc-JzoSs5Pi.js} +3 -3
  10. package/dist/dashboard/{agent-gc-Coz8zQt_.js.map → agent-gc-JzoSs5Pi.js.map} +1 -1
  11. package/dist/dashboard/{agent-idle-CAwB-K6M.js → agent-idle-D-Qy5BN_.js} +2 -2
  12. package/dist/dashboard/{agent-idle-CAwB-K6M.js.map → agent-idle-D-Qy5BN_.js.map} +1 -1
  13. package/dist/dashboard/{agent-state-Ci6PhjOE.js → agent-state-B196fj1h.js} +38 -16
  14. package/dist/dashboard/agent-state-B196fj1h.js.map +1 -0
  15. package/dist/dashboard/{agent-state-CbUEwUEQ.js → agent-state-IpWnw8lv.js} +1 -1
  16. package/dist/dashboard/{agent-state-service-D6IVrX3B.js → agent-state-service-CCo5-9DR.js} +3 -3
  17. package/dist/dashboard/{agent-state-service-D6IVrX3B.js.map → agent-state-service-CCo5-9DR.js.map} +1 -1
  18. package/dist/dashboard/{agent-state-service-DcN1j6eK.js → agent-state-service-D_F3VZ23.js} +1 -1
  19. package/dist/dashboard/{agents-BVvL4o_4.js → agents-CkGhnAmu.js} +1 -1
  20. package/dist/dashboard/{backlog-auto-trigger-BuSBqG2V.js → backlog-auto-trigger-B5Z2zBtC.js} +2 -2
  21. package/dist/dashboard/{backlog-auto-trigger-BuSBqG2V.js.map → backlog-auto-trigger-B5Z2zBtC.js.map} +1 -1
  22. package/dist/dashboard/build-info-BTjOB0Xr.js +2 -0
  23. package/dist/dashboard/{build-info-Cj3Y0K87.js → build-info-D0EJNj6C.js} +3 -3
  24. package/dist/dashboard/{build-info-Cj3Y0K87.js.map → build-info-D0EJNj6C.js.map} +1 -1
  25. package/dist/dashboard/cli-CIznFrcE.js +2 -0
  26. package/dist/dashboard/{cli-DIhQieif.js → cli-DCbVrSsg.js} +2 -2
  27. package/dist/dashboard/{cli-DIhQieif.js.map → cli-DCbVrSsg.js.map} +1 -1
  28. package/dist/dashboard/{close-issue-CRlmrE5g.js → close-issue-Bmu9aOIx.js} +2 -2
  29. package/dist/dashboard/{close-issue-CRlmrE5g.js.map → close-issue-Bmu9aOIx.js.map} +1 -1
  30. package/dist/dashboard/{closed-issue-reaper-DrHyYgJR.js → closed-issue-reaper-COxfTtLz.js} +5 -5
  31. package/dist/dashboard/{closed-issue-reaper-DrHyYgJR.js.map → closed-issue-reaper-COxfTtLz.js.map} +1 -1
  32. package/dist/dashboard/{closed-issue-reaper-DWlw2EtL.js → closed-issue-reaper-DwMwG_Pz.js} +1 -1
  33. package/dist/dashboard/{compaction-continuation-DhYgsXmF.js → compaction-continuation-Bqc212Zm.js} +2 -2
  34. package/dist/dashboard/{compaction-continuation-DhYgsXmF.js.map → compaction-continuation-Bqc212Zm.js.map} +1 -1
  35. package/dist/dashboard/{conflict-gate-vczgdVTa.js → conflict-gate-9mPVg7-5.js} +1 -1
  36. package/dist/dashboard/{conflict-gate-Bt-lLgYf.js → conflict-gate-CGQTcR0I.js} +3 -3
  37. package/dist/dashboard/{conflict-gate-Bt-lLgYf.js.map → conflict-gate-CGQTcR0I.js.map} +1 -1
  38. package/dist/dashboard/{conversation-compaction-CsdCbcQB.js → conversation-compaction-C7P6V8Iw.js} +5 -5
  39. package/dist/dashboard/{conversation-compaction-CsdCbcQB.js.map → conversation-compaction-C7P6V8Iw.js.map} +1 -1
  40. package/dist/dashboard/{conversation-compaction-D0zgWM1f.js → conversation-compaction-Cck5oi-V.js} +1 -1
  41. package/dist/dashboard/{conversation-service-6LaymUV-.js → conversation-service-CsOpwI9Y.js} +37 -5
  42. package/dist/dashboard/{conversation-service-6LaymUV-.js.map → conversation-service-CsOpwI9Y.js.map} +1 -1
  43. package/dist/dashboard/conversation-service-plOFkoMo.js +3 -0
  44. package/dist/dashboard/dashboard-db-worker.js +1 -1
  45. package/dist/dashboard/{deacon-CU47dU7U.js → deacon-B8oMMIgN.js} +62 -62
  46. package/dist/dashboard/{deacon-CU47dU7U.js.map → deacon-B8oMMIgN.js.map} +1 -1
  47. package/dist/dashboard/{deacon-DYsOa_ss.js → deacon-b7J57Svt.js} +2 -2
  48. package/dist/dashboard/{deacon-pending-lifecycle-ijGX8wLb.js → deacon-pending-lifecycle-3NIJ7ew5.js} +2 -2
  49. package/dist/dashboard/{deacon-pending-lifecycle-ijGX8wLb.js.map → deacon-pending-lifecycle-3NIJ7ew5.js.map} +1 -1
  50. package/dist/dashboard/deacon.js +5 -5
  51. package/dist/dashboard/{delivery-DMYxIE0J.js → delivery-lnI-gQKo.js} +1 -1
  52. package/dist/dashboard/{deploy-patrol-C4eXco1S.js → deploy-patrol-u3v2krg9.js} +2 -2
  53. package/dist/dashboard/{deploy-patrol-C4eXco1S.js.map → deploy-patrol-u3v2krg9.js.map} +1 -1
  54. package/dist/dashboard/{feedback-stuck-retirement-Dd5XNrMr.js → feedback-stuck-retirement-CoFNqjCc.js} +2 -2
  55. package/dist/dashboard/{feedback-stuck-retirement-Dd5XNrMr.js.map → feedback-stuck-retirement-CoFNqjCc.js.map} +1 -1
  56. package/dist/dashboard/{feedback-target-BzdJ2wIR.js → feedback-target-BBCh3RRq.js} +1 -1
  57. package/dist/dashboard/{feedback-target-BcsA_GRV.js → feedback-target-CeCq6EhW.js} +5 -5
  58. package/dist/dashboard/{feedback-target-BcsA_GRV.js.map → feedback-target-CeCq6EhW.js.map} +1 -1
  59. package/dist/dashboard/{flywheel-Is3w2lcT.js → flywheel-DKldI63J.js} +7 -7
  60. package/dist/dashboard/{flywheel-Is3w2lcT.js.map → flywheel-DKldI63J.js.map} +1 -1
  61. package/dist/dashboard/{flywheel-D0guNqkh.js → flywheel-DpRPLErh.js} +7 -7
  62. package/dist/dashboard/{flywheel-D0guNqkh.js.map → flywheel-DpRPLErh.js.map} +1 -1
  63. package/dist/dashboard/{flywheel-B34cdfbd.js → flywheel-jeZFYvm-.js} +1 -1
  64. package/dist/dashboard/{flywheel-merge-order-6HiPR2WG.js → flywheel-merge-order-0OnoosaO.js} +1 -1
  65. package/dist/dashboard/{flywheel-merge-order-BsNPMu0S.js → flywheel-merge-order-PG5op4j7.js} +2 -2
  66. package/dist/dashboard/{flywheel-merge-order-BsNPMu0S.js.map → flywheel-merge-order-PG5op4j7.js.map} +1 -1
  67. package/dist/dashboard/{harness-resolve-CzTFVZ5l.js → harness-resolve-C0HWj3H9.js} +2 -2
  68. package/dist/dashboard/{harness-resolve-CzTFVZ5l.js.map → harness-resolve-C0HWj3H9.js.map} +1 -1
  69. package/dist/dashboard/{identity-Dc7rQLln.js → identity-Cot1Hg4G.js} +2 -2
  70. package/dist/dashboard/{identity-Dc7rQLln.js.map → identity-Cot1Hg4G.js.map} +1 -1
  71. package/dist/dashboard/{inspect-agent-CP7Bu47O.js → inspect-agent-BDmLWbGx.js} +3 -3
  72. package/dist/dashboard/{inspect-agent-CP7Bu47O.js.map → inspect-agent-BDmLWbGx.js.map} +1 -1
  73. package/dist/dashboard/inspect-agent-BcOkA-hC.js +2 -0
  74. package/dist/dashboard/{issue-lifecycle-BPbczKyy.js → issue-lifecycle-1B_v8Rf5.js} +6 -6
  75. package/dist/dashboard/{issue-lifecycle-BPbczKyy.js.map → issue-lifecycle-1B_v8Rf5.js.map} +1 -1
  76. package/dist/dashboard/{issue-lifecycle-FaugTi39.js → issue-lifecycle-CIrfbIbj.js} +1 -1
  77. package/dist/dashboard/{issue-service-singleton-Dsad9NTt.js → issue-service-singleton-BVwPzjwF.js} +1 -1
  78. package/dist/dashboard/{issue-service-singleton-BrZQJLRI.js → issue-service-singleton-KcRrOiFD.js} +2 -2
  79. package/dist/dashboard/{issue-service-singleton-BrZQJLRI.js.map → issue-service-singleton-KcRrOiFD.js.map} +1 -1
  80. package/dist/dashboard/{jsonl-resolver-DQEe0DHM.js → jsonl-resolver-jxbif7MD.js} +3 -3
  81. package/dist/dashboard/{jsonl-resolver-DQEe0DHM.js.map → jsonl-resolver-jxbif7MD.js.map} +1 -1
  82. package/dist/dashboard/{kimi-code-Cx5YUJpS.js → kimi-code-BZh3NgcN.js} +1 -1
  83. package/dist/dashboard/{lifecycle-DZFHmpGI.js → lifecycle-CvcZ4_fA.js} +4 -4
  84. package/dist/dashboard/{lifecycle-DZFHmpGI.js.map → lifecycle-CvcZ4_fA.js.map} +1 -1
  85. package/dist/dashboard/{linear-mcp-auth-DylPJABZ.js → linear-mcp-auth-CZoj_-d7.js} +1 -1
  86. package/dist/dashboard/{linear-mcp-auth-BFlpMvWh.js → linear-mcp-auth-Dx74yCAY.js} +2 -2
  87. package/dist/dashboard/{linear-mcp-auth-BFlpMvWh.js.map → linear-mcp-auth-Dx74yCAY.js.map} +1 -1
  88. package/dist/dashboard/{memory-governor-B7uDWRo9.js → memory-governor-Bv3LAqk3.js} +5 -5
  89. package/dist/dashboard/{memory-governor-B7uDWRo9.js.map → memory-governor-Bv3LAqk3.js.map} +1 -1
  90. package/dist/dashboard/{merge-agent-ddEcZDZD.js → merge-agent-1zVLl6k_.js} +1 -1
  91. package/dist/dashboard/{merge-agent-ttRY053V.js → merge-agent-8zrQu48t.js} +8 -8
  92. package/dist/dashboard/{merge-agent-ttRY053V.js.map → merge-agent-8zrQu48t.js.map} +1 -1
  93. package/dist/dashboard/merge-ops-CFJaMPLu.js +2 -0
  94. package/dist/dashboard/{merge-train-f_un38UJ.js → merge-train-BYH_cF7G.js} +2 -2
  95. package/dist/dashboard/{merge-train-f_un38UJ.js.map → merge-train-BYH_cF7G.js.map} +1 -1
  96. package/dist/dashboard/{merge-train-deps-GPlHOjK6.js → merge-train-deps-BTfXM5AR.js} +2 -2
  97. package/dist/dashboard/{merge-train-deps-GPlHOjK6.js.map → merge-train-deps-BTfXM5AR.js.map} +1 -1
  98. package/dist/dashboard/{messaging-BasbftDu.js → messaging-Bk6vGsMw.js} +1 -1
  99. package/dist/dashboard/{orphan-proposed-reconciler-DFHdQSEg.js → orphan-proposed-reconciler-B898fk26.js} +6 -6
  100. package/dist/dashboard/{orphan-proposed-reconciler-DFHdQSEg.js.map → orphan-proposed-reconciler-B898fk26.js.map} +1 -1
  101. package/dist/dashboard/{orphan-proposed-reconciler-DzAxrM99.js → orphan-proposed-reconciler-Bx_aWS4B.js} +1 -1
  102. package/dist/dashboard/{parked-residue-DMtbxJml.js → parked-residue-q2kzrYSm.js} +9 -9
  103. package/dist/dashboard/{parked-residue-DMtbxJml.js.map → parked-residue-q2kzrYSm.js.map} +1 -1
  104. package/dist/dashboard/{post-merge-lifecycle-worker-jzN2g_EY.js → post-merge-lifecycle-worker-Cl7-uf4g.js} +2 -2
  105. package/dist/dashboard/{post-merge-lifecycle-worker-jzN2g_EY.js.map → post-merge-lifecycle-worker-Cl7-uf4g.js.map} +1 -1
  106. package/dist/dashboard/{project-resource-refresh-queue-cqOeJ0fB.js → project-resource-refresh-queue-O_dRfPHn.js} +1 -1
  107. package/dist/dashboard/{project-resource-refresh-queue-DebwjPPA.js → project-resource-refresh-queue-se3T9IYP.js} +4 -4
  108. package/dist/dashboard/{project-resource-refresh-queue-DebwjPPA.js.map → project-resource-refresh-queue-se3T9IYP.js.map} +1 -1
  109. package/dist/dashboard/{reconstruct-cache-Bb2Jg2DZ.js → reconstruct-cache-XpWC9L0F.js} +2 -2
  110. package/dist/dashboard/{reconstruct-cache-Bb2Jg2DZ.js.map → reconstruct-cache-XpWC9L0F.js.map} +1 -1
  111. package/dist/dashboard/{release-engine-78iCajIc.js → release-engine-BuzxOamf.js} +2 -2
  112. package/dist/dashboard/{release-engine-78iCajIc.js.map → release-engine-BuzxOamf.js.map} +1 -1
  113. package/dist/dashboard/{remote-completion-D5wzZCte.js → remote-completion-BCZgeKPS.js} +3 -3
  114. package/dist/dashboard/{remote-completion-D5wzZCte.js.map → remote-completion-BCZgeKPS.js.map} +1 -1
  115. package/dist/dashboard/{resolver-BGZh3lXA.js → resolver-BeNrqNou.js} +5 -5
  116. package/dist/dashboard/{resolver-BGZh3lXA.js.map → resolver-BeNrqNou.js.map} +1 -1
  117. package/dist/dashboard/{resource-pressure-patrol-Bg23rPV-.js → resource-pressure-patrol-Ccg_aCgO.js} +3 -3
  118. package/dist/dashboard/{resource-pressure-patrol-Bg23rPV-.js.map → resource-pressure-patrol-Ccg_aCgO.js.map} +1 -1
  119. package/dist/dashboard/{resume-BKyB4hA1.js → resume-KGCrn0DV.js} +1 -1
  120. package/dist/dashboard/{review-agent-ZdP-HmwY.js → review-agent-BmM6YMZW.js} +1 -1
  121. package/dist/dashboard/{review-agent-DHs-JngN.js → review-agent-DRWVU8fP.js} +13 -13
  122. package/dist/dashboard/{review-agent-DHs-JngN.js.map → review-agent-DRWVU8fP.js.map} +1 -1
  123. package/dist/dashboard/{review-convoy-liveness-BTMvU4CA.js → review-convoy-liveness-EvCDv8Q_.js} +3 -3
  124. package/dist/dashboard/{review-convoy-liveness-BTMvU4CA.js.map → review-convoy-liveness-EvCDv8Q_.js.map} +1 -1
  125. package/dist/dashboard/{review-run-recovery-BYalQzbh.js → review-run-recovery-Ctm48Snt.js} +1 -1
  126. package/dist/dashboard/{review-run-recovery-BvVG3oUr.js → review-run-recovery-DNDI58cM.js} +2 -2
  127. package/dist/dashboard/{review-run-recovery-BvVG3oUr.js.map → review-run-recovery-DNDI58cM.js.map} +1 -1
  128. package/dist/dashboard/{review-status-DXTFzCmR.js → review-status-FnlvQuPI.js} +1 -1
  129. package/dist/dashboard/{review-status-emit-C9YW6SQL.js → review-status-emit-CeMS31DX.js} +2 -2
  130. package/dist/dashboard/{review-status-emit-C9YW6SQL.js.map → review-status-emit-CeMS31DX.js.map} +1 -1
  131. package/dist/dashboard/{review-status-BegAr86G.js → review-status-yY5qt7Rl.js} +5 -5
  132. package/dist/dashboard/{review-status-BegAr86G.js.map → review-status-yY5qt7Rl.js.map} +1 -1
  133. package/dist/dashboard/{review-verdict-feedback-qlVBi19-.js → review-verdict-feedback-BNgRj1e3.js} +4 -4
  134. package/dist/dashboard/{review-verdict-feedback-qlVBi19-.js.map → review-verdict-feedback-BNgRj1e3.js.map} +1 -1
  135. package/dist/dashboard/{review-verdict-feedback-Dp139Lmv.js → review-verdict-feedback-D39cuSV1.js} +1 -1
  136. package/dist/dashboard/{review-verdict-writer-CJr_Ob0Y.js → review-verdict-writer-DvFfKAn-.js} +2 -2
  137. package/dist/dashboard/{review-verdict-writer-CJr_Ob0Y.js.map → review-verdict-writer-DvFfKAn-.js.map} +1 -1
  138. package/dist/dashboard/{review-verdict-writer-BVco3WoI.js → review-verdict-writer-PcGBkvJ4.js} +1 -1
  139. package/dist/dashboard/{sequence-io-iljWlslY.js → sequence-io-DZyschsf.js} +2 -2
  140. package/dist/dashboard/{sequence-io-iljWlslY.js.map → sequence-io-DZyschsf.js.map} +1 -1
  141. package/dist/dashboard/{sequencer-agent-BGGVKxtw.js → sequencer-agent-BXDw5cNx.js} +5 -5
  142. package/dist/dashboard/{sequencer-agent-BGGVKxtw.js.map → sequencer-agent-BXDw5cNx.js.map} +1 -1
  143. package/dist/dashboard/server.js +79 -72
  144. package/dist/dashboard/server.js.map +1 -1
  145. package/dist/dashboard/{service-kzhN0DLg.js → service-DP50Omvn.js} +33 -33
  146. package/dist/dashboard/{service-kzhN0DLg.js.map → service-DP50Omvn.js.map} +1 -1
  147. package/dist/dashboard/{smart-compaction-owKHJDbL.js → smart-compaction-944GL8PN.js} +1 -1
  148. package/dist/dashboard/{smart-compaction-C96F2aFQ.js → smart-compaction-BzDfF6yb.js} +2 -2
  149. package/dist/dashboard/{smart-compaction-C96F2aFQ.js.map → smart-compaction-BzDfF6yb.js.map} +1 -1
  150. package/dist/dashboard/{spawn-planning-session-CiJdOHTD.js → spawn-planning-session-BcVnHJjm.js} +1 -1
  151. package/dist/dashboard/{spawn-planning-session-FmJa6PCS.js → spawn-planning-session-CH8IYli7.js} +3 -3
  152. package/dist/dashboard/{spawn-planning-session-FmJa6PCS.js.map → spawn-planning-session-CH8IYli7.js.map} +1 -1
  153. package/dist/dashboard/{specialist-context-_ootmzn2.js → specialist-context-DhDTXVht.js} +3 -3
  154. package/dist/dashboard/{specialist-context-_ootmzn2.js.map → specialist-context-DhDTXVht.js.map} +1 -1
  155. package/dist/dashboard/{specialist-logs-BbAX221-.js → specialist-logs-C1bcnZ-G.js} +2 -2
  156. package/dist/dashboard/{specialist-logs-BbAX221-.js.map → specialist-logs-C1bcnZ-G.js.map} +1 -1
  157. package/dist/dashboard/{specialists-COZoYaiz.js → specialists-BKmReEWT.js} +53 -53
  158. package/dist/dashboard/{specialists-COZoYaiz.js.map → specialists-BKmReEWT.js.map} +1 -1
  159. package/dist/dashboard/{specialists-RPLJnYc1.js → specialists-Bvrvt0br.js} +12 -12
  160. package/dist/dashboard/{specialists-RPLJnYc1.js.map → specialists-Bvrvt0br.js.map} +1 -1
  161. package/dist/dashboard/{specialists-DTAOVZpU.js → specialists-CD6GEKXk.js} +1 -1
  162. package/dist/dashboard/{specialists-D8sYZnPb.js → specialists-eFWpJRBc.js} +1 -1
  163. package/dist/dashboard/{stall-sweeper-9bRBZhrQ.js → stall-sweeper-D3fZvg7O.js} +3 -3
  164. package/dist/dashboard/{stall-sweeper-9bRBZhrQ.js.map → stall-sweeper-D3fZvg7O.js.map} +1 -1
  165. package/dist/dashboard/{state-migrate-J3tFJnbd.js → state-migrate-KZ2goscQ.js} +2 -2
  166. package/dist/dashboard/{state-migrate-J3tFJnbd.js.map → state-migrate-KZ2goscQ.js.map} +1 -1
  167. package/dist/dashboard/{stuck-remediation-BvTK_NYN.js → stuck-remediation-Cb2V1roj.js} +1 -1
  168. package/dist/dashboard/{stuck-remediation-4Rf_xMEb.js → stuck-remediation-CnoV0kcv.js} +5 -5
  169. package/dist/dashboard/{stuck-remediation-4Rf_xMEb.js.map → stuck-remediation-CnoV0kcv.js.map} +1 -1
  170. package/dist/dashboard/{summary-fork-PLcckTRE.js → summary-fork-CxuNBM0F.js} +2 -2
  171. package/dist/dashboard/{summary-fork-D-cylknJ.js → summary-fork-lC2vMXly.js} +4 -4
  172. package/dist/dashboard/{summary-fork-D-cylknJ.js.map → summary-fork-lC2vMXly.js.map} +1 -1
  173. package/dist/dashboard/{teardown-workspace-CTL16rnG.js → teardown-workspace-C-9murBw.js} +4 -4
  174. package/dist/dashboard/{teardown-workspace-CTL16rnG.js.map → teardown-workspace-C-9murBw.js.map} +1 -1
  175. package/dist/dashboard/{test-agent-queue-CMgYZiR_.js → test-agent-queue-YCBRzaAB.js} +3 -3
  176. package/dist/dashboard/{test-agent-queue-CMgYZiR_.js.map → test-agent-queue-YCBRzaAB.js.map} +1 -1
  177. package/dist/dashboard/{uat-failure-feedback-DS6W9X3I.js → uat-failure-feedback-B-1mL8Zp.js} +3 -3
  178. package/dist/dashboard/{uat-failure-feedback-DS6W9X3I.js.map → uat-failure-feedback-B-1mL8Zp.js.map} +1 -1
  179. package/dist/dashboard/{uat-promote-verification-CRsIHE_q.js → uat-promote-verification-BEBPcpPg.js} +2 -2
  180. package/dist/dashboard/{uat-promote-verification-CRsIHE_q.js.map → uat-promote-verification-BEBPcpPg.js.map} +1 -1
  181. package/dist/dashboard/{uat-train-BoA9r6_I.js → uat-train-BFo3OQUB.js} +1 -1
  182. package/dist/dashboard/{uat-train-Cd8CJeNe.js → uat-train-COgoJomz.js} +8 -8
  183. package/dist/dashboard/{uat-train-Cd8CJeNe.js.map → uat-train-COgoJomz.js.map} +1 -1
  184. package/dist/dashboard/{validate-BdmvTIym.js → validate-069_N1e2.js} +2 -2
  185. package/dist/dashboard/{validate-BdmvTIym.js.map → validate-069_N1e2.js.map} +1 -1
  186. package/dist/dashboard/{verification-runner-BO0K3xNA.js → verification-runner-CQnZyC5A.js} +1 -1
  187. package/dist/dashboard/{verification-runner-fEY1Qj-l.js → verification-runner-fy3wNrWn.js} +4 -4
  188. package/dist/dashboard/{verification-runner-fEY1Qj-l.js.map → verification-runner-fy3wNrWn.js.map} +1 -1
  189. package/dist/dashboard/workflows-Bk6Kt0ZQ.js +2 -0
  190. package/dist/dashboard/{workflows-CxVnygYU.js → workflows-N4QMkDzN.js} +10 -10
  191. package/dist/dashboard/{workflows-CxVnygYU.js.map → workflows-N4QMkDzN.js.map} +1 -1
  192. package/dist/dashboard/{workspaces-Cpz0xJWQ.js → workspaces-DmoyfHoU.js} +33 -33
  193. package/dist/dashboard/{workspaces-Cpz0xJWQ.js.map → workspaces-DmoyfHoU.js.map} +1 -1
  194. package/dist/{lifecycle-C6k0HWEO.js → lifecycle-DCFcjg7y.js} +1 -1
  195. package/dist/{lifecycle-D5oRpvvB.js → lifecycle-GkaHQJNK.js} +2 -2
  196. package/dist/{lifecycle-D5oRpvvB.js.map → lifecycle-GkaHQJNK.js.map} +1 -1
  197. package/dist/{merge-agent-Drufc7tU.js → merge-agent-CogNFasY.js} +2 -2
  198. package/dist/{merge-agent-Drufc7tU.js.map → merge-agent-CogNFasY.js.map} +1 -1
  199. package/dist/{merge-agent-CBOVY_eC.js → merge-agent-eteKQ9Rb.js} +1 -1
  200. package/package.json +1 -1
  201. package/dist/build-info-BgrwLUy6.js +0 -2
  202. package/dist/dashboard/agent-state-Ci6PhjOE.js.map +0 -1
  203. package/dist/dashboard/build-info-CYlxvZSQ.js +0 -2
  204. package/dist/dashboard/cli-ZAS502uC.js +0 -2
  205. package/dist/dashboard/conversation-service-Dlks_hSS.js +0 -3
  206. package/dist/dashboard/inspect-agent-DTuSg95i.js +0 -2
  207. package/dist/dashboard/merge-ops-Bgc-EScO.js +0 -2
  208. package/dist/dashboard/workflows-CgGNyl1z.js +0 -2
@@ -1,5 +1,5 @@
1
1
  import { i as getAllReviewStatusesFromDb, l as init_review_status_sync } from "./review-status-sync-CHt0oq_3.js";
2
- import { G as liveOrderIssueLookup, W as listBooks, q as orderIssueStoreStatus } from "./flywheel-Is3w2lcT.js";
2
+ import { G as liveOrderIssueLookup, W as listBooks, q as orderIssueStoreStatus } from "./flywheel-DKldI63J.js";
3
3
  import { join } from "node:path";
4
4
  import { existsSync, readdirSync, statSync } from "node:fs";
5
5
  //#region ../../lib/cloister/merge-blockers.ts
@@ -183,4 +183,4 @@ function validateBookForStart(stateRoot, book, options = {}) {
183
183
  //#endregion
184
184
  export { getMergeBlockersPayload as i, hasOrderIssuePrd as n, validateBookForStart as r, createOrderPrdLookup as t };
185
185
 
186
- //# sourceMappingURL=validate-BdmvTIym.js.map
186
+ //# sourceMappingURL=validate-069_N1e2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate-BdmvTIym.js","names":[],"sources":["../../src/lib/cloister/merge-blockers.ts","../../src/lib/orders/validate.ts"],"sourcesContent":["import { getAllReviewStatusesFromDb } from '../overdeck/review-status-sync.js';\n\n/**\n * PRs that passed review but cannot merge for a native gate reason (PAN-1620):\n * merge conflicts, failing checks, a not-mergeable state, or a sibling repo stranded\n * with unmerged commits and no merged review artifact.\n *\n * Reads `review_status` directly from SQLite — NO HTTP — so it works inside a\n * network-sandboxed harness (e.g. codex's bwrap sandbox) where a `curl` to the\n * dashboard's `/api/flywheel/merge-blockers` cannot reach `127.0.0.1:3011`.\n * Shared by the dashboard route and the `pan flywheel merge-blockers` CLI so the\n * two surfaces can never disagree.\n */\nconst MERGE_BLOCKER_TYPES = new Set([\n 'merge_conflict',\n 'failing_checks',\n 'not_mergeable',\n 'unmerged_sibling_repo',\n]);\n\nexport interface MergeBlocker {\n issueId: string;\n prUrl?: string;\n reasons: Array<{ type: string; summary: string }>;\n}\n\nexport function getMergeBlockersPayload(): MergeBlocker[] {\n const statuses = getAllReviewStatusesFromDb();\n const out: MergeBlocker[] = [];\n for (const [issueId, status] of Object.entries(statuses)) {\n if (status.reviewStatus !== 'passed') continue;\n if (status.mergeStatus === 'merged') continue;\n const reasons = (status.blockerReasons ?? []).filter((b) => MERGE_BLOCKER_TYPES.has(b.type));\n if (reasons.length === 0) continue;\n out.push({ issueId, prUrl: status.prUrl, reasons: reasons.map((b) => ({ type: b.type, summary: b.summary })) });\n }\n return out;\n}\n","import { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { OrderBook } from '@overdeck/contracts';\nimport { listBooks, orderIssueStoreStatus } from './resolver.js';\nimport { liveOrderIssueLookup } from './resolver.js';\nimport type {\n OrderBookFinding,\n OrderBookValidationResult,\n OrderIssueLookup,\n} from './types.js';\n\nfunction hasNonEmptyFile(path: string): boolean {\n try {\n return existsSync(path) && statSync(path).isFile() && statSync(path).size > 0;\n } catch {\n return false;\n }\n}\n\nfunction issuePattern(issueId: string): RegExp {\n const escaped = issueId.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(?:^|[-_])${escaped}(?:[-_.]|$)`, 'i');\n}\n\nfunction nonEmptyFileNames(directory: string): string[] {\n if (!existsSync(directory)) return [];\n return readdirSync(directory).filter((name) => hasNonEmptyFile(join(directory, name)));\n}\n\nexport function createOrderPrdLookup(stateRoot: string): (issueId: string) => boolean {\n const draftNames = new Set([\n ...nonEmptyFileNames(join(stateRoot, 'drafts')),\n ...nonEmptyFileNames(join(stateRoot, '.pan', 'drafts')),\n ].map((name) => name.toLowerCase()));\n const specNames = [\n ...nonEmptyFileNames(join(stateRoot, 'specs')),\n ...nonEmptyFileNames(join(stateRoot, '.pan', 'specs')),\n ];\n return (issueId: string) => {\n const lower = issueId.toLowerCase();\n if (draftNames.has(`${lower}.md`)) return true;\n const pattern = issuePattern(issueId);\n return specNames.some((name) => pattern.test(name));\n };\n}\n\nexport function hasOrderIssuePrd(stateRoot: string, issueId: string): boolean {\n const lower = issueId.toLowerCase();\n const draftPaths = [\n join(stateRoot, 'drafts', `${lower}.md`),\n join(stateRoot, '.pan', 'drafts', `${lower}.md`),\n ];\n if (draftPaths.some(hasNonEmptyFile)) return true;\n\n for (const specsDir of [join(stateRoot, 'specs'), join(stateRoot, '.pan', 'specs')]) {\n if (!existsSync(specsDir)) continue;\n const pattern = issuePattern(issueId);\n if (readdirSync(specsDir).some((name) => pattern.test(name) && hasNonEmptyFile(join(specsDir, name)))) {\n return true;\n }\n }\n return false;\n}\n\nfunction findCycle(book: OrderBook): string[] | null {\n const issues = new Set(book.items.map((item) => item.issue.toUpperCase()));\n const edges = new Map(\n book.items.map((item) => [\n item.issue.toUpperCase(),\n item.prereqs.map((prereq) => prereq.toUpperCase()).filter((prereq) => issues.has(prereq)),\n ]),\n );\n const visiting = new Set<string>();\n const visited = new Set<string>();\n const path: string[] = [];\n\n const visit = (issue: string): string[] | null => {\n if (visiting.has(issue)) {\n const start = path.indexOf(issue);\n return [...path.slice(start), issue];\n }\n if (visited.has(issue)) return null;\n visiting.add(issue);\n path.push(issue);\n for (const prereq of edges.get(issue) ?? []) {\n const cycle = visit(prereq);\n if (cycle) return cycle;\n }\n path.pop();\n visiting.delete(issue);\n visited.add(issue);\n return null;\n };\n\n for (const issue of issues) {\n const cycle = visit(issue);\n if (cycle) return cycle;\n }\n return null;\n}\n\nexport function validateBookForStart(\n stateRoot: string,\n book: OrderBook,\n options: {\n issueLookup?: OrderIssueLookup;\n storeStatus?: () => { started: boolean; issueCount: number };\n hasPrd?: (issueId: string) => boolean;\n books?: readonly OrderBook[];\n } = {},\n): OrderBookValidationResult {\n const blocks: OrderBookFinding[] = [];\n const warns: OrderBookFinding[] = [];\n\n const storeStatus = options.issueLookup\n ? null\n : (options.storeStatus ?? orderIssueStoreStatus)();\n const storeUnavailable = storeStatus !== null\n && (!storeStatus.started || storeStatus.issueCount === 0);\n if (storeUnavailable) {\n blocks.push({\n code: 'issue-store-unavailable',\n issue: book.id,\n message: 'Issue store is unavailable or empty — start the dashboard once (`pan up`) to populate the shared issue cache, then retry',\n });\n }\n\n if (book.items.length === 0) {\n blocks.push({\n code: 'empty-book',\n issue: book.id,\n message: 'Order book must contain at least one issue',\n });\n }\n const issueLookup = options.issueLookup ?? liveOrderIssueLookup;\n const ids = new Set<string>();\n for (const item of book.items) {\n ids.add(item.issue.toUpperCase());\n item.prereqs.forEach((prereq) => ids.add(prereq.toUpperCase()));\n }\n const issueState = storeUnavailable ? new Map() : issueLookup([...ids]);\n\n if (!storeUnavailable) {\n for (const item of book.items) {\n const issue = item.issue.toUpperCase();\n const state = issueState.get(issue);\n if (!state?.open) {\n blocks.push({\n code: 'issue-not-open',\n issue,\n message: state ? `${issue} is not open` : `${issue} could not be resolved as an open issue`,\n });\n }\n }\n }\n\n for (const other of options.books ?? listBooks(stateRoot)) {\n if (other.id === book.id || other.status === 'complete') continue;\n for (const item of other.items) {\n const issue = item.issue.toUpperCase();\n if (!ids.has(issue) || !book.items.some((candidate) => candidate.issue.toUpperCase() === issue)) continue;\n blocks.push({\n code: 'duplicate-membership',\n issue,\n message: `${issue} already belongs to non-complete order book ${other.id}`,\n });\n }\n }\n\n const bookIssues = new Set(book.items.map((item) => item.issue.toUpperCase()));\n if (!storeUnavailable) {\n for (const item of book.items) {\n for (const rawPrereq of item.prereqs) {\n const prereq = rawPrereq.toUpperCase();\n if (!bookIssues.has(prereq) && !issueState.has(prereq)) {\n blocks.push({\n code: 'unresolved-prerequisite',\n issue: item.issue,\n message: `${item.issue} prerequisite ${prereq} could not be resolved`,\n });\n }\n }\n }\n }\n\n const cycle = findCycle(book);\n if (cycle) {\n blocks.push({\n code: 'prerequisite-cycle',\n issue: cycle[0]!,\n message: `Prerequisite cycle: ${cycle.join(' → ')}`,\n });\n }\n\n const hasPrd = options.hasPrd ?? ((issueId: string) => hasOrderIssuePrd(stateRoot, issueId));\n for (const item of book.items) {\n if (item.lane !== 'B' || hasPrd(item.issue)) continue;\n const finding: OrderBookFinding = {\n code: 'missing-prd',\n issue: item.issue,\n message: `${item.issue} has no draft PRD or canonical spec`,\n };\n if (item.planAtPickup) warns.push(finding);\n else blocks.push(finding);\n }\n\n return { blocks, warns };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"validate-069_N1e2.js","names":[],"sources":["../../src/lib/cloister/merge-blockers.ts","../../src/lib/orders/validate.ts"],"sourcesContent":["import { getAllReviewStatusesFromDb } from '../overdeck/review-status-sync.js';\n\n/**\n * PRs that passed review but cannot merge for a native gate reason (PAN-1620):\n * merge conflicts, failing checks, a not-mergeable state, or a sibling repo stranded\n * with unmerged commits and no merged review artifact.\n *\n * Reads `review_status` directly from SQLite — NO HTTP — so it works inside a\n * network-sandboxed harness (e.g. codex's bwrap sandbox) where a `curl` to the\n * dashboard's `/api/flywheel/merge-blockers` cannot reach `127.0.0.1:3011`.\n * Shared by the dashboard route and the `pan flywheel merge-blockers` CLI so the\n * two surfaces can never disagree.\n */\nconst MERGE_BLOCKER_TYPES = new Set([\n 'merge_conflict',\n 'failing_checks',\n 'not_mergeable',\n 'unmerged_sibling_repo',\n]);\n\nexport interface MergeBlocker {\n issueId: string;\n prUrl?: string;\n reasons: Array<{ type: string; summary: string }>;\n}\n\nexport function getMergeBlockersPayload(): MergeBlocker[] {\n const statuses = getAllReviewStatusesFromDb();\n const out: MergeBlocker[] = [];\n for (const [issueId, status] of Object.entries(statuses)) {\n if (status.reviewStatus !== 'passed') continue;\n if (status.mergeStatus === 'merged') continue;\n const reasons = (status.blockerReasons ?? []).filter((b) => MERGE_BLOCKER_TYPES.has(b.type));\n if (reasons.length === 0) continue;\n out.push({ issueId, prUrl: status.prUrl, reasons: reasons.map((b) => ({ type: b.type, summary: b.summary })) });\n }\n return out;\n}\n","import { existsSync, readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { OrderBook } from '@overdeck/contracts';\nimport { listBooks, orderIssueStoreStatus } from './resolver.js';\nimport { liveOrderIssueLookup } from './resolver.js';\nimport type {\n OrderBookFinding,\n OrderBookValidationResult,\n OrderIssueLookup,\n} from './types.js';\n\nfunction hasNonEmptyFile(path: string): boolean {\n try {\n return existsSync(path) && statSync(path).isFile() && statSync(path).size > 0;\n } catch {\n return false;\n }\n}\n\nfunction issuePattern(issueId: string): RegExp {\n const escaped = issueId.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n return new RegExp(`(?:^|[-_])${escaped}(?:[-_.]|$)`, 'i');\n}\n\nfunction nonEmptyFileNames(directory: string): string[] {\n if (!existsSync(directory)) return [];\n return readdirSync(directory).filter((name) => hasNonEmptyFile(join(directory, name)));\n}\n\nexport function createOrderPrdLookup(stateRoot: string): (issueId: string) => boolean {\n const draftNames = new Set([\n ...nonEmptyFileNames(join(stateRoot, 'drafts')),\n ...nonEmptyFileNames(join(stateRoot, '.pan', 'drafts')),\n ].map((name) => name.toLowerCase()));\n const specNames = [\n ...nonEmptyFileNames(join(stateRoot, 'specs')),\n ...nonEmptyFileNames(join(stateRoot, '.pan', 'specs')),\n ];\n return (issueId: string) => {\n const lower = issueId.toLowerCase();\n if (draftNames.has(`${lower}.md`)) return true;\n const pattern = issuePattern(issueId);\n return specNames.some((name) => pattern.test(name));\n };\n}\n\nexport function hasOrderIssuePrd(stateRoot: string, issueId: string): boolean {\n const lower = issueId.toLowerCase();\n const draftPaths = [\n join(stateRoot, 'drafts', `${lower}.md`),\n join(stateRoot, '.pan', 'drafts', `${lower}.md`),\n ];\n if (draftPaths.some(hasNonEmptyFile)) return true;\n\n for (const specsDir of [join(stateRoot, 'specs'), join(stateRoot, '.pan', 'specs')]) {\n if (!existsSync(specsDir)) continue;\n const pattern = issuePattern(issueId);\n if (readdirSync(specsDir).some((name) => pattern.test(name) && hasNonEmptyFile(join(specsDir, name)))) {\n return true;\n }\n }\n return false;\n}\n\nfunction findCycle(book: OrderBook): string[] | null {\n const issues = new Set(book.items.map((item) => item.issue.toUpperCase()));\n const edges = new Map(\n book.items.map((item) => [\n item.issue.toUpperCase(),\n item.prereqs.map((prereq) => prereq.toUpperCase()).filter((prereq) => issues.has(prereq)),\n ]),\n );\n const visiting = new Set<string>();\n const visited = new Set<string>();\n const path: string[] = [];\n\n const visit = (issue: string): string[] | null => {\n if (visiting.has(issue)) {\n const start = path.indexOf(issue);\n return [...path.slice(start), issue];\n }\n if (visited.has(issue)) return null;\n visiting.add(issue);\n path.push(issue);\n for (const prereq of edges.get(issue) ?? []) {\n const cycle = visit(prereq);\n if (cycle) return cycle;\n }\n path.pop();\n visiting.delete(issue);\n visited.add(issue);\n return null;\n };\n\n for (const issue of issues) {\n const cycle = visit(issue);\n if (cycle) return cycle;\n }\n return null;\n}\n\nexport function validateBookForStart(\n stateRoot: string,\n book: OrderBook,\n options: {\n issueLookup?: OrderIssueLookup;\n storeStatus?: () => { started: boolean; issueCount: number };\n hasPrd?: (issueId: string) => boolean;\n books?: readonly OrderBook[];\n } = {},\n): OrderBookValidationResult {\n const blocks: OrderBookFinding[] = [];\n const warns: OrderBookFinding[] = [];\n\n const storeStatus = options.issueLookup\n ? null\n : (options.storeStatus ?? orderIssueStoreStatus)();\n const storeUnavailable = storeStatus !== null\n && (!storeStatus.started || storeStatus.issueCount === 0);\n if (storeUnavailable) {\n blocks.push({\n code: 'issue-store-unavailable',\n issue: book.id,\n message: 'Issue store is unavailable or empty — start the dashboard once (`pan up`) to populate the shared issue cache, then retry',\n });\n }\n\n if (book.items.length === 0) {\n blocks.push({\n code: 'empty-book',\n issue: book.id,\n message: 'Order book must contain at least one issue',\n });\n }\n const issueLookup = options.issueLookup ?? liveOrderIssueLookup;\n const ids = new Set<string>();\n for (const item of book.items) {\n ids.add(item.issue.toUpperCase());\n item.prereqs.forEach((prereq) => ids.add(prereq.toUpperCase()));\n }\n const issueState = storeUnavailable ? new Map() : issueLookup([...ids]);\n\n if (!storeUnavailable) {\n for (const item of book.items) {\n const issue = item.issue.toUpperCase();\n const state = issueState.get(issue);\n if (!state?.open) {\n blocks.push({\n code: 'issue-not-open',\n issue,\n message: state ? `${issue} is not open` : `${issue} could not be resolved as an open issue`,\n });\n }\n }\n }\n\n for (const other of options.books ?? listBooks(stateRoot)) {\n if (other.id === book.id || other.status === 'complete') continue;\n for (const item of other.items) {\n const issue = item.issue.toUpperCase();\n if (!ids.has(issue) || !book.items.some((candidate) => candidate.issue.toUpperCase() === issue)) continue;\n blocks.push({\n code: 'duplicate-membership',\n issue,\n message: `${issue} already belongs to non-complete order book ${other.id}`,\n });\n }\n }\n\n const bookIssues = new Set(book.items.map((item) => item.issue.toUpperCase()));\n if (!storeUnavailable) {\n for (const item of book.items) {\n for (const rawPrereq of item.prereqs) {\n const prereq = rawPrereq.toUpperCase();\n if (!bookIssues.has(prereq) && !issueState.has(prereq)) {\n blocks.push({\n code: 'unresolved-prerequisite',\n issue: item.issue,\n message: `${item.issue} prerequisite ${prereq} could not be resolved`,\n });\n }\n }\n }\n }\n\n const cycle = findCycle(book);\n if (cycle) {\n blocks.push({\n code: 'prerequisite-cycle',\n issue: cycle[0]!,\n message: `Prerequisite cycle: ${cycle.join(' → ')}`,\n });\n }\n\n const hasPrd = options.hasPrd ?? ((issueId: string) => hasOrderIssuePrd(stateRoot, issueId));\n for (const item of book.items) {\n if (item.lane !== 'B' || hasPrd(item.issue)) continue;\n const finding: OrderBookFinding = {\n code: 'missing-prd',\n issue: item.issue,\n message: `${item.issue} has no draft PRD or canonical spec`,\n };\n if (item.planAtPickup) warns.push(finding);\n else blocks.push(finding);\n }\n\n return { blocks, warns };\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { n as reconcileInterruptedVerifications, r as runVerificationForIssue } from "./verification-runner-fEY1Qj-l.js";
1
+ import { n as reconcileInterruptedVerifications, r as runVerificationForIssue } from "./verification-runner-fy3wNrWn.js";
2
2
  export { reconcileInterruptedVerifications, runVerificationForIssue };
@@ -1,12 +1,12 @@
1
1
  import { $t as findProjectByPathSync, Li as getOverdeckHome, On as resolveProjectFromIssueSync, Ri as init_paths, Vi as packageRoot, fn as init_projects } from "./config-yaml-Dce9VUd6.js";
2
- import { Gt as messageAgent, Mn as stopAgent, j as setAgentPaused, q as init_agents } from "./agent-state-Ci6PhjOE.js";
2
+ import { Gt as messageAgent, Mn as stopAgent, j as setAgentPaused, q as init_agents } from "./agent-state-B196fj1h.js";
3
3
  import { i as readReviewStatusMap, n as init_review_status_source } from "./review-status-source-Jq0BXmn3.js";
4
4
  import { o as init_lifecycle, s as isXBriefFilename } from "./lifecycle-BSQIQ1Sq.js";
5
5
  import { s as init_io, t as XBriefMergeConflictError } from "./io-Cm4Sf_6P.js";
6
6
  import { d as resolveWorkspaceRepoRootsSync, i as init_project_repos } from "./project-repos-J6jc42uD.js";
7
- import { H as init_review_status_reconcile, O as capturePipelineStageForIssue, V as MERGED_VERIFICATION_REASON, _ as markWorkspaceStuck, d as getReviewStatusSync, k as init_pipeline, p as init_review_status, w as setReviewStatusSync } from "./review-status-BegAr86G.js";
7
+ import { H as init_review_status_reconcile, O as capturePipelineStageForIssue, V as MERGED_VERIFICATION_REASON, _ as markWorkspaceStuck, d as getReviewStatusSync, k as init_pipeline, p as init_review_status, w as setReviewStatusSync } from "./review-status-yY5qt7Rl.js";
8
8
  import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-lbXBFycU.js";
9
- import { n as resolveIssueFeedbackTarget, r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-BcsA_GRV.js";
9
+ import { n as resolveIssueFeedbackTarget, r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-CeCq6EhW.js";
10
10
  import { r as runQualityGates, t as DEFAULT_GATES } from "./validation-Dxdai-37.js";
11
11
  import { n as verificationArtifactPath, r as writeVerificationArtifact, t as readVerificationArtifact } from "./verification-artifact-DhIkPgrP.js";
12
12
  import { n as getXBriefACStatusSync } from "./acceptance-criteria-D-OIjvuX.js";
@@ -895,4 +895,4 @@ function runVerificationForIssueInProcess(issueId, workspacePath, workspaceInfo,
895
895
  //#endregion
896
896
  export { workspaceChangesetHasContent as a, runVerificationForIssueInProcess as i, reconcileInterruptedVerifications as n, runVerificationForIssue as r, changesetHasNoContent as t };
897
897
 
898
- //# sourceMappingURL=verification-runner-fEY1Qj-l.js.map
898
+ //# sourceMappingURL=verification-runner-fy3wNrWn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verification-runner-fEY1Qj-l.js","names":["exec","join","basename","dirname"],"sources":["../../src/lib/cloister/verification-feedback.ts","../../src/lib/cloister/verification-worker-supervisor.ts","../../src/lib/cloister/verification-runner.ts"],"sourcesContent":["export function buildFinalFailureInstructions(issueId: string): string {\n return `## NEEDS-YOU: Verification stuck\n\nAutomatic verification paused after repeated failures so it does not keep spending cycles on the same failing gate.\n\nFix every reported failure, commit and push the corrections, then run \\`pan done ${issueId} -c \"<summary>\"\\`. That command resets verification and returns the latest commit to the normal review, test, and merge pipeline. If you cannot complete the fixes, report the concrete blocker for operator help.`;\n}\n","import { closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { spawn } from 'node:child_process';\n\nimport { getOverdeckHome, packageRoot } from '../paths.js';\nimport type { VerificationRunnerOptions, VerificationRunnerOutcome, WorkspaceInfo } from './verification-types.js';\n\nexport type WorkerState = {\n runId: string;\n issueId: string;\n workspacePath: string;\n pid: number;\n startedAt: string;\n resultPath: string;\n phase: 'queued' | 'running';\n admittedAt: string | null;\n currentGate?: string;\n currentAttempt?: number;\n};\n\nconst POLL_MS = 250;\nconst MAX_RUN_MS = 65 * 60 * 1000;\nconst WORKER_EXIT_POLL_MS = 50;\nconst WORKER_EXIT_GRACE_MS = 1_000;\n\nfunction safeIssueId(issueId: string): string {\n return issueId.toLowerCase().replace(/[^a-z0-9-]/g, '-');\n}\n\nfunction workerDir(issueId: string): string {\n return join(getOverdeckHome(), 'verification-workers', safeIssueId(issueId));\n}\n\nfunction statePath(issueId: string): string {\n return join(workerDir(issueId), 'state.json');\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Kill an expired worker and its gate children. The worker is spawned\n * detached, so it leads its own process group — signal the group first so a\n * mid-gate `npm`/`bun` child dies with it, falling back to the bare pid.\n * Wait for the worker to exit before returning so timeout recovery cannot\n * overlap a fresh verification run with the expired worker.\n */\nasync function killWorkerProcessGroup(pid: number): Promise<boolean> {\n for (const signal of ['SIGTERM', 'SIGKILL'] as const) {\n try {\n process.kill(-pid, signal);\n } catch {\n try { process.kill(pid, signal); } catch { /* already gone */ }\n }\n const deadline = Date.now() + WORKER_EXIT_GRACE_MS;\n while (isProcessAlive(pid) && Date.now() < deadline) {\n await new Promise<void>((resolve) => setTimeout(resolve, WORKER_EXIT_POLL_MS));\n }\n if (!isProcessAlive(pid)) return true;\n }\n return false;\n}\n\nexport function readVerificationWorkerState(issueId: string): WorkerState | null {\n try {\n const parsed = JSON.parse(readFileSync(statePath(issueId), 'utf8')) as Partial<WorkerState>;\n if (\n parsed.issueId !== issueId\n || !Number.isInteger(parsed.pid)\n || typeof parsed.runId !== 'string'\n || typeof parsed.workspacePath !== 'string'\n || typeof parsed.startedAt !== 'string'\n || typeof parsed.resultPath !== 'string'\n ) return null;\n return {\n ...parsed,\n runId: parsed.runId,\n issueId,\n workspacePath: parsed.workspacePath,\n pid: parsed.pid!,\n startedAt: parsed.startedAt,\n resultPath: parsed.resultPath,\n phase: parsed.phase === 'queued' ? 'queued' : 'running',\n admittedAt: parsed.admittedAt === undefined ? parsed.startedAt : parsed.admittedAt,\n };\n } catch {\n return null;\n }\n}\n\nexport function isVerificationWorkerActive(issueId: string): boolean {\n const state = readVerificationWorkerState(issueId);\n return !!state && isProcessAlive(state.pid) && !existsSync(state.resultPath);\n}\n\nfunction writeJsonAtomic(path: string, value: unknown): void {\n const temp = `${path}.${process.pid}.tmp`;\n writeFileSync(temp, `${JSON.stringify(value, null, 2)}\\n`);\n renameSync(temp, path);\n}\n\nexport function verificationWorkerDeadline(state: WorkerState): number | null {\n if (state.phase !== 'running' || !state.admittedAt) return null;\n const admittedAt = Date.parse(state.admittedAt);\n return Number.isFinite(admittedAt) ? admittedAt + MAX_RUN_MS : null;\n}\n\nexport function markVerificationWorkerAdmissionPhase(\n issueId: string,\n update: {\n phase: 'queued' | 'running';\n gateName: string;\n attempt: number;\n admittedAt?: string;\n },\n): void {\n const state = readVerificationWorkerState(issueId);\n if (!state || state.pid !== process.pid) return;\n writeJsonAtomic(statePath(issueId), {\n ...state,\n phase: update.phase,\n admittedAt: update.phase === 'running' ? update.admittedAt ?? null : null,\n currentGate: update.gateName,\n currentAttempt: update.attempt,\n });\n}\n\nasync function waitForResult(state: WorkerState): Promise<VerificationRunnerOutcome> {\n for (;;) {\n if (existsSync(state.resultPath)) {\n return JSON.parse(readFileSync(state.resultPath, 'utf8')) as VerificationRunnerOutcome;\n }\n if (!isProcessAlive(state.pid)) {\n return { outcome: 'error', message: `Verification worker ${state.pid} exited before writing a result` };\n }\n const current = readVerificationWorkerState(state.issueId) ?? state;\n const deadline = verificationWorkerDeadline(current);\n if (deadline !== null && Date.now() >= deadline) {\n // PAN-3674 follow-up: kill the expired worker — it outlived its budget.\n // Leaving it alive stranded PAN-3668 on 2026-08-13: every later attempt\n // re-joined the zombie registration and instantly re-failed on the same\n // deadline, and no fresh worker ever started.\n await killWorkerProcessGroup(state.pid);\n return { outcome: 'error', message: `Verification worker ${state.pid} exceeded ${MAX_RUN_MS}ms after CPU admission` };\n }\n await new Promise<void>((resolve) => setTimeout(resolve, POLL_MS));\n }\n}\n\nexport async function runSupervisedVerification(\n issueId: string,\n workspacePath: string,\n workspaceInfo: WorkspaceInfo,\n logPrefix: string,\n options: Pick<VerificationRunnerOptions, 'syncTargetBranch' | 'skipPlanChecklist'> = {},\n): Promise<VerificationRunnerOutcome> {\n const existing = readVerificationWorkerState(issueId);\n // Never join a worker past its deadline: its result (if it ever lands) is\n // for a stale gate run, and waitForResult would re-fail on the same deadline\n // forever. Kill it and fall through to a fresh worker.\n if (existing && existing.workspacePath === workspacePath && isProcessAlive(existing.pid) && !existsSync(existing.resultPath)) {\n const existingDeadline = verificationWorkerDeadline(existing);\n if (existingDeadline === null || Date.now() < existingDeadline) {\n console.log(`[${logPrefix}] Joining live verification worker ${existing.pid} for ${issueId}`);\n return waitForResult(existing);\n }\n console.warn(`[${logPrefix}] Verification worker ${existing.pid} for ${issueId} is past its deadline — killing it and starting fresh`);\n if (!await killWorkerProcessGroup(existing.pid)) {\n return {\n outcome: 'error',\n message: `Verification worker ${existing.pid} is past its deadline but still alive; refusing to start an overlapping worker`,\n };\n }\n }\n\n const dir = workerDir(issueId);\n mkdirSync(dir, { recursive: true });\n const runId = `${Date.now()}-${process.pid}`;\n const resultPath = join(dir, `result-${runId}.json`);\n const logPath = join(dir, `worker-${runId}.log`);\n const workerPath = process.env.OVERDECK_VERIFICATION_WORKER_PATH\n || join(packageRoot, 'dist', 'verification-worker.js');\n if (!existsSync(workerPath)) {\n return { outcome: 'error', message: `Verification worker bundle missing at ${workerPath}; run npm run build` };\n }\n\n const logFd = openSync(logPath, 'a');\n const child = spawn(process.execPath, [\n workerPath,\n JSON.stringify({ issueId, workspacePath, workspaceInfo, logPrefix, options, runId, resultPath }),\n ], {\n detached: true,\n stdio: ['ignore', logFd, logFd],\n env: { ...process.env, OVERDECK_VERIFICATION_WORKER: '1' },\n });\n closeSync(logFd);\n if (!child.pid) return { outcome: 'error', message: 'Failed to spawn verification worker' };\n\n const state: WorkerState = {\n runId,\n issueId,\n workspacePath,\n pid: child.pid,\n startedAt: new Date().toISOString(),\n resultPath,\n phase: 'queued',\n admittedAt: null,\n };\n writeJsonAtomic(statePath(issueId), state);\n child.unref();\n console.log(`[${logPrefix}] Verification worker ${child.pid} supervising ${issueId}`);\n return waitForResult(state);\n}\n","/**\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 { promisify } from 'util';\nimport { Effect } from 'effect';\nimport { getReviewStatusSync, markWorkspaceStuck, setReviewStatusSync } from '../review-status.js';\nimport { MERGED_VERIFICATION_REASON } from '../review-status-reconcile.js';\nimport { runQualityGates, DEFAULT_GATES } from './validation.js';\nimport {\n readVerificationArtifact,\n verificationArtifactPath,\n writeVerificationArtifact,\n} from './verification-artifact.js';\nimport { buildFinalFailureInstructions } from './verification-feedback.js';\nimport {\n isVerificationWorkerActive,\n markVerificationWorkerAdmissionPhase,\n runSupervisedVerification,\n} from './verification-worker-supervisor.js';\nimport type {\n VerificationRunnerOptions,\n VerificationRunnerOutcome,\n WorkspaceInfo,\n} from './verification-types.js';\nimport { readReviewStatusMap } from './review-status-source.js';\nimport { writeFeedbackFile } from './feedback-writer.js';\nimport { resolveIssueFeedbackTarget, surfaceIssueFeedbackNeedsYou } from './feedback-target.js';\nimport { messageAgent, setAgentPaused, stopAgent } from '../agents.js';\nimport { findProjectByPathSync, resolveProjectFromIssueSync } from '../projects.js';\nimport { resolveWorkspaceRepoRootsSync } from '../project-repos.js';\nimport { getXBriefACStatusSync } from '../xbrief/acceptance-criteria.js';\nimport { XBriefMergeConflictError } from '../xbrief/io.js';\nimport { isXBriefFilename } from '../xbrief/lifecycle.js';\nimport { checkIncompletePlanItemsPromise } from '../work/done-preflight.js';\nimport { capturePipelineStageForIssue } from '../telemetry/pipeline.js';\nimport type { TemplatePlaceholders } from '../workspace-config.js';\nimport type { HeadAnchor } from '../git-utils.js';\n\nconst execAsync = promisify(exec);\n\nexport const VERIFICATION_MAX_CYCLES = 3;\nconst NO_PROGRESS_REPEAT_THRESHOLD = 2;\n\nexport type { VerificationRunnerOptions, VerificationRunnerOutcome, WorkspaceInfo } from './verification-types.js';\n\nfunction skipMergedVerification(\n issueId: string,\n logPrefix: string,\n status = getReviewStatusSync(issueId),\n): VerificationRunnerOutcome | null {\n if (status?.mergeStatus !== 'merged') return null;\n\n setReviewStatusSync(issueId, {\n verificationStatus: 'skipped',\n verificationNotes: MERGED_VERIFICATION_REASON,\n });\n console.log(`[${logPrefix}] Skipping pre-merge verification for ${issueId}: ${MERGED_VERIFICATION_REASON}`);\n return { outcome: 'skipped', reason: MERGED_VERIFICATION_REASON };\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 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 if (skipMergedVerification(issueId, logPrefix)) return;\n\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\n/**\n * Boot reconciliation for verifications no worker owns. Live supervised workers\n * survive dashboard restarts and retain ownership of their running status.\n * A running status without a live worker is orphaned, so reset it to pending\n * and finalize the artifact rather than leaving the issue wedged forever.\n *\n * PAN-3339: `pending` on an already-merged issue is the other ownerless shape.\n * \"Verification re-runs on the next cycle\" is true only while the review\n * pipeline can still dispatch one; after merge there is no next cycle, so the\n * verdict sits at `pending` and DoD row 3 blocks close-out forever. The write\n * door settles this at the merge write going forward — this sweep heals rows\n * that were already stranded before that guard existed.\n */\nexport function reconcileInterruptedVerifications(logPrefix = 'boot-reconciliation'): number {\n let reset = 0;\n try {\n const statuses = readReviewStatusMap() ?? {};\n for (const [issueId, status] of Object.entries(statuses)) {\n const verificationStatus = (status as { verificationStatus?: string }).verificationStatus;\n if (\n verificationStatus === 'pending' &&\n (status as { mergeStatus?: string }).mergeStatus === 'merged'\n ) {\n setReviewStatusSync(issueId, {\n verificationStatus: 'skipped',\n verificationNotes: MERGED_VERIFICATION_REASON,\n });\n console.log(`[${logPrefix}] settled ownerless pending verification for merged ${issueId} (PAN-3339)`);\n continue;\n }\n if (verificationStatus !== 'running') continue;\n if (isVerificationWorkerActive(issueId)) {\n console.log(`[${logPrefix}] preserved live supervised verification for ${issueId}`);\n continue;\n }\n setReviewStatusSync(issueId, {\n verificationStatus: 'pending',\n verificationNotes: 'The supervised verification worker stopped before recording a result; verification re-runs on the next cycle.',\n });\n reset += 1;\n try {\n const resolved = resolveProjectFromIssueSync(issueId);\n const workspacePath = resolved\n ? join(resolved.projectPath, 'workspaces', `feature-${issueId.toLowerCase()}`)\n : null;\n const artifact = workspacePath ? readVerificationArtifact(workspacePath) : null;\n if (workspacePath && artifact?.outcome === 'running') {\n writeVerificationArtifact(workspacePath, issueId, [\n ...artifact.gates.map((gate) => ({\n name: gate.name,\n passed: gate.passed,\n required: gate.required,\n output: gate.output ?? '',\n durationMs: gate.durationMs,\n ...(gate.error ? { error: gate.error } : {}),\n })),\n {\n name: artifact.currentGate ?? 'interrupted',\n passed: false,\n required: true,\n output: 'The supervised verification worker stopped unexpectedly before this gate finished.',\n durationMs: 0,\n error: 'supervised verification worker stopped unexpectedly',\n },\n ]);\n }\n } catch { /* artifact finalization is best-effort */ }\n console.log(`[${logPrefix}] reset stale running verification for ${issueId} (PAN-2669)`);\n }\n } catch (err) {\n console.warn(`[${logPrefix}] interrupted-verification sweep failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n return reset;\n}\n\nasync function deliverVerificationFeedback(\n issueId: string,\n message: string,\n details: Record<string, unknown>,\n logPrefix: string,\n): Promise<void> {\n if (skipMergedVerification(issueId, logPrefix)) return;\n\n const target = await resolveIssueFeedbackTarget(issueId);\n if (skipMergedVerification(issueId, logPrefix)) return;\n\n if ('agentId' in target) {\n // PAN-2668: verification feedback owes rework — a stopped-by-user agent\n // with a completed handoff is re-driven, not silently queued mail.\n await messageAgent(target.agentId, message, 'internal', { owesRework: true });\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 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/, task state, xBRIEF) 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/') && !isXBriefFilename(f));\n return content.length === 0;\n}\n\n/**\n * Return whether any actual workspace repository contains implementation\n * changes. `undefined` means at least one repo diff failed and no positive\n * evidence was found, so callers must conservatively skip the empty guard.\n */\nexport async function workspaceChangesetHasContent(\n issueId: string,\n workspacePath: string,\n): Promise<boolean | undefined> {\n const roots = resolveWorkspaceRepoRootsSync(issueId, workspacePath);\n let diffFailed = false;\n\n for (const root of roots) {\n try {\n const { stdout } = await execAsync(\n `git diff --name-only origin/${root.targetBranch}...HEAD`,\n { cwd: root.dir, encoding: 'utf-8', timeout: 15_000 },\n );\n if (!changesetHasNoContent(stdout.split('\\n'))) return true;\n } catch {\n diffFailed = true;\n }\n }\n\n return diffFailed ? undefined : false;\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 mergedOutcome = skipMergedVerification(issueId, logPrefix, currentStatus);\n if (mergedOutcome) return mergedOutcome;\n\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 repoRoots = resolveWorkspaceRepoRootsSync(issueId, workspacePath);\n const isPolyrepo = repoRoots.some(root => root.isPolyrepo);\n\n // === Sync target branch ===\n if (options.syncTargetBranch !== false) {\n if (repoRoots.length === 0) {\n console.log(`[${logPrefix}] No git directories found in workspace ${workspacePath} — skipping sync`);\n } else {\n const syncResults: SyncResult[] = [];\n for (const root of repoRoots) {\n const repoName = isPolyrepo ? root.repoKey : undefined;\n const displayName = repoName || basename(workspacePath);\n console.log(`[${logPrefix}] Syncing ${root.targetBranch} into ${displayName} for ${issueId}...`);\n syncResults.push(await syncSingleRepo(root.dir, root.targetBranch));\n }\n\n const postSyncMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postSyncMergedOutcome) return postSyncMergedOutcome;\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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\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 const postSyncMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postSyncMergedOutcome) return postSyncMergedOutcome;\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/${repoRoots[0]?.targetBranch ?? 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 // PAN-2665: write the artifact incrementally so the dashboard's Test/Lint\n // node shows gates completing live. Every write is best-effort — a failed\n // artifact write must never fail verification itself.\n const liveGateResults: import('./validation.js').QualityGateResult[] = [];\n let liveGateName: string | undefined;\n let liveGateTail = '';\n let lastTailWriteMs = 0;\n const writeLiveArtifact = () => {\n try {\n writeVerificationArtifact(workspacePath, issueId, liveGateResults, {\n currentGate: liveGateName,\n currentGateOutput: liveGateTail || undefined,\n });\n } catch { /* best-effort */ }\n };\n writeLiveArtifact();\n\n const gateResults = await Effect.runPromise(runQualityGates(gates, workspacePath, 'pre_push', {\n issueId,\n isRemote: workspaceInfo.isRemote,\n vmName: workspaceInfo.vmName,\n placeholders,\n ...(options.onGateLog ? { onLog: options.onGateLog } : {}),\n onAdmissionPhase: (state) => markVerificationWorkerAdmissionPhase(issueId, state),\n onGateStart: (name) => {\n liveGateName = name;\n liveGateTail = '';\n writeLiveArtifact();\n },\n onGateOutput: (_name, chunk) => {\n // Rolling ANSI-stripped tail, flushed at most once per second so the\n // Test/Lint panel streams the running gate without hammering the disk.\n // eslint-disable-next-line no-control-regex\n liveGateTail = (liveGateTail + chunk.replace(/\\u001b\\[[0-9;]*[A-Za-z]/g, '')).slice(-4000);\n const now = Date.now();\n if (now - lastTailWriteMs >= 1000) {\n lastTailWriteMs = now;\n writeLiveArtifact();\n }\n },\n onGateResult: (result) => {\n liveGateResults.push(result);\n liveGateName = undefined;\n liveGateTail = '';\n writeLiveArtifact();\n },\n }));\n\n const postGateMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postGateMergedOutcome) return postGateMergedOutcome;\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 // Finalize the live artifact so the Test/Lint node doesn't stay stuck at\n // \"running\" — the infra gate's error explains what could not run.\n try {\n writeVerificationArtifact(workspacePath, issueId, gateResults);\n } catch { /* best-effort */ }\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 const rebuildResult = await Effect.runPromise(rebuildWorkspaceStack(issueId, {\n onProgress: (m) => console.log(`[${logPrefix}] ${issueId} stack rebuild: ${m}`),\n }));\n if (!rebuildResult.success) {\n console.warn(`[${logPrefix}] Stack rebuild for ${issueId} failed: ${rebuildResult.error}`);\n }\n } catch (err) {\n console.warn(`[${logPrefix}] Could not settle 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 // Durable terminal record of this gate run, surfaced by the issue tree's\n // Test/Lint node (replaces the incremental 'running' writes above).\n try {\n writeVerificationArtifact(workspacePath, issueId, gateResults);\n } catch (artifactErr: any) {\n console.warn(`[${logPrefix}] Could not write verification artifact for ${issueId}: ${artifactErr.message}`);\n }\n\n if (failedGate) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = failedGate.name;\n const fullOutputPath = verificationArtifactPath(workspacePath);\n const summary = `Verification FAILED at ${failedCheck} (${failedGate.durationMs}ms).\\n\\nFull gate output: ${fullOutputPath}`;\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 complete gate output at \\`${fullOutputPath}\\` 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\\nThe command can run for several minutes. A yielded exec result or background-terminal notice means it is still running, not that it succeeded. Poll the same terminal until it exits, inspect the real exit code, then confirm \\`pan show ${issueId}\\` or \\`pan review pending\\` shows the issue re-entered review. Do NOT stop between steps or after pushing; stop only after exit code 0 and the observed pipeline state change.`;\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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\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. If the exec yields to a background terminal, poll that same terminal until it exits; then require exit code 0 and confirm pan show ${issueId} or pan review pending shows re-entry before declaring success.`;\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 // xBRIEF AC gate: check all acceptance criteria are completed (runs after quality gates)\n // Wrap in try-catch to detect merge conflict markers in the xBRIEF document and send\n // actionable feedback rather than falling through to a generic infrastructure error.\n let acStatus: ReturnType<typeof getXBriefACStatusSync>;\n try {\n acStatus = getXBriefACStatusSync(workspacePath);\n } catch (xbriefErr: any) {\n if (xbriefErr instanceof XBriefMergeConflictError) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'vbrief-conflicts';\n const summary = `xBRIEF 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 xBRIEF spec BEFORE resubmitting\\n\\n1. Open the xBRIEF 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: `xBRIEF 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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — the xBRIEF document 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 xBRIEF conflict feedback for ${issueId}:`, feedbackErr);\n }\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n throw xbriefErr;\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 task with \\`pan task close\\` — the canonical writer publishes the close and AC statuses sync 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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\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 const taskBlockers = options.skipPlanChecklist\n ? []\n : await checkIncompletePlanItemsPromise(workspacePath, issueId);\n const postChecklistMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postChecklistMergedOutcome) return postChecklistMergedOutcome;\n\n if (taskBlockers.length > 0) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'incomplete-plan-items';\n const itemIds = taskBlockers\n .map((line) => line.match(/^\\s+-\\s+(\\S+)/)?.[1])\n .filter((id): id is string => Boolean(id));\n const summary = `Checklist completion check FAILED — ${itemIds.length} incomplete item(s) remain:\\n\\n${taskBlockers.join('\\n')}`;\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\\nComplete each listed item with \\`pan task done ${issueId} <item>\\` after committing and pushing its implementation, then resubmit the review request.`;\n\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `Checklist completion check FAILED — ${itemIds.length} incomplete item(s) remain (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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — ${itemIds.length} incomplete item(s) remain.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nRead the file, complete every listed item with pan task after committing and pushing, then request a new review with pan review request.`;\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 open-task 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/xBRIEF task state);\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 const changesetHasContent = await workspaceChangesetHasContent(issueId, workspacePath);\n const postDiffMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postDiffMergedOutcome) return postDiffMergedOutcome;\n\n if (changesetHasContent === false) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'empty-changeset';\n const comparedTargets = repoRoots.map(root => `${root.repoKey}:origin/${root.targetBranch}`).join(', ');\n const summary = `Branch has no implementation — only pipeline artifacts (.pan/xBRIEF task state) changed across workspace repos vs ${comparedTargets}. 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/xBRIEF task state changed across ${comparedTargets}).\\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: comparedTargets,\n }, logPrefix);\n console.error(`[${logPrefix}] VERIFICATION FAILED for ${issueId}: empty-changeset (no content files across ${comparedTargets})`);\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 if (changesetHasContent === undefined) {\n console.warn(`[${logPrefix}] empty-changeset guard skipped (one or more repo diffs failed)`);\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 // PAN-2948: polyrepo-aware — the wrapper repo's HEAD never changes, so\n // snapshotting it would make this comparison report \"no drift\" forever.\n let lastVerifiedCommit: HeadAnchor | undefined;\n try {\n const { snapshotWorkspaceHeadsPromise } = await import('../git-utils.js');\n lastVerifiedCommit = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);\n } catch { /* non-fatal — skip optimization if we can't get HEAD */ }\n\n const prePassMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (prePassMergedOutcome) return prePassMergedOutcome;\n\n setReviewStatusSync(issueId, {\n verificationStatus: 'passed',\n verificationNotes: undefined,\n ...(lastVerifiedCommit ? { lastVerifiedCommit } : {}),\n });\n void capturePipelineStageForIssue(issueId, 'verification_passed');\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 const errorMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (errorMergedOutcome) return errorMergedOutcome;\n\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 process.env.OVERDECK_VERIFICATION_WORKER === '1'\n ? runVerificationForIssueInProcess(issueId, workspacePath, workspaceInfo, logPrefix, options)\n : Effect.promise(() => runSupervisedVerification(issueId, workspacePath, workspaceInfo, logPrefix, options));\n}\n\nexport function runVerificationForIssueInProcess(\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-fy3wNrWn.js","names":["exec","join","basename","dirname"],"sources":["../../src/lib/cloister/verification-feedback.ts","../../src/lib/cloister/verification-worker-supervisor.ts","../../src/lib/cloister/verification-runner.ts"],"sourcesContent":["export function buildFinalFailureInstructions(issueId: string): string {\n return `## NEEDS-YOU: Verification stuck\n\nAutomatic verification paused after repeated failures so it does not keep spending cycles on the same failing gate.\n\nFix every reported failure, commit and push the corrections, then run \\`pan done ${issueId} -c \"<summary>\"\\`. That command resets verification and returns the latest commit to the normal review, test, and merge pipeline. If you cannot complete the fixes, report the concrete blocker for operator help.`;\n}\n","import { closeSync, existsSync, mkdirSync, openSync, readFileSync, renameSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { spawn } from 'node:child_process';\n\nimport { getOverdeckHome, packageRoot } from '../paths.js';\nimport type { VerificationRunnerOptions, VerificationRunnerOutcome, WorkspaceInfo } from './verification-types.js';\n\nexport type WorkerState = {\n runId: string;\n issueId: string;\n workspacePath: string;\n pid: number;\n startedAt: string;\n resultPath: string;\n phase: 'queued' | 'running';\n admittedAt: string | null;\n currentGate?: string;\n currentAttempt?: number;\n};\n\nconst POLL_MS = 250;\nconst MAX_RUN_MS = 65 * 60 * 1000;\nconst WORKER_EXIT_POLL_MS = 50;\nconst WORKER_EXIT_GRACE_MS = 1_000;\n\nfunction safeIssueId(issueId: string): string {\n return issueId.toLowerCase().replace(/[^a-z0-9-]/g, '-');\n}\n\nfunction workerDir(issueId: string): string {\n return join(getOverdeckHome(), 'verification-workers', safeIssueId(issueId));\n}\n\nfunction statePath(issueId: string): string {\n return join(workerDir(issueId), 'state.json');\n}\n\nfunction isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Kill an expired worker and its gate children. The worker is spawned\n * detached, so it leads its own process group — signal the group first so a\n * mid-gate `npm`/`bun` child dies with it, falling back to the bare pid.\n * Wait for the worker to exit before returning so timeout recovery cannot\n * overlap a fresh verification run with the expired worker.\n */\nasync function killWorkerProcessGroup(pid: number): Promise<boolean> {\n for (const signal of ['SIGTERM', 'SIGKILL'] as const) {\n try {\n process.kill(-pid, signal);\n } catch {\n try { process.kill(pid, signal); } catch { /* already gone */ }\n }\n const deadline = Date.now() + WORKER_EXIT_GRACE_MS;\n while (isProcessAlive(pid) && Date.now() < deadline) {\n await new Promise<void>((resolve) => setTimeout(resolve, WORKER_EXIT_POLL_MS));\n }\n if (!isProcessAlive(pid)) return true;\n }\n return false;\n}\n\nexport function readVerificationWorkerState(issueId: string): WorkerState | null {\n try {\n const parsed = JSON.parse(readFileSync(statePath(issueId), 'utf8')) as Partial<WorkerState>;\n if (\n parsed.issueId !== issueId\n || !Number.isInteger(parsed.pid)\n || typeof parsed.runId !== 'string'\n || typeof parsed.workspacePath !== 'string'\n || typeof parsed.startedAt !== 'string'\n || typeof parsed.resultPath !== 'string'\n ) return null;\n return {\n ...parsed,\n runId: parsed.runId,\n issueId,\n workspacePath: parsed.workspacePath,\n pid: parsed.pid!,\n startedAt: parsed.startedAt,\n resultPath: parsed.resultPath,\n phase: parsed.phase === 'queued' ? 'queued' : 'running',\n admittedAt: parsed.admittedAt === undefined ? parsed.startedAt : parsed.admittedAt,\n };\n } catch {\n return null;\n }\n}\n\nexport function isVerificationWorkerActive(issueId: string): boolean {\n const state = readVerificationWorkerState(issueId);\n return !!state && isProcessAlive(state.pid) && !existsSync(state.resultPath);\n}\n\nfunction writeJsonAtomic(path: string, value: unknown): void {\n const temp = `${path}.${process.pid}.tmp`;\n writeFileSync(temp, `${JSON.stringify(value, null, 2)}\\n`);\n renameSync(temp, path);\n}\n\nexport function verificationWorkerDeadline(state: WorkerState): number | null {\n if (state.phase !== 'running' || !state.admittedAt) return null;\n const admittedAt = Date.parse(state.admittedAt);\n return Number.isFinite(admittedAt) ? admittedAt + MAX_RUN_MS : null;\n}\n\nexport function markVerificationWorkerAdmissionPhase(\n issueId: string,\n update: {\n phase: 'queued' | 'running';\n gateName: string;\n attempt: number;\n admittedAt?: string;\n },\n): void {\n const state = readVerificationWorkerState(issueId);\n if (!state || state.pid !== process.pid) return;\n writeJsonAtomic(statePath(issueId), {\n ...state,\n phase: update.phase,\n admittedAt: update.phase === 'running' ? update.admittedAt ?? null : null,\n currentGate: update.gateName,\n currentAttempt: update.attempt,\n });\n}\n\nasync function waitForResult(state: WorkerState): Promise<VerificationRunnerOutcome> {\n for (;;) {\n if (existsSync(state.resultPath)) {\n return JSON.parse(readFileSync(state.resultPath, 'utf8')) as VerificationRunnerOutcome;\n }\n if (!isProcessAlive(state.pid)) {\n return { outcome: 'error', message: `Verification worker ${state.pid} exited before writing a result` };\n }\n const current = readVerificationWorkerState(state.issueId) ?? state;\n const deadline = verificationWorkerDeadline(current);\n if (deadline !== null && Date.now() >= deadline) {\n // PAN-3674 follow-up: kill the expired worker — it outlived its budget.\n // Leaving it alive stranded PAN-3668 on 2026-08-13: every later attempt\n // re-joined the zombie registration and instantly re-failed on the same\n // deadline, and no fresh worker ever started.\n await killWorkerProcessGroup(state.pid);\n return { outcome: 'error', message: `Verification worker ${state.pid} exceeded ${MAX_RUN_MS}ms after CPU admission` };\n }\n await new Promise<void>((resolve) => setTimeout(resolve, POLL_MS));\n }\n}\n\nexport async function runSupervisedVerification(\n issueId: string,\n workspacePath: string,\n workspaceInfo: WorkspaceInfo,\n logPrefix: string,\n options: Pick<VerificationRunnerOptions, 'syncTargetBranch' | 'skipPlanChecklist'> = {},\n): Promise<VerificationRunnerOutcome> {\n const existing = readVerificationWorkerState(issueId);\n // Never join a worker past its deadline: its result (if it ever lands) is\n // for a stale gate run, and waitForResult would re-fail on the same deadline\n // forever. Kill it and fall through to a fresh worker.\n if (existing && existing.workspacePath === workspacePath && isProcessAlive(existing.pid) && !existsSync(existing.resultPath)) {\n const existingDeadline = verificationWorkerDeadline(existing);\n if (existingDeadline === null || Date.now() < existingDeadline) {\n console.log(`[${logPrefix}] Joining live verification worker ${existing.pid} for ${issueId}`);\n return waitForResult(existing);\n }\n console.warn(`[${logPrefix}] Verification worker ${existing.pid} for ${issueId} is past its deadline — killing it and starting fresh`);\n if (!await killWorkerProcessGroup(existing.pid)) {\n return {\n outcome: 'error',\n message: `Verification worker ${existing.pid} is past its deadline but still alive; refusing to start an overlapping worker`,\n };\n }\n }\n\n const dir = workerDir(issueId);\n mkdirSync(dir, { recursive: true });\n const runId = `${Date.now()}-${process.pid}`;\n const resultPath = join(dir, `result-${runId}.json`);\n const logPath = join(dir, `worker-${runId}.log`);\n const workerPath = process.env.OVERDECK_VERIFICATION_WORKER_PATH\n || join(packageRoot, 'dist', 'verification-worker.js');\n if (!existsSync(workerPath)) {\n return { outcome: 'error', message: `Verification worker bundle missing at ${workerPath}; run npm run build` };\n }\n\n const logFd = openSync(logPath, 'a');\n const child = spawn(process.execPath, [\n workerPath,\n JSON.stringify({ issueId, workspacePath, workspaceInfo, logPrefix, options, runId, resultPath }),\n ], {\n detached: true,\n stdio: ['ignore', logFd, logFd],\n env: { ...process.env, OVERDECK_VERIFICATION_WORKER: '1' },\n });\n closeSync(logFd);\n if (!child.pid) return { outcome: 'error', message: 'Failed to spawn verification worker' };\n\n const state: WorkerState = {\n runId,\n issueId,\n workspacePath,\n pid: child.pid,\n startedAt: new Date().toISOString(),\n resultPath,\n phase: 'queued',\n admittedAt: null,\n };\n writeJsonAtomic(statePath(issueId), state);\n child.unref();\n console.log(`[${logPrefix}] Verification worker ${child.pid} supervising ${issueId}`);\n return waitForResult(state);\n}\n","/**\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 { promisify } from 'util';\nimport { Effect } from 'effect';\nimport { getReviewStatusSync, markWorkspaceStuck, setReviewStatusSync } from '../review-status.js';\nimport { MERGED_VERIFICATION_REASON } from '../review-status-reconcile.js';\nimport { runQualityGates, DEFAULT_GATES } from './validation.js';\nimport {\n readVerificationArtifact,\n verificationArtifactPath,\n writeVerificationArtifact,\n} from './verification-artifact.js';\nimport { buildFinalFailureInstructions } from './verification-feedback.js';\nimport {\n isVerificationWorkerActive,\n markVerificationWorkerAdmissionPhase,\n runSupervisedVerification,\n} from './verification-worker-supervisor.js';\nimport type {\n VerificationRunnerOptions,\n VerificationRunnerOutcome,\n WorkspaceInfo,\n} from './verification-types.js';\nimport { readReviewStatusMap } from './review-status-source.js';\nimport { writeFeedbackFile } from './feedback-writer.js';\nimport { resolveIssueFeedbackTarget, surfaceIssueFeedbackNeedsYou } from './feedback-target.js';\nimport { messageAgent, setAgentPaused, stopAgent } from '../agents.js';\nimport { findProjectByPathSync, resolveProjectFromIssueSync } from '../projects.js';\nimport { resolveWorkspaceRepoRootsSync } from '../project-repos.js';\nimport { getXBriefACStatusSync } from '../xbrief/acceptance-criteria.js';\nimport { XBriefMergeConflictError } from '../xbrief/io.js';\nimport { isXBriefFilename } from '../xbrief/lifecycle.js';\nimport { checkIncompletePlanItemsPromise } from '../work/done-preflight.js';\nimport { capturePipelineStageForIssue } from '../telemetry/pipeline.js';\nimport type { TemplatePlaceholders } from '../workspace-config.js';\nimport type { HeadAnchor } from '../git-utils.js';\n\nconst execAsync = promisify(exec);\n\nexport const VERIFICATION_MAX_CYCLES = 3;\nconst NO_PROGRESS_REPEAT_THRESHOLD = 2;\n\nexport type { VerificationRunnerOptions, VerificationRunnerOutcome, WorkspaceInfo } from './verification-types.js';\n\nfunction skipMergedVerification(\n issueId: string,\n logPrefix: string,\n status = getReviewStatusSync(issueId),\n): VerificationRunnerOutcome | null {\n if (status?.mergeStatus !== 'merged') return null;\n\n setReviewStatusSync(issueId, {\n verificationStatus: 'skipped',\n verificationNotes: MERGED_VERIFICATION_REASON,\n });\n console.log(`[${logPrefix}] Skipping pre-merge verification for ${issueId}: ${MERGED_VERIFICATION_REASON}`);\n return { outcome: 'skipped', reason: MERGED_VERIFICATION_REASON };\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 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 if (skipMergedVerification(issueId, logPrefix)) return;\n\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\n/**\n * Boot reconciliation for verifications no worker owns. Live supervised workers\n * survive dashboard restarts and retain ownership of their running status.\n * A running status without a live worker is orphaned, so reset it to pending\n * and finalize the artifact rather than leaving the issue wedged forever.\n *\n * PAN-3339: `pending` on an already-merged issue is the other ownerless shape.\n * \"Verification re-runs on the next cycle\" is true only while the review\n * pipeline can still dispatch one; after merge there is no next cycle, so the\n * verdict sits at `pending` and DoD row 3 blocks close-out forever. The write\n * door settles this at the merge write going forward — this sweep heals rows\n * that were already stranded before that guard existed.\n */\nexport function reconcileInterruptedVerifications(logPrefix = 'boot-reconciliation'): number {\n let reset = 0;\n try {\n const statuses = readReviewStatusMap() ?? {};\n for (const [issueId, status] of Object.entries(statuses)) {\n const verificationStatus = (status as { verificationStatus?: string }).verificationStatus;\n if (\n verificationStatus === 'pending' &&\n (status as { mergeStatus?: string }).mergeStatus === 'merged'\n ) {\n setReviewStatusSync(issueId, {\n verificationStatus: 'skipped',\n verificationNotes: MERGED_VERIFICATION_REASON,\n });\n console.log(`[${logPrefix}] settled ownerless pending verification for merged ${issueId} (PAN-3339)`);\n continue;\n }\n if (verificationStatus !== 'running') continue;\n if (isVerificationWorkerActive(issueId)) {\n console.log(`[${logPrefix}] preserved live supervised verification for ${issueId}`);\n continue;\n }\n setReviewStatusSync(issueId, {\n verificationStatus: 'pending',\n verificationNotes: 'The supervised verification worker stopped before recording a result; verification re-runs on the next cycle.',\n });\n reset += 1;\n try {\n const resolved = resolveProjectFromIssueSync(issueId);\n const workspacePath = resolved\n ? join(resolved.projectPath, 'workspaces', `feature-${issueId.toLowerCase()}`)\n : null;\n const artifact = workspacePath ? readVerificationArtifact(workspacePath) : null;\n if (workspacePath && artifact?.outcome === 'running') {\n writeVerificationArtifact(workspacePath, issueId, [\n ...artifact.gates.map((gate) => ({\n name: gate.name,\n passed: gate.passed,\n required: gate.required,\n output: gate.output ?? '',\n durationMs: gate.durationMs,\n ...(gate.error ? { error: gate.error } : {}),\n })),\n {\n name: artifact.currentGate ?? 'interrupted',\n passed: false,\n required: true,\n output: 'The supervised verification worker stopped unexpectedly before this gate finished.',\n durationMs: 0,\n error: 'supervised verification worker stopped unexpectedly',\n },\n ]);\n }\n } catch { /* artifact finalization is best-effort */ }\n console.log(`[${logPrefix}] reset stale running verification for ${issueId} (PAN-2669)`);\n }\n } catch (err) {\n console.warn(`[${logPrefix}] interrupted-verification sweep failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n return reset;\n}\n\nasync function deliverVerificationFeedback(\n issueId: string,\n message: string,\n details: Record<string, unknown>,\n logPrefix: string,\n): Promise<void> {\n if (skipMergedVerification(issueId, logPrefix)) return;\n\n const target = await resolveIssueFeedbackTarget(issueId);\n if (skipMergedVerification(issueId, logPrefix)) return;\n\n if ('agentId' in target) {\n // PAN-2668: verification feedback owes rework — a stopped-by-user agent\n // with a completed handoff is re-driven, not silently queued mail.\n await messageAgent(target.agentId, message, 'internal', { owesRework: true });\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 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/, task state, xBRIEF) 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/') && !isXBriefFilename(f));\n return content.length === 0;\n}\n\n/**\n * Return whether any actual workspace repository contains implementation\n * changes. `undefined` means at least one repo diff failed and no positive\n * evidence was found, so callers must conservatively skip the empty guard.\n */\nexport async function workspaceChangesetHasContent(\n issueId: string,\n workspacePath: string,\n): Promise<boolean | undefined> {\n const roots = resolveWorkspaceRepoRootsSync(issueId, workspacePath);\n let diffFailed = false;\n\n for (const root of roots) {\n try {\n const { stdout } = await execAsync(\n `git diff --name-only origin/${root.targetBranch}...HEAD`,\n { cwd: root.dir, encoding: 'utf-8', timeout: 15_000 },\n );\n if (!changesetHasNoContent(stdout.split('\\n'))) return true;\n } catch {\n diffFailed = true;\n }\n }\n\n return diffFailed ? undefined : false;\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 mergedOutcome = skipMergedVerification(issueId, logPrefix, currentStatus);\n if (mergedOutcome) return mergedOutcome;\n\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 repoRoots = resolveWorkspaceRepoRootsSync(issueId, workspacePath);\n const isPolyrepo = repoRoots.some(root => root.isPolyrepo);\n\n // === Sync target branch ===\n if (options.syncTargetBranch !== false) {\n if (repoRoots.length === 0) {\n console.log(`[${logPrefix}] No git directories found in workspace ${workspacePath} — skipping sync`);\n } else {\n const syncResults: SyncResult[] = [];\n for (const root of repoRoots) {\n const repoName = isPolyrepo ? root.repoKey : undefined;\n const displayName = repoName || basename(workspacePath);\n console.log(`[${logPrefix}] Syncing ${root.targetBranch} into ${displayName} for ${issueId}...`);\n syncResults.push(await syncSingleRepo(root.dir, root.targetBranch));\n }\n\n const postSyncMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postSyncMergedOutcome) return postSyncMergedOutcome;\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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\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 const postSyncMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postSyncMergedOutcome) return postSyncMergedOutcome;\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/${repoRoots[0]?.targetBranch ?? 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 // PAN-2665: write the artifact incrementally so the dashboard's Test/Lint\n // node shows gates completing live. Every write is best-effort — a failed\n // artifact write must never fail verification itself.\n const liveGateResults: import('./validation.js').QualityGateResult[] = [];\n let liveGateName: string | undefined;\n let liveGateTail = '';\n let lastTailWriteMs = 0;\n const writeLiveArtifact = () => {\n try {\n writeVerificationArtifact(workspacePath, issueId, liveGateResults, {\n currentGate: liveGateName,\n currentGateOutput: liveGateTail || undefined,\n });\n } catch { /* best-effort */ }\n };\n writeLiveArtifact();\n\n const gateResults = await Effect.runPromise(runQualityGates(gates, workspacePath, 'pre_push', {\n issueId,\n isRemote: workspaceInfo.isRemote,\n vmName: workspaceInfo.vmName,\n placeholders,\n ...(options.onGateLog ? { onLog: options.onGateLog } : {}),\n onAdmissionPhase: (state) => markVerificationWorkerAdmissionPhase(issueId, state),\n onGateStart: (name) => {\n liveGateName = name;\n liveGateTail = '';\n writeLiveArtifact();\n },\n onGateOutput: (_name, chunk) => {\n // Rolling ANSI-stripped tail, flushed at most once per second so the\n // Test/Lint panel streams the running gate without hammering the disk.\n // eslint-disable-next-line no-control-regex\n liveGateTail = (liveGateTail + chunk.replace(/\\u001b\\[[0-9;]*[A-Za-z]/g, '')).slice(-4000);\n const now = Date.now();\n if (now - lastTailWriteMs >= 1000) {\n lastTailWriteMs = now;\n writeLiveArtifact();\n }\n },\n onGateResult: (result) => {\n liveGateResults.push(result);\n liveGateName = undefined;\n liveGateTail = '';\n writeLiveArtifact();\n },\n }));\n\n const postGateMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postGateMergedOutcome) return postGateMergedOutcome;\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 // Finalize the live artifact so the Test/Lint node doesn't stay stuck at\n // \"running\" — the infra gate's error explains what could not run.\n try {\n writeVerificationArtifact(workspacePath, issueId, gateResults);\n } catch { /* best-effort */ }\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 const rebuildResult = await Effect.runPromise(rebuildWorkspaceStack(issueId, {\n onProgress: (m) => console.log(`[${logPrefix}] ${issueId} stack rebuild: ${m}`),\n }));\n if (!rebuildResult.success) {\n console.warn(`[${logPrefix}] Stack rebuild for ${issueId} failed: ${rebuildResult.error}`);\n }\n } catch (err) {\n console.warn(`[${logPrefix}] Could not settle 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 // Durable terminal record of this gate run, surfaced by the issue tree's\n // Test/Lint node (replaces the incremental 'running' writes above).\n try {\n writeVerificationArtifact(workspacePath, issueId, gateResults);\n } catch (artifactErr: any) {\n console.warn(`[${logPrefix}] Could not write verification artifact for ${issueId}: ${artifactErr.message}`);\n }\n\n if (failedGate) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = failedGate.name;\n const fullOutputPath = verificationArtifactPath(workspacePath);\n const summary = `Verification FAILED at ${failedCheck} (${failedGate.durationMs}ms).\\n\\nFull gate output: ${fullOutputPath}`;\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 complete gate output at \\`${fullOutputPath}\\` 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\\nThe command can run for several minutes. A yielded exec result or background-terminal notice means it is still running, not that it succeeded. Poll the same terminal until it exits, inspect the real exit code, then confirm \\`pan show ${issueId}\\` or \\`pan review pending\\` shows the issue re-entered review. Do NOT stop between steps or after pushing; stop only after exit code 0 and the observed pipeline state change.`;\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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\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. If the exec yields to a background terminal, poll that same terminal until it exits; then require exit code 0 and confirm pan show ${issueId} or pan review pending shows re-entry before declaring success.`;\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 // xBRIEF AC gate: check all acceptance criteria are completed (runs after quality gates)\n // Wrap in try-catch to detect merge conflict markers in the xBRIEF document and send\n // actionable feedback rather than falling through to a generic infrastructure error.\n let acStatus: ReturnType<typeof getXBriefACStatusSync>;\n try {\n acStatus = getXBriefACStatusSync(workspacePath);\n } catch (xbriefErr: any) {\n if (xbriefErr instanceof XBriefMergeConflictError) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'vbrief-conflicts';\n const summary = `xBRIEF 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 xBRIEF spec BEFORE resubmitting\\n\\n1. Open the xBRIEF 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: `xBRIEF 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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — the xBRIEF document 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 xBRIEF conflict feedback for ${issueId}:`, feedbackErr);\n }\n return { outcome: 'failed', failedCheck, cycleCount: newCycleCount, maxCycles: VERIFICATION_MAX_CYCLES };\n }\n throw xbriefErr;\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 task with \\`pan task close\\` — the canonical writer publishes the close and AC statuses sync 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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\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 const taskBlockers = options.skipPlanChecklist\n ? []\n : await checkIncompletePlanItemsPromise(workspacePath, issueId);\n const postChecklistMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postChecklistMergedOutcome) return postChecklistMergedOutcome;\n\n if (taskBlockers.length > 0) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'incomplete-plan-items';\n const itemIds = taskBlockers\n .map((line) => line.match(/^\\s+-\\s+(\\S+)/)?.[1])\n .filter((id): id is string => Boolean(id));\n const summary = `Checklist completion check FAILED — ${itemIds.length} incomplete item(s) remain:\\n\\n${taskBlockers.join('\\n')}`;\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\\nComplete each listed item with \\`pan task done ${issueId} <item>\\` after committing and pushing its implementation, then resubmit the review request.`;\n\n try {\n const fileResult = await Effect.runPromise(writeFeedbackFile({\n issueId,\n workspacePath,\n specialist: 'verification-gate',\n outcome: 'failed',\n summary: `Checklist completion check FAILED — ${itemIds.length} incomplete item(s) remain (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 repeated attempts.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nFix every reported failure, commit and push the corrections, then run pan done ${issueId} -c \"<summary>\" to reset verification and return the latest commit to the normal pipeline.`\n : `VERIFICATION FAILED for ${issueId}.\\nFailed check: ${failedCheck} — ${itemIds.length} incomplete item(s) remain.\\n\\nMUST READ: ${fileResult.filePath}\\n\\nRead the file, complete every listed item with pan task after committing and pushing, then request a new review with pan review request.`;\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 open-task 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/xBRIEF task state);\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 const changesetHasContent = await workspaceChangesetHasContent(issueId, workspacePath);\n const postDiffMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (postDiffMergedOutcome) return postDiffMergedOutcome;\n\n if (changesetHasContent === false) {\n const newCycleCount = currentCycles + 1;\n const failedCheck = 'empty-changeset';\n const comparedTargets = repoRoots.map(root => `${root.repoKey}:origin/${root.targetBranch}`).join(', ');\n const summary = `Branch has no implementation — only pipeline artifacts (.pan/xBRIEF task state) changed across workspace repos vs ${comparedTargets}. 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/xBRIEF task state changed across ${comparedTargets}).\\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: comparedTargets,\n }, logPrefix);\n console.error(`[${logPrefix}] VERIFICATION FAILED for ${issueId}: empty-changeset (no content files across ${comparedTargets})`);\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 if (changesetHasContent === undefined) {\n console.warn(`[${logPrefix}] empty-changeset guard skipped (one or more repo diffs failed)`);\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 // PAN-2948: polyrepo-aware — the wrapper repo's HEAD never changes, so\n // snapshotting it would make this comparison report \"no drift\" forever.\n let lastVerifiedCommit: HeadAnchor | undefined;\n try {\n const { snapshotWorkspaceHeadsPromise } = await import('../git-utils.js');\n lastVerifiedCommit = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);\n } catch { /* non-fatal — skip optimization if we can't get HEAD */ }\n\n const prePassMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (prePassMergedOutcome) return prePassMergedOutcome;\n\n setReviewStatusSync(issueId, {\n verificationStatus: 'passed',\n verificationNotes: undefined,\n ...(lastVerifiedCommit ? { lastVerifiedCommit } : {}),\n });\n void capturePipelineStageForIssue(issueId, 'verification_passed');\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 const errorMergedOutcome = skipMergedVerification(issueId, logPrefix);\n if (errorMergedOutcome) return errorMergedOutcome;\n\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 process.env.OVERDECK_VERIFICATION_WORKER === '1'\n ? runVerificationForIssueInProcess(issueId, workspacePath, workspaceInfo, logPrefix, options)\n : Effect.promise(() => runSupervisedVerification(issueId, workspacePath, workspaceInfo, logPrefix, options));\n}\n\nexport function runVerificationForIssueInProcess(\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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"}
@@ -0,0 +1,2 @@
1
+ import { a as deepWipe, i as closeOut } from "./workflows-N4QMkDzN.js";
2
+ export { closeOut, deepWipe };
@@ -1,24 +1,24 @@
1
1
  import { $ as readIssueRecord, Gn as extractNumberSync, J as getProjectConfigFromWorkspacePath, Kn as extractPrefixSync, Ri as init_paths, X as markRecordPipelineClosedOutSync, Y as init_record, Z as markRecordPipelineResidueClosedOutSync, ot as writeCloseOutDodGate, qn as init_issue_id, rt as resolveProjectForIssue, vi as OVERDECK_HOME } from "./config-yaml-Dce9VUd6.js";
2
2
  import { p as init_config, s as getDashboardApiUrlSync } from "./config-BUjU7GZQ.js";
3
- import { Ln as listRunningAgents, _ as init_agent_state, i as clearAgentOperatorGatesForIssueSync, q as init_agents } from "./agent-state-Ci6PhjOE.js";
3
+ import { Ln as listRunningAgents, _ as init_agent_state, i as clearAgentOperatorGatesForIssueSync, q as init_agents } from "./agent-state-B196fj1h.js";
4
4
  import { a as init_feature_registry_population, o as recordFeatureRegistryLifecycle } from "./post-merge-state-DGlkiVIO.js";
5
5
  import { a as init_git_utils, c as rehydrateHeadAnchor } from "./git-utils-D96xW28f.js";
6
6
  import { i as loadCloisterConfig, r as init_config$1 } from "./config-B-MLcKSo.js";
7
7
  import { c as resolveProjectReposForIssueSync, i as init_project_repos } from "./project-repos-J6jc42uD.js";
8
8
  import { c as init_merge_sync, j as listUatGenerationsSync } from "./merge-sync-CTGkR1_m.js";
9
- import { A as resolvePipelineTelemetryContext, D as capturePipelineStage, k as init_pipeline, p as init_review_status, u as getReviewStatus, w as setReviewStatusSync } from "./review-status-BegAr86G.js";
10
- import { t as pruneStoppedAgentsForIssue } from "./agent-gc-Coz8zQt_.js";
9
+ import { A as resolvePipelineTelemetryContext, D as capturePipelineStage, k as init_pipeline, p as init_review_status, u as getReviewStatus, w as setReviewStatusSync } from "./review-status-yY5qt7Rl.js";
10
+ import { t as pruneStoppedAgentsForIssue } from "./agent-gc-JzoSs5Pi.js";
11
11
  import { i as isTrackerIssueClosed, n as init_issue_closed } from "./issue-closed-D7aMUeMq.js";
12
12
  import { t as getAutoCloseOutCanonicalState } from "./deacon-canonical-state-wi63RApC.js";
13
13
  import { n as getForgeAdapter } from "./forge-CEe3eFjh.js";
14
14
  import { a as stepSkipped, i as stepOk, n as init_types, r as stepFailed, t as getLinearApiKey } from "./types-JR7ZOtpL.js";
15
15
  import { i as findWorkspacePath, t as archivePlanning } from "./archive-planning-CtdBSD1-.js";
16
16
  import { r as init_recovery_trip, t as acknowledgeAllOpenRecoveryTrips } from "./recovery-trip-7JFHFjeo.js";
17
- import { t as closeIssue } from "./close-issue-CRlmrE5g.js";
17
+ import { t as closeIssue } from "./close-issue-Bmu9aOIx.js";
18
18
  import { i as gatherIssueBranchContainment, s as init_pipeline_membership_gather } from "./pipeline-membership-gather-QYMqf_Wf.js";
19
19
  import { o as fetchRequiredStatusChecks, r as fetchIssuePullRequest, t as fetchCommitCheckRuns } from "./pull-requests-EBvcAtZO.js";
20
20
  import { a as buildResidueDodGate, i as buildAbandonedDodGate, n as DOD_ROWS, o as canAcceptDodMisses, r as acceptFlagFor, t as BRANCH_ABSENT_MERGE_ERROR } from "./dod-C9m0JqhG.js";
21
- import { t as teardownWorkspace } from "./teardown-workspace-CTL16rnG.js";
21
+ import { t as teardownWorkspace } from "./teardown-workspace-C-9murBw.js";
22
22
  import { n as loadShipRecords, t as aggregateGenerationShipStatus } from "./ship-status-CJvaa4QB.js";
23
23
  import { resolve } from "node:path";
24
24
  import { Effect } from "effect";
@@ -879,7 +879,7 @@ function closeOut(ctx, opts = {}) {
879
879
  }
880
880
  const uatEvidenceStep = yield* Effect.promise(async () => {
881
881
  try {
882
- const { healUatPromotionVerification } = await import("./uat-promote-verification-CRsIHE_q.js");
882
+ const { healUatPromotionVerification } = await import("./uat-promote-verification-BEBPcpPg.js");
883
883
  const evidence = await healUatPromotionVerification(ctx.issueId);
884
884
  if (!evidence) return stepSkipped("dod:uat-promotion-evidence", ["No missing UAT-promotion verification evidence found"]);
885
885
  return stepOk("dod:uat-promotion-evidence", [`Recorded verification from ${evidence.generation}`, ...evidence.mergeSha ? [`Promoted to main at ${evidence.mergeSha.slice(0, 9)}`] : []]);
@@ -1204,7 +1204,7 @@ async function verifyBranchMergedImpl(ctx) {
1204
1204
  };
1205
1205
  try {
1206
1206
  try {
1207
- const { loadReviewStatuses } = await import("./review-status-DXTFzCmR.js");
1207
+ const { loadReviewStatuses } = await import("./review-status-FnlvQuPI.js");
1208
1208
  if (loadReviewStatuses()[ctx.issueId.toUpperCase()]?.mergeStatus === "merged") return stepOk(step, ["Merge specialist confirmed merge completed"]);
1209
1209
  } catch {}
1210
1210
  const resolvedRoots = resolveProjectReposForIssueSync(ctx.issueId)?.filter((repo) => repo.required).map((repo) => ({
@@ -1488,7 +1488,7 @@ async function resetIssueToTodoImpl(ctx) {
1488
1488
  */
1489
1489
  async function resetPostMergeStateForIssue(issueId) {
1490
1490
  try {
1491
- const { resetPostMergeState } = await import("./merge-agent-ddEcZDZD.js");
1491
+ const { resetPostMergeState } = await import("./merge-agent-1zVLl6k_.js");
1492
1492
  resetPostMergeState(issueId);
1493
1493
  resetPostMergeState(issueId.toUpperCase());
1494
1494
  } catch {
@@ -1504,7 +1504,7 @@ function clearReviewStatusStep(issueId) {
1504
1504
  async function clearReviewStatusStepImpl(issueId) {
1505
1505
  const step = "clear-review-status";
1506
1506
  try {
1507
- const { clearReviewStatus } = await import("./review-status-DXTFzCmR.js");
1507
+ const { clearReviewStatus } = await import("./review-status-FnlvQuPI.js");
1508
1508
  clearReviewStatus(issueId.toUpperCase());
1509
1509
  return stepOk(step, ["Review status cleared"]);
1510
1510
  } catch {
@@ -1571,4 +1571,4 @@ async function resetIssueToCanceledImpl(ctx) {
1571
1571
  //#endregion
1572
1572
  export { deepWipe as a, verifyConventionBranchMerged as c, closeOut as i, cancelIssueWorkflow as n, resetToTodo as o, close as r, verifyBranchMergedImpl as s, approve as t };
1573
1573
 
1574
- //# sourceMappingURL=workflows-CxVnygYU.js.map
1574
+ //# sourceMappingURL=workflows-N4QMkDzN.js.map