@overdeck/desktop 0.46.0 → 0.47.1

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 (388) hide show
  1. package/drizzle/overdeck/0000_overdeck_init.sql +4 -1
  2. package/package.json +1 -1
  3. package/server/{acceptance-criteria-CCwFGICj.js → acceptance-criteria-Cd7ZGZCq.js} +2 -2
  4. package/server/{advancing-selfheal-De1L-Sb4.js → advancing-selfheal-DieFp3qi.js} +6 -6
  5. package/server/{agent-gc-CBULruzm.js → agent-gc-BMcgTDl7.js} +5 -5
  6. package/server/{agent-state-VQk8fY9F.js → agent-state-DyZJia9f.js} +1 -1
  7. package/server/{agent-state-service-BlnSkRFA.js → agent-state-service-BOzQhLjU.js} +15 -9
  8. package/server/agent-state-service-DFO6qvHp.js +2 -0
  9. package/server/agent-state-source-Ca_zCaII.js +21 -0
  10. package/server/{agents-C5rWYhb6.js → agents-CtACUuVG.js} +23 -16
  11. package/server/{agents-BKKkxKgK.js → agents-Dnn4XgdB.js} +1 -1
  12. package/server/archive-planning-BHCd_eL5.js +2 -0
  13. package/server/{archive-planning-C0lAbNB_.js → archive-planning-Binfb99i.js} +10 -6
  14. package/server/{artifact-index-jobs-ug6ZxIP5.js → artifact-index-jobs-Jn7BGOtV.js} +2 -2
  15. package/server/{assemble-DnffNpOo.js → assemble-DsqK9OAq.js} +2 -2
  16. package/server/{tmux-dedup-DbN6MGzM.js → auto-spawn-consent-BooqhC3L.js} +262 -13
  17. package/server/{backlog-auto-trigger-Dh-i9PQf.js → backlog-auto-trigger-BADGPxov.js} +3 -3
  18. package/server/{behavior-CfIg6pKp.js → behavior-B7biGtFT.js} +2 -2
  19. package/server/boot-reconciled-stop-events-bQUzU8ns.js +44 -0
  20. package/server/{bridge-pool-patrol-CUFmjVDN.js → bridge-pool-patrol-DsPj6F7t.js} +1 -1
  21. package/server/{briefing-freshness-DHmCSLar.js → briefing-freshness-CUerZqWd.js} +2 -2
  22. package/server/{build-info-CuFfxZxp.js → build-info-D0q_i8WM.js} +3 -3
  23. package/server/{build-info-BP160gU7.js → build-info-Du74MKiP.js} +1 -1
  24. package/server/{checkpoint-manager-Dxh0FYsv.js → checkpoint-manager-Cu-R5Uzg.js} +1 -1
  25. package/server/{checkpoint-manager-DEWD82qK.js → checkpoint-manager-R5tnaxEY.js} +2 -2
  26. package/server/checkpoint-worker.js +1 -1
  27. package/server/{checkpoints-CZvbtLnr.js → checkpoints-DYtLu-PB.js} +2 -2
  28. package/server/{checkpoints-DMTgXuLG.js → checkpoints-wF84ubZ8.js} +1 -1
  29. package/server/{claude-hooks-provision-fvy4RD2b.js → claude-hooks-provision-DXI3Wqlm.js} +2 -2
  30. package/server/{claude-hooks-provision-CN-xo-do.js → claude-hooks-provision-UKxCeOyj.js} +1 -1
  31. package/server/{claude-permissions-CN0cSCPp.js → claude-permissions-DYVLnX9t.js} +2 -2
  32. package/server/{claude-settings-overlay-CJn35FHQ.js → claude-settings-overlay-DsbpIq2d.js} +2 -2
  33. package/server/{claude-settings-overlay-Dabi9slj.js → claude-settings-overlay-DxP2F_gY.js} +1 -1
  34. package/server/cli-D6mRfUE6.js +3 -0
  35. package/server/{cli-oCWYA1pE.js → cli-DzRKxxP_.js} +9 -9
  36. package/server/{cliproxy-C8mB3KuB.js → cliproxy-CG4meRFc.js} +2 -2
  37. package/server/{cliproxy-PGwTX_o8.js → cliproxy-Cwzw39yN.js} +1 -1
  38. package/server/{close-issue-D5MF5GqF.js → close-issue-BX1bATJy.js} +5 -5
  39. package/server/{closed-issue-reaper-CJ24u0Zt.js → closed-issue-reaper-DvnTSN6a.js} +1 -1
  40. package/server/{closed-issue-reaper-Cltx86x5.js → closed-issue-reaper-hLt0W86J.js} +62 -12
  41. package/server/{codex-Drlf5Xhf.js → codex-BYwi1uyW.js} +6 -6
  42. package/server/{codex-parser-DpB89Vqa.js → codex-parser-Poyz29GE.js} +2 -2
  43. package/server/{codex-BdEsUFWh.js → codex-rnJN3v3_.js} +1 -1
  44. package/server/{compaction-continuation-K2AxQX4H.js → compaction-continuation-DtMfHN0f.js} +3 -3
  45. package/server/{config-Dr3pW6w6.js → config-CX4vk1CV.js} +2 -2
  46. package/server/{config-DV-grfQc.js → config-R793W0yA.js} +1 -1
  47. package/server/{config-B2IMcBxx.js → config-ktAVnp4s.js} +2 -2
  48. package/server/{config-yaml-CmOPzmBb.js → config-yaml-CxdwhAIA.js} +10 -2
  49. package/server/{conflict-gate-B9cN3SBi.js → conflict-gate-BNv6UolH.js} +59 -13
  50. package/server/conflict-gate-BSTlwCtF.js +3 -0
  51. package/server/{context-layers-D6LZo3l1.js → context-layers-DCdaGsRG.js} +2 -2
  52. package/server/{context-layers-dR5YxHYB.js → context-layers-DlWsDiRF.js} +3 -3
  53. package/server/{control-settings-C7DUehE1.js → control-settings-qYYHrIqy.js} +13 -6
  54. package/server/{conversation-compaction-Dj4FAKoZ.js → conversation-compaction-BxUKObHb.js} +1 -1
  55. package/server/{conversation-compaction-BoqdDXWF.js → conversation-compaction-CXQrN3I_.js} +8 -8
  56. package/server/{conversation-service-BCxl4f8Z.js → conversation-service-CDnQ3ayN.js} +1 -1
  57. package/server/{conversation-service-5aCnq1zR.js → conversation-service-CZiUE8Uw.js} +8 -7
  58. package/server/{conversations-BUpYsOZg.js → conversations-D7lR670u.js} +4 -4
  59. package/server/{conversations-C34dyIb9.js → conversations-DXl5YTf4.js} +1 -1
  60. package/server/{cost-Bgcub5kW.js → cost-Aat8HfO_.js} +2 -2
  61. package/server/{cost-CvxRrucd.js → cost-CWvN9FP2.js} +3 -3
  62. package/server/{cost-sync-Dv3LUaNW.js → cost-sync-DiUBXwl6.js} +3 -3
  63. package/server/{dag-ombYYt4s.js → dag-5QlmH0oC.js} +2 -2
  64. package/server/{dangerous-git-ops-BcJPC5Rr.js → dangerous-git-ops-DWX6Og8c.js} +1 -1
  65. package/server/dashboard-db-worker.js +7 -7
  66. package/server/{deacon-hi9KLPLT.js → deacon-B1LD5cJU.js} +741 -211
  67. package/server/{deacon-DrXqT9LQ.js → deacon-PW_bg4uL.js} +3 -3
  68. package/server/{deacon-nudge-log-BNBebzeL.js → deacon-nudge-log-DPHsO14z.js} +3 -3
  69. package/server/{deacon-pending-lifecycle-Cpk0k7Hi.js → deacon-pending-lifecycle-2ZflPxgo.js} +3 -3
  70. package/server/deacon-swarm-BkKR7SXu.js +2 -0
  71. package/server/{deacon-swarm-DBxUaO-A.js → deacon-swarm-DwGUgSVp.js} +15 -14
  72. package/server/deacon.js +8 -8
  73. package/server/{dead-end-trip-CQcP70ND.js → dead-end-trip-B06RFIr2.js} +3 -3
  74. package/server/{delivery-Da0zEMY4.js → delivery-C2M73sBg.js} +1 -1
  75. package/server/{deploy-patrol-Df-Tmaq0.js → deploy-patrol-BNjeCL8u.js} +8 -8
  76. package/server/{deploy-queue-UjKGYsDe.js → deploy-queue-CKT_Ia9p.js} +2 -2
  77. package/server/{deploy-queue-9SrhZR63.js → deploy-queue-DMMYhFC8.js} +1 -1
  78. package/server/{deploy-window-rpqpWqHA.js → deploy-window-DC8lze3d.js} +6 -6
  79. package/server/{deploy-window-jOiPRHL0.js → deploy-window-D_AimdNN.js} +1 -1
  80. package/server/{dev-supervisor-CC46Ig8q.js → dev-supervisor-C4F0vbno.js} +2 -2
  81. package/server/{devcontainer-renderer-68CSCRnu.js → devcontainer-renderer-66sqMQIi.js} +3 -3
  82. package/server/{dist-CJy72uEg.js → dist-C5FT9lTG.js} +1 -1
  83. package/server/dist-qcf9gAP0.js +3 -0
  84. package/server/{dist-src-Bik83hFi.js → dist-src-B-AlGWSl.js} +1 -1
  85. package/server/{docker-BMVTSFL5.js → docker-BxrFhTZ_.js} +1 -1
  86. package/server/{docker-Dam7mbIB.js → docker-CoAT8R0J.js} +2 -2
  87. package/server/{dod-Dar-yheg.js → dod-Bg6wsKTV.js} +26 -5
  88. package/server/durable-review-pipeline-D_DcfIGP.js +3 -0
  89. package/server/{durable-review-pipeline-CGZ5QBxh.js → durable-review-pipeline-HkAgnx0L.js} +5 -2
  90. package/server/{ensure-devcontainer-C98V8yW-.js → ensure-devcontainer-Bg5HJAcO.js} +1 -1
  91. package/server/{ensure-devcontainer-B057YA81.js → ensure-devcontainer-DTxChVuA.js} +4 -4
  92. package/server/{esm-shims-Br9BPdkR.js → esm-shims-CaBWIR7f.js} +1 -1
  93. package/server/{event-store-ELqkVOn0.js → event-store-5UKzh9Jf.js} +1 -1
  94. package/server/{event-store-zY5MJHgF.js → event-store-CrHcVC5_.js} +3 -3
  95. package/server/{events-D6pyqhzM.js → events-ChEFB7Jp.js} +1 -1
  96. package/server/{events-D9PR1IC0.js → events-DhRN-6vM.js} +3 -3
  97. package/server/{factory-CRoOpGsF.js → factory-BezSPaTd.js} +5 -5
  98. package/server/{feature-registry-population--YUXU999.js → feature-registry-population-DhswNiXx.js} +4 -4
  99. package/server/{feature-registry-storage-BORBTo0y.js → feature-registry-storage-CUVNpAso.js} +2 -2
  100. package/server/{features--nFkJY8v.js → features-B2CfNPFw.js} +2 -2
  101. package/server/{feedback-target-C0ZzyHvU.js → feedback-target-CMrEAoeA.js} +1 -1
  102. package/server/{feedback-target-Dt9BsapX.js → feedback-target-VBr9gKgX.js} +18 -7
  103. package/server/{feedback-writer-D1fm-5Z8.js → feedback-writer-CY91ckuw.js} +1 -1
  104. package/server/{feedback-writer-BG0RUZiu.js → feedback-writer-xpFgU632.js} +5 -5
  105. package/server/{flywheel-BiT3odRb.js → flywheel-CTVY3yCG.js} +38 -19
  106. package/server/{flywheel-CLVB55Be.js → flywheel-DQqsSm7P.js} +14 -14
  107. package/server/{flywheel-BekukH4i.js → flywheel-DsICCjTR.js} +1 -1
  108. package/server/{flywheel-merge-order-BKw9o6ku.js → flywheel-merge-order-C-TI4JGu.js} +1 -1
  109. package/server/{flywheel-merge-order-BJv1DZz1.js → flywheel-merge-order-CMGz-imq.js} +7 -7
  110. package/server/forge-D647IMNa.js +3 -0
  111. package/server/{forge-CZbSg6Ds.js → forge-RTNqJe6a.js} +2 -2
  112. package/server/{from-D_4_dk7i.js → from-DxGcivc9.js} +1 -1
  113. package/server/fs-lock-Bre3sGoz.js +130 -0
  114. package/server/{fts-db-BeOomFa-.js → fts-db-wROfFfje.js} +2 -2
  115. package/server/{fts-operations-BdewJ_g9.js → fts-operations-BuTdlZFA.js} +2 -2
  116. package/server/{git-utils-CI6cwyyC.js → git-utils-CedsVume.js} +1 -1
  117. package/server/{git-utils-ameCgDdy.js → git-utils-DtdoEXJk.js} +4 -4
  118. package/server/{github-app-DtAsvwzK.js → github-app-DIE8BkHI.js} +1 -1
  119. package/server/{github-app-CQ1Lo6LA.js → github-app-gVnZcP9B.js} +2 -2
  120. package/server/{github-client-BfyDxuRN.js → github-client-BrAC6ELh.js} +3 -3
  121. package/server/{github-client-Cj0yl_07.js → github-client-CBOkvBUl.js} +1 -1
  122. package/server/{github-pr-lookup-BDq6Wznz.js → github-pr-lookup-CgMULTPf.js} +2 -2
  123. package/server/{harness-binary-DqkftwTb.js → harness-binary-CnBHpd57.js} +2 -2
  124. package/server/{harness-resolve-CqMqM1Mb.js → harness-resolve-BVj6sI8m.js} +4 -4
  125. package/server/{health-events-CazRxJUS.js → health-events-BBWO_Dh9.js} +2 -2
  126. package/server/{health-events-_xfTaOUs.js → health-events-Der6bOkm.js} +1 -1
  127. package/server/{hooks-BnJsxlSq.js → hooks-BJNal-bs.js} +1 -1
  128. package/server/{hooks-BO3QT1sn.js → hooks-BOavco-e.js} +2 -2
  129. package/server/{hume-CDYJxqx-.js → hume-DBocJFkA.js} +2 -2
  130. package/server/hume-DtWN8oV5.js +3 -0
  131. package/server/{idle-stack-reaper-BYqERdkE.js → idle-stack-reaper-CyGxXOfC.js} +1 -1
  132. package/server/{idle-stack-reaper-CnGx_PO_.js → idle-stack-reaper-DQFh8rDh.js} +2 -2
  133. package/server/{in-flight-guard-Bq3epG58.js → in-flight-guard-nXEKoxI7.js} +1 -1
  134. package/server/{infra-BjuxvjdS.js → infra-BDQDRopn.js} +15 -4
  135. package/server/{injection-UCf8EsjX.js → injection-CCopdUKz.js} +7 -7
  136. package/server/{injection-DZxlV2al.js → injection-DfFFEMKL.js} +1 -1
  137. package/server/inspect-agent-CPqXI81t.js +2 -0
  138. package/server/{inspect-agent-6kylZnrm.js → inspect-agent-FCDlNT_i.js} +12 -12
  139. package/server/{internal-token-DvMTQSOS.js → internal-token-BG6yQKNL.js} +2 -2
  140. package/server/{internal-token-M9omeXM1.js → internal-token-BJZa40Ld.js} +1 -1
  141. package/server/{io-VHvc0Ssp.js → io-C0NV7y6C.js} +4 -4
  142. package/server/{issue-closed-B6KJkmHZ.js → issue-closed-CNNGbhWm.js} +8 -8
  143. package/server/{issue-lifecycle-C4Zj0WmE.js → issue-lifecycle-BXfzxFCD.js} +29 -23
  144. package/server/{issue-lifecycle-9gk3fnXN.js → issue-lifecycle-DSH0GpWC.js} +1 -1
  145. package/server/{issue-service-singleton-DmCh7EHj.js → issue-service-singleton-F3A5VP6M.js} +10 -10
  146. package/server/{issue-service-singleton-PMx8F1jr.js → issue-service-singleton-lwFJ4dHk.js} +1 -1
  147. package/server/{issues-CgnQ1OGQ.js → issues-DA-U_MpR.js} +2 -2
  148. package/server/{jsonl-parser-DJOH_O-w.js → jsonl-parser-BXiGANOh.js} +3 -3
  149. package/server/{label-cleanup-Dv7AV_R1.js → label-cleanup-BnxRk0Eo.js} +3 -3
  150. package/server/{lifecycle-CTdOWYMi.js → lifecycle-DOgGnpIv.js} +2 -2
  151. package/server/{lifecycle-DDN8ApVY.js → lifecycle-Di48-w4x.js} +6 -6
  152. package/server/{lifecycle-io-D-lGdzK3.js → lifecycle-io-1XSeczTr.js} +5 -5
  153. package/server/{lifecycle-io-D_zTLvP1.js → lifecycle-io-eVG6v_8-.js} +1 -1
  154. package/server/{linear-client-BQU36QqE.js → linear-client-CYZRrcjp.js} +3 -3
  155. package/server/{linear-client-CY4O_Tu3.js → linear-client-CvGo9n7M.js} +1 -1
  156. package/server/{linear-mcp-auth-BnU4TYfY.js → linear-mcp-auth-Cp0XaP96.js} +5 -5
  157. package/server/{linear-mcp-auth-NYBq_oHZ.js → linear-mcp-auth-DoJnjdPZ.js} +1 -1
  158. package/server/memory-fts-worker.js +1 -1
  159. package/server/{merge-Bpx4jjht.js → merge-DO14mOr3.js} +3 -3
  160. package/server/{merge-idOG--29.js → merge-ZF99ig6A.js} +1 -1
  161. package/server/{merge-agent-DrXa1CpW.js → merge-agent-C1-9zbP_.js} +1 -1
  162. package/server/{merge-agent-DdMVSV2Y.js → merge-agent-gpiRkcvj.js} +31 -31
  163. package/server/{merge-batch-C5q1c1GX.js → merge-batch-C11ocNkO.js} +1 -1
  164. package/server/{merge-completeness-BMm8tMyZ.js → merge-completeness-BUzPZy0E.js} +4 -4
  165. package/server/{merge-completeness-D0ljXbk3.js → merge-completeness-CghMbyX7.js} +1 -1
  166. package/server/merge-ops-7QqziXAh.js +2 -0
  167. package/server/merge-rebase-B4pgzvQJ.js +2 -0
  168. package/server/{merge-rebase-xLnMlw5h.js → merge-rebase-iwlUzZjr.js} +2 -2
  169. package/server/{merge-set-DzsOTBg5.js → merge-set-BymrheTj.js} +1 -1
  170. package/server/{merge-set-DH7ot3yz.js → merge-set-Dbnx4chw.js} +4 -4
  171. package/server/{merge-sync-CQ-LgZ1_.js → merge-sync-CM978zez.js} +7 -4
  172. package/server/merge-sync-CqEtqjI2.js +3 -0
  173. package/server/{merge-train-DTEMyIu4.js → merge-train-DvLcAn1G.js} +4 -4
  174. package/server/{merge-train-deps-CNPJzepw.js → merge-train-deps-Cl_kcRbO.js} +21 -15
  175. package/server/{merge-verification-x3JO8Dtz.js → merge-verification-c9Y9mllw.js} +6 -6
  176. package/server/{merged-docker-cleanup-worker-CTpC27Bs.js → merged-docker-cleanup-worker-CGiDOdv8.js} +3 -3
  177. package/server/{merged-docker-cleanup-worker-Cdi9apm-.js → merged-docker-cleanup-worker-DgsLOx3E.js} +1 -1
  178. package/server/{multipart-parser-IMSBfePV.js → multipart-parser-D0twwRjz.js} +2 -2
  179. package/server/{no-resume-mode-C5ULAXwO.js → no-resume-mode-DZvP0M_S.js} +1 -1
  180. package/server/node_modules/.package-lock.json +4 -4
  181. package/server/node_modules/@types/node/README.md +1 -1
  182. package/server/node_modules/@types/node/crypto.d.ts +1 -1
  183. package/server/node_modules/@types/node/package.json +2 -2
  184. package/server/{orphan-proposed-reconciler-CWmOdM9-.js → orphan-proposed-reconciler-6r2OEfYd.js} +1 -1
  185. package/server/{orphan-proposed-reconciler-Dg6U4ADZ.js → orphan-proposed-reconciler-DtQP6oE_.js} +230 -31
  186. package/server/package-lock.json +5 -5
  187. package/server/package.json +1 -1
  188. package/server/{pan-dir-ubraCiUg.js → pan-dir-DAOb1V2-.js} +4 -4
  189. package/server/{paths-cXmOwSbh.js → paths-DuATV5iE.js} +2 -2
  190. package/server/{pending-lifecycle-claim-DEteYdS9.js → pending-lifecycle-claim-DQUHIDfX.js} +2 -2
  191. package/server/persistent-logger-CBj016pT.js +57 -0
  192. package/server/{pickup-D8xtG1J2.js → pickup-zXZl5lQI.js} +4 -3
  193. package/server/{pipeline-membership-CrAPLYtf.js → pipeline-membership-B2yUcBz7.js} +1 -1
  194. package/server/{pipeline-membership-BGSvkT2M.js → pipeline-membership-DHOXmvba.js} +1 -1
  195. package/server/{pipeline-membership-gather-CET40frr.js → pipeline-membership-gather-BIcJ-N0W.js} +114 -9
  196. package/server/{pipeline-membership-gather-DTfcgxLl.js → pipeline-membership-gather-OkLXuvxR.js} +1 -1
  197. package/server/{pipeline-notifier-ImNXknf0.js → pipeline-notifier-BmwrVKsO.js} +1 -1
  198. package/server/{pipeline-notifier-BuQ0e4hF.js → pipeline-notifier-CxMes51i.js} +2 -2
  199. package/server/{post-merge-lifecycle-worker-DbO10pum.js → post-merge-lifecycle-worker-3u_rA4R0.js} +3 -3
  200. package/server/{project-pipelines-Bim6bThI.js → project-pipelines-C3SPFJ38.js} +2 -2
  201. package/server/{project-repos-C0nuoBGv.js → project-repos-BOpBzkO6.js} +2 -2
  202. package/server/{project-repos-CRE6Ykow.js → project-repos-BgW4lcIa.js} +1 -1
  203. package/server/{projects-B03Wr-xc.js → projects-_n3Zui6K.js} +1 -1
  204. package/server/{prompts-BEx08AIu.js → prompts-B0TtboFm.js} +2 -2
  205. package/server/{providers-D7IluJe0.js → providers-BI1mOBQ4.js} +1 -1
  206. package/server/{providers-evXhiQeg.js → providers-O2smCvSz.js} +7 -7
  207. package/server/public/assets/{chunk-BO2N2NFS-D1s4-Sqp.js → chunk-BO2N2NFS-D_pGACYN.js} +4 -4
  208. package/server/public/assets/{diagram-OG6HWLK6-1gdMoSF7.js → diagram-OG6HWLK6-BO6fe3hH.js} +1 -1
  209. package/server/public/assets/{dist-DqDRYW6P.js → dist-5zingMiA.js} +3 -3
  210. package/server/public/assets/{dist-CxAOHbil.js → dist-CVxhbI2E.js} +1 -1
  211. package/server/public/assets/{ganttDiagram-6RSMTGT7-BYex-Ec7.js → ganttDiagram-6RSMTGT7-Bgj4A7kp.js} +1 -1
  212. package/server/public/assets/{highlighted-body-OFNGDK62-DlVkiG0S.js → highlighted-body-OFNGDK62-DNPK7_cm.js} +1 -1
  213. package/server/public/assets/{index-K0hAYCgV.js → index-DEpY-D1O.js} +148 -148
  214. package/server/public/assets/index-Ddkcz3WT.css +1 -0
  215. package/server/public/assets/{linear-B4cuEFmO.js → linear-BB0jQT16.js} +1 -1
  216. package/server/public/assets/mermaid-GHXKKRXX-BzPfaQJ1.js +1 -0
  217. package/server/public/assets/{pieDiagram-4H26LBE5-CBHNBIJQ.js → pieDiagram-4H26LBE5-DeGIzzpZ.js} +1 -1
  218. package/server/public/assets/{prod-CN2nHBvX.js → prod-XBLvikex.js} +4 -4
  219. package/server/public/assets/{quadrantDiagram-W4KKPZXB-Bom87VOQ.js → quadrantDiagram-W4KKPZXB-BV9SLeWz.js} +1 -1
  220. package/server/public/assets/{sankeyDiagram-5OEKKPKP-UrBeyLxk.js → sankeyDiagram-5OEKKPKP-Dwja0gj8.js} +1 -1
  221. package/server/public/assets/{xychartDiagram-2RQKCTM6-DhkbrIxR.js → xychartDiagram-2RQKCTM6-DCB4qvfw.js} +1 -1
  222. package/server/public/index.html +2 -2
  223. package/server/{pull-requests-DHWiKxo7.js → pull-requests-BonZ4WVG.js} +3 -3
  224. package/server/{pull-requests-Cv7LxzUN.js → pull-requests-DNcJUVWA.js} +1 -1
  225. package/server/{queries-DHJm7bTd.js → queries-DCX27GRr.js} +266 -155
  226. package/server/{rally-B71M9f4o.js → rally-Cxe7lKYX.js} +3 -3
  227. package/server/{rally-api-D5uXN08-.js → rally-api-Cp50exEi.js} +1 -1
  228. package/server/{rally-api-Dkqmok65.js → rally-api-CzkKenoi.js} +2 -2
  229. package/server/{rally-client-CxsA6ExK.js → rally-client-Bu3Cekkw.js} +1 -1
  230. package/server/{rally-client-Bfqm6XI4.js → rally-client-CyBBEDHu.js} +5 -5
  231. package/server/rally-x6ztTQo4.js +3 -0
  232. package/server/{reap-terminal-sessions-CvmwaqKv.js → reap-terminal-sessions-CtAhr6L0.js} +2 -2
  233. package/server/{reap-terminal-sessions-BQ23nriz.js → reap-terminal-sessions-DvFqQUnq.js} +2 -2
  234. package/server/{rebuild-stack-qeRqHZxH.js → rebuild-stack-BKYpIPDL.js} +2 -2
  235. package/server/{rebuild-stack-0EEYReVZ.js → rebuild-stack-hCQtprWC.js} +7 -7
  236. package/server/{reconstruct-cache-BbYFsqLa.js → reconstruct-cache-CF2avArx.js} +9 -8
  237. package/server/{record-CtroO946.js → record-BTwWhtBb.js} +1 -1
  238. package/server/{record-update-Z0QCxmMp.js → record-update-DaOKS7Wb.js} +5 -128
  239. package/server/{record-update-DH6dLJID.js → record-update-DhI7eySG.js} +1 -1
  240. package/server/{recovery-trip-eJe26h-f.js → recovery-trip-D-wM9EfB.js} +2 -2
  241. package/server/{release-engine-lPUp-MTd.js → release-engine-_eO3VFth.js} +5 -5
  242. package/server/{release-set-BwGeyZKX.js → release-set-vxgZwwZV.js} +3 -3
  243. package/server/{remote-BCd02Es1.js → remote-BienmcrZ.js} +3 -3
  244. package/server/{remote-CVGUhXMV.js → remote-CVPCc7Vy.js} +3 -3
  245. package/server/{remote-agents-C1bssi41.js → remote-agents-kwsEZvXu.js} +1 -1
  246. package/server/{remote-agents-C_VxssLU.js → remote-agents-kxraOCGT.js} +17 -8
  247. package/server/{remote-completion-DAB0P706.js → remote-completion-BtmZ42aP.js} +13 -13
  248. package/server/resume-DXIIfJNk.js +3 -0
  249. package/server/{review-agent-CHhI66UP.js → review-agent-CIRr0yYt.js} +31 -29
  250. package/server/{review-agent-CD4RCI0Y.js → review-agent-UpAM4DmT.js} +1 -1
  251. package/server/{review-artifacts-DSMRIfuJ.js → review-artifacts-BCODM9ww.js} +5 -5
  252. package/server/{review-context-oFuBbiEE.js → review-context-BBsNrDri.js} +9 -9
  253. package/server/{review-convoy-liveness-CpzrcJ5F.js → review-convoy-liveness-l06_LYCt.js} +2 -2
  254. package/server/review-status-CacDM78F.js +3 -0
  255. package/server/{review-status-yljtTd-q.js → review-status-CwhA9wmd.js} +329 -110
  256. package/server/{review-status-emit-CUExtHd5.js → review-status-emit-BPJwYcRy.js} +3 -3
  257. package/server/{review-status-enrichment-QV_hQkgS.js → review-status-enrichment-DvyZAbGR.js} +3 -3
  258. package/server/{review-status-source-ylw5QZUR.js → review-status-source-B70ekARK.js} +1 -1
  259. package/server/{review-status-source-CpvJnvnQ.js → review-status-source-DWnFE0b6.js} +1 -1
  260. package/server/{review-status-sync-NaWvI9Xf.js → review-status-sync-B0IS6Beh.js} +1 -1
  261. package/server/{review-status-sync-483sujRo.js → review-status-sync-h2CJX6ju.js} +11 -6
  262. package/server/{review-verdict-feedback-BPDn4li_.js → review-verdict-feedback-qRohbFG2.js} +1 -1
  263. package/server/{review-verdict-feedback-CELeUinh.js → review-verdict-feedback-yrrmgps_.js} +91 -15
  264. package/server/{rollup-DTNvelz9.js → rollup-CUoav0Op.js} +8 -8
  265. package/server/{rollup-DYZfq1c4.js → rollup-DxCjJaAM.js} +1 -1
  266. package/server/{scanner-CV35oSn4.js → scanner-ChURu_b-.js} +7 -7
  267. package/server/{sequence-io-DF_8iuhV.js → sequence-io-D9ITDxzq.js} +4 -4
  268. package/server/{sequencer-agent-B2WeCtGi.js → sequencer-agent-m7gmaakW.js} +7 -6
  269. package/server/server.js +435 -418
  270. package/server/{service-Br9rpBNA.js → service-BzFG0Us_.js} +88 -59
  271. package/server/{session-fork-D0LY152N.js → session-fork-KBq4HIHF.js} +2 -2
  272. package/server/{session-history-BUyK29eq.js → session-history-C_EMhIIF.js} +7 -55
  273. package/server/settings-9jSGHBPY.js +2 -0
  274. package/server/{settings-Bse1Pdcj.js → settings-BLbcDqUp.js} +3 -3
  275. package/server/{settings-CvVGqNEs.js → settings-DejgzzLs.js} +2 -2
  276. package/server/{shadow-engineering-BWLa8ODz.js → shadow-engineering-D8R9I8Yl.js} +3 -3
  277. package/server/{shadow-state-FV6PHfEW.js → shadow-state-C0Af4clN.js} +1 -1
  278. package/server/{shadow-state-B4fpKxOO.js → shadow-state-fzIqIMDD.js} +2 -2
  279. package/server/{shadow-utils-D7asqxOZ.js → shadow-utils-Ugca_9ND.js} +2 -2
  280. package/server/{ship-log-xplJ8t75.js → ship-log-VAv-lHrF.js} +1 -1
  281. package/server/{smart-compaction-D3U_79f-.js → smart-compaction-B2Xu5XEb.js} +7 -7
  282. package/server/{smart-compaction-CPp2Ykf6.js → smart-compaction-BcYY_Suf.js} +1 -1
  283. package/server/{spawn-planning-session-DGfZ5B8D.js → spawn-planning-session-DhCoBPct.js} +38 -50
  284. package/server/spawn-planning-session-Dsv-350T.js +3 -0
  285. package/server/{specialist-completion-Br48eiDP.js → specialist-completion-z6v3ZqJE.js} +1 -1
  286. package/server/{specialist-context-cVbGnTa3.js → specialist-context-CrA5azkJ.js} +5 -5
  287. package/server/{specialist-handoff-logger-DK-GTz4s.js → specialist-handoff-logger-CmpZYJMB.js} +2 -2
  288. package/server/{specialist-logs-Cl5-hqT8.js → specialist-logs-BorrIu0x.js} +3 -3
  289. package/server/{specialists-CNfYO3G2.js → specialists-2yLmqph9.js} +298 -180
  290. package/server/{specialists-Tdezg_6N.js → specialists-CH6ah6D-.js} +1 -1
  291. package/server/{specialists-Cicieuzu.js → specialists-Dfx9_Wzb.js} +18 -18
  292. package/server/{specialists-JHsdU3pA.js → specialists-ZdrifiKx.js} +1 -1
  293. package/server/specs-DKV3jIEs.js +3 -0
  294. package/server/{src-Ck028hjO.js → src-B2e5rGu2.js} +6 -6
  295. package/server/{src-CRmCHlma.js → src-B948bGVR.js} +57 -13
  296. package/server/{src-UWcGe0Ix.js → src-Dm_NV7f6.js} +3 -3
  297. package/server/{stack-health-DqSqx0zv.js → stack-health-Bf2WdG4E.js} +2 -2
  298. package/server/{stack-health-CJLMrLBl.js → stack-health-CoWAhA99.js} +1 -1
  299. package/server/{stale-task-claims-CYFOUNlT.js → stale-task-claims-D1Ll8fI5.js} +5 -4
  300. package/server/{staleness-D47CUJok.js → staleness-45qZ_a60.js} +1 -1
  301. package/server/{staleness-BQ-0gMYK.js → staleness-CuED1Psm.js} +1 -1
  302. package/server/{state-home-BYV7qZTW.js → state-home-B4EWfIxF.js} +2 -2
  303. package/server/{state-mapping-BVldLhBf.js → state-mapping-BEONzr8P.js} +1 -1
  304. package/server/{state-migrate-CvvBtS0Y.js → state-migrate-Cd8BH33U.js} +4 -4
  305. package/server/{stuck-remediation-Wt0UVvu1.js → stuck-remediation-ChcooZuk.js} +1 -1
  306. package/server/{stuck-remediation-mkLC6G_t.js → stuck-remediation-DmY5UJLg.js} +24 -23
  307. package/server/{substrate-bug-weights-service-XfLAKnmK.js → substrate-bug-weights-service-BvTWrFUz.js} +3 -3
  308. package/server/{summary-fork-CD7GOts0.js → summary-fork--Jr8duYh.js} +2 -2
  309. package/server/{summary-fork-xiXBnWG9.js → summary-fork-Ct514_Jl.js} +8 -8
  310. package/server/supervisor/{injection-budget-B5SbvDx2.js → injection-budget-B3UyEONL.js} +1 -1
  311. package/server/supervisor/{paths-K3noE4N_.js → paths-BBOnCYlO.js} +10 -2
  312. package/server/supervisor/pty-supervisor.js +4 -4
  313. package/server/supervisor/{pty-token-B7lp0ElT.js → pty-token-CWRffcCa.js} +3 -3
  314. package/server/{supervisor-DL788vos.js → supervisor-B7BHGcNA.js} +3 -3
  315. package/server/supervisor-CyR_mW5B.js +2 -0
  316. package/server/{swarm-readiness-BV14DF5N.js → swarm-readiness-MNE5O8hn.js} +3 -3
  317. package/server/{system-prerequisites-pdWG6ZQs.js → system-prerequisites-Cin9ZgDx.js} +2 -2
  318. package/server/{teardown-workspace-l2F4_zim.js → teardown-workspace-CvBpvc85.js} +15 -15
  319. package/server/{test-agent-queue-qakFIIGz.js → test-agent-queue-DmSIqays.js} +8 -7
  320. package/server/{test-verdict-Gw-btEfb.js → test-verdict-BieVDAV1.js} +1 -1
  321. package/server/{test-verdict-BJYDggMm.js → test-verdict-Cy2jJGTe.js} +1 -1
  322. package/server/{tldr-daemon-BKOYB616.js → tldr-daemon-Ca0eovh3.js} +1 -1
  323. package/server/{tldr-daemon-CBaWkV9k.js → tldr-daemon-IOssGwg7.js} +2 -2
  324. package/server/{tmux-B1Wbxz5o.js → tmux-CfDHob9M.js} +174 -4
  325. package/server/{tmux-DQ6jB76i.js → tmux-Ctk6RV5l.js} +1 -1
  326. package/server/{token-Cxbk023d.js → token-B10VFNOD.js} +2 -2
  327. package/server/{token-util-CLq2MmQt.js → token-util-CZ8WPtdk.js} +1 -1
  328. package/server/token-util-CrfQ2FKf.js +3 -0
  329. package/server/{tracker-config-DZ8Zn2nQ.js → tracker-config-CHbrjg6m.js} +2 -2
  330. package/server/{tracker-utils-L0FKtjq2.js → tracker-utils-DZZq_C0R.js} +2 -2
  331. package/server/{traefik-connect-bNX6jKkb.js → traefik-connect-GHomyBaD.js} +1 -1
  332. package/server/{tunnel-BAm1XgjG.js → tunnel-Bdyb-sNq.js} +3 -3
  333. package/server/{tunnel-CjSnHdTc.js → tunnel-Dz7y434T.js} +1 -1
  334. package/server/{typed-errors-BHhE85Ul.js → typed-errors-BR_RmPS_.js} +1 -1
  335. package/server/{typed-errors-2BTMxkZq.js → typed-errors-Bn_2WRU7.js} +1 -1
  336. package/server/{types-hraoaQIp.js → types-D2ETIB8T.js} +1 -1
  337. package/server/{types-q67TYYg5.js → types-Dh6RI5Vj.js} +1 -1
  338. package/server/{uat-promote-verification-CKB9ZrKC.js → uat-promote-verification-DyvQXvIn.js} +5 -5
  339. package/server/{uat-train-D5UjcyAa.js → uat-train-Dv0Bxer7.js} +0 -0
  340. package/server/{uat-train-Cu-4nvbf.js → uat-train-diX_7shd.js} +1 -1
  341. package/server/{validate-Cxsx5Uz1.js → validate-606KcYZC.js} +3 -3
  342. package/server/{validation-DEaTZafj.js → validation-Cf7aaV5A.js} +1 -1
  343. package/server/{validation-VZgJxmqc.js → validation-CnrDul1x.js} +4 -4
  344. package/server/{verification-artifact-g3yuxQDL.js → verification-artifact-D4b-bio9.js} +1 -1
  345. package/server/{verification-artifact-C85cRTc_.js → verification-artifact-GOaj8u2s.js} +1 -1
  346. package/server/{verification-runner-KDZIsBj4.js → verification-runner-B5MVxDvU.js} +19 -19
  347. package/server/{verification-runner-DlZI8yhw.js → verification-runner-DiPaUP-C.js} +1 -1
  348. package/server/{vtt-parser-Jr94BF3Y.js → vtt-parser-CMU5EZ5R.js} +1 -1
  349. package/server/{work-agent-prompt-C-vuP3_J.js → work-agent-prompt-Csb3fbVR.js} +9 -9
  350. package/server/{workflows-D0oip4eV.js → workflows-D87ajwV6.js} +113 -43
  351. package/server/workflows-DN6NyVGd.js +2 -0
  352. package/server/{workspace-BqFg__wH.js → workspace-AIOM7n00.js} +1 -1
  353. package/server/{workspace-anchor-drift-B4gMRHl4.js → workspace-anchor-drift-19cJ1bH5.js} +1 -1
  354. package/server/{workspace-anchor-drift-CZKofakh.js → workspace-anchor-drift-C3mK5wNI.js} +4 -4
  355. package/server/{workspace-config-B123aZl-.js → workspace-config-CJ7RqQiP.js} +1 -1
  356. package/server/{workspace-C0fH3aek.js → workspace-iD8oULqu.js} +3 -3
  357. package/server/{workspace-manager-CDTKjjdU.js → workspace-manager-B38rFWA1.js} +1 -1
  358. package/server/{workspace-manager-CwO-Hek7.js → workspace-manager-CXfrw4rR.js} +13 -13
  359. package/server/{workspace-metadata-D4M8BM4W.js → workspace-metadata-BuMRco5P.js} +1 -1
  360. package/server/{workspace-metadata-CQv00QwK.js → workspace-metadata-eHSj_NsP.js} +2 -2
  361. package/server/{workspaces-j1e_6aAT.js → workspaces-DbtMX2TM.js} +136 -113
  362. package/sync-sources/skills/pan-merge/SKILL.md +7 -5
  363. package/sync-sources/skills/pan-release/SKILL.md +57 -0
  364. package/server/agent-state-service-hZpxIw1E.js +0 -2
  365. package/server/archive-planning-0FJ6Xd3b.js +0 -2
  366. package/server/cli-DmXETsw-.js +0 -3
  367. package/server/conflict-gate-Dh754uyA.js +0 -3
  368. package/server/deacon-swarm-I2JfX5Tg.js +0 -2
  369. package/server/dist-DSlxIU1H.js +0 -3
  370. package/server/durable-review-pipeline-jpgCJZFp.js +0 -3
  371. package/server/forge-DK3blQb_.js +0 -3
  372. package/server/hume-Dq--7rOQ.js +0 -3
  373. package/server/inspect-agent-BVwDrVrz.js +0 -2
  374. package/server/label-reconciler--F85rufp.js +0 -113
  375. package/server/merge-ops-DdpTiEMt.js +0 -2
  376. package/server/merge-rebase-DGQpYJU3.js +0 -2
  377. package/server/merge-sync-Ca7F5JnQ.js +0 -3
  378. package/server/public/assets/index-Cc7cnFC4.css +0 -1
  379. package/server/public/assets/mermaid-GHXKKRXX-DyDHFXHV.js +0 -1
  380. package/server/rally-YDjU513q.js +0 -3
  381. package/server/resume-u9byntrq.js +0 -3
  382. package/server/review-status-BZH8h-6W.js +0 -3
  383. package/server/settings-CdvIF84R.js +0 -2
  384. package/server/spawn-planning-session-1nFi3gfk.js +0 -2
  385. package/server/specs-Bt7WJDoC.js +0 -3
  386. package/server/supervisor-UWiQNK-y.js +0 -2
  387. package/server/token-util-zlz9U0ki.js +0 -3
  388. package/server/workflows-CHrx_hcW.js +0 -2
@@ -1,52 +1,57 @@
1
1
  import { i as __require, t as __commonJSMin } from "./rolldown-runtime-DNCzzKnI.js";
2
- import { Fr as init_errors, Gn as init_projects, Gr as OVERDECK_HOME, Ir as AGENTS_DIR, Pt as init_record, Yn as listProjectsSync, ar as resolveProjectFromIssueSync, b as DEFAULT_CONFIG$1, ci as init_paths, dn as reconcileStatePlaneDrift, f as loadConfigSync, fi as sessionFilePath, hn as init_state_plane, ln as init_auto_commit, mn as getMainDivergence, s as init_load, x as init_defaults, zn as getProjectSync, zt as readIssueRecordSync } from "./config-yaml-CmOPzmBb.js";
3
- import { n as init_build_info, t as getBuildInfo } from "./build-info-CuFfxZxp.js";
4
- import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-BNBebzeL.js";
2
+ import { Fr as init_errors, Gn as init_projects, Gr as OVERDECK_HOME, Ir as AGENTS_DIR, Pt as init_record, Yn as listProjectsSync, Zn as loadProjectsConfigSync, ar as resolveProjectFromIssueSync, b as DEFAULT_CONFIG$1, dn as reconcileStatePlaneDrift, f as loadConfigSync, hn as init_state_plane, li as init_paths, ln as init_auto_commit, mn as getMainDivergence, or as resolveProjectPath, pi as sessionFilePath, s as init_load, x as init_defaults, zn as getProjectSync, zt as readIssueRecordSync } from "./config-yaml-CxdwhAIA.js";
3
+ import { n as init_build_info, t as getBuildInfo } from "./build-info-D0q_i8WM.js";
4
+ import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-DPHsO14z.js";
5
5
  import { i as emitActivityTtsSync, o as init_activity_logger, r as emitActivityEntrySync } from "./activity-logger-CyteR4JO.js";
6
- import { i as updateIssueRecord, r as init_record_update } from "./record-update-Z0QCxmMp.js";
7
- import { A as listPaneValues, B as sendKeysAsync, D as killSession, E as isPaneDead, H as sessionExists, I as querySessionSync, M as listSessionNames, N as listSessions, U as sessionExistsSync, i as capturePane, w as init_tmux, z as sendKeys } from "./tmux-B1Wbxz5o.js";
8
- import { a as init_event_store, i as initEventStore } from "./event-store-zY5MJHgF.js";
9
- import { D as projectLegacySystemHealthSummary, t as init_src } from "./src-CRmCHlma.js";
10
- import { L as init_review_dispatch_decision, R as needsReviewDispatch, S as setReviewStatusSync, f as init_review_status, m as loadReviewStatuses, u as getReviewStatusSync, z as reviewGatesPassedSync } from "./review-status-yljtTd-q.js";
11
- import { c as listAllAgentsSync, d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-C5rWYhb6.js";
12
- import { $n as getAgentDir, Bt as init_transcript_landing, Ct as resetPatrolDispatchBudget, Et as workResumeSlotsAvailable, Fr as getAgentRuntimeState, G as resumeAgent, Ir as getAgentRuntimeStateSync, J as isContextOverflowTail, K as init_context_overflow, Ln as buildResumeContinueMessage, Lr as init_runtime_state, Ot as init_memory_verdict_cache, Pt as deliverInitialPromptWithRetry, Rr as saveAgentRuntimeState, Ur as init_codex_auth, Vr as applyCodexAuthBurnFlag, Wr as paneShowsCodexAuthBurn, X as messageAgent, Xn as clearAgentTroubledSync, Y as init_messaging, Zn as clearYieldForResumeSync, _ as init_linux, _r as saveAgentStateSync, _t as describeRunningAgents, a as listRunningAgentsSync, b as init_agents$1, br as setAgentYieldedSync, bt as init_concurrency, c as getRuntimeCensus, fr as recordAgentFailure, ft as init_termination, g as LINUX_MEMORY_PRESSURE_DEFAULTS, gr as saveAgentState, h as init_collector, hr as resetAgentFailureCount, ht as countRunningAgents, i as listRunningAgents, ir as init_agent_state, kt as setCachedMemoryVerdict, lr as markAgentRunningState, m as createHostHealthCollector, n as init_queries, pt as stopAgent, r as listAgentStates, rr as getAgentStateSync, s as descendantPidsForSession, tr as getAgentState, u as init_runtime_census, v as DARWIN_MEMORY_PRESSURE_DEFAULTS, wt as tryReserveAdvancingSlot, xt as releaseAdvancingSlot, y as init_darwin, yr as setAgentPausedSync, yt as getConcurrencyLimits, zt as captureTranscriptUserRecordSnapshot } from "./queries-DHJm7bTd.js";
13
- import { c as logDeaconEventSync, l as getRuntimeSnapshot, o as init_persistent_logger, s as logAgentLifecycleSync, u as init_agent_runtime_mirror } from "./session-history-BUyK29eq.js";
14
- import { n as resolveGitHubIssueSync, t as init_tracker_utils } from "./tracker-utils-L0FKtjq2.js";
15
- import { i as ensureInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-DvMTQSOS.js";
16
- import { c as init_review_status_sync, l as markWorkspaceStuck } from "./review-status-sync-483sujRo.js";
17
- import { i as readReviewStatusMap, n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-CpvJnvnQ.js";
18
- import { i as init_merge_set, r as getMergeSetSync } from "./merge-set-DH7ot3yz.js";
19
- import { m as readWorkspacePlanSync, o as init_io } from "./io-VHvc0Ssp.js";
20
- import { f as init_config, m as loadConfigSync$1, p as loadConfig$1 } from "./config-Dr3pW6w6.js";
21
- import { E as stampBootReconciliation, g as setBootReconciliationGrace, h as setBootReconciliationDecision, l as isDeaconGloballyPaused, r as getBootReconciliationState, s as init_control_settings } from "./control-settings-C7DUehE1.js";
22
- import { d as init_docker_stats, u as DockerStatsCollector } from "./stack-health-DqSqx0zv.js";
23
- import { l as init_dag, o as getDispatchableItems } from "./dag-ombYYt4s.js";
24
- import { a as loadCloisterConfigSync, i as loadCloisterConfig, r as init_config$1 } from "./config-B2IMcBxx.js";
25
- import { a as findRecreatedLegacyStatePaths, o as init_state_home } from "./state-home-BYV7qZTW.js";
26
- import { M as withConcurrencyLimit, j as init_concurrency$1 } from "./github-app-CQ1Lo6LA.js";
27
- import { a as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-mkLC6G_t.js";
28
- import { n as __filename, r as init_esm_shims } from "./esm-shims-Br9BPdkR.js";
29
- import { i as init_staleness, r as computeBuildStaleness } from "./staleness-D47CUJok.js";
30
- import { a as pidsWithCwdUnder, i as sweepAutoCloseOutCache, n as pruneTerminalStoppedAgents, r as getAutoCloseOutCanonicalState } from "./agent-gc-CBULruzm.js";
31
- import { n as init_issue_closed, r as isIssueClosed } from "./issue-closed-B6KJkmHZ.js";
32
- import { a as observeForgeMergeState, i as init_merge_completeness } from "./merge-completeness-BMm8tMyZ.js";
33
- import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-BG0RUZiu.js";
34
- import { r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-Dt9BsapX.js";
35
- import { a as init_review_monitor, i as REVIEW_SUB_ROLES, n as init_review_convoy_liveness, r as reviewTimestampMs, t as evaluateReviewConvoyLiveness } from "./review-convoy-liveness-CpzrcJ5F.js";
36
- import { J as parseReviewerSessionName, U as getTmuxSessionName, g as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-Cicieuzu.js";
37
- import { a as inferBranchFromWorkspace, i as findWorkspacePath } from "./archive-planning-C0lAbNB_.js";
38
- import { n as init_merge_verification, r as shouldSkipDispatchAsMerged } from "./merge-verification-x3JO8Dtz.js";
39
- import { n as init_review_verdict_feedback, t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-CELeUinh.js";
40
- import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-bNX6jKkb.js";
41
- import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-DBxUaO-A.js";
42
- import { n as isExplicitNoResumeRequest, t as init_no_resume_mode } from "./no-resume-mode-C5ULAXwO.js";
43
- import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-Bq3epG58.js";
44
- import { n as reconcileClosedIssueAgents } from "./closed-issue-reaper-Cltx86x5.js";
45
- import { n as init_label_reconciler, r as reconcilePipelineLabelsPatrol } from "./label-reconciler--F85rufp.js";
46
- import { t as recordDeadEndNeedsYou } from "./dead-end-trip-CQcP70ND.js";
47
- import { a as spawnWorkAgentThroughAgentsEndpoint, i as reconcileOrphanProposedSpecs, o as triggerRebuildAndStart } from "./orphan-proposed-reconciler-Dg6U4ADZ.js";
48
- import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-CnGx_PO_.js";
49
- import { i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-BJYDggMm.js";
6
+ import { i as updateIssueRecord, r as init_record_update } from "./record-update-DaOKS7Wb.js";
7
+ import { A as listPaneValues, B as sendKeysAsync, D as killSession, E as isPaneDead, H as sessionExists, I as querySessionSync, M as listSessionNames, N as listSessions, U as sessionExistsSync, i as capturePane, w as init_tmux, z as sendKeys } from "./tmux-CfDHob9M.js";
8
+ import { a as init_event_store, i as initEventStore } from "./event-store-CrHcVC5_.js";
9
+ import { D as projectLegacySystemHealthSummary, t as init_src } from "./src-B948bGVR.js";
10
+ import { B as reviewGatesPassedSync, C as setReviewStatusSync, H as findBlockingFindings, K as readJournalStatusSync, R as init_review_dispatch_decision, U as init_review_findings, W as init_review_status_record_sync, d as getReviewStatusSync, h as loadReviewStatuses, p as init_review_status, z as needsReviewDispatch } from "./review-status-CwhA9wmd.js";
11
+ import { n as logAgentLifecycleSync, r as logDeaconEventSync, t as init_persistent_logger } from "./persistent-logger-CBj016pT.js";
12
+ import { c as listAllAgentsSync, d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-CtACUuVG.js";
13
+ import { $n as getAgentDir, Br as saveAgentRuntimeState, Bt as init_transcript_landing, Ct as resetPatrolDispatchBudget, Et as workResumeSlotsAvailable, G as resumeAgent, Gr as init_codex_auth, J as isContextOverflowTail, K as init_context_overflow, Kr as paneShowsCodexAuthBurn, Ln as buildResumeContinueMessage, Lr as getAgentRuntimeState, Ot as init_memory_verdict_cache, Pt as deliverInitialPromptWithRetry, Rr as getAgentRuntimeStateSync, Ur as applyCodexAuthBurnFlag, X as messageAgent, Xn as clearAgentTroubledSync, Y as init_messaging, Zn as clearYieldForResumeSync, _ as init_linux, _r as saveAgentStateSync, _t as describeRunningAgents, a as listRunningAgentsSync, b as init_agents$1, br as setAgentYieldedSync, bt as init_concurrency, c as getRuntimeCensus, fr as recordAgentFailure, ft as init_termination, g as LINUX_MEMORY_PRESSURE_DEFAULTS, gr as saveAgentState, h as init_collector, hr as resetAgentFailureCount, ht as countRunningAgents, i as listRunningAgents, ir as init_agent_state, kt as setCachedMemoryVerdict, lr as markAgentRunningState, m as createHostHealthCollector, n as init_queries, pt as stopAgent, r as listAgentStates, rr as getAgentStateSync, s as descendantPidsForSession, tr as getAgentState, u as init_runtime_census, v as DARWIN_MEMORY_PRESSURE_DEFAULTS, wt as tryReserveAdvancingSlot, xt as releaseAdvancingSlot, y as init_darwin, yr as setAgentPausedSync, yt as getConcurrencyLimits, zr as init_runtime_state, zt as captureTranscriptUserRecordSnapshot } from "./queries-DCX27GRr.js";
14
+ import { o as getRuntimeSnapshot, s as init_agent_runtime_mirror } from "./session-history-C_EMhIIF.js";
15
+ import { n as resolveGitHubIssueSync, t as init_tracker_utils } from "./tracker-utils-DZZq_C0R.js";
16
+ import { i as ensureInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-BG6yQKNL.js";
17
+ import { c as init_review_status_sync, l as markWorkspaceStuck } from "./review-status-sync-h2CJX6ju.js";
18
+ import { i as readReviewStatusMap, n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-DWnFE0b6.js";
19
+ import { _ as markMerged, c as init_merge_sync, f as listActiveAutoMerges, m as listProblemAutoMerges, t as cancelPending } from "./merge-sync-CM978zez.js";
20
+ import { i as init_merge_set, r as getMergeSetSync } from "./merge-set-Dbnx4chw.js";
21
+ import { m as readWorkspacePlanSync, o as init_io } from "./io-C0NV7y6C.js";
22
+ import { f as init_config, m as loadConfigSync$1, p as loadConfig$1 } from "./config-CX4vk1CV.js";
23
+ import { D as setSetting, O as stampBootReconciliation, _ as setBootReconciliationGrace, c as init_control_settings, g as setBootReconciliationDecision, o as getLastCleanShutdownAt, r as getBootReconciliationState, s as getSetting, u as isDeaconGloballyPaused } from "./control-settings-qYYHrIqy.js";
24
+ import { d as init_docker_stats, u as DockerStatsCollector } from "./stack-health-Bf2WdG4E.js";
25
+ import { l as init_dag, o as getDispatchableItems } from "./dag-5QlmH0oC.js";
26
+ import { a as loadCloisterConfigSync, i as loadCloisterConfig, r as init_config$1 } from "./config-ktAVnp4s.js";
27
+ import { a as findRecreatedLegacyStatePaths, o as init_state_home } from "./state-home-B4EWfIxF.js";
28
+ import { M as withConcurrencyLimit, j as init_concurrency$1 } from "./github-app-gVnZcP9B.js";
29
+ import { a as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-DmY5UJLg.js";
30
+ import { n as __filename, r as init_esm_shims } from "./esm-shims-CaBWIR7f.js";
31
+ import { i as init_staleness, r as computeBuildStaleness } from "./staleness-45qZ_a60.js";
32
+ import { a as pidsWithCwdUnder, i as sweepAutoCloseOutCache, n as pruneTerminalStoppedAgents, r as getAutoCloseOutCanonicalState } from "./agent-gc-BMcgTDl7.js";
33
+ import { n as init_issue_closed, r as isIssueClosed } from "./issue-closed-CNNGbhWm.js";
34
+ import { n as getForgeAdapter, r as init_forge } from "./forge-RTNqJe6a.js";
35
+ import { a as observeForgeMergeState, i as init_merge_completeness } from "./merge-completeness-BUzPZy0E.js";
36
+ import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-xpFgU632.js";
37
+ import { n as resolveIssueFeedbackTarget, r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-VBr9gKgX.js";
38
+ import { a as init_review_monitor, i as REVIEW_SUB_ROLES, n as init_review_convoy_liveness, r as reviewTimestampMs, t as evaluateReviewConvoyLiveness } from "./review-convoy-liveness-l06_LYCt.js";
39
+ import { J as parseReviewerSessionName, U as getTmuxSessionName, g as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-Dfx9_Wzb.js";
40
+ import { a as inferBranchFromWorkspace, i as findWorkspacePath } from "./archive-planning-Binfb99i.js";
41
+ import { n as init_merge_verification, r as shouldSkipDispatchAsMerged } from "./merge-verification-c9Y9mllw.js";
42
+ import { a as findVerdictReportAsync, i as findVerdictReport, n as init_review_verdict_feedback, o as init_review_verdict_report, s as parseVerdictReport, t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-yrrmgps_.js";
43
+ import { _ as init_label_reconciler, a as gatherProjectLensSignals, s as init_pipeline_membership_gather, v as reconcilePipelineLabelsPatrol } from "./pipeline-membership-gather-BIcJ-N0W.js";
44
+ import { n as init_pipeline_membership, r as resolvePipelineMembership } from "./pipeline-membership-B2yUcBz7.js";
45
+ import { i as init_conflict_gate, o as probeBranchConflictPaths } from "./conflict-gate-BNv6UolH.js";
46
+ import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-GHomyBaD.js";
47
+ import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-DwGUgSVp.js";
48
+ import { n as isExplicitNoResumeRequest, t as init_no_resume_mode } from "./no-resume-mode-DZvP0M_S.js";
49
+ import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-nXEKoxI7.js";
50
+ import { r as reconcileClosedIssueAgents } from "./closed-issue-reaper-hLt0W86J.js";
51
+ import { t as recordDeadEndNeedsYou } from "./dead-end-trip-B06RFIr2.js";
52
+ import { a as spawnWorkAgentThroughAgentsEndpoint, i as reconcileOrphanProposedSpecs, o as triggerRebuildAndStart } from "./orphan-proposed-reconciler-DtQP6oE_.js";
53
+ import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-DQFh8rDh.js";
54
+ import { i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-Cy2jJGTe.js";
50
55
  import { createRequire } from "node:module";
51
56
  import { join } from "node:path";
52
57
  import { Effect } from "effect";
@@ -55,7 +60,7 @@ import { basename as basename$1, dirname as dirname$1, join as join$1 } from "pa
55
60
  import { cpus, loadavg } from "os";
56
61
  import { freemem as freemem$1, homedir as homedir$1, platform as platform$1, totalmem as totalmem$1 } from "node:os";
57
62
  import { closeSync as closeSync$1, existsSync as existsSync$1, openSync as openSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, unlinkSync as unlinkSync$1, writeFileSync as writeFileSync$1 } from "node:fs";
58
- import { readFile } from "node:fs/promises";
63
+ import { readFile, readdir, stat as stat$1 } from "node:fs/promises";
59
64
  import { readFile as readFile$1, readdir as readdir$1, writeFile as writeFile$1 } from "fs/promises";
60
65
  import { exec, execFile, execFileSync, spawn } from "node:child_process";
61
66
  import { promisify } from "node:util";
@@ -67,15 +72,20 @@ init_paths();
67
72
  init_errors();
68
73
  init_activity_logger();
69
74
  init_projects();
75
+ init_state_plane();
76
+ init_auto_commit();
77
+ init_record();
70
78
  init_tmux();
71
79
  init_src();
80
+ init_persistent_logger();
72
81
  init_agents();
73
82
  init_agent_runtime_mirror();
74
- init_persistent_logger();
75
83
  init_tracker_utils();
76
84
  init_review_status_sync();
77
85
  init_review_status_source();
86
+ init_merge_sync();
78
87
  init_merge_set();
88
+ init_review_status_record_sync();
79
89
  init_review_dispatch_decision();
80
90
  init_review_status();
81
91
  init_codex_auth();
@@ -22432,7 +22442,7 @@ function acceptedReasons(state, hostReasons, agents, services) {
22432
22442
  //#endregion
22433
22443
  //#region services/system-health-service.ts
22434
22444
  init_review_status_source();
22435
- const execAsync$3 = promisify(exec);
22445
+ const execAsync$4 = promisify(exec);
22436
22446
  const KB = 1024;
22437
22447
  const GIB$1 = 1024 ** 3;
22438
22448
  function parseMemoryPsi(content) {
@@ -22560,7 +22570,7 @@ async function readProcMemoryDarwin() {
22560
22570
  let memAvailable = freemem$1();
22561
22571
  let memFree = freemem$1();
22562
22572
  try {
22563
- const { stdout } = await execAsync$3("vm_stat", {
22573
+ const { stdout } = await execAsync$4("vm_stat", {
22564
22574
  encoding: "utf-8",
22565
22575
  timeout: 5e3
22566
22576
  });
@@ -22580,7 +22590,7 @@ async function readProcMemoryDarwin() {
22580
22590
  let swapTotal = 0;
22581
22591
  let swapFree = 0;
22582
22592
  try {
22583
- const { stdout } = await execAsync$3("sysctl -n vm.swapusage", {
22593
+ const { stdout } = await execAsync$4("sysctl -n vm.swapusage", {
22584
22594
  encoding: "utf-8",
22585
22595
  timeout: 5e3
22586
22596
  });
@@ -23148,11 +23158,10 @@ async function assessMemoryPressure() {
23148
23158
  }
23149
23159
  //#endregion
23150
23160
  //#region ../../lib/cloister/agent-grace.ts
23151
- init_state_plane();
23152
- init_auto_commit();
23153
- init_record();
23154
23161
  init_record_update();
23155
23162
  init_internal_token();
23163
+ init_review_findings();
23164
+ init_control_settings();
23156
23165
  const WORK_LAUNCHER_GRACE_MS = 12e4;
23157
23166
  function isStartingWithinGrace(state, now = Date.now(), graceMs = WORK_LAUNCHER_GRACE_MS) {
23158
23167
  if (state.status !== "starting") return false;
@@ -23202,7 +23211,7 @@ async function checkInspectAgentTimeouts(now = /* @__PURE__ */ new Date()) {
23202
23211
  console.warn(`[deacon] Failed to kill inspect session ${sessionName}: ${msg}`);
23203
23212
  });
23204
23213
  try {
23205
- const { messageAgent } = await import("./agents-BKKkxKgK.js");
23214
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
23206
23215
  await messageAgent(`agent-${issueId.toLowerCase()}`, verdict, "deacon:inspect-watchdog");
23207
23216
  } catch (err) {
23208
23217
  const msg = err instanceof Error ? err.message : String(err);
@@ -23396,7 +23405,7 @@ async function maybeProactivelyCompactContext(sessionName, now) {
23396
23405
  if (!agentState?.workspace || !sessionId || !agentState.model) return null;
23397
23406
  let usage = null;
23398
23407
  try {
23399
- const { computeContextUsage } = await import("./conversation-service-BCxl4f8Z.js");
23408
+ const { computeContextUsage } = await import("./conversation-service-CDnQ3ayN.js");
23400
23409
  usage = await computeContextUsage(sessionFilePath(agentState.workspace, sessionId), agentState.model);
23401
23410
  } catch {
23402
23411
  return null;
@@ -23495,9 +23504,9 @@ async function checkApiErrorAgents() {
23495
23504
  }
23496
23505
  if (!tmuxOutput.includes("❯")) continue;
23497
23506
  try {
23498
- const { maybeContinueCompactedAgent } = await import("./compaction-continuation-K2AxQX4H.js");
23499
- const { findLastCompactBoundary } = await import("./conversation-service-BCxl4f8Z.js");
23500
- const { deliverAgentMessage } = await import("./delivery-Da0zEMY4.js");
23507
+ const { maybeContinueCompactedAgent } = await import("./compaction-continuation-DtMfHN0f.js");
23508
+ const { findLastCompactBoundary } = await import("./conversation-service-CDnQ3ayN.js");
23509
+ const { deliverAgentMessage } = await import("./delivery-C2M73sBg.js");
23501
23510
  const continued = await maybeContinueCompactedAgent({
23502
23511
  agentId: sessionName,
23503
23512
  tmuxOutput,
@@ -23548,13 +23557,13 @@ async function checkApiErrorAgents() {
23548
23557
  const st = getAgentStateSync(sessionName);
23549
23558
  const sid = st?.sessionId ?? runtimeState?.claudeSessionId;
23550
23559
  if (st?.workspace && sid && st.model) {
23551
- const { computeContextUsage } = await import("./conversation-service-BCxl4f8Z.js");
23560
+ const { computeContextUsage } = await import("./conversation-service-CDnQ3ayN.js");
23552
23561
  const usage = await computeContextUsage(sessionFilePath(st.workspace, sid), st.model);
23553
23562
  if (usage && usage.percentUsed < 85) recoveredPct = usage.percentUsed;
23554
23563
  }
23555
23564
  } catch {}
23556
23565
  if (recoveredPct !== null) {
23557
- const { clearWorkspaceStuck } = await import("./review-status-sync-NaWvI9Xf.js");
23566
+ const { clearWorkspaceStuck } = await import("./review-status-sync-B0IS6Beh.js");
23558
23567
  clearWorkspaceStuck(issueId);
23559
23568
  stuckOverflowNativeRecoveryState.delete(sessionName);
23560
23569
  actions.push(`Context overflow recovery: cleared stuck flag for ${sessionName} (context back to ${Math.round(recoveredPct)}%)`);
@@ -23570,7 +23579,7 @@ async function checkApiErrorAgents() {
23570
23579
  rec.attempts += 1;
23571
23580
  rec.lastAttempt = now;
23572
23581
  stuckOverflowNativeRecoveryState.set(sessionName, rec);
23573
- const { resumeAgent } = await import("./agents-BKKkxKgK.js");
23582
+ const { resumeAgent } = await import("./agents-Dnn4XgdB.js");
23574
23583
  const recovered = await resumeAgent(sessionName, void 0, { compact: true });
23575
23584
  if (recovered.success) {
23576
23585
  stuckOverflowNativeRecoveryState.delete(sessionName);
@@ -23618,7 +23627,7 @@ async function checkApiErrorAgents() {
23618
23627
  }
23619
23628
  const compactAttempts = (ov?.compactAttempts ?? 0) + 1;
23620
23629
  if (issueId !== null) {
23621
- const { resumeAgent } = await import("./agents-BKKkxKgK.js");
23630
+ const { resumeAgent } = await import("./agents-Dnn4XgdB.js");
23622
23631
  const resumeResult = await resumeAgent(sessionName, void 0, { compact: true });
23623
23632
  contextOverflowRecoveryState.set(sessionName, {
23624
23633
  lastAttempt: now,
@@ -23737,7 +23746,7 @@ function isStuckMergingState(status, now) {
23737
23746
  }
23738
23747
  async function readSpecStatus(projectPath, issueId) {
23739
23748
  try {
23740
- const { findSpecByIssue } = await import("./specs-Bt7WJDoC.js");
23749
+ const { findSpecByIssue } = await import("./specs-DKV3jIEs.js");
23741
23750
  return (await Effect.runPromise(findSpecByIssue(projectPath, issueId)))?.status;
23742
23751
  } catch {
23743
23752
  return;
@@ -23819,13 +23828,151 @@ async function reconcileStuckMergingStates() {
23819
23828
  reviewGatesPassed: reviewGatesPassedSync,
23820
23829
  setReviewStatus: setReviewStatusSync,
23821
23830
  enqueuePostMerge: async (issueId, projectPath, branch) => {
23822
- const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DbO10pum.js");
23831
+ const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-3u_rA4R0.js");
23823
23832
  return enqueuePostMergeLifecycle(issueId, projectPath, branch);
23824
23833
  },
23825
23834
  warn: (message) => console.warn(message)
23826
23835
  });
23827
23836
  }
23828
23837
  //#endregion
23838
+ //#region ../../lib/cloister/deacon-auto-merge-reconcile.ts
23839
+ init_forge();
23840
+ init_merge_set();
23841
+ init_projects();
23842
+ const AUTO_MERGE_RECONCILE_COOLDOWN_MS = 600 * 1e3;
23843
+ const UNBOUNDED_ROW_LIMIT = -1;
23844
+ const autoMergeReconcileCooldowns = /* @__PURE__ */ new Map();
23845
+ const autoMergeLastCheckedAt = /* @__PURE__ */ new Map();
23846
+ function groupByIssue(rows) {
23847
+ const grouped = /* @__PURE__ */ new Map();
23848
+ for (const row of rows) {
23849
+ const issueRows = grouped.get(row.issueId) ?? [];
23850
+ issueRows.push(row);
23851
+ grouped.set(row.issueId, issueRows);
23852
+ }
23853
+ return grouped;
23854
+ }
23855
+ function normalizeArtifactUrl(url) {
23856
+ return url.replace(/[?#].*$/, "").replace(/\/+$/, "");
23857
+ }
23858
+ function repositoryFromArtifactUrl(url, forge) {
23859
+ try {
23860
+ const parsed = new URL(url);
23861
+ if (forge === "github" && parsed.hostname.toLowerCase() !== "github.com") return void 0;
23862
+ const marker = forge === "gitlab" ? "/-/merge_requests/" : "/pull/";
23863
+ const markerIndex = parsed.pathname.indexOf(marker);
23864
+ if (markerIndex <= 1) return void 0;
23865
+ return parsed.pathname.slice(1, markerIndex);
23866
+ } catch {
23867
+ return;
23868
+ }
23869
+ }
23870
+ function pruneTracking(activeIssueIds) {
23871
+ for (const issueId of autoMergeReconcileCooldowns.keys()) if (!activeIssueIds.has(issueId)) autoMergeReconcileCooldowns.delete(issueId);
23872
+ for (const issueId of autoMergeLastCheckedAt.keys()) if (!activeIssueIds.has(issueId)) autoMergeLastCheckedAt.delete(issueId);
23873
+ }
23874
+ async function reconcileForgeCandidate(candidate, deps, now) {
23875
+ const { issueId, problemRows, representative, artifactRepo, projectPath } = candidate;
23876
+ autoMergeLastCheckedAt.set(issueId, now);
23877
+ try {
23878
+ const repository = repositoryFromArtifactUrl(representative.prUrl, representative.forge);
23879
+ if (!await deps.getForgeAdapter(representative.forge).findMergedArtifact({
23880
+ sourceBranch: artifactRepo?.sourceBranch ?? `feature/${issueId.toLowerCase()}`,
23881
+ ...artifactRepo?.targetBranch ? { targetBranch: artifactRepo.targetBranch } : {},
23882
+ artifactUrl: representative.prUrl,
23883
+ ...artifactRepo?.artifactId ? { artifactId: artifactRepo.artifactId } : {},
23884
+ ...repository ? { repository } : {},
23885
+ cwd: artifactRepo?.repoPath ?? projectPath
23886
+ })) {
23887
+ autoMergeReconcileCooldowns.set(issueId, now + AUTO_MERGE_RECONCILE_COOLDOWN_MS);
23888
+ return [];
23889
+ }
23890
+ const actions = [];
23891
+ for (const row of problemRows) {
23892
+ if (!deps.markMerged(row.id)) continue;
23893
+ const action = `Reconciled auto-merge row ${row.id} for ${issueId} — forge confirms the merge`;
23894
+ actions.push(action);
23895
+ deps.log(`[deacon] ${action}`);
23896
+ }
23897
+ autoMergeReconcileCooldowns.delete(issueId);
23898
+ return actions;
23899
+ } catch (error) {
23900
+ autoMergeReconcileCooldowns.set(issueId, now + AUTO_MERGE_RECONCILE_COOLDOWN_MS);
23901
+ deps.warn(`[deacon] Auto-merge row reconciliation failed for ${issueId}: ${error instanceof Error ? error.message : String(error)}`);
23902
+ return [];
23903
+ }
23904
+ }
23905
+ async function reconcileAutoMergeRowsWithDeps(deps) {
23906
+ const actions = [];
23907
+ const now = deps.now();
23908
+ let rows;
23909
+ try {
23910
+ rows = [...deps.listProblemAutoMerges(UNBOUNDED_ROW_LIMIT), ...deps.listActiveAutoMerges(UNBOUNDED_ROW_LIMIT).filter((row) => row.status === "pending")];
23911
+ } catch (error) {
23912
+ deps.warn(`[deacon] Auto-merge row reconciliation failed to list rows: ${error instanceof Error ? error.message : String(error)}`);
23913
+ return actions;
23914
+ }
23915
+ const grouped = groupByIssue(rows);
23916
+ pruneTracking(new Set(grouped.keys()));
23917
+ const forgeCandidates = [];
23918
+ for (const [issueId, issueRows] of grouped) {
23919
+ const cooledUntil = autoMergeReconcileCooldowns.get(issueId);
23920
+ if (cooledUntil && now < cooledUntil) continue;
23921
+ try {
23922
+ if (deps.readJournalStatus(issueId)?.durable.closedOut === true) {
23923
+ for (const row of issueRows) {
23924
+ if (!deps.cancelPending(row.id, "auto-merge-reconciler")) continue;
23925
+ const action = `Cancelled closed-out auto-merge row ${row.id} for ${issueId}`;
23926
+ actions.push(action);
23927
+ deps.log(`[deacon] ${action}`);
23928
+ }
23929
+ autoMergeReconcileCooldowns.delete(issueId);
23930
+ autoMergeLastCheckedAt.delete(issueId);
23931
+ continue;
23932
+ }
23933
+ const problemRows = issueRows.filter((row) => row.status === "blocked" || row.status === "failed");
23934
+ if (problemRows.length === 0) continue;
23935
+ const representative = problemRows.reduce((latest, row) => row.id > latest.id ? row : latest);
23936
+ const project = deps.resolveProject(issueId);
23937
+ if (!project) throw new Error(`project resolution failed for ${issueId}`);
23938
+ const artifactUrl = normalizeArtifactUrl(representative.prUrl);
23939
+ const artifactRepo = deps.getMergeSet(issueId)?.repos.find((repo) => repo.forge === representative.forge && repo.artifactUrl !== void 0 && normalizeArtifactUrl(repo.artifactUrl) === artifactUrl);
23940
+ forgeCandidates.push({
23941
+ issueId,
23942
+ problemRows,
23943
+ representative,
23944
+ artifactRepo,
23945
+ projectPath: project.projectPath
23946
+ });
23947
+ } catch (error) {
23948
+ autoMergeReconcileCooldowns.set(issueId, now + AUTO_MERGE_RECONCILE_COOLDOWN_MS);
23949
+ deps.warn(`[deacon] Auto-merge row reconciliation failed for ${issueId}: ${error instanceof Error ? error.message : String(error)}`);
23950
+ }
23951
+ }
23952
+ forgeCandidates.sort((left, right) => {
23953
+ return (autoMergeLastCheckedAt.get(left.issueId) ?? 0) - (autoMergeLastCheckedAt.get(right.issueId) ?? 0) || left.representative.id - right.representative.id;
23954
+ });
23955
+ const batch = forgeCandidates.slice(0, 4);
23956
+ const reconciled = await Promise.all(batch.map((candidate) => reconcileForgeCandidate(candidate, deps, now)));
23957
+ for (const candidateActions of reconciled) actions.push(...candidateActions);
23958
+ return actions;
23959
+ }
23960
+ async function reconcileAutoMergeRows() {
23961
+ return reconcileAutoMergeRowsWithDeps({
23962
+ now: Date.now,
23963
+ listProblemAutoMerges,
23964
+ listActiveAutoMerges,
23965
+ cancelPending,
23966
+ markMerged,
23967
+ readJournalStatus: readJournalStatusSync,
23968
+ getMergeSet: getMergeSetSync,
23969
+ resolveProject: resolveProjectFromIssueSync,
23970
+ getForgeAdapter,
23971
+ log: (message) => console.log(message),
23972
+ warn: (message) => console.warn(message)
23973
+ });
23974
+ }
23975
+ //#endregion
23829
23976
  //#region ../../lib/cloister/deacon-merge.ts
23830
23977
  init_paths();
23831
23978
  init_activity_logger();
@@ -23836,7 +23983,7 @@ init_tracker_utils();
23836
23983
  init_merge_set();
23837
23984
  init_tmux();
23838
23985
  init_config$1();
23839
- const execAsync$2 = promisify$1(exec);
23986
+ const execAsync$3 = promisify$1(exec);
23840
23987
  const execFileAsync$4 = promisify$1(execFile);
23841
23988
  const ciRetryMap = /* @__PURE__ */ new Map();
23842
23989
  const MERGE_READY_REMINDER_MS = 3600 * 1e3;
@@ -23926,7 +24073,7 @@ async function reconcileStaleMergeStatus() {
23926
24073
  ].includes(status.mergeStatus ?? "") || ["merging", "failed"].includes(mergeSet?.status ?? "");
23927
24074
  let specStatus;
23928
24075
  try {
23929
- const { findSpecByIssue } = await import("./specs-Bt7WJDoC.js");
24076
+ const { findSpecByIssue } = await import("./specs-DKV3jIEs.js");
23930
24077
  const spec = await Effect.runPromise(findSpecByIssue(project.projectPath, issueId));
23931
24078
  specStatus = spec?.status;
23932
24079
  if (spec && (spec.status === "completed" || spec.status === "cancelled")) {
@@ -23936,7 +24083,7 @@ async function reconcileStaleMergeStatus() {
23936
24083
  } catch {}
23937
24084
  const branch = `feature/${issueId.toLowerCase()}`;
23938
24085
  if (postMergeIncomplete) {
23939
- const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DbO10pum.js");
24086
+ const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-3u_rA4R0.js");
23940
24087
  const action = enqueuePostMergeLifecycle(issueId, project.projectPath, branch);
23941
24088
  if (action) actions.push(action);
23942
24089
  continue;
@@ -23948,7 +24095,7 @@ async function reconcileStaleMergeStatus() {
23948
24095
  } catch {}
23949
24096
  if (!isMerged) isMerged = (await observeGitHubBranchMerge(issueId, branch, project.projectPath)).merged;
23950
24097
  if (shouldObserveForge && mergeRelevant) try {
23951
- const observation = await (await import("./merge-completeness-D0ljXbk3.js")).observeForgeMergeState(issueId);
24098
+ const observation = await (await import("./merge-completeness-CghMbyX7.js")).observeForgeMergeState(issueId);
23952
24099
  const blocker = observation.repos.find((repo) => repo.state === "unverifiable");
23953
24100
  if (blocker) {
23954
24101
  console.warn(`[deacon] ${issueId}: forge merge state is unverifiable — ${blocker.reason}`);
@@ -23975,7 +24122,7 @@ async function reconcileStaleMergeStatus() {
23975
24122
  const msg = `Reconciled stale mergeStatus for ${issueId} — branch ${branch} is merged to main`;
23976
24123
  actions.push(msg);
23977
24124
  console.log(`[deacon] ${msg}`);
23978
- const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DbO10pum.js");
24125
+ const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-3u_rA4R0.js");
23979
24126
  const action = enqueuePostMergeLifecycle(issueId, project.projectPath, branch);
23980
24127
  if (action) actions.push(action);
23981
24128
  }
@@ -23998,7 +24145,7 @@ const falseMergedReset = /* @__PURE__ */ new Set();
23998
24145
  async function reconcileFalseMerged() {
23999
24146
  const actions = [];
24000
24147
  try {
24001
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DtAsvwzK.js");
24148
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DIE8BkHI.js");
24002
24149
  if (!isGitHubAppConfigured()) return actions;
24003
24150
  const statuses = loadReviewStatuses();
24004
24151
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -24043,7 +24190,7 @@ const CLOSED_PR_RECONCILE_COOLDOWN_MS = 600 * 1e3;
24043
24190
  async function reconcileClosedPrReadyForMerge() {
24044
24191
  const actions = [];
24045
24192
  try {
24046
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DtAsvwzK.js");
24193
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DIE8BkHI.js");
24047
24194
  if (!isGitHubAppConfigured()) return actions;
24048
24195
  const statuses = loadReviewStatuses();
24049
24196
  const now = Date.now();
@@ -24115,7 +24262,7 @@ const STALE_MERGE_BLOCKER_COOLDOWN_MS = 120 * 1e3;
24115
24262
  async function reconcileStaleMergeBlockers() {
24116
24263
  const actions = [];
24117
24264
  try {
24118
- const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-Dh754uyA.js");
24265
+ const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-BSTlwCtF.js");
24119
24266
  const statuses = loadReviewStatuses();
24120
24267
  const now = Date.now();
24121
24268
  const deps = buildRealConflictGateDeps();
@@ -24258,7 +24405,7 @@ async function checkFailedMergeRetry() {
24258
24405
  if (ciEntry.count === 5) {
24259
24406
  console.log(`[deacon] CI check failure for ${issueId} — retries exhausted, notifying work agent`);
24260
24407
  const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
24261
- const { writeFeedbackFile } = await import("./feedback-writer-D1fm-5Z8.js");
24408
+ const { writeFeedbackFile } = await import("./feedback-writer-CY91ckuw.js");
24262
24409
  const ciFileResult = await Effect.runPromise(writeFeedbackFile({
24263
24410
  issueId,
24264
24411
  specialist: "merge-agent",
@@ -24290,7 +24437,7 @@ async function checkFailedMergeRetry() {
24290
24437
  ciRetryMap.set(issueId, ciEntry);
24291
24438
  console.log(`[deacon] CI check failure for ${issueId} — notifying agent to re-submit (attempt ${ciEntry.count}/5)`);
24292
24439
  const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
24293
- const { writeFeedbackFile } = await import("./feedback-writer-D1fm-5Z8.js");
24440
+ const { writeFeedbackFile } = await import("./feedback-writer-CY91ckuw.js");
24294
24441
  const ciFileResult2 = await Effect.runPromise(writeFeedbackFile({
24295
24442
  issueId,
24296
24443
  specialist: "merge-agent",
@@ -24318,7 +24465,7 @@ async function checkFailedMergeRetry() {
24318
24465
  const lastNudge = timeoutNudgeCooldowns.get(issueIdForFb);
24319
24466
  if (!lastNudge || now - lastNudge >= TIMEOUT_NUDGE_COOLDOWN_MS) {
24320
24467
  const timeoutNotes = status.mergeNotes;
24321
- const { writeFeedbackFile } = await import("./feedback-writer-D1fm-5Z8.js");
24468
+ const { writeFeedbackFile } = await import("./feedback-writer-CY91ckuw.js");
24322
24469
  await Effect.runPromise(writeFeedbackFile({
24323
24470
  issueId: issueIdForFb,
24324
24471
  specialist: "merge-agent",
@@ -24423,7 +24570,7 @@ async function autoCloseOut(now = /* @__PURE__ */ new Date()) {
24423
24570
  } } : {}
24424
24571
  };
24425
24572
  try {
24426
- const { closeOut } = await import("./workflows-CHrx_hcW.js");
24573
+ const { closeOut } = await import("./workflows-DN6NyVGd.js");
24427
24574
  const result = await Effect.runPromise(closeOut(ctx));
24428
24575
  if (!result.success) {
24429
24576
  const failed = result.steps.find((step) => !step.success && !step.skipped);
@@ -24509,13 +24656,13 @@ async function checkFirstCompletionAgents() {
24509
24656
  if (!agentState?.workspace || !existsSync(agentState.workspace)) continue;
24510
24657
  let hasCommits = false;
24511
24658
  try {
24512
- const { stdout: gitLog } = await execAsync$2("git log --oneline -3 2>/dev/null", { cwd: agentState.workspace });
24659
+ const { stdout: gitLog } = await execAsync$3("git log --oneline -3 2>/dev/null", { cwd: agentState.workspace });
24513
24660
  hasCommits = gitLog.trim().length > 0;
24514
24661
  } catch {
24515
24662
  try {
24516
24663
  const subdirs = readdirSync(agentState.workspace, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith("."));
24517
24664
  for (const sub of subdirs) try {
24518
- const { stdout: subLog } = await execAsync$2("git log --oneline -3 2>/dev/null", { cwd: join$1(agentState.workspace, sub.name) });
24665
+ const { stdout: subLog } = await execAsync$3("git log --oneline -3 2>/dev/null", { cwd: join$1(agentState.workspace, sub.name) });
24519
24666
  if (subLog.trim().length > 0) {
24520
24667
  hasCommits = true;
24521
24668
  break;
@@ -24736,7 +24883,7 @@ async function checkPostReviewCommits() {
24736
24883
  const actions = [];
24737
24884
  try {
24738
24885
  const statuses = loadReviewStatuses();
24739
- const { resolveProjectFromIssueSync } = await import("./projects-B03Wr-xc.js");
24886
+ const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
24740
24887
  for (const [issueId, status] of Object.entries(statuses)) {
24741
24888
  const isBlocked = status.reviewStatus === "blocked";
24742
24889
  if (!isBlocked) blockedReviewDriftObservations.delete(issueId);
@@ -24766,8 +24913,8 @@ async function checkPostReviewCommits() {
24766
24913
  if (!project) continue;
24767
24914
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
24768
24915
  if (!existsSync(workspacePath)) continue;
24769
- const { formatAnchorShort, rehydrateHeadAnchor } = await import("./git-utils-CI6cwyyC.js");
24770
- const { evaluateWorkspaceAnchorDrift } = await import("./workspace-anchor-drift-B4gMRHl4.js");
24916
+ const { formatAnchorShort, rehydrateHeadAnchor } = await import("./git-utils-CedsVume.js");
24917
+ const { evaluateWorkspaceAnchorDrift } = await import("./workspace-anchor-drift-19cJ1bH5.js");
24771
24918
  const verdict = await evaluateWorkspaceAnchorDrift(issueId, workspacePath, rehydrateHeadAnchor(reviewedAnchor));
24772
24919
  if (verdict.kind === "unreadable" || verdict.kind === "current") {
24773
24920
  blockedReviewDriftObservations.delete(issueId);
@@ -24817,7 +24964,7 @@ async function checkPostReviewCommits() {
24817
24964
  actions.push(`Deferred post-review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
24818
24965
  logDeaconEventSync(`checkPostReviewCommits: deferred review for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
24819
24966
  } else if (freshStatus?.reviewStatus === "pending") {
24820
- const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
24967
+ const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
24821
24968
  const branch = `feature/${issueId.toLowerCase()}`;
24822
24969
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
24823
24970
  issueId,
@@ -25198,7 +25345,7 @@ function reviewConvoyLiveness(issueId) {
25198
25345
  */
25199
25346
  async function recoverUnhealthyTestStack(issueId, workspacePath) {
25200
25347
  const key = issueId.toUpperCase();
25201
- const { getWorkspaceStackHealth } = await import("./stack-health-CJLMrLBl.js");
25348
+ const { getWorkspaceStackHealth } = await import("./stack-health-CoWAhA99.js");
25202
25349
  const health = await Effect.runPromise(getWorkspaceStackHealth(issueId, { workspacePath }));
25203
25350
  if (health.healthy) {
25204
25351
  testStackRebuildState.delete(key);
@@ -25230,7 +25377,7 @@ async function recoverUnhealthyTestStack(issueId, workspacePath) {
25230
25377
  record.attempts += 1;
25231
25378
  testStackRebuildState.set(key, record);
25232
25379
  console.log(`[deacon] Test stack for ${key} unhealthy (${health.reasons.join("; ")}) — rebuilding (attempt ${record.attempts}/${TEST_STACK_REBUILD_MAX_ATTEMPTS})`);
25233
- const { rebuildWorkspaceStack } = await import("./rebuild-stack-qeRqHZxH.js");
25380
+ const { rebuildWorkspaceStack } = await import("./rebuild-stack-BKYpIPDL.js");
25234
25381
  const result = await Effect.runPromise(rebuildWorkspaceStack(issueId, { onProgress: (m) => console.log(`[deacon] ${key} stack rebuild: ${m}`) }));
25235
25382
  if (!result.success) {
25236
25383
  console.warn(`[deacon] Test stack rebuild failed for ${key}: ${result.error}`);
@@ -25398,7 +25545,7 @@ async function handleReviewCoordinatorDied(issueId, _sessionName, _reason) {
25398
25545
  return actions;
25399
25546
  }
25400
25547
  try {
25401
- const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
25548
+ const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
25402
25549
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
25403
25550
  issueId,
25404
25551
  workspace,
@@ -25473,7 +25620,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25473
25620
  const issueLower = issueId.toLowerCase();
25474
25621
  const workspace = getAgentStateSync(`agent-${issueLower}`)?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
25475
25622
  if (workspace) try {
25476
- if ((options.readWorkspaceHead ? await options.readWorkspaceHead(workspace) : await (await import("./git-utils-CI6cwyyC.js")).snapshotWorkspaceHeadsPromise(issueId, workspace)) === status.lastVerifiedCommit) {
25623
+ if ((options.readWorkspaceHead ? await options.readWorkspaceHead(workspace) : await (await import("./git-utils-CedsVume.js")).snapshotWorkspaceHeadsPromise(issueId, workspace)) === status.lastVerifiedCommit) {
25477
25624
  setReviewStatusSync(issueId, {
25478
25625
  reviewStatus: "pending",
25479
25626
  reviewNotes: void 0
@@ -25495,7 +25642,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25495
25642
  if (project) {
25496
25643
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
25497
25644
  if (existsSync(workspacePath)) {
25498
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CI6cwyyC.js");
25645
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CedsVume.js");
25499
25646
  reviewUpdate["reviewedAtCommit"] = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);
25500
25647
  }
25501
25648
  }
@@ -25550,7 +25697,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25550
25697
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
25551
25698
  if (workspace && resolved && !tryReserveAdvancingSlot() && !await tryYieldForAdvancingDispatch("review", issueId)) actions.push(`Deferred review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
25552
25699
  else if (workspace && resolved) try {
25553
- const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
25700
+ const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
25554
25701
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
25555
25702
  issueId,
25556
25703
  workspace,
@@ -25575,8 +25722,8 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25575
25722
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
25576
25723
  if (workspace && resolved) {
25577
25724
  const branch = `feature/${issueLower}`;
25578
- const { spawnRun } = await import("./agents-BKKkxKgK.js");
25579
- const { buildTestRolePrompt } = await import("./test-agent-queue-qakFIIGz.js");
25725
+ const { spawnRun } = await import("./agents-Dnn4XgdB.js");
25726
+ const { buildTestRolePrompt } = await import("./test-agent-queue-DmSIqays.js");
25580
25727
  const stackRecovery = await recoverUnhealthyTestStack(issueId, workspace);
25581
25728
  if (stackRecovery === "cooldown" || stackRecovery === "exhausted") {
25582
25729
  setReviewStatusSync(issueId, { testStatus: "dispatch_failed" });
@@ -25592,7 +25739,8 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25592
25739
  issueId,
25593
25740
  workspace,
25594
25741
  branch
25595
- })
25742
+ }),
25743
+ startedBy: "deacon:orphan-test-recovery"
25596
25744
  });
25597
25745
  testStackRebuildState.delete(issueId.toUpperCase());
25598
25746
  setReviewStatusSync(issueId, { testStatus: "testing" });
@@ -25714,7 +25862,7 @@ async function recoverStalledReviewConvoys(getCanonicalState = getAutoCloseOutCa
25714
25862
  record.lastAttempt = now;
25715
25863
  record.attempts += 1;
25716
25864
  stalledReviewConvoyRecoveryState.set(key, record);
25717
- const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
25865
+ const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
25718
25866
  try {
25719
25867
  const result = await Effect.runPromise(spawnReviewRoleForIssue({
25720
25868
  issueId,
@@ -25785,7 +25933,7 @@ async function checkMissingReviewStatuses() {
25785
25933
  continue;
25786
25934
  }
25787
25935
  try {
25788
- const { spawnReviewRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
25936
+ const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
25789
25937
  await Effect.runPromise(spawnReviewRoleForIssue({
25790
25938
  issueId,
25791
25939
  workspace,
@@ -25813,11 +25961,14 @@ async function checkMissingReviewStatuses() {
25813
25961
  //#endregion
25814
25962
  //#region ../../lib/cloister/deacon-review-unsignaled.ts
25815
25963
  init_agents$1();
25964
+ init_activity_logger();
25816
25965
  init_projects();
25817
25966
  init_review_status();
25818
25967
  init_specialists();
25819
25968
  init_tmux();
25820
25969
  init_review_convoy_liveness();
25970
+ init_review_verdict_feedback();
25971
+ init_review_verdict_report();
25821
25972
  /**
25822
25973
  * Detect issues stuck in `reviewing` status with no active review session.
25823
25974
  *
@@ -25836,7 +25987,7 @@ async function checkStuckReviewing() {
25836
25987
  const actions = [];
25837
25988
  const REVIEW_STUCK_THRESHOLD_MS = 1800 * 1e3;
25838
25989
  try {
25839
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-BZH8h-6W.js");
25990
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-CacDM78F.js");
25840
25991
  const statuses = loadReviewStatuses();
25841
25992
  const now = Date.now();
25842
25993
  const activeReviewIssues = /* @__PURE__ */ new Set();
@@ -25894,25 +26045,183 @@ async function checkStuckReviewing() {
25894
26045
  * - Only nudges once per review cycle (tracked by runId in the review dir)
25895
26046
  */
25896
26047
  const unsignaledReviewNudges = /* @__PURE__ */ new Map();
25897
- function isSynthesisForActiveReviewRun(dirPath, status, synthesisMtimeMs) {
26048
+ const pendingVerdictNudges = /* @__PURE__ */ new Map();
26049
+ function reviewAnchorFromContext(context) {
26050
+ if (context.repos) {
26051
+ if (context.repos.length === 0) return void 0;
26052
+ const heads = [];
26053
+ for (const repo of context.repos) {
26054
+ if (!repo.repoKey?.trim() || !repo.headSha?.trim()) return void 0;
26055
+ heads.push(`${repo.repoKey.trim()}@${repo.headSha.trim()}`);
26056
+ }
26057
+ return heads.join(" ");
26058
+ }
26059
+ return context.headSha?.trim() || void 0;
26060
+ }
26061
+ function shellQuote(value) {
26062
+ return `'${value.replaceAll("'", "'\\''")}'`;
26063
+ }
26064
+ function buildReviewCompletionCommand(issueId, verdict, notes, runId) {
26065
+ let command = `pan admin specialists done review ${shellQuote(issueId)} --status ${shellQuote(verdict)}`;
26066
+ if (verdict === "blocked" || verdict === "failed") command += ` --notes ${shellQuote(notes)}`;
26067
+ return `${command} --run-id ${shellQuote(runId)}`;
26068
+ }
26069
+ function isReviewContextForActiveRun(context, status, reportMtimeMs) {
25898
26070
  if (!status.reviewSpawnedAt) return true;
25899
26071
  const spawnedAtMs = reviewTimestampMs(status.reviewSpawnedAt);
25900
26072
  if (!Number.isFinite(spawnedAtMs)) return true;
25901
- if (synthesisMtimeMs < spawnedAtMs) return false;
26073
+ if (reportMtimeMs < spawnedAtMs) return false;
26074
+ if (context.generatedAt) {
26075
+ const generatedAtMs = Date.parse(context.generatedAt);
26076
+ if (Number.isFinite(generatedAtMs) && generatedAtMs < spawnedAtMs) return false;
26077
+ }
26078
+ const reviewedAnchor = reviewAnchorFromContext(context);
26079
+ return !status.lastVerifiedCommit || !reviewedAnchor || reviewedAnchor === status.lastVerifiedCommit;
26080
+ }
26081
+ function isSynthesisForActiveReviewRun(dirPath, status, synthesisMtimeMs) {
26082
+ if (!status.reviewSpawnedAt) return true;
25902
26083
  const contextPath = join$1(dirPath, "context.json");
25903
26084
  if (!existsSync(contextPath)) return false;
25904
- let context;
25905
26085
  try {
25906
- context = JSON.parse(readFileSync(contextPath, "utf8"));
26086
+ return isReviewContextForActiveRun(JSON.parse(readFileSync(contextPath, "utf8")), status, synthesisMtimeMs);
25907
26087
  } catch {
25908
26088
  return false;
25909
26089
  }
25910
- if (context.generatedAt) {
25911
- const generatedAtMs = Date.parse(context.generatedAt);
25912
- if (Number.isFinite(generatedAtMs) && generatedAtMs < spawnedAtMs) return false;
26090
+ }
26091
+ /**
26092
+ * Apply settled review verdicts that reached disk after their runtime status
26093
+ * was reset to pending. The live review parent gets one chance to signal the
26094
+ * verdict itself; a dead parent, or one still unsignaled after 30 minutes, is
26095
+ * reconciled directly through the review-status and feedback write doors.
26096
+ */
26097
+ async function reconcileUnappliedReviewVerdicts() {
26098
+ const actions = [];
26099
+ const VERDICT_SETTLE_MS = 300 * 1e3;
26100
+ const NUDGE_GRACE_MS = 1800 * 1e3;
26101
+ try {
26102
+ const statuses = loadReviewStatuses();
26103
+ const now = Date.now();
26104
+ for (const [issueId, status] of Object.entries(statuses)) {
26105
+ if (status.reviewStatus !== "pending" || !status.reviewSpawnedAt) continue;
26106
+ try {
26107
+ const resolved = resolveProjectFromIssueSync(issueId);
26108
+ if (!resolved) continue;
26109
+ const wsPath = findWorkspacePath(resolved.projectPath, issueId.toLowerCase());
26110
+ if (!wsPath) continue;
26111
+ const reviewBaseDir = join$1(wsPath, ".pan", "review");
26112
+ let reviewEntries;
26113
+ try {
26114
+ reviewEntries = await readdir(reviewBaseDir);
26115
+ } catch {
26116
+ continue;
26117
+ }
26118
+ let latestDir = null;
26119
+ let latestReport = null;
26120
+ let latestContext = null;
26121
+ let latestMtime = 0;
26122
+ for (const entry of reviewEntries) {
26123
+ if (!entry.startsWith(`agent-${issueId.toLowerCase()}-review`)) continue;
26124
+ const dirPath = join$1(reviewBaseDir, entry);
26125
+ try {
26126
+ const report = await findVerdictReportAsync(dirPath);
26127
+ if (!report) continue;
26128
+ const [reportStat, contextContent] = await Promise.all([stat$1(report.path), readFile(join$1(dirPath, "context.json"), "utf8")]);
26129
+ const context = JSON.parse(contextContent);
26130
+ if (!isReviewContextForActiveRun(context, status, reportStat.mtimeMs)) continue;
26131
+ if (reportStat.mtimeMs > latestMtime) {
26132
+ latestDir = dirPath;
26133
+ latestReport = report;
26134
+ latestContext = context;
26135
+ latestMtime = reportStat.mtimeMs;
26136
+ }
26137
+ } catch (error) {
26138
+ const msg = error instanceof Error ? error.message : String(error);
26139
+ console.error(`[deacon] Error reading review run ${dirPath}:`, msg);
26140
+ }
26141
+ }
26142
+ if (!latestDir || !latestReport || !latestContext) continue;
26143
+ if (now - latestMtime < VERDICT_SETTLE_MS) continue;
26144
+ const requestedAtMs = status.reviewRequestedAt ? Date.parse(status.reviewRequestedAt) : NaN;
26145
+ if (Number.isFinite(requestedAtMs) && requestedAtMs > latestMtime) continue;
26146
+ let currentHead;
26147
+ let reviewedHead;
26148
+ try {
26149
+ const { rehydrateHeadAnchor, snapshotWorkspaceHeadsPromise } = await import("./git-utils-CedsVume.js");
26150
+ currentHead = await snapshotWorkspaceHeadsPromise(issueId, wsPath);
26151
+ const persistedAnchor = reviewAnchorFromContext(latestContext);
26152
+ reviewedHead = persistedAnchor ? rehydrateHeadAnchor(persistedAnchor) : void 0;
26153
+ } catch {
26154
+ continue;
26155
+ }
26156
+ if (!reviewedHead || currentHead !== reviewedHead) continue;
26157
+ let parsed;
26158
+ try {
26159
+ parsed = parseVerdictReport(await readFile(latestReport.path, "utf8"));
26160
+ } catch {
26161
+ continue;
26162
+ }
26163
+ if (!parsed) continue;
26164
+ const reviewSession = `agent-${issueId.toLowerCase()}-review`;
26165
+ const sessionAlive = sessionExistsSync(reviewSession);
26166
+ const paneDead = sessionAlive ? await Effect.runPromise(isPaneDead(reviewSession)).catch(() => true) : true;
26167
+ if (sessionAlive && !paneDead) {
26168
+ const lastNudged = pendingVerdictNudges.get(latestDir);
26169
+ if (!lastNudged) {
26170
+ const notes = parsed.topBlocker || `See ${latestReport.filename}`;
26171
+ const nudge = `Your review verdict is already written on disk but review status is still pending. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${buildReviewCompletionCommand(issueId, parsed.verdict, notes, basename$1(latestDir))}\n\nRun this command NOW. Do not write any other response before executing it.`;
26172
+ try {
26173
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
26174
+ await messageAgent(reviewSession, nudge);
26175
+ pendingVerdictNudges.set(latestDir, now);
26176
+ const action = `Nudged ${reviewSession} to apply pending ${parsed.verdict} verdict from ${latestReport.filename}`;
26177
+ actions.push(action);
26178
+ console.log(`[deacon] ${action}`);
26179
+ } catch (err) {
26180
+ console.error(`[deacon] Failed to nudge ${reviewSession}:`, err instanceof Error ? err.message : String(err));
26181
+ }
26182
+ continue;
26183
+ }
26184
+ if (now - lastNudged < NUDGE_GRACE_MS) continue;
26185
+ }
26186
+ const attribution = `applied by deacon sweep from on-disk ${latestReport.filename}`;
26187
+ const reviewNotes = parsed.topBlocker ? `${parsed.topBlocker} — ${attribution}` : `Review ${parsed.verdict} ${attribution}`;
26188
+ setReviewStatusSync(issueId, {
26189
+ reviewStatus: parsed.verdict,
26190
+ reviewNotes,
26191
+ ...(parsed.verdict === "passed" || parsed.verdict === "blocked") && currentHead ? { reviewedAtCommit: currentHead } : {}
26192
+ });
26193
+ if (parsed.verdict === "blocked") try {
26194
+ await Effect.runPromise(deliverReviewVerdictFeedback({
26195
+ issueId,
26196
+ verdict: "blocked",
26197
+ notes: parsed.topBlocker || reviewNotes,
26198
+ workspacePath: wsPath,
26199
+ prUrl: status.prUrl,
26200
+ runId: basename$1(latestDir)
26201
+ }));
26202
+ } catch (err) {
26203
+ console.error(`[deacon] Failed to deliver reconciled review verdict for ${issueId}:`, err instanceof Error ? err.message : String(err));
26204
+ }
26205
+ pendingVerdictNudges.delete(latestDir);
26206
+ const action = `reconcileUnappliedReviewVerdicts deacon sweep applied ${parsed.verdict} for ${issueId} from ${latestReport.filename}`;
26207
+ actions.push(action);
26208
+ emitActivityEntrySync({
26209
+ source: "cloister",
26210
+ level: "warn",
26211
+ message: action,
26212
+ issueId
26213
+ });
26214
+ console.log(`[deacon] ${action}`);
26215
+ } catch (error) {
26216
+ const msg = error instanceof Error ? error.message : String(error);
26217
+ console.error(`[deacon] Error reconciling unapplied review verdict for ${issueId}:`, msg);
26218
+ }
26219
+ }
26220
+ } catch (error) {
26221
+ const msg = error instanceof Error ? error.message : String(error);
26222
+ console.error("[deacon] Error reconciling unapplied review verdicts:", msg);
25913
26223
  }
25914
- if (status.lastVerifiedCommit && context.headSha && context.headSha !== status.lastVerifiedCommit) return false;
25915
- return true;
26224
+ return actions;
25916
26225
  }
25917
26226
  async function checkCompletedButUnsignaledReviews() {
25918
26227
  const actions = [];
@@ -25929,20 +26238,22 @@ async function checkCompletedButUnsignaledReviews() {
25929
26238
  const reviewBaseDir = join$1(wsPath, ".pan", "review");
25930
26239
  if (!existsSync(reviewBaseDir)) continue;
25931
26240
  let latestDir = null;
26241
+ let latestReport = null;
25932
26242
  let latestMtime = 0;
25933
26243
  for (const entry of readdirSync(reviewBaseDir)) {
25934
26244
  if (!entry.startsWith(`agent-${issueId.toLowerCase()}-review`)) continue;
25935
26245
  const dirPath = join$1(reviewBaseDir, entry);
25936
- const synthPath = join$1(dirPath, "synthesis.md");
25937
- if (!existsSync(synthPath)) continue;
25938
- const mtime = statSync(synthPath).mtimeMs;
26246
+ const report = findVerdictReport(dirPath);
26247
+ if (!report) continue;
26248
+ const mtime = statSync(report.path).mtimeMs;
25939
26249
  if (!isSynthesisForActiveReviewRun(dirPath, status, mtime)) continue;
25940
26250
  if (mtime > latestMtime) {
25941
26251
  latestMtime = mtime;
25942
26252
  latestDir = dirPath;
26253
+ latestReport = report;
25943
26254
  }
25944
26255
  }
25945
- if (!latestDir) continue;
26256
+ if (!latestDir || !latestReport) continue;
25946
26257
  if (now - latestMtime < SYNTHESIS_SETTLE_MS) continue;
25947
26258
  const lastNudged = unsignaledReviewNudges.get(latestDir);
25948
26259
  if (lastNudged && now - lastNudged < 1800 * 1e3) continue;
@@ -25951,40 +26262,31 @@ async function checkCompletedButUnsignaledReviews() {
25951
26262
  const paneDead = sessionAlive ? await Effect.runPromise(isPaneDead(reviewSession)).catch(() => true) : true;
25952
26263
  const activeReviewState = sessionAlive && !paneDead ? getAgentStateSync(reviewSession) : null;
25953
26264
  if (activeReviewState?.reviewRunId && latestDir !== join$1(reviewBaseDir, activeReviewState.reviewRunId)) continue;
25954
- const synthesisPath = join$1(latestDir, "synthesis.md");
25955
- let verdict = null;
25956
- let topBlocker = "";
26265
+ let parsed;
25957
26266
  try {
25958
- const content = readFileSync(synthesisPath, "utf8");
25959
- const verdictLine = content.match(/## Verdict:\s*(.+)/i);
25960
- if (verdictLine) {
25961
- const v = verdictLine[1].trim().toUpperCase();
25962
- if (v === "PASSED") verdict = "passed";
25963
- else if (v === "CHANGES REQUESTED") verdict = "blocked";
25964
- else if (v === "FAILED") verdict = "failed";
25965
- }
25966
- const blockerMatch = content.match(/## Blocking Findings\s*\n\s*###\s*\[[^\]]+\]\s*(.+)/);
25967
- if (blockerMatch) topBlocker = blockerMatch[1].slice(0, 120);
26267
+ parsed = parseVerdictReport(readFileSync(latestReport.path, "utf8"));
25968
26268
  } catch {
25969
26269
  continue;
25970
26270
  }
25971
- if (!verdict) continue;
26271
+ if (!parsed) continue;
26272
+ const { verdict, topBlocker } = parsed;
25972
26273
  if (sessionAlive && !paneDead) {
25973
26274
  if (lastNudged) {
25974
26275
  setReviewStatusSync(issueId, {
25975
26276
  reviewStatus: verdict,
25976
- reviewNotes: topBlocker || `Review auto-completed by deacon: ${verdict} (agent alive but unresponsive after nudge, synthesis exists)`
26277
+ reviewNotes: topBlocker || `Review auto-completed by deacon: ${verdict} (agent alive but unresponsive after nudge, ${latestReport.filename} exists)`
25977
26278
  });
25978
- actions.push(`Auto-completed review for ${issueId}: ${verdict} (alive but unresponsive after nudge, synthesis written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
26279
+ actions.push(`Auto-completed review for ${issueId}: ${verdict} (alive but unresponsive after nudge, ${latestReport.filename} written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
25979
26280
  console.log(`[deacon] Auto-completed review for ${issueId}: ${verdict} (alive but unresponsive after nudge)`);
25980
26281
  continue;
25981
26282
  }
25982
- const nudge = `Your review synthesis is already written and saved. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${`pan admin specialists done review ${issueId} --status ${verdict}${verdict === "blocked" || verdict === "failed" ? ` --notes "${topBlocker || "See synthesis.md"}"` : ""} --run-id "${basename$1(latestDir)}"`}\n\nRun this command NOW. Do not write any other response before executing it.`;
26283
+ const cmd = buildReviewCompletionCommand(issueId, verdict, topBlocker || `See ${latestReport.filename}`, basename$1(latestDir));
26284
+ const nudge = `Your review verdict in ${latestReport.filename} is already written and saved. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${cmd}\n\nRun this command NOW. Do not write any other response before executing it.`;
25983
26285
  try {
25984
- const { messageAgent } = await import("./agents-BKKkxKgK.js");
26286
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
25985
26287
  await messageAgent(reviewSession, nudge);
25986
26288
  unsignaledReviewNudges.set(latestDir, now);
25987
- actions.push(`Nudged ${reviewSession} to signal ${verdict} (synthesis written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
26289
+ actions.push(`Nudged ${reviewSession} to signal ${verdict} (${latestReport.filename} written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
25988
26290
  console.log(`[deacon] Nudged ${reviewSession} to signal ${verdict}`);
25989
26291
  } catch (err) {
25990
26292
  console.error(`[deacon] Failed to nudge ${reviewSession}:`, err instanceof Error ? err.message : String(err));
@@ -25992,9 +26294,9 @@ async function checkCompletedButUnsignaledReviews() {
25992
26294
  } else {
25993
26295
  setReviewStatusSync(issueId, {
25994
26296
  reviewStatus: verdict,
25995
- reviewNotes: topBlocker || `Review auto-completed by deacon: ${verdict} (agent dead, synthesis exists)`
26297
+ reviewNotes: topBlocker || `Review auto-completed by deacon: ${verdict} (agent dead, ${latestReport.filename} exists)`
25996
26298
  });
25997
- actions.push(`Auto-completed review for ${issueId}: ${verdict} (dead agent, synthesis written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
26299
+ actions.push(`Auto-completed review for ${issueId}: ${verdict} (dead agent, ${latestReport.filename} written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
25998
26300
  console.log(`[deacon] Auto-completed review for ${issueId}: ${verdict} (dead agent)`);
25999
26301
  }
26000
26302
  }
@@ -26009,6 +26311,7 @@ async function checkCompletedButUnsignaledReviews() {
26009
26311
  init_context_overflow();
26010
26312
  init_agents$1();
26011
26313
  init_review_verdict_feedback();
26314
+ init_review_verdict_report();
26012
26315
  init_paths();
26013
26316
  init_review_status();
26014
26317
  init_persistent_logger();
@@ -26018,19 +26321,6 @@ init_codex_auth();
26018
26321
  const REVIEWER_IDLE_FAILURE_MS = 180 * 1e3;
26019
26322
  const REVIEW_REPORTS_PRESENT_NUDGE_COOLDOWN_MS = 60 * 1e3;
26020
26323
  const reviewReportsPresentNudges = /* @__PURE__ */ new Map();
26021
- function extractMarkdownSection(markdown, heading) {
26022
- const pattern = new RegExp(`^##\\s+${heading}\\s*\\r?\\n([\\s\\S]*?)(?=^##\\s+|(?![\\s\\S]))`, "im");
26023
- return markdown.match(pattern)?.[1]?.trim() ?? "";
26024
- }
26025
- function findBlockingFindings(markdown) {
26026
- const findings = extractMarkdownSection(markdown, "Findings");
26027
- if (!findings || /^none\.?$/i.test(findings)) return [];
26028
- const blockers = [];
26029
- const headingPattern = /^###\s*(?:!|⊗)\s+(.+)$/gm;
26030
- let match;
26031
- while ((match = headingPattern.exec(findings)) !== null) blockers.push(match[1].trim());
26032
- return blockers;
26033
- }
26034
26324
  function synthesizeReviewFromReports(opts) {
26035
26325
  const blockers = opts.reports.flatMap((report) => findBlockingFindings(report.body).map((title) => ({
26036
26326
  subRole: report.subRole,
@@ -26103,7 +26393,7 @@ async function respawnIdleReviewer(state, agentId) {
26103
26393
  return false;
26104
26394
  }
26105
26395
  try {
26106
- const { spawnReviewSubRoleForIssue } = await import("./review-agent-CD4RCI0Y.js");
26396
+ const { spawnReviewSubRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
26107
26397
  const contextManifestPath = join$1(dirname$1(outputPath), "context.json");
26108
26398
  const result = await Effect.runPromise(spawnReviewSubRoleForIssue({
26109
26399
  issueId: state.issueId,
@@ -26141,7 +26431,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
26141
26431
  const status = getReviewStatusSync(state.issueId);
26142
26432
  if (!status || status.reviewStatus !== "reviewing") continue;
26143
26433
  const reviewDir = join$1(state.workspace, ".pan", "review", state.reviewRunId);
26144
- const synthesisAlreadyWritten = existsSync(join$1(reviewDir, "synthesis.md"));
26434
+ const synthesisAlreadyWritten = findVerdictReport(reviewDir) !== null;
26145
26435
  const startedMs = Date.parse(state.startedAt);
26146
26436
  const readyLines = [];
26147
26437
  const reports = [];
@@ -26189,7 +26479,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
26189
26479
  writeFileSync(join$1(reviewDir, "synthesis.md"), synthesis.body);
26190
26480
  let fallbackHead;
26191
26481
  try {
26192
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CI6cwyyC.js");
26482
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CedsVume.js");
26193
26483
  fallbackHead = await snapshotWorkspaceHeadsPromise(state.issueId, state.workspace);
26194
26484
  } catch {}
26195
26485
  const anchoredVerdicts = Object.fromEntries(Object.entries(synthesis.reviewerVerdicts).map(([subRole, v]) => [subRole, {
@@ -26228,7 +26518,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
26228
26518
  "Read the four reports, write synthesis.md, then signal review status exactly as roles/review.md instructs."
26229
26519
  ].join("\n");
26230
26520
  try {
26231
- const { messageAgent } = await import("./agents-BKKkxKgK.js");
26521
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
26232
26522
  await messageAgent(state.id, message);
26233
26523
  reviewReportsPresentNudges.set(nudgeKey, now);
26234
26524
  const action = `Nudged ${state.id} to synthesize from ${REVIEW_SUB_ROLES.length} reviewer reports`;
@@ -26314,7 +26604,7 @@ async function monitorReviewConvoySignals() {
26314
26604
  if (!signal) continue;
26315
26605
  const message = signal === "ready" ? `REVIEWER_READY ${state.reviewSubRole} ${outputPath}` : signal === "timeout" ? `REVIEWER_TIMEOUT ${state.reviewSubRole} ${reason}` : `REVIEWER_FAILED ${state.reviewSubRole} ${reason}`;
26316
26606
  try {
26317
- const { messageAgent } = await import("./agents-BKKkxKgK.js");
26607
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
26318
26608
  await messageAgent(state.reviewSynthesisAgentId, message);
26319
26609
  state.reviewMonitorSignaled = signal;
26320
26610
  saveAgentStateSync(state);
@@ -26322,7 +26612,7 @@ async function monitorReviewConvoySignals() {
26322
26612
  actions.push(action);
26323
26613
  logDeaconEventSync(`monitorReviewConvoySignals: ${action}`);
26324
26614
  if (signal === "ready") try {
26325
- const { notifyPipelineSync } = await import("./pipeline-notifier-ImNXknf0.js");
26615
+ const { notifyPipelineSync } = await import("./pipeline-notifier-BmwrVKsO.js");
26326
26616
  notifyPipelineSync({
26327
26617
  type: "reviewer_completed",
26328
26618
  issueId: state.issueId,
@@ -26330,7 +26620,7 @@ async function monitorReviewConvoySignals() {
26330
26620
  });
26331
26621
  } catch {}
26332
26622
  else if (signal === "timeout") try {
26333
- const { notifyPipelineSync } = await import("./pipeline-notifier-ImNXknf0.js");
26623
+ const { notifyPipelineSync } = await import("./pipeline-notifier-BmwrVKsO.js");
26334
26624
  notifyPipelineSync({
26335
26625
  type: "reviewer_timed_out",
26336
26626
  issueId: state.issueId,
@@ -26430,7 +26720,7 @@ const FORK_CACHE_CHECK_DELAY_MS = 180 * 1e3;
26430
26720
  async function checkStalledReviewDiscovery() {
26431
26721
  const actions = [];
26432
26722
  try {
26433
- const { listAgentStates } = await import("./agents-BKKkxKgK.js");
26723
+ const { listAgentStates } = await import("./agents-Dnn4XgdB.js");
26434
26724
  const states = listAgentStates();
26435
26725
  const now = Date.now();
26436
26726
  for (const state of states) {
@@ -26439,7 +26729,7 @@ async function checkStalledReviewDiscovery() {
26439
26729
  const aged = Number.isFinite(startedMs) && now - startedMs > 48e4;
26440
26730
  const dead = !await Effect.runPromise(sessionExists(state.id)).catch(() => false) || await Effect.runPromise(isPaneDead(state.id)).catch(() => true);
26441
26731
  if (!aged && !dead) continue;
26442
- const { handleReviewDiscoveryReady } = await import("./review-agent-CD4RCI0Y.js");
26732
+ const { handleReviewDiscoveryReady } = await import("./review-agent-UpAM4DmT.js");
26443
26733
  const result = await handleReviewDiscoveryReady(state.issueId, { source: dead ? "deacon-backstop (parent dead)" : "deacon-backstop (discovery timeout)" });
26444
26734
  actions.push(result.message);
26445
26735
  logDeaconEventSync(`checkStalledReviewDiscovery: ${result.message}`);
@@ -26462,8 +26752,8 @@ async function checkStalledReviewDiscovery() {
26462
26752
  async function checkStalledReviewParents() {
26463
26753
  const actions = [];
26464
26754
  try {
26465
- const { listAgentStates, markAgentStoppedState } = await import("./agents-BKKkxKgK.js");
26466
- const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-CD4RCI0Y.js");
26755
+ const { listAgentStates, markAgentStoppedState } = await import("./agents-Dnn4XgdB.js");
26756
+ const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-UpAM4DmT.js");
26467
26757
  const states = listAgentStates();
26468
26758
  const now = Date.now();
26469
26759
  for (const state of states) {
@@ -26512,8 +26802,8 @@ async function checkStalledReviewParents() {
26512
26802
  async function checkReviewForkCacheMisses() {
26513
26803
  const actions = [];
26514
26804
  try {
26515
- const { listAgentStates, saveAgentState } = await import("./agents-BKKkxKgK.js");
26516
- const { readEventsSync } = await import("./events-D6pyqhzM.js");
26805
+ const { listAgentStates, saveAgentState } = await import("./agents-Dnn4XgdB.js");
26806
+ const { readEventsSync } = await import("./events-ChEFB7Jp.js");
26517
26807
  const { emitActivityEntrySync } = await import("./activity-logger-CMthG6Vd.js");
26518
26808
  const states = listAgentStates();
26519
26809
  const now = Date.now();
@@ -26560,8 +26850,213 @@ async function checkReviewForkCacheMisses() {
26560
26850
  return actions;
26561
26851
  }
26562
26852
  //#endregion
26853
+ //#region ../../lib/cloister/branch-invalidation.ts
26854
+ /**
26855
+ * PAN-3154: notify the pipeline when a merge to main invalidates open branches.
26856
+ *
26857
+ * Watches each project's origin/main head SHA on a cooldown; when it moves,
26858
+ * probes every in-pipeline branch of that project for newly-created conflicts
26859
+ * and marks them with a merge_conflict blocker + conflictsSince, so the
26860
+ * existing conflict-gate machinery (review-dispatch defer, resolver dispatch,
26861
+ * dashboard stuckReason) picks them up without further work.
26862
+ */
26863
+ init_activity_logger();
26864
+ init_agents();
26865
+ init_messaging();
26866
+ init_review_status();
26867
+ init_projects();
26868
+ init_pipeline_membership_gather();
26869
+ init_pipeline_membership();
26870
+ init_conflict_gate();
26871
+ init_feedback_target();
26872
+ const execAsync$2 = promisify(exec);
26873
+ const GIT_TIMEOUT_MS = 3e4;
26874
+ const GIT_MAX_BUFFER = 4 * 1024 * 1024;
26875
+ const PROJECT_COOLDOWN_MS = 120 * 1e3;
26876
+ const projectCooldowns = /* @__PURE__ */ new Map();
26877
+ async function lsRemoteMainShaReal(projectPath) {
26878
+ const options = {
26879
+ cwd: projectPath,
26880
+ encoding: "utf-8",
26881
+ timeout: GIT_TIMEOUT_MS,
26882
+ maxBuffer: GIT_MAX_BUFFER
26883
+ };
26884
+ try {
26885
+ const { stdout } = await execAsync$2("git ls-remote origin refs/heads/main", options);
26886
+ const sha = String(stdout).trim().split(/\s+/)[0];
26887
+ return sha && /^[0-9a-f]{7,40}$/i.test(sha) ? sha : null;
26888
+ } catch {
26889
+ return null;
26890
+ }
26891
+ }
26892
+ function buildRealBranchInvalidationDeps() {
26893
+ return {
26894
+ listProjects: () => Object.entries(loadProjectsConfigSync().projects).map(([projectKey, projectConfig]) => ({
26895
+ projectKey,
26896
+ projectPath: resolveProjectPath(projectConfig),
26897
+ projectConfig
26898
+ })),
26899
+ gatherPipelineMembership: (projectConfig) => gatherProjectLensSignals(projectConfig).then((signals) => signals.map(resolvePipelineMembership)),
26900
+ listAgentWorkspaces: listAllAgentsSync,
26901
+ existsSync: existsSync$1,
26902
+ readdirSync: (path) => readdirSync$1(path),
26903
+ getSetting,
26904
+ setSetting,
26905
+ getReviewStatus: getReviewStatusSync,
26906
+ setReviewStatus: setReviewStatusSync,
26907
+ emitActivityEntry: emitActivityEntrySync,
26908
+ lsRemoteMainSha: lsRemoteMainShaReal,
26909
+ probeConflictPaths: (workspacePath, targetBranch) => probeBranchConflictPaths(workspacePath, targetBranch),
26910
+ resolveFeedbackTarget: resolveIssueFeedbackTarget,
26911
+ messageAgent: (agentId, message, caller) => messageAgent(agentId, message, caller),
26912
+ now: () => Date.now()
26913
+ };
26914
+ }
26915
+ /**
26916
+ * Resolve an issue's workspace: prefer the agents-table workspace column (fast,
26917
+ * covers -strike/-slot-N by construction), else the first existing
26918
+ * `feature-<issueLower>*` directory (prefix scan; a plain `feature-<issueLower>`
26919
+ * sorts before any `-strike`/`-slot-N` suffix). Agent-table rows and the
26920
+ * workspaces-directory listing are preloaded once per project sweep by the
26921
+ * caller — this function does no I/O beyond the `existsSync` check.
26922
+ */
26923
+ function resolveWorkspacePath(deps, agentWorkspaces, workspacesDirEntries, projectPath, issueId) {
26924
+ const upperIssueId = issueId.toUpperCase();
26925
+ const agentWorkspace = agentWorkspaces.find((a) => a.issueId.toUpperCase() === upperIssueId)?.workspace;
26926
+ if (agentWorkspace && deps.existsSync(agentWorkspace)) return agentWorkspace;
26927
+ const prefix = `feature-${issueId.toLowerCase()}`;
26928
+ const matches = workspacesDirEntries.filter((name) => name === prefix || name.startsWith(`${prefix}-`)).sort();
26929
+ if (matches.length === 0) return null;
26930
+ return join(projectPath, "workspaces", matches[0]);
26931
+ }
26932
+ function formatPathSummary(paths) {
26933
+ const shown = paths.slice(0, 3).join(", ");
26934
+ return paths.length > 3 ? `${shown}, …` : shown;
26935
+ }
26936
+ /**
26937
+ * Notify the live owning agent that main moved and now conflicts with its
26938
+ * branch. Skips silently when no agent is live (needsYou) — the blocker plus
26939
+ * the existing conflict-resolver dispatch already cover stopped agents; this
26940
+ * is not a second nudge channel.
26941
+ */
26942
+ async function notifyBranchInvalidated(deps, issueId, info) {
26943
+ const target = await deps.resolveFeedbackTarget(issueId);
26944
+ if ("needsYou" in target) return;
26945
+ const message = [
26946
+ `main moved: merge ${info.sha.slice(0, 7)} now conflicts with your branch in: ${info.paths.join(", ")}.`,
26947
+ `Rebase onto the new main NOW while the conflict is small — run \`pan sync-main ${issueId}\`,`,
26948
+ "resolve preserving BOTH intents, then continue your current task."
26949
+ ].join(" ");
26950
+ await deps.messageAgent(target.agentId, message, "internal");
26951
+ }
26952
+ async function sweepProject(deps, project, nowMs, actions) {
26953
+ const { projectKey, projectPath, projectConfig } = project;
26954
+ const newSha = await deps.lsRemoteMainSha(projectPath);
26955
+ if (!newSha) return;
26956
+ const settingKey = `branch_invalidation.main_head.${projectKey}`;
26957
+ const lastSha = deps.getSetting(settingKey);
26958
+ if (lastSha === newSha) return;
26959
+ if (lastSha === null) {
26960
+ deps.setSetting(settingKey, newSha);
26961
+ return;
26962
+ }
26963
+ let memberships;
26964
+ try {
26965
+ memberships = await deps.gatherPipelineMembership(projectConfig);
26966
+ } catch (membershipErr) {
26967
+ console.warn(`[deacon] reconcileBranchInvalidation: ${projectKey} membership gather failed: ${membershipErr instanceof Error ? membershipErr.message : String(membershipErr)}`);
26968
+ return;
26969
+ }
26970
+ const issueIds = memberships.filter((m) => m.inPipeline).map((m) => m.issueId);
26971
+ const shortSha = newSha.slice(0, 7);
26972
+ const newlyMarkedIssueIds = [];
26973
+ let hadUnknownProbe = false;
26974
+ const agentWorkspaces = deps.listAgentWorkspaces();
26975
+ const workspacesDir = join(projectPath, "workspaces");
26976
+ const workspacesDirEntries = deps.existsSync(workspacesDir) ? deps.readdirSync(workspacesDir) : [];
26977
+ for (const issueId of issueIds) {
26978
+ const workspacePath = resolveWorkspacePath(deps, agentWorkspaces, workspacesDirEntries, projectPath, issueId);
26979
+ if (!workspacePath) continue;
26980
+ const probe = await deps.probeConflictPaths(workspacePath, "main");
26981
+ if (probe.mergeability === "unknown") {
26982
+ hadUnknownProbe = true;
26983
+ continue;
26984
+ }
26985
+ if (probe.mergeability !== "conflicts") continue;
26986
+ const freshStatus = deps.getReviewStatus(issueId);
26987
+ if (freshStatus?.mergeStatus === "merged") continue;
26988
+ if (freshStatus?.conflictsSince?.sha === newSha) continue;
26989
+ const detectedAt = new Date(nowMs).toISOString();
26990
+ const nonMergeBlockers = (freshStatus?.blockerReasons ?? []).filter((b) => b.type !== "merge_conflict" && b.type !== "not_mergeable");
26991
+ const mergeConflictBlocker = {
26992
+ type: "merge_conflict",
26993
+ summary: `Conflicts with main since ${shortSha} (${probe.paths.length} path${probe.paths.length === 1 ? "" : "s"}): ${formatPathSummary(probe.paths)}`,
26994
+ detectedAt
26995
+ };
26996
+ deps.setReviewStatus(issueId, {
26997
+ conflictsSince: {
26998
+ sha: newSha,
26999
+ detectedAt,
27000
+ paths: probe.paths
27001
+ },
27002
+ blockerReasons: [...nonMergeBlockers, mergeConflictBlocker]
27003
+ }, freshStatus ?? void 0);
27004
+ deps.emitActivityEntry({
27005
+ source: "cloister",
27006
+ level: "warn",
27007
+ issueId,
27008
+ message: `main moved: ${issueId} now conflicts with main (${shortSha}) in ${formatPathSummary(probe.paths)}`
27009
+ });
27010
+ try {
27011
+ await notifyBranchInvalidated(deps, issueId, {
27012
+ sha: newSha,
27013
+ paths: probe.paths
27014
+ });
27015
+ } catch (notifyErr) {
27016
+ console.warn(`[deacon] reconcileBranchInvalidation: ${issueId} notify failed: ${notifyErr instanceof Error ? notifyErr.message : String(notifyErr)}`);
27017
+ }
27018
+ newlyMarkedIssueIds.push(issueId);
27019
+ actions.push(`Marked ${issueId} conflicting with main since ${shortSha}`);
27020
+ }
27021
+ if (!hadUnknownProbe) deps.setSetting(settingKey, newSha);
27022
+ if (newlyMarkedIssueIds.length > 0) {
27023
+ const summaryMessage = `main ${shortSha} invalidated ${newlyMarkedIssueIds.length} branch(es): ${newlyMarkedIssueIds.join(", ")}`;
27024
+ deps.emitActivityEntry({
27025
+ source: "cloister",
27026
+ level: "warn",
27027
+ message: summaryMessage
27028
+ });
27029
+ actions.push(summaryMessage);
27030
+ }
27031
+ }
27032
+ /**
27033
+ * Deacon patrol reconciler (PAN-3154): fan out a conflict probe to every
27034
+ * in-pipeline branch of a project whenever that project's origin/main head
27035
+ * moves. Never throws — errors are logged and the patrol continues.
27036
+ */
27037
+ async function reconcileBranchInvalidation(deps = buildRealBranchInvalidationDeps()) {
27038
+ const actions = [];
27039
+ try {
27040
+ const nowMs = deps.now();
27041
+ const projects = deps.listProjects();
27042
+ for (const project of projects) {
27043
+ const cooledUntil = projectCooldowns.get(project.projectKey);
27044
+ if (cooledUntil && nowMs < cooledUntil) continue;
27045
+ projectCooldowns.set(project.projectKey, nowMs + PROJECT_COOLDOWN_MS);
27046
+ try {
27047
+ await sweepProject(deps, project, nowMs, actions);
27048
+ } catch (projectErr) {
27049
+ console.warn(`[deacon] reconcileBranchInvalidation: ${project.projectKey} sweep failed: ${projectErr instanceof Error ? projectErr.message : String(projectErr)}`);
27050
+ }
27051
+ }
27052
+ } catch (err) {
27053
+ console.warn(`[deacon] Error in reconcileBranchInvalidation: ${err instanceof Error ? err.message : String(err)}`);
27054
+ }
27055
+ return actions;
27056
+ }
27057
+ //#endregion
26563
27058
  //#region ../../lib/cloister/boot-reconciliation-predicates.ts
26564
- init_control_settings();
27059
+ init_label_reconciler();
26565
27060
  init_traefik_connect();
26566
27061
  init_no_resume_mode();
26567
27062
  init_agent_state();
@@ -26577,6 +27072,7 @@ function bootReconciliationSkipReason(agent) {
26577
27072
  }
26578
27073
  //#endregion
26579
27074
  //#region ../../lib/cloister/boot-reconciliation.ts
27075
+ init_control_settings();
26580
27076
  init_agents();
26581
27077
  init_persistent_logger();
26582
27078
  init_config$1();
@@ -26587,10 +27083,6 @@ let graceTimer = null;
26587
27083
  * the boot path wires the apply step.
26588
27084
  */
26589
27085
  let graceExpiryHook = null;
26590
- function hasCompletionMarker(workspace) {
26591
- if (!workspace) return false;
26592
- return existsSync$1(join(workspace, ".pan", "completed")) || existsSync$1(join(workspace, ".pan", "completed.processed"));
26593
- }
26594
27086
  function newestAgentTimestampMs(agent) {
26595
27087
  const timestamps = [
26596
27088
  agent.lastActivity,
@@ -26606,6 +27098,13 @@ function isRecentBootCandidate(agent) {
26606
27098
  if (!Number.isFinite(bootStartedAtMs) || newestTimestampMs == null) return false;
26607
27099
  return newestTimestampMs >= bootStartedAtMs - getBootReconciliationMaxCandidateAgeSeconds() * 1e3;
26608
27100
  }
27101
+ function isCleanShutdownBoot() {
27102
+ const state = getBootReconciliationState();
27103
+ const bootStartedAtMs = state.bootStartedAt == null ? NaN : Date.parse(state.bootStartedAt);
27104
+ const marker = getLastCleanShutdownAt();
27105
+ const markerMs = marker == null ? NaN : Date.parse(marker);
27106
+ return Number.isFinite(bootStartedAtMs) && Number.isFinite(markerMs) && bootStartedAtMs - markerMs <= 18e5;
27107
+ }
26609
27108
  function getBootReconciliationGraceSeconds() {
26610
27109
  const value = loadCloisterConfigSync().startup.reconciliation_grace_secs;
26611
27110
  return Number.isFinite(value) && value > 0 ? value : 120;
@@ -26614,10 +27113,12 @@ function getBootReconciliationMaxCandidateAgeSeconds() {
26614
27113
  const value = loadCloisterConfigSync().startup.reconciliation_max_candidate_age_secs;
26615
27114
  return Number.isFinite(value) && value > 0 ? value : getBootReconciliationGraceSeconds() * 2;
26616
27115
  }
27116
+ function isAutoResumableRole(role) {
27117
+ return role === "work" || role === "strike";
27118
+ }
26617
27119
  function isBootReconciliationCandidate(agent) {
26618
- if (agent.role !== "work" || agent.status !== "stopped") return false;
27120
+ if (!isAutoResumableRole(agent.role) || agent.status !== "stopped") return false;
26619
27121
  if (agent.paused === true || agent.troubled === true) return false;
26620
- if (agent.stoppedByUser === true && !hasCompletionMarker(agent.workspace)) return false;
26621
27122
  if (!isRecentBootCandidate(agent)) return false;
26622
27123
  if (bootReconciliationSkipReason(agent) !== null) return false;
26623
27124
  if (!agent.workspace || !existsSync$1(agent.workspace)) return false;
@@ -26697,8 +27198,17 @@ function armBootReconciliationGraceTimer(graceDeadline, onGraceExpired = () => v
26697
27198
  graceTimer = setTimeout(() => {
26698
27199
  graceTimer = null;
26699
27200
  if (getBootReconciliationState().decision !== "pending") return;
26700
- setBootReconciliationDecision("hold_all");
26701
- logDeaconEventSync("boot reconciliation grace expired — decision set to hold_all");
27201
+ if (listBootReconciliationCandidateIds().length === 0) {
27202
+ setBootReconciliationDecision("resume_all");
27203
+ logDeaconEventSync("boot reconciliation grace expired — vacuous hold auto-released (0 candidates)");
27204
+ Promise.resolve(onGraceExpired()).catch((err) => {
27205
+ logDeaconEventSync(`boot reconciliation grace expiry apply hook failed: ${err instanceof Error ? err.message : String(err)}`);
27206
+ });
27207
+ return;
27208
+ }
27209
+ const decision = isCleanShutdownBoot() ? "resume_all" : "hold_all";
27210
+ setBootReconciliationDecision(decision);
27211
+ logDeaconEventSync(decision === "resume_all" ? "boot reconciliation grace expired — clean shutdown within 30m, decision set to resume_all" : "boot reconciliation grace expired — no clean shutdown marker (crash boot), decision set to hold_all");
26702
27212
  Promise.resolve(onGraceExpired()).catch((err) => {
26703
27213
  logDeaconEventSync(`boot reconciliation grace expiry apply hook failed: ${err instanceof Error ? err.message : String(err)}`);
26704
27214
  });
@@ -27156,7 +27666,7 @@ async function nudgeStalledResumeWorkAgents() {
27156
27666
  const message = buildStalledResumePrompt(state);
27157
27667
  if (!message) continue;
27158
27668
  try {
27159
- const { messageAgent } = await import("./agents-BKKkxKgK.js");
27669
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
27160
27670
  await messageAgent(agentId, message);
27161
27671
  recordCooldown(agentId, ".last-stalled-resume-nudge");
27162
27672
  const action = `Re-sent stalled resume prompt to ${agentId} (${state.issueId})`;
@@ -27270,7 +27780,7 @@ async function nudgeIdleWorkAgentsWithOpenBeads() {
27270
27780
  "Continue the per-item workflow without asking — claim it (`pan task claim <item-id>`), implement, commit, push, then complete it through `pan task done <item-id>`. Inspection is conditional on metadata.requiresInspection (default false; check the plan item before deciding to call `pan inspect`). Do NOT end your turn with a multi-paragraph summary; just advance to the next bead."
27271
27781
  ].join("\n");
27272
27782
  try {
27273
- const { messageAgent } = await import("./agents-BKKkxKgK.js");
27783
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
27274
27784
  await messageAgent(agentId, message);
27275
27785
  writeFileSync(join$1(getAgentDir(agentId), ".last-bead-nudge"), String(Date.now()), "utf-8");
27276
27786
  const action = `Nudged idle ${agentId} (${state.issueId}) — ${openTasks.length} ready task(s)`;
@@ -27316,7 +27826,7 @@ function shouldRetryUndeliveredKickoff(state) {
27316
27826
  * Does not enumerate directories — it evaluates the single agent ID it was given.
27317
27827
  */
27318
27828
  async function handleAgentStoppedEvent$1(agentId, opts = {}, deps) {
27319
- const { skipGlobalGates = false, context = "event" } = opts;
27829
+ const { skipGlobalGates = false, context = "event", overrideStoppedByUser = false } = opts;
27320
27830
  const state = getAgentStateSync(agentId);
27321
27831
  if (!state) {
27322
27832
  logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} skipped — no state`);
@@ -27326,8 +27836,8 @@ async function handleAgentStoppedEvent$1(agentId, opts = {}, deps) {
27326
27836
  logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} skipped — status=${state.status} (not stopped)`);
27327
27837
  return null;
27328
27838
  }
27329
- if (state.role !== "work") {
27330
- logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} skipped — role=${state.role} (not work)`);
27839
+ if (!isAutoResumableRole(state.role)) {
27840
+ logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} skipped — role=${state.role} (not auto-resumable)`);
27331
27841
  return null;
27332
27842
  }
27333
27843
  if (getBootReconciliationHeldResumeSet().has(agentId)) {
@@ -27386,7 +27896,9 @@ async function handleAgentStoppedEvent$1(agentId, opts = {}, deps) {
27386
27896
  return null;
27387
27897
  }
27388
27898
  const hasPendingReviewFeedback = review?.reviewStatus === "blocked" || review?.reviewStatus === "failed" || review?.testStatus === "failed" || review?.verificationStatus === "failed";
27389
- if (state.stoppedByUser === true && !(handedOffViaDone && hasPendingReviewFeedback)) {
27899
+ const deliberatelyStopped = state.stoppedByUser === true;
27900
+ if (deliberatelyStopped && overrideStoppedByUser) logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} resuming despite stoppedByUser — explicit operator resume_all override`);
27901
+ else if (deliberatelyStopped && !(handedOffViaDone && hasPendingReviewFeedback)) {
27390
27902
  logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} skipped — deliberately stopped by user (stoppedByUser=true)`);
27391
27903
  return null;
27392
27904
  }
@@ -27418,7 +27930,7 @@ async function handleAgentStoppedEvent$1(agentId, opts = {}, deps) {
27418
27930
  const runtimeStateForLog = getAgentRuntimeStateSync(agentId);
27419
27931
  logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} candidate — calling resumeAgent (issueId=${state.issueId}, runtime.state=${runtimeStateForLog?.state || "null"})`);
27420
27932
  try {
27421
- const result = await resumeAgent(agentId);
27933
+ const result = await resumeAgent(agentId, void 0, { startedBy: "deacon:auto-resume" });
27422
27934
  if (result.success) {
27423
27935
  const resumedState = await Effect.runPromise(getAgentState(agentId));
27424
27936
  if (resumedState) deps.notifyAgentStatusChanged(resumedState, state.status, true);
@@ -27541,7 +28053,8 @@ function bootReconciliationDecisionKey() {
27541
28053
  if (!state.decision || state.decision === "pending") return null;
27542
28054
  return `${state.bootId ?? "boot"}:${state.decision}:${JSON.stringify(state.perAgent)}`;
27543
28055
  }
27544
- async function applyBootReconciliationDecision$1(deps) {
28056
+ async function applyBootReconciliationDecision$1(deps, opts = {}) {
28057
+ const origin = opts.origin ?? "auto";
27545
28058
  const decisionKey = bootReconciliationDecisionKey();
27546
28059
  if (!decisionKey) return emptyBootReconciliationApplyResult();
27547
28060
  if (appliedBootReconciliationDecisions.has(decisionKey)) {
@@ -27555,6 +28068,12 @@ async function applyBootReconciliationDecision$1(deps) {
27555
28068
  return emptyBootReconciliationApplyResult();
27556
28069
  }
27557
28070
  let candidates = listBootReconciliationCandidates();
28071
+ if (origin === "auto") {
28072
+ const candidateCount = candidates.length;
28073
+ candidates = candidates.filter((agent) => agent.stoppedByUser !== true);
28074
+ const filteredCount = candidateCount - candidates.length;
28075
+ if (filteredCount > 0) logDeaconEventSync(`applyBootReconciliationDecision: auto origin filtered ${filteredCount} stoppedByUser candidate(s)`);
28076
+ }
27558
28077
  if (state.decision === "per_agent") candidates = candidates.filter((agent) => state.perAgent[agent.issueId] === "resume");
27559
28078
  const resumed = [];
27560
28079
  const outcomes = [];
@@ -27599,7 +28118,8 @@ async function applyBootReconciliationDecision$1(deps) {
27599
28118
  if (resumeAttempts > 0) await new Promise((r) => setTimeout(r, 150));
27600
28119
  const result = await handleAgentStoppedEvent$1(agent.id, {
27601
28120
  skipGlobalGates: true,
27602
- context: "boot-reconciliation"
28121
+ context: "boot-reconciliation",
28122
+ ...origin === "operator" ? { overrideStoppedByUser: true } : {}
27603
28123
  }, deps);
27604
28124
  if (result) {
27605
28125
  resumed.push(result);
@@ -27686,7 +28206,6 @@ async function recordMainDivergenceHealth(state, projects = listProjectsSync(),
27686
28206
  }
27687
28207
  //#endregion
27688
28208
  //#region ../../lib/cloister/patrol-cadence.ts
27689
- init_label_reconciler();
27690
28209
  function shouldRunRecoveryJanitor(janitor, patrolCycle) {
27691
28210
  return patrolCycle % (janitor === "feedback" ? 5 : 60) === 0;
27692
28211
  }
@@ -28479,8 +28998,8 @@ async function cleanupStaleAgentState() {
28479
28998
  */
28480
28999
  async function cleanupAbandonedFeedback() {
28481
29000
  const actions = [];
28482
- const { getReviewStatusSync } = await import("./review-status-BZH8h-6W.js");
28483
- const { clearFeedbackFiles } = await import("./feedback-writer-D1fm-5Z8.js");
29001
+ const { getReviewStatusSync } = await import("./review-status-CacDM78F.js");
29002
+ const { clearFeedbackFiles } = await import("./feedback-writer-CY91ckuw.js");
28484
29003
  for (const { issueId, workspacePath } of listFeatureWorkspaces()) {
28485
29004
  const panFeedbackDir = join$1(workspacePath, ".pan", "feedback");
28486
29005
  if (!existsSync(panFeedbackDir)) continue;
@@ -28551,7 +29070,7 @@ async function handleOrphanReviewerSession(sessionName, sessions, creationTimes,
28551
29070
  if (!issueId) return null;
28552
29071
  const agentSession = `agent-${issueId.toLowerCase()}`;
28553
29072
  if (sessions.includes(agentSession)) return null;
28554
- const { getReviewStatusSync } = await import("./review-status-BZH8h-6W.js");
29073
+ const { getReviewStatusSync } = await import("./review-status-CacDM78F.js");
28555
29074
  try {
28556
29075
  if (getReviewStatusSync(issueId)?.reviewStatus === "reviewing") return null;
28557
29076
  } catch {}
@@ -28673,7 +29192,7 @@ async function checkOrphanedCompletions() {
28673
29192
  async function checkPendingTestDispatch() {
28674
29193
  const actions = [];
28675
29194
  try {
28676
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-BZH8h-6W.js");
29195
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-CacDM78F.js");
28677
29196
  const statuses = loadReviewStatuses();
28678
29197
  const now = Date.now();
28679
29198
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -28706,7 +29225,7 @@ async function checkPendingTestDispatch() {
28706
29225
  console.log(`[deacon] ${issueId}: skipping test re-dispatch — issue is closed`);
28707
29226
  continue;
28708
29227
  }
28709
- const { resolveProjectFromIssueSync } = await import("./projects-B03Wr-xc.js");
29228
+ const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
28710
29229
  const resolved = resolveProjectFromIssueSync(issueId);
28711
29230
  if (!resolved) continue;
28712
29231
  const issueLower = issueId.toLowerCase();
@@ -28721,8 +29240,8 @@ async function checkPendingTestDispatch() {
28721
29240
  logDeaconEventSync(`checkPendingTestDispatch: deferred test for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
28722
29241
  continue;
28723
29242
  }
28724
- const { spawnRun } = await import("./agents-BKKkxKgK.js");
28725
- const { buildTestRolePrompt } = await import("./test-agent-queue-qakFIIGz.js");
29243
+ const { spawnRun } = await import("./agents-Dnn4XgdB.js");
29244
+ const { buildTestRolePrompt } = await import("./test-agent-queue-DmSIqays.js");
28726
29245
  try {
28727
29246
  const run = await spawnRun(issueId, "test", {
28728
29247
  workspace,
@@ -28730,7 +29249,8 @@ async function checkPendingTestDispatch() {
28730
29249
  issueId,
28731
29250
  workspace,
28732
29251
  branch
28733
- })
29252
+ }),
29253
+ startedBy: "deacon:test-retry"
28734
29254
  });
28735
29255
  setReviewStatusSync(issueId, {
28736
29256
  testStatus: "testing",
@@ -28845,7 +29365,7 @@ async function checkCompletedButUnsignaledTests() {
28845
29365
  const cmd = `pan admin specialists done test ${issueId} --status ${decision.status}${noteArg}`;
28846
29366
  const nudge = `Your test verdict (${decision.status}) is already written to .pan/test/result.json. Your ONLY remaining task is to execute this Bash command immediately — do not analyze, do not summarize, do not ask questions, just run it:\n\n${cmd}\n\nRun this command NOW. Do not write any other response before executing it.`;
28847
29367
  try {
28848
- const { messageAgent } = await import("./agents-BKKkxKgK.js");
29368
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
28849
29369
  await messageAgent(testSession, nudge);
28850
29370
  unsignaledTestNudges.set(testSession, now);
28851
29371
  const msg = `Nudged ${testSession} to signal ${decision.status} (verdict artifact present)`;
@@ -28859,7 +29379,7 @@ async function checkCompletedButUnsignaledTests() {
28859
29379
  case "nudge-write": {
28860
29380
  const nudge = `Your test run for ${issueId} looks finished but no verdict was recorded. Decide the verdict from the gates/UAT you ran, then do BOTH of these now: (1) write the workspace file .pan/test/result.json as {"status":"passed"|"failed","notes":"<evidence>"}, and (2) run: pan admin specialists done test ${issueId} --status passed|failed. Do this immediately — do not summarize or ask questions, just write the file and run the command.`;
28861
29381
  try {
28862
- const { messageAgent } = await import("./agents-BKKkxKgK.js");
29382
+ const { messageAgent } = await import("./agents-Dnn4XgdB.js");
28863
29383
  await messageAgent(testSession, nudge);
28864
29384
  unsignaledTestNudges.set(testSession, now);
28865
29385
  const msg = `Nudged ${testSession} to write+signal a test verdict (no artifact yet)`;
@@ -28882,8 +29402,8 @@ async function checkCompletedButUnsignaledTests() {
28882
29402
  async function checkVerificationReviewContradiction() {
28883
29403
  const actions = [];
28884
29404
  try {
28885
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-BZH8h-6W.js");
28886
- const { resolveProjectFromIssueSync } = await import("./projects-B03Wr-xc.js");
29405
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-CacDM78F.js");
29406
+ const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
28887
29407
  const statuses = loadReviewStatuses();
28888
29408
  for (const [issueId, status] of Object.entries(statuses)) if (status.verificationStatus === "passed" && status.reviewStatus === "reviewing" && status.stuckReason === "review_infrastructure_failure") {
28889
29409
  let reviewedAtCommit;
@@ -28892,7 +29412,7 @@ async function checkVerificationReviewContradiction() {
28892
29412
  if (project) {
28893
29413
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
28894
29414
  if (existsSync(workspacePath)) {
28895
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CI6cwyyC.js");
29415
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CedsVume.js");
28896
29416
  reviewedAtCommit = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);
28897
29417
  }
28898
29418
  }
@@ -28956,8 +29476,8 @@ async function cleanupOrphanedPlanningSessions() {
28956
29476
  async function handleAgentStoppedEvent(agentId, opts = {}) {
28957
29477
  return handleAgentStoppedEvent$1(agentId, opts, autoResumeNotifierDeps());
28958
29478
  }
28959
- async function applyBootReconciliationDecision() {
28960
- return applyBootReconciliationDecision$1(autoResumeNotifierDeps());
29479
+ async function applyBootReconciliationDecision(opts = {}) {
29480
+ return applyBootReconciliationDecision$1(autoResumeNotifierDeps(), opts);
28961
29481
  }
28962
29482
  async function reconcileAgentLiveness() {
28963
29483
  if (isDeaconGloballyPaused()) {
@@ -28988,7 +29508,7 @@ async function checkReadyForMergeStuck() {
28988
29508
  const testStatusGreenCiReconcileCooldowns = /* @__PURE__ */ new Map();
28989
29509
  const TEST_STATUS_GREEN_CI_RECONCILE_COOLDOWN_MS = 300 * 1e3;
28990
29510
  async function reconcileTestStatusFromGreenCi() {
28991
- const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-DtAsvwzK.js");
29511
+ const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-DIE8BkHI.js");
28992
29512
  return reconcileTestStatusFromGreenCiWithDeps({
28993
29513
  isGitHubAppConfigured,
28994
29514
  loadReviewStatuses,
@@ -29009,7 +29529,7 @@ async function reconcileTestStatusFromGreenCi() {
29009
29529
  */
29010
29530
  async function clearStaleCiFeedback(issueId) {
29011
29531
  const { readdir, rm } = await import("fs/promises");
29012
- const { resolveProjectFromIssueSync } = await import("./projects-B03Wr-xc.js");
29532
+ const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
29013
29533
  const projectConfig = resolveProjectFromIssueSync(issueId);
29014
29534
  if (!projectConfig) return;
29015
29535
  const repoDir = projectConfig.projectPath;
@@ -29305,7 +29825,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
29305
29825
  }
29306
29826
  }
29307
29827
  try {
29308
- const { resolveProjectFromIssueSync } = await import("./projects-B03Wr-xc.js");
29828
+ const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
29309
29829
  const resolved = resolveProjectFromIssueSync(issueLower.toUpperCase());
29310
29830
  if (resolved) await killOrphanedWorkspaceProcesses(`${resolved.projectPath}/workspaces/feature-${issueLower}`);
29311
29831
  } catch {}
@@ -29354,8 +29874,8 @@ async function checkWorkspaceContainerHealth(sharedState) {
29354
29874
  async function checkMergedWorkSessions() {
29355
29875
  const actions = [];
29356
29876
  try {
29357
- const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-BQ23nriz.js");
29358
- const { setAgentPaused } = await import("./agents-BKKkxKgK.js");
29877
+ const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-DvFqQUnq.js");
29878
+ const { setAgentPaused } = await import("./agents-Dnn4XgdB.js");
29359
29879
  const toKill = selectMergedWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
29360
29880
  for (const session of toKill) try {
29361
29881
  await Effect.runPromise(setAgentPaused(session, "merged — awaiting close-out (verify on main)", true));
@@ -29395,7 +29915,7 @@ const AWAITING_TEST_IDLE_REAP_MS = 600 * 1e3;
29395
29915
  async function checkAwaitingTestWorkSessions() {
29396
29916
  const actions = [];
29397
29917
  try {
29398
- const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-BQ23nriz.js");
29918
+ const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-DvFqQUnq.js");
29399
29919
  const candidates = selectAwaitingTestWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
29400
29920
  const now = Date.now();
29401
29921
  for (const session of candidates) {
@@ -29448,26 +29968,26 @@ async function runPatrol() {
29448
29968
  hasLoggedGlobalPauseSkip = false;
29449
29969
  addLog("info", `Patrol cycle ${state.patrolCycle} — checking per-project specialists`, state.patrolCycle);
29450
29970
  console.log(`[deacon] Patrol cycle ${state.patrolCycle} - checking per-project specialists`);
29451
- for (const a of await (await import("./stale-task-claims-CYFOUNlT.js")).patrolStaleTaskClaims()) {
29971
+ for (const a of await (await import("./stale-task-claims-D1Ll8fI5.js")).patrolStaleTaskClaims()) {
29452
29972
  actions.push(a);
29453
29973
  addLog("action", a, state.patrolCycle);
29454
29974
  }
29455
29975
  const stuckRemediationActions = await checkStuckAgentRemediation();
29456
29976
  actions.push(...stuckRemediationActions);
29457
29977
  for (const a of stuckRemediationActions) addLog("action", a, state.patrolCycle);
29458
- const { reconcileInFlightJournals } = await import("./advancing-selfheal-De1L-Sb4.js");
29978
+ const { reconcileInFlightJournals } = await import("./advancing-selfheal-DieFp3qi.js");
29459
29979
  const reconciledJournalActions = await reconcileInFlightJournals();
29460
29980
  actions.push(...reconciledJournalActions);
29461
29981
  for (const a of reconciledJournalActions) addLog("action", a, state.patrolCycle);
29462
29982
  try {
29463
29983
  const pendingFile = join$1(OVERDECK_HOME, "pending-post-merge.json");
29464
- const { processPendingLifecycleForPatrol } = await import("./deacon-pending-lifecycle-Cpk0k7Hi.js");
29984
+ const { processPendingLifecycleForPatrol } = await import("./deacon-pending-lifecycle-2ZflPxgo.js");
29465
29985
  const action = await processPendingLifecycleForPatrol(pendingFile);
29466
29986
  if (action) actions.push(action);
29467
29987
  } catch (err) {
29468
29988
  console.warn(`[deacon] Failed to process pending lifecycle: ${err.message}`);
29469
29989
  }
29470
- if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-Df-Tmaq0.js")).runScheduledDeployPatrol();
29990
+ if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-BNjeCL8u.js")).runScheduledDeployPatrol();
29471
29991
  const livenessActions = await reconcileAgentLiveness();
29472
29992
  actions.push(...livenessActions);
29473
29993
  for (const a of livenessActions) addLog("action", a, state.patrolCycle);
@@ -29483,7 +30003,7 @@ async function runPatrol() {
29483
30003
  const idleStackActions = await reconcileIdleWorkspaceStacks();
29484
30004
  actions.push(...idleStackActions);
29485
30005
  for (const a of idleStackActions) addLog("action", a, state.patrolCycle);
29486
- for (const a of await (await import("./bridge-pool-patrol-CUFmjVDN.js")).patrolDockerBridgePool()) {
30006
+ for (const a of await (await import("./bridge-pool-patrol-DsPj6F7t.js")).patrolDockerBridgePool()) {
29487
30007
  actions.push(a);
29488
30008
  addLog("action", a, state.patrolCycle);
29489
30009
  }
@@ -29503,7 +30023,7 @@ async function runPatrol() {
29503
30023
  actions.push(...suspendActions);
29504
30024
  for (const a of suspendActions) addLog("action", a, state.patrolCycle);
29505
30025
  try {
29506
- const { resolveProjectFromIssueSync } = await import("./projects-B03Wr-xc.js");
30026
+ const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
29507
30027
  const allStatuses = loadReviewStatuses();
29508
30028
  for (const [issueId, status] of Object.entries(allStatuses)) {
29509
30029
  if (!status.readyForMerge || status.mergeStatus === "merged") continue;
@@ -29523,7 +30043,7 @@ async function runPatrol() {
29523
30043
  } catch (err) {
29524
30044
  console.warn(`[deacon] Failed to check workspace existence: ${err.message}`);
29525
30045
  }
29526
- const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-De1L-Sb4.js");
30046
+ const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-DieFp3qi.js");
29527
30047
  const reapedWorkActions = await checkMergedWorkSessions();
29528
30048
  actions.push(...reapedWorkActions);
29529
30049
  for (const a of reapedWorkActions) addLog("action", a, state.patrolCycle);
@@ -29531,7 +30051,7 @@ async function runPatrol() {
29531
30051
  actions.push(...reapedMergedAdvancingActions);
29532
30052
  for (const a of reapedMergedAdvancingActions) addLog("action", a, state.patrolCycle);
29533
30053
  try {
29534
- const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-DAB0P706.js");
30054
+ const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-BtmZ42aP.js");
29535
30055
  const remoteCredentialActions = await refreshClaudeCredentialsForActiveRemoteAgents();
29536
30056
  actions.push(...remoteCredentialActions);
29537
30057
  for (const a of remoteCredentialActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -29539,7 +30059,7 @@ async function runPatrol() {
29539
30059
  addLog("warn", `Remote credential refresh patrol failed: ${err.message}`, state.patrolCycle);
29540
30060
  }
29541
30061
  try {
29542
- const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-C1bssi41.js");
30062
+ const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-kwsEZvXu.js");
29543
30063
  const heartbeatActions = await refreshHostHeartbeatForEphemeralVms();
29544
30064
  actions.push(...heartbeatActions);
29545
30065
  for (const a of heartbeatActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -29547,7 +30067,7 @@ async function runPatrol() {
29547
30067
  addLog("warn", `Remote heartbeat refresh patrol failed: ${err.message}`, state.patrolCycle);
29548
30068
  }
29549
30069
  try {
29550
- const { reapCompletedRemoteAgents } = await import("./remote-completion-DAB0P706.js");
30070
+ const { reapCompletedRemoteAgents } = await import("./remote-completion-BtmZ42aP.js");
29551
30071
  const remoteReap = await reapCompletedRemoteAgents();
29552
30072
  for (const r of remoteReap) if (r.status === "handed-off" || r.status === "error") {
29553
30073
  const msg = `Remote reap ${r.issueId}: ${r.status} (${r.details.join("; ")})`;
@@ -29596,6 +30116,9 @@ async function runPatrol() {
29596
30116
  const unsignaledReviewActions = await checkCompletedButUnsignaledReviews();
29597
30117
  actions.push(...unsignaledReviewActions);
29598
30118
  for (const a of unsignaledReviewActions) addLog("action", a, state.patrolCycle);
30119
+ const unappliedReviewActions = await reconcileUnappliedReviewVerdicts();
30120
+ actions.push(...unappliedReviewActions);
30121
+ for (const a of unappliedReviewActions) addLog("action", a, state.patrolCycle);
29599
30122
  const verifContradictionActions = await checkVerificationReviewContradiction();
29600
30123
  actions.push(...verifContradictionActions);
29601
30124
  for (const a of verifContradictionActions) addLog("action", a, state.patrolCycle);
@@ -29649,9 +30172,16 @@ async function runPatrol() {
29649
30172
  const closedPrReadyActions = await reconcileClosedPrReadyForMerge();
29650
30173
  actions.push(...closedPrReadyActions);
29651
30174
  for (const a of closedPrReadyActions) addLog("action", a, state.patrolCycle);
30175
+ for (const a of await reconcileAutoMergeRows()) {
30176
+ actions.push(a);
30177
+ addLog("action", a, state.patrolCycle);
30178
+ }
29652
30179
  const staleMergeBlockerActions = await reconcileStaleMergeBlockers();
29653
30180
  actions.push(...staleMergeBlockerActions);
29654
30181
  for (const a of staleMergeBlockerActions) addLog("action", a, state.patrolCycle);
30182
+ const branchInvalidationActions = await reconcileBranchInvalidation();
30183
+ actions.push(...branchInvalidationActions);
30184
+ for (const a of branchInvalidationActions) addLog("action", a, state.patrolCycle);
29655
30185
  const stuckReadyActions = reconcileStuckReadyForMerge();
29656
30186
  actions.push(...stuckReadyActions);
29657
30187
  for (const a of stuckReadyActions) addLog("action", a, state.patrolCycle);
@@ -29733,7 +30263,7 @@ async function runPatrol() {
29733
30263
  const issueId = runtimeState.currentIssue;
29734
30264
  try {
29735
30265
  if (getReviewStatusSync(issueId)?.mergeStatus === "merging") {
29736
- const { resolveProjectFromIssueSync } = await import("./projects-B03Wr-xc.js");
30266
+ const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
29737
30267
  const resolved = resolveProjectFromIssueSync(issueId);
29738
30268
  if (resolved) {
29739
30269
  const branch = `feature/${issueId.toLowerCase()}`;
@@ -29747,7 +30277,7 @@ async function runPatrol() {
29747
30277
  mergeStatus: "merged",
29748
30278
  readyForMerge: false
29749
30279
  });
29750
- const { postMergeLifecycle } = await import("./merge-agent-DrXa1CpW.js");
30280
+ const { postMergeLifecycle } = await import("./merge-agent-C1-9zbP_.js");
29751
30281
  postMergeLifecycle(issueId, resolved.projectPath).catch((err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`));
29752
30282
  actions.push(`Auto-completed stale merge for ${issueId}`);
29753
30283
  } else {
@@ -29927,7 +30457,7 @@ function startDeacon() {
29927
30457
  logDeaconEventSync(`startDeacon: health monitor starting (patrol every ${config.patrolIntervalMs / 1e3}s)`);
29928
30458
  (async () => {
29929
30459
  await reconcileAgentLiveness();
29930
- const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-De1L-Sb4.js");
30460
+ const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-DieFp3qi.js");
29931
30461
  await runBootAdvancingSelfHeal();
29932
30462
  runScheduledPatrol("startup");
29933
30463
  })().catch((err) => {
@@ -29997,6 +30527,6 @@ function assessDeaconPatrolFreshness(params) {
29997
30527
  };
29998
30528
  }
29999
30529
  //#endregion
30000
- export { isSynthesisForActiveReviewRun as $, reconcileTestStatusFromGreenCi as A, formatUptime as At, isRapidPostResumeDeath as B, classifyAgentHealth as Bt, handleAgentHeartbeatDeadEvent as C, deliverOrchestratedCompact as Ct, loadConfig as D, WORK_LAUNCHER_GRACE_MS as Dt, isDeaconRunning as E, checkInspectAgentTimeouts as Et, setAgentStoppedNotifier as F, getResourceConfig as Ft, isBootReconciliationCandidate as G, nudgeStalledResumeWorkAgents as H, setMergeReadyNotifier as I, getSystemHealthEvidenceSnapshot as It, cleanupOrphanedReviewSessions as J, listBootReconciliationCandidates as K, startDeacon as L, getSystemHealthSnapshot as Lt, runPatrol as M, getCurrentDockerStats as Mt, saveState as N, getAcceptedSystemHealthSnapshot as Nt, loadState as O, classifyMemoryPressure as Ot, setAgentStatusChangedNotifier as P, getDeployStaleness as Pt, checkStuckReviewing as Q, stopDeacon as R, isSmeeConfiguredSync as Rt, getLastPatrolResult as S, stuckOverflowNativeRecoveryState as St, handleAgentStoppedForOrphanReviewerSessions as T, INSPECT_TIMEOUT_MS as Tt, redeliverUndeliveredKickoffs as U, nudgeIdleWorkAgentsWithOpenBeads as V, extendBootReconciliationGrace as W, synthesizeReviewFromReports as X, monitorReviewConvoySignals as Y, checkCompletedButUnsignaledReviews as Z, cleanupOrphanedPlanningSessions as _, reconcileStuckReadyForMerge as _t, checkCompletedButUnsignaledTests as a, reviewConvoyLiveness as at, getDeaconLogs as b, contextOverflowRecoveryState as bt, checkMergedWorkSessions as c, autoCloseOut as ct, checkReadyForMergeStuck as d, ciRetryMap as dt, checkMissingReviewStatuses as et, checkStuckWorkAgents as f, reconcileClosedPrReadyForMerge as ft, cleanupOrphanReviewerSessions as g, reconcileStaleMergeStatus as gt, cleanupAbandonedFeedback as h, reconcileStaleMergeBlockers as ht, checkAwaitingTestWorkSessions as i, recoverStalledReviewConvoys as it, resetPatrolHeartbeatForStartup as j, getContainerHistory as jt, reconcileAgentLiveness as k, getResourceStacks as kt, checkOrphanedCompletions as l, checkFailedMergeRetry as lt, checkWorkspaceContainerHealth as m, reconcileMergedButReviewing as mt, assessDeaconPatrolFreshness as n, handleReviewCoordinatorDied as nt, checkDeadEndAgents as o, stalledReviewConvoyRecoveryState as ot, checkVerificationReviewContradiction as p, reconcileFalseMerged as pt, startBootReconciliation as q, checkAndSuspendIdleAgents as r, handleWorkCompleted as rt, checkMassDeath as s, checkPostReviewCommits as st, applyBootReconciliationDecision as t, checkOrphanedReviewStatuses as tt, checkPendingTestDispatch as u, checkFirstCompletionAgents as ut, cleanupStaleAgentState as v, reconcileStuckMergingStates as vt, handleAgentStoppedEvent as w, paneShowsClaudeBootBlockingScreen as wt, getDeaconStatus as x, contextProactiveCompactState as xt, containerRestartBackoffMs as y, checkApiErrorAgents as yt, isPreKickoffLaunchDeath as z, startSmeeProcessSync as zt };
30530
+ export { checkStuckReviewing as $, reconcileTestStatusFromGreenCi as A, WORK_LAUNCHER_GRACE_MS as At, isRapidPostResumeDeath as B, getSystemHealthSnapshot as Bt, handleAgentHeartbeatDeadEvent as C, contextOverflowRecoveryState as Ct, loadConfig as D, paneShowsClaudeBootBlockingScreen as Dt, isDeaconRunning as E, deliverOrchestratedCompact as Et, setAgentStoppedNotifier as F, getCurrentDockerStats as Ft, isAutoResumableRole as G, nudgeStalledResumeWorkAgents as H, startSmeeProcessSync as Ht, setMergeReadyNotifier as I, getAcceptedSystemHealthSnapshot as It, startBootReconciliation as J, isBootReconciliationCandidate as K, startDeacon as L, getDeployStaleness as Lt, runPatrol as M, getResourceStacks as Mt, saveState as N, formatUptime as Nt, loadState as O, INSPECT_TIMEOUT_MS as Ot, setAgentStatusChangedNotifier as P, getContainerHistory as Pt, checkCompletedButUnsignaledReviews as Q, stopDeacon as R, getResourceConfig as Rt, getLastPatrolResult as S, checkApiErrorAgents as St, handleAgentStoppedForOrphanReviewerSessions as T, stuckOverflowNativeRecoveryState as Tt, redeliverUndeliveredKickoffs as U, classifyAgentHealth as Ut, nudgeIdleWorkAgentsWithOpenBeads as V, isSmeeConfiguredSync as Vt, extendBootReconciliationGrace as W, monitorReviewConvoySignals as X, cleanupOrphanedReviewSessions as Y, synthesizeReviewFromReports as Z, cleanupOrphanedPlanningSessions as _, reconcileStaleMergeBlockers as _t, checkCompletedButUnsignaledTests as a, handleWorkCompleted as at, getDeaconLogs as b, reconcileAutoMergeRows as bt, checkMergedWorkSessions as c, stalledReviewConvoyRecoveryState as ct, checkReadyForMergeStuck as d, checkFailedMergeRetry as dt, isSynthesisForActiveReviewRun as et, checkStuckWorkAgents as f, checkFirstCompletionAgents as ft, cleanupOrphanReviewerSessions as g, reconcileMergedButReviewing as gt, cleanupAbandonedFeedback as h, reconcileFalseMerged as ht, checkAwaitingTestWorkSessions as i, handleReviewCoordinatorDied as it, resetPatrolHeartbeatForStartup as j, classifyMemoryPressure as jt, reconcileAgentLiveness as k, checkInspectAgentTimeouts as kt, checkOrphanedCompletions as l, checkPostReviewCommits as lt, checkWorkspaceContainerHealth as m, reconcileClosedPrReadyForMerge as mt, assessDeaconPatrolFreshness as n, checkMissingReviewStatuses as nt, checkDeadEndAgents as o, recoverStalledReviewConvoys as ot, checkVerificationReviewContradiction as p, ciRetryMap as pt, listBootReconciliationCandidates as q, checkAndSuspendIdleAgents as r, checkOrphanedReviewStatuses as rt, checkMassDeath as s, reviewConvoyLiveness as st, applyBootReconciliationDecision as t, reconcileUnappliedReviewVerdicts as tt, checkPendingTestDispatch as u, autoCloseOut as ut, cleanupStaleAgentState as v, reconcileStaleMergeStatus as vt, handleAgentStoppedEvent as w, contextProactiveCompactState as wt, getDeaconStatus as x, reconcileStuckMergingStates as xt, containerRestartBackoffMs as y, reconcileStuckReadyForMerge as yt, isPreKickoffLaunchDeath as z, getSystemHealthEvidenceSnapshot as zt };
30001
30531
 
30002
- //# sourceMappingURL=deacon-hi9KLPLT.js.map
30532
+ //# sourceMappingURL=deacon-B1LD5cJU.js.map