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

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 +201 -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 +1586 -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 +300 -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 +3154 -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,985 @@
1
+ /**
2
+ * Functional workspace transactions for action execution.
3
+ *
4
+ * An action body normally mutates the host tree in place, which leaves the
5
+ * engine two bad options: trust the declaration, or diff the whole repository
6
+ * after the fact. This module takes the third one. The body runs against an
7
+ * **isolated workspace** seeded with exactly its declared read set; its writes
8
+ * are a value — a whole-tree diff — that reaches the host only through an
9
+ * explicit {@link Service.materialize} step with preconditions and rollback.
10
+ *
11
+ * Two consequences follow, and they are the reason this exists:
12
+ *
13
+ * - **Whole-tree write observation is structural.** The transaction *is* the
14
+ * tree, so "did this body write outside its declared write set" is a map
15
+ * comparison, not an inference. `StepBoundary`'s filesystem layer can only
16
+ * re-measure paths it was told about, which is why it never claims
17
+ * `wholeTreeWritesVerified` and why nothing it settled could enter the
18
+ * cross-run cache.
19
+ * - **The host is untouched until copy-back.** An execution whose observations
20
+ * contradict its declaration is {@link Invalidated}, and an invalidated
21
+ * result exposes provenance and violations *only* — never the candidate
22
+ * output, files, or queued effects.
23
+ *
24
+ * This is a **deterministic transaction model, not a security boundary** — the
25
+ * same caveat the proof of concept carried. A body that reaches the host
26
+ * through a service this module does not seed (a spawned native process, an
27
+ * undecorated socket) is outside the transaction. Actually denying that
28
+ * ambient access requires a machine boundary such as the providers in
29
+ * `packages/smithers/flows/sandbox/docs/api.md`. The one host
30
+ * write this module *does* perform is confined, however: copy-back resolves
31
+ * symlinks before it lands a byte and refuses any target whose canonical
32
+ * location escapes the workspace root.
33
+ *
34
+ * Settled bundles reach the host without a human review gate. Governing
35
+ * design: `docs/concepts/workspace-transactions.md`.
36
+ *
37
+ * @since 0.1.0
38
+ */
39
+ import * as ArtifactStore from "@smthrs/artifacts/ArtifactStore";
40
+ import * as FileLease from "@smthrs/artifacts/FileLease";
41
+ import { Sha256 } from "@smthrs/crypto";
42
+ import * as KernelFileSystem from "@smthrs/kernel/FileSystem";
43
+ import { Workspace as KernelWorkspace } from "@smthrs/kernel/Workspace";
44
+ import { DerivedKey } from "@smthrs/keys";
45
+ import * as FileSet from "@smthrs/plan/FileSet";
46
+ import * as Cause from "effect/Cause";
47
+ import * as Context from "effect/Context";
48
+ import * as Effect from "effect/Effect";
49
+ import * as Exit from "effect/Exit";
50
+ import * as FileSystem from "effect/FileSystem";
51
+ import * as Layer from "effect/Layer";
52
+ import * as Metric from "effect/Metric";
53
+ import * as Path from "effect/Path";
54
+ import * as PlatformError from "effect/PlatformError";
55
+ import * as RcMap from "effect/RcMap";
56
+ import * as Ref from "effect/Ref";
57
+ import * as Result from "effect/Result";
58
+ import * as Schema from "effect/Schema";
59
+ import * as Scope from "effect/Scope";
60
+ import * as Semaphore from "effect/Semaphore";
61
+ import * as EngineStoreMetrics from "./EngineStoreMetrics.js";
62
+ import * as FileBoundarySnapshot from "./internal/FileBoundarySnapshot.js";
63
+ import * as FileEnumeration from "./internal/FileEnumeration.js";
64
+ import { compareText } from "./internal/Ordering.js";
65
+ /**
66
+ * Context service made available only inside a workspace transaction.
67
+ *
68
+ * @category services
69
+ * @since 0.1.0
70
+ */
71
+ export const Workspace = Context.Service("@smthrs/engine-store/WorkspaceSandbox/Workspace");
72
+ /**
73
+ * Stable workspace sandbox failure codes.
74
+ *
75
+ * @category schemas
76
+ * @since 0.1.0
77
+ */
78
+ export const WorkspaceErrorCode = Schema.Literals([
79
+ "invalid_path",
80
+ "not_found",
81
+ "host_unavailable",
82
+ "path_escapes_workspace",
83
+ "commit_lock_timeout"
84
+ ]);
85
+ /**
86
+ * A body could not execute inside — or its result could not be moved through —
87
+ * an isolated workspace.
88
+ *
89
+ * `cause` carries the refusing host or artifact-store failure whole, so a
90
+ * debugger sees the original error instead of a flattened message
91
+ * (`PlatformError`'s own convention).
92
+ *
93
+ * @category errors
94
+ * @since 0.1.0
95
+ */
96
+ export class WorkspaceError extends Schema.TaggedError()("@smthrs/engine-store/WorkspaceError", {
97
+ code: WorkspaceErrorCode,
98
+ message: Schema.String,
99
+ cause: Schema.optional(Schema.Defect())
100
+ }) {
101
+ }
102
+ /**
103
+ * Copy-back would overwrite host state that changed since the transaction's
104
+ * base snapshot was taken.
105
+ *
106
+ * The engine answers this by retrying the attempt from a fresh base a bounded
107
+ * number of times. This local retry is rebase-shaped. The worktree-lane
108
+ * surface was removed; this error does not recreate it.
109
+ *
110
+ * @category errors
111
+ * @since 0.1.0
112
+ */
113
+ export class MaterializationConflict extends Schema.TaggedError()("@smthrs/engine-store/MaterializationConflict", {
114
+ paths: Schema.Array(Schema.NonEmptyString.check(Schema.isMaxLength(4_096))).check(Schema.isMaxLength(1_024)),
115
+ message: Schema.NonEmptyString.check(Schema.isMaxLength(16_384))
116
+ }) {
117
+ }
118
+ /**
119
+ * Whether a failure is a materialization conflict in live or durable form.
120
+ * Persisted failures retain the schema tag but not the class prototype, so
121
+ * replay classification must recognize both representations.
122
+ *
123
+ * @category guards
124
+ * @since 0.1.0
125
+ */
126
+ export const isMaterializationConflict = (error) => {
127
+ if (typeof error !== "object" || error === null)
128
+ return false;
129
+ try {
130
+ if (error instanceof MaterializationConflict)
131
+ return true;
132
+ const own = (name) => {
133
+ const descriptor = Object.getOwnPropertyDescriptor(error, name);
134
+ return descriptor !== undefined && descriptor.enumerable && "value" in descriptor
135
+ ? descriptor.value
136
+ : undefined;
137
+ };
138
+ const paths = own("paths");
139
+ const message = own("message");
140
+ if (own("_tag") !== MaterializationConflict.identifier ||
141
+ typeof message !== "string" ||
142
+ message.length === 0 ||
143
+ message.length > 16_384 ||
144
+ !Array.isArray(paths) ||
145
+ Object.getPrototypeOf(paths) !== Array.prototype ||
146
+ paths.length > 1_024)
147
+ return false;
148
+ for (let index = 0; index < paths.length; index++) {
149
+ const descriptor = Object.getOwnPropertyDescriptor(paths, String(index));
150
+ if (descriptor === undefined ||
151
+ !("value" in descriptor) ||
152
+ !descriptor.enumerable ||
153
+ typeof descriptor.value !== "string" ||
154
+ descriptor.value.length === 0 ||
155
+ descriptor.value.length > 4_096)
156
+ return false;
157
+ }
158
+ if (Reflect.ownKeys(paths).some((key) => key !== "length" &&
159
+ (typeof key !== "string" || !/^(0|[1-9][0-9]*)$/.test(key) || Number(key) >= paths.length)))
160
+ return false;
161
+ return Reflect.ownKeys(error).every((key) => key === "_tag" || key === "paths" || key === "message");
162
+ }
163
+ catch {
164
+ return false;
165
+ }
166
+ };
167
+ /**
168
+ * Context service for the selected workspace sandbox implementation.
169
+ *
170
+ * @category services
171
+ * @since 0.1.0
172
+ */
173
+ export const WorkspaceSandbox = Context.Service("@smthrs/engine-store/WorkspaceSandbox");
174
+ /**
175
+ * Constructs a workspace sandbox from an implementation.
176
+ *
177
+ * @category constructors
178
+ * @since 0.1.0
179
+ */
180
+ export const make = (service) => WorkspaceSandbox.of(service);
181
+ /**
182
+ * Provides a workspace sandbox implementation.
183
+ *
184
+ * @category layers
185
+ * @since 0.1.0
186
+ */
187
+ export const layer = (service) => Layer.succeed(WorkspaceSandbox, make(service));
188
+ /**
189
+ * Context service for the queued-effect dispatch stage. Optional: with no
190
+ * dispatcher provided the engine journals what a transaction queued and sends
191
+ * nothing.
192
+ *
193
+ * @category services
194
+ * @since 0.1.0
195
+ */
196
+ export const EffectDispatcher = Context.Service("@smthrs/engine-store/WorkspaceSandbox/EffectDispatcher");
197
+ /**
198
+ * Provides a queued-effect dispatch stage.
199
+ *
200
+ * @category layers
201
+ * @since 0.1.0
202
+ */
203
+ export const layerDispatcher = (dispatcher) => Layer.succeed(EffectDispatcher, EffectDispatcher.of(dispatcher));
204
+ // -----------------------------------------------------------------------------
205
+ // path vocabulary
206
+ // -----------------------------------------------------------------------------
207
+ const decoder = new TextDecoder();
208
+ const encoder = new TextEncoder();
209
+ const invalidPath = (path) => new WorkspaceError({
210
+ code: "invalid_path",
211
+ message: `Workspace paths must be relative paths inside the workspace without '..': ${path}`
212
+ });
213
+ /**
214
+ * Normalizes a caller path to a workspace-relative key.
215
+ *
216
+ * Absolute paths are accepted only under `root`, which is how a body that
217
+ * resolved `workspace.root` itself still lands inside the transaction; every
218
+ * other absolute path, and anything traversing upward, is refused rather than
219
+ * silently confined.
220
+ */
221
+ const normalizePath = (root, path, allowRoot = false) => {
222
+ const slashed = path.replaceAll("\\", "/");
223
+ const slashedRoot = root.replaceAll("\\", "/");
224
+ const rooted = slashed === slashedRoot
225
+ ? ""
226
+ : slashedRoot !== "" && slashed.startsWith(`${slashedRoot}/`)
227
+ ? slashed.slice(slashedRoot.length + 1)
228
+ : slashed;
229
+ const parts = rooted.split("/");
230
+ if (rooted.startsWith("/") || parts.some((part) => part === ".."))
231
+ return Result.fail(invalidPath(path));
232
+ const compact = parts.filter((part) => part !== "" && part !== ".").join("/");
233
+ return compact === "" && !allowRoot ? Result.fail(invalidPath(path)) : Result.succeed(compact);
234
+ };
235
+ /**
236
+ * Whether a declared write-set entry covers an observed path. A plain string
237
+ * is a literal path, even when it contains `*` or `**`, exactly as
238
+ * `StepBoundary` captures and `FileSet.overlaps` compares it; wildcard
239
+ * declarations are written as a Glob.
240
+ */
241
+ const covers = (entry, path) => typeof entry === "string"
242
+ ? entry === path
243
+ : entry._tag === "TreeArtifact"
244
+ ? path === entry.path || path.startsWith(`${entry.path}/`)
245
+ : FileSet.matchesGlob(entry, path);
246
+ const resource = (path) => ({ kind: "file", id: path });
247
+ /**
248
+ * Restates a declaration in the transaction's own path vocabulary.
249
+ *
250
+ * A caller may declare `out/result.txt` or the absolute path the same file has
251
+ * on the host — the kernel-decorated `FileSystem` accepts both, so the
252
+ * declaration does too. Observed paths are always workspace-relative, so the
253
+ * declaration has to be brought to the same footing before anything is
254
+ * compared against it, or an absolute declaration would cover nothing and
255
+ * every write would read as undeclared. An entry that cannot be named inside
256
+ * the workspace is kept verbatim: it covers nothing, which is the honest
257
+ * answer for a declaration pointing outside the tree.
258
+ */
259
+ const workspaceRelative = (root, descriptor) => {
260
+ const relative = (path) => {
261
+ const normalized = normalizePath(root, path);
262
+ return Result.isFailure(normalized) ? path : normalized.success;
263
+ };
264
+ return {
265
+ readSet: descriptor.readSet.map((entry) => FileSet.isGlob(entry)
266
+ ? {
267
+ ...entry,
268
+ include: [relative(entry.include[0]), ...entry.include.slice(1).map(relative)],
269
+ ...(entry.exclude === undefined ? {} : { exclude: entry.exclude.map(relative) })
270
+ }
271
+ : { ...entry, path: relative(entry.path) }),
272
+ writeSet: descriptor.writeSet.map((entry) => typeof entry === "string"
273
+ ? relative(entry)
274
+ : entry._tag === "TreeArtifact"
275
+ ? { ...entry, path: relative(entry.path) }
276
+ : {
277
+ ...entry,
278
+ include: [relative(entry.include[0]), ...entry.include.slice(1).map(relative)],
279
+ ...(entry.exclude === undefined ? {} : { exclude: entry.exclude.map(relative) })
280
+ }),
281
+ ...(descriptor.removes === undefined ? {} : { removes: descriptor.removes.map(relative) }),
282
+ boundaryMode: descriptor.boundaryMode
283
+ };
284
+ };
285
+ const digestOf = (bytes) => Schema.decodeUnknownEffect(Sha256)(bytes).pipe(Effect.orDie);
286
+ const parentDirectory = (path) => {
287
+ const index = path.lastIndexOf("/");
288
+ return index <= 0 ? undefined : path.slice(0, index);
289
+ };
290
+ const notFound = (path) => new WorkspaceError({ code: "not_found", message: `Workspace file does not exist: ${path}` });
291
+ /**
292
+ * The transaction surfaces: the {@link Workspace} tag and a re-rooted Effect
293
+ * `FileSystem`, both over one path-keyed map.
294
+ *
295
+ * The `FileSystem` is built from `makeNoop` on purpose. Only the operations
296
+ * listed here are meaningful over a functional map, and a body reaching for
297
+ * one that is not — a temp file, a watch, a stream — gets the platform's own
298
+ * refusal rather than a plausible lie. Widening the surface is a deliberate
299
+ * change to this list, never a silent default.
300
+ */
301
+ const transaction = (base, trace, root) => {
302
+ const files = new Map(base);
303
+ const produced = new Set();
304
+ const resolvePath = (path, allowRoot = false) => {
305
+ const normalized = normalizePath(root, path, allowRoot);
306
+ return Result.isFailure(normalized) ? Effect.fail(normalized.failure) : Effect.succeed(normalized.success);
307
+ };
308
+ const readBytes = Effect.fn("WorkspaceSandbox.read")(function* (path) {
309
+ const key = yield* resolvePath(path);
310
+ trace.attemptedReads.push({ path: key, produced: produced.has(key) });
311
+ const content = files.get(key);
312
+ if (content === undefined)
313
+ return yield* Effect.fail(notFound(key));
314
+ trace.inputs.push({ path: key, content });
315
+ return content.slice();
316
+ });
317
+ const writeBytes = Effect.fn("WorkspaceSandbox.write")(function* (path, content) {
318
+ const key = yield* resolvePath(path);
319
+ produced.add(key);
320
+ files.set(key, content.slice());
321
+ });
322
+ const removePath = Effect.fn("WorkspaceSandbox.remove")(function* (path) {
323
+ const key = yield* resolvePath(path);
324
+ produced.add(key);
325
+ files.delete(key);
326
+ });
327
+ const workspace = Workspace.of({
328
+ readFile: (path) => readBytes(path),
329
+ writeFile: (path, content) => writeBytes(path, content),
330
+ removeFile: (path) => removePath(path),
331
+ queueEffect: (effect) => Effect.sync(() => trace.effects.push(effect))
332
+ });
333
+ const refuse = (method, path) => (error) => error.code === "not_found"
334
+ ? PlatformError.systemError({
335
+ _tag: "NotFound",
336
+ module: "FileSystem",
337
+ method,
338
+ description: error.message,
339
+ pathOrDescriptor: path
340
+ })
341
+ : PlatformError.badArgument({ module: "FileSystem", method, description: error.message });
342
+ const fileSystem = FileSystem.makeNoop({
343
+ // `exists` and `readDirectory` trace every PRESENCE they reveal: under a
344
+ // whole-tree-seeding host the map holds undeclared world state, and a
345
+ // probe that observes it is a read the key never folded. Absence stays
346
+ // untraced — under the declared-set host an undeclared path is absent by
347
+ // construction, the Bazel forest's own deterministic answer.
348
+ exists: (path) => resolvePath(path, true).pipe(Effect.map((key) => {
349
+ if (key === "")
350
+ return true;
351
+ if (files.has(key)) {
352
+ trace.attemptedReads.push({ path: key, produced: produced.has(key) });
353
+ return true;
354
+ }
355
+ const prefix = `${key}/`;
356
+ let present = false;
357
+ for (const candidate of files.keys()) {
358
+ if (!candidate.startsWith(prefix))
359
+ continue;
360
+ trace.attemptedReads.push({ path: candidate, produced: produced.has(candidate) });
361
+ present = true;
362
+ }
363
+ return present;
364
+ }),
365
+ // A path the transaction cannot even name does not exist in it; that
366
+ // is an answer, not a host failure.
367
+ Effect.catch(() => Effect.succeed(false))),
368
+ readFile: (path) => readBytes(path).pipe(Effect.mapError(refuse("readFile", path))),
369
+ readFileString: (path) => readBytes(path).pipe(Effect.map((bytes) => decoder.decode(bytes)), Effect.mapError(refuse("readFileString", path))),
370
+ writeFile: (path, data) => writeBytes(path, data).pipe(Effect.mapError(refuse("writeFile", path))),
371
+ writeFileString: (path, data) => writeBytes(path, encoder.encode(data)).pipe(Effect.mapError(refuse("writeFileString", path))),
372
+ remove: (path) => removePath(path).pipe(Effect.mapError(refuse("remove", path))),
373
+ // Directories are implicit in a path-keyed map: creating one is a
374
+ // successful no-op so a body that mirrors ordinary filesystem discipline
375
+ // works unchanged, and listing one is a prefix scan.
376
+ makeDirectory: () => Effect.void,
377
+ readDirectory: (path) => resolvePath(path, true).pipe(Effect.map((key) => {
378
+ const prefix = key === "" ? "" : `${key}/`;
379
+ const entries = new Set();
380
+ for (const candidate of files.keys()) {
381
+ if (!candidate.startsWith(prefix))
382
+ continue;
383
+ // A listing reveals each file it names, so each is a traced read.
384
+ trace.attemptedReads.push({ path: candidate, produced: produced.has(candidate) });
385
+ entries.add(candidate.slice(prefix.length).split("/")[0]);
386
+ }
387
+ return [...entries].sort(compareText);
388
+ }), Effect.mapError(refuse("readDirectory", path)))
389
+ });
390
+ return { files, workspace, fileSystem };
391
+ };
392
+ const changes = Effect.fn("WorkspaceSandbox.changes")(function* (base, current, host) {
393
+ const paths = [...new Set([...base.keys(), ...current.keys()])].sort(compareText);
394
+ const result = [];
395
+ for (const path of paths) {
396
+ const before = base.get(path);
397
+ const after = current.get(path);
398
+ // A path the transaction never observed is not a path the host lacks: ask
399
+ // the host what is there before claiming the change creates it.
400
+ const beforeDigest = before === undefined ? yield* host.baseline(path) : yield* digestOf(before);
401
+ const afterDigest = after === undefined ? undefined : yield* digestOf(after);
402
+ if (beforeDigest === afterDigest)
403
+ continue;
404
+ result.push({
405
+ path,
406
+ beforeDigest,
407
+ afterDigest,
408
+ ...(after === undefined ? {} : { after: yield* host.retain(after) })
409
+ });
410
+ }
411
+ return result;
412
+ });
413
+ /**
414
+ * The compare-and-set every copy-back runs before it writes a single byte,
415
+ * capturing each target's pre-image while it looks.
416
+ *
417
+ * Both hosts share it, so "all-or-nothing" cannot drift between the in-memory
418
+ * conformance implementation and the filesystem one: a bundle whose base moved
419
+ * is refused whole, and the tree is left exactly as it was found. The captured
420
+ * pre-images are the rollback journal the filesystem host restores from when a
421
+ * mid-apply refusal would otherwise strand a half-written tree.
422
+ */
423
+ const preflight = Effect.fn("WorkspaceSandbox.preflight")(function* (changes, current) {
424
+ const conflicting = [];
425
+ const before = new Map();
426
+ for (const change of changes) {
427
+ const content = yield* current(change.path);
428
+ before.set(change.path, content);
429
+ const digest = content === undefined ? undefined : yield* digestOf(content);
430
+ conflicting.push(...(digest === change.beforeDigest ? [] : [change.path]));
431
+ }
432
+ const conflict = conflicting.length === 0 ? undefined : new MaterializationConflict({
433
+ paths: conflicting,
434
+ message: "Workspace state changed after the transaction's base snapshot was taken"
435
+ });
436
+ return { conflict, before };
437
+ });
438
+ const revisionOf = Effect.fn("WorkspaceSandbox.revision")(function* (base) {
439
+ const entries = [];
440
+ for (const [path, content] of [...base].sort((left, right) => compareText(left[0], right[0]))) {
441
+ entries.push({ path, digest: yield* digestOf(content) });
442
+ }
443
+ return yield* Schema.decodeUnknownEffect(DerivedKey)({ kind: "workspace-revision", entries }).pipe(Effect.orDie);
444
+ });
445
+ /**
446
+ * Everything the declaration failed to predict, deduplicated.
447
+ *
448
+ * Reads and writes are checked against the declaration's exact paths and patterns; writes
449
+ * against the declared write set's patterns. A read of a file the body itself
450
+ * produced is not undeclared — the transaction, not the host, supplied it.
451
+ *
452
+ * @category accessors
453
+ * @since 0.1.0
454
+ */
455
+ export const violations = (descriptor, base, provenance) => {
456
+ const declaredReads = descriptor.readSet;
457
+ const observed = [
458
+ ...provenance.inputs
459
+ .filter((input) => base.has(input.resource.id) &&
460
+ !declaredReads.some((entry) => FileSet.isGlob(entry) ? FileSet.matchesGlob(entry, input.resource.id) : entry.path === input.resource.id))
461
+ .map((input) => ({ kind: "undeclared-read", resource: input.resource })),
462
+ ...provenance.outputs
463
+ .filter((output) => ![...descriptor.writeSet, ...descriptor.removes ?? []].some((entry) => covers(entry, output.resource.id)))
464
+ .map((output) => ({ kind: "undeclared-write", resource: output.resource }))
465
+ ];
466
+ return [
467
+ ...new Map(observed.map((violation) => [`${violation.kind}:${violation.resource.id}`, violation])).values()
468
+ ];
469
+ };
470
+ /**
471
+ * Builds a workspace sandbox over a {@link Host}.
472
+ *
473
+ * @category constructors
474
+ * @since 0.1.0
475
+ */
476
+ export const makeHosted = (host) => {
477
+ const memo = new Map();
478
+ /**
479
+ * The speculative half, untraced: the `execute` span below wraps it, so
480
+ * the transaction body reports under one span with its metrics.
481
+ */
482
+ const executeBody = Effect.fnUntraced(function* (execution) {
483
+ const boundary = FileBoundarySnapshot.make(execution.descriptor);
484
+ const key = execution.cacheKey;
485
+ if (key !== undefined) {
486
+ const hit = memo.get(key);
487
+ if (hit !== undefined) {
488
+ return {
489
+ _tag: "Accepted",
490
+ result: hit.result,
491
+ violations: hit.violations,
492
+ cache: { status: "hit", key }
493
+ };
494
+ }
495
+ }
496
+ const captured = yield* host.snapshot(boundary);
497
+ // The host owns its returned buffers. Preserve the instant represented by
498
+ // snapshot() even if that host or another fiber mutates them while the
499
+ // workflow is suspended.
500
+ const base = new Map([...captured].map(([path, content]) => [path, content.slice()]));
501
+ const trace = { inputs: [], attemptedReads: [], effects: [] };
502
+ const isolated = transaction(base, trace, host.root);
503
+ const outcome = yield* execution.workflow.pipe(Effect.provideService(Workspace, isolated.workspace), Effect.provideService(FileSystem.FileSystem, isolated.fileSystem), Effect.exit);
504
+ const inputs = [];
505
+ for (const input of trace.inputs) {
506
+ inputs.push({ resource: resource(input.path), digest: yield* digestOf(input.content) });
507
+ }
508
+ const descriptor = workspaceRelative(host.root, boundary);
509
+ const undeclaredReads = trace.attemptedReads.filter((attempt) => !attempt.produced &&
510
+ !descriptor.readSet.some((entry) => FileSet.isGlob(entry) ? FileSet.matchesGlob(entry, attempt.path) : entry.path === attempt.path));
511
+ if (Exit.isFailure(outcome)) {
512
+ // Hard mode only, mirroring the success path below: in expected mode
513
+ // an undeclared read is a deviation the engine journals, and a body's
514
+ // own typed failure must surface as itself — converting it into an
515
+ // isolation verdict would both harden a soft boundary and mask the
516
+ // error the retry policy classifies on.
517
+ if (undeclaredReads.length > 0 && boundary.boundaryMode === "hard") {
518
+ return {
519
+ _tag: "Invalidated",
520
+ provenance: {
521
+ baseRevision: yield* revisionOf(base),
522
+ inputs,
523
+ outputs: []
524
+ },
525
+ violations: [
526
+ ...new Map(undeclaredReads.map((attempt) => [attempt.path, {
527
+ kind: "undeclared-read",
528
+ resource: resource(attempt.path)
529
+ }])).values()
530
+ ]
531
+ };
532
+ }
533
+ return yield* Effect.failCause(outcome.cause);
534
+ }
535
+ const output = outcome.value;
536
+ const files = yield* changes(base, isolated.files, host);
537
+ const provenance = {
538
+ baseRevision: yield* revisionOf(base),
539
+ inputs,
540
+ outputs: files.map((change) => ({
541
+ resource: resource(change.path),
542
+ operation: change.afterDigest === undefined ? "remove" : "write",
543
+ digest: change.afterDigest
544
+ }))
545
+ };
546
+ const invalid = [
547
+ ...new Map([
548
+ ...violations(descriptor, base, provenance),
549
+ ...undeclaredReads.map((attempt) => ({
550
+ kind: "undeclared-read",
551
+ resource: resource(attempt.path)
552
+ }))
553
+ ].map((violation) => [`${violation.kind}:${violation.resource.id}`, violation])).values()
554
+ ];
555
+ // Hard mode discards; expected mode admits the result and leaves the
556
+ // deviation for the engine to journal and reconcile
557
+ // (`Effect Taxonomy.md`, "Expected sets — the soft mode"). Either way
558
+ // the host has not been touched.
559
+ if (invalid.length > 0 && boundary.boundaryMode === "hard") {
560
+ return { _tag: "Invalidated", provenance, violations: invalid };
561
+ }
562
+ const result = { output, files, provenance, effects: trace.effects };
563
+ if (key !== undefined) {
564
+ memo.set(key, { result: result, violations: invalid });
565
+ }
566
+ return {
567
+ _tag: "Accepted",
568
+ result,
569
+ violations: invalid,
570
+ cache: key === undefined ? { status: "disabled" } : { status: "miss", key }
571
+ };
572
+ });
573
+ return make({
574
+ execute: Effect.fn("WorkspaceSandbox.execute")(function* (execution) {
575
+ yield* Effect.annotateCurrentSpan({ boundaryMode: execution.descriptor.boundaryMode });
576
+ return yield* executeBody(execution);
577
+ }, (effect) => EngineStoreMetrics.observe({
578
+ timer: EngineStoreMetrics.sandboxExecutionDuration,
579
+ counter: EngineStoreMetrics.sandboxExecution
580
+ })(effect)),
581
+ materialize: Effect.fn("WorkspaceSandbox.materialize")(function* (accepted) {
582
+ yield* Effect.annotateCurrentSpan({ changes: accepted.result.files.length });
583
+ // Nothing to copy back needs no commit: a body that changed nothing
584
+ // (a sealed read) must not need write authority over the root.
585
+ if (accepted.result.files.length === 0)
586
+ return;
587
+ yield* host.commit(accepted.result.files);
588
+ }, (effect) => EngineStoreMetrics.observe({
589
+ timer: EngineStoreMetrics.materializationDuration,
590
+ counter: EngineStoreMetrics.materialization
591
+ })(effect))
592
+ });
593
+ };
594
+ /**
595
+ * Creates a deterministic in-memory workspace sandbox.
596
+ *
597
+ * The returned `files` effect observes *host* state, not a running
598
+ * transaction: it changes only through `service.materialize`. This host hands
599
+ * the transaction its whole tree rather than seeding the declared read set, so
600
+ * an undeclared read is observable — which is exactly what makes it the
601
+ * conformance implementation for the bare tier of `Effect Taxonomy.md`.
602
+ *
603
+ * @category constructors
604
+ * @since 0.1.0
605
+ */
606
+ export const makeMemory = (initialFiles = {}) => Effect.gen(function* () {
607
+ const entries = [];
608
+ for (const [path, content] of Object.entries(initialFiles)) {
609
+ const normalized = normalizePath("", path);
610
+ if (Result.isFailure(normalized))
611
+ return yield* Effect.fail(normalized.failure);
612
+ entries.push([normalized.success, typeof content === "string" ? encoder.encode(content) : content.slice()]);
613
+ }
614
+ const host = yield* Ref.make(new Map(entries));
615
+ const service = makeHosted({
616
+ root: "",
617
+ snapshot: () => Ref.get(host),
618
+ // This host seeds the transaction with the WHOLE tree, so a path the
619
+ // transaction did not observe is one the host genuinely did not hold:
620
+ // `undefined` is the honest snapshot-time answer, and a file that
621
+ // appeared underneath the transaction is caught by copy-back's
622
+ // compare-and-set rather than clobbered.
623
+ baseline: () => Effect.succeed(undefined),
624
+ retain: (bytes) => Effect.succeed(bytes.slice()),
625
+ commit: Effect.fn("WorkspaceSandbox.commit")(function* (changes) {
626
+ yield* Effect.annotateCurrentSpan({ changes: changes.length });
627
+ const current = yield* Ref.get(host);
628
+ const { conflict } = yield* preflight(changes, (path) => Effect.succeed(current.get(path)));
629
+ if (conflict !== undefined) {
630
+ yield* Metric.update(EngineStoreMetrics.materializationConflicts, 1);
631
+ return yield* Effect.fail(conflict);
632
+ }
633
+ const next = new Map(current);
634
+ for (const change of changes) {
635
+ if (change.afterDigest === undefined)
636
+ next.delete(change.path);
637
+ else
638
+ next.set(change.path, change.after.slice());
639
+ }
640
+ yield* Ref.set(host, next);
641
+ })
642
+ });
643
+ return {
644
+ service,
645
+ files: Ref.get(host).pipe(Effect.map((current) => [...current]
646
+ .map(([path, content]) => ({ path, content }))
647
+ .sort((left, right) => compareText(left.path, right.path))))
648
+ };
649
+ });
650
+ // Shared across separately constructed sandboxes. Entries live only while a
651
+ // commit is running or waiting, so short-lived workspace roots do not leak.
652
+ const CommitLocks = Context.Service("@smthrs/engine-store/WorkspaceSandbox/CommitLocks");
653
+ const locksLayer = Layer.effect(CommitLocks, RcMap.make({ lookup: (_root) => Semaphore.make(1) }));
654
+ // The memo map shares the layer across active operations, including operations
655
+ // from different store instances. Their scopes release the final owner.
656
+ const lockOwners = Layer.makeMemoMapUnsafe();
657
+ const coordinateCommit = (root, write) => Effect.scoped(Effect.gen(function* () {
658
+ const services = yield* Layer.buildWithMemoMap(locksLayer, lockOwners, yield* Scope.Scope);
659
+ const lock = yield* RcMap.get(Context.get(services, CommitLocks), root);
660
+ return yield* lock.withPermit(write);
661
+ }));
662
+ const commitLockName = ".smithers-workspace-lock";
663
+ // The conventional engine state directory: the SQLite store, its WAL/SHM
664
+ // siblings, and the artifact objects. A step body must never replace them.
665
+ const engineStateName = ".flows";
666
+ const defaultMaxInlineBytes = 1024 * 1024;
667
+ const hostFailure = (cause) => new WorkspaceError({
668
+ code: "host_unavailable",
669
+ message: "the host filesystem could not serve the workspace transaction",
670
+ cause
671
+ });
672
+ const artifactFailure = (cause) => new WorkspaceError({
673
+ code: "host_unavailable",
674
+ message: `the artifact store could not serve the workspace transaction: ${cause.message}`,
675
+ cause
676
+ });
677
+ /**
678
+ * The errno names the descriptor-relative host reports when it refuses to
679
+ * resolve a path inside its pinned root: a symlink at the final component
680
+ * (`ELOOP`); a symlink at an intermediate component (`ELOOP` on Linux,
681
+ * `ENOTDIR` on Darwin, which also covers a file standing where a directory
682
+ * must be); or `..` traversal, a path outside the root, a hard-linked file, or
683
+ * a root whose identity changed (`EPERM`). Each means the change does not
684
+ * name a workspace entry reachable without following a link.
685
+ */
686
+ const confinementCodes = new Set(["ELOOP", "ENOTDIR", "EPERM"]);
687
+ const refusedByConfinement = (error) => error.reason._tag !== "BadArgument" &&
688
+ typeof error.reason.cause === "object" && error.reason.cause !== null &&
689
+ confinementCodes.has(error.reason.cause.code);
690
+ /** Maps one copy-back host failure onto the sandbox's typed error codes. */
691
+ const copyBackFailure = (path) => (error) => refusedByConfinement(error)
692
+ ? new WorkspaceError({
693
+ code: "path_escapes_workspace",
694
+ message: `materializing ${path} was refused: it does not name a workspace entry reachable without following a link (${error.message})`,
695
+ cause: error
696
+ })
697
+ : hostFailure(error);
698
+ /**
699
+ * Maps a commit-lock failure: a missed acquisition deadline is
700
+ * `commit_lock_timeout`, so a caller can tell "another writer holds the root"
701
+ * from "the host refused".
702
+ */
703
+ const lockFailure = (cause) => Cause.isTimeoutError(cause)
704
+ ? new WorkspaceError({
705
+ code: "commit_lock_timeout",
706
+ message: `another writer held ${commitLockName} for the whole acquisition deadline; a lock whose owner stopped is reclaimed once its heartbeat is ${FileLease.defaultStaleAfterMs} ms old`,
707
+ cause
708
+ })
709
+ // `FileLease` hands every other refusal over as the host's `PlatformError`.
710
+ : copyBackFailure(commitLockName)(cause);
711
+ // Over-approximates the spellings a case-insensitive, normalization-insensitive
712
+ // volume equates: `.FLOWS`, `.flow\u017f`, and `.\ufb02ows` all open `.flows` on
713
+ // default APFS. Folding more than a volume does only refuses more names.
714
+ const foldPath = (path) => path.normalize("NFKC").toUpperCase().toLowerCase().normalize("NFKC");
715
+ // NTFS with 8.3 name creation on (the system volume default) also opens a
716
+ // long name through its generated short name: `.flows` through `FLOWS~1`, or
717
+ // `FL3A2B~1` once the numbered tails collide. Linux reaches such a volume
718
+ // through WSL's `/mnt/c` and macOS through SMB, so the shape is refused on
719
+ // every host. The pattern is broader than the generator: any `~` and digit
720
+ // tail on a base of at most eight characters, with an extension of at most
721
+ // three.
722
+ const shortNameAlias = /^[^.~]{0,7}~\d{1,7}(\.[^.]{0,3})?$/u;
723
+ const isShortNameAlias = (segment) => {
724
+ // `split` always yields a first element, possibly empty.
725
+ const base = segment.split(".")[0];
726
+ return base.length <= 8 && shortNameAlias.test(segment);
727
+ };
728
+ /**
729
+ * Builds the filesystem-backed workspace sandbox.
730
+ *
731
+ * **Copy-in, not overlay.** The transaction is seeded with exactly the
732
+ * declared read set and nothing else
733
+ * (`docs/concepts/workspace-transactions.md`). Bazel uses the same strategy, which
734
+ * is why whole-tree write observation is structural here. Re-rooting a
735
+ * body onto a bare host tree instead would leave every undeclared file
736
+ * readable and reduce enforcement to the taxonomy's weakest, post-hoc
737
+ * detection-by-diff tier; and the OS-level overlay that would fix that is not
738
+ * reachable through Effect's `FileSystem` tag, so it could not run in a
739
+ * browser. Seeding costs a copy of the declared reads and buys both.
740
+ *
741
+ * **Copy-back is confined and journaled.** Every copy-back host call (the
742
+ * lock, preflight, apply, and rollback) goes through
743
+ * `@smthrs/kernel/FileSystem`'s `confined` view: one descriptor-relative,
744
+ * no-follow request against the workspace root pinned when the commit starts.
745
+ * A symlink anywhere on a change's path, a hard-linked file, or a root
746
+ * replaced mid-commit is refused with `path_escapes_workspace`, never
747
+ * followed, and no check-then-write window exists for a concurrent process to
748
+ * swap a link into. A copy-back through a symlink that stays inside the root
749
+ * is refused too: the body writes the referent path itself. `fs` must
750
+ * therefore carry the kernel's descriptor-relative executor (Node and Bun
751
+ * hosts use `@smthrs/platform-node`'s `AtomicFileSystem`) or a
752
+ * whole-filesystem isolation attestation (`withIsolatedFileSystem`, for an
753
+ * in-memory volume); a plain path-based host is refused at copy-back with
754
+ * `host_unavailable`. Snapshot reads use `fs` as given. A root-keyed semaphore and
755
+ * the `.smithers-workspace-lock` lease file (`@smthrs/artifacts/FileLease`)
756
+ * serialize cooperating callers, including separate processes. Preconditions run before file
757
+ * changes, and the apply loop keeps each target's pre-image for in-process
758
+ * rollback. A crash or rollback failure can leave partial changes; see
759
+ * {@link Service.materialize} for the caller's reconciliation obligations.
760
+ * Hosts must implement exclusive `wx` file creation, `stat` with an mtime,
761
+ * `utimes`, `rename`, and `remove` for the reserved lock. Copy-back
762
+ * also refuses the `.flows` engine state directory and any
763
+ * {@link FileSystemOptions.reservedPaths}, so no write set or boundary mode
764
+ * lets a step body replace the engine database or its artifact blobs.
765
+ *
766
+ * @category constructors
767
+ * @since 0.1.0
768
+ */
769
+ export const makeFileSystem = (fs, platformPath, artifacts, workspaceRoot, options = {}) => {
770
+ const maxInlineBytes = options.maxInlineBytes ?? defaultMaxInlineBytes;
771
+ const root = workspaceRoot.replaceAll(/\/+$/g, "");
772
+ const reserved = [
773
+ commitLockName,
774
+ engineStateName,
775
+ ...(options.reservedPaths ?? []).map((path) => path.replace(/^(\.\/)+/, "").replaceAll(/\/+$/g, ""))
776
+ ].filter((path) => path !== "" && path !== ".").map((name) => ({ name, segments: foldPath(name).split("/") }));
777
+ // Why the root-relative `path` is refused, if it targets or lies beneath a
778
+ // reserved entry. The confined host refuses every symlink on a path, so the
779
+ // remaining aliases are spellings the volume itself equates: case,
780
+ // compatibility, and normalization variants on APFS and NTFS, and NTFS 8.3
781
+ // short names. Comparing folded segments, and refusing a short-name shape
782
+ // wherever a reserved segment stands, refuses them on every volume,
783
+ // case-sensitive ones included.
784
+ const reservedAt = (path) => {
785
+ const segments = foldPath(path).split("/");
786
+ const within = reserved.filter((entry) => entry.segments.length <= segments.length);
787
+ const exact = within.find((entry) => entry.segments.every((segment, index) => segments[index] === segment));
788
+ if (exact !== undefined)
789
+ return `the workspace path ${exact.name} is reserved`;
790
+ const alias = within.find((entry) =>
791
+ // `within` holds only entries no longer than the path, so every index is present.
792
+ entry.segments.every((segment, index) => segments[index] === segment || isShortNameAlias(segments[index])));
793
+ if (alias === undefined)
794
+ return undefined;
795
+ const spelling = path.split("/").slice(0, alias.segments.length).join("/");
796
+ return `the workspace path ${spelling} may be a short-name alias of a reserved path`;
797
+ };
798
+ const hostPath = (path) => root === "" ? path : `${root}/${path}`;
799
+ // One host call, not two: the read reports an absent path itself. On the
800
+ // confined host
801
+ // the `exists` probe that used to precede every read was a second CPython
802
+ // fork (`@smthrs/platform-node/AtomicFileSystem`) for an answer the read
803
+ // was about to give.
804
+ const readFrom = (host, path, onError) => host.readFile(path).pipe(Effect.catchReason("PlatformError", "NotFound", () => Effect.succeed(undefined)), Effect.mapError(onError));
805
+ const readIfPresent = Effect.fn("WorkspaceSandbox.readIfPresent")(function* (path) {
806
+ return yield* readFrom(fs, path, hostFailure);
807
+ });
808
+ const canonicalRoot = fs.realPath(root === "" ? "." : root).pipe(Effect.catchReason("PlatformError", "NotFound", () => Effect.succeed(undefined)), Effect.mapError(hostFailure));
809
+ const withCommitLock = (changes, effect) => Effect.gen(function* () {
810
+ for (const change of changes) {
811
+ const hit = reservedAt(change.path);
812
+ if (hit !== undefined)
813
+ return yield* Effect.fail(hostFailure(hit));
814
+ }
815
+ yield* fs.makeDirectory(root === "" ? "." : root, { recursive: true }).pipe(Effect.mapError(hostFailure));
816
+ // Pinned once per commit, after the root exists: every lock, preflight,
817
+ // apply, and rollback call below resolves against this root identity.
818
+ const host = yield* KernelFileSystem.confined(fs, root).pipe(Effect.provideService(Path.Path, platformPath), Effect.mapError(hostFailure));
819
+ const canonical = yield* canonicalRoot;
820
+ // The confined view refuses `utimes`, which the lease heartbeat needs.
821
+ // The heartbeat touches the lock only after a confined, no-follow read
822
+ // found this call's own token there, so the one path-based call it
823
+ // makes can at worst refresh an mtime.
824
+ const leaseHost = { ...host, utimes: fs.utimes };
825
+ return yield* coordinateCommit(canonical ?? root, FileLease.withLease(leaseHost, hostPath(commitLockName), effect(host), lockFailure, {
826
+ label: "Workspace commit lock",
827
+ annotations: { root: canonical ?? root }
828
+ }));
829
+ });
830
+ const commitWith = Effect.fn("WorkspaceSandbox.commit")(function* (host, changes) {
831
+ yield* Effect.annotateCurrentSpan({ changes: changes.length });
832
+ // The advisory lock and process semaphore cover preflight, apply, and
833
+ // rollback. Preconditions run only after both are acquired.
834
+ const { before, conflict } = yield* preflight(changes, (path) => readFrom(host, hostPath(path), copyBackFailure(path)));
835
+ if (conflict !== undefined) {
836
+ yield* Metric.update(EngineStoreMetrics.materializationConflicts, 1);
837
+ return yield* Effect.fail(conflict);
838
+ }
839
+ const resolved = new Map();
840
+ for (const change of changes) {
841
+ if (change.afterDigest === undefined)
842
+ continue;
843
+ const bytes = change.after ?? (yield* artifacts.get(`${change.afterDigest}`).pipe(Effect.mapError((error) => error._tag === "@smthrs/artifacts/ArtifactStoreError"
844
+ ? artifactFailure(error)
845
+ : new WorkspaceError({
846
+ code: "not_found",
847
+ message: `the retained bytes for ${change.path} are unavailable: ${error.message}`,
848
+ cause: error
849
+ }))));
850
+ resolved.set(change.path, bytes);
851
+ }
852
+ const applied = [];
853
+ const apply = Effect.gen(function* () {
854
+ for (const change of changes) {
855
+ // Journal the change before touching its target: a write that
856
+ // fails halfway may still have mutated the file it was writing.
857
+ applied.push(change);
858
+ const target = hostPath(change.path);
859
+ if (change.afterDigest === undefined) {
860
+ yield* host.remove(target).pipe(Effect.mapError(copyBackFailure(change.path)));
861
+ continue;
862
+ }
863
+ const parent = parentDirectory(target);
864
+ if (parent !== undefined) {
865
+ yield* host.makeDirectory(parent, { recursive: true }).pipe(Effect.mapError(copyBackFailure(change.path)));
866
+ }
867
+ yield* host.writeFile(target, resolved.get(change.path)).pipe(Effect.mapError(copyBackFailure(change.path)));
868
+ }
869
+ });
870
+ const rollback = Effect.gen(function* () {
871
+ for (const change of [...applied].reverse()) {
872
+ const target = hostPath(change.path);
873
+ const previous = before.get(change.path);
874
+ if (previous === undefined) {
875
+ yield* host.remove(target, { force: true }).pipe(Effect.mapError(copyBackFailure(change.path)));
876
+ }
877
+ else {
878
+ yield* host.writeFile(target, previous).pipe(Effect.mapError(copyBackFailure(change.path)));
879
+ }
880
+ }
881
+ // Keep empty parent directories. Effect's portable FileSystem has no
882
+ // atomic, non-recursive rmdir; recursively deleting a directory after
883
+ // a separate emptiness check could erase a concurrent writer's file.
884
+ });
885
+ yield* apply.pipe(Effect.catchCause((cause) => Effect.gen(function* () {
886
+ const restored = yield* Effect.exit(rollback);
887
+ if (Exit.isSuccess(restored))
888
+ return yield* Effect.failCause(cause);
889
+ const reasons = restored.cause.reasons
890
+ .filter(Cause.isFailReason)
891
+ .map((reason) => reason.error.message);
892
+ // Both failures travel: the apply cause that opened the window and
893
+ // the rollback cause that could not close it, composed the way
894
+ // `acquireUseRelease` composes a failed use with a failed release.
895
+ return yield* Effect.failCause(Cause.combine(cause, Cause.fail(new WorkspaceError({
896
+ code: "host_unavailable",
897
+ message: `copy-back failed mid-apply and rollback could not restore the workspace: ${reasons.join("; ")}`,
898
+ cause: restored.cause
899
+ }))));
900
+ })),
901
+ // Interruption inside the apply window is a mid-sequence abort the
902
+ // journal exists to prevent; the window is bounded local work, so it
903
+ // closes before the fiber answers the interrupt.
904
+ Effect.uninterruptible);
905
+ });
906
+ return makeHosted({
907
+ root,
908
+ snapshot: Effect.fn("WorkspaceSandbox.snapshot")(function* (descriptor) {
909
+ yield* Effect.annotateCurrentSpan({
910
+ reads: descriptor.readSet.length,
911
+ boundaryMode: descriptor.boundaryMode
912
+ });
913
+ const base = new Map();
914
+ for (const entry of descriptor.readSet) {
915
+ // Through `FileEnumeration`, never the host `glob`: host results skip
916
+ // dotfiles, so a declared read glob covering one would seed a sandbox
917
+ // that silently hides it from the body.
918
+ const paths = FileSet.isGlob(entry)
919
+ ? yield* FileEnumeration.expandGlob(fs, entry, {
920
+ resolve: (path) => path === "" ? (root === "" ? "." : root) : hostPath(path)
921
+ }).pipe(Effect.mapError(hostFailure))
922
+ : [entry.path];
923
+ for (const path of paths) {
924
+ const normalized = normalizePath(root, path);
925
+ if (Result.isFailure(normalized))
926
+ return yield* Effect.fail(normalized.failure);
927
+ const content = yield* readIfPresent(hostPath(normalized.success));
928
+ // A declared read that does not exist is seeded as absent, not as an
929
+ // error: `StepBoundary.prepare` already records the mismatch as the
930
+ // evidence that refuses the cache hit.
931
+ if (content !== undefined)
932
+ base.set(normalized.success, content);
933
+ }
934
+ }
935
+ for (const path of descriptor.removes ?? []) {
936
+ const normalized = normalizePath(root, path);
937
+ /* v8 ignore next -- `FileBoundary.removes` is `FileSet.Pattern`-checked, so a decoded boundary cannot carry an upward or absolute removal; the branch guards hand-built descriptors */
938
+ if (Result.isFailure(normalized))
939
+ return yield* Effect.fail(normalized.failure);
940
+ const content = yield* readIfPresent(hostPath(normalized.success));
941
+ if (content !== undefined)
942
+ base.set(normalized.success, content);
943
+ }
944
+ return base;
945
+ }),
946
+ baseline: Effect.fn("WorkspaceSandbox.baseline")(function* (path) {
947
+ const content = yield* readIfPresent(hostPath(path));
948
+ return content === undefined ? undefined : yield* digestOf(content);
949
+ }),
950
+ // The bytes now live at the change's `afterDigest`; the change itself
951
+ // carries only the reference, exactly as oversized `StepBoundary`
952
+ // evidence does.
953
+ retain: (bytes) => bytes.length <= maxInlineBytes
954
+ ? Effect.succeed(bytes)
955
+ : artifacts.put(bytes).pipe(Effect.mapError(artifactFailure), Effect.as(undefined)),
956
+ commit: (changes) => withCommitLock(changes, (host) => commitWith(host, changes))
957
+ });
958
+ };
959
+ /**
960
+ * Provides the filesystem-backed workspace sandbox.
961
+ *
962
+ * Host access arrives through Effect's `FileSystem` tag — the same tag the
963
+ * capability kernel decorates in place — and blob retention through
964
+ * `@smthrs/artifacts`, so the same sandbox runs over a purely local store or a
965
+ * local-plus-shared composition without knowing which it got. The workspace
966
+ * root arrives through the kernel's `Workspace` service, so absolute paths a
967
+ * body resolved for itself still land inside the transaction.
968
+ *
969
+ * The layer refuses to build over a host that {@link makeFileSystem} could
970
+ * not confine (a plain path-based `FileSystem`), failing with
971
+ * `host_unavailable`, so a composition that could never copy back safely is
972
+ * rejected at startup rather than at its first commit.
973
+ *
974
+ * @category layers
975
+ * @since 0.1.0
976
+ */
977
+ export const layerFileSystem = (options = {}) => Layer.effect(WorkspaceSandbox, Effect.gen(function* () {
978
+ const fs = yield* FileSystem.FileSystem;
979
+ const platformPath = yield* Path.Path;
980
+ const artifacts = yield* ArtifactStore.ArtifactStore;
981
+ const workspace = yield* KernelWorkspace;
982
+ yield* KernelFileSystem.requireConfinable(fs, workspace.root).pipe(Effect.mapError(hostFailure));
983
+ return makeFileSystem(fs, platformPath, artifacts, workspace.root, options);
984
+ }));
985
+ //# sourceMappingURL=WorkspaceSandbox.js.map