@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
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/base/resilience/_internal.ts","../../../src/base/resilience/backoff.ts","../../../src/base/resilience/timeout.ts","../../../src/presets/harness/index.ts","../../../src/presets/harness/actor-pool.ts","../../../src/presets/ai/context/index.ts","../../../src/utils/ai/_internal.ts","../../../src/base/meta/domain-meta.ts","../../../src/presets/harness/eval-verifier.ts","../../../src/presets/harness/refine-executor.ts","../../../src/presets/harness/refine-loop.ts","../../../src/base/mutation/index.ts","../../../src/utils/messaging/message.ts","../../../src/utils/messaging/index.ts","../../../src/presets/harness/harness-loop.ts","../../../src/base/sources/settled.ts","../../../src/base/resilience/retry.ts","../../../src/utils/ai/prompts/prompt-node.ts","../../../src/utils/orchestration/pipeline-graph.ts","../../../src/utils/ai/agents/chat-stream.ts","../../../src/utils/ai/agents/tool-execution.ts","../../../src/utils/ai/agents/tool-registry.ts","../../../src/base/utils/decay.ts","../../../src/utils/harness/_internal.ts","../../../src/utils/harness/defaults.ts","../../../src/utils/harness/strategy.ts","../../../src/utils/orchestration/audited-success-tracker.ts","../../../src/utils/harness/types.ts","../../../src/utils/job-queue/index.ts","../../../src/presets/harness/ownership-controller.ts","../../../src/presets/harness/profile.ts","../../../src/presets/harness/spawnable.ts","../../../src/presets/ai/agents.ts","../../../src/presets/ai/agent.ts","../../../src/presets/ai/agent-loop.ts","../../../src/presets/harness/trace.ts"],"sourcesContent":["/**\n * Internal helpers shared by resilience sub-files.\n *\n * Not part of the public surface. The base-layer resilience operators\n * co-located here (`retry.ts`, `status.ts`, `timeout.ts`) import what they\n * need from this file directly; the utils-layer resilience primitives that\n * stayed in `utils/resilience/` (`breaker.ts`, `rate-limiter.ts`,\n * `fallback.ts`) import it top-down via `../../base/resilience/_internal.js`.\n *\n * `NodeOrValue<T>` is the only export re-surfaced publicly — there is no\n * `base/resilience/index.ts`; it ships through `utils/resilience/index.ts`\n * (and `utils/memory/index.ts`). Every resilience primitive that accepts\n * reactive options uses it as the option-arg shape.\n */\n\nimport type { Node, NodeOptions } from \"@graphrefly/pure-ts/core\";\nimport { DATA, type Message } from \"@graphrefly/pure-ts/core\";\n\nexport type ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nexport function operatorOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\nexport function clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nexport function msgVal(m: Message): unknown {\n\treturn m[1];\n}\n\nexport function coerceDelayNs(raw: number): number {\n\tif (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n\t\tthrow new TypeError(\"backoff strategy must return a finite number\");\n\t}\n\treturn raw < 0 ? 0 : raw;\n}\n\nexport function isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\t\"cache\" in x &&\n\t\ttypeof (x as Node).subscribe === \"function\"\n\t);\n}\n\n/**\n * Either a literal value or a reactive Node carrying it. Mirrors\n * {@link FallbackInput}'s precedent for \"options that may be reactive.\"\n *\n * Used by {@link timeout} / {@link retry} / {@link rateLimiter} /\n * {@link circuitBreaker} / {@link budgetGate} to accept reactive option\n * configurations (Tier 6.5 3.2, 2026-04-29). Each primitive subscribes\n * to the option Node via {@link resolveReactiveOption} and rebinds\n * internal state per its locked swap-semantic rule (see each primitive's\n * JSDoc for the rule).\n *\n * @category extra\n */\nexport type NodeOrValue<T> = T | Node<T>;\n\n/**\n * Closure-mirror helper for `NodeOrValue<T>` options\n * (COMPOSITION-GUIDE §28). Returns:\n * - `current()` — read the latest value (cached at construction; updated\n * on each Node DATA emission).\n * - `unsub()` — release the subscription. Static-form arg never\n * subscribes; `unsub` is a no-op there.\n *\n * `onChange` fires on each DATA after the initial value (skips the\n * cache-seed read). Use to rebind primitive-internal state per the\n * primitive's locked swap-semantic rule.\n *\n * @internal\n */\nexport function resolveReactiveOption<T>(\n\targ: NodeOrValue<T>,\n\tonChange?: (next: T) => void,\n): { current: () => T; unsub: () => void } {\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg, unsub: () => undefined };\n\t}\n\tconst node = arg as Node<T>;\n\tlet latest: T = node.cache as T;\n\tconst unsub = node.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tlatest = m[1] as T;\n\t\t\t\tif (onChange) onChange(latest);\n\t\t\t}\n\t\t}\n\t});\n\treturn {\n\t\tcurrent: () => latest,\n\t\tunsub,\n\t};\n}\n\nexport function isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nexport function isAsyncIterable(x: unknown): x is AsyncIterable<unknown> {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\ttypeof (x as AsyncIterable<unknown>)[Symbol.asyncIterator] === \"function\"\n\t);\n}\n","/**\n * Backoff strategies for {@link retry} (roadmap §3.1). Delays are in **nanoseconds**.\n *\n * Convention: all graphrefly-ts timestamps and durations use nanoseconds (`_ns` suffix).\n * 1 second = 1_000_000_000 ns, 1 ms = 1_000_000 ns.\n */\n\nexport const NS_PER_MS = 1_000_000;\nexport const NS_PER_SEC = 1_000_000_000;\n\nexport type JitterMode = \"none\" | \"full\" | \"equal\";\n\nexport type BackoffPreset =\n\t| \"constant\"\n\t| \"linear\"\n\t| \"exponential\"\n\t| \"fibonacci\"\n\t| \"decorrelatedJitter\";\n\n/** `(attempt, error?, previousDelayNs?) => delayNs | null` — `null` means zero delay. */\nexport type BackoffStrategy = (\n\tattempt: number,\n\terror?: unknown,\n\tprevDelayNs?: number | null,\n) => number | null;\n\nfunction clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nfunction applyJitter(delay: number, jitter: JitterMode): number {\n\tif (jitter === \"none\") return delay;\n\tif (jitter === \"full\") return Math.random() * delay;\n\treturn delay / 2 + Math.random() * (delay / 2);\n}\n\nfunction randomBetween(min: number, max: number): number {\n\treturn min + Math.random() * (max - min);\n}\n\n/**\n * Builds a strategy that always returns the same delay in nanoseconds.\n *\n * @param delayNs - Non-negative delay in nanoseconds; values below zero are clamped to zero.\n * @returns `BackoffStrategy` for use with {@link retry} or custom timers.\n *\n * @example\n * ```ts\n * import { constant, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: constant(0.25 * NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function constant(delayNs: number): BackoffStrategy {\n\tconst safe = clampNonNegative(delayNs);\n\treturn () => safe;\n}\n\n/**\n * Builds linear backoff: `baseNs + stepNs * attempt` (`stepNs` defaults to `baseNs`).\n *\n * @param baseNs - Base delay in nanoseconds (clamped non-negative).\n * @param stepNs - Added per retry attempt in nanoseconds (clamped non-negative).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { linear, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // Attempt 0 → 1 s, attempt 1 → 2 s, attempt 2 → 3 s …\n * const out = retry(source, { count: 4, backoff: linear(NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function linear(baseNs: number, stepNs?: number): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeStep = stepNs === undefined ? safeBase : clampNonNegative(stepNs);\n\treturn (attempt: number) => safeBase + safeStep * Math.max(0, attempt);\n}\n\nexport type ExponentialBackoffOptions = {\n\tbaseNs?: number;\n\tfactor?: number;\n\tmaxDelayNs?: number;\n\tjitter?: JitterMode;\n};\n\n/**\n * Builds exponential backoff in nanoseconds, capped by `maxDelayNs`, with optional jitter.\n *\n * @param options - Base, factor, cap, and jitter mode.\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @remarks\n * **Jitter:** `\"full\"` spreads delay across `[0, delay]`; `\"equal\"` uses `[delay/2, delay]`.\n *\n * @example\n * ```ts\n * import { exponential, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // 100 ms → 200 ms → 400 ms … capped at 30 s, with full jitter\n * const out = retry(source, {\n * count: 5,\n * backoff: exponential({ baseNs: 100 * NS_PER_SEC / 1000, jitter: \"full\" }),\n * });\n * ```\n *\n * @category extra\n */\nexport function exponential(options?: ExponentialBackoffOptions): BackoffStrategy {\n\tconst baseNs = clampNonNegative(options?.baseNs ?? 100 * NS_PER_MS);\n\tconst factor = options?.factor !== undefined && options.factor < 1 ? 1 : (options?.factor ?? 2);\n\tconst maxDelayNs = clampNonNegative(options?.maxDelayNs ?? 30 * NS_PER_SEC);\n\tconst jitter = options?.jitter ?? \"none\";\n\n\treturn (attempt: number) => {\n\t\tlet delay: number;\n\t\tif (baseNs === 0) {\n\t\t\tdelay = 0;\n\t\t} else if (factor === 1) {\n\t\t\tdelay = baseNs;\n\t\t} else {\n\t\t\tconst capRatio = maxDelayNs / baseNs;\n\t\t\tlet growth = 1;\n\t\t\tfor (let i = 0; i < Math.max(0, attempt); i++) {\n\t\t\t\tif (growth >= capRatio) {\n\t\t\t\t\tgrowth = capRatio;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tgrowth *= factor;\n\t\t\t}\n\t\t\tdelay = baseNs * growth;\n\t\t\tif (delay > maxDelayNs) delay = maxDelayNs;\n\t\t}\n\t\treturn applyJitter(delay, jitter);\n\t};\n}\n\n/**\n * Builds Fibonacci-scaled delays: `1, 2, 3, 5, … × baseNs`, capped at `maxDelayNs`.\n *\n * @param baseNs - Multiplier applied to the Fibonacci unit (default `100ms` in nanoseconds).\n * @param maxDelayNs - Upper bound in nanoseconds (default `30s`).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { fibonacci, retry, NS_PER_MS } from \"@graphrefly/graphrefly-ts\";\n *\n * // Delays: 100 ms, 200 ms, 300 ms, 500 ms, 800 ms … (× 100 ms base)\n * const out = retry(source, { count: 5, backoff: fibonacci(100 * NS_PER_MS) });\n * ```\n *\n * @category extra\n */\nexport function fibonacci(baseNs = 100 * NS_PER_MS, maxDelayNs = 30 * NS_PER_SEC): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeMax = clampNonNegative(maxDelayNs);\n\n\tfunction fibUnit(attempt: number): number {\n\t\tif (attempt <= 0) return 1;\n\t\tlet prev = 1;\n\t\tlet cur = 2;\n\t\tfor (let i = 1; i < attempt; i++) {\n\t\t\tconst next = prev + cur;\n\t\t\tprev = cur;\n\t\t\tcur = next;\n\t\t}\n\t\treturn cur;\n\t}\n\n\treturn (attempt: number) => {\n\t\tconst raw = fibUnit(attempt) * safeBase;\n\t\treturn raw <= safeMax ? raw : safeMax;\n\t};\n}\n\n/**\n * Decorrelated jitter (AWS-recommended): `random(baseNs, min(maxNs, lastDelay * 3))`.\n *\n * Stateless — uses `prevDelayNs` (passed by the consumer) instead of closure state.\n * Safe to share across concurrent retry sequences.\n *\n * @param baseNs - Floor of the random range (default `100ms` in nanoseconds).\n * @param maxNs - Ceiling cap (default `30s` in nanoseconds).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { decorrelatedJitter, retry, NS_PER_MS, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, {\n * count: 6,\n * backoff: decorrelatedJitter(100 * NS_PER_MS, 10 * NS_PER_SEC),\n * });\n * ```\n *\n * @category extra\n */\nexport function decorrelatedJitter(\n\tbaseNs = 100 * NS_PER_MS,\n\tmaxNs = 30 * NS_PER_SEC,\n): BackoffStrategy {\n\treturn (_attempt, _error, prevDelayNs) => {\n\t\tconst last = prevDelayNs ?? baseNs;\n\t\tconst ceiling = Math.min(maxNs, last * 3);\n\t\treturn randomBetween(baseNs, ceiling);\n\t};\n}\n\n/**\n * Decorator that caps any strategy at `maxAttempts`. Returns `null` (stop retrying) after the cap.\n *\n * @param strategy - Inner strategy to wrap.\n * @param maxAttempts - Maximum number of attempts (inclusive).\n * @returns Wrapped `BackoffStrategy`.\n *\n * @example\n * ```ts\n * import { withMaxAttempts, exponential } from \"@graphrefly/graphrefly-ts\";\n *\n * const capped = withMaxAttempts(exponential(), 3);\n * capped(3); // null — no more retries beyond attempt 3\n * ```\n *\n * @category extra\n */\nexport function withMaxAttempts(strategy: BackoffStrategy, maxAttempts: number): BackoffStrategy {\n\treturn (attempt, error, prevDelayNs) => {\n\t\tif (attempt >= maxAttempts) return null;\n\t\treturn strategy(attempt, error, prevDelayNs);\n\t};\n}\n\n/**\n * Maps a preset name to a concrete {@link BackoffStrategy} with library-default parameters.\n *\n * @param name - One of `constant`, `linear`, `exponential`, `fibonacci`, or `decorrelatedJitter`.\n * @returns Configured strategy with default parameters.\n * @throws Error when `name` is not a known preset.\n *\n * @example\n * ```ts\n * import { resolveBackoffPreset, retry } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: resolveBackoffPreset(\"exponential\") });\n * // Equivalent to retry(source, { count: 3, backoff: exponential() })\n * ```\n *\n * @category extra\n */\nexport function resolveBackoffPreset(name: BackoffPreset): BackoffStrategy {\n\tif (name === \"constant\") return constant(1 * NS_PER_SEC);\n\tif (name === \"linear\") return linear(1 * NS_PER_SEC);\n\tif (name === \"exponential\") return exponential();\n\tif (name === \"fibonacci\") return fibonacci();\n\tif (name === \"decorrelatedJitter\") return decorrelatedJitter();\n\tthrow new Error(\n\t\t`Unknown backoff preset: \"${String(name)}\". Use one of: constant, linear, exponential, fibonacci, decorrelatedJitter`,\n\t);\n}\n","/**\n * Timeout — emits `ERROR` with `TimeoutError` if no `DATA` arrives within the deadline.\n *\n * §3.1c — caching, fallback & composition sugar. Uses\n * `core/clock.js`-style nanoseconds and a `ResettableTimer` so the deadline\n * resets on each DATA. Distinct from the `operators/control.ts` timeout\n * (which forwards a caller-supplied error/value) — this one is the\n * resilience family's \"deadline → ERROR\" primitive.\n *\n * **DS-13.5.B (locked 2026-05-01).** Pre-1.0 break: returns\n * {@link TimeoutBundle} with `node` + `timeoutState` companion. Opts\n * accept `Partial<TimeoutOptions>` or `Node<Partial<TimeoutOptions>>`\n * (object-shape, replacing the old `NodeOrValue<number>` flat shape).\n * State preservation across rebind: `ns` change does NOT reset the\n * in-flight deadline — new `ns` applies to next attempt only.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\tmonotonicNs,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport { isNode, operatorOpts } from \"./_internal.js\";\nimport { NS_PER_MS } from \"./backoff.js\";\n\n/**\n * Thrown by {@link withTimeout} when no `DATA` arrives within the deadline.\n *\n * @category extra\n */\nexport class TimeoutError extends Error {\n\toverride name = \"TimeoutError\";\n\tconstructor(ns: number) {\n\t\tsuper(`Timed out after ${ns / NS_PER_MS}ms`);\n\t}\n}\n\n/**\n * Options accepted by {@link withTimeout}.\n *\n * - `ns` — deadline in nanoseconds (must be `> 0`). Required at the\n * first opts settle; missing / non-positive values throw at\n * construction.\n * - `meta` — optional metadata merged onto the result node's `meta`\n * for describe()/explain() introspection. Reactive `meta` updates\n * are picked up on the next attempt's emission.\n *\n * @category extra/resilience\n */\nexport interface TimeoutOptions {\n\tns: number;\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Lifecycle-shaped state companion emitted by {@link withTimeout}.\n *\n * Default `equals` dedups on the `status` field — subscribers don't\n * re-fire on identical-shape transitions, but DO fire on every state\n * transition AND on payload changes within the same status (e.g. when\n * `running.startedAt_ns` advances on a fresh attempt).\n *\n * @category extra/resilience\n */\nexport type TimeoutState =\n\t| { status: \"pending\" }\n\t| { status: \"running\"; startedAt_ns: number; deadline_ns: number }\n\t| { status: \"completed\"; settledAt_ns: number }\n\t| { status: \"errored\"; firedAt_ns: number; deadline_ns: number };\n\n/**\n * Bundle returned by {@link withTimeout}: the timeout-wrapped output node and\n * its lifecycle-shaped state companion.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `timeoutState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `timeoutState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `timeoutState`, which can flip\n * between states from different in-flight machines. Don't fan out\n * `node` to multiple subscribers and rely on `timeoutState` accuracy\n * unless you use {@link keepalive} / {@link share}-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface TimeoutBundle<T> {\n\tnode: Node<T>;\n\ttimeoutState: Node<TimeoutState>;\n}\n\ninterface TimeoutExtraOpts {\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Wrap `source` with a deadline. If no `DATA` arrives within `opts.ns`\n * nanoseconds, the result node emits `[[ERROR, TimeoutError]]` and\n * transitions `timeoutState` to `\"errored\"`.\n *\n * The timer starts on subscription and resets on each `DATA`. `DIRTY`\n * does NOT reset the timer. Terminal messages (`COMPLETE` / `ERROR`)\n * cancel the timer.\n *\n * **Reactive opts (DS-13.5.B, locked 2026-05-01).**\n *\n * - Static-form callers pass `Partial<TimeoutOptions>` (today's path).\n * `ns` is validated at construction; missing / non-positive throws\n * `RangeError`.\n * - Reactive-form callers pass `Node<Partial<TimeoutOptions>>` — each\n * emission shallow-merges over the prior opts. Empty `{}` emissions\n * are no-ops (no rebind, no companion fire). Mid-flight opts swap\n * does NOT reset the in-flight deadline; new `ns` applies to the\n * next `startTimer()` call.\n * - When the opts Node has `cache === undefined` (SENTINEL: no opts\n * emitted yet), the source is paused until the first valid opts\n * settle. The first valid settle must carry `ns > 0` or the timer\n * layer emits an ERROR (downstream observable) — distinct from the\n * construction-time `RangeError` thrown for static / cache-defined\n * invalid values.\n *\n * @param source - Upstream node.\n * @param opts - `Partial<TimeoutOptions>` (static) or\n * `Node<Partial<TimeoutOptions>>` (reactive).\n * @param extraOpts - Forwarded factory metadata (meta field merged\n * onto the result node).\n * @returns {@link TimeoutBundle} with `node` and `timeoutState`.\n *\n * @throws {RangeError} when the first opts settle is missing or has\n * non-positive `ns`.\n *\n * @category extra\n */\nexport function withTimeout<T>(\n\tsource: Node<T>,\n\topts: Partial<TimeoutOptions> | Node<Partial<TimeoutOptions>>,\n\textraOpts?: TimeoutExtraOpts,\n): TimeoutBundle<T> {\n\tconst isReactive = isNode(opts);\n\n\t// Construction-time validation:\n\t// - Static form: validate the supplied object eagerly.\n\t// - Node form with defined cache: validate the cache value eagerly.\n\t// - Node form with `cache === undefined`: defer validation to first\n\t// DATA emission; source is paused in the meantime.\n\tlet latestOpts: TimeoutOptions | null = null;\n\tif (!isReactive) {\n\t\tconst staticOpts = opts as Partial<TimeoutOptions>;\n\t\tif (\n\t\t\tstaticOpts.ns === undefined ||\n\t\t\ttypeof staticOpts.ns !== \"number\" ||\n\t\t\t!Number.isFinite(staticOpts.ns) ||\n\t\t\tstaticOpts.ns <= 0\n\t\t) {\n\t\t\tthrow new RangeError(\"withTimeout: opts.ns must be a positive finite number\");\n\t\t}\n\t\tlatestOpts = {\n\t\t\tns: staticOpts.ns,\n\t\t\t...(staticOpts.meta != null ? { meta: staticOpts.meta } : {}),\n\t\t};\n\t} else {\n\t\tconst cached = (opts as Node<Partial<TimeoutOptions>>).cache as\n\t\t\t| Partial<TimeoutOptions>\n\t\t\t| undefined;\n\t\tif (cached !== undefined) {\n\t\t\tif (\n\t\t\t\tcached.ns === undefined ||\n\t\t\t\ttypeof cached.ns !== \"number\" ||\n\t\t\t\t!Number.isFinite(cached.ns) ||\n\t\t\t\tcached.ns <= 0\n\t\t\t) {\n\t\t\t\tthrow new RangeError(\n\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tlatestOpts = {\n\t\t\t\tns: cached.ns,\n\t\t\t\t...(cached.meta != null ? { meta: cached.meta } : {}),\n\t\t\t};\n\t\t}\n\t}\n\n\tconst callerMeta = extraOpts?.meta;\n\tconst factoryArgs: Record<string, unknown> = isReactive\n\t\t? { ns: \"Node<Partial<TimeoutOptions>>\" }\n\t\t: { ns: latestOpts!.ns };\n\n\t// Companion state node — lifecycle-shaped. Default Object.is-on-status\n\t// dedup so identical-shape transitions don't re-fire downstream.\n\tconst timeoutState = node<TimeoutState>([], {\n\t\tname: \"timeoutState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\" },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\t(a as { status: string }).status === (b as { status: string }).status &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\n\tconst out = node<T>(\n\t\t(_data, a) => {\n\t\t\tlet stopped = false;\n\t\t\tlet lastDeadlineNs = 0;\n\t\t\tconst timer = new ResettableTimer();\n\t\t\tlet optsUnsub: (() => void) | null = null;\n\t\t\tlet srcUnsub: (() => void) | null = null;\n\n\t\t\tfunction emitState(next: TimeoutState): void {\n\t\t\t\ttimeoutState.down([[DIRTY], [DATA, next]]);\n\t\t\t}\n\n\t\t\tfunction startTimer(): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\t// QA A4 (2026-05-03): defensive guard — `latestOpts.ns`\n\t\t\t\t// reaching `undefined` / `NaN` / non-finite is a Class-of-\n\t\t\t\t// bugs source: an explicit `{ ns: undefined }` emit would\n\t\t\t\t// pass the per-key validation (which only checks\n\t\t\t\t// `next.ns !== undefined`) and shallow-merge over a valid\n\t\t\t\t// prior `ns`. Without this guard, `delayMs = NaN`, which\n\t\t\t\t// `setTimeout` treats as `0` → spurious immediate timeout.\n\t\t\t\tif (\n\t\t\t\t\tlatestOpts == null ||\n\t\t\t\t\ttypeof latestOpts.ns !== \"number\" ||\n\t\t\t\t\t!Number.isFinite(latestOpts.ns) ||\n\t\t\t\t\tlatestOpts.ns <= 0\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst ns = latestOpts.ns;\n\t\t\t\tlastDeadlineNs = ns;\n\t\t\t\tconst startedAt = monotonicNs();\n\t\t\t\tconst delayMs = ns / NS_PER_MS;\n\t\t\t\temitState({\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\tstartedAt_ns: startedAt,\n\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t});\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tsrcUnsub?.();\n\t\t\t\t\temitState({\n\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t\t});\n\t\t\t\t\ta.down([[ERROR, new TimeoutError(ns)]]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction attachSource(): void {\n\t\t\t\tif (srcUnsub != null || stopped) return;\n\t\t\t\tsrcUnsub = source.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (stopped) return;\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tstartTimer();\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\t\tsettledAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t\tdeadline_ns: lastDeadlineNs,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// Kick the initial timer if we already have valid opts.\n\t\t\t\tif (latestOpts != null && latestOpts.ns > 0) {\n\t\t\t\t\tstartTimer();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isReactive) {\n\t\t\t\tconst optsNode = opts as Node<Partial<TimeoutOptions>>;\n\t\t\t\toptsUnsub = optsNode.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\t\tconst next = m[1] as Partial<TimeoutOptions>;\n\t\t\t\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\t\t\t\t// Empty `{}` emit is a no-op (lock spec).\n\t\t\t\t\t\tconst keys = Object.keys(next);\n\t\t\t\t\t\tif (keys.length === 0) continue;\n\t\t\t\t\t\t// QA A4 (2026-05-03): validate ns whenever it APPEARS\n\t\t\t\t\t\t// in the emit's keys — including `{ ns: undefined }`,\n\t\t\t\t\t\t// which would otherwise skip validation and shallow-\n\t\t\t\t\t\t// merge over a valid prior `ns` with `undefined`,\n\t\t\t\t\t\t// producing `delayMs = NaN` ≈ 0 ms in startTimer().\n\t\t\t\t\t\t// `'ns' in next` covers both \"explicitly undefined\"\n\t\t\t\t\t\t// and \"explicitly invalid\" forms.\n\t\t\t\t\t\tif (\"ns\" in next) {\n\t\t\t\t\t\t\tif (typeof next.ns !== \"number\" || !Number.isFinite(next.ns) || next.ns <= 0) {\n\t\t\t\t\t\t\t\tif (latestOpts == null) {\n\t\t\t\t\t\t\t\t\t// First settle invalid — emit ERROR rather\n\t\t\t\t\t\t\t\t\t// than throw (mid-subscribe; sync throw\n\t\t\t\t\t\t\t\t\t// would corrupt the host scheduler).\n\t\t\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\t\t\ta.down([\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\tERROR,\n\t\t\t\t\t\t\t\t\t\t\tnew RangeError(\n\t\t\t\t\t\t\t\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Ignore invalid mid-flight ns updates; keep\n\t\t\t\t\t\t\t\t// prior latestOpts.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst wasNull = latestOpts == null;\n\t\t\t\t\t\tlatestOpts = {\n\t\t\t\t\t\t\t...(latestOpts ?? { ns: 0 }),\n\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t} as TimeoutOptions;\n\t\t\t\t\t\t// First valid settle activates the source attach.\n\t\t\t\t\t\tif (wasNull && latestOpts.ns > 0) {\n\t\t\t\t\t\t\tattachSource();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Static form: attach immediately. Reactive form with defined\n\t\t\t// cache also attaches immediately (latestOpts pre-populated).\n\t\t\tif (latestOpts != null) {\n\t\t\t\tattachSource();\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tstopped = true;\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tif (srcUnsub) srcUnsub();\n\t\t\t\t\tif (optsUnsub) optsUnsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: { ...(callerMeta ?? {}), ...factoryTag(\"withTimeout\", factoryArgs) },\n\t\t},\n\t);\n\n\treturn { node: out, timeoutState };\n}\n","/**\n * Harness presets — opinionated compositions of harness + ai utils.\n *\n * @module\n */\n\nexport * from \"./actor-pool.js\";\nexport * from \"./eval-verifier.js\";\nexport * from \"./harness-loop.js\";\nexport * from \"./ownership-controller.js\";\nexport * from \"./profile.js\";\nexport * from \"./refine-executor.js\";\nexport * from \"./refine-loop.js\";\nexport * from \"./spawnable.js\";\nexport * from \"./trace.js\";\n","/**\n * DS-14.6.A U-B — `actorPool()` (Phase 14.5).\n *\n * The dynamic-track complement to `spawnable()` (SESSION-DS-14.6-A L7/L8 +\n * 9Q walk). An actor is **identity + cursor + tool closure, NOT a subgraph**\n * (D-B1): no per-actor mount, so `describe()` shows only the pool / todo /\n * context-hub collections and the actor count drifts inside a single\n * reactive `active` map node. `depthCap` is enforced via the depth carried\n * on the attach request (D-B2); `release()` cascades teardown to the\n * actor's context view + todo cursor subscriptions (§3i — free).\n *\n * Contrast `spawnable()`: agent IS a subgraph, topology reflects the agent\n * set, `describe()`-visible — use it when agent identities are pre-known.\n * Use `actorPool()` for runtime recursive fan-out where agent count drifts.\n *\n * @module\n */\n\nimport { type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport {\n\ttype ContextEntry,\n\ttype ContextView,\n\ttype RenderedEntry,\n\trenderContextView,\n\ttype TaggedContextPoolBundle,\n\ttaggedContextPool,\n} from \"../ai/context/index.js\";\n\nexport type ActorId = string;\n\nexport interface Todo {\n\treadonly id: string;\n\treadonly assignee?: ActorId;\n\treadonly payload: unknown;\n}\n\nexport type ActorStatus = \"idle\" | \"running\" | \"blocked\" | \"done\";\n\nexport interface ActorState {\n\treadonly id: ActorId;\n\treadonly depth: number;\n\treadonly status: ActorStatus;\n}\n\nexport interface ActorSpec<T> {\n\treadonly id?: ActorId;\n\t/** Recursion depth — gated against `depthCap` (D-B2). Default 0 (root). */\n\treadonly depth?: number;\n\t/** Per-actor compression view over the shared context pool. */\n\treadonly view: Omit<ContextView<T>, \"pressure\"> & { readonly pressure: Node<number> };\n}\n\nexport interface ActorHandle<T> {\n\treadonly id: ActorId;\n\t/** This actor's compressed context slice. */\n\treadonly context: Node<readonly RenderedEntry<T>[]>;\n\t/** Todos currently assigned to this actor (or unassigned). */\n\treadonly todoCursor: Node<readonly Todo[]>;\n\t/** Write an entry into the shared pool, stamped with this actor's id tag. */\n\tpublish(entry: Omit<ContextEntry<T>, \"id\" | \"t_ns\"> & { id?: string }): string;\n\tenqueueTodo(t: Todo): void;\n\treadonly status: Node<ActorStatus>;\n\tsetStatus(s: ActorStatus): void;\n\t/** Idempotent. Tears the actor's subscriptions + removes it from `active`. */\n\trelease(): void;\n}\n\nexport interface ActorPoolOptions<T> {\n\treadonly name?: string;\n\t/** Max recursion depth; `attachActor` with `depth > depthCap` throws. */\n\treadonly depthCap?: number;\n\t/** Forwarded to the backing context pool. */\n\treadonly contextTopic?: string;\n\treadonly llmCompress?: TaggedContextPoolBundle<T>[\"_opts\"][\"llmCompress\"];\n}\n\nexport interface ActorPoolBundle<T> {\n\tattachActor(spec: ActorSpec<T>): ActorHandle<T>;\n\treadonly contextPool: TaggedContextPoolBundle<T>;\n\treadonly todos: ReactiveLogBundle<Todo>;\n\t/** Single reactive map of live actors — `describe()`-coherent (D-B1). */\n\treadonly active: Node<ReadonlyMap<ActorId, ActorState>>;\n\treadonly graph: Graph;\n\tdispose(): void;\n}\n\n/** Process-wide sequence for collision-safe default mount names (QA P6). */\nlet _actorPoolSeq = 0;\n\nexport function actorPool<T = unknown>(\n\tparent: Graph,\n\topts: ActorPoolOptions<T> = {},\n): ActorPoolBundle<T> {\n\t// QA P6: collision-safe default — recursive fan-out spins nested pools\n\t// under one parent; static \"actorPool\" would collide on `parent.mount`.\n\tconst name = opts.name ?? `actorPool-${++_actorPoolSeq}`;\n\tconst graph = new Graph(name);\n\tparent.mount(name, graph);\n\tconst depthCap = opts.depthCap ?? Number.POSITIVE_INFINITY;\n\t// QA P5: per-pool actor counter (was module-global → test-pollution).\n\tlet autoActor = 0;\n\t// QA P7: track live handles so dispose() can release them all.\n\tconst liveHandles = new Set<ActorHandle<T>>();\n\n\tconst contextPool = taggedContextPool<T>(graph, {\n\t\ttopic: opts.contextTopic ?? \"context\",\n\t\tllmCompress: opts.llmCompress,\n\t\tname: `${name}.ctx`,\n\t});\n\tconst todos: ReactiveLogBundle<Todo> = reactiveLog<Todo>(undefined, { name: `${name}.todos` });\n\n\t// Single reactive `active` map node — actor count drifts inside it; no\n\t// per-actor subgraph mount (D-B1, describe-coherent).\n\tconst stateMap = new Map<ActorId, ActorState>();\n\tconst active = node<ReadonlyMap<ActorId, ActorState>>([], {\n\t\tname: `${name}.active`,\n\t\tinitial: new Map(),\n\t});\n\tfunction pushActive(): void {\n\t\tactive.emit(new Map(stateMap));\n\t}\n\n\tfunction attachActor(spec: ActorSpec<T>): ActorHandle<T> {\n\t\tconst depth = spec.depth ?? 0;\n\t\tif (depth > depthCap) {\n\t\t\tthrow new RangeError(`actorPool: depth ${depth} exceeds depthCap ${depthCap}`);\n\t\t}\n\t\tconst id = spec.id ?? `actor-${++autoActor}`;\n\n\t\tconst context = renderContextView(contextPool, spec.view as ContextView<T>);\n\t\t// Per-actor todo cursor — assigned-to-me or unassigned.\n\t\tconst todoCursor = node<readonly Todo[]>(\n\t\t\t[todos.entries as Node],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\tconst all = (data[0] != null && data[0].length > 0 ? data[0].at(-1) : ctx.prevData[0]) as\n\t\t\t\t\t| readonly Todo[]\n\t\t\t\t\t| undefined;\n\t\t\t\tactions.emit((all ?? []).filter((t) => t.assignee === id || t.assignee === undefined));\n\t\t\t},\n\t\t\t{ describeKind: \"derived\" },\n\t\t);\n\t\tconst status = node<ActorStatus>([], { name: `${name}.${id}.status`, initial: \"idle\" });\n\n\t\tstateMap.set(id, { id, depth, status: \"idle\" });\n\t\tpushActive();\n\n\t\t// Keepalive subs so `.cache` stays warm; torn on release (cascade-cancel).\n\t\tconst subs = [\n\t\t\tcontext.subscribe(() => {}),\n\t\t\ttodoCursor.subscribe(() => {}),\n\t\t\tstatus.subscribe(() => {}),\n\t\t];\n\t\tlet released = false;\n\n\t\tconst handle: ActorHandle<T> = {\n\t\t\tid,\n\t\t\tcontext,\n\t\t\ttodoCursor,\n\t\t\tstatus,\n\t\t\tpublish(entry) {\n\t\t\t\tconst tags = [...(entry.tags ?? []), `actor:${id}`];\n\t\t\t\treturn contextPool.add({ ...entry, tags });\n\t\t\t},\n\t\t\tenqueueTodo(t) {\n\t\t\t\ttodos.append(t);\n\t\t\t},\n\t\t\tsetStatus(s) {\n\t\t\t\tstatus.emit(s);\n\t\t\t\tconst prev = stateMap.get(id);\n\t\t\t\tif (prev) {\n\t\t\t\t\tstateMap.set(id, { ...prev, status: s });\n\t\t\t\t\tpushActive();\n\t\t\t\t}\n\t\t\t},\n\t\t\trelease() {\n\t\t\t\tif (released) return;\n\t\t\t\treleased = true;\n\t\t\t\t// Cascade-cancel: tearing the keepalive subs deactivates the\n\t\t\t\t// per-actor derived nodes (lazy-deactivation — COMPOSITION-GUIDE\n\t\t\t\t// §1), detaching `context`/`todoCursor`/`status` from the shared\n\t\t\t\t// pool/todos logs once no other subscriber remains.\n\t\t\t\tfor (const u of subs) u();\n\t\t\t\tstateMap.delete(id);\n\t\t\t\tliveHandles.delete(handle);\n\t\t\t\tpushActive();\n\t\t\t},\n\t\t};\n\t\tliveHandles.add(handle);\n\t\treturn handle;\n\t}\n\n\treturn {\n\t\tattachActor,\n\t\tcontextPool,\n\t\ttodos,\n\t\tactive,\n\t\tgraph,\n\t\tdispose(): void {\n\t\t\t// QA P7: release outstanding actors first (tears their keepalive\n\t\t\t// subs / deactivates per-actor derived nodes) before disposing the\n\t\t\t// shared pool + todo log.\n\t\t\tfor (const h of [...liveHandles]) h.release();\n\t\t\tcontextPool.dispose();\n\t\t\ttodos.dispose();\n\t\t},\n\t};\n}\n","/**\n * DS-14.6.A U-A — tagged context substrate (Phase 14.5).\n *\n * Per-view tagged context (SESSION-DS-14.6-A L3–L6 + SESSION-DS-14.6-A-9Q\n * implementation walk). Pool stores immutable tier-0 originals on an\n * **append-only `reactiveLog`** (D-A4 — structural tier-0 immutability, free\n * `LogChange` mutations, side-steps the DS14R1 TTL/LRU prune-fidelity bug).\n * Each consumer holds a `ContextView` that materialises its own filtered +\n * compressed slice (`Node<readonly RenderedEntry[]>`). Routing is mechanical\n * tag comparison (zero LLM); only `llm-summary` rules cross to an injected\n * `llmCompress` (D-A3). Compression cache is one shared `(id, tier)` map in\n * the pool bundle, bounded LRU (D-A5). Schema is pure data, presentation\n * layer (D-A1) — no `@graphrefly/pure-ts` consumer.\n *\n * @module\n */\n\nimport { type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../../../utils/ai/_internal.js\";\n\n// ── Schema (pure data — D-A1) ────────────────────────────────────────────────\n\nexport type Tag = string;\n\n/** Compression tier. 0 = original; higher = more compressed. */\nexport type Tier = 0 | 1 | 2 | 3;\n\nexport interface ContextEntry<T> {\n\t/** Stable id — cache key component `(id, tier)`. Auto-assigned if omitted. */\n\treadonly id: string;\n\treadonly payload: T;\n\treadonly tags: readonly Tag[];\n\t/** 0..1. Budget/GC ordering. */\n\treadonly importance: number;\n\treadonly compressible: boolean;\n\treadonly topic: string;\n\t/** Wall-clock at add (ns) — used by `poolGC({ olderThanNs })`. */\n\treadonly t_ns: number;\n}\n\nexport interface RuleMatch {\n\treadonly topic?: string | RegExp;\n\treadonly tagsAny?: readonly Tag[];\n\treadonly importanceMin?: number;\n\treadonly importanceMax?: number;\n\treadonly compressible?: boolean;\n}\n\nexport type CompressionRule =\n\t| { readonly match: RuleMatch; readonly action: \"evict\" }\n\t| { readonly match: RuleMatch; readonly action: \"truncate\"; readonly maxChars: number }\n\t| { readonly match: RuleMatch; readonly action: \"reference\" }\n\t| { readonly match: RuleMatch; readonly action: \"llm-summary\"; readonly toTier: Tier };\n\nexport interface RenderedEntry<T> {\n\treadonly id: string;\n\treadonly topic: string;\n\treadonly tags: readonly Tag[];\n\treadonly tier: Tier;\n\t/** Original payload at tier 0; compressed `string` otherwise. */\n\treadonly payload: T | string;\n\treadonly compressed: boolean;\n}\n\nexport interface ContextView<T> {\n\treadonly filter: (e: ContextEntry<T>) => boolean;\n\t/** 0..1. A rule fires when `pressure > 0` and the entry matches. */\n\treadonly pressure: Node<number>;\n\treadonly budgetTokens: number;\n\treadonly rules: readonly CompressionRule[];\n\t/** Default `s => Math.ceil(s.length / 4)`. */\n\treadonly tokenizer?: (s: string) => number;\n}\n\nexport interface PoolGCPolicy {\n\t/** Drop entries with `t_ns < (now - olderThanNs)`. */\n\treadonly olderThanNs?: number;\n\t/** Drop entries with `importance < importanceBelow`. */\n\treadonly importanceBelow?: number;\n\t/**\n\t * **Scope**, not a match-to-evict rule: when set, GC only considers\n\t * entries whose `topic === this`; entries of other topics always survive.\n\t * `olderThanNs` / `importanceBelow` are ANDed *within* this scope.\n\t */\n\treadonly topic?: string;\n\t/** Keep at most this many most-recent entries. */\n\treadonly max?: number;\n}\n\n/** `(entry, toTier) => compressedText`. Injected; required iff a view uses `llm-summary`. */\nexport type LlmCompress<T> = (entry: ContextEntry<T>, toTier: Tier) => string;\n\nexport interface TaggedContextPoolOptions<T> {\n\treadonly topic: string;\n\t/** Forwarded to the backing append-only `reactiveLog` (poolGC ceiling). */\n\treadonly maxEntries?: number;\n\t/** Required iff any rendered view uses an `llm-summary` rule (D-A3). */\n\treadonly llmCompress?: LlmCompress<T>;\n\t/** Shared `(id, tier)` compression cache cap (D-A5). Default 512. */\n\treadonly cacheMax?: number;\n\treadonly name?: string;\n}\n\nexport interface TaggedContextPoolBundle<T> {\n\t/**\n\t * Append an entry (immutable tier-0). Returns its id (auto-assigned\n\t * `ctx-N` per-pool if omitted).\n\t *\n\t * **Caller-supplied ids must be unique within the pool.** The log is\n\t * append-only and does NOT dedupe; the compression cache is keyed by\n\t * `(id, tier)`, so appending two different entries with the same explicit\n\t * `id` makes the second render the first's cached summary (QA P11).\n\t */\n\tadd(entry: Omit<ContextEntry<T>, \"id\" | \"t_ns\"> & { id?: string }): string;\n\t/** All live tier-0 entries. */\n\treadonly entries: Node<readonly ContextEntry<T>[]>;\n\t/** Entries carrying `tag`. */\n\tbyTag(tag: Tag): Node<readonly ContextEntry<T>[]>;\n\t/** Pool-global retention (L6 — distinct from per-view filtering). Returns removed count. */\n\tpoolGC(policy: PoolGCPolicy): number;\n\treadonly graph: Graph;\n\t/** Internal — shared compression cache (one per pool, D-A5). */\n\treadonly _cache: CompressionCache;\n\treadonly _opts: TaggedContextPoolOptions<T>;\n\tdispose(): void;\n}\n\n// ── Shared bounded (id,tier) compression cache (D-A5) ────────────────────────\n\n/**\n * Bounded LRU cache keyed by `(id, tier)`. Uses a nested `Map<id, Map<tier,\n * value>>` (NOT a `${id}::${tier}` string key) so a caller-supplied `id`\n * containing the separator cannot collide (QA P5). LRU is tracked at the\n * (id,tier) leaf via a flat insertion-order key list.\n */\nexport class CompressionCache {\n\tprivate readonly _m = new Map<string, Map<Tier, string>>();\n\t/** Insertion-order list of `id` keys for LRU eviction at the id granularity. */\n\tprivate readonly _order: string[] = [];\n\tconstructor(private readonly _max: number) {}\n\tget(id: string, tier: Tier): string | undefined {\n\t\tconst inner = this._m.get(id);\n\t\tconst v = inner?.get(tier);\n\t\tif (v !== undefined) {\n\t\t\tconst i = this._order.indexOf(id);\n\t\t\tif (i >= 0) this._order.splice(i, 1);\n\t\t\tthis._order.push(id);\n\t\t}\n\t\treturn v;\n\t}\n\tset(id: string, tier: Tier, value: string): void {\n\t\tlet inner = this._m.get(id);\n\t\tif (inner === undefined) {\n\t\t\tinner = new Map<Tier, string>();\n\t\t\tthis._m.set(id, inner);\n\t\t}\n\t\tinner.set(tier, value);\n\t\tconst i = this._order.indexOf(id);\n\t\tif (i >= 0) this._order.splice(i, 1);\n\t\tthis._order.push(id);\n\t\twhile (this._m.size > this._max) {\n\t\t\tconst evict = this._order.shift();\n\t\t\tif (evict === undefined) break;\n\t\t\tthis._m.delete(evict);\n\t\t}\n\t}\n}\n\n// ── Pool ─────────────────────────────────────────────────────────────────────\n\n/** Process-wide sequence for collision-safe default mount names (QA P6). */\nlet _poolSeq = 0;\n\n/**\n * Append-only tagged context pool (D-A4). The pool is a `reactiveLog` of\n * immutable tier-0 entries plus a derived `entries` node; `byTag` derives a\n * filtered view; `poolGC` is the explicit pool-global retention (L6).\n */\nexport function taggedContextPool<T>(\n\tparent: Graph,\n\topts: TaggedContextPoolOptions<T>,\n): TaggedContextPoolBundle<T> {\n\t// QA P6: collision-safe default mount name — two pools with the same\n\t// `topic` under one parent must not collide on `parent.mount`. Explicit\n\t// `opts.name` is respected verbatim (caller owns uniqueness then).\n\tconst mountName = opts.name ?? `ctxpool-${opts.topic}-${++_poolSeq}`;\n\tconst graph = new Graph(mountName);\n\tparent.mount(mountName, graph);\n\n\tconst log: ReactiveLogBundle<ContextEntry<T>> = reactiveLog<ContextEntry<T>>(undefined, {\n\t\tname: `${mountName}.log`,\n\t\tmaxSize: opts.maxEntries,\n\t});\n\tconst cache = new CompressionCache(opts.cacheMax ?? 512);\n\t// QA P5: per-pool id counter (was module-global → test-pollution +\n\t// cross-pool cache-key cross-talk).\n\tlet autoId = 0;\n\n\tconst entries: Node<readonly ContextEntry<T>[]> = log.entries;\n\n\tfunction add(e: Omit<ContextEntry<T>, \"id\" | \"t_ns\"> & { id?: string }): string {\n\t\tconst id = e.id ?? `ctx-${++autoId}`;\n\t\tlog.append({\n\t\t\tid,\n\t\t\tpayload: e.payload,\n\t\t\ttags: e.tags,\n\t\t\timportance: e.importance,\n\t\t\tcompressible: e.compressible,\n\t\t\ttopic: e.topic,\n\t\t\tt_ns: wallClockNs(), // QA P2 — clock.ts invariant (was Date.now()*1e6)\n\t\t});\n\t\treturn id;\n\t}\n\n\tfunction byTag(tag: Tag): Node<readonly ContextEntry<T>[]> {\n\t\treturn node<readonly ContextEntry<T>[]>(\n\t\t\t[entries as Node],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\tconst cur = (data[0] != null && data[0].length > 0 ? data[0].at(-1) : ctx.prevData[0]) as\n\t\t\t\t\t| readonly ContextEntry<T>[]\n\t\t\t\t\t| undefined;\n\t\t\t\tactions.emit((cur ?? []).filter((x) => x.tags.includes(tag)));\n\t\t\t},\n\t\t\t{ describeKind: \"derived\", meta: aiMeta(\"contextPool.byTag\", { tag }) },\n\t\t);\n\t}\n\n\tfunction poolGC(policy: PoolGCPolicy): number {\n\t\tconst all = log.entries.cache ?? [];\n\t\tconst nowNs = wallClockNs();\n\t\tlet survivors = all.filter((e) => {\n\t\t\t// QA P1: `topic` is a SCOPE, not a match-to-evict rule — entries\n\t\t\t// outside the topic are never GC'd by this call; eviction criteria\n\t\t\t// (olderThanNs / importanceBelow) are ANDed within the scope.\n\t\t\tif (policy.topic != null && e.topic !== policy.topic) return true;\n\t\t\tif (policy.olderThanNs != null && nowNs - e.t_ns >= policy.olderThanNs) return false;\n\t\t\tif (policy.importanceBelow != null && e.importance < policy.importanceBelow) return false;\n\t\t\treturn true;\n\t\t});\n\t\tif (policy.max != null && survivors.length > policy.max) {\n\t\t\tsurvivors = survivors.slice(survivors.length - policy.max);\n\t\t}\n\t\tconst removed = all.length - survivors.length;\n\t\tif (removed > 0) {\n\t\t\tlog.clear();\n\t\t\tlog.appendMany(survivors);\n\t\t}\n\t\treturn removed;\n\t}\n\n\treturn {\n\t\tadd,\n\t\tentries,\n\t\tbyTag,\n\t\tpoolGC,\n\t\tgraph,\n\t\t_cache: cache,\n\t\t_opts: opts,\n\t\tdispose(): void {\n\t\t\tlog.dispose();\n\t\t},\n\t};\n}\n\n// ── tierCompress + renderContextView ─────────────────────────────────────────\n\nconst DEFAULT_TOKENIZER = (s: string): number => Math.ceil(s.length / 4);\n\nfunction matches(e: ContextEntry<unknown>, m: RuleMatch): boolean {\n\tif (m.topic != null) {\n\t\tif (typeof m.topic === \"string\" ? e.topic !== m.topic : !m.topic.test(e.topic)) return false;\n\t}\n\tif (m.tagsAny != null && !m.tagsAny.some((t) => e.tags.includes(t))) return false;\n\tif (m.importanceMin != null && e.importance < m.importanceMin) return false;\n\tif (m.importanceMax != null && e.importance > m.importanceMax) return false;\n\tif (m.compressible != null && e.compressible !== m.compressible) return false;\n\treturn true;\n}\n\n/**\n * Apply the first matching rule to one entry under `pressure`. Non-LLM\n * strategies (truncate / evict / reference) are pure data; `llm-summary`\n * calls the injected `llmCompress`, caching by `(id, toTier)` (D-A5).\n * Returns `undefined` for evicted / pressure-filtered entries.\n */\nexport function tierCompress<T>(\n\te: ContextEntry<T>,\n\trules: readonly CompressionRule[],\n\tpressure: number,\n\tcache: CompressionCache,\n\tllmCompress?: LlmCompress<T>,\n): RenderedEntry<T> | undefined {\n\tconst base: RenderedEntry<T> = {\n\t\tid: e.id,\n\t\ttopic: e.topic,\n\t\ttags: e.tags,\n\t\ttier: 0,\n\t\tpayload: e.payload,\n\t\tcompressed: false,\n\t};\n\tif (pressure <= 0) return base;\n\tfor (const rule of rules) {\n\t\tif (!matches(e, rule.match)) continue;\n\t\tswitch (rule.action) {\n\t\t\tcase \"evict\":\n\t\t\t\treturn undefined;\n\t\t\tcase \"reference\":\n\t\t\t\treturn { ...base, tier: 1, payload: `[ref:${e.id}]`, compressed: true };\n\t\t\tcase \"truncate\": {\n\t\t\t\tconst s = typeof e.payload === \"string\" ? e.payload : JSON.stringify(e.payload);\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttier: 1,\n\t\t\t\t\tpayload: s.length > rule.maxChars ? s.slice(0, rule.maxChars) : s,\n\t\t\t\t\tcompressed: s.length > rule.maxChars,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"llm-summary\": {\n\t\t\t\tif (!llmCompress) {\n\t\t\t\t\t// Defence-in-depth — construction guard should have thrown.\n\t\t\t\t\tthrow new Error(\"tierCompress: 'llm-summary' rule requires `llmCompress`\");\n\t\t\t\t}\n\t\t\t\tconst cached = cache.get(e.id, rule.toTier);\n\t\t\t\tconst text = cached ?? llmCompress(e, rule.toTier);\n\t\t\t\tif (cached === undefined) cache.set(e.id, rule.toTier, text);\n\t\t\t\treturn { ...base, tier: rule.toTier, payload: text, compressed: true };\n\t\t\t}\n\t\t}\n\t}\n\treturn base;\n}\n\n/**\n * Per-consumer reactive rendering (D-A2). Materialises a\n * `Node<readonly RenderedEntry[]>` over the pool: filter → per-entry rule\n * application under `pressure` → token-budget trim (lowest-importance first).\n *\n * Recomputes the slice per `(entries | pressure)` wave (O(n) — behaviourally\n * identical to the incremental closure-mirror; incremental is a perf\n * follow-up, not a correctness gap).\n *\n * @throws if any rule is `llm-summary` and the pool has no `llmCompress`\n * (D-A3 construction guard).\n */\nexport function renderContextView<T>(\n\tpool: TaggedContextPoolBundle<T>,\n\tview: ContextView<T>,\n): Node<readonly RenderedEntry<T>[]> {\n\tconst usesLlm = view.rules.some((r) => r.action === \"llm-summary\");\n\tif (usesLlm && !pool._opts.llmCompress) {\n\t\tthrow new Error(\n\t\t\t\"renderContextView: view has an 'llm-summary' rule but the pool was created without `llmCompress` (DS-14.6.A D-A3).\",\n\t\t);\n\t}\n\tconst tokenize = view.tokenizer ?? DEFAULT_TOKENIZER;\n\tconst llmCompress = pool._opts.llmCompress;\n\n\treturn node<readonly RenderedEntry<T>[]>(\n\t\t[pool.entries as Node, view.pressure as Node],\n\t\t(data, actions, ctx) => {\n\t\t\tconst entries = (data[0] != null && data[0].length > 0 ? data[0].at(-1) : ctx.prevData[0]) as\n\t\t\t\t| readonly ContextEntry<T>[]\n\t\t\t\t| undefined;\n\t\t\tconst pressure = (data[1] != null && data[1].length > 0 ? data[1].at(-1) : ctx.prevData[1]) as\n\t\t\t\t| number\n\t\t\t\t| undefined;\n\t\t\tif (entries === undefined) {\n\t\t\t\tactions.emit([]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst p = pressure ?? 0;\n\t\t\tconst rendered: RenderedEntry<T>[] = [];\n\t\t\tfor (const e of entries) {\n\t\t\t\tif (!view.filter(e)) continue;\n\t\t\t\tconst r = tierCompress(e, view.rules, p, pool._cache, llmCompress);\n\t\t\t\tif (r !== undefined) rendered.push(r);\n\t\t\t}\n\t\t\t// Token-budget trim: drop lowest-importance entries until under budget.\n\t\t\tconst cost = (r: RenderedEntry<T>): number =>\n\t\t\t\ttokenize(typeof r.payload === \"string\" ? r.payload : JSON.stringify(r.payload));\n\t\t\tlet total = 0;\n\t\t\tfor (const r of rendered) total += cost(r);\n\t\t\tif (total > view.budgetTokens) {\n\t\t\t\tconst byImp = entries.reduce<Map<string, number>>(\n\t\t\t\t\t(acc, e) => acc.set(e.id, e.importance),\n\t\t\t\t\tnew Map(),\n\t\t\t\t);\n\t\t\t\trendered.sort((a, b) => (byImp.get(a.id) ?? 0) - (byImp.get(b.id) ?? 0));\n\t\t\t\twhile (total > view.budgetTokens && rendered.length > 0) {\n\t\t\t\t\ttotal -= cost(rendered.shift() as RenderedEntry<T>);\n\t\t\t\t}\n\t\t\t}\n\t\t\tactions.emit(rendered);\n\t\t},\n\t\t{ describeKind: \"derived\", meta: aiMeta(\"contextView\", { topic: pool._opts.topic }) },\n\t);\n}\n","/**\n * @internal — shared helpers for the AI pattern modules.\n *\n * NOT part of the public API. Consumers reach public symbols through\n * `@graphrefly/graphrefly/patterns/ai` (the barrel).\n *\n * @module\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\tnode,\n\tResettableTimer,\n} from \"@graphrefly/pure-ts/core\";\nimport { fromAny, type NodeInput } from \"@graphrefly/pure-ts/extra\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n} from \"./adapters/core/types.js\";\n\nexport function aiMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"ai\", kind, extra);\n}\n\nexport function isPromiseLike(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nexport function isNodeLike(x: unknown): x is Node<unknown> {\n\treturn (\n\t\ttypeof x === \"object\" &&\n\t\tx !== null &&\n\t\t\"subscribe\" in x &&\n\t\ttypeof (x as Node<unknown>).subscribe === \"function\" &&\n\t\t\"cache\" in x\n\t);\n}\n\nexport function isAsyncIterableLike(x: unknown): x is AsyncIterable<unknown> {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\tSymbol.asyncIterator in x &&\n\t\ttypeof (x as AsyncIterable<unknown>)[Symbol.asyncIterator] === \"function\"\n\t);\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** First settled `DATA` from a `Node` (do not pass plain strings — `fromAny` would iterate chars). */\nexport function firstDataFromNode(\n\tresolved: Node<unknown>,\n\topts?: { timeoutMs?: number },\n): Promise<unknown> {\n\tif ((resolved as { status?: string }).status === \"settled\") {\n\t\tconst immediate = resolved.cache;\n\t\tif (immediate !== undefined) {\n\t\t\treturn Promise.resolve(immediate);\n\t\t}\n\t}\n\tconst timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = new ResettableTimer();\n\t\tconst unsub = resolved.subscribe((messages) => {\n\t\t\tfor (const msg of messages) {\n\t\t\t\tif (msg[0] === DATA) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\tresolve(msg[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (msg[0] === ERROR) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\treject(msg[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (msg[0] === COMPLETE) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\treject(new Error(\"firstDataFromNode: completed without producing a value\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\ttimer.start(timeoutMs, () => {\n\t\t\tunsub();\n\t\t\treject(new Error(`firstDataFromNode: timed out after ${timeoutMs}ms`));\n\t\t});\n\t});\n}\n\n/** Await Promise-likes, then resolve `Node` / async-iterable inputs via `fromAny` + first `DATA`. */\nexport async function resolveToolHandlerResult(value: unknown): Promise<unknown> {\n\tif (isPromiseLike(value)) {\n\t\treturn resolveToolHandlerResult(await value);\n\t}\n\tif (isNodeLike(value)) {\n\t\treturn firstDataFromNode(value);\n\t}\n\tif (isAsyncIterableLike(value)) {\n\t\treturn firstDataFromNode(fromAny(value as NodeInput<unknown>));\n\t}\n\treturn value;\n}\n\n/** Strip markdown code fences, handling trailing commentary after closing fence. */\nexport function stripFences(text: string): string {\n\tconst match = text.match(/^```(?:json)?\\s*([\\s\\S]*?)\\s*```[\\s\\S]*$/);\n\treturn match ? match[1]! : text;\n}\n\n/**\n * Bridge-layer failure kind reported to {@link OneShotLlmCallConfig.onFailure}.\n *\n * - `\"throw\"` — synchronous throw from `adapter.invoke()`.\n * - `\"error\"` — `[ERROR, value]` message on the bridged Node.\n * - `\"complete\"` — the bridged Node closed without emitting DATA.\n * - `\"onSuccess-threw\"` — `onSuccess(resp)` itself threw (uncaught parse /\n * builder error). Caller's `onFailure` decides the failure-payload shape.\n */\nexport type OneShotLlmFailureKind = \"throw\" | \"error\" | \"complete\" | \"onSuccess-threw\";\n\n/** Configuration for {@link _oneShotLlmCall}. */\nexport interface OneShotLlmCallConfig<T> {\n\t/**\n\t * Build the success payload from the adapter's first DATA message.\n\t * MAY throw — the helper catches and routes through `onFailure(kind:\n\t * \"onSuccess-threw\", err)` so callers don't need their own try/catch.\n\t */\n\tonSuccess: (resp: LLMResponse) => T;\n\t/**\n\t * Build a failure payload when the bridge layer reports any of the\n\t * {@link OneShotLlmFailureKind} categories. Caller chooses the detail\n\t * string format and any error-class metadata.\n\t */\n\tonFailure: (kind: OneShotLlmFailureKind, err: unknown) => T;\n\t/**\n\t * Forwarded to `adapter.invoke(messages, opts)` — `signal` is set\n\t * by the helper from the producer's AbortController and CANNOT be\n\t * overridden here (cancellation is a hard contract of this helper).\n\t */\n\tinvokeOpts?: Omit<LLMInvokeOptions, \"signal\">;\n\t/**\n\t * Optional parent abort signal (e.g. JobFlow pump's per-claim signal).\n\t * When the parent aborts, the helper aborts its inner AbortController —\n\t * so `adapter.invoke({ signal })` and `fromAny({ signal })` see the\n\t * cascade and cancel in-flight work. Pump-driven harness teardown\n\t * (`harness.destroy()`) propagates through this hook (Tier 6.5 2.5b).\n\t */\n\tparentSignal?: AbortSignal;\n}\n\n/**\n * Internal — one-shot bridge from `adapter.invoke()` (a `NodeInput<LLMResponse>`)\n * into a producer that emits exactly one DATA + COMPLETE.\n *\n * **Why this exists.** The harness's `defaultLlmExecutor` and\n * `defaultLlmVerifier` (Tier 6.5 C2) both call `adapter.invoke()` once\n * per claimed JobFlow job and need to:\n * 1. Subscribe to the bridged Node, capture the first DATA, parse, emit\n * a domain payload.\n * 2. Map adapter throws / ERROR / COMPLETE-without-DATA to a domain\n * failure payload (rather than nack the JobFlow claim).\n * 3. Thread `signal: ac.signal` into BOTH `adapter.invoke()` (via\n * `LLMInvokeOptions.signal`) and `fromAny()` (covers Node-shaped\n * invokeResults) so teardown actually aborts in-flight HTTP work.\n * 4. Tear down the inner subscription cleanly when DATA captures or\n * when the producer is unsubscribed.\n *\n * Pre-extraction this body was duplicated ~80 LOC across the two default\n * bridges; symmetric fixes had to land twice (qa F1 / F2 / F5). This\n * helper centralizes the producer body so future bridge-layer fixes apply\n * once.\n *\n * **Not part of the public API.** Callers in `patterns/ai/_internal.ts`'s\n * import surface (the harness defaults today) use this; user code should\n * use `promptNode` for cross-wave reactive transforms or call\n * `adapter.invoke()` directly.\n */\nexport function _oneShotLlmCall<T>(\n\tadapter: LLMAdapter,\n\tmessages: readonly ChatMessage[],\n\tconfig: OneShotLlmCallConfig<T>,\n): NodeInput<T> {\n\treturn node<T>(\n\t\t(_data, actions) => {\n\t\t\tconst ac = new AbortController();\n\t\t\t// Link parent signal (e.g. pump per-claim signal) so cascading\n\t\t\t// teardown propagates: parent abort → inner ac.abort → adapter +\n\t\t\t// fromAny cancel.\n\t\t\tconst parentSignal = config.parentSignal;\n\t\t\tlet unlinkParent: () => void = () => undefined;\n\t\t\tif (parentSignal) {\n\t\t\t\tif (parentSignal.aborted) {\n\t\t\t\t\tac.abort();\n\t\t\t\t} else {\n\t\t\t\t\tconst onParentAbort = (): void => ac.abort();\n\t\t\t\t\tparentSignal.addEventListener(\"abort\", onParentAbort, { once: true });\n\t\t\t\t\tunlinkParent = () => parentSignal.removeEventListener(\"abort\", onParentAbort);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet captured = false;\n\t\t\tlet unsub: (() => void) | null = null;\n\t\t\tconst emitOnce = (value: T): void => {\n\t\t\t\tif (captured) return;\n\t\t\t\tcaptured = true;\n\t\t\t\tactions.down([[DATA, value], [COMPLETE]] satisfies Messages);\n\t\t\t\tunsub?.();\n\t\t\t\tunsub = null;\n\t\t\t};\n\t\t\tlet invokeResult: NodeInput<LLMResponse>;\n\t\t\ttry {\n\t\t\t\tinvokeResult = adapter.invoke(messages, { ...config.invokeOpts, signal: ac.signal });\n\t\t\t} catch (err) {\n\t\t\t\temitOnce(config.onFailure(\"throw\", err));\n\t\t\t\treturn {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tunlinkParent();\n\t\t\t\t\t\tac.abort();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst callNode = fromAny<LLMResponse>(invokeResult, { signal: ac.signal });\n\t\t\tunsub = callNode.subscribe((batch) => {\n\t\t\t\tfor (const m of batch) {\n\t\t\t\t\tif (captured) return;\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\temitOnce(config.onSuccess(m[1] as LLMResponse));\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\temitOnce(config.onFailure(\"onSuccess-threw\", err));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\t\temitOnce(config.onFailure(\"error\", m[1]));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\t\t// COMPLETE without prior DATA — without this arm the JobFlow\n\t\t\t\t\t\t// pump's claim would stall (qa F1 regression). Helper handles\n\t\t\t\t\t\t// for ALL callers; defaults can't regress.\n\t\t\t\t\t\temitOnce(config.onFailure(\"complete\", undefined));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t// Sync DATA delivery (cached state / `fromAny` over a sync value):\n\t\t\t// the callback ran reentrantly before `unsub` was assigned, so the\n\t\t\t// `unsub?.()` call inside `emitOnce` was a no-op. Drop the upstream\n\t\t\t// subscription now that we have the handle.\n\t\t\tif (captured && unsub) {\n\t\t\t\tunsub();\n\t\t\t\tunsub = null;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tunlinkParent();\n\t\t\t\t\tac.abort();\n\t\t\t\t\tunsub?.();\n\t\t\t\t\tunsub = null;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ describeKind: \"producer\" },\n\t);\n}\n","/**\n * Metadata helpers for pattern-layer nodes (Tier 2.2 promotion from\n * `patterns/_internal/`).\n *\n * Each domain (orchestration, messaging, reduction, ai, cqrs, domain_template,\n * memory, lens, audit, harness) shares the same metadata convention. Promoted\n * to `extra/` so non-patterns code (and downstream consumers building their\n * own domain primitives) can use the same shape.\n *\n * @module\n */\n\n/**\n * Build a domain metadata object for pattern-layer nodes.\n *\n * Each domain follows the same shape: `{ [domain]: true, [domain]_type: kind, ...extra }`.\n *\n * @param domain - The domain tag (e.g. `\"orchestration\"`, `\"ai\"`, `\"cqrs\"`).\n * @param kind - The specific type within the domain (e.g. `\"gate\"`, `\"prompt\"`).\n * @param extra - Additional metadata to merge.\n * @returns Metadata object.\n */\nexport function domainMeta(\n\tdomain: string,\n\tkind: string,\n\textra?: Record<string, unknown>,\n): Record<string, unknown> {\n\treturn {\n\t\t[domain]: true,\n\t\t[`${domain}_type`]: kind,\n\t\t...(extra ?? {}),\n\t};\n}\n","/**\n * evalVerifier — re-run the affected eval tasks against the execute-stage\n * artifact instead of asking an LLM to opine on the fix.\n *\n * Pairs naturally with {@link refineExecutor}: refineExecutor emits an\n * `ExecuteOutput<T>.artifact` holding the converged candidate; evalVerifier\n * pulls it out via `extractArtifact` and feeds a single-candidate batch\n * into the same `Evaluator<T>` shape that `refineLoop` used. Consistent\n * scoring between EXECUTE and VERIFY — no \"LLM said it looks fine\" gap.\n *\n * **C2 lifecycle (Tier 6.5).** The work fn is invoked once per claimed\n * verify-stage job. A fresh single-candidate eval subgraph is mounted\n * inside the work fn and tears down when the JobFlow pump ack/unsubs.\n *\n * @module\n */\n\nimport { batch, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { filter } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport type {\n\tExecuteOutput,\n\tHarnessExecutor,\n\tHarnessJobPayload,\n\tHarnessVerifier,\n\tTriagedItem,\n\tVerifyOutput,\n} from \"../../utils/harness/types.js\";\nimport type { JobEnvelope } from \"../../utils/job-queue/index.js\";\nimport { refineExecutor } from \"./refine-executor.js\";\nimport type {\n\tDatasetItem,\n\tEvalResult,\n\tEvaluator,\n\tRefineLoopOptions,\n\tRefineStrategy,\n} from \"./refine-loop.js\";\n\n/** Summary of the re-eval wave passed to a custom `toOutput` mapper. */\nexport interface EvalVerifierSummary {\n\treadonly scores: readonly EvalResult[];\n\treadonly meanScore: number;\n\treadonly passCount: number;\n\treadonly total: number;\n\treadonly threshold: number;\n\t/**\n\t * True when the EXECUTE stage did not produce an artifact (i.e.\n\t * `extractArtifact` returned `null` / `undefined`). Downstream mappers\n\t * can distinguish this from \"evaluator ran but everything scored zero\".\n\t */\n\treadonly missingArtifact?: boolean;\n}\n\n/** Configuration for {@link evalVerifier}. */\nexport interface EvalVerifierConfig<T> {\n\t/**\n\t * Pull the artifact that should be re-evaluated out of the execute-stage\n\t * output. Default: `(exec) => exec.artifact as T` — works out-of-the-box\n\t * with `refineExecutor` (which populates `artifact` by default).\n\t */\n\textractArtifact?: (exec: ExecuteOutput<T>, item: TriagedItem) => T | null | undefined;\n\n\t/**\n\t * Reactive evaluator — same contract as `refineLoop`'s `Evaluator<T>`.\n\t */\n\tevaluator: Evaluator<T>;\n\n\t/**\n\t * Resolve which dataset rows to score this verification against.\n\t */\n\tdatasetFor: (item: TriagedItem) => readonly DatasetItem[];\n\n\t/** Mean score required to pass verification. Default `0.5`. */\n\tthreshold?: number;\n\n\t/** Optional output mapper — override the default findings / errorClass shape. */\n\ttoOutput?: (summary: EvalVerifierSummary) => VerifyOutput;\n\n\t/** Node name prefix for introspection. */\n\tname?: string;\n\n\t/**\n\t * Optional parent graph on which per-claim eval subgraphs mount at\n\t * `eval/${claimId}` (DS-13.5.D.4, locked 2026-05-01). When provided,\n\t * each claim creates a fresh `Graph(\\`eval_${claimId}\\`)` subgraph\n\t * carrying `candidates` / `dataset` / `output` and mounts it at\n\t * `eval/${claimId}` on this parent — `describe()` walks the parent\n\t * see the per-claim topology while the claim is in flight, and the\n\t * subgraph is removed via `parent.remove(\"eval/${claimId}\")` on the\n\t * output node's `deactivate` cleanup (fires when JobFlow's pump\n\t * unsubscribes after ack/nack).\n\t *\n\t * **claimId source.** `JobEnvelope.id` (assigned at enqueue time);\n\t * unique within a JobFlow lifetime — uniqueness within a single pump\n\t * cycle is the JobFlow's contract.\n\t *\n\t * When omitted, internal nodes float (pre-DS-13.5.D.4 behavior).\n\t */\n\tgraph?: Graph;\n}\n\nfunction meanScore(scores: readonly EvalResult[]): number {\n\tif (scores.length === 0) return Number.NEGATIVE_INFINITY;\n\tlet sum = 0;\n\tfor (const s of scores) sum += s.score;\n\treturn sum / scores.length;\n}\n\nfunction defaultToOutput(summary: EvalVerifierSummary): VerifyOutput {\n\tconst { passCount, total, meanScore: mean, threshold, missingArtifact } = summary;\n\tconst meanStr = Number.isFinite(mean) ? mean.toFixed(3) : String(mean);\n\tconst verified = !missingArtifact && total > 0 && mean >= threshold;\n\tconst findings = missingArtifact\n\t\t? [\"EXECUTE stage did not emit an artifact; cannot verify reactively\"]\n\t\t: verified\n\t\t\t? [`${passCount}/${total} eval tasks passed; mean score ${meanStr} ≥ ${threshold}`]\n\t\t\t: total === 0\n\t\t\t\t? [\"No eval tasks were selected for this item — cannot verify\"]\n\t\t\t\t: [\n\t\t\t\t\t\t`${passCount}/${total} eval tasks passed; mean score ${meanStr} < threshold ${threshold}`,\n\t\t\t\t\t];\n\treturn verified\n\t\t? { verified: true, findings }\n\t\t: { verified: false, findings, errorClass: \"structural\" };\n}\n\nfunction defaultExtractArtifact<T>(exec: ExecuteOutput<T>): T | null | undefined {\n\treturn exec.artifact ?? null;\n}\n\n/**\n * Build a {@link HarnessVerifier} that re-runs the eval suite against the\n * artifact produced by EXECUTE.\n *\n * Reads `job.payload.execution` (filled by the upstream execute work fn)\n * and runs the evaluator against `extractArtifact(execution, item)`.\n * Returns the same payload with `verify` filled in.\n *\n * @example Pair with refineExecutor for end-to-end eval consistency.\n * ```ts\n * const evaluator: Evaluator<CatalogEntry> = (cands, ds) => runEval(cands, ds);\n * const harness = harnessLoop(\"repair\", {\n * adapter,\n * executor: refineExecutor({ ..., evaluator, ...strategyConfig }),\n * verifier: evalVerifier({ evaluator, datasetFor, threshold: 0.8 }),\n * });\n * ```\n */\nexport function evalVerifier<T>(config: EvalVerifierConfig<T>): HarnessVerifier<T> {\n\tconst name = config.name ?? \"eval-verifier\";\n\tconst threshold = config.threshold ?? 0.5;\n\tconst toOutput = config.toOutput ?? defaultToOutput;\n\tconst extract = config.extractArtifact ?? defaultExtractArtifact<T>;\n\tconst parentGraph = config.graph;\n\t// DS-13.5.B QA A7 (2026-05-03): per-claimId collision counter.\n\t// Reingest paths preserve identity per DS-13.5.D.3 so the same\n\t// claimId can land on the verifier while a prior cycle is still\n\t// in-flight. Without disambiguation, `parentGraph.mount(\n\t// \"eval/${id}\", sub)` would either silently overwrite the prior\n\t// mount or throw \"mount already exists\". The counter is keyed by\n\t// claimId so DISTINCT ids start at seq=0 (`eval/${id}`) and only\n\t// REPEAT ids get a `_${seq}` suffix.\n\tconst mountSeqByClaimId = new Map<string, number>();\n\n\treturn (job: JobEnvelope<HarnessJobPayload<T>>) => {\n\t\tconst { item, execution } = job.payload;\n\t\t// Defensive: verify stage should always run AFTER execute stage with\n\t\t// `execution` populated. If it isn't, surface that as a structural\n\t\t// failure so the dispatch effect can route the item.\n\t\tif (execution == null) {\n\t\t\treturn {\n\t\t\t\t...job.payload,\n\t\t\t\tverify: {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tfindings: [\"evalVerifier: prior execute stage produced no execution\"],\n\t\t\t\t\terrorClass: \"structural\" as const,\n\t\t\t\t},\n\t\t\t} satisfies HarnessJobPayload<T>;\n\t\t}\n\t\tconst artifact = extract(execution, item);\n\t\tif (artifact == null) {\n\t\t\treturn {\n\t\t\t\t...job.payload,\n\t\t\t\tverify: toOutput({\n\t\t\t\t\tscores: [],\n\t\t\t\t\tmeanScore: Number.NEGATIVE_INFINITY,\n\t\t\t\t\tpassCount: 0,\n\t\t\t\t\ttotal: 0,\n\t\t\t\t\tthreshold,\n\t\t\t\t\tmissingArtifact: true,\n\t\t\t\t}),\n\t\t\t} satisfies HarnessJobPayload<T>;\n\t\t}\n\n\t\t// Per-claim eval subgraph. State seeds with the single candidate +\n\t\t// resolved dataset; the evaluator returns a Node<readonly EvalResult[]>.\n\t\t// The terminal payload emits when the evaluator settles; intermediate\n\t\t// nulls are filtered.\n\t\t//\n\t\t// **Batch-coalescing for synchronous-emit-during-subscribe evaluators\n\t\t// (COMPOSITION-GUIDE §9a).** This `batch()` wrap is load-bearing for a\n\t\t// SPECIFIC evaluator pattern: evaluators that, during the\n\t\t// `evaluator(candidates, dataset)` constructor call, synchronously\n\t\t// `subscribe()` to BOTH inputs and emit on each subscribe-callback\n\t\t// firing. Each subscribe pushes the cached value to its callback, the\n\t\t// callback runs `out.emit(...)`, and that emit becomes its own wave\n\t\t// when not inside a batch — leaving multiple DATA messages visible to\n\t\t// the downstream `derived` once it activates. The JobFlow pump's\n\t\t// \"first DATA wins\" capture would then fire on the FIRST intermediate\n\t\t// emit (e.g. empty scores from a pre-dataset recompute) instead of\n\t\t// the final settled value.\n\t\t//\n\t\t// Wrapping the constructor call in `batch()` coalesces those internal\n\t\t// emits into one multi-message delivery (§9a); sugar `derived`\n\t\t// auto-unwraps to the LAST value per its snapshot/combine semantics\n\t\t// (sugar.ts), so the downstream sees only the final settled scores.\n\t\t//\n\t\t// **Async evaluators are NOT covered by this fix.** Evaluators that\n\t\t// subscribe via microtask / Promise.then() / setTimeout don't see the\n\t\t// §9a hazard at all — their emits land in separate waves regardless\n\t\t// of whether the constructor call is batched. The fix is strictly\n\t\t// for the synchronous-emit-during-subscribe pattern (today's tests:\n\t\t// `presenceEvaluator` in actuator-executor.test.ts; `keywordEvaluator`\n\t\t// in refine-executor.test.ts uses `derived` and is naturally\n\t\t// single-emit). See `harness-default-bridges.test.ts` regression test\n\t\t// \"evalVerifier coalesces synchronous-emit-during-subscribe\n\t\t// evaluators\" for the locked contract.\n\t\t// DS-13.5.D.4 (locked 2026-05-01): when `parentGraph` is configured,\n\t\t// each claim creates its own subgraph `eval_${claimId}` and mounts\n\t\t// it at `eval/${claimId}` on the parent. Internal node names use\n\t\t// the simple shape (`candidates`, `dataset`, `output`) since each\n\t\t// subgraph is a fresh namespace. Cleanup attaches to `raw`'s\n\t\t// deactivate hook so the segment is removed when JobFlow\n\t\t// unsubscribes after ack/nack (canonical \"last unsubscribe\"\n\t\t// signal via the existing NodeFnCleanup.onDeactivation protocol).\n\t\tconst claimId = job.id;\n\t\t// QA A7: only append a `_${seq}` suffix when this claimId has\n\t\t// already been mounted (collision case). Distinct claimIds\n\t\t// resolve to `eval/${claimId}` as before.\n\t\tconst seq = mountSeqByClaimId.get(claimId) ?? 0;\n\t\tmountSeqByClaimId.set(claimId, seq + 1);\n\t\tconst segmentSuffix = seq === 0 ? \"\" : `_${seq}`;\n\t\tconst segmentPath = `eval/${claimId}${segmentSuffix}`;\n\t\tconst sub = parentGraph != null ? new Graph(`eval_${claimId}${segmentSuffix}`) : null;\n\t\tconst candidatesName = sub != null ? \"candidates\" : `${name}/candidates`;\n\t\tconst datasetName = sub != null ? \"dataset\" : `${name}/dataset`;\n\t\tconst outputName = sub != null ? \"output\" : `${name}/output`;\n\t\tconst gateName = sub != null ? \"gate-out\" : `${name}/gate-out`;\n\n\t\tconst candidates = node<readonly T[]>([], {\n\t\t\tinitial: [artifact as T],\n\t\t\tname: candidatesName,\n\t\t});\n\t\tconst dataset = node<readonly DatasetItem[]>([], {\n\t\t\tinitial: config.datasetFor(item),\n\t\t\tname: datasetName,\n\t\t});\n\t\tif (sub != null) {\n\t\t\tsub.add(candidates, { name: \"candidates\" });\n\t\t\tsub.add(dataset, { name: \"dataset\" });\n\t\t}\n\t\tlet scoresNode!: ReturnType<Evaluator<T>>;\n\t\tbatch(() => {\n\t\t\tscoresNode = config.evaluator(candidates, dataset);\n\t\t});\n\t\t// DS-13.5.B QA A1 (2026-05-03): the deactivate cleanup hook MUST\n\t\t// be returned on every fn run, including the early-return path\n\t\t// where `arr == null` (evaluator emits a placeholder before\n\t\t// settling). Cleanup capture happens at the END of fn execution\n\t\t// (NodeFnCleanup contract), so a fn that returned early without\n\t\t// the cleanup object would leak `eval/${claimId}` if its first\n\t\t// run produced null and the consumer unsubscribed before\n\t\t// scoresNode emits non-null.\n\t\tconst cleanup =\n\t\t\tparentGraph != null\n\t\t\t\t? () => ({\n\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t// Auto-unmount on JobFlow's pump unsubscribe after\n\t\t\t\t\t\t\t// ack/nack (DS-13.5.D.4). Idempotent: try/catch\n\t\t\t\t\t\t\t// covers the case where the segment was already\n\t\t\t\t\t\t\t// removed (e.g. parent destroy cascade ran first).\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tparentGraph.remove(segmentPath);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t/* best-effort cleanup */\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t: () => undefined;\n\t\tconst raw = node<HarnessJobPayload<T> | null>(\n\t\t\t[scoresNode as Node<unknown>],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst arr = data[0] as readonly EvalResult[] | null | undefined;\n\t\t\t\tif (arr == null) {\n\t\t\t\t\tactions.emit(null);\n\t\t\t\t\treturn cleanup();\n\t\t\t\t}\n\t\t\t\tconst mean = meanScore(arr);\n\t\t\t\tconst passCount = arr.filter((s) => s.score >= threshold).length;\n\t\t\t\tactions.emit({\n\t\t\t\t\t...job.payload,\n\t\t\t\t\tverify: toOutput({\n\t\t\t\t\t\tscores: arr,\n\t\t\t\t\t\tmeanScore: mean,\n\t\t\t\t\t\tpassCount,\n\t\t\t\t\t\ttotal: arr.length,\n\t\t\t\t\t\tthreshold,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn cleanup();\n\t\t\t},\n\t\t\t{ name: outputName, describeKind: \"derived\" },\n\t\t);\n\t\tconst gateOut = filter(raw, (v) => v != null, { name: gateName }) as ReturnType<\n\t\t\tHarnessVerifier<T>\n\t\t>;\n\t\tif (sub != null) {\n\t\t\tsub.add(raw, { name: \"output\" });\n\t\t\t// QA A6: register the gate-out filter on the per-claim\n\t\t\t// subgraph so describe() walks see the consumer-facing node\n\t\t\t// alongside candidates/dataset/output. Without this, the\n\t\t\t// returned filter floats and the subgraph's external surface\n\t\t\t// is incomplete in topology snapshots.\n\t\t\tsub.add(gateOut as Node<unknown>, { name: \"gate-out\" });\n\t\t\t(parentGraph as Graph).mount(segmentPath, sub);\n\t\t}\n\t\treturn gateOut;\n\t};\n}\n\n/**\n * Config for {@link harnessEvalPair} — the typed bundle that produces a\n * matched `refineExecutor<T>` + `evalVerifier<T>` pair sharing one\n * {@link Evaluator} and one `datasetFor` resolver.\n */\nexport interface HarnessEvalPairConfig<T> {\n\t/** Map a triaged item to the seed candidate. */\n\tseedFrom: (item: TriagedItem) => T;\n\t/** The reactive evaluator used by BOTH executor and verifier. */\n\tevaluator: Evaluator<T>;\n\t/** The refinement strategy (e.g. `errorCritique(teacher)`). */\n\tstrategy: RefineStrategy<T>;\n\t/** Resolve dataset rows per triaged item. */\n\tdatasetFor: (item: TriagedItem) => readonly DatasetItem[];\n\t/** Pass-threshold for the verifier. Default `0.5`. */\n\tthreshold?: number;\n\t/** Convergence / budget options forwarded to each inner `refineLoop`. */\n\trefine?: Omit<RefineLoopOptions, \"dataset\" | \"name\">;\n\t/**\n\t * Shared node-name prefix — the executor becomes `${name}-exec` and the\n\t * verifier `${name}-verify` for distinct but related describe() paths.\n\t * Default `\"harness-pair\"`.\n\t */\n\tname?: string;\n}\n\n/**\n * Typed factory that returns a matched `{ executor, verifier }` pair.\n *\n * Prevents the \"executor wrote `A`, verifier expected `B`\" class of runtime\n * cast errors — `T` is threaded through both sides, so mixing up the\n * configuration is a compile error instead of a silent `as T` in\n * `extractArtifact`. Shares the evaluator so EXECUTE and VERIFY score with\n * identical semantics (the whole point of `evalVerifier`).\n */\nexport function harnessEvalPair<T>(config: HarnessEvalPairConfig<T>): {\n\texecutor: HarnessExecutor<T>;\n\tverifier: HarnessVerifier<T>;\n} {\n\tconst baseName = config.name ?? \"harness-pair\";\n\tconst executor = refineExecutor<T>({\n\t\tname: `${baseName}-exec`,\n\t\tseedFrom: config.seedFrom,\n\t\tevaluator: config.evaluator,\n\t\tstrategy: config.strategy,\n\t\tdatasetFor: config.datasetFor,\n\t\trefine: config.refine,\n\t});\n\tconst verifier = evalVerifier<T>({\n\t\tname: `${baseName}-verify`,\n\t\tevaluator: config.evaluator,\n\t\tdatasetFor: config.datasetFor,\n\t\tthreshold: config.threshold,\n\t});\n\treturn { executor, verifier };\n}\n","/**\n * refineExecutor — bridge a `refineLoop` into the harness EXECUTE work fn.\n *\n * Each claimed job mounts a fresh `refineLoop`; when the loop reaches a\n * terminal status (`converged` / `budget` / `errored`), the work fn emits a\n * single {@link HarnessJobPayload} with `execution` filled in. The JobFlow\n * pump subscribes once, takes the first DATA, then unsubscribes — so the\n * inner loop tears down cleanly when the harness acks the job.\n *\n * **C2 lifecycle (Tier 6.5).** The work fn is invoked once per claim, so\n * no internal `switchMap` is needed (the prior pre-C2 shape used switchMap\n * to handle a stream of items). The pump owns the per-claim lifecycle:\n * activation when the work fn returns, teardown when the result Node is\n * unsubscribed.\n *\n * **Cross-item learning:** a fresh refineLoop per item means\n * `errorCritique`-style failure sampling does NOT accumulate across items\n * sharing a `rootCause`. A persistent-loop + re-seed surface is filed in\n * `docs/optimizations.md` as a long-term follow-up.\n *\n * @module\n */\n\nimport { node } from \"@graphrefly/pure-ts/core\";\nimport { filter } from \"@graphrefly/pure-ts/extra\";\nimport type {\n\tExecuteOutput,\n\tHarnessExecutor,\n\tHarnessJobPayload,\n\tTriagedItem,\n} from \"../../utils/harness/types.js\";\nimport type { JobEnvelope } from \"../../utils/job-queue/index.js\";\nimport {\n\ttype DatasetItem,\n\ttype Evaluator,\n\ttype RefineLoopOptions,\n\ttype RefineStatus,\n\ttype RefineStrategy,\n\trefineLoop,\n} from \"./refine-loop.js\";\n\n/** Terminal-run snapshot passed to a custom `toOutput` mapper. */\nexport interface RefineExecutorResult<T> {\n\t/** Best candidate the inner loop converged on. `null` if no candidates were scored. */\n\treadonly best: T | null;\n\t/** Aggregate score at termination. `-Infinity` if the batch was empty. */\n\treadonly score: number;\n\t/** Reason the loop terminated. */\n\treadonly status: RefineStatus;\n}\n\n/** Configuration for {@link refineExecutor}. */\nexport interface RefineExecutorConfig<T> {\n\t/** Map a triaged item to the seed candidate (e.g. a catalog entry, prompt, patch). */\n\tseedFrom: (item: TriagedItem) => T;\n\n\t/** Reactive evaluator — same shape as passed to `refineLoop`. */\n\tevaluator: Evaluator<T>;\n\n\t/** Strategy (e.g. `errorCritique(teacher)`). Applied to every item's inner loop. */\n\tstrategy: RefineStrategy<T>;\n\n\t/** Map a triaged item to the dataset rows the evaluator should score against. */\n\tdatasetFor: (item: TriagedItem) => readonly DatasetItem[];\n\n\t/**\n\t * Optional mapper from the inner loop's terminal snapshot to an\n\t * `ExecuteOutput<T>`. Default: converged→success, budget→partial,\n\t * errored→failure.\n\t */\n\ttoOutput?: (result: RefineExecutorResult<T>) => ExecuteOutput<T>;\n\n\t/** Convergence / budget options forwarded to each inner `refineLoop`. */\n\trefine?: Omit<RefineLoopOptions, \"dataset\" | \"name\">;\n\n\t/** Node name prefix for introspection. Default `\"refine-executor\"`. */\n\tname?: string;\n}\n\nfunction defaultToOutput<T>(result: RefineExecutorResult<T>): ExecuteOutput<T> {\n\tconst { best, score, status } = result;\n\tconst scoreStr = Number.isFinite(score) ? score.toFixed(3) : String(score);\n\tconst artifact = (best ?? undefined) as T | undefined;\n\tif (status === \"converged\") {\n\t\treturn {\n\t\t\toutcome: \"success\",\n\t\t\tdetail: `refineLoop converged at score ${scoreStr}`,\n\t\t\tartifact,\n\t\t};\n\t}\n\tif (status === \"budget\") {\n\t\treturn {\n\t\t\toutcome: \"partial\",\n\t\t\tdetail: `refineLoop hit budget at score ${scoreStr}`,\n\t\t\tartifact,\n\t\t};\n\t}\n\treturn {\n\t\toutcome: \"failure\",\n\t\tdetail: `refineLoop errored (status=${status})`,\n\t\tartifact,\n\t};\n}\n\n/**\n * Build a {@link HarnessExecutor} backed by a `refineLoop` per claimed\n * job.\n *\n * @example Eval-driven repair loop in the harness EXECUTE slot.\n * ```ts\n * const harness = harnessLoop(\"repair\", {\n * adapter,\n * executor: refineExecutor({\n * seedFrom: (item) => initialCatalogEntry(item),\n * datasetFor: (item) => pickAffectedTasks(item, allTasks),\n * evaluator: (cands, tasks) => runEvalBatch(cands, tasks),\n * strategy: errorCritique({ teacher, width: 3 }),\n * refine: { maxIterations: 5, minScore: 0.9 },\n * }),\n * });\n * ```\n */\nexport function refineExecutor<T>(config: RefineExecutorConfig<T>): HarnessExecutor<T> {\n\tconst name = config.name ?? \"refine-executor\";\n\tconst toOutput = config.toOutput ?? defaultToOutput<T>;\n\n\treturn (job: JobEnvelope<HarnessJobPayload<T>>) => {\n\t\tconst item = job.payload.item;\n\t\tconst loop = refineLoop<T>(config.seedFrom(item), config.evaluator, config.strategy, {\n\t\t\t...config.refine,\n\t\t\tdataset: config.datasetFor(item),\n\t\t\tname: `${name}/inner`,\n\t\t});\n\t\t// Terminal-allowlist guard — emit non-null only on `converged` / `budget` /\n\t\t// `errored`; intermediate `running` waves emit `null` (deduped via the\n\t\t// node's default Object.is). The trailing `filter(v != null)` strips\n\t\t// the null DATA so the JobFlow pump's first-DATA capture sees the\n\t\t// terminal payload, not the intermediate null.\n\t\tconst raw = node<HarnessJobPayload<T> | null>(\n\t\t\t[loop.status, loop.best, loop._score],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst s = data[0] as RefineStatus;\n\t\t\t\tif (s !== \"converged\" && s !== \"budget\" && s !== \"errored\") {\n\t\t\t\t\tactions.emit(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst exec = toOutput({\n\t\t\t\t\tbest: data[1] as T | null,\n\t\t\t\t\tscore: data[2] as number,\n\t\t\t\t\tstatus: s,\n\t\t\t\t});\n\t\t\t\tactions.emit({\n\t\t\t\t\t...job.payload,\n\t\t\t\t\texecution: { item, ...exec },\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: `${name}/output`, describeKind: \"derived\" },\n\t\t);\n\t\treturn filter(raw, (v) => v != null, { name: `${name}/gate-out` }) as ReturnType<\n\t\t\tHarnessExecutor<T>\n\t\t>;\n\t};\n}\n","/**\n * refineLoop — universal prompt/artifact optimization loop as a reactive Graph.\n *\n * Roadmap §9.8 (Wave 2.5). The loop is a 4-topic reactive pipeline:\n *\n * iterationTrigger ──▶ GENERATE ──▶ EVALUATE ──▶ ANALYZE ──▶ DECIDE\n * │ │\n * └─────── feedback + trigger ◀─────┘\n *\n * Each stage is a `TopicGraph` so dispatches stay O(1) per subscriber (cursor-\n * based) and every iteration is observable, replayable, and checkpointable.\n *\n * Composition invariants (from COMPOSITION-GUIDE):\n * - §7 feedback cycle: only `iterationTrigger` drives re-generation. Strategy\n * + feedback + dataset are read via closure updaters (§28 factory-time seed)\n * so mid-run swaps apply to the NEXT iteration, never retrigger the current.\n * - §28 factory-time seed: strategy, lastFeedback, prevCandidates, dataset\n * closures captured at wiring time + updated via subscribe handlers so the\n * first activation doesn't drop the initial pair.\n * - §32 nested-drain state-mirror: the decide-effect writes `lastFeedback`\n * BEFORE bumping `iterationTrigger` inside its `batch()`, guaranteeing the\n * mirror is current when the next-iteration wave reaches the generate fn.\n * - §19 terminal-emission: history / best emit once per iteration (settled),\n * not on every intermediate wave.\n * - §27 attachSnapshotStorage: the whole graph is checkpointable — pause overnight,\n * resume tomorrow from the exact iteration count, candidate set, strategy.\n *\n * Scope clamp (v1): core factory + `RefineStrategy<T>` + `blindVariation` and\n * `errorCritique` built-ins + budget gating + checkpoint/resume.\n * `mutateAndRefine` / registry / `autoSelectStrategy` / `optimizeCatalog` /\n * `refineExecutor` are deferred.\n *\n * @module\n */\n\n// `createNode` is the local alias for `node` so calls don't shadow\n// `Graph.prototype.node` when the file's body inadvertently references the\n// graph's `.node()` method. B5f keeps protocol-primitive construction visually\n// distinct from graph-instance method dispatch.\nimport {\n\tbatch,\n\tnode as createNode,\n\tDATA,\n\tERROR,\n\tmonotonicNs,\n\ttype Node,\n\tplaceholderArgs,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport type { NodeInput } from \"@graphrefly/pure-ts/extra\";\nimport { switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { tryIncrementBounded } from \"../../base/mutation/index.js\";\nimport { messagingHub, type TopicGraph } from \"../../utils/messaging/index.js\";\n\n// ---------------------------------------------------------------------------\n// Core types\n// ---------------------------------------------------------------------------\n\n/** A single task row — the unit the evaluator scores one candidate against. */\nexport interface DatasetItem {\n\treadonly id: string;\n\treadonly [k: string]: unknown;\n}\n\n/**\n * One candidate's score on one task. Higher is better by convention.\n *\n * Set `candidateIndex` when the evaluator fans out scores across multiple\n * candidates (e.g. `candidates × tasks`). `pickBest` aggregates mean scores\n * per `candidateIndex` when present; when absent, falls back to positional\n * alignment (`scores[i]` ↔ `candidates[i]`).\n */\nexport interface EvalResult {\n\treadonly taskId: string;\n\treadonly score: number;\n\treadonly error?: string;\n\treadonly detail?: unknown;\n\t/** 0-based index into the `candidates` batch this score belongs to. */\n\treadonly candidateIndex?: number;\n}\n\n/** Aggregated feedback the strategy produces from a scores batch. */\nexport interface Feedback {\n\treadonly summary: string;\n\treadonly critique?: unknown;\n\treadonly weakTasks?: readonly string[];\n\treadonly score: number;\n}\n\n/**\n * Strategy interface — plain object, no base class. Strategies implement three\n * pure hooks; the loop infrastructure wraps them in reactive nodes so every\n * decision is visible in `describe()`.\n *\n * `generate` may be sync or async. Async generates yield a microtask per\n * iteration — that's what gives `pause()` / `setStrategy()` a window to\n * interleave. **A fully synchronous `generate` will drain the entire loop\n * during factory activation** (all iterations run before `refineLoop()`\n * returns), which is usually not what you want for observable, steerable\n * loops. Real strategies that call LLMs / evals are async and Just Work;\n * custom sync strategies for tests are fine but should be marked `async`\n * to match real cadence.\n */\nexport interface RefineStrategy<T> {\n\treadonly name: string;\n\t/** Produce initial candidates from the seed. Called at iteration 0. */\n\tseed(seed: T): readonly T[];\n\t/** Reduce scores to feedback. Pure function. */\n\tanalyze(scores: readonly EvalResult[], candidates: readonly T[]): Feedback;\n\t/**\n\t * Generate next-iteration candidates from feedback + prior candidates.\n\t * Async allowed — the loop awaits via `fromAny`.\n\t */\n\tgenerate(feedback: Feedback, candidates: readonly T[]): Promise<readonly T[]> | readonly T[];\n}\n\n/**\n * Evaluator shape — Shape 4 (2026-04-22): both `candidates` and `dataset` are\n * reactive nodes; the evaluator's returned node IS the EVALUATE topic's source\n * (no glue). Implementers can batch-eval (e.g. `funnel` with concurrency) or\n * map per-candidate — user's code.\n *\n * **Cancel-on-input contract (load-bearing).** Evaluators with async work\n * (LLM calls, network requests, etc.) MUST cancel any in-flight work when\n * `candidates` emits a new batch. The canonical pattern is `switchMap` over\n * `candidates`. If an evaluator does NOT cancel — e.g. naively kicks a\n * `Promise.all` per-batch and emits whatever resolves — late scores from a\n * prior iteration can arrive after the loop has already moved to the next\n * iteration (especially after `pause()` / `resume()`). Such stale scores\n * trip {@link refineLoop}'s `feedbackEnvelopeNode` with mismatched\n * `iter`/`scores`/`items`, producing an incorrect `DecideEvent` and (worse)\n * marking the iter as decided so the real iter's scores get skipped by\n * de-dup, stalling the loop. See `optimizations.md` \"refineLoop async-\n * evaluator stale-scores follow-up\" for the proposed `wrapEvaluator()`\n * helper that would enforce cancellation.\n *\n * **`EvalResult.candidateIndex` semantics.** Optional per-result field.\n * When present, multi-candidate aggregators ({@link errorCritique}'s\n * `pickBest`) score per index, picking the candidate with the highest\n * mean score. When absent across all results, those aggregators fall back\n * to positional matching against `candidates[0]` — meaning a strategy that\n * generates >1 candidate but emits unindexed scores effectively only ever\n * critiques the first candidate. Set `candidateIndex` whenever the\n * evaluator's score corresponds to a specific candidate in the batch.\n */\nexport type Evaluator<T> = (\n\tcandidates: Node<readonly T[]>,\n\tdataset: Node<readonly DatasetItem[]>,\n) => Node<readonly EvalResult[]>;\n\n// ---------------------------------------------------------------------------\n// Convergence\n// ---------------------------------------------------------------------------\n\n/**\n * Early-stop controls. Each field fans into its own derived node; the four\n * combine via `||` into `converged: Node<boolean>`. Callers see exactly\n * which rule tripped via `status` / the DECIDE topic's `reason`.\n */\nexport interface ConvergenceOptions {\n\t/** Stop when aggregate score has not improved for N iterations. */\n\tpatience?: number;\n\t/** Stop when aggregate score reaches or exceeds this. */\n\tminScore?: number;\n\t/** Stop when absolute delta between consecutive scores falls below this. */\n\tminDelta?: number;\n\t/** Stop after N total evaluations (iteration count × per-iter candidates). */\n\tmaxEvaluations?: number;\n\t/** Stop after N iterations. Always set a finite bound in production. */\n\tmaxIterations?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Topic payloads (one per stage)\n// ---------------------------------------------------------------------------\n\n/** Emitted to the GENERATE topic each time the strategy produces a batch. */\nexport interface GenerateEvent<T> {\n\treadonly iteration: number;\n\treadonly candidates: readonly T[];\n\treadonly timestamp_ns: number;\n}\n\n/** Emitted to the EVALUATE topic when scores settle for an iteration. */\nexport interface EvaluateEvent<T> {\n\treadonly iteration: number;\n\treadonly candidates: readonly T[];\n\treadonly scores: readonly EvalResult[];\n\treadonly timestamp_ns: number;\n}\n\n/** Emitted to the ANALYZE topic — strategy's reduction over scores. */\nexport interface AnalyzeEvent<T> {\n\treadonly iteration: number;\n\treadonly candidates: readonly T[];\n\treadonly feedback: Feedback;\n\treadonly timestamp_ns: number;\n}\n\n/** Emitted to the DECIDE topic — branch taken this iteration. */\nexport interface DecideEvent {\n\treadonly iteration: number;\n\treadonly decision: \"continue\" | \"converged\" | \"budget\" | \"paused\";\n\treadonly reason?: string;\n\treadonly timestamp_ns: number;\n}\n\n// ---------------------------------------------------------------------------\n// Status + history\n// ---------------------------------------------------------------------------\n\nexport type RefineStatus = \"running\" | \"converged\" | \"budget\" | \"paused\" | \"errored\";\n\n/**\n * **Internal envelope** — carries the iteration number alongside the\n * candidates batch so `iter` rides the data wave through the pipeline. Lets\n * downstream stages read iter from a real reactive edge instead of from\n * `iterationTrigger.cache` (P3 violation; see /qa D1, 2026-05-01).\n *\n * Sidecar `candidatesItemsNode = derived([candidatesNode], ([env]) => env.items)`\n * preserves the user-facing `Evaluator<T>` API (which sees `Node<readonly T[]>`).\n */\ninterface CandidatesEnvelope<T> {\n\treadonly iter: number;\n\treadonly items: readonly T[];\n}\n\n/**\n * **Internal envelope** — assembled by `feedbackEnvelopeNode` from\n * `userScoresNode` + `candidatesNode`. Carries iter + items + scores +\n * feedback together as the trigger payload for `decideEffect` (`§16` nested\n * `withLatestFrom` advisory-samples history / budget / pause). Lets\n * `decideEffect` read iter from the envelope (no `iterationTrigger.cache` read)\n * AND ensures decideEffect only fires when the user evaluator has actually\n * emitted fresh scores (gate via `batchData[scores]` length, eliminating\n * spurious decides on candidates-only fan-out waves).\n */\ninterface FeedbackEnvelope<T> {\n\treadonly iter: number;\n\treadonly items: readonly T[];\n\treadonly scores: readonly EvalResult[];\n\treadonly feedback: Feedback;\n}\n\nexport interface Iteration<T> {\n\treadonly n: number;\n\treadonly candidates: readonly T[];\n\treadonly scores: readonly EvalResult[];\n\treadonly feedback: Feedback;\n\t/** `null` iff the candidate batch for this iteration was empty. */\n\treadonly best: T | null;\n\treadonly bestScore: number;\n\treadonly timestamp_ns: number;\n}\n\n// ---------------------------------------------------------------------------\n// Factory + returned graph\n// ---------------------------------------------------------------------------\n\nexport interface RefineLoopOptions extends ConvergenceOptions {\n\t/** Reactive dataset OR a plain array (auto-wrapped into `state`). */\n\tdataset: NodeInput<readonly DatasetItem[]> | readonly DatasetItem[];\n\t/** Total teacher calls cap across iterations. Default: unlimited. */\n\tbudget?: number;\n\t/** Graph name. Default: `\"refine-loop\"`. */\n\tname?: string;\n\t/** Extra graph options forwarded to the underlying `Graph`. */\n\tgraph?: GraphOptions;\n}\n\n/**\n * `class RefineLoopGraph<T> extends Graph` — the universal prompt/artifact\n * optimization loop as a reactive Graph subclass.\n *\n * Constructed via the {@link refineLoop} factory in normal use; exported as a\n * class so consumers can `instanceof`-narrow on returned values (Phase 13.G\n * `agent(spec)` is the consumer that motivated the migration). All\n * observability tools (`describe`, `explain`, `observe`, `attachSnapshotStorage`,\n * `snapshot`) Just Work since this `extends Graph`.\n *\n * **Phase 12.D (2026-04-30):** Migrated from `Object.assign(graph, ...)` factory\n * pattern to `class extends Graph` (Tier R5.1 deferral lifted; mirrors the\n * `MemoryWith*Graph` precedent). `setStrategy` / `pause` / `resume` are now\n * instance methods that read `this.strategy` / `this._pauseState` / `this.status`\n * / `this._iteration` instead of factory-local closures.\n */\nexport class RefineLoopGraph<T> extends Graph {\n\treadonly best: Node<T | null>;\n\t/**\n\t * Best score so far. Pseudo-private (`_score`) to avoid colliding with any\n\t * future `Graph.prototype.score` method (B5d forward-compat hazard\n\t * prevention). Typed-public — read via `loop._score.cache` /\n\t * `loop._score.subscribe(...)` from external code.\n\t */\n\treadonly _score: Node<number>;\n\treadonly status: Node<RefineStatus>;\n\treadonly history: Node<readonly Iteration<T>[]>;\n\treadonly strategy: Node<RefineStrategy<T>>;\n\t/**\n\t * Monotonic iteration counter. Pseudo-private (`_iteration`) to avoid\n\t * colliding with any future `Graph.prototype.iteration` method (B5d\n\t * forward-compat hazard prevention). Typed-public — read via\n\t * `loop._iteration.cache` / `loop._iteration.subscribe(...)`.\n\t */\n\treadonly _iteration: Node<number>;\n\t/** Stage topic — subscribe for per-stage streaming / cursor consumers. */\n\treadonly generate: TopicGraph<GenerateEvent<T>>;\n\t/** Stage topic — subscribe for per-stage streaming / cursor consumers. */\n\treadonly evaluate: TopicGraph<EvaluateEvent<T>>;\n\t/** Stage topic — subscribe for per-stage streaming / cursor consumers. */\n\treadonly analyze: TopicGraph<AnalyzeEvent<T>>;\n\t/** Stage topic — subscribe for per-stage streaming / cursor consumers. */\n\treadonly decide: TopicGraph<DecideEvent>;\n\n\t/** Internal: paused-flag node. Mounted as \"paused\" in describe(). */\n\tprivate readonly _pauseState: Node<boolean>;\n\n\tconstructor(\n\t\tseed: T,\n\t\tevaluator: Evaluator<T>,\n\t\tinitialStrategy: RefineStrategy<T>,\n\t\topts: RefineLoopOptions,\n\t) {\n\t\tconst name = opts.name ?? \"refine-loop\";\n\t\tsuper(name, opts.graph);\n\n\t\t// /qa A2 (2026-04-30): tag the Graph with its constructing factory so\n\t\t// `describe()` / `compileSpec` round-trip surfaces provenance — mirrors\n\t\t// the `agentMemory` pattern. `seed` / `evaluator` / `initialStrategy`\n\t\t// and option fields are non-JSON (functions, strategies); route through\n\t\t// `placeholderArgs` (DG2=ii) which substitutes `\"<function>\"` /\n\t\t// `\"<Node>\"` / `\"<unserializable>\"` for non-JSON values.\n\t\tthis.tagFactory(\n\t\t\t\"refineLoop\",\n\t\t\tplaceholderArgs({ seed, evaluator, initialStrategy, ...opts } as unknown as Record<\n\t\t\t\tstring,\n\t\t\t\tunknown\n\t\t\t>),\n\t\t);\n\n\t\t// --- Dataset: auto-wrap arrays into a state node ------------------------\n\t\tconst datasetNode: Node<readonly DatasetItem[]> = isNode<readonly DatasetItem[]>(opts.dataset)\n\t\t\t? opts.dataset\n\t\t\t: createNode<readonly DatasetItem[]>([], {\n\t\t\t\t\tname: \"dataset\",\n\t\t\t\t\tinitial: opts.dataset as readonly DatasetItem[],\n\t\t\t\t});\n\t\tthis.add(datasetNode, { name: \"dataset\" });\n\n\t\t// --- State nodes --------------------------------------------------------\n\t\tconst iterationTrigger = createNode<number>([], { name: \"iteration\", initial: 0 });\n\t\tthis.add(iterationTrigger, { name: \"iteration\" });\n\n\t\tconst strategyNode = createNode<RefineStrategy<T>>([], {\n\t\t\tname: \"strategy\",\n\t\t\tinitial: initialStrategy,\n\t\t\tequals: () => false, // always propagate strategy swaps\n\t\t});\n\t\tthis.add(strategyNode, { name: \"strategy\" });\n\n\t\tconst lastFeedbackState = createNode<Feedback | null>([], {\n\t\t\tname: \"lastFeedback\",\n\t\t\tinitial: null,\n\t\t});\n\t\tthis.add(lastFeedbackState, { name: \"lastFeedback\" });\n\n\t\tconst prevCandidatesState = createNode<readonly T[]>([], {\n\t\t\tname: \"prevCandidates\",\n\t\t\tinitial: [],\n\t\t});\n\t\tthis.add(prevCandidatesState, { name: \"prevCandidates\" });\n\n\t\tconst pauseState = createNode<boolean>([], { name: \"paused\", initial: false });\n\t\tthis.add(pauseState, { name: \"paused\" });\n\n\t\tconst statusState = createNode<RefineStatus>([], { name: \"status\", initial: \"running\" });\n\t\tthis.add(statusState, { name: \"status\" });\n\n\t\tconst historyState = createNode<readonly Iteration<T>[]>([], {\n\t\t\tname: \"history\",\n\t\t\tinitial: [],\n\t\t\tequals: () => false, // append-style; reactive consumers want every push\n\t\t});\n\t\tthis.add(historyState, { name: \"history\" });\n\n\t\tconst bestState = createNode<T | null>([], { name: \"best\", initial: null });\n\t\tthis.add(bestState, { name: \"best\" });\n\n\t\tconst scoreState = createNode<number>([], { name: \"score\", initial: Number.NEGATIVE_INFINITY });\n\t\tthis.add(scoreState, { name: \"score\" });\n\n\t\t// --- Budget counter -----------------------------------------------------\n\t\tconst budgetState = createNode<number>([], { name: \"budget-used\", initial: 0 });\n\t\tthis.add(budgetState, { name: \"budget-used\" });\n\n\t\t// --- Stage hub (Shape B + C-aspects) ------------------------------------\n\t\t// One messagingHub instead of four standalone TopicGraphs. Topics are\n\t\t// eagerly created so the public accessors (loop.generate etc.) are\n\t\t// available immediately without waiting for the first event to fire.\n\t\t// The hub is mounted in this so all stage topics appear under \"stages::\"\n\t\t// in describe()/explain() — visible edges, not closure-held singletons.\n\t\tconst hub = messagingHub(\"stages\");\n\t\tthis.mount(\"stages\", hub);\n\t\tconst hubGenerateTopic = hub.topic<GenerateEvent<T>>(\"generate\");\n\t\tconst hubEvaluateTopic = hub.topic<EvaluateEvent<T>>(\"evaluate\");\n\t\tconst hubAnalyzeTopic = hub.topic<AnalyzeEvent<T>>(\"analyze\");\n\t\tconst hubDecideTopic = hub.topic<DecideEvent>(\"decide\");\n\n\t\t// /qa A1 (2026-04-30): assign the public field surface BEFORE wiring\n\t\t// any effect / subscribe activation below. A synchronous strategy can\n\t\t// drain the entire GENERATE → EVALUATE → ANALYZE → DECIDE cascade\n\t\t// during the constructor body (see strategy doc above); fields must be\n\t\t// reachable in case any future subscribe handler dereferences `this.X`\n\t\t// during that synchronous drain. Defensive — no current handler reads\n\t\t// `this.<field>`, but keeping construction-order safe avoids future\n\t\t// undefined-field crashes.\n\t\tthis.best = bestState as Node<T | null>;\n\t\tthis._score = scoreState;\n\t\tthis.status = statusState;\n\t\tthis.history = historyState;\n\t\tthis.strategy = strategyNode;\n\t\tthis._iteration = iterationTrigger;\n\t\tthis.generate = hubGenerateTopic;\n\t\tthis.evaluate = hubEvaluateTopic;\n\t\tthis.analyze = hubAnalyzeTopic;\n\t\tthis.decide = hubDecideTopic;\n\t\tthis._pauseState = pauseState;\n\n\t\t// --- Factory-time seed closures (§28) -----------------------------------\n\t\t// These mirror the reactive dep values so the generate fn can read them\n\t\t// without the multi-dep push-on-subscribe initial-pair drop. Per\n\t\t// COMPOSITION-GUIDE-PROTOCOL.md §28: \"The closure reads inside the\n\t\t// reactive fn are NOT P3 violations — they read a closure variable,\n\t\t// not a `.cache`.\" Subscribe handlers run synchronously on dep DATA,\n\t\t// so the closure mirrors are always current by the time the generate\n\t\t// fn fires for the next iter.\n\t\tlet latestStrategy: RefineStrategy<T> = initialStrategy;\n\t\tlet latestFeedback: Feedback | null = null;\n\t\tlet latestPrevCandidates: readonly T[] = [];\n\t\tthis.addDisposer(\n\t\t\tstrategyNode.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestStrategy = m[1] as RefineStrategy<T>;\n\t\t\t}),\n\t\t);\n\t\tthis.addDisposer(\n\t\t\tlastFeedbackState.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestFeedback = m[1] as Feedback | null;\n\t\t\t}),\n\t\t);\n\t\tthis.addDisposer(\n\t\t\tprevCandidatesState.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestPrevCandidates = m[1] as readonly T[];\n\t\t\t}),\n\t\t);\n\n\t\t// --- GENERATE: iterationTrigger → candidates ----------------------------\n\t\t// switchMap cancels any in-flight generate when a new iteration fires.\n\t\t// At iteration 0, strategy.seed(seed). At iteration > 0, strategy.generate.\n\t\t//\n\t\t// Sync strategies emit in the same wave as `iterationTrigger` — no microtask\n\t\t// bridge. This eliminates the per-topic iteration race (Edge #5): all four\n\t\t// stage effects drain under one wave, so iteration numbers across\n\t\t// GENERATE / EVALUATE / ANALYZE / DECIDE are guaranteed identical.\n\t\t//\n\t\t// Async strategies still cross a Promise boundary — that's the strategy's\n\t\t// async-source contract (spec §5.10: async boundaries belong in sources).\n\t\t// Cancellation on strategy swap / pause / new iteration uses switchMap's\n\t\t// inner-node unsubscribe + a `cancelled` flag so late Promise resolutions\n\t\t// don't emit into a torn-down switchMap slot.\n\t\t//\n\t\t// **/qa D1 (2026-05-01) — envelope shape:** the inner producer emits\n\t\t// `{iter, items}` so `iter` rides the data wave through every downstream\n\t\t// stage. Eliminates the cross-node `iterationTrigger.cache` P3 violation\n\t\t// in `decideEffect` (and the resume-stall failure mode it caused). User-\n\t\t// facing evaluator API stays `Node<readonly T[]>` via the\n\t\t// `candidatesItemsNode` sidecar derived below.\n\t\tconst candidatesNode = switchMap<number, CandidatesEnvelope<T>>(\n\t\t\titerationTrigger,\n\t\t\t(iter) => {\n\t\t\t\tconst strat = latestStrategy;\n\t\t\t\tconst isSeed = iter === 0 || latestFeedback == null;\n\t\t\t\treturn createNode<CandidatesEnvelope<T>>(\n\t\t\t\t\t[],\n\t\t\t\t\t(_data, actions) => {\n\t\t\t\t\t\tlet cancelled = false;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst result = isSeed\n\t\t\t\t\t\t\t\t? strat.seed(seed)\n\t\t\t\t\t\t\t\t: strat.generate(latestFeedback as Feedback, latestPrevCandidates);\n\t\t\t\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t\t\t(v) => {\n\t\t\t\t\t\t\t\t\t\tif (!cancelled) actions.emit({ iter, items: v });\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\t\t\tif (!cancelled) actions.down([[ERROR, err]]);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t\t\t\tcancelled = true;\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tactions.emit({ iter, items: result });\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tcancelled = true;\n\t\t\t\t\t\t\tactions.down([[ERROR, err]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t},\n\t\t\t\t\t{ describeKind: \"producer\" },\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ name: \"candidates\" },\n\t\t);\n\t\tthis.add(candidatesNode, { name: \"candidates\" });\n\n\t\t// User-facing items sidecar: preserves the `Evaluator<T>` API\n\t\t// (`(candidates: Node<readonly T[]>, dataset: Node<readonly DatasetItem[]>) => ...`)\n\t\t// while the internal pipeline reads iter from the envelope.\n\t\tconst candidatesItemsNode = createNode<readonly T[]>(\n\t\t\t[candidatesNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst env = data[0] as CandidatesEnvelope<T> | undefined;\n\t\t\t\tif (env === undefined) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit(env.items);\n\t\t\t},\n\t\t\t{ name: \"candidates-items\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(candidatesItemsNode, { name: \"candidates-items\" });\n\n\t\t// Error watcher — strategy throws surface as ERROR on `candidatesNode`.\n\t\t// Promote to `status = \"errored\"` so callers don't have to subscribe to\n\t\t// the error channel directly.\n\t\tconst errorWatcher = createNode(\n\t\t\t[candidatesNode],\n\t\t\t(_batchData, _actions, ctx) => {\n\t\t\t\tconst terminal = ctx.terminalDeps[0];\n\t\t\t\tif (terminal !== undefined && terminal !== true) {\n\t\t\t\t\tstatusState.emit(\"errored\");\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ name: \"error-watcher\", describeKind: \"effect\", errorWhenDepsError: false },\n\t\t);\n\t\tthis.add(errorWatcher, { name: \"error-watcher\" });\n\t\tthis.addDisposer(errorWatcher.subscribe(() => undefined));\n\n\t\t// GENERATE stage: three nodes replace one monolithic effect.\n\t\t// (1) derived computes the event payload — reactive edge visible in explain().\n\t\t// (2) publish effect routes the derived event to the hub topic.\n\t\t// (3) mirror effect keeps prevCandidatesState in sync for §28 closure reads.\n\t\t// Budget accounting stays in decideEffect (single authority).\n\t\t// /qa D1: iter + items both come from the candidates envelope — no\n\t\t// separate `iterationTrigger` dep, no cross-node cache reads.\n\t\tconst generateEventNode = createNode<GenerateEvent<T>>(\n\t\t\t[candidatesNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst env = data[0] as CandidatesEnvelope<T>;\n\t\t\t\tactions.emit({\n\t\t\t\t\titeration: env.iter,\n\t\t\t\t\tcandidates: env.items,\n\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"generate-event\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(generateEventNode, { name: \"generate-event\" });\n\t\tthis.addDisposer(generateEventNode.subscribe(() => undefined));\n\n\t\tconst generatePublishEffect = createNode(\n\t\t\t[generateEventNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\thubGenerateTopic.publish(data[0] as GenerateEvent<T>);\n\t\t\t},\n\t\t\t{ name: \"generate-publish\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(generatePublishEffect, { name: \"generate-publish\" });\n\t\tthis.addDisposer(generatePublishEffect.subscribe(() => undefined));\n\n\t\tconst generateMirrorEffect = createNode(\n\t\t\t[candidatesNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst env = data[0] as CandidatesEnvelope<T>;\n\t\t\t\tprevCandidatesState.emit(env.items);\n\t\t\t},\n\t\t\t{ name: \"generate-mirror\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(generateMirrorEffect, { name: \"generate-mirror\" });\n\t\tthis.addDisposer(generateMirrorEffect.subscribe(() => undefined));\n\n\t\t// --- EVALUATE: candidates × dataset → scores ----------------------------\n\t\t// User evaluator sees the items sidecar (preserves `Evaluator<T>` API).\n\t\tconst scoresNode = evaluator(candidatesItemsNode, datasetNode);\n\t\tthis.add(scoresNode, { name: \"scores\" });\n\n\t\t// EVALUATE stage: derived event node + publish effect.\n\t\t// /qa D1: iter from candidates envelope; gate on `scoresFired` so a\n\t\t// candidates-only fan-out wave (e.g. async eval still in flight) does\n\t\t// NOT publish a stale evaluate event.\n\t\tconst evaluateEventNode = createNode<EvaluateEvent<T>>(\n\t\t\t[scoresNode, candidatesNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst scoresFired = batchData[0] != null && batchData[0].length > 0;\n\t\t\t\tif (!scoresFired) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst scores = data[0] as readonly EvalResult[];\n\t\t\t\tconst env = data[1] as CandidatesEnvelope<T>;\n\t\t\t\tactions.emit({\n\t\t\t\t\titeration: env.iter,\n\t\t\t\t\tcandidates: env.items,\n\t\t\t\t\tscores,\n\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"evaluate-event\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(evaluateEventNode, { name: \"evaluate-event\" });\n\t\tthis.addDisposer(evaluateEventNode.subscribe(() => undefined));\n\n\t\tconst evaluatePublishEffect = createNode(\n\t\t\t[evaluateEventNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\thubEvaluateTopic.publish(data[0] as EvaluateEvent<T>);\n\t\t\t},\n\t\t\t{ name: \"evaluate-publish\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(evaluatePublishEffect, { name: \"evaluate-publish\" });\n\t\tthis.addDisposer(evaluatePublishEffect.subscribe(() => undefined));\n\n\t\t// --- ANALYZE: strategy.analyze(scores, candidates) → feedbackEnvelope ---\n\t\t// /qa D1: feedbackEnvelope is the canonical iter-tagged trigger payload\n\t\t// for the DECIDE stage. Gates on `scoresFired` so a candidates-only\n\t\t// wave (async eval not settled yet) does NOT emit stale feedback into\n\t\t// `decideEffect`. When the user evaluator emits, both deps' caches are\n\t\t// consistent (candidates envelope carries iter that matches the scores\n\t\t// the user just produced — *assuming the user evaluator cancels async\n\t\t// work on candidates change; see Evaluator<T> JSDoc contract*).\n\t\tconst feedbackEnvelopeNode = createNode<FeedbackEnvelope<T>>(\n\t\t\t[scoresNode, candidatesNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst scoresFired = batchData[0] != null && batchData[0].length > 0;\n\t\t\t\tif (!scoresFired) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst scores = data[0] as readonly EvalResult[];\n\t\t\t\tconst env = data[1] as CandidatesEnvelope<T>;\n\t\t\t\tactions.emit({\n\t\t\t\t\titer: env.iter,\n\t\t\t\t\titems: env.items,\n\t\t\t\t\tscores,\n\t\t\t\t\tfeedback: latestStrategy.analyze(scores, env.items),\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"feedback-envelope\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(feedbackEnvelopeNode, { name: \"feedback-envelope\" });\n\n\t\t// User-facing feedback projection sidecar — preserves `feedback` path\n\t\t// for observers that consume the bare `Feedback` shape via\n\t\t// `loop.observe(\"feedback\")` etc.\n\t\tconst feedbackNode = createNode<Feedback>(\n\t\t\t[feedbackEnvelopeNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst fbEnv = data[0] as FeedbackEnvelope<T>;\n\t\t\t\tactions.emit(fbEnv.feedback);\n\t\t\t},\n\t\t\t{ name: \"feedback\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(feedbackNode, { name: \"feedback\" });\n\n\t\t// ANALYZE stage: derived event node + publish effect.\n\t\t// /qa D1: pull iter + items from feedbackEnvelopeNode (single source of\n\t\t// truth for the analyze beat). No cross-node cache reads.\n\t\tconst analyzeEventNode = createNode<AnalyzeEvent<T>>(\n\t\t\t[feedbackEnvelopeNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst fbEnv = data[0] as FeedbackEnvelope<T>;\n\t\t\t\tactions.emit({\n\t\t\t\t\titeration: fbEnv.iter,\n\t\t\t\t\tcandidates: fbEnv.items,\n\t\t\t\t\tfeedback: fbEnv.feedback,\n\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"analyze-event\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(analyzeEventNode, { name: \"analyze-event\" });\n\t\tthis.addDisposer(analyzeEventNode.subscribe(() => undefined));\n\n\t\tconst analyzePublishEffect = createNode(\n\t\t\t[analyzeEventNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\thubAnalyzeTopic.publish(data[0] as AnalyzeEvent<T>);\n\t\t\t},\n\t\t\t{ name: \"analyze-publish\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(analyzePublishEffect, { name: \"analyze-publish\" });\n\t\tthis.addDisposer(analyzePublishEffect.subscribe(() => undefined));\n\n\t\t// --- Convergence: four derived nodes fanning into one boolean -----------\n\t\tconst patienceNode = createNode<boolean>(\n\t\t\t[historyState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst h = data[0] as readonly Iteration<T>[];\n\t\t\t\tif (opts.patience == null || h.length <= opts.patience) {\n\t\t\t\t\tactions.emit(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// No improvement over the last `patience` iterations.\n\t\t\t\tconst lookback = h.slice(-(opts.patience + 1));\n\t\t\t\tconst baseline = lookback[0]!.bestScore;\n\t\t\t\tactions.emit(lookback.slice(1).every((i) => i.bestScore <= baseline));\n\t\t\t},\n\t\t\t{ name: \"patience-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(patienceNode, { name: \"patience-check\" });\n\n\t\tconst minScoreNode = createNode<boolean>(\n\t\t\t[scoreState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(opts.minScore != null && (data[0] as number) >= opts.minScore);\n\t\t\t},\n\t\t\t{ name: \"min-score-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(minScoreNode, { name: \"min-score-check\" });\n\n\t\tconst minDeltaNode = createNode<boolean>(\n\t\t\t[historyState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst h = data[0] as readonly Iteration<T>[];\n\t\t\t\tif (opts.minDelta == null || h.length < 2) {\n\t\t\t\t\tactions.emit(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst prev = h[h.length - 2]!.bestScore;\n\t\t\t\tconst curr = h[h.length - 1]!.bestScore;\n\t\t\t\tactions.emit(Math.abs(curr - prev) < opts.minDelta);\n\t\t\t},\n\t\t\t{ name: \"min-delta-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(minDeltaNode, { name: \"min-delta-check\" });\n\n\t\tconst maxEvalsNode = createNode<boolean>(\n\t\t\t[budgetState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(opts.maxEvaluations != null && (data[0] as number) >= opts.maxEvaluations);\n\t\t\t},\n\t\t\t{ name: \"max-evaluations-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(maxEvalsNode, { name: \"max-evaluations-check\" });\n\n\t\tconst maxIterNode = createNode<boolean>(\n\t\t\t[iterationTrigger],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(opts.maxIterations != null && (data[0] as number) >= opts.maxIterations);\n\t\t\t},\n\t\t\t{ name: \"max-iterations-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(maxIterNode, { name: \"max-iterations-check\" });\n\n\t\tconst budgetExhaustedNode = createNode<boolean>(\n\t\t\t[budgetState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(opts.budget != null && (data[0] as number) >= opts.budget);\n\t\t\t},\n\t\t\t{ name: \"budget-exhausted-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(budgetExhaustedNode, { name: \"budget-exhausted-check\" });\n\n\t\t// Activate convergence derivations so their cache stays current — decideEffect\n\t\t// reads their cache via external-boundary reads (§28). They must NOT be direct\n\t\t// deps: that would create a feedback cycle (decideEffect writes history/score,\n\t\t// convergence derives from those, cycle).\n\t\tthis.addDisposer(patienceNode.subscribe(() => undefined));\n\t\tthis.addDisposer(minScoreNode.subscribe(() => undefined));\n\t\tthis.addDisposer(minDeltaNode.subscribe(() => undefined));\n\t\tthis.addDisposer(maxEvalsNode.subscribe(() => undefined));\n\t\tthis.addDisposer(maxIterNode.subscribe(() => undefined));\n\t\tthis.addDisposer(budgetExhaustedNode.subscribe(() => undefined));\n\n\t\tconst convergedNode = createNode<{ converged: boolean; reason?: string }>(\n\t\t\t[patienceNode, minScoreNode, minDeltaNode, maxEvalsNode, maxIterNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst [p, ms, md, me, mi] = data;\n\t\t\t\tif (p) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"patience\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (ms) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"min-score\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (md) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"min-delta\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (me) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"max-evaluations\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (mi) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"max-iterations\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit({ converged: false });\n\t\t\t},\n\t\t\t{ name: \"converged\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(convergedNode, { name: \"converged\" });\n\t\tthis.addDisposer(convergedNode.subscribe(() => undefined));\n\n\t\t// --- DECIDE: feedbackEnvelope settles → fire next iteration OR terminate ---\n\t\t// **/qa D1 (2026-05-01) — reactive form via §32 envelope + sole-owner\n\t\t// `.cache` reads + reactive `pauseState` dep.** Two patterns at play:\n\t\t//\n\t\t// - **`iter` rides with the feedbackEnvelope payload** (§32 envelope).\n\t\t// Eliminates the original `iterationTrigger.cache` cross-node read\n\t\t// that caused the resume-stall (where iter.cache was bumped past\n\t\t// the candidates batch we're processing).\n\t\t//\n\t\t// - **`historyState` / `budgetState` are read via `.cache`** as a\n\t\t// sole-owner pattern: decideEffect is the SOLE WRITER + sole\n\t\t// reactive READER, both declared in the same enclosing constructor\n\t\t// scope. Reading their `.cache` here is \"read your own scratchpad\"\n\t\t// semantically, even though they're sibling Node objects. Adding\n\t\t// them as direct deps would create the §7 self-feedback cycle\n\t\t// (decideEffect writes them, would re-trigger itself); closure\n\t\t// mirrors would just duplicate state already held in the nodes\n\t\t// themselves. The comment block belongs to /qa D1 follow-up\n\t\t// (2026-05-01) — explicit user lock that sole-owner-and-reader\n\t\t// nodes in the same enclosing scope are a sanctioned `.cache` read\n\t\t// form.\n\t\t//\n\t\t// - **`pauseState` is a direct dep** because it's an EXTERNAL CONTROL\n\t\t// INPUT — written by `pause()` / `resume()` imperative methods at\n\t\t// the user-call boundary, NOT by decideEffect. Making it a real\n\t\t// declared edge surfaces \"this decision considers pause state\" in\n\t\t// `describe()` / `explain()` topology. The `feedbackFired` gate\n\t\t// below skips fn body execution when only pauseState fired (no new\n\t\t// iteration to decide).\n\t\t//\n\t\t// Trigger semantics: feedbackEnvelopeNode itself only fires when the\n\t\t// user evaluator emits fresh scores (gate via `batchData[scoresIdx]`\n\t\t// in feedbackEnvelopeNode), so a candidates-only fan-out wave (async\n\t\t// eval still in flight after `resume()`) does NOT spuriously trigger\n\t\t// decideEffect.\n\t\t//\n\t\t// **Score-staleness contract:** if the user's `Evaluator<T>` does NOT\n\t\t// cancel its async work when `candidates` changes, late scores from a\n\t\t// prior iter can emit to scoresNode and trip feedbackEnvelopeNode +\n\t\t// decideEffect with the new candidates' iter tag but stale scores\n\t\t// data. See `Evaluator<T>` JSDoc (cancel-on-input contract) and\n\t\t// `optimizations.md` \"refineLoop async-evaluator stale-scores\n\t\t// follow-up\" for the wrapper proposal.\n\t\t//\n\t\t// Track last-decided iteration to avoid re-deciding when feedbackEnv\n\t\t// re-fires within one wave (e.g. async evaluator emits multiple\n\t\t// scores per candidates change).\n\t\tlet lastDecidedIteration = -1;\n\t\tconst decideEffect = createNode(\n\t\t\t[feedbackEnvelopeNode, pauseState],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\t// `pauseState` is declared dep #1 — gate skips fn body when\n\t\t\t\t// only pauseState fired (no new iteration to decide; we just\n\t\t\t\t// want pauseState's prevData to advance for the next feedback\n\t\t\t\t// fire).\n\t\t\t\tconst feedbackFired = batchData[0] != null && batchData[0].length > 0;\n\t\t\t\tif (!feedbackFired) return;\n\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst fbEnv = data[0] as FeedbackEnvelope<T>;\n\t\t\t\tconst paused = data[1] as boolean;\n\n\t\t\t\tconst i = fbEnv.iter;\n\t\t\t\tconst fb = fbEnv.feedback;\n\t\t\t\tconst cs = fbEnv.items;\n\t\t\t\tconst scores = fbEnv.scores;\n\n\t\t\t\t// De-dup: only run once per iteration. fn may fire multiple\n\t\t\t\t// times per wave as feedbackEnvelopeNode settles.\n\t\t\t\tif (i <= lastDecidedIteration) return;\n\t\t\t\tlastDecidedIteration = i;\n\n\t\t\t\t// Sole-owner `.cache` reads — decideEffect is the SOLE\n\t\t\t\t// writer and sole reactive reader of these state nodes.\n\t\t\t\tconst currentHistory = historyState.cache as readonly Iteration<T>[];\n\t\t\t\tconst currentBudget = budgetState.cache as number;\n\n\t\t\t\t// Compute next history / score.\n\t\t\t\tconst { best, bestScore } = pickBest(cs, scores);\n\t\t\t\tconst iteration: Iteration<T> = {\n\t\t\t\t\tn: i,\n\t\t\t\t\tcandidates: cs,\n\t\t\t\t\tscores,\n\t\t\t\t\tfeedback: fb,\n\t\t\t\t\tbest,\n\t\t\t\t\tbestScore,\n\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t};\n\t\t\t\tconst nextHistory = [...currentHistory, iteration];\n\t\t\t\t// Budget accounting — decideEffect is the single authority.\n\t\t\t\tconst nextBudget = currentBudget + cs.length;\n\n\t\t\t\t// Inline convergence checks — single source of truth. The derived\n\t\t\t\t// `convergedNode` + friends exist for describe()/observe() surface;\n\t\t\t\t// inlining here avoids a drain-round-trip deadlock where decideEffect\n\t\t\t\t// would need convergedNode.cache to update before running, but\n\t\t\t\t// convergedNode needs historyState.emit from inside decideEffect.\n\t\t\t\tlet decision: DecideEvent[\"decision\"] = \"continue\";\n\t\t\t\tlet reason: string | undefined;\n\t\t\t\tconst budgetOut = opts.budget != null && nextBudget >= opts.budget;\n\t\t\t\tif (budgetOut) {\n\t\t\t\t\tdecision = \"budget\";\n\t\t\t\t\treason = \"budget\";\n\t\t\t\t} else if (opts.minScore != null && fb.score >= opts.minScore) {\n\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\treason = \"min-score\";\n\t\t\t\t} else if (opts.maxIterations != null && i >= opts.maxIterations) {\n\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\treason = \"max-iterations\";\n\t\t\t\t} else if (opts.maxEvaluations != null && nextBudget >= opts.maxEvaluations) {\n\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\treason = \"max-evaluations\";\n\t\t\t\t} else if (opts.minDelta != null && nextHistory.length >= 2) {\n\t\t\t\t\tconst prev = nextHistory[nextHistory.length - 2]!.bestScore;\n\t\t\t\t\tconst curr = nextHistory[nextHistory.length - 1]!.bestScore;\n\t\t\t\t\tif (Math.abs(curr - prev) < opts.minDelta) {\n\t\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\t\treason = \"min-delta\";\n\t\t\t\t\t}\n\t\t\t\t} else if (opts.patience != null && nextHistory.length > opts.patience) {\n\t\t\t\t\tconst lookback = nextHistory.slice(-(opts.patience + 1));\n\t\t\t\t\tconst baseline = lookback[0]!.bestScore;\n\t\t\t\t\tif (lookback.slice(1).every((it) => it.bestScore <= baseline)) {\n\t\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\t\treason = \"patience\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// paused takes precedence over continue — if paused AND no convergence,\n\t\t\t\t// we pause. Otherwise if converged we stop for real.\n\t\t\t\tif (decision === \"continue\" && paused) {\n\t\t\t\t\tdecision = \"paused\";\n\t\t\t\t}\n\n\t\t\t\t// All emissions in one batch — drain order is feedback mirror first\n\t\t\t\t// (§32), then iterationTrigger, so the next generate sees fresh fb.\n\t\t\t\t// `lastFeedbackState` is always mirrored (regardless of decision) so\n\t\t\t\t// resume-after-pause gets current feedback; only `iterationTrigger`\n\t\t\t\t// is gated on `continue`.\n\t\t\t\tbatch(() => {\n\t\t\t\t\tbestState.emit(best);\n\t\t\t\t\tscoreState.emit(fb.score);\n\t\t\t\t\thistoryState.emit(nextHistory);\n\t\t\t\t\tbudgetState.emit(nextBudget);\n\t\t\t\t\tlastFeedbackState.emit(fb);\n\t\t\t\t\thubDecideTopic.publish({\n\t\t\t\t\t\titeration: i,\n\t\t\t\t\t\tdecision,\n\t\t\t\t\t\treason,\n\t\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t\t});\n\n\t\t\t\t\tif (decision === \"continue\") {\n\t\t\t\t\t\titerationTrigger.emit(i + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstatusState.emit(\n\t\t\t\t\t\t\tdecision === \"converged\" ? \"converged\" : decision === \"budget\" ? \"budget\" : \"paused\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"decide-bridge\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(decideEffect, { name: \"decide-bridge\" });\n\t\tthis.addDisposer(decideEffect.subscribe(() => undefined));\n\n\t\t// /qa A1 (2026-04-30): public field surface (best / score / status /\n\t\t// history / strategy / iteration / generate / evaluate / analyze /\n\t\t// decide / _pauseState) is assigned EARLIER, immediately after the\n\t\t// stage hub is mounted (search \"qa A1\" above). Doing the assignment\n\t\t// before any subscribe activation keeps `this.<field>` reachable\n\t\t// during a synchronous strategy drain.\n\t}\n\n\t/** Swap the active strategy mid-run (human-in-the-loop handoff). */\n\tsetStrategy(next: RefineStrategy<T>): void {\n\t\tthis.strategy.emit(next);\n\t}\n\n\t/** Pause after the current iteration completes. */\n\tpause(): void {\n\t\tthis._pauseState.emit(true);\n\t}\n\n\t/**\n\t * Resume a paused loop. Idempotent: only un-pauses from the \"paused\"\n\t * terminal state. Converged / budget / errored are permanent — a user\n\t * wanting to start over should construct a fresh refineLoop.\n\t */\n\tresume(): void {\n\t\tif (this.status.cache !== \"paused\") return;\n\t\tbatch(() => {\n\t\t\tthis._pauseState.emit(false);\n\t\t\tthis.status.emit(\"running\" as RefineStatus);\n\t\t\tthis._iteration.emit((this._iteration.cache as number) + 1);\n\t\t});\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Structural type-guard for `Node<T>`. Checks the three core Node methods\n * (`subscribe`, `down`, `emit`) as callable properties — rejects plain objects\n * with a single `subscribe` field that happen to look like a Node but aren't.\n */\nfunction isNode<T>(x: unknown): x is Node<T> {\n\tif (typeof x !== \"object\" || x === null) return false;\n\tconst obj = x as Record<string, unknown>;\n\treturn (\n\t\ttypeof obj.subscribe === \"function\" &&\n\t\ttypeof obj.down === \"function\" &&\n\t\ttypeof obj.emit === \"function\"\n\t);\n}\n\nfunction pickBest<T>(\n\tcandidates: readonly T[],\n\tscores: readonly EvalResult[],\n): { best: T | null; bestScore: number } {\n\t// Empty batch → no best. Use `null` per COMPOSITION-GUIDE §3: `undefined`\n\t// is the protocol SENTINEL, `null` is the domain sentinel for \"no value\".\n\tif (candidates.length === 0) {\n\t\treturn { best: null, bestScore: Number.NEGATIVE_INFINITY };\n\t}\n\tif (candidates.length === 1) {\n\t\tconst mean = meanScore(scores);\n\t\treturn { best: candidates[0]!, bestScore: mean };\n\t}\n\t// Fan-out aware: when any score carries `candidateIndex`, aggregate mean\n\t// score per candidate. When absent, fall back to positional `scores[i]` ↔\n\t// `candidates[i]` alignment (one-score-per-candidate convention).\n\tconst hasFanOut = scores.some((s) => typeof s.candidateIndex === \"number\");\n\tif (hasFanOut) {\n\t\tconst sums = new Array<{ sum: number; count: number }>(candidates.length);\n\t\tfor (let i = 0; i < candidates.length; i++) sums[i] = { sum: 0, count: 0 };\n\t\tfor (const s of scores) {\n\t\t\tconst idx = s.candidateIndex;\n\t\t\tif (typeof idx === \"number\" && idx >= 0 && idx < candidates.length) {\n\t\t\t\tsums[idx]!.sum += s.score;\n\t\t\t\tsums[idx]!.count += 1;\n\t\t\t}\n\t\t}\n\t\tlet best = candidates[0]!;\n\t\tlet bestScore = sums[0]!.count > 0 ? sums[0]!.sum / sums[0]!.count : Number.NEGATIVE_INFINITY;\n\t\tfor (let i = 1; i < candidates.length; i++) {\n\t\t\tconst avg = sums[i]!.count > 0 ? sums[i]!.sum / sums[i]!.count : Number.NEGATIVE_INFINITY;\n\t\t\tif (avg > bestScore) {\n\t\t\t\tbestScore = avg;\n\t\t\t\tbest = candidates[i]!;\n\t\t\t}\n\t\t}\n\t\treturn { best, bestScore };\n\t}\n\tlet best = candidates[0]!;\n\tlet bestScore = scores[0]?.score ?? Number.NEGATIVE_INFINITY;\n\tfor (let i = 1; i < candidates.length; i++) {\n\t\tconst s = scores[i]?.score ?? Number.NEGATIVE_INFINITY;\n\t\tif (s > bestScore) {\n\t\t\tbestScore = s;\n\t\t\tbest = candidates[i]!;\n\t\t}\n\t}\n\treturn { best, bestScore };\n}\n\nfunction meanScore(scores: readonly EvalResult[]): number {\n\tif (scores.length === 0) return Number.NEGATIVE_INFINITY;\n\tlet sum = 0;\n\tfor (const s of scores) sum += s.score;\n\treturn sum / scores.length;\n}\n\n// ---------------------------------------------------------------------------\n// refineLoop factory\n// ---------------------------------------------------------------------------\n\n/**\n * Construct a {@link RefineLoopGraph} — the universal prompt/artifact\n * optimization loop. Thin wrapper over `new RefineLoopGraph(...)` for\n * call-site ergonomics.\n */\nexport function refineLoop<T>(\n\tseed: T,\n\tevaluator: Evaluator<T>,\n\tinitialStrategy: RefineStrategy<T>,\n\topts: RefineLoopOptions,\n): RefineLoopGraph<T> {\n\treturn new RefineLoopGraph<T>(seed, evaluator, initialStrategy, opts);\n}\n\n// ---------------------------------------------------------------------------\n// Built-in strategy: blindVariation\n// ---------------------------------------------------------------------------\n\n/**\n * Context passed to a `blindVariation` teacher per call. `reportCost` is a\n * per-call hook — see `BlindVariationOptions.tokens`.\n */\nexport interface BlindVariationContext<T> {\n\treadonly prior: T;\n\t/**\n\t * Report tokens consumed by this teacher call. Aggregated per iteration\n\t * and flushed to `opts.tokens` in the strategy's `finally` block so\n\t * partial spend is preserved when the teacher throws mid-batch.\n\t */\n\treadonly reportCost: (tokens: number) => void;\n}\n\nexport interface BlindVariationOptions<T> {\n\t/** Name — default: `\"blindVariation\"`. */\n\tname?: string;\n\t/** Number of candidates generated per iteration. Default: 4. */\n\twidth?: number;\n\t/**\n\t * Run teacher calls in parallel via `Promise.all`. Default `true` — the\n\t * common case (independent LLM calls). Set `false` to run sequentially\n\t * via `for/await` when teachers share stateful resources (rate limiters,\n\t * rolling context, serial API ordering) that don't tolerate concurrency.\n\t */\n\tparallel?: boolean;\n\t/**\n\t * Optional cost counter node. Running total tokens reported via\n\t * `ctx.reportCost` during each iteration is added to this node in the\n\t * strategy's `finally` block — fires on success AND on teacher throw so\n\t * partial spend is never lost. User owns the node; wire to `budgetGate`,\n\t * `attachSnapshotStorage`, telemetry, etc.\n\t */\n\ttokens?: Node<number>;\n\t/**\n\t * Teacher — given `{prior, reportCost}`, produce one variant. Async\n\t * allowed. Called `width` times per iteration. Call `ctx.reportCost(n)`\n\t * to track tokens consumed per call (optional, no-op if `opts.tokens`\n\t * is not set).\n\t */\n\tteacher: (ctx: BlindVariationContext<T>) => Promise<T> | T;\n}\n\n/**\n * Simplest built-in strategy: generate N variants per iteration via the\n * supplied `teacher`; no feedback-informed steering (equivalent to Random\n * Search). Validates the loop infrastructure end-to-end and is the baseline\n * every other strategy should outperform.\n *\n * `analyze` records the mean score and flags the worst task — strategies that\n * care about per-task critique layer on top.\n */\nexport function blindVariation<T>(opts: BlindVariationOptions<T>): RefineStrategy<T> {\n\tconst width = opts.width ?? 4;\n\tconst name = opts.name ?? \"blindVariation\";\n\treturn {\n\t\tname,\n\t\tseed(seed) {\n\t\t\t// Iteration 0 emits just the seed — strategy.seed is synchronous by\n\t\t\t// contract, so we can't call an async teacher here. `width`-many\n\t\t\t// teacher-produced variants begin at iteration 1 via `generate`.\n\t\t\treturn [seed];\n\t\t},\n\t\tanalyze(scores, _candidates) {\n\t\t\tconst score = meanScore(scores);\n\t\t\tlet worst: EvalResult | null = null;\n\t\t\tfor (const s of scores) {\n\t\t\t\tif (!worst || s.score < worst.score) worst = s;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tsummary: `blindVariation iteration: mean=${score.toFixed(3)}, n=${scores.length}`,\n\t\t\t\tscore,\n\t\t\t\tweakTasks: worst ? [worst.taskId] : [],\n\t\t\t};\n\t\t},\n\t\tasync generate(_feedback, candidates) {\n\t\t\tif (candidates.length === 0) {\n\t\t\t\t// Empty candidate batch is a contract violation — either the\n\t\t\t\t// seed was empty or a previous generate returned nothing. Surface\n\t\t\t\t// as an error rather than silently returning [] (which would\n\t\t\t\t// stall the loop in an infinite zero-candidate cycle).\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"blindVariation.generate: empty candidate batch — cannot derive prior for teacher\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Pick the current \"recent best\" — `null` IS a valid domain value\n\t\t\t// per COMPOSITION-GUIDE §3; the length guard above has already\n\t\t\t// filtered the `undefined` protocol sentinel.\n\t\t\tconst prior = candidates[candidates.length - 1] as T;\n\t\t\tlet iterCost = 0;\n\t\t\tconst reportCost = (n: number) => {\n\t\t\t\titerCost += n;\n\t\t\t};\n\t\t\tconst ctx: BlindVariationContext<T> = { prior, reportCost };\n\t\t\ttry {\n\t\t\t\tif (opts.parallel !== false) {\n\t\t\t\t\treturn await Promise.all(Array.from({ length: width }, () => opts.teacher(ctx)));\n\t\t\t\t}\n\t\t\t\tconst out: T[] = [];\n\t\t\t\tfor (let i = 0; i < width; i++) {\n\t\t\t\t\tout.push(await opts.teacher(ctx));\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t} finally {\n\t\t\t\tif (opts.tokens != null && iterCost > 0) {\n\t\t\t\t\t// /qa D1 follow-up (2026-05-01): replaced direct `.cache` read\n\t\t\t\t\t// + emit with `tryIncrementBounded`, which encapsulates the\n\t\t\t\t\t// self-owned-counter `.cache` access in the canonical helper\n\t\t\t\t\t// (sole sanctioned site per its JSDoc). Cap is unbounded for\n\t\t\t\t\t// the token meter.\n\t\t\t\t\ttryIncrementBounded(opts.tokens, Number.MAX_SAFE_INTEGER, iterCost);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Built-in strategy: errorCritique\n// ---------------------------------------------------------------------------\n\n/**\n * Context passed to an `errorCritique` teacher. `critique` is the pre-formatted\n * summary a prompt template can drop in verbatim; `failures` carries the\n * structured evidence (per-task error / score / detail) for richer prompts.\n */\nexport interface ErrorCritiqueContext<T> {\n\treadonly prior: T;\n\treadonly critique: string;\n\treadonly failures: readonly EvalResult[];\n\t/**\n\t * Report tokens consumed by this teacher call. Aggregated per iteration\n\t * and flushed to `opts.tokens` in the strategy's `finally` block so\n\t * partial spend is preserved when the teacher throws mid-batch.\n\t */\n\treadonly reportCost: (tokens: number) => void;\n}\n\nexport interface ErrorCritiqueOptions<T> {\n\t/** Name — default: `\"errorCritique\"`. */\n\tname?: string;\n\t/** Number of candidates generated per iteration. Default: 4. */\n\twidth?: number;\n\t/**\n\t * Cut-off below which a task is classified as a failure and fed into the\n\t * critique. Default: the batch mean — any task scoring below the batch\n\t * mean is a failure. Pass a number for an absolute cut-off, or a function\n\t * for per-batch computation (e.g. a percentile). When the default mean\n\t * is non-finite (NaN / ±Infinity from a degenerate evaluator), ALL scores\n\t * are treated as failures so the critique loop continues to steer.\n\t */\n\tfailureThreshold?: number | ((scores: readonly EvalResult[]) => number);\n\t/** Cap on failure samples packed into the critique. Default: 5. */\n\tmaxFailureSamples?: number;\n\t/**\n\t * Format failures into the `critique` string passed to the teacher. Default\n\t * joins `- taskId (score=N) | error: …` lines. Override to shape LLM prompts.\n\t *\n\t * **Note:** the `feedback` argument is a shell with `{score, weakTasks}`\n\t * populated; `summary` is empty because `analyze` computes the final summary\n\t * AFTER `formatCritique` runs (the summary embeds the formatted count).\n\t * Rely on `failures` and `feedback.score` — do not read `feedback.summary`\n\t * here.\n\t */\n\tformatCritique?: (failures: readonly EvalResult[], feedback: Feedback) => string;\n\t/**\n\t * Run teacher calls in parallel via `Promise.all`. Default `true` — the\n\t * common case (independent LLM calls). Set `false` to run sequentially\n\t * via `for/await` when teachers share stateful resources (rate limiters,\n\t * rolling context, serial API ordering) that don't tolerate concurrency.\n\t */\n\tparallel?: boolean;\n\t/**\n\t * Optional cost counter node. Running total tokens reported via\n\t * `ctx.reportCost` during each iteration is added to this node in the\n\t * strategy's `finally` block — fires on success AND on teacher throw so\n\t * partial spend is never lost. User owns the node; wire to `budgetGate`,\n\t * `attachSnapshotStorage`, telemetry, etc.\n\t */\n\ttokens?: Node<number>;\n\t/**\n\t * Teacher — given `{prior, critique, failures, reportCost}`, produce one\n\t * refined variant. Called `width` times per iteration. Async allowed.\n\t * Call `ctx.reportCost(n)` to track tokens consumed per call (optional,\n\t * no-op if `opts.tokens` is not set).\n\t */\n\tteacher: (ctx: ErrorCritiqueContext<T>) => Promise<T> | T;\n}\n\n/**\n * Private payload stashed inside `Feedback.critique` so `generate` can recover\n * the analyze-time prior + failure set without another pass over scores.\n */\ninterface ErrorCritiquePrivate<T> {\n\treadonly kind: \"errorCritique\";\n\treadonly best: T | null;\n\treadonly failures: readonly EvalResult[];\n\treadonly critiqueText: string;\n}\n\nfunction isErrorCritiquePrivate<T>(v: unknown): v is ErrorCritiquePrivate<T> {\n\treturn typeof v === \"object\" && v !== null && (v as { kind?: unknown }).kind === \"errorCritique\";\n}\n\nfunction defaultFormatCritique(failures: readonly EvalResult[], feedback: Feedback): string {\n\tif (failures.length === 0) {\n\t\treturn `No task scored below the batch mean (${feedback.score.toFixed(3)}). Reinforce the current direction.`;\n\t}\n\tconst lines = failures.map((f) => {\n\t\tconst err = f.error != null ? ` | error: ${f.error}` : \"\";\n\t\treturn `- ${f.taskId} (score=${f.score.toFixed(3)})${err}`;\n\t});\n\treturn `Failures below threshold:\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Critique-driven strategy (ProTeGi-style \"textual gradient\"). Each iteration:\n * 1. `analyze` classifies tasks scoring below a threshold as failures, picks\n * the best candidate from the batch, and packs both plus a formatted\n * critique string into `feedback.critique` as a private payload.\n * 2. `generate` unpacks that payload and calls the teacher with\n * `{prior, critique, failures, reportCost}` `width` times, returning the\n * refined batch.\n *\n * The teacher receives a pre-formatted string (drop into an LLM prompt) AND\n * the structured failure list (for richer prompts that want per-task detail).\n * Throws on empty candidate batches — matches `blindVariation`'s contract\n * (no silent zero-candidate cycles).\n *\n * When `setStrategy()` swaps this strategy in mid-run, the first `generate`\n * may receive a `Feedback` produced by the prior strategy (no private payload);\n * the fallback path uses `candidates[last]` as the prior and the feedback\n * summary as the critique, so the loop keeps running without a stall. When a\n * private payload IS present, `priv.critiqueText` takes precedence over any\n * edits a caller made to `feedback.summary` — treat `critique` as the\n * strategy-owned channel.\n */\nexport function errorCritique<T>(opts: ErrorCritiqueOptions<T>): RefineStrategy<T> {\n\tconst width = opts.width ?? 4;\n\tconst name = opts.name ?? \"errorCritique\";\n\tconst maxFailureSamples = opts.maxFailureSamples ?? 5;\n\tconst format = opts.formatCritique ?? defaultFormatCritique;\n\n\treturn {\n\t\tname,\n\t\tseed(seed) {\n\t\t\t// Iteration 0 emits just the seed. The critique loop begins at\n\t\t\t// iteration 1, once real scores exist to derive failures from.\n\t\t\treturn [seed];\n\t\t},\n\t\tanalyze(scores, candidates) {\n\t\t\tconst score = meanScore(scores);\n\t\t\tconst userThreshold =\n\t\t\t\ttypeof opts.failureThreshold === \"function\"\n\t\t\t\t\t? opts.failureThreshold(scores)\n\t\t\t\t\t: opts.failureThreshold;\n\t\t\t// A1: when the user didn't supply a threshold AND the batch-mean\n\t\t\t// default is non-finite (e.g. evaluator produced NaN / ±Infinity),\n\t\t\t// treat every score as a failure instead of filtering with `< NaN`\n\t\t\t// (which would be false for every score → silent no-op).\n\t\t\tconst thresholdUnresolvable = userThreshold === undefined && !Number.isFinite(score);\n\t\t\tconst threshold = userThreshold ?? score;\n\t\t\tconst allFailures = thresholdUnresolvable\n\t\t\t\t? [...scores].sort((a, b) => a.score - b.score)\n\t\t\t\t: scores\n\t\t\t\t\t\t.filter((s) => s.score < threshold)\n\t\t\t\t\t\t.slice()\n\t\t\t\t\t\t.sort((a, b) => a.score - b.score);\n\t\t\tconst failures = allFailures.slice(0, maxFailureSamples);\n\n\t\t\tconst { best, bestScore } = pickBest(candidates, scores);\n\t\t\tconst feedbackShell: Feedback = {\n\t\t\t\tsummary: \"\",\n\t\t\t\tscore,\n\t\t\t\tweakTasks: failures.map((f) => f.taskId),\n\t\t\t};\n\t\t\tconst critiqueText = format(failures, feedbackShell);\n\n\t\t\tconst priv: ErrorCritiquePrivate<T> = {\n\t\t\t\tkind: \"errorCritique\",\n\t\t\t\tbest,\n\t\t\t\tfailures,\n\t\t\t\tcritiqueText,\n\t\t\t};\n\t\t\tconst retainedSuffix =\n\t\t\t\tallFailures.length > failures.length ? ` (top ${failures.length} retained)` : \"\";\n\t\t\treturn {\n\t\t\t\tsummary: `errorCritique iteration: mean=${score.toFixed(3)}, failures=${allFailures.length}${retainedSuffix}/${scores.length}, bestScore=${bestScore.toFixed(3)}`,\n\t\t\t\tcritique: priv,\n\t\t\t\tweakTasks: failures.map((f) => f.taskId),\n\t\t\t\tscore,\n\t\t\t};\n\t\t},\n\t\tasync generate(feedback, candidates) {\n\t\t\t// N1: Length guard FIRST. The only protocol-sentinel risk is\n\t\t\t// `undefined` sneaking in via an empty candidates array; after\n\t\t\t// this check, `null` values (including `priv.best === null` when\n\t\t\t// T admits null) flow through as domain-valid per\n\t\t\t// COMPOSITION-GUIDE §3 / spec §1.\n\t\t\tif (candidates.length === 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"errorCritique.generate: empty candidate batch — cannot derive prior for teacher\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst priv = isErrorCritiquePrivate<T>(feedback.critique) ? feedback.critique : undefined;\n\t\t\tconst prior: T =\n\t\t\t\tpriv !== undefined ? (priv.best as T) : (candidates[candidates.length - 1] as T);\n\t\t\tconst critique = priv?.critiqueText ?? feedback.summary;\n\t\t\tconst failures = priv?.failures ?? [];\n\t\t\tlet iterCost = 0;\n\t\t\tconst reportCost = (n: number) => {\n\t\t\t\titerCost += n;\n\t\t\t};\n\t\t\tconst ctx: ErrorCritiqueContext<T> = { prior, critique, failures, reportCost };\n\t\t\ttry {\n\t\t\t\tif (opts.parallel !== false) {\n\t\t\t\t\treturn await Promise.all(Array.from({ length: width }, () => opts.teacher(ctx)));\n\t\t\t\t}\n\t\t\t\tconst out: T[] = [];\n\t\t\t\tfor (let i = 0; i < width; i++) {\n\t\t\t\t\tout.push(await opts.teacher(ctx));\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t} finally {\n\t\t\t\tif (opts.tokens != null && iterCost > 0) {\n\t\t\t\t\t// /qa D1 follow-up (2026-05-01): replaced direct `.cache` read\n\t\t\t\t\t// + emit with `tryIncrementBounded`, which encapsulates the\n\t\t\t\t\t// self-owned-counter `.cache` access in the canonical helper.\n\t\t\t\t\ttryIncrementBounded(opts.tokens, Number.MAX_SAFE_INTEGER, iterCost);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * Universal mutation framework (Phase 14 — DS-14 locked 2026-05-05).\n *\n * Single `mutate(act, opts)` factory replaces the prior `lightMutation` +\n * `wrapMutation` two-tier split (pre-1.0 break per Q-O2).\n *\n * Two frames:\n * - `\"inline\"` — no batch; up() runs raw. Seq bumps before action; persists\n * on throw. Hot-path-friendly for atomic single-write mutations.\n * - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n * deferred deliveries, then `down()` runs (if provided), then failure record.\n *\n * Phase-4 primitives share the same shape: imperative mutation methods +\n * closure state + reactive audit log + freeze-at-entry + rollback-on-throw.\n * This module factors out the common machinery so each primitive becomes\n * declarative wiring over typed audit records.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tDIRTY,\n\ttype Node,\n\ttype NodeGuard,\n\tnode,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype ReactiveLogBundle,\n\ttype ReactiveLogOptions,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\n\n// ── tryIncrementBounded ──────────────────────────────────────────────────\n\n/**\n * Bounded increment for a self-owned counter state node.\n *\n * Reads `counter.cache`, bumps by `by` (default 1) if `cur + by <= cap`,\n * writes back. Returns `false` when the cap would be exceeded (no-op write).\n * Documented P3 exception: the counter is not a declared dep of the caller —\n * it's a private budget read+written from a single call site. This helper\n * keeps the `.cache` access in one named place so caller bodies (which may\n * be inside reactive fn execution paths) stay free of cross-node `.cache`\n * reads.\n *\n * **Safety today:**\n * 1. Single-threaded JS runner never invokes the caller concurrently.\n * 2. `counter.down` writes the cache synchronously before returning, so\n * synchronous re-entry through a downstream publish reads the\n * freshly-incremented value — no double-count.\n *\n * **Future risk:** under a free-threaded runner (PY no-GIL or hypothetical\n * concurrent TS runner), two concurrent firings could still race. Revisit\n * when that surfaces.\n *\n * @param counter - Self-owned counter Node. Caller is the sole writer.\n * @param cap - Upper bound (inclusive). Pass `Number.MAX_SAFE_INTEGER` for\n * \"effectively unbounded\" use cases (e.g. token meters).\n * @param by - Delta to add (default `1`). Must be a finite non-negative\n * number; callers should pre-validate. Overflow-safe via\n * `by > cap - cur` check rather than `cur + by >= cap`.\n */\nexport function tryIncrementBounded(counter: Node<number>, cap: number, by = 1): boolean {\n\tconst cur = (counter.cache as number | undefined) ?? 0;\n\tif (by > cap - cur) return false;\n\tcounter.down([[DIRTY], [DATA, cur + by]]);\n\treturn true;\n}\n\n// ── Audit record schema ──────────────────────────────────────────────────\n\n/** Shared base shape for every audit record. Per-primitive types extend this. */\nexport interface BaseAuditRecord {\n\treadonly t_ns: number;\n\treadonly seq?: number;\n\treadonly handlerVersion?: { id: string; version: string | number };\n}\n\n// ── Default audit guard ──────────────────────────────────────────────────\n\n/**\n * Allow `observe` and `signal`; deny external `write` on the audit log so\n * consumers can subscribe + signal-bridge but cannot inject fake records.\n */\nexport const DEFAULT_AUDIT_GUARD: NodeGuard = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ── createAuditLog ───────────────────────────────────────────────────────\n\nexport type AuditLogOpts<R extends BaseAuditRecord> = {\n\tname: string;\n\t/** Bounded retention; default 1024 per Audit 2 / cross-cutting bounded-default policy. */\n\tretainedLimit?: number;\n\t/** Override the default audit guard. */\n\tguard?: NodeGuard;\n\t/** Mount the audit `entries` Node under this graph (and activate withLatest). */\n\tgraph?: Graph;\n\t/** Pass-through to {@link reactiveLog}. */\n\tversioning?: ReactiveLogOptions<R>[\"versioning\"];\n};\n\n/**\n * Build a reactive audit log with sane defaults: bounded retention, deny-write\n * guard, `withLatest()` companions activated. Returns the {@link ReactiveLogBundle}\n * directly — primitives expose this as `<primitive>.events` / `.decisions` /\n * `.dispatches` / `.invocations` and alias it as `.audit`.\n *\n * @category internal\n */\nexport function createAuditLog<R extends BaseAuditRecord>(\n\topts: AuditLogOpts<R>,\n): ReactiveLogBundle<R> {\n\tconst log = reactiveLog<R>([], {\n\t\tname: opts.name,\n\t\tmaxSize: opts.retainedLimit ?? 1024,\n\t\tguard: opts.guard ?? DEFAULT_AUDIT_GUARD,\n\t\t...(opts.versioning != null ? { versioning: opts.versioning } : {}),\n\t});\n\t// Lazy companion activation up-front so `bundle.lastValue` / `hasLatest`\n\t// are queryable without an explicit `withLatest()` call.\n\tlog.withLatest();\n\tif (opts.graph) {\n\t\topts.graph.add(log.entries, { name: opts.name });\n\t}\n\treturn log;\n}\n\n// ── Universal mutation factory (Phase 14 — DS-14 lock Q-O2/Q-O3) ────────\n//\n// Single `mutate(act, opts)` factory. Two frames:\n//\n// - `\"inline\"` — no batch frame; up() runs raw. Seq bumps before action;\n// persists on throw. Hot-path-friendly for atomic single-write mutations.\n//\n// - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n// deferred deliveries, then `down()` runs, then failure record persists.\n//\n// **Heuristic:** if your imperative method's body is one or two lines (mutate\n// state, emit), use `frame: \"inline\"`. If it runs a user-supplied handler or\n// has multiple steps that could leave inconsistent state mid-throw, use\n// `frame: \"transactional\"`.\n\nexport type FailureMeta = {\n\tt_ns: number;\n\tseq?: number;\n\terrorType: string;\n};\n\nexport type SuccessMeta = {\n\tt_ns: number;\n\tseq?: number;\n};\n\n/**\n * Mutation action shape. Plain function shorthand auto-wraps as `{ up: fn }`.\n *\n * - `up` — the mutation action (the \"up migration\").\n * - `down` — optional rollback for closure mutations that `batch()` can't\n * reach. Receives the SAME frozen args as `up`. Runs AFTER batch reactive\n * rollback, BEFORE the failure record. Throws inside `down` are\n * console.error'd without masking the original error. Only meaningful\n * with `frame: \"transactional\"`.\n */\nexport type MutationAct<TArgs extends readonly unknown[], TResult> = {\n\tup: (...args: TArgs) => TResult;\n\tdown?: (...args: TArgs) => void;\n};\n\nexport type MutationFrame = \"inline\" | \"transactional\";\n\nexport type MutateOpts<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord> = {\n\t/** Frame mode. `\"inline\"` = no batch; `\"transactional\"` = batch + rollback. */\n\tframe: MutationFrame;\n\t/**\n\t * Optional log to append records to. When omitted, the wrapper still\n\t * provides freeze / seq-advance / rollback-on-throw but skips record\n\t * emission — useful for primitives that want centralized mutation\n\t * semantics without a dedicated log surface (e.g. `Topic.publish`).\n\t */\n\tlog?: ReactiveLogBundle<R>;\n\t/** Build the success record from the action's args + result + meta. */\n\tonSuccessRecord?: (args: TArgs, result: TResult, meta: SuccessMeta) => R | undefined;\n\t/** Build the failure record from the args + error + meta. */\n\tonFailureRecord?: (args: TArgs, error: unknown, meta: FailureMeta) => R | undefined;\n\t/** Deep-freeze args at entry (default `true`). Opt out for hot paths. */\n\tfreeze?: boolean;\n\t/** Optional sequence cursor — auto-advanced and stamped onto records. */\n\tseq?: Node<number>;\n\t/** Optional handler version — stamped per Audit 5. */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n/**\n * Universal mutation factory (Phase 14 — DS-14 Q-O2).\n *\n * Replaces the prior `lightMutation` + `wrapMutation` two-tier split.\n * Single factory with `frame: \"inline\" | \"transactional\"` discriminant.\n *\n * @param act - The mutation action. Either a plain function (auto-wrapped as\n * `{ up: fn }`) or a `{ up, down? }` object for explicit rollback.\n * @param opts - Configuration: frame, log, record builders, freeze, seq.\n * @returns A typed wrapper function with the same signature as `act.up`.\n */\nexport function mutate<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord>(\n\tact: MutationAct<TArgs, TResult> | ((...args: TArgs) => TResult),\n\topts: MutateOpts<TArgs, TResult, R>,\n): (...args: TArgs) => TResult {\n\tconst { up, down } = typeof act === \"function\" ? { up: act, down: undefined } : act;\n\tconst freeze = opts.freeze ?? true;\n\n\tif (opts.frame === \"inline\") {\n\t\treturn function wrapped(...args: TArgs): TResult {\n\t\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\t\tconst t_ns = wallClockNs();\n\t\t\tconst seq = opts.seq ? bumpCursor(opts.seq) : undefined;\n\t\t\ttry {\n\t\t\t\tconst result = up(...sealed);\n\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tif (opts.log && opts.onFailureRecord) {\n\t\t\t\t\tconst errorType = err instanceof Error ? err.name : typeof err;\n\t\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\t}\n\n\t// frame === \"transactional\"\n\treturn function wrapped(...args: TArgs): TResult {\n\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\tconst t_ns = wallClockNs();\n\t\tlet result: TResult;\n\t\tlet captured: unknown;\n\t\tlet captureSet = false;\n\t\tlet seq: number | undefined;\n\t\ttry {\n\t\t\tbatch(() => {\n\t\t\t\tif (opts.seq) seq = bumpCursor(opts.seq);\n\t\t\t\ttry {\n\t\t\t\t\tresult = up(...sealed);\n\t\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\t\topts.log,\n\t\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\t\tsealed,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tcaptured = err;\n\t\t\t\t\tcaptureSet = true;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (outerErr) {\n\t\t\t// Fire `down` AFTER batch's reactive rollback, BEFORE failure record.\n\t\t\t// Gate on `captureSet` — if the throw came from outside the inner try\n\t\t\t// (framework-level batch error before action ran), don't fire down.\n\t\t\tif (captureSet && down) {\n\t\t\t\ttry {\n\t\t\t\t\tdown(...sealed);\n\t\t\t\t} catch (downErr) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`mutate: down hook threw — original action error preserved (${\n\t\t\t\t\t\t\tcaptured instanceof Error ? captured.name : typeof captured\n\t\t\t\t\t\t}). Down error:`,\n\t\t\t\t\t\tdownErr,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captureSet && opts.log && opts.onFailureRecord) {\n\t\t\t\tconst errorType = captured instanceof Error ? captured.name : typeof captured;\n\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\topts.log,\n\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\tsealed,\n\t\t\t\t\tcaptured,\n\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\topts.handlerVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow captureSet ? captured : outerErr;\n\t\t}\n\t\treturn result!;\n\t};\n}\n\n/**\n * Advance a cursor node and return the new value. Emits `[DIRTY], [DATA, next]`\n * directly on the cursor — atomic outside a batch, rollback-discardable inside.\n *\n * Resets to `0` if the cursor cache is missing, non-numeric, `NaN`, or\n * non-finite (e.g. corrupted by `restore()` from a malformed snapshot, or\n * by a misbehaving codec). `??` alone would let `NaN` and `\"\"` pass through\n * and silently corrupt audit ordering downstream.\n *\n * **Silent reset diagnostic (EH-12).** When the cache holds a non-numeric\n * value at bump time, the cursor restarts at 0 and the next bump returns 1\n * — colliding with the seq stamped on the very first record after construct.\n * To make seq-monotonicity violations after a restore visible to operators,\n * the helper emits a one-shot `console.warn` per cursor instance describing\n * the offending value. The cursor is identified by a `WeakSet<Node<number>>`\n * so the warning fires exactly once per node — repeat malformed bumps stay\n * quiet to avoid log spam. Production callers wanting to suppress can swap\n * the global `console` (universal-safe code path; no Node-only API used).\n *\n * Works whether or not the cursor has any subscribers — `down` updates the\n * cache regardless, so primitives that bump before consumers attach (e.g.\n * `JobQueueGraph.enqueue`) still see a coherent sequence.\n *\n * @category internal\n */\nconst _bumpCursorWarned = new WeakSet<Node<number>>();\nexport function bumpCursor(seq: Node<number>): number {\n\tconst raw = seq.cache;\n\tconst valid = typeof raw === \"number\" && Number.isFinite(raw);\n\tif (!valid && raw !== undefined && !_bumpCursorWarned.has(seq)) {\n\t\t_bumpCursorWarned.add(seq);\n\t\tconsole.warn(\n\t\t\t`bumpCursor: cursor cache held a non-numeric value (${String(raw)}); resetting to 0. ` +\n\t\t\t\t\"Causes include: a snapshot codec round-tripping the cursor as a string / null / NaN, \" +\n\t\t\t\t\"OR a malformed initial seed (e.g. state<number>(NaN)). \" +\n\t\t\t\t\"Audit consumers may see colliding seq values after this point.\",\n\t\t);\n\t}\n\tconst cur = valid ? raw : 0;\n\tconst next = cur + 1;\n\tseq.down([[DIRTY], [DATA, next]]);\n\treturn next;\n}\n\n/**\n * Build a record via the supplied builder, stamp `handlerVersion` if present,\n * and append it to the audit log. `undefined` records are skipped (callers\n * pass an `onSuccess` / `onFailure` that returns `undefined` to opt out per\n * call).\n *\n * @category internal\n */\nexport function appendAudit<\n\tTArgs extends readonly unknown[],\n\tTValue,\n\tR extends BaseAuditRecord,\n\tM extends SuccessMeta | FailureMeta,\n>(\n\taudit: ReactiveLogBundle<R>,\n\tbuilder: (args: TArgs, value: TValue, meta: M) => R | undefined,\n\targs: TArgs,\n\tvalue: TValue,\n\tmeta: M,\n\thandlerVersion?: { id: string; version: string | number },\n): void {\n\tconst record = builder(args, value, meta);\n\tif (record === undefined) return;\n\tconst stamped = handlerVersion != null ? ({ ...record, handlerVersion } as R) : record;\n\taudit.append(stamped);\n}\n\n// ── registerCursor / registerCursorMap ───────────────────────────────────\n\n/**\n * Promote a closure counter to a state node mounted under `graph`.\n * Replaces ad-hoc `let _seq = 0` patterns with a node observable in\n * `describe()` and persistable via storage tiers.\n *\n * @category internal\n */\nexport function registerCursor(graph: Graph, name: string, initial = 0): Node<number> {\n\tconst cursor = node<number>([], { initial, name, describeKind: \"state\" });\n\tgraph.add(cursor, { name });\n\treturn cursor;\n}\n\n/**\n * Promote a closure `Map<K, number>` to N state nodes (one per key) mounted\n * under `<graph>::<name>::<key>`. Used by saga (per-event-type cursor).\n *\n * @category internal\n */\nexport function registerCursorMap<K extends string>(\n\tgraph: Graph,\n\tname: string,\n\tkeys: readonly K[],\n\tinitial = 0,\n): { readonly [P in K]: Node<number> } {\n\tconst out = {} as { [P in K]: Node<number> };\n\t// Mount cursors under a child plain-Graph so per-key node names stay flat\n\t// (path-separator `::` is reserved by Graph.add). Using `Graph` directly\n\t// rather than `graph.constructor` avoids spawning a typed subclass with\n\t// an incompatible constructor signature (e.g., CqrsGraph(name, opts)).\n\tconst sub = new Graph(name);\n\tfor (const k of keys) {\n\t\tconst cursor = node<number>([], {\n\t\t\tinitial,\n\t\t\tname: k,\n\t\t\tdescribeKind: \"state\",\n\t\t});\n\t\tsub.add(cursor, { name: k });\n\t\tout[k] = cursor;\n\t}\n\tgraph.mount(name, sub);\n\treturn out;\n}\n","/**\n * Standard `TopicMessage<T>` envelope for hub topics + well-known topic name\n * constants (Phase 13.B; spec source: archive/docs/SESSION-human-llm-intervention-primitives.md\n * §6 + archive/docs/SESSION-multi-agent-gap-analysis.md §6 cross-cut).\n *\n * `TopicMessage<T>` is the **recommended** wrapper for cross-agent / cross-graph\n * topic payloads — it carries identity, schema, deadline, and correlation\n * metadata alongside the typed `payload`. It is NOT a required protocol\n * type; raw `topic<T>` continues to work for in-process payloads where the\n * envelope fields would be noise.\n *\n * Use the envelope when:\n * - Two or more graphs (or human + LLM consumers) communicate over a topic\n * and need a stable wire shape — `correlationId` is the join key, `schema`\n * gates payload validation, `expiresAt` enables TTL enforcement.\n * - A topic carries multiple payload kinds and consumers need to discriminate\n * without parsing structurally.\n *\n * The standard well-known topic constants below are **conventions** — string\n * literals callers can pass to `messagingHub().topic(NAME)` to get a\n * predictable lookup. The hub does not enforce any topic to actually exist;\n * topics are still lazy on first access.\n */\n\n// ---------------------------------------------------------------------------\n// JSON Schema — minimal local type\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal JSON Schema shape, scoped to what `TopicMessage<T>` validates against.\n * Locked DS-13.B (2026-04-30): zero-dep posture, structural shape only — no\n * full validator shipped. Callers that want full validation supply their own\n * (e.g. `ajv`, `zod`, `valibot`) and read `Message.schema` as the rule\n * source. The shape covers the JSON-Schema-7 subset that hub-topic payload\n * descriptions actually need:\n * - `type` / `properties` / `required` / `additionalProperties` for objects.\n * - `items` for arrays.\n * - `enum` / `const` for value constraints.\n * - `$ref` / `definitions` for shared sub-schemas.\n *\n * If a concrete consumer needs a richer shape (oneOf, allOf, format, etc.),\n * extend this type — it's a structural contract, not a tagged union, so\n * additive fields don't break existing producers.\n */\nexport interface JsonSchema {\n\treadonly type?:\n\t\t| \"string\"\n\t\t| \"number\"\n\t\t| \"integer\"\n\t\t| \"boolean\"\n\t\t| \"object\"\n\t\t| \"array\"\n\t\t| \"null\"\n\t\t| readonly (\"string\" | \"number\" | \"integer\" | \"boolean\" | \"object\" | \"array\" | \"null\")[];\n\treadonly properties?: Readonly<Record<string, JsonSchema>>;\n\treadonly required?: readonly string[];\n\treadonly additionalProperties?: boolean | JsonSchema;\n\treadonly items?: JsonSchema | readonly JsonSchema[];\n\treadonly enum?: readonly unknown[];\n\treadonly const?: unknown;\n\treadonly $ref?: string;\n\treadonly definitions?: Readonly<Record<string, JsonSchema>>;\n\treadonly description?: string;\n\treadonly title?: string;\n}\n\n// ---------------------------------------------------------------------------\n// TopicMessage<T> envelope\n// ---------------------------------------------------------------------------\n\n/**\n * Recommended envelope for hub topic payloads. Carries identity, optional\n * schema reference, optional expiry, optional correlation, and the typed\n * payload itself.\n *\n * - `id` — globally-unique identifier for this message instance. Producers\n * mint it (UUID, ULID, hash, etc.); consumers use it for deduplication and\n * trace correlation. **Required.**\n * - `schema` — optional structural description of `payload`. Validators\n * (caller-supplied) read this to gate or shape consumption. Writers MAY\n * include the schema inline for self-describing topics, or omit when the\n * payload type is statically known to all consumers.\n * - `expiresAt` — ISO 8601 timestamp; consumers SHOULD drop / fallback past\n * this point. Substrate enforcement is via composition (`timeout(source,\n * ms)` + `fallback`), not a hub-level rule.\n * - `correlationId` — links related messages across topics (request /\n * response pairs, conversation threads, multi-agent handoffs). Producers\n * propagate it; consumers filter / group on it.\n * - `payload` — the typed body. Type parameter `T` is the consumer-agreed\n * shape; the envelope adds metadata around it without coupling consumers\n * to a concrete payload type.\n *\n * Reactive composition with the envelope:\n *\n * ```ts\n * const requests = hub.topic<TopicMessage<RequestBody>>(PROMPTS_TOPIC);\n * const responses = hub.topic<TopicMessage<ResponseBody>>(RESPONSES_TOPIC);\n *\n * // Filter responses to one correlation\n * const myResponse = derived([responses.latest], ([msg]) =>\n * msg?.correlationId === requestId ? [msg.payload] : [],\n * );\n * ```\n */\nexport interface TopicMessage<T> {\n\treadonly id: string;\n\treadonly schema?: JsonSchema;\n\treadonly expiresAt?: string;\n\treadonly correlationId?: string;\n\treadonly payload: T;\n}\n\n// ---------------------------------------------------------------------------\n// Standard topic name constants\n// ---------------------------------------------------------------------------\n\n/**\n * Well-known topic name for human / LLM prompts directed at the harness.\n * Example payload: `TopicMessage<{ prompt: string; context?: object }>`.\n *\n * Co-locked with {@link RESPONSES_TOPIC} per the human-LLM intervention\n * session §6 #4 (paired request / response convention).\n */\nexport const PROMPTS_TOPIC = \"prompts\";\n\n/**\n * Well-known topic name for responses to {@link PROMPTS_TOPIC} entries.\n * Producers pair the response to its prompt via `correlationId`. Example\n * payload: `TopicMessage<{ content: string; finishReason?: string }>`.\n */\nexport const RESPONSES_TOPIC = \"responses\";\n\n/**\n * Well-known topic name for out-of-band injections — runtime overrides /\n * hot-fixes / human nudges that bypass the normal request flow. Example\n * payload: `TopicMessage<{ kind: \"context-patch\" | \"policy-override\" | ...;\n * data: unknown }>`. Per-injection consumers decide how (and whether) to\n * apply.\n */\nexport const INJECTIONS_TOPIC = \"injections\";\n\n/**\n * Well-known topic name for items the harness deferred for later attention\n * (parked queue, follow-up tracker, \"I'll get back to this\"). Producer is\n * usually the harness itself; consumer is a tracker / dashboard / human.\n * Example payload: `TopicMessage<{ reason: string; original: unknown }>`.\n */\nexport const DEFERRED_TOPIC = \"deferred\";\n\n/**\n * Well-known topic name for spawn requests (Phase 13.I `spawnable()`\n * surface). Producer emits a `TopicMessage<SpawnRequest>` to request a child\n * agent / subgraph; consumer is the materializer that mints the slot.\n * Example payload: `TopicMessage<{ presetId: string; taskInput: unknown;\n * depth?: number }>`. `correlationId` links the spawn to its parent\n * conversation; `expiresAt` enforces TTL on long-lived requests.\n */\nexport const SPAWNS_TOPIC = \"spawns\";\n\n/**\n * DS-14.6.A D-B3 — well-known topic for the dynamic `actorPool()` shared\n * tagged-context pool. Actors publish `ContextEntry` here; per-actor views\n * render their own compressed slice.\n */\nexport const CONTEXT_TOPIC = \"context\";\n\n/**\n * DS-14.6.A D-B3 — well-known topic for the `actorPool()` shared todo list.\n * Any actor may `enqueueTodo`; actors pull assigned todos via their cursor.\n */\nexport const TODOS_TOPIC = \"todos\";\n\n/**\n * Tuple of all well-known topic constants — useful for \"register all\n * standard topics on a hub\" patterns and for compile-time exhaustiveness\n * checks.\n */\nexport const STANDARD_TOPICS = [\n\tPROMPTS_TOPIC,\n\tRESPONSES_TOPIC,\n\tINJECTIONS_TOPIC,\n\tDEFERRED_TOPIC,\n\tSPAWNS_TOPIC,\n\tCONTEXT_TOPIC,\n\tTODOS_TOPIC,\n] as const;\n\n/**\n * Union of all well-known topic name string literals.\n */\nexport type StandardTopic = (typeof STANDARD_TOPICS)[number];\n","/**\n * Messaging patterns (roadmap §4.2).\n *\n * Pulsar-inspired messaging primitives modeled as graph factories:\n * - `topic()` for append-only topic streams with a retained window.\n * - `subscription()` for cursor-based consumers.\n * - `topicBridge()` for autonomous topic-to-topic relay.\n * - `messagingHub()` for a lazy topic registry.\n *\n * Plus the Phase 13.B standard `Message<T>` envelope and well-known topic\n * name constants ({@link PROMPTS_TOPIC} / {@link RESPONSES_TOPIC} /\n * {@link INJECTIONS_TOPIC} / {@link DEFERRED_TOPIC} / {@link SPAWNS_TOPIC})\n * — recommended (not enforced) wire shape for cross-graph topic payloads.\n *\n * Job queue / job flow primitives live in `patterns/job-queue` — they are a\n * distinct domain that happens to share reactive-log / reactive-map\n * infrastructure with topics.\n */\n\nexport {\n\ttype HubRemoveTopicRecord,\n\thubRemoveTopicKeyOf,\n\ttype MessagingAuditRecord,\n\ttype SubscriptionAckRecord,\n\ttype SubscriptionPullAndAckRecord,\n\tsubscriptionAckKeyOf,\n\tsubscriptionPullAndAckKeyOf,\n\ttype TopicPublishRecord,\n\ttopicPublishKeyOf,\n} from \"./audit-records.js\";\nexport {\n\tCONTEXT_TOPIC,\n\tDEFERRED_TOPIC,\n\tINJECTIONS_TOPIC,\n\ttype JsonSchema,\n\tPROMPTS_TOPIC,\n\tRESPONSES_TOPIC,\n\tSPAWNS_TOPIC,\n\tSTANDARD_TOPICS,\n\ttype StandardTopic,\n\tTODOS_TOPIC,\n\ttype TopicMessage,\n} from \"./message.js\";\n\nimport { batch, COMPLETE, DATA, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { keepalive, type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport { mutate } from \"../../base/mutation/index.js\";\n\nconst DEFAULT_MAX_PER_PUMP = 256;\n\nfunction requireNonNegativeInt(value: number, label: string): number {\n\tif (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {\n\t\tthrow new Error(`${label} must be a non-negative integer`);\n\t}\n\treturn value;\n}\n\nfunction messagingMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"messaging\", kind, extra);\n}\n\nexport type TopicOptions = {\n\tgraph?: GraphOptions;\n\t/** Bounded retention; default 1024 per cross-cutting policy (Audit 2/4). */\n\tretainedLimit?: number;\n};\n\nconst DEFAULT_TOPIC_RETAINED_LIMIT = 1024;\n\nexport class TopicGraph<T> extends Graph {\n\tprivate readonly _log;\n\tprivate readonly _publishImpl: (value: T) => void;\n\treadonly events: Node<readonly T[]>;\n\t/**\n\t * Most recently published value. Stays in the protocol SENTINEL state\n\t * (`cache === undefined`, no DATA emitted) until the first publish, then\n\t * tracks the latest entry. Spec §5.12 reserves `undefined` as the\n\t * \"never sent DATA\" sentinel — and `TopicGraph.publish(undefined)` is\n\t * rejected — so `cache === undefined` unambiguously signals \"empty topic\"\n\t * even when `T` itself includes `null` (i.e., `topic<number | null>`).\n\t *\n\t * **Within a reactive fn:** detect the empty-topic case via\n\t * `ctx.prevData[i] === undefined` for the dep slot holding `topic.latest`,\n\t * or check `latest.cache === undefined` outside reactive code. No\n\t * separate `hasLatest` companion needed — the SENTINEL is the answer.\n\t */\n\treadonly latest: Node<T>;\n\n\tconstructor(name: string, opts: TopicOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis._log = reactiveLog<T>([], {\n\t\t\tname: \"events\",\n\t\t\tmaxSize: opts.retainedLimit ?? DEFAULT_TOPIC_RETAINED_LIMIT,\n\t\t});\n\t\tthis.events = this._log.entries;\n\t\tthis.add(this.events, { name: \"events\" });\n\t\t// `this.derived(\"latest\", [\"events\"], …)` is expressible after the\n\t\t// 2026-04-30 self-resolve fix in `Graph._resolveFromSegments` — a\n\t\t// single-segment path matching the graph's own name (e.g.\n\t\t// `topic(\"events\").resolve(\"events\")`) no longer collapses to empty\n\t\t// and falls through to local-node lookup. Replaces the prior\n\t\t// `node([events], …) + this.add(...)` workaround.\n\t\t//\n\t\t// SENTINEL on empty: returning `[]` here yields a RESOLVED-only wave\n\t\t// (no DATA), so `latest.cache` stays `undefined` until the first\n\t\t// publish. `TopicGraph.publish(undefined)` is rejected (line below),\n\t\t// so `undefined` cache is unambiguously \"empty topic\" even when `T`\n\t\t// itself includes `null`. Drops the prior `hasLatest` companion as\n\t\t// redundant.\n\t\tthis.latest = this.derived<T>(\n\t\t\t\"latest\",\n\t\t\t[\"events\"],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst entries = data[0] as readonly T[];\n\t\t\t\treturn entries.length === 0 ? [] : [entries[entries.length - 1] as T];\n\t\t\t},\n\t\t\t{ meta: messagingMeta(\"topic_latest\") },\n\t\t);\n\t\tthis.addDisposer(keepalive(this.latest));\n\n\t\t// D1(a): on teardown, propagate COMPLETE on `events` so downstream\n\t\t// derived chains (including any externally-held SubscriptionGraph\n\t\t// sources) see the termination via their `terminalDeps` and can stop\n\t\t// serving stale caches. Tier-3 terminal per spec §2.2.\n\t\t//\n\t\t// EC16 (verified 2026-04-30): the COMPLETE-then-disposeAllViews order\n\t\t// is intentional. COMPLETE propagates SYNCHRONOUSLY through every\n\t\t// subscriber (cursor views, derived chains) so they self-unsubscribe\n\t\t// in their terminal handler before `disposeAllViews` runs. Swapping\n\t\t// the order would clear view caches before subscribers receive the\n\t\t// terminal — strictly worse. Reading `.cache` outside a reactive fn\n\t\t// across teardown is an anti-pattern (spec §5.12) and not a use case\n\t\t// this ordering needs to preserve.\n\t\tthis.addDisposer(() => {\n\t\t\tthis.events.down([[COMPLETE]]);\n\t\t});\n\t\t// P9: release any memoized tail/slice view keepalives held by the log.\n\t\t// TopicGraph itself doesn't call log.tail/slice, but plugins may have\n\t\t// attached views via `_log` — defensive (typical reactive subscribers\n\t\t// have already unsubscribed in their COMPLETE handler above).\n\t\tthis.addDisposer(() => this._log.disposeAllViews());\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: route publish through `mutate`\n\t\t// for centralized freeze + re-throw semantics. No audit log surface\n\t\t// (per Tier 8 γ-0): the topic's `events` log already records every\n\t\t// successful publish, so a separate audit Node would be redundant.\n\t\t// `freeze: false` because topic payloads can be large and per-publish\n\t\t// cost matters on hot paths.\n\t\tthis._publishImpl = mutate<[T], void, never>(\n\t\t\t(value): void => {\n\t\t\t\tthis._log.append(value);\n\t\t\t},\n\t\t\t{ frame: \"inline\", freeze: false },\n\t\t);\n\t}\n\n\tpublish(value: T): void {\n\t\t// SENTINEL alignment (Wave B.1 Unit 11 lock): `undefined` is the\n\t\t// protocol-level \"never sent DATA\" sentinel — refusing it here\n\t\t// preserves `lastValue: Node<T | undefined>` semantics.\n\t\tif (value === undefined) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`TopicGraph \"${this.name}\": publish(undefined) is not allowed (spec §5.12 SENTINEL).`,\n\t\t\t);\n\t\t}\n\t\tthis._publishImpl(value);\n\t}\n\n\t/**\n\t * Wire one or more append-log storage tiers (Audit 4). Each tier receives\n\t * appended events per wave; rollback honors the wave-as-transaction model.\n\t *\n\t * Named `attachEventStorage` (not `attachStorage`) to avoid colliding with\n\t * the inherited {@link Graph.attachSnapshotStorage} which takes the\n\t * paired `AttachSnapshotTierPair[]` shape (Phase 14.6) — distinct\n\t * concerns, distinct surfaces.\n\t *\n\t * @returns Disposer.\n\t */\n\tattachEventStorage(\n\t\ttiers: readonly import(\"@graphrefly/pure-ts/extra\").AppendLogStorageTier<T>[],\n\t): () => void {\n\t\treturn this._log.attachStorage(tiers);\n\t}\n\n\tretained(): readonly T[] {\n\t\treturn this.events.cache as readonly T[];\n\t}\n\n\t/** Internal log bundle — used by TopicBridgeGraph for `attach`. */\n\tget _logBundle() {\n\t\treturn this._log;\n\t}\n}\n\nexport type SubscriptionOptions = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Starting cursor position.\n\t * @deprecated Use `from` instead.\n\t */\n\tcursor?: number;\n\t/**\n\t * Starting position for the subscription.\n\t * - `\"retained\"` (default) — cursor starts at 0; consumer sees all retained history.\n\t * - `\"now\"` — cursor starts at current topic length; consumer ignores history.\n\t * - `number` — explicit cursor position.\n\t */\n\tfrom?: \"now\" | \"retained\" | number;\n\t/**\n\t * When this signal node emits DATA, the subscription auto-advances cursor\n\t * to current `available.length`. Useful for \"ack everything when X happens\"\n\t * patterns. The reactive edge `advanceOn → cursor` is visible in `explain()`.\n\t */\n\tadvanceOn?: Node<unknown>;\n};\n\n/** Result of {@link SubscriptionGraph.pullAndAck}. */\nexport type PullAndAckResult<T> = {\n\titems: readonly T[];\n\tcursor: number;\n};\n\nexport class SubscriptionGraph<T> extends Graph {\n\treadonly cursor: Node<number>;\n\treadonly available: Node<readonly T[]>;\n\t/**\n\t * Reference to the upstream topic graph. Intentionally NOT mounted\n\t * under this subscription: a subscription is a VIEW over an\n\t * externally-owned topic. Double-mounting (e.g. hub-owned topic +\n\t * sub-mount here) would make either-side teardown leave the other\n\t * holding a dead reference. Node-level `derived([topicEvents], …)`\n\t * still wires the data dependency across graph boundaries. D1(e).\n\t */\n\treadonly topic: TopicGraph<T>;\n\n\tprivate _disposed = false;\n\tprivate readonly _ackImpl: (count: number | undefined) => number;\n\tprivate readonly _pullAndAckImpl: (limit: number | undefined) => PullAndAckResult<T>;\n\n\tconstructor(name: string, topicGraph: TopicGraph<T>, opts: SubscriptionOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis.topic = topicGraph;\n\n\t\t// Resolve initial cursor from `from` option, falling back to legacy `cursor` option.\n\t\tlet initialCursor: number;\n\t\tif (opts.from !== undefined) {\n\t\t\tif (opts.from === \"retained\") {\n\t\t\t\tinitialCursor = 0;\n\t\t\t} else if (opts.from === \"now\") {\n\t\t\t\t// §28 sanctioned factory-time boundary read.\n\t\t\t\tinitialCursor = (topicGraph.events.cache as readonly T[]).length;\n\t\t\t} else {\n\t\t\t\tinitialCursor = requireNonNegativeInt(opts.from, \"subscription from\");\n\t\t\t}\n\t\t} else {\n\t\t\tinitialCursor = requireNonNegativeInt(opts.cursor ?? 0, \"subscription cursor\");\n\t\t}\n\n\t\tthis.cursor = this.state<number>(\"cursor\", initialCursor, {\n\t\t\tmeta: messagingMeta(\"subscription_cursor\"),\n\t\t});\n\n\t\t// B.1 Unit 12 lock: `available` depends directly on topic.events + cursor\n\t\t// via `view({ kind: \"fromCursor\" })`. No `source` passthrough node —\n\t\t// describe shows `topic::events → available` (cross-graph edge) and\n\t\t// `cursor → available` (local edge). One fewer node per subscription.\n\t\tthis.available = topicGraph._logBundle.view({ kind: \"fromCursor\", cursor: this.cursor });\n\t\tthis.add(this.available, { name: \"available\" });\n\t\tthis.addDisposer(keepalive(this.available));\n\n\t\t// Optional reactive auto-advance: when `advanceOn` emits a NEW DATA\n\t\t// (after construction), cursor advances by `available.length` atomically.\n\t\t// Edge visible in describe: advancePump depends on advanceOn.\n\t\t// `_advanceInitialized` guards against the initial push-on-subscribe fire\n\t\t// that would advance cursor before the user has a chance to read.\n\t\tif (opts.advanceOn !== undefined) {\n\t\t\tconst advanceOn = opts.advanceOn;\n\t\t\tlet advanceInitialized = false;\n\t\t\tconst advancePump = node<unknown>(\n\t\t\t\t[advanceOn],\n\t\t\t\t() => {\n\t\t\t\t\t// Skip the initial push-on-subscribe wave.\n\t\t\t\t\tif (!advanceInitialized) {\n\t\t\t\t\t\tadvanceInitialized = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (this._disposed) return;\n\t\t\t\t\tconst avail = this.available.cache as readonly T[];\n\t\t\t\t\tif (avail.length === 0) return;\n\t\t\t\t\tconst next = (this.cursor.cache as number) + avail.length;\n\t\t\t\t\tthis.cursor.emit(next);\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"advancePump\",\n\t\t\t\t\tdescribeKind: \"effect\",\n\t\t\t\t\tmeta: messagingMeta(\"subscription_advance_pump\"),\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.add(advancePump, { name: \"advancePump\" });\n\t\t\tthis.addDisposer(keepalive(advancePump));\n\t\t}\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: route ack + pullAndAck through\n\t\t// `mutate` for centralized freeze + re-throw semantics. No audit\n\t\t// log surface (per Tier 8 γ-0): the cursor's own emission stream already\n\t\t// records every advance, so a separate audit Node would be redundant.\n\t\t// `freeze: false` because count/limit are simple numbers; freezing is\n\t\t// pointless overhead. Disposed-checks stay outside the wrapper so a\n\t\t// no-op call doesn't unnecessarily run the wrapper.\n\t\tthis._ackImpl = mutate<[number | undefined], number, never>(\n\t\t\t(count): number => {\n\t\t\t\tconst available = this.available.cache as readonly T[];\n\t\t\t\tconst requested =\n\t\t\t\t\tcount === undefined\n\t\t\t\t\t\t? available.length\n\t\t\t\t\t\t: requireNonNegativeInt(count, \"subscription ack count\");\n\t\t\t\tconst step = Math.min(requested, available.length);\n\t\t\t\tif (step <= 0) return this.cursor.cache as number;\n\t\t\t\tconst next = (this.cursor.cache as number) + step;\n\t\t\t\t// F8: use emit() so the pipeline auto-prefixes DIRTY, runs equals\n\t\t\t\t// substitution, and produces a proper two-phase wave (the raw\n\t\t\t\t// `down([[DATA, next]])` path bypassed those contracts).\n\t\t\t\tthis.cursor.emit(next);\n\t\t\t\treturn next;\n\t\t\t},\n\t\t\t{ frame: \"inline\", freeze: false },\n\t\t);\n\n\t\tthis._pullAndAckImpl = mutate<[number | undefined], PullAndAckResult<T>, never>(\n\t\t\t(limit): PullAndAckResult<T> => {\n\t\t\t\tconst available = this.available.cache as readonly T[];\n\t\t\t\tconst max =\n\t\t\t\t\tlimit === undefined\n\t\t\t\t\t\t? available.length\n\t\t\t\t\t\t: requireNonNegativeInt(limit, \"subscription pullAndAck limit\");\n\t\t\t\tconst items = available.slice(0, max);\n\t\t\t\tif (items.length === 0) return { items, cursor: this.cursor.cache as number };\n\t\t\t\tconst next = (this.cursor.cache as number) + items.length;\n\t\t\t\tthis.cursor.emit(next);\n\t\t\t\treturn { items, cursor: next };\n\t\t\t},\n\t\t\t{ frame: \"inline\", freeze: false },\n\t\t);\n\t}\n\n\tack(count?: number): number {\n\t\tif (this._disposed) return this.cursor.cache as number;\n\t\treturn this._ackImpl(count);\n\t}\n\n\tpull(limit?: number): readonly T[] {\n\t\tif (this._disposed) return [];\n\t\tconst available = this.available.cache as readonly T[];\n\t\tconst max =\n\t\t\tlimit === undefined\n\t\t\t\t? available.length\n\t\t\t\t: requireNonNegativeInt(limit, \"subscription pull limit\");\n\t\treturn available.slice(0, max);\n\t}\n\n\t/**\n\t * Atomic pull-and-acknowledge. Returns `{ items, cursor }` where `cursor`\n\t * is the new cursor position after advancing. Under single-threaded JS the\n\t * snapshot and advance are atomic; PY callers use a per-subscription Lock.\n\t *\n\t * Replaces `pull(limit, { ack: true })`.\n\t */\n\tpullAndAck(limit?: number): PullAndAckResult<T> {\n\t\tif (this._disposed) return { items: [], cursor: this.cursor.cache as number };\n\t\treturn this._pullAndAckImpl(limit);\n\t}\n\n\t/**\n\t * Release internal subscriptions and mark the subscription torn-down.\n\t * Subsequent `pull`, `pullAndAck`, `ack` return empty / current cursor.\n\t * Emits COMPLETE on `cursor` so derived consumers (e.g. `available`) see\n\t * the termination signal. Also drains `addDisposer` callbacks (including\n\t * the `keepalive(advancePump)` subscription) so no keepalive leak occurs.\n\t */\n\tdispose(): void {\n\t\tif (this._disposed) return;\n\t\tthis._disposed = true;\n\t\tthis.cursor.down([[COMPLETE]]);\n\t\t// m4: drain addDisposer callbacks to release the keepalive subscription.\n\t\tthis.destroy();\n\t}\n}\n\nexport type TopicBridgeOptions<TIn, TOut> = {\n\tgraph?: GraphOptions;\n\tcursor?: number;\n\tmaxPerPump?: number;\n\t/**\n\t * Optional transform/filter applied to each item before republishing.\n\t *\n\t * **At-most-once with silent drop:** when `map` returns `undefined`, the\n\t * input is consumed from the source cursor but NOT republished. Filtered\n\t * items are not retained for retry. If you need filter-with-retry\n\t * semantics, do the filtering in a downstream subscription on the bridged\n\t * output rather than in the `map` function.\n\t */\n\tmap?: (value: TIn) => TOut | undefined;\n};\n\nexport class TopicBridgeGraph<TIn, TOut = TIn> extends Graph {\n\tprivate readonly _sourceSub;\n\treadonly bridgedCount: Node<number>;\n\t/**\n\t * Emits each mapped batch as DATA — gives downstream observers a reactive\n\t * stream of bridged values. Also the link target for `target._log.attach`.\n\t */\n\treadonly output: Node<readonly TOut[]>;\n\n\tconstructor(\n\t\tname: string,\n\t\tsourceTopic: TopicGraph<TIn>,\n\t\ttargetTopic: TopicGraph<TOut>,\n\t\topts: TopicBridgeOptions<TIn, TOut> = {},\n\t) {\n\t\tsuper(name, opts.graph);\n\t\tthis._sourceSub = subscription<TIn>(`${name}-subscription`, sourceTopic, {\n\t\t\tcursor: opts.cursor,\n\t\t});\n\t\tthis.mount(\"subscription\", this._sourceSub);\n\n\t\tconst maxPerPump = Math.max(\n\t\t\t1,\n\t\t\trequireNonNegativeInt(opts.maxPerPump ?? DEFAULT_MAX_PER_PUMP, \"topic bridge maxPerPump\"),\n\t\t);\n\t\tconst mapValue = opts.map ?? ((value: TIn) => value as unknown as TOut);\n\n\t\t// Reactive output node: derives a mapped batch from `available`.\n\t\t// §24 compliant — output is a real derived edge, visible in describe.\n\t\t// Replaces imperative publish loop. Items where mapValue returns undefined\n\t\t// are filtered out (opt-out / filter).\n\t\tthis.output = node<readonly TOut[]>(\n\t\t\t[this._sourceSub.available],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst arr = data[0] as readonly TIn[];\n\t\t\t\tconst outBatch: TOut[] = [];\n\t\t\t\tconst take = Math.min(arr.length, maxPerPump);\n\t\t\t\tfor (let i = 0; i < take; i++) {\n\t\t\t\t\tconst mapped = mapValue(arr[i] as TIn);\n\t\t\t\t\tif (mapped !== undefined) outBatch.push(mapped);\n\t\t\t\t}\n\t\t\t\tactions.emit(outBatch);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"output\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: messagingMeta(\"topic_bridge_output\", { targetRef: targetTopic.name }),\n\t\t\t\tinitial: [],\n\t\t\t},\n\t\t);\n\t\tthis.add(this.output, { name: \"output\" });\n\t\tthis.addDisposer(keepalive(this.output));\n\n\t\t// bridgedCount: state node accumulating total bridged items.\n\t\t// Updated by ackPump after each batch — edge visible via ackPump dep on output.\n\t\tthis.bridgedCount = this.state<number>(\"bridgedCount\", 0, {\n\t\t\tmeta: messagingMeta(\"topic_bridge_count\"),\n\t\t});\n\t\tthis.addDisposer(keepalive(this.bridgedCount));\n\n\t\t// ackPump: effect that advances the subscription cursor and updates\n\t\t// bridgedCount after each batch. Runs after `output` settles.\n\t\t// Captures refs to `this.output`, `this._sourceSub`, `this.bridgedCount`\n\t\t// to avoid `this` inside the fn body.\n\t\tconst outputRef = this.output;\n\t\tconst subRef = this._sourceSub;\n\t\tconst countRef = this.bridgedCount;\n\t\tconst ackPump = this.effect(\n\t\t\t\"ackPump\",\n\t\t\t[\"output\"],\n\t\t\t() => {\n\t\t\t\tconst outBatch = outputRef.cache as readonly TOut[];\n\t\t\t\tif (outBatch.length === 0) return;\n\t\t\t\tconst availLen = (subRef.available.cache as readonly TIn[]).length;\n\t\t\t\tconst toAck = Math.min(availLen, maxPerPump);\n\t\t\t\tif (toAck > 0) {\n\t\t\t\t\tsubRef.ack(toAck);\n\t\t\t\t\tconst prev = (countRef.cache as number) ?? 0;\n\t\t\t\t\tcountRef.emit(prev + outBatch.length);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: messagingMeta(\"topic_bridge_ack_pump\"),\n\t\t\t},\n\t\t);\n\t\tthis.addDisposer(keepalive(ackPump));\n\n\t\t// Wire output into target topic's log reactively.\n\t\t// _attachArrayToLog subscribes to output and publishes each item to targetTopic.\n\t\t// Teardown: disposer runs before mount teardown.\n\t\tconst detach = _attachArrayToLog(this.output, targetTopic);\n\t\tthis.addDisposer(detach);\n\t}\n}\n\n/**\n * Attaches each element of an array-valued Node to a TopicGraph's log.\n * Every DATA emission on `source` appends all items in the array to `targetTopic`.\n * Returns a disposer.\n */\nfunction _attachArrayToLog<T>(source: Node<readonly T[]>, targetTopic: TopicGraph<T>): () => void {\n\treturn source.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] !== DATA) continue;\n\t\t\tconst arr = m[1] as readonly T[];\n\t\t\tif (arr.length === 0) continue;\n\t\t\tbatch(() => {\n\t\t\t\tfor (const v of arr) targetTopic.publish(v);\n\t\t\t});\n\t\t}\n\t});\n}\n\n// ── TopicRegistry ─────────────────────────────────────────────────────────\n\n/**\n * Private pure data structure managing a named set of {@link TopicGraph}\n * instances. Extracted from {@link MessagingHubGraph} for separation of\n * concerns (B.2 Unit 14 lock: D — split into TopicRegistry + facade).\n *\n * Reusable if other domain consumers (e.g. cqrs.eventLogs) want a shared\n * topic registry later.\n *\n * @internal\n */\nexport class TopicRegistry {\n\tprivate readonly _map = new Map<string, TopicGraph<unknown>>();\n\t/** Reactive monotonic version counter. Advances on topic create/remove. */\n\treadonly version: Node<number>;\n\n\tconstructor(versionNode: Node<number>) {\n\t\tthis.version = versionNode;\n\t}\n\n\tget size(): number {\n\t\treturn this._map.size;\n\t}\n\n\thas(name: string): boolean {\n\t\treturn this._map.has(name);\n\t}\n\n\tget<T>(name: string): TopicGraph<T> | undefined {\n\t\treturn this._map.get(name) as TopicGraph<T> | undefined;\n\t}\n\n\tset<T>(name: string, t: TopicGraph<T>): void {\n\t\tthis._map.set(name, t as TopicGraph<unknown>);\n\t}\n\n\tdelete(name: string): boolean {\n\t\treturn this._map.delete(name);\n\t}\n\n\tkeys(): IterableIterator<string> {\n\t\treturn this._map.keys();\n\t}\n}\n\n// ── MessagingHubGraph ─────────────────────────────────────────────────────\n\nexport type MessagingHubOptions = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Default `TopicOptions` applied to every topic created via `topic(name)`\n\t * without explicit options. Per-call opts override. Default: `{}`\n\t * (unbounded retention per topic unless `retainedLimit` is set per call).\n\t */\n\tdefaultTopicOptions?: TopicOptions;\n};\n\n/**\n * Lazy Pulsar-inspired topic registry. Manages a named set of {@link TopicGraph}\n * instances with retention + cursor semantics. Topics are created on first\n * access; `removeTopic(name)` unmounts and tears down via {@link Graph.remove}.\n *\n * Internally delegates to {@link TopicRegistry} for topic map management\n * (B.2 Unit 14 lock: D facade split).\n *\n * **Relationship to `pubsub()` in `src/extra/pubsub.ts`:** `pubsub` is a\n * lightweight last-value state hub (no retention, no cursors). `MessagingHubGraph`\n * is the full messaging hub — retained message logs, cursor-based subscriptions,\n * and pattern-layer lifecycle management.\n *\n * @category patterns\n */\nexport class MessagingHubGraph extends Graph {\n\tprivate readonly _registry: TopicRegistry;\n\t/** Reactive monotonic version counter — advances on topic create/remove. */\n\treadonly version: Node<number>;\n\tprivate readonly _defaultTopicOptions: TopicOptions;\n\tprivate readonly _removeTopicImpl: (name: string) => void;\n\n\tconstructor(name: string, opts: MessagingHubOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\t// B.2 Unit 14 lock: promote _version → version: Node<number>.\n\t\tconst versionNode = this.state<number>(\"version\", 0, {\n\t\t\tmeta: messagingMeta(\"hub_version\"),\n\t\t});\n\t\tthis.version = versionNode;\n\t\tthis._registry = new TopicRegistry(versionNode);\n\t\t// P8: shallow-copy caller-provided defaults so post-construction\n\t\t// mutations by the caller don't leak into every future `topic()` call.\n\t\tthis._defaultTopicOptions = { ...(opts.defaultTopicOptions ?? {}) };\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: route the registry-delete branch of\n\t\t// `removeTopic` through `mutate` for centralized re-throw\n\t\t// semantics. No audit log surface (per Tier 8 γ-0).\n\t\t// `freeze: false` because the only arg is a string name (freeze pointless).\n\t\t// **Closure-state caveat (γ-4):** the inner `try/finally` mutates\n\t\t// `_registry` (a `Map`) and emits the version bump. mutate has no\n\t\t// `batch()` frame, so reactive emissions are NOT rolled back on throw —\n\t\t// and even if it did, `Map.delete` on closure state is invisible to the\n\t\t// batch and can't be unwound. The pre-existing try/finally on\n\t\t// `Graph.remove` is what guarantees registry/version converge to a\n\t\t// consistent state when `remove()` throws; `mutate` adds nothing\n\t\t// to that contract beyond the re-throw.\n\t\tthis._removeTopicImpl = mutate<[string], void, never>(\n\t\t\t(topicName): void => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.remove(topicName); // unmounts, drops edges, tears down\n\t\t\t\t} finally {\n\t\t\t\t\tthis._registry.delete(topicName);\n\t\t\t\t\tconst cur = (this.version.cache as number) ?? 0;\n\t\t\t\t\tthis.version.emit(cur + 1);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ frame: \"inline\", freeze: false },\n\t\t);\n\t}\n\n\t/** Number of topics currently in the hub. */\n\tget size(): number {\n\t\treturn this._registry.size;\n\t}\n\n\t/** Checks topic existence without creating. */\n\thas(name: string): boolean {\n\t\treturn this._registry.has(name);\n\t}\n\n\t/** Iterator over topic names. */\n\ttopicNames(): IterableIterator<string> {\n\t\treturn this._registry.keys();\n\t}\n\n\t/**\n\t * Returns the {@link TopicGraph} for `name`, creating lazily on first call.\n\t * Subsequent calls with the same name return the same instance (options on\n\t * repeat calls are ignored — the topic is already configured).\n\t */\n\ttopic<T = unknown>(name: string, opts?: TopicOptions): TopicGraph<T> {\n\t\tlet t = this._registry.get<T>(name);\n\t\tif (t === undefined) {\n\t\t\tconst effective: TopicOptions = { ...this._defaultTopicOptions, ...(opts ?? {}) };\n\t\t\tt = new TopicGraph<T>(name, effective);\n\t\t\tthis._registry.set(name, t);\n\t\t\tthis.mount(name, t);\n\t\t\tconst cur = (this.version.cache as number) ?? 0;\n\t\t\tthis.version.emit(cur + 1);\n\t\t}\n\t\treturn t;\n\t}\n\n\t/**\n\t * Publishes a value to the topic, lazily creating it on first publish.\n\t *\n\t * **Late-subscriber caveat:** the topic is created lazily, so subscribers\n\t * that attach AFTER a publish only see the retained window (governed by\n\t * `retainedLimit` on `TopicOptions` / `defaultTopicOptions`). If\n\t * `retainedLimit === 0` is set explicitly, early publishes are\n\t * effectively dropped — prefer an unset `retainedLimit` (unbounded\n\t * retention) or subscribe before publishing when late-subscribers matter.\n\t */\n\tpublish<T = unknown>(name: string, value: T): void {\n\t\tthis.topic<T>(name).publish(value);\n\t}\n\n\t/**\n\t * Bulk publish — issues all publishes inside one outer batch. New topics\n\t * are created on demand. No-op if `entries` yields nothing.\n\t *\n\t * **Iterable consumption (F6):** `entries` is consumed once (single-pass)\n\t * INSIDE the batch frame. If the iterator throws mid-way, the batch is\n\t * discarded and NO publishes are visible to subscribers (all-or-nothing).\n\t * Pass an array or `Set` for multi-shot callers.\n\t */\n\tpublishMany(entries: Iterable<[string, unknown]>): void {\n\t\t// P2: iterate inside batch — no `[...entries]` materialization so large\n\t\t// / infinite iterables don't OOM, and iterator throws are contained.\n\t\tbatch(() => {\n\t\t\tfor (const [name, value] of entries) {\n\t\t\t\tthis.topic(name).publish(value);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Creates a {@link SubscriptionGraph} over a named topic. The topic is\n\t * lazily created if missing. Subscription lifecycle is owned by the caller —\n\t * the hub does NOT mount the subscription.\n\t *\n\t * @param subName - Local name for the subscription graph.\n\t * @param topicName - Hub topic to subscribe to.\n\t * @param opts - `SubscriptionOptions` (initial cursor, etc.).\n\t */\n\tsubscribe<T = unknown>(\n\t\tsubName: string,\n\t\ttopicName: string,\n\t\topts?: SubscriptionOptions,\n\t): SubscriptionGraph<T> {\n\t\tconst t = this.topic<T>(topicName);\n\t\treturn new SubscriptionGraph<T>(subName, t, opts);\n\t}\n\n\t/**\n\t * Unmounts and tears down the topic's graph. Returns `true` if the topic\n\t * existed. Subscribers receive `TEARDOWN` via {@link Graph.remove}.\n\t *\n\t * **Closure-state caveat:** the registry mutation (`_registry.delete`) and\n\t * version bump happen in a `try/finally`, so registry/version converge to\n\t * a consistent state even when {@link Graph.remove} throws. `mutate`\n\t * does not roll back this mutation on throw — `Map.delete` on closure\n\t * state is invisible to any batch frame. The pre-existing try/finally is\n\t * load-bearing for that invariant.\n\t */\n\tremoveTopic(name: string): boolean {\n\t\tif (!this._registry.has(name)) return false;\n\t\t// P1 / P3: Graph.remove first — if it throws, `_registry` must NOT still\n\t\t// hold the broken half-disposed topic (otherwise the next\n\t\t// `hub.topic(name)` returns the corrupted reference). The `try/finally`\n\t\t// inside `_removeTopicImpl`'s action body preserves that invariant.\n\t\tthis._removeTopicImpl(name);\n\t\treturn true;\n\t}\n}\n\n/**\n * Creates a Pulsar-inspired topic graph (append-only retained stream + latest value).\n */\nexport function topic<T>(name: string, opts?: TopicOptions): TopicGraph<T> {\n\treturn new TopicGraph<T>(name, opts);\n}\n\n/**\n * Creates a lazy Pulsar-inspired messaging hub. Topics are created on first access\n * via `hub.topic(name)`; `hub.publish(name, value)` shortcuts through the registry.\n *\n * @example\n * ```ts\n * import { messagingHub } from \"@graphrefly/graphrefly/patterns/messaging\";\n *\n * const hub = messagingHub(\"main\", { defaultTopicOptions: { retainedLimit: 256 } });\n * hub.publish(\"orders\", { id: 1 });\n * hub.publishMany([[\"shipments\", { id: 1 }], [\"orders\", { id: 2 }]]);\n * const sub = hub.subscribe(\"orders-worker\", \"orders\", { cursor: 0 });\n * ```\n */\nexport function messagingHub(name: string, opts?: MessagingHubOptions): MessagingHubGraph {\n\treturn new MessagingHubGraph(name, opts);\n}\n\n/**\n * Creates a cursor-based subscription graph over a topic.\n */\nexport function subscription<T>(\n\tname: string,\n\ttopicGraph: TopicGraph<T>,\n\topts?: SubscriptionOptions,\n): SubscriptionGraph<T> {\n\treturn new SubscriptionGraph<T>(name, topicGraph, opts);\n}\n\n/**\n * Creates an autonomous cursor-based topic relay graph.\n *\n * When `opts.map` is provided, items where `map` returns `undefined` are\n * consumed from the source cursor but NOT republished (at-most-once with\n * silent drop). For filter-with-retry semantics, apply the filter in a\n * downstream subscription on the bridge's `output` node instead.\n */\nexport function topicBridge<TIn, TOut = TIn>(\n\tname: string,\n\tsourceTopic: TopicGraph<TIn>,\n\ttargetTopic: TopicGraph<TOut>,\n\topts?: TopicBridgeOptions<TIn, TOut>,\n): TopicBridgeGraph<TIn, TOut> {\n\treturn new TopicBridgeGraph<TIn, TOut>(name, sourceTopic, targetTopic, opts);\n}\n\n// ── LogProjector ──────────────────────────────────────────────────────────\n//\n// Promotion 2 (memo:Re Story 6.4 back-derivation, design-review-locked\n// 2026-05-16). A cursor-driven projector over a log/topic where a per-item\n// sink can poison-fail. memo:Re hand-rolled `createProjectorCursor` and got\n// the failure mode wrong: a bare `catch { break; }` conflated a *transient*\n// condition (a native feature not yet available → retry later) with a\n// *poison* entry (will never project) → a permanent head-of-line block of\n// every newer entry. The fix is a real, observable, subscribable dead-letter\n// topic + a typed failure policy.\n//\n// Built ON `subscription()` (TopicGraph source) / the bundle's `fromCursor`\n// view (ReactiveLogBundle source) — the same hardened cursor machinery\n// `SubscriptionGraph` itself uses — so the consumer never hand-rolls cursor\n// persistence/durability (the Med \"durability skew\" + parse-leniency findings\n// dissolve). Scope is deliberately bounded: `halt | deadLetter` only, NO\n// programmatic retry/backoff (compose a downstream subscription on\n// `deadLetter` for that — avoids the §44 wrap-imperative-as-primitive trap).\n\nexport type ProjectorPoisonPolicy = \"halt\" | \"deadLetter\";\n\n/** A poison entry routed to {@link LogProjectorGraph.deadLetter}. */\nexport type DeadLetterEntry<T> = {\n\treadonly item: T;\n\t/** `Error.message` (or `String(thrown)`) from the failing `sink`. */\n\treadonly error: string;\n\t/** Absolute 0-based log position of the poisoned item. */\n\treadonly cursorPos: number;\n};\n\nexport type LogProjectorOptions<T> = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Per-item side-effecting projection.\n\t *\n\t * **Transient-vs-poison contract (read this).** The projector cannot tell\n\t * \"this will project later\" from \"this will never project\" — only the sink\n\t * knows. So the contract is:\n\t * - **Return normally** (sync return, or a resolved Promise) → the item is\n\t * *handled*; the cursor advances. Use this for the success path AND for\n\t * any transient/skip condition the sink wants to no-op (e.g. an optional\n\t * native feature not yet available — return without throwing; the entry\n\t * is simply considered done for this projector).\n\t * - **Throw / reject** → the item is *poison*; the {@link onPoison} policy\n\t * applies. Do NOT throw for transient conditions or the item is\n\t * dead-lettered (or halts the stream).\n\t */\n\treadonly sink: (item: T) => void | Promise<void>;\n\t/**\n\t * Behaviour when `sink` throws/rejects on an item (poison):\n\t * - `\"halt\"` (default) — stop projecting at the poison item; the cursor\n\t * does NOT advance past it (head-of-line stop). `position` stalls — that\n\t * is the observable signal. No retry/backoff is built in.\n\t * - `\"deadLetter\"` — publish `{ item, error, cursorPos }` to the\n\t * {@link LogProjectorGraph.deadLetter} topic and advance past it, so\n\t * newer entries still project.\n\t */\n\treadonly onPoison?: ProjectorPoisonPolicy;\n\t/**\n\t * Initial cursor position. `\"retained\"` (default) projects all history;\n\t * `\"now\"` skips existing entries (project only future appends); a number\n\t * starts at that absolute index.\n\t */\n\treadonly from?: \"retained\" | \"now\" | number;\n\t/** Retained window for the `deadLetter` topic. Default 1024. */\n\treadonly deadLetterRetainedLimit?: number;\n};\n\n/**\n * Cursor-driven projector over a {@link TopicGraph} or {@link ReactiveLogBundle}.\n *\n * Topology (mounted on the returned graph):\n * - `subscription` (TopicGraph source only) — the hardened\n * {@link SubscriptionGraph} cursor; or a local `cursor` state + the\n * bundle's `fromCursor` view (ReactiveLogBundle source).\n * - `drain` — an `effect` that, on every not-yet-projected wave, schedules a\n * serialized async pass that calls `sink` per item (mirrors the\n * `SubscriptionGraph.ackPump` / `TopicBridge.ackPump` effect precedent +\n * memo:Re's `inFlight` chain — one wave processed at a time).\n * - `deadLetter` — a real {@link TopicGraph} (NOT a callback): poison entries\n * are observable in `describe()` and subscribable, instead of memo:Re's\n * silent `break`.\n *\n * **No imperative reads.** Observe `position` (cursor) / subscribe to\n * `deadLetter`. `idle()` is a test-only await convenience.\n *\n * @category patterns\n */\nexport class LogProjectorGraph<T> extends Graph {\n\t/** Reactive count of fully-projected entries (the cursor; read-only). */\n\treadonly position: Node<number>;\n\t/**\n\t * Poison entries (populated when `onPoison: \"deadLetter\"`). A real topic —\n\t * subscribable + visible in `describe()`.\n\t */\n\treadonly deadLetter: TopicGraph<DeadLetterEntry<T>>;\n\tprivate _inFlight: Promise<void> = Promise.resolve();\n\n\tconstructor(\n\t\tname: string,\n\t\tsource: TopicGraph<T> | ReactiveLogBundle<T>,\n\t\topts: LogProjectorOptions<T>,\n\t) {\n\t\tsuper(name, opts.graph);\n\t\tconst onPoison: ProjectorPoisonPolicy = opts.onPoison ?? \"halt\";\n\t\tconst sink = opts.sink;\n\n\t\tconst dl = new TopicGraph<DeadLetterEntry<T>>(`${name}_dead_letter`, {\n\t\t\tretainedLimit: opts.deadLetterRetainedLimit ?? DEFAULT_TOPIC_RETAINED_LIMIT,\n\t\t});\n\t\tthis.mount(\"deadLetter\", dl);\n\t\tthis.deadLetter = dl;\n\n\t\t// Uniform cursor surface over either source kind. A TopicGraph reuses\n\t\t// the hardened SubscriptionGraph cursor; a ReactiveLogBundle uses a\n\t\t// local state cursor + the bundle's `fromCursor` view — the very\n\t\t// machinery SubscriptionGraph is itself built on.\n\t\tlet available: Node<readonly T[]>;\n\t\tlet cursorBase: () => number;\n\t\tlet advance: (n: number) => void;\n\n\t\tif (source instanceof TopicGraph) {\n\t\t\tconst sub = new SubscriptionGraph<T>(`${name}_subscription`, source, {\n\t\t\t\tfrom: opts.from ?? \"retained\",\n\t\t\t});\n\t\t\tthis.mount(\"subscription\", sub);\n\t\t\tavailable = sub.available;\n\t\t\tthis.position = sub.cursor;\n\t\t\tcursorBase = () => sub.cursor.cache as number;\n\t\t\tadvance = (n) => {\n\t\t\t\tif (n > 0) sub.ack(n);\n\t\t\t};\n\t\t} else {\n\t\t\tconst log = source;\n\t\t\tlet initialCursor: number;\n\t\t\tif (opts.from === \"now\") {\n\t\t\t\tinitialCursor = log.size;\n\t\t\t} else if (typeof opts.from === \"number\") {\n\t\t\t\tinitialCursor = requireNonNegativeInt(opts.from, \"logProjector from\");\n\t\t\t} else {\n\t\t\t\tinitialCursor = 0; // \"retained\"\n\t\t\t}\n\t\t\tconst cursor = this.state<number>(\"cursor\", initialCursor, {\n\t\t\t\tmeta: messagingMeta(\"log_projector_cursor\"),\n\t\t\t});\n\t\t\tthis.position = cursor;\n\t\t\tcursorBase = () => cursor.cache as number;\n\t\t\tavailable = log.view({ kind: \"fromCursor\", cursor });\n\t\t\tadvance = (n) => {\n\t\t\t\tif (n > 0) cursor.emit((cursor.cache as number) + n);\n\t\t\t};\n\t\t}\n\n\t\t// `halt` is a HARD LATCH (QA-C): on the first poison under `onPoison:\n\t\t// \"halt\"`, `sink` has been invoked exactly once on the poison item;\n\t\t// the projector then freezes — no further `sink` calls, no rescheduled\n\t\t// drains — so a later unrelated append cannot re-invoke the (possibly\n\t\t// side-effecting, non-idempotent) sink on the poison. The stalled\n\t\t// `position` + frozen stream IS the observable signal. v1 has no retry\n\t\t// (compose downstream of `deadLetter` if you need that).\n\t\tlet halted = false;\n\n\t\t// Serialized async drain. One wave processed at a time (the inFlight\n\t\t// chain) so an async `sink` cannot interleave; the cursor is advanced\n\t\t// ONCE per pass after the captured snapshot is processed (mirrors\n\t\t// memo:Re's `runPump` + the ackPump effect precedent).\n\t\tconst runDrain = async (): Promise<void> => {\n\t\t\tif (halted) return;\n\t\t\tconst snapshot = (available.cache as readonly T[] | undefined) ?? [];\n\t\t\tif (snapshot.length === 0) return;\n\t\t\tlet consumed = 0;\n\t\t\tfor (let i = 0; i < snapshot.length; i += 1) {\n\t\t\t\tconst item = snapshot[i] as T;\n\t\t\t\ttry {\n\t\t\t\t\tawait sink(item);\n\t\t\t\t\tconsumed += 1;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconst error = e instanceof Error ? e.message : String(e);\n\t\t\t\t\tif (onPoison === \"deadLetter\") {\n\t\t\t\t\t\tdl.publish({ item, error, cursorPos: cursorBase() + consumed });\n\t\t\t\t\t\tconsumed += 1; // advance past the poison\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// \"halt\" — latch and stop here; do NOT advance past the\n\t\t\t\t\t// poison, do NOT re-invoke `sink` on any later wave.\n\t\t\t\t\thalted = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (consumed > 0) advance(consumed);\n\t\t};\n\t\tconst schedule = (): void => {\n\t\t\tif (halted) return; // latched — no further drains\n\t\t\tthis._inFlight = this._inFlight.then(runDrain, runDrain);\n\t\t};\n\n\t\t// Effect: every wave that exposes not-yet-projected entries schedules a\n\t\t// drain. Side-effecting (sink / cursor advance / dead-letter publish) →\n\t\t// an `effect` node, not a pure derived (COMPOSITION-GUIDE §35; exact\n\t\t// `SubscriptionGraph.advancePump` precedent — never calls `emit` on its\n\t\t// own node, kept warm via `keepalive`).\n\t\tconst drain = node<unknown>(\n\t\t\t[available],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst b = batchData[0];\n\t\t\t\tconst snap = (b != null && b.length > 0 ? b.at(-1) : ctx.prevData[0]) as\n\t\t\t\t\t| readonly T[]\n\t\t\t\t\t| undefined;\n\t\t\t\tif (snap && snap.length > 0) schedule();\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"drain\",\n\t\t\t\tdescribeKind: \"effect\",\n\t\t\t\tmeta: messagingMeta(\"log_projector_drain\"),\n\t\t\t},\n\t\t);\n\t\tthis.add(drain, { name: \"drain\" });\n\t\tthis.addDisposer(keepalive(drain));\n\t}\n\n\t/**\n\t * Await any in-flight drain pass. **Test convenience only** — the canonical\n\t * reactive observable is {@link LogProjectorGraph.position}.\n\t */\n\tidle(): Promise<void> {\n\t\treturn this._inFlight;\n\t}\n}\n\n/**\n * Creates a cursor-driven log/topic projector with a typed poison-failure\n * policy and an observable dead-letter topic.\n *\n * @example\n * ```ts\n * import { logProjector, topic } from \"@graphrefly/graphrefly\";\n *\n * const events = topic<Doc>(\"docs\");\n * const proj = logProjector(\"indexer\", events, {\n * sink: async (doc) => { await index(doc); }, // throw ⇒ poison\n * onPoison: \"deadLetter\",\n * });\n * proj.deadLetter.events.subscribe(/* observe poison *​/);\n * ```\n *\n * @remarks\n * **Use an UNBOUNDED source for durable / long-lived projection.** The cursor\n * is an absolute index; the underlying `fromCursor` view slices the source's\n * *current* entries array. A `TopicGraph` with a `retainedLimit` (or a\n * `ReactiveLogBundle` with `maxSize`) trims its head, so an absolute cursor\n * past the retained window reads the wrong offset (skips entries or stalls).\n * This is inherited `subscription()` / `fromCursor` behaviour, not specific to\n * `logProjector` — but it matters here because projection is typically\n * long-lived. For unbounded projection pass a source with NO `retainedLimit` /\n * `maxSize` (memo:Re's `changesetLog` is unbounded ✓).\n *\n * @category patterns\n */\nexport function logProjector<T>(\n\tname: string,\n\tsource: TopicGraph<T> | ReactiveLogBundle<T>,\n\topts: LogProjectorOptions<T>,\n): LogProjectorGraph<T> {\n\treturn new LogProjectorGraph<T>(name, source, opts);\n}\n","/**\n * harnessLoop() factory (roadmap §9.0).\n *\n * Wires the static 7-stage topology: INTAKE → TRIAGE → QUEUE → GATE →\n * EXECUTE → VERIFY → REFLECT. Static topology, flowing data — the Kafka\n * insight applied to human+LLM collaboration.\n *\n * **Hub model (Wave B Unit 20 C + Q1).** All reactive-wire-crossing topics\n * live in one `MessagingHubGraph` exposed as `HarnessGraph.queues`: the\n * four per-route queues, an `__unrouted` dead-letter, plus `intake`,\n * `retry`, `verify-results`, and the `triage-output` fan-in topic. The\n * router is a single derived/effect pair that publishes to `triage-output`;\n * per-route `topicBridge`s fan out by `map:` predicate. Routing is data\n * (topic name), not code — every routing decision is a visible edge in\n * `describe()` / `explain()`.\n *\n * **EXECUTE/VERIFY via JobFlow (Tier 6.5 C2 lock, 2026-04-28).** The\n * stages 5–6 EXECUTE → VERIFY pair runs through an internal `executeFlow`\n * JobFlow with two stages (`execute`, `verify`). Each stage's pump owns\n * `claim → work → ack` for one claim; the verify stage's payload contains\n * `{ item, execution, verify }` so the post-completed dispatch effect can\n * route the 3-way verdict (verified / self-correctable retry / structural\n * + reingest) without any cross-wave `withLatestFrom` pairing. Items\n * arriving from per-route topics + retry feedback enter via a single\n * `enqueueEffect` that pushes to `executeFlow.queue(\"execute\")`.\n *\n * @module\n */\n\nimport { monotonicNs, type Node, node, placeholderArgs } from \"@graphrefly/pure-ts/core\";\nimport { merge, withLatestFrom } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport { tryIncrementBounded } from \"../../base/mutation/index.js\";\nimport { _oneShotLlmCall, stripFences } from \"../../utils/ai/_internal.js\";\nimport type { ChatMessage, LLMAdapter } from \"../../utils/ai/index.js\";\nimport { promptNode } from \"../../utils/ai/index.js\";\nimport { trackingKey } from \"../../utils/harness/_internal.js\";\nimport {\n\tDEFAULT_DECAY_RATE,\n\tDEFAULT_EXECUTE_PROMPT,\n\tDEFAULT_QUEUE_CONFIGS,\n\tDEFAULT_SEVERITY_WEIGHTS,\n\tDEFAULT_TRIAGE_PROMPT,\n\tDEFAULT_VERIFY_PROMPT,\n\tdefaultErrorClassifier,\n\tQUEUE_NAMES,\n\tresolvePromptFn,\n} from \"../../utils/harness/defaults.js\";\nimport {\n\ttype StrategyModelGraph,\n\ttype StrategySnapshot,\n\tstrategyModel,\n} from \"../../utils/harness/strategy.js\";\nimport type {\n\tErrorClassifier,\n\tExecuteOutput,\n\tExecutePromptFn,\n\tExecutionResult,\n\tHarnessExecutor,\n\tHarnessJobPayload,\n\tHarnessLoopOptions,\n\tHarnessVerifier,\n\tIntakeItem,\n\tQueueConfig,\n\tQueueRoute,\n\tTriagedItem,\n\tVerifyOutput,\n\tVerifyPromptFn,\n\tVerifyResult,\n} from \"../../utils/harness/types.js\";\nimport { DEFAULT_PRESET_ID, strategyKey } from \"../../utils/harness/types.js\";\nimport {\n\ttype JobEnvelope,\n\ttype JobFlowGraph,\n\ttype JobQueueGraph,\n\tjobFlow,\n\tjobQueue,\n} from \"../../utils/job-queue/index.js\";\nimport {\n\ttype MessagingHubGraph,\n\tmessagingHub,\n\ttype TopicGraph,\n\ttopicBridge,\n} from \"../../utils/messaging/index.js\";\nimport { type GateController, pipelineGraph } from \"../../utils/orchestration/index.js\";\n\n// ---------------------------------------------------------------------------\n// Hub topic names (internal constants — strings are the routing API)\n// ---------------------------------------------------------------------------\n\nconst TOPIC_INTAKE = \"intake\";\nconst TOPIC_TRIAGE_OUTPUT = \"triage-output\";\nconst TOPIC_RETRY = \"retry\";\nconst TOPIC_VERIFY_RESULTS = \"verify-results\";\nconst TOPIC_UNROUTED = \"__unrouted\";\n\n// ---------------------------------------------------------------------------\n// Default LLM executor / verifier work fns (Tier 6.5 C2)\n// ---------------------------------------------------------------------------\n\n/**\n * Build the default EXECUTE work fn — calls `adapter.invoke()` once per\n * claimed job, parses the JSON response into an `ExecuteOutput<A>`, and\n * returns a {@link HarnessJobPayload} with `execution` filled in.\n *\n * Errors (parse failure, adapter throw, malformed JSON) are caught and\n * surfaced as a `failure`-outcome payload — the dispatch effect routes\n * the item rather than dropping it via pump nack (see C2 contract on\n * {@link HarnessExecutor}).\n *\n * Subsumes the pre-Tier-6.5 `promptNode`-based default: per-claim LLM\n * calls don't benefit from `promptNode`'s cross-wave switchMap, and a\n * fresh per-claim subgraph would be wasteful. Direct `adapter.invoke`\n * is the right shape inside JobFlow pumps.\n *\n * @param adapter - LLMAdapter for the execute call.\n * @param prompt - Prompt template (string or `(item) => string`). Defaults\n * to the harness's built-in execute prompt.\n */\nexport function defaultLlmExecutor<A = unknown>(\n\tadapter: LLMAdapter,\n\tprompt?: string | ExecutePromptFn,\n): HarnessExecutor<A> {\n\tconst promptFn = resolvePromptFn<TriagedItem>(prompt, DEFAULT_EXECUTE_PROMPT, (tpl, item) =>\n\t\ttpl.replace(\"{{item}}\", JSON.stringify(item)),\n\t);\n\treturn (job, opts) => {\n\t\tconst item = job.payload.item;\n\t\tconst messages: readonly ChatMessage[] = [{ role: \"user\", content: promptFn(item) }];\n\t\t// Bridge-layer flakes get `outcome: \"failure\"` with no `errorClass`.\n\t\t// The dispatch effect's `errorClassifier` runs over `detail` and the\n\t\t// default classifier matches `parse|json|config|validation|syntax`,\n\t\t// so parse-error flakes route to retry. Adapter HTTP/network failures\n\t\t// without a keyword fall through to structural per the existing\n\t\t// asymmetry (executor side relies on classifier; verifier side sets\n\t\t// errorClass directly per qa F3).\n\t\tconst failurePayload = (detail: string): HarnessJobPayload<A> => ({\n\t\t\t...job.payload,\n\t\t\texecution: { item, outcome: \"failure\", detail },\n\t\t});\n\t\tconst formatErr = (err: unknown): string => (err instanceof Error ? err.message : String(err));\n\t\t// One-shot bridge via `_oneShotLlmCall` (patterns/ai/_internal.ts).\n\t\t// Helper owns subscription / abort / first-DATA capture / COMPLETE\n\t\t// arm; this site owns parse + validate + payload mapping. Pump-\n\t\t// supplied `opts.signal` (Tier 6.5 2.5b) cascades into adapter +\n\t\t// fromAny via `parentSignal`.\n\t\treturn _oneShotLlmCall<HarnessJobPayload<A>>(adapter, messages, {\n\t\t\tparentSignal: opts?.signal,\n\t\t\tonSuccess: (resp) => {\n\t\t\t\tlet parsed: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tparsed = JSON.parse(stripFences(String(resp.content)));\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn failurePayload(`execute parse error: ${formatErr(err)}`);\n\t\t\t\t}\n\t\t\t\t// Validate plain object before field access — non-object JSON\n\t\t\t\t// (`null` / number / array / string) silently masks malformed\n\t\t\t\t// responses unless caught here. Surfaced via parse-error keyword\n\t\t\t\t// for classifier routing.\n\t\t\t\tif (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\t\t\treturn failurePayload(\n\t\t\t\t\t\t`execute parse error: non-object response: ${JSON.stringify(parsed)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst obj = parsed as Partial<ExecuteOutput<A>>;\n\t\t\t\treturn {\n\t\t\t\t\t...job.payload,\n\t\t\t\t\texecution: {\n\t\t\t\t\t\titem,\n\t\t\t\t\t\toutcome: obj.outcome ?? \"failure\",\n\t\t\t\t\t\tdetail: obj.detail ?? \"unknown\",\n\t\t\t\t\t\tartifact: obj.artifact,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\tonFailure: (kind, err) => {\n\t\t\t\tif (kind === \"complete\") {\n\t\t\t\t\treturn failurePayload(\"adapter completed without emitting DATA\");\n\t\t\t\t}\n\t\t\t\treturn failurePayload(`executor failed: ${formatErr(err)}`);\n\t\t\t},\n\t\t});\n\t};\n}\n\n/**\n * Build the default VERIFY work fn — calls `adapter.invoke()` once per\n * claimed job to review the prior-stage execution, parses the JSON\n * response into a `VerifyOutput`, and returns a {@link HarnessJobPayload}\n * with `verify` filled in.\n *\n * Same C2 error semantics as {@link defaultLlmExecutor}: parse / adapter\n * failures are surfaced as a structural-failure verify payload so the\n * dispatch effect routes the item.\n */\nexport function defaultLlmVerifier<A = unknown>(\n\tadapter: LLMAdapter,\n\tprompt?: string | VerifyPromptFn<A>,\n): HarnessVerifier<A> {\n\tconst promptFn = resolvePromptFn<readonly [ExecuteOutput<A> | null, TriagedItem | null]>(\n\t\tprompt,\n\t\tDEFAULT_VERIFY_PROMPT,\n\t\t(tpl, pair) => {\n\t\t\tconst [execution, item] = pair;\n\t\t\treturn tpl\n\t\t\t\t.replace(\"{{execution}}\", JSON.stringify(execution))\n\t\t\t\t.replace(\"{{item}}\", JSON.stringify(item));\n\t\t},\n\t);\n\treturn (job, opts) => {\n\t\tconst { item, execution } = job.payload;\n\t\tif (execution == null) {\n\t\t\t// Defensive — verify stage runs after execute; if execution is\n\t\t\t// missing, surface as STRUCTURAL failure rather than throw. This is\n\t\t\t// the only structural-classified path here: it indicates a topology\n\t\t\t// bug (verify ran without execute), not an LLM-bridge flake. Bridge\n\t\t\t// flakes (parse / adapter throw / ERROR / COMPLETE-without-DATA) get\n\t\t\t// `errorClass: \"self-correctable\"` below so the dispatch effect's\n\t\t\t// retry budget absorbs them before reingest fires (qa F3).\n\t\t\treturn {\n\t\t\t\t...job.payload,\n\t\t\t\tverify: {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tfindings: [\"verifier: prior execute stage produced no execution\"],\n\t\t\t\t\terrorClass: \"structural\",\n\t\t\t\t},\n\t\t\t} satisfies HarnessJobPayload<A>;\n\t\t}\n\t\tconst messages: readonly ChatMessage[] = [\n\t\t\t{ role: \"user\", content: promptFn([execution, item]) },\n\t\t];\n\t\t// Bridge-layer flakes: classify as self-correctable so the dispatch\n\t\t// effect routes via the retry budget first. Persistent flakes still\n\t\t// fall through to structural after `maxRetries` exhaustion (qa F3).\n\t\tconst failurePayload = (finding: string): HarnessJobPayload<A> => ({\n\t\t\t...job.payload,\n\t\t\tverify: {\n\t\t\t\tverified: false,\n\t\t\t\tfindings: [finding],\n\t\t\t\terrorClass: \"self-correctable\",\n\t\t\t},\n\t\t});\n\t\tconst formatErr = (err: unknown): string => (err instanceof Error ? err.message : String(err));\n\t\t// One-shot bridge — see `_oneShotLlmCall` JSDoc. Helper owns the\n\t\t// subscribe + capture + abort + COMPLETE arm; this site owns parse +\n\t\t// validate + verify-payload mapping. Pump-supplied `opts.signal`\n\t\t// (Tier 6.5 2.5b) cascades into adapter + fromAny via `parentSignal`.\n\t\treturn _oneShotLlmCall<HarnessJobPayload<A>>(adapter, messages, {\n\t\t\tparentSignal: opts?.signal,\n\t\t\tonSuccess: (resp) => {\n\t\t\t\tlet parsed: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tparsed = JSON.parse(stripFences(String(resp.content)));\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn failurePayload(`verify parse error: ${formatErr(err)}`);\n\t\t\t\t}\n\t\t\t\tif (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\t\t\treturn failurePayload(\n\t\t\t\t\t\t`verify parse error: non-object response: ${JSON.stringify(parsed)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst obj = parsed as Partial<VerifyOutput>;\n\t\t\t\treturn {\n\t\t\t\t\t...job.payload,\n\t\t\t\t\tverify: {\n\t\t\t\t\t\tverified: obj.verified === true,\n\t\t\t\t\t\tfindings: obj.findings ?? [],\n\t\t\t\t\t\terrorClass: obj.errorClass,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\tonFailure: (kind, err) => {\n\t\t\t\tif (kind === \"complete\") {\n\t\t\t\t\treturn failurePayload(\"verifier completed without emitting DATA\");\n\t\t\t\t}\n\t\t\t\treturn failurePayload(`verifier failed: ${formatErr(err)}`);\n\t\t\t},\n\t\t});\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// HarnessGraph\n// ---------------------------------------------------------------------------\n\n/**\n * The graph returned by {@link harnessLoop}. Wraps a single\n * {@link MessagingHubGraph} that owns all reactive-wire-crossing topics\n * (intake, per-route queues, `__unrouted`, retry, verify-results,\n * triage-output), plus an `executeFlow` JobFlow that owns the\n * EXECUTE → VERIFY pipeline (Tier 6.5 C2). Sugar getters expose the\n * canonical topics so the surface stays ergonomic.\n */\nexport class HarnessGraph<A = unknown> extends Graph {\n\t/** Messaging hub — the routing-data plane. Queue topics live here. */\n\treadonly queues: MessagingHubGraph;\n\n\t/**\n\t * EXECUTE → VERIFY JobFlow (Tier 6.5 C2). Pumps own claim/ack/nack\n\t * lifecycle for each stage. Inspect via:\n\t * - `harness.executeFlow.queue(\"execute\").pending` — pending depth.\n\t * - `harness.executeFlow.queue(\"verify\").pending` — items mid-execute.\n\t * - `harness.executeFlow.completed` — verified items waiting for the\n\t * dispatch effect's 3-way routing.\n\t * - `harness.executeFlow.completedCount` — total terminal completions.\n\t */\n\treadonly executeFlow: JobFlowGraph<HarnessJobPayload<A>>;\n\n\t/**\n\t * Per-route JobQueueGraph audit mirrors. Each triaged item that reaches\n\t * a queue is also enqueued here, giving reactive `depth` + `pending` +\n\t * `jobs` observables per route. The dispatch effect ack/removeBy-id's\n\t * the matching job on terminal verdict. The executeFlow JobFlow handles\n\t * the EXECUTE → VERIFY data flow; this is a parallel audit-side ledger\n\t * for per-route depth metrics. Inspect via\n\t * `harness.jobs.get(route).depth.cache` for backpressure metrics.\n\t */\n\treadonly jobs: ReadonlyMap<QueueRoute, JobQueueGraph<TriagedItem>>;\n\n\t/** Per-route gate controllers (only for gated queues). */\n\treadonly gates: ReadonlyMap<QueueRoute, GateController<TriagedItem>>;\n\n\t/**\n\t * Per-route queue topics — typed accessor for the four\n\t * {@link QUEUE_NAMES} entries (`auto-fix`, `needs-decision`,\n\t * `investigation`, `backlog`). Mirrors the `gates` / `jobs` map\n\t * shape so callers can iterate `[route, topic]` pairs without\n\t * hand-rolling `harness.queues.topicNames()` + meta-topic exclusion.\n\t *\n\t * Excludes the meta topics that share the hub:\n\t * `intake` (use {@link intake}), `verify-results` (use\n\t * {@link verifyResults}), `retry` (use {@link retry}), `__unrouted`\n\t * (use {@link unrouted}), and the internal `triage-output` fan-in.\n\t */\n\treadonly queueTopics: ReadonlyMap<QueueRoute, TopicGraph<TriagedItem>>;\n\n\t/** Strategy model — `auditedSuccessTracker` keyed by `StrategyKey`. */\n\treadonly strategy: StrategyModelGraph;\n\n\t/** Global retry count across all items (circuit breaker). Reactive — subscribable. */\n\treadonly totalRetries: Node<number>;\n\n\t/** Global reingestion count across all items (circuit breaker). Reactive — subscribable. */\n\treadonly totalReingestions: Node<number>;\n\n\t/**\n\t * Per-route priority score nodes, populated only when `opts.priority` is\n\t * set on {@link harnessLoop}. Each node emits a score combining severity,\n\t * attention decay, and strategy-model effectiveness for the route's\n\t * current head-of-queue item. `undefined` means the caller did not opt\n\t * in to priority scoring.\n\t */\n\treadonly priorityScores?: ReadonlyMap<QueueRoute, Node<number>>;\n\n\t/**\n\t * REFLECT-stage tick marker — emits one DATA per terminal verdict observed\n\t * on `executeFlow.completed`. `equals: () => false` so each completion\n\t * produces an observable tick (no Object.is collapse on identical\n\t * `null` payloads). Inspection tools (`harnessTrace`, dashboards) can\n\t * subscribe directly here instead of resolving by string path\n\t * (`harness.node(\"reflect\")`) — the field is the lock against rename\n\t * drift.\n\t */\n\treadonly reflect: Node<null>;\n\n\tconstructor(\n\t\tname: string,\n\t\tqueues: MessagingHubGraph,\n\t\texecuteFlow: JobFlowGraph<HarnessJobPayload<A>>,\n\t\tqueueTopics: Map<QueueRoute, TopicGraph<TriagedItem>>,\n\t\tjobs: Map<QueueRoute, JobQueueGraph<TriagedItem>>,\n\t\tgates: Map<QueueRoute, GateController<TriagedItem>>,\n\t\tstrategy: StrategyModelGraph,\n\t\ttotalRetries: Node<number>,\n\t\ttotalReingestions: Node<number>,\n\t\treflect: Node<null>,\n\t\tpriorityScores?: Map<QueueRoute, Node<number>>,\n\t) {\n\t\tsuper(name);\n\t\tthis.queues = queues;\n\t\tthis.executeFlow = executeFlow;\n\t\tthis.queueTopics = queueTopics;\n\t\tthis.jobs = jobs;\n\t\tthis.gates = gates;\n\t\tthis.strategy = strategy;\n\t\tthis.totalRetries = totalRetries;\n\t\tthis.totalReingestions = totalReingestions;\n\t\tthis.reflect = reflect;\n\t\tthis.priorityScores = priorityScores;\n\t}\n\n\t/** Intake topic — publish items here to enter the loop. */\n\tget intake(): TopicGraph<IntakeItem> {\n\t\treturn this.queues.topic<IntakeItem>(TOPIC_INTAKE);\n\t}\n\n\t/** Verify results topic — subscribe to see verification outcomes. */\n\tget verifyResults(): TopicGraph<VerifyResult<A>> {\n\t\treturn this.queues.topic<VerifyResult<A>>(TOPIC_VERIFY_RESULTS);\n\t}\n\n\t/** Retry feedback topic — fast-retry re-entry point. */\n\tget retry(): TopicGraph<TriagedItem> {\n\t\treturn this.queues.topic<TriagedItem>(TOPIC_RETRY);\n\t}\n\n\t/** Dead-letter topic for items whose LLM-chosen route is unknown. */\n\tget unrouted(): TopicGraph<TriagedItem> {\n\t\treturn this.queues.topic<TriagedItem>(TOPIC_UNROUTED);\n\t}\n\n\t/**\n\t * Stage-label → observe-path map for the 7 pipeline stages.\n\t *\n\t * Decouples inspection tools (`harnessTrace`, `harnessProfile`, custom\n\t * dashboards) from mount-structure churn: hub migration, future stage\n\t * splits, gate remounting, or the Tier 6.5 C2 JobFlow rewire shouldn't\n\t * require edits to `trace.ts` as long as this method stays accurate.\n\t *\n\t * Each stage yields `{ label, paths }`; consumers iterate paths per\n\t * stage and attach observers. Tier 6.5: EXECUTE / VERIFY paths now\n\t * resolve to the `executeFlow` stage queues + the `verify-dispatch`\n\t * effect node.\n\t */\n\tstageNodes(): ReadonlyArray<{ label: string; paths: readonly string[] }> {\n\t\tconst hub = this.queues;\n\t\tconst resolveHubPath = (name: string): string | null =>\n\t\t\thub.has(name) ? `queues::${name}::latest` : null;\n\t\tconst includeIf = <T>(value: T | null | undefined): readonly T[] =>\n\t\t\tvalue == null ? [] : [value];\n\n\t\tconst queuePaths = QUEUE_NAMES.flatMap((r) => includeIf(resolveHubPath(r)));\n\t\tconst gatePaths: string[] = [];\n\t\tfor (const [route] of this.gates) {\n\t\t\tgatePaths.push(`gates::${route}/gate`);\n\t\t}\n\t\treturn [\n\t\t\t{ label: \"INTAKE\", paths: includeIf(resolveHubPath(\"intake\")) },\n\t\t\t{ label: \"TRIAGE\", paths: [\"triage\"] },\n\t\t\t{ label: \"QUEUE\", paths: queuePaths },\n\t\t\t{ label: \"GATE\", paths: gatePaths },\n\t\t\t{ label: \"EXECUTE\", paths: [\"executeFlow::execute::events\"] },\n\t\t\t{ label: \"VERIFY\", paths: [\"executeFlow::verify::events\"] },\n\t\t\t{ label: \"REFLECT\", paths: [\"reflect\"] },\n\t\t\t{ label: \"STRATEGY\", paths: [\"strategy::entries\"] },\n\t\t];\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// harnessLoop factory\n// ---------------------------------------------------------------------------\n\n/**\n * Wire the reactive collaboration loop as a static-topology graph.\n *\n * The loop has 7 stages:\n * 1. **INTAKE** — items arrive from multiple sources via `intake.publish()`\n * 2. **TRIAGE** — promptNode classifies, routes, and prioritizes\n * 3. **QUEUE** — 4 priority-ordered TopicGraphs (auto-fix, needs-decision, investigation, backlog)\n * 4. **GATE** — human approval on configurable queues\n * 5. **EXECUTE** — JobFlow `execute` stage; user-supplied or default work fn\n * 6. **VERIFY** — JobFlow `verify` stage; verifies the executed artifact\n * 7. **REFLECT** — strategy model records outcomes; dispatch effect routes 3-way\n *\n * @param name - Graph name.\n * @param opts - Configuration.\n * @returns HarnessGraph with controller accessors.\n */\nexport function harnessLoop<A = unknown>(\n\tname: string,\n\topts: HarnessLoopOptions<A>,\n): HarnessGraph<A> {\n\tconst adapter = opts.adapter;\n\tconst maxRetries = opts.maxRetries ?? 2;\n\tconst retainedLimit = opts.retainedLimit ?? 1000;\n\tconst errorClassifier: ErrorClassifier = opts.errorClassifier ?? defaultErrorClassifier;\n\n\tconst queueConfigs = new Map<QueueRoute, QueueConfig>();\n\tfor (const route of QUEUE_NAMES) {\n\t\tqueueConfigs.set(route, {\n\t\t\t...DEFAULT_QUEUE_CONFIGS[route],\n\t\t\t...opts.queues?.[route],\n\t\t});\n\t}\n\n\t// --- Messaging hub (Wave B Q1 Option A) ---\n\tconst queuesHub = messagingHub(`${name}/queues`, {\n\t\tdefaultTopicOptions: { retainedLimit },\n\t});\n\n\t// Eagerly create canonical topics so they appear in `describe()` from\n\t// construction time and `harness.queues.has(route)` answers `true`\n\t// before any publish.\n\tconst intake = queuesHub.topic<IntakeItem>(TOPIC_INTAKE);\n\tconst triageOutput = queuesHub.topic<TriagedItem>(TOPIC_TRIAGE_OUTPUT);\n\tconst retryTopic = queuesHub.topic<TriagedItem>(TOPIC_RETRY);\n\tconst verifyResults = queuesHub.topic<VerifyResult<A>>(TOPIC_VERIFY_RESULTS);\n\tconst queueTopics = new Map<QueueRoute, TopicGraph<TriagedItem>>();\n\tfor (const route of QUEUE_NAMES) {\n\t\tqueueTopics.set(route, queuesHub.topic<TriagedItem>(route));\n\t}\n\tconst unroutedTopic = queuesHub.topic<TriagedItem>(TOPIC_UNROUTED);\n\n\t// --- Strategy model (used by triage + dispatch) ---\n\tconst strategy = strategyModel();\n\n\t// --- Stage 2: TRIAGE ---\n\t// triageInput pairs intake.latest (trigger) with strategy.entries\n\t// (advisory, sampled via withLatestFrom). Breaks the feedback cycle\n\t// (verify → strategy.record → strategy.entries would otherwise re-fire\n\t// triage on every recorded outcome).\n\tconst triageInput = withLatestFrom(\n\t\tintake.latest as Node<unknown>,\n\t\tstrategy.entries as Node<unknown>,\n\t);\n\n\tconst triagePromptFn = resolvePromptFn<readonly [IntakeItem, StrategySnapshot]>(\n\t\topts.triagePrompt,\n\t\tDEFAULT_TRIAGE_PROMPT,\n\t\t(tpl, pair) => {\n\t\t\tconst [item, strat] = pair;\n\t\t\treturn tpl\n\t\t\t\t.replace(\"{{strategy}}\", JSON.stringify(Array.from(strat.entries())))\n\t\t\t\t.replace(\"{{item}}\", JSON.stringify(item));\n\t\t},\n\t);\n\n\tconst triageNode = promptNode<TriagedItem>(\n\t\tadapter as LLMAdapter,\n\t\t[triageInput as Node<unknown>],\n\t\t(pair: unknown) => {\n\t\t\t// `intake.latest` is now SENTINEL on empty (COMPOSITION-GUIDE §1a),\n\t\t\t// so the `withLatestFrom partial:false` gate holds the fn until both\n\t\t\t// deps deliver real DATA. The `=== undefined` guard catches the\n\t\t\t// edge where the pair itself is unset (defensive — shouldn't fire\n\t\t\t// in normal flow).\n\t\t\tconst asPair = pair as readonly [IntakeItem, StrategySnapshot] | undefined;\n\t\t\tif (asPair === undefined) return \"\";\n\t\t\treturn triagePromptFn(asPair);\n\t\t},\n\t\t{\n\t\t\tname: \"triage\",\n\t\t\tformat: \"json\",\n\t\t},\n\t);\n\n\t// --- Stage 3: QUEUE (hub routing) ---\n\t//\n\t// Router is a thin effect that publishes the merged TriagedItem to\n\t// `triage-output`. `topicBridge`s fan it out to per-route queues by\n\t// filtering on `item.route`. Unknown routes flow into `__unrouted` so\n\t// misclassified items become a subscribable dead-letter signal.\n\tconst routerInput = withLatestFrom(triageNode as Node<unknown>, triageInput as Node<unknown>);\n\tconst router = node(\n\t\t[routerInput as Node<unknown>],\n\t\t(batchData, _actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst pair = data[0];\n\t\t\tif (pair == null) return;\n\t\t\tconst [classification, triagePair] = pair as [\n\t\t\t\tTriagedItem | null,\n\t\t\t\t[IntakeItem | null, StrategySnapshot] | null,\n\t\t\t];\n\t\t\tif (!classification?.route) return;\n\t\t\tconst intakeItem = triagePair?.[0];\n\t\t\t// Intake fields win over classification: the LLM only owns the five\n\t\t\t// triage-classification fields (rootCause, intervention, route,\n\t\t\t// priority, triageReasoning); any intake state it accidentally\n\t\t\t// returns is overwritten by the real intake value via the trailing\n\t\t\t// spread.\n\t\t\tconst merged: TriagedItem = { ...classification, ...intakeItem } as TriagedItem;\n\t\t\ttriageOutput.publish(merged);\n\t\t},\n\t\t{ describeKind: \"effect\" },\n\t);\n\tconst routerUnsub = router.subscribe(() => {});\n\n\t// TopicBridges fan triage-output into per-route queues (visible edges).\n\tconst knownRoutes = new Set<string>(QUEUE_NAMES);\n\tfor (const route of QUEUE_NAMES) {\n\t\ttopicBridge<TriagedItem>(`bridge/${route}`, triageOutput, queueTopics.get(route)!, {\n\t\t\tmap: (item) => (item.route === route ? item : undefined),\n\t\t});\n\t}\n\ttopicBridge<TriagedItem>(\"bridge/__unrouted\", triageOutput, unroutedTopic, {\n\t\tmap: (item) => (knownRoutes.has(item.route) ? undefined : item),\n\t});\n\n\t// --- Per-route audit JobQueueGraphs (parallel ledger) ---\n\t//\n\t// One jobQueue per route mirrors the route topic's publishes so\n\t// dashboards get a subscribable `depth` / `pending` / `jobs` view of\n\t// in-progress items. Identity is established at enqueue time (the\n\t// returned `id` is paired with `trackingKey(item)`); the dispatch\n\t// effect calls `JobQueueGraph.removeById(id)` on terminal verdict.\n\t//\n\t// This audit ledger runs in parallel with the `executeFlow` JobFlow\n\t// (Tier 6.5 C2). The two are complementary:\n\t// - This ledger gives **per-route** depth/pending observables\n\t// (\"how backed up is auto-fix?\").\n\t// - executeFlow gives **per-stage** depth/pending observables\n\t// (\"how many items are mid-execute?\").\n\t//\n\t// **Retry handling.** Retry items republished to `retryTopic` flow\n\t// into executeFlow (via the enqueue effect) but NOT into per-route\n\t// audit jq's (retryTopic isn't mirrored). The audit job stays alive\n\t// across retries — only terminal (verified / structural) decisions\n\t// remove it. `depth` reflects \"items still being worked on\".\n\t//\n\t// **Ring-buffer safety.** WeakSet keyed on item identity; once the\n\t// topic's ring buffer trims the head, dropped entries become\n\t// unreachable and the WeakSet auto-prunes.\n\tconst jobQueues = new Map<QueueRoute, JobQueueGraph<TriagedItem>>();\n\tconst routeJobIds = new Map<string, { route: QueueRoute; id: string }>();\n\tfor (const route of QUEUE_NAMES) {\n\t\tjobQueues.set(route, jobQueue<TriagedItem>(`jobs/${route}`));\n\t}\n\tconst jobMirrorUnsubs: Array<() => void> = [];\n\tfor (const route of QUEUE_NAMES) {\n\t\tconst topic = queueTopics.get(route)!;\n\t\tconst jq = jobQueues.get(route)!;\n\t\tconst seen = new WeakSet<object>();\n\t\tconst mirror = node(\n\t\t\t[topic.events as Node<unknown>],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst events = data[0];\n\t\t\t\tconst arr = (events ?? []) as readonly TriagedItem[];\n\t\t\t\tfor (const item of arr) {\n\t\t\t\t\tif (seen.has(item as unknown as object)) continue;\n\t\t\t\t\tseen.add(item as unknown as object);\n\t\t\t\t\tconst id = jq.enqueue(item);\n\t\t\t\t\trouteJobIds.set(trackingKey(item), { route, id });\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ name: `jobs/${route}-mirror`, describeKind: \"effect\" },\n\t\t);\n\t\tjobMirrorUnsubs.push(mirror.subscribe(() => {}));\n\t}\n\n\tfunction ackJob(item: TriagedItem): void {\n\t\tconst key = trackingKey(item);\n\t\tconst entry = routeJobIds.get(key);\n\t\tif (!entry) return;\n\t\tjobQueues.get(entry.route)?.removeById(entry.id);\n\t\trouteJobIds.delete(key);\n\t}\n\n\t// --- Stage 4: GATE ---\n\t//\n\t// Per-route gates between `topic.latest` and the executeFlow enqueue.\n\t// Foreign-node-accept (Session B.1): pass `topic.latest` directly; the\n\t// gate factory auto-adds the source under `${name}/source` inside its\n\t// own graph if not already registered.\n\tconst gateGraph = pipelineGraph(\"gates\");\n\tconst gateControllers = new Map<QueueRoute, GateController<TriagedItem>>();\n\tfor (const route of QUEUE_NAMES) {\n\t\tconst config = queueConfigs.get(route)!;\n\t\tif (!config.gated) continue;\n\t\tconst topic = queueTopics.get(route)!;\n\t\tconst ctrl = gateGraph.approvalGate<TriagedItem>(\n\t\t\t`${route}/gate`,\n\t\t\ttopic.latest as Node<unknown>,\n\t\t\t{\n\t\t\t\tmaxPending: config.maxPending,\n\t\t\t\tstartOpen: config.startOpen,\n\t\t\t},\n\t\t);\n\t\tgateControllers.set(route, ctrl);\n\t}\n\n\t// --- executeInput: merge of post-gate route latests + retry feedback ---\n\t// All inputs are SENTINEL until first DATA (COMPOSITION-GUIDE §1a): topic\n\t// `latest` returns `[]` on empty, gate `output` doesn't push pre-DATA.\n\tconst queueOutputs: Node<TriagedItem>[] = [];\n\tfor (const route of QUEUE_NAMES) {\n\t\tconst config = queueConfigs.get(route)!;\n\t\tif (config.gated && gateControllers.has(route)) {\n\t\t\tqueueOutputs.push(gateControllers.get(route)!.output as Node<TriagedItem>);\n\t\t} else {\n\t\t\tqueueOutputs.push(queueTopics.get(route)!.latest);\n\t\t}\n\t}\n\tqueueOutputs.push(retryTopic.latest);\n\n\tconst executeInput = merge<TriagedItem>(...queueOutputs);\n\n\t// --- Stages 5+6: EXECUTE → VERIFY via JobFlow (Tier 6.5 C2) ---\n\tconst executor: HarnessExecutor<A> =\n\t\topts.executor ?? defaultLlmExecutor<A>(adapter as LLMAdapter, opts.executePrompt);\n\tconst verifier: HarnessVerifier<A> =\n\t\topts.verifier ?? defaultLlmVerifier<A>(adapter as LLMAdapter, opts.verifyPrompt);\n\n\t// Per-stage `maxPerPump` caps via the JobFlow `StageDef.maxPerPump`\n\t// extension (Tier 6.5 D1 follow-up). Each stage gets its own cap;\n\t// callers can pin execute at a low concurrency for cost control while\n\t// leaving verify unbounded (or vice versa). Defaults to\n\t// `Number.MAX_SAFE_INTEGER` per stage — matches today's unbounded\n\t// `merge()` parallelism.\n\tconst executeMaxPerPump = opts.executeMaxPerPump ?? Number.MAX_SAFE_INTEGER;\n\tconst verifyMaxPerPump = opts.verifyMaxPerPump ?? Number.MAX_SAFE_INTEGER;\n\n\tconst executeFlow = jobFlow<HarnessJobPayload<A>>(`${name}/executeFlow`, {\n\t\tstages: [\n\t\t\t{ name: \"execute\", work: (job) => executor(job), maxPerPump: executeMaxPerPump },\n\t\t\t{ name: \"verify\", work: (job) => verifier(job), maxPerPump: verifyMaxPerPump },\n\t\t],\n\t});\n\n\t// Enqueue effect: per-item bridge from the reactive `executeInput`\n\t// stream into the JobFlow. Each non-null item becomes one JobEnvelope\n\t// at the execute stage. Retry items (via `retryTopic`) re-enter the\n\t// flow as fresh enqueues with their `$retries` counter bumped.\n\tconst enqueueEffect = node(\n\t\t[executeInput as Node<unknown>],\n\t\t(batchData, _actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst item = data[0];\n\t\t\tif (item === undefined) return;\n\t\t\texecuteFlow.enqueue({ item: item as TriagedItem });\n\t\t},\n\t\t{ name: \"execute-enqueue\", describeKind: \"effect\" },\n\t);\n\tconst enqueueUnsub = enqueueEffect.subscribe(() => {});\n\n\t// --- Stage 7: dispatch effect (REFLECT + retry/structural routing) ---\n\t//\n\t// Replaces the pre-Tier-6.5 `fastRetry` effect. Reads completed\n\t// JobEnvelopes from `executeFlow.completed`, identifies new ones via\n\t// WeakSet, and dispatches the 3-way verdict:\n\t//\n\t// 1. **Verified** → record success, publish VerifyResult, ack audit job.\n\t// 2. **Self-correctable + retries available** → republish to retryTopic\n\t// with $retries bumped (no audit ack — retry stays in the audit ledger).\n\t// 3. **Structural / retries exhausted** → record failure, publish\n\t// VerifyResult, ack audit job, reingest if reingestion budget remains.\n\t//\n\t// Imperative cross-graph publish from inside an effect is sanctioned\n\t// per COMPOSITION-GUIDE §32 / §35 for terminal side-effects with audit\n\t// trails (here: verifyResults / retry / intake topics).\n\tconst maxReingestions = opts.maxReingestions ?? 1;\n\tconst maxTotalRetries = Math.min(opts.maxTotalRetries ?? maxRetries * 10, 100);\n\tconst maxTotalReingestions = Math.min(opts.maxTotalReingestions ?? maxReingestions * 10, 100);\n\tconst totalRetries = node([], { initial: 0 });\n\tconst totalReingestions = node([], { initial: 0 });\n\n\tfunction assembleResult(\n\t\texecution: ExecutionResult<A>,\n\t\tverify: VerifyOutput,\n\t\titem: TriagedItem,\n\t): VerifyResult<A> {\n\t\treturn {\n\t\t\titem,\n\t\t\texecution,\n\t\t\tverified: verify.verified,\n\t\t\tfindings: verify.findings ?? [],\n\t\t\terrorClass: verify.errorClass,\n\t\t};\n\t}\n\n\tfunction handleVerified(vr: VerifyResult<A>, item: TriagedItem): void {\n\t\tstrategy.record(strategyKey(DEFAULT_PRESET_ID, item.rootCause, item.intervention), true, {\n\t\t\tpresetId: DEFAULT_PRESET_ID,\n\t\t\trootCause: item.rootCause,\n\t\t\tintervention: item.intervention,\n\t\t});\n\t\tverifyResults.publish(vr);\n\t\tackJob(item);\n\t}\n\n\tfunction handleRetry(vr: VerifyResult<A>, item: TriagedItem): void {\n\t\tconst key = trackingKey(item);\n\t\tconst itemRetries = item.$retries ?? 0;\n\t\tconst retryItem: TriagedItem = {\n\t\t\t...item,\n\t\t\t$retries: itemRetries + 1,\n\t\t\tsummary: `[RETRY ${itemRetries + 1}/${maxRetries}] ${key} — Previous attempt failed: ${vr.findings.join(\"; \")}`,\n\t\t\trelatedTo: [key],\n\t\t};\n\t\tretryTopic.publish(retryItem);\n\t\t// Audit job stays alive across retries — only terminal (verified /\n\t\t// structural) decisions remove it.\n\t}\n\n\tfunction handleStructural(vr: VerifyResult<A>, item: TriagedItem): void {\n\t\tstrategy.record(strategyKey(DEFAULT_PRESET_ID, item.rootCause, item.intervention), false, {\n\t\t\tpresetId: DEFAULT_PRESET_ID,\n\t\t\trootCause: item.rootCause,\n\t\t\tintervention: item.intervention,\n\t\t});\n\t\tverifyResults.publish(vr);\n\t\tackJob(item);\n\t\tconst key = trackingKey(item);\n\t\tconst itemReingestions = item.$reingestions ?? 0;\n\t\tif (\n\t\t\titemReingestions < maxReingestions &&\n\t\t\ttryIncrementBounded(totalReingestions, maxTotalReingestions)\n\t\t) {\n\t\t\tintake.publish({\n\t\t\t\tsource: item.source,\n\t\t\t\tsummary: `Verification failed for: ${key}`,\n\t\t\t\tevidence: vr.findings.join(\"\\n\"),\n\t\t\t\taffectsAreas: item.affectsAreas,\n\t\t\t\taffectsEvalTasks: item.affectsEvalTasks,\n\t\t\t\tseverity: item.severity ?? \"high\",\n\t\t\t\trelatedTo: [key],\n\t\t\t\t$reingestions: itemReingestions + 1,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Monotonic length cursor (qa F4) — `executeFlow.completed` retains up to\n\t// `DEFAULT_COMPLETED_RETAINED_LIMIT` (1024) entries; each new completion\n\t// emits a fresh snapshot containing every retained job. A naive\n\t// `WeakSet.has` walk is O(retainedLimit) per emit. Track the last-seen\n\t// length and only iterate the new tail. The cursor is capped at the\n\t// snapshot length to handle ring-buffer trims (when the retained log\n\t// drops oldest entries past the limit, `arr.length` shrinks and the\n\t// cursor catches up automatically).\n\tlet dispatchCursor = 0;\n\tconst dispatchEffect = node(\n\t\t[executeFlow.completed as Node<unknown>],\n\t\t(batchData, _actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst log = data[0];\n\t\t\tconst arr = (log ?? []) as readonly JobEnvelope<HarnessJobPayload<A>>[];\n\t\t\t// Trim handling: if the retained log shrunk below our cursor, the\n\t\t\t// missing entries are gone (we already processed them or the trim\n\t\t\t// happened mid-flight); just clamp.\n\t\t\tif (dispatchCursor > arr.length) dispatchCursor = arr.length;\n\t\t\tconst start = dispatchCursor;\n\t\t\tdispatchCursor = arr.length;\n\t\t\tfor (let i = start; i < arr.length; i++) {\n\t\t\t\tconst job = arr[i] as JobEnvelope<HarnessJobPayload<A>>;\n\t\t\t\tconst { item, execution, verify } = job.payload;\n\t\t\t\t// Defensive — both should always be present in a verify-stage\n\t\t\t\t// completion. If either is missing, log via verifyResults so the\n\t\t\t\t// failure is observable but don't block the dispatch effect.\n\t\t\t\tif (execution == null || verify == null) {\n\t\t\t\t\tackJob(item);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst vr = assembleResult(execution, verify, item);\n\t\t\t\tif (vr.verified) {\n\t\t\t\t\thandleVerified(vr, item);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst errClass =\n\t\t\t\t\tvr.errorClass ??\n\t\t\t\t\terrorClassifier({\n\t\t\t\t\t\titem,\n\t\t\t\t\t\toutcome: execution.outcome,\n\t\t\t\t\t\tdetail: vr.findings.join(\"; \"),\n\t\t\t\t\t});\n\t\t\t\tconst itemRetries = item.$retries ?? 0;\n\t\t\t\tif (\n\t\t\t\t\terrClass === \"self-correctable\" &&\n\t\t\t\t\titemRetries < maxRetries &&\n\t\t\t\t\ttryIncrementBounded(totalRetries, maxTotalRetries)\n\t\t\t\t) {\n\t\t\t\t\thandleRetry(vr, item);\n\t\t\t\t} else {\n\t\t\t\t\thandleStructural(vr, item);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ name: \"verify-dispatch\", describeKind: \"effect\" },\n\t);\n\tconst dispatchUnsub = dispatchEffect.subscribe(() => {});\n\n\t// REFLECT — topology marker derived from completed-log emissions.\n\t// `equals: () => false` disables Object.is absorption so each\n\t// completion produces an observable REFLECT tick (one per verify\n\t// wave). Without this, `null === null` would collapse every emit\n\t// after the first into RESOLVED and the trace would show a single\n\t// REFLECT event over the whole run.\n\tconst reflectNode = node(\n\t\t[executeFlow.completed as Node<unknown>],\n\t\t(_batchData, actions) => {\n\t\t\tactions.emit(null);\n\t\t},\n\t\t{\n\t\t\tname: \"reflect\",\n\t\t\tequals: () => false,\n\t\t},\n\t);\n\n\t// --- Optional priority scoring (Unit 19) ---\n\tlet priorityScores: Map<QueueRoute, Node<number>> | undefined;\n\tif (opts.priority) {\n\t\tpriorityScores = buildPriorityScores(queueTopics, strategy, opts);\n\t}\n\n\t// --- Assemble HarnessGraph ---\n\tconst harness = new HarnessGraph<A>(\n\t\tname,\n\t\tqueuesHub,\n\t\texecuteFlow,\n\t\tqueueTopics,\n\t\tjobQueues,\n\t\tgateControllers,\n\t\tstrategy,\n\t\ttotalRetries,\n\t\ttotalReingestions,\n\t\treflectNode as Node<null>,\n\t\tpriorityScores,\n\t);\n\n\t// Register disposers for unregistered internal nodes.\n\tharness.addDisposer(routerUnsub);\n\tharness.addDisposer(enqueueUnsub);\n\tharness.addDisposer(dispatchUnsub);\n\t// Strategy is mounted as a child subgraph below; its disposal cascades\n\t// via the mount lifecycle (no separate `addDisposer(strategy.dispose)`\n\t// needed post Class B audit Alt E migration).\n\tfor (const unsub of jobMirrorUnsubs) harness.addDisposer(unsub);\n\n\t// Register stage nodes for introspection (harnessTrace, describe,\n\t// observe). Tier 6.3: triage-input + router-input named so\n\t// `explain(intake.latest, reflect)` walks named nodes end-to-end with\n\t// no `<anonymous>` entries.\n\tharness.add(triageInput as Node<unknown>, { name: \"triage-input\" });\n\tharness.add(triageNode as Node<unknown>, { name: \"triage\" });\n\tharness.add(routerInput as Node<unknown>, { name: \"router-input\" });\n\tharness.add(executeInput as Node<unknown>, { name: \"execute-input\" });\n\tharness.add(enqueueEffect as Node<unknown>, { name: \"execute-enqueue\" });\n\tharness.add(dispatchEffect as Node<unknown>, { name: \"verify-dispatch\" });\n\tharness.add(reflectNode as Node<unknown>, { name: \"reflect\" });\n\t// Reflect is a topology marker — subscribe so its fn registers as a\n\t// reactive edge visible in `describe()` / `explain()` immediately on\n\t// harness construction.\n\tharness.addDisposer(reflectNode.subscribe(() => undefined));\n\tif (priorityScores) {\n\t\tfor (const [route, score] of priorityScores) {\n\t\t\tharness.add(score as Node<unknown>, { name: `priority/${route}` });\n\t\t\tharness.addDisposer(score.subscribe(() => {}));\n\t\t}\n\t}\n\n\t// Mount subgraphs\n\tharness.mount(\"queues\", queuesHub);\n\tharness.mount(\"gates\", gateGraph);\n\tharness.mount(\"executeFlow\", executeFlow);\n\tharness.mount(\"strategy\", strategy);\n\tfor (const [route, jq] of jobQueues) {\n\t\tharness.mount(`jobs/${route}`, jq);\n\t}\n\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` exposes provenance.\n\tharness.tagFactory(\"harnessLoop\", placeholderArgs(opts as unknown as Record<string, unknown>));\n\n\treturn harness;\n}\n\n// ---------------------------------------------------------------------------\n// Priority scoring wiring (Unit 19 decision 2)\n// ---------------------------------------------------------------------------\n\nfunction buildPriorityScores<A>(\n\tqueueTopics: Map<QueueRoute, TopicGraph<TriagedItem>>,\n\tstrategy: StrategyModelGraph,\n\topts: HarnessLoopOptions<A>,\n): Map<QueueRoute, Node<number>> {\n\tif (!opts.lastInteractionNs) {\n\t\tthrow new Error(\n\t\t\t\"harnessLoop: `opts.priority` requires `opts.lastInteractionNs` — pass a Node<number> (e.g. `fromTimer(60_000)` or a `state(monotonicNs())` you bump on human interaction). Priority scores only decay when this node settles; an internal default would freeze age at construction time.\",\n\t\t);\n\t}\n\tconst lastInteractionNs = opts.lastInteractionNs;\n\tconst signals = opts.priority ?? {};\n\tconst severityWeights = {\n\t\t...DEFAULT_SEVERITY_WEIGHTS,\n\t\t...signals.severityWeights,\n\t} as Record<string, number>;\n\tconst decayRate = signals.decayRate ?? DEFAULT_DECAY_RATE;\n\tconst effectivenessThreshold = signals.effectivenessThreshold ?? 0.7;\n\tconst effectivenessBoost = signals.effectivenessBoost ?? 15;\n\n\tconst scores = new Map<QueueRoute, Node<number>>();\n\tfor (const [route, topic] of queueTopics) {\n\t\tconst score = node<number>(\n\t\t\t[\n\t\t\t\ttopic.latest as Node<unknown>,\n\t\t\t\tstrategy.entries as Node<unknown>,\n\t\t\t\tlastInteractionNs as Node<unknown>,\n\t\t\t],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst vals = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst item = vals[0] as TriagedItem | undefined;\n\t\t\t\tif (item === undefined) {\n\t\t\t\t\tactions.emit(0);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst baseWeight = severityWeights[item.severity ?? \"medium\"] ?? 40;\n\t\t\t\tconst ageSeconds = (monotonicNs() - (vals[2] as number)) / 1e9;\n\t\t\t\tlet s = baseWeight * Math.exp(-decayRate * Math.max(0, ageSeconds));\n\t\t\t\tconst key = strategyKey(DEFAULT_PRESET_ID, item.rootCause, item.intervention);\n\t\t\t\tconst strat = vals[1] as ReadonlyMap<string, { successRate: number }>;\n\t\t\t\tconst entry = strat?.get(key);\n\t\t\t\tif (entry && entry.successRate >= effectivenessThreshold) {\n\t\t\t\t\ts += effectivenessBoost;\n\t\t\t\t}\n\t\t\t\tactions.emit(s);\n\t\t\t},\n\t\t\t{ name: `priority/${route}`, describeKind: \"derived\" },\n\t\t);\n\t\tscores.set(route, score);\n\t}\n\treturn scores;\n}\n","/**\n * Settled/signal helpers.\n *\n * Moved from extra/sources/settled.ts during cleave A2.\n * `keepalive` is substrate — it lives at `@graphrefly/pure-ts`\n * (`packages/pure-ts/src/extra/sources/_keepalive.ts`), not here.\n */\n\n/**\n * Settled / signal helpers — boundary primitives for converting reactive\n * sources into Promise/AbortSignal endpoints.\n *\n * - {@link firstValueFrom} / {@link firstWhere} — Promise of the first\n * matching DATA.\n * - {@link awaitSettled} — composition over `firstWhere` + reactive\n * `timeout` from `extra/resilience` (lazy import to avoid a\n * resilience → sources cycle).\n * - {@link nodeSignal} — `Node<boolean>` → `AbortSignal` bridge.\n * - {@link reactiveCounter} — capped counter exposed as a `Node<number>`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\n\n/**\n * Converts the first `DATA` on `source` into a Promise; rejects on `ERROR` or `COMPLETE` without data.\n *\n * **Important:** This subscribes and waits for a **future** emission. Data that\n * has already flowed is gone and will not be seen. Call this *before* the upstream\n * emits, or use `source.cache` / `source.status` for already-cached state.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * @param source - Node to read once.\n * @returns Promise of the first value.\n *\n * @example\n * ```ts\n * import { firstValueFrom, of } from \"@graphrefly/graphrefly-ts\";\n *\n * await firstValueFrom(of(42));\n * ```\n *\n * @category extra\n */\nexport function firstValueFrom<T>(source: Node<T>): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet shouldUnsub = false;\n\t\tlet unsub: (() => void) | undefined;\n\t\tunsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tresolve(m[1] as T);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(m[1]);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(new Error(\"completed without DATA\"));\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif (shouldUnsub) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t}\n\t});\n}\n\n/**\n * Wait for the first DATA value from `source` that satisfies `predicate`.\n *\n * Subscribes directly and resolves on the first DATA value where\n * `predicate` returns true. Reactive, no polling. Use in tests and\n * bridging code where you need a single matching value as a Promise.\n *\n * **Important:** This only captures **future** emissions — data that has\n * already flowed through the node is gone. Call this *before* the upstream\n * emits. For already-cached values, use `source.cache` / `source.status`.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * ```ts\n * const val = await firstWhere(strategy.snapshot, snap => snap.size > 0);\n * ```\n *\n * @param source - Upstream node to observe.\n * @param predicate - Returns `true` for the value to resolve on.\n * @param opts - `{ skipCurrent?: boolean }`. When `skipCurrent: true`, any DATA\n * delivered during the synchronous `subscribe()` call (push-on-subscribe §2.2\n * replay of the cached value) is ignored — the promise resolves only on the\n * next future emission. Useful when the caller wants to await the next\n * settlement event after an imperative action (e.g. `run()` minting a new\n * runVersion, where the currently-cached value belongs to the previous run).\n *\n * @category extra\n */\nexport function firstWhere<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: { skipCurrent?: boolean; kick?: () => void },\n): Promise<T> {\n\t// Lock 3.A (Phase 13.6.B): subscribe synchronously inside the function\n\t// body — NOT inside the Promise executor. Subscribing inside the\n\t// executor would defer the subscription past any synchronous `kick()`\n\t// the caller fires after the call returns, race-losing the very wave\n\t// the caller wants to observe.\n\t//\n\t// To bridge sync-subscribe with the async Promise contract, we record\n\t// any settlement that fires *before* the Promise constructor runs, and\n\t// the executor immediately resolves/rejects with the recorded value.\n\t// Settlements after the executor runs go straight through resolve/reject.\n\ttype Pending =\n\t\t| { kind: \"data\"; value: T }\n\t\t| { kind: \"error\"; err: unknown }\n\t\t| { kind: \"complete\" };\n\tlet pending: Pending | undefined;\n\tlet resolveFn: ((value: T) => void) | undefined;\n\tlet rejectFn: ((err: unknown) => void) | undefined;\n\tlet settled = false;\n\tlet shouldUnsub = false;\n\tlet unsub: (() => void) | undefined;\n\tlet inInitialSyncPhase = opts?.skipCurrent === true;\n\n\t// QA P1: every settler short-circuits when `settled === true` so a\n\t// later settle attempt (e.g. `kick()` throwing AFTER it synchronously\n\t// fired matching DATA, OR a `[DATA matched, ERROR]` wave during\n\t// push-on-subscribe) cannot overwrite an earlier `pending` outcome.\n\t// Without this gate, a kick that races sink-callback settlement could\n\t// reject a Promise the user already has resolved-DATA for.\n\tconst settleData = (v: T): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (resolveFn != null) resolveFn(v);\n\t\telse pending = { kind: \"data\", value: v };\n\t};\n\tconst settleError = (err: unknown): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"error\", err };\n\t};\n\tconst settleComplete = (): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tconst err = new Error(\"completed without matching value\");\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"complete\" };\n\t};\n\tconst detach = (): void => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\n\tconst sink: (msgs: Messages) => void = (msgs) => {\n\t\tif (settled) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (settled) return;\n\t\t\t// During the initial sync phase, swallow only cached DATA\n\t\t\t// (push-on-subscribe §2.2). Terminal ERROR / COMPLETE must\n\t\t\t// still reject the promise — otherwise an already-terminated\n\t\t\t// source synchronously delivering `[[ERROR, ...]]` or\n\t\t\t// `[[COMPLETE]]` during `subscribe()` would hang forever\n\t\t\t// under `skipCurrent: true`.\n\t\t\tif (inInitialSyncPhase && m[0] === DATA) continue;\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tconst v = m[1] as T;\n\t\t\t\tif (predicate(v)) {\n\t\t\t\t\tsettleData(v);\n\t\t\t\t\tdetach();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\tsettleError(m[1]);\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\tsettleComplete();\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\tunsub = source.subscribe(sink);\n\tinInitialSyncPhase = false;\n\t// Lock 3.A: fire `kick` AFTER subscribe is in place. With sync\n\t// subscribe + sync kick, the resulting wave reaches `sink` before\n\t// control returns — making subscribe-before-kick ordering structurally\n\t// impossible to misuse.\n\tif (opts?.kick != null && !settled) {\n\t\ttry {\n\t\t\topts.kick();\n\t\t} catch (err) {\n\t\t\tsettleError(err);\n\t\t\tdetach();\n\t\t}\n\t}\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\t// If a settlement landed synchronously before the executor runs,\n\t\t// flush it through immediately.\n\t\tif (pending != null) {\n\t\t\tif (pending.kind === \"data\") resolve(pending.value);\n\t\t\telse if (pending.kind === \"error\") reject(pending.err);\n\t\t\telse reject(new Error(\"completed without matching value\"));\n\t\t\treturn;\n\t\t}\n\t\tresolveFn = resolve;\n\t\trejectFn = reject;\n\t});\n}\n\n/**\n * Await the first non-nullish DATA value from `source`, with optional\n * timeout. Composition sugar over `firstWhere` + reactive timeout.\n *\n * Designed as the CLI/boundary sink for reactive pipelines that end in a\n * nullable node (e.g. `promptNode` — per COMPOSITION-GUIDE §8, it emits\n * `null` before it settles with a real value). Replaces the common pattern\n * `firstValueFrom(filter(source, v => v != null))` with a deadline.\n *\n * - Rejects with `TimeoutError` (from `extra/resilience`) if no matching\n * value arrives within `timeoutMs`. Omit `timeoutMs` for unbounded wait.\n * - `predicate` defaults to `v => v != null`. Pass a custom predicate to\n * gate on a stronger condition (e.g. `v => typeof v === \"string\"`).\n * - Pass `skipCurrent: true` to ignore the currently-cached value delivered\n * synchronously via push-on-subscribe and resolve only on the *next*\n * matching emission. Useful after an imperative action that should produce\n * a fresh settlement (e.g. `run()` minting a new version — the stale\n * cached value from the previous run must not resolve the new caller).\n *\n * ```ts\n * const brief = await awaitSettled(briefNode, { timeoutMs: 120_000 });\n * // or with a predicate:\n * const rich = await awaitSettled(node, {\n * predicate: (v): v is MyShape => typeof v === \"object\" && v != null && \"key\" in v,\n * timeoutMs: 60_000,\n * });\n * // or after kicking off a fresh run:\n * kickOff();\n * const fresh = await awaitSettled(resultNode, { skipCurrent: true });\n * ```\n *\n * Reactive inside, sync propagation — the one async boundary is the\n * returned `Promise<T>` (spec §5.10: async belongs at sources and\n * boundaries, not in the graph).\n *\n * @param source - Upstream node to observe.\n * @param opts - `{ predicate?, timeoutMs?, skipCurrent? }`.\n * @returns Promise that resolves with the first matching value, or rejects on timeout / ERROR / COMPLETE-without-DATA.\n *\n * @category extra\n */\n// Lazy module-cache for the `withTimeout` resilience operator. The dynamic\n// import keeps `settled` free of an eager edge into the resilience family;\n// first call pays the one-shot import, subsequent calls hit cached refs.\nlet _timeoutOp: typeof import(\"../resilience/timeout.js\").withTimeout | undefined;\nlet _nsPerMs: number | undefined;\n\nexport async function awaitSettled<T>(\n\tsource: Node<T>,\n\topts?: {\n\t\tpredicate?: (value: T) => boolean;\n\t\ttimeoutMs?: number;\n\t\tskipCurrent?: boolean;\n\t\t/**\n\t\t * Lock 3.A (Phase 13.6.B): fired AFTER subscribe is in place but\n\t\t * BEFORE the helper's async boundary is exposed to the caller.\n\t\t * Subscribe-before-kick is structurally enforced — the kick's\n\t\t * synchronous wave reaches `sink` before control returns. Replaces\n\t\t * the prior load-bearing-comment pattern (M.20-load-bearing) with\n\t\t * a misuse-impossible API shape.\n\t\t *\n\t\t * Common pattern:\n\t\t * await awaitSettled(node, {\n\t\t * skipCurrent: true,\n\t\t * kick: () => producer.emit(value),\n\t\t * });\n\t\t *\n\t\t * Omit `kick` for external-trigger cases where the wave is fired\n\t\t * by code outside the helper's caller; subscribe still lands\n\t\t * synchronously inside the helper body so the next external wave\n\t\t * is not lost.\n\t\t */\n\t\tkick?: () => void;\n\t},\n): Promise<NonNullable<T>> {\n\tconst predicate = opts?.predicate ?? ((v: T) => v != null);\n\tconst skipCurrent = opts?.skipCurrent;\n\tconst kick = opts?.kick;\n\tif (opts?.timeoutMs == null || opts.timeoutMs <= 0) {\n\t\treturn (await firstWhere(source, predicate, { skipCurrent, kick })) as NonNullable<T>;\n\t}\n\t// Reactive composition: `timeout()` wraps the source as a Node that\n\t// emits ERROR(TimeoutError) on deadline. `firstWhere` then resolves on\n\t// the first matching DATA or rejects on that ERROR. One async boundary\n\t// (the returned Promise), everything inside is sync reactive.\n\tif (_timeoutOp === undefined) {\n\t\tconst [timeoutMod, backoff] = await Promise.all([\n\t\t\timport(\"../resilience/timeout.js\"),\n\t\t\timport(\"../resilience/backoff.js\"),\n\t\t]);\n\t\t_timeoutOp = timeoutMod.withTimeout;\n\t\t_nsPerMs = backoff.NS_PER_MS;\n\t}\n\tconst guarded = _timeoutOp(source, { ns: opts.timeoutMs * (_nsPerMs as number) }).node;\n\treturn (await firstWhere(guarded, predicate, { skipCurrent, kick })) as NonNullable<T>;\n}\n\n/**\n * Converts a reactive `Node<boolean>` into a browser-standard `AbortSignal`\n * that fires when the node settles on `true`. Useful for threading a reactive\n * \"cancel\" flag into any async boundary that accepts a signal (fetch, LLM SDK\n * calls, child-process APIs, timers).\n *\n * **Contract.**\n * - `signal.abort(reason)` fires exactly once, on the first DATA emission with\n * a truthy value. Subsequent emissions are ignored (AbortSignal is\n * single-shot).\n * - Null / `false` / sentinel values are ignored. Push-on-subscribe will\n * check the currently-cached value on subscribe and abort immediately if\n * it's already `true`.\n * - `reason` defaults to `\"cancelled via nodeSignal\"`; pass `opts.reason` to\n * override (`DOMException`, `Error`, or any value accepted by\n * `AbortController.abort`).\n *\n * **Lifecycle.**\n * - Returns a `{signal, dispose}` bundle. Call `dispose()` when you're done\n * with the signal (e.g. in a `finally` after the async operation completes).\n * `dispose()` unsubscribes from the node and is a no-op once the signal has\n * fired.\n * - **Memory note:** without `dispose()` the subscription keeps the reactive\n * node alive for the lifetime of the process. For bridge calls inside a\n * `switchMap` project fn, the switchMap supersede tears the inner subgraph\n * down, which is usually the right lifetime — but still call `dispose()`\n * from the caller's `finally` for clarity.\n *\n * @example\n * ```ts\n * const aborted = state(false);\n * const { signal, dispose } = nodeSignal(aborted);\n * try {\n * const resp = await adapter.invoke(msgs, { signal });\n * return resp;\n * } finally {\n * dispose();\n * }\n * ```\n *\n * @category extra\n */\nexport function nodeSignal(\n\tsource: Node<boolean>,\n\topts?: { reason?: unknown },\n): { signal: AbortSignal; dispose: () => void } {\n\tconst ctrl = new AbortController();\n\tconst reason = opts?.reason ?? new Error(\"cancelled via nodeSignal\");\n\tlet unsub: (() => void) | undefined;\n\tlet shouldUnsub = false;\n\tconst done = () => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\tunsub = source.subscribe((msgs) => {\n\t\tif (ctrl.signal.aborted) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA && m[1] === true) {\n\t\t\t\tctrl.abort(reason);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\t// Treat an ERROR on the abort source as a cancel signal too —\n\t\t\t\t// a broken control channel should fail closed, not leak the\n\t\t\t\t// in-flight call. Use the error as the abort reason.\n\t\t\t\tctrl.abort(m[1]);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t// Source completed without aborting — no-op. `done()` already\n\t\t\t\t// released the subscription here, so a later `dispose()` call\n\t\t\t\t// from the caller is a no-op (safe / idempotent).\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\treturn {\n\t\tsignal: ctrl.signal,\n\t\tdispose: () => {\n\t\t\tif (unsub) {\n\t\t\t\tunsub();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// reactiveCounter\n// ---------------------------------------------------------------------------\n\n/** Bundle returned by {@link reactiveCounter}. */\nexport type ReactiveCounterBundle = {\n\t/** Reactive node holding the current count. */\n\treadonly node: Node<number>;\n\t/** Increment by 1. Returns `false` if cap would be exceeded. */\n\tincrement(): boolean;\n\t/** Current count (synchronous read). */\n\tget(): number;\n\t/** Whether the counter has reached its cap. */\n\tatCap(): boolean;\n};\n\n/**\n * Reactive counter with a cap — the building block for circuit breakers.\n *\n * Wraps a `state(0)` node with `increment()` that respects a maximum.\n * The `node` is subscribable and composable like any reactive node. When\n * the cap is reached, `increment()` returns `false`.\n *\n * ```ts\n * const retries = reactiveCounter(10);\n * retries.increment(); // true — count is now 1\n * retries.node.subscribe(...); // reactive updates\n * retries.atCap(); // false\n * ```\n *\n * @param cap - Maximum value (inclusive). 0 = no increments allowed.\n * @category extra\n */\nexport function reactiveCounter(cap: number): ReactiveCounterBundle {\n\tconst counter = node([], { initial: 0 });\n\treturn {\n\t\tnode: counter,\n\t\tincrement() {\n\t\t\tconst current = counter.cache ?? 0;\n\t\t\tif (current >= cap) return false;\n\t\t\tcounter.down([[DIRTY], [DATA, current + 1]]);\n\t\t\treturn true;\n\t\t},\n\t\tget() {\n\t\t\treturn counter.cache ?? 0;\n\t\t},\n\t\tatCap() {\n\t\t\treturn (counter.cache ?? 0) >= cap;\n\t\t},\n\t};\n}\n","/**\n * Retry — re-attempt a node on terminal failure.\n *\n * Two modes selected by the type of `input`:\n * - **Source mode** (`Node<T>`): resubscribes the same node after each ERROR.\n * Upstream must be `resubscribable: true` or retries are silent no-ops.\n * - **Factory mode** (`() => Node<T>`): builds a fresh node per attempt.\n *\n * Shared with `circuitBreaker` / `rateLimiter`: `NodeOrValue<RetryOptions>`\n * lets callers swap retry config reactively (re-validates on each attempt).\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Message,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n} from \"@graphrefly/pure-ts/core\";\nimport { coerceDelayNs, isNode, msgVal, type NodeOrValue, operatorOpts } from \"./_internal.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport type { StatusValue } from \"./status.js\";\n\n/**\n * Lifecycle-shaped state companion emitted by {@link retry} (DS-13.5.B,\n * locked 2026-05-01). Tracks the retry state machine's current status,\n * the attempt counter, and the last scheduled delay (null before the\n * first retry).\n *\n * @category extra/resilience\n */\nexport interface RetryState {\n\tstatus: StatusValue;\n\tattempt: number;\n\tlastDelay_ns: number | null;\n}\n\n/**\n * Bundle returned by {@link retry}: the retry-wrapped output node and its\n * lifecycle state companion. Pre-1.0 break vs the prior `Node<T>` return.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `retryState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `retryState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `retryState`, including\n * `publish(\"pending\")` resets that can clobber an in-flight machine's\n * `running`/`paused` state. Don't fan out `node` to multiple subscribers\n * and rely on `retryState` accuracy unless you use\n * {@link keepalive} / `share`-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface RetryBundle<T> {\n\tnode: Node<T>;\n\tretryState: Node<RetryState>;\n}\n\nexport type RetryOptions = {\n\t/**\n\t * Max retry attempts after each terminal `ERROR` (not counting the first failure).\n\t *\n\t * **Required when `backoff` is set.** Pass `Infinity` to opt in to unbounded retries\n\t * — the explicit value rules out the silent-infinite-budget footgun (a flaky provider\n\t * + exponential backoff + omitted `count` would previously default to ~2.1B retries).\n\t */\n\tcount?: number;\n\t/** Delay between attempts; strategies use **nanoseconds**. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n\t/**\n\t * Caller-supplied metadata merged into the produced node's `meta` (Tier 5.2\n\t * D8 widening). Use {@link domainMeta} to tag the layer for `describe()`\n\t * grouping. The primitive's `factoryTag(\"retry\", …)` always wins against\n\t * caller keys.\n\t */\n\tmeta?: Record<string, unknown>;\n};\n\n/** Factory-mode-only options. `initial` seeds the outer node's cache before the first attempt. */\nexport type RetryFactoryOptions<T> = RetryOptions & {\n\t/** Initial cache value for the outer node before the factory runs the first time. */\n\tinitial?: T;\n};\n\n/**\n * Resolved retry config shared by source-mode and factory-mode wrappers.\n * Centralises the unbounded-retry footgun guard and strategy resolution.\n */\ntype ResolvedRetryConfig = {\n\tmaxRetries: number;\n\tstrategy: BackoffStrategy | null;\n};\n\nfunction resolveRetryConfig(opts?: RetryOptions): ResolvedRetryConfig {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\n\t// Unbounded-retry footgun fix: if `backoff` is set without explicit `count`,\n\t// throw at construction time. Caller must opt in to `Infinity` for unbounded.\n\tif (backoffOpt !== undefined && count === undefined) {\n\t\tthrow new RangeError(\n\t\t\t\"retry({ backoff }) requires explicit count to prevent unbounded retries; pass { count: <n>, backoff: ... }\",\n\t\t);\n\t}\n\n\tconst maxRetries = count !== undefined ? count : 0;\n\tif (maxRetries < 0) throw new RangeError(\"retry count must be >= 0\");\n\n\tconst strategy: BackoffStrategy | null =\n\t\tbackoffOpt === undefined\n\t\t\t? null\n\t\t\t: typeof backoffOpt === \"string\"\n\t\t\t\t? resolveBackoffPreset(backoffOpt)\n\t\t\t\t: backoffOpt;\n\n\treturn { maxRetries, strategy };\n}\n\nfunction retryFactoryArgs(opts?: RetryOptions): Record<string, unknown> | undefined {\n\tconst args: Record<string, unknown> = {};\n\tif (opts?.count !== undefined) args.count = opts.count;\n\tif (typeof opts?.backoff === \"string\") args.backoff = opts.backoff;\n\treturn Object.keys(args).length > 0 ? args : undefined;\n}\n\n/**\n * Shared retry state machine. Both `_retrySource` and `_retryFactory` thin-wrap this:\n * the only per-mode logic is supplied via `acquireSource` (returns a fresh `Node<T>`\n * per attempt — for source-mode it just returns the captured `Node`; for factory-mode\n * it calls the user factory and forwards synchronous throws into the same retry path).\n *\n * **Reactive cfg (Tier 6.5 3.2.2, 2026-04-29).** `getCfg` is invoked at\n * every decision point (`scheduleRetryOrFinish` count + strategy reads)\n * so option swaps mid-flight take effect at the next attempt boundary\n * per the locked semantic rule: \"next attempt fails immediately if\n * already exhausted under new count; `backoff` swap takes effect at next\n * retry's delay calculation.\"\n */\nfunction _runRetryStateMachine<T>(\n\tgetCfg: () => ResolvedRetryConfig,\n\tacquireSource: () => Node<T>,\n\ta: { emit: (v: T) => void; down: (msgs: Message[]) => void },\n\temitState?: (next: RetryState) => void,\n): () => void {\n\tlet attempt = 0;\n\tlet stopped = false;\n\tlet prevDelay: number | null = null;\n\tlet unsub: (() => void) | undefined;\n\tconst timer = new ResettableTimer();\n\tconst publish = (status: StatusValue): void => {\n\t\temitState?.({ status, attempt, lastDelay_ns: prevDelay });\n\t};\n\tpublish(\"pending\");\n\n\tfunction disconnectUpstream(): void {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\tif (stopped) return;\n\t\tconst cfg = getCfg();\n\t\tif (attempt >= cfg.maxRetries) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tconst raw = cfg.strategy === null ? 0 : cfg.strategy(attempt, err, prevDelay);\n\t\t// null from strategy = \"stop retrying\" (e.g. withMaxAttempts cap reached)\n\t\tif (raw === null || raw === undefined) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\t// A misbehaving strategy (returns NaN / non-finite / negative) MUST NOT\n\t\t// escape into the upstream drain. Treat it like `strategy === null`\n\t\t// (stop retrying) and emit the original error — the strategy bug is a\n\t\t// separate concern the user can inspect via the emitted error's stack.\n\t\tlet delayNs: number;\n\t\ttry {\n\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t} catch {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tprevDelay = delayNs;\n\t\tattempt += 1;\n\t\tdisconnectUpstream();\n\t\tpublish(\"paused\");\n\t\t// `Math.max(1, …)` floor: every backoff schedule floors at 1ms even when\n\t\t// the strategy returns 0ns. Avoids 0-delay re-entrancy on the active\n\t\t// stack frame (which would risk stack overflow on a tight ERROR loop).\n\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\ttimer.start(delayMs, () => {\n\t\t\tif (stopped) return;\n\t\t\tconnect();\n\t\t});\n\t}\n\n\tfunction connect(): void {\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tlet src: Node<T>;\n\t\ttry {\n\t\t\tsrc = acquireSource();\n\t\t} catch (err) {\n\t\t\tscheduleRetryOrFinish(err);\n\t\t\treturn;\n\t\t}\n\t\tpublish(\"running\");\n\t\tunsub = src.subscribe((msgs) => {\n\t\t\tif (stopped) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst t = m[0];\n\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\telse if (t === DATA) {\n\t\t\t\t\tattempt = 0;\n\t\t\t\t\tprevDelay = null;\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\tpublish(\"running\");\n\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t// DF2 (2026-04-29): set `stopped = true` BEFORE\n\t\t\t\t\t// `disconnectUpstream()` so a re-entrant ERROR delivered\n\t\t\t\t\t// in the same wave (after disconnect runs but before the\n\t\t\t\t\t// teardown closure fires `stopped = true`) hits the\n\t\t\t\t\t// `if (stopped) return` guard at line 159 and cannot\n\t\t\t\t\t// schedule a new retry timer.\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\tpublish(\"completed\");\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\treturn;\n\t\t\t\t} else a.down([m]);\n\t\t\t}\n\t\t});\n\t}\n\n\tconnect();\n\n\treturn () => {\n\t\tconst wasStopped = stopped;\n\t\tstopped = true;\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tif (!wasStopped) publish(\"cancelled\");\n\t};\n}\n\n/**\n * Retry operator — two modes selected by the type of `input`:\n *\n * **Source mode** (`input: Node<T>`): resubscribes to the same node after each terminal\n * `ERROR`. The upstream should use `resubscribable: true` if it must emit again after `ERROR`.\n *\n * **Factory mode** (`input: () => Node<T>`): invokes the factory to build a fresh `Node<T>`\n * on every connect / reconnect. Ideal for producers that capture per-attempt resources\n * (sockets, clients, file handles) that become unusable after an error. Synchronous\n * exceptions thrown by the factory are treated as terminal ERROR and run through the\n * same retry pipeline as inner-node ERROR.\n *\n * @param input - Upstream node or factory that returns a fresh node per attempt.\n * @param opts - `count` caps attempts (**required when `backoff` is set**; pass `Infinity` to opt in to unbounded); `backoff` supplies delay in **nanoseconds** (or a preset name); `initial` seeds the outer node cache (factory mode only).\n * @returns Node that retries on error.\n *\n * @throws {RangeError} when `backoff` is provided without an explicit `count` (unbounded-retry footgun guard) or when `count < 0`.\n *\n * @remarks\n * **Protocol:** Forwards unknown message tuples unchanged; handles `DIRTY`, `DATA`, `RESOLVED`, `COMPLETE`, `ERROR`.\n *\n * **Backoff floor:** every scheduled delay is floored at 1ms via `Math.max(1, delayNs / NS_PER_MS)` even when the strategy returns 0ns. This avoids 0-delay re-entrancy on the active stack frame on a tight ERROR loop. Strategies that return `null`/`undefined` stop retrying immediately and forward the original error.\n *\n * @example\n * ```ts\n * // Source mode — resubscribe the same node:\n * import { ERROR, NS_PER_SEC, producer, retry, constant } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = producer(\n * (a) => { a.down([[ERROR, new Error(\"x\")]]); },\n * { resubscribable: true },\n * );\n * const out = retry(src, { count: 2, backoff: constant(0.25 * NS_PER_SEC) });\n *\n * // Factory mode — fresh node per attempt (e.g. reconnecting WebSocket):\n * import { NS_PER_SEC, exponential, retry, fromWebSocket } from \"@graphrefly/graphrefly-ts\";\n *\n * const connected$ = retry(\n * () => fromWebSocket(new WebSocket(\"wss://example/stream\")),\n * { count: 10, backoff: exponential({ baseNs: 1 * NS_PER_SEC }) },\n * );\n * ```\n *\n * @category extra\n */\nexport function retry<T>(input: Node<T>, opts?: NodeOrValue<RetryOptions>): RetryBundle<T>;\nexport function retry<T>(\n\tinput: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n): RetryBundle<T>;\nexport function retry<T>(\n\tinput: Node<T> | (() => Node<T>),\n\topts?: NodeOrValue<RetryOptions | RetryFactoryOptions<T>>,\n): RetryBundle<T> {\n\tconst retryState = node<RetryState>([], {\n\t\tname: \"retryState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\", attempt: 0, lastDelay_ns: null },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\tconst emit = (s: RetryState): void => {\n\t\tretryState.down([[DIRTY], [DATA, s]]);\n\t};\n\tif (typeof input === \"function\") {\n\t\treturn {\n\t\t\tnode: _retryFactory(input, opts as NodeOrValue<RetryFactoryOptions<T>> | undefined, emit),\n\t\t\tretryState,\n\t\t};\n\t}\n\treturn {\n\t\tnode: _retrySource(input, opts as NodeOrValue<RetryOptions> | undefined, emit),\n\t\tretryState,\n\t};\n}\n\n// DS-13.5.B helper: like `resolveReactiveOption` but shallow-merges each\n// reactive emit over the prior opts and treats empty `{}` as a no-op\n// (per the locked cross-cutting rule). Static-form arg returns the value\n// as-is and never subscribes.\nfunction makeMergedOptsMirror<R extends Record<string, unknown>>(\n\targ: NodeOrValue<R> | undefined,\n): { current: () => R | undefined; unsub: () => void } {\n\tif (arg === undefined) {\n\t\treturn { current: () => undefined, unsub: () => undefined };\n\t}\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg as R, unsub: () => undefined };\n\t}\n\tconst optsNode = arg as Node<R>;\n\tlet merged: R | undefined = (optsNode.cache as R | undefined) ?? undefined;\n\tconst unsub = optsNode.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] !== DATA) continue;\n\t\t\tconst next = m[1] as R | undefined;\n\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\tif (Object.keys(next).length === 0) continue; // empty {} no-op\n\t\t\tmerged = { ...(merged ?? ({} as R)), ...next } as R;\n\t\t}\n\t});\n\treturn { current: () => merged, unsub };\n}\n\n// DF6 (2026-04-29): once-per-source dedup for the source-mode-retry warn.\n// Mirrors the `_bumpCursorWarned` pattern in `extra/mutation/index.ts`.\nconst _retrySourceNonResubscribableWarned = new WeakSet<Node<unknown>>();\n\nfunction _retrySource<T>(\n\tsource: Node<T>,\n\topts?: NodeOrValue<RetryOptions>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\t// Source-mode retry re-subscribes to the SAME source node after each\n\t// terminal ERROR. If the upstream was constructed with the default\n\t// `resubscribable: false`, the second subscribe-after-terminal is a\n\t// silent no-op and retries effectively never re-deliver. Surface\n\t// once-per-source so misconfigurations fail loud without log spam.\n\tconst sourceWithFlag = source as unknown as { _resubscribable?: boolean };\n\tif (\n\t\tsourceWithFlag._resubscribable === false &&\n\t\t!_retrySourceNonResubscribableWarned.has(source)\n\t) {\n\t\t_retrySourceNonResubscribableWarned.add(source);\n\t\tconsole.warn(\n\t\t\t\"retry(source, opts): source-mode requires `resubscribable: true` on the upstream \" +\n\t\t\t\t\"node. Retries will be silent no-ops after the first ERROR. Either pass \" +\n\t\t\t\t\"`resubscribable: true` to the source factory, OR use factory-mode retry \" +\n\t\t\t\t\"`retry(() => buildSource(), opts)` so each attempt builds a fresh node.\",\n\t\t);\n\t}\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryOptions | undefined);\n\t// Eager validation for static-form opts (preserves construction-time\n\t// \"backoff without count\" RangeError). Reactive-form opts re-validate\n\t// per `getCfg()` call inside the state machine.\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryOptions>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, () => source, a, emitState);\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tinner();\n\t\t\t\t\tmerged.unsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n\nfunction _retryFactory<T>(\n\tfactory: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryFactoryOptions<T> | undefined);\n\t// Eager validation for static-form opts (Tier 3.1 footgun preservation).\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryFactoryOptions<T>>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, factory, a, emitState);\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tinner();\n\t\t\t\t\tmerged.unsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: staticOpts?.initial as T | undefined,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n","/**\n * `promptNode` — universal LLM transform as a reactive derived node.\n *\n * The shape: `deps → messagesNode (derived) → switchMap → response (producer) → output`.\n * Each upstream wave is one LLM call; superseding waves cancel the in-flight\n * call via the abort signal threaded through `nodeSignal(opts.abort)`.\n *\n * The producer-shape on the inner is load-bearing: it emits exactly one DATA\n * + COMPLETE per wave, so the outer switchMap sees one DATA per wave (matches\n * the `HarnessExecutor` contract). A `node([response], (batchData, actions, ctx) => {\n * const data = ...; actions.emit(parse(data[0]));\n * }, { describeKind: \"derived\" })` would have its\n * own first-run / push-on-subscribe semantics that can leak a transient null\n * before the real response arrives — observed and reverted in an earlier\n * attempt; see SESSION-ai-harness-module-review.md line 3654 for context.\n * Locked as path (b) producer-based by Session C (2026-04-27); inner-node\n * naming aligned to `prompt_node::response` per the C+D widening (2026-04-30).\n *\n * **Retry / replay-cache.** Stack middleware on the adapter:\n *\n * ```ts\n * import { withRetry, withReplayCache } from \"@graphrefly/graphrefly/patterns/ai\";\n *\n * const adapter = withRetry(\n * withReplayCache(baseAdapter, { keyFn: (ctx) => ctx.messages[0].content }),\n * { count: 3, backoff: 200 },\n * );\n * const result = promptNode(adapter, [input], (q) => q);\n * ```\n *\n * `promptNode` no longer ships `retries` / `cache` options — they duplicated\n * middleware already at the adapter layer.\n *\n * **Cross-wave cache (COMPOSITION-GUIDE §32).** The switchMap output cache\n * survives across new outer DATAs — `promptNode`'s cached value persists\n * until the next wave fully resolves. Consumers that need to distinguish\n * \"fresh value for THIS session\" from \"stale cache from a prior session\"\n * (e.g. `agentLoop` resetting on new `run()`) must add a `node([])` mirror\n * at their session boundary and depend on the mirror, not the `promptNode`\n * output directly. `promptNode` itself stays primitive — it does not\n * embed a state-mirror.\n *\n * @module\n */\n\nimport { COMPLETE, DATA, ERROR, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { fromAny, type NodeInput, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { nodeSignal } from \"../../../base/sources/settled.js\";\nimport { aiMeta, stripFences } from \"../_internal.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n\tToolDefinition,\n} from \"../adapters/core/types.js\";\n\nexport type PromptNodeOptions = {\n\tname?: string;\n\tmodel?: string;\n\ttemperature?: number;\n\tmaxTokens?: number;\n\t/**\n\t * Output format:\n\t * - `\"text\"` (default) — emit the response content as a string.\n\t * - `\"json\"` — `JSON.parse` the content (markdown fences stripped).\n\t * - `\"raw\"` — emit the full {@link LLMResponse} object (subsumes the\n\t * pre-Tier-2.3 `fromLLM` shape; use this when you need `usage` /\n\t * `toolCalls` / `finishReason` alongside `content`).\n\t */\n\tformat?: \"text\" | \"json\" | \"raw\";\n\t/**\n\t * Reactive tool definitions forwarded to the adapter. Pair with\n\t * `format: \"raw\"` (or read `toolCalls` from a downstream parser) when\n\t * tool-calling is in scope.\n\t *\n\t * **Reactive declared edge** (DF12, Tier 7): `tools` is a `Node` so the\n\t * tools list participates in `describe()` topology and `explain()` causal\n\t * chains. The tools Node is added to `messagesNode`'s declared deps —\n\t * tools changes re-invoke the LLM (treated as a new call envelope).\n\t * Wrap with `distinctUntilChanged` upstream if your tool selector emits\n\t * noisy duplicates that would otherwise spam the adapter. See\n\t * COMPOSITION-GUIDE §31 (Dynamic tool selection) for the canonical\n\t * `toolSelector` pattern that produces this Node.\n\t *\n\t * **Activation note:** since `tools` is a real declared dep, `messagesNode`\n\t * waits for the tools Node to DATA at least once before firing\n\t * (push-on-subscribe SENTINEL gate). Pass a `node<ToolDefinition[]>([], { initial: [] })`\n\t * if you want immediate activation with no tools, or the latest published\n\t * `toolSelector.tools` Node.\n\t */\n\ttools?: Node<readonly ToolDefinition[]>;\n\t/**\n\t * Optional system prompt. Forwarded via `opts.systemPrompt` to the adapter\n\t * only — never pushed as a `{role:\"system\"}` message (avoiding the\n\t * double-send class of bug where adapters that normalize both shapes end\n\t * up with two system entries).\n\t */\n\tsystemPrompt?: string;\n\t/**\n\t * Optional reactive abort signal. When the node emits `true`, the in-flight\n\t * `adapter.invoke()` call is cancelled via `AbortController.abort()`.\n\t * Threaded through `nodeSignal(abort)` — a one-shot bridge. Useful inside\n\t * agent state machines where a separate `aborted` state should cancel the\n\t * current LLM call without superseding via switchMap.\n\t */\n\tabort?: Node<boolean>;\n\tmeta?: Record<string, unknown>;\n};\n\n/** Extract text content from an LLM response, handling various response shapes. */\nfunction extractContent(resp: unknown): string {\n\tif (resp != null && typeof resp === \"object\" && \"content\" in resp) {\n\t\treturn String((resp as LLMResponse).content);\n\t}\n\tif (typeof resp === \"string\") return resp;\n\treturn String(resp);\n}\n\nfunction previewContent(text: string, max = 200): string {\n\tif (text.length <= max) return text;\n\treturn `${text.slice(0, max)}…`;\n}\n\n/**\n * Universal LLM transform: wraps a prompt template + model adapter into a reactive derived node.\n * Re-invokes the LLM whenever any dep changes. Suitable for triage, QA, hypothesis, parity, etc.\n *\n * **Topology** (visible in `describe()`):\n * ```\n * <deps...>, [tools?] → <name>::messages (derived, meta.ai = prompt_node::messages)\n * <name>::messages → <name>::output (switchMap product, meta.ai = prompt_node::output)\n * per-wave inner: <name>::response (producer, meta.ai = prompt_node::response)\n * ```\n * When `opts.tools` is supplied, the tools `Node` is appended to\n * `messagesNode`'s declared deps so it appears as a real edge in `describe()`\n * / `explain()` (DF12, Tier 7).\n *\n * **No-input semantics** (matches the codebase-wide SENTINEL convention):\n * - **Initial no-input** (no real input has ever arrived) — emits nothing.\n * Outer cache stays `undefined`; `subscribe` consumers see no DATA event.\n * Use this to keep downstream gating clean: a `withLatestFrom`-paired\n * trigger won't fire until the LLM has actually produced something.\n * - **Mid-flow no-input** (input dropped to nullish after at least one\n * real LLM call) — emits `null` as a domain \"input went away\" signal.\n * Downstream consumers can distinguish \"haven't started\" from \"input\n * gone.\"\n *\n * **Retries / caching:** stack `withRetry` / `withReplayCache` middleware on the\n * `adapter` argument — `promptNode` no longer ships its own duplicated retry /\n * cache loops (pre-1.0 cleanup, see review session 1).\n *\n * @param adapter - LLM adapter (provider-agnostic). Wrap with `withRetry` /\n * `withReplayCache` middleware for transient-error tolerance\n * or replay caching.\n * @param deps - Input nodes whose values feed the prompt.\n * @param prompt - Static string or template function receiving dep values.\n * @param opts - Optional configuration.\n * @returns `Node` emitting LLM responses (string or parsed JSON).\n */\n// Overload 1: `format: \"raw\"` constrains the emit type to `LLMResponse | null`\n// (the full adapter response, with `usage` / `toolCalls` / `finishReason`).\n// Subsumes the pre-Tier-2.3 `fromLLM` shape.\nexport function promptNode(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts: PromptNodeOptions & { format: \"raw\" },\n): Node<LLMResponse | null>;\n// Overload 2: `format: \"text\" | \"json\"` (default text) — emit-type is the\n// caller's `T` (defaults to `string`). For `\"json\"` callers typically pass\n// the parsed shape (e.g. `promptNode<MyShape>(...)`).\nexport function promptNode<T = string>(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts?: Omit<PromptNodeOptions, \"format\"> & { format?: \"text\" | \"json\" },\n): Node<T | null>;\nexport function promptNode<T = string>(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts?: PromptNodeOptions,\n): Node<T | null> {\n\tconst format = opts?.format ?? \"text\";\n\tconst baseName = opts?.name ?? \"prompt_node\";\n\n\t// qa A8: tools without `format: \"raw\"` is a footgun — adapter receives\n\t// the tool definitions and may produce `toolCalls`, but the emit path\n\t// only extracts `content`. Warn at construction; downstream parsers\n\t// reading `toolCalls` from a custom `format: \"raw\"` consumer pattern\n\t// can ignore by setting `format: \"raw\"` (intent now matches behavior).\n\tif (opts?.tools !== undefined && format !== \"raw\") {\n\t\tconsole.warn(\n\t\t\t\"promptNode: `tools` is set but `format !== 'raw'`. \" +\n\t\t\t\t\"Tool calls in the response will be silently dropped — set \" +\n\t\t\t\t\"`format: 'raw'` to receive the full LLMResponse with `toolCalls`.\",\n\t\t);\n\t}\n\n\t// SENTINEL semantics rely on the universal first-run gate + standard\n\t// prevData semantics (undefined = SENTINEL, any other value = DATA seen):\n\t// - **Initial no-input** (no dep has ever DATA'd, so prevData is\n\t// undefined across the board): the `derived`'s first-run gate blocks\n\t// `messagesNode`'s fn entirely. It never emits, switchMap never\n\t// fires, outer cache stays `undefined`.\n\t// - **Mid-flow no-input** (deps previously DATA'd then went nullish):\n\t// fn runs, returns `[]`, switchMap dispatches the `node([], { initial: null })`\n\t// branch → outer emits `null` as the domain \"input went away\" signal.\n\t// No `initial: []` and no closure flag — `prevData === undefined` is\n\t// already the sentinel marker, and the gate already enforces \"don't fire\n\t// fn until every dep has DATA'd at least once.\"\n\t//\n\t// DF12: when `opts.tools` is a Node, it's appended to `messagesNode`'s\n\t// declared deps. The fn slices values into user-deps + tools, and emits\n\t// an envelope `{ messages, tools }` so switchMap's per-wave inner can\n\t// read the latest tools via the reactive edge instead of a closure.\n\ttype Envelope = {\n\t\tmessages: readonly ChatMessage[];\n\t\ttools: readonly ToolDefinition[] | undefined;\n\t};\n\tconst userDepsLength = deps.length;\n\tconst allDeps: readonly Node<unknown>[] =\n\t\topts?.tools !== undefined ? [...deps, opts.tools as Node<unknown>] : deps;\n\tconst messagesNode = node<Envelope>(\n\t\tallDeps as Node<unknown>[],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst userValues = data.slice(0, userDepsLength);\n\t\t\tconst toolsValue =\n\t\t\t\topts?.tools !== undefined\n\t\t\t\t\t? (data[userDepsLength] as readonly ToolDefinition[] | undefined)\n\t\t\t\t\t: undefined;\n\t\t\t// Dep-level null guard (composition guide §8): if any USER dep is\n\t\t\t// nullish, emit empty messages → switchMap emits null (mid-flow\n\t\t\t// drop-out). The tools dep can legitimately be empty `[]`; only\n\t\t\t// user deps gate the call.\n\t\t\tif (userValues.some((v) => v == null)) {\n\t\t\t\tactions.emit({ messages: [], tools: toolsValue });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst text = typeof prompt === \"string\" ? prompt : prompt(...userValues);\n\t\t\tif (!text) {\n\t\t\t\tactions.emit({ messages: [], tools: toolsValue });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// systemPrompt forwarded through invoke opts only (no double-send).\n\t\t\tactions.emit({\n\t\t\t\tmessages: [{ role: \"user\" as const, content: text }],\n\t\t\t\ttools: toolsValue,\n\t\t\t});\n\t\t},\n\t\t{\n\t\t\tname: `${baseName}::messages`,\n\t\t\tmeta: aiMeta(\"prompt_node::messages\"),\n\t\t},\n\t);\n\n\tconst result = switchMap<Envelope, T | null>(\n\t\tmessagesNode,\n\t\t(envelope) => {\n\t\t\tconst { messages: msgs, tools } = envelope;\n\t\t\tif (!msgs || msgs.length === 0) {\n\t\t\t\treturn node<T | null>([], { initial: null }) as NodeInput<T | null>;\n\t\t\t}\n\n\t\t\t// Producer ensures exactly one DATA + COMPLETE per wave; switchMap\n\t\t\t// sees one DATA, the harness's \"one emission per wave\" contract is\n\t\t\t// honored. Earlier attempts using a derived node leaked\n\t\t\t// transient nulls via the derived's first-run gate.\n\t\t\treturn node<T | null>(\n\t\t\t\t(_data, actions) => {\n\t\t\t\t\tlet done = false;\n\t\t\t\t\tlet cancelled = false;\n\t\t\t\t\tlet abortDispose: (() => void) | undefined;\n\n\t\t\t\t\tconst invokeOpts: LLMInvokeOptions = {\n\t\t\t\t\t\tmodel: opts?.model,\n\t\t\t\t\t\ttemperature: opts?.temperature,\n\t\t\t\t\t\tmaxTokens: opts?.maxTokens,\n\t\t\t\t\t\tsystemPrompt: opts?.systemPrompt,\n\t\t\t\t\t\t...(tools !== undefined ? { tools } : {}),\n\t\t\t\t\t};\n\t\t\t\t\tif (opts?.abort) {\n\t\t\t\t\t\tconst sig = nodeSignal(opts.abort);\n\t\t\t\t\t\tinvokeOpts.signal = sig.signal;\n\t\t\t\t\t\tabortDispose = sig.dispose;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet invokeResult: NodeInput<LLMResponse>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tinvokeResult = adapter.invoke(msgs, invokeOpts);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\tactions.down([[ERROR, err]]);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst callNode = fromAny(invokeResult);\n\n\t\t\t\t\tconst sub = callNode.subscribe((batch) => {\n\t\t\t\t\t\tif (cancelled || done) return;\n\t\t\t\t\t\tfor (const msg of batch) {\n\t\t\t\t\t\t\t// F-11: re-check `cancelled` (and `done`) at the top of\n\t\t\t\t\t\t\t// each per-message iteration so a teardown / abort that\n\t\t\t\t\t\t\t// fires synchronously between messages stops processing\n\t\t\t\t\t\t\t// further batched messages immediately.\n\t\t\t\t\t\t\tif (cancelled || done) return;\n\t\t\t\t\t\t\tif (msg[0] === DATA) {\n\t\t\t\t\t\t\t\tconst resp = msg[1] as LLMResponse;\n\t\t\t\t\t\t\t\t// `format: \"raw\"` bypasses parsing — emit the full\n\t\t\t\t\t\t\t\t// LLMResponse object (subsumes the pre-Tier-2.3 `fromLLM`\n\t\t\t\t\t\t\t\t// output shape).\n\t\t\t\t\t\t\t\tif (format === \"raw\") {\n\t\t\t\t\t\t\t\t\tactions.emit(resp as unknown as T);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// F-12: cache the extracted content once on the\n\t\t\t\t\t\t\t\t\t// parse-failure path so we don't call\n\t\t\t\t\t\t\t\t\t// `extractContent(resp)` twice (once for parsing,\n\t\t\t\t\t\t\t\t\t// once for the error-message preview).\n\t\t\t\t\t\t\t\t\tlet content: string;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tcontent = extractContent(resp);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\t// extractContent itself failed — propagate as\n\t\t\t\t\t\t\t\t\t\t// an ERROR with a generic raw-extraction message.\n\t\t\t\t\t\t\t\t\t\tconst wrapped = new Error(\n\t\t\t\t\t\t\t\t\t\t\t`promptNode: failed to extract content from LLM response: ${\n\t\t\t\t\t\t\t\t\t\t\t\t(err as Error).message\n\t\t\t\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal-error\n\t\t\t\t\t\t\t\t\t\t// branches so we don't retain the AbortController\n\t\t\t\t\t\t\t\t\t\t// after the wave terminates. Idempotent.\n\t\t\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\t\t\tactions.down([[ERROR, wrapped]]);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tconst parsed: T =\n\t\t\t\t\t\t\t\t\t\t\tformat === \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t? (JSON.parse(stripFences(content)) as T)\n\t\t\t\t\t\t\t\t\t\t\t\t: (content as unknown as T);\n\t\t\t\t\t\t\t\t\t\tactions.emit(parsed);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\tconst wrapped = new Error(\n\t\t\t\t\t\t\t\t\t\t\t`promptNode: failed to parse LLM response as JSON: ${\n\t\t\t\t\t\t\t\t\t\t\t\t(err as Error).message\n\t\t\t\t\t\t\t\t\t\t\t}\\n Raw content (first 200 chars): ${previewContent(content)}`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t// F-7: dispose abort hook on parse-error\n\t\t\t\t\t\t\t\t\t\t// terminal branch.\n\t\t\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\t\t\tactions.down([[ERROR, wrapped]]);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (msg[0] === ERROR) {\n\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal ERROR branch.\n\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\tactions.down([[ERROR, msg[1]]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} else if (msg[0] === COMPLETE) {\n\t\t\t\t\t\t\t\t// Adapter completed — propagate. emit() above already\n\t\t\t\t\t\t\t\t// queued the parsed value so the wave carries DATA + COMPLETE.\n\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal COMPLETE branch.\n\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\tactions.down([[COMPLETE]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Spec §1.3.6 forward-unknown — DIRTY/RESOLVED/INVALIDATE/\n\t\t\t\t\t\t\t\t// PAUSE/RESUME etc. should propagate so downstream caches /\n\t\t\t\t\t\t\t\t// flow-control hooks aren't starved. Re-typed `as never`\n\t\t\t\t\t\t\t\t// because the call's NodeInput<LLMResponse> message tuple\n\t\t\t\t\t\t\t\t// is wider than the unbound `T` projection.\n\t\t\t\t\t\t\t\tactions.down([msg as never]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\tcancelled = true;\n\t\t\t\t\t\t\tsub();\n\t\t\t\t\t\t\t// F-7: cleanup callback's abortDispose call is idempotent —\n\t\t\t\t\t\t\t// the terminal-branch dispose above sets `abortDispose =\n\t\t\t\t\t\t\t// undefined` so this is a no-op when terminal-fired.\n\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdescribeKind: \"producer\",\n\t\t\t\t\tname: `${baseName}::response`,\n\t\t\t\t\tmeta: aiMeta(\"prompt_node::response\"),\n\t\t\t\t},\n\t\t\t) as NodeInput<T | null>;\n\t\t},\n\t\t{\n\t\t\tname: `${baseName}::output`,\n\t\t\tmeta: opts?.meta\n\t\t\t\t? { ...aiMeta(\"prompt_node::output\"), ...opts.meta }\n\t\t\t\t: aiMeta(\"prompt_node::output\"),\n\t\t},\n\t);\n\n\treturn result;\n}\n","/**\n * PipelineGraph subclass (Wave A.1 Unit 1 — locked 2026-04-24).\n *\n * Specialized {@link Graph} that hosts workflow-DAG sugar methods:\n * `task` / `classify` / `combine` / `approval` / `approvalGate` / `catch`.\n * The legacy `pipeline` / `task` / `branch` / `join` / `subPipeline` /\n * `approval` / `loop` / `onFailure` factories from {@link ./index} continue\n * to work for migration ease; new code should prefer methods on this class.\n *\n * **Tier 2.3 rename:** the prior `gate(...)` method is now `approvalGate(...)`,\n * disambiguating it from the other gate-family primitives (`budgetGate` for\n * numeric constraints, `valve` for boolean switching, `policyGate` for ABAC\n * rules). The \"gating dimension\" here is **human judgment**.\n *\n * Construction: `pipelineGraph(name, opts?)` or `new PipelineGraph(name, opts)`.\n */\n\nimport type { NodeActions } from \"@graphrefly/pure-ts/core\";\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tplaceholderArgs,\n\tRESOLVED,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport type { ReactiveLogBundle } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport { type BaseAuditRecord, createAuditLog, mutate } from \"../../base/mutation/index.js\";\n\nexport type StepRef = string | Node<unknown>;\n\nfunction meta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"orchestration\", kind, extra);\n}\n\n// ── Decision audit record (Audit 2 + Wave A.2 Unit 8) ─────────────────────\n\nexport type DecisionAction =\n\t| \"approve\"\n\t| \"reject\"\n\t| \"modify\"\n\t| \"drop\"\n\t| \"open\"\n\t| \"close\"\n\t| \"teardown\";\n\nexport interface Decision<T = unknown> extends BaseAuditRecord {\n\treadonly action: DecisionAction;\n\treadonly count?: number;\n\treadonly items?: readonly T[];\n\treadonly unflushed?: number;\n}\n\n/** Recommended `keyOf` for keyed-storage adapters (Audit 2 #7). */\nexport const decisionKeyOf = <T>(d: Decision<T>): string => d.action;\n\n// ── Gate ─────────────────────────────────────────────────────────────────\n\nexport interface GateOptions<_T = unknown> {\n\t/** Bounded default 1000 (Audit 2 cross-cutting). `Infinity` is opt-in. */\n\tmaxPending?: number;\n\tstartOpen?: boolean;\n\t/**\n\t * Reactive auto-approve: gate's `latestIsOpen` mirrors this node's truthy\n\t * value. False→true transition drains the pending queue.\n\t *\n\t * **`COMPLETE` / `ERROR` on the approver are silently ignored** — the gate\n\t * stays in its current state. For permanent-open latching, use\n\t * `onceOnly: true` (the first truthy approval latches; subsequent falsy\n\t * values are ignored). The gate has no graceful terminal-state behavior\n\t * for the approver itself.\n\t */\n\tapprover?: Node<unknown>;\n\t/** Latch — first truthy approval opens permanently; `close()` becomes no-op. */\n\tonceOnly?: boolean;\n\tmeta?: Record<string, unknown>;\n\thandlerVersion?: { id: string; version: string | number };\n}\n\nexport interface GateController<T> {\n\t/**\n\t * The post-gate output node. Renamed from `node` (Tier 5.2 / EC6,\n\t * 2026-04-29) to avoid shadowing `Graph.node(name)` when a gate is\n\t * accessed off a `PipelineGraph` instance.\n\t */\n\treadonly output: Node<T>;\n\treadonly pending: Node<readonly T[]>;\n\treadonly count: Node<number>;\n\treadonly isOpen: Node<boolean>;\n\treadonly droppedCount: Node<number>;\n\treadonly decisions: ReactiveLogBundle<Decision<T>>;\n\treadonly audit: ReactiveLogBundle<Decision<T>>;\n\tapprove(count?: number): void;\n\treject(count?: number): void;\n\tmodify(fn: (value: T, index: number, pending: readonly T[]) => T, count?: number): void;\n\topen(): void;\n\tclose(): void;\n}\n\n// ── catch (rename of onFailure; Wave A.2 Unit 10) ─────────────────────────\n\n/**\n * Terminal-cause discriminator for the {@link PipelineGraph.catch} recovery\n * handler. Tier 1.6.3 status-enum migration: was `{ kind: \"complete\" | \"error\" }`\n * pre-1.0; aligned with the canonical lifecycle enum\n * (`status: \"running\" | \"completed\" | \"errored\" | \"cancelled\"`). The variant\n * structure is preserved — `errored` still carries `error: unknown` and\n * `completed` carries no payload.\n */\nexport type TerminalCause = { kind: \"errored\"; error: unknown } | { kind: \"completed\" };\n\nexport interface CatchOptions<_T> {\n\t/**\n\t * Which terminal cause to recover. Default `\"errored\"` (Tier 1.6.3 rename\n\t * of `\"error\"`). `\"completed\"` recovers COMPLETE; `\"terminal\"` recovers\n\t * either. Aligns with the canonical lifecycle enum that\n\t * {@link TerminalCause.kind} now uses.\n\t */\n\ton?: \"errored\" | \"completed\" | \"terminal\";\n\tcompleteWhenDepsComplete?: boolean;\n\tmeta?: Record<string, unknown>;\n\thandlerVersion?: { id: string; version: string | number };\n}\n\n// ── classify result envelope (Wave A.1 Unit 3) ───────────────────────────\n\nexport interface ClassifyResult<TTag extends string, T> {\n\treadonly tag: TTag | \"error\";\n\treadonly value: T;\n\treadonly error?: unknown;\n}\n\n// ── PipelineGraph ────────────────────────────────────────────────────────\n\nexport class PipelineGraph extends Graph {\n\t// -- task -----------------------------------------------------------------\n\n\t/**\n\t * Register a workflow task (`node` + auto-add). String deps resolve via\n\t * `this.resolve(path)`; Node deps via {@link Graph.nameOf} O(1) lookup.\n\t *\n\t * `run` receives `(data: readonly unknown[], ctx)` — the snapshot of latest\n\t * values per dep (same shape as the old `DerivedFn` sugar).\n\t */\n\ttask<T>(\n\t\tname: string,\n\t\trun: (data: readonly unknown[], ctx: { prevData: readonly unknown[] }) => T | undefined | null,\n\t\topts: { deps?: ReadonlyArray<StepRef>; meta?: Record<string, unknown> } = {},\n\t): Node<T> {\n\t\tconst deps = (opts.deps ?? []).map((d) => this._resolveStep(d));\n\t\tconst step = node<T>(\n\t\t\tdeps,\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst result = run(data, ctx);\n\t\t\t\tif (result !== undefined && result !== null) actions.emit(result);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: meta(\"task\", opts.meta),\n\t\t\t} as NodeOptions<T>,\n\t\t);\n\t\tthis.add(step, { name });\n\t\treturn step;\n\t}\n\n\t// -- classify (n-way; replaces binary `branch`) --------------------------\n\n\tclassify<TTag extends string, T>(\n\t\tname: string,\n\t\tsource: StepRef,\n\t\ttagger: (value: T) => TTag,\n\t\topts: { meta?: Record<string, unknown> } = {},\n\t): Node<ClassifyResult<TTag, T>> {\n\t\tconst src = this._resolveStep(source);\n\t\tconst step = node<ClassifyResult<TTag, T>>(\n\t\t\t[src],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst value = data[0];\n\t\t\t\ttry {\n\t\t\t\t\tactions.emit({ tag: tagger(value as T), value: value as T });\n\t\t\t\t} catch (error) {\n\t\t\t\t\tactions.emit({ tag: \"error\" as const, value: value as T, error });\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: meta(\"classify\", opts.meta),\n\t\t\t} as NodeOptions<ClassifyResult<TTag, T>>,\n\t\t);\n\t\tthis.add(step, { name });\n\t\treturn step;\n\t}\n\n\t// -- combine (keyed-record fan-in; replaces positional `join`) -----------\n\n\tcombine<R extends Record<string, StepRef>>(\n\t\tname: string,\n\t\tdeps: R,\n\t\topts: { meta?: Record<string, unknown> } = {},\n\t): Node<{ [K in keyof R]: unknown }> {\n\t\tconst keys = Object.keys(deps) as Array<keyof R & string>;\n\t\tconst nodes = keys.map((k) => this._resolveStep(deps[k] as StepRef));\n\t\tconst step = node<{ [K in keyof R]: unknown }>(\n\t\t\tnodes,\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst values = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst out = {} as { [K in keyof R]: unknown };\n\t\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\t\t(out as Record<string, unknown>)[keys[i] as string] = values[i];\n\t\t\t\t}\n\t\t\t\tactions.emit(out);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: meta(\"combine\", opts.meta),\n\t\t\t} as NodeOptions<{ [K in keyof R]: unknown }>,\n\t\t);\n\t\tthis.add(step, { name });\n\t\treturn step;\n\t}\n\n\t// -- approvalGate ---------------------------------------------------------\n\n\tapprovalGate<T>(name: string, source: StepRef, opts: GateOptions<T> = {}): GateController<T> {\n\t\tconst maxPending = opts.maxPending ?? 1000;\n\t\tif (maxPending < 1 && maxPending !== Number.POSITIVE_INFINITY) {\n\t\t\tthrow new RangeError(\"approvalGate: maxPending must be >= 1\");\n\t\t}\n\t\tconst startOpen = opts.startOpen ?? false;\n\n\t\t// C3 — wrap a foreign Node source in a local proxy derived. The proxy\n\t\t// is owned by THIS graph; downstream wiring uses the proxy (not the\n\t\t// foreign Node) so the cross-graph ownership invariant holds. Causal\n\t\t// chain is preserved via the dep edge — `describe()` still surfaces\n\t\t// the foreign Node's path through the proxy.\n\t\tlet src: Node<unknown>;\n\t\tif (typeof source === \"string\") {\n\t\t\tsrc = this._resolveStep(source);\n\t\t} else if (this.nameOf(source) !== undefined) {\n\t\t\tsrc = source;\n\t\t} else {\n\t\t\tconst proxy = node<unknown>(\n\t\t\t\t[source],\n\t\t\t\t(batchData, actions) => {\n\t\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\t\tif (batch0 == null || batch0.length === 0) return;\n\t\t\t\t\tfor (const v of batch0) actions.emit(v);\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\t\tmeta: factoryTag(\"proxy\"),\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.add(proxy, { name: `${name}/source` });\n\t\t\tsrc = proxy;\n\t\t}\n\n\t\t// State subgraph\n\t\tconst internal = new Graph(`${name}-state`);\n\t\tconst pendingNode = internal.state<readonly T[]>(\"pending\", [], {\n\t\t\tequals: () => false,\n\t\t});\n\t\tconst isOpenNode = internal.state<boolean>(\"isOpen\", startOpen);\n\t\tconst countNode = internal.derived<number>(\"count\", [\"pending\"], (batchData, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\treturn [(data[0] as readonly T[]).length];\n\t\t});\n\t\tconst droppedCountNode = internal.state<number>(\"droppedCount\", 0);\n\t\tconst decisions = createAuditLog<Decision<T>>({\n\t\t\tname: \"decisions\",\n\t\t\tretainedLimit: 1024,\n\t\t\tgraph: internal,\n\t\t});\n\t\tthis.mount(`${name}-state`, internal);\n\n\t\tlet queue: T[] = [];\n\t\tlet torn = false;\n\t\tlet latched = false;\n\t\t// Closure-mirror per COMPOSITION-GUIDE §28 factory-time seed pattern.\n\t\t// `output` samples `latestIsOpen` inside its fn body when deciding\n\t\t// emit-vs-enqueue; reading a closure variable is NOT a P3 violation\n\t\t// (§28). An in-session Phase 9 plan would have relocated the value to\n\t\t// `internal.derived(\"latestIsOpen\", ...)` + `.cache` reads (which IS\n\t\t// a P3 violation); plan was reverted at the design level after\n\t\t// re-reading §28 — pattern preserved here. See `archive/docs/SESSION-\n\t\t// graph-narrow-waist.md` § \"Status of existing modifications\".\n\t\tlet latestIsOpen = startOpen;\n\t\tconst isOpenUnsub = isOpenNode.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) latestIsOpen = m[1] as boolean;\n\t\t\t}\n\t\t});\n\t\tthis.addDisposer(isOpenUnsub);\n\n\t\tfunction syncPending(): void {\n\t\t\tpendingNode.emit([...queue]);\n\t\t}\n\n\t\tfunction recordDecision(\n\t\t\taction: DecisionAction,\n\t\t\titems?: readonly T[],\n\t\t\tunflushed?: number,\n\t\t): void {\n\t\t\tdecisions.append({\n\t\t\t\taction,\n\t\t\t\tt_ns: wallClockNs(),\n\t\t\t\t...(items !== undefined ? { items, count: items.length } : {}),\n\t\t\t\t...(unflushed !== undefined ? { unflushed } : {}),\n\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t} as Decision<T>);\n\t\t}\n\n\t\tfunction enqueue(value: T): void {\n\t\t\tqueue.push(value);\n\t\t\tif (queue.length > maxPending) {\n\t\t\t\tconst dropped = queue.shift() as T;\n\t\t\t\tdroppedCountNode.emit((droppedCountNode.cache as number) + 1);\n\t\t\t\trecordDecision(\"drop\", [dropped]);\n\t\t\t}\n\t\t\tsyncPending();\n\t\t}\n\n\t\tfunction dequeue(n: number): T[] {\n\t\t\tconst items = queue.splice(0, n);\n\t\t\tsyncPending();\n\t\t\treturn items;\n\t\t}\n\n\t\tconst output = node<T>(\n\t\t\t[src],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst terminal = ctx.terminalDeps[0];\n\t\t\t\tif (terminal !== undefined) {\n\t\t\t\t\ttorn = true;\n\t\t\t\t\tconst unflushed = queue.length;\n\t\t\t\t\tqueue = [];\n\t\t\t\t\tsyncPending();\n\t\t\t\t\trecordDecision(\"teardown\", undefined, unflushed);\n\t\t\t\t\tactions.down(terminal === true ? [[COMPLETE]] : [[ERROR, terminal]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0 as T[]) {\n\t\t\t\t\tif (latestIsOpen) {\n\t\t\t\t\t\tactions.emit(v);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tenqueue(v);\n\t\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: meta(\"approval_gate\", opts.meta),\n\t\t\t},\n\t\t);\n\t\tthis.add(output, { name });\n\n\t\t// Reactive approver mode: mirror latestIsOpen to the approver's value.\n\t\t// **m1:** approver `COMPLETE` / `ERROR` are silently ignored — gate stays\n\t\t// in current state. For latching behavior, use `onceOnly: true`.\n\t\tif (opts.approver != null) {\n\t\t\tconst initialApproved = Boolean(opts.approver.cache);\n\t\t\tif (initialApproved) {\n\t\t\t\tisOpenNode.emit(true);\n\t\t\t\tlatestIsOpen = true;\n\t\t\t\tif (opts.onceOnly) latched = true;\n\t\t\t}\n\t\t\tconst approverSub = opts.approver.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\tconst truthy = Boolean(m[1]);\n\t\t\t\t\tif (truthy && !latestIsOpen) {\n\t\t\t\t\t\t// false → true transition\n\t\t\t\t\t\tif (opts.onceOnly) {\n\t\t\t\t\t\t\tif (latched) continue;\n\t\t\t\t\t\t\tlatched = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tisOpenNode.emit(true);\n\t\t\t\t\t\t\tconst items = dequeue(queue.length);\n\t\t\t\t\t\t\t// M11: include items count in approver-driven open decisions\n\t\t\t\t\t\t\t// so audit consumers see how many items were flushed.\n\t\t\t\t\t\t\trecordDecision(\"open\", items);\n\t\t\t\t\t\t\tfor (const item of items) {\n\t\t\t\t\t\t\t\tif (torn) break;\n\t\t\t\t\t\t\t\toutput.emit(item);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (!truthy && latestIsOpen) {\n\t\t\t\t\t\tif (opts.onceOnly && latched) continue;\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tisOpenNode.emit(false);\n\t\t\t\t\t\t\trecordDecision(\"close\");\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.addDisposer(approverSub);\n\t\t}\n\n\t\tconst guardTorn = (method: string): void => {\n\t\t\tif (torn) throw new Error(`approvalGate: ${method}() called after the gate was torn down`);\n\t\t};\n\n\t\tconst approveImpl = (count = 1): void => {\n\t\t\tguardTorn(\"approve\");\n\t\t\tconst items = dequeue(count);\n\t\t\tfor (const item of items) {\n\t\t\t\tif (torn) break;\n\t\t\t\toutput.emit(item);\n\t\t\t}\n\t\t};\n\t\tconst rejectImpl = (count = 1): void => {\n\t\t\tguardTorn(\"reject\");\n\t\t\tdequeue(count);\n\t\t};\n\t\tconst modifyImpl = (\n\t\t\tfn: (value: T, index: number, pending: readonly T[]) => T,\n\t\t\tcount = 1,\n\t\t): void => {\n\t\t\tguardTorn(\"modify\");\n\t\t\tconst snapshot = [...queue] as readonly T[];\n\t\t\tconst items = dequeue(count);\n\t\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\t\tif (torn) break;\n\t\t\t\toutput.emit(fn(items[i], i, snapshot));\n\t\t\t}\n\t\t};\n\t\tconst openImpl = (): void => {\n\t\t\tguardTorn(\"open\");\n\t\t\tisOpenNode.emit(true);\n\t\t\tconst items = dequeue(queue.length);\n\t\t\tfor (const item of items) {\n\t\t\t\tif (torn) break;\n\t\t\t\toutput.emit(item);\n\t\t\t}\n\t\t};\n\t\tconst closeImpl = (): void => {\n\t\t\tguardTorn(\"close\");\n\t\t\tif (opts.onceOnly && latched) return;\n\t\t\tisOpenNode.emit(false);\n\t\t};\n\n\t\tconst approve = mutate(approveImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (args, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"approve\",\n\t\t\t\t\tcount: (args[0] as number | undefined) ?? 1,\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\t\tconst reject = mutate(rejectImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (args, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"reject\",\n\t\t\t\t\tcount: (args[0] as number | undefined) ?? 1,\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\t\tconst modify = mutate(modifyImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (args, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"modify\",\n\t\t\t\t\tcount: (args[1] as number | undefined) ?? 1,\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\t\tconst open = mutate(openImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (_a, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"open\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\t\tconst close = mutate(closeImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (_a, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"close\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\n\t\tthis.addDisposer(countNode.subscribe(() => undefined));\n\n\t\tconst controller: GateController<T> = {\n\t\t\toutput,\n\t\t\tpending: pendingNode,\n\t\t\tcount: countNode,\n\t\t\tisOpen: isOpenNode,\n\t\t\tdroppedCount: droppedCountNode,\n\t\t\tdecisions,\n\t\t\taudit: decisions,\n\t\t\tapprove,\n\t\t\treject,\n\t\t\tmodify,\n\t\t\topen,\n\t\t\tclose,\n\t\t};\n\t\treturn controller;\n\t}\n\n\t// -- approval (thin alias over approvalGate({ approver, maxPending: 1 })) -\n\n\t/**\n\t * Reactive approval step: passes items through when `approver` is truthy;\n\t * holds at most one pending item (maxPending: 1) when falsy. A thin alias\n\t * over `approvalGate({ approver, maxPending: 1 })` — use `approvalGate()`\n\t * directly for finer control (maxPending, onceOnly, manual approve/reject).\n\t */\n\tapproval<T>(\n\t\tname: string,\n\t\tsource: StepRef,\n\t\tapprover: Node<unknown>,\n\t\topts: Omit<GateOptions<T>, \"approver\" | \"maxPending\"> = {},\n\t): GateController<T> {\n\t\treturn this.approvalGate<T>(name, source, { ...opts, approver, maxPending: 1 });\n\t}\n\n\t// -- catch (renamed onFailure; dep-channel intercept) -------------------\n\n\tcatch<T>(\n\t\tname: string,\n\t\tsource: StepRef,\n\t\trecover: (cause: TerminalCause, actions: NodeActions) => T,\n\t\topts: CatchOptions<T> = {},\n\t): Node<T> {\n\t\tconst src = this._resolveStep(source);\n\t\tconst mode = opts.on ?? \"errored\";\n\t\tconst step = node<T>(\n\t\t\t[src],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst terminal = ctx.terminalDeps[0];\n\t\t\t\tif (terminal !== undefined) {\n\t\t\t\t\tconst cause: TerminalCause =\n\t\t\t\t\t\tterminal === true ? { kind: \"completed\" } : { kind: \"errored\", error: terminal };\n\t\t\t\t\tif (mode === \"terminal\" || mode === cause.kind) {\n\t\t\t\t\t\tactions.emit(recover(cause, actions));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tactions.down(cause.kind === \"completed\" ? [[COMPLETE]] : [[ERROR, cause.error]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0 as T[]) actions.emit(v);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tcompleteWhenDepsComplete:\n\t\t\t\t\topts.completeWhenDepsComplete ?? !(mode === \"completed\" || mode === \"terminal\"),\n\t\t\t\terrorWhenDepsError: !(mode === \"errored\" || mode === \"terminal\"),\n\t\t\t\tmeta: meta(\"catch\", opts.meta),\n\t\t\t} as NodeOptions<T>,\n\t\t);\n\t\tthis.add(step, { name });\n\t\treturn step;\n\t}\n\n\t// -- internals ----------------------------------------------------------\n\n\tprivate _resolveStep(dep: StepRef): Node<unknown> {\n\t\tif (typeof dep === \"string\") return this.resolve(dep);\n\t\tconst existing = this.nameOf(dep);\n\t\tif (existing === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`PipelineGraph \"${this.name}\": Node dep is not registered. Pass a string path or call graph.add(node) first.`,\n\t\t\t);\n\t\t}\n\t\treturn dep;\n\t}\n}\n\n/** Factory wrapper — `pipelineGraph(name, opts?)`. Equivalent to `new PipelineGraph(name, opts)`. */\nexport function pipelineGraph(name: string, opts?: GraphOptions): PipelineGraph {\n\tconst g = new PipelineGraph(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` exposes provenance. `factoryArgs` is the\n\t// constructor opts (sans the `factory`/`factoryArgs` keys themselves to\n\t// avoid recursive nesting). QA F13: route through `placeholderArgs` for\n\t// consistency with sibling factories — `GraphOptions[key: string]: unknown`\n\t// is open-ended, so user-extension keys may carry non-JSON content.\n\tconst { factory: _f, factoryArgs: _fa, ...tagArgs } = (opts ?? {}) as Record<string, unknown>;\n\tg.tagFactory(\"pipelineGraph\", placeholderArgs(tagArgs));\n\treturn g;\n}\n","import { type Node, node, RESOLVED } from \"@graphrefly/pure-ts/core\";\nimport { keepalive, type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../_internal.js\";\nimport type { ChatMessage } from \"../adapters/core/types.js\";\n\n// ---------------------------------------------------------------------------\n// chatStream\n// ---------------------------------------------------------------------------\n\nexport type ChatStreamOptions = {\n\tgraph?: GraphOptions;\n\tmaxMessages?: number;\n};\n\nexport class ChatStreamGraph extends Graph {\n\tprivate readonly _log: ReactiveLogBundle<ChatMessage>;\n\treadonly messages: Node<readonly ChatMessage[]>;\n\t/**\n\t * Most recently appended message. Stays in the protocol SENTINEL state\n\t * (`cache === undefined`, no DATA emitted) until the first append, then\n\t * tracks the latest entry. Per COMPOSITION-GUIDE §1a, the SENTINEL is\n\t * the canonical \"no value yet\" signal — consumers detect empty via\n\t * `data[i] === undefined` inside reactive fns or `latest.cache === undefined`\n\t * outside. No `T | null` placeholder, no `hasLatest` companion.\n\t */\n\treadonly latest: Node<ChatMessage>;\n\treadonly messageCount: Node<number>;\n\n\tconstructor(name: string, opts: ChatStreamOptions = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\tthis._log = reactiveLog<ChatMessage>([], {\n\t\t\tname: \"messages\",\n\t\t\tmaxSize: opts.maxMessages,\n\t\t});\n\t\tthis.messages = this._log.entries;\n\t\tthis.add(this.messages, { name: \"messages\" });\n\n\t\t// SENTINEL on empty (COMPOSITION-GUIDE §1a): return `[]` for\n\t\t// RESOLVED-only on empty stream, `[T]` to emit DATA. `latest.cache`\n\t\t// stays `undefined` until the first append.\n\t\tthis.latest = node<ChatMessage>(\n\t\t\t[this.messages],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst entries = data[0] as readonly ChatMessage[];\n\t\t\t\tif (entries.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit(entries[entries.length - 1] as ChatMessage);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"latest\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"chat_latest\"),\n\t\t\t},\n\t\t);\n\t\tthis.add(this.latest, { name: \"latest\" });\n\t\tthis.addDisposer(keepalive(this.latest));\n\n\t\tthis.messageCount = node<number>(\n\t\t\t[this.messages],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly ChatMessage[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"messageCount\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"chat_message_count\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.messageCount, { name: \"messageCount\" });\n\t\tthis.addDisposer(keepalive(this.messageCount));\n\t}\n\n\tappend(role: ChatMessage[\"role\"], content: string, extra?: Partial<ChatMessage>): void {\n\t\tthis._log.append({ role, content, ...extra });\n\t}\n\n\tappendToolResult(callId: string, content: string): void {\n\t\tthis._log.append({ role: \"tool\", content, toolCallId: callId });\n\t}\n\n\tclear(): void {\n\t\tthis._log.clear();\n\t}\n\n\tallMessages(): readonly ChatMessage[] {\n\t\treturn this.messages.cache as readonly ChatMessage[];\n\t}\n}\n\nexport function chatStream(name: string, opts?: ChatStreamOptions): ChatStreamGraph {\n\treturn new ChatStreamGraph(name, opts);\n}\n","/**\n * `toolExecution` — reactive per-tool-call executor with retry + rescue.\n *\n * Lifted from the inlined `executeToolReactively` helper inside `agent-loop.ts`\n * so it can be consumed standalone by any caller with a reactive `toolCalls`\n * batch — not just `agentLoop`. The shape is: one input `Node<readonly\n * ToolCall[]>` + a `ToolRegistryGraph` → one output `Node<readonly\n * ToolResult[]>`. Each call maps to a per-call `retrySource(executeReactive)`\n * → optional `rescue` chain that emits the handler result on success, or a\n * JSON-wrapped `{ error }` payload on terminal failure so the LLM can see the\n * error as tool output and decide whether to try again via another tool call.\n *\n * **Cancellation.** `executeReactive` mints a per-call `AbortController` and\n * threads its signal into the handler call. When `switchMap` supersedes the\n * inner (a fresh `toolCalls` batch arrives) or the outer graph tears down,\n * the per-call node unsubscribes and `ac.abort()` fires. Signal-aware\n * handlers (`fetch(url, {signal})`, child-process kill, DB cancel) actually\n * stop in-flight work; handlers that ignore the signal still complete to\n * their original termination, but their result is discarded.\n *\n * @module\n */\n\nimport { type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { rescue, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { retry } from \"../../../base/resilience/retry.js\";\nimport type { ToolCall } from \"../adapters/core/types.js\";\nimport type { ToolRegistryGraph } from \"./tool-registry.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A single tool execution outcome: `{id, content}` where content is a JSON string. */\nexport interface ToolResult {\n\treadonly id: string;\n\treadonly content: string;\n}\n\nexport type ToolExecutionOptions = {\n\t/**\n\t * Reactive tool-call batch. Each non-empty emission triggers a fresh\n\t * per-call execution fan-out; superseding emissions cancel the prior fan.\n\t */\n\ttoolCalls: Node<readonly ToolCall[]>;\n\t/** Registry that resolves tool name → handler. */\n\ttools: ToolRegistryGraph;\n\t/**\n\t * Retry count per individual tool call. `retrySource({count: N})` retries\n\t * up to N times on error (N retries = N+1 total attempts). Default: 1.\n\t */\n\tretryCount?: number;\n\t/**\n\t * How to surface a terminal error after retries are exhausted.\n\t * - `\"rescue\"` (default): emit `{id, content: JSON.stringify({error})}`\n\t * so the LLM sees the failure as structured tool output and can decide\n\t * how to react. Sibling calls in the same batch continue to their own\n\t * completion; one call's failure does not affect the others.\n\t * - `\"propagate\"`: let the ERROR propagate downstream. **Blast radius:**\n\t * the per-batch `derived` join auto-errors when any per-call node\n\t * terminates with ERROR, so one call's failure discards every sibling's\n\t * DATA (even ones that already settled with a valid ToolResult). Use\n\t * `\"propagate\"` only when a single tool failure should be fatal for the\n\t * whole batch; prefer `\"rescue\"` when you want the LLM to see partial\n\t * results plus per-call error markers.\n\t */\n\tonError?: \"rescue\" | \"propagate\";\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Reactive executor for a batch of LLM tool calls.\n *\n * Each DATA emission on `toolCalls` dispatches a fresh per-call fan-out: for\n * every call in the batch, construct a `retrySource(fromAny(tools.execute(\n * name, args)))` node, optionally `rescue` it into a JSON error shape, and\n * join the results via a `derived` whose first-run gate waits for every call\n * to settle before emitting the batch. Empty batches (`calls.length === 0`)\n * are a caller-side invariant violation (the upstream gate should emit\n * RESOLVED for empty batches, not DATA) and trigger a loud error — callers\n * that want to accept empty batches should upstream-filter them first.\n *\n * Reference-equality + content-equality dedup is applied to the output batch\n * so duplicate re-emissions from a completing retrySource don't propagate.\n *\n * @param opts - `{ toolCalls, tools, retryCount?, onError? }`.\n * @returns `Node<readonly ToolResult[]>` — one ToolResult per input ToolCall.\n */\nexport function toolExecution(opts: ToolExecutionOptions): Node<readonly ToolResult[]> {\n\tconst { toolCalls, tools } = opts;\n\tconst retryCount = opts.retryCount ?? 1;\n\tconst onError = opts.onError ?? \"rescue\";\n\n\tconst batchEquals = (a: readonly ToolResult[], b: readonly ToolResult[]): boolean => {\n\t\tif (a === b) return true;\n\t\tif (a.length !== b.length) return false;\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tconst ai = a[i];\n\t\t\tconst bi = b[i];\n\t\t\tif (ai?.id !== bi?.id) return false;\n\t\t\tif (ai?.content !== bi?.content) return false;\n\t\t}\n\t\treturn true;\n\t};\n\n\treturn switchMap<readonly ToolCall[], readonly ToolResult[]>(toolCalls, (calls) => {\n\t\tif (calls == null || calls.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"toolExecution: received an empty tool-call batch as DATA — callers must upstream-filter empty batches (emit RESOLVED) so switchMap is only dispatched for non-empty batches.\",\n\t\t\t);\n\t\t}\n\t\tconst perCall = calls.map((call) => executeOne(call, tools, retryCount, onError));\n\t\t// `executeOne` returns `Node<ToolResult>` in both \"rescue\" and\n\t\t// \"propagate\" modes (the rescue handler builds a `ToolResult`\n\t\t// shape; the success `derived` builds one directly). The join\n\t\t// just forwards the per-call values — no shape coercion needed.\n\t\treturn node(\n\t\t\tperCall,\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(data as readonly ToolResult[]);\n\t\t\t},\n\t\t\t{ describeKind: \"derived\", name: \"toolExecution::batch\", equals: batchEquals },\n\t\t);\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\n/**\n * Per-call reactive executor. `retrySource` re-invokes the factory on ERROR\n * (each attempt mints a fresh `executeReactive` node, which in turn mints a\n * fresh `AbortController` and handler invocation). `executeReactive` itself\n * handles synchronous handler throws — they surface as `[[ERROR, err]]`\n * inside the producer, so `retrySource`'s reactive ERROR path fires\n * consistently regardless of handler shape. No `Promise.resolve().then(...)`\n * thunk needed — the reactive path is end-to-end.\n *\n * Handlers that return a plain string are surfaced as-is; anything else is\n * `JSON.stringify`'d so LLMs that parse tool results can roundtrip\n * structured data without surprise quoting.\n */\nfunction executeOne(\n\tcall: ToolCall,\n\ttools: ToolRegistryGraph,\n\tretryCount: number,\n\tonError: \"rescue\" | \"propagate\",\n): Node<ToolResult> {\n\tconst attempted: Node<unknown> = retry(() => tools.executeReactive(call.name, call.arguments), {\n\t\tcount: retryCount,\n\t}).node;\n\tconst onSuccess = node<ToolResult>(\n\t\t[attempted],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst val = data[0];\n\t\t\tactions.emit({\n\t\t\t\tid: call.id,\n\t\t\t\tcontent: typeof val === \"string\" ? val : JSON.stringify(val),\n\t\t\t});\n\t\t},\n\t\t{ describeKind: \"derived\" },\n\t);\n\tif (onError === \"propagate\") return onSuccess;\n\treturn rescue(onSuccess, (err) => ({\n\t\tid: call.id,\n\t\tcontent: JSON.stringify({ error: String(err) }),\n\t}));\n}\n","import { ERROR, type Messages, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { fromAsyncIter, fromPromise, keepalive, reactiveMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta, isNodeLike } from \"../_internal.js\";\nimport type { ToolDefinition } from \"../adapters/core/types.js\";\n\n// ---------------------------------------------------------------------------\n// toolRegistry\n// ---------------------------------------------------------------------------\n\nexport type ToolRegistryOptions = {\n\tgraph?: GraphOptions;\n};\n\n/**\n * `ToolRegistryGraph` — name-keyed registry of {@link ToolDefinition}s.\n *\n * **Reactive-only execution.** The only execution path is\n * {@link executeReactive}, which returns a `Node<unknown>` for the handler\n * result. Composing factories (`toolExecution`, `agentLoop`) consume it\n * directly inside `retrySource` / `switchMap` chains. There is intentionally\n * no imperative `execute()` Promise method — the registry was originally a\n * dual-boundary class (imperative + reactive) and the imperative path was\n * the only thing in the codebase bridging through `Promise.resolve().then()`\n * to feed `fromAny`. Removing it left every consumer on a single\n * reactive-all-the-way path with real abort propagation.\n *\n * For non-reactive callers (debug scripts, one-shot tests), bridge with\n * `awaitSettled(toolRegistry.executeReactive(name, args))`.\n *\n * **Wave A Unit 6 refactor:** internal storage migrated from `state<Map>`\n * (O(N) Map-copy per mutation) to `ReactiveMapBundle<string, ToolDefinition>`\n * (O(1) mutations + version counter).\n */\nexport class ToolRegistryGraph extends Graph {\n\treadonly definitions: Node<ReadonlyMap<string, ToolDefinition>>;\n\treadonly schemas: Node<readonly ToolDefinition[]>;\n\tprivate readonly _bundle: ReturnType<typeof reactiveMap<string, ToolDefinition>>;\n\n\tconstructor(name: string, opts: ToolRegistryOptions = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\tthis._bundle = reactiveMap<string, ToolDefinition>({\n\t\t\tname: \"definitions\",\n\t\t});\n\t\tthis.definitions = this._bundle.entries;\n\t\tthis.add(this.definitions, { name: \"definitions\" });\n\n\t\tthis.schemas = node<readonly ToolDefinition[]>(\n\t\t\t[this.definitions],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst defs = data[0];\n\t\t\t\tactions.emit([...((defs ?? new Map()) as ReadonlyMap<string, ToolDefinition>).values()]);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"schemas\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"tool_schemas\"),\n\t\t\t\tinitial: [],\n\t\t\t},\n\t\t);\n\t\tthis.add(this.schemas, { name: \"schemas\" });\n\t\tthis.addDisposer(keepalive(this.schemas));\n\t}\n\n\tregister(tool: ToolDefinition): void {\n\t\tthis._bundle.set(tool.name, tool);\n\t}\n\n\tunregister(name: string): void {\n\t\tthis._bundle.delete(name);\n\t}\n\n\t/**\n\t * Reactive execution — returns a `Node<unknown>` that emits the handler\n\t * result. The returned node is a `producer` that:\n\t *\n\t * 1. Mints a per-call `AbortController` whose `signal` is threaded into\n\t * the handler call AND into `fromAny` (so a `fromPromise` /\n\t * `fromAsyncIter` inner abandons cleanly when the consumer\n\t * unsubscribes).\n\t * 2. Runs `tool.handler(args, {signal})` inside a try/catch — a\n\t * synchronous throw surfaces as `[[ERROR, err]]` downstream instead\n\t * of escaping the producer.\n\t * 3. Forwards every message from the inner `fromAny` chain to the\n\t * producer's outputs.\n\t * 4. On teardown (subscriber count drops to zero, e.g. `switchMap`\n\t * supersede) calls `ac.abort()` and unsubscribes the inner.\n\t * Signal-aware handlers (e.g. `fetch(url, {signal})`) actually stop.\n\t *\n\t * Each call mints a fresh node tied to a fresh `handler(args, ...)`\n\t * invocation — call `executeReactive` again for repeated invocations.\n\t *\n\t * @throws `Error` synchronously when `name` is not registered (no node is\n\t * constructed — the caller gets a pre-wiring failure rather than a\n\t * silent ERROR wave on an empty graph).\n\t */\n\texecuteReactive(name: string, args: Record<string, unknown>): Node<unknown> {\n\t\tconst tool = this._bundle.get(name);\n\t\tif (!tool) throw new Error(`toolRegistry: unknown tool \"${name}\"`);\n\t\treturn node<unknown>(\n\t\t\t[],\n\t\t\t(_data, actions) => {\n\t\t\t\tconst ac = new AbortController();\n\t\t\t\tlet inner: Node<unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tconst raw = tool.handler(args, { signal: ac.signal });\n\t\t\t\t\tinner = handlerResultToNode(raw, ac.signal);\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// Synchronous throw from handler → ERROR. Producer cleanup\n\t\t\t\t\t// still aborts the controller for symmetry (no-op if no\n\t\t\t\t\t// signal listeners attached).\n\t\t\t\t\tactions.down([[ERROR, err]] satisfies Messages);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\tac.abort();\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst unsub = inner.subscribe((batch) => {\n\t\t\t\t\tactions.down(batch as Messages);\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tac.abort();\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: `executeReactive::${name}`,\n\t\t\t\tdescribeKind: \"producer\",\n\t\t\t\tmeta: aiMeta(\"tool_execute_reactive\"),\n\t\t\t},\n\t\t);\n\t}\n\n\tgetDefinition(name: string): ToolDefinition | undefined {\n\t\t// Pure read via the snapshot cache — avoids the bundle's\n\t\t// `wrapMutation` path (which would run the version-bump check and\n\t\t// any configured retention eviction on every lookup). Safe because\n\t\t// `getDefinition` is a boundary API, not a reactive fn body.\n\t\treturn this._bundle.entries.cache?.get(name);\n\t}\n}\n\nexport function toolRegistry(name: string, opts?: ToolRegistryOptions): ToolRegistryGraph {\n\treturn new ToolRegistryGraph(name, opts);\n}\n\n/**\n * Coerce a tool handler return value into a `Node<unknown>`.\n *\n * Differs from `fromAny` by treating **strings, arrays, plain iterables, and\n * scalar objects as single DATA values** rather than iterating them. A tool\n * handler that returns `\"hello world\"` should surface as one `DATA(\"hello\n * world\")`, not 11 `DATA` events of single characters; an array `[1, 2, 3]`\n * should surface as `DATA([1, 2, 3])`, not three separate emissions.\n *\n * Reactive shapes (Node, Promise, AsyncIterable) are unwrapped as expected.\n *\n * @internal\n */\nfunction handlerResultToNode(raw: unknown, signal: AbortSignal): Node<unknown> {\n\tif (isNodeLike(raw)) {\n\t\treturn raw as Node<unknown>;\n\t}\n\tif (raw != null && typeof (raw as PromiseLike<unknown>).then === \"function\") {\n\t\treturn fromPromise(raw as PromiseLike<unknown>, { signal });\n\t}\n\tif (raw != null && typeof raw === \"object\" && Symbol.asyncIterator in (raw as object)) {\n\t\treturn fromAsyncIter(raw as AsyncIterable<unknown>, { signal });\n\t}\n\t// String, number, boolean, null, undefined, plain object, array,\n\t// sync iterable — treat as a single DATA value via a resolved Promise so\n\t// `fromPromise`'s scalar-DATA-emit + COMPLETE semantics match the\n\t// pre-refactor `tools.execute` behavior (which always wrapped via async).\n\treturn fromPromise(Promise.resolve(raw), { signal });\n}\n","/**\n * Pure exponential-decay utility (Tier 2.2 promotion from `patterns/memory/`).\n *\n * Used by `collection`, `agentMemory`, harness `strategy.ts`, and any\n * downstream consumer that needs decay-with-floor scoring. Promoted to\n * `extra/utils/` because the math has zero domain semantics and is reusable\n * by non-memory primitives (e.g. routing weight decay, retry-attempt aging).\n *\n * @module\n */\n\n/**\n * Default exponential-decay rate corresponding to a 7-day half-life.\n *\n * `Math.LN2 / (7 × 86_400)` ≈ `1.146e-6`. Imported by memory tiers + any\n * consumer that wants the same default cadence as `agentMemory`'s active\n * tier. Tier 4.4 (Wave AM Unit 1) — promoted from\n * `patterns/ai/memory/tiers.ts` so non-memory consumers can share the\n * canonical default without reaching across domains.\n */\nexport const DEFAULT_DECAY_RATE = Math.LN2 / (7 * 86_400);\n\n/**\n * Exponential decay with floor: `score = max(minScore, baseScore * exp(-ratePerSecond * ageSeconds))`.\n *\n * Tolerant fallbacks (deliberate for use inside reactive derived fns):\n * - non-finite `baseScore` → `minScore`\n * - non-positive `ageSeconds` (incl. clock skew) → `max(minScore, baseScore)` (no decay)\n * - non-positive `ratePerSecond` → `max(minScore, baseScore)` (no decay; rate=0 disables)\n *\n * Underflow boundary: `Math.exp(-745) === 0`. For very long ages × rates the\n * result clamps to `minScore`; if you need slow decay over years, choose a\n * smaller `ratePerSecond` rather than relying on graceful underflow.\n *\n * Half-life conversion: `ratePerSecond = Math.LN2 / halfLifeSeconds`.\n */\nexport function decay(\n\tbaseScore: number,\n\tageSeconds: number,\n\tratePerSecond: number,\n\tminScore = 0,\n): number {\n\tif (!Number.isFinite(baseScore)) return minScore;\n\tif (!Number.isFinite(ageSeconds) || ageSeconds <= 0) return Math.max(minScore, baseScore);\n\tif (!Number.isFinite(ratePerSecond) || ratePerSecond <= 0) return Math.max(minScore, baseScore);\n\tconst decayed = baseScore * Math.exp(-ratePerSecond * ageSeconds);\n\treturn Math.max(minScore, decayed);\n}\n","/**\n * Harness-domain internal helpers.\n *\n * trackingKey extracted from patterns/_internal/index.ts during cleave A2.\n * Destination decided per STOP #1 resolution: harness-domain shape,\n * used only by utils/harness/types.ts and presets/harness/harness-loop.ts.\n */\n\n// trackingKey\n// ---------------------------------------------------------------------------\n\n/**\n * Stable tracking key for an item with retry/reingestion decoration.\n *\n * Uses `relatedTo[0]` if present (carries the original key forward through\n * retries and reingestions). Falls back to `summary` for first-time items.\n *\n * This avoids deriving keys from mutated summary strings — retries decorate\n * the summary with `[RETRY N/M]` and failure context, so regex-stripping\n * would be fragile and any new decoration pattern would risk infinite loops\n * by generating novel keys.\n *\n * **Caller contract — uniqueness (qa D1, 2026-04-29).** Two distinct intake\n * items sharing the same `summary` (and neither carrying `relatedTo`)\n * produce the SAME tracking key. The harness's `routeJobIds` map is keyed\n * by this value: a duplicate-key publish overwrites the prior mapping, and\n * a later `ackJob` for the original publish acks the wrong audit job.\n * Single-threaded JS makes the typical structural-failure path safe (the\n * ack runs before reingest publishes), but multi-publisher concurrency or\n * batched intake of two items with identical summaries can race.\n *\n * **Caller responsibility:** ensure `summary` uniqueness OR carry an\n * explicit stable id via `relatedTo[0]` for items that may collide. For\n * retry/reingestion paths the `relatedTo` array MUST start with the\n * original tracking key — `[originalKey, ...]` — so the carried-forward\n * identity matches the audit log entry created at first publish.\n *\n * @internal\n */\nexport function trackingKey(item: { summary: string; relatedTo?: string[] }): string {\n\treturn item.relatedTo?.[0] ?? item.summary;\n}\n","/**\n * Harness runtime defaults (roadmap §9.0).\n *\n * Split out from `types.ts` in Wave B Unit 15 G so the type file holds\n * only type declarations and plug-in contracts. Runtime constants and\n * helpers live here; the harness barrel (`index.ts`) re-exports both so\n * external consumers see a single surface.\n *\n * @module\n */\n\nimport type {\n\tErrorClass,\n\tErrorClassifier,\n\tExecutionResult,\n\tIntervention,\n\tPresetId,\n\tQueueConfig,\n\tQueueRoute,\n\tRootCause,\n\tSeverity,\n\tStrategyKey,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Route / queue\n// ---------------------------------------------------------------------------\n\n/** Ordered queue route names for iteration. */\nexport const QUEUE_NAMES: readonly QueueRoute[] = [\n\t\"auto-fix\",\n\t\"needs-decision\",\n\t\"investigation\",\n\t\"backlog\",\n];\n\n/** Default queue configurations. */\nexport const DEFAULT_QUEUE_CONFIGS: Record<QueueRoute, QueueConfig> = {\n\t\"auto-fix\": { gated: false },\n\t\"needs-decision\": { gated: true },\n\tinvestigation: { gated: true },\n\t// `startOpen` intentionally omitted — backlog is not gated, so the flag\n\t// would be meaningless. Dropped in Unit 15 G trim pass.\n\tbacklog: { gated: false },\n};\n\n// ---------------------------------------------------------------------------\n// Priority scoring\n// ---------------------------------------------------------------------------\n\n/** Default severity weights. */\nexport const DEFAULT_SEVERITY_WEIGHTS: Record<Severity, number> = {\n\tcritical: 100,\n\thigh: 70,\n\tmedium: 40,\n\tlow: 10,\n};\n\n/** Default decay rate: ~7-day half-life. Re-exported from `base/utils/decay.ts`. */\nexport { DEFAULT_DECAY_RATE } from \"../../base/utils/decay.js\";\n\n// ---------------------------------------------------------------------------\n// Strategy model\n// ---------------------------------------------------------------------------\n\n/**\n * Canonical 3-axis composite-key factory: `${presetId}|${rootCause}→${intervention}`.\n *\n * **Phase 13.I axis extension (DS-13.I, 2026-05-01).** Pre-multi-agent\n * callers without a preset registry pass {@link DEFAULT_PRESET_ID}\n * (`\"default\"`) for the first arg. Pre-1.0 breaking signature change;\n * persisted strategy-model snapshots from before this date are NOT portable.\n */\nexport function strategyKey(\n\tpresetId: PresetId,\n\trootCause: RootCause,\n\tintervention: Intervention,\n): StrategyKey {\n\treturn `${presetId}|${rootCause}→${intervention}`;\n}\n\n// ---------------------------------------------------------------------------\n// Error classifier\n// ---------------------------------------------------------------------------\n\n/**\n * Regex-word-boundary match over a closed keyword set. Callers needing\n * domain-specific failure modes should supply a custom\n * {@link ErrorClassifier}; this default exists so zero-config harness runs\n * still distinguish parse-class failures (fast-retry) from everything\n * else (full loop via reingestion).\n */\nconst SELF_CORRECTABLE_RE = /\\b(parse|json|config|validation|syntax)\\b/i;\n\n/** Default error classifier: parse/config errors are self-correctable. */\nexport const defaultErrorClassifier: ErrorClassifier = (result: ExecutionResult): ErrorClass =>\n\tSELF_CORRECTABLE_RE.test(result.detail) ? \"self-correctable\" : \"structural\";\n\n// ---------------------------------------------------------------------------\n// Default stage prompts\n// ---------------------------------------------------------------------------\n\n/** Default TRIAGE prompt — LLM classifies intake items into root-cause + intervention + route + priority. */\nexport const DEFAULT_TRIAGE_PROMPT = `You are a triage classifier for a reactive collaboration harness.\n\nGiven an intake item, classify it and output JSON:\n{\n \"rootCause\": \"composition\" | \"missing-fn\" | \"bad-docs\" | \"schema-gap\" | \"regression\" | \"unknown\",\n \"intervention\": \"template\" | \"catalog-fn\" | \"docs\" | \"wrapper\" | \"schema-change\" | \"investigate\",\n \"route\": \"auto-fix\" | \"needs-decision\" | \"investigation\" | \"backlog\",\n \"priority\": <number 0-100>,\n \"triageReasoning\": \"<one sentence>\"\n}\n\nStrategy model (past effectiveness):\n{{strategy}}\n\nIntake item:\n{{item}}`;\n\n/** Default EXECUTE prompt — LLM produces a fix given a triaged issue. */\nexport const DEFAULT_EXECUTE_PROMPT = `You are an implementation agent.\n\nGiven a triaged issue with root cause and intervention type, produce a fix.\n\nIssue:\n{{item}}\n\nOutput JSON:\n{\n \"outcome\": \"success\" | \"failure\" | \"partial\",\n \"detail\": \"<description of what was done or what failed>\"\n}`;\n\n/** Default VERIFY prompt — LLM reviews an execution result against the original issue. */\nexport const DEFAULT_VERIFY_PROMPT = `You are a QA reviewer.\n\nGiven an execution result, verify whether the fix is correct.\n\nExecution:\n{{execution}}\n\nOriginal issue:\n{{item}}\n\nOutput JSON:\n{\n \"verified\": true/false,\n \"findings\": [\"<finding1>\", ...],\n \"errorClass\": \"self-correctable\" | \"structural\" // only if verified=false\n}`;\n\n// ---------------------------------------------------------------------------\n// Prompt resolver helper\n// ---------------------------------------------------------------------------\n\n/**\n * Collapse the `string | ((input: In) => string) | undefined` prompt-template\n * pattern into a single `(input: In) => string`. A function `raw` is used as-is\n * (the caller opted into full control). Otherwise `raw ?? fallbackTemplate`\n * is fed through `substitute`, which does the placeholder replacement.\n *\n * Used by the three harness stages (TRIAGE / EXECUTE / VERIFY), which each\n * accept a `string | function` config but use different placeholder schemes\n * (`{{item}}`, `{{execution}}`, `{{strategy}}`). The helper absorbs only the\n * branch logic; the per-stage placeholder substitution lives at the call site.\n */\nexport function resolvePromptFn<In>(\n\traw: string | ((input: In) => string) | undefined,\n\tfallbackTemplate: string,\n\tsubstitute: (template: string, input: In) => string,\n): (input: In) => string {\n\tif (typeof raw === \"function\") return raw;\n\tconst template = raw ?? fallbackTemplate;\n\treturn (input) => substitute(template, input);\n}\n","/**\n * Strategy model and priority scoring (roadmap §9.0).\n *\n * `strategyModel` returns a typed alias of {@link AuditedSuccessTrackerGraph}\n * keyed by `StrategyKey` (the composite `rootCause→intervention` string).\n * The shared substrate (Class B audit Alt E collapse, 2026-04-30) replaces\n * the prior bespoke bundle shape; composite-key callers use {@link strategyKey}\n * to compute the key and pass `{ rootCause, intervention }` as record decoration.\n *\n * @module\n */\n\nimport { monotonicNs, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { decay } from \"../../base/utils/decay.js\";\nimport {\n\ttype AuditedSuccessTrackerGraph,\n\tauditedSuccessTracker,\n} from \"../orchestration/audited-success-tracker.js\";\n\nimport {\n\tDEFAULT_DECAY_RATE,\n\tDEFAULT_PRESET_ID,\n\tDEFAULT_SEVERITY_WEIGHTS,\n\ttype PrioritySignals,\n\ttype StrategyEntry,\n\ttype StrategyKey,\n\tstrategyKey,\n\ttype TriagedItem,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Strategy model\n// ---------------------------------------------------------------------------\n\n/** Snapshot shape for the strategy-model `entries` node. */\nexport type StrategySnapshot = ReadonlyMap<StrategyKey, StrategyEntry>;\n\n/** Strategy-model graph: a typed alias of {@link AuditedSuccessTrackerGraph}. */\nexport type StrategyModelGraph = AuditedSuccessTrackerGraph<StrategyKey, StrategyEntry>;\n\n/**\n * Create a strategy model that tracks\n * `presetId × rootCause × intervention → successRate` over completed\n * issues (presetId axis added in Phase 13.I, 2026-05-01). Returns an\n * {@link AuditedSuccessTrackerGraph} keyed by {@link StrategyKey}.\n *\n * The reactive `entries` field is a `Node<StrategySnapshot>` suitable for\n * `describe()` / `withLatestFrom` composition.\n *\n * Composite-key conversion happens at the call site:\n * ```ts\n * const strategy = strategyModel();\n * strategy.record(strategyKey(presetId, rootCause, intervention), success, {\n * presetId,\n * rootCause,\n * intervention,\n * });\n * strategy.lookup(strategyKey(presetId, rootCause, intervention));\n * ```\n *\n * Pass {@link DEFAULT_PRESET_ID} (`\"default\"`) for the presetId axis when\n * no preset registry is wired (single-agent harness).\n *\n * The model feeds back into TRIAGE for routing hints.\n */\nexport function strategyModel(): StrategyModelGraph {\n\treturn auditedSuccessTracker<StrategyKey, StrategyEntry>({ name: \"strategy\" });\n}\n\n// ---------------------------------------------------------------------------\n// Priority scoring\n// ---------------------------------------------------------------------------\n\n/**\n * Create a priority scoring derived node for a single triaged item.\n *\n * Combines severity weight, attention decay, strategy model effectiveness,\n * and an optional external urgency signal.\n *\n * **Age sampling caveat.** The `ageSeconds` term is computed as\n * `monotonicNs() - lastInteractionNs.cache` at *each reactive update*. If\n * nothing upstream settles, the score node does not recompute — so a\n * long-idle queue may show a stale score. Pass a `fromTimer(...)`-driven\n * node as a dep (or re-emit on `lastInteractionNs`) when live age decay\n * matters.\n *\n * **Not the same as `TriagedItem.priority`.** The LLM-emitted\n * `priority: 0..100` field on each triaged item is decorative today — the\n * queue consumption order ignores it (tracked in `docs/optimizations.md`\n * as a priority-ordered queue enhancement). This function computes an\n * orthogonal reactive score; it does NOT override the LLM's per-item\n * priority, nor does it drive queue ordering. Wire it to\n * `HarnessGraph.priorityScores` to surface per-route pressure.\n *\n * @param item - Node holding the triaged item.\n * @param strategy - Strategy model node.\n * @param lastInteractionNs - Node holding the monotonic timestamp (ns) of last human interaction.\n * @param urgency - Optional external urgency signal node (0–1 scale).\n * @param signals - Configurable scoring parameters.\n */\nexport function priorityScore(\n\titem: Node<TriagedItem>,\n\tstrategy: Node<StrategySnapshot>,\n\tlastInteractionNs: Node<number>,\n\turgency?: Node<number>,\n\tsignals?: PrioritySignals,\n): Node<number> {\n\tconst severityWeights = { ...DEFAULT_SEVERITY_WEIGHTS, ...signals?.severityWeights };\n\tconst decayRate = signals?.decayRate ?? DEFAULT_DECAY_RATE;\n\tconst effectivenessThreshold = signals?.effectivenessThreshold ?? 0.7;\n\tconst effectivenessBoost = signals?.effectivenessBoost ?? 15;\n\n\tconst deps: Node<unknown>[] = [item, strategy, lastInteractionNs];\n\tif (urgency) deps.push(urgency);\n\n\treturn node<number>(\n\t\tdeps,\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst values = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst itm = values[0] as TriagedItem;\n\t\t\tconst strat = values[1] as StrategySnapshot;\n\t\t\tconst lastNs = values[2] as number;\n\t\t\tconst urg = urgency ? (values[3] as number) : 0;\n\n\t\t\t// Base score from severity\n\t\t\tconst baseWeight = severityWeights[itm.severity ?? \"medium\"];\n\t\t\tconst ageSeconds = (monotonicNs() - lastNs) / 1e9;\n\t\t\tlet score = decay(baseWeight, ageSeconds, decayRate, 0);\n\n\t\t\t// Strategy model boost\n\t\t\tconst key = strategyKey(DEFAULT_PRESET_ID, itm.rootCause, itm.intervention);\n\t\t\tconst entry = strat.get(key);\n\t\t\tif (entry && entry.successRate >= effectivenessThreshold) {\n\t\t\t\tscore += effectivenessBoost;\n\t\t\t}\n\n\t\t\t// External urgency boost (0–1 scale → 0–20 points)\n\t\t\tscore += urg * 20;\n\n\t\t\tactions.emit(score);\n\t\t},\n\t\t{ name: \"priority-score\", describeKind: \"derived\" },\n\t);\n}\n","/**\n * `auditedSuccessTracker` — domain-agnostic per-key success-rate tracker.\n *\n * Reactive `key → { attempts, successes, successRate }` map mounted as a\n * Graph subclass. Reusable substrate for any domain that needs to track\n * outcomes per identifier (routing strategy effectiveness, A/B-test arms,\n * cache-policy tuning, retry-strategy selection, etc.).\n *\n * Replaces the prior `effectivenessTracker` and `strategyModel` factories\n * (Class B audit Alt E collapse, 2026-04-30). Composite-key callers (e.g.\n * `rootCause × intervention`) convert to a string key at the call site.\n *\n * @module\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { keepalive, type ReactiveMapBundle, reactiveMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\n\n/** A single success-rate record for one key. */\nexport interface AuditedSuccessEntry<TKey extends string = string> {\n\treadonly key: TKey;\n\treadonly attempts: number;\n\treadonly successes: number;\n\treadonly successRate: number;\n}\n\n/** Snapshot shape — fresh `ReadonlyMap` on every mutation. */\nexport type AuditedSuccessSnapshot<\n\tTKey extends string = string,\n\tTEntry extends AuditedSuccessEntry<TKey> = AuditedSuccessEntry<TKey>,\n> = ReadonlyMap<TKey, TEntry>;\n\n/** Options for {@link auditedSuccessTracker}. */\nexport interface AuditedSuccessTrackerOptions {\n\t/** Optional graph identity (passed to the underlying Graph constructor). */\n\tgraph?: GraphOptions;\n\t/** Name of the tracker subgraph. Default `\"audited-success-tracker\"`. */\n\tname?: string;\n}\n\n/**\n * Reactive success-rate tracker mounted as a Graph subclass.\n *\n * `key → AuditedSuccessEntry` with `record(key, success, extra?)` /\n * `lookup(key)` methods. The {@link entries} field is a\n * `Node<ReadonlyMap<TKey, TEntry>>` suitable for graph composition —\n * exposed under name `\"entries\"` for `describe()` / `explain()`.\n *\n * Backed by the {@link reactiveMap} substrate; each successful `record(...)`\n * fires a DATA emission carrying the post-mutation map.\n *\n * **Field name.** This Graph subclass uses `entries` (not `snapshot`) for\n * the public-face Node because `Graph.prototype.snapshot()` is the\n * built-in persistence-snapshot method on the parent class — using\n * `snapshot` here would shadow it and break DTS generation.\n *\n * @typeParam TKey - String-typed key shape. Composite-key domains (e.g.\n * `rootCause × intervention`) convert to a string at the call site.\n * @typeParam TEntry - Entry shape; defaults to {@link AuditedSuccessEntry}.\n * Domains that need extra fields (e.g. `rootCause`/`intervention`) extend\n * this interface and pass the extra fields via `record(...)`'s `extra` arg.\n */\nexport class AuditedSuccessTrackerGraph<\n\tTKey extends string = string,\n\tTEntry extends AuditedSuccessEntry<TKey> = AuditedSuccessEntry<TKey>,\n> extends Graph {\n\t/** Reactive entries — `Node<ReadonlyMap<TKey, TEntry>>`, fresh map per mutation. */\n\treadonly entries: Node<AuditedSuccessSnapshot<TKey, TEntry>>;\n\n\tprivate readonly _map: ReactiveMapBundle<TKey, TEntry>;\n\n\tconstructor(opts?: AuditedSuccessTrackerOptions) {\n\t\tsuper(opts?.name ?? \"audited-success-tracker\", opts?.graph);\n\t\tthis._map = reactiveMap<TKey, TEntry>({ name: \"entries\" });\n\t\tthis.entries = this._map.entries;\n\t\tthis.add(this.entries, { name: \"entries\" });\n\n\t\t// Keep the entries node activated without external subscribers so\n\t\t// `tracker.entries.cache` is readable from sync code paths and\n\t\t// `lookup()` callers don't have to manage subscriptions. Released on\n\t\t// Graph dispose along with the underlying reactiveMap.\n\t\tthis.addDisposer(keepalive(this.entries));\n\t\tthis.addDisposer(() => this._map.dispose());\n\t}\n\n\t/**\n\t * Record a completed attempt. `extra` fields are merged into the stored\n\t * entry — use for domain-specific decoration (e.g. `{ rootCause,\n\t * intervention }` on the strategy-model collapse path).\n\t *\n\t * **Caller contract for typed `TEntry`.** When `TEntry` extends\n\t * {@link AuditedSuccessEntry} with required fields beyond\n\t * `key`/`attempts`/`successes`/`successRate`, the caller must supply\n\t * those required fields in `extra` on the **first** `record(key, ...)`\n\t * for that key. The internal `as TEntry` cast trusts this. Subsequent\n\t * `record(key, ...)` calls inherit the prior entry's fields, so `extra`\n\t * may be omitted or partial. Forgetting required fields on the first\n\t * record produces an entry whose typed-required fields are `undefined`\n\t * at runtime — TS won't catch it. Strategy callers always pass\n\t * `{ rootCause, intervention }`, so the StrategyEntry case is safe.\n\t */\n\trecord(\n\t\tkey: TKey,\n\t\tsuccess: boolean,\n\t\textra?: Partial<Omit<TEntry, \"key\" | \"attempts\" | \"successes\" | \"successRate\">>,\n\t): void {\n\t\tconst existing = this._map.get(key);\n\t\tconst attempts = (existing?.attempts ?? 0) + 1;\n\t\tconst successes = (existing?.successes ?? 0) + (success ? 1 : 0);\n\t\tthis._map.set(key, {\n\t\t\t...(existing ?? {}),\n\t\t\t...(extra ?? {}),\n\t\t\tkey,\n\t\t\tattempts,\n\t\t\tsuccesses,\n\t\t\tsuccessRate: successes / attempts,\n\t\t} as TEntry);\n\t}\n\n\t/**\n\t * Look up the entry for a key.\n\t *\n\t * Pure read: this tracker doesn't configure a TTL on the underlying\n\t * `reactiveMap`, so `_map.get(key)` never triggers TTL-expiry pruning\n\t * (which would otherwise be an observable side effect emitting a fresh\n\t * `entries` snapshot). If `AuditedSuccessTrackerOptions` ever gains a\n\t * `mapOptions` carve-out exposing TTL, revisit this contract.\n\t */\n\tlookup(key: TKey): TEntry | undefined {\n\t\treturn this._map.get(key);\n\t}\n}\n\n/**\n * Construct an {@link AuditedSuccessTrackerGraph}. Replaces the prior\n * `effectivenessTracker()` and `strategyModel()` factories.\n *\n * @example\n * ```ts\n * // Generic per-action tracker\n * const tracker = auditedSuccessTracker({ name: \"ab-test\" });\n * tracker.record(\"variant-a\", true);\n * tracker.record(\"variant-b\", false);\n * tracker.entries.subscribe(snap => console.log(snap.get(\"variant-a\")));\n *\n * // Composite-key (rootCause × intervention) tracker — caller computes the key\n * type StrategyEntry = AuditedSuccessEntry<StrategyKey> & {\n * rootCause: RootCause;\n * intervention: Intervention;\n * };\n * const strategy = auditedSuccessTracker<StrategyKey, StrategyEntry>({\n * name: \"strategy\",\n * });\n * strategy.record(\n * strategyKey(rootCause, intervention),\n * true,\n * { rootCause, intervention },\n * );\n * ```\n *\n * @category extra\n */\nexport function auditedSuccessTracker<\n\tTKey extends string = string,\n\tTEntry extends AuditedSuccessEntry<TKey> = AuditedSuccessEntry<TKey>,\n>(opts?: AuditedSuccessTrackerOptions): AuditedSuccessTrackerGraph<TKey, TEntry> {\n\treturn new AuditedSuccessTrackerGraph<TKey, TEntry>(opts);\n}\n","/**\n * Harness wiring types (roadmap §9.0).\n *\n * Shared types for the reactive collaboration loop: intake, triage, queue,\n * gate, execute, verify, reflect. These types are intentionally domain-agnostic\n * — the harness loop is not specific to eval workflows.\n *\n * Runtime constants and helpers live in `./defaults.ts`. The harness barrel\n * (`./index.ts`) re-exports both so external consumers see a single surface.\n *\n * @module\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { NodeInput } from \"@graphrefly/pure-ts/extra\";\n// Type-only import avoids a runtime cycle with `patterns/ai`.\nimport type { LLMAdapter } from \"../ai/index.js\";\nimport type { JobEnvelope } from \"../job-queue/index.js\";\n\n// ---------------------------------------------------------------------------\n// Intake\n// ---------------------------------------------------------------------------\n\n/** Known intake source tags. */\nexport type KnownIntakeSource = \"eval\" | \"test\" | \"human\" | \"code-change\" | \"hypothesis\" | \"parity\";\n\n/**\n * Sources that can produce intake items. Open union — the known tags\n * retain IDE autocomplete while user-supplied strings (e.g. `\"schema\"`,\n * `\"slack\"`) pass through without a type change.\n */\nexport type IntakeSource = KnownIntakeSource | (string & {});\n\n/** Severity levels for intake items. */\nexport type Severity = \"critical\" | \"high\" | \"medium\" | \"low\";\n\n/** Root cause categories for triage classification. */\nexport type RootCause =\n\t| \"composition\"\n\t| \"missing-fn\"\n\t| \"bad-docs\"\n\t| \"schema-gap\"\n\t| \"regression\"\n\t| \"unknown\";\n\n/** Intervention types that address root causes. */\nexport type Intervention =\n\t| \"template\"\n\t| \"catalog-fn\"\n\t| \"docs\"\n\t| \"wrapper\"\n\t| \"schema-change\"\n\t| \"investigate\";\n\n/** Routing destinations after triage. Closed union — iterated via `QUEUE_NAMES`. */\nexport type QueueRoute = \"auto-fix\" | \"needs-decision\" | \"investigation\" | \"backlog\";\n\n/**\n * An item entering the harness loop via the INTAKE stage.\n *\n * All intake sources produce this uniform shape — the intake topic\n * doesn't care where items came from.\n *\n * `$`-prefix keys (`$reingestions`, `$retries` on {@link TriagedItem}) are\n * framework-only — an LLM round-tripping the serialized item is far less\n * likely to echo back a `$`-prefixed key than an `_`-prefixed one, which\n * neutralizes the field-collision class that surfaced earlier in the\n * router's spread order.\n */\nexport interface IntakeItem {\n\tsource: IntakeSource;\n\tsummary: string;\n\tevidence: string;\n\taffectsAreas: string[];\n\taffectsEvalTasks?: string[];\n\tseverity?: Severity;\n\t/**\n\t * Identity-preservation key for retried / reingested items.\n\t *\n\t * `relatedTo[0]` MUST carry the original tracking key for retry /\n\t * reingest items so the harness's `routeJobIds` map preserves\n\t * identity across decorated retry summaries (per qa D1, 2026-04-29).\n\t * First-time publishes leave this `undefined`; the tracking key\n\t * falls back to `summary` via {@link trackingKey}.\n\t *\n\t * **Collision contract (DS-13.5.D.3, locked 2026-05-01).** Items\n\t * lacking `relatedTo[0]` and producing colliding `trackingKey()`\n\t * derivations overwrite the prior `routeJobIds` entry —\n\t * **last-write-wins**. Framework-enforced uniqueness was rejected\n\t * because it would break legitimate retry / reingest patterns where\n\t * an explicit `relatedTo[0]` carries the original key forward.\n\t *\n\t * **Single-threaded contract.** Ack runs before reingest publishes\n\t * (harness flow invariant) — under the standard single-threaded JS\n\t * pump this collapses the only practical race window. Multi-publisher\n\t * concurrency or batched intake of two first-time items with identical\n\t * `summary` can still race at boundaries; callers carrying their own\n\t * stable id should set `relatedTo[0]`.\n\t *\n\t * See {@link trackingKey} JSDoc in `patterns/_internal/index.ts` for\n\t * the uniqueness caller contract.\n\t *\n\t * Spec: docs/implementation-plan.md DS-13.5.D.3\n\t */\n\trelatedTo?: string[];\n\t/** Item-carried reingestion count. Incremented on each full-loop reingestion. */\n\t$reingestions?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Triage output\n// ---------------------------------------------------------------------------\n\n/** Output of the TRIAGE stage — enriched intake item with classification. */\nexport interface TriagedItem extends IntakeItem {\n\trootCause: RootCause;\n\tintervention: Intervention;\n\troute: QueueRoute;\n\tpriority: number;\n\ttriageReasoning?: string;\n\t/** Item-carried retry count. Incremented on each fast-retry pass. */\n\t$retries?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Strategy model\n// ---------------------------------------------------------------------------\n\n/**\n * Preset / persona / skill identifier. Open string set; conventionally\n * matches keys used in {@link presetRegistry} (Phase 13.H). Use\n * {@link DEFAULT_PRESET_ID} (\"default\") when no preset registry is wired.\n */\nexport type PresetId = string;\n\n/** Default presetId used when no preset registry is wired (back-compat for 2-axis callers). */\nexport const DEFAULT_PRESET_ID: PresetId = \"default\";\n\n/**\n * Key format: `${presetId}|${rootCause}→${intervention}`.\n *\n * **Phase 13.I axis extension (DS-13.I, 2026-05-01).** Widened from the\n * pre-multi-agent 2-axis `${rootCause}→${intervention}` to a 3-axis key\n * carrying the presetId of the agent that ran. Pre-1.0 breaking change;\n * existing callsites pass {@link DEFAULT_PRESET_ID} for the new axis when\n * they don't have a preset registry wired. The strategy-model storage\n * (`auditedSuccessTracker<StrategyKey, StrategyEntry>`) is unchanged\n * structurally — the key shape change cascades through the existing\n * tracker without surface refactor.\n */\nexport type StrategyKey = `${PresetId}|${RootCause}→${Intervention}`;\n\n/**\n * Effectiveness record for a `(presetId, rootCause, intervention)` triple.\n * Stored under `auditedSuccessTracker<StrategyKey, StrategyEntry>` (Class B\n * audit Alt E collapse, 2026-04-30; presetId axis added Phase 13.I,\n * 2026-05-01) — `key` is the composite `strategyKey(presetId, rc, intv)`\n * computed at the call site; `presetId` / `rootCause` / `intervention` are\n * decoration carried via `record(...)` so consumers can read them without\n * re-parsing the key.\n */\nexport interface StrategyEntry {\n\tkey: StrategyKey;\n\tpresetId: PresetId;\n\trootCause: RootCause;\n\tintervention: Intervention;\n\tattempts: number;\n\tsuccesses: number;\n\tsuccessRate: number;\n}\n\n// ---------------------------------------------------------------------------\n// Execution & verification\n// ---------------------------------------------------------------------------\n\n/**\n * LLM output shape from the EXECUTE stage (partial — lacks `item`).\n *\n * Generic over the artifact type `A` so typed executors like\n * `refineExecutor<T>` can flow `T` through to an `evalVerifier<T>` without\n * the caller casting `artifact` at the boundary. Defaults to `unknown`\n * for escape-hatch executors that carry opaque state.\n */\nexport type ExecuteOutput<A = unknown> = {\n\t/**\n\t * Execution outcome classification:\n\t *\n\t * - `\"success\"`: execution completed cleanly and the artifact (if any) is\n\t * ready for verification. The verifier should proceed with a full\n\t * evaluation pass.\n\t * - `\"failure\"`: execution did not produce a usable artifact — the actuator\n\t * threw, a prompt parse failed, or `shouldApply` skipped the item. The\n\t * verifier should treat this as a non-result and route accordingly.\n\t * - `\"partial\"`: execution produced a candidate that converged but did not\n\t * fully meet verification criteria. Used by `refineExecutor` when the\n\t * iteration cap is reached without full convergence; the artifact holds\n\t * the best candidate achieved.\n\t */\n\toutcome: \"success\" | \"failure\" | \"partial\";\n\tdetail: string;\n\t/**\n\t * Optional opaque artifact that a custom executor (e.g. `refineExecutor`)\n\t * may attach so downstream verifiers can re-run evaluation against the\n\t * thing that was produced. LLM-backed default executors never populate\n\t * this — it's an escape hatch for reactive executors carrying structured\n\t * output (a refined prompt, a patched spec, a generated template, ...).\n\t */\n\tartifact?: A;\n};\n\n/** Full execution result assembled downstream (LLM output + context). */\nexport interface ExecutionResult<A = unknown> {\n\titem: TriagedItem;\n\t/**\n\t * Execution outcome classification. Same semantics as\n\t * {@link ExecuteOutput.outcome}:\n\t *\n\t * - `\"success\"`: execution completed cleanly; artifact is ready for\n\t * verification.\n\t * - `\"failure\"`: no usable artifact was produced.\n\t * - `\"partial\"`: best candidate produced but convergence criteria not met\n\t * (iteration cap reached in `refineExecutor`).\n\t */\n\toutcome: \"success\" | \"failure\" | \"partial\";\n\tdetail: string;\n\t/**\n\t * Passthrough of {@link ExecuteOutput.artifact} when the executor emitted\n\t * one. Reactive executors like `refineExecutor` populate this; LLM-backed\n\t * default executors leave it undefined.\n\t */\n\tartifact?: A;\n}\n\n/** Whether an error is self-correctable (fast-retry) or structural (full loop). */\nexport type ErrorClass = \"self-correctable\" | \"structural\";\n\n/** Classifier for fast-retry path. */\nexport type ErrorClassifier = (result: ExecutionResult) => ErrorClass;\n\n// ---------------------------------------------------------------------------\n// Verification output\n// ---------------------------------------------------------------------------\n\n/** Result of the VERIFY stage. */\nexport interface VerifyResult<A = unknown> {\n\titem: TriagedItem;\n\texecution: ExecutionResult<A>;\n\tverified: boolean;\n\tfindings: string[];\n\terrorClass?: ErrorClass;\n}\n\n/**\n * Verifier output shape — what a custom verifier emits. The harness\n * assembles this into the full {@link VerifyResult} using the triaged\n * item + execute output sampled from `executeContextNode`.\n */\nexport interface VerifyOutput {\n\tverified: boolean;\n\tfindings: string[];\n\terrorClass?: ErrorClass;\n}\n\n// ---------------------------------------------------------------------------\n// Priority scoring\n// ---------------------------------------------------------------------------\n\n/** Configurable signals for priority scoring. */\nexport interface PrioritySignals {\n\t/** Per-severity base weight (default: critical=100, high=70, medium=40, low=10). */\n\tseverityWeights?: Partial<Record<Severity, number>>;\n\t/** Decay rate per second for attention decay (default ~1.15e-6 ≈ 7-day half-life). */\n\tdecayRate?: number;\n\t/** Strategy model effectiveness boost threshold (default 0.7). */\n\teffectivenessThreshold?: number;\n\t/** Strategy model effectiveness boost amount (default 15). */\n\teffectivenessBoost?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Harness loop configuration\n// ---------------------------------------------------------------------------\n\nimport type { StrategySnapshot } from \"./strategy.js\";\n\n/** Per-queue configuration in the harness loop. */\nexport interface QueueConfig {\n\t/** Whether this queue is gated (requires human approval). */\n\tgated: boolean;\n\t/** Maximum pending items in the gate (default Infinity). */\n\tmaxPending?: number;\n\t/** Start the gate in open (auto-approve) mode? Only meaningful when `gated: true`. */\n\tstartOpen?: boolean;\n}\n\n/**\n * Accumulating per-job payload threaded through the harness's\n * `executeFlow` ({@link harnessLoop} Tier 6.5 C2 lock). Each stage's work fn\n * receives the prior payload and returns a new one with its own field\n * filled in:\n *\n * - The `enqueueEffect` seeds with `{ item }` only.\n * - The execute work fn fills `execution`.\n * - The verify work fn fills `verify`.\n *\n * The post-completed dispatch effect reads `verify.verified` /\n * `verify.errorClass` to route the item to `verifyResults` /\n * `retryTopic.publish(...)` / `intake.publish(...)` (3-way verdict).\n *\n * Carrying `item` through stage payloads (rather than re-pairing via a\n * separate `withLatestFrom` node) is the C2 deviation from today's\n * `executeContextNode` design: each `JobEnvelope` is self-contained, so the\n * verify pump can run multiple in-flight jobs in parallel without an\n * external pairing node.\n */\nexport interface HarnessJobPayload<A = unknown> {\n\t/** The triaged item flowing through execute → verify → dispatch. */\n\titem: TriagedItem;\n\t/** Filled by the execute work fn. Verify reads this; dispatch routes. */\n\texecution?: ExecutionResult<A>;\n\t/** Filled by the verify work fn. Dispatch reads `verified` / `errorClass`. */\n\tverify?: VerifyOutput;\n}\n\n/**\n * Pluggable EXECUTE work fn — receives a {@link JobEnvelope} carrying a\n * {@link HarnessJobPayload} (with `item` set, `execution` / `verify`\n * unset), returns a {@link NodeInput} that emits the same payload with\n * `execution` filled.\n *\n * **C2 contract (Tier 6.5 lock, 2026-04-28):**\n * 1. Emit DATA exactly once per claimed job. The JobFlow pump subscribes\n * once, takes the first DATA, then unsubscribes. Subsequent emissions\n * are ignored.\n * 2. Errors must be caught and surfaced as a `failure` outcome inside the\n * payload — never throw / return ERROR. A pump nack would drop the\n * item from JobFlow before the dispatch effect could route it.\n * 3. The work fn runs once per claim — no internal `switchMap` needed.\n * Per-item subgraphs (e.g. a fresh `refineLoop` per claim) are\n * instantiated inside the work fn body.\n *\n * `defaultLlmExecutor` (in `defaults.ts`) is a thin `adapter.invoke()`\n * wrapper. `refineExecutor` builds a per-claim `refineLoop`.\n * `actuatorExecutor` runs a side-effecting `apply(item, signal)`.\n */\nexport type HarnessExecutor<A = unknown> = (\n\tjob: JobEnvelope<HarnessJobPayload<A>>,\n\topts?: { signal: AbortSignal },\n) => NodeInput<HarnessJobPayload<A>>;\n\n/**\n * Pluggable VERIFY work fn — receives a {@link JobEnvelope} whose payload\n * has `item` + `execution` populated, returns a {@link NodeInput} that\n * emits the same payload with `verify` filled.\n *\n * Same C2 contract rules 1–3 as {@link HarnessExecutor}. The dispatch\n * effect downstream reads `verify.verified` (success → ack +\n * verifyResults publish), `verify.errorClass === \"self-correctable\"`\n * (retry → republish to retry topic with `$retries` bumped), or anything\n * else (structural → reingest to intake if budget remains).\n *\n * Verify-LLM-call failures (parse error, adapter throw, timeout) MUST be\n * caught and surfaced as a structural-failure `verify` payload (`{\n * verified: false, findings: [...], errorClass: \"structural\" }`) so the\n * dispatch effect can route the item rather than silently drop it.\n */\nexport type HarnessVerifier<A = unknown> = (\n\tjob: JobEnvelope<HarnessJobPayload<A>>,\n\topts?: { signal: AbortSignal },\n) => NodeInput<HarnessJobPayload<A>>;\n\n/** Triage prompt callable shape — pair of `[intake item, strategy snapshot]`. */\nexport type TriagePromptFn = (pair: readonly [IntakeItem, StrategySnapshot]) => string;\n/** Execute prompt callable shape. */\nexport type ExecutePromptFn = (item: TriagedItem) => string;\n/** Verify prompt callable shape — pair of `[execute output, triaged item]`. */\nexport type VerifyPromptFn<A = unknown> = (\n\tpair: readonly [ExecuteOutput<A> | null, TriagedItem | null],\n) => string;\n\n/** Options for {@link harnessLoop}. */\nexport interface HarnessLoopOptions<A = unknown> {\n\t/** LLM adapter for promptNode-based stages (triage + any default executor/verifier). */\n\tadapter: LLMAdapter;\n\n\t/** Custom triage prompt (receives IntakeItem + strategy snapshot as a tuple). */\n\ttriagePrompt?: string | TriagePromptFn;\n\n\t/**\n\t * Execute prompt — sugar over the default LLM executor. Ignored when\n\t * `executor` is set.\n\t */\n\texecutePrompt?: string | ExecutePromptFn;\n\n\t/**\n\t * Verify prompt — sugar over the default LLM verifier. Ignored when\n\t * `verifier` is set.\n\t */\n\tverifyPrompt?: string | VerifyPromptFn<A>;\n\n\t/**\n\t * Pluggable EXECUTE slot. When omitted, the harness uses a `promptNode`\n\t * driven by `adapter` + `executePrompt`. Replace to plug in a\n\t * `refineExecutor`, tool-using agent, or any reactive execution pipeline.\n\t */\n\texecutor?: HarnessExecutor<A>;\n\n\t/**\n\t * Pluggable VERIFY slot. When omitted, the harness uses a `promptNode`\n\t * driven by `adapter` + `verifyPrompt`. Replace to plug in an\n\t * `evalVerifier` that re-runs affected eval tasks.\n\t */\n\tverifier?: HarnessVerifier<A>;\n\n\t/** Per-queue configuration overrides. */\n\tqueues?: Partial<Record<QueueRoute, QueueConfig>>;\n\n\t/** Priority scoring signals. */\n\tpriority?: PrioritySignals;\n\n\t/**\n\t * Reactive last-human-interaction timestamp (monotonic ns). Drives the\n\t * priority score age-decay term for `HarnessGraph.priorityScores`.\n\t *\n\t * **Required when `opts.priority` is set.** Priority score nodes only\n\t * re-derive when `topic.latest`, `strategy.snapshot`, or this tick settles —\n\t * an idle queue would freeze its age at construction time if we\n\t * auto-defaulted. Typical sources:\n\t * - `fromTimer(60_000)` — steady tick, uniform decay.\n\t * - `state(monotonicNs())` — bumped from a human-interaction handler.\n\t * - A reactive view over a DB column / external metrics source.\n\t */\n\tlastInteractionNs?: Node<number>;\n\n\t/** Error classifier for fast-retry path. */\n\terrorClassifier?: ErrorClassifier;\n\n\t/** Max fast-retries per item before routing to full intake (default 2). */\n\tmaxRetries?: number;\n\n\t/** Global retry cap across all items — circuit breaker (default maxRetries × 10). */\n\tmaxTotalRetries?: number;\n\n\t/** Max re-ingestions from verify→intake before giving up (default 1). */\n\tmaxReingestions?: number;\n\n\t/** Global reingestion cap across all items — circuit breaker (default maxReingestions × 10). */\n\tmaxTotalReingestions?: number;\n\n\t/** Retained limit for topic logs (default 1000). */\n\tretainedLimit?: number;\n\n\t/**\n\t * Per-pump-tick claim cap on the internal `executeFlow` JobFlow's `execute`\n\t * stage (Tier 6.5 C2). Default `Number.MAX_SAFE_INTEGER` — every pending\n\t * claim is processed in one tick (matches today's unbounded `merge()`\n\t * parallelism). Lower this to bound LLM cost spikes on bursty intake.\n\t *\n\t * **Caveat.** This caps **claims per pump tick**, not total concurrent\n\t * inflight. Bounded-inflight is a separate primitive concern — see\n\t * `docs/optimizations.md` \"Tier 6.5 follow-up — bounded concurrent inflight\n\t * on JobFlow stages\".\n\t */\n\texecuteMaxPerPump?: number;\n\n\t/**\n\t * Per-pump-tick claim cap on the internal `executeFlow` JobFlow's\n\t * `verify` stage. Default `Number.MAX_SAFE_INTEGER`. Same caveat as\n\t * {@link HarnessLoopOptions.executeMaxPerPump}. Honored independently\n\t * of the execute cap via `StageDef.maxPerPump` (Tier 6.5 D1).\n\t */\n\tverifyMaxPerPump?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Barrel re-exports from defaults.ts — preserves the pre-split import\n// surface (`import { QUEUE_NAMES, defaultErrorClassifier } from \".../types\"`).\n// ---------------------------------------------------------------------------\n\nexport {\n\tDEFAULT_DECAY_RATE,\n\tDEFAULT_QUEUE_CONFIGS,\n\tDEFAULT_SEVERITY_WEIGHTS,\n\tdefaultErrorClassifier,\n\tQUEUE_NAMES,\n\tstrategyKey,\n} from \"./defaults.js\";\n","/**\n * Job queue patterns (roadmap §4.2).\n *\n * Queue / flow primitives modeled as graph factories:\n * - `jobQueue()` — claim/ack/nack workflow with reactive depth.\n * - `jobFlow()` — multi-stage queue chain.\n *\n * Topic / subscription / hub primitives live in `patterns/messaging`.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tERROR,\n\ttype Node,\n\tnode,\n\tplaceholderArgs,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport type { AppendLogStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport {\n\tfromAny,\n\tkeepalive,\n\ttype NodeInput,\n\ttype ReactiveLogBundle,\n\treactiveList,\n\treactiveLog,\n\treactiveMap,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport {\n\ttype BaseAuditRecord,\n\tbumpCursor,\n\tcreateAuditLog,\n\tmutate,\n\tregisterCursor,\n} from \"../../base/mutation/index.js\";\n\nconst DEFAULT_MAX_PER_PUMP = 256;\nconst DEFAULT_COMPLETED_RETAINED_LIMIT = 1024;\n\nfunction requireNonNegativeInt(value: number, label: string): number {\n\tif (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {\n\t\tthrow new Error(`${label} must be a non-negative integer`);\n\t}\n\treturn value;\n}\n\nfunction jobQueueMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"job_queue\", kind, extra);\n}\n\nexport type JobState = \"queued\" | \"inflight\";\n\nexport type JobEnvelope<T> = {\n\tid: string;\n\tpayload: T;\n\tattempts: number;\n\tmetadata: Readonly<Record<string, unknown>>;\n\tstate: JobState;\n};\n\n/** Audit record for a job-queue mutation (Audit 2 cross-cutting). */\nexport type JobEventAction = \"enqueue\" | \"claim\" | \"ack\" | \"nack\" | \"remove\";\n\nexport interface JobEvent<T = unknown> extends BaseAuditRecord {\n\treadonly action: JobEventAction;\n\treadonly id: string;\n\treadonly attempts?: number;\n\treadonly payload?: T;\n}\n\n/** Recommended `keyOf` for keyed-storage adapters (Audit 2 #7). */\nexport const jobEventKeyOf = <T>(e: JobEvent<T>): string => e.action;\n\nexport type JobQueueOptions = {\n\tgraph?: GraphOptions;\n};\n\nexport class JobQueueGraph<T> extends Graph {\n\tprivate readonly _pending;\n\tprivate readonly _jobs;\n\tprivate readonly _seqCursor: Node<number>;\n\treadonly pending: Node<readonly string[]>;\n\treadonly jobs: Node<ReadonlyMap<string, JobEnvelope<T>>>;\n\treadonly depth: Node<number>;\n\t/** Audit log of every queue mutation (Audit 2). */\n\treadonly events: ReactiveLogBundle<JobEvent<T>>;\n\t/** Alias for {@link JobQueueGraph.events} — Audit 2 `.audit` duplication. */\n\treadonly audit: ReactiveLogBundle<JobEvent<T>>;\n\n\t// Tier 8 / COMPOSITION-GUIDE §35: mutate wrappers for the four\n\t// single-record mutation methods. Assigned in the constructor (NOT via\n\t// class-field initializers) because field initializers run before the\n\t// constructor body — `this.events` and `this._seqCursor` aren't ready yet.\n\t// `claim` stays inline because it emits one record per claimed job.\n\tprivate readonly _enqueueImpl: (\n\t\tpayload: T,\n\t\topts: { id?: string; metadata?: Record<string, unknown> },\n\t) => string;\n\tprivate readonly _ackImpl: (id: string, job: JobEnvelope<T>) => void;\n\tprivate readonly _nackImpl: (id: string, job: JobEnvelope<T>, requeue: boolean) => void;\n\tprivate readonly _removeByIdImpl: (id: string, job: JobEnvelope<T>) => void;\n\n\tconstructor(name: string, opts: JobQueueOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis._pending = reactiveList<string>([], { name: \"pending\" });\n\t\tthis._jobs = reactiveMap<string, JobEnvelope<T>>({ name: \"jobs\" });\n\t\tthis.pending = this._pending.items;\n\t\tthis.jobs = this._jobs.entries;\n\t\tthis.add(this.pending, { name: \"pending\" });\n\t\tthis.add(this.jobs, { name: \"jobs\" });\n\t\tthis.depth = node(\n\t\t\t[this.pending],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly string[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"depth\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: jobQueueMeta(\"queue_depth\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.depth, { name: \"depth\" });\n\t\tthis.addDisposer(keepalive(this.depth));\n\n\t\tthis.events = createAuditLog<JobEvent<T>>({\n\t\t\tname: \"events\",\n\t\t\tretainedLimit: 1024,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis.audit = this.events;\n\t\tthis._seqCursor = registerCursor(this, \"seq\", 0);\n\n\t\t// `freeze: false` everywhere because the payload may be large and\n\t\t// per-mutation cost matters on hot paths. mutate bumps `seq` via\n\t\t// the registered cursor BEFORE the action runs, so action bodies that\n\t\t// need the just-bumped value (e.g. enqueue's auto-id) read\n\t\t// `this._seqCursor.cache`.\n\t\tthis._enqueueImpl = mutate<\n\t\t\t[T, { id?: string; metadata?: Record<string, unknown> }],\n\t\t\tstring,\n\t\t\tJobEvent<T>\n\t\t>(\n\t\t\t(payload, enqueueOpts): string => {\n\t\t\t\tconst seq = this._seqCursor.cache as number;\n\t\t\t\tconst id = enqueueOpts.id ?? `${this.name}-${seq}`;\n\t\t\t\tif (this._jobs.get(id) !== undefined) {\n\t\t\t\t\tthrow new Error(`jobQueue(\"${this.name}\"): duplicate job id \"${id}\"`);\n\t\t\t\t}\n\t\t\t\tconst job: JobEnvelope<T> = {\n\t\t\t\t\tid,\n\t\t\t\t\tpayload,\n\t\t\t\t\tattempts: 0,\n\t\t\t\t\tmetadata: Object.freeze({ ...(enqueueOpts.metadata ?? {}) }),\n\t\t\t\t\tstate: \"queued\",\n\t\t\t\t};\n\t\t\t\tthis._jobs.set(id, job);\n\t\t\t\tthis._pending.append(id);\n\t\t\t\treturn id;\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([payload], id, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"enqueue\",\n\t\t\t\t\tid,\n\t\t\t\t\tpayload,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._ackImpl = mutate<[string, JobEnvelope<T>], void, JobEvent<T>>(\n\t\t\t(id, _job): void => {\n\t\t\t\tthis._jobs.delete(id);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"ack\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._nackImpl = mutate<[string, JobEnvelope<T>, boolean], void, JobEvent<T>>(\n\t\t\t(id, job, requeue): void => {\n\t\t\t\tif (requeue) {\n\t\t\t\t\tthis._jobs.set(id, { ...job, state: \"queued\" });\n\t\t\t\t\tthis._pending.append(id);\n\t\t\t\t} else {\n\t\t\t\t\tthis._jobs.delete(id);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"nack\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._removeByIdImpl = mutate<[string, JobEnvelope<T>], void, JobEvent<T>>(\n\t\t\t(id, job): void => {\n\t\t\t\tif (job.state === \"queued\") {\n\t\t\t\t\tconst pending = this.pending.cache as readonly string[];\n\t\t\t\t\tconst idx = pending.indexOf(id);\n\t\t\t\t\tif (idx >= 0) this._pending.pop(idx);\n\t\t\t\t}\n\t\t\t\tthis._jobs.delete(id);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"remove\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Wire append-log storage tiers (Audit 4). Returns a disposer.\n\t *\n\t * Named `attachEventStorage` to avoid colliding with {@link Graph.attachSnapshotStorage}.\n\t */\n\tattachEventStorage(tiers: readonly AppendLogStorageTier<JobEvent<T>>[]): () => void {\n\t\treturn this.events.attachStorage(tiers);\n\t}\n\n\tenqueue(payload: T, opts: { id?: string; metadata?: Record<string, unknown> } = {}): string {\n\t\treturn this._enqueueImpl(payload, opts);\n\t}\n\n\tclaim(limit = 1): readonly JobEnvelope<T>[] {\n\t\tconst max = requireNonNegativeInt(limit, \"job queue claim limit\");\n\t\tif (max === 0) return [];\n\t\tconst out: JobEnvelope<T>[] = [];\n\t\twhile (out.length < max) {\n\t\t\tconst ids = this.pending.cache as readonly string[];\n\t\t\tif (ids.length === 0) break;\n\t\t\tconst id = this._pending.pop(0);\n\t\t\tconst job = this._jobs.get(id);\n\t\t\tif (!job || job.state !== \"queued\") continue;\n\t\t\tconst inflight: JobEnvelope<T> = {\n\t\t\t\t...job,\n\t\t\t\tstate: \"inflight\",\n\t\t\t\tattempts: job.attempts + 1,\n\t\t\t};\n\t\t\tthis._jobs.set(id, inflight);\n\t\t\tout.push(inflight);\n\t\t\t// claim emits one audit record per claimed job; mutate wraps a\n\t\t\t// single call → single record, so claim stays inline and bumps the\n\t\t\t// cursor directly via the shared `bumpCursor` helper.\n\t\t\tthis.events.append({\n\t\t\t\taction: \"claim\",\n\t\t\t\tid,\n\t\t\t\tattempts: inflight.attempts,\n\t\t\t\tt_ns: wallClockNs(),\n\t\t\t\tseq: bumpCursor(this._seqCursor),\n\t\t\t});\n\t\t}\n\t\treturn out;\n\t}\n\n\tack(id: string): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job || job.state !== \"inflight\") return false;\n\t\tthis._ackImpl(id, job);\n\t\treturn true;\n\t}\n\n\tnack(id: string, opts: { requeue?: boolean } = {}): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job || job.state !== \"inflight\") return false;\n\t\tthis._nackImpl(id, job, opts.requeue ?? true);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Remove a job by id regardless of its current state. Returns `true` if\n\t * the job existed and was removed, `false` if no job has this id.\n\t *\n\t * `ack` only works on inflight; `nack` only works on inflight.\n\t * `removeById` is the state-agnostic escape hatch — useful for\n\t * audit/observability layers that enqueue but never claim, and need to\n\t * finalize a job when an external decision (e.g. harness verify\n\t * outcome) resolves it. Distinct name from the inherited\n\t * {@link Graph.remove}, which removes a mounted child subgraph by path.\n\t *\n\t * When the job is in `queued` state, its id is also pulled from the\n\t * `pending` list — depth + pending snapshot stay consistent.\n\t */\n\tremoveById(id: string): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job) return false;\n\t\tthis._removeByIdImpl(id, job);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Subscribe to a Node and enqueue each DATA payload into this queue.\n\t * Returns a disposer that stops consuming when called.\n\t *\n\t * Used internally by {@link JobFlowGraph} for stage-to-stage wiring but\n\t * also useful for users wiring an external source into a job queue.\n\t *\n\t * @param source - Node whose DATA values are enqueued.\n\t * @param opts - Optional enqueue options (id generator, metadata prefix).\n\t */\n\tconsumeFrom(\n\t\tsource: Node<T>,\n\t\topts?: {\n\t\t\tmetadata?: Record<string, unknown>;\n\t\t},\n\t): () => void {\n\t\treturn source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tconst payload = m[1] as T;\n\t\t\t\tthis.enqueue(payload, opts ? { metadata: opts.metadata } : undefined);\n\t\t\t}\n\t\t});\n\t}\n}\n\n// ── StageDef ─────────────────────────────────────────────────────────────\n\n/**\n * Work function for a job flow stage. Receives the full job envelope and\n * an optional per-claim options object carrying an `AbortSignal`; returns\n * a `NodeInput<T>` — raw value (sync), Promise (async), or Node (composed\n * pipeline). `fromAny` coerces any of these shapes.\n *\n * On error / rejection: the stage nacks the job (no requeue by default).\n *\n * **Per-claim signal (Tier 6.5 2.5b, 2026-04-29).** The pump mints an\n * `AbortController` per claim and supplies its `signal` via `opts`. The\n * signal aborts when (a) the result node settles (first DATA / first\n * ERROR — auto-cleanup after the pump captures), OR (b) the pump itself\n * tears down (e.g. parent Graph `destroy()`). User-supplied work fns that\n * do long-running async (HTTP, LLM streams, evaluator subgraphs) can\n * forward this signal into `fetch({ signal })`, `adapter.invoke({ signal\n * })`, etc. for cooperative cancellation. Sync work fns ignore `opts` —\n * the second arg is optional, no behavior change for legacy callers.\n *\n * Mirrors the `LLMInvokeOptions.signal` / `apply(item, { signal })` /\n * tool-handler `(args, { signal })` precedents — same shape across the\n * library's user-callback boundaries.\n */\nexport type WorkFn<T> = (job: JobEnvelope<T>, opts?: { signal: AbortSignal }) => NodeInput<T>;\n\n/**\n * Stage definition for {@link JobFlowGraph}. Either a bare name string\n * (no work hook, pure pass-through) or a full definition object.\n */\nexport type StageDef<T> =\n\t| string\n\t| {\n\t\t\tname: string;\n\t\t\twork?: WorkFn<T>;\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t\t/**\n\t\t\t * Per-stage cap on `claim → work → ack` cycles per pump tick.\n\t\t\t * Overrides {@link JobFlowOptions.maxPerPump} for this stage. Useful\n\t\t\t * when stages have asymmetric cost (e.g. an LLM-execute stage capped\n\t\t\t * at 4 concurrent calls while a cheap verify stage runs unbounded).\n\t\t\t *\n\t\t\t * Falls back to the top-level `JobFlowOptions.maxPerPump`, which in\n\t\t\t * turn falls back to `DEFAULT_MAX_PER_PUMP` (256).\n\t\t\t */\n\t\t\tmaxPerPump?: number;\n\t\t\t/**\n\t\t\t * Per-stage cap on TOTAL concurrent inflight claims (Tier 6.5 3.1,\n\t\t\t * 2026-04-29). Distinct from {@link maxPerPump}: `maxPerPump` caps\n\t\t\t * claims per pump tick, while `maxInflight` caps the number of\n\t\t\t * unsettled in-flight claims at any moment across all ticks. Use\n\t\t\t * for rigorous LLM cost ceilings (e.g. \"no more than 4 concurrent\n\t\t\t * adapter.invoke calls regardless of pending depth\").\n\t\t\t *\n\t\t\t * When set, the stage mounts an internal `state(0)` counter as a\n\t\t\t * pump dep so the pump re-fires on each settle — pending items\n\t\t\t * resume claiming as soon as inflight drops below the cap.\n\t\t\t *\n\t\t\t * Unset (default): unbounded inflight, gated only by `maxPerPump`.\n\t\t\t */\n\t\t\tmaxInflight?: number;\n\t };\n\nexport type JobFlowOptions<T = unknown> = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Stage definitions. Each stage is either a bare name string (pure\n\t * pass-through) or a `{ name, work?, handlerVersion?, maxPerPump? }` object.\n\t *\n\t * For back-compat, `string[]` values behave as stages with no work hook.\n\t */\n\tstages?: readonly StageDef<T>[];\n\t/**\n\t * Default cap on claims per pump tick across all stages. Per-stage\n\t * overrides can be set on each {@link StageDef.maxPerPump}; if neither is\n\t * set, falls back to `DEFAULT_MAX_PER_PUMP` (256).\n\t */\n\tmaxPerPump?: number;\n};\n\nexport class JobFlowGraph<T> extends Graph {\n\tprivate readonly _stageNames: readonly string[];\n\tprivate readonly _stageWorkFns: ReadonlyMap<string, WorkFn<T>>;\n\tprivate readonly _queues = new Map<string, JobQueueGraph<T>>();\n\tprivate readonly _completed;\n\treadonly completed: Node<readonly JobEnvelope<T>[]>;\n\treadonly completedCount: Node<number>;\n\n\tconstructor(name: string, opts: JobFlowOptions<T> = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\t// Normalise stage definitions.\n\t\tconst rawStages = opts.stages ?? ([\"incoming\", \"processing\", \"done\"] as readonly StageDef<T>[]);\n\t\tconst stageNames: string[] = [];\n\t\tconst stageWorkFns = new Map<string, WorkFn<T>>();\n\t\tconst stageMaxPerPump = new Map<string, number>();\n\t\tconst stageMaxInflight = new Map<string, number>();\n\n\t\tfor (const raw of rawStages) {\n\t\t\tconst stageName = typeof raw === \"string\" ? raw.trim() : raw.name.trim();\n\t\t\tif (typeof raw !== \"string\" && raw.work) {\n\t\t\t\tstageWorkFns.set(stageName, raw.work);\n\t\t\t}\n\t\t\tif (typeof raw !== \"string\" && raw.maxPerPump != null) {\n\t\t\t\tstageMaxPerPump.set(\n\t\t\t\t\tstageName,\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\t1,\n\t\t\t\t\t\trequireNonNegativeInt(raw.maxPerPump, `job flow stage \"${stageName}\" maxPerPump`),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (typeof raw !== \"string\" && raw.maxInflight != null) {\n\t\t\t\tstageMaxInflight.set(\n\t\t\t\t\tstageName,\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\t1,\n\t\t\t\t\t\trequireNonNegativeInt(raw.maxInflight, `job flow stage \"${stageName}\" maxInflight`),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tstageNames.push(stageName);\n\t\t}\n\n\t\tif (stageNames.length < 2) {\n\t\t\tthrow new Error(`jobFlow(\"${name}\"): requires at least 2 stages`);\n\t\t}\n\t\tconst unique = new Set(stageNames);\n\t\tif (unique.size !== stageNames.length) {\n\t\t\tthrow new Error(`jobFlow(\"${name}\"): stage names must be unique`);\n\t\t}\n\t\tthis._stageNames = Object.freeze([...stageNames]);\n\t\tthis._stageWorkFns = stageWorkFns;\n\n\t\tfor (const stage of this._stageNames) {\n\t\t\tconst q = jobQueue<T>(`${name}-${stage}`);\n\t\t\tthis._queues.set(stage, q);\n\t\t\tthis.mount(stage, q);\n\t\t}\n\n\t\tthis._completed = reactiveLog<JobEnvelope<T>>([], {\n\t\t\tname: \"completed\",\n\t\t\tmaxSize: DEFAULT_COMPLETED_RETAINED_LIMIT,\n\t\t});\n\t\tthis.completed = this._completed.entries;\n\t\tthis.add(this.completed, { name: \"completed\" });\n\t\tthis.completedCount = node(\n\t\t\t[this.completed],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly JobEnvelope<T>[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"completedCount\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: jobQueueMeta(\"job_flow_completed_count\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.completedCount, { name: \"completedCount\" });\n\t\tthis.addDisposer(keepalive(this.completedCount));\n\n\t\tconst defaultMaxPerPump = Math.max(\n\t\t\t1,\n\t\t\trequireNonNegativeInt(opts.maxPerPump ?? DEFAULT_MAX_PER_PUMP, \"job flow maxPerPump\"),\n\t\t);\n\n\t\t// Wire up per-stage pumps.\n\t\tfor (let i = 0; i < this._stageNames.length; i += 1) {\n\t\t\tconst stage = this._stageNames[i] as string;\n\t\t\tconst current = this.queue(stage);\n\t\t\tconst next =\n\t\t\t\ti + 1 < this._stageNames.length ? this.queue(this._stageNames[i + 1] as string) : null;\n\t\t\tconst workFn = this._stageWorkFns.get(stage);\n\t\t\t// Per-stage `maxPerPump` override falls back to the top-level cap.\n\t\t\t// Captured per stage so each pump's loop sees its own resolved limit.\n\t\t\tconst stagePerPump = stageMaxPerPump.get(stage) ?? defaultMaxPerPump;\n\t\t\tconst stageMaxInflightCap = stageMaxInflight.get(stage);\n\t\t\t// When `maxInflight` is set, mount a state(0) counter on the graph\n\t\t\t// and wire it as an extra pump dep — settles `inflightCounter.emit`\n\t\t\t// re-fire the pump so pending items resume claiming after each\n\t\t\t// settle (without a counter, the pump only fires on `pending`\n\t\t\t// changes, which `ack` does not affect → maxInflight at saturation\n\t\t\t// would deadlock the queue).\n\t\t\t// qa F-D (Tier 5 /qa pass, 2026-04-29): mount under `__inflight__/`\n\t\t\t// internal namespace so the counter cannot collide with a user-named\n\t\t\t// stage (e.g. `inflight_my-stage`). Matches the EH-16\n\t\t\t// `__processManagers__/<name>` convention (COMPOSITION-GUIDE §38 —\n\t\t\t// internal infrastructure paths use the `__` prefix).\n\t\t\tconst inflightCounter =\n\t\t\t\tstageMaxInflightCap !== undefined\n\t\t\t\t\t? node<number>([], { name: `__inflight__/${stage}`, initial: 0 })\n\t\t\t\t\t: null;\n\t\t\tif (inflightCounter) {\n\t\t\t\tthis.add(inflightCounter, { name: `__inflight__/${stage}` });\n\t\t\t}\n\n\t\t\t// `isTerminal` marks the last stage — completed jobs go into\n\t\t\t// `_completed` log instead of a next queue.\n\t\t\tconst isTerminal = next === null;\n\n\t\t\tif (workFn) {\n\t\t\t\t// ── Stage with work hook ──────────────────────────────────────\n\t\t\t\t// Pump effect: claim one job, run work(job), forward result on\n\t\t\t\t// success; nack on failure.\n\t\t\t\t// Per B.3 lock: effects ARE sanctioned for side-effects.\n\t\t\t\t// `fromAny` bridges sync value / Promise / Node → Node<T>.\n\t\t\t\t//\n\t\t\t\t// **Inflight teardown drain (Tier 6.5 2.5a, 2026-04-29).** Each\n\t\t\t\t// claim mints a per-claim `AbortController` and tracks the\n\t\t\t\t// `(unsub, ac)` pair in a `ctx.store.inflight` Set. The\n\t\t\t\t// per-claim signal is supplied to the work fn via the optional\n\t\t\t\t// second-arg `{ signal }` (mirrors `LLMInvokeOptions.signal` /\n\t\t\t\t// `apply(item, {signal})` / tool-handler precedents). On the\n\t\t\t\t// pump's `deactivate` hook (parent Graph TEARDOWN cascade —\n\t\t\t\t// e.g. `harness.destroy()`), every inflight entry is aborted +\n\t\t\t\t// unsubscribed so user-supplied async work (LLM streams, eval\n\t\t\t\t// HTTP calls, refineLoop iterations) gets cooperative\n\t\t\t\t// cancellation instead of leaking past the harness lifetime.\n\t\t\t\ttype InflightEntry = { unsub: () => void; ac: AbortController };\n\t\t\t\ttype InflightStore = { entries: Set<InflightEntry>; terminated: boolean };\n\t\t\t\tconst pumpDeps: Node[] =\n\t\t\t\t\tinflightCounter != null ? [current.pending, inflightCounter] : [current.pending];\n\t\t\t\tconst pump = node<unknown>(\n\t\t\t\t\tpumpDeps,\n\t\t\t\t\t(_data, _actions, ctx) => {\n\t\t\t\t\t\tif (!(\"inflight\" in ctx.store)) {\n\t\t\t\t\t\t\tctx.store.inflight = {\n\t\t\t\t\t\t\t\tentries: new Set<InflightEntry>(),\n\t\t\t\t\t\t\t\tterminated: false,\n\t\t\t\t\t\t\t} satisfies InflightStore;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst inflightStore = ctx.store.inflight as InflightStore;\n\t\t\t\t\t\tconst inflight = inflightStore.entries;\n\t\t\t\t\t\tlet processed = 0;\n\t\t\t\t\t\twhile (processed < stagePerPump) {\n\t\t\t\t\t\t\t// 3.1 maxInflight gate: cap concurrent inflight across pump\n\t\t\t\t\t\t\t// ticks. The inflightCounter (mounted as a pump dep) re-fires\n\t\t\t\t\t\t\t// the pump when a settle decrements it, so pending items\n\t\t\t\t\t\t\t// resume claiming when capacity frees up.\n\t\t\t\t\t\t\tif (stageMaxInflightCap !== undefined && inflight.size >= stageMaxInflightCap) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst claims = current.claim(1);\n\t\t\t\t\t\t\tif (claims.length === 0) break;\n\t\t\t\t\t\t\tconst job = claims[0] as JobEnvelope<T>;\n\t\t\t\t\t\t\tif (!job) break;\n\n\t\t\t\t\t\t\t// Build the updated path accumulator.\n\t\t\t\t\t\t\tconst prevPath = (job.metadata.job_flow_path as readonly string[] | undefined) ?? [];\n\t\t\t\t\t\t\tconst newPath = [...prevPath, stage];\n\n\t\t\t\t\t\t\tconst ac = new AbortController();\n\t\t\t\t\t\t\tconst entry: InflightEntry = { unsub: () => undefined, ac };\n\t\t\t\t\t\t\tinflight.add(entry);\n\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\n\t\t\t\t\t\t\tlet result: NodeInput<T>;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tresult = workFn(job, { signal: ac.signal });\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t// Sync throw → nack no-requeue.\n\t\t\t\t\t\t\t\tinflight.delete(entry);\n\t\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\t\t\t\t\t\t\t\tcurrent.nack(job.id, { requeue: false });\n\t\t\t\t\t\t\t\tprocessed += 1;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Coerce to Node<T> via fromAny.\n\t\t\t\t\t\t\tconst resultNode = fromAny<T>(result);\n\n\t\t\t\t\t\t\t// M8: Subscribe once to the result node; on DATA forward; on ERROR nack.\n\t\t\t\t\t\t\t// Use `let unsub` + TDZ guard (same pattern as toPromise) so sync\n\t\t\t\t\t\t\t// DATA delivery inside subscribe() doesn't hit TDZ on `unsub`.\n\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\tlet unsub: (() => void) | undefined;\n\t\t\t\t\t\t\tconst cleanupSub = (): void => {\n\t\t\t\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\t\t\t\tunsub();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tPromise.resolve().then(() => unsub?.());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tinflight.delete(entry);\n\t\t\t\t\t\t\t\t// qa F-F (Tier 5 /qa pass, 2026-04-29): skip the counter\n\t\t\t\t\t\t\t\t// emit after teardown — the counter Node is itself in the\n\t\t\t\t\t\t\t\t// cascade. Late ERROR/DATA arriving via the deferred\n\t\t\t\t\t\t\t\t// `Promise.resolve().then(unsub)` path could otherwise emit\n\t\t\t\t\t\t\t\t// on a torn-down node.\n\t\t\t\t\t\t\t\tif (!inflightStore.terminated) {\n\t\t\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tunsub = resultNode.subscribe((msgs) => {\n\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t\tcleanupSub();\n\t\t\t\t\t\t\t\t\t\tconst newPayload = m[1] as T;\n\t\t\t\t\t\t\t\t\t\tconst newMetadata = {\n\t\t\t\t\t\t\t\t\t\t\t...job.metadata,\n\t\t\t\t\t\t\t\t\t\t\tjob_flow_path: newPath,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\tif (isTerminal) {\n\t\t\t\t\t\t\t\t\t\t\tconst completedJob: JobEnvelope<T> = {\n\t\t\t\t\t\t\t\t\t\t\t\t...job,\n\t\t\t\t\t\t\t\t\t\t\t\tpayload: newPayload,\n\t\t\t\t\t\t\t\t\t\t\t\tmetadata: Object.freeze(newMetadata),\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t\t\t\tthis._completed.append(completedJob);\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t\t\t\t(next as JobQueueGraph<T>).enqueue(newPayload, {\n\t\t\t\t\t\t\t\t\t\t\t\t\tmetadata: newMetadata,\n\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t\tcleanupSub();\n\t\t\t\t\t\t\t\t\t\tcurrent.nack(job.id, { requeue: false });\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tentry.unsub = () => unsub?.();\n\n\t\t\t\t\t\t\tprocessed += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t\t// qa F-F: set terminated BEFORE draining so any\n\t\t\t\t\t\t\t\t// `cleanupSub` racing via the deferred-microtask path\n\t\t\t\t\t\t\t\t// (`Promise.resolve().then(() => unsub?.())`) sees\n\t\t\t\t\t\t\t\t// `terminated === true` and skips its `inflightCounter.emit`.\n\t\t\t\t\t\t\t\tinflightStore.terminated = true;\n\t\t\t\t\t\t\t\tfor (const e of inflight) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\te.ac.abort();\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// best-effort\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\te.unsub();\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// best-effort\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tinflight.clear();\n\t\t\t\t\t\t\t\t// Lock 6.D (Phase 13.6.B): drop the `inflight` key\n\t\t\t\t\t\t\t\t// so the next activation re-initializes a fresh\n\t\t\t\t\t\t\t\t// `InflightStore` with `terminated: false`. Without\n\t\t\t\t\t\t\t\t// this, post-flip preserve-by-default keeps the\n\t\t\t\t\t\t\t\t// stale `terminated: true` flag and silently\n\t\t\t\t\t\t\t\t// suppresses inflight-counter emits forever.\n\t\t\t\t\t\t\t\tdelete ctx.store.inflight;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tmeta: jobQueueMeta(\"job_flow_pump\", { stage, has_work: true }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthis.addDisposer(keepalive(pump));\n\t\t\t} else {\n\t\t\t\t// ── Stage without work hook (pass-through ferry) ──────────────\n\t\t\t\t// Claim, accumulate path, forward to next stage or completed.\n\t\t\t\tconst pump = this.effect(\n\t\t\t\t\t`pump_${stage}`,\n\t\t\t\t\t[`${stage}::pending`],\n\t\t\t\t\t() => {\n\t\t\t\t\t\tlet moved = 0;\n\t\t\t\t\t\twhile (moved < stagePerPump) {\n\t\t\t\t\t\t\tconst claim = current.claim(1);\n\t\t\t\t\t\t\tif (claim.length === 0) break;\n\t\t\t\t\t\t\tconst job = claim[0] as JobEnvelope<T>;\n\t\t\t\t\t\t\tif (!job) break;\n\n\t\t\t\t\t\t\tconst prevPath = (job.metadata.job_flow_path as readonly string[] | undefined) ?? [];\n\t\t\t\t\t\t\tconst newPath = [...prevPath, stage];\n\t\t\t\t\t\t\tconst newMetadata = { ...job.metadata, job_flow_path: newPath };\n\n\t\t\t\t\t\t\tif (isTerminal) {\n\t\t\t\t\t\t\t\tconst completedJob: JobEnvelope<T> = {\n\t\t\t\t\t\t\t\t\t...job,\n\t\t\t\t\t\t\t\t\tmetadata: Object.freeze(newMetadata),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\tthis._completed.append(completedJob);\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t(next as JobQueueGraph<T>).enqueue(job.payload, {\n\t\t\t\t\t\t\t\t\t\tmetadata: newMetadata,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmoved += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tmeta: jobQueueMeta(\"job_flow_pump\", { stage, has_work: false }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthis.addDisposer(keepalive(pump));\n\t\t\t}\n\t\t}\n\t}\n\n\tstages(): readonly string[] {\n\t\treturn this._stageNames;\n\t}\n\n\tqueue(stage: string): JobQueueGraph<T> {\n\t\tconst q = this._queues.get(stage);\n\t\tif (!q) throw new Error(`jobFlow(\"${this.name}\"): unknown stage \"${stage}\"`);\n\t\treturn q;\n\t}\n\n\tenqueue(payload: T, opts: { id?: string; metadata?: Record<string, unknown> } = {}): string {\n\t\treturn this.queue(this._stageNames[0] as string).enqueue(payload, opts);\n\t}\n\n\tretainedCompleted(): readonly JobEnvelope<T>[] {\n\t\treturn this.completed.cache as readonly JobEnvelope<T>[];\n\t}\n}\n\n/**\n * Creates a Pulsar-inspired job queue graph with claim/ack/nack workflow.\n */\nexport function jobQueue<T>(name: string, opts?: JobQueueOptions): JobQueueGraph<T> {\n\treturn new JobQueueGraph<T>(name, opts);\n}\n\n/**\n * Creates an autonomous multi-stage queue chain graph.\n */\nexport function jobFlow<T>(name: string, opts?: JobFlowOptions<T>): JobFlowGraph<T> {\n\tconst g = new JobFlowGraph<T>(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` surfaces provenance. Route through\n\t// `placeholderArgs` since `stages[].work` is a function and\n\t// `opts.graph` may carry non-JSON fields.\n\tconst { factory: _f, factoryArgs: _fa, ...tagArgs } = (opts ?? {}) as Record<string, unknown>;\n\tg.tagFactory(\"jobFlow\", placeholderArgs(tagArgs));\n\treturn g;\n}\n","/**\n * `ownershipController()` — multi-agent subgraph ownership preset\n * (DS-14.5.A delta #8; L5/L6 + Q1–Q10).\n *\n * **Placement (documented choice).** Lives in `presets/harness/` alongside\n * the other multi-agent coordination presets (`spawnable()`, `actorPool()`).\n * Per the 4-layer rubric this is a ≥3-utils composition (messaging `topic` +\n * `derived` arbitration + Guard ABAC) wiring multi-agent coordination — the\n * same charter as `harness/`'s existing `spawnable`/`actorPool`. A separate\n * `presets/multi-agent/` directory was rejected to avoid fragmenting the\n * multi-agent presets across two folders for a single factory (L6: \"recipe +\n * preset, NO new primitive\").\n *\n * **What it is.** A `Graph` that owns a shared ownership `topic` (Q3 — one\n * topic carries claim / release / override; subscribers narrow by `kind`),\n * a reactive `current` derivation that folds the ownership log applying the\n * L0–L3 staircase, and a `guard` (`policyAllowing` — the Q7 reactive-options\n * Guard widening) the caller mounts on the owned subgraph. It **consumes the\n * existing DS-14 {@link OwnershipChange}** envelope — it does NOT redefine it.\n *\n * **Staircase (Q10 — `level` is a priority axis, NOT a mechanism enum):**\n * - **L1 TTL** — a `claim` carries a level; the controller's `ttl` (ms)\n * bounds the live window. L1 honors TTL strictly (Q4): a crash inside the\n * window does NOT early-release; recommend `ttl ≤ 60s`.\n * - **L2 heartbeat** — `heartbeat?: NodeInput<unknown>` (Q2). Any reactive\n * trigger Node; each emission resets the countdown (\"max tolerance since\n * last sign of life\", unified across L1/L2). No library timer is shipped\n * and no `claim.heartbeat()` method exists (`feedback_no_imperative` +\n * `feedback_no_imperative_wrap_as_primitive`).\n * - **L3 supervisor** — a `kind:\"override\"` change wins by `level` priority\n * regardless of expiry/heartbeat (priority axis independent of the expiry\n * axis). Supervisor publishes to the SAME topic (Q3).\n *\n * **No polling / no timer (spec §5.8/§5.9/§5.10).** Expiry is evaluated\n * reactively: `current` recomputes whenever the ownership topic OR the\n * heartbeat OR the optional `clock` trigger emits, folding the whole log\n * from scratch (idempotent — no carried mutable cursor). Auto-release on\n * wall-clock TTL requires the caller to wire a reactive `clock` tick\n * (`fromTimer({ ms })` or an activity-derived Node) — the library does not\n * own a timer (L6 / Q2). Without `clock`, expiry still resolves at the next\n * topic/heartbeat emission and on any read that recomputes the derivation.\n *\n * @module\n */\n\nimport { type Node, type NodeGuard, policyAllowing, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { NodeInput, OwnershipChange, OwnershipChangePayload } from \"@graphrefly/pure-ts/extra\";\nimport { fromAny } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport { type TopicGraph, topic } from \"../../utils/messaging/index.js\";\n\n/** Ownership level — priority axis (Q10). Higher rank = higher priority. */\nconst LEVEL_RANK = { L0: 0, L1: 1, L2: 2, L3: 3 } as const;\ntype OwnershipLevel = keyof typeof LEVEL_RANK;\n\n/** Options for {@link ownershipController}. */\nexport type OwnershipControllerOptions = {\n\t/**\n\t * TTL (milliseconds) bounding the live window of a claim. Honored\n\t * strictly (Q4) — a crash inside the window does not early-release.\n\t * Recommend ≤ 60_000 for L1 holds; wire `heartbeat` (L2) for longer.\n\t */\n\treadonly ttl: number;\n\t/**\n\t * L2 heartbeat (Q2). Any reactive trigger Node — each emission resets the\n\t * TTL countdown. Simple: `fromTimer({ ms: ttl / 3 })`. Activity-based:\n\t * `derived([toolCalls.events], …)`. Omitted → pure L1 TTL semantics.\n\t */\n\treadonly heartbeat?: NodeInput<unknown>;\n\t/**\n\t * L3 supervisor id. A `kind:\"override\"` change whose `actor` equals this\n\t * id wins by `level` priority regardless of expiry/heartbeat. Override\n\t * delivery is the shared topic with the `kind:\"override\"` discriminant\n\t * (Q3) — not a separate priority topic.\n\t */\n\treadonly supervisor?: string;\n\t/**\n\t * Optional reactive clock trigger used ONLY to re-evaluate TTL expiry\n\t * (e.g. `fromTimer({ ms: 1_000 })`). The library ships no timer (L6/Q2);\n\t * wire this for wall-clock-driven auto-release without an intervening\n\t * claim/heartbeat. Without it, expiry resolves lazily on the next\n\t * topic/heartbeat emission.\n\t */\n\treadonly clock?: NodeInput<unknown>;\n\t/** Bounded retention for the ownership topic (default 256). */\n\treadonly retainedLimit?: number;\n};\n\n/**\n * Resolved ownership state emitted by {@link OwnershipControllerGraph.current}.\n * `owner` is `null` when unclaimed or the live claim has expired.\n */\nexport type OwnershipState = {\n\treadonly owner: string | null;\n\treadonly level: OwnershipLevel | null;\n\t/** Allow-set fed to the Guard. `[]` (deny-all) when `owner === null`. */\n\treadonly allowed: readonly string[];\n\t/**\n\t * Internal (F3/F4) — last sign-of-life (wall-clock ns) for the *current*\n\t * claim: `max(claim.sinceNs, last in-window heartbeat)`. Carried in the\n\t * derivation's OWN emitted state (read back via `ctx.prevData`) so the\n\t * fold is pure — same (folded log, beat-this-wave, now, prevState) →\n\t * same output. NEVER an instance field. `null` when unclaimed. Scoped to\n\t * the active claim: a value older than the active claim's `sinceNs` (a\n\t * prior owner's beat) is discarded so it cannot extend a new owner.\n\t */\n\treadonly signOfLifeNs: number | null;\n};\n\nconst EMPTY_STATE: OwnershipState = {\n\towner: null,\n\tlevel: null,\n\tallowed: [],\n\tsignOfLifeNs: null,\n};\n\ntype ActiveOwner = { owner: string; level: OwnershipLevel; sinceNs: number };\n\n/**\n * Multi-agent subgraph ownership controller. See module docs.\n *\n * Public surface:\n * - `topic` — the shared ownership `TopicGraph<OwnershipChange>` (Q3).\n * Agents publish claim/release/override here (use the `claim`/`release`/\n * `override` helpers — thin reactive wrappers over `topic.publish`, i.e.\n * message flow, NOT imperative triggers).\n * - `current` — `Node<OwnershipState>`: the reactively-resolved owner after\n * applying L1 TTL + L2 heartbeat + L3 supervisor arbitration.\n * - `allowed` — `Node<readonly string[]>`: the Guard allow-set (derived from\n * `current`); re-points on claim/release/override with no rewire.\n * - `guard` — `NodeGuard` from `policyAllowing(this.allowed)`. Mount on the\n * owned subgraph's nodes (`node({ guard })`) for the Q7 hard-block.\n */\nexport class OwnershipControllerGraph extends Graph {\n\treadonly topic: TopicGraph<OwnershipChange>;\n\treadonly current: Node<OwnershipState>;\n\treadonly allowed: Node<readonly string[]>;\n\treadonly guard: NodeGuard;\n\n\tprivate readonly _ttlNs: number;\n\tprivate readonly _supervisor: string | undefined;\n\t/**\n\t * Whether a heartbeat `NodeInput` was supplied at construction (F14 —\n\t * `claim()`'s `level` default is `\"L2\"` when wired, else `\"L1\"`). NOT a\n\t * mutable accumulator — set once in the constructor, read-only after.\n\t */\n\tprivate readonly _hasHeartbeat: boolean;\n\n\tconstructor(name: string, opts: OwnershipControllerOptions) {\n\t\tsuper(name);\n\t\tthis._ttlNs = Math.max(0, opts.ttl) * 1_000_000;\n\t\tthis._supervisor = opts.supervisor;\n\t\tthis._hasHeartbeat = opts.heartbeat != null;\n\n\t\tthis.topic = topic<OwnershipChange>(`${name}__ownership`, {\n\t\t\tretainedLimit: opts.retainedLimit ?? 256,\n\t\t});\n\t\t// The topic is its own TopicGraph; tear it down with this controller.\n\t\t// (Not mounted — `topic.events` already belongs to the TopicGraph; a\n\t\t// re-`add` would violate single-graph node ownership. Consumers\n\t\t// inspect ownership via `current` / `allowed`, not via a mount.)\n\t\tthis.addDisposer(() => {\n\t\t\tthis.topic.destroy();\n\t\t});\n\n\t\t// `current` recomputes whenever the ownership stream changes, the\n\t\t// heartbeat fires, or the optional clock ticks — the only sources\n\t\t// that can change the resolved owner. ALL deps wired BEFORE any claim\n\t\t// can be published (observers before emitters — §47 rule 2).\n\t\tconst deps: Node<unknown>[] = [this.topic.events as Node<unknown>];\n\t\tconst heartbeatIdx = opts.heartbeat != null ? deps.push(fromAny(opts.heartbeat)) - 1 : -1;\n\t\tif (opts.clock != null) deps.push(fromAny(opts.clock) as Node<unknown>);\n\n\t\tthis.current = this.derived<OwnershipState>(\n\t\t\t\"currentOwner\",\n\t\t\tdeps,\n\t\t\t(batchData, ctx) => {\n\t\t\t\t// Wall-clock (F2) — must match `makeChange`'s `t_ns` stamp so\n\t\t\t\t// `nowNs - active.sinceNs` compares like-for-like. Mixing\n\t\t\t\t// monotonic + wall clocks (the prior bug) made TTL math\n\t\t\t\t// nonsense once the two clocks diverged.\n\t\t\t\tconst nowNs = wallClockNs();\n\t\t\t\t// Did the heartbeat dep emit this wave? `batchData[i]` is the\n\t\t\t\t// array of values dep `i` emitted THIS wave; a non-empty\n\t\t\t\t// heartbeat batch is one or more beats.\n\t\t\t\tconst beatThisWave =\n\t\t\t\t\theartbeatIdx >= 0 &&\n\t\t\t\t\t(() => {\n\t\t\t\t\t\tconst hb = batchData[heartbeatIdx] as readonly unknown[] | null | undefined;\n\t\t\t\t\t\treturn hb != null && hb.length > 0;\n\t\t\t\t\t})();\n\n\t\t\t\t// Fold the WHOLE ownership log from scratch (idempotent — the\n\t\t\t\t// topic emits the full retained array, so a cursor would be a\n\t\t\t\t// bug surface; pure reduction is correct and simple, §47).\n\t\t\t\t// `batchData[0]` is `(readonly OwnershipChange[])[]` — the\n\t\t\t\t// snapshots emitted this wave; take the latest (mirrors\n\t\t\t\t// `topic.latest`'s `batch.at(-1)` pattern). On a SENTINEL\n\t\t\t\t// first-activation wave fall back to `ctx.prevData[0]`.\n\t\t\t\tconst topoBatch = batchData[0] as\n\t\t\t\t\t| readonly (readonly OwnershipChange[])[]\n\t\t\t\t\t| null\n\t\t\t\t\t| undefined;\n\t\t\t\tconst log = (\n\t\t\t\t\ttopoBatch != null && topoBatch.length > 0\n\t\t\t\t\t\t? topoBatch[topoBatch.length - 1]\n\t\t\t\t\t\t: (ctx.prevData[0] as readonly OwnershipChange[] | undefined)\n\t\t\t\t) as readonly OwnershipChange[] | undefined;\n\t\t\t\tlet active: ActiveOwner | null = null;\n\t\t\t\tif (log != null) {\n\t\t\t\t\tfor (const ch of log) {\n\t\t\t\t\t\tif (ch?.change == null) continue;\n\t\t\t\t\t\tactive = applyChange(active, ch, this._supervisor);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// F3/F4 — PURE sign-of-life. Read the prior `signOfLifeNs`\n\t\t\t\t// from THIS derivation's own previously-emitted state\n\t\t\t\t// (`ctx.prevData[0]` for the `current` node is unavailable —\n\t\t\t\t// `prevData[0]` is the topic dep — so we read `ctx.cache`,\n\t\t\t\t// the node's own last emit). No instance field anywhere.\n\t\t\t\tconst prevState = (ctx.cache ?? undefined) as OwnershipState | undefined;\n\n\t\t\t\tlet nextActive: ActiveOwner | null = active;\n\t\t\t\tlet signOfLifeNs: number | null = null;\n\n\t\t\t\tif (active != null && this._ttlNs > 0) {\n\t\t\t\t\t// Carry the prior sign-of-life ONLY if it belongs to THIS\n\t\t\t\t\t// claim (>= the active claim's `sinceNs`). A value from a\n\t\t\t\t\t// prior owner (older than `sinceNs`) is discarded so a\n\t\t\t\t\t// stale beat cannot extend a freshly-claimed window. A new\n\t\t\t\t\t// owner therefore starts from its own claim time.\n\t\t\t\t\tconst carried =\n\t\t\t\t\t\tprevState?.signOfLifeNs != null && prevState.signOfLifeNs >= active.sinceNs\n\t\t\t\t\t\t\t? prevState.signOfLifeNs\n\t\t\t\t\t\t\t: active.sinceNs;\n\t\t\t\t\t// Expire FIRST against the carried sign-of-life (Q4 strict —\n\t\t\t\t\t// a late beat must NOT resurrect an already-lapsed claim),\n\t\t\t\t\t// THEN accept a still-timely beat THIS wave. `signOfLifeNs`\n\t\t\t\t\t// only ever advances on an actual beat-this-wave, so a\n\t\t\t\t\t// recompute storm with no beat cannot renew a dead claim\n\t\t\t\t\t// (idempotent re-fold).\n\t\t\t\t\tconst lapsed = nowNs - carried >= this._ttlNs;\n\t\t\t\t\tif (lapsed) {\n\t\t\t\t\t\tnextActive = null;\n\t\t\t\t\t\tsignOfLifeNs = null;\n\t\t\t\t\t} else if (beatThisWave) {\n\t\t\t\t\t\tsignOfLifeNs = nowNs; // timely beat → renew\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsignOfLifeNs = carried; // unchanged — carry forward\n\t\t\t\t\t}\n\t\t\t\t} else if (active != null) {\n\t\t\t\t\t// No TTL configured — never expires; sign-of-life still\n\t\t\t\t\t// tracked (owner-scoped) for completeness/observability.\n\t\t\t\t\tconst carried =\n\t\t\t\t\t\tprevState?.signOfLifeNs != null && prevState.signOfLifeNs >= active.sinceNs\n\t\t\t\t\t\t\t? prevState.signOfLifeNs\n\t\t\t\t\t\t\t: active.sinceNs;\n\t\t\t\t\tsignOfLifeNs = beatThisWave ? nowNs : carried;\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\tnextActive == null\n\t\t\t\t\t\t? EMPTY_STATE\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\towner: nextActive.owner,\n\t\t\t\t\t\t\t\tlevel: nextActive.level,\n\t\t\t\t\t\t\t\tallowed: [nextActive.owner],\n\t\t\t\t\t\t\t\tsignOfLifeNs,\n\t\t\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t},\n\t\t\t{ keepAlive: true },\n\t\t);\n\n\t\tthis.allowed = this.derived<readonly string[]>(\n\t\t\t\"allowed\",\n\t\t\t[this.current],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst batch = batchData[0] as readonly OwnershipState[] | null | undefined;\n\t\t\t\tconst s = (batch != null && batch.length > 0 ? batch[batch.length - 1] : ctx.prevData[0]) as\n\t\t\t\t\t| OwnershipState\n\t\t\t\t\t| undefined;\n\t\t\t\treturn [s?.allowed ?? []];\n\t\t\t},\n\t\t\t{ keepAlive: true },\n\t\t);\n\t\t// F12 — `keepAlive: true` above already installs a self-pruning\n\t\t// keepalive subscription (same as `current`); a second\n\t\t// `keepalive(this.allowed)` disposer was redundant double-subscription.\n\n\t\t// Q7 — the reactive-options Guard. `policyAllowing` reads\n\t\t// `this.allowed.cache` synchronously at write-check time, so\n\t\t// claim/release/override re-point the allow-set with NO rewire.\n\t\tthis.guard = policyAllowing(this.allowed);\n\t}\n\n\t/**\n\t * Publish a `claim`. Thin reactive wrapper over `topic.publish` (message\n\t * flow per §29 — NOT an imperative trigger). `level` defaults to `\"L2\"`\n\t * when this controller has a heartbeat wired, else `\"L1\"`.\n\t */\n\tclaim(actor: string, level?: OwnershipLevel): void {\n\t\t// F14 — documented default (JSDoc + §47): L2 when a heartbeat\n\t\t// NodeInput was wired at construction, else L1.\n\t\tconst lvl = level ?? (this._hasHeartbeat ? \"L2\" : \"L1\");\n\t\tthis.topic.publish(makeChange({ kind: \"claim\", subgraphId: this.name, actor, level: lvl }));\n\t}\n\n\t/** Publish a `release`. Clears ownership iff `actor` is the current owner. */\n\trelease(actor: string): void {\n\t\tthis.topic.publish(makeChange({ kind: \"release\", subgraphId: this.name, actor }));\n\t}\n\n\t/**\n\t * Publish a supervisor `override` (L3). Wins by `level` priority\n\t * regardless of expiry (Q10). `actor` should be this controller's\n\t * `supervisor` id for the override to take precedence.\n\t */\n\toverride(actor: string, previousActor: string, reason: string): void {\n\t\tthis.topic.publish(\n\t\t\tmakeChange({ kind: \"override\", subgraphId: this.name, actor, previousActor, reason }),\n\t\t);\n\t}\n}\n\n/** Wrap an {@link OwnershipChangePayload} in the DS-14 {@link OwnershipChange} envelope. */\nfunction makeChange(payload: OwnershipChangePayload): OwnershipChange {\n\t// F2 — `BaseChange.t_ns` is contractually wall-clock (`wallClockNs()`,\n\t// see change.ts). The fold compares `nowNs (wallClockNs)` against\n\t// `ch.t_ns` for TTL/expiry, so stamp + compare MUST use the same clock.\n\tconst t = wallClockNs();\n\treturn { structure: \"ownership\", version: t, t_ns: t, lifecycle: \"ownership\", change: payload };\n}\n\n/**\n * Fold one ownership change into the resolved-owner state.\n *\n * - `claim` — sets the active owner (records claim time for L1 TTL). A\n * lower-priority claim cannot displace a higher-`level` live owner (Q10 —\n * override arbitration is pure level comparison).\n * - `release` — clears ownership iff the releasing actor is the owner.\n * - `override` — supervisor override: wins by `level` priority. Carries\n * `previousActor` + `reason` per DS-14 (Q3); modeled as an L3 hand-off to\n * `p.actor`.\n */\nfunction applyChange(\n\tactive: ActiveOwner | null,\n\tch: OwnershipChange,\n\tsupervisor: string | undefined,\n): ActiveOwner | null {\n\tconst p = ch.change;\n\t// Use the change's publish timestamp (`t_ns` — wall-clock, stamped in\n\t// `makeChange`) as the claim time — NOT the fold time. The log is re-folded\n\t// from scratch on every recompute (§47), so stamping a fresh clock read\n\t// here would re-baseline the TTL window every recompute and the claim would\n\t// never expire. The fold compares against `wallClockNs()` (F2 — same clock).\n\tif (p.kind === \"claim\") {\n\t\tif (active != null && LEVEL_RANK[active.level] > LEVEL_RANK[p.level]) return active;\n\t\treturn { owner: p.actor, level: p.level, sinceNs: ch.t_ns };\n\t}\n\tif (p.kind === \"release\") {\n\t\tif (active != null && active.owner === p.actor) return null;\n\t\treturn active;\n\t}\n\t// override (F5) — a `kind:\"override\"` only seizes ownership when the\n\t// publishing actor IS the configured supervisor. The prior disjunction\n\t// `|| LEVEL_RANK.L3 >= LEVEL_RANK[active.level]` was a tautology (L3 is the\n\t// max rank ⇒ always true), so ANY actor's override took over. If no\n\t// supervisor is configured, overrides are explicitly disabled (a non-null\n\t// `supervisor` is the gate, not an accidental fall-through).\n\tconst isSupervisor = supervisor != null && p.actor === supervisor;\n\tif (isSupervisor) {\n\t\treturn { owner: p.actor, level: \"L3\", sinceNs: ch.t_ns };\n\t}\n\treturn active;\n}\n\n/**\n * Create a multi-agent subgraph ownership controller (DS-14.5.A #8).\n *\n * @example\n * ```ts\n * const oc = ownershipController(\"payments\", { ttl: 30_000, supervisor: \"lead\" });\n * // Mount the Guard on the owned subgraph:\n * const n = node([], { initial: 0, guard: oc.guard });\n * oc.claim(\"agent-a\"); // agent-a now owns; non-owner writes throw\n * oc.override(\"lead\", \"agent-a\", \"rebalance\"); // supervisor takes over\n * ```\n */\nexport function ownershipController(\n\tname: string,\n\topts: OwnershipControllerOptions,\n): OwnershipControllerGraph {\n\treturn new OwnershipControllerGraph(name, opts);\n}\n","/**\n * Harness-specific graph profiling (roadmap §9.0).\n *\n * Extends {@link graphProfile} with harness domain counters:\n * queue depths, strategy entries, retry/reingestion tracker sizes.\n *\n * @module\n */\n\nimport {\n\ttype GraphProfileOptions,\n\ttype GraphProfileResult,\n\tgraphProfile,\n} from \"@graphrefly/pure-ts/graph\";\nimport { QUEUE_NAMES } from \"../../utils/harness/defaults.js\";\nimport type { QueueRoute, TriagedItem } from \"../../utils/harness/types.js\";\nimport type { HarnessGraph } from \"./harness-loop.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Harness-specific profile extending the base graph profile. */\nexport interface HarnessProfileResult extends GraphProfileResult {\n\t/** Per-queue retained item counts. */\n\tqueueDepths: Record<QueueRoute, number>;\n\t/** Number of rootCause→intervention entries in the strategy model. */\n\tstrategyEntries: number;\n\t/** Global retry count across all items. */\n\ttotalRetries: number;\n\t/** Global reingestion count across all items. */\n\ttotalReingestions: number;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Profile a harness graph with domain-specific counters.\n *\n * **Snapshot caveat (Unit 22 B).** Reads `.cache` values from the\n * strategy / retry / reingestion nodes + each queue topic's `.retained()`\n * view. These are point-in-time reads and are not transactional — if you\n * invoke this during an in-flight reactive wave the values may reflect\n * a partially-settled frame. For end-of-wave accuracy, call from outside\n * any batch boundary.\n *\n * @param harness - The HarnessGraph to profile.\n * @param opts - Optional base profile options.\n * @returns Harness profile with queue depths, strategy stats, and tracker sizes.\n */\nexport function harnessProfile(\n\tharness: HarnessGraph,\n\topts?: GraphProfileOptions,\n): HarnessProfileResult {\n\tconst base = graphProfile(harness, opts);\n\n\t// Unit 22 B: iterate the hub's topic registry instead of a raw Map so\n\t// queue topics added post-construction (dead-letter `__unrouted`, etc.)\n\t// don't get silently ignored.\n\tconst queueDepths: Record<string, number> = {};\n\tfor (const route of QUEUE_NAMES) {\n\t\tconst t = harness.queues.has(route) ? harness.queues.topic<TriagedItem>(route) : null;\n\t\tqueueDepths[route] = t?.retained().length ?? 0;\n\t}\n\n\treturn {\n\t\t...base,\n\t\tqueueDepths: queueDepths as Record<QueueRoute, number>,\n\t\tstrategyEntries: harness.strategy.entries.cache?.size ?? 0,\n\t\ttotalRetries: harness.totalRetries.cache ?? 0,\n\t\ttotalReingestions: harness.totalReingestions.cache ?? 0,\n\t};\n}\n","/**\n * Phase 13.I — `spawnable()` harness preset.\n *\n * Source: `archive/docs/SESSION-multi-agent-gap-analysis.md` G3 lock B + G5\n * reframe.\n *\n * Wraps a {@link MessagingHubGraph} + {@link presetRegistry} +\n * (per-request) {@link agent} mounting + depth-cap + termination contract.\n * Consumers emit a `TopicMessage<SpawnPayload>` to the well-known\n * {@link SPAWNS_TOPIC}; `spawnable()` mints a fresh agent from the\n * matching preset, mounts it, and tracks it in `activeSlot` until the\n * agent settles or expires. Out-of-policy requests (depth-cap exceeded,\n * unknown presetId, schema-invalid, expired) flow to the `rejected`\n * topic.\n *\n * **Cross-cut #1 lock (no `agent.run()`):** spawnable kicks each agent\n * via `bundle.in.emit(taskInput)`; status transitions are observed via\n * the agent's reactive `status` Node.\n *\n * **Termination contract:**\n * - `done` / `error` from the agent's `status` → unmount + remove from\n * `activeSlot`.\n * - `expiresAt` (set on the request envelope, ISO 8601) — when the wall\n * clock passes the deadline AND the agent is still active, the agent is\n * aborted (via `loop.abort()`) and reported on `rejected` with\n * `reason: \"expired\"`. (Per-spawn timeout via the `timeout` operator\n * recipe is documented in COMPOSITION-GUIDE-PATTERNS.)\n *\n * **Depth-cap:** locked recipe (DS-13.I) is `valve(spawnTopic, derived(\n * [depthCounter], n => n < cap))`, but the practical pattern in\n * `spawnable()` checks depth per-request inside the request handler so\n * over-cap requests can be reported on `rejected`. Callers who want hard\n * cuts (no rejection signal) can wrap their own publish path with\n * `valve` per the recipe.\n */\n\nimport { batch, DATA, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { keepalive } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../../utils/ai/_internal.js\";\nimport type { LLMResponse } from \"../../utils/ai/adapters/core/types.js\";\nimport {\n\ttype MessagingHubGraph,\n\tSPAWNS_TOPIC,\n\ttype SubscriptionGraph,\n\tsubscription,\n\ttype TopicGraph,\n\ttype TopicMessage,\n\ttopic,\n} from \"../../utils/messaging/index.js\";\nimport type { AgentBundle, AgentSpec, AgentStatus } from \"../ai/agent.js\";\nimport type { PresetRegistryBundle } from \"../ai/agents.js\";\nimport { agent } from \"../ai/agents.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Payload of a spawn request envelope. Wraps in a {@link Message}<...>:\n * the request body sets `presetId` (the preset registry key) and\n * `taskInput` (the typed input passed to the spawned agent's `bundle.in`).\n */\nexport interface SpawnPayload<TIn> {\n\treadonly presetId: string;\n\treadonly taskInput: TIn;\n}\n\n/**\n * Rejection record published to the `rejected` topic when a spawn request\n * is denied. `reason` is a short human-readable code.\n */\nexport interface SpawnRejection<TIn> {\n\treadonly request: TopicMessage<SpawnPayload<TIn>>;\n\treadonly reason: string;\n}\n\n/**\n * Options for {@link spawnable}.\n */\nexport interface SpawnableOpts<TIn, TOut> {\n\t/** Existing messaging hub. {@link SPAWNS_TOPIC} is created lazily on it. */\n\treadonly hub: MessagingHubGraph;\n\t/** Preset registry — keys must match `request.payload.presetId`. */\n\treadonly registry: PresetRegistryBundle<AgentSpec<TIn, TOut>>;\n\t/**\n\t * Local mount name on the hub for this spawnable's subgraph. Multiple\n\t * spawnable instances on the same hub must use distinct names. Default\n\t * `\"spawnable\"`.\n\t */\n\treadonly name?: string;\n\t/** Maximum concurrently-active agents. Default unbounded. */\n\treadonly depthCap?: number;\n\t/**\n\t * Initial cursor for the spawn-topic subscription. Default `\"now\"` —\n\t * pre-existing retained spawn requests are NOT replayed at construction.\n\t * Pass `\"retained\"` to replay or a number for explicit cursor offset.\n\t */\n\treadonly from?: \"now\" | \"retained\" | number;\n\t/**\n\t * Optional caller-supplied validator. Returns `true` to accept the\n\t * request, `false` to reject. Reject reason on the `rejected` topic is\n\t * `\"schema validation failed\"`. Pair with the `Message.schema` field carried\n\t * in the envelope when full JSON-Schema validation is needed (consumer\n\t * supplies the validator — ajv / zod / valibot — and reads the schema\n\t * from the envelope to gate). The substrate itself does NOT ship a\n\t * JSON-Schema validator; the `Message.schema` field is wire convention.\n\t */\n\treadonly validate?: (request: TopicMessage<SpawnPayload<TIn>>) => boolean;\n}\n\n/**\n * The bundle returned by {@link spawnable}.\n */\nexport interface SpawnableBundle<TIn, TOut> {\n\t/** The well-known spawn topic — emit `TopicMessage<SpawnPayload<TIn>>` here. */\n\treadonly spawnTopic: TopicGraph<TopicMessage<SpawnPayload<TIn>>>;\n\t/** Reactive map of currently-active agent bundles, keyed by request id. */\n\treadonly activeSlot: Node<ReadonlyMap<string, AgentBundle<TIn, TOut>>>;\n\t/** Topic of rejected requests with reason. */\n\treadonly rejected: TopicGraph<SpawnRejection<TIn>>;\n\t/** The internal SpawnableGraph subgraph (mounted under the hub). */\n\treadonly graph: SpawnableGraph<TIn, TOut>;\n}\n\n// ---------------------------------------------------------------------------\n// SpawnableGraph\n// ---------------------------------------------------------------------------\n\n/**\n * Graph subclass implementing {@link SpawnableBundle}'s topology.\n * Mounted under the hub at `opts.name` (default `\"spawnable\"`).\n *\n * Topology:\n * ```\n * <hub>\n * ├── spawns (TopicGraph; well-known well-named spawn topic)\n * └── <name> (SpawnableGraph)\n * ├── spawn-sub (SubscriptionGraph over hub::spawns::events)\n * ├── rejected (TopicGraph<SpawnRejection>)\n * ├── active-slot (Node<ReadonlyMap<id, AgentBundle>>)\n * └── spawn-{req.id}/ (mounted AgentGraph per active spawn)\n * ```\n */\nexport class SpawnableGraph<TIn, TOut> extends Graph {\n\treadonly spawnTopic: TopicGraph<TopicMessage<SpawnPayload<TIn>>>;\n\treadonly rejected: TopicGraph<SpawnRejection<TIn>>;\n\treadonly activeSlot: Node<ReadonlyMap<string, AgentBundle<TIn, TOut>>>;\n\tprivate readonly _spawnSub: SubscriptionGraph<TopicMessage<SpawnPayload<TIn>>>;\n\tprivate readonly _registry: PresetRegistryBundle<AgentSpec<TIn, TOut>>;\n\tprivate readonly _depthCap: number | undefined;\n\tprivate readonly _validate: ((req: TopicMessage<SpawnPayload<TIn>>) => boolean) | undefined;\n\tprivate _disposed = false;\n\n\tconstructor(opts: SpawnableOpts<TIn, TOut>) {\n\t\tconst name = opts.name ?? \"spawnable\";\n\t\tsuper(name);\n\n\t\tthis._registry = opts.registry;\n\t\tthis._depthCap = opts.depthCap;\n\t\tthis._validate = opts.validate;\n\n\t\t// Spawn topic on the hub (well-known name; lazy-created if absent).\n\t\tthis.spawnTopic = opts.hub.topic<TopicMessage<SpawnPayload<TIn>>>(SPAWNS_TOPIC);\n\n\t\t// Rejected topic is private to this spawnable subgraph.\n\t\tthis.rejected = topic<SpawnRejection<TIn>>(\"rejected\");\n\t\tthis.mount(\"rejected\", this.rejected);\n\n\t\t// Active-slot map. `equals: () => false` so each mutation emits a\n\t\t// fresh snapshot even when callers pass an identity-equal Map ref.\n\t\tconst activeSlotNode = node<ReadonlyMap<string, AgentBundle<TIn, TOut>>>([], {\n\t\t\tname: \"active-slot\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"spawnable_active_slot\"),\n\t\t\tinitial: new Map(),\n\t\t\tequals: () => false,\n\t\t});\n\t\tthis.add(activeSlotNode, { name: \"active-slot\" });\n\t\tthis.activeSlot = activeSlotNode;\n\n\t\t// Cursor-based subscription over hub.spawnTopic.events. Lives under\n\t\t// this spawnable subgraph (NOT the hub), so multiple spawnable\n\t\t// instances on the same hub get independent cursors.\n\t\t// Default `from: \"now\"` skips pre-construction retained requests —\n\t\t// older requests are NOT replayed unless the caller opts in.\n\t\tthis._spawnSub = subscription<TopicMessage<SpawnPayload<TIn>>>(\"spawn-sub\", this.spawnTopic, {\n\t\t\tfrom: opts.from ?? \"now\",\n\t\t});\n\t\tthis.mount(\"spawn-sub\", this._spawnSub);\n\n\t\t// Subscribe to `available` to process new requests; ack as we go.\n\t\tconst subRef = this._spawnSub;\n\t\tconst unsub = subRef.available.subscribe((msgs) => {\n\t\t\tif (this._disposed) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tconst items = m[1] as readonly TopicMessage<SpawnPayload<TIn>>[];\n\t\t\t\tif (items.length === 0) continue;\n\t\t\t\tfor (const req of items) {\n\t\t\t\t\tif (this._disposed) return;\n\t\t\t\t\tthis._processRequest(req);\n\t\t\t\t}\n\t\t\t\tsubRef.ack(items.length);\n\t\t\t}\n\t\t});\n\t\tthis.addDisposer(unsub);\n\t\tthis.addDisposer(() => {\n\t\t\tthis._disposed = true;\n\t\t});\n\t\t// Keepalive on the active-slot Node so external `cache` reads stay\n\t\t// current even when no one is subscribed.\n\t\tthis.addDisposer(keepalive(activeSlotNode));\n\t}\n\n\tprivate _processRequest(req: TopicMessage<SpawnPayload<TIn>>): void {\n\t\tif (this._disposed) return;\n\n\t\t// Custom validation.\n\t\tif (this._validate && !this._validate(req)) {\n\t\t\tthis.rejected.publish({ request: req, reason: \"schema validation failed\" });\n\t\t\treturn;\n\t\t}\n\n\t\t// Expiry check (only on entry — per-agent timeouts during run are a\n\t\t// future iteration; recipe-style composition with `timeout` covers\n\t\t// the in-flight case until then). Use `wallClockNs()` so test\n\t\t// suites that monkey-patch the central clock can pin expiry decisions.\n\t\tif (req.expiresAt != null) {\n\t\t\tconst expiry = Date.parse(req.expiresAt);\n\t\t\tif (!Number.isFinite(expiry)) {\n\t\t\t\tthis.rejected.publish({ request: req, reason: \"invalid expiresAt\" });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst nowMs = wallClockNs() / 1_000_000;\n\t\t\tif (nowMs >= expiry) {\n\t\t\t\tthis.rejected.publish({ request: req, reason: \"expired\" });\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Depth-cap check.\n\t\tconst currentMap =\n\t\t\t(this.activeSlot.cache as ReadonlyMap<string, AgentBundle<TIn, TOut>> | undefined) ??\n\t\t\tnew Map();\n\t\tif (this._depthCap != null && currentMap.size >= this._depthCap) {\n\t\t\tthis.rejected.publish({\n\t\t\t\trequest: req,\n\t\t\t\treason: `depth-cap exceeded (${currentMap.size}/${this._depthCap})`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Look up preset.\n\t\tconst spec = this._registry.registry.get(req.payload.presetId);\n\t\tif (!spec) {\n\t\t\tthis.rejected.publish({\n\t\t\t\trequest: req,\n\t\t\t\treason: `unknown presetId: ${req.payload.presetId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Mint and mount the agent. Slot name is derived from the request id\n\t\t// so it's traceable in describe / explain output.\n\t\tconst slotName = `spawn-${req.id}`;\n\t\tlet bundle: AgentBundle<TIn, TOut>;\n\t\ttry {\n\t\t\tbundle = agent<TIn, TOut>(this, { ...spec, name: slotName });\n\t\t} catch (e) {\n\t\t\tthis.rejected.publish({\n\t\t\t\trequest: req,\n\t\t\t\treason: `agent mint failed: ${(e as Error).message ?? \"unknown\"}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Update active-slot.\n\t\tconst updated = new Map(currentMap);\n\t\tupdated.set(req.id, bundle);\n\t\tthis.activeSlot.emit(updated);\n\n\t\t// Watch for completion BEFORE kicking, so a synchronous adapter that\n\t\t// drives status straight to \"done\" inside the kick still triggers\n\t\t// cleanup. Subscribe to status; on terminal, unmount + remove. Each\n\t\t// per-spawn statusUnsub releases inside `onTerminal` so we don't\n\t\t// accumulate dead disposers per-spawn over the spawnable's lifetime.\n\t\tlet statusUnsub: (() => void) | undefined;\n\t\tconst onTerminal = (stat: AgentStatus): void => {\n\t\t\tif (stat !== \"done\" && stat !== \"error\") return;\n\t\t\t// Idempotent — guard against double-fire.\n\t\t\tconst live =\n\t\t\t\t(this.activeSlot.cache as ReadonlyMap<string, AgentBundle<TIn, TOut>> | undefined) ??\n\t\t\t\tnew Map();\n\t\t\tif (!live.has(req.id)) return;\n\t\t\tbatch(() => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.remove(slotName);\n\t\t\t\t} catch {\n\t\t\t\t\t// Already removed (e.g., parent destroyed mid-flight).\n\t\t\t\t}\n\t\t\t\tconst next = new Map(live);\n\t\t\t\tnext.delete(req.id);\n\t\t\t\tthis.activeSlot.emit(next);\n\t\t\t});\n\t\t\t// Release the per-spawn status subscription now that the spawn\n\t\t\t// is finished — prevents disposer accumulation over many spawns.\n\t\t\tstatusUnsub?.();\n\t\t\tstatusUnsub = undefined;\n\t\t};\n\t\tstatusUnsub = bundle.status.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) onTerminal(m[1] as AgentStatus);\n\t\t\t}\n\t\t});\n\t\t// Defensive disposer — fires on SpawnableGraph.destroy() if the\n\t\t// spawn is still in-flight. `onTerminal` clears `statusUnsub` so\n\t\t// double-call is a no-op.\n\t\tthis.addDisposer(() => statusUnsub?.());\n\n\t\t// Kick the agent reactively.\n\t\tbundle.in.emit(req.payload.taskInput);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// spawnable() factory\n// ---------------------------------------------------------------------------\n\n/**\n * Constructs a {@link SpawnableGraph}, mounts it under `opts.hub` at\n * `opts.name` (default `\"spawnable\"`), and returns the\n * {@link SpawnableBundle} contract.\n *\n * **Composition with Phase 13 substrate:**\n * - Builds on **13.B** ({@link Message} envelope, {@link SPAWNS_TOPIC}).\n * - Builds on **13.G/H** ({@link agent}, {@link AgentBundle}).\n * - Builds on **13.H** ({@link presetRegistry}).\n * - The depth-cap gate is documented as a **13.D recipe**\n * (`valve(spawnTopic, derived([depthCounter], n => n < cap))`); inside\n * `spawnable()` the depth check is per-request so over-cap requests\n * surface on `rejected`. Callers wanting a hard cut (no rejection\n * signal) can wrap their publish path with `valve`.\n *\n * **Strategy-key axis (DS-13.I):** when `harnessLoop` is wired to a\n * spawnable, downstream `strategy.record(...)` calls should pass the\n * spawning agent's `presetId` for the {@link strategyKey} first axis.\n * Single-agent harness keeps using {@link DEFAULT_PRESET_ID} as before.\n *\n * @example\n * ```ts\n * const hub = messagingHub(\"hub\");\n * const presets = presetRegistry<AgentSpec<string, LLMResponse>>();\n * presets.put(\"researcher\", { name: \"researcher\", adapter: openai, systemPrompt: \"...\" });\n * presets.put(\"coder\", { name: \"coder\", adapter: anthropic, systemPrompt: \"...\" });\n *\n * const sp = spawnable({ hub, registry: presets, depthCap: 5 });\n *\n * // Trigger a spawn:\n * sp.spawnTopic.publish({\n * id: \"req-42\",\n * payload: { presetId: \"researcher\", taskInput: \"what is reactive graph composition?\" },\n * });\n *\n * // Observe active agents:\n * sp.activeSlot.subscribe((msgs) => { ... });\n *\n * // Observe rejections:\n * sp.rejected.events.subscribe((msgs) => { ... });\n * ```\n *\n * @category patterns\n */\nexport function spawnable<TIn = string, TOut = LLMResponse>(\n\topts: SpawnableOpts<TIn, TOut>,\n): SpawnableBundle<TIn, TOut> {\n\tconst graph = new SpawnableGraph<TIn, TOut>(opts);\n\topts.hub.mount(opts.name ?? \"spawnable\", graph);\n\treturn {\n\t\tspawnTopic: graph.spawnTopic,\n\t\tactiveSlot: graph.activeSlot,\n\t\trejected: graph.rejected,\n\t\tgraph,\n\t};\n}\n","/**\n * Phase 13.H — `agent(spec)` preset + `presetRegistry` sugar.\n *\n * Source: `archive/docs/SESSION-multi-agent-gap-analysis.md` G1 + G2.\n *\n * `agent()` is the ergonomic factory — given a parent Graph and an\n * `AgentSpec`, mints an `AgentGraph`, mounts it under the parent at\n * `spec.name`, and returns the `AgentBundle` contract.\n *\n * `presetRegistry()` is thin sugar over `reactiveMap` — a typed reactive\n * map of `<id, preset>`. Pairs with `materialize` (Phase 13.C) for\n * dynamic preset selection: callers store specs / factories / configs in\n * the registry and `materialize` mounts the matching one based on a\n * routing key.\n *\n * **Cross-cut #1 lock:** no `agent.run()` imperative sugar — caller-side\n * runtime is `bundle.in.emit(input)` + `awaitSettled(bundle.out)`.\n */\n\nimport { type ReactiveMapBundle, reactiveMap } from \"@graphrefly/pure-ts/extra\";\nimport type { Graph } from \"@graphrefly/pure-ts/graph\";\nimport type { LLMResponse } from \"../../utils/ai/adapters/core/types.js\";\nimport { type AgentBundle, AgentGraph, type AgentSpec } from \"./agent.js\";\n\n// ---------------------------------------------------------------------------\n// agent() factory\n// ---------------------------------------------------------------------------\n\n/**\n * Mints an {@link AgentGraph} from `spec`, mounts it under `parent` at\n * `spec.name`, and returns the {@link AgentBundle} contract.\n *\n * **Default type parameters.** When called without explicit type params,\n * `TIn` defaults to `string` and `TOut` to `LLMResponse` — the common\n * case where the caller writes a user message and reads the raw response.\n * Custom types require both `inMapper` and `outMapper` in the spec; the\n * default mappers throw at runtime if `TIn` / `TOut` aren't string /\n * LLMResponse.\n *\n * **Memory partition default.** Each `agent()` call mints its own\n * `AgentMemoryGraph` if `spec.memory` is omitted (private memory; the\n * common case). Pass an explicit shared instance — e.g.\n * `agent(parent, { ..., memory: sharedMemory })` for two agents — to\n * implement §29 handoff context transfer.\n *\n * **Reactive entry / exit:**\n * - `bundle.in.emit(input)` kicks the loop reactively (no imperative\n * `.run()` per cross-cut #1 lock).\n * - `awaitSettled(bundle.out, { skipCurrent: true })` resolves on the\n * first response after the kick. `skipCurrent` matters for the second\n * call onward — `out` caches the prior response.\n *\n * **Mounting.** The factory mounts under `parent.mount(spec.name, ...)`.\n * The slot name must be free on `parent` at construction time. To keep\n * the agent unmounted, construct `new AgentGraph(spec)` directly.\n *\n * @example\n * ```ts\n * import { agent, awaitSettled, Graph } from \"@graphrefly/graphrefly-ts\";\n *\n * const parent = new Graph(\"parent\");\n * const a = agent(parent, {\n * name: \"researcher\",\n * adapter: openaiAdapter,\n * systemPrompt: \"Research the user's question carefully.\",\n * });\n * a.in.emit(\"What's the capital of France?\");\n * const resp = await awaitSettled(a.out, { skipCurrent: true });\n * ```\n *\n * @category patterns\n */\nexport function agent<TIn = string, TOut = LLMResponse>(\n\tparent: Graph,\n\tspec: AgentSpec<TIn, TOut>,\n): AgentBundle<TIn, TOut> {\n\tconst graph = new AgentGraph<TIn, TOut>(spec);\n\tparent.mount(spec.name, graph);\n\treturn {\n\t\tin: graph.in,\n\t\tout: graph.out,\n\t\tstatus: graph.status,\n\t\tcost: graph.cost,\n\t\tgraph,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// presetRegistry()\n// ---------------------------------------------------------------------------\n\n/**\n * The bundle returned by {@link presetRegistry}. Wraps a `reactiveMap`\n * with imperative `put` / `remove` shortcuts and exposes the underlying\n * `registry` for direct reactive consumption (`.entries` is a\n * `Node<ReadonlyMap<string, TPreset>>`).\n *\n * Use the `registry.entries` Node directly with {@link materialize} (Phase\n * 13.C) — pass it as the `factories` argument when `TPreset` is itself\n * a `() => Graph` factory thunk, or transform via `derived` when\n * `TPreset` is a richer spec type that needs a `spec → factory` adapter.\n */\nexport interface PresetRegistryBundle<TPreset> {\n\t/**\n\t * The underlying reactive map. `registry.entries` is the\n\t * `Node<ReadonlyMap<string, TPreset>>` — pass directly to\n\t * {@link materialize} when preset shape matches the factories arg.\n\t */\n\treadonly registry: ReactiveMapBundle<string, TPreset>;\n\t/** Imperative add / replace. Always emits a fresh snapshot. */\n\tput(id: string, preset: TPreset): void;\n\t/** Imperative remove. Returns `true` if the id was present. */\n\tremove(id: string): boolean;\n}\n\n/**\n * Thin sugar over `reactiveMap` — a typed registry of `<id, preset>` for\n * agent / strategy / persona / skill catalogs.\n *\n * **Generic over preset shape.** `TPreset` is open — could be an\n * {@link AgentSpec}, a `() => Graph` factory thunk, a static config\n * object, or anything else. Decoupled from `agent()` so the same primitive\n * powers harnessLoop strategy registries, pipelineGraph stage catalogs,\n * etc.\n *\n * **Composes with `materialize`.** When `TPreset` is a `() => Graph`\n * factory, pass `registry.entries` directly to\n * {@link materialize} as the `factories` argument. When `TPreset` is a\n * spec, transform via `derived` to build a `Map<id, () => Graph>` adapter:\n *\n * ```ts\n * const presets = presetRegistry<AgentSpec<string, LLMResponse>>();\n * presets.put(\"researcher\", { name: \"researcher\", adapter, systemPrompt: \"...\" });\n *\n * // Adapter: spec → factory.\n * const factories = derived(\n * [presets.registry.entries],\n * ([m]) => new Map(\n * [...m].map(([id, spec]) => [id, () => new AgentGraph(spec)]),\n * ),\n * );\n * const slot = materialize(activeKey, factories, parent);\n * ```\n *\n * @param initial - Optional initial entries.\n * @returns {@link PresetRegistryBundle}.\n *\n * @category patterns\n */\nexport function presetRegistry<TPreset>(\n\tinitial?: ReadonlyMap<string, TPreset>,\n): PresetRegistryBundle<TPreset> {\n\tconst registry = reactiveMap<string, TPreset>({ name: \"presetRegistry\" });\n\tif (initial != null) {\n\t\tfor (const [id, preset] of initial) {\n\t\t\tregistry.set(id, preset);\n\t\t}\n\t}\n\treturn {\n\t\tregistry,\n\t\tput(id, preset) {\n\t\t\tregistry.set(id, preset);\n\t\t},\n\t\tremove(id) {\n\t\t\tif (!registry.has(id)) return false;\n\t\t\tregistry.delete(id);\n\t\t\treturn true;\n\t\t},\n\t};\n}\n","/**\n * Phase 13.G — `AgentBundle<TIn, TOut>` interface + `class AgentGraph extends Graph`.\n *\n * Source: `archive/docs/SESSION-multi-agent-gap-analysis.md` G1 lock B.\n *\n * Composes the existing substrate (`agentLoop`, `toolRegistry`,\n * `agentMemory`) into a typed inbox/outbox subgraph that other parts of a\n * multi-agent system can wire to. Sibling preset `agent()` (in\n * `./agents.ts`) is the ergonomic factory; this file is the contract.\n *\n * **Cross-cut #1 lock (no `agent.run()`):** caller-side runtime entry is\n * `bundle.in.emit(input)` + `awaitSettled(bundle.out)`. The legacy\n * `agentLoop.run()` is still available on `bundle.graph.loop` for\n * single-shot Promise-bridge use cases, but `agent()` does NOT expose a\n * `run()` method on the bundle.\n *\n * **Memory partition default:** private memory per agent (each `agent(...)`\n * call creates its own `AgentMemoryGraph` if none passed). Pass an explicit\n * shared instance for §29 handoff context-transfer.\n */\n\nimport { batch, DATA, INVALIDATE, type Node, node, RESOLVED } from \"@graphrefly/pure-ts/core\";\nimport { keepalive } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../../utils/ai/_internal.js\";\nimport type {\n\tInputTokens,\n\tLLMAdapter,\n\tLLMResponse,\n\tOutputTokens,\n\tTokenUsage,\n\tToolDefinition,\n} from \"../../utils/ai/adapters/core/types.js\";\nimport {\n\ttype SubscriptionGraph,\n\tsubscription,\n\ttype TopicGraph,\n\ttopic,\n} from \"../../utils/messaging/index.js\";\nimport { type AgentLoopGraph, agentLoop } from \"./agent-loop.js\";\nimport type { AgentMemoryGraph } from \"./agent-memory.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Lifecycle status of an {@link AgentGraph}.\n *\n * - `idle` — no input has been received since construction or last reset.\n * - `running` — inputs are flowing through the underlying agentLoop\n * (collapses the loop's `thinking` + `acting` substates so consumers\n * don't have to model the tool-call inner loop).\n * - `verifying` — verifier subgraph is in flight (reserved; lights up when\n * the verifier slot is added in a future wave per G7 recipe).\n * - `done` — the most recent input has settled with a verified response.\n * - `error` — the loop or verifier produced a terminal error.\n *\n * **Note (Phase 13.G, 2026-05-01):** v1 of `agent()` has no built-in\n * verifier slot — `verifying` is reserved but never produced. When a\n * verifier consumer surfaces, this enum widens (non-breaking type\n * widening; existing consumers see the same `idle | running | done | error`\n * subset).\n */\nexport type AgentStatus = \"idle\" | \"running\" | \"verifying\" | \"done\" | \"error\";\n\n/**\n * Aggregated cost for an agent's run, surfaced as a `Node<CostState>` on\n * the bundle. **Wraps the canonical {@link TokenUsage}** so consumers get\n * the full provider-disaggregated token classes (cache-read /\n * cache-write-5m / cache-write-1h / audio / image / video / tool-use /\n * reasoning / prediction-accepted / prediction-rejected / extensions /\n * auxiliary non-token costs / raw escape-hatch) without losing fidelity\n * for downstream pricing. USD conversion is a downstream `derived` over\n * `usage`.\n *\n * - `usage` — accumulated {@link TokenUsage} across all turns of the\n * current input.\n * - `turns` — number of completed agentLoop iterations (LLM invocations).\n *\n * **Counter scope:** resets to {@link ZERO_COST} on each new `bundle.in`\n * emit (per-input cost rather than per-agent-lifetime). Sum across multiple\n * inputs by snapshotting `cost` at `done` and accumulating externally —\n * a per-lifetime cost is a downstream `scan` over this.\n *\n * **Helpers.** Use `sumInputTokens(usage)` / `sumOutputTokens(usage)` from\n * `@graphrefly/graphrefly-ts` to flatten to scalars when the caller wants\n * a single number.\n */\nexport interface CostState {\n\treadonly usage: TokenUsage;\n\treadonly turns: number;\n}\n\nconst EMPTY_INPUT: InputTokens = Object.freeze({ regular: 0 });\nconst EMPTY_OUTPUT: OutputTokens = Object.freeze({ regular: 0 });\nconst EMPTY_USAGE: TokenUsage = Object.freeze({ input: EMPTY_INPUT, output: EMPTY_OUTPUT });\n\n/** Empty cost. Used as the initial value and the per-input reset baseline. */\nexport const ZERO_COST: CostState = Object.freeze({ usage: EMPTY_USAGE, turns: 0 });\n\n// ---------------------------------------------------------------------------\n// TokenUsage accumulator\n// ---------------------------------------------------------------------------\n\nfunction addOptional(a: number | undefined, b: number | undefined): number | undefined {\n\tif (a == null && b == null) return undefined;\n\treturn (a ?? 0) + (b ?? 0);\n}\n\nfunction addExtensions(\n\ta: Record<string, number> | undefined,\n\tb: Record<string, number> | undefined,\n): Record<string, number> | undefined {\n\tif (a == null && b == null) return undefined;\n\tconst out: Record<string, number> = { ...(a ?? {}) };\n\tfor (const [k, v] of Object.entries(b ?? {})) {\n\t\tout[k] = (out[k] ?? 0) + v;\n\t}\n\treturn out;\n}\n\n/**\n * Accumulates two {@link TokenUsage} snapshots. All field classes are\n * summed; optional fields propagate as `undefined` when absent from both\n * sides, otherwise treated as 0 for the missing side. `auxiliary` and\n * `extensions` merge by key. `raw` is dropped — it's a per-call escape\n * hatch, not summable.\n *\n * @category extra\n */\nexport function addUsage(a: TokenUsage, b: TokenUsage): TokenUsage {\n\tconst out: TokenUsage = {\n\t\tinput: {\n\t\t\tregular: a.input.regular + b.input.regular,\n\t\t\t...(addOptional(a.input.cacheRead, b.input.cacheRead) !== undefined && {\n\t\t\t\tcacheRead: addOptional(a.input.cacheRead, b.input.cacheRead) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.cacheWrite5m, b.input.cacheWrite5m) !== undefined && {\n\t\t\t\tcacheWrite5m: addOptional(a.input.cacheWrite5m, b.input.cacheWrite5m) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.cacheWrite1h, b.input.cacheWrite1h) !== undefined && {\n\t\t\t\tcacheWrite1h: addOptional(a.input.cacheWrite1h, b.input.cacheWrite1h) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.cacheWriteOther, b.input.cacheWriteOther) !== undefined && {\n\t\t\t\tcacheWriteOther: addOptional(a.input.cacheWriteOther, b.input.cacheWriteOther) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.audio, b.input.audio) !== undefined && {\n\t\t\t\taudio: addOptional(a.input.audio, b.input.audio) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.image, b.input.image) !== undefined && {\n\t\t\t\timage: addOptional(a.input.image, b.input.image) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.video, b.input.video) !== undefined && {\n\t\t\t\tvideo: addOptional(a.input.video, b.input.video) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.toolUse, b.input.toolUse) !== undefined && {\n\t\t\t\ttoolUse: addOptional(a.input.toolUse, b.input.toolUse) as number,\n\t\t\t}),\n\t\t\t...(addExtensions(a.input.extensions, b.input.extensions) !== undefined && {\n\t\t\t\textensions: addExtensions(a.input.extensions, b.input.extensions) as Record<string, number>,\n\t\t\t}),\n\t\t},\n\t\toutput: {\n\t\t\tregular: a.output.regular + b.output.regular,\n\t\t\t...(addOptional(a.output.reasoning, b.output.reasoning) !== undefined && {\n\t\t\t\treasoning: addOptional(a.output.reasoning, b.output.reasoning) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.output.audio, b.output.audio) !== undefined && {\n\t\t\t\taudio: addOptional(a.output.audio, b.output.audio) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.output.predictionAccepted, b.output.predictionAccepted) !== undefined && {\n\t\t\t\tpredictionAccepted: addOptional(\n\t\t\t\t\ta.output.predictionAccepted,\n\t\t\t\t\tb.output.predictionAccepted,\n\t\t\t\t) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.output.predictionRejected, b.output.predictionRejected) !== undefined && {\n\t\t\t\tpredictionRejected: addOptional(\n\t\t\t\t\ta.output.predictionRejected,\n\t\t\t\t\tb.output.predictionRejected,\n\t\t\t\t) as number,\n\t\t\t}),\n\t\t\t...(addExtensions(a.output.extensions, b.output.extensions) !== undefined && {\n\t\t\t\textensions: addExtensions(a.output.extensions, b.output.extensions) as Record<\n\t\t\t\t\tstring,\n\t\t\t\t\tnumber\n\t\t\t\t>,\n\t\t\t}),\n\t\t},\n\t\t...(addExtensions(a.auxiliary, b.auxiliary) !== undefined && {\n\t\t\tauxiliary: addExtensions(a.auxiliary, b.auxiliary) as Record<string, number>,\n\t\t}),\n\t};\n\treturn out;\n}\n\n/**\n * Spec for {@link agent} (in `./agents.ts`). Required fields are minimal —\n * `name` and `adapter` cover the common case where the input is a string\n * and the output is the raw `LLMResponse`. Optional fields shape the\n * agent's behavior:\n *\n * - **Mappers** (`inMapper` / `outMapper`) translate between caller-typed\n * `TIn` / `TOut` and the loop's internal `string` / `LLMResponse`. Default\n * identity mappers are wired automatically when `TIn` extends `string`\n * and `TOut` extends `LLMResponse`.\n * - **`tools`** is a reactive `NodeInput<readonly ToolDefinition[]>` —\n * `agent()` subscribes and reconciles the underlying `toolRegistry`'s\n * registrations on each emit. Static-array form is also accepted.\n * - **`memory`** is an explicit `AgentMemoryGraph` instance for shared\n * memory across agents (§29 handoff context transfer). Default: private\n * memory per agent (each `agent()` call mints its own).\n * - **`maxIterations`** caps the underlying agentLoop's tool-call inner\n * loop. Default 10 (matches `agentLoop`).\n * - **Verifier slot** is intentionally not in v1 — G7 reframe locks it as\n * a caller-composed recipe. When a real consumer surfaces, a\n * `verifier?: (out: Node<TOut>) => NodeInput<VerifierResult>` field\n * lands here additively.\n */\nexport interface AgentSpec<TIn, TOut> {\n\t/** Local mount name when wired to a parent graph. Required. */\n\treadonly name: string;\n\t/** LLM adapter for the underlying agentLoop. Required. */\n\treadonly adapter: LLMAdapter;\n\t/** Optional system prompt. Static today; reactive widening pending. */\n\treadonly systemPrompt?: string;\n\t/**\n\t * Optional reactive tool list. When a Node, the agent subscribes and\n\t * reconciles the underlying `toolRegistry` registrations on each emit\n\t * (additions registered, removals unregistered). When a static array,\n\t * tools are registered once at construction.\n\t */\n\treadonly tools?: Node<readonly ToolDefinition[]> | readonly ToolDefinition[];\n\t/**\n\t * Optional shared memory. Default: private (agent mints its own\n\t * `AgentMemoryGraph` if needed; not yet wired into the loop's chat —\n\t * that wiring is a separate follow-up). Pass an explicit instance to\n\t * share memory across agents for §29 handoff context transfer.\n\t */\n\treadonly memory?: AgentMemoryGraph<unknown>;\n\t/**\n\t * Maps caller-typed input → string for the underlying chat. Defaults to\n\t * identity when `TIn extends string`; required otherwise.\n\t */\n\treadonly inMapper?: (input: TIn) => string;\n\t/**\n\t * Maps the agentLoop's `LLMResponse` → caller-typed output. Defaults to\n\t * identity when `TOut extends LLMResponse`; required otherwise.\n\t */\n\treadonly outMapper?: (response: LLMResponse) => TOut;\n\t/** Caps tool-call inner-loop iterations. Default 10. */\n\treadonly maxIterations?: number;\n\t/** Escape hatch for non-core fields. Surfaced in `describe()` via meta. */\n\treadonly meta?: Record<string, unknown>;\n}\n\n/**\n * Public contract for an agent — typed inbox/outbox + lifecycle / cost\n * observables + the underlying graph for inspection / mounting.\n *\n * **Reactive entry:** caller writes to `in` (e.g. `bundle.in.emit(input)`).\n * The agent reactively kicks the underlying loop and produces `out`.\n *\n * **Reactive exit:** caller reads `out` via `subscribe` (continuous) or\n * `awaitSettled(out)` (single-shot). Both `in` and `out` stay SENTINEL\n * (`cache === undefined`) until the first real emission — no `null`\n * push-on-subscribe trap (per `feedback_use_prevdata_for_sentinel`).\n *\n * **Cross-graph wiring:** the bundle's `graph` is mountable under any\n * parent via `parent.mount(name, bundle.graph)`. After mount, the bundle's\n * Nodes are reachable through both the bundle reference (direct) and via\n * `parent.node(\"<name>::out\")` etc. (qualified path).\n */\nexport interface AgentBundle<TIn, TOut> {\n\treadonly in: Node<TIn>;\n\treadonly out: Node<TOut>;\n\treadonly status: Node<AgentStatus>;\n\treadonly cost: Node<CostState>;\n\treadonly graph: AgentGraph<TIn, TOut>;\n}\n\n// ---------------------------------------------------------------------------\n// AgentGraph\n// ---------------------------------------------------------------------------\n\nconst TERMINAL_STATUSES = new Set<AgentStatus>([\"done\", \"error\"]);\n\n/**\n * Graph subclass implementing {@link AgentBundle}. Mounts an inner\n * {@link AgentLoopGraph} at `loop/`; `in` / `out` / `status` / `cost`\n * surface the bundle contract as top-level nodes.\n *\n * Construction is internal — use the {@link agent} factory in\n * `./agents.ts` for normal use. Direct `new AgentGraph(name, spec)` is\n * supported for callers that want full control over mount order.\n *\n * **Topology:**\n * ```\n * <name>\n * ├── loop (AgentLoopGraph subgraph)\n * │ ├── chat\n * │ ├── tools\n * │ ├── status / turn / aborted / lastResponse / ...\n * ├── in (Node<TIn>, SENTINEL until first emit)\n * ├── out (Node<TOut>, SENTINEL until first response)\n * ├── status (Node<AgentStatus>, mirror of loop.status)\n * └── cost (Node<CostState>)\n * ```\n *\n * **Lifecycle:**\n * - On `in` emit: `inMapper` projects to `string`; appended to\n * `loop.chat`; loop status reset (`turn=0`, `aborted=false`,\n * `status=\"thinking\"`); per-input cost counters reset to zero.\n * - On `loop.lastResponse` emit: cost rolls forward; `out` emits\n * `outMapper(response)`.\n * - On `loop.status=\"done\"`: agent's status emits `\"done\"`.\n * - On `loop.status=\"error\"` (or any ERROR propagation): agent's status\n * emits `\"error\"`.\n */\nexport class AgentGraph<TIn, TOut> extends Graph {\n\t/** The agent's typed inbox. Writable; `in.emit(value)` kicks the loop. */\n\treadonly in: Node<TIn>;\n\t/** The agent's typed outbox. SENTINEL until first response. */\n\treadonly out: Node<TOut>;\n\t/** Lifecycle status (translated from the underlying loop's substates). */\n\treadonly status: Node<AgentStatus>;\n\t/** Cumulative cost for the current / most-recent input. */\n\treadonly cost: Node<CostState>;\n\t/** The underlying agentLoop — exposed for inspection / advanced wiring. */\n\treadonly loop: AgentLoopGraph;\n\t/** Optional shared memory subgraph (mounted at `memory/` if provided). */\n\treadonly memory: AgentMemoryGraph<unknown> | null;\n\n\tconstructor(spec: AgentSpec<TIn, TOut>, opts?: GraphOptions) {\n\t\tsuper(spec.name, opts);\n\n\t\t// --- 1. Mount the agentLoop subgraph. ------------------------------\n\t\tconst initialTools = Array.isArray(spec.tools)\n\t\t\t? (spec.tools as readonly ToolDefinition[])\n\t\t\t: undefined;\n\t\tthis.loop = agentLoop(`${spec.name}-loop`, {\n\t\t\tadapter: spec.adapter,\n\t\t\t...(spec.systemPrompt != null ? { systemPrompt: spec.systemPrompt } : {}),\n\t\t\t...(initialTools != null ? { tools: initialTools } : {}),\n\t\t\t...(spec.maxIterations != null ? { maxTurns: spec.maxIterations } : {}),\n\t\t});\n\t\tthis.mount(\"loop\", this.loop);\n\n\t\t// --- 2. Reactive tools subscription (if Node-form). ----------------\n\t\t// agentLoop's tools are static-array at construction; we reconcile\n\t\t// dynamically by subscribing to the user's reactive Node and\n\t\t// register/unregister against the inner toolRegistry.\n\t\tif (spec.tools != null && !Array.isArray(spec.tools)) {\n\t\t\tconst toolsNode = spec.tools as Node<readonly ToolDefinition[]>;\n\t\t\tconst registered = new Set<string>();\n\t\t\tconst unsubTools = toolsNode.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\tconst next = m[1] as readonly ToolDefinition[];\n\t\t\t\t\tconst nextNames = new Set(next.map((t) => t.name));\n\t\t\t\t\t// Unregister missing.\n\t\t\t\t\tfor (const name of registered) {\n\t\t\t\t\t\tif (!nextNames.has(name)) {\n\t\t\t\t\t\t\tthis.loop.tools.unregister(name);\n\t\t\t\t\t\t\tregistered.delete(name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Register new (idempotent guard via local tracking).\n\t\t\t\t\tfor (const tool of next) {\n\t\t\t\t\t\tif (!registered.has(tool.name)) {\n\t\t\t\t\t\t\tthis.loop.tools.register(tool);\n\t\t\t\t\t\t\tregistered.add(tool.name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.addDisposer(unsubTools);\n\t\t}\n\n\t\t// --- 3. Optional shared memory subgraph (passed through). ----------\n\t\t// v1: memory is mounted but NOT yet wired into the loop's chat — the\n\t\t// chat-context-from-memory glue is a separate follow-up. Mounting it\n\t\t// here gives the bundle a stable surface for §29 handoff (callers\n\t\t// can pass the SAME instance to multiple agents for shared memory).\n\t\tthis.memory = spec.memory ?? null;\n\t\tif (this.memory != null) {\n\t\t\tthis.mount(\"memory\", this.memory);\n\t\t}\n\n\t\t// --- 4. `in` — the typed inbox. ------------------------------------\n\t\t// SENTINEL until first emit; `equals: () => false` so re-emitting the\n\t\t// same value still kicks (no spurious dedup of repeat inputs).\n\t\tthis.in = node<TIn>([], {\n\t\t\tname: \"in\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"agent_in\"),\n\t\t\tequals: () => false,\n\t\t});\n\t\tthis.add(this.in, { name: \"in\" });\n\n\t\t// --- 5. `cost` — per-input token counters. -------------------------\n\t\tconst costNode = node<CostState>([], {\n\t\t\tname: \"cost\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"agent_cost\"),\n\t\t\tinitial: ZERO_COST,\n\t\t});\n\t\tthis.add(costNode, { name: \"cost\" });\n\t\tthis.cost = costNode;\n\n\t\t// --- 6. `out` — the typed outbox. ----------------------------------\n\t\t// Derived from `loop.lastResponse`. SENTINEL while `loop.lastResponse`\n\t\t// has never emitted a real response (F9 fix: the loop now stays\n\t\t// SENTINEL too — no more eager `null` placeholder), so the SENTINEL\n\t\t// detector inside the fn is `prevData[0] === undefined`. Between\n\t\t// runs, `loop.lastResponse.down([[INVALIDATE]])` clears that\n\t\t// `prevData` slot back to undefined, so this derived correctly gates\n\t\t// to RESOLVED on the next status=\"idle\" wave.\n\t\tconst outMapper = spec.outMapper ?? defaultOutMapper<TOut>();\n\t\tconst outNode = node<TOut>(\n\t\t\t[this.loop.lastResponse],\n\t\t\t(data, a, ctx) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tconst resp =\n\t\t\t\t\tbatch0 != null && batch0.length > 0\n\t\t\t\t\t\t? (batch0.at(-1) as LLMResponse | undefined)\n\t\t\t\t\t\t: (ctx.prevData[0] as LLMResponse | undefined);\n\t\t\t\tif (resp === undefined) {\n\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ta.emit(outMapper(resp));\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"out\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"agent_out\"),\n\t\t\t\t// Each in.emit may produce a structurally-equal response (e.g.\n\t\t\t\t// from a deterministic adapter) — disable framework dedup so\n\t\t\t\t// repeat emits propagate and `awaitSettled({skipCurrent:true})`\n\t\t\t\t// sees them. Callers can wrap with `distinctUntilChanged` if\n\t\t\t\t// they want change-only semantics.\n\t\t\t\tequals: () => false,\n\t\t\t},\n\t\t);\n\t\tthis.add(outNode, { name: \"out\" });\n\t\tthis.out = outNode;\n\n\t\t// --- 7. `status` — translated from loop.status. --------------------\n\t\t// Mirror via §32 pattern: a state node downstream consumers depend on,\n\t\t// reset and updated by an effect listening to loop.status.\n\t\tconst statusNode = node<AgentStatus>([], {\n\t\t\tname: \"status\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"agent_status\"),\n\t\t\tinitial: \"idle\",\n\t\t});\n\t\tthis.add(statusNode, { name: \"status\" });\n\t\tthis.status = statusNode;\n\n\t\tconst statusMirrorEff = node(\n\t\t\t[this.loop.status],\n\t\t\t(data, _a, ctx) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tconst loopStatus =\n\t\t\t\t\tbatch0 != null && batch0.length > 0\n\t\t\t\t\t\t? (batch0.at(-1) as string)\n\t\t\t\t\t\t: ((ctx.prevData[0] as string | undefined) ?? \"idle\");\n\t\t\t\tconst next: AgentStatus =\n\t\t\t\t\tloopStatus === \"idle\"\n\t\t\t\t\t\t? \"idle\"\n\t\t\t\t\t\t: loopStatus === \"thinking\" || loopStatus === \"acting\"\n\t\t\t\t\t\t\t? \"running\"\n\t\t\t\t\t\t\t: loopStatus === \"done\"\n\t\t\t\t\t\t\t\t? \"done\"\n\t\t\t\t\t\t\t\t: loopStatus === \"error\"\n\t\t\t\t\t\t\t\t\t? \"error\"\n\t\t\t\t\t\t\t\t\t: \"idle\";\n\t\t\t\tif (statusNode.cache !== next) statusNode.emit(next);\n\t\t\t},\n\t\t\t{ describeKind: \"effect\", meta: aiMeta(\"agent_status_mirror\") },\n\t\t);\n\t\tthis.addDisposer(keepalive(statusMirrorEff));\n\n\t\t// --- 8. Cost-rollup effect. ---------------------------------------\n\t\t// Rolls forward on each loop.lastResponse emission. Reads\n\t\t// loop.turn.cache for the iteration count (sole-owner-reactive-reader\n\t\t// per Phase 12 D1 lock — loop is mounted as a subgraph of this Graph).\n\t\t// SENTINEL gate: `prevData[0] === undefined` means no response has\n\t\t// ever been delivered for this run (post-INVALIDATE reset between\n\t\t// runs), so the rollup short-circuits.\n\t\tconst costEff = node(\n\t\t\t[this.loop.lastResponse],\n\t\t\t(data, _a, ctx) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tconst resp =\n\t\t\t\t\tbatch0 != null && batch0.length > 0\n\t\t\t\t\t\t? (batch0.at(-1) as LLMResponse | undefined)\n\t\t\t\t\t\t: (ctx.prevData[0] as LLMResponse | undefined);\n\t\t\t\tif (resp === undefined) return;\n\t\t\t\tconst prev = (costNode.cache as CostState | undefined) ?? ZERO_COST;\n\t\t\t\tconst turns = (this.loop.turn.cache as number | undefined) ?? prev.turns;\n\t\t\t\tconst next: CostState = {\n\t\t\t\t\tusage: resp.usage != null ? addUsage(prev.usage, resp.usage) : prev.usage,\n\t\t\t\t\tturns,\n\t\t\t\t};\n\t\t\t\tcostNode.emit(next);\n\t\t\t},\n\t\t\t{ describeKind: \"effect\", meta: aiMeta(\"agent_cost_rollup\") },\n\t\t);\n\t\tthis.addDisposer(keepalive(costEff));\n\n\t\t// --- 9. `in` → input queue → drain → kick the loop. ----------------\n\t\t// Phase 13.G/H + /qa N1(b) lock (2026-05-01): bundle.in is a\n\t\t// writable surface, but kicks are queued through an internal\n\t\t// hub-style topic + cursor subscription. Out-of-the-box queueing —\n\t\t// caller fires `in.emit(x)` while the agent is mid-run; the input\n\t\t// is parked on the queue and picked up when the loop returns to\n\t\t// `idle` / `done` / `error`. No mid-run reset / cost-leak hazard\n\t\t// (which the prior raw `in.subscribe → kick` path had).\n\t\t//\n\t\t// Topology:\n\t\t// `in` (state Node, writable) → `inputBridge` (subscribe →\n\t\t// publish) → `inputTopic` (TopicGraph<TIn>) → `inputSub`\n\t\t// (SubscriptionGraph<TIn>) → `drainEffect` (effect on\n\t\t// [inputSub.available, loop.status]) → loop kick.\n\t\tconst inMapper = spec.inMapper ?? defaultInMapper<TIn>();\n\t\tconst inputTopic: TopicGraph<TIn> = topic<TIn>(\"input-topic\");\n\t\tthis.mount(\"input-topic\", inputTopic);\n\t\tconst inputSub: SubscriptionGraph<TIn> = subscription<TIn>(\"input-sub\", inputTopic, {\n\t\t\tfrom: \"now\",\n\t\t});\n\t\tthis.mount(\"input-sub\", inputSub);\n\n\t\t// Bridge: `in.emit(x)` publishes to the topic. Validates the\n\t\t// caller-supplied input via `inMapper` at the boundary so the\n\t\t// type error surfaces in the caller's stack frame (not later\n\t\t// during drain). Per the F9 SENTINEL trap, `in` cache is\n\t\t// `undefined` until the first emit; push-on-subscribe delivers\n\t\t// nothing.\n\t\tconst inputBridge = this.in.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tconst input = m[1] as TIn;\n\t\t\t\t// Boundary type-check: throws if TIn is not string and no\n\t\t\t\t// inMapper supplied. Better here than at drain time so the\n\t\t\t\t// caller's `in.emit(...)` raises synchronously.\n\t\t\t\tinMapper(input);\n\t\t\t\tinputTopic.publish(input);\n\t\t\t}\n\t\t});\n\t\tthis.addDisposer(inputBridge);\n\n\t\t// Drain effect: when an input is pending AND the loop is ready\n\t\t// (`idle` / `done` / `error`), pull one and kick. Re-entrancy\n\t\t// guard via `loop.status` — `thinking` / `acting` skip.\n\t\tconst drainEffect = node(\n\t\t\t[inputSub.available, this.loop.status],\n\t\t\t(data, _a, ctx) => {\n\t\t\t\tconst availBatch = data[0];\n\t\t\t\tconst statusBatch = data[1];\n\t\t\t\tconst avail =\n\t\t\t\t\t(availBatch != null && availBatch.length > 0\n\t\t\t\t\t\t? (availBatch.at(-1) as readonly TIn[])\n\t\t\t\t\t\t: ((ctx.prevData[0] as readonly TIn[] | undefined) ?? [])) ?? [];\n\t\t\t\tconst stat =\n\t\t\t\t\t(statusBatch != null && statusBatch.length > 0\n\t\t\t\t\t\t? (statusBatch.at(-1) as string)\n\t\t\t\t\t\t: ((ctx.prevData[1] as string | undefined) ?? \"idle\")) ?? \"idle\";\n\t\t\t\tif (avail.length === 0) return;\n\t\t\t\tif (stat === \"thinking\" || stat === \"acting\") return;\n\t\t\t\tconst result = inputSub.pullAndAck(1);\n\t\t\t\tif (result.items.length === 0) return;\n\t\t\t\tconst input = result.items[0] as TIn;\n\t\t\t\tconst userMsg = inMapper(input);\n\t\t\t\tbatch(() => {\n\t\t\t\t\t// Reset per-input accumulators so cost/turns don't include\n\t\t\t\t\t// the previous input. `lastResponse` is reset via plain\n\t\t\t\t\t// `[[INVALIDATE]]` — under DS-13.5.A INVALIDATE both clears\n\t\t\t\t\t// `_cached` AND settles the consuming wave (decrements\n\t\t\t\t\t// `_dirtyDepCount` like RESOLVED), so dependents like\n\t\t\t\t\t// `out` / `costEff` fire on the next status transition\n\t\t\t\t\t// without staying wedged in DIRTY. Pre-DS-13.5.A this used\n\t\t\t\t\t// the `[[INVALIDATE], [RESOLVED]]` paired-reset workaround.\n\t\t\t\t\tthis.loop.lastResponse.down([[INVALIDATE]]);\n\t\t\t\t\tthis.loop.turn.emit(0);\n\t\t\t\t\tthis.loop.aborted.emit(false);\n\t\t\t\t\tcostNode.emit(ZERO_COST);\n\t\t\t\t\tthis.loop.chat.append(\"user\", userMsg);\n\t\t\t\t\tthis.loop.status.emit(\"thinking\");\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ describeKind: \"effect\", meta: aiMeta(\"agent_input_drain\") },\n\t\t);\n\t\tthis.addDisposer(keepalive(drainEffect));\n\n\t\t// `out` and `status` keepalives are unnecessary because the cost /\n\t\t// status effects above already activate `loop.lastResponse` and\n\t\t// `loop.status` — the derived `out` reads from a kept-alive source.\n\t\t// We do keep `out` alive explicitly so `awaitSettled(bundle.out,\n\t\t// { skipCurrent: true })` works even when no other consumer\n\t\t// subscribes between input and response.\n\t\tthis.addDisposer(keepalive(this.out));\n\n\t\t// Surface in describe.\n\t\tvoid TERMINAL_STATUSES;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Default mappers\n// ---------------------------------------------------------------------------\n\n/**\n * Default `inMapper` for `TIn extends string`. Asserts the runtime type at\n * the boundary so callers who omit `inMapper` for a non-string `TIn` get a\n * clear error rather than a silent passthrough.\n */\nfunction defaultInMapper<TIn>(): (input: TIn) => string {\n\treturn (input) => {\n\t\tif (typeof input !== \"string\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t`agent: inMapper is required when TIn is not a string (got ${typeof input}). Pass spec.inMapper.`,\n\t\t\t);\n\t\t}\n\t\treturn input;\n\t};\n}\n\n/**\n * Default `outMapper` for `TOut extends LLMResponse`. Asserts the response\n * shape at the boundary; callers with a non-LLMResponse `TOut` must\n * provide `outMapper`.\n */\nfunction defaultOutMapper<TOut>(): (response: LLMResponse) => TOut {\n\treturn (response) => response as unknown as TOut;\n}\n","/**\n * Reactive agent loop — autonomous multi-turn LLM agent with tool execution.\n */\n\nexport type AgentLoopStatus = \"idle\" | \"thinking\" | \"acting\" | \"done\" | \"error\";\n\nimport {\n\tbatch,\n\tDATA,\n\tERROR,\n\tINVALIDATE,\n\ttype Node,\n\tnode,\n\tnode as nodeFactory,\n\tplaceholderArgs,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport { fromAny, keepalive, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { awaitSettled } from \"../../base/sources/settled.js\";\nimport { aiMeta } from \"../../utils/ai/_internal.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMResponse,\n\tToolCall,\n\tToolDefinition,\n} from \"../../utils/ai/adapters/core/types.js\";\nimport { type ChatStreamGraph, chatStream } from \"../../utils/ai/agents/chat-stream.js\";\nimport { type ToolResult, toolExecution } from \"../../utils/ai/agents/tool-execution.js\";\nimport { type ToolRegistryGraph, toolRegistry } from \"../../utils/ai/agents/tool-registry.js\";\n\nexport type { ToolResult } from \"../../utils/ai/agents/tool-execution.js\";\n\n// ---------------------------------------------------------------------------\n// agentLoop\n// ---------------------------------------------------------------------------\n\nexport type AgentLoopOptions = {\n\tgraph?: GraphOptions;\n\tadapter: LLMAdapter;\n\ttools?: readonly ToolDefinition[];\n\tsystemPrompt?: string;\n\tmaxTurns?: number;\n\tstopWhen?: (response: LLMResponse) => boolean;\n\tonToolCall?: (call: ToolCall) => void;\n\tmaxMessages?: number;\n\tmodel?: string;\n\ttemperature?: number;\n\tmaxTokens?: number;\n\t/**\n\t * Reactive tool-call splice (COMPOSITION-GUIDE §31 \"interception is security\").\n\t * When set, the raw `toolCalls` node is piped through this transform before\n\t * reaching the executor. The transform is a pure reactive composition —\n\t * `(calls: Node<readonly ToolCall[]>) => Node<readonly ToolCall[]>` — so the\n\t * gate is visible in `describe()` / `explain()` as a real edge (no hidden\n\t * imperative wraps; §24).\n\t *\n\t * Typical uses:\n\t * - **Filter / block** — `derived([calls, policy], ([raw, p]) => raw.filter(p))`\n\t * - **Throttle / debounce** — `throttle(calls, windowMs)`\n\t * - **Human-in-the-loop approval** — pipe through a `gate` controller so\n\t * calls wait for human approval before reaching the executor.\n\t *\n\t * The public `agent.toolCalls` node surfaces the POST-intercept stream, so\n\t * audit / telemetry consumers see what the executor actually runs. The raw\n\t * pre-intercept stream is not exposed — tests that need it should run\n\t * without `interceptToolCalls` set (the identity case).\n\t */\n\tinterceptToolCalls?: (calls: Node<readonly ToolCall[]>) => Node<readonly ToolCall[]>;\n};\n\n/**\n * Reactive agent loop.\n *\n * The loop is a reactive state machine wired entirely from graph primitives:\n * `chat.messages` + `tools.schemas` + gating state feed a `promptInput`\n * derived; `switchMap` turns non-null inputs into an LLM invocation via\n * `fromAny(adapter.invoke(...))`. The LLM response drives chat writes and\n * status transitions via effects. Tool calls flow through a reactive\n * executor (`retrySource` + `rescue`) that retries once on error and\n * surfaces terminal errors as JSON-shaped `ToolResult` payloads for the\n * LLM to react to.\n *\n * **No imperative control flow inside the reactive layer** (spec §5.8-5.12):\n * no `while` loops, no manual `await adapter.invoke`, no polling.\n * `agent.run()` is a thin `awaitSettled` bridge so callers can still `await`\n * the loop if they want a Promise.\n *\n * Public surface:\n * - `chat` / `tools` — subgraphs (imperative `append` at boundary, reactive `executeReactive` for tool invocation)\n * - `status` / `turn` / `aborted` — state nodes with explicit initials\n * - `lastResponse` / `toolCalls` / `toolResults` — reactive outputs (SENTINEL until first emission; callers use `awaitSettled` / `subscribe`)\n * - `run(userMessage?, signal?)` — optional user append + Promise bridge\n * - `abort()` — imperative abort shim; flips `aborted` state\n *\n * **Lifecycle: single-mount.** `AgentLoopGraph` instances expect to be\n * constructed once and used until `destroy()`. The internal closure mirrors\n * (`latestTurn` / `latestAborted` / `latestStatus`) are wired by\n * subscribe-and-capture at construction time; their `addDisposer`-registered\n * subscriptions are torn down on subgraph unmount or `destroy()`. After\n * teardown the mirrors freeze at their last value, so re-using a destroyed\n * instance — calling `run()` again, or remounting under a new parent —\n * would silently feed stale mirror data into reactive fn bodies. If you\n * need to \"reset\" an agent, build a fresh `AgentLoopGraph` instance instead\n * of recycling.\n */\nexport class AgentLoopGraph extends Graph {\n\treadonly chat: ChatStreamGraph;\n\treadonly tools: ToolRegistryGraph;\n\n\t/** Current agent status. `initial: \"idle\"` — always has a real value. */\n\treadonly status: Node<AgentLoopStatus>;\n\t/** Turn count (completed LLM invocations this run). `initial: 0`. */\n\treadonly turn: Node<number>;\n\t/** Aborted flag; flipped by `abort()` or external `AbortSignal`. `initial: false`. */\n\treadonly aborted: Node<boolean>;\n\n\t/**\n\t * Most recent LLM response. State-backed mirror driven by the response\n\t * effect. **Stays SENTINEL** (`cache === undefined`, no DATA emitted)\n\t * until the first real response — bridge subscribers see no spurious\n\t * push-on-subscribe DATA. After a real response, holds the latest\n\t * `LLMResponse`. Reset between `run()` calls via `[[INVALIDATE]]` (clears\n\t * cache back to SENTINEL) so a second run with a pre-aborted signal\n\t * cannot leak the prior run's response. Bridge with\n\t * `awaitSettled(lastResponse)` for the first DATA as a Promise; consumers\n\t * inside reactive fns gate on `ctx.prevData[i] === undefined`.\n\t */\n\treadonly lastResponse: Node<LLMResponse>;\n\t/** Tool-call batch emitted by the most recent LLM response. SENTINEL. */\n\treadonly toolCalls: Node<readonly ToolCall[]>;\n\t/** Tool-result batch (one entry per call) after reactive execution. SENTINEL. */\n\treadonly toolResults: Node<readonly ToolResult[]>;\n\n\tprivate readonly _terminalResult: Node<LLMResponse>;\n\tprivate readonly _disposeRunWiring: () => void;\n\t/** Guards against overlapping `run()` calls. */\n\tprivate _running = false;\n\t/**\n\t * Abort controller for the currently-running `adapter.invoke`. Minted per\n\t * switchMap project; aborted when the reactive `aborted` node flips true\n\t * OR when the caller's external `AbortSignal` fires. Threaded into\n\t * `adapter.invoke({ signal })` AND `fromAny(promise, { signal })`, so the\n\t * reactive layer sees ERROR when the wire call is cancelled.\n\t */\n\tprivate _currentAbortController: AbortController | null = null;\n\n\tconstructor(name: string, opts: AgentLoopOptions) {\n\t\tsuper(name, opts.graph);\n\n\t\t// Mount chat subgraph\n\t\tthis.chat = chatStream(`${name}-chat`, { maxMessages: opts.maxMessages });\n\t\tthis.mount(\"chat\", this.chat);\n\n\t\t// Mount tool registry subgraph\n\t\tthis.tools = toolRegistry(`${name}-tools`);\n\t\tthis.mount(\"tools\", this.tools);\n\n\t\tif (opts.tools) {\n\t\t\tfor (const tool of opts.tools) {\n\t\t\t\tthis.tools.register(tool);\n\t\t\t}\n\t\t}\n\n\t\t// --- State nodes (always have a real value; explicit initials) ---\n\t\tthis.status = node<AgentLoopStatus>([], {\n\t\t\t...{\n\t\t\t\tname: \"status\",\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tmeta: aiMeta(\"agent_status\"),\n\t\t\t},\n\t\t\tinitial: \"idle\",\n\t\t});\n\t\tthis.add(this.status, { name: \"status\" });\n\n\t\tthis.turn = node<number>([], {\n\t\t\t...{\n\t\t\t\tname: \"turn\",\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tmeta: aiMeta(\"agent_turn_count\"),\n\t\t\t},\n\t\t\tinitial: 0,\n\t\t});\n\t\tthis.add(this.turn, { name: \"turn\" });\n\n\t\tthis.aborted = node<boolean>([], {\n\t\t\t...{\n\t\t\t\tname: \"aborted\",\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tmeta: aiMeta(\"agent_aborted\"),\n\t\t\t},\n\t\t\tinitial: false,\n\t\t});\n\t\tthis.add(this.aborted, { name: \"aborted\" });\n\n\t\t// --- Reactive pipeline ---\n\t\t//\n\t\t// **Read pattern (Phase 12 D1 lock + F2 fix 2026-05-01).** State\n\t\t// scratchpad held on this `AgentLoopGraph` (turn / aborted / chat /\n\t\t// tools) is read inside reactive fn bodies via either:\n\t\t// (a) `data[i]` / `ctx.prevData[i]` for declared deps, OR\n\t\t// (b) sole-owner `.cache` reads on subgraph-mounted state Nodes\n\t\t// (chat / tools mounted as subgraphs of this Graph; the agent\n\t\t// is the sole owner; promptInput / effResponse / effResults\n\t\t// live in the same enclosing constructor scope — sanctioned\n\t\t// form per Phase 12 D1 read-pattern lock).\n\t\t//\n\t\t// Closure mirrors (`latestTurn` / `latestAborted` / `latestStatus`)\n\t\t// are kept ONLY for fields where (b) doesn't simplify the call site\n\t\t// — turn / aborted / status are state Nodes registered on `this`\n\t\t// directly (not subgraphs), and the closure form keeps\n\t\t// effResponse's batch logic readable. They are CORRECT but are NOT\n\t\t// safe under nested drains (the subscribe handler may not have run\n\t\t// yet when a downstream fn reads the closure). For nested-drain-\n\t\t// reachable reads (promptInput, called via `agentLoop.run` from\n\t\t// inside another graph's reactive subscribe handler), prefer (a) or\n\t\t// (b) over the closure mirror. F2 root cause: chat.messages.cache\n\t\t// is updated DURING the DATA-settle phase (before subscribers\n\t\t// run), so `.cache` reads are always at least as fresh as closure\n\t\t// mirrors. See `optimizations.md` \"Phase 13 design-session inputs\n\t\t// from §13.M lock-test\" F2.\n\t\t//\n\t\t// **Pattern note on `latestTurn` staleness under in-batch reads.**\n\t\t// Effect 1 emits `turnNode.emit(next)` inside its batch; Effect 2\n\t\t// reads `latestTurn` on the following wave (after toolResults\n\t\t// settle). Because batch drain is FIFO, `turnSub`'s handler runs\n\t\t// before Effect 2's next wave fires, so `latestTurn` is up-to-date\n\t\t// by the time Effect 2 reads it. This invariant is stable as long\n\t\t// as `turnNode.emit` remains inside Effect 1's batch — a future\n\t\t// refactor that un-batches the emit would regress silently.\n\t\tlet latestTurn = 0;\n\t\tconst turnSub = this.turn.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) if (m[0] === DATA) latestTurn = m[1] as number;\n\t\t});\n\t\tlet latestAborted = false;\n\t\tconst abortedSub = this.aborted.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) if (m[0] === DATA) latestAborted = m[1] as boolean;\n\t\t});\n\n\t\tconst adapter = opts.adapter;\n\t\tconst systemPrompt = opts.systemPrompt;\n\t\tconst model = opts.model;\n\t\tconst temperature = opts.temperature;\n\t\tconst maxTokens = opts.maxTokens;\n\t\tconst maxTurns = opts.maxTurns ?? 10;\n\t\tconst stopWhen = opts.stopWhen;\n\n\t\t// Capture `this` for closures that don't bind `this`.\n\t\tconst chat = this.chat;\n\t\tconst tools = this.tools;\n\t\tconst statusNode = this.status;\n\t\tconst turnNode = this.turn;\n\t\tconst abortedNode = this.aborted;\n\n\t\t// promptInput: STATUS is the only reactive trigger — chat.messages,\n\t\t// tools.schemas, turn, aborted are sampled via closure-held mirrors\n\t\t// (all populated by subscribe-and-capture above). This prevents the\n\t\t// classic feedback cycle (COMPOSITION-GUIDE §7): if chat.messageCount\n\t\t// were a reactive dep here, effect 1's `chat.append` would trigger a\n\t\t// promptInput wave, which under effect-1's batch would see status\n\t\t// STILL \"thinking\" (pre-drain) and fire a spurious LLM invocation.\n\t\t// By gating only on status, chat writes don't re-trigger — only\n\t\t// explicit status transitions do.\n\t\tconst promptInput: Node<InvokeInput> = nodeFactory<InvokeInput>(\n\t\t\t[statusNode],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\tconst stat = readLatest<AgentLoopStatus>(data, ctx.prevData, 0, \"idle\");\n\t\t\t\tif (stat !== \"thinking\" || latestAborted || latestTurn >= maxTurns) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// F2 fix (2026-05-01): under nested drains, the closure mirrors\n\t\t\t\t// `latestMessages` / `latestSchemas` lag the actual node state —\n\t\t\t\t// messagesSub / schemasSub subscribers may not have run yet when\n\t\t\t\t// promptInput fires (the drain processes status's downstream\n\t\t\t\t// before chat.messages's subscribers fire, even though\n\t\t\t\t// chat.messages.cache is already settled). Read `.cache`\n\t\t\t\t// directly per Phase 12 D1 read-pattern lock: chat / tools are\n\t\t\t\t// mounted as subgraphs of this AgentLoopGraph (sole owner) and\n\t\t\t\t// promptInput is a reactive reader in the same enclosing\n\t\t\t\t// constructor scope — sanctioned `.cache` form. See\n\t\t\t\t// `optimizations.md` \"Phase 13 design-session inputs from §13.M\n\t\t\t\t// lock-test\" F2.\n\t\t\t\tconst messages = (this.chat.messages.cache as readonly ChatMessage[] | undefined) ?? [];\n\t\t\t\tif (messages.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst schemas = (this.tools.schemas.cache as readonly ToolDefinition[] | undefined) ?? [];\n\t\t\t\tactions.emit({ messages, tools: schemas });\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"promptInput\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"agent_prompt_input\", {\n\t\t\t\t\t// State this fn body samples beyond its declared `statusNode`\n\t\t\t\t\t// dep. `aborted` / `turn` come from §28 closure mirrors\n\t\t\t\t\t// (`latestAborted` / `latestTurn`); `chat.messages` /\n\t\t\t\t\t// `tools.schemas` come from sole-owner `.cache` reads\n\t\t\t\t\t// (Phase 12 D1 lock + F2 fix; see comment block above).\n\t\t\t\t\t// Listed here so inspection tooling can surface fold-in\n\t\t\t\t\t// state without grepping source.\n\t\t\t\t\tclosureReads: [\"aborted\", \"turn\", \"chat.messages\", \"tools.schemas\"],\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tconst llmResponse: Node<LLMResponse> = switchMap(\n\t\t\tpromptInput,\n\t\t\t(input) => {\n\t\t\t\tconst controller = new AbortController();\n\t\t\t\tthis._currentAbortController = controller;\n\t\t\t\tif (latestAborted) {\n\t\t\t\t\tcontroller.abort(new Error(\"agentLoop: aborted\"));\n\t\t\t\t}\n\t\t\t\t// Wave A Unit B-CC fix: drop the `Promise.resolve(adapter.invoke(...))`\n\t\t\t\t// wrapper. `adapter.invoke` returns a `NodeInput<LLMResponse>`\n\t\t\t\t// (Promise | Node | raw). `fromAny` already handles all three\n\t\t\t\t// shapes; the manual `Promise.resolve` wrapper would force a\n\t\t\t\t// Node-returning adapter into an extra microtask hop and lose\n\t\t\t\t// reactivity (see Unit 11 + Unit 1 for the parallel cleanup).\n\t\t\t\treturn fromAny(\n\t\t\t\t\tadapter.invoke(input.messages, {\n\t\t\t\t\t\ttools: input.tools.length > 0 ? input.tools : undefined,\n\t\t\t\t\t\tsystemPrompt,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttemperature,\n\t\t\t\t\t\tmaxTokens,\n\t\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t\t}),\n\t\t\t\t\t{ signal: controller.signal },\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ equals: () => false },\n\t\t);\n\n\t\t// State mirror for `lastResponse` — exists for **cross-run reset\n\t\t// semantics**, NOT the §32 mid-wave hazard.\n\t\t//\n\t\t// Why: `llmResponse` is a switchMap output; its cache persists across\n\t\t// `run()` calls (switchMap's output node has no built-in reset path —\n\t\t// the cache stays at the last DATA the inner emitted). A second\n\t\t// `run()` with a pre-aborted signal would otherwise have\n\t\t// `_terminalResult` evaluate `stat=done` (driven by `effAbort`) +\n\t\t// `resp=<prior run's response>` (cached on `llmResponse`) and resolve\n\t\t// the Promise with stale data instead of rejecting with AbortError.\n\t\t// The mirror is **reset via `[[INVALIDATE]]`** in `run()`'s reset\n\t\t// batch — INVALIDATE clears `_cached` back to `undefined` (SENTINEL)\n\t\t// AND clears the `prevData` slot on every dependent (`_terminalResult`,\n\t\t// `toolCallsRaw`), so the abort path correctly emits\n\t\t// `[[ERROR, AbortError]]` from terminalResult's `stat=\"done\" &&\n\t\t// prevData[lastResponse] === undefined → ERROR` guard.\n\t\t//\n\t\t// **No `T | null` placeholder.** Per `feedback_use_prevdata_for_sentinel`\n\t\t// + COMPOSITION-GUIDE §1a, the SENTINEL state IS the \"never sent\n\t\t// real DATA yet\" signal. An eager `initial: null` would push `[null]`\n\t\t// to every fresh subscriber — a footgun for bridge subscribers that\n\t\t// would otherwise need `if (resp == null) continue` guards. Stay\n\t\t// SENTINEL; consumers detect \"no response yet\" via\n\t\t// `ctx.prevData[i] === undefined` (or `cache === undefined` outside\n\t\t// reactive fns). F9 lock-test (`multi-agent-example.test.ts` test 5)\n\t\t// pins this invariant.\n\t\t//\n\t\t// What this does NOT solve: the §32 mid-wave \"stale peer-read\"\n\t\t// hazard. Investigation (2026-04-25) confirmed `_dirtyDepCount`\n\t\t// gating in `_maybeRunFnOnSettlement` already prevents that — when\n\t\t// `effResponse`'s nested batch fires `status=\"done\"` mid-iteration,\n\t\t// terminal's status dep settles but its `llmResponse` (or mirror)\n\t\t// dep is still DIRTY from Phase 1, so the fn does not run until\n\t\t// Phase 2 visits both deps. Verified by fast-check invariant `#12b\n\t\t// nested-drain-peer-consistency-compound` and by the multi-turn\n\t\t// `executes tool calls and loops` test passing under either dep\n\t\t// shape (`[statusNode, llmResponse]` or `[statusNode, lastResponseState]`).\n\t\t//\n\t\t// Verified by: QA C3 regression tests (`run() with pre-aborted\n\t\t// signal rejects AbortError` and `second run() with pre-aborted\n\t\t// signal rejects AbortError (no stale response leak)`) — both\n\t\t// fail when `_terminalResult` is rewired to depend on `llmResponse`\n\t\t// directly. See COMPOSITION-GUIDE §32 (cross-wave reset reframe).\n\t\tconst lastResponseState = node<LLMResponse>([], {\n\t\t\tname: \"lastResponse\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"agent_last_response\"),\n\t\t});\n\t\tthis.lastResponse = lastResponseState;\n\n\t\t// toolCalls: raw node that emits DATA only when status === \"acting\" and\n\t\t// the current response has tool calls. Otherwise emits RESOLVED. Using\n\t\t// DATA([]) for the idle case would cause switchMap(toolCalls) to\n\t\t// re-dispatch its inner (creating a fresh node([], { initial: [] }) source whose\n\t\t// emissions re-trigger effects downstream). RESOLVED keeps the inner\n\t\t// alive and lets upstream waves pass through without re-dispatch.\n\t\t// Inner raw tool-call stream — name `toolCallsRaw` so the post-intercept\n\t\t// public surface (`this.toolCalls`) is unambiguous in `describe()`.\n\t\t// QA-fix: previously the inner was named `\"toolCalls\"`, which collided\n\t\t// with `this.toolCalls` if the user-supplied interceptor returned a\n\t\t// wrapper that internally retained a reference to this raw node —\n\t\t// `describe()` would render two distinct nodes both labeled `\"toolCalls\"`.\n\t\tconst toolCallsRaw = nodeFactory<readonly ToolCall[]>(\n\t\t\t[lastResponseState, statusNode],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\t// SENTINEL guard: `lastResponseState` stays `undefined` (cache\n\t\t\t\t// + prevData) until the first real response. `readLatest`'s\n\t\t\t\t// fallback returns `undefined` here so the no-DATA branch is\n\t\t\t\t// indistinguishable from the protocol SENTINEL — both gate to\n\t\t\t\t// RESOLVED. Per `feedback_use_prevdata_for_sentinel`.\n\t\t\t\tconst resp = readLatest<LLMResponse | undefined>(data, ctx.prevData, 0, undefined);\n\t\t\t\tconst stat = readLatest<AgentLoopStatus>(data, ctx.prevData, 1, \"idle\");\n\t\t\t\tif (stat !== \"acting\") {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst calls = resp?.toolCalls;\n\t\t\t\tif (calls == null || calls.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit(calls);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"toolCallsRaw\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"agent_tool_calls_raw\"),\n\t\t\t},\n\t\t);\n\t\t// Reactive splice (D9 / COMPOSITION-GUIDE §31). When `interceptToolCalls`\n\t\t// is set, the raw tool-call stream is transformed in the graph — the\n\t\t// executor sees the gated stream, and `agent.toolCalls` surfaces the\n\t\t// post-intercept view so audit / telemetry match reality.\n\t\tconst gatedToolCallsNode = opts.interceptToolCalls\n\t\t\t? opts.interceptToolCalls(toolCallsRaw)\n\t\t\t: toolCallsRaw;\n\t\tthis.toolCalls = gatedToolCallsNode;\n\n\t\t// Delegate per-call fan-out + retry + rescue to the `toolExecution`\n\t\t// primitive. `toolCallsRaw` already gates empty batches to RESOLVED,\n\t\t// so `toolExecution`'s \"non-empty batch only\" contract is satisfied\n\t\t// upstream. `retryCount: 1` matches the pre-extraction behaviour\n\t\t// (one retry after first failure = 2 attempts total).\n\t\tconst toolResultsNode: Node<readonly ToolResult[]> = toolExecution({\n\t\t\ttoolCalls: gatedToolCallsNode,\n\t\t\ttools,\n\t\t\tretryCount: 1,\n\t\t});\n\t\tthis.toolResults = toolResultsNode;\n\n\t\t// --- State-machine effects ---\n\t\t// Effect 1: LLM response landed → write lastResponse mirror + chat,\n\t\t// transition status, increment turn. Emission ORDER inside the batch\n\t\t// matters (drain is FIFO under any outer-batch depth):\n\t\t// 1. `lastResponseState.emit(response)` FIRST — so when the drain\n\t\t// fires the status=done wave later in the queue, `_terminalResult`'s\n\t\t// dep on `lastResponseState` has already been updated.\n\t\t// 2. `statusNode.emit(nextStatus)` — drives state machine.\n\t\t// 3. `turnNode.emit(next)` — counter.\n\t\t// 4. `chat.append(...)` LAST — chat.messageCount wave now sees the\n\t\t// new status (so `promptInput` gates correctly).\n\t\t// Without (1) first, `_terminalResult` reads stale `prevData` for\n\t\t// lastResponse when status transitions synchronously during drain.\n\t\t//\n\t\t// **Invariant independence from outer batch depth.** `downWithBatch`\n\t\t// preserves FIFO drain order regardless of nesting — whether the\n\t\t// outer batch is at depth 0 (common: Promise microtask) or depth >0\n\t\t// (user-composed `batch()` scope around `agent.run()`), the emissions\n\t\t// above drain in the order they were enqueued. The state-mirror\n\t\t// pattern holds in both cases.\n\t\t//\n\t\t// **Abort guard (C2 defense-in-depth).** If the `aborted` state has\n\t\t// flipped true between `adapter.invoke`'s Promise resolution and this\n\t\t// effect firing (micro-race), bail out so we don't append to chat or\n\t\t// execute tool calls for an abandoned run. The controller.abort() in\n\t\t// effAbort also fires the signal, which causes `fromAny` to emit\n\t\t// ERROR — but that ERROR propagation arrives in a separate wave, so\n\t\t// this guard covers the \"Promise already resolved before abort hit\n\t\t// the controller\" case.\n\t\tconst effResponse = node(\n\t\t\t[llmResponse],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tif (latestAborted) return;\n\t\t\t\tconst response = data[0] as LLMResponse;\n\t\t\t\tconst next = latestTurn + 1;\n\t\t\t\tconst hasToolCalls = response.toolCalls != null && response.toolCalls.length > 0;\n\t\t\t\tconst naturalStop =\n\t\t\t\t\tresponse.finishReason === \"end_turn\" &&\n\t\t\t\t\t(!response.toolCalls || response.toolCalls.length === 0);\n\t\t\t\tconst customStop = stopWhen?.(response) === true;\n\t\t\t\tconst capReached = next >= maxTurns;\n\t\t\t\tconst nextStatus: AgentLoopStatus =\n\t\t\t\t\tcustomStop || naturalStop || !hasToolCalls || capReached ? \"done\" : \"acting\";\n\t\t\t\tbatch(() => {\n\t\t\t\t\tlastResponseState.emit(response);\n\t\t\t\t\tstatusNode.emit(nextStatus);\n\t\t\t\t\tturnNode.emit(next);\n\t\t\t\t\tchat.append(\"assistant\", response.content, {\n\t\t\t\t\t\ttoolCalls: response.toolCalls,\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\n\t\t);\n\n\t\t// Effect 2: Tool results landed → append to chat, transition to\n\t\t// thinking (or done if turn cap reached). Same ordering discipline —\n\t\t// status emits before chat mutations. Abort guard mirrors effResponse.\n\t\tconst effResults = node(\n\t\t\t[toolResultsNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tif (latestAborted) return;\n\t\t\t\tconst arr = data[0] as readonly ToolResult[];\n\t\t\t\tif (arr.length === 0) return;\n\t\t\t\tconst nextStatus: AgentLoopStatus = latestTurn >= maxTurns ? \"done\" : \"thinking\";\n\t\t\t\tbatch(() => {\n\t\t\t\t\tstatusNode.emit(nextStatus);\n\t\t\t\t\tfor (const r of arr) chat.appendToolResult(r.id, r.content);\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\n\t\t);\n\n\t\t// Effect 3: external abort → cancel in-flight wire call + terminal status.\n\t\t// Aborting the controller causes the switchMap inner's `fromAny` to\n\t\t// emit ERROR (signal-bound), which tears down the subscription. The\n\t\t// `status=\"done\"` emit drives `_terminalResult` to resolve `run()`'s\n\t\t// Promise (via AbortError when `resp == null`, see C3).\n\t\t//\n\t\t// Unit 4 Q5: status guard — if status is already \"done\" (the natural-\n\t\t// completion path raced the abort), skip the redundant emit so the\n\t\t// status-node event log isn't polluted with a trailing duplicate.\n\t\t// Closure-mirror `latestStatus` keeps the comparison synchronous and\n\t\t// P3-compliant (closure read, not `.cache` read — see §28). Seeded\n\t\t// from `statusNode.cache` to match the §28 factory-time-seed pattern\n\t\t// that `latestTurn` / `latestAborted` use — the literal `\"idle\"` would\n\t\t// silently drift if the constructor initial value ever changed.\n\t\tlet latestStatus: AgentLoopStatus = (statusNode.cache as AgentLoopStatus | undefined) ?? \"idle\";\n\t\tconst statusSub = statusNode.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) if (m[0] === DATA) latestStatus = m[1] as AgentLoopStatus;\n\t\t});\n\t\tconst effAbort = node(\n\t\t\t[abortedNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tif (data[0] === true) {\n\t\t\t\t\tthis._currentAbortController?.abort(new Error(\"agentLoop: aborted\"));\n\t\t\t\t\tif (latestStatus !== \"done\") statusNode.emit(\"done\");\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\n\t\t);\n\n\t\t// Keepalive so the pipeline stays activated even without external\n\t\t// subscribers. Callers don't need to subscribe to `llmResponse` /\n\t\t// `toolResults` for the loop to run.\n\t\tconst kaResponse = keepalive(effResponse);\n\t\tconst kaResults = keepalive(effResults);\n\t\tconst kaAbort = keepalive(effAbort);\n\n\t\t// terminalResult emits the final `LLMResponse` on each \"done\"\n\t\t// transition. The old compound `{response, runVersion}` shape existed\n\t\t// to let a re-entrant caller's `awaitSettled` predicate filter out\n\t\t// the PREVIOUS run's cached DATA; that job now belongs to\n\t\t// `awaitSettled({skipCurrent: true})` (extra/sources.ts) which\n\t\t// ignores the initial push-on-subscribe DATA and resolves only on\n\t\t// fresh post-subscribe emissions. Retiring the stamp removes a\n\t\t// closure-held counter and a per-emission object allocation from\n\t\t// the hot path.\n\t\t//\n\t\t// C3 (abort-before-response) post-SENTINEL: when `stat === \"done\"` but\n\t\t// `lastResponseState` is SENTINEL (no DATA ever delivered for this\n\t\t// run — `prevData[1] === undefined`, equivalently `resp === undefined`\n\t\t// after `readLatest`'s fallback), emit `ERROR(AbortError)` so the\n\t\t// awaiting Promise rejects instead of hanging on a RESOLVED. The\n\t\t// SENTINEL state is restored at every `run()` boundary by\n\t\t// `lastResponse.down([[INVALIDATE]])` (clears `_cached` AND clears\n\t\t// each dependent's `prevData` slot for this dep), so a second run\n\t\t// after a successful first run still detects the abort cleanly —\n\t\t// no stale `prevData` leak.\n\t\tthis._terminalResult = nodeFactory<LLMResponse>(\n\t\t\t[statusNode, lastResponseState],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\tconst stat = readLatest<AgentLoopStatus>(data, ctx.prevData, 0, \"idle\");\n\t\t\t\tconst resp = readLatest<LLMResponse | undefined>(data, ctx.prevData, 1, undefined);\n\t\t\t\tif (stat === \"done\") {\n\t\t\t\t\tif (resp !== undefined) {\n\t\t\t\t\t\tactions.emit(resp);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst err = new Error(\"agentLoop: aborted\") as Error & { name: string };\n\t\t\t\t\terr.name = \"AbortError\";\n\t\t\t\t\tactions.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (stat === \"error\") {\n\t\t\t\t\tactions.down([[ERROR, new Error(\"agentLoop: errored\")]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"terminalResult\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"agent_terminal_result\"),\n\t\t\t\t// `lastResponseState` is SENTINEL until the first real response\n\t\t\t\t// arrives — without `partial: true`, the spec §2.7 first-run\n\t\t\t\t// gate would block this fn from ever firing on the abort-\n\t\t\t\t// before-response path (`status → \"done\"` while `lastResponse`\n\t\t\t\t// has never delivered DATA). The fn explicitly handles the\n\t\t\t\t// SENTINEL case (`resp === undefined → ERROR(AbortError)`),\n\t\t\t\t// so partial-fire is safe by design.\n\t\t\t\tpartial: true,\n\t\t\t},\n\t\t);\n\t\t// Wave B-CC Q2/C: register intermediate pipeline nodes so consumers\n\t\t// can `observe(path)` them by name (e.g. `agent.observe(\"promptInput\")`).\n\t\t// They were already visible in `describe()` via dep traversal, but not\n\t\t// path-addressable. Tools using the `observe`-by-path API now work.\n\t\t//\n\t\t// QA-fix (#5 stability): registrations live AFTER ALL dependent nodes\n\t\t// are constructed (`promptInput → llmResponse → effResponse →\n\t\t// lastResponseState → toolCallsRaw → toolResultsNode → effResults →\n\t\t// effAbort → _terminalResult`). Topology event-stream consumers\n\t\t// subscribed at construction time now see registrations in an order\n\t\t// where every edge between two registered nodes is already valid —\n\t\t// no transient partial graph slipping through to live mermaid / d2\n\t\t// renderers.\n\t\tthis.add(promptInput as Node<unknown>, { name: \"promptInput\" });\n\t\tthis.add(llmResponse as Node<unknown>, { name: \"llmResponse\" });\n\t\tthis.add(this.lastResponse as Node<unknown>, { name: \"lastResponse\" });\n\t\t// When no interceptor is configured, `this.toolCalls === toolCallsRaw` —\n\t\t// registering the same instance under two names trips the per-graph\n\t\t// `_nodeToName` collision check. Register the raw under `toolCalls`\n\t\t// directly in that case; otherwise register both (raw + post-intercept).\n\t\tif (this.toolCalls === toolCallsRaw) {\n\t\t\tthis.add(this.toolCalls as Node<unknown>, { name: \"toolCalls\" });\n\t\t} else {\n\t\t\tthis.add(toolCallsRaw as Node<unknown>, { name: \"toolCallsRaw\" });\n\t\t\tthis.add(this.toolCalls as Node<unknown>, { name: \"toolCalls\" });\n\t\t}\n\t\tthis.add(toolResultsNode as Node<unknown>, { name: \"toolResults\" });\n\t\tthis.add(this._terminalResult as Node<unknown>, { name: \"terminalResult\" });\n\n\t\t// Register subscriptions via `addDisposer` so they tear down on\n\t\t// subgraph unmount (not just explicit `destroy()`). A caller that\n\t\t// unmounts the AgentLoopGraph from its parent via `graph.remove(...)`\n\t\t// would otherwise keep `turnSub` / `abortedSub` live against dead state.\n\t\tthis.addDisposer(turnSub);\n\t\tthis.addDisposer(abortedSub);\n\t\tthis.addDisposer(statusSub);\n\t\tthis.addDisposer(kaResponse);\n\t\tthis.addDisposer(kaResults);\n\t\tthis.addDisposer(kaAbort);\n\t\tthis._disposeRunWiring = (): void => {\n\t\t\t// addDisposer takes care of teardown; this shim stays for the\n\t\t\t// `destroy()` override's idempotency contract (safe no-op if the\n\t\t\t// disposers already fired).\n\t\t};\n\t}\n\n\t/**\n\t * Bridge to `Promise<LLMResponse>` over the reactive pipeline.\n\t *\n\t * - If `userMessage` is provided, appends it as a user message and\n\t * transitions status to `\"thinking\"` to kick the loop.\n\t * - If `signal` is provided, binds it to the reactive `aborted` node\n\t * AND threads into `adapter.invoke({ signal })` so the wire call can\n\t * cancel mid-flight. The reactive `aborted` state + effect 3 guarantee\n\t * that even an adapter that ignores `signal` will stop emitting into\n\t * the agent graph.\n\t * - Resolves when `status === \"done\"` with the final LLM response.\n\t * Rejects with `AbortError` when the abort signal fires pre-response.\n\t * Rejects with the stage error when `status === \"error\"`.\n\t *\n\t * **Concurrency:** `run()` refuses to overlap with a pending call on the\n\t * same agent. Attempting to call `run()` while a previous `run()` is\n\t * still in-flight throws a `RangeError` immediately. Stale-resolution\n\t * safety is provided by `awaitSettled({skipCurrent: true})`, which\n\t * ignores the cached initial DATA from any previous run and resolves\n\t * only on a fresh post-subscribe emission of `_terminalResult`.\n\t */\n\tasync run(userMessage?: string, signal?: AbortSignal): Promise<LLMResponse | null> {\n\t\tif (this._running) {\n\t\t\tthrow new RangeError(\n\t\t\t\t`agentLoop \"${this.name}\": run() called while a previous run() is still pending — await the previous run before starting another, or call abort() first`,\n\t\t\t);\n\t\t}\n\t\tthis._running = true;\n\n\t\tlet offAbort: (() => void) | undefined;\n\t\ttry {\n\t\t\t// Reset per-run state. `lastResponse` MUST be cleared here —\n\t\t\t// without it, `_terminalResult` would read the prior run's\n\t\t\t// cached response during a second `run()` with a pre-aborted\n\t\t\t// signal: `effAbort` drives `status → \"done\"`, `_terminalResult`\n\t\t\t// evaluates `stat=\"done\"` + `resp=<prior respA>` and emits DATA\n\t\t\t// as a fresh post-subscribe signal → `awaitSettled` resolves\n\t\t\t// with the stale response instead of rejecting with AbortError.\n\t\t\t// The C3 `stat=done && resp===undefined → ERROR` guard in\n\t\t\t// `_terminalResult` is only correct once the reset clears the\n\t\t\t// cache.\n\t\t\t//\n\t\t\t// **SENTINEL reset via plain `[[INVALIDATE]]`** (DS-13.5.A,\n\t\t\t// 2026-05-01). Pre-DS-13.5.A this required a paired\n\t\t\t// `[[INVALIDATE], [RESOLVED]]` because INVALIDATE alone left\n\t\t\t// dependents wedged in DIRTY. With INVALIDATE settling the wave\n\t\t\t// (decrementing `_dirtyDepCount` like RESOLVED) and clearing\n\t\t\t// `_cached` + each dependent's `prevData[lastResponse]` slot\n\t\t\t// back to `undefined`, a single emission restores SENTINEL state\n\t\t\t// AND lets dependents fire on the next status transition.\n\t\t\t// `lastResponse` is a `Node<LLMResponse>` with no `initial` —\n\t\t\t// it stays SENTINEL until the first real response; resetting\n\t\t\t// via `emit(null)` would push a `null` DATA placeholder (the\n\t\t\t// F9 trap), which is why INVALIDATE rather than emit is used.\n\t\t\tbatch(() => {\n\t\t\t\tthis.lastResponse.down([[INVALIDATE]]);\n\t\t\t\tthis.turn.emit(0);\n\t\t\t\tthis.aborted.emit(false);\n\t\t\t\tthis.status.emit(\"idle\");\n\t\t\t});\n\t\t\tif (userMessage != null) this.chat.append(\"user\", userMessage);\n\n\t\t\t// Subscribe to `_terminalResult` BEFORE transitioning to\n\t\t\t// \"thinking\" — otherwise a synchronous adapter (mock tests,\n\t\t\t// offline stubs) would drain status → done → DATA on\n\t\t\t// `_terminalResult` before `awaitSettled` had a chance to\n\t\t\t// subscribe, and `skipCurrent: true` would swallow the only\n\t\t\t// DATA this run will produce. `awaitSettled` / `firstWhere`\n\t\t\t// subscribes synchronously during the `async` function's\n\t\t\t// initial execution slice, so calling it before the kick\n\t\t\t// guarantees the subscription is in place when the pipeline\n\t\t\t// starts draining.\n\t\t\t//\n\t\t\t// `skipCurrent: true` still matters: on the second `run()`\n\t\t\t// call `_terminalResult` holds cached DATA from the prior run,\n\t\t\t// and push-on-subscribe would resolve immediately with that\n\t\t\t// stale value without the skip.\n\t\t\tconst resultPromise = awaitSettled(this._terminalResult, { skipCurrent: true });\n\n\t\t\tif (signal != null) {\n\t\t\t\tif (signal.aborted) {\n\t\t\t\t\tthis.aborted.emit(true);\n\t\t\t\t} else {\n\t\t\t\t\tconst listener = (): void => this.aborted.emit(true);\n\t\t\t\t\tsignal.addEventListener(\"abort\", listener, { once: true });\n\t\t\t\t\toffAbort = (): void => signal.removeEventListener(\"abort\", listener);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Kick — transition to \"thinking\" fires promptInput → llmResponse.\n\t\t\t// Skip the kick when the signal was already aborted: `effAbort`\n\t\t\t// has driven `status → \"done\"` above, and a trailing\n\t\t\t// `thinking` emit would produce a non-monotonic `idle → done →\n\t\t\t// thinking` sequence in the status-event log for no reactive\n\t\t\t// benefit (promptInput gates on `!latestAborted` anyway).\n\t\t\tif (signal?.aborted !== true) {\n\t\t\t\tthis.status.emit(\"thinking\");\n\t\t\t}\n\n\t\t\treturn await resultPromise;\n\t\t} finally {\n\t\t\toffAbort?.();\n\t\t\tthis._running = false;\n\t\t\tthis._currentAbortController = null;\n\t\t}\n\t}\n\n\t/**\n\t * Flip the reactive `aborted` state. Equivalent to setting an external\n\t * `AbortSignal` — the pipeline observes and transitions to `\"done\"`.\n\t */\n\tabort(): void {\n\t\tthis.aborted.emit(true);\n\t}\n\n\toverride destroy(): void {\n\t\ttry {\n\t\t\tthis._disposeRunWiring();\n\t\t} catch {\n\t\t\t/* best-effort: disposing keepalives shouldn't block destroy */\n\t\t}\n\t\tsuper.destroy();\n\t}\n}\n\n/**\n * Read the latest value for dep `i` inside a raw-`node()` fn body.\n *\n * Checks `batchData[i]` first (this-wave DATA from the dep), falls back to\n * `ctx.prevData[i]` (last DATA from prior waves), and finally to `fallback`\n * when the dep has never emitted (SENTINEL). Matches the unwrap semantics\n * `derived`'s sugar applies, so raw nodes can read deps uniformly.\n *\n * @internal\n */\nfunction readLatest<T>(\n\tbatchData: readonly (readonly unknown[] | undefined)[],\n\tprevData: readonly unknown[],\n\tindex: number,\n\tfallback: T,\n): T {\n\tconst batch = batchData[index];\n\tif (batch != null && batch.length > 0) return batch[batch.length - 1] as T;\n\tconst prev = prevData[index];\n\treturn (prev !== undefined ? prev : fallback) as T;\n}\n\n/** @internal Shape of the LLM invocation input — constructed inside `promptInput`. */\ninterface InvokeInput {\n\treadonly messages: readonly ChatMessage[];\n\treadonly tools: readonly ToolDefinition[];\n}\n\nexport function agentLoop(name: string, opts: AgentLoopOptions): AgentLoopGraph {\n\tconst g = new AgentLoopGraph(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` exposes provenance. Opts include non-JSON\n\t// fields (`adapter`, `tools`, `stopWhen`, `onToolCall`,\n\t// `interceptToolCalls`, etc.) so route through `placeholderArgs`\n\t// (DG2=ii).\n\tg.tagFactory(\"agentLoop\", placeholderArgs(opts as unknown as Record<string, unknown>));\n\treturn g;\n}\n","/**\n * Harness pipeline trace — thin sugar over `graph.observe({ format: \"stage-log\" })`.\n *\n * Since 2026-04-22 (D2), stage-labeled tracing is a first-class observe format\n * on {@link Graph}. `harnessTrace` wires that format over the 7 pipeline stages\n * (INTAKE → TRIAGE → QUEUE → GATE → EXECUTE → VERIFY → STRATEGY) with sensible\n * defaults so harness consumers don't need to restate the stage map.\n *\n * For non-harness graphs, call `graph.observe({ format: \"stage-log\", stageLabels })`\n * directly — the format is domain-agnostic.\n *\n * @module\n */\n\nimport { monotonicNs } from \"@graphrefly/pure-ts/core\";\nimport type { ObserveEvent, ObserveResult } from \"@graphrefly/pure-ts/graph\";\nimport type { HarnessGraph } from \"./harness-loop.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Event type captured by structured trace. */\nexport type TraceEventType = \"data\" | \"error\" | \"complete\";\n\n/** A single structured trace event. */\nexport interface TraceEvent {\n\t/** Elapsed seconds since trace was created. */\n\telapsed: number;\n\t/** Pipeline stage label (INTAKE, TRIAGE, QUEUE, GATE, EXECUTE, VERIFY, STRATEGY). */\n\tstage: string;\n\t/** Event type. */\n\ttype: TraceEventType;\n\t/** Data payload (present for \"data\" and \"error\" events). Omitted at \"summary\" detail. */\n\tdata?: unknown;\n\t/** Human-readable summary of the data. Present at \"standard\" and \"full\" detail. */\n\tsummary?: string;\n}\n\n/** Detail level for trace output. */\nexport type TraceDetail =\n\t/** Stage + elapsed only. No data preview. Lowest overhead. */\n\t| \"summary\"\n\t/** Stage + elapsed + truncated data preview. Default. */\n\t| \"standard\"\n\t/** Stage + elapsed + full raw data. Use for debugging, not production. */\n\t| \"full\";\n\n/** Handle returned by {@link harnessTrace}. Call `dispose()` to stop tracing. */\nexport interface HarnessTraceHandle {\n\t/** Stop tracing and detach all observers. Safe to call multiple times. */\n\tdispose(): void;\n\t/**\n\t * Structured trace events collected since creation. Plain array — no\n\t * subscription needed (COMPOSITION-GUIDE §1: avoid lazy-activation\n\t * friction for inspection tools). Populated reactively via observe().\n\t */\n\treadonly events: readonly TraceEvent[];\n}\n\n/** Options for {@link harnessTrace}. */\nexport interface HarnessTraceOptions {\n\t/** Sink for rendered trace lines. Default: `console.log`. Pass `null` for structured-only. */\n\tlogger?: ((line: string) => void) | null;\n\t/** Detail level for both string and structured output. Default: `\"summary\"`. */\n\tdetail?: TraceDetail;\n}\n\n// ---------------------------------------------------------------------------\n// Stage labels\n// ---------------------------------------------------------------------------\n\n/**\n * Observe paths → stage labels for the 7 harness stages. Path set is\n * sourced from {@link HarnessGraph.stageNodes} so inspection tools stay\n * decoupled from mount-structure changes (Unit 22 C).\n */\nfunction buildStageLabels(harness: HarnessGraph): Record<string, string> {\n\tconst labels: Record<string, string> = {};\n\tfor (const { label, paths } of harness.stageNodes()) {\n\t\tfor (const p of paths) labels[p] = label;\n\t}\n\treturn labels;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Attach a stage-log trace over the harness pipeline. Delegates to\n * `harness.observe({ format: \"stage-log\", ... })` for each stage path —\n * every event is captured in `handle.events` (structured) AND rendered via\n * the `logger` (string output).\n *\n * **Detail levels:**\n * - `\"summary\"` — stage + elapsed only. Minimal overhead.\n * - `\"standard\"` (default) — stage + elapsed + truncated data preview.\n * - `\"full\"` — stage + elapsed + full raw data object in events.\n *\n * Elapsed timestamps are relative to the `harnessTrace()` invocation time,\n * not the first event.\n */\nexport function harnessTrace(\n\tharness: HarnessGraph,\n\topts?: HarnessTraceOptions,\n): HarnessTraceHandle {\n\tconst logger: ((line: string) => void) | null =\n\t\topts?.logger === null ? null : (opts?.logger ?? console.log);\n\tconst detail: TraceDetail = opts?.detail ?? \"summary\";\n\tconst startNs = monotonicNs();\n\tconst observations: ObserveResult[] = [];\n\tconst events: TraceEvent[] = [];\n\tconst stageLabels = buildStageLabels(harness);\n\n\tfunction elapsedSecs(): number {\n\t\treturn (monotonicNs() - startNs) / 1e9;\n\t}\n\n\tfunction recordEvent(stage: string, type: TraceEventType, rawData: unknown): void {\n\t\tconst ev: TraceEvent = { elapsed: elapsedSecs(), stage, type };\n\t\tif (detail !== \"summary\") ev.summary = summarize(rawData);\n\t\tif (detail === \"full\") ev.data = rawData;\n\t\tevents.push(ev);\n\t}\n\n\t// One observe call per path — keeps per-stage elapsed offsets anchored to\n\t// this invocation (the shared stage-log format uses its own elapsed clock\n\t// per observation, which matches the legacy behavior). We also intercept\n\t// each event through `onEvent` so structured `events[]` stays populated\n\t// regardless of `logger`.\n\tfor (const [path, stage] of Object.entries(stageLabels)) {\n\t\ttry {\n\t\t\tconst obs = harness.observe(path, {\n\t\t\t\tformat: \"stage-log\",\n\t\t\t\tstageLabels,\n\t\t\t\tlogger: logger ? (line: string) => logger(line) : () => {},\n\t\t\t\tincludeTypes: [\"data\", \"error\", \"complete\"],\n\t\t\t});\n\t\t\tobs.onEvent((event: ObserveEvent) => {\n\t\t\t\tif (event.type === \"data\") recordEvent(stage, \"data\", (event as { data: unknown }).data);\n\t\t\t\telse if (event.type === \"error\")\n\t\t\t\t\trecordEvent(stage, \"error\", (event as { data: unknown }).data);\n\t\t\t\telse if (event.type === \"complete\") recordEvent(stage, \"complete\", undefined);\n\t\t\t});\n\t\t\tobservations.push(obs);\n\t\t} catch (err) {\n\t\t\t// Node may not exist yet (e.g., a gated-queue route that hasn't been\n\t\t\t// mounted on this harness). Record a synthetic error trace event so\n\t\t\t// consumers see WHICH stage dropped out and why — silent swallow\n\t\t\t// breaks dry-run equivalence (a regression in stage wiring would\n\t\t\t// not surface in the trace).\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\trecordEvent(stage, \"error\", `observe-unavailable: ${path} — ${msg}`);\n\t\t\tif (logger) {\n\t\t\t\tlogger(`[${elapsedSecs().toFixed(3)}s] ${stage.padEnd(9)} ✗ observe-unavailable: ${msg}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tget events(): readonly TraceEvent[] {\n\t\t\treturn events;\n\t\t},\n\t\tdispose() {\n\t\t\tfor (const obs of observations) obs.dispose();\n\t\t\tobservations.length = 0;\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Helpers — kept here because `observe({ format: \"stage-log\" })` emits short\n// one-line previews; the structured `events[]` is free to carry richer\n// summaries with different truncation bounds (120 for JSON, 80 for strings).\n// ---------------------------------------------------------------------------\n\nfunction summarize(value: unknown): string {\n\tif (value == null) return \"null\";\n\tif (typeof value === \"string\") return truncate(value, 80);\n\tif (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n\tif (typeof value === \"bigint\") return String(value);\n\ttry {\n\t\tconst json = JSON.stringify(value);\n\t\treturn truncate(json, 120);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n\nfunction truncate(s: string, max: number): string {\n\treturn s.length > max ? `${s.slice(0, max - 1)}…` : s;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAoBO,SAAS,aAAgB,MAAkC;AACjE,SAAO,EAAE,cAAc,WAAW,GAAG,KAAK;AAC3C;AAMO,SAAS,OAAO,GAAqB;AAC3C,SAAO,EAAE,CAAC;AACX;AAEO,SAAS,cAAc,KAAqB;AAClD,MAAI,OAAO,QAAQ,YAAY,CAAC,OAAO,SAAS,GAAG,GAAG;AACrD,UAAM,IAAI,UAAU,8CAA8C;AAAA,EACnE;AACA,SAAO,MAAM,IAAI,IAAI;AACtB;AAEO,SAASA,QAAO,GAAuB;AAC7C,SACC,KAAK,QACL,OAAO,MAAM,YACb,WAAW,KACX,OAAQ,EAAW,cAAc;AAEnC;AA9CA,IAgBAC;AAhBA;AAAA;AAAA;AAgBA,IAAAA,eAAmC;AAAA;AAAA;;;AChBnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0BA,SAAS,iBAAiB,OAAuB;AAChD,SAAO,QAAQ,IAAI,IAAI;AACxB;AAEA,SAAS,YAAY,OAAe,QAA4B;AAC/D,MAAI,WAAW,OAAQ,QAAO;AAC9B,MAAI,WAAW,OAAQ,QAAO,KAAK,OAAO,IAAI;AAC9C,SAAO,QAAQ,IAAI,KAAK,OAAO,KAAK,QAAQ;AAC7C;AAEA,SAAS,cAAc,KAAa,KAAqB;AACxD,SAAO,MAAM,KAAK,OAAO,KAAK,MAAM;AACrC;AAiBO,SAAS,SAAS,SAAkC;AAC1D,QAAM,OAAO,iBAAiB,OAAO;AACrC,SAAO,MAAM;AACd;AAmBO,SAAS,OAAO,QAAgB,QAAkC;AACxE,QAAM,WAAW,iBAAiB,MAAM;AACxC,QAAM,WAAW,WAAW,SAAY,WAAW,iBAAiB,MAAM;AAC1E,SAAO,CAAC,YAAoB,WAAW,WAAW,KAAK,IAAI,GAAG,OAAO;AACtE;AA+BO,SAAS,YAAY,SAAsD;AACjF,QAAM,SAAS,iBAAiB,SAAS,UAAU,MAAM,SAAS;AAClE,QAAM,SAAS,SAAS,WAAW,UAAa,QAAQ,SAAS,IAAI,IAAK,SAAS,UAAU;AAC7F,QAAM,aAAa,iBAAiB,SAAS,cAAc,KAAK,UAAU;AAC1E,QAAM,SAAS,SAAS,UAAU;AAElC,SAAO,CAAC,YAAoB;AAC3B,QAAI;AACJ,QAAI,WAAW,GAAG;AACjB,cAAQ;AAAA,IACT,WAAW,WAAW,GAAG;AACxB,cAAQ;AAAA,IACT,OAAO;AACN,YAAM,WAAW,aAAa;AAC9B,UAAI,SAAS;AACb,eAAS,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,GAAG,KAAK;AAC9C,YAAI,UAAU,UAAU;AACvB,mBAAS;AACT;AAAA,QACD;AACA,kBAAU;AAAA,MACX;AACA,cAAQ,SAAS;AACjB,UAAI,QAAQ,WAAY,SAAQ;AAAA,IACjC;AACA,WAAO,YAAY,OAAO,MAAM;AAAA,EACjC;AACD;AAmBO,SAAS,UAAU,SAAS,MAAM,WAAW,aAAa,KAAK,YAA6B;AAClG,QAAM,WAAW,iBAAiB,MAAM;AACxC,QAAM,UAAU,iBAAiB,UAAU;AAE3C,WAAS,QAAQ,SAAyB;AACzC,QAAI,WAAW,EAAG,QAAO;AACzB,QAAI,OAAO;AACX,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AACjC,YAAM,OAAO,OAAO;AACpB,aAAO;AACP,YAAM;AAAA,IACP;AACA,WAAO;AAAA,EACR;AAEA,SAAO,CAAC,YAAoB;AAC3B,UAAM,MAAM,QAAQ,OAAO,IAAI;AAC/B,WAAO,OAAO,UAAU,MAAM;AAAA,EAC/B;AACD;AAwBO,SAAS,mBACf,SAAS,MAAM,WACf,QAAQ,KAAK,YACK;AAClB,SAAO,CAAC,UAAU,QAAQ,gBAAgB;AACzC,UAAM,OAAO,eAAe;AAC5B,UAAM,UAAU,KAAK,IAAI,OAAO,OAAO,CAAC;AACxC,WAAO,cAAc,QAAQ,OAAO;AAAA,EACrC;AACD;AAmBO,SAAS,gBAAgB,UAA2B,aAAsC;AAChG,SAAO,CAAC,SAAS,OAAO,gBAAgB;AACvC,QAAI,WAAW,YAAa,QAAO;AACnC,WAAO,SAAS,SAAS,OAAO,WAAW;AAAA,EAC5C;AACD;AAmBO,SAAS,qBAAqB,MAAsC;AAC1E,MAAI,SAAS,WAAY,QAAO,SAAS,IAAI,UAAU;AACvD,MAAI,SAAS,SAAU,QAAO,OAAO,IAAI,UAAU;AACnD,MAAI,SAAS,cAAe,QAAO,YAAY;AAC/C,MAAI,SAAS,YAAa,QAAO,UAAU;AAC3C,MAAI,SAAS,qBAAsB,QAAO,mBAAmB;AAC7D,QAAM,IAAI;AAAA,IACT,4BAA4B,OAAO,IAAI,CAAC;AAAA,EACzC;AACD;AAvQA,IAOa,WACA;AARb;AAAA;AAAA;AAOO,IAAM,YAAY;AAClB,IAAM,aAAa;AAAA;AAAA;;;ACR1B;AAAA;AAAA;AAAA;AAAA;AA8IO,SAAS,YACf,QACA,MACA,WACmB;AACnB,QAAM,aAAaC,QAAO,IAAI;AAO9B,MAAI,aAAoC;AACxC,MAAI,CAAC,YAAY;AAChB,UAAM,aAAa;AACnB,QACC,WAAW,OAAO,UAClB,OAAO,WAAW,OAAO,YACzB,CAAC,OAAO,SAAS,WAAW,EAAE,KAC9B,WAAW,MAAM,GAChB;AACD,YAAM,IAAI,WAAW,uDAAuD;AAAA,IAC7E;AACA,iBAAa;AAAA,MACZ,IAAI,WAAW;AAAA,MACf,GAAI,WAAW,QAAQ,OAAO,EAAE,MAAM,WAAW,KAAK,IAAI,CAAC;AAAA,IAC5D;AAAA,EACD,OAAO;AACN,UAAM,SAAU,KAAuC;AAGvD,QAAI,WAAW,QAAW;AACzB,UACC,OAAO,OAAO,UACd,OAAO,OAAO,OAAO,YACrB,CAAC,OAAO,SAAS,OAAO,EAAE,KAC1B,OAAO,MAAM,GACZ;AACD,cAAM,IAAI;AAAA,UACT;AAAA,QACD;AAAA,MACD;AACA,mBAAa;AAAA,QACZ,IAAI,OAAO;AAAA,QACX,GAAI,OAAO,QAAQ,OAAO,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;AAAA,MACpD;AAAA,IACD;AAAA,EACD;AAEA,QAAM,aAAa,WAAW;AAC9B,QAAM,cAAuC,aAC1C,EAAE,IAAI,gCAAgC,IACtC,EAAE,IAAI,WAAY,GAAG;AAIxB,QAAM,mBAAe,oBAAmB,CAAC,GAAG;AAAA,IAC3C,MAAM;AAAA,IACN,cAAc;AAAA,IACd,SAAS,EAAE,QAAQ,UAAU;AAAA,IAC7B,QAAQ,CAAC,GAAG,MACX,MAAM,KACL,KAAK,QACL,KAAK,QACL,OAAO,MAAM,YACb,OAAO,MAAM,YACZ,EAAyB,WAAY,EAAyB,UAC/D,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;AAAA,EACzC,CAAC;AAED,QAAM,UAAM;AAAA,IACX,CAAC,OAAO,MAAM;AACb,UAAI,UAAU;AACd,UAAI,iBAAiB;AACrB,YAAM,QAAQ,IAAI,8BAAgB;AAClC,UAAI,YAAiC;AACrC,UAAI,WAAgC;AAEpC,eAAS,UAAU,MAA0B;AAC5C,qBAAa,KAAK,CAAC,CAAC,mBAAK,GAAG,CAAC,oBAAM,IAAI,CAAC,CAAC;AAAA,MAC1C;AAEA,eAAS,aAAmB;AAC3B,YAAI,QAAS;AAQb,YACC,cAAc,QACd,OAAO,WAAW,OAAO,YACzB,CAAC,OAAO,SAAS,WAAW,EAAE,KAC9B,WAAW,MAAM,GAChB;AACD;AAAA,QACD;AACA,cAAM,KAAK,WAAW;AACtB,yBAAiB;AACjB,cAAM,gBAAY,2BAAY;AAC9B,cAAM,UAAU,KAAK;AACrB,kBAAU;AAAA,UACT,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,aAAa;AAAA,QACd,CAAC;AACD,cAAM,MAAM,SAAS,MAAM;AAC1B,cAAI,QAAS;AACb,oBAAU;AACV,qBAAW;AACX,oBAAU;AAAA,YACT,QAAQ;AAAA,YACR,gBAAY,2BAAY;AAAA,YACxB,aAAa;AAAA,UACd,CAAC;AACD,YAAE,KAAK,CAAC,CAAC,qBAAO,IAAI,aAAa,EAAE,CAAC,CAAC,CAAC;AAAA,QACvC,CAAC;AAAA,MACF;AAEA,eAAS,eAAqB;AAC7B,YAAI,YAAY,QAAQ,QAAS;AACjC,mBAAW,OAAO,UAAU,CAAC,SAAS;AACrC,qBAAW,KAAK,MAAM;AACrB,gBAAI,QAAS;AACb,kBAAM,IAAI,EAAE,CAAC;AACb,gBAAI,MAAM,oBAAO,GAAE,KAAK,CAAC,CAAC,mBAAK,CAAC,CAAC;AAAA,qBACxB,MAAM,oBAAM;AACpB,yBAAW;AACX,gBAAE,KAAK,EAAE,CAAC,CAAM;AAAA,YACjB,WAAW,MAAM,uBAAU,GAAE,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AAAA,qBACrC,MAAM,wBAAU;AACxB,oBAAM,OAAO;AACb,wBAAU;AACV,wBAAU;AAAA,gBACT,QAAQ;AAAA,gBACR,kBAAc,2BAAY;AAAA,cAC3B,CAAC;AACD,gBAAE,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACnB;AAAA,YACD,WAAW,MAAM,qBAAO;AACvB,oBAAM,OAAO;AACb,wBAAU;AACV,wBAAU;AAAA,gBACT,QAAQ;AAAA,gBACR,gBAAY,2BAAY;AAAA,gBACxB,aAAa;AAAA,cACd,CAAC;AACD,gBAAE,KAAK,CAAC,CAAC,CAAC;AACV;AAAA,YACD,WAAW,MAAM,wBAAU;AAC1B,oBAAM,OAAO;AACb,wBAAU;AACV,gBAAE,KAAK,CAAC,CAAC,CAAC;AACV;AAAA,YACD,MAAO,GAAE,KAAK,CAAC,CAAC,CAAC;AAAA,UAClB;AAAA,QACD,CAAC;AAED,YAAI,cAAc,QAAQ,WAAW,KAAK,GAAG;AAC5C,qBAAW;AAAA,QACZ;AAAA,MACD;AAEA,UAAI,YAAY;AACf,cAAM,WAAW;AACjB,oBAAY,SAAS,UAAU,CAAC,SAAS;AACxC,qBAAW,KAAK,MAAM;AACrB,gBAAI,EAAE,CAAC,MAAM,mBAAM;AACnB,kBAAM,OAAO,EAAE,CAAC;AAChB,gBAAI,QAAQ,QAAQ,OAAO,SAAS,SAAU;AAE9C,kBAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,gBAAI,KAAK,WAAW,EAAG;AAQvB,gBAAI,QAAQ,MAAM;AACjB,kBAAI,OAAO,KAAK,OAAO,YAAY,CAAC,OAAO,SAAS,KAAK,EAAE,KAAK,KAAK,MAAM,GAAG;AAC7E,oBAAI,cAAc,MAAM;AAIvB,4BAAU;AACV,oBAAE,KAAK;AAAA,oBACN;AAAA,sBACC;AAAA,sBACA,IAAI;AAAA,wBACH;AAAA,sBACD;AAAA,oBACD;AAAA,kBACD,CAAC;AACD;AAAA,gBACD;AAGA;AAAA,cACD;AAAA,YACD;AACA,kBAAM,UAAU,cAAc;AAC9B,yBAAa;AAAA,cACZ,GAAI,cAAc,EAAE,IAAI,EAAE;AAAA,cAC1B,GAAG;AAAA,YACJ;AAEA,gBAAI,WAAW,WAAW,KAAK,GAAG;AACjC,2BAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD,CAAC;AAAA,MACF;AAIA,UAAI,cAAc,MAAM;AACvB,qBAAa;AAAA,MACd;AAEA,aAAO;AAAA,QACN,gBAAgB,MAAM;AACrB,oBAAU;AACV,gBAAM,OAAO;AACb,cAAI,SAAU,UAAS;AACvB,cAAI,UAAW,WAAU;AAAA,QAC1B;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,GAAG,aAAa;AAAA,MAChB,SAAS,OAAO;AAAA,MAChB,MAAM,EAAE,GAAI,cAAc,CAAC,GAAI,OAAG,0BAAW,eAAe,WAAW,EAAE;AAAA,IAC1E;AAAA,EACD;AAEA,SAAO,EAAE,MAAM,KAAK,aAAa;AAClC;AA9XA,IAiBAC,eAqBa;AAtCb;AAAA;AAAA;AAiBA,IAAAA,gBAYO;AACP;AACA;AAOO,IAAM,eAAN,cAA2B,MAAM;AAAA,MAC9B,OAAO;AAAA,MAChB,YAAY,IAAY;AACvB,cAAM,mBAAmB,KAAK,SAAS,IAAI;AAAA,MAC5C;AAAA,IACD;AAAA;AAAA;;;AC3CA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACkBA,IAAAC,eAAgC;AAChC,IAAAC,gBAAoD;AACpD,IAAAC,gBAAsB;;;ACHtB,IAAAC,eAA6C;AAC7C,IAAAC,gBAAoD;AACpD,mBAAsB;;;ACVtB,kBAQO;AACP,mBAAwC;;;ACIjC,SAAS,WACf,QACA,MACA,OAC0B;AAC1B,SAAO;AAAA,IACN,CAAC,MAAM,GAAG;AAAA,IACV,CAAC,GAAG,MAAM,OAAO,GAAG;AAAA,IACpB,GAAI,SAAS,CAAC;AAAA,EACf;AACD;;;ADLO,SAAS,OAAO,MAAc,OAA0D;AAC9F,SAAO,WAAW,MAAM,MAAM,KAAK;AACpC;AAMO,SAAS,WAAW,GAAgC;AAC1D,SACC,OAAO,MAAM,YACb,MAAM,QACN,eAAe,KACf,OAAQ,EAAoB,cAAc,cAC1C,WAAW;AAEb;AAuEO,SAAS,YAAY,MAAsB;AACjD,QAAM,QAAQ,KAAK,MAAM,0CAA0C;AACnE,SAAO,QAAQ,MAAM,CAAC,IAAK;AAC5B;AAsEO,SAAS,gBACf,SACA,UACA,QACe;AACf,aAAO;AAAA,IACN,CAAC,OAAO,YAAY;AACnB,YAAM,KAAK,IAAI,gBAAgB;AAI/B,YAAM,eAAe,OAAO;AAC5B,UAAI,eAA2B,MAAM;AACrC,UAAI,cAAc;AACjB,YAAI,aAAa,SAAS;AACzB,aAAG,MAAM;AAAA,QACV,OAAO;AACN,gBAAM,gBAAgB,MAAY,GAAG,MAAM;AAC3C,uBAAa,iBAAiB,SAAS,eAAe,EAAE,MAAM,KAAK,CAAC;AACpE,yBAAe,MAAM,aAAa,oBAAoB,SAAS,aAAa;AAAA,QAC7E;AAAA,MACD;AACA,UAAI,WAAW;AACf,UAAI,QAA6B;AACjC,YAAM,WAAW,CAAC,UAAmB;AACpC,YAAI,SAAU;AACd,mBAAW;AACX,gBAAQ,KAAK,CAAC,CAAC,kBAAM,KAAK,GAAG,CAAC,oBAAQ,CAAC,CAAoB;AAC3D,gBAAQ;AACR,gBAAQ;AAAA,MACT;AACA,UAAI;AACJ,UAAI;AACH,uBAAe,QAAQ,OAAO,UAAU,EAAE,GAAG,OAAO,YAAY,QAAQ,GAAG,OAAO,CAAC;AAAA,MACpF,SAAS,KAAK;AACb,iBAAS,OAAO,UAAU,SAAS,GAAG,CAAC;AACvC,eAAO;AAAA,UACN,gBAAgB,MAAM;AACrB,yBAAa;AACb,eAAG,MAAM;AAAA,UACV;AAAA,QACD;AAAA,MACD;AACA,YAAM,eAAW,sBAAqB,cAAc,EAAE,QAAQ,GAAG,OAAO,CAAC;AACzE,cAAQ,SAAS,UAAU,CAACC,YAAU;AACrC,mBAAW,KAAKA,SAAO;AACtB,cAAI,SAAU;AACd,cAAI,EAAE,CAAC,MAAM,kBAAM;AAClB,gBAAI;AACH,uBAAS,OAAO,UAAU,EAAE,CAAC,CAAgB,CAAC;AAAA,YAC/C,SAAS,KAAK;AACb,uBAAS,OAAO,UAAU,mBAAmB,GAAG,CAAC;AAAA,YAClD;AACA;AAAA,UACD;AACA,cAAI,EAAE,CAAC,MAAM,mBAAO;AACnB,qBAAS,OAAO,UAAU,SAAS,EAAE,CAAC,CAAC,CAAC;AACxC;AAAA,UACD;AACA,cAAI,EAAE,CAAC,MAAM,sBAAU;AAItB,qBAAS,OAAO,UAAU,YAAY,MAAS,CAAC;AAChD;AAAA,UACD;AAAA,QACD;AAAA,MACD,CAAC;AAKD,UAAI,YAAY,OAAO;AACtB,cAAM;AACN,gBAAQ;AAAA,MACT;AACA,aAAO;AAAA,QACN,gBAAgB,MAAM;AACrB,uBAAa;AACb,aAAG,MAAM;AACT,kBAAQ;AACR,kBAAQ;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAAA,IACA,EAAE,cAAc,WAAW;AAAA,EAC5B;AACD;;;ADzIO,IAAM,mBAAN,MAAuB;AAAA,EAI7B,YAA6B,MAAc;AAAd;AAAA,EAAe;AAAA,EAH3B,KAAK,oBAAI,IAA+B;AAAA;AAAA,EAExC,SAAmB,CAAC;AAAA,EAErC,IAAI,IAAY,MAAgC;AAC/C,UAAM,QAAQ,KAAK,GAAG,IAAI,EAAE;AAC5B,UAAM,IAAI,OAAO,IAAI,IAAI;AACzB,QAAI,MAAM,QAAW;AACpB,YAAM,IAAI,KAAK,OAAO,QAAQ,EAAE;AAChC,UAAI,KAAK,EAAG,MAAK,OAAO,OAAO,GAAG,CAAC;AACnC,WAAK,OAAO,KAAK,EAAE;AAAA,IACpB;AACA,WAAO;AAAA,EACR;AAAA,EACA,IAAI,IAAY,MAAY,OAAqB;AAChD,QAAI,QAAQ,KAAK,GAAG,IAAI,EAAE;AAC1B,QAAI,UAAU,QAAW;AACxB,cAAQ,oBAAI,IAAkB;AAC9B,WAAK,GAAG,IAAI,IAAI,KAAK;AAAA,IACtB;AACA,UAAM,IAAI,MAAM,KAAK;AACrB,UAAM,IAAI,KAAK,OAAO,QAAQ,EAAE;AAChC,QAAI,KAAK,EAAG,MAAK,OAAO,OAAO,GAAG,CAAC;AACnC,SAAK,OAAO,KAAK,EAAE;AACnB,WAAO,KAAK,GAAG,OAAO,KAAK,MAAM;AAChC,YAAM,QAAQ,KAAK,OAAO,MAAM;AAChC,UAAI,UAAU,OAAW;AACzB,WAAK,GAAG,OAAO,KAAK;AAAA,IACrB;AAAA,EACD;AACD;AAKA,IAAI,WAAW;AAOR,SAAS,kBACf,QACA,MAC6B;AAI7B,QAAM,YAAY,KAAK,QAAQ,WAAW,KAAK,KAAK,IAAI,EAAE,QAAQ;AAClE,QAAM,QAAQ,IAAI,mBAAM,SAAS;AACjC,SAAO,MAAM,WAAW,KAAK;AAE7B,QAAM,UAA0C,2BAA6B,QAAW;AAAA,IACvF,MAAM,GAAG,SAAS;AAAA,IAClB,SAAS,KAAK;AAAA,EACf,CAAC;AACD,QAAM,QAAQ,IAAI,iBAAiB,KAAK,YAAY,GAAG;AAGvD,MAAI,SAAS;AAEb,QAAM,UAA4C,IAAI;AAEtD,WAAS,IAAI,GAAmE;AAC/E,UAAM,KAAK,EAAE,MAAM,OAAO,EAAE,MAAM;AAClC,QAAI,OAAO;AAAA,MACV;AAAA,MACA,SAAS,EAAE;AAAA,MACX,MAAM,EAAE;AAAA,MACR,YAAY,EAAE;AAAA,MACd,cAAc,EAAE;AAAA,MAChB,OAAO,EAAE;AAAA,MACT,UAAM,0BAAY;AAAA;AAAA,IACnB,CAAC;AACD,WAAO;AAAA,EACR;AAEA,WAAS,MAAM,KAA4C;AAC1D,eAAO;AAAA,MACN,CAAC,OAAe;AAAA,MAChB,CAAC,MAAM,SAAS,QAAQ;AACvB,cAAM,MAAO,KAAK,CAAC,KAAK,QAAQ,KAAK,CAAC,EAAE,SAAS,IAAI,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAGpF,gBAAQ,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,SAAS,GAAG,CAAC,CAAC;AAAA,MAC7D;AAAA,MACA,EAAE,cAAc,WAAW,MAAM,OAAO,qBAAqB,EAAE,IAAI,CAAC,EAAE;AAAA,IACvE;AAAA,EACD;AAEA,WAAS,OAAOC,SAA8B;AAC7C,UAAM,MAAM,IAAI,QAAQ,SAAS,CAAC;AAClC,UAAM,YAAQ,0BAAY;AAC1B,QAAI,YAAY,IAAI,OAAO,CAAC,MAAM;AAIjC,UAAIA,QAAO,SAAS,QAAQ,EAAE,UAAUA,QAAO,MAAO,QAAO;AAC7D,UAAIA,QAAO,eAAe,QAAQ,QAAQ,EAAE,QAAQA,QAAO,YAAa,QAAO;AAC/E,UAAIA,QAAO,mBAAmB,QAAQ,EAAE,aAAaA,QAAO,gBAAiB,QAAO;AACpF,aAAO;AAAA,IACR,CAAC;AACD,QAAIA,QAAO,OAAO,QAAQ,UAAU,SAASA,QAAO,KAAK;AACxD,kBAAY,UAAU,MAAM,UAAU,SAASA,QAAO,GAAG;AAAA,IAC1D;AACA,UAAM,UAAU,IAAI,SAAS,UAAU;AACvC,QAAI,UAAU,GAAG;AAChB,UAAI,MAAM;AACV,UAAI,WAAW,SAAS;AAAA,IACzB;AACA,WAAO;AAAA,EACR;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,UAAgB;AACf,UAAI,QAAQ;AAAA,IACb;AAAA,EACD;AACD;AAIA,IAAM,oBAAoB,CAAC,MAAsB,KAAK,KAAK,EAAE,SAAS,CAAC;AAEvE,SAAS,QAAQ,GAA0B,GAAuB;AACjE,MAAI,EAAE,SAAS,MAAM;AACpB,QAAI,OAAO,EAAE,UAAU,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,EAAE,KAAK,EAAG,QAAO;AAAA,EACxF;AACA,MAAI,EAAE,WAAW,QAAQ,CAAC,EAAE,QAAQ,KAAK,CAAC,MAAM,EAAE,KAAK,SAAS,CAAC,CAAC,EAAG,QAAO;AAC5E,MAAI,EAAE,iBAAiB,QAAQ,EAAE,aAAa,EAAE,cAAe,QAAO;AACtE,MAAI,EAAE,iBAAiB,QAAQ,EAAE,aAAa,EAAE,cAAe,QAAO;AACtE,MAAI,EAAE,gBAAgB,QAAQ,EAAE,iBAAiB,EAAE,aAAc,QAAO;AACxE,SAAO;AACR;AAQO,SAAS,aACf,GACA,OACA,UACA,OACA,aAC+B;AAC/B,QAAM,OAAyB;AAAA,IAC9B,IAAI,EAAE;AAAA,IACN,OAAO,EAAE;AAAA,IACT,MAAM,EAAE;AAAA,IACR,MAAM;AAAA,IACN,SAAS,EAAE;AAAA,IACX,YAAY;AAAA,EACb;AACA,MAAI,YAAY,EAAG,QAAO;AAC1B,aAAW,QAAQ,OAAO;AACzB,QAAI,CAAC,QAAQ,GAAG,KAAK,KAAK,EAAG;AAC7B,YAAQ,KAAK,QAAQ;AAAA,MACpB,KAAK;AACJ,eAAO;AAAA,MACR,KAAK;AACJ,eAAO,EAAE,GAAG,MAAM,MAAM,GAAG,SAAS,QAAQ,EAAE,EAAE,KAAK,YAAY,KAAK;AAAA,MACvE,KAAK,YAAY;AAChB,cAAM,IAAI,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU,KAAK,UAAU,EAAE,OAAO;AAC9E,eAAO;AAAA,UACN,GAAG;AAAA,UACH,MAAM;AAAA,UACN,SAAS,EAAE,SAAS,KAAK,WAAW,EAAE,MAAM,GAAG,KAAK,QAAQ,IAAI;AAAA,UAChE,YAAY,EAAE,SAAS,KAAK;AAAA,QAC7B;AAAA,MACD;AAAA,MACA,KAAK,eAAe;AACnB,YAAI,CAAC,aAAa;AAEjB,gBAAM,IAAI,MAAM,yDAAyD;AAAA,QAC1E;AACA,cAAM,SAAS,MAAM,IAAI,EAAE,IAAI,KAAK,MAAM;AAC1C,cAAM,OAAO,UAAU,YAAY,GAAG,KAAK,MAAM;AACjD,YAAI,WAAW,OAAW,OAAM,IAAI,EAAE,IAAI,KAAK,QAAQ,IAAI;AAC3D,eAAO,EAAE,GAAG,MAAM,MAAM,KAAK,QAAQ,SAAS,MAAM,YAAY,KAAK;AAAA,MACtE;AAAA,IACD;AAAA,EACD;AACA,SAAO;AACR;AAcO,SAAS,kBACf,MACA,MACoC;AACpC,QAAM,UAAU,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,aAAa;AACjE,MAAI,WAAW,CAAC,KAAK,MAAM,aAAa;AACvC,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,QAAM,WAAW,KAAK,aAAa;AACnC,QAAM,cAAc,KAAK,MAAM;AAE/B,aAAO;AAAA,IACN,CAAC,KAAK,SAAiB,KAAK,QAAgB;AAAA,IAC5C,CAAC,MAAM,SAAS,QAAQ;AACvB,YAAM,UAAW,KAAK,CAAC,KAAK,QAAQ,KAAK,CAAC,EAAE,SAAS,IAAI,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAGxF,YAAM,WAAY,KAAK,CAAC,KAAK,QAAQ,KAAK,CAAC,EAAE,SAAS,IAAI,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAGzF,UAAI,YAAY,QAAW;AAC1B,gBAAQ,KAAK,CAAC,CAAC;AACf;AAAA,MACD;AACA,YAAM,IAAI,YAAY;AACtB,YAAM,WAA+B,CAAC;AACtC,iBAAW,KAAK,SAAS;AACxB,YAAI,CAAC,KAAK,OAAO,CAAC,EAAG;AACrB,cAAM,IAAI,aAAa,GAAG,KAAK,OAAO,GAAG,KAAK,QAAQ,WAAW;AACjE,YAAI,MAAM,OAAW,UAAS,KAAK,CAAC;AAAA,MACrC;AAEA,YAAM,OAAO,CAAC,MACb,SAAS,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU,KAAK,UAAU,EAAE,OAAO,CAAC;AAC/E,UAAI,QAAQ;AACZ,iBAAW,KAAK,SAAU,UAAS,KAAK,CAAC;AACzC,UAAI,QAAQ,KAAK,cAAc;AAC9B,cAAM,QAAQ,QAAQ;AAAA,UACrB,CAAC,KAAK,MAAM,IAAI,IAAI,EAAE,IAAI,EAAE,UAAU;AAAA,UACtC,oBAAI,IAAI;AAAA,QACT;AACA,iBAAS,KAAK,CAAC,GAAG,OAAO,MAAM,IAAI,EAAE,EAAE,KAAK,MAAM,MAAM,IAAI,EAAE,EAAE,KAAK,EAAE;AACvE,eAAO,QAAQ,KAAK,gBAAgB,SAAS,SAAS,GAAG;AACxD,mBAAS,KAAK,SAAS,MAAM,CAAqB;AAAA,QACnD;AAAA,MACD;AACA,cAAQ,KAAK,QAAQ;AAAA,IACtB;AAAA,IACA,EAAE,cAAc,WAAW,MAAM,OAAO,eAAe,EAAE,OAAO,KAAK,MAAM,MAAM,CAAC,EAAE;AAAA,EACrF;AACD;;;ADrTA,IAAI,gBAAgB;AAEb,SAAS,UACf,QACA,OAA4B,CAAC,GACR;AAGrB,QAAM,OAAO,KAAK,QAAQ,aAAa,EAAE,aAAa;AACtD,QAAM,QAAQ,IAAI,oBAAM,IAAI;AAC5B,SAAO,MAAM,MAAM,KAAK;AACxB,QAAM,WAAW,KAAK,YAAY,OAAO;AAEzC,MAAI,YAAY;AAEhB,QAAM,cAAc,oBAAI,IAAoB;AAE5C,QAAM,cAAc,kBAAqB,OAAO;AAAA,IAC/C,OAAO,KAAK,gBAAgB;AAAA,IAC5B,aAAa,KAAK;AAAA,IAClB,MAAM,GAAG,IAAI;AAAA,EACd,CAAC;AACD,QAAM,YAAiC,2BAAkB,QAAW,EAAE,MAAM,GAAG,IAAI,SAAS,CAAC;AAI7F,QAAM,WAAW,oBAAI,IAAyB;AAC9C,QAAM,aAAS,mBAAuC,CAAC,GAAG;AAAA,IACzD,MAAM,GAAG,IAAI;AAAA,IACb,SAAS,oBAAI,IAAI;AAAA,EAClB,CAAC;AACD,WAAS,aAAmB;AAC3B,WAAO,KAAK,IAAI,IAAI,QAAQ,CAAC;AAAA,EAC9B;AAEA,WAAS,YAAY,MAAoC;AACxD,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,QAAQ,UAAU;AACrB,YAAM,IAAI,WAAW,oBAAoB,KAAK,qBAAqB,QAAQ,EAAE;AAAA,IAC9E;AACA,UAAM,KAAK,KAAK,MAAM,SAAS,EAAE,SAAS;AAE1C,UAAM,UAAU,kBAAkB,aAAa,KAAK,IAAsB;AAE1E,UAAM,iBAAa;AAAA,MAClB,CAAC,MAAM,OAAe;AAAA,MACtB,CAAC,MAAM,SAAS,QAAQ;AACvB,cAAM,MAAO,KAAK,CAAC,KAAK,QAAQ,KAAK,CAAC,EAAE,SAAS,IAAI,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAGpF,gBAAQ,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,aAAa,MAAM,EAAE,aAAa,MAAS,CAAC;AAAA,MACtF;AAAA,MACA,EAAE,cAAc,UAAU;AAAA,IAC3B;AACA,UAAM,aAAS,mBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,IAAI,EAAE,WAAW,SAAS,OAAO,CAAC;AAEtF,aAAS,IAAI,IAAI,EAAE,IAAI,OAAO,QAAQ,OAAO,CAAC;AAC9C,eAAW;AAGX,UAAM,OAAO;AAAA,MACZ,QAAQ,UAAU,MAAM;AAAA,MAAC,CAAC;AAAA,MAC1B,WAAW,UAAU,MAAM;AAAA,MAAC,CAAC;AAAA,MAC7B,OAAO,UAAU,MAAM;AAAA,MAAC,CAAC;AAAA,IAC1B;AACA,QAAI,WAAW;AAEf,UAAM,SAAyB;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,OAAO;AACd,cAAM,OAAO,CAAC,GAAI,MAAM,QAAQ,CAAC,GAAI,SAAS,EAAE,EAAE;AAClD,eAAO,YAAY,IAAI,EAAE,GAAG,OAAO,KAAK,CAAC;AAAA,MAC1C;AAAA,MACA,YAAY,GAAG;AACd,cAAM,OAAO,CAAC;AAAA,MACf;AAAA,MACA,UAAU,GAAG;AACZ,eAAO,KAAK,CAAC;AACb,cAAM,OAAO,SAAS,IAAI,EAAE;AAC5B,YAAI,MAAM;AACT,mBAAS,IAAI,IAAI,EAAE,GAAG,MAAM,QAAQ,EAAE,CAAC;AACvC,qBAAW;AAAA,QACZ;AAAA,MACD;AAAA,MACA,UAAU;AACT,YAAI,SAAU;AACd,mBAAW;AAKX,mBAAW,KAAK,KAAM,GAAE;AACxB,iBAAS,OAAO,EAAE;AAClB,oBAAY,OAAO,MAAM;AACzB,mBAAW;AAAA,MACZ;AAAA,IACD;AACA,gBAAY,IAAI,MAAM;AACtB,WAAO;AAAA,EACR;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAgB;AAIf,iBAAW,KAAK,CAAC,GAAG,WAAW,EAAG,GAAE,QAAQ;AAC5C,kBAAY,QAAQ;AACpB,YAAM,QAAQ;AAAA,IACf;AAAA,EACD;AACD;;;AI/LA,IAAAC,eAAuC;AACvC,IAAAC,gBAAuB;AACvB,IAAAC,gBAAsB;;;ACItB,IAAAC,eAAqB;AACrB,IAAAC,gBAAuB;;;ACevB,IAAAC,eASO;AAEP,IAAAC,gBAA0B;AAC1B,IAAAC,gBAAyC;;;ACjCzC,IAAAC,eASO;AACP,IAAAC,gBAIO;AACP,IAAAC,gBAAsB;AAgCf,SAAS,oBAAoB,SAAuB,KAAa,KAAK,GAAY;AACxF,QAAM,MAAO,QAAQ,SAAgC;AACrD,MAAI,KAAK,MAAM,IAAK,QAAO;AAC3B,UAAQ,KAAK,CAAC,CAAC,kBAAK,GAAG,CAAC,mBAAM,MAAM,EAAE,CAAC,CAAC;AACxC,SAAO;AACR;AAiBO,IAAM,0BAAiC,qBAAO,CAAC,OAAO,SAAS;AACrE,QAAM,SAAS;AACf,QAAM,QAAQ;AACd,OAAK,OAAO;AACb,CAAC;AAwBM,SAAS,eACf,MACuB;AACvB,QAAM,UAAM,2BAAe,CAAC,GAAG;AAAA,IAC9B,MAAM,KAAK;AAAA,IACX,SAAS,KAAK,iBAAiB;AAAA,IAC/B,OAAO,KAAK,SAAS;AAAA,IACrB,GAAI,KAAK,cAAc,OAAO,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,EAClE,CAAC;AAGD,MAAI,WAAW;AACf,MAAI,KAAK,OAAO;AACf,SAAK,MAAM,IAAI,IAAI,SAAS,EAAE,MAAM,KAAK,KAAK,CAAC;AAAA,EAChD;AACA,SAAO;AACR;AAmEA,SAAS,WAAc,OAAa;AACnC,MAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO;AAClF,aAAW,KAAK,OAAO,KAAK,KAAgC,GAAG;AAC9D,eAAY,MAAkC,CAAC,CAAC;AAAA,EACjD;AACA,SAAO,OAAO,OAAO,KAAK;AAC3B;AAaO,SAAS,OACf,KACA,MAC8B;AAC9B,QAAM,EAAE,IAAI,KAAK,IAAI,OAAO,QAAQ,aAAa,EAAE,IAAI,KAAK,MAAM,OAAU,IAAI;AAChF,QAAM,SAAS,KAAK,UAAU;AAE9B,MAAI,KAAK,UAAU,UAAU;AAC5B,WAAO,SAAS,WAAW,MAAsB;AAChD,YAAM,SAAS,SAAU,KAAK,IAAI,UAAU,IAAyB;AACrE,YAAM,WAAO,0BAAY;AACzB,YAAM,MAAM,KAAK,MAAM,WAAW,KAAK,GAAG,IAAI;AAC9C,UAAI;AACH,cAAM,SAAS,GAAG,GAAG,MAAM;AAC3B,YAAI,KAAK,OAAO,KAAK,iBAAiB;AACrC;AAAA,YACC,KAAK;AAAA,YACL,KAAK;AAAA,YACL;AAAA,YACA;AAAA,YACA,EAAE,MAAM,IAAI;AAAA,YACZ,KAAK;AAAA,UACN;AAAA,QACD;AACA,eAAO;AAAA,MACR,SAAS,KAAK;AACb,YAAI,KAAK,OAAO,KAAK,iBAAiB;AACrC,gBAAM,YAAY,eAAe,QAAQ,IAAI,OAAO,OAAO;AAC3D;AAAA,YACC,KAAK;AAAA,YACL,KAAK;AAAA,YACL;AAAA,YACA;AAAA,YACA,EAAE,MAAM,KAAK,UAAU;AAAA,YACvB,KAAK;AAAA,UACN;AAAA,QACD;AACA,cAAM;AAAA,MACP;AAAA,IACD;AAAA,EACD;AAGA,SAAO,SAAS,WAAW,MAAsB;AAChD,UAAM,SAAS,SAAU,KAAK,IAAI,UAAU,IAAyB;AACrE,UAAM,WAAO,0BAAY;AACzB,QAAI;AACJ,QAAI;AACJ,QAAI,aAAa;AACjB,QAAI;AACJ,QAAI;AACH,8BAAM,MAAM;AACX,YAAI,KAAK,IAAK,OAAM,WAAW,KAAK,GAAG;AACvC,YAAI;AACH,mBAAS,GAAG,GAAG,MAAM;AACrB,cAAI,KAAK,OAAO,KAAK,iBAAiB;AACrC;AAAA,cACC,KAAK;AAAA,cACL,KAAK;AAAA,cACL;AAAA,cACA;AAAA,cACA,EAAE,MAAM,IAAI;AAAA,cACZ,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD,SAAS,KAAK;AACb,qBAAW;AACX,uBAAa;AACb,gBAAM;AAAA,QACP;AAAA,MACD,CAAC;AAAA,IACF,SAAS,UAAU;AAIlB,UAAI,cAAc,MAAM;AACvB,YAAI;AACH,eAAK,GAAG,MAAM;AAAA,QACf,SAAS,SAAS;AACjB,kBAAQ;AAAA,YACP,mEACC,oBAAoB,QAAQ,SAAS,OAAO,OAAO,QACpD;AAAA,YACA;AAAA,UACD;AAAA,QACD;AAAA,MACD;AACA,UAAI,cAAc,KAAK,OAAO,KAAK,iBAAiB;AACnD,cAAM,YAAY,oBAAoB,QAAQ,SAAS,OAAO,OAAO;AACrE;AAAA,UACC,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA,EAAE,MAAM,KAAK,UAAU;AAAA,UACvB,KAAK;AAAA,QACN;AAAA,MACD;AACA,YAAM,aAAa,WAAW;AAAA,IAC/B;AACA,WAAO;AAAA,EACR;AACD;AA2BA,IAAM,oBAAoB,oBAAI,QAAsB;AAC7C,SAAS,WAAW,KAA2B;AACrD,QAAM,MAAM,IAAI;AAChB,QAAM,QAAQ,OAAO,QAAQ,YAAY,OAAO,SAAS,GAAG;AAC5D,MAAI,CAAC,SAAS,QAAQ,UAAa,CAAC,kBAAkB,IAAI,GAAG,GAAG;AAC/D,sBAAkB,IAAI,GAAG;AACzB,YAAQ;AAAA,MACP,sDAAsD,OAAO,GAAG,CAAC;AAAA,IAIlE;AAAA,EACD;AACA,QAAM,MAAM,QAAQ,MAAM;AAC1B,QAAM,OAAO,MAAM;AACnB,MAAI,KAAK,CAAC,CAAC,kBAAK,GAAG,CAAC,mBAAM,IAAI,CAAC,CAAC;AAChC,SAAO;AACR;AAUO,SAAS,YAMf,OACA,SACA,MACA,OACAC,OACA,gBACO;AACP,QAAM,SAAS,QAAQ,MAAM,OAAOA,KAAI;AACxC,MAAI,WAAW,OAAW;AAC1B,QAAM,UAAU,kBAAkB,OAAQ,EAAE,GAAG,QAAQ,eAAe,IAAU;AAChF,QAAM,OAAO,OAAO;AACrB;AAWO,SAAS,eAAe,OAAc,MAAc,UAAU,GAAiB;AACrF,QAAM,aAAS,mBAAa,CAAC,GAAG,EAAE,SAAS,MAAM,cAAc,QAAQ,CAAC;AACxE,QAAM,IAAI,QAAQ,EAAE,KAAK,CAAC;AAC1B,SAAO;AACR;;;ACxPO,IAAM,eAAe;;;ACjH5B,IAAAC,eAAuD;AACvD,IAAAC,gBAA+D;AAC/D,IAAAC,gBAAyC;AAIzC,IAAM,uBAAuB;AAE7B,SAAS,sBAAsB,OAAe,OAAuB;AACpE,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AACrE,UAAM,IAAI,MAAM,GAAG,KAAK,iCAAiC;AAAA,EAC1D;AACA,SAAO;AACR;AAEA,SAAS,cAAc,MAAc,OAA0D;AAC9F,SAAO,WAAW,aAAa,MAAM,KAAK;AAC3C;AAQA,IAAM,+BAA+B;AAE9B,IAAM,aAAN,cAA4B,oBAAM;AAAA,EACvB;AAAA,EACA;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA;AAAA,EAET,YAAY,MAAc,OAAqB,CAAC,GAAG;AAClD,UAAM,MAAM,KAAK,KAAK;AACtB,SAAK,WAAO,2BAAe,CAAC,GAAG;AAAA,MAC9B,MAAM;AAAA,MACN,SAAS,KAAK,iBAAiB;AAAA,IAChC,CAAC;AACD,SAAK,SAAS,KAAK,KAAK;AACxB,SAAK,IAAI,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAcxC,SAAK,SAAS,KAAK;AAAA,MAClB;AAAA,MACA,CAAC,QAAQ;AAAA,MACT,CAAC,WAAW,QAAQ;AACnB,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,UAAU,KAAK,CAAC;AACtB,eAAO,QAAQ,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,QAAQ,SAAS,CAAC,CAAM;AAAA,MACrE;AAAA,MACA,EAAE,MAAM,cAAc,cAAc,EAAE;AAAA,IACvC;AACA,SAAK,gBAAY,yBAAU,KAAK,MAAM,CAAC;AAevC,SAAK,YAAY,MAAM;AACtB,WAAK,OAAO,KAAK,CAAC,CAAC,qBAAQ,CAAC,CAAC;AAAA,IAC9B,CAAC;AAKD,SAAK,YAAY,MAAM,KAAK,KAAK,gBAAgB,CAAC;AAQlD,SAAK,eAAe;AAAA,MACnB,CAAC,UAAgB;AAChB,aAAK,KAAK,OAAO,KAAK;AAAA,MACvB;AAAA,MACA,EAAE,OAAO,UAAU,QAAQ,MAAM;AAAA,IAClC;AAAA,EACD;AAAA,EAEA,QAAQ,OAAgB;AAIvB,QAAI,UAAU,QAAW;AACxB,YAAM,IAAI;AAAA,QACT,eAAe,KAAK,IAAI;AAAA,MACzB;AAAA,IACD;AACA,SAAK,aAAa,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,mBACC,OACa;AACb,WAAO,KAAK,KAAK,cAAc,KAAK;AAAA,EACrC;AAAA,EAEA,WAAyB;AACxB,WAAO,KAAK,OAAO;AAAA,EACpB;AAAA;AAAA,EAGA,IAAI,aAAa;AAChB,WAAO,KAAK;AAAA,EACb;AACD;AA8BO,IAAM,oBAAN,cAAmC,oBAAM;AAAA,EACtC;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA,EAED,YAAY;AAAA,EACH;AAAA,EACA;AAAA,EAEjB,YAAY,MAAc,YAA2B,OAA4B,CAAC,GAAG;AACpF,UAAM,MAAM,KAAK,KAAK;AACtB,SAAK,QAAQ;AAGb,QAAI;AACJ,QAAI,KAAK,SAAS,QAAW;AAC5B,UAAI,KAAK,SAAS,YAAY;AAC7B,wBAAgB;AAAA,MACjB,WAAW,KAAK,SAAS,OAAO;AAE/B,wBAAiB,WAAW,OAAO,MAAuB;AAAA,MAC3D,OAAO;AACN,wBAAgB,sBAAsB,KAAK,MAAM,mBAAmB;AAAA,MACrE;AAAA,IACD,OAAO;AACN,sBAAgB,sBAAsB,KAAK,UAAU,GAAG,qBAAqB;AAAA,IAC9E;AAEA,SAAK,SAAS,KAAK,MAAc,UAAU,eAAe;AAAA,MACzD,MAAM,cAAc,qBAAqB;AAAA,IAC1C,CAAC;AAMD,SAAK,YAAY,WAAW,WAAW,KAAK,EAAE,MAAM,cAAc,QAAQ,KAAK,OAAO,CAAC;AACvF,SAAK,IAAI,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,SAAK,gBAAY,yBAAU,KAAK,SAAS,CAAC;AAO1C,QAAI,KAAK,cAAc,QAAW;AACjC,YAAM,YAAY,KAAK;AACvB,UAAI,qBAAqB;AACzB,YAAM,kBAAc;AAAA,QACnB,CAAC,SAAS;AAAA,QACV,MAAM;AAEL,cAAI,CAAC,oBAAoB;AACxB,iCAAqB;AACrB;AAAA,UACD;AACA,cAAI,KAAK,UAAW;AACpB,gBAAM,QAAQ,KAAK,UAAU;AAC7B,cAAI,MAAM,WAAW,EAAG;AACxB,gBAAM,OAAQ,KAAK,OAAO,QAAmB,MAAM;AACnD,eAAK,OAAO,KAAK,IAAI;AAAA,QACtB;AAAA,QACA;AAAA,UACC,MAAM;AAAA,UACN,cAAc;AAAA,UACd,MAAM,cAAc,2BAA2B;AAAA,QAChD;AAAA,MACD;AACA,WAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,WAAK,gBAAY,yBAAU,WAAW,CAAC;AAAA,IACxC;AASA,SAAK,WAAW;AAAA,MACf,CAAC,UAAkB;AAClB,cAAM,YAAY,KAAK,UAAU;AACjC,cAAM,YACL,UAAU,SACP,UAAU,SACV,sBAAsB,OAAO,wBAAwB;AACzD,cAAM,OAAO,KAAK,IAAI,WAAW,UAAU,MAAM;AACjD,YAAI,QAAQ,EAAG,QAAO,KAAK,OAAO;AAClC,cAAM,OAAQ,KAAK,OAAO,QAAmB;AAI7C,aAAK,OAAO,KAAK,IAAI;AACrB,eAAO;AAAA,MACR;AAAA,MACA,EAAE,OAAO,UAAU,QAAQ,MAAM;AAAA,IAClC;AAEA,SAAK,kBAAkB;AAAA,MACtB,CAAC,UAA+B;AAC/B,cAAM,YAAY,KAAK,UAAU;AACjC,cAAM,MACL,UAAU,SACP,UAAU,SACV,sBAAsB,OAAO,+BAA+B;AAChE,cAAM,QAAQ,UAAU,MAAM,GAAG,GAAG;AACpC,YAAI,MAAM,WAAW,EAAG,QAAO,EAAE,OAAO,QAAQ,KAAK,OAAO,MAAgB;AAC5E,cAAM,OAAQ,KAAK,OAAO,QAAmB,MAAM;AACnD,aAAK,OAAO,KAAK,IAAI;AACrB,eAAO,EAAE,OAAO,QAAQ,KAAK;AAAA,MAC9B;AAAA,MACA,EAAE,OAAO,UAAU,QAAQ,MAAM;AAAA,IAClC;AAAA,EACD;AAAA,EAEA,IAAI,OAAwB;AAC3B,QAAI,KAAK,UAAW,QAAO,KAAK,OAAO;AACvC,WAAO,KAAK,SAAS,KAAK;AAAA,EAC3B;AAAA,EAEA,KAAK,OAA8B;AAClC,QAAI,KAAK,UAAW,QAAO,CAAC;AAC5B,UAAM,YAAY,KAAK,UAAU;AACjC,UAAM,MACL,UAAU,SACP,UAAU,SACV,sBAAsB,OAAO,yBAAyB;AAC1D,WAAO,UAAU,MAAM,GAAG,GAAG;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,WAAW,OAAqC;AAC/C,QAAI,KAAK,UAAW,QAAO,EAAE,OAAO,CAAC,GAAG,QAAQ,KAAK,OAAO,MAAgB;AAC5E,WAAO,KAAK,gBAAgB,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,UAAgB;AACf,QAAI,KAAK,UAAW;AACpB,SAAK,YAAY;AACjB,SAAK,OAAO,KAAK,CAAC,CAAC,qBAAQ,CAAC,CAAC;AAE7B,SAAK,QAAQ;AAAA,EACd;AACD;AAkBO,IAAM,mBAAN,cAAgD,oBAAM;AAAA,EAC3C;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA,EAET,YACC,MACA,aACA,aACA,OAAsC,CAAC,GACtC;AACD,UAAM,MAAM,KAAK,KAAK;AACtB,SAAK,aAAa,aAAkB,GAAG,IAAI,iBAAiB,aAAa;AAAA,MACxE,QAAQ,KAAK;AAAA,IACd,CAAC;AACD,SAAK,MAAM,gBAAgB,KAAK,UAAU;AAE1C,UAAM,aAAa,KAAK;AAAA,MACvB;AAAA,MACA,sBAAsB,KAAK,cAAc,sBAAsB,yBAAyB;AAAA,IACzF;AACA,UAAM,WAAW,KAAK,QAAQ,CAAC,UAAe;AAM9C,SAAK,aAAS;AAAA,MACb,CAAC,KAAK,WAAW,SAAS;AAAA,MAC1B,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACA,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,cAAM,WAAmB,CAAC;AAC1B,cAAM,OAAO,KAAK,IAAI,IAAI,QAAQ,UAAU;AAC5C,iBAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC9B,gBAAM,SAAS,SAAS,IAAI,CAAC,CAAQ;AACrC,cAAI,WAAW,OAAW,UAAS,KAAK,MAAM;AAAA,QAC/C;AACA,gBAAQ,KAAK,QAAQ;AAAA,MACtB;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,cAAc,uBAAuB,EAAE,WAAW,YAAY,KAAK,CAAC;AAAA,QAC1E,SAAS,CAAC;AAAA,MACX;AAAA,IACD;AACA,SAAK,IAAI,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,SAAK,gBAAY,yBAAU,KAAK,MAAM,CAAC;AAIvC,SAAK,eAAe,KAAK,MAAc,gBAAgB,GAAG;AAAA,MACzD,MAAM,cAAc,oBAAoB;AAAA,IACzC,CAAC;AACD,SAAK,gBAAY,yBAAU,KAAK,YAAY,CAAC;AAM7C,UAAM,YAAY,KAAK;AACvB,UAAM,SAAS,KAAK;AACpB,UAAM,WAAW,KAAK;AACtB,UAAM,UAAU,KAAK;AAAA,MACpB;AAAA,MACA,CAAC,QAAQ;AAAA,MACT,MAAM;AACL,cAAM,WAAW,UAAU;AAC3B,YAAI,SAAS,WAAW,EAAG;AAC3B,cAAM,WAAY,OAAO,UAAU,MAAyB;AAC5D,cAAM,QAAQ,KAAK,IAAI,UAAU,UAAU;AAC3C,YAAI,QAAQ,GAAG;AACd,iBAAO,IAAI,KAAK;AAChB,gBAAM,OAAQ,SAAS,SAAoB;AAC3C,mBAAS,KAAK,OAAO,SAAS,MAAM;AAAA,QACrC;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM,cAAc,uBAAuB;AAAA,MAC5C;AAAA,IACD;AACA,SAAK,gBAAY,yBAAU,OAAO,CAAC;AAKnC,UAAM,SAAS,kBAAkB,KAAK,QAAQ,WAAW;AACzD,SAAK,YAAY,MAAM;AAAA,EACxB;AACD;AAOA,SAAS,kBAAqB,QAA4B,aAAwC;AACjG,SAAO,OAAO,UAAU,CAAC,SAAS;AACjC,eAAW,KAAK,MAAM;AACrB,UAAI,EAAE,CAAC,MAAM,kBAAM;AACnB,YAAM,MAAM,EAAE,CAAC;AACf,UAAI,IAAI,WAAW,EAAG;AACtB,8BAAM,MAAM;AACX,mBAAW,KAAK,IAAK,aAAY,QAAQ,CAAC;AAAA,MAC3C,CAAC;AAAA,IACF;AAAA,EACD,CAAC;AACF;AAcO,IAAM,gBAAN,MAAoB;AAAA,EACT,OAAO,oBAAI,IAAiC;AAAA;AAAA,EAEpD;AAAA,EAET,YAAY,aAA2B;AACtC,SAAK,UAAU;AAAA,EAChB;AAAA,EAEA,IAAI,OAAe;AAClB,WAAO,KAAK,KAAK;AAAA,EAClB;AAAA,EAEA,IAAI,MAAuB;AAC1B,WAAO,KAAK,KAAK,IAAI,IAAI;AAAA,EAC1B;AAAA,EAEA,IAAO,MAAyC;AAC/C,WAAO,KAAK,KAAK,IAAI,IAAI;AAAA,EAC1B;AAAA,EAEA,IAAO,MAAc,GAAwB;AAC5C,SAAK,KAAK,IAAI,MAAM,CAAwB;AAAA,EAC7C;AAAA,EAEA,OAAO,MAAuB;AAC7B,WAAO,KAAK,KAAK,OAAO,IAAI;AAAA,EAC7B;AAAA,EAEA,OAAiC;AAChC,WAAO,KAAK,KAAK,KAAK;AAAA,EACvB;AACD;AA6BO,IAAM,oBAAN,cAAgC,oBAAM;AAAA,EAC3B;AAAA;AAAA,EAER;AAAA,EACQ;AAAA,EACA;AAAA,EAEjB,YAAY,MAAc,OAA4B,CAAC,GAAG;AACzD,UAAM,MAAM,KAAK,KAAK;AAEtB,UAAM,cAAc,KAAK,MAAc,WAAW,GAAG;AAAA,MACpD,MAAM,cAAc,aAAa;AAAA,IAClC,CAAC;AACD,SAAK,UAAU;AACf,SAAK,YAAY,IAAI,cAAc,WAAW;AAG9C,SAAK,uBAAuB,EAAE,GAAI,KAAK,uBAAuB,CAAC,EAAG;AAclE,SAAK,mBAAmB;AAAA,MACvB,CAAC,cAAoB;AACpB,YAAI;AACH,eAAK,OAAO,SAAS;AAAA,QACtB,UAAE;AACD,eAAK,UAAU,OAAO,SAAS;AAC/B,gBAAM,MAAO,KAAK,QAAQ,SAAoB;AAC9C,eAAK,QAAQ,KAAK,MAAM,CAAC;AAAA,QAC1B;AAAA,MACD;AAAA,MACA,EAAE,OAAO,UAAU,QAAQ,MAAM;AAAA,IAClC;AAAA,EACD;AAAA;AAAA,EAGA,IAAI,OAAe;AAClB,WAAO,KAAK,UAAU;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,MAAuB;AAC1B,WAAO,KAAK,UAAU,IAAI,IAAI;AAAA,EAC/B;AAAA;AAAA,EAGA,aAAuC;AACtC,WAAO,KAAK,UAAU,KAAK;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAmB,MAAc,MAAoC;AACpE,QAAI,IAAI,KAAK,UAAU,IAAO,IAAI;AAClC,QAAI,MAAM,QAAW;AACpB,YAAM,YAA0B,EAAE,GAAG,KAAK,sBAAsB,GAAI,QAAQ,CAAC,EAAG;AAChF,UAAI,IAAI,WAAc,MAAM,SAAS;AACrC,WAAK,UAAU,IAAI,MAAM,CAAC;AAC1B,WAAK,MAAM,MAAM,CAAC;AAClB,YAAM,MAAO,KAAK,QAAQ,SAAoB;AAC9C,WAAK,QAAQ,KAAK,MAAM,CAAC;AAAA,IAC1B;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,QAAqB,MAAc,OAAgB;AAClD,SAAK,MAAS,IAAI,EAAE,QAAQ,KAAK;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,YAAY,SAA4C;AAGvD,4BAAM,MAAM;AACX,iBAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACpC,aAAK,MAAM,IAAI,EAAE,QAAQ,KAAK;AAAA,MAC/B;AAAA,IACD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,UACC,SACA,WACA,MACuB;AACvB,UAAM,IAAI,KAAK,MAAS,SAAS;AACjC,WAAO,IAAI,kBAAqB,SAAS,GAAG,IAAI;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,YAAY,MAAuB;AAClC,QAAI,CAAC,KAAK,UAAU,IAAI,IAAI,EAAG,QAAO;AAKtC,SAAK,iBAAiB,IAAI;AAC1B,WAAO;AAAA,EACR;AACD;AAKO,SAAS,MAAS,MAAc,MAAoC;AAC1E,SAAO,IAAI,WAAc,MAAM,IAAI;AACpC;AAgBO,SAAS,aAAa,MAAc,MAA+C;AACzF,SAAO,IAAI,kBAAkB,MAAM,IAAI;AACxC;AAKO,SAAS,aACf,MACA,YACA,MACuB;AACvB,SAAO,IAAI,kBAAqB,MAAM,YAAY,IAAI;AACvD;AAUO,SAAS,YACf,MACA,aACA,aACA,MAC8B;AAC9B,SAAO,IAAI,iBAA4B,MAAM,aAAa,aAAa,IAAI;AAC5E;;;AHlgBO,IAAM,kBAAN,cAAiC,oBAAM;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAGQ;AAAA,EAEjB,YACC,MACA,WACA,iBACA,MACC;AACD,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,MAAM,KAAK,KAAK;AAQtB,SAAK;AAAA,MACJ;AAAA,UACA,8BAAgB,EAAE,MAAM,WAAW,iBAAiB,GAAG,KAAK,CAG3D;AAAA,IACF;AAGA,UAAM,cAA4C,OAA+B,KAAK,OAAO,IAC1F,KAAK,cACL,aAAAC,MAAmC,CAAC,GAAG;AAAA,MACvC,MAAM;AAAA,MACN,SAAS,KAAK;AAAA,IACf,CAAC;AACH,SAAK,IAAI,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,UAAM,uBAAmB,aAAAA,MAAmB,CAAC,GAAG,EAAE,MAAM,aAAa,SAAS,EAAE,CAAC;AACjF,SAAK,IAAI,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,UAAM,mBAAe,aAAAA,MAA8B,CAAC,GAAG;AAAA,MACtD,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,MAAM;AAAA;AAAA,IACf,CAAC;AACD,SAAK,IAAI,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,UAAM,wBAAoB,aAAAA,MAA4B,CAAC,GAAG;AAAA,MACzD,MAAM;AAAA,MACN,SAAS;AAAA,IACV,CAAC;AACD,SAAK,IAAI,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,UAAM,0BAAsB,aAAAA,MAAyB,CAAC,GAAG;AAAA,MACxD,MAAM;AAAA,MACN,SAAS,CAAC;AAAA,IACX,CAAC;AACD,SAAK,IAAI,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,UAAM,iBAAa,aAAAA,MAAoB,CAAC,GAAG,EAAE,MAAM,UAAU,SAAS,MAAM,CAAC;AAC7E,SAAK,IAAI,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,UAAM,kBAAc,aAAAA,MAAyB,CAAC,GAAG,EAAE,MAAM,UAAU,SAAS,UAAU,CAAC;AACvF,SAAK,IAAI,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,UAAM,mBAAe,aAAAA,MAAoC,CAAC,GAAG;AAAA,MAC5D,MAAM;AAAA,MACN,SAAS,CAAC;AAAA,MACV,QAAQ,MAAM;AAAA;AAAA,IACf,CAAC;AACD,SAAK,IAAI,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,UAAM,gBAAY,aAAAA,MAAqB,CAAC,GAAG,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAC1E,SAAK,IAAI,WAAW,EAAE,MAAM,OAAO,CAAC;AAEpC,UAAM,iBAAa,aAAAA,MAAmB,CAAC,GAAG,EAAE,MAAM,SAAS,SAAS,OAAO,kBAAkB,CAAC;AAC9F,SAAK,IAAI,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,UAAM,kBAAc,aAAAA,MAAmB,CAAC,GAAG,EAAE,MAAM,eAAe,SAAS,EAAE,CAAC;AAC9E,SAAK,IAAI,aAAa,EAAE,MAAM,cAAc,CAAC;AAQ7C,UAAM,MAAM,aAAa,QAAQ;AACjC,SAAK,MAAM,UAAU,GAAG;AACxB,UAAM,mBAAmB,IAAI,MAAwB,UAAU;AAC/D,UAAM,mBAAmB,IAAI,MAAwB,UAAU;AAC/D,UAAM,kBAAkB,IAAI,MAAuB,SAAS;AAC5D,UAAM,iBAAiB,IAAI,MAAmB,QAAQ;AAUtD,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,WAAW;AAChB,SAAK,aAAa;AAClB,SAAK,WAAW;AAChB,SAAK,WAAW;AAChB,SAAK,UAAU;AACf,SAAK,SAAS;AACd,SAAK,cAAc;AAUnB,QAAI,iBAAoC;AACxC,QAAI,iBAAkC;AACtC,QAAI,uBAAqC,CAAC;AAC1C,SAAK;AAAA,MACJ,aAAa,UAAU,CAAC,SAAS;AAChC,mBAAW,KAAK,KAAM,KAAI,EAAE,CAAC,MAAM,kBAAM,kBAAiB,EAAE,CAAC;AAAA,MAC9D,CAAC;AAAA,IACF;AACA,SAAK;AAAA,MACJ,kBAAkB,UAAU,CAAC,SAAS;AACrC,mBAAW,KAAK,KAAM,KAAI,EAAE,CAAC,MAAM,kBAAM,kBAAiB,EAAE,CAAC;AAAA,MAC9D,CAAC;AAAA,IACF;AACA,SAAK;AAAA,MACJ,oBAAoB,UAAU,CAAC,SAAS;AACvC,mBAAW,KAAK,KAAM,KAAI,EAAE,CAAC,MAAM,kBAAM,wBAAuB,EAAE,CAAC;AAAA,MACpE,CAAC;AAAA,IACF;AAuBA,UAAM,qBAAiB;AAAA,MACtB;AAAA,MACA,CAAC,SAAS;AACT,cAAM,QAAQ;AACd,cAAM,SAAS,SAAS,KAAK,kBAAkB;AAC/C,mBAAO,aAAAA;AAAA,UACN,CAAC;AAAA,UACD,CAAC,OAAO,YAAY;AACnB,gBAAI,YAAY;AAChB,gBAAI;AACH,oBAAM,SAAS,SACZ,MAAM,KAAK,IAAI,IACf,MAAM,SAAS,gBAA4B,oBAAoB;AAClE,kBAAI,kBAAkB,SAAS;AAC9B,uBAAO;AAAA,kBACN,CAAC,MAAM;AACN,wBAAI,CAAC,UAAW,SAAQ,KAAK,EAAE,MAAM,OAAO,EAAE,CAAC;AAAA,kBAChD;AAAA,kBACA,CAAC,QAAQ;AACR,wBAAI,CAAC,UAAW,SAAQ,KAAK,CAAC,CAAC,oBAAO,GAAG,CAAC,CAAC;AAAA,kBAC5C;AAAA,gBACD;AACA,uBAAO;AAAA,kBACN,gBAAgB,MAAM;AACrB,gCAAY;AAAA,kBACb;AAAA,gBACD;AAAA,cACD;AACA,sBAAQ,KAAK,EAAE,MAAM,OAAO,OAAO,CAAC;AAAA,YACrC,SAAS,KAAK;AACb,0BAAY;AACZ,sBAAQ,KAAK,CAAC,CAAC,oBAAO,GAAG,CAAC,CAAC;AAAA,YAC5B;AACA,mBAAO;AAAA,UACR;AAAA,UACA,EAAE,cAAc,WAAW;AAAA,QAC5B;AAAA,MACD;AAAA,MACA,EAAE,MAAM,aAAa;AAAA,IACtB;AACA,SAAK,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAK/C,UAAM,0BAAsB,aAAAA;AAAA,MAC3B,CAAC,cAAc;AAAA,MACf,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,QAAQ,QAAW;AACtB,kBAAQ,KAAK,CAAC,CAAC,qBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,gBAAQ,KAAK,IAAI,KAAK;AAAA,MACvB;AAAA,MACA,EAAE,MAAM,oBAAoB,cAAc,UAAU;AAAA,IACrD;AACA,SAAK,IAAI,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAK1D,UAAM,mBAAe,aAAAD;AAAA,MACpB,CAAC,cAAc;AAAA,MACf,CAAC,YAAY,UAAU,QAAQ;AAC9B,cAAM,WAAW,IAAI,aAAa,CAAC;AACnC,YAAI,aAAa,UAAa,aAAa,MAAM;AAChD,sBAAY,KAAK,SAAS;AAAA,QAC3B;AAAA,MACD;AAAA,MACA,EAAE,MAAM,iBAAiB,cAAc,UAAU,oBAAoB,MAAM;AAAA,IAC5E;AACA,SAAK,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,SAAK,YAAY,aAAa,UAAU,MAAM,MAAS,CAAC;AASxD,UAAM,wBAAoB,aAAAA;AAAA,MACzB,CAAC,cAAc;AAAA,MACf,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,gBAAQ,KAAK;AAAA,UACZ,WAAW,IAAI;AAAA,UACf,YAAY,IAAI;AAAA,UAChB,kBAAc,0BAAY;AAAA,QAC3B,CAAC;AAAA,MACF;AAAA,MACA,EAAE,MAAM,kBAAkB,cAAc,UAAU;AAAA,IACnD;AACA,SAAK,IAAI,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,SAAK,YAAY,kBAAkB,UAAU,MAAM,MAAS,CAAC;AAE7D,UAAM,4BAAwB,aAAAD;AAAA,MAC7B,CAAC,iBAAiB;AAAA,MAClB,CAAC,WAAW,UAAU,QAAQ;AAC7B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,yBAAiB,QAAQ,KAAK,CAAC,CAAqB;AAAA,MACrD;AAAA,MACA,EAAE,MAAM,oBAAoB,cAAc,SAAS;AAAA,IACpD;AACA,SAAK,IAAI,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,SAAK,YAAY,sBAAsB,UAAU,MAAM,MAAS,CAAC;AAEjE,UAAM,2BAAuB,aAAAD;AAAA,MAC5B,CAAC,cAAc;AAAA,MACf,CAAC,WAAW,UAAU,QAAQ;AAC7B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,4BAAoB,KAAK,IAAI,KAAK;AAAA,MACnC;AAAA,MACA,EAAE,MAAM,mBAAmB,cAAc,SAAS;AAAA,IACnD;AACA,SAAK,IAAI,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,SAAK,YAAY,qBAAqB,UAAU,MAAM,MAAS,CAAC;AAIhE,UAAM,aAAa,UAAU,qBAAqB,WAAW;AAC7D,SAAK,IAAI,YAAY,EAAE,MAAM,SAAS,CAAC;AAMvC,UAAM,wBAAoB,aAAAD;AAAA,MACzB,CAAC,YAAY,cAAc;AAAA,MAC3B,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,cAAc,UAAU,CAAC,KAAK,QAAQ,UAAU,CAAC,EAAE,SAAS;AAClE,YAAI,CAAC,aAAa;AACjB,kBAAQ,KAAK,CAAC,CAAC,qBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,SAAS,KAAK,CAAC;AACrB,cAAM,MAAM,KAAK,CAAC;AAClB,gBAAQ,KAAK;AAAA,UACZ,WAAW,IAAI;AAAA,UACf,YAAY,IAAI;AAAA,UAChB;AAAA,UACA,kBAAc,0BAAY;AAAA,QAC3B,CAAC;AAAA,MACF;AAAA,MACA,EAAE,MAAM,kBAAkB,cAAc,UAAU;AAAA,IACnD;AACA,SAAK,IAAI,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,SAAK,YAAY,kBAAkB,UAAU,MAAM,MAAS,CAAC;AAE7D,UAAM,4BAAwB,aAAAD;AAAA,MAC7B,CAAC,iBAAiB;AAAA,MAClB,CAAC,WAAW,UAAU,QAAQ;AAC7B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,yBAAiB,QAAQ,KAAK,CAAC,CAAqB;AAAA,MACrD;AAAA,MACA,EAAE,MAAM,oBAAoB,cAAc,SAAS;AAAA,IACpD;AACA,SAAK,IAAI,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,SAAK,YAAY,sBAAsB,UAAU,MAAM,MAAS,CAAC;AAUjE,UAAM,2BAAuB,aAAAD;AAAA,MAC5B,CAAC,YAAY,cAAc;AAAA,MAC3B,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,cAAc,UAAU,CAAC,KAAK,QAAQ,UAAU,CAAC,EAAE,SAAS;AAClE,YAAI,CAAC,aAAa;AACjB,kBAAQ,KAAK,CAAC,CAAC,qBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,SAAS,KAAK,CAAC;AACrB,cAAM,MAAM,KAAK,CAAC;AAClB,gBAAQ,KAAK;AAAA,UACZ,MAAM,IAAI;AAAA,UACV,OAAO,IAAI;AAAA,UACX;AAAA,UACA,UAAU,eAAe,QAAQ,QAAQ,IAAI,KAAK;AAAA,QACnD,CAAC;AAAA,MACF;AAAA,MACA,EAAE,MAAM,qBAAqB,cAAc,UAAU;AAAA,IACtD;AACA,SAAK,IAAI,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAK5D,UAAM,mBAAe,aAAAD;AAAA,MACpB,CAAC,oBAAoB;AAAA,MACrB,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,QAAQ,KAAK,CAAC;AACpB,gBAAQ,KAAK,MAAM,QAAQ;AAAA,MAC5B;AAAA,MACA,EAAE,MAAM,YAAY,cAAc,UAAU;AAAA,IAC7C;AACA,SAAK,IAAI,cAAc,EAAE,MAAM,WAAW,CAAC;AAK3C,UAAM,uBAAmB,aAAAD;AAAA,MACxB,CAAC,oBAAoB;AAAA,MACrB,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,QAAQ,KAAK,CAAC;AACpB,gBAAQ,KAAK;AAAA,UACZ,WAAW,MAAM;AAAA,UACjB,YAAY,MAAM;AAAA,UAClB,UAAU,MAAM;AAAA,UAChB,kBAAc,0BAAY;AAAA,QAC3B,CAAC;AAAA,MACF;AAAA,MACA,EAAE,MAAM,iBAAiB,cAAc,UAAU;AAAA,IAClD;AACA,SAAK,IAAI,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,SAAK,YAAY,iBAAiB,UAAU,MAAM,MAAS,CAAC;AAE5D,UAAM,2BAAuB,aAAAD;AAAA,MAC5B,CAAC,gBAAgB;AAAA,MACjB,CAAC,WAAW,UAAU,QAAQ;AAC7B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,wBAAgB,QAAQ,KAAK,CAAC,CAAoB;AAAA,MACnD;AAAA,MACA,EAAE,MAAM,mBAAmB,cAAc,SAAS;AAAA,IACnD;AACA,SAAK,IAAI,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,SAAK,YAAY,qBAAqB,UAAU,MAAM,MAAS,CAAC;AAGhE,UAAM,mBAAe,aAAAD;AAAA,MACpB,CAAC,YAAY;AAAA,MACb,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,IAAI,KAAK,CAAC;AAChB,YAAI,KAAK,YAAY,QAAQ,EAAE,UAAU,KAAK,UAAU;AACvD,kBAAQ,KAAK,KAAK;AAClB;AAAA,QACD;AAEA,cAAM,WAAW,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE;AAC7C,cAAM,WAAW,SAAS,CAAC,EAAG;AAC9B,gBAAQ,KAAK,SAAS,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,QAAQ,CAAC;AAAA,MACrE;AAAA,MACA,EAAE,MAAM,kBAAkB,cAAc,UAAU;AAAA,IACnD;AACA,SAAK,IAAI,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,UAAM,mBAAe,aAAAD;AAAA,MACpB,CAAC,UAAU;AAAA,MACX,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,gBAAQ,KAAK,KAAK,YAAY,QAAS,KAAK,CAAC,KAAgB,KAAK,QAAQ;AAAA,MAC3E;AAAA,MACA,EAAE,MAAM,mBAAmB,cAAc,UAAU;AAAA,IACpD;AACA,SAAK,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,UAAM,mBAAe,aAAAD;AAAA,MACpB,CAAC,YAAY;AAAA,MACb,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,IAAI,KAAK,CAAC;AAChB,YAAI,KAAK,YAAY,QAAQ,EAAE,SAAS,GAAG;AAC1C,kBAAQ,KAAK,KAAK;AAClB;AAAA,QACD;AACA,cAAM,OAAO,EAAE,EAAE,SAAS,CAAC,EAAG;AAC9B,cAAM,OAAO,EAAE,EAAE,SAAS,CAAC,EAAG;AAC9B,gBAAQ,KAAK,KAAK,IAAI,OAAO,IAAI,IAAI,KAAK,QAAQ;AAAA,MACnD;AAAA,MACA,EAAE,MAAM,mBAAmB,cAAc,UAAU;AAAA,IACpD;AACA,SAAK,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,UAAM,mBAAe,aAAAD;AAAA,MACpB,CAAC,WAAW;AAAA,MACZ,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,gBAAQ,KAAK,KAAK,kBAAkB,QAAS,KAAK,CAAC,KAAgB,KAAK,cAAc;AAAA,MACvF;AAAA,MACA,EAAE,MAAM,yBAAyB,cAAc,UAAU;AAAA,IAC1D;AACA,SAAK,IAAI,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,UAAM,kBAAc,aAAAD;AAAA,MACnB,CAAC,gBAAgB;AAAA,MACjB,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,gBAAQ,KAAK,KAAK,iBAAiB,QAAS,KAAK,CAAC,KAAgB,KAAK,aAAa;AAAA,MACrF;AAAA,MACA,EAAE,MAAM,wBAAwB,cAAc,UAAU;AAAA,IACzD;AACA,SAAK,IAAI,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,UAAM,0BAAsB,aAAAD;AAAA,MAC3B,CAAC,WAAW;AAAA,MACZ,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,gBAAQ,KAAK,KAAK,UAAU,QAAS,KAAK,CAAC,KAAgB,KAAK,MAAM;AAAA,MACvE;AAAA,MACA,EAAE,MAAM,0BAA0B,cAAc,UAAU;AAAA,IAC3D;AACA,SAAK,IAAI,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAMhE,SAAK,YAAY,aAAa,UAAU,MAAM,MAAS,CAAC;AACxD,SAAK,YAAY,aAAa,UAAU,MAAM,MAAS,CAAC;AACxD,SAAK,YAAY,aAAa,UAAU,MAAM,MAAS,CAAC;AACxD,SAAK,YAAY,aAAa,UAAU,MAAM,MAAS,CAAC;AACxD,SAAK,YAAY,YAAY,UAAU,MAAM,MAAS,CAAC;AACvD,SAAK,YAAY,oBAAoB,UAAU,MAAM,MAAS,CAAC;AAE/D,UAAM,oBAAgB,aAAAD;AAAA,MACrB,CAAC,cAAc,cAAc,cAAc,cAAc,WAAW;AAAA,MACpE,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,IAAI;AAC5B,YAAI,GAAG;AACN,kBAAQ,KAAK,EAAE,WAAW,MAAM,QAAQ,WAAW,CAAC;AACpD;AAAA,QACD;AACA,YAAI,IAAI;AACP,kBAAQ,KAAK,EAAE,WAAW,MAAM,QAAQ,YAAY,CAAC;AACrD;AAAA,QACD;AACA,YAAI,IAAI;AACP,kBAAQ,KAAK,EAAE,WAAW,MAAM,QAAQ,YAAY,CAAC;AACrD;AAAA,QACD;AACA,YAAI,IAAI;AACP,kBAAQ,KAAK,EAAE,WAAW,MAAM,QAAQ,kBAAkB,CAAC;AAC3D;AAAA,QACD;AACA,YAAI,IAAI;AACP,kBAAQ,KAAK,EAAE,WAAW,MAAM,QAAQ,iBAAiB,CAAC;AAC1D;AAAA,QACD;AACA,gBAAQ,KAAK,EAAE,WAAW,MAAM,CAAC;AAAA,MAClC;AAAA,MACA,EAAE,MAAM,aAAa,cAAc,UAAU;AAAA,IAC9C;AACA,SAAK,IAAI,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,SAAK,YAAY,cAAc,UAAU,MAAM,MAAS,CAAC;AAiDzD,QAAI,uBAAuB;AAC3B,UAAM,mBAAe,aAAAD;AAAA,MACpB,CAAC,sBAAsB,UAAU;AAAA,MACjC,CAAC,WAAW,UAAU,QAAQ;AAK7B,cAAM,gBAAgB,UAAU,CAAC,KAAK,QAAQ,UAAU,CAAC,EAAE,SAAS;AACpE,YAAI,CAAC,cAAe;AAEpB,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAOC,OAClCD,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAASC,EAAC;AAAA,QAClE;AACA,cAAM,QAAQ,KAAK,CAAC;AACpB,cAAM,SAAS,KAAK,CAAC;AAErB,cAAM,IAAI,MAAM;AAChB,cAAM,KAAK,MAAM;AACjB,cAAM,KAAK,MAAM;AACjB,cAAM,SAAS,MAAM;AAIrB,YAAI,KAAK,qBAAsB;AAC/B,+BAAuB;AAIvB,cAAM,iBAAiB,aAAa;AACpC,cAAM,gBAAgB,YAAY;AAGlC,cAAM,EAAE,MAAM,UAAU,IAAI,SAAS,IAAI,MAAM;AAC/C,cAAM,YAA0B;AAAA,UAC/B,GAAG;AAAA,UACH,YAAY;AAAA,UACZ;AAAA,UACA,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA,kBAAc,0BAAY;AAAA,QAC3B;AACA,cAAM,cAAc,CAAC,GAAG,gBAAgB,SAAS;AAEjD,cAAM,aAAa,gBAAgB,GAAG;AAOtC,YAAI,WAAoC;AACxC,YAAI;AACJ,cAAM,YAAY,KAAK,UAAU,QAAQ,cAAc,KAAK;AAC5D,YAAI,WAAW;AACd,qBAAW;AACX,mBAAS;AAAA,QACV,WAAW,KAAK,YAAY,QAAQ,GAAG,SAAS,KAAK,UAAU;AAC9D,qBAAW;AACX,mBAAS;AAAA,QACV,WAAW,KAAK,iBAAiB,QAAQ,KAAK,KAAK,eAAe;AACjE,qBAAW;AACX,mBAAS;AAAA,QACV,WAAW,KAAK,kBAAkB,QAAQ,cAAc,KAAK,gBAAgB;AAC5E,qBAAW;AACX,mBAAS;AAAA,QACV,WAAW,KAAK,YAAY,QAAQ,YAAY,UAAU,GAAG;AAC5D,gBAAM,OAAO,YAAY,YAAY,SAAS,CAAC,EAAG;AAClD,gBAAM,OAAO,YAAY,YAAY,SAAS,CAAC,EAAG;AAClD,cAAI,KAAK,IAAI,OAAO,IAAI,IAAI,KAAK,UAAU;AAC1C,uBAAW;AACX,qBAAS;AAAA,UACV;AAAA,QACD,WAAW,KAAK,YAAY,QAAQ,YAAY,SAAS,KAAK,UAAU;AACvE,gBAAM,WAAW,YAAY,MAAM,EAAE,KAAK,WAAW,EAAE;AACvD,gBAAM,WAAW,SAAS,CAAC,EAAG;AAC9B,cAAI,SAAS,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,GAAG,aAAa,QAAQ,GAAG;AAC9D,uBAAW;AACX,qBAAS;AAAA,UACV;AAAA,QACD;AAGA,YAAI,aAAa,cAAc,QAAQ;AACtC,qBAAW;AAAA,QACZ;AAOA,gCAAM,MAAM;AACX,oBAAU,KAAK,IAAI;AACnB,qBAAW,KAAK,GAAG,KAAK;AACxB,uBAAa,KAAK,WAAW;AAC7B,sBAAY,KAAK,UAAU;AAC3B,4BAAkB,KAAK,EAAE;AACzB,yBAAe,QAAQ;AAAA,YACtB,WAAW;AAAA,YACX;AAAA,YACA;AAAA,YACA,kBAAc,0BAAY;AAAA,UAC3B,CAAC;AAED,cAAI,aAAa,YAAY;AAC5B,6BAAiB,KAAK,IAAI,CAAC;AAAA,UAC5B,OAAO;AACN,wBAAY;AAAA,cACX,aAAa,cAAc,cAAc,aAAa,WAAW,WAAW;AAAA,YAC7E;AAAA,UACD;AAAA,QACD,CAAC;AAAA,MACF;AAAA,MACA,EAAE,MAAM,iBAAiB,cAAc,SAAS;AAAA,IACjD;AACA,SAAK,IAAI,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,SAAK,YAAY,aAAa,UAAU,MAAM,MAAS,CAAC;AAAA,EAQzD;AAAA;AAAA,EAGA,YAAY,MAA+B;AAC1C,SAAK,SAAS,KAAK,IAAI;AAAA,EACxB;AAAA;AAAA,EAGA,QAAc;AACb,SAAK,YAAY,KAAK,IAAI;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAe;AACd,QAAI,KAAK,OAAO,UAAU,SAAU;AACpC,4BAAM,MAAM;AACX,WAAK,YAAY,KAAK,KAAK;AAC3B,WAAK,OAAO,KAAK,SAAyB;AAC1C,WAAK,WAAW,KAAM,KAAK,WAAW,QAAmB,CAAC;AAAA,IAC3D,CAAC;AAAA,EACF;AACD;AAWA,SAAS,OAAU,GAA0B;AAC5C,MAAI,OAAO,MAAM,YAAY,MAAM,KAAM,QAAO;AAChD,QAAM,MAAM;AACZ,SACC,OAAO,IAAI,cAAc,cACzB,OAAO,IAAI,SAAS,cACpB,OAAO,IAAI,SAAS;AAEtB;AAEA,SAAS,SACR,YACA,QACwC;AAGxC,MAAI,WAAW,WAAW,GAAG;AAC5B,WAAO,EAAE,MAAM,MAAM,WAAW,OAAO,kBAAkB;AAAA,EAC1D;AACA,MAAI,WAAW,WAAW,GAAG;AAC5B,UAAM,OAAO,UAAU,MAAM;AAC7B,WAAO,EAAE,MAAM,WAAW,CAAC,GAAI,WAAW,KAAK;AAAA,EAChD;AAIA,QAAM,YAAY,OAAO,KAAK,CAAC,MAAM,OAAO,EAAE,mBAAmB,QAAQ;AACzE,MAAI,WAAW;AACd,UAAM,OAAO,IAAI,MAAsC,WAAW,MAAM;AACxE,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,IAAK,MAAK,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,EAAE;AACzE,eAAW,KAAK,QAAQ;AACvB,YAAM,MAAM,EAAE;AACd,UAAI,OAAO,QAAQ,YAAY,OAAO,KAAK,MAAM,WAAW,QAAQ;AACnE,aAAK,GAAG,EAAG,OAAO,EAAE;AACpB,aAAK,GAAG,EAAG,SAAS;AAAA,MACrB;AAAA,IACD;AACA,QAAIC,QAAO,WAAW,CAAC;AACvB,QAAIC,aAAY,KAAK,CAAC,EAAG,QAAQ,IAAI,KAAK,CAAC,EAAG,MAAM,KAAK,CAAC,EAAG,QAAQ,OAAO;AAC5E,aAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC3C,YAAM,MAAM,KAAK,CAAC,EAAG,QAAQ,IAAI,KAAK,CAAC,EAAG,MAAM,KAAK,CAAC,EAAG,QAAQ,OAAO;AACxE,UAAI,MAAMA,YAAW;AACpB,QAAAA,aAAY;AACZ,QAAAD,QAAO,WAAW,CAAC;AAAA,MACpB;AAAA,IACD;AACA,WAAO,EAAE,MAAAA,OAAM,WAAAC,WAAU;AAAA,EAC1B;AACA,MAAI,OAAO,WAAW,CAAC;AACvB,MAAI,YAAY,OAAO,CAAC,GAAG,SAAS,OAAO;AAC3C,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC3C,UAAM,IAAI,OAAO,CAAC,GAAG,SAAS,OAAO;AACrC,QAAI,IAAI,WAAW;AAClB,kBAAY;AACZ,aAAO,WAAW,CAAC;AAAA,IACpB;AAAA,EACD;AACA,SAAO,EAAE,MAAM,UAAU;AAC1B;AAEA,SAAS,UAAU,QAAuC;AACzD,MAAI,OAAO,WAAW,EAAG,QAAO,OAAO;AACvC,MAAI,MAAM;AACV,aAAW,KAAK,OAAQ,QAAO,EAAE;AACjC,SAAO,MAAM,OAAO;AACrB;AAWO,SAAS,WACf,MACA,WACA,iBACA,MACqB;AACrB,SAAO,IAAI,gBAAmB,MAAM,WAAW,iBAAiB,IAAI;AACrE;AA0DO,SAAS,eAAkB,MAAmD;AACpF,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,OAAO,KAAK,QAAQ;AAC1B,SAAO;AAAA,IACN;AAAA,IACA,KAAK,MAAM;AAIV,aAAO,CAAC,IAAI;AAAA,IACb;AAAA,IACA,QAAQ,QAAQ,aAAa;AAC5B,YAAM,QAAQ,UAAU,MAAM;AAC9B,UAAI,QAA2B;AAC/B,iBAAW,KAAK,QAAQ;AACvB,YAAI,CAAC,SAAS,EAAE,QAAQ,MAAM,MAAO,SAAQ;AAAA,MAC9C;AACA,aAAO;AAAA,QACN,SAAS,kCAAkC,MAAM,QAAQ,CAAC,CAAC,OAAO,OAAO,MAAM;AAAA,QAC/E;AAAA,QACA,WAAW,QAAQ,CAAC,MAAM,MAAM,IAAI,CAAC;AAAA,MACtC;AAAA,IACD;AAAA,IACA,MAAM,SAAS,WAAW,YAAY;AACrC,UAAI,WAAW,WAAW,GAAG;AAK5B,cAAM,IAAI;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAIA,YAAM,QAAQ,WAAW,WAAW,SAAS,CAAC;AAC9C,UAAI,WAAW;AACf,YAAM,aAAa,CAAC,MAAc;AACjC,oBAAY;AAAA,MACb;AACA,YAAM,MAAgC,EAAE,OAAO,WAAW;AAC1D,UAAI;AACH,YAAI,KAAK,aAAa,OAAO;AAC5B,iBAAO,MAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,MAAM,KAAK,QAAQ,GAAG,CAAC,CAAC;AAAA,QAChF;AACA,cAAM,MAAW,CAAC;AAClB,iBAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC/B,cAAI,KAAK,MAAM,KAAK,QAAQ,GAAG,CAAC;AAAA,QACjC;AACA,eAAO;AAAA,MACR,UAAE;AACD,YAAI,KAAK,UAAU,QAAQ,WAAW,GAAG;AAMxC,8BAAoB,KAAK,QAAQ,OAAO,kBAAkB,QAAQ;AAAA,QACnE;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;AAqFA,SAAS,uBAA0B,GAA0C;AAC5E,SAAO,OAAO,MAAM,YAAY,MAAM,QAAS,EAAyB,SAAS;AAClF;AAEA,SAAS,sBAAsB,UAAiC,UAA4B;AAC3F,MAAI,SAAS,WAAW,GAAG;AAC1B,WAAO,wCAAwC,SAAS,MAAM,QAAQ,CAAC,CAAC;AAAA,EACzE;AACA,QAAM,QAAQ,SAAS,IAAI,CAAC,MAAM;AACjC,UAAM,MAAM,EAAE,SAAS,OAAO,aAAa,EAAE,KAAK,KAAK;AACvD,WAAO,KAAK,EAAE,MAAM,WAAW,EAAE,MAAM,QAAQ,CAAC,CAAC,IAAI,GAAG;AAAA,EACzD,CAAC;AACD,SAAO;AAAA,EAA8B,MAAM,KAAK,IAAI,CAAC;AACtD;AAwBO,SAAS,cAAiB,MAAkD;AAClF,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,oBAAoB,KAAK,qBAAqB;AACpD,QAAM,SAAS,KAAK,kBAAkB;AAEtC,SAAO;AAAA,IACN;AAAA,IACA,KAAK,MAAM;AAGV,aAAO,CAAC,IAAI;AAAA,IACb;AAAA,IACA,QAAQ,QAAQ,YAAY;AAC3B,YAAM,QAAQ,UAAU,MAAM;AAC9B,YAAM,gBACL,OAAO,KAAK,qBAAqB,aAC9B,KAAK,iBAAiB,MAAM,IAC5B,KAAK;AAKT,YAAM,wBAAwB,kBAAkB,UAAa,CAAC,OAAO,SAAS,KAAK;AACnF,YAAM,YAAY,iBAAiB;AACnC,YAAM,cAAc,wBACjB,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,IAC5C,OACC,OAAO,CAAC,MAAM,EAAE,QAAQ,SAAS,EACjC,MAAM,EACN,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AACpC,YAAM,WAAW,YAAY,MAAM,GAAG,iBAAiB;AAEvD,YAAM,EAAE,MAAM,UAAU,IAAI,SAAS,YAAY,MAAM;AACvD,YAAM,gBAA0B;AAAA,QAC/B,SAAS;AAAA,QACT;AAAA,QACA,WAAW,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,MACxC;AACA,YAAM,eAAe,OAAO,UAAU,aAAa;AAEnD,YAAM,OAAgC;AAAA,QACrC,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACD;AACA,YAAM,iBACL,YAAY,SAAS,SAAS,SAAS,SAAS,SAAS,MAAM,eAAe;AAC/E,aAAO;AAAA,QACN,SAAS,iCAAiC,MAAM,QAAQ,CAAC,CAAC,cAAc,YAAY,MAAM,GAAG,cAAc,IAAI,OAAO,MAAM,eAAe,UAAU,QAAQ,CAAC,CAAC;AAAA,QAC/J,UAAU;AAAA,QACV,WAAW,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM;AAAA,QACvC;AAAA,MACD;AAAA,IACD;AAAA,IACA,MAAM,SAAS,UAAU,YAAY;AAMpC,UAAI,WAAW,WAAW,GAAG;AAC5B,cAAM,IAAI;AAAA,UACT;AAAA,QACD;AAAA,MACD;AACA,YAAM,OAAO,uBAA0B,SAAS,QAAQ,IAAI,SAAS,WAAW;AAChF,YAAM,QACL,SAAS,SAAa,KAAK,OAAc,WAAW,WAAW,SAAS,CAAC;AAC1E,YAAM,WAAW,MAAM,gBAAgB,SAAS;AAChD,YAAM,WAAW,MAAM,YAAY,CAAC;AACpC,UAAI,WAAW;AACf,YAAM,aAAa,CAAC,MAAc;AACjC,oBAAY;AAAA,MACb;AACA,YAAM,MAA+B,EAAE,OAAO,UAAU,UAAU,WAAW;AAC7E,UAAI;AACH,YAAI,KAAK,aAAa,OAAO;AAC5B,iBAAO,MAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,MAAM,GAAG,MAAM,KAAK,QAAQ,GAAG,CAAC,CAAC;AAAA,QAChF;AACA,cAAM,MAAW,CAAC;AAClB,iBAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC/B,cAAI,KAAK,MAAM,KAAK,QAAQ,GAAG,CAAC;AAAA,QACjC;AACA,eAAO;AAAA,MACR,UAAE;AACD,YAAI,KAAK,UAAU,QAAQ,WAAW,GAAG;AAIxC,8BAAoB,KAAK,QAAQ,OAAO,kBAAkB,QAAQ;AAAA,QACnE;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;;;AD94CA,SAAS,gBAAmB,QAAmD;AAC9E,QAAM,EAAE,MAAM,OAAO,OAAO,IAAI;AAChC,QAAM,WAAW,OAAO,SAAS,KAAK,IAAI,MAAM,QAAQ,CAAC,IAAI,OAAO,KAAK;AACzE,QAAM,WAAY,QAAQ;AAC1B,MAAI,WAAW,aAAa;AAC3B,WAAO;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,iCAAiC,QAAQ;AAAA,MACjD;AAAA,IACD;AAAA,EACD;AACA,MAAI,WAAW,UAAU;AACxB,WAAO;AAAA,MACN,SAAS;AAAA,MACT,QAAQ,kCAAkC,QAAQ;AAAA,MAClD;AAAA,IACD;AAAA,EACD;AACA,SAAO;AAAA,IACN,SAAS;AAAA,IACT,QAAQ,8BAA8B,MAAM;AAAA,IAC5C;AAAA,EACD;AACD;AAoBO,SAAS,eAAkB,QAAqD;AACtF,QAAM,OAAO,OAAO,QAAQ;AAC5B,QAAM,WAAW,OAAO,YAAY;AAEpC,SAAO,CAAC,QAA2C;AAClD,UAAM,OAAO,IAAI,QAAQ;AACzB,UAAM,OAAO,WAAc,OAAO,SAAS,IAAI,GAAG,OAAO,WAAW,OAAO,UAAU;AAAA,MACpF,GAAG,OAAO;AAAA,MACV,SAAS,OAAO,WAAW,IAAI;AAAA,MAC/B,MAAM,GAAG,IAAI;AAAA,IACd,CAAC;AAMD,UAAM,UAAM;AAAA,MACX,CAAC,KAAK,QAAQ,KAAK,MAAM,KAAK,MAAM;AAAA,MACpC,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,IAAI,KAAK,CAAC;AAChB,YAAI,MAAM,eAAe,MAAM,YAAY,MAAM,WAAW;AAC3D,kBAAQ,KAAK,IAAI;AACjB;AAAA,QACD;AACA,cAAM,OAAO,SAAS;AAAA,UACrB,MAAM,KAAK,CAAC;AAAA,UACZ,OAAO,KAAK,CAAC;AAAA,UACb,QAAQ;AAAA,QACT,CAAC;AACD,gBAAQ,KAAK;AAAA,UACZ,GAAG,IAAI;AAAA,UACP,WAAW,EAAE,MAAM,GAAG,KAAK;AAAA,QAC5B,CAAC;AAAA,MACF;AAAA,MACA,EAAE,MAAM,GAAG,IAAI,WAAW,cAAc,UAAU;AAAA,IACnD;AACA,eAAO,sBAAO,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,MAAM,GAAG,IAAI,YAAY,CAAC;AAAA,EAGlE;AACD;;;ADhEA,SAASC,WAAU,QAAuC;AACzD,MAAI,OAAO,WAAW,EAAG,QAAO,OAAO;AACvC,MAAI,MAAM;AACV,aAAW,KAAK,OAAQ,QAAO,EAAE;AACjC,SAAO,MAAM,OAAO;AACrB;AAEA,SAASC,iBAAgB,SAA4C;AACpE,QAAM,EAAE,WAAW,OAAO,WAAW,MAAM,WAAW,gBAAgB,IAAI;AAC1E,QAAM,UAAU,OAAO,SAAS,IAAI,IAAI,KAAK,QAAQ,CAAC,IAAI,OAAO,IAAI;AACrE,QAAM,WAAW,CAAC,mBAAmB,QAAQ,KAAK,QAAQ;AAC1D,QAAM,WAAW,kBACd,CAAC,kEAAkE,IACnE,WACC,CAAC,GAAG,SAAS,IAAI,KAAK,kCAAkC,OAAO,WAAM,SAAS,EAAE,IAChF,UAAU,IACT,CAAC,gEAA2D,IAC5D;AAAA,IACA,GAAG,SAAS,IAAI,KAAK,kCAAkC,OAAO,gBAAgB,SAAS;AAAA,EACxF;AACJ,SAAO,WACJ,EAAE,UAAU,MAAM,SAAS,IAC3B,EAAE,UAAU,OAAO,UAAU,YAAY,aAAa;AAC1D;AAEA,SAAS,uBAA0B,MAA8C;AAChF,SAAO,KAAK,YAAY;AACzB;AAoBO,SAAS,aAAgB,QAAmD;AAClF,QAAM,OAAO,OAAO,QAAQ;AAC5B,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,WAAW,OAAO,YAAYA;AACpC,QAAM,UAAU,OAAO,mBAAmB;AAC1C,QAAM,cAAc,OAAO;AAS3B,QAAM,oBAAoB,oBAAI,IAAoB;AAElD,SAAO,CAAC,QAA2C;AAClD,UAAM,EAAE,MAAM,UAAU,IAAI,IAAI;AAIhC,QAAI,aAAa,MAAM;AACtB,aAAO;AAAA,QACN,GAAG,IAAI;AAAA,QACP,QAAQ;AAAA,UACP,UAAU;AAAA,UACV,UAAU,CAAC,yDAAyD;AAAA,UACpE,YAAY;AAAA,QACb;AAAA,MACD;AAAA,IACD;AACA,UAAM,WAAW,QAAQ,WAAW,IAAI;AACxC,QAAI,YAAY,MAAM;AACrB,aAAO;AAAA,QACN,GAAG,IAAI;AAAA,QACP,QAAQ,SAAS;AAAA,UAChB,QAAQ,CAAC;AAAA,UACT,WAAW,OAAO;AAAA,UAClB,WAAW;AAAA,UACX,OAAO;AAAA,UACP;AAAA,UACA,iBAAiB;AAAA,QAClB,CAAC;AAAA,MACF;AAAA,IACD;AA2CA,UAAM,UAAU,IAAI;AAIpB,UAAM,MAAM,kBAAkB,IAAI,OAAO,KAAK;AAC9C,sBAAkB,IAAI,SAAS,MAAM,CAAC;AACtC,UAAM,gBAAgB,QAAQ,IAAI,KAAK,IAAI,GAAG;AAC9C,UAAM,cAAc,QAAQ,OAAO,GAAG,aAAa;AACnD,UAAM,MAAM,eAAe,OAAO,IAAI,oBAAM,QAAQ,OAAO,GAAG,aAAa,EAAE,IAAI;AACjF,UAAM,iBAAiB,OAAO,OAAO,eAAe,GAAG,IAAI;AAC3D,UAAM,cAAc,OAAO,OAAO,YAAY,GAAG,IAAI;AACrD,UAAM,aAAa,OAAO,OAAO,WAAW,GAAG,IAAI;AACnD,UAAM,WAAW,OAAO,OAAO,aAAa,GAAG,IAAI;AAEnD,UAAM,iBAAa,mBAAmB,CAAC,GAAG;AAAA,MACzC,SAAS,CAAC,QAAa;AAAA,MACvB,MAAM;AAAA,IACP,CAAC;AACD,UAAM,cAAU,mBAA6B,CAAC,GAAG;AAAA,MAChD,SAAS,OAAO,WAAW,IAAI;AAAA,MAC/B,MAAM;AAAA,IACP,CAAC;AACD,QAAI,OAAO,MAAM;AAChB,UAAI,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1C,UAAI,IAAI,SAAS,EAAE,MAAM,UAAU,CAAC;AAAA,IACrC;AACA,QAAI;AACJ,4BAAM,MAAM;AACX,mBAAa,OAAO,UAAU,YAAY,OAAO;AAAA,IAClD,CAAC;AASD,UAAM,UACL,eAAe,OACZ,OAAO;AAAA,MACP,gBAAgB,MAAM;AAKrB,YAAI;AACH,sBAAY,OAAO,WAAW;AAAA,QAC/B,QAAQ;AAAA,QAER;AAAA,MACD;AAAA,IACD,KACC,MAAM;AACV,UAAM,UAAM;AAAA,MACX,CAAC,UAA2B;AAAA,MAC5B,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,OAAO,MAAM;AAChB,kBAAQ,KAAK,IAAI;AACjB,iBAAO,QAAQ;AAAA,QAChB;AACA,cAAM,OAAOF,WAAU,GAAG;AAC1B,cAAM,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE;AAC1D,gBAAQ,KAAK;AAAA,UACZ,GAAG,IAAI;AAAA,UACP,QAAQ,SAAS;AAAA,YAChB,QAAQ;AAAA,YACR,WAAW;AAAA,YACX;AAAA,YACA,OAAO,IAAI;AAAA,YACX;AAAA,UACD,CAAC;AAAA,QACF,CAAC;AACD,eAAO,QAAQ;AAAA,MAChB;AAAA,MACA,EAAE,MAAM,YAAY,cAAc,UAAU;AAAA,IAC7C;AACA,UAAM,cAAU,sBAAO,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAGhE,QAAI,OAAO,MAAM;AAChB,UAAI,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAM/B,UAAI,IAAI,SAA0B,EAAE,MAAM,WAAW,CAAC;AACtD,MAAC,YAAsB,MAAM,aAAa,GAAG;AAAA,IAC9C;AACA,WAAO;AAAA,EACR;AACD;AAqCO,SAAS,gBAAmB,QAGjC;AACD,QAAM,WAAW,OAAO,QAAQ;AAChC,QAAM,WAAW,eAAkB;AAAA,IAClC,MAAM,GAAG,QAAQ;AAAA,IACjB,UAAU,OAAO;AAAA,IACjB,WAAW,OAAO;AAAA,IAClB,UAAU,OAAO;AAAA,IACjB,YAAY,OAAO;AAAA,IACnB,QAAQ,OAAO;AAAA,EAChB,CAAC;AACD,QAAM,WAAW,aAAgB;AAAA,IAChC,MAAM,GAAG,QAAQ;AAAA,IACjB,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO;AAAA,IACnB,WAAW,OAAO;AAAA,EACnB,CAAC;AACD,SAAO,EAAE,UAAU,SAAS;AAC7B;;;AMvWA,IAAAG,gBAA8D;AAC9D,IAAAC,iBAAsC;AACtC,IAAAC,iBAAsB;;;ACVtB,IAAAC,gBAQO;AA6FA,SAAS,WACf,QACA,WACA,MACa;AAeb,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,UAAU;AACd,MAAI,cAAc;AAClB,MAAI;AACJ,MAAI,qBAAqB,MAAM,gBAAgB;AAQ/C,QAAM,aAAa,CAAC,MAAe;AAClC,QAAI,QAAS;AACb,cAAU;AACV,QAAI,aAAa,KAAM,WAAU,CAAC;AAAA,QAC7B,WAAU,EAAE,MAAM,QAAQ,OAAO,EAAE;AAAA,EACzC;AACA,QAAM,cAAc,CAAC,QAAuB;AAC3C,QAAI,QAAS;AACb,cAAU;AACV,QAAI,YAAY,KAAM,UAAS,GAAG;AAAA,QAC7B,WAAU,EAAE,MAAM,SAAS,IAAI;AAAA,EACrC;AACA,QAAM,iBAAiB,MAAY;AAClC,QAAI,QAAS;AACb,cAAU;AACV,UAAM,MAAM,IAAI,MAAM,kCAAkC;AACxD,QAAI,YAAY,KAAM,UAAS,GAAG;AAAA,QAC7B,WAAU,EAAE,MAAM,WAAW;AAAA,EACnC;AACA,QAAM,SAAS,MAAY;AAC1B,QAAI,OAAO;AACV,YAAM;AACN,cAAQ;AAAA,IACT,MAAO,eAAc;AAAA,EACtB;AAEA,QAAM,OAAiC,CAAC,SAAS;AAChD,QAAI,QAAS;AACb,eAAW,KAAK,MAAM;AACrB,UAAI,QAAS;AAOb,UAAI,sBAAsB,EAAE,CAAC,MAAM,mBAAM;AACzC,UAAI,EAAE,CAAC,MAAM,oBAAM;AAClB,cAAM,IAAI,EAAE,CAAC;AACb,YAAI,UAAU,CAAC,GAAG;AACjB,qBAAW,CAAC;AACZ,iBAAO;AACP;AAAA,QACD;AAAA,MACD;AACA,UAAI,EAAE,CAAC,MAAM,qBAAO;AACnB,oBAAY,EAAE,CAAC,CAAC;AAChB,eAAO;AACP;AAAA,MACD;AACA,UAAI,EAAE,CAAC,MAAM,wBAAU;AACtB,uBAAe;AACf,eAAO;AACP;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACA,UAAQ,OAAO,UAAU,IAAI;AAC7B,uBAAqB;AAKrB,MAAI,MAAM,QAAQ,QAAQ,CAAC,SAAS;AACnC,QAAI;AACH,WAAK,KAAK;AAAA,IACX,SAAS,KAAK;AACb,kBAAY,GAAG;AACf,aAAO;AAAA,IACR;AAAA,EACD;AACA,MAAI,aAAa;AAChB,YAAQ;AACR,YAAQ;AAAA,EACT;AAEA,SAAO,IAAI,QAAW,CAAC,SAAS,WAAW;AAG1C,QAAI,WAAW,MAAM;AACpB,UAAI,QAAQ,SAAS,OAAQ,SAAQ,QAAQ,KAAK;AAAA,eACzC,QAAQ,SAAS,QAAS,QAAO,QAAQ,GAAG;AAAA,UAChD,QAAO,IAAI,MAAM,kCAAkC,CAAC;AACzD;AAAA,IACD;AACA,gBAAY;AACZ,eAAW;AAAA,EACZ,CAAC;AACF;AA8CA,IAAI;AACJ,IAAI;AAEJ,eAAsB,aACrB,QACA,MAyB0B;AAC1B,QAAM,YAAY,MAAM,cAAc,CAAC,MAAS,KAAK;AACrD,QAAM,cAAc,MAAM;AAC1B,QAAM,OAAO,MAAM;AACnB,MAAI,MAAM,aAAa,QAAQ,KAAK,aAAa,GAAG;AACnD,WAAQ,MAAM,WAAW,QAAQ,WAAW,EAAE,aAAa,KAAK,CAAC;AAAA,EAClE;AAKA,MAAI,eAAe,QAAW;AAC7B,UAAM,CAAC,YAAY,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC/C;AAAA,MACA;AAAA,IACD,CAAC;AACD,iBAAa,WAAW;AACxB,eAAW,QAAQ;AAAA,EACpB;AACA,QAAM,UAAU,WAAW,QAAQ,EAAE,IAAI,KAAK,YAAa,SAAoB,CAAC,EAAE;AAClF,SAAQ,MAAM,WAAW,SAAS,WAAW,EAAE,aAAa,KAAK,CAAC;AACnE;AA4CO,SAAS,WACf,QACA,MAC+C;AAC/C,QAAM,OAAO,IAAI,gBAAgB;AACjC,QAAM,SAAS,MAAM,UAAU,IAAI,MAAM,0BAA0B;AACnE,MAAI;AACJ,MAAI,cAAc;AAClB,QAAM,OAAO,MAAM;AAClB,QAAI,OAAO;AACV,YAAM;AACN,cAAQ;AAAA,IACT,MAAO,eAAc;AAAA,EACtB;AACA,UAAQ,OAAO,UAAU,CAAC,SAAS;AAClC,QAAI,KAAK,OAAO,QAAS;AACzB,eAAW,KAAK,MAAM;AACrB,UAAI,EAAE,CAAC,MAAM,sBAAQ,EAAE,CAAC,MAAM,MAAM;AACnC,aAAK,MAAM,MAAM;AACjB,aAAK;AACL;AAAA,MACD;AACA,UAAI,EAAE,CAAC,MAAM,qBAAO;AAInB,aAAK,MAAM,EAAE,CAAC,CAAC;AACf,aAAK;AACL;AAAA,MACD;AACA,UAAI,EAAE,CAAC,MAAM,wBAAU;AAItB,aAAK;AACL;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AACD,MAAI,aAAa;AAChB,YAAQ;AACR,YAAQ;AAAA,EACT;AACA,SAAO;AAAA,IACN,QAAQ,KAAK;AAAA,IACb,SAAS,MAAM;AACd,UAAI,OAAO;AACV,cAAM;AACN,gBAAQ;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACD;;;ACxaA,IAAAC,gBAWO;AACP;AACA;AAgFA,SAAS,mBAAmB,MAA0C;AACrE,QAAM,QAAQ,MAAM;AACpB,QAAM,aAAa,MAAM;AAIzB,MAAI,eAAe,UAAa,UAAU,QAAW;AACpD,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAEA,QAAM,aAAa,UAAU,SAAY,QAAQ;AACjD,MAAI,aAAa,EAAG,OAAM,IAAI,WAAW,0BAA0B;AAEnE,QAAM,WACL,eAAe,SACZ,OACA,OAAO,eAAe,WACrB,qBAAqB,UAAU,IAC/B;AAEL,SAAO,EAAE,YAAY,SAAS;AAC/B;AAEA,SAAS,iBAAiB,MAA0D;AACnF,QAAM,OAAgC,CAAC;AACvC,MAAI,MAAM,UAAU,OAAW,MAAK,QAAQ,KAAK;AACjD,MAAI,OAAO,MAAM,YAAY,SAAU,MAAK,UAAU,KAAK;AAC3D,SAAO,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO;AAC9C;AAeA,SAAS,sBACR,QACA,eACA,GACA,WACa;AACb,MAAI,UAAU;AACd,MAAI,UAAU;AACd,MAAI,YAA2B;AAC/B,MAAI;AACJ,QAAM,QAAQ,IAAI,8BAAgB;AAClC,QAAM,UAAU,CAAC,WAA8B;AAC9C,gBAAY,EAAE,QAAQ,SAAS,cAAc,UAAU,CAAC;AAAA,EACzD;AACA,UAAQ,SAAS;AAEjB,WAAS,qBAA2B;AACnC,YAAQ;AACR,YAAQ;AAAA,EACT;AAEA,WAAS,sBAAsB,KAAoB;AAClD,QAAI,QAAS;AACb,UAAM,MAAM,OAAO;AACnB,QAAI,WAAW,IAAI,YAAY;AAC9B,yBAAmB;AACnB,cAAQ,SAAS;AACjB,QAAE,KAAK,CAAC,CAAC,qBAAO,GAAG,CAAC,CAAC;AACrB;AAAA,IACD;AACA,UAAM,MAAM,IAAI,aAAa,OAAO,IAAI,IAAI,SAAS,SAAS,KAAK,SAAS;AAE5E,QAAI,QAAQ,QAAQ,QAAQ,QAAW;AACtC,yBAAmB;AACnB,cAAQ,SAAS;AACjB,QAAE,KAAK,CAAC,CAAC,qBAAO,GAAG,CAAC,CAAC;AACrB;AAAA,IACD;AAKA,QAAI;AACJ,QAAI;AACH,gBAAU,cAAc,GAAG;AAAA,IAC5B,QAAQ;AACP,yBAAmB;AACnB,cAAQ,SAAS;AACjB,QAAE,KAAK,CAAC,CAAC,qBAAO,GAAG,CAAC,CAAC;AACrB;AAAA,IACD;AACA,gBAAY;AACZ,eAAW;AACX,uBAAmB;AACnB,YAAQ,QAAQ;AAIhB,UAAM,UAAU,UAAU,IAAI,UAAU,YAAY;AAGpD,UAAM,MAAM,SAAS,MAAM;AAC1B,UAAI,QAAS;AACb,cAAQ;AAAA,IACT,CAAC;AAAA,EACF;AAEA,WAAS,UAAgB;AACxB,UAAM,OAAO;AACb,uBAAmB;AACnB,QAAI;AACJ,QAAI;AACH,YAAM,cAAc;AAAA,IACrB,SAAS,KAAK;AACb,4BAAsB,GAAG;AACzB;AAAA,IACD;AACA,YAAQ,SAAS;AACjB,YAAQ,IAAI,UAAU,CAAC,SAAS;AAC/B,UAAI,QAAS;AACb,iBAAW,KAAK,MAAM;AACrB,cAAM,IAAI,EAAE,CAAC;AACb,YAAI,MAAM,oBAAO,GAAE,KAAK,CAAC,CAAC,mBAAK,CAAC,CAAC;AAAA,iBACxB,MAAM,oBAAM;AACpB,oBAAU;AACV,sBAAY;AACZ,YAAE,KAAK,EAAE,CAAC,CAAM;AAChB,kBAAQ,SAAS;AAAA,QAClB,WAAW,MAAM,uBAAU,GAAE,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AAAA,iBACrC,MAAM,wBAAU;AAOxB,oBAAU;AACV,6BAAmB;AACnB,kBAAQ,WAAW;AACnB,YAAE,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AAAA,QACpB,WAAW,MAAM,qBAAO;AACvB,gCAAsB,OAAO,CAAC,CAAC;AAC/B;AAAA,QACD,MAAO,GAAE,KAAK,CAAC,CAAC,CAAC;AAAA,MAClB;AAAA,IACD,CAAC;AAAA,EACF;AAEA,UAAQ;AAER,SAAO,MAAM;AACZ,UAAM,aAAa;AACnB,cAAU;AACV,UAAM,OAAO;AACb,uBAAmB;AACnB,QAAI,CAAC,WAAY,SAAQ,WAAW;AAAA,EACrC;AACD;AAoDO,SAAS,MACf,OACA,MACiB;AACjB,QAAM,iBAAa,oBAAiB,CAAC,GAAG;AAAA,IACvC,MAAM;AAAA,IACN,cAAc;AAAA,IACd,SAAS,EAAE,QAAQ,WAAW,SAAS,GAAG,cAAc,KAAK;AAAA,IAC7D,QAAQ,CAAC,GAAG,MACX,MAAM,KACL,KAAK,QACL,KAAK,QACL,OAAO,MAAM,YACb,OAAO,MAAM,YACb,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC;AAAA,EACzC,CAAC;AACD,QAAM,OAAO,CAAC,MAAwB;AACrC,eAAW,KAAK,CAAC,CAAC,mBAAK,GAAG,CAAC,oBAAM,CAAC,CAAC,CAAC;AAAA,EACrC;AACA,MAAI,OAAO,UAAU,YAAY;AAChC,WAAO;AAAA,MACN,MAAM,cAAc,OAAO,MAAyD,IAAI;AAAA,MACxF;AAAA,IACD;AAAA,EACD;AACA,SAAO;AAAA,IACN,MAAM,aAAa,OAAO,MAA+C,IAAI;AAAA,IAC7E;AAAA,EACD;AACD;AAMA,SAAS,qBACR,KACsD;AACtD,MAAI,QAAQ,QAAW;AACtB,WAAO,EAAE,SAAS,MAAM,QAAW,OAAO,MAAM,OAAU;AAAA,EAC3D;AACA,MAAI,CAACC,QAAO,GAAG,GAAG;AACjB,WAAO,EAAE,SAAS,MAAM,KAAU,OAAO,MAAM,OAAU;AAAA,EAC1D;AACA,QAAM,WAAW;AACjB,MAAI,SAAyB,SAAS,SAA2B;AACjE,QAAM,QAAQ,SAAS,UAAU,CAAC,SAAS;AAC1C,eAAW,KAAK,MAAM;AACrB,UAAI,EAAE,CAAC,MAAM,mBAAM;AACnB,YAAM,OAAO,EAAE,CAAC;AAChB,UAAI,QAAQ,QAAQ,OAAO,SAAS,SAAU;AAC9C,UAAI,OAAO,KAAK,IAAI,EAAE,WAAW,EAAG;AACpC,eAAS,EAAE,GAAI,UAAW,CAAC,GAAU,GAAG,KAAK;AAAA,IAC9C;AAAA,EACD,CAAC;AACD,SAAO,EAAE,SAAS,MAAM,QAAQ,MAAM;AACvC;AAIA,IAAM,sCAAsC,oBAAI,QAAuB;AAEvE,SAAS,aACR,QACA,MACA,WACU;AAMV,QAAM,iBAAiB;AACvB,MACC,eAAe,oBAAoB,SACnC,CAAC,oCAAoC,IAAI,MAAM,GAC9C;AACD,wCAAoC,IAAI,MAAM;AAC9C,YAAQ;AAAA,MACP;AAAA,IAID;AAAA,EACD;AACA,QAAM,aAAaA,QAAO,IAAI,IAAI,SAAa;AAI/C,MAAI,CAACA,QAAO,IAAI,EAAG,oBAAmB,UAAU;AAChD,aAAO;AAAA,IACN,CAAC,OAAO,MAAM;AACb,YAAM,SAAS,qBAAmC,IAAI;AACtD,YAAM,SAAS,MAA2B,mBAAmB,OAAO,QAAQ,CAAC;AAC7E,YAAM,QAAQ,sBAAsB,QAAQ,MAAM,QAAQ,GAAG,SAAS;AACtE,aAAO;AAAA,QACN,gBAAgB,MAAM;AACrB,gBAAM;AACN,iBAAO,MAAM;AAAA,QACd;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,GAAG,aAAa;AAAA,MAChB,SAAS,OAAO;AAAA,MAChB,MAAM;AAAA,QACL,GAAI,YAAY,QAAQ,CAAC;AAAA,QACzB,OAAG;AAAA,UACF;AAAA,UACAA,QAAO,IAAI,IAAI,EAAE,cAAc,KAAK,IAAI,iBAAiB,UAAU;AAAA,QACpE;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;AAEA,SAAS,cACR,SACA,MACA,WACU;AACV,QAAM,aAAaA,QAAO,IAAI,IAAI,SAAa;AAE/C,MAAI,CAACA,QAAO,IAAI,EAAG,oBAAmB,UAAU;AAChD,aAAO;AAAA,IACN,CAAC,OAAO,MAAM;AACb,YAAM,SAAS,qBAA6C,IAAI;AAChE,YAAM,SAAS,MAA2B,mBAAmB,OAAO,QAAQ,CAAC;AAC7E,YAAM,QAAQ,sBAAsB,QAAQ,SAAS,GAAG,SAAS;AACjE,aAAO;AAAA,QACN,gBAAgB,MAAM;AACrB,gBAAM;AACN,iBAAO,MAAM;AAAA,QACd;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,GAAG,aAAa;AAAA,MAChB,SAAS,YAAY;AAAA,MACrB,MAAM;AAAA,QACL,GAAI,YAAY,QAAQ,CAAC;AAAA,QACzB,OAAG;AAAA,UACF;AAAA,UACAA,QAAO,IAAI,IAAI,EAAE,cAAc,KAAK,IAAI,iBAAiB,UAAU;AAAA,QACpE;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;;;ACtaA,IAAAC,gBAAuD;AACvD,IAAAC,gBAAmD;AAiEnD,SAAS,eAAe,MAAuB;AAC9C,MAAI,QAAQ,QAAQ,OAAO,SAAS,YAAY,aAAa,MAAM;AAClE,WAAO,OAAQ,KAAqB,OAAO;AAAA,EAC5C;AACA,MAAI,OAAO,SAAS,SAAU,QAAO;AACrC,SAAO,OAAO,IAAI;AACnB;AAEA,SAAS,eAAe,MAAc,MAAM,KAAa;AACxD,MAAI,KAAK,UAAU,IAAK,QAAO;AAC/B,SAAO,GAAG,KAAK,MAAM,GAAG,GAAG,CAAC;AAC7B;AAwDO,SAAS,WACf,SACA,MACA,QACA,MACiB;AACjB,QAAM,SAAS,MAAM,UAAU;AAC/B,QAAM,WAAW,MAAM,QAAQ;AAO/B,MAAI,MAAM,UAAU,UAAa,WAAW,OAAO;AAClD,YAAQ;AAAA,MACP;AAAA,IAGD;AAAA,EACD;AAuBA,QAAM,iBAAiB,KAAK;AAC5B,QAAM,UACL,MAAM,UAAU,SAAY,CAAC,GAAG,MAAM,KAAK,KAAsB,IAAI;AACtE,QAAM,mBAAe;AAAA,IACpB;AAAA,IACA,CAAC,WAAW,SAAS,QAAQ;AAC5B,YAAM,OAAO,UAAU;AAAA,QAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,MAClE;AACA,YAAM,aAAa,KAAK,MAAM,GAAG,cAAc;AAC/C,YAAM,aACL,MAAM,UAAU,SACZ,KAAK,cAAc,IACpB;AAKJ,UAAI,WAAW,KAAK,CAAC,MAAM,KAAK,IAAI,GAAG;AACtC,gBAAQ,KAAK,EAAE,UAAU,CAAC,GAAG,OAAO,WAAW,CAAC;AAChD;AAAA,MACD;AACA,YAAM,OAAO,OAAO,WAAW,WAAW,SAAS,OAAO,GAAG,UAAU;AACvE,UAAI,CAAC,MAAM;AACV,gBAAQ,KAAK,EAAE,UAAU,CAAC,GAAG,OAAO,WAAW,CAAC;AAChD;AAAA,MACD;AAEA,cAAQ,KAAK;AAAA,QACZ,UAAU,CAAC,EAAE,MAAM,QAAiB,SAAS,KAAK,CAAC;AAAA,QACnD,OAAO;AAAA,MACR,CAAC;AAAA,IACF;AAAA,IACA;AAAA,MACC,MAAM,GAAG,QAAQ;AAAA,MACjB,MAAM,OAAO,uBAAuB;AAAA,IACrC;AAAA,EACD;AAEA,QAAM,aAAS;AAAA,IACd;AAAA,IACA,CAAC,aAAa;AACb,YAAM,EAAE,UAAU,MAAM,MAAM,IAAI;AAClC,UAAI,CAAC,QAAQ,KAAK,WAAW,GAAG;AAC/B,mBAAO,oBAAe,CAAC,GAAG,EAAE,SAAS,KAAK,CAAC;AAAA,MAC5C;AAMA,iBAAO;AAAA,QACN,CAAC,OAAO,YAAY;AACnB,cAAI,OAAO;AACX,cAAI,YAAY;AAChB,cAAI;AAEJ,gBAAM,aAA+B;AAAA,YACpC,OAAO,MAAM;AAAA,YACb,aAAa,MAAM;AAAA,YACnB,WAAW,MAAM;AAAA,YACjB,cAAc,MAAM;AAAA,YACpB,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,UACxC;AACA,cAAI,MAAM,OAAO;AAChB,kBAAM,MAAM,WAAW,KAAK,KAAK;AACjC,uBAAW,SAAS,IAAI;AACxB,2BAAe,IAAI;AAAA,UACpB;AAEA,cAAI;AACJ,cAAI;AACH,2BAAe,QAAQ,OAAO,MAAM,UAAU;AAAA,UAC/C,SAAS,KAAK;AACb,mBAAO;AACP,oBAAQ,KAAK,CAAC,CAAC,qBAAO,GAAG,CAAC,CAAC;AAC3B,mBAAO;AAAA,cACN,gBAAgB,MAAM;AACrB,+BAAe;AAAA,cAChB;AAAA,YACD;AAAA,UACD;AAEA,gBAAM,eAAW,uBAAQ,YAAY;AAErC,gBAAM,MAAM,SAAS,UAAU,CAACA,YAAU;AACzC,gBAAI,aAAa,KAAM;AACvB,uBAAW,OAAOA,SAAO;AAKxB,kBAAI,aAAa,KAAM;AACvB,kBAAI,IAAI,CAAC,MAAM,oBAAM;AACpB,sBAAM,OAAO,IAAI,CAAC;AAIlB,oBAAI,WAAW,OAAO;AACrB,0BAAQ,KAAK,IAAoB;AAAA,gBAClC,OAAO;AAKN,sBAAI;AACJ,sBAAI;AACH,8BAAU,eAAe,IAAI;AAAA,kBAC9B,SAAS,KAAK;AAGb,0BAAM,UAAU,IAAI;AAAA,sBACnB,4DACE,IAAc,OAChB;AAAA,oBACD;AAIA,mCAAe;AACf,mCAAe;AACf,2BAAO;AACP,4BAAQ,KAAK,CAAC,CAAC,qBAAO,OAAO,CAAC,CAAC;AAC/B;AAAA,kBACD;AACA,sBAAI;AACH,0BAAM,SACL,WAAW,SACP,KAAK,MAAM,YAAY,OAAO,CAAC,IAC/B;AACL,4BAAQ,KAAK,MAAM;AAAA,kBACpB,SAAS,KAAK;AACb,0BAAM,UAAU,IAAI;AAAA,sBACnB,qDACE,IAAc,OAChB;AAAA,mCAAsC,eAAe,OAAO,CAAC;AAAA,oBAC9D;AAGA,mCAAe;AACf,mCAAe;AACf,2BAAO;AACP,4BAAQ,KAAK,CAAC,CAAC,qBAAO,OAAO,CAAC,CAAC;AAC/B;AAAA,kBACD;AAAA,gBACD;AAAA,cACD,WAAW,IAAI,CAAC,MAAM,qBAAO;AAE5B,+BAAe;AACf,+BAAe;AACf,uBAAO;AACP,wBAAQ,KAAK,CAAC,CAAC,qBAAO,IAAI,CAAC,CAAC,CAAC,CAAC;AAC9B;AAAA,cACD,WAAW,IAAI,CAAC,MAAM,wBAAU;AAI/B,+BAAe;AACf,+BAAe;AACf,uBAAO;AACP,wBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACzB;AAAA,cACD,OAAO;AAMN,wBAAQ,KAAK,CAAC,GAAY,CAAC;AAAA,cAC5B;AAAA,YACD;AAAA,UACD,CAAC;AAED,iBAAO;AAAA,YACN,gBAAgB,MAAM;AACrB,0BAAY;AACZ,kBAAI;AAIJ,6BAAe;AACf,6BAAe;AAAA,YAChB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,cAAc;AAAA,UACd,MAAM,GAAG,QAAQ;AAAA,UACjB,MAAM,OAAO,uBAAuB;AAAA,QACrC;AAAA,MACD;AAAA,IACD;AAAA,IACA;AAAA,MACC,MAAM,GAAG,QAAQ;AAAA,MACjB,MAAM,MAAM,OACT,EAAE,GAAG,OAAO,qBAAqB,GAAG,GAAG,KAAK,KAAK,IACjD,OAAO,qBAAqB;AAAA,IAChC;AAAA,EACD;AAEA,SAAO;AACR;;;ACpZA,IAAAC,gBAYO;AAEP,IAAAC,gBAAyC;AAMzC,SAAS,KAAK,MAAc,OAA0D;AACrF,SAAO,WAAW,iBAAiB,MAAM,KAAK;AAC/C;AAqGO,IAAM,gBAAN,cAA4B,oBAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUxC,KACC,MACA,KACA,OAA0E,CAAC,GACjE;AACV,UAAM,QAAQ,KAAK,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC;AAC9D,UAAM,WAAO;AAAA,MACZ;AAAA,MACA,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,SAAS,IAAI,MAAM,GAAG;AAC5B,YAAI,WAAW,UAAa,WAAW,KAAM,SAAQ,KAAK,MAAM;AAAA,MACjE;AAAA,MACA;AAAA,QACC;AAAA,QACA,cAAc;AAAA,QACd,MAAM,KAAK,QAAQ,KAAK,IAAI;AAAA,MAC7B;AAAA,IACD;AACA,SAAK,IAAI,MAAM,EAAE,KAAK,CAAC;AACvB,WAAO;AAAA,EACR;AAAA;AAAA,EAIA,SACC,MACA,QACA,QACA,OAA2C,CAAC,GACZ;AAChC,UAAM,MAAM,KAAK,aAAa,MAAM;AACpC,UAAM,WAAO;AAAA,MACZ,CAAC,GAAG;AAAA,MACJ,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACA,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,QAAQ,KAAK,CAAC;AACpB,YAAI;AACH,kBAAQ,KAAK,EAAE,KAAK,OAAO,KAAU,GAAG,MAAkB,CAAC;AAAA,QAC5D,SAAS,OAAO;AACf,kBAAQ,KAAK,EAAE,KAAK,SAAkB,OAAmB,MAAM,CAAC;AAAA,QACjE;AAAA,MACD;AAAA,MACA;AAAA,QACC;AAAA,QACA,cAAc;AAAA,QACd,MAAM,KAAK,YAAY,KAAK,IAAI;AAAA,MACjC;AAAA,IACD;AACA,SAAK,IAAI,MAAM,EAAE,KAAK,CAAC;AACvB,WAAO;AAAA,EACR;AAAA;AAAA,EAIA,QACC,MACA,MACA,OAA2C,CAAC,GACR;AACpC,UAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,UAAM,QAAQ,KAAK,IAAI,CAAC,MAAM,KAAK,aAAa,KAAK,CAAC,CAAY,CAAC;AACnE,UAAM,WAAO;AAAA,MACZ;AAAA,MACA,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,SAAS,UAAU;AAAA,UAAI,CAACA,SAAO,MACpCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,MAAM,CAAC;AACb,iBAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACrC,UAAC,IAAgC,KAAK,CAAC,CAAW,IAAI,OAAO,CAAC;AAAA,QAC/D;AACA,gBAAQ,KAAK,GAAG;AAAA,MACjB;AAAA,MACA;AAAA,QACC;AAAA,QACA,cAAc;AAAA,QACd,MAAM,KAAK,WAAW,KAAK,IAAI;AAAA,MAChC;AAAA,IACD;AACA,SAAK,IAAI,MAAM,EAAE,KAAK,CAAC;AACvB,WAAO;AAAA,EACR;AAAA;AAAA,EAIA,aAAgB,MAAc,QAAiB,OAAuB,CAAC,GAAsB;AAC5F,UAAM,aAAa,KAAK,cAAc;AACtC,QAAI,aAAa,KAAK,eAAe,OAAO,mBAAmB;AAC9D,YAAM,IAAI,WAAW,uCAAuC;AAAA,IAC7D;AACA,UAAM,YAAY,KAAK,aAAa;AAOpC,QAAI;AACJ,QAAI,OAAO,WAAW,UAAU;AAC/B,YAAM,KAAK,aAAa,MAAM;AAAA,IAC/B,WAAW,KAAK,OAAO,MAAM,MAAM,QAAW;AAC7C,YAAM;AAAA,IACP,OAAO;AACN,YAAM,YAAQ;AAAA,QACb,CAAC,MAAM;AAAA,QACP,CAAC,WAAW,YAAY;AACvB,gBAAM,SAAS,UAAU,CAAC;AAC1B,cAAI,UAAU,QAAQ,OAAO,WAAW,EAAG;AAC3C,qBAAW,KAAK,OAAQ,SAAQ,KAAK,CAAC;AAAA,QACvC;AAAA,QACA;AAAA,UACC,cAAc;AAAA,UACd,UAAM,0BAAW,OAAO;AAAA,QACzB;AAAA,MACD;AACA,WAAK,IAAI,OAAO,EAAE,MAAM,GAAG,IAAI,UAAU,CAAC;AAC1C,YAAM;AAAA,IACP;AAGA,UAAM,WAAW,IAAI,oBAAM,GAAG,IAAI,QAAQ;AAC1C,UAAM,cAAc,SAAS,MAAoB,WAAW,CAAC,GAAG;AAAA,MAC/D,QAAQ,MAAM;AAAA,IACf,CAAC;AACD,UAAM,aAAa,SAAS,MAAe,UAAU,SAAS;AAC9D,UAAM,YAAY,SAAS,QAAgB,SAAS,CAAC,SAAS,GAAG,CAAC,WAAW,QAAQ;AACpF,YAAM,OAAO,UAAU;AAAA,QAAI,CAACA,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,MAClE;AACA,aAAO,CAAE,KAAK,CAAC,EAAmB,MAAM;AAAA,IACzC,CAAC;AACD,UAAM,mBAAmB,SAAS,MAAc,gBAAgB,CAAC;AACjE,UAAM,YAAY,eAA4B;AAAA,MAC7C,MAAM;AAAA,MACN,eAAe;AAAA,MACf,OAAO;AAAA,IACR,CAAC;AACD,SAAK,MAAM,GAAG,IAAI,UAAU,QAAQ;AAEpC,QAAI,QAAa,CAAC;AAClB,QAAI,OAAO;AACX,QAAI,UAAU;AASd,QAAI,eAAe;AACnB,UAAM,cAAc,WAAW,UAAU,CAAC,SAAS;AAClD,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,mBAAM,gBAAe,EAAE,CAAC;AAAA,MACtC;AAAA,IACD,CAAC;AACD,SAAK,YAAY,WAAW;AAE5B,aAAS,cAAoB;AAC5B,kBAAY,KAAK,CAAC,GAAG,KAAK,CAAC;AAAA,IAC5B;AAEA,aAAS,eACR,QACA,OACA,WACO;AACP,gBAAU,OAAO;AAAA,QAChB;AAAA,QACA,UAAM,2BAAY;AAAA,QAClB,GAAI,UAAU,SAAY,EAAE,OAAO,OAAO,MAAM,OAAO,IAAI,CAAC;AAAA,QAC5D,GAAI,cAAc,SAAY,EAAE,UAAU,IAAI,CAAC;AAAA,QAC/C,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E,CAAgB;AAAA,IACjB;AAEA,aAAS,QAAQ,OAAgB;AAChC,YAAM,KAAK,KAAK;AAChB,UAAI,MAAM,SAAS,YAAY;AAC9B,cAAM,UAAU,MAAM,MAAM;AAC5B,yBAAiB,KAAM,iBAAiB,QAAmB,CAAC;AAC5D,uBAAe,QAAQ,CAAC,OAAO,CAAC;AAAA,MACjC;AACA,kBAAY;AAAA,IACb;AAEA,aAAS,QAAQ,GAAgB;AAChC,YAAM,QAAQ,MAAM,OAAO,GAAG,CAAC;AAC/B,kBAAY;AACZ,aAAO;AAAA,IACR;AAEA,UAAM,aAAS;AAAA,MACd,CAAC,GAAG;AAAA,MACJ,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,WAAW,IAAI,aAAa,CAAC;AACnC,YAAI,aAAa,QAAW;AAC3B,iBAAO;AACP,gBAAM,YAAY,MAAM;AACxB,kBAAQ,CAAC;AACT,sBAAY;AACZ,yBAAe,YAAY,QAAW,SAAS;AAC/C,kBAAQ,KAAK,aAAa,OAAO,CAAC,CAAC,sBAAQ,CAAC,IAAI,CAAC,CAAC,qBAAO,QAAQ,CAAC,CAAC;AACnE;AAAA,QACD;AACA,cAAM,SAAS,UAAU,CAAC;AAC1B,YAAI,UAAU,QAAQ,OAAO,WAAW,GAAG;AAC1C,kBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,mBAAW,KAAK,QAAe;AAC9B,cAAI,cAAc;AACjB,oBAAQ,KAAK,CAAC;AAAA,UACf,OAAO;AACN,oBAAQ,CAAC;AACT,oBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AAAA,UAC1B;AAAA,QACD;AAAA,MACD;AAAA,MACA;AAAA,QACC;AAAA,QACA,cAAc;AAAA,QACd,MAAM,KAAK,iBAAiB,KAAK,IAAI;AAAA,MACtC;AAAA,IACD;AACA,SAAK,IAAI,QAAQ,EAAE,KAAK,CAAC;AAKzB,QAAI,KAAK,YAAY,MAAM;AAC1B,YAAM,kBAAkB,QAAQ,KAAK,SAAS,KAAK;AACnD,UAAI,iBAAiB;AACpB,mBAAW,KAAK,IAAI;AACpB,uBAAe;AACf,YAAI,KAAK,SAAU,WAAU;AAAA,MAC9B;AACA,YAAM,cAAc,KAAK,SAAS,UAAU,CAAC,SAAS;AACrD,mBAAW,KAAK,MAAM;AACrB,cAAI,EAAE,CAAC,MAAM,mBAAM;AACnB,gBAAM,SAAS,QAAQ,EAAE,CAAC,CAAC;AAC3B,cAAI,UAAU,CAAC,cAAc;AAE5B,gBAAI,KAAK,UAAU;AAClB,kBAAI,QAAS;AACb,wBAAU;AAAA,YACX;AACA,qCAAM,MAAM;AACX,yBAAW,KAAK,IAAI;AACpB,oBAAM,QAAQ,QAAQ,MAAM,MAAM;AAGlC,6BAAe,QAAQ,KAAK;AAC5B,yBAAW,QAAQ,OAAO;AACzB,oBAAI,KAAM;AACV,uBAAO,KAAK,IAAI;AAAA,cACjB;AAAA,YACD,CAAC;AAAA,UACF,WAAW,CAAC,UAAU,cAAc;AACnC,gBAAI,KAAK,YAAY,QAAS;AAC9B,qCAAM,MAAM;AACX,yBAAW,KAAK,KAAK;AACrB,6BAAe,OAAO;AAAA,YACvB,CAAC;AAAA,UACF;AAAA,QACD;AAAA,MACD,CAAC;AACD,WAAK,YAAY,WAAW;AAAA,IAC7B;AAEA,UAAM,YAAY,CAAC,WAAyB;AAC3C,UAAI,KAAM,OAAM,IAAI,MAAM,iBAAiB,MAAM,wCAAwC;AAAA,IAC1F;AAEA,UAAM,cAAc,CAAC,QAAQ,MAAY;AACxC,gBAAU,SAAS;AACnB,YAAM,QAAQ,QAAQ,KAAK;AAC3B,iBAAW,QAAQ,OAAO;AACzB,YAAI,KAAM;AACV,eAAO,KAAK,IAAI;AAAA,MACjB;AAAA,IACD;AACA,UAAM,aAAa,CAAC,QAAQ,MAAY;AACvC,gBAAU,QAAQ;AAClB,cAAQ,KAAK;AAAA,IACd;AACA,UAAM,aAAa,CAClB,IACA,QAAQ,MACE;AACV,gBAAU,QAAQ;AAClB,YAAM,WAAW,CAAC,GAAG,KAAK;AAC1B,YAAM,QAAQ,QAAQ,KAAK;AAC3B,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACtC,YAAI,KAAM;AACV,eAAO,KAAK,GAAG,MAAM,CAAC,GAAG,GAAG,QAAQ,CAAC;AAAA,MACtC;AAAA,IACD;AACA,UAAM,WAAW,MAAY;AAC5B,gBAAU,MAAM;AAChB,iBAAW,KAAK,IAAI;AACpB,YAAM,QAAQ,QAAQ,MAAM,MAAM;AAClC,iBAAW,QAAQ,OAAO;AACzB,YAAI,KAAM;AACV,eAAO,KAAK,IAAI;AAAA,MACjB;AAAA,IACD;AACA,UAAM,YAAY,MAAY;AAC7B,gBAAU,OAAO;AACjB,UAAI,KAAK,YAAY,QAAS;AAC9B,iBAAW,KAAK,KAAK;AAAA,IACtB;AAEA,UAAM,UAAU,OAAO,aAAa;AAAA,MACnC,OAAO;AAAA,MACP,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,iBAAiB,CAAC,MAAM,IAAI,OAC1B;AAAA,QACA,QAAQ;AAAA,QACR,OAAQ,KAAK,CAAC,KAA4B;AAAA,QAC1C,MAAM,EAAE;AAAA,QACR,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,MACD,iBAAiB,CAAC,IAAI,IAAI,OACxB;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE;AAAA,QACR,WAAW,EAAE;AAAA,QACb,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,IACF,CAAC;AACD,UAAM,SAAS,OAAO,YAAY;AAAA,MACjC,OAAO;AAAA,MACP,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,iBAAiB,CAAC,MAAM,IAAI,OAC1B;AAAA,QACA,QAAQ;AAAA,QACR,OAAQ,KAAK,CAAC,KAA4B;AAAA,QAC1C,MAAM,EAAE;AAAA,QACR,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,MACD,iBAAiB,CAAC,IAAI,IAAI,OACxB;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE;AAAA,QACR,WAAW,EAAE;AAAA,QACb,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,IACF,CAAC;AACD,UAAM,SAAS,OAAO,YAAY;AAAA,MACjC,OAAO;AAAA,MACP,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,iBAAiB,CAAC,MAAM,IAAI,OAC1B;AAAA,QACA,QAAQ;AAAA,QACR,OAAQ,KAAK,CAAC,KAA4B;AAAA,QAC1C,MAAM,EAAE;AAAA,QACR,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,MACD,iBAAiB,CAAC,IAAI,IAAI,OACxB;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE;AAAA,QACR,WAAW,EAAE;AAAA,QACb,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,IACF,CAAC;AACD,UAAM,OAAO,OAAO,UAAU;AAAA,MAC7B,OAAO;AAAA,MACP,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,iBAAiB,CAAC,IAAI,IAAI,OACxB;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE;AAAA,QACR,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,MACD,iBAAiB,CAAC,IAAI,IAAI,OACxB;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE;AAAA,QACR,WAAW,EAAE;AAAA,QACb,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,IACF,CAAC;AACD,UAAM,QAAQ,OAAO,WAAW;AAAA,MAC/B,OAAO;AAAA,MACP,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,iBAAiB,CAAC,IAAI,IAAI,OACxB;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE;AAAA,QACR,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,MACD,iBAAiB,CAAC,IAAI,IAAI,OACxB;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,EAAE;AAAA,QACR,WAAW,EAAE;AAAA,QACb,GAAI,KAAK,kBAAkB,OAAO,EAAE,gBAAgB,KAAK,eAAe,IAAI,CAAC;AAAA,MAC9E;AAAA,IACF,CAAC;AAED,SAAK,YAAY,UAAU,UAAU,MAAM,MAAS,CAAC;AAErD,UAAM,aAAgC;AAAA,MACrC;AAAA,MACA,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,SACC,MACA,QACA,UACA,OAAwD,CAAC,GACrC;AACpB,WAAO,KAAK,aAAgB,MAAM,QAAQ,EAAE,GAAG,MAAM,UAAU,YAAY,EAAE,CAAC;AAAA,EAC/E;AAAA;AAAA,EAIA,MACC,MACA,QACA,SACA,OAAwB,CAAC,GACf;AACV,UAAM,MAAM,KAAK,aAAa,MAAM;AACpC,UAAM,OAAO,KAAK,MAAM;AACxB,UAAM,WAAO;AAAA,MACZ,CAAC,GAAG;AAAA,MACJ,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,WAAW,IAAI,aAAa,CAAC;AACnC,YAAI,aAAa,QAAW;AAC3B,gBAAM,QACL,aAAa,OAAO,EAAE,MAAM,YAAY,IAAI,EAAE,MAAM,WAAW,OAAO,SAAS;AAChF,cAAI,SAAS,cAAc,SAAS,MAAM,MAAM;AAC/C,oBAAQ,KAAK,QAAQ,OAAO,OAAO,CAAC;AACpC;AAAA,UACD;AACA,kBAAQ,KAAK,MAAM,SAAS,cAAc,CAAC,CAAC,sBAAQ,CAAC,IAAI,CAAC,CAAC,qBAAO,MAAM,KAAK,CAAC,CAAC;AAC/E;AAAA,QACD;AACA,cAAM,SAAS,UAAU,CAAC;AAC1B,YAAI,UAAU,QAAQ,OAAO,WAAW,GAAG;AAC1C,kBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,mBAAW,KAAK,OAAe,SAAQ,KAAK,CAAC;AAAA,MAC9C;AAAA,MACA;AAAA,QACC;AAAA,QACA,cAAc;AAAA,QACd,0BACC,KAAK,4BAA4B,EAAE,SAAS,eAAe,SAAS;AAAA,QACrE,oBAAoB,EAAE,SAAS,aAAa,SAAS;AAAA,QACrD,MAAM,KAAK,SAAS,KAAK,IAAI;AAAA,MAC9B;AAAA,IACD;AACA,SAAK,IAAI,MAAM,EAAE,KAAK,CAAC;AACvB,WAAO;AAAA,EACR;AAAA;AAAA,EAIQ,aAAa,KAA6B;AACjD,QAAI,OAAO,QAAQ,SAAU,QAAO,KAAK,QAAQ,GAAG;AACpD,UAAM,WAAW,KAAK,OAAO,GAAG;AAChC,QAAI,aAAa,QAAW;AAC3B,YAAM,IAAI;AAAA,QACT,kBAAkB,KAAK,IAAI;AAAA,MAC5B;AAAA,IACD;AACA,WAAO;AAAA,EACR;AACD;AAGO,SAAS,cAAc,MAAc,MAAoC;AAC/E,QAAM,IAAI,IAAI,cAAc,MAAM,IAAI;AAOtC,QAAM,EAAE,SAAS,IAAI,aAAa,KAAK,GAAG,QAAQ,IAAK,QAAQ,CAAC;AAChE,IAAE,WAAW,qBAAiB,+BAAgB,OAAO,CAAC;AACtD,SAAO;AACR;;;AC7pBA,IAAAC,gBAA0C;AAC1C,IAAAC,iBAA+D;AAC/D,IAAAC,gBAAyC;AAalC,IAAM,kBAAN,cAA8B,oBAAM;AAAA,EACzB;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA,EACA;AAAA,EAET,YAAY,MAAc,OAA0B,CAAC,GAAG;AACvD,UAAM,MAAM,KAAK,KAAK;AAEtB,SAAK,WAAO,4BAAyB,CAAC,GAAG;AAAA,MACxC,MAAM;AAAA,MACN,SAAS,KAAK;AAAA,IACf,CAAC;AACD,SAAK,WAAW,KAAK,KAAK;AAC1B,SAAK,IAAI,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAK5C,SAAK,aAAS;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,UAAU,KAAK,CAAC;AACtB,YAAI,QAAQ,WAAW,GAAG;AACzB,kBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,gBAAQ,KAAK,QAAQ,QAAQ,SAAS,CAAC,CAAgB;AAAA,MACxD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,aAAa;AAAA,MAC3B;AAAA,IACD;AACA,SAAK,IAAI,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,SAAK,gBAAY,0BAAU,KAAK,MAAM,CAAC;AAEvC,SAAK,mBAAe;AAAA,MACnB,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACA,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,gBAAQ,KAAM,KAAK,CAAC,EAA6B,MAAM;AAAA,MACxD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,oBAAoB;AAAA,QACjC,SAAS;AAAA,MACV;AAAA,IACD;AACA,SAAK,IAAI,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,SAAK,gBAAY,0BAAU,KAAK,YAAY,CAAC;AAAA,EAC9C;AAAA,EAEA,OAAO,MAA2B,SAAiB,OAAoC;AACtF,SAAK,KAAK,OAAO,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC;AAAA,EAC7C;AAAA,EAEA,iBAAiB,QAAgB,SAAuB;AACvD,SAAK,KAAK,OAAO,EAAE,MAAM,QAAQ,SAAS,YAAY,OAAO,CAAC;AAAA,EAC/D;AAAA,EAEA,QAAc;AACb,SAAK,KAAK,MAAM;AAAA,EACjB;AAAA,EAEA,cAAsC;AACrC,WAAO,KAAK,SAAS;AAAA,EACtB;AACD;AAEO,SAAS,WAAW,MAAc,MAA2C;AACnF,SAAO,IAAI,gBAAgB,MAAM,IAAI;AACtC;;;AC/EA,IAAAC,gBAAgC;AAChC,IAAAC,iBAAkC;AAmE3B,SAAS,cAAc,MAAyD;AACtF,QAAM,EAAE,WAAW,MAAM,IAAI;AAC7B,QAAM,aAAa,KAAK,cAAc;AACtC,QAAM,UAAU,KAAK,WAAW;AAEhC,QAAM,cAAc,CAAC,GAA0B,MAAsC;AACpF,QAAI,MAAM,EAAG,QAAO;AACpB,QAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,aAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAClC,YAAM,KAAK,EAAE,CAAC;AACd,YAAM,KAAK,EAAE,CAAC;AACd,UAAI,IAAI,OAAO,IAAI,GAAI,QAAO;AAC9B,UAAI,IAAI,YAAY,IAAI,QAAS,QAAO;AAAA,IACzC;AACA,WAAO;AAAA,EACR;AAEA,aAAO,0BAAsD,WAAW,CAAC,UAAU;AAClF,QAAI,SAAS,QAAQ,MAAM,WAAW,GAAG;AACxC,YAAM,IAAI;AAAA,QACT;AAAA,MACD;AAAA,IACD;AACA,UAAM,UAAU,MAAM,IAAI,CAAC,SAAS,WAAW,MAAM,OAAO,YAAY,OAAO,CAAC;AAKhF,eAAO;AAAA,MACN;AAAA,MACA,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,gBAAQ,KAAK,IAA6B;AAAA,MAC3C;AAAA,MACA,EAAE,cAAc,WAAW,MAAM,wBAAwB,QAAQ,YAAY;AAAA,IAC9E;AAAA,EACD,CAAC;AACF;AAmBA,SAAS,WACR,MACA,OACA,YACA,SACmB;AACnB,QAAM,YAA2B,MAAM,MAAM,MAAM,gBAAgB,KAAK,MAAM,KAAK,SAAS,GAAG;AAAA,IAC9F,OAAO;AAAA,EACR,CAAC,EAAE;AACH,QAAM,gBAAY;AAAA,IACjB,CAAC,SAAS;AAAA,IACV,CAAC,WAAW,SAAS,QAAQ;AAC5B,YAAM,OAAO,UAAU;AAAA,QAAI,CAACA,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,MAClE;AACA,YAAM,MAAM,KAAK,CAAC;AAClB,cAAQ,KAAK;AAAA,QACZ,IAAI,KAAK;AAAA,QACT,SAAS,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG;AAAA,MAC5D,CAAC;AAAA,IACF;AAAA,IACA,EAAE,cAAc,UAAU;AAAA,EAC3B;AACA,MAAI,YAAY,YAAa,QAAO;AACpC,aAAO,uBAAO,WAAW,CAAC,SAAS;AAAA,IAClC,IAAI,KAAK;AAAA,IACT,SAAS,KAAK,UAAU,EAAE,OAAO,OAAO,GAAG,EAAE,CAAC;AAAA,EAC/C,EAAE;AACH;;;ACjLA,IAAAC,gBAAsD;AACtD,IAAAC,iBAAmE;AACnE,IAAAC,gBAAyC;AAgClC,IAAM,oBAAN,cAAgC,oBAAM;AAAA,EACnC;AAAA,EACA;AAAA,EACQ;AAAA,EAEjB,YAAY,MAAc,OAA4B,CAAC,GAAG;AACzD,UAAM,MAAM,KAAK,KAAK;AAEtB,SAAK,cAAU,4BAAoC;AAAA,MAClD,MAAM;AAAA,IACP,CAAC;AACD,SAAK,cAAc,KAAK,QAAQ;AAChC,SAAK,IAAI,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,SAAK,cAAU;AAAA,MACd,CAAC,KAAK,WAAW;AAAA,MACjB,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,OAAO,KAAK,CAAC;AACnB,gBAAQ,KAAK,CAAC,IAAK,QAAQ,oBAAI,IAAI,GAA2C,OAAO,CAAC,CAAC;AAAA,MACxF;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,cAAc;AAAA,QAC3B,SAAS,CAAC;AAAA,MACX;AAAA,IACD;AACA,SAAK,IAAI,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,SAAK,gBAAY,0BAAU,KAAK,OAAO,CAAC;AAAA,EACzC;AAAA,EAEA,SAAS,MAA4B;AACpC,SAAK,QAAQ,IAAI,KAAK,MAAM,IAAI;AAAA,EACjC;AAAA,EAEA,WAAW,MAAoB;AAC9B,SAAK,QAAQ,OAAO,IAAI;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BA,gBAAgB,MAAc,MAA8C;AAC3E,UAAM,OAAO,KAAK,QAAQ,IAAI,IAAI;AAClC,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,+BAA+B,IAAI,GAAG;AACjE,eAAO;AAAA,MACN,CAAC;AAAA,MACD,CAAC,OAAO,YAAY;AACnB,cAAM,KAAK,IAAI,gBAAgB;AAC/B,YAAI;AACJ,YAAI;AACH,gBAAM,MAAM,KAAK,QAAQ,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;AACpD,kBAAQ,oBAAoB,KAAK,GAAG,MAAM;AAAA,QAC3C,SAAS,KAAK;AAIb,kBAAQ,KAAK,CAAC,CAAC,qBAAO,GAAG,CAAC,CAAoB;AAC9C,iBAAO;AAAA,YACN,gBAAgB,MAAM;AACrB,iBAAG,MAAM;AAAA,YACV;AAAA,UACD;AAAA,QACD;AACA,cAAM,QAAQ,MAAM,UAAU,CAACA,YAAU;AACxC,kBAAQ,KAAKA,OAAiB;AAAA,QAC/B,CAAC;AACD,eAAO;AAAA,UACN,gBAAgB,MAAM;AACrB,eAAG,MAAM;AACT,kBAAM;AAAA,UACP;AAAA,QACD;AAAA,MACD;AAAA,MACA;AAAA,QACC,MAAM,oBAAoB,IAAI;AAAA,QAC9B,cAAc;AAAA,QACd,MAAM,OAAO,uBAAuB;AAAA,MACrC;AAAA,IACD;AAAA,EACD;AAAA,EAEA,cAAc,MAA0C;AAKvD,WAAO,KAAK,QAAQ,QAAQ,OAAO,IAAI,IAAI;AAAA,EAC5C;AACD;AAEO,SAAS,aAAa,MAAc,MAA+C;AACzF,SAAO,IAAI,kBAAkB,MAAM,IAAI;AACxC;AAeA,SAAS,oBAAoB,KAAc,QAAoC;AAC9E,MAAI,WAAW,GAAG,GAAG;AACpB,WAAO;AAAA,EACR;AACA,MAAI,OAAO,QAAQ,OAAQ,IAA6B,SAAS,YAAY;AAC5E,eAAO,4BAAY,KAA6B,EAAE,OAAO,CAAC;AAAA,EAC3D;AACA,MAAI,OAAO,QAAQ,OAAO,QAAQ,YAAY,OAAO,iBAAkB,KAAgB;AACtF,eAAO,8BAAc,KAA+B,EAAE,OAAO,CAAC;AAAA,EAC/D;AAKA,aAAO,4BAAY,QAAQ,QAAQ,GAAG,GAAG,EAAE,OAAO,CAAC;AACpD;;;ACjKO,IAAM,qBAAqB,KAAK,OAAO,IAAI;;;ACmB3C,SAAS,YAAY,MAAyD;AACpF,SAAO,KAAK,YAAY,CAAC,KAAK,KAAK;AACpC;;;ACZO,IAAM,cAAqC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAGO,IAAM,wBAAyD;AAAA,EACrE,YAAY,EAAE,OAAO,MAAM;AAAA,EAC3B,kBAAkB,EAAE,OAAO,KAAK;AAAA,EAChC,eAAe,EAAE,OAAO,KAAK;AAAA;AAAA;AAAA,EAG7B,SAAS,EAAE,OAAO,MAAM;AACzB;AAOO,IAAM,2BAAqD;AAAA,EACjE,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AACN;AAiBO,SAAS,YACf,UACA,WACA,cACc;AACd,SAAO,GAAG,QAAQ,IAAI,SAAS,SAAI,YAAY;AAChD;AAaA,IAAM,sBAAsB;AAGrB,IAAM,yBAA0C,CAAC,WACvD,oBAAoB,KAAK,OAAO,MAAM,IAAI,qBAAqB;AAOzD,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkB9B,IAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc/B,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgC9B,SAAS,gBACf,KACA,kBACA,YACwB;AACxB,MAAI,OAAO,QAAQ,WAAY,QAAO;AACtC,QAAM,WAAW,OAAO;AACxB,SAAO,CAAC,UAAU,WAAW,UAAU,KAAK;AAC7C;;;ACnKA,IAAAC,gBAA6C;;;ACI7C,IAAAC,iBAA+D;AAC/D,IAAAC,iBAAyC;AA8ClC,IAAM,6BAAN,cAGG,qBAAM;AAAA;AAAA,EAEN;AAAA,EAEQ;AAAA,EAEjB,YAAY,MAAqC;AAChD,UAAM,MAAM,QAAQ,2BAA2B,MAAM,KAAK;AAC1D,SAAK,WAAO,4BAA0B,EAAE,MAAM,UAAU,CAAC;AACzD,SAAK,UAAU,KAAK,KAAK;AACzB,SAAK,IAAI,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAM1C,SAAK,gBAAY,0BAAU,KAAK,OAAO,CAAC;AACxC,SAAK,YAAY,MAAM,KAAK,KAAK,QAAQ,CAAC;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,OACC,KACA,SACA,OACO;AACP,UAAM,WAAW,KAAK,KAAK,IAAI,GAAG;AAClC,UAAM,YAAY,UAAU,YAAY,KAAK;AAC7C,UAAM,aAAa,UAAU,aAAa,MAAM,UAAU,IAAI;AAC9D,SAAK,KAAK,IAAI,KAAK;AAAA,MAClB,GAAI,YAAY,CAAC;AAAA,MACjB,GAAI,SAAS,CAAC;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,YAAY;AAAA,IAC1B,CAAW;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,KAA+B;AACrC,WAAO,KAAK,KAAK,IAAI,GAAG;AAAA,EACzB;AACD;AA+BO,SAAS,sBAGd,MAA+E;AAChF,SAAO,IAAI,2BAAyC,IAAI;AACzD;;;AChCO,IAAM,oBAA8B;;;AFvEpC,SAAS,gBAAoC;AACnD,SAAO,sBAAkD,EAAE,MAAM,WAAW,CAAC;AAC9E;;;AGzDA,IAAAC,gBAQO;AAEP,IAAAC,iBAQO;AACP,IAAAC,iBAAyC;AAUzC,IAAMC,wBAAuB;AAC7B,IAAM,mCAAmC;AAEzC,SAASC,uBAAsB,OAAe,OAAuB;AACpE,MAAI,CAAC,OAAO,SAAS,KAAK,KAAK,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AACrE,UAAM,IAAI,MAAM,GAAG,KAAK,iCAAiC;AAAA,EAC1D;AACA,SAAO;AACR;AAEA,SAAS,aAAa,MAAc,OAA0D;AAC7F,SAAO,WAAW,aAAa,MAAM,KAAK;AAC3C;AA6BO,IAAM,gBAAN,cAA+B,qBAAM;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOQ;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,MAAc,OAAwB,CAAC,GAAG;AACrD,UAAM,MAAM,KAAK,KAAK;AACtB,SAAK,eAAW,6BAAqB,CAAC,GAAG,EAAE,MAAM,UAAU,CAAC;AAC5D,SAAK,YAAQ,4BAAoC,EAAE,MAAM,OAAO,CAAC;AACjE,SAAK,UAAU,KAAK,SAAS;AAC7B,SAAK,OAAO,KAAK,MAAM;AACvB,SAAK,IAAI,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,SAAK,IAAI,KAAK,MAAM,EAAE,MAAM,OAAO,CAAC;AACpC,SAAK,YAAQ;AAAA,MACZ,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,gBAAQ,KAAM,KAAK,CAAC,EAAwB,MAAM;AAAA,MACnD;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,aAAa,aAAa;AAAA,QAChC,SAAS;AAAA,MACV;AAAA,IACD;AACA,SAAK,IAAI,KAAK,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,SAAK,gBAAY,0BAAU,KAAK,KAAK,CAAC;AAEtC,SAAK,SAAS,eAA4B;AAAA,MACzC,MAAM;AAAA,MACN,eAAe;AAAA,MACf,OAAO;AAAA,IACR,CAAC;AACD,SAAK,QAAQ,KAAK;AAClB,SAAK,aAAa,eAAe,MAAM,OAAO,CAAC;AAO/C,SAAK,eAAe;AAAA,MAKnB,CAAC,SAAS,gBAAwB;AACjC,cAAM,MAAM,KAAK,WAAW;AAC5B,cAAM,KAAK,YAAY,MAAM,GAAG,KAAK,IAAI,IAAI,GAAG;AAChD,YAAI,KAAK,MAAM,IAAI,EAAE,MAAM,QAAW;AACrC,gBAAM,IAAI,MAAM,aAAa,KAAK,IAAI,yBAAyB,EAAE,GAAG;AAAA,QACrE;AACA,cAAM,MAAsB;AAAA,UAC3B;AAAA,UACA;AAAA,UACA,UAAU;AAAA,UACV,UAAU,OAAO,OAAO,EAAE,GAAI,YAAY,YAAY,CAAC,EAAG,CAAC;AAAA,UAC3D,OAAO;AAAA,QACR;AACA,aAAK,MAAM,IAAI,IAAI,GAAG;AACtB,aAAK,SAAS,OAAO,EAAE;AACvB,eAAO;AAAA,MACR;AAAA,MACA;AAAA,QACC,OAAO;AAAA,QACP,KAAK,KAAK;AAAA,QACV,KAAK,KAAK;AAAA,QACV,QAAQ;AAAA,QACR,iBAAiB,CAAC,CAAC,OAAO,GAAG,IAAI,EAAE,MAAM,IAAI,OAAO;AAAA,UACnD,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK,OAAO;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAEA,SAAK,WAAW;AAAA,MACf,CAAC,IAAI,SAAe;AACnB,aAAK,MAAM,OAAO,EAAE;AAAA,MACrB;AAAA,MACA;AAAA,QACC,OAAO;AAAA,QACP,KAAK,KAAK;AAAA,QACV,KAAK,KAAK;AAAA,QACV,QAAQ;AAAA,QACR,iBAAiB,CAAC,CAAC,IAAI,GAAG,GAAG,IAAI,EAAE,MAAM,IAAI,OAAO;AAAA,UACnD,QAAQ;AAAA,UACR;AAAA,UACA,UAAU,IAAI;AAAA,UACd;AAAA,UACA,KAAK,OAAO;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAEA,SAAK,YAAY;AAAA,MAChB,CAAC,IAAI,KAAK,YAAkB;AAC3B,YAAI,SAAS;AACZ,eAAK,MAAM,IAAI,IAAI,EAAE,GAAG,KAAK,OAAO,SAAS,CAAC;AAC9C,eAAK,SAAS,OAAO,EAAE;AAAA,QACxB,OAAO;AACN,eAAK,MAAM,OAAO,EAAE;AAAA,QACrB;AAAA,MACD;AAAA,MACA;AAAA,QACC,OAAO;AAAA,QACP,KAAK,KAAK;AAAA,QACV,KAAK,KAAK;AAAA,QACV,QAAQ;AAAA,QACR,iBAAiB,CAAC,CAAC,IAAI,GAAG,GAAG,IAAI,EAAE,MAAM,IAAI,OAAO;AAAA,UACnD,QAAQ;AAAA,UACR;AAAA,UACA,UAAU,IAAI;AAAA,UACd;AAAA,UACA,KAAK,OAAO;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAEA,SAAK,kBAAkB;AAAA,MACtB,CAAC,IAAI,QAAc;AAClB,YAAI,IAAI,UAAU,UAAU;AAC3B,gBAAM,UAAU,KAAK,QAAQ;AAC7B,gBAAM,MAAM,QAAQ,QAAQ,EAAE;AAC9B,cAAI,OAAO,EAAG,MAAK,SAAS,IAAI,GAAG;AAAA,QACpC;AACA,aAAK,MAAM,OAAO,EAAE;AAAA,MACrB;AAAA,MACA;AAAA,QACC,OAAO;AAAA,QACP,KAAK,KAAK;AAAA,QACV,KAAK,KAAK;AAAA,QACV,QAAQ;AAAA,QACR,iBAAiB,CAAC,CAAC,IAAI,GAAG,GAAG,IAAI,EAAE,MAAM,IAAI,OAAO;AAAA,UACnD,QAAQ;AAAA,UACR;AAAA,UACA,UAAU,IAAI;AAAA,UACd;AAAA,UACA,KAAK,OAAO;AAAA,QACb;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB,OAAiE;AACnF,WAAO,KAAK,OAAO,cAAc,KAAK;AAAA,EACvC;AAAA,EAEA,QAAQ,SAAY,OAA4D,CAAC,GAAW;AAC3F,WAAO,KAAK,aAAa,SAAS,IAAI;AAAA,EACvC;AAAA,EAEA,MAAM,QAAQ,GAA8B;AAC3C,UAAM,MAAMC,uBAAsB,OAAO,uBAAuB;AAChE,QAAI,QAAQ,EAAG,QAAO,CAAC;AACvB,UAAM,MAAwB,CAAC;AAC/B,WAAO,IAAI,SAAS,KAAK;AACxB,YAAM,MAAM,KAAK,QAAQ;AACzB,UAAI,IAAI,WAAW,EAAG;AACtB,YAAM,KAAK,KAAK,SAAS,IAAI,CAAC;AAC9B,YAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,UAAI,CAAC,OAAO,IAAI,UAAU,SAAU;AACpC,YAAM,WAA2B;AAAA,QAChC,GAAG;AAAA,QACH,OAAO;AAAA,QACP,UAAU,IAAI,WAAW;AAAA,MAC1B;AACA,WAAK,MAAM,IAAI,IAAI,QAAQ;AAC3B,UAAI,KAAK,QAAQ;AAIjB,WAAK,OAAO,OAAO;AAAA,QAClB,QAAQ;AAAA,QACR;AAAA,QACA,UAAU,SAAS;AAAA,QACnB,UAAM,2BAAY;AAAA,QAClB,KAAK,WAAW,KAAK,UAAU;AAAA,MAChC,CAAC;AAAA,IACF;AACA,WAAO;AAAA,EACR;AAAA,EAEA,IAAI,IAAqB;AACxB,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,CAAC,OAAO,IAAI,UAAU,WAAY,QAAO;AAC7C,SAAK,SAAS,IAAI,GAAG;AACrB,WAAO;AAAA,EACR;AAAA,EAEA,KAAK,IAAY,OAA8B,CAAC,GAAY;AAC3D,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,CAAC,OAAO,IAAI,UAAU,WAAY,QAAO;AAC7C,SAAK,UAAU,IAAI,KAAK,KAAK,WAAW,IAAI;AAC5C,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,WAAW,IAAqB;AAC/B,UAAM,MAAM,KAAK,MAAM,IAAI,EAAE;AAC7B,QAAI,CAAC,IAAK,QAAO;AACjB,SAAK,gBAAgB,IAAI,GAAG;AAC5B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,YACC,QACA,MAGa;AACb,WAAO,OAAO,UAAU,CAAC,SAAS;AACjC,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,mBAAM;AACnB,cAAM,UAAU,EAAE,CAAC;AACnB,aAAK,QAAQ,SAAS,OAAO,EAAE,UAAU,KAAK,SAAS,IAAI,MAAS;AAAA,MACrE;AAAA,IACD,CAAC;AAAA,EACF;AACD;AAkFO,IAAM,eAAN,cAA8B,qBAAM;AAAA,EACzB;AAAA,EACA;AAAA,EACA,UAAU,oBAAI,IAA8B;AAAA,EAC5C;AAAA,EACR;AAAA,EACA;AAAA,EAET,YAAY,MAAc,OAA0B,CAAC,GAAG;AACvD,UAAM,MAAM,KAAK,KAAK;AAGtB,UAAM,YAAY,KAAK,UAAW,CAAC,YAAY,cAAc,MAAM;AACnE,UAAM,aAAuB,CAAC;AAC9B,UAAM,eAAe,oBAAI,IAAuB;AAChD,UAAM,kBAAkB,oBAAI,IAAoB;AAChD,UAAM,mBAAmB,oBAAI,IAAoB;AAEjD,eAAW,OAAO,WAAW;AAC5B,YAAM,YAAY,OAAO,QAAQ,WAAW,IAAI,KAAK,IAAI,IAAI,KAAK,KAAK;AACvE,UAAI,OAAO,QAAQ,YAAY,IAAI,MAAM;AACxC,qBAAa,IAAI,WAAW,IAAI,IAAI;AAAA,MACrC;AACA,UAAI,OAAO,QAAQ,YAAY,IAAI,cAAc,MAAM;AACtD,wBAAgB;AAAA,UACf;AAAA,UACA,KAAK;AAAA,YACJ;AAAA,YACAA,uBAAsB,IAAI,YAAY,mBAAmB,SAAS,cAAc;AAAA,UACjF;AAAA,QACD;AAAA,MACD;AACA,UAAI,OAAO,QAAQ,YAAY,IAAI,eAAe,MAAM;AACvD,yBAAiB;AAAA,UAChB;AAAA,UACA,KAAK;AAAA,YACJ;AAAA,YACAA,uBAAsB,IAAI,aAAa,mBAAmB,SAAS,eAAe;AAAA,UACnF;AAAA,QACD;AAAA,MACD;AACA,iBAAW,KAAK,SAAS;AAAA,IAC1B;AAEA,QAAI,WAAW,SAAS,GAAG;AAC1B,YAAM,IAAI,MAAM,YAAY,IAAI,gCAAgC;AAAA,IACjE;AACA,UAAM,SAAS,IAAI,IAAI,UAAU;AACjC,QAAI,OAAO,SAAS,WAAW,QAAQ;AACtC,YAAM,IAAI,MAAM,YAAY,IAAI,gCAAgC;AAAA,IACjE;AACA,SAAK,cAAc,OAAO,OAAO,CAAC,GAAG,UAAU,CAAC;AAChD,SAAK,gBAAgB;AAErB,eAAW,SAAS,KAAK,aAAa;AACrC,YAAM,IAAI,SAAY,GAAG,IAAI,IAAI,KAAK,EAAE;AACxC,WAAK,QAAQ,IAAI,OAAO,CAAC;AACzB,WAAK,MAAM,OAAO,CAAC;AAAA,IACpB;AAEA,SAAK,iBAAa,4BAA4B,CAAC,GAAG;AAAA,MACjD,MAAM;AAAA,MACN,SAAS;AAAA,IACV,CAAC;AACD,SAAK,YAAY,KAAK,WAAW;AACjC,SAAK,IAAI,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,SAAK,qBAAiB;AAAA,MACrB,CAAC,KAAK,SAAS;AAAA,MACf,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACD,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,gBAAQ,KAAM,KAAK,CAAC,EAAgC,MAAM;AAAA,MAC3D;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,aAAa,0BAA0B;AAAA,QAC7C,SAAS;AAAA,MACV;AAAA,IACD;AACA,SAAK,IAAI,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,SAAK,gBAAY,0BAAU,KAAK,cAAc,CAAC;AAE/C,UAAM,oBAAoB,KAAK;AAAA,MAC9B;AAAA,MACAC,uBAAsB,KAAK,cAAcC,uBAAsB,qBAAqB;AAAA,IACrF;AAGA,aAAS,IAAI,GAAG,IAAI,KAAK,YAAY,QAAQ,KAAK,GAAG;AACpD,YAAM,QAAQ,KAAK,YAAY,CAAC;AAChC,YAAM,UAAU,KAAK,MAAM,KAAK;AAChC,YAAM,OACL,IAAI,IAAI,KAAK,YAAY,SAAS,KAAK,MAAM,KAAK,YAAY,IAAI,CAAC,CAAW,IAAI;AACnF,YAAM,SAAS,KAAK,cAAc,IAAI,KAAK;AAG3C,YAAM,eAAe,gBAAgB,IAAI,KAAK,KAAK;AACnD,YAAM,sBAAsB,iBAAiB,IAAI,KAAK;AAYtD,YAAM,kBACL,wBAAwB,aACrB,oBAAa,CAAC,GAAG,EAAE,MAAM,gBAAgB,KAAK,IAAI,SAAS,EAAE,CAAC,IAC9D;AACJ,UAAI,iBAAiB;AACpB,aAAK,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,KAAK,GAAG,CAAC;AAAA,MAC5D;AAIA,YAAM,aAAa,SAAS;AAE5B,UAAI,QAAQ;AAoBX,cAAM,WACL,mBAAmB,OAAO,CAAC,QAAQ,SAAS,eAAe,IAAI,CAAC,QAAQ,OAAO;AAChF,cAAM,WAAO;AAAA,UACZ;AAAA,UACA,CAAC,OAAO,UAAU,QAAQ;AACzB,gBAAI,EAAE,cAAc,IAAI,QAAQ;AAC/B,kBAAI,MAAM,WAAW;AAAA,gBACpB,SAAS,oBAAI,IAAmB;AAAA,gBAChC,YAAY;AAAA,cACb;AAAA,YACD;AACA,kBAAM,gBAAgB,IAAI,MAAM;AAChC,kBAAM,WAAW,cAAc;AAC/B,gBAAI,YAAY;AAChB,mBAAO,YAAY,cAAc;AAKhC,kBAAI,wBAAwB,UAAa,SAAS,QAAQ,qBAAqB;AAC9E;AAAA,cACD;AACA,oBAAM,SAAS,QAAQ,MAAM,CAAC;AAC9B,kBAAI,OAAO,WAAW,EAAG;AACzB,oBAAM,MAAM,OAAO,CAAC;AACpB,kBAAI,CAAC,IAAK;AAGV,oBAAM,WAAY,IAAI,SAAS,iBAAmD,CAAC;AACnF,oBAAM,UAAU,CAAC,GAAG,UAAU,KAAK;AAEnC,oBAAM,KAAK,IAAI,gBAAgB;AAC/B,oBAAM,QAAuB,EAAE,OAAO,MAAM,QAAW,GAAG;AAC1D,uBAAS,IAAI,KAAK;AAClB,+BAAiB,KAAK,SAAS,IAAI;AAEnC,kBAAI;AACJ,kBAAI;AACH,yBAAS,OAAO,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;AAAA,cAC3C,QAAQ;AAEP,yBAAS,OAAO,KAAK;AACrB,iCAAiB,KAAK,SAAS,IAAI;AACnC,wBAAQ,KAAK,IAAI,IAAI,EAAE,SAAS,MAAM,CAAC;AACvC,6BAAa;AACb;AAAA,cACD;AAGA,oBAAM,iBAAa,wBAAW,MAAM;AAKpC,kBAAI,UAAU;AACd,kBAAI;AACJ,oBAAM,aAAa,MAAY;AAC9B,oBAAI,OAAO;AACV,wBAAM;AAAA,gBACP,OAAO;AACN,0BAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,CAAC;AAAA,gBACvC;AACA,yBAAS,OAAO,KAAK;AAMrB,oBAAI,CAAC,cAAc,YAAY;AAC9B,mCAAiB,KAAK,SAAS,IAAI;AAAA,gBACpC;AAAA,cACD;AACA,sBAAQ,WAAW,UAAU,CAAC,SAAS;AACtC,oBAAI,QAAS;AACb,2BAAW,KAAK,MAAM;AACrB,sBAAI,EAAE,CAAC,MAAM,oBAAM;AAClB,8BAAU;AACV,+BAAW;AACX,0BAAM,aAAa,EAAE,CAAC;AACtB,0BAAM,cAAc;AAAA,sBACnB,GAAG,IAAI;AAAA,sBACP,eAAe;AAAA,oBAChB;AACA,wBAAI,YAAY;AACf,4BAAM,eAA+B;AAAA,wBACpC,GAAG;AAAA,wBACH,SAAS;AAAA,wBACT,UAAU,OAAO,OAAO,WAAW;AAAA,sBACpC;AACA,+CAAM,MAAM;AACX,gCAAQ,IAAI,IAAI,EAAE;AAClB,6BAAK,WAAW,OAAO,YAAY;AAAA,sBACpC,CAAC;AAAA,oBACF,OAAO;AACN,+CAAM,MAAM;AACX,gCAAQ,IAAI,IAAI,EAAE;AAClB,wBAAC,KAA0B,QAAQ,YAAY;AAAA,0BAC9C,UAAU;AAAA,wBACX,CAAC;AAAA,sBACF,CAAC;AAAA,oBACF;AACA;AAAA,kBACD,WAAW,EAAE,CAAC,MAAM,qBAAO;AAC1B,8BAAU;AACV,+BAAW;AACX,4BAAQ,KAAK,IAAI,IAAI,EAAE,SAAS,MAAM,CAAC;AACvC;AAAA,kBACD;AAAA,gBACD;AAAA,cACD,CAAC;AACD,oBAAM,QAAQ,MAAM,QAAQ;AAE5B,2BAAa;AAAA,YACd;AACA,mBAAO;AAAA,cACN,gBAAgB,MAAM;AAKrB,8BAAc,aAAa;AAC3B,2BAAW,KAAK,UAAU;AACzB,sBAAI;AACH,sBAAE,GAAG,MAAM;AAAA,kBACZ,QAAQ;AAAA,kBAER;AACA,sBAAI;AACH,sBAAE,MAAM;AAAA,kBACT,QAAQ;AAAA,kBAER;AAAA,gBACD;AACA,yBAAS,MAAM;AAOf,uBAAO,IAAI,MAAM;AAAA,cAClB;AAAA,YACD;AAAA,UACD;AAAA,UACA;AAAA,YACC,MAAM,aAAa,iBAAiB,EAAE,OAAO,UAAU,KAAK,CAAC;AAAA,UAC9D;AAAA,QACD;AACA,aAAK,gBAAY,0BAAU,IAAI,CAAC;AAAA,MACjC,OAAO;AAGN,cAAM,OAAO,KAAK;AAAA,UACjB,QAAQ,KAAK;AAAA,UACb,CAAC,GAAG,KAAK,WAAW;AAAA,UACpB,MAAM;AACL,gBAAI,QAAQ;AACZ,mBAAO,QAAQ,cAAc;AAC5B,oBAAM,QAAQ,QAAQ,MAAM,CAAC;AAC7B,kBAAI,MAAM,WAAW,EAAG;AACxB,oBAAM,MAAM,MAAM,CAAC;AACnB,kBAAI,CAAC,IAAK;AAEV,oBAAM,WAAY,IAAI,SAAS,iBAAmD,CAAC;AACnF,oBAAM,UAAU,CAAC,GAAG,UAAU,KAAK;AACnC,oBAAM,cAAc,EAAE,GAAG,IAAI,UAAU,eAAe,QAAQ;AAE9D,kBAAI,YAAY;AACf,sBAAM,eAA+B;AAAA,kBACpC,GAAG;AAAA,kBACH,UAAU,OAAO,OAAO,WAAW;AAAA,gBACpC;AACA,yCAAM,MAAM;AACX,0BAAQ,IAAI,IAAI,EAAE;AAClB,uBAAK,WAAW,OAAO,YAAY;AAAA,gBACpC,CAAC;AAAA,cACF,OAAO;AACN,yCAAM,MAAM;AACX,0BAAQ,IAAI,IAAI,EAAE;AAClB,kBAAC,KAA0B,QAAQ,IAAI,SAAS;AAAA,oBAC/C,UAAU;AAAA,kBACX,CAAC;AAAA,gBACF,CAAC;AAAA,cACF;AACA,uBAAS;AAAA,YACV;AAAA,UACD;AAAA,UACA;AAAA,YACC,MAAM,aAAa,iBAAiB,EAAE,OAAO,UAAU,MAAM,CAAC;AAAA,UAC/D;AAAA,QACD;AACA,aAAK,gBAAY,0BAAU,IAAI,CAAC;AAAA,MACjC;AAAA,IACD;AAAA,EACD;AAAA,EAEA,SAA4B;AAC3B,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,MAAM,OAAiC;AACtC,UAAM,IAAI,KAAK,QAAQ,IAAI,KAAK;AAChC,QAAI,CAAC,EAAG,OAAM,IAAI,MAAM,YAAY,KAAK,IAAI,sBAAsB,KAAK,GAAG;AAC3E,WAAO;AAAA,EACR;AAAA,EAEA,QAAQ,SAAY,OAA4D,CAAC,GAAW;AAC3F,WAAO,KAAK,MAAM,KAAK,YAAY,CAAC,CAAW,EAAE,QAAQ,SAAS,IAAI;AAAA,EACvE;AAAA,EAEA,oBAA+C;AAC9C,WAAO,KAAK,UAAU;AAAA,EACvB;AACD;AAKO,SAAS,SAAY,MAAc,MAA0C;AACnF,SAAO,IAAI,cAAiB,MAAM,IAAI;AACvC;AAKO,SAAS,QAAW,MAAc,MAA2C;AACnF,QAAM,IAAI,IAAI,aAAgB,MAAM,IAAI;AAKxC,QAAM,EAAE,SAAS,IAAI,aAAa,KAAK,GAAG,QAAQ,IAAK,QAAQ,CAAC;AAChE,IAAE,WAAW,eAAW,+BAAgB,OAAO,CAAC;AAChD,SAAO;AACR;;;AdjtBA,IAAM,eAAe;AACrB,IAAM,sBAAsB;AAC5B,IAAM,cAAc;AACpB,IAAM,uBAAuB;AAC7B,IAAM,iBAAiB;AAyBhB,SAAS,mBACf,SACA,QACqB;AACrB,QAAM,WAAW;AAAA,IAA6B;AAAA,IAAQ;AAAA,IAAwB,CAAC,KAAK,SACnF,IAAI,QAAQ,YAAY,KAAK,UAAU,IAAI,CAAC;AAAA,EAC7C;AACA,SAAO,CAAC,KAAK,SAAS;AACrB,UAAM,OAAO,IAAI,QAAQ;AACzB,UAAM,WAAmC,CAAC,EAAE,MAAM,QAAQ,SAAS,SAAS,IAAI,EAAE,CAAC;AAQnF,UAAM,iBAAiB,CAAC,YAA0C;AAAA,MACjE,GAAG,IAAI;AAAA,MACP,WAAW,EAAE,MAAM,SAAS,WAAW,OAAO;AAAA,IAC/C;AACA,UAAM,YAAY,CAAC,QAA0B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAM5F,WAAO,gBAAsC,SAAS,UAAU;AAAA,MAC/D,cAAc,MAAM;AAAA,MACpB,WAAW,CAAC,SAAS;AACpB,YAAI;AACJ,YAAI;AACH,mBAAS,KAAK,MAAM,YAAY,OAAO,KAAK,OAAO,CAAC,CAAC;AAAA,QACtD,SAAS,KAAK;AACb,iBAAO,eAAe,wBAAwB,UAAU,GAAG,CAAC,EAAE;AAAA,QAC/D;AAKA,YAAI,UAAU,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAC1E,iBAAO;AAAA,YACN,6CAA6C,KAAK,UAAU,MAAM,CAAC;AAAA,UACpE;AAAA,QACD;AACA,cAAM,MAAM;AACZ,eAAO;AAAA,UACN,GAAG,IAAI;AAAA,UACP,WAAW;AAAA,YACV;AAAA,YACA,SAAS,IAAI,WAAW;AAAA,YACxB,QAAQ,IAAI,UAAU;AAAA,YACtB,UAAU,IAAI;AAAA,UACf;AAAA,QACD;AAAA,MACD;AAAA,MACA,WAAW,CAAC,MAAM,QAAQ;AACzB,YAAI,SAAS,YAAY;AACxB,iBAAO,eAAe,yCAAyC;AAAA,QAChE;AACA,eAAO,eAAe,oBAAoB,UAAU,GAAG,CAAC,EAAE;AAAA,MAC3D;AAAA,IACD,CAAC;AAAA,EACF;AACD;AAYO,SAAS,mBACf,SACA,QACqB;AACrB,QAAM,WAAW;AAAA,IAChB;AAAA,IACA;AAAA,IACA,CAAC,KAAK,SAAS;AACd,YAAM,CAAC,WAAW,IAAI,IAAI;AAC1B,aAAO,IACL,QAAQ,iBAAiB,KAAK,UAAU,SAAS,CAAC,EAClD,QAAQ,YAAY,KAAK,UAAU,IAAI,CAAC;AAAA,IAC3C;AAAA,EACD;AACA,SAAO,CAAC,KAAK,SAAS;AACrB,UAAM,EAAE,MAAM,UAAU,IAAI,IAAI;AAChC,QAAI,aAAa,MAAM;AAQtB,aAAO;AAAA,QACN,GAAG,IAAI;AAAA,QACP,QAAQ;AAAA,UACP,UAAU;AAAA,UACV,UAAU,CAAC,qDAAqD;AAAA,UAChE,YAAY;AAAA,QACb;AAAA,MACD;AAAA,IACD;AACA,UAAM,WAAmC;AAAA,MACxC,EAAE,MAAM,QAAQ,SAAS,SAAS,CAAC,WAAW,IAAI,CAAC,EAAE;AAAA,IACtD;AAIA,UAAM,iBAAiB,CAAC,aAA2C;AAAA,MAClE,GAAG,IAAI;AAAA,MACP,QAAQ;AAAA,QACP,UAAU;AAAA,QACV,UAAU,CAAC,OAAO;AAAA,QAClB,YAAY;AAAA,MACb;AAAA,IACD;AACA,UAAM,YAAY,CAAC,QAA0B,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAK5F,WAAO,gBAAsC,SAAS,UAAU;AAAA,MAC/D,cAAc,MAAM;AAAA,MACpB,WAAW,CAAC,SAAS;AACpB,YAAI;AACJ,YAAI;AACH,mBAAS,KAAK,MAAM,YAAY,OAAO,KAAK,OAAO,CAAC,CAAC;AAAA,QACtD,SAAS,KAAK;AACb,iBAAO,eAAe,uBAAuB,UAAU,GAAG,CAAC,EAAE;AAAA,QAC9D;AACA,YAAI,UAAU,QAAQ,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAC1E,iBAAO;AAAA,YACN,4CAA4C,KAAK,UAAU,MAAM,CAAC;AAAA,UACnE;AAAA,QACD;AACA,cAAM,MAAM;AACZ,eAAO;AAAA,UACN,GAAG,IAAI;AAAA,UACP,QAAQ;AAAA,YACP,UAAU,IAAI,aAAa;AAAA,YAC3B,UAAU,IAAI,YAAY,CAAC;AAAA,YAC3B,YAAY,IAAI;AAAA,UACjB;AAAA,QACD;AAAA,MACD;AAAA,MACA,WAAW,CAAC,MAAM,QAAQ;AACzB,YAAI,SAAS,YAAY;AACxB,iBAAO,eAAe,0CAA0C;AAAA,QACjE;AACA,eAAO,eAAe,oBAAoB,UAAU,GAAG,CAAC,EAAE;AAAA,MAC3D;AAAA,IACD,CAAC;AAAA,EACF;AACD;AAcO,IAAM,eAAN,cAAwC,qBAAM;AAAA;AAAA,EAE3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA;AAAA,EAET,YACC,MACA,QACA,aACA,aACA,MACA,OACA,UACA,cACA,mBACA,SACA,gBACC;AACD,UAAM,IAAI;AACV,SAAK,SAAS;AACd,SAAK,cAAc;AACnB,SAAK,cAAc;AACnB,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,WAAW;AAChB,SAAK,eAAe;AACpB,SAAK,oBAAoB;AACzB,SAAK,UAAU;AACf,SAAK,iBAAiB;AAAA,EACvB;AAAA;AAAA,EAGA,IAAI,SAAiC;AACpC,WAAO,KAAK,OAAO,MAAkB,YAAY;AAAA,EAClD;AAAA;AAAA,EAGA,IAAI,gBAA6C;AAChD,WAAO,KAAK,OAAO,MAAuB,oBAAoB;AAAA,EAC/D;AAAA;AAAA,EAGA,IAAI,QAAiC;AACpC,WAAO,KAAK,OAAO,MAAmB,WAAW;AAAA,EAClD;AAAA;AAAA,EAGA,IAAI,WAAoC;AACvC,WAAO,KAAK,OAAO,MAAmB,cAAc;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,aAAyE;AACxE,UAAM,MAAM,KAAK;AACjB,UAAM,iBAAiB,CAAC,SACvB,IAAI,IAAI,IAAI,IAAI,WAAW,IAAI,aAAa;AAC7C,UAAM,YAAY,CAAI,UACrB,SAAS,OAAO,CAAC,IAAI,CAAC,KAAK;AAE5B,UAAM,aAAa,YAAY,QAAQ,CAAC,MAAM,UAAU,eAAe,CAAC,CAAC,CAAC;AAC1E,UAAM,YAAsB,CAAC;AAC7B,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO;AACjC,gBAAU,KAAK,UAAU,KAAK,OAAO;AAAA,IACtC;AACA,WAAO;AAAA,MACN,EAAE,OAAO,UAAU,OAAO,UAAU,eAAe,QAAQ,CAAC,EAAE;AAAA,MAC9D,EAAE,OAAO,UAAU,OAAO,CAAC,QAAQ,EAAE;AAAA,MACrC,EAAE,OAAO,SAAS,OAAO,WAAW;AAAA,MACpC,EAAE,OAAO,QAAQ,OAAO,UAAU;AAAA,MAClC,EAAE,OAAO,WAAW,OAAO,CAAC,8BAA8B,EAAE;AAAA,MAC5D,EAAE,OAAO,UAAU,OAAO,CAAC,6BAA6B,EAAE;AAAA,MAC1D,EAAE,OAAO,WAAW,OAAO,CAAC,SAAS,EAAE;AAAA,MACvC,EAAE,OAAO,YAAY,OAAO,CAAC,mBAAmB,EAAE;AAAA,IACnD;AAAA,EACD;AACD;AAsBO,SAAS,YACf,MACA,MACkB;AAClB,QAAM,UAAU,KAAK;AACrB,QAAM,aAAa,KAAK,cAAc;AACtC,QAAM,gBAAgB,KAAK,iBAAiB;AAC5C,QAAM,kBAAmC,KAAK,mBAAmB;AAEjE,QAAM,eAAe,oBAAI,IAA6B;AACtD,aAAW,SAAS,aAAa;AAChC,iBAAa,IAAI,OAAO;AAAA,MACvB,GAAG,sBAAsB,KAAK;AAAA,MAC9B,GAAG,KAAK,SAAS,KAAK;AAAA,IACvB,CAAC;AAAA,EACF;AAGA,QAAM,YAAY,aAAa,GAAG,IAAI,WAAW;AAAA,IAChD,qBAAqB,EAAE,cAAc;AAAA,EACtC,CAAC;AAKD,QAAM,SAAS,UAAU,MAAkB,YAAY;AACvD,QAAM,eAAe,UAAU,MAAmB,mBAAmB;AACrE,QAAM,aAAa,UAAU,MAAmB,WAAW;AAC3D,QAAM,gBAAgB,UAAU,MAAuB,oBAAoB;AAC3E,QAAM,cAAc,oBAAI,IAAyC;AACjE,aAAW,SAAS,aAAa;AAChC,gBAAY,IAAI,OAAO,UAAU,MAAmB,KAAK,CAAC;AAAA,EAC3D;AACA,QAAM,gBAAgB,UAAU,MAAmB,cAAc;AAGjE,QAAM,WAAW,cAAc;AAO/B,QAAM,kBAAc;AAAA,IACnB,OAAO;AAAA,IACP,SAAS;AAAA,EACV;AAEA,QAAM,iBAAiB;AAAA,IACtB,KAAK;AAAA,IACL;AAAA,IACA,CAAC,KAAK,SAAS;AACd,YAAM,CAAC,MAAM,KAAK,IAAI;AACtB,aAAO,IACL,QAAQ,gBAAgB,KAAK,UAAU,MAAM,KAAK,MAAM,QAAQ,CAAC,CAAC,CAAC,EACnE,QAAQ,YAAY,KAAK,UAAU,IAAI,CAAC;AAAA,IAC3C;AAAA,EACD;AAEA,QAAM,aAAa;AAAA,IAClB;AAAA,IACA,CAAC,WAA4B;AAAA,IAC7B,CAAC,SAAkB;AAMlB,YAAM,SAAS;AACf,UAAI,WAAW,OAAW,QAAO;AACjC,aAAO,eAAe,MAAM;AAAA,IAC7B;AAAA,IACA;AAAA,MACC,MAAM;AAAA,MACN,QAAQ;AAAA,IACT;AAAA,EACD;AAQA,QAAM,kBAAc,+BAAe,YAA6B,WAA4B;AAC5F,QAAM,aAAS;AAAA,IACd,CAAC,WAA4B;AAAA,IAC7B,CAAC,WAAW,UAAU,QAAQ;AAC7B,YAAM,OAAO,UAAU;AAAA,QAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,MAClE;AACA,YAAM,OAAO,KAAK,CAAC;AACnB,UAAI,QAAQ,KAAM;AAClB,YAAM,CAAC,gBAAgB,UAAU,IAAI;AAIrC,UAAI,CAAC,gBAAgB,MAAO;AAC5B,YAAM,aAAa,aAAa,CAAC;AAMjC,YAAM,SAAsB,EAAE,GAAG,gBAAgB,GAAG,WAAW;AAC/D,mBAAa,QAAQ,MAAM;AAAA,IAC5B;AAAA,IACA,EAAE,cAAc,SAAS;AAAA,EAC1B;AACA,QAAM,cAAc,OAAO,UAAU,MAAM;AAAA,EAAC,CAAC;AAG7C,QAAM,cAAc,IAAI,IAAY,WAAW;AAC/C,aAAW,SAAS,aAAa;AAChC,gBAAyB,UAAU,KAAK,IAAI,cAAc,YAAY,IAAI,KAAK,GAAI;AAAA,MAClF,KAAK,CAAC,SAAU,KAAK,UAAU,QAAQ,OAAO;AAAA,IAC/C,CAAC;AAAA,EACF;AACA,cAAyB,qBAAqB,cAAc,eAAe;AAAA,IAC1E,KAAK,CAAC,SAAU,YAAY,IAAI,KAAK,KAAK,IAAI,SAAY;AAAA,EAC3D,CAAC;AA0BD,QAAM,YAAY,oBAAI,IAA4C;AAClE,QAAM,cAAc,oBAAI,IAA+C;AACvE,aAAW,SAAS,aAAa;AAChC,cAAU,IAAI,OAAO,SAAsB,QAAQ,KAAK,EAAE,CAAC;AAAA,EAC5D;AACA,QAAM,kBAAqC,CAAC;AAC5C,aAAW,SAAS,aAAa;AAChC,UAAMC,SAAQ,YAAY,IAAI,KAAK;AACnC,UAAM,KAAK,UAAU,IAAI,KAAK;AAC9B,UAAM,OAAO,oBAAI,QAAgB;AACjC,UAAM,aAAS;AAAA,MACd,CAACA,OAAM,MAAuB;AAAA,MAC9B,CAAC,WAAW,UAAU,QAAQ;AAC7B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACD,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,SAAS,KAAK,CAAC;AACrB,cAAM,MAAO,UAAU,CAAC;AACxB,mBAAW,QAAQ,KAAK;AACvB,cAAI,KAAK,IAAI,IAAyB,EAAG;AACzC,eAAK,IAAI,IAAyB;AAClC,gBAAM,KAAK,GAAG,QAAQ,IAAI;AAC1B,sBAAY,IAAI,YAAY,IAAI,GAAG,EAAE,OAAO,GAAG,CAAC;AAAA,QACjD;AAAA,MACD;AAAA,MACA,EAAE,MAAM,QAAQ,KAAK,WAAW,cAAc,SAAS;AAAA,IACxD;AACA,oBAAgB,KAAK,OAAO,UAAU,MAAM;AAAA,IAAC,CAAC,CAAC;AAAA,EAChD;AAEA,WAAS,OAAO,MAAyB;AACxC,UAAM,MAAM,YAAY,IAAI;AAC5B,UAAM,QAAQ,YAAY,IAAI,GAAG;AACjC,QAAI,CAAC,MAAO;AACZ,cAAU,IAAI,MAAM,KAAK,GAAG,WAAW,MAAM,EAAE;AAC/C,gBAAY,OAAO,GAAG;AAAA,EACvB;AAQA,QAAM,YAAY,cAAc,OAAO;AACvC,QAAM,kBAAkB,oBAAI,IAA6C;AACzE,aAAW,SAAS,aAAa;AAChC,UAAM,SAAS,aAAa,IAAI,KAAK;AACrC,QAAI,CAAC,OAAO,MAAO;AACnB,UAAMC,SAAQ,YAAY,IAAI,KAAK;AACnC,UAAM,OAAO,UAAU;AAAA,MACtB,GAAG,KAAK;AAAA,MACRA,OAAM;AAAA,MACN;AAAA,QACC,YAAY,OAAO;AAAA,QACnB,WAAW,OAAO;AAAA,MACnB;AAAA,IACD;AACA,oBAAgB,IAAI,OAAO,IAAI;AAAA,EAChC;AAKA,QAAM,eAAoC,CAAC;AAC3C,aAAW,SAAS,aAAa;AAChC,UAAM,SAAS,aAAa,IAAI,KAAK;AACrC,QAAI,OAAO,SAAS,gBAAgB,IAAI,KAAK,GAAG;AAC/C,mBAAa,KAAK,gBAAgB,IAAI,KAAK,EAAG,MAA2B;AAAA,IAC1E,OAAO;AACN,mBAAa,KAAK,YAAY,IAAI,KAAK,EAAG,MAAM;AAAA,IACjD;AAAA,EACD;AACA,eAAa,KAAK,WAAW,MAAM;AAEnC,QAAM,mBAAe,sBAAmB,GAAG,YAAY;AAGvD,QAAM,WACL,KAAK,YAAY,mBAAsB,SAAuB,KAAK,aAAa;AACjF,QAAM,WACL,KAAK,YAAY,mBAAsB,SAAuB,KAAK,YAAY;AAQhF,QAAM,oBAAoB,KAAK,qBAAqB,OAAO;AAC3D,QAAM,mBAAmB,KAAK,oBAAoB,OAAO;AAEzD,QAAM,cAAc,QAA8B,GAAG,IAAI,gBAAgB;AAAA,IACxE,QAAQ;AAAA,MACP,EAAE,MAAM,WAAW,MAAM,CAAC,QAAQ,SAAS,GAAG,GAAG,YAAY,kBAAkB;AAAA,MAC/E,EAAE,MAAM,UAAU,MAAM,CAAC,QAAQ,SAAS,GAAG,GAAG,YAAY,iBAAiB;AAAA,IAC9E;AAAA,EACD,CAAC;AAMD,QAAM,oBAAgB;AAAA,IACrB,CAAC,YAA6B;AAAA,IAC9B,CAAC,WAAW,UAAU,QAAQ;AAC7B,YAAM,OAAO,UAAU;AAAA,QAAI,CAACD,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,MAClE;AACA,YAAM,OAAO,KAAK,CAAC;AACnB,UAAI,SAAS,OAAW;AACxB,kBAAY,QAAQ,EAAE,KAA0B,CAAC;AAAA,IAClD;AAAA,IACA,EAAE,MAAM,mBAAmB,cAAc,SAAS;AAAA,EACnD;AACA,QAAM,eAAe,cAAc,UAAU,MAAM;AAAA,EAAC,CAAC;AAiBrD,QAAM,kBAAkB,KAAK,mBAAmB;AAChD,QAAM,kBAAkB,KAAK,IAAI,KAAK,mBAAmB,aAAa,IAAI,GAAG;AAC7E,QAAM,uBAAuB,KAAK,IAAI,KAAK,wBAAwB,kBAAkB,IAAI,GAAG;AAC5F,QAAM,mBAAe,oBAAK,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC;AAC5C,QAAM,wBAAoB,oBAAK,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC;AAEjD,WAAS,eACR,WACA,QACA,MACkB;AAClB,WAAO;AAAA,MACN;AAAA,MACA;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO,YAAY,CAAC;AAAA,MAC9B,YAAY,OAAO;AAAA,IACpB;AAAA,EACD;AAEA,WAAS,eAAe,IAAqB,MAAyB;AACrE,aAAS,OAAO,YAAY,mBAAmB,KAAK,WAAW,KAAK,YAAY,GAAG,MAAM;AAAA,MACxF,UAAU;AAAA,MACV,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,IACpB,CAAC;AACD,kBAAc,QAAQ,EAAE;AACxB,WAAO,IAAI;AAAA,EACZ;AAEA,WAAS,YAAY,IAAqB,MAAyB;AAClE,UAAM,MAAM,YAAY,IAAI;AAC5B,UAAM,cAAc,KAAK,YAAY;AACrC,UAAM,YAAyB;AAAA,MAC9B,GAAG;AAAA,MACH,UAAU,cAAc;AAAA,MACxB,SAAS,UAAU,cAAc,CAAC,IAAI,UAAU,KAAK,GAAG,oCAA+B,GAAG,SAAS,KAAK,IAAI,CAAC;AAAA,MAC7G,WAAW,CAAC,GAAG;AAAA,IAChB;AACA,eAAW,QAAQ,SAAS;AAAA,EAG7B;AAEA,WAAS,iBAAiB,IAAqB,MAAyB;AACvE,aAAS,OAAO,YAAY,mBAAmB,KAAK,WAAW,KAAK,YAAY,GAAG,OAAO;AAAA,MACzF,UAAU;AAAA,MACV,WAAW,KAAK;AAAA,MAChB,cAAc,KAAK;AAAA,IACpB,CAAC;AACD,kBAAc,QAAQ,EAAE;AACxB,WAAO,IAAI;AACX,UAAM,MAAM,YAAY,IAAI;AAC5B,UAAM,mBAAmB,KAAK,iBAAiB;AAC/C,QACC,mBAAmB,mBACnB,oBAAoB,mBAAmB,oBAAoB,GAC1D;AACD,aAAO,QAAQ;AAAA,QACd,QAAQ,KAAK;AAAA,QACb,SAAS,4BAA4B,GAAG;AAAA,QACxC,UAAU,GAAG,SAAS,KAAK,IAAI;AAAA,QAC/B,cAAc,KAAK;AAAA,QACnB,kBAAkB,KAAK;AAAA,QACvB,UAAU,KAAK,YAAY;AAAA,QAC3B,WAAW,CAAC,GAAG;AAAA,QACf,eAAe,mBAAmB;AAAA,MACnC,CAAC;AAAA,IACF;AAAA,EACD;AAUA,MAAI,iBAAiB;AACrB,QAAM,qBAAiB;AAAA,IACtB,CAAC,YAAY,SAA0B;AAAA,IACvC,CAAC,WAAW,UAAU,QAAQ;AAC7B,YAAM,OAAO,UAAU;AAAA,QAAI,CAACA,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,MAClE;AACA,YAAM,MAAM,KAAK,CAAC;AAClB,YAAM,MAAO,OAAO,CAAC;AAIrB,UAAI,iBAAiB,IAAI,OAAQ,kBAAiB,IAAI;AACtD,YAAM,QAAQ;AACd,uBAAiB,IAAI;AACrB,eAAS,IAAI,OAAO,IAAI,IAAI,QAAQ,KAAK;AACxC,cAAM,MAAM,IAAI,CAAC;AACjB,cAAM,EAAE,MAAM,WAAW,OAAO,IAAI,IAAI;AAIxC,YAAI,aAAa,QAAQ,UAAU,MAAM;AACxC,iBAAO,IAAI;AACX;AAAA,QACD;AACA,cAAM,KAAK,eAAe,WAAW,QAAQ,IAAI;AACjD,YAAI,GAAG,UAAU;AAChB,yBAAe,IAAI,IAAI;AACvB;AAAA,QACD;AACA,cAAM,WACL,GAAG,cACH,gBAAgB;AAAA,UACf;AAAA,UACA,SAAS,UAAU;AAAA,UACnB,QAAQ,GAAG,SAAS,KAAK,IAAI;AAAA,QAC9B,CAAC;AACF,cAAM,cAAc,KAAK,YAAY;AACrC,YACC,aAAa,sBACb,cAAc,cACd,oBAAoB,cAAc,eAAe,GAChD;AACD,sBAAY,IAAI,IAAI;AAAA,QACrB,OAAO;AACN,2BAAiB,IAAI,IAAI;AAAA,QAC1B;AAAA,MACD;AAAA,IACD;AAAA,IACA,EAAE,MAAM,mBAAmB,cAAc,SAAS;AAAA,EACnD;AACA,QAAM,gBAAgB,eAAe,UAAU,MAAM;AAAA,EAAC,CAAC;AAQvD,QAAM,kBAAc;AAAA,IACnB,CAAC,YAAY,SAA0B;AAAA,IACvC,CAAC,YAAY,YAAY;AACxB,cAAQ,KAAK,IAAI;AAAA,IAClB;AAAA,IACA;AAAA,MACC,MAAM;AAAA,MACN,QAAQ,MAAM;AAAA,IACf;AAAA,EACD;AAGA,MAAI;AACJ,MAAI,KAAK,UAAU;AAClB,qBAAiB,oBAAoB,aAAa,UAAU,IAAI;AAAA,EACjE;AAGA,QAAM,UAAU,IAAI;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAGA,UAAQ,YAAY,WAAW;AAC/B,UAAQ,YAAY,YAAY;AAChC,UAAQ,YAAY,aAAa;AAIjC,aAAW,SAAS,gBAAiB,SAAQ,YAAY,KAAK;AAM9D,UAAQ,IAAI,aAA8B,EAAE,MAAM,eAAe,CAAC;AAClE,UAAQ,IAAI,YAA6B,EAAE,MAAM,SAAS,CAAC;AAC3D,UAAQ,IAAI,aAA8B,EAAE,MAAM,eAAe,CAAC;AAClE,UAAQ,IAAI,cAA+B,EAAE,MAAM,gBAAgB,CAAC;AACpE,UAAQ,IAAI,eAAgC,EAAE,MAAM,kBAAkB,CAAC;AACvE,UAAQ,IAAI,gBAAiC,EAAE,MAAM,kBAAkB,CAAC;AACxE,UAAQ,IAAI,aAA8B,EAAE,MAAM,UAAU,CAAC;AAI7D,UAAQ,YAAY,YAAY,UAAU,MAAM,MAAS,CAAC;AAC1D,MAAI,gBAAgB;AACnB,eAAW,CAAC,OAAO,KAAK,KAAK,gBAAgB;AAC5C,cAAQ,IAAI,OAAwB,EAAE,MAAM,YAAY,KAAK,GAAG,CAAC;AACjE,cAAQ,YAAY,MAAM,UAAU,MAAM;AAAA,MAAC,CAAC,CAAC;AAAA,IAC9C;AAAA,EACD;AAGA,UAAQ,MAAM,UAAU,SAAS;AACjC,UAAQ,MAAM,SAAS,SAAS;AAChC,UAAQ,MAAM,eAAe,WAAW;AACxC,UAAQ,MAAM,YAAY,QAAQ;AAClC,aAAW,CAAC,OAAO,EAAE,KAAK,WAAW;AACpC,YAAQ,MAAM,QAAQ,KAAK,IAAI,EAAE;AAAA,EAClC;AAIA,UAAQ,WAAW,mBAAe,+BAAgB,IAA0C,CAAC;AAE7F,SAAO;AACR;AAMA,SAAS,oBACR,aACA,UACA,MACgC;AAChC,MAAI,CAAC,KAAK,mBAAmB;AAC5B,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,QAAM,oBAAoB,KAAK;AAC/B,QAAM,UAAU,KAAK,YAAY,CAAC;AAClC,QAAM,kBAAkB;AAAA,IACvB,GAAG;AAAA,IACH,GAAG,QAAQ;AAAA,EACZ;AACA,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,yBAAyB,QAAQ,0BAA0B;AACjE,QAAM,qBAAqB,QAAQ,sBAAsB;AAEzD,QAAM,SAAS,oBAAI,IAA8B;AACjD,aAAW,CAAC,OAAOC,MAAK,KAAK,aAAa;AACzC,UAAM,YAAQ;AAAA,MACb;AAAA,QACCA,OAAM;AAAA,QACN,SAAS;AAAA,QACT;AAAA,MACD;AAAA,MACA,CAAC,WAAW,SAAS,QAAQ;AAC5B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACD,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,cAAM,OAAO,KAAK,CAAC;AACnB,YAAI,SAAS,QAAW;AACvB,kBAAQ,KAAK,CAAC;AACd;AAAA,QACD;AACA,cAAM,aAAa,gBAAgB,KAAK,YAAY,QAAQ,KAAK;AACjE,cAAM,kBAAc,2BAAY,IAAK,KAAK,CAAC,KAAgB;AAC3D,YAAI,IAAI,aAAa,KAAK,IAAI,CAAC,YAAY,KAAK,IAAI,GAAG,UAAU,CAAC;AAClE,cAAM,MAAM,YAAY,mBAAmB,KAAK,WAAW,KAAK,YAAY;AAC5E,cAAM,QAAQ,KAAK,CAAC;AACpB,cAAM,QAAQ,OAAO,IAAI,GAAG;AAC5B,YAAI,SAAS,MAAM,eAAe,wBAAwB;AACzD,eAAK;AAAA,QACN;AACA,gBAAQ,KAAK,CAAC;AAAA,MACf;AAAA,MACA,EAAE,MAAM,YAAY,KAAK,IAAI,cAAc,UAAU;AAAA,IACtD;AACA,WAAO,IAAI,OAAO,KAAK;AAAA,EACxB;AACA,SAAO;AACR;;;Aeh9BA,IAAAE,gBAAuE;AAEvE,IAAAC,iBAAwB;AACxB,IAAAC,iBAAsB;AAItB,IAAM,aAAa,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,EAAE;AAyDhD,IAAM,cAA8B;AAAA,EACnC,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS,CAAC;AAAA,EACV,cAAc;AACf;AAmBO,IAAM,2BAAN,cAAuC,qBAAM;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEQ;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA;AAAA,EAEjB,YAAY,MAAc,MAAkC;AAC3D,UAAM,IAAI;AACV,SAAK,SAAS,KAAK,IAAI,GAAG,KAAK,GAAG,IAAI;AACtC,SAAK,cAAc,KAAK;AACxB,SAAK,gBAAgB,KAAK,aAAa;AAEvC,SAAK,QAAQ,MAAuB,GAAG,IAAI,eAAe;AAAA,MACzD,eAAe,KAAK,iBAAiB;AAAA,IACtC,CAAC;AAKD,SAAK,YAAY,MAAM;AACtB,WAAK,MAAM,QAAQ;AAAA,IACpB,CAAC;AAMD,UAAM,OAAwB,CAAC,KAAK,MAAM,MAAuB;AACjE,UAAM,eAAe,KAAK,aAAa,OAAO,KAAK,SAAK,wBAAQ,KAAK,SAAS,CAAC,IAAI,IAAI;AACvF,QAAI,KAAK,SAAS,KAAM,MAAK,SAAK,wBAAQ,KAAK,KAAK,CAAkB;AAEtE,SAAK,UAAU,KAAK;AAAA,MACnB;AAAA,MACA;AAAA,MACA,CAAC,WAAW,QAAQ;AAKnB,cAAM,YAAQ,2BAAY;AAI1B,cAAM,eACL,gBAAgB,MACf,MAAM;AACN,gBAAM,KAAK,UAAU,YAAY;AACjC,iBAAO,MAAM,QAAQ,GAAG,SAAS;AAAA,QAClC,GAAG;AASJ,cAAM,YAAY,UAAU,CAAC;AAI7B,cAAM,MACL,aAAa,QAAQ,UAAU,SAAS,IACrC,UAAU,UAAU,SAAS,CAAC,IAC7B,IAAI,SAAS,CAAC;AAEnB,YAAI,SAA6B;AACjC,YAAI,OAAO,MAAM;AAChB,qBAAW,MAAM,KAAK;AACrB,gBAAI,IAAI,UAAU,KAAM;AACxB,qBAAS,YAAY,QAAQ,IAAI,KAAK,WAAW;AAAA,UAClD;AAAA,QACD;AAOA,cAAM,YAAa,IAAI,SAAS;AAEhC,YAAI,aAAiC;AACrC,YAAI,eAA8B;AAElC,YAAI,UAAU,QAAQ,KAAK,SAAS,GAAG;AAMtC,gBAAM,UACL,WAAW,gBAAgB,QAAQ,UAAU,gBAAgB,OAAO,UACjE,UAAU,eACV,OAAO;AAOX,gBAAM,SAAS,QAAQ,WAAW,KAAK;AACvC,cAAI,QAAQ;AACX,yBAAa;AACb,2BAAe;AAAA,UAChB,WAAW,cAAc;AACxB,2BAAe;AAAA,UAChB,OAAO;AACN,2BAAe;AAAA,UAChB;AAAA,QACD,WAAW,UAAU,MAAM;AAG1B,gBAAM,UACL,WAAW,gBAAgB,QAAQ,UAAU,gBAAgB,OAAO,UACjE,UAAU,eACV,OAAO;AACX,yBAAe,eAAe,QAAQ;AAAA,QACvC;AAEA,eAAO;AAAA,UACN,cAAc,OACX,cACA;AAAA,YACA,OAAO,WAAW;AAAA,YAClB,OAAO,WAAW;AAAA,YAClB,SAAS,CAAC,WAAW,KAAK;AAAA,YAC1B;AAAA,UACD;AAAA,QACH;AAAA,MACD;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACnB;AAEA,SAAK,UAAU,KAAK;AAAA,MACnB;AAAA,MACA,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,WAAW,QAAQ;AACnB,cAAMC,UAAQ,UAAU,CAAC;AACzB,cAAM,IAAKA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAMA,QAAM,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC;AAGvF,eAAO,CAAC,GAAG,WAAW,CAAC,CAAC;AAAA,MACzB;AAAA,MACA,EAAE,WAAW,KAAK;AAAA,IACnB;AAQA,SAAK,YAAQ,8BAAe,KAAK,OAAO;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAe,OAA8B;AAGlD,UAAM,MAAM,UAAU,KAAK,gBAAgB,OAAO;AAClD,SAAK,MAAM,QAAQ,WAAW,EAAE,MAAM,SAAS,YAAY,KAAK,MAAM,OAAO,OAAO,IAAI,CAAC,CAAC;AAAA,EAC3F;AAAA;AAAA,EAGA,QAAQ,OAAqB;AAC5B,SAAK,MAAM,QAAQ,WAAW,EAAE,MAAM,WAAW,YAAY,KAAK,MAAM,MAAM,CAAC,CAAC;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS,OAAe,eAAuB,QAAsB;AACpE,SAAK,MAAM;AAAA,MACV,WAAW,EAAE,MAAM,YAAY,YAAY,KAAK,MAAM,OAAO,eAAe,OAAO,CAAC;AAAA,IACrF;AAAA,EACD;AACD;AAGA,SAAS,WAAW,SAAkD;AAIrE,QAAM,QAAI,2BAAY;AACtB,SAAO,EAAE,WAAW,aAAa,SAAS,GAAG,MAAM,GAAG,WAAW,aAAa,QAAQ,QAAQ;AAC/F;AAaA,SAAS,YACR,QACA,IACA,YACqB;AACrB,QAAM,IAAI,GAAG;AAMb,MAAI,EAAE,SAAS,SAAS;AACvB,QAAI,UAAU,QAAQ,WAAW,OAAO,KAAK,IAAI,WAAW,EAAE,KAAK,EAAG,QAAO;AAC7E,WAAO,EAAE,OAAO,EAAE,OAAO,OAAO,EAAE,OAAO,SAAS,GAAG,KAAK;AAAA,EAC3D;AACA,MAAI,EAAE,SAAS,WAAW;AACzB,QAAI,UAAU,QAAQ,OAAO,UAAU,EAAE,MAAO,QAAO;AACvD,WAAO;AAAA,EACR;AAOA,QAAM,eAAe,cAAc,QAAQ,EAAE,UAAU;AACvD,MAAI,cAAc;AACjB,WAAO,EAAE,OAAO,EAAE,OAAO,OAAO,MAAM,SAAS,GAAG,KAAK;AAAA,EACxD;AACA,SAAO;AACR;AAcO,SAAS,oBACf,MACA,MAC2B;AAC3B,SAAO,IAAI,yBAAyB,MAAM,IAAI;AAC/C;;;AClYA,IAAAC,iBAIO;AAuCA,SAAS,eACf,SACA,MACuB;AACvB,QAAM,WAAO,6BAAa,SAAS,IAAI;AAKvC,QAAM,cAAsC,CAAC;AAC7C,aAAW,SAAS,aAAa;AAChC,UAAM,IAAI,QAAQ,OAAO,IAAI,KAAK,IAAI,QAAQ,OAAO,MAAmB,KAAK,IAAI;AACjF,gBAAY,KAAK,IAAI,GAAG,SAAS,EAAE,UAAU;AAAA,EAC9C;AAEA,SAAO;AAAA,IACN,GAAG;AAAA,IACH;AAAA,IACA,iBAAiB,QAAQ,SAAS,QAAQ,OAAO,QAAQ;AAAA,IACzD,cAAc,QAAQ,aAAa,SAAS;AAAA,IAC5C,mBAAmB,QAAQ,kBAAkB,SAAS;AAAA,EACvD;AACD;;;ACtCA,IAAAC,gBAA0D;AAC1D,IAAAC,iBAA0B;AAC1B,IAAAC,iBAAsB;;;ACnBtB,IAAAC,iBAAoD;;;ACEpD,IAAAC,gBAAmE;AACnE,IAAAC,iBAA0B;AAC1B,IAAAC,iBAAyC;;;ACjBzC,IAAAC,gBAUO;AACP,IAAAC,iBAA8C;AAC9C,IAAAC,iBAAyC;AAyFlC,IAAM,iBAAN,cAA6B,qBAAM;AAAA,EAChC;AAAA,EACA;AAAA;AAAA,EAGA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAEQ;AAAA,EACA;AAAA;AAAA,EAET,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQX,0BAAkD;AAAA,EAE1D,YAAY,MAAc,MAAwB;AACjD,UAAM,MAAM,KAAK,KAAK;AAGtB,SAAK,OAAO,WAAW,GAAG,IAAI,SAAS,EAAE,aAAa,KAAK,YAAY,CAAC;AACxE,SAAK,MAAM,QAAQ,KAAK,IAAI;AAG5B,SAAK,QAAQ,aAAa,GAAG,IAAI,QAAQ;AACzC,SAAK,MAAM,SAAS,KAAK,KAAK;AAE9B,QAAI,KAAK,OAAO;AACf,iBAAW,QAAQ,KAAK,OAAO;AAC9B,aAAK,MAAM,SAAS,IAAI;AAAA,MACzB;AAAA,IACD;AAGA,SAAK,aAAS,oBAAsB,CAAC,GAAG;AAAA,MACvC,GAAG;AAAA,QACF,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,cAAc;AAAA,MAC5B;AAAA,MACA,SAAS;AAAA,IACV,CAAC;AACD,SAAK,IAAI,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,SAAK,WAAO,oBAAa,CAAC,GAAG;AAAA,MAC5B,GAAG;AAAA,QACF,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,kBAAkB;AAAA,MAChC;AAAA,MACA,SAAS;AAAA,IACV,CAAC;AACD,SAAK,IAAI,KAAK,MAAM,EAAE,MAAM,OAAO,CAAC;AAEpC,SAAK,cAAU,oBAAc,CAAC,GAAG;AAAA,MAChC,GAAG;AAAA,QACF,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,eAAe;AAAA,MAC7B;AAAA,MACA,SAAS;AAAA,IACV,CAAC;AACD,SAAK,IAAI,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAqC1C,QAAI,aAAa;AACjB,UAAM,UAAU,KAAK,KAAK,UAAU,CAAC,SAAS;AAC7C,iBAAW,KAAK,KAAM,KAAI,EAAE,CAAC,MAAM,mBAAM,cAAa,EAAE,CAAC;AAAA,IAC1D,CAAC;AACD,QAAI,gBAAgB;AACpB,UAAM,aAAa,KAAK,QAAQ,UAAU,CAAC,SAAS;AACnD,iBAAW,KAAK,KAAM,KAAI,EAAE,CAAC,MAAM,mBAAM,iBAAgB,EAAE,CAAC;AAAA,IAC7D,CAAC;AAED,UAAM,UAAU,KAAK;AACrB,UAAM,eAAe,KAAK;AAC1B,UAAM,QAAQ,KAAK;AACnB,UAAM,cAAc,KAAK;AACzB,UAAM,YAAY,KAAK;AACvB,UAAM,WAAW,KAAK,YAAY;AAClC,UAAM,WAAW,KAAK;AAGtB,UAAM,OAAO,KAAK;AAClB,UAAM,QAAQ,KAAK;AACnB,UAAM,aAAa,KAAK;AACxB,UAAM,WAAW,KAAK;AACtB,UAAM,cAAc,KAAK;AAWzB,UAAM,kBAAiC,cAAAC;AAAA,MACtC,CAAC,UAAU;AAAA,MACX,CAAC,MAAM,SAAS,QAAQ;AACvB,cAAM,OAAO,WAA4B,MAAM,IAAI,UAAU,GAAG,MAAM;AACtE,YAAI,SAAS,cAAc,iBAAiB,cAAc,UAAU;AACnE,kBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AAaA,cAAM,WAAY,KAAK,KAAK,SAAS,SAAgD,CAAC;AACtF,YAAI,SAAS,WAAW,GAAG;AAC1B,kBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,cAAM,UAAW,KAAK,MAAM,QAAQ,SAAmD,CAAC;AACxF,gBAAQ,KAAK,EAAE,UAAU,OAAO,QAAQ,CAAC;AAAA,MAC1C;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAQlC,cAAc,CAAC,WAAW,QAAQ,iBAAiB,eAAe;AAAA,QACnE,CAAC;AAAA,MACF;AAAA,IACD;AAEA,UAAM,kBAAiC;AAAA,MACtC;AAAA,MACA,CAAC,UAAU;AACV,cAAM,aAAa,IAAI,gBAAgB;AACvC,aAAK,0BAA0B;AAC/B,YAAI,eAAe;AAClB,qBAAW,MAAM,IAAI,MAAM,oBAAoB,CAAC;AAAA,QACjD;AAOA,mBAAO;AAAA,UACN,QAAQ,OAAO,MAAM,UAAU;AAAA,YAC9B,OAAO,MAAM,MAAM,SAAS,IAAI,MAAM,QAAQ;AAAA,YAC9C;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ,WAAW;AAAA,UACpB,CAAC;AAAA,UACD,EAAE,QAAQ,WAAW,OAAO;AAAA,QAC7B;AAAA,MACD;AAAA,MACA,EAAE,QAAQ,MAAM,MAAM;AAAA,IACvB;AA6CA,UAAM,wBAAoB,oBAAkB,CAAC,GAAG;AAAA,MAC/C,MAAM;AAAA,MACN,cAAc;AAAA,MACd,MAAM,OAAO,qBAAqB;AAAA,IACnC,CAAC;AACD,SAAK,eAAe;AAcpB,UAAM,mBAAe,cAAAA;AAAA,MACpB,CAAC,mBAAmB,UAAU;AAAA,MAC9B,CAAC,MAAM,SAAS,QAAQ;AAMvB,cAAM,OAAO,WAAoC,MAAM,IAAI,UAAU,GAAG,MAAS;AACjF,cAAM,OAAO,WAA4B,MAAM,IAAI,UAAU,GAAG,MAAM;AACtE,YAAI,SAAS,UAAU;AACtB,kBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,cAAM,QAAQ,MAAM;AACpB,YAAI,SAAS,QAAQ,MAAM,WAAW,GAAG;AACxC,kBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACzB;AAAA,QACD;AACA,gBAAQ,KAAK,KAAK;AAAA,MACnB;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,sBAAsB;AAAA,MACpC;AAAA,IACD;AAKA,UAAM,qBAAqB,KAAK,qBAC7B,KAAK,mBAAmB,YAAY,IACpC;AACH,SAAK,YAAY;AAOjB,UAAM,kBAA+C,cAAc;AAAA,MAClE,WAAW;AAAA,MACX;AAAA,MACA,YAAY;AAAA,IACb,CAAC;AACD,SAAK,cAAc;AA+BnB,UAAM,kBAAc;AAAA,MACnB,CAAC,WAAW;AAAA,MACZ,CAAC,WAAW,UAAU,QAAQ;AAC7B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACC,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,YAAI,cAAe;AACnB,cAAM,WAAW,KAAK,CAAC;AACvB,cAAM,OAAO,aAAa;AAC1B,cAAM,eAAe,SAAS,aAAa,QAAQ,SAAS,UAAU,SAAS;AAC/E,cAAM,cACL,SAAS,iBAAiB,eACzB,CAAC,SAAS,aAAa,SAAS,UAAU,WAAW;AACvD,cAAM,aAAa,WAAW,QAAQ,MAAM;AAC5C,cAAM,aAAa,QAAQ;AAC3B,cAAM,aACL,cAAc,eAAe,CAAC,gBAAgB,aAAa,SAAS;AACrE,iCAAM,MAAM;AACX,4BAAkB,KAAK,QAAQ;AAC/B,qBAAW,KAAK,UAAU;AAC1B,mBAAS,KAAK,IAAI;AAClB,eAAK,OAAO,aAAa,SAAS,SAAS;AAAA,YAC1C,WAAW,SAAS;AAAA,UACrB,CAAC;AAAA,QACF,CAAC;AAAA,MACF;AAAA,MACA,EAAE,cAAc,SAAS;AAAA,IAC1B;AAKA,UAAM,iBAAa;AAAA,MAClB,CAAC,eAAe;AAAA,MAChB,CAAC,WAAW,UAAU,QAAQ;AAC7B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACA,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,YAAI,cAAe;AACnB,cAAM,MAAM,KAAK,CAAC;AAClB,YAAI,IAAI,WAAW,EAAG;AACtB,cAAM,aAA8B,cAAc,WAAW,SAAS;AACtE,iCAAM,MAAM;AACX,qBAAW,KAAK,UAAU;AAC1B,qBAAW,KAAK,IAAK,MAAK,iBAAiB,EAAE,IAAI,EAAE,OAAO;AAAA,QAC3D,CAAC;AAAA,MACF;AAAA,MACA,EAAE,cAAc,SAAS;AAAA,IAC1B;AAgBA,QAAI,eAAiC,WAAW,SAAyC;AACzF,UAAM,YAAY,WAAW,UAAU,CAAC,SAAS;AAChD,iBAAW,KAAK,KAAM,KAAI,EAAE,CAAC,MAAM,mBAAM,gBAAe,EAAE,CAAC;AAAA,IAC5D,CAAC;AACD,UAAM,eAAW;AAAA,MAChB,CAAC,WAAW;AAAA,MACZ,CAAC,WAAW,UAAU,QAAQ;AAC7B,cAAM,OAAO,UAAU;AAAA,UAAI,CAACA,SAAO,MAClCA,WAAS,QAAQA,QAAM,SAAS,IAAIA,QAAM,GAAG,EAAE,IAAI,IAAI,SAAS,CAAC;AAAA,QAClE;AACA,YAAI,KAAK,CAAC,MAAM,MAAM;AACrB,eAAK,yBAAyB,MAAM,IAAI,MAAM,oBAAoB,CAAC;AACnE,cAAI,iBAAiB,OAAQ,YAAW,KAAK,MAAM;AAAA,QACpD;AAAA,MACD;AAAA,MACA,EAAE,cAAc,SAAS;AAAA,IAC1B;AAKA,UAAM,iBAAa,0BAAU,WAAW;AACxC,UAAM,gBAAY,0BAAU,UAAU;AACtC,UAAM,cAAU,0BAAU,QAAQ;AAsBlC,SAAK,sBAAkB,cAAAD;AAAA,MACtB,CAAC,YAAY,iBAAiB;AAAA,MAC9B,CAAC,MAAM,SAAS,QAAQ;AACvB,cAAM,OAAO,WAA4B,MAAM,IAAI,UAAU,GAAG,MAAM;AACtE,cAAM,OAAO,WAAoC,MAAM,IAAI,UAAU,GAAG,MAAS;AACjF,YAAI,SAAS,QAAQ;AACpB,cAAI,SAAS,QAAW;AACvB,oBAAQ,KAAK,IAAI;AACjB;AAAA,UACD;AACA,gBAAM,MAAM,IAAI,MAAM,oBAAoB;AAC1C,cAAI,OAAO;AACX,kBAAQ,KAAK,CAAC,CAAC,qBAAO,GAAG,CAAC,CAAC;AAC3B;AAAA,QACD;AACA,YAAI,SAAS,SAAS;AACrB,kBAAQ,KAAK,CAAC,CAAC,qBAAO,IAAI,MAAM,oBAAoB,CAAC,CAAC,CAAC;AACvD;AAAA,QACD;AACA,gBAAQ,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AAAA,MAC1B;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAQpC,SAAS;AAAA,MACV;AAAA,IACD;AAcA,SAAK,IAAI,aAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,SAAK,IAAI,aAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,SAAK,IAAI,KAAK,cAA+B,EAAE,MAAM,eAAe,CAAC;AAKrE,QAAI,KAAK,cAAc,cAAc;AACpC,WAAK,IAAI,KAAK,WAA4B,EAAE,MAAM,YAAY,CAAC;AAAA,IAChE,OAAO;AACN,WAAK,IAAI,cAA+B,EAAE,MAAM,eAAe,CAAC;AAChE,WAAK,IAAI,KAAK,WAA4B,EAAE,MAAM,YAAY,CAAC;AAAA,IAChE;AACA,SAAK,IAAI,iBAAkC,EAAE,MAAM,cAAc,CAAC;AAClE,SAAK,IAAI,KAAK,iBAAkC,EAAE,MAAM,iBAAiB,CAAC;AAM1E,SAAK,YAAY,OAAO;AACxB,SAAK,YAAY,UAAU;AAC3B,SAAK,YAAY,SAAS;AAC1B,SAAK,YAAY,UAAU;AAC3B,SAAK,YAAY,SAAS;AAC1B,SAAK,YAAY,OAAO;AACxB,SAAK,oBAAoB,MAAY;AAAA,IAIrC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAM,IAAI,aAAsB,QAAmD;AAClF,QAAI,KAAK,UAAU;AAClB,YAAM,IAAI;AAAA,QACT,cAAc,KAAK,IAAI;AAAA,MACxB;AAAA,IACD;AACA,SAAK,WAAW;AAEhB,QAAI;AACJ,QAAI;AAwBH,+BAAM,MAAM;AACX,aAAK,aAAa,KAAK,CAAC,CAAC,wBAAU,CAAC,CAAC;AACrC,aAAK,KAAK,KAAK,CAAC;AAChB,aAAK,QAAQ,KAAK,KAAK;AACvB,aAAK,OAAO,KAAK,MAAM;AAAA,MACxB,CAAC;AACD,UAAI,eAAe,KAAM,MAAK,KAAK,OAAO,QAAQ,WAAW;AAiB7D,YAAM,gBAAgB,aAAa,KAAK,iBAAiB,EAAE,aAAa,KAAK,CAAC;AAE9E,UAAI,UAAU,MAAM;AACnB,YAAI,OAAO,SAAS;AACnB,eAAK,QAAQ,KAAK,IAAI;AAAA,QACvB,OAAO;AACN,gBAAM,WAAW,MAAY,KAAK,QAAQ,KAAK,IAAI;AACnD,iBAAO,iBAAiB,SAAS,UAAU,EAAE,MAAM,KAAK,CAAC;AACzD,qBAAW,MAAY,OAAO,oBAAoB,SAAS,QAAQ;AAAA,QACpE;AAAA,MACD;AAQA,UAAI,QAAQ,YAAY,MAAM;AAC7B,aAAK,OAAO,KAAK,UAAU;AAAA,MAC5B;AAEA,aAAO,MAAM;AAAA,IACd,UAAE;AACD,iBAAW;AACX,WAAK,WAAW;AAChB,WAAK,0BAA0B;AAAA,IAChC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAc;AACb,SAAK,QAAQ,KAAK,IAAI;AAAA,EACvB;AAAA,EAES,UAAgB;AACxB,QAAI;AACH,WAAK,kBAAkB;AAAA,IACxB,QAAQ;AAAA,IAER;AACA,UAAM,QAAQ;AAAA,EACf;AACD;AAYA,SAAS,WACR,WACA,UACA,OACA,UACI;AACJ,QAAMC,UAAQ,UAAU,KAAK;AAC7B,MAAIA,WAAS,QAAQA,QAAM,SAAS,EAAG,QAAOA,QAAMA,QAAM,SAAS,CAAC;AACpE,QAAM,OAAO,SAAS,KAAK;AAC3B,SAAQ,SAAS,SAAY,OAAO;AACrC;AAQO,SAAS,UAAU,MAAc,MAAwC;AAC/E,QAAM,IAAI,IAAI,eAAe,MAAM,IAAI;AAMvC,IAAE,WAAW,iBAAa,+BAAgB,IAA0C,CAAC;AACrF,SAAO;AACR;;;AD9tBA,IAAM,cAA2B,OAAO,OAAO,EAAE,SAAS,EAAE,CAAC;AAC7D,IAAM,eAA6B,OAAO,OAAO,EAAE,SAAS,EAAE,CAAC;AAC/D,IAAM,cAA0B,OAAO,OAAO,EAAE,OAAO,aAAa,QAAQ,aAAa,CAAC;AAGnF,IAAM,YAAuB,OAAO,OAAO,EAAE,OAAO,aAAa,OAAO,EAAE,CAAC;AAMlF,SAAS,YAAY,GAAuB,GAA2C;AACtF,MAAI,KAAK,QAAQ,KAAK,KAAM,QAAO;AACnC,UAAQ,KAAK,MAAM,KAAK;AACzB;AAEA,SAAS,cACR,GACA,GACqC;AACrC,MAAI,KAAK,QAAQ,KAAK,KAAM,QAAO;AACnC,QAAM,MAA8B,EAAE,GAAI,KAAK,CAAC,EAAG;AACnD,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,CAAC,CAAC,GAAG;AAC7C,QAAI,CAAC,KAAK,IAAI,CAAC,KAAK,KAAK;AAAA,EAC1B;AACA,SAAO;AACR;AAWO,SAAS,SAAS,GAAe,GAA2B;AAClE,QAAM,MAAkB;AAAA,IACvB,OAAO;AAAA,MACN,SAAS,EAAE,MAAM,UAAU,EAAE,MAAM;AAAA,MACnC,GAAI,YAAY,EAAE,MAAM,WAAW,EAAE,MAAM,SAAS,MAAM,UAAa;AAAA,QACtE,WAAW,YAAY,EAAE,MAAM,WAAW,EAAE,MAAM,SAAS;AAAA,MAC5D;AAAA,MACA,GAAI,YAAY,EAAE,MAAM,cAAc,EAAE,MAAM,YAAY,MAAM,UAAa;AAAA,QAC5E,cAAc,YAAY,EAAE,MAAM,cAAc,EAAE,MAAM,YAAY;AAAA,MACrE;AAAA,MACA,GAAI,YAAY,EAAE,MAAM,cAAc,EAAE,MAAM,YAAY,MAAM,UAAa;AAAA,QAC5E,cAAc,YAAY,EAAE,MAAM,cAAc,EAAE,MAAM,YAAY;AAAA,MACrE;AAAA,MACA,GAAI,YAAY,EAAE,MAAM,iBAAiB,EAAE,MAAM,eAAe,MAAM,UAAa;AAAA,QAClF,iBAAiB,YAAY,EAAE,MAAM,iBAAiB,EAAE,MAAM,eAAe;AAAA,MAC9E;AAAA,MACA,GAAI,YAAY,EAAE,MAAM,OAAO,EAAE,MAAM,KAAK,MAAM,UAAa;AAAA,QAC9D,OAAO,YAAY,EAAE,MAAM,OAAO,EAAE,MAAM,KAAK;AAAA,MAChD;AAAA,MACA,GAAI,YAAY,EAAE,MAAM,OAAO,EAAE,MAAM,KAAK,MAAM,UAAa;AAAA,QAC9D,OAAO,YAAY,EAAE,MAAM,OAAO,EAAE,MAAM,KAAK;AAAA,MAChD;AAAA,MACA,GAAI,YAAY,EAAE,MAAM,OAAO,EAAE,MAAM,KAAK,MAAM,UAAa;AAAA,QAC9D,OAAO,YAAY,EAAE,MAAM,OAAO,EAAE,MAAM,KAAK;AAAA,MAChD;AAAA,MACA,GAAI,YAAY,EAAE,MAAM,SAAS,EAAE,MAAM,OAAO,MAAM,UAAa;AAAA,QAClE,SAAS,YAAY,EAAE,MAAM,SAAS,EAAE,MAAM,OAAO;AAAA,MACtD;AAAA,MACA,GAAI,cAAc,EAAE,MAAM,YAAY,EAAE,MAAM,UAAU,MAAM,UAAa;AAAA,QAC1E,YAAY,cAAc,EAAE,MAAM,YAAY,EAAE,MAAM,UAAU;AAAA,MACjE;AAAA,IACD;AAAA,IACA,QAAQ;AAAA,MACP,SAAS,EAAE,OAAO,UAAU,EAAE,OAAO;AAAA,MACrC,GAAI,YAAY,EAAE,OAAO,WAAW,EAAE,OAAO,SAAS,MAAM,UAAa;AAAA,QACxE,WAAW,YAAY,EAAE,OAAO,WAAW,EAAE,OAAO,SAAS;AAAA,MAC9D;AAAA,MACA,GAAI,YAAY,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK,MAAM,UAAa;AAAA,QAChE,OAAO,YAAY,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;AAAA,MAClD;AAAA,MACA,GAAI,YAAY,EAAE,OAAO,oBAAoB,EAAE,OAAO,kBAAkB,MAAM,UAAa;AAAA,QAC1F,oBAAoB;AAAA,UACnB,EAAE,OAAO;AAAA,UACT,EAAE,OAAO;AAAA,QACV;AAAA,MACD;AAAA,MACA,GAAI,YAAY,EAAE,OAAO,oBAAoB,EAAE,OAAO,kBAAkB,MAAM,UAAa;AAAA,QAC1F,oBAAoB;AAAA,UACnB,EAAE,OAAO;AAAA,UACT,EAAE,OAAO;AAAA,QACV;AAAA,MACD;AAAA,MACA,GAAI,cAAc,EAAE,OAAO,YAAY,EAAE,OAAO,UAAU,MAAM,UAAa;AAAA,QAC5E,YAAY,cAAc,EAAE,OAAO,YAAY,EAAE,OAAO,UAAU;AAAA,MAInE;AAAA,IACD;AAAA,IACA,GAAI,cAAc,EAAE,WAAW,EAAE,SAAS,MAAM,UAAa;AAAA,MAC5D,WAAW,cAAc,EAAE,WAAW,EAAE,SAAS;AAAA,IAClD;AAAA,EACD;AACA,SAAO;AACR;AA2FA,IAAM,oBAAoB,oBAAI,IAAiB,CAAC,QAAQ,OAAO,CAAC;AAkCzD,IAAM,aAAN,cAAoC,qBAAM;AAAA;AAAA,EAEvC;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAET,YAAY,MAA4B,MAAqB;AAC5D,UAAM,KAAK,MAAM,IAAI;AAGrB,UAAM,eAAe,MAAM,QAAQ,KAAK,KAAK,IACzC,KAAK,QACN;AACH,SAAK,OAAO,UAAU,GAAG,KAAK,IAAI,SAAS;AAAA,MAC1C,SAAS,KAAK;AAAA,MACd,GAAI,KAAK,gBAAgB,OAAO,EAAE,cAAc,KAAK,aAAa,IAAI,CAAC;AAAA,MACvE,GAAI,gBAAgB,OAAO,EAAE,OAAO,aAAa,IAAI,CAAC;AAAA,MACtD,GAAI,KAAK,iBAAiB,OAAO,EAAE,UAAU,KAAK,cAAc,IAAI,CAAC;AAAA,IACtE,CAAC;AACD,SAAK,MAAM,QAAQ,KAAK,IAAI;AAM5B,QAAI,KAAK,SAAS,QAAQ,CAAC,MAAM,QAAQ,KAAK,KAAK,GAAG;AACrD,YAAM,YAAY,KAAK;AACvB,YAAM,aAAa,oBAAI,IAAY;AACnC,YAAM,aAAa,UAAU,UAAU,CAAC,SAAS;AAChD,mBAAW,KAAK,MAAM;AACrB,cAAI,EAAE,CAAC,MAAM,mBAAM;AACnB,gBAAM,OAAO,EAAE,CAAC;AAChB,gBAAM,YAAY,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAEjD,qBAAW,QAAQ,YAAY;AAC9B,gBAAI,CAAC,UAAU,IAAI,IAAI,GAAG;AACzB,mBAAK,KAAK,MAAM,WAAW,IAAI;AAC/B,yBAAW,OAAO,IAAI;AAAA,YACvB;AAAA,UACD;AAEA,qBAAW,QAAQ,MAAM;AACxB,gBAAI,CAAC,WAAW,IAAI,KAAK,IAAI,GAAG;AAC/B,mBAAK,KAAK,MAAM,SAAS,IAAI;AAC7B,yBAAW,IAAI,KAAK,IAAI;AAAA,YACzB;AAAA,UACD;AAAA,QACD;AAAA,MACD,CAAC;AACD,WAAK,YAAY,UAAU;AAAA,IAC5B;AAOA,SAAK,SAAS,KAAK,UAAU;AAC7B,QAAI,KAAK,UAAU,MAAM;AACxB,WAAK,MAAM,UAAU,KAAK,MAAM;AAAA,IACjC;AAKA,SAAK,SAAK,oBAAU,CAAC,GAAG;AAAA,MACvB,MAAM;AAAA,MACN,cAAc;AAAA,MACd,MAAM,OAAO,UAAU;AAAA,MACvB,QAAQ,MAAM;AAAA,IACf,CAAC;AACD,SAAK,IAAI,KAAK,IAAI,EAAE,MAAM,KAAK,CAAC;AAGhC,UAAM,eAAW,oBAAgB,CAAC,GAAG;AAAA,MACpC,MAAM;AAAA,MACN,cAAc;AAAA,MACd,MAAM,OAAO,YAAY;AAAA,MACzB,SAAS;AAAA,IACV,CAAC;AACD,SAAK,IAAI,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,SAAK,OAAO;AAUZ,UAAM,YAAY,KAAK,aAAa,iBAAuB;AAC3D,UAAM,cAAU;AAAA,MACf,CAAC,KAAK,KAAK,YAAY;AAAA,MACvB,CAAC,MAAM,GAAG,QAAQ;AACjB,cAAM,SAAS,KAAK,CAAC;AACrB,cAAM,OACL,UAAU,QAAQ,OAAO,SAAS,IAC9B,OAAO,GAAG,EAAE,IACZ,IAAI,SAAS,CAAC;AACnB,YAAI,SAAS,QAAW;AACvB,YAAE,KAAK,CAAC,CAAC,sBAAQ,CAAC,CAAC;AACnB;AAAA,QACD;AACA,UAAE,KAAK,UAAU,IAAI,CAAC;AAAA,MACvB;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,cAAc;AAAA,QACd,MAAM,OAAO,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMxB,QAAQ,MAAM;AAAA,MACf;AAAA,IACD;AACA,SAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,SAAK,MAAM;AAKX,UAAM,iBAAa,oBAAkB,CAAC,GAAG;AAAA,MACxC,MAAM;AAAA,MACN,cAAc;AAAA,MACd,MAAM,OAAO,cAAc;AAAA,MAC3B,SAAS;AAAA,IACV,CAAC;AACD,SAAK,IAAI,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,SAAK,SAAS;AAEd,UAAM,sBAAkB;AAAA,MACvB,CAAC,KAAK,KAAK,MAAM;AAAA,MACjB,CAAC,MAAM,IAAI,QAAQ;AAClB,cAAM,SAAS,KAAK,CAAC;AACrB,cAAM,aACL,UAAU,QAAQ,OAAO,SAAS,IAC9B,OAAO,GAAG,EAAE,IACX,IAAI,SAAS,CAAC,KAA4B;AAChD,cAAM,OACL,eAAe,SACZ,SACA,eAAe,cAAc,eAAe,WAC3C,YACA,eAAe,SACd,SACA,eAAe,UACd,UACA;AACP,YAAI,WAAW,UAAU,KAAM,YAAW,KAAK,IAAI;AAAA,MACpD;AAAA,MACA,EAAE,cAAc,UAAU,MAAM,OAAO,qBAAqB,EAAE;AAAA,IAC/D;AACA,SAAK,gBAAY,0BAAU,eAAe,CAAC;AAS3C,UAAM,cAAU;AAAA,MACf,CAAC,KAAK,KAAK,YAAY;AAAA,MACvB,CAAC,MAAM,IAAI,QAAQ;AAClB,cAAM,SAAS,KAAK,CAAC;AACrB,cAAM,OACL,UAAU,QAAQ,OAAO,SAAS,IAC9B,OAAO,GAAG,EAAE,IACZ,IAAI,SAAS,CAAC;AACnB,YAAI,SAAS,OAAW;AACxB,cAAM,OAAQ,SAAS,SAAmC;AAC1D,cAAM,QAAS,KAAK,KAAK,KAAK,SAAgC,KAAK;AACnE,cAAM,OAAkB;AAAA,UACvB,OAAO,KAAK,SAAS,OAAO,SAAS,KAAK,OAAO,KAAK,KAAK,IAAI,KAAK;AAAA,UACpE;AAAA,QACD;AACA,iBAAS,KAAK,IAAI;AAAA,MACnB;AAAA,MACA,EAAE,cAAc,UAAU,MAAM,OAAO,mBAAmB,EAAE;AAAA,IAC7D;AACA,SAAK,gBAAY,0BAAU,OAAO,CAAC;AAgBnC,UAAM,WAAW,KAAK,YAAY,gBAAqB;AACvD,UAAM,aAA8B,MAAW,aAAa;AAC5D,SAAK,MAAM,eAAe,UAAU;AACpC,UAAM,WAAmC,aAAkB,aAAa,YAAY;AAAA,MACnF,MAAM;AAAA,IACP,CAAC;AACD,SAAK,MAAM,aAAa,QAAQ;AAQhC,UAAM,cAAc,KAAK,GAAG,UAAU,CAAC,SAAS;AAC/C,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,mBAAM;AACnB,cAAM,QAAQ,EAAE,CAAC;AAIjB,iBAAS,KAAK;AACd,mBAAW,QAAQ,KAAK;AAAA,MACzB;AAAA,IACD,CAAC;AACD,SAAK,YAAY,WAAW;AAK5B,UAAM,kBAAc;AAAA,MACnB,CAAC,SAAS,WAAW,KAAK,KAAK,MAAM;AAAA,MACrC,CAAC,MAAM,IAAI,QAAQ;AAClB,cAAM,aAAa,KAAK,CAAC;AACzB,cAAM,cAAc,KAAK,CAAC;AAC1B,cAAM,SACJ,cAAc,QAAQ,WAAW,SAAS,IACvC,WAAW,GAAG,EAAE,IACf,IAAI,SAAS,CAAC,KAAoC,CAAC,MAAO,CAAC;AACjE,cAAM,QACJ,eAAe,QAAQ,YAAY,SAAS,IACzC,YAAY,GAAG,EAAE,IAChB,IAAI,SAAS,CAAC,KAA4B,WAAY;AAC5D,YAAI,MAAM,WAAW,EAAG;AACxB,YAAI,SAAS,cAAc,SAAS,SAAU;AAC9C,cAAM,SAAS,SAAS,WAAW,CAAC;AACpC,YAAI,OAAO,MAAM,WAAW,EAAG;AAC/B,cAAM,QAAQ,OAAO,MAAM,CAAC;AAC5B,cAAM,UAAU,SAAS,KAAK;AAC9B,iCAAM,MAAM;AASX,eAAK,KAAK,aAAa,KAAK,CAAC,CAAC,wBAAU,CAAC,CAAC;AAC1C,eAAK,KAAK,KAAK,KAAK,CAAC;AACrB,eAAK,KAAK,QAAQ,KAAK,KAAK;AAC5B,mBAAS,KAAK,SAAS;AACvB,eAAK,KAAK,KAAK,OAAO,QAAQ,OAAO;AACrC,eAAK,KAAK,OAAO,KAAK,UAAU;AAAA,QACjC,CAAC;AAAA,MACF;AAAA,MACA,EAAE,cAAc,UAAU,MAAM,OAAO,mBAAmB,EAAE;AAAA,IAC7D;AACA,SAAK,gBAAY,0BAAU,WAAW,CAAC;AAQvC,SAAK,gBAAY,0BAAU,KAAK,GAAG,CAAC;AAGpC,SAAK;AAAA,EACN;AACD;AAWA,SAAS,kBAA+C;AACvD,SAAO,CAAC,UAAU;AACjB,QAAI,OAAO,UAAU,UAAU;AAC9B,YAAM,IAAI;AAAA,QACT,6DAA6D,OAAO,KAAK;AAAA,MAC1E;AAAA,IACD;AACA,WAAO;AAAA,EACR;AACD;AAOA,SAAS,mBAA0D;AAClE,SAAO,CAAC,aAAa;AACtB;;;ADrjBO,SAAS,MACf,QACA,MACyB;AACzB,QAAM,QAAQ,IAAI,WAAsB,IAAI;AAC5C,SAAO,MAAM,KAAK,MAAM,KAAK;AAC7B,SAAO;AAAA,IACN,IAAI,MAAM;AAAA,IACV,KAAK,MAAM;AAAA,IACX,QAAQ,MAAM;AAAA,IACd,MAAM,MAAM;AAAA,IACZ;AAAA,EACD;AACD;;;AD2DO,IAAM,iBAAN,cAAwC,qBAAM;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,YAAY;AAAA,EAEpB,YAAY,MAAgC;AAC3C,UAAM,OAAO,KAAK,QAAQ;AAC1B,UAAM,IAAI;AAEV,SAAK,YAAY,KAAK;AACtB,SAAK,YAAY,KAAK;AACtB,SAAK,YAAY,KAAK;AAGtB,SAAK,aAAa,KAAK,IAAI,MAAuC,YAAY;AAG9E,SAAK,WAAW,MAA2B,UAAU;AACrD,SAAK,MAAM,YAAY,KAAK,QAAQ;AAIpC,UAAM,qBAAiB,oBAAkD,CAAC,GAAG;AAAA,MAC5E,MAAM;AAAA,MACN,cAAc;AAAA,MACd,MAAM,OAAO,uBAAuB;AAAA,MACpC,SAAS,oBAAI,IAAI;AAAA,MACjB,QAAQ,MAAM;AAAA,IACf,CAAC;AACD,SAAK,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,SAAK,aAAa;AAOlB,SAAK,YAAY,aAA8C,aAAa,KAAK,YAAY;AAAA,MAC5F,MAAM,KAAK,QAAQ;AAAA,IACpB,CAAC;AACD,SAAK,MAAM,aAAa,KAAK,SAAS;AAGtC,UAAM,SAAS,KAAK;AACpB,UAAM,QAAQ,OAAO,UAAU,UAAU,CAAC,SAAS;AAClD,UAAI,KAAK,UAAW;AACpB,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,mBAAM;AACnB,cAAM,QAAQ,EAAE,CAAC;AACjB,YAAI,MAAM,WAAW,EAAG;AACxB,mBAAW,OAAO,OAAO;AACxB,cAAI,KAAK,UAAW;AACpB,eAAK,gBAAgB,GAAG;AAAA,QACzB;AACA,eAAO,IAAI,MAAM,MAAM;AAAA,MACxB;AAAA,IACD,CAAC;AACD,SAAK,YAAY,KAAK;AACtB,SAAK,YAAY,MAAM;AACtB,WAAK,YAAY;AAAA,IAClB,CAAC;AAGD,SAAK,gBAAY,0BAAU,cAAc,CAAC;AAAA,EAC3C;AAAA,EAEQ,gBAAgB,KAA4C;AACnE,QAAI,KAAK,UAAW;AAGpB,QAAI,KAAK,aAAa,CAAC,KAAK,UAAU,GAAG,GAAG;AAC3C,WAAK,SAAS,QAAQ,EAAE,SAAS,KAAK,QAAQ,2BAA2B,CAAC;AAC1E;AAAA,IACD;AAMA,QAAI,IAAI,aAAa,MAAM;AAC1B,YAAM,SAAS,KAAK,MAAM,IAAI,SAAS;AACvC,UAAI,CAAC,OAAO,SAAS,MAAM,GAAG;AAC7B,aAAK,SAAS,QAAQ,EAAE,SAAS,KAAK,QAAQ,oBAAoB,CAAC;AACnE;AAAA,MACD;AACA,YAAM,YAAQ,2BAAY,IAAI;AAC9B,UAAI,SAAS,QAAQ;AACpB,aAAK,SAAS,QAAQ,EAAE,SAAS,KAAK,QAAQ,UAAU,CAAC;AACzD;AAAA,MACD;AAAA,IACD;AAGA,UAAM,aACJ,KAAK,WAAW,SACjB,oBAAI,IAAI;AACT,QAAI,KAAK,aAAa,QAAQ,WAAW,QAAQ,KAAK,WAAW;AAChE,WAAK,SAAS,QAAQ;AAAA,QACrB,SAAS;AAAA,QACT,QAAQ,uBAAuB,WAAW,IAAI,IAAI,KAAK,SAAS;AAAA,MACjE,CAAC;AACD;AAAA,IACD;AAGA,UAAM,OAAO,KAAK,UAAU,SAAS,IAAI,IAAI,QAAQ,QAAQ;AAC7D,QAAI,CAAC,MAAM;AACV,WAAK,SAAS,QAAQ;AAAA,QACrB,SAAS;AAAA,QACT,QAAQ,qBAAqB,IAAI,QAAQ,QAAQ;AAAA,MAClD,CAAC;AACD;AAAA,IACD;AAIA,UAAM,WAAW,SAAS,IAAI,EAAE;AAChC,QAAI;AACJ,QAAI;AACH,eAAS,MAAiB,MAAM,EAAE,GAAG,MAAM,MAAM,SAAS,CAAC;AAAA,IAC5D,SAAS,GAAG;AACX,WAAK,SAAS,QAAQ;AAAA,QACrB,SAAS;AAAA,QACT,QAAQ,sBAAuB,EAAY,WAAW,SAAS;AAAA,MAChE,CAAC;AACD;AAAA,IACD;AAGA,UAAM,UAAU,IAAI,IAAI,UAAU;AAClC,YAAQ,IAAI,IAAI,IAAI,MAAM;AAC1B,SAAK,WAAW,KAAK,OAAO;AAO5B,QAAI;AACJ,UAAM,aAAa,CAAC,SAA4B;AAC/C,UAAI,SAAS,UAAU,SAAS,QAAS;AAEzC,YAAM,OACJ,KAAK,WAAW,SACjB,oBAAI,IAAI;AACT,UAAI,CAAC,KAAK,IAAI,IAAI,EAAE,EAAG;AACvB,+BAAM,MAAM;AACX,YAAI;AACH,eAAK,OAAO,QAAQ;AAAA,QACrB,QAAQ;AAAA,QAER;AACA,cAAM,OAAO,IAAI,IAAI,IAAI;AACzB,aAAK,OAAO,IAAI,EAAE;AAClB,aAAK,WAAW,KAAK,IAAI;AAAA,MAC1B,CAAC;AAGD,oBAAc;AACd,oBAAc;AAAA,IACf;AACA,kBAAc,OAAO,OAAO,UAAU,CAAC,SAAS;AAC/C,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,mBAAM,YAAW,EAAE,CAAC,CAAgB;AAAA,MAClD;AAAA,IACD,CAAC;AAID,SAAK,YAAY,MAAM,cAAc,CAAC;AAGtC,WAAO,GAAG,KAAK,IAAI,QAAQ,SAAS;AAAA,EACrC;AACD;AAkDO,SAAS,UACf,MAC6B;AAC7B,QAAM,QAAQ,IAAI,eAA0B,IAAI;AAChD,OAAK,IAAI,MAAM,KAAK,QAAQ,aAAa,KAAK;AAC9C,SAAO;AAAA,IACN,YAAY,MAAM;AAAA,IAClB,YAAY,MAAM;AAAA,IAClB,UAAU,MAAM;AAAA,IAChB;AAAA,EACD;AACD;;;AIlXA,IAAAC,gBAA4B;AA+D5B,SAAS,iBAAiB,SAA+C;AACxE,QAAM,SAAiC,CAAC;AACxC,aAAW,EAAE,OAAO,MAAM,KAAK,QAAQ,WAAW,GAAG;AACpD,eAAW,KAAK,MAAO,QAAO,CAAC,IAAI;AAAA,EACpC;AACA,SAAO;AACR;AAoBO,SAAS,aACf,SACA,MACqB;AACrB,QAAM,SACL,MAAM,WAAW,OAAO,OAAQ,MAAM,UAAU,QAAQ;AACzD,QAAM,SAAsB,MAAM,UAAU;AAC5C,QAAM,cAAU,2BAAY;AAC5B,QAAM,eAAgC,CAAC;AACvC,QAAM,SAAuB,CAAC;AAC9B,QAAM,cAAc,iBAAiB,OAAO;AAE5C,WAAS,cAAsB;AAC9B,gBAAQ,2BAAY,IAAI,WAAW;AAAA,EACpC;AAEA,WAAS,YAAY,OAAe,MAAsB,SAAwB;AACjF,UAAM,KAAiB,EAAE,SAAS,YAAY,GAAG,OAAO,KAAK;AAC7D,QAAI,WAAW,UAAW,IAAG,UAAU,UAAU,OAAO;AACxD,QAAI,WAAW,OAAQ,IAAG,OAAO;AACjC,WAAO,KAAK,EAAE;AAAA,EACf;AAOA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,WAAW,GAAG;AACxD,QAAI;AACH,YAAM,MAAM,QAAQ,QAAQ,MAAM;AAAA,QACjC,QAAQ;AAAA,QACR;AAAA,QACA,QAAQ,SAAS,CAAC,SAAiB,OAAO,IAAI,IAAI,MAAM;AAAA,QAAC;AAAA,QACzD,cAAc,CAAC,QAAQ,SAAS,UAAU;AAAA,MAC3C,CAAC;AACD,UAAI,QAAQ,CAAC,UAAwB;AACpC,YAAI,MAAM,SAAS,OAAQ,aAAY,OAAO,QAAS,MAA4B,IAAI;AAAA,iBAC9E,MAAM,SAAS;AACvB,sBAAY,OAAO,SAAU,MAA4B,IAAI;AAAA,iBACrD,MAAM,SAAS,WAAY,aAAY,OAAO,YAAY,MAAS;AAAA,MAC7E,CAAC;AACD,mBAAa,KAAK,GAAG;AAAA,IACtB,SAAS,KAAK;AAMb,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,kBAAY,OAAO,SAAS,wBAAwB,IAAI,WAAM,GAAG,EAAE;AACnE,UAAI,QAAQ;AACX,eAAO,IAAI,YAAY,EAAE,QAAQ,CAAC,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC,gCAA2B,GAAG,EAAE;AAAA,MACzF;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AAAA,IACN,IAAI,SAAgC;AACnC,aAAO;AAAA,IACR;AAAA,IACA,UAAU;AACT,iBAAW,OAAO,aAAc,KAAI,QAAQ;AAC5C,mBAAa,SAAS;AAAA,IACvB;AAAA,EACD;AACD;AAQA,SAAS,UAAU,OAAwB;AAC1C,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,SAAU,QAAO,SAAS,OAAO,EAAE;AACxD,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAW,QAAO,OAAO,KAAK;AAChF,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAClD,MAAI;AACH,UAAM,OAAO,KAAK,UAAU,KAAK;AACjC,WAAO,SAAS,MAAM,GAAG;AAAA,EAC1B,QAAQ;AACP,WAAO,OAAO,KAAK;AAAA,EACpB;AACD;AAEA,SAAS,SAAS,GAAW,KAAqB;AACjD,SAAO,EAAE,SAAS,MAAM,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,WAAM;AACrD;","names":["isNode","import_core","isNode","import_core","import_core","import_extra","import_graph","import_core","import_extra","batch","policy","import_core","import_extra","import_graph","import_core","import_extra","import_core","import_extra","import_graph","import_core","import_extra","import_graph","meta","import_core","import_extra","import_graph","batch","createNode","batch","i","best","bestScore","batch","meanScore","defaultToOutput","batch","import_core","import_extra","import_graph","import_core","import_core","isNode","import_core","import_extra","batch","import_core","import_graph","batch","import_core","import_extra","import_graph","batch","import_core","import_extra","batch","import_core","import_extra","import_graph","batch","import_core","import_extra","import_graph","import_core","import_extra","import_graph","DEFAULT_MAX_PER_PUMP","requireNonNegativeInt","batch","requireNonNegativeInt","DEFAULT_MAX_PER_PUMP","batch","topic","import_core","import_extra","import_graph","batch","import_graph","import_core","import_extra","import_graph","import_extra","import_core","import_extra","import_graph","import_core","import_extra","import_graph","nodeFactory","batch","import_core"]}
1
+ {"version":3,"sources":["../../../src/base/resilience/_internal.ts","../../../src/base/resilience/backoff.ts","../../../src/base/resilience/timeout.ts","../../../src/presets/harness/index.ts","../../../src/presets/harness/actor-pool.ts","../../../src/presets/ai/context/index.ts","../../../src/utils/ai/_internal.ts","../../../src/base/meta/domain-meta.ts","../../../src/presets/harness/eval-verifier.ts","../../../src/presets/harness/refine-executor.ts","../../../src/presets/harness/refine-loop.ts","../../../src/base/mutation/index.ts","../../../src/utils/messaging/message.ts","../../../src/utils/messaging/index.ts","../../../src/presets/harness/harness-loop.ts","../../../src/base/sources/settled.ts","../../../src/base/resilience/retry.ts","../../../src/utils/ai/prompts/prompt-node.ts","../../../src/utils/orchestration/pipeline-graph.ts","../../../src/utils/ai/agents/chat-stream.ts","../../../src/utils/ai/agents/tool-execution.ts","../../../src/utils/ai/agents/tool-registry.ts","../../../src/base/utils/decay.ts","../../../src/utils/harness/_internal.ts","../../../src/utils/harness/defaults.ts","../../../src/utils/harness/strategy.ts","../../../src/utils/orchestration/audited-success-tracker.ts","../../../src/utils/harness/types.ts","../../../src/utils/job-queue/index.ts","../../../src/presets/harness/ownership-controller.ts","../../../src/presets/harness/profile.ts","../../../src/presets/harness/spawnable.ts","../../../src/presets/ai/agents.ts","../../../src/presets/ai/agent.ts","../../../src/presets/ai/agent-loop.ts","../../../src/presets/harness/trace.ts"],"sourcesContent":["/**\n * Internal helpers shared by resilience sub-files.\n *\n * Not part of the public surface. The base-layer resilience operators\n * co-located here (`retry.ts`, `status.ts`, `timeout.ts`) import what they\n * need from this file directly; the utils-layer resilience primitives that\n * stayed in `utils/resilience/` (`breaker.ts`, `rate-limiter.ts`,\n * `fallback.ts`) import it top-down via `../../base/resilience/_internal.js`.\n *\n * `NodeOrValue<T>` is the only export re-surfaced publicly — there is no\n * `base/resilience/index.ts`; it ships through `utils/resilience/index.ts`\n * (and `utils/memory/index.ts`). Every resilience primitive that accepts\n * reactive options uses it as the option-arg shape.\n */\n\nimport type { Node, NodeOptions } from \"@graphrefly/pure-ts/core\";\nimport { DATA, type Message } from \"@graphrefly/pure-ts/core\";\n\nexport type ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nexport function operatorOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\nexport function clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nexport function msgVal(m: Message): unknown {\n\treturn m[1];\n}\n\nexport function coerceDelayNs(raw: number): number {\n\tif (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n\t\tthrow new TypeError(\"backoff strategy must return a finite number\");\n\t}\n\treturn raw < 0 ? 0 : raw;\n}\n\nexport function isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\t\"cache\" in x &&\n\t\ttypeof (x as Node).subscribe === \"function\"\n\t);\n}\n\n/**\n * Either a literal value or a reactive Node carrying it. Mirrors\n * {@link FallbackInput}'s precedent for \"options that may be reactive.\"\n *\n * Used by {@link timeout} / {@link retry} / {@link rateLimiter} /\n * {@link circuitBreaker} / {@link budgetGate} to accept reactive option\n * configurations (Tier 6.5 3.2, 2026-04-29). Each primitive subscribes\n * to the option Node via {@link resolveReactiveOption} and rebinds\n * internal state per its locked swap-semantic rule (see each primitive's\n * JSDoc for the rule).\n *\n * @category extra\n */\nexport type NodeOrValue<T> = T | Node<T>;\n\n/**\n * Closure-mirror helper for `NodeOrValue<T>` options\n * (COMPOSITION-GUIDE §28). Returns:\n * - `current()` — read the latest value (cached at construction; updated\n * on each Node DATA emission).\n * - `unsub()` — release the subscription. Static-form arg never\n * subscribes; `unsub` is a no-op there.\n *\n * `onChange` fires on each DATA after the initial value (skips the\n * cache-seed read). Use to rebind primitive-internal state per the\n * primitive's locked swap-semantic rule.\n *\n * @internal\n */\nexport function resolveReactiveOption<T>(\n\targ: NodeOrValue<T>,\n\tonChange?: (next: T) => void,\n): { current: () => T; unsub: () => void } {\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg, unsub: () => undefined };\n\t}\n\tconst node = arg as Node<T>;\n\tlet latest: T = node.cache as T;\n\tconst unsub = node.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tlatest = m[1] as T;\n\t\t\t\tif (onChange) onChange(latest);\n\t\t\t}\n\t\t}\n\t});\n\treturn {\n\t\tcurrent: () => latest,\n\t\tunsub,\n\t};\n}\n\nexport function isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nexport function isAsyncIterable(x: unknown): x is AsyncIterable<unknown> {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\ttypeof (x as AsyncIterable<unknown>)[Symbol.asyncIterator] === \"function\"\n\t);\n}\n","/**\n * Backoff strategies for {@link retry} (roadmap §3.1). Delays are in **nanoseconds**.\n *\n * Convention: all graphrefly-ts timestamps and durations use nanoseconds (`_ns` suffix).\n * 1 second = 1_000_000_000 ns, 1 ms = 1_000_000 ns.\n */\n\nexport const NS_PER_MS = 1_000_000;\nexport const NS_PER_SEC = 1_000_000_000;\n\nexport type JitterMode = \"none\" | \"full\" | \"equal\";\n\nexport type BackoffPreset =\n\t| \"constant\"\n\t| \"linear\"\n\t| \"exponential\"\n\t| \"fibonacci\"\n\t| \"decorrelatedJitter\";\n\n/** `(attempt, error?, previousDelayNs?) => delayNs | null` — `null` means zero delay. */\nexport type BackoffStrategy = (\n\tattempt: number,\n\terror?: unknown,\n\tprevDelayNs?: number | null,\n) => number | null;\n\nfunction clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nfunction applyJitter(delay: number, jitter: JitterMode): number {\n\tif (jitter === \"none\") return delay;\n\tif (jitter === \"full\") return Math.random() * delay;\n\treturn delay / 2 + Math.random() * (delay / 2);\n}\n\nfunction randomBetween(min: number, max: number): number {\n\treturn min + Math.random() * (max - min);\n}\n\n/**\n * Builds a strategy that always returns the same delay in nanoseconds.\n *\n * @param delayNs - Non-negative delay in nanoseconds; values below zero are clamped to zero.\n * @returns `BackoffStrategy` for use with {@link retry} or custom timers.\n *\n * @example\n * ```ts\n * import { constant, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: constant(0.25 * NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function constant(delayNs: number): BackoffStrategy {\n\tconst safe = clampNonNegative(delayNs);\n\treturn () => safe;\n}\n\n/**\n * Builds linear backoff: `baseNs + stepNs * attempt` (`stepNs` defaults to `baseNs`).\n *\n * @param baseNs - Base delay in nanoseconds (clamped non-negative).\n * @param stepNs - Added per retry attempt in nanoseconds (clamped non-negative).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { linear, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // Attempt 0 → 1 s, attempt 1 → 2 s, attempt 2 → 3 s …\n * const out = retry(source, { count: 4, backoff: linear(NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function linear(baseNs: number, stepNs?: number): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeStep = stepNs === undefined ? safeBase : clampNonNegative(stepNs);\n\treturn (attempt: number) => safeBase + safeStep * Math.max(0, attempt);\n}\n\nexport type ExponentialBackoffOptions = {\n\tbaseNs?: number;\n\tfactor?: number;\n\tmaxDelayNs?: number;\n\tjitter?: JitterMode;\n};\n\n/**\n * Builds exponential backoff in nanoseconds, capped by `maxDelayNs`, with optional jitter.\n *\n * @param options - Base, factor, cap, and jitter mode.\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @remarks\n * **Jitter:** `\"full\"` spreads delay across `[0, delay]`; `\"equal\"` uses `[delay/2, delay]`.\n *\n * @example\n * ```ts\n * import { exponential, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // 100 ms → 200 ms → 400 ms … capped at 30 s, with full jitter\n * const out = retry(source, {\n * count: 5,\n * backoff: exponential({ baseNs: 100 * NS_PER_SEC / 1000, jitter: \"full\" }),\n * });\n * ```\n *\n * @category extra\n */\nexport function exponential(options?: ExponentialBackoffOptions): BackoffStrategy {\n\tconst baseNs = clampNonNegative(options?.baseNs ?? 100 * NS_PER_MS);\n\tconst factor = options?.factor !== undefined && options.factor < 1 ? 1 : (options?.factor ?? 2);\n\tconst maxDelayNs = clampNonNegative(options?.maxDelayNs ?? 30 * NS_PER_SEC);\n\tconst jitter = options?.jitter ?? \"none\";\n\n\treturn (attempt: number) => {\n\t\tlet delay: number;\n\t\tif (baseNs === 0) {\n\t\t\tdelay = 0;\n\t\t} else if (factor === 1) {\n\t\t\tdelay = baseNs;\n\t\t} else {\n\t\t\tconst capRatio = maxDelayNs / baseNs;\n\t\t\tlet growth = 1;\n\t\t\tfor (let i = 0; i < Math.max(0, attempt); i++) {\n\t\t\t\tif (growth >= capRatio) {\n\t\t\t\t\tgrowth = capRatio;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tgrowth *= factor;\n\t\t\t}\n\t\t\tdelay = baseNs * growth;\n\t\t\tif (delay > maxDelayNs) delay = maxDelayNs;\n\t\t}\n\t\treturn applyJitter(delay, jitter);\n\t};\n}\n\n/**\n * Builds Fibonacci-scaled delays: `1, 2, 3, 5, … × baseNs`, capped at `maxDelayNs`.\n *\n * @param baseNs - Multiplier applied to the Fibonacci unit (default `100ms` in nanoseconds).\n * @param maxDelayNs - Upper bound in nanoseconds (default `30s`).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { fibonacci, retry, NS_PER_MS } from \"@graphrefly/graphrefly-ts\";\n *\n * // Delays: 100 ms, 200 ms, 300 ms, 500 ms, 800 ms … (× 100 ms base)\n * const out = retry(source, { count: 5, backoff: fibonacci(100 * NS_PER_MS) });\n * ```\n *\n * @category extra\n */\nexport function fibonacci(baseNs = 100 * NS_PER_MS, maxDelayNs = 30 * NS_PER_SEC): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeMax = clampNonNegative(maxDelayNs);\n\n\tfunction fibUnit(attempt: number): number {\n\t\tif (attempt <= 0) return 1;\n\t\tlet prev = 1;\n\t\tlet cur = 2;\n\t\tfor (let i = 1; i < attempt; i++) {\n\t\t\tconst next = prev + cur;\n\t\t\tprev = cur;\n\t\t\tcur = next;\n\t\t}\n\t\treturn cur;\n\t}\n\n\treturn (attempt: number) => {\n\t\tconst raw = fibUnit(attempt) * safeBase;\n\t\treturn raw <= safeMax ? raw : safeMax;\n\t};\n}\n\n/**\n * Decorrelated jitter (AWS-recommended): `random(baseNs, min(maxNs, lastDelay * 3))`.\n *\n * Stateless — uses `prevDelayNs` (passed by the consumer) instead of closure state.\n * Safe to share across concurrent retry sequences.\n *\n * @param baseNs - Floor of the random range (default `100ms` in nanoseconds).\n * @param maxNs - Ceiling cap (default `30s` in nanoseconds).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { decorrelatedJitter, retry, NS_PER_MS, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, {\n * count: 6,\n * backoff: decorrelatedJitter(100 * NS_PER_MS, 10 * NS_PER_SEC),\n * });\n * ```\n *\n * @category extra\n */\nexport function decorrelatedJitter(\n\tbaseNs = 100 * NS_PER_MS,\n\tmaxNs = 30 * NS_PER_SEC,\n): BackoffStrategy {\n\treturn (_attempt, _error, prevDelayNs) => {\n\t\tconst last = prevDelayNs ?? baseNs;\n\t\tconst ceiling = Math.min(maxNs, last * 3);\n\t\treturn randomBetween(baseNs, ceiling);\n\t};\n}\n\n/**\n * Decorator that caps any strategy at `maxAttempts`. Returns `null` (stop retrying) after the cap.\n *\n * @param strategy - Inner strategy to wrap.\n * @param maxAttempts - Maximum number of attempts (inclusive).\n * @returns Wrapped `BackoffStrategy`.\n *\n * @example\n * ```ts\n * import { withMaxAttempts, exponential } from \"@graphrefly/graphrefly-ts\";\n *\n * const capped = withMaxAttempts(exponential(), 3);\n * capped(3); // null — no more retries beyond attempt 3\n * ```\n *\n * @category extra\n */\nexport function withMaxAttempts(strategy: BackoffStrategy, maxAttempts: number): BackoffStrategy {\n\treturn (attempt, error, prevDelayNs) => {\n\t\tif (attempt >= maxAttempts) return null;\n\t\treturn strategy(attempt, error, prevDelayNs);\n\t};\n}\n\n/**\n * Maps a preset name to a concrete {@link BackoffStrategy} with library-default parameters.\n *\n * @param name - One of `constant`, `linear`, `exponential`, `fibonacci`, or `decorrelatedJitter`.\n * @returns Configured strategy with default parameters.\n * @throws Error when `name` is not a known preset.\n *\n * @example\n * ```ts\n * import { resolveBackoffPreset, retry } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: resolveBackoffPreset(\"exponential\") });\n * // Equivalent to retry(source, { count: 3, backoff: exponential() })\n * ```\n *\n * @category extra\n */\nexport function resolveBackoffPreset(name: BackoffPreset): BackoffStrategy {\n\tif (name === \"constant\") return constant(1 * NS_PER_SEC);\n\tif (name === \"linear\") return linear(1 * NS_PER_SEC);\n\tif (name === \"exponential\") return exponential();\n\tif (name === \"fibonacci\") return fibonacci();\n\tif (name === \"decorrelatedJitter\") return decorrelatedJitter();\n\tthrow new Error(\n\t\t`Unknown backoff preset: \"${String(name)}\". Use one of: constant, linear, exponential, fibonacci, decorrelatedJitter`,\n\t);\n}\n","/**\n * Timeout — emits `ERROR` with `TimeoutError` if no `DATA` arrives within the deadline.\n *\n * §3.1c — caching, fallback & composition sugar. Uses\n * `core/clock.js`-style nanoseconds and a `ResettableTimer` so the deadline\n * resets on each DATA. Distinct from the `operators/control.ts` timeout\n * (which forwards a caller-supplied error/value) — this one is the\n * resilience family's \"deadline → ERROR\" primitive.\n *\n * **DS-13.5.B (locked 2026-05-01).** Pre-1.0 break: returns\n * {@link TimeoutBundle} with `node` + `timeoutState` companion. Opts\n * accept `Partial<TimeoutOptions>` or `Node<Partial<TimeoutOptions>>`\n * (object-shape, replacing the old `NodeOrValue<number>` flat shape).\n * State preservation across rebind: `ns` change does NOT reset the\n * in-flight deadline — new `ns` applies to next attempt only.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\tmonotonicNs,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport { isNode, operatorOpts } from \"./_internal.js\";\nimport { NS_PER_MS } from \"./backoff.js\";\n\n/**\n * Thrown by {@link withTimeout} when no `DATA` arrives within the deadline.\n *\n * @category extra\n */\nexport class TimeoutError extends Error {\n\toverride name = \"TimeoutError\";\n\tconstructor(ns: number) {\n\t\tsuper(`Timed out after ${ns / NS_PER_MS}ms`);\n\t}\n}\n\n/**\n * Options accepted by {@link withTimeout}.\n *\n * - `ns` — deadline in nanoseconds (must be `> 0`). Required at the\n * first opts settle; missing / non-positive values throw at\n * construction.\n * - `meta` — optional metadata merged onto the result node's `meta`\n * for describe()/explain() introspection. Reactive `meta` updates\n * are picked up on the next attempt's emission.\n *\n * @category extra/resilience\n */\nexport interface TimeoutOptions {\n\tns: number;\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Lifecycle-shaped state companion emitted by {@link withTimeout}.\n *\n * Default `equals` dedups on the `status` field — subscribers don't\n * re-fire on identical-shape transitions, but DO fire on every state\n * transition AND on payload changes within the same status (e.g. when\n * `running.startedAt_ns` advances on a fresh attempt).\n *\n * @category extra/resilience\n */\nexport type TimeoutState =\n\t| { status: \"pending\" }\n\t| { status: \"running\"; startedAt_ns: number; deadline_ns: number }\n\t| { status: \"completed\"; settledAt_ns: number }\n\t| { status: \"errored\"; firedAt_ns: number; deadline_ns: number };\n\n/**\n * Bundle returned by {@link withTimeout}: the timeout-wrapped output node and\n * its lifecycle-shaped state companion.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `timeoutState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `timeoutState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `timeoutState`, which can flip\n * between states from different in-flight machines. Don't fan out\n * `node` to multiple subscribers and rely on `timeoutState` accuracy\n * unless you use {@link keepalive} / {@link share}-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface TimeoutBundle<T> {\n\tnode: Node<T>;\n\ttimeoutState: Node<TimeoutState>;\n}\n\ninterface TimeoutExtraOpts {\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Wrap `source` with a deadline. If no `DATA` arrives within `opts.ns`\n * nanoseconds, the result node emits `[[ERROR, TimeoutError]]` and\n * transitions `timeoutState` to `\"errored\"`.\n *\n * The timer starts on subscription and resets on each `DATA`. `DIRTY`\n * does NOT reset the timer. Terminal messages (`COMPLETE` / `ERROR`)\n * cancel the timer.\n *\n * **Reactive opts (DS-13.5.B, locked 2026-05-01).**\n *\n * - Static-form callers pass `Partial<TimeoutOptions>` (today's path).\n * `ns` is validated at construction; missing / non-positive throws\n * `RangeError`.\n * - Reactive-form callers pass `Node<Partial<TimeoutOptions>>` — each\n * emission shallow-merges over the prior opts. Empty `{}` emissions\n * are no-ops (no rebind, no companion fire). Mid-flight opts swap\n * does NOT reset the in-flight deadline; new `ns` applies to the\n * next `startTimer()` call.\n * - When the opts Node has `cache === undefined` (SENTINEL: no opts\n * emitted yet), the source is paused until the first valid opts\n * settle. The first valid settle must carry `ns > 0` or the timer\n * layer emits an ERROR (downstream observable) — distinct from the\n * construction-time `RangeError` thrown for static / cache-defined\n * invalid values.\n *\n * @param source - Upstream node.\n * @param opts - `Partial<TimeoutOptions>` (static) or\n * `Node<Partial<TimeoutOptions>>` (reactive).\n * @param extraOpts - Forwarded factory metadata (meta field merged\n * onto the result node).\n * @returns {@link TimeoutBundle} with `node` and `timeoutState`.\n *\n * @throws {RangeError} when the first opts settle is missing or has\n * non-positive `ns`.\n *\n * @category extra\n */\nexport function withTimeout<T>(\n\tsource: Node<T>,\n\topts: Partial<TimeoutOptions> | Node<Partial<TimeoutOptions>>,\n\textraOpts?: TimeoutExtraOpts,\n): TimeoutBundle<T> {\n\tconst isReactive = isNode(opts);\n\n\t// Construction-time validation:\n\t// - Static form: validate the supplied object eagerly.\n\t// - Node form with defined cache: validate the cache value eagerly.\n\t// - Node form with `cache === undefined`: defer validation to first\n\t// DATA emission; source is paused in the meantime.\n\tlet latestOpts: TimeoutOptions | null = null;\n\tif (!isReactive) {\n\t\tconst staticOpts = opts as Partial<TimeoutOptions>;\n\t\tif (\n\t\t\tstaticOpts.ns === undefined ||\n\t\t\ttypeof staticOpts.ns !== \"number\" ||\n\t\t\t!Number.isFinite(staticOpts.ns) ||\n\t\t\tstaticOpts.ns <= 0\n\t\t) {\n\t\t\tthrow new RangeError(\"withTimeout: opts.ns must be a positive finite number\");\n\t\t}\n\t\tlatestOpts = {\n\t\t\tns: staticOpts.ns,\n\t\t\t...(staticOpts.meta != null ? { meta: staticOpts.meta } : {}),\n\t\t};\n\t} else {\n\t\tconst cached = (opts as Node<Partial<TimeoutOptions>>).cache as\n\t\t\t| Partial<TimeoutOptions>\n\t\t\t| undefined;\n\t\tif (cached !== undefined) {\n\t\t\tif (\n\t\t\t\tcached.ns === undefined ||\n\t\t\t\ttypeof cached.ns !== \"number\" ||\n\t\t\t\t!Number.isFinite(cached.ns) ||\n\t\t\t\tcached.ns <= 0\n\t\t\t) {\n\t\t\t\tthrow new RangeError(\n\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tlatestOpts = {\n\t\t\t\tns: cached.ns,\n\t\t\t\t...(cached.meta != null ? { meta: cached.meta } : {}),\n\t\t\t};\n\t\t}\n\t}\n\n\tconst callerMeta = extraOpts?.meta;\n\tconst factoryArgs: Record<string, unknown> = isReactive\n\t\t? { ns: \"Node<Partial<TimeoutOptions>>\" }\n\t\t: { ns: latestOpts!.ns };\n\n\t// Companion state node — lifecycle-shaped. Default Object.is-on-status\n\t// dedup so identical-shape transitions don't re-fire downstream.\n\tconst timeoutState = node<TimeoutState>([], {\n\t\tname: \"timeoutState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\" },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\t(a as { status: string }).status === (b as { status: string }).status &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\n\tconst out = node<T>(\n\t\t(_data, a) => {\n\t\t\tlet stopped = false;\n\t\t\tlet lastDeadlineNs = 0;\n\t\t\tconst timer = new ResettableTimer();\n\t\t\tlet optsUnsub: (() => void) | null = null;\n\t\t\tlet srcUnsub: (() => void) | null = null;\n\n\t\t\tfunction emitState(next: TimeoutState): void {\n\t\t\t\ttimeoutState.down([[DIRTY], [DATA, next]]);\n\t\t\t}\n\n\t\t\tfunction startTimer(): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\t// QA A4 (2026-05-03): defensive guard — `latestOpts.ns`\n\t\t\t\t// reaching `undefined` / `NaN` / non-finite is a Class-of-\n\t\t\t\t// bugs source: an explicit `{ ns: undefined }` emit would\n\t\t\t\t// pass the per-key validation (which only checks\n\t\t\t\t// `next.ns !== undefined`) and shallow-merge over a valid\n\t\t\t\t// prior `ns`. Without this guard, `delayMs = NaN`, which\n\t\t\t\t// `setTimeout` treats as `0` → spurious immediate timeout.\n\t\t\t\tif (\n\t\t\t\t\tlatestOpts == null ||\n\t\t\t\t\ttypeof latestOpts.ns !== \"number\" ||\n\t\t\t\t\t!Number.isFinite(latestOpts.ns) ||\n\t\t\t\t\tlatestOpts.ns <= 0\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst ns = latestOpts.ns;\n\t\t\t\tlastDeadlineNs = ns;\n\t\t\t\tconst startedAt = monotonicNs();\n\t\t\t\tconst delayMs = ns / NS_PER_MS;\n\t\t\t\temitState({\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\tstartedAt_ns: startedAt,\n\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t});\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tsrcUnsub?.();\n\t\t\t\t\temitState({\n\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t\t});\n\t\t\t\t\ta.down([[ERROR, new TimeoutError(ns)]]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction attachSource(): void {\n\t\t\t\tif (srcUnsub != null || stopped) return;\n\t\t\t\tsrcUnsub = source.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (stopped) return;\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tstartTimer();\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\t\tsettledAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t\tdeadline_ns: lastDeadlineNs,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t// Kick the initial timer if we already have valid opts.\n\t\t\t\tif (latestOpts != null && latestOpts.ns > 0) {\n\t\t\t\t\tstartTimer();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isReactive) {\n\t\t\t\tconst optsNode = opts as Node<Partial<TimeoutOptions>>;\n\t\t\t\toptsUnsub = optsNode.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\t\tconst next = m[1] as Partial<TimeoutOptions>;\n\t\t\t\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\t\t\t\t// Empty `{}` emit is a no-op (lock spec).\n\t\t\t\t\t\tconst keys = Object.keys(next);\n\t\t\t\t\t\tif (keys.length === 0) continue;\n\t\t\t\t\t\t// QA A4 (2026-05-03): validate ns whenever it APPEARS\n\t\t\t\t\t\t// in the emit's keys — including `{ ns: undefined }`,\n\t\t\t\t\t\t// which would otherwise skip validation and shallow-\n\t\t\t\t\t\t// merge over a valid prior `ns` with `undefined`,\n\t\t\t\t\t\t// producing `delayMs = NaN` ≈ 0 ms in startTimer().\n\t\t\t\t\t\t// `'ns' in next` covers both \"explicitly undefined\"\n\t\t\t\t\t\t// and \"explicitly invalid\" forms.\n\t\t\t\t\t\tif (\"ns\" in next) {\n\t\t\t\t\t\t\tif (typeof next.ns !== \"number\" || !Number.isFinite(next.ns) || next.ns <= 0) {\n\t\t\t\t\t\t\t\tif (latestOpts == null) {\n\t\t\t\t\t\t\t\t\t// First settle invalid — emit ERROR rather\n\t\t\t\t\t\t\t\t\t// than throw (mid-subscribe; sync throw\n\t\t\t\t\t\t\t\t\t// would corrupt the host scheduler).\n\t\t\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\t\t\ta.down([\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\tERROR,\n\t\t\t\t\t\t\t\t\t\t\tnew RangeError(\n\t\t\t\t\t\t\t\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Ignore invalid mid-flight ns updates; keep\n\t\t\t\t\t\t\t\t// prior latestOpts.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst wasNull = latestOpts == null;\n\t\t\t\t\t\tlatestOpts = {\n\t\t\t\t\t\t\t...(latestOpts ?? { ns: 0 }),\n\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t} as TimeoutOptions;\n\t\t\t\t\t\t// First valid settle activates the source attach.\n\t\t\t\t\t\tif (wasNull && latestOpts.ns > 0) {\n\t\t\t\t\t\t\tattachSource();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Static form: attach immediately. Reactive form with defined\n\t\t\t// cache also attaches immediately (latestOpts pre-populated).\n\t\t\tif (latestOpts != null) {\n\t\t\t\tattachSource();\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tstopped = true;\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tif (srcUnsub) srcUnsub();\n\t\t\t\t\tif (optsUnsub) optsUnsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: { ...(callerMeta ?? {}), ...factoryTag(\"withTimeout\", factoryArgs) },\n\t\t},\n\t);\n\n\treturn { node: out, timeoutState };\n}\n","/**\n * Harness presets — opinionated compositions of harness + ai utils.\n *\n * @module\n */\n\nexport * from \"./actor-pool.js\";\nexport * from \"./eval-verifier.js\";\nexport * from \"./harness-loop.js\";\nexport * from \"./ownership-controller.js\";\nexport * from \"./profile.js\";\nexport * from \"./refine-executor.js\";\nexport * from \"./refine-loop.js\";\nexport * from \"./spawnable.js\";\nexport * from \"./trace.js\";\n","/**\n * DS-14.6.A U-B — `actorPool()` (Phase 14.5).\n *\n * The dynamic-track complement to `spawnable()` (SESSION-DS-14.6-A L7/L8 +\n * 9Q walk). An actor is **identity + cursor + tool closure, NOT a subgraph**\n * (D-B1): no per-actor mount, so `describe()` shows only the pool / todo /\n * context-hub collections and the actor count drifts inside a single\n * reactive `active` map node. `depthCap` is enforced via the depth carried\n * on the attach request (D-B2); `release()` cascades teardown to the\n * actor's context view + todo cursor subscriptions (§3i — free).\n *\n * Contrast `spawnable()`: agent IS a subgraph, topology reflects the agent\n * set, `describe()`-visible — use it when agent identities are pre-known.\n * Use `actorPool()` for runtime recursive fan-out where agent count drifts.\n *\n * @module\n */\n\nimport { type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport {\n\ttype ContextEntry,\n\ttype ContextView,\n\ttype RenderedEntry,\n\trenderContextView,\n\ttype TaggedContextPoolBundle,\n\ttaggedContextPool,\n} from \"../ai/context/index.js\";\n\nexport type ActorId = string;\n\nexport interface Todo {\n\treadonly id: string;\n\treadonly assignee?: ActorId;\n\treadonly payload: unknown;\n}\n\nexport type ActorStatus = \"idle\" | \"running\" | \"blocked\" | \"done\";\n\nexport interface ActorState {\n\treadonly id: ActorId;\n\treadonly depth: number;\n\treadonly status: ActorStatus;\n}\n\nexport interface ActorSpec<T> {\n\treadonly id?: ActorId;\n\t/** Recursion depth — gated against `depthCap` (D-B2). Default 0 (root). */\n\treadonly depth?: number;\n\t/** Per-actor compression view over the shared context pool. */\n\treadonly view: Omit<ContextView<T>, \"pressure\"> & { readonly pressure: Node<number> };\n}\n\nexport interface ActorHandle<T> {\n\treadonly id: ActorId;\n\t/** This actor's compressed context slice. */\n\treadonly context: Node<readonly RenderedEntry<T>[]>;\n\t/** Todos currently assigned to this actor (or unassigned). */\n\treadonly todoCursor: Node<readonly Todo[]>;\n\t/** Write an entry into the shared pool, stamped with this actor's id tag. */\n\tpublish(entry: Omit<ContextEntry<T>, \"id\" | \"t_ns\"> & { id?: string }): string;\n\tenqueueTodo(t: Todo): void;\n\treadonly status: Node<ActorStatus>;\n\tsetStatus(s: ActorStatus): void;\n\t/** Idempotent. Tears the actor's subscriptions + removes it from `active`. */\n\trelease(): void;\n}\n\nexport interface ActorPoolOptions<T> {\n\treadonly name?: string;\n\t/**\n\t * Max recursion depth; `attachActor` with `depth > depthCap` throws.\n\t * Default: `8` (F-ACTOR, 2026-05-18 smell sweep — a finite default bounds\n\t * runaway recursive fan-out; previously silently `Infinity`). Pass an\n\t * explicit `Number.POSITIVE_INFINITY` to opt in to unbounded recursion.\n\t */\n\treadonly depthCap?: number;\n\t/** Forwarded to the backing context pool. */\n\treadonly contextTopic?: string;\n\treadonly llmCompress?: TaggedContextPoolBundle<T>[\"_opts\"][\"llmCompress\"];\n}\n\nexport interface ActorPoolBundle<T> {\n\tattachActor(spec: ActorSpec<T>): ActorHandle<T>;\n\treadonly contextPool: TaggedContextPoolBundle<T>;\n\treadonly todos: ReactiveLogBundle<Todo>;\n\t/** Single reactive map of live actors — `describe()`-coherent (D-B1). */\n\treadonly active: Node<ReadonlyMap<ActorId, ActorState>>;\n\treadonly graph: Graph;\n\tdispose(): void;\n}\n\n/** Process-wide sequence for collision-safe default mount names (QA P6). */\nlet _actorPoolSeq = 0;\n\nexport function actorPool<T = unknown>(\n\tparent: Graph,\n\topts: ActorPoolOptions<T> = {},\n): ActorPoolBundle<T> {\n\t// QA P6: collision-safe default — recursive fan-out spins nested pools\n\t// under one parent; static \"actorPool\" would collide on `parent.mount`.\n\tconst name = opts.name ?? `actorPool-${++_actorPoolSeq}`;\n\tconst graph = new Graph(name);\n\tparent.mount(name, graph);\n\tconst depthCap = opts.depthCap ?? 8;\n\t// QA P5: per-pool actor counter (was module-global → test-pollution).\n\tlet autoActor = 0;\n\t// QA P7: track live handles so dispose() can release them all.\n\tconst liveHandles = new Set<ActorHandle<T>>();\n\n\tconst contextPool = taggedContextPool<T>(graph, {\n\t\ttopic: opts.contextTopic ?? \"context\",\n\t\tllmCompress: opts.llmCompress,\n\t\tname: `${name}.ctx`,\n\t});\n\tconst todos: ReactiveLogBundle<Todo> = reactiveLog<Todo>(undefined, { name: `${name}.todos` });\n\n\t// Single reactive `active` map node — actor count drifts inside it; no\n\t// per-actor subgraph mount (D-B1, describe-coherent).\n\tconst stateMap = new Map<ActorId, ActorState>();\n\tconst active = node<ReadonlyMap<ActorId, ActorState>>([], {\n\t\tname: `${name}.active`,\n\t\tinitial: new Map(),\n\t});\n\tfunction pushActive(): void {\n\t\tactive.emit(new Map(stateMap));\n\t}\n\n\tfunction attachActor(spec: ActorSpec<T>): ActorHandle<T> {\n\t\tconst depth = spec.depth ?? 0;\n\t\tif (depth > depthCap) {\n\t\t\tthrow new RangeError(`actorPool: depth ${depth} exceeds depthCap ${depthCap}`);\n\t\t}\n\t\tconst id = spec.id ?? `actor-${++autoActor}`;\n\n\t\tconst context = renderContextView(contextPool, spec.view as ContextView<T>);\n\t\t// Per-actor todo cursor — assigned-to-me or unassigned.\n\t\tconst todoCursor = node<readonly Todo[]>(\n\t\t\t[todos.entries as Node],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\tconst all = (data[0] != null && data[0].length > 0 ? data[0].at(-1) : ctx.prevData[0]) as\n\t\t\t\t\t| readonly Todo[]\n\t\t\t\t\t| undefined;\n\t\t\t\tactions.emit((all ?? []).filter((t) => t.assignee === id || t.assignee === undefined));\n\t\t\t},\n\t\t\t{ describeKind: \"derived\" },\n\t\t);\n\t\tconst status = node<ActorStatus>([], { name: `${name}.${id}.status`, initial: \"idle\" });\n\n\t\tstateMap.set(id, { id, depth, status: \"idle\" });\n\t\tpushActive();\n\n\t\t// Keepalive subs so `.cache` stays warm; torn on release (cascade-cancel).\n\t\tconst subs = [\n\t\t\tcontext.subscribe(() => {}),\n\t\t\ttodoCursor.subscribe(() => {}),\n\t\t\tstatus.subscribe(() => {}),\n\t\t];\n\t\tlet released = false;\n\n\t\tconst handle: ActorHandle<T> = {\n\t\t\tid,\n\t\t\tcontext,\n\t\t\ttodoCursor,\n\t\t\tstatus,\n\t\t\tpublish(entry) {\n\t\t\t\tconst tags = [...(entry.tags ?? []), `actor:${id}`];\n\t\t\t\treturn contextPool.add({ ...entry, tags });\n\t\t\t},\n\t\t\tenqueueTodo(t) {\n\t\t\t\ttodos.append(t);\n\t\t\t},\n\t\t\tsetStatus(s) {\n\t\t\t\tstatus.emit(s);\n\t\t\t\tconst prev = stateMap.get(id);\n\t\t\t\tif (prev) {\n\t\t\t\t\tstateMap.set(id, { ...prev, status: s });\n\t\t\t\t\tpushActive();\n\t\t\t\t}\n\t\t\t},\n\t\t\trelease() {\n\t\t\t\tif (released) return;\n\t\t\t\treleased = true;\n\t\t\t\t// Cascade-cancel: tearing the keepalive subs deactivates the\n\t\t\t\t// per-actor derived nodes (lazy-deactivation — COMPOSITION-GUIDE\n\t\t\t\t// §1), detaching `context`/`todoCursor`/`status` from the shared\n\t\t\t\t// pool/todos logs once no other subscriber remains.\n\t\t\t\tfor (const u of subs) u();\n\t\t\t\tstateMap.delete(id);\n\t\t\t\tliveHandles.delete(handle);\n\t\t\t\tpushActive();\n\t\t\t},\n\t\t};\n\t\tliveHandles.add(handle);\n\t\treturn handle;\n\t}\n\n\treturn {\n\t\tattachActor,\n\t\tcontextPool,\n\t\ttodos,\n\t\tactive,\n\t\tgraph,\n\t\tdispose(): void {\n\t\t\t// QA P7: release outstanding actors first (tears their keepalive\n\t\t\t// subs / deactivates per-actor derived nodes) before disposing the\n\t\t\t// shared pool + todo log.\n\t\t\tfor (const h of [...liveHandles]) h.release();\n\t\t\tcontextPool.dispose();\n\t\t\ttodos.dispose();\n\t\t},\n\t};\n}\n","/**\n * DS-14.6.A U-A — tagged context substrate (Phase 14.5).\n *\n * Per-view tagged context (SESSION-DS-14.6-A L3–L6 + SESSION-DS-14.6-A-9Q\n * implementation walk). Pool stores immutable tier-0 originals on an\n * **append-only `reactiveLog`** (D-A4 — structural tier-0 immutability, free\n * `LogChange` mutations, side-steps the DS14R1 TTL/LRU prune-fidelity bug).\n * Each consumer holds a `ContextView` that materialises its own filtered +\n * compressed slice (`Node<readonly RenderedEntry[]>`). Routing is mechanical\n * tag comparison (zero LLM); only `llm-summary` rules cross to an injected\n * `llmCompress` (D-A3). Compression cache is one shared `(id, tier)` map in\n * the pool bundle, bounded LRU (D-A5). Schema is pure data, presentation\n * layer (D-A1) — no `@graphrefly/pure-ts` consumer.\n *\n * @module\n */\n\nimport { type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../../../utils/ai/_internal.js\";\n\n// ── Schema (pure data — D-A1) ────────────────────────────────────────────────\n\nexport type Tag = string;\n\n/** Compression tier. 0 = original; higher = more compressed. */\nexport type Tier = 0 | 1 | 2 | 3;\n\nexport interface ContextEntry<T> {\n\t/** Stable id — cache key component `(id, tier)`. Auto-assigned if omitted. */\n\treadonly id: string;\n\treadonly payload: T;\n\treadonly tags: readonly Tag[];\n\t/** 0..1. Budget/GC ordering. */\n\treadonly importance: number;\n\treadonly compressible: boolean;\n\treadonly topic: string;\n\t/** Wall-clock at add (ns) — used by `poolGC({ olderThanNs })`. */\n\treadonly t_ns: number;\n}\n\nexport interface RuleMatch {\n\treadonly topic?: string | RegExp;\n\treadonly tagsAny?: readonly Tag[];\n\treadonly importanceMin?: number;\n\treadonly importanceMax?: number;\n\treadonly compressible?: boolean;\n}\n\nexport type CompressionRule =\n\t| { readonly match: RuleMatch; readonly action: \"evict\" }\n\t| { readonly match: RuleMatch; readonly action: \"truncate\"; readonly maxChars: number }\n\t| { readonly match: RuleMatch; readonly action: \"reference\" }\n\t| { readonly match: RuleMatch; readonly action: \"llm-summary\"; readonly toTier: Tier };\n\nexport interface RenderedEntry<T> {\n\treadonly id: string;\n\treadonly topic: string;\n\treadonly tags: readonly Tag[];\n\treadonly tier: Tier;\n\t/** Original payload at tier 0; compressed `string` otherwise. */\n\treadonly payload: T | string;\n\treadonly compressed: boolean;\n}\n\nexport interface ContextView<T> {\n\treadonly filter: (e: ContextEntry<T>) => boolean;\n\t/** 0..1. A rule fires when `pressure > 0` and the entry matches. */\n\treadonly pressure: Node<number>;\n\treadonly budgetTokens: number;\n\treadonly rules: readonly CompressionRule[];\n\t/** Default `s => Math.ceil(s.length / 4)`. */\n\treadonly tokenizer?: (s: string) => number;\n}\n\nexport interface PoolGCPolicy {\n\t/** Drop entries with `t_ns < (now - olderThanNs)`. */\n\treadonly olderThanNs?: number;\n\t/** Drop entries with `importance < importanceBelow`. */\n\treadonly importanceBelow?: number;\n\t/**\n\t * **Scope**, not a match-to-evict rule: when set, GC only considers\n\t * entries whose `topic === this`; entries of other topics always survive.\n\t * `olderThanNs` / `importanceBelow` are ANDed *within* this scope.\n\t */\n\treadonly topic?: string;\n\t/** Keep at most this many most-recent entries. */\n\treadonly max?: number;\n}\n\n/** `(entry, toTier) => compressedText`. Injected; required iff a view uses `llm-summary`. */\nexport type LlmCompress<T> = (entry: ContextEntry<T>, toTier: Tier) => string;\n\nexport interface TaggedContextPoolOptions<T> {\n\treadonly topic: string;\n\t/** Forwarded to the backing append-only `reactiveLog` (poolGC ceiling). */\n\treadonly maxEntries?: number;\n\t/** Required iff any rendered view uses an `llm-summary` rule (D-A3). */\n\treadonly llmCompress?: LlmCompress<T>;\n\t/** Shared `(id, tier)` compression cache cap (D-A5). Default 512. */\n\treadonly cacheMax?: number;\n\treadonly name?: string;\n}\n\nexport interface TaggedContextPoolBundle<T> {\n\t/**\n\t * Append an entry (immutable tier-0). Returns its id (auto-assigned\n\t * `ctx-N` per-pool if omitted).\n\t *\n\t * **Caller-supplied ids must be unique within the pool.** The log is\n\t * append-only and does NOT dedupe; the compression cache is keyed by\n\t * `(id, tier)`, so appending two different entries with the same explicit\n\t * `id` makes the second render the first's cached summary (QA P11).\n\t */\n\tadd(entry: Omit<ContextEntry<T>, \"id\" | \"t_ns\"> & { id?: string }): string;\n\t/** All live tier-0 entries. */\n\treadonly entries: Node<readonly ContextEntry<T>[]>;\n\t/** Entries carrying `tag`. */\n\tbyTag(tag: Tag): Node<readonly ContextEntry<T>[]>;\n\t/** Pool-global retention (L6 — distinct from per-view filtering). Returns removed count. */\n\tpoolGC(policy: PoolGCPolicy): number;\n\treadonly graph: Graph;\n\t/** Internal — shared compression cache (one per pool, D-A5). */\n\treadonly _cache: CompressionCache;\n\treadonly _opts: TaggedContextPoolOptions<T>;\n\tdispose(): void;\n}\n\n// ── Shared bounded (id,tier) compression cache (D-A5) ────────────────────────\n\n/**\n * Bounded LRU cache keyed by `(id, tier)`. Uses a nested `Map<id, Map<tier,\n * value>>` (NOT a `${id}::${tier}` string key) so a caller-supplied `id`\n * containing the separator cannot collide (QA P5). LRU is tracked at the\n * (id,tier) leaf via a flat insertion-order key list.\n */\nexport class CompressionCache {\n\tprivate readonly _m = new Map<string, Map<Tier, string>>();\n\t/** Insertion-order list of `id` keys for LRU eviction at the id granularity. */\n\tprivate readonly _order: string[] = [];\n\tconstructor(private readonly _max: number) {}\n\tget(id: string, tier: Tier): string | undefined {\n\t\tconst inner = this._m.get(id);\n\t\tconst v = inner?.get(tier);\n\t\tif (v !== undefined) {\n\t\t\tconst i = this._order.indexOf(id);\n\t\t\tif (i >= 0) this._order.splice(i, 1);\n\t\t\tthis._order.push(id);\n\t\t}\n\t\treturn v;\n\t}\n\tset(id: string, tier: Tier, value: string): void {\n\t\tlet inner = this._m.get(id);\n\t\tif (inner === undefined) {\n\t\t\tinner = new Map<Tier, string>();\n\t\t\tthis._m.set(id, inner);\n\t\t}\n\t\tinner.set(tier, value);\n\t\tconst i = this._order.indexOf(id);\n\t\tif (i >= 0) this._order.splice(i, 1);\n\t\tthis._order.push(id);\n\t\twhile (this._m.size > this._max) {\n\t\t\tconst evict = this._order.shift();\n\t\t\tif (evict === undefined) break;\n\t\t\tthis._m.delete(evict);\n\t\t}\n\t}\n}\n\n// ── Pool ─────────────────────────────────────────────────────────────────────\n\n/** Process-wide sequence for collision-safe default mount names (QA P6). */\nlet _poolSeq = 0;\n\n/**\n * Append-only tagged context pool (D-A4). The pool is a `reactiveLog` of\n * immutable tier-0 entries plus a derived `entries` node; `byTag` derives a\n * filtered view; `poolGC` is the explicit pool-global retention (L6).\n */\nexport function taggedContextPool<T>(\n\tparent: Graph,\n\topts: TaggedContextPoolOptions<T>,\n): TaggedContextPoolBundle<T> {\n\t// QA P6: collision-safe default mount name — two pools with the same\n\t// `topic` under one parent must not collide on `parent.mount`. Explicit\n\t// `opts.name` is respected verbatim (caller owns uniqueness then).\n\tconst mountName = opts.name ?? `ctxpool-${opts.topic}-${++_poolSeq}`;\n\tconst graph = new Graph(mountName);\n\tparent.mount(mountName, graph);\n\n\tconst log: ReactiveLogBundle<ContextEntry<T>> = reactiveLog<ContextEntry<T>>(undefined, {\n\t\tname: `${mountName}.log`,\n\t\tmaxSize: opts.maxEntries,\n\t});\n\tconst cache = new CompressionCache(opts.cacheMax ?? 512);\n\t// QA P5: per-pool id counter (was module-global → test-pollution +\n\t// cross-pool cache-key cross-talk).\n\tlet autoId = 0;\n\n\tconst entries: Node<readonly ContextEntry<T>[]> = log.entries;\n\n\tfunction add(e: Omit<ContextEntry<T>, \"id\" | \"t_ns\"> & { id?: string }): string {\n\t\tconst id = e.id ?? `ctx-${++autoId}`;\n\t\tlog.append({\n\t\t\tid,\n\t\t\tpayload: e.payload,\n\t\t\ttags: e.tags,\n\t\t\timportance: e.importance,\n\t\t\tcompressible: e.compressible,\n\t\t\ttopic: e.topic,\n\t\t\tt_ns: wallClockNs(), // QA P2 — clock.ts invariant (was Date.now()*1e6)\n\t\t});\n\t\treturn id;\n\t}\n\n\tfunction byTag(tag: Tag): Node<readonly ContextEntry<T>[]> {\n\t\treturn node<readonly ContextEntry<T>[]>(\n\t\t\t[entries as Node],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\tconst cur = (data[0] != null && data[0].length > 0 ? data[0].at(-1) : ctx.prevData[0]) as\n\t\t\t\t\t| readonly ContextEntry<T>[]\n\t\t\t\t\t| undefined;\n\t\t\t\tactions.emit((cur ?? []).filter((x) => x.tags.includes(tag)));\n\t\t\t},\n\t\t\t{ describeKind: \"derived\", meta: aiMeta(\"contextPool.byTag\", { tag }) },\n\t\t);\n\t}\n\n\tfunction poolGC(policy: PoolGCPolicy): number {\n\t\tconst all = log.entries.cache ?? [];\n\t\tconst nowNs = wallClockNs();\n\t\tlet survivors = all.filter((e) => {\n\t\t\t// QA P1: `topic` is a SCOPE, not a match-to-evict rule — entries\n\t\t\t// outside the topic are never GC'd by this call; eviction criteria\n\t\t\t// (olderThanNs / importanceBelow) are ANDed within the scope.\n\t\t\tif (policy.topic != null && e.topic !== policy.topic) return true;\n\t\t\tif (policy.olderThanNs != null && nowNs - e.t_ns >= policy.olderThanNs) return false;\n\t\t\tif (policy.importanceBelow != null && e.importance < policy.importanceBelow) return false;\n\t\t\treturn true;\n\t\t});\n\t\tif (policy.max != null && survivors.length > policy.max) {\n\t\t\tsurvivors = survivors.slice(survivors.length - policy.max);\n\t\t}\n\t\tconst removed = all.length - survivors.length;\n\t\tif (removed > 0) {\n\t\t\tlog.clear();\n\t\t\tlog.appendMany(survivors);\n\t\t}\n\t\treturn removed;\n\t}\n\n\treturn {\n\t\tadd,\n\t\tentries,\n\t\tbyTag,\n\t\tpoolGC,\n\t\tgraph,\n\t\t_cache: cache,\n\t\t_opts: opts,\n\t\tdispose(): void {\n\t\t\tlog.dispose();\n\t\t},\n\t};\n}\n\n// ── tierCompress + renderContextView ─────────────────────────────────────────\n\nconst DEFAULT_TOKENIZER = (s: string): number => Math.ceil(s.length / 4);\n\nfunction matches(e: ContextEntry<unknown>, m: RuleMatch): boolean {\n\tif (m.topic != null) {\n\t\tif (typeof m.topic === \"string\" ? e.topic !== m.topic : !m.topic.test(e.topic)) return false;\n\t}\n\tif (m.tagsAny != null && !m.tagsAny.some((t) => e.tags.includes(t))) return false;\n\tif (m.importanceMin != null && e.importance < m.importanceMin) return false;\n\tif (m.importanceMax != null && e.importance > m.importanceMax) return false;\n\tif (m.compressible != null && e.compressible !== m.compressible) return false;\n\treturn true;\n}\n\n/**\n * Apply the first matching rule to one entry under `pressure`. Non-LLM\n * strategies (truncate / evict / reference) are pure data; `llm-summary`\n * calls the injected `llmCompress`, caching by `(id, toTier)` (D-A5).\n * Returns `undefined` for evicted / pressure-filtered entries.\n */\nexport function tierCompress<T>(\n\te: ContextEntry<T>,\n\trules: readonly CompressionRule[],\n\tpressure: number,\n\tcache: CompressionCache,\n\tllmCompress?: LlmCompress<T>,\n): RenderedEntry<T> | undefined {\n\tconst base: RenderedEntry<T> = {\n\t\tid: e.id,\n\t\ttopic: e.topic,\n\t\ttags: e.tags,\n\t\ttier: 0,\n\t\tpayload: e.payload,\n\t\tcompressed: false,\n\t};\n\tif (pressure <= 0) return base;\n\tfor (const rule of rules) {\n\t\tif (!matches(e, rule.match)) continue;\n\t\tswitch (rule.action) {\n\t\t\tcase \"evict\":\n\t\t\t\treturn undefined;\n\t\t\tcase \"reference\":\n\t\t\t\treturn { ...base, tier: 1, payload: `[ref:${e.id}]`, compressed: true };\n\t\t\tcase \"truncate\": {\n\t\t\t\tconst s = typeof e.payload === \"string\" ? e.payload : JSON.stringify(e.payload);\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttier: 1,\n\t\t\t\t\tpayload: s.length > rule.maxChars ? s.slice(0, rule.maxChars) : s,\n\t\t\t\t\tcompressed: s.length > rule.maxChars,\n\t\t\t\t};\n\t\t\t}\n\t\t\tcase \"llm-summary\": {\n\t\t\t\tif (!llmCompress) {\n\t\t\t\t\t// Defence-in-depth — construction guard should have thrown.\n\t\t\t\t\tthrow new Error(\"tierCompress: 'llm-summary' rule requires `llmCompress`\");\n\t\t\t\t}\n\t\t\t\tconst cached = cache.get(e.id, rule.toTier);\n\t\t\t\tconst text = cached ?? llmCompress(e, rule.toTier);\n\t\t\t\tif (cached === undefined) cache.set(e.id, rule.toTier, text);\n\t\t\t\treturn { ...base, tier: rule.toTier, payload: text, compressed: true };\n\t\t\t}\n\t\t}\n\t}\n\treturn base;\n}\n\n/**\n * Per-consumer reactive rendering (D-A2). Materialises a\n * `Node<readonly RenderedEntry[]>` over the pool: filter → per-entry rule\n * application under `pressure` → token-budget trim (lowest-importance first).\n *\n * Recomputes the slice per `(entries | pressure)` wave (O(n) — behaviourally\n * identical to the incremental closure-mirror; incremental is a perf\n * follow-up, not a correctness gap).\n *\n * @throws if any rule is `llm-summary` and the pool has no `llmCompress`\n * (D-A3 construction guard).\n */\nexport function renderContextView<T>(\n\tpool: TaggedContextPoolBundle<T>,\n\tview: ContextView<T>,\n): Node<readonly RenderedEntry<T>[]> {\n\tconst usesLlm = view.rules.some((r) => r.action === \"llm-summary\");\n\tif (usesLlm && !pool._opts.llmCompress) {\n\t\tthrow new Error(\n\t\t\t\"renderContextView: view has an 'llm-summary' rule but the pool was created without `llmCompress` (DS-14.6.A D-A3).\",\n\t\t);\n\t}\n\tconst tokenize = view.tokenizer ?? DEFAULT_TOKENIZER;\n\tconst llmCompress = pool._opts.llmCompress;\n\n\treturn node<readonly RenderedEntry<T>[]>(\n\t\t[pool.entries as Node, view.pressure as Node],\n\t\t(data, actions, ctx) => {\n\t\t\tconst entries = (data[0] != null && data[0].length > 0 ? data[0].at(-1) : ctx.prevData[0]) as\n\t\t\t\t| readonly ContextEntry<T>[]\n\t\t\t\t| undefined;\n\t\t\tconst pressure = (data[1] != null && data[1].length > 0 ? data[1].at(-1) : ctx.prevData[1]) as\n\t\t\t\t| number\n\t\t\t\t| undefined;\n\t\t\tif (entries === undefined) {\n\t\t\t\tactions.emit([]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst p = pressure ?? 0;\n\t\t\tconst rendered: RenderedEntry<T>[] = [];\n\t\t\tfor (const e of entries) {\n\t\t\t\tif (!view.filter(e)) continue;\n\t\t\t\tconst r = tierCompress(e, view.rules, p, pool._cache, llmCompress);\n\t\t\t\tif (r !== undefined) rendered.push(r);\n\t\t\t}\n\t\t\t// Token-budget trim: drop lowest-importance entries until under budget.\n\t\t\tconst cost = (r: RenderedEntry<T>): number =>\n\t\t\t\ttokenize(typeof r.payload === \"string\" ? r.payload : JSON.stringify(r.payload));\n\t\t\tlet total = 0;\n\t\t\tfor (const r of rendered) total += cost(r);\n\t\t\tif (total > view.budgetTokens) {\n\t\t\t\tconst byImp = entries.reduce<Map<string, number>>(\n\t\t\t\t\t(acc, e) => acc.set(e.id, e.importance),\n\t\t\t\t\tnew Map(),\n\t\t\t\t);\n\t\t\t\trendered.sort((a, b) => (byImp.get(a.id) ?? 0) - (byImp.get(b.id) ?? 0));\n\t\t\t\twhile (total > view.budgetTokens && rendered.length > 0) {\n\t\t\t\t\ttotal -= cost(rendered.shift() as RenderedEntry<T>);\n\t\t\t\t}\n\t\t\t}\n\t\t\tactions.emit(rendered);\n\t\t},\n\t\t{ describeKind: \"derived\", meta: aiMeta(\"contextView\", { topic: pool._opts.topic }) },\n\t);\n}\n","/**\n * @internal — shared helpers for the AI pattern modules.\n *\n * NOT part of the public API. Consumers reach public symbols through\n * `@graphrefly/graphrefly/utils/ai` (the barrel).\n *\n * @module\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\tnode,\n\tResettableTimer,\n} from \"@graphrefly/pure-ts/core\";\nimport { fromAny, type NodeInput } from \"@graphrefly/pure-ts/extra\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n} from \"./adapters/core/types.js\";\n\nexport function aiMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"ai\", kind, extra);\n}\n\nexport function isPromiseLike(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nexport function isNodeLike(x: unknown): x is Node<unknown> {\n\treturn (\n\t\ttypeof x === \"object\" &&\n\t\tx !== null &&\n\t\t\"subscribe\" in x &&\n\t\ttypeof (x as Node<unknown>).subscribe === \"function\" &&\n\t\t\"cache\" in x\n\t);\n}\n\nexport function isAsyncIterableLike(x: unknown): x is AsyncIterable<unknown> {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\tSymbol.asyncIterator in x &&\n\t\ttypeof (x as AsyncIterable<unknown>)[Symbol.asyncIterator] === \"function\"\n\t);\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** First settled `DATA` from a `Node` (do not pass plain strings — `fromAny` would iterate chars). */\nexport function firstDataFromNode(\n\tresolved: Node<unknown>,\n\topts?: { timeoutMs?: number },\n): Promise<unknown> {\n\tif ((resolved as { status?: string }).status === \"settled\") {\n\t\tconst immediate = resolved.cache;\n\t\tif (immediate !== undefined) {\n\t\t\treturn Promise.resolve(immediate);\n\t\t}\n\t}\n\tconst timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\treturn new Promise((resolve, reject) => {\n\t\tconst timer = new ResettableTimer();\n\t\tconst unsub = resolved.subscribe((messages) => {\n\t\t\tfor (const msg of messages) {\n\t\t\t\tif (msg[0] === DATA) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\tresolve(msg[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (msg[0] === ERROR) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\treject(msg[1]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (msg[0] === COMPLETE) {\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tunsub();\n\t\t\t\t\treject(new Error(\"firstDataFromNode: completed without producing a value\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\ttimer.start(timeoutMs, () => {\n\t\t\tunsub();\n\t\t\treject(new Error(`firstDataFromNode: timed out after ${timeoutMs}ms`));\n\t\t});\n\t});\n}\n\n/** Await Promise-likes, then resolve `Node` / async-iterable inputs via `fromAny` + first `DATA`. */\nexport async function resolveToolHandlerResult(value: unknown): Promise<unknown> {\n\tif (isPromiseLike(value)) {\n\t\treturn resolveToolHandlerResult(await value);\n\t}\n\tif (isNodeLike(value)) {\n\t\treturn firstDataFromNode(value);\n\t}\n\tif (isAsyncIterableLike(value)) {\n\t\treturn firstDataFromNode(fromAny(value as NodeInput<unknown>));\n\t}\n\treturn value;\n}\n\n/** Strip markdown code fences, handling trailing commentary after closing fence. */\nexport function stripFences(text: string): string {\n\tconst match = text.match(/^```(?:json)?\\s*([\\s\\S]*?)\\s*```[\\s\\S]*$/);\n\treturn match ? match[1]! : text;\n}\n\n/**\n * Bridge-layer failure kind reported to {@link OneShotLlmCallConfig.onFailure}.\n *\n * - `\"throw\"` — synchronous throw from `adapter.invoke()`.\n * - `\"error\"` — `[ERROR, value]` message on the bridged Node.\n * - `\"complete\"` — the bridged Node closed without emitting DATA.\n * - `\"onSuccess-threw\"` — `onSuccess(resp)` itself threw (uncaught parse /\n * builder error). Caller's `onFailure` decides the failure-payload shape.\n */\nexport type OneShotLlmFailureKind = \"throw\" | \"error\" | \"complete\" | \"onSuccess-threw\";\n\n/** Configuration for {@link _oneShotLlmCall}. */\nexport interface OneShotLlmCallConfig<T> {\n\t/**\n\t * Build the success payload from the adapter's first DATA message.\n\t * MAY throw — the helper catches and routes through `onFailure(kind:\n\t * \"onSuccess-threw\", err)` so callers don't need their own try/catch.\n\t */\n\tonSuccess: (resp: LLMResponse) => T;\n\t/**\n\t * Build a failure payload when the bridge layer reports any of the\n\t * {@link OneShotLlmFailureKind} categories. Caller chooses the detail\n\t * string format and any error-class metadata.\n\t */\n\tonFailure: (kind: OneShotLlmFailureKind, err: unknown) => T;\n\t/**\n\t * Forwarded to `adapter.invoke(messages, opts)` — `signal` is set\n\t * by the helper from the producer's AbortController and CANNOT be\n\t * overridden here (cancellation is a hard contract of this helper).\n\t */\n\tinvokeOpts?: Omit<LLMInvokeOptions, \"signal\">;\n\t/**\n\t * Optional parent abort signal (e.g. JobFlow pump's per-claim signal).\n\t * When the parent aborts, the helper aborts its inner AbortController —\n\t * so `adapter.invoke({ signal })` and `fromAny({ signal })` see the\n\t * cascade and cancel in-flight work. Pump-driven harness teardown\n\t * (`harness.destroy()`) propagates through this hook (Tier 6.5 2.5b).\n\t */\n\tparentSignal?: AbortSignal;\n}\n\n/**\n * Internal — one-shot bridge from `adapter.invoke()` (a `NodeInput<LLMResponse>`)\n * into a producer that emits exactly one DATA + COMPLETE.\n *\n * **Why this exists.** The harness's `defaultLlmExecutor` and\n * `defaultLlmVerifier` (Tier 6.5 C2) both call `adapter.invoke()` once\n * per claimed JobFlow job and need to:\n * 1. Subscribe to the bridged Node, capture the first DATA, parse, emit\n * a domain payload.\n * 2. Map adapter throws / ERROR / COMPLETE-without-DATA to a domain\n * failure payload (rather than nack the JobFlow claim).\n * 3. Thread `signal: ac.signal` into BOTH `adapter.invoke()` (via\n * `LLMInvokeOptions.signal`) and `fromAny()` (covers Node-shaped\n * invokeResults) so teardown actually aborts in-flight HTTP work.\n * 4. Tear down the inner subscription cleanly when DATA captures or\n * when the producer is unsubscribed.\n *\n * Pre-extraction this body was duplicated ~80 LOC across the two default\n * bridges; symmetric fixes had to land twice (qa F1 / F2 / F5). This\n * helper centralizes the producer body so future bridge-layer fixes apply\n * once.\n *\n * **Not part of the public API.** Callers in `patterns/ai/_internal.ts`'s\n * import surface (the harness defaults today) use this; user code should\n * use `promptNode` for cross-wave reactive transforms or call\n * `adapter.invoke()` directly.\n */\nexport function _oneShotLlmCall<T>(\n\tadapter: LLMAdapter,\n\tmessages: readonly ChatMessage[],\n\tconfig: OneShotLlmCallConfig<T>,\n): NodeInput<T> {\n\treturn node<T>(\n\t\t(_data, actions) => {\n\t\t\tconst ac = new AbortController();\n\t\t\t// Link parent signal (e.g. pump per-claim signal) so cascading\n\t\t\t// teardown propagates: parent abort → inner ac.abort → adapter +\n\t\t\t// fromAny cancel.\n\t\t\tconst parentSignal = config.parentSignal;\n\t\t\tlet unlinkParent: () => void = () => undefined;\n\t\t\tif (parentSignal) {\n\t\t\t\tif (parentSignal.aborted) {\n\t\t\t\t\tac.abort();\n\t\t\t\t} else {\n\t\t\t\t\tconst onParentAbort = (): void => ac.abort();\n\t\t\t\t\tparentSignal.addEventListener(\"abort\", onParentAbort, { once: true });\n\t\t\t\t\tunlinkParent = () => parentSignal.removeEventListener(\"abort\", onParentAbort);\n\t\t\t\t}\n\t\t\t}\n\t\t\tlet captured = false;\n\t\t\tlet unsub: (() => void) | null = null;\n\t\t\tconst emitOnce = (value: T): void => {\n\t\t\t\tif (captured) return;\n\t\t\t\tcaptured = true;\n\t\t\t\tactions.down([[DATA, value], [COMPLETE]] satisfies Messages);\n\t\t\t\tunsub?.();\n\t\t\t\tunsub = null;\n\t\t\t};\n\t\t\tlet invokeResult: NodeInput<LLMResponse>;\n\t\t\ttry {\n\t\t\t\tinvokeResult = adapter.invoke(messages, { ...config.invokeOpts, signal: ac.signal });\n\t\t\t} catch (err) {\n\t\t\t\temitOnce(config.onFailure(\"throw\", err));\n\t\t\t\treturn {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tunlinkParent();\n\t\t\t\t\t\tac.abort();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst callNode = fromAny<LLMResponse>(invokeResult, { signal: ac.signal });\n\t\t\tunsub = callNode.subscribe((batch) => {\n\t\t\t\tfor (const m of batch) {\n\t\t\t\t\tif (captured) return;\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\temitOnce(config.onSuccess(m[1] as LLMResponse));\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\temitOnce(config.onFailure(\"onSuccess-threw\", err));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\t\temitOnce(config.onFailure(\"error\", m[1]));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\t\t// COMPLETE without prior DATA — without this arm the JobFlow\n\t\t\t\t\t\t// pump's claim would stall (qa F1 regression). Helper handles\n\t\t\t\t\t\t// for ALL callers; defaults can't regress.\n\t\t\t\t\t\temitOnce(config.onFailure(\"complete\", undefined));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t// Sync DATA delivery (cached state / `fromAny` over a sync value):\n\t\t\t// the callback ran reentrantly before `unsub` was assigned, so the\n\t\t\t// `unsub?.()` call inside `emitOnce` was a no-op. Drop the upstream\n\t\t\t// subscription now that we have the handle.\n\t\t\tif (captured && unsub) {\n\t\t\t\tunsub();\n\t\t\t\tunsub = null;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tunlinkParent();\n\t\t\t\t\tac.abort();\n\t\t\t\t\tunsub?.();\n\t\t\t\t\tunsub = null;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ describeKind: \"producer\" },\n\t);\n}\n","/**\n * Metadata helpers for pattern-layer nodes (Tier 2.2 promotion from\n * `patterns/_internal/`).\n *\n * Each domain (orchestration, messaging, reduction, ai, cqrs, domain_template,\n * memory, lens, audit, harness) shares the same metadata convention. Promoted\n * to `extra/` so non-patterns code (and downstream consumers building their\n * own domain primitives) can use the same shape.\n *\n * @module\n */\n\n/**\n * Build a domain metadata object for pattern-layer nodes.\n *\n * Each domain follows the same shape: `{ [domain]: true, [domain]_type: kind, ...extra }`.\n *\n * @param domain - The domain tag (e.g. `\"orchestration\"`, `\"ai\"`, `\"cqrs\"`).\n * @param kind - The specific type within the domain (e.g. `\"gate\"`, `\"prompt\"`).\n * @param extra - Additional metadata to merge.\n * @returns Metadata object.\n */\nexport function domainMeta(\n\tdomain: string,\n\tkind: string,\n\textra?: Record<string, unknown>,\n): Record<string, unknown> {\n\treturn {\n\t\t[domain]: true,\n\t\t[`${domain}_type`]: kind,\n\t\t...(extra ?? {}),\n\t};\n}\n","/**\n * evalVerifier — re-run the affected eval tasks against the execute-stage\n * artifact instead of asking an LLM to opine on the fix.\n *\n * Pairs naturally with {@link refineExecutor}: refineExecutor emits an\n * `ExecuteOutput<T>.artifact` holding the converged candidate; evalVerifier\n * pulls it out via `extractArtifact` and feeds a single-candidate batch\n * into the same `Evaluator<T>` shape that `refineLoop` used. Consistent\n * scoring between EXECUTE and VERIFY — no \"LLM said it looks fine\" gap.\n *\n * **C2 lifecycle (Tier 6.5).** The work fn is invoked once per claimed\n * verify-stage job. A fresh single-candidate eval subgraph is mounted\n * inside the work fn and tears down when the JobFlow pump ack/unsubs.\n *\n * @module\n */\n\nimport { batch, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { filter } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport type {\n\tExecuteOutput,\n\tHarnessExecutor,\n\tHarnessJobPayload,\n\tHarnessVerifier,\n\tTriagedItem,\n\tVerifyOutput,\n} from \"../../utils/harness/types.js\";\nimport type { JobEnvelope } from \"../../utils/job-queue/index.js\";\nimport { refineExecutor } from \"./refine-executor.js\";\nimport type {\n\tDatasetItem,\n\tEvalResult,\n\tEvaluator,\n\tRefineLoopOptions,\n\tRefineStrategy,\n} from \"./refine-loop.js\";\n\n/** Summary of the re-eval wave passed to a custom `toOutput` mapper. */\nexport interface EvalVerifierSummary {\n\treadonly scores: readonly EvalResult[];\n\treadonly meanScore: number;\n\treadonly passCount: number;\n\treadonly total: number;\n\treadonly threshold: number;\n\t/**\n\t * True when the EXECUTE stage did not produce an artifact (i.e.\n\t * `extractArtifact` returned `null` / `undefined`). Downstream mappers\n\t * can distinguish this from \"evaluator ran but everything scored zero\".\n\t */\n\treadonly missingArtifact?: boolean;\n}\n\n/** Configuration for {@link evalVerifier}. */\nexport interface EvalVerifierConfig<T> {\n\t/**\n\t * Pull the artifact that should be re-evaluated out of the execute-stage\n\t * output. Default: `(exec) => exec.artifact as T` — works out-of-the-box\n\t * with `refineExecutor` (which populates `artifact` by default).\n\t */\n\textractArtifact?: (exec: ExecuteOutput<T>, item: TriagedItem) => T | null | undefined;\n\n\t/**\n\t * Reactive evaluator — same contract as `refineLoop`'s `Evaluator<T>`.\n\t */\n\tevaluator: Evaluator<T>;\n\n\t/**\n\t * Resolve which dataset rows to score this verification against.\n\t */\n\tdatasetFor: (item: TriagedItem) => readonly DatasetItem[];\n\n\t/** Mean score required to pass verification. Default `0.5`. */\n\tthreshold?: number;\n\n\t/** Optional output mapper — override the default findings / errorClass shape. */\n\ttoOutput?: (summary: EvalVerifierSummary) => VerifyOutput;\n\n\t/** Node name prefix for introspection. */\n\tname?: string;\n\n\t/**\n\t * Optional parent graph on which per-claim eval subgraphs mount at\n\t * `eval/${claimId}` (DS-13.5.D.4, locked 2026-05-01). When provided,\n\t * each claim creates a fresh `Graph(\\`eval_${claimId}\\`)` subgraph\n\t * carrying `candidates` / `dataset` / `output` and mounts it at\n\t * `eval/${claimId}` on this parent — `describe()` walks the parent\n\t * see the per-claim topology while the claim is in flight, and the\n\t * subgraph is removed via `parent.remove(\"eval/${claimId}\")` on the\n\t * output node's `deactivate` cleanup (fires when JobFlow's pump\n\t * unsubscribes after ack/nack).\n\t *\n\t * **claimId source.** `JobEnvelope.id` (assigned at enqueue time);\n\t * unique within a JobFlow lifetime — uniqueness within a single pump\n\t * cycle is the JobFlow's contract.\n\t *\n\t * When omitted, internal nodes float (pre-DS-13.5.D.4 behavior).\n\t */\n\tgraph?: Graph;\n}\n\nfunction meanScore(scores: readonly EvalResult[]): number {\n\tif (scores.length === 0) return Number.NEGATIVE_INFINITY;\n\tlet sum = 0;\n\tfor (const s of scores) sum += s.score;\n\treturn sum / scores.length;\n}\n\nfunction defaultToOutput(summary: EvalVerifierSummary): VerifyOutput {\n\tconst { passCount, total, meanScore: mean, threshold, missingArtifact } = summary;\n\tconst meanStr = Number.isFinite(mean) ? mean.toFixed(3) : String(mean);\n\tconst verified = !missingArtifact && total > 0 && mean >= threshold;\n\tconst findings = missingArtifact\n\t\t? [\"EXECUTE stage did not emit an artifact; cannot verify reactively\"]\n\t\t: verified\n\t\t\t? [`${passCount}/${total} eval tasks passed; mean score ${meanStr} ≥ ${threshold}`]\n\t\t\t: total === 0\n\t\t\t\t? [\"No eval tasks were selected for this item — cannot verify\"]\n\t\t\t\t: [\n\t\t\t\t\t\t`${passCount}/${total} eval tasks passed; mean score ${meanStr} < threshold ${threshold}`,\n\t\t\t\t\t];\n\treturn verified\n\t\t? { verified: true, findings }\n\t\t: { verified: false, findings, errorClass: \"structural\" };\n}\n\nfunction defaultExtractArtifact<T>(exec: ExecuteOutput<T>): T | null | undefined {\n\treturn exec.artifact ?? null;\n}\n\n/**\n * Build a {@link HarnessVerifier} that re-runs the eval suite against the\n * artifact produced by EXECUTE.\n *\n * Reads `job.payload.execution` (filled by the upstream execute work fn)\n * and runs the evaluator against `extractArtifact(execution, item)`.\n * Returns the same payload with `verify` filled in.\n *\n * @example Pair with refineExecutor for end-to-end eval consistency.\n * ```ts\n * const evaluator: Evaluator<CatalogEntry> = (cands, ds) => runEval(cands, ds);\n * const harness = harnessLoop(\"repair\", {\n * adapter,\n * executor: refineExecutor({ ..., evaluator, ...strategyConfig }),\n * verifier: evalVerifier({ evaluator, datasetFor, threshold: 0.8 }),\n * });\n * ```\n */\nexport function evalVerifier<T>(config: EvalVerifierConfig<T>): HarnessVerifier<T> {\n\tconst name = config.name ?? \"eval-verifier\";\n\tconst threshold = config.threshold ?? 0.5;\n\tconst toOutput = config.toOutput ?? defaultToOutput;\n\tconst extract = config.extractArtifact ?? defaultExtractArtifact<T>;\n\tconst parentGraph = config.graph;\n\t// DS-13.5.B QA A7 (2026-05-03): per-claimId collision counter.\n\t// Reingest paths preserve identity per DS-13.5.D.3 so the same\n\t// claimId can land on the verifier while a prior cycle is still\n\t// in-flight. Without disambiguation, `parentGraph.mount(\n\t// \"eval/${id}\", sub)` would either silently overwrite the prior\n\t// mount or throw \"mount already exists\". The counter is keyed by\n\t// claimId so DISTINCT ids start at seq=0 (`eval/${id}`) and only\n\t// REPEAT ids get a `_${seq}` suffix.\n\tconst mountSeqByClaimId = new Map<string, number>();\n\n\treturn (job: JobEnvelope<HarnessJobPayload<T>>) => {\n\t\tconst { item, execution } = job.payload;\n\t\t// Defensive: verify stage should always run AFTER execute stage with\n\t\t// `execution` populated. If it isn't, surface that as a structural\n\t\t// failure so the dispatch effect can route the item.\n\t\tif (execution == null) {\n\t\t\treturn {\n\t\t\t\t...job.payload,\n\t\t\t\tverify: {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tfindings: [\"evalVerifier: prior execute stage produced no execution\"],\n\t\t\t\t\terrorClass: \"structural\" as const,\n\t\t\t\t},\n\t\t\t} satisfies HarnessJobPayload<T>;\n\t\t}\n\t\tconst artifact = extract(execution, item);\n\t\tif (artifact == null) {\n\t\t\treturn {\n\t\t\t\t...job.payload,\n\t\t\t\tverify: toOutput({\n\t\t\t\t\tscores: [],\n\t\t\t\t\tmeanScore: Number.NEGATIVE_INFINITY,\n\t\t\t\t\tpassCount: 0,\n\t\t\t\t\ttotal: 0,\n\t\t\t\t\tthreshold,\n\t\t\t\t\tmissingArtifact: true,\n\t\t\t\t}),\n\t\t\t} satisfies HarnessJobPayload<T>;\n\t\t}\n\n\t\t// Per-claim eval subgraph. State seeds with the single candidate +\n\t\t// resolved dataset; the evaluator returns a Node<readonly EvalResult[]>.\n\t\t// The terminal payload emits when the evaluator settles; intermediate\n\t\t// nulls are filtered.\n\t\t//\n\t\t// **Batch-coalescing for synchronous-emit-during-subscribe evaluators\n\t\t// (COMPOSITION-GUIDE §9a).** This `batch()` wrap is load-bearing for a\n\t\t// SPECIFIC evaluator pattern: evaluators that, during the\n\t\t// `evaluator(candidates, dataset)` constructor call, synchronously\n\t\t// `subscribe()` to BOTH inputs and emit on each subscribe-callback\n\t\t// firing. Each subscribe pushes the cached value to its callback, the\n\t\t// callback runs `out.emit(...)`, and that emit becomes its own wave\n\t\t// when not inside a batch — leaving multiple DATA messages visible to\n\t\t// the downstream `derived` once it activates. The JobFlow pump's\n\t\t// \"first DATA wins\" capture would then fire on the FIRST intermediate\n\t\t// emit (e.g. empty scores from a pre-dataset recompute) instead of\n\t\t// the final settled value.\n\t\t//\n\t\t// Wrapping the constructor call in `batch()` coalesces those internal\n\t\t// emits into one multi-message delivery (§9a); sugar `derived`\n\t\t// auto-unwraps to the LAST value per its snapshot/combine semantics\n\t\t// (sugar.ts), so the downstream sees only the final settled scores.\n\t\t//\n\t\t// **Async evaluators are NOT covered by this fix.** Evaluators that\n\t\t// subscribe via microtask / Promise.then() / setTimeout don't see the\n\t\t// §9a hazard at all — their emits land in separate waves regardless\n\t\t// of whether the constructor call is batched. The fix is strictly\n\t\t// for the synchronous-emit-during-subscribe pattern (today's tests:\n\t\t// `presenceEvaluator` in actuator-executor.test.ts; `keywordEvaluator`\n\t\t// in refine-executor.test.ts uses `derived` and is naturally\n\t\t// single-emit). See `harness-default-bridges.test.ts` regression test\n\t\t// \"evalVerifier coalesces synchronous-emit-during-subscribe\n\t\t// evaluators\" for the locked contract.\n\t\t// DS-13.5.D.4 (locked 2026-05-01): when `parentGraph` is configured,\n\t\t// each claim creates its own subgraph `eval_${claimId}` and mounts\n\t\t// it at `eval/${claimId}` on the parent. Internal node names use\n\t\t// the simple shape (`candidates`, `dataset`, `output`) since each\n\t\t// subgraph is a fresh namespace. Cleanup attaches to `raw`'s\n\t\t// deactivate hook so the segment is removed when JobFlow\n\t\t// unsubscribes after ack/nack (canonical \"last unsubscribe\"\n\t\t// signal via the existing NodeFnCleanup.onDeactivation protocol).\n\t\tconst claimId = job.id;\n\t\t// QA A7: only append a `_${seq}` suffix when this claimId has\n\t\t// already been mounted (collision case). Distinct claimIds\n\t\t// resolve to `eval/${claimId}` as before.\n\t\tconst seq = mountSeqByClaimId.get(claimId) ?? 0;\n\t\tmountSeqByClaimId.set(claimId, seq + 1);\n\t\tconst segmentSuffix = seq === 0 ? \"\" : `_${seq}`;\n\t\tconst segmentPath = `eval/${claimId}${segmentSuffix}`;\n\t\tconst sub = parentGraph != null ? new Graph(`eval_${claimId}${segmentSuffix}`) : null;\n\t\tconst candidatesName = sub != null ? \"candidates\" : `${name}/candidates`;\n\t\tconst datasetName = sub != null ? \"dataset\" : `${name}/dataset`;\n\t\tconst outputName = sub != null ? \"output\" : `${name}/output`;\n\t\tconst gateName = sub != null ? \"gate-out\" : `${name}/gate-out`;\n\n\t\tconst candidates = node<readonly T[]>([], {\n\t\t\tinitial: [artifact as T],\n\t\t\tname: candidatesName,\n\t\t});\n\t\tconst dataset = node<readonly DatasetItem[]>([], {\n\t\t\tinitial: config.datasetFor(item),\n\t\t\tname: datasetName,\n\t\t});\n\t\tif (sub != null) {\n\t\t\tsub.add(candidates, { name: \"candidates\" });\n\t\t\tsub.add(dataset, { name: \"dataset\" });\n\t\t}\n\t\tlet scoresNode!: ReturnType<Evaluator<T>>;\n\t\tbatch(() => {\n\t\t\tscoresNode = config.evaluator(candidates, dataset);\n\t\t});\n\t\t// DS-13.5.B QA A1 (2026-05-03): the deactivate cleanup hook MUST\n\t\t// be returned on every fn run, including the early-return path\n\t\t// where `arr == null` (evaluator emits a placeholder before\n\t\t// settling). Cleanup capture happens at the END of fn execution\n\t\t// (NodeFnCleanup contract), so a fn that returned early without\n\t\t// the cleanup object would leak `eval/${claimId}` if its first\n\t\t// run produced null and the consumer unsubscribed before\n\t\t// scoresNode emits non-null.\n\t\tconst cleanup =\n\t\t\tparentGraph != null\n\t\t\t\t? () => ({\n\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t// Auto-unmount on JobFlow's pump unsubscribe after\n\t\t\t\t\t\t\t// ack/nack (DS-13.5.D.4). Idempotent: try/catch\n\t\t\t\t\t\t\t// covers the case where the segment was already\n\t\t\t\t\t\t\t// removed (e.g. parent destroy cascade ran first).\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tparentGraph.remove(segmentPath);\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t/* best-effort cleanup */\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t: () => undefined;\n\t\tconst raw = node<HarnessJobPayload<T> | null>(\n\t\t\t[scoresNode as Node<unknown>],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst arr = data[0] as readonly EvalResult[] | null | undefined;\n\t\t\t\tif (arr == null) {\n\t\t\t\t\tactions.emit(null);\n\t\t\t\t\treturn cleanup();\n\t\t\t\t}\n\t\t\t\tconst mean = meanScore(arr);\n\t\t\t\tconst passCount = arr.filter((s) => s.score >= threshold).length;\n\t\t\t\tactions.emit({\n\t\t\t\t\t...job.payload,\n\t\t\t\t\tverify: toOutput({\n\t\t\t\t\t\tscores: arr,\n\t\t\t\t\t\tmeanScore: mean,\n\t\t\t\t\t\tpassCount,\n\t\t\t\t\t\ttotal: arr.length,\n\t\t\t\t\t\tthreshold,\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn cleanup();\n\t\t\t},\n\t\t\t{ name: outputName, describeKind: \"derived\" },\n\t\t);\n\t\tconst gateOut = filter(raw, (v) => v != null, { name: gateName }) as ReturnType<\n\t\t\tHarnessVerifier<T>\n\t\t>;\n\t\tif (sub != null) {\n\t\t\tsub.add(raw, { name: \"output\" });\n\t\t\t// QA A6: register the gate-out filter on the per-claim\n\t\t\t// subgraph so describe() walks see the consumer-facing node\n\t\t\t// alongside candidates/dataset/output. Without this, the\n\t\t\t// returned filter floats and the subgraph's external surface\n\t\t\t// is incomplete in topology snapshots.\n\t\t\tsub.add(gateOut as Node<unknown>, { name: \"gate-out\" });\n\t\t\t(parentGraph as Graph).mount(segmentPath, sub);\n\t\t}\n\t\treturn gateOut;\n\t};\n}\n\n/**\n * Config for {@link harnessEvalPair} — the typed bundle that produces a\n * matched `refineExecutor<T>` + `evalVerifier<T>` pair sharing one\n * {@link Evaluator} and one `datasetFor` resolver.\n */\nexport interface HarnessEvalPairConfig<T> {\n\t/** Map a triaged item to the seed candidate. */\n\tseedFrom: (item: TriagedItem) => T;\n\t/** The reactive evaluator used by BOTH executor and verifier. */\n\tevaluator: Evaluator<T>;\n\t/** The refinement strategy (e.g. `errorCritique(teacher)`). */\n\tstrategy: RefineStrategy<T>;\n\t/** Resolve dataset rows per triaged item. */\n\tdatasetFor: (item: TriagedItem) => readonly DatasetItem[];\n\t/** Pass-threshold for the verifier. Default `0.5`. */\n\tthreshold?: number;\n\t/** Convergence / budget options forwarded to each inner `refineLoop`. */\n\trefine?: Omit<RefineLoopOptions, \"dataset\" | \"name\">;\n\t/**\n\t * Shared node-name prefix — the executor becomes `${name}-exec` and the\n\t * verifier `${name}-verify` for distinct but related describe() paths.\n\t * Default `\"harness-pair\"`.\n\t */\n\tname?: string;\n}\n\n/**\n * Typed factory that returns a matched `{ executor, verifier }` pair.\n *\n * Prevents the \"executor wrote `A`, verifier expected `B`\" class of runtime\n * cast errors — `T` is threaded through both sides, so mixing up the\n * configuration is a compile error instead of a silent `as T` in\n * `extractArtifact`. Shares the evaluator so EXECUTE and VERIFY score with\n * identical semantics (the whole point of `evalVerifier`).\n */\nexport function harnessEvalPair<T>(config: HarnessEvalPairConfig<T>): {\n\texecutor: HarnessExecutor<T>;\n\tverifier: HarnessVerifier<T>;\n} {\n\tconst baseName = config.name ?? \"harness-pair\";\n\tconst executor = refineExecutor<T>({\n\t\tname: `${baseName}-exec`,\n\t\tseedFrom: config.seedFrom,\n\t\tevaluator: config.evaluator,\n\t\tstrategy: config.strategy,\n\t\tdatasetFor: config.datasetFor,\n\t\trefine: config.refine,\n\t});\n\tconst verifier = evalVerifier<T>({\n\t\tname: `${baseName}-verify`,\n\t\tevaluator: config.evaluator,\n\t\tdatasetFor: config.datasetFor,\n\t\tthreshold: config.threshold,\n\t});\n\treturn { executor, verifier };\n}\n","/**\n * refineExecutor — bridge a `refineLoop` into the harness EXECUTE work fn.\n *\n * Each claimed job mounts a fresh `refineLoop`; when the loop reaches a\n * terminal status (`converged` / `budget` / `errored`), the work fn emits a\n * single {@link HarnessJobPayload} with `execution` filled in. The JobFlow\n * pump subscribes once, takes the first DATA, then unsubscribes — so the\n * inner loop tears down cleanly when the harness acks the job.\n *\n * **C2 lifecycle (Tier 6.5).** The work fn is invoked once per claim, so\n * no internal `switchMap` is needed (the prior pre-C2 shape used switchMap\n * to handle a stream of items). The pump owns the per-claim lifecycle:\n * activation when the work fn returns, teardown when the result Node is\n * unsubscribed.\n *\n * **Cross-item learning:** a fresh refineLoop per item means\n * `errorCritique`-style failure sampling does NOT accumulate across items\n * sharing a `rootCause`. A persistent-loop + re-seed surface is filed in\n * `docs/optimizations.md` as a long-term follow-up.\n *\n * @module\n */\n\nimport { node } from \"@graphrefly/pure-ts/core\";\nimport { filter } from \"@graphrefly/pure-ts/extra\";\nimport type {\n\tExecuteOutput,\n\tHarnessExecutor,\n\tHarnessJobPayload,\n\tTriagedItem,\n} from \"../../utils/harness/types.js\";\nimport type { JobEnvelope } from \"../../utils/job-queue/index.js\";\nimport {\n\ttype DatasetItem,\n\ttype Evaluator,\n\ttype RefineLoopOptions,\n\ttype RefineStatus,\n\ttype RefineStrategy,\n\trefineLoop,\n} from \"./refine-loop.js\";\n\n/** Terminal-run snapshot passed to a custom `toOutput` mapper. */\nexport interface RefineExecutorResult<T> {\n\t/**\n\t * Best candidate the inner loop converged on. `undefined` (SENTINEL) if the\n\t * inner loop never produced a best — e.g. it `errored` before any iteration\n\t * settled. (`loop.best` is a SENTINEL `Node<T>` post the 2026-05-18\n\t * anti-pattern sweep — no `null` placeholder.)\n\t */\n\treadonly best: T | undefined;\n\t/** Aggregate score at termination. `-Infinity` if the batch was empty. */\n\treadonly score: number;\n\t/** Reason the loop terminated. */\n\treadonly status: RefineStatus;\n}\n\n/** Configuration for {@link refineExecutor}. */\nexport interface RefineExecutorConfig<T> {\n\t/** Map a triaged item to the seed candidate (e.g. a catalog entry, prompt, patch). */\n\tseedFrom: (item: TriagedItem) => T;\n\n\t/** Reactive evaluator — same shape as passed to `refineLoop`. */\n\tevaluator: Evaluator<T>;\n\n\t/** Strategy (e.g. `errorCritique(teacher)`). Applied to every item's inner loop. */\n\tstrategy: RefineStrategy<T>;\n\n\t/** Map a triaged item to the dataset rows the evaluator should score against. */\n\tdatasetFor: (item: TriagedItem) => readonly DatasetItem[];\n\n\t/**\n\t * Optional mapper from the inner loop's terminal snapshot to an\n\t * `ExecuteOutput<T>`. Default: converged→success, budget→partial,\n\t * errored→failure.\n\t */\n\ttoOutput?: (result: RefineExecutorResult<T>) => ExecuteOutput<T>;\n\n\t/** Convergence / budget options forwarded to each inner `refineLoop`. */\n\trefine?: Omit<RefineLoopOptions, \"dataset\" | \"name\">;\n\n\t/** Node name prefix for introspection. Default `\"refine-executor\"`. */\n\tname?: string;\n}\n\nfunction defaultToOutput<T>(result: RefineExecutorResult<T>): ExecuteOutput<T> {\n\tconst { best, score, status } = result;\n\tconst scoreStr = Number.isFinite(score) ? score.toFixed(3) : String(score);\n\tconst artifact: T | undefined = best;\n\tif (status === \"converged\") {\n\t\treturn {\n\t\t\toutcome: \"success\",\n\t\t\tdetail: `refineLoop converged at score ${scoreStr}`,\n\t\t\tartifact,\n\t\t};\n\t}\n\tif (status === \"budget\") {\n\t\treturn {\n\t\t\toutcome: \"partial\",\n\t\t\tdetail: `refineLoop hit budget at score ${scoreStr}`,\n\t\t\tartifact,\n\t\t};\n\t}\n\treturn {\n\t\toutcome: \"failure\",\n\t\tdetail: `refineLoop errored (status=${status})`,\n\t\tartifact,\n\t};\n}\n\n/**\n * Build a {@link HarnessExecutor} backed by a `refineLoop` per claimed\n * job.\n *\n * @example Eval-driven repair loop in the harness EXECUTE slot.\n * ```ts\n * const harness = harnessLoop(\"repair\", {\n * adapter,\n * executor: refineExecutor({\n * seedFrom: (item) => initialCatalogEntry(item),\n * datasetFor: (item) => pickAffectedTasks(item, allTasks),\n * evaluator: (cands, tasks) => runEvalBatch(cands, tasks),\n * strategy: errorCritique({ teacher, width: 3 }),\n * refine: { maxIterations: 5, minScore: 0.9 },\n * }),\n * });\n * ```\n */\nexport function refineExecutor<T>(config: RefineExecutorConfig<T>): HarnessExecutor<T> {\n\tconst name = config.name ?? \"refine-executor\";\n\tconst toOutput = config.toOutput ?? defaultToOutput<T>;\n\n\treturn (job: JobEnvelope<HarnessJobPayload<T>>) => {\n\t\tconst item = job.payload.item;\n\t\tconst loop = refineLoop<T>(config.seedFrom(item), config.evaluator, config.strategy, {\n\t\t\t...config.refine,\n\t\t\tdataset: config.datasetFor(item),\n\t\t\tname: `${name}/inner`,\n\t\t});\n\t\t// Terminal-allowlist guard — emit non-null only on `converged` / `budget` /\n\t\t// `errored`; intermediate `running` waves emit `null` (deduped via the\n\t\t// node's default Object.is). The trailing `filter(v != null)` strips\n\t\t// the null DATA so the JobFlow pump's first-DATA capture sees the\n\t\t// terminal payload, not the intermediate null.\n\t\tconst raw = node<HarnessJobPayload<T> | null>(\n\t\t\t[loop.status, loop.best, loop._score],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst s = data[0] as RefineStatus;\n\t\t\t\tif (s !== \"converged\" && s !== \"budget\" && s !== \"errored\") {\n\t\t\t\t\tactions.emit(null);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst exec = toOutput({\n\t\t\t\t\tbest: data[1] as T | undefined,\n\t\t\t\t\tscore: data[2] as number,\n\t\t\t\t\tstatus: s,\n\t\t\t\t});\n\t\t\t\tactions.emit({\n\t\t\t\t\t...job.payload,\n\t\t\t\t\texecution: { item, ...exec },\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: `${name}/output`, describeKind: \"derived\" },\n\t\t);\n\t\treturn filter(raw, (v) => v != null, { name: `${name}/gate-out` }) as ReturnType<\n\t\t\tHarnessExecutor<T>\n\t\t>;\n\t};\n}\n","/**\n * refineLoop — universal prompt/artifact optimization loop as a reactive Graph.\n *\n * Roadmap §9.8 (Wave 2.5). The loop is a 4-topic reactive pipeline:\n *\n * iterationTrigger ──▶ GENERATE ──▶ EVALUATE ──▶ ANALYZE ──▶ DECIDE\n * │ │\n * └─────── feedback + trigger ◀─────┘\n *\n * Each stage is a `TopicGraph` so dispatches stay O(1) per subscriber (cursor-\n * based) and every iteration is observable, replayable, and checkpointable.\n *\n * Composition invariants (from COMPOSITION-GUIDE):\n * - §7 feedback cycle: only `iterationTrigger` drives re-generation. Strategy\n * + feedback + dataset are read via closure updaters (§28 factory-time seed)\n * so mid-run swaps apply to the NEXT iteration, never retrigger the current.\n * - §28 factory-time seed: strategy, lastFeedback, prevCandidates, dataset\n * closures captured at wiring time + updated via subscribe handlers so the\n * first activation doesn't drop the initial pair.\n * - §32 nested-drain state-mirror: the decide-effect writes `lastFeedback`\n * BEFORE bumping `iterationTrigger` inside its `batch()`, guaranteeing the\n * mirror is current when the next-iteration wave reaches the generate fn.\n * - §19 terminal-emission: history / best emit once per iteration (settled),\n * not on every intermediate wave.\n * - §27 attachSnapshotStorage: the whole graph is checkpointable — pause overnight,\n * resume tomorrow from the exact iteration count, candidate set, strategy.\n *\n * Scope clamp (v1): core factory + `RefineStrategy<T>` + `blindVariation` and\n * `errorCritique` built-ins + budget gating + checkpoint/resume.\n * `mutateAndRefine` / registry / `autoSelectStrategy` / `optimizeCatalog` /\n * `refineExecutor` are deferred.\n *\n * @module\n */\n\n// `createNode` is the local alias for `node` so calls don't shadow\n// `Graph.prototype.node` when the file's body inadvertently references the\n// graph's `.node()` method. B5f keeps protocol-primitive construction visually\n// distinct from graph-instance method dispatch.\nimport {\n\tbatch,\n\tnode as createNode,\n\tDATA,\n\tERROR,\n\tmonotonicNs,\n\ttype Node,\n\tplaceholderArgs,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport type { NodeInput } from \"@graphrefly/pure-ts/extra\";\nimport { switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { tryIncrementBounded } from \"../../base/mutation/index.js\";\nimport { messagingHub, type TopicGraph } from \"../../utils/messaging/index.js\";\n\n// ---------------------------------------------------------------------------\n// Core types\n// ---------------------------------------------------------------------------\n\n/** A single task row — the unit the evaluator scores one candidate against. */\nexport interface DatasetItem {\n\treadonly id: string;\n\treadonly [k: string]: unknown;\n}\n\n/**\n * One candidate's score on one task. Higher is better by convention.\n *\n * Set `candidateIndex` when the evaluator fans out scores across multiple\n * candidates (e.g. `candidates × tasks`). `pickBest` aggregates mean scores\n * per `candidateIndex` when present; when absent, falls back to positional\n * alignment (`scores[i]` ↔ `candidates[i]`).\n */\nexport interface EvalResult {\n\treadonly taskId: string;\n\treadonly score: number;\n\treadonly error?: string;\n\treadonly detail?: unknown;\n\t/** 0-based index into the `candidates` batch this score belongs to. */\n\treadonly candidateIndex?: number;\n}\n\n/** Aggregated feedback the strategy produces from a scores batch. */\nexport interface Feedback {\n\treadonly summary: string;\n\treadonly critique?: unknown;\n\treadonly weakTasks?: readonly string[];\n\treadonly score: number;\n}\n\n/**\n * Strategy interface — plain object, no base class. Strategies implement three\n * pure hooks; the loop infrastructure wraps them in reactive nodes so every\n * decision is visible in `describe()`.\n *\n * `generate` may be sync or async. Async generates yield a microtask per\n * iteration — that's what gives `pause()` / `setStrategy()` a window to\n * interleave. **A fully synchronous `generate` will drain the entire loop\n * during factory activation** (all iterations run before `refineLoop()`\n * returns), which is usually not what you want for observable, steerable\n * loops. Real strategies that call LLMs / evals are async and Just Work;\n * custom sync strategies for tests are fine but should be marked `async`\n * to match real cadence.\n */\nexport interface RefineStrategy<T> {\n\treadonly name: string;\n\t/** Produce initial candidates from the seed. Called at iteration 0. */\n\tseed(seed: T): readonly T[];\n\t/** Reduce scores to feedback. Pure function. */\n\tanalyze(scores: readonly EvalResult[], candidates: readonly T[]): Feedback;\n\t/**\n\t * Generate next-iteration candidates from feedback + prior candidates.\n\t * Async allowed — the loop awaits via `fromAny`.\n\t */\n\tgenerate(feedback: Feedback, candidates: readonly T[]): Promise<readonly T[]> | readonly T[];\n}\n\n/**\n * Evaluator shape — Shape 4 (2026-04-22): both `candidates` and `dataset` are\n * reactive nodes; the evaluator's returned node IS the EVALUATE topic's source\n * (no glue). Implementers can batch-eval (e.g. `funnel` with concurrency) or\n * map per-candidate — user's code.\n *\n * **Cancel-on-input contract (load-bearing).** Evaluators with async work\n * (LLM calls, network requests, etc.) MUST cancel any in-flight work when\n * `candidates` emits a new batch. The canonical pattern is `switchMap` over\n * `candidates`. If an evaluator does NOT cancel — e.g. naively kicks a\n * `Promise.all` per-batch and emits whatever resolves — late scores from a\n * prior iteration can arrive after the loop has already moved to the next\n * iteration (especially after `pause()` / `resume()`). Such stale scores\n * trip {@link refineLoop}'s `feedbackEnvelopeNode` with mismatched\n * `iter`/`scores`/`items`, producing an incorrect `DecideEvent` and (worse)\n * marking the iter as decided so the real iter's scores get skipped by\n * de-dup, stalling the loop. See `optimizations.md` \"refineLoop async-\n * evaluator stale-scores follow-up\" for the proposed `wrapEvaluator()`\n * helper that would enforce cancellation.\n *\n * **`EvalResult.candidateIndex` semantics.** Optional per-result field.\n * When present, multi-candidate aggregators ({@link errorCritique}'s\n * `pickBest`) score per index, picking the candidate with the highest\n * mean score. When absent across all results, those aggregators fall back\n * to positional matching against `candidates[0]` — meaning a strategy that\n * generates >1 candidate but emits unindexed scores effectively only ever\n * critiques the first candidate. Set `candidateIndex` whenever the\n * evaluator's score corresponds to a specific candidate in the batch.\n */\nexport type Evaluator<T> = (\n\tcandidates: Node<readonly T[]>,\n\tdataset: Node<readonly DatasetItem[]>,\n) => Node<readonly EvalResult[]>;\n\n// ---------------------------------------------------------------------------\n// Convergence\n// ---------------------------------------------------------------------------\n\n/**\n * Early-stop controls. Each field fans into its own derived node; the four\n * combine via `||` into `converged: Node<boolean>`. Callers see exactly\n * which rule tripped via `status` / the DECIDE topic's `reason`.\n */\nexport interface ConvergenceOptions {\n\t/** Stop when aggregate score has not improved for N iterations. */\n\tpatience?: number;\n\t/** Stop when aggregate score reaches or exceeds this. */\n\tminScore?: number;\n\t/** Stop when absolute delta between consecutive scores falls below this. */\n\tminDelta?: number;\n\t/** Stop after N total evaluations (iteration count × per-iter candidates). */\n\tmaxEvaluations?: number;\n\t/** Stop after N iterations. Always set a finite bound in production. */\n\tmaxIterations?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Topic payloads (one per stage)\n// ---------------------------------------------------------------------------\n\n/** Emitted to the GENERATE topic each time the strategy produces a batch. */\nexport interface GenerateEvent<T> {\n\treadonly iteration: number;\n\treadonly candidates: readonly T[];\n\treadonly timestamp_ns: number;\n}\n\n/** Emitted to the EVALUATE topic when scores settle for an iteration. */\nexport interface EvaluateEvent<T> {\n\treadonly iteration: number;\n\treadonly candidates: readonly T[];\n\treadonly scores: readonly EvalResult[];\n\treadonly timestamp_ns: number;\n}\n\n/** Emitted to the ANALYZE topic — strategy's reduction over scores. */\nexport interface AnalyzeEvent<T> {\n\treadonly iteration: number;\n\treadonly candidates: readonly T[];\n\treadonly feedback: Feedback;\n\treadonly timestamp_ns: number;\n}\n\n/** Emitted to the DECIDE topic — branch taken this iteration. */\nexport interface DecideEvent {\n\treadonly iteration: number;\n\treadonly decision: \"continue\" | \"converged\" | \"budget\" | \"paused\";\n\treadonly reason?: string;\n\treadonly timestamp_ns: number;\n}\n\n// ---------------------------------------------------------------------------\n// Status + history\n// ---------------------------------------------------------------------------\n\nexport type RefineStatus = \"running\" | \"converged\" | \"budget\" | \"paused\" | \"errored\";\n\n/**\n * **Internal envelope** — carries the iteration number alongside the\n * candidates batch so `iter` rides the data wave through the pipeline. Lets\n * downstream stages read iter from a real reactive edge instead of from\n * `iterationTrigger.cache` (P3 violation; see /qa D1, 2026-05-01).\n *\n * Sidecar `candidatesItemsNode = derived([candidatesNode], ([env]) => env.items)`\n * preserves the user-facing `Evaluator<T>` API (which sees `Node<readonly T[]>`).\n */\ninterface CandidatesEnvelope<T> {\n\treadonly iter: number;\n\treadonly items: readonly T[];\n}\n\n/**\n * **Internal envelope** — assembled by `feedbackEnvelopeNode` from\n * `userScoresNode` + `candidatesNode`. Carries iter + items + scores +\n * feedback together as the trigger payload for `decideEffect` (`§16` nested\n * `withLatestFrom` advisory-samples history / budget / pause). Lets\n * `decideEffect` read iter from the envelope (no `iterationTrigger.cache` read)\n * AND ensures decideEffect only fires when the user evaluator has actually\n * emitted fresh scores (gate via `batchData[scores]` length, eliminating\n * spurious decides on candidates-only fan-out waves).\n */\ninterface FeedbackEnvelope<T> {\n\treadonly iter: number;\n\treadonly items: readonly T[];\n\treadonly scores: readonly EvalResult[];\n\treadonly feedback: Feedback;\n}\n\nexport interface Iteration<T> {\n\treadonly n: number;\n\treadonly candidates: readonly T[];\n\treadonly scores: readonly EvalResult[];\n\treadonly feedback: Feedback;\n\t/** `null` iff the candidate batch for this iteration was empty. */\n\treadonly best: T | null;\n\treadonly bestScore: number;\n\treadonly timestamp_ns: number;\n}\n\n// ---------------------------------------------------------------------------\n// Factory + returned graph\n// ---------------------------------------------------------------------------\n\nexport interface RefineLoopOptions extends ConvergenceOptions {\n\t/** Reactive dataset OR a plain array (auto-wrapped into `state`). */\n\tdataset: NodeInput<readonly DatasetItem[]> | readonly DatasetItem[];\n\t/** Total teacher calls cap across iterations. Default: unlimited. */\n\tbudget?: number;\n\t/** Graph name. Default: `\"refine-loop\"`. */\n\tname?: string;\n\t/** Extra graph options forwarded to the underlying `Graph`. */\n\tgraph?: GraphOptions;\n}\n\n/**\n * `class RefineLoopGraph<T> extends Graph` — the universal prompt/artifact\n * optimization loop as a reactive Graph subclass.\n *\n * Constructed via the {@link refineLoop} factory in normal use; exported as a\n * class so consumers can `instanceof`-narrow on returned values (Phase 13.G\n * `agent(spec)` is the consumer that motivated the migration). All\n * observability tools (`describe`, `explain`, `observe`, `attachSnapshotStorage`,\n * `snapshot`) Just Work since this `extends Graph`.\n *\n * **Phase 12.D (2026-04-30):** Migrated from `Object.assign(graph, ...)` factory\n * pattern to `class extends Graph` (Tier R5.1 deferral lifted; mirrors the\n * `MemoryWith*Graph` precedent). `setStrategy` / `pause` / `resume` are now\n * instance methods that read `this.strategy` / `this._pauseState` / `this.status`\n * / `this._iteration` instead of factory-local closures.\n */\nexport class RefineLoopGraph<T> extends Graph {\n\t/**\n\t * Best candidate so far. **SENTINEL until the first iteration settles** —\n\t * `loop.best.cache` is `undefined` (not `null`) before any iteration\n\t * produces a best, and a degenerate empty-candidate iteration leaves the\n\t * prior best in place rather than wiping it. Consumers guard with\n\t * `=== undefined` (spec §3 SENTINEL), not `== null`. (Anti-pattern sweep\n\t * 2026-05-18: dropped the `initial: null` eager-placeholder; `null` is\n\t * reserved for the per-iteration {@link Iteration.best} data field where an\n\t * empty batch is a valid domain value.)\n\t */\n\treadonly best: Node<T>;\n\t/**\n\t * Best score so far. Pseudo-private (`_score`) to avoid colliding with any\n\t * future `Graph.prototype.score` method (B5d forward-compat hazard\n\t * prevention). Typed-public — read via `loop._score.cache` /\n\t * `loop._score.subscribe(...)` from external code.\n\t */\n\treadonly _score: Node<number>;\n\treadonly status: Node<RefineStatus>;\n\treadonly history: Node<readonly Iteration<T>[]>;\n\treadonly strategy: Node<RefineStrategy<T>>;\n\t/**\n\t * Monotonic iteration counter. Pseudo-private (`_iteration`) to avoid\n\t * colliding with any future `Graph.prototype.iteration` method (B5d\n\t * forward-compat hazard prevention). Typed-public — read via\n\t * `loop._iteration.cache` / `loop._iteration.subscribe(...)`.\n\t */\n\treadonly _iteration: Node<number>;\n\t/** Stage topic — subscribe for per-stage streaming / cursor consumers. */\n\treadonly generate: TopicGraph<GenerateEvent<T>>;\n\t/** Stage topic — subscribe for per-stage streaming / cursor consumers. */\n\treadonly evaluate: TopicGraph<EvaluateEvent<T>>;\n\t/** Stage topic — subscribe for per-stage streaming / cursor consumers. */\n\treadonly analyze: TopicGraph<AnalyzeEvent<T>>;\n\t/** Stage topic — subscribe for per-stage streaming / cursor consumers. */\n\treadonly decide: TopicGraph<DecideEvent>;\n\n\t/** Internal: paused-flag node. Mounted as \"paused\" in describe(). */\n\tprivate readonly _pauseState: Node<boolean>;\n\n\tconstructor(\n\t\tseed: T,\n\t\tevaluator: Evaluator<T>,\n\t\tinitialStrategy: RefineStrategy<T>,\n\t\topts: RefineLoopOptions,\n\t) {\n\t\tconst name = opts.name ?? \"refine-loop\";\n\t\tsuper(name, opts.graph);\n\n\t\t// /qa A2 (2026-04-30): tag the Graph with its constructing factory so\n\t\t// `describe()` / `compileSpec` round-trip surfaces provenance — mirrors\n\t\t// the `agentMemory` pattern. `seed` / `evaluator` / `initialStrategy`\n\t\t// and option fields are non-JSON (functions, strategies); route through\n\t\t// `placeholderArgs` (DG2=ii) which substitutes `\"<function>\"` /\n\t\t// `\"<Node>\"` / `\"<unserializable>\"` for non-JSON values.\n\t\tthis.tagFactory(\n\t\t\t\"refineLoop\",\n\t\t\tplaceholderArgs({ seed, evaluator, initialStrategy, ...opts } as unknown as Record<\n\t\t\t\tstring,\n\t\t\t\tunknown\n\t\t\t>),\n\t\t);\n\n\t\t// --- Dataset: auto-wrap arrays into a state node ------------------------\n\t\tconst datasetNode: Node<readonly DatasetItem[]> = isNode<readonly DatasetItem[]>(opts.dataset)\n\t\t\t? opts.dataset\n\t\t\t: createNode<readonly DatasetItem[]>([], {\n\t\t\t\t\tname: \"dataset\",\n\t\t\t\t\tinitial: opts.dataset as readonly DatasetItem[],\n\t\t\t\t});\n\t\tthis.add(datasetNode, { name: \"dataset\" });\n\n\t\t// --- State nodes --------------------------------------------------------\n\t\tconst iterationTrigger = createNode<number>([], { name: \"iteration\", initial: 0 });\n\t\tthis.add(iterationTrigger, { name: \"iteration\" });\n\n\t\tconst strategyNode = createNode<RefineStrategy<T>>([], {\n\t\t\tname: \"strategy\",\n\t\t\tinitial: initialStrategy,\n\t\t\tequals: () => false, // always propagate strategy swaps\n\t\t});\n\t\tthis.add(strategyNode, { name: \"strategy\" });\n\n\t\t// SENTINEL until the first iteration mirrors feedback (anti-pattern\n\t\t// sweep 2026-05-18 — dropped the `initial: null` eager-placeholder that\n\t\t// pushed `[null]` to every fresh subscriber). Only ever carries a real\n\t\t// `Feedback` (the decide-effect mirror at the bottom always emits a\n\t\t// concrete `fb`), so SENTINEL-before-first cleanly means \"no iteration\n\t\t// has completed yet\" rather than a spurious `null` DATA.\n\t\tconst lastFeedbackState = createNode<Feedback>([], {\n\t\t\tname: \"lastFeedback\",\n\t\t});\n\t\tthis.add(lastFeedbackState, { name: \"lastFeedback\" });\n\n\t\tconst prevCandidatesState = createNode<readonly T[]>([], {\n\t\t\tname: \"prevCandidates\",\n\t\t\tinitial: [],\n\t\t});\n\t\tthis.add(prevCandidatesState, { name: \"prevCandidates\" });\n\n\t\tconst pauseState = createNode<boolean>([], { name: \"paused\", initial: false });\n\t\tthis.add(pauseState, { name: \"paused\" });\n\n\t\tconst statusState = createNode<RefineStatus>([], { name: \"status\", initial: \"running\" });\n\t\tthis.add(statusState, { name: \"status\" });\n\n\t\tconst historyState = createNode<readonly Iteration<T>[]>([], {\n\t\t\tname: \"history\",\n\t\t\tinitial: [],\n\t\t\tequals: () => false, // append-style; reactive consumers want every push\n\t\t});\n\t\tthis.add(historyState, { name: \"history\" });\n\n\t\t// SENTINEL until the first iteration produces a best (anti-pattern\n\t\t// sweep 2026-05-18). Never carries `null`: the decide-effect skips the\n\t\t// emit when `pickBest` yields no best, so a degenerate empty-candidate\n\t\t// iteration preserves the prior best instead of wiping it to `null`.\n\t\tconst bestState = createNode<T>([], { name: \"best\" });\n\t\tthis.add(bestState, { name: \"best\" });\n\n\t\tconst scoreState = createNode<number>([], { name: \"score\", initial: Number.NEGATIVE_INFINITY });\n\t\tthis.add(scoreState, { name: \"score\" });\n\n\t\t// --- Budget counter -----------------------------------------------------\n\t\tconst budgetState = createNode<number>([], { name: \"budget-used\", initial: 0 });\n\t\tthis.add(budgetState, { name: \"budget-used\" });\n\n\t\t// --- Stage hub (Shape B + C-aspects) ------------------------------------\n\t\t// One messagingHub instead of four standalone TopicGraphs. Topics are\n\t\t// eagerly created so the public accessors (loop.generate etc.) are\n\t\t// available immediately without waiting for the first event to fire.\n\t\t// The hub is mounted in this so all stage topics appear under \"stages::\"\n\t\t// in describe()/explain() — visible edges, not closure-held singletons.\n\t\tconst hub = messagingHub(\"stages\");\n\t\tthis.mount(\"stages\", hub);\n\t\tconst hubGenerateTopic = hub.topic<GenerateEvent<T>>(\"generate\");\n\t\tconst hubEvaluateTopic = hub.topic<EvaluateEvent<T>>(\"evaluate\");\n\t\tconst hubAnalyzeTopic = hub.topic<AnalyzeEvent<T>>(\"analyze\");\n\t\tconst hubDecideTopic = hub.topic<DecideEvent>(\"decide\");\n\n\t\t// /qa A1 (2026-04-30): assign the public field surface BEFORE wiring\n\t\t// any effect / subscribe activation below. A synchronous strategy can\n\t\t// drain the entire GENERATE → EVALUATE → ANALYZE → DECIDE cascade\n\t\t// during the constructor body (see strategy doc above); fields must be\n\t\t// reachable in case any future subscribe handler dereferences `this.X`\n\t\t// during that synchronous drain. Defensive — no current handler reads\n\t\t// `this.<field>`, but keeping construction-order safe avoids future\n\t\t// undefined-field crashes.\n\t\tthis.best = bestState;\n\t\tthis._score = scoreState;\n\t\tthis.status = statusState;\n\t\tthis.history = historyState;\n\t\tthis.strategy = strategyNode;\n\t\tthis._iteration = iterationTrigger;\n\t\tthis.generate = hubGenerateTopic;\n\t\tthis.evaluate = hubEvaluateTopic;\n\t\tthis.analyze = hubAnalyzeTopic;\n\t\tthis.decide = hubDecideTopic;\n\t\tthis._pauseState = pauseState;\n\n\t\t// --- Factory-time seed closures (§28) -----------------------------------\n\t\t// These mirror the reactive dep values so the generate fn can read them\n\t\t// without the multi-dep push-on-subscribe initial-pair drop. Per\n\t\t// COMPOSITION-GUIDE-PROTOCOL.md §28: \"The closure reads inside the\n\t\t// reactive fn are NOT P3 violations — they read a closure variable,\n\t\t// not a `.cache`.\" Subscribe handlers run synchronously on dep DATA,\n\t\t// so the closure mirrors are always current by the time the generate\n\t\t// fn fires for the next iter.\n\t\tlet latestStrategy: RefineStrategy<T> = initialStrategy;\n\t\tlet latestFeedback: Feedback | undefined;\n\t\tlet latestPrevCandidates: readonly T[] = [];\n\t\tthis.addDisposer(\n\t\t\tstrategyNode.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestStrategy = m[1] as RefineStrategy<T>;\n\t\t\t}),\n\t\t);\n\t\tthis.addDisposer(\n\t\t\tlastFeedbackState.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestFeedback = m[1] as Feedback;\n\t\t\t}),\n\t\t);\n\t\tthis.addDisposer(\n\t\t\tprevCandidatesState.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestPrevCandidates = m[1] as readonly T[];\n\t\t\t}),\n\t\t);\n\n\t\t// --- GENERATE: iterationTrigger → candidates ----------------------------\n\t\t// switchMap cancels any in-flight generate when a new iteration fires.\n\t\t// At iteration 0, strategy.seed(seed). At iteration > 0, strategy.generate.\n\t\t//\n\t\t// Sync strategies emit in the same wave as `iterationTrigger` — no microtask\n\t\t// bridge. This eliminates the per-topic iteration race (Edge #5): all four\n\t\t// stage effects drain under one wave, so iteration numbers across\n\t\t// GENERATE / EVALUATE / ANALYZE / DECIDE are guaranteed identical.\n\t\t//\n\t\t// Async strategies still cross a Promise boundary — that's the strategy's\n\t\t// async-source contract (spec §5.10: async boundaries belong in sources).\n\t\t// Cancellation on strategy swap / pause / new iteration uses switchMap's\n\t\t// inner-node unsubscribe + a `cancelled` flag so late Promise resolutions\n\t\t// don't emit into a torn-down switchMap slot.\n\t\t//\n\t\t// **/qa D1 (2026-05-01) — envelope shape:** the inner producer emits\n\t\t// `{iter, items}` so `iter` rides the data wave through every downstream\n\t\t// stage. Eliminates the cross-node `iterationTrigger.cache` P3 violation\n\t\t// in `decideEffect` (and the resume-stall failure mode it caused). User-\n\t\t// facing evaluator API stays `Node<readonly T[]>` via the\n\t\t// `candidatesItemsNode` sidecar derived below.\n\t\tconst candidatesNode = switchMap<number, CandidatesEnvelope<T>>(\n\t\t\titerationTrigger,\n\t\t\t(iter) => {\n\t\t\t\tconst strat = latestStrategy;\n\t\t\t\tconst isSeed = iter === 0 || latestFeedback === undefined;\n\t\t\t\treturn createNode<CandidatesEnvelope<T>>(\n\t\t\t\t\t[],\n\t\t\t\t\t(_data, actions) => {\n\t\t\t\t\t\tlet cancelled = false;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst result = isSeed\n\t\t\t\t\t\t\t\t? strat.seed(seed)\n\t\t\t\t\t\t\t\t: strat.generate(latestFeedback as Feedback, latestPrevCandidates);\n\t\t\t\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\t\t\t\tresult.then(\n\t\t\t\t\t\t\t\t\t(v) => {\n\t\t\t\t\t\t\t\t\t\tif (!cancelled) actions.emit({ iter, items: v });\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\t\t\tif (!cancelled) actions.down([[ERROR, err]]);\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t\t\t\tcancelled = true;\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tactions.emit({ iter, items: result });\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tcancelled = true;\n\t\t\t\t\t\t\tactions.down([[ERROR, err]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t},\n\t\t\t\t\t{ describeKind: \"producer\" },\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ name: \"candidates\" },\n\t\t);\n\t\tthis.add(candidatesNode, { name: \"candidates\" });\n\n\t\t// User-facing items sidecar: preserves the `Evaluator<T>` API\n\t\t// (`(candidates: Node<readonly T[]>, dataset: Node<readonly DatasetItem[]>) => ...`)\n\t\t// while the internal pipeline reads iter from the envelope.\n\t\tconst candidatesItemsNode = createNode<readonly T[]>(\n\t\t\t[candidatesNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst env = data[0] as CandidatesEnvelope<T> | undefined;\n\t\t\t\tif (env === undefined) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit(env.items);\n\t\t\t},\n\t\t\t{ name: \"candidates-items\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(candidatesItemsNode, { name: \"candidates-items\" });\n\n\t\t// Error watcher — strategy throws surface as ERROR on `candidatesNode`.\n\t\t// Promote to `status = \"errored\"` so callers don't have to subscribe to\n\t\t// the error channel directly.\n\t\tconst errorWatcher = createNode(\n\t\t\t[candidatesNode],\n\t\t\t(_batchData, _actions, ctx) => {\n\t\t\t\tconst terminal = ctx.terminalDeps[0];\n\t\t\t\tif (terminal !== undefined && terminal !== true) {\n\t\t\t\t\tstatusState.emit(\"errored\");\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ name: \"error-watcher\", describeKind: \"effect\", errorWhenDepsError: false },\n\t\t);\n\t\tthis.add(errorWatcher, { name: \"error-watcher\" });\n\t\tthis.addDisposer(errorWatcher.subscribe(() => undefined));\n\n\t\t// GENERATE stage: three nodes replace one monolithic effect.\n\t\t// (1) derived computes the event payload — reactive edge visible in explain().\n\t\t// (2) publish effect routes the derived event to the hub topic.\n\t\t// (3) mirror effect keeps prevCandidatesState in sync for §28 closure reads.\n\t\t// Budget accounting stays in decideEffect (single authority).\n\t\t// /qa D1: iter + items both come from the candidates envelope — no\n\t\t// separate `iterationTrigger` dep, no cross-node cache reads.\n\t\tconst generateEventNode = createNode<GenerateEvent<T>>(\n\t\t\t[candidatesNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst env = data[0] as CandidatesEnvelope<T>;\n\t\t\t\tactions.emit({\n\t\t\t\t\titeration: env.iter,\n\t\t\t\t\tcandidates: env.items,\n\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"generate-event\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(generateEventNode, { name: \"generate-event\" });\n\t\tthis.addDisposer(generateEventNode.subscribe(() => undefined));\n\n\t\tconst generatePublishEffect = createNode(\n\t\t\t[generateEventNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\thubGenerateTopic.publish(data[0] as GenerateEvent<T>);\n\t\t\t},\n\t\t\t{ name: \"generate-publish\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(generatePublishEffect, { name: \"generate-publish\" });\n\t\tthis.addDisposer(generatePublishEffect.subscribe(() => undefined));\n\n\t\tconst generateMirrorEffect = createNode(\n\t\t\t[candidatesNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst env = data[0] as CandidatesEnvelope<T>;\n\t\t\t\tprevCandidatesState.emit(env.items);\n\t\t\t},\n\t\t\t{ name: \"generate-mirror\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(generateMirrorEffect, { name: \"generate-mirror\" });\n\t\tthis.addDisposer(generateMirrorEffect.subscribe(() => undefined));\n\n\t\t// --- EVALUATE: candidates × dataset → scores ----------------------------\n\t\t// User evaluator sees the items sidecar (preserves `Evaluator<T>` API).\n\t\tconst scoresNode = evaluator(candidatesItemsNode, datasetNode);\n\t\tthis.add(scoresNode, { name: \"scores\" });\n\n\t\t// EVALUATE stage: derived event node + publish effect.\n\t\t// /qa D1: iter from candidates envelope; gate on `scoresFired` so a\n\t\t// candidates-only fan-out wave (e.g. async eval still in flight) does\n\t\t// NOT publish a stale evaluate event.\n\t\tconst evaluateEventNode = createNode<EvaluateEvent<T>>(\n\t\t\t[scoresNode, candidatesNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst scoresFired = batchData[0] != null && batchData[0].length > 0;\n\t\t\t\tif (!scoresFired) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst scores = data[0] as readonly EvalResult[];\n\t\t\t\tconst env = data[1] as CandidatesEnvelope<T>;\n\t\t\t\tactions.emit({\n\t\t\t\t\titeration: env.iter,\n\t\t\t\t\tcandidates: env.items,\n\t\t\t\t\tscores,\n\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"evaluate-event\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(evaluateEventNode, { name: \"evaluate-event\" });\n\t\tthis.addDisposer(evaluateEventNode.subscribe(() => undefined));\n\n\t\tconst evaluatePublishEffect = createNode(\n\t\t\t[evaluateEventNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\thubEvaluateTopic.publish(data[0] as EvaluateEvent<T>);\n\t\t\t},\n\t\t\t{ name: \"evaluate-publish\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(evaluatePublishEffect, { name: \"evaluate-publish\" });\n\t\tthis.addDisposer(evaluatePublishEffect.subscribe(() => undefined));\n\n\t\t// --- ANALYZE: strategy.analyze(scores, candidates) → feedbackEnvelope ---\n\t\t// /qa D1: feedbackEnvelope is the canonical iter-tagged trigger payload\n\t\t// for the DECIDE stage. Gates on `scoresFired` so a candidates-only\n\t\t// wave (async eval not settled yet) does NOT emit stale feedback into\n\t\t// `decideEffect`. When the user evaluator emits, both deps' caches are\n\t\t// consistent (candidates envelope carries iter that matches the scores\n\t\t// the user just produced — *assuming the user evaluator cancels async\n\t\t// work on candidates change; see Evaluator<T> JSDoc contract*).\n\t\tconst feedbackEnvelopeNode = createNode<FeedbackEnvelope<T>>(\n\t\t\t[scoresNode, candidatesNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst scoresFired = batchData[0] != null && batchData[0].length > 0;\n\t\t\t\tif (!scoresFired) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst scores = data[0] as readonly EvalResult[];\n\t\t\t\tconst env = data[1] as CandidatesEnvelope<T>;\n\t\t\t\tactions.emit({\n\t\t\t\t\titer: env.iter,\n\t\t\t\t\titems: env.items,\n\t\t\t\t\tscores,\n\t\t\t\t\tfeedback: latestStrategy.analyze(scores, env.items),\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"feedback-envelope\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(feedbackEnvelopeNode, { name: \"feedback-envelope\" });\n\n\t\t// User-facing feedback projection sidecar — preserves `feedback` path\n\t\t// for observers that consume the bare `Feedback` shape via\n\t\t// `loop.observe(\"feedback\")` etc.\n\t\tconst feedbackNode = createNode<Feedback>(\n\t\t\t[feedbackEnvelopeNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst fbEnv = data[0] as FeedbackEnvelope<T>;\n\t\t\t\tactions.emit(fbEnv.feedback);\n\t\t\t},\n\t\t\t{ name: \"feedback\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(feedbackNode, { name: \"feedback\" });\n\n\t\t// ANALYZE stage: derived event node + publish effect.\n\t\t// /qa D1: pull iter + items from feedbackEnvelopeNode (single source of\n\t\t// truth for the analyze beat). No cross-node cache reads.\n\t\tconst analyzeEventNode = createNode<AnalyzeEvent<T>>(\n\t\t\t[feedbackEnvelopeNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst fbEnv = data[0] as FeedbackEnvelope<T>;\n\t\t\t\tactions.emit({\n\t\t\t\t\titeration: fbEnv.iter,\n\t\t\t\t\tcandidates: fbEnv.items,\n\t\t\t\t\tfeedback: fbEnv.feedback,\n\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"analyze-event\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(analyzeEventNode, { name: \"analyze-event\" });\n\t\tthis.addDisposer(analyzeEventNode.subscribe(() => undefined));\n\n\t\tconst analyzePublishEffect = createNode(\n\t\t\t[analyzeEventNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\thubAnalyzeTopic.publish(data[0] as AnalyzeEvent<T>);\n\t\t\t},\n\t\t\t{ name: \"analyze-publish\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(analyzePublishEffect, { name: \"analyze-publish\" });\n\t\tthis.addDisposer(analyzePublishEffect.subscribe(() => undefined));\n\n\t\t// --- Convergence: four derived nodes fanning into one boolean -----------\n\t\tconst patienceNode = createNode<boolean>(\n\t\t\t[historyState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst h = data[0] as readonly Iteration<T>[];\n\t\t\t\tif (opts.patience == null || h.length <= opts.patience) {\n\t\t\t\t\tactions.emit(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// No improvement over the last `patience` iterations.\n\t\t\t\tconst lookback = h.slice(-(opts.patience + 1));\n\t\t\t\tconst baseline = lookback[0]!.bestScore;\n\t\t\t\tactions.emit(lookback.slice(1).every((i) => i.bestScore <= baseline));\n\t\t\t},\n\t\t\t{ name: \"patience-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(patienceNode, { name: \"patience-check\" });\n\n\t\tconst minScoreNode = createNode<boolean>(\n\t\t\t[scoreState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(opts.minScore != null && (data[0] as number) >= opts.minScore);\n\t\t\t},\n\t\t\t{ name: \"min-score-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(minScoreNode, { name: \"min-score-check\" });\n\n\t\tconst minDeltaNode = createNode<boolean>(\n\t\t\t[historyState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst h = data[0] as readonly Iteration<T>[];\n\t\t\t\tif (opts.minDelta == null || h.length < 2) {\n\t\t\t\t\tactions.emit(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst prev = h[h.length - 2]!.bestScore;\n\t\t\t\tconst curr = h[h.length - 1]!.bestScore;\n\t\t\t\tactions.emit(Math.abs(curr - prev) < opts.minDelta);\n\t\t\t},\n\t\t\t{ name: \"min-delta-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(minDeltaNode, { name: \"min-delta-check\" });\n\n\t\tconst maxEvalsNode = createNode<boolean>(\n\t\t\t[budgetState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(opts.maxEvaluations != null && (data[0] as number) >= opts.maxEvaluations);\n\t\t\t},\n\t\t\t{ name: \"max-evaluations-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(maxEvalsNode, { name: \"max-evaluations-check\" });\n\n\t\tconst maxIterNode = createNode<boolean>(\n\t\t\t[iterationTrigger],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(opts.maxIterations != null && (data[0] as number) >= opts.maxIterations);\n\t\t\t},\n\t\t\t{ name: \"max-iterations-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(maxIterNode, { name: \"max-iterations-check\" });\n\n\t\tconst budgetExhaustedNode = createNode<boolean>(\n\t\t\t[budgetState],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(opts.budget != null && (data[0] as number) >= opts.budget);\n\t\t\t},\n\t\t\t{ name: \"budget-exhausted-check\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(budgetExhaustedNode, { name: \"budget-exhausted-check\" });\n\n\t\t// Activate convergence derivations so their cache stays current — decideEffect\n\t\t// reads their cache via external-boundary reads (§28). They must NOT be direct\n\t\t// deps: that would create a feedback cycle (decideEffect writes history/score,\n\t\t// convergence derives from those, cycle).\n\t\tthis.addDisposer(patienceNode.subscribe(() => undefined));\n\t\tthis.addDisposer(minScoreNode.subscribe(() => undefined));\n\t\tthis.addDisposer(minDeltaNode.subscribe(() => undefined));\n\t\tthis.addDisposer(maxEvalsNode.subscribe(() => undefined));\n\t\tthis.addDisposer(maxIterNode.subscribe(() => undefined));\n\t\tthis.addDisposer(budgetExhaustedNode.subscribe(() => undefined));\n\n\t\tconst convergedNode = createNode<{ converged: boolean; reason?: string }>(\n\t\t\t[patienceNode, minScoreNode, minDeltaNode, maxEvalsNode, maxIterNode],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst [p, ms, md, me, mi] = data;\n\t\t\t\tif (p) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"patience\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (ms) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"min-score\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (md) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"min-delta\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (me) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"max-evaluations\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (mi) {\n\t\t\t\t\tactions.emit({ converged: true, reason: \"max-iterations\" });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit({ converged: false });\n\t\t\t},\n\t\t\t{ name: \"converged\", describeKind: \"derived\" },\n\t\t);\n\t\tthis.add(convergedNode, { name: \"converged\" });\n\t\tthis.addDisposer(convergedNode.subscribe(() => undefined));\n\n\t\t// --- DECIDE: feedbackEnvelope settles → fire next iteration OR terminate ---\n\t\t// **/qa D1 (2026-05-01) — reactive form via §32 envelope + sole-owner\n\t\t// `.cache` reads + reactive `pauseState` dep.** Two patterns at play:\n\t\t//\n\t\t// - **`iter` rides with the feedbackEnvelope payload** (§32 envelope).\n\t\t// Eliminates the original `iterationTrigger.cache` cross-node read\n\t\t// that caused the resume-stall (where iter.cache was bumped past\n\t\t// the candidates batch we're processing).\n\t\t//\n\t\t// - **`historyState` / `budgetState` are read via `.cache`** as a\n\t\t// sole-owner pattern: decideEffect is the SOLE WRITER + sole\n\t\t// reactive READER, both declared in the same enclosing constructor\n\t\t// scope. Reading their `.cache` here is \"read your own scratchpad\"\n\t\t// semantically, even though they're sibling Node objects. Adding\n\t\t// them as direct deps would create the §7 self-feedback cycle\n\t\t// (decideEffect writes them, would re-trigger itself); closure\n\t\t// mirrors would just duplicate state already held in the nodes\n\t\t// themselves. The comment block belongs to /qa D1 follow-up\n\t\t// (2026-05-01) — explicit user lock that sole-owner-and-reader\n\t\t// nodes in the same enclosing scope are a sanctioned `.cache` read\n\t\t// form.\n\t\t//\n\t\t// - **`pauseState` is a direct dep** because it's an EXTERNAL CONTROL\n\t\t// INPUT — written by `pause()` / `resume()` imperative methods at\n\t\t// the user-call boundary, NOT by decideEffect. Making it a real\n\t\t// declared edge surfaces \"this decision considers pause state\" in\n\t\t// `describe()` / `explain()` topology. The `feedbackFired` gate\n\t\t// below skips fn body execution when only pauseState fired (no new\n\t\t// iteration to decide).\n\t\t//\n\t\t// Trigger semantics: feedbackEnvelopeNode itself only fires when the\n\t\t// user evaluator emits fresh scores (gate via `batchData[scoresIdx]`\n\t\t// in feedbackEnvelopeNode), so a candidates-only fan-out wave (async\n\t\t// eval still in flight after `resume()`) does NOT spuriously trigger\n\t\t// decideEffect.\n\t\t//\n\t\t// **Score-staleness contract:** if the user's `Evaluator<T>` does NOT\n\t\t// cancel its async work when `candidates` changes, late scores from a\n\t\t// prior iter can emit to scoresNode and trip feedbackEnvelopeNode +\n\t\t// decideEffect with the new candidates' iter tag but stale scores\n\t\t// data. See `Evaluator<T>` JSDoc (cancel-on-input contract) and\n\t\t// `optimizations.md` \"refineLoop async-evaluator stale-scores\n\t\t// follow-up\" for the wrapper proposal.\n\t\t//\n\t\t// Track last-decided iteration to avoid re-deciding when feedbackEnv\n\t\t// re-fires within one wave (e.g. async evaluator emits multiple\n\t\t// scores per candidates change).\n\t\tlet lastDecidedIteration = -1;\n\t\tconst decideEffect = createNode(\n\t\t\t[feedbackEnvelopeNode, pauseState],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\t// `pauseState` is declared dep #1 — gate skips fn body when\n\t\t\t\t// only pauseState fired (no new iteration to decide; we just\n\t\t\t\t// want pauseState's prevData to advance for the next feedback\n\t\t\t\t// fire).\n\t\t\t\tconst feedbackFired = batchData[0] != null && batchData[0].length > 0;\n\t\t\t\tif (!feedbackFired) return;\n\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst fbEnv = data[0] as FeedbackEnvelope<T>;\n\t\t\t\tconst paused = data[1] as boolean;\n\n\t\t\t\tconst i = fbEnv.iter;\n\t\t\t\tconst fb = fbEnv.feedback;\n\t\t\t\tconst cs = fbEnv.items;\n\t\t\t\tconst scores = fbEnv.scores;\n\n\t\t\t\t// De-dup: only run once per iteration. fn may fire multiple\n\t\t\t\t// times per wave as feedbackEnvelopeNode settles.\n\t\t\t\tif (i <= lastDecidedIteration) return;\n\t\t\t\tlastDecidedIteration = i;\n\n\t\t\t\t// Sole-owner `.cache` reads — decideEffect is the SOLE\n\t\t\t\t// writer and sole reactive reader of these state nodes.\n\t\t\t\tconst currentHistory = historyState.cache as readonly Iteration<T>[];\n\t\t\t\tconst currentBudget = budgetState.cache as number;\n\n\t\t\t\t// Compute next history / score.\n\t\t\t\tconst { best, bestScore } = pickBest(cs, scores);\n\t\t\t\tconst iteration: Iteration<T> = {\n\t\t\t\t\tn: i,\n\t\t\t\t\tcandidates: cs,\n\t\t\t\t\tscores,\n\t\t\t\t\tfeedback: fb,\n\t\t\t\t\tbest,\n\t\t\t\t\tbestScore,\n\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t};\n\t\t\t\tconst nextHistory = [...currentHistory, iteration];\n\t\t\t\t// Budget accounting — decideEffect is the single authority.\n\t\t\t\tconst nextBudget = currentBudget + cs.length;\n\n\t\t\t\t// Inline convergence checks — single source of truth. The derived\n\t\t\t\t// `convergedNode` + friends exist for describe()/observe() surface;\n\t\t\t\t// inlining here avoids a drain-round-trip deadlock where decideEffect\n\t\t\t\t// would need convergedNode.cache to update before running, but\n\t\t\t\t// convergedNode needs historyState.emit from inside decideEffect.\n\t\t\t\tlet decision: DecideEvent[\"decision\"] = \"continue\";\n\t\t\t\tlet reason: string | undefined;\n\t\t\t\tconst budgetOut = opts.budget != null && nextBudget >= opts.budget;\n\t\t\t\tif (budgetOut) {\n\t\t\t\t\tdecision = \"budget\";\n\t\t\t\t\treason = \"budget\";\n\t\t\t\t} else if (opts.minScore != null && fb.score >= opts.minScore) {\n\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\treason = \"min-score\";\n\t\t\t\t} else if (opts.maxIterations != null && i >= opts.maxIterations) {\n\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\treason = \"max-iterations\";\n\t\t\t\t} else if (opts.maxEvaluations != null && nextBudget >= opts.maxEvaluations) {\n\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\treason = \"max-evaluations\";\n\t\t\t\t} else if (opts.minDelta != null && nextHistory.length >= 2) {\n\t\t\t\t\tconst prev = nextHistory[nextHistory.length - 2]!.bestScore;\n\t\t\t\t\tconst curr = nextHistory[nextHistory.length - 1]!.bestScore;\n\t\t\t\t\tif (Math.abs(curr - prev) < opts.minDelta) {\n\t\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\t\treason = \"min-delta\";\n\t\t\t\t\t}\n\t\t\t\t} else if (opts.patience != null && nextHistory.length > opts.patience) {\n\t\t\t\t\tconst lookback = nextHistory.slice(-(opts.patience + 1));\n\t\t\t\t\tconst baseline = lookback[0]!.bestScore;\n\t\t\t\t\tif (lookback.slice(1).every((it) => it.bestScore <= baseline)) {\n\t\t\t\t\t\tdecision = \"converged\";\n\t\t\t\t\t\treason = \"patience\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// paused takes precedence over continue — if paused AND no convergence,\n\t\t\t\t// we pause. Otherwise if converged we stop for real.\n\t\t\t\tif (decision === \"continue\" && paused) {\n\t\t\t\t\tdecision = \"paused\";\n\t\t\t\t}\n\n\t\t\t\t// All emissions in one batch — drain order is feedback mirror first\n\t\t\t\t// (§32), then iterationTrigger, so the next generate sees fresh fb.\n\t\t\t\t// `lastFeedbackState` is always mirrored (regardless of decision) so\n\t\t\t\t// resume-after-pause gets current feedback; only `iterationTrigger`\n\t\t\t\t// is gated on `continue`.\n\t\t\t\tbatch(() => {\n\t\t\t\t\t// `best` is `T | null` from pickBest — `null` only on an empty\n\t\t\t\t\t// candidate batch (strategies throw on empty, so unreachable in\n\t\t\t\t\t// practice). Skip the emit rather than pushing `null` into the\n\t\t\t\t\t// SENTINEL `Node<T>`: a degenerate iteration preserves the prior\n\t\t\t\t\t// best instead of wiping it. (Anti-pattern sweep 2026-05-18.)\n\t\t\t\t\tif (best !== null) bestState.emit(best);\n\t\t\t\t\tscoreState.emit(fb.score);\n\t\t\t\t\thistoryState.emit(nextHistory);\n\t\t\t\t\tbudgetState.emit(nextBudget);\n\t\t\t\t\tlastFeedbackState.emit(fb);\n\t\t\t\t\thubDecideTopic.publish({\n\t\t\t\t\t\titeration: i,\n\t\t\t\t\t\tdecision,\n\t\t\t\t\t\treason,\n\t\t\t\t\t\ttimestamp_ns: monotonicNs(),\n\t\t\t\t\t});\n\n\t\t\t\t\tif (decision === \"continue\") {\n\t\t\t\t\t\titerationTrigger.emit(i + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstatusState.emit(\n\t\t\t\t\t\t\tdecision === \"converged\" ? \"converged\" : decision === \"budget\" ? \"budget\" : \"paused\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ name: \"decide-bridge\", describeKind: \"effect\" },\n\t\t);\n\t\tthis.add(decideEffect, { name: \"decide-bridge\" });\n\t\tthis.addDisposer(decideEffect.subscribe(() => undefined));\n\n\t\t// /qa A1 (2026-04-30): public field surface (best / score / status /\n\t\t// history / strategy / iteration / generate / evaluate / analyze /\n\t\t// decide / _pauseState) is assigned EARLIER, immediately after the\n\t\t// stage hub is mounted (search \"qa A1\" above). Doing the assignment\n\t\t// before any subscribe activation keeps `this.<field>` reachable\n\t\t// during a synchronous strategy drain.\n\t}\n\n\t/** Swap the active strategy mid-run (human-in-the-loop handoff). */\n\tsetStrategy(next: RefineStrategy<T>): void {\n\t\tthis.strategy.emit(next);\n\t}\n\n\t/** Pause after the current iteration completes. */\n\tpause(): void {\n\t\tthis._pauseState.emit(true);\n\t}\n\n\t/**\n\t * Resume a paused loop. Idempotent: only un-pauses from the \"paused\"\n\t * terminal state. Converged / budget / errored are permanent — a user\n\t * wanting to start over should construct a fresh refineLoop.\n\t */\n\tresume(): void {\n\t\tif (this.status.cache !== \"paused\") return;\n\t\tbatch(() => {\n\t\t\tthis._pauseState.emit(false);\n\t\t\tthis.status.emit(\"running\" as RefineStatus);\n\t\t\tthis._iteration.emit((this._iteration.cache as number) + 1);\n\t\t});\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Structural type-guard for `Node<T>`. Checks the three core Node methods\n * (`subscribe`, `down`, `emit`) as callable properties — rejects plain objects\n * with a single `subscribe` field that happen to look like a Node but aren't.\n */\nfunction isNode<T>(x: unknown): x is Node<T> {\n\tif (typeof x !== \"object\" || x === null) return false;\n\tconst obj = x as Record<string, unknown>;\n\treturn (\n\t\ttypeof obj.subscribe === \"function\" &&\n\t\ttypeof obj.down === \"function\" &&\n\t\ttypeof obj.emit === \"function\"\n\t);\n}\n\nfunction pickBest<T>(\n\tcandidates: readonly T[],\n\tscores: readonly EvalResult[],\n): { best: T | null; bestScore: number } {\n\t// Empty batch → no best. Use `null` per COMPOSITION-GUIDE §3: `undefined`\n\t// is the protocol SENTINEL, `null` is the domain sentinel for \"no value\".\n\tif (candidates.length === 0) {\n\t\treturn { best: null, bestScore: Number.NEGATIVE_INFINITY };\n\t}\n\tif (candidates.length === 1) {\n\t\tconst mean = meanScore(scores);\n\t\treturn { best: candidates[0]!, bestScore: mean };\n\t}\n\t// Fan-out aware: when any score carries `candidateIndex`, aggregate mean\n\t// score per candidate. When absent, fall back to positional `scores[i]` ↔\n\t// `candidates[i]` alignment (one-score-per-candidate convention).\n\tconst hasFanOut = scores.some((s) => typeof s.candidateIndex === \"number\");\n\tif (hasFanOut) {\n\t\tconst sums = new Array<{ sum: number; count: number }>(candidates.length);\n\t\tfor (let i = 0; i < candidates.length; i++) sums[i] = { sum: 0, count: 0 };\n\t\tfor (const s of scores) {\n\t\t\tconst idx = s.candidateIndex;\n\t\t\tif (typeof idx === \"number\" && idx >= 0 && idx < candidates.length) {\n\t\t\t\tsums[idx]!.sum += s.score;\n\t\t\t\tsums[idx]!.count += 1;\n\t\t\t}\n\t\t}\n\t\tlet best = candidates[0]!;\n\t\tlet bestScore = sums[0]!.count > 0 ? sums[0]!.sum / sums[0]!.count : Number.NEGATIVE_INFINITY;\n\t\tfor (let i = 1; i < candidates.length; i++) {\n\t\t\tconst avg = sums[i]!.count > 0 ? sums[i]!.sum / sums[i]!.count : Number.NEGATIVE_INFINITY;\n\t\t\tif (avg > bestScore) {\n\t\t\t\tbestScore = avg;\n\t\t\t\tbest = candidates[i]!;\n\t\t\t}\n\t\t}\n\t\treturn { best, bestScore };\n\t}\n\tlet best = candidates[0]!;\n\tlet bestScore = scores[0]?.score ?? Number.NEGATIVE_INFINITY;\n\tfor (let i = 1; i < candidates.length; i++) {\n\t\tconst s = scores[i]?.score ?? Number.NEGATIVE_INFINITY;\n\t\tif (s > bestScore) {\n\t\t\tbestScore = s;\n\t\t\tbest = candidates[i]!;\n\t\t}\n\t}\n\treturn { best, bestScore };\n}\n\nfunction meanScore(scores: readonly EvalResult[]): number {\n\tif (scores.length === 0) return Number.NEGATIVE_INFINITY;\n\tlet sum = 0;\n\tfor (const s of scores) sum += s.score;\n\treturn sum / scores.length;\n}\n\n// ---------------------------------------------------------------------------\n// refineLoop factory\n// ---------------------------------------------------------------------------\n\n/**\n * Construct a {@link RefineLoopGraph} — the universal prompt/artifact\n * optimization loop. Thin wrapper over `new RefineLoopGraph(...)` for\n * call-site ergonomics.\n */\nexport function refineLoop<T>(\n\tseed: T,\n\tevaluator: Evaluator<T>,\n\tinitialStrategy: RefineStrategy<T>,\n\topts: RefineLoopOptions,\n): RefineLoopGraph<T> {\n\treturn new RefineLoopGraph<T>(seed, evaluator, initialStrategy, opts);\n}\n\n// ---------------------------------------------------------------------------\n// Built-in strategy: blindVariation\n// ---------------------------------------------------------------------------\n\n/**\n * Context passed to a `blindVariation` teacher per call. `reportCost` is a\n * per-call hook — see `BlindVariationOptions.tokens`.\n */\nexport interface BlindVariationContext<T> {\n\treadonly prior: T;\n\t/**\n\t * Report tokens consumed by this teacher call. Aggregated per iteration\n\t * and flushed to `opts.tokens` in the strategy's `finally` block so\n\t * partial spend is preserved when the teacher throws mid-batch.\n\t */\n\treadonly reportCost: (tokens: number) => void;\n}\n\nexport interface BlindVariationOptions<T> {\n\t/** Name — default: `\"blindVariation\"`. */\n\tname?: string;\n\t/** Number of candidates generated per iteration. Default: 4. */\n\twidth?: number;\n\t/**\n\t * Run teacher calls in parallel via `Promise.all`. Default `true` — the\n\t * common case (independent LLM calls). Set `false` to run sequentially\n\t * via `for/await` when teachers share stateful resources (rate limiters,\n\t * rolling context, serial API ordering) that don't tolerate concurrency.\n\t */\n\tparallel?: boolean;\n\t/**\n\t * Optional cost counter node. Running total tokens reported via\n\t * `ctx.reportCost` during each iteration is added to this node in the\n\t * strategy's `finally` block — fires on success AND on teacher throw so\n\t * partial spend is never lost. User owns the node; wire to `budgetGate`,\n\t * `attachSnapshotStorage`, telemetry, etc.\n\t */\n\ttokens?: Node<number>;\n\t/**\n\t * Teacher — given `{prior, reportCost}`, produce one variant. Async\n\t * allowed. Called `width` times per iteration. Call `ctx.reportCost(n)`\n\t * to track tokens consumed per call (optional, no-op if `opts.tokens`\n\t * is not set).\n\t */\n\tteacher: (ctx: BlindVariationContext<T>) => Promise<T> | T;\n}\n\n/**\n * Simplest built-in strategy: generate N variants per iteration via the\n * supplied `teacher`; no feedback-informed steering (equivalent to Random\n * Search). Validates the loop infrastructure end-to-end and is the baseline\n * every other strategy should outperform.\n *\n * `analyze` records the mean score and flags the worst task — strategies that\n * care about per-task critique layer on top.\n */\nexport function blindVariation<T>(opts: BlindVariationOptions<T>): RefineStrategy<T> {\n\tconst width = opts.width ?? 4;\n\tconst name = opts.name ?? \"blindVariation\";\n\treturn {\n\t\tname,\n\t\tseed(seed) {\n\t\t\t// Iteration 0 emits just the seed — strategy.seed is synchronous by\n\t\t\t// contract, so we can't call an async teacher here. `width`-many\n\t\t\t// teacher-produced variants begin at iteration 1 via `generate`.\n\t\t\treturn [seed];\n\t\t},\n\t\tanalyze(scores, _candidates) {\n\t\t\tconst score = meanScore(scores);\n\t\t\tlet worst: EvalResult | null = null;\n\t\t\tfor (const s of scores) {\n\t\t\t\tif (!worst || s.score < worst.score) worst = s;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tsummary: `blindVariation iteration: mean=${score.toFixed(3)}, n=${scores.length}`,\n\t\t\t\tscore,\n\t\t\t\tweakTasks: worst ? [worst.taskId] : [],\n\t\t\t};\n\t\t},\n\t\tasync generate(_feedback, candidates) {\n\t\t\tif (candidates.length === 0) {\n\t\t\t\t// Empty candidate batch is a contract violation — either the\n\t\t\t\t// seed was empty or a previous generate returned nothing. Surface\n\t\t\t\t// as an error rather than silently returning [] (which would\n\t\t\t\t// stall the loop in an infinite zero-candidate cycle).\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"blindVariation.generate: empty candidate batch — cannot derive prior for teacher\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Pick the current \"recent best\" — `null` IS a valid domain value\n\t\t\t// per COMPOSITION-GUIDE §3; the length guard above has already\n\t\t\t// filtered the `undefined` protocol sentinel.\n\t\t\tconst prior = candidates[candidates.length - 1] as T;\n\t\t\tlet iterCost = 0;\n\t\t\tconst reportCost = (n: number) => {\n\t\t\t\titerCost += n;\n\t\t\t};\n\t\t\tconst ctx: BlindVariationContext<T> = { prior, reportCost };\n\t\t\ttry {\n\t\t\t\tif (opts.parallel !== false) {\n\t\t\t\t\treturn await Promise.all(Array.from({ length: width }, () => opts.teacher(ctx)));\n\t\t\t\t}\n\t\t\t\tconst out: T[] = [];\n\t\t\t\tfor (let i = 0; i < width; i++) {\n\t\t\t\t\tout.push(await opts.teacher(ctx));\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t} finally {\n\t\t\t\tif (opts.tokens != null && iterCost > 0) {\n\t\t\t\t\t// /qa D1 follow-up (2026-05-01): replaced direct `.cache` read\n\t\t\t\t\t// + emit with `tryIncrementBounded`, which encapsulates the\n\t\t\t\t\t// self-owned-counter `.cache` access in the canonical helper\n\t\t\t\t\t// (sole sanctioned site per its JSDoc). Cap is unbounded for\n\t\t\t\t\t// the token meter.\n\t\t\t\t\ttryIncrementBounded(opts.tokens, Number.MAX_SAFE_INTEGER, iterCost);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Built-in strategy: errorCritique\n// ---------------------------------------------------------------------------\n\n/**\n * Context passed to an `errorCritique` teacher. `critique` is the pre-formatted\n * summary a prompt template can drop in verbatim; `failures` carries the\n * structured evidence (per-task error / score / detail) for richer prompts.\n */\nexport interface ErrorCritiqueContext<T> {\n\treadonly prior: T;\n\treadonly critique: string;\n\treadonly failures: readonly EvalResult[];\n\t/**\n\t * Report tokens consumed by this teacher call. Aggregated per iteration\n\t * and flushed to `opts.tokens` in the strategy's `finally` block so\n\t * partial spend is preserved when the teacher throws mid-batch.\n\t */\n\treadonly reportCost: (tokens: number) => void;\n}\n\nexport interface ErrorCritiqueOptions<T> {\n\t/** Name — default: `\"errorCritique\"`. */\n\tname?: string;\n\t/** Number of candidates generated per iteration. Default: 4. */\n\twidth?: number;\n\t/**\n\t * Cut-off below which a task is classified as a failure and fed into the\n\t * critique. Default: the batch mean — any task scoring below the batch\n\t * mean is a failure. Pass a number for an absolute cut-off, or a function\n\t * for per-batch computation (e.g. a percentile). When the default mean\n\t * is non-finite (NaN / ±Infinity from a degenerate evaluator), ALL scores\n\t * are treated as failures so the critique loop continues to steer.\n\t */\n\tfailureThreshold?: number | ((scores: readonly EvalResult[]) => number);\n\t/** Cap on failure samples packed into the critique. Default: 5. */\n\tmaxFailureSamples?: number;\n\t/**\n\t * Format failures into the `critique` string passed to the teacher. Default\n\t * joins `- taskId (score=N) | error: …` lines. Override to shape LLM prompts.\n\t *\n\t * **Note:** the `feedback` argument is a shell with `{score, weakTasks}`\n\t * populated; `summary` is empty because `analyze` computes the final summary\n\t * AFTER `formatCritique` runs (the summary embeds the formatted count).\n\t * Rely on `failures` and `feedback.score` — do not read `feedback.summary`\n\t * here.\n\t */\n\tformatCritique?: (failures: readonly EvalResult[], feedback: Feedback) => string;\n\t/**\n\t * Run teacher calls in parallel via `Promise.all`. Default `true` — the\n\t * common case (independent LLM calls). Set `false` to run sequentially\n\t * via `for/await` when teachers share stateful resources (rate limiters,\n\t * rolling context, serial API ordering) that don't tolerate concurrency.\n\t */\n\tparallel?: boolean;\n\t/**\n\t * Optional cost counter node. Running total tokens reported via\n\t * `ctx.reportCost` during each iteration is added to this node in the\n\t * strategy's `finally` block — fires on success AND on teacher throw so\n\t * partial spend is never lost. User owns the node; wire to `budgetGate`,\n\t * `attachSnapshotStorage`, telemetry, etc.\n\t */\n\ttokens?: Node<number>;\n\t/**\n\t * Teacher — given `{prior, critique, failures, reportCost}`, produce one\n\t * refined variant. Called `width` times per iteration. Async allowed.\n\t * Call `ctx.reportCost(n)` to track tokens consumed per call (optional,\n\t * no-op if `opts.tokens` is not set).\n\t */\n\tteacher: (ctx: ErrorCritiqueContext<T>) => Promise<T> | T;\n}\n\n/**\n * Private payload stashed inside `Feedback.critique` so `generate` can recover\n * the analyze-time prior + failure set without another pass over scores.\n */\ninterface ErrorCritiquePrivate<T> {\n\treadonly kind: \"errorCritique\";\n\treadonly best: T | null;\n\treadonly failures: readonly EvalResult[];\n\treadonly critiqueText: string;\n}\n\nfunction isErrorCritiquePrivate<T>(v: unknown): v is ErrorCritiquePrivate<T> {\n\treturn typeof v === \"object\" && v !== null && (v as { kind?: unknown }).kind === \"errorCritique\";\n}\n\nfunction defaultFormatCritique(failures: readonly EvalResult[], feedback: Feedback): string {\n\tif (failures.length === 0) {\n\t\treturn `No task scored below the batch mean (${feedback.score.toFixed(3)}). Reinforce the current direction.`;\n\t}\n\tconst lines = failures.map((f) => {\n\t\tconst err = f.error != null ? ` | error: ${f.error}` : \"\";\n\t\treturn `- ${f.taskId} (score=${f.score.toFixed(3)})${err}`;\n\t});\n\treturn `Failures below threshold:\\n${lines.join(\"\\n\")}`;\n}\n\n/**\n * Critique-driven strategy (ProTeGi-style \"textual gradient\"). Each iteration:\n * 1. `analyze` classifies tasks scoring below a threshold as failures, picks\n * the best candidate from the batch, and packs both plus a formatted\n * critique string into `feedback.critique` as a private payload.\n * 2. `generate` unpacks that payload and calls the teacher with\n * `{prior, critique, failures, reportCost}` `width` times, returning the\n * refined batch.\n *\n * The teacher receives a pre-formatted string (drop into an LLM prompt) AND\n * the structured failure list (for richer prompts that want per-task detail).\n * Throws on empty candidate batches — matches `blindVariation`'s contract\n * (no silent zero-candidate cycles).\n *\n * When `setStrategy()` swaps this strategy in mid-run, the first `generate`\n * may receive a `Feedback` produced by the prior strategy (no private payload);\n * the fallback path uses `candidates[last]` as the prior and the feedback\n * summary as the critique, so the loop keeps running without a stall. When a\n * private payload IS present, `priv.critiqueText` takes precedence over any\n * edits a caller made to `feedback.summary` — treat `critique` as the\n * strategy-owned channel.\n */\nexport function errorCritique<T>(opts: ErrorCritiqueOptions<T>): RefineStrategy<T> {\n\tconst width = opts.width ?? 4;\n\tconst name = opts.name ?? \"errorCritique\";\n\tconst maxFailureSamples = opts.maxFailureSamples ?? 5;\n\tconst format = opts.formatCritique ?? defaultFormatCritique;\n\n\treturn {\n\t\tname,\n\t\tseed(seed) {\n\t\t\t// Iteration 0 emits just the seed. The critique loop begins at\n\t\t\t// iteration 1, once real scores exist to derive failures from.\n\t\t\treturn [seed];\n\t\t},\n\t\tanalyze(scores, candidates) {\n\t\t\tconst score = meanScore(scores);\n\t\t\tconst userThreshold =\n\t\t\t\ttypeof opts.failureThreshold === \"function\"\n\t\t\t\t\t? opts.failureThreshold(scores)\n\t\t\t\t\t: opts.failureThreshold;\n\t\t\t// A1: when the user didn't supply a threshold AND the batch-mean\n\t\t\t// default is non-finite (e.g. evaluator produced NaN / ±Infinity),\n\t\t\t// treat every score as a failure instead of filtering with `< NaN`\n\t\t\t// (which would be false for every score → silent no-op).\n\t\t\tconst thresholdUnresolvable = userThreshold === undefined && !Number.isFinite(score);\n\t\t\tconst threshold = userThreshold ?? score;\n\t\t\tconst allFailures = thresholdUnresolvable\n\t\t\t\t? [...scores].sort((a, b) => a.score - b.score)\n\t\t\t\t: scores\n\t\t\t\t\t\t.filter((s) => s.score < threshold)\n\t\t\t\t\t\t.slice()\n\t\t\t\t\t\t.sort((a, b) => a.score - b.score);\n\t\t\tconst failures = allFailures.slice(0, maxFailureSamples);\n\n\t\t\tconst { best, bestScore } = pickBest(candidates, scores);\n\t\t\tconst feedbackShell: Feedback = {\n\t\t\t\tsummary: \"\",\n\t\t\t\tscore,\n\t\t\t\tweakTasks: failures.map((f) => f.taskId),\n\t\t\t};\n\t\t\tconst critiqueText = format(failures, feedbackShell);\n\n\t\t\tconst priv: ErrorCritiquePrivate<T> = {\n\t\t\t\tkind: \"errorCritique\",\n\t\t\t\tbest,\n\t\t\t\tfailures,\n\t\t\t\tcritiqueText,\n\t\t\t};\n\t\t\tconst retainedSuffix =\n\t\t\t\tallFailures.length > failures.length ? ` (top ${failures.length} retained)` : \"\";\n\t\t\treturn {\n\t\t\t\tsummary: `errorCritique iteration: mean=${score.toFixed(3)}, failures=${allFailures.length}${retainedSuffix}/${scores.length}, bestScore=${bestScore.toFixed(3)}`,\n\t\t\t\tcritique: priv,\n\t\t\t\tweakTasks: failures.map((f) => f.taskId),\n\t\t\t\tscore,\n\t\t\t};\n\t\t},\n\t\tasync generate(feedback, candidates) {\n\t\t\t// N1: Length guard FIRST. The only protocol-sentinel risk is\n\t\t\t// `undefined` sneaking in via an empty candidates array; after\n\t\t\t// this check, `null` values (including `priv.best === null` when\n\t\t\t// T admits null) flow through as domain-valid per\n\t\t\t// COMPOSITION-GUIDE §3 / spec §1.\n\t\t\tif (candidates.length === 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"errorCritique.generate: empty candidate batch — cannot derive prior for teacher\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst priv = isErrorCritiquePrivate<T>(feedback.critique) ? feedback.critique : undefined;\n\t\t\tconst prior: T =\n\t\t\t\tpriv !== undefined ? (priv.best as T) : (candidates[candidates.length - 1] as T);\n\t\t\tconst critique = priv?.critiqueText ?? feedback.summary;\n\t\t\tconst failures = priv?.failures ?? [];\n\t\t\tlet iterCost = 0;\n\t\t\tconst reportCost = (n: number) => {\n\t\t\t\titerCost += n;\n\t\t\t};\n\t\t\tconst ctx: ErrorCritiqueContext<T> = { prior, critique, failures, reportCost };\n\t\t\ttry {\n\t\t\t\tif (opts.parallel !== false) {\n\t\t\t\t\treturn await Promise.all(Array.from({ length: width }, () => opts.teacher(ctx)));\n\t\t\t\t}\n\t\t\t\tconst out: T[] = [];\n\t\t\t\tfor (let i = 0; i < width; i++) {\n\t\t\t\t\tout.push(await opts.teacher(ctx));\n\t\t\t\t}\n\t\t\t\treturn out;\n\t\t\t} finally {\n\t\t\t\tif (opts.tokens != null && iterCost > 0) {\n\t\t\t\t\t// /qa D1 follow-up (2026-05-01): replaced direct `.cache` read\n\t\t\t\t\t// + emit with `tryIncrementBounded`, which encapsulates the\n\t\t\t\t\t// self-owned-counter `.cache` access in the canonical helper.\n\t\t\t\t\ttryIncrementBounded(opts.tokens, Number.MAX_SAFE_INTEGER, iterCost);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * Universal mutation framework (Phase 14 — DS-14 locked 2026-05-05).\n *\n * Single `mutate(act, opts)` factory replaces the prior `lightMutation` +\n * `wrapMutation` two-tier split (pre-1.0 break per Q-O2).\n *\n * Two frames:\n * - `\"inline\"` — no batch; up() runs raw. Seq bumps before action; persists\n * on throw. Hot-path-friendly for atomic single-write mutations.\n * - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n * deferred deliveries, then `down()` runs (if provided), then failure record.\n *\n * Phase-4 primitives share the same shape: imperative mutation methods +\n * closure state + reactive audit log + freeze-at-entry + rollback-on-throw.\n * This module factors out the common machinery so each primitive becomes\n * declarative wiring over typed audit records.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tDIRTY,\n\ttype Node,\n\ttype NodeGuard,\n\tnode,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype ReactiveLogBundle,\n\ttype ReactiveLogOptions,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\n\n// ── tryIncrementBounded ──────────────────────────────────────────────────\n\n/**\n * Bounded increment for a self-owned counter state node.\n *\n * Reads `counter.cache`, bumps by `by` (default 1) if `cur + by <= cap`,\n * writes back. Returns `false` when the cap would be exceeded (no-op write).\n * Documented P3 exception: the counter is not a declared dep of the caller —\n * it's a private budget read+written from a single call site. This helper\n * keeps the `.cache` access in one named place so caller bodies (which may\n * be inside reactive fn execution paths) stay free of cross-node `.cache`\n * reads.\n *\n * **Safety today:**\n * 1. Single-threaded JS runner never invokes the caller concurrently.\n * 2. `counter.down` writes the cache synchronously before returning, so\n * synchronous re-entry through a downstream publish reads the\n * freshly-incremented value — no double-count.\n *\n * **Future risk:** under a free-threaded runner (PY no-GIL or hypothetical\n * concurrent TS runner), two concurrent firings could still race. Revisit\n * when that surfaces.\n *\n * @param counter - Self-owned counter Node. Caller is the sole writer.\n * @param cap - Upper bound (inclusive). Pass `Number.MAX_SAFE_INTEGER` for\n * \"effectively unbounded\" use cases (e.g. token meters).\n * @param by - Delta to add (default `1`). Must be a finite non-negative\n * number; callers should pre-validate. Overflow-safe via\n * `by > cap - cur` check rather than `cur + by >= cap`.\n */\nexport function tryIncrementBounded(counter: Node<number>, cap: number, by = 1): boolean {\n\tconst cur = (counter.cache as number | undefined) ?? 0;\n\tif (by > cap - cur) return false;\n\tcounter.down([[DIRTY], [DATA, cur + by]]);\n\treturn true;\n}\n\n// ── Audit record schema ──────────────────────────────────────────────────\n\n/** Shared base shape for every audit record. Per-primitive types extend this. */\nexport interface BaseAuditRecord {\n\treadonly t_ns: number;\n\treadonly seq?: number;\n\treadonly handlerVersion?: { id: string; version: string | number };\n}\n\n// ── Default audit guard ──────────────────────────────────────────────────\n\n/**\n * Allow `observe` and `signal`; deny external `write` on the audit log so\n * consumers can subscribe + signal-bridge but cannot inject fake records.\n */\nexport const DEFAULT_AUDIT_GUARD: NodeGuard = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ── createAuditLog ───────────────────────────────────────────────────────\n\nexport type AuditLogOpts<R extends BaseAuditRecord> = {\n\tname: string;\n\t/** Bounded retention; default 1024 per Audit 2 / cross-cutting bounded-default policy. */\n\tretainedLimit?: number;\n\t/** Override the default audit guard. */\n\tguard?: NodeGuard;\n\t/** Mount the audit `entries` Node under this graph (and activate withLatest). */\n\tgraph?: Graph;\n\t/** Pass-through to {@link reactiveLog}. */\n\tversioning?: ReactiveLogOptions<R>[\"versioning\"];\n};\n\n/**\n * Build a reactive audit log with sane defaults: bounded retention, deny-write\n * guard, `withLatest()` companions activated. Returns the {@link ReactiveLogBundle}\n * directly — primitives expose this as `<primitive>.events` / `.decisions` /\n * `.dispatches` / `.invocations` and alias it as `.audit`.\n *\n * @category internal\n */\nexport function createAuditLog<R extends BaseAuditRecord>(\n\topts: AuditLogOpts<R>,\n): ReactiveLogBundle<R> {\n\tconst log = reactiveLog<R>([], {\n\t\tname: opts.name,\n\t\tmaxSize: opts.retainedLimit ?? 1024,\n\t\tguard: opts.guard ?? DEFAULT_AUDIT_GUARD,\n\t\t...(opts.versioning != null ? { versioning: opts.versioning } : {}),\n\t});\n\t// Lazy companion activation up-front so `bundle.lastValue` / `hasLatest`\n\t// are queryable without an explicit `withLatest()` call.\n\tlog.withLatest();\n\tif (opts.graph) {\n\t\topts.graph.add(log.entries, { name: opts.name });\n\t}\n\treturn log;\n}\n\n/**\n * Read-only projection of a {@link ReactiveLogBundle}. Exposes only the\n * observation surface (`entries` / `size` / `at` / `withLatest` / `lastValue`\n * / `view` / `scan` / `mutationLog`) — the mutators (`append` / `appendMany`\n * / `clear` / `trimHead` / `attach` / `attachStorage`) and the lifecycle\n * disposers are intentionally absent.\n */\nexport type ReadonlyAuditLog<R> = Pick<\n\tReactiveLogBundle<R>,\n\t\"entries\" | \"size\" | \"at\" | \"withLatest\" | \"lastValue\" | \"view\" | \"scan\" | \"mutationLog\"\n>;\n\n/**\n * Wrap an audit log so the `.audit` alias a primitive exposes (the Audit-2\n * `.audit` duplication convention — `saga.audit` / `cqrs.audit` /\n * `jobQueue.audit` / `processManager.audit`) is a **stable read-only view**,\n * not the live mutable bundle. Closes M7: a consumer calling\n * `someGraph.audit.append(...)` would otherwise silently mutate the owning\n * primitive's canonical log. The returned object is frozen and shares the\n * underlying log's nodes (zero copy) — reads are byte-identical to the live\n * bundle; mutators are simply not present (compile-time) and the object is\n * frozen (run-time defense for JS callers).\n *\n * @category internal\n */\nexport function readonlyAuditLog<R>(log: ReactiveLogBundle<R>): ReadonlyAuditLog<R> {\n\treturn Object.freeze({\n\t\tget entries() {\n\t\t\treturn log.entries;\n\t\t},\n\t\tget size() {\n\t\t\treturn log.size;\n\t\t},\n\t\tget lastValue() {\n\t\t\treturn log.lastValue;\n\t\t},\n\t\tget mutationLog() {\n\t\t\treturn log.mutationLog;\n\t\t},\n\t\tat: log.at.bind(log),\n\t\twithLatest: log.withLatest.bind(log),\n\t\tview: log.view.bind(log),\n\t\tscan: log.scan.bind(log),\n\t}) satisfies ReadonlyAuditLog<R>;\n}\n\n// ── Universal mutation factory (Phase 14 — DS-14 lock Q-O2/Q-O3) ────────\n//\n// Single `mutate(act, opts)` factory. Two frames:\n//\n// - `\"inline\"` — no batch frame; up() runs raw. Seq bumps before action;\n// persists on throw. Hot-path-friendly for atomic single-write mutations.\n//\n// - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n// deferred deliveries, then `down()` runs, then failure record persists.\n//\n// **Heuristic:** if your imperative method's body is one or two lines (mutate\n// state, emit), use `frame: \"inline\"`. If it runs a user-supplied handler or\n// has multiple steps that could leave inconsistent state mid-throw, use\n// `frame: \"transactional\"`.\n\nexport type FailureMeta = {\n\tt_ns: number;\n\tseq?: number;\n\terrorType: string;\n};\n\nexport type SuccessMeta = {\n\tt_ns: number;\n\tseq?: number;\n};\n\n/**\n * Mutation action shape. Plain function shorthand auto-wraps as `{ up: fn }`.\n *\n * - `up` — the mutation action (the \"up migration\").\n * - `down` — optional rollback for closure mutations that `batch()` can't\n * reach. Receives the SAME frozen args as `up`. Runs AFTER batch reactive\n * rollback, BEFORE the failure record. Throws inside `down` are\n * console.error'd without masking the original error. Only meaningful\n * with `frame: \"transactional\"`.\n */\nexport type MutationAct<TArgs extends readonly unknown[], TResult> = {\n\tup: (...args: TArgs) => TResult;\n\tdown?: (...args: TArgs) => void;\n};\n\nexport type MutationFrame = \"inline\" | \"transactional\";\n\nexport type MutateOpts<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord> = {\n\t/** Frame mode. `\"inline\"` = no batch; `\"transactional\"` = batch + rollback. */\n\tframe: MutationFrame;\n\t/**\n\t * Optional log to append records to. When omitted, the wrapper still\n\t * provides freeze / seq-advance / rollback-on-throw but skips record\n\t * emission — useful for primitives that want centralized mutation\n\t * semantics without a dedicated log surface (e.g. `Topic.publish`).\n\t */\n\tlog?: ReactiveLogBundle<R>;\n\t/** Build the success record from the action's args + result + meta. */\n\tonSuccessRecord?: (args: TArgs, result: TResult, meta: SuccessMeta) => R | undefined;\n\t/** Build the failure record from the args + error + meta. */\n\tonFailureRecord?: (args: TArgs, error: unknown, meta: FailureMeta) => R | undefined;\n\t/** Deep-freeze args at entry (default `true`). Opt out for hot paths. */\n\tfreeze?: boolean;\n\t/** Optional sequence cursor — auto-advanced and stamped onto records. */\n\tseq?: Node<number>;\n\t/** Optional handler version — stamped per Audit 5. */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n/**\n * Universal mutation factory (Phase 14 — DS-14 Q-O2).\n *\n * Replaces the prior `lightMutation` + `wrapMutation` two-tier split.\n * Single factory with `frame: \"inline\" | \"transactional\"` discriminant.\n *\n * @param act - The mutation action. Either a plain function (auto-wrapped as\n * `{ up: fn }`) or a `{ up, down? }` object for explicit rollback.\n * @param opts - Configuration: frame, log, record builders, freeze, seq.\n * @returns A typed wrapper function with the same signature as `act.up`.\n */\nexport function mutate<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord>(\n\tact: MutationAct<TArgs, TResult> | ((...args: TArgs) => TResult),\n\topts: MutateOpts<TArgs, TResult, R>,\n): (...args: TArgs) => TResult {\n\tconst { up, down } = typeof act === \"function\" ? { up: act, down: undefined } : act;\n\tconst freeze = opts.freeze ?? true;\n\n\tif (opts.frame === \"inline\") {\n\t\treturn function wrapped(...args: TArgs): TResult {\n\t\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\t\tconst t_ns = wallClockNs();\n\t\t\tconst seq = opts.seq ? bumpCursor(opts.seq) : undefined;\n\t\t\ttry {\n\t\t\t\tconst result = up(...sealed);\n\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tif (opts.log && opts.onFailureRecord) {\n\t\t\t\t\tconst errorType = err instanceof Error ? err.name : typeof err;\n\t\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\t}\n\n\t// frame === \"transactional\"\n\treturn function wrapped(...args: TArgs): TResult {\n\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\tconst t_ns = wallClockNs();\n\t\tlet result: TResult;\n\t\tlet captured: unknown;\n\t\tlet captureSet = false;\n\t\tlet seq: number | undefined;\n\t\ttry {\n\t\t\tbatch(() => {\n\t\t\t\tif (opts.seq) seq = bumpCursor(opts.seq);\n\t\t\t\ttry {\n\t\t\t\t\tresult = up(...sealed);\n\t\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\t\topts.log,\n\t\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\t\tsealed,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tcaptured = err;\n\t\t\t\t\tcaptureSet = true;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (outerErr) {\n\t\t\t// Fire `down` AFTER batch's reactive rollback, BEFORE failure record.\n\t\t\t// Gate on `captureSet` — if the throw came from outside the inner try\n\t\t\t// (framework-level batch error before action ran), don't fire down.\n\t\t\tif (captureSet && down) {\n\t\t\t\ttry {\n\t\t\t\t\tdown(...sealed);\n\t\t\t\t} catch (downErr) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`mutate: down hook threw — original action error preserved (${\n\t\t\t\t\t\t\tcaptured instanceof Error ? captured.name : typeof captured\n\t\t\t\t\t\t}). Down error:`,\n\t\t\t\t\t\tdownErr,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captureSet && opts.log && opts.onFailureRecord) {\n\t\t\t\tconst errorType = captured instanceof Error ? captured.name : typeof captured;\n\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\topts.log,\n\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\tsealed,\n\t\t\t\t\tcaptured,\n\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\topts.handlerVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow captureSet ? captured : outerErr;\n\t\t}\n\t\treturn result!;\n\t};\n}\n\n/**\n * Advance a cursor node and return the new value. Emits `[DIRTY], [DATA, next]`\n * directly on the cursor — atomic outside a batch, rollback-discardable inside.\n *\n * Resets to `0` if the cursor cache is missing, non-numeric, `NaN`, or\n * non-finite (e.g. corrupted by `restore()` from a malformed snapshot, or\n * by a misbehaving codec). `??` alone would let `NaN` and `\"\"` pass through\n * and silently corrupt audit ordering downstream.\n *\n * **Silent reset diagnostic (EH-12).** When the cache holds a non-numeric\n * value at bump time, the cursor restarts at 0 and the next bump returns 1\n * — colliding with the seq stamped on the very first record after construct.\n * To make seq-monotonicity violations after a restore visible to operators,\n * the helper emits a one-shot `console.warn` per cursor instance describing\n * the offending value. The cursor is identified by a `WeakSet<Node<number>>`\n * so the warning fires exactly once per node — repeat malformed bumps stay\n * quiet to avoid log spam. Production callers wanting to suppress can swap\n * the global `console` (universal-safe code path; no Node-only API used).\n *\n * Works whether or not the cursor has any subscribers — `down` updates the\n * cache regardless, so primitives that bump before consumers attach (e.g.\n * `JobQueueGraph.enqueue`) still see a coherent sequence.\n *\n * @category internal\n */\nconst _bumpCursorWarned = new WeakSet<Node<number>>();\nexport function bumpCursor(seq: Node<number>): number {\n\tconst raw = seq.cache;\n\tconst valid = typeof raw === \"number\" && Number.isFinite(raw);\n\tif (!valid && raw !== undefined && !_bumpCursorWarned.has(seq)) {\n\t\t_bumpCursorWarned.add(seq);\n\t\tconsole.warn(\n\t\t\t`bumpCursor: cursor cache held a non-numeric value (${String(raw)}); resetting to 0. ` +\n\t\t\t\t\"Causes include: a snapshot codec round-tripping the cursor as a string / null / NaN, \" +\n\t\t\t\t\"OR a malformed initial seed (e.g. state<number>(NaN)). \" +\n\t\t\t\t\"Audit consumers may see colliding seq values after this point.\",\n\t\t);\n\t}\n\tconst cur = valid ? raw : 0;\n\tconst next = cur + 1;\n\tseq.down([[DIRTY], [DATA, next]]);\n\treturn next;\n}\n\n/**\n * Build a record via the supplied builder, stamp `handlerVersion` if present,\n * and append it to the audit log. `undefined` records are skipped (callers\n * pass an `onSuccess` / `onFailure` that returns `undefined` to opt out per\n * call).\n *\n * @category internal\n */\nexport function appendAudit<\n\tTArgs extends readonly unknown[],\n\tTValue,\n\tR extends BaseAuditRecord,\n\tM extends SuccessMeta | FailureMeta,\n>(\n\taudit: ReactiveLogBundle<R>,\n\tbuilder: (args: TArgs, value: TValue, meta: M) => R | undefined,\n\targs: TArgs,\n\tvalue: TValue,\n\tmeta: M,\n\thandlerVersion?: { id: string; version: string | number },\n): void {\n\tconst record = builder(args, value, meta);\n\tif (record === undefined) return;\n\tconst stamped = handlerVersion != null ? ({ ...record, handlerVersion } as R) : record;\n\taudit.append(stamped);\n}\n\n// ── registerCursor / registerCursorMap ───────────────────────────────────\n\n/**\n * Promote a closure counter to a state node mounted under `graph`.\n * Replaces ad-hoc `let _seq = 0` patterns with a node observable in\n * `describe()` and persistable via storage tiers.\n *\n * @category internal\n */\nexport function registerCursor(graph: Graph, name: string, initial = 0): Node<number> {\n\tconst cursor = node<number>([], { initial, name, describeKind: \"state\" });\n\tgraph.add(cursor, { name });\n\treturn cursor;\n}\n\n/**\n * Promote a closure `Map<K, number>` to N state nodes (one per key) mounted\n * under `<graph>::<name>::<key>`. Used by saga (per-event-type cursor).\n *\n * @category internal\n */\nexport function registerCursorMap<K extends string>(\n\tgraph: Graph,\n\tname: string,\n\tkeys: readonly K[],\n\tinitial = 0,\n): { readonly [P in K]: Node<number> } {\n\tconst out = {} as { [P in K]: Node<number> };\n\t// Mount cursors under a child plain-Graph so per-key node names stay flat\n\t// (path-separator `::` is reserved by Graph.add). Using `Graph` directly\n\t// rather than `graph.constructor` avoids spawning a typed subclass with\n\t// an incompatible constructor signature (e.g., CqrsGraph(name, opts)).\n\tconst sub = new Graph(name);\n\tfor (const k of keys) {\n\t\tconst cursor = node<number>([], {\n\t\t\tinitial,\n\t\t\tname: k,\n\t\t\tdescribeKind: \"state\",\n\t\t});\n\t\tsub.add(cursor, { name: k });\n\t\tout[k] = cursor;\n\t}\n\tgraph.mount(name, sub);\n\treturn out;\n}\n","/**\n * Standard `TopicMessage<T>` envelope for hub topics + well-known topic name\n * constants (Phase 13.B; spec source: archive/docs/SESSION-human-llm-intervention-primitives.md\n * §6 + archive/docs/SESSION-multi-agent-gap-analysis.md §6 cross-cut).\n *\n * `TopicMessage<T>` is the **recommended** wrapper for cross-agent / cross-graph\n * topic payloads — it carries identity, schema, deadline, and correlation\n * metadata alongside the typed `payload`. It is NOT a required protocol\n * type; raw `topic<T>` continues to work for in-process payloads where the\n * envelope fields would be noise.\n *\n * Use the envelope when:\n * - Two or more graphs (or human + LLM consumers) communicate over a topic\n * and need a stable wire shape — `correlationId` is the join key, `schema`\n * gates payload validation, `expiresAt` enables TTL enforcement.\n * - A topic carries multiple payload kinds and consumers need to discriminate\n * without parsing structurally.\n *\n * The standard well-known topic constants below are **conventions** — string\n * literals callers can pass to `messagingHub().topic(NAME)` to get a\n * predictable lookup. The hub does not enforce any topic to actually exist;\n * topics are still lazy on first access.\n */\n\n// ---------------------------------------------------------------------------\n// JSON Schema — minimal local type\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal JSON Schema shape, scoped to what `TopicMessage<T>` validates against.\n * Locked DS-13.B (2026-04-30): zero-dep posture, structural shape only — no\n * full validator shipped. Callers that want full validation supply their own\n * (e.g. `ajv`, `zod`, `valibot`) and read `Message.schema` as the rule\n * source. The shape covers the JSON-Schema-7 subset that hub-topic payload\n * descriptions actually need:\n * - `type` / `properties` / `required` / `additionalProperties` for objects.\n * - `items` for arrays.\n * - `enum` / `const` for value constraints.\n * - `$ref` / `definitions` for shared sub-schemas.\n *\n * If a concrete consumer needs a richer shape (oneOf, allOf, format, etc.),\n * extend this type — it's a structural contract, not a tagged union, so\n * additive fields don't break existing producers.\n */\nexport interface JsonSchema {\n\treadonly type?:\n\t\t| \"string\"\n\t\t| \"number\"\n\t\t| \"integer\"\n\t\t| \"boolean\"\n\t\t| \"object\"\n\t\t| \"array\"\n\t\t| \"null\"\n\t\t| readonly (\"string\" | \"number\" | \"integer\" | \"boolean\" | \"object\" | \"array\" | \"null\")[];\n\treadonly properties?: Readonly<Record<string, JsonSchema>>;\n\treadonly required?: readonly string[];\n\treadonly additionalProperties?: boolean | JsonSchema;\n\treadonly items?: JsonSchema | readonly JsonSchema[];\n\treadonly enum?: readonly unknown[];\n\treadonly const?: unknown;\n\treadonly $ref?: string;\n\treadonly definitions?: Readonly<Record<string, JsonSchema>>;\n\treadonly description?: string;\n\treadonly title?: string;\n}\n\n// ---------------------------------------------------------------------------\n// TopicMessage<T> envelope\n// ---------------------------------------------------------------------------\n\n/**\n * Recommended envelope for hub topic payloads. Carries identity, optional\n * schema reference, optional expiry, optional correlation, and the typed\n * payload itself.\n *\n * - `id` — globally-unique identifier for this message instance. Producers\n * mint it (UUID, ULID, hash, etc.); consumers use it for deduplication and\n * trace correlation. **Required.**\n * - `schema` — optional structural description of `payload`. Validators\n * (caller-supplied) read this to gate or shape consumption. Writers MAY\n * include the schema inline for self-describing topics, or omit when the\n * payload type is statically known to all consumers.\n * - `expiresAt` — ISO 8601 timestamp; consumers SHOULD drop / fallback past\n * this point. Substrate enforcement is via composition (`timeout(source,\n * ms)` + `fallback`), not a hub-level rule.\n * - `correlationId` — links related messages across topics (request /\n * response pairs, conversation threads, multi-agent handoffs). Producers\n * propagate it; consumers filter / group on it.\n * - `payload` — the typed body. Type parameter `T` is the consumer-agreed\n * shape; the envelope adds metadata around it without coupling consumers\n * to a concrete payload type.\n *\n * Reactive composition with the envelope:\n *\n * ```ts\n * const requests = hub.topic<TopicMessage<RequestBody>>(PROMPTS_TOPIC);\n * const responses = hub.topic<TopicMessage<ResponseBody>>(RESPONSES_TOPIC);\n *\n * // Filter responses to one correlation\n * const myResponse = derived([responses.latest], ([msg]) =>\n * msg?.correlationId === requestId ? [msg.payload] : [],\n * );\n * ```\n */\nexport interface TopicMessage<T> {\n\treadonly id: string;\n\treadonly schema?: JsonSchema;\n\treadonly expiresAt?: string;\n\treadonly correlationId?: string;\n\treadonly payload: T;\n}\n\n// ---------------------------------------------------------------------------\n// Standard topic name constants\n// ---------------------------------------------------------------------------\n\n/**\n * Well-known topic name for human / LLM prompts directed at the harness.\n * Example payload: `TopicMessage<{ prompt: string; context?: object }>`.\n *\n * Co-locked with {@link RESPONSES_TOPIC} per the human-LLM intervention\n * session §6 #4 (paired request / response convention).\n */\nexport const PROMPTS_TOPIC = \"prompts\";\n\n/**\n * Well-known topic name for responses to {@link PROMPTS_TOPIC} entries.\n * Producers pair the response to its prompt via `correlationId`. Example\n * payload: `TopicMessage<{ content: string; finishReason?: string }>`.\n */\nexport const RESPONSES_TOPIC = \"responses\";\n\n/**\n * Well-known topic name for out-of-band injections — runtime overrides /\n * hot-fixes / human nudges that bypass the normal request flow. Example\n * payload: `TopicMessage<{ kind: \"context-patch\" | \"policy-override\" | ...;\n * data: unknown }>`. Per-injection consumers decide how (and whether) to\n * apply.\n */\nexport const INJECTIONS_TOPIC = \"injections\";\n\n/**\n * Well-known topic name for items the harness deferred for later attention\n * (parked queue, follow-up tracker, \"I'll get back to this\"). Producer is\n * usually the harness itself; consumer is a tracker / dashboard / human.\n * Example payload: `TopicMessage<{ reason: string; original: unknown }>`.\n */\nexport const DEFERRED_TOPIC = \"deferred\";\n\n/**\n * Well-known topic name for spawn requests (Phase 13.I `spawnable()`\n * surface). Producer emits a `TopicMessage<SpawnRequest>` to request a child\n * agent / subgraph; consumer is the materializer that mints the slot.\n * Example payload: `TopicMessage<{ presetId: string; taskInput: unknown;\n * depth?: number }>`. `correlationId` links the spawn to its parent\n * conversation; `expiresAt` enforces TTL on long-lived requests.\n */\nexport const SPAWNS_TOPIC = \"spawns\";\n\n/**\n * DS-14.6.A D-B3 — well-known topic for the dynamic `actorPool()` shared\n * tagged-context pool. Actors publish `ContextEntry` here; per-actor views\n * render their own compressed slice.\n */\nexport const CONTEXT_TOPIC = \"context\";\n\n/**\n * DS-14.6.A D-B3 — well-known topic for the `actorPool()` shared todo list.\n * Any actor may `enqueueTodo`; actors pull assigned todos via their cursor.\n */\nexport const TODOS_TOPIC = \"todos\";\n\n/**\n * Tuple of all well-known topic constants — useful for \"register all\n * standard topics on a hub\" patterns and for compile-time exhaustiveness\n * checks.\n */\nexport const STANDARD_TOPICS = [\n\tPROMPTS_TOPIC,\n\tRESPONSES_TOPIC,\n\tINJECTIONS_TOPIC,\n\tDEFERRED_TOPIC,\n\tSPAWNS_TOPIC,\n\tCONTEXT_TOPIC,\n\tTODOS_TOPIC,\n] as const;\n\n/**\n * Union of all well-known topic name string literals.\n */\nexport type StandardTopic = (typeof STANDARD_TOPICS)[number];\n","/**\n * Messaging patterns (roadmap §4.2).\n *\n * Pulsar-inspired messaging primitives modeled as graph factories:\n * - `topic()` for append-only topic streams with a retained window.\n * - `subscription()` for cursor-based consumers.\n * - `topicBridge()` for autonomous topic-to-topic relay.\n * - `messagingHub()` for a lazy topic registry.\n *\n * Plus the Phase 13.B standard `Message<T>` envelope and well-known topic\n * name constants ({@link PROMPTS_TOPIC} / {@link RESPONSES_TOPIC} /\n * {@link INJECTIONS_TOPIC} / {@link DEFERRED_TOPIC} / {@link SPAWNS_TOPIC})\n * — recommended (not enforced) wire shape for cross-graph topic payloads.\n *\n * Job queue / job flow primitives live in `patterns/job-queue` — they are a\n * distinct domain that happens to share reactive-log / reactive-map\n * infrastructure with topics.\n */\n\nexport {\n\ttype HubRemoveTopicRecord,\n\thubRemoveTopicKeyOf,\n\ttype MessagingAuditRecord,\n\ttype SubscriptionAckRecord,\n\ttype SubscriptionPullAndAckRecord,\n\tsubscriptionAckKeyOf,\n\tsubscriptionPullAndAckKeyOf,\n\ttype TopicPublishRecord,\n\ttopicPublishKeyOf,\n} from \"./audit-records.js\";\nexport {\n\tCONTEXT_TOPIC,\n\tDEFERRED_TOPIC,\n\tINJECTIONS_TOPIC,\n\ttype JsonSchema,\n\tPROMPTS_TOPIC,\n\tRESPONSES_TOPIC,\n\tSPAWNS_TOPIC,\n\tSTANDARD_TOPICS,\n\ttype StandardTopic,\n\tTODOS_TOPIC,\n\ttype TopicMessage,\n} from \"./message.js\";\n\nimport { batch, COMPLETE, DATA, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { keepalive, type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport { mutate } from \"../../base/mutation/index.js\";\n\nconst DEFAULT_MAX_PER_PUMP = 256;\n\nfunction requireNonNegativeInt(value: number, label: string): number {\n\tif (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {\n\t\tthrow new Error(`${label} must be a non-negative integer`);\n\t}\n\treturn value;\n}\n\nfunction messagingMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"messaging\", kind, extra);\n}\n\nexport type TopicOptions = {\n\tgraph?: GraphOptions;\n\t/** Bounded retention; default 1024 per cross-cutting policy (Audit 2/4). */\n\tretainedLimit?: number;\n};\n\nconst DEFAULT_TOPIC_RETAINED_LIMIT = 1024;\n\nexport class TopicGraph<T> extends Graph {\n\tprivate readonly _log;\n\tprivate readonly _publishImpl: (value: T) => void;\n\treadonly events: Node<readonly T[]>;\n\t/**\n\t * Most recently published value. Stays in the protocol SENTINEL state\n\t * (`cache === undefined`, no DATA emitted) until the first publish, then\n\t * tracks the latest entry. Spec §5.12 reserves `undefined` as the\n\t * \"never sent DATA\" sentinel — and `TopicGraph.publish(undefined)` is\n\t * rejected — so `cache === undefined` unambiguously signals \"empty topic\"\n\t * even when `T` itself includes `null` (i.e., `topic<number | null>`).\n\t *\n\t * **Within a reactive fn:** detect the empty-topic case via\n\t * `ctx.prevData[i] === undefined` for the dep slot holding `topic.latest`,\n\t * or check `latest.cache === undefined` outside reactive code. No\n\t * separate `hasLatest` companion needed — the SENTINEL is the answer.\n\t */\n\treadonly latest: Node<T>;\n\n\tconstructor(name: string, opts: TopicOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis._log = reactiveLog<T>([], {\n\t\t\tname: \"events\",\n\t\t\tmaxSize: opts.retainedLimit ?? DEFAULT_TOPIC_RETAINED_LIMIT,\n\t\t});\n\t\tthis.events = this._log.entries;\n\t\tthis.add(this.events, { name: \"events\" });\n\t\t// `this.derived(\"latest\", [\"events\"], …)` is expressible after the\n\t\t// 2026-04-30 self-resolve fix in `Graph._resolveFromSegments` — a\n\t\t// single-segment path matching the graph's own name (e.g.\n\t\t// `topic(\"events\").resolve(\"events\")`) no longer collapses to empty\n\t\t// and falls through to local-node lookup. Replaces the prior\n\t\t// `node([events], …) + this.add(...)` workaround.\n\t\t//\n\t\t// SENTINEL on empty: returning `[]` here yields a RESOLVED-only wave\n\t\t// (no DATA), so `latest.cache` stays `undefined` until the first\n\t\t// publish. `TopicGraph.publish(undefined)` is rejected (line below),\n\t\t// so `undefined` cache is unambiguously \"empty topic\" even when `T`\n\t\t// itself includes `null`. Drops the prior `hasLatest` companion as\n\t\t// redundant.\n\t\tthis.latest = this.derived<T>(\n\t\t\t\"latest\",\n\t\t\t[\"events\"],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst entries = data[0] as readonly T[];\n\t\t\t\treturn entries.length === 0 ? [] : [entries[entries.length - 1] as T];\n\t\t\t},\n\t\t\t{ meta: messagingMeta(\"topic_latest\") },\n\t\t);\n\t\tthis.addDisposer(keepalive(this.latest));\n\n\t\t// D1(a): on teardown, propagate COMPLETE on `events` so downstream\n\t\t// derived chains (including any externally-held SubscriptionGraph\n\t\t// sources) see the termination via their `terminalDeps` and can stop\n\t\t// serving stale caches. Tier-3 terminal per spec §2.2.\n\t\t//\n\t\t// EC16 (verified 2026-04-30): the COMPLETE-then-disposeAllViews order\n\t\t// is intentional. COMPLETE propagates SYNCHRONOUSLY through every\n\t\t// subscriber (cursor views, derived chains) so they self-unsubscribe\n\t\t// in their terminal handler before `disposeAllViews` runs. Swapping\n\t\t// the order would clear view caches before subscribers receive the\n\t\t// terminal — strictly worse. Reading `.cache` outside a reactive fn\n\t\t// across teardown is an anti-pattern (spec §5.12) and not a use case\n\t\t// this ordering needs to preserve.\n\t\tthis.addDisposer(() => {\n\t\t\tthis.events.down([[COMPLETE]]);\n\t\t});\n\t\t// P9: release any memoized tail/slice view keepalives held by the log.\n\t\t// TopicGraph itself doesn't call log.tail/slice, but plugins may have\n\t\t// attached views via `_log` — defensive (typical reactive subscribers\n\t\t// have already unsubscribed in their COMPLETE handler above).\n\t\tthis.addDisposer(() => this._log.disposeAllViews());\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: route publish through `mutate`\n\t\t// for centralized freeze + re-throw semantics. No audit log surface\n\t\t// (per Tier 8 γ-0): the topic's `events` log already records every\n\t\t// successful publish, so a separate audit Node would be redundant.\n\t\t// `freeze: false` because topic payloads can be large and per-publish\n\t\t// cost matters on hot paths.\n\t\tthis._publishImpl = mutate<[T], void, never>(\n\t\t\t(value): void => {\n\t\t\t\tthis._log.append(value);\n\t\t\t},\n\t\t\t{ frame: \"inline\", freeze: false },\n\t\t);\n\t}\n\n\tpublish(value: T): void {\n\t\t// SENTINEL alignment (Wave B.1 Unit 11 lock): `undefined` is the\n\t\t// protocol-level \"never sent DATA\" sentinel — refusing it here\n\t\t// preserves `lastValue: Node<T | undefined>` semantics.\n\t\tif (value === undefined) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`TopicGraph \"${this.name}\": publish(undefined) is not allowed (spec §5.12 SENTINEL).`,\n\t\t\t);\n\t\t}\n\t\tthis._publishImpl(value);\n\t}\n\n\t/**\n\t * Wire one or more append-log storage tiers (Audit 4). Each tier receives\n\t * appended events per wave; rollback honors the wave-as-transaction model.\n\t *\n\t * Named `attachEventStorage` (not `attachStorage`) to avoid colliding with\n\t * the inherited {@link Graph.attachSnapshotStorage} which takes the\n\t * paired `AttachSnapshotTierPair[]` shape (Phase 14.6) — distinct\n\t * concerns, distinct surfaces.\n\t *\n\t * @returns Disposer.\n\t */\n\tattachEventStorage(\n\t\ttiers: readonly import(\"@graphrefly/pure-ts/extra\").AppendLogStorageTier<T>[],\n\t): () => void {\n\t\treturn this._log.attachStorage(tiers);\n\t}\n\n\tretained(): readonly T[] {\n\t\treturn this.events.cache as readonly T[];\n\t}\n\n\t/** Internal log bundle — used by TopicBridgeGraph for `attach`. */\n\tget _logBundle() {\n\t\treturn this._log;\n\t}\n}\n\nexport type SubscriptionOptions = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Starting cursor position.\n\t * @deprecated Use `from` instead.\n\t */\n\tcursor?: number;\n\t/**\n\t * Starting position for the subscription.\n\t * - `\"retained\"` (default) — cursor starts at 0; consumer sees all retained history.\n\t * - `\"now\"` — cursor starts at current topic length; consumer ignores history.\n\t * - `number` — explicit cursor position.\n\t */\n\tfrom?: \"now\" | \"retained\" | number;\n\t/**\n\t * When this signal node emits DATA, the subscription auto-advances cursor\n\t * to current `available.length`. Useful for \"ack everything when X happens\"\n\t * patterns. The reactive edge `advanceOn → cursor` is visible in `explain()`.\n\t */\n\tadvanceOn?: Node<unknown>;\n};\n\n/** Result of {@link SubscriptionGraph.pullAndAck}. */\nexport type PullAndAckResult<T> = {\n\titems: readonly T[];\n\tcursor: number;\n};\n\nexport class SubscriptionGraph<T> extends Graph {\n\treadonly cursor: Node<number>;\n\treadonly available: Node<readonly T[]>;\n\t/**\n\t * Reference to the upstream topic graph. Intentionally NOT mounted\n\t * under this subscription: a subscription is a VIEW over an\n\t * externally-owned topic. Double-mounting (e.g. hub-owned topic +\n\t * sub-mount here) would make either-side teardown leave the other\n\t * holding a dead reference. Node-level `derived([topicEvents], …)`\n\t * still wires the data dependency across graph boundaries. D1(e).\n\t */\n\treadonly topic: TopicGraph<T>;\n\n\tprivate _disposed = false;\n\tprivate readonly _ackImpl: (count: number | undefined) => number;\n\tprivate readonly _pullAndAckImpl: (limit: number | undefined) => PullAndAckResult<T>;\n\n\tconstructor(name: string, topicGraph: TopicGraph<T>, opts: SubscriptionOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis.topic = topicGraph;\n\n\t\t// Resolve initial cursor from `from` option, falling back to legacy `cursor` option.\n\t\tlet initialCursor: number;\n\t\tif (opts.from !== undefined) {\n\t\t\tif (opts.from === \"retained\") {\n\t\t\t\tinitialCursor = 0;\n\t\t\t} else if (opts.from === \"now\") {\n\t\t\t\t// §28 sanctioned factory-time boundary read.\n\t\t\t\tinitialCursor = (topicGraph.events.cache as readonly T[]).length;\n\t\t\t} else {\n\t\t\t\tinitialCursor = requireNonNegativeInt(opts.from, \"subscription from\");\n\t\t\t}\n\t\t} else {\n\t\t\tinitialCursor = requireNonNegativeInt(opts.cursor ?? 0, \"subscription cursor\");\n\t\t}\n\n\t\tthis.cursor = this.state<number>(\"cursor\", initialCursor, {\n\t\t\tmeta: messagingMeta(\"subscription_cursor\"),\n\t\t});\n\n\t\t// B.1 Unit 12 lock: `available` depends directly on topic.events + cursor\n\t\t// via `view({ kind: \"fromCursor\" })`. No `source` passthrough node —\n\t\t// describe shows `topic::events → available` (cross-graph edge) and\n\t\t// `cursor → available` (local edge). One fewer node per subscription.\n\t\tthis.available = topicGraph._logBundle.view({ kind: \"fromCursor\", cursor: this.cursor });\n\t\tthis.add(this.available, { name: \"available\" });\n\t\tthis.addDisposer(keepalive(this.available));\n\n\t\t// Optional reactive auto-advance: when `advanceOn` emits a NEW DATA\n\t\t// (after construction), cursor advances by `available.length` atomically.\n\t\t// Edge visible in describe: advancePump depends on advanceOn.\n\t\t// `_advanceInitialized` guards against the initial push-on-subscribe fire\n\t\t// that would advance cursor before the user has a chance to read.\n\t\tif (opts.advanceOn !== undefined) {\n\t\t\tconst advanceOn = opts.advanceOn;\n\t\t\tlet advanceInitialized = false;\n\t\t\tconst advancePump = node<unknown>(\n\t\t\t\t[advanceOn],\n\t\t\t\t() => {\n\t\t\t\t\t// Skip the initial push-on-subscribe wave.\n\t\t\t\t\tif (!advanceInitialized) {\n\t\t\t\t\t\tadvanceInitialized = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (this._disposed) return;\n\t\t\t\t\tconst avail = this.available.cache as readonly T[];\n\t\t\t\t\tif (avail.length === 0) return;\n\t\t\t\t\tconst next = (this.cursor.cache as number) + avail.length;\n\t\t\t\t\tthis.cursor.emit(next);\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: \"advancePump\",\n\t\t\t\t\tdescribeKind: \"effect\",\n\t\t\t\t\tmeta: messagingMeta(\"subscription_advance_pump\"),\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.add(advancePump, { name: \"advancePump\" });\n\t\t\tthis.addDisposer(keepalive(advancePump));\n\t\t}\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: route ack + pullAndAck through\n\t\t// `mutate` for centralized freeze + re-throw semantics. No audit\n\t\t// log surface (per Tier 8 γ-0): the cursor's own emission stream already\n\t\t// records every advance, so a separate audit Node would be redundant.\n\t\t// `freeze: false` because count/limit are simple numbers; freezing is\n\t\t// pointless overhead. Disposed-checks stay outside the wrapper so a\n\t\t// no-op call doesn't unnecessarily run the wrapper.\n\t\tthis._ackImpl = mutate<[number | undefined], number, never>(\n\t\t\t(count): number => {\n\t\t\t\tconst available = this.available.cache as readonly T[];\n\t\t\t\tconst requested =\n\t\t\t\t\tcount === undefined\n\t\t\t\t\t\t? available.length\n\t\t\t\t\t\t: requireNonNegativeInt(count, \"subscription ack count\");\n\t\t\t\tconst step = Math.min(requested, available.length);\n\t\t\t\tif (step <= 0) return this.cursor.cache as number;\n\t\t\t\tconst next = (this.cursor.cache as number) + step;\n\t\t\t\t// F8: use emit() so the pipeline auto-prefixes DIRTY, runs equals\n\t\t\t\t// substitution, and produces a proper two-phase wave (the raw\n\t\t\t\t// `down([[DATA, next]])` path bypassed those contracts).\n\t\t\t\tthis.cursor.emit(next);\n\t\t\t\treturn next;\n\t\t\t},\n\t\t\t{ frame: \"inline\", freeze: false },\n\t\t);\n\n\t\tthis._pullAndAckImpl = mutate<[number | undefined], PullAndAckResult<T>, never>(\n\t\t\t(limit): PullAndAckResult<T> => {\n\t\t\t\tconst available = this.available.cache as readonly T[];\n\t\t\t\tconst max =\n\t\t\t\t\tlimit === undefined\n\t\t\t\t\t\t? available.length\n\t\t\t\t\t\t: requireNonNegativeInt(limit, \"subscription pullAndAck limit\");\n\t\t\t\tconst items = available.slice(0, max);\n\t\t\t\tif (items.length === 0) return { items, cursor: this.cursor.cache as number };\n\t\t\t\tconst next = (this.cursor.cache as number) + items.length;\n\t\t\t\tthis.cursor.emit(next);\n\t\t\t\treturn { items, cursor: next };\n\t\t\t},\n\t\t\t{ frame: \"inline\", freeze: false },\n\t\t);\n\t}\n\n\tack(count?: number): number {\n\t\tif (this._disposed) return this.cursor.cache as number;\n\t\treturn this._ackImpl(count);\n\t}\n\n\tpull(limit?: number): readonly T[] {\n\t\tif (this._disposed) return [];\n\t\tconst available = this.available.cache as readonly T[];\n\t\tconst max =\n\t\t\tlimit === undefined\n\t\t\t\t? available.length\n\t\t\t\t: requireNonNegativeInt(limit, \"subscription pull limit\");\n\t\treturn available.slice(0, max);\n\t}\n\n\t/**\n\t * Atomic pull-and-acknowledge. Returns `{ items, cursor }` where `cursor`\n\t * is the new cursor position after advancing. Under single-threaded JS the\n\t * snapshot and advance are atomic; PY callers use a per-subscription Lock.\n\t *\n\t * Replaces `pull(limit, { ack: true })`.\n\t */\n\tpullAndAck(limit?: number): PullAndAckResult<T> {\n\t\tif (this._disposed) return { items: [], cursor: this.cursor.cache as number };\n\t\treturn this._pullAndAckImpl(limit);\n\t}\n\n\t/**\n\t * Release internal subscriptions and mark the subscription torn-down.\n\t * Subsequent `pull`, `pullAndAck`, `ack` return empty / current cursor.\n\t * Emits COMPLETE on `cursor` so derived consumers (e.g. `available`) see\n\t * the termination signal. Also drains `addDisposer` callbacks (including\n\t * the `keepalive(advancePump)` subscription) so no keepalive leak occurs.\n\t */\n\tdispose(): void {\n\t\tif (this._disposed) return;\n\t\tthis._disposed = true;\n\t\tthis.cursor.down([[COMPLETE]]);\n\t\t// m4: drain addDisposer callbacks to release the keepalive subscription.\n\t\tthis.destroy();\n\t}\n}\n\nexport type TopicBridgeOptions<TIn, TOut> = {\n\tgraph?: GraphOptions;\n\tcursor?: number;\n\tmaxPerPump?: number;\n\t/**\n\t * Optional transform/filter applied to each item before republishing.\n\t *\n\t * **At-most-once with silent drop:** when `map` returns `undefined`, the\n\t * input is consumed from the source cursor but NOT republished. Filtered\n\t * items are not retained for retry. If you need filter-with-retry\n\t * semantics, do the filtering in a downstream subscription on the bridged\n\t * output rather than in the `map` function.\n\t */\n\tmap?: (value: TIn) => TOut | undefined;\n};\n\nexport class TopicBridgeGraph<TIn, TOut = TIn> extends Graph {\n\tprivate readonly _sourceSub;\n\treadonly bridgedCount: Node<number>;\n\t/**\n\t * Emits each mapped batch as DATA — gives downstream observers a reactive\n\t * stream of bridged values. Also the link target for `target._log.attach`.\n\t */\n\treadonly output: Node<readonly TOut[]>;\n\n\tconstructor(\n\t\tname: string,\n\t\tsourceTopic: TopicGraph<TIn>,\n\t\ttargetTopic: TopicGraph<TOut>,\n\t\topts: TopicBridgeOptions<TIn, TOut> = {},\n\t) {\n\t\tsuper(name, opts.graph);\n\t\tthis._sourceSub = subscription<TIn>(`${name}-subscription`, sourceTopic, {\n\t\t\tcursor: opts.cursor,\n\t\t});\n\t\tthis.mount(\"subscription\", this._sourceSub);\n\n\t\tconst maxPerPump = Math.max(\n\t\t\t1,\n\t\t\trequireNonNegativeInt(opts.maxPerPump ?? DEFAULT_MAX_PER_PUMP, \"topic bridge maxPerPump\"),\n\t\t);\n\t\tconst mapValue = opts.map ?? ((value: TIn) => value as unknown as TOut);\n\n\t\t// Reactive output node: derives a mapped batch from `available`.\n\t\t// §24 compliant — output is a real derived edge, visible in describe.\n\t\t// Replaces imperative publish loop. Items where mapValue returns undefined\n\t\t// are filtered out (opt-out / filter).\n\t\tthis.output = node<readonly TOut[]>(\n\t\t\t[this._sourceSub.available],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst arr = data[0] as readonly TIn[];\n\t\t\t\tconst outBatch: TOut[] = [];\n\t\t\t\tconst take = Math.min(arr.length, maxPerPump);\n\t\t\t\tfor (let i = 0; i < take; i++) {\n\t\t\t\t\tconst mapped = mapValue(arr[i] as TIn);\n\t\t\t\t\tif (mapped !== undefined) outBatch.push(mapped);\n\t\t\t\t}\n\t\t\t\tactions.emit(outBatch);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"output\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: messagingMeta(\"topic_bridge_output\", { targetRef: targetTopic.name }),\n\t\t\t\tinitial: [],\n\t\t\t},\n\t\t);\n\t\tthis.add(this.output, { name: \"output\" });\n\t\tthis.addDisposer(keepalive(this.output));\n\n\t\t// bridgedCount: state node accumulating total bridged items.\n\t\t// Updated by ackPump after each batch — edge visible via ackPump dep on output.\n\t\tthis.bridgedCount = this.state<number>(\"bridgedCount\", 0, {\n\t\t\tmeta: messagingMeta(\"topic_bridge_count\"),\n\t\t});\n\t\tthis.addDisposer(keepalive(this.bridgedCount));\n\n\t\t// ackPump: effect that advances the subscription cursor and updates\n\t\t// bridgedCount after each batch. Runs after `output` settles.\n\t\t// Captures refs to `this.output`, `this._sourceSub`, `this.bridgedCount`\n\t\t// to avoid `this` inside the fn body.\n\t\tconst outputRef = this.output;\n\t\tconst subRef = this._sourceSub;\n\t\tconst countRef = this.bridgedCount;\n\t\tconst ackPump = this.effect(\n\t\t\t\"ackPump\",\n\t\t\t[\"output\"],\n\t\t\t() => {\n\t\t\t\tconst outBatch = outputRef.cache as readonly TOut[];\n\t\t\t\tif (outBatch.length === 0) return;\n\t\t\t\tconst availLen = (subRef.available.cache as readonly TIn[]).length;\n\t\t\t\tconst toAck = Math.min(availLen, maxPerPump);\n\t\t\t\tif (toAck > 0) {\n\t\t\t\t\tsubRef.ack(toAck);\n\t\t\t\t\tconst prev = (countRef.cache as number) ?? 0;\n\t\t\t\t\tcountRef.emit(prev + outBatch.length);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: messagingMeta(\"topic_bridge_ack_pump\"),\n\t\t\t},\n\t\t);\n\t\tthis.addDisposer(keepalive(ackPump));\n\n\t\t// Wire output into target topic's log reactively.\n\t\t// _attachArrayToLog subscribes to output and publishes each item to targetTopic.\n\t\t// Teardown: disposer runs before mount teardown.\n\t\tconst detach = _attachArrayToLog(this.output, targetTopic);\n\t\tthis.addDisposer(detach);\n\t}\n}\n\n/**\n * Attaches each element of an array-valued Node to a TopicGraph's log.\n * Every DATA emission on `source` appends all items in the array to `targetTopic`.\n * Returns a disposer.\n */\nfunction _attachArrayToLog<T>(source: Node<readonly T[]>, targetTopic: TopicGraph<T>): () => void {\n\treturn source.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] !== DATA) continue;\n\t\t\tconst arr = m[1] as readonly T[];\n\t\t\tif (arr.length === 0) continue;\n\t\t\tbatch(() => {\n\t\t\t\tfor (const v of arr) targetTopic.publish(v);\n\t\t\t});\n\t\t}\n\t});\n}\n\n// ── TopicRegistry ─────────────────────────────────────────────────────────\n\n/**\n * Private pure data structure managing a named set of {@link TopicGraph}\n * instances. Extracted from {@link MessagingHubGraph} for separation of\n * concerns (B.2 Unit 14 lock: D — split into TopicRegistry + facade).\n *\n * Reusable if other domain consumers (e.g. cqrs.eventLogs) want a shared\n * topic registry later.\n *\n * @internal\n */\nexport class TopicRegistry {\n\tprivate readonly _map = new Map<string, TopicGraph<unknown>>();\n\t/** Reactive monotonic version counter. Advances on topic create/remove. */\n\treadonly version: Node<number>;\n\n\tconstructor(versionNode: Node<number>) {\n\t\tthis.version = versionNode;\n\t}\n\n\tget size(): number {\n\t\treturn this._map.size;\n\t}\n\n\thas(name: string): boolean {\n\t\treturn this._map.has(name);\n\t}\n\n\tget<T>(name: string): TopicGraph<T> | undefined {\n\t\treturn this._map.get(name) as TopicGraph<T> | undefined;\n\t}\n\n\tset<T>(name: string, t: TopicGraph<T>): void {\n\t\tthis._map.set(name, t as TopicGraph<unknown>);\n\t}\n\n\tdelete(name: string): boolean {\n\t\treturn this._map.delete(name);\n\t}\n\n\tkeys(): IterableIterator<string> {\n\t\treturn this._map.keys();\n\t}\n}\n\n// ── MessagingHubGraph ─────────────────────────────────────────────────────\n\nexport type MessagingHubOptions = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Default `TopicOptions` applied to every topic created via `topic(name)`\n\t * without explicit options. Per-call opts override. Default: `{}`\n\t * (unbounded retention per topic unless `retainedLimit` is set per call).\n\t */\n\tdefaultTopicOptions?: TopicOptions;\n};\n\n/**\n * Lazy Pulsar-inspired topic registry. Manages a named set of {@link TopicGraph}\n * instances with retention + cursor semantics. Topics are created on first\n * access; `removeTopic(name)` unmounts and tears down via {@link Graph.remove}.\n *\n * Internally delegates to {@link TopicRegistry} for topic map management\n * (B.2 Unit 14 lock: D facade split).\n *\n * **Relationship to `pubsub()` in `src/extra/pubsub.ts`:** `pubsub` is a\n * lightweight last-value state hub (no retention, no cursors). `MessagingHubGraph`\n * is the full messaging hub — retained message logs, cursor-based subscriptions,\n * and pattern-layer lifecycle management.\n *\n * @category patterns\n */\nexport class MessagingHubGraph extends Graph {\n\tprivate readonly _registry: TopicRegistry;\n\t/** Reactive monotonic version counter — advances on topic create/remove. */\n\treadonly version: Node<number>;\n\tprivate readonly _defaultTopicOptions: TopicOptions;\n\tprivate readonly _removeTopicImpl: (name: string) => void;\n\n\tconstructor(name: string, opts: MessagingHubOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\t// B.2 Unit 14 lock: promote _version → version: Node<number>.\n\t\tconst versionNode = this.state<number>(\"version\", 0, {\n\t\t\tmeta: messagingMeta(\"hub_version\"),\n\t\t});\n\t\tthis.version = versionNode;\n\t\tthis._registry = new TopicRegistry(versionNode);\n\t\t// P8: shallow-copy caller-provided defaults so post-construction\n\t\t// mutations by the caller don't leak into every future `topic()` call.\n\t\tthis._defaultTopicOptions = { ...(opts.defaultTopicOptions ?? {}) };\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: route the registry-delete branch of\n\t\t// `removeTopic` through `mutate` for centralized re-throw\n\t\t// semantics. No audit log surface (per Tier 8 γ-0).\n\t\t// `freeze: false` because the only arg is a string name (freeze pointless).\n\t\t// **Closure-state caveat (γ-4):** the inner `try/finally` mutates\n\t\t// `_registry` (a `Map`) and emits the version bump. mutate has no\n\t\t// `batch()` frame, so reactive emissions are NOT rolled back on throw —\n\t\t// and even if it did, `Map.delete` on closure state is invisible to the\n\t\t// batch and can't be unwound. The pre-existing try/finally on\n\t\t// `Graph.remove` is what guarantees registry/version converge to a\n\t\t// consistent state when `remove()` throws; `mutate` adds nothing\n\t\t// to that contract beyond the re-throw.\n\t\tthis._removeTopicImpl = mutate<[string], void, never>(\n\t\t\t(topicName): void => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.remove(topicName); // unmounts, drops edges, tears down\n\t\t\t\t} finally {\n\t\t\t\t\tthis._registry.delete(topicName);\n\t\t\t\t\tconst cur = (this.version.cache as number) ?? 0;\n\t\t\t\t\tthis.version.emit(cur + 1);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ frame: \"inline\", freeze: false },\n\t\t);\n\t}\n\n\t/** Number of topics currently in the hub. */\n\tget size(): number {\n\t\treturn this._registry.size;\n\t}\n\n\t/** Checks topic existence without creating. */\n\thas(name: string): boolean {\n\t\treturn this._registry.has(name);\n\t}\n\n\t/** Iterator over topic names. */\n\ttopicNames(): IterableIterator<string> {\n\t\treturn this._registry.keys();\n\t}\n\n\t/**\n\t * Returns the {@link TopicGraph} for `name`, creating lazily on first call.\n\t * Subsequent calls with the same name return the same instance (options on\n\t * repeat calls are ignored — the topic is already configured).\n\t */\n\ttopic<T = unknown>(name: string, opts?: TopicOptions): TopicGraph<T> {\n\t\tlet t = this._registry.get<T>(name);\n\t\tif (t === undefined) {\n\t\t\tconst effective: TopicOptions = { ...this._defaultTopicOptions, ...(opts ?? {}) };\n\t\t\tt = new TopicGraph<T>(name, effective);\n\t\t\tthis._registry.set(name, t);\n\t\t\tthis.mount(name, t);\n\t\t\tconst cur = (this.version.cache as number) ?? 0;\n\t\t\tthis.version.emit(cur + 1);\n\t\t}\n\t\treturn t;\n\t}\n\n\t/**\n\t * Publishes a value to the topic, lazily creating it on first publish.\n\t *\n\t * **Late-subscriber caveat:** the topic is created lazily, so subscribers\n\t * that attach AFTER a publish only see the retained window (governed by\n\t * `retainedLimit` on `TopicOptions` / `defaultTopicOptions`). If\n\t * `retainedLimit === 0` is set explicitly, early publishes are\n\t * effectively dropped — prefer an unset `retainedLimit` (unbounded\n\t * retention) or subscribe before publishing when late-subscribers matter.\n\t */\n\tpublish<T = unknown>(name: string, value: T): void {\n\t\tthis.topic<T>(name).publish(value);\n\t}\n\n\t/**\n\t * Bulk publish — issues all publishes inside one outer batch. New topics\n\t * are created on demand. No-op if `entries` yields nothing.\n\t *\n\t * **Iterable consumption (F6):** `entries` is consumed once (single-pass)\n\t * INSIDE the batch frame. If the iterator throws mid-way, the batch is\n\t * discarded and NO publishes are visible to subscribers (all-or-nothing).\n\t * Pass an array or `Set` for multi-shot callers.\n\t */\n\tpublishMany(entries: Iterable<[string, unknown]>): void {\n\t\t// P2: iterate inside batch — no `[...entries]` materialization so large\n\t\t// / infinite iterables don't OOM, and iterator throws are contained.\n\t\tbatch(() => {\n\t\t\tfor (const [name, value] of entries) {\n\t\t\t\tthis.topic(name).publish(value);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Creates a {@link SubscriptionGraph} over a named topic. The topic is\n\t * lazily created if missing. Subscription lifecycle is owned by the caller —\n\t * the hub does NOT mount the subscription.\n\t *\n\t * @param subName - Local name for the subscription graph.\n\t * @param topicName - Hub topic to subscribe to.\n\t * @param opts - `SubscriptionOptions` (initial cursor, etc.).\n\t */\n\tsubscribe<T = unknown>(\n\t\tsubName: string,\n\t\ttopicName: string,\n\t\topts?: SubscriptionOptions,\n\t): SubscriptionGraph<T> {\n\t\tconst t = this.topic<T>(topicName);\n\t\treturn new SubscriptionGraph<T>(subName, t, opts);\n\t}\n\n\t/**\n\t * Unmounts and tears down the topic's graph. Returns `true` if the topic\n\t * existed. Subscribers receive `TEARDOWN` via {@link Graph.remove}.\n\t *\n\t * **Closure-state caveat:** the registry mutation (`_registry.delete`) and\n\t * version bump happen in a `try/finally`, so registry/version converge to\n\t * a consistent state even when {@link Graph.remove} throws. `mutate`\n\t * does not roll back this mutation on throw — `Map.delete` on closure\n\t * state is invisible to any batch frame. The pre-existing try/finally is\n\t * load-bearing for that invariant.\n\t */\n\tremoveTopic(name: string): boolean {\n\t\tif (!this._registry.has(name)) return false;\n\t\t// P1 / P3: Graph.remove first — if it throws, `_registry` must NOT still\n\t\t// hold the broken half-disposed topic (otherwise the next\n\t\t// `hub.topic(name)` returns the corrupted reference). The `try/finally`\n\t\t// inside `_removeTopicImpl`'s action body preserves that invariant.\n\t\tthis._removeTopicImpl(name);\n\t\treturn true;\n\t}\n}\n\n/**\n * Creates a Pulsar-inspired topic graph (append-only retained stream + latest value).\n */\nexport function topic<T>(name: string, opts?: TopicOptions): TopicGraph<T> {\n\treturn new TopicGraph<T>(name, opts);\n}\n\n/**\n * Creates a lazy Pulsar-inspired messaging hub. Topics are created on first access\n * via `hub.topic(name)`; `hub.publish(name, value)` shortcuts through the registry.\n *\n * @example\n * ```ts\n * import { messagingHub } from \"@graphrefly/graphrefly\";\n *\n * const hub = messagingHub(\"main\", { defaultTopicOptions: { retainedLimit: 256 } });\n * hub.publish(\"orders\", { id: 1 });\n * hub.publishMany([[\"shipments\", { id: 1 }], [\"orders\", { id: 2 }]]);\n * const sub = hub.subscribe(\"orders-worker\", \"orders\", { cursor: 0 });\n * ```\n */\nexport function messagingHub(name: string, opts?: MessagingHubOptions): MessagingHubGraph {\n\treturn new MessagingHubGraph(name, opts);\n}\n\n/**\n * Creates a cursor-based subscription graph over a topic.\n */\nexport function subscription<T>(\n\tname: string,\n\ttopicGraph: TopicGraph<T>,\n\topts?: SubscriptionOptions,\n): SubscriptionGraph<T> {\n\treturn new SubscriptionGraph<T>(name, topicGraph, opts);\n}\n\n/**\n * Creates an autonomous cursor-based topic relay graph.\n *\n * When `opts.map` is provided, items where `map` returns `undefined` are\n * consumed from the source cursor but NOT republished (at-most-once with\n * silent drop). For filter-with-retry semantics, apply the filter in a\n * downstream subscription on the bridge's `output` node instead.\n */\nexport function topicBridge<TIn, TOut = TIn>(\n\tname: string,\n\tsourceTopic: TopicGraph<TIn>,\n\ttargetTopic: TopicGraph<TOut>,\n\topts?: TopicBridgeOptions<TIn, TOut>,\n): TopicBridgeGraph<TIn, TOut> {\n\treturn new TopicBridgeGraph<TIn, TOut>(name, sourceTopic, targetTopic, opts);\n}\n\n// ── LogProjector ──────────────────────────────────────────────────────────\n//\n// Promotion 2 (memo:Re Story 6.4 back-derivation, design-review-locked\n// 2026-05-16). A cursor-driven projector over a log/topic where a per-item\n// sink can poison-fail. memo:Re hand-rolled `createProjectorCursor` and got\n// the failure mode wrong: a bare `catch { break; }` conflated a *transient*\n// condition (a native feature not yet available → retry later) with a\n// *poison* entry (will never project) → a permanent head-of-line block of\n// every newer entry. The fix is a real, observable, subscribable dead-letter\n// topic + a typed failure policy.\n//\n// Built ON `subscription()` (TopicGraph source) / the bundle's `fromCursor`\n// view (ReactiveLogBundle source) — the same hardened cursor machinery\n// `SubscriptionGraph` itself uses — so the consumer never hand-rolls cursor\n// persistence/durability (the Med \"durability skew\" + parse-leniency findings\n// dissolve). Scope is deliberately bounded: `halt | deadLetter` only, NO\n// programmatic retry/backoff (compose a downstream subscription on\n// `deadLetter` for that — avoids the §44 wrap-imperative-as-primitive trap).\n\nexport type ProjectorPoisonPolicy = \"halt\" | \"deadLetter\";\n\n/** A poison entry routed to {@link LogProjectorGraph.deadLetter}. */\nexport type DeadLetterEntry<T> = {\n\treadonly item: T;\n\t/** `Error.message` (or `String(thrown)`) from the failing `sink`. */\n\treadonly error: string;\n\t/** Absolute 0-based log position of the poisoned item. */\n\treadonly cursorPos: number;\n};\n\nexport type LogProjectorOptions<T> = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Per-item side-effecting projection.\n\t *\n\t * **Transient-vs-poison contract (read this).** The projector cannot tell\n\t * \"this will project later\" from \"this will never project\" — only the sink\n\t * knows. So the contract is:\n\t * - **Return normally** (sync return, or a resolved Promise) → the item is\n\t * *handled*; the cursor advances. Use this for the success path AND for\n\t * any transient/skip condition the sink wants to no-op (e.g. an optional\n\t * native feature not yet available — return without throwing; the entry\n\t * is simply considered done for this projector).\n\t * - **Throw / reject** → the item is *poison*; the {@link onPoison} policy\n\t * applies. Do NOT throw for transient conditions or the item is\n\t * dead-lettered (or halts the stream).\n\t */\n\treadonly sink: (item: T) => void | Promise<void>;\n\t/**\n\t * Behaviour when `sink` throws/rejects on an item (poison):\n\t * - `\"halt\"` (default) — stop projecting at the poison item; the cursor\n\t * does NOT advance past it (head-of-line stop). `position` stalls — that\n\t * is the observable signal. No retry/backoff is built in.\n\t * - `\"deadLetter\"` — publish `{ item, error, cursorPos }` to the\n\t * {@link LogProjectorGraph.deadLetter} topic and advance past it, so\n\t * newer entries still project.\n\t */\n\treadonly onPoison?: ProjectorPoisonPolicy;\n\t/**\n\t * Initial cursor position. `\"retained\"` (default) projects all history;\n\t * `\"now\"` skips existing entries (project only future appends); a number\n\t * starts at that absolute index.\n\t */\n\treadonly from?: \"retained\" | \"now\" | number;\n\t/** Retained window for the `deadLetter` topic. Default 1024. */\n\treadonly deadLetterRetainedLimit?: number;\n};\n\n/**\n * Cursor-driven projector over a {@link TopicGraph} or {@link ReactiveLogBundle}.\n *\n * Topology (mounted on the returned graph):\n * - `subscription` (TopicGraph source only) — the hardened\n * {@link SubscriptionGraph} cursor; or a local `cursor` state + the\n * bundle's `fromCursor` view (ReactiveLogBundle source).\n * - `drain` — an `effect` that, on every not-yet-projected wave, schedules a\n * serialized async pass that calls `sink` per item (mirrors the\n * `SubscriptionGraph.ackPump` / `TopicBridge.ackPump` effect precedent +\n * memo:Re's `inFlight` chain — one wave processed at a time).\n * - `deadLetter` — a real {@link TopicGraph} (NOT a callback): poison entries\n * are observable in `describe()` and subscribable, instead of memo:Re's\n * silent `break`.\n *\n * **No imperative reads.** Observe `position` (cursor) / subscribe to\n * `deadLetter`. `idle()` is a test-only await convenience.\n *\n * @category patterns\n */\nexport class LogProjectorGraph<T> extends Graph {\n\t/** Reactive count of fully-projected entries (the cursor; read-only). */\n\treadonly position: Node<number>;\n\t/**\n\t * Poison entries (populated when `onPoison: \"deadLetter\"`). A real topic —\n\t * subscribable + visible in `describe()`.\n\t */\n\treadonly deadLetter: TopicGraph<DeadLetterEntry<T>>;\n\tprivate _inFlight: Promise<void> = Promise.resolve();\n\n\tconstructor(\n\t\tname: string,\n\t\tsource: TopicGraph<T> | ReactiveLogBundle<T>,\n\t\topts: LogProjectorOptions<T>,\n\t) {\n\t\tsuper(name, opts.graph);\n\t\tconst onPoison: ProjectorPoisonPolicy = opts.onPoison ?? \"halt\";\n\t\tconst sink = opts.sink;\n\n\t\tconst dl = new TopicGraph<DeadLetterEntry<T>>(`${name}_dead_letter`, {\n\t\t\tretainedLimit: opts.deadLetterRetainedLimit ?? DEFAULT_TOPIC_RETAINED_LIMIT,\n\t\t});\n\t\tthis.mount(\"deadLetter\", dl);\n\t\tthis.deadLetter = dl;\n\n\t\t// Uniform cursor surface over either source kind. A TopicGraph reuses\n\t\t// the hardened SubscriptionGraph cursor; a ReactiveLogBundle uses a\n\t\t// local state cursor + the bundle's `fromCursor` view — the very\n\t\t// machinery SubscriptionGraph is itself built on.\n\t\tlet available: Node<readonly T[]>;\n\t\tlet cursorBase: () => number;\n\t\tlet advance: (n: number) => void;\n\n\t\tif (source instanceof TopicGraph) {\n\t\t\tconst sub = new SubscriptionGraph<T>(`${name}_subscription`, source, {\n\t\t\t\tfrom: opts.from ?? \"retained\",\n\t\t\t});\n\t\t\tthis.mount(\"subscription\", sub);\n\t\t\tavailable = sub.available;\n\t\t\tthis.position = sub.cursor;\n\t\t\tcursorBase = () => sub.cursor.cache as number;\n\t\t\tadvance = (n) => {\n\t\t\t\tif (n > 0) sub.ack(n);\n\t\t\t};\n\t\t} else {\n\t\t\tconst log = source;\n\t\t\tlet initialCursor: number;\n\t\t\tif (opts.from === \"now\") {\n\t\t\t\tinitialCursor = log.size;\n\t\t\t} else if (typeof opts.from === \"number\") {\n\t\t\t\tinitialCursor = requireNonNegativeInt(opts.from, \"logProjector from\");\n\t\t\t} else {\n\t\t\t\tinitialCursor = 0; // \"retained\"\n\t\t\t}\n\t\t\tconst cursor = this.state<number>(\"cursor\", initialCursor, {\n\t\t\t\tmeta: messagingMeta(\"log_projector_cursor\"),\n\t\t\t});\n\t\t\tthis.position = cursor;\n\t\t\tcursorBase = () => cursor.cache as number;\n\t\t\tavailable = log.view({ kind: \"fromCursor\", cursor });\n\t\t\tadvance = (n) => {\n\t\t\t\tif (n > 0) cursor.emit((cursor.cache as number) + n);\n\t\t\t};\n\t\t}\n\n\t\t// `halt` is a HARD LATCH (QA-C): on the first poison under `onPoison:\n\t\t// \"halt\"`, `sink` has been invoked exactly once on the poison item;\n\t\t// the projector then freezes — no further `sink` calls, no rescheduled\n\t\t// drains — so a later unrelated append cannot re-invoke the (possibly\n\t\t// side-effecting, non-idempotent) sink on the poison. The stalled\n\t\t// `position` + frozen stream IS the observable signal. v1 has no retry\n\t\t// (compose downstream of `deadLetter` if you need that).\n\t\tlet halted = false;\n\n\t\t// Serialized async drain. One wave processed at a time (the inFlight\n\t\t// chain) so an async `sink` cannot interleave; the cursor is advanced\n\t\t// ONCE per pass after the captured snapshot is processed (mirrors\n\t\t// memo:Re's `runPump` + the ackPump effect precedent).\n\t\tconst runDrain = async (): Promise<void> => {\n\t\t\tif (halted) return;\n\t\t\tconst snapshot = (available.cache as readonly T[] | undefined) ?? [];\n\t\t\tif (snapshot.length === 0) return;\n\t\t\tlet consumed = 0;\n\t\t\tfor (let i = 0; i < snapshot.length; i += 1) {\n\t\t\t\tconst item = snapshot[i] as T;\n\t\t\t\ttry {\n\t\t\t\t\tawait sink(item);\n\t\t\t\t\tconsumed += 1;\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconst error = e instanceof Error ? e.message : String(e);\n\t\t\t\t\tif (onPoison === \"deadLetter\") {\n\t\t\t\t\t\tdl.publish({ item, error, cursorPos: cursorBase() + consumed });\n\t\t\t\t\t\tconsumed += 1; // advance past the poison\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t// \"halt\" — latch and stop here; do NOT advance past the\n\t\t\t\t\t// poison, do NOT re-invoke `sink` on any later wave.\n\t\t\t\t\thalted = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (consumed > 0) advance(consumed);\n\t\t};\n\t\tconst schedule = (): void => {\n\t\t\tif (halted) return; // latched — no further drains\n\t\t\tthis._inFlight = this._inFlight.then(runDrain, runDrain);\n\t\t};\n\n\t\t// Effect: every wave that exposes not-yet-projected entries schedules a\n\t\t// drain. Side-effecting (sink / cursor advance / dead-letter publish) →\n\t\t// an `effect` node, not a pure derived (COMPOSITION-GUIDE §35; exact\n\t\t// `SubscriptionGraph.advancePump` precedent — never calls `emit` on its\n\t\t// own node, kept warm via `keepalive`).\n\t\tconst drain = node<unknown>(\n\t\t\t[available],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst b = batchData[0];\n\t\t\t\tconst snap = (b != null && b.length > 0 ? b.at(-1) : ctx.prevData[0]) as\n\t\t\t\t\t| readonly T[]\n\t\t\t\t\t| undefined;\n\t\t\t\tif (snap && snap.length > 0) schedule();\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"drain\",\n\t\t\t\tdescribeKind: \"effect\",\n\t\t\t\tmeta: messagingMeta(\"log_projector_drain\"),\n\t\t\t},\n\t\t);\n\t\tthis.add(drain, { name: \"drain\" });\n\t\tthis.addDisposer(keepalive(drain));\n\t}\n\n\t/**\n\t * Await any in-flight drain pass. **Test convenience only** — the canonical\n\t * reactive observable is {@link LogProjectorGraph.position}.\n\t */\n\tidle(): Promise<void> {\n\t\treturn this._inFlight;\n\t}\n}\n\n/**\n * Creates a cursor-driven log/topic projector with a typed poison-failure\n * policy and an observable dead-letter topic.\n *\n * @example\n * ```ts\n * import { logProjector, topic } from \"@graphrefly/graphrefly\";\n *\n * const events = topic<Doc>(\"docs\");\n * const proj = logProjector(\"indexer\", events, {\n * sink: async (doc) => { await index(doc); }, // throw ⇒ poison\n * onPoison: \"deadLetter\",\n * });\n * proj.deadLetter.events.subscribe(/* observe poison *​/);\n * ```\n *\n * @remarks\n * **Use an UNBOUNDED source for durable / long-lived projection.** The cursor\n * is an absolute index; the underlying `fromCursor` view slices the source's\n * *current* entries array. A `TopicGraph` with a `retainedLimit` (or a\n * `ReactiveLogBundle` with `maxSize`) trims its head, so an absolute cursor\n * past the retained window reads the wrong offset (skips entries or stalls).\n * This is inherited `subscription()` / `fromCursor` behaviour, not specific to\n * `logProjector` — but it matters here because projection is typically\n * long-lived. For unbounded projection pass a source with NO `retainedLimit` /\n * `maxSize` (memo:Re's `changesetLog` is unbounded ✓).\n *\n * @category patterns\n */\nexport function logProjector<T>(\n\tname: string,\n\tsource: TopicGraph<T> | ReactiveLogBundle<T>,\n\topts: LogProjectorOptions<T>,\n): LogProjectorGraph<T> {\n\treturn new LogProjectorGraph<T>(name, source, opts);\n}\n","/**\n * harnessLoop() factory (roadmap §9.0).\n *\n * Wires the static 7-stage topology: INTAKE → TRIAGE → QUEUE → GATE →\n * EXECUTE → VERIFY → REFLECT. Static topology, flowing data — the Kafka\n * insight applied to human+LLM collaboration.\n *\n * **Hub model (Wave B Unit 20 C + Q1).** All reactive-wire-crossing topics\n * live in one `MessagingHubGraph` exposed as `HarnessGraph.queues`: the\n * four per-route queues, an `__unrouted` dead-letter, plus `intake`,\n * `retry`, `verify-results`, and the `triage-output` fan-in topic. The\n * router is a single derived/effect pair that publishes to `triage-output`;\n * per-route `topicBridge`s fan out by `map:` predicate. Routing is data\n * (topic name), not code — every routing decision is a visible edge in\n * `describe()` / `explain()`.\n *\n * **EXECUTE/VERIFY via JobFlow (Tier 6.5 C2 lock, 2026-04-28).** The\n * stages 5–6 EXECUTE → VERIFY pair runs through an internal `executeFlow`\n * JobFlow with two stages (`execute`, `verify`). Each stage's pump owns\n * `claim → work → ack` for one claim; the verify stage's payload contains\n * `{ item, execution, verify }` so the post-completed dispatch effect can\n * route the 3-way verdict (verified / self-correctable retry / structural\n * + reingest) without any cross-wave `withLatestFrom` pairing. Items\n * arriving from per-route topics + retry feedback enter via a single\n * `enqueueEffect` that pushes to `executeFlow.queue(\"execute\")`.\n *\n * @module\n */\n\nimport { monotonicNs, type Node, node, placeholderArgs } from \"@graphrefly/pure-ts/core\";\nimport { merge, withLatestFrom } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport { tryIncrementBounded } from \"../../base/mutation/index.js\";\nimport { _oneShotLlmCall, stripFences } from \"../../utils/ai/_internal.js\";\nimport type { ChatMessage, LLMAdapter } from \"../../utils/ai/index.js\";\nimport { promptNode } from \"../../utils/ai/index.js\";\nimport { trackingKey } from \"../../utils/harness/_internal.js\";\nimport {\n\tDEFAULT_DECAY_RATE,\n\tDEFAULT_EXECUTE_PROMPT,\n\tDEFAULT_QUEUE_CONFIGS,\n\tDEFAULT_SEVERITY_WEIGHTS,\n\tDEFAULT_TRIAGE_PROMPT,\n\tDEFAULT_VERIFY_PROMPT,\n\tdefaultErrorClassifier,\n\tQUEUE_NAMES,\n\tresolvePromptFn,\n} from \"../../utils/harness/defaults.js\";\nimport {\n\ttype StrategyModelGraph,\n\ttype StrategySnapshot,\n\tstrategyModel,\n} from \"../../utils/harness/strategy.js\";\nimport type {\n\tErrorClassifier,\n\tExecuteOutput,\n\tExecutePromptFn,\n\tExecutionResult,\n\tHarnessExecutor,\n\tHarnessJobPayload,\n\tHarnessLoopOptions,\n\tHarnessVerifier,\n\tIntakeItem,\n\tQueueConfig,\n\tQueueRoute,\n\tTriagedItem,\n\tVerifyOutput,\n\tVerifyPromptFn,\n\tVerifyResult,\n} from \"../../utils/harness/types.js\";\nimport { DEFAULT_PRESET_ID, strategyKey } from \"../../utils/harness/types.js\";\nimport {\n\ttype JobEnvelope,\n\ttype JobFlowGraph,\n\ttype JobQueueGraph,\n\tjobFlow,\n\tjobQueue,\n} from \"../../utils/job-queue/index.js\";\nimport {\n\ttype MessagingHubGraph,\n\tmessagingHub,\n\ttype TopicGraph,\n\ttopicBridge,\n} from \"../../utils/messaging/index.js\";\nimport { type GateController, pipelineGraph } from \"../../utils/orchestration/index.js\";\n\n// ---------------------------------------------------------------------------\n// Hub topic names (internal constants — strings are the routing API)\n// ---------------------------------------------------------------------------\n\nconst TOPIC_INTAKE = \"intake\";\nconst TOPIC_TRIAGE_OUTPUT = \"triage-output\";\nconst TOPIC_RETRY = \"retry\";\nconst TOPIC_VERIFY_RESULTS = \"verify-results\";\nconst TOPIC_UNROUTED = \"__unrouted\";\n\n// ---------------------------------------------------------------------------\n// Default LLM executor / verifier work fns (Tier 6.5 C2)\n// ---------------------------------------------------------------------------\n\n/**\n * Build the default EXECUTE work fn — calls `adapter.invoke()` once per\n * claimed job, parses the JSON response into an `ExecuteOutput<A>`, and\n * returns a {@link HarnessJobPayload} with `execution` filled in.\n *\n * Errors (parse failure, adapter throw, malformed JSON) are caught and\n * surfaced as a `failure`-outcome payload — the dispatch effect routes\n * the item rather than dropping it via pump nack (see C2 contract on\n * {@link HarnessExecutor}).\n *\n * Subsumes the pre-Tier-6.5 `promptNode`-based default: per-claim LLM\n * calls don't benefit from `promptNode`'s cross-wave switchMap, and a\n * fresh per-claim subgraph would be wasteful. Direct `adapter.invoke`\n * is the right shape inside JobFlow pumps.\n *\n * @param adapter - LLMAdapter for the execute call.\n * @param prompt - Prompt template (string or `(item) => string`). Defaults\n * to the harness's built-in execute prompt.\n */\nexport function defaultLlmExecutor<A = unknown>(\n\tadapter: LLMAdapter,\n\tprompt?: string | ExecutePromptFn,\n): HarnessExecutor<A> {\n\tconst promptFn = resolvePromptFn<TriagedItem>(prompt, DEFAULT_EXECUTE_PROMPT, (tpl, item) =>\n\t\ttpl.replace(\"{{item}}\", JSON.stringify(item)),\n\t);\n\treturn (job, opts) => {\n\t\tconst item = job.payload.item;\n\t\tconst messages: readonly ChatMessage[] = [{ role: \"user\", content: promptFn(item) }];\n\t\t// Bridge-layer flakes get `outcome: \"failure\"` with no `errorClass`.\n\t\t// The dispatch effect's `errorClassifier` runs over `detail` and the\n\t\t// default classifier matches `parse|json|config|validation|syntax`,\n\t\t// so parse-error flakes route to retry. Adapter HTTP/network failures\n\t\t// without a keyword fall through to structural per the existing\n\t\t// asymmetry (executor side relies on classifier; verifier side sets\n\t\t// errorClass directly per qa F3).\n\t\tconst failurePayload = (detail: string): HarnessJobPayload<A> => ({\n\t\t\t...job.payload,\n\t\t\texecution: { item, outcome: \"failure\", detail },\n\t\t});\n\t\tconst formatErr = (err: unknown): string => (err instanceof Error ? err.message : String(err));\n\t\t// One-shot bridge via `_oneShotLlmCall` (patterns/ai/_internal.ts).\n\t\t// Helper owns subscription / abort / first-DATA capture / COMPLETE\n\t\t// arm; this site owns parse + validate + payload mapping. Pump-\n\t\t// supplied `opts.signal` (Tier 6.5 2.5b) cascades into adapter +\n\t\t// fromAny via `parentSignal`.\n\t\treturn _oneShotLlmCall<HarnessJobPayload<A>>(adapter, messages, {\n\t\t\tparentSignal: opts?.signal,\n\t\t\tonSuccess: (resp) => {\n\t\t\t\tlet parsed: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tparsed = JSON.parse(stripFences(String(resp.content)));\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn failurePayload(`execute parse error: ${formatErr(err)}`);\n\t\t\t\t}\n\t\t\t\t// Validate plain object before field access — non-object JSON\n\t\t\t\t// (`null` / number / array / string) silently masks malformed\n\t\t\t\t// responses unless caught here. Surfaced via parse-error keyword\n\t\t\t\t// for classifier routing.\n\t\t\t\tif (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\t\t\treturn failurePayload(\n\t\t\t\t\t\t`execute parse error: non-object response: ${JSON.stringify(parsed)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst obj = parsed as Partial<ExecuteOutput<A>>;\n\t\t\t\treturn {\n\t\t\t\t\t...job.payload,\n\t\t\t\t\texecution: {\n\t\t\t\t\t\titem,\n\t\t\t\t\t\toutcome: obj.outcome ?? \"failure\",\n\t\t\t\t\t\tdetail: obj.detail ?? \"unknown\",\n\t\t\t\t\t\tartifact: obj.artifact,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\tonFailure: (kind, err) => {\n\t\t\t\tif (kind === \"complete\") {\n\t\t\t\t\treturn failurePayload(\"adapter completed without emitting DATA\");\n\t\t\t\t}\n\t\t\t\treturn failurePayload(`executor failed: ${formatErr(err)}`);\n\t\t\t},\n\t\t});\n\t};\n}\n\n/**\n * Build the default VERIFY work fn — calls `adapter.invoke()` once per\n * claimed job to review the prior-stage execution, parses the JSON\n * response into a `VerifyOutput`, and returns a {@link HarnessJobPayload}\n * with `verify` filled in.\n *\n * Same C2 error semantics as {@link defaultLlmExecutor}: parse / adapter\n * failures are surfaced as a structural-failure verify payload so the\n * dispatch effect routes the item.\n */\nexport function defaultLlmVerifier<A = unknown>(\n\tadapter: LLMAdapter,\n\tprompt?: string | VerifyPromptFn<A>,\n): HarnessVerifier<A> {\n\tconst promptFn = resolvePromptFn<readonly [ExecuteOutput<A> | null, TriagedItem | null]>(\n\t\tprompt,\n\t\tDEFAULT_VERIFY_PROMPT,\n\t\t(tpl, pair) => {\n\t\t\tconst [execution, item] = pair;\n\t\t\treturn tpl\n\t\t\t\t.replace(\"{{execution}}\", JSON.stringify(execution))\n\t\t\t\t.replace(\"{{item}}\", JSON.stringify(item));\n\t\t},\n\t);\n\treturn (job, opts) => {\n\t\tconst { item, execution } = job.payload;\n\t\tif (execution == null) {\n\t\t\t// Defensive — verify stage runs after execute; if execution is\n\t\t\t// missing, surface as STRUCTURAL failure rather than throw. This is\n\t\t\t// the only structural-classified path here: it indicates a topology\n\t\t\t// bug (verify ran without execute), not an LLM-bridge flake. Bridge\n\t\t\t// flakes (parse / adapter throw / ERROR / COMPLETE-without-DATA) get\n\t\t\t// `errorClass: \"self-correctable\"` below so the dispatch effect's\n\t\t\t// retry budget absorbs them before reingest fires (qa F3).\n\t\t\treturn {\n\t\t\t\t...job.payload,\n\t\t\t\tverify: {\n\t\t\t\t\tverified: false,\n\t\t\t\t\tfindings: [\"verifier: prior execute stage produced no execution\"],\n\t\t\t\t\terrorClass: \"structural\",\n\t\t\t\t},\n\t\t\t} satisfies HarnessJobPayload<A>;\n\t\t}\n\t\tconst messages: readonly ChatMessage[] = [\n\t\t\t{ role: \"user\", content: promptFn([execution, item]) },\n\t\t];\n\t\t// Bridge-layer flakes: classify as self-correctable so the dispatch\n\t\t// effect routes via the retry budget first. Persistent flakes still\n\t\t// fall through to structural after `maxRetries` exhaustion (qa F3).\n\t\tconst failurePayload = (finding: string): HarnessJobPayload<A> => ({\n\t\t\t...job.payload,\n\t\t\tverify: {\n\t\t\t\tverified: false,\n\t\t\t\tfindings: [finding],\n\t\t\t\terrorClass: \"self-correctable\",\n\t\t\t},\n\t\t});\n\t\tconst formatErr = (err: unknown): string => (err instanceof Error ? err.message : String(err));\n\t\t// One-shot bridge — see `_oneShotLlmCall` JSDoc. Helper owns the\n\t\t// subscribe + capture + abort + COMPLETE arm; this site owns parse +\n\t\t// validate + verify-payload mapping. Pump-supplied `opts.signal`\n\t\t// (Tier 6.5 2.5b) cascades into adapter + fromAny via `parentSignal`.\n\t\treturn _oneShotLlmCall<HarnessJobPayload<A>>(adapter, messages, {\n\t\t\tparentSignal: opts?.signal,\n\t\t\tonSuccess: (resp) => {\n\t\t\t\tlet parsed: unknown;\n\t\t\t\ttry {\n\t\t\t\t\tparsed = JSON.parse(stripFences(String(resp.content)));\n\t\t\t\t} catch (err) {\n\t\t\t\t\treturn failurePayload(`verify parse error: ${formatErr(err)}`);\n\t\t\t\t}\n\t\t\t\tif (parsed == null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\t\t\treturn failurePayload(\n\t\t\t\t\t\t`verify parse error: non-object response: ${JSON.stringify(parsed)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst obj = parsed as Partial<VerifyOutput>;\n\t\t\t\treturn {\n\t\t\t\t\t...job.payload,\n\t\t\t\t\tverify: {\n\t\t\t\t\t\tverified: obj.verified === true,\n\t\t\t\t\t\tfindings: obj.findings ?? [],\n\t\t\t\t\t\terrorClass: obj.errorClass,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\tonFailure: (kind, err) => {\n\t\t\t\tif (kind === \"complete\") {\n\t\t\t\t\treturn failurePayload(\"verifier completed without emitting DATA\");\n\t\t\t\t}\n\t\t\t\treturn failurePayload(`verifier failed: ${formatErr(err)}`);\n\t\t\t},\n\t\t});\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// HarnessGraph\n// ---------------------------------------------------------------------------\n\n/**\n * The graph returned by {@link harnessLoop}. Wraps a single\n * {@link MessagingHubGraph} that owns all reactive-wire-crossing topics\n * (intake, per-route queues, `__unrouted`, retry, verify-results,\n * triage-output), plus an `executeFlow` JobFlow that owns the\n * EXECUTE → VERIFY pipeline (Tier 6.5 C2). Sugar getters expose the\n * canonical topics so the surface stays ergonomic.\n */\nexport class HarnessGraph<A = unknown> extends Graph {\n\t/** Messaging hub — the routing-data plane. Queue topics live here. */\n\treadonly queues: MessagingHubGraph;\n\n\t/**\n\t * EXECUTE → VERIFY JobFlow (Tier 6.5 C2). Pumps own claim/ack/nack\n\t * lifecycle for each stage. Inspect via:\n\t * - `harness.executeFlow.queue(\"execute\").pending` — pending depth.\n\t * - `harness.executeFlow.queue(\"verify\").pending` — items mid-execute.\n\t * - `harness.executeFlow.completed` — verified items waiting for the\n\t * dispatch effect's 3-way routing.\n\t * - `harness.executeFlow.completedCount` — total terminal completions.\n\t */\n\treadonly executeFlow: JobFlowGraph<HarnessJobPayload<A>>;\n\n\t/**\n\t * Per-route JobQueueGraph audit mirrors. Each triaged item that reaches\n\t * a queue is also enqueued here, giving reactive `depth` + `pending` +\n\t * `jobs` observables per route. The dispatch effect ack/removeBy-id's\n\t * the matching job on terminal verdict. The executeFlow JobFlow handles\n\t * the EXECUTE → VERIFY data flow; this is a parallel audit-side ledger\n\t * for per-route depth metrics. Inspect via\n\t * `harness.jobs.get(route).depth.cache` for backpressure metrics.\n\t */\n\treadonly jobs: ReadonlyMap<QueueRoute, JobQueueGraph<TriagedItem>>;\n\n\t/** Per-route gate controllers (only for gated queues). */\n\treadonly gates: ReadonlyMap<QueueRoute, GateController<TriagedItem>>;\n\n\t/**\n\t * Per-route queue topics — typed accessor for the four\n\t * {@link QUEUE_NAMES} entries (`auto-fix`, `needs-decision`,\n\t * `investigation`, `backlog`). Mirrors the `gates` / `jobs` map\n\t * shape so callers can iterate `[route, topic]` pairs without\n\t * hand-rolling `harness.queues.topicNames()` + meta-topic exclusion.\n\t *\n\t * Excludes the meta topics that share the hub:\n\t * `intake` (use {@link intake}), `verify-results` (use\n\t * {@link verifyResults}), `retry` (use {@link retry}), `__unrouted`\n\t * (use {@link unrouted}), and the internal `triage-output` fan-in.\n\t */\n\treadonly queueTopics: ReadonlyMap<QueueRoute, TopicGraph<TriagedItem>>;\n\n\t/**\n\t * Strategy model — `auditedSuccessTracker` keyed by `StrategyKey`.\n\t *\n\t * **Ownership (EC10/EC15).** Owned by the harness: it is mounted as a\n\t * child subgraph (`harness.mount(\"strategy\", strategy)`), so its disposal\n\t * cascades from `harness.destroy()` via the mount lifecycle. Do **not**\n\t * call `strategy.destroy()` independently — the harness's `triage-input`\n\t * node and (when `opts.priority` is set) `buildPriorityScores` hold\n\t * cross-graph deps on `strategy.entries`; destroying the strategy out of\n\t * band staleness those nodes while the rest of the loop keeps running.\n\t * Read/subscribe freely; let the harness own the lifecycle.\n\t */\n\treadonly strategy: StrategyModelGraph;\n\n\t/** Global retry count across all items (circuit breaker). Reactive — subscribable. */\n\treadonly totalRetries: Node<number>;\n\n\t/** Global reingestion count across all items (circuit breaker). Reactive — subscribable. */\n\treadonly totalReingestions: Node<number>;\n\n\t/**\n\t * Per-route priority score nodes, populated only when `opts.priority` is\n\t * set on {@link harnessLoop}. Each node emits a score combining severity,\n\t * attention decay, and strategy-model effectiveness for the route's\n\t * current head-of-queue item. `undefined` means the caller did not opt\n\t * in to priority scoring.\n\t */\n\treadonly priorityScores?: ReadonlyMap<QueueRoute, Node<number>>;\n\n\t/**\n\t * REFLECT-stage tick marker — emits one DATA per terminal verdict observed\n\t * on `executeFlow.completed`. `equals: () => false` so each completion\n\t * produces an observable tick (no Object.is collapse on identical\n\t * `null` payloads). Inspection tools (`harnessTrace`, dashboards) can\n\t * subscribe directly here instead of resolving by string path\n\t * (`harness.node(\"reflect\")`) — the field is the lock against rename\n\t * drift.\n\t */\n\treadonly reflect: Node<null>;\n\n\tconstructor(\n\t\tname: string,\n\t\tqueues: MessagingHubGraph,\n\t\texecuteFlow: JobFlowGraph<HarnessJobPayload<A>>,\n\t\tqueueTopics: Map<QueueRoute, TopicGraph<TriagedItem>>,\n\t\tjobs: Map<QueueRoute, JobQueueGraph<TriagedItem>>,\n\t\tgates: Map<QueueRoute, GateController<TriagedItem>>,\n\t\tstrategy: StrategyModelGraph,\n\t\ttotalRetries: Node<number>,\n\t\ttotalReingestions: Node<number>,\n\t\treflect: Node<null>,\n\t\tpriorityScores?: Map<QueueRoute, Node<number>>,\n\t) {\n\t\tsuper(name);\n\t\tthis.queues = queues;\n\t\tthis.executeFlow = executeFlow;\n\t\tthis.queueTopics = queueTopics;\n\t\tthis.jobs = jobs;\n\t\tthis.gates = gates;\n\t\tthis.strategy = strategy;\n\t\tthis.totalRetries = totalRetries;\n\t\tthis.totalReingestions = totalReingestions;\n\t\tthis.reflect = reflect;\n\t\tthis.priorityScores = priorityScores;\n\t}\n\n\t/** Intake topic — publish items here to enter the loop. */\n\tget intake(): TopicGraph<IntakeItem> {\n\t\treturn this.queues.topic<IntakeItem>(TOPIC_INTAKE);\n\t}\n\n\t/** Verify results topic — subscribe to see verification outcomes. */\n\tget verifyResults(): TopicGraph<VerifyResult<A>> {\n\t\treturn this.queues.topic<VerifyResult<A>>(TOPIC_VERIFY_RESULTS);\n\t}\n\n\t/** Retry feedback topic — fast-retry re-entry point. */\n\tget retry(): TopicGraph<TriagedItem> {\n\t\treturn this.queues.topic<TriagedItem>(TOPIC_RETRY);\n\t}\n\n\t/** Dead-letter topic for items whose LLM-chosen route is unknown. */\n\tget unrouted(): TopicGraph<TriagedItem> {\n\t\treturn this.queues.topic<TriagedItem>(TOPIC_UNROUTED);\n\t}\n\n\t/**\n\t * Stage-label → observe-path map for the 7 pipeline stages.\n\t *\n\t * Decouples inspection tools (`harnessTrace`, `harnessProfile`, custom\n\t * dashboards) from mount-structure churn: hub migration, future stage\n\t * splits, gate remounting, or the Tier 6.5 C2 JobFlow rewire shouldn't\n\t * require edits to `trace.ts` as long as this method stays accurate.\n\t *\n\t * Each stage yields `{ label, paths }`; consumers iterate paths per\n\t * stage and attach observers. Tier 6.5: EXECUTE / VERIFY paths now\n\t * resolve to the `executeFlow` stage queues + the `verify-dispatch`\n\t * effect node.\n\t */\n\tstageNodes(): ReadonlyArray<{ label: string; paths: readonly string[] }> {\n\t\tconst hub = this.queues;\n\t\tconst resolveHubPath = (name: string): string | null =>\n\t\t\thub.has(name) ? `queues::${name}::latest` : null;\n\t\tconst includeIf = <T>(value: T | null | undefined): readonly T[] =>\n\t\t\tvalue == null ? [] : [value];\n\n\t\tconst queuePaths = QUEUE_NAMES.flatMap((r) => includeIf(resolveHubPath(r)));\n\t\tconst gatePaths: string[] = [];\n\t\tfor (const [route] of this.gates) {\n\t\t\tgatePaths.push(`gates::${route}/gate`);\n\t\t}\n\t\treturn [\n\t\t\t{ label: \"INTAKE\", paths: includeIf(resolveHubPath(\"intake\")) },\n\t\t\t{ label: \"TRIAGE\", paths: [\"triage\"] },\n\t\t\t{ label: \"QUEUE\", paths: queuePaths },\n\t\t\t{ label: \"GATE\", paths: gatePaths },\n\t\t\t{ label: \"EXECUTE\", paths: [\"executeFlow::execute::events\"] },\n\t\t\t{ label: \"VERIFY\", paths: [\"executeFlow::verify::events\"] },\n\t\t\t{ label: \"REFLECT\", paths: [\"reflect\"] },\n\t\t\t{ label: \"STRATEGY\", paths: [\"strategy::entries\"] },\n\t\t];\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// harnessLoop factory\n// ---------------------------------------------------------------------------\n\n/**\n * Wire the reactive collaboration loop as a static-topology graph.\n *\n * The loop has 7 stages:\n * 1. **INTAKE** — items arrive from multiple sources via `intake.publish()`\n * 2. **TRIAGE** — promptNode classifies, routes, and prioritizes\n * 3. **QUEUE** — 4 priority-ordered TopicGraphs (auto-fix, needs-decision, investigation, backlog)\n * 4. **GATE** — human approval on configurable queues\n * 5. **EXECUTE** — JobFlow `execute` stage; user-supplied or default work fn\n * 6. **VERIFY** — JobFlow `verify` stage; verifies the executed artifact\n * 7. **REFLECT** — strategy model records outcomes; dispatch effect routes 3-way\n *\n * @param name - Graph name.\n * @param opts - Configuration.\n * @returns HarnessGraph with controller accessors.\n */\nexport function harnessLoop<A = unknown>(\n\tname: string,\n\topts: HarnessLoopOptions<A>,\n): HarnessGraph<A> {\n\tconst adapter = opts.adapter;\n\tconst maxRetries = opts.maxRetries ?? 2;\n\tconst retainedLimit = opts.retainedLimit ?? 1000;\n\tconst errorClassifier: ErrorClassifier = opts.errorClassifier ?? defaultErrorClassifier;\n\n\tconst queueConfigs = new Map<QueueRoute, QueueConfig>();\n\tfor (const route of QUEUE_NAMES) {\n\t\tqueueConfigs.set(route, {\n\t\t\t...DEFAULT_QUEUE_CONFIGS[route],\n\t\t\t...opts.queues?.[route],\n\t\t});\n\t}\n\n\t// --- Messaging hub (Wave B Q1 Option A) ---\n\tconst queuesHub = messagingHub(`${name}/queues`, {\n\t\tdefaultTopicOptions: { retainedLimit },\n\t});\n\n\t// Eagerly create canonical topics so they appear in `describe()` from\n\t// construction time and `harness.queues.has(route)` answers `true`\n\t// before any publish.\n\tconst intake = queuesHub.topic<IntakeItem>(TOPIC_INTAKE);\n\tconst triageOutput = queuesHub.topic<TriagedItem>(TOPIC_TRIAGE_OUTPUT);\n\tconst retryTopic = queuesHub.topic<TriagedItem>(TOPIC_RETRY);\n\tconst verifyResults = queuesHub.topic<VerifyResult<A>>(TOPIC_VERIFY_RESULTS);\n\tconst queueTopics = new Map<QueueRoute, TopicGraph<TriagedItem>>();\n\tfor (const route of QUEUE_NAMES) {\n\t\tqueueTopics.set(route, queuesHub.topic<TriagedItem>(route));\n\t}\n\tconst unroutedTopic = queuesHub.topic<TriagedItem>(TOPIC_UNROUTED);\n\n\t// --- Strategy model (used by triage + dispatch) ---\n\tconst strategy = strategyModel();\n\n\t// --- Stage 2: TRIAGE ---\n\t// triageInput pairs intake.latest (trigger) with strategy.entries\n\t// (advisory, sampled via withLatestFrom). Breaks the feedback cycle\n\t// (verify → strategy.record → strategy.entries would otherwise re-fire\n\t// triage on every recorded outcome).\n\tconst triageInput = withLatestFrom(\n\t\tintake.latest as Node<unknown>,\n\t\tstrategy.entries as Node<unknown>,\n\t);\n\n\tconst triagePromptFn = resolvePromptFn<readonly [IntakeItem, StrategySnapshot]>(\n\t\topts.triagePrompt,\n\t\tDEFAULT_TRIAGE_PROMPT,\n\t\t(tpl, pair) => {\n\t\t\tconst [item, strat] = pair;\n\t\t\treturn tpl\n\t\t\t\t.replace(\"{{strategy}}\", JSON.stringify(Array.from(strat.entries())))\n\t\t\t\t.replace(\"{{item}}\", JSON.stringify(item));\n\t\t},\n\t);\n\n\tconst triageNode = promptNode<TriagedItem>(\n\t\tadapter as LLMAdapter,\n\t\t[triageInput as Node<unknown>],\n\t\t(pair: unknown) => {\n\t\t\t// `intake.latest` is now SENTINEL on empty (COMPOSITION-GUIDE §1a),\n\t\t\t// so the `withLatestFrom partial:false` gate holds the fn until both\n\t\t\t// deps deliver real DATA. The `=== undefined` guard catches the\n\t\t\t// edge where the pair itself is unset (defensive — shouldn't fire\n\t\t\t// in normal flow).\n\t\t\tconst asPair = pair as readonly [IntakeItem, StrategySnapshot] | undefined;\n\t\t\tif (asPair === undefined) return \"\";\n\t\t\treturn triagePromptFn(asPair);\n\t\t},\n\t\t{\n\t\t\tname: \"triage\",\n\t\t\tformat: \"json\",\n\t\t},\n\t);\n\n\t// --- Stage 3: QUEUE (hub routing) ---\n\t//\n\t// Router is a thin effect that publishes the merged TriagedItem to\n\t// `triage-output`. `topicBridge`s fan it out to per-route queues by\n\t// filtering on `item.route`. Unknown routes flow into `__unrouted` so\n\t// misclassified items become a subscribable dead-letter signal.\n\tconst routerInput = withLatestFrom(triageNode as Node<unknown>, triageInput as Node<unknown>);\n\tconst router = node(\n\t\t[routerInput as Node<unknown>],\n\t\t(batchData, _actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst pair = data[0];\n\t\t\tif (pair == null) return;\n\t\t\tconst [classification, triagePair] = pair as [\n\t\t\t\tTriagedItem | null,\n\t\t\t\t[IntakeItem | null, StrategySnapshot] | null,\n\t\t\t];\n\t\t\tif (!classification?.route) return;\n\t\t\tconst intakeItem = triagePair?.[0];\n\t\t\t// Intake fields win over classification: the LLM only owns the five\n\t\t\t// triage-classification fields (rootCause, intervention, route,\n\t\t\t// priority, triageReasoning); any intake state it accidentally\n\t\t\t// returns is overwritten by the real intake value via the trailing\n\t\t\t// spread.\n\t\t\tconst merged: TriagedItem = { ...classification, ...intakeItem } as TriagedItem;\n\t\t\ttriageOutput.publish(merged);\n\t\t},\n\t\t{ describeKind: \"effect\" },\n\t);\n\tconst routerUnsub = router.subscribe(() => {});\n\n\t// TopicBridges fan triage-output into per-route queues (visible edges).\n\tconst knownRoutes = new Set<string>(QUEUE_NAMES);\n\tfor (const route of QUEUE_NAMES) {\n\t\ttopicBridge<TriagedItem>(`bridge/${route}`, triageOutput, queueTopics.get(route)!, {\n\t\t\tmap: (item) => (item.route === route ? item : undefined),\n\t\t});\n\t}\n\ttopicBridge<TriagedItem>(\"bridge/__unrouted\", triageOutput, unroutedTopic, {\n\t\tmap: (item) => (knownRoutes.has(item.route) ? undefined : item),\n\t});\n\n\t// --- Per-route audit JobQueueGraphs (parallel ledger) ---\n\t//\n\t// One jobQueue per route mirrors the route topic's publishes so\n\t// dashboards get a subscribable `depth` / `pending` / `jobs` view of\n\t// in-progress items. Identity is established at enqueue time (the\n\t// returned `id` is paired with `trackingKey(item)`); the dispatch\n\t// effect calls `JobQueueGraph.removeById(id)` on terminal verdict.\n\t//\n\t// This audit ledger runs in parallel with the `executeFlow` JobFlow\n\t// (Tier 6.5 C2). The two are complementary:\n\t// - This ledger gives **per-route** depth/pending observables\n\t// (\"how backed up is auto-fix?\").\n\t// - executeFlow gives **per-stage** depth/pending observables\n\t// (\"how many items are mid-execute?\").\n\t//\n\t// **Retry handling.** Retry items republished to `retryTopic` flow\n\t// into executeFlow (via the enqueue effect) but NOT into per-route\n\t// audit jq's (retryTopic isn't mirrored). The audit job stays alive\n\t// across retries — only terminal (verified / structural) decisions\n\t// remove it. `depth` reflects \"items still being worked on\".\n\t//\n\t// **Ring-buffer safety.** WeakSet keyed on item identity; once the\n\t// topic's ring buffer trims the head, dropped entries become\n\t// unreachable and the WeakSet auto-prunes.\n\tconst jobQueues = new Map<QueueRoute, JobQueueGraph<TriagedItem>>();\n\tconst routeJobIds = new Map<string, { route: QueueRoute; id: string }>();\n\tfor (const route of QUEUE_NAMES) {\n\t\tjobQueues.set(route, jobQueue<TriagedItem>(`jobs/${route}`));\n\t}\n\tconst jobMirrorUnsubs: Array<() => void> = [];\n\tfor (const route of QUEUE_NAMES) {\n\t\tconst topic = queueTopics.get(route)!;\n\t\tconst jq = jobQueues.get(route)!;\n\t\tconst seen = new WeakSet<object>();\n\t\tconst mirror = node(\n\t\t\t[topic.events as Node<unknown>],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst events = data[0];\n\t\t\t\tconst arr = (events ?? []) as readonly TriagedItem[];\n\t\t\t\tfor (const item of arr) {\n\t\t\t\t\tif (seen.has(item as unknown as object)) continue;\n\t\t\t\t\tseen.add(item as unknown as object);\n\t\t\t\t\tconst id = jq.enqueue(item);\n\t\t\t\t\trouteJobIds.set(trackingKey(item), { route, id });\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ name: `jobs/${route}-mirror`, describeKind: \"effect\" },\n\t\t);\n\t\tjobMirrorUnsubs.push(mirror.subscribe(() => {}));\n\t}\n\n\tfunction ackJob(item: TriagedItem): void {\n\t\tconst key = trackingKey(item);\n\t\tconst entry = routeJobIds.get(key);\n\t\tif (!entry) return;\n\t\tjobQueues.get(entry.route)?.removeById(entry.id);\n\t\trouteJobIds.delete(key);\n\t}\n\n\t// --- Stage 4: GATE ---\n\t//\n\t// Per-route gates between `topic.latest` and the executeFlow enqueue.\n\t// Foreign-node-accept (Session B.1): pass `topic.latest` directly; the\n\t// gate factory auto-adds the source under `${name}/source` inside its\n\t// own graph if not already registered.\n\tconst gateGraph = pipelineGraph(\"gates\");\n\tconst gateControllers = new Map<QueueRoute, GateController<TriagedItem>>();\n\tfor (const route of QUEUE_NAMES) {\n\t\tconst config = queueConfigs.get(route)!;\n\t\tif (!config.gated) continue;\n\t\tconst topic = queueTopics.get(route)!;\n\t\tconst ctrl = gateGraph.approvalGate<TriagedItem>(\n\t\t\t`${route}/gate`,\n\t\t\ttopic.latest as Node<unknown>,\n\t\t\t{\n\t\t\t\tmaxPending: config.maxPending,\n\t\t\t\tstartOpen: config.startOpen,\n\t\t\t},\n\t\t);\n\t\tgateControllers.set(route, ctrl);\n\t}\n\n\t// --- executeInput: merge of post-gate route latests + retry feedback ---\n\t// All inputs are SENTINEL until first DATA (COMPOSITION-GUIDE §1a): topic\n\t// `latest` returns `[]` on empty, gate `output` doesn't push pre-DATA.\n\tconst queueOutputs: Node<TriagedItem>[] = [];\n\tfor (const route of QUEUE_NAMES) {\n\t\tconst config = queueConfigs.get(route)!;\n\t\tif (config.gated && gateControllers.has(route)) {\n\t\t\tqueueOutputs.push(gateControllers.get(route)!.output as Node<TriagedItem>);\n\t\t} else {\n\t\t\tqueueOutputs.push(queueTopics.get(route)!.latest);\n\t\t}\n\t}\n\tqueueOutputs.push(retryTopic.latest);\n\n\tconst executeInput = merge<TriagedItem>(...queueOutputs);\n\n\t// --- Stages 5+6: EXECUTE → VERIFY via JobFlow (Tier 6.5 C2) ---\n\tconst executor: HarnessExecutor<A> =\n\t\topts.executor ?? defaultLlmExecutor<A>(adapter as LLMAdapter, opts.executePrompt);\n\tconst verifier: HarnessVerifier<A> =\n\t\topts.verifier ?? defaultLlmVerifier<A>(adapter as LLMAdapter, opts.verifyPrompt);\n\n\t// Per-stage `maxPerPump` caps via the JobFlow `StageDef.maxPerPump`\n\t// extension (Tier 6.5 D1 follow-up). Each stage gets its own cap;\n\t// callers can pin execute at a low concurrency for cost control while\n\t// leaving verify unbounded (or vice versa). Defaults to\n\t// `Number.MAX_SAFE_INTEGER` per stage — matches today's unbounded\n\t// `merge()` parallelism.\n\tconst executeMaxPerPump = opts.executeMaxPerPump ?? Number.MAX_SAFE_INTEGER;\n\tconst verifyMaxPerPump = opts.verifyMaxPerPump ?? Number.MAX_SAFE_INTEGER;\n\n\tconst executeFlow = jobFlow<HarnessJobPayload<A>>(`${name}/executeFlow`, {\n\t\tstages: [\n\t\t\t{ name: \"execute\", work: (job) => executor(job), maxPerPump: executeMaxPerPump },\n\t\t\t{ name: \"verify\", work: (job) => verifier(job), maxPerPump: verifyMaxPerPump },\n\t\t],\n\t});\n\n\t// Enqueue effect: per-item bridge from the reactive `executeInput`\n\t// stream into the JobFlow. Each non-null item becomes one JobEnvelope\n\t// at the execute stage. Retry items (via `retryTopic`) re-enter the\n\t// flow as fresh enqueues with their `$retries` counter bumped.\n\tconst enqueueEffect = node(\n\t\t[executeInput as Node<unknown>],\n\t\t(batchData, _actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst item = data[0];\n\t\t\tif (item === undefined) return;\n\t\t\texecuteFlow.enqueue({ item: item as TriagedItem });\n\t\t},\n\t\t{ name: \"execute-enqueue\", describeKind: \"effect\" },\n\t);\n\tconst enqueueUnsub = enqueueEffect.subscribe(() => {});\n\n\t// --- Stage 7: dispatch effect (REFLECT + retry/structural routing) ---\n\t//\n\t// Replaces the pre-Tier-6.5 `fastRetry` effect. Reads completed\n\t// JobEnvelopes from `executeFlow.completed`, identifies new ones via\n\t// WeakSet, and dispatches the 3-way verdict:\n\t//\n\t// 1. **Verified** → record success, publish VerifyResult, ack audit job.\n\t// 2. **Self-correctable + retries available** → republish to retryTopic\n\t// with $retries bumped (no audit ack — retry stays in the audit ledger).\n\t// 3. **Structural / retries exhausted** → record failure, publish\n\t// VerifyResult, ack audit job, reingest if reingestion budget remains.\n\t//\n\t// Imperative cross-graph publish from inside an effect is sanctioned\n\t// per COMPOSITION-GUIDE §32 / §35 for terminal side-effects with audit\n\t// trails (here: verifyResults / retry / intake topics).\n\tconst maxReingestions = opts.maxReingestions ?? 1;\n\tconst maxTotalRetries = Math.min(opts.maxTotalRetries ?? maxRetries * 10, 100);\n\tconst maxTotalReingestions = Math.min(opts.maxTotalReingestions ?? maxReingestions * 10, 100);\n\tconst totalRetries = node([], { initial: 0 });\n\tconst totalReingestions = node([], { initial: 0 });\n\n\tfunction assembleResult(\n\t\texecution: ExecutionResult<A>,\n\t\tverify: VerifyOutput,\n\t\titem: TriagedItem,\n\t): VerifyResult<A> {\n\t\treturn {\n\t\t\titem,\n\t\t\texecution,\n\t\t\tverified: verify.verified,\n\t\t\tfindings: verify.findings ?? [],\n\t\t\terrorClass: verify.errorClass,\n\t\t};\n\t}\n\n\tfunction handleVerified(vr: VerifyResult<A>, item: TriagedItem): void {\n\t\tstrategy.record(strategyKey(DEFAULT_PRESET_ID, item.rootCause, item.intervention), true, {\n\t\t\tpresetId: DEFAULT_PRESET_ID,\n\t\t\trootCause: item.rootCause,\n\t\t\tintervention: item.intervention,\n\t\t});\n\t\tverifyResults.publish(vr);\n\t\tackJob(item);\n\t}\n\n\tfunction handleRetry(vr: VerifyResult<A>, item: TriagedItem): void {\n\t\tconst key = trackingKey(item);\n\t\tconst itemRetries = item.$retries ?? 0;\n\t\tconst retryItem: TriagedItem = {\n\t\t\t...item,\n\t\t\t$retries: itemRetries + 1,\n\t\t\tsummary: `[RETRY ${itemRetries + 1}/${maxRetries}] ${key} — Previous attempt failed: ${vr.findings.join(\"; \")}`,\n\t\t\trelatedTo: [key],\n\t\t};\n\t\tretryTopic.publish(retryItem);\n\t\t// Audit job stays alive across retries — only terminal (verified /\n\t\t// structural) decisions remove it.\n\t}\n\n\tfunction handleStructural(vr: VerifyResult<A>, item: TriagedItem): void {\n\t\tstrategy.record(strategyKey(DEFAULT_PRESET_ID, item.rootCause, item.intervention), false, {\n\t\t\tpresetId: DEFAULT_PRESET_ID,\n\t\t\trootCause: item.rootCause,\n\t\t\tintervention: item.intervention,\n\t\t});\n\t\tverifyResults.publish(vr);\n\t\tackJob(item);\n\t\tconst key = trackingKey(item);\n\t\tconst itemReingestions = item.$reingestions ?? 0;\n\t\tif (\n\t\t\titemReingestions < maxReingestions &&\n\t\t\ttryIncrementBounded(totalReingestions, maxTotalReingestions)\n\t\t) {\n\t\t\tintake.publish({\n\t\t\t\tsource: item.source,\n\t\t\t\tsummary: `Verification failed for: ${key}`,\n\t\t\t\tevidence: vr.findings.join(\"\\n\"),\n\t\t\t\taffectsAreas: item.affectsAreas,\n\t\t\t\taffectsEvalTasks: item.affectsEvalTasks,\n\t\t\t\tseverity: item.severity ?? \"high\",\n\t\t\t\trelatedTo: [key],\n\t\t\t\t$reingestions: itemReingestions + 1,\n\t\t\t});\n\t\t}\n\t}\n\n\t// Monotonic length cursor (qa F4) — `executeFlow.completed` retains up to\n\t// `DEFAULT_COMPLETED_RETAINED_LIMIT` (1024) entries; each new completion\n\t// emits a fresh snapshot containing every retained job. A naive\n\t// `WeakSet.has` walk is O(retainedLimit) per emit. Track the last-seen\n\t// length and only iterate the new tail. The cursor is capped at the\n\t// snapshot length to handle ring-buffer trims (when the retained log\n\t// drops oldest entries past the limit, `arr.length` shrinks and the\n\t// cursor catches up automatically).\n\tlet dispatchCursor = 0;\n\tconst dispatchEffect = node(\n\t\t[executeFlow.completed as Node<unknown>],\n\t\t(batchData, _actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst log = data[0];\n\t\t\tconst arr = (log ?? []) as readonly JobEnvelope<HarnessJobPayload<A>>[];\n\t\t\t// Trim handling: if the retained log shrunk below our cursor, the\n\t\t\t// missing entries are gone (we already processed them or the trim\n\t\t\t// happened mid-flight); just clamp.\n\t\t\tif (dispatchCursor > arr.length) dispatchCursor = arr.length;\n\t\t\tconst start = dispatchCursor;\n\t\t\tdispatchCursor = arr.length;\n\t\t\tfor (let i = start; i < arr.length; i++) {\n\t\t\t\tconst job = arr[i] as JobEnvelope<HarnessJobPayload<A>>;\n\t\t\t\tconst { item, execution, verify } = job.payload;\n\t\t\t\t// Defensive — both should always be present in a verify-stage\n\t\t\t\t// completion. If either is missing, log via verifyResults so the\n\t\t\t\t// failure is observable but don't block the dispatch effect.\n\t\t\t\tif (execution == null || verify == null) {\n\t\t\t\t\tackJob(item);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst vr = assembleResult(execution, verify, item);\n\t\t\t\tif (vr.verified) {\n\t\t\t\t\thandleVerified(vr, item);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst errClass =\n\t\t\t\t\tvr.errorClass ??\n\t\t\t\t\terrorClassifier({\n\t\t\t\t\t\titem,\n\t\t\t\t\t\toutcome: execution.outcome,\n\t\t\t\t\t\tdetail: vr.findings.join(\"; \"),\n\t\t\t\t\t});\n\t\t\t\tconst itemRetries = item.$retries ?? 0;\n\t\t\t\tif (\n\t\t\t\t\terrClass === \"self-correctable\" &&\n\t\t\t\t\titemRetries < maxRetries &&\n\t\t\t\t\ttryIncrementBounded(totalRetries, maxTotalRetries)\n\t\t\t\t) {\n\t\t\t\t\thandleRetry(vr, item);\n\t\t\t\t} else {\n\t\t\t\t\thandleStructural(vr, item);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ name: \"verify-dispatch\", describeKind: \"effect\" },\n\t);\n\tconst dispatchUnsub = dispatchEffect.subscribe(() => {});\n\n\t// REFLECT — topology marker derived from completed-log emissions.\n\t// `equals: () => false` disables Object.is absorption so each\n\t// completion produces an observable REFLECT tick (one per verify\n\t// wave). Without this, `null === null` would collapse every emit\n\t// after the first into RESOLVED and the trace would show a single\n\t// REFLECT event over the whole run.\n\tconst reflectNode = node(\n\t\t[executeFlow.completed as Node<unknown>],\n\t\t(_batchData, actions) => {\n\t\t\tactions.emit(null);\n\t\t},\n\t\t{\n\t\t\tname: \"reflect\",\n\t\t\tequals: () => false,\n\t\t},\n\t);\n\n\t// --- Optional priority scoring (Unit 19) ---\n\tlet priorityScores: Map<QueueRoute, Node<number>> | undefined;\n\tif (opts.priority) {\n\t\tpriorityScores = buildPriorityScores(queueTopics, strategy, opts);\n\t}\n\n\t// --- Assemble HarnessGraph ---\n\tconst harness = new HarnessGraph<A>(\n\t\tname,\n\t\tqueuesHub,\n\t\texecuteFlow,\n\t\tqueueTopics,\n\t\tjobQueues,\n\t\tgateControllers,\n\t\tstrategy,\n\t\ttotalRetries,\n\t\ttotalReingestions,\n\t\treflectNode as Node<null>,\n\t\tpriorityScores,\n\t);\n\n\t// Register disposers for unregistered internal nodes.\n\tharness.addDisposer(routerUnsub);\n\tharness.addDisposer(enqueueUnsub);\n\tharness.addDisposer(dispatchUnsub);\n\t// Strategy is mounted as a child subgraph below; its disposal cascades\n\t// via the mount lifecycle (no separate `addDisposer(strategy.dispose)`\n\t// needed post Class B audit Alt E migration).\n\tfor (const unsub of jobMirrorUnsubs) harness.addDisposer(unsub);\n\n\t// Register stage nodes for introspection (harnessTrace, describe,\n\t// observe). Tier 6.3: triage-input + router-input named so\n\t// `explain(intake.latest, reflect)` walks named nodes end-to-end with\n\t// no `<anonymous>` entries.\n\tharness.add(triageInput as Node<unknown>, { name: \"triage-input\" });\n\tharness.add(triageNode as Node<unknown>, { name: \"triage\" });\n\tharness.add(routerInput as Node<unknown>, { name: \"router-input\" });\n\tharness.add(executeInput as Node<unknown>, { name: \"execute-input\" });\n\tharness.add(enqueueEffect as Node<unknown>, { name: \"execute-enqueue\" });\n\tharness.add(dispatchEffect as Node<unknown>, { name: \"verify-dispatch\" });\n\tharness.add(reflectNode as Node<unknown>, { name: \"reflect\" });\n\t// Reflect is a topology marker — subscribe so its fn registers as a\n\t// reactive edge visible in `describe()` / `explain()` immediately on\n\t// harness construction.\n\tharness.addDisposer(reflectNode.subscribe(() => undefined));\n\tif (priorityScores) {\n\t\tfor (const [route, score] of priorityScores) {\n\t\t\tharness.add(score as Node<unknown>, { name: `priority/${route}` });\n\t\t\tharness.addDisposer(score.subscribe(() => {}));\n\t\t}\n\t}\n\n\t// Mount subgraphs\n\tharness.mount(\"queues\", queuesHub);\n\tharness.mount(\"gates\", gateGraph);\n\tharness.mount(\"executeFlow\", executeFlow);\n\tharness.mount(\"strategy\", strategy);\n\tfor (const [route, jq] of jobQueues) {\n\t\tharness.mount(`jobs/${route}`, jq);\n\t}\n\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` exposes provenance.\n\tharness.tagFactory(\"harnessLoop\", placeholderArgs(opts as unknown as Record<string, unknown>));\n\n\treturn harness;\n}\n\n// ---------------------------------------------------------------------------\n// Priority scoring wiring (Unit 19 decision 2)\n// ---------------------------------------------------------------------------\n\nfunction buildPriorityScores<A>(\n\tqueueTopics: Map<QueueRoute, TopicGraph<TriagedItem>>,\n\tstrategy: StrategyModelGraph,\n\topts: HarnessLoopOptions<A>,\n): Map<QueueRoute, Node<number>> {\n\tif (!opts.lastInteractionNs) {\n\t\tthrow new Error(\n\t\t\t\"harnessLoop: `opts.priority` requires `opts.lastInteractionNs` — pass a Node<number> (e.g. `fromTimer(60_000)` or a `state(monotonicNs())` you bump on human interaction). Priority scores only decay when this node settles; an internal default would freeze age at construction time.\",\n\t\t);\n\t}\n\tconst lastInteractionNs = opts.lastInteractionNs;\n\tconst signals = opts.priority ?? {};\n\tconst severityWeights = {\n\t\t...DEFAULT_SEVERITY_WEIGHTS,\n\t\t...signals.severityWeights,\n\t} as Record<string, number>;\n\tconst decayRate = signals.decayRate ?? DEFAULT_DECAY_RATE;\n\tconst effectivenessThreshold = signals.effectivenessThreshold ?? 0.7;\n\tconst effectivenessBoost = signals.effectivenessBoost ?? 15;\n\n\tconst scores = new Map<QueueRoute, Node<number>>();\n\tfor (const [route, topic] of queueTopics) {\n\t\tconst score = node<number>(\n\t\t\t[\n\t\t\t\ttopic.latest as Node<unknown>,\n\t\t\t\tstrategy.entries as Node<unknown>,\n\t\t\t\tlastInteractionNs as Node<unknown>,\n\t\t\t],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst vals = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst item = vals[0] as TriagedItem | undefined;\n\t\t\t\tif (item === undefined) {\n\t\t\t\t\tactions.emit(0);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst baseWeight = severityWeights[item.severity ?? \"medium\"] ?? 40;\n\t\t\t\tconst ageSeconds = (monotonicNs() - (vals[2] as number)) / 1e9;\n\t\t\t\tlet s = baseWeight * Math.exp(-decayRate * Math.max(0, ageSeconds));\n\t\t\t\tconst key = strategyKey(DEFAULT_PRESET_ID, item.rootCause, item.intervention);\n\t\t\t\tconst strat = vals[1] as ReadonlyMap<string, { successRate: number }>;\n\t\t\t\tconst entry = strat?.get(key);\n\t\t\t\tif (entry && entry.successRate >= effectivenessThreshold) {\n\t\t\t\t\ts += effectivenessBoost;\n\t\t\t\t}\n\t\t\t\tactions.emit(s);\n\t\t\t},\n\t\t\t{ name: `priority/${route}`, describeKind: \"derived\" },\n\t\t);\n\t\tscores.set(route, score);\n\t}\n\treturn scores;\n}\n","/**\n * Settled/signal helpers.\n *\n * Moved from extra/sources/settled.ts during cleave A2.\n * `keepalive` is substrate — it lives at `@graphrefly/pure-ts`\n * (`packages/pure-ts/src/extra/sources/_keepalive.ts`), not here.\n */\n\n/**\n * Settled / signal helpers — boundary primitives for converting reactive\n * sources into Promise/AbortSignal endpoints.\n *\n * - {@link firstValueFrom} / {@link firstWhere} — Promise of the first\n * matching DATA.\n * - {@link awaitSettled} — composition over `firstWhere` + reactive\n * `timeout` from `extra/resilience` (lazy import to avoid a\n * resilience → sources cycle).\n * - {@link nodeSignal} — `Node<boolean>` → `AbortSignal` bridge.\n * - {@link reactiveCounter} — capped counter exposed as a `Node<number>`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\n\n/**\n * Converts the first `DATA` on `source` into a Promise; rejects on `ERROR` or `COMPLETE` without data.\n *\n * **Important:** This subscribes and waits for a **future** emission. Data that\n * has already flowed is gone and will not be seen. Call this *before* the upstream\n * emits, or use `source.cache` / `source.status` for already-cached state.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * @param source - Node to read once.\n * @returns Promise of the first value.\n *\n * @example\n * ```ts\n * import { firstValueFrom, of } from \"@graphrefly/graphrefly-ts\";\n *\n * await firstValueFrom(of(42));\n * ```\n *\n * @category extra\n */\nexport function firstValueFrom<T>(source: Node<T>): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet shouldUnsub = false;\n\t\tlet unsub: (() => void) | undefined;\n\t\tunsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tresolve(m[1] as T);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(m[1]);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(new Error(\"completed without DATA\"));\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif (shouldUnsub) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t}\n\t});\n}\n\n/**\n * Wait for the first DATA value from `source` that satisfies `predicate`.\n *\n * Subscribes directly and resolves on the first DATA value where\n * `predicate` returns true. Reactive, no polling. Use in tests and\n * bridging code where you need a single matching value as a Promise.\n *\n * **Important:** This only captures **future** emissions — data that has\n * already flowed through the node is gone. Call this *before* the upstream\n * emits. For already-cached values, use `source.cache` / `source.status`.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * ```ts\n * const val = await firstWhere(strategy.snapshot, snap => snap.size > 0);\n * ```\n *\n * @param source - Upstream node to observe.\n * @param predicate - Returns `true` for the value to resolve on.\n * @param opts - `{ skipCurrent?: boolean }`. When `skipCurrent: true`, any DATA\n * delivered during the synchronous `subscribe()` call (push-on-subscribe §2.2\n * replay of the cached value) is ignored — the promise resolves only on the\n * next future emission. Useful when the caller wants to await the next\n * settlement event after an imperative action (e.g. `run()` minting a new\n * runVersion, where the currently-cached value belongs to the previous run).\n *\n * @category extra\n */\nexport function firstWhere<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: { skipCurrent?: boolean; kick?: () => void },\n): Promise<T> {\n\t// Lock 3.A (Phase 13.6.B): subscribe synchronously inside the function\n\t// body — NOT inside the Promise executor. Subscribing inside the\n\t// executor would defer the subscription past any synchronous `kick()`\n\t// the caller fires after the call returns, race-losing the very wave\n\t// the caller wants to observe.\n\t//\n\t// To bridge sync-subscribe with the async Promise contract, we record\n\t// any settlement that fires *before* the Promise constructor runs, and\n\t// the executor immediately resolves/rejects with the recorded value.\n\t// Settlements after the executor runs go straight through resolve/reject.\n\ttype Pending =\n\t\t| { kind: \"data\"; value: T }\n\t\t| { kind: \"error\"; err: unknown }\n\t\t| { kind: \"complete\" };\n\tlet pending: Pending | undefined;\n\tlet resolveFn: ((value: T) => void) | undefined;\n\tlet rejectFn: ((err: unknown) => void) | undefined;\n\tlet settled = false;\n\tlet shouldUnsub = false;\n\tlet unsub: (() => void) | undefined;\n\tlet inInitialSyncPhase = opts?.skipCurrent === true;\n\n\t// QA P1: every settler short-circuits when `settled === true` so a\n\t// later settle attempt (e.g. `kick()` throwing AFTER it synchronously\n\t// fired matching DATA, OR a `[DATA matched, ERROR]` wave during\n\t// push-on-subscribe) cannot overwrite an earlier `pending` outcome.\n\t// Without this gate, a kick that races sink-callback settlement could\n\t// reject a Promise the user already has resolved-DATA for.\n\tconst settleData = (v: T): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (resolveFn != null) resolveFn(v);\n\t\telse pending = { kind: \"data\", value: v };\n\t};\n\tconst settleError = (err: unknown): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"error\", err };\n\t};\n\tconst settleComplete = (): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tconst err = new Error(\"completed without matching value\");\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"complete\" };\n\t};\n\tconst detach = (): void => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\n\tconst sink: (msgs: Messages) => void = (msgs) => {\n\t\tif (settled) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (settled) return;\n\t\t\t// During the initial sync phase, swallow only cached DATA\n\t\t\t// (push-on-subscribe §2.2). Terminal ERROR / COMPLETE must\n\t\t\t// still reject the promise — otherwise an already-terminated\n\t\t\t// source synchronously delivering `[[ERROR, ...]]` or\n\t\t\t// `[[COMPLETE]]` during `subscribe()` would hang forever\n\t\t\t// under `skipCurrent: true`.\n\t\t\tif (inInitialSyncPhase && m[0] === DATA) continue;\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tconst v = m[1] as T;\n\t\t\t\tif (predicate(v)) {\n\t\t\t\t\tsettleData(v);\n\t\t\t\t\tdetach();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\tsettleError(m[1]);\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\tsettleComplete();\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\tunsub = source.subscribe(sink);\n\tinInitialSyncPhase = false;\n\t// Lock 3.A: fire `kick` AFTER subscribe is in place. With sync\n\t// subscribe + sync kick, the resulting wave reaches `sink` before\n\t// control returns — making subscribe-before-kick ordering structurally\n\t// impossible to misuse.\n\tif (opts?.kick != null && !settled) {\n\t\ttry {\n\t\t\topts.kick();\n\t\t} catch (err) {\n\t\t\tsettleError(err);\n\t\t\tdetach();\n\t\t}\n\t}\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\t// If a settlement landed synchronously before the executor runs,\n\t\t// flush it through immediately.\n\t\tif (pending != null) {\n\t\t\tif (pending.kind === \"data\") resolve(pending.value);\n\t\t\telse if (pending.kind === \"error\") reject(pending.err);\n\t\t\telse reject(new Error(\"completed without matching value\"));\n\t\t\treturn;\n\t\t}\n\t\tresolveFn = resolve;\n\t\trejectFn = reject;\n\t});\n}\n\n/**\n * Await the first non-nullish DATA value from `source`, with optional\n * timeout. Composition sugar over `firstWhere` + reactive timeout.\n *\n * Designed as the CLI/boundary sink for reactive pipelines that end in a\n * nullable node (e.g. `promptNode` — per COMPOSITION-GUIDE §8, it emits\n * `null` before it settles with a real value). Replaces the common pattern\n * `firstValueFrom(filter(source, v => v != null))` with a deadline.\n *\n * - Rejects with `TimeoutError` (from `extra/resilience`) if no matching\n * value arrives within `timeoutMs`. Omit `timeoutMs` for unbounded wait.\n * - `predicate` defaults to `v => v != null`. Pass a custom predicate to\n * gate on a stronger condition (e.g. `v => typeof v === \"string\"`).\n * - Pass `skipCurrent: true` to ignore the currently-cached value delivered\n * synchronously via push-on-subscribe and resolve only on the *next*\n * matching emission. Useful after an imperative action that should produce\n * a fresh settlement (e.g. `run()` minting a new version — the stale\n * cached value from the previous run must not resolve the new caller).\n *\n * ```ts\n * const brief = await awaitSettled(briefNode, { timeoutMs: 120_000 });\n * // or with a predicate:\n * const rich = await awaitSettled(node, {\n * predicate: (v): v is MyShape => typeof v === \"object\" && v != null && \"key\" in v,\n * timeoutMs: 60_000,\n * });\n * // or after kicking off a fresh run:\n * kickOff();\n * const fresh = await awaitSettled(resultNode, { skipCurrent: true });\n * ```\n *\n * Reactive inside, sync propagation — the one async boundary is the\n * returned `Promise<T>` (spec §5.10: async belongs at sources and\n * boundaries, not in the graph).\n *\n * @param source - Upstream node to observe.\n * @param opts - `{ predicate?, timeoutMs?, skipCurrent? }`.\n * @returns Promise that resolves with the first matching value, or rejects on timeout / ERROR / COMPLETE-without-DATA.\n *\n * @category extra\n */\n// Lazy module-cache for the `withTimeout` resilience operator. The dynamic\n// import keeps `settled` free of an eager edge into the resilience family;\n// first call pays the one-shot import, subsequent calls hit cached refs.\nlet _timeoutOp: typeof import(\"../resilience/timeout.js\").withTimeout | undefined;\nlet _nsPerMs: number | undefined;\n\nexport async function awaitSettled<T>(\n\tsource: Node<T>,\n\topts?: {\n\t\tpredicate?: (value: T) => boolean;\n\t\ttimeoutMs?: number;\n\t\tskipCurrent?: boolean;\n\t\t/**\n\t\t * Lock 3.A (Phase 13.6.B): fired AFTER subscribe is in place but\n\t\t * BEFORE the helper's async boundary is exposed to the caller.\n\t\t * Subscribe-before-kick is structurally enforced — the kick's\n\t\t * synchronous wave reaches `sink` before control returns. Replaces\n\t\t * the prior load-bearing-comment pattern (M.20-load-bearing) with\n\t\t * a misuse-impossible API shape.\n\t\t *\n\t\t * Common pattern:\n\t\t * await awaitSettled(node, {\n\t\t * skipCurrent: true,\n\t\t * kick: () => producer.emit(value),\n\t\t * });\n\t\t *\n\t\t * Omit `kick` for external-trigger cases where the wave is fired\n\t\t * by code outside the helper's caller; subscribe still lands\n\t\t * synchronously inside the helper body so the next external wave\n\t\t * is not lost.\n\t\t */\n\t\tkick?: () => void;\n\t},\n): Promise<NonNullable<T>> {\n\tconst predicate = opts?.predicate ?? ((v: T) => v != null);\n\tconst skipCurrent = opts?.skipCurrent;\n\tconst kick = opts?.kick;\n\tif (opts?.timeoutMs == null || opts.timeoutMs <= 0) {\n\t\treturn (await firstWhere(source, predicate, { skipCurrent, kick })) as NonNullable<T>;\n\t}\n\t// Reactive composition: `timeout()` wraps the source as a Node that\n\t// emits ERROR(TimeoutError) on deadline. `firstWhere` then resolves on\n\t// the first matching DATA or rejects on that ERROR. One async boundary\n\t// (the returned Promise), everything inside is sync reactive.\n\tif (_timeoutOp === undefined) {\n\t\tconst [timeoutMod, backoff] = await Promise.all([\n\t\t\timport(\"../resilience/timeout.js\"),\n\t\t\timport(\"../resilience/backoff.js\"),\n\t\t]);\n\t\t_timeoutOp = timeoutMod.withTimeout;\n\t\t_nsPerMs = backoff.NS_PER_MS;\n\t}\n\tconst guarded = _timeoutOp(source, { ns: opts.timeoutMs * (_nsPerMs as number) }).node;\n\treturn (await firstWhere(guarded, predicate, { skipCurrent, kick })) as NonNullable<T>;\n}\n\n/**\n * Converts a reactive `Node<boolean>` into a browser-standard `AbortSignal`\n * that fires when the node settles on `true`. Useful for threading a reactive\n * \"cancel\" flag into any async boundary that accepts a signal (fetch, LLM SDK\n * calls, child-process APIs, timers).\n *\n * **Contract.**\n * - `signal.abort(reason)` fires exactly once, on the first DATA emission with\n * a truthy value. Subsequent emissions are ignored (AbortSignal is\n * single-shot).\n * - Null / `false` / sentinel values are ignored. Push-on-subscribe will\n * check the currently-cached value on subscribe and abort immediately if\n * it's already `true`.\n * - `reason` defaults to `\"cancelled via nodeSignal\"`; pass `opts.reason` to\n * override (`DOMException`, `Error`, or any value accepted by\n * `AbortController.abort`).\n *\n * **Lifecycle.**\n * - Returns a `{signal, dispose}` bundle. Call `dispose()` when you're done\n * with the signal (e.g. in a `finally` after the async operation completes).\n * `dispose()` unsubscribes from the node and is a no-op once the signal has\n * fired.\n * - **Memory note:** without `dispose()` the subscription keeps the reactive\n * node alive for the lifetime of the process. For bridge calls inside a\n * `switchMap` project fn, the switchMap supersede tears the inner subgraph\n * down, which is usually the right lifetime — but still call `dispose()`\n * from the caller's `finally` for clarity.\n *\n * @example\n * ```ts\n * const aborted = state(false);\n * const { signal, dispose } = nodeSignal(aborted);\n * try {\n * const resp = await adapter.invoke(msgs, { signal });\n * return resp;\n * } finally {\n * dispose();\n * }\n * ```\n *\n * @category extra\n */\nexport function nodeSignal(\n\tsource: Node<boolean>,\n\topts?: { reason?: unknown },\n): { signal: AbortSignal; dispose: () => void } {\n\tconst ctrl = new AbortController();\n\tconst reason = opts?.reason ?? new Error(\"cancelled via nodeSignal\");\n\tlet unsub: (() => void) | undefined;\n\tlet shouldUnsub = false;\n\tconst done = () => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\tunsub = source.subscribe((msgs) => {\n\t\tif (ctrl.signal.aborted) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA && m[1] === true) {\n\t\t\t\tctrl.abort(reason);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\t// Treat an ERROR on the abort source as a cancel signal too —\n\t\t\t\t// a broken control channel should fail closed, not leak the\n\t\t\t\t// in-flight call. Use the error as the abort reason.\n\t\t\t\tctrl.abort(m[1]);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t// Source completed without aborting — no-op. `done()` already\n\t\t\t\t// released the subscription here, so a later `dispose()` call\n\t\t\t\t// from the caller is a no-op (safe / idempotent).\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\treturn {\n\t\tsignal: ctrl.signal,\n\t\tdispose: () => {\n\t\t\tif (unsub) {\n\t\t\t\tunsub();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// reactiveCounter\n// ---------------------------------------------------------------------------\n\n/** Bundle returned by {@link reactiveCounter}. */\nexport type ReactiveCounterBundle = {\n\t/** Reactive node holding the current count. */\n\treadonly node: Node<number>;\n\t/** Increment by 1. Returns `false` if cap would be exceeded. */\n\tincrement(): boolean;\n\t/** Current count (synchronous read). */\n\tget(): number;\n\t/** Whether the counter has reached its cap. */\n\tatCap(): boolean;\n};\n\n/**\n * Reactive counter with a cap — the building block for circuit breakers.\n *\n * Wraps a `state(0)` node with `increment()` that respects a maximum.\n * The `node` is subscribable and composable like any reactive node. When\n * the cap is reached, `increment()` returns `false`.\n *\n * ```ts\n * const retries = reactiveCounter(10);\n * retries.increment(); // true — count is now 1\n * retries.node.subscribe(...); // reactive updates\n * retries.atCap(); // false\n * ```\n *\n * @param cap - Maximum value (inclusive). 0 = no increments allowed.\n * @category extra\n */\nexport function reactiveCounter(cap: number): ReactiveCounterBundle {\n\tconst counter = node([], { initial: 0 });\n\treturn {\n\t\tnode: counter,\n\t\tincrement() {\n\t\t\tconst current = counter.cache ?? 0;\n\t\t\tif (current >= cap) return false;\n\t\t\tcounter.down([[DIRTY], [DATA, current + 1]]);\n\t\t\treturn true;\n\t\t},\n\t\tget() {\n\t\t\treturn counter.cache ?? 0;\n\t\t},\n\t\tatCap() {\n\t\t\treturn (counter.cache ?? 0) >= cap;\n\t\t},\n\t};\n}\n","/**\n * Retry — re-attempt a node on terminal failure.\n *\n * Two modes selected by the type of `input`:\n * - **Source mode** (`Node<T>`): resubscribes the same node after each ERROR.\n * Upstream must be `resubscribable: true` or retries are silent no-ops.\n * - **Factory mode** (`() => Node<T>`): builds a fresh node per attempt.\n *\n * Shared with `circuitBreaker` / `rateLimiter`: `NodeOrValue<RetryOptions>`\n * lets callers swap retry config reactively (re-validates on each attempt).\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Message,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n} from \"@graphrefly/pure-ts/core\";\nimport { coerceDelayNs, isNode, msgVal, type NodeOrValue, operatorOpts } from \"./_internal.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport type { StatusValue } from \"./status.js\";\n\n/**\n * Lifecycle-shaped state companion emitted by {@link retry} (DS-13.5.B,\n * locked 2026-05-01). Tracks the retry state machine's current status,\n * the attempt counter, and the last scheduled delay (null before the\n * first retry).\n *\n * @category extra/resilience\n */\nexport interface RetryState {\n\tstatus: StatusValue;\n\tattempt: number;\n\tlastDelay_ns: number | null;\n}\n\n/**\n * Bundle returned by {@link retry}: the retry-wrapped output node and its\n * lifecycle state companion. Pre-1.0 break vs the prior `Node<T>` return.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `retryState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `retryState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `retryState`, including\n * `publish(\"pending\")` resets that can clobber an in-flight machine's\n * `running`/`paused` state. Don't fan out `node` to multiple subscribers\n * and rely on `retryState` accuracy unless you use\n * {@link keepalive} / `share`-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface RetryBundle<T> {\n\tnode: Node<T>;\n\tretryState: Node<RetryState>;\n}\n\nexport type RetryOptions = {\n\t/**\n\t * Max retry attempts after each terminal `ERROR` (not counting the first failure).\n\t *\n\t * **Required when `backoff` is set.** Pass `Infinity` to opt in to unbounded retries\n\t * — the explicit value rules out the silent-infinite-budget footgun (a flaky provider\n\t * + exponential backoff + omitted `count` would previously default to ~2.1B retries).\n\t */\n\tcount?: number;\n\t/** Delay between attempts; strategies use **nanoseconds**. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n\t/**\n\t * Caller-supplied metadata merged into the produced node's `meta` (Tier 5.2\n\t * D8 widening). Use {@link domainMeta} to tag the layer for `describe()`\n\t * grouping. The primitive's `factoryTag(\"retry\", …)` always wins against\n\t * caller keys.\n\t */\n\tmeta?: Record<string, unknown>;\n};\n\n/** Factory-mode-only options. `initial` seeds the outer node's cache before the first attempt. */\nexport type RetryFactoryOptions<T> = RetryOptions & {\n\t/** Initial cache value for the outer node before the factory runs the first time. */\n\tinitial?: T;\n};\n\n/**\n * Resolved retry config shared by source-mode and factory-mode wrappers.\n * Centralises the unbounded-retry footgun guard and strategy resolution.\n */\ntype ResolvedRetryConfig = {\n\tmaxRetries: number;\n\tstrategy: BackoffStrategy | null;\n};\n\nfunction resolveRetryConfig(opts?: RetryOptions): ResolvedRetryConfig {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\n\t// Unbounded-retry footgun fix: if `backoff` is set without explicit `count`,\n\t// throw at construction time. Caller must opt in to `Infinity` for unbounded.\n\tif (backoffOpt !== undefined && count === undefined) {\n\t\tthrow new RangeError(\n\t\t\t\"retry({ backoff }) requires explicit count to prevent unbounded retries; pass { count: <n>, backoff: ... }\",\n\t\t);\n\t}\n\n\tconst maxRetries = count !== undefined ? count : 0;\n\tif (maxRetries < 0) throw new RangeError(\"retry count must be >= 0\");\n\n\tconst strategy: BackoffStrategy | null =\n\t\tbackoffOpt === undefined\n\t\t\t? null\n\t\t\t: typeof backoffOpt === \"string\"\n\t\t\t\t? resolveBackoffPreset(backoffOpt)\n\t\t\t\t: backoffOpt;\n\n\treturn { maxRetries, strategy };\n}\n\nfunction retryFactoryArgs(opts?: RetryOptions): Record<string, unknown> | undefined {\n\tconst args: Record<string, unknown> = {};\n\tif (opts?.count !== undefined) args.count = opts.count;\n\tif (typeof opts?.backoff === \"string\") args.backoff = opts.backoff;\n\treturn Object.keys(args).length > 0 ? args : undefined;\n}\n\n/**\n * Shared retry state machine. Both `_retrySource` and `_retryFactory` thin-wrap this:\n * the only per-mode logic is supplied via `acquireSource` (returns a fresh `Node<T>`\n * per attempt — for source-mode it just returns the captured `Node`; for factory-mode\n * it calls the user factory and forwards synchronous throws into the same retry path).\n *\n * **Reactive cfg (Tier 6.5 3.2.2, 2026-04-29).** `getCfg` is invoked at\n * every decision point (`scheduleRetryOrFinish` count + strategy reads)\n * so option swaps mid-flight take effect at the next attempt boundary\n * per the locked semantic rule: \"next attempt fails immediately if\n * already exhausted under new count; `backoff` swap takes effect at next\n * retry's delay calculation.\"\n */\nfunction _runRetryStateMachine<T>(\n\tgetCfg: () => ResolvedRetryConfig,\n\tacquireSource: () => Node<T>,\n\ta: { emit: (v: T) => void; down: (msgs: Message[]) => void },\n\temitState?: (next: RetryState) => void,\n): () => void {\n\tlet attempt = 0;\n\tlet stopped = false;\n\tlet prevDelay: number | null = null;\n\tlet unsub: (() => void) | undefined;\n\tconst timer = new ResettableTimer();\n\tconst publish = (status: StatusValue): void => {\n\t\temitState?.({ status, attempt, lastDelay_ns: prevDelay });\n\t};\n\tpublish(\"pending\");\n\n\tfunction disconnectUpstream(): void {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\tif (stopped) return;\n\t\tconst cfg = getCfg();\n\t\tif (attempt >= cfg.maxRetries) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tconst raw = cfg.strategy === null ? 0 : cfg.strategy(attempt, err, prevDelay);\n\t\t// null from strategy = \"stop retrying\" (e.g. withMaxAttempts cap reached)\n\t\tif (raw === null || raw === undefined) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\t// A misbehaving strategy (returns NaN / non-finite / negative) MUST NOT\n\t\t// escape into the upstream drain. Treat it like `strategy === null`\n\t\t// (stop retrying) and emit the original error — the strategy bug is a\n\t\t// separate concern the user can inspect via the emitted error's stack.\n\t\tlet delayNs: number;\n\t\ttry {\n\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t} catch {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tprevDelay = delayNs;\n\t\tattempt += 1;\n\t\tdisconnectUpstream();\n\t\tpublish(\"paused\");\n\t\t// `Math.max(1, …)` floor: every backoff schedule floors at 1ms even when\n\t\t// the strategy returns 0ns. Avoids 0-delay re-entrancy on the active\n\t\t// stack frame (which would risk stack overflow on a tight ERROR loop).\n\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\ttimer.start(delayMs, () => {\n\t\t\tif (stopped) return;\n\t\t\tconnect();\n\t\t});\n\t}\n\n\tfunction connect(): void {\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tlet src: Node<T>;\n\t\ttry {\n\t\t\tsrc = acquireSource();\n\t\t} catch (err) {\n\t\t\tscheduleRetryOrFinish(err);\n\t\t\treturn;\n\t\t}\n\t\tpublish(\"running\");\n\t\tunsub = src.subscribe((msgs) => {\n\t\t\tif (stopped) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst t = m[0];\n\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\telse if (t === DATA) {\n\t\t\t\t\tattempt = 0;\n\t\t\t\t\tprevDelay = null;\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\tpublish(\"running\");\n\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t// DF2 (2026-04-29): set `stopped = true` BEFORE\n\t\t\t\t\t// `disconnectUpstream()` so a re-entrant ERROR delivered\n\t\t\t\t\t// in the same wave (after disconnect runs but before the\n\t\t\t\t\t// teardown closure fires `stopped = true`) hits the\n\t\t\t\t\t// `if (stopped) return` guard at line 159 and cannot\n\t\t\t\t\t// schedule a new retry timer.\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\tpublish(\"completed\");\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\treturn;\n\t\t\t\t} else a.down([m]);\n\t\t\t}\n\t\t});\n\t}\n\n\tconnect();\n\n\treturn () => {\n\t\tconst wasStopped = stopped;\n\t\tstopped = true;\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tif (!wasStopped) publish(\"cancelled\");\n\t};\n}\n\n/**\n * Retry operator — two modes selected by the type of `input`:\n *\n * **Source mode** (`input: Node<T>`): resubscribes to the same node after each terminal\n * `ERROR`. The upstream should use `resubscribable: true` if it must emit again after `ERROR`.\n *\n * **Factory mode** (`input: () => Node<T>`): invokes the factory to build a fresh `Node<T>`\n * on every connect / reconnect. Ideal for producers that capture per-attempt resources\n * (sockets, clients, file handles) that become unusable after an error. Synchronous\n * exceptions thrown by the factory are treated as terminal ERROR and run through the\n * same retry pipeline as inner-node ERROR.\n *\n * @param input - Upstream node or factory that returns a fresh node per attempt.\n * @param opts - `count` caps attempts (**required when `backoff` is set**; pass `Infinity` to opt in to unbounded); `backoff` supplies delay in **nanoseconds** (or a preset name); `initial` seeds the outer node cache (factory mode only).\n * @returns Node that retries on error.\n *\n * @throws {RangeError} when `backoff` is provided without an explicit `count` (unbounded-retry footgun guard) or when `count < 0`.\n *\n * @remarks\n * **Protocol:** Forwards unknown message tuples unchanged; handles `DIRTY`, `DATA`, `RESOLVED`, `COMPLETE`, `ERROR`.\n *\n * **Backoff floor:** every scheduled delay is floored at 1ms via `Math.max(1, delayNs / NS_PER_MS)` even when the strategy returns 0ns. This avoids 0-delay re-entrancy on the active stack frame on a tight ERROR loop. Strategies that return `null`/`undefined` stop retrying immediately and forward the original error.\n *\n * @example\n * ```ts\n * // Source mode — resubscribe the same node:\n * import { ERROR, NS_PER_SEC, producer, retry, constant } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = producer(\n * (a) => { a.down([[ERROR, new Error(\"x\")]]); },\n * { resubscribable: true },\n * );\n * const out = retry(src, { count: 2, backoff: constant(0.25 * NS_PER_SEC) });\n *\n * // Factory mode — fresh node per attempt (e.g. reconnecting WebSocket):\n * import { NS_PER_SEC, exponential, retry, fromWebSocket } from \"@graphrefly/graphrefly-ts\";\n *\n * const connected$ = retry(\n * () => fromWebSocket(new WebSocket(\"wss://example/stream\")),\n * { count: 10, backoff: exponential({ baseNs: 1 * NS_PER_SEC }) },\n * );\n * ```\n *\n * @category extra\n */\nexport function retry<T>(input: Node<T>, opts?: NodeOrValue<RetryOptions>): RetryBundle<T>;\nexport function retry<T>(\n\tinput: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n): RetryBundle<T>;\nexport function retry<T>(\n\tinput: Node<T> | (() => Node<T>),\n\topts?: NodeOrValue<RetryOptions | RetryFactoryOptions<T>>,\n): RetryBundle<T> {\n\tconst retryState = node<RetryState>([], {\n\t\tname: \"retryState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\", attempt: 0, lastDelay_ns: null },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\tconst emit = (s: RetryState): void => {\n\t\tretryState.down([[DIRTY], [DATA, s]]);\n\t};\n\tif (typeof input === \"function\") {\n\t\treturn {\n\t\t\tnode: _retryFactory(input, opts as NodeOrValue<RetryFactoryOptions<T>> | undefined, emit),\n\t\t\tretryState,\n\t\t};\n\t}\n\treturn {\n\t\tnode: _retrySource(input, opts as NodeOrValue<RetryOptions> | undefined, emit),\n\t\tretryState,\n\t};\n}\n\n// DS-13.5.B helper: like `resolveReactiveOption` but shallow-merges each\n// reactive emit over the prior opts and treats empty `{}` as a no-op\n// (per the locked cross-cutting rule). Static-form arg returns the value\n// as-is and never subscribes.\nfunction makeMergedOptsMirror<R extends Record<string, unknown>>(\n\targ: NodeOrValue<R> | undefined,\n): { current: () => R | undefined; unsub: () => void } {\n\tif (arg === undefined) {\n\t\treturn { current: () => undefined, unsub: () => undefined };\n\t}\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg as R, unsub: () => undefined };\n\t}\n\tconst optsNode = arg as Node<R>;\n\tlet merged: R | undefined = (optsNode.cache as R | undefined) ?? undefined;\n\tconst unsub = optsNode.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] !== DATA) continue;\n\t\t\tconst next = m[1] as R | undefined;\n\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\tif (Object.keys(next).length === 0) continue; // empty {} no-op\n\t\t\tmerged = { ...(merged ?? ({} as R)), ...next } as R;\n\t\t}\n\t});\n\treturn { current: () => merged, unsub };\n}\n\n// DF6 (2026-04-29): once-per-source dedup for the source-mode-retry warn.\n// Mirrors the `_bumpCursorWarned` pattern in `extra/mutation/index.ts`.\nconst _retrySourceNonResubscribableWarned = new WeakSet<Node<unknown>>();\n\nfunction _retrySource<T>(\n\tsource: Node<T>,\n\topts?: NodeOrValue<RetryOptions>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\t// Source-mode retry re-subscribes to the SAME source node after each\n\t// terminal ERROR. If the upstream was constructed with the default\n\t// `resubscribable: false`, the second subscribe-after-terminal is a\n\t// silent no-op and retries effectively never re-deliver. Surface\n\t// once-per-source so misconfigurations fail loud without log spam.\n\tconst sourceWithFlag = source as unknown as { _resubscribable?: boolean };\n\tif (\n\t\tsourceWithFlag._resubscribable === false &&\n\t\t!_retrySourceNonResubscribableWarned.has(source)\n\t) {\n\t\t_retrySourceNonResubscribableWarned.add(source);\n\t\tconsole.warn(\n\t\t\t\"retry(source, opts): source-mode requires `resubscribable: true` on the upstream \" +\n\t\t\t\t\"node. Retries will be silent no-ops after the first ERROR. Either pass \" +\n\t\t\t\t\"`resubscribable: true` to the source factory, OR use factory-mode retry \" +\n\t\t\t\t\"`retry(() => buildSource(), opts)` so each attempt builds a fresh node.\",\n\t\t);\n\t}\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryOptions | undefined);\n\t// Eager validation for static-form opts (preserves construction-time\n\t// \"backoff without count\" RangeError). Reactive-form opts re-validate\n\t// per `getCfg()` call inside the state machine.\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryOptions>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, () => source, a, emitState);\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tinner();\n\t\t\t\t\tmerged.unsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n\nfunction _retryFactory<T>(\n\tfactory: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryFactoryOptions<T> | undefined);\n\t// Eager validation for static-form opts (Tier 3.1 footgun preservation).\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryFactoryOptions<T>>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, factory, a, emitState);\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tinner();\n\t\t\t\t\tmerged.unsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: staticOpts?.initial as T | undefined,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n","/**\n * `promptNode` — universal LLM transform as a reactive derived node.\n *\n * The shape: `deps → messagesNode (derived) → switchMap → response (producer) → output`.\n * Each upstream wave is one LLM call; superseding waves cancel the in-flight\n * call via the abort signal threaded through `nodeSignal(opts.abort)`.\n *\n * The producer-shape on the inner is load-bearing: it emits exactly one DATA\n * + COMPLETE per wave, so the outer switchMap sees one DATA per wave (matches\n * the `HarnessExecutor` contract). A `node([response], (batchData, actions, ctx) => {\n * const data = ...; actions.emit(parse(data[0]));\n * }, { describeKind: \"derived\" })` would have its\n * own first-run / push-on-subscribe semantics that can leak a transient null\n * before the real response arrives — observed and reverted in an earlier\n * attempt; see SESSION-ai-harness-module-review.md line 3654 for context.\n * Locked as path (b) producer-based by Session C (2026-04-27); inner-node\n * naming aligned to `prompt_node::response` per the C+D widening (2026-04-30).\n *\n * **Retry / replay-cache.** Stack middleware on the adapter:\n *\n * ```ts\n * import { withRetry, withReplayCache } from \"@graphrefly/graphrefly/utils/ai\";\n *\n * const adapter = withRetry(\n * withReplayCache(baseAdapter, { keyFn: (ctx) => ctx.messages[0].content }),\n * { count: 3, backoff: 200 },\n * );\n * const result = promptNode(adapter, [input], (q) => q);\n * ```\n *\n * `promptNode` no longer ships `retries` / `cache` options — they duplicated\n * middleware already at the adapter layer.\n *\n * **Cross-wave cache (COMPOSITION-GUIDE §32).** The switchMap output cache\n * survives across new outer DATAs — `promptNode`'s cached value persists\n * until the next wave fully resolves. Consumers that need to distinguish\n * \"fresh value for THIS session\" from \"stale cache from a prior session\"\n * (e.g. `agentLoop` resetting on new `run()`) must add a `node([])` mirror\n * at their session boundary and depend on the mirror, not the `promptNode`\n * output directly. `promptNode` itself stays primitive — it does not\n * embed a state-mirror.\n *\n * @module\n */\n\nimport { COMPLETE, DATA, ERROR, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { fromAny, type NodeInput, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { nodeSignal } from \"../../../base/sources/settled.js\";\nimport { aiMeta, stripFences } from \"../_internal.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMInvokeOptions,\n\tLLMResponse,\n\tToolDefinition,\n} from \"../adapters/core/types.js\";\n\nexport type PromptNodeOptions = {\n\tname?: string;\n\tmodel?: string;\n\ttemperature?: number;\n\tmaxTokens?: number;\n\t/**\n\t * Output format:\n\t * - `\"text\"` (default) — emit the response content as a string.\n\t * - `\"json\"` — `JSON.parse` the content (markdown fences stripped).\n\t * - `\"raw\"` — emit the full {@link LLMResponse} object (subsumes the\n\t * pre-Tier-2.3 `fromLLM` shape; use this when you need `usage` /\n\t * `toolCalls` / `finishReason` alongside `content`).\n\t */\n\tformat?: \"text\" | \"json\" | \"raw\";\n\t/**\n\t * Reactive tool definitions forwarded to the adapter. Pair with\n\t * `format: \"raw\"` (or read `toolCalls` from a downstream parser) when\n\t * tool-calling is in scope.\n\t *\n\t * **Reactive declared edge** (DF12, Tier 7): `tools` is a `Node` so the\n\t * tools list participates in `describe()` topology and `explain()` causal\n\t * chains. The tools Node is added to `messagesNode`'s declared deps —\n\t * tools changes re-invoke the LLM (treated as a new call envelope).\n\t * Wrap with `distinctUntilChanged` upstream if your tool selector emits\n\t * noisy duplicates that would otherwise spam the adapter. See\n\t * COMPOSITION-GUIDE §31 (Dynamic tool selection) for the canonical\n\t * `toolSelector` pattern that produces this Node.\n\t *\n\t * **Activation note:** since `tools` is a real declared dep, `messagesNode`\n\t * waits for the tools Node to DATA at least once before firing\n\t * (push-on-subscribe SENTINEL gate). Pass a `node<ToolDefinition[]>([], { initial: [] })`\n\t * if you want immediate activation with no tools, or the latest published\n\t * `toolSelector.tools` Node.\n\t */\n\ttools?: Node<readonly ToolDefinition[]>;\n\t/**\n\t * Optional system prompt. Forwarded via `opts.systemPrompt` to the adapter\n\t * only — never pushed as a `{role:\"system\"}` message (avoiding the\n\t * double-send class of bug where adapters that normalize both shapes end\n\t * up with two system entries).\n\t */\n\tsystemPrompt?: string;\n\t/**\n\t * Optional reactive abort signal. When the node emits `true`, the in-flight\n\t * `adapter.invoke()` call is cancelled via `AbortController.abort()`.\n\t * Threaded through `nodeSignal(abort)` — a one-shot bridge. Useful inside\n\t * agent state machines where a separate `aborted` state should cancel the\n\t * current LLM call without superseding via switchMap.\n\t */\n\tabort?: Node<boolean>;\n\tmeta?: Record<string, unknown>;\n};\n\n/** Extract text content from an LLM response, handling various response shapes. */\nfunction extractContent(resp: unknown): string {\n\tif (resp != null && typeof resp === \"object\" && \"content\" in resp) {\n\t\treturn String((resp as LLMResponse).content);\n\t}\n\tif (typeof resp === \"string\") return resp;\n\treturn String(resp);\n}\n\nfunction previewContent(text: string, max = 200): string {\n\tif (text.length <= max) return text;\n\treturn `${text.slice(0, max)}…`;\n}\n\n/**\n * Universal LLM transform: wraps a prompt template + model adapter into a reactive derived node.\n * Re-invokes the LLM whenever any dep changes. Suitable for triage, QA, hypothesis, parity, etc.\n *\n * **Topology** (visible in `describe()`):\n * ```\n * <deps...>, [tools?] → <name>::messages (derived, meta.ai = prompt_node::messages)\n * <name>::messages → <name>::output (switchMap product, meta.ai = prompt_node::output)\n * per-wave inner: <name>::response (producer, meta.ai = prompt_node::response)\n * ```\n * When `opts.tools` is supplied, the tools `Node` is appended to\n * `messagesNode`'s declared deps so it appears as a real edge in `describe()`\n * / `explain()` (DF12, Tier 7).\n *\n * **No-input semantics** (matches the codebase-wide SENTINEL convention):\n * - **Initial no-input** (no real input has ever arrived) — emits nothing.\n * Outer cache stays `undefined`; `subscribe` consumers see no DATA event.\n * Use this to keep downstream gating clean: a `withLatestFrom`-paired\n * trigger won't fire until the LLM has actually produced something.\n * - **Mid-flow no-input** (input dropped to nullish after at least one\n * real LLM call) — emits `null` as a domain \"input went away\" signal.\n * Downstream consumers can distinguish \"haven't started\" from \"input\n * gone.\"\n *\n * **Retries / caching:** stack `withRetry` / `withReplayCache` middleware on the\n * `adapter` argument — `promptNode` no longer ships its own duplicated retry /\n * cache loops (pre-1.0 cleanup, see review session 1).\n *\n * @param adapter - LLM adapter (provider-agnostic). Wrap with `withRetry` /\n * `withReplayCache` middleware for transient-error tolerance\n * or replay caching.\n * @param deps - Input nodes whose values feed the prompt.\n * @param prompt - Static string or template function receiving dep values.\n * @param opts - Optional configuration.\n * @returns `Node` emitting LLM responses (string or parsed JSON).\n */\n// Overload 1: `format: \"raw\"` constrains the emit type to `LLMResponse | null`\n// (the full adapter response, with `usage` / `toolCalls` / `finishReason`).\n// Subsumes the pre-Tier-2.3 `fromLLM` shape.\nexport function promptNode(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts: PromptNodeOptions & { format: \"raw\" },\n): Node<LLMResponse | null>;\n// Overload 2: `format: \"text\" | \"json\"` (default text) — emit-type is the\n// caller's `T` (defaults to `string`). For `\"json\"` callers typically pass\n// the parsed shape (e.g. `promptNode<MyShape>(...)`).\nexport function promptNode<T = string>(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts?: Omit<PromptNodeOptions, \"format\"> & { format?: \"text\" | \"json\" },\n): Node<T | null>;\nexport function promptNode<T = string>(\n\tadapter: LLMAdapter,\n\tdeps: readonly Node<unknown>[],\n\tprompt: string | ((...depValues: unknown[]) => string),\n\topts?: PromptNodeOptions,\n): Node<T | null> {\n\tconst format = opts?.format ?? \"text\";\n\tconst baseName = opts?.name ?? \"prompt_node\";\n\n\t// qa A8: tools without `format: \"raw\"` is a footgun — adapter receives\n\t// the tool definitions and may produce `toolCalls`, but the emit path\n\t// only extracts `content`. Warn at construction; downstream parsers\n\t// reading `toolCalls` from a custom `format: \"raw\"` consumer pattern\n\t// can ignore by setting `format: \"raw\"` (intent now matches behavior).\n\tif (opts?.tools !== undefined && format !== \"raw\") {\n\t\tconsole.warn(\n\t\t\t\"promptNode: `tools` is set but `format !== 'raw'`. \" +\n\t\t\t\t\"Tool calls in the response will be silently dropped — set \" +\n\t\t\t\t\"`format: 'raw'` to receive the full LLMResponse with `toolCalls`.\",\n\t\t);\n\t}\n\n\t// SENTINEL semantics rely on the universal first-run gate + standard\n\t// prevData semantics (undefined = SENTINEL, any other value = DATA seen):\n\t// - **Initial no-input** (no dep has ever DATA'd, so prevData is\n\t// undefined across the board): the `derived`'s first-run gate blocks\n\t// `messagesNode`'s fn entirely. It never emits, switchMap never\n\t// fires, outer cache stays `undefined`.\n\t// - **Mid-flow no-input** (deps previously DATA'd then went nullish):\n\t// fn runs, returns `[]`, switchMap dispatches the `node([], { initial: null })`\n\t// branch → outer emits `null` as the domain \"input went away\" signal.\n\t// No `initial: []` and no closure flag — `prevData === undefined` is\n\t// already the sentinel marker, and the gate already enforces \"don't fire\n\t// fn until every dep has DATA'd at least once.\"\n\t//\n\t// DF12: when `opts.tools` is a Node, it's appended to `messagesNode`'s\n\t// declared deps. The fn slices values into user-deps + tools, and emits\n\t// an envelope `{ messages, tools }` so switchMap's per-wave inner can\n\t// read the latest tools via the reactive edge instead of a closure.\n\ttype Envelope = {\n\t\tmessages: readonly ChatMessage[];\n\t\ttools: readonly ToolDefinition[] | undefined;\n\t};\n\tconst userDepsLength = deps.length;\n\tconst allDeps: readonly Node<unknown>[] =\n\t\topts?.tools !== undefined ? [...deps, opts.tools as Node<unknown>] : deps;\n\tconst messagesNode = node<Envelope>(\n\t\tallDeps as Node<unknown>[],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst userValues = data.slice(0, userDepsLength);\n\t\t\tconst toolsValue =\n\t\t\t\topts?.tools !== undefined\n\t\t\t\t\t? (data[userDepsLength] as readonly ToolDefinition[] | undefined)\n\t\t\t\t\t: undefined;\n\t\t\t// Dep-level null guard (composition guide §8): if any USER dep is\n\t\t\t// nullish, emit empty messages → switchMap emits null (mid-flow\n\t\t\t// drop-out). The tools dep can legitimately be empty `[]`; only\n\t\t\t// user deps gate the call.\n\t\t\tif (userValues.some((v) => v == null)) {\n\t\t\t\tactions.emit({ messages: [], tools: toolsValue });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst text = typeof prompt === \"string\" ? prompt : prompt(...userValues);\n\t\t\tif (!text) {\n\t\t\t\tactions.emit({ messages: [], tools: toolsValue });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// systemPrompt forwarded through invoke opts only (no double-send).\n\t\t\tactions.emit({\n\t\t\t\tmessages: [{ role: \"user\" as const, content: text }],\n\t\t\t\ttools: toolsValue,\n\t\t\t});\n\t\t},\n\t\t{\n\t\t\tname: `${baseName}::messages`,\n\t\t\tmeta: aiMeta(\"prompt_node::messages\"),\n\t\t},\n\t);\n\n\tconst result = switchMap<Envelope, T | null>(\n\t\tmessagesNode,\n\t\t(envelope) => {\n\t\t\tconst { messages: msgs, tools } = envelope;\n\t\t\tif (!msgs || msgs.length === 0) {\n\t\t\t\treturn node<T | null>([], { initial: null }) as NodeInput<T | null>;\n\t\t\t}\n\n\t\t\t// Producer ensures exactly one DATA + COMPLETE per wave; switchMap\n\t\t\t// sees one DATA, the harness's \"one emission per wave\" contract is\n\t\t\t// honored. Earlier attempts using a derived node leaked\n\t\t\t// transient nulls via the derived's first-run gate.\n\t\t\treturn node<T | null>(\n\t\t\t\t(_data, actions) => {\n\t\t\t\t\tlet done = false;\n\t\t\t\t\tlet cancelled = false;\n\t\t\t\t\tlet abortDispose: (() => void) | undefined;\n\n\t\t\t\t\tconst invokeOpts: LLMInvokeOptions = {\n\t\t\t\t\t\tmodel: opts?.model,\n\t\t\t\t\t\ttemperature: opts?.temperature,\n\t\t\t\t\t\tmaxTokens: opts?.maxTokens,\n\t\t\t\t\t\tsystemPrompt: opts?.systemPrompt,\n\t\t\t\t\t\t...(tools !== undefined ? { tools } : {}),\n\t\t\t\t\t};\n\t\t\t\t\tif (opts?.abort) {\n\t\t\t\t\t\tconst sig = nodeSignal(opts.abort);\n\t\t\t\t\t\tinvokeOpts.signal = sig.signal;\n\t\t\t\t\t\tabortDispose = sig.dispose;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet invokeResult: NodeInput<LLMResponse>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tinvokeResult = adapter.invoke(msgs, invokeOpts);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\tactions.down([[ERROR, err]]);\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\tconst callNode = fromAny(invokeResult);\n\n\t\t\t\t\tconst sub = callNode.subscribe((batch) => {\n\t\t\t\t\t\tif (cancelled || done) return;\n\t\t\t\t\t\tfor (const msg of batch) {\n\t\t\t\t\t\t\t// F-11: re-check `cancelled` (and `done`) at the top of\n\t\t\t\t\t\t\t// each per-message iteration so a teardown / abort that\n\t\t\t\t\t\t\t// fires synchronously between messages stops processing\n\t\t\t\t\t\t\t// further batched messages immediately.\n\t\t\t\t\t\t\tif (cancelled || done) return;\n\t\t\t\t\t\t\tif (msg[0] === DATA) {\n\t\t\t\t\t\t\t\tconst resp = msg[1] as LLMResponse;\n\t\t\t\t\t\t\t\t// `format: \"raw\"` bypasses parsing — emit the full\n\t\t\t\t\t\t\t\t// LLMResponse object (subsumes the pre-Tier-2.3 `fromLLM`\n\t\t\t\t\t\t\t\t// output shape).\n\t\t\t\t\t\t\t\tif (format === \"raw\") {\n\t\t\t\t\t\t\t\t\tactions.emit(resp as unknown as T);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t// F-12: cache the extracted content once on the\n\t\t\t\t\t\t\t\t\t// parse-failure path so we don't call\n\t\t\t\t\t\t\t\t\t// `extractContent(resp)` twice (once for parsing,\n\t\t\t\t\t\t\t\t\t// once for the error-message preview).\n\t\t\t\t\t\t\t\t\tlet content: string;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tcontent = extractContent(resp);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\t// extractContent itself failed — propagate as\n\t\t\t\t\t\t\t\t\t\t// an ERROR with a generic raw-extraction message.\n\t\t\t\t\t\t\t\t\t\tconst wrapped = new Error(\n\t\t\t\t\t\t\t\t\t\t\t`promptNode: failed to extract content from LLM response: ${\n\t\t\t\t\t\t\t\t\t\t\t\t(err as Error).message\n\t\t\t\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal-error\n\t\t\t\t\t\t\t\t\t\t// branches so we don't retain the AbortController\n\t\t\t\t\t\t\t\t\t\t// after the wave terminates. Idempotent.\n\t\t\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\t\t\tactions.down([[ERROR, wrapped]]);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tconst parsed: T =\n\t\t\t\t\t\t\t\t\t\t\tformat === \"json\"\n\t\t\t\t\t\t\t\t\t\t\t\t? (JSON.parse(stripFences(content)) as T)\n\t\t\t\t\t\t\t\t\t\t\t\t: (content as unknown as T);\n\t\t\t\t\t\t\t\t\t\tactions.emit(parsed);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\tconst wrapped = new Error(\n\t\t\t\t\t\t\t\t\t\t\t`promptNode: failed to parse LLM response as JSON: ${\n\t\t\t\t\t\t\t\t\t\t\t\t(err as Error).message\n\t\t\t\t\t\t\t\t\t\t\t}\\n Raw content (first 200 chars): ${previewContent(content)}`,\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t// F-7: dispose abort hook on parse-error\n\t\t\t\t\t\t\t\t\t\t// terminal branch.\n\t\t\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\t\t\tactions.down([[ERROR, wrapped]]);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (msg[0] === ERROR) {\n\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal ERROR branch.\n\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\tactions.down([[ERROR, msg[1]]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} else if (msg[0] === COMPLETE) {\n\t\t\t\t\t\t\t\t// Adapter completed — propagate. emit() above already\n\t\t\t\t\t\t\t\t// queued the parsed value so the wave carries DATA + COMPLETE.\n\t\t\t\t\t\t\t\t// F-7: dispose abort hook on terminal COMPLETE branch.\n\t\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t\t\tdone = true;\n\t\t\t\t\t\t\t\tactions.down([[COMPLETE]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// Spec §1.3.6 forward-unknown — DIRTY/RESOLVED/INVALIDATE/\n\t\t\t\t\t\t\t\t// PAUSE/RESUME etc. should propagate so downstream caches /\n\t\t\t\t\t\t\t\t// flow-control hooks aren't starved. Re-typed `as never`\n\t\t\t\t\t\t\t\t// because the call's NodeInput<LLMResponse> message tuple\n\t\t\t\t\t\t\t\t// is wider than the unbound `T` projection.\n\t\t\t\t\t\t\t\tactions.down([msg as never]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\tcancelled = true;\n\t\t\t\t\t\t\tsub();\n\t\t\t\t\t\t\t// F-7: cleanup callback's abortDispose call is idempotent —\n\t\t\t\t\t\t\t// the terminal-branch dispose above sets `abortDispose =\n\t\t\t\t\t\t\t// undefined` so this is a no-op when terminal-fired.\n\t\t\t\t\t\t\tabortDispose?.();\n\t\t\t\t\t\t\tabortDispose = undefined;\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdescribeKind: \"producer\",\n\t\t\t\t\tname: `${baseName}::response`,\n\t\t\t\t\tmeta: aiMeta(\"prompt_node::response\"),\n\t\t\t\t},\n\t\t\t) as NodeInput<T | null>;\n\t\t},\n\t\t{\n\t\t\tname: `${baseName}::output`,\n\t\t\tmeta: opts?.meta\n\t\t\t\t? { ...aiMeta(\"prompt_node::output\"), ...opts.meta }\n\t\t\t\t: aiMeta(\"prompt_node::output\"),\n\t\t},\n\t);\n\n\treturn result;\n}\n","/**\n * PipelineGraph subclass (Wave A.1 Unit 1 — locked 2026-04-24).\n *\n * Specialized {@link Graph} that hosts workflow-DAG sugar methods:\n * `task` / `classify` / `combine` / `approval` / `approvalGate` / `catch`.\n * The legacy `pipeline` / `task` / `branch` / `join` / `subPipeline` /\n * `approval` / `loop` / `onFailure` factories from {@link ./index} continue\n * to work for migration ease; new code should prefer methods on this class.\n *\n * **Tier 2.3 rename:** the prior `gate(...)` method is now `approvalGate(...)`,\n * disambiguating it from the other gate-family primitives (`budgetGate` for\n * numeric constraints, `valve` for boolean switching, `policyGate` for ABAC\n * rules). The \"gating dimension\" here is **human judgment**.\n *\n * Construction: `pipelineGraph(name, opts?)` or `new PipelineGraph(name, opts)`.\n */\n\nimport type { NodeActions } from \"@graphrefly/pure-ts/core\";\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tplaceholderArgs,\n\tRESOLVED,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport type { ReactiveLogBundle } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport { type BaseAuditRecord, createAuditLog, mutate } from \"../../base/mutation/index.js\";\n\nexport type StepRef = string | Node<unknown>;\n\nfunction meta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"orchestration\", kind, extra);\n}\n\n// ── Decision audit record (Audit 2 + Wave A.2 Unit 8) ─────────────────────\n\nexport type DecisionAction =\n\t| \"approve\"\n\t| \"reject\"\n\t| \"modify\"\n\t| \"drop\"\n\t| \"open\"\n\t| \"close\"\n\t| \"teardown\";\n\nexport interface Decision<T = unknown> extends BaseAuditRecord {\n\treadonly action: DecisionAction;\n\treadonly count?: number;\n\treadonly items?: readonly T[];\n\treadonly unflushed?: number;\n}\n\n/** Recommended `keyOf` for keyed-storage adapters (Audit 2 #7). */\nexport const decisionKeyOf = <T>(d: Decision<T>): string => d.action;\n\n// ── Gate ─────────────────────────────────────────────────────────────────\n\nexport interface GateOptions<_T = unknown> {\n\t/** Bounded default 1000 (Audit 2 cross-cutting). `Infinity` is opt-in. */\n\tmaxPending?: number;\n\tstartOpen?: boolean;\n\t/**\n\t * Reactive auto-approve: gate's `latestIsOpen` mirrors this node's truthy\n\t * value. False→true transition drains the pending queue.\n\t *\n\t * **`COMPLETE` / `ERROR` on the approver are silently ignored** — the gate\n\t * stays in its current state. For permanent-open latching, use\n\t * `onceOnly: true` (the first truthy approval latches; subsequent falsy\n\t * values are ignored). The gate has no graceful terminal-state behavior\n\t * for the approver itself.\n\t */\n\tapprover?: Node<unknown>;\n\t/** Latch — first truthy approval opens permanently; `close()` becomes no-op. */\n\tonceOnly?: boolean;\n\tmeta?: Record<string, unknown>;\n\thandlerVersion?: { id: string; version: string | number };\n}\n\nexport interface GateController<T> {\n\t/**\n\t * The post-gate output node. Renamed from `node` (Tier 5.2 / EC6,\n\t * 2026-04-29) to avoid shadowing `Graph.node(name)` when a gate is\n\t * accessed off a `PipelineGraph` instance.\n\t */\n\treadonly output: Node<T>;\n\treadonly pending: Node<readonly T[]>;\n\treadonly count: Node<number>;\n\treadonly isOpen: Node<boolean>;\n\treadonly droppedCount: Node<number>;\n\treadonly decisions: ReactiveLogBundle<Decision<T>>;\n\treadonly audit: ReactiveLogBundle<Decision<T>>;\n\tapprove(count?: number): void;\n\treject(count?: number): void;\n\tmodify(fn: (value: T, index: number, pending: readonly T[]) => T, count?: number): void;\n\topen(): void;\n\tclose(): void;\n}\n\n// ── catch (rename of onFailure; Wave A.2 Unit 10) ─────────────────────────\n\n/**\n * Terminal-cause discriminator for the {@link PipelineGraph.catch} recovery\n * handler. Tier 1.6.3 status-enum migration: was `{ kind: \"complete\" | \"error\" }`\n * pre-1.0; aligned with the canonical lifecycle enum\n * (`status: \"running\" | \"completed\" | \"errored\" | \"cancelled\"`). The variant\n * structure is preserved — `errored` still carries `error: unknown` and\n * `completed` carries no payload.\n */\nexport type TerminalCause = { kind: \"errored\"; error: unknown } | { kind: \"completed\" };\n\nexport interface CatchOptions<_T> {\n\t/**\n\t * Which terminal cause to recover. Default `\"errored\"` (Tier 1.6.3 rename\n\t * of `\"error\"`). `\"completed\"` recovers COMPLETE; `\"terminal\"` recovers\n\t * either. Aligns with the canonical lifecycle enum that\n\t * {@link TerminalCause.kind} now uses.\n\t */\n\ton?: \"errored\" | \"completed\" | \"terminal\";\n\tcompleteWhenDepsComplete?: boolean;\n\tmeta?: Record<string, unknown>;\n\thandlerVersion?: { id: string; version: string | number };\n}\n\n// ── classify result envelope (Wave A.1 Unit 3) ───────────────────────────\n\nexport interface ClassifyResult<TTag extends string, T> {\n\treadonly tag: TTag | \"error\";\n\treadonly value: T;\n\treadonly error?: unknown;\n}\n\n// ── PipelineGraph ────────────────────────────────────────────────────────\n\nexport class PipelineGraph extends Graph {\n\t// -- task -----------------------------------------------------------------\n\n\t/**\n\t * Register a workflow task (`node` + auto-add). String deps resolve via\n\t * `this.resolve(path)`; Node deps via {@link Graph.nameOf} O(1) lookup.\n\t *\n\t * `run` receives `(data: readonly unknown[], ctx)` — the snapshot of latest\n\t * values per dep (same shape as the old `DerivedFn` sugar).\n\t */\n\ttask<T>(\n\t\tname: string,\n\t\trun: (data: readonly unknown[], ctx: { prevData: readonly unknown[] }) => T | undefined | null,\n\t\topts: { deps?: ReadonlyArray<StepRef>; meta?: Record<string, unknown> } = {},\n\t): Node<T> {\n\t\tconst deps = (opts.deps ?? []).map((d) => this._resolveStep(d));\n\t\tconst step = node<T>(\n\t\t\tdeps,\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst result = run(data, ctx);\n\t\t\t\tif (result !== undefined && result !== null) actions.emit(result);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: meta(\"task\", opts.meta),\n\t\t\t} as NodeOptions<T>,\n\t\t);\n\t\tthis.add(step, { name });\n\t\treturn step;\n\t}\n\n\t// -- classify (n-way; replaces binary `branch`) --------------------------\n\n\tclassify<TTag extends string, T>(\n\t\tname: string,\n\t\tsource: StepRef,\n\t\ttagger: (value: T) => TTag,\n\t\topts: { meta?: Record<string, unknown> } = {},\n\t): Node<ClassifyResult<TTag, T>> {\n\t\tconst src = this._resolveStep(source);\n\t\tconst step = node<ClassifyResult<TTag, T>>(\n\t\t\t[src],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst value = data[0];\n\t\t\t\ttry {\n\t\t\t\t\tactions.emit({ tag: tagger(value as T), value: value as T });\n\t\t\t\t} catch (error) {\n\t\t\t\t\tactions.emit({ tag: \"error\" as const, value: value as T, error });\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: meta(\"classify\", opts.meta),\n\t\t\t} as NodeOptions<ClassifyResult<TTag, T>>,\n\t\t);\n\t\tthis.add(step, { name });\n\t\treturn step;\n\t}\n\n\t// -- combine (keyed-record fan-in; replaces positional `join`) -----------\n\n\tcombine<R extends Record<string, StepRef>>(\n\t\tname: string,\n\t\tdeps: R,\n\t\topts: { meta?: Record<string, unknown> } = {},\n\t): Node<{ [K in keyof R]: unknown }> {\n\t\tconst keys = Object.keys(deps) as Array<keyof R & string>;\n\t\tconst nodes = keys.map((k) => this._resolveStep(deps[k] as StepRef));\n\t\tconst step = node<{ [K in keyof R]: unknown }>(\n\t\t\tnodes,\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst values = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst out = {} as { [K in keyof R]: unknown };\n\t\t\t\tfor (let i = 0; i < keys.length; i++) {\n\t\t\t\t\t(out as Record<string, unknown>)[keys[i] as string] = values[i];\n\t\t\t\t}\n\t\t\t\tactions.emit(out);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: meta(\"combine\", opts.meta),\n\t\t\t} as NodeOptions<{ [K in keyof R]: unknown }>,\n\t\t);\n\t\tthis.add(step, { name });\n\t\treturn step;\n\t}\n\n\t// -- approvalGate ---------------------------------------------------------\n\n\tapprovalGate<T>(name: string, source: StepRef, opts: GateOptions<T> = {}): GateController<T> {\n\t\tconst maxPending = opts.maxPending ?? 1000;\n\t\tif (maxPending < 1 && maxPending !== Number.POSITIVE_INFINITY) {\n\t\t\tthrow new RangeError(\"approvalGate: maxPending must be >= 1\");\n\t\t}\n\t\tconst startOpen = opts.startOpen ?? false;\n\n\t\t// C3 — wrap a foreign Node source in a local proxy derived. The proxy\n\t\t// is owned by THIS graph; downstream wiring uses the proxy (not the\n\t\t// foreign Node) so the cross-graph ownership invariant holds. Causal\n\t\t// chain is preserved via the dep edge — `describe()` still surfaces\n\t\t// the foreign Node's path through the proxy.\n\t\tlet src: Node<unknown>;\n\t\tif (typeof source === \"string\") {\n\t\t\tsrc = this._resolveStep(source);\n\t\t} else if (this.nameOf(source) !== undefined) {\n\t\t\tsrc = source;\n\t\t} else {\n\t\t\tconst proxy = node<unknown>(\n\t\t\t\t[source],\n\t\t\t\t(batchData, actions) => {\n\t\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\t\tif (batch0 == null || batch0.length === 0) return;\n\t\t\t\t\tfor (const v of batch0) actions.emit(v);\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\t\tmeta: factoryTag(\"proxy\"),\n\t\t\t\t},\n\t\t\t);\n\t\t\tthis.add(proxy, { name: `${name}/source` });\n\t\t\tsrc = proxy;\n\t\t}\n\n\t\t// State subgraph\n\t\tconst internal = new Graph(`${name}-state`);\n\t\tconst pendingNode = internal.state<readonly T[]>(\"pending\", [], {\n\t\t\tequals: () => false,\n\t\t});\n\t\tconst isOpenNode = internal.state<boolean>(\"isOpen\", startOpen);\n\t\tconst countNode = internal.derived<number>(\"count\", [\"pending\"], (batchData, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\treturn [(data[0] as readonly T[]).length];\n\t\t});\n\t\tconst droppedCountNode = internal.state<number>(\"droppedCount\", 0);\n\t\tconst decisions = createAuditLog<Decision<T>>({\n\t\t\tname: \"decisions\",\n\t\t\tretainedLimit: 1024,\n\t\t\tgraph: internal,\n\t\t});\n\t\tthis.mount(`${name}-state`, internal);\n\n\t\tlet queue: T[] = [];\n\t\tlet torn = false;\n\t\tlet latched = false;\n\t\t// Closure-mirror per COMPOSITION-GUIDE §28 factory-time seed pattern.\n\t\t// `output` samples `latestIsOpen` inside its fn body when deciding\n\t\t// emit-vs-enqueue; reading a closure variable is NOT a P3 violation\n\t\t// (§28). An in-session Phase 9 plan would have relocated the value to\n\t\t// `internal.derived(\"latestIsOpen\", ...)` + `.cache` reads (which IS\n\t\t// a P3 violation); plan was reverted at the design level after\n\t\t// re-reading §28 — pattern preserved here. See `archive/docs/SESSION-\n\t\t// graph-narrow-waist.md` § \"Status of existing modifications\".\n\t\tlet latestIsOpen = startOpen;\n\t\tconst isOpenUnsub = isOpenNode.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) latestIsOpen = m[1] as boolean;\n\t\t\t}\n\t\t});\n\t\tthis.addDisposer(isOpenUnsub);\n\n\t\tfunction syncPending(): void {\n\t\t\tpendingNode.emit([...queue]);\n\t\t}\n\n\t\tfunction recordDecision(\n\t\t\taction: DecisionAction,\n\t\t\titems?: readonly T[],\n\t\t\tunflushed?: number,\n\t\t): void {\n\t\t\tdecisions.append({\n\t\t\t\taction,\n\t\t\t\tt_ns: wallClockNs(),\n\t\t\t\t...(items !== undefined ? { items, count: items.length } : {}),\n\t\t\t\t...(unflushed !== undefined ? { unflushed } : {}),\n\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t} as Decision<T>);\n\t\t}\n\n\t\tfunction enqueue(value: T): void {\n\t\t\tqueue.push(value);\n\t\t\tif (queue.length > maxPending) {\n\t\t\t\tconst dropped = queue.shift() as T;\n\t\t\t\tdroppedCountNode.emit((droppedCountNode.cache as number) + 1);\n\t\t\t\trecordDecision(\"drop\", [dropped]);\n\t\t\t}\n\t\t\tsyncPending();\n\t\t}\n\n\t\tfunction dequeue(n: number): T[] {\n\t\t\tconst items = queue.splice(0, n);\n\t\t\tsyncPending();\n\t\t\treturn items;\n\t\t}\n\n\t\tconst output = node<T>(\n\t\t\t[src],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst terminal = ctx.terminalDeps[0];\n\t\t\t\tif (terminal !== undefined) {\n\t\t\t\t\ttorn = true;\n\t\t\t\t\tconst unflushed = queue.length;\n\t\t\t\t\tqueue = [];\n\t\t\t\t\tsyncPending();\n\t\t\t\t\trecordDecision(\"teardown\", undefined, unflushed);\n\t\t\t\t\tactions.down(terminal === true ? [[COMPLETE]] : [[ERROR, terminal]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0 as T[]) {\n\t\t\t\t\tif (latestIsOpen) {\n\t\t\t\t\t\tactions.emit(v);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tenqueue(v);\n\t\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\t// Spec §2.7 R2.7.1 (DS-2.7.A). fn must fire on\n\t\t\t\t// upstream-COMPLETE/ERROR-only-without-DATA so the\n\t\t\t\t// teardown-decision record + downstream terminal forward run.\n\t\t\t\tterminalAsRealInput: true,\n\t\t\t\tmeta: meta(\"approval_gate\", opts.meta),\n\t\t\t},\n\t\t);\n\t\tthis.add(output, { name });\n\n\t\t// Reactive approver mode: mirror latestIsOpen to the approver's value.\n\t\t// **m1:** approver `COMPLETE` / `ERROR` are silently ignored — gate stays\n\t\t// in current state. For latching behavior, use `onceOnly: true`.\n\t\tif (opts.approver != null) {\n\t\t\tconst initialApproved = Boolean(opts.approver.cache);\n\t\t\tif (initialApproved) {\n\t\t\t\tisOpenNode.emit(true);\n\t\t\t\tlatestIsOpen = true;\n\t\t\t\tif (opts.onceOnly) latched = true;\n\t\t\t}\n\t\t\tconst approverSub = opts.approver.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\tconst truthy = Boolean(m[1]);\n\t\t\t\t\tif (truthy && !latestIsOpen) {\n\t\t\t\t\t\t// false → true transition\n\t\t\t\t\t\tif (opts.onceOnly) {\n\t\t\t\t\t\t\tif (latched) continue;\n\t\t\t\t\t\t\tlatched = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tisOpenNode.emit(true);\n\t\t\t\t\t\t\tconst items = dequeue(queue.length);\n\t\t\t\t\t\t\t// M11: include items count in approver-driven open decisions\n\t\t\t\t\t\t\t// so audit consumers see how many items were flushed.\n\t\t\t\t\t\t\trecordDecision(\"open\", items);\n\t\t\t\t\t\t\tfor (const item of items) {\n\t\t\t\t\t\t\t\tif (torn) break;\n\t\t\t\t\t\t\t\toutput.emit(item);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (!truthy && latestIsOpen) {\n\t\t\t\t\t\tif (opts.onceOnly && latched) continue;\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tisOpenNode.emit(false);\n\t\t\t\t\t\t\trecordDecision(\"close\");\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.addDisposer(approverSub);\n\t\t}\n\n\t\tconst guardTorn = (method: string): void => {\n\t\t\tif (torn) throw new Error(`approvalGate: ${method}() called after the gate was torn down`);\n\t\t};\n\n\t\tconst approveImpl = (count = 1): void => {\n\t\t\tguardTorn(\"approve\");\n\t\t\tconst items = dequeue(count);\n\t\t\tfor (const item of items) {\n\t\t\t\tif (torn) break;\n\t\t\t\toutput.emit(item);\n\t\t\t}\n\t\t};\n\t\tconst rejectImpl = (count = 1): void => {\n\t\t\tguardTorn(\"reject\");\n\t\t\tdequeue(count);\n\t\t};\n\t\tconst modifyImpl = (\n\t\t\tfn: (value: T, index: number, pending: readonly T[]) => T,\n\t\t\tcount = 1,\n\t\t): void => {\n\t\t\tguardTorn(\"modify\");\n\t\t\tconst snapshot = [...queue] as readonly T[];\n\t\t\tconst items = dequeue(count);\n\t\t\tfor (let i = 0; i < items.length; i++) {\n\t\t\t\tif (torn) break;\n\t\t\t\toutput.emit(fn(items[i], i, snapshot));\n\t\t\t}\n\t\t};\n\t\tconst openImpl = (): void => {\n\t\t\tguardTorn(\"open\");\n\t\t\tisOpenNode.emit(true);\n\t\t\tconst items = dequeue(queue.length);\n\t\t\tfor (const item of items) {\n\t\t\t\tif (torn) break;\n\t\t\t\toutput.emit(item);\n\t\t\t}\n\t\t};\n\t\tconst closeImpl = (): void => {\n\t\t\tguardTorn(\"close\");\n\t\t\tif (opts.onceOnly && latched) return;\n\t\t\tisOpenNode.emit(false);\n\t\t};\n\n\t\tconst approve = mutate(approveImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (args, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"approve\",\n\t\t\t\t\tcount: (args[0] as number | undefined) ?? 1,\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\t\tconst reject = mutate(rejectImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (args, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"reject\",\n\t\t\t\t\tcount: (args[0] as number | undefined) ?? 1,\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\t\tconst modify = mutate(modifyImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (args, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"modify\",\n\t\t\t\t\tcount: (args[1] as number | undefined) ?? 1,\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\t\tconst open = mutate(openImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (_a, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"open\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\t\tconst close = mutate(closeImpl, {\n\t\t\tframe: \"transactional\",\n\t\t\tlog: decisions,\n\t\t\tfreeze: false,\n\t\t\tonSuccessRecord: (_a, _r, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"close\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t\tonFailureRecord: (_a, _e, m) =>\n\t\t\t\t({\n\t\t\t\t\taction: \"drop\",\n\t\t\t\t\tt_ns: m.t_ns,\n\t\t\t\t\terrorType: m.errorType,\n\t\t\t\t\t...(opts.handlerVersion != null ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t}) as Decision<T>,\n\t\t});\n\n\t\tthis.addDisposer(countNode.subscribe(() => undefined));\n\n\t\tconst controller: GateController<T> = {\n\t\t\toutput,\n\t\t\tpending: pendingNode,\n\t\t\tcount: countNode,\n\t\t\tisOpen: isOpenNode,\n\t\t\tdroppedCount: droppedCountNode,\n\t\t\tdecisions,\n\t\t\taudit: decisions,\n\t\t\tapprove,\n\t\t\treject,\n\t\t\tmodify,\n\t\t\topen,\n\t\t\tclose,\n\t\t};\n\t\treturn controller;\n\t}\n\n\t// -- approval (thin alias over approvalGate({ approver, maxPending: 1 })) -\n\n\t/**\n\t * Reactive approval step: passes items through when `approver` is truthy;\n\t * holds at most one pending item (maxPending: 1) when falsy. A thin alias\n\t * over `approvalGate({ approver, maxPending: 1 })` — use `approvalGate()`\n\t * directly for finer control (maxPending, onceOnly, manual approve/reject).\n\t */\n\tapproval<T>(\n\t\tname: string,\n\t\tsource: StepRef,\n\t\tapprover: Node<unknown>,\n\t\topts: Omit<GateOptions<T>, \"approver\" | \"maxPending\"> = {},\n\t): GateController<T> {\n\t\treturn this.approvalGate<T>(name, source, { ...opts, approver, maxPending: 1 });\n\t}\n\n\t// -- catch (renamed onFailure; dep-channel intercept) -------------------\n\n\tcatch<T>(\n\t\tname: string,\n\t\tsource: StepRef,\n\t\trecover: (cause: TerminalCause, actions: NodeActions) => T,\n\t\topts: CatchOptions<T> = {},\n\t): Node<T> {\n\t\tconst src = this._resolveStep(source);\n\t\tconst mode = opts.on ?? \"errored\";\n\t\tconst step = node<T>(\n\t\t\t[src],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst terminal = ctx.terminalDeps[0];\n\t\t\t\tif (terminal !== undefined) {\n\t\t\t\t\tconst cause: TerminalCause =\n\t\t\t\t\t\tterminal === true ? { kind: \"completed\" } : { kind: \"errored\", error: terminal };\n\t\t\t\t\tif (mode === \"terminal\" || mode === cause.kind) {\n\t\t\t\t\t\tactions.emit(recover(cause, actions));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tactions.down(cause.kind === \"completed\" ? [[COMPLETE]] : [[ERROR, cause.error]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0 as T[]) actions.emit(v);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tcompleteWhenDepsComplete:\n\t\t\t\t\topts.completeWhenDepsComplete ?? !(mode === \"completed\" || mode === \"terminal\"),\n\t\t\t\terrorWhenDepsError: !(mode === \"errored\" || mode === \"terminal\"),\n\t\t\t\t// Spec §2.7 R2.7.1 (DS-2.7.A). `catch` exists to fire on a\n\t\t\t\t// source terminal — its whole job is `recover(cause, …)` on a\n\t\t\t\t// terminal-only wave. Without this opt-in the gate holds and\n\t\t\t\t// the recover branch never runs.\n\t\t\t\tterminalAsRealInput: true,\n\t\t\t\tmeta: meta(\"catch\", opts.meta),\n\t\t\t} as NodeOptions<T>,\n\t\t);\n\t\tthis.add(step, { name });\n\t\treturn step;\n\t}\n\n\t// -- internals ----------------------------------------------------------\n\n\tprivate _resolveStep(dep: StepRef): Node<unknown> {\n\t\tif (typeof dep === \"string\") return this.resolve(dep);\n\t\tconst existing = this.nameOf(dep);\n\t\tif (existing === undefined) {\n\t\t\tthrow new Error(\n\t\t\t\t`PipelineGraph \"${this.name}\": Node dep is not registered. Pass a string path or call graph.add(node) first.`,\n\t\t\t);\n\t\t}\n\t\treturn dep;\n\t}\n}\n\n/** Factory wrapper — `pipelineGraph(name, opts?)`. Equivalent to `new PipelineGraph(name, opts)`. */\nexport function pipelineGraph(name: string, opts?: GraphOptions): PipelineGraph {\n\tconst g = new PipelineGraph(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` exposes provenance. `factoryArgs` is the\n\t// constructor opts (sans the `factory`/`factoryArgs` keys themselves to\n\t// avoid recursive nesting). QA F13: route through `placeholderArgs` for\n\t// consistency with sibling factories — `GraphOptions[key: string]: unknown`\n\t// is open-ended, so user-extension keys may carry non-JSON content.\n\tconst { factory: _f, factoryArgs: _fa, ...tagArgs } = (opts ?? {}) as Record<string, unknown>;\n\tg.tagFactory(\"pipelineGraph\", placeholderArgs(tagArgs));\n\treturn g;\n}\n","import { type Node, node, RESOLVED } from \"@graphrefly/pure-ts/core\";\nimport { keepalive, type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../_internal.js\";\nimport type { ChatMessage } from \"../adapters/core/types.js\";\n\n// ---------------------------------------------------------------------------\n// chatStream\n// ---------------------------------------------------------------------------\n\nexport type ChatStreamOptions = {\n\tgraph?: GraphOptions;\n\tmaxMessages?: number;\n};\n\nexport class ChatStreamGraph extends Graph {\n\tprivate readonly _log: ReactiveLogBundle<ChatMessage>;\n\treadonly messages: Node<readonly ChatMessage[]>;\n\t/**\n\t * Most recently appended message. Stays in the protocol SENTINEL state\n\t * (`cache === undefined`, no DATA emitted) until the first append, then\n\t * tracks the latest entry. Per COMPOSITION-GUIDE §1a, the SENTINEL is\n\t * the canonical \"no value yet\" signal — consumers detect empty via\n\t * `data[i] === undefined` inside reactive fns or `latest.cache === undefined`\n\t * outside. No `T | null` placeholder, no `hasLatest` companion.\n\t */\n\treadonly latest: Node<ChatMessage>;\n\treadonly messageCount: Node<number>;\n\n\tconstructor(name: string, opts: ChatStreamOptions = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\tthis._log = reactiveLog<ChatMessage>([], {\n\t\t\tname: \"messages\",\n\t\t\tmaxSize: opts.maxMessages,\n\t\t});\n\t\tthis.messages = this._log.entries;\n\t\tthis.add(this.messages, { name: \"messages\" });\n\n\t\t// SENTINEL on empty (COMPOSITION-GUIDE §1a): return `[]` for\n\t\t// RESOLVED-only on empty stream, `[T]` to emit DATA. `latest.cache`\n\t\t// stays `undefined` until the first append.\n\t\tthis.latest = node<ChatMessage>(\n\t\t\t[this.messages],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst entries = data[0] as readonly ChatMessage[];\n\t\t\t\tif (entries.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit(entries[entries.length - 1] as ChatMessage);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"latest\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"chat_latest\"),\n\t\t\t},\n\t\t);\n\t\tthis.add(this.latest, { name: \"latest\" });\n\t\tthis.addDisposer(keepalive(this.latest));\n\n\t\tthis.messageCount = node<number>(\n\t\t\t[this.messages],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly ChatMessage[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"messageCount\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"chat_message_count\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.messageCount, { name: \"messageCount\" });\n\t\tthis.addDisposer(keepalive(this.messageCount));\n\t}\n\n\tappend(role: ChatMessage[\"role\"], content: string, extra?: Partial<ChatMessage>): void {\n\t\tthis._log.append({ role, content, ...extra });\n\t}\n\n\tappendToolResult(callId: string, content: string): void {\n\t\tthis._log.append({ role: \"tool\", content, toolCallId: callId });\n\t}\n\n\tclear(): void {\n\t\tthis._log.clear();\n\t}\n\n\tallMessages(): readonly ChatMessage[] {\n\t\treturn this.messages.cache as readonly ChatMessage[];\n\t}\n}\n\nexport function chatStream(name: string, opts?: ChatStreamOptions): ChatStreamGraph {\n\treturn new ChatStreamGraph(name, opts);\n}\n","/**\n * `toolExecution` — reactive per-tool-call executor with retry + rescue.\n *\n * Lifted from the inlined `executeToolReactively` helper inside `agent-loop.ts`\n * so it can be consumed standalone by any caller with a reactive `toolCalls`\n * batch — not just `agentLoop`. The shape is: one input `Node<readonly\n * ToolCall[]>` + a `ToolRegistryGraph` → one output `Node<readonly\n * ToolResult[]>`. Each call maps to a per-call `retrySource(executeReactive)`\n * → optional `rescue` chain that emits the handler result on success, or a\n * JSON-wrapped `{ error }` payload on terminal failure so the LLM can see the\n * error as tool output and decide whether to try again via another tool call.\n *\n * **Cancellation.** `executeReactive` mints a per-call `AbortController` and\n * threads its signal into the handler call. When `switchMap` supersedes the\n * inner (a fresh `toolCalls` batch arrives) or the outer graph tears down,\n * the per-call node unsubscribes and `ac.abort()` fires. Signal-aware\n * handlers (`fetch(url, {signal})`, child-process kill, DB cancel) actually\n * stop in-flight work; handlers that ignore the signal still complete to\n * their original termination, but their result is discarded.\n *\n * @module\n */\n\nimport { type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { rescue, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { retry } from \"../../../base/resilience/retry.js\";\nimport type { ToolCall } from \"../adapters/core/types.js\";\nimport type { ToolRegistryGraph } from \"./tool-registry.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A single tool execution outcome: `{id, content}` where content is a JSON string. */\nexport interface ToolResult {\n\treadonly id: string;\n\treadonly content: string;\n}\n\nexport type ToolExecutionOptions = {\n\t/**\n\t * Reactive tool-call batch. Each non-empty emission triggers a fresh\n\t * per-call execution fan-out; superseding emissions cancel the prior fan.\n\t */\n\ttoolCalls: Node<readonly ToolCall[]>;\n\t/** Registry that resolves tool name → handler. */\n\ttools: ToolRegistryGraph;\n\t/**\n\t * Retry count per individual tool call. `retrySource({count: N})` retries\n\t * up to N times on error (N retries = N+1 total attempts). Default: 1.\n\t */\n\tretryCount?: number;\n\t/**\n\t * How to surface a terminal error after retries are exhausted.\n\t * - `\"rescue\"` (default): emit `{id, content: JSON.stringify({error})}`\n\t * so the LLM sees the failure as structured tool output and can decide\n\t * how to react. Sibling calls in the same batch continue to their own\n\t * completion; one call's failure does not affect the others.\n\t * - `\"propagate\"`: let the ERROR propagate downstream. **Blast radius:**\n\t * the per-batch `derived` join auto-errors when any per-call node\n\t * terminates with ERROR, so one call's failure discards every sibling's\n\t * DATA (even ones that already settled with a valid ToolResult). Use\n\t * `\"propagate\"` only when a single tool failure should be fatal for the\n\t * whole batch; prefer `\"rescue\"` when you want the LLM to see partial\n\t * results plus per-call error markers.\n\t */\n\tonError?: \"rescue\" | \"propagate\";\n};\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Reactive executor for a batch of LLM tool calls.\n *\n * Each DATA emission on `toolCalls` dispatches a fresh per-call fan-out: for\n * every call in the batch, construct a `retrySource(fromAny(tools.execute(\n * name, args)))` node, optionally `rescue` it into a JSON error shape, and\n * join the results via a `derived` whose first-run gate waits for every call\n * to settle before emitting the batch. Empty batches (`calls.length === 0`)\n * are a caller-side invariant violation (the upstream gate should emit\n * RESOLVED for empty batches, not DATA) and trigger a loud error — callers\n * that want to accept empty batches should upstream-filter them first.\n *\n * Reference-equality + content-equality dedup is applied to the output batch\n * so duplicate re-emissions from a completing retrySource don't propagate.\n *\n * @param opts - `{ toolCalls, tools, retryCount?, onError? }`.\n * @returns `Node<readonly ToolResult[]>` — one ToolResult per input ToolCall.\n */\nexport function toolExecution(opts: ToolExecutionOptions): Node<readonly ToolResult[]> {\n\tconst { toolCalls, tools } = opts;\n\tconst retryCount = opts.retryCount ?? 1;\n\tconst onError = opts.onError ?? \"rescue\";\n\n\tconst batchEquals = (a: readonly ToolResult[], b: readonly ToolResult[]): boolean => {\n\t\tif (a === b) return true;\n\t\tif (a.length !== b.length) return false;\n\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\tconst ai = a[i];\n\t\t\tconst bi = b[i];\n\t\t\tif (ai?.id !== bi?.id) return false;\n\t\t\tif (ai?.content !== bi?.content) return false;\n\t\t}\n\t\treturn true;\n\t};\n\n\treturn switchMap<readonly ToolCall[], readonly ToolResult[]>(toolCalls, (calls) => {\n\t\tif (calls == null || calls.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t\"toolExecution: received an empty tool-call batch as DATA — callers must upstream-filter empty batches (emit RESOLVED) so switchMap is only dispatched for non-empty batches.\",\n\t\t\t);\n\t\t}\n\t\tconst perCall = calls.map((call) => executeOne(call, tools, retryCount, onError));\n\t\t// `executeOne` returns `Node<ToolResult>` in both \"rescue\" and\n\t\t// \"propagate\" modes (the rescue handler builds a `ToolResult`\n\t\t// shape; the success `derived` builds one directly). The join\n\t\t// just forwards the per-call values — no shape coercion needed.\n\t\treturn node(\n\t\t\tperCall,\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit(data as readonly ToolResult[]);\n\t\t\t},\n\t\t\t{ describeKind: \"derived\", name: \"toolExecution::batch\", equals: batchEquals },\n\t\t);\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Internals\n// ---------------------------------------------------------------------------\n\n/**\n * Per-call reactive executor. `retrySource` re-invokes the factory on ERROR\n * (each attempt mints a fresh `executeReactive` node, which in turn mints a\n * fresh `AbortController` and handler invocation). `executeReactive` itself\n * handles synchronous handler throws — they surface as `[[ERROR, err]]`\n * inside the producer, so `retrySource`'s reactive ERROR path fires\n * consistently regardless of handler shape. No `Promise.resolve().then(...)`\n * thunk needed — the reactive path is end-to-end.\n *\n * Handlers that return a plain string are surfaced as-is; anything else is\n * `JSON.stringify`'d so LLMs that parse tool results can roundtrip\n * structured data without surprise quoting.\n */\nfunction executeOne(\n\tcall: ToolCall,\n\ttools: ToolRegistryGraph,\n\tretryCount: number,\n\tonError: \"rescue\" | \"propagate\",\n): Node<ToolResult> {\n\tconst attempted: Node<unknown> = retry(() => tools.executeReactive(call.name, call.arguments), {\n\t\tcount: retryCount,\n\t}).node;\n\tconst onSuccess = node<ToolResult>(\n\t\t[attempted],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst val = data[0];\n\t\t\tactions.emit({\n\t\t\t\tid: call.id,\n\t\t\t\tcontent: typeof val === \"string\" ? val : JSON.stringify(val),\n\t\t\t});\n\t\t},\n\t\t{ describeKind: \"derived\" },\n\t);\n\tif (onError === \"propagate\") return onSuccess;\n\treturn rescue(onSuccess, (err) => ({\n\t\tid: call.id,\n\t\tcontent: JSON.stringify({ error: String(err) }),\n\t}));\n}\n","import { ERROR, type Messages, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { fromAsyncIter, fromPromise, keepalive, reactiveMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta, isNodeLike } from \"../_internal.js\";\nimport type { ToolDefinition } from \"../adapters/core/types.js\";\n\n// ---------------------------------------------------------------------------\n// toolRegistry\n// ---------------------------------------------------------------------------\n\nexport type ToolRegistryOptions = {\n\tgraph?: GraphOptions;\n};\n\n/**\n * `ToolRegistryGraph` — name-keyed registry of {@link ToolDefinition}s.\n *\n * **Reactive-only execution.** The only execution path is\n * {@link executeReactive}, which returns a `Node<unknown>` for the handler\n * result. Composing factories (`toolExecution`, `agentLoop`) consume it\n * directly inside `retrySource` / `switchMap` chains. There is intentionally\n * no imperative `execute()` Promise method — the registry was originally a\n * dual-boundary class (imperative + reactive) and the imperative path was\n * the only thing in the codebase bridging through `Promise.resolve().then()`\n * to feed `fromAny`. Removing it left every consumer on a single\n * reactive-all-the-way path with real abort propagation.\n *\n * For non-reactive callers (debug scripts, one-shot tests), bridge with\n * `awaitSettled(toolRegistry.executeReactive(name, args))`.\n *\n * **Wave A Unit 6 refactor:** internal storage migrated from `state<Map>`\n * (O(N) Map-copy per mutation) to `ReactiveMapBundle<string, ToolDefinition>`\n * (O(1) mutations + version counter).\n */\nexport class ToolRegistryGraph extends Graph {\n\treadonly definitions: Node<ReadonlyMap<string, ToolDefinition>>;\n\treadonly schemas: Node<readonly ToolDefinition[]>;\n\tprivate readonly _bundle: ReturnType<typeof reactiveMap<string, ToolDefinition>>;\n\n\tconstructor(name: string, opts: ToolRegistryOptions = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\tthis._bundle = reactiveMap<string, ToolDefinition>({\n\t\t\tname: \"definitions\",\n\t\t});\n\t\tthis.definitions = this._bundle.entries;\n\t\tthis.add(this.definitions, { name: \"definitions\" });\n\n\t\tthis.schemas = node<readonly ToolDefinition[]>(\n\t\t\t[this.definitions],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst defs = data[0];\n\t\t\t\tactions.emit([...((defs ?? new Map()) as ReadonlyMap<string, ToolDefinition>).values()]);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"schemas\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"tool_schemas\"),\n\t\t\t\tinitial: [],\n\t\t\t},\n\t\t);\n\t\tthis.add(this.schemas, { name: \"schemas\" });\n\t\tthis.addDisposer(keepalive(this.schemas));\n\t}\n\n\tregister(tool: ToolDefinition): void {\n\t\tthis._bundle.set(tool.name, tool);\n\t}\n\n\tunregister(name: string): void {\n\t\tthis._bundle.delete(name);\n\t}\n\n\t/**\n\t * Reactive execution — returns a `Node<unknown>` that emits the handler\n\t * result. The returned node is a `producer` that:\n\t *\n\t * 1. Mints a per-call `AbortController` whose `signal` is threaded into\n\t * the handler call AND into `fromAny` (so a `fromPromise` /\n\t * `fromAsyncIter` inner abandons cleanly when the consumer\n\t * unsubscribes).\n\t * 2. Runs `tool.handler(args, {signal})` inside a try/catch — a\n\t * synchronous throw surfaces as `[[ERROR, err]]` downstream instead\n\t * of escaping the producer.\n\t * 3. Forwards every message from the inner `fromAny` chain to the\n\t * producer's outputs.\n\t * 4. On teardown (subscriber count drops to zero, e.g. `switchMap`\n\t * supersede) calls `ac.abort()` and unsubscribes the inner.\n\t * Signal-aware handlers (e.g. `fetch(url, {signal})`) actually stop.\n\t *\n\t * Each call mints a fresh node tied to a fresh `handler(args, ...)`\n\t * invocation — call `executeReactive` again for repeated invocations.\n\t *\n\t * @throws `Error` synchronously when `name` is not registered (no node is\n\t * constructed — the caller gets a pre-wiring failure rather than a\n\t * silent ERROR wave on an empty graph).\n\t */\n\texecuteReactive(name: string, args: Record<string, unknown>): Node<unknown> {\n\t\tconst tool = this._bundle.get(name);\n\t\tif (!tool) throw new Error(`toolRegistry: unknown tool \"${name}\"`);\n\t\treturn node<unknown>(\n\t\t\t[],\n\t\t\t(_data, actions) => {\n\t\t\t\tconst ac = new AbortController();\n\t\t\t\tlet inner: Node<unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tconst raw = tool.handler(args, { signal: ac.signal });\n\t\t\t\t\tinner = handlerResultToNode(raw, ac.signal);\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// Synchronous throw from handler → ERROR. Producer cleanup\n\t\t\t\t\t// still aborts the controller for symmetry (no-op if no\n\t\t\t\t\t// signal listeners attached).\n\t\t\t\t\tactions.down([[ERROR, err]] satisfies Messages);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\tac.abort();\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst unsub = inner.subscribe((batch) => {\n\t\t\t\t\tactions.down(batch as Messages);\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tac.abort();\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: `executeReactive::${name}`,\n\t\t\t\tdescribeKind: \"producer\",\n\t\t\t\tmeta: aiMeta(\"tool_execute_reactive\"),\n\t\t\t},\n\t\t);\n\t}\n\n\tgetDefinition(name: string): ToolDefinition | undefined {\n\t\t// Pure read via the snapshot cache — avoids the bundle's\n\t\t// `wrapMutation` path (which would run the version-bump check and\n\t\t// any configured retention eviction on every lookup). Safe because\n\t\t// `getDefinition` is a boundary API, not a reactive fn body.\n\t\treturn this._bundle.entries.cache?.get(name);\n\t}\n}\n\nexport function toolRegistry(name: string, opts?: ToolRegistryOptions): ToolRegistryGraph {\n\treturn new ToolRegistryGraph(name, opts);\n}\n\n/**\n * Coerce a tool handler return value into a `Node<unknown>`.\n *\n * Differs from `fromAny` by treating **strings, arrays, plain iterables, and\n * scalar objects as single DATA values** rather than iterating them. A tool\n * handler that returns `\"hello world\"` should surface as one `DATA(\"hello\n * world\")`, not 11 `DATA` events of single characters; an array `[1, 2, 3]`\n * should surface as `DATA([1, 2, 3])`, not three separate emissions.\n *\n * Reactive shapes (Node, Promise, AsyncIterable) are unwrapped as expected.\n *\n * @internal\n */\nfunction handlerResultToNode(raw: unknown, signal: AbortSignal): Node<unknown> {\n\tif (isNodeLike(raw)) {\n\t\treturn raw as Node<unknown>;\n\t}\n\tif (raw != null && typeof (raw as PromiseLike<unknown>).then === \"function\") {\n\t\treturn fromPromise(raw as PromiseLike<unknown>, { signal });\n\t}\n\tif (raw != null && typeof raw === \"object\" && Symbol.asyncIterator in (raw as object)) {\n\t\treturn fromAsyncIter(raw as AsyncIterable<unknown>, { signal });\n\t}\n\t// String, number, boolean, null, undefined, plain object, array,\n\t// sync iterable — treat as a single DATA value via a resolved Promise so\n\t// `fromPromise`'s scalar-DATA-emit + COMPLETE semantics match the\n\t// pre-refactor `tools.execute` behavior (which always wrapped via async).\n\treturn fromPromise(Promise.resolve(raw), { signal });\n}\n","/**\n * Pure exponential-decay utility (Tier 2.2 promotion from `patterns/memory/`).\n *\n * Used by `collection`, `agentMemory`, harness `strategy.ts`, and any\n * downstream consumer that needs decay-with-floor scoring. Promoted to\n * `extra/utils/` because the math has zero domain semantics and is reusable\n * by non-memory primitives (e.g. routing weight decay, retry-attempt aging).\n *\n * @module\n */\n\n/**\n * Default exponential-decay rate corresponding to a 7-day half-life.\n *\n * `Math.LN2 / (7 × 86_400)` ≈ `1.146e-6`. Imported by memory tiers + any\n * consumer that wants the same default cadence as `agentMemory`'s active\n * tier. Tier 4.4 (Wave AM Unit 1) — promoted from\n * `patterns/ai/memory/tiers.ts` so non-memory consumers can share the\n * canonical default without reaching across domains.\n */\nexport const DEFAULT_DECAY_RATE = Math.LN2 / (7 * 86_400);\n\n/**\n * Exponential decay with floor: `score = max(minScore, baseScore * exp(-ratePerSecond * ageSeconds))`.\n *\n * Tolerant fallbacks (deliberate for use inside reactive derived fns):\n * - non-finite `baseScore` → `minScore`\n * - non-positive `ageSeconds` (incl. clock skew) → `max(minScore, baseScore)` (no decay)\n * - non-positive `ratePerSecond` → `max(minScore, baseScore)` (no decay; rate=0 disables)\n *\n * Underflow boundary: `Math.exp(-745) === 0`. For very long ages × rates the\n * result clamps to `minScore`; if you need slow decay over years, choose a\n * smaller `ratePerSecond` rather than relying on graceful underflow.\n *\n * Half-life conversion: `ratePerSecond = Math.LN2 / halfLifeSeconds`.\n */\nexport function decay(\n\tbaseScore: number,\n\tageSeconds: number,\n\tratePerSecond: number,\n\tminScore = 0,\n): number {\n\tif (!Number.isFinite(baseScore)) return minScore;\n\tif (!Number.isFinite(ageSeconds) || ageSeconds <= 0) return Math.max(minScore, baseScore);\n\tif (!Number.isFinite(ratePerSecond) || ratePerSecond <= 0) return Math.max(minScore, baseScore);\n\tconst decayed = baseScore * Math.exp(-ratePerSecond * ageSeconds);\n\treturn Math.max(minScore, decayed);\n}\n","/**\n * Harness-domain internal helpers.\n *\n * trackingKey extracted from patterns/_internal/index.ts during cleave A2.\n * Destination decided per STOP #1 resolution: harness-domain shape,\n * used only by utils/harness/types.ts and presets/harness/harness-loop.ts.\n */\n\n// trackingKey\n// ---------------------------------------------------------------------------\n\n/**\n * Stable tracking key for an item with retry/reingestion decoration.\n *\n * Uses `relatedTo[0]` if present (carries the original key forward through\n * retries and reingestions). Falls back to `summary` for first-time items.\n *\n * This avoids deriving keys from mutated summary strings — retries decorate\n * the summary with `[RETRY N/M]` and failure context, so regex-stripping\n * would be fragile and any new decoration pattern would risk infinite loops\n * by generating novel keys.\n *\n * **Caller contract — uniqueness (qa D1, 2026-04-29).** Two distinct intake\n * items sharing the same `summary` (and neither carrying `relatedTo`)\n * produce the SAME tracking key. The harness's `routeJobIds` map is keyed\n * by this value: a duplicate-key publish overwrites the prior mapping, and\n * a later `ackJob` for the original publish acks the wrong audit job.\n * Single-threaded JS makes the typical structural-failure path safe (the\n * ack runs before reingest publishes), but multi-publisher concurrency or\n * batched intake of two items with identical summaries can race.\n *\n * **Caller responsibility:** ensure `summary` uniqueness OR carry an\n * explicit stable id via `relatedTo[0]` for items that may collide. For\n * retry/reingestion paths the `relatedTo` array MUST start with the\n * original tracking key — `[originalKey, ...]` — so the carried-forward\n * identity matches the audit log entry created at first publish.\n *\n * @internal\n */\nexport function trackingKey(item: { summary: string; relatedTo?: string[] }): string {\n\treturn item.relatedTo?.[0] ?? item.summary;\n}\n","/**\n * Harness runtime defaults (roadmap §9.0).\n *\n * Split out from `types.ts` in Wave B Unit 15 G so the type file holds\n * only type declarations and plug-in contracts. Runtime constants and\n * helpers live here; the harness barrel (`index.ts`) re-exports both so\n * external consumers see a single surface.\n *\n * @module\n */\n\nimport type {\n\tErrorClass,\n\tErrorClassifier,\n\tExecutionResult,\n\tIntervention,\n\tPresetId,\n\tQueueConfig,\n\tQueueRoute,\n\tRootCause,\n\tSeverity,\n\tStrategyKey,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Route / queue\n// ---------------------------------------------------------------------------\n\n/** Ordered queue route names for iteration. */\nexport const QUEUE_NAMES: readonly QueueRoute[] = [\n\t\"auto-fix\",\n\t\"needs-decision\",\n\t\"investigation\",\n\t\"backlog\",\n];\n\n/** Default queue configurations. */\nexport const DEFAULT_QUEUE_CONFIGS: Record<QueueRoute, QueueConfig> = {\n\t\"auto-fix\": { gated: false },\n\t\"needs-decision\": { gated: true },\n\tinvestigation: { gated: true },\n\t// `startOpen` intentionally omitted — backlog is not gated, so the flag\n\t// would be meaningless. Dropped in Unit 15 G trim pass.\n\tbacklog: { gated: false },\n};\n\n// ---------------------------------------------------------------------------\n// Priority scoring\n// ---------------------------------------------------------------------------\n\n/** Default severity weights. */\nexport const DEFAULT_SEVERITY_WEIGHTS: Record<Severity, number> = {\n\tcritical: 100,\n\thigh: 70,\n\tmedium: 40,\n\tlow: 10,\n};\n\n/** Default decay rate: ~7-day half-life. Re-exported from `base/utils/decay.ts`. */\nexport { DEFAULT_DECAY_RATE } from \"../../base/utils/decay.js\";\n\n// ---------------------------------------------------------------------------\n// Strategy model\n// ---------------------------------------------------------------------------\n\n/**\n * Canonical 3-axis composite-key factory: `${presetId}|${rootCause}→${intervention}`.\n *\n * **Phase 13.I axis extension (DS-13.I, 2026-05-01).** Pre-multi-agent\n * callers without a preset registry pass {@link DEFAULT_PRESET_ID}\n * (`\"default\"`) for the first arg. Pre-1.0 breaking signature change;\n * persisted strategy-model snapshots from before this date are NOT portable.\n */\nexport function strategyKey(\n\tpresetId: PresetId,\n\trootCause: RootCause,\n\tintervention: Intervention,\n): StrategyKey {\n\treturn `${presetId}|${rootCause}→${intervention}`;\n}\n\n// ---------------------------------------------------------------------------\n// Error classifier\n// ---------------------------------------------------------------------------\n\n/**\n * Regex-word-boundary match over a closed keyword set. Callers needing\n * domain-specific failure modes should supply a custom\n * {@link ErrorClassifier}; this default exists so zero-config harness runs\n * still distinguish parse-class failures (fast-retry) from everything\n * else (full loop via reingestion).\n */\nconst SELF_CORRECTABLE_RE = /\\b(parse|json|config|validation|syntax)\\b/i;\n\n/** Default error classifier: parse/config errors are self-correctable. */\nexport const defaultErrorClassifier: ErrorClassifier = (result: ExecutionResult): ErrorClass =>\n\tSELF_CORRECTABLE_RE.test(result.detail) ? \"self-correctable\" : \"structural\";\n\n// ---------------------------------------------------------------------------\n// Default stage prompts\n// ---------------------------------------------------------------------------\n\n/** Default TRIAGE prompt — LLM classifies intake items into root-cause + intervention + route + priority. */\nexport const DEFAULT_TRIAGE_PROMPT = `You are a triage classifier for a reactive collaboration harness.\n\nGiven an intake item, classify it and output JSON:\n{\n \"rootCause\": \"composition\" | \"missing-fn\" | \"bad-docs\" | \"schema-gap\" | \"regression\" | \"unknown\",\n \"intervention\": \"template\" | \"catalog-fn\" | \"docs\" | \"wrapper\" | \"schema-change\" | \"investigate\",\n \"route\": \"auto-fix\" | \"needs-decision\" | \"investigation\" | \"backlog\",\n \"priority\": <number 0-100>,\n \"triageReasoning\": \"<one sentence>\"\n}\n\nStrategy model (past effectiveness):\n{{strategy}}\n\nIntake item:\n{{item}}`;\n\n/** Default EXECUTE prompt — LLM produces a fix given a triaged issue. */\nexport const DEFAULT_EXECUTE_PROMPT = `You are an implementation agent.\n\nGiven a triaged issue with root cause and intervention type, produce a fix.\n\nIssue:\n{{item}}\n\nOutput JSON:\n{\n \"outcome\": \"success\" | \"failure\" | \"partial\",\n \"detail\": \"<description of what was done or what failed>\"\n}`;\n\n/** Default VERIFY prompt — LLM reviews an execution result against the original issue. */\nexport const DEFAULT_VERIFY_PROMPT = `You are a QA reviewer.\n\nGiven an execution result, verify whether the fix is correct.\n\nExecution:\n{{execution}}\n\nOriginal issue:\n{{item}}\n\nOutput JSON:\n{\n \"verified\": true/false,\n \"findings\": [\"<finding1>\", ...],\n \"errorClass\": \"self-correctable\" | \"structural\" // only if verified=false\n}`;\n\n// ---------------------------------------------------------------------------\n// Prompt resolver helper\n// ---------------------------------------------------------------------------\n\n/**\n * Collapse the `string | ((input: In) => string) | undefined` prompt-template\n * pattern into a single `(input: In) => string`. A function `raw` is used as-is\n * (the caller opted into full control). Otherwise `raw ?? fallbackTemplate`\n * is fed through `substitute`, which does the placeholder replacement.\n *\n * Used by the three harness stages (TRIAGE / EXECUTE / VERIFY), which each\n * accept a `string | function` config but use different placeholder schemes\n * (`{{item}}`, `{{execution}}`, `{{strategy}}`). The helper absorbs only the\n * branch logic; the per-stage placeholder substitution lives at the call site.\n */\nexport function resolvePromptFn<In>(\n\traw: string | ((input: In) => string) | undefined,\n\tfallbackTemplate: string,\n\tsubstitute: (template: string, input: In) => string,\n): (input: In) => string {\n\tif (typeof raw === \"function\") return raw;\n\tconst template = raw ?? fallbackTemplate;\n\treturn (input) => substitute(template, input);\n}\n","/**\n * Strategy model and priority scoring (roadmap §9.0).\n *\n * `strategyModel` returns a typed alias of {@link AuditedSuccessTrackerGraph}\n * keyed by `StrategyKey` (the composite `rootCause→intervention` string).\n * The shared substrate (Class B audit Alt E collapse, 2026-04-30) replaces\n * the prior bespoke bundle shape; composite-key callers use {@link strategyKey}\n * to compute the key and pass `{ rootCause, intervention }` as record decoration.\n *\n * @module\n */\n\nimport { monotonicNs, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { decay } from \"../../base/utils/decay.js\";\nimport {\n\ttype AuditedSuccessTrackerGraph,\n\tauditedSuccessTracker,\n} from \"../orchestration/audited-success-tracker.js\";\n\nimport {\n\tDEFAULT_DECAY_RATE,\n\tDEFAULT_PRESET_ID,\n\tDEFAULT_SEVERITY_WEIGHTS,\n\ttype PrioritySignals,\n\ttype StrategyEntry,\n\ttype StrategyKey,\n\tstrategyKey,\n\ttype TriagedItem,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Strategy model\n// ---------------------------------------------------------------------------\n\n/** Snapshot shape for the strategy-model `entries` node. */\nexport type StrategySnapshot = ReadonlyMap<StrategyKey, StrategyEntry>;\n\n/** Strategy-model graph: a typed alias of {@link AuditedSuccessTrackerGraph}. */\nexport type StrategyModelGraph = AuditedSuccessTrackerGraph<StrategyKey, StrategyEntry>;\n\n/**\n * Create a strategy model that tracks\n * `presetId × rootCause × intervention → successRate` over completed\n * issues (presetId axis added in Phase 13.I, 2026-05-01). Returns an\n * {@link AuditedSuccessTrackerGraph} keyed by {@link StrategyKey}.\n *\n * The reactive `entries` field is a `Node<StrategySnapshot>` suitable for\n * `describe()` / `withLatestFrom` composition.\n *\n * Composite-key conversion happens at the call site:\n * ```ts\n * const strategy = strategyModel();\n * strategy.record(strategyKey(presetId, rootCause, intervention), success, {\n * presetId,\n * rootCause,\n * intervention,\n * });\n * strategy.lookup(strategyKey(presetId, rootCause, intervention));\n * ```\n *\n * Pass {@link DEFAULT_PRESET_ID} (`\"default\"`) for the presetId axis when\n * no preset registry is wired (single-agent harness).\n *\n * The model feeds back into TRIAGE for routing hints.\n */\nexport function strategyModel(): StrategyModelGraph {\n\treturn auditedSuccessTracker<StrategyKey, StrategyEntry>({ name: \"strategy\" });\n}\n\n// ---------------------------------------------------------------------------\n// Priority scoring\n// ---------------------------------------------------------------------------\n\n/**\n * Create a priority scoring derived node for a single triaged item.\n *\n * Combines severity weight, attention decay, strategy model effectiveness,\n * and an optional external urgency signal.\n *\n * **Age sampling caveat.** The `ageSeconds` term is computed as\n * `monotonicNs() - lastInteractionNs.cache` at *each reactive update*. If\n * nothing upstream settles, the score node does not recompute — so a\n * long-idle queue may show a stale score. Pass a `fromTimer(...)`-driven\n * node as a dep (or re-emit on `lastInteractionNs`) when live age decay\n * matters.\n *\n * **Not the same as `TriagedItem.priority`.** The LLM-emitted\n * `priority: 0..100` field on each triaged item is decorative today — the\n * queue consumption order ignores it (tracked in `docs/optimizations.md`\n * as a priority-ordered queue enhancement). This function computes an\n * orthogonal reactive score; it does NOT override the LLM's per-item\n * priority, nor does it drive queue ordering. Wire it to\n * `HarnessGraph.priorityScores` to surface per-route pressure.\n *\n * @param item - Node holding the triaged item.\n * @param strategy - Strategy model node.\n * @param lastInteractionNs - Node holding the monotonic timestamp (ns) of last human interaction.\n * @param urgency - Optional external urgency signal node (0–1 scale).\n * @param signals - Configurable scoring parameters.\n */\nexport function priorityScore(\n\titem: Node<TriagedItem>,\n\tstrategy: Node<StrategySnapshot>,\n\tlastInteractionNs: Node<number>,\n\turgency?: Node<number>,\n\tsignals?: PrioritySignals,\n): Node<number> {\n\tconst severityWeights = { ...DEFAULT_SEVERITY_WEIGHTS, ...signals?.severityWeights };\n\tconst decayRate = signals?.decayRate ?? DEFAULT_DECAY_RATE;\n\tconst effectivenessThreshold = signals?.effectivenessThreshold ?? 0.7;\n\tconst effectivenessBoost = signals?.effectivenessBoost ?? 15;\n\n\tconst deps: Node<unknown>[] = [item, strategy, lastInteractionNs];\n\tif (urgency) deps.push(urgency);\n\n\treturn node<number>(\n\t\tdeps,\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst values = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst itm = values[0] as TriagedItem;\n\t\t\tconst strat = values[1] as StrategySnapshot;\n\t\t\tconst lastNs = values[2] as number;\n\t\t\tconst urg = urgency ? (values[3] as number) : 0;\n\n\t\t\t// Base score from severity\n\t\t\tconst baseWeight = severityWeights[itm.severity ?? \"medium\"];\n\t\t\tconst ageSeconds = (monotonicNs() - lastNs) / 1e9;\n\t\t\tlet score = decay(baseWeight, ageSeconds, decayRate, 0);\n\n\t\t\t// Strategy model boost\n\t\t\tconst key = strategyKey(DEFAULT_PRESET_ID, itm.rootCause, itm.intervention);\n\t\t\tconst entry = strat.get(key);\n\t\t\tif (entry && entry.successRate >= effectivenessThreshold) {\n\t\t\t\tscore += effectivenessBoost;\n\t\t\t}\n\n\t\t\t// External urgency boost (0–1 scale → 0–20 points)\n\t\t\tscore += urg * 20;\n\n\t\t\tactions.emit(score);\n\t\t},\n\t\t{ name: \"priority-score\", describeKind: \"derived\" },\n\t);\n}\n","/**\n * `auditedSuccessTracker` — domain-agnostic per-key success-rate tracker.\n *\n * Reactive `key → { attempts, successes, successRate }` map mounted as a\n * Graph subclass. Reusable substrate for any domain that needs to track\n * outcomes per identifier (routing strategy effectiveness, A/B-test arms,\n * cache-policy tuning, retry-strategy selection, etc.).\n *\n * Replaces the prior `effectivenessTracker` and `strategyModel` factories\n * (Class B audit Alt E collapse, 2026-04-30). Composite-key callers (e.g.\n * `rootCause × intervention`) convert to a string key at the call site.\n *\n * @module\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { keepalive, type ReactiveMapBundle, reactiveMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\n\n/** A single success-rate record for one key. */\nexport interface AuditedSuccessEntry<TKey extends string = string> {\n\treadonly key: TKey;\n\treadonly attempts: number;\n\treadonly successes: number;\n\treadonly successRate: number;\n}\n\n/** Snapshot shape — fresh `ReadonlyMap` on every mutation. */\nexport type AuditedSuccessSnapshot<\n\tTKey extends string = string,\n\tTEntry extends AuditedSuccessEntry<TKey> = AuditedSuccessEntry<TKey>,\n> = ReadonlyMap<TKey, TEntry>;\n\n/** Options for {@link auditedSuccessTracker}. */\nexport interface AuditedSuccessTrackerOptions {\n\t/** Optional graph identity (passed to the underlying Graph constructor). */\n\tgraph?: GraphOptions;\n\t/** Name of the tracker subgraph. Default `\"audited-success-tracker\"`. */\n\tname?: string;\n}\n\n/**\n * Reactive success-rate tracker mounted as a Graph subclass.\n *\n * `key → AuditedSuccessEntry` with `record(key, success, extra?)` /\n * `lookup(key)` methods. The {@link entries} field is a\n * `Node<ReadonlyMap<TKey, TEntry>>` suitable for graph composition —\n * exposed under name `\"entries\"` for `describe()` / `explain()`.\n *\n * Backed by the {@link reactiveMap} substrate; each successful `record(...)`\n * fires a DATA emission carrying the post-mutation map.\n *\n * **Field name.** This Graph subclass uses `entries` (not `snapshot`) for\n * the public-face Node because `Graph.prototype.snapshot()` is the\n * built-in persistence-snapshot method on the parent class — using\n * `snapshot` here would shadow it and break DTS generation.\n *\n * @typeParam TKey - String-typed key shape. Composite-key domains (e.g.\n * `rootCause × intervention`) convert to a string at the call site.\n * @typeParam TEntry - Entry shape; defaults to {@link AuditedSuccessEntry}.\n * Domains that need extra fields (e.g. `rootCause`/`intervention`) extend\n * this interface and pass the extra fields via `record(...)`'s `extra` arg.\n */\nexport class AuditedSuccessTrackerGraph<\n\tTKey extends string = string,\n\tTEntry extends AuditedSuccessEntry<TKey> = AuditedSuccessEntry<TKey>,\n> extends Graph {\n\t/** Reactive entries — `Node<ReadonlyMap<TKey, TEntry>>`, fresh map per mutation. */\n\treadonly entries: Node<AuditedSuccessSnapshot<TKey, TEntry>>;\n\n\tprivate readonly _map: ReactiveMapBundle<TKey, TEntry>;\n\n\tconstructor(opts?: AuditedSuccessTrackerOptions) {\n\t\tsuper(opts?.name ?? \"audited-success-tracker\", opts?.graph);\n\t\tthis._map = reactiveMap<TKey, TEntry>({ name: \"entries\" });\n\t\tthis.entries = this._map.entries;\n\t\tthis.add(this.entries, { name: \"entries\" });\n\n\t\t// Keep the entries node activated without external subscribers so\n\t\t// `tracker.entries.cache` is readable from sync code paths and\n\t\t// `lookup()` callers don't have to manage subscriptions. Released on\n\t\t// Graph dispose along with the underlying reactiveMap.\n\t\tthis.addDisposer(keepalive(this.entries));\n\t\tthis.addDisposer(() => this._map.dispose());\n\t}\n\n\t/**\n\t * Record a completed attempt. `extra` fields are merged into the stored\n\t * entry — use for domain-specific decoration (e.g. `{ rootCause,\n\t * intervention }` on the strategy-model collapse path).\n\t *\n\t * **Caller contract for typed `TEntry`.** When `TEntry` extends\n\t * {@link AuditedSuccessEntry} with required fields beyond\n\t * `key`/`attempts`/`successes`/`successRate`, the caller must supply\n\t * those required fields in `extra` on the **first** `record(key, ...)`\n\t * for that key. The internal `as TEntry` cast trusts this. Subsequent\n\t * `record(key, ...)` calls inherit the prior entry's fields, so `extra`\n\t * may be omitted or partial. Forgetting required fields on the first\n\t * record produces an entry whose typed-required fields are `undefined`\n\t * at runtime — TS won't catch it. Strategy callers always pass\n\t * `{ rootCause, intervention }`, so the StrategyEntry case is safe.\n\t */\n\trecord(\n\t\tkey: TKey,\n\t\tsuccess: boolean,\n\t\textra?: Partial<Omit<TEntry, \"key\" | \"attempts\" | \"successes\" | \"successRate\">>,\n\t): void {\n\t\tconst existing = this._map.get(key);\n\t\tconst attempts = (existing?.attempts ?? 0) + 1;\n\t\tconst successes = (existing?.successes ?? 0) + (success ? 1 : 0);\n\t\tthis._map.set(key, {\n\t\t\t...(existing ?? {}),\n\t\t\t...(extra ?? {}),\n\t\t\tkey,\n\t\t\tattempts,\n\t\t\tsuccesses,\n\t\t\tsuccessRate: successes / attempts,\n\t\t} as TEntry);\n\t}\n\n\t/**\n\t * Look up the entry for a key.\n\t *\n\t * Pure read: this tracker doesn't configure a TTL on the underlying\n\t * `reactiveMap`, so `_map.get(key)` never triggers TTL-expiry pruning\n\t * (which would otherwise be an observable side effect emitting a fresh\n\t * `entries` snapshot). If `AuditedSuccessTrackerOptions` ever gains a\n\t * `mapOptions` carve-out exposing TTL, revisit this contract.\n\t */\n\tlookup(key: TKey): TEntry | undefined {\n\t\treturn this._map.get(key);\n\t}\n}\n\n/**\n * Construct an {@link AuditedSuccessTrackerGraph}. Replaces the prior\n * `effectivenessTracker()` and `strategyModel()` factories.\n *\n * @example\n * ```ts\n * // Generic per-action tracker\n * const tracker = auditedSuccessTracker({ name: \"ab-test\" });\n * tracker.record(\"variant-a\", true);\n * tracker.record(\"variant-b\", false);\n * tracker.entries.subscribe(snap => console.log(snap.get(\"variant-a\")));\n *\n * // Composite-key (rootCause × intervention) tracker — caller computes the key\n * type StrategyEntry = AuditedSuccessEntry<StrategyKey> & {\n * rootCause: RootCause;\n * intervention: Intervention;\n * };\n * const strategy = auditedSuccessTracker<StrategyKey, StrategyEntry>({\n * name: \"strategy\",\n * });\n * strategy.record(\n * strategyKey(rootCause, intervention),\n * true,\n * { rootCause, intervention },\n * );\n * ```\n *\n * @category extra\n */\nexport function auditedSuccessTracker<\n\tTKey extends string = string,\n\tTEntry extends AuditedSuccessEntry<TKey> = AuditedSuccessEntry<TKey>,\n>(opts?: AuditedSuccessTrackerOptions): AuditedSuccessTrackerGraph<TKey, TEntry> {\n\treturn new AuditedSuccessTrackerGraph<TKey, TEntry>(opts);\n}\n","/**\n * Harness wiring types (roadmap §9.0).\n *\n * Shared types for the reactive collaboration loop: intake, triage, queue,\n * gate, execute, verify, reflect. These types are intentionally domain-agnostic\n * — the harness loop is not specific to eval workflows.\n *\n * Runtime constants and helpers live in `./defaults.ts`. The harness barrel\n * (`./index.ts`) re-exports both so external consumers see a single surface.\n *\n * @module\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { NodeInput } from \"@graphrefly/pure-ts/extra\";\n// Type-only import avoids a runtime cycle with `patterns/ai`.\nimport type { LLMAdapter } from \"../ai/index.js\";\nimport type { JobEnvelope } from \"../job-queue/index.js\";\n\n// ---------------------------------------------------------------------------\n// Intake\n// ---------------------------------------------------------------------------\n\n/** Known intake source tags. */\nexport type KnownIntakeSource = \"eval\" | \"test\" | \"human\" | \"code-change\" | \"hypothesis\" | \"parity\";\n\n/**\n * Sources that can produce intake items. Open union — the known tags\n * retain IDE autocomplete while user-supplied strings (e.g. `\"schema\"`,\n * `\"slack\"`) pass through without a type change.\n */\nexport type IntakeSource = KnownIntakeSource | (string & {});\n\n/** Severity levels for intake items. */\nexport type Severity = \"critical\" | \"high\" | \"medium\" | \"low\";\n\n/** Root cause categories for triage classification. */\nexport type RootCause =\n\t| \"composition\"\n\t| \"missing-fn\"\n\t| \"bad-docs\"\n\t| \"schema-gap\"\n\t| \"regression\"\n\t| \"unknown\";\n\n/** Intervention types that address root causes. */\nexport type Intervention =\n\t| \"template\"\n\t| \"catalog-fn\"\n\t| \"docs\"\n\t| \"wrapper\"\n\t| \"schema-change\"\n\t| \"investigate\";\n\n/** Routing destinations after triage. Closed union — iterated via `QUEUE_NAMES`. */\nexport type QueueRoute = \"auto-fix\" | \"needs-decision\" | \"investigation\" | \"backlog\";\n\n/**\n * An item entering the harness loop via the INTAKE stage.\n *\n * All intake sources produce this uniform shape — the intake topic\n * doesn't care where items came from.\n *\n * `$`-prefix keys (`$reingestions`, `$retries` on {@link TriagedItem}) are\n * framework-only — an LLM round-tripping the serialized item is far less\n * likely to echo back a `$`-prefixed key than an `_`-prefixed one, which\n * neutralizes the field-collision class that surfaced earlier in the\n * router's spread order.\n */\nexport interface IntakeItem {\n\tsource: IntakeSource;\n\tsummary: string;\n\tevidence: string;\n\taffectsAreas: string[];\n\taffectsEvalTasks?: string[];\n\tseverity?: Severity;\n\t/**\n\t * Identity-preservation key for retried / reingested items.\n\t *\n\t * `relatedTo[0]` MUST carry the original tracking key for retry /\n\t * reingest items so the harness's `routeJobIds` map preserves\n\t * identity across decorated retry summaries (per qa D1, 2026-04-29).\n\t * First-time publishes leave this `undefined`; the tracking key\n\t * falls back to `summary` via {@link trackingKey}.\n\t *\n\t * **Collision contract (DS-13.5.D.3, locked 2026-05-01).** Items\n\t * lacking `relatedTo[0]` and producing colliding `trackingKey()`\n\t * derivations overwrite the prior `routeJobIds` entry —\n\t * **last-write-wins**. Framework-enforced uniqueness was rejected\n\t * because it would break legitimate retry / reingest patterns where\n\t * an explicit `relatedTo[0]` carries the original key forward.\n\t *\n\t * **Single-threaded contract.** Ack runs before reingest publishes\n\t * (harness flow invariant) — under the standard single-threaded JS\n\t * pump this collapses the only practical race window. Multi-publisher\n\t * concurrency or batched intake of two first-time items with identical\n\t * `summary` can still race at boundaries; callers carrying their own\n\t * stable id should set `relatedTo[0]`.\n\t *\n\t * See {@link trackingKey} JSDoc in `patterns/_internal/index.ts` for\n\t * the uniqueness caller contract.\n\t *\n\t * Spec: docs/implementation-plan.md DS-13.5.D.3\n\t */\n\trelatedTo?: string[];\n\t/** Item-carried reingestion count. Incremented on each full-loop reingestion. */\n\t$reingestions?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Triage output\n// ---------------------------------------------------------------------------\n\n/** Output of the TRIAGE stage — enriched intake item with classification. */\nexport interface TriagedItem extends IntakeItem {\n\trootCause: RootCause;\n\tintervention: Intervention;\n\troute: QueueRoute;\n\tpriority: number;\n\ttriageReasoning?: string;\n\t/** Item-carried retry count. Incremented on each fast-retry pass. */\n\t$retries?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Strategy model\n// ---------------------------------------------------------------------------\n\n/**\n * Preset / persona / skill identifier. Open string set; conventionally\n * matches keys used in {@link presetRegistry} (Phase 13.H). Use\n * {@link DEFAULT_PRESET_ID} (\"default\") when no preset registry is wired.\n */\nexport type PresetId = string;\n\n/** Default presetId used when no preset registry is wired (back-compat for 2-axis callers). */\nexport const DEFAULT_PRESET_ID: PresetId = \"default\";\n\n/**\n * Key format: `${presetId}|${rootCause}→${intervention}`.\n *\n * **Phase 13.I axis extension (DS-13.I, 2026-05-01).** Widened from the\n * pre-multi-agent 2-axis `${rootCause}→${intervention}` to a 3-axis key\n * carrying the presetId of the agent that ran. Pre-1.0 breaking change;\n * existing callsites pass {@link DEFAULT_PRESET_ID} for the new axis when\n * they don't have a preset registry wired. The strategy-model storage\n * (`auditedSuccessTracker<StrategyKey, StrategyEntry>`) is unchanged\n * structurally — the key shape change cascades through the existing\n * tracker without surface refactor.\n */\nexport type StrategyKey = `${PresetId}|${RootCause}→${Intervention}`;\n\n/**\n * Effectiveness record for a `(presetId, rootCause, intervention)` triple.\n * Stored under `auditedSuccessTracker<StrategyKey, StrategyEntry>` (Class B\n * audit Alt E collapse, 2026-04-30; presetId axis added Phase 13.I,\n * 2026-05-01) — `key` is the composite `strategyKey(presetId, rc, intv)`\n * computed at the call site; `presetId` / `rootCause` / `intervention` are\n * decoration carried via `record(...)` so consumers can read them without\n * re-parsing the key.\n */\nexport interface StrategyEntry {\n\tkey: StrategyKey;\n\tpresetId: PresetId;\n\trootCause: RootCause;\n\tintervention: Intervention;\n\tattempts: number;\n\tsuccesses: number;\n\tsuccessRate: number;\n}\n\n// ---------------------------------------------------------------------------\n// Execution & verification\n// ---------------------------------------------------------------------------\n\n/**\n * LLM output shape from the EXECUTE stage (partial — lacks `item`).\n *\n * Generic over the artifact type `A` so typed executors like\n * `refineExecutor<T>` can flow `T` through to an `evalVerifier<T>` without\n * the caller casting `artifact` at the boundary. Defaults to `unknown`\n * for escape-hatch executors that carry opaque state.\n */\nexport type ExecuteOutput<A = unknown> = {\n\t/**\n\t * Execution outcome classification:\n\t *\n\t * - `\"success\"`: execution completed cleanly and the artifact (if any) is\n\t * ready for verification. The verifier should proceed with a full\n\t * evaluation pass.\n\t * - `\"failure\"`: execution did not produce a usable artifact — the actuator\n\t * threw, a prompt parse failed, or `shouldApply` skipped the item. The\n\t * verifier should treat this as a non-result and route accordingly.\n\t * - `\"partial\"`: execution produced a candidate that converged but did not\n\t * fully meet verification criteria. Used by `refineExecutor` when the\n\t * iteration cap is reached without full convergence; the artifact holds\n\t * the best candidate achieved.\n\t */\n\toutcome: \"success\" | \"failure\" | \"partial\";\n\tdetail: string;\n\t/**\n\t * Optional opaque artifact that a custom executor (e.g. `refineExecutor`)\n\t * may attach so downstream verifiers can re-run evaluation against the\n\t * thing that was produced. LLM-backed default executors never populate\n\t * this — it's an escape hatch for reactive executors carrying structured\n\t * output (a refined prompt, a patched spec, a generated template, ...).\n\t */\n\tartifact?: A;\n};\n\n/** Full execution result assembled downstream (LLM output + context). */\nexport interface ExecutionResult<A = unknown> {\n\titem: TriagedItem;\n\t/**\n\t * Execution outcome classification. Same semantics as\n\t * {@link ExecuteOutput.outcome}:\n\t *\n\t * - `\"success\"`: execution completed cleanly; artifact is ready for\n\t * verification.\n\t * - `\"failure\"`: no usable artifact was produced.\n\t * - `\"partial\"`: best candidate produced but convergence criteria not met\n\t * (iteration cap reached in `refineExecutor`).\n\t */\n\toutcome: \"success\" | \"failure\" | \"partial\";\n\tdetail: string;\n\t/**\n\t * Passthrough of {@link ExecuteOutput.artifact} when the executor emitted\n\t * one. Reactive executors like `refineExecutor` populate this; LLM-backed\n\t * default executors leave it undefined.\n\t */\n\tartifact?: A;\n}\n\n/** Whether an error is self-correctable (fast-retry) or structural (full loop). */\nexport type ErrorClass = \"self-correctable\" | \"structural\";\n\n/** Classifier for fast-retry path. */\nexport type ErrorClassifier = (result: ExecutionResult) => ErrorClass;\n\n// ---------------------------------------------------------------------------\n// Verification output\n// ---------------------------------------------------------------------------\n\n/** Result of the VERIFY stage. */\nexport interface VerifyResult<A = unknown> {\n\titem: TriagedItem;\n\texecution: ExecutionResult<A>;\n\tverified: boolean;\n\tfindings: string[];\n\terrorClass?: ErrorClass;\n}\n\n/**\n * Verifier output shape — what a custom verifier emits. The harness\n * assembles this into the full {@link VerifyResult} using the triaged\n * item + execute output sampled from `executeContextNode`.\n */\nexport interface VerifyOutput {\n\tverified: boolean;\n\tfindings: string[];\n\terrorClass?: ErrorClass;\n}\n\n// ---------------------------------------------------------------------------\n// Priority scoring\n// ---------------------------------------------------------------------------\n\n/** Configurable signals for priority scoring. */\nexport interface PrioritySignals {\n\t/** Per-severity base weight (default: critical=100, high=70, medium=40, low=10). */\n\tseverityWeights?: Partial<Record<Severity, number>>;\n\t/** Decay rate per second for attention decay (default ~1.15e-6 ≈ 7-day half-life). */\n\tdecayRate?: number;\n\t/** Strategy model effectiveness boost threshold (default 0.7). */\n\teffectivenessThreshold?: number;\n\t/** Strategy model effectiveness boost amount (default 15). */\n\teffectivenessBoost?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Harness loop configuration\n// ---------------------------------------------------------------------------\n\nimport type { StrategySnapshot } from \"./strategy.js\";\n\n/** Per-queue configuration in the harness loop. */\nexport interface QueueConfig {\n\t/** Whether this queue is gated (requires human approval). */\n\tgated: boolean;\n\t/** Maximum pending items in the gate (default Infinity). */\n\tmaxPending?: number;\n\t/** Start the gate in open (auto-approve) mode? Only meaningful when `gated: true`. */\n\tstartOpen?: boolean;\n}\n\n/**\n * Accumulating per-job payload threaded through the harness's\n * `executeFlow` ({@link harnessLoop} Tier 6.5 C2 lock). Each stage's work fn\n * receives the prior payload and returns a new one with its own field\n * filled in:\n *\n * - The `enqueueEffect` seeds with `{ item }` only.\n * - The execute work fn fills `execution`.\n * - The verify work fn fills `verify`.\n *\n * The post-completed dispatch effect reads `verify.verified` /\n * `verify.errorClass` to route the item to `verifyResults` /\n * `retryTopic.publish(...)` / `intake.publish(...)` (3-way verdict).\n *\n * Carrying `item` through stage payloads (rather than re-pairing via a\n * separate `withLatestFrom` node) is the C2 deviation from today's\n * `executeContextNode` design: each `JobEnvelope` is self-contained, so the\n * verify pump can run multiple in-flight jobs in parallel without an\n * external pairing node.\n */\nexport interface HarnessJobPayload<A = unknown> {\n\t/** The triaged item flowing through execute → verify → dispatch. */\n\titem: TriagedItem;\n\t/** Filled by the execute work fn. Verify reads this; dispatch routes. */\n\texecution?: ExecutionResult<A>;\n\t/** Filled by the verify work fn. Dispatch reads `verified` / `errorClass`. */\n\tverify?: VerifyOutput;\n}\n\n/**\n * Pluggable EXECUTE work fn — receives a {@link JobEnvelope} carrying a\n * {@link HarnessJobPayload} (with `item` set, `execution` / `verify`\n * unset), returns a {@link NodeInput} that emits the same payload with\n * `execution` filled.\n *\n * **C2 contract (Tier 6.5 lock, 2026-04-28):**\n * 1. Emit DATA exactly once per claimed job. The JobFlow pump subscribes\n * once, takes the first DATA, then unsubscribes. Subsequent emissions\n * are ignored.\n * 2. Errors must be caught and surfaced as a `failure` outcome inside the\n * payload — never throw / return ERROR. A pump nack would drop the\n * item from JobFlow before the dispatch effect could route it.\n * 3. The work fn runs once per claim — no internal `switchMap` needed.\n * Per-item subgraphs (e.g. a fresh `refineLoop` per claim) are\n * instantiated inside the work fn body.\n *\n * `defaultLlmExecutor` (in `defaults.ts`) is a thin `adapter.invoke()`\n * wrapper. `refineExecutor` builds a per-claim `refineLoop`.\n * `actuatorExecutor` runs a side-effecting `apply(item, signal)`.\n */\nexport type HarnessExecutor<A = unknown> = (\n\tjob: JobEnvelope<HarnessJobPayload<A>>,\n\topts?: { signal: AbortSignal },\n) => NodeInput<HarnessJobPayload<A>>;\n\n/**\n * Pluggable VERIFY work fn — receives a {@link JobEnvelope} whose payload\n * has `item` + `execution` populated, returns a {@link NodeInput} that\n * emits the same payload with `verify` filled.\n *\n * Same C2 contract rules 1–3 as {@link HarnessExecutor}. The dispatch\n * effect downstream reads `verify.verified` (success → ack +\n * verifyResults publish), `verify.errorClass === \"self-correctable\"`\n * (retry → republish to retry topic with `$retries` bumped), or anything\n * else (structural → reingest to intake if budget remains).\n *\n * Verify-LLM-call failures (parse error, adapter throw, timeout) MUST be\n * caught and surfaced as a structural-failure `verify` payload (`{\n * verified: false, findings: [...], errorClass: \"structural\" }`) so the\n * dispatch effect can route the item rather than silently drop it.\n */\nexport type HarnessVerifier<A = unknown> = (\n\tjob: JobEnvelope<HarnessJobPayload<A>>,\n\topts?: { signal: AbortSignal },\n) => NodeInput<HarnessJobPayload<A>>;\n\n/** Triage prompt callable shape — pair of `[intake item, strategy snapshot]`. */\nexport type TriagePromptFn = (pair: readonly [IntakeItem, StrategySnapshot]) => string;\n/** Execute prompt callable shape. */\nexport type ExecutePromptFn = (item: TriagedItem) => string;\n/** Verify prompt callable shape — pair of `[execute output, triaged item]`. */\nexport type VerifyPromptFn<A = unknown> = (\n\tpair: readonly [ExecuteOutput<A> | null, TriagedItem | null],\n) => string;\n\n/** Options for {@link harnessLoop}. */\nexport interface HarnessLoopOptions<A = unknown> {\n\t/** LLM adapter for promptNode-based stages (triage + any default executor/verifier). */\n\tadapter: LLMAdapter;\n\n\t/** Custom triage prompt (receives IntakeItem + strategy snapshot as a tuple). */\n\ttriagePrompt?: string | TriagePromptFn;\n\n\t/**\n\t * Execute prompt — sugar over the default LLM executor. Ignored when\n\t * `executor` is set.\n\t */\n\texecutePrompt?: string | ExecutePromptFn;\n\n\t/**\n\t * Verify prompt — sugar over the default LLM verifier. Ignored when\n\t * `verifier` is set.\n\t */\n\tverifyPrompt?: string | VerifyPromptFn<A>;\n\n\t/**\n\t * Pluggable EXECUTE slot. When omitted, the harness uses a `promptNode`\n\t * driven by `adapter` + `executePrompt`. Replace to plug in a\n\t * `refineExecutor`, tool-using agent, or any reactive execution pipeline.\n\t */\n\texecutor?: HarnessExecutor<A>;\n\n\t/**\n\t * Pluggable VERIFY slot. When omitted, the harness uses a `promptNode`\n\t * driven by `adapter` + `verifyPrompt`. Replace to plug in an\n\t * `evalVerifier` that re-runs affected eval tasks.\n\t */\n\tverifier?: HarnessVerifier<A>;\n\n\t/** Per-queue configuration overrides. */\n\tqueues?: Partial<Record<QueueRoute, QueueConfig>>;\n\n\t/** Priority scoring signals. */\n\tpriority?: PrioritySignals;\n\n\t/**\n\t * Reactive last-human-interaction timestamp (monotonic ns). Drives the\n\t * priority score age-decay term for `HarnessGraph.priorityScores`.\n\t *\n\t * **Required when `opts.priority` is set.** Priority score nodes only\n\t * re-derive when `topic.latest`, `strategy.snapshot`, or this tick settles —\n\t * an idle queue would freeze its age at construction time if we\n\t * auto-defaulted. Typical sources:\n\t * - `fromTimer(60_000)` — steady tick, uniform decay.\n\t * - `state(monotonicNs())` — bumped from a human-interaction handler.\n\t * - A reactive view over a DB column / external metrics source.\n\t */\n\tlastInteractionNs?: Node<number>;\n\n\t/** Error classifier for fast-retry path. */\n\terrorClassifier?: ErrorClassifier;\n\n\t/** Max fast-retries per item before routing to full intake (default 2). */\n\tmaxRetries?: number;\n\n\t/** Global retry cap across all items — circuit breaker (default maxRetries × 10). */\n\tmaxTotalRetries?: number;\n\n\t/** Max re-ingestions from verify→intake before giving up (default 1). */\n\tmaxReingestions?: number;\n\n\t/** Global reingestion cap across all items — circuit breaker (default maxReingestions × 10). */\n\tmaxTotalReingestions?: number;\n\n\t/** Retained limit for topic logs (default 1000). */\n\tretainedLimit?: number;\n\n\t/**\n\t * Per-pump-tick claim cap on the internal `executeFlow` JobFlow's `execute`\n\t * stage (Tier 6.5 C2). Default `Number.MAX_SAFE_INTEGER` — every pending\n\t * claim is processed in one tick (matches today's unbounded `merge()`\n\t * parallelism). Lower this to bound LLM cost spikes on bursty intake.\n\t *\n\t * **Caveat.** This caps **claims per pump tick**, not total concurrent\n\t * inflight. Bounded-inflight is a separate primitive concern — see\n\t * `docs/optimizations.md` \"Tier 6.5 follow-up — bounded concurrent inflight\n\t * on JobFlow stages\".\n\t */\n\texecuteMaxPerPump?: number;\n\n\t/**\n\t * Per-pump-tick claim cap on the internal `executeFlow` JobFlow's\n\t * `verify` stage. Default `Number.MAX_SAFE_INTEGER`. Same caveat as\n\t * {@link HarnessLoopOptions.executeMaxPerPump}. Honored independently\n\t * of the execute cap via `StageDef.maxPerPump` (Tier 6.5 D1).\n\t */\n\tverifyMaxPerPump?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Barrel re-exports from defaults.ts — preserves the pre-split import\n// surface (`import { QUEUE_NAMES, defaultErrorClassifier } from \".../types\"`).\n// ---------------------------------------------------------------------------\n\nexport {\n\tDEFAULT_DECAY_RATE,\n\tDEFAULT_QUEUE_CONFIGS,\n\tDEFAULT_SEVERITY_WEIGHTS,\n\tdefaultErrorClassifier,\n\tQUEUE_NAMES,\n\tstrategyKey,\n} from \"./defaults.js\";\n","/**\n * Job queue patterns (roadmap §4.2).\n *\n * Queue / flow primitives modeled as graph factories:\n * - `jobQueue()` — claim/ack/nack workflow with reactive depth.\n * - `jobFlow()` — multi-stage queue chain.\n *\n * Topic / subscription / hub primitives live in `patterns/messaging`.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tERROR,\n\ttype Node,\n\tnode,\n\tplaceholderArgs,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport type { AppendLogStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport {\n\tfromAny,\n\tkeepalive,\n\ttype NodeInput,\n\ttype ReactiveLogBundle,\n\treactiveList,\n\treactiveLog,\n\treactiveMap,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\nimport {\n\ttype BaseAuditRecord,\n\tbumpCursor,\n\tcreateAuditLog,\n\tmutate,\n\ttype ReadonlyAuditLog,\n\treadonlyAuditLog,\n\tregisterCursor,\n} from \"../../base/mutation/index.js\";\n\nconst DEFAULT_MAX_PER_PUMP = 256;\nconst DEFAULT_COMPLETED_RETAINED_LIMIT = 1024;\n\nfunction requireNonNegativeInt(value: number, label: string): number {\n\tif (!Number.isFinite(value) || !Number.isInteger(value) || value < 0) {\n\t\tthrow new Error(`${label} must be a non-negative integer`);\n\t}\n\treturn value;\n}\n\nfunction jobQueueMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"job_queue\", kind, extra);\n}\n\nexport type JobState = \"queued\" | \"inflight\";\n\nexport type JobEnvelope<T> = {\n\tid: string;\n\tpayload: T;\n\tattempts: number;\n\tmetadata: Readonly<Record<string, unknown>>;\n\tstate: JobState;\n};\n\n/** Audit record for a job-queue mutation (Audit 2 cross-cutting). */\nexport type JobEventAction = \"enqueue\" | \"claim\" | \"ack\" | \"nack\" | \"remove\";\n\nexport interface JobEvent<T = unknown> extends BaseAuditRecord {\n\treadonly action: JobEventAction;\n\treadonly id: string;\n\treadonly attempts?: number;\n\treadonly payload?: T;\n\t/**\n\t * The failure cause for a no-requeue `\"nack\"` (F-CATCH D-3). Present only\n\t * when a job was nack'd-without-requeue because its work threw\n\t * synchronously or its result Node emitted `ERROR`. Without this, a failed\n\t * job is observable as a `\"nack\"` event but the *reason* it failed is\n\t * unrecoverable from the event stream. Carries the raw thrown value /\n\t * ERROR payload (not normalized) so callers keep full fidelity.\n\t *\n\t * Caveats: a thrown `undefined` (legal but pathological) is not recorded —\n\t * it carries no diagnostic payload and the `\"nack\"` action itself already\n\t * surfaces the failure. And like {@link JobEvent.payload}, a raw `Error` is\n\t * not JSON-round-trippable, so keyed-storage codecs wired via\n\t * `attachEventStorage` should normalize this field (e.g. capture\n\t * `message`/`stack`) before serializing.\n\t */\n\treadonly error?: unknown;\n}\n\n/** Recommended `keyOf` for keyed-storage adapters (Audit 2 #7). */\nexport const jobEventKeyOf = <T>(e: JobEvent<T>): string => e.action;\n\nexport type JobQueueOptions = {\n\tgraph?: GraphOptions;\n};\n\nexport class JobQueueGraph<T> extends Graph {\n\tprivate readonly _pending;\n\tprivate readonly _jobs;\n\tprivate readonly _seqCursor: Node<number>;\n\treadonly pending: Node<readonly string[]>;\n\treadonly jobs: Node<ReadonlyMap<string, JobEnvelope<T>>>;\n\treadonly depth: Node<number>;\n\t/** Audit log of every queue mutation (Audit 2). */\n\treadonly events: ReactiveLogBundle<JobEvent<T>>;\n\t/**\n\t * Read-only view of {@link JobQueueGraph.events} — Audit 2 `.audit`\n\t * duplication; M7 (cannot mutate the canonical log via the alias).\n\t */\n\treadonly audit: ReadonlyAuditLog<JobEvent<T>>;\n\n\t// Tier 8 / COMPOSITION-GUIDE §35: mutate wrappers for the four\n\t// single-record mutation methods. Assigned in the constructor (NOT via\n\t// class-field initializers) because field initializers run before the\n\t// constructor body — `this.events` and `this._seqCursor` aren't ready yet.\n\t// `claim` stays inline because it emits one record per claimed job.\n\tprivate readonly _enqueueImpl: (\n\t\tpayload: T,\n\t\topts: { id?: string; metadata?: Record<string, unknown> },\n\t) => string;\n\tprivate readonly _ackImpl: (id: string, job: JobEnvelope<T>) => void;\n\tprivate readonly _nackImpl: (\n\t\tid: string,\n\t\tjob: JobEnvelope<T>,\n\t\trequeue: boolean,\n\t\terror?: unknown,\n\t) => void;\n\tprivate readonly _removeByIdImpl: (id: string, job: JobEnvelope<T>) => void;\n\n\tconstructor(name: string, opts: JobQueueOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis._pending = reactiveList<string>([], { name: \"pending\" });\n\t\tthis._jobs = reactiveMap<string, JobEnvelope<T>>({ name: \"jobs\" });\n\t\tthis.pending = this._pending.items;\n\t\tthis.jobs = this._jobs.entries;\n\t\tthis.add(this.pending, { name: \"pending\" });\n\t\tthis.add(this.jobs, { name: \"jobs\" });\n\t\tthis.depth = node(\n\t\t\t[this.pending],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly string[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"depth\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: jobQueueMeta(\"queue_depth\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.depth, { name: \"depth\" });\n\t\tthis.addDisposer(keepalive(this.depth));\n\n\t\tthis.events = createAuditLog<JobEvent<T>>({\n\t\t\tname: \"events\",\n\t\t\tretainedLimit: 1024,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis.audit = readonlyAuditLog(this.events);\n\t\tthis._seqCursor = registerCursor(this, \"seq\", 0);\n\n\t\t// `freeze: false` everywhere because the payload may be large and\n\t\t// per-mutation cost matters on hot paths. mutate bumps `seq` via\n\t\t// the registered cursor BEFORE the action runs, so action bodies that\n\t\t// need the just-bumped value (e.g. enqueue's auto-id) read\n\t\t// `this._seqCursor.cache`.\n\t\tthis._enqueueImpl = mutate<\n\t\t\t[T, { id?: string; metadata?: Record<string, unknown> }],\n\t\t\tstring,\n\t\t\tJobEvent<T>\n\t\t>(\n\t\t\t(payload, enqueueOpts): string => {\n\t\t\t\tconst seq = this._seqCursor.cache as number;\n\t\t\t\tconst id = enqueueOpts.id ?? `${this.name}-${seq}`;\n\t\t\t\tif (this._jobs.get(id) !== undefined) {\n\t\t\t\t\tthrow new Error(`jobQueue(\"${this.name}\"): duplicate job id \"${id}\"`);\n\t\t\t\t}\n\t\t\t\tconst job: JobEnvelope<T> = {\n\t\t\t\t\tid,\n\t\t\t\t\tpayload,\n\t\t\t\t\tattempts: 0,\n\t\t\t\t\tmetadata: Object.freeze({ ...(enqueueOpts.metadata ?? {}) }),\n\t\t\t\t\tstate: \"queued\",\n\t\t\t\t};\n\t\t\t\tthis._jobs.set(id, job);\n\t\t\t\tthis._pending.append(id);\n\t\t\t\treturn id;\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([payload], id, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"enqueue\",\n\t\t\t\t\tid,\n\t\t\t\t\tpayload,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._ackImpl = mutate<[string, JobEnvelope<T>], void, JobEvent<T>>(\n\t\t\t(id, _job): void => {\n\t\t\t\tthis._jobs.delete(id);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"ack\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._nackImpl = mutate<[string, JobEnvelope<T>, boolean, unknown], void, JobEvent<T>>(\n\t\t\t(id, job, requeue, _error): void => {\n\t\t\t\tif (requeue) {\n\t\t\t\t\tthis._jobs.set(id, { ...job, state: \"queued\" });\n\t\t\t\t\tthis._pending.append(id);\n\t\t\t\t} else {\n\t\t\t\t\tthis._jobs.delete(id);\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job, requeue, error], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"nack\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t\t// F-CATCH D-3: surface the failure cause on the no-requeue\n\t\t\t\t\t// (terminal-failure) nack only. A requeue nack is a retry,\n\t\t\t\t\t// not a failure, so it carries no error.\n\t\t\t\t\t...(!requeue && error !== undefined ? { error } : {}),\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tthis._removeByIdImpl = mutate<[string, JobEnvelope<T>], void, JobEvent<T>>(\n\t\t\t(id, job): void => {\n\t\t\t\tif (job.state === \"queued\") {\n\t\t\t\t\tconst pending = this.pending.cache as readonly string[];\n\t\t\t\t\tconst idx = pending.indexOf(id);\n\t\t\t\t\tif (idx >= 0) this._pending.pop(idx);\n\t\t\t\t}\n\t\t\t\tthis._jobs.delete(id);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: this.events,\n\t\t\t\tseq: this._seqCursor,\n\t\t\t\tfreeze: false,\n\t\t\t\tonSuccessRecord: ([id, job], _r, { t_ns, seq }) => ({\n\t\t\t\t\taction: \"remove\",\n\t\t\t\t\tid,\n\t\t\t\t\tattempts: job.attempts,\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * Wire append-log storage tiers (Audit 4). Returns a disposer.\n\t *\n\t * Named `attachEventStorage` to avoid colliding with {@link Graph.attachSnapshotStorage}.\n\t */\n\tattachEventStorage(tiers: readonly AppendLogStorageTier<JobEvent<T>>[]): () => void {\n\t\treturn this.events.attachStorage(tiers);\n\t}\n\n\tenqueue(payload: T, opts: { id?: string; metadata?: Record<string, unknown> } = {}): string {\n\t\treturn this._enqueueImpl(payload, opts);\n\t}\n\n\tclaim(limit = 1): readonly JobEnvelope<T>[] {\n\t\tconst max = requireNonNegativeInt(limit, \"job queue claim limit\");\n\t\tif (max === 0) return [];\n\t\tconst out: JobEnvelope<T>[] = [];\n\t\twhile (out.length < max) {\n\t\t\tconst ids = this.pending.cache as readonly string[];\n\t\t\tif (ids.length === 0) break;\n\t\t\tconst id = this._pending.pop(0);\n\t\t\tconst job = this._jobs.get(id);\n\t\t\tif (!job || job.state !== \"queued\") continue;\n\t\t\tconst inflight: JobEnvelope<T> = {\n\t\t\t\t...job,\n\t\t\t\tstate: \"inflight\",\n\t\t\t\tattempts: job.attempts + 1,\n\t\t\t};\n\t\t\tthis._jobs.set(id, inflight);\n\t\t\tout.push(inflight);\n\t\t\t// claim emits one audit record per claimed job; mutate wraps a\n\t\t\t// single call → single record, so claim stays inline and bumps the\n\t\t\t// cursor directly via the shared `bumpCursor` helper.\n\t\t\tthis.events.append({\n\t\t\t\taction: \"claim\",\n\t\t\t\tid,\n\t\t\t\tattempts: inflight.attempts,\n\t\t\t\tt_ns: wallClockNs(),\n\t\t\t\tseq: bumpCursor(this._seqCursor),\n\t\t\t});\n\t\t}\n\t\treturn out;\n\t}\n\n\tack(id: string): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job || job.state !== \"inflight\") return false;\n\t\tthis._ackImpl(id, job);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Negatively-acknowledge an inflight job.\n\t *\n\t * @param opts.requeue - `true` (default) returns the job to the queue for\n\t * retry; `false` drops it permanently (terminal failure).\n\t * @param opts.error - Optional failure cause for a `requeue: false` nack.\n\t * Recorded on the emitted `\"nack\"` {@link JobEvent} as `error` so the\n\t * reason a job failed is recoverable from the event stream (F-CATCH\n\t * D-3). Ignored when `requeue` is `true` (a retry is not a failure).\n\t */\n\tnack(id: string, opts: { requeue?: boolean; error?: unknown } = {}): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job || job.state !== \"inflight\") return false;\n\t\tthis._nackImpl(id, job, opts.requeue ?? true, opts.error);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Remove a job by id regardless of its current state. Returns `true` if\n\t * the job existed and was removed, `false` if no job has this id.\n\t *\n\t * `ack` only works on inflight; `nack` only works on inflight.\n\t * `removeById` is the state-agnostic escape hatch — useful for\n\t * audit/observability layers that enqueue but never claim, and need to\n\t * finalize a job when an external decision (e.g. harness verify\n\t * outcome) resolves it. Distinct name from the inherited\n\t * {@link Graph.remove}, which removes a mounted child subgraph by path.\n\t *\n\t * When the job is in `queued` state, its id is also pulled from the\n\t * `pending` list — depth + pending snapshot stay consistent.\n\t */\n\tremoveById(id: string): boolean {\n\t\tconst job = this._jobs.get(id);\n\t\tif (!job) return false;\n\t\tthis._removeByIdImpl(id, job);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Subscribe to a Node and enqueue each DATA payload into this queue.\n\t * Returns a disposer that stops consuming when called.\n\t *\n\t * Used internally by {@link JobFlowGraph} for stage-to-stage wiring but\n\t * also useful for users wiring an external source into a job queue.\n\t *\n\t * @param source - Node whose DATA values are enqueued.\n\t * @param opts - Optional enqueue options (id generator, metadata prefix).\n\t */\n\tconsumeFrom(\n\t\tsource: Node<T>,\n\t\topts?: {\n\t\t\tmetadata?: Record<string, unknown>;\n\t\t},\n\t): () => void {\n\t\treturn source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tconst payload = m[1] as T;\n\t\t\t\tthis.enqueue(payload, opts ? { metadata: opts.metadata } : undefined);\n\t\t\t}\n\t\t});\n\t}\n}\n\n// ── StageDef ─────────────────────────────────────────────────────────────\n\n/**\n * Work function for a job flow stage. Receives the full job envelope and\n * an optional per-claim options object carrying an `AbortSignal`; returns\n * a `NodeInput<T>` — raw value (sync), Promise (async), or Node (composed\n * pipeline). `fromAny` coerces any of these shapes.\n *\n * On error / rejection: the stage nacks the job (no requeue by default).\n *\n * **Per-claim signal (Tier 6.5 2.5b, 2026-04-29).** The pump mints an\n * `AbortController` per claim and supplies its `signal` via `opts`. The\n * signal aborts when (a) the result node settles (first DATA / first\n * ERROR — auto-cleanup after the pump captures), OR (b) the pump itself\n * tears down (e.g. parent Graph `destroy()`). User-supplied work fns that\n * do long-running async (HTTP, LLM streams, evaluator subgraphs) can\n * forward this signal into `fetch({ signal })`, `adapter.invoke({ signal\n * })`, etc. for cooperative cancellation. Sync work fns ignore `opts` —\n * the second arg is optional, no behavior change for legacy callers.\n *\n * Mirrors the `LLMInvokeOptions.signal` / `apply(item, { signal })` /\n * tool-handler `(args, { signal })` precedents — same shape across the\n * library's user-callback boundaries.\n */\nexport type WorkFn<T> = (job: JobEnvelope<T>, opts?: { signal: AbortSignal }) => NodeInput<T>;\n\n/**\n * Stage definition for {@link JobFlowGraph}. Either a bare name string\n * (no work hook, pure pass-through) or a full definition object.\n */\nexport type StageDef<T> =\n\t| string\n\t| {\n\t\t\tname: string;\n\t\t\twork?: WorkFn<T>;\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t\t/**\n\t\t\t * Per-stage cap on `claim → work → ack` cycles per pump tick.\n\t\t\t * Overrides {@link JobFlowOptions.maxPerPump} for this stage. Useful\n\t\t\t * when stages have asymmetric cost (e.g. an LLM-execute stage capped\n\t\t\t * at 4 concurrent calls while a cheap verify stage runs unbounded).\n\t\t\t *\n\t\t\t * Falls back to the top-level `JobFlowOptions.maxPerPump`, which in\n\t\t\t * turn falls back to `DEFAULT_MAX_PER_PUMP` (256).\n\t\t\t */\n\t\t\tmaxPerPump?: number;\n\t\t\t/**\n\t\t\t * Per-stage cap on TOTAL concurrent inflight claims (Tier 6.5 3.1,\n\t\t\t * 2026-04-29). Distinct from {@link maxPerPump}: `maxPerPump` caps\n\t\t\t * claims per pump tick, while `maxInflight` caps the number of\n\t\t\t * unsettled in-flight claims at any moment across all ticks. Use\n\t\t\t * for rigorous LLM cost ceilings (e.g. \"no more than 4 concurrent\n\t\t\t * adapter.invoke calls regardless of pending depth\").\n\t\t\t *\n\t\t\t * When set, the stage mounts an internal `state(0)` counter as a\n\t\t\t * pump dep so the pump re-fires on each settle — pending items\n\t\t\t * resume claiming as soon as inflight drops below the cap.\n\t\t\t *\n\t\t\t * Unset (default): unbounded inflight, gated only by `maxPerPump`.\n\t\t\t */\n\t\t\tmaxInflight?: number;\n\t };\n\nexport type JobFlowOptions<T = unknown> = {\n\tgraph?: GraphOptions;\n\t/**\n\t * Stage definitions. Each stage is either a bare name string (pure\n\t * pass-through) or a `{ name, work?, handlerVersion?, maxPerPump? }` object.\n\t *\n\t * For back-compat, `string[]` values behave as stages with no work hook.\n\t */\n\tstages?: readonly StageDef<T>[];\n\t/**\n\t * Default cap on claims per pump tick across all stages. Per-stage\n\t * overrides can be set on each {@link StageDef.maxPerPump}; if neither is\n\t * set, falls back to `DEFAULT_MAX_PER_PUMP` (256).\n\t */\n\tmaxPerPump?: number;\n};\n\nexport class JobFlowGraph<T> extends Graph {\n\tprivate readonly _stageNames: readonly string[];\n\tprivate readonly _stageWorkFns: ReadonlyMap<string, WorkFn<T>>;\n\tprivate readonly _queues = new Map<string, JobQueueGraph<T>>();\n\tprivate readonly _completed;\n\treadonly completed: Node<readonly JobEnvelope<T>[]>;\n\treadonly completedCount: Node<number>;\n\n\tconstructor(name: string, opts: JobFlowOptions<T> = {}) {\n\t\tsuper(name, opts.graph);\n\n\t\t// Normalise stage definitions.\n\t\tconst rawStages = opts.stages ?? ([\"incoming\", \"processing\", \"done\"] as readonly StageDef<T>[]);\n\t\tconst stageNames: string[] = [];\n\t\tconst stageWorkFns = new Map<string, WorkFn<T>>();\n\t\tconst stageMaxPerPump = new Map<string, number>();\n\t\tconst stageMaxInflight = new Map<string, number>();\n\n\t\tfor (const raw of rawStages) {\n\t\t\tconst stageName = typeof raw === \"string\" ? raw.trim() : raw.name.trim();\n\t\t\tif (typeof raw !== \"string\" && raw.work) {\n\t\t\t\tstageWorkFns.set(stageName, raw.work);\n\t\t\t}\n\t\t\tif (typeof raw !== \"string\" && raw.maxPerPump != null) {\n\t\t\t\tstageMaxPerPump.set(\n\t\t\t\t\tstageName,\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\t1,\n\t\t\t\t\t\trequireNonNegativeInt(raw.maxPerPump, `job flow stage \"${stageName}\" maxPerPump`),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (typeof raw !== \"string\" && raw.maxInflight != null) {\n\t\t\t\tstageMaxInflight.set(\n\t\t\t\t\tstageName,\n\t\t\t\t\tMath.max(\n\t\t\t\t\t\t1,\n\t\t\t\t\t\trequireNonNegativeInt(raw.maxInflight, `job flow stage \"${stageName}\" maxInflight`),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tstageNames.push(stageName);\n\t\t}\n\n\t\tif (stageNames.length < 2) {\n\t\t\tthrow new Error(`jobFlow(\"${name}\"): requires at least 2 stages`);\n\t\t}\n\t\tconst unique = new Set(stageNames);\n\t\tif (unique.size !== stageNames.length) {\n\t\t\tthrow new Error(`jobFlow(\"${name}\"): stage names must be unique`);\n\t\t}\n\t\tthis._stageNames = Object.freeze([...stageNames]);\n\t\tthis._stageWorkFns = stageWorkFns;\n\n\t\tfor (const stage of this._stageNames) {\n\t\t\tconst q = jobQueue<T>(`${name}-${stage}`);\n\t\t\tthis._queues.set(stage, q);\n\t\t\tthis.mount(stage, q);\n\t\t}\n\n\t\tthis._completed = reactiveLog<JobEnvelope<T>>([], {\n\t\t\tname: \"completed\",\n\t\t\tmaxSize: DEFAULT_COMPLETED_RETAINED_LIMIT,\n\t\t});\n\t\tthis.completed = this._completed.entries;\n\t\tthis.add(this.completed, { name: \"completed\" });\n\t\tthis.completedCount = node(\n\t\t\t[this.completed],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tactions.emit((data[0] as readonly JobEnvelope<T>[]).length);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"completedCount\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: jobQueueMeta(\"job_flow_completed_count\"),\n\t\t\t\tinitial: 0,\n\t\t\t},\n\t\t);\n\t\tthis.add(this.completedCount, { name: \"completedCount\" });\n\t\tthis.addDisposer(keepalive(this.completedCount));\n\n\t\tconst defaultMaxPerPump = Math.max(\n\t\t\t1,\n\t\t\trequireNonNegativeInt(opts.maxPerPump ?? DEFAULT_MAX_PER_PUMP, \"job flow maxPerPump\"),\n\t\t);\n\n\t\t// Wire up per-stage pumps.\n\t\tfor (let i = 0; i < this._stageNames.length; i += 1) {\n\t\t\tconst stage = this._stageNames[i] as string;\n\t\t\tconst current = this.queue(stage);\n\t\t\tconst next =\n\t\t\t\ti + 1 < this._stageNames.length ? this.queue(this._stageNames[i + 1] as string) : null;\n\t\t\tconst workFn = this._stageWorkFns.get(stage);\n\t\t\t// Per-stage `maxPerPump` override falls back to the top-level cap.\n\t\t\t// Captured per stage so each pump's loop sees its own resolved limit.\n\t\t\tconst stagePerPump = stageMaxPerPump.get(stage) ?? defaultMaxPerPump;\n\t\t\tconst stageMaxInflightCap = stageMaxInflight.get(stage);\n\t\t\t// When `maxInflight` is set, mount a state(0) counter on the graph\n\t\t\t// and wire it as an extra pump dep — settles `inflightCounter.emit`\n\t\t\t// re-fire the pump so pending items resume claiming after each\n\t\t\t// settle (without a counter, the pump only fires on `pending`\n\t\t\t// changes, which `ack` does not affect → maxInflight at saturation\n\t\t\t// would deadlock the queue).\n\t\t\t// qa F-D (Tier 5 /qa pass, 2026-04-29): mount under `__inflight__/`\n\t\t\t// internal namespace so the counter cannot collide with a user-named\n\t\t\t// stage (e.g. `inflight_my-stage`). Matches the EH-16\n\t\t\t// `__processManagers__/<name>` convention (COMPOSITION-GUIDE §38 —\n\t\t\t// internal infrastructure paths use the `__` prefix).\n\t\t\tconst inflightCounter =\n\t\t\t\tstageMaxInflightCap !== undefined\n\t\t\t\t\t? node<number>([], { name: `__inflight__/${stage}`, initial: 0 })\n\t\t\t\t\t: null;\n\t\t\tif (inflightCounter) {\n\t\t\t\tthis.add(inflightCounter, { name: `__inflight__/${stage}` });\n\t\t\t}\n\n\t\t\t// `isTerminal` marks the last stage — completed jobs go into\n\t\t\t// `_completed` log instead of a next queue.\n\t\t\tconst isTerminal = next === null;\n\n\t\t\tif (workFn) {\n\t\t\t\t// ── Stage with work hook ──────────────────────────────────────\n\t\t\t\t// Pump effect: claim one job, run work(job), forward result on\n\t\t\t\t// success; nack on failure.\n\t\t\t\t// Per B.3 lock: effects ARE sanctioned for side-effects.\n\t\t\t\t// `fromAny` bridges sync value / Promise / Node → Node<T>.\n\t\t\t\t//\n\t\t\t\t// **Inflight teardown drain (Tier 6.5 2.5a, 2026-04-29).** Each\n\t\t\t\t// claim mints a per-claim `AbortController` and tracks the\n\t\t\t\t// `(unsub, ac)` pair in a `ctx.store.inflight` Set. The\n\t\t\t\t// per-claim signal is supplied to the work fn via the optional\n\t\t\t\t// second-arg `{ signal }` (mirrors `LLMInvokeOptions.signal` /\n\t\t\t\t// `apply(item, {signal})` / tool-handler precedents). On the\n\t\t\t\t// pump's `deactivate` hook (parent Graph TEARDOWN cascade —\n\t\t\t\t// e.g. `harness.destroy()`), every inflight entry is aborted +\n\t\t\t\t// unsubscribed so user-supplied async work (LLM streams, eval\n\t\t\t\t// HTTP calls, refineLoop iterations) gets cooperative\n\t\t\t\t// cancellation instead of leaking past the harness lifetime.\n\t\t\t\ttype InflightEntry = { unsub: () => void; ac: AbortController };\n\t\t\t\ttype InflightStore = { entries: Set<InflightEntry>; terminated: boolean };\n\t\t\t\tconst pumpDeps: Node[] =\n\t\t\t\t\tinflightCounter != null ? [current.pending, inflightCounter] : [current.pending];\n\t\t\t\tconst pump = node<unknown>(\n\t\t\t\t\tpumpDeps,\n\t\t\t\t\t(_data, _actions, ctx) => {\n\t\t\t\t\t\tif (!(\"inflight\" in ctx.store)) {\n\t\t\t\t\t\t\tctx.store.inflight = {\n\t\t\t\t\t\t\t\tentries: new Set<InflightEntry>(),\n\t\t\t\t\t\t\t\tterminated: false,\n\t\t\t\t\t\t\t} satisfies InflightStore;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst inflightStore = ctx.store.inflight as InflightStore;\n\t\t\t\t\t\tconst inflight = inflightStore.entries;\n\t\t\t\t\t\tlet processed = 0;\n\t\t\t\t\t\twhile (processed < stagePerPump) {\n\t\t\t\t\t\t\t// 3.1 maxInflight gate: cap concurrent inflight across pump\n\t\t\t\t\t\t\t// ticks. The inflightCounter (mounted as a pump dep) re-fires\n\t\t\t\t\t\t\t// the pump when a settle decrements it, so pending items\n\t\t\t\t\t\t\t// resume claiming when capacity frees up.\n\t\t\t\t\t\t\tif (stageMaxInflightCap !== undefined && inflight.size >= stageMaxInflightCap) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst claims = current.claim(1);\n\t\t\t\t\t\t\tif (claims.length === 0) break;\n\t\t\t\t\t\t\tconst job = claims[0] as JobEnvelope<T>;\n\t\t\t\t\t\t\tif (!job) break;\n\n\t\t\t\t\t\t\t// Build the updated path accumulator.\n\t\t\t\t\t\t\tconst prevPath = (job.metadata.job_flow_path as readonly string[] | undefined) ?? [];\n\t\t\t\t\t\t\tconst newPath = [...prevPath, stage];\n\n\t\t\t\t\t\t\tconst ac = new AbortController();\n\t\t\t\t\t\t\tconst entry: InflightEntry = { unsub: () => undefined, ac };\n\t\t\t\t\t\t\tinflight.add(entry);\n\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\n\t\t\t\t\t\t\tlet result: NodeInput<T>;\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tresult = workFn(job, { signal: ac.signal });\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t// Sync throw → nack no-requeue. F-CATCH D-3: thread\n\t\t\t\t\t\t\t\t// the thrown value onto the nack event so the\n\t\t\t\t\t\t\t\t// failure is diagnosable, not just observable.\n\t\t\t\t\t\t\t\tinflight.delete(entry);\n\t\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\t\t\t\t\t\t\t\tcurrent.nack(job.id, { requeue: false, error: err });\n\t\t\t\t\t\t\t\tprocessed += 1;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Coerce to Node<T> via fromAny.\n\t\t\t\t\t\t\tconst resultNode = fromAny<T>(result);\n\n\t\t\t\t\t\t\t// M8: Subscribe once to the result node; on DATA forward; on ERROR nack.\n\t\t\t\t\t\t\t// Use `let unsub` + TDZ guard (same pattern as toPromise) so sync\n\t\t\t\t\t\t\t// DATA delivery inside subscribe() doesn't hit TDZ on `unsub`.\n\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\tlet unsub: (() => void) | undefined;\n\t\t\t\t\t\t\tconst cleanupSub = (): void => {\n\t\t\t\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\t\t\t\tunsub();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tPromise.resolve().then(() => unsub?.());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tinflight.delete(entry);\n\t\t\t\t\t\t\t\t// qa F-F (Tier 5 /qa pass, 2026-04-29): skip the counter\n\t\t\t\t\t\t\t\t// emit after teardown — the counter Node is itself in the\n\t\t\t\t\t\t\t\t// cascade. Late ERROR/DATA arriving via the deferred\n\t\t\t\t\t\t\t\t// `Promise.resolve().then(unsub)` path could otherwise emit\n\t\t\t\t\t\t\t\t// on a torn-down node.\n\t\t\t\t\t\t\t\tif (!inflightStore.terminated) {\n\t\t\t\t\t\t\t\t\tinflightCounter?.emit(inflight.size);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tunsub = resultNode.subscribe((msgs) => {\n\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t\tcleanupSub();\n\t\t\t\t\t\t\t\t\t\tconst newPayload = m[1] as T;\n\t\t\t\t\t\t\t\t\t\tconst newMetadata = {\n\t\t\t\t\t\t\t\t\t\t\t...job.metadata,\n\t\t\t\t\t\t\t\t\t\t\tjob_flow_path: newPath,\n\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\tif (isTerminal) {\n\t\t\t\t\t\t\t\t\t\t\tconst completedJob: JobEnvelope<T> = {\n\t\t\t\t\t\t\t\t\t\t\t\t...job,\n\t\t\t\t\t\t\t\t\t\t\t\tpayload: newPayload,\n\t\t\t\t\t\t\t\t\t\t\t\tmetadata: Object.freeze(newMetadata),\n\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t\t\t\tthis._completed.append(completedJob);\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t\t\t\t(next as JobQueueGraph<T>).enqueue(newPayload, {\n\t\t\t\t\t\t\t\t\t\t\t\t\tmetadata: newMetadata,\n\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t\tcleanupSub();\n\t\t\t\t\t\t\t\t\t\t// F-CATCH D-3: carry the ERROR payload onto\n\t\t\t\t\t\t\t\t\t\t// the nack event (symmetric with the sync\n\t\t\t\t\t\t\t\t\t\t// -throw path) so failed jobs are diagnosable.\n\t\t\t\t\t\t\t\t\t\tcurrent.nack(job.id, { requeue: false, error: m[1] });\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tentry.unsub = () => unsub?.();\n\n\t\t\t\t\t\t\tprocessed += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\t\t\t// qa F-F: set terminated BEFORE draining so any\n\t\t\t\t\t\t\t\t// `cleanupSub` racing via the deferred-microtask path\n\t\t\t\t\t\t\t\t// (`Promise.resolve().then(() => unsub?.())`) sees\n\t\t\t\t\t\t\t\t// `terminated === true` and skips its `inflightCounter.emit`.\n\t\t\t\t\t\t\t\tinflightStore.terminated = true;\n\t\t\t\t\t\t\t\tfor (const e of inflight) {\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\te.ac.abort();\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// best-effort\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\te.unsub();\n\t\t\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t\t\t// best-effort\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tinflight.clear();\n\t\t\t\t\t\t\t\t// Lock 6.D (Phase 13.6.B): drop the `inflight` key\n\t\t\t\t\t\t\t\t// so the next activation re-initializes a fresh\n\t\t\t\t\t\t\t\t// `InflightStore` with `terminated: false`. Without\n\t\t\t\t\t\t\t\t// this, post-flip preserve-by-default keeps the\n\t\t\t\t\t\t\t\t// stale `terminated: true` flag and silently\n\t\t\t\t\t\t\t\t// suppresses inflight-counter emits forever.\n\t\t\t\t\t\t\t\tdelete ctx.store.inflight;\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tmeta: jobQueueMeta(\"job_flow_pump\", { stage, has_work: true }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthis.addDisposer(keepalive(pump));\n\t\t\t} else {\n\t\t\t\t// ── Stage without work hook (pass-through ferry) ──────────────\n\t\t\t\t// Claim, accumulate path, forward to next stage or completed.\n\t\t\t\tconst pump = this.effect(\n\t\t\t\t\t`pump_${stage}`,\n\t\t\t\t\t[`${stage}::pending`],\n\t\t\t\t\t() => {\n\t\t\t\t\t\tlet moved = 0;\n\t\t\t\t\t\twhile (moved < stagePerPump) {\n\t\t\t\t\t\t\tconst claim = current.claim(1);\n\t\t\t\t\t\t\tif (claim.length === 0) break;\n\t\t\t\t\t\t\tconst job = claim[0] as JobEnvelope<T>;\n\t\t\t\t\t\t\tif (!job) break;\n\n\t\t\t\t\t\t\tconst prevPath = (job.metadata.job_flow_path as readonly string[] | undefined) ?? [];\n\t\t\t\t\t\t\tconst newPath = [...prevPath, stage];\n\t\t\t\t\t\t\tconst newMetadata = { ...job.metadata, job_flow_path: newPath };\n\n\t\t\t\t\t\t\tif (isTerminal) {\n\t\t\t\t\t\t\t\tconst completedJob: JobEnvelope<T> = {\n\t\t\t\t\t\t\t\t\t...job,\n\t\t\t\t\t\t\t\t\tmetadata: Object.freeze(newMetadata),\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\tthis._completed.append(completedJob);\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t\tcurrent.ack(job.id);\n\t\t\t\t\t\t\t\t\t(next as JobQueueGraph<T>).enqueue(job.payload, {\n\t\t\t\t\t\t\t\t\t\tmetadata: newMetadata,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tmoved += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tmeta: jobQueueMeta(\"job_flow_pump\", { stage, has_work: false }),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthis.addDisposer(keepalive(pump));\n\t\t\t}\n\t\t}\n\t}\n\n\tstages(): readonly string[] {\n\t\treturn this._stageNames;\n\t}\n\n\tqueue(stage: string): JobQueueGraph<T> {\n\t\tconst q = this._queues.get(stage);\n\t\tif (!q) throw new Error(`jobFlow(\"${this.name}\"): unknown stage \"${stage}\"`);\n\t\treturn q;\n\t}\n\n\tenqueue(payload: T, opts: { id?: string; metadata?: Record<string, unknown> } = {}): string {\n\t\treturn this.queue(this._stageNames[0] as string).enqueue(payload, opts);\n\t}\n\n\tretainedCompleted(): readonly JobEnvelope<T>[] {\n\t\treturn this.completed.cache as readonly JobEnvelope<T>[];\n\t}\n}\n\n/**\n * Creates a Pulsar-inspired job queue graph with claim/ack/nack workflow.\n */\nexport function jobQueue<T>(name: string, opts?: JobQueueOptions): JobQueueGraph<T> {\n\treturn new JobQueueGraph<T>(name, opts);\n}\n\n/**\n * Creates an autonomous multi-stage queue chain graph.\n */\nexport function jobFlow<T>(name: string, opts?: JobFlowOptions<T>): JobFlowGraph<T> {\n\tconst g = new JobFlowGraph<T>(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` surfaces provenance. Route through\n\t// `placeholderArgs` since `stages[].work` is a function and\n\t// `opts.graph` may carry non-JSON fields.\n\tconst { factory: _f, factoryArgs: _fa, ...tagArgs } = (opts ?? {}) as Record<string, unknown>;\n\tg.tagFactory(\"jobFlow\", placeholderArgs(tagArgs));\n\treturn g;\n}\n","/**\n * `ownershipController()` — multi-agent subgraph ownership preset\n * (DS-14.5.A delta #8; L5/L6 + Q1–Q10).\n *\n * **Placement (documented choice).** Lives in `presets/harness/` alongside\n * the other multi-agent coordination presets (`spawnable()`, `actorPool()`).\n * Per the 4-layer rubric this is a ≥3-utils composition (messaging `topic` +\n * `derived` arbitration + Guard ABAC) wiring multi-agent coordination — the\n * same charter as `harness/`'s existing `spawnable`/`actorPool`. A separate\n * `presets/multi-agent/` directory was rejected to avoid fragmenting the\n * multi-agent presets across two folders for a single factory (L6: \"recipe +\n * preset, NO new primitive\").\n *\n * **What it is.** A `Graph` that owns a shared ownership `topic` (Q3 — one\n * topic carries claim / release / override; subscribers narrow by `kind`),\n * a reactive `current` derivation that folds the ownership log applying the\n * L0–L3 staircase, and a `guard` (`policyAllowing` — the Q7 reactive-options\n * Guard widening) the caller mounts on the owned subgraph. It **consumes the\n * existing DS-14 {@link OwnershipChange}** envelope — it does NOT redefine it.\n *\n * **Staircase (Q10 — `level` is a priority axis, NOT a mechanism enum):**\n * - **L1 TTL** — a `claim` carries a level; the controller's `ttl` (ms)\n * bounds the live window. L1 honors TTL strictly (Q4): a crash inside the\n * window does NOT early-release; recommend `ttl ≤ 60s`.\n * - **L2 heartbeat** — `heartbeat?: NodeInput<unknown>` (Q2). Any reactive\n * trigger Node; each emission resets the countdown (\"max tolerance since\n * last sign of life\", unified across L1/L2). No library timer is shipped\n * and no `claim.heartbeat()` method exists (`feedback_no_imperative` +\n * `feedback_no_imperative_wrap_as_primitive`).\n * - **L3 supervisor** — a `kind:\"override\"` change wins by `level` priority\n * regardless of expiry/heartbeat (priority axis independent of the expiry\n * axis). Supervisor publishes to the SAME topic (Q3).\n *\n * **No polling / no timer (spec §5.8/§5.9/§5.10).** Expiry is evaluated\n * reactively: `current` recomputes whenever the ownership topic OR the\n * heartbeat OR the optional `clock` trigger emits, folding the whole log\n * from scratch (idempotent — no carried mutable cursor). Auto-release on\n * wall-clock TTL requires the caller to wire a reactive `clock` tick\n * (`fromTimer({ ms })` or an activity-derived Node) — the library does not\n * own a timer (L6 / Q2). Without `clock`, expiry still resolves at the next\n * topic/heartbeat emission and on any read that recomputes the derivation.\n *\n * @module\n */\n\nimport { type Node, type NodeGuard, policyAllowing, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { NodeInput, OwnershipChange, OwnershipChangePayload } from \"@graphrefly/pure-ts/extra\";\nimport { fromAny } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport { type TopicGraph, topic } from \"../../utils/messaging/index.js\";\n\n/** Ownership level — priority axis (Q10). Higher rank = higher priority. */\nconst LEVEL_RANK = { L0: 0, L1: 1, L2: 2, L3: 3 } as const;\ntype OwnershipLevel = keyof typeof LEVEL_RANK;\n\n/** Options for {@link ownershipController}. */\nexport type OwnershipControllerOptions = {\n\t/**\n\t * TTL (milliseconds) bounding the live window of a claim. Honored\n\t * strictly (Q4) — a crash inside the window does not early-release.\n\t * Recommend ≤ 60_000 for L1 holds; wire `heartbeat` (L2) for longer.\n\t */\n\treadonly ttl: number;\n\t/**\n\t * L2 heartbeat (Q2). Any reactive trigger Node — each emission resets the\n\t * TTL countdown. Simple: `fromTimer({ ms: ttl / 3 })`. Activity-based:\n\t * `derived([toolCalls.events], …)`. Omitted → pure L1 TTL semantics.\n\t */\n\treadonly heartbeat?: NodeInput<unknown>;\n\t/**\n\t * L3 supervisor id. A `kind:\"override\"` change whose `actor` equals this\n\t * id wins by `level` priority regardless of expiry/heartbeat. Override\n\t * delivery is the shared topic with the `kind:\"override\"` discriminant\n\t * (Q3) — not a separate priority topic.\n\t */\n\treadonly supervisor?: string;\n\t/**\n\t * Optional reactive clock trigger used ONLY to re-evaluate TTL expiry\n\t * (e.g. `fromTimer({ ms: 1_000 })`). The library ships no timer (L6/Q2);\n\t * wire this for wall-clock-driven auto-release without an intervening\n\t * claim/heartbeat. Without it, expiry resolves lazily on the next\n\t * topic/heartbeat emission.\n\t */\n\treadonly clock?: NodeInput<unknown>;\n\t/** Bounded retention for the ownership topic (default 256). */\n\treadonly retainedLimit?: number;\n};\n\n/**\n * Resolved ownership state emitted by {@link OwnershipControllerGraph.current}.\n * `owner` is `null` when unclaimed or the live claim has expired.\n */\nexport type OwnershipState = {\n\treadonly owner: string | null;\n\treadonly level: OwnershipLevel | null;\n\t/** Allow-set fed to the Guard. `[]` (deny-all) when `owner === null`. */\n\treadonly allowed: readonly string[];\n\t/**\n\t * Internal (F3/F4) — last sign-of-life (wall-clock ns) for the *current*\n\t * claim: `max(claim.sinceNs, last in-window heartbeat)`. Carried in the\n\t * derivation's OWN emitted state (read back via `ctx.prevData`) so the\n\t * fold is pure — same (folded log, beat-this-wave, now, prevState) →\n\t * same output. NEVER an instance field. `null` when unclaimed. Scoped to\n\t * the active claim: a value older than the active claim's `sinceNs` (a\n\t * prior owner's beat) is discarded so it cannot extend a new owner.\n\t */\n\treadonly signOfLifeNs: number | null;\n};\n\nconst EMPTY_STATE: OwnershipState = {\n\towner: null,\n\tlevel: null,\n\tallowed: [],\n\tsignOfLifeNs: null,\n};\n\ntype ActiveOwner = { owner: string; level: OwnershipLevel; sinceNs: number };\n\n/**\n * Multi-agent subgraph ownership controller. See module docs.\n *\n * Public surface:\n * - `topic` — the shared ownership `TopicGraph<OwnershipChange>` (Q3).\n * Agents publish claim/release/override here (use the `claim`/`release`/\n * `override` helpers — thin reactive wrappers over `topic.publish`, i.e.\n * message flow, NOT imperative triggers).\n * - `current` — `Node<OwnershipState>`: the reactively-resolved owner after\n * applying L1 TTL + L2 heartbeat + L3 supervisor arbitration.\n * - `allowed` — `Node<readonly string[]>`: the Guard allow-set (derived from\n * `current`); re-points on claim/release/override with no rewire.\n * - `guard` — `NodeGuard` from `policyAllowing(this.allowed)`. Mount on the\n * owned subgraph's nodes (`node({ guard })`) for the Q7 hard-block.\n */\nexport class OwnershipControllerGraph extends Graph {\n\treadonly topic: TopicGraph<OwnershipChange>;\n\treadonly current: Node<OwnershipState>;\n\treadonly allowed: Node<readonly string[]>;\n\treadonly guard: NodeGuard;\n\n\tprivate readonly _ttlNs: number;\n\tprivate readonly _supervisor: string | undefined;\n\t/**\n\t * Whether a heartbeat `NodeInput` was supplied at construction (F14 —\n\t * `claim()`'s `level` default is `\"L2\"` when wired, else `\"L1\"`). NOT a\n\t * mutable accumulator — set once in the constructor, read-only after.\n\t */\n\tprivate readonly _hasHeartbeat: boolean;\n\n\tconstructor(name: string, opts: OwnershipControllerOptions) {\n\t\tsuper(name);\n\t\tthis._ttlNs = Math.max(0, opts.ttl) * 1_000_000;\n\t\tthis._supervisor = opts.supervisor;\n\t\tthis._hasHeartbeat = opts.heartbeat != null;\n\n\t\tthis.topic = topic<OwnershipChange>(`${name}__ownership`, {\n\t\t\tretainedLimit: opts.retainedLimit ?? 256,\n\t\t});\n\t\t// The topic is its own TopicGraph; tear it down with this controller.\n\t\t// (Not mounted — `topic.events` already belongs to the TopicGraph; a\n\t\t// re-`add` would violate single-graph node ownership. Consumers\n\t\t// inspect ownership via `current` / `allowed`, not via a mount.)\n\t\tthis.addDisposer(() => {\n\t\t\tthis.topic.destroy();\n\t\t});\n\n\t\t// `current` recomputes whenever the ownership stream changes, the\n\t\t// heartbeat fires, or the optional clock ticks — the only sources\n\t\t// that can change the resolved owner. ALL deps wired BEFORE any claim\n\t\t// can be published (observers before emitters — §47 rule 2).\n\t\tconst deps: Node<unknown>[] = [this.topic.events as Node<unknown>];\n\t\tconst heartbeatIdx = opts.heartbeat != null ? deps.push(fromAny(opts.heartbeat)) - 1 : -1;\n\t\tif (opts.clock != null) deps.push(fromAny(opts.clock) as Node<unknown>);\n\n\t\tthis.current = this.derived<OwnershipState>(\n\t\t\t\"currentOwner\",\n\t\t\tdeps,\n\t\t\t(batchData, ctx) => {\n\t\t\t\t// Wall-clock (F2) — must match `makeChange`'s `t_ns` stamp so\n\t\t\t\t// `nowNs - active.sinceNs` compares like-for-like. Mixing\n\t\t\t\t// monotonic + wall clocks (the prior bug) made TTL math\n\t\t\t\t// nonsense once the two clocks diverged.\n\t\t\t\tconst nowNs = wallClockNs();\n\t\t\t\t// Did the heartbeat dep emit this wave? `batchData[i]` is the\n\t\t\t\t// array of values dep `i` emitted THIS wave; a non-empty\n\t\t\t\t// heartbeat batch is one or more beats.\n\t\t\t\tconst beatThisWave =\n\t\t\t\t\theartbeatIdx >= 0 &&\n\t\t\t\t\t(() => {\n\t\t\t\t\t\tconst hb = batchData[heartbeatIdx] as readonly unknown[] | null | undefined;\n\t\t\t\t\t\treturn hb != null && hb.length > 0;\n\t\t\t\t\t})();\n\n\t\t\t\t// Fold the WHOLE ownership log from scratch (idempotent — the\n\t\t\t\t// topic emits the full retained array, so a cursor would be a\n\t\t\t\t// bug surface; pure reduction is correct and simple, §47).\n\t\t\t\t// `batchData[0]` is `(readonly OwnershipChange[])[]` — the\n\t\t\t\t// snapshots emitted this wave; take the latest (mirrors\n\t\t\t\t// `topic.latest`'s `batch.at(-1)` pattern). On a SENTINEL\n\t\t\t\t// first-activation wave fall back to `ctx.prevData[0]`.\n\t\t\t\tconst topoBatch = batchData[0] as\n\t\t\t\t\t| readonly (readonly OwnershipChange[])[]\n\t\t\t\t\t| null\n\t\t\t\t\t| undefined;\n\t\t\t\tconst log = (\n\t\t\t\t\ttopoBatch != null && topoBatch.length > 0\n\t\t\t\t\t\t? topoBatch[topoBatch.length - 1]\n\t\t\t\t\t\t: (ctx.prevData[0] as readonly OwnershipChange[] | undefined)\n\t\t\t\t) as readonly OwnershipChange[] | undefined;\n\t\t\t\tlet active: ActiveOwner | null = null;\n\t\t\t\tif (log != null) {\n\t\t\t\t\tfor (const ch of log) {\n\t\t\t\t\t\tif (ch?.change == null) continue;\n\t\t\t\t\t\tactive = applyChange(active, ch, this._supervisor);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// F3/F4 — PURE sign-of-life. Read the prior `signOfLifeNs`\n\t\t\t\t// from THIS derivation's own previously-emitted state\n\t\t\t\t// (`ctx.prevData[0]` for the `current` node is unavailable —\n\t\t\t\t// `prevData[0]` is the topic dep — so we read `ctx.cache`,\n\t\t\t\t// the node's own last emit). No instance field anywhere.\n\t\t\t\tconst prevState = (ctx.cache ?? undefined) as OwnershipState | undefined;\n\n\t\t\t\tlet nextActive: ActiveOwner | null = active;\n\t\t\t\tlet signOfLifeNs: number | null = null;\n\n\t\t\t\tif (active != null && this._ttlNs > 0) {\n\t\t\t\t\t// Carry the prior sign-of-life ONLY if it belongs to THIS\n\t\t\t\t\t// claim (>= the active claim's `sinceNs`). A value from a\n\t\t\t\t\t// prior owner (older than `sinceNs`) is discarded so a\n\t\t\t\t\t// stale beat cannot extend a freshly-claimed window. A new\n\t\t\t\t\t// owner therefore starts from its own claim time.\n\t\t\t\t\tconst carried =\n\t\t\t\t\t\tprevState?.signOfLifeNs != null && prevState.signOfLifeNs >= active.sinceNs\n\t\t\t\t\t\t\t? prevState.signOfLifeNs\n\t\t\t\t\t\t\t: active.sinceNs;\n\t\t\t\t\t// Expire FIRST against the carried sign-of-life (Q4 strict —\n\t\t\t\t\t// a late beat must NOT resurrect an already-lapsed claim),\n\t\t\t\t\t// THEN accept a still-timely beat THIS wave. `signOfLifeNs`\n\t\t\t\t\t// only ever advances on an actual beat-this-wave, so a\n\t\t\t\t\t// recompute storm with no beat cannot renew a dead claim\n\t\t\t\t\t// (idempotent re-fold).\n\t\t\t\t\tconst lapsed = nowNs - carried >= this._ttlNs;\n\t\t\t\t\tif (lapsed) {\n\t\t\t\t\t\tnextActive = null;\n\t\t\t\t\t\tsignOfLifeNs = null;\n\t\t\t\t\t} else if (beatThisWave) {\n\t\t\t\t\t\tsignOfLifeNs = nowNs; // timely beat → renew\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsignOfLifeNs = carried; // unchanged — carry forward\n\t\t\t\t\t}\n\t\t\t\t} else if (active != null) {\n\t\t\t\t\t// No TTL configured — never expires; sign-of-life still\n\t\t\t\t\t// tracked (owner-scoped) for completeness/observability.\n\t\t\t\t\tconst carried =\n\t\t\t\t\t\tprevState?.signOfLifeNs != null && prevState.signOfLifeNs >= active.sinceNs\n\t\t\t\t\t\t\t? prevState.signOfLifeNs\n\t\t\t\t\t\t\t: active.sinceNs;\n\t\t\t\t\tsignOfLifeNs = beatThisWave ? nowNs : carried;\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\tnextActive == null\n\t\t\t\t\t\t? EMPTY_STATE\n\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\towner: nextActive.owner,\n\t\t\t\t\t\t\t\tlevel: nextActive.level,\n\t\t\t\t\t\t\t\tallowed: [nextActive.owner],\n\t\t\t\t\t\t\t\tsignOfLifeNs,\n\t\t\t\t\t\t\t},\n\t\t\t\t];\n\t\t\t},\n\t\t\t{ keepAlive: true },\n\t\t);\n\n\t\tthis.allowed = this.derived<readonly string[]>(\n\t\t\t\"allowed\",\n\t\t\t[this.current],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst batch = batchData[0] as readonly OwnershipState[] | null | undefined;\n\t\t\t\tconst s = (batch != null && batch.length > 0 ? batch[batch.length - 1] : ctx.prevData[0]) as\n\t\t\t\t\t| OwnershipState\n\t\t\t\t\t| undefined;\n\t\t\t\treturn [s?.allowed ?? []];\n\t\t\t},\n\t\t\t{ keepAlive: true },\n\t\t);\n\t\t// F12 — `keepAlive: true` above already installs a self-pruning\n\t\t// keepalive subscription (same as `current`); a second\n\t\t// `keepalive(this.allowed)` disposer was redundant double-subscription.\n\n\t\t// Q7 — the reactive-options Guard. `policyAllowing` reads\n\t\t// `this.allowed.cache` synchronously at write-check time, so\n\t\t// claim/release/override re-point the allow-set with NO rewire.\n\t\tthis.guard = policyAllowing(this.allowed);\n\t}\n\n\t/**\n\t * Publish a `claim`. Thin reactive wrapper over `topic.publish` (message\n\t * flow per §29 — NOT an imperative trigger). `level` defaults to `\"L2\"`\n\t * when this controller has a heartbeat wired, else `\"L1\"`.\n\t */\n\tclaim(actor: string, level?: OwnershipLevel): void {\n\t\t// F14 — documented default (JSDoc + §47): L2 when a heartbeat\n\t\t// NodeInput was wired at construction, else L1.\n\t\tconst lvl = level ?? (this._hasHeartbeat ? \"L2\" : \"L1\");\n\t\tthis.topic.publish(makeChange({ kind: \"claim\", subgraphId: this.name, actor, level: lvl }));\n\t}\n\n\t/** Publish a `release`. Clears ownership iff `actor` is the current owner. */\n\trelease(actor: string): void {\n\t\tthis.topic.publish(makeChange({ kind: \"release\", subgraphId: this.name, actor }));\n\t}\n\n\t/**\n\t * Publish a supervisor `override` (L3). Wins by `level` priority\n\t * regardless of expiry (Q10). `actor` should be this controller's\n\t * `supervisor` id for the override to take precedence.\n\t */\n\toverride(actor: string, previousActor: string, reason: string): void {\n\t\tthis.topic.publish(\n\t\t\tmakeChange({ kind: \"override\", subgraphId: this.name, actor, previousActor, reason }),\n\t\t);\n\t}\n}\n\n/** Wrap an {@link OwnershipChangePayload} in the DS-14 {@link OwnershipChange} envelope. */\nfunction makeChange(payload: OwnershipChangePayload): OwnershipChange {\n\t// F2 — `BaseChange.t_ns` is contractually wall-clock (`wallClockNs()`,\n\t// see change.ts). The fold compares `nowNs (wallClockNs)` against\n\t// `ch.t_ns` for TTL/expiry, so stamp + compare MUST use the same clock.\n\tconst t = wallClockNs();\n\treturn { structure: \"ownership\", version: t, t_ns: t, lifecycle: \"ownership\", change: payload };\n}\n\n/**\n * Fold one ownership change into the resolved-owner state.\n *\n * - `claim` — sets the active owner (records claim time for L1 TTL). A\n * lower-priority claim cannot displace a higher-`level` live owner (Q10 —\n * override arbitration is pure level comparison).\n * - `release` — clears ownership iff the releasing actor is the owner.\n * - `override` — supervisor override: wins by `level` priority. Carries\n * `previousActor` + `reason` per DS-14 (Q3); modeled as an L3 hand-off to\n * `p.actor`.\n */\nfunction applyChange(\n\tactive: ActiveOwner | null,\n\tch: OwnershipChange,\n\tsupervisor: string | undefined,\n): ActiveOwner | null {\n\tconst p = ch.change;\n\t// Use the change's publish timestamp (`t_ns` — wall-clock, stamped in\n\t// `makeChange`) as the claim time — NOT the fold time. The log is re-folded\n\t// from scratch on every recompute (§47), so stamping a fresh clock read\n\t// here would re-baseline the TTL window every recompute and the claim would\n\t// never expire. The fold compares against `wallClockNs()` (F2 — same clock).\n\tif (p.kind === \"claim\") {\n\t\tif (active != null && LEVEL_RANK[active.level] > LEVEL_RANK[p.level]) return active;\n\t\treturn { owner: p.actor, level: p.level, sinceNs: ch.t_ns };\n\t}\n\tif (p.kind === \"release\") {\n\t\tif (active != null && active.owner === p.actor) return null;\n\t\treturn active;\n\t}\n\t// override (F5) — a `kind:\"override\"` only seizes ownership when the\n\t// publishing actor IS the configured supervisor. The prior disjunction\n\t// `|| LEVEL_RANK.L3 >= LEVEL_RANK[active.level]` was a tautology (L3 is the\n\t// max rank ⇒ always true), so ANY actor's override took over. If no\n\t// supervisor is configured, overrides are explicitly disabled (a non-null\n\t// `supervisor` is the gate, not an accidental fall-through).\n\tconst isSupervisor = supervisor != null && p.actor === supervisor;\n\tif (isSupervisor) {\n\t\treturn { owner: p.actor, level: \"L3\", sinceNs: ch.t_ns };\n\t}\n\treturn active;\n}\n\n/**\n * Create a multi-agent subgraph ownership controller (DS-14.5.A #8).\n *\n * @example\n * ```ts\n * const oc = ownershipController(\"payments\", { ttl: 30_000, supervisor: \"lead\" });\n * // Mount the Guard on the owned subgraph:\n * const n = node([], { initial: 0, guard: oc.guard });\n * oc.claim(\"agent-a\"); // agent-a now owns; non-owner writes throw\n * oc.override(\"lead\", \"agent-a\", \"rebalance\"); // supervisor takes over\n * ```\n */\nexport function ownershipController(\n\tname: string,\n\topts: OwnershipControllerOptions,\n): OwnershipControllerGraph {\n\treturn new OwnershipControllerGraph(name, opts);\n}\n","/**\n * Harness-specific graph profiling (roadmap §9.0).\n *\n * Extends {@link graphProfile} with harness domain counters:\n * queue depths, strategy entries, retry/reingestion tracker sizes.\n *\n * @module\n */\n\nimport {\n\ttype GraphProfileOptions,\n\ttype GraphProfileResult,\n\tgraphProfile,\n} from \"@graphrefly/pure-ts/graph\";\nimport { QUEUE_NAMES } from \"../../utils/harness/defaults.js\";\nimport type { QueueRoute, TriagedItem } from \"../../utils/harness/types.js\";\nimport type { HarnessGraph } from \"./harness-loop.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Harness-specific profile extending the base graph profile. */\nexport interface HarnessProfileResult extends GraphProfileResult {\n\t/** Per-queue retained item counts. */\n\tqueueDepths: Record<QueueRoute, number>;\n\t/** Number of rootCause→intervention entries in the strategy model. */\n\tstrategyEntries: number;\n\t/** Global retry count across all items. */\n\ttotalRetries: number;\n\t/** Global reingestion count across all items. */\n\ttotalReingestions: number;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Profile a harness graph with domain-specific counters.\n *\n * **Snapshot caveat (Unit 22 B).** Reads `.cache` values from the\n * strategy / retry / reingestion nodes + each queue topic's `.retained()`\n * view. These are point-in-time reads and are not transactional — if you\n * invoke this during an in-flight reactive wave the values may reflect\n * a partially-settled frame. For end-of-wave accuracy, call from outside\n * any batch boundary.\n *\n * @param harness - The HarnessGraph to profile.\n * @param opts - Optional base profile options.\n * @returns Harness profile with queue depths, strategy stats, and tracker sizes.\n */\nexport function harnessProfile(\n\tharness: HarnessGraph,\n\topts?: GraphProfileOptions,\n): HarnessProfileResult {\n\tconst base = graphProfile(harness, opts);\n\n\t// Unit 22 B: iterate the hub's topic registry instead of a raw Map so\n\t// queue topics added post-construction (dead-letter `__unrouted`, etc.)\n\t// don't get silently ignored.\n\tconst queueDepths: Record<string, number> = {};\n\tfor (const route of QUEUE_NAMES) {\n\t\tconst t = harness.queues.has(route) ? harness.queues.topic<TriagedItem>(route) : null;\n\t\tqueueDepths[route] = t?.retained().length ?? 0;\n\t}\n\n\treturn {\n\t\t...base,\n\t\tqueueDepths: queueDepths as Record<QueueRoute, number>,\n\t\tstrategyEntries: harness.strategy.entries.cache?.size ?? 0,\n\t\ttotalRetries: harness.totalRetries.cache ?? 0,\n\t\ttotalReingestions: harness.totalReingestions.cache ?? 0,\n\t};\n}\n","/**\n * Phase 13.I — `spawnable()` harness preset.\n *\n * Source: `archive/docs/SESSION-multi-agent-gap-analysis.md` G3 lock B + G5\n * reframe.\n *\n * Wraps a {@link MessagingHubGraph} + {@link presetRegistry} +\n * (per-request) {@link agent} mounting + depth-cap + termination contract.\n * Consumers emit a `TopicMessage<SpawnPayload>` to the well-known\n * {@link SPAWNS_TOPIC}; `spawnable()` mints a fresh agent from the\n * matching preset, mounts it, and tracks it in `activeSlot` until the\n * agent settles or expires. Out-of-policy requests (depth-cap exceeded,\n * unknown presetId, schema-invalid, expired) flow to the `rejected`\n * topic.\n *\n * **Cross-cut #1 lock (no `agent.run()`):** spawnable kicks each agent\n * via `bundle.in.emit(taskInput)`; status transitions are observed via\n * the agent's reactive `status` Node.\n *\n * **Termination contract:**\n * - `done` / `error` from the agent's `status` → unmount + remove from\n * `activeSlot`.\n * - `expiresAt` (set on the request envelope, ISO 8601) — when the wall\n * clock passes the deadline AND the agent is still active, the agent is\n * aborted (via `loop.abort()`) and reported on `rejected` with\n * `reason: \"expired\"`. (Per-spawn timeout via the `timeout` operator\n * recipe is documented in COMPOSITION-GUIDE-PATTERNS.)\n *\n * **Depth-cap:** locked recipe (DS-13.I) is `valve(spawnTopic, derived(\n * [depthCounter], n => n < cap))`, but the practical pattern in\n * `spawnable()` checks depth per-request inside the request handler so\n * over-cap requests can be reported on `rejected`. Callers who want hard\n * cuts (no rejection signal) can wrap their own publish path with\n * `valve` per the recipe.\n */\n\nimport { batch, DATA, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { keepalive } from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../../utils/ai/_internal.js\";\nimport type { LLMResponse } from \"../../utils/ai/adapters/core/types.js\";\nimport {\n\ttype MessagingHubGraph,\n\tSPAWNS_TOPIC,\n\ttype SubscriptionGraph,\n\tsubscription,\n\ttype TopicGraph,\n\ttype TopicMessage,\n\ttopic,\n} from \"../../utils/messaging/index.js\";\nimport type { AgentBundle, AgentSpec, AgentStatus } from \"../ai/agent.js\";\nimport type { PresetRegistryBundle } from \"../ai/agents.js\";\nimport { agent } from \"../ai/agents.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Payload of a spawn request envelope. Wraps in a {@link Message}<...>:\n * the request body sets `presetId` (the preset registry key) and\n * `taskInput` (the typed input passed to the spawned agent's `bundle.in`).\n */\nexport interface SpawnPayload<TIn> {\n\treadonly presetId: string;\n\treadonly taskInput: TIn;\n}\n\n/**\n * Rejection record published to the `rejected` topic when a spawn request\n * is denied. `reason` is a short human-readable code.\n */\nexport interface SpawnRejection<TIn> {\n\treadonly request: TopicMessage<SpawnPayload<TIn>>;\n\treadonly reason: string;\n}\n\n/**\n * Options for {@link spawnable}.\n */\nexport interface SpawnableOpts<TIn, TOut> {\n\t/** Existing messaging hub. {@link SPAWNS_TOPIC} is created lazily on it. */\n\treadonly hub: MessagingHubGraph;\n\t/** Preset registry — keys must match `request.payload.presetId`. */\n\treadonly registry: PresetRegistryBundle<AgentSpec<TIn, TOut>>;\n\t/**\n\t * Local mount name on the hub for this spawnable's subgraph. Multiple\n\t * spawnable instances on the same hub must use distinct names. Default\n\t * `\"spawnable\"`.\n\t */\n\treadonly name?: string;\n\t/** Maximum concurrently-active agents. Default unbounded. */\n\treadonly depthCap?: number;\n\t/**\n\t * Initial cursor for the spawn-topic subscription. Default `\"now\"` —\n\t * pre-existing retained spawn requests are NOT replayed at construction.\n\t * Pass `\"retained\"` to replay or a number for explicit cursor offset.\n\t */\n\treadonly from?: \"now\" | \"retained\" | number;\n\t/**\n\t * Optional caller-supplied validator. Returns `true` to accept the\n\t * request, `false` to reject. Reject reason on the `rejected` topic is\n\t * `\"schema validation failed\"`. Pair with the `Message.schema` field carried\n\t * in the envelope when full JSON-Schema validation is needed (consumer\n\t * supplies the validator — ajv / zod / valibot — and reads the schema\n\t * from the envelope to gate). The substrate itself does NOT ship a\n\t * JSON-Schema validator; the `Message.schema` field is wire convention.\n\t */\n\treadonly validate?: (request: TopicMessage<SpawnPayload<TIn>>) => boolean;\n}\n\n/**\n * The bundle returned by {@link spawnable}.\n */\nexport interface SpawnableBundle<TIn, TOut> {\n\t/** The well-known spawn topic — emit `TopicMessage<SpawnPayload<TIn>>` here. */\n\treadonly spawnTopic: TopicGraph<TopicMessage<SpawnPayload<TIn>>>;\n\t/** Reactive map of currently-active agent bundles, keyed by request id. */\n\treadonly activeSlot: Node<ReadonlyMap<string, AgentBundle<TIn, TOut>>>;\n\t/** Topic of rejected requests with reason. */\n\treadonly rejected: TopicGraph<SpawnRejection<TIn>>;\n\t/** The internal SpawnableGraph subgraph (mounted under the hub). */\n\treadonly graph: SpawnableGraph<TIn, TOut>;\n}\n\n// ---------------------------------------------------------------------------\n// SpawnableGraph\n// ---------------------------------------------------------------------------\n\n/**\n * Graph subclass implementing {@link SpawnableBundle}'s topology.\n * Mounted under the hub at `opts.name` (default `\"spawnable\"`).\n *\n * Topology:\n * ```\n * <hub>\n * ├── spawns (TopicGraph; well-known well-named spawn topic)\n * └── <name> (SpawnableGraph)\n * ├── spawn-sub (SubscriptionGraph over hub::spawns::events)\n * ├── rejected (TopicGraph<SpawnRejection>)\n * ├── active-slot (Node<ReadonlyMap<id, AgentBundle>>)\n * └── spawn-{req.id}/ (mounted AgentGraph per active spawn)\n * ```\n */\nexport class SpawnableGraph<TIn, TOut> extends Graph {\n\treadonly spawnTopic: TopicGraph<TopicMessage<SpawnPayload<TIn>>>;\n\treadonly rejected: TopicGraph<SpawnRejection<TIn>>;\n\treadonly activeSlot: Node<ReadonlyMap<string, AgentBundle<TIn, TOut>>>;\n\tprivate readonly _spawnSub: SubscriptionGraph<TopicMessage<SpawnPayload<TIn>>>;\n\tprivate readonly _registry: PresetRegistryBundle<AgentSpec<TIn, TOut>>;\n\tprivate readonly _depthCap: number | undefined;\n\tprivate readonly _validate: ((req: TopicMessage<SpawnPayload<TIn>>) => boolean) | undefined;\n\tprivate _disposed = false;\n\n\tconstructor(opts: SpawnableOpts<TIn, TOut>) {\n\t\tconst name = opts.name ?? \"spawnable\";\n\t\tsuper(name);\n\n\t\tthis._registry = opts.registry;\n\t\tthis._depthCap = opts.depthCap;\n\t\tthis._validate = opts.validate;\n\n\t\t// Spawn topic on the hub (well-known name; lazy-created if absent).\n\t\tthis.spawnTopic = opts.hub.topic<TopicMessage<SpawnPayload<TIn>>>(SPAWNS_TOPIC);\n\n\t\t// Rejected topic is private to this spawnable subgraph.\n\t\tthis.rejected = topic<SpawnRejection<TIn>>(\"rejected\");\n\t\tthis.mount(\"rejected\", this.rejected);\n\n\t\t// Active-slot map. `equals: () => false` so each mutation emits a\n\t\t// fresh snapshot even when callers pass an identity-equal Map ref.\n\t\tconst activeSlotNode = node<ReadonlyMap<string, AgentBundle<TIn, TOut>>>([], {\n\t\t\tname: \"active-slot\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"spawnable_active_slot\"),\n\t\t\tinitial: new Map(),\n\t\t\tequals: () => false,\n\t\t});\n\t\tthis.add(activeSlotNode, { name: \"active-slot\" });\n\t\tthis.activeSlot = activeSlotNode;\n\n\t\t// Cursor-based subscription over hub.spawnTopic.events. Lives under\n\t\t// this spawnable subgraph (NOT the hub), so multiple spawnable\n\t\t// instances on the same hub get independent cursors.\n\t\t// Default `from: \"now\"` skips pre-construction retained requests —\n\t\t// older requests are NOT replayed unless the caller opts in.\n\t\tthis._spawnSub = subscription<TopicMessage<SpawnPayload<TIn>>>(\"spawn-sub\", this.spawnTopic, {\n\t\t\tfrom: opts.from ?? \"now\",\n\t\t});\n\t\tthis.mount(\"spawn-sub\", this._spawnSub);\n\n\t\t// Subscribe to `available` to process new requests; ack as we go.\n\t\tconst subRef = this._spawnSub;\n\t\tconst unsub = subRef.available.subscribe((msgs) => {\n\t\t\tif (this._disposed) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tconst items = m[1] as readonly TopicMessage<SpawnPayload<TIn>>[];\n\t\t\t\tif (items.length === 0) continue;\n\t\t\t\tfor (const req of items) {\n\t\t\t\t\tif (this._disposed) return;\n\t\t\t\t\tthis._processRequest(req);\n\t\t\t\t}\n\t\t\t\tsubRef.ack(items.length);\n\t\t\t}\n\t\t});\n\t\tthis.addDisposer(unsub);\n\t\tthis.addDisposer(() => {\n\t\t\tthis._disposed = true;\n\t\t});\n\t\t// Keepalive on the active-slot Node so external `cache` reads stay\n\t\t// current even when no one is subscribed.\n\t\tthis.addDisposer(keepalive(activeSlotNode));\n\t}\n\n\tprivate _processRequest(req: TopicMessage<SpawnPayload<TIn>>): void {\n\t\tif (this._disposed) return;\n\n\t\t// Custom validation.\n\t\tif (this._validate && !this._validate(req)) {\n\t\t\tthis.rejected.publish({ request: req, reason: \"schema validation failed\" });\n\t\t\treturn;\n\t\t}\n\n\t\t// Expiry check (only on entry — per-agent timeouts during run are a\n\t\t// future iteration; recipe-style composition with `timeout` covers\n\t\t// the in-flight case until then). Use `wallClockNs()` so test\n\t\t// suites that monkey-patch the central clock can pin expiry decisions.\n\t\tif (req.expiresAt != null) {\n\t\t\tconst expiry = Date.parse(req.expiresAt);\n\t\t\tif (!Number.isFinite(expiry)) {\n\t\t\t\tthis.rejected.publish({ request: req, reason: \"invalid expiresAt\" });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst nowMs = wallClockNs() / 1_000_000;\n\t\t\tif (nowMs >= expiry) {\n\t\t\t\tthis.rejected.publish({ request: req, reason: \"expired\" });\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Depth-cap check.\n\t\tconst currentMap =\n\t\t\t(this.activeSlot.cache as ReadonlyMap<string, AgentBundle<TIn, TOut>> | undefined) ??\n\t\t\tnew Map();\n\t\tif (this._depthCap != null && currentMap.size >= this._depthCap) {\n\t\t\tthis.rejected.publish({\n\t\t\t\trequest: req,\n\t\t\t\treason: `depth-cap exceeded (${currentMap.size}/${this._depthCap})`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Look up preset.\n\t\tconst spec = this._registry.registry.get(req.payload.presetId);\n\t\tif (!spec) {\n\t\t\tthis.rejected.publish({\n\t\t\t\trequest: req,\n\t\t\t\treason: `unknown presetId: ${req.payload.presetId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Mint and mount the agent. Slot name is derived from the request id\n\t\t// so it's traceable in describe / explain output.\n\t\tconst slotName = `spawn-${req.id}`;\n\t\tlet bundle: AgentBundle<TIn, TOut>;\n\t\ttry {\n\t\t\tbundle = agent<TIn, TOut>(this, { ...spec, name: slotName });\n\t\t} catch (e) {\n\t\t\tthis.rejected.publish({\n\t\t\t\trequest: req,\n\t\t\t\treason: `agent mint failed: ${(e as Error).message ?? \"unknown\"}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// Update active-slot.\n\t\tconst updated = new Map(currentMap);\n\t\tupdated.set(req.id, bundle);\n\t\tthis.activeSlot.emit(updated);\n\n\t\t// Watch for completion BEFORE kicking, so a synchronous adapter that\n\t\t// drives status straight to \"done\" inside the kick still triggers\n\t\t// cleanup. Subscribe to status; on terminal, unmount + remove. Each\n\t\t// per-spawn statusUnsub releases inside `onTerminal` so we don't\n\t\t// accumulate dead disposers per-spawn over the spawnable's lifetime.\n\t\tlet statusUnsub: (() => void) | undefined;\n\t\tconst onTerminal = (stat: AgentStatus): void => {\n\t\t\tif (stat !== \"done\" && stat !== \"error\") return;\n\t\t\t// Idempotent — guard against double-fire.\n\t\t\tconst live =\n\t\t\t\t(this.activeSlot.cache as ReadonlyMap<string, AgentBundle<TIn, TOut>> | undefined) ??\n\t\t\t\tnew Map();\n\t\t\tif (!live.has(req.id)) return;\n\t\t\tbatch(() => {\n\t\t\t\ttry {\n\t\t\t\t\tthis.remove(slotName);\n\t\t\t\t} catch {\n\t\t\t\t\t// Already removed (e.g., parent destroyed mid-flight).\n\t\t\t\t}\n\t\t\t\tconst next = new Map(live);\n\t\t\t\tnext.delete(req.id);\n\t\t\t\tthis.activeSlot.emit(next);\n\t\t\t});\n\t\t\t// Release the per-spawn status subscription now that the spawn\n\t\t\t// is finished — prevents disposer accumulation over many spawns.\n\t\t\tstatusUnsub?.();\n\t\t\tstatusUnsub = undefined;\n\t\t};\n\t\tstatusUnsub = bundle.status.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) onTerminal(m[1] as AgentStatus);\n\t\t\t}\n\t\t});\n\t\t// Defensive disposer — fires on SpawnableGraph.destroy() if the\n\t\t// spawn is still in-flight. `onTerminal` clears `statusUnsub` so\n\t\t// double-call is a no-op.\n\t\tthis.addDisposer(() => statusUnsub?.());\n\n\t\t// Kick the agent reactively.\n\t\tbundle.in.emit(req.payload.taskInput);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// spawnable() factory\n// ---------------------------------------------------------------------------\n\n/**\n * Constructs a {@link SpawnableGraph}, mounts it under `opts.hub` at\n * `opts.name` (default `\"spawnable\"`), and returns the\n * {@link SpawnableBundle} contract.\n *\n * **Composition with Phase 13 substrate:**\n * - Builds on **13.B** ({@link Message} envelope, {@link SPAWNS_TOPIC}).\n * - Builds on **13.G/H** ({@link agent}, {@link AgentBundle}).\n * - Builds on **13.H** ({@link presetRegistry}).\n * - The depth-cap gate is documented as a **13.D recipe**\n * (`valve(spawnTopic, derived([depthCounter], n => n < cap))`); inside\n * `spawnable()` the depth check is per-request so over-cap requests\n * surface on `rejected`. Callers wanting a hard cut (no rejection\n * signal) can wrap their publish path with `valve`.\n *\n * **Strategy-key axis (DS-13.I):** when `harnessLoop` is wired to a\n * spawnable, downstream `strategy.record(...)` calls should pass the\n * spawning agent's `presetId` for the {@link strategyKey} first axis.\n * Single-agent harness keeps using {@link DEFAULT_PRESET_ID} as before.\n *\n * @example\n * ```ts\n * const hub = messagingHub(\"hub\");\n * const presets = presetRegistry<AgentSpec<string, LLMResponse>>();\n * presets.put(\"researcher\", { name: \"researcher\", adapter: openai, systemPrompt: \"...\" });\n * presets.put(\"coder\", { name: \"coder\", adapter: anthropic, systemPrompt: \"...\" });\n *\n * const sp = spawnable({ hub, registry: presets, depthCap: 5 });\n *\n * // Trigger a spawn:\n * sp.spawnTopic.publish({\n * id: \"req-42\",\n * payload: { presetId: \"researcher\", taskInput: \"what is reactive graph composition?\" },\n * });\n *\n * // Observe active agents:\n * sp.activeSlot.subscribe((msgs) => { ... });\n *\n * // Observe rejections:\n * sp.rejected.events.subscribe((msgs) => { ... });\n * ```\n *\n * @category patterns\n */\nexport function spawnable<TIn = string, TOut = LLMResponse>(\n\topts: SpawnableOpts<TIn, TOut>,\n): SpawnableBundle<TIn, TOut> {\n\tconst graph = new SpawnableGraph<TIn, TOut>(opts);\n\topts.hub.mount(opts.name ?? \"spawnable\", graph);\n\treturn {\n\t\tspawnTopic: graph.spawnTopic,\n\t\tactiveSlot: graph.activeSlot,\n\t\trejected: graph.rejected,\n\t\tgraph,\n\t};\n}\n","/**\n * Phase 13.H — `agent(spec)` preset + `presetRegistry` sugar.\n *\n * Source: `archive/docs/SESSION-multi-agent-gap-analysis.md` G1 + G2.\n *\n * `agent()` is the ergonomic factory — given a parent Graph and an\n * `AgentSpec`, mints an `AgentGraph`, mounts it under the parent at\n * `spec.name`, and returns the `AgentBundle` contract.\n *\n * `presetRegistry()` is thin sugar over `reactiveMap` — a typed reactive\n * map of `<id, preset>`. Pairs with `materialize` (Phase 13.C) for\n * dynamic preset selection: callers store specs / factories / configs in\n * the registry and `materialize` mounts the matching one based on a\n * routing key.\n *\n * **Cross-cut #1 lock:** no `agent.run()` imperative sugar — caller-side\n * runtime is `bundle.in.emit(input)` + `awaitSettled(bundle.out)`.\n */\n\nimport { type ReactiveMapBundle, reactiveMap } from \"@graphrefly/pure-ts/extra\";\nimport type { Graph } from \"@graphrefly/pure-ts/graph\";\nimport type { LLMResponse } from \"../../utils/ai/adapters/core/types.js\";\nimport { type AgentBundle, AgentGraph, type AgentSpec } from \"./agent.js\";\n\n// ---------------------------------------------------------------------------\n// agent() factory\n// ---------------------------------------------------------------------------\n\n/**\n * Mints an {@link AgentGraph} from `spec`, mounts it under `parent` at\n * `spec.name`, and returns the {@link AgentBundle} contract.\n *\n * **Default type parameters.** When called without explicit type params,\n * `TIn` defaults to `string` and `TOut` to `LLMResponse` — the common\n * case where the caller writes a user message and reads the raw response.\n * Custom types require both `inMapper` and `outMapper` in the spec; the\n * default mappers throw at runtime if `TIn` / `TOut` aren't string /\n * LLMResponse.\n *\n * **Memory partition default.** Each `agent()` call mints its own\n * `AgentMemoryGraph` if `spec.memory` is omitted (private memory; the\n * common case). Pass an explicit shared instance — e.g.\n * `agent(parent, { ..., memory: sharedMemory })` for two agents — to\n * implement §29 handoff context transfer.\n *\n * **Reactive entry / exit:**\n * - `bundle.in.emit(input)` kicks the loop reactively (no imperative\n * `.run()` per cross-cut #1 lock).\n * - `awaitSettled(bundle.out, { skipCurrent: true })` resolves on the\n * first response after the kick. `skipCurrent` matters for the second\n * call onward — `out` caches the prior response.\n *\n * **Mounting.** The factory mounts under `parent.mount(spec.name, ...)`.\n * The slot name must be free on `parent` at construction time. To keep\n * the agent unmounted, construct `new AgentGraph(spec)` directly.\n *\n * @example\n * ```ts\n * import { agent, awaitSettled, Graph } from \"@graphrefly/graphrefly-ts\";\n *\n * const parent = new Graph(\"parent\");\n * const a = agent(parent, {\n * name: \"researcher\",\n * adapter: openaiAdapter,\n * systemPrompt: \"Research the user's question carefully.\",\n * });\n * a.in.emit(\"What's the capital of France?\");\n * const resp = await awaitSettled(a.out, { skipCurrent: true });\n * ```\n *\n * @category patterns\n */\nexport function agent<TIn = string, TOut = LLMResponse>(\n\tparent: Graph,\n\tspec: AgentSpec<TIn, TOut>,\n): AgentBundle<TIn, TOut> {\n\tconst graph = new AgentGraph<TIn, TOut>(spec);\n\tparent.mount(spec.name, graph);\n\treturn {\n\t\tin: graph.in,\n\t\tout: graph.out,\n\t\tstatus: graph.status,\n\t\tcost: graph.cost,\n\t\tgraph,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// presetRegistry()\n// ---------------------------------------------------------------------------\n\n/**\n * The bundle returned by {@link presetRegistry}. Wraps a `reactiveMap`\n * with imperative `put` / `remove` shortcuts and exposes the underlying\n * `registry` for direct reactive consumption (`.entries` is a\n * `Node<ReadonlyMap<string, TPreset>>`).\n *\n * Use the `registry.entries` Node directly with {@link materialize} (Phase\n * 13.C) — pass it as the `factories` argument when `TPreset` is itself\n * a `() => Graph` factory thunk, or transform via `derived` when\n * `TPreset` is a richer spec type that needs a `spec → factory` adapter.\n */\nexport interface PresetRegistryBundle<TPreset> {\n\t/**\n\t * The underlying reactive map. `registry.entries` is the\n\t * `Node<ReadonlyMap<string, TPreset>>` — pass directly to\n\t * {@link materialize} when preset shape matches the factories arg.\n\t */\n\treadonly registry: ReactiveMapBundle<string, TPreset>;\n\t/** Imperative add / replace. Always emits a fresh snapshot. */\n\tput(id: string, preset: TPreset): void;\n\t/** Imperative remove. Returns `true` if the id was present. */\n\tremove(id: string): boolean;\n}\n\n/**\n * Thin sugar over `reactiveMap` — a typed registry of `<id, preset>` for\n * agent / strategy / persona / skill catalogs.\n *\n * **Generic over preset shape.** `TPreset` is open — could be an\n * {@link AgentSpec}, a `() => Graph` factory thunk, a static config\n * object, or anything else. Decoupled from `agent()` so the same primitive\n * powers harnessLoop strategy registries, pipelineGraph stage catalogs,\n * etc.\n *\n * **Composes with `materialize`.** When `TPreset` is a `() => Graph`\n * factory, pass `registry.entries` directly to\n * {@link materialize} as the `factories` argument. When `TPreset` is a\n * spec, transform via `derived` to build a `Map<id, () => Graph>` adapter:\n *\n * ```ts\n * const presets = presetRegistry<AgentSpec<string, LLMResponse>>();\n * presets.put(\"researcher\", { name: \"researcher\", adapter, systemPrompt: \"...\" });\n *\n * // Adapter: spec → factory.\n * const factories = derived(\n * [presets.registry.entries],\n * ([m]) => new Map(\n * [...m].map(([id, spec]) => [id, () => new AgentGraph(spec)]),\n * ),\n * );\n * const slot = materialize(activeKey, factories, parent);\n * ```\n *\n * @param initial - Optional initial entries.\n * @returns {@link PresetRegistryBundle}.\n *\n * @category patterns\n */\nexport function presetRegistry<TPreset>(\n\tinitial?: ReadonlyMap<string, TPreset>,\n): PresetRegistryBundle<TPreset> {\n\tconst registry = reactiveMap<string, TPreset>({ name: \"presetRegistry\" });\n\tif (initial != null) {\n\t\tfor (const [id, preset] of initial) {\n\t\t\tregistry.set(id, preset);\n\t\t}\n\t}\n\treturn {\n\t\tregistry,\n\t\tput(id, preset) {\n\t\t\tregistry.set(id, preset);\n\t\t},\n\t\tremove(id) {\n\t\t\tif (!registry.has(id)) return false;\n\t\t\tregistry.delete(id);\n\t\t\treturn true;\n\t\t},\n\t};\n}\n","/**\n * Phase 13.G — `AgentBundle<TIn, TOut>` interface + `class AgentGraph extends Graph`.\n *\n * Source: `archive/docs/SESSION-multi-agent-gap-analysis.md` G1 lock B.\n *\n * Composes the existing substrate (`agentLoop`, `toolRegistry`,\n * `agentMemory`) into a typed inbox/outbox subgraph that other parts of a\n * multi-agent system can wire to. Sibling preset `agent()` (in\n * `./agents.ts`) is the ergonomic factory; this file is the contract.\n *\n * **Cross-cut #1 lock (no `agent.run()`):** caller-side runtime entry is\n * `bundle.in.emit(input)` + `awaitSettled(bundle.out)`. The legacy\n * `agentLoop.run()` is still available on `bundle.graph.loop` for\n * single-shot Promise-bridge use cases, but `agent()` does NOT expose a\n * `run()` method on the bundle.\n *\n * **Memory partition default:** private memory per agent (each `agent(...)`\n * call creates its own `AgentMemoryGraph` if none passed). Pass an explicit\n * shared instance for §29 handoff context-transfer.\n */\n\nimport { batch, DATA, INVALIDATE, type Node, node, RESOLVED } from \"@graphrefly/pure-ts/core\";\nimport { keepalive } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { aiMeta } from \"../../utils/ai/_internal.js\";\nimport type {\n\tInputTokens,\n\tLLMAdapter,\n\tLLMResponse,\n\tOutputTokens,\n\tTokenUsage,\n\tToolDefinition,\n} from \"../../utils/ai/adapters/core/types.js\";\nimport {\n\ttype SubscriptionGraph,\n\tsubscription,\n\ttype TopicGraph,\n\ttopic,\n} from \"../../utils/messaging/index.js\";\nimport { type AgentLoopGraph, agentLoop } from \"./agent-loop.js\";\nimport type { AgentMemoryGraph } from \"./agent-memory.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Lifecycle status of an {@link AgentGraph}.\n *\n * - `idle` — no input has been received since construction or last reset.\n * - `running` — inputs are flowing through the underlying agentLoop\n * (collapses the loop's `thinking` + `acting` substates so consumers\n * don't have to model the tool-call inner loop).\n * - `verifying` — verifier subgraph is in flight (reserved; lights up when\n * the verifier slot is added in a future wave per G7 recipe).\n * - `done` — the most recent input has settled with a verified response.\n * - `error` — the loop or verifier produced a terminal error.\n *\n * **Note (Phase 13.G, 2026-05-01):** v1 of `agent()` has no built-in\n * verifier slot — `verifying` is reserved but never produced. When a\n * verifier consumer surfaces, this enum widens (non-breaking type\n * widening; existing consumers see the same `idle | running | done | error`\n * subset).\n */\nexport type AgentStatus = \"idle\" | \"running\" | \"verifying\" | \"done\" | \"error\";\n\n/**\n * Aggregated cost for an agent's run, surfaced as a `Node<CostState>` on\n * the bundle. **Wraps the canonical {@link TokenUsage}** so consumers get\n * the full provider-disaggregated token classes (cache-read /\n * cache-write-5m / cache-write-1h / audio / image / video / tool-use /\n * reasoning / prediction-accepted / prediction-rejected / extensions /\n * auxiliary non-token costs / raw escape-hatch) without losing fidelity\n * for downstream pricing. USD conversion is a downstream `derived` over\n * `usage`.\n *\n * - `usage` — accumulated {@link TokenUsage} across all turns of the\n * current input.\n * - `turns` — number of completed agentLoop iterations (LLM invocations).\n *\n * **Counter scope:** resets to {@link ZERO_COST} on each new `bundle.in`\n * emit (per-input cost rather than per-agent-lifetime). Sum across multiple\n * inputs by snapshotting `cost` at `done` and accumulating externally —\n * a per-lifetime cost is a downstream `scan` over this.\n *\n * **Helpers.** Use `sumInputTokens(usage)` / `sumOutputTokens(usage)` from\n * `@graphrefly/graphrefly-ts` to flatten to scalars when the caller wants\n * a single number.\n */\nexport interface CostState {\n\treadonly usage: TokenUsage;\n\treadonly turns: number;\n}\n\nconst EMPTY_INPUT: InputTokens = Object.freeze({ regular: 0 });\nconst EMPTY_OUTPUT: OutputTokens = Object.freeze({ regular: 0 });\nconst EMPTY_USAGE: TokenUsage = Object.freeze({ input: EMPTY_INPUT, output: EMPTY_OUTPUT });\n\n/** Empty cost. Used as the initial value and the per-input reset baseline. */\nexport const ZERO_COST: CostState = Object.freeze({ usage: EMPTY_USAGE, turns: 0 });\n\n// ---------------------------------------------------------------------------\n// TokenUsage accumulator\n// ---------------------------------------------------------------------------\n\nfunction addOptional(a: number | undefined, b: number | undefined): number | undefined {\n\tif (a == null && b == null) return undefined;\n\treturn (a ?? 0) + (b ?? 0);\n}\n\nfunction addExtensions(\n\ta: Record<string, number> | undefined,\n\tb: Record<string, number> | undefined,\n): Record<string, number> | undefined {\n\tif (a == null && b == null) return undefined;\n\tconst out: Record<string, number> = { ...(a ?? {}) };\n\tfor (const [k, v] of Object.entries(b ?? {})) {\n\t\tout[k] = (out[k] ?? 0) + v;\n\t}\n\treturn out;\n}\n\n/**\n * Accumulates two {@link TokenUsage} snapshots. All field classes are\n * summed; optional fields propagate as `undefined` when absent from both\n * sides, otherwise treated as 0 for the missing side. `auxiliary` and\n * `extensions` merge by key. `raw` is dropped — it's a per-call escape\n * hatch, not summable.\n *\n * @category extra\n */\nexport function addUsage(a: TokenUsage, b: TokenUsage): TokenUsage {\n\tconst out: TokenUsage = {\n\t\tinput: {\n\t\t\tregular: a.input.regular + b.input.regular,\n\t\t\t...(addOptional(a.input.cacheRead, b.input.cacheRead) !== undefined && {\n\t\t\t\tcacheRead: addOptional(a.input.cacheRead, b.input.cacheRead) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.cacheWrite5m, b.input.cacheWrite5m) !== undefined && {\n\t\t\t\tcacheWrite5m: addOptional(a.input.cacheWrite5m, b.input.cacheWrite5m) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.cacheWrite1h, b.input.cacheWrite1h) !== undefined && {\n\t\t\t\tcacheWrite1h: addOptional(a.input.cacheWrite1h, b.input.cacheWrite1h) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.cacheWriteOther, b.input.cacheWriteOther) !== undefined && {\n\t\t\t\tcacheWriteOther: addOptional(a.input.cacheWriteOther, b.input.cacheWriteOther) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.audio, b.input.audio) !== undefined && {\n\t\t\t\taudio: addOptional(a.input.audio, b.input.audio) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.image, b.input.image) !== undefined && {\n\t\t\t\timage: addOptional(a.input.image, b.input.image) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.video, b.input.video) !== undefined && {\n\t\t\t\tvideo: addOptional(a.input.video, b.input.video) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.input.toolUse, b.input.toolUse) !== undefined && {\n\t\t\t\ttoolUse: addOptional(a.input.toolUse, b.input.toolUse) as number,\n\t\t\t}),\n\t\t\t...(addExtensions(a.input.extensions, b.input.extensions) !== undefined && {\n\t\t\t\textensions: addExtensions(a.input.extensions, b.input.extensions) as Record<string, number>,\n\t\t\t}),\n\t\t},\n\t\toutput: {\n\t\t\tregular: a.output.regular + b.output.regular,\n\t\t\t...(addOptional(a.output.reasoning, b.output.reasoning) !== undefined && {\n\t\t\t\treasoning: addOptional(a.output.reasoning, b.output.reasoning) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.output.audio, b.output.audio) !== undefined && {\n\t\t\t\taudio: addOptional(a.output.audio, b.output.audio) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.output.predictionAccepted, b.output.predictionAccepted) !== undefined && {\n\t\t\t\tpredictionAccepted: addOptional(\n\t\t\t\t\ta.output.predictionAccepted,\n\t\t\t\t\tb.output.predictionAccepted,\n\t\t\t\t) as number,\n\t\t\t}),\n\t\t\t...(addOptional(a.output.predictionRejected, b.output.predictionRejected) !== undefined && {\n\t\t\t\tpredictionRejected: addOptional(\n\t\t\t\t\ta.output.predictionRejected,\n\t\t\t\t\tb.output.predictionRejected,\n\t\t\t\t) as number,\n\t\t\t}),\n\t\t\t...(addExtensions(a.output.extensions, b.output.extensions) !== undefined && {\n\t\t\t\textensions: addExtensions(a.output.extensions, b.output.extensions) as Record<\n\t\t\t\t\tstring,\n\t\t\t\t\tnumber\n\t\t\t\t>,\n\t\t\t}),\n\t\t},\n\t\t...(addExtensions(a.auxiliary, b.auxiliary) !== undefined && {\n\t\t\tauxiliary: addExtensions(a.auxiliary, b.auxiliary) as Record<string, number>,\n\t\t}),\n\t};\n\treturn out;\n}\n\n/**\n * Spec for {@link agent} (in `./agents.ts`). Required fields are minimal —\n * `name` and `adapter` cover the common case where the input is a string\n * and the output is the raw `LLMResponse`. Optional fields shape the\n * agent's behavior:\n *\n * - **Mappers** (`inMapper` / `outMapper`) translate between caller-typed\n * `TIn` / `TOut` and the loop's internal `string` / `LLMResponse`. Default\n * identity mappers are wired automatically when `TIn` extends `string`\n * and `TOut` extends `LLMResponse`.\n * - **`tools`** is a reactive `NodeInput<readonly ToolDefinition[]>` —\n * `agent()` subscribes and reconciles the underlying `toolRegistry`'s\n * registrations on each emit. Static-array form is also accepted.\n * - **`memory`** is an explicit `AgentMemoryGraph` instance for shared\n * memory across agents (§29 handoff context transfer). Default: private\n * memory per agent (each `agent()` call mints its own).\n * - **`maxIterations`** caps the underlying agentLoop's tool-call inner\n * loop. Default 10 (matches `agentLoop`).\n * - **Verifier slot** is intentionally not in v1 — G7 reframe locks it as\n * a caller-composed recipe. When a real consumer surfaces, a\n * `verifier?: (out: Node<TOut>) => NodeInput<VerifierResult>` field\n * lands here additively.\n */\nexport interface AgentSpec<TIn, TOut> {\n\t/** Local mount name when wired to a parent graph. Required. */\n\treadonly name: string;\n\t/** LLM adapter for the underlying agentLoop. Required. */\n\treadonly adapter: LLMAdapter;\n\t/** Optional system prompt. Static today; reactive widening pending. */\n\treadonly systemPrompt?: string;\n\t/**\n\t * Optional reactive tool list. When a Node, the agent subscribes and\n\t * reconciles the underlying `toolRegistry` registrations on each emit\n\t * (additions registered, removals unregistered). When a static array,\n\t * tools are registered once at construction.\n\t */\n\treadonly tools?: Node<readonly ToolDefinition[]> | readonly ToolDefinition[];\n\t/**\n\t * Optional shared memory. Default: private (agent mints its own\n\t * `AgentMemoryGraph` if needed; not yet wired into the loop's chat —\n\t * that wiring is a separate follow-up). Pass an explicit instance to\n\t * share memory across agents for §29 handoff context transfer.\n\t */\n\treadonly memory?: AgentMemoryGraph<unknown>;\n\t/**\n\t * Maps caller-typed input → string for the underlying chat. Defaults to\n\t * identity when `TIn extends string`; required otherwise.\n\t */\n\treadonly inMapper?: (input: TIn) => string;\n\t/**\n\t * Maps the agentLoop's `LLMResponse` → caller-typed output. Defaults to\n\t * identity when `TOut extends LLMResponse`; required otherwise.\n\t */\n\treadonly outMapper?: (response: LLMResponse) => TOut;\n\t/** Caps tool-call inner-loop iterations. Default 10. */\n\treadonly maxIterations?: number;\n\t/** Escape hatch for non-core fields. Surfaced in `describe()` via meta. */\n\treadonly meta?: Record<string, unknown>;\n}\n\n/**\n * Public contract for an agent — typed inbox/outbox + lifecycle / cost\n * observables + the underlying graph for inspection / mounting.\n *\n * **Reactive entry:** caller writes to `in` (e.g. `bundle.in.emit(input)`).\n * The agent reactively kicks the underlying loop and produces `out`.\n *\n * **Reactive exit:** caller reads `out` via `subscribe` (continuous) or\n * `awaitSettled(out)` (single-shot). Both `in` and `out` stay SENTINEL\n * (`cache === undefined`) until the first real emission — no `null`\n * push-on-subscribe trap (per `feedback_use_prevdata_for_sentinel`).\n *\n * **Cross-graph wiring:** the bundle's `graph` is mountable under any\n * parent via `parent.mount(name, bundle.graph)`. After mount, the bundle's\n * Nodes are reachable through both the bundle reference (direct) and via\n * `parent.node(\"<name>::out\")` etc. (qualified path).\n */\nexport interface AgentBundle<TIn, TOut> {\n\treadonly in: Node<TIn>;\n\treadonly out: Node<TOut>;\n\treadonly status: Node<AgentStatus>;\n\treadonly cost: Node<CostState>;\n\treadonly graph: AgentGraph<TIn, TOut>;\n}\n\n// ---------------------------------------------------------------------------\n// AgentGraph\n// ---------------------------------------------------------------------------\n\nconst TERMINAL_STATUSES = new Set<AgentStatus>([\"done\", \"error\"]);\n\n/**\n * Graph subclass implementing {@link AgentBundle}. Mounts an inner\n * {@link AgentLoopGraph} at `loop/`; `in` / `out` / `status` / `cost`\n * surface the bundle contract as top-level nodes.\n *\n * Construction is internal — use the {@link agent} factory in\n * `./agents.ts` for normal use. Direct `new AgentGraph(name, spec)` is\n * supported for callers that want full control over mount order.\n *\n * **Topology:**\n * ```\n * <name>\n * ├── loop (AgentLoopGraph subgraph)\n * │ ├── chat\n * │ ├── tools\n * │ ├── status / turn / aborted / lastResponse / ...\n * ├── in (Node<TIn>, SENTINEL until first emit)\n * ├── out (Node<TOut>, SENTINEL until first response)\n * ├── status (Node<AgentStatus>, mirror of loop.status)\n * └── cost (Node<CostState>)\n * ```\n *\n * **Lifecycle:**\n * - On `in` emit: `inMapper` projects to `string`; appended to\n * `loop.chat`; loop status reset (`turn=0`, `aborted=false`,\n * `status=\"thinking\"`); per-input cost counters reset to zero.\n * - On `loop.lastResponse` emit: cost rolls forward; `out` emits\n * `outMapper(response)`.\n * - On `loop.status=\"done\"`: agent's status emits `\"done\"`.\n * - On `loop.status=\"error\"` (or any ERROR propagation): agent's status\n * emits `\"error\"`.\n */\nexport class AgentGraph<TIn, TOut> extends Graph {\n\t/** The agent's typed inbox. Writable; `in.emit(value)` kicks the loop. */\n\treadonly in: Node<TIn>;\n\t/** The agent's typed outbox. SENTINEL until first response. */\n\treadonly out: Node<TOut>;\n\t/** Lifecycle status (translated from the underlying loop's substates). */\n\treadonly status: Node<AgentStatus>;\n\t/** Cumulative cost for the current / most-recent input. */\n\treadonly cost: Node<CostState>;\n\t/** The underlying agentLoop — exposed for inspection / advanced wiring. */\n\treadonly loop: AgentLoopGraph;\n\t/** Optional shared memory subgraph (mounted at `memory/` if provided). */\n\treadonly memory: AgentMemoryGraph<unknown> | null;\n\n\tconstructor(spec: AgentSpec<TIn, TOut>, opts?: GraphOptions) {\n\t\tsuper(spec.name, opts);\n\n\t\t// --- 1. Mount the agentLoop subgraph. ------------------------------\n\t\tconst initialTools = Array.isArray(spec.tools)\n\t\t\t? (spec.tools as readonly ToolDefinition[])\n\t\t\t: undefined;\n\t\tthis.loop = agentLoop(`${spec.name}-loop`, {\n\t\t\tadapter: spec.adapter,\n\t\t\t...(spec.systemPrompt != null ? { systemPrompt: spec.systemPrompt } : {}),\n\t\t\t...(initialTools != null ? { tools: initialTools } : {}),\n\t\t\t...(spec.maxIterations != null ? { maxTurns: spec.maxIterations } : {}),\n\t\t});\n\t\tthis.mount(\"loop\", this.loop);\n\n\t\t// --- 2. Reactive tools subscription (if Node-form). ----------------\n\t\t// agentLoop's tools are static-array at construction; we reconcile\n\t\t// dynamically by subscribing to the user's reactive Node and\n\t\t// register/unregister against the inner toolRegistry.\n\t\tif (spec.tools != null && !Array.isArray(spec.tools)) {\n\t\t\tconst toolsNode = spec.tools as Node<readonly ToolDefinition[]>;\n\t\t\tconst registered = new Set<string>();\n\t\t\tconst unsubTools = toolsNode.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\tconst next = m[1] as readonly ToolDefinition[];\n\t\t\t\t\tconst nextNames = new Set(next.map((t) => t.name));\n\t\t\t\t\t// Unregister missing.\n\t\t\t\t\tfor (const name of registered) {\n\t\t\t\t\t\tif (!nextNames.has(name)) {\n\t\t\t\t\t\t\tthis.loop.tools.unregister(name);\n\t\t\t\t\t\t\tregistered.delete(name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// Register new (idempotent guard via local tracking).\n\t\t\t\t\tfor (const tool of next) {\n\t\t\t\t\t\tif (!registered.has(tool.name)) {\n\t\t\t\t\t\t\tthis.loop.tools.register(tool);\n\t\t\t\t\t\t\tregistered.add(tool.name);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.addDisposer(unsubTools);\n\t\t}\n\n\t\t// --- 3. Optional shared memory subgraph (passed through). ----------\n\t\t// v1: memory is mounted but NOT yet wired into the loop's chat — the\n\t\t// chat-context-from-memory glue is a separate follow-up. Mounting it\n\t\t// here gives the bundle a stable surface for §29 handoff (callers\n\t\t// can pass the SAME instance to multiple agents for shared memory).\n\t\tthis.memory = spec.memory ?? null;\n\t\tif (this.memory != null) {\n\t\t\tthis.mount(\"memory\", this.memory);\n\t\t}\n\n\t\t// --- 4. `in` — the typed inbox. ------------------------------------\n\t\t// SENTINEL until first emit; `equals: () => false` so re-emitting the\n\t\t// same value still kicks (no spurious dedup of repeat inputs).\n\t\tthis.in = node<TIn>([], {\n\t\t\tname: \"in\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"agent_in\"),\n\t\t\tequals: () => false,\n\t\t});\n\t\tthis.add(this.in, { name: \"in\" });\n\n\t\t// --- 5. `cost` — per-input token counters. -------------------------\n\t\tconst costNode = node<CostState>([], {\n\t\t\tname: \"cost\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"agent_cost\"),\n\t\t\tinitial: ZERO_COST,\n\t\t});\n\t\tthis.add(costNode, { name: \"cost\" });\n\t\tthis.cost = costNode;\n\n\t\t// --- 6. `out` — the typed outbox. ----------------------------------\n\t\t// Derived from `loop.lastResponse`. SENTINEL while `loop.lastResponse`\n\t\t// has never emitted a real response (F9 fix: the loop now stays\n\t\t// SENTINEL too — no more eager `null` placeholder), so the SENTINEL\n\t\t// detector inside the fn is `prevData[0] === undefined`. Between\n\t\t// runs, `loop.lastResponse.down([[INVALIDATE]])` clears that\n\t\t// `prevData` slot back to undefined, so this derived correctly gates\n\t\t// to RESOLVED on the next status=\"idle\" wave.\n\t\tconst outMapper = spec.outMapper ?? defaultOutMapper<TOut>();\n\t\tconst outNode = node<TOut>(\n\t\t\t[this.loop.lastResponse],\n\t\t\t(data, a, ctx) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tconst resp =\n\t\t\t\t\tbatch0 != null && batch0.length > 0\n\t\t\t\t\t\t? (batch0.at(-1) as LLMResponse | undefined)\n\t\t\t\t\t\t: (ctx.prevData[0] as LLMResponse | undefined);\n\t\t\t\tif (resp === undefined) {\n\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ta.emit(outMapper(resp));\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"out\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"agent_out\"),\n\t\t\t\t// Each in.emit may produce a structurally-equal response (e.g.\n\t\t\t\t// from a deterministic adapter) — disable framework dedup so\n\t\t\t\t// repeat emits propagate and `awaitSettled({skipCurrent:true})`\n\t\t\t\t// sees them. Callers can wrap with `distinctUntilChanged` if\n\t\t\t\t// they want change-only semantics.\n\t\t\t\tequals: () => false,\n\t\t\t},\n\t\t);\n\t\tthis.add(outNode, { name: \"out\" });\n\t\tthis.out = outNode;\n\n\t\t// --- 7. `status` — translated from loop.status. --------------------\n\t\t// Mirror via §32 pattern: a state node downstream consumers depend on,\n\t\t// reset and updated by an effect listening to loop.status.\n\t\tconst statusNode = node<AgentStatus>([], {\n\t\t\tname: \"status\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"agent_status\"),\n\t\t\tinitial: \"idle\",\n\t\t});\n\t\tthis.add(statusNode, { name: \"status\" });\n\t\tthis.status = statusNode;\n\n\t\tconst statusMirrorEff = node(\n\t\t\t[this.loop.status],\n\t\t\t(data, _a, ctx) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tconst loopStatus =\n\t\t\t\t\tbatch0 != null && batch0.length > 0\n\t\t\t\t\t\t? (batch0.at(-1) as string)\n\t\t\t\t\t\t: ((ctx.prevData[0] as string | undefined) ?? \"idle\");\n\t\t\t\tconst next: AgentStatus =\n\t\t\t\t\tloopStatus === \"idle\"\n\t\t\t\t\t\t? \"idle\"\n\t\t\t\t\t\t: loopStatus === \"thinking\" || loopStatus === \"acting\"\n\t\t\t\t\t\t\t? \"running\"\n\t\t\t\t\t\t\t: loopStatus === \"done\"\n\t\t\t\t\t\t\t\t? \"done\"\n\t\t\t\t\t\t\t\t: loopStatus === \"error\"\n\t\t\t\t\t\t\t\t\t? \"error\"\n\t\t\t\t\t\t\t\t\t: \"idle\";\n\t\t\t\tif (statusNode.cache !== next) statusNode.emit(next);\n\t\t\t},\n\t\t\t{ describeKind: \"effect\", meta: aiMeta(\"agent_status_mirror\") },\n\t\t);\n\t\tthis.addDisposer(keepalive(statusMirrorEff));\n\n\t\t// --- 8. Cost-rollup effect. ---------------------------------------\n\t\t// Rolls forward on each loop.lastResponse emission. Reads\n\t\t// loop.turn.cache for the iteration count (sole-owner-reactive-reader\n\t\t// per Phase 12 D1 lock — loop is mounted as a subgraph of this Graph).\n\t\t// SENTINEL gate: `prevData[0] === undefined` means no response has\n\t\t// ever been delivered for this run (post-INVALIDATE reset between\n\t\t// runs), so the rollup short-circuits.\n\t\tconst costEff = node(\n\t\t\t[this.loop.lastResponse],\n\t\t\t(data, _a, ctx) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tconst resp =\n\t\t\t\t\tbatch0 != null && batch0.length > 0\n\t\t\t\t\t\t? (batch0.at(-1) as LLMResponse | undefined)\n\t\t\t\t\t\t: (ctx.prevData[0] as LLMResponse | undefined);\n\t\t\t\tif (resp === undefined) return;\n\t\t\t\tconst prev = (costNode.cache as CostState | undefined) ?? ZERO_COST;\n\t\t\t\tconst turns = (this.loop.turn.cache as number | undefined) ?? prev.turns;\n\t\t\t\tconst next: CostState = {\n\t\t\t\t\tusage: resp.usage != null ? addUsage(prev.usage, resp.usage) : prev.usage,\n\t\t\t\t\tturns,\n\t\t\t\t};\n\t\t\t\tcostNode.emit(next);\n\t\t\t},\n\t\t\t{ describeKind: \"effect\", meta: aiMeta(\"agent_cost_rollup\") },\n\t\t);\n\t\tthis.addDisposer(keepalive(costEff));\n\n\t\t// --- 9. `in` → input queue → drain → kick the loop. ----------------\n\t\t// Phase 13.G/H + /qa N1(b) lock (2026-05-01): bundle.in is a\n\t\t// writable surface, but kicks are queued through an internal\n\t\t// hub-style topic + cursor subscription. Out-of-the-box queueing —\n\t\t// caller fires `in.emit(x)` while the agent is mid-run; the input\n\t\t// is parked on the queue and picked up when the loop returns to\n\t\t// `idle` / `done` / `error`. No mid-run reset / cost-leak hazard\n\t\t// (which the prior raw `in.subscribe → kick` path had).\n\t\t//\n\t\t// Topology:\n\t\t// `in` (state Node, writable) → `inputBridge` (subscribe →\n\t\t// publish) → `inputTopic` (TopicGraph<TIn>) → `inputSub`\n\t\t// (SubscriptionGraph<TIn>) → `drainEffect` (effect on\n\t\t// [inputSub.available, loop.status]) → loop kick.\n\t\tconst inMapper = spec.inMapper ?? defaultInMapper<TIn>();\n\t\tconst inputTopic: TopicGraph<TIn> = topic<TIn>(\"input-topic\");\n\t\tthis.mount(\"input-topic\", inputTopic);\n\t\tconst inputSub: SubscriptionGraph<TIn> = subscription<TIn>(\"input-sub\", inputTopic, {\n\t\t\tfrom: \"now\",\n\t\t});\n\t\tthis.mount(\"input-sub\", inputSub);\n\n\t\t// Bridge: `in.emit(x)` publishes to the topic. Validates the\n\t\t// caller-supplied input via `inMapper` at the boundary so the\n\t\t// type error surfaces in the caller's stack frame (not later\n\t\t// during drain). Per the F9 SENTINEL trap, `in` cache is\n\t\t// `undefined` until the first emit; push-on-subscribe delivers\n\t\t// nothing.\n\t\tconst inputBridge = this.in.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\tconst input = m[1] as TIn;\n\t\t\t\t// Boundary type-check: throws if TIn is not string and no\n\t\t\t\t// inMapper supplied. Better here than at drain time so the\n\t\t\t\t// caller's `in.emit(...)` raises synchronously.\n\t\t\t\tinMapper(input);\n\t\t\t\tinputTopic.publish(input);\n\t\t\t}\n\t\t});\n\t\tthis.addDisposer(inputBridge);\n\n\t\t// Drain effect: when an input is pending AND the loop is ready\n\t\t// (`idle` / `done` / `error`), pull one and kick. Re-entrancy\n\t\t// guard via `loop.status` — `thinking` / `acting` skip.\n\t\tconst drainEffect = node(\n\t\t\t[inputSub.available, this.loop.status],\n\t\t\t(data, _a, ctx) => {\n\t\t\t\tconst availBatch = data[0];\n\t\t\t\tconst statusBatch = data[1];\n\t\t\t\tconst avail =\n\t\t\t\t\t(availBatch != null && availBatch.length > 0\n\t\t\t\t\t\t? (availBatch.at(-1) as readonly TIn[])\n\t\t\t\t\t\t: ((ctx.prevData[0] as readonly TIn[] | undefined) ?? [])) ?? [];\n\t\t\t\tconst stat =\n\t\t\t\t\t(statusBatch != null && statusBatch.length > 0\n\t\t\t\t\t\t? (statusBatch.at(-1) as string)\n\t\t\t\t\t\t: ((ctx.prevData[1] as string | undefined) ?? \"idle\")) ?? \"idle\";\n\t\t\t\tif (avail.length === 0) return;\n\t\t\t\tif (stat === \"thinking\" || stat === \"acting\") return;\n\t\t\t\tconst result = inputSub.pullAndAck(1);\n\t\t\t\tif (result.items.length === 0) return;\n\t\t\t\tconst input = result.items[0] as TIn;\n\t\t\t\tconst userMsg = inMapper(input);\n\t\t\t\tbatch(() => {\n\t\t\t\t\t// Reset per-input accumulators so cost/turns don't include\n\t\t\t\t\t// the previous input. `lastResponse` is reset via plain\n\t\t\t\t\t// `[[INVALIDATE]]` — under DS-13.5.A INVALIDATE both clears\n\t\t\t\t\t// `_cached` AND settles the consuming wave (decrements\n\t\t\t\t\t// `_dirtyDepCount` like RESOLVED), so dependents like\n\t\t\t\t\t// `out` / `costEff` fire on the next status transition\n\t\t\t\t\t// without staying wedged in DIRTY. Pre-DS-13.5.A this used\n\t\t\t\t\t// the `[[INVALIDATE], [RESOLVED]]` paired-reset workaround.\n\t\t\t\t\tthis.loop.lastResponse.down([[INVALIDATE]]);\n\t\t\t\t\tthis.loop.turn.emit(0);\n\t\t\t\t\tthis.loop.aborted.emit(false);\n\t\t\t\t\tcostNode.emit(ZERO_COST);\n\t\t\t\t\tthis.loop.chat.append(\"user\", userMsg);\n\t\t\t\t\tthis.loop.status.emit(\"thinking\");\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ describeKind: \"effect\", meta: aiMeta(\"agent_input_drain\") },\n\t\t);\n\t\tthis.addDisposer(keepalive(drainEffect));\n\n\t\t// `out` and `status` keepalives are unnecessary because the cost /\n\t\t// status effects above already activate `loop.lastResponse` and\n\t\t// `loop.status` — the derived `out` reads from a kept-alive source.\n\t\t// We do keep `out` alive explicitly so `awaitSettled(bundle.out,\n\t\t// { skipCurrent: true })` works even when no other consumer\n\t\t// subscribes between input and response.\n\t\tthis.addDisposer(keepalive(this.out));\n\n\t\t// Surface in describe.\n\t\tvoid TERMINAL_STATUSES;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Default mappers\n// ---------------------------------------------------------------------------\n\n/**\n * Default `inMapper` for `TIn extends string`. Asserts the runtime type at\n * the boundary so callers who omit `inMapper` for a non-string `TIn` get a\n * clear error rather than a silent passthrough.\n */\nfunction defaultInMapper<TIn>(): (input: TIn) => string {\n\treturn (input) => {\n\t\tif (typeof input !== \"string\") {\n\t\t\tthrow new TypeError(\n\t\t\t\t`agent: inMapper is required when TIn is not a string (got ${typeof input}). Pass spec.inMapper.`,\n\t\t\t);\n\t\t}\n\t\treturn input;\n\t};\n}\n\n/**\n * Default `outMapper` for `TOut extends LLMResponse`. Asserts the response\n * shape at the boundary; callers with a non-LLMResponse `TOut` must\n * provide `outMapper`.\n */\nfunction defaultOutMapper<TOut>(): (response: LLMResponse) => TOut {\n\treturn (response) => response as unknown as TOut;\n}\n","/**\n * Reactive agent loop — autonomous multi-turn LLM agent with tool execution.\n */\n\nexport type AgentLoopStatus = \"idle\" | \"thinking\" | \"acting\" | \"done\" | \"error\";\n\nimport {\n\tbatch,\n\tDATA,\n\tERROR,\n\tINVALIDATE,\n\ttype Node,\n\tnode,\n\tnode as nodeFactory,\n\tplaceholderArgs,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport { fromAny, keepalive, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport { awaitSettled } from \"../../base/sources/settled.js\";\nimport { aiMeta } from \"../../utils/ai/_internal.js\";\nimport type {\n\tChatMessage,\n\tLLMAdapter,\n\tLLMResponse,\n\tToolCall,\n\tToolDefinition,\n} from \"../../utils/ai/adapters/core/types.js\";\nimport { type ChatStreamGraph, chatStream } from \"../../utils/ai/agents/chat-stream.js\";\nimport { type ToolResult, toolExecution } from \"../../utils/ai/agents/tool-execution.js\";\nimport { type ToolRegistryGraph, toolRegistry } from \"../../utils/ai/agents/tool-registry.js\";\n\nexport type { ToolResult } from \"../../utils/ai/agents/tool-execution.js\";\n\n// ---------------------------------------------------------------------------\n// agentLoop\n// ---------------------------------------------------------------------------\n\nexport type AgentLoopOptions = {\n\tgraph?: GraphOptions;\n\tadapter: LLMAdapter;\n\ttools?: readonly ToolDefinition[];\n\tsystemPrompt?: string;\n\tmaxTurns?: number;\n\tstopWhen?: (response: LLMResponse) => boolean;\n\tonToolCall?: (call: ToolCall) => void;\n\tmaxMessages?: number;\n\tmodel?: string;\n\ttemperature?: number;\n\tmaxTokens?: number;\n\t/**\n\t * Reactive tool-call splice (COMPOSITION-GUIDE §31 \"interception is security\").\n\t * When set, the raw `toolCalls` node is piped through this transform before\n\t * reaching the executor. The transform is a pure reactive composition —\n\t * `(calls: Node<readonly ToolCall[]>) => Node<readonly ToolCall[]>` — so the\n\t * gate is visible in `describe()` / `explain()` as a real edge (no hidden\n\t * imperative wraps; §24).\n\t *\n\t * Typical uses:\n\t * - **Filter / block** — `derived([calls, policy], ([raw, p]) => raw.filter(p))`\n\t * - **Throttle / debounce** — `throttle(calls, windowMs)`\n\t * - **Human-in-the-loop approval** — pipe through a `gate` controller so\n\t * calls wait for human approval before reaching the executor.\n\t *\n\t * The public `agent.toolCalls` node surfaces the POST-intercept stream, so\n\t * audit / telemetry consumers see what the executor actually runs. The raw\n\t * pre-intercept stream is not exposed — tests that need it should run\n\t * without `interceptToolCalls` set (the identity case).\n\t */\n\tinterceptToolCalls?: (calls: Node<readonly ToolCall[]>) => Node<readonly ToolCall[]>;\n};\n\n/**\n * Reactive agent loop.\n *\n * The loop is a reactive state machine wired entirely from graph primitives:\n * `chat.messages` + `tools.schemas` + gating state feed a `promptInput`\n * derived; `switchMap` turns non-null inputs into an LLM invocation via\n * `fromAny(adapter.invoke(...))`. The LLM response drives chat writes and\n * status transitions via effects. Tool calls flow through a reactive\n * executor (`retrySource` + `rescue`) that retries once on error and\n * surfaces terminal errors as JSON-shaped `ToolResult` payloads for the\n * LLM to react to.\n *\n * **No imperative control flow inside the reactive layer** (spec §5.8-5.12):\n * no `while` loops, no manual `await adapter.invoke`, no polling.\n * `agent.run()` is a thin `awaitSettled` bridge so callers can still `await`\n * the loop if they want a Promise.\n *\n * Public surface:\n * - `chat` / `tools` — subgraphs (imperative `append` at boundary, reactive `executeReactive` for tool invocation)\n * - `status` / `turn` / `aborted` — state nodes with explicit initials\n * - `lastResponse` / `toolCalls` / `toolResults` — reactive outputs (SENTINEL until first emission; callers use `awaitSettled` / `subscribe`)\n * - `run(userMessage?, signal?)` — optional user append + Promise bridge\n * - `abort()` — imperative abort shim; flips `aborted` state\n *\n * **Lifecycle: single-mount.** `AgentLoopGraph` instances expect to be\n * constructed once and used until `destroy()`. The internal closure mirrors\n * (`latestTurn` / `latestAborted` / `latestStatus`) are wired by\n * subscribe-and-capture at construction time; their `addDisposer`-registered\n * subscriptions are torn down on subgraph unmount or `destroy()`. After\n * teardown the mirrors freeze at their last value, so re-using a destroyed\n * instance — calling `run()` again, or remounting under a new parent —\n * would silently feed stale mirror data into reactive fn bodies. If you\n * need to \"reset\" an agent, build a fresh `AgentLoopGraph` instance instead\n * of recycling.\n */\nexport class AgentLoopGraph extends Graph {\n\treadonly chat: ChatStreamGraph;\n\treadonly tools: ToolRegistryGraph;\n\n\t/** Current agent status. `initial: \"idle\"` — always has a real value. */\n\treadonly status: Node<AgentLoopStatus>;\n\t/** Turn count (completed LLM invocations this run). `initial: 0`. */\n\treadonly turn: Node<number>;\n\t/** Aborted flag; flipped by `abort()` or external `AbortSignal`. `initial: false`. */\n\treadonly aborted: Node<boolean>;\n\n\t/**\n\t * Most recent LLM response. State-backed mirror driven by the response\n\t * effect. **Stays SENTINEL** (`cache === undefined`, no DATA emitted)\n\t * until the first real response — bridge subscribers see no spurious\n\t * push-on-subscribe DATA. After a real response, holds the latest\n\t * `LLMResponse`. Reset between `run()` calls via `[[INVALIDATE]]` (clears\n\t * cache back to SENTINEL) so a second run with a pre-aborted signal\n\t * cannot leak the prior run's response. Bridge with\n\t * `awaitSettled(lastResponse)` for the first DATA as a Promise; consumers\n\t * inside reactive fns gate on `ctx.prevData[i] === undefined`.\n\t */\n\treadonly lastResponse: Node<LLMResponse>;\n\t/** Tool-call batch emitted by the most recent LLM response. SENTINEL. */\n\treadonly toolCalls: Node<readonly ToolCall[]>;\n\t/** Tool-result batch (one entry per call) after reactive execution. SENTINEL. */\n\treadonly toolResults: Node<readonly ToolResult[]>;\n\n\tprivate readonly _terminalResult: Node<LLMResponse>;\n\tprivate readonly _disposeRunWiring: () => void;\n\t/** Guards against overlapping `run()` calls. */\n\tprivate _running = false;\n\t/**\n\t * Abort controller for the currently-running `adapter.invoke`. Minted per\n\t * switchMap project; aborted when the reactive `aborted` node flips true\n\t * OR when the caller's external `AbortSignal` fires. Threaded into\n\t * `adapter.invoke({ signal })` AND `fromAny(promise, { signal })`, so the\n\t * reactive layer sees ERROR when the wire call is cancelled.\n\t */\n\tprivate _currentAbortController: AbortController | null = null;\n\n\tconstructor(name: string, opts: AgentLoopOptions) {\n\t\tsuper(name, opts.graph);\n\n\t\t// Mount chat subgraph\n\t\tthis.chat = chatStream(`${name}-chat`, { maxMessages: opts.maxMessages });\n\t\tthis.mount(\"chat\", this.chat);\n\n\t\t// Mount tool registry subgraph\n\t\tthis.tools = toolRegistry(`${name}-tools`);\n\t\tthis.mount(\"tools\", this.tools);\n\n\t\tif (opts.tools) {\n\t\t\tfor (const tool of opts.tools) {\n\t\t\t\tthis.tools.register(tool);\n\t\t\t}\n\t\t}\n\n\t\t// --- State nodes (always have a real value; explicit initials) ---\n\t\tthis.status = node<AgentLoopStatus>([], {\n\t\t\t...{\n\t\t\t\tname: \"status\",\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tmeta: aiMeta(\"agent_status\"),\n\t\t\t},\n\t\t\tinitial: \"idle\",\n\t\t});\n\t\tthis.add(this.status, { name: \"status\" });\n\n\t\tthis.turn = node<number>([], {\n\t\t\t...{\n\t\t\t\tname: \"turn\",\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tmeta: aiMeta(\"agent_turn_count\"),\n\t\t\t},\n\t\t\tinitial: 0,\n\t\t});\n\t\tthis.add(this.turn, { name: \"turn\" });\n\n\t\tthis.aborted = node<boolean>([], {\n\t\t\t...{\n\t\t\t\tname: \"aborted\",\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tmeta: aiMeta(\"agent_aborted\"),\n\t\t\t},\n\t\t\tinitial: false,\n\t\t});\n\t\tthis.add(this.aborted, { name: \"aborted\" });\n\n\t\t// --- Reactive pipeline ---\n\t\t//\n\t\t// **Read pattern (Phase 12 D1 lock + F2 fix 2026-05-01).** State\n\t\t// scratchpad held on this `AgentLoopGraph` (turn / aborted / chat /\n\t\t// tools) is read inside reactive fn bodies via either:\n\t\t// (a) `data[i]` / `ctx.prevData[i]` for declared deps, OR\n\t\t// (b) sole-owner `.cache` reads on subgraph-mounted state Nodes\n\t\t// (chat / tools mounted as subgraphs of this Graph; the agent\n\t\t// is the sole owner; promptInput / effResponse / effResults\n\t\t// live in the same enclosing constructor scope — sanctioned\n\t\t// form per Phase 12 D1 read-pattern lock).\n\t\t//\n\t\t// Closure mirrors (`latestTurn` / `latestAborted` / `latestStatus`)\n\t\t// are kept ONLY for fields where (b) doesn't simplify the call site\n\t\t// — turn / aborted / status are state Nodes registered on `this`\n\t\t// directly (not subgraphs), and the closure form keeps\n\t\t// effResponse's batch logic readable. They are CORRECT but are NOT\n\t\t// safe under nested drains (the subscribe handler may not have run\n\t\t// yet when a downstream fn reads the closure). For nested-drain-\n\t\t// reachable reads (promptInput, called via `agentLoop.run` from\n\t\t// inside another graph's reactive subscribe handler), prefer (a) or\n\t\t// (b) over the closure mirror. F2 root cause: chat.messages.cache\n\t\t// is updated DURING the DATA-settle phase (before subscribers\n\t\t// run), so `.cache` reads are always at least as fresh as closure\n\t\t// mirrors. See `optimizations.md` \"Phase 13 design-session inputs\n\t\t// from §13.M lock-test\" F2.\n\t\t//\n\t\t// **Pattern note on `latestTurn` staleness under in-batch reads.**\n\t\t// Effect 1 emits `turnNode.emit(next)` inside its batch; Effect 2\n\t\t// reads `latestTurn` on the following wave (after toolResults\n\t\t// settle). Because batch drain is FIFO, `turnSub`'s handler runs\n\t\t// before Effect 2's next wave fires, so `latestTurn` is up-to-date\n\t\t// by the time Effect 2 reads it. This invariant is stable as long\n\t\t// as `turnNode.emit` remains inside Effect 1's batch — a future\n\t\t// refactor that un-batches the emit would regress silently.\n\t\tlet latestTurn = 0;\n\t\tconst turnSub = this.turn.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) if (m[0] === DATA) latestTurn = m[1] as number;\n\t\t});\n\t\tlet latestAborted = false;\n\t\tconst abortedSub = this.aborted.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) if (m[0] === DATA) latestAborted = m[1] as boolean;\n\t\t});\n\n\t\tconst adapter = opts.adapter;\n\t\tconst systemPrompt = opts.systemPrompt;\n\t\tconst model = opts.model;\n\t\tconst temperature = opts.temperature;\n\t\tconst maxTokens = opts.maxTokens;\n\t\tconst maxTurns = opts.maxTurns ?? 10;\n\t\tconst stopWhen = opts.stopWhen;\n\n\t\t// Capture `this` for closures that don't bind `this`.\n\t\tconst chat = this.chat;\n\t\tconst tools = this.tools;\n\t\tconst statusNode = this.status;\n\t\tconst turnNode = this.turn;\n\t\tconst abortedNode = this.aborted;\n\n\t\t// promptInput: STATUS is the only reactive trigger — chat.messages,\n\t\t// tools.schemas, turn, aborted are sampled via closure-held mirrors\n\t\t// (all populated by subscribe-and-capture above). This prevents the\n\t\t// classic feedback cycle (COMPOSITION-GUIDE §7): if chat.messageCount\n\t\t// were a reactive dep here, effect 1's `chat.append` would trigger a\n\t\t// promptInput wave, which under effect-1's batch would see status\n\t\t// STILL \"thinking\" (pre-drain) and fire a spurious LLM invocation.\n\t\t// By gating only on status, chat writes don't re-trigger — only\n\t\t// explicit status transitions do.\n\t\tconst promptInput: Node<InvokeInput> = nodeFactory<InvokeInput>(\n\t\t\t[statusNode],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\tconst stat = readLatest<AgentLoopStatus>(data, ctx.prevData, 0, \"idle\");\n\t\t\t\tif (stat !== \"thinking\" || latestAborted || latestTurn >= maxTurns) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// F2 fix (2026-05-01): under nested drains, the closure mirrors\n\t\t\t\t// `latestMessages` / `latestSchemas` lag the actual node state —\n\t\t\t\t// messagesSub / schemasSub subscribers may not have run yet when\n\t\t\t\t// promptInput fires (the drain processes status's downstream\n\t\t\t\t// before chat.messages's subscribers fire, even though\n\t\t\t\t// chat.messages.cache is already settled). Read `.cache`\n\t\t\t\t// directly per Phase 12 D1 read-pattern lock: chat / tools are\n\t\t\t\t// mounted as subgraphs of this AgentLoopGraph (sole owner) and\n\t\t\t\t// promptInput is a reactive reader in the same enclosing\n\t\t\t\t// constructor scope — sanctioned `.cache` form. See\n\t\t\t\t// `optimizations.md` \"Phase 13 design-session inputs from §13.M\n\t\t\t\t// lock-test\" F2.\n\t\t\t\tconst messages = (this.chat.messages.cache as readonly ChatMessage[] | undefined) ?? [];\n\t\t\t\tif (messages.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst schemas = (this.tools.schemas.cache as readonly ToolDefinition[] | undefined) ?? [];\n\t\t\t\tactions.emit({ messages, tools: schemas });\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"promptInput\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"agent_prompt_input\", {\n\t\t\t\t\t// State this fn body samples beyond its declared `statusNode`\n\t\t\t\t\t// dep. `aborted` / `turn` come from §28 closure mirrors\n\t\t\t\t\t// (`latestAborted` / `latestTurn`); `chat.messages` /\n\t\t\t\t\t// `tools.schemas` come from sole-owner `.cache` reads\n\t\t\t\t\t// (Phase 12 D1 lock + F2 fix; see comment block above).\n\t\t\t\t\t// Listed here so inspection tooling can surface fold-in\n\t\t\t\t\t// state without grepping source.\n\t\t\t\t\tclosureReads: [\"aborted\", \"turn\", \"chat.messages\", \"tools.schemas\"],\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tconst llmResponse: Node<LLMResponse> = switchMap(\n\t\t\tpromptInput,\n\t\t\t(input) => {\n\t\t\t\tconst controller = new AbortController();\n\t\t\t\tthis._currentAbortController = controller;\n\t\t\t\tif (latestAborted) {\n\t\t\t\t\tcontroller.abort(new Error(\"agentLoop: aborted\"));\n\t\t\t\t}\n\t\t\t\t// Wave A Unit B-CC fix: drop the `Promise.resolve(adapter.invoke(...))`\n\t\t\t\t// wrapper. `adapter.invoke` returns a `NodeInput<LLMResponse>`\n\t\t\t\t// (Promise | Node | raw). `fromAny` already handles all three\n\t\t\t\t// shapes; the manual `Promise.resolve` wrapper would force a\n\t\t\t\t// Node-returning adapter into an extra microtask hop and lose\n\t\t\t\t// reactivity (see Unit 11 + Unit 1 for the parallel cleanup).\n\t\t\t\treturn fromAny(\n\t\t\t\t\tadapter.invoke(input.messages, {\n\t\t\t\t\t\ttools: input.tools.length > 0 ? input.tools : undefined,\n\t\t\t\t\t\tsystemPrompt,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\ttemperature,\n\t\t\t\t\t\tmaxTokens,\n\t\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t\t}),\n\t\t\t\t\t{ signal: controller.signal },\n\t\t\t\t);\n\t\t\t},\n\t\t\t{ equals: () => false },\n\t\t);\n\n\t\t// State mirror for `lastResponse` — exists for **cross-run reset\n\t\t// semantics**, NOT the §32 mid-wave hazard.\n\t\t//\n\t\t// Why: `llmResponse` is a switchMap output; its cache persists across\n\t\t// `run()` calls (switchMap's output node has no built-in reset path —\n\t\t// the cache stays at the last DATA the inner emitted). A second\n\t\t// `run()` with a pre-aborted signal would otherwise have\n\t\t// `_terminalResult` evaluate `stat=done` (driven by `effAbort`) +\n\t\t// `resp=<prior run's response>` (cached on `llmResponse`) and resolve\n\t\t// the Promise with stale data instead of rejecting with AbortError.\n\t\t// The mirror is **reset via `[[INVALIDATE]]`** in `run()`'s reset\n\t\t// batch — INVALIDATE clears `_cached` back to `undefined` (SENTINEL)\n\t\t// AND clears the `prevData` slot on every dependent (`_terminalResult`,\n\t\t// `toolCallsRaw`), so the abort path correctly emits\n\t\t// `[[ERROR, AbortError]]` from terminalResult's `stat=\"done\" &&\n\t\t// prevData[lastResponse] === undefined → ERROR` guard.\n\t\t//\n\t\t// **No `T | null` placeholder.** Per `feedback_use_prevdata_for_sentinel`\n\t\t// + COMPOSITION-GUIDE §1a, the SENTINEL state IS the \"never sent\n\t\t// real DATA yet\" signal. An eager `initial: null` would push `[null]`\n\t\t// to every fresh subscriber — a footgun for bridge subscribers that\n\t\t// would otherwise need `if (resp == null) continue` guards. Stay\n\t\t// SENTINEL; consumers detect \"no response yet\" via\n\t\t// `ctx.prevData[i] === undefined` (or `cache === undefined` outside\n\t\t// reactive fns). F9 lock-test (`multi-agent-example.test.ts` test 5)\n\t\t// pins this invariant.\n\t\t//\n\t\t// What this does NOT solve: the §32 mid-wave \"stale peer-read\"\n\t\t// hazard. Investigation (2026-04-25) confirmed `_dirtyDepCount`\n\t\t// gating in `_maybeRunFnOnSettlement` already prevents that — when\n\t\t// `effResponse`'s nested batch fires `status=\"done\"` mid-iteration,\n\t\t// terminal's status dep settles but its `llmResponse` (or mirror)\n\t\t// dep is still DIRTY from Phase 1, so the fn does not run until\n\t\t// Phase 2 visits both deps. Verified by fast-check invariant `#12b\n\t\t// nested-drain-peer-consistency-compound` and by the multi-turn\n\t\t// `executes tool calls and loops` test passing under either dep\n\t\t// shape (`[statusNode, llmResponse]` or `[statusNode, lastResponseState]`).\n\t\t//\n\t\t// Verified by: QA C3 regression tests (`run() with pre-aborted\n\t\t// signal rejects AbortError` and `second run() with pre-aborted\n\t\t// signal rejects AbortError (no stale response leak)`) — both\n\t\t// fail when `_terminalResult` is rewired to depend on `llmResponse`\n\t\t// directly. See COMPOSITION-GUIDE §32 (cross-wave reset reframe).\n\t\tconst lastResponseState = node<LLMResponse>([], {\n\t\t\tname: \"lastResponse\",\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: aiMeta(\"agent_last_response\"),\n\t\t});\n\t\tthis.lastResponse = lastResponseState;\n\n\t\t// toolCalls: raw node that emits DATA only when status === \"acting\" and\n\t\t// the current response has tool calls. Otherwise emits RESOLVED. Using\n\t\t// DATA([]) for the idle case would cause switchMap(toolCalls) to\n\t\t// re-dispatch its inner (creating a fresh node([], { initial: [] }) source whose\n\t\t// emissions re-trigger effects downstream). RESOLVED keeps the inner\n\t\t// alive and lets upstream waves pass through without re-dispatch.\n\t\t// Inner raw tool-call stream — name `toolCallsRaw` so the post-intercept\n\t\t// public surface (`this.toolCalls`) is unambiguous in `describe()`.\n\t\t// QA-fix: previously the inner was named `\"toolCalls\"`, which collided\n\t\t// with `this.toolCalls` if the user-supplied interceptor returned a\n\t\t// wrapper that internally retained a reference to this raw node —\n\t\t// `describe()` would render two distinct nodes both labeled `\"toolCalls\"`.\n\t\tconst toolCallsRaw = nodeFactory<readonly ToolCall[]>(\n\t\t\t[lastResponseState, statusNode],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\t// SENTINEL guard: `lastResponseState` stays `undefined` (cache\n\t\t\t\t// + prevData) until the first real response. `readLatest`'s\n\t\t\t\t// fallback returns `undefined` here so the no-DATA branch is\n\t\t\t\t// indistinguishable from the protocol SENTINEL — both gate to\n\t\t\t\t// RESOLVED. Per `feedback_use_prevdata_for_sentinel`.\n\t\t\t\tconst resp = readLatest<LLMResponse | undefined>(data, ctx.prevData, 0, undefined);\n\t\t\t\tconst stat = readLatest<AgentLoopStatus>(data, ctx.prevData, 1, \"idle\");\n\t\t\t\tif (stat !== \"acting\") {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst calls = resp?.toolCalls;\n\t\t\t\tif (calls == null || calls.length === 0) {\n\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.emit(calls);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"toolCallsRaw\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"agent_tool_calls_raw\"),\n\t\t\t},\n\t\t);\n\t\t// Reactive splice (D9 / COMPOSITION-GUIDE §31). When `interceptToolCalls`\n\t\t// is set, the raw tool-call stream is transformed in the graph — the\n\t\t// executor sees the gated stream, and `agent.toolCalls` surfaces the\n\t\t// post-intercept view so audit / telemetry match reality.\n\t\tconst gatedToolCallsNode = opts.interceptToolCalls\n\t\t\t? opts.interceptToolCalls(toolCallsRaw)\n\t\t\t: toolCallsRaw;\n\t\tthis.toolCalls = gatedToolCallsNode;\n\n\t\t// Delegate per-call fan-out + retry + rescue to the `toolExecution`\n\t\t// primitive. `toolCallsRaw` already gates empty batches to RESOLVED,\n\t\t// so `toolExecution`'s \"non-empty batch only\" contract is satisfied\n\t\t// upstream. `retryCount: 1` matches the pre-extraction behaviour\n\t\t// (one retry after first failure = 2 attempts total).\n\t\tconst toolResultsNode: Node<readonly ToolResult[]> = toolExecution({\n\t\t\ttoolCalls: gatedToolCallsNode,\n\t\t\ttools,\n\t\t\tretryCount: 1,\n\t\t});\n\t\tthis.toolResults = toolResultsNode;\n\n\t\t// --- State-machine effects ---\n\t\t// Effect 1: LLM response landed → write lastResponse mirror + chat,\n\t\t// transition status, increment turn. Emission ORDER inside the batch\n\t\t// matters (drain is FIFO under any outer-batch depth):\n\t\t// 1. `lastResponseState.emit(response)` FIRST — so when the drain\n\t\t// fires the status=done wave later in the queue, `_terminalResult`'s\n\t\t// dep on `lastResponseState` has already been updated.\n\t\t// 2. `statusNode.emit(nextStatus)` — drives state machine.\n\t\t// 3. `turnNode.emit(next)` — counter.\n\t\t// 4. `chat.append(...)` LAST — chat.messageCount wave now sees the\n\t\t// new status (so `promptInput` gates correctly).\n\t\t// Without (1) first, `_terminalResult` reads stale `prevData` for\n\t\t// lastResponse when status transitions synchronously during drain.\n\t\t//\n\t\t// **Invariant independence from outer batch depth.** `downWithBatch`\n\t\t// preserves FIFO drain order regardless of nesting — whether the\n\t\t// outer batch is at depth 0 (common: Promise microtask) or depth >0\n\t\t// (user-composed `batch()` scope around `agent.run()`), the emissions\n\t\t// above drain in the order they were enqueued. The state-mirror\n\t\t// pattern holds in both cases.\n\t\t//\n\t\t// **Abort guard (C2 defense-in-depth).** If the `aborted` state has\n\t\t// flipped true between `adapter.invoke`'s Promise resolution and this\n\t\t// effect firing (micro-race), bail out so we don't append to chat or\n\t\t// execute tool calls for an abandoned run. The controller.abort() in\n\t\t// effAbort also fires the signal, which causes `fromAny` to emit\n\t\t// ERROR — but that ERROR propagation arrives in a separate wave, so\n\t\t// this guard covers the \"Promise already resolved before abort hit\n\t\t// the controller\" case.\n\t\tconst effResponse = node(\n\t\t\t[llmResponse],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tif (latestAborted) return;\n\t\t\t\tconst response = data[0] as LLMResponse;\n\t\t\t\tconst next = latestTurn + 1;\n\t\t\t\tconst hasToolCalls = response.toolCalls != null && response.toolCalls.length > 0;\n\t\t\t\tconst naturalStop =\n\t\t\t\t\tresponse.finishReason === \"end_turn\" &&\n\t\t\t\t\t(!response.toolCalls || response.toolCalls.length === 0);\n\t\t\t\tconst customStop = stopWhen?.(response) === true;\n\t\t\t\tconst capReached = next >= maxTurns;\n\t\t\t\tconst nextStatus: AgentLoopStatus =\n\t\t\t\t\tcustomStop || naturalStop || !hasToolCalls || capReached ? \"done\" : \"acting\";\n\t\t\t\tbatch(() => {\n\t\t\t\t\tlastResponseState.emit(response);\n\t\t\t\t\tstatusNode.emit(nextStatus);\n\t\t\t\t\tturnNode.emit(next);\n\t\t\t\t\tchat.append(\"assistant\", response.content, {\n\t\t\t\t\t\ttoolCalls: response.toolCalls,\n\t\t\t\t\t});\n\t\t\t\t\t// EC-2 (DS-2.7.A /qa carry, resolved 2026-05-21):\n\t\t\t\t\t// cap-reached with pending `tool_use` blocks needs synthetic\n\t\t\t\t\t// `tool_result`s — every `tool_use` requires a paired\n\t\t\t\t\t// `tool_result` per Anthropic/OpenAI tool-use schemas, else\n\t\t\t\t\t// audit/replay consumers replaying `loop.chat.allMessages()`\n\t\t\t\t\t// into a fresh `adapter.invoke` see an invalid transcript.\n\t\t\t\t\t// `effFullDeny` (when wired) CANNOT help here: status flips\n\t\t\t\t\t// to `\"done\"` in this same batch, so `toolCallsRaw` gates\n\t\t\t\t\t// RESOLVED on the next wave (its `stat === \"acting\"` guard)\n\t\t\t\t\t// and `effFullDeny`'s diamond never delivers DATA. Mirrors\n\t\t\t\t\t// `effFullDeny`'s `\"[tool call denied by interceptor]\"`\n\t\t\t\t\t// pattern with a maxTurns-specific reason string.\n\t\t\t\t\tif (capReached && hasToolCalls) {\n\t\t\t\t\t\tfor (const tc of response.toolCalls as readonly ToolCall[]) {\n\t\t\t\t\t\t\tchat.appendToolResult(tc.id, \"[tool call denied: maxTurns reached]\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\n\t\t);\n\n\t\t// Effect 2: Tool results landed → append to chat, transition to\n\t\t// thinking (or done if turn cap reached). Same ordering discipline —\n\t\t// status emits before chat mutations. Abort guard mirrors effResponse.\n\t\tconst effResults = node(\n\t\t\t[toolResultsNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tif (latestAborted) return;\n\t\t\t\tconst arr = data[0] as readonly ToolResult[];\n\t\t\t\tif (arr.length === 0) return;\n\t\t\t\tconst nextStatus: AgentLoopStatus = latestTurn >= maxTurns ? \"done\" : \"thinking\";\n\t\t\t\tbatch(() => {\n\t\t\t\t\tstatusNode.emit(nextStatus);\n\t\t\t\t\tfor (const r of arr) chat.appendToolResult(r.id, r.content);\n\t\t\t\t});\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\n\t\t);\n\n\t\t// Effect 2b: interceptor-denial recovery. `effResponse` commits\n\t\t// `status=\"acting\"` from the LLM's *pre-intercept* `response.toolCalls`.\n\t\t// When an interceptor denies EVERY call, the post-intercept stream emits\n\t\t// RESOLVED (no DATA) — `toolExecution` no-ops, `effResults` never fires,\n\t\t// and `status` is stranded at \"acting\" forever (`run()` never resolves;\n\t\t// the original liveness bug). On partial deny, `effResults` advances\n\t\t// status correctly for the allowed subset, but the *denied* subset has\n\t\t// no matching `tool_result` — every assistant `tool_use` block needs\n\t\t// one for the next `adapter.invoke` to see a valid transcript per the\n\t\t// LLM-vendor schemas. This effect handles both: it synthesizes\n\t\t// `\"[tool call denied by interceptor]\"` `tool_result`s for whichever\n\t\t// calls were dropped (the full set on full deny, the dropped subset on\n\t\t// partial deny) so the LLM can adapt under the policy (user-locked:\n\t\t// continue, not terminate).\n\t\t//\n\t\t// **Why a [raw, gated] diamond with explicit `partial: true` and NO\n\t\t// `ctx.latestData[1]` fallback.** `gatedToolCallsNode` derives from\n\t\t// `toolCallsRaw`, so the two deps form a diamond — the fn recomputes\n\t\t// once after both settle (spec §1.4 / §2.7), with `batchData[0]` = the\n\t\t// raw requested calls and `batchData[1]` = the gate's emission *this\n\t\t// wave*. The core `node()` default is `partial: false` (node.ts\n\t\t// `opts.partial ?? false`); under that default, an R2.7.0 first-run\n\t\t// gate would hold this fn forever once the gate hits a RESOLVED-only\n\t\t// dep (the gate releases only on real DATA per R2.7.0). Explicit\n\t\t// `partial: true` opts into spec R2.7.2 (DS-2.7.A, 2026-05-19): the\n\t\t// gate is OFF and the fn-body is contractually responsible for\n\t\t// guarding SENTINEL slots. We DELIBERATELY do not fall back to\n\t\t// `ctx.latestData[1]` (the public name for `DepRecord.prevData`):\n\t\t// the signal IS \"the gate delivered no DATA this wave\" (RESOLVED on\n\t\t// the full-deny branch). A fallback would read a *prior allowed\n\t\t// turn*'s calls and mask the deny.\n\t\t//\n\t\t// Only wired when an interceptor is configured (`gatedToolCallsNode\n\t\t// !== toolCallsRaw`): without one there is no deny path, and a\n\t\t// `[toolCallsRaw, toolCallsRaw]` duplicate-dep node would be pointless.\n\t\t//\n\t\t// **Closure-mirror staleness** — the `latestTurn` read below relies on\n\t\t// the same FIFO drain ordering invariant the existing block at lines\n\t\t// ~224–231 documents for `effResults`. `turnNode.emit` lives inside\n\t\t// `effResponse`'s outer batch; `turnSub` drains BEFORE the diamond\n\t\t// settles `effFullDeny`. A future refactor that un-batches that emit\n\t\t// would regress all three effects together — keep the discipline.\n\t\t//\n\t\t// **Belt-and-suspenders maxTurns guard.** On normal flow `effResponse`\n\t\t// already sets `status=\"done\"` when `next >= maxTurns`, so by the time\n\t\t// `toolCallsRaw` would fire (status===\"acting\" gate) we're past the\n\t\t// cap-reaching turn and `effFullDeny` doesn't run. The\n\t\t// `latestTurn >= maxTurns ? \"done\" : \"thinking\"` check below is\n\t\t// defense-in-depth in case a future refactor inverts the ordering\n\t\t// (cheap, no path to a runtime bug).\n\t\tconst effFullDeny =\n\t\t\tgatedToolCallsNode !== toolCallsRaw\n\t\t\t\t? node(\n\t\t\t\t\t\t[toolCallsRaw, gatedToolCallsNode],\n\t\t\t\t\t\t(batchData) => {\n\t\t\t\t\t\t\tif (latestAborted) return;\n\t\t\t\t\t\t\tconst rawBatch = batchData[0];\n\t\t\t\t\t\t\tconst gatedBatch = batchData[1];\n\t\t\t\t\t\t\tconst rawCalls =\n\t\t\t\t\t\t\t\trawBatch != null && rawBatch.length > 0\n\t\t\t\t\t\t\t\t\t? (rawBatch.at(-1) as readonly ToolCall[])\n\t\t\t\t\t\t\t\t\t: null;\n\t\t\t\t\t\t\t// No real request this wave (RESOLVED upstream) — nothing to recover.\n\t\t\t\t\t\t\tif (rawCalls == null || rawCalls.length === 0) return;\n\t\t\t\t\t\t\t// Gate's emission this wave — null/empty when the interceptor\n\t\t\t\t\t\t\t// produced RESOLVED (full deny); non-empty array of the allowed\n\t\t\t\t\t\t\t// subset on partial deny / full allow.\n\t\t\t\t\t\t\tconst gatedCalls =\n\t\t\t\t\t\t\t\tgatedBatch != null && gatedBatch.length > 0\n\t\t\t\t\t\t\t\t\t? (gatedBatch.at(-1) as readonly ToolCall[])\n\t\t\t\t\t\t\t\t\t: null;\n\t\t\t\t\t\t\t// Denied subset = calls in raw not present in gated (by id).\n\t\t\t\t\t\t\t// Full deny → all rawCalls. Partial deny → subtraction.\n\t\t\t\t\t\t\t// Full allow → empty array (no recovery needed).\n\t\t\t\t\t\t\tconst allowedIds = gatedCalls === null ? null : new Set(gatedCalls.map((c) => c.id));\n\t\t\t\t\t\t\tconst denied =\n\t\t\t\t\t\t\t\tallowedIds === null ? rawCalls : rawCalls.filter((c) => !allowedIds.has(c.id));\n\t\t\t\t\t\t\tif (denied.length === 0) return; // full allow — effResults owns it\n\t\t\t\t\t\t\tconst isFullDeny = gatedCalls === null;\n\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\t// Full deny → advance status here (effResults never fires).\n\t\t\t\t\t\t\t\t// Partial deny → DON'T touch status; effResults will transition\n\t\t\t\t\t\t\t\t// after the allowed subset's tool-execution completes, so we\n\t\t\t\t\t\t\t\t// only fill in the missing tool_results for the denied subset.\n\t\t\t\t\t\t\t\tif (isFullDeny) {\n\t\t\t\t\t\t\t\t\tstatusNode.emit(latestTurn >= maxTurns ? \"done\" : \"thinking\");\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfor (const c of denied)\n\t\t\t\t\t\t\t\t\tchat.appendToolResult(c.id, \"[tool call denied by interceptor]\");\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tname: \"fullDenyRecovery\",\n\t\t\t\t\t\t\tdescribeKind: \"effect\",\n\t\t\t\t\t\t\tmeta: aiMeta(\"agent_full_deny_recovery\"),\n\t\t\t\t\t\t\t// MUST be explicit: the core `node()` default is\n\t\t\t\t\t\t\t// `partial: false` (node.ts `opts.partial ?? false`),\n\t\t\t\t\t\t\t// and `gatedToolCallsNode` only ever emits RESOLVED on the\n\t\t\t\t\t\t\t// full-deny path (never DATA/terminal). Spec R2.7.0\n\t\t\t\t\t\t\t// (DS-2.7.A, 2026-05-19) holds the `partial: false`\n\t\t\t\t\t\t\t// first-run gate until every dep has contributed real\n\t\t\t\t\t\t\t// DATA, so a `partial: false` effFullDeny would hold the\n\t\t\t\t\t\t\t// fn FOREVER. Spec R2.7.2 = `partial: true` disables the\n\t\t\t\t\t\t\t// gate; the fn body's `denied`-subtraction guard above\n\t\t\t\t\t\t\t// covers the SENTINEL slot per the R2.7.2 author\n\t\t\t\t\t\t\t// contract.\n\t\t\t\t\t\t\tpartial: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t: null;\n\n\t\t// Effect 3: external abort → cancel in-flight wire call + terminal status.\n\t\t// Aborting the controller causes the switchMap inner's `fromAny` to\n\t\t// emit ERROR (signal-bound), which tears down the subscription. The\n\t\t// `status=\"done\"` emit drives `_terminalResult` to resolve `run()`'s\n\t\t// Promise (via AbortError when `resp == null`, see C3).\n\t\t//\n\t\t// Unit 4 Q5: status guard — if status is already \"done\" (the natural-\n\t\t// completion path raced the abort), skip the redundant emit so the\n\t\t// status-node event log isn't polluted with a trailing duplicate.\n\t\t// Closure-mirror `latestStatus` keeps the comparison synchronous and\n\t\t// P3-compliant (closure read, not `.cache` read — see §28). Seeded\n\t\t// from `statusNode.cache` to match the §28 factory-time-seed pattern\n\t\t// that `latestTurn` / `latestAborted` use — the literal `\"idle\"` would\n\t\t// silently drift if the constructor initial value ever changed.\n\t\tlet latestStatus: AgentLoopStatus = (statusNode.cache as AgentLoopStatus | undefined) ?? \"idle\";\n\t\tconst statusSub = statusNode.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) if (m[0] === DATA) latestStatus = m[1] as AgentLoopStatus;\n\t\t});\n\t\tconst effAbort = node(\n\t\t\t[abortedNode],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tif (data[0] === true) {\n\t\t\t\t\tthis._currentAbortController?.abort(new Error(\"agentLoop: aborted\"));\n\t\t\t\t\tif (latestStatus !== \"done\") statusNode.emit(\"done\");\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\n\t\t);\n\n\t\t// Keepalive so the pipeline stays activated even without external\n\t\t// subscribers. Callers don't need to subscribe to `llmResponse` /\n\t\t// `toolResults` for the loop to run.\n\t\tconst kaResponse = keepalive(effResponse);\n\t\tconst kaResults = keepalive(effResults);\n\t\tconst kaFullDeny = effFullDeny ? keepalive(effFullDeny) : null;\n\t\tconst kaAbort = keepalive(effAbort);\n\n\t\t// terminalResult emits the final `LLMResponse` on each \"done\"\n\t\t// transition. The old compound `{response, runVersion}` shape existed\n\t\t// to let a re-entrant caller's `awaitSettled` predicate filter out\n\t\t// the PREVIOUS run's cached DATA; that job now belongs to\n\t\t// `awaitSettled({skipCurrent: true})` (extra/sources.ts) which\n\t\t// ignores the initial push-on-subscribe DATA and resolves only on\n\t\t// fresh post-subscribe emissions. Retiring the stamp removes a\n\t\t// closure-held counter and a per-emission object allocation from\n\t\t// the hot path.\n\t\t//\n\t\t// C3 (abort-before-response) post-SENTINEL: when `stat === \"done\"` but\n\t\t// `lastResponseState` is SENTINEL (no DATA ever delivered for this\n\t\t// run — `prevData[1] === undefined`, equivalently `resp === undefined`\n\t\t// after `readLatest`'s fallback), emit `ERROR(AbortError)` so the\n\t\t// awaiting Promise rejects instead of hanging on a RESOLVED. The\n\t\t// SENTINEL state is restored at every `run()` boundary by\n\t\t// `lastResponse.down([[INVALIDATE]])` (clears `_cached` AND clears\n\t\t// each dependent's `prevData` slot for this dep), so a second run\n\t\t// after a successful first run still detects the abort cleanly —\n\t\t// no stale `prevData` leak.\n\t\tthis._terminalResult = nodeFactory<LLMResponse>(\n\t\t\t[statusNode, lastResponseState],\n\t\t\t(data, actions, ctx) => {\n\t\t\t\tconst stat = readLatest<AgentLoopStatus>(data, ctx.prevData, 0, \"idle\");\n\t\t\t\tconst resp = readLatest<LLMResponse | undefined>(data, ctx.prevData, 1, undefined);\n\t\t\t\tif (stat === \"done\") {\n\t\t\t\t\tif (resp !== undefined) {\n\t\t\t\t\t\tactions.emit(resp);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst err = new Error(\"agentLoop: aborted\") as Error & { name: string };\n\t\t\t\t\terr.name = \"AbortError\";\n\t\t\t\t\tactions.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (stat === \"error\") {\n\t\t\t\t\tactions.down([[ERROR, new Error(\"agentLoop: errored\")]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"terminalResult\",\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: aiMeta(\"agent_terminal_result\"),\n\t\t\t\t// `lastResponseState` is SENTINEL until the first real response\n\t\t\t\t// arrives — without `partial: true`, the spec §2.7 first-run\n\t\t\t\t// gate would block this fn from ever firing on the abort-\n\t\t\t\t// before-response path (`status → \"done\"` while `lastResponse`\n\t\t\t\t// has never delivered DATA). The fn explicitly handles the\n\t\t\t\t// SENTINEL case (`resp === undefined → ERROR(AbortError)`),\n\t\t\t\t// so partial-fire is safe by design.\n\t\t\t\tpartial: true,\n\t\t\t},\n\t\t);\n\t\t// Wave B-CC Q2/C: register intermediate pipeline nodes so consumers\n\t\t// can `observe(path)` them by name (e.g. `agent.observe(\"promptInput\")`).\n\t\t// They were already visible in `describe()` via dep traversal, but not\n\t\t// path-addressable. Tools using the `observe`-by-path API now work.\n\t\t//\n\t\t// QA-fix (#5 stability): registrations live AFTER ALL dependent nodes\n\t\t// are constructed (`promptInput → llmResponse → effResponse →\n\t\t// lastResponseState → toolCallsRaw → toolResultsNode → effResults →\n\t\t// effAbort → _terminalResult`). Topology event-stream consumers\n\t\t// subscribed at construction time now see registrations in an order\n\t\t// where every edge between two registered nodes is already valid —\n\t\t// no transient partial graph slipping through to live mermaid / d2\n\t\t// renderers.\n\t\tthis.add(promptInput as Node<unknown>, { name: \"promptInput\" });\n\t\tthis.add(llmResponse as Node<unknown>, { name: \"llmResponse\" });\n\t\tthis.add(this.lastResponse as Node<unknown>, { name: \"lastResponse\" });\n\t\t// When no interceptor is configured, `this.toolCalls === toolCallsRaw` —\n\t\t// registering the same instance under two names trips the per-graph\n\t\t// `_nodeToName` collision check. Register the raw under `toolCalls`\n\t\t// directly in that case; otherwise register both (raw + post-intercept).\n\t\tif (this.toolCalls === toolCallsRaw) {\n\t\t\tthis.add(this.toolCalls as Node<unknown>, { name: \"toolCalls\" });\n\t\t} else {\n\t\t\tthis.add(toolCallsRaw as Node<unknown>, { name: \"toolCallsRaw\" });\n\t\t\tthis.add(this.toolCalls as Node<unknown>, { name: \"toolCalls\" });\n\t\t}\n\t\tthis.add(toolResultsNode as Node<unknown>, { name: \"toolResults\" });\n\t\tthis.add(this._terminalResult as Node<unknown>, { name: \"terminalResult\" });\n\n\t\t// Register subscriptions via `addDisposer` so they tear down on\n\t\t// subgraph unmount (not just explicit `destroy()`). A caller that\n\t\t// unmounts the AgentLoopGraph from its parent via `graph.remove(...)`\n\t\t// would otherwise keep `turnSub` / `abortedSub` live against dead state.\n\t\tthis.addDisposer(turnSub);\n\t\tthis.addDisposer(abortedSub);\n\t\tthis.addDisposer(statusSub);\n\t\tthis.addDisposer(kaResponse);\n\t\tthis.addDisposer(kaResults);\n\t\tif (kaFullDeny) this.addDisposer(kaFullDeny);\n\t\tthis.addDisposer(kaAbort);\n\t\tthis._disposeRunWiring = (): void => {\n\t\t\t// addDisposer takes care of teardown; this shim stays for the\n\t\t\t// `destroy()` override's idempotency contract (safe no-op if the\n\t\t\t// disposers already fired).\n\t\t};\n\t}\n\n\t/**\n\t * Bridge to `Promise<LLMResponse>` over the reactive pipeline.\n\t *\n\t * - If `userMessage` is provided, appends it as a user message and\n\t * transitions status to `\"thinking\"` to kick the loop.\n\t * - If `signal` is provided, binds it to the reactive `aborted` node\n\t * AND threads into `adapter.invoke({ signal })` so the wire call can\n\t * cancel mid-flight. The reactive `aborted` state + effect 3 guarantee\n\t * that even an adapter that ignores `signal` will stop emitting into\n\t * the agent graph.\n\t * - Resolves when `status === \"done\"` with the final LLM response.\n\t * Rejects with `AbortError` when the abort signal fires pre-response.\n\t * Rejects with the stage error when `status === \"error\"`.\n\t *\n\t * **Concurrency:** `run()` refuses to overlap with a pending call on the\n\t * same agent. Attempting to call `run()` while a previous `run()` is\n\t * still in-flight throws a `RangeError` immediately. Stale-resolution\n\t * safety is provided by `awaitSettled({skipCurrent: true})`, which\n\t * ignores the cached initial DATA from any previous run and resolves\n\t * only on a fresh post-subscribe emission of `_terminalResult`.\n\t */\n\tasync run(userMessage?: string, signal?: AbortSignal): Promise<LLMResponse | null> {\n\t\tif (this._running) {\n\t\t\tthrow new RangeError(\n\t\t\t\t`agentLoop \"${this.name}\": run() called while a previous run() is still pending — await the previous run before starting another, or call abort() first`,\n\t\t\t);\n\t\t}\n\t\tthis._running = true;\n\n\t\tlet offAbort: (() => void) | undefined;\n\t\ttry {\n\t\t\t// Reset per-run state. `lastResponse` MUST be cleared here —\n\t\t\t// without it, `_terminalResult` would read the prior run's\n\t\t\t// cached response during a second `run()` with a pre-aborted\n\t\t\t// signal: `effAbort` drives `status → \"done\"`, `_terminalResult`\n\t\t\t// evaluates `stat=\"done\"` + `resp=<prior respA>` and emits DATA\n\t\t\t// as a fresh post-subscribe signal → `awaitSettled` resolves\n\t\t\t// with the stale response instead of rejecting with AbortError.\n\t\t\t// The C3 `stat=done && resp===undefined → ERROR` guard in\n\t\t\t// `_terminalResult` is only correct once the reset clears the\n\t\t\t// cache.\n\t\t\t//\n\t\t\t// **SENTINEL reset via plain `[[INVALIDATE]]`** (DS-13.5.A,\n\t\t\t// 2026-05-01). Pre-DS-13.5.A this required a paired\n\t\t\t// `[[INVALIDATE], [RESOLVED]]` because INVALIDATE alone left\n\t\t\t// dependents wedged in DIRTY. With INVALIDATE settling the wave\n\t\t\t// (decrementing `_dirtyDepCount` like RESOLVED) and clearing\n\t\t\t// `_cached` + each dependent's `prevData[lastResponse]` slot\n\t\t\t// back to `undefined`, a single emission restores SENTINEL state\n\t\t\t// AND lets dependents fire on the next status transition.\n\t\t\t// `lastResponse` is a `Node<LLMResponse>` with no `initial` —\n\t\t\t// it stays SENTINEL until the first real response; resetting\n\t\t\t// via `emit(null)` would push a `null` DATA placeholder (the\n\t\t\t// F9 trap), which is why INVALIDATE rather than emit is used.\n\t\t\tbatch(() => {\n\t\t\t\tthis.lastResponse.down([[INVALIDATE]]);\n\t\t\t\tthis.turn.emit(0);\n\t\t\t\tthis.aborted.emit(false);\n\t\t\t\tthis.status.emit(\"idle\");\n\t\t\t});\n\t\t\tif (userMessage != null) this.chat.append(\"user\", userMessage);\n\n\t\t\t// Subscribe to `_terminalResult` BEFORE transitioning to\n\t\t\t// \"thinking\" — otherwise a synchronous adapter (mock tests,\n\t\t\t// offline stubs) would drain status → done → DATA on\n\t\t\t// `_terminalResult` before `awaitSettled` had a chance to\n\t\t\t// subscribe, and `skipCurrent: true` would swallow the only\n\t\t\t// DATA this run will produce. `awaitSettled` / `firstWhere`\n\t\t\t// subscribes synchronously during the `async` function's\n\t\t\t// initial execution slice, so calling it before the kick\n\t\t\t// guarantees the subscription is in place when the pipeline\n\t\t\t// starts draining.\n\t\t\t//\n\t\t\t// `skipCurrent: true` still matters: on the second `run()`\n\t\t\t// call `_terminalResult` holds cached DATA from the prior run,\n\t\t\t// and push-on-subscribe would resolve immediately with that\n\t\t\t// stale value without the skip.\n\t\t\tconst resultPromise = awaitSettled(this._terminalResult, { skipCurrent: true });\n\n\t\t\tif (signal != null) {\n\t\t\t\tif (signal.aborted) {\n\t\t\t\t\tthis.aborted.emit(true);\n\t\t\t\t} else {\n\t\t\t\t\tconst listener = (): void => this.aborted.emit(true);\n\t\t\t\t\tsignal.addEventListener(\"abort\", listener, { once: true });\n\t\t\t\t\toffAbort = (): void => signal.removeEventListener(\"abort\", listener);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Kick — transition to \"thinking\" fires promptInput → llmResponse.\n\t\t\t// Skip the kick when the signal was already aborted: `effAbort`\n\t\t\t// has driven `status → \"done\"` above, and a trailing\n\t\t\t// `thinking` emit would produce a non-monotonic `idle → done →\n\t\t\t// thinking` sequence in the status-event log for no reactive\n\t\t\t// benefit (promptInput gates on `!latestAborted` anyway).\n\t\t\tif (signal?.aborted !== true) {\n\t\t\t\tthis.status.emit(\"thinking\");\n\t\t\t}\n\n\t\t\treturn await resultPromise;\n\t\t} finally {\n\t\t\toffAbort?.();\n\t\t\tthis._running = false;\n\t\t\tthis._currentAbortController = null;\n\t\t}\n\t}\n\n\t/**\n\t * Flip the reactive `aborted` state. Equivalent to setting an external\n\t * `AbortSignal` — the pipeline observes and transitions to `\"done\"`.\n\t */\n\tabort(): void {\n\t\tthis.aborted.emit(true);\n\t}\n\n\toverride destroy(): void {\n\t\ttry {\n\t\t\tthis._disposeRunWiring();\n\t\t} catch {\n\t\t\t/* best-effort: disposing keepalives shouldn't block destroy */\n\t\t}\n\t\tsuper.destroy();\n\t}\n}\n\n/**\n * Read the latest value for dep `i` inside a raw-`node()` fn body.\n *\n * Checks `batchData[i]` first (this-wave DATA from the dep), falls back to\n * `ctx.prevData[i]` (last DATA from prior waves), and finally to `fallback`\n * when the dep has never emitted (SENTINEL). Matches the unwrap semantics\n * `derived`'s sugar applies, so raw nodes can read deps uniformly.\n *\n * @internal\n */\nfunction readLatest<T>(\n\tbatchData: readonly (readonly unknown[] | undefined)[],\n\tprevData: readonly unknown[],\n\tindex: number,\n\tfallback: T,\n): T {\n\tconst batch = batchData[index];\n\tif (batch != null && batch.length > 0) return batch[batch.length - 1] as T;\n\tconst prev = prevData[index];\n\treturn (prev !== undefined ? prev : fallback) as T;\n}\n\n/** @internal Shape of the LLM invocation input — constructed inside `promptInput`. */\ninterface InvokeInput {\n\treadonly messages: readonly ChatMessage[];\n\treadonly tools: readonly ToolDefinition[];\n}\n\nexport function agentLoop(name: string, opts: AgentLoopOptions): AgentLoopGraph {\n\tconst g = new AgentLoopGraph(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` exposes provenance. Opts include non-JSON\n\t// fields (`adapter`, `tools`, `stopWhen`, `onToolCall`,\n\t// `interceptToolCalls`, etc.) so route through `placeholderArgs`\n\t// (DG2=ii).\n\tg.tagFactory(\"agentLoop\", placeholderArgs(opts as unknown as Record<string, unknown>));\n\treturn g;\n}\n","/**\n * Harness pipeline trace — thin sugar over `graph.observe({ format: \"stage-log\" })`.\n *\n * Since 2026-04-22 (D2), stage-labeled tracing is a first-class observe format\n * on {@link Graph}. `harnessTrace` wires that format over the 7 pipeline stages\n * (INTAKE → TRIAGE → QUEUE → GATE → EXECUTE → VERIFY → STRATEGY) with sensible\n * defaults so harness consumers don't need to restate the stage map.\n *\n * For non-harness graphs, call `graph.observe({ format: \"stage-log\", stageLabels })`\n * directly — the format is domain-agnostic.\n *\n * @module\n */\n\nimport { monotonicNs } from \"@graphrefly/pure-ts/core\";\nimport type { ObserveEvent, ObserveResult } from \"@graphrefly/pure-ts/graph\";\nimport type { HarnessGraph } from \"./harness-loop.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Event type captured by structured trace. */\nexport type TraceEventType = \"data\" | \"error\" | \"complete\";\n\n/** A single structured trace event. */\nexport interface TraceEvent {\n\t/** Elapsed seconds since trace was created. */\n\telapsed: number;\n\t/** Pipeline stage label (INTAKE, TRIAGE, QUEUE, GATE, EXECUTE, VERIFY, STRATEGY). */\n\tstage: string;\n\t/** Event type. */\n\ttype: TraceEventType;\n\t/** Data payload (present for \"data\" and \"error\" events). Omitted at \"summary\" detail. */\n\tdata?: unknown;\n\t/** Human-readable summary of the data. Present at \"standard\" and \"full\" detail. */\n\tsummary?: string;\n}\n\n/** Detail level for trace output. */\nexport type TraceDetail =\n\t/** Stage + elapsed only. No data preview. Lowest overhead. */\n\t| \"summary\"\n\t/** Stage + elapsed + truncated data preview. Default. */\n\t| \"standard\"\n\t/** Stage + elapsed + full raw data. Use for debugging, not production. */\n\t| \"full\";\n\n/** Handle returned by {@link harnessTrace}. Call `dispose()` to stop tracing. */\nexport interface HarnessTraceHandle {\n\t/** Stop tracing and detach all observers. Safe to call multiple times. */\n\tdispose(): void;\n\t/**\n\t * Structured trace events collected since creation. Plain array — no\n\t * subscription needed (COMPOSITION-GUIDE §1: avoid lazy-activation\n\t * friction for inspection tools). Populated reactively via observe().\n\t */\n\treadonly events: readonly TraceEvent[];\n}\n\n/** Options for {@link harnessTrace}. */\nexport interface HarnessTraceOptions {\n\t/** Sink for rendered trace lines. Default: `console.log`. Pass `null` for structured-only. */\n\tlogger?: ((line: string) => void) | null;\n\t/** Detail level for both string and structured output. Default: `\"summary\"`. */\n\tdetail?: TraceDetail;\n}\n\n// ---------------------------------------------------------------------------\n// Stage labels\n// ---------------------------------------------------------------------------\n\n/**\n * Observe paths → stage labels for the 7 harness stages. Path set is\n * sourced from {@link HarnessGraph.stageNodes} so inspection tools stay\n * decoupled from mount-structure changes (Unit 22 C).\n */\nfunction buildStageLabels(harness: HarnessGraph): Record<string, string> {\n\tconst labels: Record<string, string> = {};\n\tfor (const { label, paths } of harness.stageNodes()) {\n\t\tfor (const p of paths) labels[p] = label;\n\t}\n\treturn labels;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Attach a stage-log trace over the harness pipeline. Delegates to\n * `harness.observe({ format: \"stage-log\", ... })` for each stage path —\n * every event is captured in `handle.events` (structured) AND rendered via\n * the `logger` (string output).\n *\n * **Detail levels:**\n * - `\"summary\"` — stage + elapsed only. Minimal overhead.\n * - `\"standard\"` (default) — stage + elapsed + truncated data preview.\n * - `\"full\"` — stage + elapsed + full raw data object in events.\n *\n * Elapsed timestamps are relative to the `harnessTrace()` invocation time,\n * not the first event.\n */\nexport function harnessTrace(\n\tharness: HarnessGraph,\n\topts?: HarnessTraceOptions,\n): HarnessTraceHandle {\n\tconst logger: ((line: string) => void) | null =\n\t\topts?.logger === null ? null : (opts?.logger ?? console.log);\n\tconst detail: TraceDetail = opts?.detail ?? \"summary\";\n\tconst startNs = monotonicNs();\n\tconst observations: ObserveResult[] = [];\n\tconst events: TraceEvent[] = [];\n\tconst stageLabels = buildStageLabels(harness);\n\n\tfunction elapsedSecs(): number {\n\t\treturn (monotonicNs() - startNs) / 1e9;\n\t}\n\n\tfunction recordEvent(stage: string, type: TraceEventType, rawData: unknown): void {\n\t\tconst ev: TraceEvent = { elapsed: elapsedSecs(), stage, type };\n\t\tif (detail !== \"summary\") ev.summary = summarize(rawData);\n\t\tif (detail === \"full\") ev.data = rawData;\n\t\tevents.push(ev);\n\t}\n\n\t// One observe call per path — keeps per-stage elapsed offsets anchored to\n\t// this invocation (the shared stage-log format uses its own elapsed clock\n\t// per observation, which matches the legacy behavior). We also intercept\n\t// each event through `onEvent` so structured `events[]` stays populated\n\t// regardless of `logger`.\n\tfor (const [path, stage] of Object.entries(stageLabels)) {\n\t\ttry {\n\t\t\tconst obs = harness.observe(path, {\n\t\t\t\tformat: \"stage-log\",\n\t\t\t\tstageLabels,\n\t\t\t\tlogger: logger ? (line: string) => logger(line) : () => {},\n\t\t\t\tincludeTypes: [\"data\", \"error\", \"complete\"],\n\t\t\t});\n\t\t\tobs.onEvent((event: ObserveEvent) => {\n\t\t\t\tif (event.type === \"data\") recordEvent(stage, \"data\", (event as { data: unknown }).data);\n\t\t\t\telse if (event.type === \"error\")\n\t\t\t\t\trecordEvent(stage, \"error\", (event as { data: unknown }).data);\n\t\t\t\telse if (event.type === \"complete\") recordEvent(stage, \"complete\", undefined);\n\t\t\t});\n\t\t\tobservations.push(obs);\n\t\t} catch (err) {\n\t\t\t// Node may not exist yet (e.g., a gated-queue route that hasn't been\n\t\t\t// mounted on this harness). Record a synthetic error trace event so\n\t\t\t// consumers see WHICH stage dropped out and why — silent swallow\n\t\t\t// breaks dry-run equivalence (a regression in stage wiring would\n\t\t\t// not surface in the trace).\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\trecordEvent(stage, \"error\", `observe-unavailable: ${path} — ${msg}`);\n\t\t\tif (logger) {\n\t\t\t\tlogger(`[${elapsedSecs().toFixed(3)}s] ${stage.padEnd(9)} ✗ observe-unavailable: ${msg}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tget events(): readonly TraceEvent[] {\n\t\t\treturn events;\n\t\t},\n\t\tdispose() {\n\t\t\tfor (const obs of observations) obs.dispose();\n\t\t\tobservations.length = 0;\n\t\t},\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Helpers — kept here because `observe({ format: \"stage-log\" })` emits short\n// one-line previews; the structured `events[]` is free to carry richer\n// summaries with different truncation bounds (120 for JSON, 80 for strings).\n// ---------------------------------------------------------------------------\n\nfunction summarize(value: unknown): string {\n\tif (value == null) return \"null\";\n\tif (typeof value === \"string\") return truncate(value, 80);\n\tif (typeof value === \"number\" || typeof value === \"boolean\") return String(value);\n\tif (typeof value === \"bigint\") return String(value);\n\ttry {\n\t\tconst json = JSON.stringify(value);\n\t\treturn truncate(json, 120);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n\nfunction truncate(s: string, max: number): string {\n\treturn s.length > max ? `${s.slice(0, max - 1)}…` : s;\n}\n"],"mappings":"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","names":["isNode","import_core","isNode","import_core","import_core","import_extra","import_graph","import_core","import_extra","batch","policy","import_core","import_extra","import_graph","import_core","import_extra","import_core","import_extra","import_graph","import_core","import_extra","import_graph","meta","import_core","import_extra","import_graph","batch","createNode","batch","i","best","bestScore","batch","meanScore","defaultToOutput","batch","import_core","import_extra","import_graph","import_core","import_core","isNode","import_core","import_extra","batch","import_core","import_graph","batch","import_core","import_extra","import_graph","batch","import_core","import_extra","batch","import_core","import_extra","import_graph","batch","import_core","import_extra","import_graph","import_core","import_extra","import_graph","DEFAULT_MAX_PER_PUMP","requireNonNegativeInt","batch","requireNonNegativeInt","DEFAULT_MAX_PER_PUMP","batch","topic","import_core","import_extra","import_graph","batch","import_graph","import_core","import_extra","import_graph","import_extra","import_core","import_extra","import_graph","import_core","import_extra","import_graph","nodeFactory","batch","import_core"]}