footprintjs 10.0.1 → 10.2.0

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 (368) hide show
  1. package/AGENTS.md +2 -1
  2. package/CLAUDE.md +61 -7
  3. package/README.md +136 -312
  4. package/dist/esm/index.d.ts +62 -2
  5. package/dist/esm/index.js +13 -6
  6. package/dist/esm/lib/attempt/anySignal.d.ts +19 -0
  7. package/dist/esm/lib/attempt/anySignal.js +39 -0
  8. package/dist/esm/lib/attempt/call.d.ts +88 -0
  9. package/dist/esm/lib/attempt/call.js +129 -0
  10. package/dist/esm/lib/attempt/category.d.ts +37 -0
  11. package/dist/esm/lib/attempt/category.js +131 -0
  12. package/dist/esm/lib/attempt/correlation.d.ts +95 -0
  13. package/dist/esm/lib/attempt/correlation.js +178 -0
  14. package/dist/esm/lib/attempt/deadline.d.ts +44 -0
  15. package/dist/esm/lib/attempt/deadline.js +101 -0
  16. package/dist/esm/lib/attempt/decision.d.ts +52 -0
  17. package/dist/esm/lib/attempt/decision.js +134 -0
  18. package/dist/esm/lib/attempt/effect.d.ts +76 -0
  19. package/dist/esm/lib/attempt/effect.js +160 -0
  20. package/dist/esm/lib/attempt/errors.d.ts +41 -0
  21. package/dist/esm/lib/attempt/errors.js +44 -0
  22. package/dist/esm/lib/attempt/index.d.ts +18 -0
  23. package/dist/esm/lib/attempt/index.js +15 -0
  24. package/dist/esm/lib/attempt/name.d.ts +21 -0
  25. package/dist/esm/lib/attempt/name.js +43 -0
  26. package/dist/esm/lib/attempt/observed.d.ts +66 -0
  27. package/dist/esm/lib/attempt/observed.js +171 -0
  28. package/dist/esm/lib/attempt/policy.d.ts +45 -0
  29. package/dist/esm/lib/attempt/policy.js +83 -0
  30. package/dist/esm/lib/attempt/record.d.ts +11 -0
  31. package/dist/esm/lib/attempt/record.js +24 -0
  32. package/dist/esm/lib/attempt/retryLoopContext.d.ts +18 -0
  33. package/dist/esm/lib/attempt/retryLoopContext.js +24 -0
  34. package/dist/esm/lib/attempt/retryLoopTypes.d.ts +18 -0
  35. package/dist/esm/lib/attempt/retryLoopTypes.js +2 -0
  36. package/dist/esm/lib/attempt/runner.d.ts +157 -0
  37. package/dist/esm/lib/attempt/runner.js +523 -0
  38. package/dist/esm/lib/attempt/standalone.d.ts +47 -0
  39. package/dist/esm/lib/attempt/standalone.js +126 -0
  40. package/dist/esm/lib/attempt/types.d.ts +453 -0
  41. package/dist/esm/lib/attempt/types.js +16 -0
  42. package/dist/esm/lib/budget/index.d.ts +9 -0
  43. package/dist/esm/lib/budget/index.js +9 -0
  44. package/dist/esm/lib/budget/timeBudget.d.ts +136 -0
  45. package/dist/esm/lib/budget/timeBudget.js +666 -0
  46. package/dist/esm/lib/builder/FlowChartBuilder.d.ts +88 -3
  47. package/dist/esm/lib/builder/FlowChartBuilder.js +199 -9
  48. package/dist/esm/lib/builder/retryLoop.d.ts +56 -0
  49. package/dist/esm/lib/builder/retryLoop.js +283 -0
  50. package/dist/esm/lib/builder/types.d.ts +35 -1
  51. package/dist/esm/lib/builder/types.js +1 -1
  52. package/dist/esm/lib/decide/decide.js +2 -2
  53. package/dist/esm/lib/decide/index.d.ts +1 -1
  54. package/dist/esm/lib/decide/index.js +2 -2
  55. package/dist/esm/lib/decide/types.d.ts +3 -0
  56. package/dist/esm/lib/decide/types.js +1 -8
  57. package/dist/esm/lib/engine/graph/StageNode.d.ts +11 -1
  58. package/dist/esm/lib/engine/graph/StageNode.js +1 -1
  59. package/dist/esm/lib/engine/graph/prefixNodeTree.js +5 -1
  60. package/dist/esm/lib/engine/handlers/ChildrenExecutor.js +36 -6
  61. package/dist/esm/lib/engine/handlers/DeciderHandler.js +9 -5
  62. package/dist/esm/lib/engine/handlers/ResumeEntry.js +3 -1
  63. package/dist/esm/lib/engine/handlers/SelectorHandler.js +6 -5
  64. package/dist/esm/lib/engine/handlers/StageRunner.d.ts +8 -1
  65. package/dist/esm/lib/engine/handlers/StageRunner.js +36 -9
  66. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +24 -5
  67. package/dist/esm/lib/engine/handlers/commitStage.d.ts +7 -0
  68. package/dist/esm/lib/engine/handlers/commitStage.js +22 -4
  69. package/dist/esm/lib/engine/handlers/stageError.d.ts +9 -0
  70. package/dist/esm/lib/engine/handlers/stageError.js +23 -1
  71. package/dist/esm/lib/engine/index.d.ts +2 -2
  72. package/dist/esm/lib/engine/index.js +1 -1
  73. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
  74. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +68 -40
  75. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
  76. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
  77. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
  78. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.js +61 -9
  79. package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
  80. package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
  81. package/dist/esm/lib/engine/narrative/formatting/sentences.d.ts +23 -0
  82. package/dist/esm/lib/engine/narrative/formatting/sentences.js +127 -1
  83. package/dist/esm/lib/engine/narrative/index.d.ts +2 -2
  84. package/dist/esm/lib/engine/narrative/index.js +1 -1
  85. package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +27 -21
  86. package/dist/esm/lib/engine/narrative/narrativeTypes.js +1 -1
  87. package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
  88. package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
  89. package/dist/esm/lib/engine/narrative/recorders/index.d.ts +1 -1
  90. package/dist/esm/lib/engine/narrative/recorders/index.js +1 -1
  91. package/dist/esm/lib/engine/narrative/types.d.ts +74 -5
  92. package/dist/esm/lib/engine/narrative/types.js +1 -1
  93. package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
  94. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +194 -118
  95. package/dist/esm/lib/engine/traversalContext.d.ts +7 -2
  96. package/dist/esm/lib/engine/traversalContext.js +6 -3
  97. package/dist/esm/lib/engine/types.d.ts +52 -57
  98. package/dist/esm/lib/engine/types.js +1 -1
  99. package/dist/esm/lib/errors/terminalFailure.d.ts +29 -0
  100. package/dist/esm/lib/errors/terminalFailure.js +60 -0
  101. package/dist/esm/lib/{decide → filter}/evaluator.d.ts +7 -2
  102. package/dist/esm/lib/filter/evaluator.js +135 -0
  103. package/dist/esm/lib/ids/idempotencyKey.d.ts +14 -0
  104. package/dist/esm/lib/ids/idempotencyKey.js +24 -0
  105. package/dist/esm/lib/memory/StageContext.d.ts +123 -3
  106. package/dist/esm/lib/memory/StageContext.js +245 -4
  107. package/dist/esm/lib/memory/attention.d.ts +26 -0
  108. package/dist/esm/lib/memory/attention.js +171 -0
  109. package/dist/esm/lib/memory/borrowedMutation.d.ts +8 -0
  110. package/dist/esm/lib/memory/borrowedMutation.js +14 -1
  111. package/dist/esm/lib/memory/frameTypes.d.ts +38 -0
  112. package/dist/esm/lib/memory/frameTypes.js +3 -1
  113. package/dist/esm/lib/memory/redaction.d.ts +12 -0
  114. package/dist/esm/lib/memory/redaction.js +54 -5
  115. package/dist/esm/lib/pause/record.js +10 -1
  116. package/dist/esm/lib/pause/types.d.ts +19 -0
  117. package/dist/esm/lib/pause/types.js +17 -1
  118. package/dist/esm/lib/reactive/createTypedScope.js +3 -1
  119. package/dist/esm/lib/reactive/types.d.ts +36 -4
  120. package/dist/esm/lib/reactive/types.js +3 -1
  121. package/dist/esm/lib/recorder/AttemptRecorder.d.ts +141 -0
  122. package/dist/esm/lib/recorder/AttemptRecorder.js +412 -0
  123. package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +36 -2
  124. package/dist/esm/lib/recorder/ControlDepRecorder.js +50 -2
  125. package/dist/esm/lib/recorder/EmitRecorder.d.ts +3 -0
  126. package/dist/esm/lib/recorder/EmitRecorder.js +1 -1
  127. package/dist/esm/lib/recorder/InOutRecorder.d.ts +37 -1
  128. package/dist/esm/lib/recorder/InOutRecorder.js +75 -6
  129. package/dist/esm/lib/recorder/QualityRecorder.d.ts +32 -5
  130. package/dist/esm/lib/recorder/QualityRecorder.js +87 -29
  131. package/dist/esm/lib/recorder/TopologyRecorder.d.ts +35 -5
  132. package/dist/esm/lib/recorder/TopologyRecorder.js +76 -2
  133. package/dist/esm/lib/recorder/attemptMetricRows.d.ts +11 -0
  134. package/dist/esm/lib/recorder/attemptMetricRows.js +202 -0
  135. package/dist/esm/lib/recorder/attemptMetrics.d.ts +7 -0
  136. package/dist/esm/lib/recorder/attemptMetrics.js +165 -0
  137. package/dist/esm/lib/recorder/attemptMetricsTypes.d.ts +114 -0
  138. package/dist/esm/lib/recorder/attemptMetricsTypes.js +2 -0
  139. package/dist/esm/lib/recorder/attemptOTel.d.ts +78 -0
  140. package/dist/esm/lib/recorder/attemptOTel.js +107 -0
  141. package/dist/esm/lib/recorder/attemptSeries.d.ts +81 -0
  142. package/dist/esm/lib/recorder/attemptSeries.js +103 -0
  143. package/dist/esm/lib/recorder/hooks.d.ts +9 -0
  144. package/dist/esm/lib/recorder/hooks.js +4 -1
  145. package/dist/esm/lib/runner/DeferredObserverTier.js +13 -1
  146. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +54 -6
  147. package/dist/esm/lib/runner/ExecutionRuntime.js +57 -5
  148. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +46 -2
  149. package/dist/esm/lib/runner/FlowChartExecutor.js +330 -101
  150. package/dist/esm/lib/runner/RunnableChart.d.ts +6 -0
  151. package/dist/esm/lib/runner/RunnableChart.js +5 -1
  152. package/dist/esm/lib/runner/attach.d.ts +2 -1
  153. package/dist/esm/lib/runner/attach.js +8 -2
  154. package/dist/esm/lib/runner/checkpoint.js +3 -1
  155. package/dist/esm/lib/runner/deadline.d.ts +42 -0
  156. package/dist/esm/lib/runner/deadline.js +90 -0
  157. package/dist/esm/lib/runner/index.d.ts +3 -1
  158. package/dist/esm/lib/runner/index.js +2 -1
  159. package/dist/esm/lib/runner/options.d.ts +17 -0
  160. package/dist/esm/lib/runner/options.js +3 -1
  161. package/dist/esm/lib/runner/recordSink.d.ts +128 -0
  162. package/dist/esm/lib/runner/recordSink.js +296 -0
  163. package/dist/esm/lib/runner/resume.d.ts +3 -0
  164. package/dist/esm/lib/runner/resume.js +22 -2
  165. package/dist/esm/lib/runner/snapshot.d.ts +2 -2
  166. package/dist/esm/lib/runner/snapshot.js +6 -2
  167. package/dist/esm/lib/scope/ScopeFacade.d.ts +118 -4
  168. package/dist/esm/lib/scope/ScopeFacade.js +304 -7
  169. package/dist/esm/lib/scope/recorders/DebugRecorder.d.ts +17 -3
  170. package/dist/esm/lib/scope/recorders/DebugRecorder.js +79 -13
  171. package/dist/esm/lib/scope/recorders/MetricRecorder.d.ts +10 -0
  172. package/dist/esm/lib/scope/recorders/MetricRecorder.js +15 -2
  173. package/dist/esm/lib/scope/runtime.d.ts +3 -0
  174. package/dist/esm/lib/scope/runtime.js +1 -1
  175. package/dist/esm/lib/scope/types.d.ts +6 -0
  176. package/dist/esm/lib/scope/types.js +1 -1
  177. package/dist/esm/lib/sinks/fileSink.d.ts +135 -0
  178. package/dist/esm/lib/sinks/fileSink.js +387 -0
  179. package/dist/esm/recorders.d.ts +8 -2
  180. package/dist/esm/recorders.js +7 -1
  181. package/dist/esm/sinks.d.ts +23 -0
  182. package/dist/esm/sinks.js +23 -0
  183. package/dist/esm/trace.d.ts +2 -2
  184. package/dist/esm/trace.js +1 -1
  185. package/dist/index.js +77 -60
  186. package/dist/lib/attempt/anySignal.js +43 -0
  187. package/dist/lib/attempt/call.js +134 -0
  188. package/dist/lib/attempt/category.js +136 -0
  189. package/dist/lib/attempt/correlation.js +186 -0
  190. package/dist/lib/attempt/deadline.js +112 -0
  191. package/dist/lib/attempt/decision.js +139 -0
  192. package/dist/lib/attempt/effect.js +174 -0
  193. package/dist/lib/attempt/errors.js +49 -0
  194. package/dist/lib/attempt/index.js +26 -0
  195. package/dist/lib/attempt/name.js +48 -0
  196. package/dist/lib/attempt/observed.js +177 -0
  197. package/dist/lib/attempt/policy.js +92 -0
  198. package/dist/lib/attempt/record.js +29 -0
  199. package/dist/lib/attempt/retryLoopContext.js +31 -0
  200. package/dist/lib/attempt/retryLoopTypes.js +3 -0
  201. package/dist/lib/attempt/runner.js +530 -0
  202. package/dist/lib/attempt/standalone.js +130 -0
  203. package/dist/lib/attempt/types.js +17 -0
  204. package/dist/lib/budget/index.js +17 -0
  205. package/dist/lib/budget/timeBudget.js +674 -0
  206. package/dist/lib/builder/FlowChartBuilder.js +199 -9
  207. package/dist/lib/builder/retryLoop.js +287 -0
  208. package/dist/lib/builder/types.js +1 -1
  209. package/dist/lib/decide/decide.js +2 -2
  210. package/dist/lib/decide/index.js +2 -2
  211. package/dist/lib/decide/types.js +1 -8
  212. package/dist/lib/engine/graph/StageNode.js +1 -1
  213. package/dist/lib/engine/graph/prefixNodeTree.js +5 -1
  214. package/dist/lib/engine/handlers/ChildrenExecutor.js +36 -6
  215. package/dist/lib/engine/handlers/DeciderHandler.js +7 -3
  216. package/dist/lib/engine/handlers/ResumeEntry.js +3 -1
  217. package/dist/lib/engine/handlers/SelectorHandler.js +4 -3
  218. package/dist/lib/engine/handlers/StageRunner.js +36 -9
  219. package/dist/lib/engine/handlers/SubflowExecutor.js +24 -5
  220. package/dist/lib/engine/handlers/commitStage.js +24 -5
  221. package/dist/lib/engine/handlers/stageError.js +26 -2
  222. package/dist/lib/engine/index.js +1 -1
  223. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +67 -39
  224. package/dist/lib/engine/narrative/FlowRecorderDispatcher.js +19 -2
  225. package/dist/lib/engine/narrative/NarrativeFlowRecorder.js +60 -8
  226. package/dist/lib/engine/narrative/NullControlFlowNarrativeGenerator.js +2 -1
  227. package/dist/lib/engine/narrative/formatting/sentences.js +131 -2
  228. package/dist/lib/engine/narrative/index.js +1 -1
  229. package/dist/lib/engine/narrative/narrativeTypes.js +1 -1
  230. package/dist/lib/engine/narrative/recorders/ManifestFlowRecorder.js +55 -2
  231. package/dist/lib/engine/narrative/recorders/index.js +1 -1
  232. package/dist/lib/engine/narrative/types.js +1 -1
  233. package/dist/lib/engine/traversal/FlowchartTraverser.js +192 -116
  234. package/dist/lib/engine/traversalContext.js +6 -3
  235. package/dist/lib/engine/types.js +1 -1
  236. package/dist/lib/errors/terminalFailure.js +64 -0
  237. package/dist/lib/filter/evaluator.js +139 -0
  238. package/dist/lib/ids/idempotencyKey.js +28 -0
  239. package/dist/lib/memory/StageContext.js +246 -5
  240. package/dist/lib/memory/attention.js +175 -0
  241. package/dist/lib/memory/borrowedMutation.js +16 -2
  242. package/dist/lib/memory/frameTypes.js +3 -1
  243. package/dist/lib/memory/redaction.js +54 -5
  244. package/dist/lib/pause/record.js +10 -1
  245. package/dist/lib/pause/types.js +17 -1
  246. package/dist/lib/reactive/createTypedScope.js +3 -1
  247. package/dist/lib/reactive/types.js +3 -1
  248. package/dist/lib/recorder/AttemptRecorder.js +417 -0
  249. package/dist/lib/recorder/ControlDepRecorder.js +50 -2
  250. package/dist/lib/recorder/EmitRecorder.js +1 -1
  251. package/dist/lib/recorder/InOutRecorder.js +75 -6
  252. package/dist/lib/recorder/QualityRecorder.js +87 -29
  253. package/dist/lib/recorder/TopologyRecorder.js +76 -2
  254. package/dist/lib/recorder/attemptMetricRows.js +209 -0
  255. package/dist/lib/recorder/attemptMetrics.js +174 -0
  256. package/dist/lib/recorder/attemptMetricsTypes.js +3 -0
  257. package/dist/lib/recorder/attemptOTel.js +111 -0
  258. package/dist/lib/recorder/attemptSeries.js +113 -0
  259. package/dist/lib/recorder/hooks.js +4 -1
  260. package/dist/lib/runner/DeferredObserverTier.js +13 -1
  261. package/dist/lib/runner/ExecutionRuntime.js +57 -5
  262. package/dist/lib/runner/FlowChartExecutor.js +330 -101
  263. package/dist/lib/runner/RunnableChart.js +5 -1
  264. package/dist/lib/runner/attach.js +8 -2
  265. package/dist/lib/runner/checkpoint.js +3 -1
  266. package/dist/lib/runner/deadline.js +94 -0
  267. package/dist/lib/runner/index.js +4 -2
  268. package/dist/lib/runner/options.js +3 -1
  269. package/dist/lib/runner/recordSink.js +302 -0
  270. package/dist/lib/runner/resume.js +22 -2
  271. package/dist/lib/runner/snapshot.js +6 -2
  272. package/dist/lib/scope/ScopeFacade.js +303 -6
  273. package/dist/lib/scope/recorders/DebugRecorder.js +79 -13
  274. package/dist/lib/scope/recorders/MetricRecorder.js +15 -2
  275. package/dist/lib/scope/runtime.js +1 -1
  276. package/dist/lib/scope/types.js +1 -1
  277. package/dist/lib/sinks/fileSink.js +392 -0
  278. package/dist/recorders.js +10 -2
  279. package/dist/sinks.js +32 -0
  280. package/dist/trace.js +1 -1
  281. package/dist/types/index.d.ts +62 -2
  282. package/dist/types/lib/attempt/anySignal.d.ts +19 -0
  283. package/dist/types/lib/attempt/call.d.ts +88 -0
  284. package/dist/types/lib/attempt/category.d.ts +37 -0
  285. package/dist/types/lib/attempt/correlation.d.ts +95 -0
  286. package/dist/types/lib/attempt/deadline.d.ts +44 -0
  287. package/dist/types/lib/attempt/decision.d.ts +52 -0
  288. package/dist/types/lib/attempt/effect.d.ts +76 -0
  289. package/dist/types/lib/attempt/errors.d.ts +41 -0
  290. package/dist/types/lib/attempt/index.d.ts +18 -0
  291. package/dist/types/lib/attempt/name.d.ts +21 -0
  292. package/dist/types/lib/attempt/observed.d.ts +66 -0
  293. package/dist/types/lib/attempt/policy.d.ts +45 -0
  294. package/dist/types/lib/attempt/record.d.ts +11 -0
  295. package/dist/types/lib/attempt/retryLoopContext.d.ts +18 -0
  296. package/dist/types/lib/attempt/retryLoopTypes.d.ts +18 -0
  297. package/dist/types/lib/attempt/runner.d.ts +157 -0
  298. package/dist/types/lib/attempt/standalone.d.ts +47 -0
  299. package/dist/types/lib/attempt/types.d.ts +453 -0
  300. package/dist/types/lib/budget/index.d.ts +9 -0
  301. package/dist/types/lib/budget/timeBudget.d.ts +136 -0
  302. package/dist/types/lib/builder/FlowChartBuilder.d.ts +88 -3
  303. package/dist/types/lib/builder/retryLoop.d.ts +56 -0
  304. package/dist/types/lib/builder/types.d.ts +35 -1
  305. package/dist/types/lib/decide/index.d.ts +1 -1
  306. package/dist/types/lib/decide/types.d.ts +3 -0
  307. package/dist/types/lib/engine/graph/StageNode.d.ts +11 -1
  308. package/dist/types/lib/engine/handlers/StageRunner.d.ts +8 -1
  309. package/dist/types/lib/engine/handlers/commitStage.d.ts +7 -0
  310. package/dist/types/lib/engine/handlers/stageError.d.ts +9 -0
  311. package/dist/types/lib/engine/index.d.ts +2 -2
  312. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +27 -13
  313. package/dist/types/lib/engine/narrative/FlowRecorderDispatcher.d.ts +4 -1
  314. package/dist/types/lib/engine/narrative/NarrativeFlowRecorder.d.ts +22 -3
  315. package/dist/types/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +1 -0
  316. package/dist/types/lib/engine/narrative/formatting/sentences.d.ts +23 -0
  317. package/dist/types/lib/engine/narrative/index.d.ts +2 -2
  318. package/dist/types/lib/engine/narrative/narrativeTypes.d.ts +27 -21
  319. package/dist/types/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +45 -2
  320. package/dist/types/lib/engine/narrative/recorders/index.d.ts +1 -1
  321. package/dist/types/lib/engine/narrative/types.d.ts +74 -5
  322. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +59 -19
  323. package/dist/types/lib/engine/traversalContext.d.ts +7 -2
  324. package/dist/types/lib/engine/types.d.ts +52 -57
  325. package/dist/types/lib/errors/terminalFailure.d.ts +29 -0
  326. package/dist/types/lib/{decide → filter}/evaluator.d.ts +7 -2
  327. package/dist/types/lib/ids/idempotencyKey.d.ts +14 -0
  328. package/dist/types/lib/memory/StageContext.d.ts +123 -3
  329. package/dist/types/lib/memory/attention.d.ts +26 -0
  330. package/dist/types/lib/memory/borrowedMutation.d.ts +8 -0
  331. package/dist/types/lib/memory/frameTypes.d.ts +38 -0
  332. package/dist/types/lib/memory/redaction.d.ts +12 -0
  333. package/dist/types/lib/pause/types.d.ts +19 -0
  334. package/dist/types/lib/reactive/types.d.ts +36 -4
  335. package/dist/types/lib/recorder/AttemptRecorder.d.ts +141 -0
  336. package/dist/types/lib/recorder/ControlDepRecorder.d.ts +36 -2
  337. package/dist/types/lib/recorder/EmitRecorder.d.ts +3 -0
  338. package/dist/types/lib/recorder/InOutRecorder.d.ts +37 -1
  339. package/dist/types/lib/recorder/QualityRecorder.d.ts +32 -5
  340. package/dist/types/lib/recorder/TopologyRecorder.d.ts +35 -5
  341. package/dist/types/lib/recorder/attemptMetricRows.d.ts +11 -0
  342. package/dist/types/lib/recorder/attemptMetrics.d.ts +7 -0
  343. package/dist/types/lib/recorder/attemptMetricsTypes.d.ts +114 -0
  344. package/dist/types/lib/recorder/attemptOTel.d.ts +78 -0
  345. package/dist/types/lib/recorder/attemptSeries.d.ts +81 -0
  346. package/dist/types/lib/recorder/hooks.d.ts +9 -0
  347. package/dist/types/lib/runner/ExecutionRuntime.d.ts +54 -6
  348. package/dist/types/lib/runner/FlowChartExecutor.d.ts +46 -2
  349. package/dist/types/lib/runner/RunnableChart.d.ts +6 -0
  350. package/dist/types/lib/runner/attach.d.ts +2 -1
  351. package/dist/types/lib/runner/deadline.d.ts +42 -0
  352. package/dist/types/lib/runner/index.d.ts +3 -1
  353. package/dist/types/lib/runner/options.d.ts +17 -0
  354. package/dist/types/lib/runner/recordSink.d.ts +128 -0
  355. package/dist/types/lib/runner/resume.d.ts +3 -0
  356. package/dist/types/lib/runner/snapshot.d.ts +2 -2
  357. package/dist/types/lib/scope/ScopeFacade.d.ts +118 -4
  358. package/dist/types/lib/scope/recorders/DebugRecorder.d.ts +17 -3
  359. package/dist/types/lib/scope/recorders/MetricRecorder.d.ts +10 -0
  360. package/dist/types/lib/scope/runtime.d.ts +3 -0
  361. package/dist/types/lib/scope/types.d.ts +6 -0
  362. package/dist/types/lib/sinks/fileSink.d.ts +135 -0
  363. package/dist/types/recorders.d.ts +8 -2
  364. package/dist/types/sinks.d.ts +23 -0
  365. package/dist/types/trace.d.ts +2 -2
  366. package/package.json +20 -6
  367. package/dist/esm/lib/decide/evaluator.js +0 -130
  368. package/dist/lib/decide/evaluator.js +0 -134
@@ -0,0 +1,101 @@
1
+ /**
2
+ * attempt/deadline.ts — what the run's deadline IS, to everything that reads time (design §3.1, law 3).
3
+ *
4
+ * The deadline is one number, epoch milliseconds (`env.deadline`); the executor arms the run's signal to abort when
5
+ * it passes (`runner/deadline.ts · armRun`). Reaching it is NOT a cancellation: an attempt the deadline cuts short
6
+ * timed out (it had no answer in the time it had — law 4), and the series stops `no-time-left`, not `aborted`. So
7
+ * the reason the run's signal aborts with at the deadline is BRANDED here, and the attempt runner tells the two
8
+ * apart by the brand — never by the message, never by the clock.
9
+ *
10
+ * The brand is a module-private WeakSet: an ordinary `Error` (same message, same name a run with `timeoutMs` always
11
+ * rejected with), recognisable only by identity.
12
+ */
13
+ import { anySignal } from './anySignal.js';
14
+ const DEADLINE_REASONS = new WeakSet();
15
+ /** The reason the run's signal aborts with when its deadline passes — an `Error`, branded as the deadline's. */
16
+ export function deadlineReason(message) {
17
+ const reason = new Error(message);
18
+ DEADLINE_REASONS.add(reason);
19
+ return reason;
20
+ }
21
+ /**
22
+ * Brand `reason` as a time limit — what an attempt's own cap aborts with (P2). An attempt's cap is the deadline of
23
+ * every call made inside it (`attempt/call.ts`), so a call it cuts ran out of time: `'timeout'`, never `'aborted'`.
24
+ * The run's own signal never aborts with it, so a stage attempt reads nothing new.
25
+ */
26
+ export function markTimeLimit(reason) {
27
+ DEADLINE_REASONS.add(reason);
28
+ return reason;
29
+ }
30
+ /** Whether `reason` is the run's deadline or an attempt's cap — a time limit, not a cancellation. */
31
+ export function isDeadlineReason(reason) {
32
+ return typeof reason === 'object' && reason !== null && DEADLINE_REASONS.has(reason);
33
+ }
34
+ /** Whether the signal aborted for a reason OTHER than a time limit — a cancellation. */
35
+ export function isCancelled(signal) {
36
+ return signal?.aborted === true && !isDeadlineReason(signal.reason);
37
+ }
38
+ /** A deadline as the engine reads one: a finite number (epoch ms), else none. */
39
+ export function readDeadline(value) {
40
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
41
+ }
42
+ /** The longest delay a host timer honours (2^31 − 1 ms, ~24.8 days); a longer one fires at once. */
43
+ const MAX_TIMER_MS = 2_147_483_647;
44
+ /**
45
+ * `setTimeout` for any delay: a delay past the host's limit is waited in chunks, so a 30-day deadline does not fire
46
+ * in a millisecond. Returns the one call that cancels it.
47
+ */
48
+ export function setLongTimeout(fn, ms) {
49
+ let timer;
50
+ let cancelled = false;
51
+ const arm = (left) => {
52
+ timer = setTimeout(() => {
53
+ if (cancelled)
54
+ return;
55
+ if (left > MAX_TIMER_MS)
56
+ arm(left - MAX_TIMER_MS);
57
+ else
58
+ fn();
59
+ }, Math.min(left, MAX_TIMER_MS));
60
+ };
61
+ arm(Math.max(0, ms));
62
+ return () => {
63
+ cancelled = true;
64
+ if (timer !== undefined)
65
+ clearTimeout(timer);
66
+ };
67
+ }
68
+ /** Whether `value` is an AbortSignal (structurally — a signal from another realm counts). */
69
+ export function isAbortSignal(value) {
70
+ return (typeof value === 'object' &&
71
+ value !== null &&
72
+ typeof value.aborted === 'boolean' &&
73
+ typeof value.addEventListener === 'function' &&
74
+ typeof value.removeEventListener === 'function');
75
+ }
76
+ /**
77
+ * Compose `signal` with a timer that aborts at `deadline` (epoch ms) with a branded {@link deadlineReason} — so the
78
+ * attempt runner's reading holds: the signal it is handed aborts at the deadline, as the run's does (`armRun`). A
79
+ * deadline already past aborts at once; without a deadline the signal is handed back as it is.
80
+ */
81
+ export function armDeadline(signal, deadline, message, now = Date.now) {
82
+ if (deadline === undefined)
83
+ return { signal, dispose: () => undefined };
84
+ const timer = new AbortController();
85
+ const composed = anySignal([signal, timer.signal]);
86
+ const reason = deadlineReason(message);
87
+ const left = deadline - now();
88
+ let cancel = () => undefined;
89
+ if (left <= 0)
90
+ timer.abort(reason);
91
+ else
92
+ cancel = setLongTimeout(() => timer.abort(reason), left);
93
+ return {
94
+ signal: composed.signal,
95
+ dispose: () => {
96
+ cancel();
97
+ composed.dispose();
98
+ },
99
+ };
100
+ }
101
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVhZGxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2F0dGVtcHQvZGVhZGxpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7O0dBV0c7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO0FBRS9DLGdIQUFnSDtBQUNoSCxNQUFNLFVBQVUsY0FBYyxDQUFDLE9BQWU7SUFDNUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbEMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdCLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLGFBQWEsQ0FBbUIsTUFBUztJQUN2RCxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDN0IsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELHFHQUFxRztBQUNyRyxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsTUFBZTtJQUM5QyxPQUFPLE9BQU8sTUFBTSxLQUFLLFFBQVEsSUFBSSxNQUFNLEtBQUssSUFBSSxJQUFJLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN2RixDQUFDO0FBRUQsd0ZBQXdGO0FBQ3hGLE1BQU0sVUFBVSxXQUFXLENBQUMsTUFBK0I7SUFDekQsT0FBTyxNQUFNLEVBQUUsT0FBTyxLQUFLLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUN0RSxDQUFDO0FBRUQsaUZBQWlGO0FBQ2pGLE1BQU0sVUFBVSxZQUFZLENBQUMsS0FBYztJQUN6QyxPQUFPLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUNqRixDQUFDO0FBRUQsb0dBQW9HO0FBQ3BHLE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQztBQUVuQzs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLEVBQWMsRUFBRSxFQUFVO0lBQ3ZELElBQUksS0FBZ0QsQ0FBQztJQUNyRCxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDdEIsTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRTtRQUMzQixLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUN0QixJQUFJLFNBQVM7Z0JBQUUsT0FBTztZQUN0QixJQUFJLElBQUksR0FBRyxZQUFZO2dCQUFFLEdBQUcsQ0FBQyxJQUFJLEdBQUcsWUFBWSxDQUFDLENBQUM7O2dCQUM3QyxFQUFFLEVBQUUsQ0FBQztRQUNaLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQ25DLENBQUMsQ0FBQztJQUNGLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3JCLE9BQU8sR0FBRyxFQUFFO1FBQ1YsU0FBUyxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLEtBQUssS0FBSyxTQUFTO1lBQUUsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQy9DLENBQUMsQ0FBQztBQUNKLENBQUM7QUFFRCw2RkFBNkY7QUFDN0YsTUFBTSxVQUFVLGFBQWEsQ0FBQyxLQUFjO0lBQzFDLE9BQU8sQ0FDTCxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQ3pCLEtBQUssS0FBSyxJQUFJO1FBQ2QsT0FBUSxLQUFxQixDQUFDLE9BQU8sS0FBSyxTQUFTO1FBQ25ELE9BQVEsS0FBcUIsQ0FBQyxnQkFBZ0IsS0FBSyxVQUFVO1FBQzdELE9BQVEsS0FBcUIsQ0FBQyxtQkFBbUIsS0FBSyxVQUFVLENBQ2pFLENBQUM7QUFDSixDQUFDO0FBUUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQ3pCLE1BQStCLEVBQy9CLFFBQTRCLEVBQzVCLE9BQWUsRUFDZixNQUFvQixJQUFJLENBQUMsR0FBRztJQUU1QixJQUFJLFFBQVEsS0FBSyxTQUFTO1FBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDeEUsTUFBTSxLQUFLLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUNwQyxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDbkQsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sSUFBSSxHQUFHLFFBQVEsR0FBRyxHQUFHLEVBQUUsQ0FBQztJQUM5QixJQUFJLE1BQU0sR0FBZSxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUM7SUFDekMsSUFBSSxJQUFJLElBQUksQ0FBQztRQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7O1FBQzlCLE1BQU0sR0FBRyxjQUFjLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM5RCxPQUFPO1FBQ0wsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNO1FBQ3ZCLE9BQU8sRUFBRSxHQUFHLEVBQUU7WUFDWixNQUFNLEVBQUUsQ0FBQztZQUNULFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNyQixDQUFDO0tBQ0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGF0dGVtcHQvZGVhZGxpbmUudHMg4oCUIHdoYXQgdGhlIHJ1bidzIGRlYWRsaW5lIElTLCB0byBldmVyeXRoaW5nIHRoYXQgcmVhZHMgdGltZSAoZGVzaWduIMKnMy4xLCBsYXcgMykuXG4gKlxuICogVGhlIGRlYWRsaW5lIGlzIG9uZSBudW1iZXIsIGVwb2NoIG1pbGxpc2Vjb25kcyAoYGVudi5kZWFkbGluZWApOyB0aGUgZXhlY3V0b3IgYXJtcyB0aGUgcnVuJ3Mgc2lnbmFsIHRvIGFib3J0IHdoZW5cbiAqIGl0IHBhc3NlcyAoYHJ1bm5lci9kZWFkbGluZS50cyDCtyBhcm1SdW5gKS4gUmVhY2hpbmcgaXQgaXMgTk9UIGEgY2FuY2VsbGF0aW9uOiBhbiBhdHRlbXB0IHRoZSBkZWFkbGluZSBjdXRzIHNob3J0XG4gKiB0aW1lZCBvdXQgKGl0IGhhZCBubyBhbnN3ZXIgaW4gdGhlIHRpbWUgaXQgaGFkIOKAlCBsYXcgNCksIGFuZCB0aGUgc2VyaWVzIHN0b3BzIGBuby10aW1lLWxlZnRgLCBub3QgYGFib3J0ZWRgLiBTb1xuICogdGhlIHJlYXNvbiB0aGUgcnVuJ3Mgc2lnbmFsIGFib3J0cyB3aXRoIGF0IHRoZSBkZWFkbGluZSBpcyBCUkFOREVEIGhlcmUsIGFuZCB0aGUgYXR0ZW1wdCBydW5uZXIgdGVsbHMgdGhlIHR3b1xuICogYXBhcnQgYnkgdGhlIGJyYW5kIOKAlCBuZXZlciBieSB0aGUgbWVzc2FnZSwgbmV2ZXIgYnkgdGhlIGNsb2NrLlxuICpcbiAqIFRoZSBicmFuZCBpcyBhIG1vZHVsZS1wcml2YXRlIFdlYWtTZXQ6IGFuIG9yZGluYXJ5IGBFcnJvcmAgKHNhbWUgbWVzc2FnZSwgc2FtZSBuYW1lIGEgcnVuIHdpdGggYHRpbWVvdXRNc2AgYWx3YXlzXG4gKiByZWplY3RlZCB3aXRoKSwgcmVjb2duaXNhYmxlIG9ubHkgYnkgaWRlbnRpdHkuXG4gKi9cblxuaW1wb3J0IHsgYW55U2lnbmFsIH0gZnJvbSAnLi9hbnlTaWduYWwuanMnO1xuXG5jb25zdCBERUFETElORV9SRUFTT05TID0gbmV3IFdlYWtTZXQ8b2JqZWN0PigpO1xuXG4vKiogVGhlIHJlYXNvbiB0aGUgcnVuJ3Mgc2lnbmFsIGFib3J0cyB3aXRoIHdoZW4gaXRzIGRlYWRsaW5lIHBhc3NlcyDigJQgYW4gYEVycm9yYCwgYnJhbmRlZCBhcyB0aGUgZGVhZGxpbmUncy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWFkbGluZVJlYXNvbihtZXNzYWdlOiBzdHJpbmcpOiBFcnJvciB7XG4gIGNvbnN0IHJlYXNvbiA9IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgREVBRExJTkVfUkVBU09OUy5hZGQocmVhc29uKTtcbiAgcmV0dXJuIHJlYXNvbjtcbn1cblxuLyoqXG4gKiBCcmFuZCBgcmVhc29uYCBhcyBhIHRpbWUgbGltaXQg4oCUIHdoYXQgYW4gYXR0ZW1wdCdzIG93biBjYXAgYWJvcnRzIHdpdGggKFAyKS4gQW4gYXR0ZW1wdCdzIGNhcCBpcyB0aGUgZGVhZGxpbmUgb2ZcbiAqIGV2ZXJ5IGNhbGwgbWFkZSBpbnNpZGUgaXQgKGBhdHRlbXB0L2NhbGwudHNgKSwgc28gYSBjYWxsIGl0IGN1dHMgcmFuIG91dCBvZiB0aW1lOiBgJ3RpbWVvdXQnYCwgbmV2ZXIgYCdhYm9ydGVkJ2AuXG4gKiBUaGUgcnVuJ3Mgb3duIHNpZ25hbCBuZXZlciBhYm9ydHMgd2l0aCBpdCwgc28gYSBzdGFnZSBhdHRlbXB0IHJlYWRzIG5vdGhpbmcgbmV3LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya1RpbWVMaW1pdDxUIGV4dGVuZHMgb2JqZWN0PihyZWFzb246IFQpOiBUIHtcbiAgREVBRExJTkVfUkVBU09OUy5hZGQocmVhc29uKTtcbiAgcmV0dXJuIHJlYXNvbjtcbn1cblxuLyoqIFdoZXRoZXIgYHJlYXNvbmAgaXMgdGhlIHJ1bidzIGRlYWRsaW5lIG9yIGFuIGF0dGVtcHQncyBjYXAg4oCUIGEgdGltZSBsaW1pdCwgbm90IGEgY2FuY2VsbGF0aW9uLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVhZGxpbmVSZWFzb24ocmVhc29uOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIHJldHVybiB0eXBlb2YgcmVhc29uID09PSAnb2JqZWN0JyAmJiByZWFzb24gIT09IG51bGwgJiYgREVBRExJTkVfUkVBU09OUy5oYXMocmVhc29uKTtcbn1cblxuLyoqIFdoZXRoZXIgdGhlIHNpZ25hbCBhYm9ydGVkIGZvciBhIHJlYXNvbiBPVEhFUiB0aGFuIGEgdGltZSBsaW1pdCDigJQgYSBjYW5jZWxsYXRpb24uICovXG5leHBvcnQgZnVuY3Rpb24gaXNDYW5jZWxsZWQoc2lnbmFsOiBBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gc2lnbmFsPy5hYm9ydGVkID09PSB0cnVlICYmICFpc0RlYWRsaW5lUmVhc29uKHNpZ25hbC5yZWFzb24pO1xufVxuXG4vKiogQSBkZWFkbGluZSBhcyB0aGUgZW5naW5lIHJlYWRzIG9uZTogYSBmaW5pdGUgbnVtYmVyIChlcG9jaCBtcyksIGVsc2Ugbm9uZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkRGVhZGxpbmUodmFsdWU6IHVua25vd24pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpID8gdmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbi8qKiBUaGUgbG9uZ2VzdCBkZWxheSBhIGhvc3QgdGltZXIgaG9ub3VycyAoMl4zMSDiiJIgMSBtcywgfjI0LjggZGF5cyk7IGEgbG9uZ2VyIG9uZSBmaXJlcyBhdCBvbmNlLiAqL1xuY29uc3QgTUFYX1RJTUVSX01TID0gMl8xNDdfNDgzXzY0NztcblxuLyoqXG4gKiBgc2V0VGltZW91dGAgZm9yIGFueSBkZWxheTogYSBkZWxheSBwYXN0IHRoZSBob3N0J3MgbGltaXQgaXMgd2FpdGVkIGluIGNodW5rcywgc28gYSAzMC1kYXkgZGVhZGxpbmUgZG9lcyBub3QgZmlyZVxuICogaW4gYSBtaWxsaXNlY29uZC4gUmV0dXJucyB0aGUgb25lIGNhbGwgdGhhdCBjYW5jZWxzIGl0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0TG9uZ1RpbWVvdXQoZm46ICgpID0+IHZvaWQsIG1zOiBudW1iZXIpOiAoKSA9PiB2b2lkIHtcbiAgbGV0IHRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IHVuZGVmaW5lZDtcbiAgbGV0IGNhbmNlbGxlZCA9IGZhbHNlO1xuICBjb25zdCBhcm0gPSAobGVmdDogbnVtYmVyKSA9PiB7XG4gICAgdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmIChjYW5jZWxsZWQpIHJldHVybjtcbiAgICAgIGlmIChsZWZ0ID4gTUFYX1RJTUVSX01TKSBhcm0obGVmdCAtIE1BWF9USU1FUl9NUyk7XG4gICAgICBlbHNlIGZuKCk7XG4gICAgfSwgTWF0aC5taW4obGVmdCwgTUFYX1RJTUVSX01TKSk7XG4gIH07XG4gIGFybShNYXRoLm1heCgwLCBtcykpO1xuICByZXR1cm4gKCkgPT4ge1xuICAgIGNhbmNlbGxlZCA9IHRydWU7XG4gICAgaWYgKHRpbWVyICE9PSB1bmRlZmluZWQpIGNsZWFyVGltZW91dCh0aW1lcik7XG4gIH07XG59XG5cbi8qKiBXaGV0aGVyIGB2YWx1ZWAgaXMgYW4gQWJvcnRTaWduYWwgKHN0cnVjdHVyYWxseSDigJQgYSBzaWduYWwgZnJvbSBhbm90aGVyIHJlYWxtIGNvdW50cykuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBYm9ydFNpZ25hbCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEFib3J0U2lnbmFsIHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICB0eXBlb2YgKHZhbHVlIGFzIEFib3J0U2lnbmFsKS5hYm9ydGVkID09PSAnYm9vbGVhbicgJiZcbiAgICB0eXBlb2YgKHZhbHVlIGFzIEFib3J0U2lnbmFsKS5hZGRFdmVudExpc3RlbmVyID09PSAnZnVuY3Rpb24nICYmXG4gICAgdHlwZW9mICh2YWx1ZSBhcyBBYm9ydFNpZ25hbCkucmVtb3ZlRXZlbnRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJ1xuICApO1xufVxuXG4vKiogQSBzaWduYWwgdGhhdCBhYm9ydHMgYXQgYSBkZWFkbGluZSAob3Igd2l0aCBpdHMgaW5wdXQpLCBhbmQgdGhlIG9uZSBjYWxsIHRoYXQgcmVsZWFzZXMgYm90aC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXJtZWREZWFkbGluZSB7XG4gIHJlYWRvbmx5IHNpZ25hbDogQWJvcnRTaWduYWwgfCB1bmRlZmluZWQ7XG4gIGRpc3Bvc2UoKTogdm9pZDtcbn1cblxuLyoqXG4gKiBDb21wb3NlIGBzaWduYWxgIHdpdGggYSB0aW1lciB0aGF0IGFib3J0cyBhdCBgZGVhZGxpbmVgIChlcG9jaCBtcykgd2l0aCBhIGJyYW5kZWQge0BsaW5rIGRlYWRsaW5lUmVhc29ufSDigJQgc28gdGhlXG4gKiBhdHRlbXB0IHJ1bm5lcidzIHJlYWRpbmcgaG9sZHM6IHRoZSBzaWduYWwgaXQgaXMgaGFuZGVkIGFib3J0cyBhdCB0aGUgZGVhZGxpbmUsIGFzIHRoZSBydW4ncyBkb2VzIChgYXJtUnVuYCkuIEFcbiAqIGRlYWRsaW5lIGFscmVhZHkgcGFzdCBhYm9ydHMgYXQgb25jZTsgd2l0aG91dCBhIGRlYWRsaW5lIHRoZSBzaWduYWwgaXMgaGFuZGVkIGJhY2sgYXMgaXQgaXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcm1EZWFkbGluZShcbiAgc2lnbmFsOiBBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZCxcbiAgZGVhZGxpbmU6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgbWVzc2FnZTogc3RyaW5nLFxuICBub3c6ICgpID0+IG51bWJlciA9IERhdGUubm93LFxuKTogQXJtZWREZWFkbGluZSB7XG4gIGlmIChkZWFkbGluZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4geyBzaWduYWwsIGRpc3Bvc2U6ICgpID0+IHVuZGVmaW5lZCB9O1xuICBjb25zdCB0aW1lciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgY29uc3QgY29tcG9zZWQgPSBhbnlTaWduYWwoW3NpZ25hbCwgdGltZXIuc2lnbmFsXSk7XG4gIGNvbnN0IHJlYXNvbiA9IGRlYWRsaW5lUmVhc29uKG1lc3NhZ2UpO1xuICBjb25zdCBsZWZ0ID0gZGVhZGxpbmUgLSBub3coKTtcbiAgbGV0IGNhbmNlbDogKCkgPT4gdm9pZCA9ICgpID0+IHVuZGVmaW5lZDtcbiAgaWYgKGxlZnQgPD0gMCkgdGltZXIuYWJvcnQocmVhc29uKTtcbiAgZWxzZSBjYW5jZWwgPSBzZXRMb25nVGltZW91dCgoKSA9PiB0aW1lci5hYm9ydChyZWFzb24pLCBsZWZ0KTtcbiAgcmV0dXJuIHtcbiAgICBzaWduYWw6IGNvbXBvc2VkLnNpZ25hbCxcbiAgICBkaXNwb3NlOiAoKSA9PiB7XG4gICAgICBjYW5jZWwoKTtcbiAgICAgIGNvbXBvc2VkLmRpc3Bvc2UoKTtcbiAgICB9LFxuICB9O1xufVxuIl19
@@ -0,0 +1,52 @@
1
+ /**
2
+ * attempt/decision.ts — the ONE retry rule table and the runner's evidence builder (design §3.1, §3.8, law 9).
3
+ *
4
+ * `retryRules(policy)` is the retry-or-stop decision as ordinary `decide()` rules over `AttemptInputs`, first
5
+ * match wins, default `retry` ("retryable"):
6
+ *
7
+ * 1 outcome = ok → done succeeded
8
+ * 2 outcome = paused → stop paused
9
+ * 3 aborted = true → stop aborted (the run's signal — the attempt's outcome stays its own)
10
+ * 4 attempt ≥ of → stop exhausted
11
+ * 5 retryOn = false → stop declined (a function rule: it shows the verdict it saw)
12
+ * 6 timeLeftAfterWaitMs ≤ 0 → stop no-time-left
13
+ * default → retry retryable
14
+ *
15
+ * Each rule's `label` IS the reason it names, so `reason` is a projection of the evidence, never a second
16
+ * vocabulary. The ceiling is `attempt/policy.ts · attemptCeiling`, the one reading the engine and the runner
17
+ * share.
18
+ *
19
+ * `decideAttempt` evaluates that table WITHOUT a scope (the runner has none — `decide()` needs a registered
20
+ * one) and builds the evidence `decide()` would build: the filter rows come from `decide()`'s own evaluator
21
+ * (`filter/evaluator.ts · evaluateFilter`), the function rows and the first-match loop mirror
22
+ * `decide/decide.ts` field for field and key for key. A property test pins that both paths give equal evidence
23
+ * for equal inputs (test/lib/attempt/property).
24
+ *
25
+ * Inputs are READ, one key at a time, only when a rule reaches them — so the user's `retryOn` and `backoffMs`
26
+ * run exactly when a retry needs them, as they did before the record existed.
27
+ */
28
+ import type { DecideRule, DecisionEvidence } from '../decide/types.js';
29
+ import type { AttemptInputs, AttemptNext, AttemptReason, RetryPolicy } from './types.js';
30
+ /** The table's default: no rule stopped the series, so it retries. */
31
+ export declare const RETRY_DEFAULT: Readonly<{
32
+ readonly branch: "retry";
33
+ readonly label: "retryable";
34
+ }>;
35
+ /**
36
+ * The retry rule table for `policy` — six `decide()` rules, then {@link RETRY_DEFAULT}. The ceiling is the
37
+ * whole number of attempts the policy allows, never fewer than one (`attemptCeiling`): a ceiling of `NaN` or
38
+ * `Infinity` cannot make rule 4 unreachable.
39
+ */
40
+ export declare function retryRules(policy: Pick<RetryPolicy, 'attempts'>): DecideRule<AttemptInputs>[];
41
+ /** A decision: the evidence, and its compact projection. */
42
+ export interface AttemptDecision {
43
+ readonly evidence: DecisionEvidence;
44
+ readonly next: AttemptNext;
45
+ readonly reason: AttemptReason;
46
+ }
47
+ /**
48
+ * Evaluate `rules` (a `retryRules` table) over `read` — first match wins — and build the evidence `decide()`
49
+ * would record with the default {@link RETRY_DEFAULT}. `read(key)` returns one input; it is called only for the
50
+ * keys the evaluated rules touch, in rule order.
51
+ */
52
+ export declare function decideAttempt(rules: readonly DecideRule<AttemptInputs>[], read: (key: string) => unknown): AttemptDecision;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * attempt/decision.ts — the ONE retry rule table and the runner's evidence builder (design §3.1, §3.8, law 9).
3
+ *
4
+ * `retryRules(policy)` is the retry-or-stop decision as ordinary `decide()` rules over `AttemptInputs`, first
5
+ * match wins, default `retry` ("retryable"):
6
+ *
7
+ * 1 outcome = ok → done succeeded
8
+ * 2 outcome = paused → stop paused
9
+ * 3 aborted = true → stop aborted (the run's signal — the attempt's outcome stays its own)
10
+ * 4 attempt ≥ of → stop exhausted
11
+ * 5 retryOn = false → stop declined (a function rule: it shows the verdict it saw)
12
+ * 6 timeLeftAfterWaitMs ≤ 0 → stop no-time-left
13
+ * default → retry retryable
14
+ *
15
+ * Each rule's `label` IS the reason it names, so `reason` is a projection of the evidence, never a second
16
+ * vocabulary. The ceiling is `attempt/policy.ts · attemptCeiling`, the one reading the engine and the runner
17
+ * share.
18
+ *
19
+ * `decideAttempt` evaluates that table WITHOUT a scope (the runner has none — `decide()` needs a registered
20
+ * one) and builds the evidence `decide()` would build: the filter rows come from `decide()`'s own evaluator
21
+ * (`filter/evaluator.ts · evaluateFilter`), the function rows and the first-match loop mirror
22
+ * `decide/decide.ts` field for field and key for key. A property test pins that both paths give equal evidence
23
+ * for equal inputs (test/lib/attempt/property).
24
+ *
25
+ * Inputs are READ, one key at a time, only when a rule reaches them — so the user's `retryOn` and `backoffMs`
26
+ * run exactly when a retry needs them, as they did before the record existed.
27
+ */
28
+ import { summarizeValue } from '../capture/summarize.js';
29
+ import { evaluateFilter } from '../filter/evaluator.js';
30
+ import { attemptCeiling } from './policy.js';
31
+ /** The table's default: no rule stopped the series, so it retries. */
32
+ export const RETRY_DEFAULT = Object.freeze({ branch: 'retry', label: 'retryable' });
33
+ /** `decide()`'s summary length for an evidence value (filter/evaluator.ts, decide/evidence.ts). */
34
+ const MAX_VALUE_LEN = 80;
35
+ /**
36
+ * The retry rule table for `policy` — six `decide()` rules, then {@link RETRY_DEFAULT}. The ceiling is the
37
+ * whole number of attempts the policy allows, never fewer than one (`attemptCeiling`): a ceiling of `NaN` or
38
+ * `Infinity` cannot make rule 4 unreachable.
39
+ */
40
+ export function retryRules(policy) {
41
+ return [
42
+ { when: { outcome: { eq: 'ok' } }, then: 'done', label: 'succeeded' },
43
+ { when: { outcome: { eq: 'paused' } }, then: 'stop', label: 'paused' },
44
+ { when: { aborted: { eq: true } }, then: 'stop', label: 'aborted' },
45
+ { when: { attempt: { gte: attemptCeiling(policy.attempts) } }, then: 'stop', label: 'exhausted' },
46
+ { when: (inputs) => inputs.retryOn === false, then: 'stop', label: 'declined' },
47
+ { when: { timeLeftAfterWaitMs: { lte: 0 } }, then: 'stop', label: 'no-time-left' },
48
+ ];
49
+ }
50
+ /**
51
+ * Evaluate `rules` (a `retryRules` table) over `read` — first match wins — and build the evidence `decide()`
52
+ * would record with the default {@link RETRY_DEFAULT}. `read(key)` returns one input; it is called only for the
53
+ * keys the evaluated rules touch, in rule order.
54
+ */
55
+ export function decideAttempt(rules, read) {
56
+ const evaluated = [];
57
+ for (const [index, rule] of rules.entries()) {
58
+ const evidence = evaluateRule(rule, index, read);
59
+ evaluated.push(evidence);
60
+ if (evidence.matched)
61
+ return decided(evaluated, rule.then, rule.label);
62
+ }
63
+ return decided(evaluated, RETRY_DEFAULT.branch, RETRY_DEFAULT.label);
64
+ }
65
+ function decided(rules, chosen, label) {
66
+ // decide()'s key order: rules, chosen, default, defaultLabel.
67
+ const evidence = {
68
+ rules,
69
+ chosen,
70
+ default: RETRY_DEFAULT.branch,
71
+ defaultLabel: RETRY_DEFAULT.label,
72
+ };
73
+ return { evidence, next: chosen, reason: label };
74
+ }
75
+ /** One rule, as `decide/decide.ts · evaluateRule` evaluates it — minus the scope. */
76
+ function evaluateRule(rule, index, read) {
77
+ if (typeof rule.when === 'function') {
78
+ const inputs = [];
79
+ let matched;
80
+ let matchError;
81
+ try {
82
+ matched = rule.when(readingView(read, inputs));
83
+ }
84
+ catch (error) {
85
+ matched = false;
86
+ matchError = error instanceof Error ? error.message : String(error);
87
+ }
88
+ const evidence = {
89
+ type: 'function',
90
+ ruleIndex: index,
91
+ branch: rule.then,
92
+ matched,
93
+ label: rule.label,
94
+ inputs,
95
+ ...(matchError !== undefined && { matchError }),
96
+ };
97
+ return evidence;
98
+ }
99
+ let matched = false;
100
+ let conditions = [];
101
+ let matchError;
102
+ try {
103
+ ({ matched, conditions } = evaluateFilter(read, () => false, rule.when));
104
+ }
105
+ catch (error) {
106
+ matchError = error instanceof Error ? error.message : String(error);
107
+ }
108
+ const evidence = {
109
+ type: 'filter',
110
+ ruleIndex: index,
111
+ branch: rule.then,
112
+ matched,
113
+ label: rule.label,
114
+ conditions,
115
+ ...(matchError !== undefined && { matchError }),
116
+ };
117
+ return evidence;
118
+ }
119
+ /**
120
+ * The inputs as a function rule sees them: each string-keyed read is recorded the way `decide()`'s evidence
121
+ * collector records a scope read (key, summary, not redacted — every input is a number, a name or a flag).
122
+ */
123
+ function readingView(read, inputs) {
124
+ return new Proxy({}, {
125
+ get(_target, key) {
126
+ if (typeof key !== 'string')
127
+ return undefined;
128
+ const value = read(key);
129
+ inputs.push({ key, valueSummary: summarizeValue(value, MAX_VALUE_LEN), redacted: false });
130
+ return value;
131
+ },
132
+ });
133
+ }
134
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVjaXNpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2F0dGVtcHQvZGVjaXNpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBRUgsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBVXpELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRzdDLHNFQUFzRTtBQUN0RSxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBVyxDQUFDLENBQUM7QUFFN0YsbUdBQW1HO0FBQ25HLE1BQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQztBQUV6Qjs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBQyxNQUFxQztJQUM5RCxPQUFPO1FBQ0wsRUFBRSxJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUU7UUFDckUsRUFBRSxJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUU7UUFDdEUsRUFBRSxJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUU7UUFDbkUsRUFBRSxJQUFJLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxHQUFHLEVBQUUsY0FBYyxDQUFD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QUFDO1FBQ2YsQ0FBQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGF0dGVtcHQvZGVjaXNpb24udHMg4oCUIHRoZSBPTkUgcmV0cnkgcnVsZSB0YWJsZSBhbmQgdGhlIHJ1bm5lcidzIGV2aWRlbmNlIGJ1aWxkZXIgKGRlc2lnbiDCpzMuMSwgwqczLjgsIGxhdyA5KS5cbiAqXG4gKiBgcmV0cnlSdWxlcyhwb2xpY3kpYCBpcyB0aGUgcmV0cnktb3Itc3RvcCBkZWNpc2lvbiBhcyBvcmRpbmFyeSBgZGVjaWRlKClgIHJ1bGVzIG92ZXIgYEF0dGVtcHRJbnB1dHNgLCBmaXJzdFxuICogbWF0Y2ggd2lucywgZGVmYXVsdCBgcmV0cnlgIChcInJldHJ5YWJsZVwiKTpcbiAqXG4gKiAgIDEgIG91dGNvbWUgPSBvayAgICAgICAgICAgICAgICAgICAg4oaSIGRvbmUgIHN1Y2NlZWRlZFxuICogICAyICBvdXRjb21lID0gcGF1c2VkICAgICAgICAgICAgICAgIOKGkiBzdG9wICBwYXVzZWRcbiAqICAgMyAgYWJvcnRlZCA9IHRydWUgICAgICAgICAgICAgICAgICDihpIgc3RvcCAgYWJvcnRlZCAgICAgICAgKHRoZSBydW4ncyBzaWduYWwg4oCUIHRoZSBhdHRlbXB0J3Mgb3V0Y29tZSBzdGF5cyBpdHMgb3duKVxuICogICA0ICBhdHRlbXB0IOKJpSBvZiAgICAgICAgICAgICAgICAgICAg4oaSIHN0b3AgIGV4aGF1c3RlZFxuICogICA1ICByZXRyeU9uID0gZmFsc2UgICAgICAgICAgICAgICAgIOKGkiBzdG9wICBkZWNsaW5lZCAgICAgICAoYSBmdW5jdGlvbiBydWxlOiBpdCBzaG93cyB0aGUgdmVyZGljdCBpdCBzYXcpXG4gKiAgIDYgIHRpbWVMZWZ0QWZ0ZXJXYWl0TXMg4omkIDAgICAgICAgICDihpIgc3RvcCAgbm8tdGltZS1sZWZ0XG4gKiAgICAgIGRlZmF1bHQgICAgICAgICAgICAgICAgICAgICAgICAg4oaSIHJldHJ5IHJldHJ5YWJsZVxuICpcbiAqIEVhY2ggcnVsZSdzIGBsYWJlbGAgSVMgdGhlIHJlYXNvbiBpdCBuYW1lcywgc28gYHJlYXNvbmAgaXMgYSBwcm9qZWN0aW9uIG9mIHRoZSBldmlkZW5jZSwgbmV2ZXIgYSBzZWNvbmRcbiAqIHZvY2FidWxhcnkuIFRoZSBjZWlsaW5nIGlzIGBhdHRlbXB0L3BvbGljeS50cyDCtyBhdHRlbXB0Q2VpbGluZ2AsIHRoZSBvbmUgcmVhZGluZyB0aGUgZW5naW5lIGFuZCB0aGUgcnVubmVyXG4gKiBzaGFyZS5cbiAqXG4gKiBgZGVjaWRlQXR0ZW1wdGAgZXZhbHVhdGVzIHRoYXQgdGFibGUgV0lUSE9VVCBhIHNjb3BlICh0aGUgcnVubmVyIGhhcyBub25lIOKAlCBgZGVjaWRlKClgIG5lZWRzIGEgcmVnaXN0ZXJlZFxuICogb25lKSBhbmQgYnVpbGRzIHRoZSBldmlkZW5jZSBgZGVjaWRlKClgIHdvdWxkIGJ1aWxkOiB0aGUgZmlsdGVyIHJvd3MgY29tZSBmcm9tIGBkZWNpZGUoKWAncyBvd24gZXZhbHVhdG9yXG4gKiAoYGZpbHRlci9ldmFsdWF0b3IudHMgwrcgZXZhbHVhdGVGaWx0ZXJgKSwgdGhlIGZ1bmN0aW9uIHJvd3MgYW5kIHRoZSBmaXJzdC1tYXRjaCBsb29wIG1pcnJvclxuICogYGRlY2lkZS9kZWNpZGUudHNgIGZpZWxkIGZvciBmaWVsZCBhbmQga2V5IGZvciBrZXkuIEEgcHJvcGVydHkgdGVzdCBwaW5zIHRoYXQgYm90aCBwYXRocyBnaXZlIGVxdWFsIGV2aWRlbmNlXG4gKiBmb3IgZXF1YWwgaW5wdXRzICh0ZXN0L2xpYi9hdHRlbXB0L3Byb3BlcnR5KS5cbiAqXG4gKiBJbnB1dHMgYXJlIFJFQUQsIG9uZSBrZXkgYXQgYSB0aW1lLCBvbmx5IHdoZW4gYSBydWxlIHJlYWNoZXMgdGhlbSDigJQgc28gdGhlIHVzZXIncyBgcmV0cnlPbmAgYW5kIGBiYWNrb2ZmTXNgXG4gKiBydW4gZXhhY3RseSB3aGVuIGEgcmV0cnkgbmVlZHMgdGhlbSwgYXMgdGhleSBkaWQgYmVmb3JlIHRoZSByZWNvcmQgZXhpc3RlZC5cbiAqL1xuXG5pbXBvcnQgeyBzdW1tYXJpemVWYWx1ZSB9IGZyb20gJy4uL2NhcHR1cmUvc3VtbWFyaXplLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgRGVjaWRlUnVsZSxcbiAgRGVjaXNpb25FdmlkZW5jZSxcbiAgRmlsdGVyUnVsZUV2aWRlbmNlLFxuICBGdW5jdGlvblJ1bGVFdmlkZW5jZSxcbiAgUmVhZElucHV0LFxuICBSdWxlRXZpZGVuY2UsXG4gIFdoZXJlRmlsdGVyLFxufSBmcm9tICcuLi9kZWNpZGUvdHlwZXMuanMnO1xuaW1wb3J0IHsgZXZhbHVhdGVGaWx0ZXIgfSBmcm9tICcuLi9maWx0ZXIvZXZhbHVhdG9yLmpzJztcbmltcG9ydCB7IGF0dGVtcHRDZWlsaW5nIH0gZnJvbSAnLi9wb2xpY3kuanMnO1xuaW1wb3J0IHR5cGUgeyBBdHRlbXB0SW5wdXRzLCBBdHRlbXB0TmV4dCwgQXR0ZW1wdFJlYXNvbiwgUmV0cnlQb2xpY3kgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqIFRoZSB0YWJsZSdzIGRlZmF1bHQ6IG5vIHJ1bGUgc3RvcHBlZCB0aGUgc2VyaWVzLCBzbyBpdCByZXRyaWVzLiAqL1xuZXhwb3J0IGNvbnN0IFJFVFJZX0RFRkFVTFQgPSBPYmplY3QuZnJlZXplKHsgYnJhbmNoOiAncmV0cnknLCBsYWJlbDogJ3JldHJ5YWJsZScgfSBhcyBjb25zdCk7XG5cbi8qKiBgZGVjaWRlKClgJ3Mgc3VtbWFyeSBsZW5ndGggZm9yIGFuIGV2aWRlbmNlIHZhbHVlIChmaWx0ZXIvZXZhbHVhdG9yLnRzLCBkZWNpZGUvZXZpZGVuY2UudHMpLiAqL1xuY29uc3QgTUFYX1ZBTFVFX0xFTiA9IDgwO1xuXG4vKipcbiAqIFRoZSByZXRyeSBydWxlIHRhYmxlIGZvciBgcG9saWN5YCDigJQgc2l4IGBkZWNpZGUoKWAgcnVsZXMsIHRoZW4ge0BsaW5rIFJFVFJZX0RFRkFVTFR9LiBUaGUgY2VpbGluZyBpcyB0aGVcbiAqIHdob2xlIG51bWJlciBvZiBhdHRlbXB0cyB0aGUgcG9saWN5IGFsbG93cywgbmV2ZXIgZmV3ZXIgdGhhbiBvbmUgKGBhdHRlbXB0Q2VpbGluZ2ApOiBhIGNlaWxpbmcgb2YgYE5hTmAgb3JcbiAqIGBJbmZpbml0eWAgY2Fubm90IG1ha2UgcnVsZSA0IHVucmVhY2hhYmxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmV0cnlSdWxlcyhwb2xpY3k6IFBpY2s8UmV0cnlQb2xpY3ksICdhdHRlbXB0cyc+KTogRGVjaWRlUnVsZTxBdHRlbXB0SW5wdXRzPltdIHtcbiAgcmV0dXJuIFtcbiAgICB7IHdoZW46IHsgb3V0Y29tZTogeyBlcTogJ29rJyB9IH0sIHRoZW46ICdkb25lJywgbGFiZWw6ICdzdWNjZWVkZWQnIH0sXG4gICAgeyB3aGVuOiB7IG91dGNvbWU6IHsgZXE6ICdwYXVzZWQnIH0gfSwgdGhlbjogJ3N0b3AnLCBsYWJlbDogJ3BhdXNlZCcgfSxcbiAgICB7IHdoZW46IHsgYWJvcnRlZDogeyBlcTogdHJ1ZSB9IH0sIHRoZW46ICdzdG9wJywgbGFiZWw6ICdhYm9ydGVkJyB9LFxuICAgIHsgd2hlbjogeyBhdHRlbXB0OiB7IGd0ZTogYXR0ZW1wdENlaWxpbmcocG9saWN5LmF0dGVtcHRzKSB9IH0sIHRoZW46ICdzdG9wJywgbGFiZWw6ICdleGhhdXN0ZWQnIH0sXG4gICAgeyB3aGVuOiAoaW5wdXRzKSA9PiBpbnB1dHMucmV0cnlPbiA9PT0gZmFsc2UsIHRoZW46ICdzdG9wJywgbGFiZWw6ICdkZWNsaW5lZCcgfSxcbiAgICB7IHdoZW46IHsgdGltZUxlZnRBZnRlcldhaXRNczogeyBsdGU6IDAgfSB9LCB0aGVuOiAnc3RvcCcsIGxhYmVsOiAnbm8tdGltZS1sZWZ0JyB9LFxuICBdO1xufVxuXG4vKiogQSBkZWNpc2lvbjogdGhlIGV2aWRlbmNlLCBhbmQgaXRzIGNvbXBhY3QgcHJvamVjdGlvbi4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXR0ZW1wdERlY2lzaW9uIHtcbiAgcmVhZG9ubHkgZXZpZGVuY2U6IERlY2lzaW9uRXZpZGVuY2U7XG4gIHJlYWRvbmx5IG5leHQ6IEF0dGVtcHROZXh0O1xuICByZWFkb25seSByZWFzb246IEF0dGVtcHRSZWFzb247XG59XG5cbi8qKlxuICogRXZhbHVhdGUgYHJ1bGVzYCAoYSBgcmV0cnlSdWxlc2AgdGFibGUpIG92ZXIgYHJlYWRgIOKAlCBmaXJzdCBtYXRjaCB3aW5zIOKAlCBhbmQgYnVpbGQgdGhlIGV2aWRlbmNlIGBkZWNpZGUoKWBcbiAqIHdvdWxkIHJlY29yZCB3aXRoIHRoZSBkZWZhdWx0IHtAbGluayBSRVRSWV9ERUZBVUxUfS4gYHJlYWQoa2V5KWAgcmV0dXJucyBvbmUgaW5wdXQ7IGl0IGlzIGNhbGxlZCBvbmx5IGZvciB0aGVcbiAqIGtleXMgdGhlIGV2YWx1YXRlZCBydWxlcyB0b3VjaCwgaW4gcnVsZSBvcmRlci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY2lkZUF0dGVtcHQoXG4gIHJ1bGVzOiByZWFkb25seSBEZWNpZGVSdWxlPEF0dGVtcHRJbnB1dHM+W10sXG4gIHJlYWQ6IChrZXk6IHN0cmluZykgPT4gdW5rbm93bixcbik6IEF0dGVtcHREZWNpc2lvbiB7XG4gIGNvbnN0IGV2YWx1YXRlZDogUnVsZUV2aWRlbmNlW10gPSBbXTtcbiAgZm9yIChjb25zdCBbaW5kZXgsIHJ1bGVdIG9mIHJ1bGVzLmVudHJpZXMoKSkge1xuICAgIGNvbnN0IGV2aWRlbmNlID0gZXZhbHVhdGVSdWxlKHJ1bGUsIGluZGV4LCByZWFkKTtcbiAgICBldmFsdWF0ZWQucHVzaChldmlkZW5jZSk7XG4gICAgaWYgKGV2aWRlbmNlLm1hdGNoZWQpIHJldHVybiBkZWNpZGVkKGV2YWx1YXRlZCwgcnVsZS50aGVuLCBydWxlLmxhYmVsKTtcbiAgfVxuICByZXR1cm4gZGVjaWRlZChldmFsdWF0ZWQsIFJFVFJZX0RFRkFVTFQuYnJhbmNoLCBSRVRSWV9ERUZBVUxULmxhYmVsKTtcbn1cblxuZnVuY3Rpb24gZGVjaWRlZChydWxlczogUnVsZUV2aWRlbmNlW10sIGNob3Nlbjogc3RyaW5nLCBsYWJlbDogc3RyaW5nIHwgdW5kZWZpbmVkKTogQXR0ZW1wdERlY2lzaW9uIHtcbiAgLy8gZGVjaWRlKCkncyBrZXkgb3JkZXI6IHJ1bGVzLCBjaG9zZW4sIGRlZmF1bHQsIGRlZmF1bHRMYWJlbC5cbiAgY29uc3QgZXZpZGVuY2U6IERlY2lzaW9uRXZpZGVuY2UgPSB7XG4gICAgcnVsZXMsXG4gICAgY2hvc2VuLFxuICAgIGRlZmF1bHQ6IFJFVFJZX0RFRkFVTFQuYnJhbmNoLFxuICAgIGRlZmF1bHRMYWJlbDogUkVUUllfREVGQVVMVC5sYWJlbCxcbiAgfTtcbiAgcmV0dXJuIHsgZXZpZGVuY2UsIG5leHQ6IGNob3NlbiBhcyBBdHRlbXB0TmV4dCwgcmVhc29uOiBsYWJlbCBhcyBBdHRlbXB0UmVhc29uIH07XG59XG5cbi8qKiBPbmUgcnVsZSwgYXMgYGRlY2lkZS9kZWNpZGUudHMgwrcgZXZhbHVhdGVSdWxlYCBldmFsdWF0ZXMgaXQg4oCUIG1pbnVzIHRoZSBzY29wZS4gKi9cbmZ1bmN0aW9uIGV2YWx1YXRlUnVsZShydWxlOiBEZWNpZGVSdWxlPEF0dGVtcHRJbnB1dHM+LCBpbmRleDogbnVtYmVyLCByZWFkOiAoa2V5OiBzdHJpbmcpID0+IHVua25vd24pOiBSdWxlRXZpZGVuY2Uge1xuICBpZiAodHlwZW9mIHJ1bGUud2hlbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IGlucHV0czogUmVhZElucHV0W10gPSBbXTtcbiAgICBsZXQgbWF0Y2hlZDogYm9vbGVhbjtcbiAgICBsZXQgbWF0Y2hFcnJvcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIHRyeSB7XG4gICAgICBtYXRjaGVkID0gcnVsZS53aGVuKHJlYWRpbmdWaWV3KHJlYWQsIGlucHV0cykpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBtYXRjaGVkID0gZmFsc2U7XG4gICAgICBtYXRjaEVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgIH1cbiAgICBjb25zdCBldmlkZW5jZTogRnVuY3Rpb25SdWxlRXZpZGVuY2UgPSB7XG4gICAgICB0eXBlOiAnZnVuY3Rpb24nLFxuICAgICAgcnVsZUluZGV4OiBpbmRleCxcbiAgICAgIGJyYW5jaDogcnVsZS50aGVuLFxuICAgICAgbWF0Y2hlZCxcbiAgICAgIGxhYmVsOiBydWxlLmxhYmVsLFxuICAgICAgaW5wdXRzLFxuICAgICAgLi4uKG1hdGNoRXJyb3IgIT09IHVuZGVmaW5lZCAmJiB7IG1hdGNoRXJyb3IgfSksXG4gICAgfTtcbiAgICByZXR1cm4gZXZpZGVuY2U7XG4gIH1cbiAgbGV0IG1hdGNoZWQgPSBmYWxzZTtcbiAgbGV0IGNvbmRpdGlvbnM6IEZpbHRlclJ1bGVFdmlkZW5jZVsnY29uZGl0aW9ucyddID0gW107XG4gIGxldCBtYXRjaEVycm9yOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHRyeSB7XG4gICAgKHsgbWF0Y2hlZCwgY29uZGl0aW9ucyB9ID0gZXZhbHVhdGVGaWx0ZXIocmVhZCwgKCkgPT4gZmFsc2UsIHJ1bGUud2hlbiBhcyBXaGVyZUZpbHRlcjxBdHRlbXB0SW5wdXRzPikpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIG1hdGNoRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gIH1cbiAgY29uc3QgZXZpZGVuY2U6IEZpbHRlclJ1bGVFdmlkZW5jZSA9IHtcbiAgICB0eXBlOiAnZmlsdGVyJyxcbiAgICBydWxlSW5kZXg6IGluZGV4LFxuICAgIGJyYW5jaDogcnVsZS50aGVuLFxuICAgIG1hdGNoZWQsXG4gICAgbGFiZWw6IHJ1bGUubGFiZWwsXG4gICAgY29uZGl0aW9ucyxcbiAgICAuLi4obWF0Y2hFcnJvciAhPT0gdW5kZWZpbmVkICYmIHsgbWF0Y2hFcnJvciB9KSxcbiAgfTtcbiAgcmV0dXJuIGV2aWRlbmNlO1xufVxuXG4vKipcbiAqIFRoZSBpbnB1dHMgYXMgYSBmdW5jdGlvbiBydWxlIHNlZXMgdGhlbTogZWFjaCBzdHJpbmcta2V5ZWQgcmVhZCBpcyByZWNvcmRlZCB0aGUgd2F5IGBkZWNpZGUoKWAncyBldmlkZW5jZVxuICogY29sbGVjdG9yIHJlY29yZHMgYSBzY29wZSByZWFkIChrZXksIHN1bW1hcnksIG5vdCByZWRhY3RlZCDigJQgZXZlcnkgaW5wdXQgaXMgYSBudW1iZXIsIGEgbmFtZSBvciBhIGZsYWcpLlxuICovXG5mdW5jdGlvbiByZWFkaW5nVmlldyhyZWFkOiAoa2V5OiBzdHJpbmcpID0+IHVua25vd24sIGlucHV0czogUmVhZElucHV0W10pOiBBdHRlbXB0SW5wdXRzIHtcbiAgcmV0dXJuIG5ldyBQcm94eSh7fSBhcyBBdHRlbXB0SW5wdXRzLCB7XG4gICAgZ2V0KF90YXJnZXQsIGtleSkge1xuICAgICAgaWYgKHR5cGVvZiBrZXkgIT09ICdzdHJpbmcnKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgY29uc3QgdmFsdWUgPSByZWFkKGtleSk7XG4gICAgICBpbnB1dHMucHVzaCh7IGtleSwgdmFsdWVTdW1tYXJ5OiBzdW1tYXJpemVWYWx1ZSh2YWx1ZSwgTUFYX1ZBTFVFX0xFTiksIHJlZGFjdGVkOiBmYWxzZSB9KTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9LFxuICB9KTtcbn1cbiJdfQ==
@@ -0,0 +1,76 @@
1
+ /**
2
+ * attempt/effect.ts — side-effect safety (design §3.3, packet P3): the ONE reading of what an attempt did to an
3
+ * outside system, and the ONE rule for a touching target.
4
+ *
5
+ * - `touchesProblem` — the build law, asked at every door a touching declaration enters: the builder
6
+ * (`FlowChartBuilder · applyTouches` / `applyRetryPolicy`), the traverser for a StageNode a stage returns at run
7
+ * time (`FlowchartTraverser · admitDynamicNodes`), and the stage itself (`FlowchartTraverser · executeStage`, for
8
+ * a chart edited after `build()`). A touching target that may retry without an idempotency key is refused: a
9
+ * retry of a non-idempotent effect without one can apply it twice.
10
+ * - `callTouches` — the same law for `scope.$call(target, fn, policy, { touches, idempotencyKey })`.
11
+ * - `admitIdempotencyKey` — the key's format: 1–255 printable ASCII characters, no space. It travels in a request
12
+ * header (`Idempotency-Key`), so a control character could forge one; the refusal names the field, never the
13
+ * value.
14
+ * - `effectOf` — `ok → 'applied'`; a failure whose error declares `effect: 'none'` → `'none'`; anything else →
15
+ * `'unknown'`. A timeout is the absence of an answer (law 4), so it is never `'none'`.
16
+ * - `unknownEffectError` — what a series that ends without an answer after ANY attempt of unknown effect fails
17
+ * with, in place of the attempt's own error (its `cause`).
18
+ * - `interruptProblem` — a keyless touching stage may not be re-run by an `interrupt()` resume.
19
+ */
20
+ import { UnknownEffectError } from './errors.js';
21
+ import type { AttemptEffect, AttemptOutcome, AttemptRecord, RetryPolicy, StageTouches } from './types.js';
22
+ export { MAX_IDEMPOTENCY_KEY_LENGTH } from '../ids/idempotencyKey.js';
23
+ /**
24
+ * What a touching runner series is told (`AttemptRunOptions.effect`): the system, the REAL key the attempts are made
25
+ * under, and the key as records carry it (the run's served form; the real one when no rule applies).
26
+ */
27
+ export interface EffectTarget {
28
+ readonly system: string;
29
+ readonly idempotencyKey?: string;
30
+ readonly recordedKey?: string;
31
+ }
32
+ /**
33
+ * Why a touching declaration is refused, or `undefined` when it is admitted: `touches` must be `{ system,
34
+ * idempotencyKey? }` with `system` a name and the key rule a function; and a target that may retry (`retry`'s
35
+ * ceiling above 1) must declare the key rule.
36
+ */
37
+ export declare function touchesProblem(touches: unknown, retry: Pick<RetryPolicy, 'attempts'> | undefined): string | undefined;
38
+ /** `value` as an idempotency key (`ids/idempotencyKey.ts`, the one rule), or a `TypeError` that names `where`. */
39
+ export declare function admitIdempotencyKey(where: string, value: unknown): string;
40
+ /**
41
+ * A `$call`'s side-effect declaration, admitted: `undefined` when it touches nothing; otherwise the system and the
42
+ * key, refused with a `TypeError` naming `where` when malformed, when a key comes without a system, or when the
43
+ * call may retry with no key — before anything is sent.
44
+ */
45
+ export declare function callTouches(where: string, options: unknown, policy: Pick<RetryPolicy, 'attempts'>): {
46
+ readonly system: string;
47
+ readonly idempotencyKey?: string;
48
+ } | undefined;
49
+ /** What an attempt that ended `outcome` (with `error`, when it failed) did to the outside system. */
50
+ export declare function effectOf(outcome: AttemptOutcome, error: unknown): AttemptEffect;
51
+ /**
52
+ * What a touching series fails with when any of its attempts left the effect unknown — never the attempt's own error,
53
+ * which a caller would read as a failure and retry. The key is the RECORDED one: under a redaction rule that names
54
+ * it, the error carries the placeholder, as every record does.
55
+ */
56
+ export declare function unknownEffectError(target: EffectTarget, record: AttemptRecord, cause: unknown): UnknownEffectError;
57
+ /** The key as records carry it: the served form when the caller gave one, else the key itself. */
58
+ export declare function recordedKeyOf(target: EffectTarget): string | undefined;
59
+ /** The runner's refusal of a touching series that may retry with no key — the law, at the last door. */
60
+ export declare function refuseKeylessRetry(target: EffectTarget, attempts: number): void;
61
+ /**
62
+ * Why a touching stage may not be RE-RUN by an `interrupt()` resume, or `undefined` when it may (P3). A resume
63
+ * re-runs the stage's function from its top — a second attempt of its effect — so the law that refuses a keyless
64
+ * retry refuses a keyless re-run too. Asked when the stage interrupts (`StageRunner`) and when a checkpoint is
65
+ * resumed (`runner/resume.ts · planResume`, for a checkpoint made by another version of the chart).
66
+ */
67
+ export declare function interruptProblem(touches: StageTouches | undefined): string | undefined;
68
+ /**
69
+ * The stand-in's declaration on a resume (P3): the paused stage's system, answering the key its checkpoint carried —
70
+ * the OPERATIONAL value, real (checkpoints are exempt from redaction by law). It is marked, so the run serves it
71
+ * like a key of unknown sources: under any state rule the records carry the placeholder (`isCarriedTouches`) — the
72
+ * resumed leg no longer holds the input the key was made of, so it cannot tell whether the key was masked.
73
+ */
74
+ export declare function carriedTouches(system: string, key: string): StageTouches;
75
+ /** The declaration answers a key a checkpoint carried ({@link carriedTouches}). */
76
+ export declare function isCarriedTouches(touches: unknown): boolean;
@@ -0,0 +1,160 @@
1
+ /**
2
+ * attempt/effect.ts — side-effect safety (design §3.3, packet P3): the ONE reading of what an attempt did to an
3
+ * outside system, and the ONE rule for a touching target.
4
+ *
5
+ * - `touchesProblem` — the build law, asked at every door a touching declaration enters: the builder
6
+ * (`FlowChartBuilder · applyTouches` / `applyRetryPolicy`), the traverser for a StageNode a stage returns at run
7
+ * time (`FlowchartTraverser · admitDynamicNodes`), and the stage itself (`FlowchartTraverser · executeStage`, for
8
+ * a chart edited after `build()`). A touching target that may retry without an idempotency key is refused: a
9
+ * retry of a non-idempotent effect without one can apply it twice.
10
+ * - `callTouches` — the same law for `scope.$call(target, fn, policy, { touches, idempotencyKey })`.
11
+ * - `admitIdempotencyKey` — the key's format: 1–255 printable ASCII characters, no space. It travels in a request
12
+ * header (`Idempotency-Key`), so a control character could forge one; the refusal names the field, never the
13
+ * value.
14
+ * - `effectOf` — `ok → 'applied'`; a failure whose error declares `effect: 'none'` → `'none'`; anything else →
15
+ * `'unknown'`. A timeout is the absence of an answer (law 4), so it is never `'none'`.
16
+ * - `unknownEffectError` — what a series that ends without an answer after ANY attempt of unknown effect fails
17
+ * with, in place of the attempt's own error (its `cause`).
18
+ * - `interruptProblem` — a keyless touching stage may not be re-run by an `interrupt()` resume.
19
+ */
20
+ import { idempotencyKeyProblem } from '../ids/idempotencyKey.js';
21
+ import { UnknownEffectError } from './errors.js';
22
+ import { attemptNameProblem } from './name.js';
23
+ import { attemptCeiling } from './policy.js';
24
+ export { MAX_IDEMPOTENCY_KEY_LENGTH } from '../ids/idempotencyKey.js';
25
+ /** Why `retry` with `touches` breaks the law — the shared words of every door. */
26
+ function retriedWithoutKey(system, attempts) {
27
+ return (`touches "${system}" and may retry (attempts: ${attempts}) but declares no idempotencyKey — a retry of an ` +
28
+ 'outside effect without a key can apply it twice. Declare the key rule ' +
29
+ `(.touches('${system}', { idempotencyKey: ({ args }) => \`order-\${args.orderId}\` })), or retry once.`);
30
+ }
31
+ /**
32
+ * Why a touching declaration is refused, or `undefined` when it is admitted: `touches` must be `{ system,
33
+ * idempotencyKey? }` with `system` a name and the key rule a function; and a target that may retry (`retry`'s
34
+ * ceiling above 1) must declare the key rule.
35
+ */
36
+ export function touchesProblem(touches, retry) {
37
+ if (touches === null || typeof touches !== 'object') {
38
+ return 'touches must be { system, idempotencyKey? } — the outside system and the key rule';
39
+ }
40
+ const { system, idempotencyKey } = touches;
41
+ const nameProblem = attemptNameProblem(system);
42
+ if (nameProblem !== undefined)
43
+ return `touches.system ${nameProblem} — it is a name from code, never a value`;
44
+ if (idempotencyKey !== undefined && typeof idempotencyKey !== 'function') {
45
+ return ('touches.idempotencyKey must be a function of the execution ((ctx) => string) — a constant key would make ' +
46
+ 'every run one operation');
47
+ }
48
+ const attempts = attemptCeiling(retry?.attempts);
49
+ if (attempts > 1 && idempotencyKey === undefined)
50
+ return retriedWithoutKey(system, attempts);
51
+ return undefined;
52
+ }
53
+ /** `value` as an idempotency key (`ids/idempotencyKey.ts`, the one rule), or a `TypeError` that names `where`. */
54
+ export function admitIdempotencyKey(where, value) {
55
+ const problem = idempotencyKeyProblem(value);
56
+ if (problem !== undefined) {
57
+ throw new TypeError(`${where}: idempotencyKey ${problem} (derive it from the input or the state, never from model output)`);
58
+ }
59
+ return value;
60
+ }
61
+ /**
62
+ * A `$call`'s side-effect declaration, admitted: `undefined` when it touches nothing; otherwise the system and the
63
+ * key, refused with a `TypeError` naming `where` when malformed, when a key comes without a system, or when the
64
+ * call may retry with no key — before anything is sent.
65
+ */
66
+ export function callTouches(where, options, policy) {
67
+ if (options === undefined)
68
+ return undefined;
69
+ if (options === null || typeof options !== 'object') {
70
+ throw new TypeError(`${where}: options must be { touches?, idempotencyKey? }`);
71
+ }
72
+ const { touches, idempotencyKey } = options;
73
+ if (touches === undefined) {
74
+ if (idempotencyKey !== undefined) {
75
+ throw new TypeError(`${where}: an idempotencyKey names an effect — declare the system it touches (touches)`);
76
+ }
77
+ return undefined;
78
+ }
79
+ const nameProblem = attemptNameProblem(touches);
80
+ if (nameProblem !== undefined) {
81
+ throw new TypeError(`${where}: touches ${nameProblem} — it is a name from code, never a value`);
82
+ }
83
+ const key = idempotencyKey === undefined ? undefined : admitIdempotencyKey(where, idempotencyKey);
84
+ const attempts = attemptCeiling(policy.attempts);
85
+ if (attempts > 1 && key === undefined)
86
+ throw new TypeError(`${where}: ${retriedWithoutKey(touches, attempts)}`);
87
+ return { system: touches, ...(key !== undefined && { idempotencyKey: key }) };
88
+ }
89
+ /** What an attempt that ended `outcome` (with `error`, when it failed) did to the outside system. */
90
+ export function effectOf(outcome, error) {
91
+ if (outcome === 'ok')
92
+ return 'applied';
93
+ if (outcome === 'failed' && declaresNoEffect(error))
94
+ return 'none';
95
+ return 'unknown';
96
+ }
97
+ /** The error itself says nothing was sent — `effect: 'none'`, read once; a value that cannot be read says nothing. */
98
+ function declaresNoEffect(error) {
99
+ if (error === null || typeof error !== 'object')
100
+ return false;
101
+ try {
102
+ return error.effect === 'none';
103
+ }
104
+ catch {
105
+ return false;
106
+ }
107
+ }
108
+ /**
109
+ * What a touching series fails with when any of its attempts left the effect unknown — never the attempt's own error,
110
+ * which a caller would read as a failure and retry. The key is the RECORDED one: under a redaction rule that names
111
+ * it, the error carries the placeholder, as every record does.
112
+ */
113
+ export function unknownEffectError(target, record, cause) {
114
+ return new UnknownEffectError({
115
+ system: target.system,
116
+ ...(recordedKeyOf(target) !== undefined && { idempotencyKey: recordedKeyOf(target) }),
117
+ attempts: record.attempt,
118
+ cause,
119
+ });
120
+ }
121
+ /** The key as records carry it: the served form when the caller gave one, else the key itself. */
122
+ export function recordedKeyOf(target) {
123
+ return target.recordedKey ?? target.idempotencyKey;
124
+ }
125
+ /** The runner's refusal of a touching series that may retry with no key — the law, at the last door. */
126
+ export function refuseKeylessRetry(target, attempts) {
127
+ if (attempts > 1 && target.idempotencyKey === undefined) {
128
+ throw new TypeError(`[footprint] ${retriedWithoutKey(target.system, attempts)}`);
129
+ }
130
+ }
131
+ /**
132
+ * Why a touching stage may not be RE-RUN by an `interrupt()` resume, or `undefined` when it may (P3). A resume
133
+ * re-runs the stage's function from its top — a second attempt of its effect — so the law that refuses a keyless
134
+ * retry refuses a keyless re-run too. Asked when the stage interrupts (`StageRunner`) and when a checkpoint is
135
+ * resumed (`runner/resume.ts · planResume`, for a checkpoint made by another version of the chart).
136
+ */
137
+ export function interruptProblem(touches) {
138
+ if (touches === undefined || touches.idempotencyKey !== undefined)
139
+ return undefined;
140
+ return (`touches "${touches.system}" with no idempotencyKey, and a resume after interrupt() re-runs the stage from its ` +
141
+ 'top — a second attempt of the effect without a key. Declare the key rule, or interrupt in a stage of its own.');
142
+ }
143
+ /** The touching declarations `resume()` builds around a key a checkpoint carried (`carriedTouches`). */
144
+ const CARRIED = new WeakSet();
145
+ /**
146
+ * The stand-in's declaration on a resume (P3): the paused stage's system, answering the key its checkpoint carried —
147
+ * the OPERATIONAL value, real (checkpoints are exempt from redaction by law). It is marked, so the run serves it
148
+ * like a key of unknown sources: under any state rule the records carry the placeholder (`isCarriedTouches`) — the
149
+ * resumed leg no longer holds the input the key was made of, so it cannot tell whether the key was masked.
150
+ */
151
+ export function carriedTouches(system, key) {
152
+ const touches = Object.freeze({ system, idempotencyKey: () => key });
153
+ CARRIED.add(touches);
154
+ return touches;
155
+ }
156
+ /** The declaration answers a key a checkpoint carried ({@link carriedTouches}). */
157
+ export function isCarriedTouches(touches) {
158
+ return typeof touches === 'object' && touches !== null && CARRIED.has(touches);
159
+ }
160
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZmZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9hdHRlbXB0L2VmZmVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDakUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMvQyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRzdDLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBWXRFLGtGQUFrRjtBQUNsRixTQUFTLGlCQUFpQixDQUFDLE1BQWMsRUFBRSxRQUFnQjtJQUN6RCxPQUFPLENBQ0wsWUFBWSxNQUFNLDhCQUE4QixRQUFRLG1EQUFtRDtRQUMzRyx3RUFBd0U7UUFDeEUsY0FBYyxNQUFNLG1GQUFtRixDQUN4RyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsY0FBYyxDQUFDLE9BQWdCLEVBQUUsS0FBZ0Q7SUFDL0YsSUFBSSxPQUFPLEtBQUssSUFBSSxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3BELE9BQU8sbUZBQW1GLENBQUM7SUFDN0YsQ0FBQztJQUNELE1BQU0sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLEdBQUcsT0FBZ0MsQ0FBQztJQUNwRSxNQUFNLFdBQVcsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMvQyxJQUFJLFdBQVcsS0FBSyxTQUFTO1FBQUUsT0FBTyxrQkFBa0IsV0FBVywwQ0FBMEMsQ0FBQztJQUM5RyxJQUFJLGNBQWMsS0FBSyxTQUFTLElBQUksT0FBTyxjQUFjLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDekUsT0FB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TyxDQUNMLFlBQVksT0FBTyxDQUFDLE1BQU0sc0ZBQXNGO1FBQ2hILCtHQUErRyxDQUNoSCxDQUFDO0FBQ0osQ0FBQztBQUVELHdHQUF3RztBQUN4RyxNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO0FBRXRDOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBQyxNQUFjLEVBQUUsR0FBVztJQUN4RCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ3JFLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckIsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQztBQUVELG1GQUFtRjtBQUNuRixNQUFNLFVBQVUsZ0JBQWdCLENBQUMsT0FBZ0I7SUFDL0MsT0FBTyxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksT0FBTyxLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ2pGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGF0dGVtcHQvZWZmZWN0LnRzIOKAlCBzaWRlLWVmZmVjdCBzYWZldHkgKGRlc2lnbiDCpzMuMywgcGFja2V0IFAzKTogdGhlIE9ORSByZWFkaW5nIG9mIHdoYXQgYW4gYXR0ZW1wdCBkaWQgdG8gYW5cbiAqIG91dHNpZGUgc3lzdGVtLCBhbmQgdGhlIE9ORSBydWxlIGZvciBhIHRvdWNoaW5nIHRhcmdldC5cbiAqXG4gKiAgIC0gYHRvdWNoZXNQcm9ibGVtYCDigJQgdGhlIGJ1aWxkIGxhdywgYXNrZWQgYXQgZXZlcnkgZG9vciBhIHRvdWNoaW5nIGRlY2xhcmF0aW9uIGVudGVyczogdGhlIGJ1aWxkZXJcbiAqICAgICAoYEZsb3dDaGFydEJ1aWxkZXIgwrcgYXBwbHlUb3VjaGVzYCAvIGBhcHBseVJldHJ5UG9saWN5YCksIHRoZSB0cmF2ZXJzZXIgZm9yIGEgU3RhZ2VOb2RlIGEgc3RhZ2UgcmV0dXJucyBhdCBydW5cbiAqICAgICB0aW1lIChgRmxvd2NoYXJ0VHJhdmVyc2VyIMK3IGFkbWl0RHluYW1pY05vZGVzYCksIGFuZCB0aGUgc3RhZ2UgaXRzZWxmIChgRmxvd2NoYXJ0VHJhdmVyc2VyIMK3IGV4ZWN1dGVTdGFnZWAsIGZvclxuICogICAgIGEgY2hhcnQgZWRpdGVkIGFmdGVyIGBidWlsZCgpYCkuIEEgdG91Y2hpbmcgdGFyZ2V0IHRoYXQgbWF5IHJldHJ5IHdpdGhvdXQgYW4gaWRlbXBvdGVuY3kga2V5IGlzIHJlZnVzZWQ6IGFcbiAqICAgICByZXRyeSBvZiBhIG5vbi1pZGVtcG90ZW50IGVmZmVjdCB3aXRob3V0IG9uZSBjYW4gYXBwbHkgaXQgdHdpY2UuXG4gKiAgIC0gYGNhbGxUb3VjaGVzYCDigJQgdGhlIHNhbWUgbGF3IGZvciBgc2NvcGUuJGNhbGwodGFyZ2V0LCBmbiwgcG9saWN5LCB7IHRvdWNoZXMsIGlkZW1wb3RlbmN5S2V5IH0pYC5cbiAqICAgLSBgYWRtaXRJZGVtcG90ZW5jeUtleWAg4oCUIHRoZSBrZXkncyBmb3JtYXQ6IDHigJMyNTUgcHJpbnRhYmxlIEFTQ0lJIGNoYXJhY3RlcnMsIG5vIHNwYWNlLiBJdCB0cmF2ZWxzIGluIGEgcmVxdWVzdFxuICogICAgIGhlYWRlciAoYElkZW1wb3RlbmN5LUtleWApLCBzbyBhIGNvbnRyb2wgY2hhcmFjdGVyIGNvdWxkIGZvcmdlIG9uZTsgdGhlIHJlZnVzYWwgbmFtZXMgdGhlIGZpZWxkLCBuZXZlciB0aGVcbiAqICAgICB2YWx1ZS5cbiAqICAgLSBgZWZmZWN0T2ZgIOKAlCBgb2sg4oaSICdhcHBsaWVkJ2A7IGEgZmFpbHVyZSB3aG9zZSBlcnJvciBkZWNsYXJlcyBgZWZmZWN0OiAnbm9uZSdgIOKGkiBgJ25vbmUnYDsgYW55dGhpbmcgZWxzZSDihpJcbiAqICAgICBgJ3Vua25vd24nYC4gQSB0aW1lb3V0IGlzIHRoZSBhYnNlbmNlIG9mIGFuIGFuc3dlciAobGF3IDQpLCBzbyBpdCBpcyBuZXZlciBgJ25vbmUnYC5cbiAqICAgLSBgdW5rbm93bkVmZmVjdEVycm9yYCDigJQgd2hhdCBhIHNlcmllcyB0aGF0IGVuZHMgd2l0aG91dCBhbiBhbnN3ZXIgYWZ0ZXIgQU5ZIGF0dGVtcHQgb2YgdW5rbm93biBlZmZlY3QgZmFpbHNcbiAqICAgICB3aXRoLCBpbiBwbGFjZSBvZiB0aGUgYXR0ZW1wdCdzIG93biBlcnJvciAoaXRzIGBjYXVzZWApLlxuICogICAtIGBpbnRlcnJ1cHRQcm9ibGVtYCDigJQgYSBrZXlsZXNzIHRvdWNoaW5nIHN0YWdlIG1heSBub3QgYmUgcmUtcnVuIGJ5IGFuIGBpbnRlcnJ1cHQoKWAgcmVzdW1lLlxuICovXG5cbmltcG9ydCB7IGlkZW1wb3RlbmN5S2V5UHJvYmxlbSB9IGZyb20gJy4uL2lkcy9pZGVtcG90ZW5jeUtleS5qcyc7XG5pbXBvcnQgeyBVbmtub3duRWZmZWN0RXJyb3IgfSBmcm9tICcuL2Vycm9ycy5qcyc7XG5pbXBvcnQgeyBhdHRlbXB0TmFtZVByb2JsZW0gfSBmcm9tICcuL25hbWUuanMnO1xuaW1wb3J0IHsgYXR0ZW1wdENlaWxpbmcgfSBmcm9tICcuL3BvbGljeS5qcyc7XG5pbXBvcnQgdHlwZSB7IEF0dGVtcHRFZmZlY3QsIEF0dGVtcHRPdXRjb21lLCBBdHRlbXB0UmVjb3JkLCBDYWxsT3B0aW9ucywgUmV0cnlQb2xpY3ksIFN0YWdlVG91Y2hlcyB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG5leHBvcnQgeyBNQVhfSURFTVBPVEVOQ1lfS0VZX0xFTkdUSCB9IGZyb20gJy4uL2lkcy9pZGVtcG90ZW5jeUtleS5qcyc7XG5cbi8qKlxuICogV2hhdCBhIHRvdWNoaW5nIHJ1bm5lciBzZXJpZXMgaXMgdG9sZCAoYEF0dGVtcHRSdW5PcHRpb25zLmVmZmVjdGApOiB0aGUgc3lzdGVtLCB0aGUgUkVBTCBrZXkgdGhlIGF0dGVtcHRzIGFyZSBtYWRlXG4gKiB1bmRlciwgYW5kIHRoZSBrZXkgYXMgcmVjb3JkcyBjYXJyeSBpdCAodGhlIHJ1bidzIHNlcnZlZCBmb3JtOyB0aGUgcmVhbCBvbmUgd2hlbiBubyBydWxlIGFwcGxpZXMpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEVmZmVjdFRhcmdldCB7XG4gIHJlYWRvbmx5IHN5c3RlbTogc3RyaW5nO1xuICByZWFkb25seSBpZGVtcG90ZW5jeUtleT86IHN0cmluZztcbiAgcmVhZG9ubHkgcmVjb3JkZWRLZXk/OiBzdHJpbmc7XG59XG5cbi8qKiBXaHkgYHJldHJ5YCB3aXRoIGB0b3VjaGVzYCBicmVha3MgdGhlIGxhdyDigJQgdGhlIHNoYXJlZCB3b3JkcyBvZiBldmVyeSBkb29yLiAqL1xuZnVuY3Rpb24gcmV0cmllZFdpdGhvdXRLZXkoc3lzdGVtOiBzdHJpbmcsIGF0dGVtcHRzOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gKFxuICAgIGB0b3VjaGVzIFwiJHtzeXN0ZW19XCIgYW5kIG1heSByZXRyeSAoYXR0ZW1wdHM6ICR7YXR0ZW1wdHN9KSBidXQgZGVjbGFyZXMgbm8gaWRlbXBvdGVuY3lLZXkg4oCUIGEgcmV0cnkgb2YgYW4gYCArXG4gICAgJ291dHNpZGUgZWZmZWN0IHdpdGhvdXQgYSBrZXkgY2FuIGFwcGx5IGl0IHR3aWNlLiBEZWNsYXJlIHRoZSBrZXkgcnVsZSAnICtcbiAgICBgKC50b3VjaGVzKCcke3N5c3RlbX0nLCB7IGlkZW1wb3RlbmN5S2V5OiAoeyBhcmdzIH0pID0+IFxcYG9yZGVyLVxcJHthcmdzLm9yZGVySWR9XFxgIH0pKSwgb3IgcmV0cnkgb25jZS5gXG4gICk7XG59XG5cbi8qKlxuICogV2h5IGEgdG91Y2hpbmcgZGVjbGFyYXRpb24gaXMgcmVmdXNlZCwgb3IgYHVuZGVmaW5lZGAgd2hlbiBpdCBpcyBhZG1pdHRlZDogYHRvdWNoZXNgIG11c3QgYmUgYHsgc3lzdGVtLFxuICogaWRlbXBvdGVuY3lLZXk/IH1gIHdpdGggYHN5c3RlbWAgYSBuYW1lIGFuZCB0aGUga2V5IHJ1bGUgYSBmdW5jdGlvbjsgYW5kIGEgdGFyZ2V0IHRoYXQgbWF5IHJldHJ5IChgcmV0cnlgJ3NcbiAqIGNlaWxpbmcgYWJvdmUgMSkgbXVzdCBkZWNsYXJlIHRoZSBrZXkgcnVsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvdWNoZXNQcm9ibGVtKHRvdWNoZXM6IHVua25vd24sIHJldHJ5OiBQaWNrPFJldHJ5UG9saWN5LCAnYXR0ZW1wdHMnPiB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICh0b3VjaGVzID09PSBudWxsIHx8IHR5cGVvZiB0b3VjaGVzICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiAndG91Y2hlcyBtdXN0IGJlIHsgc3lzdGVtLCBpZGVtcG90ZW5jeUtleT8gfSDigJQgdGhlIG91dHNpZGUgc3lzdGVtIGFuZCB0aGUga2V5IHJ1bGUnO1xuICB9XG4gIGNvbnN0IHsgc3lzdGVtLCBpZGVtcG90ZW5jeUtleSB9ID0gdG91Y2hlcyBhcyBQYXJ0aWFsPFN0YWdlVG91Y2hlcz47XG4gIGNvbnN0IG5hbWVQcm9ibGVtID0gYXR0ZW1wdE5hbWVQcm9ibGVtKHN5c3RlbSk7XG4gIGlmIChuYW1lUHJvYmxlbSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gYHRvdWNoZXMuc3lzdGVtICR7bmFtZVByb2JsZW19IOKAlCBpdCBpcyBhIG5hbWUgZnJvbSBjb2RlLCBuZXZlciBhIHZhbHVlYDtcbiAgaWYgKGlkZW1wb3RlbmN5S2V5ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIGlkZW1wb3RlbmN5S2V5ICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIChcbiAgICAgICd0b3VjaGVzLmlkZW1wb3RlbmN5S2V5IG11c3QgYmUgYSBmdW5jdGlvbiBvZiB0aGUgZXhlY3V0aW9uICgoY3R4KSA9PiBzdHJpbmcpIOKAlCBhIGNvbnN0YW50IGtleSB3b3VsZCBtYWtlICcgK1xuICAgICAgJ2V2ZXJ5IHJ1biBvbmUgb3BlcmF0aW9uJ1xuICAgICk7XG4gIH1cbiAgY29uc3QgYXR0ZW1wdHMgPSBhdHRlbXB0Q2VpbGluZyhyZXRyeT8uYXR0ZW1wdHMpO1xuICBpZiAoYXR0ZW1wdHMgPiAxICYmIGlkZW1wb3RlbmN5S2V5ID09PSB1bmRlZmluZWQpIHJldHVybiByZXRyaWVkV2l0aG91dEtleShzeXN0ZW0gYXMgc3RyaW5nLCBhdHRlbXB0cyk7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBgdmFsdWVgIGFzIGFuIGlkZW1wb3RlbmN5IGtleSAoYGlkcy9pZGVtcG90ZW5jeUtleS50c2AsIHRoZSBvbmUgcnVsZSksIG9yIGEgYFR5cGVFcnJvcmAgdGhhdCBuYW1lcyBgd2hlcmVgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkbWl0SWRlbXBvdGVuY3lLZXkod2hlcmU6IHN0cmluZywgdmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICBjb25zdCBwcm9ibGVtID0gaWRlbXBvdGVuY3lLZXlQcm9ibGVtKHZhbHVlKTtcbiAgaWYgKHByb2JsZW0gIT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICBgJHt3aGVyZX06IGlkZW1wb3RlbmN5S2V5ICR7cHJvYmxlbX0gKGRlcml2ZSBpdCBmcm9tIHRoZSBpbnB1dCBvciB0aGUgc3RhdGUsIG5ldmVyIGZyb20gbW9kZWwgb3V0cHV0KWAsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gdmFsdWUgYXMgc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgYCRjYWxsYCdzIHNpZGUtZWZmZWN0IGRlY2xhcmF0aW9uLCBhZG1pdHRlZDogYHVuZGVmaW5lZGAgd2hlbiBpdCB0b3VjaGVzIG5vdGhpbmc7IG90aGVyd2lzZSB0aGUgc3lzdGVtIGFuZCB0aGVcbiAqIGtleSwgcmVmdXNlZCB3aXRoIGEgYFR5cGVFcnJvcmAgbmFtaW5nIGB3aGVyZWAgd2hlbiBtYWxmb3JtZWQsIHdoZW4gYSBrZXkgY29tZXMgd2l0aG91dCBhIHN5c3RlbSwgb3Igd2hlbiB0aGVcbiAqIGNhbGwgbWF5IHJldHJ5IHdpdGggbm8ga2V5IOKAlCBiZWZvcmUgYW55dGhpbmcgaXMgc2VudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGxUb3VjaGVzKFxuICB3aGVyZTogc3RyaW5nLFxuICBvcHRpb25zOiB1bmtub3duLFxuICBwb2xpY3k6IFBpY2s8UmV0cnlQb2xpY3ksICdhdHRlbXB0cyc+LFxuKTogeyByZWFkb25seSBzeXN0ZW06IHN0cmluZzsgcmVhZG9ubHkgaWRlbXBvdGVuY3lLZXk/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb25zID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChvcHRpb25zID09PSBudWxsIHx8IHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7d2hlcmV9OiBvcHRpb25zIG11c3QgYmUgeyB0b3VjaGVzPywgaWRlbXBvdGVuY3lLZXk/IH1gKTtcbiAgfVxuICBjb25zdCB7IHRvdWNoZXMsIGlkZW1wb3RlbmN5S2V5IH0gPSBvcHRpb25zIGFzIENhbGxPcHRpb25zO1xuICBpZiAodG91Y2hlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGlkZW1wb3RlbmN5S2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7d2hlcmV9OiBhbiBpZGVtcG90ZW5jeUtleSBuYW1lcyBhbiBlZmZlY3Qg4oCUIGRlY2xhcmUgdGhlIHN5c3RlbSBpdCB0b3VjaGVzICh0b3VjaGVzKWApO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IG5hbWVQcm9ibGVtID0gYXR0ZW1wdE5hbWVQcm9ibGVtKHRvdWNoZXMpO1xuICBpZiAobmFtZVByb2JsZW0gIT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7d2hlcmV9OiB0b3VjaGVzICR7bmFtZVByb2JsZW19IOKAlCBpdCBpcyBhIG5hbWUgZnJvbSBjb2RlLCBuZXZlciBhIHZhbHVlYCk7XG4gIH1cbiAgY29uc3Qga2V5ID0gaWRlbXBvdGVuY3lLZXkgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGFkbWl0SWRlbXBvdGVuY3lLZXkod2hlcmUsIGlkZW1wb3RlbmN5S2V5KTtcbiAgY29uc3QgYXR0ZW1wdHMgPSBhdHRlbXB0Q2VpbGluZyhwb2xpY3kuYXR0ZW1wdHMpO1xuICBpZiAoYXR0ZW1wdHMgPiAxICYmIGtleSA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKGAke3doZXJlfTogJHtyZXRyaWVkV2l0aG91dEtleSh0b3VjaGVzLCBhdHRlbXB0cyl9YCk7XG4gIHJldHVybiB7IHN5c3RlbTogdG91Y2hlcywgLi4uKGtleSAhPT0gdW5kZWZpbmVkICYmIHsgaWRlbXBvdGVuY3lLZXk6IGtleSB9KSB9O1xufVxuXG4vKiogV2hhdCBhbiBhdHRlbXB0IHRoYXQgZW5kZWQgYG91dGNvbWVgICh3aXRoIGBlcnJvcmAsIHdoZW4gaXQgZmFpbGVkKSBkaWQgdG8gdGhlIG91dHNpZGUgc3lzdGVtLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVmZmVjdE9mKG91dGNvbWU6IEF0dGVtcHRPdXRjb21lLCBlcnJvcjogdW5rbm93bik6IEF0dGVtcHRFZmZlY3Qge1xuICBpZiAob3V0Y29tZSA9PT0gJ29rJykgcmV0dXJuICdhcHBsaWVkJztcbiAgaWYgKG91dGNvbWUgPT09ICdmYWlsZWQnICYmIGRlY2xhcmVzTm9FZmZlY3QoZXJyb3IpKSByZXR1cm4gJ25vbmUnO1xuICByZXR1cm4gJ3Vua25vd24nO1xufVxuXG4vKiogVGhlIGVycm9yIGl0c2VsZiBzYXlzIG5vdGhpbmcgd2FzIHNlbnQg4oCUIGBlZmZlY3Q6ICdub25lJ2AsIHJlYWQgb25jZTsgYSB2YWx1ZSB0aGF0IGNhbm5vdCBiZSByZWFkIHNheXMgbm90aGluZy4gKi9cbmZ1bmN0aW9uIGRlY2xhcmVzTm9FZmZlY3QoZXJyb3I6IHVua25vd24pOiBib29sZWFuIHtcbiAgaWYgKGVycm9yID09PSBudWxsIHx8IHR5cGVvZiBlcnJvciAhPT0gJ29iamVjdCcpIHJldHVybiBmYWxzZTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gKGVycm9yIGFzIHsgZWZmZWN0PzogdW5rbm93biB9KS5lZmZlY3QgPT09ICdub25lJztcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogV2hhdCBhIHRvdWNoaW5nIHNlcmllcyBmYWlscyB3aXRoIHdoZW4gYW55IG9mIGl0cyBhdHRlbXB0cyBsZWZ0IHRoZSBlZmZlY3QgdW5rbm93biDigJQgbmV2ZXIgdGhlIGF0dGVtcHQncyBvd24gZXJyb3IsXG4gKiB3aGljaCBhIGNhbGxlciB3b3VsZCByZWFkIGFzIGEgZmFpbHVyZSBhbmQgcmV0cnkuIFRoZSBrZXkgaXMgdGhlIFJFQ09SREVEIG9uZTogdW5kZXIgYSByZWRhY3Rpb24gcnVsZSB0aGF0IG5hbWVzXG4gKiBpdCwgdGhlIGVycm9yIGNhcnJpZXMgdGhlIHBsYWNlaG9sZGVyLCBhcyBldmVyeSByZWNvcmQgZG9lcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVua25vd25FZmZlY3RFcnJvcih0YXJnZXQ6IEVmZmVjdFRhcmdldCwgcmVjb3JkOiBBdHRlbXB0UmVjb3JkLCBjYXVzZTogdW5rbm93bik6IFVua25vd25FZmZlY3RFcnJvciB7XG4gIHJldHVybiBuZXcgVW5rbm93bkVmZmVjdEVycm9yKHtcbiAgICBzeXN0ZW06IHRhcmdldC5zeXN0ZW0sXG4gICAgLi4uKHJlY29yZGVkS2V5T2YodGFyZ2V0KSAhPT0gdW5kZWZpbmVkICYmIHsgaWRlbXBvdGVuY3lLZXk6IHJlY29yZGVkS2V5T2YodGFyZ2V0KSB9KSxcbiAgICBhdHRlbXB0czogcmVjb3JkLmF0dGVtcHQsXG4gICAgY2F1c2UsXG4gIH0pO1xufVxuXG4vKiogVGhlIGtleSBhcyByZWNvcmRzIGNhcnJ5IGl0OiB0aGUgc2VydmVkIGZvcm0gd2hlbiB0aGUgY2FsbGVyIGdhdmUgb25lLCBlbHNlIHRoZSBrZXkgaXRzZWxmLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY29yZGVkS2V5T2YodGFyZ2V0OiBFZmZlY3RUYXJnZXQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdGFyZ2V0LnJlY29yZGVkS2V5ID8/IHRhcmdldC5pZGVtcG90ZW5jeUtleTtcbn1cblxuLyoqIFRoZSBydW5uZXIncyByZWZ1c2FsIG9mIGEgdG91Y2hpbmcgc2VyaWVzIHRoYXQgbWF5IHJldHJ5IHdpdGggbm8ga2V5IOKAlCB0aGUgbGF3LCBhdCB0aGUgbGFzdCBkb29yLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZnVzZUtleWxlc3NSZXRyeSh0YXJnZXQ6IEVmZmVjdFRhcmdldCwgYXR0ZW1wdHM6IG51bWJlcik6IHZvaWQge1xuICBpZiAoYXR0ZW1wdHMgPiAxICYmIHRhcmdldC5pZGVtcG90ZW5jeUtleSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgW2Zvb3RwcmludF0gJHtyZXRyaWVkV2l0aG91dEtleSh0YXJnZXQuc3lzdGVtLCBhdHRlbXB0cyl9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBXaHkgYSB0b3VjaGluZyBzdGFnZSBtYXkgbm90IGJlIFJFLVJVTiBieSBhbiBgaW50ZXJydXB0KClgIHJlc3VtZSwgb3IgYHVuZGVmaW5lZGAgd2hlbiBpdCBtYXkgKFAzKS4gQSByZXN1bWVcbiAqIHJlLXJ1bnMgdGhlIHN0YWdlJ3MgZnVuY3Rpb24gZnJvbSBpdHMgdG9wIOKAlCBhIHNlY29uZCBhdHRlbXB0IG9mIGl0cyBlZmZlY3Qg4oCUIHNvIHRoZSBsYXcgdGhhdCByZWZ1c2VzIGEga2V5bGVzc1xuICogcmV0cnkgcmVmdXNlcyBhIGtleWxlc3MgcmUtcnVuIHRvby4gQXNrZWQgd2hlbiB0aGUgc3RhZ2UgaW50ZXJydXB0cyAoYFN0YWdlUnVubmVyYCkgYW5kIHdoZW4gYSBjaGVja3BvaW50IGlzXG4gKiByZXN1bWVkIChgcnVubmVyL3Jlc3VtZS50cyDCtyBwbGFuUmVzdW1lYCwgZm9yIGEgY2hlY2twb2ludCBtYWRlIGJ5IGFub3RoZXIgdmVyc2lvbiBvZiB0aGUgY2hhcnQpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW50ZXJydXB0UHJvYmxlbSh0b3VjaGVzOiBTdGFnZVRvdWNoZXMgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAodG91Y2hlcyA9PT0gdW5kZWZpbmVkIHx8IHRvdWNoZXMuaWRlbXBvdGVuY3lLZXkgIT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIChcbiAgICBgdG91Y2hlcyBcIiR7dG91Y2hlcy5zeXN0ZW19XCIgd2l0aCBubyBpZGVtcG90ZW5jeUtleSwgYW5kIGEgcmVzdW1lIGFmdGVyIGludGVycnVwdCgpIHJlLXJ1bnMgdGhlIHN0YWdlIGZyb20gaXRzIGAgK1xuICAgICd0b3Ag4oCUIGEgc2Vjb25kIGF0dGVtcHQgb2YgdGhlIGVmZmVjdCB3aXRob3V0IGEga2V5LiBEZWNsYXJlIHRoZSBrZXkgcnVsZSwgb3IgaW50ZXJydXB0IGluIGEgc3RhZ2Ugb2YgaXRzIG93bi4nXG4gICk7XG59XG5cbi8qKiBUaGUgdG91Y2hpbmcgZGVjbGFyYXRpb25zIGByZXN1bWUoKWAgYnVpbGRzIGFyb3VuZCBhIGtleSBhIGNoZWNrcG9pbnQgY2FycmllZCAoYGNhcnJpZWRUb3VjaGVzYCkuICovXG5jb25zdCBDQVJSSUVEID0gbmV3IFdlYWtTZXQ8b2JqZWN0PigpO1xuXG4vKipcbiAqIFRoZSBzdGFuZC1pbidzIGRlY2xhcmF0aW9uIG9uIGEgcmVzdW1lIChQMyk6IHRoZSBwYXVzZWQgc3RhZ2UncyBzeXN0ZW0sIGFuc3dlcmluZyB0aGUga2V5IGl0cyBjaGVja3BvaW50IGNhcnJpZWQg4oCUXG4gKiB0aGUgT1BFUkFUSU9OQUwgdmFsdWUsIHJlYWwgKGNoZWNrcG9pbnRzIGFyZSBleGVtcHQgZnJvbSByZWRhY3Rpb24gYnkgbGF3KS4gSXQgaXMgbWFya2VkLCBzbyB0aGUgcnVuIHNlcnZlcyBpdFxuICogbGlrZSBhIGtleSBvZiB1bmtub3duIHNvdXJjZXM6IHVuZGVyIGFueSBzdGF0ZSBydWxlIHRoZSByZWNvcmRzIGNhcnJ5IHRoZSBwbGFjZWhvbGRlciAoYGlzQ2FycmllZFRvdWNoZXNgKSDigJQgdGhlXG4gKiByZXN1bWVkIGxlZyBubyBsb25nZXIgaG9sZHMgdGhlIGlucHV0IHRoZSBrZXkgd2FzIG1hZGUgb2YsIHNvIGl0IGNhbm5vdCB0ZWxsIHdoZXRoZXIgdGhlIGtleSB3YXMgbWFza2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FycmllZFRvdWNoZXMoc3lzdGVtOiBzdHJpbmcsIGtleTogc3RyaW5nKTogU3RhZ2VUb3VjaGVzIHtcbiAgY29uc3QgdG91Y2hlcyA9IE9iamVjdC5mcmVlemUoeyBzeXN0ZW0sIGlkZW1wb3RlbmN5S2V5OiAoKSA9PiBrZXkgfSk7XG4gIENBUlJJRUQuYWRkKHRvdWNoZXMpO1xuICByZXR1cm4gdG91Y2hlcztcbn1cblxuLyoqIFRoZSBkZWNsYXJhdGlvbiBhbnN3ZXJzIGEga2V5IGEgY2hlY2twb2ludCBjYXJyaWVkICh7QGxpbmsgY2FycmllZFRvdWNoZXN9KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NhcnJpZWRUb3VjaGVzKHRvdWNoZXM6IHVua25vd24pOiBib29sZWFuIHtcbiAgcmV0dXJuIHR5cGVvZiB0b3VjaGVzID09PSAnb2JqZWN0JyAmJiB0b3VjaGVzICE9PSBudWxsICYmIENBUlJJRUQuaGFzKHRvdWNoZXMpO1xufVxuIl19