@smthrs/engine-store 0.0.0-stage → 1.0.0-rc.3

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 (787) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/LICENSE +21 -0
  3. package/README.md +146 -2
  4. package/dist/cjs/ArtifactGc.d.ts +235 -0
  5. package/dist/cjs/ArtifactGc.d.ts.map +1 -0
  6. package/dist/cjs/ArtifactGc.js +183 -0
  7. package/dist/cjs/ArtifactGc.js.map +7 -0
  8. package/dist/cjs/ArtifactSync.d.ts +164 -0
  9. package/dist/cjs/ArtifactSync.d.ts.map +1 -0
  10. package/dist/cjs/ArtifactSync.js +144 -0
  11. package/dist/cjs/ArtifactSync.js.map +7 -0
  12. package/dist/cjs/CacheSync.d.ts +112 -0
  13. package/dist/cjs/CacheSync.d.ts.map +1 -0
  14. package/dist/cjs/CacheSync.js +64 -0
  15. package/dist/cjs/CacheSync.js.map +7 -0
  16. package/dist/cjs/DeferredClockFold.d.ts +354 -0
  17. package/dist/cjs/DeferredClockFold.d.ts.map +1 -0
  18. package/dist/cjs/DeferredClockFold.js +335 -0
  19. package/dist/cjs/DeferredClockFold.js.map +7 -0
  20. package/dist/cjs/DisasterRecovery.d.ts +431 -0
  21. package/dist/cjs/DisasterRecovery.d.ts.map +1 -0
  22. package/dist/cjs/DisasterRecovery.js +453 -0
  23. package/dist/cjs/DisasterRecovery.js.map +7 -0
  24. package/dist/cjs/DurableEngineState.d.ts +776 -0
  25. package/dist/cjs/DurableEngineState.d.ts.map +1 -0
  26. package/dist/cjs/DurableEngineState.js +1536 -0
  27. package/dist/cjs/DurableEngineState.js.map +7 -0
  28. package/dist/cjs/EngineStore.d.ts +158 -0
  29. package/dist/cjs/EngineStore.d.ts.map +1 -0
  30. package/dist/cjs/EngineStore.js +398 -0
  31. package/dist/cjs/EngineStore.js.map +7 -0
  32. package/dist/cjs/EngineStoreMetrics.d.ts +276 -0
  33. package/dist/cjs/EngineStoreMetrics.d.ts.map +1 -0
  34. package/dist/cjs/EngineStoreMetrics.js +135 -0
  35. package/dist/cjs/EngineStoreMetrics.js.map +7 -0
  36. package/dist/cjs/Errors.d.ts +22 -0
  37. package/dist/cjs/Errors.d.ts.map +1 -0
  38. package/dist/cjs/Errors.js +39 -0
  39. package/dist/cjs/Errors.js.map +7 -0
  40. package/dist/cjs/EventTypes.d.ts +27 -0
  41. package/dist/cjs/EventTypes.d.ts.map +1 -0
  42. package/dist/cjs/EventTypes.js +37 -0
  43. package/dist/cjs/EventTypes.js.map +7 -0
  44. package/dist/cjs/ExecutionFacts.d.ts +59 -0
  45. package/dist/cjs/ExecutionFacts.d.ts.map +1 -0
  46. package/dist/cjs/ExecutionFacts.js +123 -0
  47. package/dist/cjs/ExecutionFacts.js.map +7 -0
  48. package/dist/cjs/ExecutionSnapshot.d.ts +117 -0
  49. package/dist/cjs/ExecutionSnapshot.d.ts.map +1 -0
  50. package/dist/cjs/ExecutionSnapshot.js +111 -0
  51. package/dist/cjs/ExecutionSnapshot.js.map +7 -0
  52. package/dist/cjs/Inconsistency.d.ts +154 -0
  53. package/dist/cjs/Inconsistency.d.ts.map +1 -0
  54. package/dist/cjs/Inconsistency.js +135 -0
  55. package/dist/cjs/Inconsistency.js.map +7 -0
  56. package/dist/cjs/Migrations.d.ts +56 -0
  57. package/dist/cjs/Migrations.d.ts.map +1 -0
  58. package/dist/cjs/Migrations.js +78 -0
  59. package/dist/cjs/Migrations.js.map +7 -0
  60. package/dist/cjs/OwnerIdentity.d.ts +91 -0
  61. package/dist/cjs/OwnerIdentity.d.ts.map +1 -0
  62. package/dist/cjs/OwnerIdentity.js +65 -0
  63. package/dist/cjs/OwnerIdentity.js.map +7 -0
  64. package/dist/cjs/PlanInputStore.d.ts +110 -0
  65. package/dist/cjs/PlanInputStore.d.ts.map +1 -0
  66. package/dist/cjs/PlanInputStore.js +224 -0
  67. package/dist/cjs/PlanInputStore.js.map +7 -0
  68. package/dist/cjs/PlanMergeStore.d.ts +113 -0
  69. package/dist/cjs/PlanMergeStore.d.ts.map +1 -0
  70. package/dist/cjs/PlanMergeStore.js +255 -0
  71. package/dist/cjs/PlanMergeStore.js.map +7 -0
  72. package/dist/cjs/PlanScheduler.d.ts +363 -0
  73. package/dist/cjs/PlanScheduler.d.ts.map +1 -0
  74. package/dist/cjs/PlanScheduler.js +1090 -0
  75. package/dist/cjs/PlanScheduler.js.map +7 -0
  76. package/dist/cjs/Reconciliation.d.ts +175 -0
  77. package/dist/cjs/Reconciliation.d.ts.map +1 -0
  78. package/dist/cjs/Reconciliation.js +119 -0
  79. package/dist/cjs/Reconciliation.js.map +7 -0
  80. package/dist/cjs/ReplayOnly.d.ts +91 -0
  81. package/dist/cjs/ReplayOnly.d.ts.map +1 -0
  82. package/dist/cjs/ReplayOnly.js +52 -0
  83. package/dist/cjs/ReplayOnly.js.map +7 -0
  84. package/dist/cjs/Retention.d.ts +113 -0
  85. package/dist/cjs/Retention.d.ts.map +1 -0
  86. package/dist/cjs/Retention.js +99 -0
  87. package/dist/cjs/Retention.js.map +7 -0
  88. package/dist/cjs/RunCatalogRead.d.ts +17 -0
  89. package/dist/cjs/RunCatalogRead.d.ts.map +1 -0
  90. package/dist/cjs/RunCatalogRead.js +33 -0
  91. package/dist/cjs/RunCatalogRead.js.map +7 -0
  92. package/dist/cjs/RunChangeFeed.d.ts +75 -0
  93. package/dist/cjs/RunChangeFeed.d.ts.map +1 -0
  94. package/dist/cjs/RunChangeFeed.js +96 -0
  95. package/dist/cjs/RunChangeFeed.js.map +7 -0
  96. package/dist/cjs/RunState.d.ts +116 -0
  97. package/dist/cjs/RunState.d.ts.map +1 -0
  98. package/dist/cjs/RunState.js +76 -0
  99. package/dist/cjs/RunState.js.map +7 -0
  100. package/dist/cjs/Selection.d.ts +495 -0
  101. package/dist/cjs/Selection.d.ts.map +1 -0
  102. package/dist/cjs/Selection.js +288 -0
  103. package/dist/cjs/Selection.js.map +7 -0
  104. package/dist/cjs/SelectionStore.d.ts +141 -0
  105. package/dist/cjs/SelectionStore.d.ts.map +1 -0
  106. package/dist/cjs/SelectionStore.js +229 -0
  107. package/dist/cjs/SelectionStore.js.map +7 -0
  108. package/dist/cjs/StepBoundary.d.ts +501 -0
  109. package/dist/cjs/StepBoundary.d.ts.map +1 -0
  110. package/dist/cjs/StepBoundary.js +619 -0
  111. package/dist/cjs/StepBoundary.js.map +7 -0
  112. package/dist/cjs/StepCacheFold.d.ts +148 -0
  113. package/dist/cjs/StepCacheFold.d.ts.map +1 -0
  114. package/dist/cjs/StepCacheFold.js +131 -0
  115. package/dist/cjs/StepCacheFold.js.map +7 -0
  116. package/dist/cjs/StepSandbox.d.ts +78 -0
  117. package/dist/cjs/StepSandbox.d.ts.map +1 -0
  118. package/dist/cjs/StepSandbox.js +75 -0
  119. package/dist/cjs/StepSandbox.js.map +7 -0
  120. package/dist/cjs/WakeBus.d.ts +116 -0
  121. package/dist/cjs/WakeBus.d.ts.map +1 -0
  122. package/dist/cjs/WakeBus.js +89 -0
  123. package/dist/cjs/WakeBus.js.map +7 -0
  124. package/dist/cjs/WorkspaceSandbox.d.ts +619 -0
  125. package/dist/cjs/WorkspaceSandbox.d.ts.map +1 -0
  126. package/dist/cjs/WorkspaceSandbox.js +711 -0
  127. package/dist/cjs/WorkspaceSandbox.js.map +7 -0
  128. package/dist/cjs/index.d.ts +157 -0
  129. package/dist/cjs/index.d.ts.map +1 -0
  130. package/dist/cjs/index.js +95 -0
  131. package/dist/cjs/index.js.map +7 -0
  132. package/dist/cjs/internal/ActionPersistence.d.ts +276 -0
  133. package/dist/cjs/internal/ActionPersistence.d.ts.map +1 -0
  134. package/dist/cjs/internal/ActionPersistence.js +1395 -0
  135. package/dist/cjs/internal/ActionPersistence.js.map +7 -0
  136. package/dist/cjs/internal/ArtifactRoots.d.ts +38 -0
  137. package/dist/cjs/internal/ArtifactRoots.d.ts.map +1 -0
  138. package/dist/cjs/internal/ArtifactRoots.js +89 -0
  139. package/dist/cjs/internal/ArtifactRoots.js.map +7 -0
  140. package/dist/cjs/internal/AttemptAdmission.d.ts +53 -0
  141. package/dist/cjs/internal/AttemptAdmission.d.ts.map +1 -0
  142. package/dist/cjs/internal/AttemptAdmission.js +52 -0
  143. package/dist/cjs/internal/AttemptAdmission.js.map +7 -0
  144. package/dist/cjs/internal/AttemptLifecycle.d.ts +245 -0
  145. package/dist/cjs/internal/AttemptLifecycle.d.ts.map +1 -0
  146. package/dist/cjs/internal/AttemptLifecycle.js +112 -0
  147. package/dist/cjs/internal/AttemptLifecycle.js.map +7 -0
  148. package/dist/cjs/internal/AttemptProbe.d.ts +53 -0
  149. package/dist/cjs/internal/AttemptProbe.d.ts.map +1 -0
  150. package/dist/cjs/internal/AttemptProbe.js +66 -0
  151. package/dist/cjs/internal/AttemptProbe.js.map +7 -0
  152. package/dist/cjs/internal/CacheAdmission.d.ts +79 -0
  153. package/dist/cjs/internal/CacheAdmission.d.ts.map +1 -0
  154. package/dist/cjs/internal/CacheAdmission.js +71 -0
  155. package/dist/cjs/internal/CacheAdmission.js.map +7 -0
  156. package/dist/cjs/internal/CacheAgeHistory.d.ts +27 -0
  157. package/dist/cjs/internal/CacheAgeHistory.d.ts.map +1 -0
  158. package/dist/cjs/internal/CacheAgeHistory.js +61 -0
  159. package/dist/cjs/internal/CacheAgeHistory.js.map +7 -0
  160. package/dist/cjs/internal/CacheAgeVerdicts.d.ts +15 -0
  161. package/dist/cjs/internal/CacheAgeVerdicts.d.ts.map +1 -0
  162. package/dist/cjs/internal/CacheAgeVerdicts.js +73 -0
  163. package/dist/cjs/internal/CacheAgeVerdicts.js.map +7 -0
  164. package/dist/cjs/internal/CacheOutputPolicy.d.ts +24 -0
  165. package/dist/cjs/internal/CacheOutputPolicy.d.ts.map +1 -0
  166. package/dist/cjs/internal/CacheOutputPolicy.js +75 -0
  167. package/dist/cjs/internal/CacheOutputPolicy.js.map +7 -0
  168. package/dist/cjs/internal/CachePublication.d.ts +97 -0
  169. package/dist/cjs/internal/CachePublication.d.ts.map +1 -0
  170. package/dist/cjs/internal/CachePublication.js +80 -0
  171. package/dist/cjs/internal/CachePublication.js.map +7 -0
  172. package/dist/cjs/internal/CallFacts.d.ts +15 -0
  173. package/dist/cjs/internal/CallFacts.d.ts.map +1 -0
  174. package/dist/cjs/internal/CallFacts.js +97 -0
  175. package/dist/cjs/internal/CallFacts.js.map +7 -0
  176. package/dist/cjs/internal/CopiedRecord.d.ts +61 -0
  177. package/dist/cjs/internal/CopiedRecord.d.ts.map +1 -0
  178. package/dist/cjs/internal/CopiedRecord.js +134 -0
  179. package/dist/cjs/internal/CopiedRecord.js.map +7 -0
  180. package/dist/cjs/internal/DeferredPersistence.d.ts +108 -0
  181. package/dist/cjs/internal/DeferredPersistence.d.ts.map +1 -0
  182. package/dist/cjs/internal/DeferredPersistence.js +270 -0
  183. package/dist/cjs/internal/DeferredPersistence.js.map +7 -0
  184. package/dist/cjs/internal/EffectRecords.d.ts +92 -0
  185. package/dist/cjs/internal/EffectRecords.d.ts.map +1 -0
  186. package/dist/cjs/internal/EffectRecords.js +63 -0
  187. package/dist/cjs/internal/EffectRecords.js.map +7 -0
  188. package/dist/cjs/internal/EngineJj.d.ts +30 -0
  189. package/dist/cjs/internal/EngineJj.d.ts.map +1 -0
  190. package/dist/cjs/internal/EngineJj.js +42 -0
  191. package/dist/cjs/internal/EngineJj.js.map +7 -0
  192. package/dist/cjs/internal/EngineStateSchema.d.ts +68 -0
  193. package/dist/cjs/internal/EngineStateSchema.d.ts.map +1 -0
  194. package/dist/cjs/internal/EngineStateSchema.js +58 -0
  195. package/dist/cjs/internal/EngineStateSchema.js.map +7 -0
  196. package/dist/cjs/internal/ExecutionSnapshotRead.d.ts +162 -0
  197. package/dist/cjs/internal/ExecutionSnapshotRead.d.ts.map +1 -0
  198. package/dist/cjs/internal/ExecutionSnapshotRead.js +199 -0
  199. package/dist/cjs/internal/ExecutionSnapshotRead.js.map +7 -0
  200. package/dist/cjs/internal/ExecutionSnapshotRelations.d.ts +39 -0
  201. package/dist/cjs/internal/ExecutionSnapshotRelations.d.ts.map +1 -0
  202. package/dist/cjs/internal/ExecutionSnapshotRelations.js +105 -0
  203. package/dist/cjs/internal/ExecutionSnapshotRelations.js.map +7 -0
  204. package/dist/cjs/internal/ExitEncoding.d.ts +180 -0
  205. package/dist/cjs/internal/ExitEncoding.d.ts.map +1 -0
  206. package/dist/cjs/internal/ExitEncoding.js +236 -0
  207. package/dist/cjs/internal/ExitEncoding.js.map +7 -0
  208. package/dist/cjs/internal/FileBoundarySnapshot.d.ts +14 -0
  209. package/dist/cjs/internal/FileBoundarySnapshot.d.ts.map +1 -0
  210. package/dist/cjs/internal/FileBoundarySnapshot.js +51 -0
  211. package/dist/cjs/internal/FileBoundarySnapshot.js.map +7 -0
  212. package/dist/cjs/internal/FileEnumeration.d.ts +127 -0
  213. package/dist/cjs/internal/FileEnumeration.d.ts.map +1 -0
  214. package/dist/cjs/internal/FileEnumeration.js +194 -0
  215. package/dist/cjs/internal/FileEnumeration.js.map +7 -0
  216. package/dist/cjs/internal/HostReflection.d.ts +80 -0
  217. package/dist/cjs/internal/HostReflection.d.ts.map +1 -0
  218. package/dist/cjs/internal/HostReflection.js +43 -0
  219. package/dist/cjs/internal/HostReflection.js.map +7 -0
  220. package/dist/cjs/internal/JournalRecords.d.ts +325 -0
  221. package/dist/cjs/internal/JournalRecords.d.ts.map +1 -0
  222. package/dist/cjs/internal/JournalRecords.js +122 -0
  223. package/dist/cjs/internal/JournalRecords.js.map +7 -0
  224. package/dist/cjs/internal/NodeJournal.d.ts +157 -0
  225. package/dist/cjs/internal/NodeJournal.d.ts.map +1 -0
  226. package/dist/cjs/internal/NodeJournal.js +192 -0
  227. package/dist/cjs/internal/NodeJournal.js.map +7 -0
  228. package/dist/cjs/internal/Ordering.d.ts +14 -0
  229. package/dist/cjs/internal/Ordering.d.ts.map +1 -0
  230. package/dist/cjs/internal/Ordering.js +25 -0
  231. package/dist/cjs/internal/Ordering.js.map +7 -0
  232. package/dist/cjs/internal/PlanInputs.d.ts +14 -0
  233. package/dist/cjs/internal/PlanInputs.d.ts.map +1 -0
  234. package/dist/cjs/internal/PlanInputs.js +78 -0
  235. package/dist/cjs/internal/PlanInputs.js.map +7 -0
  236. package/dist/cjs/internal/PlanMerges.d.ts +178 -0
  237. package/dist/cjs/internal/PlanMerges.d.ts.map +1 -0
  238. package/dist/cjs/internal/PlanMerges.js +125 -0
  239. package/dist/cjs/internal/PlanMerges.js.map +7 -0
  240. package/dist/cjs/internal/ProvenanceSlot.d.ts +30 -0
  241. package/dist/cjs/internal/ProvenanceSlot.d.ts.map +1 -0
  242. package/dist/cjs/internal/ProvenanceSlot.js +53 -0
  243. package/dist/cjs/internal/ProvenanceSlot.js.map +7 -0
  244. package/dist/cjs/internal/ResultEnvelope.d.ts +88 -0
  245. package/dist/cjs/internal/ResultEnvelope.d.ts.map +1 -0
  246. package/dist/cjs/internal/ResultEnvelope.js +90 -0
  247. package/dist/cjs/internal/ResultEnvelope.js.map +7 -0
  248. package/dist/cjs/internal/RetentionOps.d.ts +414 -0
  249. package/dist/cjs/internal/RetentionOps.d.ts.map +1 -0
  250. package/dist/cjs/internal/RetentionOps.js +354 -0
  251. package/dist/cjs/internal/RetentionOps.js.map +7 -0
  252. package/dist/cjs/internal/RunCatalogOps.d.ts +118 -0
  253. package/dist/cjs/internal/RunCatalogOps.d.ts.map +1 -0
  254. package/dist/cjs/internal/RunCatalogOps.js +85 -0
  255. package/dist/cjs/internal/RunCatalogOps.js.map +7 -0
  256. package/dist/cjs/internal/RunCoordinator.d.ts +78 -0
  257. package/dist/cjs/internal/RunCoordinator.d.ts.map +1 -0
  258. package/dist/cjs/internal/RunCoordinator.js +123 -0
  259. package/dist/cjs/internal/RunCoordinator.js.map +7 -0
  260. package/dist/cjs/internal/RunDriver.d.ts +192 -0
  261. package/dist/cjs/internal/RunDriver.d.ts.map +1 -0
  262. package/dist/cjs/internal/RunDriver.js +1584 -0
  263. package/dist/cjs/internal/RunDriver.js.map +7 -0
  264. package/dist/cjs/internal/RunLifecycle.d.ts +22 -0
  265. package/dist/cjs/internal/RunLifecycle.d.ts.map +1 -0
  266. package/dist/cjs/internal/RunLifecycle.js +63 -0
  267. package/dist/cjs/internal/RunLifecycle.js.map +7 -0
  268. package/dist/cjs/internal/RunListing.d.ts +78 -0
  269. package/dist/cjs/internal/RunListing.d.ts.map +1 -0
  270. package/dist/cjs/internal/RunListing.js +171 -0
  271. package/dist/cjs/internal/RunListing.js.map +7 -0
  272. package/dist/cjs/internal/RunListingError.d.ts +35 -0
  273. package/dist/cjs/internal/RunListingError.d.ts.map +1 -0
  274. package/dist/cjs/internal/RunListingError.js +47 -0
  275. package/dist/cjs/internal/RunListingError.js.map +7 -0
  276. package/dist/cjs/internal/RuntimeGraph.d.ts +73 -0
  277. package/dist/cjs/internal/RuntimeGraph.d.ts.map +1 -0
  278. package/dist/cjs/internal/RuntimeGraph.js +180 -0
  279. package/dist/cjs/internal/RuntimeGraph.js.map +7 -0
  280. package/dist/cjs/internal/SandboxedExecution.d.ts +80 -0
  281. package/dist/cjs/internal/SandboxedExecution.d.ts.map +1 -0
  282. package/dist/cjs/internal/SandboxedExecution.js +104 -0
  283. package/dist/cjs/internal/SandboxedExecution.js.map +7 -0
  284. package/dist/cjs/internal/StateTransaction.d.ts +44 -0
  285. package/dist/cjs/internal/StateTransaction.d.ts.map +1 -0
  286. package/dist/cjs/internal/StateTransaction.js +52 -0
  287. package/dist/cjs/internal/StateTransaction.js.map +7 -0
  288. package/dist/cjs/internal/StepFacts.d.ts +14 -0
  289. package/dist/cjs/internal/StepFacts.d.ts.map +1 -0
  290. package/dist/cjs/internal/StepFacts.js +58 -0
  291. package/dist/cjs/internal/StepFacts.js.map +7 -0
  292. package/dist/cjs/internal/TypedEvents.d.ts +14 -0
  293. package/dist/cjs/internal/TypedEvents.d.ts.map +1 -0
  294. package/dist/cjs/internal/TypedEvents.js +37 -0
  295. package/dist/cjs/internal/TypedEvents.js.map +7 -0
  296. package/dist/cjs/migrations/0001_initial.d.ts +17 -0
  297. package/dist/cjs/migrations/0001_initial.d.ts.map +1 -0
  298. package/dist/cjs/migrations/0001_initial.js +61 -0
  299. package/dist/cjs/migrations/0001_initial.js.map +7 -0
  300. package/dist/cjs/migrations/0002_selection_store.d.ts +15 -0
  301. package/dist/cjs/migrations/0002_selection_store.d.ts.map +1 -0
  302. package/dist/cjs/migrations/0002_selection_store.js +56 -0
  303. package/dist/cjs/migrations/0002_selection_store.js.map +7 -0
  304. package/dist/cjs/migrations/0003_plan_inputs.d.ts +13 -0
  305. package/dist/cjs/migrations/0003_plan_inputs.d.ts.map +1 -0
  306. package/dist/cjs/migrations/0003_plan_inputs.js +90 -0
  307. package/dist/cjs/migrations/0003_plan_inputs.js.map +7 -0
  308. package/dist/cjs/migrations/0004_plan_environment.d.ts +14 -0
  309. package/dist/cjs/migrations/0004_plan_environment.d.ts.map +1 -0
  310. package/dist/cjs/migrations/0004_plan_environment.js +56 -0
  311. package/dist/cjs/migrations/0004_plan_environment.js.map +7 -0
  312. package/dist/cjs/migrations/0005_plan_merges.d.ts +14 -0
  313. package/dist/cjs/migrations/0005_plan_merges.d.ts.map +1 -0
  314. package/dist/cjs/migrations/0005_plan_merges.js +82 -0
  315. package/dist/cjs/migrations/0005_plan_merges.js.map +7 -0
  316. package/dist/cjs/migrations/0006_execution_listing.d.ts +15 -0
  317. package/dist/cjs/migrations/0006_execution_listing.d.ts.map +1 -0
  318. package/dist/cjs/migrations/0006_execution_listing.js +101 -0
  319. package/dist/cjs/migrations/0006_execution_listing.js.map +7 -0
  320. package/dist/cjs/migrations/0007_run_parent_sequence.d.ts +15 -0
  321. package/dist/cjs/migrations/0007_run_parent_sequence.d.ts.map +1 -0
  322. package/dist/cjs/migrations/0007_run_parent_sequence.js +40 -0
  323. package/dist/cjs/migrations/0007_run_parent_sequence.js.map +7 -0
  324. package/dist/cjs/migrations/0008_deferred_consumption.d.ts +16 -0
  325. package/dist/cjs/migrations/0008_deferred_consumption.d.ts.map +1 -0
  326. package/dist/cjs/migrations/0008_deferred_consumption.js +45 -0
  327. package/dist/cjs/migrations/0008_deferred_consumption.js.map +7 -0
  328. package/dist/cjs/migrations/0009_deferred_clock_facts.d.ts +24 -0
  329. package/dist/cjs/migrations/0009_deferred_clock_facts.d.ts.map +1 -0
  330. package/dist/cjs/migrations/0009_deferred_clock_facts.js +141 -0
  331. package/dist/cjs/migrations/0009_deferred_clock_facts.js.map +7 -0
  332. package/dist/cjs/migrations/0010_pending_cancellation.d.ts +15 -0
  333. package/dist/cjs/migrations/0010_pending_cancellation.d.ts.map +1 -0
  334. package/dist/cjs/migrations/0010_pending_cancellation.js +41 -0
  335. package/dist/cjs/migrations/0010_pending_cancellation.js.map +7 -0
  336. package/dist/cjs/package.json +1 -0
  337. package/dist/cjs/test/TestStores.d.ts +89 -0
  338. package/dist/cjs/test/TestStores.d.ts.map +1 -0
  339. package/dist/cjs/test/TestStores.js +98 -0
  340. package/dist/cjs/test/TestStores.js.map +7 -0
  341. package/dist/esm/ArtifactGc.d.ts +235 -0
  342. package/dist/esm/ArtifactGc.d.ts.map +1 -0
  343. package/dist/esm/ArtifactGc.js +268 -0
  344. package/dist/esm/ArtifactGc.js.map +1 -0
  345. package/dist/esm/ArtifactSync.d.ts +164 -0
  346. package/dist/esm/ArtifactSync.d.ts.map +1 -0
  347. package/dist/esm/ArtifactSync.js +176 -0
  348. package/dist/esm/ArtifactSync.js.map +1 -0
  349. package/dist/esm/CacheSync.d.ts +112 -0
  350. package/dist/esm/CacheSync.d.ts.map +1 -0
  351. package/dist/esm/CacheSync.js +94 -0
  352. package/dist/esm/CacheSync.js.map +1 -0
  353. package/dist/esm/DeferredClockFold.d.ts +354 -0
  354. package/dist/esm/DeferredClockFold.d.ts.map +1 -0
  355. package/dist/esm/DeferredClockFold.js +472 -0
  356. package/dist/esm/DeferredClockFold.js.map +1 -0
  357. package/dist/esm/DisasterRecovery.d.ts +431 -0
  358. package/dist/esm/DisasterRecovery.d.ts.map +1 -0
  359. package/dist/esm/DisasterRecovery.js +523 -0
  360. package/dist/esm/DisasterRecovery.js.map +1 -0
  361. package/dist/esm/DurableEngineState.d.ts +776 -0
  362. package/dist/esm/DurableEngineState.d.ts.map +1 -0
  363. package/dist/esm/DurableEngineState.js +1648 -0
  364. package/dist/esm/DurableEngineState.js.map +1 -0
  365. package/dist/esm/EngineStore.d.ts +158 -0
  366. package/dist/esm/EngineStore.d.ts.map +1 -0
  367. package/dist/esm/EngineStore.js +403 -0
  368. package/dist/esm/EngineStore.js.map +1 -0
  369. package/dist/esm/EngineStoreMetrics.d.ts +276 -0
  370. package/dist/esm/EngineStoreMetrics.d.ts.map +1 -0
  371. package/dist/esm/EngineStoreMetrics.js +260 -0
  372. package/dist/esm/EngineStoreMetrics.js.map +1 -0
  373. package/dist/esm/Errors.d.ts +22 -0
  374. package/dist/esm/Errors.d.ts.map +1 -0
  375. package/dist/esm/Errors.js +22 -0
  376. package/dist/esm/Errors.js.map +1 -0
  377. package/dist/esm/EventTypes.d.ts +27 -0
  378. package/dist/esm/EventTypes.d.ts.map +1 -0
  379. package/dist/esm/EventTypes.js +27 -0
  380. package/dist/esm/EventTypes.js.map +1 -0
  381. package/dist/esm/ExecutionFacts.d.ts +59 -0
  382. package/dist/esm/ExecutionFacts.d.ts.map +1 -0
  383. package/dist/esm/ExecutionFacts.js +96 -0
  384. package/dist/esm/ExecutionFacts.js.map +1 -0
  385. package/dist/esm/ExecutionSnapshot.d.ts +117 -0
  386. package/dist/esm/ExecutionSnapshot.d.ts.map +1 -0
  387. package/dist/esm/ExecutionSnapshot.js +95 -0
  388. package/dist/esm/ExecutionSnapshot.js.map +1 -0
  389. package/dist/esm/Inconsistency.d.ts +154 -0
  390. package/dist/esm/Inconsistency.d.ts.map +1 -0
  391. package/dist/esm/Inconsistency.js +133 -0
  392. package/dist/esm/Inconsistency.js.map +1 -0
  393. package/dist/esm/Migrations.d.ts +56 -0
  394. package/dist/esm/Migrations.d.ts.map +1 -0
  395. package/dist/esm/Migrations.js +91 -0
  396. package/dist/esm/Migrations.js.map +1 -0
  397. package/dist/esm/OwnerIdentity.d.ts +91 -0
  398. package/dist/esm/OwnerIdentity.d.ts.map +1 -0
  399. package/dist/esm/OwnerIdentity.js +99 -0
  400. package/dist/esm/OwnerIdentity.js.map +1 -0
  401. package/dist/esm/PlanInputStore.d.ts +110 -0
  402. package/dist/esm/PlanInputStore.d.ts.map +1 -0
  403. package/dist/esm/PlanInputStore.js +207 -0
  404. package/dist/esm/PlanInputStore.js.map +1 -0
  405. package/dist/esm/PlanMergeStore.d.ts +113 -0
  406. package/dist/esm/PlanMergeStore.d.ts.map +1 -0
  407. package/dist/esm/PlanMergeStore.js +244 -0
  408. package/dist/esm/PlanMergeStore.js.map +1 -0
  409. package/dist/esm/PlanScheduler.d.ts +363 -0
  410. package/dist/esm/PlanScheduler.d.ts.map +1 -0
  411. package/dist/esm/PlanScheduler.js +1321 -0
  412. package/dist/esm/PlanScheduler.js.map +1 -0
  413. package/dist/esm/Reconciliation.d.ts +175 -0
  414. package/dist/esm/Reconciliation.d.ts.map +1 -0
  415. package/dist/esm/Reconciliation.js +175 -0
  416. package/dist/esm/Reconciliation.js.map +1 -0
  417. package/dist/esm/ReplayOnly.d.ts +91 -0
  418. package/dist/esm/ReplayOnly.d.ts.map +1 -0
  419. package/dist/esm/ReplayOnly.js +59 -0
  420. package/dist/esm/ReplayOnly.js.map +1 -0
  421. package/dist/esm/Retention.d.ts +113 -0
  422. package/dist/esm/Retention.d.ts.map +1 -0
  423. package/dist/esm/Retention.js +139 -0
  424. package/dist/esm/Retention.js.map +1 -0
  425. package/dist/esm/RunCatalogRead.d.ts +17 -0
  426. package/dist/esm/RunCatalogRead.d.ts.map +1 -0
  427. package/dist/esm/RunCatalogRead.js +17 -0
  428. package/dist/esm/RunCatalogRead.js.map +1 -0
  429. package/dist/esm/RunChangeFeed.d.ts +75 -0
  430. package/dist/esm/RunChangeFeed.d.ts.map +1 -0
  431. package/dist/esm/RunChangeFeed.js +81 -0
  432. package/dist/esm/RunChangeFeed.js.map +1 -0
  433. package/dist/esm/RunState.d.ts +116 -0
  434. package/dist/esm/RunState.d.ts.map +1 -0
  435. package/dist/esm/RunState.js +109 -0
  436. package/dist/esm/RunState.js.map +1 -0
  437. package/dist/esm/Selection.d.ts +495 -0
  438. package/dist/esm/Selection.d.ts.map +1 -0
  439. package/dist/esm/Selection.js +482 -0
  440. package/dist/esm/Selection.js.map +1 -0
  441. package/dist/esm/SelectionStore.d.ts +141 -0
  442. package/dist/esm/SelectionStore.d.ts.map +1 -0
  443. package/dist/esm/SelectionStore.js +215 -0
  444. package/dist/esm/SelectionStore.js.map +1 -0
  445. package/dist/esm/StepBoundary.d.ts +501 -0
  446. package/dist/esm/StepBoundary.d.ts.map +1 -0
  447. package/dist/esm/StepBoundary.js +919 -0
  448. package/dist/esm/StepBoundary.js.map +1 -0
  449. package/dist/esm/StepCacheFold.d.ts +148 -0
  450. package/dist/esm/StepCacheFold.d.ts.map +1 -0
  451. package/dist/esm/StepCacheFold.js +201 -0
  452. package/dist/esm/StepCacheFold.js.map +1 -0
  453. package/dist/esm/StepSandbox.d.ts +78 -0
  454. package/dist/esm/StepSandbox.d.ts.map +1 -0
  455. package/dist/esm/StepSandbox.js +70 -0
  456. package/dist/esm/StepSandbox.js.map +1 -0
  457. package/dist/esm/WakeBus.d.ts +116 -0
  458. package/dist/esm/WakeBus.d.ts.map +1 -0
  459. package/dist/esm/WakeBus.js +121 -0
  460. package/dist/esm/WakeBus.js.map +1 -0
  461. package/dist/esm/WorkspaceSandbox.d.ts +619 -0
  462. package/dist/esm/WorkspaceSandbox.d.ts.map +1 -0
  463. package/dist/esm/WorkspaceSandbox.js +985 -0
  464. package/dist/esm/WorkspaceSandbox.js.map +1 -0
  465. package/dist/esm/index.d.ts +157 -0
  466. package/dist/esm/index.d.ts.map +1 -0
  467. package/dist/esm/index.js +157 -0
  468. package/dist/esm/index.js.map +1 -0
  469. package/dist/esm/internal/ActionPersistence.d.ts +276 -0
  470. package/dist/esm/internal/ActionPersistence.d.ts.map +1 -0
  471. package/dist/esm/internal/ActionPersistence.js +2306 -0
  472. package/dist/esm/internal/ActionPersistence.js.map +1 -0
  473. package/dist/esm/internal/ArtifactRoots.d.ts +38 -0
  474. package/dist/esm/internal/ArtifactRoots.d.ts.map +1 -0
  475. package/dist/esm/internal/ArtifactRoots.js +76 -0
  476. package/dist/esm/internal/ArtifactRoots.js.map +1 -0
  477. package/dist/esm/internal/AttemptAdmission.d.ts +53 -0
  478. package/dist/esm/internal/AttemptAdmission.d.ts.map +1 -0
  479. package/dist/esm/internal/AttemptAdmission.js +52 -0
  480. package/dist/esm/internal/AttemptAdmission.js.map +1 -0
  481. package/dist/esm/internal/AttemptLifecycle.d.ts +245 -0
  482. package/dist/esm/internal/AttemptLifecycle.d.ts.map +1 -0
  483. package/dist/esm/internal/AttemptLifecycle.js +104 -0
  484. package/dist/esm/internal/AttemptLifecycle.js.map +1 -0
  485. package/dist/esm/internal/AttemptProbe.d.ts +53 -0
  486. package/dist/esm/internal/AttemptProbe.d.ts.map +1 -0
  487. package/dist/esm/internal/AttemptProbe.js +83 -0
  488. package/dist/esm/internal/AttemptProbe.js.map +1 -0
  489. package/dist/esm/internal/CacheAdmission.d.ts +79 -0
  490. package/dist/esm/internal/CacheAdmission.d.ts.map +1 -0
  491. package/dist/esm/internal/CacheAdmission.js +72 -0
  492. package/dist/esm/internal/CacheAdmission.js.map +1 -0
  493. package/dist/esm/internal/CacheAgeHistory.d.ts +27 -0
  494. package/dist/esm/internal/CacheAgeHistory.d.ts.map +1 -0
  495. package/dist/esm/internal/CacheAgeHistory.js +49 -0
  496. package/dist/esm/internal/CacheAgeHistory.js.map +1 -0
  497. package/dist/esm/internal/CacheAgeVerdicts.d.ts +15 -0
  498. package/dist/esm/internal/CacheAgeVerdicts.d.ts.map +1 -0
  499. package/dist/esm/internal/CacheAgeVerdicts.js +54 -0
  500. package/dist/esm/internal/CacheAgeVerdicts.js.map +1 -0
  501. package/dist/esm/internal/CacheOutputPolicy.d.ts +24 -0
  502. package/dist/esm/internal/CacheOutputPolicy.d.ts.map +1 -0
  503. package/dist/esm/internal/CacheOutputPolicy.js +73 -0
  504. package/dist/esm/internal/CacheOutputPolicy.js.map +1 -0
  505. package/dist/esm/internal/CachePublication.d.ts +97 -0
  506. package/dist/esm/internal/CachePublication.d.ts.map +1 -0
  507. package/dist/esm/internal/CachePublication.js +116 -0
  508. package/dist/esm/internal/CachePublication.js.map +1 -0
  509. package/dist/esm/internal/CallFacts.d.ts +15 -0
  510. package/dist/esm/internal/CallFacts.d.ts.map +1 -0
  511. package/dist/esm/internal/CallFacts.js +83 -0
  512. package/dist/esm/internal/CallFacts.js.map +1 -0
  513. package/dist/esm/internal/CopiedRecord.d.ts +61 -0
  514. package/dist/esm/internal/CopiedRecord.d.ts.map +1 -0
  515. package/dist/esm/internal/CopiedRecord.js +165 -0
  516. package/dist/esm/internal/CopiedRecord.js.map +1 -0
  517. package/dist/esm/internal/DeferredPersistence.d.ts +108 -0
  518. package/dist/esm/internal/DeferredPersistence.d.ts.map +1 -0
  519. package/dist/esm/internal/DeferredPersistence.js +240 -0
  520. package/dist/esm/internal/DeferredPersistence.js.map +1 -0
  521. package/dist/esm/internal/EffectRecords.d.ts +92 -0
  522. package/dist/esm/internal/EffectRecords.d.ts.map +1 -0
  523. package/dist/esm/internal/EffectRecords.js +94 -0
  524. package/dist/esm/internal/EffectRecords.js.map +1 -0
  525. package/dist/esm/internal/EngineJj.d.ts +30 -0
  526. package/dist/esm/internal/EngineJj.d.ts.map +1 -0
  527. package/dist/esm/internal/EngineJj.js +29 -0
  528. package/dist/esm/internal/EngineJj.js.map +1 -0
  529. package/dist/esm/internal/EngineStateSchema.d.ts +68 -0
  530. package/dist/esm/internal/EngineStateSchema.d.ts.map +1 -0
  531. package/dist/esm/internal/EngineStateSchema.js +53 -0
  532. package/dist/esm/internal/EngineStateSchema.js.map +1 -0
  533. package/dist/esm/internal/ExecutionSnapshotRead.d.ts +162 -0
  534. package/dist/esm/internal/ExecutionSnapshotRead.d.ts.map +1 -0
  535. package/dist/esm/internal/ExecutionSnapshotRead.js +218 -0
  536. package/dist/esm/internal/ExecutionSnapshotRead.js.map +1 -0
  537. package/dist/esm/internal/ExecutionSnapshotRelations.d.ts +39 -0
  538. package/dist/esm/internal/ExecutionSnapshotRelations.d.ts.map +1 -0
  539. package/dist/esm/internal/ExecutionSnapshotRelations.js +81 -0
  540. package/dist/esm/internal/ExecutionSnapshotRelations.js.map +1 -0
  541. package/dist/esm/internal/ExitEncoding.d.ts +180 -0
  542. package/dist/esm/internal/ExitEncoding.d.ts.map +1 -0
  543. package/dist/esm/internal/ExitEncoding.js +361 -0
  544. package/dist/esm/internal/ExitEncoding.js.map +1 -0
  545. package/dist/esm/internal/FileBoundarySnapshot.d.ts +14 -0
  546. package/dist/esm/internal/FileBoundarySnapshot.d.ts.map +1 -0
  547. package/dist/esm/internal/FileBoundarySnapshot.js +29 -0
  548. package/dist/esm/internal/FileBoundarySnapshot.js.map +1 -0
  549. package/dist/esm/internal/FileEnumeration.d.ts +127 -0
  550. package/dist/esm/internal/FileEnumeration.d.ts.map +1 -0
  551. package/dist/esm/internal/FileEnumeration.js +236 -0
  552. package/dist/esm/internal/FileEnumeration.js.map +1 -0
  553. package/dist/esm/internal/HostReflection.d.ts +80 -0
  554. package/dist/esm/internal/HostReflection.d.ts.map +1 -0
  555. package/dist/esm/internal/HostReflection.js +98 -0
  556. package/dist/esm/internal/HostReflection.js.map +1 -0
  557. package/dist/esm/internal/JournalRecords.d.ts +325 -0
  558. package/dist/esm/internal/JournalRecords.d.ts.map +1 -0
  559. package/dist/esm/internal/JournalRecords.js +306 -0
  560. package/dist/esm/internal/JournalRecords.js.map +1 -0
  561. package/dist/esm/internal/NodeJournal.d.ts +157 -0
  562. package/dist/esm/internal/NodeJournal.d.ts.map +1 -0
  563. package/dist/esm/internal/NodeJournal.js +298 -0
  564. package/dist/esm/internal/NodeJournal.js.map +1 -0
  565. package/dist/esm/internal/Ordering.d.ts +14 -0
  566. package/dist/esm/internal/Ordering.d.ts.map +1 -0
  567. package/dist/esm/internal/Ordering.js +14 -0
  568. package/dist/esm/internal/Ordering.js.map +1 -0
  569. package/dist/esm/internal/PlanInputs.d.ts +14 -0
  570. package/dist/esm/internal/PlanInputs.d.ts.map +1 -0
  571. package/dist/esm/internal/PlanInputs.js +57 -0
  572. package/dist/esm/internal/PlanInputs.js.map +1 -0
  573. package/dist/esm/internal/PlanMerges.d.ts +178 -0
  574. package/dist/esm/internal/PlanMerges.d.ts.map +1 -0
  575. package/dist/esm/internal/PlanMerges.js +113 -0
  576. package/dist/esm/internal/PlanMerges.js.map +1 -0
  577. package/dist/esm/internal/ProvenanceSlot.d.ts +30 -0
  578. package/dist/esm/internal/ProvenanceSlot.d.ts.map +1 -0
  579. package/dist/esm/internal/ProvenanceSlot.js +39 -0
  580. package/dist/esm/internal/ProvenanceSlot.js.map +1 -0
  581. package/dist/esm/internal/ResultEnvelope.d.ts +88 -0
  582. package/dist/esm/internal/ResultEnvelope.d.ts.map +1 -0
  583. package/dist/esm/internal/ResultEnvelope.js +83 -0
  584. package/dist/esm/internal/ResultEnvelope.js.map +1 -0
  585. package/dist/esm/internal/RetentionOps.d.ts +414 -0
  586. package/dist/esm/internal/RetentionOps.d.ts.map +1 -0
  587. package/dist/esm/internal/RetentionOps.js +576 -0
  588. package/dist/esm/internal/RetentionOps.js.map +1 -0
  589. package/dist/esm/internal/RunCatalogOps.d.ts +118 -0
  590. package/dist/esm/internal/RunCatalogOps.d.ts.map +1 -0
  591. package/dist/esm/internal/RunCatalogOps.js +120 -0
  592. package/dist/esm/internal/RunCatalogOps.js.map +1 -0
  593. package/dist/esm/internal/RunCoordinator.d.ts +78 -0
  594. package/dist/esm/internal/RunCoordinator.d.ts.map +1 -0
  595. package/dist/esm/internal/RunCoordinator.js +115 -0
  596. package/dist/esm/internal/RunCoordinator.js.map +1 -0
  597. package/dist/esm/internal/RunDriver.d.ts +192 -0
  598. package/dist/esm/internal/RunDriver.d.ts.map +1 -0
  599. package/dist/esm/internal/RunDriver.js +2334 -0
  600. package/dist/esm/internal/RunDriver.js.map +1 -0
  601. package/dist/esm/internal/RunLifecycle.d.ts +22 -0
  602. package/dist/esm/internal/RunLifecycle.d.ts.map +1 -0
  603. package/dist/esm/internal/RunLifecycle.js +49 -0
  604. package/dist/esm/internal/RunLifecycle.js.map +1 -0
  605. package/dist/esm/internal/RunListing.d.ts +78 -0
  606. package/dist/esm/internal/RunListing.d.ts.map +1 -0
  607. package/dist/esm/internal/RunListing.js +146 -0
  608. package/dist/esm/internal/RunListing.js.map +1 -0
  609. package/dist/esm/internal/RunListingError.d.ts +35 -0
  610. package/dist/esm/internal/RunListingError.d.ts.map +1 -0
  611. package/dist/esm/internal/RunListingError.js +27 -0
  612. package/dist/esm/internal/RunListingError.js.map +1 -0
  613. package/dist/esm/internal/RuntimeGraph.d.ts +73 -0
  614. package/dist/esm/internal/RuntimeGraph.d.ts.map +1 -0
  615. package/dist/esm/internal/RuntimeGraph.js +182 -0
  616. package/dist/esm/internal/RuntimeGraph.js.map +1 -0
  617. package/dist/esm/internal/SandboxedExecution.d.ts +80 -0
  618. package/dist/esm/internal/SandboxedExecution.d.ts.map +1 -0
  619. package/dist/esm/internal/SandboxedExecution.js +107 -0
  620. package/dist/esm/internal/SandboxedExecution.js.map +1 -0
  621. package/dist/esm/internal/StateTransaction.d.ts +44 -0
  622. package/dist/esm/internal/StateTransaction.d.ts.map +1 -0
  623. package/dist/esm/internal/StateTransaction.js +54 -0
  624. package/dist/esm/internal/StateTransaction.js.map +1 -0
  625. package/dist/esm/internal/StepFacts.d.ts +14 -0
  626. package/dist/esm/internal/StepFacts.d.ts.map +1 -0
  627. package/dist/esm/internal/StepFacts.js +35 -0
  628. package/dist/esm/internal/StepFacts.js.map +1 -0
  629. package/dist/esm/internal/TypedEvents.d.ts +14 -0
  630. package/dist/esm/internal/TypedEvents.d.ts.map +1 -0
  631. package/dist/esm/internal/TypedEvents.js +14 -0
  632. package/dist/esm/internal/TypedEvents.js.map +1 -0
  633. package/dist/esm/migrations/0001_initial.d.ts +17 -0
  634. package/dist/esm/migrations/0001_initial.d.ts.map +1 -0
  635. package/dist/esm/migrations/0001_initial.js +41 -0
  636. package/dist/esm/migrations/0001_initial.js.map +1 -0
  637. package/dist/esm/migrations/0002_selection_store.d.ts +15 -0
  638. package/dist/esm/migrations/0002_selection_store.d.ts.map +1 -0
  639. package/dist/esm/migrations/0002_selection_store.js +34 -0
  640. package/dist/esm/migrations/0002_selection_store.js.map +1 -0
  641. package/dist/esm/migrations/0003_plan_inputs.d.ts +13 -0
  642. package/dist/esm/migrations/0003_plan_inputs.d.ts.map +1 -0
  643. package/dist/esm/migrations/0003_plan_inputs.js +70 -0
  644. package/dist/esm/migrations/0003_plan_inputs.js.map +1 -0
  645. package/dist/esm/migrations/0004_plan_environment.d.ts +14 -0
  646. package/dist/esm/migrations/0004_plan_environment.d.ts.map +1 -0
  647. package/dist/esm/migrations/0004_plan_environment.js +33 -0
  648. package/dist/esm/migrations/0004_plan_environment.js.map +1 -0
  649. package/dist/esm/migrations/0005_plan_merges.d.ts +14 -0
  650. package/dist/esm/migrations/0005_plan_merges.d.ts.map +1 -0
  651. package/dist/esm/migrations/0005_plan_merges.js +59 -0
  652. package/dist/esm/migrations/0005_plan_merges.js.map +1 -0
  653. package/dist/esm/migrations/0006_execution_listing.d.ts +15 -0
  654. package/dist/esm/migrations/0006_execution_listing.d.ts.map +1 -0
  655. package/dist/esm/migrations/0006_execution_listing.js +81 -0
  656. package/dist/esm/migrations/0006_execution_listing.js.map +1 -0
  657. package/dist/esm/migrations/0007_run_parent_sequence.d.ts +15 -0
  658. package/dist/esm/migrations/0007_run_parent_sequence.d.ts.map +1 -0
  659. package/dist/esm/migrations/0007_run_parent_sequence.js +18 -0
  660. package/dist/esm/migrations/0007_run_parent_sequence.js.map +1 -0
  661. package/dist/esm/migrations/0008_deferred_consumption.d.ts +16 -0
  662. package/dist/esm/migrations/0008_deferred_consumption.d.ts.map +1 -0
  663. package/dist/esm/migrations/0008_deferred_consumption.js +24 -0
  664. package/dist/esm/migrations/0008_deferred_consumption.js.map +1 -0
  665. package/dist/esm/migrations/0009_deferred_clock_facts.d.ts +24 -0
  666. package/dist/esm/migrations/0009_deferred_clock_facts.d.ts.map +1 -0
  667. package/dist/esm/migrations/0009_deferred_clock_facts.js +127 -0
  668. package/dist/esm/migrations/0009_deferred_clock_facts.js.map +1 -0
  669. package/dist/esm/migrations/0010_pending_cancellation.d.ts +15 -0
  670. package/dist/esm/migrations/0010_pending_cancellation.d.ts.map +1 -0
  671. package/dist/esm/migrations/0010_pending_cancellation.js +19 -0
  672. package/dist/esm/migrations/0010_pending_cancellation.js.map +1 -0
  673. package/dist/esm/test/TestStores.d.ts +89 -0
  674. package/dist/esm/test/TestStores.d.ts.map +1 -0
  675. package/dist/esm/test/TestStores.js +103 -0
  676. package/dist/esm/test/TestStores.js.map +1 -0
  677. package/docs/README.md +113 -0
  678. package/docs/api.md +1494 -0
  679. package/docs/concepts/attempts-and-replay.md +149 -0
  680. package/docs/concepts/cache-admission.md +265 -0
  681. package/docs/concepts/call-facts.md +86 -0
  682. package/docs/concepts/durable-waits.md +175 -0
  683. package/docs/concepts/execution-facts.md +90 -0
  684. package/docs/concepts/ownership-and-fencing.md +128 -0
  685. package/docs/concepts/step-boundaries.md +148 -0
  686. package/docs/concepts/workspace-transactions.md +199 -0
  687. package/docs/event-types.md +14 -0
  688. package/docs/guides/back-up-and-restore.md +164 -0
  689. package/docs/guides/collect-unreferenced-artifacts.md +128 -0
  690. package/docs/guides/compose-a-durable-engine.md +146 -0
  691. package/docs/guides/coordinate-two-processes.md +120 -0
  692. package/docs/guides/defer-work-with-selection.md +171 -0
  693. package/docs/guides/delete-old-run-history.md +154 -0
  694. package/docs/guides/drive-a-plan.md +314 -0
  695. package/docs/guides/observe-engine-metrics.md +98 -0
  696. package/docs/guides/observe-executions.md +187 -0
  697. package/docs/guides/reclaim-runs-from-a-dead-host.md +133 -0
  698. package/docs/guides/share-a-cache-across-machines.md +134 -0
  699. package/docs/guides/testing.md +123 -0
  700. package/docs/installation.md +102 -0
  701. package/docs/quickstart.md +215 -0
  702. package/docs/troubleshooting.md +347 -0
  703. package/package.json +438 -3
  704. package/src/ArtifactGc.ts +408 -0
  705. package/src/ArtifactSync.ts +278 -0
  706. package/src/CacheSync.ts +131 -0
  707. package/src/DeferredClockFold.ts +586 -0
  708. package/src/DisasterRecovery.ts +888 -0
  709. package/src/DurableEngineState.ts +2656 -0
  710. package/src/EngineStore.ts +656 -0
  711. package/src/EngineStoreMetrics.ts +331 -0
  712. package/src/Errors.ts +28 -0
  713. package/src/EventTypes.ts +27 -0
  714. package/src/ExecutionFacts.ts +125 -0
  715. package/src/ExecutionSnapshot.ts +186 -0
  716. package/src/Inconsistency.ts +253 -0
  717. package/src/Migrations.ts +95 -0
  718. package/src/OwnerIdentity.ts +125 -0
  719. package/src/PlanInputStore.ts +292 -0
  720. package/src/PlanMergeStore.ts +330 -0
  721. package/src/PlanScheduler.ts +1806 -0
  722. package/src/Reconciliation.ts +224 -0
  723. package/src/ReplayOnly.ts +95 -0
  724. package/src/Retention.ts +214 -0
  725. package/src/RunCatalogRead.ts +27 -0
  726. package/src/RunChangeFeed.ts +125 -0
  727. package/src/RunState.ts +137 -0
  728. package/src/Selection.ts +683 -0
  729. package/src/SelectionStore.ts +353 -0
  730. package/src/StepBoundary.ts +1165 -0
  731. package/src/StepCacheFold.ts +244 -0
  732. package/src/StepSandbox.ts +110 -0
  733. package/src/WakeBus.ts +167 -0
  734. package/src/WorkspaceSandbox.ts +1604 -0
  735. package/src/index.ts +185 -0
  736. package/src/internal/ActionPersistence.ts +2687 -0
  737. package/src/internal/ArtifactRoots.ts +92 -0
  738. package/src/internal/AttemptAdmission.ts +76 -0
  739. package/src/internal/AttemptLifecycle.ts +163 -0
  740. package/src/internal/AttemptProbe.ts +90 -0
  741. package/src/internal/CacheAdmission.ts +133 -0
  742. package/src/internal/CacheAgeHistory.ts +58 -0
  743. package/src/internal/CacheAgeVerdicts.ts +61 -0
  744. package/src/internal/CacheOutputPolicy.ts +82 -0
  745. package/src/internal/CachePublication.ts +153 -0
  746. package/src/internal/CallFacts.ts +87 -0
  747. package/src/internal/CopiedRecord.ts +201 -0
  748. package/src/internal/DeferredPersistence.ts +459 -0
  749. package/src/internal/EffectRecords.ts +136 -0
  750. package/src/internal/EngineJj.ts +30 -0
  751. package/src/internal/EngineStateSchema.ts +92 -0
  752. package/src/internal/ExecutionSnapshotRead.ts +298 -0
  753. package/src/internal/ExecutionSnapshotRelations.ts +121 -0
  754. package/src/internal/ExitEncoding.ts +453 -0
  755. package/src/internal/FileBoundarySnapshot.ts +39 -0
  756. package/src/internal/FileEnumeration.ts +334 -0
  757. package/src/internal/HostReflection.ts +128 -0
  758. package/src/internal/JournalRecords.ts +396 -0
  759. package/src/internal/NodeJournal.ts +340 -0
  760. package/src/internal/Ordering.ts +14 -0
  761. package/src/internal/PlanInputs.ts +62 -0
  762. package/src/internal/PlanMerges.ts +123 -0
  763. package/src/internal/ProvenanceSlot.ts +52 -0
  764. package/src/internal/ResultEnvelope.ts +118 -0
  765. package/src/internal/RetentionOps.ts +865 -0
  766. package/src/internal/RunCatalogOps.ts +174 -0
  767. package/src/internal/RunCoordinator.ts +215 -0
  768. package/src/internal/RunDriver.ts +3152 -0
  769. package/src/internal/RunLifecycle.ts +53 -0
  770. package/src/internal/RunListing.ts +210 -0
  771. package/src/internal/RunListingError.ts +37 -0
  772. package/src/internal/RuntimeGraph.ts +253 -0
  773. package/src/internal/SandboxedExecution.ts +165 -0
  774. package/src/internal/StateTransaction.ts +71 -0
  775. package/src/internal/StepFacts.ts +36 -0
  776. package/src/internal/TypedEvents.ts +29 -0
  777. package/src/migrations/0001_initial.ts +51 -0
  778. package/src/migrations/0002_selection_store.ts +38 -0
  779. package/src/migrations/0003_plan_inputs.ts +75 -0
  780. package/src/migrations/0004_plan_environment.ts +34 -0
  781. package/src/migrations/0005_plan_merges.ts +60 -0
  782. package/src/migrations/0006_execution_listing.ts +86 -0
  783. package/src/migrations/0007_run_parent_sequence.ts +19 -0
  784. package/src/migrations/0008_deferred_consumption.ts +27 -0
  785. package/src/migrations/0009_deferred_clock_facts.ts +163 -0
  786. package/src/migrations/0010_pending_cancellation.ts +20 -0
  787. package/src/test/TestStores.ts +145 -0
@@ -0,0 +1,1321 @@
1
+ /**
2
+ * Drives a persisted plan: the node scheduler.
3
+ *
4
+ * `@smthrs/plan` makes the plan a value; this makes it run. The scheduler
5
+ * walks the persisted graph, dispatches ready nodes through the same
6
+ * `internal/ActionPersistence` seam every action uses — so the shared step
7
+ * cache, the workspace sandbox's execute→materialize transaction, attempt
8
+ * rows, and the fenced journal all apply unchanged — and records an
9
+ * evaluation outcome per node.
10
+ *
11
+ * ## What it is, and what it is not
12
+ *
13
+ * Skyframe's `AbstractParallelEvaluator` is the prior art for the state
14
+ * machine (`CHECK_DEPENDENCIES → VERIFIED_CLEAN | NEEDS_REBUILDING →
15
+ * REBUILDING → DONE`) and `EvaluationProgressReceiver` for the outcome
16
+ * vocabulary. Two deliberate deviations:
17
+ *
18
+ * 1. **No cache-invalidating node visitor.** Content addressing governs
19
+ * reuse. Private reverse indexes propagate settled outcomes and readiness,
20
+ * never dirty bits. Dispatch-time content measurement still decides
21
+ * whether a recorded result can serve the node.
22
+ * 2. **Completion-driven, without Skyframe restarts.** Skyframe atomically
23
+ * signals reverse dependencies when one node settles. Our dependencies are
24
+ * declared in the plan before anything runs, so one coordinator can make
25
+ * the equivalent decision from the plan, settled state, and scheduling
26
+ * permits: every completion is reconciled and immediately opens another
27
+ * admission pass. Giving up the wavefront barrier also gives up its
28
+ * trivially serialized reconciliation; draining and applying the durable
29
+ * deviation journal after each settlement, before reevaluating downstream
30
+ * readiness, restores that ordering without holding unrelated ready cones.
31
+ * The coordinator is the sole writer of scheduling state, which keeps every
32
+ * admission decision deterministic without the `DeterministicHelper` the
33
+ * vault rejected.
34
+ *
35
+ * ## The three limits
36
+ *
37
+ * The same number must never
38
+ * stand in for graph width, scheduler admission, and provider capacity. This
39
+ * module owns the middle one only: `concurrency.steps` is the leaf-execution
40
+ * cap, and `concurrency.agents` is the subset cap an agent node consumes in
41
+ * addition. Structural width is whatever the plan says; seats belong to
42
+ * `Agent Adapters` and are not modelled here.
43
+ *
44
+ * Under contention, ready work is ordered by effective priority — declared
45
+ * `priority` plus one point per capacity-constrained admission pass. A ready
46
+ * node gains a point exactly when a pass considers it but cannot give it the
47
+ * required permits. Aging is what lets priority change latency without
48
+ * permitting starvation; equal effective priorities preserve deterministic
49
+ * plan order.
50
+ *
51
+ * ## Observing the world exactly once
52
+ *
53
+ * The torn-run rule: never re-observe the
54
+ * world mid-run. Reads with no preceding writer are **source** inputs; their
55
+ * digests and glob membership are durably recorded before dispatch and restored
56
+ * on reopening. Preceding producers' outputs are measured after settlement —
57
+ * observing our own output, not the world. Later and self-writes are not source
58
+ * producers. New generations retain prior pins and record new observations.
59
+ *
60
+ * @since 0.1.0
61
+ */
62
+ import { Sha256 } from "@smthrs/crypto";
63
+ import { FlowEngine } from "@smthrs/engine";
64
+ import { Journal } from "@smthrs/journal";
65
+ import { Plan, Scheduling, StepKey } from "@smthrs/plan";
66
+ import { PlanStore } from "@smthrs/plan-store";
67
+ import * as FileSet from "@smthrs/plan/FileSet";
68
+ import { AttemptStore } from "@smthrs/run-store";
69
+ import * as Cause from "effect/Cause";
70
+ import * as Clock from "effect/Clock";
71
+ import * as Context from "effect/Context";
72
+ import * as Effect from "effect/Effect";
73
+ import * as Exit from "effect/Exit";
74
+ import * as FileSystem from "effect/FileSystem";
75
+ import * as Layer from "effect/Layer";
76
+ import * as Metric from "effect/Metric";
77
+ import * as Option from "effect/Option";
78
+ import * as Queue from "effect/Queue";
79
+ import * as Ref from "effect/Ref";
80
+ import * as Result from "effect/Result";
81
+ import * as Schema from "effect/Schema";
82
+ import * as EngineStoreMetrics from "./EngineStoreMetrics.js";
83
+ import * as ActionPersistence from "./internal/ActionPersistence.js";
84
+ import * as AttemptAdmission from "./internal/AttemptAdmission.js";
85
+ import * as CacheAgeVerdicts from "./internal/CacheAgeVerdicts.js";
86
+ import * as FileEnumeration from "./internal/FileEnumeration.js";
87
+ import * as JournalRecords from "./internal/JournalRecords.js";
88
+ import { compareText } from "./internal/Ordering.js";
89
+ import * as PlanInputs from "./internal/PlanInputs.js";
90
+ import * as PlanMerges from "./internal/PlanMerges.js";
91
+ import * as RuntimeGraph from "./internal/RuntimeGraph.js";
92
+ import * as PlanInputStore from "./PlanInputStore.js";
93
+ import * as PlanMergeStore from "./PlanMergeStore.js";
94
+ import * as Reconciliation from "./Reconciliation.js";
95
+ import * as ReplayOnly from "./ReplayOnly.js";
96
+ import * as Selection from "./Selection.js";
97
+ import * as StepBoundary from "./StepBoundary.js";
98
+ import * as WorkspaceSandbox from "./WorkspaceSandbox.js";
99
+ /**
100
+ * Service tag for the node executor.
101
+ *
102
+ * @since 0.1.0
103
+ * @category services
104
+ */
105
+ export class NodeExecutor extends Context.Service()("@smthrs/engine-store/NodeExecutor") {
106
+ }
107
+ /**
108
+ * Provides a plain {@link Executor} value as the {@link NodeExecutor} service.
109
+ *
110
+ * This is the whole wiring story for the scheduler's one open seam: a flow
111
+ * runtime, a test double, or a remote dispatcher each become a layer by
112
+ * passing themselves here.
113
+ *
114
+ * @since 0.1.0
115
+ * @category layers
116
+ */
117
+ export const layerExecutor = (executor) => Layer.succeed(NodeExecutor, executor);
118
+ /**
119
+ * A refusal the scheduler itself raises. A node's own failure is an outcome,
120
+ * not one of these — the run continues and the report says `failed`.
121
+ *
122
+ * @since 0.1.0
123
+ * @category errors
124
+ */
125
+ export class SchedulerError extends Schema.TaggedError()("@smthrs/engine-store/SchedulerError", {
126
+ code: Schema.Literals([
127
+ "invalid_plan",
128
+ "boundary_unavailable",
129
+ "key_uncomputable",
130
+ "elaboration_failed",
131
+ "store_failed"
132
+ ]),
133
+ message: Schema.String,
134
+ cause: Schema.optional(Schema.Unknown),
135
+ /** Failures while settling siblings after the primary scheduler failure. */
136
+ cleanupErrors: Schema.optional(Schema.Array(Schema.Unknown))
137
+ }) {
138
+ }
139
+ /**
140
+ * Service tag for the plan scheduler.
141
+ *
142
+ * @since 0.1.0
143
+ * @category services
144
+ */
145
+ export class PlanScheduler extends Context.Service()("@smthrs/engine-store/PlanScheduler") {
146
+ }
147
+ /**
148
+ * The declared digest handed to `StepBoundary.prepare` when the scheduler is
149
+ * *asking* what a path holds rather than asserting it. Prepare measures every
150
+ * declared read regardless of what the declaration claims, so any placeholder
151
+ * works; a self-describing one can never be mistaken for a real digest.
152
+ *
153
+ * @private
154
+ */
155
+ /**
156
+ * The tag a plan node dispatches, when its material names one.
157
+ *
158
+ * A material body is opaque to the compiler by design, so this reads it
159
+ * defensively and answers nothing rather than guessing: a merge node, a body
160
+ * an elaborator shaped differently, and a node whose tag is not a string all
161
+ * carry no tag at all. @private
162
+ */
163
+ const actionOf = (node) => {
164
+ const body = node.material.body;
165
+ if (typeof body !== "object" || body === null)
166
+ return undefined;
167
+ const fields = body;
168
+ const named = typeof fields["action"] === "string" ? fields["action"] : fields["flow"];
169
+ return typeof named === "string" && named !== "" ? named : undefined;
170
+ };
171
+ /**
172
+ * One node of a plan, as a journal record carries it.
173
+ *
174
+ * The same shape the interpreter writes, so a reader folds both executors
175
+ * with one decoder. `effects` and `key` are the plan's own; there is no
176
+ * declaration site here, because a plan node is compiled from a draft and the
177
+ * draft's author frame is not something the compiler keeps. @private
178
+ */
179
+ const nodeSummary = (node) => {
180
+ const action = actionOf(node);
181
+ return {
182
+ id: node.id,
183
+ kind: node.kind,
184
+ dependsOn: node.dependsOn,
185
+ tier: node.material.kind,
186
+ key: node.key,
187
+ generation: node.generation,
188
+ ...(action === undefined ? {} : { action })
189
+ };
190
+ };
191
+ const unmeasured = "unmeasured";
192
+ /** @private */
193
+ const isConflict = (cause) => cause.reasons.some((reason) => Cause.isFailReason(reason) && WorkspaceSandbox.isMaterializationConflict(reason.error));
194
+ /** @private */
195
+ const DeviationPayload = Schema.Struct({
196
+ stepKeyDigest: Schema.NonEmptyString,
197
+ attempt: Schema.Int,
198
+ paths: Schema.Array(Schema.String),
199
+ diffIdentity: Schema.String
200
+ });
201
+ const decodeDeviation = Schema.decodeUnknownOption(DeviationPayload);
202
+ const digestOf = Schema.decodeUnknownEffect(Sha256);
203
+ const storeFailure = (message) => (cause) => new SchedulerError({ code: "store_failed", message, cause });
204
+ const nonNegativeSafeInteger = (name, value) => {
205
+ if (!Number.isSafeInteger(value) || value < 0) {
206
+ throw new RangeError(`${name} must be a non-negative safe integer`);
207
+ }
208
+ return value;
209
+ };
210
+ /**
211
+ * Constructs a scheduler bound to one run.
212
+ *
213
+ * @since 0.1.0
214
+ * @category constructors
215
+ */
216
+ export const make = (options) => {
217
+ const admission = AttemptAdmission.makeUnsafe();
218
+ const cacheAgeVerdict = CacheAgeVerdicts.make(options.runId);
219
+ const rebaseLimit = nonNegativeSafeInteger("rebaseLimit", options.rebaseLimit ?? 3);
220
+ const scheduling = Scheduling.make(options.concurrency);
221
+ // Capture before the first async boundary. Callers can retain and mutate
222
+ // their options, but cannot change this scheduler's identity after admission.
223
+ const capturedEnvironment = Result.try(() => Schema.decodeUnknownSync(Schema.UndefinedOr(StepKey.EnvironmentIdentity))(options.environment, { onExcessProperty: "error" }));
224
+ // Every scheduler record addresses the run's root lineage, so a frame can
225
+ // reach it (`apps/site/src/content/docs/docs/concepts/time-travel.mdx`).
226
+ const lineageId = FlowEngine.Lineage.root(options.runId);
227
+ const source = (suffix) => ({ runId: options.runId, sourceId: `${options.sourceId}/${suffix}`, lineageId });
228
+ /**
229
+ * Scheduler records take the journal's durable, owner-fenced channel: a plan
230
+ * digest binds an approval, so it may never ride the lossy queue. A zombie
231
+ * that lost the run self-interrupts on `fence_lost`, exactly as
232
+ * `internal/ActionPersistence` does — a scheduler that kept dispatching
233
+ * after losing ownership is the failure mode fencing exists to prevent.
234
+ */
235
+ const emit = (record) => Effect.flatMap(Journal.Journal, (journal) => journal.emitDurable(record, options.owner)).pipe(Effect.catch((error) => error.code === "fence_lost"
236
+ ? Effect.interrupt
237
+ : Effect.fail(storeFailure("the scheduler could not journal a record")(error))));
238
+ const atomically = (message, effect) => Effect.flatMap(Journal.Journal, (journal) => journal.transact(effect)).pipe(Effect.mapError((error) => error instanceof SchedulerError ? error : storeFailure(message)(error)));
239
+ const verifyPlan = (candidate) => Plan.verify(candidate).pipe(Effect.mapError((cause) => new SchedulerError({ code: "invalid_plan", message: "the scheduler requires a verified plan", cause })));
240
+ const record = Effect.fn("PlanScheduler.record")((candidate) => Effect.gen(function* () {
241
+ const plan = yield* verifyPlan(candidate);
242
+ yield* Effect.annotateCurrentSpan({
243
+ runId: options.runId,
244
+ planId: plan.planId,
245
+ digest: plan.digest,
246
+ generation: plan.generation
247
+ });
248
+ const store = yield* PlanStore.PlanStore;
249
+ const now = yield* Clock.currentTimeMillis.pipe(Effect.map(Math.floor));
250
+ const outcome = yield* atomically("could not atomically record the plan", Effect.gen(function* () {
251
+ const recorded = yield* store.record(plan, now).pipe(Effect.mapError(storeFailure("could not record the plan")));
252
+ yield* emit(JournalRecords.planRecorded(source(`plan/${plan.planId}`), {
253
+ planId: plan.planId,
254
+ flow: plan.flow,
255
+ digest: plan.digest,
256
+ baseDigest: plan.baseDigest,
257
+ generation: plan.generation,
258
+ nodes: plan.nodes.length,
259
+ outcome: recorded._tag,
260
+ // The graph itself, beside the count it has always carried. A
261
+ // reader that only knows how MANY nodes ran cannot show which
262
+ // ones, and the count stays because the CLI's run progress reads
263
+ // it as a number.
264
+ graph: { nodes: plan.nodes.map(nodeSummary) }
265
+ }));
266
+ return recorded;
267
+ }));
268
+ yield* Effect.annotateCurrentSpan({ outcome: outcome._tag });
269
+ return outcome;
270
+ }));
271
+ const append = Effect.fn("PlanScheduler.append")((candidate) => Effect.gen(function* () {
272
+ const plan = yield* verifyPlan(candidate);
273
+ yield* Effect.annotateCurrentSpan({
274
+ runId: options.runId,
275
+ planId: plan.planId,
276
+ digest: plan.digest,
277
+ generation: plan.generation
278
+ });
279
+ const store = yield* PlanStore.PlanStore;
280
+ yield* atomically("could not atomically append the subgraph", Effect.gen(function* () {
281
+ yield* store.append(plan).pipe(Effect.mapError(storeFailure("could not append the subgraph")));
282
+ yield* emit(JournalRecords.subgraphAppended(source(`plan/${plan.planId}/${plan.generation}`), {
283
+ planId: plan.planId,
284
+ digest: plan.digest,
285
+ baseDigest: plan.baseDigest,
286
+ generation: plan.generation,
287
+ nodeIds: Plan.generationNodes(plan).map((node) => node.id),
288
+ graph: { nodes: Plan.generationNodes(plan).map(nodeSummary) }
289
+ }));
290
+ }));
291
+ yield* Effect.annotateCurrentSpan({ outcome: "appended" });
292
+ }));
293
+ const run = Effect.fn("PlanScheduler.run")((candidate) => Effect.gen(function* () {
294
+ if (Result.isFailure(capturedEnvironment)) {
295
+ return yield* Effect.fail(new SchedulerError({
296
+ code: "key_uncomputable",
297
+ message: "the scheduler requires a valid execution environment identity"
298
+ }));
299
+ }
300
+ const environment = capturedEnvironment.success;
301
+ const environmentDigest = yield* StepKey.environmentIdentity(environment).pipe(Effect.mapError((cause) => new SchedulerError({ code: "key_uncomputable", message: "could not bind the execution environment", cause })));
302
+ const initial = yield* verifyPlan(candidate);
303
+ yield* Effect.annotateCurrentSpan({
304
+ runId: options.runId,
305
+ planId: initial.planId,
306
+ digest: initial.digest,
307
+ nodes: initial.nodes.length
308
+ });
309
+ const boundaries = yield* StepBoundary.StepBoundary;
310
+ const fileSystem = yield* Effect.serviceOption(FileSystem.FileSystem);
311
+ const executor = yield* NodeExecutor;
312
+ const journal = yield* Journal.Journal;
313
+ const inputStore = yield* PlanInputStore.PlanInputStore;
314
+ const mergeStore = yield* PlanMergeStore.PlanMergeStore;
315
+ const mergeIdentity = {
316
+ runId: options.runId,
317
+ planId: initial.planId,
318
+ baseDigest: initial.baseDigest,
319
+ environmentDigest
320
+ };
321
+ const mergeFailure = (cause) => cause.code === "fence_lost"
322
+ ? Effect.interrupt :
323
+ Effect.fail(storeFailure("could not recover or persist the plan's merge decisions")(cause));
324
+ const recoveredMerges = yield* mergeStore.list(mergeIdentity, options.owner).pipe(Effect.catch(mergeFailure));
325
+ const reconciler = Option.getOrElse(yield* Effect.serviceOption(Reconciliation.Reconciliation), Reconciliation.makeDefault);
326
+ const selector = Option.getOrElse(yield* Effect.serviceOption(Selection.Selection), Selection.makeNoop);
327
+ // A verifier composes the scheduler replay-only, as it does the engine:
328
+ // a recorded node replays and a node that would run its body stops.
329
+ const replayOnly = Option.getOrUndefined(yield* Effect.serviceOption(ReplayOnly.ReplayOnly));
330
+ yield* Effect.logDebug("scheduler run started", {
331
+ digest: initial.digest,
332
+ nodes: initial.nodes.length
333
+ });
334
+ // Only a coordinator failure makes interrupted siblings terminal here.
335
+ // Parking, external cancellation and fence loss retain their established
336
+ // recovery semantics. The flag is set before the child scope closes.
337
+ let abortedForFailure = false;
338
+ const cleanupErrors = [];
339
+ let plan = yield* PlanMerges.recover(initial, recoveredMerges).pipe(Effect.catch(mergeFailure));
340
+ const graph = RuntimeGraph.make(plan.nodes);
341
+ const states = graph.states;
342
+ const results = new Map();
343
+ const digestMemo = StepKey.makeDigestMemo();
344
+ const verdicts = [];
345
+ const appended = [];
346
+ const digestToNode = new Map();
347
+ const deviationSignatures = new Map();
348
+ const writers = new Map();
349
+ const writerEntries = [];
350
+ const nodesById = new Map();
351
+ let cursor = undefined;
352
+ const events = yield* Queue.unbounded();
353
+ const stateOf = (node) => states.get(node.id);
354
+ /**
355
+ * Reconciliation's first declared owner of each path. Read version
356
+ * selection is different: only a reader's predecessors produce its
357
+ * inputs, never the reader itself or an explicitly later writer.
358
+ */
359
+ const indexWriters = (nodes) => {
360
+ for (const node of nodes) {
361
+ nodesById.set(node.id, node);
362
+ for (const entry of [...FileSet.expand(node.effects.writes), ...node.effects.removes ?? []]) {
363
+ writerEntries.push({ entry, nodeId: node.id });
364
+ if (typeof entry === "string" && !writers.has(entry)) {
365
+ writers.set(entry, node.id);
366
+ }
367
+ }
368
+ }
369
+ };
370
+ indexWriters(plan.nodes);
371
+ const writerFor = (path) => writers.get(path) ?? writerEntries.find(({ entry }) => FileSet.overlaps(entry, path))?.nodeId;
372
+ // One bounded traversal per observation/dispatch, not an eager matrix
373
+ // of every node's transitive ancestors. Shared ancestors are visited
374
+ // once, and the temporary set is released after this reader's work.
375
+ const writerScopesBefore = (node) => {
376
+ const scopes = [];
377
+ graph.visitAncestors(node, (predecessor) => {
378
+ scopes.push(...FileSet.expand(predecessor.effects.writes), ...predecessor.effects.removes ?? []);
379
+ });
380
+ return scopes;
381
+ };
382
+ const expandReads = (entries, what) => Effect.gen(function* () {
383
+ const expanded = [];
384
+ for (const entry of entries) {
385
+ if (typeof entry === "string") {
386
+ expanded.push({ entry, paths: [entry] });
387
+ continue;
388
+ }
389
+ if (Option.isNone(fileSystem)) {
390
+ return yield* Effect.fail(new SchedulerError({
391
+ code: "boundary_unavailable",
392
+ message: `the host cannot expand ${what} without a FileSystem`
393
+ }));
394
+ }
395
+ // Through `FileEnumeration`, never the host `glob`: host results
396
+ // are absolute under the kernel FileSystem and skip dotfiles, so
397
+ // a workspace-relative pattern silently expanded to nothing.
398
+ const matches = yield* FileEnumeration.expandGlob(fileSystem.value, entry).pipe(Effect.mapError((cause) => new SchedulerError({
399
+ code: "boundary_unavailable",
400
+ message: `the host could not expand ${what}`,
401
+ cause
402
+ })));
403
+ expanded.push({ entry, paths: matches });
404
+ }
405
+ return expanded;
406
+ });
407
+ const prepare = (paths, what) => boundaries.prepare({
408
+ readSet: [...new Set(paths)].sort().map((path) => ({ path, digest: unmeasured })),
409
+ writeSet: [],
410
+ boundaryMode: "hard"
411
+ }).pipe(Effect.mapError((cause) => new SchedulerError({
412
+ code: "boundary_unavailable",
413
+ message: `the host could not measure ${what}`,
414
+ cause
415
+ })));
416
+ const expandProducedMatches = (glob, writerScopes, what) => Effect.gen(function* () {
417
+ const scopes = writerScopes.filter((entry) => FileSet.overlaps(glob, entry));
418
+ if (scopes.length === 0)
419
+ return [];
420
+ if (Option.isNone(fileSystem)) {
421
+ return yield* Effect.fail(new SchedulerError({
422
+ code: "boundary_unavailable",
423
+ message: `the host cannot expand ${what} without a FileSystem`
424
+ }));
425
+ }
426
+ const paths = new Set();
427
+ for (const entry of scopes) {
428
+ if (typeof entry === "string") {
429
+ // One host call: `stat` reports both whether the producer's
430
+ // output is there yet and what kind of thing it is, so the
431
+ // `exists` probe that used to precede it only doubled the cost.
432
+ // On the confined host each call is one CPython fork
433
+ // (`@smthrs/platform-node/AtomicFileSystem`).
434
+ const info = yield* fileSystem.value.stat(entry).pipe(Effect.catchReason("PlatformError", "NotFound", () => Effect.succeed(undefined)), Effect.mapError((cause) => new SchedulerError({
435
+ code: "boundary_unavailable",
436
+ message: `the host could not expand ${what}`,
437
+ cause
438
+ })));
439
+ // Exact writer declarations name files; directory outputs use
440
+ // `TreeArtifact`, and only files are members of a read glob. A
441
+ // producer that has not written yet is simply not a candidate.
442
+ if (info?.type === "File")
443
+ paths.add(entry);
444
+ continue;
445
+ }
446
+ const matches = FileSet.isGlob(entry)
447
+ ? yield* FileEnumeration.expandGlob(fileSystem.value, entry).pipe(Effect.mapError((cause) => new SchedulerError({
448
+ code: "boundary_unavailable",
449
+ message: `the host could not expand ${what}`,
450
+ cause
451
+ })))
452
+ : yield* FileEnumeration.filesUnder(fileSystem.value, entry.path).pipe(Effect.mapError((cause) => new SchedulerError({
453
+ code: "boundary_unavailable",
454
+ message: `the host could not expand ${what}`,
455
+ cause
456
+ })));
457
+ for (const path of matches) {
458
+ if (FileSet.matchesGlob(glob, path))
459
+ paths.add(path);
460
+ }
461
+ }
462
+ return [...paths].sort();
463
+ });
464
+ // A read declaration is observed only when its node enters this run:
465
+ // generation zero here, or one newly appended generation below. Paths
466
+ // already pinned by an earlier declaration reuse that digest; measuring
467
+ // them again would tear the run. A new source path is measured now,
468
+ // which is its first observation in this run.
469
+ const pinned = new Map();
470
+ const observedReads = new Map();
471
+ const inputFailure = (cause) => cause.code === "fence_lost"
472
+ ? Effect.interrupt
473
+ : Effect.fail(storeFailure("could not recover or persist the plan's source observations")(cause));
474
+ const observeReads = (nodes, generation, what, commit) => Effect.gen(function* () {
475
+ const address = {
476
+ runId: options.runId,
477
+ planId: initial.planId,
478
+ baseDigest: initial.baseDigest,
479
+ environmentDigest,
480
+ generation
481
+ };
482
+ const stored = yield* inputStore.get(address, options.owner).pipe(Effect.catch(inputFailure));
483
+ let snapshot;
484
+ if (Option.isSome(stored)) {
485
+ snapshot = stored.value;
486
+ }
487
+ else {
488
+ const unpinned = new Set();
489
+ const observedNodes = [];
490
+ for (const node of nodes) {
491
+ const observed = [];
492
+ const reads = FileSet.expandReads(node.effects.reads);
493
+ const writerScopes = reads.length === 0 ? [] : writerScopesBefore(node);
494
+ for (const { entry, paths } of yield* expandReads(reads, what)) {
495
+ const sourcePaths = paths.filter((path) => !writerScopes.some((scope) => FileSet.overlaps(scope, path)));
496
+ for (const path of sourcePaths) {
497
+ if (!pinned.has(path))
498
+ unpinned.add(path);
499
+ }
500
+ observed.push({ entry, sourcePaths });
501
+ }
502
+ observedNodes.push({ id: node.id, key: node.key, reads: observed });
503
+ }
504
+ const pins = unpinned.size === 0 ? [] : (yield* prepare([...unpinned], what)).readSnapshot;
505
+ const measured = {
506
+ version: 1,
507
+ generation,
508
+ nodes: observedNodes,
509
+ pins
510
+ };
511
+ yield* PlanInputs.validate(measured, nodes, pinned, writerScopesBefore).pipe(Effect.catch(inputFailure));
512
+ snapshot = commit === undefined
513
+ ? yield* inputStore.record(address, measured, options.owner).pipe(Effect.catch(inputFailure))
514
+ : measured;
515
+ }
516
+ if (commit !== undefined)
517
+ snapshot = yield* commit(snapshot);
518
+ // Do not publish speculative measurements. A competing observation
519
+ // wins durably, and every recovered declaration must still describe
520
+ // this verified plan before it can influence an execution key.
521
+ const nextPins = yield* PlanInputs.validate(snapshot, nodes, pinned, writerScopesBefore).pipe(Effect.catch(inputFailure));
522
+ for (const node of snapshot.nodes)
523
+ observedReads.set(node.id, node.reads);
524
+ for (const [path, digest] of nextPins)
525
+ pinned.set(path, digest);
526
+ });
527
+ // Recover each generation before any dispatch. Existing observations
528
+ // never enumerate or measure the host again, even after process restart.
529
+ for (let generation = 0; generation <= plan.generation; generation++) {
530
+ yield* observeReads(plan.nodes.filter((node) => node.generation === generation), generation, "the plan's source inputs");
531
+ }
532
+ // A merge intent is authoritative scheduler state, not a failed-action
533
+ // cache entry or a convention inferred from an arbitrary node's body.
534
+ for (const { intent } of recoveredMerges) {
535
+ const state = stateOf(nodesById.get(intent.nodeId));
536
+ graph.stage(intent.nodeId, "skipped");
537
+ state.dispatchKey = intent.dispatchKey;
538
+ state.attempts = intent.attempts;
539
+ state.rebases = intent.rebases;
540
+ }
541
+ graph.reconcile();
542
+ const measure = (node) => Effect.gen(function* () {
543
+ const measured = new Map();
544
+ const produced = new Set();
545
+ const observed = observedReads.get(node.id);
546
+ const writerScopes = observed.length === 0 ? [] : writerScopesBefore(node);
547
+ for (const read of observed) {
548
+ if (typeof read.entry === "string") {
549
+ if (read.sourcePaths.length === 0)
550
+ produced.add(read.entry);
551
+ else
552
+ measured.set(read.entry, pinned.get(read.entry));
553
+ continue;
554
+ }
555
+ for (const path of read.sourcePaths)
556
+ measured.set(path, pinned.get(path));
557
+ // A glob's source membership is frozen above. Dispatch may only
558
+ // add paths derived from preceding writer scopes. Neither an
559
+ // unproduced arrival nor a future writer widens the source world.
560
+ for (const path of yield* expandProducedMatches(read.entry, writerScopes, `the inputs of ${node.id}`)) {
561
+ produced.add(path);
562
+ }
563
+ }
564
+ if (produced.size > 0) {
565
+ // Produced paths are our own outputs, so measuring them once their
566
+ // producer has settled is not re-observing the world.
567
+ const prepared = yield* prepare([...produced], `the inputs of ${node.id}`);
568
+ for (const entry of prepared.readSnapshot)
569
+ measured.set(entry.path, entry.digest);
570
+ }
571
+ return {
572
+ readSet: [...measured].sort(([left], [right]) => compareText(left, right)).map(([path, digest]) => ({
573
+ path,
574
+ digest
575
+ })),
576
+ writeSet: FileSet.expand(node.effects.writes),
577
+ // Declared removals travel with the boundary: they are what makes
578
+ // an absent declared output legitimate rather than a defect.
579
+ ...(node.effects.removes === undefined ? {} : { removes: node.effects.removes }),
580
+ boundaryMode: node.effects.boundaryMode
581
+ };
582
+ });
583
+ /**
584
+ * Non-sealed work uses a stable run-local structural scope: it replays
585
+ * durable attempts but never reuses an effect from another invocation.
586
+ * For sealed work:
587
+ *
588
+ * The key a dispatch is recorded under: the node's own declaration
589
+ * folded with the CONTENT of everything it consumes — the digests the
590
+ * host just measured for its files, and the digest of each upstream
591
+ * node's settled output value.
592
+ *
593
+ * Not the plan key. That key folds every upstream key transitively, so
594
+ * an edit anywhere upstream re-ran everything below it even when the
595
+ * edited node's output value was byte-identical. Bazel's
596
+ * `ActionCacheChecker` stops invalidation at unchanged content, and
597
+ * `StepKey.dispatchIdentity` is how this does.
598
+ *
599
+ * The plan key alone could never have been it either: two runs whose
600
+ * input files differ declare the same graph, and serving one the other's
601
+ * result is exactly the staleness the boundary exists to prevent.
602
+ */
603
+ const dispatchKeyFor = (node, boundary, settledResults) => (node.material.kind === "sealed" ?
604
+ StepKey.dispatchIdentity({
605
+ material: node.material,
606
+ results: Object.fromEntries(node.material.inputs.flatMap((input) => input._tag === "Ref" ? [[input.from, settledResults.get(input.from)]] : [])),
607
+ digestMemo,
608
+ environment,
609
+ hermetic: {
610
+ ...boundary,
611
+ readSet: StepBoundary.exactReads(boundary)
612
+ }
613
+ }) :
614
+ StepKey.ordinal({
615
+ runId: options.runId,
616
+ // Stable structural scope, never admission order. The declaration
617
+ // fingerprint prevents a changed plan from reusing an old attempt.
618
+ parentScope: JSON.stringify(["plan-node/v1", initial.planId, node.id, node.key]),
619
+ ordinal: 0,
620
+ tier: node.material.kind
621
+ })).pipe(
622
+ /* v8 ignore next 3 -- verified plans have serializable material, admission resolves every dependency, and successful upstream values already crossed durable serialization; key derivation still exposes its honest failure channel */
623
+ Effect.mapError((cause) => new SchedulerError({ code: "key_uncomputable", message: `could not key ${node.id}`, cause })));
624
+ const runtimeStrategyOf = (node) => node.conflicts.some((conflict) => conflict.runtime === "stop-merge") ? "stop-merge" : node.runtime;
625
+ const markSettled = (node, outcome) => {
626
+ graph.stage(node.id, outcome);
627
+ };
628
+ const emitSettlement = (node, sourceSeq) => Effect.gen(function* () {
629
+ const state = stateOf(node);
630
+ const action = actionOf(node);
631
+ yield* emit(JournalRecords.nodeSettled({ ...source(`node/${node.id}/settled`), sourceSeq }, {
632
+ planId: plan.planId,
633
+ nodeId: node.id,
634
+ planKey: node.key,
635
+ dispatchKey: state.dispatchKey,
636
+ outcome: state.outcome,
637
+ attempts: state.attempts,
638
+ rebases: state.rebases,
639
+ ...(action === undefined ? {} : { action })
640
+ }));
641
+ yield* Metric.update(EngineStoreMetrics.node[state.outcome], 1);
642
+ });
643
+ const settle = (node, outcome) => {
644
+ markSettled(node, outcome);
645
+ graph.reconcile();
646
+ return emitSettlement(node);
647
+ };
648
+ const applyVerdict = (nodeId, verdict, trigger) => Effect.gen(function* () {
649
+ verdicts.push({ nodeId, verdict });
650
+ yield* emit(JournalRecords.nodeReconciled(source(`node/${nodeId}/reconciled/${verdicts.length}`), {
651
+ planId: plan.planId,
652
+ nodeId,
653
+ trigger,
654
+ verdict
655
+ }));
656
+ if (verdict._tag === "Fail") {
657
+ // The scheduler chooses the node it asks about, so a verdict always
658
+ // names one it is tracking.
659
+ graph.stage(nodeId, "failed");
660
+ results.delete(nodeId);
661
+ return;
662
+ }
663
+ if (verdict._tag === "Reorder") {
664
+ // Re-plan with the discovered dependency made explicit. It binds
665
+ // work that has not dispatched yet — the deviating node already
666
+ // ran, and rewriting history is what append-only forbids.
667
+ // Persisting the edge is the caller's next elaboration; the
668
+ // verdict is journaled so it can be.
669
+ graph.reorder(nodeId, verdict.dependsOn);
670
+ }
671
+ // `FactorOut` needs no graph surgery: two identical extracted steps
672
+ // collapse to one key by themselves, so the second is a `clean`.
673
+ });
674
+ const dispatch = Effect.fn("PlanScheduler.dispatch")(function* (node, start) {
675
+ return yield* Effect.gen(function* () {
676
+ yield* Effect.annotateCurrentSpan({
677
+ runId: options.runId,
678
+ planId: plan.planId,
679
+ nodeId: node.id,
680
+ kind: node.kind,
681
+ planKey: node.key
682
+ });
683
+ // Attempt bookkeeping is local to this fiber. The coordinator owns
684
+ // the durable scheduler state and applies this progress only when it
685
+ // processes the terminal event.
686
+ let dispatchKey = start.dispatchKey;
687
+ let attempts = start.attempts;
688
+ let rebases = start.rebases;
689
+ while (true) {
690
+ const boundary = yield* measure(node);
691
+ const measuredKey = yield* dispatchKeyFor(node, boundary, start.results);
692
+ if (dispatchKey !== "" && dispatchKey !== measuredKey) {
693
+ yield* emit(JournalRecords.nodeInvalidated(source(`node/${node.id}/${attempts}/invalidated`), {
694
+ planId: plan.planId,
695
+ nodeId: node.id,
696
+ planKey: node.key,
697
+ from: dispatchKey,
698
+ to: measuredKey,
699
+ reason: "measured-inputs-changed"
700
+ }));
701
+ }
702
+ dispatchKey = measuredKey;
703
+ attempts = attempts + 1;
704
+ yield* Effect.annotateCurrentSpan({ dispatchKey, attempt: attempts });
705
+ const action = actionOf(node);
706
+ yield* emit(JournalRecords.nodeScheduled(source(`node/${node.id}/${attempts}`), {
707
+ planId: plan.planId,
708
+ nodeId: node.id,
709
+ kind: node.kind,
710
+ planKey: node.key,
711
+ dispatchKey,
712
+ attempt: attempts,
713
+ priority: node.priority,
714
+ waited: start.waited,
715
+ ...(action === undefined ? {} : { action })
716
+ }));
717
+ const dispatchDigest = yield* Effect.orDie(digestOf(dispatchKey));
718
+ yield* Queue.offer(events, { _tag: "AttemptKeyed", nodeId: node.id, digest: dispatchDigest });
719
+ const ran = yield* Ref.make(false);
720
+ const exit = yield* ActionPersistence.make({
721
+ runId: options.runId,
722
+ owner: options.owner,
723
+ admission,
724
+ cacheAgeVerdict,
725
+ replayOnly,
726
+ sourceId: `${options.sourceId}/node/${node.id}`,
727
+ execute: () => Ref.set(ran, true).pipe(Effect.andThen(executor.execute({ node, attempt: attempts, boundary, inputs: start.inputs })))
728
+ })({
729
+ action: {},
730
+ attempt: attempts,
731
+ key: dispatchKey,
732
+ tier: node.material.kind,
733
+ nondeterministic: node.material.nondeterministic,
734
+ metadata: boundary
735
+ }).pipe(Effect.onInterrupt(() => abortedForFailure
736
+ ? atomically("could not settle a sibling aborted by scheduler failure", Effect.gen(function* () {
737
+ const store = yield* AttemptStore.AttemptStore;
738
+ const finishedAtMs = yield* Clock.currentTimeMillis.pipe(Effect.map(Math.floor));
739
+ const identity = { runId: options.runId, stepKeyDigest: dispatchDigest, attempt: attempts };
740
+ const finished = yield* store.finish({
741
+ ...identity,
742
+ state: "failed",
743
+ finishedAtMs,
744
+ error: { code: "scheduler_aborted", message: "A scheduler failure interrupted this attempt" }
745
+ }, options.owner);
746
+ // A terminal attempt or a replacement owner already decides
747
+ // the row. Never overwrite it or emit a contradictory fact.
748
+ if (finished._tag === "Finished") {
749
+ yield* emit(JournalRecords.attemptFinished(source(`node/${node.id}/${attempts}/aborted`), {
750
+ ...identity,
751
+ state: "failed",
752
+ reason: "scheduler_aborted"
753
+ }));
754
+ }
755
+ })).pipe(Effect.catch((cause) => Effect.sync(() => {
756
+ cleanupErrors.push(cause);
757
+ })))
758
+ : Effect.void), Effect.exit);
759
+ if (Exit.isSuccess(exit)) {
760
+ return {
761
+ outcome: (yield* Ref.get(ran)) ? "built" : "clean",
762
+ result: exit.value,
763
+ dispatchKey,
764
+ attempts,
765
+ rebases
766
+ };
767
+ }
768
+ // Losing a fence self-interrupts `ActionPersistence`. An
769
+ // interrupted dispatch is the run losing ownership, never a node
770
+ // failure that the scheduler may report and continue past.
771
+ if (Cause.hasInterrupts(exit.cause))
772
+ return yield* Effect.interrupt;
773
+ // The generic executor supplies no irreversible idempotency or
774
+ // reconciliation contract. A conflict is not proof the effect
775
+ // never happened; neither a retry nor a freshly keyed merge may
776
+ // blindly execute more work after that uncertain result.
777
+ if (!isConflict(exit.cause) || node.material.kind === "irreversible") {
778
+ return { outcome: "failed", dispatchKey, attempts, rebases };
779
+ }
780
+ const strategy = runtimeStrategyOf(node);
781
+ if (strategy === "delay-rebase" && rebases < rebaseLimit) {
782
+ // Hold the dependents — they are not ready while this node is in
783
+ // flight — and re-execute against the newly recorded base. The
784
+ // next turn of the loop re-measures, which re-keys, which is a
785
+ // new attempt rather than a retry of the old identity.
786
+ rebases = rebases + 1;
787
+ continue;
788
+ }
789
+ return { outcome: "conflicted", strategy, dispatchKey, attempts, rebases };
790
+ }
791
+ }).pipe(Effect.tap((result) => Effect.annotateCurrentSpan({ outcome: result.outcome })));
792
+ });
793
+ /**
794
+ * `stop-merge`: the losing action is stopped and both lanes are routed
795
+ * through an explicit merge node appended to the SAME plan, as an
796
+ * ordinary elaboration. The merge critical section uses this module's
797
+ * restart-or-fail landing contract, so the merge node carries no rebase
798
+ * budget of its own: it lands, or the run has a failed node. There is no
799
+ * worktree-lane surface; that design was removed.
800
+ */
801
+ const appendMerge = (intent) => Effect.gen(function* () {
802
+ const node = yield* PlanMerges.validateIntent(plan, intent).pipe(Effect.catch(mergeFailure));
803
+ const winners = intent.peers.filter((id) => results.has(id));
804
+ const mergeId = PlanMerges.allocateId(plan, node.id);
805
+ const parentDigest = plan.digest;
806
+ const grown = yield* Plan.append(plan, [PlanMerges.draft(node, mergeId, winners)]).pipe(Effect.mapError((cause) => new SchedulerError({
807
+ code: "elaboration_failed",
808
+ message: `could not append the merge node for ${node.id}`,
809
+ cause
810
+ })));
811
+ // `appendMerge` copies the stopped node's effects byte-for-byte, so
812
+ // re-indexing adds no new writer coverage and cannot turn an
813
+ // already-pinned source path into a producer. The new generation's
814
+ // read declarations have not themselves been observed, however:
815
+ // expand them once now and pin only source paths this run has never
816
+ // measured. Existing pins are always reused.
817
+ yield* observeReads(Plan.generationNodes(grown), grown.generation, `generation ${grown.generation}'s source inputs`, (snapshot) => atomically("could not atomically commit the merge extension", Effect.gen(function* () {
818
+ const recorded = yield* inputStore.record({ ...mergeIdentity, generation: grown.generation }, snapshot, options.owner)
819
+ .pipe(Effect.catch(inputFailure));
820
+ yield* append(grown);
821
+ yield* mergeStore.complete(mergeIdentity, intent.nodeId, {
822
+ version: 1,
823
+ generation: grown.generation,
824
+ parentDigest,
825
+ planDigest: grown.digest,
826
+ mergeId,
827
+ mergeKey: Plan.generationNodes(grown)[0].key,
828
+ winners
829
+ }, options.owner).pipe(Effect.catch(mergeFailure));
830
+ return recorded;
831
+ })));
832
+ // No asynchronous boundary may expose only part of this admission.
833
+ // Frozen generations preserve the indexed prefix and its state.
834
+ const suffix = Plan.generationNodes(grown);
835
+ graph.append(suffix);
836
+ plan = grown;
837
+ indexWriters(suffix);
838
+ appended.push(mergeId);
839
+ });
840
+ const pendingSettlements = [];
841
+ const registerAttempt = (event) => {
842
+ const dispatchedUnder = digestToNode.get(event.digest);
843
+ if (dispatchedUnder === undefined) {
844
+ digestToNode.set(event.digest, [event.nodeId]);
845
+ }
846
+ else if (!dispatchedUnder.includes(event.nodeId)) {
847
+ digestToNode.set(event.digest, [...dispatchedUnder, event.nodeId]);
848
+ }
849
+ };
850
+ /**
851
+ * Absorbs every report already offered without processing another node's
852
+ * settlement. Attempt-key reports update attribution state immediately;
853
+ * terminal reports stay ordered in `pendingSettlements` for the one-at-a-
854
+ * time coordinator. A deviation can appear in a journal page only after
855
+ * its attempt-key report was offered, so calling this after each page
856
+ * closes the journal/queue observation race without a shared mutable map.
857
+ */
858
+ const drainReportedEvents = Effect.gen(function* () {
859
+ while (true) {
860
+ const next = yield* Queue.poll(events);
861
+ if (Option.isNone(next))
862
+ return;
863
+ if (next.value._tag === "AttemptKeyed")
864
+ registerAttempt(next.value);
865
+ else
866
+ pendingSettlements.push(next.value);
867
+ }
868
+ });
869
+ const nextSettlement = Effect.gen(function* () {
870
+ const pending = pendingSettlements.shift();
871
+ if (pending !== undefined)
872
+ return pending;
873
+ while (true) {
874
+ const event = yield* Queue.take(events);
875
+ if (event._tag === "DispatchSettled")
876
+ return event;
877
+ registerAttempt(event);
878
+ }
879
+ });
880
+ /**
881
+ * The first consumer `flows.engine.expected-set-deviation` has ever had.
882
+ * The events are read from the journal rather than from the attempt row
883
+ * on purpose: a deviation is a durable, replayable fact, and consuming
884
+ * the fact keeps this seam usable by anything else that reads the
885
+ * journal.
886
+ *
887
+ * Two properties the drain owes the reconciler, both of them about not
888
+ * letting arrival order decide a verdict:
889
+ *
890
+ * 1. **Attribute the whole page before judging any of it.** Deviating on
891
+ * the same paths is a *symmetric* fact — two steps that both ran
892
+ * `npm install` — so registering each signature as the entry was
893
+ * judged answered the same situation two different ways: the first
894
+ * node saw no peer and was failed, and only the second was factored
895
+ * out. Every deviation on the page is attributed first, so both sides
896
+ * of a pair see each other.
897
+ * 2. **Drain the journal, not one page of it.** Concurrent dispatches can
898
+ * journal more records than one page holds, and the final completion
899
+ * is the one that matters: nothing follows it to pick up what a single
900
+ * page left behind, so a deviation past the cursor would never reach
901
+ * the seam.
902
+ */
903
+ const pendingDeviations = [];
904
+ const drainDeviations = Effect.gen(function* () {
905
+ let hasMore = true;
906
+ while (hasMore) {
907
+ const page = yield* journal.entries({
908
+ runId: options.runId,
909
+ ...(cursor === undefined ? {} : { after: cursor }),
910
+ limit: 512
911
+ }).pipe(Effect.mapError(storeFailure("could not read the run's journal")));
912
+ // Every deviation in this page causally follows its attempt-key
913
+ // report. Absorb those reports now, after the journal read, so even
914
+ // an in-flight sibling can be attributed without dispatch fibers
915
+ // mutating coordinator state.
916
+ yield* drainReportedEvents;
917
+ const attributed = [];
918
+ for (const entry of page.entries) {
919
+ cursor = entry.seq;
920
+ if (entry.eventType !== "flows.engine.expected-set-deviation")
921
+ continue;
922
+ const payload = decodeDeviation(entry.payload);
923
+ if (Option.isNone(payload))
924
+ continue;
925
+ const nodeIds = digestToNode.get(payload.value.stepKeyDigest);
926
+ if (nodeIds === undefined)
927
+ continue;
928
+ // The attempt belongs to an executing node by construction. If
929
+ // its built settlement is absent from current bookkeeping — the
930
+ // record arrived first, or is being durably replayed into an
931
+ // all-clean invocation — preserve first dispatch order.
932
+ const nodeId = nodeIds.find((candidate) => states.get(candidate).outcome === "built") ?? nodeIds[0];
933
+ const signature = JSON.stringify([
934
+ "expected-set-deviation/v1",
935
+ [...new Set(payload.value.paths)].sort(compareText)
936
+ ]);
937
+ deviationSignatures.set(nodeId, signature);
938
+ attributed.push({ nodeId, signature, payload: payload.value });
939
+ }
940
+ pendingDeviations.push(...attributed);
941
+ for (let index = 0; index < pendingDeviations.length;) {
942
+ const { nodeId, payload, signature } = pendingDeviations[index];
943
+ // A concurrent dispatch can durably journal its deviation before
944
+ // its terminal event reaches the head of the coordinator queue.
945
+ // Its signature participates in symmetric attribution now, but
946
+ // its verdict waits until that node's settlement is processed.
947
+ if (states.get(nodeId)?.status !== "settled") {
948
+ index = index + 1;
949
+ continue;
950
+ }
951
+ const alsoDeviatedBy = [...deviationSignatures.entries()]
952
+ .filter(([other, otherSignature]) => other !== nodeId && otherSignature === signature)
953
+ .map(([other]) => other);
954
+ // Null prototype: a reconciler's lookup of a path named `toString` must miss.
955
+ const declaredBy = Object.assign(Object.create(null), Object.fromEntries(payload.paths.flatMap((path) => {
956
+ const owner = writerFor(path);
957
+ return owner === undefined ? [] : [[path, owner]];
958
+ })));
959
+ const verdict = yield* reconciler.onDeviation({
960
+ nodeId,
961
+ keyDigest: payload.stepKeyDigest,
962
+ attempt: payload.attempt,
963
+ paths: payload.paths,
964
+ diffIdentity: payload.diffIdentity,
965
+ declaredBy,
966
+ alsoDeviatedBy
967
+ });
968
+ yield* applyVerdict(nodeId, verdict, "deviation");
969
+ pendingDeviations.splice(index, 1);
970
+ }
971
+ hasMore = page.hasMore;
972
+ }
973
+ });
974
+ /**
975
+ * The selection consult, once per run, against the initial plan and the
976
+ * pinned belief snapshot (`docs/guides/defer-work-with-selection.md`). Only sinks,
977
+ * nodes nothing in the plan depends on,
978
+ * are offered, because deferring a node something consumes would block
979
+ * or corrupt its consumers. A verdict may postpone or propose, never
980
+ * remove: `Admit` is a no-op, a `Defer` marks the sink for the loop
981
+ * below, a `Propose` is journaled and nothing more (v1 never
982
+ * auto-appends), and a Defer naming a non-sink — or a Propose naming
983
+ * anything the plan already accounts for, its flow included — is
984
+ * ignored and journaled as an inconsistency observation, against the
985
+ * same `present` set the layer was shown. The `full` override skips
986
+ * the consult entirely: nothing is deferred and nothing is proposed
987
+ * under it, and the override record is what makes that visible.
988
+ * Elaboration cannot
989
+ * invalidate the marks: an appended merge node depends only on nodes
990
+ * that produced results, and a deferred node never executes, so a
991
+ * deferred sink can never gain a dependent mid-run.
992
+ */
993
+ const deferrals = new Map();
994
+ if (options.selection?.full === true) {
995
+ yield* emit(JournalRecords.selectionOverridden(source("selection/override"), {
996
+ planId: plan.planId,
997
+ mode: "full"
998
+ }));
999
+ }
1000
+ else {
1001
+ const dependedOn = new Set(plan.nodes.flatMap((node) => node.dependsOn));
1002
+ const sinks = plan.nodes.filter((node) => !dependedOn.has(node.id));
1003
+ const present = new Set([plan.flow, ...plan.nodes.map((node) => node.id)]);
1004
+ const sinkIds = new Set(sinks.map((node) => node.id));
1005
+ const selected = yield* selector.select({
1006
+ changed: options.selection?.changed ?? [],
1007
+ sinks: sinks.map((node) => ({ nodeId: node.id, planKey: node.key })),
1008
+ present: [...present],
1009
+ beliefs: options.selection?.beliefs ?? { pinnedAtMs: 0, edges: [] },
1010
+ policy: options.selection?.policy ?? { deferBelow: 0 }
1011
+ });
1012
+ for (let index = 0; index < selected.length; index++) {
1013
+ const { nodeId, verdict } = selected[index];
1014
+ if (verdict._tag === "Admit")
1015
+ continue;
1016
+ if (verdict._tag === "Defer" && sinkIds.has(nodeId)) {
1017
+ deferrals.set(nodeId, { edge: verdict.edge, likelihood: verdict.likelihood });
1018
+ continue;
1019
+ }
1020
+ if (verdict._tag === "Propose" && !present.has(nodeId)) {
1021
+ yield* emit(JournalRecords.selectionProposed(source(`selection/proposed/${index}`), {
1022
+ planId: plan.planId,
1023
+ flow: verdict.flow,
1024
+ edge: verdict.edge,
1025
+ confidence: verdict.confidence
1026
+ }));
1027
+ continue;
1028
+ }
1029
+ yield* emit(JournalRecords.selectionInconsistent(source(`selection/inconsistent/${index}`), {
1030
+ planId: plan.planId,
1031
+ nodeId,
1032
+ verdict: verdict._tag,
1033
+ reason: verdict._tag === "Defer" ? "not-a-deferrable-sink" : "proposes-a-present-node"
1034
+ }));
1035
+ }
1036
+ }
1037
+ const passiveSettlements = Effect.gen(function* () {
1038
+ while (true) {
1039
+ const blocked = graph.blocked();
1040
+ // Halt, not continue-on-failure: a dependent of failed work never
1041
+ // dispatches. Repeating this pass makes the skip cascade settle in
1042
+ // dependency order before any newly exposed work is admitted.
1043
+ for (const node of blocked)
1044
+ yield* settle(node, "skipped");
1045
+ if (blocked.length > 0)
1046
+ continue;
1047
+ // A deferral is a postponement, never a removal, and it only takes
1048
+ // effect on work that was genuinely runnable: a marked sink whose
1049
+ // cone failed settled `skipped` above instead, because work that
1050
+ // could not have run is not a debt. The debt record precedes the
1051
+ // settlement so `Selection.debt` reads them in cause-then-effect
1052
+ // order.
1053
+ const ready = graph.ready();
1054
+ const postponed = ready.filter((node) => deferrals.has(node.id));
1055
+ for (const node of postponed) {
1056
+ const debt = deferrals.get(node.id);
1057
+ yield* emit(JournalRecords.selectionDeferred(source(`node/${node.id}/selection-deferred`), {
1058
+ planId: plan.planId,
1059
+ nodeId: node.id,
1060
+ planKey: node.key,
1061
+ edge: debt.edge,
1062
+ likelihood: debt.likelihood
1063
+ }));
1064
+ yield* settle(node, "deferred");
1065
+ }
1066
+ if (postponed.length > 0)
1067
+ continue;
1068
+ return ready;
1069
+ }
1070
+ });
1071
+ const dispatchStart = (node) => {
1072
+ const state = stateOf(node);
1073
+ const settledResults = new Map();
1074
+ const inputs = [];
1075
+ for (const input of node.material.inputs) {
1076
+ if (input._tag !== "Ref")
1077
+ continue;
1078
+ const value = results.get(input.from);
1079
+ settledResults.set(input.from, value);
1080
+ // Admission proved every dependency settled successfully; `settle`
1081
+ // records even an `undefined` result in the map, so every material
1082
+ // Ref has a value to project here.
1083
+ inputs.push({ from: input.from, path: input.path, value: StepKey.project(value, input.path) });
1084
+ }
1085
+ return {
1086
+ dispatchKey: state.dispatchKey,
1087
+ attempts: state.attempts,
1088
+ rebases: state.rebases,
1089
+ waited: state.waited,
1090
+ results: settledResults,
1091
+ inputs
1092
+ };
1093
+ };
1094
+ let admissions = 0;
1095
+ yield* Effect.scoped(Effect.gen(function* () {
1096
+ let inFlightSteps = 0;
1097
+ let inFlightAgents = 0;
1098
+ const pendingMerges = recoveredMerges
1099
+ .filter((decision) => decision.completion === undefined).map((decision) => decision.intent);
1100
+ const appendReadyMerges = Effect.gen(function* () {
1101
+ for (let index = 0; index < pendingMerges.length;) {
1102
+ const pending = pendingMerges[index];
1103
+ if (pending.peers.some((peer) => states.get(peer)?.status !== "settled")) {
1104
+ index = index + 1;
1105
+ continue;
1106
+ }
1107
+ yield* appendMerge(pending);
1108
+ pendingMerges.splice(index, 1);
1109
+ }
1110
+ });
1111
+ // Passive failure/selection propagation can settle the last peer of
1112
+ // a recovered intent without a dispatch event. Recheck merges until
1113
+ // neither propagation nor an append exposes more scheduling work.
1114
+ const advance = Effect.gen(function* () {
1115
+ while (true) {
1116
+ const ready = yield* passiveSettlements;
1117
+ const before = plan.generation;
1118
+ yield* appendReadyMerges;
1119
+ if (plan.generation === before)
1120
+ return ready;
1121
+ }
1122
+ });
1123
+ const admit = (ready) => Effect.gen(function* () {
1124
+ const decision = scheduling.admit(graph.candidates(ready), { steps: inFlightSteps, agents: inFlightAgents });
1125
+ const admitted = decision.admitted.map(({ node }) => node);
1126
+ // Event-driven aging: this admission pass considered every ready
1127
+ // node, and only capacity can leave one behind.
1128
+ for (const { node, waited } of decision.deferred) {
1129
+ stateOf(node).waited = waited;
1130
+ }
1131
+ if (admitted.length > 0) {
1132
+ admissions = admissions + 1;
1133
+ yield* Effect.annotateCurrentSpan({ admissions });
1134
+ yield* Metric.update(EngineStoreMetrics.schedulerAdmissions, 1);
1135
+ yield* Effect.logDebug("scheduler admission launched", {
1136
+ admission: admissions,
1137
+ ready: ready.length,
1138
+ admitted: admitted.length,
1139
+ agents: decision.agents,
1140
+ inFlightSteps,
1141
+ inFlightAgents
1142
+ });
1143
+ }
1144
+ const launches = admitted.map((node) => {
1145
+ const start = dispatchStart(node);
1146
+ graph.start(node.id);
1147
+ inFlightSteps = inFlightSteps + 1;
1148
+ if (node.kind === "agent")
1149
+ inFlightAgents = inFlightAgents + 1;
1150
+ return { node, start };
1151
+ });
1152
+ for (const { node, start } of launches) {
1153
+ yield* dispatch(node, start).pipe(Effect.trackDuration(EngineStoreMetrics.schedulerDispatchDuration), Effect.exit, Effect.flatMap((exit) => Queue.offer(events, { _tag: "DispatchSettled", node, exit })), Effect.asVoid, Effect.forkScoped({ startImmediately: true }));
1154
+ }
1155
+ });
1156
+ // Repair a settlement missing after a crash without appending the
1157
+ // same stopped decision again when its original record survived.
1158
+ for (const { intent } of recoveredMerges)
1159
+ yield* emitSettlement(nodesById.get(intent.nodeId), 0);
1160
+ yield* Effect.flatMap(advance, admit);
1161
+ while (graph.remaining > 0) {
1162
+ // Compiled plans are acyclic, inferred edges refuse cycle closure,
1163
+ // and discovered edges point only from undispatched nodes to the
1164
+ // already-settled node whose verdict added them, so pending work
1165
+ // with nothing in flight cannot have an empty ready set. If an
1166
+ // invariant breaks anyway, fail loudly: returning here would
1167
+ // report unsettled nodes with their initial outcome as success.
1168
+ /* v8 ignore next 7 -- unreachable while the invariants above hold */
1169
+ if (inFlightSteps === 0) {
1170
+ return yield* Effect.die(new Error(`PlanScheduler invariant broken: ${graph.remaining} nodes are pending and nothing is in flight`));
1171
+ }
1172
+ const event = yield* nextSettlement;
1173
+ if (Exit.isFailure(event.exit))
1174
+ return yield* Effect.failCause(event.exit.cause);
1175
+ const node = event.node;
1176
+ const result = event.exit.value;
1177
+ const state = stateOf(node);
1178
+ inFlightSteps = inFlightSteps - 1;
1179
+ if (node.kind === "agent")
1180
+ inFlightAgents = inFlightAgents - 1;
1181
+ state.dispatchKey = result.dispatchKey;
1182
+ state.attempts = result.attempts;
1183
+ state.rebases = result.rebases;
1184
+ switch (result.outcome) {
1185
+ case "built":
1186
+ case "clean":
1187
+ results.set(node.id, result.result);
1188
+ markSettled(node, result.outcome);
1189
+ break;
1190
+ case "failed":
1191
+ markSettled(node, "failed");
1192
+ break;
1193
+ case "conflicted": {
1194
+ if (result.strategy === "stop-merge") {
1195
+ const intent = yield* atomically("could not persist the stopped-attempt decision", Effect.gen(function* () {
1196
+ const intent = yield* mergeStore.intend(mergeIdentity, {
1197
+ version: 1,
1198
+ nodeId: node.id,
1199
+ nodeKey: node.key,
1200
+ dispatchKey: state.dispatchKey,
1201
+ attempts: state.attempts,
1202
+ rebases: state.rebases,
1203
+ peers: node.conflicts.map((conflict) => conflict.with)
1204
+ .filter((peer) => states.get(peer)?.status === "running" || results.has(peer))
1205
+ }, options.owner).pipe(Effect.catch(mergeFailure));
1206
+ yield* PlanMerges.validateIntent(plan, intent).pipe(Effect.catch(mergeFailure));
1207
+ return intent;
1208
+ }));
1209
+ markSettled(node, "skipped");
1210
+ // The former dispatch barrier guaranteed that every
1211
+ // conflicting sibling admitted beside this node had reported
1212
+ // its result before `appendMerge` selected winners. Preserve
1213
+ // that semantic boundary only for those already-running
1214
+ // peers; unrelated work never holds the merge cone.
1215
+ state.dispatchKey = intent.dispatchKey;
1216
+ state.attempts = intent.attempts;
1217
+ state.rebases = intent.rebases;
1218
+ pendingMerges.push(intent);
1219
+ break;
1220
+ }
1221
+ const verdict = yield* reconciler.onConflict({
1222
+ nodeId: node.id,
1223
+ keyDigest: state.dispatchKey,
1224
+ attempt: state.attempts,
1225
+ rebases: state.rebases,
1226
+ strategy: result.strategy,
1227
+ conflictsWith: node.conflicts.map((conflict) => conflict.with)
1228
+ });
1229
+ markSettled(node, "failed");
1230
+ yield* applyVerdict(node.id, verdict, "materialization-conflict");
1231
+ break;
1232
+ }
1233
+ }
1234
+ yield* appendReadyMerges;
1235
+ // The dispatch durably journalled every deviation before its event.
1236
+ // Apply those verdicts before consulting downstream readiness.
1237
+ yield* drainDeviations;
1238
+ // A dispatch outcome is provisional until its deviations have been
1239
+ // reconciled. Persist exactly one terminal fact, after a Fail
1240
+ // verdict has had the chance to replace built with failed.
1241
+ yield* emitSettlement(node);
1242
+ graph.reconcile();
1243
+ // Process terminal events already observed by the journal drain
1244
+ // before opening more permits. This preserves fail-fast behavior for
1245
+ // an already-failed sibling while still admitting immediately when
1246
+ // unrelated work is genuinely still in flight.
1247
+ const ready = yield* advance;
1248
+ if (pendingSettlements.length === 0)
1249
+ yield* admit(ready);
1250
+ }
1251
+ }).pipe(Effect.onError((cause) => Effect.sync(() => {
1252
+ abortedForFailure = cause.reasons.some((reason) => reason._tag === "Fail");
1253
+ })))).pipe(Effect.catch((error) => Effect.fail(cleanupErrors.length === 0 ? error : new SchedulerError({
1254
+ code: error.code,
1255
+ message: error.message,
1256
+ cause: error.cause,
1257
+ cleanupErrors
1258
+ }))));
1259
+ const settlements = plan.nodes.map((node) => {
1260
+ const state = stateOf(node);
1261
+ return {
1262
+ nodeId: node.id,
1263
+ planKey: node.key,
1264
+ dispatchKey: state.dispatchKey,
1265
+ outcome: state.outcome,
1266
+ attempts: state.attempts,
1267
+ rebases: state.rebases
1268
+ };
1269
+ });
1270
+ yield* Effect.logDebug("scheduler run completed", {
1271
+ admissions,
1272
+ built: settlements.filter((settlement) => settlement.outcome === "built").length,
1273
+ clean: settlements.filter((settlement) => settlement.outcome === "clean").length,
1274
+ failed: settlements.filter((settlement) => settlement.outcome === "failed").length,
1275
+ skipped: settlements.filter((settlement) => settlement.outcome === "skipped").length,
1276
+ deferred: settlements.filter((settlement) => settlement.outcome === "deferred").length
1277
+ });
1278
+ return {
1279
+ planId: plan.planId,
1280
+ digest: plan.digest,
1281
+ settlements,
1282
+ results: Object.fromEntries(results),
1283
+ verdicts,
1284
+ appended
1285
+ };
1286
+ }).pipe(Effect.annotateSpans({ runId: options.runId }), Effect.annotateLogs({ runId: options.runId }), Effect.onExit((exit) => Effect.annotateCurrentSpan({ outcome: EngineStoreMetrics.exitTag(exit).toLowerCase() }))));
1287
+ return { record, append, run };
1288
+ };
1289
+ /**
1290
+ * Provides a scheduler bound to one run.
1291
+ *
1292
+ * @since 0.1.0
1293
+ * @category layers
1294
+ */
1295
+ export const layer = (options) => Layer.succeed(PlanScheduler, make(options));
1296
+ /**
1297
+ * The recertification driver: re-drives a compiled plan under a fresh,
1298
+ * caller-supplied run with the `full` selection override — guess-free by
1299
+ * construction — then reports the deferring run's remaining debt via
1300
+ * `Selection.debt(deferringRunId, { repaidBy: [options.runId] })`.
1301
+ *
1302
+ * The design draft placed this beside the other Selection helpers; it lives
1303
+ * here because it constructs a scheduler, and `Selection` must stay
1304
+ * type-only toward this module to keep the dependency graph acyclic. The
1305
+ * deferring run's journal is never written — repayment is a read-side join.
1306
+ * Scheduling the cadence (nightly, per-merge) stays a product concern; this
1307
+ * is only the primitive one pass runs.
1308
+ *
1309
+ * @since 0.1.0
1310
+ * @category combinators
1311
+ */
1312
+ export const recertify = Effect.fn("PlanScheduler.recertify")((input) => Effect.gen(function* () {
1313
+ const scheduler = make({
1314
+ ...input.options,
1315
+ selection: { ...input.options.selection, full: true }
1316
+ });
1317
+ const report = yield* scheduler.run(input.plan);
1318
+ const remaining = yield* Selection.debt(input.deferringRunId, { repaidBy: [input.options.runId] });
1319
+ return { runId: input.options.runId, report, remaining };
1320
+ }));
1321
+ //# sourceMappingURL=PlanScheduler.js.map