@smthrs/flow 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 (654) hide show
  1. package/CHANGELOG.md +160 -0
  2. package/LICENSE +21 -0
  3. package/README.md +210 -2
  4. package/THIRD_PARTY_NOTICES.md +52 -0
  5. package/dist/cjs/Action/Action.d.ts +250 -0
  6. package/dist/cjs/Action/Action.d.ts.map +1 -0
  7. package/dist/cjs/Action/Action.js +42 -0
  8. package/dist/cjs/Action/Action.js.map +7 -0
  9. package/dist/cjs/Action/AttemptTimedOut.d.ts +33 -0
  10. package/dist/cjs/Action/AttemptTimedOut.d.ts.map +1 -0
  11. package/dist/cjs/Action/AttemptTimedOut.js +51 -0
  12. package/dist/cjs/Action/AttemptTimedOut.js.map +7 -0
  13. package/dist/cjs/Action/BoundaryMode.d.ts +29 -0
  14. package/dist/cjs/Action/BoundaryMode.d.ts.map +1 -0
  15. package/dist/cjs/Action/BoundaryMode.js +36 -0
  16. package/dist/cjs/Action/BoundaryMode.js.map +7 -0
  17. package/dist/cjs/Action/CacheEnvironment.d.ts +158 -0
  18. package/dist/cjs/Action/CacheEnvironment.d.ts.map +1 -0
  19. package/dist/cjs/Action/CacheEnvironment.js +57 -0
  20. package/dist/cjs/Action/CacheEnvironment.js.map +7 -0
  21. package/dist/cjs/Action/ConcurrentKeylessDispatch.d.ts +34 -0
  22. package/dist/cjs/Action/ConcurrentKeylessDispatch.d.ts.map +1 -0
  23. package/dist/cjs/Action/ConcurrentKeylessDispatch.js +46 -0
  24. package/dist/cjs/Action/ConcurrentKeylessDispatch.js.map +7 -0
  25. package/dist/cjs/Action/Context.d.ts +131 -0
  26. package/dist/cjs/Action/Context.d.ts.map +1 -0
  27. package/dist/cjs/Action/Context.js +68 -0
  28. package/dist/cjs/Action/Context.js.map +7 -0
  29. package/dist/cjs/Action/DuplicateImplementation.d.ts +20 -0
  30. package/dist/cjs/Action/DuplicateImplementation.d.ts.map +1 -0
  31. package/dist/cjs/Action/DuplicateImplementation.js +46 -0
  32. package/dist/cjs/Action/DuplicateImplementation.js.map +7 -0
  33. package/dist/cjs/Action/FileBoundary.d.ts +59 -0
  34. package/dist/cjs/Action/FileBoundary.d.ts.map +1 -0
  35. package/dist/cjs/Action/FileBoundary.js +81 -0
  36. package/dist/cjs/Action/FileBoundary.js.map +7 -0
  37. package/dist/cjs/Action/FileInput.d.ts +28 -0
  38. package/dist/cjs/Action/FileInput.d.ts.map +1 -0
  39. package/dist/cjs/Action/FileInput.js +42 -0
  40. package/dist/cjs/Action/FileInput.js.map +7 -0
  41. package/dist/cjs/Action/Filegroup.d.ts +16 -0
  42. package/dist/cjs/Action/Filegroup.d.ts.map +1 -0
  43. package/dist/cjs/Action/Filegroup.js +27 -0
  44. package/dist/cjs/Action/Filegroup.js.map +7 -0
  45. package/dist/cjs/Action/Glob.d.ts +8 -0
  46. package/dist/cjs/Action/Glob.d.ts.map +1 -0
  47. package/dist/cjs/Action/Glob.js +28 -0
  48. package/dist/cjs/Action/Glob.js.map +7 -0
  49. package/dist/cjs/Action/ImplementationVersionMismatch.d.ts +26 -0
  50. package/dist/cjs/Action/ImplementationVersionMismatch.d.ts.map +1 -0
  51. package/dist/cjs/Action/ImplementationVersionMismatch.js +45 -0
  52. package/dist/cjs/Action/ImplementationVersionMismatch.js.map +7 -0
  53. package/dist/cjs/Action/Implementations.d.ts +114 -0
  54. package/dist/cjs/Action/Implementations.d.ts.map +1 -0
  55. package/dist/cjs/Action/Implementations.js +65 -0
  56. package/dist/cjs/Action/Implementations.js.map +7 -0
  57. package/dist/cjs/Action/InfraInterrupt.d.ts +26 -0
  58. package/dist/cjs/Action/InfraInterrupt.d.ts.map +1 -0
  59. package/dist/cjs/Action/InfraInterrupt.js +46 -0
  60. package/dist/cjs/Action/InfraInterrupt.js.map +7 -0
  61. package/dist/cjs/Action/InfraInterruptRetriesExhausted.d.ts +33 -0
  62. package/dist/cjs/Action/InfraInterruptRetriesExhausted.d.ts.map +1 -0
  63. package/dist/cjs/Action/InfraInterruptRetriesExhausted.js +54 -0
  64. package/dist/cjs/Action/InfraInterruptRetriesExhausted.js.map +7 -0
  65. package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts +26 -0
  66. package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts.map +1 -0
  67. package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.js +47 -0
  68. package/dist/cjs/Action/IrreversibleRetryRequiresIdempotencyKey.js.map +7 -0
  69. package/dist/cjs/Action/StepIdentity.d.ts +153 -0
  70. package/dist/cjs/Action/StepIdentity.d.ts.map +1 -0
  71. package/dist/cjs/Action/StepIdentity.js +75 -0
  72. package/dist/cjs/Action/StepIdentity.js.map +7 -0
  73. package/dist/cjs/Action/TreeArtifact.d.ts +8 -0
  74. package/dist/cjs/Action/TreeArtifact.d.ts.map +1 -0
  75. package/dist/cjs/Action/TreeArtifact.js +25 -0
  76. package/dist/cjs/Action/TreeArtifact.js.map +7 -0
  77. package/dist/cjs/Action/TypeId.d.ts +8 -0
  78. package/dist/cjs/Action/TypeId.d.ts.map +1 -0
  79. package/dist/cjs/Action/TypeId.js +25 -0
  80. package/dist/cjs/Action/TypeId.js.map +7 -0
  81. package/dist/cjs/Action/UncanonicalIdempotencyKey.d.ts +32 -0
  82. package/dist/cjs/Action/UncanonicalIdempotencyKey.d.ts.map +1 -0
  83. package/dist/cjs/Action/UncanonicalIdempotencyKey.js +51 -0
  84. package/dist/cjs/Action/UncanonicalIdempotencyKey.js.map +7 -0
  85. package/dist/cjs/Action/idempotencyKey.d.ts +21 -0
  86. package/dist/cjs/Action/idempotencyKey.d.ts.map +1 -0
  87. package/dist/cjs/Action/idempotencyKey.js +59 -0
  88. package/dist/cjs/Action/idempotencyKey.js.map +7 -0
  89. package/dist/cjs/Action/index.d.ts +29 -0
  90. package/dist/cjs/Action/index.d.ts.map +1 -0
  91. package/dist/cjs/Action/index.js +60 -0
  92. package/dist/cjs/Action/index.js.map +7 -0
  93. package/dist/cjs/Action/make.d.ts +128 -0
  94. package/dist/cjs/Action/make.d.ts.map +1 -0
  95. package/dist/cjs/Action/make.js +373 -0
  96. package/dist/cjs/Action/make.js.map +7 -0
  97. package/dist/cjs/Action/raceAll.d.ts +21 -0
  98. package/dist/cjs/Action/raceAll.d.ts.map +1 -0
  99. package/dist/cjs/Action/raceAll.js +46 -0
  100. package/dist/cjs/Action/raceAll.js.map +7 -0
  101. package/dist/cjs/Action/retry.d.ts +19 -0
  102. package/dist/cjs/Action/retry.d.ts.map +1 -0
  103. package/dist/cjs/Action/retry.js +75 -0
  104. package/dist/cjs/Action/retry.js.map +7 -0
  105. package/dist/cjs/Deadline.d.ts +105 -0
  106. package/dist/cjs/Deadline.d.ts.map +1 -0
  107. package/dist/cjs/Deadline.js +104 -0
  108. package/dist/cjs/Deadline.js.map +7 -0
  109. package/dist/cjs/DurableClock.d.ts +61 -0
  110. package/dist/cjs/DurableClock.d.ts.map +1 -0
  111. package/dist/cjs/DurableClock.js +90 -0
  112. package/dist/cjs/DurableClock.js.map +7 -0
  113. package/dist/cjs/DurableDeferred.d.ts +311 -0
  114. package/dist/cjs/DurableDeferred.d.ts.map +1 -0
  115. package/dist/cjs/DurableDeferred.js +322 -0
  116. package/dist/cjs/DurableDeferred.js.map +7 -0
  117. package/dist/cjs/DurableQueue.d.ts +160 -0
  118. package/dist/cjs/DurableQueue.d.ts.map +1 -0
  119. package/dist/cjs/DurableQueue.js +229 -0
  120. package/dist/cjs/DurableQueue.js.map +7 -0
  121. package/dist/cjs/ExternalJob.d.ts +179 -0
  122. package/dist/cjs/ExternalJob.d.ts.map +1 -0
  123. package/dist/cjs/ExternalJob.js +338 -0
  124. package/dist/cjs/ExternalJob.js.map +7 -0
  125. package/dist/cjs/Fault.d.ts +131 -0
  126. package/dist/cjs/Fault.d.ts.map +1 -0
  127. package/dist/cjs/Fault.js +157 -0
  128. package/dist/cjs/Fault.js.map +7 -0
  129. package/dist/cjs/Flow/Annotations.d.ts +245 -0
  130. package/dist/cjs/Flow/Annotations.d.ts.map +1 -0
  131. package/dist/cjs/Flow/Annotations.js +72 -0
  132. package/dist/cjs/Flow/Annotations.js.map +7 -0
  133. package/dist/cjs/Flow/CapabilityCeiling.d.ts +21 -0
  134. package/dist/cjs/Flow/CapabilityCeiling.d.ts.map +1 -0
  135. package/dist/cjs/Flow/CapabilityCeiling.js +49 -0
  136. package/dist/cjs/Flow/CapabilityCeiling.js.map +7 -0
  137. package/dist/cjs/Flow/DeadlineExceeded.d.ts +33 -0
  138. package/dist/cjs/Flow/DeadlineExceeded.d.ts.map +1 -0
  139. package/dist/cjs/Flow/DeadlineExceeded.js +52 -0
  140. package/dist/cjs/Flow/DeadlineExceeded.js.map +7 -0
  141. package/dist/cjs/Flow/ExecutionIdRequired.d.ts +25 -0
  142. package/dist/cjs/Flow/ExecutionIdRequired.d.ts.map +1 -0
  143. package/dist/cjs/Flow/ExecutionIdRequired.js +46 -0
  144. package/dist/cjs/Flow/ExecutionIdRequired.js.map +7 -0
  145. package/dist/cjs/Flow/ExecutionIds.d.ts +80 -0
  146. package/dist/cjs/Flow/ExecutionIds.d.ts.map +1 -0
  147. package/dist/cjs/Flow/ExecutionIds.js +66 -0
  148. package/dist/cjs/Flow/ExecutionIds.js.map +7 -0
  149. package/dist/cjs/Flow/Flow.d.ts +422 -0
  150. package/dist/cjs/Flow/Flow.d.ts.map +1 -0
  151. package/dist/cjs/Flow/Flow.js +17 -0
  152. package/dist/cjs/Flow/Flow.js.map +7 -0
  153. package/dist/cjs/Flow/MaxRoundsExceeded.d.ts +35 -0
  154. package/dist/cjs/Flow/MaxRoundsExceeded.d.ts.map +1 -0
  155. package/dist/cjs/Flow/MaxRoundsExceeded.js +50 -0
  156. package/dist/cjs/Flow/MaxRoundsExceeded.js.map +7 -0
  157. package/dist/cjs/Flow/Outcome.d.ts +162 -0
  158. package/dist/cjs/Flow/Outcome.d.ts.map +1 -0
  159. package/dist/cjs/Flow/Outcome.js +80 -0
  160. package/dist/cjs/Flow/Outcome.js.map +7 -0
  161. package/dist/cjs/Flow/Result.d.ts +186 -0
  162. package/dist/cjs/Flow/Result.d.ts.map +1 -0
  163. package/dist/cjs/Flow/Result.js +159 -0
  164. package/dist/cjs/Flow/Result.js.map +7 -0
  165. package/dist/cjs/Flow/Runtime.d.ts +98 -0
  166. package/dist/cjs/Flow/Runtime.d.ts.map +1 -0
  167. package/dist/cjs/Flow/Runtime.js +160 -0
  168. package/dist/cjs/Flow/Runtime.js.map +7 -0
  169. package/dist/cjs/Flow/TypeId.d.ts +8 -0
  170. package/dist/cjs/Flow/TypeId.d.ts.map +1 -0
  171. package/dist/cjs/Flow/TypeId.js +25 -0
  172. package/dist/cjs/Flow/TypeId.js.map +7 -0
  173. package/dist/cjs/Flow/index.d.ts +17 -0
  174. package/dist/cjs/Flow/index.d.ts.map +1 -0
  175. package/dist/cjs/Flow/index.js +29 -0
  176. package/dist/cjs/Flow/index.js.map +7 -0
  177. package/dist/cjs/Flow/internal.d.ts +34 -0
  178. package/dist/cjs/Flow/internal.d.ts.map +1 -0
  179. package/dist/cjs/Flow/internal.js +187 -0
  180. package/dist/cjs/Flow/internal.js.map +7 -0
  181. package/dist/cjs/Flow/make.d.ts +134 -0
  182. package/dist/cjs/Flow/make.d.ts.map +1 -0
  183. package/dist/cjs/Flow/make.js +104 -0
  184. package/dist/cjs/Flow/make.js.map +7 -0
  185. package/dist/cjs/FlowRuntime/CancelRequestFailed.d.ts +55 -0
  186. package/dist/cjs/FlowRuntime/CancelRequestFailed.d.ts.map +1 -0
  187. package/dist/cjs/FlowRuntime/CancelRequestFailed.js +51 -0
  188. package/dist/cjs/FlowRuntime/CancelRequestFailed.js.map +7 -0
  189. package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.d.ts +23 -0
  190. package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.d.ts.map +1 -0
  191. package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.js +55 -0
  192. package/dist/cjs/FlowRuntime/ExecutionIdentityConflict.js.map +7 -0
  193. package/dist/cjs/FlowRuntime/FlowCycleDetected.d.ts +28 -0
  194. package/dist/cjs/FlowRuntime/FlowCycleDetected.d.ts.map +1 -0
  195. package/dist/cjs/FlowRuntime/FlowCycleDetected.js +49 -0
  196. package/dist/cjs/FlowRuntime/FlowCycleDetected.js.map +7 -0
  197. package/dist/cjs/FlowRuntime/FlowExecutionNotFound.d.ts +38 -0
  198. package/dist/cjs/FlowRuntime/FlowExecutionNotFound.d.ts.map +1 -0
  199. package/dist/cjs/FlowRuntime/FlowExecutionNotFound.js +53 -0
  200. package/dist/cjs/FlowRuntime/FlowExecutionNotFound.js.map +7 -0
  201. package/dist/cjs/FlowRuntime/FlowInstance.d.ts +115 -0
  202. package/dist/cjs/FlowRuntime/FlowInstance.d.ts.map +1 -0
  203. package/dist/cjs/FlowRuntime/FlowInstance.js +37 -0
  204. package/dist/cjs/FlowRuntime/FlowInstance.js.map +7 -0
  205. package/dist/cjs/FlowRuntime/FlowRuntime.d.ts +198 -0
  206. package/dist/cjs/FlowRuntime/FlowRuntime.d.ts.map +1 -0
  207. package/dist/cjs/FlowRuntime/FlowRuntime.js +37 -0
  208. package/dist/cjs/FlowRuntime/FlowRuntime.js.map +7 -0
  209. package/dist/cjs/FlowRuntime/NodeRecord.d.ts +175 -0
  210. package/dist/cjs/FlowRuntime/NodeRecord.d.ts.map +1 -0
  211. package/dist/cjs/FlowRuntime/NodeRecord.js +17 -0
  212. package/dist/cjs/FlowRuntime/NodeRecord.js.map +7 -0
  213. package/dist/cjs/FlowRuntime/WaitingAnnotation.d.ts +69 -0
  214. package/dist/cjs/FlowRuntime/WaitingAnnotation.d.ts.map +1 -0
  215. package/dist/cjs/FlowRuntime/WaitingAnnotation.js +53 -0
  216. package/dist/cjs/FlowRuntime/WaitingAnnotation.js.map +7 -0
  217. package/dist/cjs/FlowRuntime/index.d.ts +14 -0
  218. package/dist/cjs/FlowRuntime/index.d.ts.map +1 -0
  219. package/dist/cjs/FlowRuntime/index.js +26 -0
  220. package/dist/cjs/FlowRuntime/index.js.map +7 -0
  221. package/dist/cjs/Graph.d.ts +325 -0
  222. package/dist/cjs/Graph.d.ts.map +1 -0
  223. package/dist/cjs/Graph.js +1021 -0
  224. package/dist/cjs/Graph.js.map +7 -0
  225. package/dist/cjs/HumanTask.d.ts +440 -0
  226. package/dist/cjs/HumanTask.d.ts.map +1 -0
  227. package/dist/cjs/HumanTask.js +413 -0
  228. package/dist/cjs/HumanTask.js.map +7 -0
  229. package/dist/cjs/Interpreter.d.ts +222 -0
  230. package/dist/cjs/Interpreter.d.ts.map +1 -0
  231. package/dist/cjs/Interpreter.js +888 -0
  232. package/dist/cjs/Interpreter.js.map +7 -0
  233. package/dist/cjs/Poll.d.ts +238 -0
  234. package/dist/cjs/Poll.d.ts.map +1 -0
  235. package/dist/cjs/Poll.js +150 -0
  236. package/dist/cjs/Poll.js.map +7 -0
  237. package/dist/cjs/RetryPolicy.d.ts +273 -0
  238. package/dist/cjs/RetryPolicy.d.ts.map +1 -0
  239. package/dist/cjs/RetryPolicy.js +251 -0
  240. package/dist/cjs/RetryPolicy.js.map +7 -0
  241. package/dist/cjs/Sleep.d.ts +98 -0
  242. package/dist/cjs/Sleep.d.ts.map +1 -0
  243. package/dist/cjs/Sleep.js +133 -0
  244. package/dist/cjs/Sleep.js.map +7 -0
  245. package/dist/cjs/Stall.d.ts +173 -0
  246. package/dist/cjs/Stall.d.ts.map +1 -0
  247. package/dist/cjs/Stall.js +92 -0
  248. package/dist/cjs/Stall.js.map +7 -0
  249. package/dist/cjs/WaitFor.d.ts +109 -0
  250. package/dist/cjs/WaitFor.d.ts.map +1 -0
  251. package/dist/cjs/WaitFor.js +117 -0
  252. package/dist/cjs/WaitFor.js.map +7 -0
  253. package/dist/cjs/index.d.ts +107 -0
  254. package/dist/cjs/index.d.ts.map +1 -0
  255. package/dist/cjs/index.js +69 -0
  256. package/dist/cjs/index.js.map +7 -0
  257. package/dist/cjs/internal/BoundedJson.d.ts +48 -0
  258. package/dist/cjs/internal/BoundedJson.d.ts.map +1 -0
  259. package/dist/cjs/internal/BoundedJson.js +96 -0
  260. package/dist/cjs/internal/BoundedJson.js.map +7 -0
  261. package/dist/cjs/internal/DeclarationSite.d.ts +135 -0
  262. package/dist/cjs/internal/DeclarationSite.d.ts.map +1 -0
  263. package/dist/cjs/internal/DeclarationSite.js +89 -0
  264. package/dist/cjs/internal/DeclarationSite.js.map +7 -0
  265. package/dist/cjs/internal/Declarations.d.ts +35 -0
  266. package/dist/cjs/internal/Declarations.d.ts.map +1 -0
  267. package/dist/cjs/internal/Declarations.js +50 -0
  268. package/dist/cjs/internal/Declarations.js.map +7 -0
  269. package/dist/cjs/internal/ExecutionMiddleware.d.ts +21 -0
  270. package/dist/cjs/internal/ExecutionMiddleware.d.ts.map +1 -0
  271. package/dist/cjs/internal/ExecutionMiddleware.js +39 -0
  272. package/dist/cjs/internal/ExecutionMiddleware.js.map +7 -0
  273. package/dist/cjs/internal/JsonSchemaSubset.d.ts +133 -0
  274. package/dist/cjs/internal/JsonSchemaSubset.d.ts.map +1 -0
  275. package/dist/cjs/internal/JsonSchemaSubset.js +229 -0
  276. package/dist/cjs/internal/JsonSchemaSubset.js.map +7 -0
  277. package/dist/cjs/internal/OutcomeMarker.d.ts +18 -0
  278. package/dist/cjs/internal/OutcomeMarker.d.ts.map +1 -0
  279. package/dist/cjs/internal/OutcomeMarker.js +27 -0
  280. package/dist/cjs/internal/OutcomeMarker.js.map +7 -0
  281. package/dist/cjs/package.json +1 -0
  282. package/dist/esm/Action/Action.d.ts +250 -0
  283. package/dist/esm/Action/Action.d.ts.map +1 -0
  284. package/dist/esm/Action/Action.js +30 -0
  285. package/dist/esm/Action/Action.js.map +1 -0
  286. package/dist/esm/Action/AttemptTimedOut.d.ts +33 -0
  287. package/dist/esm/Action/AttemptTimedOut.d.ts.map +1 -0
  288. package/dist/esm/Action/AttemptTimedOut.js +32 -0
  289. package/dist/esm/Action/AttemptTimedOut.js.map +1 -0
  290. package/dist/esm/Action/BoundaryMode.d.ts +29 -0
  291. package/dist/esm/Action/BoundaryMode.d.ts.map +1 -0
  292. package/dist/esm/Action/BoundaryMode.js +23 -0
  293. package/dist/esm/Action/BoundaryMode.js.map +1 -0
  294. package/dist/esm/Action/CacheEnvironment.d.ts +158 -0
  295. package/dist/esm/Action/CacheEnvironment.d.ts.map +1 -0
  296. package/dist/esm/Action/CacheEnvironment.js +130 -0
  297. package/dist/esm/Action/CacheEnvironment.js.map +1 -0
  298. package/dist/esm/Action/ConcurrentKeylessDispatch.d.ts +34 -0
  299. package/dist/esm/Action/ConcurrentKeylessDispatch.d.ts.map +1 -0
  300. package/dist/esm/Action/ConcurrentKeylessDispatch.js +33 -0
  301. package/dist/esm/Action/ConcurrentKeylessDispatch.js.map +1 -0
  302. package/dist/esm/Action/Context.d.ts +131 -0
  303. package/dist/esm/Action/Context.d.ts.map +1 -0
  304. package/dist/esm/Action/Context.js +99 -0
  305. package/dist/esm/Action/Context.js.map +1 -0
  306. package/dist/esm/Action/DuplicateImplementation.d.ts +20 -0
  307. package/dist/esm/Action/DuplicateImplementation.d.ts.map +1 -0
  308. package/dist/esm/Action/DuplicateImplementation.js +20 -0
  309. package/dist/esm/Action/DuplicateImplementation.js.map +1 -0
  310. package/dist/esm/Action/FileBoundary.d.ts +59 -0
  311. package/dist/esm/Action/FileBoundary.d.ts.map +1 -0
  312. package/dist/esm/Action/FileBoundary.js +60 -0
  313. package/dist/esm/Action/FileBoundary.js.map +1 -0
  314. package/dist/esm/Action/FileInput.d.ts +28 -0
  315. package/dist/esm/Action/FileInput.d.ts.map +1 -0
  316. package/dist/esm/Action/FileInput.js +32 -0
  317. package/dist/esm/Action/FileInput.js.map +1 -0
  318. package/dist/esm/Action/Filegroup.d.ts +16 -0
  319. package/dist/esm/Action/Filegroup.d.ts.map +1 -0
  320. package/dist/esm/Action/Filegroup.js +15 -0
  321. package/dist/esm/Action/Filegroup.js.map +1 -0
  322. package/dist/esm/Action/Glob.d.ts +8 -0
  323. package/dist/esm/Action/Glob.d.ts.map +1 -0
  324. package/dist/esm/Action/Glob.js +7 -0
  325. package/dist/esm/Action/Glob.js.map +1 -0
  326. package/dist/esm/Action/ImplementationVersionMismatch.d.ts +26 -0
  327. package/dist/esm/Action/ImplementationVersionMismatch.d.ts.map +1 -0
  328. package/dist/esm/Action/ImplementationVersionMismatch.js +24 -0
  329. package/dist/esm/Action/ImplementationVersionMismatch.js.map +1 -0
  330. package/dist/esm/Action/Implementations.d.ts +114 -0
  331. package/dist/esm/Action/Implementations.d.ts.map +1 -0
  332. package/dist/esm/Action/Implementations.js +94 -0
  333. package/dist/esm/Action/Implementations.js.map +1 -0
  334. package/dist/esm/Action/InfraInterrupt.d.ts +26 -0
  335. package/dist/esm/Action/InfraInterrupt.d.ts.map +1 -0
  336. package/dist/esm/Action/InfraInterrupt.js +25 -0
  337. package/dist/esm/Action/InfraInterrupt.js.map +1 -0
  338. package/dist/esm/Action/InfraInterruptRetriesExhausted.d.ts +33 -0
  339. package/dist/esm/Action/InfraInterruptRetriesExhausted.d.ts.map +1 -0
  340. package/dist/esm/Action/InfraInterruptRetriesExhausted.js +32 -0
  341. package/dist/esm/Action/InfraInterruptRetriesExhausted.js.map +1 -0
  342. package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts +26 -0
  343. package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.d.ts.map +1 -0
  344. package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.js +25 -0
  345. package/dist/esm/Action/IrreversibleRetryRequiresIdempotencyKey.js.map +1 -0
  346. package/dist/esm/Action/StepIdentity.d.ts +153 -0
  347. package/dist/esm/Action/StepIdentity.d.ts.map +1 -0
  348. package/dist/esm/Action/StepIdentity.js +139 -0
  349. package/dist/esm/Action/StepIdentity.js.map +1 -0
  350. package/dist/esm/Action/TreeArtifact.d.ts +8 -0
  351. package/dist/esm/Action/TreeArtifact.d.ts.map +1 -0
  352. package/dist/esm/Action/TreeArtifact.js +7 -0
  353. package/dist/esm/Action/TreeArtifact.js.map +1 -0
  354. package/dist/esm/Action/TypeId.d.ts +8 -0
  355. package/dist/esm/Action/TypeId.d.ts.map +1 -0
  356. package/dist/esm/Action/TypeId.js +9 -0
  357. package/dist/esm/Action/TypeId.js.map +1 -0
  358. package/dist/esm/Action/UncanonicalIdempotencyKey.d.ts +32 -0
  359. package/dist/esm/Action/UncanonicalIdempotencyKey.d.ts.map +1 -0
  360. package/dist/esm/Action/UncanonicalIdempotencyKey.js +31 -0
  361. package/dist/esm/Action/UncanonicalIdempotencyKey.js.map +1 -0
  362. package/dist/esm/Action/idempotencyKey.d.ts +21 -0
  363. package/dist/esm/Action/idempotencyKey.d.ts.map +1 -0
  364. package/dist/esm/Action/idempotencyKey.js +50 -0
  365. package/dist/esm/Action/idempotencyKey.js.map +1 -0
  366. package/dist/esm/Action/index.d.ts +29 -0
  367. package/dist/esm/Action/index.d.ts.map +1 -0
  368. package/dist/esm/Action/index.js +30 -0
  369. package/dist/esm/Action/index.js.map +1 -0
  370. package/dist/esm/Action/make.d.ts +128 -0
  371. package/dist/esm/Action/make.d.ts.map +1 -0
  372. package/dist/esm/Action/make.js +405 -0
  373. package/dist/esm/Action/make.js.map +1 -0
  374. package/dist/esm/Action/raceAll.d.ts +21 -0
  375. package/dist/esm/Action/raceAll.d.ts.map +1 -0
  376. package/dist/esm/Action/raceAll.js +20 -0
  377. package/dist/esm/Action/raceAll.js.map +1 -0
  378. package/dist/esm/Action/retry.d.ts +19 -0
  379. package/dist/esm/Action/retry.d.ts.map +1 -0
  380. package/dist/esm/Action/retry.js +72 -0
  381. package/dist/esm/Action/retry.js.map +1 -0
  382. package/dist/esm/Deadline.d.ts +105 -0
  383. package/dist/esm/Deadline.d.ts.map +1 -0
  384. package/dist/esm/Deadline.js +152 -0
  385. package/dist/esm/Deadline.js.map +1 -0
  386. package/dist/esm/DurableClock.d.ts +61 -0
  387. package/dist/esm/DurableClock.d.ts.map +1 -0
  388. package/dist/esm/DurableClock.js +75 -0
  389. package/dist/esm/DurableClock.js.map +1 -0
  390. package/dist/esm/DurableDeferred.d.ts +311 -0
  391. package/dist/esm/DurableDeferred.d.ts.map +1 -0
  392. package/dist/esm/DurableDeferred.js +357 -0
  393. package/dist/esm/DurableDeferred.js.map +1 -0
  394. package/dist/esm/DurableQueue.d.ts +160 -0
  395. package/dist/esm/DurableQueue.d.ts.map +1 -0
  396. package/dist/esm/DurableQueue.js +303 -0
  397. package/dist/esm/DurableQueue.js.map +1 -0
  398. package/dist/esm/ExternalJob.d.ts +179 -0
  399. package/dist/esm/ExternalJob.d.ts.map +1 -0
  400. package/dist/esm/ExternalJob.js +296 -0
  401. package/dist/esm/ExternalJob.js.map +1 -0
  402. package/dist/esm/Fault.d.ts +131 -0
  403. package/dist/esm/Fault.d.ts.map +1 -0
  404. package/dist/esm/Fault.js +198 -0
  405. package/dist/esm/Fault.js.map +1 -0
  406. package/dist/esm/Flow/Annotations.d.ts +245 -0
  407. package/dist/esm/Flow/Annotations.d.ts.map +1 -0
  408. package/dist/esm/Flow/Annotations.js +110 -0
  409. package/dist/esm/Flow/Annotations.js.map +1 -0
  410. package/dist/esm/Flow/CapabilityCeiling.d.ts +21 -0
  411. package/dist/esm/Flow/CapabilityCeiling.d.ts.map +1 -0
  412. package/dist/esm/Flow/CapabilityCeiling.js +27 -0
  413. package/dist/esm/Flow/CapabilityCeiling.js.map +1 -0
  414. package/dist/esm/Flow/DeadlineExceeded.d.ts +33 -0
  415. package/dist/esm/Flow/DeadlineExceeded.d.ts.map +1 -0
  416. package/dist/esm/Flow/DeadlineExceeded.js +34 -0
  417. package/dist/esm/Flow/DeadlineExceeded.js.map +1 -0
  418. package/dist/esm/Flow/ExecutionIdRequired.d.ts +25 -0
  419. package/dist/esm/Flow/ExecutionIdRequired.d.ts.map +1 -0
  420. package/dist/esm/Flow/ExecutionIdRequired.js +30 -0
  421. package/dist/esm/Flow/ExecutionIdRequired.js.map +1 -0
  422. package/dist/esm/Flow/ExecutionIds.d.ts +80 -0
  423. package/dist/esm/Flow/ExecutionIds.d.ts.map +1 -0
  424. package/dist/esm/Flow/ExecutionIds.js +91 -0
  425. package/dist/esm/Flow/ExecutionIds.js.map +1 -0
  426. package/dist/esm/Flow/Flow.d.ts +422 -0
  427. package/dist/esm/Flow/Flow.d.ts.map +1 -0
  428. package/dist/esm/Flow/Flow.js +3 -0
  429. package/dist/esm/Flow/Flow.js.map +1 -0
  430. package/dist/esm/Flow/MaxRoundsExceeded.d.ts +35 -0
  431. package/dist/esm/Flow/MaxRoundsExceeded.d.ts.map +1 -0
  432. package/dist/esm/Flow/MaxRoundsExceeded.js +34 -0
  433. package/dist/esm/Flow/MaxRoundsExceeded.js.map +1 -0
  434. package/dist/esm/Flow/Outcome.d.ts +162 -0
  435. package/dist/esm/Flow/Outcome.d.ts.map +1 -0
  436. package/dist/esm/Flow/Outcome.js +115 -0
  437. package/dist/esm/Flow/Outcome.js.map +1 -0
  438. package/dist/esm/Flow/Result.d.ts +186 -0
  439. package/dist/esm/Flow/Result.d.ts.map +1 -0
  440. package/dist/esm/Flow/Result.js +171 -0
  441. package/dist/esm/Flow/Result.js.map +1 -0
  442. package/dist/esm/Flow/Runtime.d.ts +98 -0
  443. package/dist/esm/Flow/Runtime.d.ts.map +1 -0
  444. package/dist/esm/Flow/Runtime.js +231 -0
  445. package/dist/esm/Flow/Runtime.js.map +1 -0
  446. package/dist/esm/Flow/TypeId.d.ts +8 -0
  447. package/dist/esm/Flow/TypeId.d.ts.map +1 -0
  448. package/dist/esm/Flow/TypeId.js +9 -0
  449. package/dist/esm/Flow/TypeId.js.map +1 -0
  450. package/dist/esm/Flow/index.d.ts +17 -0
  451. package/dist/esm/Flow/index.d.ts.map +1 -0
  452. package/dist/esm/Flow/index.js +18 -0
  453. package/dist/esm/Flow/index.js.map +1 -0
  454. package/dist/esm/Flow/internal.d.ts +34 -0
  455. package/dist/esm/Flow/internal.d.ts.map +1 -0
  456. package/dist/esm/Flow/internal.js +149 -0
  457. package/dist/esm/Flow/internal.js.map +1 -0
  458. package/dist/esm/Flow/make.d.ts +134 -0
  459. package/dist/esm/Flow/make.d.ts.map +1 -0
  460. package/dist/esm/Flow/make.js +106 -0
  461. package/dist/esm/Flow/make.js.map +1 -0
  462. package/dist/esm/FlowRuntime/CancelRequestFailed.d.ts +55 -0
  463. package/dist/esm/FlowRuntime/CancelRequestFailed.d.ts.map +1 -0
  464. package/dist/esm/FlowRuntime/CancelRequestFailed.js +53 -0
  465. package/dist/esm/FlowRuntime/CancelRequestFailed.js.map +1 -0
  466. package/dist/esm/FlowRuntime/ExecutionIdentityConflict.d.ts +23 -0
  467. package/dist/esm/FlowRuntime/ExecutionIdentityConflict.d.ts.map +1 -0
  468. package/dist/esm/FlowRuntime/ExecutionIdentityConflict.js +24 -0
  469. package/dist/esm/FlowRuntime/ExecutionIdentityConflict.js.map +1 -0
  470. package/dist/esm/FlowRuntime/FlowCycleDetected.d.ts +28 -0
  471. package/dist/esm/FlowRuntime/FlowCycleDetected.d.ts.map +1 -0
  472. package/dist/esm/FlowRuntime/FlowCycleDetected.js +35 -0
  473. package/dist/esm/FlowRuntime/FlowCycleDetected.js.map +1 -0
  474. package/dist/esm/FlowRuntime/FlowExecutionNotFound.d.ts +38 -0
  475. package/dist/esm/FlowRuntime/FlowExecutionNotFound.d.ts.map +1 -0
  476. package/dist/esm/FlowRuntime/FlowExecutionNotFound.js +40 -0
  477. package/dist/esm/FlowRuntime/FlowExecutionNotFound.js.map +1 -0
  478. package/dist/esm/FlowRuntime/FlowInstance.d.ts +115 -0
  479. package/dist/esm/FlowRuntime/FlowInstance.d.ts.map +1 -0
  480. package/dist/esm/FlowRuntime/FlowInstance.js +24 -0
  481. package/dist/esm/FlowRuntime/FlowInstance.js.map +1 -0
  482. package/dist/esm/FlowRuntime/FlowRuntime.d.ts +198 -0
  483. package/dist/esm/FlowRuntime/FlowRuntime.d.ts.map +1 -0
  484. package/dist/esm/FlowRuntime/FlowRuntime.js +34 -0
  485. package/dist/esm/FlowRuntime/FlowRuntime.js.map +1 -0
  486. package/dist/esm/FlowRuntime/NodeRecord.d.ts +175 -0
  487. package/dist/esm/FlowRuntime/NodeRecord.d.ts.map +1 -0
  488. package/dist/esm/FlowRuntime/NodeRecord.js +21 -0
  489. package/dist/esm/FlowRuntime/NodeRecord.js.map +1 -0
  490. package/dist/esm/FlowRuntime/WaitingAnnotation.d.ts +69 -0
  491. package/dist/esm/FlowRuntime/WaitingAnnotation.d.ts.map +1 -0
  492. package/dist/esm/FlowRuntime/WaitingAnnotation.js +53 -0
  493. package/dist/esm/FlowRuntime/WaitingAnnotation.js.map +1 -0
  494. package/dist/esm/FlowRuntime/index.d.ts +14 -0
  495. package/dist/esm/FlowRuntime/index.d.ts.map +1 -0
  496. package/dist/esm/FlowRuntime/index.js +15 -0
  497. package/dist/esm/FlowRuntime/index.js.map +1 -0
  498. package/dist/esm/Graph.d.ts +325 -0
  499. package/dist/esm/Graph.d.ts.map +1 -0
  500. package/dist/esm/Graph.js +1483 -0
  501. package/dist/esm/Graph.js.map +1 -0
  502. package/dist/esm/HumanTask.d.ts +440 -0
  503. package/dist/esm/HumanTask.d.ts.map +1 -0
  504. package/dist/esm/HumanTask.js +794 -0
  505. package/dist/esm/HumanTask.js.map +1 -0
  506. package/dist/esm/Interpreter.d.ts +222 -0
  507. package/dist/esm/Interpreter.d.ts.map +1 -0
  508. package/dist/esm/Interpreter.js +1269 -0
  509. package/dist/esm/Interpreter.js.map +1 -0
  510. package/dist/esm/Poll.d.ts +238 -0
  511. package/dist/esm/Poll.d.ts.map +1 -0
  512. package/dist/esm/Poll.js +282 -0
  513. package/dist/esm/Poll.js.map +1 -0
  514. package/dist/esm/RetryPolicy.d.ts +273 -0
  515. package/dist/esm/RetryPolicy.d.ts.map +1 -0
  516. package/dist/esm/RetryPolicy.js +429 -0
  517. package/dist/esm/RetryPolicy.js.map +1 -0
  518. package/dist/esm/Sleep.d.ts +98 -0
  519. package/dist/esm/Sleep.d.ts.map +1 -0
  520. package/dist/esm/Sleep.js +230 -0
  521. package/dist/esm/Sleep.js.map +1 -0
  522. package/dist/esm/Stall.d.ts +173 -0
  523. package/dist/esm/Stall.d.ts.map +1 -0
  524. package/dist/esm/Stall.js +138 -0
  525. package/dist/esm/Stall.js.map +1 -0
  526. package/dist/esm/WaitFor.d.ts +109 -0
  527. package/dist/esm/WaitFor.d.ts.map +1 -0
  528. package/dist/esm/WaitFor.js +184 -0
  529. package/dist/esm/WaitFor.js.map +1 -0
  530. package/dist/esm/index.d.ts +107 -0
  531. package/dist/esm/index.d.ts.map +1 -0
  532. package/dist/esm/index.js +108 -0
  533. package/dist/esm/index.js.map +1 -0
  534. package/dist/esm/internal/BoundedJson.d.ts +48 -0
  535. package/dist/esm/internal/BoundedJson.d.ts.map +1 -0
  536. package/dist/esm/internal/BoundedJson.js +107 -0
  537. package/dist/esm/internal/BoundedJson.js.map +1 -0
  538. package/dist/esm/internal/DeclarationSite.d.ts +135 -0
  539. package/dist/esm/internal/DeclarationSite.d.ts.map +1 -0
  540. package/dist/esm/internal/DeclarationSite.js +196 -0
  541. package/dist/esm/internal/DeclarationSite.js.map +1 -0
  542. package/dist/esm/internal/Declarations.d.ts +35 -0
  543. package/dist/esm/internal/Declarations.d.ts.map +1 -0
  544. package/dist/esm/internal/Declarations.js +43 -0
  545. package/dist/esm/internal/Declarations.js.map +1 -0
  546. package/dist/esm/internal/ExecutionMiddleware.d.ts +21 -0
  547. package/dist/esm/internal/ExecutionMiddleware.d.ts.map +1 -0
  548. package/dist/esm/internal/ExecutionMiddleware.js +13 -0
  549. package/dist/esm/internal/ExecutionMiddleware.js.map +1 -0
  550. package/dist/esm/internal/JsonSchemaSubset.d.ts +133 -0
  551. package/dist/esm/internal/JsonSchemaSubset.d.ts.map +1 -0
  552. package/dist/esm/internal/JsonSchemaSubset.js +363 -0
  553. package/dist/esm/internal/JsonSchemaSubset.js.map +1 -0
  554. package/dist/esm/internal/OutcomeMarker.d.ts +18 -0
  555. package/dist/esm/internal/OutcomeMarker.d.ts.map +1 -0
  556. package/dist/esm/internal/OutcomeMarker.js +18 -0
  557. package/dist/esm/internal/OutcomeMarker.js.map +1 -0
  558. package/docs/README.md +150 -0
  559. package/docs/api.md +436 -0
  560. package/docs/concepts/bodies-and-plans.md +157 -0
  561. package/docs/concepts/execution-identity.md +142 -0
  562. package/docs/concepts/flows-and-actions.md +129 -0
  563. package/docs/concepts/suspension-and-replay.md +130 -0
  564. package/docs/concepts/the-runtime-port.md +110 -0
  565. package/docs/concepts/trampoline-rounds.md +151 -0
  566. package/docs/guides/ask-a-person.md +184 -0
  567. package/docs/guides/build-a-body.md +161 -0
  568. package/docs/guides/cancel-and-roll-back.md +112 -0
  569. package/docs/guides/implement-an-action.md +147 -0
  570. package/docs/guides/inspect-the-plan.md +154 -0
  571. package/docs/guides/poll-until-ready.md +167 -0
  572. package/docs/guides/queue-work-to-a-worker.md +122 -0
  573. package/docs/guides/retry-a-failing-action.md +243 -0
  574. package/docs/guides/reuse-a-recorded-result.md +122 -0
  575. package/docs/guides/run-a-child-flow.md +108 -0
  576. package/docs/guides/run-an-external-job.md +86 -0
  577. package/docs/guides/use-a-prompt.md +38 -0
  578. package/docs/guides/wait-for-a-deadline.md +141 -0
  579. package/docs/guides/wait-for-an-external-signal.md +151 -0
  580. package/docs/installation.md +82 -0
  581. package/docs/quickstart.md +155 -0
  582. package/docs/reference/flow.md +1831 -0
  583. package/docs/testing.md +157 -0
  584. package/docs/troubleshooting.md +286 -0
  585. package/package.json +327 -3
  586. package/src/Action/Action.ts +333 -0
  587. package/src/Action/AttemptTimedOut.ts +37 -0
  588. package/src/Action/BoundaryMode.ts +33 -0
  589. package/src/Action/CacheEnvironment.ts +170 -0
  590. package/src/Action/ConcurrentKeylessDispatch.ts +38 -0
  591. package/src/Action/Context.ts +156 -0
  592. package/src/Action/DuplicateImplementation.ts +24 -0
  593. package/src/Action/FileBoundary.ts +77 -0
  594. package/src/Action/FileInput.ts +42 -0
  595. package/src/Action/Filegroup.ts +16 -0
  596. package/src/Action/Glob.ts +8 -0
  597. package/src/Action/ImplementationVersionMismatch.ts +27 -0
  598. package/src/Action/Implementations.ts +149 -0
  599. package/src/Action/InfraInterrupt.ts +30 -0
  600. package/src/Action/InfraInterruptRetriesExhausted.ts +37 -0
  601. package/src/Action/IrreversibleRetryRequiresIdempotencyKey.ts +32 -0
  602. package/src/Action/StepIdentity.ts +219 -0
  603. package/src/Action/TreeArtifact.ts +8 -0
  604. package/src/Action/TypeId.ts +9 -0
  605. package/src/Action/UncanonicalIdempotencyKey.ts +36 -0
  606. package/src/Action/idempotencyKey.ts +67 -0
  607. package/src/Action/index.ts +31 -0
  608. package/src/Action/make.ts +657 -0
  609. package/src/Action/raceAll.ts +48 -0
  610. package/src/Action/retry.ts +92 -0
  611. package/src/Deadline.ts +185 -0
  612. package/src/DurableClock.ts +133 -0
  613. package/src/DurableDeferred.ts +753 -0
  614. package/src/DurableQueue.ts +519 -0
  615. package/src/ExternalJob.ts +432 -0
  616. package/src/Fault.ts +279 -0
  617. package/src/Flow/Annotations.ts +151 -0
  618. package/src/Flow/CapabilityCeiling.ts +37 -0
  619. package/src/Flow/DeadlineExceeded.ts +40 -0
  620. package/src/Flow/ExecutionIdRequired.ts +36 -0
  621. package/src/Flow/ExecutionIds.ts +133 -0
  622. package/src/Flow/Flow.ts +576 -0
  623. package/src/Flow/MaxRoundsExceeded.ts +39 -0
  624. package/src/Flow/Outcome.ts +179 -0
  625. package/src/Flow/Result.ts +284 -0
  626. package/src/Flow/Runtime.ts +309 -0
  627. package/src/Flow/TypeId.ts +9 -0
  628. package/src/Flow/index.ts +19 -0
  629. package/src/Flow/internal.ts +237 -0
  630. package/src/Flow/make.ts +279 -0
  631. package/src/FlowRuntime/CancelRequestFailed.ts +56 -0
  632. package/src/FlowRuntime/ExecutionIdentityConflict.ts +32 -0
  633. package/src/FlowRuntime/FlowCycleDetected.ts +41 -0
  634. package/src/FlowRuntime/FlowExecutionNotFound.ts +46 -0
  635. package/src/FlowRuntime/FlowInstance.ts +128 -0
  636. package/src/FlowRuntime/FlowRuntime.ts +333 -0
  637. package/src/FlowRuntime/NodeRecord.ts +183 -0
  638. package/src/FlowRuntime/WaitingAnnotation.ts +85 -0
  639. package/src/FlowRuntime/index.ts +17 -0
  640. package/src/Graph.ts +1862 -0
  641. package/src/HumanTask.ts +1003 -0
  642. package/src/Interpreter.ts +1593 -0
  643. package/src/Poll.ts +414 -0
  644. package/src/RetryPolicy.ts +550 -0
  645. package/src/Sleep.ts +267 -0
  646. package/src/Stall.ts +217 -0
  647. package/src/WaitFor.ts +228 -0
  648. package/src/index.ts +125 -0
  649. package/src/internal/BoundedJson.ts +109 -0
  650. package/src/internal/DeclarationSite.ts +214 -0
  651. package/src/internal/Declarations.ts +49 -0
  652. package/src/internal/ExecutionMiddleware.ts +29 -0
  653. package/src/internal/JsonSchemaSubset.ts +392 -0
  654. package/src/internal/OutcomeMarker.ts +19 -0
@@ -0,0 +1,1483 @@
1
+ /**
2
+ * Graph building: a flow declaration plus a real payload, walked once into the
3
+ * drafts a plan is compiled from.
4
+ *
5
+ * This is the plan phase of `docs/concepts/bodies-and-plans.md` and nothing
6
+ * else — no I/O, no execution, no elaboration. {@link build} evaluates the
7
+ * body with the REAL payload, because a body's own payload is data
8
+ * (`docs/concepts/flows-and-actions.md`), and evaluates every
9
+ * continuation and branch arm exactly once against a STRICT
10
+ * {@link module:Planned.Planned} placeholder, because a step result does not
11
+ * exist yet. A body that computes on a placeholder therefore fails here,
12
+ * naming the node, rather than baking `NaN` into a plan.
13
+ *
14
+ * Fatal refusals stay fatal. Computing on a planned value throws its
15
+ * `GraphBuildError` immediately, as does recursively expanding an inline
16
+ * `.call()`, because either case makes the requested graph invalid. Recoverable
17
+ * topology loss, such as a missing or invalid continuation, is reported in
18
+ * {@link Graph.diagnostics} so the remaining graph can still be inspected.
19
+ *
20
+ * The walk is stack-safe by construction: topology and payloads are traversed
21
+ * with explicit stacks, never native recursion, and each carries a nesting
22
+ * bound. Topology past the bound is a typed `graph_too_deep` refusal, a
23
+ * payload past it is `payload_too_deep`, and a payload containing itself is
24
+ * `cyclic_payload` — all three fail loudly where unbounded recursion would
25
+ * overflow the native stack without a typed error.
26
+ *
27
+ * Composition follows the same note: `Other.call(payload)` splices the
28
+ * callee's body into this graph with the capabilities of the two declarations
29
+ * intersected, and a flow that calls itself inline throws with the trampoline
30
+ * (`docs/concepts/trampoline-rounds.md`) and the child boundary as the two
31
+ * ways out. A callee whose declared placement the enclosing flow does not carry
32
+ * throws for the same reason and names the same way out, because inline
33
+ * expansion is the claim that these steps run in the caller's execution.
34
+ * `Other.child(payload)` is that boundary: one leaf node here, its own
35
+ * execution when the graph is driven. A branch expands BOTH arms, so the
36
+ * exit condition and the handoff site are visible topology before anything
37
+ * runs, and the predicate rides the branch's key material as a digest.
38
+ *
39
+ * What comes out is `@smthrs/plan` shaped: {@link Graph.drafts} feeds
40
+ * `Plan.compile` and `Plan.append` unchanged, and the `Ref`/`Pending` inputs a
41
+ * node's key material names are what the compiler turns into dependency
42
+ * digests and the plan turns into edges. Structural node ids are derived only
43
+ * from traversal positions and do not enter a plan draft's hashed value, so
44
+ * editing a mapper re-keys exactly what reads it. The interpreter does use an
45
+ * `ActionCall` id as durable dispatch-site material: it is the replay-stable
46
+ * discriminator that keeps identical declarations at distinct graph
47
+ * positions out of one arrival-ordered ordinal scope.
48
+ *
49
+ * Adapted from the agent repo's `@smthrs/core` `Graph.ts`. The lenient
50
+ * placeholder, the model-shaped `Dynamic` node, the lane-merge elaboration,
51
+ * and the conflict pass do not come across: the placeholder is strict here,
52
+ * a model call is an ordinary action, and write overlap is resolved by
53
+ * `Plan.compile`, which owns that verdict.
54
+ *
55
+ * @since 0.1.0
56
+ */
57
+ import * as Capability from "@smthrs/capability/Capability";
58
+ import * as Effects from "@smthrs/plan/Effects";
59
+ import { GraphBuildError, isFatalDiagnostic } from "@smthrs/plan/GraphBuildError";
60
+ import * as KeyMaterial from "@smthrs/plan/KeyMaterial";
61
+ import * as Node from "@smthrs/plan/Node";
62
+ import * as Planned from "@smthrs/plan/Planned";
63
+ import * as Context from "effect/Context";
64
+ import * as Option from "effect/Option";
65
+ import * as Predicate from "effect/Predicate";
66
+ import * as Schema from "effect/Schema";
67
+ import { TypeId as ActionTypeId } from "./Action/TypeId.js";
68
+ import * as Annotations from "./Flow/Annotations.js";
69
+ import { capabilityCeilings } from "./Flow/CapabilityCeiling.js";
70
+ import { TypeId as FlowTypeId } from "./Flow/TypeId.js";
71
+ import * as DeclarationSite from "./internal/DeclarationSite.js";
72
+ import { OutcomeNodeTypeId, OutcomeValueTypeId } from "./internal/OutcomeMarker.js";
73
+ /**
74
+ * What a node that declared nothing contributes: it claims no path either way,
75
+ * so `expected` is the honest default.
76
+ *
77
+ * @private
78
+ */
79
+ const emptyEffects = { reads: [], writes: [], boundaryMode: "expected" };
80
+ /** @private */
81
+ const sorted = (values) => [...new Set(values)].sort();
82
+ /** @private */
83
+ const flowDeclaration = (value) => Predicate.hasProperty(value, FlowTypeId) ? value : undefined;
84
+ /** @private */
85
+ const actionDeclaration = (value) => Predicate.hasProperty(value, ActionTypeId) ? value : undefined;
86
+ /** @private */
87
+ const declaredEffects = (annotations) => Option.getOrUndefined(Context.getOption(annotations, Annotations.EffectsDeclaration));
88
+ /** @private */
89
+ const declaredPlacement = (annotations) => Option.getOrUndefined(Context.getOption(annotations, Annotations.Placement));
90
+ /** @private */
91
+ const declaredEnvelope = (annotations) => Option.getOrUndefined(Context.getOption(annotations, Annotations.EffectEnvelope));
92
+ /**
93
+ * What an author reads when a declaration claimed more authority than the one
94
+ * enclosing it granted. Each of the three states the claim, names the flow
95
+ * whose envelope it escaped, and says the one thing that fixes it, because an
96
+ * author who widened an envelope by accident needs the narrowing, not a
97
+ * classification.
98
+ *
99
+ * @private
100
+ */
101
+ const refusalMessage = (narrowed, site) => {
102
+ const at = `"${site.flow}" at "${site.id}"`;
103
+ switch (narrowed.code) {
104
+ case "effect_outside_envelope":
105
+ return `Flow ${at} declares ${narrowed.paths.length === 1 ? "a path" : "paths"} its caller's effect ` +
106
+ `envelope does not cover: ${narrowed.paths.join(", ")}. Widen the caller's declared effects to cover ` +
107
+ "them, or narrow this declaration to what the envelope already allows.";
108
+ case "effect_mode_widening":
109
+ return `Flow ${at} declares an expected effect mode inside a hermetic envelope. A hermetic envelope is ` +
110
+ "the claim that every effect beneath it is declared, so the callee has to declare a hermetic mode too.";
111
+ case "effect_tier_widening":
112
+ return `Flow ${at} declares an effect tier its caller's envelope does not permit. A tier may only narrow ` +
113
+ "from irreversible to compensable to sealed, so raise the caller's tier or lower this one.";
114
+ }
115
+ };
116
+ /**
117
+ * The declaration identity that enters a call node's hashed body: what the
118
+ * callee accepts and produces, so a schema change re-keys the call.
119
+ *
120
+ * The identity is JSON-Schema-SHAPED, and that is its stated limit. Two
121
+ * schemas whose decoders disagree can serialize to the same document, because
122
+ * an effect transformation carries behaviour a JSON Schema document does not
123
+ * describe. Changing only a codec's behaviour therefore does NOT re-key the
124
+ * call, and a cached or recorded result computed under the old codec is
125
+ * replayed under the new one. No fingerprint can close this automatically:
126
+ * effect codecs are not serializable, so the identity would have to be
127
+ * author-supplied. Until a declaration carries one, an author who changes a
128
+ * transformation and needs the call re-keyed renames the declaration.
129
+ * `@smthrs/core` carries the same algorithm and the same limit.
130
+ *
131
+ * @private
132
+ */
133
+ const schemaIdentity = (schema) => {
134
+ const cached = schemaDocuments.get(schema);
135
+ if (cached !== undefined)
136
+ return cached;
137
+ const document = Schema.toJsonSchemaDocument(schema, { onExcessProperty: "error" });
138
+ schemaDocuments.set(schema, document);
139
+ return document;
140
+ };
141
+ /**
142
+ * One document per schema object. A document is a pure function of the
143
+ * schema's AST and schemas are immutable, so every node and every build that
144
+ * names the same declaration reuses the document rather than regenerating it.
145
+ *
146
+ * @private
147
+ */
148
+ const schemaDocuments = new WeakMap();
149
+ /** @private */
150
+ const isPlainObject = (value) => typeof value === "object" && value !== null &&
151
+ (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
152
+ /**
153
+ * The reference a value stands for, whether it is a live placeholder — a real
154
+ * payload may carry one, naming a node an earlier generation already planned —
155
+ * or the inert record an AST payload kept.
156
+ *
157
+ * @private
158
+ */
159
+ const referenceOf = (value) => {
160
+ const live = Planned.reference(value);
161
+ if (live !== undefined)
162
+ return live;
163
+ return Node.plannedReference(value);
164
+ };
165
+ /** @private */
166
+ const outcomeTagOf = (ast) => {
167
+ const descriptor = Object.getOwnPropertyDescriptor(ast, OutcomeNodeTypeId);
168
+ if (descriptor === undefined || !("value" in descriptor))
169
+ return undefined;
170
+ const value = descriptor.value;
171
+ return value === "Done" || value === "To" || value === "Park" ? value : undefined;
172
+ };
173
+ /**
174
+ * Rebuilds the strict placeholder a reference names, so a spliced body sees
175
+ * the same refusals an inline body does.
176
+ *
177
+ * @private
178
+ */
179
+ const placeholder = (reference, node) => reference.path.reduce((value, key) => value[key], Planned.make(node));
180
+ /**
181
+ * The nesting bound the build enforces on authored topology. The walk itself
182
+ * is iterative and cannot overflow the native stack, so the bound is policy:
183
+ * topology a thousand combinators deep is a generated artifact, and refusing
184
+ * it with a typed `graph_too_deep` names the fix — `.child()` boundaries or
185
+ * trampoline handoffs — where unbounded acceptance would only defer the
186
+ * failure to whatever walks the plan next.
187
+ *
188
+ * It is EXPORTED so a composition that unrolls its own topology, as
189
+ * `@smthrs/patterns` does for a bounded loop, refuses at the same number the
190
+ * build enforces instead of restating it and drifting.
191
+ *
192
+ * @since 0.1.0
193
+ * @category models
194
+ */
195
+ export const maximumGraphDepth = 1_000;
196
+ /**
197
+ * The nesting bound the build enforces on payload data, for the same reason
198
+ * {@link maximumGraphDepth} bounds topology: hydration, hashing, and reference
199
+ * scanning walk iteratively, and the bound turns a pathologically deep payload
200
+ * into a typed `payload_too_deep` refusal instead of an unbounded walk over
201
+ * data a plan would have to hash and store level by level.
202
+ *
203
+ * @private
204
+ */
205
+ const maximumPayloadDepth = 1_000;
206
+ /** @private */
207
+ const container = (value, at) => {
208
+ if (Array.isArray(value))
209
+ return value;
210
+ if (typeof value !== "object" || value === null)
211
+ return undefined;
212
+ try {
213
+ return isPlainObject(value) ? value : undefined;
214
+ }
215
+ catch {
216
+ throw new GraphBuildError({
217
+ code: "invalid_payload",
218
+ node: at,
219
+ path: [],
220
+ message: `Payload at "${at}" does not expose an inert object prototype.`
221
+ });
222
+ }
223
+ };
224
+ /**
225
+ * Walks one payload with an explicit stack. Real recursion would let a deep
226
+ * payload overflow the native stack instead of failing loudly, so depth is a
227
+ * typed refusal here: a value already on the ancestor chain is
228
+ * `cyclic_payload`, and nesting past {@link maximumPayloadDepth} is
229
+ * `payload_too_deep`. Values that are neither placeholders nor plain data
230
+ * pass through untraversed to the key canonicalizer, which is the one
231
+ * component entitled to refuse them.
232
+ *
233
+ * Rebuilding writes members with a null-prototype target and
234
+ * `defineProperty`, never `output[key] = …`: `__proto__` routes through
235
+ * `Object.prototype`'s accessor, so an own `__proto__` field whose value is a
236
+ * primitive would be silently DROPPED and one whose value is an object would
237
+ * reparent the copy instead of being recorded on it. A payload may carry that
238
+ * key — `JSON.parse` produces it as an own data property — and both outcomes
239
+ * are wrong here: a hydrated payload would be planned and run with a field
240
+ * its author wrote missing, and two payloads that differ only in that field
241
+ * would hash to one key. `@smthrs/plan`'s AST cloner answers this the
242
+ * same way.
243
+ *
244
+ * @private
245
+ */
246
+ const walkPayload = (root, walk) => {
247
+ const resolvedRoot = walk.resolve(root);
248
+ if (resolvedRoot !== undefined)
249
+ return resolvedRoot.value;
250
+ const rootContainer = container(root, walk.at);
251
+ if (rootContainer === undefined)
252
+ return root;
253
+ const open = (source) => {
254
+ const descriptors = (() => {
255
+ try {
256
+ return Object.getOwnPropertyDescriptors(source);
257
+ }
258
+ catch {
259
+ throw new GraphBuildError({
260
+ code: "invalid_payload",
261
+ node: walk.at,
262
+ path: [],
263
+ message: `Payload at "${walk.at}" does not expose inert own properties.`
264
+ });
265
+ }
266
+ })();
267
+ if (Array.isArray(source)) {
268
+ const members = Array.from({ length: source.length }, (_, index) => {
269
+ const descriptor = descriptors[String(index)];
270
+ if (descriptor === undefined)
271
+ return undefined;
272
+ if (!("value" in descriptor)) {
273
+ throw new GraphBuildError({
274
+ code: "invalid_payload",
275
+ node: walk.at,
276
+ path: [String(index)],
277
+ message: `Payload at "${walk.at}" contains an accessor at index ${index}. Pass inert data.`
278
+ });
279
+ }
280
+ return descriptor.value;
281
+ });
282
+ return { source, keys: undefined, members, output: [], index: 0 };
283
+ }
284
+ const keys = walk.keysOf(Object.keys(descriptors).filter((key) => descriptors[key]?.enumerable === true));
285
+ const members = keys.map((key) => {
286
+ const descriptor = descriptors[key];
287
+ if (!("value" in descriptor)) {
288
+ throw new GraphBuildError({
289
+ code: "invalid_payload",
290
+ node: walk.at,
291
+ path: [key],
292
+ message: `Payload at "${walk.at}" contains accessor property "${key}". Pass inert data.`
293
+ });
294
+ }
295
+ return descriptor.value;
296
+ });
297
+ return {
298
+ source,
299
+ keys,
300
+ members,
301
+ output: Object.create(null),
302
+ index: 0
303
+ };
304
+ };
305
+ const rootFrame = open(rootContainer);
306
+ const frames = [rootFrame];
307
+ const ancestors = new Set([rootContainer]);
308
+ while (frames.length > 0) {
309
+ const frame = frames[frames.length - 1];
310
+ if (frame.index >= frame.members.length) {
311
+ frames.pop();
312
+ ancestors.delete(frame.source);
313
+ continue;
314
+ }
315
+ const position = frame.index;
316
+ frame.index = position + 1;
317
+ const key = frame.keys?.[position];
318
+ const member = frame.members[position];
319
+ const place = (produced) => {
320
+ if (key === undefined) {
321
+ const members = frame.output;
322
+ members.push(produced);
323
+ return;
324
+ }
325
+ Object.defineProperty(frame.output, key, {
326
+ configurable: true,
327
+ enumerable: true,
328
+ value: produced,
329
+ writable: true
330
+ });
331
+ };
332
+ const resolved = walk.resolve(member);
333
+ if (resolved !== undefined) {
334
+ place(resolved.value);
335
+ continue;
336
+ }
337
+ const nested = container(member, walk.at);
338
+ if (nested === undefined) {
339
+ place(member);
340
+ continue;
341
+ }
342
+ if (ancestors.has(nested)) {
343
+ throw new GraphBuildError({
344
+ code: "cyclic_payload",
345
+ node: walk.at,
346
+ path: [],
347
+ message: `Payload at "${walk.at}" contains itself, so no plan can hash or serialize it. Pass acyclic data.`
348
+ });
349
+ }
350
+ if (frames.length >= maximumPayloadDepth) {
351
+ throw new GraphBuildError({
352
+ code: "payload_too_deep",
353
+ node: walk.at,
354
+ path: [],
355
+ message: `Payload at "${walk.at}" nests more than ${maximumPayloadDepth} levels deep. ` +
356
+ "Flatten the payload: a plan hashes and stores every level of it."
357
+ });
358
+ }
359
+ const opened = open(nested);
360
+ place(opened.output);
361
+ ancestors.add(nested);
362
+ frames.push(opened);
363
+ }
364
+ return rootFrame.output;
365
+ };
366
+ /**
367
+ * Turns an AST payload back into what a body must see: real data where the
368
+ * caller wrote data, strict placeholders where it passed a step result. The
369
+ * substitution rewrites a branch's own subject token to its upstream node, and
370
+ * a catch's own subject token to the node it protects, which are those arms'
371
+ * subjects by construction.
372
+ *
373
+ * @private
374
+ */
375
+ const hydrate = (value, substitutions, at) => walkPayload(value, {
376
+ at,
377
+ keysOf: (keys) => keys,
378
+ resolve: (member) => {
379
+ const reference = referenceOf(member);
380
+ return reference === undefined
381
+ ? undefined
382
+ : { value: placeholder(reference, substitutions.get(reference.node) ?? reference.node) };
383
+ }
384
+ });
385
+ /**
386
+ * The hashed form of a payload: placeholders keep their property path and drop
387
+ * the node they came from, because the node id is a lookup address and the
388
+ * dependency itself is named by a separate `Ref`. The same walk collects every
389
+ * upstream result the payload reads into `found`, in sorted-key order, so a
390
+ * payload is canonicalized once rather than walked again for its references.
391
+ *
392
+ * @private
393
+ */
394
+ const literal = (value, found, at) => walkPayload(value, {
395
+ at,
396
+ keysOf: (keys) => [...keys].sort(),
397
+ resolve: (member) => {
398
+ const reference = Planned.reference(member);
399
+ if (reference === undefined)
400
+ return undefined;
401
+ found.push(reference);
402
+ return { value: { _tag: "PlannedInput", path: [...reference.path] } };
403
+ }
404
+ });
405
+ /**
406
+ * Whether an inline call would place the callee somewhere the enclosing flow
407
+ * cannot run it.
408
+ *
409
+ * A placement directive is opaque to this package — `Annotations.Placement` is
410
+ * `Schema.Unknown`, and interpreting it is a scheduler's job — so the only
411
+ * verdict available here is identity: the same directive is satisfiable, a
412
+ * different one is not. The local comparison has the structural semantics of a
413
+ * canonicalized literal without serializing it: arrays compare by length and
414
+ * element, objects by their own enumerable keys independent of key order, and
415
+ * primitives by `Object.is`. That makes `NaN` equal to itself and cheaply keeps
416
+ * `-0` distinct from `0`. A visited-pair map terminates cyclic object graphs.
417
+ *
418
+ * Identity is claimed only over data the comparison can read inertly. Two
419
+ * distinct objects are identical only when both are plain — an ordinary object
420
+ * literal or a null-prototype object, or two arrays — and only through own data
421
+ * properties: a `Date`, `Map`, `RegExp`, class instance, or function is
422
+ * identical to itself by reference and to nothing else, and an accessor-backed
423
+ * key is identical to nothing at all, because reading it would run author code
424
+ * during graph building. Every one of those is a REFUSAL to prove identity, so
425
+ * the call is pushed to an explicit `.child()` boundary rather than admitted
426
+ * inline against a placement nobody checked. A `Proxy` over a plain object
427
+ * still observes the key and descriptor reads; making the directive inert
428
+ * before it is compared is the remaining half of that hardening.
429
+ *
430
+ * Identity over a CYCLIC directive is bisimulation: the visited-pair map makes
431
+ * two directives identical when they unfold to the same infinite tree, so a
432
+ * self-cycle and a two-node cycle of the same shape are the same directive.
433
+ * Cycle lengths that share no factor pair off against each other for their
434
+ * least common multiple of comparisons, which is what
435
+ * {@link maxComparisonPairs} bounds.
436
+ *
437
+ * DECIDED: an enclosing flow that declares NO
438
+ * placement is unconstrained and satisfies any callee, rather than satisfying
439
+ * only a callee that declares none. Inline expansion runs the callee's steps in
440
+ * the caller's execution, so the constraint that matters is the one the caller
441
+ * already carries; refusing an undeclared caller would make `Flow.Placement`
442
+ * mandatory on every flow in a call chain to keep `.call()` usable.
443
+ *
444
+ * @private
445
+ */
446
+ const structuralIdentity = (left, right) => {
447
+ const pending = [[left, right]];
448
+ const visited = new WeakMap();
449
+ let examined = 0;
450
+ try {
451
+ while (pending.length > 0) {
452
+ const [left, right] = pending.pop();
453
+ if (++examined > maxComparisonPairs)
454
+ return false;
455
+ if (Object.is(left, right))
456
+ continue;
457
+ if (left !== Object(left))
458
+ return false;
459
+ if (right !== Object(right))
460
+ return false;
461
+ const leftObject = left;
462
+ const rightObject = right;
463
+ const leftIsArray = Array.isArray(leftObject);
464
+ if (leftIsArray !== Array.isArray(rightObject))
465
+ return false;
466
+ if (leftIsArray && leftObject.length !== rightObject.length) {
467
+ return false;
468
+ }
469
+ const seen = visited.get(leftObject) ?? new WeakSet();
470
+ if (seen.has(rightObject))
471
+ continue;
472
+ seen.add(rightObject);
473
+ visited.set(leftObject, seen);
474
+ if (!leftIsArray && !(isPlainObject(leftObject) && isPlainObject(rightObject)))
475
+ return false;
476
+ const leftKeys = Reflect.ownKeys(leftObject).filter((key) => Object.prototype.propertyIsEnumerable.call(leftObject, key));
477
+ const rightKeys = Reflect.ownKeys(rightObject).filter((key) => Object.prototype.propertyIsEnumerable.call(rightObject, key));
478
+ if (leftKeys.length !== rightKeys.length)
479
+ return false;
480
+ for (const key of leftKeys) {
481
+ if (!Object.prototype.propertyIsEnumerable.call(rightObject, key))
482
+ return false;
483
+ // Descriptors rather than `Reflect.get`: a getter is author code, and
484
+ // graph building must not run it.
485
+ const leftMember = Object.getOwnPropertyDescriptor(leftObject, key);
486
+ const rightMember = Object.getOwnPropertyDescriptor(rightObject, key);
487
+ if (!("value" in leftMember) || !("value" in rightMember))
488
+ return false;
489
+ pending.push([leftMember.value, rightMember.value]);
490
+ }
491
+ }
492
+ }
493
+ catch {
494
+ // Every reflection above is a Proxy trap, and a trap is author code that
495
+ // may throw. Graph building must not fail with whatever it threw, so an
496
+ // unreadable directive gets the verdict every other one gets: identity is
497
+ // not proved, and the call goes to an explicit `.child()` boundary.
498
+ return false;
499
+ }
500
+ return true;
501
+ };
502
+ /**
503
+ * The most value pairs one placement comparison examines before giving up.
504
+ *
505
+ * A directive is author data walked at planning time, so the comparison needs a
506
+ * ceiling that does not depend on how large or how cyclic that data is.
507
+ * Exhausting the ceiling is a refusal to prove identity, not a claim that the
508
+ * two directives differ.
509
+ *
510
+ * @private
511
+ */
512
+ const maxComparisonPairs = 100_000;
513
+ /** @private */
514
+ const placementConflicts = (enclosing, callee) => enclosing !== undefined && callee !== undefined && !structuralIdentity(enclosing, callee);
515
+ /** The most characters one rendered placement contributes to a diagnostic. */
516
+ const maxPlacementChars = 240;
517
+ /** How many levels of a placement a diagnostic renders before eliding. */
518
+ const maxPlacementDepth = 4;
519
+ /**
520
+ * How many members of one array or object a diagnostic renders.
521
+ *
522
+ * An array's cost is its LENGTH, not its member count: `new Array(100_000)` owns
523
+ * no properties and still renders a hundred thousand separators without this
524
+ * bound, so a directive a byte long becomes a diagnostic megabytes long.
525
+ */
526
+ const maxPlacementMembers = 32;
527
+ /**
528
+ * A bounded, inert rendering of a placement directive, for the refusal that
529
+ * names it.
530
+ *
531
+ * An author who declared two placements needs to see WHICH two the build
532
+ * compared and how they differ, so the refusal prints both. The directive is
533
+ * arbitrary author data, so this holds to exactly the discipline
534
+ * {@link structuralIdentity} holds to: own enumerable data properties only,
535
+ * never an accessor, plain objects and arrays walked and everything else named
536
+ * by kind, under a depth bound, a cycle guard, and a length bound so a large
537
+ * directive cannot become the whole message. Array indices are read as
538
+ * descriptors rather than iterated, because iteration invokes an index getter;
539
+ * a hole renders as `<hole>`. Both arrays and objects render at most
540
+ * {@link maxPlacementMembers} members and mark the rest `<more>`, so the work
541
+ * is bounded before the string is truncated rather than after. Object members
542
+ * are sorted, so two directives that differ only in key order render
543
+ * identically, matching the comparison that admitted them. It never throws.
544
+ *
545
+ * @private
546
+ */
547
+ const renderPlacement = (value) => {
548
+ const render = (value, depth, seen) => {
549
+ if (typeof value === "string")
550
+ return JSON.stringify(value);
551
+ if (typeof value === "bigint")
552
+ return `${value}n`;
553
+ if (Object(value) !== value)
554
+ return String(value);
555
+ const object = value;
556
+ if (seen.includes(object))
557
+ return "<cycle>";
558
+ if (depth === maxPlacementDepth)
559
+ return "<elided>";
560
+ const nested = [...seen, object];
561
+ if (Array.isArray(object)) {
562
+ const length = object.length;
563
+ const shown = Math.min(length, maxPlacementMembers);
564
+ const members = [];
565
+ for (let index = 0; index < shown; index++) {
566
+ // `Array.prototype.map` invokes an index getter, so indices are read as
567
+ // descriptors here for the same reason keys are below.
568
+ const member = Object.getOwnPropertyDescriptor(object, String(index));
569
+ members.push(member === undefined
570
+ ? "<hole>"
571
+ : "value" in member
572
+ ? render(member.value, depth + 1, nested)
573
+ : "<accessor>");
574
+ }
575
+ if (length > shown)
576
+ members.push("<more>");
577
+ return `[${members.join(",")}]`;
578
+ }
579
+ if (!isPlainObject(object))
580
+ return Object.prototype.toString.call(object);
581
+ const keys = Reflect.ownKeys(object)
582
+ .filter((key) => Object.prototype.propertyIsEnumerable.call(object, key))
583
+ .sort((left, right) => String(left).localeCompare(String(right)));
584
+ // Select the bounded prefix before rendering values. Rendering every
585
+ // member and slicing afterward still traverses the entire omitted forest.
586
+ const members = keys.slice(0, maxPlacementMembers)
587
+ .map((key) => {
588
+ const member = Object.getOwnPropertyDescriptor(object, key);
589
+ const rendered = "value" in member ? render(member.value, depth + 1, nested) : "<accessor>";
590
+ return `${String(key)}:${rendered}`;
591
+ })
592
+ .sort();
593
+ const shown = keys.length > maxPlacementMembers
594
+ ? [...members, "<more>"]
595
+ : members;
596
+ return `{${shown.join(",")}}`;
597
+ };
598
+ try {
599
+ const rendered = render(value, 0, []);
600
+ return rendered.length <= maxPlacementChars
601
+ ? rendered
602
+ : `${rendered.slice(0, maxPlacementChars)} [${rendered.length - maxPlacementChars} characters dropped]`;
603
+ }
604
+ catch {
605
+ return "<unrenderable>";
606
+ }
607
+ };
608
+ /**
609
+ * The `Literal` a payload hashes as, followed by one `Ref` per distinct
610
+ * upstream result it reads.
611
+ *
612
+ * @private
613
+ */
614
+ const payloadInputs = (payload, at) => {
615
+ const found = [];
616
+ const inputs = [{ _tag: "Literal", value: literal(payload, found, at) }];
617
+ const seen = new Set();
618
+ for (const reference of found) {
619
+ const identity = JSON.stringify([reference.node, ...reference.path]);
620
+ if (seen.has(identity))
621
+ continue;
622
+ seen.add(identity);
623
+ inputs.push({ _tag: "Ref", from: reference.node, path: [...reference.path] });
624
+ }
625
+ return inputs;
626
+ };
627
+ /**
628
+ * Builds the graph of a flow declaration, or of a bare node, by walking the
629
+ * AST once.
630
+ *
631
+ * A flow is entered as a call to itself: the returned graph's `root` node is
632
+ * that call, carrying the flow's declared effects, placement, and
633
+ * capabilities, and its body spliced beneath it. Every flow has a body, so the
634
+ * only inline call this leaves as a leaf is one whose declaration did not
635
+ * survive serialization beside its AST.
636
+ *
637
+ * @since 0.1.0
638
+ * @category constructors
639
+ */
640
+ export const build = (flowOrNode, payload, options = {}) => {
641
+ const observed = [];
642
+ const observedIds = new Set();
643
+ const observedEdges = [];
644
+ const observedDiagnostics = [];
645
+ const observeIdentity = (node, field, identity) => {
646
+ if (options.callbackIdentity !== "stable" ||
647
+ (identity !== undefined && identity.algorithm !== "sha256-source-ephemeral/v4"))
648
+ return;
649
+ observedDiagnostics.push(new GraphBuildError({
650
+ code: "unstable_callback",
651
+ node,
652
+ path: [field],
653
+ message: `Callback ${field} at "${node}" has ${identity === undefined ? "unavailable" : "process-local"} identity ` +
654
+ "and cannot enter a stable graph. " +
655
+ "Use Node.capture with every semantic capture, including the version of imported implementation behavior."
656
+ }));
657
+ };
658
+ /**
659
+ * The explicit walk stack. Every step is a thunk; expanding a node pushes
660
+ * its steps in reverse so they pop in authoring order, which keeps the
661
+ * observed nodes, edges, and diagnostics in exactly the order a recursive
662
+ * walk would produce while making depth a data structure instead of native
663
+ * stack frames a deep graph could exhaust.
664
+ */
665
+ const operations = [];
666
+ /** Stacks steps to run in the order written, ahead of everything stacked. */
667
+ const sequence = (steps) => {
668
+ for (let index = steps.length - 1; index >= 0; index--)
669
+ operations.push(steps[index]);
670
+ };
671
+ const record = (entry) => {
672
+ if (observedIds.has(entry.id)) {
673
+ throw new GraphBuildError({
674
+ code: "duplicate_node",
675
+ node: entry.id,
676
+ path: [],
677
+ message: `Node id "${entry.id}" is durable dispatch identity, so two nodes may not share one. ` +
678
+ "Two structural addresses in this graph collided, most often because a Node.all member name " +
679
+ "contains the separator a nested address also produces. Rename one of them."
680
+ });
681
+ }
682
+ observedIds.add(entry.id);
683
+ const material = {
684
+ version: KeyMaterial.version,
685
+ kind: entry.tier,
686
+ body: entry.capabilityCeilings?.length
687
+ ? { ...entry.body, capabilityCeilings: entry.capabilityCeilings }
688
+ : entry.body,
689
+ inputs: entry.inputs,
690
+ layers: sorted(options.resolveLayers?.({
691
+ nodeId: entry.id,
692
+ kind: entry.kind,
693
+ capabilities: entry.capabilities,
694
+ effects: entry.effects,
695
+ placement: entry.placement
696
+ }) ?? []),
697
+ capabilities: entry.capabilities,
698
+ ...(entry.nondeterministic === undefined ? {} : { nondeterministic: entry.nondeterministic }),
699
+ ...(entry.effects === undefined ? {} : { effects: entry.effects }),
700
+ ...(entry.placement === undefined ? {} : { placement: entry.placement })
701
+ };
702
+ observed.push({
703
+ id: entry.id,
704
+ kind: entry.kind,
705
+ dependencies: entry.dependencies,
706
+ capabilities: entry.capabilities,
707
+ capabilityCeilings: entry.capabilityCeilings ?? [],
708
+ placement: entry.placement,
709
+ // Priority reaches the compiled plan through the draft and stays OUT of
710
+ // `material`: it orders ready work without changing what the work
711
+ // produces, so raising it must not re-key a step.
712
+ draft: {
713
+ id: entry.id,
714
+ material,
715
+ effects: entry.effects ?? emptyEffects,
716
+ ...(entry.priority === undefined ? {} : { priority: entry.priority })
717
+ },
718
+ ast: entry.ast,
719
+ payload: entry.payload,
720
+ ...(entry.declaredAt === undefined ? {} : { declaredAt: entry.declaredAt })
721
+ });
722
+ };
723
+ /**
724
+ * An envelope is graph-owned and reaches every node it encloses as the same
725
+ * object, so it is read into its prepared form once and each enclosed
726
+ * declaration is checked against that: a wide envelope costs its size once
727
+ * per build rather than once per node that narrows it.
728
+ */
729
+ const preparedEnvelopes = new Map();
730
+ /**
731
+ * Checks one declaration against the envelope enclosing it, recording the
732
+ * refusal and answering whether the declaration may become the envelope for
733
+ * what it encloses in turn. A refused declaration must NOT replace the last
734
+ * accepted one: widening beneath it would then be measured against the very
735
+ * claim that was just rejected.
736
+ */
737
+ const admitEnvelope = (enclosing, declared, site) => {
738
+ if (declared === undefined)
739
+ return enclosing;
740
+ if (enclosing === undefined)
741
+ return declared;
742
+ let prepared = preparedEnvelopes.get(enclosing);
743
+ if (prepared === undefined) {
744
+ prepared = Effects.prepareEnvelope(enclosing);
745
+ preparedEnvelopes.set(enclosing, prepared);
746
+ }
747
+ const narrowed = Effects.narrowPrepared(prepared, declared);
748
+ if (narrowed.ok)
749
+ return declared;
750
+ observedDiagnostics.push(new GraphBuildError({
751
+ code: narrowed.code,
752
+ node: site.id,
753
+ path: [...narrowed.paths],
754
+ message: refusalMessage(narrowed, site)
755
+ }));
756
+ return enclosing;
757
+ };
758
+ /**
759
+ * Expands the node a flow call becomes, shared by the entry point and by
760
+ * every `FlowCall` in a body.
761
+ */
762
+ const coveredCapability = (stack, text) => {
763
+ const groups = stack.flatMap((flow) => capabilityCeilings(flow.annotations));
764
+ if (groups.length === 0)
765
+ return true;
766
+ const candidate = Capability.parsePattern(text);
767
+ if (Option.isNone(candidate))
768
+ return false;
769
+ return groups.every((group) => group.some((text) => {
770
+ const grant = Capability.parsePattern(text);
771
+ return Option.isSome(grant) && Capability.subsumes(grant.value, candidate.value);
772
+ }));
773
+ };
774
+ const expandFlowCall = (call) => {
775
+ const annotations = call.declaration?.annotations ?? Context.empty();
776
+ const dependencies = call.dependencies;
777
+ const inputs = [...payloadInputs(call.payload, call.id), ...call.inputs];
778
+ const target = call.mode === "inline" ? call.declaration : undefined;
779
+ const ceiling = sorted(capabilityCeilings(annotations)[0] ?? call.capabilities);
780
+ const placement = declaredPlacement(annotations);
781
+ const envelope = declaredEnvelope(annotations);
782
+ // The authority checks are recorded, not thrown: a graph whose callee
783
+ // claimed too much is still worth inspecting, and the author needs every
784
+ // over-claim in the composition at once rather than the first one.
785
+ //
786
+ // They run for EVERY call mode. An explicit `.child()` boundary and a
787
+ // trampoline handoff give the callee its own execution, not its own
788
+ // authority: whoever writes the call is still the one granting it, which is
789
+ // the rule `@smthrs/core`'s graph applies to a call whose body it does not
790
+ // splice.
791
+ const calleeEnvelope = admitEnvelope(call.envelope, envelope, { id: call.id, flow: call.flow });
792
+ const dropped = ceiling.filter((capability) => !coveredCapability(call.stack, capability));
793
+ if (dropped.length > 0) {
794
+ observedDiagnostics.push(new GraphBuildError({
795
+ code: "capability_outside_grant",
796
+ node: call.id,
797
+ path: dropped,
798
+ message: `Flow "${call.flow}" at "${call.id}" requires ${dropped.join(", ")}, which the calling flow ` +
799
+ "does not provably grant. Execution intersects this declaration with every caller ceiling."
800
+ }));
801
+ }
802
+ // The placement refusal precedes the recursion one only in position: an
803
+ // inline call the caller cannot host is invalid whether or not the callee's
804
+ // declaration survived to be spliced, because inline expansion is the claim
805
+ // that these steps run in the caller's execution.
806
+ if (call.mode === "inline" && placementConflicts(call.placement, placement)) {
807
+ throw new GraphBuildError({
808
+ code: "placement_requires_boundary",
809
+ node: call.id,
810
+ path: [],
811
+ message: `Flow "${call.flow}" is called inline at "${call.id}", but its declared placement ` +
812
+ `${renderPlacement(placement)} is not structurally identical to the enclosing flow's ` +
813
+ `${renderPlacement(call.placement)}. An inline .call() runs in the caller's execution, so use ` +
814
+ `${call.flow}.child(payload) to give it its own.`
815
+ });
816
+ }
817
+ const recordCall = () => {
818
+ const bodyIdentity = call.declaration === undefined ? undefined : Node.functionIdentity(call.declaration.body);
819
+ observeIdentity(call.id, "body", bodyIdentity);
820
+ record({
821
+ id: call.id,
822
+ kind: "FlowCall",
823
+ dependencies,
824
+ capabilities: call.capabilities,
825
+ capabilityCeilings: [
826
+ ...call.stack.flatMap((flow) => capabilityCeilings(flow.annotations)),
827
+ ...capabilityCeilings(annotations)
828
+ ],
829
+ effects: declaredEffects(annotations),
830
+ placement,
831
+ priority: call.priority,
832
+ // A declared envelope states how reversible the flow beneath it is, so
833
+ // it is the call's tier. A flow that declared none keeps the sealed
834
+ // default every call has always carried, which is what keeps every
835
+ // existing flow's key exactly where it was.
836
+ tier: envelope?.tier ?? "sealed",
837
+ body: {
838
+ _tag: "FlowCall",
839
+ flow: call.flow,
840
+ mode: call.mode,
841
+ declaration: call.declaration === undefined ? undefined : {
842
+ payload: schemaIdentity(call.declaration.payloadSchema),
843
+ success: schemaIdentity(call.declaration.successSchema),
844
+ error: schemaIdentity(call.declaration.errorSchema),
845
+ capabilities: ceiling,
846
+ // A spliced body re-keys this call through the `Ref` on the node it
847
+ // produced. A call the graph keeps as a LEAF — an explicit boundary,
848
+ // a handoff — has no such node, and its own digest is the only thing
849
+ // an edited body can move.
850
+ body: bodyIdentity
851
+ }
852
+ },
853
+ inputs,
854
+ ast: call.ast,
855
+ payload: call.payload,
856
+ declaredAt: DeclarationSite.declaredAt(call.declaration)
857
+ });
858
+ };
859
+ if (target === undefined) {
860
+ recordCall();
861
+ return;
862
+ }
863
+ if (call.stack.includes(target)) {
864
+ throw new GraphBuildError({
865
+ code: "recursion_requires_boundary",
866
+ node: call.id,
867
+ path: [],
868
+ message: `Flow "${call.flow}" cannot call itself inline at "${call.id}". ` +
869
+ `Use ${call.flow}.to(payload) to hand off to the next round, or .child(payload) for an explicit boundary.`
870
+ });
871
+ }
872
+ const built = target.body(call.payload);
873
+ const spliced = `${call.id}.flow`;
874
+ sequence([
875
+ () => expand({
876
+ ast: built.ast,
877
+ id: spliced,
878
+ depth: call.depth + 1,
879
+ capabilities: ceiling.filter((capability) => coveredCapability(call.stack, capability)),
880
+ // Inside the spliced body the callee's own placement is the one to
881
+ // satisfy; a callee that declared none keeps running under the
882
+ // caller's.
883
+ placement: placement ?? call.placement,
884
+ envelope: calleeEnvelope,
885
+ priority: call.priority,
886
+ substitutions: call.substitutions,
887
+ stack: [...call.stack, target],
888
+ prerequisite: undefined,
889
+ barriers: call.barriers
890
+ }),
891
+ () => {
892
+ dependencies.push(spliced);
893
+ observedEdges.push({ from: spliced, to: call.id, reason: "value" });
894
+ inputs.push({ _tag: "Ref", from: spliced, path: [] });
895
+ },
896
+ recordCall
897
+ ]);
898
+ };
899
+ /**
900
+ * The continuation of an `AndThen`, evaluated exactly once against the
901
+ * placeholder standing for its upstream result. A continuation that is gone
902
+ * — an AST that crossed a serialization boundary — or that answered with
903
+ * something other than a node leaves the remainder out and says so, because
904
+ * a graph missing that recoverable step is still worth inspecting. Computing
905
+ * on the placeholder is a fatal build refusal and propagates unchanged.
906
+ */
907
+ const continuation = (ast, id, subject) => {
908
+ const builder = Node.continuation(ast);
909
+ if (builder === undefined) {
910
+ observedDiagnostics.push(new GraphBuildError({
911
+ code: "invalid_continuation",
912
+ node: id,
913
+ path: [],
914
+ message: `Node.bindPlanned at "${id}" no longer holds its continuation builder, so its continuation is ` +
915
+ "missing from the graph. An AST that crossed a serialization boundary left that side table behind."
916
+ }));
917
+ return undefined;
918
+ }
919
+ const built = builder(Planned.make(subject));
920
+ if (Node.isNode(built))
921
+ return built.ast;
922
+ observedDiagnostics.push(new GraphBuildError({
923
+ code: "invalid_continuation",
924
+ node: id,
925
+ path: [],
926
+ message: `Node.bindPlanned at "${id}" did not produce a Node, so its continuation is missing from the graph.`
927
+ }));
928
+ return undefined;
929
+ };
930
+ const expand = (request) => {
931
+ if (request.depth > maximumGraphDepth) {
932
+ throw new GraphBuildError({
933
+ code: "graph_too_deep",
934
+ node: request.id,
935
+ path: [],
936
+ message: `The graph nests more than ${maximumGraphDepth} levels deep. ` +
937
+ "Split the flow with .child() boundaries or trampoline handoffs so one execution plans a bounded graph."
938
+ });
939
+ }
940
+ const { ast, capabilities, depth, envelope, id, placement, stack, substitutions } = request;
941
+ // A node's own priority wins; otherwise it inherits the enclosing one.
942
+ const priority = ast.priority ?? request.priority;
943
+ const dependencies = [];
944
+ const inputs = [];
945
+ const depend = (from, reason) => {
946
+ dependencies.push(from);
947
+ observedEdges.push({ from, to: id, reason });
948
+ inputs.push(reason === "continuation" ? { _tag: "Pending", from } : { _tag: "Ref", from, path: [] });
949
+ };
950
+ const child = (childAst, childId, options = {}) => ({
951
+ ast: childAst,
952
+ id: childId,
953
+ depth: depth + 1,
954
+ capabilities,
955
+ placement,
956
+ envelope,
957
+ priority,
958
+ substitutions: options.substitutions ?? substitutions,
959
+ stack,
960
+ prerequisite: options.prerequisite,
961
+ barriers: options.barriers ?? request.barriers
962
+ });
963
+ if (request.prerequisite !== undefined)
964
+ depend(request.prerequisite, "continuation");
965
+ for (const barrier of request.barriers) {
966
+ if (barrier !== request.prerequisite)
967
+ depend(barrier, "continuation");
968
+ }
969
+ switch (ast._tag) {
970
+ case "FlowCall": {
971
+ expandFlowCall({
972
+ id,
973
+ depth,
974
+ ast,
975
+ flow: ast.flow,
976
+ mode: ast.mode,
977
+ declaration: flowDeclaration(Node.declaration(ast)),
978
+ payload: hydrate(ast.payload, substitutions, id),
979
+ capabilities,
980
+ placement,
981
+ envelope,
982
+ priority,
983
+ substitutions,
984
+ stack,
985
+ barriers: request.barriers,
986
+ dependencies,
987
+ inputs
988
+ });
989
+ return;
990
+ }
991
+ case "ActionCall": {
992
+ const declared = actionDeclaration(Node.declaration(ast));
993
+ const annotations = declared?.annotations ?? Context.empty();
994
+ const payload = hydrate(ast.payload, substitutions, id);
995
+ // An action is a leaf, so its declaration cannot become an envelope for
996
+ // anything; it is only checked against the one it sits inside.
997
+ admitEnvelope(envelope, declaredEnvelope(annotations), { id, flow: ast.action });
998
+ // The ceiling the declaration named, read off its bag exactly as a
999
+ // called flow's is. An action that named none keeps the enclosing grant
1000
+ // and adds nothing to its key, so every declaration written before the
1001
+ // literal existed keys exactly where it did.
1002
+ const ceiling = sorted(Context.get(annotations, Annotations.Capabilities));
1003
+ const dropped = ceiling.filter((capability) => !coveredCapability(stack, capability));
1004
+ if (dropped.length > 0) {
1005
+ observedDiagnostics.push(new GraphBuildError({
1006
+ code: "capability_outside_grant",
1007
+ node: id,
1008
+ path: dropped,
1009
+ message: `Action "${ast.action}" at "${id}" requires ${dropped.join(", ")}, which the calling ` +
1010
+ "flow does not provably grant. Execution intersects this declaration with every caller ceiling."
1011
+ }));
1012
+ }
1013
+ record({
1014
+ id,
1015
+ kind: ast._tag,
1016
+ dependencies,
1017
+ capabilities,
1018
+ capabilityCeilings: [
1019
+ ...stack.flatMap((flow) => capabilityCeilings(flow.annotations)),
1020
+ ...capabilityCeilings(annotations)
1021
+ ],
1022
+ effects: declaredEffects(annotations),
1023
+ placement: declaredPlacement(annotations),
1024
+ priority,
1025
+ tier: declared?.tier ?? "sealed",
1026
+ nondeterministic: declared?.nondeterministic,
1027
+ body: {
1028
+ _tag: "ActionCall",
1029
+ action: ast.action,
1030
+ tier: declared?.tier ?? "sealed",
1031
+ declaration: declared === undefined ? undefined : {
1032
+ payload: schemaIdentity(declared.payloadSchema),
1033
+ success: schemaIdentity(declared.successSchema),
1034
+ error: schemaIdentity(declared.errorSchema),
1035
+ ...(ceiling.length === 0 ? {} : { capabilities: ceiling }),
1036
+ ...(declared.implementationVersion === undefined
1037
+ ? {}
1038
+ : { implementationVersion: declared.implementationVersion })
1039
+ }
1040
+ },
1041
+ inputs: [...payloadInputs(payload, id), ...inputs],
1042
+ ast,
1043
+ payload,
1044
+ declaredAt: DeclarationSite.declaredAt(declared)
1045
+ });
1046
+ return;
1047
+ }
1048
+ case "Succeed": {
1049
+ const value = hydrate(ast.value, substitutions, id);
1050
+ const outcome = outcomeTagOf(ast);
1051
+ if (outcome !== undefined) {
1052
+ const tag = typeof value === "object" && value !== null
1053
+ ? Object.getOwnPropertyDescriptor(value, "_tag")
1054
+ : undefined;
1055
+ if (tag === undefined || !("value" in tag) || tag.value !== outcome) {
1056
+ throw new GraphBuildError({
1057
+ code: "invalid_payload",
1058
+ node: id,
1059
+ path: [],
1060
+ message: `Flow outcome node at "${id}" lost its ${outcome} payload.`
1061
+ });
1062
+ }
1063
+ Object.defineProperty(value, OutcomeValueTypeId, {
1064
+ configurable: false,
1065
+ enumerable: false,
1066
+ value: outcome,
1067
+ writable: false
1068
+ });
1069
+ }
1070
+ record({
1071
+ id,
1072
+ kind: ast._tag,
1073
+ dependencies,
1074
+ capabilities,
1075
+ effects: undefined,
1076
+ placement: undefined,
1077
+ priority,
1078
+ tier: "sealed",
1079
+ body: outcome === undefined ? { _tag: ast._tag } : { _tag: ast._tag, outcome },
1080
+ inputs: [...payloadInputs(value, id), ...inputs],
1081
+ ast,
1082
+ payload: value
1083
+ });
1084
+ return;
1085
+ }
1086
+ case "Fail": {
1087
+ // A constant failure is a leaf exactly as `Succeed` is, and its error
1088
+ // is hydrated and keyed the same way: two different refusals are two
1089
+ // different steps, and one that reads an upstream result depends on it.
1090
+ const error = hydrate(ast.error, substitutions, id);
1091
+ record({
1092
+ id,
1093
+ kind: ast._tag,
1094
+ dependencies,
1095
+ capabilities,
1096
+ effects: undefined,
1097
+ placement: undefined,
1098
+ priority,
1099
+ tier: "sealed",
1100
+ body: { _tag: ast._tag },
1101
+ inputs: [...payloadInputs(error, id), ...inputs],
1102
+ ast,
1103
+ payload: error
1104
+ });
1105
+ return;
1106
+ }
1107
+ case "All": {
1108
+ const members = Object.keys(ast.nodes);
1109
+ const steps = [];
1110
+ for (const member of members) {
1111
+ // This durable address cannot be re-keyed here without coordinating
1112
+ // the plan and engine stores. The record-time duplicate check guards
1113
+ // arbitrary member names instead.
1114
+ const memberId = `${id}.all.${member}`;
1115
+ steps.push(() => expand(child(ast.nodes[member], memberId)));
1116
+ steps.push(() => depend(memberId, "value"));
1117
+ }
1118
+ steps.push(() => record({
1119
+ id,
1120
+ kind: ast._tag,
1121
+ dependencies,
1122
+ capabilities,
1123
+ effects: undefined,
1124
+ placement: undefined,
1125
+ priority,
1126
+ tier: "sealed",
1127
+ body: { _tag: ast._tag, members },
1128
+ inputs,
1129
+ ast,
1130
+ payload: undefined
1131
+ }));
1132
+ sequence(steps);
1133
+ return;
1134
+ }
1135
+ case "Race": {
1136
+ // A join that settles early is expanded exactly as `All` is: every
1137
+ // member is topology the plan shows, and the interpreter decides at
1138
+ // run time which of them it waits for.
1139
+ const members = Object.keys(ast.nodes);
1140
+ const steps = [];
1141
+ for (const member of members) {
1142
+ const memberId = `${id}.race.${member}`;
1143
+ steps.push(() => expand(child(ast.nodes[member], memberId)));
1144
+ steps.push(() => depend(memberId, "value"));
1145
+ }
1146
+ steps.push(() => record({
1147
+ id,
1148
+ kind: ast._tag,
1149
+ dependencies,
1150
+ capabilities,
1151
+ effects: undefined,
1152
+ placement: undefined,
1153
+ priority,
1154
+ tier: "sealed",
1155
+ body: { _tag: ast._tag, mode: ast.mode, count: ast.count, members },
1156
+ inputs,
1157
+ ast,
1158
+ payload: undefined
1159
+ }));
1160
+ sequence(steps);
1161
+ return;
1162
+ }
1163
+ case "Map": {
1164
+ observeIdentity(id, "mapper", ast.mapper);
1165
+ const first = `${id}.map`;
1166
+ sequence([
1167
+ () => expand(child(ast.first, first)),
1168
+ () => depend(first, "value"),
1169
+ () => record({
1170
+ id,
1171
+ kind: ast._tag,
1172
+ dependencies,
1173
+ capabilities,
1174
+ effects: undefined,
1175
+ placement: undefined,
1176
+ priority,
1177
+ tier: "sealed",
1178
+ body: { _tag: ast._tag, mapper: ast.mapper },
1179
+ inputs,
1180
+ ast,
1181
+ payload: undefined
1182
+ })
1183
+ ]);
1184
+ return;
1185
+ }
1186
+ case "AndThen": {
1187
+ observeIdentity(id, "continuation", ast.continuation);
1188
+ const first = `${id}.andThen`;
1189
+ sequence([
1190
+ () => expand(child(ast.first, first)),
1191
+ () => depend(first, "value"),
1192
+ () => {
1193
+ // The continuation builder runs only after the first subtree is
1194
+ // fully observed, exactly where the recursive walk evaluated it.
1195
+ const next = ast.next ?? continuation(ast, id, first);
1196
+ if (next === undefined)
1197
+ return;
1198
+ const thenId = `${id}.then`;
1199
+ sequence([
1200
+ () => expand(child(next, thenId, {
1201
+ prerequisite: first,
1202
+ // Explicit andThen sequences every descendant, not only the
1203
+ // result/join node. bindPlanned remains a dependency builder:
1204
+ // independent members can run while a referenced producer runs.
1205
+ // The first subtree already carries the outer barriers, so
1206
+ // its success transitively gates every nested descendant.
1207
+ barriers: ast.next === undefined ? request.barriers : [first]
1208
+ })),
1209
+ () => depend(thenId, "value")
1210
+ ]);
1211
+ },
1212
+ () => record({
1213
+ id,
1214
+ kind: ast._tag,
1215
+ dependencies,
1216
+ capabilities,
1217
+ effects: undefined,
1218
+ placement: undefined,
1219
+ priority,
1220
+ tier: "sealed",
1221
+ body: { _tag: ast._tag, continuation: ast.continuation, static: ast.next !== undefined },
1222
+ inputs,
1223
+ ast,
1224
+ payload: undefined
1225
+ })
1226
+ ]);
1227
+ return;
1228
+ }
1229
+ case "Branch": {
1230
+ observeIdentity(id, "predicate", ast.predicate);
1231
+ const first = `${id}.branch`;
1232
+ // DECIDED: each Branch AST carries its own
1233
+ // subject token. An outer subject captured inside a nested arm must
1234
+ // retain the outer binding; one shared token silently rebound it to
1235
+ // the inner branch's subject.
1236
+ const arms = new Map([...substitutions, [ast.subject, first]]);
1237
+ sequence([
1238
+ () => expand(child(ast.first, first)),
1239
+ () => depend(first, "value"),
1240
+ () => expand(child(ast.then, `${id}.then`, { substitutions: arms, prerequisite: first })),
1241
+ () => depend(`${id}.then`, "value"),
1242
+ () => expand(child(ast.else, `${id}.else`, { substitutions: arms, prerequisite: first })),
1243
+ () => depend(`${id}.else`, "value"),
1244
+ () => record({
1245
+ id,
1246
+ kind: ast._tag,
1247
+ dependencies,
1248
+ capabilities,
1249
+ effects: undefined,
1250
+ placement: undefined,
1251
+ priority,
1252
+ tier: "sealed",
1253
+ body: { _tag: ast._tag, predicate: ast.predicate },
1254
+ inputs,
1255
+ ast,
1256
+ payload: undefined
1257
+ })
1258
+ ]);
1259
+ return;
1260
+ }
1261
+ case "Catch": {
1262
+ if (ast.filter !== undefined)
1263
+ observeIdentity(id, "filter", ast.filterIdentity);
1264
+ const protectedId = `${id}.protected`;
1265
+ const failureId = `${id}.failure`;
1266
+ // DECIDED: each Catch AST carries its own
1267
+ // subject token, exactly as each Branch does. An outer error captured
1268
+ // inside a nested failure arm must retain the outer binding; one shared
1269
+ // token silently rebound it to the inner catch's protected node.
1270
+ const recovery = new Map([...substitutions, [ast.subject, protectedId]]);
1271
+ sequence([
1272
+ () => expand(child(ast.protected, protectedId)),
1273
+ () => depend(protectedId, "value"),
1274
+ () => expand(child(ast.failure, failureId, { substitutions: recovery, prerequisite: protectedId })),
1275
+ () => {
1276
+ dependencies.push(failureId);
1277
+ observedEdges.push({ from: protectedId, to: failureId, reason: "failure" });
1278
+ observedEdges.push({ from: failureId, to: id, reason: "value" });
1279
+ inputs.push({ _tag: "Ref", from: failureId, path: [] });
1280
+ },
1281
+ () => record({
1282
+ id,
1283
+ kind: ast._tag,
1284
+ dependencies,
1285
+ capabilities,
1286
+ effects: undefined,
1287
+ placement: undefined,
1288
+ priority,
1289
+ tier: "sealed",
1290
+ body: { _tag: ast._tag, filter: ast.filter, filterIdentity: ast.filterIdentity },
1291
+ inputs,
1292
+ ast,
1293
+ payload: undefined
1294
+ })
1295
+ ]);
1296
+ return;
1297
+ }
1298
+ }
1299
+ };
1300
+ const declaration = flowDeclaration(flowOrNode);
1301
+ const root = options.root ?? "root";
1302
+ if (declaration === undefined) {
1303
+ expand({
1304
+ ast: flowOrNode.ast,
1305
+ id: root,
1306
+ depth: 0,
1307
+ capabilities: [],
1308
+ placement: undefined,
1309
+ envelope: undefined,
1310
+ priority: undefined,
1311
+ substitutions: new Map(),
1312
+ stack: [],
1313
+ prerequisite: undefined,
1314
+ barriers: []
1315
+ });
1316
+ }
1317
+ else {
1318
+ const entry = hydrate(payload, new Map(), root);
1319
+ expandFlowCall({
1320
+ id: root,
1321
+ depth: 0,
1322
+ // The entry is a call to the flow itself that no author wrote, so its
1323
+ // AST is synthesized here rather than recorded by `Node.flowCall`, which
1324
+ // would replace a payload's non-JSON values with their plain-object
1325
+ // copies. What a body was planned with stays what the entry node shows.
1326
+ ast: { _tag: "FlowCall", flow: declaration._tag, mode: "inline", payload: entry },
1327
+ flow: declaration._tag,
1328
+ mode: "inline",
1329
+ declaration,
1330
+ payload: entry,
1331
+ capabilities: sorted(Context.get(declaration.annotations, Annotations.Capabilities)),
1332
+ // Nothing encloses the entry, so its own declared placement is what the
1333
+ // body it splices has to be satisfiable under, not a constraint on it.
1334
+ // Its declared envelope reads the same way: the entry is the top of the
1335
+ // authority chain, so it grants rather than narrows.
1336
+ placement: undefined,
1337
+ envelope: undefined,
1338
+ priority: undefined,
1339
+ substitutions: new Map(),
1340
+ stack: [],
1341
+ barriers: [],
1342
+ dependencies: [],
1343
+ inputs: []
1344
+ });
1345
+ }
1346
+ // The walk itself: pop until every stacked step has run. A refusal thrown
1347
+ // by any step propagates out of the build unchanged.
1348
+ while (operations.length > 0)
1349
+ operations.pop()();
1350
+ return {
1351
+ nodes: observed,
1352
+ edges: observedEdges,
1353
+ diagnostics: observedDiagnostics
1354
+ };
1355
+ };
1356
+ /**
1357
+ * The observed nodes, children before the parents that consume them.
1358
+ *
1359
+ * @since 0.1.0
1360
+ * @category accessors
1361
+ */
1362
+ export const nodes = (graph) => graph.nodes;
1363
+ /**
1364
+ * The dependency edges, in the order they were observed.
1365
+ *
1366
+ * @since 0.1.0
1367
+ * @category accessors
1368
+ */
1369
+ export const edges = (graph) => graph.edges;
1370
+ /**
1371
+ * States that a file this runtime is about to evaluate holds bytes read from
1372
+ * another, so the declarations inside it are reported at the file an author
1373
+ * can open.
1374
+ *
1375
+ * A host that verifies a flow's source evaluates THE BYTES IT MEASURED, and
1376
+ * the only way to evaluate bytes here is to write them somewhere and import
1377
+ * that path: `@smthrs/registry` `Executable` writes them as a scratch sibling
1378
+ * of the entry and removes it when the load is over. Without this, every node
1379
+ * of an agent-authored flow names that scratch file, and a reader offered its
1380
+ * path is offered a file nothing holds (D-068).
1381
+ *
1382
+ * The loader states this BEFORE it imports, because a declaration captures its
1383
+ * site while the module is evaluated and never rewrites it. Both sides hold
1384
+ * the same module: a loaded flow is recognized by this package's own type id,
1385
+ * so a graph file resolving a second copy of `@smthrs/flow` is refused as not
1386
+ * a flow at all rather than registered with a site nothing corrected.
1387
+ *
1388
+ * @since 0.1.0
1389
+ * @category constructors
1390
+ */
1391
+ export const evaluatedFrom = (evaluated, entry) => DeclarationSite.evaluatedFrom(evaluated, entry);
1392
+ /**
1393
+ * The drafts, in node order, ready for `Plan.compile` or `Plan.append`
1394
+ * unchanged.
1395
+ *
1396
+ * A graph with a FATAL diagnostic is inspectable but intentionally not
1397
+ * compilable: returning its partial drafts would turn missing topology into a
1398
+ * valid plan. This accessor therefore throws the first fatal build refusal, and
1399
+ * it is the ONLY way to reach the drafts. The built graph holds nodes, and a
1400
+ * draft is the node's own {@link GraphNode.draft}.
1401
+ *
1402
+ * An advisory refusal does not withhold the drafts. The one advisory code is
1403
+ * `capability_outside_grant`, where the callee runs with LESS authority than it
1404
+ * asked for: the author needs to see it, and the graph it describes is exactly
1405
+ * the graph that will run.
1406
+ *
1407
+ * @since 0.1.0
1408
+ * @category accessors
1409
+ */
1410
+ export const drafts = (graph) => {
1411
+ const refusal = graph.diagnostics.find(isFatalDiagnostic);
1412
+ if (refusal !== undefined)
1413
+ throw refusal;
1414
+ return graph.nodes.map((node) => node.draft);
1415
+ };
1416
+ /**
1417
+ * Recoverable topology issues recorded during the build, such as a missing
1418
+ * continuation builder or a continuation that did not produce a node. Fatal
1419
+ * refusals, including computing on a planned value and recursive inline
1420
+ * `.call()`, throw from {@link build} and never appear here.
1421
+ *
1422
+ * @since 0.1.0
1423
+ * @category accessors
1424
+ */
1425
+ export const diagnostics = (graph) => graph.diagnostics;
1426
+ /** Inspect the existing graph model with an unresolved input reference.
1427
+ * Run this only in the same guest that loads the declaration: plan-time body
1428
+ * code is repository code too. An input-dependent body is reported explicitly
1429
+ * without choosing a sample payload. As with Planned values in bodies, use
1430
+ * node combinators for branching; JavaScript truthiness is not inspectable.
1431
+ * @category constructors
1432
+ * @since 1.0.0
1433
+ */
1434
+ export const inspect = (flow) => {
1435
+ const prompt = "prompt" in flow && typeof flow.prompt === "function"
1436
+ ? Function.prototype.toString.call(flow.prompt)
1437
+ : undefined;
1438
+ // The prompt source belongs to the declaration, so it rides on every
1439
+ // inspection, whether or not the graph could be built.
1440
+ const withPrompt = (inspection) => prompt === undefined ? inspection : { ...inspection, prompt };
1441
+ try {
1442
+ const graph = build(flow, Planned.make("input"));
1443
+ const nodes = graph.nodes.map((node) => ({
1444
+ id: node.id,
1445
+ kind: node.kind,
1446
+ ...(node.ast._tag === "FlowCall" ?
1447
+ { label: node.ast.flow }
1448
+ : node.ast._tag === "ActionCall"
1449
+ ? { label: node.ast.action }
1450
+ : {}),
1451
+ dependencies: node.dependencies
1452
+ }));
1453
+ // Inline flow calls group the actions beneath them; only boundary calls
1454
+ // and actions are steps, so the same work is never displayed twice.
1455
+ const steps = graph.nodes.flatMap((node) => node.ast._tag === "ActionCall" ?
1456
+ [{ id: node.id, label: node.ast.action }]
1457
+ : node.ast._tag === "FlowCall" && node.ast.mode !== "inline"
1458
+ ? [{ id: node.id, label: node.ast.flow }]
1459
+ : []);
1460
+ return withPrompt({
1461
+ nodes,
1462
+ edges: graph.edges,
1463
+ steps,
1464
+ diagnostics: graph.diagnostics.map(({ code, message }) => ({ code, message }))
1465
+ });
1466
+ }
1467
+ catch (error) {
1468
+ return withPrompt({
1469
+ // The declaration itself is a known boundary even when its internals
1470
+ // require real input. Do not publish a fictitious empty execution.
1471
+ nodes: [{ id: "root", kind: "FlowCall", label: flow._tag, dependencies: [] }],
1472
+ edges: [],
1473
+ steps: [{ id: "root", label: flow._tag }],
1474
+ diagnostics: [{
1475
+ code: error instanceof GraphBuildError
1476
+ ? error.code === "planned_value_computed" ? "declaration_requires_input" : error.code
1477
+ : "declaration_inspection_failed",
1478
+ message: error instanceof Error ? error.message : String(error)
1479
+ }]
1480
+ });
1481
+ }
1482
+ };
1483
+ //# sourceMappingURL=Graph.js.map