@overdeck/desktop 0.47.1 → 0.48.0

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 (444) hide show
  1. package/drizzle/overdeck/0000_overdeck_init.sql +59 -0
  2. package/package.json +1 -1
  3. package/server/{acceptance-criteria-Cd7ZGZCq.js → acceptance-criteria-DmtLDbtt.js} +2 -2
  4. package/server/{activity-logger-CyteR4JO.js → activity-logger-Co5qljIj.js} +55 -4
  5. package/server/activity-logger-K7FYGF_z.js +3 -0
  6. package/server/{advancing-selfheal-DieFp3qi.js → advancing-selfheal-8AR68Asf.js} +6 -6
  7. package/server/{agent-gc-BMcgTDl7.js → agent-gc-BmYeT6eH.js} +5 -5
  8. package/server/agent-state-Dq3s84-P.js +3 -0
  9. package/server/{agent-state-service-DFO6qvHp.js → agent-state-service-DK1Vay1E.js} +1 -1
  10. package/server/{agent-state-service-BOzQhLjU.js → agent-state-service-rjnzpHDx.js} +6 -6
  11. package/server/{agent-state-source-Ca_zCaII.js → agent-state-source-Ds968-j6.js} +1 -1
  12. package/server/{agents-CtACUuVG.js → agents-Dls7tfJH.js} +5 -5
  13. package/server/agents-IPSa5kzn.js +3 -0
  14. package/server/{archive-planning-Binfb99i.js → archive-planning-Cq7cyinS.js} +51 -24
  15. package/server/archive-planning-MbkGCBIY.js +2 -0
  16. package/server/{artifact-index-jobs-Jn7BGOtV.js → artifact-index-jobs-Dj_8kpTd.js} +3 -3
  17. package/server/{assemble-DsqK9OAq.js → assemble-BTCmbcfH.js} +20 -13
  18. package/server/{auto-spawn-consent-BooqhC3L.js → auto-spawn-consent-lXqRJ1Dr.js} +304 -121
  19. package/server/{backlog-auto-trigger-BADGPxov.js → backlog-auto-trigger-Dn-amzt6.js} +3 -3
  20. package/server/{behavior-B7biGtFT.js → behavior-DIMQMRzs.js} +2 -2
  21. package/server/{boot-reconciled-stop-events-bQUzU8ns.js → boot-reconciled-stop-events-D6SeUTIr.js} +1 -1
  22. package/server/{bridge-pool-patrol-DsPj6F7t.js → bridge-pool-patrol-BEjt-xF3.js} +2 -2
  23. package/server/{briefing-freshness-CUerZqWd.js → briefing-freshness-3PNmL_p3.js} +2 -2
  24. package/server/{build-info-D0q_i8WM.js → build-info-CJg813Hm.js} +3 -3
  25. package/server/{build-info-Du74MKiP.js → build-info-CXyeFsXu.js} +1 -1
  26. package/server/{checkpoint-manager-Cu-R5Uzg.js → checkpoint-manager-9t7G5c1V.js} +1 -1
  27. package/server/{checkpoint-manager-R5tnaxEY.js → checkpoint-manager-B2G38R3p.js} +3 -3
  28. package/server/checkpoint-worker.js +1 -1
  29. package/server/{checkpoints-wF84ubZ8.js → checkpoints-CuBgiXO-.js} +1 -1
  30. package/server/{checkpoints-DYtLu-PB.js → checkpoints-VTZMd4Qm.js} +2 -2
  31. package/server/{claude-hooks-provision-DXI3Wqlm.js → claude-hooks-provision-55SyQaPz.js} +2 -2
  32. package/server/{claude-hooks-provision-UKxCeOyj.js → claude-hooks-provision-CEUT-CZd.js} +1 -1
  33. package/server/{claude-permissions-DYVLnX9t.js → claude-permissions-Cn0dIu2i.js} +2 -2
  34. package/server/{claude-settings-overlay-DxP2F_gY.js → claude-settings-overlay-B19hdzSA.js} +1 -1
  35. package/server/{claude-settings-overlay-DsbpIq2d.js → claude-settings-overlay-Yg_ANh81.js} +2 -2
  36. package/server/{cli-DzRKxxP_.js → cli-C9S84iTy.js} +79 -22
  37. package/server/cli-M1cwZ__d.js +3 -0
  38. package/server/{cliproxy-CG4meRFc.js → cliproxy-CJq3KXU6.js} +2 -2
  39. package/server/{cliproxy-Cwzw39yN.js → cliproxy-DgEZlr7Y.js} +1 -1
  40. package/server/{close-issue-BX1bATJy.js → close-issue-DPxRddGR.js} +5 -5
  41. package/server/{closed-issue-reaper-hLt0W86J.js → closed-issue-reaper-C5Zn4GRS.js} +13 -13
  42. package/server/{closed-issue-reaper-DvnTSN6a.js → closed-issue-reaper-D-2B48Ri.js} +1 -1
  43. package/server/{codex-rnJN3v3_.js → codex-B3n_rkwn.js} +1 -1
  44. package/server/{codex-BYwi1uyW.js → codex-CjkD1PJu.js} +6 -6
  45. package/server/{codex-parser-Poyz29GE.js → codex-parser-DpB1Il-P.js} +2 -2
  46. package/server/{compaction-continuation-DtMfHN0f.js → compaction-continuation-DZD9ukSE.js} +3 -3
  47. package/server/{config-R793W0yA.js → config-C5saf4Ja.js} +1 -1
  48. package/server/{config-CX4vk1CV.js → config-DnLJATZk.js} +2 -2
  49. package/server/{config-ktAVnp4s.js → config-DvM8jtQK.js} +2 -2
  50. package/server/{config-yaml-CxdwhAIA.js → config-yaml-BSCqwmX0.js} +11299 -10972
  51. package/server/{conflict-gate-BSTlwCtF.js → conflict-gate-DXa_L28t.js} +1 -1
  52. package/server/{conflict-gate-BNv6UolH.js → conflict-gate-WfVqgalf.js} +4 -4
  53. package/server/{context-layers-DCdaGsRG.js → context-layers-D7UqH9Ab.js} +2 -2
  54. package/server/{context-layers-DlWsDiRF.js → context-layers-Dpz3Vd6d.js} +3 -3
  55. package/server/{control-settings-qYYHrIqy.js → control-settings-DVf6pKyv.js} +4 -4
  56. package/server/{conversation-compaction-BxUKObHb.js → conversation-compaction-5XuH6OBn.js} +1 -1
  57. package/server/{conversation-compaction-CXQrN3I_.js → conversation-compaction-COrbnX1J.js} +8 -8
  58. package/server/{conversation-service-CZiUE8Uw.js → conversation-service-BufdtnZF.js} +169 -10
  59. package/server/{conversation-service-CDnQ3ayN.js → conversation-service-DnUyIiLb.js} +1 -1
  60. package/server/{conversations-D7lR670u.js → conversations-B4rxz-Wl.js} +17 -10
  61. package/server/{conversations-DXl5YTf4.js → conversations-D1bwxQMy.js} +1 -1
  62. package/server/{cost-Aat8HfO_.js → cost-CpFDrJUS.js} +46 -2
  63. package/server/{cost-CWvN9FP2.js → cost-KLuwKCW9.js} +3 -3
  64. package/server/{cost-sync-DiUBXwl6.js → cost-sync-cesi9dp8.js} +3 -3
  65. package/server/{dag-5QlmH0oC.js → dag-BYiFMqpU.js} +2 -2
  66. package/server/{dangerous-git-ops-DWX6Og8c.js → dangerous-git-ops-BKvd3-Hk.js} +1 -1
  67. package/server/dashboard-db-worker.js +7 -7
  68. package/server/{deacon-PW_bg4uL.js → deacon-BbsWw8a6.js} +3 -3
  69. package/server/{deacon-B1LD5cJU.js → deacon-HdEh0Esp.js} +672 -181
  70. package/server/deacon-event-client-C93rvOT7.js +237 -0
  71. package/server/deacon-event-client-Ck5Ei7Mn.js +3 -0
  72. package/server/{deacon-nudge-log-DPHsO14z.js → deacon-nudge-log-BND_97Wo.js} +4 -3
  73. package/server/{deacon-pending-lifecycle-2ZflPxgo.js → deacon-pending-lifecycle-CD3YsiQK.js} +3 -3
  74. package/server/deacon-swarm-DgWADWd_.js +2 -0
  75. package/server/{deacon-swarm-DwGUgSVp.js → deacon-swarm-rqrl4TMs.js} +39 -18
  76. package/server/deacon.js +12 -210
  77. package/server/{dead-end-trip-B06RFIr2.js → dead-end-trip-DSF23CLX.js} +4 -3
  78. package/server/dead-end-trip-zKlS4v6f.js +2 -0
  79. package/server/delivery-CsbQdZkS.js +3 -0
  80. package/server/{deploy-patrol-BNjeCL8u.js → deploy-patrol-kARAkji4.js} +17 -21
  81. package/server/{deploy-queue-CKT_Ia9p.js → deploy-queue-Bj0HJT1i.js} +2 -2
  82. package/server/{deploy-queue-DMMYhFC8.js → deploy-queue-rjTUy1RM.js} +1 -1
  83. package/server/{deploy-window-DC8lze3d.js → deploy-window-B2IM-9G5.js} +10 -44
  84. package/server/{deploy-window-D_AimdNN.js → deploy-window-BNFWnA8D.js} +1 -1
  85. package/server/{dev-supervisor-C4F0vbno.js → dev-supervisor-B1mZYXz4.js} +2 -2
  86. package/server/{devcontainer-renderer-66sqMQIi.js → devcontainer-renderer-B-o68Z5B.js} +3 -3
  87. package/server/{dist-C5FT9lTG.js → dist-3W--cGMa.js} +1 -1
  88. package/server/dist-BR0QtwmS.js +3 -0
  89. package/server/{dist-src-B-AlGWSl.js → dist-src-C-Vk2jNk.js} +1 -1
  90. package/server/{docker-BxrFhTZ_.js → docker-DH3jUYg1.js} +1 -1
  91. package/server/{docker-CoAT8R0J.js → docker-meuLKLzV.js} +27 -20
  92. package/server/{dod-Bg6wsKTV.js → dod-D7-9dCOD.js} +1 -1
  93. package/server/{driver-CKVGi51s.js → driver-CmsY2RLl.js} +1 -1
  94. package/server/{durable-review-pipeline-D_DcfIGP.js → durable-review-pipeline-CStTgOAf.js} +1 -1
  95. package/server/{durable-review-pipeline-HkAgnx0L.js → durable-review-pipeline-Chq0lzjL.js} +1 -1
  96. package/server/{ensure-devcontainer-Bg5HJAcO.js → ensure-devcontainer-BE3llBWP.js} +1 -1
  97. package/server/{ensure-devcontainer-DTxChVuA.js → ensure-devcontainer-BXrY7C2Z.js} +4 -4
  98. package/server/{esm-shims-CaBWIR7f.js → esm-shims-Bzy4ZzNU.js} +1 -1
  99. package/server/event-store-COd2tOx8.js +3 -0
  100. package/server/{event-store-CrHcVC5_.js → event-store-D_AR-Y78.js} +184 -11
  101. package/server/{events-ChEFB7Jp.js → events-CCkFWa7X.js} +1 -1
  102. package/server/{events-DhRN-6vM.js → events-zjDQozet.js} +3 -3
  103. package/server/{factory-BezSPaTd.js → factory-DhavwKVc.js} +5 -5
  104. package/server/{feature-registry-population-DhswNiXx.js → feature-registry-population-DWGBKyWd.js} +4 -4
  105. package/server/{feature-registry-storage-CUVNpAso.js → feature-registry-storage-C5DkXmCM.js} +3 -3
  106. package/server/{features-B2CfNPFw.js → features-CC47YcCX.js} +2 -2
  107. package/server/{feedback-target-CMrEAoeA.js → feedback-target-D9Tex35_.js} +1 -1
  108. package/server/{feedback-target-VBr9gKgX.js → feedback-target-DoRCR3L-.js} +8 -8
  109. package/server/{feedback-writer-CY91ckuw.js → feedback-writer-CTSuA6lw.js} +1 -1
  110. package/server/{feedback-writer-xpFgU632.js → feedback-writer-DdsBdtNL.js} +5 -5
  111. package/server/{flywheel-DsICCjTR.js → flywheel-DHWHzaYK.js} +1 -1
  112. package/server/{flywheel-DQqsSm7P.js → flywheel-DJQa9az8.js} +14 -14
  113. package/server/{flywheel-CTVY3yCG.js → flywheel-TacAI9MA.js} +21 -17
  114. package/server/{flywheel-merge-order-C-TI4JGu.js → flywheel-merge-order-D2foPh88.js} +1 -1
  115. package/server/{flywheel-merge-order-CMGz-imq.js → flywheel-merge-order-DRtex2Dt.js} +7 -7
  116. package/server/forge-CdlCG9aS.js +3 -0
  117. package/server/{forge-RTNqJe6a.js → forge-c8LeC-tw.js} +2 -2
  118. package/server/{from-DxGcivc9.js → from-BogSwvr2.js} +1 -1
  119. package/server/{fs-lock-Bre3sGoz.js → fs-lock-D_GeJtXl.js} +3 -3
  120. package/server/{fts-operations-BuTdlZFA.js → fts-operations-DP9R-8Q3.js} +3 -3
  121. package/server/{git-utils-CedsVume.js → git-utils-C31x1lpE.js} +1 -1
  122. package/server/{git-utils-DtdoEXJk.js → git-utils-xQ74FoSn.js} +5 -4
  123. package/server/{github-app-DIE8BkHI.js → github-app-CpQSDlv8.js} +1 -1
  124. package/server/{github-app-gVnZcP9B.js → github-app-D2QuvZ3j.js} +3 -3
  125. package/server/{github-client-BrAC6ELh.js → github-client-D9YvJX5D.js} +3 -3
  126. package/server/{github-client-CBOkvBUl.js → github-client-Tpi3PmKX.js} +1 -1
  127. package/server/{github-pr-lookup-CgMULTPf.js → github-pr-lookup-DvBMv-IW.js} +2 -2
  128. package/server/{harness-binary-CnBHpd57.js → harness-binary-BHxWf_sX.js} +7 -6
  129. package/server/{harness-resolve-BVj6sI8m.js → harness-resolve-bj9WMABA.js} +4 -4
  130. package/server/{health-events-BBWO_Dh9.js → health-events-bCDPn59Z.js} +2 -2
  131. package/server/{health-events-Der6bOkm.js → health-events-qo7Ss34U.js} +1 -1
  132. package/server/{hooks-BOavco-e.js → hooks-Dyxtg5fk.js} +2 -2
  133. package/server/{hooks-BJNal-bs.js → hooks-X2XHBB2b.js} +1 -1
  134. package/server/{hume-DBocJFkA.js → hume-DrZEGpqc.js} +2 -2
  135. package/server/hume-YPsy4UA8.js +3 -0
  136. package/server/{idle-stack-reaper-DQFh8rDh.js → idle-stack-reaper-CJ1ygW0p.js} +37 -7
  137. package/server/{idle-stack-reaper-CyGxXOfC.js → idle-stack-reaper-uJGOb-vu.js} +1 -1
  138. package/server/{in-flight-guard-nXEKoxI7.js → in-flight-guard-CG2Eo-rr.js} +1 -1
  139. package/server/{infra-BDQDRopn.js → infra-CTrmVqc_.js} +111 -6
  140. package/server/{injection-DfFFEMKL.js → injection-BisQ0lpX.js} +1 -1
  141. package/server/{injection-CCopdUKz.js → injection-C9sxqbc2.js} +73 -193
  142. package/server/{inspect-agent-FCDlNT_i.js → inspect-agent-BoSO51YC.js} +12 -12
  143. package/server/inspect-agent-BykeOH4a.js +2 -0
  144. package/server/{internal-token-BG6yQKNL.js → internal-token-AvXePaQT.js} +2 -2
  145. package/server/{internal-token-BJZa40Ld.js → internal-token-Djkj-yqK.js} +1 -1
  146. package/server/{io-C0NV7y6C.js → io-mxOWMZ7I.js} +6 -6
  147. package/server/{issue-closed-CNNGbhWm.js → issue-closed-Bj_bCv_0.js} +7 -7
  148. package/server/{issue-lifecycle-DSH0GpWC.js → issue-lifecycle-A5YIpDZE.js} +1 -1
  149. package/server/{issue-lifecycle-BXfzxFCD.js → issue-lifecycle-BXUqaHzF.js} +32 -28
  150. package/server/{issue-service-singleton-F3A5VP6M.js → issue-service-singleton-BPNEXczv.js} +11 -11
  151. package/server/{issue-service-singleton-lwFJ4dHk.js → issue-service-singleton-CcaHjKPR.js} +1 -1
  152. package/server/{issues-DA-U_MpR.js → issues-AX-YBeAQ.js} +2 -2
  153. package/server/{jsonl-parser-BXiGANOh.js → jsonl-parser-CgYWQ20q.js} +7 -3
  154. package/server/kimi-code-BYbme0aV.js +579 -0
  155. package/server/kimi-code-D_Ppt82c.js +3 -0
  156. package/server/kimi-parser-B-JBg3Pv.js +147 -0
  157. package/server/{label-cleanup-BnxRk0Eo.js → label-cleanup-sXUlgdM0.js} +3 -3
  158. package/server/{lifecycle-DOgGnpIv.js → lifecycle-D2X3al0D.js} +2 -2
  159. package/server/{lifecycle-Di48-w4x.js → lifecycle-DjlljAZ1.js} +6 -6
  160. package/server/{lifecycle-io-eVG6v_8-.js → lifecycle-io-C5nVk55o.js} +1 -1
  161. package/server/{lifecycle-io-1XSeczTr.js → lifecycle-io-NPm1YtIG.js} +5 -5
  162. package/server/{linear-client-CvGo9n7M.js → linear-client--luYwCZg.js} +1 -1
  163. package/server/{linear-client-CYZRrcjp.js → linear-client-B8pLegW1.js} +3 -3
  164. package/server/{linear-mcp-auth-Cp0XaP96.js → linear-mcp-auth-BQVWV0I3.js} +6 -6
  165. package/server/{linear-mcp-auth-DoJnjdPZ.js → linear-mcp-auth-Dx81Zl4G.js} +1 -1
  166. package/server/memory-fts-worker.js +1 -1
  167. package/server/{merge-DO14mOr3.js → merge-Bx5Bh9pi.js} +3 -3
  168. package/server/{merge-ZF99ig6A.js → merge-Dqmh_zja.js} +1 -1
  169. package/server/{merge-agent-gpiRkcvj.js → merge-agent-DP9AUY29.js} +33 -33
  170. package/server/{merge-agent-C1-9zbP_.js → merge-agent-DWd0KfiS.js} +1 -1
  171. package/server/{merge-batch-C11ocNkO.js → merge-batch-BdmvTEAC.js} +1 -1
  172. package/server/{merge-completeness-CghMbyX7.js → merge-completeness-BfRwFjRx.js} +1 -1
  173. package/server/{merge-completeness-BUzPZy0E.js → merge-completeness-C1FevcDT.js} +4 -4
  174. package/server/merge-ops-B98tKc1e.js +2 -0
  175. package/server/merge-rebase-BLykMwPO.js +2 -0
  176. package/server/{merge-rebase-iwlUzZjr.js → merge-rebase-BX1xKsrE.js} +2 -2
  177. package/server/{merge-set-Dbnx4chw.js → merge-set-DsLjjLEV.js} +4 -4
  178. package/server/{merge-set-BymrheTj.js → merge-set-H6epHOsw.js} +1 -1
  179. package/server/{merge-sync-CM978zez.js → merge-sync-BEdfsQV4.js} +2 -2
  180. package/server/{merge-sync-CqEtqjI2.js → merge-sync-BebcWWGA.js} +1 -1
  181. package/server/{merge-train-DvLcAn1G.js → merge-train-D1I0lNOT.js} +4 -4
  182. package/server/{merge-train-deps-Cl_kcRbO.js → merge-train-deps-D_-C0Pk2.js} +4 -4
  183. package/server/{merge-verification-c9Y9mllw.js → merge-verification-DN1Ov9bU.js} +6 -6
  184. package/server/{merged-docker-cleanup-worker-CGiDOdv8.js → merged-docker-cleanup-worker-CfXSr2pA.js} +4 -4
  185. package/server/{merged-docker-cleanup-worker-DgsLOx3E.js → merged-docker-cleanup-worker-ybsPyHjB.js} +1 -1
  186. package/server/{multipart-parser-D0twwRjz.js → multipart-parser-CL5QG8iv.js} +2 -2
  187. package/server/{no-resume-mode-DZvP0M_S.js → no-resume-mode-DUR7Hi98.js} +1 -1
  188. package/server/node_modules/.package-lock.json +7 -7
  189. package/server/node_modules/brace-expansion/README.md +23 -1
  190. package/server/node_modules/brace-expansion/index.js +206 -85
  191. package/server/node_modules/brace-expansion/package.json +1 -1
  192. package/server/node_modules/msgpackr/dist/index-no-eval.cjs +34 -28
  193. package/server/node_modules/msgpackr/dist/index-no-eval.cjs.map +1 -1
  194. package/server/node_modules/msgpackr/dist/index-no-eval.min.js +1 -1
  195. package/server/node_modules/msgpackr/dist/index-no-eval.min.js.map +1 -1
  196. package/server/node_modules/msgpackr/dist/index.js +34 -28
  197. package/server/node_modules/msgpackr/dist/index.js.map +1 -1
  198. package/server/node_modules/msgpackr/dist/index.min.js +1 -1
  199. package/server/node_modules/msgpackr/dist/index.min.js.map +1 -1
  200. package/server/node_modules/msgpackr/dist/node.cjs +36 -29
  201. package/server/node_modules/msgpackr/dist/node.cjs.map +1 -1
  202. package/server/node_modules/msgpackr/dist/test.js +63 -32
  203. package/server/node_modules/msgpackr/dist/test.js.map +1 -1
  204. package/server/node_modules/msgpackr/dist/unpack-no-eval.cjs +34 -28
  205. package/server/node_modules/msgpackr/dist/unpack-no-eval.cjs.map +1 -1
  206. package/server/node_modules/msgpackr/package.json +1 -1
  207. package/server/node_modules/msgpackr/unpack.js +34 -28
  208. package/server/{orphan-proposed-reconciler-6r2OEfYd.js → orphan-proposed-reconciler-CEW1maPl.js} +1 -1
  209. package/server/{orphan-proposed-reconciler-DtQP6oE_.js → orphan-proposed-reconciler-DfqHZftT.js} +23 -22
  210. package/server/package-lock.json +8 -8
  211. package/server/package.json +1 -1
  212. package/server/{pan-dir-DAOb1V2-.js → pan-dir-DhgKfO86.js} +21 -6
  213. package/server/{paths-DuATV5iE.js → paths-BUuhi6jM.js} +17 -17
  214. package/server/{pending-lifecycle-claim-DQUHIDfX.js → pending-lifecycle-claim-DJlA1rTR.js} +2 -2
  215. package/server/{persistent-logger-CBj016pT.js → persistent-logger-s8cbpFNV.js} +2 -2
  216. package/server/{pickup-zXZl5lQI.js → pickup-2AxtB3dW.js} +1 -1
  217. package/server/{pipeline-membership-DHOXmvba.js → pipeline-membership-2_okL5bm.js} +1 -1
  218. package/server/{pipeline-membership-B2yUcBz7.js → pipeline-membership-Dqv6_0ig.js} +1 -1
  219. package/server/{pipeline-membership-gather-OkLXuvxR.js → pipeline-membership-gather-4F1-tXKI.js} +1 -1
  220. package/server/{pipeline-membership-gather-BIcJ-N0W.js → pipeline-membership-gather-CtJ_7aGf.js} +149 -17
  221. package/server/{pipeline-notifier-BmwrVKsO.js → pipeline-notifier-CO9rxJgB.js} +1 -1
  222. package/server/{pipeline-notifier-CxMes51i.js → pipeline-notifier-DDfVBJhJ.js} +2 -2
  223. package/server/{post-merge-lifecycle-worker-3u_rA4R0.js → post-merge-lifecycle-worker-DmSOkeNp.js} +3 -3
  224. package/server/{project-pipelines-C3SPFJ38.js → project-pipelines-72WE8GVK.js} +2 -2
  225. package/server/{project-repos-BOpBzkO6.js → project-repos-BAqDwtvi.js} +16 -11
  226. package/server/project-repos-Df90Zw7Y.js +3 -0
  227. package/server/projects-WqMWCdpa.js +3 -0
  228. package/server/{prompts-B0TtboFm.js → prompts-XkL10m8M.js} +2 -2
  229. package/server/{providers-O2smCvSz.js → providers-ClGPGkQ8.js} +15 -12
  230. package/server/providers-DFUOed8u.js +3 -0
  231. package/server/public/assets/{chunk-BO2N2NFS-D_pGACYN.js → chunk-BO2N2NFS-CeQUdPxr.js} +4 -4
  232. package/server/public/assets/{diagram-OG6HWLK6-BO6fe3hH.js → diagram-OG6HWLK6-B7rgk4yT.js} +1 -1
  233. package/server/public/assets/{dist-5zingMiA.js → dist-2RPazfXY.js} +3 -3
  234. package/server/public/assets/{dist-CVxhbI2E.js → dist-B9NInrVZ.js} +1 -1
  235. package/server/public/assets/{ganttDiagram-6RSMTGT7-Bgj4A7kp.js → ganttDiagram-6RSMTGT7-Bxp0gV14.js} +1 -1
  236. package/server/public/assets/{highlighted-body-OFNGDK62-DNPK7_cm.js → highlighted-body-OFNGDK62-CzoRTVlC.js} +1 -1
  237. package/server/public/assets/index-Cml-kHo6.css +1 -0
  238. package/server/public/assets/{index-DEpY-D1O.js → index-CvN8cEgs.js} +216 -215
  239. package/server/public/assets/{linear-BB0jQT16.js → linear-CFEEl3ND.js} +1 -1
  240. package/server/public/assets/mermaid-GHXKKRXX-CpV7nCBM.js +1 -0
  241. package/server/public/assets/{pieDiagram-4H26LBE5-DeGIzzpZ.js → pieDiagram-4H26LBE5-BeR8R0cr.js} +1 -1
  242. package/server/public/assets/{prod-XBLvikex.js → prod-CYjzjCrn.js} +4 -4
  243. package/server/public/assets/{quadrantDiagram-W4KKPZXB-BV9SLeWz.js → quadrantDiagram-W4KKPZXB-BpcTkFuW.js} +1 -1
  244. package/server/public/assets/{sankeyDiagram-5OEKKPKP-Dwja0gj8.js → sankeyDiagram-5OEKKPKP-Bx2ETEV5.js} +1 -1
  245. package/server/public/assets/{xychartDiagram-2RQKCTM6-DCB4qvfw.js → xychartDiagram-2RQKCTM6-BKgEAFaj.js} +1 -1
  246. package/server/public/index.html +2 -2
  247. package/server/{pull-requests-BonZ4WVG.js → pull-requests-B-KrUph5.js} +3 -3
  248. package/server/{pull-requests-DNcJUVWA.js → pull-requests-DK5k92B4.js} +1 -1
  249. package/server/{queries-DCX27GRr.js → queries-DVpl1vsU.js} +1212 -193
  250. package/server/{rally-Cxe7lKYX.js → rally-DbE561hD.js} +3 -3
  251. package/server/rally-O_st_X7n.js +3 -0
  252. package/server/{rally-api-CzkKenoi.js → rally-api-CZLeEd2C.js} +2 -2
  253. package/server/{rally-api-Cp50exEi.js → rally-api-DaHtn5QN.js} +1 -1
  254. package/server/{rally-client-Bu3Cekkw.js → rally-client-C-MAl8ur.js} +1 -1
  255. package/server/{rally-client-CyBBEDHu.js → rally-client-Ch3zRsBX.js} +5 -5
  256. package/server/{reap-terminal-sessions-CtAhr6L0.js → reap-terminal-sessions-C1n0ALRb.js} +2 -2
  257. package/server/{reap-terminal-sessions-DvFqQUnq.js → reap-terminal-sessions-DegFS2p1.js} +2 -2
  258. package/server/{rebuild-stack-hCQtprWC.js → rebuild-stack-C9Li44A3.js} +20 -10
  259. package/server/{rebuild-stack-BKYpIPDL.js → rebuild-stack-qC0jCNm6.js} +2 -2
  260. package/server/{reconstruct-cache-CF2avArx.js → reconstruct-cache-BHyiAg02.js} +7 -7
  261. package/server/record-aVzu-LGm.js +3 -0
  262. package/server/record-update-CZh46a2f.js +617 -0
  263. package/server/{record-update-DhI7eySG.js → record-update-DtdJK2Iw.js} +1 -1
  264. package/server/recovery-trip-CSNWSLDn.js +77 -0
  265. package/server/recovery-trip-_16hFKv4.js +3 -0
  266. package/server/{release-engine-_eO3VFth.js → release-engine-Be5MX5GP.js} +5 -5
  267. package/server/{release-set-vxgZwwZV.js → release-set-DJv_O6PS.js} +3 -3
  268. package/server/{remote-BienmcrZ.js → remote-BMM3uH2J.js} +3 -3
  269. package/server/{remote-CVPCc7Vy.js → remote-C0xVTHA5.js} +3 -3
  270. package/server/{remote-agents-kwsEZvXu.js → remote-agents-BIIoc5pD.js} +1 -1
  271. package/server/{remote-agents-kxraOCGT.js → remote-agents-EUiZ26bj.js} +7 -7
  272. package/server/{remote-completion-BtmZ42aP.js → remote-completion-BS4tJUn8.js} +13 -13
  273. package/server/resolver-BvHd6RE4.js +163 -0
  274. package/server/resume-9thEqAQR.js +3 -0
  275. package/server/{review-agent-CIRr0yYt.js → review-agent-BHGaBoBu.js} +29 -29
  276. package/server/{review-agent-UpAM4DmT.js → review-agent-CD3RQ-tc.js} +1 -1
  277. package/server/{review-artifacts-BCODM9ww.js → review-artifacts-DyhajWso.js} +6 -6
  278. package/server/{review-context-BBsNrDri.js → review-context-B-dlsPnx.js} +9 -9
  279. package/server/{review-convoy-liveness-l06_LYCt.js → review-convoy-liveness-D7M-s_nS.js} +2 -2
  280. package/server/{review-status-CacDM78F.js → review-status-B6wYcOtP.js} +1 -1
  281. package/server/{review-status-CwhA9wmd.js → review-status-CKLk5aZ-.js} +306 -59
  282. package/server/{review-status-emit-BPJwYcRy.js → review-status-emit-CJ7UmEVU.js} +3 -3
  283. package/server/{review-status-enrichment-DvyZAbGR.js → review-status-enrichment-DJRgGX7-.js} +3 -3
  284. package/server/review-status-limits-4EJDCGHO.js +7 -0
  285. package/server/{review-status-source-DWnFE0b6.js → review-status-source-7nU3Z2wL.js} +1 -1
  286. package/server/{review-status-source-B70ekARK.js → review-status-source-BsDYGfyv.js} +1 -1
  287. package/server/{review-status-sync-B0IS6Beh.js → review-status-sync-BLssMTEW.js} +1 -1
  288. package/server/{review-status-sync-h2CJX6ju.js → review-status-sync-BxBeHRde.js} +35 -11
  289. package/server/{review-verdict-feedback-yrrmgps_.js → review-verdict-feedback-5jWuzgpc.js} +22 -10
  290. package/server/{review-verdict-feedback-qRohbFG2.js → review-verdict-feedback-HRY9P4bN.js} +1 -1
  291. package/server/{rollup-CUoav0Op.js → rollup-BGIrCEkU.js} +79 -44
  292. package/server/rollup-CZB4UL9q.js +3 -0
  293. package/server/{scanner-ChURu_b-.js → scanner-DydjXPrz.js} +16 -9
  294. package/server/search-DdtIjAiu.js +395 -0
  295. package/server/{sequence-io-D9ITDxzq.js → sequence-io-Fw-cLyDs.js} +4 -4
  296. package/server/{sequencer-agent-m7gmaakW.js → sequencer-agent-BcpGMt5x.js} +15 -10
  297. package/server/server.js +1258 -438
  298. package/server/{service-BzFG0Us_.js → service-BFFkGsG4.js} +58 -58
  299. package/server/{session-fork-KBq4HIHF.js → session-fork-D0V-3e5P.js} +2 -2
  300. package/server/{session-history-C_EMhIIF.js → session-history-Bta5l9jY.js} +5 -5
  301. package/server/{settings-DejgzzLs.js → settings-Ce8B1daF.js} +2 -2
  302. package/server/{settings-BLbcDqUp.js → settings-E3FnEIUx.js} +3 -3
  303. package/server/settings-eOOJpxi_.js +2 -0
  304. package/server/{shadow-engineering-D8R9I8Yl.js → shadow-engineering-Mt9nJO4i.js} +3 -3
  305. package/server/{shadow-state-C0Af4clN.js → shadow-state-Bzj_AZCV.js} +1 -1
  306. package/server/{shadow-state-fzIqIMDD.js → shadow-state-DrkhoVSx.js} +2 -2
  307. package/server/{shadow-utils-Ugca_9ND.js → shadow-utils-H1GfqP06.js} +2 -2
  308. package/server/{ship-log-VAv-lHrF.js → ship-log-CFUIo4PR.js} +1 -1
  309. package/server/{smart-compaction-BcYY_Suf.js → smart-compaction-DSTq-Wua.js} +1 -1
  310. package/server/{smart-compaction-B2Xu5XEb.js → smart-compaction-Hzp3KCJX.js} +7 -7
  311. package/server/{spawn-planning-session-Dsv-350T.js → spawn-planning-session-C0uSA2SL.js} +2 -2
  312. package/server/{spawn-planning-session-DhCoBPct.js → spawn-planning-session-DN4son31.js} +23 -21
  313. package/server/{specialist-completion-z6v3ZqJE.js → specialist-completion-Cf6tpIh1.js} +1 -1
  314. package/server/{specialist-context-CrA5azkJ.js → specialist-context-DEUEkjIQ.js} +5 -5
  315. package/server/{specialist-handoff-logger-CmpZYJMB.js → specialist-handoff-logger-D_LmQDj3.js} +2 -2
  316. package/server/{specialist-logs-BorrIu0x.js → specialist-logs-7Ynue0R7.js} +3 -3
  317. package/server/{specialists-ZdrifiKx.js → specialists-CQwBEGlD.js} +1 -1
  318. package/server/{specialists-2yLmqph9.js → specialists-DAjPgYs_.js} +504 -238
  319. package/server/{specialists-Dfx9_Wzb.js → specialists-Hr6iW9fU.js} +18 -18
  320. package/server/{specialists-CH6ah6D-.js → specialists-MOoeB4A8.js} +1 -1
  321. package/server/specs-Dl88cbKY.js +3 -0
  322. package/server/{src-B948bGVR.js → src-BYdwL_n-.js} +668 -64
  323. package/server/{src-Dm_NV7f6.js → src-DQnkPN2i.js} +3 -3
  324. package/server/{src-B2e5rGu2.js → src-DhfDV0o4.js} +6 -6
  325. package/server/{stack-health-Bf2WdG4E.js → stack-health-D_iKwNRg.js} +107 -16
  326. package/server/stack-health-deVSdDwn.js +3 -0
  327. package/server/{stale-task-claims-D1Ll8fI5.js → stale-task-claims-BYJGqhLI.js} +5 -5
  328. package/server/{staleness-CuED1Psm.js → staleness-CopBDKnA.js} +1 -1
  329. package/server/{staleness-45qZ_a60.js → staleness-D8WeMUHd.js} +1 -1
  330. package/server/{state-home-B4EWfIxF.js → state-home-DjN8qduI.js} +24 -3
  331. package/server/{state-mapping-BEONzr8P.js → state-mapping-DlM7OYRW.js} +1 -1
  332. package/server/{state-migrate-Cd8BH33U.js → state-migrate-a2p1gtD7.js} +4 -4
  333. package/server/state-mirror-Cv_XgvT5.js +121 -0
  334. package/server/{stuck-remediation-ChcooZuk.js → stuck-remediation-CXJX_kki.js} +1 -1
  335. package/server/{stuck-remediation-DmY5UJLg.js → stuck-remediation-CbCRSz1v.js} +31 -732
  336. package/server/{substrate-bug-weights-service-BvTWrFUz.js → substrate-bug-weights-service-DxpopNd9.js} +3 -3
  337. package/server/{summary-fork--Jr8duYh.js → summary-fork-B61fjRJn.js} +2 -2
  338. package/server/{summary-fork-Ct514_Jl.js → summary-fork-B9pszUJN.js} +91 -10
  339. package/server/supervisor/{injection-budget-B3UyEONL.js → injection-budget-Ar7hgyJq.js} +1 -1
  340. package/server/supervisor/pty-supervisor.js +12 -3
  341. package/server/supervisor/{pty-token-CWRffcCa.js → pty-token-CXCFU0Z8.js} +1 -1
  342. package/server/{supervisor-B7BHGcNA.js → supervisor-BvnxbuuF.js} +6 -4
  343. package/server/supervisor-C69kpqvd.js +2 -0
  344. package/server/{swarm-readiness-MNE5O8hn.js → swarm-readiness-vTw1kqGa.js} +3 -3
  345. package/server/{system-prerequisites-Cin9ZgDx.js → system-prerequisites-LLzTEqsK.js} +3 -3
  346. package/server/{teardown-workspace-CvBpvc85.js → teardown-workspace-CqKKVJr1.js} +15 -15
  347. package/server/{test-agent-queue-DmSIqays.js → test-agent-queue-CWMq7oyG.js} +8 -7
  348. package/server/{test-verdict-BieVDAV1.js → test-verdict-NdtgRBuA.js} +1 -1
  349. package/server/{test-verdict-Cy2jJGTe.js → test-verdict-diIWE6hz.js} +15 -3
  350. package/server/{tldr-daemon-Ca0eovh3.js → tldr-daemon-B1Jhrtc8.js} +1 -1
  351. package/server/{tldr-daemon-IOssGwg7.js → tldr-daemon-Bpls1CJB.js} +2 -2
  352. package/server/{tmux-CfDHob9M.js → tmux-CImZaX4q.js} +10 -16
  353. package/server/tmux-Cjpx8L8u.js +4 -0
  354. package/server/{token-B10VFNOD.js → token-Bgpjo3tE.js} +2 -2
  355. package/server/token-util-BsjFll-k.js +3 -0
  356. package/server/{token-util-CZ8WPtdk.js → token-util-BymbpkJp.js} +1 -1
  357. package/server/{tracker-config-CHbrjg6m.js → tracker-config-4DaKVTfc.js} +2 -2
  358. package/server/{tracker-utils-DZZq_C0R.js → tracker-utils-BDeAXC-q.js} +2 -2
  359. package/server/{traefik-connect-GHomyBaD.js → traefik-connect-CC5FyxYj.js} +1 -1
  360. package/server/{tunnel-Dz7y434T.js → tunnel-CDWkeceJ.js} +1 -1
  361. package/server/{tunnel-Bdyb-sNq.js → tunnel-CPf5M-Pc.js} +3 -3
  362. package/server/{typed-errors-Bn_2WRU7.js → typed-errors-9K7Dq_Vn.js} +1 -1
  363. package/server/{typed-errors-BR_RmPS_.js → typed-errors-DrS5fb5z.js} +1 -1
  364. package/server/{types-D2ETIB8T.js → types-DzlUKiuf.js} +4 -3
  365. package/server/{types-Dh6RI5Vj.js → types-kI9ik8XO.js} +1 -1
  366. package/server/{uat-promote-verification-DyvQXvIn.js → uat-promote-verification-c_pxoxEc.js} +5 -5
  367. package/server/{uat-train-Dv0Bxer7.js → uat-train-CWGxBdJO.js} +0 -0
  368. package/server/{uat-train-diX_7shd.js → uat-train-CfCYd2ve.js} +1 -1
  369. package/server/{validate-606KcYZC.js → validate-f3ItVCfm.js} +3 -3
  370. package/server/{validation-Cf7aaV5A.js → validation-5G_wQtea.js} +1 -1
  371. package/server/{validation-CnrDul1x.js → validation-7tSiCM82.js} +4 -4
  372. package/server/{verification-artifact-GOaj8u2s.js → verification-artifact-9h9dH8uX.js} +1 -1
  373. package/server/{verification-artifact-D4b-bio9.js → verification-artifact-C_4WJnf6.js} +1 -1
  374. package/server/{verification-runner-DiPaUP-C.js → verification-runner-BV5F6wrA.js} +1 -1
  375. package/server/{verification-runner-B5MVxDvU.js → verification-runner-D58KmBhK.js} +18 -38
  376. package/server/{vtt-parser-CMU5EZ5R.js → vtt-parser-2iT9OHa9.js} +1 -1
  377. package/server/{work-agent-prompt-Csb3fbVR.js → work-agent-prompt-D03s4DD1.js} +9 -9
  378. package/server/{workflows-D87ajwV6.js → workflows-BMBwLYPV.js} +281 -98
  379. package/server/workflows-BOmWGpIh.js +2 -0
  380. package/server/{workspace-iD8oULqu.js → workspace-BgflNCH0.js} +3 -3
  381. package/server/{workspace-AIOM7n00.js → workspace-Cn9ywfSW.js} +1 -1
  382. package/server/{workspace-anchor-drift-19cJ1bH5.js → workspace-anchor-drift-C8Fy3shi.js} +1 -1
  383. package/server/{workspace-anchor-drift-C3mK5wNI.js → workspace-anchor-drift-CMiNncwq.js} +5 -8
  384. package/server/{workspace-config-CJ7RqQiP.js → workspace-config-aUc2nIz6.js} +1 -1
  385. package/server/{workspace-manager-CXfrw4rR.js → workspace-manager-Bem7ZBs9.js} +521 -292
  386. package/server/workspace-manager-C0CpNh3t.js +3 -0
  387. package/server/{workspace-metadata-BuMRco5P.js → workspace-metadata-C5iSlPRo.js} +1 -1
  388. package/server/{workspace-metadata-eHSj_NsP.js → workspace-metadata-UKmTYmDQ.js} +2 -2
  389. package/server/{workspaces-DbtMX2TM.js → workspaces-DqxgwDZ8.js} +143 -113
  390. package/sync-sources/hooks/notification-hook +12 -1
  391. package/sync-sources/hooks/pan-hook-lib.sh +226 -0
  392. package/sync-sources/hooks/session-start-hook +31 -4
  393. package/sync-sources/hooks/work-agent-stop-hook +23 -1
  394. package/sync-sources/skills/pan-memory/SKILL.md +19 -3
  395. package/sync-sources/skills/pan-projects/SKILL.md +9 -0
  396. package/sync-sources/skills/pan-restart/SKILL.md +26 -7
  397. package/sync-sources/skills/pan-workspace/SKILL.md +77 -0
  398. package/server/activity-logger-CMthG6Vd.js +0 -3
  399. package/server/agent-state-DyZJia9f.js +0 -3
  400. package/server/agents-Dnn4XgdB.js +0 -3
  401. package/server/archive-planning-BHCd_eL5.js +0 -2
  402. package/server/cli-D6mRfUE6.js +0 -3
  403. package/server/deacon-swarm-BkKR7SXu.js +0 -2
  404. package/server/delivery-C2M73sBg.js +0 -3
  405. package/server/dist-qcf9gAP0.js +0 -3
  406. package/server/event-store-5UKzh9Jf.js +0 -3
  407. package/server/forge-D647IMNa.js +0 -3
  408. package/server/fts-db-wROfFfje.js +0 -146
  409. package/server/hume-DtWN8oV5.js +0 -3
  410. package/server/inspect-agent-CPqXI81t.js +0 -2
  411. package/server/merge-ops-7QqziXAh.js +0 -2
  412. package/server/merge-rebase-B4pgzvQJ.js +0 -2
  413. package/server/node_modules/brace-expansion/.tap/coverage/8b906b8c-e21f-40b5-8c0d-214d8c2682c5.json +0 -757
  414. package/server/node_modules/brace-expansion/.tap/processinfo/8b906b8c-e21f-40b5-8c0d-214d8c2682c5.json +0 -719
  415. package/server/node_modules/brace-expansion/ADVISORY-CVE-2026-14257.md +0 -107
  416. package/server/node_modules/brace-expansion/dist/commonjs/index.d.ts +0 -8
  417. package/server/node_modules/brace-expansion/dist/commonjs/index.d.ts.map +0 -1
  418. package/server/node_modules/brace-expansion/dist/commonjs/index.js +0 -263
  419. package/server/node_modules/brace-expansion/dist/commonjs/index.js.map +0 -1
  420. package/server/node_modules/brace-expansion/dist/commonjs/package.json +0 -3
  421. package/server/node_modules/brace-expansion/dist/esm/index.d.ts +0 -8
  422. package/server/node_modules/brace-expansion/dist/esm/index.d.ts.map +0 -1
  423. package/server/node_modules/brace-expansion/dist/esm/index.js +0 -259
  424. package/server/node_modules/brace-expansion/dist/esm/index.js.map +0 -1
  425. package/server/node_modules/brace-expansion/dist/esm/package.json +0 -3
  426. package/server/project-repos-BgW4lcIa.js +0 -3
  427. package/server/projects-_n3Zui6K.js +0 -3
  428. package/server/providers-BI1mOBQ4.js +0 -3
  429. package/server/public/assets/index-Ddkcz3WT.css +0 -1
  430. package/server/public/assets/mermaid-GHXKKRXX-BzPfaQJ1.js +0 -1
  431. package/server/rally-x6ztTQo4.js +0 -3
  432. package/server/record-BTwWhtBb.js +0 -3
  433. package/server/record-update-DaOKS7Wb.js +0 -277
  434. package/server/recovery-trip-D-wM9EfB.js +0 -44
  435. package/server/resume-DXIIfJNk.js +0 -3
  436. package/server/rollup-DxCjJaAM.js +0 -3
  437. package/server/settings-9jSGHBPY.js +0 -2
  438. package/server/specs-DKV3jIEs.js +0 -3
  439. package/server/stack-health-CoWAhA99.js +0 -3
  440. package/server/supervisor-CyR_mW5B.js +0 -2
  441. package/server/tmux-Ctk6RV5l.js +0 -3
  442. package/server/token-util-CrfQ2FKf.js +0 -3
  443. package/server/workflows-DN6NyVGd.js +0 -2
  444. package/server/workspace-manager-B38rFWA1.js +0 -3
@@ -1,66 +1,69 @@
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, 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
- 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-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";
2
+ import { Cn as resolveProjectPath, Hr as AGENTS_DIR, Ot as getMainDivergence, Q as readIssueRecordSync, Sn as resolveProjectFromIssueSync, St as init_auto_commit, Tt as reconcileStatePlaneDrift, Vr as init_errors, Zr as OVERDECK_HOME, b as DEFAULT_CONFIG$1, cn as init_projects, dn as listProjects, f as loadConfigSync, fn as listProjectsSync, hi as init_paths, kt as init_state_plane, mn as loadProjectsConfigSync, nn as getProjectSync, q as init_record, s as init_load, x as init_defaults, yi as sessionFilePath } from "./config-yaml-BSCqwmX0.js";
3
+ import { n as init_build_info, t as getBuildInfo } from "./build-info-CJg813Hm.js";
4
+ import { n as getDashboardIdentity, t as recordDeaconNudge } from "./deacon-nudge-log-BND_97Wo.js";
5
+ import { f as init_config, m as loadConfigSync$1, p as loadConfig$1 } from "./config-DnLJATZk.js";
6
+ import { a as emitActivityEntrySync, c as init_activity_logger, o as emitActivityTtsSync, r as emitActivityEntryOnce } from "./activity-logger-Co5qljIj.js";
7
+ import { a as recordLockPath, i as readOwner, n as init_fs_lock } from "./fs-lock-D_GeJtXl.js";
8
+ import { i as updateIssueRecord, r as init_record_update } from "./record-update-CZh46a2f.js";
9
+ import { C as init_tmux, E as killSession, F as querySessionSync, H as sessionExistsSync, M as listSessions, R as sendKeys, T as isPaneDead, V as sessionExists, j as listSessionNames, k as listPaneValues, r as capturePane, z as sendKeysAsync } from "./tmux-CImZaX4q.js";
10
+ import { a as init_event_store, i as initEventStore } from "./event-store-D_AR-Y78.js";
11
+ import { D as projectLegacySystemHealthSummary, t as init_src } from "./src-BYdwL_n-.js";
12
+ import { B as reviewGatesPassedSync, C as setReviewStatusSync, G as findWorkspaceVerdictConflicts, H as findBlockingFindings, J as readJournalStatusSync, K as init_review_status_record_sync, R as init_review_dispatch_decision, U as init_review_findings, W as drainWorkspaceVerdictFallback, Y as readWorkspaceVerdictFallback, d as getReviewStatusSync, h as loadReviewStatuses, p as init_review_status, z as needsReviewDispatch } from "./review-status-CKLk5aZ-.js";
13
+ import { n as logAgentLifecycleSync, r as logDeaconEventSync, t as init_persistent_logger } from "./persistent-logger-s8cbpFNV.js";
14
+ import { c as listAllAgentsSync, d as isTerminalIssueStage, o as init_agents, u as getIssueStageSync } from "./agents-Dls7tfJH.js";
15
+ import { At as countRunningAgents, Dt as init_termination, Er as markAgentRunningState, Ft as init_concurrency, Ir as setAgentPausedSync, It as releaseAdvancingSlot, Lr as setAgentYieldedSync, Mr as resetAgentFailureCount, Mt as describeRunningAgents, Nr as saveAgentState, Ot as stopAgent, Pr as saveAgentStateSync, Pt as getConcurrencyLimits, Rt as resetPatrolDispatchBudget, Ut as init_memory_verdict_cache, Vt as workResumeSlotsAvailable, Wt as setCachedMemoryVerdict, Yt as deliverInitialPromptWithRetry, _ as init_linux, a as listRunningAgentsSync, b as init_agents$1, br as getAgentStateSync, c as getRuntimeCensus, ci as init_codex_auth, ct as init_context_overflow, dt as init_messaging, ei as getAgentRuntimeState, er as buildResumeContinueMessage, ft as messageAgent, g as LINUX_MEMORY_PRESSURE_DEFAULTS, gr as getAgentDir, h as init_collector, i as listRunningAgents, kr as recordAgentFailure, li as paneShowsCodexAuthBurn, m as createHostHealthCollector, mr as clearYieldForResumeSync, n as init_queries, ni as init_runtime_state, nn as init_transcript_landing, oi as applyCodexAuthBurnFlag, pr as clearAgentTroubledSync, r as listAgentStates, ri as saveAgentRuntimeState, s as descendantPidsForSession, st as resumeAgent, ti as getAgentRuntimeStateSync, tn as captureTranscriptUserRecordSnapshot, u as init_runtime_census, ut as isContextOverflowTail, v as DARWIN_MEMORY_PRESSURE_DEFAULTS, vr as getAgentState, xr as init_agent_state, y as init_darwin, zt as tryReserveAdvancingSlot } from "./queries-DVpl1vsU.js";
16
+ import { o as getRuntimeSnapshot, s as init_agent_runtime_mirror } from "./session-history-Bta5l9jY.js";
17
+ import { n as resolveGitHubIssueSync, t as init_tracker_utils } from "./tracker-utils-BDeAXC-q.js";
18
+ import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-AvXePaQT.js";
19
+ import { c as init_review_status_sync, l as markWorkspaceStuck } from "./review-status-sync-BxBeHRde.js";
20
+ import { i as readReviewStatusMap, n as init_review_status_source, t as classifyAdvancingSessionLifecycle } from "./review-status-source-7nU3Z2wL.js";
21
+ import { d as PENDING_PROMOTION_FILENAME, f as WORKSPACE_RUNTIME_DIRNAME, m as init_types } from "./types-DzlUKiuf.js";
22
+ import { _ as markMerged, c as init_merge_sync, f as listActiveAutoMerges, m as listProblemAutoMerges, t as cancelPending } from "./merge-sync-BEdfsQV4.js";
23
+ import { i as init_merge_set, r as getMergeSetSync } from "./merge-set-DsLjjLEV.js";
24
+ import { C as init_specs, S as findSpecByIssue, f as readPlanSync, h as readWorkspacePlanSync, o as findWorkspaceDraftPlanSync, s as init_io } from "./io-mxOWMZ7I.js";
25
+ 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-DVf6pKyv.js";
26
+ import { f as DockerStatsCollector, p as init_docker_stats } from "./stack-health-D_iKwNRg.js";
27
+ import { l as init_dag, o as getDispatchableItems } from "./dag-BYiFMqpU.js";
28
+ import { a as loadCloisterConfigSync, i as loadCloisterConfig, r as init_config$1 } from "./config-DvM8jtQK.js";
29
+ import { a as findRecreatedLegacyStatePaths, o as init_state_home } from "./state-home-DjN8qduI.js";
30
+ import { M as withConcurrencyLimit, j as init_concurrency$1 } from "./github-app-D2QuvZ3j.js";
31
+ import { n as __filename, r as init_esm_shims } from "./esm-shims-Bzy4ZzNU.js";
32
+ import { i as init_staleness, r as computeBuildStaleness } from "./staleness-D8WeMUHd.js";
33
+ import { a as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-CbCRSz1v.js";
34
+ import { a as pidsWithCwdUnder, i as sweepAutoCloseOutCache, n as pruneTerminalStoppedAgents, r as getAutoCloseOutCanonicalState } from "./agent-gc-BmYeT6eH.js";
35
+ import { n as init_issue_closed, r as isIssueClosed } from "./issue-closed-Bj_bCv_0.js";
36
+ import { n as getForgeAdapter, r as init_forge } from "./forge-c8LeC-tw.js";
37
+ import { a as observeForgeMergeState, i as init_merge_completeness } from "./merge-completeness-C1FevcDT.js";
38
+ import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-DdsBdtNL.js";
39
+ import { n as resolveIssueFeedbackTarget, r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-DoRCR3L-.js";
40
+ 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-D7M-s_nS.js";
41
+ import { J as parseReviewerSessionName, U as getTmuxSessionName, g as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-Hr6iW9fU.js";
42
+ import { a as inferBranchFromWorkspace, i as findWorkspacePath } from "./archive-planning-Cq7cyinS.js";
43
+ import { n as init_merge_verification, r as shouldSkipDispatchAsMerged } from "./merge-verification-DN1Ov9bU.js";
44
+ 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-5jWuzgpc.js";
45
+ import { _ as init_label_reconciler, a as gatherProjectLensSignals, s as init_pipeline_membership_gather, v as reconcilePipelineLabelsPatrol } from "./pipeline-membership-gather-CtJ_7aGf.js";
46
+ import { n as init_pipeline_membership, r as resolvePipelineMembership } from "./pipeline-membership-Dqv6_0ig.js";
47
+ import { i as init_conflict_gate, o as probeBranchConflictPaths } from "./conflict-gate-WfVqgalf.js";
48
+ import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-CC5FyxYj.js";
49
+ import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-rqrl4TMs.js";
50
+ import { i as recordRecoveryFailure, n as findRecoveryTrip, r as init_recovery_trip } from "./recovery-trip-CSNWSLDn.js";
51
+ import { n as isExplicitNoResumeRequest, t as init_no_resume_mode } from "./no-resume-mode-DUR7Hi98.js";
52
+ import { r as init_in_flight_guard, t as createInFlightGuard } from "./in-flight-guard-CG2Eo-rr.js";
53
+ import { r as reconcileClosedIssueAgents } from "./closed-issue-reaper-C5Zn4GRS.js";
54
+ import { t as recordDeadEndNeedsYou } from "./dead-end-trip-DSF23CLX.js";
55
+ import { a as spawnWorkAgentThroughAgentsEndpoint, i as reconcileOrphanProposedSpecs, o as triggerRebuildAndStart } from "./orphan-proposed-reconciler-DfqHZftT.js";
56
+ import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-CJ1ygW0p.js";
57
+ import { a as recordUnsignaledTestEscalation, i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-diIWE6hz.js";
55
58
  import { createRequire } from "node:module";
56
- import { join } from "node:path";
59
+ import { dirname, join } from "node:path";
57
60
  import { Effect } from "effect";
58
61
  import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "fs";
59
62
  import { basename as basename$1, dirname as dirname$1, join as join$1 } from "path";
60
63
  import { cpus, loadavg } from "os";
61
64
  import { freemem as freemem$1, homedir as homedir$1, platform as platform$1, totalmem as totalmem$1 } from "node:os";
62
65
  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";
63
- import { readFile, readdir, stat as stat$1 } from "node:fs/promises";
66
+ import { mkdir, readFile, readdir, rename, rm, stat as stat$1, writeFile } from "node:fs/promises";
64
67
  import { readFile as readFile$1, readdir as readdir$1, writeFile as writeFile$1 } from "fs/promises";
65
68
  import { exec, execFile, execFileSync, spawn } from "node:child_process";
66
69
  import { promisify } from "node:util";
@@ -70,11 +73,12 @@ import { layer } from "@effect/platform-node/NodeServices";
70
73
  //#region ../../lib/agents/health.ts
71
74
  init_paths();
72
75
  init_errors();
73
- init_activity_logger();
74
76
  init_projects();
75
77
  init_state_plane();
76
78
  init_auto_commit();
77
79
  init_record();
80
+ init_config();
81
+ init_activity_logger();
78
82
  init_tmux();
79
83
  init_src();
80
84
  init_persistent_logger();
@@ -21785,7 +21789,6 @@ new ((/* @__PURE__ */ __commonJSMin(((exports, module) => {
21785
21789
  * stopSmeeProcess();
21786
21790
  * isSmeeProcessRunning();
21787
21791
  */
21788
- init_config();
21789
21792
  const SMEE_URL_PATH = join(homedir$1(), ".overdeck", "github-app", "smee-url");
21790
21793
  const SMEE_PID_PATH = join(homedir$1(), ".overdeck", "github-app", "smee.pid");
21791
21794
  const SMEE_LOG_PATH = join(homedir$1(), ".overdeck", "logs", "smee.log");
@@ -23158,9 +23161,13 @@ async function assessMemoryPressure() {
23158
23161
  }
23159
23162
  //#endregion
23160
23163
  //#region ../../lib/cloister/agent-grace.ts
23164
+ init_fs_lock();
23161
23165
  init_record_update();
23162
23166
  init_internal_token();
23167
+ init_types();
23163
23168
  init_review_findings();
23169
+ init_specs();
23170
+ init_io();
23164
23171
  init_control_settings();
23165
23172
  const WORK_LAUNCHER_GRACE_MS = 12e4;
23166
23173
  function isStartingWithinGrace(state, now = Date.now(), graceMs = WORK_LAUNCHER_GRACE_MS) {
@@ -23211,7 +23218,7 @@ async function checkInspectAgentTimeouts(now = /* @__PURE__ */ new Date()) {
23211
23218
  console.warn(`[deacon] Failed to kill inspect session ${sessionName}: ${msg}`);
23212
23219
  });
23213
23220
  try {
23214
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
23221
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
23215
23222
  await messageAgent(`agent-${issueId.toLowerCase()}`, verdict, "deacon:inspect-watchdog");
23216
23223
  } catch (err) {
23217
23224
  const msg = err instanceof Error ? err.message : String(err);
@@ -23405,7 +23412,7 @@ async function maybeProactivelyCompactContext(sessionName, now) {
23405
23412
  if (!agentState?.workspace || !sessionId || !agentState.model) return null;
23406
23413
  let usage = null;
23407
23414
  try {
23408
- const { computeContextUsage } = await import("./conversation-service-CDnQ3ayN.js");
23415
+ const { computeContextUsage } = await import("./conversation-service-DnUyIiLb.js");
23409
23416
  usage = await computeContextUsage(sessionFilePath(agentState.workspace, sessionId), agentState.model);
23410
23417
  } catch {
23411
23418
  return null;
@@ -23504,9 +23511,9 @@ async function checkApiErrorAgents() {
23504
23511
  }
23505
23512
  if (!tmuxOutput.includes("❯")) continue;
23506
23513
  try {
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");
23514
+ const { maybeContinueCompactedAgent } = await import("./compaction-continuation-DZD9ukSE.js");
23515
+ const { findLastCompactBoundary } = await import("./conversation-service-DnUyIiLb.js");
23516
+ const { deliverAgentMessage } = await import("./delivery-CsbQdZkS.js");
23510
23517
  const continued = await maybeContinueCompactedAgent({
23511
23518
  agentId: sessionName,
23512
23519
  tmuxOutput,
@@ -23557,13 +23564,13 @@ async function checkApiErrorAgents() {
23557
23564
  const st = getAgentStateSync(sessionName);
23558
23565
  const sid = st?.sessionId ?? runtimeState?.claudeSessionId;
23559
23566
  if (st?.workspace && sid && st.model) {
23560
- const { computeContextUsage } = await import("./conversation-service-CDnQ3ayN.js");
23567
+ const { computeContextUsage } = await import("./conversation-service-DnUyIiLb.js");
23561
23568
  const usage = await computeContextUsage(sessionFilePath(st.workspace, sid), st.model);
23562
23569
  if (usage && usage.percentUsed < 85) recoveredPct = usage.percentUsed;
23563
23570
  }
23564
23571
  } catch {}
23565
23572
  if (recoveredPct !== null) {
23566
- const { clearWorkspaceStuck } = await import("./review-status-sync-B0IS6Beh.js");
23573
+ const { clearWorkspaceStuck } = await import("./review-status-sync-BLssMTEW.js");
23567
23574
  clearWorkspaceStuck(issueId);
23568
23575
  stuckOverflowNativeRecoveryState.delete(sessionName);
23569
23576
  actions.push(`Context overflow recovery: cleared stuck flag for ${sessionName} (context back to ${Math.round(recoveredPct)}%)`);
@@ -23579,7 +23586,7 @@ async function checkApiErrorAgents() {
23579
23586
  rec.attempts += 1;
23580
23587
  rec.lastAttempt = now;
23581
23588
  stuckOverflowNativeRecoveryState.set(sessionName, rec);
23582
- const { resumeAgent } = await import("./agents-Dnn4XgdB.js");
23589
+ const { resumeAgent } = await import("./agents-IPSa5kzn.js");
23583
23590
  const recovered = await resumeAgent(sessionName, void 0, { compact: true });
23584
23591
  if (recovered.success) {
23585
23592
  stuckOverflowNativeRecoveryState.delete(sessionName);
@@ -23627,7 +23634,7 @@ async function checkApiErrorAgents() {
23627
23634
  }
23628
23635
  const compactAttempts = (ov?.compactAttempts ?? 0) + 1;
23629
23636
  if (issueId !== null) {
23630
- const { resumeAgent } = await import("./agents-Dnn4XgdB.js");
23637
+ const { resumeAgent } = await import("./agents-IPSa5kzn.js");
23631
23638
  const resumeResult = await resumeAgent(sessionName, void 0, { compact: true });
23632
23639
  contextOverflowRecoveryState.set(sessionName, {
23633
23640
  lastAttempt: now,
@@ -23746,7 +23753,7 @@ function isStuckMergingState(status, now) {
23746
23753
  }
23747
23754
  async function readSpecStatus(projectPath, issueId) {
23748
23755
  try {
23749
- const { findSpecByIssue } = await import("./specs-DKV3jIEs.js");
23756
+ const { findSpecByIssue } = await import("./specs-Dl88cbKY.js");
23750
23757
  return (await Effect.runPromise(findSpecByIssue(projectPath, issueId)))?.status;
23751
23758
  } catch {
23752
23759
  return;
@@ -23828,7 +23835,7 @@ async function reconcileStuckMergingStates() {
23828
23835
  reviewGatesPassed: reviewGatesPassedSync,
23829
23836
  setReviewStatus: setReviewStatusSync,
23830
23837
  enqueuePostMerge: async (issueId, projectPath, branch) => {
23831
- const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-3u_rA4R0.js");
23838
+ const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DmSOkeNp.js");
23832
23839
  return enqueuePostMergeLifecycle(issueId, projectPath, branch);
23833
23840
  },
23834
23841
  warn: (message) => console.warn(message)
@@ -24073,7 +24080,7 @@ async function reconcileStaleMergeStatus() {
24073
24080
  ].includes(status.mergeStatus ?? "") || ["merging", "failed"].includes(mergeSet?.status ?? "");
24074
24081
  let specStatus;
24075
24082
  try {
24076
- const { findSpecByIssue } = await import("./specs-DKV3jIEs.js");
24083
+ const { findSpecByIssue } = await import("./specs-Dl88cbKY.js");
24077
24084
  const spec = await Effect.runPromise(findSpecByIssue(project.projectPath, issueId));
24078
24085
  specStatus = spec?.status;
24079
24086
  if (spec && (spec.status === "completed" || spec.status === "cancelled")) {
@@ -24083,7 +24090,7 @@ async function reconcileStaleMergeStatus() {
24083
24090
  } catch {}
24084
24091
  const branch = `feature/${issueId.toLowerCase()}`;
24085
24092
  if (postMergeIncomplete) {
24086
- const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-3u_rA4R0.js");
24093
+ const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DmSOkeNp.js");
24087
24094
  const action = enqueuePostMergeLifecycle(issueId, project.projectPath, branch);
24088
24095
  if (action) actions.push(action);
24089
24096
  continue;
@@ -24095,7 +24102,7 @@ async function reconcileStaleMergeStatus() {
24095
24102
  } catch {}
24096
24103
  if (!isMerged) isMerged = (await observeGitHubBranchMerge(issueId, branch, project.projectPath)).merged;
24097
24104
  if (shouldObserveForge && mergeRelevant) try {
24098
- const observation = await (await import("./merge-completeness-CghMbyX7.js")).observeForgeMergeState(issueId);
24105
+ const observation = await (await import("./merge-completeness-BfRwFjRx.js")).observeForgeMergeState(issueId);
24099
24106
  const blocker = observation.repos.find((repo) => repo.state === "unverifiable");
24100
24107
  if (blocker) {
24101
24108
  console.warn(`[deacon] ${issueId}: forge merge state is unverifiable — ${blocker.reason}`);
@@ -24122,7 +24129,7 @@ async function reconcileStaleMergeStatus() {
24122
24129
  const msg = `Reconciled stale mergeStatus for ${issueId} — branch ${branch} is merged to main`;
24123
24130
  actions.push(msg);
24124
24131
  console.log(`[deacon] ${msg}`);
24125
- const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-3u_rA4R0.js");
24132
+ const { enqueuePostMergeLifecycle } = await import("./post-merge-lifecycle-worker-DmSOkeNp.js");
24126
24133
  const action = enqueuePostMergeLifecycle(issueId, project.projectPath, branch);
24127
24134
  if (action) actions.push(action);
24128
24135
  }
@@ -24145,7 +24152,7 @@ const falseMergedReset = /* @__PURE__ */ new Set();
24145
24152
  async function reconcileFalseMerged() {
24146
24153
  const actions = [];
24147
24154
  try {
24148
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DIE8BkHI.js");
24155
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CpQSDlv8.js");
24149
24156
  if (!isGitHubAppConfigured()) return actions;
24150
24157
  const statuses = loadReviewStatuses();
24151
24158
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -24190,7 +24197,7 @@ const CLOSED_PR_RECONCILE_COOLDOWN_MS = 600 * 1e3;
24190
24197
  async function reconcileClosedPrReadyForMerge() {
24191
24198
  const actions = [];
24192
24199
  try {
24193
- const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-DIE8BkHI.js");
24200
+ const { getPullRequestState, isGitHubAppConfigured } = await import("./github-app-CpQSDlv8.js");
24194
24201
  if (!isGitHubAppConfigured()) return actions;
24195
24202
  const statuses = loadReviewStatuses();
24196
24203
  const now = Date.now();
@@ -24262,7 +24269,7 @@ const STALE_MERGE_BLOCKER_COOLDOWN_MS = 120 * 1e3;
24262
24269
  async function reconcileStaleMergeBlockers() {
24263
24270
  const actions = [];
24264
24271
  try {
24265
- const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-BSTlwCtF.js");
24272
+ const { resolveConflictGate, buildRealConflictGateDeps } = await import("./conflict-gate-DXa_L28t.js");
24266
24273
  const statuses = loadReviewStatuses();
24267
24274
  const now = Date.now();
24268
24275
  const deps = buildRealConflictGateDeps();
@@ -24405,7 +24412,7 @@ async function checkFailedMergeRetry() {
24405
24412
  if (ciEntry.count === 5) {
24406
24413
  console.log(`[deacon] CI check failure for ${issueId} — retries exhausted, notifying work agent`);
24407
24414
  const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
24408
- const { writeFeedbackFile } = await import("./feedback-writer-CY91ckuw.js");
24415
+ const { writeFeedbackFile } = await import("./feedback-writer-CTSuA6lw.js");
24409
24416
  const ciFileResult = await Effect.runPromise(writeFeedbackFile({
24410
24417
  issueId,
24411
24418
  specialist: "merge-agent",
@@ -24437,7 +24444,7 @@ async function checkFailedMergeRetry() {
24437
24444
  ciRetryMap.set(issueId, ciEntry);
24438
24445
  console.log(`[deacon] CI check failure for ${issueId} — notifying agent to re-submit (attempt ${ciEntry.count}/5)`);
24439
24446
  const ciNotes = status.mergeNotes || "CI checks are failing on the PR";
24440
- const { writeFeedbackFile } = await import("./feedback-writer-CY91ckuw.js");
24447
+ const { writeFeedbackFile } = await import("./feedback-writer-CTSuA6lw.js");
24441
24448
  const ciFileResult2 = await Effect.runPromise(writeFeedbackFile({
24442
24449
  issueId,
24443
24450
  specialist: "merge-agent",
@@ -24465,7 +24472,7 @@ async function checkFailedMergeRetry() {
24465
24472
  const lastNudge = timeoutNudgeCooldowns.get(issueIdForFb);
24466
24473
  if (!lastNudge || now - lastNudge >= TIMEOUT_NUDGE_COOLDOWN_MS) {
24467
24474
  const timeoutNotes = status.mergeNotes;
24468
- const { writeFeedbackFile } = await import("./feedback-writer-CY91ckuw.js");
24475
+ const { writeFeedbackFile } = await import("./feedback-writer-CTSuA6lw.js");
24469
24476
  await Effect.runPromise(writeFeedbackFile({
24470
24477
  issueId: issueIdForFb,
24471
24478
  specialist: "merge-agent",
@@ -24570,7 +24577,7 @@ async function autoCloseOut(now = /* @__PURE__ */ new Date()) {
24570
24577
  } } : {}
24571
24578
  };
24572
24579
  try {
24573
- const { closeOut } = await import("./workflows-DN6NyVGd.js");
24580
+ const { closeOut } = await import("./workflows-BOmWGpIh.js");
24574
24581
  const result = await Effect.runPromise(closeOut(ctx));
24575
24582
  if (!result.success) {
24576
24583
  const failed = result.steps.find((step) => !step.success && !step.skipped);
@@ -24864,6 +24871,8 @@ init_concurrency();
24864
24871
  const BLOCKED_REVIEW_MISSING_ANCHOR_LOG_INTERVAL_MS = 3600 * 1e3;
24865
24872
  const blockedReviewMissingAnchorLogs = /* @__PURE__ */ new Map();
24866
24873
  const blockedReviewDriftObservations = /* @__PURE__ */ new Map();
24874
+ const lastResetAnchors = /* @__PURE__ */ new Map();
24875
+ const resetLoopEscalated = /* @__PURE__ */ new Set();
24867
24876
  function uniformReviewerVerdictAnchor(status) {
24868
24877
  const verdicts = Object.values(status.reviewerVerdicts ?? {});
24869
24878
  if (verdicts.length === 0) return void 0;
@@ -24883,12 +24892,14 @@ async function checkPostReviewCommits() {
24883
24892
  const actions = [];
24884
24893
  try {
24885
24894
  const statuses = loadReviewStatuses();
24886
- const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
24895
+ const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
24887
24896
  for (const [issueId, status] of Object.entries(statuses)) {
24888
24897
  const isBlocked = status.reviewStatus === "blocked";
24889
24898
  if (!isBlocked) blockedReviewDriftObservations.delete(issueId);
24890
24899
  if (status.mergeStatus === "merged") {
24891
24900
  blockedReviewDriftObservations.delete(issueId);
24901
+ lastResetAnchors.delete(issueId);
24902
+ resetLoopEscalated.delete(issueId);
24892
24903
  continue;
24893
24904
  }
24894
24905
  if (!isBlocked && status.reviewStatus !== "passed" && !status.readyForMerge) continue;
@@ -24913,8 +24924,8 @@ async function checkPostReviewCommits() {
24913
24924
  if (!project) continue;
24914
24925
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
24915
24926
  if (!existsSync(workspacePath)) continue;
24916
- const { formatAnchorShort, rehydrateHeadAnchor } = await import("./git-utils-CedsVume.js");
24917
- const { evaluateWorkspaceAnchorDrift } = await import("./workspace-anchor-drift-19cJ1bH5.js");
24927
+ const { formatAnchorShort, rehydrateHeadAnchor } = await import("./git-utils-C31x1lpE.js");
24928
+ const { evaluateWorkspaceAnchorDrift } = await import("./workspace-anchor-drift-C8Fy3shi.js");
24918
24929
  const verdict = await evaluateWorkspaceAnchorDrift(issueId, workspacePath, rehydrateHeadAnchor(reviewedAnchor));
24919
24930
  if (verdict.kind === "unreadable" || verdict.kind === "current") {
24920
24931
  blockedReviewDriftObservations.delete(issueId);
@@ -24927,6 +24938,16 @@ async function checkPostReviewCommits() {
24927
24938
  continue;
24928
24939
  }
24929
24940
  const currentHead = verdict.currentAnchor;
24941
+ if (lastResetAnchors.get(issueId) === currentHead) {
24942
+ if (!resetLoopEscalated.has(issueId)) {
24943
+ resetLoopEscalated.add(issueId);
24944
+ const message = `${issueId} — review reset suppressed: drift against ${formatAnchorShort(currentHead)} already caused a reset and the workspace has not moved since. This indicates an anchor-producer disagreement, not new commits; review will not re-dispatch until the workspace head actually changes.`;
24945
+ logDeaconEventSync(`checkPostReviewCommits: ${message}`);
24946
+ const { recordDeadEndNeedsYou } = await import("./dead-end-trip-zKlS4v6f.js");
24947
+ await recordDeadEndNeedsYou(issueId, "review-reset-loop", currentHead, message);
24948
+ }
24949
+ continue;
24950
+ }
24930
24951
  if (isBlocked) {
24931
24952
  const priorObservation = blockedReviewDriftObservations.get(issueId);
24932
24953
  if (!priorObservation || priorObservation.reviewedAnchor !== reviewedAnchor || priorObservation.currentAnchor !== currentHead) {
@@ -24939,6 +24960,8 @@ async function checkPostReviewCommits() {
24939
24960
  blockedReviewDriftObservations.delete(issueId);
24940
24961
  }
24941
24962
  console.log(`[deacon] Post-review commit detected for ${issueId}: was ${formatAnchorShort(reviewedAnchor)}, now ${formatAnchorShort(currentHead)} — resetting review`);
24963
+ lastResetAnchors.set(issueId, currentHead);
24964
+ resetLoopEscalated.delete(issueId);
24942
24965
  if (isBlocked) setReviewStatusSync(issueId, {
24943
24966
  reviewStatus: "pending",
24944
24967
  readyForMerge: false,
@@ -24964,7 +24987,7 @@ async function checkPostReviewCommits() {
24964
24987
  actions.push(`Deferred post-review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
24965
24988
  logDeaconEventSync(`checkPostReviewCommits: deferred review for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
24966
24989
  } else if (freshStatus?.reviewStatus === "pending") {
24967
- const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
24990
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
24968
24991
  const branch = `feature/${issueId.toLowerCase()}`;
24969
24992
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
24970
24993
  issueId,
@@ -25345,7 +25368,7 @@ function reviewConvoyLiveness(issueId) {
25345
25368
  */
25346
25369
  async function recoverUnhealthyTestStack(issueId, workspacePath) {
25347
25370
  const key = issueId.toUpperCase();
25348
- const { getWorkspaceStackHealth } = await import("./stack-health-CoWAhA99.js");
25371
+ const { getWorkspaceStackHealth } = await import("./stack-health-deVSdDwn.js");
25349
25372
  const health = await Effect.runPromise(getWorkspaceStackHealth(issueId, { workspacePath }));
25350
25373
  if (health.healthy) {
25351
25374
  testStackRebuildState.delete(key);
@@ -25377,7 +25400,7 @@ async function recoverUnhealthyTestStack(issueId, workspacePath) {
25377
25400
  record.attempts += 1;
25378
25401
  testStackRebuildState.set(key, record);
25379
25402
  console.log(`[deacon] Test stack for ${key} unhealthy (${health.reasons.join("; ")}) — rebuilding (attempt ${record.attempts}/${TEST_STACK_REBUILD_MAX_ATTEMPTS})`);
25380
- const { rebuildWorkspaceStack } = await import("./rebuild-stack-BKYpIPDL.js");
25403
+ const { rebuildWorkspaceStack } = await import("./rebuild-stack-qC0jCNm6.js");
25381
25404
  const result = await Effect.runPromise(rebuildWorkspaceStack(issueId, { onProgress: (m) => console.log(`[deacon] ${key} stack rebuild: ${m}`) }));
25382
25405
  if (!result.success) {
25383
25406
  console.warn(`[deacon] Test stack rebuild failed for ${key}: ${result.error}`);
@@ -25545,7 +25568,7 @@ async function handleReviewCoordinatorDied(issueId, _sessionName, _reason) {
25545
25568
  return actions;
25546
25569
  }
25547
25570
  try {
25548
- const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
25571
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
25549
25572
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
25550
25573
  issueId,
25551
25574
  workspace,
@@ -25620,7 +25643,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25620
25643
  const issueLower = issueId.toLowerCase();
25621
25644
  const workspace = getAgentStateSync(`agent-${issueLower}`)?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
25622
25645
  if (workspace) try {
25623
- if ((options.readWorkspaceHead ? await options.readWorkspaceHead(workspace) : await (await import("./git-utils-CedsVume.js")).snapshotWorkspaceHeadsPromise(issueId, workspace)) === status.lastVerifiedCommit) {
25646
+ if ((options.readWorkspaceHead ? await options.readWorkspaceHead(workspace) : await (await import("./git-utils-C31x1lpE.js")).snapshotWorkspaceHeadsPromise(issueId, workspace)) === status.lastVerifiedCommit) {
25624
25647
  setReviewStatusSync(issueId, {
25625
25648
  reviewStatus: "pending",
25626
25649
  reviewNotes: void 0
@@ -25642,7 +25665,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25642
25665
  if (project) {
25643
25666
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
25644
25667
  if (existsSync(workspacePath)) {
25645
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CedsVume.js");
25668
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-C31x1lpE.js");
25646
25669
  reviewUpdate["reviewedAtCommit"] = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);
25647
25670
  }
25648
25671
  }
@@ -25697,7 +25720,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25697
25720
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
25698
25721
  if (workspace && resolved && !tryReserveAdvancingSlot() && !await tryYieldForAdvancingDispatch("review", issueId)) actions.push(`Deferred review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
25699
25722
  else if (workspace && resolved) try {
25700
- const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
25723
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
25701
25724
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
25702
25725
  issueId,
25703
25726
  workspace,
@@ -25722,8 +25745,8 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
25722
25745
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
25723
25746
  if (workspace && resolved) {
25724
25747
  const branch = `feature/${issueLower}`;
25725
- const { spawnRun } = await import("./agents-Dnn4XgdB.js");
25726
- const { buildTestRolePrompt } = await import("./test-agent-queue-DmSIqays.js");
25748
+ const { spawnRun } = await import("./agents-IPSa5kzn.js");
25749
+ const { buildTestRolePrompt } = await import("./test-agent-queue-CWMq7oyG.js");
25727
25750
  const stackRecovery = await recoverUnhealthyTestStack(issueId, workspace);
25728
25751
  if (stackRecovery === "cooldown" || stackRecovery === "exhausted") {
25729
25752
  setReviewStatusSync(issueId, { testStatus: "dispatch_failed" });
@@ -25862,7 +25885,7 @@ async function recoverStalledReviewConvoys(getCanonicalState = getAutoCloseOutCa
25862
25885
  record.lastAttempt = now;
25863
25886
  record.attempts += 1;
25864
25887
  stalledReviewConvoyRecoveryState.set(key, record);
25865
- const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
25888
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
25866
25889
  try {
25867
25890
  const result = await Effect.runPromise(spawnReviewRoleForIssue({
25868
25891
  issueId,
@@ -25933,7 +25956,7 @@ async function checkMissingReviewStatuses() {
25933
25956
  continue;
25934
25957
  }
25935
25958
  try {
25936
- const { spawnReviewRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
25959
+ const { spawnReviewRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
25937
25960
  await Effect.runPromise(spawnReviewRoleForIssue({
25938
25961
  issueId,
25939
25962
  workspace,
@@ -25987,7 +26010,7 @@ async function checkStuckReviewing() {
25987
26010
  const actions = [];
25988
26011
  const REVIEW_STUCK_THRESHOLD_MS = 1800 * 1e3;
25989
26012
  try {
25990
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-CacDM78F.js");
26013
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
25991
26014
  const statuses = loadReviewStatuses();
25992
26015
  const now = Date.now();
25993
26016
  const activeReviewIssues = /* @__PURE__ */ new Set();
@@ -26146,7 +26169,7 @@ async function reconcileUnappliedReviewVerdicts() {
26146
26169
  let currentHead;
26147
26170
  let reviewedHead;
26148
26171
  try {
26149
- const { rehydrateHeadAnchor, snapshotWorkspaceHeadsPromise } = await import("./git-utils-CedsVume.js");
26172
+ const { rehydrateHeadAnchor, snapshotWorkspaceHeadsPromise } = await import("./git-utils-C31x1lpE.js");
26150
26173
  currentHead = await snapshotWorkspaceHeadsPromise(issueId, wsPath);
26151
26174
  const persistedAnchor = reviewAnchorFromContext(latestContext);
26152
26175
  reviewedHead = persistedAnchor ? rehydrateHeadAnchor(persistedAnchor) : void 0;
@@ -26170,7 +26193,7 @@ async function reconcileUnappliedReviewVerdicts() {
26170
26193
  const notes = parsed.topBlocker || `See ${latestReport.filename}`;
26171
26194
  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
26195
  try {
26173
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
26196
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
26174
26197
  await messageAgent(reviewSession, nudge);
26175
26198
  pendingVerdictNudges.set(latestDir, now);
26176
26199
  const action = `Nudged ${reviewSession} to apply pending ${parsed.verdict} verdict from ${latestReport.filename}`;
@@ -26283,7 +26306,7 @@ async function checkCompletedButUnsignaledReviews() {
26283
26306
  const cmd = buildReviewCompletionCommand(issueId, verdict, topBlocker || `See ${latestReport.filename}`, basename$1(latestDir));
26284
26307
  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.`;
26285
26308
  try {
26286
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
26309
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
26287
26310
  await messageAgent(reviewSession, nudge);
26288
26311
  unsignaledReviewNudges.set(latestDir, now);
26289
26312
  actions.push(`Nudged ${reviewSession} to signal ${verdict} (${latestReport.filename} written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
@@ -26393,7 +26416,7 @@ async function respawnIdleReviewer(state, agentId) {
26393
26416
  return false;
26394
26417
  }
26395
26418
  try {
26396
- const { spawnReviewSubRoleForIssue } = await import("./review-agent-UpAM4DmT.js");
26419
+ const { spawnReviewSubRoleForIssue } = await import("./review-agent-CD3RQ-tc.js");
26397
26420
  const contextManifestPath = join$1(dirname$1(outputPath), "context.json");
26398
26421
  const result = await Effect.runPromise(spawnReviewSubRoleForIssue({
26399
26422
  issueId: state.issueId,
@@ -26479,7 +26502,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
26479
26502
  writeFileSync(join$1(reviewDir, "synthesis.md"), synthesis.body);
26480
26503
  let fallbackHead;
26481
26504
  try {
26482
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CedsVume.js");
26505
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-C31x1lpE.js");
26483
26506
  fallbackHead = await snapshotWorkspaceHeadsPromise(state.issueId, state.workspace);
26484
26507
  } catch {}
26485
26508
  const anchoredVerdicts = Object.fromEntries(Object.entries(synthesis.reviewerVerdicts).map(([subRole, v]) => [subRole, {
@@ -26518,7 +26541,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
26518
26541
  "Read the four reports, write synthesis.md, then signal review status exactly as roles/review.md instructs."
26519
26542
  ].join("\n");
26520
26543
  try {
26521
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
26544
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
26522
26545
  await messageAgent(state.id, message);
26523
26546
  reviewReportsPresentNudges.set(nudgeKey, now);
26524
26547
  const action = `Nudged ${state.id} to synthesize from ${REVIEW_SUB_ROLES.length} reviewer reports`;
@@ -26604,7 +26627,7 @@ async function monitorReviewConvoySignals() {
26604
26627
  if (!signal) continue;
26605
26628
  const message = signal === "ready" ? `REVIEWER_READY ${state.reviewSubRole} ${outputPath}` : signal === "timeout" ? `REVIEWER_TIMEOUT ${state.reviewSubRole} ${reason}` : `REVIEWER_FAILED ${state.reviewSubRole} ${reason}`;
26606
26629
  try {
26607
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
26630
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
26608
26631
  await messageAgent(state.reviewSynthesisAgentId, message);
26609
26632
  state.reviewMonitorSignaled = signal;
26610
26633
  saveAgentStateSync(state);
@@ -26612,7 +26635,7 @@ async function monitorReviewConvoySignals() {
26612
26635
  actions.push(action);
26613
26636
  logDeaconEventSync(`monitorReviewConvoySignals: ${action}`);
26614
26637
  if (signal === "ready") try {
26615
- const { notifyPipelineSync } = await import("./pipeline-notifier-BmwrVKsO.js");
26638
+ const { notifyPipelineSync } = await import("./pipeline-notifier-CO9rxJgB.js");
26616
26639
  notifyPipelineSync({
26617
26640
  type: "reviewer_completed",
26618
26641
  issueId: state.issueId,
@@ -26620,7 +26643,7 @@ async function monitorReviewConvoySignals() {
26620
26643
  });
26621
26644
  } catch {}
26622
26645
  else if (signal === "timeout") try {
26623
- const { notifyPipelineSync } = await import("./pipeline-notifier-BmwrVKsO.js");
26646
+ const { notifyPipelineSync } = await import("./pipeline-notifier-CO9rxJgB.js");
26624
26647
  notifyPipelineSync({
26625
26648
  type: "reviewer_timed_out",
26626
26649
  issueId: state.issueId,
@@ -26720,7 +26743,7 @@ const FORK_CACHE_CHECK_DELAY_MS = 180 * 1e3;
26720
26743
  async function checkStalledReviewDiscovery() {
26721
26744
  const actions = [];
26722
26745
  try {
26723
- const { listAgentStates } = await import("./agents-Dnn4XgdB.js");
26746
+ const { listAgentStates } = await import("./agents-IPSa5kzn.js");
26724
26747
  const states = listAgentStates();
26725
26748
  const now = Date.now();
26726
26749
  for (const state of states) {
@@ -26729,7 +26752,7 @@ async function checkStalledReviewDiscovery() {
26729
26752
  const aged = Number.isFinite(startedMs) && now - startedMs > 48e4;
26730
26753
  const dead = !await Effect.runPromise(sessionExists(state.id)).catch(() => false) || await Effect.runPromise(isPaneDead(state.id)).catch(() => true);
26731
26754
  if (!aged && !dead) continue;
26732
- const { handleReviewDiscoveryReady } = await import("./review-agent-UpAM4DmT.js");
26755
+ const { handleReviewDiscoveryReady } = await import("./review-agent-CD3RQ-tc.js");
26733
26756
  const result = await handleReviewDiscoveryReady(state.issueId, { source: dead ? "deacon-backstop (parent dead)" : "deacon-backstop (discovery timeout)" });
26734
26757
  actions.push(result.message);
26735
26758
  logDeaconEventSync(`checkStalledReviewDiscovery: ${result.message}`);
@@ -26752,8 +26775,8 @@ async function checkStalledReviewDiscovery() {
26752
26775
  async function checkStalledReviewParents() {
26753
26776
  const actions = [];
26754
26777
  try {
26755
- const { listAgentStates, markAgentStoppedState } = await import("./agents-Dnn4XgdB.js");
26756
- const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-UpAM4DmT.js");
26778
+ const { listAgentStates, markAgentStoppedState } = await import("./agents-IPSa5kzn.js");
26779
+ const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-CD3RQ-tc.js");
26757
26780
  const states = listAgentStates();
26758
26781
  const now = Date.now();
26759
26782
  for (const state of states) {
@@ -26777,7 +26800,7 @@ async function checkStalledReviewParents() {
26777
26800
  actions.push(message);
26778
26801
  logDeaconEventSync(message);
26779
26802
  try {
26780
- const { emitActivityEntrySync } = await import("./activity-logger-CMthG6Vd.js");
26803
+ const { emitActivityEntrySync } = await import("./activity-logger-K7FYGF_z.js");
26781
26804
  emitActivityEntrySync({
26782
26805
  source: "review",
26783
26806
  level: "warn",
@@ -26802,9 +26825,9 @@ async function checkStalledReviewParents() {
26802
26825
  async function checkReviewForkCacheMisses() {
26803
26826
  const actions = [];
26804
26827
  try {
26805
- const { listAgentStates, saveAgentState } = await import("./agents-Dnn4XgdB.js");
26806
- const { readEventsSync } = await import("./events-ChEFB7Jp.js");
26807
- const { emitActivityEntrySync } = await import("./activity-logger-CMthG6Vd.js");
26828
+ const { listAgentStates, saveAgentState } = await import("./agents-IPSa5kzn.js");
26829
+ const { readEventsSync } = await import("./events-CCkFWa7X.js");
26830
+ const { emitActivityEntrySync } = await import("./activity-logger-K7FYGF_z.js");
26808
26831
  const states = listAgentStates();
26809
26832
  const now = Date.now();
26810
26833
  for (const parent of states) {
@@ -27273,7 +27296,6 @@ function startBootReconciliation(options = {}) {
27273
27296
  }
27274
27297
  //#endregion
27275
27298
  //#region ../../lib/agents/pinned-launch.ts
27276
- init_io();
27277
27299
  init_dag();
27278
27300
  init_agent_state();
27279
27301
  function parseFlagValue(content, flag) {
@@ -27666,7 +27688,7 @@ async function nudgeStalledResumeWorkAgents() {
27666
27688
  const message = buildStalledResumePrompt(state);
27667
27689
  if (!message) continue;
27668
27690
  try {
27669
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
27691
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
27670
27692
  await messageAgent(agentId, message);
27671
27693
  recordCooldown(agentId, ".last-stalled-resume-nudge");
27672
27694
  const action = `Re-sent stalled resume prompt to ${agentId} (${state.issueId})`;
@@ -27780,7 +27802,7 @@ async function nudgeIdleWorkAgentsWithOpenBeads() {
27780
27802
  "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."
27781
27803
  ].join("\n");
27782
27804
  try {
27783
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
27805
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
27784
27806
  await messageAgent(agentId, message);
27785
27807
  writeFileSync(join$1(getAgentDir(agentId), ".last-bead-nudge"), String(Date.now()), "utf-8");
27786
27808
  const action = `Nudged idle ${agentId} (${state.issueId}) — ${openTasks.length} ready task(s)`;
@@ -28210,6 +28232,290 @@ function shouldRunRecoveryJanitor(janitor, patrolCycle) {
28210
28232
  return patrolCycle % (janitor === "feedback" ? 5 : 60) === 0;
28211
28233
  }
28212
28234
  //#endregion
28235
+ //#region ../../lib/cloister/pending-promotion-reconciler.ts
28236
+ init_activity_logger();
28237
+ init_internal_token();
28238
+ init_projects();
28239
+ init_io();
28240
+ init_issue_closed();
28241
+ const MARKER_GRACE_MS = 12e4;
28242
+ const MARKERLESS_SPEC_GRACE_MS = 5 * 6e4;
28243
+ const NEEDS_YOU_ATTEMPTS = 5;
28244
+ function normalizeIssueId(value) {
28245
+ return typeof value === "string" && /^[A-Za-z]+-\d+$/.test(value.trim()) ? value.trim().toUpperCase() : null;
28246
+ }
28247
+ function issueIdFromWorkspaceName(name) {
28248
+ const match = name.match(/^feature-([a-z]+-\d+)$/i);
28249
+ return match ? match[1].toUpperCase() : null;
28250
+ }
28251
+ function parseDate(value) {
28252
+ if (typeof value !== "string") return null;
28253
+ const parsed = Date.parse(value);
28254
+ return Number.isFinite(parsed) ? parsed : null;
28255
+ }
28256
+ function parseMarker(value, expectedIssueId) {
28257
+ if (!value || typeof value !== "object") return null;
28258
+ const marker = value;
28259
+ const issueId = normalizeIssueId(marker["issueId"]);
28260
+ if (marker["version"] !== "1" || issueId !== expectedIssueId) return null;
28261
+ if (typeof marker["canonicalFilename"] !== "string" || marker["canonicalFilename"].length === 0) return null;
28262
+ if (parseDate(marker["finalizedAt"]) === null) return null;
28263
+ return {
28264
+ version: "1",
28265
+ issueId,
28266
+ canonicalFilename: marker["canonicalFilename"],
28267
+ noPrd: marker["noPrd"] === true,
28268
+ autoSpawnRequested: marker["autoSpawnRequested"] === true,
28269
+ finalizedAt: marker["finalizedAt"],
28270
+ lastError: typeof marker["lastError"] === "string" ? marker["lastError"] : "complete-planning failed",
28271
+ lastAttemptAt: typeof marker["lastAttemptAt"] === "string" ? marker["lastAttemptAt"] : marker["finalizedAt"],
28272
+ patrolAttempts: Number.isInteger(marker["patrolAttempts"]) && Number(marker["patrolAttempts"]) >= 0 ? Number(marker["patrolAttempts"]) : 0
28273
+ };
28274
+ }
28275
+ async function readMarker(path, issueId) {
28276
+ try {
28277
+ return parseMarker(JSON.parse(await readFile(path, "utf-8")), issueId);
28278
+ } catch {
28279
+ return null;
28280
+ }
28281
+ }
28282
+ async function loadProjects(projects) {
28283
+ if (projects) return projects;
28284
+ return Effect.runPromise(listProjects().pipe(Effect.catch(() => Effect.succeed([]))));
28285
+ }
28286
+ async function defaultFindPromotedSpec(projectPath, issueId) {
28287
+ return Effect.runPromise(findSpecByIssue(projectPath, issueId).pipe(Effect.catch(() => Effect.succeed(null))));
28288
+ }
28289
+ function internalDashboardOrigin() {
28290
+ const port = Number.parseInt(process.env["API_PORT"] ?? process.env["PORT"] ?? "3011", 10);
28291
+ return process.env["OVERDECK_INTERNAL_DASHBOARD_URL"] ?? `http://127.0.0.1:${port}`;
28292
+ }
28293
+ function logDiagnostic(kind, info = {}) {
28294
+ console.debug(`[pending-promotion-reconciler] ${kind}`, info);
28295
+ }
28296
+ function markerPathForWorkspace(workspacePath) {
28297
+ return join(workspacePath, WORKSPACE_RUNTIME_DIRNAME, PENDING_PROMOTION_FILENAME);
28298
+ }
28299
+ function canonicalFilenameFromSpec(doc) {
28300
+ const filename = doc.plan.metadata?.canonicalFilename;
28301
+ return typeof filename === "string" && filename.length > 0 ? filename : null;
28302
+ }
28303
+ async function writeMarker(path, marker) {
28304
+ await mkdir(dirname(path), { recursive: true });
28305
+ const tmp = `${path}.tmp`;
28306
+ await writeFile(tmp, JSON.stringify(marker, null, 2) + "\n", "utf-8");
28307
+ await rename(tmp, path);
28308
+ }
28309
+ const defaultMarkerIo = {
28310
+ read: readMarker,
28311
+ write: writeMarker,
28312
+ remove: (path) => rm(path, { force: true })
28313
+ };
28314
+ async function findPendingPromotionCandidates(options = {}) {
28315
+ const projects = await loadProjects(options.projects);
28316
+ const now = (options.clock ?? (() => /* @__PURE__ */ new Date()))().getTime();
28317
+ const findPromotedSpec = options.findPromotedSpec ?? defaultFindPromotedSpec;
28318
+ const markerIo = options.markerIo ?? defaultMarkerIo;
28319
+ const candidates = [];
28320
+ for (const { key, config } of projects) {
28321
+ const workspacesDir = join(config.path, "workspaces");
28322
+ const workspaces = await readdir(workspacesDir, { withFileTypes: true }).catch(() => []);
28323
+ for (const workspace of workspaces) {
28324
+ if (!workspace.isDirectory() || workspace.name.endsWith("-strike")) continue;
28325
+ const issueId = issueIdFromWorkspaceName(workspace.name);
28326
+ if (!issueId) continue;
28327
+ const workspacePath = join(workspacesDir, workspace.name);
28328
+ const markerPath = markerPathForWorkspace(workspacePath);
28329
+ const marker = await markerIo.read(markerPath, issueId);
28330
+ const specPath = findWorkspaceDraftPlanSync(workspacePath);
28331
+ if (!specPath) continue;
28332
+ let spec;
28333
+ try {
28334
+ spec = readPlanSync(specPath);
28335
+ } catch {
28336
+ logDiagnostic("candidate-skipped", {
28337
+ issueId,
28338
+ reason: "spec-unreadable"
28339
+ });
28340
+ continue;
28341
+ }
28342
+ if (spec.plan.status !== "proposed" || normalizeIssueId(spec.plan.id) !== issueId) continue;
28343
+ if (marker) {
28344
+ candidates.push({
28345
+ projectKey: key,
28346
+ projectName: config.name,
28347
+ projectPath: config.path,
28348
+ workspacePath,
28349
+ issueId,
28350
+ specPath,
28351
+ markerPath,
28352
+ marker,
28353
+ canonicalFilename: marker.canonicalFilename,
28354
+ noPrd: marker.noPrd,
28355
+ autoSpawnRequested: marker.autoSpawnRequested,
28356
+ finalizedAt: marker.finalizedAt,
28357
+ patrolAttempts: marker.patrolAttempts
28358
+ });
28359
+ continue;
28360
+ }
28361
+ if (spec.plan.metadata?.promotionIntent === "manual") continue;
28362
+ const specInfo = await stat$1(specPath).catch(() => null);
28363
+ if (!specInfo || now - specInfo.mtimeMs < MARKERLESS_SPEC_GRACE_MS) continue;
28364
+ if (await findPromotedSpec(config.path, issueId)) continue;
28365
+ const canonicalFilename = canonicalFilenameFromSpec(spec);
28366
+ if (!canonicalFilename) {
28367
+ logDiagnostic("candidate-skipped", {
28368
+ issueId,
28369
+ reason: "canonical-filename-missing"
28370
+ });
28371
+ continue;
28372
+ }
28373
+ candidates.push({
28374
+ projectKey: key,
28375
+ projectName: config.name,
28376
+ projectPath: config.path,
28377
+ workspacePath,
28378
+ issueId,
28379
+ specPath,
28380
+ markerPath,
28381
+ marker: null,
28382
+ canonicalFilename,
28383
+ noPrd: false,
28384
+ autoSpawnRequested: false,
28385
+ finalizedAt: specInfo.mtime.toISOString(),
28386
+ patrolAttempts: 0
28387
+ });
28388
+ }
28389
+ }
28390
+ return candidates;
28391
+ }
28392
+ function parseResponseBody(text) {
28393
+ try {
28394
+ const parsed = JSON.parse(text);
28395
+ return parsed && typeof parsed === "object" ? parsed : {};
28396
+ } catch {
28397
+ return {};
28398
+ }
28399
+ }
28400
+ function responseError(status, body, text) {
28401
+ if (typeof body["error"] === "string") return body["error"];
28402
+ if (typeof body["message"] === "string") return body["message"];
28403
+ return text.slice(0, 200) || `complete-planning returned HTTP ${status}`;
28404
+ }
28405
+ function responseStillPending(status, body) {
28406
+ return status === 202 || body["inFlight"] === true || typeof body["skipped"] === "string";
28407
+ }
28408
+ async function reconcilePendingPromotions(options = {}) {
28409
+ const now = (options.clock ?? (() => /* @__PURE__ */ new Date()))();
28410
+ const nowMs = now.getTime();
28411
+ const fetchImpl = options.fetch ?? fetch;
28412
+ const dashboardOrigin = options.dashboardOrigin ?? internalDashboardOrigin();
28413
+ const internalToken = (options.getInternalToken ?? getInternalTokenSync)();
28414
+ const findPromotedSpec = options.findPromotedSpec ?? defaultFindPromotedSpec;
28415
+ const isClosed = options.isClosed ?? ((issueId) => isIssueClosed(issueId));
28416
+ const recordNeedsYou = options.recordNeedsYou ?? recordDeadEndNeedsYou;
28417
+ const emitActivity = options.emitActivity ?? emitActivityEntrySync;
28418
+ const markerIo = options.markerIo ?? defaultMarkerIo;
28419
+ const candidates = await findPendingPromotionCandidates({
28420
+ ...options,
28421
+ clock: () => now,
28422
+ findPromotedSpec,
28423
+ markerIo
28424
+ });
28425
+ const actions = [];
28426
+ for (const candidate of candidates) {
28427
+ if (await isClosed(candidate.issueId)) {
28428
+ logDiagnostic("candidate-skipped", {
28429
+ issueId: candidate.issueId,
28430
+ reason: "closed"
28431
+ });
28432
+ continue;
28433
+ }
28434
+ if (await findPromotedSpec(candidate.projectPath, candidate.issueId)) {
28435
+ await markerIo.remove(candidate.markerPath);
28436
+ actions.push(`Cleared resolved pending-promotion marker for ${candidate.issueId}`);
28437
+ continue;
28438
+ }
28439
+ const finalizedAtMs = parseDate(candidate.finalizedAt);
28440
+ if (finalizedAtMs === null || nowMs - finalizedAtMs < MARKER_GRACE_MS) {
28441
+ logDiagnostic("candidate-skipped", {
28442
+ issueId: candidate.issueId,
28443
+ reason: "grace-window"
28444
+ });
28445
+ continue;
28446
+ }
28447
+ let response = null;
28448
+ let body = {};
28449
+ let error = null;
28450
+ try {
28451
+ response = await fetchImpl(new URL(`/api/issues/${encodeURIComponent(candidate.issueId)}/complete-planning`, dashboardOrigin), {
28452
+ method: "POST",
28453
+ headers: {
28454
+ "content-type": "application/json",
28455
+ origin: dashboardOrigin,
28456
+ ...internalToken ? { [INTERNAL_TOKEN_HEADER]: internalToken } : {}
28457
+ },
28458
+ body: JSON.stringify({
28459
+ noPrd: candidate.noPrd,
28460
+ startedBy: "pending-promotion-reconciler"
28461
+ })
28462
+ });
28463
+ const text = await response.text();
28464
+ body = parseResponseBody(text);
28465
+ if (responseStillPending(response.status, body)) {
28466
+ logDiagnostic("promotion-deferred", {
28467
+ issueId: candidate.issueId,
28468
+ status: response.status,
28469
+ body
28470
+ });
28471
+ continue;
28472
+ }
28473
+ if (response.status !== 200 || !response.ok || body["success"] === false || body["ok"] === false) error = responseError(response.status, body, text);
28474
+ } catch (cause) {
28475
+ error = cause instanceof Error ? cause.message : String(cause);
28476
+ }
28477
+ if (!error && response?.status === 200) {
28478
+ await markerIo.remove(candidate.markerPath);
28479
+ const action = `Recovered pending planning promotion for ${candidate.issueId}`;
28480
+ actions.push(action);
28481
+ emitActivity({
28482
+ source: "cloister",
28483
+ level: "success",
28484
+ issueId: candidate.issueId,
28485
+ message: `${candidate.issueId} planning promotion recovered automatically`,
28486
+ details: JSON.stringify({
28487
+ issueId: candidate.issueId,
28488
+ workspacePath: candidate.workspacePath,
28489
+ reconciler: "pending-promotion",
28490
+ timestamp: now.toISOString()
28491
+ })
28492
+ });
28493
+ continue;
28494
+ }
28495
+ const nextAttempts = candidate.patrolAttempts + 1;
28496
+ const lastError = error ?? "complete-planning did not converge";
28497
+ await markerIo.write(candidate.markerPath, {
28498
+ version: "1",
28499
+ issueId: candidate.issueId,
28500
+ canonicalFilename: candidate.canonicalFilename,
28501
+ noPrd: candidate.noPrd,
28502
+ autoSpawnRequested: candidate.autoSpawnRequested,
28503
+ finalizedAt: candidate.finalizedAt,
28504
+ lastError,
28505
+ lastAttemptAt: now.toISOString(),
28506
+ patrolAttempts: nextAttempts
28507
+ });
28508
+ logDiagnostic("promotion-failed", {
28509
+ issueId: candidate.issueId,
28510
+ patrolAttempts: nextAttempts,
28511
+ error: lastError
28512
+ });
28513
+ actions.push(`Pending planning promotion for ${candidate.issueId} failed attempt ${nextAttempts}: ${lastError}`);
28514
+ if (nextAttempts >= NEEDS_YOU_ATTEMPTS) await recordNeedsYou(candidate.issueId, "pending-promotion", candidate.finalizedAt, `Planning promotion for ${candidate.issueId} has failed ${nextAttempts} patrol attempts. The finalized plan remains unpromoted. Run \`pan plan done ${candidate.issueId}\` to retry manually, then inspect the complete-planning error if it still fails.`);
28515
+ }
28516
+ return actions;
28517
+ }
28518
+ //#endregion
28213
28519
  //#region ../../lib/cloister/test-status-green-ci-reconciler.ts
28214
28520
  const terminalMergeStatuses = new Set([
28215
28521
  "merged",
@@ -28709,6 +29015,175 @@ async function cleanupOrphanedInspectSessions() {
28709
29015
  return actions;
28710
29016
  }
28711
29017
  //#endregion
29018
+ //#region ../../lib/cloister/deacon-verdict-fallback-sweep.ts
29019
+ init_test_verdict();
29020
+ init_review_status();
29021
+ init_review_status_record_sync();
29022
+ init_projects();
29023
+ init_recovery_trip();
29024
+ init_activity_logger();
29025
+ /**
29026
+ * Total time this sweep may spend waiting on warning delivery, across ALL issues.
29027
+ *
29028
+ * Bounding each request alone is not enough: the sweep visits issues serially,
29029
+ * so N stranded fallbacks against a stalled dashboard would cost N × the
29030
+ * per-request deadline — six would consume a whole 60s patrol interval and dozens
29031
+ * would hold it for many minutes, starving every later issue and later patrol
29032
+ * phase while the patrol heartbeat still reported healthy. The systemic
29033
+ * degradation that strands several verdicts at once is exactly the state that
29034
+ * makes every loopback request hit its deadline, so the budget is shared.
29035
+ */
29036
+ const SWEEP_WARNING_BUDGET_MS = 30 * 1e3;
29037
+ /**
29038
+ * Resolve `attempt`, or give up at `deadlineMs` and report `failed`.
29039
+ *
29040
+ * Abandoning a warning is always safe: nothing is marked warned on `failed`, and
29041
+ * a later retry carries the same idempotency key, so a call that lands after we
29042
+ * stopped waiting returns `duplicate` rather than emitting a second warning.
29043
+ */
29044
+ async function withWarningDeadline(attempt, deadlineMs) {
29045
+ let timer;
29046
+ try {
29047
+ return await Promise.race([attempt, new Promise((resolve) => {
29048
+ timer = setTimeout(() => {
29049
+ resolve("failed");
29050
+ }, deadlineMs);
29051
+ })]);
29052
+ } finally {
29053
+ if (timer) clearTimeout(timer);
29054
+ }
29055
+ }
29056
+ /**
29057
+ * Episodes already warned about in THIS process, keyed by recovery path + issue
29058
+ * + the fallback's own `updatedAt`.
29059
+ *
29060
+ * Only an optimisation, never the dedupe of record: it saves re-querying the
29061
+ * event log every patrol. Correctness across restarts comes from the two
29062
+ * durable planes — the open recovery trip, and `emitActivityEntryOnce`'s
29063
+ * event-log check on the episode id. An episode is added here only after the
29064
+ * warning is confirmed durable, so a failed append is retried rather than
29065
+ * suppressed, and entries are dropped once the trip lands.
29066
+ */
29067
+ const warnedEpisodes = /* @__PURE__ */ new Set();
29068
+ /**
29069
+ * Describe a verdict conflict and the one action that reliably clears it.
29070
+ *
29071
+ * Deliberately does NOT hand out a `pan admin specialists done` command. That
29072
+ * command is not a general conflict resolver: `merge` takes passed|failed and
29073
+ * maps them to merged|failed (so the displayed `merged` is rejected), `inspect`
29074
+ * requires an `--item` this pipeline-level conflict cannot identify, `review`
29075
+ * does not accept `skipped`, verification has no specialist at all, and
29076
+ * re-signalling the value already in the journal writes no replacement fallback
29077
+ * — so the conflicting one survives and every later drain withholds it again.
29078
+ * A conflict can also span several gates, which one command cannot settle.
29079
+ *
29080
+ * A strictly newer review cycle is the only instruction correct for every gate
29081
+ * and every choice, so that is what the operator is told, along with what it
29082
+ * costs. A dedicated resolve-this-generation operation through the verdict write
29083
+ * door would let an operator adopt a specific written verdict instead; until
29084
+ * that exists, promising it here would be a lie.
29085
+ */
29086
+ function conflictMessage(issueId, conflicts, ageMinutes) {
29087
+ const detail = conflicts.map((c) => `${c.gate} (the record holds "${c.journalValue}", the workspace fallback holds "${c.fallbackValue}")`).join("; ");
29088
+ return `${issueId} — two different verdicts have been written for ${conflicts.length === 1 ? "one gate" : `${conflicts.length} gates`} and Overdeck cannot tell which is newer, so it refuses to choose: ${detail}. This has been unresolved for ${ageMinutes}min and will NOT clear on its own: the fold is withheld on every patrol, by design, so that neither written verdict is destroyed. An operator must decide. The one action that reliably clears it for every gate is to dispatch a strictly newer review cycle for ${issueId} — that supersedes the stranded fallback and re-runs the gates, rather than adopting either of the verdicts already written. Overdeck has no command today that adopts one specific written verdict, so do not expect a re-signal of an existing value to clear this.`;
29089
+ }
29090
+ async function lockOwnerDescription(issueId) {
29091
+ try {
29092
+ const resolved = resolveProjectFromIssueSync(issueId);
29093
+ if (!resolved) return "unknown writer";
29094
+ const project = getProjectSync(resolved.projectKey);
29095
+ if (!project) return "unknown writer";
29096
+ return (await readOwner(recordLockPath(project, issueId))).description;
29097
+ } catch {
29098
+ return "unknown writer";
29099
+ }
29100
+ }
29101
+ /**
29102
+ * Drain every pending workspace verdict fallback, and surface the ones that stay
29103
+ * stuck. Returns one action line per drain or escalation, for the patrol log.
29104
+ *
29105
+ * `budgetMs` bounds the total time spent waiting on warning delivery. The deacon
29106
+ * derives it from the resolved patrol interval so a shortened interval cannot be
29107
+ * overrun by the sweep.
29108
+ */
29109
+ async function sweepStrandedVerdictFallbacks(now = Date.now(), budgetMs = SWEEP_WARNING_BUDGET_MS) {
29110
+ const actions = [];
29111
+ let statuses;
29112
+ try {
29113
+ statuses = loadReviewStatuses();
29114
+ } catch {
29115
+ return actions;
29116
+ }
29117
+ const candidates = [];
29118
+ for (const [issueId, status] of Object.entries(statuses)) {
29119
+ if (status.mergeStatus === "merged" || status.closedOut) continue;
29120
+ try {
29121
+ const fallback = await readWorkspaceVerdictFallback(issueId);
29122
+ if (!fallback) continue;
29123
+ if (await drainWorkspaceVerdictFallback(issueId)) {
29124
+ actions.push(`Drained stranded verdict fallback for ${issueId}`);
29125
+ continue;
29126
+ }
29127
+ const ageMs = now - Date.parse(fallback.updatedAt);
29128
+ if (!Number.isFinite(ageMs) || ageMs < 6e5) continue;
29129
+ if (status.stuck || status.deaconIgnored) continue;
29130
+ const resolved = resolveProjectFromIssueSync(issueId);
29131
+ const workspacePath = resolved ? findWorkspacePath(resolved.projectPath, issueId.toLowerCase()) : null;
29132
+ if (!workspacePath) continue;
29133
+ const ageMinutes = Math.round(ageMs / 6e4);
29134
+ const conflicts = await findWorkspaceVerdictConflicts(issueId, fallback);
29135
+ const conflicted = conflicts.length > 0;
29136
+ const recoveryPath = conflicted ? "verdict-fallback-conflict" : "verdict-fallback-contention";
29137
+ const episode = `${recoveryPath}:${issueId}:${fallback.updatedAt}`;
29138
+ let message;
29139
+ let summary;
29140
+ if (conflicted) {
29141
+ message = conflictMessage(issueId, conflicts, ageMinutes);
29142
+ summary = `${issueId}: verdict conflict on ${conflicts.map((c) => c.gate).join(", ")} — needs operator adjudication`;
29143
+ } else {
29144
+ const owner = await lockOwnerDescription(issueId);
29145
+ message = `${issueId} — verdict fallback undrained for ${ageMinutes}min; the per-issue record lock is contended (current owner: ${owner}). The verdict is durable in the workspace fallback and folds automatically once the lock frees.`;
29146
+ summary = `${issueId}: verdict contended ${ageMinutes}min (lock owner: ${owner})`;
29147
+ }
29148
+ if ((await findRecoveryTrip(issueId, recoveryPath, fallback.updatedAt))?.open === true) {
29149
+ warnedEpisodes.delete(episode);
29150
+ continue;
29151
+ }
29152
+ candidates.push({
29153
+ issueId,
29154
+ workspacePath,
29155
+ recoveryPath,
29156
+ generation: fallback.updatedAt,
29157
+ episode,
29158
+ message,
29159
+ summary
29160
+ });
29161
+ } catch {}
29162
+ }
29163
+ const pending = candidates.filter((c) => !warnedEpisodes.has(c.episode));
29164
+ if (pending.length > 0) (await Promise.all(pending.map((candidate) => withWarningDeadline(emitActivityEntryOnce({
29165
+ id: `verdict-fallback:${candidate.episode}`,
29166
+ source: "cloister",
29167
+ level: "warn",
29168
+ issueId: candidate.issueId,
29169
+ message: candidate.message
29170
+ }), budgetMs).catch(() => "failed")))).forEach((outcome, index) => {
29171
+ const candidate = pending[index];
29172
+ if (outcome === "appended" || outcome === "duplicate") {
29173
+ warnedEpisodes.add(candidate.episode);
29174
+ if (outcome === "appended") actions.push(candidate.summary);
29175
+ } else actions.push(`${candidate.issueId}: verdict-fallback warning could not be confirmed — retrying next patrol`);
29176
+ });
29177
+ for (const candidate of candidates) try {
29178
+ const { emitNeedsYou } = await recordRecoveryFailure(candidate.workspacePath, candidate.issueId, candidate.recoveryPath, candidate.generation, 1);
29179
+ warnedEpisodes.delete(candidate.episode);
29180
+ if (emitNeedsYou) actions.push(`needs-you ${candidate.summary}`);
29181
+ } catch {
29182
+ actions.push(`${candidate.issueId}: ${candidate.recoveryPath} needs-you trip could not be recorded (record lock contended) — retrying next patrol`);
29183
+ }
29184
+ return actions;
29185
+ }
29186
+ //#endregion
28712
29187
  //#region ../../lib/cloister/deacon.ts
28713
29188
  /**
28714
29189
  * Cloister Deacon - Health Monitor for Specialist Agents
@@ -28735,7 +29210,6 @@ init_specialists();
28735
29210
  init_agents$1();
28736
29211
  init_tmux();
28737
29212
  init_issue_closed();
28738
- init_test_verdict();
28739
29213
  const execAsync = promisify$1(exec$1);
28740
29214
  promisify$1(execFile$1);
28741
29215
  /**
@@ -28998,8 +29472,8 @@ async function cleanupStaleAgentState() {
28998
29472
  */
28999
29473
  async function cleanupAbandonedFeedback() {
29000
29474
  const actions = [];
29001
- const { getReviewStatusSync } = await import("./review-status-CacDM78F.js");
29002
- const { clearFeedbackFiles } = await import("./feedback-writer-CY91ckuw.js");
29475
+ const { getReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
29476
+ const { clearFeedbackFiles } = await import("./feedback-writer-CTSuA6lw.js");
29003
29477
  for (const { issueId, workspacePath } of listFeatureWorkspaces()) {
29004
29478
  const panFeedbackDir = join$1(workspacePath, ".pan", "feedback");
29005
29479
  if (!existsSync(panFeedbackDir)) continue;
@@ -29070,7 +29544,7 @@ async function handleOrphanReviewerSession(sessionName, sessions, creationTimes,
29070
29544
  if (!issueId) return null;
29071
29545
  const agentSession = `agent-${issueId.toLowerCase()}`;
29072
29546
  if (sessions.includes(agentSession)) return null;
29073
- const { getReviewStatusSync } = await import("./review-status-CacDM78F.js");
29547
+ const { getReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
29074
29548
  try {
29075
29549
  if (getReviewStatusSync(issueId)?.reviewStatus === "reviewing") return null;
29076
29550
  } catch {}
@@ -29192,7 +29666,7 @@ async function checkOrphanedCompletions() {
29192
29666
  async function checkPendingTestDispatch() {
29193
29667
  const actions = [];
29194
29668
  try {
29195
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-CacDM78F.js");
29669
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
29196
29670
  const statuses = loadReviewStatuses();
29197
29671
  const now = Date.now();
29198
29672
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -29225,7 +29699,7 @@ async function checkPendingTestDispatch() {
29225
29699
  console.log(`[deacon] ${issueId}: skipping test re-dispatch — issue is closed`);
29226
29700
  continue;
29227
29701
  }
29228
- const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
29702
+ const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
29229
29703
  const resolved = resolveProjectFromIssueSync(issueId);
29230
29704
  if (!resolved) continue;
29231
29705
  const issueLower = issueId.toLowerCase();
@@ -29240,8 +29714,8 @@ async function checkPendingTestDispatch() {
29240
29714
  logDeaconEventSync(`checkPendingTestDispatch: deferred test for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
29241
29715
  continue;
29242
29716
  }
29243
- const { spawnRun } = await import("./agents-Dnn4XgdB.js");
29244
- const { buildTestRolePrompt } = await import("./test-agent-queue-DmSIqays.js");
29717
+ const { spawnRun } = await import("./agents-IPSa5kzn.js");
29718
+ const { buildTestRolePrompt } = await import("./test-agent-queue-CWMq7oyG.js");
29245
29719
  try {
29246
29720
  const run = await spawnRun(issueId, "test", {
29247
29721
  workspace,
@@ -29317,6 +29791,8 @@ async function checkPendingTestDispatch() {
29317
29791
  * - Only honors an artifact newer than the current test dispatch (H3)
29318
29792
  */
29319
29793
  const unsignaledTestNudges = /* @__PURE__ */ new Map();
29794
+ /** PAN-3092: test dispatch generations already escalated — never nudged again. */
29795
+ const unsignaledTestEscalations = /* @__PURE__ */ new Set();
29320
29796
  async function checkCompletedButUnsignaledTests() {
29321
29797
  const actions = [];
29322
29798
  const TEST_SETTLE_MS = 300 * 1e3;
@@ -29339,13 +29815,13 @@ async function checkCompletedButUnsignaledTests() {
29339
29815
  const paneDead = sessionAlive ? await Effect.runPromise(isPaneDead(testSession)).catch(() => true) : true;
29340
29816
  const sessionLive = sessionAlive && !paneDead;
29341
29817
  const idle = sessionLive ? isAgentIdleForNudge(testSession, TEST_SETTLE_MS, now) : false;
29342
- const lastNudged = unsignaledTestNudges.get(testSession);
29343
- const alreadyNudged = !!(lastNudged && now - lastNudged < NUDGE_DEDUP_MS);
29344
29818
  const lastDispatchAt = status.history?.filter((h) => h.type === "test" && h.status === "testing").pop()?.timestamp;
29819
+ const lastNudged = unsignaledTestNudges.get(testSession);
29820
+ const escalationKey = `${testSession}:${lastDispatchAt ?? "unknown"}`;
29345
29821
  const decision = decideUnsignaledTestAction({
29346
29822
  sessionLive,
29347
29823
  idle,
29348
- alreadyNudged,
29824
+ alreadyNudged: unsignaledTestEscalations.has(escalationKey) || !!(lastNudged && now - lastNudged < NUDGE_DEDUP_MS),
29349
29825
  artifact: readTestVerdictArtifact(wsPath, lastDispatchAt ? new Date(lastDispatchAt).getTime() : void 0)
29350
29826
  });
29351
29827
  switch (decision.action) {
@@ -29365,7 +29841,7 @@ async function checkCompletedButUnsignaledTests() {
29365
29841
  const cmd = `pan admin specialists done test ${issueId} --status ${decision.status}${noteArg}`;
29366
29842
  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.`;
29367
29843
  try {
29368
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
29844
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
29369
29845
  await messageAgent(testSession, nudge);
29370
29846
  unsignaledTestNudges.set(testSession, now);
29371
29847
  const msg = `Nudged ${testSession} to signal ${decision.status} (verdict artifact present)`;
@@ -29379,7 +29855,7 @@ async function checkCompletedButUnsignaledTests() {
29379
29855
  case "nudge-write": {
29380
29856
  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.`;
29381
29857
  try {
29382
- const { messageAgent } = await import("./agents-Dnn4XgdB.js");
29858
+ const { messageAgent } = await import("./agents-IPSa5kzn.js");
29383
29859
  await messageAgent(testSession, nudge);
29384
29860
  unsignaledTestNudges.set(testSession, now);
29385
29861
  const msg = `Nudged ${testSession} to write+signal a test verdict (no artifact yet)`;
@@ -29390,6 +29866,15 @@ async function checkCompletedButUnsignaledTests() {
29390
29866
  }
29391
29867
  break;
29392
29868
  }
29869
+ case "escalate": {
29870
+ unsignaledTestEscalations.add(escalationKey);
29871
+ const msg = await recordUnsignaledTestEscalation(wsPath, issueId, testSession, lastDispatchAt ?? "unknown");
29872
+ if (msg) {
29873
+ actions.push(msg);
29874
+ console.warn(`[deacon] ${msg}`);
29875
+ }
29876
+ break;
29877
+ }
29393
29878
  default: break;
29394
29879
  }
29395
29880
  }
@@ -29402,8 +29887,8 @@ async function checkCompletedButUnsignaledTests() {
29402
29887
  async function checkVerificationReviewContradiction() {
29403
29888
  const actions = [];
29404
29889
  try {
29405
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-CacDM78F.js");
29406
- const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
29890
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-B6wYcOtP.js");
29891
+ const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
29407
29892
  const statuses = loadReviewStatuses();
29408
29893
  for (const [issueId, status] of Object.entries(statuses)) if (status.verificationStatus === "passed" && status.reviewStatus === "reviewing" && status.stuckReason === "review_infrastructure_failure") {
29409
29894
  let reviewedAtCommit;
@@ -29412,7 +29897,7 @@ async function checkVerificationReviewContradiction() {
29412
29897
  if (project) {
29413
29898
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
29414
29899
  if (existsSync(workspacePath)) {
29415
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-CedsVume.js");
29900
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-C31x1lpE.js");
29416
29901
  reviewedAtCommit = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);
29417
29902
  }
29418
29903
  }
@@ -29508,7 +29993,7 @@ async function checkReadyForMergeStuck() {
29508
29993
  const testStatusGreenCiReconcileCooldowns = /* @__PURE__ */ new Map();
29509
29994
  const TEST_STATUS_GREEN_CI_RECONCILE_COOLDOWN_MS = 300 * 1e3;
29510
29995
  async function reconcileTestStatusFromGreenCi() {
29511
- const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-DIE8BkHI.js");
29996
+ const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-CpQSDlv8.js");
29512
29997
  return reconcileTestStatusFromGreenCiWithDeps({
29513
29998
  isGitHubAppConfigured,
29514
29999
  loadReviewStatuses,
@@ -29529,7 +30014,7 @@ async function reconcileTestStatusFromGreenCi() {
29529
30014
  */
29530
30015
  async function clearStaleCiFeedback(issueId) {
29531
30016
  const { readdir, rm } = await import("fs/promises");
29532
- const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
30017
+ const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
29533
30018
  const projectConfig = resolveProjectFromIssueSync(issueId);
29534
30019
  if (!projectConfig) return;
29535
30020
  const repoDir = projectConfig.projectPath;
@@ -29550,26 +30035,21 @@ async function clearStaleCiFeedback(issueId) {
29550
30035
  const deadEndCooldowns = /* @__PURE__ */ new Map();
29551
30036
  const DEAD_END_STALENESS_MS = 300 * 1e3;
29552
30037
  const DEAD_END_COOLDOWN_MS = 600 * 1e3;
29553
- /**
29554
- * Detect dead-end agents: review blocked, tests failed, or merge failed (CI)
29555
- * but work agent is idle.
29556
- *
29557
- * This happens when:
29558
- * - Review feedback was delivered with a wrong URL (now fixed, but old feedback persists)
29559
- * - Agent forgot how to resubmit (context compaction lost instructions)
29560
- * - Feedback delivery to tmux failed silently
29561
- * - Merge failed due to CI checks (now handled in checkFailedMergeRetry by routing
29562
- * to the work agent with feedback; dead-end catches cases where the agent is idle)
29563
- *
29564
- * Recovery: re-queue the review via the request-review API endpoint and
29565
- * send the agent a nudge message with the correct resubmit command.
29566
- * For CI-blocked merges: clear the stale merge failure and feedback files.
29567
- */
29568
- async function checkDeadEndAgents() {
30038
+ async function checkDeadEndAgents(deps = {}) {
29569
30039
  const actions = [];
30040
+ const readReviewStatuses = deps.loadReviewStatuses ?? loadReviewStatuses;
30041
+ const hasSession = deps.sessionExistsSync ?? sessionExistsSync;
30042
+ const readAgentState = deps.getAgentStateSync ?? getAgentStateSync;
30043
+ const resolveAgentDir = deps.getAgentDir ?? getAgentDir;
30044
+ const decideRedrive = deps.decideAgentAutonomousRedrive ?? decideAgentAutonomousRedrive;
30045
+ const recordNeedsYou = deps.recordDeadEndNeedsYou ?? recordDeadEndNeedsYou;
30046
+ const spawnWorkAgent = deps.spawnWorkAgentThroughAgentsEndpoint ?? spawnWorkAgentThroughAgentsEndpoint;
30047
+ const updateReviewStatus = deps.setReviewStatusSync ?? setReviewStatusSync;
30048
+ const clearAgentTroubled = deps.clearAgentTroubledSync ?? clearAgentTroubledSync;
30049
+ const saveAgentState = deps.saveAgentStateSync ?? saveAgentStateSync;
29570
30050
  try {
29571
- const statuses = loadReviewStatuses();
29572
- const now = Date.now();
30051
+ const statuses = readReviewStatuses();
30052
+ const now = deps.now?.() ?? Date.now();
29573
30053
  for (const [key, status] of Object.entries(statuses)) {
29574
30054
  const isReviewBlocked = status.reviewStatus === "blocked" || status.reviewStatus === "failed";
29575
30055
  const isVerificationFailed = status.verificationStatus === "failed";
@@ -29600,24 +30080,27 @@ async function checkDeadEndAgents() {
29600
30080
  else if (isVerificationFailed) statusType = status.reviewStatus === "pending" ? "verification failed while review pending" : "verification failed";
29601
30081
  else if (isTestFailed) statusType = "tests failed";
29602
30082
  else statusType = "merge CI blocked";
29603
- if (!sessionExistsSync(agentSessionName)) {
30083
+ if (!hasSession(agentSessionName)) {
29604
30084
  if (isReviewBlocked || isVerificationFailed || isTestFailed) {
29605
- const agentState = getAgentStateSync(agentSessionName);
29606
- const gateDecision = decideAgentAutonomousRedrive(agentState ?? {}, getAgentDir(agentSessionName), true);
30085
+ const agentState = readAgentState(agentSessionName);
30086
+ const gateDecision = await decideRedrive(agentState ?? {}, resolveAgentDir(agentSessionName), true);
29607
30087
  if (gateDecision.decision === "defer") {
29608
30088
  console.log(`[deacon] PAN-2209: ${issueId} (${statusType}) re-drive deferred — ${gateDecision.reason}`);
29609
- const trip = gateDecision.needsYou && await recordDeadEndNeedsYou(issueId, "operator-stopped-rework", status.updatedAt ?? statusType, `Dead-end recovery needs-you: ${issueId} was explicitly stopped before handoff`);
30089
+ const pendingOperatorDecision = gateDecision.reason.startsWith("agent is waiting on an operator decision");
30090
+ const recoveryPath = pendingOperatorDecision ? "pending-operator-decision" : "operator-stopped-rework";
30091
+ const needsYouMessage = pendingOperatorDecision ? `Dead-end recovery needs-you: ${issueId} ${gateDecision.reason}. Answer it with 'pan answer ${issueId}'.` : `Dead-end recovery needs-you: ${issueId} was explicitly stopped before handoff`;
30092
+ const trip = gateDecision.needsYou && await recordNeedsYou(issueId, recoveryPath, status.updatedAt ?? statusType, needsYouMessage);
29610
30093
  if (trip) actions.push(trip);
29611
30094
  } else {
29612
30095
  if (gateDecision.gateDecision.clearStoppedByUser && agentState) {
29613
30096
  delete agentState.stoppedByUser;
29614
- saveAgentStateSync(agentState);
30097
+ saveAgentState(agentState);
29615
30098
  }
29616
30099
  deadEndCooldowns.set(key, now);
29617
- setReviewStatusSync(issueId, { autoRequeueCount: autoRequeueCount + 1 });
29618
- clearAgentTroubledSync(agentSessionName);
30100
+ updateReviewStatus(issueId, { autoRequeueCount: autoRequeueCount + 1 });
30101
+ clearAgentTroubled(agentSessionName);
29619
30102
  try {
29620
- const spawn = await spawnWorkAgentThroughAgentsEndpoint(issueId);
30103
+ const spawn = await spawnWorkAgent(issueId);
29621
30104
  if (spawn.spawned) {
29622
30105
  actions.push(`Dead-end recovery (PAN-2209): respawned dead work agent for ${issueId} (${statusType}) to address feedback`);
29623
30106
  console.log(`[deacon] PAN-2209: respawned dead work agent for ${issueId} (${statusType})`);
@@ -29773,7 +30256,7 @@ async function killOrphanedWorkspaceProcesses(workspacePath) {
29773
30256
  async function checkWorkspaceContainerHealth(sharedState) {
29774
30257
  const actions = [];
29775
30258
  try {
29776
- const { stdout } = await execAsync("docker ps -a --filter \"status=exited\" --filter \"name=overdeck-feature-\" --format \"{{.Names}}|{{.Status}}\" 2>/dev/null || true", {
30259
+ const { stdout } = await execAsync("docker ps -a --filter \"status=exited\" --filter \"name=feature-\" --format \"{{.Names}}|{{.Status}}\" 2>/dev/null || true", {
29777
30260
  encoding: "utf-8",
29778
30261
  timeout: 1e4
29779
30262
  });
@@ -29786,7 +30269,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
29786
30269
  for (const line of crashed) {
29787
30270
  const [name, status] = line.split("|");
29788
30271
  if (!name) continue;
29789
- const match = name.match(/overdeck-feature-([\w-]+?)-(frontend|server)-/);
30272
+ const match = name.match(/feature-((?:[a-z]+-\d+)|(?:(?:f|us|de|ta|tc)\d+))-(frontend|server)-\d+$/i);
29790
30273
  if (!match) continue;
29791
30274
  const exitMatch = status?.match(/Exited \((\d+)\)/);
29792
30275
  if (exitMatch && exitMatch[1] === "0") continue;
@@ -29825,7 +30308,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
29825
30308
  }
29826
30309
  }
29827
30310
  try {
29828
- const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
30311
+ const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
29829
30312
  const resolved = resolveProjectFromIssueSync(issueLower.toUpperCase());
29830
30313
  if (resolved) await killOrphanedWorkspaceProcesses(`${resolved.projectPath}/workspaces/feature-${issueLower}`);
29831
30314
  } catch {}
@@ -29874,8 +30357,8 @@ async function checkWorkspaceContainerHealth(sharedState) {
29874
30357
  async function checkMergedWorkSessions() {
29875
30358
  const actions = [];
29876
30359
  try {
29877
- const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-DvFqQUnq.js");
29878
- const { setAgentPaused } = await import("./agents-Dnn4XgdB.js");
30360
+ const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-DegFS2p1.js");
30361
+ const { setAgentPaused } = await import("./agents-IPSa5kzn.js");
29879
30362
  const toKill = selectMergedWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
29880
30363
  for (const session of toKill) try {
29881
30364
  await Effect.runPromise(setAgentPaused(session, "merged — awaiting close-out (verify on main)", true));
@@ -29915,7 +30398,7 @@ const AWAITING_TEST_IDLE_REAP_MS = 600 * 1e3;
29915
30398
  async function checkAwaitingTestWorkSessions() {
29916
30399
  const actions = [];
29917
30400
  try {
29918
- const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-DvFqQUnq.js");
30401
+ const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-DegFS2p1.js");
29919
30402
  const candidates = selectAwaitingTestWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
29920
30403
  const now = Date.now();
29921
30404
  for (const session of candidates) {
@@ -29968,32 +30451,37 @@ async function runPatrol() {
29968
30451
  hasLoggedGlobalPauseSkip = false;
29969
30452
  addLog("info", `Patrol cycle ${state.patrolCycle} — checking per-project specialists`, state.patrolCycle);
29970
30453
  console.log(`[deacon] Patrol cycle ${state.patrolCycle} - checking per-project specialists`);
29971
- for (const a of await (await import("./stale-task-claims-D1Ll8fI5.js")).patrolStaleTaskClaims()) {
30454
+ for (const a of await (await import("./stale-task-claims-BYJGqhLI.js")).patrolStaleTaskClaims()) {
29972
30455
  actions.push(a);
29973
30456
  addLog("action", a, state.patrolCycle);
29974
30457
  }
29975
30458
  const stuckRemediationActions = await checkStuckAgentRemediation();
29976
30459
  actions.push(...stuckRemediationActions);
29977
30460
  for (const a of stuckRemediationActions) addLog("action", a, state.patrolCycle);
29978
- const { reconcileInFlightJournals } = await import("./advancing-selfheal-DieFp3qi.js");
30461
+ const { reconcileInFlightJournals } = await import("./advancing-selfheal-8AR68Asf.js");
29979
30462
  const reconciledJournalActions = await reconcileInFlightJournals();
29980
30463
  actions.push(...reconciledJournalActions);
29981
30464
  for (const a of reconciledJournalActions) addLog("action", a, state.patrolCycle);
29982
30465
  try {
29983
30466
  const pendingFile = join$1(OVERDECK_HOME, "pending-post-merge.json");
29984
- const { processPendingLifecycleForPatrol } = await import("./deacon-pending-lifecycle-2ZflPxgo.js");
30467
+ const { processPendingLifecycleForPatrol } = await import("./deacon-pending-lifecycle-CD3YsiQK.js");
29985
30468
  const action = await processPendingLifecycleForPatrol(pendingFile);
29986
30469
  if (action) actions.push(action);
29987
30470
  } catch (err) {
29988
30471
  console.warn(`[deacon] Failed to process pending lifecycle: ${err.message}`);
29989
30472
  }
29990
- if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-BNjeCL8u.js")).runScheduledDeployPatrol();
30473
+ if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-kARAkji4.js")).runScheduledDeployPatrol();
29991
30474
  const livenessActions = await reconcileAgentLiveness();
29992
30475
  actions.push(...livenessActions);
29993
30476
  for (const a of livenessActions) addLog("action", a, state.patrolCycle);
29994
- const orphanProposedActions = await reconcileOrphanProposedSpecs();
29995
- actions.push(...orphanProposedActions);
29996
- for (const a of orphanProposedActions) addLog("action", a, state.patrolCycle);
30477
+ for (const a of await reconcileOrphanProposedSpecs()) {
30478
+ actions.push(a);
30479
+ addLog("action", a, state.patrolCycle);
30480
+ }
30481
+ for (const a of await reconcilePendingPromotions()) {
30482
+ actions.push(a);
30483
+ addLog("action", a, state.patrolCycle);
30484
+ }
29997
30485
  const closedIssueAgentActions = await reconcileClosedIssueAgents();
29998
30486
  actions.push(...closedIssueAgentActions);
29999
30487
  for (const a of closedIssueAgentActions) addLog("action", a, state.patrolCycle);
@@ -30003,7 +30491,7 @@ async function runPatrol() {
30003
30491
  const idleStackActions = await reconcileIdleWorkspaceStacks();
30004
30492
  actions.push(...idleStackActions);
30005
30493
  for (const a of idleStackActions) addLog("action", a, state.patrolCycle);
30006
- for (const a of await (await import("./bridge-pool-patrol-DsPj6F7t.js")).patrolDockerBridgePool()) {
30494
+ for (const a of await (await import("./bridge-pool-patrol-BEjt-xF3.js")).patrolDockerBridgePool()) {
30007
30495
  actions.push(a);
30008
30496
  addLog("action", a, state.patrolCycle);
30009
30497
  }
@@ -30023,7 +30511,7 @@ async function runPatrol() {
30023
30511
  actions.push(...suspendActions);
30024
30512
  for (const a of suspendActions) addLog("action", a, state.patrolCycle);
30025
30513
  try {
30026
- const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
30514
+ const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
30027
30515
  const allStatuses = loadReviewStatuses();
30028
30516
  for (const [issueId, status] of Object.entries(allStatuses)) {
30029
30517
  if (!status.readyForMerge || status.mergeStatus === "merged") continue;
@@ -30043,7 +30531,7 @@ async function runPatrol() {
30043
30531
  } catch (err) {
30044
30532
  console.warn(`[deacon] Failed to check workspace existence: ${err.message}`);
30045
30533
  }
30046
- const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-DieFp3qi.js");
30534
+ const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-8AR68Asf.js");
30047
30535
  const reapedWorkActions = await checkMergedWorkSessions();
30048
30536
  actions.push(...reapedWorkActions);
30049
30537
  for (const a of reapedWorkActions) addLog("action", a, state.patrolCycle);
@@ -30051,7 +30539,7 @@ async function runPatrol() {
30051
30539
  actions.push(...reapedMergedAdvancingActions);
30052
30540
  for (const a of reapedMergedAdvancingActions) addLog("action", a, state.patrolCycle);
30053
30541
  try {
30054
- const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-BtmZ42aP.js");
30542
+ const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-BS4tJUn8.js");
30055
30543
  const remoteCredentialActions = await refreshClaudeCredentialsForActiveRemoteAgents();
30056
30544
  actions.push(...remoteCredentialActions);
30057
30545
  for (const a of remoteCredentialActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -30059,7 +30547,7 @@ async function runPatrol() {
30059
30547
  addLog("warn", `Remote credential refresh patrol failed: ${err.message}`, state.patrolCycle);
30060
30548
  }
30061
30549
  try {
30062
- const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-kwsEZvXu.js");
30550
+ const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-BIIoc5pD.js");
30063
30551
  const heartbeatActions = await refreshHostHeartbeatForEphemeralVms();
30064
30552
  actions.push(...heartbeatActions);
30065
30553
  for (const a of heartbeatActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -30067,7 +30555,7 @@ async function runPatrol() {
30067
30555
  addLog("warn", `Remote heartbeat refresh patrol failed: ${err.message}`, state.patrolCycle);
30068
30556
  }
30069
30557
  try {
30070
- const { reapCompletedRemoteAgents } = await import("./remote-completion-BtmZ42aP.js");
30558
+ const { reapCompletedRemoteAgents } = await import("./remote-completion-BS4tJUn8.js");
30071
30559
  const remoteReap = await reapCompletedRemoteAgents();
30072
30560
  for (const r of remoteReap) if (r.status === "handed-off" || r.status === "error") {
30073
30561
  const msg = `Remote reap ${r.issueId}: ${r.status} (${r.details.join("; ")})`;
@@ -30119,6 +30607,9 @@ async function runPatrol() {
30119
30607
  const unappliedReviewActions = await reconcileUnappliedReviewVerdicts();
30120
30608
  actions.push(...unappliedReviewActions);
30121
30609
  for (const a of unappliedReviewActions) addLog("action", a, state.patrolCycle);
30610
+ const verdictFallbackActions = await sweepStrandedVerdictFallbacks(Date.now(), Math.max(1e3, Math.floor(config.patrolIntervalMs / 2)));
30611
+ actions.push(...verdictFallbackActions);
30612
+ for (const a of verdictFallbackActions) addLog("action", a, state.patrolCycle);
30122
30613
  const verifContradictionActions = await checkVerificationReviewContradiction();
30123
30614
  actions.push(...verifContradictionActions);
30124
30615
  for (const a of verifContradictionActions) addLog("action", a, state.patrolCycle);
@@ -30263,7 +30754,7 @@ async function runPatrol() {
30263
30754
  const issueId = runtimeState.currentIssue;
30264
30755
  try {
30265
30756
  if (getReviewStatusSync(issueId)?.mergeStatus === "merging") {
30266
- const { resolveProjectFromIssueSync } = await import("./projects-_n3Zui6K.js");
30757
+ const { resolveProjectFromIssueSync } = await import("./projects-WqMWCdpa.js");
30267
30758
  const resolved = resolveProjectFromIssueSync(issueId);
30268
30759
  if (resolved) {
30269
30760
  const branch = `feature/${issueId.toLowerCase()}`;
@@ -30277,7 +30768,7 @@ async function runPatrol() {
30277
30768
  mergeStatus: "merged",
30278
30769
  readyForMerge: false
30279
30770
  });
30280
- const { postMergeLifecycle } = await import("./merge-agent-C1-9zbP_.js");
30771
+ const { postMergeLifecycle } = await import("./merge-agent-DWd0KfiS.js");
30281
30772
  postMergeLifecycle(issueId, resolved.projectPath).catch((err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`));
30282
30773
  actions.push(`Auto-completed stale merge for ${issueId}`);
30283
30774
  } else {
@@ -30457,7 +30948,7 @@ function startDeacon() {
30457
30948
  logDeaconEventSync(`startDeacon: health monitor starting (patrol every ${config.patrolIntervalMs / 1e3}s)`);
30458
30949
  (async () => {
30459
30950
  await reconcileAgentLiveness();
30460
- const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-DieFp3qi.js");
30951
+ const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-8AR68Asf.js");
30461
30952
  await runBootAdvancingSelfHeal();
30462
30953
  runScheduledPatrol("startup");
30463
30954
  })().catch((err) => {
@@ -30529,4 +31020,4 @@ function assessDeaconPatrolFreshness(params) {
30529
31020
  //#endregion
30530
31021
  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 };
30531
31022
 
30532
- //# sourceMappingURL=deacon-B1LD5cJU.js.map
31023
+ //# sourceMappingURL=deacon-HdEh0Esp.js.map