@graphrefly/graphrefly 0.47.2 → 0.48.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 (266) hide show
  1. package/dist/base/composition/index.cjs +4 -3
  2. package/dist/base/composition/index.cjs.map +1 -1
  3. package/dist/base/composition/index.d.cts +14 -5
  4. package/dist/base/composition/index.d.ts +14 -5
  5. package/dist/base/composition/index.js +8 -8
  6. package/dist/base/index.cjs +152 -78
  7. package/dist/base/index.cjs.map +1 -1
  8. package/dist/base/index.d.cts +2 -2
  9. package/dist/base/index.d.ts +2 -2
  10. package/dist/base/index.js +75 -70
  11. package/dist/base/io/index.cjs +31 -17
  12. package/dist/base/io/index.cjs.map +1 -1
  13. package/dist/base/io/index.d.cts +32 -5
  14. package/dist/base/io/index.d.ts +32 -5
  15. package/dist/base/io/index.js +1 -1
  16. package/dist/base/mutation/index.cjs +21 -0
  17. package/dist/base/mutation/index.cjs.map +1 -1
  18. package/dist/base/mutation/index.d.cts +23 -1
  19. package/dist/base/mutation/index.d.ts +23 -1
  20. package/dist/base/mutation/index.js +3 -1
  21. package/dist/base/sources/browser/index.cjs +5 -3
  22. package/dist/base/sources/browser/index.cjs.map +1 -1
  23. package/dist/base/sources/browser/index.d.cts +20 -2
  24. package/dist/base/sources/browser/index.d.ts +20 -2
  25. package/dist/base/sources/browser/index.js +5 -3
  26. package/dist/base/sources/browser/index.js.map +1 -1
  27. package/dist/base/sources/event/index.cjs +28 -0
  28. package/dist/base/sources/event/index.cjs.map +1 -1
  29. package/dist/base/sources/event/index.d.cts +67 -3
  30. package/dist/base/sources/event/index.d.ts +67 -3
  31. package/dist/base/sources/event/index.js +4 -1
  32. package/dist/base/sources/index.cjs +75 -37
  33. package/dist/base/sources/index.cjs.map +1 -1
  34. package/dist/base/sources/index.d.cts +1 -1
  35. package/dist/base/sources/index.d.ts +1 -1
  36. package/dist/base/sources/index.js +5 -2
  37. package/dist/{chunk-R6ZCSXKX.js → chunk-23MAWVOJ.js} +3 -3
  38. package/dist/{chunk-MS3WPRJR.js → chunk-3REMCHSS.js} +6 -6
  39. package/dist/chunk-3REMCHSS.js.map +1 -0
  40. package/dist/{chunk-CEVNQ74M.js → chunk-3YGXPUHW.js} +2 -2
  41. package/dist/{chunk-CEVNQ74M.js.map → chunk-3YGXPUHW.js.map} +1 -1
  42. package/dist/{chunk-6ZLCPUXS.js → chunk-46X2EFQH.js} +15 -4
  43. package/dist/chunk-46X2EFQH.js.map +1 -0
  44. package/dist/{chunk-NY2PYHNC.js → chunk-5UY3PNFY.js} +12 -5
  45. package/dist/chunk-5UY3PNFY.js.map +1 -0
  46. package/dist/{chunk-FQSQONOU.js → chunk-65OM4XLQ.js} +49 -3
  47. package/dist/chunk-65OM4XLQ.js.map +1 -0
  48. package/dist/{chunk-3PSLNJDU.js → chunk-6DQYBIHW.js} +314 -49
  49. package/dist/chunk-6DQYBIHW.js.map +1 -0
  50. package/dist/{chunk-LDCSZ72P.js → chunk-6YBER5UP.js} +3 -3
  51. package/dist/{chunk-LDCSZ72P.js.map → chunk-6YBER5UP.js.map} +1 -1
  52. package/dist/{chunk-3O3NKZJW.js → chunk-7T7WLEPM.js} +24 -3
  53. package/dist/chunk-7T7WLEPM.js.map +1 -0
  54. package/dist/{chunk-PKPO3JTZ.js → chunk-AQAKDE7F.js} +29 -11
  55. package/dist/chunk-AQAKDE7F.js.map +1 -0
  56. package/dist/{chunk-6MRSX3YK.js → chunk-B5Y5GPD5.js} +2 -2
  57. package/dist/{chunk-BXGZFGZ4.js → chunk-C5QD5DQX.js} +22 -1
  58. package/dist/chunk-C5QD5DQX.js.map +1 -0
  59. package/dist/{chunk-4XCHZRUJ.js → chunk-D5YGR4TP.js} +58 -7
  60. package/dist/chunk-D5YGR4TP.js.map +1 -0
  61. package/dist/{chunk-NPRP3MCV.js → chunk-DHDCOOJU.js} +2 -2
  62. package/dist/chunk-DHDCOOJU.js.map +1 -0
  63. package/dist/{chunk-VP3TIUDF.js → chunk-DVTDF5OI.js} +2 -2
  64. package/dist/{chunk-OXD5LFQP.js → chunk-G7H6PN7P.js} +2 -2
  65. package/dist/{chunk-EL5VHUGK.js → chunk-GGKHHG5Y.js} +32 -18
  66. package/dist/chunk-GGKHHG5Y.js.map +1 -0
  67. package/dist/{chunk-446I4EGD.js → chunk-J5TBZFBD.js} +2 -2
  68. package/dist/{chunk-7AVQIGF6.js → chunk-K4ZYJ4EM.js} +554 -460
  69. package/dist/chunk-K4ZYJ4EM.js.map +1 -0
  70. package/dist/{chunk-QFE5BQH7.js → chunk-LTSI7ULC.js} +2 -2
  71. package/dist/{chunk-5GVURVIG.js → chunk-MMHGYX44.js} +12 -2
  72. package/dist/{chunk-5GVURVIG.js.map → chunk-MMHGYX44.js.map} +1 -1
  73. package/dist/{chunk-KRFGO5QH.js → chunk-MQMTRKY3.js} +118 -43
  74. package/dist/chunk-MQMTRKY3.js.map +1 -0
  75. package/dist/{chunk-42FQ27MQ.js → chunk-MTODGQBR.js} +44 -179
  76. package/dist/chunk-MTODGQBR.js.map +1 -0
  77. package/dist/{chunk-FVINAAKA.js → chunk-NBK6QQMG.js} +14 -13
  78. package/dist/{chunk-FVINAAKA.js.map → chunk-NBK6QQMG.js.map} +1 -1
  79. package/dist/{chunk-KNU73RZW.js → chunk-NSA5K5G2.js} +2 -2
  80. package/dist/{chunk-MLTPJMH6.js → chunk-QQYULEZL.js} +2 -2
  81. package/dist/chunk-QSW4DFKE.js +31 -0
  82. package/dist/chunk-QSW4DFKE.js.map +1 -0
  83. package/dist/{chunk-VAZXUK6G.js → chunk-SUNCHMML.js} +2 -2
  84. package/dist/{chunk-EP4WVQLX.js → chunk-T2U6N3FV.js} +6 -6
  85. package/dist/{chunk-T7SP3EYR.js → chunk-T5URUIIY.js} +33 -24
  86. package/dist/chunk-T5URUIIY.js.map +1 -0
  87. package/dist/{chunk-VNXAF2KE.js → chunk-TPTZZV25.js} +6 -6
  88. package/dist/chunk-TPTZZV25.js.map +1 -0
  89. package/dist/{chunk-IOJDYUA7.js → chunk-V46JWFGV.js} +6 -5
  90. package/dist/chunk-V46JWFGV.js.map +1 -0
  91. package/dist/{chunk-WGDEBIP4.js → chunk-X6ESZDR6.js} +5 -6
  92. package/dist/chunk-X6ESZDR6.js.map +1 -0
  93. package/dist/{chunk-N65E26UL.js → chunk-XEWV254I.js} +2 -2
  94. package/dist/{chunk-N65E26UL.js.map → chunk-XEWV254I.js.map} +1 -1
  95. package/dist/{chunk-PTWADEH3.js → chunk-YBJVKMTM.js} +34 -14
  96. package/dist/chunk-YBJVKMTM.js.map +1 -0
  97. package/dist/{chunk-DDTS7F5O.js → chunk-ZW32BPXV.js} +12 -3
  98. package/dist/chunk-ZW32BPXV.js.map +1 -0
  99. package/dist/compat/index.cjs +51 -4
  100. package/dist/compat/index.cjs.map +1 -1
  101. package/dist/compat/index.d.cts +1 -1
  102. package/dist/compat/index.d.ts +1 -1
  103. package/dist/compat/index.js +6 -6
  104. package/dist/compat/nestjs/index.cjs +51 -4
  105. package/dist/compat/nestjs/index.cjs.map +1 -1
  106. package/dist/compat/nestjs/index.d.cts +1 -1
  107. package/dist/compat/nestjs/index.d.ts +1 -1
  108. package/dist/compat/nestjs/index.js +3 -3
  109. package/dist/{fallback-Bx46zqky.d.cts → fallback-BROR6ZhO.d.cts} +1 -1
  110. package/dist/{fallback-pIWW8A2d.d.ts → fallback-DO80aM_3.d.ts} +1 -1
  111. package/dist/{index-B_p8tnvf.d.cts → index-D1z3XcF9.d.cts} +1 -0
  112. package/dist/{index-_HDSmPyp.d.ts → index-DZ6yua0Q.d.ts} +1 -0
  113. package/dist/index.cjs +2215 -1676
  114. package/dist/index.cjs.map +1 -1
  115. package/dist/index.d.cts +10 -10
  116. package/dist/index.d.ts +10 -10
  117. package/dist/index.js +169 -146
  118. package/dist/index.js.map +1 -1
  119. package/dist/presets/ai/index.cjs +46 -0
  120. package/dist/presets/ai/index.cjs.map +1 -1
  121. package/dist/presets/ai/index.js +12 -12
  122. package/dist/presets/harness/index.cjs +130 -18
  123. package/dist/presets/harness/index.cjs.map +1 -1
  124. package/dist/presets/harness/index.d.cts +15 -5
  125. package/dist/presets/harness/index.d.ts +15 -5
  126. package/dist/presets/harness/index.js +22 -22
  127. package/dist/presets/index.cjs +222 -53
  128. package/dist/presets/index.cjs.map +1 -1
  129. package/dist/presets/index.d.cts +2 -2
  130. package/dist/presets/index.d.ts +2 -2
  131. package/dist/presets/index.js +45 -45
  132. package/dist/presets/inspect/index.cjs +63 -14
  133. package/dist/presets/inspect/index.cjs.map +1 -1
  134. package/dist/presets/inspect/index.d.cts +1 -1
  135. package/dist/presets/inspect/index.d.ts +1 -1
  136. package/dist/presets/inspect/index.js +6 -6
  137. package/dist/presets/resilience/index.cjs +29 -21
  138. package/dist/presets/resilience/index.cjs.map +1 -1
  139. package/dist/presets/resilience/index.d.cts +12 -8
  140. package/dist/presets/resilience/index.d.ts +12 -8
  141. package/dist/presets/resilience/index.js +3 -3
  142. package/dist/{rate-limiter-DpVbSYdH.d.cts → rate-limiter-DC26FM8J.d.cts} +10 -1
  143. package/dist/{rate-limiter-CEALq4N1.d.ts → rate-limiter-DyWpwpQP.d.ts} +10 -1
  144. package/dist/{reactive-layout-fswlBUvX.d.ts → reactive-layout-BBBWH0V_.d.cts} +85 -4
  145. package/dist/{reactive-layout-fswlBUvX.d.cts → reactive-layout-BBBWH0V_.d.ts} +85 -4
  146. package/dist/solutions/index.cjs +168 -47
  147. package/dist/solutions/index.cjs.map +1 -1
  148. package/dist/solutions/index.d.cts +2 -2
  149. package/dist/solutions/index.d.ts +2 -2
  150. package/dist/solutions/index.js +28 -28
  151. package/dist/{spawnable-5mDY501F.d.cts → spawnable-B2IlW60f.d.cts} +23 -2
  152. package/dist/{spawnable-D3lR0oQu.d.ts → spawnable-tttFz2Nh.d.ts} +23 -2
  153. package/dist/testing/index.cjs +94 -0
  154. package/dist/testing/index.cjs.map +1 -0
  155. package/dist/testing/index.d.cts +59 -0
  156. package/dist/testing/index.d.ts +59 -0
  157. package/dist/testing/index.js +73 -0
  158. package/dist/testing/index.js.map +1 -0
  159. package/dist/utils/ai/browser.cjs.map +1 -1
  160. package/dist/utils/ai/browser.d.cts +2 -2
  161. package/dist/utils/ai/browser.d.ts +2 -2
  162. package/dist/utils/ai/browser.js +6 -6
  163. package/dist/utils/ai/browser.js.map +1 -1
  164. package/dist/utils/ai/index.cjs +250 -166
  165. package/dist/utils/ai/index.cjs.map +1 -1
  166. package/dist/utils/ai/index.d.cts +108 -12
  167. package/dist/utils/ai/index.d.ts +108 -12
  168. package/dist/utils/ai/index.js +21 -19
  169. package/dist/utils/ai/node.cjs.map +1 -1
  170. package/dist/utils/ai/node.d.cts +5 -5
  171. package/dist/utils/ai/node.d.ts +5 -5
  172. package/dist/utils/ai/node.js +2 -2
  173. package/dist/utils/ai/node.js.map +1 -1
  174. package/dist/utils/cqrs/index.cjs +29 -3
  175. package/dist/utils/cqrs/index.cjs.map +1 -1
  176. package/dist/utils/cqrs/index.d.cts +12 -7
  177. package/dist/utils/cqrs/index.d.ts +12 -7
  178. package/dist/utils/cqrs/index.js +2 -2
  179. package/dist/utils/demo-shell/index.cjs +45 -19
  180. package/dist/utils/demo-shell/index.cjs.map +1 -1
  181. package/dist/utils/demo-shell/index.d.cts +1 -1
  182. package/dist/utils/demo-shell/index.d.ts +1 -1
  183. package/dist/utils/demo-shell/index.js +2 -2
  184. package/dist/utils/domain-templates/index.cjs.map +1 -1
  185. package/dist/utils/domain-templates/index.js +3 -3
  186. package/dist/utils/graphspec/index.cjs.map +1 -1
  187. package/dist/utils/graphspec/index.js +3 -3
  188. package/dist/utils/index.cjs +1642 -1225
  189. package/dist/utils/index.cjs.map +1 -1
  190. package/dist/utils/index.d.cts +7 -7
  191. package/dist/utils/index.d.ts +7 -7
  192. package/dist/utils/index.js +72 -54
  193. package/dist/utils/inspect/index.cjs +52 -4
  194. package/dist/utils/inspect/index.cjs.map +1 -1
  195. package/dist/utils/inspect/index.d.cts +32 -3
  196. package/dist/utils/inspect/index.d.ts +32 -3
  197. package/dist/utils/inspect/index.js +4 -4
  198. package/dist/utils/job-queue/index.cjs +46 -9
  199. package/dist/utils/job-queue/index.cjs.map +1 -1
  200. package/dist/utils/job-queue/index.d.cts +33 -3
  201. package/dist/utils/job-queue/index.d.ts +33 -3
  202. package/dist/utils/job-queue/index.js +2 -2
  203. package/dist/utils/memory/index.cjs +556 -462
  204. package/dist/utils/memory/index.cjs.map +1 -1
  205. package/dist/utils/memory/index.d.cts +203 -24
  206. package/dist/utils/memory/index.d.ts +203 -24
  207. package/dist/utils/memory/index.js +10 -2
  208. package/dist/utils/messaging/index.cjs.map +1 -1
  209. package/dist/utils/messaging/index.d.cts +4 -3
  210. package/dist/utils/messaging/index.d.ts +4 -3
  211. package/dist/utils/messaging/index.js +2 -2
  212. package/dist/utils/orchestration/index.cjs +9 -0
  213. package/dist/utils/orchestration/index.cjs.map +1 -1
  214. package/dist/utils/orchestration/index.js +3 -3
  215. package/dist/utils/process/index.cjs +32 -2
  216. package/dist/utils/process/index.cjs.map +1 -1
  217. package/dist/utils/process/index.d.cts +4 -3
  218. package/dist/utils/process/index.d.ts +4 -3
  219. package/dist/utils/process/index.js +2 -2
  220. package/dist/utils/reactive-layout/index.cjs +184 -55
  221. package/dist/utils/reactive-layout/index.cjs.map +1 -1
  222. package/dist/utils/reactive-layout/index.d.cts +128 -3
  223. package/dist/utils/reactive-layout/index.d.ts +128 -3
  224. package/dist/utils/reactive-layout/index.js +16 -8
  225. package/dist/utils/reduction/index.cjs.map +1 -1
  226. package/dist/utils/reduction/index.js +2 -2
  227. package/dist/utils/resilience/index.cjs +29 -20
  228. package/dist/utils/resilience/index.cjs.map +1 -1
  229. package/dist/utils/resilience/index.d.cts +1 -1
  230. package/dist/utils/resilience/index.d.ts +1 -1
  231. package/dist/utils/resilience/index.js +2 -2
  232. package/dist/utils/surface/index.cjs.map +1 -1
  233. package/dist/utils/surface/index.js +4 -4
  234. package/package.json +15 -3
  235. package/dist/chunk-3O3NKZJW.js.map +0 -1
  236. package/dist/chunk-3PSLNJDU.js.map +0 -1
  237. package/dist/chunk-42FQ27MQ.js.map +0 -1
  238. package/dist/chunk-4XCHZRUJ.js.map +0 -1
  239. package/dist/chunk-6ZLCPUXS.js.map +0 -1
  240. package/dist/chunk-7AVQIGF6.js.map +0 -1
  241. package/dist/chunk-BXGZFGZ4.js.map +0 -1
  242. package/dist/chunk-DDTS7F5O.js.map +0 -1
  243. package/dist/chunk-EL5VHUGK.js.map +0 -1
  244. package/dist/chunk-FQSQONOU.js.map +0 -1
  245. package/dist/chunk-IOJDYUA7.js.map +0 -1
  246. package/dist/chunk-KRFGO5QH.js.map +0 -1
  247. package/dist/chunk-MS3WPRJR.js.map +0 -1
  248. package/dist/chunk-NPRP3MCV.js.map +0 -1
  249. package/dist/chunk-NY2PYHNC.js.map +0 -1
  250. package/dist/chunk-PKPO3JTZ.js.map +0 -1
  251. package/dist/chunk-PTWADEH3.js.map +0 -1
  252. package/dist/chunk-T7SP3EYR.js.map +0 -1
  253. package/dist/chunk-VNXAF2KE.js.map +0 -1
  254. package/dist/chunk-W2BOPXTI.js +0 -1
  255. package/dist/chunk-W2BOPXTI.js.map +0 -1
  256. package/dist/chunk-WGDEBIP4.js.map +0 -1
  257. /package/dist/{chunk-R6ZCSXKX.js.map → chunk-23MAWVOJ.js.map} +0 -0
  258. /package/dist/{chunk-6MRSX3YK.js.map → chunk-B5Y5GPD5.js.map} +0 -0
  259. /package/dist/{chunk-VP3TIUDF.js.map → chunk-DVTDF5OI.js.map} +0 -0
  260. /package/dist/{chunk-OXD5LFQP.js.map → chunk-G7H6PN7P.js.map} +0 -0
  261. /package/dist/{chunk-446I4EGD.js.map → chunk-J5TBZFBD.js.map} +0 -0
  262. /package/dist/{chunk-QFE5BQH7.js.map → chunk-LTSI7ULC.js.map} +0 -0
  263. /package/dist/{chunk-KNU73RZW.js.map → chunk-NSA5K5G2.js.map} +0 -0
  264. /package/dist/{chunk-MLTPJMH6.js.map → chunk-QQYULEZL.js.map} +0 -0
  265. /package/dist/{chunk-VAZXUK6G.js.map → chunk-SUNCHMML.js.map} +0 -0
  266. /package/dist/{chunk-EP4WVQLX.js.map → chunk-T2U6N3FV.js.map} +0 -0
@@ -3,8 +3,8 @@ import { ReactiveLogBundle, OwnershipChange, NodeInput } from '@graphrefly/pure-
3
3
  import { Graph, GraphProfileResult, GraphProfileOptions } from '@graphrefly/pure-ts/graph';
4
4
  import { R as RenderedEntry, b as ContextEntry, c as ContextView, e as TaggedContextPoolBundle } from '../../index-DLAxYaN5.cjs';
5
5
  import { b as ExecuteOutput, p as TriagedItem, V as VerifyOutput, g as HarnessVerifier, H as HarnessExecutor, k as QueueRoute } from '../../types-vCq7ShIm.cjs';
6
- import { f as Evaluator, D as DatasetItem, d as EvalResult, i as RefineStrategy, g as RefineLoopOptions, H as HarnessGraph, h as RefineStatus } from '../../spawnable-5mDY501F.cjs';
7
- export { A as AnalyzeEvent, B as BlindVariationContext, a as BlindVariationOptions, C as ConvergenceOptions, b as DecideEvent, E as ErrorCritiqueContext, c as ErrorCritiqueOptions, e as EvaluateEvent, F as Feedback, G as GenerateEvent, I as Iteration, R as RefineLoopGraph, S as SpawnPayload, j as SpawnRejection, k as SpawnableBundle, l as SpawnableGraph, m as SpawnableOpts, n as blindVariation, o as defaultLlmExecutor, p as defaultLlmVerifier, q as errorCritique, r as harnessLoop, s as refineLoop, t as spawnable } from '../../spawnable-5mDY501F.cjs';
6
+ import { f as Evaluator, D as DatasetItem, d as EvalResult, i as RefineStrategy, g as RefineLoopOptions, H as HarnessGraph, h as RefineStatus } from '../../spawnable-B2IlW60f.cjs';
7
+ export { A as AnalyzeEvent, B as BlindVariationContext, a as BlindVariationOptions, C as ConvergenceOptions, b as DecideEvent, E as ErrorCritiqueContext, c as ErrorCritiqueOptions, e as EvaluateEvent, F as Feedback, G as GenerateEvent, I as Iteration, R as RefineLoopGraph, S as SpawnPayload, j as SpawnRejection, k as SpawnableBundle, l as SpawnableGraph, m as SpawnableOpts, n as blindVariation, o as defaultLlmExecutor, p as defaultLlmVerifier, q as errorCritique, r as harnessLoop, s as refineLoop, t as spawnable } from '../../spawnable-B2IlW60f.cjs';
8
8
  import { TopicGraph } from '../../utils/messaging/index.cjs';
9
9
  import '../../types-BB5Lw-pB.cjs';
10
10
  import '../../utils/job-queue/index.cjs';
@@ -73,7 +73,12 @@ interface ActorHandle<T> {
73
73
  }
74
74
  interface ActorPoolOptions<T> {
75
75
  readonly name?: string;
76
- /** Max recursion depth; `attachActor` with `depth > depthCap` throws. */
76
+ /**
77
+ * Max recursion depth; `attachActor` with `depth > depthCap` throws.
78
+ * Default: `8` (F-ACTOR, 2026-05-18 smell sweep — a finite default bounds
79
+ * runaway recursive fan-out; previously silently `Infinity`). Pass an
80
+ * explicit `Number.POSITIVE_INFINITY` to opt in to unbounded recursion.
81
+ */
77
82
  readonly depthCap?: number;
78
83
  /** Forwarded to the backing context pool. */
79
84
  readonly contextTopic?: string;
@@ -444,8 +449,13 @@ declare function harnessProfile(harness: HarnessGraph, opts?: GraphProfileOption
444
449
 
445
450
  /** Terminal-run snapshot passed to a custom `toOutput` mapper. */
446
451
  interface RefineExecutorResult<T> {
447
- /** Best candidate the inner loop converged on. `null` if no candidates were scored. */
448
- readonly best: T | null;
452
+ /**
453
+ * Best candidate the inner loop converged on. `undefined` (SENTINEL) if the
454
+ * inner loop never produced a best — e.g. it `errored` before any iteration
455
+ * settled. (`loop.best` is a SENTINEL `Node<T>` post the 2026-05-18
456
+ * anti-pattern sweep — no `null` placeholder.)
457
+ */
458
+ readonly best: T | undefined;
449
459
  /** Aggregate score at termination. `-Infinity` if the batch was empty. */
450
460
  readonly score: number;
451
461
  /** Reason the loop terminated. */
@@ -3,8 +3,8 @@ import { ReactiveLogBundle, OwnershipChange, NodeInput } from '@graphrefly/pure-
3
3
  import { Graph, GraphProfileResult, GraphProfileOptions } from '@graphrefly/pure-ts/graph';
4
4
  import { R as RenderedEntry, b as ContextEntry, c as ContextView, e as TaggedContextPoolBundle } from '../../index-DLAxYaN5.js';
5
5
  import { b as ExecuteOutput, p as TriagedItem, V as VerifyOutput, g as HarnessVerifier, H as HarnessExecutor, k as QueueRoute } from '../../types-CJWIMJiZ.js';
6
- import { f as Evaluator, D as DatasetItem, d as EvalResult, i as RefineStrategy, g as RefineLoopOptions, H as HarnessGraph, h as RefineStatus } from '../../spawnable-D3lR0oQu.js';
7
- export { A as AnalyzeEvent, B as BlindVariationContext, a as BlindVariationOptions, C as ConvergenceOptions, b as DecideEvent, E as ErrorCritiqueContext, c as ErrorCritiqueOptions, e as EvaluateEvent, F as Feedback, G as GenerateEvent, I as Iteration, R as RefineLoopGraph, S as SpawnPayload, j as SpawnRejection, k as SpawnableBundle, l as SpawnableGraph, m as SpawnableOpts, n as blindVariation, o as defaultLlmExecutor, p as defaultLlmVerifier, q as errorCritique, r as harnessLoop, s as refineLoop, t as spawnable } from '../../spawnable-D3lR0oQu.js';
6
+ import { f as Evaluator, D as DatasetItem, d as EvalResult, i as RefineStrategy, g as RefineLoopOptions, H as HarnessGraph, h as RefineStatus } from '../../spawnable-tttFz2Nh.js';
7
+ export { A as AnalyzeEvent, B as BlindVariationContext, a as BlindVariationOptions, C as ConvergenceOptions, b as DecideEvent, E as ErrorCritiqueContext, c as ErrorCritiqueOptions, e as EvaluateEvent, F as Feedback, G as GenerateEvent, I as Iteration, R as RefineLoopGraph, S as SpawnPayload, j as SpawnRejection, k as SpawnableBundle, l as SpawnableGraph, m as SpawnableOpts, n as blindVariation, o as defaultLlmExecutor, p as defaultLlmVerifier, q as errorCritique, r as harnessLoop, s as refineLoop, t as spawnable } from '../../spawnable-tttFz2Nh.js';
8
8
  import { TopicGraph } from '../../utils/messaging/index.js';
9
9
  import '../../types-BB5Lw-pB.js';
10
10
  import '../../utils/job-queue/index.js';
@@ -73,7 +73,12 @@ interface ActorHandle<T> {
73
73
  }
74
74
  interface ActorPoolOptions<T> {
75
75
  readonly name?: string;
76
- /** Max recursion depth; `attachActor` with `depth > depthCap` throws. */
76
+ /**
77
+ * Max recursion depth; `attachActor` with `depth > depthCap` throws.
78
+ * Default: `8` (F-ACTOR, 2026-05-18 smell sweep — a finite default bounds
79
+ * runaway recursive fan-out; previously silently `Infinity`). Pass an
80
+ * explicit `Number.POSITIVE_INFINITY` to opt in to unbounded recursion.
81
+ */
77
82
  readonly depthCap?: number;
78
83
  /** Forwarded to the backing context pool. */
79
84
  readonly contextTopic?: string;
@@ -444,8 +449,13 @@ declare function harnessProfile(harness: HarnessGraph, opts?: GraphProfileOption
444
449
 
445
450
  /** Terminal-run snapshot passed to a custom `toOutput` mapper. */
446
451
  interface RefineExecutorResult<T> {
447
- /** Best candidate the inner loop converged on. `null` if no candidates were scored. */
448
- readonly best: T | null;
452
+ /**
453
+ * Best candidate the inner loop converged on. `undefined` (SENTINEL) if the
454
+ * inner loop never produced a best — e.g. it `errored` before any iteration
455
+ * settled. (`loop.best` is a SENTINEL `Node<T>` post the 2026-05-18
456
+ * anti-pattern sweep — no `null` placeholder.)
457
+ */
458
+ readonly best: T | undefined;
449
459
  /** Aggregate score at termination. `-Infinity` if the batch was empty. */
450
460
  readonly score: number;
451
461
  /** Reason the loop terminated. */
@@ -7,8 +7,8 @@ import {
7
7
  harnessTrace,
8
8
  ownershipController,
9
9
  refineExecutor
10
- } from "../../chunk-VNXAF2KE.js";
11
- import "../../chunk-VP3TIUDF.js";
10
+ } from "../../chunk-TPTZZV25.js";
11
+ import "../../chunk-DVTDF5OI.js";
12
12
  import {
13
13
  HarnessGraph,
14
14
  RefineLoopGraph,
@@ -20,33 +20,33 @@ import {
20
20
  harnessLoop,
21
21
  refineLoop,
22
22
  spawnable
23
- } from "../../chunk-PTWADEH3.js";
24
- import "../../chunk-FQSQONOU.js";
23
+ } from "../../chunk-YBJVKMTM.js";
24
+ import "../../chunk-65OM4XLQ.js";
25
25
  import "../../chunk-OIWU3NYV.js";
26
- import "../../chunk-PKPO3JTZ.js";
27
- import "../../chunk-KRFGO5QH.js";
28
- import "../../chunk-6MRSX3YK.js";
29
- import "../../chunk-DDTS7F5O.js";
30
- import "../../chunk-EP4WVQLX.js";
31
- import "../../chunk-T7SP3EYR.js";
26
+ import "../../chunk-AQAKDE7F.js";
27
+ import "../../chunk-MQMTRKY3.js";
28
+ import "../../chunk-B5Y5GPD5.js";
29
+ import "../../chunk-LTSI7ULC.js";
30
+ import "../../chunk-ZW32BPXV.js";
31
+ import "../../chunk-T2U6N3FV.js";
32
+ import "../../chunk-T5URUIIY.js";
32
33
  import "../../chunk-GUNIRPEJ.js";
33
- import "../../chunk-N65E26UL.js";
34
- import "../../chunk-QFE5BQH7.js";
35
- import "../../chunk-MS3WPRJR.js";
36
- import "../../chunk-7AVQIGF6.js";
37
- import "../../chunk-NPRP3MCV.js";
38
- import "../../chunk-QMBYUVRL.js";
39
- import "../../chunk-FMPF42Q4.js";
40
- import "../../chunk-BXGZFGZ4.js";
41
- import "../../chunk-IOJDYUA7.js";
42
- import "../../chunk-OXD5LFQP.js";
43
- import "../../chunk-5GVURVIG.js";
44
- import "../../chunk-N6MNJNHB.js";
34
+ import "../../chunk-XEWV254I.js";
35
+ import "../../chunk-3REMCHSS.js";
36
+ import "../../chunk-K4ZYJ4EM.js";
37
+ import "../../chunk-DHDCOOJU.js";
45
38
  import "../../chunk-F7EKHR32.js";
46
39
  import "../../chunk-JA67ZQG2.js";
47
40
  import "../../chunk-KUFXLAEY.js";
48
41
  import "../../chunk-TSBFTJKM.js";
49
42
  import "../../chunk-P5LBT622.js";
43
+ import "../../chunk-QMBYUVRL.js";
44
+ import "../../chunk-FMPF42Q4.js";
45
+ import "../../chunk-C5QD5DQX.js";
46
+ import "../../chunk-V46JWFGV.js";
47
+ import "../../chunk-G7H6PN7P.js";
48
+ import "../../chunk-MMHGYX44.js";
49
+ import "../../chunk-N6MNJNHB.js";
50
50
  import "../../chunk-AZDQPQ3V.js";
51
51
  export {
52
52
  HarnessGraph,
@@ -559,6 +559,26 @@ function createAuditLog(opts) {
559
559
  }
560
560
  return log;
561
561
  }
562
+ function readonlyAuditLog(log) {
563
+ return Object.freeze({
564
+ get entries() {
565
+ return log.entries;
566
+ },
567
+ get size() {
568
+ return log.size;
569
+ },
570
+ get lastValue() {
571
+ return log.lastValue;
572
+ },
573
+ get mutationLog() {
574
+ return log.mutationLog;
575
+ },
576
+ at: log.at.bind(log),
577
+ withLatest: log.withLatest.bind(log),
578
+ view: log.view.bind(log),
579
+ scan: log.scan.bind(log)
580
+ });
581
+ }
562
582
  function deepFreeze(value) {
563
583
  if (value === null || typeof value !== "object" || Object.isFrozen(value)) return value;
564
584
  for (const k of Object.keys(value)) {
@@ -2027,6 +2047,11 @@ var AgentLoopGraph = class extends import_graph5.Graph {
2027
2047
  chat.append("assistant", response.content, {
2028
2048
  toolCalls: response.toolCalls
2029
2049
  });
2050
+ if (capReached && hasToolCalls) {
2051
+ for (const tc of response.toolCalls) {
2052
+ chat.appendToolResult(tc.id, "[tool call denied: maxTurns reached]");
2053
+ }
2054
+ }
2030
2055
  });
2031
2056
  },
2032
2057
  { describeKind: "effect" }
@@ -2048,6 +2073,45 @@ var AgentLoopGraph = class extends import_graph5.Graph {
2048
2073
  },
2049
2074
  { describeKind: "effect" }
2050
2075
  );
2076
+ const effFullDeny = gatedToolCallsNode !== toolCallsRaw ? (0, import_core11.node)(
2077
+ [toolCallsRaw, gatedToolCallsNode],
2078
+ (batchData) => {
2079
+ if (latestAborted) return;
2080
+ const rawBatch = batchData[0];
2081
+ const gatedBatch = batchData[1];
2082
+ const rawCalls = rawBatch != null && rawBatch.length > 0 ? rawBatch.at(-1) : null;
2083
+ if (rawCalls == null || rawCalls.length === 0) return;
2084
+ const gatedCalls = gatedBatch != null && gatedBatch.length > 0 ? gatedBatch.at(-1) : null;
2085
+ const allowedIds = gatedCalls === null ? null : new Set(gatedCalls.map((c) => c.id));
2086
+ const denied = allowedIds === null ? rawCalls : rawCalls.filter((c) => !allowedIds.has(c.id));
2087
+ if (denied.length === 0) return;
2088
+ const isFullDeny = gatedCalls === null;
2089
+ (0, import_core11.batch)(() => {
2090
+ if (isFullDeny) {
2091
+ statusNode.emit(latestTurn >= maxTurns ? "done" : "thinking");
2092
+ }
2093
+ for (const c of denied)
2094
+ chat.appendToolResult(c.id, "[tool call denied by interceptor]");
2095
+ });
2096
+ },
2097
+ {
2098
+ name: "fullDenyRecovery",
2099
+ describeKind: "effect",
2100
+ meta: aiMeta("agent_full_deny_recovery"),
2101
+ // MUST be explicit: the core `node()` default is
2102
+ // `partial: false` (node.ts `opts.partial ?? false`),
2103
+ // and `gatedToolCallsNode` only ever emits RESOLVED on the
2104
+ // full-deny path (never DATA/terminal). Spec R2.7.0
2105
+ // (DS-2.7.A, 2026-05-19) holds the `partial: false`
2106
+ // first-run gate until every dep has contributed real
2107
+ // DATA, so a `partial: false` effFullDeny would hold the
2108
+ // fn FOREVER. Spec R2.7.2 = `partial: true` disables the
2109
+ // gate; the fn body's `denied`-subtraction guard above
2110
+ // covers the SENTINEL slot per the R2.7.2 author
2111
+ // contract.
2112
+ partial: true
2113
+ }
2114
+ ) : null;
2051
2115
  let latestStatus = statusNode.cache ?? "idle";
2052
2116
  const statusSub = statusNode.subscribe((msgs) => {
2053
2117
  for (const m of msgs) if (m[0] === import_core11.DATA) latestStatus = m[1];
@@ -2067,6 +2131,7 @@ var AgentLoopGraph = class extends import_graph5.Graph {
2067
2131
  );
2068
2132
  const kaResponse = (0, import_extra7.keepalive)(effResponse);
2069
2133
  const kaResults = (0, import_extra7.keepalive)(effResults);
2134
+ const kaFullDeny = effFullDeny ? (0, import_extra7.keepalive)(effFullDeny) : null;
2070
2135
  const kaAbort = (0, import_extra7.keepalive)(effAbort);
2071
2136
  this._terminalResult = (0, import_core11.node)(
2072
2137
  [statusNode, lastResponseState],
@@ -2119,6 +2184,7 @@ var AgentLoopGraph = class extends import_graph5.Graph {
2119
2184
  this.addDisposer(statusSub);
2120
2185
  this.addDisposer(kaResponse);
2121
2186
  this.addDisposer(kaResults);
2187
+ if (kaFullDeny) this.addDisposer(kaFullDeny);
2122
2188
  this.addDisposer(kaAbort);
2123
2189
  this._disposeRunWiring = () => {
2124
2190
  };
@@ -4768,7 +4834,7 @@ function actorPool(parent, opts = {}) {
4768
4834
  const name = opts.name ?? `actorPool-${++_actorPoolSeq}`;
4769
4835
  const graph = new import_graph12.Graph(name);
4770
4836
  parent.mount(name, graph);
4771
- const depthCap = opts.depthCap ?? Number.POSITIVE_INFINITY;
4837
+ const depthCap = opts.depthCap ?? 8;
4772
4838
  let autoActor = 0;
4773
4839
  const liveHandles = /* @__PURE__ */ new Set();
4774
4840
  const contextPool = taggedContextPool(graph, {
@@ -4872,6 +4938,16 @@ var import_core23 = require("@graphrefly/pure-ts/core");
4872
4938
  var import_extra20 = require("@graphrefly/pure-ts/extra");
4873
4939
  var import_graph13 = require("@graphrefly/pure-ts/graph");
4874
4940
  var RefineLoopGraph = class extends import_graph13.Graph {
4941
+ /**
4942
+ * Best candidate so far. **SENTINEL until the first iteration settles** —
4943
+ * `loop.best.cache` is `undefined` (not `null`) before any iteration
4944
+ * produces a best, and a degenerate empty-candidate iteration leaves the
4945
+ * prior best in place rather than wiping it. Consumers guard with
4946
+ * `=== undefined` (spec §3 SENTINEL), not `== null`. (Anti-pattern sweep
4947
+ * 2026-05-18: dropped the `initial: null` eager-placeholder; `null` is
4948
+ * reserved for the per-iteration {@link Iteration.best} data field where an
4949
+ * empty batch is a valid domain value.)
4950
+ */
4875
4951
  best;
4876
4952
  /**
4877
4953
  * Best score so far. Pseudo-private (`_score`) to avoid colliding with any
@@ -4922,8 +4998,7 @@ var RefineLoopGraph = class extends import_graph13.Graph {
4922
4998
  });
4923
4999
  this.add(strategyNode, { name: "strategy" });
4924
5000
  const lastFeedbackState = (0, import_core23.node)([], {
4925
- name: "lastFeedback",
4926
- initial: null
5001
+ name: "lastFeedback"
4927
5002
  });
4928
5003
  this.add(lastFeedbackState, { name: "lastFeedback" });
4929
5004
  const prevCandidatesState = (0, import_core23.node)([], {
@@ -4942,7 +5017,7 @@ var RefineLoopGraph = class extends import_graph13.Graph {
4942
5017
  // append-style; reactive consumers want every push
4943
5018
  });
4944
5019
  this.add(historyState, { name: "history" });
4945
- const bestState = (0, import_core23.node)([], { name: "best", initial: null });
5020
+ const bestState = (0, import_core23.node)([], { name: "best" });
4946
5021
  this.add(bestState, { name: "best" });
4947
5022
  const scoreState = (0, import_core23.node)([], { name: "score", initial: Number.NEGATIVE_INFINITY });
4948
5023
  this.add(scoreState, { name: "score" });
@@ -4966,7 +5041,7 @@ var RefineLoopGraph = class extends import_graph13.Graph {
4966
5041
  this.decide = hubDecideTopic;
4967
5042
  this._pauseState = pauseState;
4968
5043
  let latestStrategy = initialStrategy;
4969
- let latestFeedback = null;
5044
+ let latestFeedback;
4970
5045
  let latestPrevCandidates = [];
4971
5046
  this.addDisposer(
4972
5047
  strategyNode.subscribe((msgs) => {
@@ -4987,7 +5062,7 @@ var RefineLoopGraph = class extends import_graph13.Graph {
4987
5062
  iterationTrigger,
4988
5063
  (iter) => {
4989
5064
  const strat = latestStrategy;
4990
- const isSeed = iter === 0 || latestFeedback == null;
5065
+ const isSeed = iter === 0 || latestFeedback === void 0;
4991
5066
  return (0, import_core23.node)(
4992
5067
  [],
4993
5068
  (_data, actions) => {
@@ -5379,7 +5454,7 @@ var RefineLoopGraph = class extends import_graph13.Graph {
5379
5454
  decision = "paused";
5380
5455
  }
5381
5456
  (0, import_core23.batch)(() => {
5382
- bestState.emit(best);
5457
+ if (best !== null) bestState.emit(best);
5383
5458
  scoreState.emit(fb.score);
5384
5459
  historyState.emit(nextHistory);
5385
5460
  budgetState.emit(nextBudget);
@@ -5619,7 +5694,7 @@ function errorCritique(opts) {
5619
5694
  function defaultToOutput(result) {
5620
5695
  const { best, score, status } = result;
5621
5696
  const scoreStr = Number.isFinite(score) ? score.toFixed(3) : String(score);
5622
- const artifact = best ?? void 0;
5697
+ const artifact = best;
5623
5698
  if (status === "converged") {
5624
5699
  return {
5625
5700
  outcome: "success",
@@ -6441,31 +6516,40 @@ var RATE_LIMITER_INITIAL_STATE = Object.freeze({
6441
6516
  pendingCount: 0,
6442
6517
  paused: false
6443
6518
  });
6519
+ function validateRateLimiterOpts(o) {
6520
+ if (o.maxEvents <= 0) throw new RangeError("maxEvents must be > 0");
6521
+ if (o.windowNs <= 0) throw new RangeError("windowNs must be > 0");
6522
+ if (o.maxBuffer === void 0) {
6523
+ throw new RangeError(
6524
+ "rateLimiter requires explicit maxBuffer (use Infinity to opt in to unbounded)"
6525
+ );
6526
+ }
6527
+ const isUnbounded = o.maxBuffer === Infinity;
6528
+ if (!isUnbounded && (!Number.isInteger(o.maxBuffer) || o.maxBuffer < 1)) {
6529
+ throw new RangeError("maxBuffer must be a positive integer (or Infinity for unbounded)");
6530
+ }
6531
+ }
6532
+ function resolveInitialReactiveOpts(optsNode) {
6533
+ const cached = optsNode.cache;
6534
+ if (cached === void 0) {
6535
+ throw new RangeError(
6536
+ "rateLimiter: reactive (Node-form) opts must carry a cached value at construction \u2014 seed the opts Node with `initial`. Mode (bounded vs unbounded) and the initial cap are LOCKED from `.cache` at construction and the swap handler rejects mode toggles; an un-seeded Node would silently lock bounded `maxBuffer: 1` (D4)."
6537
+ );
6538
+ }
6539
+ return cached;
6540
+ }
6444
6541
  function rateLimiter(source, opts) {
6445
6542
  const isReactive = isNode(opts);
6446
- if (!isReactive) {
6447
- const o = opts;
6448
- if (o.maxEvents <= 0) throw new RangeError("maxEvents must be > 0");
6449
- if (o.windowNs <= 0) throw new RangeError("windowNs must be > 0");
6450
- if (o.maxBuffer === void 0) {
6451
- throw new RangeError(
6452
- "rateLimiter requires explicit maxBuffer (use Infinity to opt in to unbounded)"
6453
- );
6454
- }
6455
- const isUnbounded0 = o.maxBuffer === Infinity;
6456
- if (!isUnbounded0 && (!Number.isInteger(o.maxBuffer) || o.maxBuffer < 1)) {
6457
- throw new RangeError("maxBuffer must be a positive integer (or Infinity for unbounded)");
6458
- }
6459
- }
6460
- const initialOpts = isReactive ? opts.cache : opts;
6461
- const initialMaxBuffer = initialOpts?.maxBuffer;
6543
+ const initialOpts = isReactive ? resolveInitialReactiveOpts(opts) : opts;
6544
+ validateRateLimiterOpts(initialOpts);
6545
+ const initialMaxBuffer = initialOpts.maxBuffer;
6462
6546
  const isUnbounded = initialMaxBuffer === Infinity;
6463
6547
  const out = (0, import_core30.node)(
6464
6548
  (_data, a) => {
6465
- let maxEvents = initialOpts?.maxEvents ?? 1;
6466
- let windowNs = initialOpts?.windowNs ?? NS_PER_SEC;
6467
- let maxBuffer = initialMaxBuffer ?? 1;
6468
- let onOverflow = initialOpts?.onOverflow ?? "drop-newest";
6549
+ let maxEvents = initialOpts.maxEvents;
6550
+ let windowNs = initialOpts.windowNs;
6551
+ let maxBuffer = initialMaxBuffer;
6552
+ let onOverflow = initialOpts.onOverflow ?? "drop-newest";
6469
6553
  let refillPerSec = maxEvents * NS_PER_SEC / windowNs;
6470
6554
  let tokenTimeNs = NS_PER_SEC / refillPerSec;
6471
6555
  let bucket = tokenBucket(maxEvents, refillPerSec);
@@ -6836,6 +6920,10 @@ var PipelineGraph = class extends import_graph15.Graph {
6836
6920
  {
6837
6921
  name,
6838
6922
  describeKind: "derived",
6923
+ // Spec §2.7 R2.7.1 (DS-2.7.A). fn must fire on
6924
+ // upstream-COMPLETE/ERROR-only-without-DATA so the
6925
+ // teardown-decision record + downstream terminal forward run.
6926
+ terminalAsRealInput: true,
6839
6927
  meta: meta("approval_gate", opts.meta)
6840
6928
  }
6841
6929
  );
@@ -7053,6 +7141,11 @@ var PipelineGraph = class extends import_graph15.Graph {
7053
7141
  describeKind: "derived",
7054
7142
  completeWhenDepsComplete: opts.completeWhenDepsComplete ?? !(mode === "completed" || mode === "terminal"),
7055
7143
  errorWhenDepsError: !(mode === "errored" || mode === "terminal"),
7144
+ // Spec §2.7 R2.7.1 (DS-2.7.A). `catch` exists to fire on a
7145
+ // source terminal — its whole job is `recover(cause, …)` on a
7146
+ // terminal-only wave. Without this opt-in the gate holds and
7147
+ // the recover branch never runs.
7148
+ terminalAsRealInput: true,
7056
7149
  meta: meta("catch", opts.meta)
7057
7150
  }
7058
7151
  );
@@ -7255,7 +7348,10 @@ var JobQueueGraph = class extends import_graph17.Graph {
7255
7348
  depth;
7256
7349
  /** Audit log of every queue mutation (Audit 2). */
7257
7350
  events;
7258
- /** Alias for {@link JobQueueGraph.events} — Audit 2 `.audit` duplication. */
7351
+ /**
7352
+ * Read-only view of {@link JobQueueGraph.events} — Audit 2 `.audit`
7353
+ * duplication; M7 (cannot mutate the canonical log via the alias).
7354
+ */
7259
7355
  audit;
7260
7356
  // Tier 8 / COMPOSITION-GUIDE §35: mutate wrappers for the four
7261
7357
  // single-record mutation methods. Assigned in the constructor (NOT via
@@ -7296,7 +7392,7 @@ var JobQueueGraph = class extends import_graph17.Graph {
7296
7392
  retainedLimit: 1024,
7297
7393
  graph: this
7298
7394
  });
7299
- this.audit = this.events;
7395
+ this.audit = readonlyAuditLog(this.events);
7300
7396
  this._seqCursor = registerCursor(this, "seq", 0);
7301
7397
  this._enqueueImpl = mutate(
7302
7398
  (payload, enqueueOpts) => {
@@ -7349,7 +7445,7 @@ var JobQueueGraph = class extends import_graph17.Graph {
7349
7445
  }
7350
7446
  );
7351
7447
  this._nackImpl = mutate(
7352
- (id, job, requeue) => {
7448
+ (id, job, requeue, _error) => {
7353
7449
  if (requeue) {
7354
7450
  this._jobs.set(id, { ...job, state: "queued" });
7355
7451
  this._pending.append(id);
@@ -7362,12 +7458,16 @@ var JobQueueGraph = class extends import_graph17.Graph {
7362
7458
  log: this.events,
7363
7459
  seq: this._seqCursor,
7364
7460
  freeze: false,
7365
- onSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({
7461
+ onSuccessRecord: ([id, job, requeue, error], _r, { t_ns, seq }) => ({
7366
7462
  action: "nack",
7367
7463
  id,
7368
7464
  attempts: job.attempts,
7369
7465
  t_ns,
7370
- seq: seq ?? 0
7466
+ seq: seq ?? 0,
7467
+ // F-CATCH D-3: surface the failure cause on the no-requeue
7468
+ // (terminal-failure) nack only. A requeue nack is a retry,
7469
+ // not a failure, so it carries no error.
7470
+ ...!requeue && error !== void 0 ? { error } : {}
7371
7471
  })
7372
7472
  }
7373
7473
  );
@@ -7439,10 +7539,20 @@ var JobQueueGraph = class extends import_graph17.Graph {
7439
7539
  this._ackImpl(id, job);
7440
7540
  return true;
7441
7541
  }
7542
+ /**
7543
+ * Negatively-acknowledge an inflight job.
7544
+ *
7545
+ * @param opts.requeue - `true` (default) returns the job to the queue for
7546
+ * retry; `false` drops it permanently (terminal failure).
7547
+ * @param opts.error - Optional failure cause for a `requeue: false` nack.
7548
+ * Recorded on the emitted `"nack"` {@link JobEvent} as `error` so the
7549
+ * reason a job failed is recoverable from the event stream (F-CATCH
7550
+ * D-3). Ignored when `requeue` is `true` (a retry is not a failure).
7551
+ */
7442
7552
  nack(id, opts = {}) {
7443
7553
  const job = this._jobs.get(id);
7444
7554
  if (!job || job.state !== "inflight") return false;
7445
- this._nackImpl(id, job, opts.requeue ?? true);
7555
+ this._nackImpl(id, job, opts.requeue ?? true, opts.error);
7446
7556
  return true;
7447
7557
  }
7448
7558
  /**
@@ -7608,10 +7718,10 @@ var JobFlowGraph = class extends import_graph17.Graph {
7608
7718
  let result;
7609
7719
  try {
7610
7720
  result = workFn(job, { signal: ac.signal });
7611
- } catch {
7721
+ } catch (err) {
7612
7722
  inflight.delete(entry);
7613
7723
  inflightCounter?.emit(inflight.size);
7614
- current.nack(job.id, { requeue: false });
7724
+ current.nack(job.id, { requeue: false, error: err });
7615
7725
  processed += 1;
7616
7726
  continue;
7617
7727
  }
@@ -7662,7 +7772,7 @@ var JobFlowGraph = class extends import_graph17.Graph {
7662
7772
  } else if (m[0] === import_core33.ERROR) {
7663
7773
  settled = true;
7664
7774
  cleanupSub();
7665
- current.nack(job.id, { requeue: false });
7775
+ current.nack(job.id, { requeue: false, error: m[1] });
7666
7776
  return;
7667
7777
  }
7668
7778
  }
@@ -7918,7 +8028,18 @@ var HarnessGraph = class extends import_graph18.Graph {
7918
8028
  * (use {@link unrouted}), and the internal `triage-output` fan-in.
7919
8029
  */
7920
8030
  queueTopics;
7921
- /** Strategy model — `auditedSuccessTracker` keyed by `StrategyKey`. */
8031
+ /**
8032
+ * Strategy model — `auditedSuccessTracker` keyed by `StrategyKey`.
8033
+ *
8034
+ * **Ownership (EC10/EC15).** Owned by the harness: it is mounted as a
8035
+ * child subgraph (`harness.mount("strategy", strategy)`), so its disposal
8036
+ * cascades from `harness.destroy()` via the mount lifecycle. Do **not**
8037
+ * call `strategy.destroy()` independently — the harness's `triage-input`
8038
+ * node and (when `opts.priority` is set) `buildPriorityScores` hold
8039
+ * cross-graph deps on `strategy.entries`; destroying the strategy out of
8040
+ * band staleness those nodes while the rest of the loop keeps running.
8041
+ * Read/subscribe freely; let the harness own the lifecycle.
8042
+ */
7922
8043
  strategy;
7923
8044
  /** Global retry count across all items (circuit breaker). Reactive — subscribable. */
7924
8045
  totalRetries;
@@ -9218,7 +9339,11 @@ function healthReportEqual(a, b) {
9218
9339
  }
9219
9340
  return true;
9220
9341
  }
9221
- function graphLens(target) {
9342
+ function graphLens(target, opts = {}) {
9343
+ const mutLogOpt = opts.mutations;
9344
+ const mutationsEnabled = mutLogOpt != null;
9345
+ const pendingFlowChanges = [];
9346
+ let disposed = false;
9222
9347
  const topologyHandle = target.describe({
9223
9348
  reactive: true,
9224
9349
  detail: "standard",
@@ -9261,17 +9386,26 @@ function graphLens(target) {
9261
9386
  const path = event.path;
9262
9387
  if (path == null || path === "") continue;
9263
9388
  const prior = flowMap.get(path);
9389
+ const count = (prior?.count ?? 0) + 1;
9264
9390
  flowMap.set(path, {
9265
9391
  path,
9266
- count: (prior?.count ?? 0) + 1,
9392
+ count,
9267
9393
  lastUpdate_ns: c.flushedAt_ns
9268
9394
  });
9395
+ if (mutationsEnabled && !disposed) {
9396
+ pendingFlowChanges.push({ kind: "tick", path, count });
9397
+ }
9269
9398
  }
9270
9399
  }
9271
9400
  if (desc != null && flowMap.size > 0) {
9272
9401
  const valid = new Set(Object.keys(desc.nodes));
9273
9402
  for (const k of [...flowMap.keys()]) {
9274
- if (!valid.has(k)) flowMap.delete(k);
9403
+ if (!valid.has(k)) {
9404
+ flowMap.delete(k);
9405
+ if (mutationsEnabled && !disposed) {
9406
+ pendingFlowChanges.push({ kind: "evict", path: k });
9407
+ }
9408
+ }
9275
9409
  }
9276
9410
  }
9277
9411
  actions.emit(new Map(flowMap));
@@ -9282,15 +9416,50 @@ function graphLens(target) {
9282
9416
  meta: domainMeta("lens", "flow")
9283
9417
  }
9284
9418
  );
9419
+ let flowMutations;
9420
+ let stopFlowMutKeep;
9421
+ if (mutLogOpt != null) {
9422
+ const log = (0, import_extra30.reactiveLog)(void 0, {
9423
+ name: mutLogOpt === true ? "graphLens.flowMutations" : mutLogOpt.name ?? "graphLens.flowMutations",
9424
+ maxSize: mutLogOpt === true ? void 0 : mutLogOpt.maxSize
9425
+ });
9426
+ flowMutations = log;
9427
+ let mutVersion = 0;
9428
+ const flowMutationsDrain = (0, import_core39.node)(
9429
+ [flow],
9430
+ (_batchData, _actions, _ctx) => {
9431
+ if (pendingFlowChanges.length === 0) return;
9432
+ const drained = pendingFlowChanges.splice(0);
9433
+ for (const change of drained) {
9434
+ log.append({
9435
+ structure: "lensFlow",
9436
+ version: ++mutVersion,
9437
+ t_ns: (0, import_core39.wallClockNs)(),
9438
+ lifecycle: "data",
9439
+ change
9440
+ });
9441
+ }
9442
+ },
9443
+ {
9444
+ name: "graphLens.flowMutationsDrain",
9445
+ describeKind: "effect",
9446
+ meta: domainMeta("lens", "flowMutations")
9447
+ }
9448
+ );
9449
+ stopFlowMutKeep = (0, import_extra30.keepalive)(flowMutationsDrain);
9450
+ }
9285
9451
  const stopFlowKeep = (0, import_extra30.keepalive)(flow);
9286
- let disposed = false;
9287
9452
  return {
9288
9453
  topology,
9289
9454
  health,
9290
9455
  flow,
9456
+ ...flowMutations ? { flowMutations } : {},
9291
9457
  dispose() {
9292
9458
  if (disposed) return;
9293
9459
  disposed = true;
9460
+ stopFlowMutKeep?.();
9461
+ flowMutations?.dispose();
9462
+ pendingFlowChanges.length = 0;
9294
9463
  stopFlowKeep();
9295
9464
  stopHealthKeep();
9296
9465
  topologyHandle.dispose();
@@ -9509,11 +9678,12 @@ var GuardedExecutionGraph = class extends import_graph26.Graph {
9509
9678
  this.addDisposer((0, import_extra31.keepalive)(this.scope));
9510
9679
  const scopedHandle = target.describe({
9511
9680
  reactive: true,
9512
- // F8 (Tier 5.2): `_actorNode` is `Node<Actor | null>`. The cast is
9513
- // safe at runtime per the `resolveActorOption` null-tolerance
9514
- // contract `null` / `undefined` cache is treated as "no scoping"
9515
- // (full visibility). See `scopedDescribeNode` for the matching
9516
- // per-call site and graph.ts § "Cache-undefined semantics".
9681
+ // F8 (resolved 2026-05-18): `GraphDescribeOptions.actor` is now
9682
+ // `Actor | Node<Actor | null>`, so `_actorNode` (a
9683
+ // `Node<Actor | null>`) passes without a cast. A `null`/`undefined`
9684
+ // cache resolves to "no scoping" (full visibility) per
9685
+ // `resolveActorOption`. See graph.ts § "Cache-undefined/null
9686
+ // semantics".
9517
9687
  actor: this._actorNode,
9518
9688
  reactiveName: "scopedDescribe"
9519
9689
  });
@@ -9559,11 +9729,11 @@ var GuardedExecutionGraph = class extends import_graph26.Graph {
9559
9729
  const actorNode = actorOverride == null ? this._actorNode : isNode4(actorOverride) ? actorOverride : (0, import_core41.node)([], { name: "actor_override", initial: actorOverride });
9560
9730
  const handle = this._target.describe({
9561
9731
  reactive: true,
9562
- // `_actorNode` is `Node<Actor | null>`. The `as Node<Actor>` cast is
9563
- // safe at runtime: `_describeReactive` resolves the actor via
9564
- // `resolveActorOption`, which treats `null`/`undefined` cache as
9565
- // "no scoping" (full visibility). Documented in graph.ts §
9566
- // "Cache-undefined semantics."
9732
+ // F8 (resolved 2026-05-18): `actor` accepts `Node<Actor | null>`
9733
+ // directly. `actorNode` is `_actorNode` (`Node<Actor | null>`) or
9734
+ // an override (`Node<Actor>`/`Node<Actor | null>`); both assign
9735
+ // without a cast. `_describeReactive` resolves via
9736
+ // `resolveActorOption` (null/undefined cache → no scoping).
9567
9737
  actor: actorNode,
9568
9738
  ...opts ?? {}
9569
9739
  });
@@ -9664,7 +9834,6 @@ var ResilientPipelineGraph = class extends import_graph27.Graph {
9664
9834
  } else {
9665
9835
  const rateOpts = {
9666
9836
  ...opts.rateLimit,
9667
- maxBuffer: opts.rateLimit.maxBuffer ?? Infinity,
9668
9837
  meta: domainMeta("resilient", "rate-limit")
9669
9838
  };
9670
9839
  const bundle = rateLimiter(current, rateOpts);