@overdeck/desktop 0.49.1 → 0.50.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 (545) hide show
  1. package/drizzle/overdeck/0000_overdeck_init.sql +1 -0
  2. package/package.json +1 -1
  3. package/server/{acceptance-criteria-Crw-xSJ3.js → acceptance-criteria-B_maCGZv.js} +2 -2
  4. package/server/{active-dashboard-bundle-CLwfD-Om.js → active-dashboard-bundle-CCqpFWiz.js} +2 -2
  5. package/server/activity-logger-B0X2JJwM.js +3 -0
  6. package/server/{activity-logger-BAVLrkR7.js → activity-logger-SlTXYCVf.js} +22 -4
  7. package/server/{advancing-selfheal-BQiJ7mIH.js → advancing-selfheal-BJAfiY-C.js} +12 -7
  8. package/server/{agent-gc-5E0lgxI1.js → agent-gc-bhikjoJ_.js} +11 -11
  9. package/server/agent-idle-D-UQ7gDv.js +745 -0
  10. package/server/agent-state-BrUPf_7Z.js +3 -0
  11. package/server/{agent-state-Bb3UUxQm.js → agent-state-FABw8neJ.js} +682 -454
  12. package/server/{agent-state-service-keg-x1bT.js → agent-state-service-BAQApt97.js} +1 -1
  13. package/server/{agent-state-service-BFbttwRA.js → agent-state-service-rDenYSlD.js} +5 -5
  14. package/server/agents-DixZjXWm.js +3 -0
  15. package/server/{agents-CqQJW75N.js → agents-DzpQidT8.js} +8 -8
  16. package/server/{archive-planning-BwEhu9Oq.js → archive-planning-BL1ABtW0.js} +20 -135
  17. package/server/archive-planning-D3gw32U9.js +2 -0
  18. package/server/{artifact-index-jobs-C6Lg2rKm.js → artifact-index-jobs-Cjdme0jS.js} +3 -3
  19. package/server/{assemble-DyTp2gSB.js → assemble-B_JgnCbG.js} +28 -9
  20. package/server/{auto-spawn-consent-BDfe4qz0.js → auto-spawn-consent-BesWchEi.js} +8 -7
  21. package/server/{backlog-auto-trigger-DuOGpdDW.js → backlog-auto-trigger-COLq639j.js} +3 -3
  22. package/server/{behavior-Bitko0mD.js → behavior-DCg8CIWC.js} +3 -3
  23. package/server/{bridge-pool-patrol-DiHEd13O.js → bridge-pool-patrol-BDohuMRt.js} +2 -2
  24. package/server/{briefing-freshness-CDJcmHHZ.js → briefing-freshness-ENa_hW_V.js} +2 -2
  25. package/server/build-info-Dx2qrVhb.js +2 -0
  26. package/server/{build-info-DTX8JwVP.js → build-info-WuZT6xyi.js} +3 -3
  27. package/server/{checkpoint-manager-BlOOdzLF.js → checkpoint-manager-CSZ7aVQF.js} +26 -9
  28. package/server/{checkpoint-manager-CKg1tn34.js → checkpoint-manager-DXhGRvg4.js} +1 -1
  29. package/server/checkpoint-worker.js +1 -1
  30. package/server/{checkpoints-BGfl0cHM.js → checkpoints-DUkUsPVS.js} +2 -2
  31. package/server/{checkpoints-DRALkfDS.js → checkpoints-tm_w6Y4V.js} +1 -1
  32. package/server/{claude-hooks-provision-B_tv3wzE.js → claude-hooks-provision-CTh9zxEi.js} +1 -1
  33. package/server/{claude-hooks-provision-BlGv6twJ.js → claude-hooks-provision-fRofvhTN.js} +2 -2
  34. package/server/{claude-permissions-aHgDcZi5.js → claude-permissions-DLrb9ovz.js} +18 -3
  35. package/server/{claude-settings-overlay-T2LWLteV.js → claude-settings-overlay-BYnXaTVc.js} +2 -2
  36. package/server/{claude-settings-overlay-CYOvFE3A.js → claude-settings-overlay-CMS5Jab5.js} +1 -1
  37. package/server/cli-BflmtEFM.js +2 -0
  38. package/server/{cli-Do8UpLoI.js → cli-CoQou1t_.js} +11 -11
  39. package/server/{cliproxy-CX6jHRDP.js → cliproxy-DXDQcR3I.js} +52 -17
  40. package/server/cliproxy-DdhFpcXU.js +3 -0
  41. package/server/{close-issue-J0_eWYT1.js → close-issue-CpQ0BWg-.js} +5 -5
  42. package/server/{closed-issue-reaper-bFppuk6F.js → closed-issue-reaper-CdcJRvUx.js} +13 -12
  43. package/server/{closed-issue-reaper-Cl2h9AfT.js → closed-issue-reaper-TymtZM37.js} +1 -1
  44. package/server/{codex-icapA4om.js → codex-BValsmtK.js} +1 -1
  45. package/server/{codex-OOea7lXs.js → codex-DYyZL8JD.js} +16 -10
  46. package/server/{compaction-continuation-D5voR1ME.js → compaction-continuation-CVjbdGKt.js} +3 -3
  47. package/server/{config-Cjleh3_U.js → config-CvKH7r7W.js} +1 -1
  48. package/server/{config-tucKBCCc.js → config-NxI9Yl2f.js} +2 -2
  49. package/server/{config-DC75T4Mr.js → config-_qaa1UXH.js} +2 -2
  50. package/server/{config-yaml-BwOEANMr.js → config-yaml-D60AnTIu.js} +55 -15
  51. package/server/{conflict-gate-DlpWCMd7.js → conflict-gate-0dD1kxjN.js} +1 -1
  52. package/server/{conflict-gate-D2L1kZeL.js → conflict-gate-hAUCL-un.js} +5 -5
  53. package/server/{context-layers-CSPGc2Hb.js → context-layers-CdpabJj0.js} +3 -3
  54. package/server/context-layers-Ds1MnEFI.js +4 -0
  55. package/server/{continue-U3Af0jUq.js → continue-CnvrUfxw.js} +3 -3
  56. package/server/{control-settings-5k6ixdFW.js → control-settings-Db0uXgVM.js} +310 -7
  57. package/server/{conversation-compaction-CSpVpxN6.js → conversation-compaction-B-1KETG9.js} +8 -8
  58. package/server/{conversation-compaction-Ciit9O6k.js → conversation-compaction-DzMXGRiJ.js} +1 -1
  59. package/server/{conversation-service-BxrB5lUT.js → conversation-service-BL-asWPX.js} +1 -1
  60. package/server/{conversation-service-BteE4ELK.js → conversation-service-BxIOd5ay.js} +21 -7
  61. package/server/conversations-CEMfwMt-.js +3 -0
  62. package/server/{conversations-DhwxsOru.js → conversations-nS6QgYpD.js} +12 -7
  63. package/server/cost-3FyqKK56.js +838 -0
  64. package/server/{cost-Bnf9NUC5.js → cost-Cctc-Q9M.js} +3 -3
  65. package/server/{cost-CQKI6OCu.js → cost-DTuIRE4y.js} +2 -2
  66. package/server/{cost-sync-B-ADeXKY.js → cost-sync-DfmvLT9L.js} +3 -3
  67. package/server/{dag-DI9LaK_q.js → dag-o-dUpw1L.js} +6 -19
  68. package/server/{dangerous-git-ops-akhA3iyF.js → dangerous-git-ops-BOtXCFkT.js} +1 -1
  69. package/server/dashboard-db-worker.js +61 -11
  70. package/server/{deacon-TPYssFYt.js → deacon-CsisLmPt.js} +1735 -172
  71. package/server/{deacon-canonical-state-DFYymrDw.js → deacon-canonical-state-DkdkQS5p.js} +3 -3
  72. package/server/deacon-e6py3jkM.js +4 -0
  73. package/server/{deacon-event-client-Te5v10-b.js → deacon-event-client-BCjHiGAY.js} +1 -1
  74. package/server/{deacon-event-client-BKOL4AcL.js → deacon-event-client-CMQswEHX.js} +2 -2
  75. package/server/{deacon-nudge-log-BtlTWgWu.js → deacon-nudge-log-pcliw8Dr.js} +1 -1
  76. package/server/{deacon-pending-lifecycle-DVHjOLje.js → deacon-pending-lifecycle-BzaE76Xo.js} +3 -3
  77. package/server/deacon.js +11 -11
  78. package/server/{dead-end-trip-P0IF1O0E.js → dead-end-trip-Bs3hxIn6.js} +3 -3
  79. package/server/dead-end-trip-DUbiRMtT.js +2 -0
  80. package/server/delivery-DhZGRShH.js +3 -0
  81. package/server/{deploy-patrol-BXjlvoV3.js → deploy-patrol-B8sKkA8h.js} +8 -8
  82. package/server/deploy-queue--smqHLhe.js +2 -0
  83. package/server/{deploy-queue-o7shYg1j.js → deploy-queue-CCGWXFkp.js} +2 -2
  84. package/server/{deploy-window-CNT6fOff.js → deploy-window-YuJewzmC.js} +4 -4
  85. package/server/{deploy-window-BMk5_oX6.js → deploy-window-hgsvZ3UZ.js} +1 -1
  86. package/server/{dev-supervisor-SR1CLOAK.js → dev-supervisor-4SBloJHV.js} +2 -2
  87. package/server/{devcontainer-renderer-enMmNDFa.js → devcontainer-renderer-BiJhwFNi.js} +3 -3
  88. package/server/{dist-CPTO_zMR.js → dist-CoR2sivG.js} +1 -1
  89. package/server/dist-FHv1s5ez.js +3 -0
  90. package/server/{docker-B7qUZptz.js → docker-CWO7dcIP.js} +3 -3
  91. package/server/{docker-KR3zSFKY.js → docker-DQzyMXkd.js} +1 -1
  92. package/server/{dod-gK835UMf.js → dod-BAk5arLF.js} +1 -1
  93. package/server/{done-preflight-CksRvh49.js → done-preflight-CGFA0M1b.js} +1 -1
  94. package/server/{done-preflight-Bk8aExAL.js → done-preflight-Cx9JGznT.js} +5 -5
  95. package/server/{driver-CmsY2RLl.js → driver-BtcFz-qu.js} +14 -3
  96. package/server/durable-review-pipeline-BOEZ0chh.js +3 -0
  97. package/server/{durable-review-pipeline-DgYHucN2.js → durable-review-pipeline-Djx_lvFd.js} +11 -2
  98. package/server/{ensure-devcontainer-BQ4YizSH.js → ensure-devcontainer-Dk6ZMOUC.js} +1 -1
  99. package/server/{ensure-devcontainer-ojerEqQg.js → ensure-devcontainer-DzYBBwnM.js} +4 -4
  100. package/server/{esm-shims-1htPASWs.js → esm-shims-deFq5Hhl.js} +1 -1
  101. package/server/{event-store-BgEjNsvk.js → event-store-C50Qt-f1.js} +1 -1
  102. package/server/{event-store-D7qcJXuZ.js → event-store-DTns2XZP.js} +5 -5
  103. package/server/{event-store-provider-BKvk2rDj.js → event-store-provider-Bu1Qrg6v.js} +1 -1
  104. package/server/{events-BIKGJZOT.js → events-B6xW8Cpm.js} +3 -3
  105. package/server/{dist-src-BM9eudEd.js → factory-CWVKwKFE.js} +714 -2
  106. package/server/{feature-registry-storage-ewNSIVsQ.js → feature-registry-storage-vaxRN3WO.js} +3 -3
  107. package/server/{features-CGopJXdU.js → features-DXWwktJB.js} +2 -2
  108. package/server/{feedback-stuck-retirement-B8-fX7NA.js → feedback-stuck-retirement-CXAYe2rU.js} +2 -2
  109. package/server/{feedback-target-CkyLYohm.js → feedback-target-DSVpi0gT.js} +1 -1
  110. package/server/{feedback-target-Ci6N5p4G.js → feedback-target-yPD_wclF.js} +10 -10
  111. package/server/{feedback-writer-DfuVjvH0.js → feedback-writer-BzN4qvaP.js} +1 -1
  112. package/server/{feedback-writer-D4ULO4qG.js → feedback-writer-Ds1Wjsz4.js} +5 -5
  113. package/server/{flywheel-DXI_WITn.js → flywheel-BCZS-FlW.js} +1 -1
  114. package/server/{flywheel-BwYPDlhK.js → flywheel-CC4gE_rx.js} +15 -15
  115. package/server/{flywheel-C7yek87O.js → flywheel-DWKd7bMc.js} +79 -29
  116. package/server/{flywheel-merge-order-C5m5bYBc.js → flywheel-merge-order-DDT3i57u.js} +1 -1
  117. package/server/{flywheel-merge-order-CXfU4M6l.js → flywheel-merge-order-DJwH2KpL.js} +17 -15
  118. package/server/forge-4VVCRcF7.js +2 -0
  119. package/server/{forge-DYX9sKzG.js → forge-CHADjOFs.js} +2 -2
  120. package/server/{from-DAdMxC29.js → from-C3dzmjSO.js} +1 -1
  121. package/server/{fs-lock-cw25uO_E.js → fs-lock-DQ_gUxfq.js} +2 -2
  122. package/server/{fts-operations-D_rzLxX5.js → fts-operations-asZo2fh1.js} +3 -3
  123. package/server/git-info-DMOSfJ9I.js +148 -0
  124. package/server/{git-utils-Y0zG25ez.js → git-utils-BAMwn9Nf.js} +1 -1
  125. package/server/{git-utils-DV4B9TRl.js → git-utils-BdHk8y7g.js} +4 -4
  126. package/server/{github-app-C33lDk9Z.js → github-app-BWziYCf3.js} +1 -1
  127. package/server/{github-app-4UX8VIr8.js → github-app-BlMSzSTw.js} +2 -2
  128. package/server/{github-client-nPj5ckZO.js → github-client-OK24qpol.js} +1 -1
  129. package/server/{github-client-DkJVR908.js → github-client-w6j5nVlz.js} +3 -3
  130. package/server/{github-pr-lookup-C9Vokb0W.js → github-pr-lookup-bGcsEvLE.js} +2 -2
  131. package/server/{harness-binary-BgXYDo2Z.js → harness-binary-DChiynaB.js} +2 -2
  132. package/server/{harness-resolve-1NZcVx7n.js → harness-resolve-BplBEbwn.js} +4 -4
  133. package/server/{health-events-jMfxrElt.js → health-events-BTqsmunw.js} +1 -1
  134. package/server/{health-events-DlX_FVAB.js → health-events-Bk3LjaJ9.js} +2 -2
  135. package/server/{hooks-NQ19vvlB.js → hooks-DJR1yR9w.js} +2 -2
  136. package/server/{hooks-W3REcb3h.js → hooks-EndRNrx9.js} +1 -1
  137. package/server/{hume-BFkid2PO.js → hume-1FJmNDTq.js} +2 -2
  138. package/server/hume-gXLmRhmN.js +3 -0
  139. package/server/{identity-Bwh6VGeL.js → identity-C3s8lyp0.js} +3 -3
  140. package/server/{idle-stack-reaper-CHtCNpvd.js → idle-stack-reaper-CBelVOE3.js} +1 -1
  141. package/server/{idle-stack-reaper-BeU_KxWx.js → idle-stack-reaper-DtoI4al6.js} +4 -4
  142. package/server/{in-flight-guard-pcwXKLGz.js → in-flight-guard-B7khcBdQ.js} +1 -1
  143. package/server/{infra-KTp9KV9u.js → infra-CJRi_5Wu.js} +36 -7
  144. package/server/{injection-67YyU6SC.js → injection-ADWQ3D0s.js} +8 -8
  145. package/server/{injection-BxbZKPDh.js → injection-BWsgHvrL.js} +1 -1
  146. package/server/{inspect-agent-VHSihlb7.js → inspect-agent-CCfNJjKr.js} +12 -12
  147. package/server/inspect-agent-Dhp3hCGp.js +2 -0
  148. package/server/{internal-token-B-z-sGBH.js → internal-token-BCTEqUCX.js} +1 -1
  149. package/server/{internal-token-zY75jrRJ.js → internal-token-BeIWG_kT.js} +2 -2
  150. package/server/{io-DfvO2xyh.js → io-BCtZoXHo.js} +5 -5
  151. package/server/{issue-closed-dvEWKO7Q.js → issue-closed-CiYAa6bX.js} +7 -7
  152. package/server/{issue-lifecycle-3N8XF7lP.js → issue-lifecycle-BETNVVLq.js} +206 -29
  153. package/server/{issue-lifecycle-BI6jAfp8.js → issue-lifecycle-DaKN57sx.js} +1 -1
  154. package/server/{issue-service-singleton-CL6hESX2.js → issue-service-singleton-1Q0ER8Yc.js} +1 -1
  155. package/server/{issue-service-singleton-BN_2MXp4.js → issue-service-singleton-C_sZ0HjP.js} +124 -11
  156. package/server/issue-title-fallback-B91iD66g.js +120 -0
  157. package/server/{issues-CkvUoAnq.js → issues-RGHQUKhB.js} +2 -2
  158. package/server/{jsonl-parser-CrEb2PWr.js → jsonl-parser-Dfs1dlYE.js} +3 -3
  159. package/server/jsonl-resolver-bFtftCDd.js +324 -0
  160. package/server/{kimi-code-DoMoGqIu.js → kimi-code-BxkDgaj4.js} +1 -1
  161. package/server/{kimi-code-C26gmGxM.js → kimi-code-CNYRA8Dd.js} +14 -12
  162. package/server/{kimi-parser-Dmhy3UlR.js → kimi-parser-OcWwmOqF.js} +2 -2
  163. package/server/{label-cleanup-X2lWfghH.js → label-cleanup-CefxK9tL.js} +3 -3
  164. package/server/{lifecycle-B0rL38D3.js → lifecycle-DDZ7w-BY.js} +6 -6
  165. package/server/{lifecycle-Bg44O-9x.js → lifecycle-DVXyUil2.js} +2 -2
  166. package/server/{lifecycle-io-DQDU0apV.js → lifecycle-io-D1oBiMce.js} +1 -1
  167. package/server/{lifecycle-io-CCBpRv5m.js → lifecycle-io-D7N0vQNj.js} +5 -5
  168. package/server/{linear-client-B0cIkTs4.js → linear-client-DUN7zCeb.js} +3 -3
  169. package/server/{linear-client-6V2E-DSa.js → linear-client-TL32snOy.js} +1 -1
  170. package/server/{linear-mcp-auth-LCo9AWUd.js → linear-mcp-auth-CtRKSHy5.js} +1 -1
  171. package/server/{linear-mcp-auth-Dsu9Io9r.js → linear-mcp-auth-bB0CPyjh.js} +5 -5
  172. package/server/memory-fts-worker.js +1 -1
  173. package/server/{memory-governor-A4O6vI9d.js → memory-governor-Cvv_9K0M.js} +88 -22
  174. package/server/{memory-pressure-patrol-BWlWywmA.js → memory-pressure-patrol-C6DJJQRA.js} +38 -14
  175. package/server/{merge-BGWcBxku.js → merge-DOCR6pHi.js} +1 -1
  176. package/server/{merge-vz80RvSE.js → merge-FTk4LsnM.js} +3 -3
  177. package/server/{merge-agent-GWhmnxFk.js → merge-agent-C-dsN9se.js} +37 -33
  178. package/server/{merge-agent-BRSz26Oh.js → merge-agent-D-4_iQgy.js} +2 -2
  179. package/server/{merge-batch-CFMEtTxv.js → merge-batch-BJjzUUL7.js} +1 -1
  180. package/server/{merge-completeness-CP347umA.js → merge-completeness-BOtBUwTU.js} +4 -4
  181. package/server/{merge-completeness-7ajHAIR-.js → merge-completeness-CoLJxfUY.js} +1 -1
  182. package/server/merge-eligibility-C4rTS97F.js +3 -0
  183. package/server/merge-eligibility-D7wRnJbj.js +51 -0
  184. package/server/merge-ops-Cf02szJ5.js +2 -0
  185. package/server/merge-rebase-Bj7eJAG4.js +2 -0
  186. package/server/{merge-rebase-C5htyEEH.js → merge-rebase-KBw4rdh3.js} +2 -2
  187. package/server/{merge-set-DsGW8fmc.js → merge-set-CVfEM57p.js} +1 -1
  188. package/server/{merge-set-eiE2nC6C.js → merge-set-CyW-xSn4.js} +4 -4
  189. package/server/{merge-sync-CM2-myXu.js → merge-sync-CYGsJy0u.js} +1 -1
  190. package/server/{merge-sync-Ct0-cxMX.js → merge-sync-YLvOPAry.js} +2 -2
  191. package/server/{merge-train-BOu3fN7O.js → merge-train-VxLn8Ms4.js} +4 -4
  192. package/server/{merge-train-deps-LXHGK61n.js → merge-train-deps-D0y4hBB9.js} +4 -4
  193. package/server/{merge-verification-BRp08IzI.js → merge-verification-BfJRNMiD.js} +6 -6
  194. package/server/{merged-docker-cleanup-worker-CwldDjHV.js → merged-docker-cleanup-worker-Bh5fKG_b.js} +4 -4
  195. package/server/{merged-docker-cleanup-worker-C8eGn78a.js → merged-docker-cleanup-worker-Ci9oeFAe.js} +1 -1
  196. package/server/messaging-Dfbhgjd6.js +3 -0
  197. package/server/{multipart-parser-OAuW7824.js → multipart-parser-BYwfKOVU.js} +2 -2
  198. package/server/{no-resume-mode-MWI6pnrK.js → no-resume-mode-DjMQRkId.js} +1 -1
  199. package/server/node_modules/.package-lock.json +24 -24
  200. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/AGENTS.md +14 -0
  201. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/CLAUDE.md +14 -0
  202. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/README.md +10 -3
  203. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/package.json +2 -2
  204. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/40_sql/10_basics.ts +175 -0
  205. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/40_sql/index.md +6 -0
  206. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/10_basics.ts +3 -1
  207. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/20_testing.ts +100 -0
  208. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/api/Users.ts +30 -14
  209. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/domain/User.ts +15 -6
  210. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Authorization.ts +11 -10
  211. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Users/http.ts +41 -32
  212. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/51_http-server/fixtures/server/Users.ts +141 -20
  213. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/ai-docs/src/70_cli/10_basics.ts +31 -5
  214. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.d.ts.map +1 -1
  215. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js +10 -9
  216. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeChildProcessSpawner.js.map +1 -1
  217. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeClusterSocket.d.ts.map +1 -1
  218. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeClusterSocket.js +12 -9
  219. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeClusterSocket.js.map +1 -1
  220. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeSocket.js +1 -1
  221. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeSocket.js.map +1 -1
  222. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeSocketServer.js +4 -4
  223. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeSocketServer.js.map +1 -1
  224. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.d.ts.map +1 -1
  225. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.js +10 -4
  226. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/NodeStream.js.map +1 -1
  227. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.d.ts +4 -0
  228. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.d.ts.map +1 -0
  229. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.js +10 -0
  230. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/dist/internal/nodeChildProcessSpawner.js.map +1 -0
  231. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/package.json +7 -7
  232. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeChildProcessSpawner.ts +16 -11
  233. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeClusterSocket.ts +15 -12
  234. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeSocket.ts +1 -1
  235. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeSocketServer.ts +4 -4
  236. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/NodeStream.ts +10 -4
  237. package/server/node_modules/@effect/platform-node/node_modules/@effect/platform-node-shared/src/internal/nodeChildProcessSpawner.ts +16 -0
  238. package/server/node_modules/@types/node/README.md +1 -1
  239. package/server/node_modules/@types/node/buffer.buffer.d.ts +5 -5
  240. package/server/node_modules/@types/node/crypto.d.ts +2 -2
  241. package/server/node_modules/@types/node/http.d.ts +16 -0
  242. package/server/node_modules/@types/node/http2.d.ts +10 -2
  243. package/server/node_modules/@types/node/package.json +2 -2
  244. package/server/node_modules/@types/node/process.d.ts +52 -0
  245. package/server/node_modules/@types/node/quic.d.ts +210 -28
  246. package/server/node_modules/@types/node/sqlite.d.ts +6 -2
  247. package/server/node_modules/@types/node/test.d.ts +36 -0
  248. package/server/node_modules/ansi-regex/index.js +3 -2
  249. package/server/node_modules/ansi-regex/package.json +1 -1
  250. package/server/node_modules/effect/node_modules/uuid/README.md +19 -19
  251. package/server/node_modules/effect/node_modules/uuid/dist/v1.js +7 -3
  252. package/server/node_modules/effect/node_modules/uuid/dist/v7.js +5 -2
  253. package/server/node_modules/effect/node_modules/uuid/dist-node/v1.js +7 -3
  254. package/server/node_modules/effect/node_modules/uuid/dist-node/v7.js +5 -2
  255. package/server/node_modules/effect/node_modules/uuid/package.json +4 -3
  256. package/server/node_modules/gaxios/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  257. package/server/node_modules/gaxios/build/esm/tsconfig.tsbuildinfo +1 -1
  258. package/server/node_modules/gaxios/package.json +3 -3
  259. package/server/node_modules/msgpackr/dist/index-no-eval.cjs +11 -5
  260. package/server/node_modules/msgpackr/dist/index-no-eval.cjs.map +1 -1
  261. package/server/node_modules/msgpackr/dist/index-no-eval.min.js +1 -1
  262. package/server/node_modules/msgpackr/dist/index-no-eval.min.js.map +1 -1
  263. package/server/node_modules/msgpackr/dist/index.js +11 -5
  264. package/server/node_modules/msgpackr/dist/index.js.map +1 -1
  265. package/server/node_modules/msgpackr/dist/index.min.js +1 -1
  266. package/server/node_modules/msgpackr/dist/index.min.js.map +1 -1
  267. package/server/node_modules/msgpackr/dist/node.cjs +11 -5
  268. package/server/node_modules/msgpackr/dist/node.cjs.map +1 -1
  269. package/server/node_modules/msgpackr/dist/test.js +11 -5
  270. package/server/node_modules/msgpackr/dist/test.js.map +1 -1
  271. package/server/node_modules/msgpackr/dist/unpack-no-eval.cjs +11 -5
  272. package/server/node_modules/msgpackr/dist/unpack-no-eval.cjs.map +1 -1
  273. package/server/node_modules/msgpackr/package.json +1 -1
  274. package/server/node_modules/msgpackr/unpack.js +11 -5
  275. package/server/node_modules/picomatch/lib/parse.js +10 -1
  276. package/server/node_modules/picomatch/lib/scan.js +30 -18
  277. package/server/node_modules/picomatch/package.json +1 -1
  278. package/server/{orphan-proposed-reconciler-BAE5AZ_e.js → orphan-proposed-reconciler-CnP0K2v3.js} +2 -2
  279. package/server/{orphan-proposed-reconciler-cV3URUqk.js → orphan-proposed-reconciler-nFUlquZt.js} +24 -23
  280. package/server/package-lock.json +25 -25
  281. package/server/package.json +1 -1
  282. package/server/{pan-dir-DDd91kMb.js → pan-dir-B4NfzOf3.js} +5 -5
  283. package/server/{deacon-merge-BOGFEV8_.js → parked-residue-8WbU0y1z.js} +188 -69
  284. package/server/{paths-CRLnDgcI.js → paths-rETQhTF2.js} +2 -2
  285. package/server/{pending-lifecycle-claim-CYgMiDAP.js → pending-lifecycle-claim-yAwDuGS4.js} +2 -2
  286. package/server/{pickup-BjJsSX12.js → pickup-Dle6k9Xt.js} +1 -1
  287. package/server/{pipeline-agent-reader-BLc43dVJ.js → pipeline-agent-reader-CeWhQzXC.js} +5 -5
  288. package/server/{pipeline-membership-BHZp_ShY.js → pipeline-membership-BV4hdkHm.js} +1 -1
  289. package/server/{pipeline-membership-5qlRz5Qg.js → pipeline-membership-C9ykcjsn.js} +1 -1
  290. package/server/{pipeline-membership-gather-CGFY1v-y.js → pipeline-membership-gather-Ba0wJNCR.js} +17 -12
  291. package/server/{pipeline-membership-gather-WhRc1yke.js → pipeline-membership-gather-C9E22B2W.js} +1 -1
  292. package/server/{pipeline-notifier-C4fZ2ito.js → pipeline-notifier-B5DPXvnr.js} +1 -1
  293. package/server/{pipeline-notifier-BmsLWM_2.js → pipeline-notifier-p190L97e.js} +2 -2
  294. package/server/{post-merge-lifecycle-worker-KK1RTKRE.js → post-merge-lifecycle-worker-OQoK8Ckg.js} +3 -3
  295. package/server/{post-merge-state-_Lj3LDLh.js → post-merge-state-DFaf7OI1.js} +4 -4
  296. package/server/prd-locations-F2oLSAhy.js +124 -0
  297. package/server/{project-pipelines-CCkebHOu.js → project-pipelines-CUsa6U59.js} +2 -2
  298. package/server/project-repos-BVdi9-ch.js +3 -0
  299. package/server/{project-repos-B4MK48j4.js → project-repos-CsfvLtmr.js} +29 -3
  300. package/server/project-resource-refresh-queue-BehrH4Ai.js +865 -0
  301. package/server/project-resource-refresh-queue-D2110Guc.js +2 -0
  302. package/server/{projects-DvPEAP18.js → projects-BMuEf14J.js} +1 -1
  303. package/server/{prompts-BiS5I2tZ.js → prompts-CKpDt8Jn.js} +2 -2
  304. package/server/providers-Buv2wmFU.js +3 -0
  305. package/server/{providers-DrfK0Ip8.js → providers-CxPKmyif.js} +7 -7
  306. package/server/public/assets/{chunk-BO2N2NFS-GtVe_o56.js → chunk-BO2N2NFS-DZOQVqV1.js} +4 -4
  307. package/server/public/assets/{diagram-OG6HWLK6-BvhcYYHc.js → diagram-OG6HWLK6-oKeXcbO1.js} +1 -1
  308. package/server/public/assets/{dist-CSmUXazd.js → dist-2qPmeRzT.js} +3 -3
  309. package/server/public/assets/{dist-D0ryefak.js → dist-ClBlE-Nm.js} +1 -1
  310. package/server/public/assets/{ganttDiagram-6RSMTGT7-BXA51DzM.js → ganttDiagram-6RSMTGT7-BwdG9fQv.js} +1 -1
  311. package/server/public/assets/{highlighted-body-OFNGDK62-mlV4EpWt.js → highlighted-body-OFNGDK62-BzGNdskQ.js} +1 -1
  312. package/server/public/assets/index-CdPveU3M.css +1 -0
  313. package/server/public/assets/index-Cg6tdZoY.js +860 -0
  314. package/server/public/assets/{linear-BPE7oswm.js → linear-DpEt1TJb.js} +1 -1
  315. package/server/public/assets/mermaid-GHXKKRXX-6KBD_3T_.js +1 -0
  316. package/server/public/assets/{pieDiagram-4H26LBE5-BguGGV3S.js → pieDiagram-4H26LBE5-9BpM4oRJ.js} +1 -1
  317. package/server/public/assets/{prod-aKDYUrXQ.js → prod-CzJiNNEG.js} +4 -4
  318. package/server/public/assets/{quadrantDiagram-W4KKPZXB-Bx3i4B6H.js → quadrantDiagram-W4KKPZXB-BXWVAoZx.js} +1 -1
  319. package/server/public/assets/{sankeyDiagram-5OEKKPKP-B5vuLjA4.js → sankeyDiagram-5OEKKPKP-5oxodGEw.js} +1 -1
  320. package/server/public/assets/{xychartDiagram-2RQKCTM6-HPlpkqsN.js → xychartDiagram-2RQKCTM6-BChDrHxZ.js} +1 -1
  321. package/server/public/index.html +2 -2
  322. package/server/pull-requests-CmlandI7.js +2 -0
  323. package/server/{pull-requests-BcHIsFJv.js → pull-requests-T0OV0Vn4.js} +3 -3
  324. package/server/{rally-B1OMtzch.js → rally-CUqj2oIN.js} +3 -3
  325. package/server/rally-DYIn9R2U.js +3 -0
  326. package/server/{rally-api-ShZ4kvn0.js → rally-api-BFPb2oSq.js} +2 -2
  327. package/server/{rally-api-u_vkr5c_.js → rally-api-BoucQG1u.js} +1 -1
  328. package/server/{rally-client-D6Feq1Ka.js → rally-client-16iObny7.js} +5 -5
  329. package/server/{rally-client-DgZvUZqX.js → rally-client-CsqLjLLa.js} +1 -1
  330. package/server/{reap-terminal-sessions-CRfiXLY0.js → reap-terminal-sessions-BaDSNR-k.js} +2 -2
  331. package/server/{reap-terminal-sessions-D7f3zSE9.js → reap-terminal-sessions-DgEIKMhH.js} +2 -2
  332. package/server/{rebuild-stack-CCwKHZb6.js → rebuild-stack-BcBVFJp3.js} +2 -2
  333. package/server/{rebuild-stack-DKxOnkpE.js → rebuild-stack-CyXMrj6K.js} +7 -7
  334. package/server/reconciler-caYiRnPy.js +657 -0
  335. package/server/{reconstruct-cache-BP8UIKt7.js → reconstruct-cache-3JzPOune.js} +7 -7
  336. package/server/{record-By-wp6pg.js → record-DYOg97Iv.js} +1 -1
  337. package/server/{record-update-D23jPU6b.js → record-update-BPqpBu3O.js} +9 -7
  338. package/server/{record-update-ByGtIlUK.js → record-update-CDPEX7BH.js} +1 -1
  339. package/server/{recovery-trip-C4dTl8DO.js → recovery-trip-CpfW6LCJ.js} +43 -10
  340. package/server/{recovery-trip-qloOYOFz.js → recovery-trip-xqKC07Gy.js} +1 -1
  341. package/server/{release-engine-Crc0Tjx-.js → release-engine-C_OOhCaK.js} +5 -5
  342. package/server/{release-set-DDXwbIK7.js → release-set-DOIDz2vw.js} +3 -3
  343. package/server/{remote-oEMfXlwT.js → remote-BTh-sjpX.js} +3 -3
  344. package/server/{remote-agents-Bgtc2nOO.js → remote-agents-DbbN7vSm.js} +6 -6
  345. package/server/{remote-agents-DQVGZVQ9.js → remote-agents-MuXx2gWm.js} +1 -1
  346. package/server/{remote-completion-DxUJ5HKR.js → remote-completion-LcWCpAm2.js} +13 -13
  347. package/server/{remote-CBpLi4Yy.js → remote-xY0B43Ho.js} +3 -3
  348. package/server/{resolver-CuAULbLs.js → resolver-C2QKOf09.js} +2 -2
  349. package/server/{resolver-C8rooxoz.js → resolver-D4nsxfGo.js} +31 -8
  350. package/server/resume-ByUrJUNX.js +3 -0
  351. package/server/{review-agent-7C2w5CzU.js → review-agent-BRBTm1qE.js} +43 -55
  352. package/server/review-agent-Caodi0PX.js +3 -0
  353. package/server/{review-artifacts-BJeEfm2r.js → review-artifacts-DgaDlbO4.js} +6 -6
  354. package/server/{review-convoy-liveness-DfF9eXjI.js → review-convoy-liveness-BBvyuRLC.js} +20 -11
  355. package/server/{review-run-recovery-ZjuDTNhZ.js → review-run-recovery-DCzWMMvE.js} +1 -1
  356. package/server/{review-run-recovery-7BKt2Es0.js → review-run-recovery-THHMKlXJ.js} +3 -3
  357. package/server/{review-status-CUnjjOUu.js → review-status-Bge_3XTR.js} +1 -1
  358. package/server/{review-status-DBnR5t4z.js → review-status-DpniqzPT.js} +113 -44
  359. package/server/{review-status-emit-Cg4tOb8U.js → review-status-emit-D7sM720S.js} +3 -3
  360. package/server/{review-status-enrichment-D-rQshu6.js → review-status-enrichment-PDI4-faj.js} +3 -3
  361. package/server/{review-status-source-DSn0glLa.js → review-status-source-D2PCWS6E.js} +1 -1
  362. package/server/{review-status-source-Ct912fv_.js → review-status-source-Jq0BXmn3.js} +1 -1
  363. package/server/{review-status-sync-B7V_Gg51.js → review-status-sync-C6ZKTI8f.js} +11 -8
  364. package/server/{review-status-sync-YthpOH_q.js → review-status-sync-CvpHWyvR.js} +1 -1
  365. package/server/{review-verdict-feedback-C-dBon_-.js → review-verdict-feedback-B2ojHFH5.js} +8 -8
  366. package/server/{review-verdict-feedback-DqXTuJk8.js → review-verdict-feedback-tyMoLT2L.js} +1 -1
  367. package/server/{review-verdict-writer-CKaJWp75.js → review-verdict-writer-Cy_1pnIj.js} +7 -7
  368. package/server/{review-verdict-writer-jldSh3Bm.js → review-verdict-writer-DjrJ64eS.js} +1 -1
  369. package/server/{rollup-DZwH4CLs.js → rollup-Cp0KEoOu.js} +1 -1
  370. package/server/{rollup-QCwYcBdP.js → rollup-DU3xBQu2.js} +8 -8
  371. package/server/{scanner-2aHeLC3W.js → scanner-BFKG3Gxv.js} +8 -8
  372. package/server/{search-DwHYaj66.js → search-DhtKwbBC.js} +2 -2
  373. package/server/{secret-redaction-B5G1xZ3k.js → secret-redaction-DLZ-VqHq.js} +1 -1
  374. package/server/{sequence-io-POKWdusG.js → sequence-io-C-Q19Jez.js} +4 -4
  375. package/server/{sequencer-agent-DS00KHVm.js → sequencer-agent-eN2P2lDz.js} +6 -6
  376. package/server/server.js +1499 -1350
  377. package/server/{service-BLb_CyPL.js → service-CThO0Sar.js} +80 -774
  378. package/server/{session-fork-DcTzVwex.js → session-fork-ZYTHtpBh.js} +2 -2
  379. package/server/settings-ByDRfuuE.js +2 -0
  380. package/server/{settings-Clw8UVNs.js → settings-CTywpFw5.js} +2 -2
  381. package/server/{settings-B9-H2K_E.js → settings-nAT-eK56.js} +3 -3
  382. package/server/{shadow-engineering-C6oO_PiR.js → shadow-engineering-BHZKPJhq.js} +3 -3
  383. package/server/{shadow-state-CEGrrECe.js → shadow-state-BTLi4Axs.js} +2 -2
  384. package/server/{shadow-state-e7250VUx.js → shadow-state-CZ_LnPsi.js} +1 -1
  385. package/server/{shadow-utils-xFk2Wusb.js → shadow-utils-CPLlPHdn.js} +2 -2
  386. package/server/{ship-log-7BnQHuKU.js → ship-log-D-CphNZx.js} +1 -1
  387. package/server/{ship-record-CwUX6Afo.js → ship-record-BaBla0l_.js} +7 -7
  388. package/server/{ship-record-BgUPnpT0.js → ship-record-BlvX8-xv.js} +1 -1
  389. package/server/{ship-status-Ce3_3edi.js → ship-status-rQbPQBsF.js} +2 -2
  390. package/server/{smart-compaction-BmfIi3oL.js → smart-compaction-CUXn8mfX.js} +1 -1
  391. package/server/{smart-compaction-Dy0gw1VH.js → smart-compaction-D1CNGdZx.js} +7 -7
  392. package/server/{spawn-planning-session-nH3b4Drz.js → spawn-planning-session-DCmO6COk.js} +19 -19
  393. package/server/{spawn-planning-session-CfhxRJoY.js → spawn-planning-session-DfEWyrVV.js} +2 -2
  394. package/server/{specialist-completion-CC1XJbTx.js → specialist-completion-BMv3K54P.js} +1 -1
  395. package/server/{specialist-context-cHwpcXSh.js → specialist-context-C1-CfYQb.js} +5 -5
  396. package/server/{specialist-handoff-logger-GqnGSYoJ.js → specialist-handoff-logger-BDKoz5Z9.js} +2 -2
  397. package/server/{specialist-logs-5OTnrV91.js → specialist-logs-BJQFkpdG.js} +3 -3
  398. package/server/specialists-CYt1U3Zm.js +4 -0
  399. package/server/{specialists-8LcQi9Np.js → specialists-D6MUU31Q.js} +21 -272
  400. package/server/{specialists-DocAK-7A.js → specialists-DhS79T9v.js} +369 -691
  401. package/server/{specialists-xXcJHAyg.js → specialists-Dx0zRTxX.js} +1 -1
  402. package/server/specialists-registry-BRLCi61y.js +3 -0
  403. package/server/specialists-registry-Bng0OFGH.js +277 -0
  404. package/server/specs-oRGyfz6C.js +3 -0
  405. package/server/{src-C2TAxwki.js → src-C7gGe4KU.js} +6 -6
  406. package/server/{src-DudQNYVw.js → src-CdwN6WY6.js} +344 -7
  407. package/server/{src-DUVvEA8Q.js → src-DMosbuSJ.js} +3 -3
  408. package/server/{stack-health-DKT4ySnA.js → stack-health-BKfNaqMm.js} +3 -3
  409. package/server/{stack-health-CbyiYS9H.js → stack-health-Bz711z1Y.js} +1 -1
  410. package/server/{stale-task-claims-PzFee70R.js → stale-task-claims-DMRLb5R2.js} +5 -5
  411. package/server/{staleness-D8UTEXV5.js → staleness-CxZaIhrn.js} +1 -1
  412. package/server/{staleness-BjOAq9-d.js → staleness-r_dkMyMG.js} +1 -1
  413. package/server/{stall-sweeper-DOyIfeLR.js → stall-sweeper-CBWqSWV2.js} +8 -8
  414. package/server/{state-home-DhAZlk5k.js → state-home-DhsMqg8W.js} +2 -2
  415. package/server/{state-mapping-BVSs84bO.js → state-mapping-D2yC81Vy.js} +1 -1
  416. package/server/{state-migrate-CJKEwpB0.js → state-migrate-C2Ouyd6e.js} +6 -6
  417. package/server/{state-mirror-Do7pag7W.js → state-mirror-BPXciz84.js} +3 -3
  418. package/server/stuck-remediation-DALieAkx.js +2 -0
  419. package/server/stuck-remediation-kta3KN7c.js +774 -0
  420. package/server/{substrate-bug-weights-service-BTNjHBnl.js → substrate-bug-weights-service-D_ICP7TI.js} +3 -3
  421. package/server/{summary-fork-CvB7Oyq9.js → summary-fork-CojrFKb6.js} +2 -2
  422. package/server/{summary-fork-CZ88rhVx.js → summary-fork-DhhaFhxZ.js} +113 -30
  423. package/server/supervisor/{pane-composer-BaLLspSj.js → pane-composer-CoiVkGIt.js} +8 -1
  424. package/server/supervisor/{paths-D6XUcR_g.js → paths-DTGbtcaP.js} +8 -4
  425. package/server/supervisor/pty-supervisor.js +3 -3
  426. package/server/supervisor/{pty-token-DjjHxoCq.js → pty-token-GVqnvU3U.js} +2 -2
  427. package/server/supervisor-DSSWo4M2.js +2 -0
  428. package/server/{supervisor-D4v0WfiQ.js → supervisor-DqH-laVL.js} +4 -4
  429. package/server/{swarm-readiness-D8R-LWX5.js → swarm-readiness-LF8ZF_hc.js} +3 -3
  430. package/server/{synthesis-verdict-N5Z11pg7.js → synthesis-verdict-CGFF8uQI.js} +2 -2
  431. package/server/{synthesis-verdict-B6wvLGcA.js → synthesis-verdict-DSoOFUIV.js} +1 -1
  432. package/server/{system-prerequisites-BbGZ_WHF.js → system-prerequisites-Lsx0jUUV.js} +2 -2
  433. package/server/{teardown-workspace-CYend-KY.js → teardown-workspace-DMwomEG1.js} +16 -16
  434. package/server/{test-agent-queue-BUtWhNcc.js → test-agent-queue-Cu0D6BYe.js} +6 -6
  435. package/server/{test-verdict-BWm3hgDj.js → test-verdict-9mvl7pQn.js} +1 -1
  436. package/server/{test-verdict-BWtRmdiR.js → test-verdict-oNSv1rVr.js} +2 -2
  437. package/server/{tldr-daemon-CneJ24eL.js → tldr-daemon-CRSAkhBx.js} +1 -1
  438. package/server/{tldr-daemon-CMVBT4kT.js → tldr-daemon-McqCk2X7.js} +2 -2
  439. package/server/tmux-CYucGrTl.js +4 -0
  440. package/server/{tmux-BqXzRuaH.js → tmux-wnT_hg-s.js} +91 -19
  441. package/server/{token-CO3INKbh.js → token-BdfZLRg1.js} +2 -2
  442. package/server/{token-util-DyJJyX_B.js → token-util-Crcay9j_.js} +1 -1
  443. package/server/token-util-DfUS3Lpp.js +3 -0
  444. package/server/{tracker-config-DVzhaUxO.js → tracker-config-tfAOWgng.js} +2 -2
  445. package/server/{tracker-utils-xnVJVrrO.js → tracker-utils-Dbg_pVZg.js} +2 -2
  446. package/server/{traefik-connect-A5k54mCv.js → traefik-connect-DoQvQ6oJ.js} +1 -1
  447. package/server/{tunnel-DauSR-rs.js → tunnel-B1MNIgkL.js} +1 -1
  448. package/server/{tunnel-CwOnS-PB.js → tunnel-skW68j9B.js} +3 -3
  449. package/server/{typed-errors-B-gfU2RB.js → typed-errors-CZ3GFBvo.js} +1 -1
  450. package/server/{typed-errors-DzC4zXbI.js → typed-errors-DXqf3RnP.js} +1 -1
  451. package/server/{types-DjpLVpsj.js → types-PW4zkxCM.js} +1 -1
  452. package/server/{types-DbxY2QB6.js → types-pLpbsNto.js} +1 -1
  453. package/server/{uat-failure-feedback-BVqsWlrr.js → uat-failure-feedback-ly8ZwtfC.js} +5 -5
  454. package/server/{uat-promote-verification-DmG097QS.js → uat-promote-verification-BBaMwfdc.js} +5 -5
  455. package/server/{uat-train-DVUNW03P.js → uat-train-BBEiYSep.js} +0 -0
  456. package/server/{uat-train-COSy-vEX.js → uat-train-D7Ran2FB.js} +1 -1
  457. package/server/{validate-Dvv83iBx.js → validate-BYcBcBwg.js} +3 -3
  458. package/server/{validation-DlHafKzu.js → validation-BfG2jW5C.js} +9 -6
  459. package/server/{validation-BdCjzWLN.js → validation-nSrYiYvA.js} +1 -1
  460. package/server/{verification-artifact-CaSbxUVg.js → verification-artifact-Cmhgq4b_.js} +1 -1
  461. package/server/{verification-artifact-0Zku8N-W.js → verification-artifact-DglwaHke.js} +1 -1
  462. package/server/{verification-runner-DwP2fUEF.js → verification-runner-BEq5ZF-h.js} +53 -27
  463. package/server/{verification-runner-C6wdZda2.js → verification-runner-CFjAuv9u.js} +1 -1
  464. package/server/{vtt-parser-luerJpYT.js → vtt-parser-Va--tv27.js} +1 -1
  465. package/server/work-agent-prompt-BnhKNAg7.js +3 -0
  466. package/server/{work-agent-prompt--9AWNYwZ.js → work-agent-prompt-CaD2ue8m.js} +14 -14
  467. package/server/{work-agent-start-BNQO65W7.js → work-agent-start-0nJ-6UeA.js} +2 -2
  468. package/server/{work-agent-start-DkzseQFl.js → work-agent-start-D8NEN5KD.js} +1 -1
  469. package/server/workflows-BtHRlFIm.js +2 -0
  470. package/server/{workflows-BYwR2aIN.js → workflows-C7mxM1qc.js} +114 -41
  471. package/server/{workspace-iTnTycOB.js → workspace-BAhMgMaO.js} +3 -3
  472. package/server/{workspace-B-QJa3Ps.js → workspace-Dbqv9ehn.js} +1 -1
  473. package/server/{workspace-anchor-drift-CHiGg8iu.js → workspace-anchor-drift-B_3kyyxJ.js} +4 -4
  474. package/server/{workspace-anchor-drift-DTt6h2Em.js → workspace-anchor-drift-Bpa3xoni.js} +1 -1
  475. package/server/{workspace-config-D0CavVtz.js → workspace-config-D-bNq2CF.js} +1 -1
  476. package/server/{workspace-manager-5BKPV6SY.js → workspace-manager-BrbX90Rm.js} +1 -1
  477. package/server/{workspace-manager-W1OnbvU5.js → workspace-manager-CM8RCrSc.js} +17 -17
  478. package/server/{workspace-metadata-tbbevEmP.js → workspace-metadata-BEOwJSdK.js} +1 -1
  479. package/server/{workspace-metadata-dJhXvZGQ.js → workspace-metadata-Cu6yfxBS.js} +2 -2
  480. package/server/{workspaces-BlpbOPZ7.js → workspaces-C7LAuZfe.js} +140 -709
  481. package/sync-sources/dev-skills/pan-style-guide/SKILL.md +90 -15
  482. package/sync-sources/hooks/linear-mcp-auth-hook +6 -1
  483. package/sync-sources/rules/agent-message-delivery.md +21 -14
  484. package/sync-sources/rules/handoff-isolate-cwd.md +4 -4
  485. package/sync-sources/rules/pan-handoff-focus-limit.md +14 -5
  486. package/sync-sources/rules/ste-writing.md +17 -0
  487. package/sync-sources/rules/work-agents-via-pan.md +2 -1
  488. package/sync-sources/rules/writing-style.md +3 -2
  489. package/sync-sources/skills/{skill-creator → claude-skill-creator}/SKILL.md +1 -1
  490. package/sync-sources/skills/{skill-creator → claude-skill-creator}/scripts/init_skill.py +1 -1
  491. package/sync-sources/skills/{skill-creator → claude-skill-creator}/scripts/package_skill.py +1 -1
  492. package/sync-sources/skills/pan-gauntlet-loop/SKILL.md +230 -0
  493. package/sync-sources/skills/pan-gauntlet-loop/assets/PROMPT.template.md +92 -0
  494. package/sync-sources/skills/pan-gauntlet-loop/assets/REFERENCE-BAR.template.md +53 -0
  495. package/sync-sources/skills/pan-gauntlet-loop/assets/STYLE.template.md +41 -0
  496. package/sync-sources/skills/pan-gauntlet-loop/assets/gauntlet-index.html +237 -0
  497. package/sync-sources/skills/pan-gauntlet-loop/references/domains.md +106 -0
  498. package/sync-sources/skills/pan-handoff/SKILL.md +24 -6
  499. package/sync-sources/skills/pan-help/SKILL.md +1 -1
  500. package/sync-sources/skills/pan-peer-review/SKILL.md +3 -3
  501. package/sync-sources/skills/pan-restart/SKILL.md +6 -3
  502. package/sync-sources/skills/pan-start/SKILL.md +3 -0
  503. package/sync-sources/skills/pan-swarm/SKILL.md +32 -44
  504. package/sync-sources/skills/pan-sync/SKILL.md +1 -1
  505. package/server/activity-logger-BejO16Am.js +0 -3
  506. package/server/agent-state-DH_-Jkua.js +0 -3
  507. package/server/agents-megfmQHM.js +0 -3
  508. package/server/archive-planning-C-H9cM_J.js +0 -2
  509. package/server/build-info-PQlh_Rhb.js +0 -2
  510. package/server/cli-TaZspPHS.js +0 -2
  511. package/server/cliproxy-36ncAXlu.js +0 -3
  512. package/server/context-layers-CF6zHws4.js +0 -4
  513. package/server/conversations-AnGJ5rtX.js +0 -3
  514. package/server/deacon-BEH-IY0v.js +0 -5
  515. package/server/deacon-swarm-BHX-kR1b.js +0 -2
  516. package/server/deacon-swarm-BiLfNm_v.js +0 -1522
  517. package/server/dead-end-trip-BWpDg1Qd.js +0 -2
  518. package/server/delivery-cJM6zRjJ.js +0 -3
  519. package/server/deploy-queue-CmVBZEja.js +0 -2
  520. package/server/dist-VKBfkdi7.js +0 -3
  521. package/server/durable-review-pipeline-DgcVCYDL.js +0 -3
  522. package/server/factory-D4V2wd_V.js +0 -717
  523. package/server/forge-CrP1L3i6.js +0 -2
  524. package/server/hume-1ubD_6O7.js +0 -3
  525. package/server/inspect-agent-CfxERkNt.js +0 -2
  526. package/server/merge-ops-DtHx17Vd.js +0 -2
  527. package/server/merge-rebase-BvB4UuNS.js +0 -2
  528. package/server/project-repos-BJiShUsN.js +0 -3
  529. package/server/providers-CStNGwze.js +0 -3
  530. package/server/public/assets/index-BFEwfmqX.js +0 -860
  531. package/server/public/assets/index-_USwyTAT.css +0 -1
  532. package/server/public/assets/mermaid-GHXKKRXX-Dsln95SK.js +0 -1
  533. package/server/pull-requests-C1Cqp2yo.js +0 -2
  534. package/server/rally-CjayjUIl.js +0 -3
  535. package/server/resume-D7JuMCRQ.js +0 -3
  536. package/server/review-agent-BUNTVJK2.js +0 -2
  537. package/server/settings-DBWB1gsG.js +0 -2
  538. package/server/specialists-D8gsOCwh.js +0 -3
  539. package/server/specs-BqkrRnU9.js +0 -3
  540. package/server/stuck-remediation-Di5JYkoo.js +0 -1164
  541. package/server/stuck-remediation-TNM1VhZb.js +0 -2
  542. package/server/supervisor-DX8VsPnb.js +0 -2
  543. package/server/tmux-CqNapnrr.js +0 -4
  544. package/server/token-util-Bu8bPF9f.js +0 -3
  545. package/server/workflows-Cf4LAnhg.js +0 -2
@@ -1,58 +1,63 @@
1
- import { Bi as sessionFilePath, Fi as init_paths, Gn as init_issue_id, Ht as init_state_read_home, Mt as init_state_plane, On as resolveProjectFromIssueSync, Ot as reconcileStatePlaneDrift, Tt as init_auto_commit, Wt as resolveStateReadHomeSync, Y as init_record, Yr as FsError, _n as listProjectsAsync, et as readIssueRecordForWorkspaceSync, fn as init_projects, gi as OVERDECK_HOME, gn as listProjects, j as RECORD_DIRNAME, jt as getMainDivergence, oi as init_errors, on as getProjectSync, qn as parseIssueIdSync, si as AGENTS_DIR, tt as readIssueRecordSync, vn as listProjectsSync } from "./config-yaml-BwOEANMr.js";
2
- import { m as loadConfig$1, p as init_config } from "./config-tucKBCCc.js";
3
- import { a as emitActivityEntrySync, c as init_activity_logger, o as emitActivityTtsSync, r as emitActivityEntryOnce } from "./activity-logger-BAVLrkR7.js";
4
- import { a as recordLockPath, i as readOwner, n as init_fs_lock } from "./fs-lock-cw25uO_E.js";
5
- import { a as updateIssueRecord, i as init_record_update, n as clearRecordPipelineClosedOut } from "./record-update-D23jPU6b.js";
6
- import { A as listSessionNames, B as sessionExists, L as sendKeys, O as listPaneValues, P as querySessionSync, R as sendKeysAsync, S as init_tmux, T as killSession, V as sessionExistsSync, j as listSessions, r as capturePane, w as isPaneDead } from "./tmux-BqXzRuaH.js";
7
- import { _ as logDeaconEventSync, c as init_agents, d as removeAgentRecordSync, g as logAgentLifecycleSync, h as init_persistent_logger, m as isTerminalIssueStage, p as getIssueStageSync, u as listAllAgentsSync } from "./agents-CqQJW75N.js";
8
- import { A as setAgentPausedSync, Bn as tryReserveAdvancingSlot, C as recordAgentFailure, D as saveAgentState, E as resetAgentFailureCount, Fn as getConcurrencyLimits, G as init_agents$1, H as getAgentRuntimeStateSync, Hn as workResumeSlotsAvailable, In as init_concurrency, It as isContextOverflowTail, Ln as releaseAdvancingSlot, Lr as hasAgentRuntimeInSubtree, Lt as init_messaging, Nn as describeRunningAgents, Nt as resumeAgent, O as saveAgentStateSync, Pt as init_context_overflow, Qn as deliverInitialPromptWithRetry, Rr as init_runtime_command, Rt as messageAgent, Un as init_swarm_slot_lifecycle, W as saveAgentRuntimeState, Wn as isTerminalSwarmSlotAgent, _n as removeAgentStateDir, ar as init_transcript_landing, c as clearYieldForResumeSync, ci as buildResumeContinueMessage, cn as listAgentStates, f as getAgentState, fn as RETAINED_TRANSCRIPTS_MARKER, fr as init_codex_auth, h as init_agent_state, in as stopAgent, ir as captureTranscriptUserRecordSnapshot, j as setAgentYieldedSync, jn as countRunningAgents, ln as listRunningAgents, m as getAgentStateSync, mn as init_state_dir_removal, mr as paneShowsCodexAuthBurn, pr as isCodexAuthRouted, s as clearAgentTroubledSync, u as getAgentDir, un as listRunningAgentsSync, ur as applyCodexAuthBurnFlag, y as markAgentRunningState, zn as resetPatrolDispatchBudget } from "./agent-state-Bb3UUxQm.js";
9
- import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-zY75jrRJ.js";
10
- import { N as listConversations, j as listArchivedConversations, k as init_conversations } from "./conversations-DhwxsOru.js";
11
- import { O as stampBootReconciliation, _ as setBootReconciliationGrace, c as init_control_settings, g as setBootReconciliationDecision, o as getLastCleanShutdownAt, r as getBootReconciliationState, u as isDeaconGloballyPaused } from "./control-settings-5k6ixdFW.js";
12
- import { d as PENDING_PROMOTION_FILENAME, f as WORKSPACE_RUNTIME_DIRNAME, m as init_types } from "./types-DbxY2QB6.js";
13
- import { C as init_specs, S as findSpecByIssue, f as readPlanSync, h as readWorkspacePlanSync, o as findWorkspaceDraftPlanSync, s as init_io } from "./io-DfvO2xyh.js";
14
- import { l as init_dag, o as getDispatchableItems } from "./dag-DI9LaK_q.js";
15
- import { a as loadCloisterConfigSync, r as init_config$1 } from "./config-DC75T4Mr.js";
16
- import { a as init_state_home, o as inspectLegacyStatePaths } from "./state-home-DhAZlk5k.js";
17
- import { l as init_review_status_sync, u as markWorkspaceStuck } from "./review-status-sync-B7V_Gg51.js";
18
- import { B as needsReviewDispatch, G as findBlockingFindings, J as findWorkspaceVerdictConflicts, K as init_review_findings, Q as readWorkspaceVerdictFallback, Y as init_review_status_record_sync, d as getReviewStatusSync, h as loadReviewStatuses, p as init_review_status, q as drainWorkspaceVerdictFallback, w as setReviewStatusSync, z as init_review_dispatch_decision } from "./review-status-DBnR5t4z.js";
19
- import { d as init_review_verdict_report, f as parseVerdictReport, l as findVerdictReport, u as findVerdictReportAsync } from "./synthesis-verdict-N5Z11pg7.js";
20
- import { t as assessMemoryPressure } from "./memory-governor-A4O6vI9d.js";
21
- import { a as getAgentEffectiveLastActivityMs, o as isAgentIdleForNudge, t as checkStuckAgentRemediation } from "./stuck-remediation-Di5JYkoo.js";
22
- import { n as pruneTerminalStoppedAgents, r as pidsWithCwdUnder } from "./agent-gc-5E0lgxI1.js";
23
- import { t as recordDeaconNudge } from "./deacon-nudge-log-BtlTWgWu.js";
24
- import { a as readLiveTrackerIssueState, n as init_issue_closed, r as isIssueClosed } from "./issue-closed-dvEWKO7Q.js";
25
- import { t as getAutoCloseOutCanonicalState } from "./deacon-canonical-state-DFYymrDw.js";
26
- import { a as ciRetryMap, c as reconcileMergedButReviewing, d as reconcileStuckReadyForMerge, f as reconcileAutoMergeRows, i as checkReadyForMergeStuck$1, l as reconcileStaleMergeBlockers, n as checkFailedMergeRetry, o as reconcileClosedPrReadyForMerge, p as reconcileStuckMergingStates, r as checkFirstCompletionAgents, s as reconcileFalseMerged, t as autoCloseOut, u as reconcileStaleMergeStatus } from "./deacon-merge-BOGFEV8_.js";
27
- import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-D4ULO4qG.js";
28
- import { r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-Ci6N5p4G.js";
29
- import { t as recordReviewVerdict } from "./review-verdict-writer-CKaJWp75.js";
30
- import { a as observeActiveReviewArtifact, i as convergeRowFromVerdictOfRecord, n as reviewTimestampMs, r as REVIEW_SUB_ROLES, t as evaluateReviewConvoyLiveness } from "./review-convoy-liveness-DfF9eXjI.js";
31
- import { J as parseReviewerSessionName, U as getTmuxSessionName, g as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-8LcQi9Np.js";
32
- import { a as inferBranchFromWorkspace, i as findWorkspacePath } from "./archive-planning-BwEhu9Oq.js";
33
- import { n as shouldSkipDispatchAsMerged } from "./merge-verification-BRp08IzI.js";
34
- import { t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-C-dBon_-.js";
35
- import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-A5k54mCv.js";
36
- import { g as decideAgentAutonomousRedrive, r as coordinateSwarmSlots, y as listFeatureWorkspaces } from "./deacon-swarm-BiLfNm_v.js";
37
- import { i as recordRecoveryFailure, n as findRecoveryTrip, r as init_recovery_trip } from "./recovery-trip-C4dTl8DO.js";
38
- import { t as isExplicitNoResumeRequest } from "./no-resume-mode-MWI6pnrK.js";
39
- import { t as createInFlightGuard } from "./in-flight-guard-pcwXKLGz.js";
40
- import { r as reconcileClosedIssueAgents } from "./closed-issue-reaper-bFppuk6F.js";
41
- import { b as reconcilePipelineLabelsPatrol, y as init_label_reconciler } from "./pipeline-membership-gather-CGFY1v-y.js";
42
- import { t as recordDeadEndNeedsYou } from "./dead-end-trip-P0IF1O0E.js";
43
- import { a as triggerRebuildAndStart, i as reconcileOrphanProposedSpecs } from "./orphan-proposed-reconciler-cV3URUqk.js";
44
- import { n as spawnWorkAgentThroughAgentsEndpoint } from "./work-agent-start-BNQO65W7.js";
45
- import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-BeU_KxWx.js";
46
- import { a as recordUnsignaledTestEscalation, i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-BWtRmdiR.js";
47
- import { dirname, join } from "node:path";
1
+ import { E as init_tier_table, It as isStatePlaneOnlyStatus, J as getProjectConfigFromWorkspacePath, K as getIssueRecordPathForWorkspace, Mt as init_state_plane, O as resolveTieredExecutionEnabled, On as resolveProjectFromIssueSync, Ot as reconcileStatePlaneDrift, Qr as FsError, Tt as init_auto_commit, Wi as sessionFilePath, Y as init_record, Yn as parseIssueIdSync, _n as listProjectsAsync, et as readIssueRecordForWorkspaceSync, fn as init_projects, gn as listProjects, jt as getMainDivergence, li as init_errors, on as getProjectSync, p as loadConfigSync, qn as init_issue_id, rt as resolveProjectForIssue, t as init_config_yaml, tt as readIssueRecordSync, ui as AGENTS_DIR, vn as listProjectsSync, yi as OVERDECK_HOME, zi as init_paths } from "./config-yaml-D60AnTIu.js";
2
+ import { m as loadConfig$1, p as init_config } from "./config-NxI9Yl2f.js";
3
+ import { i as emitActivityEntryOnce, l as init_activity_logger, o as emitActivityEntrySync, s as emitActivityTtsSync } from "./activity-logger-SlTXYCVf.js";
4
+ import { a as recordLockPath, i as readOwner, n as init_fs_lock } from "./fs-lock-DQ_gUxfq.js";
5
+ import { a as updateIssueRecord, i as init_record_update, n as clearRecordPipelineClosedOut, o as updateIssueRecordForWorkspace } from "./record-update-BPqpBu3O.js";
6
+ import { B as sendKeys, C as init_tmux, E as killSession, I as querySessionSync, M as listSessionNamesSync, N as listSessions, T as isPaneDead, U as sessionExists, V as sendKeysAsync, W as sessionExistsSync, j as listSessionNames, k as listPaneValues, r as capturePane, v as getManagedTmuxSocketName } from "./tmux-wnT_hg-s.js";
7
+ import { _ as logDeaconEventSync, c as init_agents, d as removeAgentRecordSync, g as logAgentLifecycleSync, h as init_persistent_logger, m as isTerminalIssueStage, p as getIssueStageSync, u as listAllAgentsSync } from "./agents-DzpQidT8.js";
8
+ import { O as stampBootReconciliation, _ as setBootReconciliationGrace, c as init_control_settings, d as isDeaconGloballyPausedSync, g as setBootReconciliationDecision, o as getLastCleanShutdownAt, r as getBootReconciliationState, u as isDeaconGloballyPaused } from "./control-settings-Db0uXgVM.js";
9
+ import { $ as deliverCommitForReview, $n as isTerminalSwarmSlotAgent, A as saveAgentStateSync, Ai as getAgentRuntimeSnapshot, Bn as countRunningAgents, Cn as init_state_dir_removal, Cr as paneShowsCodexAuthBurn, Dr as init_spawn_prep, En as removeAgentStateDir, Er as defaultRunWorkspace, Fr as init_resolve_tier, Ft as resumeAgent, Gn as init_concurrency, Hn as describeRunningAgents, Ht as init_messaging, Ir as resolveTier, Jn as resetPatrolDispatchBudget, K as saveAgentRuntimeState, Kn as releaseAdvancingSlot, Kr as hasAgentRuntimeInSubtree, M as setAgentPausedSync, N as setAgentYieldedSync, O as resetAgentFailureCount, Qn as init_swarm_slot_lifecycle, Sr as isCodexAuthRouted, T as recordAgentFailure, Ut as messageAgent, Vn as countRunningSwarmSlotsForIssue, Vt as isContextOverflowTail, W as getAgentRuntimeStateSync, Wn as getConcurrencyLimits, Xn as tryReserveSwarmSlot, Yn as tryReserveAdvancingSlot, Zn as workResumeSlotsAvailable, _ as init_agent_state, _i as buildResumeContinueMessage, _n as listAgentStates, _t as init_pending_decision_gate, an as init_spawn, at as broadcastCommit, cn as ensureRegisteredSlotWorktree, d as decideResumeGate, dt as reconcileSlotState, er as getCachedMemoryVerdict, et as init_tier_supervisor, f as getAgentDir, fn as init_termination, g as getAgentStateSync, gt as detectPendingOperatorDecision, it as supervisorAgentId, ji as init_agent_runtime, k as saveAgentState, l as clearAgentTroubledSync, ln as init_registered_slot_spawn, lt as init_slot_reconcile, m as getAgentState, mr as init_transcript_landing, nt as shouldSupervise, ot as init_tier_feed, p as getAgentResumeGateBlockReason, pn as stopAgent, pr as captureTranscriptUserRecordSnapshot, q as init_agents$1, qn as releaseSwarmSlot, qr as init_runtime_command, rt as spawnTierSupervisor, sn as spawnRun, sr as deliverInitialPromptWithRetry, tr as init_memory_verdict_cache, tt as loadPrdDraft, u as clearYieldForResumeSync, ut as listSlotAssignments, vn as listRunningAgents, x as markAgentRunningState, xn as RETAINED_TRANSCRIPTS_MARKER, xr as init_codex_auth, yn as listRunningAgentsSync, yr as applyCodexAuthBurnFlag, zt as init_context_overflow } from "./agent-state-FABw8neJ.js";
10
+ import { i as ensureInternalTokenSync, o as getInternalTokenSync, s as init_internal_token, t as INTERNAL_TOKEN_HEADER } from "./internal-token-BeIWG_kT.js";
11
+ import { A as init_conversations, M as listArchivedConversations, P as listConversations } from "./conversations-nS6QgYpD.js";
12
+ import { d as PENDING_PROMOTION_FILENAME, f as WORKSPACE_RUNTIME_DIRNAME, m as init_types } from "./types-pLpbsNto.js";
13
+ import { C as init_specs, S as findSpecByIssue, b as subItemsOf, f as readPlanSync, h as readWorkspacePlanSync, i as findPlanSync, n as applyStatusOverrides, o as findWorkspaceDraftPlanSync, s as init_io, y as init_types$1 } from "./io-BCtZoXHo.js";
14
+ import { a as getDispatchableItems, c as init_dag } from "./dag-o-dUpw1L.js";
15
+ import { a as loadCloisterConfigSync, r as init_config$1 } from "./config-_qaa1UXH.js";
16
+ import { a as init_state_home, o as inspectLegacyStatePaths } from "./state-home-DhsMqg8W.js";
17
+ import { d as resolveWorkspaceRepoRootsSync, i as init_project_repos, u as resolveSlotWorkspaceWorktreesSync } from "./project-repos-CsfvLtmr.js";
18
+ import { r as init_swarm_readiness, t as analyzeSwarmReadiness } from "./swarm-readiness-LF8ZF_hc.js";
19
+ import { l as init_review_status_sync, u as markWorkspaceStuck } from "./review-status-sync-C6ZKTI8f.js";
20
+ import { B as needsReviewDispatch, G as findBlockingFindings, J as findWorkspaceVerdictConflicts, K as init_review_findings, Q as readWorkspaceVerdictFallback, Y as init_review_status_record_sync, d as getReviewStatusSync, h as loadReviewStatuses, p as init_review_status, q as drainWorkspaceVerdictFallback, w as setReviewStatusSync, z as init_review_dispatch_decision } from "./review-status-DpniqzPT.js";
21
+ import { d as init_review_verdict_report, f as parseVerdictReport, l as findVerdictReport, u as findVerdictReportAsync } from "./synthesis-verdict-CGFF8uQI.js";
22
+ import { t as assessMemoryPressure } from "./memory-governor-Cvv_9K0M.js";
23
+ import { r as isAgentIdleForNudge, t as getAgentEffectiveLastActivityMs } from "./agent-idle-D-UQ7gDv.js";
24
+ import { n as pruneTerminalStoppedAgents, r as pidsWithCwdUnder } from "./agent-gc-bhikjoJ_.js";
25
+ import { t as recordDeaconNudge } from "./deacon-nudge-log-pcliw8Dr.js";
26
+ import { a as readLiveTrackerIssueState, n as init_issue_closed, r as isIssueClosed } from "./issue-closed-CiYAa6bX.js";
27
+ import { t as getAutoCloseOutCanonicalState } from "./deacon-canonical-state-DkdkQS5p.js";
28
+ import { a as checkFailedMergeRetry, c as ciRetryMap, d as reconcileMergedButReviewing, f as reconcileStaleMergeBlockers, g as reconcileStuckMergingStates, h as reconcileAutoMergeRows, i as autoCloseOut, l as reconcileClosedPrReadyForMerge, m as reconcileStuckReadyForMerge, n as reconcileTerminalIssueResidue, o as checkFirstCompletionAgents, p as reconcileStaleMergeStatus, r as listIssueRecords, s as checkReadyForMergeStuck$1, u as reconcileFalseMerged } from "./parked-residue-8WbU0y1z.js";
29
+ import { a as writeFeedbackFile, i as init_feedback_writer } from "./feedback-writer-Ds1Wjsz4.js";
30
+ import { r as surfaceIssueFeedbackNeedsYou, t as init_feedback_target } from "./feedback-target-yPD_wclF.js";
31
+ import { t as recordReviewVerdict } from "./review-verdict-writer-Cy_1pnIj.js";
32
+ import { a as observeActiveReviewArtifact, i as convergeRowFromVerdictOfRecord, n as reviewTimestampMs, r as REVIEW_SUB_ROLES, t as evaluateReviewConvoyLiveness } from "./review-convoy-liveness-BBvyuRLC.js";
33
+ import { g as getAllProjectSpecialistStatuses, t as init_specialists } from "./specialists-D6MUU31Q.js";
34
+ import { m as parseReviewerSessionName, s as getTmuxSessionName } from "./specialists-registry-Bng0OFGH.js";
35
+ import { a as inferBranchFromWorkspace, i as findWorkspacePath } from "./archive-planning-BL1ABtW0.js";
36
+ import { n as shouldSkipDispatchAsMerged } from "./merge-verification-BfJRNMiD.js";
37
+ import { t as deliverReviewVerdictFeedback } from "./review-verdict-feedback-B2ojHFH5.js";
38
+ import { n as reconcileTraefikNetworks, t as init_traefik_connect } from "./traefik-connect-DoQvQ6oJ.js";
39
+ import { i as recordRecoveryFailure, n as findRecoveryTrip, r as init_recovery_trip } from "./recovery-trip-CpfW6LCJ.js";
40
+ import { a as init_work_agent_prompt, n as buildWorkAgentPrompt } from "./work-agent-prompt-CaD2ue8m.js";
41
+ import { t as isExplicitNoResumeRequest } from "./no-resume-mode-DjMQRkId.js";
42
+ import { t as createInFlightGuard } from "./in-flight-guard-B7khcBdQ.js";
43
+ import { t as checkStuckAgentRemediation } from "./stuck-remediation-kta3KN7c.js";
44
+ import { r as reconcileClosedIssueAgents } from "./closed-issue-reaper-CdcJRvUx.js";
45
+ import { b as reconcilePipelineLabelsPatrol, y as init_label_reconciler } from "./pipeline-membership-gather-Ba0wJNCR.js";
46
+ import { t as recordDeadEndNeedsYou } from "./dead-end-trip-Bs3hxIn6.js";
47
+ import { a as triggerRebuildAndStart, i as reconcileOrphanProposedSpecs } from "./orphan-proposed-reconciler-nFUlquZt.js";
48
+ import { n as spawnWorkAgentThroughAgentsEndpoint } from "./work-agent-start-0nJ-6UeA.js";
49
+ import { n as reconcileIdleWorkspaceStacks } from "./idle-stack-reaper-DtoI4al6.js";
50
+ import { a as recordUnsignaledTestEscalation, i as readTestVerdictArtifact, n as decideUnsignaledTestAction, r as init_test_verdict } from "./test-verdict-oNSv1rVr.js";
51
+ import { basename, dirname, join, relative, resolve } from "node:path";
48
52
  import { Effect } from "effect";
49
53
  import { appendFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "fs";
50
54
  import { basename as basename$1, dirname as dirname$1, join as join$1 } from "path";
51
55
  import { cpus, loadavg } from "os";
52
- import { existsSync as existsSync$1, promises as promises$1, readFileSync as readFileSync$1 } from "node:fs";
56
+ import { hostname } from "node:os";
57
+ import { existsSync as existsSync$1, readFileSync as readFileSync$1 } from "node:fs";
53
58
  import { access, mkdir, readFile, readdir, rename, rm, rmdir, stat, writeFile } from "node:fs/promises";
54
59
  import { readdir as readdir$1 } from "fs/promises";
55
- import { execFile, execFileSync } from "node:child_process";
60
+ import { exec, execFile, execFileSync } from "node:child_process";
56
61
  import { promisify } from "node:util";
57
62
  import { exec as exec$1, execFile as execFile$1 } from "child_process";
58
63
  import { promisify as promisify$1 } from "util";
@@ -61,10 +66,11 @@ init_paths();
61
66
  init_errors();
62
67
  init_issue_id();
63
68
  init_projects();
64
- init_state_read_home();
65
69
  init_state_plane();
66
70
  init_auto_commit();
67
71
  init_record();
72
+ init_tier_table();
73
+ init_config_yaml();
68
74
  init_config();
69
75
  init_activity_logger();
70
76
  init_fs_lock();
@@ -73,19 +79,36 @@ init_tmux();
73
79
  init_persistent_logger();
74
80
  init_agents();
75
81
  init_internal_token();
82
+ init_agent_runtime();
76
83
  init_conversations();
77
84
  init_runtime_command();
85
+ init_control_settings();
78
86
  init_types();
79
87
  init_specs();
88
+ init_types$1();
80
89
  init_io();
90
+ init_dag();
91
+ init_resolve_tier();
92
+ init_spawn_prep();
81
93
  init_codex_auth();
82
94
  init_transcript_landing();
83
95
  init_config$1();
96
+ init_memory_verdict_cache();
84
97
  init_swarm_slot_lifecycle();
85
98
  init_concurrency();
86
99
  init_state_dir_removal();
100
+ init_state_home();
101
+ init_termination();
102
+ init_project_repos();
103
+ init_registered_slot_spawn();
104
+ init_spawn();
87
105
  init_messaging();
88
106
  init_context_overflow();
107
+ init_pending_decision_gate();
108
+ init_swarm_readiness();
109
+ init_slot_reconcile();
110
+ init_tier_feed();
111
+ init_tier_supervisor();
89
112
  init_agents$1();
90
113
  init_agent_state();
91
114
  init_review_status_sync();
@@ -142,7 +165,7 @@ async function checkInspectAgentTimeouts(now = /* @__PURE__ */ new Date()) {
142
165
  console.warn(`[deacon] Failed to kill inspect session ${sessionName}: ${msg}`);
143
166
  });
144
167
  try {
145
- const { messageAgent } = await import("./agents-megfmQHM.js");
168
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
146
169
  await messageAgent(`agent-${issueId.toLowerCase()}`, verdict, "deacon:inspect-watchdog");
147
170
  } catch (err) {
148
171
  const msg = err instanceof Error ? err.message : String(err);
@@ -182,12 +205,12 @@ function paneShowsModelSwitch(pane, launchModel) {
182
205
  }
183
206
  return Boolean(target && target.toLowerCase() !== launchModel.toLowerCase());
184
207
  }
185
- const defaultDeps$3 = {
208
+ const defaultDeps$7 = {
186
209
  capturePane: (agentId) => Effect.runPromise(capturePane(agentId, 100)),
187
210
  sendKey: (agentId, key) => sendKeysAsync(agentId, key, "known-modal-handler"),
188
211
  settle: () => new Promise((resolve) => setTimeout(resolve, 300))
189
212
  };
190
- async function handleKnownAgentModal(agentId, deps = defaultDeps$3, initialPane) {
213
+ async function handleKnownAgentModal(agentId, deps = defaultDeps$7, initialPane) {
191
214
  const pane = initialPane ?? await deps.capturePane(agentId);
192
215
  const modal = KNOWN_AGENT_MODALS.find((candidate) => candidate.matches(pane));
193
216
  if (!modal) return "none";
@@ -280,7 +303,7 @@ const apiErrorRecoveryState = /* @__PURE__ */ new Map();
280
303
  * backend's own limit produces a hard 400 instead.
281
304
  */
282
305
  /** Continuation nudge sent after a successful harness /compact (specialist/planning sessions). */
283
- const CONTEXT_OVERFLOW_CONTINUE_MSG = "Your context was compacted to recover from a context-window overflow. Continue from where you left off using the compacted summary and your beads / continue.json — do NOT start over.";
306
+ const CONTEXT_OVERFLOW_CONTINUE_MSG = "Your context was compacted to recover from a context-window overflow. Continue from where you left off using the compacted summary and your xBRIEF items / continue.json — do NOT start over.";
284
307
  /**
285
308
  * Let a recovery attempt finish before judging the result. MUST exceed the
286
309
  * patrol interval (60s): at exactly one interval the guard expires on the very
@@ -405,9 +428,9 @@ async function checkApiErrorAgents() {
405
428
  }
406
429
  if (!tmuxOutput.includes("❯")) continue;
407
430
  try {
408
- const { maybeContinueCompactedAgent } = await import("./compaction-continuation-D5voR1ME.js");
409
- const { findLastCompactBoundary } = await import("./conversation-service-BxrB5lUT.js");
410
- const { deliverAgentMessage } = await import("./delivery-cJM6zRjJ.js");
431
+ const { maybeContinueCompactedAgent } = await import("./compaction-continuation-CVjbdGKt.js");
432
+ const { findLastCompactBoundary } = await import("./conversation-service-BL-asWPX.js");
433
+ const { deliverAgentMessage } = await import("./delivery-DhZGRShH.js");
411
434
  const continued = await maybeContinueCompactedAgent({
412
435
  agentId: sessionName,
413
436
  tmuxOutput,
@@ -458,13 +481,13 @@ async function checkApiErrorAgents() {
458
481
  const st = getAgentStateSync(sessionName);
459
482
  const sid = st?.sessionId ?? runtimeState?.claudeSessionId;
460
483
  if (st?.workspace && sid && st.model) {
461
- const { computeContextUsage } = await import("./conversation-service-BxrB5lUT.js");
484
+ const { computeContextUsage } = await import("./conversation-service-BL-asWPX.js");
462
485
  const usage = await computeContextUsage(sessionFilePath(st.workspace, sid), st.model);
463
486
  if (usage && usage.percentUsed < 85) recoveredPct = usage.percentUsed;
464
487
  }
465
488
  } catch {}
466
489
  if (recoveredPct !== null) {
467
- const { clearWorkspaceStuck } = await import("./review-status-sync-YthpOH_q.js");
490
+ const { clearWorkspaceStuck } = await import("./review-status-sync-CvpHWyvR.js");
468
491
  clearWorkspaceStuck(issueId);
469
492
  stuckOverflowNativeRecoveryState.delete(sessionName);
470
493
  actions.push(`Context overflow recovery: cleared stuck flag for ${sessionName} (context back to ${Math.round(recoveredPct)}%)`);
@@ -480,7 +503,7 @@ async function checkApiErrorAgents() {
480
503
  rec.attempts += 1;
481
504
  rec.lastAttempt = now;
482
505
  stuckOverflowNativeRecoveryState.set(sessionName, rec);
483
- const { resumeAgent } = await import("./agents-megfmQHM.js");
506
+ const { resumeAgent } = await import("./agents-DixZjXWm.js");
484
507
  const recovered = await resumeAgent(sessionName, void 0, { compact: true });
485
508
  if (recovered.success) {
486
509
  stuckOverflowNativeRecoveryState.delete(sessionName);
@@ -528,7 +551,7 @@ async function checkApiErrorAgents() {
528
551
  }
529
552
  const compactAttempts = (ov?.compactAttempts ?? 0) + 1;
530
553
  if (issueId !== null) {
531
- const { resumeAgent } = await import("./agents-megfmQHM.js");
554
+ const { resumeAgent } = await import("./agents-DixZjXWm.js");
532
555
  const resumeResult = await resumeAgent(sessionName, void 0, { compact: true });
533
556
  contextOverflowRecoveryState.set(sessionName, {
534
557
  lastAttempt: now,
@@ -783,7 +806,7 @@ async function checkPostReviewCommits() {
783
806
  const actions = [];
784
807
  try {
785
808
  const statuses = loadReviewStatuses();
786
- const { resolveProjectFromIssueSync } = await import("./projects-DvPEAP18.js");
809
+ const { resolveProjectFromIssueSync } = await import("./projects-BMuEf14J.js");
787
810
  for (const [issueId, status] of Object.entries(statuses)) {
788
811
  const isBlocked = status.reviewStatus === "blocked";
789
812
  if (!isBlocked) blockedReviewDriftObservations.delete(issueId);
@@ -815,8 +838,8 @@ async function checkPostReviewCommits() {
815
838
  if (!project) continue;
816
839
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
817
840
  if (!existsSync(workspacePath)) continue;
818
- const { formatAnchorShort, rehydrateHeadAnchor } = await import("./git-utils-Y0zG25ez.js");
819
- const { evaluateWorkspaceAnchorDrift } = await import("./workspace-anchor-drift-DTt6h2Em.js");
841
+ const { formatAnchorShort, rehydrateHeadAnchor } = await import("./git-utils-BAMwn9Nf.js");
842
+ const { evaluateWorkspaceAnchorDrift } = await import("./workspace-anchor-drift-Bpa3xoni.js");
820
843
  const verdict = await evaluateWorkspaceAnchorDrift(issueId, workspacePath, rehydrateHeadAnchor(reviewedAnchor));
821
844
  if (verdict.kind === "unreadable" || verdict.kind === "current") {
822
845
  blockedReviewDriftObservations.delete(issueId);
@@ -834,7 +857,7 @@ async function checkPostReviewCommits() {
834
857
  resetLoopEscalated.add(issueId);
835
858
  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.`;
836
859
  logDeaconEventSync(`checkPostReviewCommits: ${message}`);
837
- const { recordDeadEndNeedsYou } = await import("./dead-end-trip-BWpDg1Qd.js");
860
+ const { recordDeadEndNeedsYou } = await import("./dead-end-trip-DUbiRMtT.js");
838
861
  await recordDeadEndNeedsYou(issueId, "review-reset-loop", currentHead, message);
839
862
  }
840
863
  continue;
@@ -878,7 +901,7 @@ async function checkPostReviewCommits() {
878
901
  actions.push(`Deferred post-review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
879
902
  logDeaconEventSync(`checkPostReviewCommits: deferred review for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
880
903
  } else if (freshStatus?.reviewStatus === "pending") {
881
- const { spawnReviewRoleForIssue } = await import("./review-agent-BUNTVJK2.js");
904
+ const { spawnReviewRoleForIssue } = await import("./review-agent-Caodi0PX.js");
882
905
  const branch = `feature/${issueId.toLowerCase()}`;
883
906
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
884
907
  issueId,
@@ -920,7 +943,7 @@ async function checkPostReviewCommits() {
920
943
  * of life regardless of tmux. The deacon's liveness arbiter consults this
921
944
  * before declaring an agent orphaned.
922
945
  */
923
- const execFileAsync$4 = promisify(execFile);
946
+ const execFileAsync$5 = promisify(execFile);
924
947
  const defaultPgrep = (pattern) => {
925
948
  try {
926
949
  execFileSync("pgrep", ["-f", pattern], { stdio: [
@@ -935,7 +958,7 @@ const defaultPgrep = (pattern) => {
935
958
  };
936
959
  const defaultAsyncPgrep = async (pattern) => {
937
960
  try {
938
- await execFileAsync$4("pgrep", ["-f", pattern], { encoding: "utf8" });
961
+ await execFileAsync$5("pgrep", ["-f", pattern], { encoding: "utf8" });
939
962
  return true;
940
963
  } catch (error) {
941
964
  if (typeof error === "object" && error !== null && "code" in error && error.code === 1) return false;
@@ -962,7 +985,7 @@ init_review_status();
962
985
  init_tmux();
963
986
  init_feedback_writer();
964
987
  init_feedback_target();
965
- const execFileAsync$3 = promisify(execFile);
988
+ const execFileAsync$4 = promisify(execFile);
966
989
  function internalDashboardUrl() {
967
990
  const port = Number.parseInt(process.env.API_PORT ?? process.env.PORT ?? "3011", 10);
968
991
  return process.env.OVERDECK_INTERNAL_DASHBOARD_URL ?? `http://127.0.0.1:${port}`;
@@ -1042,14 +1065,14 @@ async function defaultIsStrikeAgentAlive(agentId) {
1042
1065
  return true;
1043
1066
  }
1044
1067
  }
1045
- function defaultDeps$2() {
1068
+ function defaultDeps$6() {
1046
1069
  return {
1047
1070
  loadStatuses: loadReviewStatuses,
1048
1071
  getStatus: getReviewStatusSync,
1049
1072
  setStatus: setReviewStatusSync,
1050
1073
  resolveProject: resolveProjectFromIssueSync,
1051
1074
  mergeIssue: requestStrikeMerge,
1052
- getMainHead: async (projectPath) => (await execFileAsync$3("git", ["rev-parse", "origin/main"], {
1075
+ getMainHead: async (projectPath) => (await execFileAsync$4("git", ["rev-parse", "origin/main"], {
1053
1076
  cwd: projectPath,
1054
1077
  encoding: "utf8"
1055
1078
  })).stdout.trim(),
@@ -1071,7 +1094,7 @@ function defaultDeps$2() {
1071
1094
  isScheduled: (key) => strikeLandingSupervisor.has(key),
1072
1095
  isPersistentlyOwned: () => false,
1073
1096
  listProjects: listProjectsAsync,
1074
- git: async (args, cwd) => (await execFileAsync$3("git", args, {
1097
+ git: async (args, cwd) => (await execFileAsync$4("git", args, {
1075
1098
  cwd,
1076
1099
  encoding: "utf8"
1077
1100
  })).stdout.trim(),
@@ -1273,7 +1296,7 @@ async function salvageStrandedStrikeBranches(deps) {
1273
1296
  }
1274
1297
  async function patrolStrikeLandings(overrides = {}) {
1275
1298
  const deps = {
1276
- ...defaultDeps$2(),
1299
+ ...defaultDeps$6(),
1277
1300
  ...overrides
1278
1301
  };
1279
1302
  const actions = await salvageStrandedStrikeBranches(deps);
@@ -1450,7 +1473,7 @@ function reviewConvoyLiveness(issueId) {
1450
1473
  */
1451
1474
  async function recoverUnhealthyTestStack(issueId, workspacePath) {
1452
1475
  const key = issueId.toUpperCase();
1453
- const { getWorkspaceStackHealth } = await import("./stack-health-CbyiYS9H.js");
1476
+ const { getWorkspaceStackHealth } = await import("./stack-health-Bz711z1Y.js");
1454
1477
  const health = await Effect.runPromise(getWorkspaceStackHealth(issueId, { workspacePath }));
1455
1478
  if (health.healthy) {
1456
1479
  testStackRebuildState.delete(key);
@@ -1482,7 +1505,7 @@ async function recoverUnhealthyTestStack(issueId, workspacePath) {
1482
1505
  record.attempts += 1;
1483
1506
  testStackRebuildState.set(key, record);
1484
1507
  console.log(`[deacon] Test stack for ${key} unhealthy (${health.reasons.join("; ")}) — rebuilding (attempt ${record.attempts}/${TEST_STACK_REBUILD_MAX_ATTEMPTS})`);
1485
- const { rebuildWorkspaceStack } = await import("./rebuild-stack-CCwKHZb6.js");
1508
+ const { rebuildWorkspaceStack } = await import("./rebuild-stack-BcBVFJp3.js");
1486
1509
  const result = await Effect.runPromise(rebuildWorkspaceStack(issueId, { onProgress: (m) => console.log(`[deacon] ${key} stack rebuild: ${m}`) }));
1487
1510
  if (!result.success) {
1488
1511
  console.warn(`[deacon] Test stack rebuild failed for ${key}: ${result.error}`);
@@ -1668,7 +1691,7 @@ async function handleReviewCoordinatorDied(issueId, _sessionName, _reason) {
1668
1691
  return actions;
1669
1692
  }
1670
1693
  try {
1671
- const { spawnReviewRoleForIssue } = await import("./review-agent-BUNTVJK2.js");
1694
+ const { spawnReviewRoleForIssue } = await import("./review-agent-Caodi0PX.js");
1672
1695
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
1673
1696
  issueId,
1674
1697
  workspace,
@@ -1743,7 +1766,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
1743
1766
  const issueLower = issueId.toLowerCase();
1744
1767
  const workspace = getAgentStateSync(`agent-${issueLower}`)?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
1745
1768
  if (workspace) try {
1746
- if ((options.readWorkspaceHead ? await options.readWorkspaceHead(workspace) : await (await import("./git-utils-Y0zG25ez.js")).snapshotWorkspaceHeadsPromise(issueId, workspace)) === status.lastVerifiedCommit) {
1769
+ if ((options.readWorkspaceHead ? await options.readWorkspaceHead(workspace) : await (await import("./git-utils-BAMwn9Nf.js")).snapshotWorkspaceHeadsPromise(issueId, workspace)) === status.lastVerifiedCommit) {
1747
1770
  setReviewStatusSync(issueId, {
1748
1771
  reviewStatus: "pending",
1749
1772
  reviewNotes: void 0
@@ -1765,7 +1788,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
1765
1788
  if (project) {
1766
1789
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
1767
1790
  if (existsSync(workspacePath)) {
1768
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-Y0zG25ez.js");
1791
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-BAMwn9Nf.js");
1769
1792
  reviewUpdate["reviewedAtCommit"] = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);
1770
1793
  }
1771
1794
  }
@@ -1827,7 +1850,7 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
1827
1850
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
1828
1851
  if (workspace && resolved && !tryReserveAdvancingSlot() && !await tryYieldForAdvancingDispatch("review", issueId)) actions.push(`Deferred review re-dispatch for ${issueId} — advancing-role concurrency ceiling reached`);
1829
1852
  else if (workspace && resolved) try {
1830
- const { spawnReviewRoleForIssue } = await import("./review-agent-BUNTVJK2.js");
1853
+ const { spawnReviewRoleForIssue } = await import("./review-agent-Caodi0PX.js");
1831
1854
  const dispatchResult = await Effect.runPromise(spawnReviewRoleForIssue({
1832
1855
  issueId,
1833
1856
  workspace,
@@ -1852,8 +1875,8 @@ async function reconcileReviewStatusOrphan(issueId, rawStatus, options = {}) {
1852
1875
  const workspace = agentState?.workspace || (resolved ? findWorkspacePath(resolved.projectPath, issueLower) : null);
1853
1876
  if (workspace && resolved) {
1854
1877
  const branch = `feature/${issueLower}`;
1855
- const { spawnRun } = await import("./agents-megfmQHM.js");
1856
- const { buildTestRolePrompt } = await import("./test-agent-queue-BUtWhNcc.js");
1878
+ const { spawnRun } = await import("./agents-DixZjXWm.js");
1879
+ const { buildTestRolePrompt } = await import("./test-agent-queue-Cu0D6BYe.js");
1857
1880
  const stackRecovery = await recoverUnhealthyTestStack(issueId, workspace);
1858
1881
  if (stackRecovery === "cooldown" || stackRecovery === "exhausted") {
1859
1882
  setReviewStatusSync(issueId, { testStatus: "dispatch_failed" });
@@ -1992,7 +2015,7 @@ async function recoverStalledReviewConvoys(getCanonicalState = getAutoCloseOutCa
1992
2015
  record.lastAttempt = now;
1993
2016
  record.attempts += 1;
1994
2017
  stalledReviewConvoyRecoveryState.set(key, record);
1995
- const { spawnReviewRoleForIssue } = await import("./review-agent-BUNTVJK2.js");
2018
+ const { spawnReviewRoleForIssue } = await import("./review-agent-Caodi0PX.js");
1996
2019
  try {
1997
2020
  const result = await Effect.runPromise(spawnReviewRoleForIssue({
1998
2021
  issueId,
@@ -2063,7 +2086,7 @@ async function checkMissingReviewStatuses() {
2063
2086
  continue;
2064
2087
  }
2065
2088
  try {
2066
- const { spawnReviewRoleForIssue } = await import("./review-agent-BUNTVJK2.js");
2089
+ const { spawnReviewRoleForIssue } = await import("./review-agent-Caodi0PX.js");
2067
2090
  await Effect.runPromise(spawnReviewRoleForIssue({
2068
2091
  issueId,
2069
2092
  workspace,
@@ -2114,7 +2137,7 @@ async function checkStuckReviewing() {
2114
2137
  const actions = [];
2115
2138
  const REVIEW_STUCK_THRESHOLD_MS = 1800 * 1e3;
2116
2139
  try {
2117
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-CUnjjOUu.js");
2140
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-Bge_3XTR.js");
2118
2141
  const statuses = loadReviewStatuses();
2119
2142
  const now = Date.now();
2120
2143
  const activeReviewIssues = /* @__PURE__ */ new Set();
@@ -2273,7 +2296,7 @@ async function reconcileUnappliedReviewVerdicts() {
2273
2296
  let currentHead;
2274
2297
  let reviewedHead;
2275
2298
  try {
2276
- const { rehydrateHeadAnchor, snapshotWorkspaceHeadsPromise } = await import("./git-utils-Y0zG25ez.js");
2299
+ const { rehydrateHeadAnchor, snapshotWorkspaceHeadsPromise } = await import("./git-utils-BAMwn9Nf.js");
2277
2300
  currentHead = await snapshotWorkspaceHeadsPromise(issueId, wsPath);
2278
2301
  const persistedAnchor = reviewAnchorFromContext(latestContext);
2279
2302
  reviewedHead = persistedAnchor ? rehydrateHeadAnchor(persistedAnchor) : void 0;
@@ -2297,7 +2320,7 @@ async function reconcileUnappliedReviewVerdicts() {
2297
2320
  const notes = parsed.topBlocker || `See ${latestReport.filename}`;
2298
2321
  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.`;
2299
2322
  try {
2300
- const { messageAgent } = await import("./agents-megfmQHM.js");
2323
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
2301
2324
  await messageAgent(reviewSession, nudge);
2302
2325
  pendingVerdictNudges.set(latestDir, now);
2303
2326
  const action = `Nudged ${reviewSession} to apply pending ${parsed.verdict} verdict from ${latestReport.filename}`;
@@ -2416,7 +2439,7 @@ async function checkCompletedButUnsignaledReviews() {
2416
2439
  const cmd = buildReviewCompletionCommand(issueId, verdict, topBlocker || `See ${latestReport.filename}`, basename$1(latestDir));
2417
2440
  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.`;
2418
2441
  try {
2419
- const { messageAgent } = await import("./agents-megfmQHM.js");
2442
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
2420
2443
  await messageAgent(reviewSession, nudge);
2421
2444
  unsignaledReviewNudges.set(latestDir, now);
2422
2445
  actions.push(`Nudged ${reviewSession} to signal ${verdict} (${latestReport.filename} written ${Math.round((now - latestMtime) / 6e4)}min ago)`);
@@ -2521,7 +2544,7 @@ async function retryReviewer(state, agentId, trigger) {
2521
2544
  return false;
2522
2545
  }
2523
2546
  try {
2524
- const { spawnReviewSubRoleForIssue } = await import("./review-agent-BUNTVJK2.js");
2547
+ const { spawnReviewSubRoleForIssue } = await import("./review-agent-Caodi0PX.js");
2525
2548
  const contextManifestPath = join$1(dirname$1(outputPath), "context.json");
2526
2549
  const result = await Effect.runPromise(spawnReviewSubRoleForIssue({
2527
2550
  issueId: state.issueId,
@@ -2607,11 +2630,11 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
2607
2630
  writeFileSync(join$1(reviewDir, "synthesis.md"), synthesis.body);
2608
2631
  let fallbackHead;
2609
2632
  try {
2610
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-Y0zG25ez.js");
2633
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-BAMwn9Nf.js");
2611
2634
  fallbackHead = await snapshotWorkspaceHeadsPromise(state.issueId, state.workspace);
2612
2635
  } catch {}
2613
2636
  const notes = synthesis.topBlocker || "Review approved by Deacon fallback from completed reviewer reports";
2614
- const { recordReviewVerdict } = await import("./review-verdict-writer-jldSh3Bm.js");
2637
+ const { recordReviewVerdict } = await import("./review-verdict-writer-DjrJ64eS.js");
2615
2638
  const outcome = await recordReviewVerdict(state.issueId, {
2616
2639
  verdict: synthesis.verdict,
2617
2640
  notes,
@@ -2652,7 +2675,7 @@ async function nudgeSynthesisForCompleteReviewerReports(states) {
2652
2675
  "Read the four reports, write synthesis.md, then signal review status exactly as roles/review.md instructs."
2653
2676
  ].join("\n");
2654
2677
  try {
2655
- const { messageAgent } = await import("./agents-megfmQHM.js");
2678
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
2656
2679
  await messageAgent(state.id, message);
2657
2680
  reviewReportsPresentNudges.set(nudgeKey, now);
2658
2681
  const action = `Nudged ${state.id} to synthesize from ${REVIEW_SUB_ROLES.length} reviewer reports`;
@@ -2764,7 +2787,7 @@ async function monitorReviewConvoySignals() {
2764
2787
  if (!signal) continue;
2765
2788
  const message = signal === "ready" ? `REVIEWER_READY ${state.reviewSubRole} ${outputPath}` : signal === "timeout" ? `REVIEWER_TIMEOUT ${state.reviewSubRole} ${reason}` : `REVIEWER_FAILED ${state.reviewSubRole} ${reason}`;
2766
2789
  try {
2767
- const { messageAgent } = await import("./agents-megfmQHM.js");
2790
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
2768
2791
  await messageAgent(state.reviewSynthesisAgentId, message);
2769
2792
  state.reviewMonitorSignaled = signal;
2770
2793
  saveAgentStateSync(state);
@@ -2772,7 +2795,7 @@ async function monitorReviewConvoySignals() {
2772
2795
  actions.push(action);
2773
2796
  logDeaconEventSync(`monitorReviewConvoySignals: ${action}`);
2774
2797
  if (signal === "ready") try {
2775
- const { notifyPipelineSync } = await import("./pipeline-notifier-C4fZ2ito.js");
2798
+ const { notifyPipelineSync } = await import("./pipeline-notifier-B5DPXvnr.js");
2776
2799
  notifyPipelineSync({
2777
2800
  type: "reviewer_completed",
2778
2801
  issueId: state.issueId,
@@ -2780,7 +2803,7 @@ async function monitorReviewConvoySignals() {
2780
2803
  });
2781
2804
  } catch {}
2782
2805
  else if (signal === "timeout") try {
2783
- const { notifyPipelineSync } = await import("./pipeline-notifier-C4fZ2ito.js");
2806
+ const { notifyPipelineSync } = await import("./pipeline-notifier-B5DPXvnr.js");
2784
2807
  notifyPipelineSync({
2785
2808
  type: "reviewer_timed_out",
2786
2809
  issueId: state.issueId,
@@ -2889,8 +2912,8 @@ async function cleanupOrphanedReviewSessions() {
2889
2912
  async function checkStalledReviewParents() {
2890
2913
  const actions = [];
2891
2914
  try {
2892
- const { listAgentStates } = await import("./agents-megfmQHM.js");
2893
- const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-BUNTVJK2.js");
2915
+ const { listAgentStates } = await import("./agents-DixZjXWm.js");
2916
+ const { PARENT_REVIEW_TIMEOUT_MS } = await import("./review-agent-Caodi0PX.js");
2894
2917
  const states = listAgentStates();
2895
2918
  const now = Date.now();
2896
2919
  for (const state of states) {
@@ -2914,7 +2937,7 @@ async function checkStalledReviewParents() {
2914
2937
  paneTail: paneTail.split("\n").filter(Boolean).slice(-5).join(" | ").slice(0, 400)
2915
2938
  };
2916
2939
  try {
2917
- const { markWorkspaceStuck } = await import("./review-status-CUnjjOUu.js");
2940
+ const { markWorkspaceStuck } = await import("./review-status-Bge_3XTR.js");
2918
2941
  markWorkspaceStuck(state.issueId, "review_parent_stalled_needs_you", {
2919
2942
  reason: `Review parent ${state.id} is past its review deadline with no verdict on record`,
2920
2943
  ...evidence
@@ -2926,7 +2949,7 @@ async function checkStalledReviewParents() {
2926
2949
  actions.push(message);
2927
2950
  logDeaconEventSync(message);
2928
2951
  try {
2929
- const { emitActivityEntrySync } = await import("./activity-logger-BejO16Am.js");
2952
+ const { emitActivityEntrySync } = await import("./activity-logger-B0X2JJwM.js");
2930
2953
  emitActivityEntrySync({
2931
2954
  source: "review",
2932
2955
  level: "warn",
@@ -2957,9 +2980,1564 @@ function hasTerminalVerdictOfRecord(state) {
2957
2980
  }
2958
2981
  }
2959
2982
  //#endregion
2960
- //#region ../../lib/cloister/boot-reconciliation-predicates.ts
2961
- init_control_settings();
2983
+ //#region ../../lib/agents/slot-merge.ts
2962
2984
  init_traefik_connect();
2985
+ const execAsync$5 = promisify(exec);
2986
+ async function verifyAndMergeSlot(issue, slotIndex, item, options = {}) {
2987
+ const issueId = typeof issue === "string" ? issue : issue.issueId;
2988
+ const featureWorkspace = typeof issue === "string" ? defaultRunWorkspace(issue) : issue.featureWorkspace ?? defaultRunWorkspace(issue.issueId);
2989
+ const slotWorkspace = typeof issue === "string" ? `${featureWorkspace}-slot-${slotIndex}` : issue.slotWorkspace ?? `${featureWorkspace}-slot-${slotIndex}`;
2990
+ const slotBranch = typeof issue === "string" ? `feature/${issueId.toLowerCase()}-slot-${slotIndex}` : issue.slotBranch ?? `feature/${issueId.toLowerCase()}-slot-${slotIndex}`;
2991
+ const deps = {
2992
+ run: async (command, cwd) => execAsync$5(command, { cwd }),
2993
+ resolveRepoRoots: resolveWorkspaceRepoRootsSync,
2994
+ ...options.deps
2995
+ };
2996
+ const verifyCommands = item.metadata?.verify_commands ?? [];
2997
+ const expectedOutputs = item.metadata?.expected_outputs ?? [];
2998
+ const evidence = {
2999
+ verifyCommands,
3000
+ expectedOutputs,
3001
+ commandOutputs: []
3002
+ };
3003
+ if (!Number.isInteger(slotIndex) || slotIndex < 1) return {
3004
+ verified: false,
3005
+ merged: false,
3006
+ conflicts: false,
3007
+ evidence,
3008
+ failure: `Invalid slot index: ${slotIndex}`
3009
+ };
3010
+ if (verifyCommands.length === 0) return {
3011
+ verified: false,
3012
+ merged: false,
3013
+ conflicts: false,
3014
+ evidence,
3015
+ failure: `Item ${item.id} has no verify_commands`
3016
+ };
3017
+ if (expectedOutputs.length === 0) return {
3018
+ verified: false,
3019
+ merged: false,
3020
+ conflicts: false,
3021
+ evidence,
3022
+ failure: `Item ${item.id} has no expected_outputs`
3023
+ };
3024
+ for (const command of verifyCommands) try {
3025
+ const output = await deps.run(command, slotWorkspace);
3026
+ evidence.commandOutputs.push({
3027
+ command,
3028
+ stdout: output.stdout,
3029
+ stderr: output.stderr
3030
+ });
3031
+ } catch (error) {
3032
+ const failed = commandFailure(error);
3033
+ evidence.commandOutputs.push({
3034
+ command,
3035
+ stdout: failed.stdout,
3036
+ stderr: failed.stderr
3037
+ });
3038
+ return {
3039
+ verified: false,
3040
+ merged: false,
3041
+ conflicts: false,
3042
+ evidence,
3043
+ failure: `Verify command failed for ${item.id}: ${command}`
3044
+ };
3045
+ }
3046
+ const slotRoots = deps.resolveRepoRoots(issueId, slotWorkspace);
3047
+ if (slotRoots.some((root) => root.degradedPolyrepo)) return {
3048
+ verified: true,
3049
+ merged: false,
3050
+ conflicts: false,
3051
+ evidence,
3052
+ failure: `Could not resolve polyrepo roots for slot ${slotIndex} — refusing to infer a merge`
3053
+ };
3054
+ const aheadByRepo = /* @__PURE__ */ new Map();
3055
+ for (const root of slotRoots) aheadByRepo.set(root.repoKey, await aheadCount(deps.run, root.dir, root.sourceBranch, slotBranch));
3056
+ const rootsWithWork = slotRoots.filter((root) => (aheadByRepo.get(root.repoKey) ?? 0) > 0);
3057
+ if (rootsWithWork.length === 0) return {
3058
+ verified: true,
3059
+ merged: false,
3060
+ conflicts: false,
3061
+ evidence,
3062
+ failure: `Slot branch ${slotBranch} has no unmerged current-item changes in any repo — refusing to mark item ${item.id} merged`
3063
+ };
3064
+ if (!slotRoots.some((root) => root.isPolyrepo)) try {
3065
+ evidence.mergeOutput = await deps.run(`git merge --no-ff ${JSON.stringify(slotBranch)}`, featureWorkspace);
3066
+ return {
3067
+ verified: true,
3068
+ merged: true,
3069
+ conflicts: false,
3070
+ evidence
3071
+ };
3072
+ } catch (error) {
3073
+ const failed = commandFailure(error);
3074
+ evidence.mergeOutput = {
3075
+ stdout: failed.stdout,
3076
+ stderr: failed.stderr
3077
+ };
3078
+ await deps.run("git merge --abort", featureWorkspace).catch(() => {});
3079
+ return {
3080
+ verified: true,
3081
+ merged: false,
3082
+ conflicts: true,
3083
+ evidence,
3084
+ failure: `Slot branch ${slotBranch} did not merge cleanly`
3085
+ };
3086
+ }
3087
+ const baseRoots = new Map(deps.resolveRepoRoots(issueId, featureWorkspace).map((root) => [root.repoKey, root]));
3088
+ const repoMergeOutputs = [];
3089
+ for (const root of rootsWithWork) {
3090
+ const baseRoot = baseRoots.get(root.repoKey);
3091
+ if (!baseRoot) return {
3092
+ verified: true,
3093
+ merged: false,
3094
+ conflicts: false,
3095
+ evidence: {
3096
+ ...evidence,
3097
+ repoMergeOutputs
3098
+ },
3099
+ failure: `No base feature-workspace checkout for repo ${root.repoKey} — cannot integrate slot ${slotIndex}`
3100
+ };
3101
+ try {
3102
+ const output = await deps.run(`git merge --no-ff ${JSON.stringify(slotBranch)}`, baseRoot.dir);
3103
+ repoMergeOutputs.push({
3104
+ repoKey: root.repoKey,
3105
+ stdout: output.stdout,
3106
+ stderr: output.stderr
3107
+ });
3108
+ } catch (error) {
3109
+ const failed = commandFailure(error);
3110
+ repoMergeOutputs.push({
3111
+ repoKey: root.repoKey,
3112
+ stdout: failed.stdout,
3113
+ stderr: failed.stderr
3114
+ });
3115
+ await deps.run("git merge --abort", baseRoot.dir).catch(() => {});
3116
+ return {
3117
+ verified: true,
3118
+ merged: false,
3119
+ conflicts: true,
3120
+ evidence: {
3121
+ ...evidence,
3122
+ repoMergeOutputs
3123
+ },
3124
+ failure: `Slot branch ${slotBranch} did not merge cleanly into ${root.repoKey}`
3125
+ };
3126
+ }
3127
+ }
3128
+ return {
3129
+ verified: true,
3130
+ merged: true,
3131
+ conflicts: false,
3132
+ evidence: {
3133
+ ...evidence,
3134
+ repoMergeOutputs
3135
+ }
3136
+ };
3137
+ }
3138
+ /** Count base..branch commits in one repo; a missing branch or repo means zero. */
3139
+ async function aheadCount(run, cwd, baseBranch, branch) {
3140
+ try {
3141
+ const { stdout } = await run(`git rev-list --count ${JSON.stringify(baseBranch)}..${JSON.stringify(branch)}`, cwd);
3142
+ const count = Number(stdout.trim());
3143
+ return Number.isFinite(count) && count > 0 ? count : 0;
3144
+ } catch {
3145
+ return 0;
3146
+ }
3147
+ }
3148
+ function commandFailure(error) {
3149
+ const partial = error;
3150
+ return {
3151
+ stdout: typeof partial.stdout === "string" ? partial.stdout : "",
3152
+ stderr: typeof partial.stderr === "string" ? partial.stderr : typeof partial.message === "string" ? partial.message : String(error)
3153
+ };
3154
+ }
3155
+ //#endregion
3156
+ //#region ../../lib/pan-dir/task-door.ts
3157
+ /** Single task-mutation write door over the immutable xBRIEF specification. */
3158
+ var TaskStatusChangeError = class extends Error {
3159
+ constructor(message, details) {
3160
+ super(message);
3161
+ this.details = details;
3162
+ this.name = "TaskStatusChangeError";
3163
+ }
3164
+ };
3165
+ const TERMINAL = new Set(["completed", "cancelled"]);
3166
+ function statusFor(type) {
3167
+ if (type === "claim") return "running";
3168
+ if (type === "done") return "completed";
3169
+ if (type === "block") return "blocked";
3170
+ if (type === "unblock") return "pending";
3171
+ if (type === "reopen") return "pending";
3172
+ return "cancelled";
3173
+ }
3174
+ function subItemOverrideKey(itemId, subItemId) {
3175
+ return subItemId.includes(".") ? subItemId : `${itemId}.${subItemId}`;
3176
+ }
3177
+ function allowedFrom(type, status) {
3178
+ if (type === "claim") return status === "pending";
3179
+ if (type === "done") return status === "running";
3180
+ if (type === "block") return status === "pending" || status === "running";
3181
+ if (type === "unblock") return status === "blocked";
3182
+ if (type === "reopen") return status === "completed";
3183
+ return status === "pending" || status === "running" || status === "blocked";
3184
+ }
3185
+ function taskError(issueId, itemId, operation, currentStatus, owner, extra) {
3186
+ const ownerText = owner ? ` The current claim owner is ${owner}.` : "";
3187
+ const recovery = `Run \`pan task show ${issueId} ${itemId}\` to inspect the current task state before retrying.`;
3188
+ return new TaskStatusChangeError(`Task ${itemId} on ${issueId} is ${currentStatus}, so ${operation} is not allowed.${ownerText}${extra ? ` ${extra}` : ""} ${recovery}`, {
3189
+ issueId,
3190
+ itemId,
3191
+ operation,
3192
+ currentStatus,
3193
+ owner
3194
+ });
3195
+ }
3196
+ function archiveClaim(record, itemId, outcome, reason, forced, now) {
3197
+ const claim = record.tasks?.claims[itemId];
3198
+ if (!claim || !record.tasks) return;
3199
+ const entry = {
3200
+ ...claim,
3201
+ itemId,
3202
+ outcome,
3203
+ reason,
3204
+ forced: forced || void 0,
3205
+ releasedAt: now
3206
+ };
3207
+ record.tasks.claimHistory = [...record.tasks.claimHistory ?? [], entry].slice(-50);
3208
+ delete record.tasks.claims[itemId];
3209
+ }
3210
+ async function applyTaskStatusChange(project, issueId, operation) {
3211
+ const normalizedIssueId = issueId.toUpperCase();
3212
+ const writerId = operation.writerId ?? process.env.OVERDECK_AGENT_ID ?? `cli-${process.pid}@${hostname()}`;
3213
+ let result;
3214
+ await updateIssueRecord(project, normalizedIssueId, (record) => {
3215
+ const planPath = findPlanSync(join(project.path, "workspaces", `feature-${normalizedIssueId.toLowerCase()}`));
3216
+ if (!planPath) throw new Error(`The xBRIEF for ${normalizedIssueId} is missing or unreadable. Return the issue to planning before changing task state.`);
3217
+ const item = applyStatusOverrides(readPlanSync(planPath), record.statusOverrides ?? {}).plan.items.find(({ id }) => id === operation.itemId);
3218
+ if (!item) throw new Error(`Task ${operation.itemId} does not exist in the immutable xBRIEF for ${normalizedIssueId}. Return the issue to planning to change scope.`);
3219
+ const currentStatus = item.status;
3220
+ const currentSequence = record.tasks?.sequence ?? 0;
3221
+ const existingClaim = record.tasks?.claims[operation.itemId];
3222
+ const nextStatus = statusFor(operation.type);
3223
+ const subItems = subItemsOf(item);
3224
+ const subIds = operation.subItemIds?.length ? new Set(operation.subItemIds) : new Set(operation.type === "done" || operation.type === "cancel" || operation.type === "reopen" ? subItems.map(({ id }) => id) : []);
3225
+ const repeatedCancellation = operation.type === "cancel" && currentStatus === "cancelled";
3226
+ if (operation.expectedSequence !== void 0 && operation.expectedSequence !== currentSequence) throw new TaskStatusChangeError(`Task sequence conflict for ${normalizedIssueId}: expected ${operation.expectedSequence}, but the current sequence is ${currentSequence}. Run \`pan task next ${normalizedIssueId}\` and retry with the new sequence.`, {
3227
+ issueId: normalizedIssueId,
3228
+ itemId: operation.itemId,
3229
+ operation: operation.type,
3230
+ currentStatus,
3231
+ currentSequence
3232
+ });
3233
+ if (TERMINAL.has(currentStatus) && !repeatedCancellation && operation.type !== "reopen") throw taskError(normalizedIssueId, operation.itemId, operation.type, currentStatus, existingClaim?.writerId);
3234
+ if (operation.force && !operation.reason) throw taskError(normalizedIssueId, operation.itemId, operation.type, currentStatus, existingClaim?.writerId, "A forced transition requires --reason.");
3235
+ if ((operation.type === "block" || operation.type === "cancel" || operation.type === "reopen") && !operation.reason) throw taskError(normalizedIssueId, operation.itemId, operation.type, currentStatus, existingClaim?.writerId, "This transition requires --reason.");
3236
+ if (repeatedCancellation && subItems.every((subItem) => subItem.status === "cancelled")) {
3237
+ result = {
3238
+ issueId: normalizedIssueId,
3239
+ itemId: operation.itemId,
3240
+ status: "cancelled",
3241
+ sequence: currentSequence,
3242
+ idempotent: true
3243
+ };
3244
+ return record;
3245
+ }
3246
+ if (operation.type === "claim" && currentStatus === "running" && existingClaim?.writerId === writerId) {
3247
+ result = {
3248
+ issueId: normalizedIssueId,
3249
+ itemId: operation.itemId,
3250
+ status: "running",
3251
+ sequence: currentSequence,
3252
+ claim: existingClaim,
3253
+ idempotent: true
3254
+ };
3255
+ return record;
3256
+ }
3257
+ const ownerRestricted = (operation.type === "done" || operation.type === "block" || operation.type === "cancel") && currentStatus === "running";
3258
+ if (!operation.force && ownerRestricted && existingClaim?.writerId !== writerId) throw taskError(normalizedIssueId, operation.itemId, operation.type, currentStatus, existingClaim?.writerId ?? "missing claim owner");
3259
+ if (!operation.force && !repeatedCancellation && !allowedFrom(operation.type, currentStatus)) throw taskError(normalizedIssueId, operation.itemId, operation.type, currentStatus, existingClaim?.writerId);
3260
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3261
+ record.tasks ??= {
3262
+ sequence: 0,
3263
+ claims: {}
3264
+ };
3265
+ record.statusOverrides = {
3266
+ ...record.statusOverrides ?? {},
3267
+ [operation.itemId]: nextStatus
3268
+ };
3269
+ for (const subId of subIds) record.statusOverrides[subItemOverrideKey(operation.itemId, subId)] = nextStatus;
3270
+ if (operation.type === "claim") record.tasks.claims[operation.itemId] = {
3271
+ writerId,
3272
+ agentId: process.env.OVERDECK_AGENT_ID ?? null,
3273
+ pid: process.pid,
3274
+ host: hostname(),
3275
+ claimedAt: now
3276
+ };
3277
+ else if (existingClaim) archiveClaim(record, operation.itemId, nextStatus === "completed" ? "completed" : nextStatus === "blocked" ? "blocked" : "cancelled", operation.reason, operation.force ?? false, now);
3278
+ if (operation.reason) record.tasks.statusReasons = {
3279
+ ...record.tasks.statusReasons ?? {},
3280
+ [operation.itemId]: {
3281
+ reason: operation.reason,
3282
+ updatedAt: now,
3283
+ forced: operation.force || void 0
3284
+ }
3285
+ };
3286
+ record.tasks.sequence = currentSequence + 1;
3287
+ result = {
3288
+ issueId: normalizedIssueId,
3289
+ itemId: operation.itemId,
3290
+ status: nextStatus,
3291
+ sequence: record.tasks.sequence,
3292
+ claim: record.tasks.claims[operation.itemId]
3293
+ };
3294
+ return record;
3295
+ }, { writerId });
3296
+ if (!result) throw new Error(`Task mutation for ${normalizedIssueId}/${operation.itemId} produced no result.`);
3297
+ return result;
3298
+ }
3299
+ //#endregion
3300
+ //#region ../../lib/swarm-policy.ts
3301
+ init_projects();
3302
+ function resolveSwarmPolicyLayers(global = {}, project = {}, issue = {}, cli = {}) {
3303
+ const resolve = (key, fallback) => {
3304
+ for (const [source, layer] of [
3305
+ ["cli", cli],
3306
+ ["issue", issue],
3307
+ ["project", project],
3308
+ ["global", global]
3309
+ ]) if (layer[key] !== void 0) return {
3310
+ value: layer[key],
3311
+ source
3312
+ };
3313
+ return {
3314
+ value: fallback,
3315
+ source: "default"
3316
+ };
3317
+ };
3318
+ const mode = resolve("mode", "off");
3319
+ const maxSlots = resolve("maxSlots", 3);
3320
+ const autoAdvance = resolve("autoAdvance", true);
3321
+ return {
3322
+ mode: mode.value,
3323
+ maxSlots: maxSlots.value,
3324
+ autoAdvance: autoAdvance.value,
3325
+ source: {
3326
+ mode: mode.source,
3327
+ maxSlots: maxSlots.source,
3328
+ autoAdvance: autoAdvance.source
3329
+ }
3330
+ };
3331
+ }
3332
+ function resolveSwarmPolicy(issueId, cli = {}) {
3333
+ const global = loadConfigSync().config.swarm;
3334
+ if (!issueId) return resolveSwarmPolicyLayers(global, {}, {}, cli);
3335
+ const resolved = resolveProjectFromIssueSync(issueId);
3336
+ const project = resolved ? getProjectSync(resolved.projectKey) : void 0;
3337
+ const issue = project ? readIssueRecordSync(project, issueId)?.swarm?.policy : void 0;
3338
+ return resolveSwarmPolicyLayers(global, project?.swarm, issue, cli);
3339
+ }
3340
+ function resolveAutomaticSwarmPolicy(issueId, swarmEligible, manual = false) {
3341
+ const policy = resolveSwarmPolicy(issueId);
3342
+ return {
3343
+ policy,
3344
+ spawnForeman: manual || policy.mode !== "off" && swarmEligible,
3345
+ requireSwarmReadiness: policy.mode === "always",
3346
+ advanceWavesWithoutConfirmation: policy.autoAdvance,
3347
+ reason: manual ? "manual" : policy.mode === "off" ? "mode-off" : swarmEligible ? "eligible" : "not-ready"
3348
+ };
3349
+ }
3350
+ //#endregion
3351
+ //#region ../../lib/cloister/deacon-workspaces.ts
3352
+ init_projects();
3353
+ function listFeatureWorkspaces(options = {}) {
3354
+ const includeSlotWorkspaces = options.includeSlotWorkspaces ?? true;
3355
+ const projects = listProjectsSync();
3356
+ const workspaces = [];
3357
+ for (const { config: projectConfig } of projects) {
3358
+ const workspacesRoot = join$1(projectConfig.path, "workspaces");
3359
+ if (!existsSync(workspacesRoot)) continue;
3360
+ let entries;
3361
+ try {
3362
+ entries = readdirSync(workspacesRoot, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("feature-")).filter((e) => includeSlotWorkspaces || !/-slot-\d+$/.test(e.name)).map((e) => e.name);
3363
+ } catch {
3364
+ continue;
3365
+ }
3366
+ for (const entry of entries) workspaces.push({
3367
+ issueId: entry.replace(/^feature-/, "").toUpperCase(),
3368
+ workspacePath: join$1(workspacesRoot, entry),
3369
+ projectPath: projectConfig.path
3370
+ });
3371
+ }
3372
+ return workspaces;
3373
+ }
3374
+ //#endregion
3375
+ //#region ../../lib/cloister/deacon-swarm-orphan-gc.ts
3376
+ /**
3377
+ * Reconcile GC for truly-orphaned slots (PAN-2214, completes PAN-2213(c)).
3378
+ *
3379
+ * An orphan is a slot index with an on-disk worktree or a local slot branch but
3380
+ * no slotAssignments entry and no live agent tmux session. Zero-commit-ahead
3381
+ * orphans are removed; orphans with unmerged commits are only reported so the
3382
+ * operator can push them via `pan swarm reset` — never deleted.
3383
+ */
3384
+ async function gcOrphanedSlots(issueId, workspacePath, reconciled, deps) {
3385
+ const actions = [];
3386
+ const issueLower = issueId.toLowerCase();
3387
+ const worktreeSlotIndexes = await listSlotWorktreeIndexes(workspacePath, deps.runGitCommand);
3388
+ const branchesBySlot = new Map(reconciled.branches.map((branch) => [branch.slotIndex, branch.branch]));
3389
+ const candidateSlotIndexes = [...new Set([...worktreeSlotIndexes, ...branchesBySlot.keys()])].sort((a, b) => a - b);
3390
+ if (candidateSlotIndexes.length === 0) return actions;
3391
+ const ownedSlotIndexes = new Set([
3392
+ ...(deps.listSlotAssignments ?? listSlotAssignments)(issueId, workspacePath).map((assignment) => assignment.slotIndex),
3393
+ ...reconciled.merged.map((slot) => slot.slotIndex),
3394
+ ...reconciled.inFlight.map((slot) => slot.slotIndex)
3395
+ ]);
3396
+ const sessionNames = new Set(await deps.listSessionNames());
3397
+ for (const slotIndex of candidateSlotIndexes) {
3398
+ if (ownedSlotIndexes.has(slotIndex)) continue;
3399
+ if (sessionNames.has(`agent-${issueLower}-slot-${slotIndex}`)) continue;
3400
+ const branch = branchesBySlot.get(slotIndex);
3401
+ const aheadCount = branch ? await countCommitsAhead$1(workspacePath, branch, deps.runGitCommand) : 0;
3402
+ if (aheadCount === null || aheadCount > 0) {
3403
+ actions.push(`[swarm] orphan slot ${slotIndex} for ${issueId} preserved: ${branch} has ${aheadCount ?? "an unknown number of"} unmerged commit(s) — run \`pan swarm reset ${issueId}\` to push it to origin before cleanup`);
3404
+ continue;
3405
+ }
3406
+ if (worktreeSlotIndexes.has(slotIndex)) await deps.runGitCommand(`git worktree remove --force ${JSON.stringify(`${workspacePath}-slot-${slotIndex}`)}`, workspacePath);
3407
+ if (branch) await deps.runGitCommand(`git branch -D ${JSON.stringify(branch)}`, workspacePath);
3408
+ actions.push(`[swarm] gc-orphan slot ${slotIndex} for ${issueId}`);
3409
+ }
3410
+ return actions;
3411
+ }
3412
+ async function listSlotWorktreeIndexes(workspacePath, runGitCommand) {
3413
+ const indexes = /* @__PURE__ */ new Set();
3414
+ try {
3415
+ const result = await runGitCommand("git worktree list --porcelain", workspacePath);
3416
+ const pattern = new RegExp(`^worktree ${escapeRegExp(workspacePath)}-slot-(\\d+)$`);
3417
+ for (const line of String(result?.stdout ?? "").split("\n")) {
3418
+ const match = pattern.exec(line.trim());
3419
+ if (match) indexes.add(Number(match[1]));
3420
+ }
3421
+ } catch {}
3422
+ return indexes;
3423
+ }
3424
+ async function countCommitsAhead$1(workspacePath, branch, runGitCommand) {
3425
+ try {
3426
+ const result = await runGitCommand(`git rev-list --count HEAD..${JSON.stringify(branch)}`, workspacePath);
3427
+ const count = Number(String(result?.stdout ?? "").trim());
3428
+ return Number.isFinite(count) ? count : null;
3429
+ } catch {
3430
+ return null;
3431
+ }
3432
+ }
3433
+ function escapeRegExp(value) {
3434
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3435
+ }
3436
+ //#endregion
3437
+ //#region ../../lib/cloister/deacon-swarm-record.ts
3438
+ init_record();
3439
+ init_record_update();
3440
+ function readSwarmHold(workspacePath, issueId) {
3441
+ return readIssueRecordForWorkspaceSync(workspacePath, issueId.toUpperCase())?.swarm?.hold;
3442
+ }
3443
+ async function writeSwarmHold(workspacePath, issueId, hold) {
3444
+ await updateIssueRecordForWorkspace(workspacePath, issueId.toUpperCase(), (record) => ({
3445
+ ...record,
3446
+ swarm: {
3447
+ ...record.swarm ?? {},
3448
+ hold
3449
+ }
3450
+ }));
3451
+ }
3452
+ function readSwarmCompletionObservation(workspacePath, issueId, progressKey) {
3453
+ return readIssueRecordForWorkspaceSync(workspacePath, issueId.toUpperCase())?.swarm?.completionObservations?.[progressKey];
3454
+ }
3455
+ async function writeSwarmCompletionObservation(workspacePath, issueId, progressKey, observation) {
3456
+ await updateIssueRecordForWorkspace(workspacePath, issueId.toUpperCase(), (record) => ({
3457
+ ...record,
3458
+ swarm: {
3459
+ ...record.swarm ?? {},
3460
+ completionObservations: {
3461
+ ...record.swarm?.completionObservations ?? {},
3462
+ [progressKey]: observation
3463
+ }
3464
+ }
3465
+ }));
3466
+ }
3467
+ async function clearSwarmCompletionObservationRecord(workspacePath, issueId, progressKey) {
3468
+ await updateIssueRecordForWorkspace(workspacePath, issueId.toUpperCase(), (record) => {
3469
+ const existing = record.swarm?.completionObservations;
3470
+ if (!existing?.[progressKey]) return record;
3471
+ const completionObservations = { ...existing };
3472
+ delete completionObservations[progressKey];
3473
+ return {
3474
+ ...record,
3475
+ swarm: {
3476
+ ...record.swarm ?? {},
3477
+ completionObservations
3478
+ }
3479
+ };
3480
+ });
3481
+ }
3482
+ async function writeSwarmForemanTakeover(workspacePath, issueId, itemId, slotIndex) {
3483
+ await updateIssueRecordForWorkspace(workspacePath, issueId.toUpperCase(), (record) => ({
3484
+ ...record,
3485
+ swarm: {
3486
+ ...record.swarm ?? {},
3487
+ reclaimedItems: {
3488
+ ...record.swarm?.reclaimedItems ?? {},
3489
+ [itemId]: {
3490
+ slotIndex,
3491
+ reclaimedAt: (/* @__PURE__ */ new Date()).toISOString()
3492
+ }
3493
+ }
3494
+ }
3495
+ }));
3496
+ }
3497
+ /**
3498
+ * PAN-2372 WI-3 / FR-6: clear a slot's completion marker once the coordinator
3499
+ * (WI-4) has consumed it (merge/requeue). No-op when no marker exists for the
3500
+ * slot, so callers can clear unconditionally on the terminal transition.
3501
+ */
3502
+ async function clearSwarmSlotCompletion(workspacePath, issueId, slotIndex) {
3503
+ const normalizedIssueId = issueId.toUpperCase();
3504
+ const current = readIssueRecordForWorkspaceSync(workspacePath, normalizedIssueId);
3505
+ if (!current?.swarm?.slotCompletions || !(String(slotIndex) in current.swarm.slotCompletions)) return;
3506
+ await updateIssueRecordForWorkspace(workspacePath, normalizedIssueId, (record) => {
3507
+ const existing = record.swarm?.slotCompletions;
3508
+ if (!existing || !(String(slotIndex) in existing)) return record;
3509
+ const next = { ...existing };
3510
+ delete next[String(slotIndex)];
3511
+ return {
3512
+ ...record,
3513
+ swarm: {
3514
+ ...record.swarm,
3515
+ slotCompletions: next
3516
+ }
3517
+ };
3518
+ });
3519
+ }
3520
+ /**
3521
+ * Consume all durable ownership for a slot in one record update. Merged-slot
3522
+ * GC uses this after it removes the worktree and branch so a completion marker
3523
+ * cannot outlive the assignment and keep the freed index occupied.
3524
+ */
3525
+ async function clearSwarmSlotOwnership(workspacePath, issueId, slotIndex, _itemId) {
3526
+ await updateIssueRecordForWorkspace(workspacePath, issueId.toUpperCase(), (record) => {
3527
+ const swarm = record.swarm ?? {};
3528
+ const slotAssignments = (swarm.slotAssignments ?? []).filter((assignment) => assignment.slotIndex !== slotIndex);
3529
+ const slotCompletions = { ...swarm.slotCompletions ?? {} };
3530
+ delete slotCompletions[String(slotIndex)];
3531
+ return {
3532
+ ...record,
3533
+ swarm: {
3534
+ ...swarm,
3535
+ slotAssignments,
3536
+ slotCompletions
3537
+ }
3538
+ };
3539
+ });
3540
+ }
3541
+ async function clearReleasedBlockedSwarmSlot(workspacePath, issueId, slotIndex) {
3542
+ await updateIssueRecordForWorkspace(workspacePath, issueId.toUpperCase(), (record) => {
3543
+ const releasedBlockedSlots = { ...record.swarm?.releasedBlockedSlots ?? {} };
3544
+ delete releasedBlockedSlots[String(slotIndex)];
3545
+ return {
3546
+ ...record,
3547
+ swarm: {
3548
+ ...record.swarm ?? {},
3549
+ releasedBlockedSlots
3550
+ }
3551
+ };
3552
+ });
3553
+ }
3554
+ //#endregion
3555
+ //#region ../../lib/cloister/deacon-swarm-completion.ts
3556
+ init_messaging();
3557
+ init_project_repos();
3558
+ init_config$1();
3559
+ const execAsync$4 = promisify(exec);
3560
+ async function classifyDoneWithoutSignal(slot, deps, options, observation) {
3561
+ if ((options.inferCompletion ?? "off") === "off" || !slot.agentId || !slot.branch || !options.workspacePath || !options.issueId) {
3562
+ if (options.workspacePath && options.issueId) await (deps.clearCompletionObservation ?? clearSwarmCompletionObservationRecord)(options.workspacePath, options.issueId, observation.progressKey);
3563
+ return null;
3564
+ }
3565
+ const aheadCount = await (deps.getSlotBranchAheadCount ?? defaultGetSlotBranchAheadCount)(options.workspacePath, options.issueId, slot.branch).catch(() => 0);
3566
+ const clean = await (deps.isSlotWorktreeClean ?? defaultIsSlotWorktreeClean)(`${options.workspacePath}-slot-${slot.slotIndex}`).catch(() => false);
3567
+ if (aheadCount < 1 || !clean) {
3568
+ await (deps.clearCompletionObservation ?? clearSwarmCompletionObservationRecord)(options.workspacePath, options.issueId, observation.progressKey);
3569
+ return null;
3570
+ }
3571
+ const signature = `${observation.commitTime ?? "none"}:${observation.outputDigest}:${aheadCount}:clean`;
3572
+ const previous = (deps.readCompletionObservation ?? readSwarmCompletionObservation)(options.workspacePath, options.issueId, observation.progressKey);
3573
+ const current = {
3574
+ signature,
3575
+ nudged: previous?.signature === signature ? previous.nudged : false,
3576
+ consecutiveDoneCount: previous?.signature === signature ? previous.consecutiveDoneCount + 1 : 1
3577
+ };
3578
+ const actions = [];
3579
+ const normalizedIssueId = options.issueId.toUpperCase();
3580
+ if (!current.nudged) {
3581
+ if (deps.sendCompletionNudge) await deps.sendCompletionNudge(slot.agentId, normalizedIssueId);
3582
+ current.nudged = true;
3583
+ actions.push(`[swarm] nudged slot ${slot.slotIndex} (item ${slot.itemId}) for ${normalizedIssueId}: run pan done ${normalizedIssueId}`);
3584
+ }
3585
+ await (deps.writeCompletionObservation ?? writeSwarmCompletionObservation)(options.workspacePath, options.issueId, observation.progressKey, current);
3586
+ return {
3587
+ ...slot,
3588
+ lifecycle: "awaiting-completion-signal",
3589
+ reason: "no-progress-timeout",
3590
+ stalledForMs: observation.stalledForMs,
3591
+ signal: "completion-nudge",
3592
+ actions
3593
+ };
3594
+ }
3595
+ async function classifyDurableReadySlot(slot, deps, options) {
3596
+ if (!slot.branch || !options.workspacePath || !options.issueId) return null;
3597
+ if (await (deps.getSlotBranchAheadCount ?? defaultGetSlotBranchAheadCount)(options.workspacePath, options.issueId, slot.branch).catch(() => 0) < 1) return null;
3598
+ if (!await (deps.isSlotWorktreeClean ?? defaultIsSlotWorktreeClean)(`${options.workspacePath}-slot-${slot.slotIndex}`).catch(() => false)) return null;
3599
+ return {
3600
+ ...slot,
3601
+ lifecycle: "ready-to-merge",
3602
+ exitStatus: 0,
3603
+ signal: "inferred"
3604
+ };
3605
+ }
3606
+ async function clearSwarmCompletionObservation(workspacePath, issueId, progressKey, deps) {
3607
+ await (deps.clearCompletionObservation ?? clearSwarmCompletionObservationRecord)(workspacePath, issueId, progressKey);
3608
+ }
3609
+ async function defaultGetSlotBranchAheadCount(workspacePath, issueId, branch) {
3610
+ const baseBranch = `feature/${issueId.toLowerCase()}`;
3611
+ const roots = resolveWorkspaceRepoRootsSync(issueId, branch.match(/-slot-(\d+)(?:-attempt-\d+)?$/) ? `${workspacePath}-slot-${branch.match(/-slot-(\d+)(?:-attempt-\d+)?$/)[1]}` : workspacePath);
3612
+ let total = 0;
3613
+ for (const root of roots) {
3614
+ if (root.degradedPolyrepo) return 0;
3615
+ const { stdout } = await execAsync$4(`git rev-list --count ${JSON.stringify(baseBranch)}..${JSON.stringify(branch)}`, { cwd: root.dir });
3616
+ if (!/^\d+$/.test(stdout.trim())) return 0;
3617
+ total += Number(stdout.trim());
3618
+ }
3619
+ return total;
3620
+ }
3621
+ async function defaultIsSlotWorktreeClean(slotWorkspacePath) {
3622
+ const match = /feature-([a-z]+-\d+)-slot-\d+$/.exec(slotWorkspacePath);
3623
+ const roots = match ? resolveWorkspaceRepoRootsSync(match[1].toUpperCase(), slotWorkspacePath) : [];
3624
+ if (roots.some((root) => root.degradedPolyrepo)) return false;
3625
+ return (roots.length > 0 ? await Promise.all(roots.map((root) => execAsync$4("git status --porcelain", { cwd: root.dir }).then((result) => result.stdout))) : [(await execAsync$4("git status --porcelain", { cwd: slotWorkspacePath })).stdout]).every(isStatePlaneOnlyStatus);
3626
+ }
3627
+ async function defaultSendCompletionNudge(agentId, issueId) {
3628
+ await messageAgent(agentId, `You appear to have committed clean slot work but have not signaled completion. If the slot is complete, run exactly:\n\npan done ${issueId}`, "deacon:swarm-completion-inference");
3629
+ }
3630
+ //#endregion
3631
+ //#region ../../lib/cloister/deacon-swarm-gc.ts
3632
+ init_agent_state();
3633
+ init_project_repos();
3634
+ const MERGED_LIVE_SLOT_IDLE_MS = 1800 * 1e3;
3635
+ async function gcMergedSlots(issueId, workspacePath, slots, deps) {
3636
+ return (await gcMergedSlotsWithStatus(issueId, workspacePath, slots, deps)).actions;
3637
+ }
3638
+ async function gcMergedSlotsWithStatus(issueId, workspacePath, slots, deps) {
3639
+ const actions = [];
3640
+ const uncleared = [];
3641
+ const sessionNames = new Set(await deps.listSessionNames());
3642
+ const worktreeExists = deps.slotWorktreeExists ?? existsSync$1;
3643
+ for (const slot of slots) {
3644
+ if (slot.status !== "merged") continue;
3645
+ const agentId = slot.agentId ?? `agent-${issueId.toLowerCase()}-slot-${slot.slotIndex}`;
3646
+ let reapAction = null;
3647
+ if (sessionNames.has(agentId)) {
3648
+ const completionProven = slot.mergedVia === "completed-status";
3649
+ const lastActivity = (deps.getAgentLastActivity ?? ((id) => getAgentStateSync(id)?.lastActivity))(agentId);
3650
+ const idleFor = lastActivity ? Date.now() - Date.parse(lastActivity) : 0;
3651
+ if (!completionProven && (!Number.isFinite(idleFor) || idleFor < MERGED_LIVE_SLOT_IDLE_MS)) {
3652
+ actions.push(`[swarm] gc skipped slot ${slot.slotIndex} (item ${slot.itemId}) for ${issueId}: agent session alive`);
3653
+ uncleared.push(slot);
3654
+ continue;
3655
+ }
3656
+ reapAction = completionProven ? `[swarm] gc reaped merged agent ${agentId}` : `[swarm] gc reaped idle merged agent ${agentId}`;
3657
+ }
3658
+ const slotWorkspace = `${workspacePath}-slot-${slot.slotIndex}`;
3659
+ const slotBranch = slot.branch ?? `feature/${issueId.toLowerCase()}-slot-${slot.slotIndex}`;
3660
+ if (worktreeExists(slotWorkspace)) {
3661
+ if (!await removeSlotWorkspace(issueId, workspacePath, slotWorkspace, slotBranch, slot, deps, actions)) {
3662
+ uncleared.push(slot);
3663
+ continue;
3664
+ }
3665
+ }
3666
+ const branchExists = await slotBranchExists(deps.runGitCommand, workspacePath, slotBranch);
3667
+ if (branchExists === null) {
3668
+ actions.push(`[swarm] gc deferred slot ${slot.slotIndex} (item ${slot.itemId}) for ${issueId}: branch state of ${slotBranch} could not be determined`);
3669
+ uncleared.push(slot);
3670
+ continue;
3671
+ }
3672
+ if (branchExists) try {
3673
+ await deps.runGitCommand(`git branch -D ${JSON.stringify(slotBranch)}`, workspacePath);
3674
+ } catch (error) {
3675
+ actions.push(`[swarm] gc deferred slot ${slot.slotIndex} (item ${slot.itemId}) for ${issueId}: branch delete failed: ${error instanceof Error ? error.message : String(error)}`);
3676
+ uncleared.push(slot);
3677
+ continue;
3678
+ }
3679
+ await deps.clearSlotAssignment(workspacePath, issueId, slot.slotIndex, slot.itemId);
3680
+ if (reapAction) try {
3681
+ await (deps.stopSlotAgent ?? ((id) => Effect.runPromise(stopAgent(id))))(agentId);
3682
+ actions.push(reapAction);
3683
+ } catch (error) {
3684
+ actions.push(`[swarm] could not reap merged agent ${agentId}: ${error instanceof Error ? error.message : String(error)}`);
3685
+ }
3686
+ actions.push(`[swarm] gc slot ${slot.slotIndex} (item ${slot.itemId}) for ${issueId}`);
3687
+ }
3688
+ return {
3689
+ actions,
3690
+ uncleared
3691
+ };
3692
+ }
3693
+ /**
3694
+ * Whether the outer workspace has a local `slotBranch`, or null when that
3695
+ * cannot be determined. `git branch --list` exits 0 with empty output for an
3696
+ * absent branch, so a throw is always an indeterminate state, never "absent".
3697
+ */
3698
+ async function slotBranchExists(runGitCommand, workspacePath, slotBranch) {
3699
+ try {
3700
+ const result = await runGitCommand(`git branch --list ${JSON.stringify(slotBranch)}`, workspacePath);
3701
+ return String(result?.stdout ?? "").trim().length > 0;
3702
+ } catch {
3703
+ return null;
3704
+ }
3705
+ }
3706
+ /**
3707
+ * Remove a merged slot's workspace (PAN-3686). A polyrepo slot workspace is an
3708
+ * aggregate directory whose registered git worktrees are the nested sub-repo
3709
+ * checkouts (<slot>/fe, <slot>/api, …), each owned by a different parent
3710
+ * repository. Git cannot remove the aggregate root while nested worktrees
3711
+ * live inside it ("Directory not empty"), so every nested worktree is
3712
+ * detached through the workspace abstraction first, in its owning parent
3713
+ * repo.
3714
+ *
3715
+ * Cleanup is atomic in intent: a read-only preflight proves every nested repo
3716
+ * safe AND removable, and decides the aggregate root's removal route, before
3717
+ * the first mutation. Discovering an unsafe or unremovable nested checkout
3718
+ * after an earlier one was already detached is the Tier-1 partial-cleanup
3719
+ * defect the preflight exists to prevent (PAN-3686 post-deploy review). Any
3720
+ * preflight failure defers the whole slot with zero removals.
3721
+ *
3722
+ * Never discards unmerged or locally-modified nested work. PAN-3695: a slot
3723
+ * that reached merged status with unmerged nested branches is INTEGRATED here,
3724
+ * not just deferred — each unmerged nested slot branch is merged through the
3725
+ * canonical nested merge path (`git merge --no-ff` into the per-repo base
3726
+ * feature-workspace checkout, same as verifyAndMergeSlot) and ancestry is
3727
+ * re-verified repo by repo before any removal. A repo whose merge is pending
3728
+ * or failed defers the whole slot with an actionable repo-specific reason;
3729
+ * successful per-repo merges are preserved and the next pass retries the rest.
3730
+ * Uncommitted nested changes still defer the slot untouched.
3731
+ */
3732
+ async function removeSlotWorkspace(issueId, workspacePath, slotWorkspace, slotBranch, slot, deps, actions) {
3733
+ const defer = (reason) => {
3734
+ actions.push(`[swarm] gc deferred slot ${slot.slotIndex} (item ${slot.itemId}) for ${issueId}: ${reason}`);
3735
+ return false;
3736
+ };
3737
+ const { isPolyrepo, nested } = (deps.listSlotWorkspaceWorktrees ?? resolveSlotWorkspaceWorktreesSync)(issueId, slotWorkspace);
3738
+ if (nested.length > 0) {
3739
+ const mergeFailures = await mergeNestedSlotBranches(issueId, workspacePath, slotBranch, nested, deps);
3740
+ if (mergeFailures.length > 0) return defer(`nested merge incomplete: ${mergeFailures.join("; ")}`);
3741
+ }
3742
+ for (const worktree of nested) {
3743
+ const blocked = await nestedWorktreeDirtyReason(deps.runGitCommand, worktree);
3744
+ if (blocked) return defer(`preserving nested work: ${blocked}`);
3745
+ }
3746
+ for (const worktree of nested) {
3747
+ const registered = await isRegisteredWorktree(deps.runGitCommand, worktree.parentRepo, worktree.dir);
3748
+ if (registered === null) return defer(`${worktree.repoKey}: worktree registration in parent repo could not be determined`);
3749
+ if (!registered) return defer(`${worktree.repoKey}: nested worktree is not registered in its parent repo (an earlier partial cleanup may have detached it); run pan swarm reset ${issueId}`);
3750
+ }
3751
+ const aggregateRegistered = await isRegisteredWorktree(deps.runGitCommand, workspacePath, slotWorkspace);
3752
+ if (aggregateRegistered === null) return defer("aggregate worktree registration could not be determined");
3753
+ const detached = [];
3754
+ for (const worktree of nested) {
3755
+ try {
3756
+ await deps.runGitCommand(`git worktree remove --force ${JSON.stringify(worktree.dir)}`, worktree.parentRepo);
3757
+ detached.push(worktree.repoKey);
3758
+ } catch (error) {
3759
+ const partial = detached.length > 0 ? ` (already detached: ${detached.join(", ")})` : "";
3760
+ return defer(`nested worktree remove failed in ${worktree.repoKey}${partial}: ${error instanceof Error ? error.message : String(error)}`);
3761
+ }
3762
+ try {
3763
+ await deps.runGitCommand(`git branch -D ${JSON.stringify(slotBranch)}`, worktree.parentRepo);
3764
+ } catch (error) {
3765
+ actions.push(`[swarm] gc note slot ${slot.slotIndex} (item ${slot.itemId}) for ${issueId}: nested branch ${slotBranch} delete failed in ${worktree.repoKey}: ${error instanceof Error ? error.message : String(error)}`);
3766
+ }
3767
+ }
3768
+ if (!aggregateRegistered && isPolyrepo) try {
3769
+ await (deps.removeDirectory ?? ((path) => rm(path, {
3770
+ recursive: true,
3771
+ force: true
3772
+ })))(slotWorkspace);
3773
+ return true;
3774
+ } catch (rmError) {
3775
+ return defer(`aggregate directory remove failed: ${rmError instanceof Error ? rmError.message : String(rmError)}`);
3776
+ }
3777
+ try {
3778
+ await deps.runGitCommand(`git worktree remove --force ${JSON.stringify(slotWorkspace)}`, workspacePath);
3779
+ return true;
3780
+ } catch (error) {
3781
+ const message = error instanceof Error ? error.message : String(error);
3782
+ if (isPolyrepo && /is not a working tree/.test(message)) try {
3783
+ await (deps.removeDirectory ?? ((path) => rm(path, {
3784
+ recursive: true,
3785
+ force: true
3786
+ })))(slotWorkspace);
3787
+ return true;
3788
+ } catch (rmError) {
3789
+ return defer(`aggregate directory remove failed: ${rmError instanceof Error ? rmError.message : String(rmError)}`);
3790
+ }
3791
+ return defer(`worktree remove failed: ${message}`);
3792
+ }
3793
+ }
3794
+ /**
3795
+ * Whether `worktreeDir` is a registered worktree of the repository at
3796
+ * `repoDir`, or null when the registration state cannot be determined. The
3797
+ * porcelain list always names at least the repository's own main worktree, so
3798
+ * a response with no `worktree` lines is an anomaly, not proof of "absent".
3799
+ * Shared with `pan swarm reset` (PAN-3713), which must distinguish an
3800
+ * already-unregistered nested worktree (the desired postcondition) from a
3801
+ * genuine removal failure.
3802
+ */
3803
+ async function isRegisteredWorktree(runGitCommand, repoDir, worktreeDir) {
3804
+ try {
3805
+ const result = await runGitCommand("git worktree list --porcelain", repoDir);
3806
+ const paths = String(result?.stdout ?? "").split("\n").filter((line) => line.startsWith("worktree ")).map((line) => line.slice(9).trim());
3807
+ if (paths.length === 0) return null;
3808
+ return paths.includes(worktreeDir);
3809
+ } catch {
3810
+ return null;
3811
+ }
3812
+ }
3813
+ /**
3814
+ * Merge every nested slot branch that still has commits its per-repo feature
3815
+ * branch lacks, through the canonical nested merge path (PAN-3695): the merge
3816
+ * runs in the repo's base feature-workspace checkout, then ancestry is
3817
+ * re-verified by re-counting `featureBranch..slotBranch` — a merge command
3818
+ * exiting 0 is not proof the slot head landed — and the parent feature branch
3819
+ * is pushed to origin so the work actually leaves the machine. A dirty base
3820
+ * checkout refuses the merge, and a missing or degraded base checkout fails
3821
+ * the repo outright — without it, remote durability cannot be verified, even
3822
+ * when the local feature branch already contains the slot head. Every repo is
3823
+ * attempted even after a sibling fails, so successful merges are preserved and
3824
+ * only the failed repos are retried on the next pass. Returns the per-repo
3825
+ * failure reasons; an empty list means every nested repo's slot branch is an
3826
+ * ancestor of its pushed feature branch.
3827
+ */
3828
+ async function mergeNestedSlotBranches(issueId, workspacePath, slotBranch, nested, deps) {
3829
+ const failures = [];
3830
+ const baseRoots = new Map((deps.listFeatureWorkspaceRepoRoots ?? resolveWorkspaceRepoRootsSync)(issueId, workspacePath).map((root) => [root.repoKey, root]));
3831
+ for (const worktree of nested) {
3832
+ const ahead = await countCommitsAhead(deps.runGitCommand, worktree.parentRepo, worktree.featureBranch, slotBranch);
3833
+ if (ahead === null) {
3834
+ failures.push(`${worktree.repoKey}: merge state of ${slotBranch} against ${worktree.featureBranch} could not be determined`);
3835
+ continue;
3836
+ }
3837
+ const baseRoot = baseRoots.get(worktree.repoKey);
3838
+ if (!baseRoot || baseRoot.degradedPolyrepo) {
3839
+ failures.push(ahead > 0 ? `${worktree.repoKey}: no base feature-workspace checkout for ${worktree.featureBranch} — cannot merge ${slotBranch} (${ahead} unmerged commit(s))` : `${worktree.repoKey}: no base feature-workspace checkout for ${worktree.featureBranch} — cannot verify and push remote durability`);
3840
+ continue;
3841
+ }
3842
+ if (ahead > 0) {
3843
+ const baseDirty = await baseCheckoutDirtyReason(deps.runGitCommand, worktree, baseRoot, slotBranch);
3844
+ if (baseDirty) {
3845
+ failures.push(baseDirty);
3846
+ continue;
3847
+ }
3848
+ try {
3849
+ await deps.runGitCommand(`git merge --no-ff ${JSON.stringify(slotBranch)}`, baseRoot.dir);
3850
+ } catch (error) {
3851
+ await deps.runGitCommand("git merge --abort", baseRoot.dir).catch(() => {});
3852
+ failures.push(`${worktree.repoKey}: ${slotBranch} did not merge cleanly into ${worktree.featureBranch}: ${error instanceof Error ? error.message : String(error)}`);
3853
+ continue;
3854
+ }
3855
+ const remaining = await countCommitsAhead(deps.runGitCommand, worktree.parentRepo, worktree.featureBranch, slotBranch);
3856
+ if (remaining !== 0) {
3857
+ failures.push(`${worktree.repoKey}: ancestry verification failed — ${slotBranch} still has ${remaining ?? "an unknown number of"} commit(s) not in ${worktree.featureBranch} after merge`);
3858
+ continue;
3859
+ }
3860
+ }
3861
+ const unpushed = await countCommitsAhead(deps.runGitCommand, baseRoot.dir, `origin/${worktree.featureBranch}`, worktree.featureBranch);
3862
+ if (ahead > 0 || unpushed === null || unpushed > 0) try {
3863
+ await deps.runGitCommand(`git push origin ${JSON.stringify(worktree.featureBranch)}`, baseRoot.dir);
3864
+ } catch (error) {
3865
+ failures.push(`${worktree.repoKey}: merged ${slotBranch} into ${worktree.featureBranch} but push to origin failed: ${error instanceof Error ? error.message : String(error)}`);
3866
+ continue;
3867
+ }
3868
+ }
3869
+ return failures;
3870
+ }
3871
+ /**
3872
+ * Why a base feature-workspace checkout must not receive a merge right now, or
3873
+ * null when it is clean. Tracked local modifications block the merge (git would
3874
+ * refuse or, worse, entangle someone's uncommitted work); untracked files do
3875
+ * not, so they are ignored here.
3876
+ */
3877
+ async function baseCheckoutDirtyReason(runGitCommand, worktree, baseRoot, slotBranch) {
3878
+ try {
3879
+ const status = await runGitCommand("git status --porcelain --untracked-files=no", baseRoot.dir);
3880
+ if (String(status?.stdout ?? "").trim().length > 0) return `${worktree.repoKey}: base feature checkout of ${worktree.featureBranch} has uncommitted changes — refusing to merge ${slotBranch}`;
3881
+ } catch {
3882
+ return `${worktree.repoKey}: base feature checkout state of ${worktree.featureBranch} could not be determined — refusing to merge ${slotBranch}`;
3883
+ }
3884
+ return null;
3885
+ }
3886
+ /**
3887
+ * Why a nested slot worktree must be preserved, or null when it is safe to
3888
+ * remove. Any tracked change or non-ignored untracked file blocks removal
3889
+ * (ignored build artifacts do not). Merge state is handled separately by
3890
+ * mergeNestedSlotBranches before this runs.
3891
+ */
3892
+ async function nestedWorktreeDirtyReason(runGitCommand, worktree) {
3893
+ try {
3894
+ const status = await runGitCommand("git status --porcelain --untracked-files=all", worktree.dir);
3895
+ if (String(status?.stdout ?? "").trim().length > 0) return `${worktree.repoKey}: worktree has uncommitted changes`;
3896
+ } catch {
3897
+ return `${worktree.repoKey}: worktree status could not be determined`;
3898
+ }
3899
+ return null;
3900
+ }
3901
+ async function countCommitsAhead(runGitCommand, parentRepo, featureBranch, slotBranch) {
3902
+ try {
3903
+ const result = await runGitCommand(`git rev-list --count ${JSON.stringify(featureBranch)}..${JSON.stringify(slotBranch)}`, parentRepo);
3904
+ const stdout = String(result?.stdout ?? "").trim();
3905
+ if (!/^\d+$/.test(stdout)) return null;
3906
+ return Number(stdout);
3907
+ } catch {
3908
+ return null;
3909
+ }
3910
+ }
3911
+ //#endregion
3912
+ //#region ../../lib/cloister/swarm-tiered-hooks.ts
3913
+ /**
3914
+ * PAN-2385 — tiered-execution commit hooks for the swarm dispatch path.
3915
+ *
3916
+ * The tier-feed and tier-supervisor libraries shipped with PAN-1791/2222 but
3917
+ * had no production caller: commits landed and neither the standing crew nor
3918
+ * the subscribe-policy supervisor ever heard about them (found live during
3919
+ * the first Standing Crew run, PAN-2383). This module is the ignition.
3920
+ *
3921
+ * Fired from mergeReadySlots after a slot's bead commits merge into the
3922
+ * feature workspace:
3923
+ * 1. broadcastCommit — every live slot agent hears the rendered diff
3924
+ * (ingestion-only; everyone-hears-everything per docs/TIERED-EXECUTION.md).
3925
+ * 2. shouldSupervise(item, subscribe) → deliverCommitForReview — the
3926
+ * standing supervisor reviews per its subscribe policy. This is
3927
+ * independent of supervisor.owns_inspection, which only routes
3928
+ * `pan inspect`.
3929
+ *
3930
+ * Both hooks are best-effort: the commit has already landed, so a delivery
3931
+ * failure logs loudly and never blocks the merge loop.
3932
+ */
3933
+ init_tmux();
3934
+ init_config_yaml();
3935
+ init_slot_reconcile();
3936
+ const execAsync$3 = promisify(exec);
3937
+ const defaultDeps$5 = {
3938
+ loadConfig: loadConfigSync,
3939
+ getHeadSha: async (workspacePath) => (await execAsync$3("git rev-parse HEAD", { cwd: workspacePath })).stdout.trim(),
3940
+ listAssignments: listSlotAssignments,
3941
+ isSessionAlive: (sessionName) => Effect.runPromise(sessionExists(sessionName)),
3942
+ broadcast: broadcastCommit,
3943
+ ensureSupervisor: spawnTierSupervisor,
3944
+ deliverReview: deliverCommitForReview,
3945
+ loadPrd: loadPrdDraft
3946
+ };
3947
+ /** Resolve the tier name a bead belongs to, for the feed header. Falls back to
3948
+ * the slot label when the tier table cannot resolve the item (fail-open here is
3949
+ * correct: the feed is informational and the commit has already landed). */
3950
+ function tierNameForItem(item, tiered, slotIndex) {
3951
+ if (item) try {
3952
+ return resolveTier(item, tiered).tierName;
3953
+ } catch {}
3954
+ return `slot-${slotIndex}`;
3955
+ }
3956
+ /**
3957
+ * Fire the commit feed + supervisor review for a bead whose commits just
3958
+ * merged into the feature workspace. Returns deacon action-log lines.
3959
+ */
3960
+ async function fireTieredCommitHooks(options, deps = defaultDeps$5) {
3961
+ const actions = [];
3962
+ const { issueId, workspacePath, item, doc } = options;
3963
+ let tiered;
3964
+ try {
3965
+ tiered = deps.loadConfig().config.tieredExecution;
3966
+ } catch (err) {
3967
+ actions.push(`[tiered] skipped commit hooks for ${issueId}: config load failed (${err instanceof Error ? err.message : String(err)})`);
3968
+ return actions;
3969
+ }
3970
+ if (!tiered || !resolveTieredExecutionEnabled(tiered, doc.plan.metadata)) return actions;
3971
+ let sha;
3972
+ try {
3973
+ sha = await deps.getHeadSha(workspacePath);
3974
+ } catch (err) {
3975
+ actions.push(`[tiered] commit hooks for ${issueId} item ${item.id} could not resolve HEAD: ${err instanceof Error ? err.message : String(err)}`);
3976
+ return actions;
3977
+ }
3978
+ try {
3979
+ const itemsById = new Map(doc.plan.items.map((planItem) => [planItem.id, planItem]));
3980
+ const assignments = deps.listAssignments(issueId, workspacePath);
3981
+ const listeners = [];
3982
+ for (const assignment of assignments) {
3983
+ if (!assignment.agentId) continue;
3984
+ if (!await deps.isSessionAlive(assignment.agentId)) continue;
3985
+ listeners.push({
3986
+ tierName: tierNameForItem(itemsById.get(assignment.itemId), tiered, assignment.slotIndex),
3987
+ agentId: assignment.agentId
3988
+ });
3989
+ }
3990
+ if (listeners.length > 0) {
3991
+ const delivered = (await deps.broadcast({
3992
+ workspace: workspacePath,
3993
+ issueId,
3994
+ sha,
3995
+ itemTitle: item.title,
3996
+ itemId: item.id,
3997
+ tiers: listeners,
3998
+ feedConfig: tiered.feed
3999
+ })).filter((delivery) => delivery.result.ok).length;
4000
+ actions.push(`[tiered] broadcast commit ${sha.slice(0, 10)} (item ${item.id}) for ${issueId} to ${delivered}/${listeners.length} standing agents`);
4001
+ }
4002
+ } catch (err) {
4003
+ actions.push(`[tiered] feed broadcast FAILED for ${issueId} item ${item.id}: ${err instanceof Error ? err.message : String(err)}`);
4004
+ }
4005
+ try {
4006
+ const supervisor = tiered.supervisor;
4007
+ if (supervisor && shouldSupervise(item, supervisor.subscribe)) {
4008
+ const agentId = supervisorAgentId(issueId);
4009
+ if (!await deps.isSessionAlive(agentId)) {
4010
+ await deps.ensureSupervisor(issueId, supervisor, { workspace: workspacePath });
4011
+ actions.push(`[tiered] spawned standing supervisor ${agentId} for ${issueId}`);
4012
+ }
4013
+ const prdMarkdown = await deps.loadPrd(workspacePath, issueId).catch(() => void 0);
4014
+ await deps.deliverReview({
4015
+ supervisorAgentId: agentId,
4016
+ workspacePath,
4017
+ issueId,
4018
+ item,
4019
+ sha,
4020
+ itemId: item.id,
4021
+ prdMarkdown
4022
+ });
4023
+ actions.push(`[tiered] supervisor review dispatched for ${issueId} item ${item.id} (subscribe=${supervisor.subscribe})`);
4024
+ }
4025
+ } catch (err) {
4026
+ actions.push(`[tiered] supervisor review FAILED for ${issueId} item ${item.id}: ${err instanceof Error ? err.message : String(err)}`);
4027
+ }
4028
+ return actions;
4029
+ }
4030
+ //#endregion
4031
+ //#region ../../lib/cloister/redrive-gate.ts
4032
+ init_recovery_trip();
4033
+ /**
4034
+ * PAN-2543 shared autonomous re-drive gate.
4035
+ *
4036
+ * Recovery entry points classify agent gates, apply the intent policy, and
4037
+ * consult the cached memory verdict through this one function before acting.
4038
+ * Callers still reserve their role-specific concurrency slot after admission.
4039
+ */
4040
+ init_agent_state();
4041
+ function decideAutonomousRedrive(state, context = {}) {
4042
+ const gateDecision = decideResumeGate(getAgentResumeGateBlockReason(state), "autonomous", context);
4043
+ if (gateDecision.decision !== "proceed") return {
4044
+ decision: "defer",
4045
+ reason: gateDecision.reason,
4046
+ ...gateDecision.decision === "block" && gateDecision.needsYou ? { needsYou: true } : {}
4047
+ };
4048
+ const memoryVerdict = getCachedMemoryVerdict();
4049
+ if (memoryVerdict && memoryVerdict.band !== "ok") return {
4050
+ decision: "defer",
4051
+ reason: `memory pressure is ${memoryVerdict.band}`
4052
+ };
4053
+ return {
4054
+ decision: "proceed",
4055
+ gateDecision
4056
+ };
4057
+ }
4058
+ async function decideAgentAutonomousRedrive(state, agentDir, owesRework, deps = {}) {
4059
+ const admission = decideAutonomousRedrive(state, {
4060
+ hasCompletedHandoff: existsSync$1(join(agentDir, "completed")) || existsSync$1(join(agentDir, "completed.processed")),
4061
+ owesRework
4062
+ });
4063
+ if (admission.decision === "defer") return admission;
4064
+ const agentId = basename(agentDir);
4065
+ const pendingDecision = await (deps.detectPendingOperatorDecision ?? detectPendingOperatorDecision)(agentId);
4066
+ if (pendingDecision) return {
4067
+ decision: "defer",
4068
+ reason: `agent is waiting on an operator decision (${pendingDecision.reason})`,
4069
+ needsYou: true
4070
+ };
4071
+ return admission;
4072
+ }
4073
+ //#endregion
4074
+ //#region ../../lib/cloister/swarm-failed-slot.ts
4075
+ init_record_update();
4076
+ init_agent_state();
4077
+ //#endregion
4078
+ //#region ../../lib/cloister/swarm-blocked-slot.ts
4079
+ init_project_repos();
4080
+ const execFileAsync$3 = promisify(execFile);
4081
+ async function prepareReleasedSwarmSlot(issueId, workspacePath, slotIndex, itemId, branch) {
4082
+ await ensureRegisteredSlotWorktree(issueId, workspacePath, {
4083
+ agentId: `agent-${issueId.toLowerCase()}-slot-${slotIndex}`,
4084
+ branch,
4085
+ workspace: `${workspacePath}-slot-${slotIndex}`,
4086
+ slotIndex,
4087
+ slotItemId: itemId
4088
+ });
4089
+ }
4090
+ async function defaultIsSlotBranchPushed(workspacePath, issueId, branch) {
4091
+ const slotIndex = branch.match(/-slot-(\d+)(?:-attempt-\d+)?$/)?.[1];
4092
+ if (!slotIndex) return false;
4093
+ const roots = resolveWorkspaceRepoRootsSync(issueId, `${workspacePath}-slot-${slotIndex}`);
4094
+ if (roots.length === 0 || roots.some((root) => root.degradedPolyrepo)) return false;
4095
+ try {
4096
+ return (await Promise.all(roots.map(async (root) => {
4097
+ await refreshDurableSlotRef(root.dir, branch);
4098
+ return true;
4099
+ }))).every(Boolean);
4100
+ } catch {
4101
+ return false;
4102
+ }
4103
+ }
4104
+ /** Preserve a blocked attempt and provision a unique branch identity for slot reuse. */
4105
+ async function archiveBlockedSwarmSlot(issueId, workspacePath, slotIndex, branch, now = /* @__PURE__ */ new Date()) {
4106
+ const releasedAt = now.toISOString();
4107
+ const suffix = releasedAt.replace(/[-:.TZ]/g, "");
4108
+ const slotWorkspace = `${workspacePath}-slot-${slotIndex}`;
4109
+ const archivedWorktree = `${slotWorkspace}-blocked-${suffix}`;
4110
+ const archivedBranch = `${branch}-blocked-${suffix}`;
4111
+ const replacementBranch = `feature/${issueId.toLowerCase()}-slot-${slotIndex}-attempt-${suffix}`;
4112
+ const slotRoots = resolveWorkspaceRepoRootsSync(issueId, slotWorkspace);
4113
+ const baseRoots = new Map(resolveWorkspaceRepoRootsSync(issueId, workspacePath).map((root) => [root.repoKey, root]));
4114
+ if (slotRoots.length === 0 || slotRoots.some((root) => root.degradedPolyrepo)) throw new Error(`Cannot archive blocked slot ${slotIndex}: repository roots are unavailable.`);
4115
+ for (const root of slotRoots) await execFileAsync$3("git", [
4116
+ "push",
4117
+ "origin",
4118
+ `${await refreshDurableSlotRef(root.dir, branch)}:refs/heads/${archivedBranch}`
4119
+ ], { cwd: root.dir });
4120
+ await rename(slotWorkspace, archivedWorktree);
4121
+ for (const root of slotRoots) {
4122
+ const baseRoot = baseRoots.get(root.repoKey);
4123
+ if (!baseRoot) throw new Error(`Cannot archive blocked slot ${slotIndex}: missing base repository ${root.repoKey}.`);
4124
+ const nestedPath = relative(slotWorkspace, root.dir);
4125
+ const archivedRoot = nestedPath ? resolve(archivedWorktree, nestedPath) : archivedWorktree;
4126
+ await execFileAsync$3("git", [
4127
+ "worktree",
4128
+ "repair",
4129
+ archivedRoot
4130
+ ], { cwd: baseRoot.dir });
4131
+ await execFileAsync$3("git", [
4132
+ "branch",
4133
+ archivedBranch,
4134
+ branch
4135
+ ], { cwd: baseRoot.dir });
4136
+ await execFileAsync$3("git", ["switch", archivedBranch], { cwd: archivedRoot });
4137
+ }
4138
+ return {
4139
+ archivedBranch,
4140
+ archivedWorktree,
4141
+ replacementBranch,
4142
+ releasedAt
4143
+ };
4144
+ }
4145
+ async function refreshDurableSlotRef(workspace, branch) {
4146
+ const remoteRef = `refs/remotes/origin/${branch}`;
4147
+ await execFileAsync$3("git", [
4148
+ "fetch",
4149
+ "--no-tags",
4150
+ "origin",
4151
+ `+refs/heads/${branch}:${remoteRef}`
4152
+ ], { cwd: workspace });
4153
+ await execFileAsync$3("git", [
4154
+ "merge-base",
4155
+ "--is-ancestor",
4156
+ `refs/heads/${branch}`,
4157
+ remoteRef
4158
+ ], { cwd: workspace });
4159
+ return remoteRef;
4160
+ }
4161
+ //#endregion
4162
+ //#region ../../lib/cloister/swarm-foreman.ts
4163
+ init_messaging();
4164
+ init_projects();
4165
+ init_tmux();
4166
+ init_work_agent_prompt();
4167
+ const defaultDeps$4 = {
4168
+ listSessionNamesSync: () => listSessionNamesSync(),
4169
+ messageAgent,
4170
+ buildWorkAgentPrompt,
4171
+ spawnRun,
4172
+ resolveProjectFromIssueSync
4173
+ };
4174
+ async function ensureSwarmForeman(issueId, workspacePath, options, deps = defaultDeps$4) {
4175
+ const issue = issueId.toUpperCase();
4176
+ const agentId = `agent-${issue.toLowerCase()}`;
4177
+ if (deps.listSessionNamesSync().includes(agentId)) {
4178
+ await deps.messageAgent(agentId, options.prompt ?? `Continue managing ${issue} as its swarm foreman. Run pan swarm status ${issue} --json before acting.`, "pan-swarm");
4179
+ return [`[swarm] attached to live foreman ${agentId} for ${issue}`];
4180
+ }
4181
+ const basePrompt = await deps.buildWorkAgentPrompt({
4182
+ issueId: issue,
4183
+ env: "LOCAL",
4184
+ workspacePath,
4185
+ projectRoot: deps.resolveProjectFromIssueSync(issue)?.projectPath
4186
+ });
4187
+ return [`[swarm] spawned foreman ${(await deps.spawnRun(issue, "work", {
4188
+ workspace: workspacePath,
4189
+ prompt: options.prompt ? `${basePrompt}\n\n${options.prompt}` : basePrompt,
4190
+ foreman: true,
4191
+ startedBy: options.startedBy
4192
+ })).id} for ${issue}`];
4193
+ }
4194
+ //#endregion
4195
+ //#region ../../lib/cloister/swarm-foreman-liveness.ts
4196
+ init_activity_logger();
4197
+ init_slot_reconcile();
4198
+ init_concurrency();
4199
+ const defaultDeps$3 = {
4200
+ listSlotAssignments,
4201
+ readSwarmHold,
4202
+ workResumeSlotsAvailable,
4203
+ ensureSwarmForeman,
4204
+ writeSwarmHold,
4205
+ emitActivityEntry: emitActivityEntrySync
4206
+ };
4207
+ const respawnFailures = /* @__PURE__ */ new Map();
4208
+ async function maintainSwarmForeman(issueId, workspacePath, reconciled, sessions, overrides = {}, allowSpawn = true, bootstrap = false) {
4209
+ const definedOverrides = Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0));
4210
+ const deps = {
4211
+ ...defaultDeps$3,
4212
+ ...definedOverrides
4213
+ };
4214
+ const issueLower = issueId.toLowerCase();
4215
+ if (!allowSpawn) return [];
4216
+ const mergedSlotIndexes = new Set(reconciled.merged.map((slot) => slot.slotIndex));
4217
+ if (!(bootstrap || sessions.some((name) => name.startsWith(`agent-${issueLower}-slot-`)) || reconciled.branches.some((branch) => !mergedSlotIndexes.has(branch.slotIndex)) || deps.listSlotAssignments(issueId, workspacePath).length > 0)) {
4218
+ respawnFailures.delete(issueId);
4219
+ return [];
4220
+ }
4221
+ if (sessions.includes(`agent-${issueLower}`) || deps.readSwarmHold(workspacePath, issueId)) return [];
4222
+ if (deps.workResumeSlotsAvailable() <= 0) return [`[swarm-janitor] deferred foreman respawn for ${issueId}: resource governor`];
4223
+ const failures = respawnFailures.get(issueId) ?? 0;
4224
+ if (failures >= 3) return [];
4225
+ try {
4226
+ const prompt = `Resume ${issueId} swarm foreman duties: read .pan/continue.json, run pan swarm status ${issueId} --json, reconcile current state, then continue the wave loop.`;
4227
+ const actions = await deps.ensureSwarmForeman(issueId, workspacePath, {
4228
+ startedBy: "deacon:swarm-janitor",
4229
+ prompt
4230
+ });
4231
+ respawnFailures.delete(issueId);
4232
+ return actions;
4233
+ } catch (error) {
4234
+ const count = failures + 1;
4235
+ respawnFailures.set(issueId, count);
4236
+ const actions = [`[swarm-janitor] foreman respawn failed for ${issueId} (${count}/3): ${error instanceof Error ? error.message : String(error)}`];
4237
+ if (count < 3) return actions;
4238
+ const message = `${issueId} swarm halted after 3 consecutive foreman respawn failures; operator action is required.`;
4239
+ await deps.writeSwarmHold(workspacePath, issueId, {
4240
+ reason: message,
4241
+ setBy: "deacon:swarm-janitor",
4242
+ at: (/* @__PURE__ */ new Date()).toISOString()
4243
+ });
4244
+ deps.emitActivityEntry({
4245
+ source: "cloister",
4246
+ level: "error",
4247
+ issueId,
4248
+ message
4249
+ });
4250
+ actions.push(`[swarm-janitor] ${message}`);
4251
+ return actions;
4252
+ }
4253
+ }
4254
+ //#endregion
4255
+ //#region ../../lib/cloister/deacon-swarm.ts
4256
+ init_messaging();
4257
+ init_spawn();
4258
+ init_slot_reconcile();
4259
+ init_record();
4260
+ init_record_update();
4261
+ init_tmux();
4262
+ init_io();
4263
+ init_review_status();
4264
+ init_concurrency();
4265
+ const execAsync$2 = promisify(exec);
4266
+ const DEFAULT_SWARM_STALL_THRESHOLD_MS = 1800 * 1e3;
4267
+ const slotProgressObservations = /* @__PURE__ */ new Map();
4268
+ const defaultDeps$2 = {
4269
+ findSpecByIssue,
4270
+ listFeatureWorkspaces: () => listFeatureWorkspaces({ includeSlotWorkspaces: false }),
4271
+ reconcileSlotState,
4272
+ listSessionNames: () => Effect.runPromise(listSessionNames()),
4273
+ isPaneDead: (sessionName) => Effect.runPromise(isPaneDead(sessionName)),
4274
+ getPaneExitStatus: async (sessionName) => {
4275
+ const raw = (await Effect.runPromise(listPaneValues(sessionName, "#{pane_dead_status}")))[0]?.trim();
4276
+ if (!raw) return null;
4277
+ const status = Number(raw);
4278
+ return Number.isFinite(status) ? status : null;
4279
+ },
4280
+ getAgentRuntimeState: (agentId) => Effect.runPromise(getAgentRuntimeSnapshot(agentId)),
4281
+ getPaneOutputDigest: async (sessionName) => Effect.runPromise(capturePane(sessionName, 200)),
4282
+ getBranchTipCommitTime: async (workspacePath, branch) => {
4283
+ try {
4284
+ const { stdout } = await execAsync$2(`git log -1 --format=%ct ${JSON.stringify(branch)}`, { cwd: workspacePath });
4285
+ const seconds = Number(stdout.trim());
4286
+ return Number.isFinite(seconds) ? seconds * 1e3 : null;
4287
+ } catch {
4288
+ return null;
4289
+ }
4290
+ },
4291
+ getSlotBranchAheadCount: defaultGetSlotBranchAheadCount,
4292
+ isSlotWorktreeClean: defaultIsSlotWorktreeClean,
4293
+ isSlotBranchPushed: defaultIsSlotBranchPushed,
4294
+ archiveBlockedSlot: archiveBlockedSwarmSlot,
4295
+ prepareReleasedSlot: prepareReleasedSwarmSlot,
4296
+ sendCompletionNudge: defaultSendCompletionNudge,
4297
+ slotWorktreeExists: existsSync$1,
4298
+ verifyAndMergeSlot,
4299
+ applyTaskOperationToPlanFile: (issueId, operation, workspacePath = "") => {
4300
+ return applyTaskStatusChange(resolveProjectForIssue(issueId) ?? getProjectConfigFromWorkspacePath(workspacePath), issueId, operation);
4301
+ },
4302
+ fireTieredCommitHooks,
4303
+ recordSlotAssignment,
4304
+ clearSlotAssignment,
4305
+ runGitCommand: (command, cwd) => execAsync$2(command, { cwd }),
4306
+ registeredSlotCapacityAvailable: (issueId, selectedCount) => registeredSlotCapacityAvailable(issueId, selectedCount),
4307
+ tryReserveSwarmSlot,
4308
+ releaseSwarmSlot,
4309
+ spawnRun,
4310
+ getIssueHold: defaultGetIssueHold,
4311
+ shouldDispatch: defaultShouldDispatch,
4312
+ readSwarmHold,
4313
+ getMaxSlotIndex: defaultGetMaxSlotIndex,
4314
+ listSlotAssignments,
4315
+ listReleasedSlotIndexes: (issueId, workspacePath) => Object.keys(readIssueRecordForWorkspaceSync(workspacePath, issueId)?.swarm?.releasedBlockedSlots ?? {}).map(Number),
4316
+ getReleasedSlotBranch: (issueId, workspacePath, slotIndex) => readIssueRecordForWorkspaceSync(workspacePath, issueId)?.swarm?.releasedBlockedSlots?.[String(slotIndex)]?.replacementBranch,
4317
+ clearReleasedSlot: clearReleasedBlockedSwarmSlot,
4318
+ readStatusOverrides: defaultReadStatusOverrides,
4319
+ readSlotCompletion: defaultReadSlotCompletion,
4320
+ clearSlotCompletion: clearSwarmSlotCompletion,
4321
+ recordForemanTakeover: writeSwarmForemanTakeover,
4322
+ ensureSwarmForeman,
4323
+ sendStallEvent: (agentId, message) => messageAgent(agentId, message, "deacon:swarm-stall"),
4324
+ resolveAutomaticSwarmPolicy
4325
+ };
4326
+ function defaultGetMaxSlotIndex() {
4327
+ return Math.max(1, getConcurrencyLimits().reservedSwarmSlots);
4328
+ }
4329
+ function defaultGetIssueHold(issueId) {
4330
+ try {
4331
+ return getReviewStatusSync(issueId);
4332
+ } catch {
4333
+ return null;
4334
+ }
4335
+ }
4336
+ function defaultReadStatusOverrides(workspacePath, issueId) {
4337
+ const normalized = issueId.toUpperCase();
4338
+ const record = readIssueRecordForWorkspaceSync(workspacePath, normalized);
4339
+ if (record === null && existsSync$1(getIssueRecordPathForWorkspace(workspacePath, normalized))) {
4340
+ console.warn(`[swarm] record unreadable for ${normalized} — treating as no overrides; see .corrupt sidecar`);
4341
+ return;
4342
+ }
4343
+ return record?.statusOverrides;
4344
+ }
4345
+ /**
4346
+ * PAN-2372 WI-4 / FR-6: read a slot's durable completion marker from the record
4347
+ * door. Returns undefined when no record or no marker exists. Used by
4348
+ * classifyInFlightSlots to recognize a slot whose `pan done` durably recorded
4349
+ * completion even when the runtime plane (agent state, tmux session) is gone.
4350
+ */
4351
+ function defaultReadSlotCompletion(workspacePath, issueId, slotIndex) {
4352
+ try {
4353
+ return readIssueRecordForWorkspaceSync(workspacePath, issueId.toUpperCase())?.swarm?.slotCompletions?.[String(slotIndex)];
4354
+ } catch {
4355
+ return;
4356
+ }
4357
+ }
4358
+ function defaultShouldDispatch(issueId) {
4359
+ if (isDeaconGloballyPausedSync()) return false;
4360
+ const hold = defaultGetIssueHold(issueId);
4361
+ return !(hold?.stuck || hold?.deaconIgnored);
4362
+ }
4363
+ async function swarmJanitorPass(deps = defaultDeps$2) {
4364
+ const actions = [];
4365
+ const sessions = await deps.listSessionNames();
4366
+ for (const workspace of deps.listFeatureWorkspaces()) {
4367
+ const issueId = workspace.issueId.toUpperCase();
4368
+ const spec = await Effect.runPromise((deps.findSpecByIssue ?? findSpecByIssue)(workspace.projectPath, issueId));
4369
+ if (!spec) continue;
4370
+ const reconciled = await deps.reconcileSlotState(issueId, workspace.workspacePath, spec.document);
4371
+ actions.push(`[swarm-janitor] enumerated ${issueId}`);
4372
+ actions.push(...await gcMergedSlots(issueId, workspace.workspacePath, reconciled.merged, deps));
4373
+ actions.push(...await gcOrphanedSlots(issueId, workspace.workspacePath, reconciled, deps));
4374
+ const automatic = (deps.resolveAutomaticSwarmPolicy ?? resolveAutomaticSwarmPolicy)(issueId, analyzeSwarmReadiness(spec.document).swarmEligible);
4375
+ actions.push(...await maintainSwarmForeman(issueId, workspace.workspacePath, reconciled, sessions, deps, automatic.policy.mode !== "off", automatic.spawnForeman));
4376
+ const classified = await classifyInFlightSlots(reconciled.inFlight, {
4377
+ ...deps,
4378
+ listSessionNames: async () => sessions
4379
+ }, {
4380
+ issueId,
4381
+ workspacePath: workspace.workspacePath
4382
+ });
4383
+ for (const slot of classified.filter((candidate) => candidate.signal === "stall-event")) {
4384
+ await deps.sendStallEvent?.(`agent-${issueId.toLowerCase()}`, `[swarm-event] slot ${slot.slotIndex} stalled (no progress ${Math.floor((slot.stalledForMs ?? 0) / 6e4)}m)`);
4385
+ actions.push(`[swarm-janitor] notified ${issueId} foreman that slot ${slot.slotIndex} stalled`);
4386
+ }
4387
+ }
4388
+ return actions;
4389
+ }
4390
+ async function classifyInFlightSlots(slots, deps = defaultDeps$2, options = {}) {
4391
+ const sessionNames = new Set(await deps.listSessionNames());
4392
+ const classified = [];
4393
+ const now = options.now ?? Date.now();
4394
+ const stallThresholdMs = options.stallThresholdMs ?? swarmStallThresholdMs();
4395
+ for (const slot of slots) {
4396
+ if (options.workspacePath && options.issueId) {
4397
+ const completion = await (deps.readSlotCompletion ?? defaultReadSlotCompletion)(options.workspacePath, options.issueId, slot.slotIndex);
4398
+ if (completion) {
4399
+ if (completion.itemId === slot.itemId) {
4400
+ classified.push({
4401
+ ...slot,
4402
+ lifecycle: "ready-to-merge",
4403
+ exitStatus: 0,
4404
+ signal: "durable-completion"
4405
+ });
4406
+ continue;
4407
+ }
4408
+ await (deps.clearSlotCompletion ?? clearSwarmSlotCompletion)(options.workspacePath, options.issueId, slot.slotIndex);
4409
+ }
4410
+ }
4411
+ const durableReady = await classifyDurableReadySlot(slot, deps, options);
4412
+ if (!slot.agentId) {
4413
+ if (durableReady) {
4414
+ classified.push(durableReady);
4415
+ continue;
4416
+ }
4417
+ classified.push({
4418
+ ...slot,
4419
+ lifecycle: "failed",
4420
+ reason: "missing-agent"
4421
+ });
4422
+ continue;
4423
+ }
4424
+ if (!sessionNames.has(slot.agentId)) {
4425
+ if (durableReady) {
4426
+ classified.push(durableReady);
4427
+ continue;
4428
+ }
4429
+ classified.push({
4430
+ ...slot,
4431
+ lifecycle: "failed",
4432
+ reason: "vanished-session"
4433
+ });
4434
+ continue;
4435
+ }
4436
+ if (!await deps.isPaneDead(slot.agentId)) {
4437
+ const outputDigest = deps.getPaneOutputDigest ? await deps.getPaneOutputDigest(slot.agentId).catch(() => "") : "";
4438
+ const commitTime = slot.branch && options.workspacePath && deps.getBranchTipCommitTime ? await deps.getBranchTipCommitTime(options.workspacePath, slot.branch).catch(() => null) : null;
4439
+ const progressKey = slotProgressKey(slot);
4440
+ const previous = slotProgressObservations.get(progressKey);
4441
+ if (!previous || previous.commitTime !== commitTime || previous.outputDigest !== outputDigest) {
4442
+ slotProgressObservations.set(progressKey, {
4443
+ commitTime,
4444
+ outputDigest,
4445
+ lastProgressAt: now
4446
+ });
4447
+ if (options.workspacePath && options.issueId) await clearSwarmCompletionObservation(options.workspacePath, options.issueId, progressKey, deps);
4448
+ classified.push({
4449
+ ...slot,
4450
+ lifecycle: "running"
4451
+ });
4452
+ continue;
4453
+ }
4454
+ const stalledForMs = now - previous.lastProgressAt;
4455
+ if (stalledForMs > stallThresholdMs) {
4456
+ const awaitingSignal = await classifyDoneWithoutSignal(slot, deps, options, {
4457
+ commitTime,
4458
+ outputDigest,
4459
+ progressKey,
4460
+ stalledForMs
4461
+ });
4462
+ if (awaitingSignal) {
4463
+ classified.push(awaitingSignal);
4464
+ continue;
4465
+ }
4466
+ classified.push({
4467
+ ...slot,
4468
+ lifecycle: "stalled",
4469
+ reason: "no-progress-timeout",
4470
+ stalledForMs,
4471
+ ...!previous.stallNotified ? { signal: "stall-event" } : {}
4472
+ });
4473
+ previous.stallNotified = true;
4474
+ continue;
4475
+ }
4476
+ classified.push({
4477
+ ...slot,
4478
+ lifecycle: "running"
4479
+ });
4480
+ continue;
4481
+ }
4482
+ const exitStatus = await deps.getPaneExitStatus(slot.agentId);
4483
+ if (exitStatus === 0) {
4484
+ classified.push({
4485
+ ...slot,
4486
+ lifecycle: "ready-to-merge",
4487
+ exitStatus
4488
+ });
4489
+ continue;
4490
+ }
4491
+ classified.push({
4492
+ ...slot,
4493
+ lifecycle: "failed",
4494
+ exitStatus,
4495
+ reason: exitStatus === null ? "pane-exit-unknown" : "pane-exit-nonzero"
4496
+ });
4497
+ }
4498
+ return classified;
4499
+ }
4500
+ function slotProgressKey(slot) {
4501
+ return slot.agentId ?? slot.branch ?? `${slot.itemId}:${slot.slotIndex}`;
4502
+ }
4503
+ function swarmStallThresholdMs() {
4504
+ const raw = process.env.PAN_SWARM_STALL_THRESHOLD_MS;
4505
+ if (!raw) return DEFAULT_SWARM_STALL_THRESHOLD_MS;
4506
+ const parsed = Number(raw);
4507
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_SWARM_STALL_THRESHOLD_MS;
4508
+ }
4509
+ function recordSlotAssignment(workspacePath, issueId, assignment) {
4510
+ return updateIssueRecordForWorkspace(workspacePath, issueId.toUpperCase(), (record) => {
4511
+ const slotAssignments = [...(record.swarm?.slotAssignments ?? []).filter((slot) => slot.slotIndex !== assignment.slotIndex && slot.itemId !== assignment.itemId), {
4512
+ ...assignment,
4513
+ assignedAt: (/* @__PURE__ */ new Date()).toISOString()
4514
+ }].sort((a, b) => a.slotIndex - b.slotIndex);
4515
+ const slotCompletions = { ...record.swarm?.slotCompletions ?? {} };
4516
+ delete slotCompletions[String(assignment.slotIndex)];
4517
+ return {
4518
+ ...record,
4519
+ swarm: {
4520
+ ...record.swarm ?? {},
4521
+ slotAssignments,
4522
+ slotCompletions
4523
+ }
4524
+ };
4525
+ }).then(() => void 0);
4526
+ }
4527
+ function clearSlotAssignment(workspacePath, issueId, slotIndex, itemId) {
4528
+ return clearSwarmSlotOwnership(workspacePath, issueId, slotIndex, itemId);
4529
+ }
4530
+ /**
4531
+ * Whether the issue may register another slot. Counts only tmux-ALIVE slot
4532
+ * sessions (stale agents-table rows blocked all dispatch at zero live slots
4533
+ * after a reset), capped by the same swarm reserve tryReserveSwarmSlot
4534
+ * enforces — never maxWorkAgents (PAN-2214).
4535
+ */
4536
+ function registeredSlotCapacityAvailable(issueId, selectedCount, liveSlotCount = countRunningSwarmSlotsForIssue(issueId), limits = getConcurrencyLimits()) {
4537
+ return liveSlotCount + selectedCount < limits.reservedSwarmSlots;
4538
+ }
4539
+ //#endregion
4540
+ //#region ../../lib/cloister/boot-reconciliation-predicates.ts
2963
4541
  init_agent_state();
2964
4542
  init_review_status();
2965
4543
  function bootReconciliationSkipReason(agent) {
@@ -2973,6 +4551,7 @@ function bootReconciliationSkipReason(agent) {
2973
4551
  }
2974
4552
  //#endregion
2975
4553
  //#region ../../lib/cloister/boot-reconciliation.ts
4554
+ init_control_settings();
2976
4555
  init_agents();
2977
4556
  init_persistent_logger();
2978
4557
  init_config$1();
@@ -3183,7 +4762,6 @@ function startBootReconciliation(options = {}) {
3183
4762
  }
3184
4763
  //#endregion
3185
4764
  //#region ../../lib/agents/pinned-launch.ts
3186
- init_dag();
3187
4765
  init_agent_state();
3188
4766
  function parseFlagValue(content, flag) {
3189
4767
  const escapedFlag = flag.replace("-", "\\-");
@@ -3284,6 +4862,8 @@ init_review_status();
3284
4862
  init_control_settings();
3285
4863
  init_agents$1();
3286
4864
  init_tmux();
4865
+ init_io();
4866
+ init_dag();
3287
4867
  const orphanFailureRecordedForAutoResume = /* @__PURE__ */ new Set();
3288
4868
  function isVerifyPausedAgentState(state) {
3289
4869
  if (state.paused !== true || !state.issueId) return false;
@@ -3539,7 +5119,7 @@ async function nudgeStalledResumeWorkAgents() {
3539
5119
  const message = buildStalledResumePrompt(state);
3540
5120
  if (!message) continue;
3541
5121
  try {
3542
- const { messageAgent } = await import("./agents-megfmQHM.js");
5122
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
3543
5123
  await messageAgent(agentId, message);
3544
5124
  recordCooldown(agentId, ".last-stalled-resume-nudge");
3545
5125
  const action = `Re-sent stalled resume prompt to ${agentId} (${state.issueId})`;
@@ -3653,7 +5233,7 @@ async function nudgeIdleWorkAgentsWithOpenBeads() {
3653
5233
  "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."
3654
5234
  ].join("\n");
3655
5235
  try {
3656
- const { messageAgent } = await import("./agents-megfmQHM.js");
5236
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
3657
5237
  await messageAgent(agentId, message);
3658
5238
  writeFileSync(join$1(getAgentDir(agentId), ".last-bead-nudge"), String(Date.now()), "utf-8");
3659
5239
  const action = `Nudged idle ${agentId} (${state.issueId}) — ${openTasks.length} ready task(s)`;
@@ -3713,6 +5293,10 @@ async function handleAgentStoppedEvent$1(agentId, opts = {}, deps) {
3713
5293
  logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} skipped — role=${state.role} (not auto-resumable)`);
3714
5294
  return null;
3715
5295
  }
5296
+ if (state.foreman === true) {
5297
+ logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} skipped — swarm janitor owns foreman liveness`);
5298
+ return null;
5299
+ }
3716
5300
  if (state.phase === "retained-transcripts") {
3717
5301
  logDeaconEventSync(`handleAgentStoppedEvent: ${agentId} skipped — retired (transcripts retained)`);
3718
5302
  return null;
@@ -4191,6 +5775,7 @@ const cleanupClosedIssueAgentDirectories = (options) => Effect.tryPromise({
4191
5775
  //#region ../../lib/cloister/transcript-retention.ts
4192
5776
  init_state_dir_removal();
4193
5777
  init_agents();
5778
+ init_record();
4194
5779
  init_paths();
4195
5780
  init_tmux();
4196
5781
  function isTranscriptRetentionTerminalAgent(agent, readRecord = readIssueRecordForWorkspaceSync) {
@@ -4384,36 +5969,8 @@ async function sweepTranscriptRetention(options) {
4384
5969
  return [action];
4385
5970
  }
4386
5971
  //#endregion
4387
- //#region ../../lib/pan-dir/record-list.ts
4388
- init_state_home();
4389
- /** Canonical bounded enumeration facet of the issue-record read door. */
4390
- init_record();
4391
- async function readIssueRecordDirectory(recordsDir, records) {
4392
- const entries = await promises$1.readdir(recordsDir, { withFileTypes: true }).catch(() => []);
4393
- await Promise.all(entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map(async (entry) => {
4394
- try {
4395
- const record = JSON.parse(await promises$1.readFile(join(recordsDir, entry.name), "utf-8"));
4396
- if (record.issueId) records.set(record.issueId.toUpperCase(), record);
4397
- } catch (error) {
4398
- console.warn(`[record] Preserving unreadable issue record ${join(recordsDir, entry.name)} during enumeration: ${error instanceof Error ? error.message : String(error)}`);
4399
- }
4400
- }));
4401
- }
4402
- async function listIssueRecords(project) {
4403
- const stateHome = resolveStateReadHomeSync(project);
4404
- const records = /* @__PURE__ */ new Map();
4405
- if (stateHome.migrated) {
4406
- await readIssueRecordDirectory(join(stateHome.root, RECORD_DIRNAME), records);
4407
- return [...records.values()];
4408
- }
4409
- await readIssueRecordDirectory(join(project.path, ".pan", RECORD_DIRNAME), records);
4410
- const workspacesDir = join(project.path, "workspaces");
4411
- const workspaces = await promises$1.readdir(workspacesDir, { withFileTypes: true }).catch(() => []);
4412
- await Promise.all(workspaces.filter((entry) => entry.isDirectory()).map((entry) => readIssueRecordDirectory(join(workspacesDir, entry.name, ".pan", RECORD_DIRNAME), records)));
4413
- return [...records.values()];
4414
- }
4415
- //#endregion
4416
5972
  //#region ../../lib/cloister/state-plane-patrol.ts
5973
+ init_record_update();
4417
5974
  init_issue_closed();
4418
5975
  function statePlaneReconcileEveryCycles(patrolIntervalMs) {
4419
5976
  return Math.max(1, Math.ceil(3600 * 1e3 / patrolIntervalMs));
@@ -4497,6 +6054,7 @@ const recreatedStateWarnings = createRecreatedStateWarningReporter();
4497
6054
  //#endregion
4498
6055
  //#region ../../lib/cloister/deacon-main-divergence.ts
4499
6056
  init_projects();
6057
+ init_state_plane();
4500
6058
  async function recordMainDivergenceHealth(state, projects = listProjectsSync(), measure = getMainDivergence) {
4501
6059
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
4502
6060
  const records = [];
@@ -4536,6 +6094,7 @@ function shouldRunRecoveryJanitor(janitor, patrolCycle) {
4536
6094
  //#region ../../lib/cloister/pending-promotion-reconciler.ts
4537
6095
  init_activity_logger();
4538
6096
  init_internal_token();
6097
+ init_specs();
4539
6098
  init_projects();
4540
6099
  init_io();
4541
6100
  init_issue_closed();
@@ -5777,8 +7336,8 @@ async function cleanupStaleAgentState() {
5777
7336
  */
5778
7337
  async function cleanupAbandonedFeedback() {
5779
7338
  const actions = [];
5780
- const { getReviewStatusSync } = await import("./review-status-CUnjjOUu.js");
5781
- const { clearFeedbackFiles } = await import("./feedback-writer-DfuVjvH0.js");
7339
+ const { getReviewStatusSync } = await import("./review-status-Bge_3XTR.js");
7340
+ const { clearFeedbackFiles } = await import("./feedback-writer-BzN4qvaP.js");
5782
7341
  for (const { issueId, workspacePath } of listFeatureWorkspaces()) {
5783
7342
  const panFeedbackDir = join$1(workspacePath, ".pan", "feedback");
5784
7343
  if (!existsSync(panFeedbackDir)) continue;
@@ -5809,7 +7368,7 @@ async function cleanupAbandonedFeedback() {
5809
7368
  const ORPHAN_REVIEWER_AGE_MS = 3600 * 1e3;
5810
7369
  async function loadTmuxSessionsWithCreationTimes() {
5811
7370
  try {
5812
- const { stdout } = await execAsync(`tmux -L overdeck -f ${join$1(OVERDECK_HOME, "tmux", "overdeck.tmux.conf")} list-sessions -F '#{session_name} #{session_created}'`, { encoding: "utf-8" });
7371
+ const { stdout } = await execAsync(`tmux -L ${getManagedTmuxSocketName()} -f ${join$1(OVERDECK_HOME, "tmux", "overdeck.tmux.conf")} list-sessions -F '#{session_name} #{session_created}'`, { encoding: "utf-8" });
5813
7372
  const lines = stdout.split("\n").filter((l) => l.trim());
5814
7373
  const sessions = [];
5815
7374
  const creationTimes = /* @__PURE__ */ new Map();
@@ -5849,7 +7408,7 @@ async function handleOrphanReviewerSession(sessionName, sessions, creationTimes,
5849
7408
  if (!issueId) return null;
5850
7409
  const agentSession = `agent-${issueId.toLowerCase()}`;
5851
7410
  if (sessions.includes(agentSession)) return null;
5852
- const { getReviewStatusSync } = await import("./review-status-CUnjjOUu.js");
7411
+ const { getReviewStatusSync } = await import("./review-status-Bge_3XTR.js");
5853
7412
  try {
5854
7413
  if (getReviewStatusSync(issueId)?.reviewStatus === "reviewing") return null;
5855
7414
  } catch {}
@@ -5971,7 +7530,7 @@ async function checkOrphanedCompletions() {
5971
7530
  async function checkPendingTestDispatch() {
5972
7531
  const actions = [];
5973
7532
  try {
5974
- const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-CUnjjOUu.js");
7533
+ const { loadReviewStatuses, setReviewStatusSync } = await import("./review-status-Bge_3XTR.js");
5975
7534
  const statuses = loadReviewStatuses();
5976
7535
  const now = Date.now();
5977
7536
  for (const [issueId, status] of Object.entries(statuses)) {
@@ -6004,7 +7563,7 @@ async function checkPendingTestDispatch() {
6004
7563
  console.log(`[deacon] ${issueId}: skipping test re-dispatch — issue is closed`);
6005
7564
  continue;
6006
7565
  }
6007
- const { resolveProjectFromIssueSync } = await import("./projects-DvPEAP18.js");
7566
+ const { resolveProjectFromIssueSync } = await import("./projects-BMuEf14J.js");
6008
7567
  const resolved = resolveProjectFromIssueSync(issueId);
6009
7568
  if (!resolved) continue;
6010
7569
  const issueLower = issueId.toLowerCase();
@@ -6019,8 +7578,8 @@ async function checkPendingTestDispatch() {
6019
7578
  logDeaconEventSync(`checkPendingTestDispatch: deferred test for ${issueId} — advancing ceiling reached (PAN-1665) — ${describeRunningAgents()}`);
6020
7579
  continue;
6021
7580
  }
6022
- const { spawnRun } = await import("./agents-megfmQHM.js");
6023
- const { buildTestRolePrompt } = await import("./test-agent-queue-BUtWhNcc.js");
7581
+ const { spawnRun } = await import("./agents-DixZjXWm.js");
7582
+ const { buildTestRolePrompt } = await import("./test-agent-queue-Cu0D6BYe.js");
6024
7583
  try {
6025
7584
  const run = await spawnRun(issueId, "test", {
6026
7585
  workspace,
@@ -6150,7 +7709,7 @@ async function checkCompletedButUnsignaledTests() {
6150
7709
  const cmd = `pan admin specialists done test ${issueId} --status ${decision.status}${noteArg}${decision.uatStatus ? ` --uat-status ${decision.uatStatus}${decision.uatNotes ? ` --uat-notes "${decision.uatNotes.replace(/"/g, "'").slice(0, 120)}"` : ""}` : ""}`;
6151
7710
  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.`;
6152
7711
  try {
6153
- const { messageAgent } = await import("./agents-megfmQHM.js");
7712
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
6154
7713
  await messageAgent(testSession, nudge);
6155
7714
  unsignaledTestNudges.set(testSession, now);
6156
7715
  const msg = `Nudged ${testSession} to signal ${decision.status} (verdict artifact present)`;
@@ -6164,7 +7723,7 @@ async function checkCompletedButUnsignaledTests() {
6164
7723
  case "nudge-write": {
6165
7724
  const nudge = `Your test run for ${issueId} looks finished but no verdict was recorded. Decide the automated-gate verdict and, when UAT was required, its separate verdict. Then do BOTH now: (1) write .pan/test/result.json as {"status":"passed"|"failed","notes":"<gate evidence>","uatStatus":"passed"|"failed","uatNotes":"<UAT evidence>"} (omit UAT fields only when UAT was not required), and (2) run: pan admin specialists done test ${issueId} --status passed|failed [--uat-status passed|failed]. Do this immediately — do not summarize or ask questions, just write the file and run the command.`;
6166
7725
  try {
6167
- const { messageAgent } = await import("./agents-megfmQHM.js");
7726
+ const { messageAgent } = await import("./agents-DixZjXWm.js");
6168
7727
  await messageAgent(testSession, nudge);
6169
7728
  unsignaledTestNudges.set(testSession, now);
6170
7729
  const msg = `Nudged ${testSession} to write+signal a test verdict (no artifact yet)`;
@@ -6196,8 +7755,8 @@ async function checkCompletedButUnsignaledTests() {
6196
7755
  async function checkVerificationReviewContradiction() {
6197
7756
  const actions = [];
6198
7757
  try {
6199
- const { loadReviewStatuses } = await import("./review-status-CUnjjOUu.js");
6200
- const { resolveProjectFromIssueSync } = await import("./projects-DvPEAP18.js");
7758
+ const { loadReviewStatuses } = await import("./review-status-Bge_3XTR.js");
7759
+ const { resolveProjectFromIssueSync } = await import("./projects-BMuEf14J.js");
6201
7760
  const statuses = loadReviewStatuses();
6202
7761
  for (const [issueId, status] of Object.entries(statuses)) if (status.verificationStatus === "passed" && status.reviewStatus === "reviewing" && status.stuckReason === "review_infrastructure_failure") {
6203
7762
  let reviewedAtCommit;
@@ -6206,12 +7765,12 @@ async function checkVerificationReviewContradiction() {
6206
7765
  if (project) {
6207
7766
  const workspacePath = join$1(project.projectPath, "workspaces", `feature-${issueId.toLowerCase()}`);
6208
7767
  if (existsSync(workspacePath)) {
6209
- const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-Y0zG25ez.js");
7768
+ const { snapshotWorkspaceHeadsPromise } = await import("./git-utils-BAMwn9Nf.js");
6210
7769
  reviewedAtCommit = await snapshotWorkspaceHeadsPromise(issueId, workspacePath);
6211
7770
  }
6212
7771
  }
6213
7772
  } catch {}
6214
- const { recordReviewVerdict } = await import("./review-verdict-writer-jldSh3Bm.js");
7773
+ const { recordReviewVerdict } = await import("./review-verdict-writer-DjrJ64eS.js");
6215
7774
  const bypass = await recordReviewVerdict(issueId, {
6216
7775
  verdict: "passed",
6217
7776
  notes: "Review bypassed: verification passed but review infrastructure repeatedly failed.",
@@ -6306,7 +7865,7 @@ async function checkReadyForMergeStuck() {
6306
7865
  const testStatusGreenCiReconcileCooldowns = /* @__PURE__ */ new Map();
6307
7866
  const TEST_STATUS_GREEN_CI_RECONCILE_COOLDOWN_MS = 300 * 1e3;
6308
7867
  async function reconcileTestStatusFromGreenCi() {
6309
- const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-C33lDk9Z.js");
7868
+ const { getCiCheckRunsState, getPullRequestHeadState, isGitHubAppConfigured } = await import("./github-app-BWziYCf3.js");
6310
7869
  return reconcileTestStatusFromGreenCiWithDeps({
6311
7870
  isGitHubAppConfigured,
6312
7871
  loadReviewStatuses,
@@ -6327,7 +7886,7 @@ async function reconcileTestStatusFromGreenCi() {
6327
7886
  */
6328
7887
  async function clearStaleCiFeedback(issueId) {
6329
7888
  const { readdir, rm } = await import("fs/promises");
6330
- const { resolveProjectFromIssueSync } = await import("./projects-DvPEAP18.js");
7889
+ const { resolveProjectFromIssueSync } = await import("./projects-BMuEf14J.js");
6331
7890
  const projectConfig = resolveProjectFromIssueSync(issueId);
6332
7891
  if (!projectConfig) return;
6333
7892
  const repoDir = projectConfig.projectPath;
@@ -6621,7 +8180,7 @@ async function checkWorkspaceContainerHealth(sharedState) {
6621
8180
  }
6622
8181
  }
6623
8182
  try {
6624
- const { resolveProjectFromIssueSync } = await import("./projects-DvPEAP18.js");
8183
+ const { resolveProjectFromIssueSync } = await import("./projects-BMuEf14J.js");
6625
8184
  const resolved = resolveProjectFromIssueSync(issueLower.toUpperCase());
6626
8185
  if (resolved) await killOrphanedWorkspaceProcesses(`${resolved.projectPath}/workspaces/feature-${issueLower}`);
6627
8186
  } catch {}
@@ -6670,8 +8229,8 @@ async function checkWorkspaceContainerHealth(sharedState) {
6670
8229
  async function checkMergedWorkSessions() {
6671
8230
  const actions = [];
6672
8231
  try {
6673
- const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-D7f3zSE9.js");
6674
- const { setAgentPaused } = await import("./agents-megfmQHM.js");
8232
+ const { selectMergedWorkSessions } = await import("./reap-terminal-sessions-DgEIKMhH.js");
8233
+ const { setAgentPaused } = await import("./agents-DixZjXWm.js");
6675
8234
  const toKill = selectMergedWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
6676
8235
  for (const session of toKill) try {
6677
8236
  await Effect.runPromise(setAgentPaused(session, "merged — awaiting close-out (verify on main)", true));
@@ -6711,7 +8270,7 @@ const AWAITING_TEST_IDLE_REAP_MS = 600 * 1e3;
6711
8270
  async function checkAwaitingTestWorkSessions() {
6712
8271
  const actions = [];
6713
8272
  try {
6714
- const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-D7f3zSE9.js");
8273
+ const { selectAwaitingTestWorkSessions } = await import("./reap-terminal-sessions-DgEIKMhH.js");
6715
8274
  const candidates = selectAwaitingTestWorkSessions(loadReviewStatuses(), [...await Effect.runPromise(listSessionNames())]);
6716
8275
  const now = Date.now();
6717
8276
  for (const session of candidates) {
@@ -6764,7 +8323,7 @@ async function runPatrol() {
6764
8323
  hasLoggedGlobalPauseSkip = false;
6765
8324
  addLog("info", `Patrol cycle ${state.patrolCycle} — checking per-project specialists`, state.patrolCycle);
6766
8325
  console.log(`[deacon] Patrol cycle ${state.patrolCycle} - checking per-project specialists`);
6767
- for (const a of await (await import("./stale-task-claims-PzFee70R.js")).patrolStaleTaskClaims()) {
8326
+ for (const a of await (await import("./stale-task-claims-DMRLb5R2.js")).patrolStaleTaskClaims()) {
6768
8327
  actions.push(a);
6769
8328
  addLog("action", a, state.patrolCycle);
6770
8329
  }
@@ -6772,30 +8331,30 @@ async function runPatrol() {
6772
8331
  actions.push(...stuckRemediationActions);
6773
8332
  for (const a of stuckRemediationActions) addLog("action", a, state.patrolCycle);
6774
8333
  try {
6775
- const sweepRecommendations = await (await import("./stall-sweeper-DOyIfeLR.js")).runStallSweeperPatrol();
8334
+ const sweepRecommendations = await (await import("./stall-sweeper-CBWqSWV2.js")).runStallSweeperPatrol();
6776
8335
  actions.push(...sweepRecommendations);
6777
8336
  for (const recommendation of sweepRecommendations) addLog("info", recommendation, state.patrolCycle);
6778
8337
  } catch (err) {
6779
8338
  console.warn(`[deacon] stall sweeper patrol failed: ${err?.message ?? err}`);
6780
8339
  addLog("warn", `Stall sweeper patrol failed: ${err?.message ?? err}`, state.patrolCycle);
6781
8340
  }
6782
- const { reconcileInFlightJournals } = await import("./advancing-selfheal-BQiJ7mIH.js");
8341
+ const { reconcileInFlightJournals } = await import("./advancing-selfheal-BJAfiY-C.js");
6783
8342
  const reconciledJournalActions = await reconcileInFlightJournals();
6784
8343
  actions.push(...reconciledJournalActions);
6785
8344
  for (const a of reconciledJournalActions) addLog("action", a, state.patrolCycle);
6786
- for (const a of (await import("./feedback-stuck-retirement-B8-fX7NA.js")).retireResolvedFeedbackDeliveryStuckFlags()) {
8345
+ for (const a of (await import("./feedback-stuck-retirement-CXAYe2rU.js")).retireResolvedFeedbackDeliveryStuckFlags()) {
6787
8346
  actions.push(a);
6788
8347
  addLog("action", a, state.patrolCycle);
6789
8348
  }
6790
8349
  try {
6791
8350
  const pendingFile = join$1(OVERDECK_HOME, "pending-post-merge.json");
6792
- const { processPendingLifecycleForPatrol } = await import("./deacon-pending-lifecycle-DVHjOLje.js");
8351
+ const { processPendingLifecycleForPatrol } = await import("./deacon-pending-lifecycle-BzaE76Xo.js");
6793
8352
  const action = await processPendingLifecycleForPatrol(pendingFile);
6794
8353
  if (action) actions.push(action);
6795
8354
  } catch (err) {
6796
8355
  console.warn(`[deacon] Failed to process pending lifecycle: ${err.message}`);
6797
8356
  }
6798
- if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-BXjlvoV3.js")).runScheduledDeployPatrol();
8357
+ if (state.patrolCycle % 5 === 0) await (await import("./deploy-patrol-B8sKkA8h.js")).runScheduledDeployPatrol();
6799
8358
  const livenessActions = await reconcileAgentLiveness();
6800
8359
  actions.push(...livenessActions);
6801
8360
  for (const a of livenessActions) addLog("action", a, state.patrolCycle);
@@ -6816,7 +8375,7 @@ async function runPatrol() {
6816
8375
  const idleStackActions = await reconcileIdleWorkspaceStacks();
6817
8376
  actions.push(...idleStackActions);
6818
8377
  for (const a of idleStackActions) addLog("action", a, state.patrolCycle);
6819
- for (const a of await (await import("./bridge-pool-patrol-DiHEd13O.js")).patrolDockerBridgePool()) {
8378
+ for (const a of await (await import("./bridge-pool-patrol-BDohuMRt.js")).patrolDockerBridgePool()) {
6820
8379
  actions.push(a);
6821
8380
  addLog("action", a, state.patrolCycle);
6822
8381
  }
@@ -6836,7 +8395,7 @@ async function runPatrol() {
6836
8395
  actions.push(...suspendActions);
6837
8396
  for (const a of suspendActions) addLog("action", a, state.patrolCycle);
6838
8397
  try {
6839
- const { resolveProjectFromIssueSync } = await import("./projects-DvPEAP18.js");
8398
+ const { resolveProjectFromIssueSync } = await import("./projects-BMuEf14J.js");
6840
8399
  const allStatuses = loadReviewStatuses();
6841
8400
  for (const [issueId, status] of Object.entries(allStatuses)) {
6842
8401
  if (!status.readyForMerge || status.mergeStatus === "merged") continue;
@@ -6856,7 +8415,7 @@ async function runPatrol() {
6856
8415
  } catch (err) {
6857
8416
  console.warn(`[deacon] Failed to check workspace existence: ${err.message}`);
6858
8417
  }
6859
- const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-BQiJ7mIH.js");
8418
+ const { checkMergedAdvancingSessions } = await import("./advancing-selfheal-BJAfiY-C.js");
6860
8419
  const reapedWorkActions = await checkMergedWorkSessions();
6861
8420
  actions.push(...reapedWorkActions);
6862
8421
  for (const a of reapedWorkActions) addLog("action", a, state.patrolCycle);
@@ -6864,7 +8423,7 @@ async function runPatrol() {
6864
8423
  actions.push(...reapedMergedAdvancingActions);
6865
8424
  for (const a of reapedMergedAdvancingActions) addLog("action", a, state.patrolCycle);
6866
8425
  try {
6867
- const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-DxUJ5HKR.js");
8426
+ const { refreshClaudeCredentialsForActiveRemoteAgents } = await import("./remote-completion-LcWCpAm2.js");
6868
8427
  const remoteCredentialActions = await refreshClaudeCredentialsForActiveRemoteAgents();
6869
8428
  actions.push(...remoteCredentialActions);
6870
8429
  for (const a of remoteCredentialActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -6872,7 +8431,7 @@ async function runPatrol() {
6872
8431
  addLog("warn", `Remote credential refresh patrol failed: ${err.message}`, state.patrolCycle);
6873
8432
  }
6874
8433
  try {
6875
- const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-DQVGZVQ9.js");
8434
+ const { refreshHostHeartbeatForEphemeralVms } = await import("./remote-agents-MuXx2gWm.js");
6876
8435
  const heartbeatActions = await refreshHostHeartbeatForEphemeralVms();
6877
8436
  actions.push(...heartbeatActions);
6878
8437
  for (const a of heartbeatActions) addLog(a.includes("failed") ? "warn" : "action", a, state.patrolCycle);
@@ -6880,7 +8439,7 @@ async function runPatrol() {
6880
8439
  addLog("warn", `Remote heartbeat refresh patrol failed: ${err.message}`, state.patrolCycle);
6881
8440
  }
6882
8441
  try {
6883
- const { reapCompletedRemoteAgents } = await import("./remote-completion-DxUJ5HKR.js");
8442
+ const { reapCompletedRemoteAgents } = await import("./remote-completion-LcWCpAm2.js");
6884
8443
  const remoteReap = await reapCompletedRemoteAgents();
6885
8444
  for (const r of remoteReap) if (r.status === "handed-off" || r.status === "error") {
6886
8445
  const msg = `Remote reap ${r.issueId}: ${r.status} (${r.details.join("; ")})`;
@@ -6963,7 +8522,7 @@ async function runPatrol() {
6963
8522
  actions.push(a);
6964
8523
  addLog("action", a, state.patrolCycle);
6965
8524
  }
6966
- const swarmActions = await coordinateSwarmSlots();
8525
+ const swarmActions = await swarmJanitorPass();
6967
8526
  actions.push(...swarmActions);
6968
8527
  for (const a of swarmActions) addLog("action", a, state.patrolCycle);
6969
8528
  const staleMergeActions = await reconcileStaleMergeStatus();
@@ -6989,7 +8548,7 @@ async function runPatrol() {
6989
8548
  const staleMergeBlockerActions = await reconcileStaleMergeBlockers();
6990
8549
  actions.push(...staleMergeBlockerActions);
6991
8550
  for (const a of staleMergeBlockerActions) addLog("action", a, state.patrolCycle);
6992
- const stuckReadyActions = reconcileStuckReadyForMerge();
8551
+ const stuckReadyActions = await reconcileStuckReadyForMerge();
6993
8552
  actions.push(...stuckReadyActions);
6994
8553
  for (const a of stuckReadyActions) addLog("action", a, state.patrolCycle);
6995
8554
  const deadEndActions = await checkDeadEndAgents();
@@ -7027,6 +8586,10 @@ async function runPatrol() {
7027
8586
  actions.push(result.message);
7028
8587
  addLog(result.level, result.message, state.patrolCycle);
7029
8588
  }
8589
+ if (state.patrolCycle % statePlaneReconcileEveryCycles(config.patrolIntervalMs) === 0) for (const result of await reconcileTerminalIssueResidue(projectConfigs)) {
8590
+ actions.push(result.message);
8591
+ addLog(result.level, result.message, state.patrolCycle);
8592
+ }
7030
8593
  for (const warning of await recreatedStateWarnings(projectConfigs)) addLog(warning.level, warning.message, state.patrolCycle);
7031
8594
  const divergenceWarnings = await recordMainDivergenceHealth(state, projectConfigs);
7032
8595
  for (const warning of divergenceWarnings) addLog("warn", warning, state.patrolCycle);
@@ -7076,7 +8639,7 @@ async function runPatrol() {
7076
8639
  const issueId = runtimeState.currentIssue;
7077
8640
  try {
7078
8641
  if (getReviewStatusSync(issueId)?.mergeStatus === "merging") {
7079
- const { resolveProjectFromIssueSync } = await import("./projects-DvPEAP18.js");
8642
+ const { resolveProjectFromIssueSync } = await import("./projects-BMuEf14J.js");
7080
8643
  const resolved = resolveProjectFromIssueSync(issueId);
7081
8644
  if (resolved) {
7082
8645
  const branch = `feature/${issueId.toLowerCase()}`;
@@ -7090,7 +8653,7 @@ async function runPatrol() {
7090
8653
  mergeStatus: "merged",
7091
8654
  readyForMerge: false
7092
8655
  });
7093
- const { postMergeLifecycle } = await import("./merge-agent-BRSz26Oh.js");
8656
+ const { postMergeLifecycle } = await import("./merge-agent-D-4_iQgy.js");
7094
8657
  postMergeLifecycle(issueId, resolved.projectPath).catch((err) => console.warn(`[deacon] postMergeLifecycle failed for ${issueId}: ${err}`));
7095
8658
  actions.push(`Auto-completed stale merge for ${issueId}`);
7096
8659
  } else {
@@ -7270,7 +8833,7 @@ function startDeacon() {
7270
8833
  logDeaconEventSync(`startDeacon: health monitor starting (patrol every ${config.patrolIntervalMs / 1e3}s)`);
7271
8834
  (async () => {
7272
8835
  await reconcileAgentLiveness();
7273
- const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-BQiJ7mIH.js");
8836
+ const { runBootAdvancingSelfHeal } = await import("./advancing-selfheal-BJAfiY-C.js");
7274
8837
  await runBootAdvancingSelfHeal();
7275
8838
  runScheduledPatrol("startup");
7276
8839
  })().catch((err) => {
@@ -7283,7 +8846,7 @@ function startDeacon() {
7283
8846
  }, config.patrolIntervalMs);
7284
8847
  memoryPatrolInterval = setInterval(() => {
7285
8848
  (async () => {
7286
- const { patrolMemoryPressure } = await import("./memory-pressure-patrol-BWlWywmA.js");
8849
+ const { patrolMemoryPressure } = await import("./memory-pressure-patrol-C6DJJQRA.js");
7287
8850
  for (const action of await patrolMemoryPressure()) logDeaconEventSync(`memory-pressure-patrol: ${action}`);
7288
8851
  })().catch((err) => {
7289
8852
  logDeaconEventSync(`memory-pressure-patrol: error: ${err instanceof Error ? err.message : String(err)}`);
@@ -7353,6 +8916,6 @@ function assessDeaconPatrolFreshness(params) {
7353
8916
  };
7354
8917
  }
7355
8918
  //#endregion
7356
- export { synthesizeReviewFromReports as $, reconcileAgentLiveness as A, cleanupClosedIssueAgentDirectories as B, getLastPatrolResult as C, isDeaconRunning as D, handleAgentStoppedForOrphanReviewerSessions as E, setAgentStatusChangedNotifier as F, redeliverUndeliveredKickoffs as G, isRapidPostResumeDeath as H, setAgentStoppedNotifier as I, isBootReconciliationCandidate as J, extendBootReconciliationGrace as K, setMergeReadyNotifier as L, resetPatrolHeartbeatForStartup as M, runPatrol as N, loadConfig as O, saveState as P, monitorReviewConvoySignals as Q, startDeacon as R, getDeaconStatus as S, handleAgentStoppedEvent as T, nudgeIdleWorkAgentsWithOpenBeads as U, isPreKickoffLaunchDeath as V, nudgeStalledResumeWorkAgents as W, startBootReconciliation as X, listBootReconciliationCandidates as Y, cleanupOrphanedReviewSessions as Z, cleanupOrphanReviewerSessions as _, checkInspectAgentTimeouts as _t, checkAwaitingTestWorkSessions as a, checkOrphanedReviewStatuses as at, containerRestartBackoffMs as b, checkMassDeath as c, recoverStalledReviewConvoys as ct, checkPendingTestDispatch as d, checkPostReviewCommits as dt, checkCompletedButUnsignaledReviews as et, checkReadyForMergeStuck as f, checkApiErrorAgents as ft, cleanupAbandonedFeedback as g, INSPECT_TIMEOUT_MS as gt, checkWorkspaceContainerHealth as h, paneShowsClaudeBootBlockingScreen as ht, checkAndSuspendIdleAgents as i, checkMissingReviewStatuses as it, reconcileTestStatusFromGreenCi as j, loadState as k, checkMergedWorkSessions as l, reviewConvoyLiveness as lt, checkVerificationReviewContradiction as m, stuckOverflowNativeRecoveryState as mt, applyBootReconciliationDecision as n, isSynthesisForActiveReviewRun as nt, checkCompletedButUnsignaledTests as o, handleReviewCoordinatorDied as ot, checkStuckWorkAgents as p, contextOverflowRecoveryState as pt, isAutoResumableRole as q, assessDeaconPatrolFreshness as r, reconcileUnappliedReviewVerdicts as rt, checkDeadEndAgents as s, handleWorkCompleted as st, MEMORY_PATROL_INTERVAL_MS as t, checkStuckReviewing as tt, checkOrphanedCompletions as u, stalledReviewConvoyRecoveryState as ut, cleanupOrphanedPlanningSessions as v, WORK_LAUNCHER_GRACE_MS as vt, handleAgentHeartbeatDeadEvent as w, getDeaconLogs as x, cleanupStaleAgentState as y, stopDeacon as z };
8919
+ export { monitorReviewConvoySignals as $, reconcileAgentLiveness as A, cleanupClosedIssueAgentDirectories as B, getLastPatrolResult as C, isDeaconRunning as D, handleAgentStoppedForOrphanReviewerSessions as E, setAgentStatusChangedNotifier as F, redeliverUndeliveredKickoffs as G, isRapidPostResumeDeath as H, setAgentStoppedNotifier as I, isBootReconciliationCandidate as J, extendBootReconciliationGrace as K, setMergeReadyNotifier as L, resetPatrolHeartbeatForStartup as M, runPatrol as N, loadConfig as O, saveState as P, cleanupOrphanedReviewSessions as Q, startDeacon as R, getDeaconStatus as S, handleAgentStoppedEvent as T, nudgeIdleWorkAgentsWithOpenBeads as U, isPreKickoffLaunchDeath as V, nudgeStalledResumeWorkAgents as W, startBootReconciliation as X, listBootReconciliationCandidates as Y, resolveSwarmPolicy as Z, cleanupOrphanReviewerSessions as _, INSPECT_TIMEOUT_MS as _t, checkAwaitingTestWorkSessions as a, checkMissingReviewStatuses as at, containerRestartBackoffMs as b, checkMassDeath as c, handleWorkCompleted as ct, checkPendingTestDispatch as d, stalledReviewConvoyRecoveryState as dt, synthesizeReviewFromReports as et, checkReadyForMergeStuck as f, checkPostReviewCommits as ft, cleanupAbandonedFeedback as g, paneShowsClaudeBootBlockingScreen as gt, checkWorkspaceContainerHealth as h, stuckOverflowNativeRecoveryState as ht, checkAndSuspendIdleAgents as i, reconcileUnappliedReviewVerdicts as it, reconcileTestStatusFromGreenCi as j, loadState as k, checkMergedWorkSessions as l, recoverStalledReviewConvoys as lt, checkVerificationReviewContradiction as m, contextOverflowRecoveryState as mt, applyBootReconciliationDecision as n, checkStuckReviewing as nt, checkCompletedButUnsignaledTests as o, checkOrphanedReviewStatuses as ot, checkStuckWorkAgents as p, checkApiErrorAgents as pt, isAutoResumableRole as q, assessDeaconPatrolFreshness as r, isSynthesisForActiveReviewRun as rt, checkDeadEndAgents as s, handleReviewCoordinatorDied as st, MEMORY_PATROL_INTERVAL_MS as t, checkCompletedButUnsignaledReviews as tt, checkOrphanedCompletions as u, reviewConvoyLiveness as ut, cleanupOrphanedPlanningSessions as v, checkInspectAgentTimeouts as vt, handleAgentHeartbeatDeadEvent as w, getDeaconLogs as x, cleanupStaleAgentState as y, WORK_LAUNCHER_GRACE_MS as yt, stopDeacon as z };
7357
8920
 
7358
- //# sourceMappingURL=deacon-TPYssFYt.js.map
8921
+ //# sourceMappingURL=deacon-CsisLmPt.js.map