@smthrs/flow 0.0.0-stage → 1.0.0-rc.12

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