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,165 @@
1
+ import { gaveUp } from './attemptSeries.js';
2
+ export const attemptRowKey = (row) => JSON.stringify(row.kind === 'attempt'
3
+ ? [row.kind, row.runId, row.id]
4
+ : row.kind === 'decision'
5
+ ? [row.kind, row.runId, row.series, row.attempt]
6
+ : [row.kind, row.runId]);
7
+ export const logicalKey = (runId, series, attempt) => JSON.stringify([runId, series, attempt]);
8
+ export const seriesKey = (runId, series) => JSON.stringify([runId, series]);
9
+ export function reference(row) {
10
+ const { id, series, runId, runtimeStageId, attemptKind, target, traceId, startedAt, durationMs, outcome, category, next, reason, retryLoop, } = row;
11
+ return {
12
+ id,
13
+ series,
14
+ runId,
15
+ runtimeStageId,
16
+ attemptKind,
17
+ target,
18
+ ...(traceId === undefined ? {} : { traceId }),
19
+ startedAt,
20
+ durationMs,
21
+ outcome,
22
+ ...(category === undefined ? {} : { category }),
23
+ next,
24
+ reason,
25
+ ...(retryLoop === undefined ? {} : { retryLoop: { ...retryLoop } }),
26
+ };
27
+ }
28
+ const order = (a, b) => b.durationMs - a.durationMs || b.startedAt - a.startedAt || a.id.localeCompare(b.id);
29
+ export function worst(rows, limit) {
30
+ return [...rows].sort(order).slice(0, limit).map(reference);
31
+ }
32
+ function summarized(target, rows, decisions, exemplars) {
33
+ const byKind = { stage: 0, call: 0, observed: 0 };
34
+ const byOutcome = { ok: 0, failed: 0, timeout: 0, aborted: 0, paused: 0 };
35
+ const byCategory = { timeout: 0, 'rate-limited': 0, server: 0, network: 0, auth: 0, permanent: 0, unknown: 0 };
36
+ let retries = 0;
37
+ const retried = new Set();
38
+ const gave = new Set();
39
+ const stopped = new Set();
40
+ for (const row of rows) {
41
+ byKind[row.attemptKind]++;
42
+ byOutcome[row.outcome]++;
43
+ if (row.category !== undefined)
44
+ byCategory[row.category]++;
45
+ // A reconciliation wire call is work, but its one-call stop is not a logical workflow give-up.
46
+ if (row.retryLoop?.phase === 'reconcile')
47
+ continue;
48
+ const logical = row.retryLoop;
49
+ const decision = logical === undefined ? row : decisions.get(logicalKey(row.runId, logical.series, logical.attempt));
50
+ if (decision === undefined ||
51
+ (logical !== undefined && (decision.kind !== 'decision' || decision.attemptId !== row.id)))
52
+ continue; // A logical verdict belongs only to the exact physical attempt it cites.
53
+ const key = seriesKey(row.runId, logical?.series ?? row.series);
54
+ if (decision.next === 'retry') {
55
+ retries++;
56
+ retried.add(key);
57
+ }
58
+ if (gaveUp({ next: decision.next, reason: decision.reason })) {
59
+ gave.add(key);
60
+ stopped.add(row);
61
+ }
62
+ }
63
+ const sorted = [...rows].sort(order);
64
+ const n = sorted.length;
65
+ const rank = (p) => (n === 0 ? 0 : sorted[n - Math.ceil(n * p)].durationMs);
66
+ const refs = (include) => sorted.filter(include).slice(0, exemplars).map(reference);
67
+ const used = rows.reduce((n, row) => n + row.durationMs, 0);
68
+ return {
69
+ target,
70
+ count: n,
71
+ byKind,
72
+ byOutcome,
73
+ byCategory,
74
+ retries,
75
+ seriesRetried: retried.size,
76
+ gaveUp: gave.size,
77
+ effectUnknown: rows.filter((row) => row.effect === 'unknown').length,
78
+ latencyMs: {
79
+ p50: rank(0.5),
80
+ p90: rank(0.9),
81
+ p95: rank(0.95),
82
+ max: n === 0 ? 0 : sorted[0].durationMs,
83
+ mean: n === 0 ? 0 : used / n,
84
+ },
85
+ budgetUsedMs: used,
86
+ exemplars: {
87
+ slowest: refs(() => true),
88
+ timeout: refs((row) => row.outcome === 'timeout'),
89
+ failed: refs((row) => row.outcome === 'failed' || row.outcome === 'aborted'),
90
+ unknown: refs((row) => row.effect === 'unknown'),
91
+ gaveUp: refs((row) => stopped.has(row)),
92
+ },
93
+ };
94
+ }
95
+ export function aggregateAttempts(rows, exemplars, storage) {
96
+ // Append stores may contain multiple lifecycle versions; the last row is the recorded current fact.
97
+ const unique = new Map(rows.map((row) => [attemptRowKey(row), row]));
98
+ const all = [...unique.values()];
99
+ const decisions = new Map();
100
+ const physical = new Map(all
101
+ .filter((row) => row.kind === 'attempt')
102
+ .map((row) => [JSON.stringify([row.runId, row.id]), row]));
103
+ let unsupported = 0;
104
+ const grouped = new Map();
105
+ for (const row of all)
106
+ if (row.kind === 'decision') {
107
+ const source = physical.get(JSON.stringify([row.runId, row.attemptId]));
108
+ const loop = source?.retryLoop;
109
+ if (source === undefined ||
110
+ source.target !== row.target ||
111
+ loop?.phase !== 'attempt' ||
112
+ loop.id !== row.id ||
113
+ loop.series !== row.series ||
114
+ loop.attempt !== row.attempt ||
115
+ loop.of !== row.of) {
116
+ unsupported++;
117
+ continue;
118
+ }
119
+ decisions.set(logicalKey(row.runId, row.series, row.attempt), row);
120
+ }
121
+ for (const row of all)
122
+ if (row.kind === 'attempt') {
123
+ const bucket = grouped.get(row.target) ?? [];
124
+ bucket.push(row);
125
+ grouped.set(row.target, bucket);
126
+ }
127
+ const byTarget = new Map([...grouped].map(([target, entries]) => [target, summarized(target, entries, decisions, exemplars)]));
128
+ const runs = new Map();
129
+ for (const row of all) {
130
+ const bucket = runs.get(row.runId) ?? [];
131
+ bucket.push(row);
132
+ runs.set(row.runId, bucket);
133
+ }
134
+ const byRun = new Map();
135
+ for (const [runId, own] of runs) {
136
+ const attempts = own.filter((row) => row.kind === 'attempt');
137
+ const perTarget = new Map();
138
+ for (const row of attempts) {
139
+ const bucket = perTarget.get(row.target) ?? [];
140
+ bucket.push(row);
141
+ perTarget.set(row.target, bucket);
142
+ }
143
+ const stats = [...perTarget].map(([target, entries]) => summarized(target, entries, decisions, 0));
144
+ const run = own.find((row) => row.kind === 'run');
145
+ byRun.set(runId, {
146
+ runId,
147
+ attempts: attempts.length,
148
+ retries: stats.reduce((n, s) => n + s.retries, 0),
149
+ gaveUp: stats.reduce((n, s) => n + s.gaveUp, 0),
150
+ budgetUsedMs: stats.reduce((n, s) => n + s.budgetUsedMs, 0),
151
+ exemplars: worst(attempts, exemplars),
152
+ outcome: run?.kind === 'run' ? run.outcome : 'incomplete',
153
+ });
154
+ }
155
+ return {
156
+ byTarget,
157
+ byRun,
158
+ storage: {
159
+ ...storage,
160
+ omittedRows: storage.omittedRows + unsupported,
161
+ incomplete: storage.incomplete || unsupported > 0,
162
+ },
163
+ };
164
+ }
165
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW1wdE1ldHJpY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlY29yZGVyL2F0dGVtcHRNZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVdBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QyxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsQ0FBQyxHQUFlLEVBQVUsRUFBRSxDQUN2RCxJQUFJLENBQUMsU0FBUyxDQUNaLEdBQUcsQ0FBQyxJQUFJLEtBQUssU0FBUztJQUNwQixDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQztJQUMvQixDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksS0FBSyxVQUFVO1FBQ3pCLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUM7UUFDaEQsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLENBQzFCLENBQUM7QUFDSixNQUFNLENBQUMsTUFBTSxVQUFVLEdBQUcsQ0FBQyxLQUFhLEVBQUUsTUFBYyxFQUFFLE9BQWUsRUFBVSxFQUFFLENBQ25GLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDM0MsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLENBQUMsS0FBYSxFQUFFLE1BQWMsRUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0FBQ3BHLE1BQU0sVUFBVSxTQUFTLENBQUMsR0FBdUI7SUFDL0MsTUFBTSxFQUNKLEVBQUUsRUFDRixN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QUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1lBQy9DLFlBQVksRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQzNELFNBQVMsRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQztZQUNyQyxPQUFPLEVBQUUsR0FBRyxFQUFFLElBQUksS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLFlBQVk7U0FDMUQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU87UUFDTCxRQUFRO1FBQ1IsS0FBSztRQUNMLE9BQU8sRUFBRTtZQUNQLEdBQUcsT0FBTztZQUNWLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxHQUFHLFdBQVc7WUFDOUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVLElBQUksV0FBVyxHQUFHLENBQUM7U0FDbEQ7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKiBBZ2dyZWdhdGUgcmVjb3JkZWQgZmFjdHM7IG5vIGV4ZWN1dGlvbi10cmVlIHdhbGsgYW5kIG5vIHJlY29uc3RydWN0aW9uIG9mIGxvZ2ljYWwgcmV0cmllcyBmcm9tIGV2ZW50IGNvdW50cy4gKi9cbmltcG9ydCB0eXBlIHsgQXR0ZW1wdFJlYXNvbiB9IGZyb20gJy4uL2F0dGVtcHQvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1xuICBBdHRlbXB0QWdncmVnYXRlLFxuICBBdHRlbXB0RGVjaXNpb25Sb3csXG4gIEF0dGVtcHRNZXRyaWNSZWYsXG4gIEF0dGVtcHRSb3csXG4gIEF0dGVtcHRTdGF0cyxcbiAgQXR0ZW1wdFN0b3JhZ2VTdGF0cyxcbiAgUGh5c2ljYWxBdHRlbXB0Um93LFxufSBmcm9tICcuL2F0dGVtcHRNZXRyaWNzVHlwZXMuanMnO1xuaW1wb3J0IHsgZ2F2ZVVwIH0gZnJvbSAnLi9hdHRlbXB0U2VyaWVzLmpzJztcblxuZXhwb3J0IGNvbnN0IGF0dGVtcHRSb3dLZXkgPSAocm93OiBBdHRlbXB0Um93KTogc3RyaW5nID0+XG4gIEpTT04uc3RyaW5naWZ5KFxuICAgIHJvdy5raW5kID09PSAnYXR0ZW1wdCdcbiAgICAgID8gW3Jvdy5raW5kLCByb3cucnVuSWQsIHJvdy5pZF1cbiAgICAgIDogcm93LmtpbmQgPT09ICdkZWNpc2lvbidcbiAgICAgID8gW3Jvdy5raW5kLCByb3cucnVuSWQsIHJvdy5zZXJpZXMsIHJvdy5hdHRlbXB0XVxuICAgICAgOiBbcm93LmtpbmQsIHJvdy5ydW5JZF0sXG4gICk7XG5leHBvcnQgY29uc3QgbG9naWNhbEtleSA9IChydW5JZDogc3RyaW5nLCBzZXJpZXM6IHN0cmluZywgYXR0ZW1wdDogbnVtYmVyKTogc3RyaW5nID0+XG4gIEpTT04uc3RyaW5naWZ5KFtydW5JZCwgc2VyaWVzLCBhdHRlbXB0XSk7XG5leHBvcnQgY29uc3Qgc2VyaWVzS2V5ID0gKHJ1bklkOiBzdHJpbmcsIHNlcmllczogc3RyaW5nKTogc3RyaW5nID0+IEpTT04uc3RyaW5naWZ5KFtydW5JZCwgc2VyaWVzXSk7XG5leHBvcnQgZnVuY3Rpb24gcmVmZXJlbmNlKHJvdzogUGh5c2ljYWxBdHRlbXB0Um93KTogQXR0ZW1wdE1ldHJpY1JlZiB7XG4gIGNvbnN0IHtcbiAgICBpZCxcbiAgICBzZXJpZXMsXG4gICAgcnVuSWQsXG4gICAgcnVudGltZVN0YWdlSWQsXG4gICAgYXR0ZW1wdEtpbmQsXG4gICAgdGFyZ2V0LFxuICAgIHRyYWNlSWQsXG4gICAgc3RhcnRlZEF0LFxuICAgIGR1cmF0aW9uTXMsXG4gICAgb3V0Y29tZSxcbiAgICBjYXRlZ29yeSxcbiAgICBuZXh0LFxuICAgIHJlYXNvbixcbiAgICByZXRyeUxvb3AsXG4gIH0gPSByb3c7XG4gIHJldHVybiB7XG4gICAgaWQsXG4gICAgc2VyaWVzLFxuICAgIHJ1bklkLFxuICAgIHJ1bnRpbWVTdGFnZUlkLFxuICAgIGF0dGVtcHRLaW5kLFxuICAgIHRhcmdldCxcbiAgICAuLi4odHJhY2VJZCA9PT0gdW5kZWZpbmVkID8ge30gOiB7IHRyYWNlSWQgfSksXG4gICAgc3RhcnRlZEF0LFxuICAgIGR1cmF0aW9uTXMsXG4gICAgb3V0Y29tZSxcbiAgICAuLi4oY2F0ZWdvcnkgPT09IHVuZGVmaW5lZCA/IHt9IDogeyBjYXRlZ29yeSB9KSxcbiAgICBuZXh0LFxuICAgIHJlYXNvbixcbiAgICAuLi4ocmV0cnlMb29wID09PSB1bmRlZmluZWQgPyB7fSA6IHsgcmV0cnlMb29wOiB7IC4uLnJldHJ5TG9vcCB9IH0pLFxuICB9O1xufVxuY29uc3Qgb3JkZXIgPSAoYTogUGh5c2ljYWxBdHRlbXB0Um93LCBiOiBQaHlzaWNhbEF0dGVtcHRSb3cpID0+XG4gIGIuZHVyYXRpb25NcyAtIGEuZHVyYXRpb25NcyB8fCBiLnN0YXJ0ZWRBdCAtIGEuc3RhcnRlZEF0IHx8IGEuaWQubG9jYWxlQ29tcGFyZShiLmlkKTtcbmV4cG9ydCBmdW5jdGlvbiB3b3JzdChyb3dzOiByZWFkb25seSBQaHlzaWNhbEF0dGVtcHRSb3dbXSwgbGltaXQ6IG51bWJlcik6IEF0dGVtcHRNZXRyaWNSZWZbXSB7XG4gIHJldHVybiBbLi4ucm93c10uc29ydChvcmRlcikuc2xpY2UoMCwgbGltaXQpLm1hcChyZWZlcmVuY2UpO1xufVxuZnVuY3Rpb24gc3VtbWFyaXplZChcbiAgdGFyZ2V0OiBzdHJpbmcsXG4gIHJvd3M6IHJlYWRvbmx5IFBoeXNpY2FsQXR0ZW1wdFJvd1tdLFxuICBkZWNpc2lvbnM6IE1hcDxzdHJpbmcsIEF0dGVtcHREZWNpc2lvblJvdz4sXG4gIGV4ZW1wbGFyczogbnVtYmVyLFxuKTogQXR0ZW1wdFN0YXRzIHtcbiAgY29uc3QgYnlLaW5kID0geyBzdGFnZTogMCwgY2FsbDogMCwgb2JzZXJ2ZWQ6IDAgfTtcbiAgY29uc3QgYnlPdXRjb21lID0geyBvazogMCwgZmFpbGVkOiAwLCB0aW1lb3V0OiAwLCBhYm9ydGVkOiAwLCBwYXVzZWQ6IDAgfTtcbiAgY29uc3QgYnlDYXRlZ29yeSA9IHsgdGltZW91dDogMCwgJ3JhdGUtbGltaXRlZCc6IDAsIHNlcnZlcjogMCwgbmV0d29yazogMCwgYXV0aDogMCwgcGVybWFuZW50OiAwLCB1bmtub3duOiAwIH07XG4gIGxldCByZXRyaWVzID0gMDtcbiAgY29uc3QgcmV0cmllZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCBnYXZlID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IHN0b3BwZWQgPSBuZXcgU2V0PFBoeXNpY2FsQXR0ZW1wdFJvdz4oKTtcbiAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgIGJ5S2luZFtyb3cuYXR0ZW1wdEtpbmRdKys7XG4gICAgYnlPdXRjb21lW3Jvdy5vdXRjb21lXSsrO1xuICAgIGlmIChyb3cuY2F0ZWdvcnkgIT09IHVuZGVmaW5lZCkgYnlDYXRlZ29yeVtyb3cuY2F0ZWdvcnldKys7XG4gICAgLy8gQSByZWNvbmNpbGlhdGlvbiB3aXJlIGNhbGwgaXMgd29yaywgYnV0IGl0cyBvbmUtY2FsbCBzdG9wIGlzIG5vdCBhIGxvZ2ljYWwgd29ya2Zsb3cgZ2l2ZS11cC5cbiAgICBpZiAocm93LnJldHJ5TG9vcD8ucGhhc2UgPT09ICdyZWNvbmNpbGUnKSBjb250aW51ZTtcbiAgICBjb25zdCBsb2dpY2FsID0gcm93LnJldHJ5TG9vcDtcbiAgICBjb25zdCBkZWNpc2lvbiA9XG4gICAgICBsb2dpY2FsID09PSB1bmRlZmluZWQgPyByb3cgOiBkZWNpc2lvbnMuZ2V0KGxvZ2ljYWxLZXkocm93LnJ1bklkLCBsb2dpY2FsLnNlcmllcywgbG9naWNhbC5hdHRlbXB0KSk7XG4gICAgaWYgKFxuICAgICAgZGVjaXNpb24gPT09IHVuZGVmaW5lZCB8fFxuICAgICAgKGxvZ2ljYWwgIT09IHVuZGVmaW5lZCAmJiAoZGVjaXNpb24ua2luZCAhPT0gJ2RlY2lzaW9uJyB8fCBkZWNpc2lvbi5hdHRlbXB0SWQgIT09IHJvdy5pZCkpXG4gICAgKVxuICAgICAgY29udGludWU7IC8vIEEgbG9naWNhbCB2ZXJkaWN0IGJlbG9uZ3Mgb25seSB0byB0aGUgZXhhY3QgcGh5c2ljYWwgYXR0ZW1wdCBpdCBjaXRlcy5cbiAgICBjb25zdCBrZXkgPSBzZXJpZXNLZXkocm93LnJ1bklkLCBsb2dpY2FsPy5zZXJpZXMgPz8gcm93LnNlcmllcyk7XG4gICAgaWYgKGRlY2lzaW9uLm5leHQgPT09ICdyZXRyeScpIHtcbiAgICAgIHJldHJpZXMrKztcbiAgICAgIHJldHJpZWQuYWRkKGtleSk7XG4gICAgfVxuICAgIGlmIChnYXZlVXAoeyBuZXh0OiBkZWNpc2lvbi5uZXh0LCByZWFzb246IGRlY2lzaW9uLnJlYXNvbiBhcyBBdHRlbXB0UmVhc29uIH0pKSB7XG4gICAgICBnYXZlLmFkZChrZXkpO1xuICAgICAgc3RvcHBlZC5hZGQocm93KTtcbiAgICB9XG4gIH1cbiAgY29uc3Qgc29ydGVkID0gWy4uLnJvd3NdLnNvcnQob3JkZXIpO1xuICBjb25zdCBuID0gc29ydGVkLmxlbmd0aDtcbiAgY29uc3QgcmFuayA9IChwOiBudW1iZXIpID0+IChuID09PSAwID8gMCA6IHNvcnRlZFtuIC0gTWF0aC5jZWlsKG4gKiBwKV0uZHVyYXRpb25Ncyk7XG4gIGNvbnN0IHJlZnMgPSAoaW5jbHVkZTogKHJvdzogUGh5c2ljYWxBdHRlbXB0Um93KSA9PiBib29sZWFuKSA9PlxuICAgIHNvcnRlZC5maWx0ZXIoaW5jbHVkZSkuc2xpY2UoMCwgZXhlbXBsYXJzKS5tYXAocmVmZXJlbmNlKTtcbiAgY29uc3QgdXNlZCA9IHJvd3MucmVkdWNlKChuLCByb3cpID0+IG4gKyByb3cuZHVyYXRpb25NcywgMCk7XG4gIHJldHVybiB7XG4gICAgdGFyZ2V0LFxuICAgIGNvdW50OiBuLFxuICAgIGJ5S2luZCxcbiAgICBieU91dGNvbWUsXG4gICAgYnlDYXRlZ29yeSxcbiAgICByZXRyaWVzLFxuICAgIHNlcmllc1JldHJpZWQ6IHJldHJpZWQuc2l6ZSxcbiAgICBnYXZlVXA6IGdhdmUuc2l6ZSxcbiAgICBlZmZlY3RVbmtub3duOiByb3dzLmZpbHRlcigocm93KSA9PiByb3cuZWZmZWN0ID09PSAndW5rbm93bicpLmxlbmd0aCxcbiAgICBsYXRlbmN5TXM6IHtcbiAgICAgIHA1MDogcmFuaygwLjUpLFxuICAgICAgcDkwOiByYW5rKDAuOSksXG4gICAgICBwOTU6IHJhbmsoMC45NSksXG4gICAgICBtYXg6IG4gPT09IDAgPyAwIDogc29ydGVkWzBdLmR1cmF0aW9uTXMsXG4gICAgICBtZWFuOiBuID09PSAwID8gMCA6IHVzZWQgLyBuLFxuICAgIH0sXG4gICAgYnVkZ2V0VXNlZE1zOiB1c2VkLFxuICAgIGV4ZW1wbGFyczoge1xuICAgICAgc2xvd2VzdDogcmVmcygoKSA9PiB0cnVlKSxcbiAgICAgIHRpbWVvdXQ6IHJlZnMoKHJvdykgPT4gcm93Lm91dGNvbWUgPT09ICd0aW1lb3V0JyksXG4gICAgICBmYWlsZWQ6IHJlZnMoKHJvdykgPT4gcm93Lm91dGNvbWUgPT09ICdmYWlsZWQnIHx8IHJvdy5vdXRjb21lID09PSAnYWJvcnRlZCcpLFxuICAgICAgdW5rbm93bjogcmVmcygocm93KSA9PiByb3cuZWZmZWN0ID09PSAndW5rbm93bicpLFxuICAgICAgZ2F2ZVVwOiByZWZzKChyb3cpID0+IHN0b3BwZWQuaGFzKHJvdykpLFxuICAgIH0sXG4gIH07XG59XG5leHBvcnQgZnVuY3Rpb24gYWdncmVnYXRlQXR0ZW1wdHMoXG4gIHJvd3M6IHJlYWRvbmx5IEF0dGVtcHRSb3dbXSxcbiAgZXhlbXBsYXJzOiBudW1iZXIsXG4gIHN0b3JhZ2U6IEF0dGVtcHRTdG9yYWdlU3RhdHMsXG4pOiBBdHRlbXB0QWdncmVnYXRlIHtcbiAgLy8gQXBwZW5kIHN0b3JlcyBtYXkgY29udGFpbiBtdWx0aXBsZSBsaWZlY3ljbGUgdmVyc2lvbnM7IHRoZSBsYXN0IHJvdyBpcyB0aGUgcmVjb3JkZWQgY3VycmVudCBmYWN0LlxuICBjb25zdCB1bmlxdWUgPSBuZXcgTWFwKHJvd3MubWFwKChyb3cpID0+IFthdHRlbXB0Um93S2V5KHJvdyksIHJvd10pKTtcbiAgY29uc3QgYWxsID0gWy4uLnVuaXF1ZS52YWx1ZXMoKV07XG4gIGNvbnN0IGRlY2lzaW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBBdHRlbXB0RGVjaXNpb25Sb3c+KCk7XG4gIGNvbnN0IHBoeXNpY2FsID0gbmV3IE1hcChcbiAgICBhbGxcbiAgICAgIC5maWx0ZXIoKHJvdyk6IHJvdyBpcyBQaHlzaWNhbEF0dGVtcHRSb3cgPT4gcm93LmtpbmQgPT09ICdhdHRlbXB0JylcbiAgICAgIC5tYXAoKHJvdykgPT4gW0pTT04uc3RyaW5naWZ5KFtyb3cucnVuSWQsIHJvdy5pZF0pLCByb3ddKSxcbiAgKTtcbiAgbGV0IHVuc3VwcG9ydGVkID0gMDtcbiAgY29uc3QgZ3JvdXBlZCA9IG5ldyBNYXA8c3RyaW5nLCBQaHlzaWNhbEF0dGVtcHRSb3dbXT4oKTtcbiAgZm9yIChjb25zdCByb3cgb2YgYWxsKVxuICAgIGlmIChyb3cua2luZCA9PT0gJ2RlY2lzaW9uJykge1xuICAgICAgY29uc3Qgc291cmNlID0gcGh5c2ljYWwuZ2V0KEpTT04uc3RyaW5naWZ5KFtyb3cucnVuSWQsIHJvdy5hdHRlbXB0SWRdKSk7XG4gICAgICBjb25zdCBsb29wID0gc291cmNlPy5yZXRyeUxvb3A7XG4gICAgICBpZiAoXG4gICAgICAgIHNvdXJjZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgIHNvdXJjZS50YXJnZXQgIT09IHJvdy50YXJnZXQgfHxcbiAgICAgICAgbG9vcD8ucGhhc2UgIT09ICdhdHRlbXB0JyB8fFxuICAgICAgICBsb29wLmlkICE9PSByb3cuaWQgfHxcbiAgICAgICAgbG9vcC5zZXJpZXMgIT09IHJvdy5zZXJpZXMgfHxcbiAgICAgICAgbG9vcC5hdHRlbXB0ICE9PSByb3cuYXR0ZW1wdCB8fFxuICAgICAgICBsb29wLm9mICE9PSByb3cub2ZcbiAgICAgICkge1xuICAgICAgICB1bnN1cHBvcnRlZCsrO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGRlY2lzaW9ucy5zZXQobG9naWNhbEtleShyb3cucnVuSWQsIHJvdy5zZXJpZXMsIHJvdy5hdHRlbXB0KSwgcm93KTtcbiAgICB9XG4gIGZvciAoY29uc3Qgcm93IG9mIGFsbClcbiAgICBpZiAocm93LmtpbmQgPT09ICdhdHRlbXB0Jykge1xuICAgICAgY29uc3QgYnVja2V0ID0gZ3JvdXBlZC5nZXQocm93LnRhcmdldCkgPz8gW107XG4gICAgICBidWNrZXQucHVzaChyb3cpO1xuICAgICAgZ3JvdXBlZC5zZXQocm93LnRhcmdldCwgYnVja2V0KTtcbiAgICB9XG4gIGNvbnN0IGJ5VGFyZ2V0ID0gbmV3IE1hcChcbiAgICBbLi4uZ3JvdXBlZF0ubWFwKChbdGFyZ2V0LCBlbnRyaWVzXSkgPT4gW3RhcmdldCwgc3VtbWFyaXplZCh0YXJnZXQsIGVudHJpZXMsIGRlY2lzaW9ucywgZXhlbXBsYXJzKV0pLFxuICApO1xuICBjb25zdCBydW5zID0gbmV3IE1hcDxzdHJpbmcsIEF0dGVtcHRSb3dbXT4oKTtcbiAgZm9yIChjb25zdCByb3cgb2YgYWxsKSB7XG4gICAgY29uc3QgYnVja2V0ID0gcnVucy5nZXQocm93LnJ1bklkKSA/PyBbXTtcbiAgICBidWNrZXQucHVzaChyb3cpO1xuICAgIHJ1bnMuc2V0KHJvdy5ydW5JZCwgYnVja2V0KTtcbiAgfVxuICBjb25zdCBieVJ1bjogQXR0ZW1wdEFnZ3JlZ2F0ZVsnYnlSdW4nXSA9IG5ldyBNYXAoKTtcbiAgZm9yIChjb25zdCBbcnVuSWQsIG93bl0gb2YgcnVucykge1xuICAgIGNvbnN0IGF0dGVtcHRzID0gb3duLmZpbHRlcigocm93KTogcm93IGlzIFBoeXNpY2FsQXR0ZW1wdFJvdyA9PiByb3cua2luZCA9PT0gJ2F0dGVtcHQnKTtcbiAgICBjb25zdCBwZXJUYXJnZXQgPSBuZXcgTWFwPHN0cmluZywgUGh5c2ljYWxBdHRlbXB0Um93W10+KCk7XG4gICAgZm9yIChjb25zdCByb3cgb2YgYXR0ZW1wdHMpIHtcbiAgICAgIGNvbnN0IGJ1Y2tldCA9IHBlclRhcmdldC5nZXQocm93LnRhcmdldCkgPz8gW107XG4gICAgICBidWNrZXQucHVzaChyb3cpO1xuICAgICAgcGVyVGFyZ2V0LnNldChyb3cudGFyZ2V0LCBidWNrZXQpO1xuICAgIH1cbiAgICBjb25zdCBzdGF0cyA9IFsuLi5wZXJUYXJnZXRdLm1hcCgoW3RhcmdldCwgZW50cmllc10pID0+IHN1bW1hcml6ZWQodGFyZ2V0LCBlbnRyaWVzLCBkZWNpc2lvbnMsIDApKTtcbiAgICBjb25zdCBydW4gPSBvd24uZmluZCgocm93KSA9PiByb3cua2luZCA9PT0gJ3J1bicpO1xuICAgIGJ5UnVuLnNldChydW5JZCwge1xuICAgICAgcnVuSWQsXG4gICAgICBhdHRlbXB0czogYXR0ZW1wdHMubGVuZ3RoLFxuICAgICAgcmV0cmllczogc3RhdHMucmVkdWNlKChuLCBzKSA9PiBuICsgcy5yZXRyaWVzLCAwKSxcbiAgICAgIGdhdmVVcDogc3RhdHMucmVkdWNlKChuLCBzKSA9PiBuICsgcy5nYXZlVXAsIDApLFxuICAgICAgYnVkZ2V0VXNlZE1zOiBzdGF0cy5yZWR1Y2UoKG4sIHMpID0+IG4gKyBzLmJ1ZGdldFVzZWRNcywgMCksXG4gICAgICBleGVtcGxhcnM6IHdvcnN0KGF0dGVtcHRzLCBleGVtcGxhcnMpLFxuICAgICAgb3V0Y29tZTogcnVuPy5raW5kID09PSAncnVuJyA/IHJ1bi5vdXRjb21lIDogJ2luY29tcGxldGUnLFxuICAgIH0pO1xuICB9XG4gIHJldHVybiB7XG4gICAgYnlUYXJnZXQsXG4gICAgYnlSdW4sXG4gICAgc3RvcmFnZToge1xuICAgICAgLi4uc3RvcmFnZSxcbiAgICAgIG9taXR0ZWRSb3dzOiBzdG9yYWdlLm9taXR0ZWRSb3dzICsgdW5zdXBwb3J0ZWQsXG4gICAgICBpbmNvbXBsZXRlOiBzdG9yYWdlLmluY29tcGxldGUgfHwgdW5zdXBwb3J0ZWQgPiAwLFxuICAgIH0sXG4gIH07XG59XG4iXX0=
@@ -0,0 +1,114 @@
1
+ /** Payload-free P7 rows and public metric projections. Store adapters receive named facts, never errors or keys. */
2
+ import type { AttemptId } from 'foottrace';
3
+ import type { RetryLoopCall, RetryLoopDecision } from '../attempt/retryLoopTypes.js';
4
+ import type { AttemptCategory, AttemptEffect, AttemptKind, AttemptNext, AttemptOutcome, AttemptReason } from '../attempt/types.js';
5
+ export interface AttemptMetricRef {
6
+ readonly id: AttemptId;
7
+ readonly series: string;
8
+ readonly runId: string;
9
+ readonly runtimeStageId: string;
10
+ readonly attemptKind: AttemptKind;
11
+ readonly retryLoop?: RetryLoopCall;
12
+ readonly target: string;
13
+ readonly traceId?: string;
14
+ readonly startedAt: number;
15
+ readonly durationMs: number;
16
+ readonly outcome: AttemptOutcome;
17
+ readonly category?: AttemptCategory;
18
+ readonly next: AttemptNext;
19
+ readonly reason: AttemptReason;
20
+ }
21
+ export interface PhysicalAttemptRow extends AttemptMetricRef {
22
+ readonly kind: 'attempt';
23
+ readonly attemptKind: AttemptKind;
24
+ readonly attempt: number;
25
+ readonly of?: number;
26
+ readonly effect?: AttemptEffect;
27
+ readonly retryLoop?: RetryLoopCall;
28
+ }
29
+ export interface AttemptDecisionRow extends RetryLoopDecision {
30
+ readonly kind: 'decision';
31
+ readonly runId: string;
32
+ readonly target: string;
33
+ readonly runtimeStageId: string;
34
+ readonly attemptId: AttemptId;
35
+ readonly startedAt: number;
36
+ }
37
+ export interface AttemptRunRow {
38
+ readonly kind: 'run';
39
+ readonly runId: string;
40
+ readonly startedAt: number;
41
+ readonly endedAt?: number;
42
+ readonly outcome: 'running' | 'ok' | 'failed' | 'paused';
43
+ }
44
+ export type AttemptRow = PhysicalAttemptRow | AttemptDecisionRow | AttemptRunRow;
45
+ export interface AttemptQuery {
46
+ readonly since?: number;
47
+ readonly until?: number;
48
+ readonly target?: string;
49
+ readonly runId?: string;
50
+ }
51
+ export interface AttemptStore {
52
+ append(rows: readonly AttemptRow[]): void | Promise<void>;
53
+ read(query: AttemptQuery): Promise<readonly AttemptRow[]>;
54
+ /** Optional known retention accounting; omitted evidence must not appear complete. */
55
+ stats?(): {
56
+ readonly omittedRows: number;
57
+ };
58
+ }
59
+ export interface AttemptStorageStats {
60
+ readonly pending: number;
61
+ readonly failed: number;
62
+ readonly dropped: number;
63
+ readonly omittedRows: number;
64
+ readonly incomplete: boolean;
65
+ }
66
+ export interface AttemptStats {
67
+ readonly target: string;
68
+ readonly count: number;
69
+ readonly byKind: Record<AttemptKind, number>;
70
+ readonly byOutcome: Record<AttemptOutcome, number>;
71
+ readonly byCategory: Record<AttemptCategory, number>;
72
+ readonly retries: number;
73
+ readonly seriesRetried: number;
74
+ readonly gaveUp: number;
75
+ readonly effectUnknown: number;
76
+ readonly latencyMs: {
77
+ readonly p50: number;
78
+ readonly p90: number;
79
+ readonly p95: number;
80
+ readonly max: number;
81
+ readonly mean: number;
82
+ };
83
+ /** Sum of attempt durations (work time), which can overlap or nest; not elapsed run time. */
84
+ readonly budgetUsedMs: number;
85
+ readonly exemplars: {
86
+ readonly slowest: AttemptMetricRef[];
87
+ readonly timeout: AttemptMetricRef[];
88
+ readonly failed: AttemptMetricRef[];
89
+ readonly unknown: AttemptMetricRef[];
90
+ readonly gaveUp: AttemptMetricRef[];
91
+ };
92
+ }
93
+ export interface AttemptRunStats {
94
+ readonly runId: string;
95
+ readonly attempts: number;
96
+ readonly retries: number;
97
+ readonly gaveUp: number;
98
+ readonly budgetUsedMs: number;
99
+ readonly budgetMs?: number;
100
+ readonly exemplars: AttemptMetricRef[];
101
+ readonly outcome: AttemptRunRow['outcome'] | 'incomplete';
102
+ }
103
+ export interface AttemptAggregate {
104
+ readonly byTarget: Map<string, AttemptStats>;
105
+ readonly byRun: Map<string, AttemptRunStats>;
106
+ readonly storage: AttemptStorageStats;
107
+ }
108
+ export interface AttemptRecorderOptions {
109
+ readonly exemplars?: number;
110
+ readonly maxRows?: number;
111
+ readonly maxPending?: number;
112
+ readonly storeTimeoutMs?: number;
113
+ readonly store?: AttemptStore;
114
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW1wdE1ldHJpY3NUeXBlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcmVjb3JkZXIvYXR0ZW1wdE1ldHJpY3NUeXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIFBheWxvYWQtZnJlZSBQNyByb3dzIGFuZCBwdWJsaWMgbWV0cmljIHByb2plY3Rpb25zLiBTdG9yZSBhZGFwdGVycyByZWNlaXZlIG5hbWVkIGZhY3RzLCBuZXZlciBlcnJvcnMgb3Iga2V5cy4gKi9cbmltcG9ydCB0eXBlIHsgQXR0ZW1wdElkIH0gZnJvbSAnZm9vdHRyYWNlJztcblxuaW1wb3J0IHR5cGUgeyBSZXRyeUxvb3BDYWxsLCBSZXRyeUxvb3BEZWNpc2lvbiB9IGZyb20gJy4uL2F0dGVtcHQvcmV0cnlMb29wVHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1xuICBBdHRlbXB0Q2F0ZWdvcnksXG4gIEF0dGVtcHRFZmZlY3QsXG4gIEF0dGVtcHRLaW5kLFxuICBBdHRlbXB0TmV4dCxcbiAgQXR0ZW1wdE91dGNvbWUsXG4gIEF0dGVtcHRSZWFzb24sXG59IGZyb20gJy4uL2F0dGVtcHQvdHlwZXMuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF0dGVtcHRNZXRyaWNSZWYge1xuICByZWFkb25seSBpZDogQXR0ZW1wdElkO1xuICByZWFkb25seSBzZXJpZXM6IHN0cmluZztcbiAgcmVhZG9ubHkgcnVuSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgcnVudGltZVN0YWdlSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgYXR0ZW1wdEtpbmQ6IEF0dGVtcHRLaW5kO1xuICByZWFkb25seSByZXRyeUxvb3A/OiBSZXRyeUxvb3BDYWxsO1xuICByZWFkb25seSB0YXJnZXQ6IHN0cmluZztcbiAgcmVhZG9ubHkgdHJhY2VJZD86IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhcnRlZEF0OiBudW1iZXI7XG4gIHJlYWRvbmx5IGR1cmF0aW9uTXM6IG51bWJlcjtcbiAgcmVhZG9ubHkgb3V0Y29tZTogQXR0ZW1wdE91dGNvbWU7XG4gIHJlYWRvbmx5IGNhdGVnb3J5PzogQXR0ZW1wdENhdGVnb3J5O1xuICByZWFkb25seSBuZXh0OiBBdHRlbXB0TmV4dDtcbiAgcmVhZG9ubHkgcmVhc29uOiBBdHRlbXB0UmVhc29uO1xufVxuZXhwb3J0IGludGVyZmFjZSBQaHlzaWNhbEF0dGVtcHRSb3cgZXh0ZW5kcyBBdHRlbXB0TWV0cmljUmVmIHtcbiAgcmVhZG9ubHkga2luZDogJ2F0dGVtcHQnO1xuICByZWFkb25seSBhdHRlbXB0S2luZDogQXR0ZW1wdEtpbmQ7XG4gIHJlYWRvbmx5IGF0dGVtcHQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgb2Y/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGVmZmVjdD86IEF0dGVtcHRFZmZlY3Q7XG4gIHJlYWRvbmx5IHJldHJ5TG9vcD86IFJldHJ5TG9vcENhbGw7XG59XG5leHBvcnQgaW50ZXJmYWNlIEF0dGVtcHREZWNpc2lvblJvdyBleHRlbmRzIFJldHJ5TG9vcERlY2lzaW9uIHtcbiAgcmVhZG9ubHkga2luZDogJ2RlY2lzaW9uJztcbiAgcmVhZG9ubHkgcnVuSWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgdGFyZ2V0OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJ1bnRpbWVTdGFnZUlkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGF0dGVtcHRJZDogQXR0ZW1wdElkO1xuICByZWFkb25seSBzdGFydGVkQXQ6IG51bWJlcjtcbn1cbmV4cG9ydCBpbnRlcmZhY2UgQXR0ZW1wdFJ1blJvdyB7XG4gIHJlYWRvbmx5IGtpbmQ6ICdydW4nO1xuICByZWFkb25seSBydW5JZDogc3RyaW5nO1xuICByZWFkb25seSBzdGFydGVkQXQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgZW5kZWRBdD86IG51bWJlcjtcbiAgcmVhZG9ubHkgb3V0Y29tZTogJ3J1bm5pbmcnIHwgJ29rJyB8ICdmYWlsZWQnIHwgJ3BhdXNlZCc7XG59XG5leHBvcnQgdHlwZSBBdHRlbXB0Um93ID0gUGh5c2ljYWxBdHRlbXB0Um93IHwgQXR0ZW1wdERlY2lzaW9uUm93IHwgQXR0ZW1wdFJ1blJvdztcbmV4cG9ydCBpbnRlcmZhY2UgQXR0ZW1wdFF1ZXJ5IHtcbiAgcmVhZG9ubHkgc2luY2U/OiBudW1iZXI7XG4gIHJlYWRvbmx5IHVudGlsPzogbnVtYmVyO1xuICByZWFkb25seSB0YXJnZXQ/OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJ1bklkPzogc3RyaW5nO1xufVxuZXhwb3J0IGludGVyZmFjZSBBdHRlbXB0U3RvcmUge1xuICBhcHBlbmQocm93czogcmVhZG9ubHkgQXR0ZW1wdFJvd1tdKTogdm9pZCB8IFByb21pc2U8dm9pZD47XG4gIHJlYWQocXVlcnk6IEF0dGVtcHRRdWVyeSk6IFByb21pc2U8cmVhZG9ubHkgQXR0ZW1wdFJvd1tdPjtcbiAgLyoqIE9wdGlvbmFsIGtub3duIHJldGVudGlvbiBhY2NvdW50aW5nOyBvbWl0dGVkIGV2aWRlbmNlIG11c3Qgbm90IGFwcGVhciBjb21wbGV0ZS4gKi9cbiAgc3RhdHM/KCk6IHsgcmVhZG9ubHkgb21pdHRlZFJvd3M6IG51bWJlciB9O1xufVxuZXhwb3J0IGludGVyZmFjZSBBdHRlbXB0U3RvcmFnZVN0YXRzIHtcbiAgcmVhZG9ubHkgcGVuZGluZzogbnVtYmVyO1xuICByZWFkb25seSBmYWlsZWQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgZHJvcHBlZDogbnVtYmVyO1xuICByZWFkb25seSBvbWl0dGVkUm93czogbnVtYmVyO1xuICByZWFkb25seSBpbmNvbXBsZXRlOiBib29sZWFuO1xufVxuZXhwb3J0IGludGVyZmFjZSBBdHRlbXB0U3RhdHMge1xuICByZWFkb25seSB0YXJnZXQ6IHN0cmluZztcbiAgcmVhZG9ubHkgY291bnQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgYnlLaW5kOiBSZWNvcmQ8QXR0ZW1wdEtpbmQsIG51bWJlcj47XG4gIHJlYWRvbmx5IGJ5T3V0Y29tZTogUmVjb3JkPEF0dGVtcHRPdXRjb21lLCBudW1iZXI+O1xuICByZWFkb25seSBieUNhdGVnb3J5OiBSZWNvcmQ8QXR0ZW1wdENhdGVnb3J5LCBudW1iZXI+O1xuICByZWFkb25seSByZXRyaWVzOiBudW1iZXI7XG4gIHJlYWRvbmx5IHNlcmllc1JldHJpZWQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgZ2F2ZVVwOiBudW1iZXI7XG4gIHJlYWRvbmx5IGVmZmVjdFVua25vd246IG51bWJlcjtcbiAgcmVhZG9ubHkgbGF0ZW5jeU1zOiB7XG4gICAgcmVhZG9ubHkgcDUwOiBudW1iZXI7XG4gICAgcmVhZG9ubHkgcDkwOiBudW1iZXI7XG4gICAgcmVhZG9ubHkgcDk1OiBudW1iZXI7XG4gICAgcmVhZG9ubHkgbWF4OiBudW1iZXI7XG4gICAgcmVhZG9ubHkgbWVhbjogbnVtYmVyO1xuICB9O1xuICAvKiogU3VtIG9mIGF0dGVtcHQgZHVyYXRpb25zICh3b3JrIHRpbWUpLCB3aGljaCBjYW4gb3ZlcmxhcCBvciBuZXN0OyBub3QgZWxhcHNlZCBydW4gdGltZS4gKi9cbiAgcmVhZG9ubHkgYnVkZ2V0VXNlZE1zOiBudW1iZXI7XG4gIHJlYWRvbmx5IGV4ZW1wbGFyczoge1xuICAgIHJlYWRvbmx5IHNsb3dlc3Q6IEF0dGVtcHRNZXRyaWNSZWZbXTtcbiAgICByZWFkb25seSB0aW1lb3V0OiBBdHRlbXB0TWV0cmljUmVmW107XG4gICAgcmVhZG9ubHkgZmFpbGVkOiBBdHRlbXB0TWV0cmljUmVmW107XG4gICAgcmVhZG9ubHkgdW5rbm93bjogQXR0ZW1wdE1ldHJpY1JlZltdO1xuICAgIHJlYWRvbmx5IGdhdmVVcDogQXR0ZW1wdE1ldHJpY1JlZltdO1xuICB9O1xufVxuZXhwb3J0IGludGVyZmFjZSBBdHRlbXB0UnVuU3RhdHMge1xuICByZWFkb25seSBydW5JZDogc3RyaW5nO1xuICByZWFkb25seSBhdHRlbXB0czogbnVtYmVyO1xuICByZWFkb25seSByZXRyaWVzOiBudW1iZXI7XG4gIHJlYWRvbmx5IGdhdmVVcDogbnVtYmVyO1xuICByZWFkb25seSBidWRnZXRVc2VkTXM6IG51bWJlcjtcbiAgcmVhZG9ubHkgYnVkZ2V0TXM/OiBudW1iZXI7XG4gIHJlYWRvbmx5IGV4ZW1wbGFyczogQXR0ZW1wdE1ldHJpY1JlZltdO1xuICByZWFkb25seSBvdXRjb21lOiBBdHRlbXB0UnVuUm93WydvdXRjb21lJ10gfCAnaW5jb21wbGV0ZSc7XG59XG5leHBvcnQgaW50ZXJmYWNlIEF0dGVtcHRBZ2dyZWdhdGUge1xuICByZWFkb25seSBieVRhcmdldDogTWFwPHN0cmluZywgQXR0ZW1wdFN0YXRzPjtcbiAgcmVhZG9ubHkgYnlSdW46IE1hcDxzdHJpbmcsIEF0dGVtcHRSdW5TdGF0cz47XG4gIHJlYWRvbmx5IHN0b3JhZ2U6IEF0dGVtcHRTdG9yYWdlU3RhdHM7XG59XG5leHBvcnQgaW50ZXJmYWNlIEF0dGVtcHRSZWNvcmRlck9wdGlvbnMge1xuICByZWFkb25seSBleGVtcGxhcnM/OiBudW1iZXI7XG4gIHJlYWRvbmx5IG1heFJvd3M/OiBudW1iZXI7XG4gIHJlYWRvbmx5IG1heFBlbmRpbmc/OiBudW1iZXI7XG4gIHJlYWRvbmx5IHN0b3JlVGltZW91dE1zPzogbnVtYmVyO1xuICByZWFkb25seSBzdG9yZT86IEF0dGVtcHRTdG9yZTtcbn1cbiJdfQ==
@@ -0,0 +1,78 @@
1
+ import type { AttemptStats, PhysicalAttemptRow } from './attemptMetricsTypes.js';
2
+ export declare function attemptOTel(rows: readonly PhysicalAttemptRow[], byTarget: ReadonlyMap<string, AttemptStats>, limit: number): {
3
+ resourceMetrics: {
4
+ resource: {
5
+ attributes: never[];
6
+ };
7
+ scopeMetrics: {
8
+ scope: {
9
+ name: string;
10
+ };
11
+ metrics: ({
12
+ name: string;
13
+ unit: string;
14
+ description: string;
15
+ histogram: {
16
+ aggregationTemporality: number;
17
+ dataPoints: {
18
+ attributes: {
19
+ key: string;
20
+ value: {
21
+ stringValue: string;
22
+ };
23
+ }[];
24
+ startTimeUnixNano: string;
25
+ timeUnixNano: string;
26
+ count: string;
27
+ sum: number;
28
+ explicitBounds: number[];
29
+ bucketCounts: string[];
30
+ exemplars: {
31
+ traceId?: string | undefined;
32
+ asDouble: number;
33
+ timeUnixNano: string;
34
+ filteredAttributes: {
35
+ key: string;
36
+ value: {
37
+ stringValue: string;
38
+ };
39
+ }[];
40
+ }[];
41
+ }[];
42
+ };
43
+ sum?: undefined;
44
+ } | {
45
+ name: string;
46
+ unit: string;
47
+ sum: {
48
+ aggregationTemporality: number;
49
+ isMonotonic: boolean;
50
+ dataPoints: {
51
+ attributes: {
52
+ key: string;
53
+ value: {
54
+ stringValue: string;
55
+ };
56
+ }[];
57
+ startTimeUnixNano: string;
58
+ timeUnixNano: string;
59
+ asDouble: number;
60
+ exemplars: {
61
+ asDouble: number;
62
+ traceId?: string | undefined;
63
+ timeUnixNano: string;
64
+ filteredAttributes: {
65
+ key: string;
66
+ value: {
67
+ stringValue: string;
68
+ };
69
+ }[];
70
+ }[];
71
+ }[];
72
+ };
73
+ description?: undefined;
74
+ histogram?: undefined;
75
+ })[];
76
+ }[];
77
+ }[];
78
+ };
@@ -0,0 +1,107 @@
1
+ /** OTLP JSON metrics: exact histogram bucket counts and real bounded physical-attempt exemplars. */
2
+ import { worst } from './attemptMetrics.js';
3
+ const BOUNDS = [1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000];
4
+ const attribute = (key, value) => ({ key, value: { stringValue: value } });
5
+ const nano = (ms) => (BigInt(Math.trunc(ms)) * 1000000n).toString();
6
+ function exemplars(refs, value = 'duration') {
7
+ return refs.map((ref) => ({
8
+ asDouble: value === 'count' ? 1 : ref.durationMs,
9
+ timeUnixNano: nano(ref.startedAt),
10
+ filteredAttributes: [
11
+ attribute('footprint.attempt.kind', ref.attemptKind),
12
+ attribute('footprint.attempt.id', ref.id),
13
+ attribute('footprint.runtime_stage_id', ref.runtimeStageId),
14
+ attribute('footprint.series', ref.series),
15
+ attribute('footprint.run_id', ref.runId),
16
+ ...(ref.traceId === undefined ? [] : [attribute('footprint.trace_id', ref.traceId)]),
17
+ ...(ref.retryLoop === undefined
18
+ ? []
19
+ : [
20
+ attribute('footprint.retry_loop.series', ref.retryLoop.series),
21
+ attribute('footprint.retry_loop.phase', ref.retryLoop.phase),
22
+ ]),
23
+ ],
24
+ ...(/^[a-f0-9]{32}$/.test(ref.traceId ?? '') && !/^0+$/.test(ref.traceId ?? '') ? { traceId: ref.traceId } : {}),
25
+ }));
26
+ }
27
+ export function attemptOTel(rows, byTarget, limit) {
28
+ const grouped = new Map();
29
+ for (const row of rows) {
30
+ const key = JSON.stringify([row.target, row.outcome, row.category ?? null, row.attemptKind]);
31
+ const bucket = grouped.get(key) ?? [];
32
+ bucket.push(row);
33
+ grouped.set(key, bucket);
34
+ }
35
+ const histograms = [...grouped.values()].map((group) => {
36
+ const first = group[0];
37
+ const buckets = Array(BOUNDS.length + 1).fill(0);
38
+ for (const row of group) {
39
+ const at = BOUNDS.findIndex((bound) => row.durationMs <= bound);
40
+ buckets[at < 0 ? BOUNDS.length : at]++;
41
+ }
42
+ return {
43
+ attributes: [
44
+ attribute('footprint.target', first.target),
45
+ attribute('footprint.outcome', first.outcome),
46
+ attribute('footprint.attempt.kind', first.attemptKind),
47
+ ...(first.category === undefined ? [] : [attribute('footprint.category', first.category)]),
48
+ ],
49
+ startTimeUnixNano: nano(group.reduce((n, row) => Math.min(n, row.startedAt), Infinity)),
50
+ timeUnixNano: nano(group.reduce((n, row) => Math.max(n, row.startedAt + row.durationMs), 0)),
51
+ count: String(group.length),
52
+ sum: group.reduce((n, row) => n + row.durationMs, 0),
53
+ explicitBounds: [...BOUNDS],
54
+ bucketCounts: buckets.map(String),
55
+ exemplars: exemplars(worst(group, limit)),
56
+ };
57
+ });
58
+ const counts = histograms.map(({ attributes, startTimeUnixNano, timeUnixNano, count, exemplars: refs }) => ({
59
+ attributes,
60
+ startTimeUnixNano,
61
+ timeUnixNano,
62
+ asDouble: Number(count),
63
+ exemplars: refs.map((ref) => ({ ...ref, asDouble: 1 })),
64
+ }));
65
+ const gave = [...byTarget.values()]
66
+ .filter((stat) => stat.gaveUp > 0)
67
+ .map((stat) => ({
68
+ attributes: [attribute('footprint.target', stat.target)],
69
+ asDouble: stat.gaveUp,
70
+ startTimeUnixNano: nano(rows.filter((row) => row.target === stat.target).reduce((n, row) => Math.min(n, row.startedAt), Infinity)),
71
+ timeUnixNano: nano(rows
72
+ .filter((row) => row.target === stat.target)
73
+ .reduce((n, row) => Math.max(n, row.startedAt + row.durationMs), 0)),
74
+ exemplars: exemplars(stat.exemplars.gaveUp, 'count'),
75
+ }));
76
+ return {
77
+ resourceMetrics: [
78
+ {
79
+ resource: { attributes: [] },
80
+ scopeMetrics: [
81
+ {
82
+ scope: { name: 'footprintjs.attempts' },
83
+ metrics: [
84
+ {
85
+ name: 'footprint.attempt.duration',
86
+ unit: 'ms',
87
+ description: 'Attempt work duration; nested attempts may overlap',
88
+ histogram: { aggregationTemporality: 2, dataPoints: histograms },
89
+ },
90
+ {
91
+ name: 'footprint.attempt.count',
92
+ unit: '{attempt}',
93
+ sum: { aggregationTemporality: 2, isMonotonic: true, dataPoints: counts },
94
+ },
95
+ {
96
+ name: 'footprint.attempt.gave_up',
97
+ unit: '{series}',
98
+ sum: { aggregationTemporality: 2, isMonotonic: true, dataPoints: gave },
99
+ },
100
+ ],
101
+ },
102
+ ],
103
+ },
104
+ ],
105
+ };
106
+ }
107
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0ZW1wdE9UZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlY29yZGVyL2F0dGVtcHRPVGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9HQUFvRztBQUNwRyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFNUMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzFFLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBVyxFQUFFLEtBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQzNGLE1BQU0sSUFBSSxHQUFHLENBQUMsRUFBVSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDNUUsU0FBUyxTQUFTLENBQUMsSUFBaUMsRUFBRSxRQUE4QixVQUFVO0lBQzVGLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN4QixRQUFRLEVBQUUsS0FBSyxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsVUFBVTtRQUNoRCxZQUFZLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7UUFDakMsa0JBQWtCLEVBQUU7WUFDbEIsU0FBUyxDQUFDLHdCQUF3QixFQUFFLEdBQUcsQ0FBQyxXQUFXLENBQUM7WUFDcEQs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SlNPTiBtZXRyaWNzOiBleGFjdCBoaXN0b2dyYW0gYnVja2V0IGNvdW50cyBhbmQgcmVhbCBib3VuZGVkIHBoeXNpY2FsLWF0dGVtcHQgZXhlbXBsYXJzLiAqL1xuaW1wb3J0IHsgd29yc3QgfSBmcm9tICcuL2F0dGVtcHRNZXRyaWNzLmpzJztcbmltcG9ydCB0eXBlIHsgQXR0ZW1wdE1ldHJpY1JlZiwgQXR0ZW1wdFN0YXRzLCBQaHlzaWNhbEF0dGVtcHRSb3cgfSBmcm9tICcuL2F0dGVtcHRNZXRyaWNzVHlwZXMuanMnO1xuY29uc3QgQk9VTkRTID0gWzEsIDUsIDEwLCAyNSwgNTAsIDEwMCwgMjUwLCA1MDAsIDEwMDAsIDI1MDAsIDUwMDAsIDEwMDAwXTtcbmNvbnN0IGF0dHJpYnV0ZSA9IChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZykgPT4gKHsga2V5LCB2YWx1ZTogeyBzdHJpbmdWYWx1ZTogdmFsdWUgfSB9KTtcbmNvbnN0IG5hbm8gPSAobXM6IG51bWJlcikgPT4gKEJpZ0ludChNYXRoLnRydW5jKG1zKSkgKiAxMDAwMDAwbikudG9TdHJpbmcoKTtcbmZ1bmN0aW9uIGV4ZW1wbGFycyhyZWZzOiByZWFkb25seSBBdHRlbXB0TWV0cmljUmVmW10sIHZhbHVlOiAnZHVyYXRpb24nIHwgJ2NvdW50JyA9ICdkdXJhdGlvbicpIHtcbiAgcmV0dXJuIHJlZnMubWFwKChyZWYpID0+ICh7XG4gICAgYXNEb3VibGU6IHZhbHVlID09PSAnY291bnQnID8gMSA6IHJlZi5kdXJhdGlvbk1zLFxuICAgIHRpbWVVbml4TmFubzogbmFubyhyZWYuc3RhcnRlZEF0KSxcbiAgICBmaWx0ZXJlZEF0dHJpYnV0ZXM6IFtcbiAgICAgIGF0dHJpYnV0ZSgnZm9vdHByaW50LmF0dGVtcHQua2luZCcsIHJlZi5hdHRlbXB0S2luZCksXG4gICAgICBhdHRyaWJ1dGUoJ2Zvb3RwcmludC5hdHRlbXB0LmlkJywgcmVmLmlkKSxcbiAgICAgIGF0dHJpYnV0ZSgnZm9vdHByaW50LnJ1bnRpbWVfc3RhZ2VfaWQnLCByZWYucnVudGltZVN0YWdlSWQpLFxuICAgICAgYXR0cmlidXRlKCdmb290cHJpbnQuc2VyaWVzJywgcmVmLnNlcmllcyksXG4gICAgICBhdHRyaWJ1dGUoJ2Zvb3RwcmludC5ydW5faWQnLCByZWYucnVuSWQpLFxuICAgICAgLi4uKHJlZi50cmFjZUlkID09PSB1bmRlZmluZWQgPyBbXSA6IFthdHRyaWJ1dGUoJ2Zvb3RwcmludC50cmFjZV9pZCcsIHJlZi50cmFjZUlkKV0pLFxuICAgICAgLi4uKHJlZi5yZXRyeUxvb3AgPT09IHVuZGVmaW5lZFxuICAgICAgICA/IFtdXG4gICAgICAgIDogW1xuICAgICAgICAgICAgYXR0cmlidXRlKCdmb290cHJpbnQucmV0cnlfbG9vcC5zZXJpZXMnLCByZWYucmV0cnlMb29wLnNlcmllcyksXG4gICAgICAgICAgICBhdHRyaWJ1dGUoJ2Zvb3RwcmludC5yZXRyeV9sb29wLnBoYXNlJywgcmVmLnJldHJ5TG9vcC5waGFzZSksXG4gICAgICAgICAgXSksXG4gICAgXSxcbiAgICAuLi4oL15bYS1mMC05XXszMn0kLy50ZXN0KHJlZi50cmFjZUlkID8/ICcnKSAmJiAhL14wKyQvLnRlc3QocmVmLnRyYWNlSWQgPz8gJycpID8geyB0cmFjZUlkOiByZWYudHJhY2VJZCB9IDoge30pLFxuICB9KSk7XG59XG5leHBvcnQgZnVuY3Rpb24gYXR0ZW1wdE9UZWwoXG4gIHJvd3M6IHJlYWRvbmx5IFBoeXNpY2FsQXR0ZW1wdFJvd1tdLFxuICBieVRhcmdldDogUmVhZG9ubHlNYXA8c3RyaW5nLCBBdHRlbXB0U3RhdHM+LFxuICBsaW1pdDogbnVtYmVyLFxuKSB7XG4gIGNvbnN0IGdyb3VwZWQgPSBuZXcgTWFwPHN0cmluZywgUGh5c2ljYWxBdHRlbXB0Um93W10+KCk7XG4gIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShbcm93LnRhcmdldCwgcm93Lm91dGNvbWUsIHJvdy5jYXRlZ29yeSA/PyBudWxsLCByb3cuYXR0ZW1wdEtpbmRdKTtcbiAgICBjb25zdCBidWNrZXQgPSBncm91cGVkLmdldChrZXkpID8/IFtdO1xuICAgIGJ1Y2tldC5wdXNoKHJvdyk7XG4gICAgZ3JvdXBlZC5zZXQoa2V5LCBidWNrZXQpO1xuICB9XG4gIGNvbnN0IGhpc3RvZ3JhbXMgPSBbLi4uZ3JvdXBlZC52YWx1ZXMoKV0ubWFwKChncm91cCkgPT4ge1xuICAgIGNvbnN0IGZpcnN0ID0gZ3JvdXBbMF07XG4gICAgY29uc3QgYnVja2V0cyA9IEFycmF5KEJPVU5EUy5sZW5ndGggKyAxKS5maWxsKDApIGFzIG51bWJlcltdO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIGdyb3VwKSB7XG4gICAgICBjb25zdCBhdCA9IEJPVU5EUy5maW5kSW5kZXgoKGJvdW5kKSA9PiByb3cuZHVyYXRpb25NcyA8PSBib3VuZCk7XG4gICAgICBidWNrZXRzW2F0IDwgMCA/IEJPVU5EUy5sZW5ndGggOiBhdF0rKztcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGF0dHJpYnV0ZXM6IFtcbiAgICAgICAgYXR0cmlidXRlKCdmb290cHJpbnQudGFyZ2V0JywgZmlyc3QudGFyZ2V0KSxcbiAgICAgICAgYXR0cmlidXRlKCdmb290cHJpbnQub3V0Y29tZScsIGZpcnN0Lm91dGNvbWUpLFxuICAgICAgICBhdHRyaWJ1dGUoJ2Zvb3RwcmludC5hdHRlbXB0LmtpbmQnLCBmaXJzdC5hdHRlbXB0S2luZCksXG4gICAgICAgIC4uLihmaXJzdC5jYXRlZ29yeSA9PT0gdW5kZWZpbmVkID8gW10gOiBbYXR0cmlidXRlKCdmb290cHJpbnQuY2F0ZWdvcnknLCBmaXJzdC5jYXRlZ29yeSldKSxcbiAgICAgIF0sXG4gICAgICBzdGFydFRpbWVVbml4TmFubzogbmFubyhncm91cC5yZWR1Y2UoKG4sIHJvdykgPT4gTWF0aC5taW4obiwgcm93LnN0YXJ0ZWRBdCksIEluZmluaXR5KSksXG4gICAgICB0aW1lVW5peE5hbm86IG5hbm8oZ3JvdXAucmVkdWNlKChuLCByb3cpID0+IE1hdGgubWF4KG4sIHJvdy5zdGFydGVkQXQgKyByb3cuZHVyYXRpb25NcyksIDApKSxcbiAgICAgIGNvdW50OiBTdHJpbmcoZ3JvdXAubGVuZ3RoKSxcbiAgICAgIHN1bTogZ3JvdXAucmVkdWNlKChuLCByb3cpID0+IG4gKyByb3cuZHVyYXRpb25NcywgMCksXG4gICAgICBleHBsaWNpdEJvdW5kczogWy4uLkJPVU5EU10sXG4gICAgICBidWNrZXRDb3VudHM6IGJ1Y2tldHMubWFwKFN0cmluZyksXG4gICAgICBleGVtcGxhcnM6IGV4ZW1wbGFycyh3b3JzdChncm91cCwgbGltaXQpKSxcbiAgICB9O1xuICB9KTtcbiAgY29uc3QgY291bnRzID0gaGlzdG9ncmFtcy5tYXAoKHsgYXR0cmlidXRlcywgc3RhcnRUaW1lVW5peE5hbm8sIHRpbWVVbml4TmFubywgY291bnQsIGV4ZW1wbGFyczogcmVmcyB9KSA9PiAoe1xuICAgIGF0dHJpYnV0ZXMsXG4gICAgc3RhcnRUaW1lVW5peE5hbm8sXG4gICAgdGltZVVuaXhOYW5vLFxuICAgIGFzRG91YmxlOiBOdW1iZXIoY291bnQpLFxuICAgIGV4ZW1wbGFyczogcmVmcy5tYXAoKHJlZikgPT4gKHsgLi4ucmVmLCBhc0RvdWJsZTogMSB9KSksXG4gIH0pKTtcbiAgY29uc3QgZ2F2ZSA9IFsuLi5ieVRhcmdldC52YWx1ZXMoKV1cbiAgICAuZmlsdGVyKChzdGF0KSA9PiBzdGF0LmdhdmVVcCA+IDApXG4gICAgLm1hcCgoc3RhdCkgPT4gKHtcbiAgICAgIGF0dHJpYnV0ZXM6IFthdHRyaWJ1dGUoJ2Zvb3RwcmludC50YXJnZXQnLCBzdGF0LnRhcmdldCldLFxuICAgICAgYXNEb3VibGU6IHN0YXQuZ2F2ZVVwLFxuICAgICAgc3RhcnRUaW1lVW5peE5hbm86IG5hbm8oXG4gICAgICAgIHJvd3MuZmlsdGVyKChyb3cpID0+IHJvdy50YXJnZXQgPT09IHN0YXQudGFyZ2V0KS5yZWR1Y2UoKG4sIHJvdykgPT4gTWF0aC5taW4obiwgcm93LnN0YXJ0ZWRBdCksIEluZmluaXR5KSxcbiAgICAgICksXG4gICAgICB0aW1lVW5peE5hbm86IG5hbm8oXG4gICAgICAgIHJvd3NcbiAgICAgICAgICAuZmlsdGVyKChyb3cpID0+IHJvdy50YXJnZXQgPT09IHN0YXQudGFyZ2V0KVxuICAgICAgICAgIC5yZWR1Y2UoKG4sIHJvdykgPT4gTWF0aC5tYXgobiwgcm93LnN0YXJ0ZWRBdCArIHJvdy5kdXJhdGlvbk1zKSwgMCksXG4gICAgICApLFxuICAgICAgZXhlbXBsYXJzOiBleGVtcGxhcnMoc3RhdC5leGVtcGxhcnMuZ2F2ZVVwLCAnY291bnQnKSxcbiAgICB9KSk7XG4gIHJldHVybiB7XG4gICAgcmVzb3VyY2VNZXRyaWNzOiBbXG4gICAgICB7XG4gICAgICAgIHJlc291cmNlOiB7IGF0dHJpYnV0ZXM6IFtdIH0sXG4gICAgICAgIHNjb3BlTWV0cmljczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHNjb3BlOiB7IG5hbWU6ICdmb290cHJpbnRqcy5hdHRlbXB0cycgfSxcbiAgICAgICAgICAgIG1ldHJpY3M6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG5hbWU6ICdmb290cHJpbnQuYXR0ZW1wdC5kdXJhdGlvbicsXG4gICAgICAgICAgICAgICAgdW5pdDogJ21zJyxcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0F0dGVtcHQgd29yayBkdXJhdGlvbjsgbmVzdGVkIGF0dGVtcHRzIG1heSBvdmVybGFwJyxcbiAgICAgICAgICAgICAgICBoaXN0b2dyYW06IHsgYWdncmVnYXRpb25UZW1wb3JhbGl0eTogMiwgZGF0YVBvaW50czogaGlzdG9ncmFtcyB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbmFtZTogJ2Zvb3RwcmludC5hdHRlbXB0LmNvdW50JyxcbiAgICAgICAgICAgICAgICB1bml0OiAne2F0dGVtcHR9JyxcbiAgICAgICAgICAgICAgICBzdW06IHsgYWdncmVnYXRpb25UZW1wb3JhbGl0eTogMiwgaXNNb25vdG9uaWM6IHRydWUsIGRhdGFQb2ludHM6IGNvdW50cyB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbmFtZTogJ2Zvb3RwcmludC5hdHRlbXB0LmdhdmVfdXAnLFxuICAgICAgICAgICAgICAgIHVuaXQ6ICd7c2VyaWVzfScsXG4gICAgICAgICAgICAgICAgc3VtOiB7IGFnZ3JlZ2F0aW9uVGVtcG9yYWxpdHk6IDIsIGlzTW9ub3RvbmljOiB0cnVlLCBkYXRhUG9pbnRzOiBnYXZlIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIF0sXG4gIH07XG59XG4iXX0=
@@ -0,0 +1,81 @@
1
+ /**
2
+ * recorder/attemptSeries.ts — what a RECORDER keeps of a series: the one evidence predicate, the stop that gave up, and a
3
+ * per-series tally rebuilt from `onAttempt` records (design §5.1, P1c).
4
+ *
5
+ * WHY one module: seven built-in recorders account for attempts, and each must agree on two questions — "is this
6
+ * series worth a row?" and "did it give up?" — or a Topology node and a boundary count would disagree about the
7
+ * same run. Asked here, once.
8
+ *
9
+ * THE predicate (`isRetryEvidence`): a series is evidence when it RETRIED (some attempt was followed by another),
10
+ * GAVE UP while a retry was possible (it stopped `exhausted`, `declined` or `no-time-left` with `of > 1`, §3.9), or
11
+ * TIMED OUT (an attempt ran out of its cap or the deadline — P1b's lone timeout is the incident's own shape). A
12
+ * policy stage that succeeded first time — or that paused or was aborted on its first attempt — is
13
+ * indistinguishable from a stage with no policy in every recorder row, so a chart in which nothing retried keeps
14
+ * those rows byte-identical (law 2). So is a LONE attempt (`of: 1`, recorded for every stage of a run with a
15
+ * deadline, P1b) that merely failed: a stage error like any other, so a deadline alone never multiplies rows.
16
+ *
17
+ * Records arrive in order within a series, so the predicate is decided at the series' FIRST record: attempt 1 is
18
+ * evidence iff it did not end the series quietly, and every later attempt is evidence by being one.
19
+ *
20
+ * L5 (`recorder/**`), beside the stores: it imports the attempt vocabulary's types only (the L0 leaf), so
21
+ * `recorder/` never takes a runtime edge into `attempt/` — whose runner reaches `decide/` and `scope/`, which
22
+ * import `recorder/` (a module cycle).
23
+ */
24
+ import type { AttemptOutcome, AttemptRecord, AttemptSummary } from '../attempt/types.js';
25
+ /**
26
+ * One attempt, named — `series` (the stage execution's `runtimeStageId`) plus the 1-based `attempt`. The
27
+ * identity `AttemptRecord` carries until the engine stamps foottrace's attempt id (design §3.4).
28
+ */
29
+ export interface AttemptRef {
30
+ readonly series: string;
31
+ readonly attempt: number;
32
+ }
33
+ /** Attempt counts per outcome — the shape `AttemptSummary` uses, without the series' end. */
34
+ export type AttemptOutcomeCounts = Readonly<Record<AttemptOutcome, number>>;
35
+ /** The series stopped on this record because retrying was given up (exhausted, declined or no time left). */
36
+ export declare function gaveUp(record: Pick<AttemptRecord, 'next' | 'reason'>): boolean;
37
+ /**
38
+ * The record belongs to a STAGE's series that retried, gave up or timed out — the one row predicate every recorder
39
+ * shares. A call's or an observed attempt (`scope.$call`, `observed()`, P2) is never a row here: these recorders keep
40
+ * one row per stage execution, and a call is counted per TARGET (the `attempts()` recorder, P7) — drawn as a stage's
41
+ * retry it would say the stage retried when only its call did.
42
+ */
43
+ export declare function isRetryEvidence(record: AttemptRecord): boolean;
44
+ /** Did the attempt itself fail — a failure, a timeout or the run's abort (not a success, not a pause)? */
45
+ export declare function attemptFailed(record: AttemptRecord): boolean;
46
+ /** The record's name. */
47
+ export declare function attemptRef(record: AttemptRecord): AttemptRef;
48
+ /**
49
+ * The path-prefixed id of the subflow an attempt's stage ran in (`'sf-outer/sf-inner'`), or `undefined` at the top
50
+ * level — read off the stage execution's `runtimeStageId` (the event's, else the series'), the one id that always
51
+ * carries it.
52
+ */
53
+ export declare function subflowOfAttempt(event: {
54
+ readonly record: AttemptRecord;
55
+ readonly traversalContext?: {
56
+ readonly runtimeStageId: string;
57
+ };
58
+ }): string | undefined;
59
+ /** A zeroed per-outcome count. */
60
+ export declare function emptyOutcomeCounts(): Record<AttemptOutcome, number>;
61
+ /** What a recorder knows of one series so far. `summary` is present once the series ended. */
62
+ export interface AttemptSeriesState {
63
+ readonly series: string;
64
+ /** The series' attempts, in order. */
65
+ readonly attempts: readonly AttemptRef[];
66
+ /**
67
+ * The series at a glance — the same value the runner stamps on `StageSnapshot.attemptSummary`, rebuilt from the
68
+ * records. Absent while the last record says `retry`: the series is in flight, or the run's signal cut its wait
69
+ * (no record follows; only the execution tree knows how it ended).
70
+ */
71
+ readonly summary?: AttemptSummary;
72
+ }
73
+ /**
74
+ * Per-series tallies, keyed by `series`, for the series that are evidence. `add` returns the series' state after
75
+ * the record, or `undefined` for a record that is not evidence (nothing to keep).
76
+ */
77
+ export declare class AttemptSeriesBook {
78
+ private readonly bySeries;
79
+ add(record: AttemptRecord): AttemptSeriesState | undefined;
80
+ clear(): void;
81
+ }