chainlesschain 0.163.7 → 0.163.8

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 (181) hide show
  1. package/package.json +2 -1
  2. package/src/assets/web-panel/assets/{AIOps-axqQfwv8.js → AIOps-CavM7W3k.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-DV-Ro0By.js → ActionButton-CUvZGabQ.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-Bt72WEVu.js → Analytics-DeBnWnbe.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-BtepG55E.js → AppLayout-DbI5kxvd.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-B7KaJ7S_.js → Artifacts-D93bigKm.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-FNFaUg7A.js → Audit-CBNvfUZa.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-DFb6J2wQ.js → BackgroundAgents-CJLyh_YU.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-CC7YBhyj.js → Backup-D_0yoehD.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-RkgTNVtj.js → BaseInput-TJxmbObW.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-hHEmGZy-.js → Chat-CE0dto1q.js} +5 -5
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CAP9YhHv.js → ChatBubbleRenderer-CZ5-yYiD.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-z5wXOQP1.js → Checkbox-Ck1RVIVo.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DVaDJnxy.js → Codegen-qpoyf6DK.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-CJmaRDR5.js → Col-DUyPWjIE.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DF29_2bI.js → Community-D_S1BemS.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-DtkQkBzn.js → Compact-BjxeK-Gc.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-xoHDxp7I.js → Compliance-Dd3CEJsu.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-BUm-R7ht.js → Cowork-B4QG7-ad.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-Cgl14ZkB.js → Cron-BtZnids5.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BNcbmoqh.js → Crosschain-CHPfCBFD.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-Bwja0Zo9.js → DID-DT8DCEOK.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-Bk5XjEdJ.js → Dashboard-COQab5_U.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-Ci36Oitq.js → Dropdown-BY1PsQuU.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer--U04ZN4q.js → EmailListRenderer-CsuAuaq3.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2gNPR2s.js → FamilyGuardDashboard-BqpinD-j.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-C4KghYn7.js → Federation-D0gkfQFv.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-QL7x_Q_0.js → FormItemContext-BqgE-axK.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-F3Ryltwm.js → GenericCardRenderer-D0hJ2KvC.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-2HassK5k.js → Git-CmMB0uPY.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-DoBIp7oe.js → Governance-BnVEI0Dk.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference--W01QhZ-.js → Inference-YTAMihRP.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DmvwqGpT.js → KnowledgeGraph-0ax7VHop.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-BBJ4yAel.js → Logs-B9TRcokL.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-yySN5YNM.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-D5lNngSI.js → Marketplace-B6CSuD_H.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-CkEVOMKH.js → McpTools-CjMXvOVU.js} +4 -4
  38. package/src/assets/web-panel/assets/{Memory-B1Ow1xVE.js → Memory-CXRF71U3.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-SgYbUfb6.js → MobileBridge-DQgNp_oS.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-BWdOvQAj.js → MobileProjects-DlPwcCbq.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-DcTXSSma.js → Mtc-6hDTRPe1.js} +2 -2
  42. package/src/assets/web-panel/assets/{MtcAudit-Dt3WG4oj.js → MtcAudit-BlVHU1DS.js} +2 -2
  43. package/src/assets/web-panel/assets/{Multisig-B9B38UZx.js → Multisig-DP9pzEbV.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-B0S4GGvG.js → NLProgramming-Djorh8EV.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-DZ5U58Ng.js → Notes-oLZ-JkUg.js} +4 -4
  46. package/src/assets/web-panel/assets/{NotificationSettings-PjL5ZW34.js → NotificationSettings-Cg288VH3.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DrAX2ESt.js → OrderTableRenderer-Bb1O3Ofr.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-Cv1GYs-c.js → Organization-CBdo-bHs.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-Bbkp_PL3.js → Overflow-qZdnVumx.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-BD8QUgoZ.js → P2P-D4kNfGNQ.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-BO-2PeaB.js → PdhVaultBrowser-DnlMemM7.js} +5 -5
  52. package/src/assets/web-panel/assets/{Permissions-D_OPVa02.js → Permissions-DHucHFBJ.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-mh-pEmaB.js → PersonalDataHub-BovlOIPR.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-6JC2EDdb.js → Pipeline-Deru3CQY.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-CUshzUAG.js → Privacy-Bq5oTTbU.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-Cs2Aalri.js → ProjectInit-BfzxVWAz.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-1ak49tcj.js → ProjectSettings-CKC6XBtH.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-BV4oApsm.js → Projects-CMolGhae.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-CXXxvafH.js → Providers-C_jx4TWX.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-PTcDsF58.js → QrScannerModal-BdIHeVGC.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-CDwucrJw.js → QuickAsk-BwZwAcPD.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-CJlLVRXR.js → Recommend-BNTt0L-m.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-DlN-ETsO.js → RemoteSession-Biyn2-Ro.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-DI23LR6m.js → Reputation-D6VpG32B.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-Cl7UQMrM.js → Row-D_74OvQQ.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-CexHNfh8.js → RssFeed-BTr0a-BQ.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-BneBWvRN.js → Search-C3MCFoNU.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-DX7Phgrp.js → Security-CqW9aJ6s.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-BWXO8Mte.js → Services-Cw5GNaHF.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-DCyOjKPJ.js → Skeleton-DZps5qeY.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CXqERsTB.js → Skills-C6NQ1znT.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-bhbrbz8E.js → Sla-DFP8G2Sh.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-3IPU0HBZ.js → SpeechSettings-ESt6MB6v.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-DBNTQLbM.js → SyncSettings-BHnN98aM.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-quP0bkN-.js → Tasks-NiSCaOf-.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-BouWmgho.js → Templates-DsKFhW2C.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-qv0D9s7z.js → Tenant-CQ0E0ze5.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-BxvbE8BB.js → Terminal-D_rBu_by.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-D-IeLnJ2.js → TimelineRenderer-D3Vm4Po4.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-CFMKKyVG.js → Tokens-DNTxRH6q.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-L8as3UuJ.js → Trigger-Dgprz1ms.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-MxmA4VZG.js → Trust-B2rUnVBD.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-C0VvJYRi.js → UkeySign-DEGQNc6_.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-Bf5QZj8N.js → VideoEditing-jlsAx3Eh.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-BIJ9riRz.js → Wallet-8jQih1ij.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-B8p9Mhkw.js → WebAuthn-XLeO6xIB.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-BVsuaPen.js → WorkflowEditor-De_dgDAG.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BfkjoKpV.js → chat-CI19R_Sk.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DeAlsWK8.js → colors-DsYTOYN3.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-Cs97bz5j.js → compact-item-CM3-t_Qr.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-BqbG60LH.js → createContext-BjxlBRZv.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-S1ld2LwU.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-i_RY0b1X.js → hasIn-RDaWX_4i.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-U4f5izHz.js → index-9R6BxAr0.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-0-agYlWL.js → index-B-Z8eFUJ.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-B1CbOH1i.js → index-B0PMlbMs.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DqBgBpgp.js → index-B5REnKt8.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BcUXAB2s.js → index-B7WBt_4T.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CIG8fQ2_.js → index-B9O9YyWE.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-gyFpvL7l.js → index-BCnZyIMA.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-yObj1O4n.js → index-BGqqJfL0.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DiSkx4UB.js → index-BHNYPO0b.js} +3 -3
  103. package/src/assets/web-panel/assets/{index-Bm7lLR4c.js → index-BKJr-TZp.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BOVkf1K3.js → index-BN6UPD2E.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BESLFt4q.js → index-Bi46Xu4u.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CE2VtTlp.js → index-BlT2VAEK.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DmbfhJUP.js → index-C0yx-jtQ.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BYUVuwKt.js → index-C4gkzxkw.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CeWoNHau.js → index-CVQMeiwH.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-PT_5sBMA.js → index-Cd3euP_4.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CgsqdnRV.js → index-Cd9OJhHG.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-B-3tEpTc.js → index-CiECJi-Q.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BkBi5TmC.js → index-CjTrRt13.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-D2B4VPyP.js → index-CnHH7bnD.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-dIHr4B_u.js → index-Cpqm1qfU.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B5UkyA3c.js → index-CyOGN6a5.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Dk7-v4hP.js → index-D0zcy54x.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-ZxO_-E8a.js → index-D6sm5-Xq.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-B-JVTrpr.js → index-DIUnNOjG.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Dk2qouAz.js → index-DX7tuWVJ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BuLQobzW.js → index-DXXtGMUJ.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DUUrv141.js → index-DcPFB8qJ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-D9evtvg2.js → index-DoQA0-52.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-COdGA-8n.js → index-Drlnwr8F.js} +1 -1
  125. package/src/assets/web-panel/assets/index-Drz6yq0m.js +1 -0
  126. package/src/assets/web-panel/assets/{index-CED2PL_y.js → index-Dsij_KsN.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-79V_zv1s.js → index-Dxge-xWl.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CG3PRyAL.js → index-DyIWssPC.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-YXgLng0K.js → index-IeiL9RKc.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-s1opAL-M.js → index-nAH87mQP.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Cf3WCLmy.js → index-pPL66J85.js} +1 -1
  132. package/src/assets/web-panel/assets/index-uWiUs7S_.js +1 -0
  133. package/src/assets/web-panel/assets/{initDefaultProps-C9h9yKL3.js → initDefaultProps-BTL88of4.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BvmLsPdu.js → motion-BUB2pXwB.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-CoL4ekU1.js → move-egCkkOMm.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-C4pMy6xV.js → mtc-parser-DAWhZC8c.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-DPuJfNxx.js → omit-CvOxe_6d.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-D0KEeaK2.js → pickAttrs-DZUSLZ5Z.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BpkyINxt.js → placementArrow-BERxGNMY.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-DQI_wOq8.js → responsiveObserve-DZuDfZ9n.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-DYfdDiRg.js → slide-DO756sgI.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-B5dtvb0D.js → statusUtils-BRQlIz28.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-CF310mSj.js → styleChecker-DCSfdybl.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-D1Qp4BLp.js → useFlexGapSupport-LD8dWVve.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-C7_iyvJK.js → useFs-BX9uW2LK.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-DZUt_fIm.js → usePersonalDataHub-BPSlPuHU.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-D3dsi0lZ.js → vnode-BmOILC9V.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-WdbOlvdQ.js → zoom-1iKowKGg.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +3 -3
  151. package/src/commands/automation.js +103 -1
  152. package/src/commands/team-merge-review.js +937 -0
  153. package/src/commands/team.js +2 -0
  154. package/src/data/changelog.json +14 -1
  155. package/src/lib/agent-schedule-store.js +139 -28
  156. package/src/lib/agent-team/team-merge-review-store.js +765 -0
  157. package/src/lib/agent-team/team-merge-review-transaction.js +1223 -0
  158. package/src/lib/agent-team/team-merge-review.js +1847 -0
  159. package/src/lib/automation-center-incidents.js +314 -0
  160. package/src/lib/automation-center-runtime.js +448 -0
  161. package/src/lib/automation-center.js +182 -38
  162. package/src/lib/automation-engine.js +41 -0
  163. package/src/lib/automation-execution-authority.js +241 -12
  164. package/src/lib/automation-execution-incident.js +737 -0
  165. package/src/lib/cowork-cron.js +85 -14
  166. package/src/lib/scheduler-kernel/agenda-adapter.js +17 -7
  167. package/src/lib/scheduler-kernel/automation-adapter.js +105 -11
  168. package/src/lib/scheduler-kernel/automation-event-adapter.js +87 -11
  169. package/src/lib/scheduler-kernel/contract.js +91 -0
  170. package/src/lib/scheduler-kernel/cowork-cron-adapter.js +12 -1
  171. package/src/lib/scheduler-kernel/loop-adapter.js +7 -1
  172. package/src/lib/scheduler-kernel/routine-adapter.js +7 -1
  173. package/src/lib/scheduler-kernel/runtime-control-capabilities.js +31 -0
  174. package/src/lib/scheduler-kernel/runtime.js +176 -3
  175. package/src/lib/scheduler-kernel/store.js +1253 -45
  176. package/src/runtime/agent-core.js +10 -0
  177. package/src/runtime/mcp-config.js +81 -10
  178. package/src/assets/web-panel/assets/MarkdownRenderer-BLCZMzhJ.js +0 -1
  179. package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +0 -1
  180. package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +0 -1
  181. package/src/assets/web-panel/assets/index-ChVT0p9u.js +0 -1
@@ -25,6 +25,7 @@ import {
25
25
  normalizeJson,
26
26
  } from "./contract.js";
27
27
  import { SchedulerRuntime } from "./runtime.js";
28
+ import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
28
29
  import { schedulerMigrationSourceDigest } from "./store.js";
29
30
  import {
30
31
  bindSchedulerAuthorityPolicy,
@@ -571,6 +572,7 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
571
572
  }
572
573
  return {
573
574
  kind: COWORK_CRON_SCHEDULER_KIND,
575
+ runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
574
576
  async adjudicate({ occurrence, adjudication }) {
575
577
  const payload = occurrence.payload;
576
578
  const cwd = normalizedCwd(payload.cwd);
@@ -604,7 +606,7 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
604
606
  }
605
607
  return { continue: true };
606
608
  },
607
- async execute({ occurrence, signal }) {
609
+ async execute({ occurrence, signal, checkpoint }) {
608
610
  const payload = occurrence.payload;
609
611
  const expected = coworkCronScheduleSnapshot(payload?.schedule);
610
612
  const expectedDigest = coworkCronScheduleDigest(expected);
@@ -662,6 +664,12 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
662
664
  );
663
665
  }
664
666
 
667
+ checkpoint({
668
+ deliveryId,
669
+ phase: "before_execution_bind",
670
+ scheduleId: expected.id,
671
+ });
672
+
665
673
  current = bindSchedulerScheduleFire(cwd, expected.id, {
666
674
  deliveryId,
667
675
  occurrenceId: occurrence.id,
@@ -803,6 +811,9 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
803
811
  );
804
812
  }
805
813
  },
814
+ async resume(context) {
815
+ return this.execute(context);
816
+ },
806
817
  classifyError(error) {
807
818
  return {
808
819
  retryable: error?.retryable === true,
@@ -7,6 +7,7 @@ import {
7
7
  normalizeJson,
8
8
  } from "./contract.js";
9
9
  import { SchedulerRuntime } from "./runtime.js";
10
+ import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
10
11
  import {
11
12
  schedulerJobDefinitionDigest,
12
13
  schedulerMigrationSourceDigest,
@@ -785,6 +786,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
785
786
  const transientResults = new Map();
786
787
  return {
787
788
  kind: LOOP_SCHEDULER_KIND,
789
+ runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
788
790
  async adjudicate({ occurrence, adjudication }) {
789
791
  if (adjudication.decision === "confirmed_applied") {
790
792
  const match = /^iteration:(\d+)$/.exec(occurrence.triggerKey);
@@ -799,7 +801,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
799
801
  }
800
802
  return { continue: true };
801
803
  },
802
- async execute({ occurrence, signal, adjudication }) {
804
+ async execute({ occurrence, signal, adjudication, checkpoint }) {
803
805
  const definition = loopExecutionSnapshot(occurrence?.payload?.definition);
804
806
  if (
805
807
  occurrence.payload.snapshotDigest !== loopExecutionDigest(definition)
@@ -826,6 +828,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
826
828
  `Loop iteration may already have produced side effects; refusing replay: ${occurrence.id}`,
827
829
  );
828
830
  }
831
+ checkpoint({ iteration, phase: "before_runner" });
829
832
  const result =
830
833
  (await runIteration(iteration, { signal, definition })) || {};
831
834
  const persisted = persistedIterationResult(iteration, result);
@@ -835,6 +838,9 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
835
838
  });
836
839
  return persisted;
837
840
  },
841
+ async resume(context) {
842
+ return this.execute(context);
843
+ },
838
844
  classifyError() {
839
845
  return { retryable: false };
840
846
  },
@@ -13,6 +13,7 @@ import {
13
13
  normalizeIdentifier,
14
14
  } from "./contract.js";
15
15
  import { SchedulerRuntime } from "./runtime.js";
16
+ import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
16
17
  import { schedulerMigrationSourceDigest } from "./store.js";
17
18
  import {
18
19
  bindSchedulerAuthorityPolicy,
@@ -772,6 +773,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
772
773
  }
773
774
  return {
774
775
  kind: ROUTINE_SCHEDULER_KIND,
776
+ runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
775
777
  async adjudicate({ occurrence, adjudication }) {
776
778
  const payload = occurrence.payload;
777
779
  const expected = payload?.routine;
@@ -812,7 +814,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
812
814
  }
813
815
  return { continue: true };
814
816
  },
815
- async execute({ occurrence, adjudication }) {
817
+ async execute({ occurrence, adjudication, checkpoint }) {
816
818
  const payload = occurrence.payload;
817
819
  const expected = payload?.routine;
818
820
  if (!expected) {
@@ -884,6 +886,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
884
886
  `Routine was disabled before scheduled execution: ${expected.id}`,
885
887
  );
886
888
  }
889
+ checkpoint({ phase: "before_run_bind", runId: schedulerRunId });
887
890
  const execution = await executeRoutine(
888
891
  routineStore,
889
892
  effectiveCurrent,
@@ -912,6 +915,9 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
912
915
  }
913
916
  return execution;
914
917
  },
918
+ async resume(context) {
919
+ return this.execute(context);
920
+ },
915
921
  classifyError(error) {
916
922
  return { retryable: error?.retryable !== false };
917
923
  },
@@ -0,0 +1,31 @@
1
+ import {
2
+ RUNTIME_CONTROL_SAFE_POINTS,
3
+ RUNTIME_CONTROL_SCHEMA_VERSION,
4
+ RUNTIME_PAUSE_RESUME,
5
+ normalizeRuntimeControlCapability,
6
+ } from "./contract.js";
7
+ import { RUNTIME_CONTROL_JOB_KINDS } from "./store.js";
8
+
9
+ /** Canonical cooperative pause/resume declaration for production adapters. */
10
+ export const CHECKPOINT_V1_RUNTIME_CONTROL = normalizeRuntimeControlCapability({
11
+ schemaVersion: RUNTIME_CONTROL_SCHEMA_VERSION,
12
+ pauseResume: RUNTIME_PAUSE_RESUME.CHECKPOINT_V1,
13
+ safePoints: [
14
+ RUNTIME_CONTROL_SAFE_POINTS.BEFORE_EXECUTE,
15
+ RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT,
16
+ ],
17
+ });
18
+
19
+ export const NO_RUNTIME_CONTROL = normalizeRuntimeControlCapability();
20
+
21
+ const automationCenterJobKinds = new Set(RUNTIME_CONTROL_JOB_KINDS);
22
+
23
+ /**
24
+ * Resolve Automation Center capabilities without trusting a caller-supplied
25
+ * adapter. Unknown kinds deliberately remain unsupported.
26
+ */
27
+ export function resolveAutomationCenterRuntimeControl(jobKind) {
28
+ return automationCenterJobKinds.has(jobKind)
29
+ ? CHECKPOINT_V1_RUNTIME_CONTROL
30
+ : NO_RUNTIME_CONTROL;
31
+ }
@@ -1,10 +1,15 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import {
3
3
  OCCURRENCE_STATUS,
4
+ RUNTIME_CONTROL_SCHEMA_VERSION,
5
+ RUNTIME_CONTROL_SAFE_POINTS,
6
+ RUNTIME_PAUSE_RESUME,
4
7
  SchedulerKernelError,
8
+ canonicalJson,
5
9
  normalizeEpochMs,
6
10
  normalizeIdentifier,
7
11
  normalizeJson,
12
+ normalizeRuntimeControlCapability,
8
13
  } from "./contract.js";
9
14
 
10
15
  export const DEFAULT_RUNTIME_LEASE_MS = 60_000;
@@ -17,6 +22,15 @@ const TERMINAL_OCCURRENCE_STATUSES = new Set([
17
22
  OCCURRENCE_STATUS.DEAD_LETTER,
18
23
  ]);
19
24
 
25
+ class SchedulerPauseSignal extends Error {
26
+ constructor(control, checkpoint) {
27
+ super("Scheduler adapter reached a requested pause checkpoint");
28
+ this.name = "SchedulerPauseSignal";
29
+ this.control = control;
30
+ this.checkpoint = checkpoint;
31
+ }
32
+ }
33
+
20
34
  function runtimeError(code, message, details = undefined, cause = undefined) {
21
35
  return new SchedulerKernelError(
22
36
  code,
@@ -95,7 +109,21 @@ function normalizeAdapter(adapter) {
95
109
  `Scheduler adapter must implement execute(): ${kind}`,
96
110
  );
97
111
  }
98
- return { kind, adapter };
112
+ const runtimeControl = normalizeRuntimeControlCapability(
113
+ adapter.runtimeControl,
114
+ );
115
+ if (
116
+ runtimeControl.safePoints.includes(
117
+ RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT,
118
+ ) &&
119
+ typeof adapter.resume !== "function"
120
+ ) {
121
+ throw runtimeError(
122
+ "SCHEDULER_RUNTIME_INVALID_ADAPTER",
123
+ `Scheduler adapter must implement resume() for adapter checkpoints: ${kind}`,
124
+ );
125
+ }
126
+ return { kind, adapter, runtimeControl };
99
127
  }
100
128
 
101
129
  function normalizeAdapters(adapters = []) {
@@ -268,6 +296,14 @@ export class SchedulerRuntime {
268
296
  return this;
269
297
  }
270
298
 
299
+ runtimeControlFor(jobKind) {
300
+ const kind = normalizeIdentifier(jobKind, "jobKind", { maxLength: 128 });
301
+ const adapter = this.adapters.get(kind);
302
+ return adapter
303
+ ? normalizeRuntimeControlCapability(adapter.runtimeControl)
304
+ : normalizeRuntimeControlCapability();
305
+ }
306
+
271
307
  async _settleRejected(occurrence, error, retryable = false) {
272
308
  const settled = this.store.settle({
273
309
  occurrenceId: occurrence.id,
@@ -314,6 +350,9 @@ export class SchedulerRuntime {
314
350
  ),
315
351
  );
316
352
  }
353
+ const runtimeControl = normalizeRuntimeControlCapability(
354
+ adapter.runtimeControl,
355
+ );
317
356
 
318
357
  let decision;
319
358
  let allowed = false;
@@ -368,6 +407,103 @@ export class SchedulerRuntime {
368
407
  aborted.retryable = true;
369
408
  return this._settleRejected(occurrence, aborted, true);
370
409
  }
410
+ const readBoundControl = (state) => {
411
+ if (typeof this.store.getOccurrenceControl !== "function") return null;
412
+ const control = this.store.getOccurrenceControl(occurrence.id);
413
+ if (control?.state !== state) return null;
414
+ if (
415
+ runtimeControl.pauseResume !== RUNTIME_PAUSE_RESUME.CHECKPOINT_V1 ||
416
+ canonicalJson(control.capability, "runtimeControl.persisted") !==
417
+ canonicalJson(runtimeControl, "runtimeControl.adapter")
418
+ ) {
419
+ throw runtimeError(
420
+ "SCHEDULER_RUNTIME_CONTROL_CAPABILITY_MISMATCH",
421
+ `Scheduler runtime-control evidence no longer matches adapter capability: ${occurrence.id}`,
422
+ {
423
+ capabilityDigest: control.capabilityDigest,
424
+ adapterPauseResume: runtimeControl.pauseResume,
425
+ },
426
+ );
427
+ }
428
+ if (control.expectedFence !== occurrence.fence) {
429
+ throw runtimeError(
430
+ "SCHEDULER_RUNTIME_CONTROL_FENCE_MISMATCH",
431
+ `Scheduler runtime control is not bound to this claim: ${occurrence.id}`,
432
+ {
433
+ expectedFence: control.expectedFence,
434
+ actualFence: occurrence.fence,
435
+ },
436
+ );
437
+ }
438
+ return control;
439
+ };
440
+ const readPendingPause = () => readBoundControl("pause_requested");
441
+ const readResumingControl = () => {
442
+ const control = readBoundControl("resumed");
443
+ if (!control) return null;
444
+ const checkpoint = control.checkpoint;
445
+ if (
446
+ !checkpoint ||
447
+ checkpoint.schemaVersion !== RUNTIME_CONTROL_SCHEMA_VERSION ||
448
+ !Object.values(RUNTIME_CONTROL_SAFE_POINTS).includes(
449
+ checkpoint.safePoint,
450
+ ) ||
451
+ !Object.hasOwn(checkpoint, "data") ||
452
+ !runtimeControl.safePoints.includes(checkpoint.safePoint)
453
+ ) {
454
+ throw runtimeError(
455
+ "SCHEDULER_RUNTIME_RESUME_CHECKPOINT_INVALID",
456
+ `Scheduler resume checkpoint is invalid for adapter: ${occurrence.id}`,
457
+ );
458
+ }
459
+ return control;
460
+ };
461
+ const acknowledgePause = (control, safePoint, checkpoint) => {
462
+ if (typeof this.store.ackOccurrencePause !== "function") {
463
+ throw runtimeError(
464
+ "SCHEDULER_RUNTIME_CONTROL_STORE_UNSUPPORTED",
465
+ "Scheduler store cannot acknowledge durable runtime controls",
466
+ );
467
+ }
468
+ const acknowledged = this.store.ackOccurrencePause({
469
+ occurrenceId: occurrence.id,
470
+ ownerId: this.ownerId,
471
+ fence: occurrence.fence,
472
+ requestId: control.pauseRequestId,
473
+ expectedRevision: control.revision,
474
+ safePoint,
475
+ checkpoint,
476
+ });
477
+ return {
478
+ status: "paused",
479
+ occurrence: acknowledged.occurrence,
480
+ control: acknowledged.control,
481
+ result: null,
482
+ error: null,
483
+ };
484
+ };
485
+ let pendingPause;
486
+ let resumingControl;
487
+ try {
488
+ pendingPause = readPendingPause();
489
+ resumingControl = readResumingControl();
490
+ } catch (error) {
491
+ linked.dispose();
492
+ return this._settleRejected(occurrence, error, false);
493
+ }
494
+ if (
495
+ pendingPause &&
496
+ runtimeControl.safePoints.includes(
497
+ RUNTIME_CONTROL_SAFE_POINTS.BEFORE_EXECUTE,
498
+ )
499
+ ) {
500
+ linked.dispose();
501
+ return acknowledgePause(
502
+ pendingPause,
503
+ RUNTIME_CONTROL_SAFE_POINTS.BEFORE_EXECUTE,
504
+ { adapterStarted: false },
505
+ );
506
+ }
371
507
  let leaseError = null;
372
508
  let renewing = false;
373
509
  const renew = () => {
@@ -415,7 +551,26 @@ export class SchedulerRuntime {
415
551
  : null,
416
552
  signal: linked.controller.signal,
417
553
  renewLease: renew,
554
+ runtimeControl,
555
+ resumeCheckpoint: resumingControl?.checkpoint ?? null,
556
+ checkpoint: (data = null) => {
557
+ if (
558
+ !runtimeControl.safePoints.includes(
559
+ RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT,
560
+ )
561
+ ) {
562
+ return { pauseRequested: false };
563
+ }
564
+ const control = readPendingPause();
565
+ if (!control) return { pauseRequested: false };
566
+ throw new SchedulerPauseSignal(control, data);
567
+ },
418
568
  };
569
+ const invokeAdapter = () =>
570
+ resumingControl?.checkpoint.safePoint ===
571
+ RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT
572
+ ? adapter.resume(context, resumingControl.checkpoint)
573
+ : adapter.execute(context);
419
574
  try {
420
575
  let result;
421
576
  if (context.adjudication?.status === "pending") {
@@ -466,9 +621,9 @@ export class SchedulerRuntime {
466
621
  adjudicationRequestId: context.adjudication.requestId,
467
622
  decision: context.adjudication.decision,
468
623
  })
469
- : await adapter.execute(context);
624
+ : await invokeAdapter();
470
625
  } else {
471
- result = await adapter.execute(context);
626
+ result = await invokeAdapter();
472
627
  }
473
628
  if (leaseError) throw leaseError;
474
629
  if (linked.controller.signal.aborted) {
@@ -492,6 +647,13 @@ export class SchedulerRuntime {
492
647
  return settledResult(settled);
493
648
  } catch (error) {
494
649
  if (leaseError) throw leaseError;
650
+ if (error instanceof SchedulerPauseSignal) {
651
+ return acknowledgePause(
652
+ error.control,
653
+ RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT,
654
+ error.checkpoint,
655
+ );
656
+ }
495
657
  let policy;
496
658
  let settlementError = error;
497
659
  try {
@@ -545,6 +707,17 @@ export class SchedulerRuntime {
545
707
  leaseMs: this.leaseMs,
546
708
  });
547
709
  if (!claimed) {
710
+ const control =
711
+ typeof this.store.getOccurrenceControl === "function"
712
+ ? this.store.getOccurrenceControl(id)
713
+ : null;
714
+ if (control?.state === "paused") {
715
+ return {
716
+ status: "paused",
717
+ occurrence: this.store.getOccurrence(id),
718
+ control,
719
+ };
720
+ }
548
721
  return {
549
722
  status: "busy",
550
723
  occurrence: this.store.getOccurrence(id),