@knpkv/control-center 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/README.md +52 -9
  2. package/dist/client/.vite/manifest.json +183 -170
  3. package/dist/client/assets/{ActiveWorkPage-DJQgGZeV.js → ActiveWorkPage-Dd1mxPrq.js} +2 -2
  4. package/dist/client/assets/{ActiveWorkPage-DJQgGZeV.js.map → ActiveWorkPage-Dd1mxPrq.js.map} +1 -1
  5. package/dist/client/assets/AgentPage-C3LThgPZ.js +3 -0
  6. package/dist/client/assets/AgentPage-C3LThgPZ.js.map +1 -0
  7. package/dist/client/assets/{AtlassianOAuthCallbackPage-D1F1xE_2.js → AtlassianOAuthCallbackPage-BPoF6oKf.js} +2 -2
  8. package/dist/client/assets/{AtlassianOAuthCallbackPage-D1F1xE_2.js.map → AtlassianOAuthCallbackPage-BPoF6oKf.js.map} +1 -1
  9. package/dist/client/assets/AuthorizedSharePage-jjqu6W_f.js +2 -0
  10. package/dist/client/assets/AuthorizedSharePage-jjqu6W_f.js.map +1 -0
  11. package/dist/client/assets/BrowserCrypto-BMbjhcvP.js +2 -0
  12. package/dist/client/assets/{BrowserCrypto-DVWR7DFd.js.map → BrowserCrypto-BMbjhcvP.js.map} +1 -1
  13. package/dist/client/assets/BrowserSessionHydrator-BC1ymLkL.js +2 -0
  14. package/dist/client/assets/BrowserSessionHydrator-BC1ymLkL.js.map +1 -0
  15. package/dist/client/assets/CommandSearch-WwAVDrD9.js +2 -0
  16. package/dist/client/assets/{CommandSearch-CP_QCbkm.js.map → CommandSearch-WwAVDrD9.js.map} +1 -1
  17. package/dist/client/assets/ItemsPage-CKK_KkJ2.js +2 -0
  18. package/dist/client/assets/{ItemsPage-BGFUkRL2.js.map → ItemsPage-CKK_KkJ2.js.map} +1 -1
  19. package/dist/client/assets/{PairPage-DIgzx0K2.js → PairPage-DA6cmyqF.js} +2 -2
  20. package/dist/client/assets/{PairPage-DIgzx0K2.js.map → PairPage-DA6cmyqF.js.map} +1 -1
  21. package/dist/client/assets/PortfolioOverview-CEI4gpXi.js +2 -0
  22. package/dist/client/assets/PortfolioOverview-CEI4gpXi.js.map +1 -0
  23. package/dist/client/assets/PullRequestReviewPanel-D7AKnwL-.js +6 -0
  24. package/dist/client/assets/PullRequestReviewPanel-D7AKnwL-.js.map +1 -0
  25. package/dist/client/assets/ReleaseRoute-CbPW3qUT.js +2 -0
  26. package/dist/client/assets/{ReleaseRoute-DXJ8Jg60.js.map → ReleaseRoute-CbPW3qUT.js.map} +1 -1
  27. package/dist/client/assets/ReleaseWorkset-BluAe7Sq.js +2 -0
  28. package/dist/client/assets/{ReleaseWorkset-Dtzalmji.js.map → ReleaseWorkset-BluAe7Sq.js.map} +1 -1
  29. package/dist/client/assets/ServicesPage-_B89DAvG.js +2 -0
  30. package/dist/client/assets/ServicesPage-_B89DAvG.js.map +1 -0
  31. package/dist/client/assets/TimelinePage-DvpgD8AY.js +2 -0
  32. package/dist/client/assets/TimelinePage-DvpgD8AY.js.map +1 -0
  33. package/dist/client/assets/WorkspaceEntityLink-DPj6MKI2.js +2 -0
  34. package/dist/client/assets/{WorkspaceEntityLink-AdZ_T-Wk.js.map → WorkspaceEntityLink-DPj6MKI2.js.map} +1 -1
  35. package/dist/client/assets/WorkspaceEntityRoute-B01fxxB3.js +3 -0
  36. package/dist/client/assets/WorkspaceEntityRoute-B01fxxB3.js.map +1 -0
  37. package/dist/client/assets/{WorkspaceHomeLink-XbKSPths.js → WorkspaceHomeLink-CkJfzO25.js} +2 -2
  38. package/dist/client/assets/{WorkspaceHomeLink-XbKSPths.js.map → WorkspaceHomeLink-CkJfzO25.js.map} +1 -1
  39. package/dist/client/assets/WorkspacePullRequestDetails-HwDgp12e.js +3 -0
  40. package/dist/client/assets/WorkspacePullRequestDetails-HwDgp12e.js.map +1 -0
  41. package/dist/client/assets/{WorkspaceReleaseLayout-cfboC5Qh.js → WorkspaceReleaseLayout-CGHi8eoo.js} +2 -2
  42. package/dist/client/assets/{WorkspaceReleaseLayout-cfboC5Qh.js.map → WorkspaceReleaseLayout-CGHi8eoo.js.map} +1 -1
  43. package/dist/client/assets/{WorkspaceSettingsPage-Fy7Wx8Y2.js → WorkspaceSettingsPage-DyoGiGJG.js} +2 -2
  44. package/dist/client/assets/{WorkspaceSettingsPage-Fy7Wx8Y2.js.map → WorkspaceSettingsPage-DyoGiGJG.js.map} +1 -1
  45. package/dist/client/assets/agent-api-CeONl_8w.js +19 -0
  46. package/dist/client/assets/agent-api-CeONl_8w.js.map +1 -0
  47. package/dist/client/assets/authenticatedMutationClient-DYaieXUe.js +2 -0
  48. package/dist/client/assets/{authenticatedMutationClient-Ccwguc3i.js.map → authenticatedMutationClient-DYaieXUe.js.map} +1 -1
  49. package/dist/client/assets/authorizedShareTransport-cxBoQzQ2.js +2 -0
  50. package/dist/client/assets/{authorizedShareTransport-DZHgFEkh.js.map → authorizedShareTransport-cxBoQzQ2.js.map} +1 -1
  51. package/dist/client/assets/client-DKS82kT_.js +5 -0
  52. package/dist/client/assets/client-DKS82kT_.js.map +1 -0
  53. package/dist/client/assets/connectionTestTransport-I_Ga9UNs.js +2 -0
  54. package/dist/client/assets/{connectionTestTransport-BQ55d6Me.js.map → connectionTestTransport-I_Ga9UNs.js.map} +1 -1
  55. package/dist/client/assets/index-C7_FDTU7.js +11 -0
  56. package/dist/client/assets/index-C7_FDTU7.js.map +1 -0
  57. package/dist/client/assets/{patterns-5N-j-AD2-BwypFm-e.js → patterns-5N-j-AD2-B9qgekXA.js} +2 -2
  58. package/dist/client/assets/{patterns-5N-j-AD2-BwypFm-e.js.map → patterns-5N-j-AD2-B9qgekXA.js.map} +1 -1
  59. package/dist/client/assets/{presentPortfolio-D3ZIcnqt.js → presentPortfolio-C_JsoSWg.js} +2 -2
  60. package/dist/client/assets/presentPortfolio-C_JsoSWg.js.map +1 -0
  61. package/dist/client/assets/{presentWorkspaceItems-Bmh4oEbH.js → presentWorkspaceItems-DboAfwGc.js} +2 -2
  62. package/dist/client/assets/{presentWorkspaceItems-Bmh4oEbH.js.map → presentWorkspaceItems-DboAfwGc.js.map} +1 -1
  63. package/dist/client/assets/{pullRequestReviewFailures-S74M-fOk.js → pullRequestReviewFailures-DHmYwffV.js} +2 -2
  64. package/dist/client/assets/{pullRequestReviewFailures-S74M-fOk.js.map → pullRequestReviewFailures-DHmYwffV.js.map} +1 -1
  65. package/dist/client/assets/pullRequestReviewThreadReplay-Vy1k53qE.js +2 -0
  66. package/dist/client/assets/pullRequestReviewThreadReplay-Vy1k53qE.js.map +1 -0
  67. package/dist/client/assets/releaseRoutes-t9uCfs5T.js +2 -0
  68. package/dist/client/assets/{releaseRoutes-BCuIdZyA.js.map → releaseRoutes-t9uCfs5T.js.map} +1 -1
  69. package/dist/client/assets/serviceOnboarding-DLINCon7.js +2 -0
  70. package/dist/client/assets/{serviceOnboarding-Jg_0yNjf.js.map → serviceOnboarding-DLINCon7.js.map} +1 -1
  71. package/dist/client/assets/{useWorkspaceDefaultLanding-CzlDdEF-.js → useWorkspaceDefaultLanding-CC5ImHkL.js} +3 -3
  72. package/dist/client/assets/{useWorkspaceDefaultLanding-CzlDdEF-.js.map → useWorkspaceDefaultLanding-CC5ImHkL.js.map} +1 -1
  73. package/dist/client/assets/{useWorkspaceItems-Cd3MPke2.js → useWorkspaceItems-B1X-JNwq.js} +2 -2
  74. package/dist/client/assets/{useWorkspaceItems-Cd3MPke2.js.map → useWorkspaceItems-B1X-JNwq.js.map} +1 -1
  75. package/dist/client/assets/workspaceEntityRoutes-2TejMrzb.js +2 -0
  76. package/dist/client/assets/workspaceEntityRoutes-2TejMrzb.js.map +1 -0
  77. package/dist/client/assets/workspaceScrollCapture-BsjcWVsk.js +2 -0
  78. package/dist/client/assets/workspaceScrollCapture-BsjcWVsk.js.map +1 -0
  79. package/dist/client/assets/workspaceSettingsTransport-Dw2hueXv.js +2 -0
  80. package/dist/client/assets/{workspaceSettingsTransport-CZWYL5T7.js.map → workspaceSettingsTransport-Dw2hueXv.js.map} +1 -1
  81. package/dist/client/build-graph.json +17 -0
  82. package/dist/client/index.html +1 -1
  83. package/dist/server/api/agent.d.ts +563 -44
  84. package/dist/server/api/agent.d.ts.map +1 -1
  85. package/dist/server/api/deliveryGraph.d.ts +454 -454
  86. package/dist/server/api/index.d.ts +1 -1
  87. package/dist/server/api/index.d.ts.map +1 -1
  88. package/dist/server/api/index.js +4 -4
  89. package/dist/server/api/liveEvents.d.ts +20 -0
  90. package/dist/server/api/liveEvents.d.ts.map +1 -1
  91. package/dist/server/api/portfolio.d.ts +23 -0
  92. package/dist/server/api/portfolio.d.ts.map +1 -1
  93. package/dist/server/api/shares.d.ts +2 -2
  94. package/dist/server/assets/{BindConfig-DIsf2Rnh.js → BindConfig-Bj282xDC.js} +2094 -290
  95. package/dist/server/assets/BindConfig-Bj282xDC.js.map +1 -0
  96. package/dist/server/assets/{CodePipelineStateDecoder-CVf1A2zG.js → CodePipelineStateDecoder-CNiFRgSi.js} +2 -2
  97. package/dist/server/assets/{CodePipelineStateDecoder-CVf1A2zG.js.map → CodePipelineStateDecoder-CNiFRgSi.js.map} +1 -1
  98. package/dist/server/assets/{agent-CyZ40zs1.js → agent-ZvwskOQu.js} +160 -10
  99. package/dist/server/assets/agent-ZvwskOQu.js.map +1 -0
  100. package/dist/server/assets/{controlCenterApi-ZUX3Y-LE.js → controlCenterApi-5j3gOXgE.js} +5 -5
  101. package/dist/server/assets/{controlCenterApi-ZUX3Y-LE.js.map → controlCenterApi-5j3gOXgE.js.map} +1 -1
  102. package/dist/server/assets/{descriptor-CKtTnhef.js → descriptor-CCvNzSZL.js} +10 -10
  103. package/dist/server/assets/{descriptor-CKtTnhef.js.map → descriptor-CCvNzSZL.js.map} +1 -1
  104. package/dist/server/assets/{failures-mgYDkUZy.js → failures-CesHLYbN.js} +2 -2
  105. package/dist/server/assets/{failures-mgYDkUZy.js.map → failures-CesHLYbN.js.map} +1 -1
  106. package/dist/server/assets/{firstPartyServices-D7b8BOek.js → firstPartyServices-Cdzjcs2H.js} +2 -2
  107. package/dist/server/assets/{firstPartyServices-D7b8BOek.js.map → firstPartyServices-Cdzjcs2H.js.map} +1 -1
  108. package/dist/server/assets/{manualPluginSynchronization-DFlhKvav.js → manualPluginSynchronization-CzIhZ_Dw.js} +5 -5
  109. package/dist/server/assets/{manualPluginSynchronization-DFlhKvav.js.map → manualPluginSynchronization-CzIhZ_Dw.js.map} +1 -1
  110. package/dist/server/assets/{plugins-D__oMDpI.js → plugins-DiPrfzV8.js} +2 -2
  111. package/dist/server/assets/{plugins-D__oMDpI.js.map → plugins-DiPrfzV8.js.map} +1 -1
  112. package/dist/server/assets/{readiness-BhA-Nr9c.js → readiness-BtntBhDj.js} +3 -3
  113. package/dist/server/assets/{readiness-BhA-Nr9c.js.map → readiness-BtntBhDj.js.map} +1 -1
  114. package/dist/server/assets/{relationshipInferenceMaterialization-DYBcaWhQ.js → relationshipInferenceMaterialization-CR6xyMNL.js} +1121 -159
  115. package/dist/server/assets/relationshipInferenceMaterialization-CR6xyMNL.js.map +1 -0
  116. package/dist/server/assets/{workspaceSettings-BE713Oe8.js → workspaceSettings-C2Zsk6RI.js} +2784 -2700
  117. package/dist/server/assets/workspaceSettings-C2Zsk6RI.js.map +1 -0
  118. package/dist/server/build-graph.json +117 -4
  119. package/dist/server/domain/actors.d.ts +12 -12
  120. package/dist/server/domain/deliveryGraph.d.ts +49 -49
  121. package/dist/server/domain/governedAction/bindings.d.ts +24 -12
  122. package/dist/server/domain/governedAction/bindings.d.ts.map +1 -1
  123. package/dist/server/domain/governedAction/lifecycle.d.ts +8 -8
  124. package/dist/server/domain/governedAction/model.d.ts +39 -18
  125. package/dist/server/domain/governedAction/model.d.ts.map +1 -1
  126. package/dist/server/domain/governedAction/stateMachine.d.ts +34 -34
  127. package/dist/server/domain/index.js +6 -6
  128. package/dist/server/domain/normalizedIssue.d.ts +1 -1
  129. package/dist/server/domain/prReview.d.ts +38 -0
  130. package/dist/server/domain/prReview.d.ts.map +1 -1
  131. package/dist/server/domain/prReviewReconciliation.d.ts +56 -0
  132. package/dist/server/domain/prReviewReconciliation.d.ts.map +1 -0
  133. package/dist/server/domain/prReviewRevision.d.ts +1 -0
  134. package/dist/server/domain/prReviewRevision.d.ts.map +1 -1
  135. package/dist/server/domain/readiness/model.d.ts +3 -3
  136. package/dist/server/domain/release.d.ts +3 -3
  137. package/dist/server/domain/releasePublication.d.ts +4 -0
  138. package/dist/server/domain/releasePublication.d.ts.map +1 -0
  139. package/dist/server/index.js +8 -8
  140. package/dist/server/server/agent/AgentJobWorker.d.ts +10 -1
  141. package/dist/server/server/agent/AgentJobWorker.d.ts.map +1 -1
  142. package/dist/server/server/agent/ReleaseAgentPrompt.d.ts.map +1 -1
  143. package/dist/server/server/agent/internal/AgentJobTaskExecutor.d.ts +4 -3
  144. package/dist/server/server/agent/internal/AgentJobTaskExecutor.d.ts.map +1 -1
  145. package/dist/server/server/agent/internal/PrReviewSandboxSession.d.ts +17 -1
  146. package/dist/server/server/agent/internal/PrReviewSandboxSession.d.ts.map +1 -1
  147. package/dist/server/server/agent/internal/PrReviewTaskExecutor.d.ts +76 -2
  148. package/dist/server/server/agent/internal/PrReviewTaskExecutor.d.ts.map +1 -1
  149. package/dist/server/server/agent/internal/PrReviewTelemetry.d.ts +27 -0
  150. package/dist/server/server/agent/internal/PrReviewTelemetry.d.ts.map +1 -0
  151. package/dist/server/server/api/ApplicationServices.d.ts +39 -5
  152. package/dist/server/server/api/ApplicationServices.d.ts.map +1 -1
  153. package/dist/server/server/api/Handlers.d.ts.map +1 -1
  154. package/dist/server/server/api/RequestBoundary.d.ts.map +1 -1
  155. package/dist/server/server/application/GovernedReviewSuggestionPublicationGateway.d.ts.map +1 -1
  156. package/dist/server/server/application/ReviewSuggestionPublicationGateway.d.ts +4 -0
  157. package/dist/server/server/application/ReviewSuggestionPublicationGateway.d.ts.map +1 -1
  158. package/dist/server/server/application/index.d.ts +1 -0
  159. package/dist/server/server/application/index.d.ts.map +1 -1
  160. package/dist/server/server/application/liveEvents.d.ts.map +1 -1
  161. package/dist/server/server/application/pipelineExecutionProjection.d.ts +6 -6
  162. package/dist/server/server/application/portfolioSnapshots.d.ts +2014 -4
  163. package/dist/server/server/application/portfolioSnapshots.d.ts.map +1 -1
  164. package/dist/server/server/application/pullRequestReviews.d.ts.map +1 -1
  165. package/dist/server/server/application/releaseAgent.d.ts +11 -3
  166. package/dist/server/server/application/releaseAgent.d.ts.map +1 -1
  167. package/dist/server/server/application/releasePublicationIntent.d.ts +7 -0
  168. package/dist/server/server/application/releasePublicationIntent.d.ts.map +1 -0
  169. package/dist/server/server/application/releasePublicationMetadata.d.ts +61 -0
  170. package/dist/server/server/application/releasePublicationMetadata.d.ts.map +1 -0
  171. package/dist/server/server/application/releasePublicationSubmissions.d.ts +3699 -0
  172. package/dist/server/server/application/releasePublicationSubmissions.d.ts.map +1 -0
  173. package/dist/server/server/application/releaseSynchronization.d.ts.map +1 -1
  174. package/dist/server/server/cli.js +8 -8
  175. package/dist/server/server/cli.js.map +1 -1
  176. package/dist/server/server/governance/governedActionDigests.d.ts +233 -218
  177. package/dist/server/server/governance/governedActionDigests.d.ts.map +1 -1
  178. package/dist/server/server/governance/internal/GovernedActionExecutionEngine.d.ts +3 -4
  179. package/dist/server/server/governance/internal/GovernedActionExecutionEngine.d.ts.map +1 -1
  180. package/dist/server/server/governance/internal/execution-store/begin.d.ts.map +1 -1
  181. package/dist/server/server/governance/internal/execution-store/dispatch-inbox.d.ts +1 -1
  182. package/dist/server/server/governance/internal/execution-store/dispatch-outcome.d.ts +8 -8
  183. package/dist/server/server/governance/internal/execution-store/provider-outcome-fold.d.ts +2 -2
  184. package/dist/server/server/governance/internal/execution-store/reconciliation-inbox.d.ts +1 -1
  185. package/dist/server/server/governance/internal/execution-store/recovery-claim.d.ts +36 -30
  186. package/dist/server/server/governance/internal/execution-store/recovery-claim.d.ts.map +1 -1
  187. package/dist/server/server/index.js +5 -5
  188. package/dist/server/server/internal/codepipeline-state-probe.js +1 -1
  189. package/dist/server/server/persistence/Database.d.ts +1 -1
  190. package/dist/server/server/persistence/Database.d.ts.map +1 -1
  191. package/dist/server/server/persistence/Persistence.d.ts +1539 -577
  192. package/dist/server/server/persistence/Persistence.d.ts.map +1 -1
  193. package/dist/server/server/persistence/backup/BackupArchive.d.ts.map +1 -1
  194. package/dist/server/server/persistence/repositories/agentJobModels.d.ts +345 -8
  195. package/dist/server/server/persistence/repositories/agentJobModels.d.ts.map +1 -1
  196. package/dist/server/server/persistence/repositories/agentJobRepository.d.ts +654 -192
  197. package/dist/server/server/persistence/repositories/agentJobRepository.d.ts.map +1 -1
  198. package/dist/server/server/persistence/repositories/delivery-graph/contract.d.ts +138 -138
  199. package/dist/server/server/persistence/repositories/delivery-graph/decode.d.ts +25 -25
  200. package/dist/server/server/persistence/repositories/delivery-graph/read.d.ts +111 -111
  201. package/dist/server/server/persistence/repositories/delivery-graph/rows.d.ts +27 -27
  202. package/dist/server/server/persistence/repositories/delivery-graph/write.d.ts +48 -48
  203. package/dist/server/server/persistence/repositories/deliveryGraphRepository.d.ts +111 -111
  204. package/dist/server/server/persistence/repositories/governed-action/codec.d.ts +255 -234
  205. package/dist/server/server/persistence/repositories/governed-action/codec.d.ts.map +1 -1
  206. package/dist/server/server/persistence/repositories/governed-action/contract.d.ts +66 -46
  207. package/dist/server/server/persistence/repositories/governed-action/contract.d.ts.map +1 -1
  208. package/dist/server/server/persistence/repositories/governed-action/read.d.ts +664 -190
  209. package/dist/server/server/persistence/repositories/governed-action/read.d.ts.map +1 -1
  210. package/dist/server/server/persistence/repositories/governed-action/transaction.d.ts +676 -206
  211. package/dist/server/server/persistence/repositories/governed-action/transaction.d.ts.map +1 -1
  212. package/dist/server/server/persistence/repositories/governed-action/write-preparation.d.ts +37 -31
  213. package/dist/server/server/persistence/repositories/governed-action/write-preparation.d.ts.map +1 -1
  214. package/dist/server/server/persistence/repositories/governed-action/write-replay.d.ts +44 -32
  215. package/dist/server/server/persistence/repositories/governed-action/write-replay.d.ts.map +1 -1
  216. package/dist/server/server/persistence/repositories/governed-action/write.d.ts +44 -32
  217. package/dist/server/server/persistence/repositories/governed-action/write.d.ts.map +1 -1
  218. package/dist/server/server/persistence/repositories/governedActionRepository.d.ts +674 -205
  219. package/dist/server/server/persistence/repositories/governedActionRepository.d.ts.map +1 -1
  220. package/dist/server/server/persistence/repositories/internal/reviewSuggestionRevisions.d.ts +85 -4
  221. package/dist/server/server/persistence/repositories/internal/reviewSuggestionRevisions.d.ts.map +1 -1
  222. package/dist/server/server/persistence/repositories/models.d.ts +9 -9
  223. package/dist/server/server/persistence/repositories/peopleRepository.d.ts +36 -36
  224. package/dist/server/server/persistence/repositories/providerAccountRepository.d.ts +1 -1
  225. package/dist/server/server/persistence/repositories/readiness/assessments.d.ts +6 -6
  226. package/dist/server/server/persistence/repositories/readiness/contract.d.ts +450 -450
  227. package/dist/server/server/persistence/repositories/readiness/queue.d.ts +14 -14
  228. package/dist/server/server/persistence/repositories/readinessRepository.d.ts +7 -7
  229. package/dist/server/server/persistence/repositories/releaseRepository.d.ts +18 -18
  230. package/dist/server/server/persistence/repositories/retentionRepository.d.ts.map +1 -1
  231. package/dist/server/server/persistence/repositories/timelineRepository.d.ts +4 -4
  232. package/dist/server/server/plugins/atlassian/AtlassianOAuthGrants.d.ts.map +1 -1
  233. package/dist/server/server/plugins/atlassian/AtlassianOAuthScopes.d.ts +9 -0
  234. package/dist/server/server/plugins/atlassian/AtlassianOAuthScopes.d.ts.map +1 -0
  235. package/dist/server/server/plugins/atlassian/AtlassianProfiles.d.ts.map +1 -1
  236. package/dist/server/server/plugins/codecommit/CodeCommitPluginDefinition.d.ts.map +1 -1
  237. package/dist/server/server/plugins/jira/JiraReadPlugin.d.ts +2 -2
  238. package/dist/server/server/plugins/jira/JiraReadPlugin.d.ts.map +1 -1
  239. package/dist/server/server/plugins/jira/JiraReadProvider.d.ts.map +1 -1
  240. package/dist/server/server/plugins/jira/JiraReleaseVersionLimits.d.ts +8 -0
  241. package/dist/server/server/plugins/jira/JiraReleaseVersionLimits.d.ts.map +1 -0
  242. package/dist/server/server/plugins/jira/index.d.ts +1 -1
  243. package/dist/server/server/plugins/jira/index.d.ts.map +1 -1
  244. package/dist/server/server/runtime/Bootstrap.d.ts +1 -1
  245. package/dist/server/server/runtime/Bootstrap.d.ts.map +1 -1
  246. package/dist/server/server/runtime/ControlCenterServer.d.ts +3 -3
  247. package/dist/server/server/runtime/ControlCenterServer.d.ts.map +1 -1
  248. package/dist/server/server/runtime/PrReviewWorkerStartup.d.ts +11 -1
  249. package/dist/server/server/runtime/PrReviewWorkerStartup.d.ts.map +1 -1
  250. package/dist/server/server/runtime/RetentionStartup.d.ts.map +1 -1
  251. package/dist/server/server/runtime/ServerLifecycle.d.ts.map +1 -1
  252. package/dist/server/server/secrets/SecretStore.d.ts.map +1 -1
  253. package/package.json +9 -8
  254. package/dist/client/assets/AgentPage-DGL93TJU.js +0 -3
  255. package/dist/client/assets/AgentPage-DGL93TJU.js.map +0 -1
  256. package/dist/client/assets/AuthorizedSharePage-DCQUFY2I.js +0 -2
  257. package/dist/client/assets/AuthorizedSharePage-DCQUFY2I.js.map +0 -1
  258. package/dist/client/assets/BrowserCrypto-DVWR7DFd.js +0 -2
  259. package/dist/client/assets/BrowserSessionHydrator-DE46feEX.js +0 -2
  260. package/dist/client/assets/BrowserSessionHydrator-DE46feEX.js.map +0 -1
  261. package/dist/client/assets/CommandSearch-CP_QCbkm.js +0 -2
  262. package/dist/client/assets/ItemsPage-BGFUkRL2.js +0 -2
  263. package/dist/client/assets/PortfolioOverview-D45rk8Hl.js +0 -2
  264. package/dist/client/assets/PortfolioOverview-D45rk8Hl.js.map +0 -1
  265. package/dist/client/assets/PullRequestReviewPanel-CqPtjhVW.js +0 -6
  266. package/dist/client/assets/PullRequestReviewPanel-CqPtjhVW.js.map +0 -1
  267. package/dist/client/assets/ReleaseRoute-DXJ8Jg60.js +0 -2
  268. package/dist/client/assets/ReleaseWorkset-Dtzalmji.js +0 -2
  269. package/dist/client/assets/ServicesPage-DGcUjd2H.js +0 -2
  270. package/dist/client/assets/ServicesPage-DGcUjd2H.js.map +0 -1
  271. package/dist/client/assets/TimelinePage-Bq1RTQlP.js +0 -2
  272. package/dist/client/assets/TimelinePage-Bq1RTQlP.js.map +0 -1
  273. package/dist/client/assets/WorkspaceEntityLink-AdZ_T-Wk.js +0 -2
  274. package/dist/client/assets/WorkspaceEntityRoute-Bxxnc8us.js +0 -3
  275. package/dist/client/assets/WorkspaceEntityRoute-Bxxnc8us.js.map +0 -1
  276. package/dist/client/assets/WorkspacePullRequestDetails-BErJ5bk8.js +0 -3
  277. package/dist/client/assets/WorkspacePullRequestDetails-BErJ5bk8.js.map +0 -1
  278. package/dist/client/assets/agent-api-QVqt4a0O.js +0 -19
  279. package/dist/client/assets/agent-api-QVqt4a0O.js.map +0 -1
  280. package/dist/client/assets/authenticatedMutationClient-Ccwguc3i.js +0 -2
  281. package/dist/client/assets/authorizedShareTransport-DZHgFEkh.js +0 -2
  282. package/dist/client/assets/client-D27unen8.js +0 -5
  283. package/dist/client/assets/client-D27unen8.js.map +0 -1
  284. package/dist/client/assets/connectionTestTransport-BQ55d6Me.js +0 -2
  285. package/dist/client/assets/index-j5ze816l.js +0 -11
  286. package/dist/client/assets/index-j5ze816l.js.map +0 -1
  287. package/dist/client/assets/presentPortfolio-D3ZIcnqt.js.map +0 -1
  288. package/dist/client/assets/pullRequestReviewThreadReplay-oljKM7Xz.js +0 -2
  289. package/dist/client/assets/pullRequestReviewThreadReplay-oljKM7Xz.js.map +0 -1
  290. package/dist/client/assets/releaseRoutes-BCuIdZyA.js +0 -2
  291. package/dist/client/assets/serviceOnboarding-Jg_0yNjf.js +0 -2
  292. package/dist/client/assets/workspaceScrollCapture-CJ4QUptr.js +0 -2
  293. package/dist/client/assets/workspaceScrollCapture-CJ4QUptr.js.map +0 -1
  294. package/dist/client/assets/workspaceSettingsTransport-CZWYL5T7.js +0 -2
  295. package/dist/server/assets/BindConfig-DIsf2Rnh.js.map +0 -1
  296. package/dist/server/assets/agent-CyZ40zs1.js.map +0 -1
  297. package/dist/server/assets/relationshipInferenceMaterialization-DYBcaWhQ.js.map +0 -1
  298. package/dist/server/assets/workspaceSettings-BE713Oe8.js.map +0 -1
@@ -1,15 +1,16 @@
1
- import { $ as GovernedActionEnvelopeMaterialV1, $n as ReadinessAssessment, Ai as PrReviewSuggestion, C as RelationshipRepairReview, Ct as DeliveryEntityService, D as advanceGovernedActionLifecycle, E as GovernedActionProviderLineage, Et as DeliveryRelationship, F as GovernedActionTransitionDigest, Fi as PrReviewSuggestionId, Fn as Person, Ft as LedgerRevision, G as governedActionAuthorizationMatchesTransition, In as PersonAvatar, J as GovernedActionAttemptDigest, K as governedActionAuthorizationMismatches, L as GovernedActionTransitionV1, Ln as PersonSourceIdentity, M as GovernedActionState, Mt as EvidenceValue, N as GovernedActionTransitionCause, O as GovernedActionCommandDigest, Oi as PrReviewReport, Ot as EvidenceClaim, P as GovernedActionTransitionCommand, Q as GovernedActionEnvelopeDigest, Qn as ReadinessArtifactRevision, Qr as Freshness, R as GovernedActionUnknownOutcome, Rn as Role, Rt as RelationshipEndpointKind, S as RelationshipRepairRationale, St as DeliveryEntityProjection, T as GovernedActionLifecycleHeadV1, Tr as ReleaseReadinessAssessment, Tt as DeliveryNode, Un as EnvironmentReadinessAssessment, Vn as derivePersonInitials, W as governedActionAuthorityMismatches, X as GovernedActionAuthorizationDigest, Y as GovernedActionAttemptV1, Z as GovernedActionAuthorizationV1, _t as PortfolioInvalidatedEventV1, a as WorkspaceSettingsSections, ai as PrReviewSuggestionEdit, b as RelationshipRepairProposal, br as ReadinessRuleVersion, c as isGovernedWorkspaceSettingsSection, ci as PrReviewSuggestionRevision, ct as GovernedActionPolicyDigest, di as PrReviewSuggestionRevisionPageSize, ei as PluginHealth, er as ReadinessCandidateDigest, et as GovernedActionEnvelopeV1, fi as PrReviewSuggestionRevisionSequence, hi as hasSamePrReviewTechnicalClaim, hn as Release, ht as DomainEventMetadataV1, ii as PrReviewSuggestionAgentAuthor, it as GovernedActionIdempotencyKey, jn as Actor, k as GovernedActionCommandId, ki as PrReviewSubject, kt as EvidenceItem, l as TimelineActorKind, li as PrReviewSuggestionRevisionAuthor, lt as GovernedActionPolicyEvaluationDigest, mi as PrReviewSuggestionValidated, mt as DomainEventCorrelationId, nr as ReadinessDerivationVersion, nt as GovernedActionEvidenceSet, o as WorkspaceSettingsV1, q as governedActionPermissionGrants, r as GovernedWorkspaceSettingsSections, rt as GovernedActionEvidenceSetDigest, s as changedWorkspaceSettingsSections, si as PrReviewSuggestionRequiresRevalidation, t as DEFAULT_WORKSPACE_SETTINGS, ui as PrReviewSuggestionRevisionPage, ut as GovernedActionPolicyEvaluationV1, v as RelationshipRepairApplication, vr as ReadinessRuleId, vt as PortfolioInvalidatedPayloadV1, w as RelationshipRepairReviewDecision, wr as ReadinessVerdict, wt as DeliveryEntityStatusGroup, x as RelationshipRepairProposalOrigin, xt as DeliveryEntityKind, y as RelationshipRepairDisposition, zn as RoleAssignment } from "./workspaceSettings-BE713Oe8.js";
2
- import { $ as SourceRevision, At as SessionId, Ct as RelationshipId, Dt as ReviewCommandArtifactId, Et as ReleaseId, K as MaximumPluginPayloadBytes, Mt as WorkspaceId, N as NormalizedPluginEventV1, Nt as WorkspaceSettingsMutationId, Ot as ReviewSuggestionPublicationReservationId, Q as Revision$1, S as PluginProviderOperationId, St as ReadinessAssessmentId, Tt as RelationshipRepairReviewId, X as NormalizationSchemaVersion, Y as hasMaximumPluginJsonBytes, Z as ProviderId, _t as JobId, at as DomainEventId, bt as PrReviewSuggestionRevisionId, c as SemanticVersion, ct as EventCursor, dt as FollowedResourceId, et as SourceUrl, ft as GovernedActionAttemptId, g as PluginActionPayloadDigest, gt as GraphNodeId, h as PluginActionDispatchResultV1, ht as GovernedActionTransitionId, it as AgentThreadId, jt as ShareId, kt as RoleAssignmentId, lt as EvidenceClaimId, mt as GovernedActionId, n as NegotiatedPluginDescriptorV1, nt as UtcTimestamp, o as PluginDescriptorV1, ot as EntityId, pt as GovernedActionAuthorizationId, rt as AgentId, st as EnvironmentId, tt as VendorImmutableId, ut as EvidenceId, vt as PersonId, wt as RelationshipRepairProposalId, xt as ProviderAccountId, y as PluginActionReconciliationKey, yt as PluginConnectionId } from "./descriptor-CKtTnhef.js";
3
- import { V as ReviewAgentProfile } from "./agent-CyZ40zs1.js";
4
- import { a as ReleaseReadinessCandidateMaterial, c as normalizeReadinessRuleMaterial, i as ReadinessRuleMaterial, l as normalizeReleaseReadinessCandidateMaterial, n as summarizeEnvironmentReadiness, r as EnvironmentReadinessCandidateMaterial, s as normalizeEnvironmentReadinessCandidateMaterial, u as AuthorizedShareGrant } from "./readiness-BhA-Nr9c.js";
5
- import { d as PluginUnsupportedCapabilityFailure, o as PluginMalformedResponseFailure } from "./failures-mgYDkUZy.js";
1
+ import { $n as PrReviewSuggestionEdit, A as DeliveryNode, Ai as PortfolioInvalidatedPayloadV1, Ar as PrReviewSuggestionId, B as LedgerRevision, Bi as RoleAssignment, Br as GovernedActionCommandId, C as RelationshipRepairReview, Cr as PrReviewReport, D as DeliveryEntityProjection, Di as DomainEventMetadataV1, E as DeliveryEntityKind, Ei as DomainEventCorrelationId, Fr as reconcilePrReviewReports, Gr as GovernedActionTransitionCommand, Hi as derivePersonInitials, Ii as Person, Ir as GovernedActionLifecycleHeadV1, Jn as PluginHealth, Jr as GovernedActionTransitionV1, Jt as ReadinessCandidateDigest, Kn as Freshness, Kr as GovernedActionTransitionDigest, Kt as ReadinessArtifactRevision, L as EvidenceValue, Li as PersonAvatar, Lr as GovernedActionProviderLineage, Lt as EnvironmentReadinessAssessment, Mi as Actor, N as EvidenceClaim, O as DeliveryEntityService, P as EvidenceItem, Qn as PrReviewSuggestionAgentAuthor, Ri as PersonSourceIdentity, Rr as advanceGovernedActionLifecycle, S as RelationshipRepairRationale, Tr as PrReviewSuggestion, U as RelationshipEndpointKind, Ur as GovernedActionState, Wr as GovernedActionTransitionCause, Xt as ReadinessDerivationVersion, Yr as GovernedActionUnknownOutcome, a as WorkspaceSettingsSections, ai as GovernedActionAttemptDigest, ar as PrReviewSuggestionRevisionPageSize, b as RelationshipRepairProposal, bi as GovernedActionPolicyEvaluationDigest, bt as Release, c as isGovernedWorkspaceSettingsSection, ci as GovernedActionAuthorizationV1, cr as PrReviewSuggestionValidated, di as GovernedActionEnvelopeV1, fn as ReadinessRuleId, hi as GovernedActionIdempotencyKey, ii as governedActionPermissionGrants, ir as PrReviewSuggestionRevisionPage, j as DeliveryRelationship, k as DeliveryEntityStatusGroup, ki as PortfolioInvalidatedEventV1, l as TimelineActorKind, li as GovernedActionEnvelopeDigest, lr as hasSamePrReviewTechnicalClaim, mi as GovernedActionEvidenceSetDigest, mn as ReadinessRuleVersion, ni as governedActionAuthorizationMatchesTransition, nr as PrReviewSuggestionRevision, o as WorkspaceSettingsV1, oi as GovernedActionAttemptV1, or as PrReviewSuggestionRevisionSequence, pi as GovernedActionEvidenceSet, qt as ReadinessAssessment, r as GovernedWorkspaceSettingsSections, ri as governedActionAuthorizationMismatches, rr as PrReviewSuggestionRevisionAuthor, s as changedWorkspaceSettingsSections, si as GovernedActionAuthorizationDigest, t as DEFAULT_WORKSPACE_SETTINGS, ti as governedActionAuthorityMismatches, tr as PrReviewSuggestionRequiresRevalidation, ui as GovernedActionEnvelopeMaterialV1, v as RelationshipRepairApplication, vn as ReadinessVerdict, w as RelationshipRepairReviewDecision, wr as PrReviewSubject, x as RelationshipRepairProposalOrigin, xi as GovernedActionPolicyEvaluationV1, y as RelationshipRepairDisposition, yi as GovernedActionPolicyDigest, yn as ReleaseReadinessAssessment, zi as Role, zr as GovernedActionCommandDigest } from "./workspaceSettings-C2Zsk6RI.js";
2
+ import { $ as SourceRevision, At as ShareId, Ct as RelationshipRepairProposalId, Dt as ReviewSuggestionPublicationReservationId, Et as ReviewCommandArtifactId, K as MaximumPluginPayloadBytes, Mt as WorkspaceSettingsMutationId, N as NormalizedPluginEventV1, Nt as UtcTimestamp, Ot as RoleAssignmentId, Q as Revision$1, S as PluginProviderOperationId, St as RelationshipId, Tt as ReleaseId, X as NormalizationSchemaVersion, Y as hasMaximumPluginJsonBytes, Z as ProviderId, _t as PersonId, at as EntityId, bt as ProviderAccountId, c as SemanticVersion, ct as EvidenceClaimId, dt as GovernedActionAttemptId, et as SourceUrl, ft as GovernedActionAuthorizationId, g as PluginActionPayloadDigest, gt as JobId, h as PluginActionDispatchResultV1, ht as GraphNodeId, it as DomainEventId, jt as WorkspaceId, kt as SessionId, lt as EvidenceId, mt as GovernedActionTransitionId, n as NegotiatedPluginDescriptorV1, nt as AgentId, o as PluginDescriptorV1, ot as EnvironmentId, pt as GovernedActionId, rt as AgentThreadId, st as EventCursor, tt as VendorImmutableId, ut as FollowedResourceId, vt as PluginConnectionId, wt as RelationshipRepairReviewId, xt as ReadinessAssessmentId, y as PluginActionReconciliationKey, yt as PrReviewSuggestionRevisionId } from "./descriptor-CCvNzSZL.js";
3
+ import { U as ReviewAgentProfile, q as ReviewSuggestionPublicationOperation } from "./agent-ZvwskOQu.js";
4
+ import { a as ReleaseReadinessCandidateMaterial, c as normalizeReadinessRuleMaterial, i as ReadinessRuleMaterial, l as normalizeReleaseReadinessCandidateMaterial, n as summarizeEnvironmentReadiness, r as EnvironmentReadinessCandidateMaterial, s as normalizeEnvironmentReadinessCandidateMaterial, u as AuthorizedShareGrant } from "./readiness-BtntBhDj.js";
5
+ import { d as PluginUnsupportedCapabilityFailure, o as PluginMalformedResponseFailure } from "./failures-CesHLYbN.js";
6
6
  import { AgentContextFingerprint, AgentProviderError, AgentProviderId, AgentRuntimeEvent, AgentSessionRef, MAXIMUM_AGENT_RUNTIME_EVENT_BYTES } from "@knpkv/ai-runtime";
7
7
  import * as Effect$1 from "effect/Effect";
8
8
  import * as Schema$1 from "effect/Schema";
9
- import { Cause, Context, Crypto, Effect, FileSystem, Layer, Option, Path, Predicate, Result, Schema, Semaphore, Stream } from "effect";
10
9
  import * as DateTime$1 from "effect/DateTime";
10
+ import { Cause, Context, Crypto, Effect, FileSystem, Layer, Option, Path, Predicate, Result, Schema, Semaphore, Stream } from "effect";
11
11
  import * as Encoding$1 from "effect/Encoding";
12
12
  import * as Result$1 from "effect/Result";
13
+ import * as SchemaGetter from "effect/SchemaGetter";
13
14
  import * as Context$1 from "effect/Context";
14
15
  import * as Layer$1 from "effect/Layer";
15
16
  import * as Option$1 from "effect/Option";
@@ -221,7 +222,7 @@ var schema_default = {
221
222
  {
222
223
  "type": "table",
223
224
  "name": "agent_review_suggestion_publications",
224
- "sql": "CREATE TABLE agent_review_suggestion_publications (\n workspace_id TEXT NOT NULL,\n job_id TEXT NOT NULL,\n suggestion_id TEXT NOT NULL CHECK(\n length(suggestion_id) = 71 AND suggestion_id GLOB 'sha256:*'\n AND substr(suggestion_id, 8) NOT GLOB '*[^0-9a-f]*'\n ),\n revision_id TEXT NOT NULL CHECK(\n length(revision_id) = 71 AND revision_id GLOB 'sha256:*'\n AND substr(revision_id, 8) NOT GLOB '*[^0-9a-f]*'\n ),\n content_digest TEXT NOT NULL CHECK(\n length(content_digest) = 71 AND content_digest GLOB 'sha256:*'\n AND substr(content_digest, 8) NOT GLOB '*[^0-9a-f]*'\n ),\n state TEXT NOT NULL CHECK(state IN ('reserved', 'published')),\n publication_id TEXT,\n reservation_id TEXT NOT NULL,\n reservation_acquired_at TEXT NOT NULL,\n reserved_at TEXT NOT NULL,\n published_at TEXT,\n PRIMARY KEY (workspace_id, job_id, suggestion_id, revision_id),\n FOREIGN KEY (workspace_id, job_id)\n REFERENCES agent_jobs(workspace_id, job_id)\n ON DELETE RESTRICT,\n CHECK(reserved_at <= reservation_acquired_at),\n CHECK(\n (state = 'reserved' AND (\n (publication_id IS NULL AND published_at IS NULL) OR\n (publication_id IS NOT NULL AND published_at IS NOT NULL AND reserved_at <= published_at)\n )) OR\n (state = 'published' AND publication_id IS NOT NULL AND published_at IS NOT NULL\n AND reserved_at <= published_at)\n )\n )"
225
+ "sql": "CREATE TABLE agent_review_suggestion_publications (\n workspace_id TEXT NOT NULL,\n job_id TEXT NOT NULL,\n suggestion_id TEXT NOT NULL CHECK(\n length(suggestion_id) = 71 AND suggestion_id GLOB 'sha256:*'\n AND substr(suggestion_id, 8) NOT GLOB '*[^0-9a-f]*'\n ),\n revision_id TEXT NOT NULL CHECK(\n length(revision_id) = 71 AND revision_id GLOB 'sha256:*'\n AND substr(revision_id, 8) NOT GLOB '*[^0-9a-f]*'\n ),\n content_digest TEXT NOT NULL CHECK(\n length(content_digest) = 71 AND content_digest GLOB 'sha256:*'\n AND substr(content_digest, 8) NOT GLOB '*[^0-9a-f]*'\n ),\n state TEXT NOT NULL CHECK(state IN ('reserved', 'published')),\n publication_id TEXT,\n comment_id TEXT CHECK(comment_id IS NULL OR length(comment_id) BETWEEN 1 AND 512),\n previous_content_digest TEXT CHECK(previous_content_digest IS NULL OR (length(previous_content_digest) = 71 AND previous_content_digest GLOB 'sha256:*' AND substr(previous_content_digest, 8) NOT GLOB '*[^0-9a-f]*')),\n previous_publication_id TEXT CHECK(previous_publication_id IS NULL OR length(previous_publication_id) BETWEEN 1 AND 512),\n previous_published_at TEXT,\n reservation_id TEXT NOT NULL,\n reservation_acquired_at TEXT NOT NULL,\n reserved_at TEXT NOT NULL,\n published_at TEXT,\n CHECK((previous_content_digest IS NULL AND previous_publication_id IS NULL AND previous_published_at IS NULL) OR (previous_content_digest IS NOT NULL AND previous_publication_id IS NOT NULL AND previous_published_at IS NOT NULL AND state = 'reserved')),\n PRIMARY KEY (workspace_id, job_id, suggestion_id, revision_id),\n FOREIGN KEY (workspace_id, job_id)\n REFERENCES agent_jobs(workspace_id, job_id)\n ON DELETE RESTRICT,\n CHECK(reserved_at <= reservation_acquired_at),\n CHECK(\n (state = 'reserved' AND (\n (publication_id IS NULL AND published_at IS NULL) OR\n (publication_id IS NOT NULL AND published_at IS NOT NULL AND reserved_at <= published_at)\n )) OR\n (state = 'published' AND publication_id IS NOT NULL AND published_at IS NOT NULL\n AND reserved_at <= published_at)\n )\n )"
225
226
  },
226
227
  {
227
228
  "type": "table",
@@ -328,6 +329,11 @@ var schema_default = {
328
329
  "name": "governed_action_denial_policy_evaluations",
329
330
  "sql": "CREATE TABLE governed_action_denial_policy_evaluations (\n workspace_id TEXT NOT NULL,\n action_id TEXT NOT NULL,\n transition_id TEXT NOT NULL,\n policy_evaluation_digest TEXT NOT NULL,\n PRIMARY KEY (workspace_id, action_id, transition_id),\n UNIQUE (workspace_id, action_id, policy_evaluation_digest),\n FOREIGN KEY (workspace_id, action_id, transition_id)\n REFERENCES governed_action_transitions(workspace_id, action_id, transition_id),\n FOREIGN KEY (workspace_id, action_id, policy_evaluation_digest)\n REFERENCES governed_action_policy_evaluations(workspace_id, action_id, evaluation_digest)\n )"
330
331
  },
332
+ {
333
+ "type": "table",
334
+ "name": "governed_action_entity_targets",
335
+ "sql": "CREATE TABLE governed_action_entity_targets (\n workspace_id TEXT NOT NULL,\n action_id TEXT NOT NULL,\n plugin_connection_id TEXT NOT NULL,\n provider_id TEXT NOT NULL CHECK(provider_id IN (\n 'codecommit', 'codepipeline', 'jira', 'confluence', 'clockify'\n )),\n entity_id TEXT NOT NULL,\n PRIMARY KEY (workspace_id, action_id),\n FOREIGN KEY (workspace_id, action_id)\n REFERENCES governed_actions(workspace_id, action_id)\n ON DELETE RESTRICT,\n FOREIGN KEY (workspace_id, entity_id, plugin_connection_id, provider_id)\n REFERENCES entities(workspace_id, entity_id, plugin_connection_id, provider_id)\n ON DELETE RESTRICT\n )"
336
+ },
331
337
  {
332
338
  "type": "table",
333
339
  "name": "governed_action_execution_leases",
@@ -368,6 +374,16 @@ var schema_default = {
368
374
  "name": "governed_action_recovery_claims",
369
375
  "sql": "CREATE TABLE governed_action_recovery_claims (\n workspace_id TEXT NOT NULL,\n action_id TEXT NOT NULL,\n claim_sequence INTEGER NOT NULL CHECK(claim_sequence >= 1),\n claim_token_digest TEXT NOT NULL CHECK(\n length(claim_token_digest) = 64 AND claim_token_digest NOT GLOB '*[^0-9a-f]*'\n ),\n claimed_at TEXT NOT NULL,\n lease_expires_at TEXT NOT NULL,\n PRIMARY KEY (workspace_id, action_id, claim_sequence),\n UNIQUE (claim_token_digest),\n UNIQUE (workspace_id, action_id, claim_token_digest),\n FOREIGN KEY (workspace_id, action_id)\n REFERENCES governed_action_execution_leases(workspace_id, action_id),\n CHECK(claimed_at < lease_expires_at)\n )"
370
376
  },
377
+ {
378
+ "type": "table",
379
+ "name": "governed_action_release_publication_slots",
380
+ "sql": "CREATE TABLE governed_action_release_publication_slots (\n workspace_id TEXT NOT NULL,\n action_id TEXT NOT NULL,\n provider_id TEXT NOT NULL CHECK(provider_id = 'confluence'),\n release_id TEXT NOT NULL CHECK(length(release_id) = 36),\n predecessor_action_id TEXT CHECK(\n predecessor_action_id IS NULL OR length(predecessor_action_id) = 36\n ),\n PRIMARY KEY (workspace_id, action_id),\n FOREIGN KEY (workspace_id, action_id)\n REFERENCES governed_action_release_publications(workspace_id, action_id)\n ON DELETE RESTRICT\n )"
381
+ },
382
+ {
383
+ "type": "table",
384
+ "name": "governed_action_release_publications",
385
+ "sql": "CREATE TABLE governed_action_release_publications (\n workspace_id TEXT NOT NULL,\n action_id TEXT NOT NULL,\n provider_id TEXT NOT NULL CHECK(provider_id IN (\n 'codecommit', 'codepipeline', 'jira', 'confluence', 'clockify'\n )),\n release_id TEXT NOT NULL CHECK(length(release_id) = 36),\n predecessor_action_id TEXT CHECK(\n predecessor_action_id IS NULL OR length(predecessor_action_id) = 36\n ),\n PRIMARY KEY (workspace_id, action_id),\n FOREIGN KEY (workspace_id, action_id)\n REFERENCES governed_actions(workspace_id, action_id)\n ON DELETE RESTRICT,\n FOREIGN KEY (workspace_id, release_id)\n REFERENCES releases(workspace_id, release_id)\n ON DELETE RESTRICT\n )"
386
+ },
371
387
  {
372
388
  "type": "table",
373
389
  "name": "governed_action_target_dimensions",
@@ -381,7 +397,7 @@ var schema_default = {
381
397
  {
382
398
  "type": "table",
383
399
  "name": "governed_actions",
384
- "sql": "CREATE TABLE governed_actions (\n workspace_id TEXT NOT NULL,\n action_id TEXT NOT NULL,\n plugin_connection_id TEXT NOT NULL,\n provider_id TEXT NOT NULL CHECK(provider_id IN (\n 'codecommit', 'codepipeline', 'jira', 'confluence', 'clockify'\n )),\n target_entity_id TEXT NOT NULL,\n idempotency_key TEXT NOT NULL CHECK(length(idempotency_key) BETWEEN 1 AND 512),\n envelope_digest TEXT NOT NULL CHECK(\n length(envelope_digest) = 71 AND envelope_digest GLOB 'sha256:*'\n AND substr(envelope_digest, 8) NOT GLOB '*[^0-9a-f]*'\n ),\n envelope_json TEXT NOT NULL CHECK(length(envelope_json) BETWEEN 2 AND 1048576),\n state TEXT CHECK(state IN (\n 'proposed', 'authorized', 'denied', 'expired', 'cancelled', 'started',\n 'cancel-requested', 'cancel-requested-unknown', 'succeeded', 'failed', 'unknown'\n )),\n lineage_json TEXT CHECK(lineage_json IS NULL OR length(lineage_json) BETWEEN 2 AND 65536),\n lineage_kind TEXT CHECK(lineage_kind IS NULL OR lineage_kind IN (\n 'none', 'accepted', 'reconcilable', 'manual', 'terminal'\n )),\n provider_operation_id TEXT CHECK(\n provider_operation_id IS NULL OR length(provider_operation_id) BETWEEN 1 AND 512\n ),\n reconciliation_key TEXT CHECK(\n reconciliation_key IS NULL OR length(reconciliation_key) BETWEEN 1 AND 512\n ),\n terminal_status TEXT CHECK(\n terminal_status IS NULL OR terminal_status IN ('succeeded', 'failed', 'cancelled')\n ),\n head_transition_id TEXT,\n head_sequence INTEGER CHECK(head_sequence IS NULL OR head_sequence >= 1),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (workspace_id, action_id),\n UNIQUE (workspace_id, plugin_connection_id, idempotency_key),\n UNIQUE (workspace_id, action_id, envelope_digest),\n FOREIGN KEY (workspace_id) REFERENCES workspaces(workspace_id),\n FOREIGN KEY (workspace_id, plugin_connection_id, provider_id)\n REFERENCES plugin_connections(workspace_id, plugin_connection_id, provider_id),\n FOREIGN KEY (workspace_id, target_entity_id, plugin_connection_id, provider_id)\n REFERENCES entities(workspace_id, entity_id, plugin_connection_id, provider_id),\n CHECK(created_at <= updated_at),\n CHECK(\n (state IS NULL AND lineage_json IS NULL AND lineage_kind IS NULL\n AND provider_operation_id IS NULL AND reconciliation_key IS NULL AND terminal_status IS NULL\n AND head_transition_id IS NULL AND head_sequence IS NULL) OR\n (state IS NOT NULL AND lineage_json IS NOT NULL AND lineage_kind IS NOT NULL\n AND head_transition_id IS NOT NULL AND head_sequence IS NOT NULL)\n ),\n CHECK(\n lineage_kind IS NULL OR\n (lineage_kind = 'none' AND provider_operation_id IS NULL\n AND reconciliation_key IS NULL AND terminal_status IS NULL) OR\n (lineage_kind = 'accepted' AND provider_operation_id IS NOT NULL\n AND reconciliation_key IS NOT NULL AND terminal_status IS NULL) OR\n (lineage_kind = 'reconcilable' AND reconciliation_key IS NOT NULL\n AND terminal_status IS NULL) OR\n (lineage_kind = 'manual' AND reconciliation_key IS NULL AND terminal_status IS NULL) OR\n (lineage_kind = 'terminal' AND provider_operation_id IS NOT NULL\n AND reconciliation_key IS NULL AND terminal_status IS NOT NULL)\n ),\n CHECK(\n state IS NULL OR\n (state IN ('proposed', 'authorized', 'denied', 'expired') AND lineage_kind = 'none') OR\n (state = 'cancelled' AND (\n lineage_kind = 'none' OR (lineage_kind = 'terminal' AND terminal_status = 'cancelled')\n )) OR\n (state IN ('started', 'cancel-requested') AND lineage_kind IN ('none', 'accepted')) OR\n (state IN ('unknown', 'cancel-requested-unknown')\n AND lineage_kind IN ('reconcilable', 'manual')) OR\n (state = 'succeeded' AND lineage_kind = 'terminal' AND terminal_status = 'succeeded') OR\n (state = 'failed' AND lineage_kind = 'terminal' AND terminal_status = 'failed')\n )\n )"
400
+ "sql": "CREATE TABLE governed_actions (\n workspace_id TEXT NOT NULL,\n action_id TEXT NOT NULL,\n plugin_connection_id TEXT NOT NULL,\n provider_id TEXT NOT NULL CHECK(provider_id IN (\n 'codecommit', 'codepipeline', 'jira', 'confluence', 'clockify'\n )),\n target_entity_id TEXT NOT NULL,\n idempotency_key TEXT NOT NULL CHECK(length(idempotency_key) BETWEEN 1 AND 512),\n envelope_digest TEXT NOT NULL CHECK(\n length(envelope_digest) = 71 AND envelope_digest GLOB 'sha256:*'\n AND substr(envelope_digest, 8) NOT GLOB '*[^0-9a-f]*'\n ),\n envelope_json TEXT NOT NULL CHECK(length(envelope_json) BETWEEN 2 AND 1048576),\n state TEXT CHECK(state IN (\n 'proposed', 'authorized', 'denied', 'expired', 'cancelled', 'started',\n 'cancel-requested', 'cancel-requested-unknown', 'succeeded', 'failed', 'unknown'\n )),\n lineage_json TEXT CHECK(lineage_json IS NULL OR length(lineage_json) BETWEEN 2 AND 65536),\n lineage_kind TEXT CHECK(lineage_kind IS NULL OR lineage_kind IN (\n 'none', 'accepted', 'reconcilable', 'manual', 'terminal'\n )),\n provider_operation_id TEXT CHECK(\n provider_operation_id IS NULL OR length(provider_operation_id) BETWEEN 1 AND 512\n ),\n reconciliation_key TEXT CHECK(\n reconciliation_key IS NULL OR length(reconciliation_key) BETWEEN 1 AND 512\n ),\n terminal_status TEXT CHECK(\n terminal_status IS NULL OR terminal_status IN ('succeeded', 'failed', 'cancelled')\n ),\n head_transition_id TEXT,\n head_sequence INTEGER CHECK(head_sequence IS NULL OR head_sequence >= 1),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n PRIMARY KEY (workspace_id, action_id),\n UNIQUE (workspace_id, plugin_connection_id, idempotency_key),\n UNIQUE (workspace_id, action_id, envelope_digest),\n FOREIGN KEY (workspace_id) REFERENCES workspaces(workspace_id),\n FOREIGN KEY (workspace_id, plugin_connection_id, provider_id)\n REFERENCES plugin_connections(workspace_id, plugin_connection_id, provider_id),\n CHECK(created_at <= updated_at),\n CHECK(\n (state IS NULL AND lineage_json IS NULL AND lineage_kind IS NULL\n AND provider_operation_id IS NULL AND reconciliation_key IS NULL AND terminal_status IS NULL\n AND head_transition_id IS NULL AND head_sequence IS NULL) OR\n (state IS NOT NULL AND lineage_json IS NOT NULL AND lineage_kind IS NOT NULL\n AND head_transition_id IS NOT NULL AND head_sequence IS NOT NULL)\n ),\n CHECK(\n lineage_kind IS NULL OR\n (lineage_kind = 'none' AND provider_operation_id IS NULL\n AND reconciliation_key IS NULL AND terminal_status IS NULL) OR\n (lineage_kind = 'accepted' AND provider_operation_id IS NOT NULL\n AND reconciliation_key IS NOT NULL AND terminal_status IS NULL) OR\n (lineage_kind = 'reconcilable' AND reconciliation_key IS NOT NULL\n AND terminal_status IS NULL) OR\n (lineage_kind = 'manual' AND reconciliation_key IS NULL AND terminal_status IS NULL) OR\n (lineage_kind = 'terminal' AND provider_operation_id IS NOT NULL\n AND reconciliation_key IS NULL AND terminal_status IS NOT NULL)\n ),\n CHECK(\n state IS NULL OR\n (state IN ('proposed', 'authorized', 'denied', 'expired') AND lineage_kind = 'none') OR\n (state = 'cancelled' AND (\n lineage_kind = 'none' OR (lineage_kind = 'terminal' AND terminal_status = 'cancelled')\n )) OR\n (state IN ('started', 'cancel-requested') AND lineage_kind IN ('none', 'accepted')) OR\n (state IN ('unknown', 'cancel-requested-unknown')\n AND lineage_kind IN ('reconcilable', 'manual')) OR\n (state = 'succeeded' AND lineage_kind = 'terminal' AND terminal_status = 'succeeded') OR\n (state = 'failed' AND lineage_kind = 'terminal' AND terminal_status = 'failed')\n )\n )"
385
401
  },
386
402
  {
387
403
  "type": "table",
@@ -656,7 +672,7 @@ var schema_default = {
656
672
  {
657
673
  "type": "index",
658
674
  "name": "agent_thread_events_review_result_idx",
659
- "sql": "CREATE UNIQUE INDEX agent_thread_events_review_result_idx\n ON agent_thread_events(workspace_id, job_id)\n WHERE event_kind = 'review-report'"
675
+ "sql": "CREATE INDEX agent_thread_events_review_result_idx\n ON agent_thread_events(workspace_id, job_id, event_sequence DESC)\n WHERE event_kind = 'review-report'"
660
676
  },
661
677
  {
662
678
  "type": "index",
@@ -778,6 +794,16 @@ var schema_default = {
778
794
  "name": "governed_action_recovery_claim_expiry_idx",
779
795
  "sql": "CREATE INDEX governed_action_recovery_claim_expiry_idx\n ON governed_action_recovery_claims(lease_expires_at, workspace_id, action_id, claim_sequence)"
780
796
  },
797
+ {
798
+ "type": "index",
799
+ "name": "governed_action_release_publication_slots_unique_idx",
800
+ "sql": "CREATE UNIQUE INDEX governed_action_release_publication_slots_unique_idx\n ON governed_action_release_publication_slots(\n workspace_id, provider_id, release_id, COALESCE(predecessor_action_id, '')\n )"
801
+ },
802
+ {
803
+ "type": "index",
804
+ "name": "governed_action_release_publications_lookup_idx",
805
+ "sql": "CREATE INDEX governed_action_release_publications_lookup_idx\n ON governed_action_release_publications(\n workspace_id, provider_id, release_id, action_id DESC\n )"
806
+ },
781
807
  {
782
808
  "type": "index",
783
809
  "name": "governed_action_target_dimensions_lookup_idx",
@@ -1203,6 +1229,21 @@ var schema_default = {
1203
1229
  "name": "governed_action_denial_policy_exact_owner",
1204
1230
  "sql": "CREATE TRIGGER governed_action_denial_policy_exact_owner\n BEFORE INSERT ON governed_action_denial_policy_evaluations\n WHEN NOT EXISTS (\n SELECT 1\n FROM governed_action_transitions transition_record\n JOIN governed_action_policy_evaluations evaluation\n ON evaluation.workspace_id = NEW.workspace_id\n AND evaluation.action_id = NEW.action_id\n AND evaluation.evaluation_digest = NEW.policy_evaluation_digest\n WHERE transition_record.workspace_id = NEW.workspace_id\n AND transition_record.action_id = NEW.action_id\n AND transition_record.transition_id = NEW.transition_id\n AND transition_record.command_tag = 'deny'\n AND evaluation.decision = 'denied'\n AND evaluation.evaluated_at <= transition_record.occurred_at\n AND NOT EXISTS (\n SELECT 1\n FROM audit_events audit\n WHERE audit.workspace_id = transition_record.workspace_id\n AND audit.action_id = transition_record.action_id\n AND audit.transition_id = transition_record.transition_id\n )\n )\n BEGIN\n SELECT RAISE(ABORT, 'denial policy evaluation must belong to its exact deny transition');\n END"
1205
1231
  },
1232
+ {
1233
+ "type": "trigger",
1234
+ "name": "governed_action_entity_targets_exact",
1235
+ "sql": "CREATE TRIGGER governed_action_entity_targets_exact\n BEFORE INSERT ON governed_action_entity_targets\n WHEN NOT EXISTS (\n SELECT 1 FROM governed_actions action\n WHERE action.workspace_id = NEW.workspace_id\n AND action.action_id = NEW.action_id\n AND action.plugin_connection_id = NEW.plugin_connection_id\n AND action.provider_id = NEW.provider_id\n AND action.target_entity_id = NEW.entity_id\n AND json_type(action.envelope_json, '$.releasePublication') IS NULL\n )\n BEGIN\n SELECT RAISE(ABORT, 'governed action entity target must match the immutable envelope');\n END"
1236
+ },
1237
+ {
1238
+ "type": "trigger",
1239
+ "name": "governed_action_entity_targets_no_delete",
1240
+ "sql": "CREATE TRIGGER governed_action_entity_targets_no_delete\n BEFORE DELETE ON governed_action_entity_targets\n BEGIN\n SELECT RAISE(ABORT, 'governed action entity targets are immutable');\n END"
1241
+ },
1242
+ {
1243
+ "type": "trigger",
1244
+ "name": "governed_action_entity_targets_no_update",
1245
+ "sql": "CREATE TRIGGER governed_action_entity_targets_no_update\n BEFORE UPDATE ON governed_action_entity_targets\n BEGIN\n SELECT RAISE(ABORT, 'governed action entity targets are immutable');\n END"
1246
+ },
1206
1247
  {
1207
1248
  "type": "trigger",
1208
1249
  "name": "governed_action_execution_lease_exact_start",
@@ -1338,6 +1379,36 @@ var schema_default = {
1338
1379
  "name": "governed_action_recovery_claims_no_update",
1339
1380
  "sql": "CREATE TRIGGER governed_action_recovery_claims_no_update\n BEFORE UPDATE ON governed_action_recovery_claims\n BEGIN\n SELECT RAISE(ABORT, 'governed_action_recovery_claims is immutable');\n END"
1340
1381
  },
1382
+ {
1383
+ "type": "trigger",
1384
+ "name": "governed_action_release_publication_slots_exact",
1385
+ "sql": "CREATE TRIGGER governed_action_release_publication_slots_exact\n BEFORE INSERT ON governed_action_release_publication_slots\n WHEN NOT EXISTS (\n SELECT 1 FROM governed_action_release_publications publication\n WHERE publication.workspace_id = NEW.workspace_id\n AND publication.action_id = NEW.action_id\n AND publication.provider_id = NEW.provider_id\n AND publication.release_id = NEW.release_id\n AND publication.predecessor_action_id IS NEW.predecessor_action_id\n )\n BEGIN\n SELECT RAISE(ABORT, 'governed action release publication slot must match immutable publication history');\n END"
1386
+ },
1387
+ {
1388
+ "type": "trigger",
1389
+ "name": "governed_action_release_publication_slots_release",
1390
+ "sql": "CREATE TRIGGER governed_action_release_publication_slots_release\n AFTER UPDATE OF state ON governed_actions\n WHEN NEW.state IN ('denied', 'expired', 'cancelled', 'failed')\n BEGIN\n DELETE FROM governed_action_release_publication_slots\n WHERE workspace_id = NEW.workspace_id AND action_id = NEW.action_id;\n END"
1391
+ },
1392
+ {
1393
+ "type": "trigger",
1394
+ "name": "governed_action_release_publications_exact",
1395
+ "sql": "CREATE TRIGGER governed_action_release_publications_exact\n BEFORE INSERT ON governed_action_release_publications\n WHEN NOT EXISTS (\n SELECT 1 FROM governed_actions action\n WHERE action.workspace_id = NEW.workspace_id\n AND action.action_id = NEW.action_id\n AND action.provider_id = NEW.provider_id\n AND json_extract(action.envelope_json, '$.releasePublication.releaseId') = NEW.release_id\n AND json_extract(action.envelope_json, '$.releasePublication.predecessorPublicationActionId') IS NEW.predecessor_action_id\n )\n BEGIN\n SELECT RAISE(ABORT, 'governed action release publication must match the immutable envelope');\n END"
1396
+ },
1397
+ {
1398
+ "type": "trigger",
1399
+ "name": "governed_action_release_publications_no_delete",
1400
+ "sql": "CREATE TRIGGER governed_action_release_publications_no_delete\n BEFORE DELETE ON governed_action_release_publications\n BEGIN\n SELECT RAISE(ABORT, 'governed action release publications are immutable');\n END"
1401
+ },
1402
+ {
1403
+ "type": "trigger",
1404
+ "name": "governed_action_release_publications_no_update",
1405
+ "sql": "CREATE TRIGGER governed_action_release_publications_no_update\n BEFORE UPDATE ON governed_action_release_publications\n BEGIN\n SELECT RAISE(ABORT, 'governed action release publications are immutable');\n END"
1406
+ },
1407
+ {
1408
+ "type": "trigger",
1409
+ "name": "governed_action_target_authority_exact",
1410
+ "sql": "CREATE TRIGGER governed_action_target_authority_exact\n BEFORE INSERT ON governed_actions\n WHEN NOT EXISTS (\n SELECT 1 FROM entities entity\n WHERE entity.workspace_id = NEW.workspace_id\n AND entity.entity_id = NEW.target_entity_id\n AND entity.plugin_connection_id = NEW.plugin_connection_id\n AND entity.provider_id = NEW.provider_id\n ) AND NOT (\n json_valid(NEW.envelope_json)\n AND json_extract(NEW.envelope_json, '$.releasePublication.releaseId') = NEW.target_entity_id\n AND (\n (\n NEW.provider_id = 'jira'\n AND json_extract(NEW.envelope_json, '$.proposal.request.actionKind') = 'create-release-version'\n AND json_extract(NEW.envelope_json, '$.proposal.request.target.entityType') = 'jira.project-version'\n ) OR (\n NEW.provider_id = 'confluence'\n AND (\n (\n json_extract(NEW.envelope_json, '$.proposal.request.actionKind') = 'create-page'\n AND json_extract(NEW.envelope_json, '$.proposal.request.target.entityType') = 'release-page'\n ) OR (\n json_extract(NEW.envelope_json, '$.proposal.request.actionKind') = 'update-page'\n AND json_extract(NEW.envelope_json, '$.proposal.request.target.entityType') = 'page'\n )\n )\n )\n )\n AND EXISTS (\n SELECT 1 FROM releases release\n WHERE release.workspace_id = NEW.workspace_id\n AND release.release_id = NEW.target_entity_id\n )\n )\n BEGIN\n SELECT RAISE(ABORT, 'governed action target must be an exact entity or supported release publication');\n END"
1411
+ },
1341
1412
  {
1342
1413
  "type": "trigger",
1343
1414
  "name": "governed_action_target_dimensions_exact",
@@ -1868,13 +1939,13 @@ var configureAndVerifyPragmas = Effect.fn("Database.configureAndVerifyPragmas")(
1868
1939
  yield* sql`PRAGMA foreign_keys = ON`;
1869
1940
  yield* sql`PRAGMA journal_mode = WAL`;
1870
1941
  yield* sql`PRAGMA busy_timeout = 5000`;
1871
- }).pipe(Effect.catchCause(() => new DatabaseInitializationError({ operation: "configure" })));
1942
+ }).pipe(Effect.mapError(() => new DatabaseInitializationError({ operation: "configure" })));
1872
1943
  yield* Effect.gen(function* () {
1873
1944
  const foreignKeys = yield* sql`PRAGMA foreign_keys`.pipe(Effect.flatMap((rows) => decodeRows$4(ForeignKeysPragmaRow, rows)));
1874
1945
  const journalMode = yield* sql`PRAGMA journal_mode`.pipe(Effect.flatMap((rows) => decodeRows$4(JournalModePragmaRow, rows)));
1875
1946
  const busyTimeout = yield* sql`PRAGMA busy_timeout`.pipe(Effect.flatMap((rows) => decodeRows$4(BusyTimeoutPragmaRow, rows)));
1876
1947
  if (foreignKeys.length !== 1 || foreignKeys[0]?.foreignKeys !== 1 || journalMode.length !== 1 || journalMode[0]?.journalMode.toLowerCase() !== "wal" || busyTimeout.length !== 1 || busyTimeout[0]?.timeout !== 5e3) return yield* Effect.fail("SQLite pragmas did not retain their required values");
1877
- }).pipe(Effect.catchCause(() => new DatabaseInitializationError({ operation: "verify-pragmas" })));
1948
+ }).pipe(Effect.mapError(() => new DatabaseInitializationError({ operation: "verify-pragmas" })));
1878
1949
  });
1879
1950
  /** Run the startup SQLite integrity boundary. @internal */
1880
1951
  var verifyDatabaseIntegrity = Effect.fn("Database.verifyIntegrity")(function* (sql) {
@@ -1885,7 +1956,7 @@ var verifyDatabaseIntegrity = Effect.fn("Database.verifyIntegrity")(function* (s
1885
1956
  }).pipe(Effect.mapError(() => new DatabaseInitializationError({ operation: "verify-integrity" })));
1886
1957
  });
1887
1958
  var checkpointBeforeSchemaChange = Effect.fn("Database.checkpointBeforeSchemaChange")(function* (sql) {
1888
- yield* sql`PRAGMA wal_checkpoint(TRUNCATE)`.pipe(Effect.catchCause(() => new SchemaWriteBarrierError({ phase: "acquire" })));
1959
+ yield* sql`PRAGMA wal_checkpoint(TRUNCATE)`.pipe(Effect.mapError(() => new SchemaWriteBarrierError({ phase: "acquire" })));
1889
1960
  });
1890
1961
  var verifyCheckpointStayedQuiescent = Effect.fn("Database.verifyCheckpointStayedQuiescent")(function* (databaseFile) {
1891
1962
  const fileSystem = yield* FileSystem.FileSystem;
@@ -1894,10 +1965,11 @@ var verifyCheckpointStayedQuiescent = Effect.fn("Database.verifyCheckpointStayed
1894
1965
  const info = yield* fileSystem.stat(walFile).pipe(Effect.mapError(() => new SchemaWriteBarrierError({ phase: "verify" })));
1895
1966
  if (info.type !== "File" || info.size !== 0n) return yield* new SchemaWriteBarrierError({ phase: "verify" });
1896
1967
  });
1897
- /** Convert schema transaction defects and interruption into a redacted typed failure. */
1968
+ /** Convert transaction defects into a redacted failure while preserving cancellation. */
1898
1969
  var sandboxSchemaTransaction = (transaction) => transaction.pipe(Effect.catchCause((cause) => {
1970
+ if (Cause.hasInterrupts(cause)) return Effect.failCause(cause);
1899
1971
  const typedFailure = Cause.findErrorOption(cause);
1900
- if (Cause.hasDies(cause) || Cause.hasInterrupts(cause) || Option.isNone(typedFailure)) return Effect.fail(new SchemaWriteBarrierError({ phase: "verify" }));
1972
+ if (Cause.hasDies(cause) || Option.isNone(typedFailure)) return Effect.fail(new SchemaWriteBarrierError({ phase: "verify" }));
1901
1973
  return Effect.fail(typedFailure.value);
1902
1974
  }));
1903
1975
  /** Hold SQLite's reserved writer transaction across one fresh-schema operation. */
@@ -1909,8 +1981,10 @@ var makeClientLayer = (busyTimeoutMilliseconds, databaseUrl, maxConnections) =>
1909
1981
  transformResultNames: snakeToCamel,
1910
1982
  url: databaseUrl
1911
1983
  };
1912
- return LibsqlClient.layer(clientConfig).pipe(Layer.catchCause(() => Layer.effectContext(Effect.fail(new DatabaseInitializationError({ operation: "connect" })))));
1984
+ return LibsqlClient.layer(clientConfig).pipe(Layer.catchCause(handleDatabaseConnectionCause));
1913
1985
  };
1986
+ /** Redact client construction defects while retaining every original interruption reason. @internal */
1987
+ var handleDatabaseConnectionCause = (cause) => Cause.hasInterrupts(cause) ? Layer.effectContext(Effect.failCause(Cause.fromReasons(cause.reasons.filter(Cause.isInterruptReason)))) : Layer.effectContext(Effect.fail(new DatabaseInitializationError({ operation: "connect" })));
1914
1988
  var initializeDatabase = Effect.fn("Database.initializeDatabase")(function* (config) {
1915
1989
  yield* schemaLock.withPermit(Effect.scoped(Effect.gen(function* () {
1916
1990
  const context = yield* Layer.build(makeClientLayer(config.busyTimeoutMilliseconds, config.databaseUrl, 1));
@@ -2451,6 +2525,10 @@ var MAXIMUM_AGENT_ATTEMPT_OUTPUT_BYTES = 1048576;
2451
2525
  var MAXIMUM_AGENT_JOB_PROMPT_LENGTH = 5e3;
2452
2526
  /** Maximum thread events returned by one replay page. */
2453
2527
  var MAXIMUM_AGENT_THREAD_EVENT_PAGE_SIZE = 128;
2528
+ /** One explicit extension is bounded to the selected profile's original budget. */
2529
+ var MAXIMUM_REVIEW_BUDGET_EXTENSION_COUNT = 1;
2530
+ /** Hard upper bound for one immutable review, including its single extension. */
2531
+ var MAXIMUM_REVIEW_BUDGET_MILLIS = 36e5;
2454
2532
  /** Positive sequence assigned to attempts within one durable job. */
2455
2533
  var AgentAttemptSequence = Schema$1.Int.check(Schema$1.isBetween({
2456
2534
  minimum: 1,
@@ -2481,7 +2559,18 @@ var ReleaseChatAgentJobTask = Schema$1.TaggedStruct("release-chat", {});
2481
2559
  var PrReviewAgentJobTaskFields = {
2482
2560
  pluginConnectionId: PluginConnectionId,
2483
2561
  subject: PrReviewSubject,
2484
- reviewProfile: ReviewAgentProfile
2562
+ reviewProfile: ReviewAgentProfile,
2563
+ intent: Schema$1.optionalKey(Schema$1.Literals([
2564
+ "full-review",
2565
+ "suggestion-edit",
2566
+ "suggestion-revalidation"
2567
+ ])),
2568
+ target: Schema$1.optionalKey(Schema$1.Struct({
2569
+ sourceJobId: JobId,
2570
+ suggestionId: PrReviewSuggestionId,
2571
+ selectedRevisionId: PrReviewSuggestionRevisionId,
2572
+ history: PrReviewSuggestionRevisionPage
2573
+ }))
2485
2574
  };
2486
2575
  /** Read-only review request bound to one immutable pull request head. */
2487
2576
  var EnqueuePrReviewAgentJobTask = Schema$1.TaggedStruct("pr-review", PrReviewAgentJobTaskFields);
@@ -2497,6 +2586,7 @@ var PrReviewThreadRunSummary = Schema$1.Struct({
2497
2586
  state: Schema$1.Literals([
2498
2587
  "cancelled",
2499
2588
  "failed",
2589
+ "interrupted",
2500
2590
  "succeeded",
2501
2591
  "unknown"
2502
2592
  ]),
@@ -2579,6 +2669,14 @@ var ClaimedAgentJob = Schema$1.Struct({
2579
2669
  access: Schema$1.Literals(["read-only", "workspace-write"]),
2580
2670
  prompt: AgentJobPrompt,
2581
2671
  context: AgentContextSnapshotRecord,
2672
+ reviewBudgetMillis: Schema$1.optionalKey(Schema$1.Int.check(Schema$1.isBetween({
2673
+ minimum: 1,
2674
+ maximum: 36e5
2675
+ }))),
2676
+ reviewBudgetExtensionCount: Schema$1.optionalKey(Schema$1.Int.check(Schema$1.isBetween({
2677
+ minimum: 0,
2678
+ maximum: 1
2679
+ }))),
2582
2680
  sessionRef: Schema$1.NullOr(AgentSessionRef),
2583
2681
  cancellationRequested: Schema$1.Boolean
2584
2682
  });
@@ -2614,8 +2712,53 @@ var CompleteAgentReviewInput = Schema$1.Struct({
2614
2712
  report: Schema$1.Unknown,
2615
2713
  completedAt: UtcTimestamp
2616
2714
  });
2715
+ /** Startup transition for review attempts whose owning process disappeared. */
2716
+ var InterruptRunningReviewsInput = Schema$1.Struct({
2717
+ workspaceId: WorkspaceId,
2718
+ interruptedAt: UtcTimestamp,
2719
+ preservedAttempts: Schema$1.optionalKey(Schema$1.Array(Schema$1.Struct({
2720
+ jobId: JobId,
2721
+ attemptSequence: AgentAttemptSequence
2722
+ })))
2723
+ });
2724
+ /** Durable identity used to match a live Review Sandbox to one immutable attempt. */
2725
+ var RunningPrReviewAttempt = Schema$1.Struct({
2726
+ jobId: JobId,
2727
+ attemptSequence: AgentAttemptSequence,
2728
+ attemptId: Schema$1.String.check(Schema$1.isPattern(/^[a-f0-9]{12}$/u)),
2729
+ sessionRef: Schema$1.NullOr(AgentSessionRef)
2730
+ });
2731
+ /** Startup handoff for a live server-private Review Sandbox. */
2732
+ var AttachRunningPrReviewSessionInput = Schema$1.Struct({
2733
+ workspaceId: WorkspaceId,
2734
+ jobId: JobId,
2735
+ attemptSequence: AgentAttemptSequence,
2736
+ sessionRef: AgentSessionRef
2737
+ });
2738
+ /** Persist the latest validated report while an immutable review is still running. */
2739
+ var RecordAgentReviewProgressInput = Schema$1.Struct({
2740
+ workspaceId: WorkspaceId,
2741
+ jobId: JobId,
2742
+ attemptSequence: AgentAttemptSequence,
2743
+ leaseToken: AgentLeaseToken,
2744
+ report: Schema$1.Unknown,
2745
+ occurredAt: UtcTimestamp
2746
+ });
2747
+ /** Read the effective budget of one claimed immutable review. */
2748
+ var ReadReviewBudgetInput = Schema$1.Struct({
2749
+ workspaceId: WorkspaceId,
2750
+ jobId: JobId,
2751
+ task: AgentJobTask
2752
+ });
2617
2753
  /** Digest binding one durable publication reservation to the exact confirmed body. */
2618
2754
  var ReviewSuggestionPublicationDigest = Schema$1.String.check(Schema$1.isPattern(/^sha256:[0-9a-f]{64}$/u, { expected: "a lowercase SHA-256 digest" })).pipe(Schema$1.brand("ReviewSuggestionPublicationDigest"));
2755
+ /** Provider comment identity retained for governed lifecycle operations. */
2756
+ var ReviewSuggestionPublicationCommentId = Schema$1.String.check(Schema$1.isTrimmed(), Schema$1.isNonEmpty(), Schema$1.isMaxLength(512)).pipe(Schema$1.brand("ReviewSuggestionPublicationCommentId"));
2757
+ /** Provider receipt coordinate decoded to the persisted comment identity. */
2758
+ var ReviewSuggestionPublicationCommentLocator = Schema$1.TemplateLiteral([Schema$1.Literal("comment:"), ReviewSuggestionPublicationCommentId]).pipe(Schema$1.decodeTo(ReviewSuggestionPublicationCommentId, {
2759
+ decode: SchemaGetter.transform((locator) => locator.slice(8)),
2760
+ encode: SchemaGetter.transform((commentId) => `comment:${commentId}`)
2761
+ }));
2619
2762
  /** Atomic pre-provider reservation for one suggestion and exact confirmed body. */
2620
2763
  var ReserveReviewSuggestionPublicationInput = Schema$1.Struct({
2621
2764
  workspaceId: WorkspaceId,
@@ -2623,21 +2766,25 @@ var ReserveReviewSuggestionPublicationInput = Schema$1.Struct({
2623
2766
  suggestionId: PrReviewSuggestionId,
2624
2767
  revisionId: PrReviewSuggestionRevisionId,
2625
2768
  contentDigest: ReviewSuggestionPublicationDigest,
2769
+ operation: Schema$1.optionalKey(ReviewSuggestionPublicationOperation),
2770
+ commentId: Schema$1.optionalKey(ReviewSuggestionPublicationCommentId),
2626
2771
  reservationId: ReviewSuggestionPublicationReservationId,
2627
2772
  reservedAt: UtcTimestamp
2628
2773
  });
2629
2774
  /** Durable result of reserving an exact publication body. */
2630
2775
  var ReviewSuggestionPublicationReservation = Schema$1.Union([
2631
- Schema$1.TaggedStruct("acquired", {}),
2632
- Schema$1.TaggedStruct("in-progress", {}),
2776
+ Schema$1.TaggedStruct("acquired", { commentId: Schema$1.optionalKey(ReviewSuggestionPublicationCommentId) }),
2777
+ Schema$1.TaggedStruct("in-progress", { commentId: Schema$1.optionalKey(ReviewSuggestionPublicationCommentId) }),
2633
2778
  Schema$1.TaggedStruct("recoverable", {
2634
2779
  publicationId: GovernedActionId,
2635
2780
  publishedAt: UtcTimestamp,
2636
- reservationId: ReviewSuggestionPublicationReservationId
2781
+ reservationId: ReviewSuggestionPublicationReservationId,
2782
+ commentId: Schema$1.optionalKey(ReviewSuggestionPublicationCommentId)
2637
2783
  }),
2638
2784
  Schema$1.TaggedStruct("published", {
2639
2785
  publicationId: GovernedActionId,
2640
- publishedAt: UtcTimestamp
2786
+ publishedAt: UtcTimestamp,
2787
+ commentId: Schema$1.optionalKey(ReviewSuggestionPublicationCommentId)
2641
2788
  })
2642
2789
  ]);
2643
2790
  /** Release one exact reservation after a confirmed provider no-write outcome. */
@@ -2656,16 +2803,36 @@ var RecordReviewSuggestionPublicationInput = Schema$1.Struct({
2656
2803
  suggestionId: PrReviewSuggestionId,
2657
2804
  revisionId: PrReviewSuggestionRevisionId,
2658
2805
  contentDigest: ReviewSuggestionPublicationDigest,
2806
+ operation: Schema$1.optionalKey(ReviewSuggestionPublicationOperation),
2659
2807
  reservationId: ReviewSuggestionPublicationReservationId,
2660
2808
  publicationId: GovernedActionId,
2809
+ commentId: Schema$1.optionalKey(ReviewSuggestionPublicationCommentId),
2661
2810
  publishedAt: UtcTimestamp,
2662
2811
  finalize: Schema$1.optionalKey(Schema$1.Boolean)
2663
2812
  });
2813
+ /** Lookup for the latest durable publication target of one exact suggestion. */
2814
+ var ReadReviewSuggestionPublicationInput = Schema$1.Struct({
2815
+ workspaceId: WorkspaceId,
2816
+ jobId: JobId,
2817
+ suggestionId: PrReviewSuggestionId,
2818
+ revisionId: PrReviewSuggestionRevisionId
2819
+ });
2820
+ var ReadReviewSuggestionPublication = Schema$1.Struct({
2821
+ state: Schema$1.Literal("published"),
2822
+ publicationId: GovernedActionId,
2823
+ commentId: ReviewSuggestionPublicationCommentId
2824
+ });
2664
2825
  /** Workspace-scoped lookup for one durable review result. */
2665
2826
  var AgentReviewResultInput = Schema$1.Struct({
2666
2827
  workspaceId: WorkspaceId,
2667
2828
  jobId: JobId
2668
2829
  });
2830
+ /** Request one operator-authorized extension of a running review's budget. */
2831
+ var ExtendReviewBudgetInput = Schema$1.Struct({
2832
+ workspaceId: WorkspaceId,
2833
+ jobId: JobId,
2834
+ extendedAt: UtcTimestamp
2835
+ });
2669
2836
  /** Sanitized durable review result attributable to one terminal attempt. */
2670
2837
  var AgentReviewResultRecord = Schema$1.Struct({
2671
2838
  workspaceId: WorkspaceId,
@@ -2683,6 +2850,11 @@ var ReadReviewSuggestionRevisionsInput = Schema$1.Struct({
2683
2850
  limit: PrReviewSuggestionRevisionPageSize
2684
2851
  });
2685
2852
  /** Complete compare-and-append command for one immutable suggestion edit. */
2853
+ var ReviewSuggestionRevisionLeaseFence = Schema$1.Struct({
2854
+ jobId: JobId,
2855
+ attemptSequence: AgentAttemptSequence,
2856
+ leaseToken: AgentLeaseToken
2857
+ });
2686
2858
  var AppendReviewSuggestionRevisionInput = Schema$1.Struct({
2687
2859
  workspaceId: WorkspaceId,
2688
2860
  jobId: JobId,
@@ -2690,16 +2862,27 @@ var AppendReviewSuggestionRevisionInput = Schema$1.Struct({
2690
2862
  expectedRevisionId: PrReviewSuggestionRevisionId,
2691
2863
  expectedSequence: PrReviewSuggestionRevisionSequence,
2692
2864
  edit: PrReviewSuggestionEdit,
2693
- state: Schema$1.optionalKey(Schema$1.Literal("dismissed")),
2865
+ state: Schema$1.optionalKey(Schema$1.Literals(["dismissed", "stale"])),
2866
+ dismissalReason: Schema$1.optionalKey(PrReviewSuggestion.fields.dismissalReason),
2867
+ validation: Schema$1.optionalKey(Schema$1.Literal("validated")),
2694
2868
  author: PrReviewSuggestionRevisionAuthor,
2695
- createdAt: UtcTimestamp
2869
+ createdAt: UtcTimestamp,
2870
+ leaseFence: Schema$1.optionalKey(ReviewSuggestionRevisionLeaseFence)
2871
+ });
2872
+ /** Atomic targeted completion: append the source revision and terminalize the worker job together. */
2873
+ var CompleteTargetedReviewInput = Schema$1.Struct({
2874
+ source: AppendReviewSuggestionRevisionInput,
2875
+ target: CompleteAgentReviewInput
2696
2876
  });
2697
2877
  /** Exact immutable subject used to recover its newest durable review job. */
2698
2878
  var LatestAgentReviewInput = Schema$1.Struct({
2699
2879
  workspaceId: WorkspaceId,
2700
2880
  pluginConnectionId: PluginConnectionId,
2701
2881
  subject: PrReviewSubject,
2702
- jobId: Schema$1.optionalKey(JobId)
2882
+ excludeJobId: Schema$1.optionalKey(JobId),
2883
+ excludeSubjectRevision: Schema$1.optionalKey(Schema$1.String),
2884
+ jobId: Schema$1.optionalKey(JobId),
2885
+ allowDifferentHead: Schema$1.optionalKey(Schema$1.Boolean)
2703
2886
  });
2704
2887
  /** Cursor-bounded lookup for the durable thread behind a stable pull request. */
2705
2888
  var PrReviewThreadSubject = Schema$1.Struct({
@@ -2741,16 +2924,26 @@ var LatestAgentReviewRecord = Schema$1.Struct({
2741
2924
  threadId: AgentThreadId,
2742
2925
  providerId: AgentProviderId,
2743
2926
  model: AgentModel,
2744
- state: AgentJobState,
2927
+ state: Schema$1.Union([AgentJobState, Schema$1.Literal("interrupted")]),
2745
2928
  createdAt: UtcTimestamp,
2746
2929
  terminalAt: Schema$1.NullOr(UtcTimestamp),
2930
+ startedAt: Schema$1.optionalKey(Schema$1.NullOr(UtcTimestamp)),
2931
+ reviewBudgetMillis: Schema$1.optionalKey(Schema$1.Int.check(Schema$1.isBetween({
2932
+ minimum: 1,
2933
+ maximum: 36e5
2934
+ }))),
2935
+ reviewBudgetExtensionCount: Schema$1.optionalKey(Schema$1.Int.check(Schema$1.isBetween({
2936
+ minimum: 0,
2937
+ maximum: 1
2938
+ }))),
2939
+ taskIntent: Schema$1.optionalKey(Schema$1.NullOr(Schema$1.Literals(["suggestion-edit", "suggestion-revalidation"]))),
2747
2940
  report: Schema$1.NullOr(PrReviewReport),
2748
2941
  reviewProfile: ReviewAgentProfile,
2749
2942
  activity: Schema$1.Struct({
2750
2943
  events: Schema$1.Array(Schema$1.String.check(Schema$1.isNonEmpty(), Schema$1.isMaxLength(MAXIMUM_AGENT_ATTEMPT_OUTPUT_BYTES))).check(Schema$1.isMaxLength(128)),
2751
2944
  truncated: Schema$1.Boolean
2752
2945
  })
2753
- }).check(Schema$1.makeFilter(({ report, state }) => state === "succeeded" === (report !== null), { expected: "only succeeded review jobs to carry a report" }));
2946
+ }).check(Schema$1.makeFilter(({ report, state }) => report === null || state === "succeeded" || state === "failed" || state === "cancelled" || state === "interrupted", { expected: "only terminal review jobs to carry a report" }));
2754
2947
  /** One immutable event in a release thread. */
2755
2948
  var AgentThreadEvent = Schema$1.Struct({
2756
2949
  workspaceId: WorkspaceId,
@@ -3602,6 +3795,58 @@ var ContentStore = class ContentStore extends Context.Service()("@knpkv/control-
3602
3795
  static layer = Layer.effect(ContentStore, makeContentStore);
3603
3796
  };
3604
3797
  //#endregion
3798
+ //#region src/domain/prReviewReconciliation.ts
3799
+ /** Pure cross-head reconciliation for immutable PR-review suggestions. @module */
3800
+ /** Validate a report's explicit host transition set against the two immutable heads. */
3801
+ var validatePrReviewReportTransitions = (previous, current, declared) => {
3802
+ const expected = reconcilePrReviewReports(previous, current);
3803
+ const expectedById = new Map(expected.map((transition) => [transition.suggestionId, transition]));
3804
+ const declaredById = /* @__PURE__ */ new Map();
3805
+ for (const transition of declared) {
3806
+ if (!expectedById.has(transition.suggestionId)) return {
3807
+ _tag: "failure",
3808
+ failure: {
3809
+ _tag: "unknown-id",
3810
+ suggestionId: transition.suggestionId
3811
+ }
3812
+ };
3813
+ if (declaredById.has(transition.suggestionId)) return {
3814
+ _tag: "failure",
3815
+ failure: {
3816
+ _tag: "duplicate-id",
3817
+ suggestionId: transition.suggestionId
3818
+ }
3819
+ };
3820
+ declaredById.set(transition.suggestionId, transition);
3821
+ }
3822
+ for (const [suggestionId, expectedTransition] of expectedById) {
3823
+ const actual = declaredById.get(suggestionId);
3824
+ if (actual === void 0) return {
3825
+ _tag: "failure",
3826
+ failure: {
3827
+ _tag: "missing-transition",
3828
+ suggestionId
3829
+ }
3830
+ };
3831
+ if (actual.transition !== expectedTransition.transition || actual.previousState !== expectedTransition.previousState || actual.currentState !== expectedTransition.currentState || actual.previousDismissalReason !== expectedTransition.previousDismissalReason || actual.previousHead !== expectedTransition.previousHead || actual.currentHead !== expectedTransition.currentHead) return {
3832
+ _tag: "failure",
3833
+ failure: {
3834
+ _tag: "contradictory-transition",
3835
+ suggestionId,
3836
+ expected: expectedTransition.transition,
3837
+ actual: actual.transition
3838
+ }
3839
+ };
3840
+ }
3841
+ return {
3842
+ _tag: "success",
3843
+ transitions: expected.map(({ suggestionId, transition: kind }) => ({
3844
+ suggestionId,
3845
+ kind
3846
+ }))
3847
+ };
3848
+ };
3849
+ //#endregion
3605
3850
  //#region src/server/persistence/repositories/internal/reviewSuggestionRevisions.ts
3606
3851
  var REVISION_ID_NAMESPACE = "review-suggestion-revision/v1";
3607
3852
  var PersistedDigest$1 = Schema$1.String.check(Schema$1.isPattern(/^sha256:[0-9a-f]{64}$/u, { expected: "a lowercase SHA-256 digest" }));
@@ -3775,68 +4020,91 @@ var makeReviewSuggestionRevisionOperations = (dependencies) => {
3775
4020
  nextBeforeSequence: hasMore ? revisions.at(-1)?.sequence ?? null : null
3776
4021
  }).pipe(Effect$1.mapError(() => operationFailure("agent-job.review-revision-page-invalid")));
3777
4022
  });
3778
- return {
3779
- append: Effect$1.fn("ReviewSuggestionRevisions.append")(function* (input) {
3780
- const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(AppendReviewSuggestionRevisionInput))(input);
3781
- return yield* database.transaction(Effect$1.gen(function* () {
3782
- const current = yield* currentRevision(request.workspaceId, request.jobId, request.suggestionId);
3783
- if ((yield* deriveRevisionId(request.jobId, request.suggestionId, request.expectedSequence)) !== request.expectedRevisionId) return yield* new AgentJobInputError({
3784
- workspaceId: request.workspaceId,
3785
- jobId: request.jobId,
3786
- reason: "revision-identity-mismatch"
3787
- });
3788
- if (current.revisionId !== request.expectedRevisionId || current.sequence !== request.expectedSequence) return yield* new RevisionConflictError({
4023
+ const appendInTransaction = Effect$1.fn("ReviewSuggestionRevisions.appendInTransaction")(function* (input) {
4024
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(AppendReviewSuggestionRevisionInput))(input);
4025
+ return yield* Effect$1.gen(function* () {
4026
+ if (request.leaseFence !== void 0) {
4027
+ if ((yield* sql`SELECT 1
4028
+ FROM agent_jobs job
4029
+ JOIN agent_job_leases lease
4030
+ ON lease.workspace_id = job.workspace_id
4031
+ AND lease.job_id = job.job_id
4032
+ AND lease.attempt_sequence = ${request.leaseFence.attemptSequence}
4033
+ AND lease.lease_token = ${request.leaseFence.leaseToken}
4034
+ WHERE job.workspace_id = ${request.workspaceId}
4035
+ AND job.job_id = ${request.leaseFence.jobId}
4036
+ AND job.state = 'running'
4037
+ AND job.cancel_requested_at IS NULL
4038
+ AND lease.lease_expires_at > ${Schema$1.encodeSync(PrReviewSuggestionRevision.fields.createdAt)(request.createdAt)}
4039
+ LIMIT 1`).length !== 1) return yield* new AgentJobInputError({
3789
4040
  workspaceId: request.workspaceId,
3790
- recordKind: "agent-review-suggestion-revision",
3791
- recordKey: revisionRecordKey(request.jobId, request.suggestionId),
3792
- expectedRevision: request.expectedSequence,
3793
- actualRevision: current.sequence
4041
+ jobId: request.leaseFence.jobId,
4042
+ reason: "cancellation-requested"
3794
4043
  });
3795
- const currentEdit = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(PrReviewSuggestionEdit))(current.suggestion).pipe(Effect$1.mapError(() => recordFailure(request.workspaceId, request.jobId, request.suggestionId, "agent-review-current-edit-invalid")));
3796
- if ((yield* Schema$1.encodeUnknownEffect(Schema$1.fromJsonString(PrReviewSuggestionEdit))(currentEdit).pipe(Effect$1.mapError(() => operationFailure("agent-job.encode-current-review-edit")))) === (yield* Schema$1.encodeUnknownEffect(Schema$1.fromJsonString(PrReviewSuggestionEdit))(request.edit).pipe(Effect$1.mapError(() => operationFailure("agent-job.encode-requested-review-edit")))) && request.state === void 0) return current;
3797
- if ((yield* sql`SELECT 1
4044
+ }
4045
+ const current = yield* currentRevision(request.workspaceId, request.jobId, request.suggestionId);
4046
+ if ((yield* deriveRevisionId(request.jobId, request.suggestionId, request.expectedSequence)) !== request.expectedRevisionId) return yield* new AgentJobInputError({
4047
+ workspaceId: request.workspaceId,
4048
+ jobId: request.jobId,
4049
+ reason: "revision-identity-mismatch"
4050
+ });
4051
+ if (current.revisionId !== request.expectedRevisionId || current.sequence !== request.expectedSequence) return yield* new RevisionConflictError({
4052
+ workspaceId: request.workspaceId,
4053
+ recordKind: "agent-review-suggestion-revision",
4054
+ recordKey: revisionRecordKey(request.jobId, request.suggestionId),
4055
+ expectedRevision: request.expectedSequence,
4056
+ actualRevision: current.sequence
4057
+ });
4058
+ const currentEdit = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(PrReviewSuggestionEdit))(current.suggestion).pipe(Effect$1.mapError(() => recordFailure(request.workspaceId, request.jobId, request.suggestionId, "agent-review-current-edit-invalid")));
4059
+ if ((yield* Schema$1.encodeUnknownEffect(Schema$1.fromJsonString(PrReviewSuggestionEdit))(currentEdit).pipe(Effect$1.mapError(() => operationFailure("agent-job.encode-current-review-edit")))) === (yield* Schema$1.encodeUnknownEffect(Schema$1.fromJsonString(PrReviewSuggestionEdit))(request.edit).pipe(Effect$1.mapError(() => operationFailure("agent-job.encode-requested-review-edit")))) && request.state === void 0 && request.validation === void 0) return current;
4060
+ if ((yield* sql`SELECT 1
3798
4061
  FROM agent_review_suggestion_publications
3799
4062
  WHERE workspace_id = ${request.workspaceId}
3800
4063
  AND job_id = ${request.jobId}
3801
4064
  AND suggestion_id = ${request.suggestionId}
3802
4065
  LIMIT 1`).length > 0) return yield* new AgentJobInputError({
3803
- workspaceId: request.workspaceId,
3804
- jobId: request.jobId,
3805
- reason: "invalid-transition"
3806
- });
3807
- if (current.suggestion.state !== "draft" || request.edit.replacement !== void 0 && request.edit.replacement.reviewedHead !== current.subject.headRevision || DateTime$1.Order(request.createdAt, current.createdAt) < 0) return yield* new AgentJobInputError({
3808
- workspaceId: request.workspaceId,
3809
- jobId: request.jobId,
3810
- reason: "invalid-transition"
3811
- });
3812
- const sequence = PrReviewSuggestionRevisionSequence.make(current.sequence + 1);
3813
- const revisionId = yield* deriveRevisionId(request.jobId, request.suggestionId, sequence);
3814
- const validation = hasSamePrReviewTechnicalClaim(currentEdit, request.edit) ? current.validation : PrReviewSuggestionRequiresRevalidation.make({
3815
- reviewedHead: current.subject.headRevision,
3816
- sourceRevisionId: current.revisionId,
3817
- reason: request.author._tag === "agent" ? "agent-edit-not-validated" : "technical-claim-edited"
3818
- });
3819
- const suggestion = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(PrReviewSuggestion))({
3820
- suggestionId: request.suggestionId,
3821
- state: request.state ?? current.suggestion.state,
3822
- ...request.edit
3823
- }).pipe(Effect$1.mapError(() => operationFailure("agent-job.review-revision-suggestion-invalid")));
3824
- const revision = yield* Effect$1.try({
3825
- try: () => PrReviewSuggestionRevision.make({
3826
- revisionId,
3827
- sequence,
3828
- predecessorRevisionId: current.revisionId,
3829
- sourceJobId: request.jobId,
3830
- subject: current.subject,
3831
- suggestion,
3832
- validation,
3833
- author: request.author,
3834
- createdAt: request.createdAt
3835
- }),
3836
- catch: () => operationFailure("agent-job.review-revision-invalid")
3837
- });
3838
- const encoded = yield* encodeRevision(request.workspaceId, revision);
3839
- yield* sql`INSERT INTO agent_review_suggestion_revisions (
4066
+ workspaceId: request.workspaceId,
4067
+ jobId: request.jobId,
4068
+ reason: "invalid-transition"
4069
+ });
4070
+ if (current.suggestion.state !== "draft" && !(request.state === "stale" && current.suggestion.state === "published") || request.state === "dismissed" && request.dismissalReason === void 0 || request.state !== "dismissed" && request.dismissalReason !== void 0 || request.edit.replacement !== void 0 && request.edit.replacement.reviewedHead !== current.subject.headRevision || DateTime$1.Order(request.createdAt, current.createdAt) < 0) return yield* new AgentJobInputError({
4071
+ workspaceId: request.workspaceId,
4072
+ jobId: request.jobId,
4073
+ reason: "invalid-transition"
4074
+ });
4075
+ const sequence = PrReviewSuggestionRevisionSequence.make(current.sequence + 1);
4076
+ const revisionId = yield* deriveRevisionId(request.jobId, request.suggestionId, sequence);
4077
+ const validation = request.validation === "validated" && request.author._tag === "agent" ? PrReviewSuggestionValidated.make({
4078
+ reviewedHead: current.subject.headRevision,
4079
+ validatingJobId: request.author.jobId,
4080
+ sourceRevisionId: current.revisionId
4081
+ }) : hasSamePrReviewTechnicalClaim(currentEdit, request.edit) ? current.validation : PrReviewSuggestionRequiresRevalidation.make({
4082
+ reviewedHead: current.subject.headRevision,
4083
+ sourceRevisionId: current.revisionId,
4084
+ reason: request.author._tag === "agent" ? "agent-edit-not-validated" : "technical-claim-edited"
4085
+ });
4086
+ const suggestion = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(PrReviewSuggestion))({
4087
+ suggestionId: request.suggestionId,
4088
+ state: request.state ?? current.suggestion.state,
4089
+ ...request.dismissalReason === void 0 ? {} : { dismissalReason: request.dismissalReason },
4090
+ ...request.edit
4091
+ }).pipe(Effect$1.mapError(() => operationFailure("agent-job.review-revision-suggestion-invalid")));
4092
+ const revision = yield* Effect$1.try({
4093
+ try: () => PrReviewSuggestionRevision.make({
4094
+ revisionId,
4095
+ sequence,
4096
+ predecessorRevisionId: current.revisionId,
4097
+ sourceJobId: request.jobId,
4098
+ subject: current.subject,
4099
+ suggestion,
4100
+ validation,
4101
+ author: request.author,
4102
+ createdAt: request.createdAt
4103
+ }),
4104
+ catch: () => operationFailure("agent-job.review-revision-invalid")
4105
+ });
4106
+ const encoded = yield* encodeRevision(request.workspaceId, revision);
4107
+ yield* sql`INSERT INTO agent_review_suggestion_revisions (
3840
4108
  workspace_id, source_job_id, suggestion_id, revision_sequence,
3841
4109
  revision_id, predecessor_revision_id, revision_json,
3842
4110
  revision_digest, created_at
@@ -3846,27 +4114,32 @@ var makeReviewSuggestionRevisionOperations = (dependencies) => {
3846
4114
  ${encoded.json}, ${encoded.digest},
3847
4115
  ${Schema$1.encodeSync(PrReviewSuggestionRevision.fields.createdAt)(request.createdAt)}
3848
4116
  )`;
3849
- const job = yield* getJob(request.workspaceId, request.jobId);
3850
- yield* appendThreadEvent({
3851
- workspaceId: request.workspaceId,
3852
- threadId: job.threadId,
3853
- jobId: request.jobId,
3854
- attemptSequence: null,
3855
- eventKind: "review-suggestion-revised",
3856
- payload: {
3857
- suggestionId: request.suggestionId,
3858
- revisionId,
3859
- sequence,
3860
- authorKind: request.author._tag,
3861
- validationState: validation._tag,
3862
- suggestionState: suggestion.state
3863
- },
3864
- payloadSchema: ReviewSuggestionRevisedPayload,
3865
- occurredAt: request.createdAt
3866
- });
3867
- return revision;
3868
- }));
4117
+ const job = yield* getJob(request.workspaceId, request.jobId);
4118
+ yield* appendThreadEvent({
4119
+ workspaceId: request.workspaceId,
4120
+ threadId: job.threadId,
4121
+ jobId: request.jobId,
4122
+ attemptSequence: null,
4123
+ eventKind: "review-suggestion-revised",
4124
+ payload: {
4125
+ suggestionId: request.suggestionId,
4126
+ revisionId,
4127
+ sequence,
4128
+ authorKind: request.author._tag,
4129
+ validationState: validation._tag,
4130
+ suggestionState: suggestion.state
4131
+ },
4132
+ payloadSchema: ReviewSuggestionRevisedPayload,
4133
+ occurredAt: request.createdAt
4134
+ });
4135
+ return revision;
4136
+ });
4137
+ });
4138
+ return {
4139
+ append: Effect$1.fn("ReviewSuggestionRevisions.append")(function* (input) {
4140
+ return yield* database.transaction(appendInTransaction(input));
3869
4141
  }),
4142
+ appendInTransaction,
3870
4143
  read
3871
4144
  };
3872
4145
  };
@@ -3904,10 +4177,16 @@ var PersistedJobQueuedPayload = Schema$1.Struct({
3904
4177
  model: EnqueueAgentJobInput.fields.model,
3905
4178
  providerId: EnqueueAgentJobInput.fields.providerId,
3906
4179
  subjectRevision: EnqueueAgentJobInput.fields.subjectRevision,
3907
- task: AgentJobTask
4180
+ task: AgentJobTask,
4181
+ reviewBudgetMillis: Schema$1.optionalKey(Schema$1.Int.check(Schema$1.isBetween({
4182
+ minimum: 1,
4183
+ maximum: 36e5
4184
+ }))),
4185
+ reviewBudgetExtensionCount: Schema$1.optionalKey(Schema$1.Literal(1))
3908
4186
  });
3909
4187
  var CancellationRequestedPayload = Schema$1.Struct({ requestedAt: UtcTimestamp });
3910
4188
  var ProviderFailurePayload = Schema$1.Struct({ error: AgentProviderError });
4189
+ var PROCESS_RESTART_INTERRUPTION_MESSAGE = "Review interrupted because the Control Center process restarted.";
3911
4190
  var ReviewSuggestionPublishedPayload = Schema$1.Struct({
3912
4191
  suggestionId: RecordReviewSuggestionPublicationInput.fields.suggestionId,
3913
4192
  revisionId: RecordReviewSuggestionPublicationInput.fields.revisionId,
@@ -3918,6 +4197,10 @@ var ReviewSuggestionPublicationRow = Schema$1.Struct({
3918
4197
  contentDigest: ReviewSuggestionPublicationDigest,
3919
4198
  state: Schema$1.Literals(["reserved", "published"]),
3920
4199
  publicationId: Schema$1.NullOr(GovernedActionId),
4200
+ commentId: Schema$1.NullOr(ReviewSuggestionPublicationCommentId),
4201
+ previousContentDigest: Schema$1.NullOr(ReviewSuggestionPublicationDigest),
4202
+ previousPublicationId: Schema$1.NullOr(GovernedActionId),
4203
+ previousPublishedAt: Schema$1.NullOr(UtcTimestamp),
3921
4204
  reservationAcquiredAt: UtcTimestamp,
3922
4205
  reservationId: ReviewSuggestionPublicationReservationId,
3923
4206
  reservedAt: UtcTimestamp,
@@ -4069,6 +4352,11 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4069
4352
  json
4070
4353
  };
4071
4354
  });
4355
+ const sanitizeAgentReviewReport = (report) => (() => {
4356
+ const { transitions: _agentOwnedTransitions, ...agentOwnedReport } = report;
4357
+ return PrReviewReport.make(agentOwnedReport);
4358
+ })();
4359
+ const isAgentOwnedSuggestionState = (state) => state === "draft" || state === "resolved";
4072
4360
  const decodeTaskContext = Effect$1.fn("AgentJobRepository.decodeTaskContext")(function* (workspaceId, jobId, taskContextJson, taskContextDigest) {
4073
4361
  const bytes = yield* bytesFromText(taskContextJson);
4074
4362
  if ((yield* digestBytes(bytes)) !== taskContextDigest) return yield* persistedRecordError(workspaceId, "agent-job", jobId, "agent-job-task-context-integrity-invalid");
@@ -4255,6 +4543,49 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4255
4543
  case "job-completed": return yield* decodeRuntimePayload(workspaceId, row, payload);
4256
4544
  }
4257
4545
  });
4546
+ const reviewBudgetState = Effect$1.fn("AgentJobRepository.reviewBudgetState")(function* (workspaceId, jobId, task) {
4547
+ if (task._tag !== "pr-review") return {
4548
+ reviewBudgetMillis: void 0,
4549
+ reviewBudgetExtensionCount: 0
4550
+ };
4551
+ const rows = yield* sql`SELECT
4552
+ workspace_id AS workspaceId, thread_id AS threadId,
4553
+ event_sequence AS eventSequence, job_id AS jobId,
4554
+ attempt_sequence AS attemptSequence, event_kind AS eventKind,
4555
+ payload_json AS payloadJson, payload_digest AS payloadDigest,
4556
+ payload_byte_length AS payloadByteLength, occurred_at AS occurredAt
4557
+ FROM agent_thread_events
4558
+ WHERE workspace_id = ${workspaceId}
4559
+ AND job_id = ${jobId}
4560
+ AND event_kind = 'job-queued'
4561
+ ORDER BY event_sequence`.pipe(mapPersistenceOperation("agent-job.review-budget"));
4562
+ let reviewBudgetMillis = task.reviewProfile.budgetMillis;
4563
+ let reviewBudgetExtensionCount = 0;
4564
+ for (const unknownRow of rows) {
4565
+ const row = Schema$1.decodeUnknownResult(ThreadEventRow)(unknownRow);
4566
+ if (Result$1.isFailure(row)) return yield* persistedRecordError(workspaceId, "agent-review-budget", jobId, "agent-review-budget-event-schema-invalid");
4567
+ const bytes = yield* bytesFromText(row.success.payloadJson);
4568
+ const actualDigest = yield* digestBytes(bytes);
4569
+ if (bytes.length !== row.success.payloadByteLength || actualDigest !== row.success.payloadDigest) return yield* persistedRecordError(workspaceId, "agent-review-budget", jobId, "agent-review-budget-event-integrity-invalid");
4570
+ const parsed = Schema$1.decodeUnknownResult(Schema$1.UnknownFromJsonString)(row.success.payloadJson);
4571
+ if (Result$1.isFailure(parsed)) return yield* persistedRecordError(workspaceId, "agent-review-budget", jobId, "agent-review-budget-event-json-invalid");
4572
+ const decoded = Schema$1.decodeUnknownResult(PersistedJobQueuedPayload)(parsed.success);
4573
+ if (Result$1.isFailure(decoded)) {
4574
+ const legacy = Schema$1.decodeUnknownResult(JobQueuedPayload)(parsed.success);
4575
+ if (Result$1.isFailure(legacy)) return yield* persistedRecordError(workspaceId, "agent-review-budget", jobId, "agent-review-budget-event-invalid");
4576
+ continue;
4577
+ }
4578
+ if (decoded.success.task._tag !== "pr-review") continue;
4579
+ if (decoded.success.reviewBudgetMillis !== void 0) {
4580
+ reviewBudgetMillis = decoded.success.reviewBudgetMillis;
4581
+ reviewBudgetExtensionCount = decoded.success.reviewBudgetExtensionCount ?? 1;
4582
+ }
4583
+ }
4584
+ return {
4585
+ reviewBudgetMillis,
4586
+ reviewBudgetExtensionCount
4587
+ };
4588
+ });
4258
4589
  const reviewContextSnapshot = Effect$1.fn("AgentJobRepository.reviewContextSnapshot")(function* (workspaceId, threadId) {
4259
4590
  const rendered = renderAgentReviewContextEventsQuery({
4260
4591
  workspaceId,
@@ -4320,12 +4651,14 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4320
4651
  });
4321
4652
  break;
4322
4653
  }
4323
- case "job-failed":
4654
+ case "job-failed": {
4655
+ const failure = yield* Schema$1.decodeUnknownEffect(ProviderFailurePayload)(payload);
4324
4656
  runs.set(row.jobId, {
4325
4657
  ...current,
4326
- state: "failed"
4658
+ state: failure.error.message === "Review interrupted because the Control Center process restarted." ? "interrupted" : "failed"
4327
4659
  });
4328
4660
  break;
4661
+ }
4329
4662
  case "cancel-requested":
4330
4663
  if (row.jobState === "cancelled") runs.set(row.jobId, {
4331
4664
  ...current,
@@ -4416,14 +4749,16 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4416
4749
  FROM agent_thread_events
4417
4750
  WHERE workspace_id = ${request.workspaceId}
4418
4751
  AND job_id = ${request.jobId}
4419
- AND event_kind = 'review-report'`.pipe(mapPersistenceOperation("agent-job.review-result"));
4752
+ AND event_kind = 'review-report'
4753
+ ORDER BY event_sequence DESC
4754
+ LIMIT 1`.pipe(mapPersistenceOperation("agent-job.review-result"));
4420
4755
  if (rows.length === 0) return yield* new RecordNotFoundError({
4421
4756
  workspaceId: request.workspaceId,
4422
4757
  recordKind: "agent-review-result",
4423
4758
  recordKey: request.jobId
4424
4759
  });
4425
4760
  const row = Schema$1.decodeUnknownResult(ThreadEventRow)(rows[0]);
4426
- if (rows.length !== 1 || Result$1.isFailure(row) || row.success.attemptSequence === null) return yield* persistedRecordError(request.workspaceId, "agent-review-result", request.jobId, "agent-review-result-schema-invalid");
4761
+ if (Result$1.isFailure(row) || row.success.attemptSequence === null) return yield* persistedRecordError(request.workspaceId, "agent-review-result", request.jobId, "agent-review-result-schema-invalid");
4427
4762
  const report = yield* decodeEventPayload(request.workspaceId, row.success);
4428
4763
  const decodedReport = Schema$1.decodeUnknownResult(PrReviewReport)(report);
4429
4764
  if (Result$1.isFailure(decodedReport)) return yield* persistedRecordError(request.workspaceId, "agent-review-result", request.jobId, "agent-review-result-payload-invalid");
@@ -4508,14 +4843,16 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4508
4843
  FROM agent_thread_events
4509
4844
  WHERE workspace_id = ${request.workspaceId}
4510
4845
  AND job_id = ${request.jobId}
4511
- AND event_kind = 'review-report'`.pipe(mapPersistenceOperation("agent-job.original-review-result"));
4846
+ AND event_kind = 'review-report'
4847
+ ORDER BY event_sequence ASC
4848
+ LIMIT 1`.pipe(mapPersistenceOperation("agent-job.original-review-result"));
4512
4849
  if (rows.length === 0) return yield* new RecordNotFoundError({
4513
4850
  workspaceId: request.workspaceId,
4514
4851
  recordKind: "agent-review-result",
4515
4852
  recordKey: request.jobId
4516
4853
  });
4517
4854
  const row = Schema$1.decodeUnknownResult(ThreadEventRow)(rows[0]);
4518
- if (rows.length !== 1 || Result$1.isFailure(row) || row.success.attemptSequence === null) return yield* persistedRecordError(request.workspaceId, "agent-review-result", request.jobId, "agent-review-original-result-schema-invalid");
4855
+ if (Result$1.isFailure(row) || row.success.attemptSequence === null) return yield* persistedRecordError(request.workspaceId, "agent-review-result", request.jobId, "agent-review-original-result-schema-invalid");
4519
4856
  const report = Schema$1.decodeUnknownResult(PrReviewReport)(yield* decodeEventPayload(request.workspaceId, row.success));
4520
4857
  if (Result$1.isFailure(report)) return yield* persistedRecordError(request.workspaceId, "agent-review-result", request.jobId, "agent-review-original-result-payload-invalid");
4521
4858
  return yield* Schema$1.decodeUnknownEffect(Schema$1.toType(AgentReviewResultRecord))({
@@ -4526,6 +4863,34 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4526
4863
  completedAt: row.success.occurredAt
4527
4864
  });
4528
4865
  });
4866
+ const findPreviousReviewReport = Effect$1.fn("AgentJobRepository.findPreviousReviewReport")(function* (input) {
4867
+ const subjectJson = yield* Schema$1.encodeUnknownEffect(Schema$1.fromJsonString(PrReviewSubject))(input.subject).pipe(Effect$1.mapError(() => new PersistenceOperationError({ operation: "agent-job.previous-review-subject" })));
4868
+ const taskContextPrefix = `{"_tag":"pr-review","pluginConnectionId":"${input.pluginConnectionId}","subject":${subjectJson},"reviewProfile":`;
4869
+ const identityPrefix = taskContextPrefix.slice(0, taskContextPrefix.indexOf("\"baseRevision\""));
4870
+ const rendered = renderLatestAgentReviewQuery({
4871
+ workspaceId: input.workspaceId,
4872
+ taskContextPrefix: identityPrefix,
4873
+ excludeTargeted: true,
4874
+ excludeJobId: input.excludeJobId,
4875
+ excludeSubjectRevision: input.subject.headRevision,
4876
+ limit: 32
4877
+ });
4878
+ const rows = yield* sql.unsafe(rendered.sql, [...rendered.params]).pipe(mapPersistenceOperation("agent-job.previous-review"));
4879
+ for (const rawRow of rows) {
4880
+ const row = Schema$1.decodeUnknownResult(LatestReviewRow)(rawRow);
4881
+ if (Result$1.isFailure(row)) return yield* persistedRecordError(input.workspaceId, "agent-review", input.subject.pullRequestId, "agent-review-previous-schema-invalid");
4882
+ if (row.success.state !== "succeeded" && row.success.state !== "failed" && row.success.state !== "cancelled") continue;
4883
+ const result = yield* readReviewResult({
4884
+ workspaceId: input.workspaceId,
4885
+ jobId: row.success.jobId
4886
+ }).pipe(Effect$1.catchTag("RecordNotFoundError", () => Effect$1.succeed(null)));
4887
+ if (result !== null && result.report !== null) return Option$1.some({
4888
+ jobId: row.success.jobId,
4889
+ report: result.report
4890
+ });
4891
+ }
4892
+ return Option$1.none();
4893
+ });
4529
4894
  const decodeThreadEventRows = Effect$1.fn("AgentJobRepository.decodeThreadEventRows")(function* (workspaceId, threadId, rows) {
4530
4895
  const decodedRows = yield* Schema$1.decodeUnknownEffect(Schema$1.Array(ReplayThreadEventRow))(rows).pipe(Effect$1.mapError(() => persistedRecordError(workspaceId, "agent-thread", threadId, "agent-thread-event-schema-invalid")));
4531
4896
  const tasksByJob = /* @__PURE__ */ new Map();
@@ -4619,10 +4984,94 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4619
4984
  });
4620
4985
  return current;
4621
4986
  });
4987
+ const currentPublishedReviewSuggestion = Effect$1.fn("AgentJobRepository.currentPublishedReviewSuggestion")(function* (input) {
4988
+ const current = (yield* reviewSuggestionRevisions.read({
4989
+ workspaceId: input.workspaceId,
4990
+ jobId: input.jobId,
4991
+ suggestionId: input.suggestionId,
4992
+ beforeSequence: null,
4993
+ limit: PrReviewSuggestionRevisionPageSize.make(1)
4994
+ })).current;
4995
+ if (current.revisionId !== input.revisionId || current.suggestion.state !== "published" || current.validation._tag !== "validated") return yield* new AgentJobInputError({
4996
+ workspaceId: input.workspaceId,
4997
+ jobId: input.jobId,
4998
+ reason: "invalid-transition"
4999
+ });
5000
+ return current;
5001
+ });
4622
5002
  return {
4623
5003
  appendReviewSuggestionRevision: Effect$1.fn("AgentJobRepository.appendReviewSuggestionRevision")(function* (input) {
4624
5004
  return yield* reviewSuggestionRevisions.append(input).pipe(mapPersistenceOperation("agent-job.append-review-suggestion-revision"));
4625
5005
  }),
5006
+ completeTargetedReview: Effect$1.fn("AgentJobRepository.completeTargetedReview")(function* (input) {
5007
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(CompleteTargetedReviewInput))(input);
5008
+ const report = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(PrReviewReport))(request.target.report).pipe(Effect$1.mapError(() => new AgentJobInputError({
5009
+ workspaceId: request.target.workspaceId,
5010
+ jobId: request.target.jobId,
5011
+ reason: "invalid-result"
5012
+ })));
5013
+ const encodedReport = yield* encodeReviewReport(report).pipe(Effect$1.mapError(() => new AgentJobInputError({
5014
+ workspaceId: request.target.workspaceId,
5015
+ jobId: request.target.jobId,
5016
+ reason: "invalid-result"
5017
+ })));
5018
+ return yield* database.transaction(Effect$1.gen(function* () {
5019
+ const job = yield* getJob(request.target.workspaceId, request.target.jobId);
5020
+ if (job.state === "cancel-requested") return yield* new AgentJobInputError({
5021
+ workspaceId: request.target.workspaceId,
5022
+ jobId: request.target.jobId,
5023
+ reason: "cancellation-requested"
5024
+ });
5025
+ if (job.state !== "running" || job.task._tag !== "pr-review" || job.subjectRevision !== job.task.subject.headRevision || !PrReviewSubjectEquivalence(job.task.subject, report.subject)) return yield* new AgentJobInputError({
5026
+ workspaceId: request.target.workspaceId,
5027
+ jobId: request.target.jobId,
5028
+ reason: "task-mismatch"
5029
+ });
5030
+ yield* validateLease({
5031
+ workspaceId: request.target.workspaceId,
5032
+ jobId: request.target.jobId,
5033
+ attemptSequence: request.target.attemptSequence,
5034
+ leaseToken: request.target.leaseToken,
5035
+ observedAt: request.target.completedAt
5036
+ });
5037
+ const revision = yield* reviewSuggestionRevisions.appendInTransaction(request.source);
5038
+ const eventSequence = yield* reserveEventSequence(request.target.workspaceId, job.threadId);
5039
+ yield* sql`INSERT INTO agent_thread_events (
5040
+ workspace_id, thread_id, event_sequence, job_id, attempt_sequence,
5041
+ event_kind, payload_json, payload_digest, payload_byte_length, occurred_at
5042
+ ) VALUES (
5043
+ ${request.target.workspaceId}, ${job.threadId}, ${eventSequence},
5044
+ ${request.target.jobId}, ${request.target.attemptSequence}, 'review-report',
5045
+ ${encodedReport.json}, ${encodedReport.digest}, ${encodedReport.bytes.length},
5046
+ ${encodeTimestamp$11(request.target.completedAt)}
5047
+ )`;
5048
+ yield* appendThreadEvent({
5049
+ workspaceId: request.target.workspaceId,
5050
+ threadId: job.threadId,
5051
+ jobId: request.target.jobId,
5052
+ attemptSequence: request.target.attemptSequence,
5053
+ eventKind: "job-completed",
5054
+ payload: {
5055
+ _tag: "completed",
5056
+ outcome: "success",
5057
+ sessionRef: null
5058
+ },
5059
+ payloadSchema: AgentRuntimeEvent,
5060
+ occurredAt: request.target.completedAt
5061
+ });
5062
+ yield* completeAttempt({
5063
+ workspaceId: request.target.workspaceId,
5064
+ jobId: request.target.jobId,
5065
+ attemptSequence: request.target.attemptSequence,
5066
+ completedAt: request.target.completedAt,
5067
+ outcome: "success",
5068
+ state: "succeeded",
5069
+ sessionRef: null,
5070
+ errorJson: null
5071
+ });
5072
+ return revision;
5073
+ })).pipe(mapPersistenceOperation("agent-job.complete-targeted-review"));
5074
+ }),
4626
5075
  enqueue: Effect$1.fn("AgentJobRepository.enqueue")(function* (input) {
4627
5076
  const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(EnqueueAgentJobInput))(input);
4628
5077
  if (request.task._tag === "pr-review" && (request.access !== "read-only" || request.subjectRevision !== request.task.subject.headRevision)) return yield* new AgentJobInputError({
@@ -4739,6 +5188,7 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4739
5188
  fingerprint: claimed.success.contextFingerprint,
4740
5189
  task
4741
5190
  });
5191
+ const reviewBudget = yield* reviewBudgetState(request.workspaceId, candidate.jobId, task);
4742
5192
  const contextPayload = yield* encodePayload(AgentContextSnapshotRecord, context);
4743
5193
  let sessionRef = null;
4744
5194
  if (candidate.attemptSequence > 0) {
@@ -4787,6 +5237,8 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4787
5237
  access: claimed.success.access,
4788
5238
  prompt: claimed.success.prompt,
4789
5239
  context,
5240
+ ...reviewBudget.reviewBudgetMillis === void 0 ? {} : { reviewBudgetMillis: reviewBudget.reviewBudgetMillis },
5241
+ reviewBudgetExtensionCount: reviewBudget.reviewBudgetExtensionCount,
4790
5242
  sessionRef,
4791
5243
  cancellationRequested: claimed.success.state === "cancel-requested"
4792
5244
  });
@@ -4942,18 +5394,64 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4942
5394
  return persistedEvent;
4943
5395
  })).pipe(mapPersistenceOperation("agent-job.append-event"));
4944
5396
  }),
5397
+ recordReviewProgress: Effect$1.fnUntraced(function* (input) {
5398
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(RecordAgentReviewProgressInput))(input);
5399
+ const agentReport = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(PrReviewReport))(request.report).pipe(Effect$1.mapError(() => new AgentJobInputError({
5400
+ workspaceId: request.workspaceId,
5401
+ jobId: request.jobId,
5402
+ reason: "invalid-result"
5403
+ })));
5404
+ if (!agentReport.suggestions.every(({ state }) => isAgentOwnedSuggestionState(state))) return yield* new AgentJobInputError({
5405
+ workspaceId: request.workspaceId,
5406
+ jobId: request.jobId,
5407
+ reason: "invalid-result"
5408
+ });
5409
+ const report = sanitizeAgentReviewReport(agentReport);
5410
+ return yield* database.transaction(Effect$1.gen(function* () {
5411
+ const job = yield* getJob(request.workspaceId, request.jobId);
5412
+ if (job.state !== "running" && job.state !== "cancel-requested" || job.task._tag !== "pr-review" || !PrReviewSubjectEquivalence(job.task.subject, report.subject)) return yield* new AgentJobInputError({
5413
+ workspaceId: request.workspaceId,
5414
+ jobId: request.jobId,
5415
+ reason: "task-mismatch"
5416
+ });
5417
+ yield* validateLease({
5418
+ workspaceId: request.workspaceId,
5419
+ jobId: request.jobId,
5420
+ attemptSequence: request.attemptSequence,
5421
+ leaseToken: request.leaseToken,
5422
+ observedAt: request.occurredAt
5423
+ });
5424
+ yield* appendThreadEvent({
5425
+ workspaceId: request.workspaceId,
5426
+ threadId: job.threadId,
5427
+ jobId: request.jobId,
5428
+ attemptSequence: request.attemptSequence,
5429
+ eventKind: "review-report",
5430
+ payload: report,
5431
+ payloadSchema: PrReviewReport,
5432
+ occurredAt: request.occurredAt
5433
+ });
5434
+ return yield* Schema$1.decodeUnknownEffect(Schema$1.toType(AgentReviewResultRecord))({
5435
+ workspaceId: request.workspaceId,
5436
+ jobId: request.jobId,
5437
+ attemptSequence: request.attemptSequence,
5438
+ report,
5439
+ completedAt: request.occurredAt
5440
+ });
5441
+ })).pipe(mapPersistenceOperation("agent-job.record-review-progress"));
5442
+ }, Effect$1.withTracerEnabled(false)),
4945
5443
  completeReview: Effect$1.fnUntraced(function* (input) {
4946
5444
  const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(CompleteAgentReviewInput))(input);
4947
- const report = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(PrReviewReport))(request.report).pipe(Effect$1.mapError(() => new AgentJobInputError({
5445
+ const agentReport = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(PrReviewReport))(request.report).pipe(Effect$1.mapError(() => new AgentJobInputError({
4948
5446
  workspaceId: request.workspaceId,
4949
5447
  jobId: request.jobId,
4950
5448
  reason: "invalid-result"
4951
5449
  })));
4952
- const encodedReport = yield* encodeReviewReport(report).pipe(Effect$1.mapError(() => new AgentJobInputError({
5450
+ if (!agentReport.suggestions.every(({ state }) => isAgentOwnedSuggestionState(state))) return yield* new AgentJobInputError({
4953
5451
  workspaceId: request.workspaceId,
4954
5452
  jobId: request.jobId,
4955
5453
  reason: "invalid-result"
4956
- })));
5454
+ });
4957
5455
  return yield* database.transaction(Effect$1.gen(function* () {
4958
5456
  const job = yield* getJob(request.workspaceId, request.jobId);
4959
5457
  if (job.state === "cancel-requested") return yield* new AgentJobInputError({
@@ -4961,11 +5459,66 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
4961
5459
  jobId: request.jobId,
4962
5460
  reason: "cancellation-requested"
4963
5461
  });
4964
- if (job.state !== "running" || job.task._tag !== "pr-review" || job.subjectRevision !== job.task.subject.headRevision || !PrReviewSubjectEquivalence(job.task.subject, report.subject)) return yield* new AgentJobInputError({
5462
+ if (job.state !== "running" || job.task._tag !== "pr-review" || job.subjectRevision !== job.task.subject.headRevision || !PrReviewSubjectEquivalence(job.task.subject, agentReport.subject)) return yield* new AgentJobInputError({
4965
5463
  workspaceId: request.workspaceId,
4966
5464
  jobId: request.jobId,
4967
5465
  reason: "task-mismatch"
4968
5466
  });
5467
+ const previous = yield* findPreviousReviewReport({
5468
+ workspaceId: request.workspaceId,
5469
+ pluginConnectionId: job.task.pluginConnectionId,
5470
+ subject: job.task.subject,
5471
+ excludeJobId: request.jobId
5472
+ });
5473
+ const previousReport = Option$1.isSome(previous) ? previous.value.report : PrReviewReport.make({
5474
+ ...agentReport,
5475
+ suggestions: [],
5476
+ transitions: []
5477
+ });
5478
+ if (Option$1.isSome(previous)) for (const suggestion of previous.value.report.suggestions) {
5479
+ if (suggestion.state !== "draft" && suggestion.state !== "published" && suggestion.state !== "reopened") continue;
5480
+ const currentRevision = yield* reviewSuggestionRevisions.read({
5481
+ workspaceId: request.workspaceId,
5482
+ jobId: previous.value.jobId,
5483
+ suggestionId: suggestion.suggestionId,
5484
+ beforeSequence: null,
5485
+ limit: PrReviewSuggestionRevisionPageSize.make(1)
5486
+ });
5487
+ if (currentRevision.current.suggestion.state !== "draft" && currentRevision.current.suggestion.state !== "published") continue;
5488
+ yield* reviewSuggestionRevisions.appendInTransaction({
5489
+ workspaceId: request.workspaceId,
5490
+ jobId: previous.value.jobId,
5491
+ suggestionId: suggestion.suggestionId,
5492
+ expectedRevisionId: currentRevision.current.revisionId,
5493
+ expectedSequence: currentRevision.current.sequence,
5494
+ edit: Schema$1.decodeUnknownSync(PrReviewSuggestionEdit)(currentRevision.current.suggestion),
5495
+ state: "stale",
5496
+ author: PrReviewSuggestionAgentAuthor.make({
5497
+ jobId: request.jobId,
5498
+ providerId: job.providerId,
5499
+ model: job.model,
5500
+ runtimeMetadata: null
5501
+ }),
5502
+ createdAt: request.completedAt
5503
+ });
5504
+ }
5505
+ const expectedTransitions = reconcilePrReviewReports(previousReport, agentReport);
5506
+ if (agentReport.transitions !== void 0) {
5507
+ if (validatePrReviewReportTransitions(previousReport, agentReport, agentReport.transitions)._tag === "failure") return yield* new AgentJobInputError({
5508
+ workspaceId: request.workspaceId,
5509
+ jobId: request.jobId,
5510
+ reason: "invalid-result"
5511
+ });
5512
+ }
5513
+ const report = PrReviewReport.make({
5514
+ ...agentReport,
5515
+ transitions: expectedTransitions
5516
+ });
5517
+ const encodedReport = yield* encodeReviewReport(report).pipe(Effect$1.mapError(() => new AgentJobInputError({
5518
+ workspaceId: request.workspaceId,
5519
+ jobId: request.jobId,
5520
+ reason: "invalid-result"
5521
+ })));
4969
5522
  yield* validateLease({
4970
5523
  workspaceId: request.workspaceId,
4971
5524
  jobId: request.jobId,
@@ -5016,12 +5569,43 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5016
5569
  });
5017
5570
  })).pipe(mapPersistenceOperation("agent-job.complete-review"));
5018
5571
  }, Effect$1.withTracerEnabled(false)),
5572
+ readReviewSuggestionPublication: Effect$1.fn("AgentJobRepository.readReviewSuggestionPublication")(function* (input) {
5573
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(ReadReviewSuggestionPublicationInput))(input);
5574
+ const rows = yield* sql`SELECT
5575
+ revision_id AS revisionId, content_digest AS contentDigest, state,
5576
+ publication_id AS publicationId, comment_id AS commentId,
5577
+ previous_content_digest AS previousContentDigest,
5578
+ previous_publication_id AS previousPublicationId,
5579
+ previous_published_at AS previousPublishedAt,
5580
+ reservation_id AS reservationId,
5581
+ reservation_acquired_at AS reservationAcquiredAt, reserved_at AS reservedAt,
5582
+ published_at AS publishedAt
5583
+ FROM agent_review_suggestion_publications
5584
+ WHERE workspace_id = ${request.workspaceId}
5585
+ AND job_id = ${request.jobId}
5586
+ AND suggestion_id = ${request.suggestionId}
5587
+ AND revision_id = ${request.revisionId}`;
5588
+ if (rows.length === 0) return null;
5589
+ const decoded = Schema$1.decodeUnknownResult(ReviewSuggestionPublicationRow)(rows[0]);
5590
+ if (Result$1.isFailure(decoded)) return yield* persistedRecordError(request.workspaceId, "agent-review-suggestion-publication", `${request.jobId}:${request.suggestionId}:${request.revisionId}`, "agent-review-suggestion-publication-schema-invalid");
5591
+ const row = decoded.success;
5592
+ if (row.state !== "published" || row.publicationId === null || row.commentId === null) return null;
5593
+ return yield* Schema$1.decodeUnknownEffect(ReadReviewSuggestionPublication)({
5594
+ state: row.state,
5595
+ publicationId: row.publicationId,
5596
+ commentId: row.commentId
5597
+ });
5598
+ }),
5019
5599
  reserveReviewSuggestionPublication: Effect$1.fn("AgentJobRepository.reserveReviewSuggestionPublication")(function* (input) {
5020
5600
  const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(ReserveReviewSuggestionPublicationInput))(input);
5021
5601
  return yield* database.transaction(Effect$1.gen(function* () {
5602
+ const operation = request.operation ?? "create";
5022
5603
  const existingRows = yield* sql`SELECT
5023
5604
  revision_id AS revisionId, content_digest AS contentDigest, state,
5024
- publication_id AS publicationId, reservation_id AS reservationId,
5605
+ publication_id AS publicationId, comment_id AS commentId,
5606
+ previous_content_digest AS previousContentDigest,
5607
+ previous_publication_id AS previousPublicationId,
5608
+ previous_published_at AS previousPublishedAt, reservation_id AS reservationId,
5025
5609
  reservation_acquired_at AS reservationAcquiredAt, reserved_at AS reservedAt,
5026
5610
  published_at AS publishedAt
5027
5611
  FROM agent_review_suggestion_publications
@@ -5031,23 +5615,54 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5031
5615
  AND revision_id = ${request.revisionId}`;
5032
5616
  if (existingRows.length > 0) {
5033
5617
  const existing = yield* Schema$1.decodeUnknownEffect(ReviewSuggestionPublicationRow)(existingRows[0]);
5034
- if (existing.contentDigest !== request.contentDigest) return yield* new AgentJobInputError({
5035
- workspaceId: request.workspaceId,
5036
- jobId: request.jobId,
5037
- reason: "invalid-transition"
5038
- });
5618
+ if (existing.contentDigest !== request.contentDigest) {
5619
+ if (operation !== "create" && existing.state === "published" && existing.publicationId !== null && existing.publishedAt !== null && existing.commentId !== null && existing.commentId === request.commentId) {
5620
+ yield* currentPublishedReviewSuggestion(request);
5621
+ yield* sql`UPDATE agent_review_suggestion_publications
5622
+ SET content_digest = ${request.contentDigest},
5623
+ state = 'reserved',
5624
+ publication_id = NULL,
5625
+ previous_content_digest = ${existing.contentDigest},
5626
+ previous_publication_id = ${existing.publicationId},
5627
+ previous_published_at = ${encodeTimestamp$11(existing.publishedAt)},
5628
+ reservation_id = ${request.reservationId},
5629
+ reservation_acquired_at = ${encodeTimestamp$11(request.reservedAt)},
5630
+ published_at = NULL
5631
+ WHERE workspace_id = ${request.workspaceId}
5632
+ AND job_id = ${request.jobId}
5633
+ AND suggestion_id = ${request.suggestionId}
5634
+ AND revision_id = ${request.revisionId}
5635
+ AND state = 'published'
5636
+ AND content_digest = ${existing.contentDigest}
5637
+ AND comment_id = ${request.commentId}`;
5638
+ return ReviewSuggestionPublicationReservation.make({
5639
+ _tag: (yield* readChanges(sql)) === 1 ? "acquired" : "in-progress",
5640
+ commentId: existing.commentId
5641
+ });
5642
+ }
5643
+ return yield* new AgentJobInputError({
5644
+ workspaceId: request.workspaceId,
5645
+ jobId: request.jobId,
5646
+ reason: "invalid-transition"
5647
+ });
5648
+ }
5039
5649
  return existing.state === "published" && existing.publicationId !== null && existing.publishedAt !== null ? ReviewSuggestionPublicationReservation.make({
5040
5650
  _tag: "published",
5041
5651
  publicationId: existing.publicationId,
5042
- publishedAt: existing.publishedAt
5652
+ publishedAt: existing.publishedAt,
5653
+ ...existing.commentId === null ? {} : { commentId: existing.commentId }
5043
5654
  }) : existing.publicationId !== null && existing.publishedAt !== null ? ReviewSuggestionPublicationReservation.make({
5044
5655
  _tag: "recoverable",
5045
5656
  publicationId: existing.publicationId,
5046
5657
  publishedAt: existing.publishedAt,
5047
- reservationId: existing.reservationId
5658
+ reservationId: existing.reservationId,
5659
+ ...existing.commentId === null ? {} : { commentId: existing.commentId }
5048
5660
  }) : yield* Effect$1.gen(function* () {
5049
5661
  const recoveryEligibleAt = DateTime$1.add(existing.reservationAcquiredAt, { minutes: REVIEW_SUGGESTION_PUBLICATION_RESERVATION_LIFETIME_MINUTES });
5050
- if (DateTime$1.Order(request.reservedAt, recoveryEligibleAt) < 0) return ReviewSuggestionPublicationReservation.make({ _tag: "in-progress" });
5662
+ if (DateTime$1.Order(request.reservedAt, recoveryEligibleAt) < 0) return ReviewSuggestionPublicationReservation.make({
5663
+ _tag: "in-progress",
5664
+ ...existing.commentId === null ? {} : { commentId: existing.commentId }
5665
+ });
5051
5666
  yield* sql`UPDATE agent_review_suggestion_publications
5052
5667
  SET reservation_id = ${request.reservationId},
5053
5668
  reservation_acquired_at = ${encodeTimestamp$11(request.reservedAt)}
@@ -5060,24 +5675,37 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5060
5675
  AND publication_id IS NULL
5061
5676
  AND reservation_id = ${existing.reservationId}
5062
5677
  AND reservation_acquired_at = ${encodeTimestamp$11(existing.reservationAcquiredAt)}`;
5063
- return ReviewSuggestionPublicationReservation.make({ _tag: (yield* readChanges(sql)) === 1 ? "acquired" : "in-progress" });
5678
+ return ReviewSuggestionPublicationReservation.make({
5679
+ _tag: (yield* readChanges(sql)) === 1 ? "acquired" : "in-progress",
5680
+ ...existing.commentId === null ? {} : { commentId: existing.commentId }
5681
+ });
5064
5682
  });
5065
5683
  }
5684
+ if (operation !== "create") return yield* new AgentJobInputError({
5685
+ workspaceId: request.workspaceId,
5686
+ jobId: request.jobId,
5687
+ reason: "invalid-transition"
5688
+ });
5066
5689
  yield* currentPublishableReviewSuggestion(request);
5067
5690
  const inserted = yield* sql`INSERT INTO agent_review_suggestion_publications (
5068
5691
  workspace_id, job_id, suggestion_id, revision_id, content_digest, state,
5069
- publication_id, reservation_id, reservation_acquired_at,
5070
- reserved_at, published_at
5692
+ publication_id, comment_id, reservation_id, reservation_acquired_at,
5693
+ reserved_at, published_at, previous_content_digest,
5694
+ previous_publication_id, previous_published_at
5071
5695
  ) VALUES (
5072
5696
  ${request.workspaceId}, ${request.jobId}, ${request.suggestionId},
5073
5697
  ${request.revisionId}, ${request.contentDigest}, 'reserved', NULL,
5698
+ NULL,
5074
5699
  ${request.reservationId}, ${encodeTimestamp$11(request.reservedAt)},
5075
- ${encodeTimestamp$11(request.reservedAt)}, NULL
5700
+ ${encodeTimestamp$11(request.reservedAt)}, NULL, NULL, NULL, NULL
5076
5701
  ) ON CONFLICT DO NOTHING
5077
5702
  RETURNING suggestion_id AS suggestionId`;
5078
5703
  const rows = yield* sql`SELECT
5079
5704
  revision_id AS revisionId, content_digest AS contentDigest, state,
5080
- publication_id AS publicationId, reservation_id AS reservationId,
5705
+ publication_id AS publicationId, comment_id AS commentId,
5706
+ previous_content_digest AS previousContentDigest,
5707
+ previous_publication_id AS previousPublicationId,
5708
+ previous_published_at AS previousPublishedAt, reservation_id AS reservationId,
5081
5709
  reservation_acquired_at AS reservationAcquiredAt, reserved_at AS reservedAt,
5082
5710
  published_at AS publishedAt
5083
5711
  FROM agent_review_suggestion_publications
@@ -5094,26 +5722,47 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5094
5722
  return row.success.state === "published" && row.success.publicationId !== null && row.success.publishedAt !== null ? ReviewSuggestionPublicationReservation.make({
5095
5723
  _tag: "published",
5096
5724
  publicationId: row.success.publicationId,
5097
- publishedAt: row.success.publishedAt
5725
+ publishedAt: row.success.publishedAt,
5726
+ ...row.success.commentId === null ? {} : { commentId: row.success.commentId }
5098
5727
  }) : row.success.publicationId !== null && row.success.publishedAt !== null ? ReviewSuggestionPublicationReservation.make({
5099
5728
  _tag: "recoverable",
5100
5729
  publicationId: row.success.publicationId,
5101
5730
  publishedAt: row.success.publishedAt,
5102
- reservationId: row.success.reservationId
5731
+ reservationId: row.success.reservationId,
5732
+ ...row.success.commentId === null ? {} : { commentId: row.success.commentId }
5103
5733
  }) : ReviewSuggestionPublicationReservation.make({ _tag: inserted.length === 1 ? "acquired" : "in-progress" });
5104
5734
  })).pipe(mapPersistenceOperation("agent-job.reserve-review-suggestion-publication"));
5105
5735
  }),
5106
5736
  releaseReviewSuggestionPublication: Effect$1.fn("AgentJobRepository.releaseReviewSuggestionPublication")(function* (input) {
5107
5737
  const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(ReleaseReviewSuggestionPublicationInput))(input);
5108
- yield* sql`DELETE FROM agent_review_suggestion_publications
5109
- WHERE workspace_id = ${request.workspaceId}
5110
- AND job_id = ${request.jobId}
5111
- AND suggestion_id = ${request.suggestionId}
5112
- AND revision_id = ${request.revisionId}
5113
- AND content_digest = ${request.contentDigest}
5114
- AND state = 'reserved'
5115
- AND publication_id IS NULL
5116
- AND reservation_id = ${request.reservationId}`.pipe(mapPersistenceOperation("agent-job.release-review-suggestion-publication"));
5738
+ yield* database.transaction(Effect$1.gen(function* () {
5739
+ yield* sql`UPDATE agent_review_suggestion_publications
5740
+ SET content_digest = previous_content_digest,
5741
+ state = 'published',
5742
+ publication_id = previous_publication_id,
5743
+ previous_content_digest = NULL,
5744
+ previous_publication_id = NULL,
5745
+ previous_published_at = NULL,
5746
+ published_at = previous_published_at
5747
+ WHERE workspace_id = ${request.workspaceId}
5748
+ AND job_id = ${request.jobId}
5749
+ AND suggestion_id = ${request.suggestionId}
5750
+ AND revision_id = ${request.revisionId}
5751
+ AND content_digest = ${request.contentDigest}
5752
+ AND state = 'reserved'
5753
+ AND publication_id IS NULL
5754
+ AND previous_content_digest IS NOT NULL
5755
+ AND reservation_id = ${request.reservationId}`;
5756
+ if ((yield* readChanges(sql)) === 0) yield* sql`DELETE FROM agent_review_suggestion_publications
5757
+ WHERE workspace_id = ${request.workspaceId}
5758
+ AND job_id = ${request.jobId}
5759
+ AND suggestion_id = ${request.suggestionId}
5760
+ AND revision_id = ${request.revisionId}
5761
+ AND content_digest = ${request.contentDigest}
5762
+ AND state = 'reserved'
5763
+ AND publication_id IS NULL
5764
+ AND reservation_id = ${request.reservationId}`;
5765
+ })).pipe(mapPersistenceOperation("agent-job.release-review-suggestion-publication"));
5117
5766
  }),
5118
5767
  recordReviewSuggestionPublication: Effect$1.fn("AgentJobRepository.recordReviewSuggestionPublication")(function* (input) {
5119
5768
  const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(RecordReviewSuggestionPublicationInput))(input);
@@ -5121,7 +5770,10 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5121
5770
  const job = yield* getJob(request.workspaceId, request.jobId);
5122
5771
  const publicationRows = yield* sql`SELECT
5123
5772
  revision_id AS revisionId, content_digest AS contentDigest, state,
5124
- publication_id AS publicationId, reservation_id AS reservationId,
5773
+ publication_id AS publicationId, comment_id AS commentId,
5774
+ previous_content_digest AS previousContentDigest,
5775
+ previous_publication_id AS previousPublicationId,
5776
+ previous_published_at AS previousPublishedAt, reservation_id AS reservationId,
5125
5777
  reservation_acquired_at AS reservationAcquiredAt, reserved_at AS reservedAt,
5126
5778
  published_at AS publishedAt
5127
5779
  FROM agent_review_suggestion_publications
@@ -5136,7 +5788,7 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5136
5788
  reason: "invalid-transition"
5137
5789
  });
5138
5790
  if (publication.success.state === "published") {
5139
- if (publication.success.contentDigest === request.contentDigest && publication.success.publicationId === request.publicationId) return;
5791
+ if (publication.success.contentDigest === request.contentDigest && publication.success.publicationId === request.publicationId && (request.commentId === void 0 || publication.success.commentId === request.commentId)) return;
5140
5792
  return yield* new AgentJobInputError({
5141
5793
  workspaceId: request.workspaceId,
5142
5794
  jobId: request.jobId,
@@ -5148,9 +5800,18 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5148
5800
  jobId: request.jobId,
5149
5801
  reason: "invalid-transition"
5150
5802
  });
5803
+ if (request.commentId !== void 0 && publication.success.commentId !== null && publication.success.commentId !== request.commentId) return yield* new AgentJobInputError({
5804
+ workspaceId: request.workspaceId,
5805
+ jobId: request.jobId,
5806
+ reason: "invalid-transition"
5807
+ });
5151
5808
  if (request.finalize === false) {
5152
5809
  yield* sql`UPDATE agent_review_suggestion_publications
5153
5810
  SET publication_id = ${request.publicationId},
5811
+ comment_id = COALESCE(${request.commentId ?? null}, comment_id),
5812
+ previous_content_digest = NULL,
5813
+ previous_publication_id = NULL,
5814
+ previous_published_at = NULL,
5154
5815
  published_at = ${encodeTimestamp$11(request.publishedAt)}
5155
5816
  WHERE workspace_id = ${request.workspaceId}
5156
5817
  AND job_id = ${request.jobId}
@@ -5178,10 +5839,15 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5178
5839
  workspaceId: request.workspaceId,
5179
5840
  jobId: request.jobId
5180
5841
  });
5181
- yield* currentPublishableReviewSuggestion(request);
5842
+ if ((request.operation ?? "create") === "create") yield* currentPublishableReviewSuggestion(request);
5843
+ else yield* currentPublishedReviewSuggestion(request);
5182
5844
  yield* sql`UPDATE agent_review_suggestion_publications
5183
5845
  SET state = 'published',
5184
5846
  publication_id = ${request.publicationId},
5847
+ comment_id = COALESCE(${request.commentId ?? null}, comment_id),
5848
+ previous_content_digest = NULL,
5849
+ previous_publication_id = NULL,
5850
+ previous_published_at = NULL,
5185
5851
  published_at = ${encodeTimestamp$11(request.publishedAt)}
5186
5852
  WHERE workspace_id = ${request.workspaceId}
5187
5853
  AND job_id = ${request.jobId}
@@ -5260,6 +5926,181 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5260
5926
  return persistedEvent;
5261
5927
  })).pipe(mapPersistenceOperation("agent-job.fail-attempt"));
5262
5928
  }),
5929
+ listRunningPrReviewAttempts: Effect$1.fn("AgentJobRepository.listRunningPrReviewAttempts")(function* (workspaceId) {
5930
+ const rows = yield* sql`SELECT
5931
+ job.job_id AS jobId, attempt.attempt_sequence AS attemptSequence,
5932
+ job.provider_id AS providerId, attempt.session_ref AS sessionRef
5933
+ FROM agent_jobs job
5934
+ JOIN agent_job_attempts attempt
5935
+ ON attempt.workspace_id = job.workspace_id
5936
+ AND attempt.job_id = job.job_id
5937
+ WHERE job.workspace_id = ${workspaceId}
5938
+ AND job.state IN ('running', 'cancel-requested')
5939
+ AND attempt.completed_at IS NULL
5940
+ ORDER BY job.job_id, attempt.attempt_sequence`;
5941
+ const attempts = [];
5942
+ for (const row of rows) {
5943
+ const jobId = yield* Schema$1.decodeUnknownEffect(JobId)(row.jobId).pipe(Effect$1.mapError(() => new PersistenceOperationError({ operation: "agent-job.running-review-job-id" })));
5944
+ const attemptSequence = yield* Schema$1.decodeUnknownEffect(AgentAttemptSequence)(row.attemptSequence).pipe(Effect$1.mapError(() => new PersistenceOperationError({ operation: "agent-job.running-review-attempt-sequence" })));
5945
+ const providerId = yield* Schema$1.decodeUnknownEffect(Schema$1.String)(row.providerId).pipe(Effect$1.mapError(() => new PersistenceOperationError({ operation: "agent-job.running-review-provider-id" })));
5946
+ if ((yield* getJob(workspaceId, jobId)).task._tag !== "pr-review") continue;
5947
+ const digest = yield* cryptoService.digest("SHA-256", yield* bytesFromText(`${providerId}:${jobId}:${String(attemptSequence)}`)).pipe(Effect$1.mapError(() => new PersistenceOperationError({ operation: "agent-job.running-review-attempt-id" })));
5948
+ const attempt = Schema$1.decodeUnknownResult(RunningPrReviewAttempt)({
5949
+ jobId,
5950
+ attemptSequence,
5951
+ attemptId: Encoding$1.encodeHex(digest).slice(0, 12),
5952
+ sessionRef: row.sessionRef
5953
+ });
5954
+ if (Result$1.isFailure(attempt)) return yield* new PersistenceOperationError({ operation: "agent-job.running-review-attempt-invalid" });
5955
+ attempts.push(attempt.success);
5956
+ }
5957
+ return attempts;
5958
+ }),
5959
+ attachRunningPrReviewSession: Effect$1.fn("AgentJobRepository.attachRunningPrReviewSession")(function* (input) {
5960
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(AttachRunningPrReviewSessionInput))(input);
5961
+ yield* sql`UPDATE agent_job_attempts
5962
+ SET session_ref = ${request.sessionRef}
5963
+ WHERE workspace_id = ${request.workspaceId}
5964
+ AND job_id = ${request.jobId}
5965
+ AND attempt_sequence = ${request.attemptSequence}
5966
+ AND completed_at IS NULL
5967
+ AND EXISTS (
5968
+ SELECT 1 FROM agent_jobs job
5969
+ WHERE job.workspace_id = agent_job_attempts.workspace_id
5970
+ AND job.job_id = agent_job_attempts.job_id
5971
+ AND job.state IN ('running', 'cancel-requested')
5972
+ )`;
5973
+ }),
5974
+ interruptRunningReviews: Effect$1.fn("AgentJobRepository.interruptRunningReviews")(function* (input) {
5975
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(InterruptRunningReviewsInput))(input);
5976
+ return yield* database.transaction(Effect$1.gen(function* () {
5977
+ const rows = yield* sql`SELECT job_id AS jobId
5978
+ FROM agent_jobs
5979
+ WHERE workspace_id = ${request.workspaceId}
5980
+ AND state IN ('running', 'cancel-requested')`;
5981
+ let interrupted = 0;
5982
+ for (const row of rows) {
5983
+ const jobId = yield* Schema$1.decodeUnknownEffect(JobId)(row.jobId).pipe(Effect$1.mapError(() => new PersistenceOperationError({ operation: "agent-job.interrupt-job-id" })));
5984
+ const job = yield* getJob(request.workspaceId, jobId);
5985
+ if (job.task._tag !== "pr-review") continue;
5986
+ const attemptRows = yield* sql`SELECT attempt_sequence AS attemptSequence
5987
+ FROM agent_job_attempts
5988
+ WHERE workspace_id = ${request.workspaceId}
5989
+ AND job_id = ${jobId}
5990
+ AND completed_at IS NULL
5991
+ ORDER BY attempt_sequence DESC
5992
+ LIMIT 1`;
5993
+ const attempt = Schema$1.decodeUnknownResult(Schema$1.Struct({ attemptSequence: AgentAttemptSequence }))(attemptRows[0]);
5994
+ if (Result$1.isFailure(attempt)) continue;
5995
+ if (request.preservedAttempts?.some((preserved) => preserved.jobId === jobId && preserved.attemptSequence === attempt.success.attemptSequence)) continue;
5996
+ const existing = yield* readReviewResult({
5997
+ workspaceId: request.workspaceId,
5998
+ jobId
5999
+ }).pipe(Effect$1.result);
6000
+ if (Result$1.isFailure(existing) && existing.failure._tag !== "RecordNotFoundError") return yield* existing.failure;
6001
+ const report = Result$1.isSuccess(existing) ? {
6002
+ ...existing.success.report,
6003
+ completion: {
6004
+ status: "unable-to-conclude",
6005
+ reason: PROCESS_RESTART_INTERRUPTION_MESSAGE
6006
+ }
6007
+ } : {
6008
+ schemaVersion: 3,
6009
+ subject: job.task.subject,
6010
+ completion: {
6011
+ status: "unable-to-conclude",
6012
+ reason: PROCESS_RESTART_INTERRUPTION_MESSAGE
6013
+ },
6014
+ suggestions: [],
6015
+ notes: []
6016
+ };
6017
+ yield* appendThreadEvent({
6018
+ workspaceId: request.workspaceId,
6019
+ threadId: job.threadId,
6020
+ jobId,
6021
+ attemptSequence: attempt.success.attemptSequence,
6022
+ eventKind: "review-report",
6023
+ payload: report,
6024
+ payloadSchema: PrReviewReport,
6025
+ occurredAt: request.interruptedAt
6026
+ });
6027
+ const error = new AgentProviderError({
6028
+ providerId: job.providerId,
6029
+ phase: "execution",
6030
+ message: PROCESS_RESTART_INTERRUPTION_MESSAGE,
6031
+ retryable: false
6032
+ });
6033
+ const encodedFailure = yield* encodePayload(ProviderFailurePayload, { error });
6034
+ yield* appendThreadEvent({
6035
+ workspaceId: request.workspaceId,
6036
+ threadId: job.threadId,
6037
+ jobId,
6038
+ attemptSequence: attempt.success.attemptSequence,
6039
+ eventKind: "job-failed",
6040
+ payload: { error },
6041
+ payloadSchema: ProviderFailurePayload,
6042
+ occurredAt: request.interruptedAt
6043
+ });
6044
+ yield* completeAttempt({
6045
+ workspaceId: request.workspaceId,
6046
+ jobId,
6047
+ attemptSequence: attempt.success.attemptSequence,
6048
+ completedAt: request.interruptedAt,
6049
+ outcome: "failed",
6050
+ state: "failed",
6051
+ sessionRef: null,
6052
+ errorJson: encodedFailure.json
6053
+ });
6054
+ interrupted += 1;
6055
+ }
6056
+ return { interrupted };
6057
+ })).pipe(mapPersistenceOperation("agent-job.interrupt-running-reviews"));
6058
+ }),
6059
+ reviewBudget: Effect$1.fn("AgentJobRepository.reviewBudget")(function* (input) {
6060
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(ReadReviewBudgetInput))(input);
6061
+ return yield* reviewBudgetState(request.workspaceId, request.jobId, request.task);
6062
+ }),
6063
+ extendReviewBudget: Effect$1.fn("AgentJobRepository.extendReviewBudget")(function* (input) {
6064
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(ExtendReviewBudgetInput))(input);
6065
+ return yield* database.transaction(Effect$1.gen(function* () {
6066
+ const job = yield* getJob(request.workspaceId, request.jobId);
6067
+ if (job.task._tag !== "pr-review" || job.state !== "running") return yield* new AgentJobInputError({
6068
+ workspaceId: request.workspaceId,
6069
+ jobId: request.jobId,
6070
+ reason: "invalid-transition"
6071
+ });
6072
+ const current = yield* reviewBudgetState(request.workspaceId, request.jobId, job.task);
6073
+ if (current.reviewBudgetExtensionCount >= 1 || current.reviewBudgetMillis === void 0 || current.reviewBudgetMillis + job.task.reviewProfile.budgetMillis > 36e5) return yield* new AgentJobInputError({
6074
+ workspaceId: request.workspaceId,
6075
+ jobId: request.jobId,
6076
+ reason: "invalid-transition"
6077
+ });
6078
+ const reviewBudgetMillis = current.reviewBudgetMillis + job.task.reviewProfile.budgetMillis;
6079
+ yield* appendThreadEvent({
6080
+ workspaceId: request.workspaceId,
6081
+ threadId: job.threadId,
6082
+ jobId: request.jobId,
6083
+ attemptSequence: null,
6084
+ eventKind: "job-queued",
6085
+ payload: {
6086
+ access: job.access,
6087
+ contextFingerprint: job.contextFingerprint,
6088
+ model: job.model,
6089
+ providerId: job.providerId,
6090
+ subjectRevision: job.subjectRevision,
6091
+ task: job.task,
6092
+ reviewBudgetMillis,
6093
+ reviewBudgetExtensionCount: 1
6094
+ },
6095
+ payloadSchema: PersistedJobQueuedPayload,
6096
+ occurredAt: request.extendedAt
6097
+ });
6098
+ return {
6099
+ reviewBudgetMillis,
6100
+ reviewBudgetExtensionCount: 1
6101
+ };
6102
+ })).pipe(mapPersistenceOperation("agent-job.extend-review-budget"));
6103
+ }),
5263
6104
  requestCancellation: Effect$1.fn("AgentJobRepository.requestCancellation")(function* (input) {
5264
6105
  const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(RequestAgentCancellationInput))(input);
5265
6106
  yield* database.transaction(Effect$1.gen(function* () {
@@ -5299,10 +6140,13 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5299
6140
  const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(LatestAgentReviewInput))(input);
5300
6141
  const subjectJson = yield* Schema$1.encodeUnknownEffect(Schema$1.fromJsonString(PrReviewSubject))(request.subject).pipe(Effect$1.mapError(() => new PersistenceOperationError({ operation: "agent-job.latest-review-subject" })));
5301
6142
  const taskContextPrefix = `{"_tag":"pr-review","pluginConnectionId":"${request.pluginConnectionId}","subject":${subjectJson},"reviewProfile":`;
6143
+ const identityPrefix = taskContextPrefix.slice(0, taskContextPrefix.indexOf("\"baseRevision\""));
5302
6144
  const rendered = renderLatestAgentReviewQuery({
5303
6145
  workspaceId: request.workspaceId,
5304
- subjectRevision: request.subject.headRevision,
5305
- taskContextPrefix,
6146
+ ...request.excludeJobId === void 0 ? {} : { excludeJobId: request.excludeJobId },
6147
+ ...request.allowDifferentHead === true ? {} : { subjectRevision: request.subject.headRevision },
6148
+ taskContextPrefix: request.allowDifferentHead === true ? identityPrefix : taskContextPrefix,
6149
+ excludeTargeted: true,
5306
6150
  ...request.jobId === void 0 ? {} : { jobId: request.jobId }
5307
6151
  });
5308
6152
  const rows = yield* sql.unsafe(rendered.sql, [...rendered.params]).pipe(mapPersistenceOperation("agent-job.latest-review"));
@@ -5310,11 +6154,28 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5310
6154
  const row = Schema$1.decodeUnknownResult(LatestReviewRow)(rows[0]);
5311
6155
  if (rows.length !== 1 || Result$1.isFailure(row)) return yield* persistedRecordError(request.workspaceId, "agent-review", request.subject.pullRequestId, "agent-review-latest-schema-invalid");
5312
6156
  const task = yield* decodeTaskContext(request.workspaceId, row.success.jobId, row.success.taskContextJson, row.success.taskContextDigest);
5313
- if (task._tag !== "pr-review" || task.pluginConnectionId !== request.pluginConnectionId || !PrReviewSubjectEquivalence(task.subject, request.subject)) return yield* persistedRecordError(request.workspaceId, "agent-review", request.subject.pullRequestId, "agent-review-subject-mismatch");
5314
- const report = row.success.state === "succeeded" ? (yield* readReviewResult({
6157
+ let interrupted = false;
6158
+ if (row.success.state === "failed") {
6159
+ const interruptionRows = yield* sql`SELECT COUNT(*) AS interrupted
6160
+ FROM agent_thread_events
6161
+ WHERE workspace_id = ${request.workspaceId}
6162
+ AND job_id = ${row.success.jobId}
6163
+ AND event_kind = 'job-failed'
6164
+ AND payload_json LIKE ${`%${PROCESS_RESTART_INTERRUPTION_MESSAGE}%`}`.pipe(mapPersistenceOperation("agent-job.latest-review-interruption"));
6165
+ interrupted = Number(interruptionRows[0]?.interrupted ?? 0) > 0;
6166
+ }
6167
+ if (task._tag !== "pr-review" || task.pluginConnectionId !== request.pluginConnectionId || (request.allowDifferentHead === true ? task.subject.providerId !== request.subject.providerId || task.subject.repository !== request.subject.repository || task.subject.pullRequestId !== request.subject.pullRequestId : !PrReviewSubjectEquivalence(task.subject, request.subject))) return yield* persistedRecordError(request.workspaceId, "agent-review", request.subject.pullRequestId, "agent-review-subject-mismatch");
6168
+ const reviewBudget = yield* reviewBudgetState(request.workspaceId, row.success.jobId, task);
6169
+ const startedRows = yield* sql`SELECT MAX(started_at) AS startedAt
6170
+ FROM agent_job_attempts
6171
+ WHERE workspace_id = ${request.workspaceId} AND job_id = ${row.success.jobId}`.pipe(mapPersistenceOperation("agent-job.latest-review-started-at"));
6172
+ const startedAt = Schema$1.decodeUnknownResult(Schema$1.Struct({ startedAt: Schema$1.NullOr(UtcTimestamp) }))(startedRows[0]);
6173
+ if (startedRows.length !== 1 || Result$1.isFailure(startedAt)) return yield* persistedRecordError(request.workspaceId, "agent-review", request.subject.pullRequestId, "agent-review-started-at-schema-invalid");
6174
+ const reviewResult = row.success.state === "succeeded" || row.success.state === "failed" || row.success.state === "cancelled" ? yield* readReviewResult({
5315
6175
  workspaceId: request.workspaceId,
5316
6176
  jobId: row.success.jobId
5317
- })).report : null;
6177
+ }).pipe(Effect$1.catchTag("RecordNotFoundError", () => Effect$1.succeed(null))) : null;
6178
+ const report = reviewResult === null ? null : reviewResult.report;
5318
6179
  const activityRows = yield* sql`SELECT
5319
6180
  workspace_id AS workspaceId, thread_id AS threadId,
5320
6181
  event_sequence AS eventSequence, job_id AS jobId,
@@ -5338,6 +6199,11 @@ var makeAgentJobRepository = Effect$1.gen(function* () {
5338
6199
  }
5339
6200
  const record = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(LatestAgentReviewRecord))({
5340
6201
  ...row.success,
6202
+ state: interrupted ? "interrupted" : row.success.state,
6203
+ startedAt: startedAt.success.startedAt,
6204
+ ...reviewBudget.reviewBudgetMillis === void 0 ? {} : { reviewBudgetMillis: reviewBudget.reviewBudgetMillis },
6205
+ reviewBudgetExtensionCount: reviewBudget.reviewBudgetExtensionCount,
6206
+ taskIntent: task.intent ?? null,
5341
6207
  report,
5342
6208
  reviewProfile: task.reviewProfile,
5343
6209
  activity: {
@@ -8443,6 +9309,12 @@ var GovernedActionTargetReadInput = Schema$1.Struct({
8443
9309
  maximum: 100
8444
9310
  }))
8445
9311
  });
9312
+ /** Bounded batched lookup for the latest successful publications of exact releases. */
9313
+ var GovernedActionReleasePublicationReadInput = Schema$1.Struct({
9314
+ workspaceId: WorkspaceId,
9315
+ providerId: Schema$1.Literal("confluence"),
9316
+ releaseIds: Schema$1.Array(ReleaseId).check(Schema$1.isMinLength(1), Schema$1.isMaxLength(200), Schema$1.isUnique())
9317
+ });
8446
9318
  Schema$1.Struct({
8447
9319
  envelope: GovernedActionEnvelopeV1,
8448
9320
  head: GovernedActionLifecycleHeadV1,
@@ -9252,6 +10124,10 @@ var GovernedActionTargetCandidateIdentity = Schema$1.Struct({
9252
10124
  actionId: GovernedActionId,
9253
10125
  sortAt: UtcTimestamp
9254
10126
  });
10127
+ var GovernedActionReleasePublicationCandidate = Schema$1.Struct({
10128
+ actionId: GovernedActionId,
10129
+ releaseId: ReleaseId
10130
+ });
9255
10131
  var malformed = (request, recordKind, diagnosticCode, recordKey = request.actionId) => governedActionRecordError({
9256
10132
  workspaceId: request.workspaceId,
9257
10133
  recordKind,
@@ -9561,6 +10437,61 @@ var makeGovernedActionRead = Effect$1.gen(function* () {
9561
10437
  cursor = identities[identities.length - 1] ?? null;
9562
10438
  }
9563
10439
  return selectLatestTerminalByTarget(request, candidates);
10440
+ }),
10441
+ readLatestTerminalReleasePublications: Effect$1.fn("GovernedActionReader.readLatestTerminalReleasePublications")(function* (request) {
10442
+ const releaseIdsJson = JSON.stringify(request.releaseIds);
10443
+ const rows = yield* sql`WITH requested_release_ids AS (
10444
+ SELECT value AS releaseId
10445
+ FROM json_each(${releaseIdsJson})
10446
+ ),
10447
+ ranked_publications AS (
10448
+ SELECT
10449
+ publication.action_id AS actionId,
10450
+ publication.release_id AS releaseId,
10451
+ ROW_NUMBER() OVER (
10452
+ PARTITION BY publication.release_id
10453
+ ORDER BY action.updated_at DESC, action.action_id DESC
10454
+ ) AS candidateRank
10455
+ FROM governed_action_release_publications AS publication
10456
+ JOIN governed_actions AS action
10457
+ ON action.workspace_id = publication.workspace_id
10458
+ AND action.action_id = publication.action_id
10459
+ JOIN governed_action_target_dimensions AS dimensions
10460
+ ON dimensions.workspace_id = action.workspace_id
10461
+ AND dimensions.action_id = action.action_id
10462
+ JOIN requested_release_ids AS requested
10463
+ ON requested.releaseId = publication.release_id
10464
+ WHERE publication.workspace_id = ${request.workspaceId}
10465
+ AND publication.provider_id = ${request.providerId}
10466
+ AND action.state IN (
10467
+ 'proposed', 'authorized', 'started', 'cancel-requested',
10468
+ 'unknown', 'cancel-requested-unknown', 'succeeded'
10469
+ )
10470
+ AND dimensions.action_kind IN ('create-page', 'update-page')
10471
+ )
10472
+ SELECT actionId, releaseId
10473
+ FROM ranked_publications
10474
+ WHERE candidateRank = 1
10475
+ ORDER BY releaseId`;
10476
+ const candidates = yield* Schema$1.decodeUnknownEffect(Schema$1.Array(GovernedActionReleasePublicationCandidate).check(Schema$1.isMaxLength(request.releaseIds.length)))(rows).pipe(Effect$1.mapError(() => new PersistedRecordError({
10477
+ workspaceId: request.workspaceId,
10478
+ recordKind: "governed-action",
10479
+ recordKey: request.workspaceId,
10480
+ diagnosticCode: "governed-action-schema-invalid"
10481
+ })));
10482
+ return yield* Effect$1.forEach(candidates, ({ actionId, releaseId }) => read({
10483
+ workspaceId: request.workspaceId,
10484
+ actionId
10485
+ }).pipe(Effect$1.flatMap((record) => {
10486
+ const publication = record.envelope.releasePublication;
10487
+ const actionKind = record.envelope.proposal.request.actionKind;
10488
+ return publication !== void 0 && publication.releaseId === releaseId && record.envelope.providerId === request.providerId && (actionKind === "create-page" || actionKind === "update-page") && (record.head.state === "proposed" || record.head.state === "authorized" || record.head.state === "started" || record.head.state === "cancel-requested" || record.head.state === "unknown" || record.head.state === "cancel-requested-unknown" || record.head.state === "succeeded" && record.head.lineage._tag === "terminal" && record.head.lineage.receipt.status === "succeeded") ? Effect$1.succeed(record) : Effect$1.fail(new PersistedRecordError({
10489
+ workspaceId: request.workspaceId,
10490
+ recordKind: "governed-action",
10491
+ recordKey: actionId,
10492
+ diagnosticCode: "governed-action-identity-mismatch"
10493
+ }));
10494
+ })));
9564
10495
  })
9565
10496
  };
9566
10497
  });
@@ -9596,11 +10527,13 @@ var makeGovernedActionTransaction = Effect$1.gen(function* () {
9596
10527
  const read = (request) => reader.read(request).pipe(Effect$1.provideService(Crypto$1.Crypto, cryptoService));
9597
10528
  const readByIdempotencyKey = (request) => reader.readByIdempotencyKey(request).pipe(Effect$1.provideService(Crypto$1.Crypto, cryptoService));
9598
10529
  const readLatestTerminalByTarget = (request) => reader.readLatestTerminalByTarget(request).pipe(Effect$1.provideService(Crypto$1.Crypto, cryptoService));
10530
+ const readLatestTerminalReleasePublications = (request) => reader.readLatestTerminalReleasePublications(request).pipe(Effect$1.provideService(Crypto$1.Crypto, cryptoService));
9599
10531
  return {
9600
10532
  capture,
9601
10533
  read,
9602
10534
  readByIdempotencyKey,
9603
10535
  readLatestTerminalByTarget,
10536
+ readLatestTerminalReleasePublications,
9604
10537
  transact
9605
10538
  };
9606
10539
  });
@@ -10066,6 +10999,28 @@ var makeGovernedActionTransactionWrite = Effect$1.gen(function* () {
10066
10999
  ${input.envelope.proposal.request.actionKind},
10067
11000
  ${input.envelope.proposal.request.expectedRevision}
10068
11001
  )`;
11002
+ if (input.envelope.releasePublication !== void 0) {
11003
+ yield* sql`INSERT INTO governed_action_release_publications (
11004
+ workspace_id, action_id, provider_id, release_id, predecessor_action_id
11005
+ ) VALUES (
11006
+ ${input.envelope.workspaceId}, ${input.envelope.actionId},
11007
+ ${input.envelope.providerId}, ${input.envelope.releasePublication.releaseId},
11008
+ ${input.envelope.releasePublication.predecessorPublicationActionId ?? null}
11009
+ )`;
11010
+ if (input.envelope.providerId === "confluence") yield* sql`INSERT INTO governed_action_release_publication_slots (
11011
+ workspace_id, action_id, provider_id, release_id, predecessor_action_id
11012
+ ) VALUES (
11013
+ ${input.envelope.workspaceId}, ${input.envelope.actionId},
11014
+ ${input.envelope.providerId}, ${input.envelope.releasePublication.releaseId},
11015
+ ${input.envelope.releasePublication.predecessorPublicationActionId ?? null}
11016
+ )`;
11017
+ } else yield* sql`INSERT INTO governed_action_entity_targets (
11018
+ workspace_id, action_id, plugin_connection_id, provider_id, entity_id
11019
+ ) VALUES (
11020
+ ${input.envelope.workspaceId}, ${input.envelope.actionId},
11021
+ ${input.envelope.pluginConnectionId}, ${input.envelope.providerId},
11022
+ ${input.envelope.targetEntityId}
11023
+ )`;
10069
11024
  } else {
10070
11025
  yield* verifyRootIdentity(input, envelopeJson, root).pipe(captureMalformedGovernedActionRow(root));
10071
11026
  if (input.command._tag === "propose") return yield* inputError("conflicting-action-identity");
@@ -10198,6 +11153,13 @@ var makeGovernedActionRepository = Effect$1.gen(function* () {
10198
11153
  reason: "invalid-request"
10199
11154
  })));
10200
11155
  return yield* transaction.transact("governed-action.read-latest-terminal-by-target", transaction.readLatestTerminalByTarget(request));
11156
+ }),
11157
+ readLatestTerminalReleasePublications: Effect$1.fn("GovernedActionRepository.readLatestTerminalReleasePublications")(function* (input) {
11158
+ const request = yield* Schema$1.decodeUnknownEffect(Schema$1.toType(GovernedActionReleasePublicationReadInput))(input).pipe(Effect$1.mapError(() => new GovernedActionInputError({
11159
+ operation: "read",
11160
+ reason: "invalid-request"
11161
+ })));
11162
+ return yield* transaction.transact("governed-action.read-latest-terminal-release-publications", transaction.readLatestTerminalReleasePublications(request));
10201
11163
  })
10202
11164
  };
10203
11165
  });
@@ -16155,13 +17117,11 @@ var makeRetentionRepository = Effect$1.gen(function* () {
16155
17117
  SELECT 1 FROM agent_review_suggestion_revisions revision
16156
17118
  WHERE revision.workspace_id = job.workspace_id
16157
17119
  AND revision.source_job_id = job.job_id
16158
- AND revision.created_at > ${cutoffAt}
16159
17120
  )
16160
17121
  AND NOT EXISTS (
16161
17122
  SELECT 1 FROM agent_thread_events event
16162
17123
  WHERE event.workspace_id = job.workspace_id
16163
17124
  AND event.job_id = job.job_id
16164
- AND event.occurred_at > ${cutoffAt}
16165
17125
  )
16166
17126
  AND NOT EXISTS (
16167
17127
  SELECT 1 FROM domain_events event
@@ -16178,12 +17138,6 @@ var makeRetentionRepository = Effect$1.gen(function* () {
16178
17138
  yield* Effect$1.forEach(jobIds, (jobId) => sql`INSERT INTO retention_cleanup_claims (
16179
17139
  workspace_id, run_id, retention_class, record_key
16180
17140
  ) VALUES (${workspaceId}, ${run.runId}, 'agent-content', ${jobId})`, { discard: true });
16181
- yield* sql`DELETE FROM agent_review_suggestion_revisions
16182
- WHERE workspace_id = ${workspaceId}
16183
- AND source_job_id IN ${sql.in(jobIds)}`;
16184
- yield* sql`DELETE FROM agent_thread_events
16185
- WHERE workspace_id = ${workspaceId}
16186
- AND job_id IN ${sql.in(jobIds)}`;
16187
17141
  yield* sql`DELETE FROM agent_job_leases
16188
17142
  WHERE workspace_id = ${workspaceId}
16189
17143
  AND job_id IN ${sql.in(jobIds)}`;
@@ -16891,13 +17845,24 @@ var makePersistence = Effect.gen(function* () {
16891
17845
  appendReviewSuggestionRevision: (...args) => publicOperation("agent-job.append-review-suggestion-revision", agentJobs.appendReviewSuggestionRevision(...args)),
16892
17846
  claimNext: (...args) => publicOperation("agent-job.claim-next", agentJobs.claimNext(...args)),
16893
17847
  completeReview: (...args) => publicOperation("agent-job.complete-review", agentJobs.completeReview(...args)),
17848
+ recordReviewProgress: (...args) => publicOperation("agent-job.record-review-progress", agentJobs.recordReviewProgress(...args)),
16894
17849
  enqueue: (...args) => publicOperation("agent-job.enqueue", agentJobs.enqueue(...args)),
16895
17850
  failAttempt: (...args) => publicOperation("agent-job.fail-attempt", agentJobs.failAttempt(...args)),
16896
17851
  latestReview: (...args) => publicOperation("agent-job.latest-review", agentJobs.latestReview(...args)),
17852
+ latestReviewForPullRequest: (...args) => publicOperation("agent-job.latest-review-for-pull-request", agentJobs.latestReview({
17853
+ ...args[0],
17854
+ allowDifferentHead: true
17855
+ })),
17856
+ listRunningPrReviewAttempts: (...args) => publicOperation("agent-job.list-running-pr-review-attempts", agentJobs.listRunningPrReviewAttempts(...args)),
17857
+ attachRunningPrReviewSession: (...args) => publicOperation("agent-job.attach-running-pr-review-session", agentJobs.attachRunningPrReviewSession(...args)),
17858
+ readReviewSuggestionPublication: (...args) => publicOperation("agent-job.read-review-suggestion-publication", agentJobs.readReviewSuggestionPublication(...args)),
16897
17859
  releaseReviewSuggestionPublication: (...args) => publicOperation("agent-job.release-review-suggestion-publication", agentJobs.releaseReviewSuggestionPublication(...args)),
16898
17860
  reserveReviewSuggestionPublication: (...args) => publicOperation("agent-job.reserve-review-suggestion-publication", agentJobs.reserveReviewSuggestionPublication(...args)),
16899
17861
  recordReviewSuggestionPublication: (...args) => publicOperation("agent-job.record-review-suggestion-publication", agentJobs.recordReviewSuggestionPublication(...args)),
17862
+ reviewBudget: (...args) => publicOperation("agent-job.review-budget", agentJobs.reviewBudget(...args)),
16900
17863
  requestCancellation: (...args) => publicOperation("agent-job.request-cancellation", agentJobs.requestCancellation(...args)),
17864
+ extendReviewBudget: (...args) => publicOperation("agent-job.extend-review-budget", agentJobs.extendReviewBudget(...args)),
17865
+ interruptRunningReviews: (...args) => publicOperation("agent-job.interrupt-running-reviews", agentJobs.interruptRunningReviews(...args)),
16901
17866
  reviewThreadAfter: (...args) => publicOperation("agent-job.review-thread-after", agentJobs.reviewThreadAfter(...args)),
16902
17867
  reviewThreadBefore: (...args) => publicOperation("agent-job.review-thread-before", agentJobs.reviewThreadBefore(...args)),
16903
17868
  reviewThreadTail: (...args) => publicOperation("agent-job.review-thread-tail", agentJobs.reviewThreadTail(...args)),
@@ -16946,7 +17911,8 @@ var makePersistence = Effect.gen(function* () {
16946
17911
  commit: (...args) => publicOperation("governed-action.commit", governedActions.commit(...args)),
16947
17912
  read: (...args) => publicOperation("governed-action.read", governedActions.read(...args)),
16948
17913
  readByIdempotencyKey: (...args) => publicOperation("governed-action.read-by-idempotency-key", governedActions.readByIdempotencyKey(...args)),
16949
- readLatestTerminalByTarget: (...args) => publicOperation("governed-action.read-latest-terminal-by-target", governedActions.readLatestTerminalByTarget(...args))
17914
+ readLatestTerminalByTarget: (...args) => publicOperation("governed-action.read-latest-terminal-by-target", governedActions.readLatestTerminalByTarget(...args)),
17915
+ readLatestTerminalReleasePublications: (...args) => publicOperation("governed-action.read-latest-terminal-release-publications", governedActions.readLatestTerminalReleasePublications(...args))
16950
17916
  },
16951
17917
  people: {
16952
17918
  createPerson: (...args) => publicOperation("people.create-person", people.createPerson(...args)),
@@ -17124,10 +18090,6 @@ var AuthorizedShares = class extends Context$1.Service()("@knpkv/control-center/
17124
18090
  var DeliveryGraphInspection = class extends Context$1.Service()("@knpkv/control-center/server/api/DeliveryGraphInspection") {};
17125
18091
  /** Authenticated mutation boundary for durable relationship-repair proposals. */
17126
18092
  var RelationshipRepairProposals = class extends Context$1.Service()("@knpkv/control-center/server/api/RelationshipRepairProposals") {};
17127
- /**
17128
- * Release-aware conversational boundary. Implementations own context projection,
17129
- * provider selection, prompt hardening, cancellation, and provider error redaction.
17130
- */
17131
18093
  var ReleaseAgentTurns = class extends Context$1.Service()("@knpkv/control-center/server/api/ReleaseAgentTurns") {};
17132
18094
  /**
17133
18095
  * Provider-neutral durable release-agent boundary. Implementations derive job,
@@ -18115,6 +19077,6 @@ var reconcileRelationshipInferencePolicy = Effect$1.fn("RelationshipInferenceMat
18115
19077
  return receipt;
18116
19078
  });
18117
19079
  //#endregion
18118
- export { negotiatePluginDescriptorV1 as $, databaseLayer as $n, AppendReviewSuggestionRevisionInput as $t, PullRequestReviews as A, PersonRecord as An, SchemaWriteBarrierError as Ar, BlobStoreInputError as At, persistenceLayerFromDatabase as B, QuarantinedRecordMetadata as Bn, AgentJobTask as Bt, CodePipelineReads as C, ContentBlobDigest as Cn, WorkspaceSettingsNoChangesError as Cr, ProjectionRow as Ct, MediaReads as D, EntityRecord as Dn, BackupManifestError as Dr, BlobContainmentError as Dt, LiveEvents as E, EntityKind as En, BackupLimitError as Er, AgentJobRepository as Et, TimelineReads as F, ProviderFamily as Fn, AgentContextSnapshotRecord as Ft, authorizeWorkspaceSettingsGovernanceRequest as G, VendorResourceId as Gn, AgentReviewResultRecord as Gt, ReviewCommandArtifactMetadata as H, ReleaseSnapshotRecord as Hn, AgentLeaseOwner as Ht, WorkspaceSettingsAdministration as I, ProviderFamilyMatchesProvider as In, AgentEventCursor as It, digestEnvironmentReadinessCandidate as J, providerFamilyForProvider as Jn, AgentReviewThreadHistoryInput as Jt, governedHumanMutationPolicyAllows as K, WorkspaceName as Kn, AgentReviewThreadAfterInput as Kt, PluginConnection as L, QuarantineDiagnosticSummary as Ln, AgentJobInputError as Lt, ReleaseAgentJobs as M, PluginConnectionRecord as Mn, BlobTooLargeError as Mt, ReleaseAgentTurns as N, ProviderAccountDisplayName as Nn, BlobUnexpectedEofError as Nt, PluginAdministration as O, FollowedResourceDisplayName as On, BackupSqlError as Or, BlobIntegrityError as Ot, TimelineExportAudits as P, ProviderAccountRecord as Pn, AgentAttemptSequence as Pt, hasPluginCapability as Q, Database as Qn, AppendAgentEventInput as Qt, Persistence as R, QuarantineReasonCode as Rn, AgentJobPrompt as Rt, AuthorizedShares as S, QuarantineRepository as Sn, WorkspaceSettingsMutationConflictError as Sr, EvidenceRow as St, DeliveryGraphInspection as T, ContentBlobStorageClass as Tn, BackupIntegrityError as Tr, DeliveryGraphWriteBatch as Tt, ReviewCommandArtifactRepository as U, RoleAssignmentRecord as Un, AgentLeaseToken as Ut, ReviewCommandArtifactHandle as V, RecordRevision as Vn, AgentJobTaskTag as Vt, WorkspaceSettingsRepository as W, VendorAccountId as Wn, AgentReviewResultInput as Wt, digestReleaseReadinessCandidate as X, mapPersistenceOperation as Xn, AgentThreadEvent as Xt, digestReadinessRule as Y, BlobClassification as Yn, AgentReviewThreadTailInput as Yt, HOST_PLUGIN_CAPABILITY_VERSIONS as Z, readChanges as Zn, AgentThreadEventPageSize as Zt, ApplicationConflict as _, ReviewSuggestionPublicationDigest as _n, ReproducibleContentUnavailableError as _r, makeGovernedActionEnvelope as _t, firstPartySyncStreamKey as a, EnqueueAgentJobTask as an, PersistenceConfig as ar, makeGovernedActionTransactionWrite as at, ApplicationResourceNotFound as b, SecretRef as bn, SourceIdentityMismatchError as br, makeDeliveryGraphDecoders as bt, RawConfluenceAttachmentPage as c, MAXIMUM_AGENT_ATTEMPT_OUTPUT_BYTES as cn, DatabaseInitializationError as cr, canonicalizeGovernedActionJson as ct, RawConfluencePage as d, PrReviewThreadContextSnapshot as dn, PersistenceConfigError as dr, digestGovernedActionPayload as dt, ClaimAgentJobInput as en, validateExistingControlCenterDatabase as er, PluginPageId as et, RawConfluenceSpacePage as f, PrReviewThreadSubject as fn, PersistenceOperationError as fr, digestGovernedActionPolicyDefinition as ft, RawConfluenceWatcherPage as g, ReserveReviewSuggestionPublicationInput as gn, RecordNotFoundError as gr, encodeGovernedActionUnknownOutcome as gt, RawConfluenceVersionPage as h, ReleaseReviewSuggestionPublicationInput as hn, RecordAlreadyExistsError as hr, encodeGovernedActionDispatchOutcome as ht, DomainEventWakeups as i, EnqueueAgentJobInput as in, LocalDatabaseUrl as ir, StoredPluginConfigurationKey as it, RelationshipRepairProposals as j, PluginConnectionDisplayName as jn, BlobDigest as jr, BlobStoreIoError as jt, PortfolioSnapshots as k, FollowedResourceRecord as kn, BackupStorageError as kr, BlobNotFoundError as kt, RawConfluenceCurrentUser as l, MAXIMUM_AGENT_JOB_PROMPT_LENGTH as ln, MAXIMUM_PERSISTENCE_RECORD_KEY_LENGTH as lr, digestCanonicalGovernedActionJson as lt, RawConfluenceVersion as m, RecordReviewSuggestionPublicationInput as mn, QuarantineWriteError as mr, digestGovernedActionTransitionCommand as mt, reconcileRelationshipInferencePolicy as n, CompleteAgentReviewInput as nn, validateCurrentSchema as nr, PluginStreamKey as nt, supportsFirstPartySynchronization as o, LatestAgentReviewInput as on, decodePersistenceConfig as or, makeGovernedActionTransaction as ot, RawConfluenceUsers as p, ReadReviewSuggestionRevisionsInput as pn, PluginConnectionLimitError as pr, digestGovernedActionPolicyEvaluation as pt, ReadinessDigestError as q, WorkspaceRecord as qn, AgentReviewThreadBeforeInput as qt, appendPortfolioInvalidation as r, EMPTY_PR_REVIEW_THREAD_CONTEXT as rn, BlobRoot as rr, StoredPluginConfiguration as rt, ConfluencePageAttributesV1 as s, LatestAgentReviewRecord as sn, ContentMetadataMismatchError as sr, GovernedActionDigestError as st, materializeRelationshipInference as t, ClaimedAgentJob as tn, CURRENT_SCHEMA_VERSION as tr, PluginRecordKey as tt, RawConfluenceDraftPage as u, MAXIMUM_AGENT_THREAD_EVENT_PAGE_SIZE as un, PersistedRecordError as ur, digestGovernedActionEvidenceSet as ut, ApplicationInvalidRequest as v, ReviewSuggestionPublicationReservation as vn, RevisionConflictError as vr, verifyGovernedActionEnvelope as vt, CompleteDiffReads as w, ContentBlobMetadata as wn, BackupInputError as wr, decodeRows$3 as wt, ApplicationServiceUnavailable as x, makePersistedRowQuarantine as xn, WorkspaceSettingsGovernanceError as xr, ClaimRow as xt, ApplicationRateLimited as y, blobPath as yn, SecretReferenceScopeConflictError as yr, GovernedActionCommitInput as yt, persistenceLayer as z, QuarantineRecordKind as zn, AgentJobState as zt };
19080
+ export { negotiatePluginDescriptorV1 as $, QuarantineReasonCode as $n, AppendAgentEventInput as $t, PullRequestReviews as A, ReviewSuggestionPublicationDigest as An, RecordAlreadyExistsError as Ar, BlobNotFoundError as At, persistenceLayerFromDatabase as B, ContentBlobStorageClass as Bn, BackupIntegrityError as Br, AgentJobState as Bt, CodePipelineReads as C, ReadReviewSuggestionRevisionsInput as Cn, DatabaseInitializationError as Cr, ProjectionRow as Ct, MediaReads as D, ReserveReviewSuggestionPublicationInput as Dn, PersistenceOperationError as Dr, PROCESS_RESTART_INTERRUPTION_MESSAGE as Dt, LiveEvents as E, ReleaseReviewSuggestionPublicationInput as En, PersistenceConfigError as Er, AgentJobRepository as Et, TimelineReads as F, SecretRef as Fn, SourceIdentityMismatchError as Fr, AgentAttemptSequence as Ft, authorizeWorkspaceSettingsGovernanceRequest as G, PersonRecord as Gn, SchemaWriteBarrierError as Gr, AgentReviewResultInput as Gt, ReviewCommandArtifactMetadata as H, EntityRecord as Hn, BackupManifestError as Hr, AgentJobTaskTag as Ht, WorkspaceSettingsAdministration as I, makePersistedRowQuarantine as In, WorkspaceSettingsGovernanceError as Ir, AgentContextSnapshotRecord as It, digestEnvironmentReadinessCandidate as J, ProviderAccountDisplayName as Jn, AgentReviewThreadBeforeInput as Jt, governedHumanMutationPolicyAllows as K, PluginConnectionDisplayName as Kn, BlobDigest as Kr, AgentReviewResultRecord as Kt, PluginConnection as L, QuarantineRepository as Ln, WorkspaceSettingsMutationConflictError as Lr, AgentEventCursor as Lt, ReleaseAgentJobs as M, ReviewSuggestionRevisionLeaseFence as Mn, ReproducibleContentUnavailableError as Mr, BlobStoreIoError as Mt, ReleaseAgentTurns as N, RunningPrReviewAttempt as Nn, RevisionConflictError as Nr, BlobTooLargeError as Nt, PluginAdministration as O, ReviewSuggestionPublicationCommentId as On, PluginConnectionLimitError as Or, BlobContainmentError as Ot, TimelineExportAudits as P, blobPath as Pn, SecretReferenceScopeConflictError as Pr, BlobUnexpectedEofError as Pt, hasPluginCapability as Q, QuarantineDiagnosticSummary as Qn, AgentThreadEventPageSize as Qt, Persistence as R, ContentBlobDigest as Rn, WorkspaceSettingsNoChangesError as Rr, AgentJobInputError as Rt, AuthorizedShares as S, ReadReviewSuggestionPublicationInput as Sn, ContentMetadataMismatchError as Sr, EvidenceRow as St, DeliveryGraphInspection as T, RecordReviewSuggestionPublicationInput as Tn, PersistedRecordError as Tr, DeliveryGraphWriteBatch as Tt, ReviewCommandArtifactRepository as U, FollowedResourceDisplayName as Un, BackupSqlError as Ur, AgentLeaseOwner as Ut, ReviewCommandArtifactHandle as V, EntityKind as Vn, BackupLimitError as Vr, AgentJobTask as Vt, WorkspaceSettingsRepository as W, FollowedResourceRecord as Wn, BackupStorageError as Wr, AgentLeaseToken as Wt, digestReleaseReadinessCandidate as X, ProviderFamily as Xn, AgentReviewThreadTailInput as Xt, digestReadinessRule as Y, ProviderAccountRecord as Yn, AgentReviewThreadHistoryInput as Yt, HOST_PLUGIN_CAPABILITY_VERSIONS as Z, ProviderFamilyMatchesProvider as Zn, AgentThreadEvent as Zt, ApplicationConflict as _, MAXIMUM_REVIEW_BUDGET_MILLIS as _n, validateCurrentSchema as _r, makeGovernedActionEnvelope as _t, firstPartySyncStreamKey as a, CompleteTargetedReviewInput as an, VendorAccountId as ar, makeGovernedActionTransactionWrite as at, ApplicationResourceNotFound as b, ReadReviewBudgetInput as bn, PersistenceConfig as br, makeDeliveryGraphDecoders as bt, RawConfluenceAttachmentPage as c, EnqueueAgentJobTask as cn, WorkspaceRecord as cr, canonicalizeGovernedActionJson as ct, RawConfluencePage as d, LatestAgentReviewInput as dn, mapPersistenceOperation as dr, digestGovernedActionPayload as dt, AppendReviewSuggestionRevisionInput as en, QuarantineRecordKind as er, PluginPageId as et, RawConfluenceSpacePage as f, LatestAgentReviewRecord as fn, readChanges as fr, digestGovernedActionPolicyDefinition as ft, RawConfluenceWatcherPage as g, MAXIMUM_REVIEW_BUDGET_EXTENSION_COUNT as gn, CURRENT_SCHEMA_VERSION as gr, encodeGovernedActionUnknownOutcome as gt, RawConfluenceVersionPage as h, MAXIMUM_AGENT_THREAD_EVENT_PAGE_SIZE as hn, validateExistingControlCenterDatabase as hr, encodeGovernedActionDispatchOutcome as ht, DomainEventWakeups as i, CompleteAgentReviewInput as in, RoleAssignmentRecord as ir, StoredPluginConfigurationKey as it, RelationshipRepairProposals as j, ReviewSuggestionPublicationReservation as jn, RecordNotFoundError as jr, BlobStoreInputError as jt, PortfolioSnapshots as k, ReviewSuggestionPublicationCommentLocator as kn, QuarantineWriteError as kr, BlobIntegrityError as kt, RawConfluenceCurrentUser as l, ExtendReviewBudgetInput as ln, providerFamilyForProvider as lr, digestCanonicalGovernedActionJson as lt, RawConfluenceVersion as m, MAXIMUM_AGENT_JOB_PROMPT_LENGTH as mn, databaseLayer as mr, digestGovernedActionTransitionCommand as mt, reconcileRelationshipInferencePolicy as n, ClaimAgentJobInput as nn, RecordRevision as nr, PluginStreamKey as nt, supportsFirstPartySynchronization as o, EMPTY_PR_REVIEW_THREAD_CONTEXT as on, VendorResourceId as or, makeGovernedActionTransaction as ot, RawConfluenceUsers as p, MAXIMUM_AGENT_ATTEMPT_OUTPUT_BYTES as pn, Database as pr, digestGovernedActionPolicyEvaluation as pt, ReadinessDigestError as q, PluginConnectionRecord as qn, AgentReviewThreadAfterInput as qt, appendPortfolioInvalidation as r, ClaimedAgentJob as rn, ReleaseSnapshotRecord as rr, StoredPluginConfiguration as rt, ConfluencePageAttributesV1 as s, EnqueueAgentJobInput as sn, WorkspaceName as sr, GovernedActionDigestError as st, materializeRelationshipInference as t, AttachRunningPrReviewSessionInput as tn, QuarantinedRecordMetadata as tr, PluginRecordKey as tt, RawConfluenceDraftPage as u, InterruptRunningReviewsInput as un, BlobClassification as ur, digestGovernedActionEvidenceSet as ut, ApplicationInvalidRequest as v, PrReviewThreadContextSnapshot as vn, BlobRoot as vr, verifyGovernedActionEnvelope as vt, CompleteDiffReads as w, RecordAgentReviewProgressInput as wn, MAXIMUM_PERSISTENCE_RECORD_KEY_LENGTH as wr, decodeRows$3 as wt, ApplicationServiceUnavailable as x, ReadReviewSuggestionPublication as xn, decodePersistenceConfig as xr, ClaimRow as xt, ApplicationRateLimited as y, PrReviewThreadSubject as yn, LocalDatabaseUrl as yr, GovernedActionCommitInput as yt, persistenceLayer as z, ContentBlobMetadata as zn, BackupInputError as zr, AgentJobPrompt as zt };
18119
19081
 
18120
- //# sourceMappingURL=relationshipInferenceMaterialization-DYBcaWhQ.js.map
19082
+ //# sourceMappingURL=relationshipInferenceMaterialization-CR6xyMNL.js.map