@overdeck/core 0.45.10 → 0.45.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (219) hide show
  1. package/dist/{agent-state-KVbJEG5f.js → agent-state-RLhS7ckO.js} +1 -1
  2. package/dist/{agents-pp8FO7Uj.js → agents-By3u_fQ8.js} +1 -1
  3. package/dist/{agents-CQHK0CSA.js → agents-CgVr77Qq.js} +12 -12
  4. package/dist/{agents-CQHK0CSA.js.map → agents-CgVr77Qq.js.map} +1 -1
  5. package/dist/{backlog-auto-trigger-CyuoS0nl.js → backlog-auto-trigger-B_-1tk4e.js} +5 -5
  6. package/dist/{backlog-auto-trigger-CyuoS0nl.js.map → backlog-auto-trigger-B_-1tk4e.js.map} +1 -1
  7. package/dist/cli/index.js +45 -45
  8. package/dist/{cli-Cewlu3yU.js → cli-DGeSW85B.js} +2 -2
  9. package/dist/{cli-Cewlu3yU.js.map → cli-DGeSW85B.js.map} +1 -1
  10. package/dist/cli-MTB9IOoR.js +3 -0
  11. package/dist/{close-issue-BJGX9_z7.js → close-issue-Djajb6Sv.js} +2 -2
  12. package/dist/{close-issue-BJGX9_z7.js.map → close-issue-Djajb6Sv.js.map} +1 -1
  13. package/dist/{concurrency-Ca-fC7tA.js → concurrency-4rzjHAQA.js} +1 -1
  14. package/dist/{conversation-compaction-B_6s9EvM.js → conversation-compaction-BQvZh09I.js} +4 -4
  15. package/dist/{conversation-compaction-B_6s9EvM.js.map → conversation-compaction-BQvZh09I.js.map} +1 -1
  16. package/dist/dashboard/{advancing-selfheal-CMlGznKv.js → advancing-selfheal-BezNfM3P.js} +3 -3
  17. package/dist/dashboard/{advancing-selfheal-CMlGznKv.js.map → advancing-selfheal-BezNfM3P.js.map} +1 -1
  18. package/dist/dashboard/{agent-state-xk_G8t90.js → agent-state-BUANcaA7.js} +1 -1
  19. package/dist/dashboard/{agent-state-service-C1iUF9Ft.js → agent-state-service-DmFpIMbP.js} +1 -1
  20. package/dist/dashboard/{agent-state-service-5ge9xxhx.js → agent-state-service-tXUdp6UF.js} +2 -2
  21. package/dist/dashboard/{agent-state-service-5ge9xxhx.js.map → agent-state-service-tXUdp6UF.js.map} +1 -1
  22. package/dist/dashboard/{agents-BIggLvi_.js → agents-C-vqmKDi.js} +1 -1
  23. package/dist/dashboard/{agents-DHvsjsuP.js → agents-C7V4odQ6.js} +11 -11
  24. package/dist/dashboard/{agents-DHvsjsuP.js.map → agents-C7V4odQ6.js.map} +1 -1
  25. package/dist/dashboard/{backlog-auto-trigger-COm_R96V.js → backlog-auto-trigger-Cb8PR-5w.js} +2 -2
  26. package/dist/dashboard/{backlog-auto-trigger-COm_R96V.js.map → backlog-auto-trigger-Cb8PR-5w.js.map} +1 -1
  27. package/dist/dashboard/{cli-CvK9xuSS.js → cli-BgzbB6h3.js} +2 -2
  28. package/dist/dashboard/{cli-CvK9xuSS.js.map → cli-BgzbB6h3.js.map} +1 -1
  29. package/dist/dashboard/cli-DCqy_wFa.js +3 -0
  30. package/dist/dashboard/{close-issue-BnpErnD1.js → close-issue-BWf3pxn4.js} +2 -2
  31. package/dist/dashboard/{close-issue-BnpErnD1.js.map → close-issue-BWf3pxn4.js.map} +1 -1
  32. package/dist/dashboard/{closed-issue-reaper-DRqK5k39.js → closed-issue-reaper-D7XPq5pY.js} +4 -4
  33. package/dist/dashboard/{closed-issue-reaper-DRqK5k39.js.map → closed-issue-reaper-D7XPq5pY.js.map} +1 -1
  34. package/dist/dashboard/{closed-issue-reaper-BLCQwTpF.js → closed-issue-reaper-VSTSTROK.js} +1 -1
  35. package/dist/dashboard/{conflict-gate-JdFuhKuF.js → conflict-gate-DwOslTij.js} +1 -1
  36. package/dist/dashboard/{conflict-gate-BhKvrPxn.js → conflict-gate-FFEvTDVA.js} +3 -3
  37. package/dist/dashboard/{conflict-gate-BhKvrPxn.js.map → conflict-gate-FFEvTDVA.js.map} +1 -1
  38. package/dist/dashboard/{conversation-compaction-C5o_eKEm.js → conversation-compaction-CCqN4hWk.js} +4 -4
  39. package/dist/dashboard/{conversation-compaction-C5o_eKEm.js.map → conversation-compaction-CCqN4hWk.js.map} +1 -1
  40. package/dist/dashboard/{conversation-compaction-Ba5aZdrb.js → conversation-compaction-CL5Ti4j4.js} +1 -1
  41. package/dist/dashboard/{deacon-j3qSZ7--.js → deacon-CGHl90eC.js} +107 -50
  42. package/dist/dashboard/{deacon-j3qSZ7--.js.map → deacon-CGHl90eC.js.map} +1 -1
  43. package/dist/dashboard/{deacon-Cv2RMfHs.js → deacon-DMPh40Im.js} +2 -2
  44. package/dist/dashboard/deacon-swarm-CVTiNL0N.js +2 -0
  45. package/dist/dashboard/{deacon-swarm-DadWNi5J.js → deacon-swarm-aMMJTq6t.js} +4 -4
  46. package/dist/dashboard/{deacon-swarm-DadWNi5J.js.map → deacon-swarm-aMMJTq6t.js.map} +1 -1
  47. package/dist/dashboard/deacon.js +4 -4
  48. package/dist/dashboard/{feedback-target-oE4-Esxl.js → feedback-target-dJjFfITP.js} +4 -4
  49. package/dist/dashboard/{feedback-target-oE4-Esxl.js.map → feedback-target-dJjFfITP.js.map} +1 -1
  50. package/dist/dashboard/{feedback-target-C4DaDSZ8.js → feedback-target-nQSM6ygL.js} +1 -1
  51. package/dist/dashboard/{flywheel-ClMjGW_u.js → flywheel-BLoVNtJV.js} +6 -6
  52. package/dist/dashboard/{flywheel-ClMjGW_u.js.map → flywheel-BLoVNtJV.js.map} +1 -1
  53. package/dist/dashboard/{flywheel-DefHRzY4.js → flywheel-Cqf8vu7N.js} +6 -6
  54. package/dist/dashboard/{flywheel-DefHRzY4.js.map → flywheel-Cqf8vu7N.js.map} +1 -1
  55. package/dist/dashboard/{flywheel-BqDdGvrQ.js → flywheel-PJsbrXNY.js} +1 -1
  56. package/dist/dashboard/{flywheel-merge-order-CuDcqTRJ.js → flywheel-merge-order-B7BH8mZ3.js} +2 -2
  57. package/dist/dashboard/{flywheel-merge-order-CuDcqTRJ.js.map → flywheel-merge-order-B7BH8mZ3.js.map} +1 -1
  58. package/dist/dashboard/{flywheel-merge-order-B6YDSElh.js → flywheel-merge-order-CCwF60b-.js} +1 -1
  59. package/dist/dashboard/{harness-resolve-DKeSVsJL.js → harness-resolve-B3f9G1Kp.js} +2 -2
  60. package/dist/dashboard/{harness-resolve-DKeSVsJL.js.map → harness-resolve-B3f9G1Kp.js.map} +1 -1
  61. package/dist/dashboard/{inspect-agent-BKKc0XnB.js → inspect-agent-CKF5-SJr.js} +3 -3
  62. package/dist/dashboard/{inspect-agent-BKKc0XnB.js.map → inspect-agent-CKF5-SJr.js.map} +1 -1
  63. package/dist/dashboard/inspect-agent-CqpEWGWy.js +2 -0
  64. package/dist/dashboard/{issue-lifecycle-DnhQgddB.js → issue-lifecycle-5LbOcATP.js} +7 -7
  65. package/dist/dashboard/{issue-lifecycle-DnhQgddB.js.map → issue-lifecycle-5LbOcATP.js.map} +1 -1
  66. package/dist/dashboard/{issue-lifecycle-nY4esZn8.js → issue-lifecycle-CjYqQ669.js} +1 -1
  67. package/dist/dashboard/{issue-service-singleton-Bnqv1uaa.js → issue-service-singleton-B8iu_TKV.js} +1 -1
  68. package/dist/dashboard/{issue-service-singleton-_AquSBTl.js → issue-service-singleton-CDGt__oQ.js} +2 -2
  69. package/dist/dashboard/{issue-service-singleton-_AquSBTl.js.map → issue-service-singleton-CDGt__oQ.js.map} +1 -1
  70. package/dist/dashboard/{lifecycle-CGKm7doE.js → lifecycle-CEg4sHZH.js} +4 -4
  71. package/dist/dashboard/{lifecycle-CGKm7doE.js.map → lifecycle-CEg4sHZH.js.map} +1 -1
  72. package/dist/dashboard/{merge-agent-Dh8Y9PDO.js → merge-agent-7nBiCytp.js} +1 -1
  73. package/dist/dashboard/{merge-agent-BcgAYStl.js → merge-agent-C81xPIGd.js} +6 -6
  74. package/dist/dashboard/{merge-agent-BcgAYStl.js.map → merge-agent-C81xPIGd.js.map} +1 -1
  75. package/dist/dashboard/merge-ops-DE_6CnmZ.js +2 -0
  76. package/dist/dashboard/{merge-train-DmxlYbEo.js → merge-train-D3qzRccL.js} +2 -2
  77. package/dist/dashboard/{merge-train-DmxlYbEo.js.map → merge-train-D3qzRccL.js.map} +1 -1
  78. package/dist/dashboard/{merge-train-deps-DBHsOWt9.js → merge-train-deps-Be5ElC_P.js} +2 -2
  79. package/dist/dashboard/{merge-train-deps-DBHsOWt9.js.map → merge-train-deps-Be5ElC_P.js.map} +1 -1
  80. package/dist/dashboard/{orphan-proposed-reconciler-Db8tUhce.js → orphan-proposed-reconciler-Boq_XaRe.js} +3 -3
  81. package/dist/dashboard/{orphan-proposed-reconciler-Db8tUhce.js.map → orphan-proposed-reconciler-Boq_XaRe.js.map} +1 -1
  82. package/dist/dashboard/{orphan-proposed-reconciler-mXV--tcB.js → orphan-proposed-reconciler-C0sPnDq_.js} +1 -1
  83. package/dist/dashboard/{reconstruct-cache-_tDZ2D72.js → reconstruct-cache-C2pCltOq.js} +3 -3
  84. package/dist/dashboard/{reconstruct-cache-_tDZ2D72.js.map → reconstruct-cache-C2pCltOq.js.map} +1 -1
  85. package/dist/dashboard/{remote-completion-Bklh6loJ.js → remote-completion-BmxD5UMQ.js} +3 -3
  86. package/dist/dashboard/{remote-completion-Bklh6loJ.js.map → remote-completion-BmxD5UMQ.js.map} +1 -1
  87. package/dist/dashboard/resume-C-nxu9Y4.js +3 -0
  88. package/dist/dashboard/{review-agent-phzqNqIs.js → review-agent-D6P6d3pz.js} +26 -17
  89. package/dist/dashboard/review-agent-D6P6d3pz.js.map +1 -0
  90. package/dist/dashboard/review-agent-DTINEffB.js +3 -0
  91. package/dist/dashboard/{review-context-CCq56O_Y.js → review-context-Dyo0tsBa.js} +2 -2
  92. package/dist/dashboard/{review-context-CCq56O_Y.js.map → review-context-Dyo0tsBa.js.map} +1 -1
  93. package/dist/dashboard/{review-status-BQjqQXZG.js → review-status-B5ZASOo4.js} +18 -5
  94. package/dist/dashboard/review-status-B5ZASOo4.js.map +1 -0
  95. package/dist/dashboard/{review-status-bBkqUj5i.js → review-status-h7BXIA4z.js} +1 -1
  96. package/dist/dashboard/{review-verdict-feedback-wqnikhMK.js → review-verdict-feedback-B70VbfRL.js} +4 -4
  97. package/dist/dashboard/{review-verdict-feedback-wqnikhMK.js.map → review-verdict-feedback-B70VbfRL.js.map} +1 -1
  98. package/dist/dashboard/{review-verdict-feedback-cZh9Wi9G.js → review-verdict-feedback-CorgH49f.js} +1 -1
  99. package/dist/dashboard/{sequence-io-B2GmilSI.js → sequence-io-6YP8fVpH.js} +2 -2
  100. package/dist/dashboard/{sequence-io-B2GmilSI.js.map → sequence-io-6YP8fVpH.js.map} +1 -1
  101. package/dist/dashboard/{sequencer-agent-D8pW2aU_.js → sequencer-agent-ja-nkEc1.js} +5 -5
  102. package/dist/dashboard/{sequencer-agent-D8pW2aU_.js.map → sequencer-agent-ja-nkEc1.js.map} +1 -1
  103. package/dist/dashboard/server.js +66 -55
  104. package/dist/dashboard/server.js.map +1 -1
  105. package/dist/dashboard/{service-CILd-uOt.js → service-HKDrIy0h.js} +24 -24
  106. package/dist/dashboard/{service-CILd-uOt.js.map → service-HKDrIy0h.js.map} +1 -1
  107. package/dist/dashboard/{smart-compaction-Bgp_gwcA.js → smart-compaction-L0LSnF0_.js} +1 -1
  108. package/dist/dashboard/{smart-compaction-CrP90OFE.js → smart-compaction-uke1npUz.js} +2 -2
  109. package/dist/dashboard/{smart-compaction-CrP90OFE.js.map → smart-compaction-uke1npUz.js.map} +1 -1
  110. package/dist/dashboard/{spawn-planning-session-D15KbPOy.js → spawn-planning-session-CSMWco8B.js} +1 -1
  111. package/dist/dashboard/{spawn-planning-session-BmJWHSCu.js → spawn-planning-session-CXc0NkwV.js} +3 -3
  112. package/dist/dashboard/{spawn-planning-session-BmJWHSCu.js.map → spawn-planning-session-CXc0NkwV.js.map} +1 -1
  113. package/dist/dashboard/{specialist-context-CwKkcXL9.js → specialist-context-BGCJ24LH.js} +3 -3
  114. package/dist/dashboard/{specialist-context-CwKkcXL9.js.map → specialist-context-BGCJ24LH.js.map} +1 -1
  115. package/dist/dashboard/{specialist-logs-CvDxquV_.js → specialist-logs--Uz-r8ia.js} +2 -2
  116. package/dist/dashboard/{specialist-logs-CvDxquV_.js.map → specialist-logs--Uz-r8ia.js.map} +1 -1
  117. package/dist/dashboard/{specialists-BCjcG4uE.js → specialists-Ca9XSBCS.js} +1 -1
  118. package/dist/dashboard/{specialists-D07ybnam.js → specialists-DEfrAbWs.js} +36 -36
  119. package/dist/dashboard/{specialists-D07ybnam.js.map → specialists-DEfrAbWs.js.map} +1 -1
  120. package/dist/dashboard/{specialists-F2uMO4QS.js → specialists-DeZx9xom.js} +1 -1
  121. package/dist/dashboard/{specialists-BYi0k8CZ.js → specialists-nZ0mRwpZ.js} +12 -12
  122. package/dist/dashboard/{specialists-BYi0k8CZ.js.map → specialists-nZ0mRwpZ.js.map} +1 -1
  123. package/dist/dashboard/{summary-fork-DedqguZb.js → summary-fork-2a1L2DIU.js} +2 -2
  124. package/dist/dashboard/{summary-fork-EjvOkEPl.js → summary-fork-Xn0QUNmb.js} +3 -3
  125. package/dist/dashboard/{summary-fork-EjvOkEPl.js.map → summary-fork-Xn0QUNmb.js.map} +1 -1
  126. package/dist/dashboard/{teardown-workspace-5LCVbjfq.js → teardown-workspace-DhA6oAIK.js} +2 -2
  127. package/dist/dashboard/{teardown-workspace-5LCVbjfq.js.map → teardown-workspace-DhA6oAIK.js.map} +1 -1
  128. package/dist/dashboard/{test-agent-queue-qfsq6uaC.js → test-agent-queue-B_ukPyIK.js} +3 -3
  129. package/dist/dashboard/{test-agent-queue-qfsq6uaC.js.map → test-agent-queue-B_ukPyIK.js.map} +1 -1
  130. package/dist/dashboard/{uat-train-CtNGgXxj.js → uat-train-BLBAbJ8Y.js} +10 -10
  131. package/dist/dashboard/{uat-train-CtNGgXxj.js.map → uat-train-BLBAbJ8Y.js.map} +1 -1
  132. package/dist/dashboard/{uat-train-C3hWXtip.js → uat-train-DPfGR9_I.js} +1 -1
  133. package/dist/dashboard/{verification-runner-DuZRHjPU.js → verification-runner-KTGTNugM.js} +1 -1
  134. package/dist/dashboard/{verification-runner-BPAhPWR7.js → verification-runner-R2-4XgMO.js} +4 -4
  135. package/dist/dashboard/{verification-runner-BPAhPWR7.js.map → verification-runner-R2-4XgMO.js.map} +1 -1
  136. package/dist/dashboard/{workflows-H-COJ84X.js → workflows-CSKX5MhC.js} +7 -7
  137. package/dist/dashboard/{workflows-H-COJ84X.js.map → workflows-CSKX5MhC.js.map} +1 -1
  138. package/dist/dashboard/workflows-DVwXauef.js +2 -0
  139. package/dist/dashboard/{workspaces-CRU9_vRn.js → workspaces-DXLDgXo2.js} +32 -32
  140. package/dist/dashboard/{workspaces-CRU9_vRn.js.map → workspaces-DXLDgXo2.js.map} +1 -1
  141. package/dist/docs-index.sqlite +0 -0
  142. package/dist/{feedback-target-DTGAhFkM.js → feedback-target-BsKN4Tr_.js} +4 -4
  143. package/dist/{feedback-target-DTGAhFkM.js.map → feedback-target-BsKN4Tr_.js.map} +1 -1
  144. package/dist/{feedback-target-DutF088V.js → feedback-target-DM1WzOKy.js} +1 -1
  145. package/dist/{harness-resolve-Bz1prk6B.js → harness-resolve-B-YDNwNW.js} +2 -2
  146. package/dist/{harness-resolve-Bz1prk6B.js.map → harness-resolve-B-YDNwNW.js.map} +1 -1
  147. package/dist/{issue-lifecycle-fVqvCdKM.js → issue-lifecycle-Bc1l3U9f.js} +7 -7
  148. package/dist/{issue-lifecycle-fVqvCdKM.js.map → issue-lifecycle-Bc1l3U9f.js.map} +1 -1
  149. package/dist/{issue-service-singleton-CZm8p6Rj.js → issue-service-singleton-D-8Q6tdT.js} +1 -1
  150. package/dist/{issue-service-singleton-Cr73JAaR.js → issue-service-singleton-D1433I7n.js} +2 -2
  151. package/dist/{issue-service-singleton-Cr73JAaR.js.map → issue-service-singleton-D1433I7n.js.map} +1 -1
  152. package/dist/{lifecycle-CR6tZfl1.js → lifecycle-SmrqysDf.js} +7 -7
  153. package/dist/{lifecycle-CR6tZfl1.js.map → lifecycle-SmrqysDf.js.map} +1 -1
  154. package/dist/{lifecycle-D_EWiUjk.js → lifecycle-mRMyiIXs.js} +2 -2
  155. package/dist/{merge-agent-LM4avOtA.js → merge-agent-B9hIZ6Z0.js} +6 -6
  156. package/dist/{merge-agent-LM4avOtA.js.map → merge-agent-B9hIZ6Z0.js.map} +1 -1
  157. package/dist/{merge-agent-Bj046HE1.js → merge-agent-DUj22cXL.js} +1 -1
  158. package/dist/{merge-fulfillment-DrnC1Kmg.js → merge-fulfillment-__P4WE-T.js} +3 -3
  159. package/dist/{merge-fulfillment-DrnC1Kmg.js.map → merge-fulfillment-__P4WE-T.js.map} +1 -1
  160. package/dist/{reconstruct-cache-NPqoAUg-.js → reconstruct-cache-9SWp82SQ.js} +3 -3
  161. package/dist/{reconstruct-cache-NPqoAUg-.js.map → reconstruct-cache-9SWp82SQ.js.map} +1 -1
  162. package/dist/{records-BIkN1LQ4.js → records-CTmvuRzz.js} +14 -1
  163. package/dist/{records-BIkN1LQ4.js.map → records-CTmvuRzz.js.map} +1 -1
  164. package/dist/records-backfill-BQcmTmwF.js +2 -0
  165. package/dist/{records-backfill-HM0Pln6N.js → records-backfill-BrNsv_zT.js} +2 -2
  166. package/dist/{records-backfill-HM0Pln6N.js.map → records-backfill-BrNsv_zT.js.map} +1 -1
  167. package/dist/resume-Bn4kDk9x.js +3 -0
  168. package/dist/{review-agent-DFosQzCG.js → review-agent-PhqOhpx3.js} +24 -16
  169. package/dist/{review-agent-DFosQzCG.js.map → review-agent-PhqOhpx3.js.map} +1 -1
  170. package/dist/review-agent-hLbRRxZF.js +3 -0
  171. package/dist/{review-status-iJwfEoNX.js → review-status-B_XXomV0.js} +6 -6
  172. package/dist/{review-status-iJwfEoNX.js.map → review-status-B_XXomV0.js.map} +1 -1
  173. package/dist/{review-status-BbNVlXh1.js → review-status-Bo-EFVKh.js} +1 -1
  174. package/dist/{review-verdict-feedback-BGPw3z1X.js → review-verdict-feedback-CXHkoiKZ.js} +1 -1
  175. package/dist/{review-verdict-feedback-CCZ05atV.js → review-verdict-feedback-DGV13LDb.js} +4 -4
  176. package/dist/{review-verdict-feedback-CCZ05atV.js.map → review-verdict-feedback-DGV13LDb.js.map} +1 -1
  177. package/dist/{sequence-io-CcxZNHcD.js → sequence-io-Cg4NHAco.js} +1 -1
  178. package/dist/{sequence-io-Cx1usxG3.js → sequence-io-CyxvNHfA.js} +2 -2
  179. package/dist/{sequence-io-Cx1usxG3.js.map → sequence-io-CyxvNHfA.js.map} +1 -1
  180. package/dist/{smart-compaction-ByUEgQkF.js → smart-compaction-ByKXTQNy.js} +2 -2
  181. package/dist/{smart-compaction-ByUEgQkF.js.map → smart-compaction-ByKXTQNy.js.map} +1 -1
  182. package/dist/{smart-compaction-DfLe_CtH.js → smart-compaction-U6e_uB1E.js} +1 -1
  183. package/dist/{specialist-context-McuGkaeR.js → specialist-context-BUTadO-U.js} +3 -3
  184. package/dist/{specialist-context-McuGkaeR.js.map → specialist-context-BUTadO-U.js.map} +1 -1
  185. package/dist/{specialist-logs-CUUJ4eiB.js → specialist-logs-pEMCTtGZ.js} +2 -2
  186. package/dist/{specialist-logs-CUUJ4eiB.js.map → specialist-logs-pEMCTtGZ.js.map} +1 -1
  187. package/dist/{specialists-BSrylD1S.js → specialists-BGFnrQ8n.js} +1 -1
  188. package/dist/{specialists-B0elgInc.js → specialists-DeTkkp8b.js} +12 -12
  189. package/dist/{specialists-B0elgInc.js.map → specialists-DeTkkp8b.js.map} +1 -1
  190. package/dist/{summary-fork-DskMRnyb.js → summary-fork-CgzThE2-.js} +2 -2
  191. package/dist/{summary-fork-CPUTKcAT.js → summary-fork-Dx1RMuvU.js} +3 -3
  192. package/dist/{summary-fork-CPUTKcAT.js.map → summary-fork-Dx1RMuvU.js.map} +1 -1
  193. package/dist/{sync-BiNVQHBf.js → sync-Bsww9tuj.js} +2 -2
  194. package/dist/{sync-BiNVQHBf.js.map → sync-Bsww9tuj.js.map} +1 -1
  195. package/dist/sync-CylE_SjB.js +2 -0
  196. package/dist/{verdict-restore-DQiV7_fe.js → verdict-restore-DGpX0ZOJ.js} +5 -5
  197. package/dist/{verdict-restore-DQiV7_fe.js.map → verdict-restore-DGpX0ZOJ.js.map} +1 -1
  198. package/dist/{webhook-handlers-DHBSEDEm.js → webhook-handlers-BjsfIL7u.js} +3 -3
  199. package/dist/{webhook-handlers-DHBSEDEm.js.map → webhook-handlers-BjsfIL7u.js.map} +1 -1
  200. package/dist/{workspace-migrate-duUsWNpd.js → workspace-migrate-BBQ8nAnP.js} +2 -2
  201. package/dist/{workspace-migrate-duUsWNpd.js.map → workspace-migrate-BBQ8nAnP.js.map} +1 -1
  202. package/dist/{workspace-reap-DLCIoJmn.js → workspace-reap-12O9354k.js} +2 -2
  203. package/dist/{workspace-reap-DLCIoJmn.js.map → workspace-reap-12O9354k.js.map} +1 -1
  204. package/package.json +1 -1
  205. package/scripts/file-size-baseline.txt +1 -1
  206. package/dist/cli-DBWG12XK.js +0 -3
  207. package/dist/dashboard/cli-CJDWXE_Y.js +0 -3
  208. package/dist/dashboard/deacon-swarm-D1iAUX-P.js +0 -2
  209. package/dist/dashboard/inspect-agent-vm88mLYr.js +0 -2
  210. package/dist/dashboard/merge-ops-QdBiQ8XB.js +0 -2
  211. package/dist/dashboard/resume-DnIsmIgC.js +0 -3
  212. package/dist/dashboard/review-agent-DgySDb-G.js +0 -3
  213. package/dist/dashboard/review-agent-phzqNqIs.js.map +0 -1
  214. package/dist/dashboard/review-status-BQjqQXZG.js.map +0 -1
  215. package/dist/dashboard/workflows-Cz8OtiB4.js +0 -2
  216. package/dist/records-backfill-DEgtRyKL.js +0 -2
  217. package/dist/resume-DGymuXZM.js +0 -3
  218. package/dist/review-agent-DjVadURa.js +0 -3
  219. package/dist/sync-4jqukkxz.js +0 -2
@@ -1 +1 @@
1
- {"version":3,"file":"records-BIkN1LQ4.js","names":["fsp"],"sources":["../src/lib/overdeck/agent-state-sync.ts","../src/lib/review-status-normalize.ts","../src/lib/overdeck/review-status-sync.ts","../src/lib/pan-dir/record-lock.ts","../src/lib/pan-dir/records.ts"],"sourcesContent":["import type { AgentState, Role } from '../agents.js';\nimport type { RuntimeName } from '../runtimes/types.js';\nimport { getOverdeckDatabaseSync } from './infra.js';\n\ntype OverdeckAgentRow = {\n id: string;\n issue_id: string;\n role: string;\n status: string;\n workspace: string;\n session_id: string | null;\n harness: string | null;\n model: string | null;\n host_override: string | null;\n delivery_method: string | null;\n started_at: number | null;\n last_resume_at: number | null;\n stopped_by_user: number | null;\n stopped_by_pause: number | null;\n kickoff_delivered: number | null;\n paused: number | null;\n paused_reason: string | null;\n yielded_by_scheduler: number | null;\n yielded_at: number | null;\n last_yield_resume_at: number | null;\n troubled: number | null;\n channels_enabled: number | null;\n consecutive_failures: number | null;\n first_failure_in_run_at: number | null;\n last_failure_next_retry_at: number | null;\n stopped_at: number | null;\n paused_at: number | null;\n troubled_at: number | null;\n last_activity: number | null;\n last_failure_reason: string | null;\n phase: string | null;\n role_run_head: string | null;\n flywheel_run_id: string | null;\n cost_so_far: number | null;\n review_sub_role: string | null;\n review_run_id: string | null;\n review_synthesis_agent_id: string | null;\n review_output_path: string | null;\n review_deadline_at: number | null;\n review_monitor_signaled: string | null;\n review_retry_attempt: number | null;\n updated_at: number;\n};\n\n/** Exported for agent-projection.ts transactional writes. */\nexport const AGENT_COLUMNS_FOR_DB = [\n 'id',\n 'issue_id',\n 'role',\n 'status',\n 'workspace',\n 'session_id',\n 'harness',\n 'model',\n 'host_override',\n 'delivery_method',\n 'started_at',\n 'last_resume_at',\n 'stopped_by_user',\n 'stopped_by_pause',\n 'kickoff_delivered',\n 'paused',\n 'paused_reason',\n 'yielded_by_scheduler',\n 'yielded_at',\n 'last_yield_resume_at',\n 'troubled',\n 'channels_enabled',\n 'consecutive_failures',\n 'first_failure_in_run_at',\n 'last_failure_next_retry_at',\n 'stopped_at',\n 'paused_at',\n 'troubled_at',\n 'last_activity',\n 'last_failure_reason',\n 'phase',\n 'role_run_head',\n 'flywheel_run_id',\n 'cost_so_far',\n 'review_sub_role',\n 'review_run_id',\n 'review_synthesis_agent_id',\n 'review_output_path',\n 'review_deadline_at',\n 'review_monitor_signaled',\n 'review_retry_attempt',\n 'updated_at',\n] as const;\n\nconst SELECT_AGENT_SQL = `SELECT ${AGENT_COLUMNS_FOR_DB.join(', ')} FROM agents`;\n\nfunction isoFromMillis(value: number | null | undefined): string | undefined {\n return value == null ? undefined : new Date(value).toISOString();\n}\n\nfunction millisFromIso(value: string | null | undefined): number | null {\n if (!value) return null;\n const millis = Date.parse(value);\n return Number.isFinite(millis) ? millis : null;\n}\n\nfunction boolFromInteger(value: number | null | undefined): boolean | undefined {\n return value == null ? undefined : Boolean(value);\n}\n\nfunction hostOverrideFromRow(value: string | null | undefined): boolean | undefined {\n if (value == null) return undefined;\n return value === '1' || value === 'true' || value === 'yes';\n}\n\nfunction hostOverrideToRow(value: boolean | undefined): string | null {\n return value === true ? 'true' : null;\n}\n\nfunction overdeckRowToAgentState(row: OverdeckAgentRow): AgentState {\n const deliveryMethod = row.delivery_method as AgentState['deliveryMethod'] | null;\n return {\n id: row.id,\n issueId: row.issue_id,\n workspace: row.workspace,\n role: row.role as Role,\n model: row.model ?? '',\n status: row.status as AgentState['status'],\n startedAt: isoFromMillis(row.started_at) ?? isoFromMillis(row.updated_at) ?? new Date().toISOString(),\n harness: row.harness ? (row.harness as RuntimeName) : undefined,\n lastResumeAt: isoFromMillis(row.last_resume_at),\n stoppedByUser: boolFromInteger(row.stopped_by_user),\n stoppedByPause: boolFromInteger(row.stopped_by_pause),\n kickoffDelivered: boolFromInteger(row.kickoff_delivered),\n paused: boolFromInteger(row.paused),\n pausedReason: row.paused_reason ?? undefined,\n yieldedByScheduler: boolFromInteger(row.yielded_by_scheduler),\n yieldedAt: isoFromMillis(row.yielded_at),\n lastYieldResumeAt: isoFromMillis(row.last_yield_resume_at),\n troubled: boolFromInteger(row.troubled),\n consecutiveFailures: row.consecutive_failures ?? undefined,\n firstFailureInRunAt: isoFromMillis(row.first_failure_in_run_at),\n lastFailureNextRetryAt: isoFromMillis(row.last_failure_next_retry_at),\n sessionId: row.session_id ?? undefined,\n channelsEnabled: boolFromInteger(row.channels_enabled),\n supervisorEnabled: deliveryMethod === 'supervisor' ? true : undefined,\n deliveryMethod: deliveryMethod ?? undefined,\n hostOverride: hostOverrideFromRow(row.host_override),\n stoppedAt: isoFromMillis(row.stopped_at),\n pausedAt: isoFromMillis(row.paused_at),\n troubledAt: isoFromMillis(row.troubled_at),\n lastActivity: isoFromMillis(row.last_activity),\n lastFailureReason: row.last_failure_reason ?? undefined,\n phase: row.phase == null ? undefined : (row.phase as AgentState['phase']),\n roleRunHead: row.role_run_head ?? undefined,\n flywheelRunId: row.flywheel_run_id ?? undefined,\n costSoFar: row.cost_so_far ?? undefined,\n reviewSubRole: row.review_sub_role ?? undefined,\n reviewRunId: row.review_run_id ?? undefined,\n reviewSynthesisAgentId: row.review_synthesis_agent_id ?? undefined,\n reviewOutputPath: row.review_output_path ?? undefined,\n reviewDeadlineAt: isoFromMillis(row.review_deadline_at),\n reviewMonitorSignaled: (row.review_monitor_signaled ?? undefined) as AgentState['reviewMonitorSignaled'],\n reviewRetryAttempt: row.review_retry_attempt ?? undefined,\n };\n}\n\n/** Exported for agent-projection.ts transactional writes. */\nexport function stateToOverdeckParamsForDb(state: AgentState, updatedAt: number): unknown[] {\n const deliveryMethod = state.deliveryMethod ?? (state.supervisorEnabled === true ? 'supervisor' : null);\n return [\n state.id,\n state.issueId,\n state.role,\n state.status,\n state.workspace,\n state.sessionId ?? null,\n state.harness ?? '',\n state.model ?? '',\n hostOverrideToRow(state.hostOverride),\n deliveryMethod,\n millisFromIso(state.startedAt),\n millisFromIso(state.lastResumeAt),\n state.stoppedByUser == null ? null : (state.stoppedByUser ? 1 : 0),\n state.stoppedByPause == null ? null : (state.stoppedByPause ? 1 : 0),\n state.kickoffDelivered == null ? null : (state.kickoffDelivered ? 1 : 0),\n state.paused == null ? null : (state.paused ? 1 : 0),\n state.pausedReason ?? null,\n state.yieldedByScheduler == null ? null : (state.yieldedByScheduler ? 1 : 0),\n millisFromIso(state.yieldedAt),\n millisFromIso(state.lastYieldResumeAt),\n state.troubled == null ? null : (state.troubled ? 1 : 0),\n state.channelsEnabled == null ? null : (state.channelsEnabled ? 1 : 0),\n state.consecutiveFailures ?? null,\n millisFromIso(state.firstFailureInRunAt),\n millisFromIso(state.lastFailureNextRetryAt),\n millisFromIso(state.stoppedAt),\n millisFromIso(state.pausedAt),\n millisFromIso(state.troubledAt),\n millisFromIso(state.lastActivity),\n state.lastFailureReason ?? null,\n state.phase ?? null,\n state.roleRunHead ?? null,\n state.flywheelRunId ?? null,\n state.costSoFar ?? null,\n state.reviewSubRole ?? null,\n state.reviewRunId ?? null,\n state.reviewSynthesisAgentId ?? null,\n state.reviewOutputPath ?? null,\n millisFromIso(state.reviewDeadlineAt),\n state.reviewMonitorSignaled ?? null,\n state.reviewRetryAttempt ?? null,\n updatedAt,\n ];\n}\n\nexport function getOverdeckAgentStateSync(agentId: string): AgentState | null {\n const row = getOverdeckDatabaseSync()\n .prepare(`${SELECT_AGENT_SQL} WHERE id = ?`)\n .get(agentId) as OverdeckAgentRow | undefined;\n return row ? overdeckRowToAgentState(row) : null;\n}\n\nexport function listOverdeckAgentStatesSync(): AgentState[] {\n const rows = getOverdeckDatabaseSync()\n .prepare(SELECT_AGENT_SQL)\n .all() as OverdeckAgentRow[];\n return rows.map(overdeckRowToAgentState);\n}\n\nexport function saveOverdeckAgentStateSync(state: AgentState): void {\n const db = getOverdeckDatabaseSync();\n const updatedAt = Date.now();\n db.prepare(\n `INSERT OR IGNORE INTO issues (id, stage, updated_at) VALUES (?, 'working', ?)`,\n ).run(state.issueId, updatedAt);\n db.prepare(\n `INSERT OR REPLACE INTO agents (${AGENT_COLUMNS_FOR_DB.join(', ')}) VALUES (${AGENT_COLUMNS_FOR_DB.map(() => '?').join(', ')})`,\n ).run(...stateToOverdeckParamsForDb(state, updatedAt));\n}\n","import { Effect } from 'effect';\nimport type { ReviewStatus } from './review-status.js';\n\nexport function normalizeReviewStatusSync(status: ReviewStatus): ReviewStatus {\n const shouldClearMergeNotes = status.mergeStatus === 'verifying' || status.mergeStatus === 'merged';\n const shouldClearReadyForMerge =\n status.mergeStatus === 'merged' ||\n // PAN-1862 (FR-16): a skipped review (mode none) passes the gate like passed.\n (status.reviewStatus !== 'passed' && status.reviewStatus !== 'skipped') ||\n (status.testStatus !== 'passed' && status.testStatus !== 'skipped') ||\n (status.uatStatus !== undefined && status.uatStatus !== 'passed') ||\n ((status.blockerReasons?.length ?? 0) > 0);\n\n return {\n ...status,\n ...(shouldClearMergeNotes ? { mergeNotes: undefined } : {}),\n ...(shouldClearReadyForMerge ? { readyForMerge: false } : {}),\n };\n}\n\n// ─── Effect variants (PAN-1249) ───────────────────────────────────────────────\n\n/** Normalize a review status record (clear stale fields). Pure. */\nexport const normalizeReviewStatus = (\n status: ReviewStatus,\n): Effect.Effect<ReviewStatus> => Effect.sync(() => normalizeReviewStatusSync(status));\n","/**\n * Sync CRUD for review_status in overdeck.db.\n *\n * Mirrors the surface of database/review-status-db.ts but reads/writes\n * overdeck.db via getOverdeckDatabaseSync() instead of panopticon.db.\n *\n * The overdeck review_status table has the same column set as the old DB\n * (added in the 0000_overdeck_init.sql migration). status_history is shared\n * between the old and new domains — both tables exist in overdeck.db.\n */\nimport { Effect } from 'effect';\nimport type { BlockerReason, ReviewStatus, StatusHistoryEntry } from '../review-status.js';\nimport { normalizeReviewStatusSync } from '../review-status-normalize.js';\nimport { getOverdeckDatabaseSync } from './infra.js';\n\n// ── Timestamp helpers — overdeck stores timestamps as integer epoch-MILLISECONDS;\n// the ReviewStatus domain type exposes them as ISO strings, so convert at the\n// storage boundary (PAN-1961). ─────────────────────────────────────────────\nfunction isoToMs(value: string | null | undefined): number | null {\n if (!value) return null;\n const ms = Date.parse(value);\n return Number.isFinite(ms) ? ms : null;\n}\nfunction msToIso(value: number | null | undefined): string | undefined {\n return value == null ? undefined : new Date(value).toISOString();\n}\n\n// ── Internal row type ────────────────────────────────────────────────────────\n\ninterface DbRow {\n issue_id: string;\n review_status: string;\n test_status: string;\n merge_status: string | null;\n inspect_status: string | null;\n inspect_notes: string | null;\n inspect_started_at: number | null;\n inspect_bead_id: string | null;\n verification_status: string | null;\n verification_notes: string | null;\n verification_cycle_count: number | null;\n verification_max_cycles: number | null;\n review_notes: string | null;\n test_notes: string | null;\n merge_notes: string | null;\n updated_at: number;\n ready_for_merge: number;\n auto_requeue_count: number | null;\n merge_retry_count: number | null;\n pr_url: string | null;\n pr_head_sha: string | null;\n pr_number: number | null;\n stuck: number;\n stuck_reason: string | null;\n stuck_at: number | null;\n stuck_details: string | null;\n reviewed_at_commit: string | null;\n review_spawned_at: number | null;\n conflict_resolution_dispatched_at: number | null;\n test_retry_count: number | null;\n review_retry_count: number | null;\n recovery_started_at: number | null;\n deacon_ignored: number;\n deacon_ignored_at: number | null;\n deacon_ignored_reason: string | null;\n blocker_reasons: string | null;\n last_verified_commit: string | null;\n merge_step: string | null;\n auto_merge: number | null;\n}\n\nfunction rowToReviewStatus(row: DbRow, history: StatusHistoryEntry[]): ReviewStatus {\n return normalizeReviewStatusSync({\n issueId: row.issue_id.toUpperCase(),\n reviewStatus: row.review_status as ReviewStatus['reviewStatus'],\n testStatus: row.test_status as ReviewStatus['testStatus'],\n mergeStatus: (row.merge_status as ReviewStatus['mergeStatus']) ?? undefined,\n inspectStatus: (row.inspect_status as ReviewStatus['inspectStatus']) ?? undefined,\n inspectNotes: row.inspect_notes ?? undefined,\n inspectStartedAt: msToIso(row.inspect_started_at),\n inspectBeadId: row.inspect_bead_id ?? undefined,\n verificationStatus:\n (row.verification_status as ReviewStatus['verificationStatus']) ?? undefined,\n verificationNotes: row.verification_notes ?? undefined,\n verificationCycleCount: row.verification_cycle_count ?? undefined,\n verificationMaxCycles: row.verification_max_cycles ?? undefined,\n reviewNotes: row.review_notes ?? undefined,\n testNotes: row.test_notes ?? undefined,\n mergeNotes: row.merge_notes ?? undefined,\n updatedAt: msToIso(row.updated_at) ?? new Date(0).toISOString(),\n readyForMerge: row.ready_for_merge === 1,\n autoRequeueCount: row.auto_requeue_count ?? undefined,\n mergeRetryCount: row.merge_retry_count ?? undefined,\n prUrl: row.pr_url ?? undefined,\n prHeadSha: row.pr_head_sha ?? undefined,\n prNumber: row.pr_number ?? undefined,\n stuck: row.stuck === 1 ? true : undefined,\n stuckReason: row.stuck_reason ?? undefined,\n stuckAt: msToIso(row.stuck_at),\n stuckDetails: row.stuck_details ?? undefined,\n reviewedAtCommit: row.reviewed_at_commit ?? undefined,\n reviewSpawnedAt: msToIso(row.review_spawned_at),\n conflictResolutionDispatchedAt: msToIso(row.conflict_resolution_dispatched_at),\n testRetryCount: row.test_retry_count ?? undefined,\n reviewRetryCount: row.review_retry_count ?? undefined,\n recoveryStartedAt: msToIso(row.recovery_started_at),\n deaconIgnored: row.deacon_ignored === 1 ? true : undefined,\n deaconIgnoredAt: msToIso(row.deacon_ignored_at),\n deaconIgnoredReason: row.deacon_ignored_reason ?? undefined,\n blockerReasons: row.blocker_reasons\n ? (JSON.parse(row.blocker_reasons) as BlockerReason[])\n : undefined,\n lastVerifiedCommit: row.last_verified_commit ?? undefined,\n mergeStep: row.merge_step ?? undefined,\n autoMerge:\n row.auto_merge === null || row.auto_merge === undefined\n ? undefined\n : row.auto_merge === 1,\n history: history.length > 0 ? history : undefined,\n });\n}\n\nfunction getHistorySync(issueId: string): StatusHistoryEntry[] {\n const db = getOverdeckDatabaseSync();\n const rows = db\n .prepare(\n `SELECT type, status, timestamp, notes FROM status_history\n WHERE issue_id = ? ORDER BY timestamp ASC`,\n )\n .all(issueId.toUpperCase()) as Array<{\n type: string;\n status: string;\n timestamp: number;\n notes: string | null;\n }>;\n return rows.map((r) => ({\n type: r.type as StatusHistoryEntry['type'],\n status: r.status,\n timestamp: new Date(r.timestamp).toISOString(),\n ...(r.notes ? { notes: r.notes } : {}),\n }));\n}\n\n// ── Write operations ─────────────────────────────────────────────────────────\n\nexport function upsertReviewStatusSync(status: ReviewStatus): void {\n const db = getOverdeckDatabaseSync();\n const s = { ...status, issueId: status.issueId.toUpperCase() };\n\n const upsert = db.transaction(() => {\n // Ensure the issues row exists so status_history FK is satisfied.\n db.prepare(\n `INSERT OR IGNORE INTO issues (id, stage, updated_at) VALUES (?, 'working', ?)`,\n ).run(s.issueId, Date.now());\n\n db.prepare(`\n INSERT INTO review_status (\n issue_id, review_status, test_status, merge_status,\n inspect_status, inspect_notes, inspect_started_at, inspect_bead_id,\n verification_status, verification_notes,\n verification_cycle_count, verification_max_cycles,\n review_notes, test_notes, merge_notes,\n updated_at, ready_for_merge, auto_requeue_count, merge_retry_count, pr_url,\n pr_head_sha, pr_number,\n stuck, stuck_reason, stuck_at, stuck_details,\n reviewed_at_commit, review_spawned_at, conflict_resolution_dispatched_at,\n test_retry_count, review_retry_count, recovery_started_at,\n deacon_ignored, deacon_ignored_at, deacon_ignored_reason,\n blocker_reasons, last_verified_commit, merge_step, auto_merge\n ) VALUES (\n ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?\n )\n ON CONFLICT(issue_id) DO UPDATE SET\n review_status = excluded.review_status,\n test_status = excluded.test_status,\n merge_status = excluded.merge_status,\n inspect_status = excluded.inspect_status,\n inspect_notes = excluded.inspect_notes,\n inspect_started_at = excluded.inspect_started_at,\n inspect_bead_id = excluded.inspect_bead_id,\n verification_status = excluded.verification_status,\n verification_notes = excluded.verification_notes,\n verification_cycle_count = excluded.verification_cycle_count,\n verification_max_cycles = excluded.verification_max_cycles,\n review_notes = excluded.review_notes,\n test_notes = excluded.test_notes,\n merge_notes = excluded.merge_notes,\n updated_at = excluded.updated_at,\n ready_for_merge = excluded.ready_for_merge,\n auto_requeue_count = excluded.auto_requeue_count,\n merge_retry_count = excluded.merge_retry_count,\n pr_url = excluded.pr_url,\n pr_head_sha = excluded.pr_head_sha,\n pr_number = excluded.pr_number,\n stuck = excluded.stuck,\n stuck_reason = excluded.stuck_reason,\n stuck_at = excluded.stuck_at,\n stuck_details = excluded.stuck_details,\n reviewed_at_commit = excluded.reviewed_at_commit,\n review_spawned_at = excluded.review_spawned_at,\n conflict_resolution_dispatched_at = excluded.conflict_resolution_dispatched_at,\n test_retry_count = excluded.test_retry_count,\n review_retry_count = excluded.review_retry_count,\n recovery_started_at = excluded.recovery_started_at,\n deacon_ignored = excluded.deacon_ignored,\n deacon_ignored_at = excluded.deacon_ignored_at,\n deacon_ignored_reason = excluded.deacon_ignored_reason,\n blocker_reasons = excluded.blocker_reasons,\n last_verified_commit = excluded.last_verified_commit,\n merge_step = excluded.merge_step,\n auto_merge = excluded.auto_merge\n `).run(\n s.issueId,\n s.reviewStatus,\n s.testStatus,\n s.mergeStatus ?? null,\n s.inspectStatus ?? null,\n null, // inspect_notes — PAN-1988: feedback text lives in the journal, not the DB cache\n isoToMs(s.inspectStartedAt),\n s.inspectBeadId ?? null,\n s.verificationStatus ?? null,\n null, // verification_notes — PAN-1988: feedback text lives in the journal, not the DB cache\n s.verificationCycleCount ?? null,\n s.verificationMaxCycles ?? null,\n null, // review_notes — PAN-1988: feedback text lives in the journal, not the DB cache\n null, // test_notes — PAN-1988: journal-only\n null, // merge_notes — PAN-1988: journal-only\n isoToMs(s.updatedAt) ?? Date.now(),\n s.readyForMerge ? 1 : 0,\n s.autoRequeueCount ?? null,\n s.mergeRetryCount ?? null,\n s.prUrl ?? null,\n s.prHeadSha ?? null,\n s.prNumber ?? null,\n s.stuck ? 1 : 0,\n s.stuckReason ?? null,\n isoToMs(s.stuckAt),\n s.stuckDetails ?? null,\n s.reviewedAtCommit ?? null,\n isoToMs(s.reviewSpawnedAt),\n isoToMs(s.conflictResolutionDispatchedAt),\n s.testRetryCount ?? null,\n s.reviewRetryCount ?? null,\n isoToMs(s.recoveryStartedAt),\n s.deaconIgnored ? 1 : 0,\n isoToMs(s.deaconIgnoredAt),\n s.deaconIgnoredReason ?? null,\n s.blockerReasons ? JSON.stringify(s.blockerReasons) : null,\n s.lastVerifiedCommit ?? null,\n s.mergeStep ?? null,\n s.autoMerge === undefined ? null : s.autoMerge ? 1 : 0,\n );\n\n if (s.history && s.history.length > 0) {\n const insertHistory = db.prepare(\n `INSERT OR IGNORE INTO status_history (issue_id, type, status, timestamp, notes)\n VALUES (?, ?, ?, ?, ?)`,\n );\n for (const entry of s.history) {\n insertHistory.run(s.issueId, entry.type, entry.status, new Date(entry.timestamp).getTime(), entry.notes ?? null);\n }\n }\n });\n\n upsert();\n}\n\nexport function deleteReviewStatus(issueId: string): void {\n const db = getOverdeckDatabaseSync();\n db.prepare('DELETE FROM review_status WHERE issue_id = ?').run(issueId.toUpperCase());\n}\n\n// ── Read operations ──────────────────────────────────────────────────────────\n\nexport function getReviewStatusFromDbSync(issueId: string): ReviewStatus | null {\n const db = getOverdeckDatabaseSync();\n const normalizedId = issueId.toUpperCase();\n const row = db\n .prepare('SELECT * FROM review_status WHERE issue_id = ?')\n .get(normalizedId) as DbRow | undefined;\n if (!row) return null;\n return rowToReviewStatus(row, getHistorySync(normalizedId));\n}\n\nexport function getAllReviewStatusesFromDb(): Record<string, ReviewStatus> {\n const db = getOverdeckDatabaseSync();\n const rows = db\n .prepare('SELECT * FROM review_status ORDER BY updated_at DESC')\n .all() as DbRow[];\n\n const historyRows = db\n .prepare(\n `SELECT issue_id, type, status, timestamp, notes FROM status_history\n ORDER BY issue_id, timestamp ASC`,\n )\n .all() as Array<{\n issue_id: string;\n type: string;\n status: string;\n timestamp: string;\n notes: string | null;\n }>;\n\n const historyByIssue = new Map<string, StatusHistoryEntry[]>();\n for (const row of historyRows) {\n const bucket = historyByIssue.get(row.issue_id) ?? [];\n bucket.push({\n type: row.type as StatusHistoryEntry['type'],\n status: row.status,\n timestamp: row.timestamp,\n ...(row.notes ? { notes: row.notes } : {}),\n });\n historyByIssue.set(row.issue_id, bucket);\n }\n\n const result: Record<string, ReviewStatus> = {};\n for (const row of rows) {\n result[row.issue_id] = rowToReviewStatus(row, historyByIssue.get(row.issue_id) ?? []);\n }\n return result;\n}\n\nexport function getReviewStatusesFromDb(issueIds: string[]): Record<string, ReviewStatus> {\n const normalizedIds = [...new Set(issueIds.map((id) => id.toUpperCase()).filter(Boolean))];\n if (normalizedIds.length === 0) return {};\n const db = getOverdeckDatabaseSync();\n const placeholders = normalizedIds.map(() => '?').join(', ');\n\n const rows = db\n .prepare(\n `SELECT * FROM review_status WHERE issue_id IN (${placeholders}) ORDER BY updated_at DESC`,\n )\n .all(...normalizedIds) as DbRow[];\n if (rows.length === 0) return {};\n\n const historyRows = db\n .prepare(\n `SELECT issue_id, type, status, timestamp, notes FROM status_history\n WHERE issue_id IN (${placeholders}) ORDER BY issue_id, timestamp ASC`,\n )\n .all(...normalizedIds) as Array<{\n issue_id: string;\n type: string;\n status: string;\n timestamp: string;\n notes: string | null;\n }>;\n\n const historyByIssue = new Map<string, StatusHistoryEntry[]>();\n for (const row of historyRows) {\n const bucket = historyByIssue.get(row.issue_id) ?? [];\n bucket.push({\n type: row.type as StatusHistoryEntry['type'],\n status: row.status,\n timestamp: row.timestamp,\n ...(row.notes ? { notes: row.notes } : {}),\n });\n historyByIssue.set(row.issue_id, bucket);\n }\n\n const result: Record<string, ReviewStatus> = {};\n for (const row of rows) {\n result[row.issue_id] = rowToReviewStatus(row, historyByIssue.get(row.issue_id) ?? []);\n }\n return result;\n}\n\n// ── Stuck state helpers ──────────────────────────────────────────────────────\n\nexport function markWorkspaceStuck(\n issueId: string,\n reason: string,\n details?: Record<string, unknown>,\n): void {\n const db = getOverdeckDatabaseSync();\n const now = Date.now();\n const detailsJson = details ? JSON.stringify(details) : null;\n db.prepare(`\n INSERT OR IGNORE INTO review_status\n (issue_id, review_status, test_status, updated_at, ready_for_merge,\n stuck, stuck_reason, stuck_at, stuck_details)\n VALUES (?, 'pending', 'pending', ?, 0, 1, ?, ?, ?)\n `).run(issueId.toUpperCase(), now, reason, now, detailsJson);\n db.prepare(`\n UPDATE review_status\n SET stuck = 1, stuck_reason = ?, stuck_at = ?, stuck_details = ?, updated_at = ?\n WHERE issue_id = ?\n `).run(reason, now, detailsJson, now, issueId.toUpperCase());\n}\n\nexport function clearWorkspaceStuck(issueId: string): void {\n const db = getOverdeckDatabaseSync();\n const now = Date.now();\n db.prepare(`\n UPDATE review_status\n SET stuck = 0, stuck_reason = NULL, stuck_at = NULL, stuck_details = NULL, updated_at = ?\n WHERE issue_id = ?\n `).run(now, issueId.toUpperCase());\n}\n\nexport function setDeaconIgnored(\n issueId: string,\n ignored: boolean,\n reason?: string,\n): void {\n const db = getOverdeckDatabaseSync();\n const now = Date.now();\n db.prepare(`\n INSERT OR IGNORE INTO review_status\n (issue_id, review_status, test_status, updated_at, ready_for_merge, deacon_ignored)\n VALUES (?, 'pending', 'pending', ?, 0, 0)\n `).run(issueId.toUpperCase(), now);\n db.prepare(`\n UPDATE review_status\n SET deacon_ignored = ?, deacon_ignored_at = ?, deacon_ignored_reason = ?, updated_at = ?\n WHERE issue_id = ?\n `).run(ignored ? 1 : 0, ignored ? now : null, reason ?? null, now, issueId.toUpperCase());\n}\n\nexport function setAutoMerge(issueId: string, autoMerge: boolean | null): void {\n const db = getOverdeckDatabaseSync();\n const now = Date.now();\n db.prepare(`\n INSERT OR IGNORE INTO review_status\n (issue_id, review_status, test_status, updated_at, ready_for_merge)\n VALUES (?, 'pending', 'pending', ?, 0)\n `).run(issueId.toUpperCase(), now);\n db.prepare(`\n UPDATE review_status SET auto_merge = ?, updated_at = ? WHERE issue_id = ?\n `).run(\n autoMerge === null ? null : autoMerge ? 1 : 0,\n now,\n issueId.toUpperCase(),\n );\n}\n\n// ── Merge-blocker reconcile candidates ───────────────────────────────────────\n\nexport interface MergeBlockerReconcileCandidate {\n issueId: string;\n prUrl: string | undefined;\n blockerReasons: BlockerReason[] | undefined;\n readyForMerge: boolean;\n}\n\n/**\n * Sync query for merge-blocker reconcile service.\n * Drop-in for getMergeBlockerReconcileCandidatesSync() from review-status-db.ts.\n */\nexport function getMergeBlockerReconcileCandidatesSync(): MergeBlockerReconcileCandidate[] {\n const db = getOverdeckDatabaseSync();\n const rows = db.prepare(`\n SELECT issue_id, pr_url, blocker_reasons, ready_for_merge\n FROM review_status\n WHERE ready_for_merge = 1\n OR blocker_reasons LIKE '%merge_conflict%'\n OR blocker_reasons LIKE '%not_mergeable%'\n `).all() as Array<{\n issue_id: string;\n pr_url: string | null;\n blocker_reasons: string | null;\n ready_for_merge: number;\n }>;\n\n return rows.map((row) => ({\n issueId: row.issue_id.toUpperCase(),\n prUrl: row.pr_url ?? undefined,\n blockerReasons: row.blocker_reasons ? JSON.parse(row.blocker_reasons) : undefined,\n readyForMerge: row.ready_for_merge === 1,\n }));\n}\n\n/**\n * Effect wrapper for getMergeBlockerReconcileCandidatesSync.\n * Drop-in for getMergeBlockerReconcileCandidates() from review-status-db.ts.\n */\nexport const getMergeBlockerReconcileCandidates = (): Effect.Effect<MergeBlockerReconcileCandidate[]> =>\n Effect.promise(() =>\n new Promise<MergeBlockerReconcileCandidate[]>((resolve, reject) => {\n setImmediate(() => {\n try {\n resolve(getMergeBlockerReconcileCandidatesSync());\n } catch (err) {\n reject(err);\n }\n });\n }),\n );\n","const issueRecordLocks = new Map<string, Promise<void>>();\n\n/**\n * Serialize async read-modify-write rebuilds for a single issue record.\n *\n * Synchronous record writers remain synchronous; async flows that read, await,\n * then write the whole record must use this lock so same-issue rebuilds cannot\n * overwrite each other's final re-read.\n */\nexport async function withIssueRecordLock<T>(\n issueId: string,\n fn: () => T | Promise<T>,\n): Promise<T> {\n const key = issueId.toUpperCase();\n const previous = issueRecordLocks.get(key) ?? Promise.resolve();\n let release: () => void = () => {};\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chain = previous.catch(() => undefined).then(() => current);\n issueRecordLocks.set(key, chain);\n\n await previous.catch(() => undefined);\n\n try {\n return await fn();\n } finally {\n release();\n if (issueRecordLocks.get(key) === chain) {\n issueRecordLocks.delete(key);\n }\n }\n}\n","/**\n * PAN-1908 / PAN-1919: per-issue permanent-record builder.\n *\n * Builds a single JSON record per issue from SQLite (pipeline verdicts, usage,\n * merges) plus the legacy project-side continue file. The actual read/write/path\n * helpers live in `record.ts` (PAN-1919 single-writer module) and write the\n * record onto the feature branch at `<workspace>/.pan/records/<issue>.json`.\n */\n\nimport { hostname } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, promises as fsp } from 'node:fs';\nimport { PAN_CONTINUES_DIRNAME, PAN_DIRNAME } from './types.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\nimport {\n getCostBreakdownByStageAndModelSync,\n getCostForIssueSync,\n} from '../overdeck/cost-sync.js';\nimport { getMergeSetSync } from '../merge-set.js';\nimport {\n getProjectSync,\n resolveProjectFromIssueSync,\n type ProjectConfig,\n} from '../projects.js';\nimport type { ReviewStatus } from '../review-status.js';\nimport type { RuntimeName } from '../runtimes/types.js';\nimport type {\n ContinueBeadsMapping,\n ContinueDecision,\n ContinueFeedbackEntry,\n ContinueHazard,\n ContinueResumePoint,\n ContinueSessionEntry,\n ScopeDriftRecord,\n} from '../vbrief/continue-state.js';\nimport { listOverdeckAgentStatesSync } from '../overdeck/agent-state-sync.js';\nimport {\n getIssueWorkspacePath,\n queueIssueRecordCommit,\n RECORD_SCHEMA_VERSION,\n readIssueRecord,\n readIssueRecordSync,\n writeIssueRecordSync,\n type PanIssueRecord,\n type PanIssuePipelineRecord,\n type PanIssueUsageRecord,\n} from './record.js';\nimport { withIssueRecordLock } from './record-lock.js';\n\nexport type {\n PanIssueRecord,\n PanIssueCloseOutRecord,\n PanIssuePipelineRecord,\n PanIssueUsageRecord,\n} from './record.js';\n\n// ─── Continue projection ──────────────────────────────────────────────────────\n\ninterface ContinueFile {\n issueId?: string;\n gitState?: { branch?: string };\n decisions?: ContinueDecision[];\n hazards?: ContinueHazard[];\n resumePoint?: ContinueResumePoint | null;\n beadsMapping?: ContinueBeadsMapping;\n sessionHistory?: ContinueSessionEntry[];\n feedback?: ContinueFeedbackEntry[];\n agentModel?: string;\n scopeDrift?: ScopeDriftRecord;\n}\n\nfunction projectContinue(raw: ContinueFile | null): Pick<PanIssueRecord, 'decisions' | 'hazards' | 'resumePoint' | 'beadsMapping' | 'sessionHistory' | 'feedback' | 'scopeDrift'> {\n return {\n decisions: raw?.decisions,\n hazards: raw?.hazards,\n resumePoint: raw?.resumePoint,\n beadsMapping: raw?.beadsMapping,\n sessionHistory: raw?.sessionHistory,\n feedback: raw?.feedback ?? [],\n scopeDrift: raw?.scopeDrift,\n };\n}\n\n// ─── Pipeline projection ──────────────────────────────────────────────────────\n\nfunction projectPipeline(\n issueId: string,\n status: ReviewStatus | null,\n existing?: PanIssuePipelineRecord,\n): PanIssuePipelineRecord {\n const base: PanIssuePipelineRecord = {\n issueId,\n reviewStatus: status?.reviewStatus ?? 'pending',\n testStatus: status?.testStatus ?? 'pending',\n verificationStatus: status?.verificationStatus,\n inspectStatus: status?.inspectStatus,\n mergeStatus: status?.mergeStatus,\n readyForMerge: status?.readyForMerge ?? false,\n closedOut: existing?.closedOut,\n closedOutAt: existing?.closedOutAt,\n updatedAt: status?.updatedAt ?? new Date().toISOString(),\n };\n\n if (!status) return base;\n\n return {\n ...base,\n reviewNotes: status.reviewNotes,\n testNotes: status.testNotes,\n verificationNotes: status.verificationNotes,\n inspectNotes: status.inspectNotes,\n mergeNotes: status.mergeNotes,\n blockerReasons: status.blockerReasons,\n prUrl: status.prUrl,\n prNumber: status.prNumber,\n prHeadSha: status.prHeadSha,\n reviewedAtCommit: status.reviewedAtCommit,\n lastVerifiedCommit: status.lastVerifiedCommit,\n reviewRequestedAt: status.reviewRequestedAt,\n scopeDrift: status.scopeDrift,\n autoMerge: status.autoMerge,\n deaconIgnored: status.deaconIgnored,\n deaconIgnoredAt: status.deaconIgnoredAt,\n deaconIgnoredReason: status.deaconIgnoredReason,\n reviewerVerdicts: (status as { reviewerVerdicts?: unknown }).reviewerVerdicts,\n };\n}\n\n// ─── Usage projection ─────────────────────────────────────────────────────────\n\nfunction projectUsage(issueId: string): PanIssueUsageRecord {\n const { byStage, totals } = getCostBreakdownByStageAndModelSync(issueId);\n const aggregate = getCostForIssueSync(issueId);\n\n return {\n byStage,\n totals,\n costAtCloseOut: {\n usd: aggregate?.totalCost ?? 0,\n pricingAsOf: new Date().toISOString(),\n },\n };\n}\n\n// ─── Merge projection ─────────────────────────────────────────────────────────\n\nfunction projectMerges(issueId: string): string[] {\n const mergeSet = getMergeSetSync(issueId);\n if (!mergeSet) return [];\n return mergeSet.repos\n .map(r => r.artifactUrl)\n .filter((url): url is string => typeof url === 'string' && url.length > 0);\n}\n\n// ─── Record builder ───────────────────────────────────────────────────────────\n\nasync function readLegacyContinueText(projectRoot: string, issueId: string): Promise<string | null> {\n const path = join(projectRoot, PAN_DIRNAME, PAN_CONTINUES_DIRNAME, `${issueId.toLowerCase()}.vbrief.json`);\n try {\n return await fsp.readFile(path, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/** Read workspace continue.json and return its statusOverrides (if any). */\nasync function readWorkspaceContinueStatusOverrides(issueId: string): Promise<Record<string, string> | undefined> {\n const workspacePath = getIssueWorkspacePath(issueId);\n if (!workspacePath || !existsSync(workspacePath)) return undefined;\n const continuePath = join(workspacePath, '.pan', 'continue.json');\n try {\n const text = await fsp.readFile(continuePath, 'utf-8');\n const parsed = JSON.parse(text) as { statusOverrides?: Record<string, string> };\n return parsed.statusOverrides ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Read harness/model for an issue from the overdeck agents table (most recent work agent). */\nfunction projectAgentHarnessModel(issueId: string): { harness?: RuntimeName; model?: string } {\n try {\n const agents = listOverdeckAgentStatesSync().filter(\n (a) => a.issueId?.toUpperCase() === issueId.toUpperCase(),\n );\n const workAgent =\n agents\n .filter((a) => a.role === 'work')\n .sort((a, b) => (b.startedAt ?? '').localeCompare(a.startedAt ?? ''))[0]\n ?? agents[agents.length - 1];\n return {\n harness: workAgent?.harness,\n model: workAgent?.model ?? undefined,\n };\n } catch {\n return {};\n }\n}\n\nexport interface BuildIssueRecordOptions {\n closedAt?: string;\n owner?: string;\n reviewStatus?: ReviewStatus | null;\n}\n\nexport async function buildIssueRecord(\n project: ProjectConfig,\n issueId: string,\n opts: BuildIssueRecordOptions = {},\n): Promise<PanIssueRecord> {\n const existing = await readIssueRecord(project, issueId);\n const legacyContinueText = await readLegacyContinueText(project.path, issueId);\n const continueSubset = projectContinue(legacyContinueText ? (JSON.parse(legacyContinueText) as ContinueFile) : null);\n const pipelineRecord = projectPipeline(issueId, opts.reviewStatus ?? null, existing?.pipeline);\n const usageRecord = projectUsage(issueId);\n const merges = projectMerges(issueId);\n\n // PAN-1919: fold workspace continue statusOverrides; fall back to existing.\n const workspaceStatusOverrides = await readWorkspaceContinueStatusOverrides(issueId);\n const mergedStatusOverrides = workspaceStatusOverrides\n ? { ...(existing?.statusOverrides ?? {}), ...workspaceStatusOverrides }\n : existing?.statusOverrides;\n\n // PAN-1919: harness/model from existing record, then agents table as fallback.\n const agentHM = existing?.harness || existing?.model\n ? { harness: existing.harness, model: existing.model }\n : projectAgentHarnessModel(issueId);\n\n return {\n issueId: issueId.toUpperCase(),\n schemaVersion: RECORD_SCHEMA_VERSION,\n ...continueSubset,\n ...existing,\n harness: agentHM.harness,\n model: agentHM.model,\n statusOverrides: mergedStatusOverrides,\n pipeline: pipelineRecord,\n closeOut: {\n usage: usageRecord,\n merges,\n ranOn: hostname(),\n closedAt: opts.closedAt,\n },\n owner: opts.owner ?? existing?.owner,\n };\n}\n\n// Re-export core record I/O from the PAN-1919 single-writer module.\nexport {\n getIssueRecordPath,\n markRecordPipelineClosedOutSync,\n writeIssueRecordSync,\n readIssueRecord,\n queueIssueRecordCommit,\n} from './record.js';\n\n// ─── Owner-URI lease (PAN-1908, CP-3) ─────────────────────────────────────────\n\nexport {\n buildOwnUri,\n claimIssueOwner,\n clearIssueOwner,\n type ClaimResult,\n} from './record.js';\n\n/**\n * PAN-1908 / PAN-1919: rebuild and queue the per-issue permanent record for a\n * given issue. Fire-and-forget: failures are logged, never thrown, so\n * review-status writes stay synchronous and fast.\n *\n * PAN-2583: returns whether the durable write actually landed, so the caller\n * can fall back to a sandbox-writable verdict drop when it did not (a sandboxed\n * reviewer cannot write ${OVERDECK_HOME}/state, and swallowing that here was\n * how blocked review verdicts silently vanished).\n */\nexport async function updateIssueRecordForIssue(\n issueId: string,\n reviewStatus?: ReviewStatus | null,\n): Promise<boolean> {\n try {\n const resolved = resolveProjectFromIssueSync(issueId);\n if (!resolved) return false;\n const project = getProjectSync(resolved.projectKey);\n if (!project) return false;\n\n await withIssueRecordLock(issueId, async () => {\n const record = await buildIssueRecord(project, issueId, { reviewStatus });\n // buildIssueRecord's `existing` snapshot is read at the top of several awaits;\n // anything written to the record during that window would be erased by this\n // whole-record write (lost update). Observed twice on PAN-1791: wiped swarm\n // slot assignments during the runaway, then wiped item statusOverrides right\n // after `pan done` — which made every completed item dispatchable again and\n // re-spawned slots for finished work. Re-read both blocks synchronously\n // immediately before writing so the freshest values survive the rebuild.\n const fresh = readIssueRecordSync(project, issueId);\n if (fresh?.swarm) record.swarm = fresh.swarm;\n if (fresh?.statusOverrides && Object.keys(fresh.statusOverrides).length > 0) {\n record.statusOverrides = { ...record.statusOverrides, ...fresh.statusOverrides };\n }\n const recordPath = writeIssueRecordSync(project, issueId, record);\n queueIssueRecordCommit(project, issueId, recordPath);\n });\n return true;\n } catch (err) {\n console.warn(`[pan-dir/records] Failed to update record for ${issueId}: ${(err as Error).message}`);\n return false;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"records-CTmvuRzz.js","names":["fsp"],"sources":["../src/lib/overdeck/agent-state-sync.ts","../src/lib/review-status-normalize.ts","../src/lib/overdeck/review-status-sync.ts","../src/lib/pan-dir/record-lock.ts","../src/lib/pan-dir/records.ts"],"sourcesContent":["import type { AgentState, Role } from '../agents.js';\nimport type { RuntimeName } from '../runtimes/types.js';\nimport { getOverdeckDatabaseSync } from './infra.js';\n\ntype OverdeckAgentRow = {\n id: string;\n issue_id: string;\n role: string;\n status: string;\n workspace: string;\n session_id: string | null;\n harness: string | null;\n model: string | null;\n host_override: string | null;\n delivery_method: string | null;\n started_at: number | null;\n last_resume_at: number | null;\n stopped_by_user: number | null;\n stopped_by_pause: number | null;\n kickoff_delivered: number | null;\n paused: number | null;\n paused_reason: string | null;\n yielded_by_scheduler: number | null;\n yielded_at: number | null;\n last_yield_resume_at: number | null;\n troubled: number | null;\n channels_enabled: number | null;\n consecutive_failures: number | null;\n first_failure_in_run_at: number | null;\n last_failure_next_retry_at: number | null;\n stopped_at: number | null;\n paused_at: number | null;\n troubled_at: number | null;\n last_activity: number | null;\n last_failure_reason: string | null;\n phase: string | null;\n role_run_head: string | null;\n flywheel_run_id: string | null;\n cost_so_far: number | null;\n review_sub_role: string | null;\n review_run_id: string | null;\n review_synthesis_agent_id: string | null;\n review_output_path: string | null;\n review_deadline_at: number | null;\n review_monitor_signaled: string | null;\n review_retry_attempt: number | null;\n updated_at: number;\n};\n\n/** Exported for agent-projection.ts transactional writes. */\nexport const AGENT_COLUMNS_FOR_DB = [\n 'id',\n 'issue_id',\n 'role',\n 'status',\n 'workspace',\n 'session_id',\n 'harness',\n 'model',\n 'host_override',\n 'delivery_method',\n 'started_at',\n 'last_resume_at',\n 'stopped_by_user',\n 'stopped_by_pause',\n 'kickoff_delivered',\n 'paused',\n 'paused_reason',\n 'yielded_by_scheduler',\n 'yielded_at',\n 'last_yield_resume_at',\n 'troubled',\n 'channels_enabled',\n 'consecutive_failures',\n 'first_failure_in_run_at',\n 'last_failure_next_retry_at',\n 'stopped_at',\n 'paused_at',\n 'troubled_at',\n 'last_activity',\n 'last_failure_reason',\n 'phase',\n 'role_run_head',\n 'flywheel_run_id',\n 'cost_so_far',\n 'review_sub_role',\n 'review_run_id',\n 'review_synthesis_agent_id',\n 'review_output_path',\n 'review_deadline_at',\n 'review_monitor_signaled',\n 'review_retry_attempt',\n 'updated_at',\n] as const;\n\nconst SELECT_AGENT_SQL = `SELECT ${AGENT_COLUMNS_FOR_DB.join(', ')} FROM agents`;\n\nfunction isoFromMillis(value: number | null | undefined): string | undefined {\n return value == null ? undefined : new Date(value).toISOString();\n}\n\nfunction millisFromIso(value: string | null | undefined): number | null {\n if (!value) return null;\n const millis = Date.parse(value);\n return Number.isFinite(millis) ? millis : null;\n}\n\nfunction boolFromInteger(value: number | null | undefined): boolean | undefined {\n return value == null ? undefined : Boolean(value);\n}\n\nfunction hostOverrideFromRow(value: string | null | undefined): boolean | undefined {\n if (value == null) return undefined;\n return value === '1' || value === 'true' || value === 'yes';\n}\n\nfunction hostOverrideToRow(value: boolean | undefined): string | null {\n return value === true ? 'true' : null;\n}\n\nfunction overdeckRowToAgentState(row: OverdeckAgentRow): AgentState {\n const deliveryMethod = row.delivery_method as AgentState['deliveryMethod'] | null;\n return {\n id: row.id,\n issueId: row.issue_id,\n workspace: row.workspace,\n role: row.role as Role,\n model: row.model ?? '',\n status: row.status as AgentState['status'],\n startedAt: isoFromMillis(row.started_at) ?? isoFromMillis(row.updated_at) ?? new Date().toISOString(),\n harness: row.harness ? (row.harness as RuntimeName) : undefined,\n lastResumeAt: isoFromMillis(row.last_resume_at),\n stoppedByUser: boolFromInteger(row.stopped_by_user),\n stoppedByPause: boolFromInteger(row.stopped_by_pause),\n kickoffDelivered: boolFromInteger(row.kickoff_delivered),\n paused: boolFromInteger(row.paused),\n pausedReason: row.paused_reason ?? undefined,\n yieldedByScheduler: boolFromInteger(row.yielded_by_scheduler),\n yieldedAt: isoFromMillis(row.yielded_at),\n lastYieldResumeAt: isoFromMillis(row.last_yield_resume_at),\n troubled: boolFromInteger(row.troubled),\n consecutiveFailures: row.consecutive_failures ?? undefined,\n firstFailureInRunAt: isoFromMillis(row.first_failure_in_run_at),\n lastFailureNextRetryAt: isoFromMillis(row.last_failure_next_retry_at),\n sessionId: row.session_id ?? undefined,\n channelsEnabled: boolFromInteger(row.channels_enabled),\n supervisorEnabled: deliveryMethod === 'supervisor' ? true : undefined,\n deliveryMethod: deliveryMethod ?? undefined,\n hostOverride: hostOverrideFromRow(row.host_override),\n stoppedAt: isoFromMillis(row.stopped_at),\n pausedAt: isoFromMillis(row.paused_at),\n troubledAt: isoFromMillis(row.troubled_at),\n lastActivity: isoFromMillis(row.last_activity),\n lastFailureReason: row.last_failure_reason ?? undefined,\n phase: row.phase == null ? undefined : (row.phase as AgentState['phase']),\n roleRunHead: row.role_run_head ?? undefined,\n flywheelRunId: row.flywheel_run_id ?? undefined,\n costSoFar: row.cost_so_far ?? undefined,\n reviewSubRole: row.review_sub_role ?? undefined,\n reviewRunId: row.review_run_id ?? undefined,\n reviewSynthesisAgentId: row.review_synthesis_agent_id ?? undefined,\n reviewOutputPath: row.review_output_path ?? undefined,\n reviewDeadlineAt: isoFromMillis(row.review_deadline_at),\n reviewMonitorSignaled: (row.review_monitor_signaled ?? undefined) as AgentState['reviewMonitorSignaled'],\n reviewRetryAttempt: row.review_retry_attempt ?? undefined,\n };\n}\n\n/** Exported for agent-projection.ts transactional writes. */\nexport function stateToOverdeckParamsForDb(state: AgentState, updatedAt: number): unknown[] {\n const deliveryMethod = state.deliveryMethod ?? (state.supervisorEnabled === true ? 'supervisor' : null);\n return [\n state.id,\n state.issueId,\n state.role,\n state.status,\n state.workspace,\n state.sessionId ?? null,\n state.harness ?? '',\n state.model ?? '',\n hostOverrideToRow(state.hostOverride),\n deliveryMethod,\n millisFromIso(state.startedAt),\n millisFromIso(state.lastResumeAt),\n state.stoppedByUser == null ? null : (state.stoppedByUser ? 1 : 0),\n state.stoppedByPause == null ? null : (state.stoppedByPause ? 1 : 0),\n state.kickoffDelivered == null ? null : (state.kickoffDelivered ? 1 : 0),\n state.paused == null ? null : (state.paused ? 1 : 0),\n state.pausedReason ?? null,\n state.yieldedByScheduler == null ? null : (state.yieldedByScheduler ? 1 : 0),\n millisFromIso(state.yieldedAt),\n millisFromIso(state.lastYieldResumeAt),\n state.troubled == null ? null : (state.troubled ? 1 : 0),\n state.channelsEnabled == null ? null : (state.channelsEnabled ? 1 : 0),\n state.consecutiveFailures ?? null,\n millisFromIso(state.firstFailureInRunAt),\n millisFromIso(state.lastFailureNextRetryAt),\n millisFromIso(state.stoppedAt),\n millisFromIso(state.pausedAt),\n millisFromIso(state.troubledAt),\n millisFromIso(state.lastActivity),\n state.lastFailureReason ?? null,\n state.phase ?? null,\n state.roleRunHead ?? null,\n state.flywheelRunId ?? null,\n state.costSoFar ?? null,\n state.reviewSubRole ?? null,\n state.reviewRunId ?? null,\n state.reviewSynthesisAgentId ?? null,\n state.reviewOutputPath ?? null,\n millisFromIso(state.reviewDeadlineAt),\n state.reviewMonitorSignaled ?? null,\n state.reviewRetryAttempt ?? null,\n updatedAt,\n ];\n}\n\nexport function getOverdeckAgentStateSync(agentId: string): AgentState | null {\n const row = getOverdeckDatabaseSync()\n .prepare(`${SELECT_AGENT_SQL} WHERE id = ?`)\n .get(agentId) as OverdeckAgentRow | undefined;\n return row ? overdeckRowToAgentState(row) : null;\n}\n\nexport function listOverdeckAgentStatesSync(): AgentState[] {\n const rows = getOverdeckDatabaseSync()\n .prepare(SELECT_AGENT_SQL)\n .all() as OverdeckAgentRow[];\n return rows.map(overdeckRowToAgentState);\n}\n\nexport function saveOverdeckAgentStateSync(state: AgentState): void {\n const db = getOverdeckDatabaseSync();\n const updatedAt = Date.now();\n db.prepare(\n `INSERT OR IGNORE INTO issues (id, stage, updated_at) VALUES (?, 'working', ?)`,\n ).run(state.issueId, updatedAt);\n db.prepare(\n `INSERT OR REPLACE INTO agents (${AGENT_COLUMNS_FOR_DB.join(', ')}) VALUES (${AGENT_COLUMNS_FOR_DB.map(() => '?').join(', ')})`,\n ).run(...stateToOverdeckParamsForDb(state, updatedAt));\n}\n","import { Effect } from 'effect';\nimport type { ReviewStatus } from './review-status.js';\n\nexport function normalizeReviewStatusSync(status: ReviewStatus): ReviewStatus {\n const shouldClearMergeNotes = status.mergeStatus === 'verifying' || status.mergeStatus === 'merged';\n const shouldClearReadyForMerge =\n status.mergeStatus === 'merged' ||\n // PAN-1862 (FR-16): a skipped review (mode none) passes the gate like passed.\n (status.reviewStatus !== 'passed' && status.reviewStatus !== 'skipped') ||\n (status.testStatus !== 'passed' && status.testStatus !== 'skipped') ||\n (status.uatStatus !== undefined && status.uatStatus !== 'passed') ||\n ((status.blockerReasons?.length ?? 0) > 0);\n\n return {\n ...status,\n ...(shouldClearMergeNotes ? { mergeNotes: undefined } : {}),\n ...(shouldClearReadyForMerge ? { readyForMerge: false } : {}),\n };\n}\n\n// ─── Effect variants (PAN-1249) ───────────────────────────────────────────────\n\n/** Normalize a review status record (clear stale fields). Pure. */\nexport const normalizeReviewStatus = (\n status: ReviewStatus,\n): Effect.Effect<ReviewStatus> => Effect.sync(() => normalizeReviewStatusSync(status));\n","/**\n * Sync CRUD for review_status in overdeck.db.\n *\n * Mirrors the surface of database/review-status-db.ts but reads/writes\n * overdeck.db via getOverdeckDatabaseSync() instead of panopticon.db.\n *\n * The overdeck review_status table has the same column set as the old DB\n * (added in the 0000_overdeck_init.sql migration). status_history is shared\n * between the old and new domains — both tables exist in overdeck.db.\n */\nimport { Effect } from 'effect';\nimport type { BlockerReason, ReviewStatus, StatusHistoryEntry } from '../review-status.js';\nimport { normalizeReviewStatusSync } from '../review-status-normalize.js';\nimport { getOverdeckDatabaseSync } from './infra.js';\n\n// ── Timestamp helpers — overdeck stores timestamps as integer epoch-MILLISECONDS;\n// the ReviewStatus domain type exposes them as ISO strings, so convert at the\n// storage boundary (PAN-1961). ─────────────────────────────────────────────\nfunction isoToMs(value: string | null | undefined): number | null {\n if (!value) return null;\n const ms = Date.parse(value);\n return Number.isFinite(ms) ? ms : null;\n}\nfunction msToIso(value: number | null | undefined): string | undefined {\n return value == null ? undefined : new Date(value).toISOString();\n}\n\n// ── Internal row type ────────────────────────────────────────────────────────\n\ninterface DbRow {\n issue_id: string;\n review_status: string;\n test_status: string;\n merge_status: string | null;\n inspect_status: string | null;\n inspect_notes: string | null;\n inspect_started_at: number | null;\n inspect_bead_id: string | null;\n verification_status: string | null;\n verification_notes: string | null;\n verification_cycle_count: number | null;\n verification_max_cycles: number | null;\n review_notes: string | null;\n test_notes: string | null;\n merge_notes: string | null;\n updated_at: number;\n ready_for_merge: number;\n auto_requeue_count: number | null;\n merge_retry_count: number | null;\n pr_url: string | null;\n pr_head_sha: string | null;\n pr_number: number | null;\n stuck: number;\n stuck_reason: string | null;\n stuck_at: number | null;\n stuck_details: string | null;\n reviewed_at_commit: string | null;\n review_spawned_at: number | null;\n conflict_resolution_dispatched_at: number | null;\n test_retry_count: number | null;\n review_retry_count: number | null;\n recovery_started_at: number | null;\n deacon_ignored: number;\n deacon_ignored_at: number | null;\n deacon_ignored_reason: string | null;\n blocker_reasons: string | null;\n last_verified_commit: string | null;\n merge_step: string | null;\n auto_merge: number | null;\n}\n\nfunction rowToReviewStatus(row: DbRow, history: StatusHistoryEntry[]): ReviewStatus {\n return normalizeReviewStatusSync({\n issueId: row.issue_id.toUpperCase(),\n reviewStatus: row.review_status as ReviewStatus['reviewStatus'],\n testStatus: row.test_status as ReviewStatus['testStatus'],\n mergeStatus: (row.merge_status as ReviewStatus['mergeStatus']) ?? undefined,\n inspectStatus: (row.inspect_status as ReviewStatus['inspectStatus']) ?? undefined,\n inspectNotes: row.inspect_notes ?? undefined,\n inspectStartedAt: msToIso(row.inspect_started_at),\n inspectBeadId: row.inspect_bead_id ?? undefined,\n verificationStatus:\n (row.verification_status as ReviewStatus['verificationStatus']) ?? undefined,\n verificationNotes: row.verification_notes ?? undefined,\n verificationCycleCount: row.verification_cycle_count ?? undefined,\n verificationMaxCycles: row.verification_max_cycles ?? undefined,\n reviewNotes: row.review_notes ?? undefined,\n testNotes: row.test_notes ?? undefined,\n mergeNotes: row.merge_notes ?? undefined,\n updatedAt: msToIso(row.updated_at) ?? new Date(0).toISOString(),\n readyForMerge: row.ready_for_merge === 1,\n autoRequeueCount: row.auto_requeue_count ?? undefined,\n mergeRetryCount: row.merge_retry_count ?? undefined,\n prUrl: row.pr_url ?? undefined,\n prHeadSha: row.pr_head_sha ?? undefined,\n prNumber: row.pr_number ?? undefined,\n stuck: row.stuck === 1 ? true : undefined,\n stuckReason: row.stuck_reason ?? undefined,\n stuckAt: msToIso(row.stuck_at),\n stuckDetails: row.stuck_details ?? undefined,\n reviewedAtCommit: row.reviewed_at_commit ?? undefined,\n reviewSpawnedAt: msToIso(row.review_spawned_at),\n conflictResolutionDispatchedAt: msToIso(row.conflict_resolution_dispatched_at),\n testRetryCount: row.test_retry_count ?? undefined,\n reviewRetryCount: row.review_retry_count ?? undefined,\n recoveryStartedAt: msToIso(row.recovery_started_at),\n deaconIgnored: row.deacon_ignored === 1 ? true : undefined,\n deaconIgnoredAt: msToIso(row.deacon_ignored_at),\n deaconIgnoredReason: row.deacon_ignored_reason ?? undefined,\n blockerReasons: row.blocker_reasons\n ? (JSON.parse(row.blocker_reasons) as BlockerReason[])\n : undefined,\n lastVerifiedCommit: row.last_verified_commit ?? undefined,\n mergeStep: row.merge_step ?? undefined,\n autoMerge:\n row.auto_merge === null || row.auto_merge === undefined\n ? undefined\n : row.auto_merge === 1,\n history: history.length > 0 ? history : undefined,\n });\n}\n\nfunction getHistorySync(issueId: string): StatusHistoryEntry[] {\n const db = getOverdeckDatabaseSync();\n const rows = db\n .prepare(\n `SELECT type, status, timestamp, notes FROM status_history\n WHERE issue_id = ? ORDER BY timestamp ASC`,\n )\n .all(issueId.toUpperCase()) as Array<{\n type: string;\n status: string;\n timestamp: number;\n notes: string | null;\n }>;\n return rows.map((r) => ({\n type: r.type as StatusHistoryEntry['type'],\n status: r.status,\n timestamp: new Date(r.timestamp).toISOString(),\n ...(r.notes ? { notes: r.notes } : {}),\n }));\n}\n\n// ── Write operations ─────────────────────────────────────────────────────────\n\nexport function upsertReviewStatusSync(status: ReviewStatus): void {\n const db = getOverdeckDatabaseSync();\n const s = { ...status, issueId: status.issueId.toUpperCase() };\n\n const upsert = db.transaction(() => {\n // Ensure the issues row exists so status_history FK is satisfied.\n db.prepare(\n `INSERT OR IGNORE INTO issues (id, stage, updated_at) VALUES (?, 'working', ?)`,\n ).run(s.issueId, Date.now());\n\n db.prepare(`\n INSERT INTO review_status (\n issue_id, review_status, test_status, merge_status,\n inspect_status, inspect_notes, inspect_started_at, inspect_bead_id,\n verification_status, verification_notes,\n verification_cycle_count, verification_max_cycles,\n review_notes, test_notes, merge_notes,\n updated_at, ready_for_merge, auto_requeue_count, merge_retry_count, pr_url,\n pr_head_sha, pr_number,\n stuck, stuck_reason, stuck_at, stuck_details,\n reviewed_at_commit, review_spawned_at, conflict_resolution_dispatched_at,\n test_retry_count, review_retry_count, recovery_started_at,\n deacon_ignored, deacon_ignored_at, deacon_ignored_reason,\n blocker_reasons, last_verified_commit, merge_step, auto_merge\n ) VALUES (\n ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?\n )\n ON CONFLICT(issue_id) DO UPDATE SET\n review_status = excluded.review_status,\n test_status = excluded.test_status,\n merge_status = excluded.merge_status,\n inspect_status = excluded.inspect_status,\n inspect_notes = excluded.inspect_notes,\n inspect_started_at = excluded.inspect_started_at,\n inspect_bead_id = excluded.inspect_bead_id,\n verification_status = excluded.verification_status,\n verification_notes = excluded.verification_notes,\n verification_cycle_count = excluded.verification_cycle_count,\n verification_max_cycles = excluded.verification_max_cycles,\n review_notes = excluded.review_notes,\n test_notes = excluded.test_notes,\n merge_notes = excluded.merge_notes,\n updated_at = excluded.updated_at,\n ready_for_merge = excluded.ready_for_merge,\n auto_requeue_count = excluded.auto_requeue_count,\n merge_retry_count = excluded.merge_retry_count,\n pr_url = excluded.pr_url,\n pr_head_sha = excluded.pr_head_sha,\n pr_number = excluded.pr_number,\n stuck = excluded.stuck,\n stuck_reason = excluded.stuck_reason,\n stuck_at = excluded.stuck_at,\n stuck_details = excluded.stuck_details,\n reviewed_at_commit = excluded.reviewed_at_commit,\n review_spawned_at = excluded.review_spawned_at,\n conflict_resolution_dispatched_at = excluded.conflict_resolution_dispatched_at,\n test_retry_count = excluded.test_retry_count,\n review_retry_count = excluded.review_retry_count,\n recovery_started_at = excluded.recovery_started_at,\n deacon_ignored = excluded.deacon_ignored,\n deacon_ignored_at = excluded.deacon_ignored_at,\n deacon_ignored_reason = excluded.deacon_ignored_reason,\n blocker_reasons = excluded.blocker_reasons,\n last_verified_commit = excluded.last_verified_commit,\n merge_step = excluded.merge_step,\n auto_merge = excluded.auto_merge\n `).run(\n s.issueId,\n s.reviewStatus,\n s.testStatus,\n s.mergeStatus ?? null,\n s.inspectStatus ?? null,\n null, // inspect_notes — PAN-1988: feedback text lives in the journal, not the DB cache\n isoToMs(s.inspectStartedAt),\n s.inspectBeadId ?? null,\n s.verificationStatus ?? null,\n null, // verification_notes — PAN-1988: feedback text lives in the journal, not the DB cache\n s.verificationCycleCount ?? null,\n s.verificationMaxCycles ?? null,\n null, // review_notes — PAN-1988: feedback text lives in the journal, not the DB cache\n null, // test_notes — PAN-1988: journal-only\n null, // merge_notes — PAN-1988: journal-only\n isoToMs(s.updatedAt) ?? Date.now(),\n s.readyForMerge ? 1 : 0,\n s.autoRequeueCount ?? null,\n s.mergeRetryCount ?? null,\n s.prUrl ?? null,\n s.prHeadSha ?? null,\n s.prNumber ?? null,\n s.stuck ? 1 : 0,\n s.stuckReason ?? null,\n isoToMs(s.stuckAt),\n s.stuckDetails ?? null,\n s.reviewedAtCommit ?? null,\n isoToMs(s.reviewSpawnedAt),\n isoToMs(s.conflictResolutionDispatchedAt),\n s.testRetryCount ?? null,\n s.reviewRetryCount ?? null,\n isoToMs(s.recoveryStartedAt),\n s.deaconIgnored ? 1 : 0,\n isoToMs(s.deaconIgnoredAt),\n s.deaconIgnoredReason ?? null,\n s.blockerReasons ? JSON.stringify(s.blockerReasons) : null,\n s.lastVerifiedCommit ?? null,\n s.mergeStep ?? null,\n s.autoMerge === undefined ? null : s.autoMerge ? 1 : 0,\n );\n\n if (s.history && s.history.length > 0) {\n const insertHistory = db.prepare(\n `INSERT OR IGNORE INTO status_history (issue_id, type, status, timestamp, notes)\n VALUES (?, ?, ?, ?, ?)`,\n );\n for (const entry of s.history) {\n insertHistory.run(s.issueId, entry.type, entry.status, new Date(entry.timestamp).getTime(), entry.notes ?? null);\n }\n }\n });\n\n upsert();\n}\n\nexport function deleteReviewStatus(issueId: string): void {\n const db = getOverdeckDatabaseSync();\n db.prepare('DELETE FROM review_status WHERE issue_id = ?').run(issueId.toUpperCase());\n}\n\n// ── Read operations ──────────────────────────────────────────────────────────\n\nexport function getReviewStatusFromDbSync(issueId: string): ReviewStatus | null {\n const db = getOverdeckDatabaseSync();\n const normalizedId = issueId.toUpperCase();\n const row = db\n .prepare('SELECT * FROM review_status WHERE issue_id = ?')\n .get(normalizedId) as DbRow | undefined;\n if (!row) return null;\n return rowToReviewStatus(row, getHistorySync(normalizedId));\n}\n\nexport function getAllReviewStatusesFromDb(): Record<string, ReviewStatus> {\n const db = getOverdeckDatabaseSync();\n const rows = db\n .prepare('SELECT * FROM review_status ORDER BY updated_at DESC')\n .all() as DbRow[];\n\n const historyRows = db\n .prepare(\n `SELECT issue_id, type, status, timestamp, notes FROM status_history\n ORDER BY issue_id, timestamp ASC`,\n )\n .all() as Array<{\n issue_id: string;\n type: string;\n status: string;\n timestamp: string;\n notes: string | null;\n }>;\n\n const historyByIssue = new Map<string, StatusHistoryEntry[]>();\n for (const row of historyRows) {\n const bucket = historyByIssue.get(row.issue_id) ?? [];\n bucket.push({\n type: row.type as StatusHistoryEntry['type'],\n status: row.status,\n timestamp: row.timestamp,\n ...(row.notes ? { notes: row.notes } : {}),\n });\n historyByIssue.set(row.issue_id, bucket);\n }\n\n const result: Record<string, ReviewStatus> = {};\n for (const row of rows) {\n result[row.issue_id] = rowToReviewStatus(row, historyByIssue.get(row.issue_id) ?? []);\n }\n return result;\n}\n\nexport function getReviewStatusesFromDb(issueIds: string[]): Record<string, ReviewStatus> {\n const normalizedIds = [...new Set(issueIds.map((id) => id.toUpperCase()).filter(Boolean))];\n if (normalizedIds.length === 0) return {};\n const db = getOverdeckDatabaseSync();\n const placeholders = normalizedIds.map(() => '?').join(', ');\n\n const rows = db\n .prepare(\n `SELECT * FROM review_status WHERE issue_id IN (${placeholders}) ORDER BY updated_at DESC`,\n )\n .all(...normalizedIds) as DbRow[];\n if (rows.length === 0) return {};\n\n const historyRows = db\n .prepare(\n `SELECT issue_id, type, status, timestamp, notes FROM status_history\n WHERE issue_id IN (${placeholders}) ORDER BY issue_id, timestamp ASC`,\n )\n .all(...normalizedIds) as Array<{\n issue_id: string;\n type: string;\n status: string;\n timestamp: string;\n notes: string | null;\n }>;\n\n const historyByIssue = new Map<string, StatusHistoryEntry[]>();\n for (const row of historyRows) {\n const bucket = historyByIssue.get(row.issue_id) ?? [];\n bucket.push({\n type: row.type as StatusHistoryEntry['type'],\n status: row.status,\n timestamp: row.timestamp,\n ...(row.notes ? { notes: row.notes } : {}),\n });\n historyByIssue.set(row.issue_id, bucket);\n }\n\n const result: Record<string, ReviewStatus> = {};\n for (const row of rows) {\n result[row.issue_id] = rowToReviewStatus(row, historyByIssue.get(row.issue_id) ?? []);\n }\n return result;\n}\n\n// ── Stuck state helpers ──────────────────────────────────────────────────────\n\nexport function markWorkspaceStuck(\n issueId: string,\n reason: string,\n details?: Record<string, unknown>,\n): void {\n const db = getOverdeckDatabaseSync();\n const now = Date.now();\n const detailsJson = details ? JSON.stringify(details) : null;\n db.prepare(`\n INSERT OR IGNORE INTO review_status\n (issue_id, review_status, test_status, updated_at, ready_for_merge,\n stuck, stuck_reason, stuck_at, stuck_details)\n VALUES (?, 'pending', 'pending', ?, 0, 1, ?, ?, ?)\n `).run(issueId.toUpperCase(), now, reason, now, detailsJson);\n db.prepare(`\n UPDATE review_status\n SET stuck = 1, stuck_reason = ?, stuck_at = ?, stuck_details = ?, updated_at = ?\n WHERE issue_id = ?\n `).run(reason, now, detailsJson, now, issueId.toUpperCase());\n}\n\nexport function clearWorkspaceStuck(issueId: string): void {\n const db = getOverdeckDatabaseSync();\n const now = Date.now();\n db.prepare(`\n UPDATE review_status\n SET stuck = 0, stuck_reason = NULL, stuck_at = NULL, stuck_details = NULL, updated_at = ?\n WHERE issue_id = ?\n `).run(now, issueId.toUpperCase());\n}\n\nexport function setDeaconIgnored(\n issueId: string,\n ignored: boolean,\n reason?: string,\n): void {\n const db = getOverdeckDatabaseSync();\n const now = Date.now();\n db.prepare(`\n INSERT OR IGNORE INTO review_status\n (issue_id, review_status, test_status, updated_at, ready_for_merge, deacon_ignored)\n VALUES (?, 'pending', 'pending', ?, 0, 0)\n `).run(issueId.toUpperCase(), now);\n db.prepare(`\n UPDATE review_status\n SET deacon_ignored = ?, deacon_ignored_at = ?, deacon_ignored_reason = ?, updated_at = ?\n WHERE issue_id = ?\n `).run(ignored ? 1 : 0, ignored ? now : null, reason ?? null, now, issueId.toUpperCase());\n}\n\nexport function setAutoMerge(issueId: string, autoMerge: boolean | null): void {\n const db = getOverdeckDatabaseSync();\n const now = Date.now();\n db.prepare(`\n INSERT OR IGNORE INTO review_status\n (issue_id, review_status, test_status, updated_at, ready_for_merge)\n VALUES (?, 'pending', 'pending', ?, 0)\n `).run(issueId.toUpperCase(), now);\n db.prepare(`\n UPDATE review_status SET auto_merge = ?, updated_at = ? WHERE issue_id = ?\n `).run(\n autoMerge === null ? null : autoMerge ? 1 : 0,\n now,\n issueId.toUpperCase(),\n );\n}\n\n// ── Merge-blocker reconcile candidates ───────────────────────────────────────\n\nexport interface MergeBlockerReconcileCandidate {\n issueId: string;\n prUrl: string | undefined;\n blockerReasons: BlockerReason[] | undefined;\n readyForMerge: boolean;\n}\n\n/**\n * Sync query for merge-blocker reconcile service.\n * Drop-in for getMergeBlockerReconcileCandidatesSync() from review-status-db.ts.\n */\nexport function getMergeBlockerReconcileCandidatesSync(): MergeBlockerReconcileCandidate[] {\n const db = getOverdeckDatabaseSync();\n const rows = db.prepare(`\n SELECT issue_id, pr_url, blocker_reasons, ready_for_merge\n FROM review_status\n WHERE ready_for_merge = 1\n OR blocker_reasons LIKE '%merge_conflict%'\n OR blocker_reasons LIKE '%not_mergeable%'\n `).all() as Array<{\n issue_id: string;\n pr_url: string | null;\n blocker_reasons: string | null;\n ready_for_merge: number;\n }>;\n\n return rows.map((row) => ({\n issueId: row.issue_id.toUpperCase(),\n prUrl: row.pr_url ?? undefined,\n blockerReasons: row.blocker_reasons ? JSON.parse(row.blocker_reasons) : undefined,\n readyForMerge: row.ready_for_merge === 1,\n }));\n}\n\n/**\n * Effect wrapper for getMergeBlockerReconcileCandidatesSync.\n * Drop-in for getMergeBlockerReconcileCandidates() from review-status-db.ts.\n */\nexport const getMergeBlockerReconcileCandidates = (): Effect.Effect<MergeBlockerReconcileCandidate[]> =>\n Effect.promise(() =>\n new Promise<MergeBlockerReconcileCandidate[]>((resolve, reject) => {\n setImmediate(() => {\n try {\n resolve(getMergeBlockerReconcileCandidatesSync());\n } catch (err) {\n reject(err);\n }\n });\n }),\n );\n","const issueRecordLocks = new Map<string, Promise<void>>();\n\n/**\n * Serialize async read-modify-write rebuilds for a single issue record.\n *\n * Synchronous record writers remain synchronous; async flows that read, await,\n * then write the whole record must use this lock so same-issue rebuilds cannot\n * overwrite each other's final re-read.\n */\nexport async function withIssueRecordLock<T>(\n issueId: string,\n fn: () => T | Promise<T>,\n): Promise<T> {\n const key = issueId.toUpperCase();\n const previous = issueRecordLocks.get(key) ?? Promise.resolve();\n let release: () => void = () => {};\n const current = new Promise<void>((resolve) => {\n release = resolve;\n });\n const chain = previous.catch(() => undefined).then(() => current);\n issueRecordLocks.set(key, chain);\n\n await previous.catch(() => undefined);\n\n try {\n return await fn();\n } finally {\n release();\n if (issueRecordLocks.get(key) === chain) {\n issueRecordLocks.delete(key);\n }\n }\n}\n","/**\n * PAN-1908 / PAN-1919: per-issue permanent-record builder.\n *\n * Builds a single JSON record per issue from SQLite (pipeline verdicts, usage,\n * merges) plus the legacy project-side continue file. The actual read/write/path\n * helpers live in `record.ts` (PAN-1919 single-writer module) and write the\n * record onto the feature branch at `<workspace>/.pan/records/<issue>.json`.\n */\n\nimport { hostname } from 'node:os';\nimport { join } from 'node:path';\nimport { existsSync, promises as fsp } from 'node:fs';\nimport { PAN_CONTINUES_DIRNAME, PAN_DIRNAME } from './types.js';\n\n// ─── Types ────────────────────────────────────────────────────────────────────\nimport {\n getCostBreakdownByStageAndModelSync,\n getCostForIssueSync,\n} from '../overdeck/cost-sync.js';\nimport { getMergeSetSync } from '../merge-set.js';\nimport {\n getProjectSync,\n resolveProjectFromIssueSync,\n type ProjectConfig,\n} from '../projects.js';\nimport type { ReviewStatus } from '../review-status.js';\nimport type { RuntimeName } from '../runtimes/types.js';\nimport type {\n ContinueBeadsMapping,\n ContinueDecision,\n ContinueFeedbackEntry,\n ContinueHazard,\n ContinueResumePoint,\n ContinueSessionEntry,\n ScopeDriftRecord,\n} from '../vbrief/continue-state.js';\nimport { listOverdeckAgentStatesSync } from '../overdeck/agent-state-sync.js';\nimport {\n getIssueWorkspacePath,\n queueIssueRecordCommit,\n RECORD_SCHEMA_VERSION,\n readIssueRecord,\n readIssueRecordSync,\n writeIssueRecordSync,\n type PanIssueRecord,\n type PanIssuePipelineRecord,\n type PanIssueUsageRecord,\n} from './record.js';\nimport { withIssueRecordLock } from './record-lock.js';\n\nexport type {\n PanIssueRecord,\n PanIssueCloseOutRecord,\n PanIssuePipelineRecord,\n PanIssueUsageRecord,\n} from './record.js';\n\n// ─── Continue projection ──────────────────────────────────────────────────────\n\ninterface ContinueFile {\n issueId?: string;\n gitState?: { branch?: string };\n decisions?: ContinueDecision[];\n hazards?: ContinueHazard[];\n resumePoint?: ContinueResumePoint | null;\n beadsMapping?: ContinueBeadsMapping;\n sessionHistory?: ContinueSessionEntry[];\n feedback?: ContinueFeedbackEntry[];\n agentModel?: string;\n scopeDrift?: ScopeDriftRecord;\n}\n\nfunction projectContinue(raw: ContinueFile | null): Pick<PanIssueRecord, 'decisions' | 'hazards' | 'resumePoint' | 'beadsMapping' | 'sessionHistory' | 'feedback' | 'scopeDrift'> {\n return {\n decisions: raw?.decisions,\n hazards: raw?.hazards,\n resumePoint: raw?.resumePoint,\n beadsMapping: raw?.beadsMapping,\n sessionHistory: raw?.sessionHistory,\n feedback: raw?.feedback ?? [],\n scopeDrift: raw?.scopeDrift,\n };\n}\n\n// ─── Pipeline projection ──────────────────────────────────────────────────────\n\nfunction projectPipeline(\n issueId: string,\n status: ReviewStatus | null,\n existing?: PanIssuePipelineRecord,\n): PanIssuePipelineRecord {\n const base: PanIssuePipelineRecord = {\n issueId,\n reviewStatus: status?.reviewStatus ?? 'pending',\n testStatus: status?.testStatus ?? 'pending',\n verificationStatus: status?.verificationStatus,\n inspectStatus: status?.inspectStatus,\n mergeStatus: status?.mergeStatus,\n readyForMerge: status?.readyForMerge ?? false,\n closedOut: existing?.closedOut,\n closedOutAt: existing?.closedOutAt,\n updatedAt: status?.updatedAt ?? new Date().toISOString(),\n };\n\n if (!status) return base;\n\n return {\n ...base,\n reviewNotes: status.reviewNotes,\n testNotes: status.testNotes,\n verificationNotes: status.verificationNotes,\n inspectNotes: status.inspectNotes,\n mergeNotes: status.mergeNotes,\n blockerReasons: status.blockerReasons,\n prUrl: status.prUrl,\n prNumber: status.prNumber,\n prHeadSha: status.prHeadSha,\n reviewedAtCommit: status.reviewedAtCommit,\n lastVerifiedCommit: status.lastVerifiedCommit,\n reviewRequestedAt: status.reviewRequestedAt,\n scopeDrift: status.scopeDrift,\n autoMerge: status.autoMerge,\n deaconIgnored: status.deaconIgnored,\n deaconIgnoredAt: status.deaconIgnoredAt,\n deaconIgnoredReason: status.deaconIgnoredReason,\n reviewerVerdicts: (status as { reviewerVerdicts?: unknown }).reviewerVerdicts,\n };\n}\n\n// ─── Usage projection ─────────────────────────────────────────────────────────\n\nfunction projectUsage(issueId: string): PanIssueUsageRecord {\n const { byStage, totals } = getCostBreakdownByStageAndModelSync(issueId);\n const aggregate = getCostForIssueSync(issueId);\n\n return {\n byStage,\n totals,\n costAtCloseOut: {\n usd: aggregate?.totalCost ?? 0,\n pricingAsOf: new Date().toISOString(),\n },\n };\n}\n\n// ─── Merge projection ─────────────────────────────────────────────────────────\n\nfunction projectMerges(issueId: string): string[] {\n const mergeSet = getMergeSetSync(issueId);\n if (!mergeSet) return [];\n return mergeSet.repos\n .map(r => r.artifactUrl)\n .filter((url): url is string => typeof url === 'string' && url.length > 0);\n}\n\n// ─── Record builder ───────────────────────────────────────────────────────────\n\nasync function readLegacyContinueText(projectRoot: string, issueId: string): Promise<string | null> {\n const path = join(projectRoot, PAN_DIRNAME, PAN_CONTINUES_DIRNAME, `${issueId.toLowerCase()}.vbrief.json`);\n try {\n return await fsp.readFile(path, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/** Read workspace continue.json and return its statusOverrides (if any). */\nasync function readWorkspaceContinueStatusOverrides(issueId: string): Promise<Record<string, string> | undefined> {\n const workspacePath = getIssueWorkspacePath(issueId);\n if (!workspacePath || !existsSync(workspacePath)) return undefined;\n const continuePath = join(workspacePath, '.pan', 'continue.json');\n try {\n const text = await fsp.readFile(continuePath, 'utf-8');\n const parsed = JSON.parse(text) as { statusOverrides?: Record<string, string> };\n return parsed.statusOverrides ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Read harness/model for an issue from the overdeck agents table (most recent work agent). */\nfunction projectAgentHarnessModel(issueId: string): { harness?: RuntimeName; model?: string } {\n try {\n const agents = listOverdeckAgentStatesSync().filter(\n (a) => a.issueId?.toUpperCase() === issueId.toUpperCase(),\n );\n const workAgent =\n agents\n .filter((a) => a.role === 'work')\n .sort((a, b) => (b.startedAt ?? '').localeCompare(a.startedAt ?? ''))[0]\n ?? agents[agents.length - 1];\n return {\n harness: workAgent?.harness,\n model: workAgent?.model ?? undefined,\n };\n } catch {\n return {};\n }\n}\n\nexport interface BuildIssueRecordOptions {\n closedAt?: string;\n owner?: string;\n reviewStatus?: ReviewStatus | null;\n}\n\nexport async function buildIssueRecord(\n project: ProjectConfig,\n issueId: string,\n opts: BuildIssueRecordOptions = {},\n): Promise<PanIssueRecord> {\n const existing = await readIssueRecord(project, issueId);\n const legacyContinueText = await readLegacyContinueText(project.path, issueId);\n const continueSubset = projectContinue(legacyContinueText ? (JSON.parse(legacyContinueText) as ContinueFile) : null);\n const pipelineRecord = projectPipeline(issueId, opts.reviewStatus ?? null, existing?.pipeline);\n const usageRecord = projectUsage(issueId);\n const merges = projectMerges(issueId);\n\n // PAN-1919: fold workspace continue statusOverrides; fall back to existing.\n const workspaceStatusOverrides = await readWorkspaceContinueStatusOverrides(issueId);\n const mergedStatusOverrides = workspaceStatusOverrides\n ? { ...(existing?.statusOverrides ?? {}), ...workspaceStatusOverrides }\n : existing?.statusOverrides;\n\n // PAN-1919: harness/model from existing record, then agents table as fallback.\n const agentHM = existing?.harness || existing?.model\n ? { harness: existing.harness, model: existing.model }\n : projectAgentHarnessModel(issueId);\n\n return {\n issueId: issueId.toUpperCase(),\n schemaVersion: RECORD_SCHEMA_VERSION,\n ...continueSubset,\n ...existing,\n harness: agentHM.harness,\n model: agentHM.model,\n statusOverrides: mergedStatusOverrides,\n pipeline: pipelineRecord,\n closeOut: {\n usage: usageRecord,\n merges,\n ranOn: hostname(),\n closedAt: opts.closedAt,\n },\n owner: opts.owner ?? existing?.owner,\n };\n}\n\n// Re-export core record I/O from the PAN-1919 single-writer module.\nexport {\n getIssueRecordPath,\n markRecordPipelineClosedOutSync,\n writeIssueRecordSync,\n readIssueRecord,\n queueIssueRecordCommit,\n} from './record.js';\n\n// ─── Owner-URI lease (PAN-1908, CP-3) ─────────────────────────────────────────\n\nexport {\n buildOwnUri,\n claimIssueOwner,\n clearIssueOwner,\n type ClaimResult,\n} from './record.js';\n\n/**\n * PAN-2587: never regress the pipeline block during a whole-record rebuild. A\n * concurrent writer (e.g. a reviewer's verdict landing between the rebuild's\n * `existing` snapshot and its write) may have put a NEWER pipeline on disk than\n * the status the rebuild projects — observed clobbering PAN-399's passed\n * verdict back to a pre-verdict snapshot. Same newer-wins rule (ISO `updatedAt`\n * comparison) the journal readers use.\n */\nexport function pickNewerPipeline(\n rebuilt: PanIssuePipelineRecord,\n fresh: PanIssuePipelineRecord | undefined,\n): PanIssuePipelineRecord {\n if (!fresh?.updatedAt || !rebuilt?.updatedAt) return rebuilt;\n return rebuilt.updatedAt < fresh.updatedAt ? fresh : rebuilt;\n}\n\n/**\n * PAN-1908 / PAN-1919: rebuild and queue the per-issue permanent record for a\n * given issue. Fire-and-forget: failures are logged, never thrown, so\n * review-status writes stay synchronous and fast.\n *\n * PAN-2583: returns whether the durable write actually landed, so the caller\n * can fall back to a sandbox-writable verdict drop when it did not (a sandboxed\n * reviewer cannot write ${OVERDECK_HOME}/state, and swallowing that here was\n * how blocked review verdicts silently vanished).\n */\nexport async function updateIssueRecordForIssue(\n issueId: string,\n reviewStatus?: ReviewStatus | null,\n): Promise<boolean> {\n try {\n const resolved = resolveProjectFromIssueSync(issueId);\n if (!resolved) return false;\n const project = getProjectSync(resolved.projectKey);\n if (!project) return false;\n\n await withIssueRecordLock(issueId, async () => {\n const record = await buildIssueRecord(project, issueId, { reviewStatus });\n // buildIssueRecord's `existing` snapshot is read at the top of several awaits;\n // anything written to the record during that window would be erased by this\n // whole-record write (lost update). Observed twice on PAN-1791: wiped swarm\n // slot assignments during the runaway, then wiped item statusOverrides right\n // after `pan done` — which made every completed item dispatchable again and\n // re-spawned slots for finished work. Re-read both blocks synchronously\n // immediately before writing so the freshest values survive the rebuild.\n const fresh = readIssueRecordSync(project, issueId);\n if (fresh?.swarm) record.swarm = fresh.swarm;\n if (fresh?.statusOverrides && Object.keys(fresh.statusOverrides).length > 0) {\n record.statusOverrides = { ...record.statusOverrides, ...fresh.statusOverrides };\n }\n record.pipeline = pickNewerPipeline(record.pipeline, fresh?.pipeline);\n const recordPath = writeIssueRecordSync(project, issueId, record);\n queueIssueRecordCommit(project, issueId, recordPath);\n });\n return true;\n } catch (err) {\n console.warn(`[pan-dir/records] Failed to update record for ${issueId}: ${(err as Error).message}`);\n return false;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { t as backfillIssueRecords } from "./records-backfill-BrNsv_zT.js";
2
+ export { backfillIssueRecords };
@@ -1,6 +1,6 @@
1
1
  import { A as resolveProjectFromIssueSync, O as resolveInfraRepo, f as getProjectSync, v as init_projects, w as loadProjectsConfigSync } from "./projects-D2nMJ9C4.js";
2
2
  import { d as queueIssueRecordCommit, f as readIssueRecord, y as writeIssueRecordSync } from "./record-osVNNpoC.js";
3
- import { _ as listOverdeckAgentStatesSync, a as withIssueRecordLock, g as init_agent_state_sync, i as init_record_lock, n as init_records, s as getAllReviewStatusesFromDb, t as buildIssueRecord, u as init_review_status_sync } from "./records-BIkN1LQ4.js";
3
+ import { _ as listOverdeckAgentStatesSync, a as withIssueRecordLock, g as init_agent_state_sync, i as init_record_lock, n as init_records, s as getAllReviewStatusesFromDb, t as buildIssueRecord, u as init_review_status_sync } from "./records-CTmvuRzz.js";
4
4
  import { existsSync } from "node:fs";
5
5
  import { join } from "node:path";
6
6
  import { readdir } from "node:fs/promises";
@@ -146,4 +146,4 @@ async function backfillIssueRecords(options = {}) {
146
146
  //#endregion
147
147
  export { collectInFlightIssueIds as n, backfillIssueRecords as t };
148
148
 
149
- //# sourceMappingURL=records-backfill-HM0Pln6N.js.map
149
+ //# sourceMappingURL=records-backfill-BrNsv_zT.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"records-backfill-HM0Pln6N.js","names":[],"sources":["../src/lib/pan-dir/records-backfill.ts"],"sourcesContent":["/**\n * PAN-1908: one-time backfill of per-issue permanent records.\n *\n * Builds a record for every in-flight issue (anything with a review_status\n * row, an agents-table row, or a `.pan/continues/<issue>.vbrief.json` file)\n * and writes it into the declared infra repo. Re-running is safe: records\n * whose content has not changed are skipped, and unchanged commits are\n * suppressed by the auto-commit diff check.\n */\n\nimport { existsSync } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { listOverdeckAgentStatesSync } from '../overdeck/agent-state-sync.js';\nimport { getAllReviewStatusesFromDb } from '../overdeck/review-status-sync.js';\nimport {\n getProjectSync,\n loadProjectsConfigSync,\n resolveInfraRepo,\n resolveProjectFromIssueSync,\n type ProjectConfig,\n} from '../projects.js';\nimport {\n buildIssueRecord,\n getIssueRecordPath,\n queueIssueRecordCommit,\n readIssueRecord,\n writeIssueRecordSync,\n type PanIssueRecord,\n} from './records.js';\nimport { withIssueRecordLock } from './record-lock.js';\n\nexport interface BackfillRecordsResult {\n processed: number;\n skipped: number;\n failed: number;\n details: Array<{ issueId: string; action: 'written' | 'skipped' | 'failed'; reason?: string }>;\n}\n\nexport interface BackfillRecordsOptions {\n /** If provided, only backfill this issue. */\n issueId?: string;\n /** Log each processed issue. */\n verbose?: boolean;\n /** Force overwrite even if the record is unchanged. */\n force?: boolean;\n}\n\nfunction getProjectRoot(project: ProjectConfig): string {\n return project.path;\n}\n\nasync function collectContinueIssueIds(project: ProjectConfig): Promise<Set<string>> {\n const ids = new Set<string>();\n const continuesDir = join(getProjectRoot(project), '.pan', 'continues');\n if (!existsSync(continuesDir)) return ids;\n\n try {\n const entries = await readdir(continuesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n const match = entry.name.match(/^([a-z0-9]+-\\d+)\\.vbrief\\.json$/i);\n if (!match) continue;\n ids.add(match[1].toUpperCase());\n }\n } catch {\n // Directory may be unreadable; skip.\n }\n return ids;\n}\n\nfunction collectAgentIssueIds(): Set<string> {\n const ids = new Set<string>();\n try {\n for (const agent of listOverdeckAgentStatesSync()) {\n if (agent.issueId) ids.add(agent.issueId.toUpperCase());\n }\n } catch {\n // Agents table may not exist on very old dbs; skip.\n }\n return ids;\n}\n\nfunction collectReviewStatusIssueIds(): Set<string> {\n const ids = new Set<string>();\n try {\n const statuses = getAllReviewStatusesFromDb();\n for (const issueId of Object.keys(statuses)) {\n ids.add(issueId.toUpperCase());\n }\n } catch {\n // review_status table may not exist; skip.\n }\n return ids;\n}\n\nexport async function collectInFlightIssueIds(projects: ProjectConfig[]): Promise<Set<string>> {\n const ids = collectAgentIssueIds();\n for (const id of collectReviewStatusIssueIds()) ids.add(id);\n\n for (const project of projects) {\n for (const id of await collectContinueIssueIds(project)) ids.add(id);\n }\n\n return ids;\n}\n\nfunction normalizeRecordForCompare(record: PanIssueRecord): string {\n // Several fields are build metadata rather than durable state and move on\n // every build: usage pricing, pipeline.updatedAt, closeOut.closedAt, etc.\n // Exclude them from idempotency comparison so unchanged issues don't churn.\n const { closeOut, pipeline, ...rest } = record;\n const normalized = {\n ...rest,\n pipeline: pipeline\n ? {\n ...pipeline,\n updatedAt: undefined,\n }\n : undefined,\n closeOut: closeOut\n ? {\n ...closeOut,\n closedAt: undefined,\n usage: closeOut.usage\n ? {\n byStage: closeOut.usage.byStage,\n totals: closeOut.usage.totals,\n }\n : undefined,\n }\n : undefined,\n };\n return JSON.stringify(normalized);\n}\n\nasync function backfillIssue(\n issueId: string,\n opts: BackfillRecordsOptions,\n): Promise<{ action: 'written' | 'skipped' | 'failed'; reason?: string }> {\n const resolved = resolveProjectFromIssueSync(issueId);\n if (!resolved) {\n return { action: 'failed', reason: 'could not resolve project' };\n }\n\n const project = getProjectSync(resolved.projectKey);\n if (!project) {\n return { action: 'failed', reason: 'project not found' };\n }\n\n try {\n const { repoPath } = resolveInfraRepo(project);\n if (!existsSync(join(repoPath, '.git'))) {\n return { action: 'failed', reason: 'infra repo is not a git checkout' };\n }\n\n return await withIssueRecordLock(issueId, async () => {\n const existing = await readIssueRecord(project, issueId);\n const reviewStatus = getAllReviewStatusesFromDb()[issueId.toUpperCase()] ?? null;\n const record = await buildIssueRecord(project, issueId, { reviewStatus });\n\n if (!opts.force && existing && normalizeRecordForCompare(existing) === normalizeRecordForCompare(record)) {\n return { action: 'skipped', reason: 'record unchanged' };\n }\n\n const recordPath = writeIssueRecordSync(project, issueId, record);\n queueIssueRecordCommit(project, issueId, recordPath);\n return { action: 'written' };\n });\n } catch (err) {\n return { action: 'failed', reason: (err as Error).message };\n }\n}\n\n/**\n * Backfill per-issue permanent records for all in-flight issues.\n */\nexport async function backfillIssueRecords(\n options: BackfillRecordsOptions = {},\n): Promise<BackfillRecordsResult> {\n const config = loadProjectsConfigSync();\n const projects = Object.entries(config.projects).map(([key, p]) => ({ ...p, key }));\n\n let issueIds: Set<string>;\n if (options.issueId) {\n issueIds = new Set([options.issueId.toUpperCase()]);\n } else {\n issueIds = await collectInFlightIssueIds(projects);\n }\n\n const result: BackfillRecordsResult = {\n processed: 0,\n skipped: 0,\n failed: 0,\n details: [],\n };\n\n for (const issueId of issueIds) {\n if (options.verbose) {\n console.log(`[records-backfill] ${issueId} ...`);\n }\n\n const outcome = await backfillIssue(issueId, options);\n result.details.push({ issueId, ...outcome });\n\n if (outcome.action === 'written') result.processed++;\n else if (outcome.action === 'skipped') result.skipped++;\n else result.failed++;\n\n if (options.verbose) {\n console.log(`[records-backfill] ${issueId} -> ${outcome.action}${outcome.reason ? ` (${outcome.reason})` : ''}`);\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"records-backfill-BrNsv_zT.js","names":[],"sources":["../src/lib/pan-dir/records-backfill.ts"],"sourcesContent":["/**\n * PAN-1908: one-time backfill of per-issue permanent records.\n *\n * Builds a record for every in-flight issue (anything with a review_status\n * row, an agents-table row, or a `.pan/continues/<issue>.vbrief.json` file)\n * and writes it into the declared infra repo. Re-running is safe: records\n * whose content has not changed are skipped, and unchanged commits are\n * suppressed by the auto-commit diff check.\n */\n\nimport { existsSync } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { listOverdeckAgentStatesSync } from '../overdeck/agent-state-sync.js';\nimport { getAllReviewStatusesFromDb } from '../overdeck/review-status-sync.js';\nimport {\n getProjectSync,\n loadProjectsConfigSync,\n resolveInfraRepo,\n resolveProjectFromIssueSync,\n type ProjectConfig,\n} from '../projects.js';\nimport {\n buildIssueRecord,\n getIssueRecordPath,\n queueIssueRecordCommit,\n readIssueRecord,\n writeIssueRecordSync,\n type PanIssueRecord,\n} from './records.js';\nimport { withIssueRecordLock } from './record-lock.js';\n\nexport interface BackfillRecordsResult {\n processed: number;\n skipped: number;\n failed: number;\n details: Array<{ issueId: string; action: 'written' | 'skipped' | 'failed'; reason?: string }>;\n}\n\nexport interface BackfillRecordsOptions {\n /** If provided, only backfill this issue. */\n issueId?: string;\n /** Log each processed issue. */\n verbose?: boolean;\n /** Force overwrite even if the record is unchanged. */\n force?: boolean;\n}\n\nfunction getProjectRoot(project: ProjectConfig): string {\n return project.path;\n}\n\nasync function collectContinueIssueIds(project: ProjectConfig): Promise<Set<string>> {\n const ids = new Set<string>();\n const continuesDir = join(getProjectRoot(project), '.pan', 'continues');\n if (!existsSync(continuesDir)) return ids;\n\n try {\n const entries = await readdir(continuesDir, { withFileTypes: true });\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n const match = entry.name.match(/^([a-z0-9]+-\\d+)\\.vbrief\\.json$/i);\n if (!match) continue;\n ids.add(match[1].toUpperCase());\n }\n } catch {\n // Directory may be unreadable; skip.\n }\n return ids;\n}\n\nfunction collectAgentIssueIds(): Set<string> {\n const ids = new Set<string>();\n try {\n for (const agent of listOverdeckAgentStatesSync()) {\n if (agent.issueId) ids.add(agent.issueId.toUpperCase());\n }\n } catch {\n // Agents table may not exist on very old dbs; skip.\n }\n return ids;\n}\n\nfunction collectReviewStatusIssueIds(): Set<string> {\n const ids = new Set<string>();\n try {\n const statuses = getAllReviewStatusesFromDb();\n for (const issueId of Object.keys(statuses)) {\n ids.add(issueId.toUpperCase());\n }\n } catch {\n // review_status table may not exist; skip.\n }\n return ids;\n}\n\nexport async function collectInFlightIssueIds(projects: ProjectConfig[]): Promise<Set<string>> {\n const ids = collectAgentIssueIds();\n for (const id of collectReviewStatusIssueIds()) ids.add(id);\n\n for (const project of projects) {\n for (const id of await collectContinueIssueIds(project)) ids.add(id);\n }\n\n return ids;\n}\n\nfunction normalizeRecordForCompare(record: PanIssueRecord): string {\n // Several fields are build metadata rather than durable state and move on\n // every build: usage pricing, pipeline.updatedAt, closeOut.closedAt, etc.\n // Exclude them from idempotency comparison so unchanged issues don't churn.\n const { closeOut, pipeline, ...rest } = record;\n const normalized = {\n ...rest,\n pipeline: pipeline\n ? {\n ...pipeline,\n updatedAt: undefined,\n }\n : undefined,\n closeOut: closeOut\n ? {\n ...closeOut,\n closedAt: undefined,\n usage: closeOut.usage\n ? {\n byStage: closeOut.usage.byStage,\n totals: closeOut.usage.totals,\n }\n : undefined,\n }\n : undefined,\n };\n return JSON.stringify(normalized);\n}\n\nasync function backfillIssue(\n issueId: string,\n opts: BackfillRecordsOptions,\n): Promise<{ action: 'written' | 'skipped' | 'failed'; reason?: string }> {\n const resolved = resolveProjectFromIssueSync(issueId);\n if (!resolved) {\n return { action: 'failed', reason: 'could not resolve project' };\n }\n\n const project = getProjectSync(resolved.projectKey);\n if (!project) {\n return { action: 'failed', reason: 'project not found' };\n }\n\n try {\n const { repoPath } = resolveInfraRepo(project);\n if (!existsSync(join(repoPath, '.git'))) {\n return { action: 'failed', reason: 'infra repo is not a git checkout' };\n }\n\n return await withIssueRecordLock(issueId, async () => {\n const existing = await readIssueRecord(project, issueId);\n const reviewStatus = getAllReviewStatusesFromDb()[issueId.toUpperCase()] ?? null;\n const record = await buildIssueRecord(project, issueId, { reviewStatus });\n\n if (!opts.force && existing && normalizeRecordForCompare(existing) === normalizeRecordForCompare(record)) {\n return { action: 'skipped', reason: 'record unchanged' };\n }\n\n const recordPath = writeIssueRecordSync(project, issueId, record);\n queueIssueRecordCommit(project, issueId, recordPath);\n return { action: 'written' };\n });\n } catch (err) {\n return { action: 'failed', reason: (err as Error).message };\n }\n}\n\n/**\n * Backfill per-issue permanent records for all in-flight issues.\n */\nexport async function backfillIssueRecords(\n options: BackfillRecordsOptions = {},\n): Promise<BackfillRecordsResult> {\n const config = loadProjectsConfigSync();\n const projects = Object.entries(config.projects).map(([key, p]) => ({ ...p, key }));\n\n let issueIds: Set<string>;\n if (options.issueId) {\n issueIds = new Set([options.issueId.toUpperCase()]);\n } else {\n issueIds = await collectInFlightIssueIds(projects);\n }\n\n const result: BackfillRecordsResult = {\n processed: 0,\n skipped: 0,\n failed: 0,\n details: [],\n };\n\n for (const issueId of issueIds) {\n if (options.verbose) {\n console.log(`[records-backfill] ${issueId} ...`);\n }\n\n const outcome = await backfillIssue(issueId, options);\n result.details.push({ issueId, ...outcome });\n\n if (outcome.action === 'written') result.processed++;\n else if (outcome.action === 'skipped') result.skipped++;\n else result.failed++;\n\n if (options.verbose) {\n console.log(`[records-backfill] ${issueId} -> ${outcome.action}${outcome.reason ? ` (${outcome.reason})` : ''}`);\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { S as resumeAgent, x as init_resume } from "./agents-CgVr77Qq.js";
2
+ init_resume();
3
+ export { resumeAgent };
@@ -6,15 +6,15 @@ import { g as resolveProjectForIssue, l as init_record, m as readIssueRecordSync
6
6
  import { d as getDevrootPathSync, f as init_config } from "./config-CPTQFN9R.js";
7
7
  import { a as init_io, r as findPlanSync, s as readPlan } from "./io-BfPe-7jt.js";
8
8
  import { b as isPaneDead, w as listSessionNames, x as killSession, y as init_tmux } from "./tmux-Ceg1ulra.js";
9
- import { E as messageAgent, I as spawnRun, Jt as getAgentStateSync, t as init_agents } from "./agents-CQHK0CSA.js";
9
+ import { E as messageAgent, I as spawnRun, Jt as getAgentStateSync, t as init_agents } from "./agents-CgVr77Qq.js";
10
10
  import { i as init_activity_logger, n as emitActivityEntrySync } from "./activity-logger-DR4VJx-J.js";
11
11
  import { a as init_agents$1 } from "./agents-BURDseV4.js";
12
12
  import { a as PAN_DIRNAME, f as init_types } from "./types-BjVYEbAq.js";
13
- import { a as init_review_status, i as getReviewStatusSync, m as setReviewStatusSync } from "./review-status-iJwfEoNX.js";
13
+ import { a as init_review_status, i as getReviewStatusSync, m as setReviewStatusSync } from "./review-status-B_XXomV0.js";
14
14
  import { a as init_lifecycle_io, i as findVBriefByIssueSync } from "./lifecycle-io-DDiMYH0_.js";
15
15
  import { n as shouldSkipDispatchAsMerged, t as init_merge_verification } from "./merge-verification-DQW7gEf1.js";
16
16
  import { n as init_github_pr_lookup, r as lookupPullRequestNumberForBranch } from "./github-pr-lookup-CHyDU4gI.js";
17
- import { n as init_review_verdict_feedback } from "./review-verdict-feedback-CCZ05atV.js";
17
+ import { n as init_review_verdict_feedback } from "./review-verdict-feedback-DGV13LDb.js";
18
18
  import { Effect } from "effect";
19
19
  import { existsSync } from "fs";
20
20
  import { dirname, join } from "path";
@@ -1086,7 +1086,7 @@ async function buildConvoyPromptPromise(opts) {
1086
1086
  }
1087
1087
  async function spawnReviewSubRoleForIssuePromise(opts) {
1088
1088
  try {
1089
- const { saveAgentState, spawnRun, getAgentStateSync, getLatestSessionIdSync, resumeAgent } = await import("./agents-pp8FO7Uj.js");
1089
+ const { saveAgentState, spawnRun, getAgentStateSync, getLatestSessionIdSync, resumeAgent } = await import("./agents-By3u_fQ8.js");
1090
1090
  const cfg = loadConfigSync().config;
1091
1091
  const outputPath = opts.outputPath ?? reviewerAgentOutputPath(opts.workspace, opts.runId, opts.subRole);
1092
1092
  const synthesisAgentId = opts.synthesisAgentId ?? `agent-${opts.issueId.toLowerCase()}-review`;
@@ -1204,7 +1204,7 @@ async function computeConvoyScope(issueId, workspace) {
1204
1204
  let carried = [];
1205
1205
  let scope = "changed";
1206
1206
  try {
1207
- const { getReviewStatusSync } = await import("./review-status-BbNVlXh1.js");
1207
+ const { getReviewStatusSync } = await import("./review-status-Bo-EFVKh.js");
1208
1208
  scope = resolveReReviewScope(issueId);
1209
1209
  const priorVerdicts = getReviewStatusSync(issueId)?.reviewerVerdicts;
1210
1210
  let changedFiles;
@@ -1247,7 +1247,7 @@ async function computeConvoyScope(issueId, workspace) {
1247
1247
  */
1248
1248
  async function forkParentSessionForReviewer(parentAgentId, workspace) {
1249
1249
  try {
1250
- const { getLatestSessionIdSync } = await import("./agents-pp8FO7Uj.js");
1250
+ const { getLatestSessionIdSync } = await import("./agents-By3u_fQ8.js");
1251
1251
  const parentSessionId = getLatestSessionIdSync(parentAgentId);
1252
1252
  if (!parentSessionId) return null;
1253
1253
  const src = sessionFilePath(workspace, parentSessionId);
@@ -1291,13 +1291,13 @@ async function launchConvoyReviewersPromise(params) {
1291
1291
  }
1292
1292
  }
1293
1293
  const cfg = loadConfigSync().config;
1294
- const { getAgentStateSync } = await import("./agents-pp8FO7Uj.js");
1294
+ const { getAgentStateSync } = await import("./agents-By3u_fQ8.js");
1295
1295
  const parentState = getAgentStateSync(params.synthesisAgentId);
1296
1296
  const reviewerResults = await Promise.all(params.inScope.map(async (subRole) => {
1297
1297
  const outputPath = reviewerAgentOutputPath(params.workspace, params.runId, subRole);
1298
1298
  let forkedSessionId;
1299
1299
  if (params.forkFromParent && parentState?.harness === "claude-code" && !params.harness) try {
1300
- const { getLatestSessionIdSync } = await import("./agents-pp8FO7Uj.js");
1300
+ const { getLatestSessionIdSync } = await import("./agents-By3u_fQ8.js");
1301
1301
  const reviewerModel = params.model ?? resolveModel("review", subRole, cfg);
1302
1302
  if (!!!getLatestSessionIdSync(reviewerAgentId(params.issueId, subRole)) && reviewerModel === parentState.model) {
1303
1303
  forkedSessionId = await forkParentSessionForReviewer(params.synthesisAgentId, params.workspace) ?? void 0;
@@ -1318,7 +1318,7 @@ async function launchConvoyReviewersPromise(params) {
1318
1318
  allowHost: params.allowHost ?? false
1319
1319
  }));
1320
1320
  if (!result.success) try {
1321
- const { messageAgent } = await import("./agents-pp8FO7Uj.js");
1321
+ const { messageAgent } = await import("./agents-By3u_fQ8.js");
1322
1322
  await messageAgent(params.synthesisAgentId, `REVIEWER_FAILED ${subRole} ${result.error ?? result.message}`);
1323
1323
  } catch (signalErr) {
1324
1324
  console.warn(`[review-agent] Failed to signal ${subRole} spawn failure to ${params.synthesisAgentId}:`, signalErr);
@@ -1345,7 +1345,7 @@ async function launchConvoyReviewersPromise(params) {
1345
1345
  async function handleReviewDiscoveryReady(issueId, opts = {}) {
1346
1346
  const normalized = issueId.toUpperCase();
1347
1347
  const parentId = `agent-${normalized.toLowerCase()}-review`;
1348
- const { saveAgentState, getAgentStateSync } = await import("./agents-pp8FO7Uj.js");
1348
+ const { saveAgentState, getAgentStateSync } = await import("./agents-By3u_fQ8.js");
1349
1349
  const parent = getAgentStateSync(parentId);
1350
1350
  if (!parent) return {
1351
1351
  success: false,
@@ -1670,13 +1670,14 @@ async function spawnReviewRoleForIssuePromise(opts) {
1670
1670
  if ((await Effect.runPromise(listSessionNames())).includes(reviewSessionName)) {
1671
1671
  const paneDead = await Effect.runPromise(isPaneDead(reviewSessionName));
1672
1672
  let staleRunId = false;
1673
+ let currentRunId;
1673
1674
  if (!paneDead && !opts.force) try {
1674
1675
  const { stdout } = await execAsync("git rev-parse --short=8 HEAD", {
1675
1676
  cwd: opts.workspace,
1676
1677
  encoding: "utf-8",
1677
1678
  timeout: 1e4
1678
1679
  });
1679
- const currentRunId = `agent-${opts.issueId.toLowerCase()}-review-${stdout.trim()}`;
1680
+ currentRunId = `agent-${opts.issueId.toLowerCase()}-review-${stdout.trim()}`;
1680
1681
  const synthReviewRunId = getAgentStateSync(reviewSessionName)?.reviewRunId;
1681
1682
  if (!synthReviewRunId || synthReviewRunId !== currentRunId) {
1682
1683
  staleRunId = true;
@@ -1690,7 +1691,11 @@ async function spawnReviewRoleForIssuePromise(opts) {
1690
1691
  const status = getReviewStatusSync(opts.issueId);
1691
1692
  const terminal = status?.reviewStatus === "passed" || status?.reviewStatus === "blocked" || status?.reviewStatus === "failed";
1692
1693
  const newerRequest = !!status?.reviewRequestedAt && (!status.reviewSpawnedAt || status.reviewRequestedAt > status.reviewSpawnedAt);
1693
- finishedIdle = terminal && newerRequest;
1694
+ let reportWritten = false;
1695
+ if (currentRunId) try {
1696
+ reportWritten = existsSync(join(opts.workspace, PAN_DIRNAME, "review", currentRunId, "review.md"));
1697
+ } catch {}
1698
+ finishedIdle = (terminal || reportWritten) && newerRequest;
1694
1699
  if (finishedIdle) console.log(`[review-agent] ${reviewSessionName} is finished-idle (verdict ${status?.reviewStatus}, newer request pending) — warm-reusing for the new review cycle`);
1695
1700
  else if (terminal) console.log(`[review-agent] ${reviewSessionName} has a terminal verdict (${status?.reviewStatus}) and no newer request — treating this dispatch as a stale duplicate; leaving the verdict intact`);
1696
1701
  } catch (statusErr) {
@@ -1766,7 +1771,7 @@ async function spawnReviewRoleForIssuePromise(opts) {
1766
1771
  });
1767
1772
  } catch {}
1768
1773
  try {
1769
- const { spawnRun, saveAgentState, getAgentState, getAgentStateSync, getLatestSessionIdSync, resumeAgent, wipeAgentStateDirs } = await import("./agents-pp8FO7Uj.js");
1774
+ const { spawnRun, saveAgentState, getAgentState, getAgentStateSync, getLatestSessionIdSync, resumeAgent, wipeAgentStateDirs } = await import("./agents-By3u_fQ8.js");
1770
1775
  const workAgentState = await Effect.runPromise(getAgentState(`agent-${opts.issueId.toLowerCase()}`));
1771
1776
  const allowHost = opts.allowHost === true || workAgentState?.hostOverride === true;
1772
1777
  let headSha = "unknown";
@@ -1872,6 +1877,7 @@ async function spawnReviewRoleForIssuePromise(opts) {
1872
1877
  const resumed = getAgentStateSync(reviewAgentId);
1873
1878
  if (resumed) {
1874
1879
  resumed.reviewRunId = runId;
1880
+ resumed.reviewDeadlineAt = new Date(Date.now() + PARENT_REVIEW_TIMEOUT_MS).toISOString();
1875
1881
  await Effect.runPromise(saveAgentState(resumed));
1876
1882
  }
1877
1883
  } catch {}
@@ -1902,6 +1908,7 @@ async function spawnReviewRoleForIssuePromise(opts) {
1902
1908
  ...allowHost ? { allowHost: true } : {}
1903
1909
  });
1904
1910
  run.reviewRunId = runId;
1911
+ run.reviewDeadlineAt = new Date(Date.now() + PARENT_REVIEW_TIMEOUT_MS).toISOString();
1905
1912
  try {
1906
1913
  await Effect.runPromise(saveAgentState(run));
1907
1914
  } catch (saveErr) {
@@ -2057,7 +2064,7 @@ function resolveReviewMode(issueId) {
2057
2064
  function isExtendedReviewEnabled(issueId) {
2058
2065
  return resolveReviewMode(issueId) === "full";
2059
2066
  }
2060
- var execAsync, spawnReviewRoleForIssue, killAllReviewerSessions, killAllReviewSessions;
2067
+ var execAsync, PARENT_REVIEW_TIMEOUT_MS, spawnReviewRoleForIssue, killAllReviewerSessions, killAllReviewSessions;
2061
2068
  var init_review_agent = __esmMin((() => {
2062
2069
  init_tmux();
2063
2070
  init_activity_logger();
@@ -2074,11 +2081,12 @@ var init_review_agent = __esmMin((() => {
2074
2081
  init_types();
2075
2082
  init_agents();
2076
2083
  execAsync = promisify$1(exec);
2084
+ PARENT_REVIEW_TIMEOUT_MS = 2700 * 1e3;
2077
2085
  spawnReviewRoleForIssue = (opts) => Effect.promise(() => spawnReviewRoleForIssuePromise(opts));
2078
2086
  killAllReviewerSessions = (projectKey, issueId) => Effect.promise(() => killAllReviewerSessionsPromise(projectKey, issueId));
2079
2087
  killAllReviewSessions = () => Effect.promise(() => killAllReviewSessionsPromise());
2080
2088
  }));
2081
2089
  //#endregion
2082
- export { killAllReviewerSessions as a, buildConvoyPrompt as c, spawnReviewSubRoleForIssue as d, reviewResumeDecision as f, reviewerOutputPath as h, killAllReviewSessions as i, handleReviewDiscoveryReady as l, init_review_monitor as m, isExtendedReviewEnabled as n, resolveReviewMode as o, REVIEW_SUB_ROLES as p, isReviewSessionForIssue as r, spawnReviewRoleForIssue as s, init_review_agent as t, resolveReReviewScope as u };
2090
+ export { killAllReviewSessions as a, spawnReviewRoleForIssue as c, resolveReReviewScope as d, spawnReviewSubRoleForIssue as f, reviewerOutputPath as g, init_review_monitor as h, isReviewSessionForIssue as i, buildConvoyPrompt as l, REVIEW_SUB_ROLES as m, init_review_agent as n, killAllReviewerSessions as o, reviewResumeDecision as p, isExtendedReviewEnabled as r, resolveReviewMode as s, PARENT_REVIEW_TIMEOUT_MS as t, handleReviewDiscoveryReady as u };
2083
2091
 
2084
- //# sourceMappingURL=review-agent-DFosQzCG.js.map
2092
+ //# sourceMappingURL=review-agent-PhqOhpx3.js.map